From d52b2c921abd3c1e8d6368858313ad0cb0468c07 Mon Sep 17 00:00:00 2001 From: DrKLO Date: Wed, 23 Dec 2020 11:48:30 +0400 Subject: [PATCH] Update to 7.3.0 (2195) --- Dockerfile | 2 +- TMessagesProj/build.gradle | 27 +- .../config/debug/AndroidManifest.xml | 1 + .../config/debug/AndroidManifest_SDK23.xml | 1 + .../config/release/AndroidManifest.xml | 1 + .../config/release/AndroidManifest_SDK23.xml | 1 + TMessagesProj/jni/CMakeLists.txt | 5 +- TMessagesProj/jni/gifvideo.cpp | 25 +- TMessagesProj/jni/tgnet/Handshake.cpp | 2 +- .../third_party/libvpx/source/libvpx/AUTHORS | 6 + .../libvpx/source/libvpx/CHANGELOG | 24 + .../libvpx/third_party/x86inc/README.libvpx | 8 +- .../libvpx/third_party/x86inc/x86inc.asm | 732 +- .../libvpx/source/libvpx/tools_common.c | 7 +- .../libvpx/source/libvpx/vp8/common/extend.c | 53 +- .../vp8/common/generic/systemdependent.c | 4 + .../vp8/common/mips/mmi/dequantize_mmi.c | 2 +- .../libvpx/vp8/common/mips/mmi/idctllm_mmi.c | 59 +- .../common/mips/mmi/loopfilter_filters_mmi.c | 532 +- .../vp8/common/mips/mmi/sixtap_filter_mmi.c | 57 +- .../vp8/common/mips/msa/vp8_macros_msa.h | 16 +- .../source/libvpx/vp8/common/threading.h | 15 +- .../libvpx/vp8/common/x86/dequantize_mmx.asm | 4 +- .../libvpx/vp8/common/x86/idctllm_mmx.asm | 4 +- .../libvpx/vp8/common/x86/idctllm_sse2.asm | 8 +- .../libvpx/vp8/common/x86/iwalsh_sse2.asm | 2 +- .../x86/loopfilter_block_sse2_x86_64.asm | 4 +- .../libvpx/vp8/common/x86/loopfilter_sse2.asm | 20 +- .../libvpx/vp8/common/x86/mfqe_sse2.asm | 6 +- .../libvpx/vp8/common/x86/recon_mmx.asm | 4 +- .../libvpx/vp8/common/x86/recon_sse2.asm | 2 +- .../libvpx/vp8/common/x86/subpixel_mmx.asm | 4 +- .../libvpx/vp8/common/x86/subpixel_sse2.asm | 16 +- .../libvpx/vp8/common/x86/subpixel_ssse3.asm | 16 +- .../source/libvpx/vp8/encoder/bitstream.c | 2 +- .../libvpx/vp8/encoder/mips/mmi/dct_mmi.c | 81 +- .../vp8/encoder/mips/mmi/vp8_quantize_mmi.c | 65 +- .../source/libvpx/vp8/encoder/onyx_if.c | 9 +- .../source/libvpx/vp8/encoder/treewriter.h | 6 +- .../vp8/encoder/x86/block_error_sse2.asm | 6 +- .../libvpx/vp8/encoder/x86/copy_sse2.asm | 2 +- .../libvpx/vp8/encoder/x86/copy_sse3.asm | 2 +- .../libvpx/vp8/encoder/x86/dct_sse2.asm | 4 +- .../libvpx/vp8/encoder/x86/fwalsh_sse2.asm | 2 +- .../x86/temporal_filter_apply_sse2.asm | 2 +- .../libvpx/source/libvpx/vp8/vp8_cx_iface.c | 7 +- .../libvpx/source/libvpx/vp8/vp8_dx_iface.c | 2 +- .../source/libvpx/vp9/common/vp9_onyxc_int.h | 12 +- .../libvpx/vp9/common/x86/vp9_mfqe_sse2.asm | 6 +- .../source/libvpx/vp9/decoder/vp9_decoder.c | 5 + .../libvpx/vp9/encoder/vp9_encodeframe.c | 20 +- .../source/libvpx/vp9/encoder/vp9_encoder.c | 459 +- .../source/libvpx/vp9/encoder/vp9_encoder.h | 206 +- .../libvpx/vp9/encoder/vp9_ext_ratectrl.c | 150 + .../libvpx/vp9/encoder/vp9_ext_ratectrl.h | 48 + .../source/libvpx/vp9/encoder/vp9_extend.c | 32 +- .../source/libvpx/vp9/encoder/vp9_firstpass.c | 165 +- .../source/libvpx/vp9/encoder/vp9_firstpass.h | 17 +- .../source/libvpx/vp9/encoder/vp9_pickmode.c | 2 +- .../source/libvpx/vp9/encoder/vp9_ratectrl.c | 86 +- .../source/libvpx/vp9/encoder/vp9_ratectrl.h | 6 +- .../source/libvpx/vp9/encoder/vp9_rdopt.c | 6 + .../libvpx/vp9/encoder/vp9_speed_features.c | 21 +- .../libvpx/vp9/encoder/vp9_svc_layercontext.c | 13 +- .../libvpx/vp9/encoder/vp9_svc_layercontext.h | 2 + .../libvpx/source/libvpx/vp9/ratectrl_rtc.cc | 174 + .../libvpx/source/libvpx/vp9/ratectrl_rtc.h | 116 + .../libvpx/source/libvpx/vp9/simple_encode.cc | 313 +- .../libvpx/source/libvpx/vp9/simple_encode.h | 192 +- .../libvpx/source/libvpx/vp9/vp9_cx_iface.c | 205 +- .../libvpx/source/libvpx/vp9/vp9_cx_iface.h | 4 +- .../source/libvpx/vp9/vp9_iface_common.c | 9 +- .../libvpx/source/libvpx/vp9/vp9cx.mk | 5 +- .../libvpx/vpx/internal/vpx_codec_internal.h | 21 +- .../libvpx/source/libvpx/vpx/src/vpx_codec.c | 2 +- .../source/libvpx/vpx/src/vpx_decoder.c | 15 +- .../libvpx/source/libvpx/vpx/src/vpx_image.c | 13 +- .../libvpx/source/libvpx/vpx/vp8cx.h | 37 + .../libvpx/source/libvpx/vpx/vpx_codec.h | 7 +- .../libvpx/source/libvpx/vpx/vpx_codec.mk | 2 + .../libvpx/source/libvpx/vpx/vpx_decoder.h | 56 +- .../libvpx/source/libvpx/vpx/vpx_encoder.h | 1 + .../source/libvpx/vpx/vpx_ext_ratectrl.h | 337 + .../libvpx/source/libvpx/vpx/vpx_image.h | 1 + .../source/libvpx/vpx_dsp/mips/macros_msa.h | 16 +- .../source/libvpx/vpx_dsp/mips/sad_mmi.c | 55 +- .../source/libvpx/vpx_dsp/mips/subtract_mmi.c | 6 +- .../source/libvpx/vpx_dsp/mips/variance_mmi.c | 248 +- .../libvpx/vpx_dsp/mips/vpx_convolve8_mmi.c | 10 +- .../libvpx/vpx_dsp/x86/add_noise_sse2.asm | 2 +- .../libvpx/vpx_dsp/x86/deblock_sse2.asm | 4 +- .../vpx_dsp/x86/highbd_variance_impl_sse2.asm | 4 +- .../source/libvpx/vpx_dsp/x86/sad_sse3.asm | 10 +- .../source/libvpx/vpx_dsp/x86/sad_sse4.asm | 10 +- .../source/libvpx/vpx_dsp/x86/sad_ssse3.asm | 4 +- .../libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm | 4 +- .../libvpx/vpx_dsp/x86/transpose_sse2.h | 4 +- .../vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm | 24 +- .../x86/vpx_high_subpixel_bilinear_sse2.asm | 24 +- .../vpx_dsp/x86/vpx_subpixel_8t_sse2.asm | 24 +- .../x86/vpx_subpixel_bilinear_sse2.asm | 24 +- .../x86/vpx_subpixel_bilinear_ssse3.asm | 24 +- .../source/libvpx/vpx_ports/asmdefs_mmi.h | 4 +- .../source/libvpx/vpx_ports/emms_mmx.asm | 2 +- .../libvpx/vpx_ports/float_control_word.asm | 4 +- .../libvpx/source/libvpx/vpx_ports/mips.h} | 24 +- .../source/libvpx/vpx_ports/mips_cpudetect.c | 57 + .../source/libvpx/vpx_ports/vpx_ports.mk | 3 + .../libvpx/vpx_ports/x86_abi_support.asm | 79 +- .../third_party/libvpx/source/libvpx/vpxenc.c | 20 +- .../third_party/libvpx/source/libvpx/vpxenc.h | 1 + .../libvpx/source/libvpx/webmdec.cc | 42 +- .../libvpx/source/libvpx/webmenc.cc | 4 +- .../jni/third_party/libyuv/include/libyuv.h | 4 +- .../libyuv/include/libyuv/convert.h | 52 +- .../libyuv/include/libyuv/convert_argb.h | 601 +- .../libyuv/include/libyuv/convert_from.h | 216 +- .../libyuv/include/libyuv/convert_from_argb.h | 15 +- .../libyuv/include/libyuv/cpu_id.h | 2 + .../libyuv/include/libyuv/macros_msa.h | 3 + .../libyuv/include/libyuv/planar_functions.h | 109 +- .../libyuv/include/libyuv/rotate.h | 8 +- .../third_party/libyuv/include/libyuv/row.h | 218 +- .../third_party/libyuv/include/libyuv/scale.h | 25 + .../libyuv/include/libyuv/scale_row.h | 251 + .../libyuv/include/libyuv/scale_uv.h | 38 + .../libyuv/include/libyuv/version.h | 2 +- .../libyuv/include/libyuv/video_common.h | 16 +- .../jni/third_party/libyuv/source/compare.cc | 20 +- .../third_party/libyuv/source/compare_gcc.cc | 344 +- .../third_party/libyuv/source/compare_neon.cc | 70 +- .../libyuv/source/compare_neon64.cc | 68 +- .../jni/third_party/libyuv/source/convert.cc | 800 +- .../third_party/libyuv/source/convert_argb.cc | 1761 +- .../third_party/libyuv/source/convert_from.cc | 958 +- .../libyuv/source/convert_from_argb.cc | 594 +- .../third_party/libyuv/source/convert_jpeg.cc | 134 + .../libyuv/source/convert_to_argb.cc | 6 - .../libyuv/source/convert_to_i420.cc | 5 - .../jni/third_party/libyuv/source/cpu_id.cc | 56 +- .../libyuv/source/planar_functions.cc | 1065 +- .../jni/third_party/libyuv/source/rotate.cc | 90 +- .../third_party/libyuv/source/rotate_argb.cc | 111 +- .../third_party/libyuv/source/rotate_gcc.cc | 540 +- .../third_party/libyuv/source/rotate_neon.cc | 182 +- .../libyuv/source/rotate_neon64.cc | 265 +- .../jni/third_party/libyuv/source/row_any.cc | 97 +- .../third_party/libyuv/source/row_common.cc | 674 +- .../jni/third_party/libyuv/source/row_gcc.cc | 5933 ++--- .../jni/third_party/libyuv/source/row_mmi.cc | 2956 +-- .../jni/third_party/libyuv/source/row_msa.cc | 590 +- .../jni/third_party/libyuv/source/row_neon.cc | 2268 +- .../third_party/libyuv/source/row_neon64.cc | 2713 ++- .../jni/third_party/libyuv/source/row_win.cc | 15 +- .../jni/third_party/libyuv/source/scale.cc | 141 +- .../third_party/libyuv/source/scale_any.cc | 118 +- .../third_party/libyuv/source/scale_argb.cc | 134 +- .../third_party/libyuv/source/scale_common.cc | 247 +- .../third_party/libyuv/source/scale_gcc.cc | 1400 +- .../third_party/libyuv/source/scale_neon.cc | 708 +- .../third_party/libyuv/source/scale_neon64.cc | 888 +- .../jni/third_party/libyuv/source/scale_uv.cc | 891 + TMessagesProj/jni/voip/CMakeLists.txt | 44 +- .../org_telegram_messenger_voip_Instance.cpp | 218 +- .../jni/voip/tgcalls/CryptoHelper.cpp | 1 + TMessagesProj/jni/voip/tgcalls/Instance.h | 7 +- .../jni/voip/tgcalls/InstanceImpl.cpp | 12 +- .../jni/voip/tgcalls/LogSinkImpl.cpp | 8 +- TMessagesProj/jni/voip/tgcalls/LogSinkImpl.h | 4 +- TMessagesProj/jni/voip/tgcalls/Manager.cpp | 12 +- TMessagesProj/jni/voip/tgcalls/Manager.h | 2 + .../jni/voip/tgcalls/MediaManager.cpp | 84 + TMessagesProj/jni/voip/tgcalls/MediaManager.h | 6 + .../jni/voip/tgcalls/NetworkManager.cpp | 47 + .../jni/voip/tgcalls/NetworkManager.h | 2 + .../voip/tgcalls/group/GroupInstanceImpl.cpp | 2125 ++ .../voip/tgcalls/group/GroupInstanceImpl.h | 120 + .../tgcalls/legacy/InstanceImplLegacy.cpp | 2 +- .../reference/InstanceImplReference.cpp | 2 +- .../voip/webrtc/api/adaptation/resource.cc | 3 + .../jni/voip/webrtc/api/array_view.h | 13 + .../webrtc/api/audio/audio_frame_processor.h | 43 + .../webrtc/api/audio/echo_canceller3_config.h | 6 +- .../api/audio/echo_canceller3_config_json.cc | 13 +- .../api/audio_codecs/audio_decoder_factory.h | 2 + .../api/audio_codecs/audio_encoder_factory.h | 2 + .../audio_codecs/ilbc/audio_encoder_ilbc.cc | 2 +- .../api/create_peerconnection_factory.cc | 7 +- .../api/create_peerconnection_factory.h | 4 +- .../jni/voip/webrtc/api/media_stream_proxy.h | 2 +- .../webrtc/{pc => api}/media_stream_track.h | 9 +- .../webrtc/api/media_stream_track_proxy.h | 8 +- .../jni/voip/webrtc/api/media_types.cc | 8 +- .../jni/voip/webrtc/api/media_types.h | 7 +- .../jni/voip/webrtc/api/neteq/neteq.h | 5 +- .../voip/webrtc/api/neteq/neteq_controller.h | 21 +- .../numerics/samples_stats_counter.cc | 3 +- .../numerics/samples_stats_counter.h | 10 +- .../webrtc/api/peer_connection_interface.h | 44 +- .../voip/webrtc/api/peer_connection_proxy.h | 1 + TMessagesProj/jni/voip/webrtc/api/proxy.cc | 25 - TMessagesProj/jni/voip/webrtc/api/proxy.h | 53 +- TMessagesProj/jni/voip/webrtc/api/rtc_error.h | 2 +- .../rtc_event_log/rtc_event_log_factory.cc | 4 + .../jni/voip/webrtc/api/rtp_headers.h | 3 +- .../jni/voip/webrtc/api/rtp_parameters.cc | 8 +- .../jni/voip/webrtc/api/rtp_parameters.h | 7 + .../voip/webrtc/api/rtp_receiver_interface.h | 4 +- .../voip/webrtc/api/rtp_sender_interface.h | 4 +- .../webrtc/api/rtp_transceiver_interface.h | 3 +- .../voip/webrtc/api/stats/rtc_stats_report.h | 4 +- .../voip/webrtc/api/stats/rtcstats_objects.h | 1 + .../webrtc/api/test/compile_all_headers.cc | 3 + ...connection_quality_test_frame_generator.cc | 108 + ..._connection_quality_test_frame_generator.h | 45 + .../webrtc/api/test/dummy_peer_connection.h | 28 +- .../api/test/frame_generator_interface.cc | 34 + .../api/test/frame_generator_interface.h | 3 +- .../voip/webrtc/api/test/mock_data_channel.h | 60 + .../api/test/mock_media_stream_interface.h | 89 + .../mock_peer_connection_factory_interface.h | 2 +- .../webrtc/api/test/mock_rtp_transceiver.h | 85 + .../api/test/neteq_simulator_factory.cc | 35 +- .../webrtc/api/test/neteq_simulator_factory.h | 4 + .../network_emulation_interfaces.h | 43 +- .../api/test/network_emulation_manager.h | 55 +- .../webrtc/api/test/simulcast_test_fixture.h | 2 + .../webrtc/api/test/videocodec_test_fixture.h | 3 + .../webrtc/api/test/videocodec_test_stats.h | 1 + .../webrtc/api/transport/network_control.h | 48 +- .../sctp_transport_factory_interface.h | 42 + .../jni/voip/webrtc/api/transport/stun.cc | 58 +- .../jni/voip/webrtc/api/transport/stun.h | 14 +- .../jni/voip/webrtc/api/uma_metrics.h | 177 +- ...builtin_video_bitrate_allocator_factory.cc | 12 +- .../voip/webrtc/api/video/encoded_image.cc | 2 +- .../jni/voip/webrtc/api/video/encoded_image.h | 27 +- .../jni/voip/webrtc/api/video/nv12_buffer.cc | 157 + .../jni/voip/webrtc/api/video/nv12_buffer.h | 85 + .../test/mock_recordable_encoded_frame.h | 34 - .../webrtc/api/video/video_codec_constants.h | 1 + .../jni/voip/webrtc/api/video/video_frame.h | 11 + .../webrtc/api/video/video_frame_buffer.cc | 56 + .../webrtc/api/video/video_frame_buffer.h | 71 + .../api/video/video_layers_allocation.h | 77 + .../webrtc/api/video/video_stream_decoder.h | 12 +- .../video/video_stream_encoder_interface.h | 12 +- .../api/video/video_stream_encoder_settings.h | 11 + .../jni/voip/webrtc/api/video/video_timing.h | 24 + .../webrtc/api/video_codecs/spatial_layer.cc | 25 + .../webrtc/api/video_codecs/spatial_layer.h | 32 + .../webrtc/api/video_codecs/video_codec.cc | 12 +- .../webrtc/api/video_codecs/video_codec.h | 17 +- .../webrtc/api/video_codecs/video_encoder.cc | 29 +- .../webrtc/api/video_codecs/video_encoder.h | 34 +- .../api/video_codecs/video_encoder_config.cc | 1 + .../api/video_codecs/video_encoder_config.h | 2 + .../api/video_codecs/video_encoder_factory.h | 2 - ...video_encoder_software_fallback_wrapper.cc | 18 +- .../webrtc/api/video_track_source_proxy.h | 4 +- .../jni/voip/webrtc/api/voip/voip_dtmf.h | 67 + .../jni/voip/webrtc/api/voip/voip_engine.h | 13 + .../webrtc/api/voip/voip_engine_factory.cc | 17 +- .../webrtc/api/voip/voip_engine_factory.h | 3 - .../voip/webrtc/api/voip/voip_statistics.h | 44 + .../webrtc/api/voip/voip_volume_control.h | 57 + .../voip/webrtc/audio/audio_receive_stream.cc | 15 +- .../voip/webrtc/audio/audio_receive_stream.h | 19 +- .../voip/webrtc/audio/audio_send_stream.cc | 30 +- .../jni/voip/webrtc/audio/audio_send_stream.h | 8 +- .../jni/voip/webrtc/audio/audio_state.cc | 4 +- .../jni/voip/webrtc/audio/audio_state.h | 8 +- .../voip/webrtc/audio/audio_transport_impl.cc | 52 +- .../voip/webrtc/audio/audio_transport_impl.h | 22 +- .../jni/voip/webrtc/audio/channel_receive.cc | 14 +- .../jni/voip/webrtc/audio/channel_receive.h | 5 +- .../webrtc/audio/mock_voe_channel_proxy.h | 7 +- .../voip/webrtc/audio/voip/audio_channel.cc | 30 + .../voip/webrtc/audio/voip/audio_channel.h | 30 + .../voip/webrtc/audio/voip/audio_egress.cc | 6 + .../jni/voip/webrtc/audio/voip/audio_egress.h | 14 + .../voip/webrtc/audio/voip/audio_ingress.cc | 10 +- .../voip/webrtc/audio/voip/audio_ingress.h | 20 +- .../jni/voip/webrtc/audio/voip/voip_core.cc | 275 +- .../jni/voip/webrtc/audio/voip/voip_core.h | 83 +- .../task/sequence_manager/test/fake_task.cc | 47 - .../task/sequence_manager/test/fake_task.h | 33 - .../sequence_manager/test/mock_time_domain.cc | 43 - .../sequence_manager/test/mock_time_domain.h | 39 - .../test/mock_time_message_pump.cc | 88 - .../test/mock_time_message_pump.h | 86 - .../test/sequence_manager_for_test.cc | 102 - .../test/sequence_manager_for_test.h | 69 - .../sequence_manager/test/test_task_queue.cc | 23 - .../sequence_manager/test/test_task_queue.h | 33 - .../test/test_task_time_observer.h | 23 - TMessagesProj/jni/voip/webrtc/call/OWNERS | 1 + .../call/adaptation/adaptation_constraint.h | 4 +- .../degradation_preference_provider.h | 1 - .../resource_adaptation_processor.cc | 74 +- .../resource_adaptation_processor.h | 33 +- .../resource_adaptation_processor_interface.h | 3 +- .../call/adaptation/video_stream_adapter.cc | 71 +- .../call/adaptation/video_stream_adapter.h | 27 +- .../voip/webrtc/call/audio_receive_stream.h | 3 +- .../jni/voip/webrtc/call/audio_send_stream.cc | 3 + .../jni/voip/webrtc/call/audio_state.h | 4 + TMessagesProj/jni/voip/webrtc/call/call.cc | 32 +- TMessagesProj/jni/voip/webrtc/call/call.h | 2 + .../jni/voip/webrtc/call/call_perf_tests.cc | 32 +- .../jni/voip/webrtc/call/degraded_call.cc | 4 + .../jni/voip/webrtc/call/degraded_call.h | 2 + .../voip/webrtc/call/rtp_payload_params.cc | 3 +- .../call/rtp_transport_controller_send.cc | 23 +- .../call/rtp_transport_controller_send.h | 2 + .../rtp_transport_controller_send_interface.h | 3 + .../jni/voip/webrtc/call/rtp_video_sender.cc | 51 +- .../jni/voip/webrtc/call/rtp_video_sender.h | 6 +- .../webrtc/call/rtp_video_sender_interface.h | 3 + .../jni/voip/webrtc/call/simulated_network.cc | 1 + TMessagesProj/jni/voip/webrtc/call/syncable.h | 2 +- .../voip/webrtc/call/video_receive_stream.h | 1 + .../jni/voip/webrtc/call/video_send_stream.cc | 1 + .../jni/voip/webrtc/call/video_send_stream.h | 1 + .../webrtc/common_audio/fir_filter_avx2.cc | 88 + .../webrtc/common_audio/fir_filter_avx2.h | 41 + .../webrtc/common_audio/fir_filter_factory.cc | 8 +- .../common_audio/resampler/sinc_resampler.cc | 54 +- .../common_audio/resampler/sinc_resampler.h | 6 +- .../resampler/sinc_resampler_avx2.cc | 66 + .../webrtc/common_audio/smoothing_filter.h | 8 +- .../ooura/fft_size_128/ooura_fft.cc | 2 +- .../webrtc/common_audio/vad/vad_unittest.h | 48 + .../voip/webrtc/common_audio/wav_header.cc | 6 +- .../webrtc/common_audio/window_generator.h | 9 +- .../voip/webrtc/common_video/frame_counts.h | 32 + .../jni/voip/webrtc/common_video/h264/OWNERS | 1 + .../common_video/h264/sps_vui_rewriter.cc | 11 +- .../common_video/h264/sps_vui_rewriter.h | 5 +- .../webrtc/common_video/i420_buffer_pool.cc | 106 - ...uffer_pool.h => video_frame_buffer_pool.h} | 50 +- .../common_video/video_frame_buffer_pool.cc | 178 + .../encoder/rtc_event_log_encoder_legacy.cc | 8 +- .../rtc_event_log_encoder_new_format.cc | 26 +- .../rtc_event_log_encoder_new_format.h | 5 +- .../logging/rtc_event_log/logged_events.cc | 8 +- .../logging/rtc_event_log/logged_events.h | 14 +- .../logging/rtc_event_log/rtc_event_log.pb.cc | 9708 -------- .../logging/rtc_event_log/rtc_event_log.pb.h | 6496 ------ .../rtc_event_log/rtc_event_log2.pb.cc | 18636 ---------------- .../logging/rtc_event_log/rtc_event_log2.pb.h | 14921 ------------- .../rtc_event_log/rtc_event_log_impl.cc | 6 + .../rtc_event_log/rtc_event_log_parser.cc | 64 +- .../rtc_event_log/rtc_event_log_parser.h | 11 +- .../rtc_event_log_unittest_helper.cc | 1313 ++ .../rtc_event_log_unittest_helper.h | 325 + .../webrtc/media/base/fake_media_engine.cc | 3 +- .../webrtc/media/base/fake_media_engine.h | 2 +- .../media/base/fake_network_interface.h | 2 +- .../voip/webrtc/media/base/media_channel.h | 6 +- .../voip/webrtc/media/base/media_constants.cc | 3 +- .../voip/webrtc/media/base/media_constants.h | 3 +- .../voip/webrtc/media/base/media_engine.cc | 13 +- .../jni/voip/webrtc/media/base/media_engine.h | 6 + .../voip/webrtc/media/base/rtp_data_engine.cc | 4 +- .../jni/voip/webrtc/media/base/rtp_utils.cc | 1 + .../voip/webrtc/media/base/video_adapter.cc | 18 + .../voip/webrtc/media/base/video_adapter.h | 13 +- .../media/engine/fake_video_codec_factory.cc | 1 - .../webrtc/media/engine/fake_webrtc_call.cc | 3 +- .../webrtc/media/engine/fake_webrtc_call.h | 9 +- .../jni/voip/webrtc/media/engine/simulcast.cc | 59 +- .../jni/voip/webrtc/media/engine/simulcast.h | 10 +- .../media/engine/simulcast_encoder_adapter.cc | 44 +- .../media/engine/simulcast_encoder_adapter.h | 3 +- .../media/engine/webrtc_media_engine.cc | 23 +- .../webrtc/media/engine/webrtc_media_engine.h | 10 +- .../media/engine/webrtc_video_engine.cc | 429 +- .../webrtc/media/engine/webrtc_video_engine.h | 48 +- .../media/engine/webrtc_voice_engine.cc | 95 +- .../webrtc/media/engine/webrtc_voice_engine.h | 38 +- .../voip/webrtc/media/sctp/sctp_transport.cc | 104 +- .../voip/webrtc/media/sctp/sctp_transport.h | 3 +- .../media/sctp/sctp_transport_internal.h | 12 - .../async_audio_processing.cc | 61 + .../async_audio_processing.h | 76 + .../modules/audio_coding/acm2/acm_receiver.cc | 41 +- .../modules/audio_coding/acm2/acm_receiver.h | 3 +- .../bitrate_controller.cc | 5 - .../codecs/ilbc/audio_encoder_ilbc.cc | 4 +- .../modules/audio_coding/codecs/ilbc/ilbc.c | 5 +- .../codecs/isac/audio_encoder_isac_t.h | 2 +- .../codecs/isac/fix/source/isacfix.c | 1 - .../codecs/opus/audio_encoder_opus.cc | 24 +- .../codecs/opus/audio_encoder_opus.h | 1 + .../audio_coding/codecs/opus/opus_fec_test.cc | 250 + .../codecs/opus/opus_interface.cc | 2 +- .../codecs/opus/opus_speed_test.cc | 147 + .../codecs/opus/test/audio_ring_buffer.cc | 76 - .../codecs/opus/test/audio_ring_buffer.h | 57 - .../audio_coding/codecs/opus/test/blocker.cc | 215 - .../audio_coding/codecs/opus/test/blocker.h | 127 - .../codecs/opus/test/lapped_transform.cc | 100 - .../codecs/opus/test/lapped_transform.h | 175 - .../codecs/tools/audio_codec_speed_test.cc | 126 + .../codecs/tools/audio_codec_speed_test.h | 93 + .../include/audio_coding_module_typedefs.h | 12 - .../audio_coding/neteq/buffer_level_filter.cc | 8 +- .../audio_coding/neteq/buffer_level_filter.h | 8 +- .../audio_coding/neteq/decision_logic.cc | 126 +- .../audio_coding/neteq/decision_logic.h | 30 +- .../audio_coding/neteq/delay_manager.cc | 359 +- .../audio_coding/neteq/delay_manager.h | 114 +- .../neteq/mock/mock_buffer_level_filter.h | 28 + .../neteq/mock/mock_delay_manager.h | 43 + .../neteq/mock/mock_neteq_controller.h | 9 +- .../modules/audio_coding/neteq/neteq_impl.cc | 65 +- .../modules/audio_coding/neteq/neteq_impl.h | 5 + .../neteq/red_payload_splitter.cc | 35 +- .../audio_coding/neteq/red_payload_splitter.h | 3 + .../neteq/statistics_calculator.cc | 28 +- .../neteq/statistics_calculator.h | 19 +- .../audio_device/android/aaudio_recorder.cc | 1 - .../android/audio_device_template.h | 47 +- .../audio_device/android/audio_record_jni.cc | 3 +- .../include/audio_device_factory.cc | 2 +- .../include/audio_device_factory.h | 6 +- .../linux/audio_device_alsa_linux.cc | 88 +- .../linux/audio_device_alsa_linux.h | 31 +- .../linux/audio_device_pulse_linux.h | 19 +- .../linux/audio_mixer_manager_alsa_linux.cc | 18 +- .../linux/audio_mixer_manager_alsa_linux.h | 20 +- .../modules/audio_mixer/audio_mixer_impl.cc | 124 +- .../modules/audio_mixer/audio_mixer_impl.h | 37 +- .../default_output_rate_calculator.cc | 6 +- .../default_output_rate_calculator.h | 5 +- .../modules/audio_mixer/frame_combiner.cc | 15 +- .../modules/audio_mixer/frame_combiner.h | 5 +- .../audio_mixer/output_rate_calculator.h | 7 +- .../aec3/adaptive_fir_filter.h | 15 + .../aec3/adaptive_fir_filter_avx2.cc | 187 + .../aec3/adaptive_fir_filter_erl.cc | 1 - .../aec3/adaptive_fir_filter_erl.h | 4 + .../aec3/adaptive_fir_filter_erl_avx2.cc | 37 + .../audio_processing/aec3/aec3_common.cc | 4 +- .../audio_processing/aec3/aec3_common.h | 4 +- .../modules/audio_processing/aec3/aec3_fft.cc | 2 +- .../audio_processing/aec3/aec_state.cc | 126 +- .../modules/audio_processing/aec3/aec_state.h | 48 +- .../audio_processing/aec3/echo_canceller3.cc | 20 +- .../aec3/echo_path_variability.h | 2 - .../audio_processing/aec3/echo_remover.cc | 6 +- .../aec3/echo_remover_metrics.cc | 93 +- .../aec3/echo_remover_metrics.h | 3 - .../modules/audio_processing/aec3/fft_data.h | 3 + .../audio_processing/aec3/fft_data_avx2.cc | 33 + .../audio_processing/aec3/filter_analyzer.cc | 8 +- .../audio_processing/aec3/filter_analyzer.h | 11 +- .../audio_processing/aec3/matched_filter.h | 17 +- .../aec3/matched_filter_avx2.cc | 132 + .../aec3/matched_filter_lag_aggregator.h | 9 +- .../audio_processing/aec3/render_buffer.h | 7 +- .../aec3/render_delay_buffer.cc | 8 +- .../aec3/render_delay_controller.cc | 8 +- .../aec3/residual_echo_estimator.cc | 54 +- .../aec3/residual_echo_estimator.h | 1 - .../aec3/subtractor_output_analyzer.cc | 11 +- .../aec3/subtractor_output_analyzer.h | 1 + .../audio_processing/aec3/suppression_gain.cc | 62 +- .../audio_processing/aec3/suppression_gain.h | 2 + .../audio_processing/aec3/transparent_mode.cc | 239 + .../audio_processing/aec3/transparent_mode.h | 47 + .../audio_processing/aec3/vector_math.h | 11 + .../audio_processing/aec3/vector_math_avx2.cc | 82 + .../aec_dump/aec_dump_impl.cc | 6 + .../audio_processing/agc2/adaptive_agc.cc | 79 +- .../audio_processing/agc2/adaptive_agc.h | 10 +- .../agc2/adaptive_digital_gain_applier.cc | 117 +- .../agc2/adaptive_digital_gain_applier.h | 62 +- .../agc2/adaptive_mode_level_estimator.cc | 216 +- .../agc2/adaptive_mode_level_estimator.h | 63 +- .../agc2/adaptive_mode_level_estimator_agc.cc | 6 +- .../agc2/adaptive_mode_level_estimator_agc.h | 2 +- .../audio_processing/agc2/agc2_common.cc | 58 - .../audio_processing/agc2/agc2_common.h | 14 +- .../audio_processing/agc2/down_sampler.h | 8 +- .../agc2/noise_spectrum_estimator.h | 8 +- .../agc2/rnn_vad/auto_correlation.cc | 21 +- .../agc2/rnn_vad/auto_correlation.h | 2 +- .../audio_processing/agc2/rnn_vad/common.cc | 2 +- .../audio_processing/agc2/rnn_vad/common.h | 50 +- .../agc2/rnn_vad/features_extraction.cc | 9 +- .../agc2/rnn_vad/features_extraction.h | 3 +- .../agc2/rnn_vad/lp_residual.cc | 93 +- .../agc2/rnn_vad/lp_residual.h | 2 +- .../agc2/rnn_vad/pitch_info.h | 29 - .../agc2/rnn_vad/pitch_search.cc | 59 +- .../agc2/rnn_vad/pitch_search.h | 21 +- .../agc2/rnn_vad/pitch_search_internal.cc | 620 +- .../agc2/rnn_vad/pitch_search_internal.h | 112 +- .../agc2/rnn_vad/ring_buffer.h | 11 +- .../audio_processing/agc2/rnn_vad/rnn.cc | 86 +- .../audio_processing/agc2/rnn_vad/rnn.h | 28 +- .../agc2/rnn_vad/rnn_vad_tool.cc | 7 +- .../agc2/rnn_vad/sequence_buffer.h | 6 +- .../agc2/rnn_vad/spectral_features.cc | 23 +- .../rnn_vad/spectral_features_internal.cc | 17 +- .../agc2/rnn_vad/spectral_features_internal.h | 2 +- .../agc2/rnn_vad/symmetric_matrix_buffer.h | 15 +- .../agc2/rnn_vad/test_utils.cc | 24 +- .../agc2/rnn_vad/test_utils.h | 29 +- .../agc2/saturation_protector.cc | 168 +- .../agc2/saturation_protector.h | 93 +- .../agc2/signal_classifier.cc | 2 +- .../audio_processing/agc2/signal_classifier.h | 14 +- .../audio_processing/agc2/vad_with_level.cc | 116 +- .../audio_processing/agc2/vad_with_level.h | 52 +- .../audio_processing_builder_impl.cc | 8 +- .../audio_processing/audio_processing_impl.cc | 72 +- .../audio_processing/audio_processing_impl.h | 3 +- .../audio_processing/gain_controller2.cc | 50 +- .../audio_processing/gain_controller2.h | 2 - .../include/audio_processing.cc | 96 +- .../include/audio_processing.h | 37 +- .../modules/audio_processing/include/config.h | 2 - .../include/mock_audio_processing.h | 4 - .../logging/apm_data_dumper.h | 6 +- .../goog_cc/delay_based_bwe.h | 7 +- .../goog_cc/goog_cc_network_control.cc | 3 +- .../goog_cc/goog_cc_network_control.h | 8 +- .../goog_cc/send_side_bandwidth_estimation.cc | 24 +- .../goog_cc/send_side_bandwidth_estimation.h | 10 +- .../goog_cc/test/goog_cc_printer.cc | 199 - .../goog_cc/test/goog_cc_printer.h | 75 - .../receive_side_congestion_controller.h | 8 +- .../webrtc/modules/desktop_capture/OWNERS | 2 - ...blank_detector_desktop_capturer_wrapper.cc | 123 - .../blank_detector_desktop_capturer_wrapper.h | 78 - ...capture_result_desktop_capturer_wrapper.cc | 49 - .../capture_result_desktop_capturer_wrapper.h | 64 - .../desktop_capture/cropped_desktop_frame.cc | 64 - .../desktop_capture/cropped_desktop_frame.h | 33 - .../cropping_window_capturer.cc | 128 - .../cropping_window_capturer.h | 84 - .../cropping_window_capturer_win.cc | 300 - .../desktop_and_cursor_composer.cc | 247 - .../desktop_and_cursor_composer.h | 93 - .../desktop_capture_options.cc | 49 - .../desktop_capture/desktop_capture_options.h | 167 - .../desktop_capture/desktop_capture_types.h | 54 - .../desktop_capture/desktop_capturer.cc | 89 - .../desktop_capture/desktop_capturer.h | 159 - .../desktop_capturer_differ_wrapper.cc | 226 - .../desktop_capturer_differ_wrapper.h | 68 - .../desktop_capturer_wrapper.cc | 60 - .../desktop_capturer_wrapper.h | 48 - .../modules/desktop_capture/desktop_frame.cc | 204 - .../modules/desktop_capture/desktop_frame.h | 216 - .../desktop_frame_generator.cc | 184 - .../desktop_capture/desktop_frame_generator.h | 121 - .../desktop_capture/desktop_frame_rotation.cc | 117 - .../desktop_capture/desktop_frame_rotation.h | 52 - .../desktop_capture/desktop_frame_win.cc | 69 - .../desktop_capture/desktop_frame_win.h | 49 - .../desktop_capture/desktop_geometry.cc | 79 - .../desktop_capture/desktop_geometry.h | 169 - .../modules/desktop_capture/desktop_region.cc | 567 - .../modules/desktop_capture/desktop_region.h | 169 - .../modules/desktop_capture/differ_block.cc | 71 - .../modules/desktop_capture/differ_block.h | 42 - .../desktop_capture/differ_vector_sse2.cc | 102 - .../desktop_capture/differ_vector_sse2.h | 31 - .../desktop_capture/fake_desktop_capturer.cc | 84 - .../desktop_capture/fake_desktop_capturer.h | 76 - .../fallback_desktop_capturer_wrapper.cc | 183 - .../fallback_desktop_capturer_wrapper.h | 64 - .../full_screen_application_handler.cc | 30 - .../full_screen_application_handler.h | 48 - .../full_screen_window_detector.cc | 84 - .../full_screen_window_detector.h | 80 - .../linux/base_capturer_pipewire.cc | 890 - .../linux/base_capturer_pipewire.h | 168 - .../linux/mouse_cursor_monitor_x11.cc | 253 - .../linux/mouse_cursor_monitor_x11.h | 68 - .../linux/screen_capturer_pipewire.cc | 29 - .../linux/screen_capturer_pipewire.h | 33 - .../linux/screen_capturer_x11.cc | 480 - .../linux/screen_capturer_x11.h | 147 - .../desktop_capture/linux/shared_x_display.cc | 101 - .../desktop_capture/linux/shared_x_display.h | 83 - .../linux/window_capturer_pipewire.cc | 29 - .../linux/window_capturer_pipewire.h | 33 - .../linux/window_capturer_x11.cc | 247 - .../linux/window_capturer_x11.h | 74 - .../linux/window_finder_x11.cc | 52 - .../desktop_capture/linux/window_finder_x11.h | 35 - .../linux/window_list_utils.cc | 199 - .../desktop_capture/linux/window_list_utils.h | 56 - .../desktop_capture/linux/x_atom_cache.cc | 51 - .../desktop_capture/linux/x_atom_cache.h | 45 - .../desktop_capture/linux/x_error_trap.cc | 69 - .../desktop_capture/linux/x_error_trap.h | 39 - .../linux/x_server_pixel_buffer.cc | 379 - .../linux/x_server_pixel_buffer.h | 89 - .../linux/x_window_property.cc | 43 - .../desktop_capture/linux/x_window_property.h | 63 - .../mock_desktop_capturer_callback.cc | 23 - .../mock_desktop_capturer_callback.h | 38 - .../modules/desktop_capture/mouse_cursor.cc | 37 - .../modules/desktop_capture/mouse_cursor.h | 49 - .../desktop_capture/mouse_cursor_monitor.h | 111 - .../mouse_cursor_monitor_linux.cc | 54 - .../mouse_cursor_monitor_mac.mm | 214 - .../mouse_cursor_monitor_null.cc | 38 - .../mouse_cursor_monitor_win.cc | 216 - .../desktop_capture/resolution_tracker.cc | 34 - .../desktop_capture/resolution_tracker.h | 34 - .../modules/desktop_capture/rgba_color.cc | 61 - .../modules/desktop_capture/rgba_color.h | 59 - .../screen_capture_frame_queue.h | 80 - .../desktop_capture/screen_capturer_darwin.mm | 33 - .../desktop_capture/screen_capturer_helper.cc | 96 - .../desktop_capture/screen_capturer_helper.h | 90 - .../desktop_capture/screen_capturer_linux.cc | 42 - .../desktop_capture/screen_capturer_win.cc | 62 - .../modules/desktop_capture/screen_drawer.cc | 30 - .../modules/desktop_capture/screen_drawer.h | 79 - .../desktop_capture/screen_drawer_linux.cc | 185 - .../screen_drawer_lock_posix.cc | 58 - .../screen_drawer_lock_posix.h | 38 - .../desktop_capture/screen_drawer_mac.cc | 30 - .../desktop_capture/screen_drawer_win.cc | 209 - .../desktop_capture/shared_desktop_frame.cc | 59 - .../desktop_capture/shared_desktop_frame.h | 65 - .../modules/desktop_capture/shared_memory.cc | 24 - .../modules/desktop_capture/shared_memory.h | 81 - .../desktop_capture/window_capturer_linux.cc | 42 - .../desktop_capture/window_capturer_mac.mm | 198 - .../desktop_capture/window_capturer_null.cc | 71 - .../desktop_capture/window_capturer_win.cc | 31 - .../modules/desktop_capture/window_finder.cc | 20 - .../modules/desktop_capture/window_finder.h | 65 - .../desktop_capture/window_finder_mac.h | 37 - .../desktop_capture/window_finder_mac.mm | 52 - .../desktop_capture/window_finder_win.cc | 46 - .../desktop_capture/window_finder_win.h | 30 - .../modules/include/module_common_types.cc | 120 - .../modules/include/module_common_types.h | 32 - .../webrtc/modules/pacing/bitrate_prober.cc | 5 +- .../modules/pacing/pacing_controller.cc | 3 +- .../modules/pacing/task_queue_paced_sender.cc | 10 +- .../remote_bitrate_estimator/inter_arrival.h | 8 +- .../remote_bitrate_estimator_abs_send_time.h | 10 +- .../remote_bitrate_estimator_single_stream.h | 10 +- .../test/bwe_test_logging.h | 7 +- .../rtp_rtcp/include/rtp_rtcp_defines.h | 1 + .../modules/rtp_rtcp/mocks/mock_rtp_rtcp.h | 7 - .../source/create_video_rtp_depacketizer.cc | 1 + .../deprecated_rtp_sender_egress.cc | 8 +- .../source/rtcp_packet/compound_packet.cc | 11 +- .../source/rtcp_packet/compound_packet.h | 5 +- .../modules/rtp_rtcp/source/rtcp_sender.cc | 15 +- .../modules/rtp_rtcp/source/rtcp_sender.h | 8 +- .../modules/rtp_rtcp/source/rtp_format.cc | 7 +- .../modules/rtp_rtcp/source/rtp_format_h265.h | 1 - .../source/rtp_header_extension_map.cc | 2 + .../rtp_rtcp/source/rtp_header_extensions.cc | 4 +- .../rtp_rtcp/source/rtp_header_extensions.h | 8 +- .../modules/rtp_rtcp/source/rtp_packet.cc | 1 + .../rtp_rtcp/source/rtp_packet_history.h | 8 +- .../rtp_rtcp/source/rtp_packetizer_av1.cc | 13 +- .../rtp_rtcp/source/rtp_packetizer_av1.h | 4 +- .../modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 13 - .../modules/rtp_rtcp/source/rtp_rtcp_impl.h | 5 - .../modules/rtp_rtcp/source/rtp_rtcp_impl2.cc | 15 - .../modules/rtp_rtcp/source/rtp_rtcp_impl2.h | 5 - .../rtp_rtcp/source/rtp_rtcp_interface.h | 7 - .../modules/rtp_rtcp/source/rtp_sender.cc | 3 + .../modules/rtp_rtcp/source/rtp_sender.h | 7 +- .../rtp_rtcp/source/rtp_sender_audio.cc | 12 +- .../rtp_rtcp/source/rtp_sender_audio.h | 10 +- .../rtp_rtcp/source/rtp_sender_egress.cc | 18 +- .../rtp_rtcp/source/rtp_sender_video.cc | 191 +- .../rtp_rtcp/source/rtp_sender_video.h | 48 +- ...sender_video_frame_transformer_delegate.cc | 9 +- ..._sender_video_frame_transformer_delegate.h | 9 +- .../modules/rtp_rtcp/source/rtp_utility.cc | 4 + .../rtp_rtcp/source/rtp_video_header.h | 4 +- .../rtp_video_layers_allocation_extension.cc | 260 + .../rtp_video_layers_allocation_extension.h | 35 + .../modules/video_capture/device_info_impl.cc | 29 +- .../modules/video_capture/device_info_impl.h | 14 +- .../video_capture/linux/device_info_linux.h | 5 +- .../codecs/av1/libaom_av1_decoder.cc | 6 +- .../codecs/av1/libaom_av1_encoder.cc | 38 +- .../codecs/av1/libaom_av1_encoder.h | 2 +- .../codecs/av1/scalability_structure_l1t2.cc | 123 - .../codecs/av1/scalability_structure_l1t2.h | 48 - .../codecs/av1/scalability_structure_l1t3.cc | 109 - .../codecs/av1/scalability_structure_l1t3.h | 53 - .../codecs/av1/scalability_structure_l2t1.cc | 102 - .../codecs/av1/scalability_structure_l2t1.h | 43 - .../av1/scalability_structure_l2t1_key.cc | 107 - .../av1/scalability_structure_l2t1_key.h | 43 - .../codecs/av1/scalability_structure_l2t2.cc | 128 - .../codecs/av1/scalability_structure_l2t2.h | 53 - .../av1/scalability_structure_l2t2_key.cc | 130 - .../av1/scalability_structure_l2t2_key.h | 53 - .../scalability_structure_l2t2_key_shift.cc | 130 - .../codecs/av1/scalability_structure_l3t1.cc | 112 - .../codecs/av1/scalability_structure_l3t3.cc | 224 - .../codecs/av1/scalability_structure_l3t3.h | 49 - .../codecs/av1/scalability_structure_s2t1.cc | 93 - .../codecs/h264/h264_decoder_impl.cc | 28 +- .../codecs/h264/h264_decoder_impl.h | 10 +- .../codecs/h264/h264_encoder_impl.cc | 38 +- .../codecs/h264/h264_encoder_impl.h | 2 +- .../include/multiplex_encoder_adapter.h | 3 +- .../multiplex/multiplex_decoder_adapter.cc | 15 +- .../multiplex/multiplex_encoder_adapter.cc | 17 +- .../codecs/vp8/libvpx_interface.cc | 4 + .../codecs/vp8/libvpx_interface.h | 2 + .../codecs/vp8/libvpx_vp8_decoder.cc | 61 +- .../codecs/vp8/libvpx_vp8_decoder.h | 7 +- .../codecs/vp8/libvpx_vp8_encoder.cc | 252 +- .../codecs/vp8/libvpx_vp8_encoder.h | 7 +- .../codecs/vp8/temporal_layers_checker.cc | 1 + .../video_coding/codecs/vp9/svc_config.h | 2 +- .../codecs/vp9/svc_rate_allocator.h | 49 +- .../video_coding/codecs/vp9/vp9_impl.cc | 477 +- .../video_coding/codecs/vp9/vp9_impl.h | 30 +- .../modules/video_coding/decoder_database.cc | 8 +- .../modules/video_coding/encoded_frame.cc | 1 - .../modules/video_coding/encoded_frame.h | 8 +- .../modules/video_coding/frame_buffer.cc | 15 +- .../modules/video_coding/frame_buffer2.cc | 5 + .../modules/video_coding/frame_buffer2.h | 9 +- .../modules/video_coding/frame_object.cc | 6 +- .../modules/video_coding/frame_object.h | 4 + .../modules/video_coding/generic_decoder.cc | 43 +- .../modules/video_coding/generic_decoder.h | 11 + .../include/video_codec_interface.h | 4 +- .../include/video_coding_defines.h | 2 - .../modules/video_coding/jitter_buffer.cc | 3 +- .../modules/video_coding/packet_buffer.h | 4 +- .../webrtc/modules/video_coding/receiver.cc | 12 - .../create_scalability_structure.cc | 28 +- .../create_scalability_structure.h | 8 +- .../svc/scalability_structure_full_svc.cc | 285 + .../svc/scalability_structure_full_svc.h | 73 + .../svc/scalability_structure_key_svc.cc | 336 + .../svc/scalability_structure_key_svc.h | 107 + .../svc/scalability_structure_l1t2.cc | 32 + .../svc/scalability_structure_l1t2.h | 28 + .../svc/scalability_structure_l1t3.cc | 34 + .../svc/scalability_structure_l1t3.h | 34 + .../svc/scalability_structure_l2t1.cc | 33 + .../svc/scalability_structure_l2t1.h | 31 + .../scalability_structure_l2t1h.cc | 2 +- .../av1 => svc}/scalability_structure_l2t1h.h | 10 +- .../svc/scalability_structure_l2t2.cc | 36 + .../svc/scalability_structure_l2t2.h | 36 + .../scalability_structure_l2t2_key_shift.cc | 176 + .../scalability_structure_l2t2_key_shift.h | 25 +- .../svc/scalability_structure_l3t1.cc | 36 + .../av1 => svc}/scalability_structure_l3t1.h | 23 +- .../svc/scalability_structure_l3t3.cc | 49 + .../svc/scalability_structure_l3t3.h | 29 + .../svc/scalability_structure_s2t1.cc | 97 + .../av1 => svc}/scalability_structure_s2t1.h | 18 +- .../svc/scalability_structure_test_helpers.cc | 104 + .../svc/scalability_structure_test_helpers.h | 59 + .../av1 => svc}/scalable_video_controller.h | 14 +- .../scalable_video_controller_no_layering.cc | 14 +- .../scalable_video_controller_no_layering.h | 13 +- .../{codecs/vp9 => svc}/svc_rate_allocator.cc | 114 +- .../video_coding/svc/svc_rate_allocator.h | 69 + .../modules/video_coding/timestamp_map.cc | 9 + .../modules/video_coding/timestamp_map.h | 1 + .../webrtc/modules/video_coding/timing.cc | 50 +- .../voip/webrtc/modules/video_coding/timing.h | 25 +- .../video_coding/utility/ivf_file_reader.cc | 5 +- .../video_coding/utility/ivf_file_writer.cc | 6 + .../video_coding/utility/quality_scaler.cc | 10 +- .../utility/simulcast_rate_allocator.cc | 10 +- .../utility/simulcast_test_fixture_impl.cc | 915 + .../utility/simulcast_test_fixture_impl.h | 93 + .../video_coding/video_codec_initializer.cc | 14 +- .../modules/video_coding/video_receiver.cc | 5 +- .../video_processing/util/denoiser_filter.cc | 2 +- .../video_processing/video_denoiser.cc | 2 +- .../modules/video_processing/video_denoiser.h | 4 +- .../jni/voip/webrtc/p2p/base/connection.cc | 8 +- .../jni/voip/webrtc/p2p/base/connection.h | 4 +- .../voip/webrtc/p2p/base/dtls_transport.cc | 6 + .../jni/voip/webrtc/p2p/base/dtls_transport.h | 8 +- .../webrtc/p2p/base/p2p_transport_channel.cc | 38 +- .../webrtc/p2p/base/p2p_transport_channel.h | 7 + .../p2p_transport_channel_ice_field_trials.h | 6 + TMessagesProj/jni/voip/webrtc/p2p/base/port.h | 4 +- .../jni/voip/webrtc/p2p/base/pseudo_tcp.cc | 187 +- .../jni/voip/webrtc/p2p/base/pseudo_tcp.h | 51 +- .../jni/voip/webrtc/p2p/base/stun_request.h | 2 +- .../jni/voip/webrtc/p2p/base/turn_port.h | 10 + .../jni/voip/webrtc/p2p/base/turn_server.cc | 4 +- .../jni/voip/webrtc/p2p/base/turn_server.h | 2 +- .../webrtc/p2p/client/basic_port_allocator.h | 7 +- .../webrtc/p2p/client/turn_port_factory.cc | 4 + .../jni/voip/webrtc/pc/audio_rtp_receiver.cc | 10 +- .../jni/voip/webrtc/pc/audio_rtp_receiver.h | 5 +- .../jni/voip/webrtc/pc/audio_track.cc | 1 - .../jni/voip/webrtc/pc/audio_track.h | 11 +- TMessagesProj/jni/voip/webrtc/pc/channel.cc | 95 +- TMessagesProj/jni/voip/webrtc/pc/channel.h | 43 +- .../jni/voip/webrtc/pc/channel_interface.h | 1 + .../jni/voip/webrtc/pc/channel_manager.cc | 6 + .../jni/voip/webrtc/pc/channel_manager.h | 19 +- .../jni/voip/webrtc/pc/connection_context.cc | 147 + .../jni/voip/webrtc/pc/connection_context.h | 134 + .../voip/webrtc/pc/data_channel_controller.cc | 14 +- .../voip/webrtc/pc/data_channel_controller.h | 5 +- .../jni/voip/webrtc/pc/dtls_srtp_transport.h | 12 + .../jni/voip/webrtc/pc/dtls_transport.cc | 1 + .../jni/voip/webrtc/pc/ice_transport.h | 6 +- .../webrtc/pc/jsep_transport_controller.cc | 21 +- .../webrtc/pc/jsep_transport_controller.h | 9 +- .../jni/voip/webrtc/pc/media_session.cc | 97 +- .../jni/voip/webrtc/pc/media_session.h | 20 + .../jni/voip/webrtc/pc/media_stream.h | 2 +- .../jni/voip/webrtc/pc/peer_connection.cc | 5731 +---- .../jni/voip/webrtc/pc/peer_connection.h | 1081 +- ...r_connection_adaptation_integrationtest.cc | 161 + .../voip/webrtc/pc/peer_connection_factory.cc | 264 +- .../voip/webrtc/pc/peer_connection_factory.h | 83 +- .../pc/peer_connection_integrationtest.cc | 5650 ----- .../pc/peer_connection_message_handler.cc | 200 + .../pc/peer_connection_message_handler.h | 59 + .../jni/voip/webrtc/pc/remote_audio_source.cc | 8 +- .../jni/voip/webrtc/pc/rtc_stats_collector.cc | 58 +- .../jni/voip/webrtc/pc/rtc_stats_collector.h | 3 +- .../webrtc/pc/rtc_stats_integrationtest.cc | 2 + .../jni/voip/webrtc/pc/rtc_stats_traversal.cc | 3 +- .../jni/voip/webrtc/pc/rtp_data_channel.h | 1 - .../webrtc/pc/rtp_parameters_conversion.cc | 3 +- .../jni/voip/webrtc/pc/rtp_receiver.h | 4 + .../jni/voip/webrtc/pc/rtp_sender.cc | 7 +- TMessagesProj/jni/voip/webrtc/pc/rtp_sender.h | 8 +- .../jni/voip/webrtc/pc/rtp_transceiver.cc | 29 +- .../jni/voip/webrtc/pc/rtp_transceiver.h | 14 +- .../webrtc/pc/rtp_transmission_manager.cc | 685 + .../voip/webrtc/pc/rtp_transmission_manager.h | 267 + .../jni/voip/webrtc/pc/rtp_transport.cc | 5 + .../jni/voip/webrtc/pc/rtp_transport.h | 2 + .../jni/voip/webrtc/pc/sctp_data_channel.cc | 11 +- .../jni/voip/webrtc/pc/sctp_data_channel.h | 2 - .../jni/voip/webrtc/pc/sdp_offer_answer.cc | 5027 +++++ .../jni/voip/webrtc/pc/sdp_offer_answer.h | 676 + .../jni/voip/webrtc/pc/sdp_state_provider.h | 54 + .../jni/voip/webrtc/pc/session_description.h | 38 +- .../jni/voip/webrtc/pc/stats_collector.cc | 4 +- .../jni/voip/webrtc/pc/stats_collector.h | 12 +- .../webrtc/pc/stats_collector_interface.h | 43 + .../jni/voip/webrtc/pc/transceiver_list.cc | 67 + .../jni/voip/webrtc/pc/transceiver_list.h | 100 + .../jni/voip/webrtc/pc/usage_pattern.cc | 49 + .../jni/voip/webrtc/pc/usage_pattern.h | 75 + .../jni/voip/webrtc/pc/video_rtp_receiver.cc | 8 +- .../jni/voip/webrtc/pc/video_rtp_receiver.h | 5 +- .../jni/voip/webrtc/pc/video_track.h | 2 +- .../jni/voip/webrtc/pc/webrtc_sdp.cc | 47 +- .../pc/webrtc_session_description_factory.cc | 72 +- .../pc/webrtc_session_description_factory.h | 25 +- .../jni/voip/webrtc/rtc_base/async_invoker.h | 2 +- .../jni/voip/webrtc/rtc_base/buffer_queue.cc | 40 +- .../jni/voip/webrtc/rtc_base/buffer_queue.h | 29 +- .../jni/voip/webrtc/rtc_base/callback.h.pump | 104 + .../jni/voip/webrtc/rtc_base/callback_list.cc | 48 + .../jni/voip/webrtc/rtc_base/callback_list.h | 167 + .../jni/voip/webrtc/rtc_base/checks.cc | 73 +- .../jni/voip/webrtc/rtc_base/checks.h | 24 + .../voip/webrtc/rtc_base/constructor_magic.h | 16 +- .../rtc_base/deprecated/signal_thread.h | 16 +- .../experiments/cpu_speed_experiment.cc | 72 +- .../experiments/cpu_speed_experiment.h | 46 +- .../experiments/quality_scaler_settings.cc | 25 +- .../experiments/quality_scaler_settings.h | 4 + .../experiments/rate_control_settings.cc | 36 +- .../experiments/rate_control_settings.h | 14 +- .../jni/voip/webrtc/rtc_base/fake_network.h | 3 +- .../jni/voip/webrtc/rtc_base/gunit.cc | 42 + .../jni/voip/webrtc/rtc_base/gunit.h | 168 + .../jni/voip/webrtc/rtc_base/location.h | 1 - .../jni/voip/webrtc/rtc_base/logging.cc | 16 +- .../jni/voip/webrtc/rtc_base/logging.h | 50 +- .../webrtc/rtc_base/memory/fifo_buffer.cc | 8 +- .../voip/webrtc/rtc_base/memory/fifo_buffer.h | 12 +- .../voip/webrtc/rtc_base/message_handler.cc | 11 +- .../voip/webrtc/rtc_base/message_handler.h | 18 +- .../jni/voip/webrtc/rtc_base/network.cc | 15 +- .../jni/voip/webrtc/rtc_base/network.h | 2 +- .../voip/webrtc/rtc_base/network_monitor.cc | 38 +- .../voip/webrtc/rtc_base/network_monitor.h | 46 +- .../rtc_base/network_monitor_factory.cc | 24 - .../webrtc/rtc_base/network_monitor_factory.h | 9 - .../webrtc/rtc_base/numerics/math_utils.h | 11 +- .../rtc_base/numerics/running_statistics.h | 8 +- .../rtc_base/numerics/safe_conversions.h | 6 +- .../webrtc/rtc_base/numerics/sample_stats.h | 2 +- .../voip/webrtc/rtc_base/openssl_adapter.h | 3 +- .../webrtc/rtc_base/openssl_certificate.cc | 18 +- .../webrtc/rtc_base/openssl_stream_adapter.cc | 127 +- .../webrtc/rtc_base/openssl_stream_adapter.h | 20 +- .../voip/webrtc/rtc_base/operations_chain.cc | 20 +- .../voip/webrtc/rtc_base/operations_chain.h | 18 +- .../webrtc/rtc_base/physical_socket_server.cc | 199 +- .../webrtc/rtc_base/physical_socket_server.h | 33 +- .../jni/voip/webrtc/rtc_base/random.h | 7 +- .../jni/voip/webrtc/rtc_base/rate_limiter.h | 8 +- .../webrtc/rtc_base/rolling_accumulator.h | 4 +- .../rtc_base/rtc_certificate_generator.cc | 86 +- .../jni/voip/webrtc/rtc_base/ssl_roots.h | 128 +- .../voip/webrtc/rtc_base/ssl_stream_adapter.h | 10 +- .../jni/voip/webrtc/rtc_base/stream.cc | 18 - .../jni/voip/webrtc/rtc_base/stream.h | 21 +- .../jni/voip/webrtc/rtc_base/string_utils.cc | 6 - .../jni/voip/webrtc/rtc_base/string_utils.h | 2 - .../voip/webrtc/rtc_base/stringize_macros.h | 38 - .../jni/voip/webrtc/rtc_base/swap_queue.h | 6 +- .../webrtc/rtc_base/synchronization/mutex.h | 40 +- .../rtc_base/synchronization/rw_lock_posix.cc | 52 - .../rtc_base/synchronization/rw_lock_posix.h | 40 - .../rtc_base/synchronization/rw_lock_win.cc | 41 - .../rtc_base/synchronization/rw_lock_win.h | 38 - .../synchronization/rw_lock_wrapper.cc | 29 - .../synchronization/rw_lock_wrapper.h | 66 - .../jni/voip/webrtc/rtc_base/system/assume.h | 73 + .../jni/voip/webrtc/rtc_base/thread.cc | 92 +- .../jni/voip/webrtc/rtc_base/thread.h | 13 +- .../rtc_base/time/timestamp_extrapolator.cc | 14 +- .../rtc_base/time/timestamp_extrapolator.h | 5 +- .../voip/webrtc/rtc_base/untyped_function.h | 324 + .../webrtc/rtc_base/virtual_socket_server.h | 2 +- .../jni/voip/webrtc/rtc_base/weak_ptr.h | 5 +- .../rtc_base/win/get_activation_factory.cc | 49 + .../rtc_base/win/get_activation_factory.h | 51 + .../jni/voip/webrtc/rtc_base/win/hstring.cc | 62 + .../jni/voip/webrtc/rtc_base/win/hstring.h | 30 + .../rtc_base/win/scoped_com_initializer.cc | 54 + .../rtc_base/win/scoped_com_initializer.h | 58 + .../webrtc/rtc_base/win/windows_version.cc | 6 +- .../webrtc/rtc_base/win/windows_version.h | 2 + .../CandidatePairChangeEvent_jni.h | 7 +- .../RtpTransceiver_jni.h | 4 +- .../generated_video_jni/EncodedImage_jni.h | 28 +- .../android/native_api/base/network_monitor.h | 18 - .../jni/voip/webrtc/sdk/android/src/jni/DEPS | 15 - .../src/jni/android_network_monitor.cc | 112 +- .../android/src/jni/android_network_monitor.h | 40 +- .../src/jni/android_video_track_source.h | 2 - .../sdk/android/src/jni/audio_device/DEPS | 4 - .../src/jni/audio_device/aaudio_recorder.cc | 2 - .../jni/audio_device/audio_device_module.cc | 45 +- .../sdk/android/src/jni/encoded_image.cc | 4 +- .../sdk/android/src/jni/pc/peer_connection.cc | 3 +- .../sdk/android/src/jni/pc/rtp_transceiver.cc | 15 +- .../android/src/jni/video_decoder_wrapper.cc | 11 - .../android/src/jni/video_decoder_wrapper.h | 4 - .../android/src/jni/video_encoder_wrapper.cc | 37 +- .../android/src/jni/video_encoder_wrapper.h | 6 +- .../webrtc/sdk/android/src/jni/video_frame.cc | 4 +- .../webrtc/sdk/android/src/jni/video_frame.h | 13 +- .../jni/voip/webrtc/stats/rtc_stats.cc | 14 + .../jni/voip/webrtc/stats/rtc_stats_report.cc | 9 +- .../jni/voip/webrtc/stats/rtcstats_objects.cc | 3 + .../webrtc/system_wrappers/include/clock.h | 10 +- .../include/cpu_features_wrapper.h | 18 +- .../webrtc/system_wrappers/source/clock.cc | 16 +- .../system_wrappers/source/cpu_features.cc | 53 +- ...ures_android.c => cpu_features_android.cc} | 6 +- ...features_linux.c => cpu_features_linux.cc} | 29 +- .../video/adaptation/balanced_constraint.cc | 58 + .../video/adaptation/balanced_constraint.h | 50 + .../video/adaptation/bitrate_constraint.cc | 65 + .../video/adaptation/bitrate_constraint.h | 52 + .../adaptation/quality_scaler_resource.cc | 38 +- .../adaptation/quality_scaler_resource.h | 14 +- .../video_stream_encoder_resource_manager.cc | 310 +- .../video_stream_encoder_resource_manager.h | 104 +- .../voip/webrtc/video/alignment_adjuster.cc | 121 + .../voip/webrtc/video/alignment_adjuster.h | 38 + .../webrtc/video/buffered_frame_decryptor.cc | 2 +- .../video/frame_encode_metadata_writer.cc | 2 +- .../jni/voip/webrtc/video/full_stack_tests.cc | 185 +- .../webrtc/video/full_stack_tests_plot.py | 569 +- .../voip/webrtc/video/pc_full_stack_tests.cc | 203 +- .../webrtc/video/rtp_streams_synchronizer.cc | 7 + .../webrtc/video/rtp_streams_synchronizer2.cc | 15 +- .../webrtc/video/rtp_video_stream_receiver.h | 3 +- .../video/rtp_video_stream_receiver2.cc | 4 + .../webrtc/video/rtp_video_stream_receiver2.h | 3 +- .../webrtc/video/send_statistics_proxy.cc | 10 +- .../webrtc/video/stream_synchronization.cc | 8 + .../webrtc/video/stream_synchronization.h | 6 + .../jni/voip/webrtc/video/video_analyzer.cc | 3 +- .../jni/voip/webrtc/video/video_analyzer.h | 2 +- .../voip/webrtc/video/video_quality_test.cc | 19 +- .../voip/webrtc/video/video_quality_test.h | 3 +- .../voip/webrtc/video/video_receive_stream.cc | 7 +- .../voip/webrtc/video/video_receive_stream.h | 3 +- .../webrtc/video/video_receive_stream2.cc | 45 +- .../voip/webrtc/video/video_receive_stream2.h | 13 +- .../voip/webrtc/video/video_send_stream.cc | 9 - .../webrtc/video/video_send_stream_impl.cc | 56 +- .../webrtc/video/video_send_stream_impl.h | 16 +- .../webrtc/video/video_send_stream_tests.cc | 193 +- .../video/video_source_sink_controller.cc | 50 +- .../video/video_source_sink_controller.h | 29 +- .../webrtc/video/video_stream_decoder_impl.cc | 64 +- .../webrtc/video/video_stream_decoder_impl.h | 16 +- .../voip/webrtc/video/video_stream_encoder.cc | 588 +- .../voip/webrtc/video/video_stream_encoder.h | 65 +- TMessagesProj/src/main/AndroidManifest.xml | 9 + .../src/main/assets/darkblue.attheme | 1 + TMessagesProj/src/main/assets/emoji/0_0.png | Bin 1743 -> 1741 bytes TMessagesProj/src/main/assets/emoji/0_1.png | Bin 1723 -> 1722 bytes TMessagesProj/src/main/assets/emoji/0_10.png | Bin 2415 -> 1621 bytes TMessagesProj/src/main/assets/emoji/0_100.png | Bin 1004 -> 1583 bytes .../src/main/assets/emoji/0_1000.png | Bin 2094 -> 2009 bytes .../src/main/assets/emoji/0_1001.png | Bin 2122 -> 1847 bytes .../src/main/assets/emoji/0_1002.png | Bin 2044 -> 2674 bytes .../src/main/assets/emoji/0_1003.png | Bin 2333 -> 2469 bytes .../src/main/assets/emoji/0_1004.png | Bin 2021 -> 2442 bytes .../src/main/assets/emoji/0_1005.png | Bin 2089 -> 2309 bytes .../src/main/assets/emoji/0_1006.png | Bin 1963 -> 2205 bytes .../src/main/assets/emoji/0_1007.png | Bin 1952 -> 2114 bytes .../src/main/assets/emoji/0_1008.png | Bin 1897 -> 2536 bytes .../src/main/assets/emoji/0_1009.png | Bin 2391 -> 2493 bytes TMessagesProj/src/main/assets/emoji/0_101.png | Bin 2206 -> 1281 bytes .../src/main/assets/emoji/0_1010.png | Bin 2268 -> 2400 bytes .../src/main/assets/emoji/0_1011.png | Bin 2209 -> 2397 bytes .../src/main/assets/emoji/0_1012.png | Bin 2209 -> 2491 bytes .../src/main/assets/emoji/0_1013.png | Bin 2213 -> 2305 bytes .../src/main/assets/emoji/0_1014.png | Bin 2152 -> 2976 bytes .../src/main/assets/emoji/0_1015.png | Bin 2249 -> 3008 bytes .../src/main/assets/emoji/0_1016.png | Bin 2196 -> 3009 bytes .../src/main/assets/emoji/0_1017.png | Bin 2225 -> 2872 bytes .../src/main/assets/emoji/0_1018.png | Bin 2625 -> 2768 bytes .../src/main/assets/emoji/0_1019.png | Bin 2343 -> 2732 bytes TMessagesProj/src/main/assets/emoji/0_102.png | Bin 1587 -> 1009 bytes .../src/main/assets/emoji/0_1020.png | Bin 2530 -> 2997 bytes .../src/main/assets/emoji/0_1021.png | Bin 3256 -> 2847 bytes .../src/main/assets/emoji/0_1022.png | Bin 3281 -> 2845 bytes .../src/main/assets/emoji/0_1023.png | Bin 3312 -> 2759 bytes .../src/main/assets/emoji/0_1024.png | Bin 3266 -> 2724 bytes .../src/main/assets/emoji/0_1025.png | Bin 3280 -> 2552 bytes .../src/main/assets/emoji/0_1026.png | Bin 3289 -> 2946 bytes .../src/main/assets/emoji/0_1027.png | Bin 3159 -> 2908 bytes .../src/main/assets/emoji/0_1028.png | Bin 3094 -> 2940 bytes .../src/main/assets/emoji/0_1029.png | Bin 3111 -> 2975 bytes TMessagesProj/src/main/assets/emoji/0_103.png | Bin 2104 -> 2209 bytes .../src/main/assets/emoji/0_1030.png | Bin 3126 -> 2944 bytes .../src/main/assets/emoji/0_1031.png | Bin 3090 -> 2925 bytes .../src/main/assets/emoji/0_1032.png | Bin 3084 -> 2685 bytes .../src/main/assets/emoji/0_1033.png | Bin 3023 -> 2764 bytes .../src/main/assets/emoji/0_1034.png | Bin 3053 -> 2615 bytes .../src/main/assets/emoji/0_1035.png | Bin 3052 -> 2792 bytes .../src/main/assets/emoji/0_1036.png | Bin 2963 -> 2588 bytes .../src/main/assets/emoji/0_1037.png | Bin 2930 -> 2557 bytes .../src/main/assets/emoji/0_1038.png | Bin 2966 -> 2504 bytes .../src/main/assets/emoji/0_1039.png | Bin 2533 -> 2404 bytes TMessagesProj/src/main/assets/emoji/0_104.png | Bin 2164 -> 1587 bytes .../src/main/assets/emoji/0_1040.png | Bin 2430 -> 2337 bytes .../src/main/assets/emoji/0_1041.png | Bin 2348 -> 2307 bytes .../src/main/assets/emoji/0_1042.png | Bin 2304 -> 2245 bytes .../src/main/assets/emoji/0_1043.png | Bin 2273 -> 2211 bytes .../src/main/assets/emoji/0_1044.png | Bin 2283 -> 2835 bytes .../src/main/assets/emoji/0_1045.png | Bin 2257 -> 2726 bytes .../src/main/assets/emoji/0_1046.png | Bin 2161 -> 2709 bytes .../src/main/assets/emoji/0_1047.png | Bin 2047 -> 2775 bytes .../src/main/assets/emoji/0_1048.png | Bin 2031 -> 2706 bytes .../src/main/assets/emoji/0_1049.png | Bin 1963 -> 2459 bytes TMessagesProj/src/main/assets/emoji/0_105.png | Bin 2706 -> 2103 bytes .../src/main/assets/emoji/0_1050.png | Bin 2086 -> 2581 bytes .../src/main/assets/emoji/0_1051.png | Bin 2142 -> 2252 bytes .../src/main/assets/emoji/0_1052.png | Bin 2124 -> 2270 bytes .../src/main/assets/emoji/0_1053.png | Bin 2120 -> 2094 bytes .../src/main/assets/emoji/0_1054.png | Bin 2155 -> 2121 bytes .../src/main/assets/emoji/0_1055.png | Bin 2154 -> 2043 bytes .../src/main/assets/emoji/0_1056.png | Bin 2044 -> 2332 bytes .../src/main/assets/emoji/0_1057.png | Bin 2175 -> 2022 bytes .../src/main/assets/emoji/0_1058.png | Bin 2145 -> 2090 bytes .../src/main/assets/emoji/0_1059.png | Bin 2195 -> 1966 bytes TMessagesProj/src/main/assets/emoji/0_106.png | Bin 2415 -> 2164 bytes .../src/main/assets/emoji/0_1060.png | Bin 2023 -> 1951 bytes .../src/main/assets/emoji/0_1061.png | Bin 2168 -> 1896 bytes .../src/main/assets/emoji/0_1062.png | Bin 1940 -> 2391 bytes .../src/main/assets/emoji/0_1063.png | Bin 1910 -> 2266 bytes .../src/main/assets/emoji/0_1064.png | Bin 1915 -> 2209 bytes .../src/main/assets/emoji/0_1065.png | Bin 1845 -> 2209 bytes .../src/main/assets/emoji/0_1066.png | Bin 1773 -> 2213 bytes .../src/main/assets/emoji/0_1067.png | Bin 1666 -> 2151 bytes .../src/main/assets/emoji/0_1068.png | Bin 1663 -> 2247 bytes .../src/main/assets/emoji/0_1069.png | Bin 2346 -> 2196 bytes TMessagesProj/src/main/assets/emoji/0_107.png | Bin 2037 -> 2705 bytes .../src/main/assets/emoji/0_1070.png | Bin 1987 -> 2225 bytes .../src/main/assets/emoji/0_1071.png | Bin 2363 -> 2619 bytes .../src/main/assets/emoji/0_1072.png | Bin 1862 -> 2340 bytes .../src/main/assets/emoji/0_1073.png | Bin 1735 -> 2529 bytes .../src/main/assets/emoji/0_1074.png | Bin 1668 -> 3259 bytes .../src/main/assets/emoji/0_1075.png | Bin 2467 -> 3281 bytes .../src/main/assets/emoji/0_1076.png | Bin 2220 -> 3313 bytes .../src/main/assets/emoji/0_1077.png | Bin 2217 -> 3267 bytes .../src/main/assets/emoji/0_1078.png | Bin 2255 -> 3277 bytes .../src/main/assets/emoji/0_1079.png | Bin 1959 -> 3289 bytes TMessagesProj/src/main/assets/emoji/0_108.png | Bin 2002 -> 2414 bytes .../src/main/assets/emoji/0_1080.png | Bin 1825 -> 3157 bytes .../src/main/assets/emoji/0_1081.png | Bin 2094 -> 3087 bytes .../src/main/assets/emoji/0_1082.png | Bin 2006 -> 3112 bytes .../src/main/assets/emoji/0_1083.png | Bin 1989 -> 3127 bytes .../src/main/assets/emoji/0_1084.png | Bin 1740 -> 3094 bytes .../src/main/assets/emoji/0_1085.png | Bin 1671 -> 3082 bytes .../src/main/assets/emoji/0_1086.png | Bin 1498 -> 3025 bytes .../src/main/assets/emoji/0_1087.png | Bin 2245 -> 3054 bytes .../src/main/assets/emoji/0_1088.png | Bin 2143 -> 3049 bytes .../src/main/assets/emoji/0_1089.png | Bin 2157 -> 2961 bytes TMessagesProj/src/main/assets/emoji/0_109.png | Bin 2511 -> 2038 bytes .../src/main/assets/emoji/0_1090.png | Bin 2099 -> 2927 bytes .../src/main/assets/emoji/0_1091.png | Bin 1892 -> 2966 bytes .../src/main/assets/emoji/0_1092.png | Bin 1836 -> 2533 bytes .../src/main/assets/emoji/0_1093.png | Bin 2195 -> 2430 bytes .../src/main/assets/emoji/0_1094.png | Bin 2038 -> 2345 bytes .../src/main/assets/emoji/0_1095.png | Bin 2074 -> 2305 bytes .../src/main/assets/emoji/0_1096.png | Bin 1919 -> 2274 bytes .../src/main/assets/emoji/0_1097.png | Bin 1781 -> 2283 bytes .../src/main/assets/emoji/0_1098.png | Bin 1617 -> 2256 bytes .../src/main/assets/emoji/0_1099.png | Bin 2054 -> 2160 bytes TMessagesProj/src/main/assets/emoji/0_11.png | Bin 1524 -> 2413 bytes TMessagesProj/src/main/assets/emoji/0_110.png | Bin 2399 -> 2003 bytes .../src/main/assets/emoji/0_1100.png | Bin 1877 -> 2045 bytes .../src/main/assets/emoji/0_1101.png | Bin 2030 -> 2030 bytes .../src/main/assets/emoji/0_1102.png | Bin 1890 -> 1962 bytes .../src/main/assets/emoji/0_1103.png | Bin 1825 -> 2084 bytes .../src/main/assets/emoji/0_1104.png | Bin 1602 -> 2141 bytes .../src/main/assets/emoji/0_1105.png | Bin 1720 -> 2125 bytes .../src/main/assets/emoji/0_1106.png | Bin 1784 -> 2117 bytes .../src/main/assets/emoji/0_1107.png | Bin 1869 -> 2153 bytes .../src/main/assets/emoji/0_1108.png | Bin 1737 -> 2154 bytes .../src/main/assets/emoji/0_1109.png | Bin 1664 -> 2045 bytes TMessagesProj/src/main/assets/emoji/0_111.png | Bin 2092 -> 2510 bytes .../src/main/assets/emoji/0_1110.png | Bin 1460 -> 2175 bytes .../src/main/assets/emoji/0_1111.png | Bin 2409 -> 2145 bytes .../src/main/assets/emoji/0_1112.png | Bin 2169 -> 2195 bytes .../src/main/assets/emoji/0_1113.png | Bin 2193 -> 2023 bytes .../src/main/assets/emoji/0_1114.png | Bin 1967 -> 2168 bytes .../src/main/assets/emoji/0_1115.png | Bin 1885 -> 1940 bytes .../src/main/assets/emoji/0_1116.png | Bin 1741 -> 1908 bytes .../src/main/assets/emoji/0_1117.png | Bin 2218 -> 1912 bytes .../src/main/assets/emoji/0_1118.png | Bin 2132 -> 1844 bytes .../src/main/assets/emoji/0_1119.png | Bin 1988 -> 1770 bytes TMessagesProj/src/main/assets/emoji/0_112.png | Bin 1296 -> 2404 bytes .../src/main/assets/emoji/0_1120.png | Bin 2043 -> 1665 bytes .../src/main/assets/emoji/0_1121.png | Bin 1968 -> 1665 bytes .../src/main/assets/emoji/0_1122.png | Bin 1749 -> 2346 bytes .../src/main/assets/emoji/0_1123.png | Bin 2315 -> 1988 bytes .../src/main/assets/emoji/0_1124.png | Bin 2252 -> 2363 bytes .../src/main/assets/emoji/0_1125.png | Bin 2191 -> 1861 bytes .../src/main/assets/emoji/0_1126.png | Bin 1988 -> 1734 bytes .../src/main/assets/emoji/0_1127.png | Bin 2046 -> 1667 bytes .../src/main/assets/emoji/0_1128.png | Bin 1917 -> 2428 bytes .../src/main/assets/emoji/0_1129.png | Bin 2318 -> 2273 bytes TMessagesProj/src/main/assets/emoji/0_113.png | Bin 1118 -> 2092 bytes .../src/main/assets/emoji/0_1130.png | Bin 2279 -> 2244 bytes .../src/main/assets/emoji/0_1131.png | Bin 2208 -> 2052 bytes .../src/main/assets/emoji/0_1132.png | Bin 2181 -> 1869 bytes .../src/main/assets/emoji/0_1133.png | Bin 2051 -> 1880 bytes .../src/main/assets/emoji/0_1134.png | Bin 1901 -> 2406 bytes .../src/main/assets/emoji/0_1135.png | Bin 2641 -> 2344 bytes .../src/main/assets/emoji/0_1136.png | Bin 2479 -> 2441 bytes .../src/main/assets/emoji/0_1137.png | Bin 2589 -> 2201 bytes .../src/main/assets/emoji/0_1138.png | Bin 2367 -> 2080 bytes .../src/main/assets/emoji/0_1139.png | Bin 2171 -> 1979 bytes TMessagesProj/src/main/assets/emoji/0_114.png | Bin 972 -> 1295 bytes .../src/main/assets/emoji/0_1140.png | Bin 2071 -> 2470 bytes .../src/main/assets/emoji/0_1141.png | Bin 2537 -> 2328 bytes .../src/main/assets/emoji/0_1142.png | Bin 2601 -> 2430 bytes .../src/main/assets/emoji/0_1143.png | Bin 2571 -> 2126 bytes .../src/main/assets/emoji/0_1144.png | Bin 2315 -> 2079 bytes .../src/main/assets/emoji/0_1145.png | Bin 2222 -> 1919 bytes .../src/main/assets/emoji/0_1146.png | Bin 1955 -> 2467 bytes .../src/main/assets/emoji/0_1147.png | Bin 2256 -> 2222 bytes .../src/main/assets/emoji/0_1148.png | Bin 2109 -> 2215 bytes .../src/main/assets/emoji/0_1149.png | Bin 2206 -> 2256 bytes TMessagesProj/src/main/assets/emoji/0_115.png | Bin 949 -> 1118 bytes .../src/main/assets/emoji/0_1150.png | Bin 2070 -> 1960 bytes .../src/main/assets/emoji/0_1151.png | Bin 1773 -> 1822 bytes .../src/main/assets/emoji/0_1152.png | Bin 1655 -> 2093 bytes .../src/main/assets/emoji/0_1153.png | Bin 2165 -> 2006 bytes .../src/main/assets/emoji/0_1154.png | Bin 2318 -> 1990 bytes .../src/main/assets/emoji/0_1155.png | Bin 2274 -> 1740 bytes .../src/main/assets/emoji/0_1156.png | Bin 2168 -> 1671 bytes .../src/main/assets/emoji/0_1157.png | Bin 2020 -> 1499 bytes .../src/main/assets/emoji/0_1158.png | Bin 1687 -> 2247 bytes .../src/main/assets/emoji/0_1159.png | Bin 1943 -> 2143 bytes TMessagesProj/src/main/assets/emoji/0_116.png | Bin 863 -> 972 bytes .../src/main/assets/emoji/0_1160.png | Bin 1921 -> 2160 bytes .../src/main/assets/emoji/0_1161.png | Bin 2183 -> 2096 bytes .../src/main/assets/emoji/0_1162.png | Bin 2044 -> 1891 bytes .../src/main/assets/emoji/0_1163.png | Bin 1886 -> 1837 bytes .../src/main/assets/emoji/0_1164.png | Bin 1782 -> 2195 bytes .../src/main/assets/emoji/0_1165.png | Bin 2271 -> 2037 bytes .../src/main/assets/emoji/0_1166.png | Bin 2109 -> 2073 bytes .../src/main/assets/emoji/0_1167.png | Bin 2014 -> 1919 bytes .../src/main/assets/emoji/0_1168.png | Bin 2007 -> 1780 bytes .../src/main/assets/emoji/0_1169.png | Bin 1724 -> 1616 bytes TMessagesProj/src/main/assets/emoji/0_117.png | Bin 720 -> 949 bytes .../src/main/assets/emoji/0_1170.png | Bin 1576 -> 2057 bytes .../src/main/assets/emoji/0_1171.png | Bin 2167 -> 1878 bytes .../src/main/assets/emoji/0_1172.png | Bin 2370 -> 2032 bytes .../src/main/assets/emoji/0_1173.png | Bin 2264 -> 1890 bytes .../src/main/assets/emoji/0_1174.png | Bin 2040 -> 1824 bytes .../src/main/assets/emoji/0_1175.png | Bin 1872 -> 1606 bytes .../src/main/assets/emoji/0_1176.png | Bin 1701 -> 1724 bytes .../src/main/assets/emoji/0_1177.png | Bin 2176 -> 1784 bytes .../src/main/assets/emoji/0_1178.png | Bin 1983 -> 1871 bytes .../src/main/assets/emoji/0_1179.png | Bin 2176 -> 1736 bytes TMessagesProj/src/main/assets/emoji/0_118.png | Bin 1177 -> 863 bytes .../src/main/assets/emoji/0_1180.png | Bin 1961 -> 1665 bytes .../src/main/assets/emoji/0_1181.png | Bin 1734 -> 1455 bytes .../src/main/assets/emoji/0_1182.png | Bin 1517 -> 2408 bytes .../src/main/assets/emoji/0_1183.png | Bin 2022 -> 2167 bytes .../src/main/assets/emoji/0_1184.png | Bin 1779 -> 2189 bytes .../src/main/assets/emoji/0_1185.png | Bin 2032 -> 1969 bytes .../src/main/assets/emoji/0_1186.png | Bin 1827 -> 1881 bytes .../src/main/assets/emoji/0_1187.png | Bin 1653 -> 1742 bytes .../src/main/assets/emoji/0_1188.png | Bin 1426 -> 2220 bytes .../src/main/assets/emoji/0_1189.png | Bin 1798 -> 2134 bytes TMessagesProj/src/main/assets/emoji/0_119.png | Bin 1106 -> 720 bytes .../src/main/assets/emoji/0_1190.png | Bin 1870 -> 1988 bytes .../src/main/assets/emoji/0_1191.png | Bin 1825 -> 2045 bytes .../src/main/assets/emoji/0_1192.png | Bin 1657 -> 1969 bytes .../src/main/assets/emoji/0_1193.png | Bin 1580 -> 1749 bytes .../src/main/assets/emoji/0_1194.png | Bin 1330 -> 2312 bytes .../src/main/assets/emoji/0_1195.png | Bin 1940 -> 2248 bytes .../src/main/assets/emoji/0_1196.png | Bin 1636 -> 2189 bytes .../src/main/assets/emoji/0_1197.png | Bin 1709 -> 1991 bytes .../src/main/assets/emoji/0_1198.png | Bin 1557 -> 2048 bytes .../src/main/assets/emoji/0_1199.png | Bin 1359 -> 1921 bytes TMessagesProj/src/main/assets/emoji/0_12.png | Bin 1561 -> 1520 bytes TMessagesProj/src/main/assets/emoji/0_120.png | Bin 968 -> 1175 bytes .../src/main/assets/emoji/0_1200.png | Bin 1204 -> 2316 bytes .../src/main/assets/emoji/0_1201.png | Bin 2389 -> 2276 bytes .../src/main/assets/emoji/0_1202.png | Bin 2187 -> 2208 bytes .../src/main/assets/emoji/0_1203.png | Bin 2496 -> 2175 bytes .../src/main/assets/emoji/0_1204.png | Bin 2190 -> 2054 bytes .../src/main/assets/emoji/0_1205.png | Bin 2113 -> 1897 bytes .../src/main/assets/emoji/0_1206.png | Bin 1940 -> 2639 bytes .../src/main/assets/emoji/0_1207.png | Bin 2222 -> 2477 bytes .../src/main/assets/emoji/0_1208.png | Bin 2140 -> 2594 bytes .../src/main/assets/emoji/0_1209.png | Bin 2146 -> 2368 bytes TMessagesProj/src/main/assets/emoji/0_121.png | Bin 1018 -> 1104 bytes .../src/main/assets/emoji/0_1210.png | Bin 2153 -> 2170 bytes .../src/main/assets/emoji/0_1211.png | Bin 2056 -> 2068 bytes .../src/main/assets/emoji/0_1212.png | Bin 1853 -> 2538 bytes .../src/main/assets/emoji/0_1213.png | Bin 2055 -> 2600 bytes .../src/main/assets/emoji/0_1214.png | Bin 2020 -> 2571 bytes .../src/main/assets/emoji/0_1215.png | Bin 2119 -> 2314 bytes .../src/main/assets/emoji/0_1216.png | Bin 1886 -> 2222 bytes .../src/main/assets/emoji/0_1217.png | Bin 1887 -> 1955 bytes .../src/main/assets/emoji/0_1218.png | Bin 1602 -> 2256 bytes .../src/main/assets/emoji/0_1219.png | Bin 1906 -> 2111 bytes TMessagesProj/src/main/assets/emoji/0_122.png | Bin 908 -> 970 bytes .../src/main/assets/emoji/0_1220.png | Bin 1725 -> 2202 bytes .../src/main/assets/emoji/0_1221.png | Bin 1847 -> 2072 bytes .../src/main/assets/emoji/0_1222.png | Bin 1674 -> 1768 bytes .../src/main/assets/emoji/0_1223.png | Bin 1505 -> 1661 bytes .../src/main/assets/emoji/0_1224.png | Bin 1427 -> 2166 bytes .../src/main/assets/emoji/0_1225.png | Bin 1777 -> 2317 bytes .../src/main/assets/emoji/0_1226.png | Bin 1637 -> 2271 bytes .../src/main/assets/emoji/0_1227.png | Bin 1777 -> 2167 bytes .../src/main/assets/emoji/0_1228.png | Bin 1520 -> 2022 bytes .../src/main/assets/emoji/0_1229.png | Bin 1449 -> 1687 bytes TMessagesProj/src/main/assets/emoji/0_123.png | Bin 770 -> 1019 bytes .../src/main/assets/emoji/0_1230.png | Bin 1364 -> 1944 bytes .../src/main/assets/emoji/0_1231.png | Bin 1630 -> 1919 bytes .../src/main/assets/emoji/0_1232.png | Bin 1577 -> 2179 bytes .../src/main/assets/emoji/0_1233.png | Bin 1649 -> 2049 bytes .../src/main/assets/emoji/0_1234.png | Bin 1498 -> 1889 bytes .../src/main/assets/emoji/0_1235.png | Bin 1503 -> 1779 bytes .../src/main/assets/emoji/0_1236.png | Bin 1286 -> 2274 bytes .../src/main/assets/emoji/0_1237.png | Bin 1857 -> 2105 bytes .../src/main/assets/emoji/0_1238.png | Bin 1692 -> 2016 bytes .../src/main/assets/emoji/0_1239.png | Bin 1801 -> 2008 bytes TMessagesProj/src/main/assets/emoji/0_124.png | Bin 1609 -> 908 bytes .../src/main/assets/emoji/0_1240.png | Bin 1717 -> 1723 bytes .../src/main/assets/emoji/0_1241.png | Bin 1484 -> 1578 bytes .../src/main/assets/emoji/0_1242.png | Bin 1277 -> 2166 bytes .../src/main/assets/emoji/0_1243.png | Bin 1847 -> 2370 bytes .../src/main/assets/emoji/0_1244.png | Bin 1690 -> 2262 bytes .../src/main/assets/emoji/0_1245.png | Bin 1741 -> 2041 bytes .../src/main/assets/emoji/0_1246.png | Bin 1556 -> 1872 bytes .../src/main/assets/emoji/0_1247.png | Bin 1505 -> 1701 bytes .../src/main/assets/emoji/0_1248.png | Bin 1287 -> 2173 bytes .../src/main/assets/emoji/0_1249.png | Bin 1651 -> 1984 bytes TMessagesProj/src/main/assets/emoji/0_125.png | Bin 1409 -> 770 bytes .../src/main/assets/emoji/0_1250.png | Bin 1652 -> 2178 bytes .../src/main/assets/emoji/0_1251.png | Bin 1664 -> 1961 bytes .../src/main/assets/emoji/0_1252.png | Bin 1509 -> 1734 bytes .../src/main/assets/emoji/0_1253.png | Bin 1374 -> 1517 bytes .../src/main/assets/emoji/0_1254.png | Bin 1341 -> 2022 bytes .../src/main/assets/emoji/0_1255.png | Bin 2420 -> 1780 bytes .../src/main/assets/emoji/0_1256.png | Bin 2172 -> 2031 bytes .../src/main/assets/emoji/0_1257.png | Bin 2423 -> 1826 bytes .../src/main/assets/emoji/0_1258.png | Bin 2239 -> 1652 bytes .../src/main/assets/emoji/0_1259.png | Bin 2017 -> 1420 bytes TMessagesProj/src/main/assets/emoji/0_126.png | Bin 1281 -> 1609 bytes .../src/main/assets/emoji/0_1260.png | Bin 1818 -> 1800 bytes .../src/main/assets/emoji/0_1261.png | Bin 2441 -> 1870 bytes .../src/main/assets/emoji/0_1262.png | Bin 2332 -> 1826 bytes .../src/main/assets/emoji/0_1263.png | Bin 2376 -> 1657 bytes .../src/main/assets/emoji/0_1264.png | Bin 2216 -> 1580 bytes .../src/main/assets/emoji/0_1265.png | Bin 2046 -> 1330 bytes .../src/main/assets/emoji/0_1266.png | Bin 1925 -> 1939 bytes .../src/main/assets/emoji/0_1267.png | Bin 2466 -> 1635 bytes .../src/main/assets/emoji/0_1268.png | Bin 2233 -> 1710 bytes .../src/main/assets/emoji/0_1269.png | Bin 2206 -> 1560 bytes TMessagesProj/src/main/assets/emoji/0_127.png | Bin 1281 -> 1409 bytes .../src/main/assets/emoji/0_1270.png | Bin 2190 -> 1358 bytes .../src/main/assets/emoji/0_1271.png | Bin 1941 -> 1205 bytes .../src/main/assets/emoji/0_1272.png | Bin 1867 -> 2389 bytes .../src/main/assets/emoji/0_1273.png | Bin 2095 -> 2190 bytes .../src/main/assets/emoji/0_1274.png | Bin 2106 -> 2495 bytes .../src/main/assets/emoji/0_1275.png | Bin 2031 -> 2191 bytes .../src/main/assets/emoji/0_1276.png | Bin 1827 -> 2113 bytes .../src/main/assets/emoji/0_1277.png | Bin 1561 -> 1942 bytes .../src/main/assets/emoji/0_1278.png | Bin 1318 -> 2224 bytes .../src/main/assets/emoji/0_1279.png | Bin 2093 -> 2140 bytes TMessagesProj/src/main/assets/emoji/0_128.png | Bin 1295 -> 1281 bytes .../src/main/assets/emoji/0_1280.png | Bin 2027 -> 2146 bytes .../src/main/assets/emoji/0_1281.png | Bin 2135 -> 2153 bytes .../src/main/assets/emoji/0_1282.png | Bin 1831 -> 2056 bytes .../src/main/assets/emoji/0_1283.png | Bin 1625 -> 1854 bytes .../src/main/assets/emoji/0_1284.png | Bin 1290 -> 2024 bytes .../src/main/assets/emoji/0_1285.png | Bin 1939 -> 2021 bytes .../src/main/assets/emoji/0_1286.png | Bin 1906 -> 2119 bytes .../src/main/assets/emoji/0_1287.png | Bin 1781 -> 1886 bytes .../src/main/assets/emoji/0_1288.png | Bin 1615 -> 1884 bytes .../src/main/assets/emoji/0_1289.png | Bin 1394 -> 1603 bytes TMessagesProj/src/main/assets/emoji/0_129.png | Bin 1126 -> 1281 bytes .../src/main/assets/emoji/0_1290.png | Bin 1253 -> 1907 bytes .../src/main/assets/emoji/0_1291.png | Bin 2633 -> 1727 bytes .../src/main/assets/emoji/0_1292.png | Bin 2376 -> 1850 bytes .../src/main/assets/emoji/0_1293.png | Bin 2414 -> 1673 bytes .../src/main/assets/emoji/0_1294.png | Bin 2451 -> 1507 bytes .../src/main/assets/emoji/0_1295.png | Bin 2326 -> 1427 bytes .../src/main/assets/emoji/0_1296.png | Bin 2269 -> 1777 bytes .../src/main/assets/emoji/0_1297.png | Bin 2454 -> 1637 bytes .../src/main/assets/emoji/0_1298.png | Bin 2212 -> 1777 bytes .../src/main/assets/emoji/0_1299.png | Bin 2373 -> 1520 bytes TMessagesProj/src/main/assets/emoji/0_13.png | Bin 1626 -> 1559 bytes TMessagesProj/src/main/assets/emoji/0_130.png | Bin 1486 -> 1295 bytes .../src/main/assets/emoji/0_1300.png | Bin 2265 -> 1450 bytes .../src/main/assets/emoji/0_1301.png | Bin 2315 -> 1364 bytes .../src/main/assets/emoji/0_1302.png | Bin 2269 -> 1630 bytes .../src/main/assets/emoji/0_1303.png | Bin 2571 -> 1577 bytes .../src/main/assets/emoji/0_1304.png | Bin 2214 -> 1649 bytes .../src/main/assets/emoji/0_1305.png | Bin 2204 -> 1496 bytes .../src/main/assets/emoji/0_1306.png | Bin 2359 -> 1504 bytes .../src/main/assets/emoji/0_1307.png | Bin 2269 -> 1286 bytes .../src/main/assets/emoji/0_1308.png | Bin 2047 -> 1857 bytes .../src/main/assets/emoji/0_1309.png | Bin 2208 -> 1692 bytes TMessagesProj/src/main/assets/emoji/0_131.png | Bin 1284 -> 1126 bytes .../src/main/assets/emoji/0_1310.png | Bin 2111 -> 1804 bytes .../src/main/assets/emoji/0_1311.png | Bin 2029 -> 1716 bytes .../src/main/assets/emoji/0_1312.png | Bin 1906 -> 1484 bytes .../src/main/assets/emoji/0_1313.png | Bin 1852 -> 1278 bytes .../src/main/assets/emoji/0_1314.png | Bin 1664 -> 1847 bytes .../src/main/assets/emoji/0_1315.png | Bin 1325 -> 1688 bytes .../src/main/assets/emoji/0_1316.png | Bin 1185 -> 1742 bytes .../src/main/assets/emoji/0_1317.png | Bin 1149 -> 1555 bytes .../src/main/assets/emoji/0_1318.png | Bin 1143 -> 1506 bytes .../src/main/assets/emoji/0_1319.png | Bin 1167 -> 1285 bytes TMessagesProj/src/main/assets/emoji/0_132.png | Bin 1279 -> 1487 bytes .../src/main/assets/emoji/0_1320.png | Bin 1044 -> 1650 bytes .../src/main/assets/emoji/0_1321.png | Bin 2773 -> 1650 bytes .../src/main/assets/emoji/0_1322.png | Bin 2707 -> 1664 bytes .../src/main/assets/emoji/0_1323.png | Bin 2525 -> 1510 bytes .../src/main/assets/emoji/0_1324.png | Bin 2327 -> 1372 bytes .../src/main/assets/emoji/0_1325.png | Bin 2246 -> 1341 bytes .../src/main/assets/emoji/0_1326.png | Bin 1907 -> 2419 bytes .../src/main/assets/emoji/0_1327.png | Bin 1891 -> 2170 bytes .../src/main/assets/emoji/0_1328.png | Bin 1880 -> 2423 bytes .../src/main/assets/emoji/0_1329.png | Bin 1757 -> 2237 bytes TMessagesProj/src/main/assets/emoji/0_133.png | Bin 1257 -> 1284 bytes .../src/main/assets/emoji/0_1330.png | Bin 1864 -> 2016 bytes .../src/main/assets/emoji/0_1331.png | Bin 1830 -> 1819 bytes .../src/main/assets/emoji/0_1332.png | Bin 1697 -> 2443 bytes .../src/main/assets/emoji/0_1333.png | Bin 2825 -> 2331 bytes .../src/main/assets/emoji/0_1334.png | Bin 2482 -> 2376 bytes .../src/main/assets/emoji/0_1335.png | Bin 2368 -> 2217 bytes .../src/main/assets/emoji/0_1336.png | Bin 1061 -> 2051 bytes .../src/main/assets/emoji/0_1337.png | Bin 1082 -> 1927 bytes .../src/main/assets/emoji/0_1338.png | Bin 1033 -> 2466 bytes .../src/main/assets/emoji/0_1339.png | Bin 1075 -> 2234 bytes TMessagesProj/src/main/assets/emoji/0_134.png | Bin 1158 -> 1280 bytes .../src/main/assets/emoji/0_1340.png | Bin 1014 -> 2205 bytes .../src/main/assets/emoji/0_1341.png | Bin 942 -> 2191 bytes .../src/main/assets/emoji/0_1342.png | Bin 2114 -> 1941 bytes .../src/main/assets/emoji/0_1343.png | Bin 1939 -> 1866 bytes .../src/main/assets/emoji/0_1344.png | Bin 2082 -> 2096 bytes .../src/main/assets/emoji/0_1345.png | Bin 1872 -> 2110 bytes .../src/main/assets/emoji/0_1346.png | Bin 1884 -> 2032 bytes .../src/main/assets/emoji/0_1347.png | Bin 1709 -> 1826 bytes .../src/main/assets/emoji/0_1348.png | Bin 1857 -> 1564 bytes .../src/main/assets/emoji/0_1349.png | Bin 1675 -> 1316 bytes TMessagesProj/src/main/assets/emoji/0_135.png | Bin 1062 -> 1257 bytes .../src/main/assets/emoji/0_1350.png | Bin 1820 -> 2093 bytes .../src/main/assets/emoji/0_1351.png | Bin 1795 -> 2028 bytes .../src/main/assets/emoji/0_1352.png | Bin 1610 -> 2134 bytes .../src/main/assets/emoji/0_1353.png | Bin 1620 -> 1833 bytes .../src/main/assets/emoji/0_1354.png | Bin 1972 -> 1628 bytes .../src/main/assets/emoji/0_1355.png | Bin 1904 -> 1292 bytes .../src/main/assets/emoji/0_1356.png | Bin 1944 -> 1939 bytes .../src/main/assets/emoji/0_1357.png | Bin 1880 -> 1905 bytes .../src/main/assets/emoji/0_1358.png | Bin 1764 -> 1782 bytes .../src/main/assets/emoji/0_1359.png | Bin 1618 -> 1614 bytes TMessagesProj/src/main/assets/emoji/0_136.png | Bin 1094 -> 1156 bytes .../src/main/assets/emoji/0_1360.png | Bin 2599 -> 1394 bytes .../src/main/assets/emoji/0_1361.png | Bin 2619 -> 1254 bytes .../src/main/assets/emoji/0_1362.png | Bin 2635 -> 2632 bytes .../src/main/assets/emoji/0_1363.png | Bin 2503 -> 2377 bytes .../src/main/assets/emoji/0_1364.png | Bin 2478 -> 2414 bytes .../src/main/assets/emoji/0_1365.png | Bin 2143 -> 2450 bytes .../src/main/assets/emoji/0_1366.png | Bin 2536 -> 2325 bytes .../src/main/assets/emoji/0_1367.png | Bin 2369 -> 2269 bytes .../src/main/assets/emoji/0_1368.png | Bin 2552 -> 2454 bytes .../src/main/assets/emoji/0_1369.png | Bin 2308 -> 2212 bytes TMessagesProj/src/main/assets/emoji/0_137.png | Bin 1188 -> 1064 bytes .../src/main/assets/emoji/0_1370.png | Bin 2287 -> 2373 bytes .../src/main/assets/emoji/0_1371.png | Bin 2192 -> 2265 bytes .../src/main/assets/emoji/0_1372.png | Bin 2582 -> 2315 bytes .../src/main/assets/emoji/0_1373.png | Bin 2449 -> 2269 bytes .../src/main/assets/emoji/0_1374.png | Bin 2464 -> 2571 bytes .../src/main/assets/emoji/0_1375.png | Bin 2318 -> 2214 bytes .../src/main/assets/emoji/0_1376.png | Bin 2318 -> 2204 bytes .../src/main/assets/emoji/0_1377.png | Bin 2246 -> 2359 bytes .../src/main/assets/emoji/0_1378.png | Bin 1809 -> 2269 bytes .../src/main/assets/emoji/0_1379.png | Bin 1702 -> 2047 bytes TMessagesProj/src/main/assets/emoji/0_138.png | Bin 945 -> 1094 bytes .../src/main/assets/emoji/0_1380.png | Bin 1730 -> 2204 bytes .../src/main/assets/emoji/0_1381.png | Bin 1591 -> 2110 bytes .../src/main/assets/emoji/0_1382.png | Bin 1635 -> 2031 bytes .../src/main/assets/emoji/0_1383.png | Bin 1550 -> 1908 bytes .../src/main/assets/emoji/0_1384.png | Bin 1672 -> 1852 bytes .../src/main/assets/emoji/0_1385.png | Bin 1476 -> 1665 bytes .../src/main/assets/emoji/0_1386.png | Bin 1483 -> 1326 bytes .../src/main/assets/emoji/0_1387.png | Bin 1482 -> 1186 bytes .../src/main/assets/emoji/0_1388.png | Bin 1440 -> 1147 bytes .../src/main/assets/emoji/0_1389.png | Bin 1322 -> 1143 bytes TMessagesProj/src/main/assets/emoji/0_139.png | Bin 1020 -> 1187 bytes .../src/main/assets/emoji/0_1390.png | Bin 1747 -> 1167 bytes .../src/main/assets/emoji/0_1391.png | Bin 1723 -> 1044 bytes .../src/main/assets/emoji/0_1392.png | Bin 1712 -> 2774 bytes .../src/main/assets/emoji/0_1393.png | Bin 1647 -> 2706 bytes .../src/main/assets/emoji/0_1394.png | Bin 1581 -> 2524 bytes .../src/main/assets/emoji/0_1395.png | Bin 1419 -> 2328 bytes .../src/main/assets/emoji/0_1396.png | Bin 2234 -> 2250 bytes .../src/main/assets/emoji/0_1397.png | Bin 2164 -> 1910 bytes .../src/main/assets/emoji/0_1398.png | Bin 2249 -> 1891 bytes .../src/main/assets/emoji/0_1399.png | Bin 2115 -> 1881 bytes TMessagesProj/src/main/assets/emoji/0_14.png | Bin 1567 -> 1625 bytes TMessagesProj/src/main/assets/emoji/0_140.png | Bin 917 -> 944 bytes .../src/main/assets/emoji/0_1400.png | Bin 2059 -> 1756 bytes .../src/main/assets/emoji/0_1401.png | Bin 2030 -> 1860 bytes .../src/main/assets/emoji/0_1402.png | Bin 2054 -> 1830 bytes .../src/main/assets/emoji/0_1403.png | Bin 1962 -> 1695 bytes .../src/main/assets/emoji/0_1404.png | Bin 1978 -> 2825 bytes .../src/main/assets/emoji/0_1405.png | Bin 1829 -> 2484 bytes .../src/main/assets/emoji/0_1406.png | Bin 1757 -> 2370 bytes .../src/main/assets/emoji/0_1407.png | Bin 1684 -> 1061 bytes .../src/main/assets/emoji/0_1408.png | Bin 2234 -> 1082 bytes .../src/main/assets/emoji/0_1409.png | Bin 1994 -> 1031 bytes TMessagesProj/src/main/assets/emoji/0_141.png | Bin 825 -> 1021 bytes .../src/main/assets/emoji/0_1410.png | Bin 2083 -> 1077 bytes .../src/main/assets/emoji/0_1411.png | Bin 1982 -> 1014 bytes .../src/main/assets/emoji/0_1412.png | Bin 1854 -> 943 bytes .../src/main/assets/emoji/0_1413.png | Bin 1878 -> 2115 bytes .../src/main/assets/emoji/0_1414.png | Bin 1322 -> 1939 bytes .../src/main/assets/emoji/0_1415.png | Bin 1312 -> 2082 bytes .../src/main/assets/emoji/0_1416.png | Bin 1310 -> 1874 bytes .../src/main/assets/emoji/0_1417.png | Bin 1166 -> 1882 bytes .../src/main/assets/emoji/0_1418.png | Bin 1252 -> 1709 bytes .../src/main/assets/emoji/0_1419.png | Bin 1075 -> 1859 bytes TMessagesProj/src/main/assets/emoji/0_142.png | Bin 691 -> 918 bytes .../src/main/assets/emoji/0_1420.png | Bin 1092 -> 1672 bytes .../src/main/assets/emoji/0_1421.png | Bin 1003 -> 1821 bytes .../src/main/assets/emoji/0_1422.png | Bin 1034 -> 1794 bytes .../src/main/assets/emoji/0_1423.png | Bin 1006 -> 1612 bytes .../src/main/assets/emoji/0_1424.png | Bin 995 -> 1620 bytes .../src/main/assets/emoji/0_1425.png | Bin 871 -> 1971 bytes .../src/main/assets/emoji/0_1426.png | Bin 1128 -> 1903 bytes .../src/main/assets/emoji/0_1427.png | Bin 1163 -> 1944 bytes .../src/main/assets/emoji/0_1428.png | Bin 1150 -> 1878 bytes .../src/main/assets/emoji/0_1429.png | Bin 1122 -> 1765 bytes TMessagesProj/src/main/assets/emoji/0_143.png | Bin 1272 -> 825 bytes .../src/main/assets/emoji/0_1430.png | Bin 1093 -> 1616 bytes .../src/main/assets/emoji/0_1431.png | Bin 1029 -> 2599 bytes .../src/main/assets/emoji/0_1432.png | Bin 2194 -> 2617 bytes .../src/main/assets/emoji/0_1433.png | Bin 1947 -> 2637 bytes .../src/main/assets/emoji/0_1434.png | Bin 1937 -> 2505 bytes .../src/main/assets/emoji/0_1435.png | Bin 1864 -> 2479 bytes .../src/main/assets/emoji/0_1436.png | Bin 1887 -> 2144 bytes .../src/main/assets/emoji/0_1437.png | Bin 1761 -> 2537 bytes .../src/main/assets/emoji/0_1438.png | Bin 1975 -> 2371 bytes .../src/main/assets/emoji/0_1439.png | Bin 1704 -> 2554 bytes TMessagesProj/src/main/assets/emoji/0_144.png | Bin 1095 -> 691 bytes .../src/main/assets/emoji/0_1440.png | Bin 1685 -> 2305 bytes .../src/main/assets/emoji/0_1441.png | Bin 1585 -> 2283 bytes .../src/main/assets/emoji/0_1442.png | Bin 1618 -> 2192 bytes .../src/main/assets/emoji/0_1443.png | Bin 1478 -> 2579 bytes .../src/main/assets/emoji/0_1444.png | Bin 1942 -> 2449 bytes .../src/main/assets/emoji/0_1445.png | Bin 1823 -> 2463 bytes .../src/main/assets/emoji/0_1446.png | Bin 1841 -> 2316 bytes .../src/main/assets/emoji/0_1447.png | Bin 1767 -> 2315 bytes .../src/main/assets/emoji/0_1448.png | Bin 1709 -> 2245 bytes .../src/main/assets/emoji/0_1449.png | Bin 1651 -> 1807 bytes TMessagesProj/src/main/assets/emoji/0_145.png | Bin 1010 -> 1273 bytes .../src/main/assets/emoji/0_1450.png | Bin 1791 -> 1702 bytes .../src/main/assets/emoji/0_1451.png | Bin 1639 -> 1729 bytes .../src/main/assets/emoji/0_1452.png | Bin 1698 -> 1591 bytes .../src/main/assets/emoji/0_1453.png | Bin 1412 -> 1635 bytes .../src/main/assets/emoji/0_1454.png | Bin 1345 -> 1554 bytes .../src/main/assets/emoji/0_1455.png | Bin 1227 -> 1672 bytes .../src/main/assets/emoji/0_1456.png | Bin 1474 -> 1475 bytes .../src/main/assets/emoji/0_1457.png | Bin 1369 -> 1485 bytes .../src/main/assets/emoji/0_1458.png | Bin 1416 -> 1481 bytes .../src/main/assets/emoji/0_1459.png | Bin 1268 -> 1441 bytes TMessagesProj/src/main/assets/emoji/0_146.png | Bin 946 -> 1098 bytes .../src/main/assets/emoji/0_1460.png | Bin 1219 -> 1321 bytes .../src/main/assets/emoji/0_1461.png | Bin 1128 -> 1746 bytes .../src/main/assets/emoji/0_1462.png | Bin 1540 -> 1722 bytes .../src/main/assets/emoji/0_1463.png | Bin 1445 -> 1711 bytes .../src/main/assets/emoji/0_1464.png | Bin 1469 -> 1647 bytes .../src/main/assets/emoji/0_1465.png | Bin 1275 -> 1583 bytes .../src/main/assets/emoji/0_1466.png | Bin 1163 -> 1418 bytes .../src/main/assets/emoji/0_1467.png | Bin 1142 -> 2236 bytes .../src/main/assets/emoji/0_1468.png | Bin 3137 -> 2165 bytes .../src/main/assets/emoji/0_1469.png | Bin 2985 -> 2253 bytes TMessagesProj/src/main/assets/emoji/0_147.png | Bin 905 -> 1009 bytes .../src/main/assets/emoji/0_1470.png | Bin 3096 -> 2113 bytes .../src/main/assets/emoji/0_1471.png | Bin 3146 -> 2060 bytes .../src/main/assets/emoji/0_1472.png | Bin 3028 -> 2035 bytes .../src/main/assets/emoji/0_1473.png | Bin 2903 -> 2056 bytes .../src/main/assets/emoji/0_1474.png | Bin 3084 -> 1964 bytes .../src/main/assets/emoji/0_1475.png | Bin 3167 -> 1977 bytes .../src/main/assets/emoji/0_1476.png | Bin 3127 -> 1827 bytes .../src/main/assets/emoji/0_1477.png | Bin 3201 -> 1757 bytes .../src/main/assets/emoji/0_1478.png | Bin 3101 -> 1683 bytes .../src/main/assets/emoji/0_1479.png | Bin 2979 -> 2234 bytes TMessagesProj/src/main/assets/emoji/0_148.png | Bin 751 -> 947 bytes .../src/main/assets/emoji/0_1480.png | Bin 3049 -> 1996 bytes .../src/main/assets/emoji/0_1481.png | Bin 2763 -> 2082 bytes .../src/main/assets/emoji/0_1482.png | Bin 2775 -> 1984 bytes .../src/main/assets/emoji/0_1483.png | Bin 2839 -> 1850 bytes .../src/main/assets/emoji/0_1484.png | Bin 3069 -> 1879 bytes .../src/main/assets/emoji/0_1485.png | Bin 3195 -> 1323 bytes .../src/main/assets/emoji/0_1486.png | Bin 2929 -> 1308 bytes .../src/main/assets/emoji/0_1487.png | Bin 2672 -> 1309 bytes .../src/main/assets/emoji/0_1488.png | Bin 2617 -> 1166 bytes .../src/main/assets/emoji/0_1489.png | Bin 2897 -> 1251 bytes TMessagesProj/src/main/assets/emoji/0_149.png | Bin 978 -> 905 bytes .../src/main/assets/emoji/0_1490.png | Bin 2903 -> 1075 bytes .../src/main/assets/emoji/0_1491.png | Bin 2832 -> 1092 bytes .../src/main/assets/emoji/0_1492.png | Bin 2662 -> 1004 bytes .../src/main/assets/emoji/0_1493.png | Bin 2420 -> 1033 bytes .../src/main/assets/emoji/0_1494.png | Bin 3208 -> 1004 bytes .../src/main/assets/emoji/0_1495.png | Bin 2972 -> 991 bytes .../src/main/assets/emoji/0_1496.png | Bin 3194 -> 872 bytes .../src/main/assets/emoji/0_1497.png | Bin 3201 -> 1128 bytes .../src/main/assets/emoji/0_1498.png | Bin 3169 -> 1164 bytes .../src/main/assets/emoji/0_1499.png | Bin 3104 -> 1150 bytes TMessagesProj/src/main/assets/emoji/0_15.png | Bin 1878 -> 1563 bytes TMessagesProj/src/main/assets/emoji/0_150.png | Bin 928 -> 751 bytes .../src/main/assets/emoji/0_1500.png | Bin 3171 -> 1122 bytes .../src/main/assets/emoji/0_1501.png | Bin 3221 -> 1093 bytes .../src/main/assets/emoji/0_1502.png | Bin 3195 -> 1031 bytes .../src/main/assets/emoji/0_1503.png | Bin 3163 -> 2193 bytes .../src/main/assets/emoji/0_1504.png | Bin 3237 -> 1950 bytes .../src/main/assets/emoji/0_1505.png | Bin 3205 -> 1936 bytes .../src/main/assets/emoji/0_1506.png | Bin 3208 -> 1866 bytes .../src/main/assets/emoji/0_1507.png | Bin 2820 -> 1885 bytes .../src/main/assets/emoji/0_1508.png | Bin 3228 -> 1765 bytes .../src/main/assets/emoji/0_1509.png | Bin 3194 -> 1975 bytes TMessagesProj/src/main/assets/emoji/0_151.png | Bin 818 -> 978 bytes .../src/main/assets/emoji/0_1510.png | Bin 3238 -> 1702 bytes .../src/main/assets/emoji/0_1511.png | Bin 3180 -> 1686 bytes .../src/main/assets/emoji/0_1512.png | Bin 3242 -> 1585 bytes .../src/main/assets/emoji/0_1513.png | Bin 2816 -> 1618 bytes .../src/main/assets/emoji/0_1514.png | Bin 2894 -> 1481 bytes .../src/main/assets/emoji/0_1515.png | Bin 2986 -> 1944 bytes .../src/main/assets/emoji/0_1516.png | Bin 3167 -> 1824 bytes .../src/main/assets/emoji/0_1517.png | Bin 3045 -> 1840 bytes .../src/main/assets/emoji/0_1518.png | Bin 2961 -> 1768 bytes .../src/main/assets/emoji/0_1519.png | Bin 2726 -> 1708 bytes TMessagesProj/src/main/assets/emoji/0_152.png | Bin 848 -> 930 bytes .../src/main/assets/emoji/0_1520.png | Bin 2657 -> 1649 bytes .../src/main/assets/emoji/0_1521.png | Bin 2666 -> 1792 bytes .../src/main/assets/emoji/0_1522.png | Bin 2966 -> 1639 bytes .../src/main/assets/emoji/0_1523.png | Bin 2790 -> 1698 bytes .../src/main/assets/emoji/0_1524.png | Bin 2684 -> 1412 bytes .../src/main/assets/emoji/0_1525.png | Bin 2565 -> 1345 bytes .../src/main/assets/emoji/0_1526.png | Bin 2933 -> 1227 bytes .../src/main/assets/emoji/0_1527.png | Bin 2615 -> 1474 bytes .../src/main/assets/emoji/0_1528.png | Bin 2775 -> 1369 bytes .../src/main/assets/emoji/0_1529.png | Bin 2846 -> 1416 bytes TMessagesProj/src/main/assets/emoji/0_153.png | Bin 715 -> 818 bytes .../src/main/assets/emoji/0_1530.png | Bin 2634 -> 1268 bytes .../src/main/assets/emoji/0_1531.png | Bin 2920 -> 1218 bytes .../src/main/assets/emoji/0_1532.png | Bin 2784 -> 1128 bytes .../src/main/assets/emoji/0_1533.png | Bin 2399 -> 1540 bytes .../src/main/assets/emoji/0_1534.png | Bin 2638 -> 1445 bytes .../src/main/assets/emoji/0_1535.png | Bin 2523 -> 1468 bytes .../src/main/assets/emoji/0_1536.png | Bin 2690 -> 1275 bytes .../src/main/assets/emoji/0_1537.png | Bin 2771 -> 1162 bytes .../src/main/assets/emoji/0_1538.png | Bin 2460 -> 1142 bytes .../src/main/assets/emoji/0_1539.png | Bin 2288 -> 3137 bytes TMessagesProj/src/main/assets/emoji/0_154.png | Bin 647 -> 848 bytes .../src/main/assets/emoji/0_1540.png | Bin 2327 -> 2987 bytes .../src/main/assets/emoji/0_1541.png | Bin 2732 -> 3119 bytes .../src/main/assets/emoji/0_1542.png | Bin 2788 -> 3161 bytes .../src/main/assets/emoji/0_1543.png | Bin 2519 -> 3013 bytes .../src/main/assets/emoji/0_1544.png | Bin 2200 -> 2786 bytes .../src/main/assets/emoji/0_1545.png | Bin 2200 -> 3158 bytes .../src/main/assets/emoji/0_1546.png | Bin 2981 -> 3167 bytes .../src/main/assets/emoji/0_1547.png | Bin 3158 -> 3116 bytes .../src/main/assets/emoji/0_1548.png | Bin 2633 -> 3133 bytes .../src/main/assets/emoji/0_1549.png | Bin 2375 -> 3087 bytes TMessagesProj/src/main/assets/emoji/0_155.png | Bin 1371 -> 715 bytes .../src/main/assets/emoji/0_1550.png | Bin 2439 -> 3068 bytes .../src/main/assets/emoji/0_1551.png | Bin 1961 -> 3044 bytes .../src/main/assets/emoji/0_1552.png | Bin 2752 -> 2766 bytes .../src/main/assets/emoji/0_1553.png | Bin 3127 -> 2892 bytes .../src/main/assets/emoji/0_1554.png | Bin 3895 -> 2829 bytes .../src/main/assets/emoji/0_1555.png | Bin 3357 -> 3210 bytes .../src/main/assets/emoji/0_1556.png | Bin 3640 -> 3068 bytes .../src/main/assets/emoji/0_1557.png | Bin 2775 -> 2845 bytes .../src/main/assets/emoji/0_1558.png | Bin 2814 -> 2672 bytes .../src/main/assets/emoji/0_1559.png | Bin 3794 -> 2719 bytes TMessagesProj/src/main/assets/emoji/0_156.png | Bin 1078 -> 647 bytes .../src/main/assets/emoji/0_1560.png | Bin 3208 -> 2923 bytes .../src/main/assets/emoji/0_1561.png | Bin 3518 -> 3033 bytes .../src/main/assets/emoji/0_1562.png | Bin 2820 -> 2793 bytes .../src/main/assets/emoji/0_1563.png | Bin 2946 -> 2730 bytes .../src/main/assets/emoji/0_1564.png | Bin 3700 -> 2420 bytes .../src/main/assets/emoji/0_1565.png | Bin 3032 -> 3206 bytes .../src/main/assets/emoji/0_1566.png | Bin 3657 -> 2974 bytes .../src/main/assets/emoji/0_1567.png | Bin 2246 -> 3200 bytes .../src/main/assets/emoji/0_1568.png | Bin 2342 -> 3193 bytes .../src/main/assets/emoji/0_1569.png | Bin 3014 -> 3193 bytes TMessagesProj/src/main/assets/emoji/0_157.png | Bin 1041 -> 1369 bytes .../src/main/assets/emoji/0_1570.png | Bin 2302 -> 3116 bytes .../src/main/assets/emoji/0_1571.png | Bin 2508 -> 3211 bytes .../src/main/assets/emoji/0_1572.png | Bin 2016 -> 3224 bytes .../src/main/assets/emoji/0_1573.png | Bin 2212 -> 3214 bytes .../src/main/assets/emoji/0_1574.png | Bin 2724 -> 3195 bytes .../src/main/assets/emoji/0_1575.png | Bin 2253 -> 3179 bytes .../src/main/assets/emoji/0_1576.png | Bin 2416 -> 3212 bytes .../src/main/assets/emoji/0_1577.png | Bin 2393 -> 3206 bytes .../src/main/assets/emoji/0_1578.png | Bin 1973 -> 2820 bytes .../src/main/assets/emoji/0_1579.png | Bin 1555 -> 3177 bytes TMessagesProj/src/main/assets/emoji/0_158.png | Bin 1032 -> 1081 bytes .../src/main/assets/emoji/0_1580.png | Bin 1203 -> 3080 bytes .../src/main/assets/emoji/0_1581.png | Bin 2414 -> 3172 bytes .../src/main/assets/emoji/0_1582.png | Bin 1318 -> 3182 bytes .../src/main/assets/emoji/0_1583.png | Bin 1291 -> 3038 bytes .../src/main/assets/emoji/0_1584.png | Bin 2007 -> 2814 bytes .../src/main/assets/emoji/0_1585.png | Bin 758 -> 2967 bytes .../src/main/assets/emoji/0_1586.png | Bin 1734 -> 2980 bytes .../src/main/assets/emoji/0_1587.png | Bin 2521 -> 3177 bytes .../src/main/assets/emoji/0_1588.png | Bin 1463 -> 3077 bytes .../src/main/assets/emoji/0_1589.png | Bin 2273 -> 2921 bytes TMessagesProj/src/main/assets/emoji/0_159.png | Bin 915 -> 1042 bytes .../src/main/assets/emoji/0_1590.png | Bin 2624 -> 2727 bytes .../src/main/assets/emoji/0_1591.png | Bin 1575 -> 2657 bytes .../src/main/assets/emoji/0_1592.png | Bin 1261 -> 2666 bytes .../src/main/assets/emoji/0_1593.png | Bin 847 -> 2984 bytes .../src/main/assets/emoji/0_1594.png | Bin 1852 -> 2851 bytes .../src/main/assets/emoji/0_1595.png | Bin 1173 -> 2784 bytes .../src/main/assets/emoji/0_1596.png | Bin 1291 -> 2644 bytes .../src/main/assets/emoji/0_1597.png | Bin 1630 -> 2959 bytes .../src/main/assets/emoji/0_1598.png | Bin 1289 -> 2615 bytes .../src/main/assets/emoji/0_1599.png | Bin 1911 -> 2751 bytes TMessagesProj/src/main/assets/emoji/0_16.png | Bin 2237 -> 1877 bytes TMessagesProj/src/main/assets/emoji/0_160.png | Bin 835 -> 1026 bytes .../src/main/assets/emoji/0_1600.png | Bin 1537 -> 2797 bytes .../src/main/assets/emoji/0_1601.png | Bin 1195 -> 2594 bytes .../src/main/assets/emoji/0_1602.png | Bin 1517 -> 2934 bytes .../src/main/assets/emoji/0_1603.png | Bin 1172 -> 2768 bytes .../src/main/assets/emoji/0_1604.png | Bin 913 -> 2399 bytes .../src/main/assets/emoji/0_1605.png | Bin 2130 -> 2463 bytes .../src/main/assets/emoji/0_1606.png | Bin 1363 -> 2597 bytes .../src/main/assets/emoji/0_1607.png | Bin 1871 -> 2694 bytes .../src/main/assets/emoji/0_1608.png | Bin 2637 -> 2861 bytes .../src/main/assets/emoji/0_1609.png | Bin 1964 -> 2563 bytes TMessagesProj/src/main/assets/emoji/0_161.png | Bin 1065 -> 915 bytes .../src/main/assets/emoji/0_1610.png | Bin 1471 -> 2288 bytes .../src/main/assets/emoji/0_1611.png | Bin 1324 -> 2423 bytes .../src/main/assets/emoji/0_1612.png | Bin 1941 -> 2656 bytes .../src/main/assets/emoji/0_1613.png | Bin 1367 -> 2814 bytes .../src/main/assets/emoji/0_1614.png | Bin 2025 -> 2483 bytes .../src/main/assets/emoji/0_1615.png | Bin 1983 -> 2428 bytes .../src/main/assets/emoji/0_1616.png | Bin 944 -> 2201 bytes .../src/main/assets/emoji/0_1617.png | Bin 596 -> 2981 bytes .../src/main/assets/emoji/0_1618.png | Bin 1802 -> 3159 bytes .../src/main/assets/emoji/0_1619.png | Bin 1438 -> 2632 bytes TMessagesProj/src/main/assets/emoji/0_162.png | Bin 849 -> 835 bytes .../src/main/assets/emoji/0_1620.png | Bin 0 -> 2375 bytes .../src/main/assets/emoji/0_1621.png | Bin 0 -> 2440 bytes .../src/main/assets/emoji/0_1622.png | Bin 0 -> 1960 bytes .../src/main/assets/emoji/0_1623.png | Bin 0 -> 2752 bytes .../src/main/assets/emoji/0_1624.png | Bin 0 -> 3132 bytes .../src/main/assets/emoji/0_1625.png | Bin 0 -> 3898 bytes .../src/main/assets/emoji/0_1626.png | Bin 0 -> 3357 bytes .../src/main/assets/emoji/0_1627.png | Bin 0 -> 3638 bytes .../src/main/assets/emoji/0_1628.png | Bin 0 -> 2773 bytes .../src/main/assets/emoji/0_1629.png | Bin 0 -> 2815 bytes TMessagesProj/src/main/assets/emoji/0_163.png | Bin 762 -> 1065 bytes .../src/main/assets/emoji/0_1630.png | Bin 0 -> 3794 bytes .../src/main/assets/emoji/0_1631.png | Bin 0 -> 3210 bytes .../src/main/assets/emoji/0_1632.png | Bin 0 -> 3519 bytes .../src/main/assets/emoji/0_1633.png | Bin 0 -> 2819 bytes .../src/main/assets/emoji/0_1634.png | Bin 0 -> 2945 bytes .../src/main/assets/emoji/0_1635.png | Bin 0 -> 3698 bytes .../src/main/assets/emoji/0_1636.png | Bin 0 -> 3033 bytes .../src/main/assets/emoji/0_1637.png | Bin 0 -> 3654 bytes .../src/main/assets/emoji/0_1638.png | Bin 0 -> 2246 bytes .../src/main/assets/emoji/0_1639.png | Bin 0 -> 2345 bytes TMessagesProj/src/main/assets/emoji/0_164.png | Bin 808 -> 850 bytes .../src/main/assets/emoji/0_1640.png | Bin 0 -> 3016 bytes .../src/main/assets/emoji/0_1641.png | Bin 0 -> 2302 bytes .../src/main/assets/emoji/0_1642.png | Bin 0 -> 2509 bytes .../src/main/assets/emoji/0_1643.png | Bin 0 -> 2018 bytes .../src/main/assets/emoji/0_1644.png | Bin 0 -> 2212 bytes .../src/main/assets/emoji/0_1645.png | Bin 0 -> 2725 bytes .../src/main/assets/emoji/0_1646.png | Bin 0 -> 2253 bytes .../src/main/assets/emoji/0_1647.png | Bin 0 -> 2416 bytes .../src/main/assets/emoji/0_1648.png | Bin 0 -> 2807 bytes .../src/main/assets/emoji/0_1649.png | Bin 0 -> 2395 bytes TMessagesProj/src/main/assets/emoji/0_165.png | Bin 698 -> 763 bytes .../src/main/assets/emoji/0_1650.png | Bin 0 -> 1973 bytes .../src/main/assets/emoji/0_1651.png | Bin 0 -> 1431 bytes .../src/main/assets/emoji/0_1652.png | Bin 0 -> 1553 bytes .../src/main/assets/emoji/0_1653.png | Bin 0 -> 1203 bytes .../src/main/assets/emoji/0_1654.png | Bin 0 -> 2415 bytes .../src/main/assets/emoji/0_1655.png | Bin 0 -> 1320 bytes .../src/main/assets/emoji/0_1656.png | Bin 0 -> 1289 bytes .../src/main/assets/emoji/0_1657.png | Bin 0 -> 2006 bytes .../src/main/assets/emoji/0_1658.png | Bin 0 -> 761 bytes .../src/main/assets/emoji/0_1659.png | Bin 0 -> 1734 bytes TMessagesProj/src/main/assets/emoji/0_166.png | Bin 570 -> 808 bytes .../src/main/assets/emoji/0_1660.png | Bin 0 -> 2521 bytes .../src/main/assets/emoji/0_1661.png | Bin 0 -> 1461 bytes .../src/main/assets/emoji/0_1662.png | Bin 0 -> 2271 bytes .../src/main/assets/emoji/0_1663.png | Bin 0 -> 1260 bytes .../src/main/assets/emoji/0_1664.png | Bin 0 -> 2622 bytes .../src/main/assets/emoji/0_1665.png | Bin 0 -> 1575 bytes .../src/main/assets/emoji/0_1666.png | Bin 0 -> 1197 bytes .../src/main/assets/emoji/0_1667.png | Bin 0 -> 846 bytes .../src/main/assets/emoji/0_1668.png | Bin 0 -> 1851 bytes .../src/main/assets/emoji/0_1669.png | Bin 0 -> 1172 bytes TMessagesProj/src/main/assets/emoji/0_167.png | Bin 947 -> 698 bytes .../src/main/assets/emoji/0_1670.png | Bin 0 -> 1291 bytes .../src/main/assets/emoji/0_1671.png | Bin 0 -> 1630 bytes .../src/main/assets/emoji/0_1672.png | Bin 0 -> 1288 bytes .../src/main/assets/emoji/0_1673.png | Bin 0 -> 1915 bytes .../src/main/assets/emoji/0_1674.png | Bin 0 -> 1539 bytes .../src/main/assets/emoji/0_1675.png | Bin 0 -> 1195 bytes .../src/main/assets/emoji/0_1676.png | Bin 0 -> 1518 bytes .../src/main/assets/emoji/0_1677.png | Bin 0 -> 1172 bytes .../src/main/assets/emoji/0_1678.png | Bin 0 -> 910 bytes .../src/main/assets/emoji/0_1679.png | Bin 0 -> 2133 bytes TMessagesProj/src/main/assets/emoji/0_168.png | Bin 908 -> 570 bytes .../src/main/assets/emoji/0_1680.png | Bin 0 -> 1366 bytes .../src/main/assets/emoji/0_1681.png | Bin 0 -> 1871 bytes .../src/main/assets/emoji/0_1682.png | Bin 0 -> 1497 bytes .../src/main/assets/emoji/0_1683.png | Bin 0 -> 2638 bytes .../src/main/assets/emoji/0_1684.png | Bin 0 -> 1966 bytes .../src/main/assets/emoji/0_1685.png | Bin 0 -> 1471 bytes .../src/main/assets/emoji/0_1686.png | Bin 0 -> 1325 bytes .../src/main/assets/emoji/0_1687.png | Bin 0 -> 1939 bytes .../src/main/assets/emoji/0_1688.png | Bin 0 -> 1371 bytes .../src/main/assets/emoji/0_1689.png | Bin 0 -> 2025 bytes TMessagesProj/src/main/assets/emoji/0_169.png | Bin 765 -> 947 bytes .../src/main/assets/emoji/0_1690.png | Bin 0 -> 1983 bytes .../src/main/assets/emoji/0_1691.png | Bin 0 -> 943 bytes .../src/main/assets/emoji/0_1692.png | Bin 0 -> 596 bytes .../src/main/assets/emoji/0_1693.png | Bin 0 -> 1802 bytes .../src/main/assets/emoji/0_1694.png | Bin 0 -> 1436 bytes TMessagesProj/src/main/assets/emoji/0_17.png | Bin 1991 -> 2234 bytes TMessagesProj/src/main/assets/emoji/0_170.png | Bin 733 -> 907 bytes TMessagesProj/src/main/assets/emoji/0_171.png | Bin 632 -> 762 bytes TMessagesProj/src/main/assets/emoji/0_172.png | Bin 588 -> 732 bytes TMessagesProj/src/main/assets/emoji/0_173.png | Bin 1044 -> 632 bytes TMessagesProj/src/main/assets/emoji/0_174.png | Bin 884 -> 588 bytes TMessagesProj/src/main/assets/emoji/0_175.png | Bin 874 -> 1043 bytes TMessagesProj/src/main/assets/emoji/0_176.png | Bin 855 -> 885 bytes TMessagesProj/src/main/assets/emoji/0_177.png | Bin 767 -> 876 bytes TMessagesProj/src/main/assets/emoji/0_178.png | Bin 732 -> 855 bytes TMessagesProj/src/main/assets/emoji/0_179.png | Bin 1206 -> 767 bytes TMessagesProj/src/main/assets/emoji/0_18.png | Bin 1538 -> 1991 bytes TMessagesProj/src/main/assets/emoji/0_180.png | Bin 983 -> 732 bytes TMessagesProj/src/main/assets/emoji/0_181.png | Bin 899 -> 1206 bytes TMessagesProj/src/main/assets/emoji/0_182.png | Bin 876 -> 983 bytes TMessagesProj/src/main/assets/emoji/0_183.png | Bin 771 -> 898 bytes TMessagesProj/src/main/assets/emoji/0_184.png | Bin 744 -> 877 bytes TMessagesProj/src/main/assets/emoji/0_185.png | Bin 1069 -> 771 bytes TMessagesProj/src/main/assets/emoji/0_186.png | Bin 871 -> 744 bytes TMessagesProj/src/main/assets/emoji/0_187.png | Bin 843 -> 1071 bytes TMessagesProj/src/main/assets/emoji/0_188.png | Bin 786 -> 870 bytes TMessagesProj/src/main/assets/emoji/0_189.png | Bin 677 -> 843 bytes TMessagesProj/src/main/assets/emoji/0_19.png | Bin 1571 -> 1537 bytes TMessagesProj/src/main/assets/emoji/0_190.png | Bin 630 -> 785 bytes TMessagesProj/src/main/assets/emoji/0_191.png | Bin 1060 -> 677 bytes TMessagesProj/src/main/assets/emoji/0_192.png | Bin 903 -> 631 bytes TMessagesProj/src/main/assets/emoji/0_193.png | Bin 815 -> 1060 bytes TMessagesProj/src/main/assets/emoji/0_194.png | Bin 810 -> 903 bytes TMessagesProj/src/main/assets/emoji/0_195.png | Bin 770 -> 818 bytes TMessagesProj/src/main/assets/emoji/0_196.png | Bin 669 -> 810 bytes TMessagesProj/src/main/assets/emoji/0_197.png | Bin 1252 -> 770 bytes TMessagesProj/src/main/assets/emoji/0_198.png | Bin 1130 -> 673 bytes TMessagesProj/src/main/assets/emoji/0_199.png | Bin 1003 -> 1253 bytes TMessagesProj/src/main/assets/emoji/0_2.png | Bin 1700 -> 1703 bytes TMessagesProj/src/main/assets/emoji/0_20.png | Bin 1559 -> 1572 bytes TMessagesProj/src/main/assets/emoji/0_200.png | Bin 1056 -> 1129 bytes TMessagesProj/src/main/assets/emoji/0_201.png | Bin 906 -> 1003 bytes TMessagesProj/src/main/assets/emoji/0_202.png | Bin 848 -> 1055 bytes TMessagesProj/src/main/assets/emoji/0_203.png | Bin 890 -> 907 bytes TMessagesProj/src/main/assets/emoji/0_204.png | Bin 784 -> 848 bytes TMessagesProj/src/main/assets/emoji/0_205.png | Bin 690 -> 1197 bytes TMessagesProj/src/main/assets/emoji/0_206.png | Bin 723 -> 809 bytes TMessagesProj/src/main/assets/emoji/0_207.png | Bin 635 -> 788 bytes TMessagesProj/src/main/assets/emoji/0_208.png | Bin 554 -> 727 bytes TMessagesProj/src/main/assets/emoji/0_209.png | Bin 786 -> 755 bytes TMessagesProj/src/main/assets/emoji/0_21.png | Bin 1805 -> 1557 bytes TMessagesProj/src/main/assets/emoji/0_210.png | Bin 812 -> 666 bytes TMessagesProj/src/main/assets/emoji/0_211.png | Bin 732 -> 888 bytes TMessagesProj/src/main/assets/emoji/0_212.png | Bin 767 -> 784 bytes TMessagesProj/src/main/assets/emoji/0_213.png | Bin 621 -> 690 bytes TMessagesProj/src/main/assets/emoji/0_214.png | Bin 498 -> 720 bytes TMessagesProj/src/main/assets/emoji/0_215.png | Bin 841 -> 636 bytes TMessagesProj/src/main/assets/emoji/0_216.png | Bin 802 -> 554 bytes TMessagesProj/src/main/assets/emoji/0_217.png | Bin 728 -> 786 bytes TMessagesProj/src/main/assets/emoji/0_218.png | Bin 750 -> 812 bytes TMessagesProj/src/main/assets/emoji/0_219.png | Bin 664 -> 729 bytes TMessagesProj/src/main/assets/emoji/0_22.png | Bin 1779 -> 1806 bytes TMessagesProj/src/main/assets/emoji/0_220.png | Bin 530 -> 767 bytes TMessagesProj/src/main/assets/emoji/0_221.png | Bin 814 -> 626 bytes TMessagesProj/src/main/assets/emoji/0_222.png | Bin 840 -> 498 bytes TMessagesProj/src/main/assets/emoji/0_223.png | Bin 768 -> 840 bytes TMessagesProj/src/main/assets/emoji/0_224.png | Bin 706 -> 799 bytes TMessagesProj/src/main/assets/emoji/0_225.png | Bin 641 -> 730 bytes TMessagesProj/src/main/assets/emoji/0_226.png | Bin 584 -> 751 bytes TMessagesProj/src/main/assets/emoji/0_227.png | Bin 876 -> 664 bytes TMessagesProj/src/main/assets/emoji/0_228.png | Bin 827 -> 526 bytes TMessagesProj/src/main/assets/emoji/0_229.png | Bin 696 -> 816 bytes TMessagesProj/src/main/assets/emoji/0_23.png | Bin 1821 -> 1778 bytes TMessagesProj/src/main/assets/emoji/0_230.png | Bin 726 -> 840 bytes TMessagesProj/src/main/assets/emoji/0_231.png | Bin 680 -> 765 bytes TMessagesProj/src/main/assets/emoji/0_232.png | Bin 529 -> 707 bytes TMessagesProj/src/main/assets/emoji/0_233.png | Bin 986 -> 645 bytes TMessagesProj/src/main/assets/emoji/0_234.png | Bin 809 -> 584 bytes TMessagesProj/src/main/assets/emoji/0_235.png | Bin 791 -> 877 bytes TMessagesProj/src/main/assets/emoji/0_236.png | Bin 790 -> 827 bytes TMessagesProj/src/main/assets/emoji/0_237.png | Bin 727 -> 696 bytes TMessagesProj/src/main/assets/emoji/0_238.png | Bin 680 -> 727 bytes TMessagesProj/src/main/assets/emoji/0_239.png | Bin 1178 -> 680 bytes TMessagesProj/src/main/assets/emoji/0_24.png | Bin 2067 -> 1821 bytes TMessagesProj/src/main/assets/emoji/0_240.png | Bin 1104 -> 529 bytes TMessagesProj/src/main/assets/emoji/0_241.png | Bin 972 -> 989 bytes TMessagesProj/src/main/assets/emoji/0_242.png | Bin 1052 -> 809 bytes TMessagesProj/src/main/assets/emoji/0_243.png | Bin 951 -> 792 bytes TMessagesProj/src/main/assets/emoji/0_244.png | Bin 823 -> 790 bytes TMessagesProj/src/main/assets/emoji/0_245.png | Bin 1130 -> 727 bytes TMessagesProj/src/main/assets/emoji/0_246.png | Bin 1029 -> 680 bytes TMessagesProj/src/main/assets/emoji/0_247.png | Bin 862 -> 1179 bytes TMessagesProj/src/main/assets/emoji/0_248.png | Bin 893 -> 1100 bytes TMessagesProj/src/main/assets/emoji/0_249.png | Bin 850 -> 970 bytes TMessagesProj/src/main/assets/emoji/0_25.png | Bin 2446 -> 2065 bytes TMessagesProj/src/main/assets/emoji/0_250.png | Bin 711 -> 1050 bytes TMessagesProj/src/main/assets/emoji/0_251.png | Bin 1323 -> 948 bytes TMessagesProj/src/main/assets/emoji/0_252.png | Bin 1146 -> 820 bytes TMessagesProj/src/main/assets/emoji/0_253.png | Bin 1121 -> 1130 bytes TMessagesProj/src/main/assets/emoji/0_254.png | Bin 1179 -> 1028 bytes TMessagesProj/src/main/assets/emoji/0_255.png | Bin 1013 -> 862 bytes TMessagesProj/src/main/assets/emoji/0_256.png | Bin 899 -> 893 bytes TMessagesProj/src/main/assets/emoji/0_257.png | Bin 1155 -> 850 bytes TMessagesProj/src/main/assets/emoji/0_258.png | Bin 1083 -> 711 bytes TMessagesProj/src/main/assets/emoji/0_259.png | Bin 1052 -> 1327 bytes TMessagesProj/src/main/assets/emoji/0_26.png | Bin 1381 -> 2448 bytes TMessagesProj/src/main/assets/emoji/0_260.png | Bin 1073 -> 1149 bytes TMessagesProj/src/main/assets/emoji/0_261.png | Bin 914 -> 1123 bytes TMessagesProj/src/main/assets/emoji/0_262.png | Bin 812 -> 1180 bytes TMessagesProj/src/main/assets/emoji/0_263.png | Bin 1657 -> 1014 bytes TMessagesProj/src/main/assets/emoji/0_264.png | Bin 1469 -> 899 bytes TMessagesProj/src/main/assets/emoji/0_265.png | Bin 1344 -> 1150 bytes TMessagesProj/src/main/assets/emoji/0_266.png | Bin 1432 -> 1085 bytes TMessagesProj/src/main/assets/emoji/0_267.png | Bin 1304 -> 1051 bytes TMessagesProj/src/main/assets/emoji/0_268.png | Bin 1165 -> 1072 bytes TMessagesProj/src/main/assets/emoji/0_269.png | Bin 1022 -> 914 bytes TMessagesProj/src/main/assets/emoji/0_27.png | Bin 2192 -> 1382 bytes TMessagesProj/src/main/assets/emoji/0_270.png | Bin 1070 -> 812 bytes TMessagesProj/src/main/assets/emoji/0_271.png | Bin 864 -> 1654 bytes TMessagesProj/src/main/assets/emoji/0_272.png | Bin 806 -> 1468 bytes TMessagesProj/src/main/assets/emoji/0_273.png | Bin 771 -> 1350 bytes TMessagesProj/src/main/assets/emoji/0_274.png | Bin 647 -> 1436 bytes TMessagesProj/src/main/assets/emoji/0_275.png | Bin 1266 -> 1303 bytes TMessagesProj/src/main/assets/emoji/0_276.png | Bin 1041 -> 1170 bytes TMessagesProj/src/main/assets/emoji/0_277.png | Bin 963 -> 1023 bytes TMessagesProj/src/main/assets/emoji/0_278.png | Bin 895 -> 1069 bytes TMessagesProj/src/main/assets/emoji/0_279.png | Bin 868 -> 867 bytes TMessagesProj/src/main/assets/emoji/0_28.png | Bin 2095 -> 2191 bytes TMessagesProj/src/main/assets/emoji/0_280.png | Bin 748 -> 807 bytes TMessagesProj/src/main/assets/emoji/0_281.png | Bin 1531 -> 771 bytes TMessagesProj/src/main/assets/emoji/0_282.png | Bin 728 -> 647 bytes TMessagesProj/src/main/assets/emoji/0_283.png | Bin 672 -> 1264 bytes TMessagesProj/src/main/assets/emoji/0_284.png | Bin 622 -> 1038 bytes TMessagesProj/src/main/assets/emoji/0_285.png | Bin 690 -> 964 bytes TMessagesProj/src/main/assets/emoji/0_286.png | Bin 614 -> 890 bytes TMessagesProj/src/main/assets/emoji/0_287.png | Bin 564 -> 867 bytes TMessagesProj/src/main/assets/emoji/0_288.png | Bin 1543 -> 748 bytes TMessagesProj/src/main/assets/emoji/0_289.png | Bin 1355 -> 1531 bytes TMessagesProj/src/main/assets/emoji/0_29.png | Bin 1749 -> 2097 bytes TMessagesProj/src/main/assets/emoji/0_290.png | Bin 1296 -> 728 bytes TMessagesProj/src/main/assets/emoji/0_291.png | Bin 1281 -> 676 bytes TMessagesProj/src/main/assets/emoji/0_292.png | Bin 1104 -> 620 bytes TMessagesProj/src/main/assets/emoji/0_293.png | Bin 988 -> 690 bytes TMessagesProj/src/main/assets/emoji/0_294.png | Bin 1520 -> 614 bytes TMessagesProj/src/main/assets/emoji/0_295.png | Bin 1409 -> 564 bytes TMessagesProj/src/main/assets/emoji/0_296.png | Bin 1310 -> 1540 bytes TMessagesProj/src/main/assets/emoji/0_297.png | Bin 1239 -> 1354 bytes TMessagesProj/src/main/assets/emoji/0_298.png | Bin 1165 -> 1296 bytes TMessagesProj/src/main/assets/emoji/0_299.png | Bin 1049 -> 1281 bytes TMessagesProj/src/main/assets/emoji/0_3.png | Bin 1935 -> 1935 bytes TMessagesProj/src/main/assets/emoji/0_30.png | Bin 2401 -> 1749 bytes TMessagesProj/src/main/assets/emoji/0_300.png | Bin 1022 -> 1103 bytes TMessagesProj/src/main/assets/emoji/0_301.png | Bin 920 -> 988 bytes TMessagesProj/src/main/assets/emoji/0_302.png | Bin 818 -> 1519 bytes TMessagesProj/src/main/assets/emoji/0_303.png | Bin 919 -> 1410 bytes TMessagesProj/src/main/assets/emoji/0_304.png | Bin 822 -> 1309 bytes TMessagesProj/src/main/assets/emoji/0_305.png | Bin 709 -> 1239 bytes TMessagesProj/src/main/assets/emoji/0_306.png | Bin 790 -> 1167 bytes TMessagesProj/src/main/assets/emoji/0_307.png | Bin 728 -> 1046 bytes TMessagesProj/src/main/assets/emoji/0_308.png | Bin 677 -> 1021 bytes TMessagesProj/src/main/assets/emoji/0_309.png | Bin 695 -> 921 bytes TMessagesProj/src/main/assets/emoji/0_31.png | Bin 3429 -> 2219 bytes TMessagesProj/src/main/assets/emoji/0_310.png | Bin 625 -> 818 bytes TMessagesProj/src/main/assets/emoji/0_311.png | Bin 566 -> 921 bytes TMessagesProj/src/main/assets/emoji/0_312.png | Bin 1181 -> 822 bytes TMessagesProj/src/main/assets/emoji/0_313.png | Bin 1260 -> 709 bytes TMessagesProj/src/main/assets/emoji/0_314.png | Bin 1776 -> 791 bytes TMessagesProj/src/main/assets/emoji/0_315.png | Bin 1174 -> 727 bytes TMessagesProj/src/main/assets/emoji/0_316.png | Bin 1004 -> 676 bytes TMessagesProj/src/main/assets/emoji/0_317.png | Bin 1342 -> 691 bytes TMessagesProj/src/main/assets/emoji/0_318.png | Bin 841 -> 623 bytes TMessagesProj/src/main/assets/emoji/0_319.png | Bin 732 -> 566 bytes TMessagesProj/src/main/assets/emoji/0_32.png | Bin 1572 -> 2401 bytes TMessagesProj/src/main/assets/emoji/0_320.png | Bin 704 -> 1180 bytes TMessagesProj/src/main/assets/emoji/0_321.png | Bin 693 -> 1259 bytes TMessagesProj/src/main/assets/emoji/0_322.png | Bin 638 -> 1776 bytes TMessagesProj/src/main/assets/emoji/0_323.png | Bin 645 -> 1175 bytes TMessagesProj/src/main/assets/emoji/0_324.png | Bin 1452 -> 1001 bytes TMessagesProj/src/main/assets/emoji/0_325.png | Bin 1214 -> 1338 bytes TMessagesProj/src/main/assets/emoji/0_326.png | Bin 1173 -> 841 bytes TMessagesProj/src/main/assets/emoji/0_327.png | Bin 1151 -> 729 bytes TMessagesProj/src/main/assets/emoji/0_328.png | Bin 1050 -> 704 bytes TMessagesProj/src/main/assets/emoji/0_329.png | Bin 976 -> 693 bytes TMessagesProj/src/main/assets/emoji/0_33.png | Bin 1532 -> 3432 bytes TMessagesProj/src/main/assets/emoji/0_330.png | Bin 879 -> 638 bytes TMessagesProj/src/main/assets/emoji/0_331.png | Bin 769 -> 645 bytes TMessagesProj/src/main/assets/emoji/0_332.png | Bin 686 -> 1451 bytes TMessagesProj/src/main/assets/emoji/0_333.png | Bin 729 -> 1215 bytes TMessagesProj/src/main/assets/emoji/0_334.png | Bin 663 -> 1173 bytes TMessagesProj/src/main/assets/emoji/0_335.png | Bin 529 -> 1151 bytes TMessagesProj/src/main/assets/emoji/0_336.png | Bin 653 -> 1051 bytes TMessagesProj/src/main/assets/emoji/0_337.png | Bin 1708 -> 974 bytes TMessagesProj/src/main/assets/emoji/0_338.png | Bin 996 -> 880 bytes TMessagesProj/src/main/assets/emoji/0_339.png | Bin 1811 -> 769 bytes TMessagesProj/src/main/assets/emoji/0_34.png | Bin 1413 -> 1577 bytes TMessagesProj/src/main/assets/emoji/0_340.png | Bin 968 -> 687 bytes TMessagesProj/src/main/assets/emoji/0_341.png | Bin 824 -> 730 bytes TMessagesProj/src/main/assets/emoji/0_342.png | Bin 817 -> 664 bytes TMessagesProj/src/main/assets/emoji/0_343.png | Bin 1756 -> 531 bytes TMessagesProj/src/main/assets/emoji/0_344.png | Bin 1700 -> 654 bytes TMessagesProj/src/main/assets/emoji/0_345.png | Bin 1612 -> 1706 bytes TMessagesProj/src/main/assets/emoji/0_346.png | Bin 1613 -> 996 bytes TMessagesProj/src/main/assets/emoji/0_347.png | Bin 1445 -> 2625 bytes TMessagesProj/src/main/assets/emoji/0_348.png | Bin 1265 -> 1997 bytes TMessagesProj/src/main/assets/emoji/0_349.png | Bin 1975 -> 1811 bytes TMessagesProj/src/main/assets/emoji/0_35.png | Bin 1520 -> 1531 bytes TMessagesProj/src/main/assets/emoji/0_350.png | Bin 1932 -> 963 bytes TMessagesProj/src/main/assets/emoji/0_351.png | Bin 2038 -> 824 bytes TMessagesProj/src/main/assets/emoji/0_352.png | Bin 1716 -> 817 bytes TMessagesProj/src/main/assets/emoji/0_353.png | Bin 1608 -> 984 bytes TMessagesProj/src/main/assets/emoji/0_354.png | Bin 1406 -> 1754 bytes TMessagesProj/src/main/assets/emoji/0_355.png | Bin 1864 -> 1699 bytes TMessagesProj/src/main/assets/emoji/0_356.png | Bin 1887 -> 1612 bytes TMessagesProj/src/main/assets/emoji/0_357.png | Bin 1896 -> 1614 bytes TMessagesProj/src/main/assets/emoji/0_358.png | Bin 1715 -> 1443 bytes TMessagesProj/src/main/assets/emoji/0_359.png | Bin 1528 -> 1264 bytes TMessagesProj/src/main/assets/emoji/0_36.png | Bin 1560 -> 1419 bytes TMessagesProj/src/main/assets/emoji/0_360.png | Bin 1490 -> 1974 bytes TMessagesProj/src/main/assets/emoji/0_361.png | Bin 1765 -> 1931 bytes TMessagesProj/src/main/assets/emoji/0_362.png | Bin 1683 -> 2037 bytes TMessagesProj/src/main/assets/emoji/0_363.png | Bin 1768 -> 1715 bytes TMessagesProj/src/main/assets/emoji/0_364.png | Bin 1663 -> 1606 bytes TMessagesProj/src/main/assets/emoji/0_365.png | Bin 1471 -> 1405 bytes TMessagesProj/src/main/assets/emoji/0_366.png | Bin 1325 -> 1865 bytes TMessagesProj/src/main/assets/emoji/0_367.png | Bin 2010 -> 1886 bytes TMessagesProj/src/main/assets/emoji/0_368.png | Bin 1796 -> 1898 bytes TMessagesProj/src/main/assets/emoji/0_369.png | Bin 1997 -> 1716 bytes TMessagesProj/src/main/assets/emoji/0_37.png | Bin 1488 -> 1519 bytes TMessagesProj/src/main/assets/emoji/0_370.png | Bin 1794 -> 1527 bytes TMessagesProj/src/main/assets/emoji/0_371.png | Bin 1683 -> 1487 bytes TMessagesProj/src/main/assets/emoji/0_372.png | Bin 1434 -> 1765 bytes TMessagesProj/src/main/assets/emoji/0_373.png | Bin 1728 -> 1683 bytes TMessagesProj/src/main/assets/emoji/0_374.png | Bin 1712 -> 1767 bytes TMessagesProj/src/main/assets/emoji/0_375.png | Bin 1685 -> 1665 bytes TMessagesProj/src/main/assets/emoji/0_376.png | Bin 1539 -> 1471 bytes TMessagesProj/src/main/assets/emoji/0_377.png | Bin 1464 -> 1325 bytes TMessagesProj/src/main/assets/emoji/0_378.png | Bin 1292 -> 2007 bytes TMessagesProj/src/main/assets/emoji/0_379.png | Bin 1571 -> 1796 bytes TMessagesProj/src/main/assets/emoji/0_38.png | Bin 1515 -> 1560 bytes TMessagesProj/src/main/assets/emoji/0_380.png | Bin 1674 -> 1999 bytes TMessagesProj/src/main/assets/emoji/0_381.png | Bin 1743 -> 1797 bytes TMessagesProj/src/main/assets/emoji/0_382.png | Bin 1506 -> 1681 bytes TMessagesProj/src/main/assets/emoji/0_383.png | Bin 1377 -> 1435 bytes TMessagesProj/src/main/assets/emoji/0_384.png | Bin 1257 -> 1726 bytes TMessagesProj/src/main/assets/emoji/0_385.png | Bin 2081 -> 1711 bytes TMessagesProj/src/main/assets/emoji/0_386.png | Bin 2034 -> 1679 bytes TMessagesProj/src/main/assets/emoji/0_387.png | Bin 2441 -> 1539 bytes TMessagesProj/src/main/assets/emoji/0_388.png | Bin 2189 -> 1464 bytes TMessagesProj/src/main/assets/emoji/0_389.png | Bin 1881 -> 1292 bytes TMessagesProj/src/main/assets/emoji/0_39.png | Bin 1524 -> 1490 bytes TMessagesProj/src/main/assets/emoji/0_390.png | Bin 1895 -> 1574 bytes TMessagesProj/src/main/assets/emoji/0_391.png | Bin 1938 -> 1673 bytes TMessagesProj/src/main/assets/emoji/0_392.png | Bin 1804 -> 1741 bytes TMessagesProj/src/main/assets/emoji/0_393.png | Bin 2055 -> 1511 bytes TMessagesProj/src/main/assets/emoji/0_394.png | Bin 1715 -> 1375 bytes TMessagesProj/src/main/assets/emoji/0_395.png | Bin 1639 -> 1257 bytes TMessagesProj/src/main/assets/emoji/0_396.png | Bin 1475 -> 2079 bytes TMessagesProj/src/main/assets/emoji/0_397.png | Bin 1814 -> 2034 bytes TMessagesProj/src/main/assets/emoji/0_398.png | Bin 1958 -> 2441 bytes TMessagesProj/src/main/assets/emoji/0_399.png | Bin 2032 -> 2190 bytes TMessagesProj/src/main/assets/emoji/0_4.png | Bin 1775 -> 1780 bytes TMessagesProj/src/main/assets/emoji/0_40.png | Bin 1625 -> 1515 bytes TMessagesProj/src/main/assets/emoji/0_400.png | Bin 1874 -> 1881 bytes TMessagesProj/src/main/assets/emoji/0_401.png | Bin 1610 -> 1895 bytes TMessagesProj/src/main/assets/emoji/0_402.png | Bin 1541 -> 1939 bytes TMessagesProj/src/main/assets/emoji/0_403.png | Bin 1931 -> 1804 bytes TMessagesProj/src/main/assets/emoji/0_404.png | Bin 1926 -> 2055 bytes TMessagesProj/src/main/assets/emoji/0_405.png | Bin 1878 -> 1715 bytes TMessagesProj/src/main/assets/emoji/0_406.png | Bin 1851 -> 1639 bytes TMessagesProj/src/main/assets/emoji/0_407.png | Bin 1688 -> 1475 bytes TMessagesProj/src/main/assets/emoji/0_408.png | Bin 1648 -> 1816 bytes TMessagesProj/src/main/assets/emoji/0_409.png | Bin 1686 -> 1960 bytes TMessagesProj/src/main/assets/emoji/0_41.png | Bin 1642 -> 1523 bytes TMessagesProj/src/main/assets/emoji/0_410.png | Bin 1926 -> 2032 bytes TMessagesProj/src/main/assets/emoji/0_411.png | Bin 1729 -> 1874 bytes TMessagesProj/src/main/assets/emoji/0_412.png | Bin 1760 -> 1610 bytes TMessagesProj/src/main/assets/emoji/0_413.png | Bin 1691 -> 1541 bytes TMessagesProj/src/main/assets/emoji/0_414.png | Bin 1570 -> 1930 bytes TMessagesProj/src/main/assets/emoji/0_415.png | Bin 1807 -> 1925 bytes TMessagesProj/src/main/assets/emoji/0_416.png | Bin 1763 -> 1876 bytes TMessagesProj/src/main/assets/emoji/0_417.png | Bin 1721 -> 1846 bytes TMessagesProj/src/main/assets/emoji/0_418.png | Bin 1820 -> 1687 bytes TMessagesProj/src/main/assets/emoji/0_419.png | Bin 1730 -> 1648 bytes TMessagesProj/src/main/assets/emoji/0_42.png | Bin 1953 -> 1625 bytes TMessagesProj/src/main/assets/emoji/0_420.png | Bin 1643 -> 1684 bytes TMessagesProj/src/main/assets/emoji/0_421.png | Bin 2097 -> 1927 bytes TMessagesProj/src/main/assets/emoji/0_422.png | Bin 2273 -> 1724 bytes TMessagesProj/src/main/assets/emoji/0_423.png | Bin 2236 -> 1761 bytes TMessagesProj/src/main/assets/emoji/0_424.png | Bin 2143 -> 1695 bytes TMessagesProj/src/main/assets/emoji/0_425.png | Bin 2065 -> 1574 bytes TMessagesProj/src/main/assets/emoji/0_426.png | Bin 2072 -> 1810 bytes TMessagesProj/src/main/assets/emoji/0_427.png | Bin 1791 -> 1766 bytes TMessagesProj/src/main/assets/emoji/0_428.png | Bin 1894 -> 1717 bytes TMessagesProj/src/main/assets/emoji/0_429.png | Bin 1920 -> 1819 bytes TMessagesProj/src/main/assets/emoji/0_43.png | Bin 1813 -> 1644 bytes TMessagesProj/src/main/assets/emoji/0_430.png | Bin 2012 -> 1729 bytes TMessagesProj/src/main/assets/emoji/0_431.png | Bin 1859 -> 1641 bytes TMessagesProj/src/main/assets/emoji/0_432.png | Bin 1807 -> 2096 bytes TMessagesProj/src/main/assets/emoji/0_433.png | Bin 1559 -> 2271 bytes TMessagesProj/src/main/assets/emoji/0_434.png | Bin 1695 -> 2237 bytes TMessagesProj/src/main/assets/emoji/0_435.png | Bin 1529 -> 2143 bytes TMessagesProj/src/main/assets/emoji/0_436.png | Bin 1837 -> 2067 bytes TMessagesProj/src/main/assets/emoji/0_437.png | Bin 1656 -> 2076 bytes TMessagesProj/src/main/assets/emoji/0_438.png | Bin 1554 -> 1790 bytes TMessagesProj/src/main/assets/emoji/0_439.png | Bin 1979 -> 1890 bytes TMessagesProj/src/main/assets/emoji/0_44.png | Bin 1900 -> 1949 bytes TMessagesProj/src/main/assets/emoji/0_440.png | Bin 1864 -> 1923 bytes TMessagesProj/src/main/assets/emoji/0_441.png | Bin 1751 -> 2004 bytes TMessagesProj/src/main/assets/emoji/0_442.png | Bin 1920 -> 1854 bytes TMessagesProj/src/main/assets/emoji/0_443.png | Bin 1624 -> 1806 bytes TMessagesProj/src/main/assets/emoji/0_444.png | Bin 1561 -> 1561 bytes TMessagesProj/src/main/assets/emoji/0_445.png | Bin 1774 -> 1696 bytes TMessagesProj/src/main/assets/emoji/0_446.png | Bin 1684 -> 1527 bytes TMessagesProj/src/main/assets/emoji/0_447.png | Bin 1720 -> 1842 bytes TMessagesProj/src/main/assets/emoji/0_448.png | Bin 1716 -> 1657 bytes TMessagesProj/src/main/assets/emoji/0_449.png | Bin 1659 -> 1558 bytes TMessagesProj/src/main/assets/emoji/0_45.png | Bin 2030 -> 1812 bytes TMessagesProj/src/main/assets/emoji/0_450.png | Bin 1590 -> 1979 bytes TMessagesProj/src/main/assets/emoji/0_451.png | Bin 1660 -> 1863 bytes TMessagesProj/src/main/assets/emoji/0_452.png | Bin 1600 -> 1754 bytes TMessagesProj/src/main/assets/emoji/0_453.png | Bin 1639 -> 1918 bytes TMessagesProj/src/main/assets/emoji/0_454.png | Bin 1652 -> 1618 bytes TMessagesProj/src/main/assets/emoji/0_455.png | Bin 1571 -> 1559 bytes TMessagesProj/src/main/assets/emoji/0_456.png | Bin 1558 -> 1777 bytes TMessagesProj/src/main/assets/emoji/0_457.png | Bin 1351 -> 1684 bytes TMessagesProj/src/main/assets/emoji/0_458.png | Bin 1244 -> 1718 bytes TMessagesProj/src/main/assets/emoji/0_459.png | Bin 1311 -> 1716 bytes TMessagesProj/src/main/assets/emoji/0_46.png | Bin 2085 -> 1902 bytes TMessagesProj/src/main/assets/emoji/0_460.png | Bin 1305 -> 1657 bytes TMessagesProj/src/main/assets/emoji/0_461.png | Bin 1134 -> 1590 bytes TMessagesProj/src/main/assets/emoji/0_462.png | Bin 995 -> 1768 bytes TMessagesProj/src/main/assets/emoji/0_463.png | Bin 1446 -> 1686 bytes TMessagesProj/src/main/assets/emoji/0_464.png | Bin 1404 -> 1720 bytes TMessagesProj/src/main/assets/emoji/0_465.png | Bin 1290 -> 1717 bytes TMessagesProj/src/main/assets/emoji/0_466.png | Bin 1328 -> 1657 bytes TMessagesProj/src/main/assets/emoji/0_467.png | Bin 1276 -> 1590 bytes TMessagesProj/src/main/assets/emoji/0_468.png | Bin 1087 -> 1661 bytes TMessagesProj/src/main/assets/emoji/0_469.png | Bin 1433 -> 1598 bytes TMessagesProj/src/main/assets/emoji/0_47.png | Bin 2347 -> 2028 bytes TMessagesProj/src/main/assets/emoji/0_470.png | Bin 1493 -> 1635 bytes TMessagesProj/src/main/assets/emoji/0_471.png | Bin 1354 -> 1651 bytes TMessagesProj/src/main/assets/emoji/0_472.png | Bin 1467 -> 1573 bytes TMessagesProj/src/main/assets/emoji/0_473.png | Bin 1296 -> 1560 bytes TMessagesProj/src/main/assets/emoji/0_474.png | Bin 1149 -> 1352 bytes TMessagesProj/src/main/assets/emoji/0_475.png | Bin 1808 -> 1243 bytes TMessagesProj/src/main/assets/emoji/0_476.png | Bin 1578 -> 1312 bytes TMessagesProj/src/main/assets/emoji/0_477.png | Bin 1725 -> 1303 bytes TMessagesProj/src/main/assets/emoji/0_478.png | Bin 1694 -> 1136 bytes TMessagesProj/src/main/assets/emoji/0_479.png | Bin 1473 -> 996 bytes TMessagesProj/src/main/assets/emoji/0_48.png | Bin 1507 -> 2084 bytes TMessagesProj/src/main/assets/emoji/0_480.png | Bin 1339 -> 1448 bytes TMessagesProj/src/main/assets/emoji/0_481.png | Bin 2111 -> 1403 bytes TMessagesProj/src/main/assets/emoji/0_482.png | Bin 1989 -> 1292 bytes TMessagesProj/src/main/assets/emoji/0_483.png | Bin 2147 -> 1328 bytes TMessagesProj/src/main/assets/emoji/0_484.png | Bin 2058 -> 1279 bytes TMessagesProj/src/main/assets/emoji/0_485.png | Bin 2003 -> 1087 bytes TMessagesProj/src/main/assets/emoji/0_486.png | Bin 1929 -> 1436 bytes TMessagesProj/src/main/assets/emoji/0_487.png | Bin 2227 -> 1488 bytes TMessagesProj/src/main/assets/emoji/0_488.png | Bin 2096 -> 1357 bytes TMessagesProj/src/main/assets/emoji/0_489.png | Bin 2081 -> 1466 bytes TMessagesProj/src/main/assets/emoji/0_49.png | Bin 1100 -> 2347 bytes TMessagesProj/src/main/assets/emoji/0_490.png | Bin 1981 -> 1297 bytes TMessagesProj/src/main/assets/emoji/0_491.png | Bin 1993 -> 1146 bytes TMessagesProj/src/main/assets/emoji/0_492.png | Bin 1834 -> 1805 bytes TMessagesProj/src/main/assets/emoji/0_493.png | Bin 1814 -> 1581 bytes TMessagesProj/src/main/assets/emoji/0_494.png | Bin 1533 -> 1725 bytes TMessagesProj/src/main/assets/emoji/0_495.png | Bin 1844 -> 1693 bytes TMessagesProj/src/main/assets/emoji/0_496.png | Bin 1884 -> 1474 bytes TMessagesProj/src/main/assets/emoji/0_497.png | Bin 1799 -> 1338 bytes TMessagesProj/src/main/assets/emoji/0_498.png | Bin 1750 -> 2111 bytes TMessagesProj/src/main/assets/emoji/0_499.png | Bin 1926 -> 1988 bytes TMessagesProj/src/main/assets/emoji/0_5.png | Bin 2099 -> 2097 bytes TMessagesProj/src/main/assets/emoji/0_50.png | Bin 1731 -> 1505 bytes TMessagesProj/src/main/assets/emoji/0_500.png | Bin 1902 -> 2146 bytes TMessagesProj/src/main/assets/emoji/0_501.png | Bin 1903 -> 2060 bytes TMessagesProj/src/main/assets/emoji/0_502.png | Bin 1735 -> 2005 bytes TMessagesProj/src/main/assets/emoji/0_503.png | Bin 1692 -> 1933 bytes TMessagesProj/src/main/assets/emoji/0_504.png | Bin 1557 -> 2224 bytes TMessagesProj/src/main/assets/emoji/0_505.png | Bin 1765 -> 2096 bytes TMessagesProj/src/main/assets/emoji/0_506.png | Bin 1777 -> 2081 bytes TMessagesProj/src/main/assets/emoji/0_507.png | Bin 1738 -> 1981 bytes TMessagesProj/src/main/assets/emoji/0_508.png | Bin 1748 -> 1992 bytes TMessagesProj/src/main/assets/emoji/0_509.png | Bin 1690 -> 1833 bytes TMessagesProj/src/main/assets/emoji/0_51.png | Bin 2819 -> 1099 bytes TMessagesProj/src/main/assets/emoji/0_510.png | Bin 1566 -> 1814 bytes TMessagesProj/src/main/assets/emoji/0_511.png | Bin 1755 -> 1533 bytes TMessagesProj/src/main/assets/emoji/0_512.png | Bin 1962 -> 1843 bytes TMessagesProj/src/main/assets/emoji/0_513.png | Bin 1970 -> 1883 bytes TMessagesProj/src/main/assets/emoji/0_514.png | Bin 1920 -> 1799 bytes TMessagesProj/src/main/assets/emoji/0_515.png | Bin 1793 -> 1749 bytes TMessagesProj/src/main/assets/emoji/0_516.png | Bin 1820 -> 1929 bytes TMessagesProj/src/main/assets/emoji/0_517.png | Bin 1914 -> 1902 bytes TMessagesProj/src/main/assets/emoji/0_518.png | Bin 2077 -> 1903 bytes TMessagesProj/src/main/assets/emoji/0_519.png | Bin 2177 -> 1736 bytes TMessagesProj/src/main/assets/emoji/0_52.png | Bin 1968 -> 1728 bytes TMessagesProj/src/main/assets/emoji/0_520.png | Bin 1917 -> 1692 bytes TMessagesProj/src/main/assets/emoji/0_521.png | Bin 1817 -> 1554 bytes TMessagesProj/src/main/assets/emoji/0_522.png | Bin 1636 -> 1768 bytes TMessagesProj/src/main/assets/emoji/0_523.png | Bin 1836 -> 1776 bytes TMessagesProj/src/main/assets/emoji/0_524.png | Bin 1918 -> 1735 bytes TMessagesProj/src/main/assets/emoji/0_525.png | Bin 1807 -> 1750 bytes TMessagesProj/src/main/assets/emoji/0_526.png | Bin 1723 -> 1690 bytes TMessagesProj/src/main/assets/emoji/0_527.png | Bin 1648 -> 1566 bytes TMessagesProj/src/main/assets/emoji/0_528.png | Bin 1652 -> 1756 bytes TMessagesProj/src/main/assets/emoji/0_529.png | Bin 2500 -> 1968 bytes TMessagesProj/src/main/assets/emoji/0_53.png | Bin 2064 -> 2817 bytes TMessagesProj/src/main/assets/emoji/0_530.png | Bin 2649 -> 1975 bytes TMessagesProj/src/main/assets/emoji/0_531.png | Bin 2565 -> 1922 bytes TMessagesProj/src/main/assets/emoji/0_532.png | Bin 2454 -> 1795 bytes TMessagesProj/src/main/assets/emoji/0_533.png | Bin 2428 -> 1820 bytes TMessagesProj/src/main/assets/emoji/0_534.png | Bin 2245 -> 1916 bytes TMessagesProj/src/main/assets/emoji/0_535.png | Bin 2616 -> 2075 bytes TMessagesProj/src/main/assets/emoji/0_536.png | Bin 2705 -> 2176 bytes TMessagesProj/src/main/assets/emoji/0_537.png | Bin 2792 -> 1916 bytes TMessagesProj/src/main/assets/emoji/0_538.png | Bin 2567 -> 1819 bytes TMessagesProj/src/main/assets/emoji/0_539.png | Bin 2423 -> 1636 bytes TMessagesProj/src/main/assets/emoji/0_54.png | Bin 2322 -> 1971 bytes TMessagesProj/src/main/assets/emoji/0_540.png | Bin 2318 -> 1835 bytes TMessagesProj/src/main/assets/emoji/0_541.png | Bin 2540 -> 1916 bytes TMessagesProj/src/main/assets/emoji/0_542.png | Bin 2526 -> 1805 bytes TMessagesProj/src/main/assets/emoji/0_543.png | Bin 2621 -> 1723 bytes TMessagesProj/src/main/assets/emoji/0_544.png | Bin 2367 -> 1648 bytes TMessagesProj/src/main/assets/emoji/0_545.png | Bin 2238 -> 1650 bytes TMessagesProj/src/main/assets/emoji/0_546.png | Bin 2278 -> 2498 bytes TMessagesProj/src/main/assets/emoji/0_547.png | Bin 2833 -> 2648 bytes TMessagesProj/src/main/assets/emoji/0_548.png | Bin 2922 -> 2565 bytes TMessagesProj/src/main/assets/emoji/0_549.png | Bin 2852 -> 2457 bytes TMessagesProj/src/main/assets/emoji/0_55.png | Bin 2550 -> 2059 bytes TMessagesProj/src/main/assets/emoji/0_550.png | Bin 2783 -> 2427 bytes TMessagesProj/src/main/assets/emoji/0_551.png | Bin 2641 -> 2243 bytes TMessagesProj/src/main/assets/emoji/0_552.png | Bin 2558 -> 2614 bytes TMessagesProj/src/main/assets/emoji/0_553.png | Bin 2676 -> 2705 bytes TMessagesProj/src/main/assets/emoji/0_554.png | Bin 2789 -> 2792 bytes TMessagesProj/src/main/assets/emoji/0_555.png | Bin 2788 -> 2567 bytes TMessagesProj/src/main/assets/emoji/0_556.png | Bin 2779 -> 2423 bytes TMessagesProj/src/main/assets/emoji/0_557.png | Bin 2640 -> 2318 bytes TMessagesProj/src/main/assets/emoji/0_558.png | Bin 2410 -> 2539 bytes TMessagesProj/src/main/assets/emoji/0_559.png | Bin 2548 -> 2528 bytes TMessagesProj/src/main/assets/emoji/0_56.png | Bin 1876 -> 2322 bytes TMessagesProj/src/main/assets/emoji/0_560.png | Bin 2650 -> 2619 bytes TMessagesProj/src/main/assets/emoji/0_561.png | Bin 2626 -> 2367 bytes TMessagesProj/src/main/assets/emoji/0_562.png | Bin 2471 -> 2237 bytes TMessagesProj/src/main/assets/emoji/0_563.png | Bin 2451 -> 2277 bytes TMessagesProj/src/main/assets/emoji/0_564.png | Bin 2276 -> 2833 bytes TMessagesProj/src/main/assets/emoji/0_565.png | Bin 2168 -> 2922 bytes TMessagesProj/src/main/assets/emoji/0_566.png | Bin 2162 -> 2852 bytes TMessagesProj/src/main/assets/emoji/0_567.png | Bin 1931 -> 2783 bytes TMessagesProj/src/main/assets/emoji/0_568.png | Bin 1910 -> 2641 bytes TMessagesProj/src/main/assets/emoji/0_569.png | Bin 1957 -> 2558 bytes TMessagesProj/src/main/assets/emoji/0_57.png | Bin 2272 -> 2549 bytes TMessagesProj/src/main/assets/emoji/0_570.png | Bin 1958 -> 2675 bytes TMessagesProj/src/main/assets/emoji/0_571.png | Bin 2179 -> 2789 bytes TMessagesProj/src/main/assets/emoji/0_572.png | Bin 2107 -> 2788 bytes TMessagesProj/src/main/assets/emoji/0_573.png | Bin 2016 -> 2777 bytes TMessagesProj/src/main/assets/emoji/0_574.png | Bin 1982 -> 2640 bytes TMessagesProj/src/main/assets/emoji/0_575.png | Bin 1971 -> 2410 bytes TMessagesProj/src/main/assets/emoji/0_576.png | Bin 1957 -> 2548 bytes TMessagesProj/src/main/assets/emoji/0_577.png | Bin 1992 -> 2650 bytes TMessagesProj/src/main/assets/emoji/0_578.png | Bin 1951 -> 2626 bytes TMessagesProj/src/main/assets/emoji/0_579.png | Bin 1990 -> 2471 bytes TMessagesProj/src/main/assets/emoji/0_58.png | Bin 1960 -> 1875 bytes TMessagesProj/src/main/assets/emoji/0_580.png | Bin 1897 -> 2451 bytes TMessagesProj/src/main/assets/emoji/0_581.png | Bin 1866 -> 2276 bytes TMessagesProj/src/main/assets/emoji/0_582.png | Bin 1881 -> 2168 bytes TMessagesProj/src/main/assets/emoji/0_583.png | Bin 2607 -> 2162 bytes TMessagesProj/src/main/assets/emoji/0_584.png | Bin 2499 -> 1931 bytes TMessagesProj/src/main/assets/emoji/0_585.png | Bin 2562 -> 1910 bytes TMessagesProj/src/main/assets/emoji/0_586.png | Bin 2539 -> 1957 bytes TMessagesProj/src/main/assets/emoji/0_587.png | Bin 2337 -> 1958 bytes TMessagesProj/src/main/assets/emoji/0_588.png | Bin 2209 -> 2179 bytes TMessagesProj/src/main/assets/emoji/0_589.png | Bin 2626 -> 2107 bytes TMessagesProj/src/main/assets/emoji/0_59.png | Bin 2052 -> 2272 bytes TMessagesProj/src/main/assets/emoji/0_590.png | Bin 2549 -> 2016 bytes TMessagesProj/src/main/assets/emoji/0_591.png | Bin 2620 -> 1982 bytes TMessagesProj/src/main/assets/emoji/0_592.png | Bin 2556 -> 1971 bytes TMessagesProj/src/main/assets/emoji/0_593.png | Bin 2503 -> 1957 bytes TMessagesProj/src/main/assets/emoji/0_594.png | Bin 2329 -> 1992 bytes TMessagesProj/src/main/assets/emoji/0_595.png | Bin 2570 -> 1951 bytes TMessagesProj/src/main/assets/emoji/0_596.png | Bin 2579 -> 1990 bytes TMessagesProj/src/main/assets/emoji/0_597.png | Bin 2680 -> 1897 bytes TMessagesProj/src/main/assets/emoji/0_598.png | Bin 2676 -> 1866 bytes TMessagesProj/src/main/assets/emoji/0_599.png | Bin 2482 -> 1881 bytes TMessagesProj/src/main/assets/emoji/0_6.png | Bin 2267 -> 2270 bytes TMessagesProj/src/main/assets/emoji/0_60.png | Bin 2076 -> 1961 bytes TMessagesProj/src/main/assets/emoji/0_600.png | Bin 2350 -> 2605 bytes TMessagesProj/src/main/assets/emoji/0_601.png | Bin 2318 -> 2499 bytes TMessagesProj/src/main/assets/emoji/0_602.png | Bin 2131 -> 2562 bytes TMessagesProj/src/main/assets/emoji/0_603.png | Bin 2377 -> 2539 bytes TMessagesProj/src/main/assets/emoji/0_604.png | Bin 2187 -> 2337 bytes TMessagesProj/src/main/assets/emoji/0_605.png | Bin 1839 -> 2209 bytes TMessagesProj/src/main/assets/emoji/0_606.png | Bin 1894 -> 2626 bytes TMessagesProj/src/main/assets/emoji/0_607.png | Bin 2079 -> 2548 bytes TMessagesProj/src/main/assets/emoji/0_608.png | Bin 2030 -> 2620 bytes TMessagesProj/src/main/assets/emoji/0_609.png | Bin 2067 -> 2557 bytes TMessagesProj/src/main/assets/emoji/0_61.png | Bin 1850 -> 2049 bytes TMessagesProj/src/main/assets/emoji/0_610.png | Bin 1917 -> 2503 bytes TMessagesProj/src/main/assets/emoji/0_611.png | Bin 1778 -> 2328 bytes TMessagesProj/src/main/assets/emoji/0_612.png | Bin 1705 -> 2570 bytes TMessagesProj/src/main/assets/emoji/0_613.png | Bin 2132 -> 2579 bytes TMessagesProj/src/main/assets/emoji/0_614.png | Bin 2029 -> 2680 bytes TMessagesProj/src/main/assets/emoji/0_615.png | Bin 2094 -> 2676 bytes TMessagesProj/src/main/assets/emoji/0_616.png | Bin 1978 -> 2482 bytes TMessagesProj/src/main/assets/emoji/0_617.png | Bin 1742 -> 2350 bytes TMessagesProj/src/main/assets/emoji/0_618.png | Bin 1617 -> 2318 bytes TMessagesProj/src/main/assets/emoji/0_619.png | Bin 3329 -> 2131 bytes TMessagesProj/src/main/assets/emoji/0_62.png | Bin 1863 -> 2075 bytes TMessagesProj/src/main/assets/emoji/0_620.png | Bin 3299 -> 2377 bytes TMessagesProj/src/main/assets/emoji/0_621.png | Bin 3474 -> 2187 bytes TMessagesProj/src/main/assets/emoji/0_622.png | Bin 3084 -> 1839 bytes TMessagesProj/src/main/assets/emoji/0_623.png | Bin 2969 -> 1894 bytes TMessagesProj/src/main/assets/emoji/0_624.png | Bin 2996 -> 2079 bytes TMessagesProj/src/main/assets/emoji/0_625.png | Bin 3396 -> 2030 bytes TMessagesProj/src/main/assets/emoji/0_626.png | Bin 3270 -> 2067 bytes TMessagesProj/src/main/assets/emoji/0_627.png | Bin 3330 -> 1917 bytes TMessagesProj/src/main/assets/emoji/0_628.png | Bin 3072 -> 1778 bytes TMessagesProj/src/main/assets/emoji/0_629.png | Bin 3074 -> 1705 bytes TMessagesProj/src/main/assets/emoji/0_63.png | Bin 1908 -> 1851 bytes TMessagesProj/src/main/assets/emoji/0_630.png | Bin 3010 -> 2132 bytes TMessagesProj/src/main/assets/emoji/0_631.png | Bin 3319 -> 2029 bytes TMessagesProj/src/main/assets/emoji/0_632.png | Bin 3259 -> 2094 bytes TMessagesProj/src/main/assets/emoji/0_633.png | Bin 3196 -> 1978 bytes TMessagesProj/src/main/assets/emoji/0_634.png | Bin 3034 -> 1742 bytes TMessagesProj/src/main/assets/emoji/0_635.png | Bin 3219 -> 1617 bytes TMessagesProj/src/main/assets/emoji/0_636.png | Bin 2897 -> 3329 bytes TMessagesProj/src/main/assets/emoji/0_637.png | Bin 2428 -> 3299 bytes TMessagesProj/src/main/assets/emoji/0_638.png | Bin 2662 -> 3474 bytes TMessagesProj/src/main/assets/emoji/0_639.png | Bin 2634 -> 3084 bytes TMessagesProj/src/main/assets/emoji/0_64.png | Bin 1842 -> 1859 bytes TMessagesProj/src/main/assets/emoji/0_640.png | Bin 2539 -> 2969 bytes TMessagesProj/src/main/assets/emoji/0_641.png | Bin 2517 -> 2995 bytes TMessagesProj/src/main/assets/emoji/0_642.png | Bin 2273 -> 3396 bytes TMessagesProj/src/main/assets/emoji/0_643.png | Bin 2485 -> 3270 bytes TMessagesProj/src/main/assets/emoji/0_644.png | Bin 2455 -> 3330 bytes TMessagesProj/src/main/assets/emoji/0_645.png | Bin 2584 -> 3072 bytes TMessagesProj/src/main/assets/emoji/0_646.png | Bin 2494 -> 3074 bytes TMessagesProj/src/main/assets/emoji/0_647.png | Bin 2356 -> 3010 bytes TMessagesProj/src/main/assets/emoji/0_648.png | Bin 2304 -> 3319 bytes TMessagesProj/src/main/assets/emoji/0_649.png | Bin 2419 -> 3259 bytes TMessagesProj/src/main/assets/emoji/0_65.png | Bin 1393 -> 1910 bytes TMessagesProj/src/main/assets/emoji/0_650.png | Bin 2403 -> 3196 bytes TMessagesProj/src/main/assets/emoji/0_651.png | Bin 2440 -> 3034 bytes TMessagesProj/src/main/assets/emoji/0_652.png | Bin 2414 -> 3219 bytes TMessagesProj/src/main/assets/emoji/0_653.png | Bin 2265 -> 2897 bytes TMessagesProj/src/main/assets/emoji/0_654.png | Bin 2236 -> 2428 bytes TMessagesProj/src/main/assets/emoji/0_655.png | Bin 2110 -> 2662 bytes TMessagesProj/src/main/assets/emoji/0_656.png | Bin 2053 -> 2634 bytes TMessagesProj/src/main/assets/emoji/0_657.png | Bin 2259 -> 2539 bytes TMessagesProj/src/main/assets/emoji/0_658.png | Bin 2045 -> 2517 bytes TMessagesProj/src/main/assets/emoji/0_659.png | Bin 1825 -> 2272 bytes TMessagesProj/src/main/assets/emoji/0_66.png | Bin 1409 -> 1844 bytes TMessagesProj/src/main/assets/emoji/0_660.png | Bin 1854 -> 2488 bytes TMessagesProj/src/main/assets/emoji/0_661.png | Bin 2079 -> 2455 bytes TMessagesProj/src/main/assets/emoji/0_662.png | Bin 2069 -> 2584 bytes TMessagesProj/src/main/assets/emoji/0_663.png | Bin 2208 -> 2494 bytes TMessagesProj/src/main/assets/emoji/0_664.png | Bin 2039 -> 2356 bytes TMessagesProj/src/main/assets/emoji/0_665.png | Bin 1898 -> 2304 bytes TMessagesProj/src/main/assets/emoji/0_666.png | Bin 1845 -> 2419 bytes TMessagesProj/src/main/assets/emoji/0_667.png | Bin 2044 -> 2401 bytes TMessagesProj/src/main/assets/emoji/0_668.png | Bin 2000 -> 2439 bytes TMessagesProj/src/main/assets/emoji/0_669.png | Bin 1967 -> 2414 bytes TMessagesProj/src/main/assets/emoji/0_67.png | Bin 1380 -> 1390 bytes TMessagesProj/src/main/assets/emoji/0_670.png | Bin 1875 -> 2265 bytes TMessagesProj/src/main/assets/emoji/0_671.png | Bin 1868 -> 2235 bytes TMessagesProj/src/main/assets/emoji/0_672.png | Bin 1773 -> 2113 bytes TMessagesProj/src/main/assets/emoji/0_673.png | Bin 3088 -> 2053 bytes TMessagesProj/src/main/assets/emoji/0_674.png | Bin 3084 -> 2259 bytes TMessagesProj/src/main/assets/emoji/0_675.png | Bin 3117 -> 2044 bytes TMessagesProj/src/main/assets/emoji/0_676.png | Bin 3102 -> 1824 bytes TMessagesProj/src/main/assets/emoji/0_677.png | Bin 2865 -> 1855 bytes TMessagesProj/src/main/assets/emoji/0_678.png | Bin 2945 -> 2075 bytes TMessagesProj/src/main/assets/emoji/0_679.png | Bin 2656 -> 2070 bytes TMessagesProj/src/main/assets/emoji/0_68.png | Bin 1657 -> 1411 bytes TMessagesProj/src/main/assets/emoji/0_680.png | Bin 2456 -> 2208 bytes TMessagesProj/src/main/assets/emoji/0_681.png | Bin 2477 -> 2038 bytes TMessagesProj/src/main/assets/emoji/0_682.png | Bin 2418 -> 1896 bytes TMessagesProj/src/main/assets/emoji/0_683.png | Bin 2223 -> 1846 bytes TMessagesProj/src/main/assets/emoji/0_684.png | Bin 2199 -> 2045 bytes TMessagesProj/src/main/assets/emoji/0_685.png | Bin 2631 -> 2001 bytes TMessagesProj/src/main/assets/emoji/0_686.png | Bin 2674 -> 1967 bytes TMessagesProj/src/main/assets/emoji/0_687.png | Bin 2566 -> 1875 bytes TMessagesProj/src/main/assets/emoji/0_688.png | Bin 2505 -> 1870 bytes TMessagesProj/src/main/assets/emoji/0_689.png | Bin 2403 -> 1773 bytes TMessagesProj/src/main/assets/emoji/0_69.png | Bin 1715 -> 1379 bytes TMessagesProj/src/main/assets/emoji/0_690.png | Bin 2318 -> 3090 bytes TMessagesProj/src/main/assets/emoji/0_691.png | Bin 2435 -> 3082 bytes TMessagesProj/src/main/assets/emoji/0_692.png | Bin 2171 -> 3112 bytes TMessagesProj/src/main/assets/emoji/0_693.png | Bin 2363 -> 3104 bytes TMessagesProj/src/main/assets/emoji/0_694.png | Bin 2227 -> 2865 bytes TMessagesProj/src/main/assets/emoji/0_695.png | Bin 1997 -> 2945 bytes TMessagesProj/src/main/assets/emoji/0_696.png | Bin 1836 -> 2654 bytes TMessagesProj/src/main/assets/emoji/0_697.png | Bin 2299 -> 2455 bytes TMessagesProj/src/main/assets/emoji/0_698.png | Bin 2142 -> 2474 bytes TMessagesProj/src/main/assets/emoji/0_699.png | Bin 2167 -> 2417 bytes TMessagesProj/src/main/assets/emoji/0_7.png | Bin 2270 -> 2269 bytes TMessagesProj/src/main/assets/emoji/0_70.png | Bin 1598 -> 1655 bytes TMessagesProj/src/main/assets/emoji/0_700.png | Bin 2113 -> 2223 bytes TMessagesProj/src/main/assets/emoji/0_701.png | Bin 1958 -> 2199 bytes TMessagesProj/src/main/assets/emoji/0_702.png | Bin 1957 -> 2631 bytes TMessagesProj/src/main/assets/emoji/0_703.png | Bin 2127 -> 2673 bytes TMessagesProj/src/main/assets/emoji/0_704.png | Bin 2094 -> 2562 bytes TMessagesProj/src/main/assets/emoji/0_705.png | Bin 2182 -> 2507 bytes TMessagesProj/src/main/assets/emoji/0_706.png | Bin 2027 -> 2403 bytes TMessagesProj/src/main/assets/emoji/0_707.png | Bin 1856 -> 2319 bytes TMessagesProj/src/main/assets/emoji/0_708.png | Bin 1729 -> 2438 bytes TMessagesProj/src/main/assets/emoji/0_709.png | Bin 2882 -> 2172 bytes TMessagesProj/src/main/assets/emoji/0_71.png | Bin 1498 -> 1717 bytes TMessagesProj/src/main/assets/emoji/0_710.png | Bin 2603 -> 2361 bytes TMessagesProj/src/main/assets/emoji/0_711.png | Bin 2908 -> 2226 bytes TMessagesProj/src/main/assets/emoji/0_712.png | Bin 2645 -> 1997 bytes TMessagesProj/src/main/assets/emoji/0_713.png | Bin 2475 -> 1838 bytes TMessagesProj/src/main/assets/emoji/0_714.png | Bin 2248 -> 2299 bytes TMessagesProj/src/main/assets/emoji/0_715.png | Bin 2690 -> 2144 bytes TMessagesProj/src/main/assets/emoji/0_716.png | Bin 2558 -> 2164 bytes TMessagesProj/src/main/assets/emoji/0_717.png | Bin 2744 -> 2111 bytes TMessagesProj/src/main/assets/emoji/0_718.png | Bin 2582 -> 1961 bytes TMessagesProj/src/main/assets/emoji/0_719.png | Bin 2514 -> 1956 bytes TMessagesProj/src/main/assets/emoji/0_72.png | Bin 1598 -> 1600 bytes TMessagesProj/src/main/assets/emoji/0_720.png | Bin 2296 -> 2129 bytes TMessagesProj/src/main/assets/emoji/0_721.png | Bin 2638 -> 2094 bytes TMessagesProj/src/main/assets/emoji/0_722.png | Bin 2624 -> 2182 bytes TMessagesProj/src/main/assets/emoji/0_723.png | Bin 2675 -> 2028 bytes TMessagesProj/src/main/assets/emoji/0_724.png | Bin 2529 -> 1856 bytes TMessagesProj/src/main/assets/emoji/0_725.png | Bin 2333 -> 1730 bytes TMessagesProj/src/main/assets/emoji/0_726.png | Bin 2289 -> 2884 bytes TMessagesProj/src/main/assets/emoji/0_727.png | Bin 1554 -> 2603 bytes TMessagesProj/src/main/assets/emoji/0_728.png | Bin 1456 -> 2907 bytes TMessagesProj/src/main/assets/emoji/0_729.png | Bin 1616 -> 2646 bytes TMessagesProj/src/main/assets/emoji/0_73.png | Bin 1443 -> 1499 bytes TMessagesProj/src/main/assets/emoji/0_730.png | Bin 1480 -> 2477 bytes TMessagesProj/src/main/assets/emoji/0_731.png | Bin 1385 -> 2247 bytes TMessagesProj/src/main/assets/emoji/0_732.png | Bin 1368 -> 2691 bytes TMessagesProj/src/main/assets/emoji/0_733.png | Bin 1632 -> 2559 bytes TMessagesProj/src/main/assets/emoji/0_734.png | Bin 1647 -> 2742 bytes TMessagesProj/src/main/assets/emoji/0_735.png | Bin 1574 -> 2581 bytes TMessagesProj/src/main/assets/emoji/0_736.png | Bin 1408 -> 2516 bytes TMessagesProj/src/main/assets/emoji/0_737.png | Bin 1509 -> 2292 bytes TMessagesProj/src/main/assets/emoji/0_738.png | Bin 1375 -> 2637 bytes TMessagesProj/src/main/assets/emoji/0_739.png | Bin 1610 -> 2627 bytes TMessagesProj/src/main/assets/emoji/0_74.png | Bin 1687 -> 1597 bytes TMessagesProj/src/main/assets/emoji/0_740.png | Bin 1567 -> 2676 bytes TMessagesProj/src/main/assets/emoji/0_741.png | Bin 1475 -> 2528 bytes TMessagesProj/src/main/assets/emoji/0_742.png | Bin 1373 -> 2335 bytes TMessagesProj/src/main/assets/emoji/0_743.png | Bin 1352 -> 2289 bytes TMessagesProj/src/main/assets/emoji/0_744.png | Bin 1337 -> 1557 bytes TMessagesProj/src/main/assets/emoji/0_745.png | Bin 1994 -> 1456 bytes TMessagesProj/src/main/assets/emoji/0_746.png | Bin 1665 -> 1615 bytes TMessagesProj/src/main/assets/emoji/0_747.png | Bin 2106 -> 1479 bytes TMessagesProj/src/main/assets/emoji/0_748.png | Bin 1866 -> 1383 bytes TMessagesProj/src/main/assets/emoji/0_749.png | Bin 1529 -> 1368 bytes TMessagesProj/src/main/assets/emoji/0_75.png | Bin 2051 -> 1443 bytes TMessagesProj/src/main/assets/emoji/0_750.png | Bin 1500 -> 1635 bytes TMessagesProj/src/main/assets/emoji/0_751.png | Bin 1860 -> 1646 bytes TMessagesProj/src/main/assets/emoji/0_752.png | Bin 1908 -> 1573 bytes TMessagesProj/src/main/assets/emoji/0_753.png | Bin 1873 -> 1402 bytes TMessagesProj/src/main/assets/emoji/0_754.png | Bin 1644 -> 1509 bytes TMessagesProj/src/main/assets/emoji/0_755.png | Bin 1596 -> 1378 bytes TMessagesProj/src/main/assets/emoji/0_756.png | Bin 1441 -> 1611 bytes TMessagesProj/src/main/assets/emoji/0_757.png | Bin 1922 -> 1569 bytes TMessagesProj/src/main/assets/emoji/0_758.png | Bin 2031 -> 1475 bytes TMessagesProj/src/main/assets/emoji/0_759.png | Bin 1993 -> 1372 bytes TMessagesProj/src/main/assets/emoji/0_76.png | Bin 2084 -> 1688 bytes TMessagesProj/src/main/assets/emoji/0_760.png | Bin 1849 -> 1351 bytes TMessagesProj/src/main/assets/emoji/0_761.png | Bin 1730 -> 1333 bytes TMessagesProj/src/main/assets/emoji/0_762.png | Bin 1594 -> 1992 bytes TMessagesProj/src/main/assets/emoji/0_763.png | Bin 2646 -> 1665 bytes TMessagesProj/src/main/assets/emoji/0_764.png | Bin 2405 -> 2105 bytes TMessagesProj/src/main/assets/emoji/0_765.png | Bin 2545 -> 1868 bytes TMessagesProj/src/main/assets/emoji/0_766.png | Bin 2475 -> 1533 bytes TMessagesProj/src/main/assets/emoji/0_767.png | Bin 2283 -> 1498 bytes TMessagesProj/src/main/assets/emoji/0_768.png | Bin 2177 -> 1860 bytes TMessagesProj/src/main/assets/emoji/0_769.png | Bin 2600 -> 1907 bytes TMessagesProj/src/main/assets/emoji/0_77.png | Bin 1872 -> 2049 bytes TMessagesProj/src/main/assets/emoji/0_770.png | Bin 2401 -> 1873 bytes TMessagesProj/src/main/assets/emoji/0_771.png | Bin 2499 -> 1643 bytes TMessagesProj/src/main/assets/emoji/0_772.png | Bin 2407 -> 1596 bytes TMessagesProj/src/main/assets/emoji/0_773.png | Bin 2285 -> 1446 bytes TMessagesProj/src/main/assets/emoji/0_774.png | Bin 2133 -> 1922 bytes TMessagesProj/src/main/assets/emoji/0_775.png | Bin 2580 -> 2031 bytes TMessagesProj/src/main/assets/emoji/0_776.png | Bin 2353 -> 1993 bytes TMessagesProj/src/main/assets/emoji/0_777.png | Bin 2504 -> 1849 bytes TMessagesProj/src/main/assets/emoji/0_778.png | Bin 2334 -> 1730 bytes TMessagesProj/src/main/assets/emoji/0_779.png | Bin 2199 -> 1594 bytes TMessagesProj/src/main/assets/emoji/0_78.png | Bin 2005 -> 2083 bytes TMessagesProj/src/main/assets/emoji/0_780.png | Bin 2107 -> 2647 bytes TMessagesProj/src/main/assets/emoji/0_781.png | Bin 3081 -> 2405 bytes TMessagesProj/src/main/assets/emoji/0_782.png | Bin 2563 -> 2545 bytes TMessagesProj/src/main/assets/emoji/0_783.png | Bin 2960 -> 2476 bytes TMessagesProj/src/main/assets/emoji/0_784.png | Bin 2628 -> 2283 bytes TMessagesProj/src/main/assets/emoji/0_785.png | Bin 2422 -> 2177 bytes TMessagesProj/src/main/assets/emoji/0_786.png | Bin 2321 -> 2600 bytes TMessagesProj/src/main/assets/emoji/0_787.png | Bin 2896 -> 2403 bytes TMessagesProj/src/main/assets/emoji/0_788.png | Bin 2578 -> 2500 bytes TMessagesProj/src/main/assets/emoji/0_789.png | Bin 2595 -> 2406 bytes TMessagesProj/src/main/assets/emoji/0_79.png | Bin 1725 -> 1872 bytes TMessagesProj/src/main/assets/emoji/0_790.png | Bin 2495 -> 2285 bytes TMessagesProj/src/main/assets/emoji/0_791.png | Bin 2385 -> 2134 bytes TMessagesProj/src/main/assets/emoji/0_792.png | Bin 2372 -> 2579 bytes TMessagesProj/src/main/assets/emoji/0_793.png | Bin 2720 -> 2353 bytes TMessagesProj/src/main/assets/emoji/0_794.png | Bin 2477 -> 2503 bytes TMessagesProj/src/main/assets/emoji/0_795.png | Bin 2501 -> 2334 bytes TMessagesProj/src/main/assets/emoji/0_796.png | Bin 2443 -> 2200 bytes TMessagesProj/src/main/assets/emoji/0_797.png | Bin 2376 -> 2107 bytes TMessagesProj/src/main/assets/emoji/0_798.png | Bin 2247 -> 3080 bytes TMessagesProj/src/main/assets/emoji/0_799.png | Bin 3064 -> 2564 bytes TMessagesProj/src/main/assets/emoji/0_8.png | Bin 1544 -> 1947 bytes TMessagesProj/src/main/assets/emoji/0_80.png | Bin 2113 -> 2004 bytes TMessagesProj/src/main/assets/emoji/0_800.png | Bin 3052 -> 2958 bytes TMessagesProj/src/main/assets/emoji/0_801.png | Bin 3145 -> 2629 bytes TMessagesProj/src/main/assets/emoji/0_802.png | Bin 3016 -> 2421 bytes TMessagesProj/src/main/assets/emoji/0_803.png | Bin 2835 -> 2320 bytes TMessagesProj/src/main/assets/emoji/0_804.png | Bin 2695 -> 2896 bytes TMessagesProj/src/main/assets/emoji/0_805.png | Bin 2995 -> 2578 bytes TMessagesProj/src/main/assets/emoji/0_806.png | Bin 2968 -> 2592 bytes TMessagesProj/src/main/assets/emoji/0_807.png | Bin 3043 -> 2495 bytes TMessagesProj/src/main/assets/emoji/0_808.png | Bin 2950 -> 2384 bytes TMessagesProj/src/main/assets/emoji/0_809.png | Bin 2754 -> 2372 bytes TMessagesProj/src/main/assets/emoji/0_81.png | Bin 1790 -> 1725 bytes TMessagesProj/src/main/assets/emoji/0_810.png | Bin 2643 -> 2723 bytes TMessagesProj/src/main/assets/emoji/0_811.png | Bin 2975 -> 2476 bytes TMessagesProj/src/main/assets/emoji/0_812.png | Bin 2932 -> 2501 bytes TMessagesProj/src/main/assets/emoji/0_813.png | Bin 2900 -> 2444 bytes TMessagesProj/src/main/assets/emoji/0_814.png | Bin 2916 -> 2376 bytes TMessagesProj/src/main/assets/emoji/0_815.png | Bin 2702 -> 2249 bytes TMessagesProj/src/main/assets/emoji/0_816.png | Bin 2588 -> 3065 bytes TMessagesProj/src/main/assets/emoji/0_817.png | Bin 3285 -> 3053 bytes TMessagesProj/src/main/assets/emoji/0_818.png | Bin 3156 -> 3149 bytes TMessagesProj/src/main/assets/emoji/0_819.png | Bin 3199 -> 3012 bytes TMessagesProj/src/main/assets/emoji/0_82.png | Bin 1382 -> 2115 bytes TMessagesProj/src/main/assets/emoji/0_820.png | Bin 2950 -> 2836 bytes TMessagesProj/src/main/assets/emoji/0_821.png | Bin 2969 -> 2693 bytes TMessagesProj/src/main/assets/emoji/0_822.png | Bin 2800 -> 2994 bytes TMessagesProj/src/main/assets/emoji/0_823.png | Bin 3253 -> 2965 bytes TMessagesProj/src/main/assets/emoji/0_824.png | Bin 3225 -> 3045 bytes TMessagesProj/src/main/assets/emoji/0_825.png | Bin 3223 -> 2952 bytes TMessagesProj/src/main/assets/emoji/0_826.png | Bin 3256 -> 2754 bytes TMessagesProj/src/main/assets/emoji/0_827.png | Bin 3095 -> 2642 bytes TMessagesProj/src/main/assets/emoji/0_828.png | Bin 2967 -> 2973 bytes TMessagesProj/src/main/assets/emoji/0_829.png | Bin 3258 -> 2932 bytes TMessagesProj/src/main/assets/emoji/0_83.png | Bin 2771 -> 1792 bytes TMessagesProj/src/main/assets/emoji/0_830.png | Bin 3089 -> 2899 bytes TMessagesProj/src/main/assets/emoji/0_831.png | Bin 3111 -> 2914 bytes TMessagesProj/src/main/assets/emoji/0_832.png | Bin 3106 -> 2703 bytes TMessagesProj/src/main/assets/emoji/0_833.png | Bin 2890 -> 2586 bytes TMessagesProj/src/main/assets/emoji/0_834.png | Bin 2828 -> 3278 bytes TMessagesProj/src/main/assets/emoji/0_835.png | Bin 2443 -> 3156 bytes TMessagesProj/src/main/assets/emoji/0_836.png | Bin 2321 -> 3197 bytes TMessagesProj/src/main/assets/emoji/0_837.png | Bin 2473 -> 2945 bytes TMessagesProj/src/main/assets/emoji/0_838.png | Bin 2368 -> 2969 bytes TMessagesProj/src/main/assets/emoji/0_839.png | Bin 2274 -> 2796 bytes TMessagesProj/src/main/assets/emoji/0_84.png | Bin 2211 -> 1382 bytes TMessagesProj/src/main/assets/emoji/0_840.png | Bin 2015 -> 3254 bytes TMessagesProj/src/main/assets/emoji/0_841.png | Bin 2214 -> 3226 bytes TMessagesProj/src/main/assets/emoji/0_842.png | Bin 2308 -> 3222 bytes TMessagesProj/src/main/assets/emoji/0_843.png | Bin 2255 -> 3252 bytes TMessagesProj/src/main/assets/emoji/0_844.png | Bin 2252 -> 3094 bytes TMessagesProj/src/main/assets/emoji/0_845.png | Bin 2038 -> 2968 bytes TMessagesProj/src/main/assets/emoji/0_846.png | Bin 2011 -> 3257 bytes TMessagesProj/src/main/assets/emoji/0_847.png | Bin 2117 -> 3087 bytes TMessagesProj/src/main/assets/emoji/0_848.png | Bin 2253 -> 3109 bytes TMessagesProj/src/main/assets/emoji/0_849.png | Bin 2299 -> 3107 bytes TMessagesProj/src/main/assets/emoji/0_85.png | Bin 1948 -> 2771 bytes TMessagesProj/src/main/assets/emoji/0_850.png | Bin 2173 -> 2889 bytes TMessagesProj/src/main/assets/emoji/0_851.png | Bin 2083 -> 2830 bytes TMessagesProj/src/main/assets/emoji/0_852.png | Bin 1972 -> 2444 bytes TMessagesProj/src/main/assets/emoji/0_853.png | Bin 2619 -> 2321 bytes TMessagesProj/src/main/assets/emoji/0_854.png | Bin 2543 -> 2474 bytes TMessagesProj/src/main/assets/emoji/0_855.png | Bin 2640 -> 2368 bytes TMessagesProj/src/main/assets/emoji/0_856.png | Bin 2633 -> 2274 bytes TMessagesProj/src/main/assets/emoji/0_857.png | Bin 2508 -> 2015 bytes TMessagesProj/src/main/assets/emoji/0_858.png | Bin 2286 -> 2215 bytes TMessagesProj/src/main/assets/emoji/0_859.png | Bin 2671 -> 2311 bytes TMessagesProj/src/main/assets/emoji/0_86.png | Bin 2336 -> 2209 bytes TMessagesProj/src/main/assets/emoji/0_860.png | Bin 2557 -> 2255 bytes TMessagesProj/src/main/assets/emoji/0_861.png | Bin 2475 -> 2251 bytes TMessagesProj/src/main/assets/emoji/0_862.png | Bin 2631 -> 2038 bytes TMessagesProj/src/main/assets/emoji/0_863.png | Bin 2480 -> 2010 bytes TMessagesProj/src/main/assets/emoji/0_864.png | Bin 2389 -> 2115 bytes TMessagesProj/src/main/assets/emoji/0_865.png | Bin 2610 -> 2253 bytes TMessagesProj/src/main/assets/emoji/0_866.png | Bin 2539 -> 2298 bytes TMessagesProj/src/main/assets/emoji/0_867.png | Bin 2580 -> 2173 bytes TMessagesProj/src/main/assets/emoji/0_868.png | Bin 2667 -> 2081 bytes TMessagesProj/src/main/assets/emoji/0_869.png | Bin 2454 -> 1972 bytes TMessagesProj/src/main/assets/emoji/0_87.png | Bin 1776 -> 1904 bytes TMessagesProj/src/main/assets/emoji/0_870.png | Bin 2362 -> 2620 bytes TMessagesProj/src/main/assets/emoji/0_871.png | Bin 2110 -> 2542 bytes TMessagesProj/src/main/assets/emoji/0_872.png | Bin 1854 -> 2640 bytes TMessagesProj/src/main/assets/emoji/0_873.png | Bin 2272 -> 2634 bytes TMessagesProj/src/main/assets/emoji/0_874.png | Bin 2032 -> 2508 bytes TMessagesProj/src/main/assets/emoji/0_875.png | Bin 1784 -> 2288 bytes TMessagesProj/src/main/assets/emoji/0_876.png | Bin 1816 -> 2670 bytes TMessagesProj/src/main/assets/emoji/0_877.png | Bin 2092 -> 2556 bytes TMessagesProj/src/main/assets/emoji/0_878.png | Bin 2058 -> 2475 bytes TMessagesProj/src/main/assets/emoji/0_879.png | Bin 2078 -> 2629 bytes TMessagesProj/src/main/assets/emoji/0_88.png | Bin 2128 -> 2332 bytes TMessagesProj/src/main/assets/emoji/0_880.png | Bin 2021 -> 2482 bytes TMessagesProj/src/main/assets/emoji/0_881.png | Bin 1905 -> 2390 bytes TMessagesProj/src/main/assets/emoji/0_882.png | Bin 1753 -> 2608 bytes TMessagesProj/src/main/assets/emoji/0_883.png | Bin 2132 -> 2539 bytes TMessagesProj/src/main/assets/emoji/0_884.png | Bin 2168 -> 2580 bytes TMessagesProj/src/main/assets/emoji/0_885.png | Bin 2195 -> 2668 bytes TMessagesProj/src/main/assets/emoji/0_886.png | Bin 2082 -> 2453 bytes TMessagesProj/src/main/assets/emoji/0_887.png | Bin 1958 -> 2360 bytes TMessagesProj/src/main/assets/emoji/0_888.png | Bin 1889 -> 2111 bytes TMessagesProj/src/main/assets/emoji/0_889.png | Bin 2352 -> 1853 bytes TMessagesProj/src/main/assets/emoji/0_89.png | Bin 2046 -> 1775 bytes TMessagesProj/src/main/assets/emoji/0_890.png | Bin 2139 -> 2270 bytes TMessagesProj/src/main/assets/emoji/0_891.png | Bin 2221 -> 2032 bytes TMessagesProj/src/main/assets/emoji/0_892.png | Bin 2121 -> 1785 bytes TMessagesProj/src/main/assets/emoji/0_893.png | Bin 1998 -> 1817 bytes TMessagesProj/src/main/assets/emoji/0_894.png | Bin 1729 -> 2092 bytes TMessagesProj/src/main/assets/emoji/0_895.png | Bin 1718 -> 2057 bytes TMessagesProj/src/main/assets/emoji/0_896.png | Bin 1650 -> 2078 bytes TMessagesProj/src/main/assets/emoji/0_897.png | Bin 1824 -> 2023 bytes TMessagesProj/src/main/assets/emoji/0_898.png | Bin 1617 -> 1905 bytes TMessagesProj/src/main/assets/emoji/0_899.png | Bin 1441 -> 1751 bytes TMessagesProj/src/main/assets/emoji/0_9.png | Bin 1620 -> 1545 bytes TMessagesProj/src/main/assets/emoji/0_90.png | Bin 1805 -> 2129 bytes TMessagesProj/src/main/assets/emoji/0_900.png | Bin 1392 -> 2131 bytes TMessagesProj/src/main/assets/emoji/0_901.png | Bin 1878 -> 2166 bytes TMessagesProj/src/main/assets/emoji/0_902.png | Bin 2021 -> 2195 bytes TMessagesProj/src/main/assets/emoji/0_903.png | Bin 2132 -> 2083 bytes TMessagesProj/src/main/assets/emoji/0_904.png | Bin 1773 -> 1958 bytes TMessagesProj/src/main/assets/emoji/0_905.png | Bin 1733 -> 1890 bytes TMessagesProj/src/main/assets/emoji/0_906.png | Bin 1599 -> 2465 bytes TMessagesProj/src/main/assets/emoji/0_907.png | Bin 2498 -> 2212 bytes TMessagesProj/src/main/assets/emoji/0_908.png | Bin 2559 -> 2463 bytes TMessagesProj/src/main/assets/emoji/0_909.png | Bin 2495 -> 2276 bytes TMessagesProj/src/main/assets/emoji/0_91.png | Bin 1779 -> 2048 bytes TMessagesProj/src/main/assets/emoji/0_910.png | Bin 2451 -> 2231 bytes TMessagesProj/src/main/assets/emoji/0_911.png | Bin 2504 -> 1842 bytes TMessagesProj/src/main/assets/emoji/0_912.png | Bin 2331 -> 2259 bytes TMessagesProj/src/main/assets/emoji/0_913.png | Bin 3070 -> 2198 bytes TMessagesProj/src/main/assets/emoji/0_914.png | Bin 2485 -> 2178 bytes TMessagesProj/src/main/assets/emoji/0_915.png | Bin 2690 -> 2186 bytes TMessagesProj/src/main/assets/emoji/0_916.png | Bin 2551 -> 2040 bytes TMessagesProj/src/main/assets/emoji/0_917.png | Bin 2289 -> 1885 bytes TMessagesProj/src/main/assets/emoji/0_918.png | Bin 2330 -> 2450 bytes TMessagesProj/src/main/assets/emoji/0_919.png | Bin 2539 -> 2331 bytes TMessagesProj/src/main/assets/emoji/0_92.png | Bin 2819 -> 1805 bytes TMessagesProj/src/main/assets/emoji/0_920.png | Bin 2665 -> 2425 bytes TMessagesProj/src/main/assets/emoji/0_921.png | Bin 2680 -> 2230 bytes TMessagesProj/src/main/assets/emoji/0_922.png | Bin 2444 -> 2090 bytes TMessagesProj/src/main/assets/emoji/0_923.png | Bin 2362 -> 1950 bytes TMessagesProj/src/main/assets/emoji/0_924.png | Bin 2117 -> 2123 bytes TMessagesProj/src/main/assets/emoji/0_925.png | Bin 2873 -> 1638 bytes TMessagesProj/src/main/assets/emoji/0_926.png | Bin 2571 -> 2059 bytes TMessagesProj/src/main/assets/emoji/0_927.png | Bin 2521 -> 1839 bytes TMessagesProj/src/main/assets/emoji/0_928.png | Bin 2324 -> 1684 bytes TMessagesProj/src/main/assets/emoji/0_929.png | Bin 2320 -> 1361 bytes TMessagesProj/src/main/assets/emoji/0_93.png | Bin 2388 -> 1780 bytes TMessagesProj/src/main/assets/emoji/0_930.png | Bin 2052 -> 1880 bytes TMessagesProj/src/main/assets/emoji/0_931.png | Bin 3684 -> 1697 bytes TMessagesProj/src/main/assets/emoji/0_932.png | Bin 2950 -> 1799 bytes TMessagesProj/src/main/assets/emoji/0_933.png | Bin 3557 -> 1667 bytes TMessagesProj/src/main/assets/emoji/0_934.png | Bin 2910 -> 1631 bytes TMessagesProj/src/main/assets/emoji/0_935.png | Bin 2599 -> 1391 bytes TMessagesProj/src/main/assets/emoji/0_936.png | Bin 2299 -> 1868 bytes TMessagesProj/src/main/assets/emoji/0_937.png | Bin 3372 -> 1762 bytes TMessagesProj/src/main/assets/emoji/0_938.png | Bin 2815 -> 1823 bytes TMessagesProj/src/main/assets/emoji/0_939.png | Bin 3246 -> 1706 bytes TMessagesProj/src/main/assets/emoji/0_94.png | Bin 2760 -> 2818 bytes TMessagesProj/src/main/assets/emoji/0_940.png | Bin 2748 -> 1587 bytes TMessagesProj/src/main/assets/emoji/0_941.png | Bin 2494 -> 1439 bytes TMessagesProj/src/main/assets/emoji/0_942.png | Bin 2277 -> 1878 bytes TMessagesProj/src/main/assets/emoji/0_943.png | Bin 3370 -> 2018 bytes TMessagesProj/src/main/assets/emoji/0_944.png | Bin 2714 -> 2130 bytes TMessagesProj/src/main/assets/emoji/0_945.png | Bin 3132 -> 1771 bytes TMessagesProj/src/main/assets/emoji/0_946.png | Bin 2585 -> 1733 bytes TMessagesProj/src/main/assets/emoji/0_947.png | Bin 2395 -> 1600 bytes TMessagesProj/src/main/assets/emoji/0_948.png | Bin 2218 -> 2494 bytes TMessagesProj/src/main/assets/emoji/0_949.png | Bin 2210 -> 2559 bytes TMessagesProj/src/main/assets/emoji/0_95.png | Bin 1399 -> 2388 bytes TMessagesProj/src/main/assets/emoji/0_950.png | Bin 2095 -> 2495 bytes TMessagesProj/src/main/assets/emoji/0_951.png | Bin 2010 -> 2452 bytes TMessagesProj/src/main/assets/emoji/0_952.png | Bin 2090 -> 2503 bytes TMessagesProj/src/main/assets/emoji/0_953.png | Bin 2006 -> 2332 bytes TMessagesProj/src/main/assets/emoji/0_954.png | Bin 1847 -> 1591 bytes TMessagesProj/src/main/assets/emoji/0_955.png | Bin 2539 -> 1546 bytes TMessagesProj/src/main/assets/emoji/0_956.png | Bin 2490 -> 1594 bytes TMessagesProj/src/main/assets/emoji/0_957.png | Bin 2400 -> 1581 bytes TMessagesProj/src/main/assets/emoji/0_958.png | Bin 2398 -> 1468 bytes TMessagesProj/src/main/assets/emoji/0_959.png | Bin 2492 -> 1559 bytes TMessagesProj/src/main/assets/emoji/0_96.png | Bin 1833 -> 2760 bytes TMessagesProj/src/main/assets/emoji/0_960.png | Bin 2308 -> 3068 bytes TMessagesProj/src/main/assets/emoji/0_961.png | Bin 2977 -> 2485 bytes TMessagesProj/src/main/assets/emoji/0_962.png | Bin 3008 -> 2691 bytes TMessagesProj/src/main/assets/emoji/0_963.png | Bin 3010 -> 2550 bytes TMessagesProj/src/main/assets/emoji/0_964.png | Bin 2872 -> 2288 bytes TMessagesProj/src/main/assets/emoji/0_965.png | Bin 2768 -> 2330 bytes TMessagesProj/src/main/assets/emoji/0_966.png | Bin 2732 -> 2536 bytes TMessagesProj/src/main/assets/emoji/0_967.png | Bin 2996 -> 2665 bytes TMessagesProj/src/main/assets/emoji/0_968.png | Bin 2847 -> 2678 bytes TMessagesProj/src/main/assets/emoji/0_969.png | Bin 2843 -> 2445 bytes TMessagesProj/src/main/assets/emoji/0_97.png | Bin 1377 -> 1399 bytes TMessagesProj/src/main/assets/emoji/0_970.png | Bin 2757 -> 2363 bytes TMessagesProj/src/main/assets/emoji/0_971.png | Bin 2724 -> 2116 bytes TMessagesProj/src/main/assets/emoji/0_972.png | Bin 2554 -> 2874 bytes TMessagesProj/src/main/assets/emoji/0_973.png | Bin 2948 -> 2572 bytes TMessagesProj/src/main/assets/emoji/0_974.png | Bin 2908 -> 2521 bytes TMessagesProj/src/main/assets/emoji/0_975.png | Bin 2940 -> 2324 bytes TMessagesProj/src/main/assets/emoji/0_976.png | Bin 2976 -> 2320 bytes TMessagesProj/src/main/assets/emoji/0_977.png | Bin 2946 -> 2052 bytes TMessagesProj/src/main/assets/emoji/0_978.png | Bin 2925 -> 3684 bytes TMessagesProj/src/main/assets/emoji/0_979.png | Bin 2685 -> 2951 bytes TMessagesProj/src/main/assets/emoji/0_98.png | Bin 1583 -> 1832 bytes TMessagesProj/src/main/assets/emoji/0_980.png | Bin 2765 -> 3557 bytes TMessagesProj/src/main/assets/emoji/0_981.png | Bin 2615 -> 2909 bytes TMessagesProj/src/main/assets/emoji/0_982.png | Bin 2792 -> 2597 bytes TMessagesProj/src/main/assets/emoji/0_983.png | Bin 2589 -> 2299 bytes TMessagesProj/src/main/assets/emoji/0_984.png | Bin 2556 -> 3372 bytes TMessagesProj/src/main/assets/emoji/0_985.png | Bin 2503 -> 2815 bytes TMessagesProj/src/main/assets/emoji/0_986.png | Bin 2404 -> 3247 bytes TMessagesProj/src/main/assets/emoji/0_987.png | Bin 2337 -> 2748 bytes TMessagesProj/src/main/assets/emoji/0_988.png | Bin 2309 -> 2493 bytes TMessagesProj/src/main/assets/emoji/0_989.png | Bin 2244 -> 2274 bytes TMessagesProj/src/main/assets/emoji/0_99.png | Bin 1280 -> 1372 bytes TMessagesProj/src/main/assets/emoji/0_990.png | Bin 2209 -> 3369 bytes TMessagesProj/src/main/assets/emoji/0_991.png | Bin 2836 -> 2711 bytes TMessagesProj/src/main/assets/emoji/0_992.png | Bin 2727 -> 3131 bytes TMessagesProj/src/main/assets/emoji/0_993.png | Bin 2702 -> 2583 bytes TMessagesProj/src/main/assets/emoji/0_994.png | Bin 2772 -> 2396 bytes TMessagesProj/src/main/assets/emoji/0_995.png | Bin 2708 -> 2219 bytes TMessagesProj/src/main/assets/emoji/0_996.png | Bin 2456 -> 2210 bytes TMessagesProj/src/main/assets/emoji/0_997.png | Bin 2581 -> 2093 bytes TMessagesProj/src/main/assets/emoji/0_998.png | Bin 2251 -> 2008 bytes TMessagesProj/src/main/assets/emoji/0_999.png | Bin 2269 -> 2090 bytes TMessagesProj/src/main/assets/emoji/1_0.png | Bin 1876 -> 1876 bytes TMessagesProj/src/main/assets/emoji/1_1.png | Bin 1684 -> 1685 bytes TMessagesProj/src/main/assets/emoji/1_10.png | Bin 2676 -> 2429 bytes TMessagesProj/src/main/assets/emoji/1_100.png | Bin 1083 -> 2070 bytes TMessagesProj/src/main/assets/emoji/1_101.png | Bin 1817 -> 2900 bytes TMessagesProj/src/main/assets/emoji/1_102.png | Bin 2142 -> 2280 bytes TMessagesProj/src/main/assets/emoji/1_103.png | Bin 2110 -> 3691 bytes TMessagesProj/src/main/assets/emoji/1_104.png | Bin 1419 -> 2100 bytes TMessagesProj/src/main/assets/emoji/1_105.png | Bin 2628 -> 1520 bytes TMessagesProj/src/main/assets/emoji/1_106.png | Bin 2186 -> 1547 bytes TMessagesProj/src/main/assets/emoji/1_107.png | Bin 653 -> 1467 bytes TMessagesProj/src/main/assets/emoji/1_108.png | Bin 3707 -> 1368 bytes TMessagesProj/src/main/assets/emoji/1_109.png | Bin 3962 -> 1175 bytes TMessagesProj/src/main/assets/emoji/1_11.png | Bin 1612 -> 2676 bytes TMessagesProj/src/main/assets/emoji/1_110.png | Bin 2101 -> 1668 bytes TMessagesProj/src/main/assets/emoji/1_111.png | Bin 2720 -> 1083 bytes TMessagesProj/src/main/assets/emoji/1_112.png | Bin 2177 -> 1376 bytes TMessagesProj/src/main/assets/emoji/1_113.png | Bin 1996 -> 1817 bytes TMessagesProj/src/main/assets/emoji/1_114.png | Bin 2532 -> 2142 bytes TMessagesProj/src/main/assets/emoji/1_115.png | Bin 1094 -> 2110 bytes TMessagesProj/src/main/assets/emoji/1_116.png | Bin 1673 -> 1420 bytes TMessagesProj/src/main/assets/emoji/1_117.png | Bin 2394 -> 2627 bytes TMessagesProj/src/main/assets/emoji/1_118.png | Bin 2531 -> 2186 bytes TMessagesProj/src/main/assets/emoji/1_119.png | Bin 1846 -> 654 bytes TMessagesProj/src/main/assets/emoji/1_12.png | Bin 1908 -> 1609 bytes TMessagesProj/src/main/assets/emoji/1_120.png | Bin 2308 -> 3708 bytes TMessagesProj/src/main/assets/emoji/1_121.png | Bin 2067 -> 3962 bytes TMessagesProj/src/main/assets/emoji/1_122.png | Bin 1860 -> 2101 bytes TMessagesProj/src/main/assets/emoji/1_123.png | Bin 2411 -> 2719 bytes TMessagesProj/src/main/assets/emoji/1_124.png | Bin 1705 -> 2177 bytes TMessagesProj/src/main/assets/emoji/1_125.png | Bin 1562 -> 1997 bytes TMessagesProj/src/main/assets/emoji/1_126.png | Bin 3089 -> 2531 bytes TMessagesProj/src/main/assets/emoji/1_127.png | Bin 3420 -> 1452 bytes TMessagesProj/src/main/assets/emoji/1_128.png | Bin 2690 -> 1094 bytes TMessagesProj/src/main/assets/emoji/1_129.png | Bin 2022 -> 1675 bytes TMessagesProj/src/main/assets/emoji/1_13.png | Bin 1329 -> 1907 bytes TMessagesProj/src/main/assets/emoji/1_130.png | Bin 1991 -> 2397 bytes TMessagesProj/src/main/assets/emoji/1_131.png | Bin 3040 -> 2531 bytes TMessagesProj/src/main/assets/emoji/1_132.png | Bin 3037 -> 1843 bytes TMessagesProj/src/main/assets/emoji/1_133.png | Bin 2402 -> 1922 bytes TMessagesProj/src/main/assets/emoji/1_134.png | Bin 2417 -> 2303 bytes TMessagesProj/src/main/assets/emoji/1_135.png | Bin 2845 -> 2068 bytes TMessagesProj/src/main/assets/emoji/1_136.png | Bin 1997 -> 1859 bytes TMessagesProj/src/main/assets/emoji/1_137.png | Bin 1415 -> 2410 bytes TMessagesProj/src/main/assets/emoji/1_138.png | Bin 1363 -> 1709 bytes TMessagesProj/src/main/assets/emoji/1_139.png | Bin 1226 -> 1562 bytes TMessagesProj/src/main/assets/emoji/1_14.png | Bin 2378 -> 1330 bytes TMessagesProj/src/main/assets/emoji/1_140.png | Bin 1450 -> 1180 bytes TMessagesProj/src/main/assets/emoji/1_141.png | Bin 1971 -> 3088 bytes TMessagesProj/src/main/assets/emoji/1_142.png | Bin 1881 -> 3418 bytes TMessagesProj/src/main/assets/emoji/1_143.png | Bin 1751 -> 2695 bytes TMessagesProj/src/main/assets/emoji/1_144.png | Bin 1005 -> 2021 bytes TMessagesProj/src/main/assets/emoji/1_145.png | Bin 1638 -> 1991 bytes TMessagesProj/src/main/assets/emoji/1_146.png | Bin 1822 -> 3041 bytes TMessagesProj/src/main/assets/emoji/1_147.png | Bin 1724 -> 3039 bytes TMessagesProj/src/main/assets/emoji/1_148.png | Bin 1106 -> 2402 bytes TMessagesProj/src/main/assets/emoji/1_149.png | Bin 2666 -> 2417 bytes TMessagesProj/src/main/assets/emoji/1_15.png | Bin 1816 -> 2378 bytes TMessagesProj/src/main/assets/emoji/1_150.png | Bin 2980 -> 2844 bytes TMessagesProj/src/main/assets/emoji/1_151.png | Bin 3063 -> 1998 bytes TMessagesProj/src/main/assets/emoji/1_152.png | Bin 2261 -> 1415 bytes TMessagesProj/src/main/assets/emoji/1_153.png | Bin 1525 -> 1362 bytes TMessagesProj/src/main/assets/emoji/1_154.png | Bin 1449 -> 1225 bytes TMessagesProj/src/main/assets/emoji/1_155.png | Bin 1596 -> 1445 bytes TMessagesProj/src/main/assets/emoji/1_156.png | Bin 1122 -> 1970 bytes TMessagesProj/src/main/assets/emoji/1_157.png | Bin 682 -> 1886 bytes TMessagesProj/src/main/assets/emoji/1_158.png | Bin 2525 -> 1748 bytes TMessagesProj/src/main/assets/emoji/1_159.png | Bin 1710 -> 1005 bytes TMessagesProj/src/main/assets/emoji/1_16.png | Bin 2165 -> 1818 bytes TMessagesProj/src/main/assets/emoji/1_160.png | Bin 1713 -> 1642 bytes TMessagesProj/src/main/assets/emoji/1_161.png | Bin 1903 -> 1823 bytes TMessagesProj/src/main/assets/emoji/1_162.png | Bin 2889 -> 1726 bytes TMessagesProj/src/main/assets/emoji/1_163.png | Bin 1367 -> 1104 bytes TMessagesProj/src/main/assets/emoji/1_164.png | Bin 1548 -> 2665 bytes TMessagesProj/src/main/assets/emoji/1_165.png | Bin 1142 -> 2979 bytes TMessagesProj/src/main/assets/emoji/1_166.png | Bin 1060 -> 3063 bytes TMessagesProj/src/main/assets/emoji/1_167.png | Bin 689 -> 2261 bytes TMessagesProj/src/main/assets/emoji/1_168.png | Bin 1676 -> 1523 bytes TMessagesProj/src/main/assets/emoji/1_169.png | Bin 1231 -> 1448 bytes TMessagesProj/src/main/assets/emoji/1_17.png | Bin 2149 -> 2165 bytes TMessagesProj/src/main/assets/emoji/1_170.png | Bin 1876 -> 1596 bytes TMessagesProj/src/main/assets/emoji/1_171.png | Bin 1050 -> 1123 bytes TMessagesProj/src/main/assets/emoji/1_172.png | Bin 1271 -> 682 bytes TMessagesProj/src/main/assets/emoji/1_173.png | Bin 3079 -> 2524 bytes TMessagesProj/src/main/assets/emoji/1_174.png | Bin 2675 -> 1710 bytes TMessagesProj/src/main/assets/emoji/1_175.png | Bin 2035 -> 1715 bytes TMessagesProj/src/main/assets/emoji/1_176.png | Bin 1197 -> 1903 bytes TMessagesProj/src/main/assets/emoji/1_177.png | Bin 1220 -> 2889 bytes TMessagesProj/src/main/assets/emoji/1_178.png | Bin 1079 -> 1366 bytes TMessagesProj/src/main/assets/emoji/1_179.png | Bin 1514 -> 1548 bytes TMessagesProj/src/main/assets/emoji/1_18.png | Bin 2056 -> 2149 bytes TMessagesProj/src/main/assets/emoji/1_180.png | Bin 2181 -> 1142 bytes TMessagesProj/src/main/assets/emoji/1_181.png | Bin 1356 -> 1060 bytes TMessagesProj/src/main/assets/emoji/1_182.png | Bin 2493 -> 689 bytes TMessagesProj/src/main/assets/emoji/1_183.png | Bin 866 -> 1676 bytes TMessagesProj/src/main/assets/emoji/1_184.png | Bin 0 -> 1231 bytes TMessagesProj/src/main/assets/emoji/1_185.png | Bin 0 -> 1874 bytes TMessagesProj/src/main/assets/emoji/1_186.png | Bin 0 -> 1050 bytes TMessagesProj/src/main/assets/emoji/1_187.png | Bin 0 -> 1272 bytes TMessagesProj/src/main/assets/emoji/1_188.png | Bin 0 -> 3079 bytes TMessagesProj/src/main/assets/emoji/1_189.png | Bin 0 -> 2676 bytes TMessagesProj/src/main/assets/emoji/1_19.png | Bin 2130 -> 2055 bytes TMessagesProj/src/main/assets/emoji/1_190.png | Bin 0 -> 2035 bytes TMessagesProj/src/main/assets/emoji/1_191.png | Bin 0 -> 1197 bytes TMessagesProj/src/main/assets/emoji/1_192.png | Bin 0 -> 1223 bytes TMessagesProj/src/main/assets/emoji/1_193.png | Bin 0 -> 1079 bytes TMessagesProj/src/main/assets/emoji/1_194.png | Bin 0 -> 1515 bytes TMessagesProj/src/main/assets/emoji/1_195.png | Bin 0 -> 2182 bytes TMessagesProj/src/main/assets/emoji/1_196.png | Bin 0 -> 1355 bytes TMessagesProj/src/main/assets/emoji/1_197.png | Bin 0 -> 2493 bytes TMessagesProj/src/main/assets/emoji/1_198.png | Bin 0 -> 866 bytes TMessagesProj/src/main/assets/emoji/1_2.png | Bin 1821 -> 1821 bytes TMessagesProj/src/main/assets/emoji/1_20.png | Bin 1940 -> 2130 bytes TMessagesProj/src/main/assets/emoji/1_21.png | Bin 1219 -> 1937 bytes TMessagesProj/src/main/assets/emoji/1_22.png | Bin 1292 -> 1222 bytes TMessagesProj/src/main/assets/emoji/1_23.png | Bin 1104 -> 1290 bytes TMessagesProj/src/main/assets/emoji/1_24.png | Bin 2233 -> 1106 bytes TMessagesProj/src/main/assets/emoji/1_25.png | Bin 1928 -> 2228 bytes TMessagesProj/src/main/assets/emoji/1_26.png | Bin 2311 -> 1929 bytes TMessagesProj/src/main/assets/emoji/1_27.png | Bin 2172 -> 2312 bytes TMessagesProj/src/main/assets/emoji/1_28.png | Bin 2039 -> 2171 bytes TMessagesProj/src/main/assets/emoji/1_29.png | Bin 1516 -> 2038 bytes TMessagesProj/src/main/assets/emoji/1_3.png | Bin 2466 -> 2465 bytes TMessagesProj/src/main/assets/emoji/1_30.png | Bin 1504 -> 1517 bytes TMessagesProj/src/main/assets/emoji/1_31.png | Bin 1456 -> 1501 bytes TMessagesProj/src/main/assets/emoji/1_32.png | Bin 1807 -> 1459 bytes TMessagesProj/src/main/assets/emoji/1_33.png | Bin 2955 -> 1803 bytes TMessagesProj/src/main/assets/emoji/1_34.png | Bin 2747 -> 2954 bytes TMessagesProj/src/main/assets/emoji/1_35.png | Bin 3077 -> 2746 bytes TMessagesProj/src/main/assets/emoji/1_36.png | Bin 2197 -> 2100 bytes TMessagesProj/src/main/assets/emoji/1_37.png | Bin 2415 -> 3077 bytes TMessagesProj/src/main/assets/emoji/1_38.png | Bin 2802 -> 2197 bytes TMessagesProj/src/main/assets/emoji/1_39.png | Bin 1767 -> 2416 bytes TMessagesProj/src/main/assets/emoji/1_4.png | Bin 1601 -> 1602 bytes TMessagesProj/src/main/assets/emoji/1_40.png | Bin 2474 -> 2800 bytes TMessagesProj/src/main/assets/emoji/1_41.png | Bin 1649 -> 1767 bytes TMessagesProj/src/main/assets/emoji/1_42.png | Bin 1523 -> 2524 bytes TMessagesProj/src/main/assets/emoji/1_43.png | Bin 1761 -> 2229 bytes TMessagesProj/src/main/assets/emoji/1_44.png | Bin 1778 -> 1838 bytes TMessagesProj/src/main/assets/emoji/1_45.png | Bin 1708 -> 2474 bytes TMessagesProj/src/main/assets/emoji/1_46.png | Bin 2442 -> 1649 bytes TMessagesProj/src/main/assets/emoji/1_47.png | Bin 2717 -> 1524 bytes TMessagesProj/src/main/assets/emoji/1_48.png | Bin 1848 -> 1760 bytes TMessagesProj/src/main/assets/emoji/1_49.png | Bin 1483 -> 1778 bytes TMessagesProj/src/main/assets/emoji/1_5.png | Bin 2059 -> 2055 bytes TMessagesProj/src/main/assets/emoji/1_50.png | Bin 1713 -> 1708 bytes TMessagesProj/src/main/assets/emoji/1_51.png | Bin 3275 -> 2439 bytes TMessagesProj/src/main/assets/emoji/1_52.png | Bin 3554 -> 2718 bytes TMessagesProj/src/main/assets/emoji/1_53.png | Bin 2630 -> 1848 bytes TMessagesProj/src/main/assets/emoji/1_54.png | Bin 3105 -> 1483 bytes TMessagesProj/src/main/assets/emoji/1_55.png | Bin 2624 -> 1715 bytes TMessagesProj/src/main/assets/emoji/1_56.png | Bin 2843 -> 3274 bytes TMessagesProj/src/main/assets/emoji/1_57.png | Bin 1574 -> 3554 bytes TMessagesProj/src/main/assets/emoji/1_58.png | Bin 1824 -> 2632 bytes TMessagesProj/src/main/assets/emoji/1_59.png | Bin 1949 -> 3103 bytes TMessagesProj/src/main/assets/emoji/1_6.png | Bin 1424 -> 1422 bytes TMessagesProj/src/main/assets/emoji/1_60.png | Bin 1571 -> 2624 bytes TMessagesProj/src/main/assets/emoji/1_61.png | Bin 1712 -> 2842 bytes TMessagesProj/src/main/assets/emoji/1_62.png | Bin 2135 -> 1574 bytes TMessagesProj/src/main/assets/emoji/1_63.png | Bin 2527 -> 1824 bytes TMessagesProj/src/main/assets/emoji/1_64.png | Bin 2237 -> 1939 bytes TMessagesProj/src/main/assets/emoji/1_65.png | Bin 1701 -> 1570 bytes TMessagesProj/src/main/assets/emoji/1_66.png | Bin 1620 -> 1713 bytes TMessagesProj/src/main/assets/emoji/1_67.png | Bin 2142 -> 1078 bytes TMessagesProj/src/main/assets/emoji/1_68.png | Bin 1445 -> 2136 bytes TMessagesProj/src/main/assets/emoji/1_69.png | Bin 1020 -> 2524 bytes TMessagesProj/src/main/assets/emoji/1_7.png | Bin 1473 -> 1473 bytes TMessagesProj/src/main/assets/emoji/1_70.png | Bin 1289 -> 2236 bytes TMessagesProj/src/main/assets/emoji/1_71.png | Bin 1403 -> 1700 bytes TMessagesProj/src/main/assets/emoji/1_72.png | Bin 1812 -> 1621 bytes TMessagesProj/src/main/assets/emoji/1_73.png | Bin 2199 -> 2142 bytes TMessagesProj/src/main/assets/emoji/1_74.png | Bin 1615 -> 1618 bytes TMessagesProj/src/main/assets/emoji/1_75.png | Bin 1291 -> 1446 bytes TMessagesProj/src/main/assets/emoji/1_76.png | Bin 1395 -> 1018 bytes TMessagesProj/src/main/assets/emoji/1_77.png | Bin 1878 -> 1289 bytes TMessagesProj/src/main/assets/emoji/1_78.png | Bin 1863 -> 1403 bytes TMessagesProj/src/main/assets/emoji/1_79.png | Bin 1263 -> 1812 bytes TMessagesProj/src/main/assets/emoji/1_8.png | Bin 1298 -> 1493 bytes TMessagesProj/src/main/assets/emoji/1_80.png | Bin 1803 -> 2196 bytes TMessagesProj/src/main/assets/emoji/1_81.png | Bin 1555 -> 1615 bytes TMessagesProj/src/main/assets/emoji/1_82.png | Bin 1364 -> 1259 bytes TMessagesProj/src/main/assets/emoji/1_83.png | Bin 1553 -> 1290 bytes TMessagesProj/src/main/assets/emoji/1_84.png | Bin 2046 -> 1396 bytes TMessagesProj/src/main/assets/emoji/1_85.png | Bin 1986 -> 1877 bytes TMessagesProj/src/main/assets/emoji/1_86.png | Bin 1758 -> 1864 bytes TMessagesProj/src/main/assets/emoji/1_87.png | Bin 2670 -> 1263 bytes TMessagesProj/src/main/assets/emoji/1_88.png | Bin 1891 -> 1803 bytes TMessagesProj/src/main/assets/emoji/1_89.png | Bin 2509 -> 1555 bytes TMessagesProj/src/main/assets/emoji/1_9.png | Bin 2426 -> 1298 bytes TMessagesProj/src/main/assets/emoji/1_90.png | Bin 2070 -> 1363 bytes TMessagesProj/src/main/assets/emoji/1_91.png | Bin 2902 -> 1552 bytes TMessagesProj/src/main/assets/emoji/1_92.png | Bin 3691 -> 2047 bytes TMessagesProj/src/main/assets/emoji/1_93.png | Bin 2099 -> 1987 bytes TMessagesProj/src/main/assets/emoji/1_94.png | Bin 1521 -> 1759 bytes TMessagesProj/src/main/assets/emoji/1_95.png | Bin 1541 -> 2670 bytes TMessagesProj/src/main/assets/emoji/1_96.png | Bin 1464 -> 1892 bytes TMessagesProj/src/main/assets/emoji/1_97.png | Bin 1367 -> 2507 bytes TMessagesProj/src/main/assets/emoji/1_98.png | Bin 1177 -> 1127 bytes TMessagesProj/src/main/assets/emoji/1_99.png | Bin 1671 -> 1473 bytes TMessagesProj/src/main/assets/emoji/2_0.png | Bin 1538 -> 1539 bytes TMessagesProj/src/main/assets/emoji/2_1.png | Bin 1722 -> 1724 bytes TMessagesProj/src/main/assets/emoji/2_10.png | Bin 1914 -> 1817 bytes TMessagesProj/src/main/assets/emoji/2_100.png | Bin 1885 -> 1580 bytes TMessagesProj/src/main/assets/emoji/2_101.png | Bin 1520 -> 1898 bytes TMessagesProj/src/main/assets/emoji/2_102.png | Bin 1699 -> 1582 bytes TMessagesProj/src/main/assets/emoji/2_103.png | Bin 1752 -> 1316 bytes TMessagesProj/src/main/assets/emoji/2_104.png | Bin 2485 -> 1670 bytes TMessagesProj/src/main/assets/emoji/2_105.png | Bin 1591 -> 1433 bytes TMessagesProj/src/main/assets/emoji/2_106.png | Bin 1990 -> 2549 bytes TMessagesProj/src/main/assets/emoji/2_107.png | Bin 1919 -> 2528 bytes TMessagesProj/src/main/assets/emoji/2_108.png | Bin 950 -> 1883 bytes TMessagesProj/src/main/assets/emoji/2_109.png | Bin 1261 -> 1519 bytes TMessagesProj/src/main/assets/emoji/2_11.png | Bin 2374 -> 1915 bytes TMessagesProj/src/main/assets/emoji/2_110.png | Bin 1775 -> 1699 bytes TMessagesProj/src/main/assets/emoji/2_111.png | Bin 1206 -> 1753 bytes TMessagesProj/src/main/assets/emoji/2_112.png | Bin 1362 -> 2483 bytes TMessagesProj/src/main/assets/emoji/2_113.png | Bin 1046 -> 1591 bytes TMessagesProj/src/main/assets/emoji/2_114.png | Bin 1402 -> 1987 bytes TMessagesProj/src/main/assets/emoji/2_115.png | Bin 0 -> 1919 bytes TMessagesProj/src/main/assets/emoji/2_116.png | Bin 0 -> 950 bytes TMessagesProj/src/main/assets/emoji/2_117.png | Bin 0 -> 1261 bytes TMessagesProj/src/main/assets/emoji/2_118.png | Bin 0 -> 1775 bytes TMessagesProj/src/main/assets/emoji/2_119.png | Bin 0 -> 1208 bytes TMessagesProj/src/main/assets/emoji/2_12.png | Bin 2049 -> 2374 bytes TMessagesProj/src/main/assets/emoji/2_120.png | Bin 0 -> 1363 bytes TMessagesProj/src/main/assets/emoji/2_121.png | Bin 0 -> 1046 bytes TMessagesProj/src/main/assets/emoji/2_122.png | Bin 0 -> 1401 bytes TMessagesProj/src/main/assets/emoji/2_13.png | Bin 2594 -> 2051 bytes TMessagesProj/src/main/assets/emoji/2_14.png | Bin 1802 -> 2594 bytes TMessagesProj/src/main/assets/emoji/2_15.png | Bin 1872 -> 1801 bytes TMessagesProj/src/main/assets/emoji/2_16.png | Bin 1969 -> 1872 bytes TMessagesProj/src/main/assets/emoji/2_17.png | Bin 1390 -> 1970 bytes TMessagesProj/src/main/assets/emoji/2_18.png | Bin 2061 -> 1390 bytes TMessagesProj/src/main/assets/emoji/2_19.png | Bin 2306 -> 2059 bytes TMessagesProj/src/main/assets/emoji/2_2.png | Bin 988 -> 990 bytes TMessagesProj/src/main/assets/emoji/2_20.png | Bin 2423 -> 2306 bytes TMessagesProj/src/main/assets/emoji/2_21.png | Bin 2420 -> 2425 bytes TMessagesProj/src/main/assets/emoji/2_22.png | Bin 1606 -> 2421 bytes TMessagesProj/src/main/assets/emoji/2_23.png | Bin 2929 -> 1605 bytes TMessagesProj/src/main/assets/emoji/2_24.png | Bin 1721 -> 1759 bytes TMessagesProj/src/main/assets/emoji/2_25.png | Bin 1312 -> 2929 bytes TMessagesProj/src/main/assets/emoji/2_26.png | Bin 1694 -> 1721 bytes TMessagesProj/src/main/assets/emoji/2_27.png | Bin 1300 -> 1406 bytes TMessagesProj/src/main/assets/emoji/2_28.png | Bin 1494 -> 1312 bytes TMessagesProj/src/main/assets/emoji/2_29.png | Bin 1820 -> 1693 bytes TMessagesProj/src/main/assets/emoji/2_3.png | Bin 2051 -> 2055 bytes TMessagesProj/src/main/assets/emoji/2_30.png | Bin 2309 -> 1302 bytes TMessagesProj/src/main/assets/emoji/2_31.png | Bin 1453 -> 1492 bytes TMessagesProj/src/main/assets/emoji/2_32.png | Bin 1211 -> 1820 bytes TMessagesProj/src/main/assets/emoji/2_33.png | Bin 2352 -> 2308 bytes TMessagesProj/src/main/assets/emoji/2_34.png | Bin 1051 -> 1453 bytes TMessagesProj/src/main/assets/emoji/2_35.png | Bin 839 -> 1211 bytes TMessagesProj/src/main/assets/emoji/2_36.png | Bin 1713 -> 2351 bytes TMessagesProj/src/main/assets/emoji/2_37.png | Bin 1033 -> 1049 bytes TMessagesProj/src/main/assets/emoji/2_38.png | Bin 2369 -> 841 bytes TMessagesProj/src/main/assets/emoji/2_39.png | Bin 1764 -> 1713 bytes TMessagesProj/src/main/assets/emoji/2_4.png | Bin 1875 -> 1874 bytes TMessagesProj/src/main/assets/emoji/2_40.png | Bin 2401 -> 1033 bytes TMessagesProj/src/main/assets/emoji/2_41.png | Bin 2140 -> 2370 bytes TMessagesProj/src/main/assets/emoji/2_42.png | Bin 1461 -> 1763 bytes TMessagesProj/src/main/assets/emoji/2_43.png | Bin 2148 -> 2401 bytes TMessagesProj/src/main/assets/emoji/2_44.png | Bin 920 -> 2140 bytes TMessagesProj/src/main/assets/emoji/2_45.png | Bin 1831 -> 1466 bytes TMessagesProj/src/main/assets/emoji/2_46.png | Bin 3045 -> 2151 bytes TMessagesProj/src/main/assets/emoji/2_47.png | Bin 2242 -> 920 bytes TMessagesProj/src/main/assets/emoji/2_48.png | Bin 1815 -> 1829 bytes TMessagesProj/src/main/assets/emoji/2_49.png | Bin 2140 -> 3045 bytes TMessagesProj/src/main/assets/emoji/2_5.png | Bin 1933 -> 1931 bytes TMessagesProj/src/main/assets/emoji/2_50.png | Bin 2352 -> 2238 bytes TMessagesProj/src/main/assets/emoji/2_51.png | Bin 1904 -> 1816 bytes TMessagesProj/src/main/assets/emoji/2_52.png | Bin 2527 -> 1125 bytes TMessagesProj/src/main/assets/emoji/2_53.png | Bin 2400 -> 2141 bytes TMessagesProj/src/main/assets/emoji/2_54.png | Bin 3428 -> 2351 bytes TMessagesProj/src/main/assets/emoji/2_55.png | Bin 2675 -> 1905 bytes TMessagesProj/src/main/assets/emoji/2_56.png | Bin 1505 -> 2530 bytes TMessagesProj/src/main/assets/emoji/2_57.png | Bin 2514 -> 2400 bytes TMessagesProj/src/main/assets/emoji/2_58.png | Bin 2406 -> 1594 bytes TMessagesProj/src/main/assets/emoji/2_59.png | Bin 1787 -> 3427 bytes TMessagesProj/src/main/assets/emoji/2_6.png | Bin 1584 -> 1584 bytes TMessagesProj/src/main/assets/emoji/2_60.png | Bin 1827 -> 2670 bytes TMessagesProj/src/main/assets/emoji/2_61.png | Bin 2148 -> 1865 bytes TMessagesProj/src/main/assets/emoji/2_62.png | Bin 3439 -> 1505 bytes TMessagesProj/src/main/assets/emoji/2_63.png | Bin 1608 -> 2513 bytes TMessagesProj/src/main/assets/emoji/2_64.png | Bin 1563 -> 2410 bytes TMessagesProj/src/main/assets/emoji/2_65.png | Bin 2382 -> 1787 bytes TMessagesProj/src/main/assets/emoji/2_66.png | Bin 1757 -> 1826 bytes TMessagesProj/src/main/assets/emoji/2_67.png | Bin 1421 -> 2148 bytes TMessagesProj/src/main/assets/emoji/2_68.png | Bin 1681 -> 3441 bytes TMessagesProj/src/main/assets/emoji/2_69.png | Bin 1435 -> 1607 bytes TMessagesProj/src/main/assets/emoji/2_7.png | Bin 2818 -> 2823 bytes TMessagesProj/src/main/assets/emoji/2_70.png | Bin 1159 -> 1562 bytes TMessagesProj/src/main/assets/emoji/2_71.png | Bin 2079 -> 2382 bytes TMessagesProj/src/main/assets/emoji/2_72.png | Bin 1603 -> 1756 bytes TMessagesProj/src/main/assets/emoji/2_73.png | Bin 1704 -> 1421 bytes TMessagesProj/src/main/assets/emoji/2_74.png | Bin 2087 -> 1672 bytes TMessagesProj/src/main/assets/emoji/2_75.png | Bin 1767 -> 1437 bytes TMessagesProj/src/main/assets/emoji/2_76.png | Bin 1438 -> 1160 bytes TMessagesProj/src/main/assets/emoji/2_77.png | Bin 1876 -> 2079 bytes TMessagesProj/src/main/assets/emoji/2_78.png | Bin 2759 -> 1603 bytes TMessagesProj/src/main/assets/emoji/2_79.png | Bin 1673 -> 1704 bytes TMessagesProj/src/main/assets/emoji/2_8.png | Bin 2438 -> 2438 bytes TMessagesProj/src/main/assets/emoji/2_80.png | Bin 1979 -> 2088 bytes TMessagesProj/src/main/assets/emoji/2_81.png | Bin 1617 -> 1767 bytes TMessagesProj/src/main/assets/emoji/2_82.png | Bin 2654 -> 1438 bytes TMessagesProj/src/main/assets/emoji/2_83.png | Bin 1946 -> 1875 bytes TMessagesProj/src/main/assets/emoji/2_84.png | Bin 1218 -> 2758 bytes TMessagesProj/src/main/assets/emoji/2_85.png | Bin 2416 -> 1675 bytes TMessagesProj/src/main/assets/emoji/2_86.png | Bin 3476 -> 1979 bytes TMessagesProj/src/main/assets/emoji/2_87.png | Bin 1821 -> 1617 bytes TMessagesProj/src/main/assets/emoji/2_88.png | Bin 1784 -> 2656 bytes TMessagesProj/src/main/assets/emoji/2_89.png | Bin 2891 -> 1945 bytes TMessagesProj/src/main/assets/emoji/2_9.png | Bin 1817 -> 1730 bytes TMessagesProj/src/main/assets/emoji/2_90.png | Bin 2601 -> 1217 bytes TMessagesProj/src/main/assets/emoji/2_91.png | Bin 1469 -> 2416 bytes TMessagesProj/src/main/assets/emoji/2_92.png | Bin 1475 -> 3477 bytes TMessagesProj/src/main/assets/emoji/2_93.png | Bin 1577 -> 1828 bytes TMessagesProj/src/main/assets/emoji/2_94.png | Bin 1899 -> 1787 bytes TMessagesProj/src/main/assets/emoji/2_95.png | Bin 1582 -> 2891 bytes TMessagesProj/src/main/assets/emoji/2_96.png | Bin 1317 -> 2602 bytes TMessagesProj/src/main/assets/emoji/2_97.png | Bin 1435 -> 1467 bytes TMessagesProj/src/main/assets/emoji/2_98.png | Bin 2549 -> 1474 bytes TMessagesProj/src/main/assets/emoji/2_99.png | Bin 2527 -> 1254 bytes TMessagesProj/src/main/assets/emoji/3_0.png | Bin 1480 -> 1483 bytes TMessagesProj/src/main/assets/emoji/3_1.png | Bin 2351 -> 2351 bytes TMessagesProj/src/main/assets/emoji/3_10.png | Bin 1828 -> 1828 bytes TMessagesProj/src/main/assets/emoji/3_100.png | Bin 2214 -> 2301 bytes TMessagesProj/src/main/assets/emoji/3_101.png | Bin 2054 -> 2162 bytes TMessagesProj/src/main/assets/emoji/3_102.png | Bin 1992 -> 2211 bytes TMessagesProj/src/main/assets/emoji/3_103.png | Bin 1762 -> 2055 bytes TMessagesProj/src/main/assets/emoji/3_104.png | Bin 2668 -> 1991 bytes TMessagesProj/src/main/assets/emoji/3_105.png | Bin 2678 -> 1761 bytes TMessagesProj/src/main/assets/emoji/3_106.png | Bin 2681 -> 2669 bytes TMessagesProj/src/main/assets/emoji/3_107.png | Bin 2684 -> 2677 bytes TMessagesProj/src/main/assets/emoji/3_108.png | Bin 2631 -> 2680 bytes TMessagesProj/src/main/assets/emoji/3_109.png | Bin 2422 -> 2682 bytes TMessagesProj/src/main/assets/emoji/3_11.png | Bin 1911 -> 1913 bytes TMessagesProj/src/main/assets/emoji/3_110.png | Bin 2216 -> 2632 bytes TMessagesProj/src/main/assets/emoji/3_111.png | Bin 2054 -> 2423 bytes TMessagesProj/src/main/assets/emoji/3_112.png | Bin 2120 -> 2215 bytes TMessagesProj/src/main/assets/emoji/3_113.png | Bin 1976 -> 2053 bytes TMessagesProj/src/main/assets/emoji/3_114.png | Bin 1841 -> 2121 bytes TMessagesProj/src/main/assets/emoji/3_115.png | Bin 1798 -> 1975 bytes TMessagesProj/src/main/assets/emoji/3_116.png | Bin 1774 -> 1841 bytes TMessagesProj/src/main/assets/emoji/3_117.png | Bin 1661 -> 1798 bytes TMessagesProj/src/main/assets/emoji/3_118.png | Bin 1780 -> 1774 bytes TMessagesProj/src/main/assets/emoji/3_119.png | Bin 1726 -> 1660 bytes TMessagesProj/src/main/assets/emoji/3_12.png | Bin 2803 -> 2803 bytes TMessagesProj/src/main/assets/emoji/3_120.png | Bin 1660 -> 1782 bytes TMessagesProj/src/main/assets/emoji/3_121.png | Bin 1467 -> 1726 bytes TMessagesProj/src/main/assets/emoji/3_122.png | Bin 2155 -> 1661 bytes TMessagesProj/src/main/assets/emoji/3_123.png | Bin 2050 -> 1468 bytes TMessagesProj/src/main/assets/emoji/3_124.png | Bin 2019 -> 2155 bytes TMessagesProj/src/main/assets/emoji/3_125.png | Bin 2000 -> 2051 bytes TMessagesProj/src/main/assets/emoji/3_126.png | Bin 2036 -> 2018 bytes TMessagesProj/src/main/assets/emoji/3_127.png | Bin 2026 -> 2003 bytes TMessagesProj/src/main/assets/emoji/3_128.png | Bin 2281 -> 2036 bytes TMessagesProj/src/main/assets/emoji/3_129.png | Bin 2198 -> 2028 bytes TMessagesProj/src/main/assets/emoji/3_13.png | Bin 1451 -> 1452 bytes TMessagesProj/src/main/assets/emoji/3_130.png | Bin 2245 -> 2282 bytes TMessagesProj/src/main/assets/emoji/3_131.png | Bin 2263 -> 2198 bytes TMessagesProj/src/main/assets/emoji/3_132.png | Bin 2223 -> 2246 bytes TMessagesProj/src/main/assets/emoji/3_133.png | Bin 2242 -> 2260 bytes TMessagesProj/src/main/assets/emoji/3_134.png | Bin 1903 -> 2226 bytes TMessagesProj/src/main/assets/emoji/3_135.png | Bin 1876 -> 2239 bytes TMessagesProj/src/main/assets/emoji/3_136.png | Bin 1845 -> 1901 bytes TMessagesProj/src/main/assets/emoji/3_137.png | Bin 1677 -> 1875 bytes TMessagesProj/src/main/assets/emoji/3_138.png | Bin 1520 -> 1844 bytes TMessagesProj/src/main/assets/emoji/3_139.png | Bin 1382 -> 1677 bytes TMessagesProj/src/main/assets/emoji/3_14.png | Bin 1524 -> 1524 bytes TMessagesProj/src/main/assets/emoji/3_140.png | Bin 1836 -> 1521 bytes TMessagesProj/src/main/assets/emoji/3_141.png | Bin 1828 -> 1383 bytes TMessagesProj/src/main/assets/emoji/3_142.png | Bin 1687 -> 1836 bytes TMessagesProj/src/main/assets/emoji/3_143.png | Bin 1598 -> 1826 bytes TMessagesProj/src/main/assets/emoji/3_144.png | Bin 1626 -> 1687 bytes TMessagesProj/src/main/assets/emoji/3_145.png | Bin 1246 -> 1598 bytes TMessagesProj/src/main/assets/emoji/3_146.png | Bin 1841 -> 1626 bytes TMessagesProj/src/main/assets/emoji/3_147.png | Bin 1877 -> 1247 bytes TMessagesProj/src/main/assets/emoji/3_148.png | Bin 1814 -> 1840 bytes TMessagesProj/src/main/assets/emoji/3_149.png | Bin 1608 -> 1878 bytes TMessagesProj/src/main/assets/emoji/3_15.png | Bin 1848 -> 1847 bytes TMessagesProj/src/main/assets/emoji/3_150.png | Bin 1508 -> 1811 bytes TMessagesProj/src/main/assets/emoji/3_151.png | Bin 1318 -> 1609 bytes TMessagesProj/src/main/assets/emoji/3_152.png | Bin 2893 -> 1508 bytes TMessagesProj/src/main/assets/emoji/3_153.png | Bin 2559 -> 1316 bytes TMessagesProj/src/main/assets/emoji/3_154.png | Bin 2504 -> 2893 bytes TMessagesProj/src/main/assets/emoji/3_155.png | Bin 2526 -> 2559 bytes TMessagesProj/src/main/assets/emoji/3_156.png | Bin 2436 -> 2508 bytes TMessagesProj/src/main/assets/emoji/3_157.png | Bin 2305 -> 2525 bytes TMessagesProj/src/main/assets/emoji/3_158.png | Bin 2675 -> 2438 bytes TMessagesProj/src/main/assets/emoji/3_159.png | Bin 2286 -> 2307 bytes TMessagesProj/src/main/assets/emoji/3_16.png | Bin 1593 -> 1595 bytes TMessagesProj/src/main/assets/emoji/3_160.png | Bin 2329 -> 2676 bytes TMessagesProj/src/main/assets/emoji/3_161.png | Bin 2373 -> 2288 bytes TMessagesProj/src/main/assets/emoji/3_162.png | Bin 2394 -> 2328 bytes TMessagesProj/src/main/assets/emoji/3_163.png | Bin 2222 -> 2373 bytes TMessagesProj/src/main/assets/emoji/3_164.png | Bin 2651 -> 2395 bytes TMessagesProj/src/main/assets/emoji/3_165.png | Bin 2489 -> 2223 bytes TMessagesProj/src/main/assets/emoji/3_166.png | Bin 2522 -> 2649 bytes TMessagesProj/src/main/assets/emoji/3_167.png | Bin 2336 -> 2490 bytes TMessagesProj/src/main/assets/emoji/3_168.png | Bin 2418 -> 2519 bytes TMessagesProj/src/main/assets/emoji/3_169.png | Bin 2365 -> 2336 bytes TMessagesProj/src/main/assets/emoji/3_17.png | Bin 2164 -> 1325 bytes TMessagesProj/src/main/assets/emoji/3_170.png | Bin 2577 -> 2418 bytes TMessagesProj/src/main/assets/emoji/3_171.png | Bin 2349 -> 2362 bytes TMessagesProj/src/main/assets/emoji/3_172.png | Bin 2469 -> 2577 bytes TMessagesProj/src/main/assets/emoji/3_173.png | Bin 2285 -> 2349 bytes TMessagesProj/src/main/assets/emoji/3_174.png | Bin 2290 -> 2469 bytes TMessagesProj/src/main/assets/emoji/3_175.png | Bin 2012 -> 2287 bytes TMessagesProj/src/main/assets/emoji/3_176.png | Bin 2319 -> 2290 bytes TMessagesProj/src/main/assets/emoji/3_177.png | Bin 1991 -> 2012 bytes TMessagesProj/src/main/assets/emoji/3_178.png | Bin 2095 -> 2322 bytes TMessagesProj/src/main/assets/emoji/3_179.png | Bin 2052 -> 2004 bytes TMessagesProj/src/main/assets/emoji/3_18.png | Bin 1361 -> 2164 bytes TMessagesProj/src/main/assets/emoji/3_180.png | Bin 2032 -> 2099 bytes TMessagesProj/src/main/assets/emoji/3_181.png | Bin 1754 -> 2053 bytes TMessagesProj/src/main/assets/emoji/3_182.png | Bin 2440 -> 2032 bytes TMessagesProj/src/main/assets/emoji/3_183.png | Bin 1994 -> 1754 bytes TMessagesProj/src/main/assets/emoji/3_184.png | Bin 2127 -> 2440 bytes TMessagesProj/src/main/assets/emoji/3_185.png | Bin 2148 -> 1995 bytes TMessagesProj/src/main/assets/emoji/3_186.png | Bin 2051 -> 2128 bytes TMessagesProj/src/main/assets/emoji/3_187.png | Bin 1901 -> 2148 bytes TMessagesProj/src/main/assets/emoji/3_188.png | Bin 2802 -> 2051 bytes TMessagesProj/src/main/assets/emoji/3_189.png | Bin 2647 -> 1899 bytes TMessagesProj/src/main/assets/emoji/3_19.png | Bin 1633 -> 1361 bytes TMessagesProj/src/main/assets/emoji/3_190.png | Bin 2570 -> 2803 bytes TMessagesProj/src/main/assets/emoji/3_191.png | Bin 2575 -> 2647 bytes TMessagesProj/src/main/assets/emoji/3_192.png | Bin 2576 -> 2570 bytes TMessagesProj/src/main/assets/emoji/3_193.png | Bin 2328 -> 2575 bytes TMessagesProj/src/main/assets/emoji/3_194.png | Bin 2409 -> 2576 bytes TMessagesProj/src/main/assets/emoji/3_195.png | Bin 2311 -> 2328 bytes TMessagesProj/src/main/assets/emoji/3_196.png | Bin 2235 -> 2409 bytes TMessagesProj/src/main/assets/emoji/3_197.png | Bin 2300 -> 2311 bytes TMessagesProj/src/main/assets/emoji/3_198.png | Bin 2143 -> 2235 bytes TMessagesProj/src/main/assets/emoji/3_199.png | Bin 2032 -> 2300 bytes TMessagesProj/src/main/assets/emoji/3_2.png | Bin 2111 -> 2113 bytes TMessagesProj/src/main/assets/emoji/3_20.png | Bin 2135 -> 1633 bytes TMessagesProj/src/main/assets/emoji/3_200.png | Bin 2269 -> 2143 bytes TMessagesProj/src/main/assets/emoji/3_201.png | Bin 2128 -> 2032 bytes TMessagesProj/src/main/assets/emoji/3_202.png | Bin 2118 -> 2269 bytes TMessagesProj/src/main/assets/emoji/3_203.png | Bin 2224 -> 2128 bytes TMessagesProj/src/main/assets/emoji/3_204.png | Bin 2075 -> 2118 bytes TMessagesProj/src/main/assets/emoji/3_205.png | Bin 1930 -> 2224 bytes TMessagesProj/src/main/assets/emoji/3_206.png | Bin 1853 -> 2075 bytes TMessagesProj/src/main/assets/emoji/3_207.png | Bin 1751 -> 1930 bytes TMessagesProj/src/main/assets/emoji/3_208.png | Bin 1630 -> 1850 bytes TMessagesProj/src/main/assets/emoji/3_209.png | Bin 1701 -> 1750 bytes TMessagesProj/src/main/assets/emoji/3_21.png | Bin 2772 -> 2136 bytes TMessagesProj/src/main/assets/emoji/3_210.png | Bin 1704 -> 1630 bytes TMessagesProj/src/main/assets/emoji/3_211.png | Bin 1746 -> 1702 bytes TMessagesProj/src/main/assets/emoji/3_212.png | Bin 1693 -> 1705 bytes TMessagesProj/src/main/assets/emoji/3_213.png | Bin 1570 -> 1744 bytes TMessagesProj/src/main/assets/emoji/3_214.png | Bin 1524 -> 1693 bytes TMessagesProj/src/main/assets/emoji/3_215.png | Bin 1538 -> 1568 bytes TMessagesProj/src/main/assets/emoji/3_216.png | Bin 1557 -> 1525 bytes TMessagesProj/src/main/assets/emoji/3_217.png | Bin 1549 -> 1538 bytes TMessagesProj/src/main/assets/emoji/3_218.png | Bin 1773 -> 1557 bytes TMessagesProj/src/main/assets/emoji/3_219.png | Bin 1720 -> 1549 bytes TMessagesProj/src/main/assets/emoji/3_22.png | Bin 2481 -> 2772 bytes TMessagesProj/src/main/assets/emoji/3_220.png | Bin 1700 -> 1772 bytes TMessagesProj/src/main/assets/emoji/3_221.png | Bin 1689 -> 1719 bytes TMessagesProj/src/main/assets/emoji/3_222.png | Bin 1709 -> 1701 bytes TMessagesProj/src/main/assets/emoji/3_223.png | Bin 1693 -> 1689 bytes TMessagesProj/src/main/assets/emoji/3_224.png | Bin 3336 -> 1708 bytes TMessagesProj/src/main/assets/emoji/3_225.png | Bin 2886 -> 1691 bytes TMessagesProj/src/main/assets/emoji/3_226.png | Bin 2985 -> 3337 bytes TMessagesProj/src/main/assets/emoji/3_227.png | Bin 2713 -> 2884 bytes TMessagesProj/src/main/assets/emoji/3_228.png | Bin 2646 -> 2985 bytes TMessagesProj/src/main/assets/emoji/3_229.png | Bin 2566 -> 2714 bytes TMessagesProj/src/main/assets/emoji/3_23.png | Bin 1737 -> 2480 bytes TMessagesProj/src/main/assets/emoji/3_230.png | Bin 3049 -> 2646 bytes TMessagesProj/src/main/assets/emoji/3_231.png | Bin 2822 -> 2566 bytes TMessagesProj/src/main/assets/emoji/3_232.png | Bin 2786 -> 3048 bytes TMessagesProj/src/main/assets/emoji/3_233.png | Bin 2604 -> 2823 bytes TMessagesProj/src/main/assets/emoji/3_234.png | Bin 2458 -> 2784 bytes TMessagesProj/src/main/assets/emoji/3_235.png | Bin 2227 -> 2605 bytes TMessagesProj/src/main/assets/emoji/3_236.png | Bin 2890 -> 2458 bytes TMessagesProj/src/main/assets/emoji/3_237.png | Bin 2778 -> 2228 bytes TMessagesProj/src/main/assets/emoji/3_238.png | Bin 2740 -> 2890 bytes TMessagesProj/src/main/assets/emoji/3_239.png | Bin 2746 -> 2778 bytes TMessagesProj/src/main/assets/emoji/3_24.png | Bin 1667 -> 1739 bytes TMessagesProj/src/main/assets/emoji/3_240.png | Bin 2659 -> 2740 bytes TMessagesProj/src/main/assets/emoji/3_241.png | Bin 2477 -> 2747 bytes TMessagesProj/src/main/assets/emoji/3_242.png | Bin 4005 -> 2656 bytes TMessagesProj/src/main/assets/emoji/3_243.png | Bin 3830 -> 2478 bytes TMessagesProj/src/main/assets/emoji/3_244.png | Bin 3893 -> 4007 bytes TMessagesProj/src/main/assets/emoji/3_245.png | Bin 3890 -> 3822 bytes TMessagesProj/src/main/assets/emoji/3_246.png | Bin 3500 -> 3898 bytes TMessagesProj/src/main/assets/emoji/3_247.png | Bin 3705 -> 3892 bytes TMessagesProj/src/main/assets/emoji/3_248.png | Bin 3378 -> 3497 bytes TMessagesProj/src/main/assets/emoji/3_249.png | Bin 3191 -> 3704 bytes TMessagesProj/src/main/assets/emoji/3_25.png | Bin 1667 -> 1667 bytes TMessagesProj/src/main/assets/emoji/3_250.png | Bin 3222 -> 3376 bytes TMessagesProj/src/main/assets/emoji/3_251.png | Bin 3183 -> 3190 bytes TMessagesProj/src/main/assets/emoji/3_252.png | Bin 3175 -> 3222 bytes TMessagesProj/src/main/assets/emoji/3_253.png | Bin 2995 -> 3182 bytes TMessagesProj/src/main/assets/emoji/3_254.png | Bin 3765 -> 3175 bytes TMessagesProj/src/main/assets/emoji/3_255.png | Bin 3451 -> 2994 bytes TMessagesProj/src/main/assets/emoji/3_256.png | Bin 3504 -> 3764 bytes TMessagesProj/src/main/assets/emoji/3_257.png | Bin 3638 -> 3449 bytes TMessagesProj/src/main/assets/emoji/3_258.png | Bin 3565 -> 3505 bytes TMessagesProj/src/main/assets/emoji/3_259.png | Bin 3461 -> 3637 bytes TMessagesProj/src/main/assets/emoji/3_26.png | Bin 1133 -> 1671 bytes TMessagesProj/src/main/assets/emoji/3_260.png | Bin 3449 -> 3565 bytes TMessagesProj/src/main/assets/emoji/3_261.png | Bin 3445 -> 3461 bytes TMessagesProj/src/main/assets/emoji/3_262.png | Bin 3429 -> 3450 bytes TMessagesProj/src/main/assets/emoji/3_263.png | Bin 3463 -> 3444 bytes TMessagesProj/src/main/assets/emoji/3_264.png | Bin 3460 -> 3433 bytes TMessagesProj/src/main/assets/emoji/3_265.png | Bin 3257 -> 3464 bytes TMessagesProj/src/main/assets/emoji/3_266.png | Bin 3375 -> 3457 bytes TMessagesProj/src/main/assets/emoji/3_267.png | Bin 3086 -> 3261 bytes TMessagesProj/src/main/assets/emoji/3_268.png | Bin 3220 -> 3378 bytes TMessagesProj/src/main/assets/emoji/3_269.png | Bin 3028 -> 3085 bytes TMessagesProj/src/main/assets/emoji/3_27.png | Bin 2237 -> 1134 bytes TMessagesProj/src/main/assets/emoji/3_270.png | Bin 2999 -> 3220 bytes TMessagesProj/src/main/assets/emoji/3_271.png | Bin 2804 -> 3026 bytes TMessagesProj/src/main/assets/emoji/3_272.png | Bin 3411 -> 2997 bytes TMessagesProj/src/main/assets/emoji/3_273.png | Bin 3391 -> 2807 bytes TMessagesProj/src/main/assets/emoji/3_274.png | Bin 3390 -> 3411 bytes TMessagesProj/src/main/assets/emoji/3_275.png | Bin 3378 -> 3386 bytes TMessagesProj/src/main/assets/emoji/3_276.png | Bin 3415 -> 3389 bytes TMessagesProj/src/main/assets/emoji/3_277.png | Bin 3431 -> 3375 bytes TMessagesProj/src/main/assets/emoji/3_278.png | Bin 2214 -> 3415 bytes TMessagesProj/src/main/assets/emoji/3_279.png | Bin 1760 -> 3432 bytes TMessagesProj/src/main/assets/emoji/3_28.png | Bin 1529 -> 2858 bytes TMessagesProj/src/main/assets/emoji/3_280.png | Bin 1507 -> 2213 bytes TMessagesProj/src/main/assets/emoji/3_281.png | Bin 1752 -> 1759 bytes TMessagesProj/src/main/assets/emoji/3_282.png | Bin 2322 -> 1505 bytes TMessagesProj/src/main/assets/emoji/3_283.png | Bin 1411 -> 1751 bytes TMessagesProj/src/main/assets/emoji/3_284.png | Bin 3152 -> 2322 bytes TMessagesProj/src/main/assets/emoji/3_285.png | Bin 1032 -> 1411 bytes TMessagesProj/src/main/assets/emoji/3_286.png | Bin 1277 -> 3151 bytes TMessagesProj/src/main/assets/emoji/3_287.png | Bin 1126 -> 1031 bytes TMessagesProj/src/main/assets/emoji/3_288.png | Bin 2609 -> 1278 bytes TMessagesProj/src/main/assets/emoji/3_289.png | Bin 3012 -> 1125 bytes TMessagesProj/src/main/assets/emoji/3_29.png | Bin 1837 -> 2237 bytes TMessagesProj/src/main/assets/emoji/3_290.png | Bin 3031 -> 2608 bytes TMessagesProj/src/main/assets/emoji/3_291.png | Bin 3029 -> 3013 bytes TMessagesProj/src/main/assets/emoji/3_292.png | Bin 3007 -> 3030 bytes TMessagesProj/src/main/assets/emoji/3_293.png | Bin 2888 -> 3025 bytes TMessagesProj/src/main/assets/emoji/3_294.png | Bin 2705 -> 3005 bytes TMessagesProj/src/main/assets/emoji/3_295.png | Bin 3056 -> 2888 bytes TMessagesProj/src/main/assets/emoji/3_296.png | Bin 2966 -> 2706 bytes TMessagesProj/src/main/assets/emoji/3_297.png | Bin 3062 -> 3056 bytes TMessagesProj/src/main/assets/emoji/3_298.png | Bin 3055 -> 2965 bytes TMessagesProj/src/main/assets/emoji/3_299.png | Bin 2869 -> 3066 bytes TMessagesProj/src/main/assets/emoji/3_3.png | Bin 2110 -> 2110 bytes TMessagesProj/src/main/assets/emoji/3_30.png | Bin 3046 -> 1532 bytes TMessagesProj/src/main/assets/emoji/3_300.png | Bin 2717 -> 3057 bytes TMessagesProj/src/main/assets/emoji/3_301.png | Bin 2969 -> 2871 bytes TMessagesProj/src/main/assets/emoji/3_302.png | Bin 2976 -> 2718 bytes TMessagesProj/src/main/assets/emoji/3_303.png | Bin 2928 -> 2968 bytes TMessagesProj/src/main/assets/emoji/3_304.png | Bin 2994 -> 2975 bytes TMessagesProj/src/main/assets/emoji/3_305.png | Bin 2999 -> 2931 bytes TMessagesProj/src/main/assets/emoji/3_306.png | Bin 2831 -> 2993 bytes TMessagesProj/src/main/assets/emoji/3_307.png | Bin 3123 -> 2996 bytes TMessagesProj/src/main/assets/emoji/3_308.png | Bin 1735 -> 2831 bytes TMessagesProj/src/main/assets/emoji/3_309.png | Bin 2994 -> 3122 bytes TMessagesProj/src/main/assets/emoji/3_31.png | Bin 2573 -> 1837 bytes TMessagesProj/src/main/assets/emoji/3_310.png | Bin 1274 -> 1737 bytes TMessagesProj/src/main/assets/emoji/3_311.png | Bin 1235 -> 2994 bytes TMessagesProj/src/main/assets/emoji/3_312.png | Bin 1972 -> 1275 bytes TMessagesProj/src/main/assets/emoji/3_313.png | Bin 1246 -> 1235 bytes TMessagesProj/src/main/assets/emoji/3_314.png | Bin 928 -> 1974 bytes TMessagesProj/src/main/assets/emoji/3_315.png | Bin 2338 -> 1246 bytes TMessagesProj/src/main/assets/emoji/3_316.png | Bin 2205 -> 928 bytes TMessagesProj/src/main/assets/emoji/3_317.png | Bin 2846 -> 2339 bytes TMessagesProj/src/main/assets/emoji/3_318.png | Bin 2218 -> 1582 bytes TMessagesProj/src/main/assets/emoji/3_319.png | Bin 1358 -> 2204 bytes TMessagesProj/src/main/assets/emoji/3_32.png | Bin 2784 -> 3045 bytes TMessagesProj/src/main/assets/emoji/3_320.png | Bin 2947 -> 2846 bytes TMessagesProj/src/main/assets/emoji/3_321.png | Bin 1315 -> 1810 bytes TMessagesProj/src/main/assets/emoji/3_322.png | Bin 817 -> 2217 bytes TMessagesProj/src/main/assets/emoji/3_323.png | Bin 2206 -> 1358 bytes TMessagesProj/src/main/assets/emoji/3_324.png | Bin 2193 -> 2947 bytes TMessagesProj/src/main/assets/emoji/3_325.png | Bin 1667 -> 1317 bytes TMessagesProj/src/main/assets/emoji/3_326.png | Bin 2362 -> 817 bytes TMessagesProj/src/main/assets/emoji/3_327.png | Bin 1653 -> 2203 bytes TMessagesProj/src/main/assets/emoji/3_328.png | Bin 0 -> 2193 bytes TMessagesProj/src/main/assets/emoji/3_329.png | Bin 0 -> 1666 bytes TMessagesProj/src/main/assets/emoji/3_33.png | Bin 2509 -> 2573 bytes TMessagesProj/src/main/assets/emoji/3_330.png | Bin 0 -> 2362 bytes TMessagesProj/src/main/assets/emoji/3_331.png | Bin 0 -> 1652 bytes TMessagesProj/src/main/assets/emoji/3_34.png | Bin 2991 -> 2784 bytes TMessagesProj/src/main/assets/emoji/3_35.png | Bin 2997 -> 2506 bytes TMessagesProj/src/main/assets/emoji/3_36.png | Bin 2950 -> 2993 bytes TMessagesProj/src/main/assets/emoji/3_37.png | Bin 2893 -> 2998 bytes TMessagesProj/src/main/assets/emoji/3_38.png | Bin 2721 -> 2950 bytes TMessagesProj/src/main/assets/emoji/3_39.png | Bin 2492 -> 2894 bytes TMessagesProj/src/main/assets/emoji/3_4.png | Bin 2325 -> 2327 bytes TMessagesProj/src/main/assets/emoji/3_40.png | Bin 3046 -> 2723 bytes TMessagesProj/src/main/assets/emoji/3_41.png | Bin 2741 -> 2490 bytes TMessagesProj/src/main/assets/emoji/3_42.png | Bin 2694 -> 3043 bytes TMessagesProj/src/main/assets/emoji/3_43.png | Bin 2621 -> 2740 bytes TMessagesProj/src/main/assets/emoji/3_44.png | Bin 2644 -> 2693 bytes TMessagesProj/src/main/assets/emoji/3_45.png | Bin 2393 -> 2620 bytes TMessagesProj/src/main/assets/emoji/3_46.png | Bin 3016 -> 2645 bytes TMessagesProj/src/main/assets/emoji/3_47.png | Bin 2927 -> 2392 bytes TMessagesProj/src/main/assets/emoji/3_48.png | Bin 2962 -> 3016 bytes TMessagesProj/src/main/assets/emoji/3_49.png | Bin 2810 -> 2925 bytes TMessagesProj/src/main/assets/emoji/3_5.png | Bin 1720 -> 1719 bytes TMessagesProj/src/main/assets/emoji/3_50.png | Bin 2678 -> 2964 bytes TMessagesProj/src/main/assets/emoji/3_51.png | Bin 2637 -> 2812 bytes TMessagesProj/src/main/assets/emoji/3_52.png | Bin 3479 -> 2683 bytes TMessagesProj/src/main/assets/emoji/3_53.png | Bin 3452 -> 2633 bytes TMessagesProj/src/main/assets/emoji/3_54.png | Bin 3431 -> 3472 bytes TMessagesProj/src/main/assets/emoji/3_55.png | Bin 1898 -> 3448 bytes TMessagesProj/src/main/assets/emoji/3_56.png | Bin 1563 -> 3431 bytes TMessagesProj/src/main/assets/emoji/3_57.png | Bin 1628 -> 1898 bytes TMessagesProj/src/main/assets/emoji/3_58.png | Bin 1527 -> 1563 bytes TMessagesProj/src/main/assets/emoji/3_59.png | Bin 1551 -> 1627 bytes TMessagesProj/src/main/assets/emoji/3_6.png | Bin 1401 -> 1402 bytes TMessagesProj/src/main/assets/emoji/3_60.png | Bin 1402 -> 1526 bytes TMessagesProj/src/main/assets/emoji/3_61.png | Bin 1644 -> 1552 bytes TMessagesProj/src/main/assets/emoji/3_62.png | Bin 1407 -> 1401 bytes TMessagesProj/src/main/assets/emoji/3_63.png | Bin 1435 -> 1644 bytes TMessagesProj/src/main/assets/emoji/3_64.png | Bin 1449 -> 1407 bytes TMessagesProj/src/main/assets/emoji/3_65.png | Bin 1400 -> 1432 bytes TMessagesProj/src/main/assets/emoji/3_66.png | Bin 1227 -> 1449 bytes TMessagesProj/src/main/assets/emoji/3_67.png | Bin 1818 -> 1400 bytes TMessagesProj/src/main/assets/emoji/3_68.png | Bin 1560 -> 1229 bytes TMessagesProj/src/main/assets/emoji/3_69.png | Bin 1605 -> 1817 bytes TMessagesProj/src/main/assets/emoji/3_7.png | Bin 2061 -> 2068 bytes TMessagesProj/src/main/assets/emoji/3_70.png | Bin 1524 -> 1560 bytes TMessagesProj/src/main/assets/emoji/3_71.png | Bin 1552 -> 1600 bytes TMessagesProj/src/main/assets/emoji/3_72.png | Bin 1402 -> 1526 bytes TMessagesProj/src/main/assets/emoji/3_73.png | Bin 2874 -> 1552 bytes TMessagesProj/src/main/assets/emoji/3_74.png | Bin 2845 -> 1401 bytes TMessagesProj/src/main/assets/emoji/3_75.png | Bin 2833 -> 2875 bytes TMessagesProj/src/main/assets/emoji/3_76.png | Bin 2854 -> 2847 bytes TMessagesProj/src/main/assets/emoji/3_77.png | Bin 2632 -> 2833 bytes TMessagesProj/src/main/assets/emoji/3_78.png | Bin 2484 -> 2853 bytes TMessagesProj/src/main/assets/emoji/3_79.png | Bin 2818 -> 2633 bytes TMessagesProj/src/main/assets/emoji/3_8.png | Bin 1394 -> 1394 bytes TMessagesProj/src/main/assets/emoji/3_80.png | Bin 2533 -> 2484 bytes TMessagesProj/src/main/assets/emoji/3_81.png | Bin 2585 -> 2820 bytes TMessagesProj/src/main/assets/emoji/3_82.png | Bin 2389 -> 2533 bytes TMessagesProj/src/main/assets/emoji/3_83.png | Bin 2260 -> 2585 bytes TMessagesProj/src/main/assets/emoji/3_84.png | Bin 2055 -> 2390 bytes TMessagesProj/src/main/assets/emoji/3_85.png | Bin 2813 -> 2262 bytes TMessagesProj/src/main/assets/emoji/3_86.png | Bin 2781 -> 2057 bytes TMessagesProj/src/main/assets/emoji/3_87.png | Bin 2704 -> 2813 bytes TMessagesProj/src/main/assets/emoji/3_88.png | Bin 2723 -> 2782 bytes TMessagesProj/src/main/assets/emoji/3_89.png | Bin 2756 -> 2706 bytes TMessagesProj/src/main/assets/emoji/3_9.png | Bin 1392 -> 1392 bytes TMessagesProj/src/main/assets/emoji/3_90.png | Bin 2568 -> 2727 bytes TMessagesProj/src/main/assets/emoji/3_91.png | Bin 2272 -> 2753 bytes TMessagesProj/src/main/assets/emoji/3_92.png | Bin 2681 -> 2569 bytes TMessagesProj/src/main/assets/emoji/3_93.png | Bin 2679 -> 2272 bytes TMessagesProj/src/main/assets/emoji/3_94.png | Bin 2694 -> 2682 bytes TMessagesProj/src/main/assets/emoji/3_95.png | Bin 2678 -> 2676 bytes TMessagesProj/src/main/assets/emoji/3_96.png | Bin 2656 -> 2692 bytes TMessagesProj/src/main/assets/emoji/3_97.png | Bin 2662 -> 2677 bytes TMessagesProj/src/main/assets/emoji/3_98.png | Bin 2300 -> 2657 bytes TMessagesProj/src/main/assets/emoji/3_99.png | Bin 2165 -> 2661 bytes TMessagesProj/src/main/assets/emoji/4_0.png | Bin 2099 -> 2101 bytes TMessagesProj/src/main/assets/emoji/4_1.png | Bin 2572 -> 2568 bytes TMessagesProj/src/main/assets/emoji/4_10.png | Bin 1836 -> 1532 bytes TMessagesProj/src/main/assets/emoji/4_100.png | Bin 1769 -> 1855 bytes TMessagesProj/src/main/assets/emoji/4_101.png | Bin 1512 -> 1904 bytes TMessagesProj/src/main/assets/emoji/4_102.png | Bin 1927 -> 2721 bytes TMessagesProj/src/main/assets/emoji/4_103.png | Bin 2266 -> 1770 bytes TMessagesProj/src/main/assets/emoji/4_104.png | Bin 2089 -> 1512 bytes TMessagesProj/src/main/assets/emoji/4_105.png | Bin 1336 -> 1927 bytes TMessagesProj/src/main/assets/emoji/4_106.png | Bin 984 -> 2267 bytes TMessagesProj/src/main/assets/emoji/4_107.png | Bin 1093 -> 2090 bytes TMessagesProj/src/main/assets/emoji/4_108.png | Bin 2783 -> 1334 bytes TMessagesProj/src/main/assets/emoji/4_109.png | Bin 1803 -> 987 bytes TMessagesProj/src/main/assets/emoji/4_11.png | Bin 1827 -> 1834 bytes TMessagesProj/src/main/assets/emoji/4_110.png | Bin 853 -> 1093 bytes TMessagesProj/src/main/assets/emoji/4_111.png | Bin 2427 -> 2781 bytes TMessagesProj/src/main/assets/emoji/4_112.png | Bin 1879 -> 1801 bytes TMessagesProj/src/main/assets/emoji/4_113.png | Bin 1417 -> 853 bytes TMessagesProj/src/main/assets/emoji/4_114.png | Bin 1545 -> 2425 bytes TMessagesProj/src/main/assets/emoji/4_115.png | Bin 1663 -> 1877 bytes TMessagesProj/src/main/assets/emoji/4_116.png | Bin 2035 -> 1417 bytes TMessagesProj/src/main/assets/emoji/4_117.png | Bin 2000 -> 1541 bytes TMessagesProj/src/main/assets/emoji/4_118.png | Bin 1726 -> 1663 bytes TMessagesProj/src/main/assets/emoji/4_119.png | Bin 1620 -> 2035 bytes TMessagesProj/src/main/assets/emoji/4_12.png | Bin 2371 -> 1828 bytes TMessagesProj/src/main/assets/emoji/4_120.png | Bin 1214 -> 2000 bytes TMessagesProj/src/main/assets/emoji/4_121.png | Bin 1758 -> 1727 bytes TMessagesProj/src/main/assets/emoji/4_122.png | Bin 1349 -> 1622 bytes TMessagesProj/src/main/assets/emoji/4_123.png | Bin 1658 -> 1215 bytes TMessagesProj/src/main/assets/emoji/4_124.png | Bin 1177 -> 1759 bytes TMessagesProj/src/main/assets/emoji/4_125.png | Bin 0 -> 1347 bytes TMessagesProj/src/main/assets/emoji/4_126.png | Bin 0 -> 1658 bytes TMessagesProj/src/main/assets/emoji/4_127.png | Bin 0 -> 1176 bytes TMessagesProj/src/main/assets/emoji/4_13.png | Bin 658 -> 2368 bytes TMessagesProj/src/main/assets/emoji/4_14.png | Bin 1285 -> 658 bytes TMessagesProj/src/main/assets/emoji/4_15.png | Bin 1462 -> 1283 bytes TMessagesProj/src/main/assets/emoji/4_16.png | Bin 1393 -> 1462 bytes TMessagesProj/src/main/assets/emoji/4_17.png | Bin 2231 -> 1394 bytes TMessagesProj/src/main/assets/emoji/4_18.png | Bin 2867 -> 2229 bytes TMessagesProj/src/main/assets/emoji/4_19.png | Bin 1982 -> 2870 bytes TMessagesProj/src/main/assets/emoji/4_2.png | Bin 2096 -> 2095 bytes TMessagesProj/src/main/assets/emoji/4_20.png | Bin 2923 -> 1982 bytes TMessagesProj/src/main/assets/emoji/4_21.png | Bin 2307 -> 2923 bytes TMessagesProj/src/main/assets/emoji/4_22.png | Bin 1930 -> 2306 bytes TMessagesProj/src/main/assets/emoji/4_23.png | Bin 1739 -> 1928 bytes TMessagesProj/src/main/assets/emoji/4_24.png | Bin 2029 -> 1739 bytes TMessagesProj/src/main/assets/emoji/4_25.png | Bin 2033 -> 2028 bytes TMessagesProj/src/main/assets/emoji/4_26.png | Bin 1402 -> 2034 bytes TMessagesProj/src/main/assets/emoji/4_27.png | Bin 1952 -> 1403 bytes TMessagesProj/src/main/assets/emoji/4_28.png | Bin 1923 -> 1955 bytes TMessagesProj/src/main/assets/emoji/4_29.png | Bin 1788 -> 1920 bytes TMessagesProj/src/main/assets/emoji/4_3.png | Bin 2014 -> 2013 bytes TMessagesProj/src/main/assets/emoji/4_30.png | Bin 1574 -> 1787 bytes TMessagesProj/src/main/assets/emoji/4_31.png | Bin 2493 -> 1574 bytes TMessagesProj/src/main/assets/emoji/4_32.png | Bin 1442 -> 2493 bytes TMessagesProj/src/main/assets/emoji/4_33.png | Bin 1764 -> 1444 bytes TMessagesProj/src/main/assets/emoji/4_34.png | Bin 1660 -> 1766 bytes TMessagesProj/src/main/assets/emoji/4_35.png | Bin 1305 -> 1657 bytes TMessagesProj/src/main/assets/emoji/4_36.png | Bin 2940 -> 1305 bytes TMessagesProj/src/main/assets/emoji/4_37.png | Bin 1958 -> 2939 bytes TMessagesProj/src/main/assets/emoji/4_38.png | Bin 1869 -> 1956 bytes TMessagesProj/src/main/assets/emoji/4_39.png | Bin 1635 -> 1866 bytes TMessagesProj/src/main/assets/emoji/4_4.png | Bin 2362 -> 2362 bytes TMessagesProj/src/main/assets/emoji/4_40.png | Bin 1723 -> 1635 bytes TMessagesProj/src/main/assets/emoji/4_41.png | Bin 2210 -> 1726 bytes TMessagesProj/src/main/assets/emoji/4_42.png | Bin 1560 -> 2211 bytes TMessagesProj/src/main/assets/emoji/4_43.png | Bin 1873 -> 1558 bytes TMessagesProj/src/main/assets/emoji/4_44.png | Bin 2065 -> 1871 bytes TMessagesProj/src/main/assets/emoji/4_45.png | Bin 1978 -> 2064 bytes TMessagesProj/src/main/assets/emoji/4_46.png | Bin 3104 -> 1978 bytes TMessagesProj/src/main/assets/emoji/4_47.png | Bin 2883 -> 3104 bytes TMessagesProj/src/main/assets/emoji/4_48.png | Bin 1248 -> 2883 bytes TMessagesProj/src/main/assets/emoji/4_49.png | Bin 2681 -> 1248 bytes TMessagesProj/src/main/assets/emoji/4_5.png | Bin 2288 -> 2291 bytes TMessagesProj/src/main/assets/emoji/4_50.png | Bin 1685 -> 2684 bytes TMessagesProj/src/main/assets/emoji/4_51.png | Bin 2032 -> 1685 bytes TMessagesProj/src/main/assets/emoji/4_52.png | Bin 1637 -> 2032 bytes TMessagesProj/src/main/assets/emoji/4_53.png | Bin 1878 -> 1637 bytes TMessagesProj/src/main/assets/emoji/4_54.png | Bin 1934 -> 1879 bytes TMessagesProj/src/main/assets/emoji/4_55.png | Bin 1892 -> 1935 bytes TMessagesProj/src/main/assets/emoji/4_56.png | Bin 1948 -> 1893 bytes TMessagesProj/src/main/assets/emoji/4_57.png | Bin 1245 -> 1947 bytes TMessagesProj/src/main/assets/emoji/4_58.png | Bin 2021 -> 1245 bytes TMessagesProj/src/main/assets/emoji/4_59.png | Bin 1892 -> 1304 bytes TMessagesProj/src/main/assets/emoji/4_6.png | Bin 1757 -> 1758 bytes TMessagesProj/src/main/assets/emoji/4_60.png | Bin 1475 -> 2021 bytes TMessagesProj/src/main/assets/emoji/4_61.png | Bin 1499 -> 1892 bytes TMessagesProj/src/main/assets/emoji/4_62.png | Bin 1575 -> 1474 bytes TMessagesProj/src/main/assets/emoji/4_63.png | Bin 3508 -> 1500 bytes TMessagesProj/src/main/assets/emoji/4_64.png | Bin 1439 -> 1575 bytes TMessagesProj/src/main/assets/emoji/4_65.png | Bin 1788 -> 3508 bytes TMessagesProj/src/main/assets/emoji/4_66.png | Bin 2052 -> 1438 bytes TMessagesProj/src/main/assets/emoji/4_67.png | Bin 2739 -> 1788 bytes TMessagesProj/src/main/assets/emoji/4_68.png | Bin 1814 -> 2054 bytes TMessagesProj/src/main/assets/emoji/4_69.png | Bin 3359 -> 2738 bytes TMessagesProj/src/main/assets/emoji/4_7.png | Bin 2251 -> 2254 bytes TMessagesProj/src/main/assets/emoji/4_70.png | Bin 3369 -> 1815 bytes TMessagesProj/src/main/assets/emoji/4_71.png | Bin 2577 -> 3358 bytes TMessagesProj/src/main/assets/emoji/4_72.png | Bin 3363 -> 3369 bytes TMessagesProj/src/main/assets/emoji/4_73.png | Bin 2836 -> 2578 bytes TMessagesProj/src/main/assets/emoji/4_74.png | Bin 1558 -> 3365 bytes TMessagesProj/src/main/assets/emoji/4_75.png | Bin 2774 -> 2838 bytes TMessagesProj/src/main/assets/emoji/4_76.png | Bin 2702 -> 1561 bytes TMessagesProj/src/main/assets/emoji/4_77.png | Bin 2599 -> 2773 bytes TMessagesProj/src/main/assets/emoji/4_78.png | Bin 2832 -> 2704 bytes TMessagesProj/src/main/assets/emoji/4_79.png | Bin 2321 -> 2602 bytes TMessagesProj/src/main/assets/emoji/4_8.png | Bin 2363 -> 2360 bytes TMessagesProj/src/main/assets/emoji/4_80.png | Bin 2357 -> 2832 bytes TMessagesProj/src/main/assets/emoji/4_81.png | Bin 1255 -> 2322 bytes TMessagesProj/src/main/assets/emoji/4_82.png | Bin 2254 -> 2357 bytes TMessagesProj/src/main/assets/emoji/4_83.png | Bin 1585 -> 1256 bytes TMessagesProj/src/main/assets/emoji/4_84.png | Bin 1927 -> 2254 bytes TMessagesProj/src/main/assets/emoji/4_85.png | Bin 2499 -> 1585 bytes TMessagesProj/src/main/assets/emoji/4_86.png | Bin 2447 -> 1267 bytes TMessagesProj/src/main/assets/emoji/4_87.png | Bin 2228 -> 1927 bytes TMessagesProj/src/main/assets/emoji/4_88.png | Bin 2648 -> 2498 bytes TMessagesProj/src/main/assets/emoji/4_89.png | Bin 2415 -> 2447 bytes TMessagesProj/src/main/assets/emoji/4_9.png | Bin 1934 -> 1938 bytes TMessagesProj/src/main/assets/emoji/4_90.png | Bin 1816 -> 2227 bytes TMessagesProj/src/main/assets/emoji/4_91.png | Bin 1789 -> 2649 bytes TMessagesProj/src/main/assets/emoji/4_92.png | Bin 2042 -> 2414 bytes TMessagesProj/src/main/assets/emoji/4_93.png | Bin 2148 -> 1817 bytes TMessagesProj/src/main/assets/emoji/4_94.png | Bin 1438 -> 1791 bytes TMessagesProj/src/main/assets/emoji/4_95.png | Bin 1911 -> 2043 bytes TMessagesProj/src/main/assets/emoji/4_96.png | Bin 2466 -> 2143 bytes TMessagesProj/src/main/assets/emoji/4_97.png | Bin 1852 -> 1439 bytes TMessagesProj/src/main/assets/emoji/4_98.png | Bin 1904 -> 1913 bytes TMessagesProj/src/main/assets/emoji/4_99.png | Bin 2724 -> 2466 bytes TMessagesProj/src/main/assets/emoji/5_0.png | Bin 1137 -> 1137 bytes TMessagesProj/src/main/assets/emoji/5_1.png | Bin 1288 -> 1290 bytes TMessagesProj/src/main/assets/emoji/5_10.png | Bin 1620 -> 1618 bytes TMessagesProj/src/main/assets/emoji/5_100.png | Bin 923 -> 1506 bytes TMessagesProj/src/main/assets/emoji/5_101.png | Bin 2231 -> 2071 bytes TMessagesProj/src/main/assets/emoji/5_102.png | Bin 1654 -> 1627 bytes TMessagesProj/src/main/assets/emoji/5_103.png | Bin 2283 -> 877 bytes TMessagesProj/src/main/assets/emoji/5_104.png | Bin 1988 -> 937 bytes TMessagesProj/src/main/assets/emoji/5_105.png | Bin 1922 -> 2157 bytes TMessagesProj/src/main/assets/emoji/5_106.png | Bin 2004 -> 1195 bytes TMessagesProj/src/main/assets/emoji/5_107.png | Bin 1949 -> 923 bytes TMessagesProj/src/main/assets/emoji/5_108.png | Bin 1927 -> 2231 bytes TMessagesProj/src/main/assets/emoji/5_109.png | Bin 1964 -> 1653 bytes TMessagesProj/src/main/assets/emoji/5_11.png | Bin 1888 -> 1887 bytes TMessagesProj/src/main/assets/emoji/5_110.png | Bin 1943 -> 2284 bytes TMessagesProj/src/main/assets/emoji/5_111.png | Bin 1263 -> 1987 bytes TMessagesProj/src/main/assets/emoji/5_112.png | Bin 1762 -> 1921 bytes TMessagesProj/src/main/assets/emoji/5_113.png | Bin 883 -> 2005 bytes TMessagesProj/src/main/assets/emoji/5_114.png | Bin 1801 -> 1949 bytes TMessagesProj/src/main/assets/emoji/5_115.png | Bin 1395 -> 1928 bytes TMessagesProj/src/main/assets/emoji/5_116.png | Bin 1247 -> 1965 bytes TMessagesProj/src/main/assets/emoji/5_117.png | Bin 593 -> 1942 bytes TMessagesProj/src/main/assets/emoji/5_118.png | Bin 927 -> 833 bytes TMessagesProj/src/main/assets/emoji/5_119.png | Bin 1522 -> 1263 bytes TMessagesProj/src/main/assets/emoji/5_120.png | Bin 969 -> 1762 bytes TMessagesProj/src/main/assets/emoji/5_121.png | Bin 1256 -> 2040 bytes TMessagesProj/src/main/assets/emoji/5_122.png | Bin 2117 -> 883 bytes TMessagesProj/src/main/assets/emoji/5_123.png | Bin 1972 -> 1800 bytes TMessagesProj/src/main/assets/emoji/5_124.png | Bin 3308 -> 1394 bytes TMessagesProj/src/main/assets/emoji/5_125.png | Bin 2259 -> 1249 bytes TMessagesProj/src/main/assets/emoji/5_126.png | Bin 1812 -> 593 bytes TMessagesProj/src/main/assets/emoji/5_127.png | Bin 1154 -> 928 bytes TMessagesProj/src/main/assets/emoji/5_128.png | Bin 3167 -> 1522 bytes TMessagesProj/src/main/assets/emoji/5_129.png | Bin 1768 -> 969 bytes TMessagesProj/src/main/assets/emoji/5_13.png | Bin 1855 -> 1856 bytes TMessagesProj/src/main/assets/emoji/5_130.png | Bin 3331 -> 1256 bytes TMessagesProj/src/main/assets/emoji/5_131.png | Bin 3265 -> 2118 bytes TMessagesProj/src/main/assets/emoji/5_132.png | Bin 3338 -> 2812 bytes TMessagesProj/src/main/assets/emoji/5_133.png | Bin 1285 -> 1973 bytes TMessagesProj/src/main/assets/emoji/5_134.png | Bin 1675 -> 870 bytes TMessagesProj/src/main/assets/emoji/5_135.png | Bin 1016 -> 690 bytes TMessagesProj/src/main/assets/emoji/5_136.png | Bin 709 -> 3307 bytes TMessagesProj/src/main/assets/emoji/5_137.png | Bin 894 -> 2259 bytes TMessagesProj/src/main/assets/emoji/5_138.png | Bin 1452 -> 1813 bytes TMessagesProj/src/main/assets/emoji/5_139.png | Bin 927 -> 1153 bytes TMessagesProj/src/main/assets/emoji/5_14.png | Bin 1909 -> 1908 bytes TMessagesProj/src/main/assets/emoji/5_140.png | Bin 923 -> 3165 bytes TMessagesProj/src/main/assets/emoji/5_141.png | Bin 1067 -> 1771 bytes TMessagesProj/src/main/assets/emoji/5_142.png | Bin 1109 -> 868 bytes TMessagesProj/src/main/assets/emoji/5_143.png | Bin 1186 -> 7626 bytes TMessagesProj/src/main/assets/emoji/5_144.png | Bin 555 -> 3334 bytes TMessagesProj/src/main/assets/emoji/5_145.png | Bin 1404 -> 3262 bytes TMessagesProj/src/main/assets/emoji/5_146.png | Bin 1530 -> 3338 bytes TMessagesProj/src/main/assets/emoji/5_147.png | Bin 1890 -> 1287 bytes TMessagesProj/src/main/assets/emoji/5_148.png | Bin 1457 -> 1675 bytes TMessagesProj/src/main/assets/emoji/5_149.png | Bin 1250 -> 1021 bytes TMessagesProj/src/main/assets/emoji/5_15.png | Bin 1015 -> 1018 bytes TMessagesProj/src/main/assets/emoji/5_150.png | Bin 2552 -> 708 bytes TMessagesProj/src/main/assets/emoji/5_151.png | Bin 1809 -> 896 bytes TMessagesProj/src/main/assets/emoji/5_152.png | Bin 845 -> 1452 bytes TMessagesProj/src/main/assets/emoji/5_153.png | Bin 932 -> 926 bytes TMessagesProj/src/main/assets/emoji/5_154.png | Bin 1163 -> 921 bytes TMessagesProj/src/main/assets/emoji/5_155.png | Bin 1213 -> 1067 bytes TMessagesProj/src/main/assets/emoji/5_156.png | Bin 1184 -> 1109 bytes TMessagesProj/src/main/assets/emoji/5_157.png | Bin 1207 -> 1185 bytes TMessagesProj/src/main/assets/emoji/5_158.png | Bin 1130 -> 555 bytes TMessagesProj/src/main/assets/emoji/5_159.png | Bin 1572 -> 560 bytes TMessagesProj/src/main/assets/emoji/5_16.png | Bin 1552 -> 1552 bytes TMessagesProj/src/main/assets/emoji/5_160.png | Bin 1694 -> 1406 bytes TMessagesProj/src/main/assets/emoji/5_161.png | Bin 1231 -> 1530 bytes TMessagesProj/src/main/assets/emoji/5_162.png | Bin 801 -> 1891 bytes TMessagesProj/src/main/assets/emoji/5_163.png | Bin 3904 -> 1459 bytes TMessagesProj/src/main/assets/emoji/5_164.png | Bin 1665 -> 1254 bytes TMessagesProj/src/main/assets/emoji/5_165.png | Bin 1193 -> 2549 bytes TMessagesProj/src/main/assets/emoji/5_166.png | Bin 1340 -> 1813 bytes TMessagesProj/src/main/assets/emoji/5_167.png | Bin 764 -> 845 bytes TMessagesProj/src/main/assets/emoji/5_168.png | Bin 1032 -> 932 bytes TMessagesProj/src/main/assets/emoji/5_169.png | Bin 1094 -> 1158 bytes TMessagesProj/src/main/assets/emoji/5_17.png | Bin 2197 -> 2199 bytes TMessagesProj/src/main/assets/emoji/5_170.png | Bin 1041 -> 1211 bytes TMessagesProj/src/main/assets/emoji/5_171.png | Bin 706 -> 1183 bytes TMessagesProj/src/main/assets/emoji/5_172.png | Bin 1726 -> 1205 bytes TMessagesProj/src/main/assets/emoji/5_173.png | Bin 1600 -> 1129 bytes TMessagesProj/src/main/assets/emoji/5_174.png | Bin 1868 -> 1572 bytes TMessagesProj/src/main/assets/emoji/5_175.png | Bin 1324 -> 1694 bytes TMessagesProj/src/main/assets/emoji/5_176.png | Bin 1899 -> 1230 bytes TMessagesProj/src/main/assets/emoji/5_177.png | Bin 1286 -> 803 bytes TMessagesProj/src/main/assets/emoji/5_178.png | Bin 1168 -> 3904 bytes TMessagesProj/src/main/assets/emoji/5_179.png | Bin 1228 -> 1665 bytes TMessagesProj/src/main/assets/emoji/5_18.png | Bin 1601 -> 1605 bytes TMessagesProj/src/main/assets/emoji/5_180.png | Bin 1355 -> 1193 bytes TMessagesProj/src/main/assets/emoji/5_181.png | Bin 2200 -> 1342 bytes TMessagesProj/src/main/assets/emoji/5_182.png | Bin 1727 -> 765 bytes TMessagesProj/src/main/assets/emoji/5_183.png | Bin 1176 -> 1032 bytes TMessagesProj/src/main/assets/emoji/5_184.png | Bin 1701 -> 1094 bytes TMessagesProj/src/main/assets/emoji/5_185.png | Bin 2145 -> 1041 bytes TMessagesProj/src/main/assets/emoji/5_186.png | Bin 2088 -> 705 bytes TMessagesProj/src/main/assets/emoji/5_187.png | Bin 2685 -> 1727 bytes TMessagesProj/src/main/assets/emoji/5_188.png | Bin 686 -> 1604 bytes TMessagesProj/src/main/assets/emoji/5_189.png | Bin 623 -> 1867 bytes TMessagesProj/src/main/assets/emoji/5_19.png | Bin 1938 -> 1936 bytes TMessagesProj/src/main/assets/emoji/5_190.png | Bin 2745 -> 1324 bytes TMessagesProj/src/main/assets/emoji/5_191.png | Bin 1820 -> 1901 bytes TMessagesProj/src/main/assets/emoji/5_192.png | Bin 1271 -> 1287 bytes TMessagesProj/src/main/assets/emoji/5_193.png | Bin 2540 -> 1167 bytes TMessagesProj/src/main/assets/emoji/5_194.png | Bin 1075 -> 1229 bytes TMessagesProj/src/main/assets/emoji/5_195.png | Bin 1280 -> 1353 bytes TMessagesProj/src/main/assets/emoji/5_196.png | Bin 1221 -> 2198 bytes TMessagesProj/src/main/assets/emoji/5_197.png | Bin 1711 -> 1727 bytes TMessagesProj/src/main/assets/emoji/5_198.png | Bin 1110 -> 1175 bytes TMessagesProj/src/main/assets/emoji/5_199.png | Bin 1846 -> 1701 bytes TMessagesProj/src/main/assets/emoji/5_2.png | Bin 1489 -> 1485 bytes TMessagesProj/src/main/assets/emoji/5_20.png | Bin 2041 -> 2040 bytes TMessagesProj/src/main/assets/emoji/5_200.png | Bin 1329 -> 2145 bytes TMessagesProj/src/main/assets/emoji/5_201.png | Bin 1503 -> 2088 bytes TMessagesProj/src/main/assets/emoji/5_202.png | Bin 1725 -> 2684 bytes TMessagesProj/src/main/assets/emoji/5_203.png | Bin 2027 -> 686 bytes TMessagesProj/src/main/assets/emoji/5_204.png | Bin 1755 -> 620 bytes TMessagesProj/src/main/assets/emoji/5_205.png | Bin 1085 -> 2743 bytes TMessagesProj/src/main/assets/emoji/5_206.png | Bin 1188 -> 1818 bytes TMessagesProj/src/main/assets/emoji/5_207.png | Bin 0 -> 1269 bytes TMessagesProj/src/main/assets/emoji/5_208.png | Bin 0 -> 2540 bytes TMessagesProj/src/main/assets/emoji/5_209.png | Bin 0 -> 1077 bytes TMessagesProj/src/main/assets/emoji/5_210.png | Bin 0 -> 1280 bytes TMessagesProj/src/main/assets/emoji/5_211.png | Bin 0 -> 1218 bytes TMessagesProj/src/main/assets/emoji/5_212.png | Bin 0 -> 1710 bytes TMessagesProj/src/main/assets/emoji/5_213.png | Bin 0 -> 1111 bytes TMessagesProj/src/main/assets/emoji/5_214.png | Bin 0 -> 1846 bytes TMessagesProj/src/main/assets/emoji/5_215.png | Bin 0 -> 1327 bytes TMessagesProj/src/main/assets/emoji/5_216.png | Bin 0 -> 1503 bytes TMessagesProj/src/main/assets/emoji/5_217.png | Bin 0 -> 1725 bytes TMessagesProj/src/main/assets/emoji/5_218.png | Bin 0 -> 2028 bytes TMessagesProj/src/main/assets/emoji/5_219.png | Bin 0 -> 1758 bytes TMessagesProj/src/main/assets/emoji/5_22.png | Bin 923 -> 923 bytes TMessagesProj/src/main/assets/emoji/5_220.png | Bin 0 -> 1088 bytes TMessagesProj/src/main/assets/emoji/5_221.png | Bin 0 -> 1185 bytes TMessagesProj/src/main/assets/emoji/5_23.png | Bin 2151 -> 2148 bytes TMessagesProj/src/main/assets/emoji/5_24.png | Bin 1288 -> 1290 bytes TMessagesProj/src/main/assets/emoji/5_25.png | Bin 946 -> 948 bytes TMessagesProj/src/main/assets/emoji/5_26.png | Bin 1870 -> 1874 bytes TMessagesProj/src/main/assets/emoji/5_27.png | Bin 1437 -> 1436 bytes TMessagesProj/src/main/assets/emoji/5_28.png | Bin 2232 -> 2233 bytes TMessagesProj/src/main/assets/emoji/5_29.png | Bin 943 -> 942 bytes TMessagesProj/src/main/assets/emoji/5_3.png | Bin 983 -> 987 bytes TMessagesProj/src/main/assets/emoji/5_30.png | Bin 1711 -> 1712 bytes TMessagesProj/src/main/assets/emoji/5_31.png | Bin 2046 -> 2046 bytes TMessagesProj/src/main/assets/emoji/5_32.png | Bin 2278 -> 2277 bytes TMessagesProj/src/main/assets/emoji/5_33.png | Bin 1623 -> 1632 bytes TMessagesProj/src/main/assets/emoji/5_34.png | Bin 2948 -> 2949 bytes TMessagesProj/src/main/assets/emoji/5_35.png | Bin 1952 -> 1952 bytes TMessagesProj/src/main/assets/emoji/5_36.png | Bin 2200 -> 2201 bytes TMessagesProj/src/main/assets/emoji/5_37.png | Bin 2268 -> 2266 bytes TMessagesProj/src/main/assets/emoji/5_38.png | Bin 1971 -> 1972 bytes TMessagesProj/src/main/assets/emoji/5_39.png | Bin 1661 -> 1661 bytes TMessagesProj/src/main/assets/emoji/5_4.png | Bin 730 -> 728 bytes TMessagesProj/src/main/assets/emoji/5_40.png | Bin 1115 -> 1113 bytes TMessagesProj/src/main/assets/emoji/5_41.png | Bin 895 -> 896 bytes TMessagesProj/src/main/assets/emoji/5_42.png | Bin 1195 -> 1193 bytes TMessagesProj/src/main/assets/emoji/5_43.png | Bin 1726 -> 1726 bytes TMessagesProj/src/main/assets/emoji/5_44.png | Bin 1803 -> 1801 bytes TMessagesProj/src/main/assets/emoji/5_45.png | Bin 2660 -> 2660 bytes TMessagesProj/src/main/assets/emoji/5_46.png | Bin 1565 -> 1567 bytes TMessagesProj/src/main/assets/emoji/5_47.png | Bin 2522 -> 2519 bytes TMessagesProj/src/main/assets/emoji/5_48.png | Bin 1614 -> 1614 bytes TMessagesProj/src/main/assets/emoji/5_49.png | Bin 1712 -> 1714 bytes TMessagesProj/src/main/assets/emoji/5_5.png | Bin 807 -> 811 bytes TMessagesProj/src/main/assets/emoji/5_50.png | Bin 1766 -> 1765 bytes TMessagesProj/src/main/assets/emoji/5_51.png | Bin 1588 -> 1586 bytes TMessagesProj/src/main/assets/emoji/5_52.png | Bin 1612 -> 2048 bytes TMessagesProj/src/main/assets/emoji/5_53.png | Bin 1108 -> 1613 bytes TMessagesProj/src/main/assets/emoji/5_54.png | Bin 2033 -> 1107 bytes TMessagesProj/src/main/assets/emoji/5_55.png | Bin 1945 -> 2034 bytes TMessagesProj/src/main/assets/emoji/5_56.png | Bin 1097 -> 1945 bytes TMessagesProj/src/main/assets/emoji/5_57.png | Bin 1109 -> 2071 bytes TMessagesProj/src/main/assets/emoji/5_58.png | Bin 1047 -> 1096 bytes TMessagesProj/src/main/assets/emoji/5_59.png | Bin 1344 -> 1137 bytes TMessagesProj/src/main/assets/emoji/5_60.png | Bin 2010 -> 1111 bytes TMessagesProj/src/main/assets/emoji/5_61.png | Bin 925 -> 1048 bytes TMessagesProj/src/main/assets/emoji/5_62.png | Bin 1561 -> 1344 bytes TMessagesProj/src/main/assets/emoji/5_63.png | Bin 2283 -> 2011 bytes TMessagesProj/src/main/assets/emoji/5_64.png | Bin 1371 -> 924 bytes TMessagesProj/src/main/assets/emoji/5_65.png | Bin 2732 -> 1140 bytes TMessagesProj/src/main/assets/emoji/5_66.png | Bin 1498 -> 1561 bytes TMessagesProj/src/main/assets/emoji/5_67.png | Bin 1805 -> 2281 bytes TMessagesProj/src/main/assets/emoji/5_68.png | Bin 1825 -> 1742 bytes TMessagesProj/src/main/assets/emoji/5_69.png | Bin 2099 -> 1380 bytes TMessagesProj/src/main/assets/emoji/5_7.png | Bin 622 -> 622 bytes TMessagesProj/src/main/assets/emoji/5_70.png | Bin 1085 -> 2733 bytes TMessagesProj/src/main/assets/emoji/5_71.png | Bin 942 -> 1496 bytes TMessagesProj/src/main/assets/emoji/5_72.png | Bin 963 -> 1805 bytes TMessagesProj/src/main/assets/emoji/5_73.png | Bin 1501 -> 1824 bytes TMessagesProj/src/main/assets/emoji/5_74.png | Bin 1296 -> 2097 bytes TMessagesProj/src/main/assets/emoji/5_75.png | Bin 1220 -> 1084 bytes TMessagesProj/src/main/assets/emoji/5_76.png | Bin 1542 -> 942 bytes TMessagesProj/src/main/assets/emoji/5_77.png | Bin 1581 -> 962 bytes TMessagesProj/src/main/assets/emoji/5_78.png | Bin 2179 -> 1501 bytes TMessagesProj/src/main/assets/emoji/5_79.png | Bin 2515 -> 1295 bytes TMessagesProj/src/main/assets/emoji/5_8.png | Bin 1505 -> 1505 bytes TMessagesProj/src/main/assets/emoji/5_80.png | Bin 2266 -> 1220 bytes TMessagesProj/src/main/assets/emoji/5_81.png | Bin 2156 -> 1541 bytes TMessagesProj/src/main/assets/emoji/5_82.png | Bin 1770 -> 1013 bytes TMessagesProj/src/main/assets/emoji/5_83.png | Bin 2112 -> 1578 bytes TMessagesProj/src/main/assets/emoji/5_84.png | Bin 1717 -> 2181 bytes TMessagesProj/src/main/assets/emoji/5_85.png | Bin 2024 -> 2509 bytes TMessagesProj/src/main/assets/emoji/5_86.png | Bin 596 -> 2266 bytes TMessagesProj/src/main/assets/emoji/5_87.png | Bin 978 -> 2156 bytes TMessagesProj/src/main/assets/emoji/5_88.png | Bin 1661 -> 1770 bytes TMessagesProj/src/main/assets/emoji/5_89.png | Bin 1729 -> 2115 bytes TMessagesProj/src/main/assets/emoji/5_9.png | Bin 1155 -> 1153 bytes TMessagesProj/src/main/assets/emoji/5_90.png | Bin 1469 -> 1722 bytes TMessagesProj/src/main/assets/emoji/5_91.png | Bin 876 -> 2023 bytes TMessagesProj/src/main/assets/emoji/5_92.png | Bin 2881 -> 596 bytes TMessagesProj/src/main/assets/emoji/5_93.png | Bin 2512 -> 978 bytes TMessagesProj/src/main/assets/emoji/5_94.png | Bin 1506 -> 1662 bytes TMessagesProj/src/main/assets/emoji/5_95.png | Bin 2071 -> 1726 bytes TMessagesProj/src/main/assets/emoji/5_96.png | Bin 1628 -> 1469 bytes TMessagesProj/src/main/assets/emoji/5_97.png | Bin 877 -> 876 bytes TMessagesProj/src/main/assets/emoji/5_98.png | Bin 2157 -> 2881 bytes TMessagesProj/src/main/assets/emoji/5_99.png | Bin 1194 -> 2514 bytes TMessagesProj/src/main/assets/emoji/6_0.png | Bin 1069 -> 1069 bytes TMessagesProj/src/main/assets/emoji/6_10.png | Bin 872 -> 873 bytes TMessagesProj/src/main/assets/emoji/6_100.png | Bin 984 -> 983 bytes TMessagesProj/src/main/assets/emoji/6_101.png | Bin 1194 -> 1192 bytes TMessagesProj/src/main/assets/emoji/6_103.png | Bin 1113 -> 1114 bytes TMessagesProj/src/main/assets/emoji/6_104.png | Bin 1234 -> 1232 bytes TMessagesProj/src/main/assets/emoji/6_107.png | Bin 826 -> 829 bytes TMessagesProj/src/main/assets/emoji/6_109.png | Bin 2389 -> 2387 bytes TMessagesProj/src/main/assets/emoji/6_11.png | Bin 947 -> 950 bytes TMessagesProj/src/main/assets/emoji/6_110.png | Bin 1099 -> 1099 bytes TMessagesProj/src/main/assets/emoji/6_111.png | Bin 1127 -> 1129 bytes TMessagesProj/src/main/assets/emoji/6_112.png | Bin 487 -> 486 bytes TMessagesProj/src/main/assets/emoji/6_113.png | Bin 855 -> 857 bytes TMessagesProj/src/main/assets/emoji/6_114.png | Bin 1162 -> 1163 bytes TMessagesProj/src/main/assets/emoji/6_115.png | Bin 1209 -> 1209 bytes TMessagesProj/src/main/assets/emoji/6_116.png | Bin 885 -> 885 bytes TMessagesProj/src/main/assets/emoji/6_117.png | Bin 1077 -> 1024 bytes TMessagesProj/src/main/assets/emoji/6_118.png | Bin 1003 -> 1078 bytes TMessagesProj/src/main/assets/emoji/6_119.png | Bin 1084 -> 1002 bytes TMessagesProj/src/main/assets/emoji/6_12.png | Bin 1320 -> 1322 bytes TMessagesProj/src/main/assets/emoji/6_120.png | Bin 1097 -> 1084 bytes TMessagesProj/src/main/assets/emoji/6_121.png | Bin 952 -> 1097 bytes TMessagesProj/src/main/assets/emoji/6_122.png | Bin 1062 -> 952 bytes TMessagesProj/src/main/assets/emoji/6_123.png | Bin 965 -> 1062 bytes TMessagesProj/src/main/assets/emoji/6_124.png | Bin 937 -> 964 bytes TMessagesProj/src/main/assets/emoji/6_125.png | Bin 930 -> 936 bytes TMessagesProj/src/main/assets/emoji/6_126.png | Bin 892 -> 930 bytes TMessagesProj/src/main/assets/emoji/6_127.png | Bin 979 -> 1002 bytes TMessagesProj/src/main/assets/emoji/6_128.png | Bin 928 -> 893 bytes TMessagesProj/src/main/assets/emoji/6_129.png | Bin 827 -> 977 bytes TMessagesProj/src/main/assets/emoji/6_130.png | Bin 795 -> 930 bytes TMessagesProj/src/main/assets/emoji/6_131.png | Bin 1114 -> 831 bytes TMessagesProj/src/main/assets/emoji/6_132.png | Bin 801 -> 794 bytes TMessagesProj/src/main/assets/emoji/6_133.png | Bin 940 -> 1125 bytes TMessagesProj/src/main/assets/emoji/6_134.png | Bin 1132 -> 801 bytes TMessagesProj/src/main/assets/emoji/6_135.png | Bin 1130 -> 942 bytes TMessagesProj/src/main/assets/emoji/6_136.png | Bin 975 -> 1135 bytes TMessagesProj/src/main/assets/emoji/6_137.png | Bin 947 -> 1129 bytes TMessagesProj/src/main/assets/emoji/6_138.png | Bin 919 -> 975 bytes TMessagesProj/src/main/assets/emoji/6_139.png | Bin 939 -> 947 bytes TMessagesProj/src/main/assets/emoji/6_140.png | Bin 855 -> 919 bytes TMessagesProj/src/main/assets/emoji/6_141.png | Bin 976 -> 941 bytes TMessagesProj/src/main/assets/emoji/6_142.png | Bin 846 -> 855 bytes TMessagesProj/src/main/assets/emoji/6_143.png | Bin 784 -> 975 bytes TMessagesProj/src/main/assets/emoji/6_144.png | Bin 863 -> 846 bytes TMessagesProj/src/main/assets/emoji/6_145.png | Bin 879 -> 784 bytes TMessagesProj/src/main/assets/emoji/6_146.png | Bin 852 -> 873 bytes TMessagesProj/src/main/assets/emoji/6_147.png | Bin 859 -> 879 bytes TMessagesProj/src/main/assets/emoji/6_148.png | Bin 915 -> 852 bytes TMessagesProj/src/main/assets/emoji/6_149.png | Bin 784 -> 859 bytes TMessagesProj/src/main/assets/emoji/6_15.png | Bin 1745 -> 1746 bytes TMessagesProj/src/main/assets/emoji/6_150.png | Bin 893 -> 915 bytes TMessagesProj/src/main/assets/emoji/6_151.png | Bin 905 -> 784 bytes TMessagesProj/src/main/assets/emoji/6_152.png | Bin 971 -> 895 bytes TMessagesProj/src/main/assets/emoji/6_153.png | Bin 1009 -> 905 bytes TMessagesProj/src/main/assets/emoji/6_154.png | Bin 896 -> 971 bytes TMessagesProj/src/main/assets/emoji/6_155.png | Bin 890 -> 1005 bytes TMessagesProj/src/main/assets/emoji/6_156.png | Bin 783 -> 896 bytes TMessagesProj/src/main/assets/emoji/6_157.png | Bin 804 -> 882 bytes TMessagesProj/src/main/assets/emoji/6_158.png | Bin 822 -> 783 bytes TMessagesProj/src/main/assets/emoji/6_159.png | Bin 795 -> 804 bytes TMessagesProj/src/main/assets/emoji/6_16.png | Bin 1686 -> 1683 bytes TMessagesProj/src/main/assets/emoji/6_160.png | Bin 726 -> 822 bytes TMessagesProj/src/main/assets/emoji/6_161.png | Bin 812 -> 795 bytes TMessagesProj/src/main/assets/emoji/6_162.png | Bin 843 -> 719 bytes TMessagesProj/src/main/assets/emoji/6_163.png | Bin 884 -> 812 bytes TMessagesProj/src/main/assets/emoji/6_164.png | Bin 841 -> 843 bytes TMessagesProj/src/main/assets/emoji/6_165.png | Bin 847 -> 884 bytes TMessagesProj/src/main/assets/emoji/6_166.png | Bin 811 -> 841 bytes TMessagesProj/src/main/assets/emoji/6_167.png | Bin 793 -> 847 bytes TMessagesProj/src/main/assets/emoji/6_168.png | Bin 792 -> 819 bytes TMessagesProj/src/main/assets/emoji/6_169.png | Bin 811 -> 793 bytes TMessagesProj/src/main/assets/emoji/6_17.png | Bin 2207 -> 2205 bytes TMessagesProj/src/main/assets/emoji/6_170.png | Bin 784 -> 792 bytes TMessagesProj/src/main/assets/emoji/6_171.png | Bin 817 -> 811 bytes TMessagesProj/src/main/assets/emoji/6_172.png | Bin 826 -> 784 bytes TMessagesProj/src/main/assets/emoji/6_173.png | Bin 803 -> 817 bytes TMessagesProj/src/main/assets/emoji/6_174.png | Bin 792 -> 826 bytes TMessagesProj/src/main/assets/emoji/6_175.png | Bin 846 -> 801 bytes TMessagesProj/src/main/assets/emoji/6_176.png | Bin 768 -> 792 bytes TMessagesProj/src/main/assets/emoji/6_177.png | Bin 729 -> 846 bytes TMessagesProj/src/main/assets/emoji/6_178.png | Bin 782 -> 768 bytes TMessagesProj/src/main/assets/emoji/6_179.png | Bin 827 -> 729 bytes TMessagesProj/src/main/assets/emoji/6_180.png | Bin 822 -> 782 bytes TMessagesProj/src/main/assets/emoji/6_181.png | Bin 894 -> 823 bytes TMessagesProj/src/main/assets/emoji/6_182.png | Bin 907 -> 822 bytes TMessagesProj/src/main/assets/emoji/6_183.png | Bin 862 -> 894 bytes TMessagesProj/src/main/assets/emoji/6_184.png | Bin 868 -> 907 bytes TMessagesProj/src/main/assets/emoji/6_185.png | Bin 941 -> 862 bytes TMessagesProj/src/main/assets/emoji/6_186.png | Bin 926 -> 868 bytes TMessagesProj/src/main/assets/emoji/6_187.png | Bin 999 -> 941 bytes TMessagesProj/src/main/assets/emoji/6_188.png | Bin 1061 -> 926 bytes TMessagesProj/src/main/assets/emoji/6_189.png | Bin 995 -> 997 bytes TMessagesProj/src/main/assets/emoji/6_19.png | Bin 1178 -> 1180 bytes TMessagesProj/src/main/assets/emoji/6_190.png | Bin 770 -> 1060 bytes TMessagesProj/src/main/assets/emoji/6_191.png | Bin 1474 -> 995 bytes TMessagesProj/src/main/assets/emoji/6_192.png | Bin 246 -> 771 bytes TMessagesProj/src/main/assets/emoji/6_193.png | Bin 157 -> 1471 bytes TMessagesProj/src/main/assets/emoji/6_194.png | Bin 273 -> 246 bytes TMessagesProj/src/main/assets/emoji/6_195.png | Bin 460 -> 157 bytes TMessagesProj/src/main/assets/emoji/6_196.png | Bin 695 -> 273 bytes TMessagesProj/src/main/assets/emoji/6_197.png | Bin 624 -> 461 bytes TMessagesProj/src/main/assets/emoji/6_198.png | Bin 845 -> 695 bytes TMessagesProj/src/main/assets/emoji/6_199.png | Bin 468 -> 623 bytes TMessagesProj/src/main/assets/emoji/6_200.png | Bin 936 -> 845 bytes TMessagesProj/src/main/assets/emoji/6_201.png | Bin 949 -> 469 bytes TMessagesProj/src/main/assets/emoji/6_202.png | Bin 1087 -> 938 bytes TMessagesProj/src/main/assets/emoji/6_203.png | Bin 597 -> 952 bytes TMessagesProj/src/main/assets/emoji/6_204.png | Bin 826 -> 1084 bytes TMessagesProj/src/main/assets/emoji/6_205.png | Bin 685 -> 597 bytes TMessagesProj/src/main/assets/emoji/6_206.png | Bin 614 -> 825 bytes TMessagesProj/src/main/assets/emoji/6_207.png | Bin 846 -> 686 bytes TMessagesProj/src/main/assets/emoji/6_208.png | Bin 528 -> 614 bytes TMessagesProj/src/main/assets/emoji/6_209.png | Bin 678 -> 844 bytes TMessagesProj/src/main/assets/emoji/6_21.png | Bin 988 -> 994 bytes TMessagesProj/src/main/assets/emoji/6_210.png | Bin 619 -> 527 bytes TMessagesProj/src/main/assets/emoji/6_211.png | Bin 499 -> 677 bytes TMessagesProj/src/main/assets/emoji/6_212.png | Bin 1075 -> 622 bytes TMessagesProj/src/main/assets/emoji/6_213.png | Bin 1101 -> 500 bytes TMessagesProj/src/main/assets/emoji/6_214.png | Bin 792 -> 1074 bytes TMessagesProj/src/main/assets/emoji/6_215.png | Bin 844 -> 1103 bytes TMessagesProj/src/main/assets/emoji/6_216.png | Bin 789 -> 792 bytes TMessagesProj/src/main/assets/emoji/6_217.png | Bin 855 -> 844 bytes TMessagesProj/src/main/assets/emoji/6_218.png | Bin 827 -> 789 bytes TMessagesProj/src/main/assets/emoji/6_219.png | Bin 755 -> 847 bytes TMessagesProj/src/main/assets/emoji/6_220.png | Bin 769 -> 827 bytes TMessagesProj/src/main/assets/emoji/6_221.png | Bin 621 -> 755 bytes TMessagesProj/src/main/assets/emoji/6_222.png | Bin 829 -> 769 bytes TMessagesProj/src/main/assets/emoji/6_223.png | Bin 457 -> 621 bytes TMessagesProj/src/main/assets/emoji/6_224.png | Bin 576 -> 829 bytes TMessagesProj/src/main/assets/emoji/6_225.png | Bin 498 -> 457 bytes TMessagesProj/src/main/assets/emoji/6_226.png | Bin 527 -> 577 bytes TMessagesProj/src/main/assets/emoji/6_227.png | Bin 569 -> 502 bytes TMessagesProj/src/main/assets/emoji/6_228.png | Bin 650 -> 529 bytes TMessagesProj/src/main/assets/emoji/6_229.png | Bin 412 -> 569 bytes TMessagesProj/src/main/assets/emoji/6_23.png | Bin 1277 -> 1283 bytes TMessagesProj/src/main/assets/emoji/6_230.png | Bin 566 -> 653 bytes TMessagesProj/src/main/assets/emoji/6_231.png | Bin 320 -> 412 bytes TMessagesProj/src/main/assets/emoji/6_232.png | Bin 176 -> 566 bytes TMessagesProj/src/main/assets/emoji/6_233.png | Bin 224 -> 320 bytes TMessagesProj/src/main/assets/emoji/6_234.png | Bin 187 -> 176 bytes TMessagesProj/src/main/assets/emoji/6_235.png | Bin 233 -> 224 bytes TMessagesProj/src/main/assets/emoji/6_236.png | Bin 187 -> 187 bytes TMessagesProj/src/main/assets/emoji/6_237.png | Bin 405 -> 233 bytes TMessagesProj/src/main/assets/emoji/6_238.png | Bin 403 -> 187 bytes TMessagesProj/src/main/assets/emoji/6_239.png | Bin 642 -> 405 bytes TMessagesProj/src/main/assets/emoji/6_24.png | Bin 1041 -> 1042 bytes TMessagesProj/src/main/assets/emoji/6_240.png | Bin 382 -> 403 bytes TMessagesProj/src/main/assets/emoji/6_241.png | Bin 491 -> 642 bytes TMessagesProj/src/main/assets/emoji/6_242.png | Bin 500 -> 382 bytes TMessagesProj/src/main/assets/emoji/6_243.png | Bin 446 -> 491 bytes TMessagesProj/src/main/assets/emoji/6_244.png | Bin 179 -> 500 bytes TMessagesProj/src/main/assets/emoji/6_245.png | Bin 394 -> 446 bytes TMessagesProj/src/main/assets/emoji/6_246.png | Bin 1614 -> 179 bytes TMessagesProj/src/main/assets/emoji/6_247.png | Bin 1729 -> 394 bytes TMessagesProj/src/main/assets/emoji/6_248.png | Bin 2064 -> 1614 bytes TMessagesProj/src/main/assets/emoji/6_249.png | Bin 2802 -> 1729 bytes TMessagesProj/src/main/assets/emoji/6_250.png | Bin 1627 -> 2065 bytes TMessagesProj/src/main/assets/emoji/6_251.png | Bin 1893 -> 2802 bytes TMessagesProj/src/main/assets/emoji/6_252.png | Bin 1910 -> 1629 bytes TMessagesProj/src/main/assets/emoji/6_253.png | Bin 1467 -> 1895 bytes TMessagesProj/src/main/assets/emoji/6_254.png | Bin 985 -> 1909 bytes TMessagesProj/src/main/assets/emoji/6_255.png | Bin 1093 -> 1466 bytes TMessagesProj/src/main/assets/emoji/6_256.png | Bin 1289 -> 983 bytes TMessagesProj/src/main/assets/emoji/6_257.png | Bin 830 -> 1094 bytes TMessagesProj/src/main/assets/emoji/6_258.png | Bin 856 -> 1291 bytes TMessagesProj/src/main/assets/emoji/6_259.png | Bin 797 -> 830 bytes TMessagesProj/src/main/assets/emoji/6_26.png | Bin 1367 -> 1366 bytes TMessagesProj/src/main/assets/emoji/6_260.png | Bin 675 -> 856 bytes TMessagesProj/src/main/assets/emoji/6_261.png | Bin 1011 -> 796 bytes TMessagesProj/src/main/assets/emoji/6_262.png | Bin 1021 -> 677 bytes TMessagesProj/src/main/assets/emoji/6_263.png | Bin 1025 -> 1009 bytes TMessagesProj/src/main/assets/emoji/6_264.png | Bin 1382 -> 1029 bytes TMessagesProj/src/main/assets/emoji/6_265.png | Bin 1365 -> 1024 bytes TMessagesProj/src/main/assets/emoji/6_266.png | Bin 1342 -> 1382 bytes TMessagesProj/src/main/assets/emoji/6_267.png | Bin 1409 -> 1365 bytes TMessagesProj/src/main/assets/emoji/6_268.png | Bin 1392 -> 1342 bytes TMessagesProj/src/main/assets/emoji/6_269.png | Bin 1359 -> 1408 bytes TMessagesProj/src/main/assets/emoji/6_27.png | Bin 1147 -> 1144 bytes TMessagesProj/src/main/assets/emoji/6_270.png | Bin 1420 -> 1396 bytes TMessagesProj/src/main/assets/emoji/6_271.png | Bin 1375 -> 1360 bytes TMessagesProj/src/main/assets/emoji/6_272.png | Bin 1425 -> 1418 bytes TMessagesProj/src/main/assets/emoji/6_273.png | Bin 1368 -> 1373 bytes TMessagesProj/src/main/assets/emoji/6_274.png | Bin 1450 -> 1433 bytes TMessagesProj/src/main/assets/emoji/6_275.png | Bin 1362 -> 1371 bytes TMessagesProj/src/main/assets/emoji/6_276.png | Bin 1365 -> 1441 bytes TMessagesProj/src/main/assets/emoji/6_277.png | Bin 1397 -> 1360 bytes TMessagesProj/src/main/assets/emoji/6_278.png | Bin 1373 -> 1365 bytes TMessagesProj/src/main/assets/emoji/6_279.png | Bin 1410 -> 1401 bytes TMessagesProj/src/main/assets/emoji/6_280.png | Bin 1392 -> 1374 bytes TMessagesProj/src/main/assets/emoji/6_281.png | Bin 1385 -> 1409 bytes TMessagesProj/src/main/assets/emoji/6_282.png | Bin 1369 -> 1390 bytes TMessagesProj/src/main/assets/emoji/6_283.png | Bin 1370 -> 1380 bytes TMessagesProj/src/main/assets/emoji/6_284.png | Bin 1396 -> 1368 bytes TMessagesProj/src/main/assets/emoji/6_285.png | Bin 1378 -> 1372 bytes TMessagesProj/src/main/assets/emoji/6_286.png | Bin 1393 -> 1394 bytes TMessagesProj/src/main/assets/emoji/6_287.png | Bin 1383 -> 1379 bytes TMessagesProj/src/main/assets/emoji/6_288.png | Bin 0 -> 1395 bytes TMessagesProj/src/main/assets/emoji/6_289.png | Bin 0 -> 1382 bytes TMessagesProj/src/main/assets/emoji/6_3.png | Bin 986 -> 992 bytes TMessagesProj/src/main/assets/emoji/6_30.png | Bin 1018 -> 1017 bytes TMessagesProj/src/main/assets/emoji/6_31.png | Bin 927 -> 929 bytes TMessagesProj/src/main/assets/emoji/6_32.png | Bin 1047 -> 1048 bytes TMessagesProj/src/main/assets/emoji/6_33.png | Bin 913 -> 914 bytes TMessagesProj/src/main/assets/emoji/6_35.png | Bin 1188 -> 1185 bytes TMessagesProj/src/main/assets/emoji/6_36.png | Bin 1161 -> 1163 bytes TMessagesProj/src/main/assets/emoji/6_37.png | Bin 833 -> 831 bytes TMessagesProj/src/main/assets/emoji/6_38.png | Bin 1062 -> 1061 bytes TMessagesProj/src/main/assets/emoji/6_39.png | Bin 984 -> 979 bytes TMessagesProj/src/main/assets/emoji/6_4.png | Bin 901 -> 904 bytes TMessagesProj/src/main/assets/emoji/6_40.png | Bin 1157 -> 1157 bytes TMessagesProj/src/main/assets/emoji/6_42.png | Bin 965 -> 965 bytes TMessagesProj/src/main/assets/emoji/6_43.png | Bin 932 -> 933 bytes TMessagesProj/src/main/assets/emoji/6_44.png | Bin 1387 -> 1383 bytes TMessagesProj/src/main/assets/emoji/6_45.png | Bin 934 -> 934 bytes TMessagesProj/src/main/assets/emoji/6_46.png | Bin 1066 -> 1064 bytes TMessagesProj/src/main/assets/emoji/6_47.png | Bin 1383 -> 1383 bytes TMessagesProj/src/main/assets/emoji/6_48.png | Bin 1157 -> 1143 bytes TMessagesProj/src/main/assets/emoji/6_49.png | Bin 1137 -> 1143 bytes TMessagesProj/src/main/assets/emoji/6_51.png | Bin 1242 -> 1243 bytes TMessagesProj/src/main/assets/emoji/6_52.png | Bin 966 -> 962 bytes TMessagesProj/src/main/assets/emoji/6_53.png | Bin 1098 -> 1098 bytes TMessagesProj/src/main/assets/emoji/6_54.png | Bin 961 -> 961 bytes TMessagesProj/src/main/assets/emoji/6_56.png | Bin 1043 -> 1042 bytes TMessagesProj/src/main/assets/emoji/6_57.png | Bin 1481 -> 1480 bytes TMessagesProj/src/main/assets/emoji/6_58.png | Bin 1245 -> 1245 bytes TMessagesProj/src/main/assets/emoji/6_59.png | Bin 1460 -> 1459 bytes TMessagesProj/src/main/assets/emoji/6_60.png | Bin 1250 -> 1247 bytes TMessagesProj/src/main/assets/emoji/6_62.png | Bin 1357 -> 1358 bytes TMessagesProj/src/main/assets/emoji/6_63.png | Bin 1263 -> 1261 bytes TMessagesProj/src/main/assets/emoji/6_64.png | Bin 1373 -> 1374 bytes TMessagesProj/src/main/assets/emoji/6_68.png | Bin 964 -> 961 bytes TMessagesProj/src/main/assets/emoji/6_69.png | Bin 1020 -> 1020 bytes TMessagesProj/src/main/assets/emoji/6_71.png | Bin 624 -> 625 bytes TMessagesProj/src/main/assets/emoji/6_72.png | Bin 971 -> 973 bytes TMessagesProj/src/main/assets/emoji/6_73.png | Bin 689 -> 685 bytes TMessagesProj/src/main/assets/emoji/6_74.png | Bin 1051 -> 1053 bytes TMessagesProj/src/main/assets/emoji/6_75.png | Bin 1239 -> 1239 bytes TMessagesProj/src/main/assets/emoji/6_76.png | Bin 1724 -> 1725 bytes TMessagesProj/src/main/assets/emoji/6_77.png | Bin 1218 -> 1219 bytes TMessagesProj/src/main/assets/emoji/6_78.png | Bin 1217 -> 1217 bytes TMessagesProj/src/main/assets/emoji/6_79.png | Bin 1123 -> 1125 bytes TMessagesProj/src/main/assets/emoji/6_8.png | Bin 871 -> 871 bytes TMessagesProj/src/main/assets/emoji/6_80.png | Bin 1677 -> 1679 bytes TMessagesProj/src/main/assets/emoji/6_81.png | Bin 1704 -> 1708 bytes TMessagesProj/src/main/assets/emoji/6_82.png | Bin 1841 -> 1841 bytes TMessagesProj/src/main/assets/emoji/6_83.png | Bin 1659 -> 1658 bytes TMessagesProj/src/main/assets/emoji/6_84.png | Bin 1707 -> 1711 bytes TMessagesProj/src/main/assets/emoji/6_85.png | Bin 1635 -> 1643 bytes TMessagesProj/src/main/assets/emoji/6_86.png | Bin 1555 -> 1555 bytes TMessagesProj/src/main/assets/emoji/6_87.png | Bin 595 -> 596 bytes TMessagesProj/src/main/assets/emoji/6_88.png | Bin 565 -> 565 bytes TMessagesProj/src/main/assets/emoji/6_89.png | Bin 576 -> 576 bytes TMessagesProj/src/main/assets/emoji/6_9.png | Bin 1249 -> 1248 bytes TMessagesProj/src/main/assets/emoji/6_90.png | Bin 553 -> 554 bytes TMessagesProj/src/main/assets/emoji/6_92.png | Bin 941 -> 943 bytes TMessagesProj/src/main/assets/emoji/6_93.png | Bin 946 -> 946 bytes TMessagesProj/src/main/assets/emoji/6_94.png | Bin 1350 -> 1352 bytes TMessagesProj/src/main/assets/emoji/6_95.png | Bin 673 -> 673 bytes TMessagesProj/src/main/assets/emoji/6_96.png | Bin 673 -> 674 bytes TMessagesProj/src/main/assets/emoji/6_97.png | Bin 946 -> 944 bytes TMessagesProj/src/main/assets/emoji/6_98.png | Bin 2258 -> 2258 bytes TMessagesProj/src/main/assets/emoji/6_99.png | Bin 1951 -> 1951 bytes TMessagesProj/src/main/assets/emoji/7_0.png | Bin 680 -> 678 bytes TMessagesProj/src/main/assets/emoji/7_1.png | Bin 571 -> 569 bytes TMessagesProj/src/main/assets/emoji/7_10.png | Bin 1091 -> 1037 bytes TMessagesProj/src/main/assets/emoji/7_100.png | Bin 1014 -> 1011 bytes TMessagesProj/src/main/assets/emoji/7_101.png | Bin 1347 -> 1014 bytes TMessagesProj/src/main/assets/emoji/7_102.png | Bin 873 -> 1344 bytes TMessagesProj/src/main/assets/emoji/7_103.png | Bin 997 -> 872 bytes TMessagesProj/src/main/assets/emoji/7_104.png | Bin 1531 -> 996 bytes TMessagesProj/src/main/assets/emoji/7_105.png | Bin 1208 -> 1532 bytes TMessagesProj/src/main/assets/emoji/7_106.png | Bin 1069 -> 1208 bytes TMessagesProj/src/main/assets/emoji/7_107.png | Bin 949 -> 1070 bytes TMessagesProj/src/main/assets/emoji/7_108.png | Bin 1071 -> 949 bytes TMessagesProj/src/main/assets/emoji/7_109.png | Bin 1310 -> 1069 bytes TMessagesProj/src/main/assets/emoji/7_11.png | Bin 1439 -> 1090 bytes TMessagesProj/src/main/assets/emoji/7_110.png | Bin 1309 -> 1309 bytes TMessagesProj/src/main/assets/emoji/7_111.png | Bin 912 -> 1309 bytes TMessagesProj/src/main/assets/emoji/7_112.png | Bin 1343 -> 912 bytes TMessagesProj/src/main/assets/emoji/7_113.png | Bin 1187 -> 1343 bytes TMessagesProj/src/main/assets/emoji/7_114.png | Bin 854 -> 1184 bytes TMessagesProj/src/main/assets/emoji/7_115.png | Bin 903 -> 856 bytes TMessagesProj/src/main/assets/emoji/7_116.png | Bin 1240 -> 904 bytes TMessagesProj/src/main/assets/emoji/7_117.png | Bin 851 -> 1240 bytes TMessagesProj/src/main/assets/emoji/7_118.png | Bin 1229 -> 852 bytes TMessagesProj/src/main/assets/emoji/7_119.png | Bin 814 -> 1228 bytes TMessagesProj/src/main/assets/emoji/7_12.png | Bin 1282 -> 1436 bytes TMessagesProj/src/main/assets/emoji/7_120.png | Bin 1838 -> 812 bytes TMessagesProj/src/main/assets/emoji/7_121.png | Bin 1458 -> 1840 bytes TMessagesProj/src/main/assets/emoji/7_122.png | Bin 1183 -> 1457 bytes TMessagesProj/src/main/assets/emoji/7_123.png | Bin 1140 -> 1185 bytes TMessagesProj/src/main/assets/emoji/7_124.png | Bin 1493 -> 1142 bytes TMessagesProj/src/main/assets/emoji/7_125.png | Bin 1605 -> 1494 bytes TMessagesProj/src/main/assets/emoji/7_126.png | Bin 904 -> 1608 bytes TMessagesProj/src/main/assets/emoji/7_127.png | Bin 1099 -> 904 bytes TMessagesProj/src/main/assets/emoji/7_128.png | Bin 949 -> 1102 bytes TMessagesProj/src/main/assets/emoji/7_129.png | Bin 1008 -> 948 bytes TMessagesProj/src/main/assets/emoji/7_13.png | Bin 1042 -> 1280 bytes TMessagesProj/src/main/assets/emoji/7_130.png | Bin 896 -> 1009 bytes TMessagesProj/src/main/assets/emoji/7_131.png | Bin 1281 -> 898 bytes TMessagesProj/src/main/assets/emoji/7_132.png | Bin 1160 -> 1282 bytes TMessagesProj/src/main/assets/emoji/7_133.png | Bin 1732 -> 1159 bytes TMessagesProj/src/main/assets/emoji/7_134.png | Bin 1098 -> 1730 bytes TMessagesProj/src/main/assets/emoji/7_135.png | Bin 1071 -> 1101 bytes TMessagesProj/src/main/assets/emoji/7_136.png | Bin 1128 -> 1071 bytes TMessagesProj/src/main/assets/emoji/7_137.png | Bin 1128 -> 1130 bytes TMessagesProj/src/main/assets/emoji/7_138.png | Bin 894 -> 1129 bytes TMessagesProj/src/main/assets/emoji/7_139.png | Bin 945 -> 898 bytes TMessagesProj/src/main/assets/emoji/7_14.png | Bin 1706 -> 1044 bytes TMessagesProj/src/main/assets/emoji/7_140.png | Bin 1098 -> 941 bytes TMessagesProj/src/main/assets/emoji/7_141.png | Bin 1953 -> 1097 bytes TMessagesProj/src/main/assets/emoji/7_142.png | Bin 948 -> 1954 bytes TMessagesProj/src/main/assets/emoji/7_143.png | Bin 892 -> 946 bytes TMessagesProj/src/main/assets/emoji/7_144.png | Bin 813 -> 891 bytes TMessagesProj/src/main/assets/emoji/7_145.png | Bin 1288 -> 811 bytes TMessagesProj/src/main/assets/emoji/7_146.png | Bin 1218 -> 1286 bytes TMessagesProj/src/main/assets/emoji/7_147.png | Bin 1115 -> 1219 bytes TMessagesProj/src/main/assets/emoji/7_148.png | Bin 1250 -> 1115 bytes TMessagesProj/src/main/assets/emoji/7_149.png | Bin 1319 -> 1250 bytes TMessagesProj/src/main/assets/emoji/7_15.png | Bin 780 -> 1706 bytes TMessagesProj/src/main/assets/emoji/7_150.png | Bin 1032 -> 1319 bytes TMessagesProj/src/main/assets/emoji/7_151.png | Bin 740 -> 1032 bytes TMessagesProj/src/main/assets/emoji/7_152.png | Bin 1217 -> 741 bytes TMessagesProj/src/main/assets/emoji/7_153.png | Bin 868 -> 1222 bytes TMessagesProj/src/main/assets/emoji/7_154.png | Bin 952 -> 867 bytes TMessagesProj/src/main/assets/emoji/7_155.png | Bin 915 -> 953 bytes TMessagesProj/src/main/assets/emoji/7_156.png | Bin 1876 -> 913 bytes TMessagesProj/src/main/assets/emoji/7_157.png | Bin 982 -> 1875 bytes TMessagesProj/src/main/assets/emoji/7_158.png | Bin 1479 -> 980 bytes TMessagesProj/src/main/assets/emoji/7_159.png | Bin 1365 -> 1477 bytes TMessagesProj/src/main/assets/emoji/7_16.png | Bin 1303 -> 777 bytes TMessagesProj/src/main/assets/emoji/7_160.png | Bin 1536 -> 1365 bytes TMessagesProj/src/main/assets/emoji/7_161.png | Bin 970 -> 1536 bytes TMessagesProj/src/main/assets/emoji/7_162.png | Bin 885 -> 968 bytes TMessagesProj/src/main/assets/emoji/7_163.png | Bin 999 -> 885 bytes TMessagesProj/src/main/assets/emoji/7_164.png | Bin 1518 -> 997 bytes TMessagesProj/src/main/assets/emoji/7_165.png | Bin 1464 -> 1516 bytes TMessagesProj/src/main/assets/emoji/7_166.png | Bin 1186 -> 1464 bytes TMessagesProj/src/main/assets/emoji/7_167.png | Bin 1157 -> 1185 bytes TMessagesProj/src/main/assets/emoji/7_168.png | Bin 646 -> 1157 bytes TMessagesProj/src/main/assets/emoji/7_169.png | Bin 1783 -> 645 bytes TMessagesProj/src/main/assets/emoji/7_17.png | Bin 1050 -> 1301 bytes TMessagesProj/src/main/assets/emoji/7_170.png | Bin 969 -> 1785 bytes TMessagesProj/src/main/assets/emoji/7_171.png | Bin 1314 -> 969 bytes TMessagesProj/src/main/assets/emoji/7_172.png | Bin 1703 -> 1315 bytes TMessagesProj/src/main/assets/emoji/7_173.png | Bin 1498 -> 1704 bytes TMessagesProj/src/main/assets/emoji/7_174.png | Bin 1376 -> 1496 bytes TMessagesProj/src/main/assets/emoji/7_175.png | Bin 1158 -> 1376 bytes TMessagesProj/src/main/assets/emoji/7_176.png | Bin 868 -> 1159 bytes TMessagesProj/src/main/assets/emoji/7_177.png | Bin 853 -> 869 bytes TMessagesProj/src/main/assets/emoji/7_178.png | Bin 1062 -> 851 bytes TMessagesProj/src/main/assets/emoji/7_179.png | Bin 1286 -> 1064 bytes TMessagesProj/src/main/assets/emoji/7_18.png | Bin 1170 -> 1053 bytes TMessagesProj/src/main/assets/emoji/7_180.png | Bin 1223 -> 1285 bytes TMessagesProj/src/main/assets/emoji/7_181.png | Bin 1289 -> 1223 bytes TMessagesProj/src/main/assets/emoji/7_182.png | Bin 737 -> 1288 bytes TMessagesProj/src/main/assets/emoji/7_183.png | Bin 1339 -> 737 bytes TMessagesProj/src/main/assets/emoji/7_184.png | Bin 1891 -> 1339 bytes TMessagesProj/src/main/assets/emoji/7_185.png | Bin 881 -> 1888 bytes TMessagesProj/src/main/assets/emoji/7_186.png | Bin 1333 -> 875 bytes TMessagesProj/src/main/assets/emoji/7_187.png | Bin 1467 -> 1334 bytes TMessagesProj/src/main/assets/emoji/7_188.png | Bin 815 -> 1466 bytes TMessagesProj/src/main/assets/emoji/7_189.png | Bin 1523 -> 816 bytes TMessagesProj/src/main/assets/emoji/7_19.png | Bin 1122 -> 1171 bytes TMessagesProj/src/main/assets/emoji/7_190.png | Bin 883 -> 1522 bytes TMessagesProj/src/main/assets/emoji/7_191.png | Bin 1043 -> 883 bytes TMessagesProj/src/main/assets/emoji/7_192.png | Bin 1338 -> 1041 bytes TMessagesProj/src/main/assets/emoji/7_193.png | Bin 942 -> 1342 bytes TMessagesProj/src/main/assets/emoji/7_194.png | Bin 1367 -> 943 bytes TMessagesProj/src/main/assets/emoji/7_195.png | Bin 1314 -> 1369 bytes TMessagesProj/src/main/assets/emoji/7_196.png | Bin 903 -> 1315 bytes TMessagesProj/src/main/assets/emoji/7_197.png | Bin 971 -> 902 bytes TMessagesProj/src/main/assets/emoji/7_198.png | Bin 1683 -> 974 bytes TMessagesProj/src/main/assets/emoji/7_199.png | Bin 1529 -> 1681 bytes TMessagesProj/src/main/assets/emoji/7_2.png | Bin 871 -> 871 bytes TMessagesProj/src/main/assets/emoji/7_20.png | Bin 1620 -> 1123 bytes TMessagesProj/src/main/assets/emoji/7_200.png | Bin 1093 -> 1529 bytes TMessagesProj/src/main/assets/emoji/7_201.png | Bin 1071 -> 1091 bytes TMessagesProj/src/main/assets/emoji/7_202.png | Bin 1306 -> 1069 bytes TMessagesProj/src/main/assets/emoji/7_203.png | Bin 1415 -> 1308 bytes TMessagesProj/src/main/assets/emoji/7_204.png | Bin 1392 -> 1418 bytes TMessagesProj/src/main/assets/emoji/7_205.png | Bin 1821 -> 1390 bytes TMessagesProj/src/main/assets/emoji/7_206.png | Bin 1337 -> 1824 bytes TMessagesProj/src/main/assets/emoji/7_207.png | Bin 765 -> 1336 bytes TMessagesProj/src/main/assets/emoji/7_208.png | Bin 1662 -> 767 bytes TMessagesProj/src/main/assets/emoji/7_209.png | Bin 1258 -> 1660 bytes TMessagesProj/src/main/assets/emoji/7_21.png | Bin 1057 -> 1619 bytes TMessagesProj/src/main/assets/emoji/7_210.png | Bin 1357 -> 1260 bytes TMessagesProj/src/main/assets/emoji/7_211.png | Bin 1297 -> 1358 bytes TMessagesProj/src/main/assets/emoji/7_212.png | Bin 1214 -> 1296 bytes TMessagesProj/src/main/assets/emoji/7_213.png | Bin 1478 -> 1218 bytes TMessagesProj/src/main/assets/emoji/7_214.png | Bin 1519 -> 1477 bytes TMessagesProj/src/main/assets/emoji/7_215.png | Bin 1532 -> 1520 bytes TMessagesProj/src/main/assets/emoji/7_216.png | Bin 1098 -> 1533 bytes TMessagesProj/src/main/assets/emoji/7_217.png | Bin 2619 -> 1098 bytes TMessagesProj/src/main/assets/emoji/7_218.png | Bin 1060 -> 2618 bytes TMessagesProj/src/main/assets/emoji/7_219.png | Bin 994 -> 1060 bytes TMessagesProj/src/main/assets/emoji/7_22.png | Bin 1274 -> 1057 bytes TMessagesProj/src/main/assets/emoji/7_220.png | Bin 1325 -> 995 bytes TMessagesProj/src/main/assets/emoji/7_221.png | Bin 1137 -> 1324 bytes TMessagesProj/src/main/assets/emoji/7_222.png | Bin 731 -> 1136 bytes TMessagesProj/src/main/assets/emoji/7_223.png | Bin 1138 -> 732 bytes TMessagesProj/src/main/assets/emoji/7_224.png | Bin 1101 -> 1137 bytes TMessagesProj/src/main/assets/emoji/7_225.png | Bin 1265 -> 1100 bytes TMessagesProj/src/main/assets/emoji/7_226.png | Bin 1423 -> 1271 bytes TMessagesProj/src/main/assets/emoji/7_227.png | Bin 1310 -> 1423 bytes TMessagesProj/src/main/assets/emoji/7_228.png | Bin 1103 -> 1310 bytes TMessagesProj/src/main/assets/emoji/7_229.png | Bin 1526 -> 1102 bytes TMessagesProj/src/main/assets/emoji/7_23.png | Bin 1052 -> 1276 bytes TMessagesProj/src/main/assets/emoji/7_230.png | Bin 1047 -> 1524 bytes TMessagesProj/src/main/assets/emoji/7_231.png | Bin 993 -> 1047 bytes TMessagesProj/src/main/assets/emoji/7_232.png | Bin 1171 -> 992 bytes TMessagesProj/src/main/assets/emoji/7_233.png | Bin 941 -> 1169 bytes TMessagesProj/src/main/assets/emoji/7_234.png | Bin 945 -> 940 bytes TMessagesProj/src/main/assets/emoji/7_235.png | Bin 1107 -> 945 bytes TMessagesProj/src/main/assets/emoji/7_236.png | Bin 1800 -> 1104 bytes TMessagesProj/src/main/assets/emoji/7_237.png | Bin 1804 -> 1801 bytes TMessagesProj/src/main/assets/emoji/7_238.png | Bin 2142 -> 1804 bytes TMessagesProj/src/main/assets/emoji/7_239.png | Bin 1646 -> 1646 bytes TMessagesProj/src/main/assets/emoji/7_24.png | Bin 970 -> 1054 bytes TMessagesProj/src/main/assets/emoji/7_240.png | Bin 941 -> 940 bytes TMessagesProj/src/main/assets/emoji/7_241.png | Bin 1012 -> 1015 bytes TMessagesProj/src/main/assets/emoji/7_242.png | Bin 1984 -> 1985 bytes TMessagesProj/src/main/assets/emoji/7_243.png | Bin 1122 -> 1121 bytes TMessagesProj/src/main/assets/emoji/7_244.png | Bin 1193 -> 1194 bytes TMessagesProj/src/main/assets/emoji/7_245.png | Bin 1770 -> 1772 bytes TMessagesProj/src/main/assets/emoji/7_246.png | Bin 1946 -> 1945 bytes TMessagesProj/src/main/assets/emoji/7_247.png | Bin 1568 -> 1567 bytes TMessagesProj/src/main/assets/emoji/7_248.png | Bin 1460 -> 2142 bytes TMessagesProj/src/main/assets/emoji/7_249.png | Bin 1288 -> 1461 bytes TMessagesProj/src/main/assets/emoji/7_25.png | Bin 706 -> 968 bytes TMessagesProj/src/main/assets/emoji/7_250.png | Bin 1023 -> 1287 bytes TMessagesProj/src/main/assets/emoji/7_251.png | Bin 1364 -> 1024 bytes TMessagesProj/src/main/assets/emoji/7_252.png | Bin 865 -> 1365 bytes TMessagesProj/src/main/assets/emoji/7_253.png | Bin 1047 -> 864 bytes TMessagesProj/src/main/assets/emoji/7_254.png | Bin 1147 -> 1048 bytes TMessagesProj/src/main/assets/emoji/7_255.png | Bin 1021 -> 1151 bytes TMessagesProj/src/main/assets/emoji/7_256.png | Bin 882 -> 1020 bytes TMessagesProj/src/main/assets/emoji/7_257.png | Bin 2106 -> 883 bytes TMessagesProj/src/main/assets/emoji/7_258.png | Bin 0 -> 2107 bytes TMessagesProj/src/main/assets/emoji/7_26.png | Bin 895 -> 707 bytes TMessagesProj/src/main/assets/emoji/7_27.png | Bin 1163 -> 896 bytes TMessagesProj/src/main/assets/emoji/7_28.png | Bin 789 -> 1164 bytes TMessagesProj/src/main/assets/emoji/7_29.png | Bin 1791 -> 786 bytes TMessagesProj/src/main/assets/emoji/7_3.png | Bin 1186 -> 1186 bytes TMessagesProj/src/main/assets/emoji/7_30.png | Bin 989 -> 1790 bytes TMessagesProj/src/main/assets/emoji/7_31.png | Bin 2084 -> 985 bytes TMessagesProj/src/main/assets/emoji/7_32.png | Bin 1458 -> 2084 bytes TMessagesProj/src/main/assets/emoji/7_33.png | Bin 1413 -> 1457 bytes TMessagesProj/src/main/assets/emoji/7_34.png | Bin 1074 -> 1410 bytes TMessagesProj/src/main/assets/emoji/7_35.png | Bin 1113 -> 1075 bytes TMessagesProj/src/main/assets/emoji/7_36.png | Bin 1280 -> 1116 bytes TMessagesProj/src/main/assets/emoji/7_37.png | Bin 2370 -> 1281 bytes TMessagesProj/src/main/assets/emoji/7_38.png | Bin 1684 -> 2369 bytes TMessagesProj/src/main/assets/emoji/7_39.png | Bin 1752 -> 1684 bytes TMessagesProj/src/main/assets/emoji/7_4.png | Bin 744 -> 743 bytes TMessagesProj/src/main/assets/emoji/7_40.png | Bin 1072 -> 1753 bytes TMessagesProj/src/main/assets/emoji/7_41.png | Bin 948 -> 1074 bytes TMessagesProj/src/main/assets/emoji/7_42.png | Bin 1519 -> 945 bytes TMessagesProj/src/main/assets/emoji/7_43.png | Bin 1248 -> 1519 bytes TMessagesProj/src/main/assets/emoji/7_44.png | Bin 962 -> 1248 bytes TMessagesProj/src/main/assets/emoji/7_45.png | Bin 1037 -> 963 bytes TMessagesProj/src/main/assets/emoji/7_46.png | Bin 1064 -> 1037 bytes TMessagesProj/src/main/assets/emoji/7_47.png | Bin 1440 -> 1065 bytes TMessagesProj/src/main/assets/emoji/7_48.png | Bin 1216 -> 1440 bytes TMessagesProj/src/main/assets/emoji/7_49.png | Bin 1803 -> 1214 bytes TMessagesProj/src/main/assets/emoji/7_50.png | Bin 1656 -> 1803 bytes TMessagesProj/src/main/assets/emoji/7_51.png | Bin 861 -> 1656 bytes TMessagesProj/src/main/assets/emoji/7_52.png | Bin 1074 -> 859 bytes TMessagesProj/src/main/assets/emoji/7_53.png | Bin 873 -> 1076 bytes TMessagesProj/src/main/assets/emoji/7_54.png | Bin 1213 -> 870 bytes TMessagesProj/src/main/assets/emoji/7_55.png | Bin 1030 -> 1211 bytes TMessagesProj/src/main/assets/emoji/7_56.png | Bin 1213 -> 1031 bytes TMessagesProj/src/main/assets/emoji/7_57.png | Bin 1624 -> 1213 bytes TMessagesProj/src/main/assets/emoji/7_58.png | Bin 1142 -> 1626 bytes TMessagesProj/src/main/assets/emoji/7_59.png | Bin 1684 -> 1145 bytes TMessagesProj/src/main/assets/emoji/7_6.png | Bin 951 -> 1087 bytes TMessagesProj/src/main/assets/emoji/7_60.png | Bin 1645 -> 1680 bytes TMessagesProj/src/main/assets/emoji/7_61.png | Bin 1267 -> 1646 bytes TMessagesProj/src/main/assets/emoji/7_62.png | Bin 897 -> 1269 bytes TMessagesProj/src/main/assets/emoji/7_63.png | Bin 1614 -> 897 bytes TMessagesProj/src/main/assets/emoji/7_64.png | Bin 1354 -> 1611 bytes TMessagesProj/src/main/assets/emoji/7_65.png | Bin 1106 -> 1357 bytes TMessagesProj/src/main/assets/emoji/7_66.png | Bin 990 -> 1105 bytes TMessagesProj/src/main/assets/emoji/7_67.png | Bin 1099 -> 990 bytes TMessagesProj/src/main/assets/emoji/7_68.png | Bin 1077 -> 1100 bytes TMessagesProj/src/main/assets/emoji/7_69.png | Bin 1116 -> 1077 bytes TMessagesProj/src/main/assets/emoji/7_7.png | Bin 1085 -> 952 bytes TMessagesProj/src/main/assets/emoji/7_70.png | Bin 1860 -> 1118 bytes TMessagesProj/src/main/assets/emoji/7_71.png | Bin 1504 -> 1858 bytes TMessagesProj/src/main/assets/emoji/7_72.png | Bin 1584 -> 1503 bytes TMessagesProj/src/main/assets/emoji/7_73.png | Bin 1092 -> 1584 bytes TMessagesProj/src/main/assets/emoji/7_74.png | Bin 1267 -> 1094 bytes TMessagesProj/src/main/assets/emoji/7_75.png | Bin 1391 -> 1270 bytes TMessagesProj/src/main/assets/emoji/7_76.png | Bin 1420 -> 1392 bytes TMessagesProj/src/main/assets/emoji/7_77.png | Bin 1002 -> 1421 bytes TMessagesProj/src/main/assets/emoji/7_78.png | Bin 1927 -> 1002 bytes TMessagesProj/src/main/assets/emoji/7_79.png | Bin 1354 -> 1930 bytes TMessagesProj/src/main/assets/emoji/7_8.png | Bin 1430 -> 1083 bytes TMessagesProj/src/main/assets/emoji/7_80.png | Bin 760 -> 1355 bytes TMessagesProj/src/main/assets/emoji/7_81.png | Bin 1729 -> 760 bytes TMessagesProj/src/main/assets/emoji/7_82.png | Bin 1433 -> 1728 bytes TMessagesProj/src/main/assets/emoji/7_83.png | Bin 2042 -> 1432 bytes TMessagesProj/src/main/assets/emoji/7_84.png | Bin 966 -> 2040 bytes TMessagesProj/src/main/assets/emoji/7_85.png | Bin 880 -> 965 bytes TMessagesProj/src/main/assets/emoji/7_86.png | Bin 998 -> 880 bytes TMessagesProj/src/main/assets/emoji/7_87.png | Bin 1254 -> 999 bytes TMessagesProj/src/main/assets/emoji/7_88.png | Bin 1010 -> 1256 bytes TMessagesProj/src/main/assets/emoji/7_89.png | Bin 1115 -> 1010 bytes TMessagesProj/src/main/assets/emoji/7_9.png | Bin 1037 -> 1429 bytes TMessagesProj/src/main/assets/emoji/7_90.png | Bin 1339 -> 1113 bytes TMessagesProj/src/main/assets/emoji/7_91.png | Bin 1435 -> 1338 bytes TMessagesProj/src/main/assets/emoji/7_92.png | Bin 1071 -> 1433 bytes TMessagesProj/src/main/assets/emoji/7_93.png | Bin 1133 -> 1070 bytes TMessagesProj/src/main/assets/emoji/7_94.png | Bin 1338 -> 1131 bytes TMessagesProj/src/main/assets/emoji/7_95.png | Bin 1275 -> 1338 bytes TMessagesProj/src/main/assets/emoji/7_96.png | Bin 1014 -> 1275 bytes TMessagesProj/src/main/assets/emoji/7_97.png | Bin 1401 -> 1014 bytes TMessagesProj/src/main/assets/emoji/7_98.png | Bin 1165 -> 1401 bytes TMessagesProj/src/main/assets/emoji/7_99.png | Bin 1010 -> 1165 bytes TMessagesProj/src/main/assets/night.attheme | 1 + .../widget/ChatListItemAnimator.java | 6 +- .../widget/DefaultItemAnimator.java | 4 +- .../recyclerview/widget/RecyclerView.java | 8 + .../telegram/messenger/AccountInstance.java | 4 + .../telegram/messenger/AndroidUtilities.java | 129 +- .../telegram/messenger/ApplicationLoader.java | 18 +- .../org/telegram/messenger/BuildVars.java | 4 +- .../org/telegram/messenger/ChatObject.java | 376 + .../messenger/ContactsController.java | 3 +- .../telegram/messenger/DocumentObject.java | 55 + .../messenger/DownloadController.java | 3 +- .../java/org/telegram/messenger/Emoji.java | 25 +- .../org/telegram/messenger/EmojiData.java | 658 +- .../org/telegram/messenger/EmuDetector.java | 3 + .../messenger/EmuInputDevicesDetector.java | 62 + .../org/telegram/messenger/FileLoader.java | 18 +- .../telegram/messenger/FileRefController.java | 11 - .../messenger/GcmPushListenerService.java | 20 +- .../org/telegram/messenger/ImageLoader.java | 60 +- .../org/telegram/messenger/ImageLocation.java | 8 +- .../org/telegram/messenger/ImageReceiver.java | 44 +- .../telegram/messenger/LocaleController.java | 4 +- .../messenger/LocationController.java | 3 + .../telegram/messenger/MediaController.java | 155 +- .../messenger/MediaDataController.java | 197 +- .../org/telegram/messenger/MessageObject.java | 380 +- .../messenger/MessagesController.java | 754 +- .../telegram/messenger/MessagesStorage.java | 300 +- .../org/telegram/messenger/NativeLoader.java | 2 +- .../messenger/NotificationCenter.java | 9 + .../messenger/NotificationsController.java | 755 +- .../NotificationsDisabledReceiver.java | 58 + .../messenger/SendMessagesHelper.java | 182 +- .../org/telegram/messenger/SharedConfig.java | 24 +- .../Components => messenger}/SvgHelper.java | 171 +- .../video/MediaCodecVideoConvertor.java | 4 +- .../org/telegram/messenger/voip/Instance.java | 74 + .../messenger/voip/NativeInstance.java | 76 + .../messenger/voip/VoIPBaseService.java | 389 +- .../telegram/messenger/voip/VoIPService.java | 665 +- .../telegram/tgnet/ConnectionsManager.java | 50 +- .../main/java/org/telegram/tgnet/TLRPC.java | 2544 ++- .../ui/ActionBar/ActionBarLayout.java | 50 +- .../ui/ActionBar/ActionBarMenuItem.java | 46 +- .../ui/ActionBar/ActionBarMenuSubItem.java | 50 +- .../ui/ActionBar/ActionBarPopupWindow.java | 35 +- .../ui/ActionBar/AdjustPanLayoutHelper.java | 40 +- .../telegram/ui/ActionBar/AlertDialog.java | 70 +- .../telegram/ui/ActionBar/BaseFragment.java | 8 +- .../telegram/ui/ActionBar/BottomSheet.java | 27 +- .../java/org/telegram/ui/ActionBar/Theme.java | 287 +- .../telegram/ui/Adapters/DialogsAdapter.java | 147 +- .../ui/Adapters/DialogsSearchAdapter.java | 29 +- .../ui/Adapters/DrawerLayoutAdapter.java | 36 +- .../org/telegram/ui/Adapters/FiltersView.java | 4 +- .../telegram/ui/Adapters/MentionsAdapter.java | 2 +- .../telegram/ui/Adapters/SearchAdapter.java | 55 +- .../ui/Adapters/SearchAdapterHelper.java | 67 +- .../telegram/ui/Adapters/StickersAdapter.java | 33 +- .../ui/Adapters/StickersSearchAdapter.java | 3 +- .../org/telegram/ui/CacheControlActivity.java | 69 +- .../ui/Cells/ArchivedStickerSetCell.java | 19 +- .../org/telegram/ui/Cells/ChatActionCell.java | 2 +- .../telegram/ui/Cells/ChatMessageCell.java | 48 +- .../org/telegram/ui/Cells/CheckBoxCell.java | 2 +- .../telegram/ui/Cells/ContextLinkCell.java | 8 +- .../org/telegram/ui/Cells/DialogCell.java | 379 +- .../ui/Cells/FeaturedStickerSetCell.java | 19 +- .../ui/Cells/FeaturedStickerSetCell2.java | 19 +- .../telegram/ui/Cells/GraySectionCell.java | 10 + .../ui/Cells/GroupCallInvitedCell.java | 132 + .../telegram/ui/Cells/GroupCallTextCell.java | 252 + .../telegram/ui/Cells/GroupCallUserCell.java | 620 + .../telegram/ui/Cells/ManageChatTextCell.java | 16 +- .../telegram/ui/Cells/ManageChatUserCell.java | 37 +- .../ui/Cells/NotificationsCheckCell.java | 4 +- .../ui/Cells/StatisticPostInfoCell.java | 9 +- .../org/telegram/ui/Cells/StickerCell.java | 17 +- .../telegram/ui/Cells/StickerEmojiCell.java | 21 +- .../org/telegram/ui/Cells/StickerSetCell.java | 19 +- .../org/telegram/ui/ChangeBioActivity.java | 17 +- .../telegram/ui/ChangeUsernameActivity.java | 6 +- .../telegram/ui/ChannelAdminLogActivity.java | 8 +- .../telegram/ui/ChannelCreateActivity.java | 7 +- .../ui/Charts/view_data/ChartHeaderView.java | 9 +- .../Charts/view_data/LegendSignatureView.java | 11 +- .../java/org/telegram/ui/ChatActivity.java | 1278 +- .../telegram/ui/ChatActivityEnterTopView.java | 116 + .../org/telegram/ui/ChatEditTypeActivity.java | 6 +- .../telegram/ui/ChatRightsEditActivity.java | 26 +- .../org/telegram/ui/ChatUsersActivity.java | 309 +- .../ui/Components/AdminLogFilterAlert.java | 23 +- .../telegram/ui/Components/AlertsCreator.java | 223 +- .../ui/Components/AnimatedFileDrawable.java | 34 +- .../ui/Components/AudioPlayerAlert.java | 2 +- .../Components/AudioVisualizerDrawable.java | 15 +- .../ui/Components/AvatarDrawable.java | 2 +- .../ui/Components/AvatarsImageView.java | 425 + .../telegram/ui/Components/BlobDrawable.java | 153 + .../org/telegram/ui/Components/Bulletin.java | 208 +- .../ui/Components/BulletinFactory.java | 135 +- .../ui/Components/ChatActivityEnterView.java | 638 +- .../ui/Components/ChatAttachAlert.java | 132 +- .../ChatAttachAlertLocationLayout.java | 2 +- .../ChatAttachAlertPhotoLayout.java | 10 + .../ui/Components/ChatAvatarContainer.java | 13 + .../ui/Components/ChatGreetingsView.java | 5 +- .../ui/Components/CheckBoxSquare.java | 21 +- .../CodepointsLengthInputFilter.java | 36 + .../ui/Components/ContactsEmptyView.java | 3 +- .../telegram/ui/Components/Crop/CropView.java | 4 +- .../ui/Components/EditTextBoldCursor.java | 111 +- .../ui/Components/EllipsizeSpanAnimator.java | 16 +- .../ui/Components/EmbedBottomSheet.java | 15 +- .../org/telegram/ui/Components/EmojiView.java | 47 +- .../FillLastLinearLayoutManager.java | 19 +- .../ui/Components/FilterTabsView.java | 521 +- .../ui/Components/FlickerLoadingView.java | 106 +- .../ui/Components/FragmentContextView.java | 797 +- .../FragmentContextViewWavesDrawable.java | 434 + .../telegram/ui/Components/GroupCallPip.java | 1037 + .../ui/Components/GroupCallPipAlertView.java | 392 + .../ui/Components/GroupCallPipButton.java | 531 + .../ui/Components/GroupVoipInviteAlert.java | 1367 ++ .../ui/Components/InstantCameraView.java | 74 +- .../telegram/ui/Components/LayoutHelper.java | 2 +- .../ui/Components/LineBlobDrawable.java | 106 + .../ui/Components/LoadingStickerDrawable.java | 12 +- .../ui/Components/NumberTextView.java | 37 +- .../Components/Paint/Views/ColorPicker.java | 10 +- .../ui/Components/PhonebookShareAlert.java | 42 +- .../PhotoViewerCaptionEnterView.java | 169 +- .../telegram/ui/Components/PipVideoView.java | 13 +- .../ui/Components/ProfileGalleryView.java | 8 +- .../ui/Components/RLottieDrawable.java | 23 +- .../ui/Components/RadialProgressView.java | 86 +- .../ui/Components/RecyclerListView.java | 13 +- .../ui/Components/ScrollSlidingTabStrip.java | 15 +- .../Components/ScrollSlidingTextTabStrip.java | 146 +- .../ui/Components/SearchViewPager.java | 26 +- .../telegram/ui/Components/SeekBarView.java | 2 +- .../telegram/ui/Components/ShareAlert.java | 25 +- .../ui/Components/SharedMediaLayout.java | 998 +- .../ui/Components/StickerEmptyView.java | 71 +- .../ui/Components/StickerMasksAlert.java | 18 +- .../Components/StickerSetBulletinLayout.java | 6 +- .../telegram/ui/Components/StickersAlert.java | 110 +- .../ui/Components/ThemePreviewDrawable.java | 1 + .../ui/Components/TrendingStickersLayout.java | 6 +- .../org/telegram/ui/Components/UndoView.java | 89 +- .../telegram/ui/Components/VideoPlayer.java | 2 +- .../ui/{ => Components}/ViewPagerFixed.java | 5 +- .../telegram/ui/Components/WaveDrawable.java | 366 + .../ui/Components/voip/VoIPButtonsLayout.java | 39 +- .../ui/Components/voip/VoIPHelper.java | 148 +- .../voip/VoIPNotificationsLayout.java | 3 +- .../ui/Components/voip/VoIPPiPView.java | 11 +- .../Components/voip/VoIPStatusTextView.java | 5 +- .../ui/Components/voip/VoIPToggleButton.java | 125 +- .../org/telegram/ui/ContactsActivity.java | 339 +- .../org/telegram/ui/ContentPreviewViewer.java | 29 +- .../org/telegram/ui/DataSettingsActivity.java | 72 +- .../java/org/telegram/ui/DialogsActivity.java | 353 +- .../org/telegram/ui/FilteredSearchView.java | 58 +- .../org/telegram/ui/GroupCallActivity.java | 2872 +++ .../org/telegram/ui/GroupCreateActivity.java | 163 +- .../org/telegram/ui/GroupInviteActivity.java | 4 +- .../telegram/ui/LanguageSelectActivity.java | 3 + .../java/org/telegram/ui/LaunchActivity.java | 243 +- .../java/org/telegram/ui/LoginActivity.java | 1 + .../java/org/telegram/ui/MediaActivity.java | 370 +- .../telegram/ui/MessageStatisticActivity.java | 11 +- .../NotificationsCustomSettingsActivity.java | 1 + .../org/telegram/ui/PasscodeActivity.java | 4 +- .../org/telegram/ui/PeopleNearbyActivity.java | 2 +- .../telegram/ui/PhotoAlbumPickerActivity.java | 5 +- .../org/telegram/ui/PhotoPickerActivity.java | 2 +- .../java/org/telegram/ui/PhotoViewer.java | 417 +- .../java/org/telegram/ui/ProfileActivity.java | 781 +- .../ui/ProfileNotificationsActivity.java | 1 + .../org/telegram/ui/StatisticActivity.java | 17 +- .../org/telegram/ui/StickersActivity.java | 4 +- .../org/telegram/ui/ThemeSetUrlActivity.java | 6 +- .../java/org/telegram/ui/VoIPFragment.java | 81 +- .../telegram/ui/VoIPPermissionActivity.java | 2 +- .../java/org/webrtc/AndroidVideoDecoder.java | 4 - .../main/java/org/webrtc/CameraSession.java | 18 + .../org/webrtc/CandidatePairChangeEvent.java | 12 +- .../main/java/org/webrtc/EncodedImage.java | 17 +- .../java/org/webrtc/HardwareVideoEncoder.java | 2 +- .../webrtc/HardwareVideoEncoderFactory.java | 13 +- .../main/java/org/webrtc/MediaCodecUtils.java | 26 + .../webrtc/MediaCodecVideoDecoderFactory.java | 13 +- .../org/webrtc/NetworkMonitorAutoDetect.java | 5 +- .../main/java/org/webrtc/RtpTransceiver.java | 6 +- .../org/webrtc/ScreenCapturerAndroid.java | 5 + .../java/org/webrtc/SessionDescription.java | 3 +- .../java/org/webrtc/SurfaceTextureHelper.java | 6 +- .../webrtc/audio/JavaAudioDeviceModule.java | 34 +- .../org/webrtc/audio/WebRtcAudioRecord.java | 82 +- .../org/webrtc/audio/WebRtcAudioTrack.java | 38 +- .../voiceengine/WebRtcAudioEffects.java | 6 +- .../voiceengine/WebRtcAudioManager.java | 2 +- .../main/res/drawable-hdpi/menu_nearby.png | Bin 0 -> 1106 bytes .../main/res/drawable-hdpi/menu_nearby_ny.png | Bin 0 -> 1195 bytes .../main/res/drawable-hdpi/msg_endcall.png | Bin 0 -> 725 bytes .../main/res/drawable-hdpi/msg_invited.png | Bin 0 -> 873 bytes .../res/drawable-hdpi/msg_photoeditor.png | Bin 0 -> 741 bytes .../main/res/drawable-hdpi/msg_replace.png | Bin 0 -> 1002 bytes .../main/res/drawable-hdpi/msg_sendphoto.png | Bin 0 -> 808 bytes .../res/drawable-hdpi/msg_voice_muted.png | Bin 0 -> 1075 bytes .../main/res/drawable-hdpi/msg_voice_pip.png | Bin 0 -> 557 bytes .../res/drawable-hdpi/msg_voice_unmuted.png | Bin 0 -> 864 bytes .../main/res/drawable-hdpi/msg_voicechat.png | Bin 0 -> 818 bytes .../res/drawable-hdpi/voice_muted_large.png | Bin 0 -> 1492 bytes .../res/drawable-hdpi/voice_unmuted_large.png | Bin 0 -> 1141 bytes .../res/drawable-hdpi/voicechat_active.png | Bin 0 -> 886 bytes .../res/drawable-hdpi/voicechat_muted.png | Bin 0 -> 711 bytes .../main/res/drawable-mdpi/menu_nearby.png | Bin 0 -> 763 bytes .../main/res/drawable-mdpi/menu_nearby_ny.png | Bin 0 -> 768 bytes .../main/res/drawable-mdpi/msg_endcall.png | Bin 0 -> 518 bytes .../main/res/drawable-mdpi/msg_invited.png | Bin 0 -> 619 bytes .../res/drawable-mdpi/msg_photoeditor.png | Bin 0 -> 528 bytes .../main/res/drawable-mdpi/msg_replace.png | Bin 0 -> 656 bytes .../main/res/drawable-mdpi/msg_sendphoto.png | Bin 0 -> 521 bytes .../res/drawable-mdpi/msg_voice_muted.png | Bin 0 -> 695 bytes .../main/res/drawable-mdpi/msg_voice_pip.png | Bin 0 -> 449 bytes .../res/drawable-mdpi/msg_voice_unmuted.png | Bin 0 -> 598 bytes .../main/res/drawable-mdpi/msg_voicechat.png | Bin 0 -> 592 bytes .../res/drawable-mdpi/voice_muted_large.png | Bin 0 -> 939 bytes .../res/drawable-mdpi/voice_unmuted_large.png | Bin 0 -> 683 bytes .../res/drawable-mdpi/voicechat_active.png | Bin 0 -> 581 bytes .../res/drawable-mdpi/voicechat_muted.png | Bin 0 -> 516 bytes .../main/res/drawable-xhdpi/menu_nearby.png | Bin 0 -> 1515 bytes .../res/drawable-xhdpi/menu_nearby_ny.png | Bin 0 -> 1590 bytes .../main/res/drawable-xhdpi/msg_endcall.png | Bin 0 -> 988 bytes .../main/res/drawable-xhdpi/msg_invited.png | Bin 0 -> 1149 bytes .../res/drawable-xhdpi/msg_photoeditor.png | Bin 0 -> 916 bytes .../main/res/drawable-xhdpi/msg_replace.png | Bin 0 -> 1122 bytes .../main/res/drawable-xhdpi/msg_sendphoto.png | Bin 0 -> 993 bytes .../res/drawable-xhdpi/msg_voice_muted.png | Bin 0 -> 1417 bytes .../main/res/drawable-xhdpi/msg_voice_pip.png | Bin 0 -> 711 bytes .../res/drawable-xhdpi/msg_voice_unmuted.png | Bin 0 -> 1116 bytes .../main/res/drawable-xhdpi/msg_voicechat.png | Bin 0 -> 1063 bytes .../res/drawable-xhdpi/voice_muted_large.png | Bin 0 -> 1920 bytes .../drawable-xhdpi/voice_unmuted_large.png | Bin 0 -> 1422 bytes .../res/drawable-xhdpi/voicechat_active.png | Bin 0 -> 1173 bytes .../res/drawable-xhdpi/voicechat_muted.png | Bin 0 -> 928 bytes .../main/res/drawable-xxhdpi/menu_nearby.png | Bin 0 -> 2197 bytes .../res/drawable-xxhdpi/menu_nearby_ny.png | Bin 0 -> 2419 bytes .../main/res/drawable-xxhdpi/msg_endcall.png | Bin 0 -> 1367 bytes .../main/res/drawable-xxhdpi/msg_invited.png | Bin 0 -> 1485 bytes .../res/drawable-xxhdpi/msg_photoeditor.png | Bin 0 -> 1423 bytes .../main/res/drawable-xxhdpi/msg_replace.png | Bin 0 -> 1490 bytes .../res/drawable-xxhdpi/msg_sendphoto.png | Bin 0 -> 1509 bytes .../res/drawable-xxhdpi/msg_voice_muted.png | Bin 0 -> 2018 bytes .../res/drawable-xxhdpi/msg_voice_pip.png | Bin 0 -> 967 bytes .../res/drawable-xxhdpi/msg_voice_unmuted.png | Bin 0 -> 1684 bytes .../res/drawable-xxhdpi/msg_voicechat.png | Bin 0 -> 1351 bytes .../res/drawable-xxhdpi/voice_muted_large.png | Bin 0 -> 3045 bytes .../drawable-xxhdpi/voice_unmuted_large.png | Bin 0 -> 2314 bytes .../res/drawable-xxhdpi/voicechat_active.png | Bin 0 -> 1935 bytes .../res/drawable-xxhdpi/voicechat_muted.png | Bin 0 -> 1643 bytes .../main/res/raw/group_pip_delete_icon.json | 1 + TMessagesProj/src/main/res/raw/ic_ban.json | 1 + .../src/main/res/raw/ic_download.json | 2 +- .../src/main/res/raw/ic_save_to_gallery.json | 1 + .../src/main/res/raw/ic_save_to_music.json | 1 + TMessagesProj/src/main/res/raw/ic_unban.json | 1 + .../src/main/res/raw/pip_video_request.svg | 3 + .../src/main/res/raw/pip_voice_request.svg | 3 + .../src/main/res/raw/voice_muted.json | 1 + .../src/main/res/raw/voice_outlined.json | 1 + .../src/main/res/raw/voicechat_connecting.mp3 | Bin 0 -> 65496 bytes .../src/main/res/raw/voicechat_join.mp3 | Bin 0 -> 18240 bytes .../src/main/res/raw/voicechat_leave.mp3 | Bin 0 -> 9600 bytes .../src/main/res/raw/voip_group_removed.json | 1 + .../src/main/res/raw/voip_invite.json | 1 + .../src/main/res/raw/voip_muted.json | 1 + .../src/main/res/raw/voip_unmuted.json | 1 + .../main/res/raw/write_contacts_fab_icon.json | 1 + .../raw/write_contacts_fab_icon_reverse.json | 1 + TMessagesProj/src/main/res/values/ids.xml | 1 + TMessagesProj/src/main/res/values/strings.xml | 116 + build.gradle | 2 +- 4526 files changed, 73002 insertions(+), 104030 deletions(-) create mode 100644 TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.c create mode 100644 TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.h create mode 100644 TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.cc create mode 100644 TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h create mode 100644 TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_ext_ratectrl.h rename TMessagesProj/jni/{voip/webrtc/modules/desktop_capture/screen_capturer_null.cc => third_party/libvpx/source/libvpx/vpx_ports/mips.h} (52%) create mode 100644 TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/mips_cpudetect.c create mode 100644 TMessagesProj/jni/third_party/libyuv/include/libyuv/scale_uv.h create mode 100644 TMessagesProj/jni/third_party/libyuv/source/scale_uv.cc create mode 100644 TMessagesProj/jni/voip/tgcalls/group/GroupInstanceImpl.cpp create mode 100644 TMessagesProj/jni/voip/tgcalls/group/GroupInstanceImpl.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/audio/audio_frame_processor.h rename TMessagesProj/jni/voip/webrtc/{pc => api}/media_stream_track.h (88%) rename TMessagesProj/jni/voip/webrtc/{rtc_base => api}/numerics/samples_stats_counter.cc (97%) rename TMessagesProj/jni/voip/webrtc/{rtc_base => api}/numerics/samples_stats_counter.h (92%) create mode 100644 TMessagesProj/jni/voip/webrtc/api/test/create_peer_connection_quality_test_frame_generator.cc create mode 100644 TMessagesProj/jni/voip/webrtc/api/test/create_peer_connection_quality_test_frame_generator.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/test/frame_generator_interface.cc create mode 100644 TMessagesProj/jni/voip/webrtc/api/test/mock_data_channel.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/test/mock_media_stream_interface.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/test/mock_rtp_transceiver.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/transport/sctp_transport_factory_interface.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/video/nv12_buffer.cc create mode 100644 TMessagesProj/jni/voip/webrtc/api/video/nv12_buffer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/api/video/test/mock_recordable_encoded_frame.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/video/video_layers_allocation.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/video_codecs/spatial_layer.cc create mode 100644 TMessagesProj/jni/voip/webrtc/api/video_codecs/spatial_layer.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/voip/voip_dtmf.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/voip/voip_statistics.h create mode 100644 TMessagesProj/jni/voip/webrtc/api/voip/voip_volume_control.h delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/fake_task.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/fake_task.h delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_domain.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_domain.h delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_message_pump.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_message_pump.h delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/sequence_manager_for_test.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/sequence_manager_for_test.h delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_queue.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_queue.h delete mode 100644 TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_time_observer.h create mode 100644 TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_avx2.cc create mode 100644 TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_avx2.h create mode 100644 TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler_avx2.cc create mode 100644 TMessagesProj/jni/voip/webrtc/common_audio/vad/vad_unittest.h create mode 100644 TMessagesProj/jni/voip/webrtc/common_video/frame_counts.h create mode 100644 TMessagesProj/jni/voip/webrtc/common_video/h264/OWNERS delete mode 100644 TMessagesProj/jni/voip/webrtc/common_video/i420_buffer_pool.cc rename TMessagesProj/jni/voip/webrtc/common_video/include/{i420_buffer_pool.h => video_frame_buffer_pool.h} (53%) create mode 100644 TMessagesProj/jni/voip/webrtc/common_video/video_frame_buffer_pool.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log.pb.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log.pb.h delete mode 100644 TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h create mode 100644 TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc create mode 100644 TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/async_audio_processing/async_audio_processing.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/async_audio_processing/async_audio_processing.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_fec_test.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_buffer_level_filter.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_delay_manager.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl_avx2.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/fft_data_avx2.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter_avx2.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/transparent_mode.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/transparent_mode.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/vector_math_avx2.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/agc2_common.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_info.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/test/goog_cc_printer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/OWNERS delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropped_desktop_frame.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropped_desktop_frame.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_options.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_options.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_types.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_wrapper.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_wrapper.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_generator.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_generator.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_rotation.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_rotation.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_win.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_win.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_geometry.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_geometry.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_region.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_region.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_block.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_block.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_vector_sse2.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_vector_sse2.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fake_desktop_capturer.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fake_desktop_capturer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_application_handler.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_application_handler.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_window_detector.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_window_detector.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_x11.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_x11.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/shared_x_display.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/shared_x_display.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_x11.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_x11.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_finder_x11.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_finder_x11.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_list_utils.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_list_utils.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_atom_cache.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_atom_cache.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_error_trap.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_error_trap.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_window_property.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_window_property.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mock_desktop_capturer_callback.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mock_desktop_capturer_callback.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/resolution_tracker.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/resolution_tracker.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/rgba_color.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/rgba_color.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capture_frame_queue.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_darwin.mm delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_helper.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_helper.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_linux.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_win.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_linux.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_lock_posix.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_lock_posix.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_mac.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_win.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_desktop_frame.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_desktop_frame.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_memory.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_memory.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_linux.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_mac.mm delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_null.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_win.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_mac.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_mac.mm delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_win.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_win.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/include/module_common_types.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t2.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t2.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t3.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t3.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t1.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t3.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t3.h delete mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_s2t1.cc rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/create_scalability_structure.cc (64%) rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/create_scalability_structure.h (72%) create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.h rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/scalability_structure_l2t1h.cc (93%) rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/scalability_structure_l2t1h.h (63%) create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2_key_shift.cc rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/scalability_structure_l2t2_key_shift.h (57%) create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t1.cc rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/scalability_structure_l3t1.h (50%) create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_s2t1.cc rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/scalability_structure_s2t1.h (61%) create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_test_helpers.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_test_helpers.h rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/scalable_video_controller.h (91%) rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/scalable_video_controller_no_layering.cc (79%) rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/av1 => svc}/scalable_video_controller_no_layering.h (66%) rename TMessagesProj/jni/voip/webrtc/modules/video_coding/{codecs/vp9 => svc}/svc_rate_allocator.cc (82%) create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/svc_rate_allocator.h create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_test_fixture_impl.cc create mode 100644 TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_test_fixture_impl.h create mode 100644 TMessagesProj/jni/voip/webrtc/pc/connection_context.cc create mode 100644 TMessagesProj/jni/voip/webrtc/pc/connection_context.h create mode 100644 TMessagesProj/jni/voip/webrtc/pc/peer_connection_adaptation_integrationtest.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/pc/peer_connection_integrationtest.cc create mode 100644 TMessagesProj/jni/voip/webrtc/pc/peer_connection_message_handler.cc create mode 100644 TMessagesProj/jni/voip/webrtc/pc/peer_connection_message_handler.h create mode 100644 TMessagesProj/jni/voip/webrtc/pc/rtp_transmission_manager.cc create mode 100644 TMessagesProj/jni/voip/webrtc/pc/rtp_transmission_manager.h create mode 100644 TMessagesProj/jni/voip/webrtc/pc/sdp_offer_answer.cc create mode 100644 TMessagesProj/jni/voip/webrtc/pc/sdp_offer_answer.h create mode 100644 TMessagesProj/jni/voip/webrtc/pc/sdp_state_provider.h create mode 100644 TMessagesProj/jni/voip/webrtc/pc/stats_collector_interface.h create mode 100644 TMessagesProj/jni/voip/webrtc/pc/transceiver_list.cc create mode 100644 TMessagesProj/jni/voip/webrtc/pc/transceiver_list.h create mode 100644 TMessagesProj/jni/voip/webrtc/pc/usage_pattern.cc create mode 100644 TMessagesProj/jni/voip/webrtc/pc/usage_pattern.h create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/callback.h.pump create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/callback_list.cc create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/callback_list.h create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/gunit.cc create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/gunit.h delete mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/stringize_macros.h delete mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_posix.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_posix.h delete mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_win.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_win.h delete mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.cc delete mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.h create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/system/assume.h create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/untyped_function.h create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/win/get_activation_factory.cc create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/win/get_activation_factory.h create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/win/hstring.cc create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/win/hstring.h create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/win/scoped_com_initializer.cc create mode 100644 TMessagesProj/jni/voip/webrtc/rtc_base/win/scoped_com_initializer.h delete mode 100644 TMessagesProj/jni/voip/webrtc/sdk/android/native_api/base/network_monitor.h delete mode 100644 TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/DEPS delete mode 100644 TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/DEPS rename TMessagesProj/jni/voip/webrtc/system_wrappers/source/{cpu_features_android.c => cpu_features_android.cc} (85%) rename TMessagesProj/jni/voip/webrtc/system_wrappers/source/{cpu_features_linux.c => cpu_features_linux.cc} (87%) create mode 100644 TMessagesProj/jni/voip/webrtc/video/adaptation/balanced_constraint.cc create mode 100644 TMessagesProj/jni/voip/webrtc/video/adaptation/balanced_constraint.h create mode 100644 TMessagesProj/jni/voip/webrtc/video/adaptation/bitrate_constraint.cc create mode 100644 TMessagesProj/jni/voip/webrtc/video/adaptation/bitrate_constraint.h create mode 100644 TMessagesProj/jni/voip/webrtc/video/alignment_adjuster.cc create mode 100644 TMessagesProj/jni/voip/webrtc/video/alignment_adjuster.h create mode 100644 TMessagesProj/src/main/assets/emoji/0_1620.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1621.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1622.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1623.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1624.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1625.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1626.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1627.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1628.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1629.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1630.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1631.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1632.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1633.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1634.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1635.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1636.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1637.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1638.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1639.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1640.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1641.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1642.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1643.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1644.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1645.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1646.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1647.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1648.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1649.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1650.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1651.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1652.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1653.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1654.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1655.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1656.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1657.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1658.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1659.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1660.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1661.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1662.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1663.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1664.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1665.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1666.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1667.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1668.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1669.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1670.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1671.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1672.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1673.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1674.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1675.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1676.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1677.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1678.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1679.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1680.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1681.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1682.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1683.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1684.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1685.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1686.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1687.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1688.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1689.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1690.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1691.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1692.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1693.png create mode 100644 TMessagesProj/src/main/assets/emoji/0_1694.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_184.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_185.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_186.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_187.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_188.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_189.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_190.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_191.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_192.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_193.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_194.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_195.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_196.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_197.png create mode 100644 TMessagesProj/src/main/assets/emoji/1_198.png create mode 100644 TMessagesProj/src/main/assets/emoji/2_115.png create mode 100644 TMessagesProj/src/main/assets/emoji/2_116.png create mode 100644 TMessagesProj/src/main/assets/emoji/2_117.png create mode 100644 TMessagesProj/src/main/assets/emoji/2_118.png create mode 100644 TMessagesProj/src/main/assets/emoji/2_119.png create mode 100644 TMessagesProj/src/main/assets/emoji/2_120.png create mode 100644 TMessagesProj/src/main/assets/emoji/2_121.png create mode 100644 TMessagesProj/src/main/assets/emoji/2_122.png create mode 100644 TMessagesProj/src/main/assets/emoji/3_328.png create mode 100644 TMessagesProj/src/main/assets/emoji/3_329.png create mode 100644 TMessagesProj/src/main/assets/emoji/3_330.png create mode 100644 TMessagesProj/src/main/assets/emoji/3_331.png create mode 100644 TMessagesProj/src/main/assets/emoji/4_125.png create mode 100644 TMessagesProj/src/main/assets/emoji/4_126.png create mode 100644 TMessagesProj/src/main/assets/emoji/4_127.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_207.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_208.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_209.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_210.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_211.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_212.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_213.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_214.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_215.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_216.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_217.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_218.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_219.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_220.png create mode 100644 TMessagesProj/src/main/assets/emoji/5_221.png create mode 100644 TMessagesProj/src/main/assets/emoji/6_288.png create mode 100644 TMessagesProj/src/main/assets/emoji/6_289.png create mode 100644 TMessagesProj/src/main/assets/emoji/7_258.png create mode 100644 TMessagesProj/src/main/java/org/telegram/messenger/EmuInputDevicesDetector.java create mode 100644 TMessagesProj/src/main/java/org/telegram/messenger/NotificationsDisabledReceiver.java rename TMessagesProj/src/main/java/org/telegram/{ui/Components => messenger}/SvgHelper.java (87%) create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/GroupCallInvitedCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/GroupCallTextCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/GroupCallUserCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/ChatActivityEnterTopView.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarsImageView.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/BlobDrawable.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/CodepointsLengthInputFilter.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/FragmentContextViewWavesDrawable.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/GroupCallPip.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/GroupCallPipAlertView.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/GroupCallPipButton.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/GroupVoipInviteAlert.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/LineBlobDrawable.java rename TMessagesProj/src/main/java/org/telegram/ui/{ => Components}/ViewPagerFixed.java (99%) create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/WaveDrawable.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/GroupCallActivity.java create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/menu_nearby.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/menu_nearby_ny.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_endcall.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_invited.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_photoeditor.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_replace.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_sendphoto.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_voice_muted.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_voice_pip.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_voice_unmuted.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_voicechat.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/voice_muted_large.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/voice_unmuted_large.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/voicechat_active.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/voicechat_muted.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/menu_nearby.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/menu_nearby_ny.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_endcall.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_invited.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_photoeditor.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_replace.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_sendphoto.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_voice_muted.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_voice_pip.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_voice_unmuted.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_voicechat.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/voice_muted_large.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/voice_unmuted_large.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/voicechat_active.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/voicechat_muted.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/menu_nearby.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/menu_nearby_ny.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_endcall.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_invited.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_photoeditor.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_replace.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_sendphoto.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_voice_muted.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_voice_pip.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_voice_unmuted.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_voicechat.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/voice_muted_large.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/voice_unmuted_large.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/voicechat_active.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/voicechat_muted.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/menu_nearby.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/menu_nearby_ny.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_endcall.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_invited.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_photoeditor.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_replace.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_sendphoto.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_voice_muted.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_voice_pip.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_voice_unmuted.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_voicechat.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/voice_muted_large.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/voice_unmuted_large.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/voicechat_active.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/voicechat_muted.png create mode 100644 TMessagesProj/src/main/res/raw/group_pip_delete_icon.json create mode 100644 TMessagesProj/src/main/res/raw/ic_ban.json create mode 100644 TMessagesProj/src/main/res/raw/ic_save_to_gallery.json create mode 100644 TMessagesProj/src/main/res/raw/ic_save_to_music.json create mode 100644 TMessagesProj/src/main/res/raw/ic_unban.json create mode 100644 TMessagesProj/src/main/res/raw/pip_video_request.svg create mode 100644 TMessagesProj/src/main/res/raw/pip_voice_request.svg create mode 100644 TMessagesProj/src/main/res/raw/voice_muted.json create mode 100644 TMessagesProj/src/main/res/raw/voice_outlined.json create mode 100644 TMessagesProj/src/main/res/raw/voicechat_connecting.mp3 create mode 100644 TMessagesProj/src/main/res/raw/voicechat_join.mp3 create mode 100644 TMessagesProj/src/main/res/raw/voicechat_leave.mp3 create mode 100644 TMessagesProj/src/main/res/raw/voip_group_removed.json create mode 100644 TMessagesProj/src/main/res/raw/voip_invite.json create mode 100644 TMessagesProj/src/main/res/raw/voip_muted.json create mode 100644 TMessagesProj/src/main/res/raw/voip_unmuted.json create mode 100644 TMessagesProj/src/main/res/raw/write_contacts_fab_icon.json create mode 100644 TMessagesProj/src/main/res/raw/write_contacts_fab_icon_reverse.json diff --git a/Dockerfile b/Dockerfile index b9886fbd8..b449368dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM gradle:6.5.0-jdk8 ENV ANDROID_SDK_URL https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip ENV ANDROID_API_LEVEL android-30 -ENV ANDROID_BUILD_TOOLS_VERSION 30.0.2 +ENV ANDROID_BUILD_TOOLS_VERSION 30.0.3 ENV ANDROID_HOME /usr/local/android-sdk-linux ENV ANDROID_NDK_VERSION 21.1.6352462 ENV ANDROID_VERSION 30 diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index e1456360c..3fb8cbc5e 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -12,24 +12,25 @@ configurations { configurations.all { exclude group: 'com.google.firebase', module: 'firebase-core' + exclude group: 'androidx.recyclerview', module: 'recyclerview' } dependencies { implementation 'androidx.core:core:1.3.2' implementation 'androidx.palette:palette:1.0.0' - implementation 'androidx.exifinterface:exifinterface:1.3.1' + implementation 'androidx.exifinterface:exifinterface:1.3.2' implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0' implementation 'androidx.multidex:multidex:2.0.1' implementation "androidx.sharetarget:sharetarget:1.0.0" compileOnly 'org.checkerframework:checker-qual:2.5.2' compileOnly 'org.checkerframework:checker-compat-qual:2.5.0' - implementation 'com.google.firebase:firebase-messaging:20.3.0' - implementation 'com.google.firebase:firebase-config:19.2.0' - implementation 'com.google.firebase:firebase-datatransport:17.0.8' + implementation 'com.google.firebase:firebase-messaging:21.0.1' + implementation 'com.google.firebase:firebase-config:20.0.2' + implementation 'com.google.firebase:firebase-datatransport:17.0.10' implementation 'com.google.firebase:firebase-appindexing:19.1.0' implementation 'com.google.android.gms:play-services-maps:17.0.0' - implementation 'com.google.android.gms:play-services-auth:18.1.0' + implementation 'com.google.android.gms:play-services-auth:19.0.0' implementation 'com.google.android.gms:play-services-vision:16.2.0' implementation 'com.google.android.gms:play-services-wearable:17.0.0' implementation 'com.google.android.gms:play-services-location:17.1.0' @@ -40,12 +41,12 @@ dependencies { implementation 'com.stripe:stripe-android:2.0.2' implementation files('libs/libgsaverification-client.aar') - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' } android { compileSdkVersion 30 - buildToolsVersion '30.0.2' + buildToolsVersion '30.0.3' ndkVersion "21.1.6352462" defaultConfig.applicationId = "org.telegram.messenger" @@ -97,9 +98,11 @@ android { jniDebuggable true signingConfig signingConfigs.debug applicationIdSuffix ".beta" - minifyEnabled true + minifyEnabled false + shrinkResources false multiDexEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + ndk.debugSymbolLevel = 'FULL' } /*debugAsan { @@ -139,6 +142,7 @@ android { minifyEnabled true multiDexEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + ndk.debugSymbolLevel = 'FULL' } release { @@ -149,6 +153,7 @@ android { shrinkResources false multiDexEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + ndk.debugSymbolLevel = 'FULL' } } @@ -285,7 +290,7 @@ android { } } - defaultConfig.versionCode = 2139 + defaultConfig.versionCode = 2195 applicationVariants.all { variant -> variant.outputs.all { output -> @@ -303,8 +308,8 @@ android { defaultConfig { minSdkVersion 16 - targetSdkVersion 28 - versionName "7.2.1" + targetSdkVersion 29 + versionName "7.3.0" vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi'] diff --git a/TMessagesProj/config/debug/AndroidManifest.xml b/TMessagesProj/config/debug/AndroidManifest.xml index 0add1a21d..c01d13c3b 100644 --- a/TMessagesProj/config/debug/AndroidManifest.xml +++ b/TMessagesProj/config/debug/AndroidManifest.xml @@ -26,6 +26,7 @@ android:hardwareAccelerated="@bool/useHardwareAcceleration" android:largeHeap="true" android:supportsRtl="false" + android:requestLegacyExternalStorage="true" tools:replace="android:supportsRtl"> diff --git a/TMessagesProj/config/debug/AndroidManifest_SDK23.xml b/TMessagesProj/config/debug/AndroidManifest_SDK23.xml index 500bbc0be..079cc4817 100644 --- a/TMessagesProj/config/debug/AndroidManifest_SDK23.xml +++ b/TMessagesProj/config/debug/AndroidManifest_SDK23.xml @@ -30,6 +30,7 @@ android:hardwareAccelerated="@bool/useHardwareAcceleration" android:largeHeap="true" android:supportsRtl="false" + android:requestLegacyExternalStorage="true" tools:replace="android:supportsRtl"> diff --git a/TMessagesProj/config/release/AndroidManifest.xml b/TMessagesProj/config/release/AndroidManifest.xml index 9600f7b57..7bb790100 100644 --- a/TMessagesProj/config/release/AndroidManifest.xml +++ b/TMessagesProj/config/release/AndroidManifest.xml @@ -27,6 +27,7 @@ android:hardwareAccelerated="@bool/useHardwareAcceleration" android:largeHeap="true" android:supportsRtl="false" + android:requestLegacyExternalStorage="true" tools:replace="android:supportsRtl"> diff --git a/TMessagesProj/config/release/AndroidManifest_SDK23.xml b/TMessagesProj/config/release/AndroidManifest_SDK23.xml index 0d58e3d78..093b6a195 100644 --- a/TMessagesProj/config/release/AndroidManifest_SDK23.xml +++ b/TMessagesProj/config/release/AndroidManifest_SDK23.xml @@ -30,6 +30,7 @@ android:hardwareAccelerated="@bool/useHardwareAcceleration" android:largeHeap="true" android:supportsRtl="false" + android:requestLegacyExternalStorage="true" tools:replace="android:supportsRtl"> diff --git a/TMessagesProj/jni/CMakeLists.txt b/TMessagesProj/jni/CMakeLists.txt index b22a566f5..9a0d4c89a 100644 --- a/TMessagesProj/jni/CMakeLists.txt +++ b/TMessagesProj/jni/CMakeLists.txt @@ -395,7 +395,7 @@ target_compile_definitions(sqlite PUBLIC #voip include(${CMAKE_HOME_DIRECTORY}/voip/CMakeLists.txt) -set(NATIVE_LIB "tmessages.34") +set(NATIVE_LIB "tmessages.35") #tmessages add_library(${NATIVE_LIB} SHARED @@ -642,7 +642,8 @@ target_sources(${NATIVE_LIB} PRIVATE third_party/libyuv/source/scale_neon64.cc third_party/libyuv/source/scale_win.cc third_party/libyuv/source/scale.cc - third_party/libyuv/source/video_common.cc) + third_party/libyuv/source/video_common.cc + third_party/libyuv/source/scale_uv.cc) target_include_directories(${NATIVE_LIB} PUBLIC opus/include diff --git a/TMessagesProj/jni/gifvideo.cpp b/TMessagesProj/jni/gifvideo.cpp index 90ac488a6..9a7a51c5a 100644 --- a/TMessagesProj/jni/gifvideo.cpp +++ b/TMessagesProj/jni/gifvideo.cpp @@ -290,7 +290,7 @@ extern "C" JNIEXPORT void JNICALL Java_org_telegram_ui_Components_AnimatedFileDr info->src = new char[len + 1]; memcpy(info->src, srcString, len); info->src[len] = '\0'; - if (srcString != 0) { + if (srcString != nullptr) { env->ReleaseStringUTFChars(src, srcString); } @@ -364,7 +364,7 @@ extern "C" JNIEXPORT void JNICALL Java_org_telegram_ui_Components_AnimatedFileDr dataArr[PARAM_NUM_WIDTH] = info->video_stream->codecpar->width; dataArr[PARAM_NUM_HEIGHT] = info->video_stream->codecpar->height; AVDictionaryEntry *rotate_tag = av_dict_get(info->video_stream->metadata, "rotate", NULL, 0); - if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) { + if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0") != 0) { char *tail; dataArr[PARAM_NUM_ROTATION] = (jint) av_strtod(rotate_tag->value, &tail); if (*tail) { @@ -373,7 +373,7 @@ extern "C" JNIEXPORT void JNICALL Java_org_telegram_ui_Components_AnimatedFileDr } else { dataArr[PARAM_NUM_ROTATION] = 0; } - if (info->video_stream->codecpar->codec_id == AV_CODEC_ID_H264) { + if (info->video_stream->codecpar->codec_id == AV_CODEC_ID_H264 || info->video_stream->codecpar->codec_id == AV_CODEC_ID_HEVC) { dataArr[PARAM_NUM_FRAMERATE] = (jint) av_q2d(info->video_stream->avg_frame_rate); } else { dataArr[PARAM_NUM_FRAMERATE] = (jint) av_q2d(info->video_stream->r_frame_rate); @@ -605,16 +605,19 @@ static inline void writeFrameToBitmap(JNIEnv *env, VideoInfo *info, jintArray da jint *dataArr = env->GetIntArrayElements(data, 0); int32_t wantedWidth; int32_t wantedHeight; + + AndroidBitmapInfo bitmapInfo; + AndroidBitmap_getInfo(env, bitmap, &bitmapInfo); + int32_t bitmapWidth = bitmapInfo.width; + int32_t bitmapHeight = bitmapInfo.height; if (dataArr != nullptr) { wantedWidth = dataArr[0]; wantedHeight = dataArr[1]; dataArr[3] = (jint) (1000 * info->frame->best_effort_timestamp * av_q2d(info->video_stream->time_base)); env->ReleaseIntArrayElements(data, dataArr, 0); } else { - AndroidBitmapInfo bitmapInfo; - AndroidBitmap_getInfo(env, bitmap, &bitmapInfo); - wantedWidth = bitmapInfo.width; - wantedHeight = bitmapInfo.height; + wantedWidth = bitmapWidth; + wantedHeight = bitmapHeight; } void *pixels; @@ -622,17 +625,17 @@ static inline void writeFrameToBitmap(JNIEnv *env, VideoInfo *info, jintArray da if (wantedWidth == info->frame->width && wantedHeight == info->frame->height || wantedWidth == info->frame->height && wantedHeight == info->frame->width) { if (info->sws_ctx == nullptr) { if (info->frame->format > AV_PIX_FMT_NONE && info->frame->format < AV_PIX_FMT_NB) { - info->sws_ctx = sws_getContext(info->frame->width, info->frame->height, (AVPixelFormat) info->frame->format, info->frame->width, info->frame->height, AV_PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL); + info->sws_ctx = sws_getContext(info->frame->width, info->frame->height, (AVPixelFormat) info->frame->format, bitmapWidth, bitmapHeight, AV_PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL); } else if (info->video_dec_ctx->pix_fmt > AV_PIX_FMT_NONE && info->video_dec_ctx->pix_fmt < AV_PIX_FMT_NB) { - info->sws_ctx = sws_getContext(info->video_dec_ctx->width, info->video_dec_ctx->height, info->video_dec_ctx->pix_fmt, info->video_dec_ctx->width, info->video_dec_ctx->height, AV_PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL); + info->sws_ctx = sws_getContext(info->video_dec_ctx->width, info->video_dec_ctx->height, info->video_dec_ctx->pix_fmt, bitmapWidth, bitmapHeight, AV_PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL); } } if (info->sws_ctx == nullptr || ((intptr_t) pixels) % 16 != 0) { if (info->frame->format == AV_PIX_FMT_YUV420P || info->frame->format == AV_PIX_FMT_YUVJ420P) { if (info->frame->colorspace == AVColorSpace::AVCOL_SPC_BT709) { - libyuv::H420ToARGB(info->frame->data[0], info->frame->linesize[0], info->frame->data[2], info->frame->linesize[2], info->frame->data[1], info->frame->linesize[1], (uint8_t *) pixels, info->frame->width * 4, info->frame->width, info->frame->height); + libyuv::H420ToARGB(info->frame->data[0], info->frame->linesize[0], info->frame->data[2], info->frame->linesize[2], info->frame->data[1], info->frame->linesize[1], (uint8_t *) pixels, bitmapWidth * 4, bitmapWidth, bitmapHeight); } else { - libyuv::I420ToARGB(info->frame->data[0], info->frame->linesize[0], info->frame->data[2], info->frame->linesize[2], info->frame->data[1], info->frame->linesize[1], (uint8_t *) pixels, info->frame->width * 4, info->frame->width, info->frame->height); + libyuv::I420ToARGB(info->frame->data[0], info->frame->linesize[0], info->frame->data[2], info->frame->linesize[2], info->frame->data[1], info->frame->linesize[1], (uint8_t *) pixels, bitmapWidth * 4, bitmapWidth, bitmapHeight); } } else if (info->frame->format == AV_PIX_FMT_BGRA) { libyuv::ABGRToARGB(info->frame->data[0], info->frame->linesize[0], (uint8_t *) pixels, info->frame->width * 4, info->frame->width, info->frame->height); diff --git a/TMessagesProj/jni/tgnet/Handshake.cpp b/TMessagesProj/jni/tgnet/Handshake.cpp index 9b378b401..f679b336f 100644 --- a/TMessagesProj/jni/tgnet/Handshake.cpp +++ b/TMessagesProj/jni/tgnet/Handshake.cpp @@ -206,7 +206,7 @@ inline bool factorizeValue(uint64_t what, uint32_t &p, uint32_t &q) { inline bool check_prime(BIGNUM *p) { int result = 0; - if (!BN_primality_test(&result, p, BN_prime_checks, bnContext, 0, NULL)) { + if (!BN_primality_test(&result, p, 64, bnContext, 0, NULL)) { if (LOGS_ENABLED) DEBUG_E("OpenSSL error at BN_primality_test"); return false; } diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/AUTHORS b/TMessagesProj/jni/third_party/libvpx/source/libvpx/AUTHORS index 3eb03e923..352c91fed 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/AUTHORS +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/AUTHORS @@ -25,6 +25,7 @@ Angie Chiang Aron Rosenberg Attila Nagy Birk Magnussen +Brian Foley Brion Vibber changjun.yang Charles 'Buck' Krasic @@ -33,6 +34,7 @@ Chi Yo Tsai chm Chris Cunningham Christian Duvivier +Clement Courbet Daniele Castagna Daniel Kang Dan Zhu @@ -91,6 +93,7 @@ John Koleszar Johnny Klonaris John Stark Jon Kunkee +Jorge E. Moreira Joshua Bleecher Snyder Joshua Litt Julia Robson @@ -125,6 +128,7 @@ Mirko Bonadei Moriyoshi Koizumi Morton Jonuschat Nathan E. Egge +Neil Birkbeck Nico Weber Niveditha Rau Parag Salasakar @@ -165,6 +169,7 @@ Shimon Doodkin Shiyou Yin Shubham Tandle Shunyao Li +Sreerenj Balachandran Stefan Holmer Suman Sunkara Supradeep T R @@ -185,6 +190,7 @@ Vignesh Venkatasubramanian Vitaly Buka Vlad Tsyrklevich Wan-Teh Chang +Wonkap Jang xiwei gu Yaowu Xu Yi Luo diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/CHANGELOG b/TMessagesProj/jni/third_party/libvpx/source/libvpx/CHANGELOG index 345d3dc4d..e731fc612 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/CHANGELOG +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/CHANGELOG @@ -1,3 +1,27 @@ +2020-07-29 v1.9.0 "Quacking Duck" + This release adds support for NV12, a separate library for rate control, as + well as incremental improvements. + + - Upgrading: + NV12 support is added to this release. + A new interface is added for VP9 rate control. The new library libvp9rc.a + must be linked by applications. + Googletest is updated to v1.10.0. + simple_encode.cc is compiled into a new library libsimple_encode.a with + CONFIG_RATE_CTRL. + + - Enhancement: + Various changes to improve VP9 SVC, rate control, quality and speed to real + time encoding. + + - Bug fixes: + Fix key frame update refresh simulcast flexible svc. + Fix to disable_16x16part speed feature for real time encoding. + Fix some signed integer overflows for VP9 rate control. + Fix initialization of delta_q_uv. + Fix condition in regulate_q for cyclic refresh. + Various fixes to dynamic resizing for VP9 SVC. + 2019-12-09 v1.8.2 "Pekin Duck" This release collects incremental improvements to many aspects of the library. diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/third_party/x86inc/README.libvpx b/TMessagesProj/jni/third_party/libvpx/source/libvpx/third_party/x86inc/README.libvpx index 36735ffbb..195654f7b 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/third_party/x86inc/README.libvpx +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/third_party/x86inc/README.libvpx @@ -1,5 +1,5 @@ URL: https://git.videolan.org/git/x264.git -Version: d23d18655249944c1ca894b451e2c82c7a584c62 +Version: 3e5aed95cc470f37e2db3e6506a8deb89b527720 License: ISC License File: LICENSE @@ -12,10 +12,8 @@ Get configuration from vpx_config.asm. Prefix functions with vpx by default. Manage name mangling (prefixing with '_') manually because 'PREFIX' does not exist in libvpx. -Expand PIC default to macho64 and respect CONFIG_PIC from libvpx -Set 'private_extern' visibility for macho targets. Copy PIC 'GLOBAL' macros from x86_abi_support.asm Use .text instead of .rodata on macho to avoid broken tables in PIC mode. -Use .text with no alignment for aout -Only use 'hidden' visibility with Chromium +Use .text with no alignment for aout. +Only use 'hidden' visibility with Chromium. Prefix ARCH_* with VPX_. diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/third_party/x86inc/x86inc.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/third_party/x86inc/x86inc.asm index 3d722fec0..3d55e921c 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/third_party/x86inc/x86inc.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/third_party/x86inc/x86inc.asm @@ -1,12 +1,12 @@ ;***************************************************************************** ;* x86inc.asm: x264asm abstraction layer ;***************************************************************************** -;* Copyright (C) 2005-2016 x264 project +;* Copyright (C) 2005-2019 x264 project ;* ;* Authors: Loren Merritt +;* Henrik Gramner ;* Anton Mitrofanov ;* Fiona Glaser -;* Henrik Gramner ;* ;* Permission to use, copy, modify, and/or distribute this software for any ;* purpose with or without fee is hereby granted, provided that the above @@ -67,19 +67,19 @@ %endif %define FORMAT_ELF 0 +%define FORMAT_MACHO 0 %ifidn __OUTPUT_FORMAT__,elf %define FORMAT_ELF 1 %elifidn __OUTPUT_FORMAT__,elf32 %define FORMAT_ELF 1 %elifidn __OUTPUT_FORMAT__,elf64 %define FORMAT_ELF 1 -%endif - -%define FORMAT_MACHO 0 -%ifidn __OUTPUT_FORMAT__,macho32 - %define FORMAT_MACHO 1 +%elifidn __OUTPUT_FORMAT__,macho + %define FORMAT_MACHO 1 +%elifidn __OUTPUT_FORMAT__,macho32 + %define FORMAT_MACHO 1 %elifidn __OUTPUT_FORMAT__,macho64 - %define FORMAT_MACHO 1 + %define FORMAT_MACHO 1 %endif ; Set PREFIX for libvpx builds. @@ -103,7 +103,11 @@ ; works around the issue. It appears to be specific to the way libvpx ; handles the tables. %macro SECTION_RODATA 0-1 16 - %ifidn __OUTPUT_FORMAT__,macho32 + %ifidn __OUTPUT_FORMAT__,win32 + SECTION .rdata align=%1 + %elif WIN64 + SECTION .rdata align=%1 + %elifidn __OUTPUT_FORMAT__,macho32 SECTION .text align=%1 fakegot: %elifidn __OUTPUT_FORMAT__,aout @@ -113,8 +117,7 @@ %endif %endmacro -; PIC macros are copied from vpx_ports/x86_abi_support.asm. The "define PIC" -; from original code is added in for 64bit. +; PIC macros from vpx_ports/x86_abi_support.asm. %ifidn __OUTPUT_FORMAT__,elf32 %define ABI_IS_32BIT 1 %elifidn __OUTPUT_FORMAT__,macho32 @@ -203,10 +206,24 @@ %ifndef GET_GOT_DEFINED %define GET_GOT_DEFINED 0 %endif -; Done with PIC macros +; End PIC macros from vpx_ports/x86_abi_support.asm. + +; libvpx explicitly sets visibilty in shared object builds. Avoid setting +; visibility to hidden as it may break builds that split sources on e.g., +; directory boundaries. +%ifdef CHROMIUM + %define VISIBILITY hidden + %define HAVE_PRIVATE_EXTERN 1 +%else + %define VISIBILITY + %define HAVE_PRIVATE_EXTERN 0 +%endif %ifdef __NASM_VER__ %use smartalign + %if __NASM_VERSION_ID__ < 0x020e0000 ; 2.14 + %define HAVE_PRIVATE_EXTERN 0 + %endif %endif ; Macros to eliminate most code duplication between x86_32 and x86_64: @@ -324,6 +341,18 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %define gprsize 4 %endif +%macro LEA 2 +%if VPX_ARCH_X86_64 + lea %1, [%2] +%elif PIC + call $+5 ; special-cased to not affect the RSB on most CPU:s + pop %1 + add %1, (%2)-$+1 +%else + mov %1, %2 +%endif +%endmacro + %macro PUSH 1 push %1 %ifidn rstk, rsp @@ -385,6 +414,10 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %endif %endmacro +%if VPX_ARCH_X86_64 == 0 + %define movsxd movifnidn +%endif + %macro movsxdifnidn 2 %ifnidn %1, %2 movsxd %1, %2 @@ -433,6 +466,8 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %endmacro %define required_stack_alignment ((mmsize + 15) & ~15) +%define vzeroupper_required (mmsize > 16 && (VPX_ARCH_X86_64 == 0 || xmm_regs_used > 16 || notcpuflag(avx512))) +%define high_mm_regs (16*cpuflag(avx512)) %macro ALLOC_STACK 1-2 0 ; stack_size, n_xmm_regs (for win64 only) %ifnum %1 @@ -483,10 +518,18 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %ifnum %1 %if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT %if %1 > 0 + ; Reserve an additional register for storing the original stack pointer, but avoid using + ; eax/rax for this purpose since it can potentially get overwritten as a return value. %assign regs_used (regs_used + 1) + %if VPX_ARCH_X86_64 && regs_used == 7 + %assign regs_used 8 + %elif VPX_ARCH_X86_64 == 0 && regs_used == 1 + %assign regs_used 2 + %endif %endif %if VPX_ARCH_X86_64 && regs_used < 5 + UNIX64 * 3 - ; Ensure that we don't clobber any registers containing arguments + ; Ensure that we don't clobber any registers containing arguments. For UNIX64 we also preserve r6 (rax) + ; since it's used as a hidden argument in vararg functions to specify the number of vector registers used. %assign regs_used 5 + UNIX64 * 3 %endif %endif @@ -516,10 +559,10 @@ DECLARE_REG 7, rdi, 64 DECLARE_REG 8, rsi, 72 DECLARE_REG 9, rbx, 80 DECLARE_REG 10, rbp, 88 -DECLARE_REG 11, R12, 96 -DECLARE_REG 12, R13, 104 -DECLARE_REG 13, R14, 112 -DECLARE_REG 14, R15, 120 +DECLARE_REG 11, R14, 96 +DECLARE_REG 12, R15, 104 +DECLARE_REG 13, R12, 112 +DECLARE_REG 14, R13, 120 %macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %assign num_args %1 @@ -538,15 +581,16 @@ DECLARE_REG 14, R15, 120 %macro WIN64_PUSH_XMM 0 ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated. - %if xmm_regs_used > 6 + %if xmm_regs_used > 6 + high_mm_regs movaps [rstk + stack_offset + 8], xmm6 %endif - %if xmm_regs_used > 7 + %if xmm_regs_used > 7 + high_mm_regs movaps [rstk + stack_offset + 24], xmm7 %endif - %if xmm_regs_used > 8 + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 %assign %%i 8 - %rep xmm_regs_used-8 + %rep %%xmm_regs_on_stack movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i %assign %%i %%i+1 %endrep @@ -555,53 +599,56 @@ DECLARE_REG 14, R15, 120 %macro WIN64_SPILL_XMM 1 %assign xmm_regs_used %1 - ASSERT xmm_regs_used <= 16 - %if xmm_regs_used > 8 + ASSERT xmm_regs_used <= 16 + high_mm_regs + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 ; Allocate stack space for callee-saved xmm registers plus shadow space and align the stack. - %assign %%pad (xmm_regs_used-8)*16 + 32 + %assign %%pad %%xmm_regs_on_stack*16 + 32 %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) SUB rsp, stack_size_padded %endif WIN64_PUSH_XMM %endmacro -%macro WIN64_RESTORE_XMM_INTERNAL 1 +%macro WIN64_RESTORE_XMM_INTERNAL 0 %assign %%pad_size 0 - %if xmm_regs_used > 8 - %assign %%i xmm_regs_used - %rep xmm_regs_used-8 + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + %assign %%i xmm_regs_used - high_mm_regs + %rep %%xmm_regs_on_stack %assign %%i %%i-1 - movaps xmm %+ %%i, [%1 + (%%i-8)*16 + stack_size + 32] + movaps xmm %+ %%i, [rsp + (%%i-8)*16 + stack_size + 32] %endrep %endif %if stack_size_padded > 0 %if stack_size > 0 && required_stack_alignment > STACK_ALIGNMENT mov rsp, rstkm %else - add %1, stack_size_padded + add rsp, stack_size_padded %assign %%pad_size stack_size_padded %endif %endif - %if xmm_regs_used > 7 - movaps xmm7, [%1 + stack_offset - %%pad_size + 24] + %if xmm_regs_used > 7 + high_mm_regs + movaps xmm7, [rsp + stack_offset - %%pad_size + 24] %endif - %if xmm_regs_used > 6 - movaps xmm6, [%1 + stack_offset - %%pad_size + 8] + %if xmm_regs_used > 6 + high_mm_regs + movaps xmm6, [rsp + stack_offset - %%pad_size + 8] %endif %endmacro -%macro WIN64_RESTORE_XMM 1 - WIN64_RESTORE_XMM_INTERNAL %1 +%macro WIN64_RESTORE_XMM 0 + WIN64_RESTORE_XMM_INTERNAL %assign stack_offset (stack_offset-stack_size_padded) + %assign stack_size_padded 0 %assign xmm_regs_used 0 %endmacro -%define has_epilogue regs_used > 7 || xmm_regs_used > 6 || mmsize == 32 || stack_size > 0 +%define has_epilogue regs_used > 7 || stack_size > 0 || vzeroupper_required || xmm_regs_used > 6+high_mm_regs %macro RET 0 - WIN64_RESTORE_XMM_INTERNAL rsp + WIN64_RESTORE_XMM_INTERNAL POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7 - %if mmsize == 32 + %if vzeroupper_required vzeroupper %endif AUTO_REP_RET @@ -620,14 +667,15 @@ DECLARE_REG 7, R10, 16 DECLARE_REG 8, R11, 24 DECLARE_REG 9, rbx, 32 DECLARE_REG 10, rbp, 40 -DECLARE_REG 11, R12, 48 -DECLARE_REG 12, R13, 56 -DECLARE_REG 13, R14, 64 -DECLARE_REG 14, R15, 72 +DECLARE_REG 11, R14, 48 +DECLARE_REG 12, R15, 56 +DECLARE_REG 13, R12, 64 +DECLARE_REG 14, R13, 72 -%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, [stack_size,] arg_names... +%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %assign num_args %1 %assign regs_used %2 + %assign xmm_regs_used %3 ASSERT regs_used >= num_args SETUP_STACK_POINTER %4 ASSERT regs_used <= 15 @@ -637,7 +685,7 @@ DECLARE_REG 14, R15, 72 DEFINE_ARGS_INTERNAL %0, %4, %5 %endmacro -%define has_epilogue regs_used > 9 || mmsize == 32 || stack_size > 0 +%define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required %macro RET 0 %if stack_size_padded > 0 @@ -648,7 +696,7 @@ DECLARE_REG 14, R15, 72 %endif %endif POP_IF_USED 14, 13, 12, 11, 10, 9 - %if mmsize == 32 + %if vzeroupper_required vzeroupper %endif AUTO_REP_RET @@ -693,7 +741,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 DEFINE_ARGS_INTERNAL %0, %4, %5 %endmacro -%define has_epilogue regs_used > 3 || mmsize == 32 || stack_size > 0 +%define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required %macro RET 0 %if stack_size_padded > 0 @@ -704,7 +752,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 %endif %endif POP_IF_USED 6, 5, 4, 3 - %if mmsize == 32 + %if vzeroupper_required vzeroupper %endif AUTO_REP_RET @@ -715,7 +763,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 %if WIN64 == 0 %macro WIN64_SPILL_XMM 1 %endmacro - %macro WIN64_RESTORE_XMM 1 + %macro WIN64_RESTORE_XMM 0 %endmacro %macro WIN64_PUSH_XMM 0 %endmacro @@ -726,7 +774,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 ; We can automatically detect "follows a branch", but not a branch target. ; (SSSE3 is a sufficient condition to know that your cpu doesn't have this problem.) %macro REP_RET 0 - %if has_epilogue + %if has_epilogue || cpuflag(ssse3) RET %else rep ret @@ -758,7 +806,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, jna, jnae, jb, jbe, jnb, jnbe, jc, jnc, js, jns, jo, jno, jp, jnp -%macro TAIL_CALL 2 ; callee, is_nonadjacent +%macro TAIL_CALL 1-2 1 ; callee, is_nonadjacent %if has_epilogue call %1 RET @@ -788,35 +836,25 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %endmacro %macro cglobal_internal 2-3+ annotate_function_size - %if %1 - %xdefine %%FUNCTION_PREFIX private_prefix - ; libvpx explicitly sets visibility in shared object builds. Avoid - ; setting visibility to hidden as it may break builds that split - ; sources on e.g., directory boundaries. - %ifdef CHROMIUM - %xdefine %%VISIBILITY hidden - %else - %xdefine %%VISIBILITY - %endif - %else - %xdefine %%FUNCTION_PREFIX public_prefix - %xdefine %%VISIBILITY - %endif %ifndef cglobaled_%2 - %xdefine %2 mangle(%%FUNCTION_PREFIX %+ _ %+ %2) + %if %1 + %xdefine %2 mangle(private_prefix %+ _ %+ %2) + %else + %xdefine %2 mangle(public_prefix %+ _ %+ %2) + %endif %xdefine %2.skip_prologue %2 %+ .skip_prologue CAT_XDEFINE cglobaled_, %2, 1 %endif %xdefine current_function %2 %xdefine current_function_section __SECT__ %if FORMAT_ELF - global %2:function %%VISIBILITY - %elif FORMAT_MACHO - %ifdef __NASM_VER__ - global %2 + %if %1 + global %2:function VISIBILITY %else - global %2:private_extern + global %2:function %endif + %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN && %1 + global %2:private_extern %else global %2 %endif @@ -827,12 +865,24 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %assign stack_offset 0 ; stack pointer offset relative to the return address %assign stack_size 0 ; amount of stack space that can be freely used inside a function %assign stack_size_padded 0 ; total amount of allocated stack space, including space for callee-saved xmm registers on WIN64 and alignment padding - %assign xmm_regs_used 0 ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64 + %assign xmm_regs_used 0 ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64 and vzeroupper %ifnidn %3, "" PROLOGUE %3 %endif %endmacro +; Create a global symbol from a local label with the correct name mangling and type +%macro cglobal_label 1 + %if FORMAT_ELF + global current_function %+ %1:function VISIBILITY + %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN + global current_function %+ %1:private_extern + %else + global current_function %+ %1 + %endif + %1: +%endmacro + %macro cextern 1 %xdefine %1 mangle(private_prefix %+ _ %+ %1) CAT_XDEFINE cglobaled_, %1, 1 @@ -851,7 +901,9 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %macro const 1-2+ %xdefine %1 mangle(private_prefix %+ _ %+ %1) %if FORMAT_ELF - global %1:data hidden + global %1:data VISIBILITY + %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN + global %1:private_extern %else global %1 %endif @@ -890,24 +942,26 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %assign cpuflags_sse (1<<4) | cpuflags_mmx2 %assign cpuflags_sse2 (1<<5) | cpuflags_sse %assign cpuflags_sse2slow (1<<6) | cpuflags_sse2 -%assign cpuflags_sse3 (1<<7) | cpuflags_sse2 -%assign cpuflags_ssse3 (1<<8) | cpuflags_sse3 -%assign cpuflags_sse4 (1<<9) | cpuflags_ssse3 -%assign cpuflags_sse42 (1<<10)| cpuflags_sse4 -%assign cpuflags_avx (1<<11)| cpuflags_sse42 -%assign cpuflags_xop (1<<12)| cpuflags_avx -%assign cpuflags_fma4 (1<<13)| cpuflags_avx -%assign cpuflags_fma3 (1<<14)| cpuflags_avx -%assign cpuflags_avx2 (1<<15)| cpuflags_fma3 +%assign cpuflags_lzcnt (1<<7) | cpuflags_sse2 +%assign cpuflags_sse3 (1<<8) | cpuflags_sse2 +%assign cpuflags_ssse3 (1<<9) | cpuflags_sse3 +%assign cpuflags_sse4 (1<<10)| cpuflags_ssse3 +%assign cpuflags_sse42 (1<<11)| cpuflags_sse4 +%assign cpuflags_aesni (1<<12)| cpuflags_sse42 +%assign cpuflags_gfni (1<<13)| cpuflags_sse42 +%assign cpuflags_avx (1<<14)| cpuflags_sse42 +%assign cpuflags_xop (1<<15)| cpuflags_avx +%assign cpuflags_fma4 (1<<16)| cpuflags_avx +%assign cpuflags_fma3 (1<<17)| cpuflags_avx +%assign cpuflags_bmi1 (1<<18)| cpuflags_avx|cpuflags_lzcnt +%assign cpuflags_bmi2 (1<<19)| cpuflags_bmi1 +%assign cpuflags_avx2 (1<<20)| cpuflags_fma3|cpuflags_bmi2 +%assign cpuflags_avx512 (1<<21)| cpuflags_avx2 ; F, CD, BW, DQ, VL -%assign cpuflags_cache32 (1<<16) -%assign cpuflags_cache64 (1<<17) -%assign cpuflags_slowctz (1<<18) -%assign cpuflags_lzcnt (1<<19) -%assign cpuflags_aligned (1<<20) ; not a cpu feature, but a function variant -%assign cpuflags_atom (1<<21) -%assign cpuflags_bmi1 (1<<22)|cpuflags_lzcnt -%assign cpuflags_bmi2 (1<<23)|cpuflags_bmi1 +%assign cpuflags_cache32 (1<<22) +%assign cpuflags_cache64 (1<<23) +%assign cpuflags_aligned (1<<24) ; not a cpu feature, but a function variant +%assign cpuflags_atom (1<<25) ; Returns a boolean value expressing whether or not the specified cpuflag is enabled. %define cpuflag(x) (((((cpuflags & (cpuflags_ %+ x)) ^ (cpuflags_ %+ x)) - 1) >> 31) & 1) @@ -950,7 +1004,7 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %if VPX_ARCH_X86_64 || cpuflag(sse2) %ifdef __NASM_VER__ - ALIGNMODE k8 + ALIGNMODE p6 %else CPU amdnop %endif @@ -963,11 +1017,12 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %endif %endmacro -; Merge mmx and sse* +; Merge mmx, sse*, and avx* ; m# is a simd register of the currently selected size ; xm# is the corresponding xmm register if mmsize >= 16, otherwise the same as m# ; ym# is the corresponding ymm register if mmsize >= 32, otherwise the same as m# -; (All 3 remain in sync through SWAP.) +; zm# is the corresponding zmm register if mmsize >= 64, otherwise the same as m# +; (All 4 remain in sync through SWAP.) %macro CAT_XDEFINE 3 %xdefine %1%2 %3 @@ -977,69 +1032,99 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %undef %1%2 %endmacro +%macro DEFINE_MMREGS 1 ; mmtype + %assign %%prev_mmregs 0 + %ifdef num_mmregs + %assign %%prev_mmregs num_mmregs + %endif + + %assign num_mmregs 8 + %if VPX_ARCH_X86_64 && mmsize >= 16 + %assign num_mmregs 16 + %if cpuflag(avx512) || mmsize == 64 + %assign num_mmregs 32 + %endif + %endif + + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE m, %%i, %1 %+ %%i + CAT_XDEFINE nn%1, %%i, %%i + %assign %%i %%i+1 + %endrep + %if %%prev_mmregs > num_mmregs + %rep %%prev_mmregs - num_mmregs + CAT_UNDEF m, %%i + CAT_UNDEF nn %+ mmtype, %%i + %assign %%i %%i+1 + %endrep + %endif + %xdefine mmtype %1 +%endmacro + +; Prefer registers 16-31 over 0-15 to avoid having to use vzeroupper +%macro AVX512_MM_PERMUTATION 0-1 0 ; start_reg + %if VPX_ARCH_X86_64 && cpuflag(avx512) + %assign %%i %1 + %rep 16-%1 + %assign %%i_high %%i+16 + SWAP %%i, %%i_high + %assign %%i %%i+1 + %endrep + %endif +%endmacro + %macro INIT_MMX 0-1+ %assign avx_enabled 0 %define RESET_MM_PERMUTATION INIT_MMX %1 %define mmsize 8 - %define num_mmregs 8 %define mova movq %define movu movq %define movh movd %define movnta movntq - %assign %%i 0 - %rep 8 - CAT_XDEFINE m, %%i, mm %+ %%i - CAT_XDEFINE nnmm, %%i, %%i - %assign %%i %%i+1 - %endrep - %rep 8 - CAT_UNDEF m, %%i - CAT_UNDEF nnmm, %%i - %assign %%i %%i+1 - %endrep INIT_CPUFLAGS %1 + DEFINE_MMREGS mm %endmacro %macro INIT_XMM 0-1+ %assign avx_enabled 0 %define RESET_MM_PERMUTATION INIT_XMM %1 %define mmsize 16 - %define num_mmregs 8 - %if VPX_ARCH_X86_64 - %define num_mmregs 16 - %endif %define mova movdqa %define movu movdqu %define movh movq %define movnta movntdq - %assign %%i 0 - %rep num_mmregs - CAT_XDEFINE m, %%i, xmm %+ %%i - CAT_XDEFINE nnxmm, %%i, %%i - %assign %%i %%i+1 - %endrep INIT_CPUFLAGS %1 + DEFINE_MMREGS xmm + %if WIN64 + AVX512_MM_PERMUTATION 6 ; Swap callee-saved registers with volatile registers + %endif %endmacro %macro INIT_YMM 0-1+ %assign avx_enabled 1 %define RESET_MM_PERMUTATION INIT_YMM %1 %define mmsize 32 - %define num_mmregs 8 - %if VPX_ARCH_X86_64 - %define num_mmregs 16 - %endif %define mova movdqa %define movu movdqu %undef movh %define movnta movntdq - %assign %%i 0 - %rep num_mmregs - CAT_XDEFINE m, %%i, ymm %+ %%i - CAT_XDEFINE nnymm, %%i, %%i - %assign %%i %%i+1 - %endrep INIT_CPUFLAGS %1 + DEFINE_MMREGS ymm + AVX512_MM_PERMUTATION +%endmacro + +%macro INIT_ZMM 0-1+ + %assign avx_enabled 1 + %define RESET_MM_PERMUTATION INIT_ZMM %1 + %define mmsize 64 + %define mova movdqa + %define movu movdqu + %undef movh + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS zmm + AVX512_MM_PERMUTATION %endmacro INIT_XMM @@ -1048,18 +1133,26 @@ INIT_XMM %define mmmm%1 mm%1 %define mmxmm%1 mm%1 %define mmymm%1 mm%1 + %define mmzmm%1 mm%1 %define xmmmm%1 mm%1 %define xmmxmm%1 xmm%1 %define xmmymm%1 xmm%1 + %define xmmzmm%1 xmm%1 %define ymmmm%1 mm%1 %define ymmxmm%1 xmm%1 %define ymmymm%1 ymm%1 + %define ymmzmm%1 ymm%1 + %define zmmmm%1 mm%1 + %define zmmxmm%1 xmm%1 + %define zmmymm%1 ymm%1 + %define zmmzmm%1 zmm%1 %define xm%1 xmm %+ m%1 %define ym%1 ymm %+ m%1 + %define zm%1 zmm %+ m%1 %endmacro %assign i 0 -%rep 16 +%rep 32 DECLARE_MMCAST i %assign i i+1 %endrep @@ -1129,25 +1222,42 @@ INIT_XMM %endif %assign %%i 0 %rep num_mmregs - CAT_XDEFINE %%f, %%i, m %+ %%i + %xdefine %%tmp m %+ %%i + CAT_XDEFINE %%f, %%i, regnumof %+ %%tmp %assign %%i %%i+1 %endrep %endmacro -%macro LOAD_MM_PERMUTATION 1 ; name to load from - %ifdef %1_m0 +%macro LOAD_MM_PERMUTATION 0-1 ; name to load from + %if %0 + %xdefine %%f %1_m + %else + %xdefine %%f current_function %+ _m + %endif + %xdefine %%tmp %%f %+ 0 + %ifnum %%tmp + RESET_MM_PERMUTATION %assign %%i 0 %rep num_mmregs - CAT_XDEFINE m, %%i, %1_m %+ %%i - CAT_XDEFINE nn, m %+ %%i, %%i + %xdefine %%tmp %%f %+ %%i + CAT_XDEFINE %%m, %%i, m %+ %%tmp %assign %%i %%i+1 %endrep + %rep num_mmregs + %assign %%i %%i-1 + CAT_XDEFINE m, %%i, %%m %+ %%i + CAT_XDEFINE nn, m %+ %%i, %%i + %endrep %endif %endmacro ; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't %macro call 1 - call_internal %1 %+ SUFFIX, %1 + %ifid %1 + call_internal %1 %+ SUFFIX, %1 + %else + call %1 + %endif %endmacro %macro call_internal 2 %xdefine %%i %2 @@ -1190,12 +1300,17 @@ INIT_XMM ;============================================================================= %assign i 0 -%rep 16 +%rep 32 %if i < 8 CAT_XDEFINE sizeofmm, i, 8 + CAT_XDEFINE regnumofmm, i, i %endif CAT_XDEFINE sizeofxmm, i, 16 CAT_XDEFINE sizeofymm, i, 32 + CAT_XDEFINE sizeofzmm, i, 64 + CAT_XDEFINE regnumofxmm, i, i + CAT_XDEFINE regnumofymm, i, i + CAT_XDEFINE regnumofzmm, i, i %assign i i+1 %endrep %undef i @@ -1214,7 +1329,7 @@ INIT_XMM ;%1 == instruction ;%2 == minimal instruction set ;%3 == 1 if float, 0 if int -;%4 == 1 if non-destructive or 4-operand (xmm, xmm, xmm, imm), 0 otherwise +;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) ;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not ;%6+: operands %macro RUN_AVX_INSTR 6-9+ @@ -1238,8 +1353,22 @@ INIT_XMM %ifdef cpuname %if notcpuflag(%2) %error use of ``%1'' %2 instruction in cpuname function: current_function - %elif cpuflags_%2 < cpuflags_sse && notcpuflag(sse2) && __sizeofreg > 8 + %elif %3 == 0 && __sizeofreg == 16 && notcpuflag(sse2) %error use of ``%1'' sse2 instruction in cpuname function: current_function + %elif %3 == 0 && __sizeofreg == 32 && notcpuflag(avx2) + %error use of ``%1'' avx2 instruction in cpuname function: current_function + %elif __sizeofreg == 16 && notcpuflag(sse) + %error use of ``%1'' sse instruction in cpuname function: current_function + %elif __sizeofreg == 32 && notcpuflag(avx) + %error use of ``%1'' avx instruction in cpuname function: current_function + %elif __sizeofreg == 64 && notcpuflag(avx512) + %error use of ``%1'' avx512 instruction in cpuname function: current_function + %elifidn %1, pextrw ; special case because the base instruction is mmx2, + %ifnid %6 ; but sse4 is required for memory operands + %if notcpuflag(sse4) + %error use of ``%1'' sse4 instruction in cpuname function: current_function + %endif + %endif %endif %endif %endif @@ -1247,14 +1376,12 @@ INIT_XMM %if __emulate_avx %xdefine __src1 %7 %xdefine __src2 %8 - %ifnidn %6, %7 - %if %0 >= 9 - CHECK_AVX_INSTR_EMU {%1 %6, %7, %8, %9}, %6, %8, %9 - %else - CHECK_AVX_INSTR_EMU {%1 %6, %7, %8}, %6, %8 - %endif - %if %5 && %4 == 0 - %ifnid %8 + %if %5 && %4 == 0 + %ifnidn %6, %7 + %ifidn %6, %8 + %xdefine __src1 %8 + %xdefine __src2 %7 + %elifnnum sizeof%8 ; 3-operand AVX instructions with a memory arg can only have it in src2, ; whereas SSE emulation prefers to have it in src1 (i.e. the mov). ; So, if the instruction is commutative with a memory arg, swap them. @@ -1262,6 +1389,13 @@ INIT_XMM %xdefine __src2 %7 %endif %endif + %endif + %ifnidn %6, __src1 + %if %0 >= 9 + CHECK_AVX_INSTR_EMU {%1 %6, %7, %8, %9}, %6, __src2, %9 + %else + CHECK_AVX_INSTR_EMU {%1 %6, %7, %8}, %6, __src2 + %endif %if __sizeofreg == 8 MOVQ %6, __src1 %elif %3 @@ -1278,9 +1412,40 @@ INIT_XMM %elif %0 >= 9 __instr %6, %7, %8, %9 %elif %0 == 8 - __instr %6, %7, %8 + %if avx_enabled && %5 + %xdefine __src1 %7 + %xdefine __src2 %8 + %ifnum regnumof%7 + %ifnum regnumof%8 + %if regnumof%7 < 8 && regnumof%8 >= 8 && regnumof%8 < 16 && sizeof%8 <= 32 + ; Most VEX-encoded instructions require an additional byte to encode when + ; src2 is a high register (e.g. m8..15). If the instruction is commutative + ; we can swap src1 and src2 when doing so reduces the instruction length. + %xdefine __src1 %8 + %xdefine __src2 %7 + %endif + %endif + %endif + __instr %6, __src1, __src2 + %else + __instr %6, %7, %8 + %endif %elif %0 == 7 - __instr %6, %7 + %if avx_enabled && %5 + %xdefine __src1 %6 + %xdefine __src2 %7 + %ifnum regnumof%6 + %ifnum regnumof%7 + %if regnumof%6 < 8 && regnumof%7 >= 8 && regnumof%7 < 16 && sizeof%7 <= 32 + %xdefine __src1 %7 + %xdefine __src2 %6 + %endif + %endif + %endif + __instr %6, __src1, __src2 + %else + __instr %6, %7 + %endif %else __instr %6 %endif @@ -1289,9 +1454,9 @@ INIT_XMM ;%1 == instruction ;%2 == minimal instruction set ;%3 == 1 if float, 0 if int -;%4 == 1 if non-destructive or 4-operand (xmm, xmm, xmm, imm), 0 otherwise +;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) ;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not -%macro AVX_INSTR 1-5 fnord, 0, 1, 0 +%macro AVX_INSTR 1-5 fnord, 0, 255, 0 %macro %1 1-10 fnord, fnord, fnord, fnord, %1, %2, %3, %4, %5 %ifidn %2, fnord RUN_AVX_INSTR %6, %7, %8, %9, %10, %1 @@ -1307,77 +1472,112 @@ INIT_XMM %endmacro %endmacro -; Instructions with both VEX and non-VEX encodings +; Instructions with both VEX/EVEX and legacy encodings ; Non-destructive instructions are written without parameters AVX_INSTR addpd, sse2, 1, 0, 1 AVX_INSTR addps, sse, 1, 0, 1 -AVX_INSTR addsd, sse2, 1, 0, 1 -AVX_INSTR addss, sse, 1, 0, 1 +AVX_INSTR addsd, sse2, 1, 0, 0 +AVX_INSTR addss, sse, 1, 0, 0 AVX_INSTR addsubpd, sse3, 1, 0, 0 AVX_INSTR addsubps, sse3, 1, 0, 0 -AVX_INSTR aesdec, fnord, 0, 0, 0 -AVX_INSTR aesdeclast, fnord, 0, 0, 0 -AVX_INSTR aesenc, fnord, 0, 0, 0 -AVX_INSTR aesenclast, fnord, 0, 0, 0 -AVX_INSTR aesimc -AVX_INSTR aeskeygenassist +AVX_INSTR aesdec, aesni, 0, 0, 0 +AVX_INSTR aesdeclast, aesni, 0, 0, 0 +AVX_INSTR aesenc, aesni, 0, 0, 0 +AVX_INSTR aesenclast, aesni, 0, 0, 0 +AVX_INSTR aesimc, aesni +AVX_INSTR aeskeygenassist, aesni AVX_INSTR andnpd, sse2, 1, 0, 0 AVX_INSTR andnps, sse, 1, 0, 0 AVX_INSTR andpd, sse2, 1, 0, 1 AVX_INSTR andps, sse, 1, 0, 1 -AVX_INSTR blendpd, sse4, 1, 0, 0 -AVX_INSTR blendps, sse4, 1, 0, 0 -AVX_INSTR blendvpd, sse4, 1, 0, 0 -AVX_INSTR blendvps, sse4, 1, 0, 0 +AVX_INSTR blendpd, sse4, 1, 1, 0 +AVX_INSTR blendps, sse4, 1, 1, 0 +AVX_INSTR blendvpd, sse4 ; can't be emulated +AVX_INSTR blendvps, sse4 ; can't be emulated +AVX_INSTR cmpeqpd, sse2, 1, 0, 1 +AVX_INSTR cmpeqps, sse, 1, 0, 1 +AVX_INSTR cmpeqsd, sse2, 1, 0, 0 +AVX_INSTR cmpeqss, sse, 1, 0, 0 +AVX_INSTR cmplepd, sse2, 1, 0, 0 +AVX_INSTR cmpleps, sse, 1, 0, 0 +AVX_INSTR cmplesd, sse2, 1, 0, 0 +AVX_INSTR cmpless, sse, 1, 0, 0 +AVX_INSTR cmpltpd, sse2, 1, 0, 0 +AVX_INSTR cmpltps, sse, 1, 0, 0 +AVX_INSTR cmpltsd, sse2, 1, 0, 0 +AVX_INSTR cmpltss, sse, 1, 0, 0 +AVX_INSTR cmpneqpd, sse2, 1, 0, 1 +AVX_INSTR cmpneqps, sse, 1, 0, 1 +AVX_INSTR cmpneqsd, sse2, 1, 0, 0 +AVX_INSTR cmpneqss, sse, 1, 0, 0 +AVX_INSTR cmpnlepd, sse2, 1, 0, 0 +AVX_INSTR cmpnleps, sse, 1, 0, 0 +AVX_INSTR cmpnlesd, sse2, 1, 0, 0 +AVX_INSTR cmpnless, sse, 1, 0, 0 +AVX_INSTR cmpnltpd, sse2, 1, 0, 0 +AVX_INSTR cmpnltps, sse, 1, 0, 0 +AVX_INSTR cmpnltsd, sse2, 1, 0, 0 +AVX_INSTR cmpnltss, sse, 1, 0, 0 +AVX_INSTR cmpordpd, sse2 1, 0, 1 +AVX_INSTR cmpordps, sse 1, 0, 1 +AVX_INSTR cmpordsd, sse2 1, 0, 0 +AVX_INSTR cmpordss, sse 1, 0, 0 AVX_INSTR cmppd, sse2, 1, 1, 0 AVX_INSTR cmpps, sse, 1, 1, 0 AVX_INSTR cmpsd, sse2, 1, 1, 0 AVX_INSTR cmpss, sse, 1, 1, 0 -AVX_INSTR comisd, sse2 -AVX_INSTR comiss, sse -AVX_INSTR cvtdq2pd, sse2 -AVX_INSTR cvtdq2ps, sse2 -AVX_INSTR cvtpd2dq, sse2 -AVX_INSTR cvtpd2ps, sse2 -AVX_INSTR cvtps2dq, sse2 -AVX_INSTR cvtps2pd, sse2 -AVX_INSTR cvtsd2si, sse2 -AVX_INSTR cvtsd2ss, sse2 -AVX_INSTR cvtsi2sd, sse2 -AVX_INSTR cvtsi2ss, sse -AVX_INSTR cvtss2sd, sse2 -AVX_INSTR cvtss2si, sse -AVX_INSTR cvttpd2dq, sse2 -AVX_INSTR cvttps2dq, sse2 -AVX_INSTR cvttsd2si, sse2 -AVX_INSTR cvttss2si, sse +AVX_INSTR cmpunordpd, sse2, 1, 0, 1 +AVX_INSTR cmpunordps, sse, 1, 0, 1 +AVX_INSTR cmpunordsd, sse2, 1, 0, 0 +AVX_INSTR cmpunordss, sse, 1, 0, 0 +AVX_INSTR comisd, sse2, 1 +AVX_INSTR comiss, sse, 1 +AVX_INSTR cvtdq2pd, sse2, 1 +AVX_INSTR cvtdq2ps, sse2, 1 +AVX_INSTR cvtpd2dq, sse2, 1 +AVX_INSTR cvtpd2ps, sse2, 1 +AVX_INSTR cvtps2dq, sse2, 1 +AVX_INSTR cvtps2pd, sse2, 1 +AVX_INSTR cvtsd2si, sse2, 1 +AVX_INSTR cvtsd2ss, sse2, 1, 0, 0 +AVX_INSTR cvtsi2sd, sse2, 1, 0, 0 +AVX_INSTR cvtsi2ss, sse, 1, 0, 0 +AVX_INSTR cvtss2sd, sse2, 1, 0, 0 +AVX_INSTR cvtss2si, sse, 1 +AVX_INSTR cvttpd2dq, sse2, 1 +AVX_INSTR cvttps2dq, sse2, 1 +AVX_INSTR cvttsd2si, sse2, 1 +AVX_INSTR cvttss2si, sse, 1 AVX_INSTR divpd, sse2, 1, 0, 0 AVX_INSTR divps, sse, 1, 0, 0 AVX_INSTR divsd, sse2, 1, 0, 0 AVX_INSTR divss, sse, 1, 0, 0 AVX_INSTR dppd, sse4, 1, 1, 0 AVX_INSTR dpps, sse4, 1, 1, 0 -AVX_INSTR extractps, sse4 +AVX_INSTR extractps, sse4, 1 +AVX_INSTR gf2p8affineinvqb, gfni, 0, 1, 0 +AVX_INSTR gf2p8affineqb, gfni, 0, 1, 0 +AVX_INSTR gf2p8mulb, gfni, 0, 0, 0 AVX_INSTR haddpd, sse3, 1, 0, 0 AVX_INSTR haddps, sse3, 1, 0, 0 AVX_INSTR hsubpd, sse3, 1, 0, 0 AVX_INSTR hsubps, sse3, 1, 0, 0 AVX_INSTR insertps, sse4, 1, 1, 0 AVX_INSTR lddqu, sse3 -AVX_INSTR ldmxcsr, sse +AVX_INSTR ldmxcsr, sse, 1 AVX_INSTR maskmovdqu, sse2 AVX_INSTR maxpd, sse2, 1, 0, 1 AVX_INSTR maxps, sse, 1, 0, 1 -AVX_INSTR maxsd, sse2, 1, 0, 1 -AVX_INSTR maxss, sse, 1, 0, 1 +AVX_INSTR maxsd, sse2, 1, 0, 0 +AVX_INSTR maxss, sse, 1, 0, 0 AVX_INSTR minpd, sse2, 1, 0, 1 AVX_INSTR minps, sse, 1, 0, 1 -AVX_INSTR minsd, sse2, 1, 0, 1 -AVX_INSTR minss, sse, 1, 0, 1 -AVX_INSTR movapd, sse2 -AVX_INSTR movaps, sse +AVX_INSTR minsd, sse2, 1, 0, 0 +AVX_INSTR minss, sse, 1, 0, 0 +AVX_INSTR movapd, sse2, 1 +AVX_INSTR movaps, sse, 1 AVX_INSTR movd, mmx -AVX_INSTR movddup, sse3 +AVX_INSTR movddup, sse3, 1 AVX_INSTR movdqa, sse2 AVX_INSTR movdqu, sse2 AVX_INSTR movhlps, sse, 1, 0, 0 @@ -1386,24 +1586,24 @@ AVX_INSTR movhps, sse, 1, 0, 0 AVX_INSTR movlhps, sse, 1, 0, 0 AVX_INSTR movlpd, sse2, 1, 0, 0 AVX_INSTR movlps, sse, 1, 0, 0 -AVX_INSTR movmskpd, sse2 -AVX_INSTR movmskps, sse +AVX_INSTR movmskpd, sse2, 1 +AVX_INSTR movmskps, sse, 1 AVX_INSTR movntdq, sse2 AVX_INSTR movntdqa, sse4 -AVX_INSTR movntpd, sse2 -AVX_INSTR movntps, sse +AVX_INSTR movntpd, sse2, 1 +AVX_INSTR movntps, sse, 1 AVX_INSTR movq, mmx AVX_INSTR movsd, sse2, 1, 0, 0 -AVX_INSTR movshdup, sse3 -AVX_INSTR movsldup, sse3 +AVX_INSTR movshdup, sse3, 1 +AVX_INSTR movsldup, sse3, 1 AVX_INSTR movss, sse, 1, 0, 0 -AVX_INSTR movupd, sse2 -AVX_INSTR movups, sse -AVX_INSTR mpsadbw, sse4 +AVX_INSTR movupd, sse2, 1 +AVX_INSTR movups, sse, 1 +AVX_INSTR mpsadbw, sse4, 0, 1, 0 AVX_INSTR mulpd, sse2, 1, 0, 1 AVX_INSTR mulps, sse, 1, 0, 1 -AVX_INSTR mulsd, sse2, 1, 0, 1 -AVX_INSTR mulss, sse, 1, 0, 1 +AVX_INSTR mulsd, sse2, 1, 0, 0 +AVX_INSTR mulss, sse, 1, 0, 0 AVX_INSTR orpd, sse2, 1, 0, 1 AVX_INSTR orps, sse, 1, 0, 1 AVX_INSTR pabsb, ssse3 @@ -1421,14 +1621,18 @@ AVX_INSTR paddsb, mmx, 0, 0, 1 AVX_INSTR paddsw, mmx, 0, 0, 1 AVX_INSTR paddusb, mmx, 0, 0, 1 AVX_INSTR paddusw, mmx, 0, 0, 1 -AVX_INSTR palignr, ssse3 +AVX_INSTR palignr, ssse3, 0, 1, 0 AVX_INSTR pand, mmx, 0, 0, 1 AVX_INSTR pandn, mmx, 0, 0, 0 AVX_INSTR pavgb, mmx2, 0, 0, 1 AVX_INSTR pavgw, mmx2, 0, 0, 1 -AVX_INSTR pblendvb, sse4, 0, 0, 0 -AVX_INSTR pblendw, sse4 -AVX_INSTR pclmulqdq +AVX_INSTR pblendvb, sse4 ; can't be emulated +AVX_INSTR pblendw, sse4, 0, 1, 0 +AVX_INSTR pclmulqdq, fnord, 0, 1, 0 +AVX_INSTR pclmulhqhqdq, fnord, 0, 0, 0 +AVX_INSTR pclmulhqlqdq, fnord, 0, 0, 0 +AVX_INSTR pclmullqhqdq, fnord, 0, 0, 0 +AVX_INSTR pclmullqlqdq, fnord, 0, 0, 0 AVX_INSTR pcmpestri, sse42 AVX_INSTR pcmpestrm, sse42 AVX_INSTR pcmpistri, sse42 @@ -1452,10 +1656,10 @@ AVX_INSTR phminposuw, sse4 AVX_INSTR phsubw, ssse3, 0, 0, 0 AVX_INSTR phsubd, ssse3, 0, 0, 0 AVX_INSTR phsubsw, ssse3, 0, 0, 0 -AVX_INSTR pinsrb, sse4 -AVX_INSTR pinsrd, sse4 -AVX_INSTR pinsrq, sse4 -AVX_INSTR pinsrw, mmx2 +AVX_INSTR pinsrb, sse4, 0, 1, 0 +AVX_INSTR pinsrd, sse4, 0, 1, 0 +AVX_INSTR pinsrq, sse4, 0, 1, 0 +AVX_INSTR pinsrw, mmx2, 0, 1, 0 AVX_INSTR pmaddwd, mmx, 0, 0, 1 AVX_INSTR pmaddubsw, ssse3, 0, 0, 0 AVX_INSTR pmaxsb, sse4, 0, 0, 1 @@ -1527,27 +1731,27 @@ AVX_INSTR punpcklwd, mmx, 0, 0, 0 AVX_INSTR punpckldq, mmx, 0, 0, 0 AVX_INSTR punpcklqdq, sse2, 0, 0, 0 AVX_INSTR pxor, mmx, 0, 0, 1 -AVX_INSTR rcpps, sse, 1, 0, 0 +AVX_INSTR rcpps, sse, 1 AVX_INSTR rcpss, sse, 1, 0, 0 -AVX_INSTR roundpd, sse4 -AVX_INSTR roundps, sse4 -AVX_INSTR roundsd, sse4 -AVX_INSTR roundss, sse4 -AVX_INSTR rsqrtps, sse, 1, 0, 0 +AVX_INSTR roundpd, sse4, 1 +AVX_INSTR roundps, sse4, 1 +AVX_INSTR roundsd, sse4, 1, 1, 0 +AVX_INSTR roundss, sse4, 1, 1, 0 +AVX_INSTR rsqrtps, sse, 1 AVX_INSTR rsqrtss, sse, 1, 0, 0 AVX_INSTR shufpd, sse2, 1, 1, 0 AVX_INSTR shufps, sse, 1, 1, 0 -AVX_INSTR sqrtpd, sse2, 1, 0, 0 -AVX_INSTR sqrtps, sse, 1, 0, 0 +AVX_INSTR sqrtpd, sse2, 1 +AVX_INSTR sqrtps, sse, 1 AVX_INSTR sqrtsd, sse2, 1, 0, 0 AVX_INSTR sqrtss, sse, 1, 0, 0 -AVX_INSTR stmxcsr, sse +AVX_INSTR stmxcsr, sse, 1 AVX_INSTR subpd, sse2, 1, 0, 0 AVX_INSTR subps, sse, 1, 0, 0 AVX_INSTR subsd, sse2, 1, 0, 0 AVX_INSTR subss, sse, 1, 0, 0 -AVX_INSTR ucomisd, sse2 -AVX_INSTR ucomiss, sse +AVX_INSTR ucomisd, sse2, 1 +AVX_INSTR ucomiss, sse, 1 AVX_INSTR unpckhpd, sse2, 1, 0, 0 AVX_INSTR unpckhps, sse, 1, 0, 0 AVX_INSTR unpcklpd, sse2, 1, 0, 0 @@ -1560,6 +1764,38 @@ AVX_INSTR pfadd, 3dnow, 1, 0, 1 AVX_INSTR pfsub, 3dnow, 1, 0, 0 AVX_INSTR pfmul, 3dnow, 1, 0, 1 +;%1 == instruction +;%2 == minimal instruction set +%macro GPR_INSTR 2 + %macro %1 2-5 fnord, %1, %2 + %ifdef cpuname + %if notcpuflag(%5) + %error use of ``%4'' %5 instruction in cpuname function: current_function + %endif + %endif + %ifidn %3, fnord + %4 %1, %2 + %else + %4 %1, %2, %3 + %endif + %endmacro +%endmacro + +GPR_INSTR andn, bmi1 +GPR_INSTR bextr, bmi1 +GPR_INSTR blsi, bmi1 +GPR_INSTR blsr, bmi1 +GPR_INSTR blsmsk, bmi1 +GPR_INSTR bzhi, bmi2 +GPR_INSTR mulx, bmi2 +GPR_INSTR pdep, bmi2 +GPR_INSTR pext, bmi2 +GPR_INSTR popcnt, sse42 +GPR_INSTR rorx, bmi2 +GPR_INSTR sarx, bmi2 +GPR_INSTR shlx, bmi2 +GPR_INSTR shrx, bmi2 + ; base-4 constants for shuffles %assign i 0 %rep 256 @@ -1610,7 +1846,7 @@ FMA_INSTR pmadcswd, pmaddwd, paddd v%5%6 %1, %2, %3, %4 %elifidn %1, %2 ; If %3 or %4 is a memory operand it needs to be encoded as the last operand. - %ifid %3 + %ifnum sizeof%3 v%{5}213%6 %2, %3, %4 %else v%{5}132%6 %2, %4, %3 @@ -1635,15 +1871,53 @@ FMA4_INSTR fmsubadd, pd, ps FMA4_INSTR fnmadd, pd, ps, sd, ss FMA4_INSTR fnmsub, pd, ps, sd, ss -; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug (fixed in 1.3.0) -%ifdef __YASM_VER__ - %if __YASM_VERSION_ID__ < 0x01030000 && VPX_ARCH_X86_64 == 0 - %macro vpbroadcastq 2 - %if sizeof%1 == 16 - movddup %1, %2 - %else - vbroadcastsd %1, %2 +; Macros for converting VEX instructions to equivalent EVEX ones. +%macro EVEX_INSTR 2-3 0 ; vex, evex, prefer_evex + %macro %1 2-7 fnord, fnord, %1, %2, %3 + %ifidn %3, fnord + %define %%args %1, %2 + %elifidn %4, fnord + %define %%args %1, %2, %3 + %else + %define %%args %1, %2, %3, %4 + %endif + %assign %%evex_required cpuflag(avx512) & %7 + %ifnum regnumof%1 + %if regnumof%1 >= 16 || sizeof%1 > 32 + %assign %%evex_required 1 %endif - %endmacro - %endif -%endif + %endif + %ifnum regnumof%2 + %if regnumof%2 >= 16 || sizeof%2 > 32 + %assign %%evex_required 1 + %endif + %endif + %ifnum regnumof%3 + %if regnumof%3 >= 16 || sizeof%3 > 32 + %assign %%evex_required 1 + %endif + %endif + %if %%evex_required + %6 %%args + %else + %5 %%args ; Prefer VEX over EVEX due to shorter instruction length + %endif + %endmacro +%endmacro + +EVEX_INSTR vbroadcastf128, vbroadcastf32x4 +EVEX_INSTR vbroadcasti128, vbroadcasti32x4 +EVEX_INSTR vextractf128, vextractf32x4 +EVEX_INSTR vextracti128, vextracti32x4 +EVEX_INSTR vinsertf128, vinsertf32x4 +EVEX_INSTR vinserti128, vinserti32x4 +EVEX_INSTR vmovdqa, vmovdqa32 +EVEX_INSTR vmovdqu, vmovdqu32 +EVEX_INSTR vpand, vpandd +EVEX_INSTR vpandn, vpandnd +EVEX_INSTR vpor, vpord +EVEX_INSTR vpxor, vpxord +EVEX_INSTR vrcpps, vrcp14ps, 1 ; EVEX versions have higher precision +EVEX_INSTR vrcpss, vrcp14ss, 1 +EVEX_INSTR vrsqrtps, vrsqrt14ps, 1 +EVEX_INSTR vrsqrtss, vrsqrt14ss, 1 diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/tools_common.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/tools_common.c index 59978b7f9..cbecfbb41 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/tools_common.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/tools_common.c @@ -91,10 +91,13 @@ int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) { for (plane = 0; plane < 3; ++plane) { uint8_t *ptr; - const int w = vpx_img_plane_width(yuv_frame, plane); + int w = vpx_img_plane_width(yuv_frame, plane); const int h = vpx_img_plane_height(yuv_frame, plane); int r; - + // Assuming that for nv12 we read all chroma data at one time + if (yuv_frame->fmt == VPX_IMG_FMT_NV12 && plane > 1) break; + // Fixing NV12 chroma width it is odd + if (yuv_frame->fmt == VPX_IMG_FMT_NV12 && plane == 1) w = (w + 1) & ~1; /* Determine the correct plane based on the image format. The for-loop * always counts in Y,U,V order, but this may not match the order of * the data on disk. diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/extend.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/extend.c index f4dbce2cd..b52e9fe93 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/extend.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/extend.c @@ -11,30 +11,40 @@ #include "extend.h" #include "vpx_mem/vpx_mem.h" -static void copy_and_extend_plane(unsigned char *s, /* source */ - int sp, /* source pitch */ - unsigned char *d, /* destination */ - int dp, /* destination pitch */ - int h, /* height */ - int w, /* width */ - int et, /* extend top border */ - int el, /* extend left border */ - int eb, /* extend bottom border */ - int er) { /* extend right border */ - int i; +static void copy_and_extend_plane( + unsigned char *s, /* source */ + int sp, /* source pitch */ + unsigned char *d, /* destination */ + int dp, /* destination pitch */ + int h, /* height */ + int w, /* width */ + int et, /* extend top border */ + int el, /* extend left border */ + int eb, /* extend bottom border */ + int er, /* extend right border */ + int interleave_step) { /* step between pixels of the current plane */ + int i, j; unsigned char *src_ptr1, *src_ptr2; unsigned char *dest_ptr1, *dest_ptr2; int linesize; + if (interleave_step < 1) interleave_step = 1; + /* copy the left and right most columns out */ src_ptr1 = s; - src_ptr2 = s + w - 1; + src_ptr2 = s + (w - 1) * interleave_step; dest_ptr1 = d - el; dest_ptr2 = d + w; for (i = 0; i < h; ++i) { memset(dest_ptr1, src_ptr1[0], el); - memcpy(dest_ptr1 + el, src_ptr1, w); + if (interleave_step == 1) { + memcpy(dest_ptr1 + el, src_ptr1, w); + } else { + for (j = 0; j < w; j++) { + dest_ptr1[el + j] = src_ptr1[interleave_step * j]; + } + } memset(dest_ptr2, src_ptr2[0], er); src_ptr1 += sp; src_ptr2 += sp; @@ -69,9 +79,12 @@ void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src, int eb = dst->border + dst->y_height - src->y_height; int er = dst->border + dst->y_width - src->y_width; + // detect nv12 colorspace + int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1; + copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, src->y_height, src->y_width, et, el, eb, - er); + er, 1); et = dst->border >> 1; el = dst->border >> 1; @@ -80,11 +93,11 @@ void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src, copy_and_extend_plane(src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride, src->uv_height, src->uv_width, et, el, - eb, er); + eb, er, chroma_step); copy_and_extend_plane(src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride, src->uv_height, src->uv_width, et, el, - eb, er); + eb, er, chroma_step); } void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, @@ -98,6 +111,8 @@ void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, int dst_y_offset = srcy * dst->y_stride + srcx; int src_uv_offset = ((srcy * src->uv_stride) >> 1) + (srcx >> 1); int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1); + // detect nv12 colorspace + int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1; /* If the side is not touching the bounder then don't extend. */ if (srcy) et = 0; @@ -107,7 +122,7 @@ void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, copy_and_extend_plane(src->y_buffer + src_y_offset, src->y_stride, dst->y_buffer + dst_y_offset, dst->y_stride, srch, srcw, - et, el, eb, er); + et, el, eb, er, 1); et = (et + 1) >> 1; el = (el + 1) >> 1; @@ -118,11 +133,11 @@ void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, copy_and_extend_plane(src->u_buffer + src_uv_offset, src->uv_stride, dst->u_buffer + dst_uv_offset, dst->uv_stride, srch, - srcw, et, el, eb, er); + srcw, et, el, eb, er, chroma_step); copy_and_extend_plane(src->v_buffer + src_uv_offset, src->uv_stride, dst->v_buffer + dst_uv_offset, dst->uv_stride, srch, - srcw, et, el, eb, er); + srcw, et, el, eb, er, chroma_step); } /* note the extension is only for the last row, for intra prediction purpose */ diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/generic/systemdependent.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/generic/systemdependent.c index 75ce7ef35..cd1b02c9c 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/generic/systemdependent.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/generic/systemdependent.c @@ -16,6 +16,8 @@ #include "vpx_ports/x86.h" #elif VPX_ARCH_PPC #include "vpx_ports/ppc.h" +#elif VPX_ARCH_MIPS +#include "vpx_ports/mips.h" #endif #include "vp8/common/onyxc_int.h" #include "vp8/common/systemdependent.h" @@ -96,6 +98,8 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) { ctx->cpu_caps = x86_simd_caps(); #elif VPX_ARCH_PPC ctx->cpu_caps = ppc_simd_caps(); +#elif VPX_ARCH_MIPS + ctx->cpu_caps = mips_cpu_caps(); #else // generic-gnu targets. ctx->cpu_caps = 0; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/dequantize_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/dequantize_mmi.c index b3f8084ae..b9330a666 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/dequantize_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/dequantize_mmi.c @@ -100,7 +100,7 @@ void vp8_dequant_idct_add_mmi(int16_t *input, int16_t *dq, unsigned char *dest, vp8_short_idct4x4llm_mmi(input, dest, stride, dest, stride); __asm__ volatile( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "gssdlc1 %[ftmp0], 0x07(%[input]) \n\t" "gssdrc1 %[ftmp0], 0x00(%[input]) \n\t" "sdl $0, 0x0f(%[input]) \n\t" diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/idctllm_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/idctllm_mmi.c index 5e48f5916..a35689dd3 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/idctllm_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/idctllm_mmi.c @@ -13,25 +13,25 @@ #include "vpx_ports/asmdefs_mmi.h" #define TRANSPOSE_4H \ - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" \ + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" \ MMI_LI(%[tmp0], 0x93) \ "mtc1 %[tmp0], %[ftmp10] \n\t" \ "punpcklhw %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ "punpcklhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "or %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ + "por %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ "punpckhhw %[ftmp6], %[ftmp1], %[ftmp0] \n\t" \ "punpckhhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "or %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ + "por %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ "punpcklhw %[ftmp7], %[ftmp3], %[ftmp0] \n\t" \ "punpcklhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "or %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ + "por %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ "punpckhhw %[ftmp8], %[ftmp3], %[ftmp0] \n\t" \ "punpckhhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "or %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ + "por %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ "punpcklwd %[ftmp1], %[ftmp5], %[ftmp7] \n\t" \ "punpckhwd %[ftmp2], %[ftmp5], %[ftmp7] \n\t" \ "punpcklwd %[ftmp3], %[ftmp6], %[ftmp8] \n\t" \ @@ -41,15 +41,19 @@ void vp8_short_idct4x4llm_mmi(int16_t *input, unsigned char *pred_ptr, int pred_stride, unsigned char *dst_ptr, int dst_stride) { double ftmp[12]; - uint32_t tmp[0]; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_04) = { 0x0004000400040004ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_4e7b) = { 0x4e7b4e7b4e7b4e7bULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_22a3) = { 0x22a322a322a322a3ULL }; + uint64_t tmp[1]; + double ff_ph_04, ff_ph_4e7b, ff_ph_22a3; __asm__ volatile ( + "dli %[tmp0], 0x0004000400040004 \n\t" + "dmtc1 %[tmp0], %[ff_ph_04] \n\t" + "dli %[tmp0], 0x4e7b4e7b4e7b4e7b \n\t" + "dmtc1 %[tmp0], %[ff_ph_4e7b] \n\t" + "dli %[tmp0], 0x22a322a322a322a3 \n\t" + "dmtc1 %[tmp0], %[ff_ph_22a3] \n\t" MMI_LI(%[tmp0], 0x02) - "mtc1 %[tmp0], %[ftmp11] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" @@ -186,9 +190,10 @@ void vp8_short_idct4x4llm_mmi(int16_t *input, unsigned char *pred_ptr, [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), - [pred_ptr]"+&r"(pred_ptr), [dst_ptr]"+&r"(dst_ptr) - : [ip]"r"(input), [ff_ph_22a3]"f"(ff_ph_22a3), - [ff_ph_4e7b]"f"(ff_ph_4e7b), [ff_ph_04]"f"(ff_ph_04), + [pred_ptr]"+&r"(pred_ptr), [dst_ptr]"+&r"(dst_ptr), + [ff_ph_4e7b]"=&f"(ff_ph_4e7b), [ff_ph_04]"=&f"(ff_ph_04), + [ff_ph_22a3]"=&f"(ff_ph_22a3) + : [ip]"r"(input), [pred_stride]"r"((mips_reg)pred_stride), [dst_stride]"r"((mips_reg)dst_stride) : "memory" @@ -198,12 +203,13 @@ void vp8_short_idct4x4llm_mmi(int16_t *input, unsigned char *pred_ptr, void vp8_dc_only_idct_add_mmi(int16_t input_dc, unsigned char *pred_ptr, int pred_stride, unsigned char *dst_ptr, int dst_stride) { - int a1 = ((input_dc + 4) >> 3); - double ftmp[5]; + int a0 = ((input_dc + 4) >> 3); + double a1, ftmp[5]; int low32; __asm__ volatile ( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "dmtc1 %[a0], %[a1] \n\t" "pshufh %[a1], %[a1], %[ftmp0] \n\t" "ulw %[low32], 0x00(%[pred_ptr]) \n\t" "mtc1 %[low32], %[ftmp1] \n\t" @@ -244,9 +250,9 @@ void vp8_dc_only_idct_add_mmi(int16_t input_dc, unsigned char *pred_ptr, "gsswrc1 %[ftmp1], 0x00(%[dst_ptr]) \n\t" : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [low32]"=&r"(low32), - [dst_ptr]"+&r"(dst_ptr), [pred_ptr]"+&r"(pred_ptr) + [dst_ptr]"+&r"(dst_ptr), [pred_ptr]"+&r"(pred_ptr), [a1]"=&f"(a1) : [dst_stride]"r"((mips_reg)dst_stride), - [pred_stride]"r"((mips_reg)pred_stride), [a1]"f"(a1) + [pred_stride]"r"((mips_reg)pred_stride), [a0]"r"(a0) : "memory" ); } @@ -254,14 +260,15 @@ void vp8_dc_only_idct_add_mmi(int16_t input_dc, unsigned char *pred_ptr, void vp8_short_inv_walsh4x4_mmi(int16_t *input, int16_t *mb_dqcoeff) { int i; int16_t output[16]; - double ftmp[12]; - uint32_t tmp[1]; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_03) = { 0x0003000300030003ULL }; + double ff_ph_03, ftmp[12]; + uint64_t tmp[1]; __asm__ volatile ( + "dli %[tmp0], 0x0003000300030003 \n\t" + "dmtc1 %[tmp0], %[ff_ph_03] \n\t" MMI_LI(%[tmp0], 0x03) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" "gsldlc1 %[ftmp2], 0x0f(%[ip]) \n\t" @@ -317,8 +324,8 @@ void vp8_short_inv_walsh4x4_mmi(int16_t *input, int16_t *mb_dqcoeff) { [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), - [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]) - : [ip]"r"(input), [op]"r"(output), [ff_ph_03]"f"(ff_ph_03) + [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), [ff_ph_03]"=&f"(ff_ph_03) + : [ip]"r"(input), [op]"r"(output) : "memory" ); diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/loopfilter_filters_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/loopfilter_filters_mmi.c index f2182f95c..a07a7e3b4 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/loopfilter_filters_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/loopfilter_filters_mmi.c @@ -13,28 +13,25 @@ #include "vp8/common/onyxc_int.h" #include "vpx_ports/asmdefs_mmi.h" -DECLARE_ALIGNED(8, static const uint64_t, ff_ph_01) = { 0x0001000100010001ULL }; -DECLARE_ALIGNED(8, static const uint64_t, - ff_ph_003f) = { 0x003f003f003f003fULL }; -DECLARE_ALIGNED(8, static const uint64_t, - ff_ph_0900) = { 0x0900090009000900ULL }; -DECLARE_ALIGNED(8, static const uint64_t, - ff_ph_1200) = { 0x1200120012001200ULL }; -DECLARE_ALIGNED(8, static const uint64_t, - ff_ph_1b00) = { 0x1b001b001b001b00ULL }; -DECLARE_ALIGNED(8, static const uint64_t, ff_pb_fe) = { 0xfefefefefefefefeULL }; -DECLARE_ALIGNED(8, static const uint64_t, ff_pb_80) = { 0x8080808080808080ULL }; -DECLARE_ALIGNED(8, static const uint64_t, ff_pb_04) = { 0x0404040404040404ULL }; -DECLARE_ALIGNED(8, static const uint64_t, ff_pb_03) = { 0x0303030303030303ULL }; -DECLARE_ALIGNED(8, static const uint64_t, ff_pb_01) = { 0x0101010101010101ULL }; - void vp8_loop_filter_horizontal_edge_mmi( unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, const unsigned char *limit, const unsigned char *thresh, int count) { - uint32_t tmp[1]; + uint64_t tmp[1]; mips_reg addr[2]; double ftmp[12]; + double ff_ph_01, ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03; + /* clang-format off */ __asm__ volatile ( + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ff_ph_01] \n\t" + "dli %[tmp0], 0xfefefefefefefefe \n\t" + "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x8080808080808080 \n\t" + "dmtc1 %[tmp0], %[ff_pb_80] \n\t" + "dli %[tmp0], 0x0404040404040404 \n\t" + "dmtc1 %[tmp0], %[ff_pb_04] \n\t" + "dli %[tmp0], 0x0303030303030303 \n\t" + "dmtc1 %[tmp0], %[ff_pb_03] \n\t" "1: \n\t" "gsldlc1 %[ftmp10], 0x07(%[limit]) \n\t" "gsldrc1 %[ftmp10], 0x00(%[limit]) \n\t" @@ -56,14 +53,14 @@ void vp8_loop_filter_horizontal_edge_mmi( "gsldrc1 %[ftmp4], 0x00(%[addr1]) \n\t" "pasubub %[ftmp1], %[ftmp3], %[ftmp4] \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) "gsldlc1 %[ftmp5], 0x07(%[addr1]) \n\t" "gsldrc1 %[ftmp5], 0x00(%[addr1]) \n\t" "pasubub %[ftmp9], %[ftmp4], %[ftmp5] \n\t" "psubusb %[ftmp1], %[ftmp9], %[ftmp10] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" "gsldlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" "gsldrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" @@ -72,35 +69,35 @@ void vp8_loop_filter_horizontal_edge_mmi( "gsldrc1 %[ftmp7], 0x00(%[addr0]) \n\t" "pasubub %[ftmp11], %[ftmp7], %[ftmp6] \n\t" "psubusb %[ftmp1], %[ftmp11], %[ftmp10] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" MMI_ADDU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) "gsldlc1 %[ftmp8], 0x07(%[addr1]) \n\t" "gsldrc1 %[ftmp8], 0x00(%[addr1]) \n\t" "pasubub %[ftmp1], %[ftmp8], %[ftmp7] \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step_x2]) "gsldlc1 %[ftmp2], 0x07(%[addr1]) \n\t" "gsldrc1 %[ftmp2], 0x00(%[addr1]) \n\t" "pasubub %[ftmp1], %[ftmp2], %[ftmp8] \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" "pasubub %[ftmp1], %[ftmp5], %[ftmp6] \n\t" "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" "pasubub %[ftmp2], %[ftmp4], %[ftmp7] \n\t" - "and %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" - "li %[tmp0], 0x01 \n\t" - "mtc1 %[tmp0], %[ftmp10] \n\t" + "pand %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp10] \n\t" "psrlh %[ftmp2], %[ftmp2], %[ftmp10] \n\t" "paddusb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" "gsldlc1 %[ftmp10], 0x07(%[blimit]) \n\t" "gsldrc1 %[ftmp10], 0x00(%[blimit]) \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp10] \n\t" "gsldlc1 %[ftmp10], 0x07(%[thresh]) \n\t" @@ -108,72 +105,72 @@ void vp8_loop_filter_horizontal_edge_mmi( "psubusb %[ftmp1], %[ftmp9], %[ftmp10] \n\t" "psubusb %[ftmp2], %[ftmp11], %[ftmp10] \n\t" "paddb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "xor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" + "pxor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp2] \n\t" - "xor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" + "pxor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "xor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" - "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" + "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" "psubsb %[ftmp2], %[ftmp4], %[ftmp7] \n\t" - "and %[ftmp2], %[ftmp2], %[ftmp1] \n\t" + "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" "psubsb %[ftmp3], %[ftmp6], %[ftmp5] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" - "and %[ftmp2], %[ftmp2], %[ftmp0] \n\t" + "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" "paddsb %[ftmp8], %[ftmp2], %[ff_pb_03] \n\t" "paddsb %[ftmp9], %[ftmp2], %[ff_pb_04] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" "punpcklbh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" "punpckhbh %[ftmp11], %[ftmp11], %[ftmp8] \n\t" - "li %[tmp0], 0x0b \n\t" - "mtc1 %[tmp0], %[ftmp10] \n\t" + "dli %[tmp0], 0x0b \n\t" + "dmtc1 %[tmp0], %[ftmp10] \n\t" "psrah %[ftmp0], %[ftmp0], %[ftmp10] \n\t" "psrah %[ftmp11], %[ftmp11], %[ftmp10] \n\t" "packsshb %[ftmp8], %[ftmp0], %[ftmp11] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "punpcklbh %[ftmp0], %[ftmp0], %[ftmp9] \n\t" "psrah %[ftmp0], %[ftmp0], %[ftmp10] \n\t" - "xor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" + "pxor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" "punpckhbh %[ftmp9], %[ftmp11], %[ftmp9] \n\t" "psrah %[ftmp9], %[ftmp9], %[ftmp10] \n\t" "paddsh %[ftmp11], %[ftmp0], %[ff_ph_01] \n\t" "packsshb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" "paddsh %[ftmp9], %[ftmp9], %[ff_ph_01] \n\t" - "li %[tmp0], 0x01 \n\t" - "mtc1 %[tmp0], %[ftmp10] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp10] \n\t" "psrah %[ftmp11], %[ftmp11], %[ftmp10] \n\t" "psrah %[ftmp9], %[ftmp9], %[ftmp10] \n\t" "packsshb %[ftmp11], %[ftmp11], %[ftmp9] \n\t" "pandn %[ftmp1], %[ftmp1], %[ftmp11] \n\t" "paddsb %[ftmp5], %[ftmp5], %[ftmp8] \n\t" - "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) "gssdlc1 %[ftmp5], 0x07(%[addr1]) \n\t" "gssdrc1 %[ftmp5], 0x00(%[addr1]) \n\t" MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) "paddsb %[ftmp4], %[ftmp4], %[ftmp1] \n\t" - "xor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" "gssdlc1 %[ftmp4], 0x07(%[addr1]) \n\t" "gssdrc1 %[ftmp4], 0x00(%[addr1]) \n\t" "psubsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" "gssdlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" "gssdrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" "psubsb %[ftmp7], %[ftmp7], %[ftmp1] \n\t" - "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" + "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" "gssdlc1 %[ftmp7], 0x07(%[addr0]) \n\t" "gssdrc1 %[ftmp7], 0x00(%[addr0]) \n\t" @@ -188,17 +185,18 @@ void vp8_loop_filter_horizontal_edge_mmi( [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) + [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), + [ff_ph_01]"=&f"(ff_ph_01), [ff_pb_fe]"=&f"(ff_pb_fe), + [ff_pb_80]"=&f"(ff_pb_80), [ff_pb_04]"=&f"(ff_pb_04), + [ff_pb_03]"=&f"(ff_pb_03) : [limit]"r"(limit), [blimit]"r"(blimit), [thresh]"r"(thresh), [src_pixel_step]"r"((mips_reg)src_pixel_step), [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)), - [src_pixel_step_x4]"r"((mips_reg)(src_pixel_step<<2)), - [ff_ph_01]"f"(ff_ph_01), [ff_pb_fe]"f"(ff_pb_fe), - [ff_pb_80]"f"(ff_pb_80), [ff_pb_04]"f"(ff_pb_04), - [ff_pb_03]"f"(ff_pb_03) + [src_pixel_step_x4]"r"((mips_reg)(src_pixel_step<<2)) : "memory" ); + /* clang-format on */ } void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, @@ -206,11 +204,23 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, const unsigned char *blimit, const unsigned char *limit, const unsigned char *thresh, int count) { - uint32_t tmp[1]; + uint64_t tmp[1]; mips_reg addr[2]; double ftmp[13]; + double ff_pb_fe, ff_ph_01, ff_pb_03, ff_pb_04, ff_pb_80; + /* clang-format off */ __asm__ volatile ( + "dli %[tmp0], 0xfefefefefefefefe \n\t" + "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ff_ph_01] \n\t" + "dli %[tmp0], 0x0303030303030303 \n\t" + "dmtc1 %[tmp0], %[ff_pb_03] \n\t" + "dli %[tmp0], 0x0404040404040404 \n\t" + "dmtc1 %[tmp0], %[ff_pb_04] \n\t" + "dli %[tmp0], 0x8080808080808080 \n\t" + "dmtc1 %[tmp0], %[ff_pb_80] \n\t" MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) MMI_ADDU(%[src_ptr], %[src_ptr], %[tmp0]) MMI_SUBU(%[src_ptr], %[src_ptr], 0x04) @@ -288,23 +298,23 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, /* abs (q2-q1) */ "pasubub %[ftmp7], %[ftmp11], %[ftmp10] \n\t" "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" /* ftmp3: abs(q1-q0) */ "pasubub %[ftmp3], %[ftmp10], %[ftmp9] \n\t" "psubusb %[ftmp7], %[ftmp3], %[ftmp8] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" /* ftmp4: abs(p1-p0) */ "pasubub %[ftmp4], %[ftmp5], %[ftmp6] \n\t" "psubusb %[ftmp7], %[ftmp4], %[ftmp8] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" /* abs (p2-p1) */ "pasubub %[ftmp7], %[ftmp2], %[ftmp5] \n\t" "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" /* abs (p3-p2) */ "pasubub %[ftmp7], %[ftmp1], %[ftmp2] \n\t" "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" "gsldlc1 %[ftmp8], 0x07(%[blimit]) \n\t" "gsldrc1 %[ftmp8], 0x00(%[blimit]) \n\t" @@ -314,14 +324,14 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, "paddusb %[ftmp11], %[ftmp11], %[ftmp11] \n\t" /* abs (p1-q1) */ "pasubub %[ftmp12], %[ftmp10], %[ftmp5] \n\t" - "and %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" - "li %[tmp0], 0x01 \n\t" - "mtc1 %[tmp0], %[ftmp1] \n\t" + "pand %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp1] \n\t" "psrlh %[ftmp12], %[ftmp12], %[ftmp1] \n\t" "paddusb %[ftmp1], %[ftmp11], %[ftmp12] \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp8] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "xor %[ftmp1], %[ftmp1], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "pxor %[ftmp1], %[ftmp1], %[ftmp1] \n\t" /* ftmp0:mask */ "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp1] \n\t" @@ -331,41 +341,41 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, /* ftmp3: abs(q1-q0) ftmp4: abs(p1-p0) */ "psubusb %[ftmp4], %[ftmp4], %[ftmp8] \n\t" "psubusb %[ftmp3], %[ftmp3], %[ftmp8] \n\t" - "or %[ftmp2], %[ftmp4], %[ftmp3] \n\t" + "por %[ftmp2], %[ftmp4], %[ftmp3] \n\t" "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp1] \n\t" "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" /* ftmp1:hev */ - "xor %[ftmp1], %[ftmp2], %[ftmp1] \n\t" + "pxor %[ftmp1], %[ftmp2], %[ftmp1] \n\t" - "xor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" - "xor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" + "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" "psubsb %[ftmp2], %[ftmp5], %[ftmp10] \n\t" - "and %[ftmp2], %[ftmp2], %[ftmp1] \n\t" + "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" "psubsb %[ftmp3], %[ftmp9], %[ftmp6] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" /* ftmp2:filter_value */ - "and %[ftmp2], %[ftmp2], %[ftmp0] \n\t" + "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" "paddsb %[ftmp11], %[ftmp2], %[ff_pb_04] \n\t" "paddsb %[ftmp12], %[ftmp2], %[ff_pb_03] \n\t" - "li %[tmp0], 0x0b \n\t" - "mtc1 %[tmp0], %[ftmp7] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" + "dli %[tmp0], 0x0b \n\t" + "dmtc1 %[tmp0], %[ftmp7] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" "punpcklbh %[ftmp0], %[ftmp0], %[ftmp12] \n\t" "punpckhbh %[ftmp8], %[ftmp8], %[ftmp12] \n\t" "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" "psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t" "packsshb %[ftmp12], %[ftmp0], %[ftmp8] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" "punpcklbh %[ftmp0], %[ftmp0], %[ftmp11] \n\t" "punpckhbh %[ftmp8], %[ftmp8], %[ftmp11] \n\t" "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" @@ -373,22 +383,22 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, "packsshb %[ftmp11], %[ftmp0], %[ftmp8] \n\t" "psubsb %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "xor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" + "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" "paddsb %[ftmp6], %[ftmp6], %[ftmp12] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" "paddsh %[ftmp0], %[ftmp0], %[ff_ph_01] \n\t" "paddsh %[ftmp8], %[ftmp8], %[ff_ph_01] \n\t" - "li %[tmp0], 0x01 \n\t" - "mtc1 %[tmp0], %[ftmp7] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp7] \n\t" "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" "psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t" "packsshb %[ftmp2], %[ftmp0], %[ftmp8] \n\t" "pandn %[ftmp2], %[ftmp1], %[ftmp2] \n\t" "psubsb %[ftmp10], %[ftmp10], %[ftmp2] \n\t" - "xor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" "paddsb %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" /* ftmp5: *op1 ; ftmp6: *op0 */ "punpcklbh %[ftmp2], %[ftmp5], %[ftmp6] \n\t" @@ -408,7 +418,7 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp9] \n\t" - "dsrl %[ftmp2], %[ftmp2], %[ftmp9] \n\t" + "ssrld %[ftmp2], %[ftmp2], %[ftmp9] \n\t" MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) MMI_SUBU(%[addr1], %[addr0], %[tmp0]) "gsswlc1 %[ftmp2], 0x05(%[addr1]) \n\t" @@ -419,21 +429,21 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, "gsswlc1 %[ftmp6], 0x05(%[addr1]) \n\t" "gsswrc1 %[ftmp6], 0x02(%[addr1]) \n\t" - "dsrl %[ftmp6], %[ftmp6], %[ftmp9] \n\t" + "ssrld %[ftmp6], %[ftmp6], %[ftmp9] \n\t" MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) "gsswlc1 %[ftmp6], 0x05(%[addr1]) \n\t" "gsswrc1 %[ftmp6], 0x02(%[addr1]) \n\t" "gsswlc1 %[ftmp1], 0x05(%[src_ptr]) \n\t" "gsswrc1 %[ftmp1], 0x02(%[src_ptr]) \n\t" - "dsrl %[ftmp1], %[ftmp1], %[ftmp9] \n\t" + "ssrld %[ftmp1], %[ftmp1], %[ftmp9] \n\t" "gsswlc1 %[ftmp1], 0x05(%[addr0]) \n\t" "gsswrc1 %[ftmp1], 0x02(%[addr0]) \n\t" MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step]) "gsswlc1 %[ftmp5], 0x05(%[addr1]) \n\t" "gsswrc1 %[ftmp5], 0x02(%[addr1]) \n\t" - "dsrl %[ftmp5], %[ftmp5], %[ftmp9] \n\t" + "ssrld %[ftmp5], %[ftmp5], %[ftmp9] \n\t" MMI_ADDU(%[addr1], %[addr0], %[tmp0]) "gsswlc1 %[ftmp5], 0x05(%[addr1]) \n\t" "gsswrc1 %[ftmp5], 0x02(%[addr1]) \n\t" @@ -450,15 +460,16 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) + [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), + [ff_ph_01]"=&f"(ff_ph_01), [ff_pb_03]"=&f"(ff_pb_03), + [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_80]"=&f"(ff_pb_80), + [ff_pb_fe]"=&f"(ff_pb_fe) : [limit]"r"(limit), [blimit]"r"(blimit), [thresh]"r"(thresh), - [src_pixel_step]"r"((mips_reg)src_pixel_step), - [ff_ph_01]"f"(ff_ph_01), [ff_pb_03]"f"(ff_pb_03), - [ff_pb_04]"f"(ff_pb_04), [ff_pb_80]"f"(ff_pb_80), - [ff_pb_fe]"f"(ff_pb_fe) + [src_pixel_step]"r"((mips_reg)src_pixel_step) : "memory" ); + /* clang-format on */ } /* clang-format off */ @@ -484,10 +495,29 @@ void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, void vp8_mbloop_filter_horizontal_edge_mmi( unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, const unsigned char *limit, const unsigned char *thresh, int count) { - uint32_t tmp[1]; + uint64_t tmp[1]; double ftmp[13]; + double ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03, ff_ph_003f, ff_ph_0900, + ff_ph_1200, ff_ph_1b00; + /* clang-format off */ __asm__ volatile ( + "dli %[tmp0], 0xfefefefefefefefe \n\t" + "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x8080808080808080 \n\t" + "dmtc1 %[tmp0], %[ff_pb_80] \n\t" + "dli %[tmp0], 0x0404040404040404 \n\t" + "dmtc1 %[tmp0], %[ff_pb_04] \n\t" + "dli %[tmp0], 0x0303030303030303 \n\t" + "dmtc1 %[tmp0], %[ff_pb_03] \n\t" + "dli %[tmp0], 0x003f003f003f003f \n\t" + "dmtc1 %[tmp0], %[ff_ph_003f] \n\t" + "dli %[tmp0], 0x0900090009000900 \n\t" + "dmtc1 %[tmp0], %[ff_ph_0900] \n\t" + "dli %[tmp0], 0x1200120012001200 \n\t" + "dmtc1 %[tmp0], %[ff_ph_1200] \n\t" + "dli %[tmp0], 0x1b001b001b001b00 \n\t" + "dmtc1 %[tmp0], %[ff_ph_1b00] \n\t" MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) MMI_SUBU(%[src_ptr], %[src_ptr], %[tmp0]) "1: \n\t" @@ -532,31 +562,31 @@ void vp8_mbloop_filter_horizontal_edge_mmi( "psubusb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" "pasubub %[ftmp1], %[ftmp3], %[ftmp4] \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" "pasubub %[ftmp10], %[ftmp4], %[ftmp5] \n\t" "psubusb %[ftmp1], %[ftmp10], %[ftmp9] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" "pasubub %[ftmp11], %[ftmp7], %[ftmp6] \n\t" "psubusb %[ftmp1], %[ftmp11], %[ftmp9] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" "pasubub %[ftmp1], %[ftmp8], %[ftmp7] \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" "pasubub %[ftmp1], %[ftmp2], %[ftmp8] \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" "pasubub %[ftmp1], %[ftmp5], %[ftmp6] \n\t" "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" "pasubub %[ftmp2], %[ftmp4], %[ftmp7] \n\t" - "and %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" - "li %[tmp0], 0x01 \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "pand %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "psrlh %[ftmp2], %[ftmp2], %[ftmp9] \n\t" "paddusb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" "psubusb %[ftmp1], %[ftmp1], %[ftmp12] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" /* ftmp0: mask */ "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" @@ -565,27 +595,27 @@ void vp8_mbloop_filter_horizontal_edge_mmi( "psubusb %[ftmp1], %[ftmp10], %[ftmp9] \n\t" "psubusb %[ftmp2], %[ftmp11], %[ftmp9] \n\t" "paddb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "xor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" + "pxor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp2] \n\t" /* ftmp1: hev */ - "xor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" + "pxor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "xor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" - "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" + "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" "psubsb %[ftmp2], %[ftmp4], %[ftmp7] \n\t" "psubsb %[ftmp9], %[ftmp6], %[ftmp5] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - "and %[ftmp2], %[ftmp2], %[ftmp0] \n\t" + "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" "pandn %[ftmp12], %[ftmp1], %[ftmp2] \n\t" - "and %[ftmp2], %[ftmp2], %[ftmp1] \n\t" + "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" - "li %[tmp0], 0x0b \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x0b \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "paddsb %[ftmp0], %[ftmp2], %[ff_pb_03] \n\t" VP8_MBLOOP_HPSRAB "paddsb %[ftmp5], %[ftmp5], %[ftmp0] \n\t" @@ -593,15 +623,15 @@ void vp8_mbloop_filter_horizontal_edge_mmi( VP8_MBLOOP_HPSRAB "psubsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "li %[tmp0], 0x07 \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "dli %[tmp0], 0x07 \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_1b00]) "psubsb %[ftmp6], %[ftmp6], %[ftmp1] \n\t" "paddsb %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) MMI_SUBU(%[src_ptr], %[src_ptr], %[tmp0]) "gssdlc1 %[ftmp5], 0x07(%[src_ptr]) \n\t" @@ -613,8 +643,8 @@ void vp8_mbloop_filter_horizontal_edge_mmi( VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_1200]) "paddsb %[ftmp4], %[ftmp4], %[ftmp1] \n\t" "psubsb %[ftmp7], %[ftmp7], %[ftmp1] \n\t" - "xor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" - "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" + "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) "gssdlc1 %[ftmp7], 0x07(%[src_ptr]) \n\t" "gssdrc1 %[ftmp7], 0x00(%[src_ptr]) \n\t" @@ -624,12 +654,12 @@ void vp8_mbloop_filter_horizontal_edge_mmi( "gssdrc1 %[ftmp4], 0x00(%[src_ptr]) \n\t" VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_0900]) - "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" - "xor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" "paddsb %[ftmp3], %[ftmp3], %[ftmp1] \n\t" "psubsb %[ftmp8], %[ftmp8], %[ftmp1] \n\t" - "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" - "xor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" MMI_ADDU(%[src_ptr], %[src_ptr], %[tmp0]) "gssdlc1 %[ftmp8], 0x07(%[src_ptr]) \n\t" "gssdrc1 %[ftmp8], 0x00(%[src_ptr]) \n\t" @@ -649,21 +679,23 @@ void vp8_mbloop_filter_horizontal_edge_mmi( [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) + [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), + [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), + [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_03]"=&f"(ff_pb_03), + [ff_ph_0900]"=&f"(ff_ph_0900), [ff_ph_1b00]"=&f"(ff_ph_1b00), + [ff_ph_1200]"=&f"(ff_ph_1200), [ff_ph_003f]"=&f"(ff_ph_003f) : [limit]"r"(limit), [blimit]"r"(blimit), [thresh]"r"(thresh), - [src_pixel_step]"r"((mips_reg)src_pixel_step), - [ff_pb_fe]"f"(ff_pb_fe), [ff_pb_80]"f"(ff_pb_80), - [ff_pb_04]"f"(ff_pb_04), [ff_pb_03]"f"(ff_pb_03), - [ff_ph_0900]"f"(ff_ph_0900), [ff_ph_1b00]"f"(ff_ph_1b00), - [ff_ph_1200]"f"(ff_ph_1200), [ff_ph_003f]"f"(ff_ph_003f) + [src_pixel_step]"r"((mips_reg)src_pixel_step) : "memory" ); + /* clang-format on */ } +/* clang-format off */ #define VP8_MBLOOP_VPSRAB_ADDH \ - "xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" \ - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" \ + "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" \ + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" \ "punpcklbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t" \ "punpckhbh %[ftmp8], %[ftmp8], %[ftmp0] \n\t" @@ -673,15 +705,30 @@ void vp8_mbloop_filter_horizontal_edge_mmi( "psrah %[ftmp7], %[ftmp7], %[ftmp12] \n\t" \ "psrah %[ftmp8], %[ftmp8], %[ftmp12] \n\t" \ "packsshb %[ftmp3], %[ftmp7], %[ftmp8] \n\t" +/* clang-format on */ void vp8_mbloop_filter_vertical_edge_mmi( unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, const unsigned char *limit, const unsigned char *thresh, int count) { mips_reg tmp[1]; - DECLARE_ALIGNED(8, const uint64_t, srct[1]); + DECLARE_ALIGNED(8, const uint64_t, srct[2]); double ftmp[14]; + double ff_ph_003f, ff_ph_0900, ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03; + /* clang-format off */ __asm__ volatile ( + "dli %[tmp0], 0x003f003f003f003f \n\t" + "dmtc1 %[tmp0], %[ff_ph_003f] \n\t" + "dli %[tmp0], 0x0900090009000900 \n\t" + "dmtc1 %[tmp0], %[ff_ph_0900] \n\t" + "dli %[tmp0], 0xfefefefefefefefe \n\t" + "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x8080808080808080 \n\t" + "dmtc1 %[tmp0], %[ff_pb_80] \n\t" + "dli %[tmp0], 0x0404040404040404 \n\t" + "dmtc1 %[tmp0], %[ff_pb_04] \n\t" + "dli %[tmp0], 0x0303030303030303 \n\t" + "dmtc1 %[tmp0], %[ff_pb_03] \n\t" MMI_SUBU(%[src_ptr], %[src_ptr], 0x04) "1: \n\t" @@ -755,23 +802,23 @@ void vp8_mbloop_filter_vertical_edge_mmi( /* abs (q2-q1) */ "pasubub %[ftmp7], %[ftmp11], %[ftmp10] \n\t" "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" /* ftmp3: abs(q1-q0) */ "pasubub %[ftmp3], %[ftmp10], %[ftmp9] \n\t" "psubusb %[ftmp7], %[ftmp3], %[ftmp13] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" /* ftmp4: abs(p1-p0) */ "pasubub %[ftmp4], %[ftmp5], %[ftmp6] \n\t" "psubusb %[ftmp7], %[ftmp4], %[ftmp13] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" /* abs (p2-p1) */ "pasubub %[ftmp7], %[ftmp2], %[ftmp5] \n\t" "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" /* abs (p3-p2) */ "pasubub %[ftmp7], %[ftmp1], %[ftmp2] \n\t" "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" "gsldlc1 %[ftmp13], 0x07(%[blimit]) \n\t" "gsldrc1 %[ftmp13], 0x00(%[blimit]) \n\t" @@ -782,14 +829,14 @@ void vp8_mbloop_filter_vertical_edge_mmi( "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" /* abs (p1-q1) / 2 */ "pasubub %[ftmp12], %[ftmp10], %[ftmp5] \n\t" - "and %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" - "li %[tmp0], 0x01 \n\t" - "mtc1 %[tmp0], %[ftmp8] \n\t" + "pand %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp8] \n\t" "psrlh %[ftmp12], %[ftmp12], %[ftmp8] \n\t" "paddusb %[ftmp12], %[ftmp1], %[ftmp12] \n\t" "psubusb %[ftmp12], %[ftmp12], %[ftmp13] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp12] \n\t" - "xor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp12] \n\t" + "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" /* ftmp0: mask */ "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp12] \n\t" @@ -797,19 +844,19 @@ void vp8_mbloop_filter_vertical_edge_mmi( "psubusb %[ftmp4], %[ftmp4], %[ftmp7] \n\t" /* abs(q1-q0) - thresh */ "psubusb %[ftmp3], %[ftmp3], %[ftmp7] \n\t" - "or %[ftmp3], %[ftmp4], %[ftmp3] \n\t" + "por %[ftmp3], %[ftmp4], %[ftmp3] \n\t" "pcmpeqb %[ftmp3], %[ftmp3], %[ftmp12] \n\t" "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" /* ftmp1: hev */ - "xor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" + "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" /* ftmp2:ps2, ftmp5:ps1, ftmp6:ps0, ftmp9:qs0, ftmp10:qs1, ftmp11:qs2 */ - "xor %[ftmp11], %[ftmp11], %[ff_pb_80] \n\t" - "xor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" - "xor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - "xor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" + "pxor %[ftmp11], %[ftmp11], %[ff_pb_80] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" + "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" + "pxor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" "psubsb %[ftmp3], %[ftmp5], %[ftmp10] \n\t" "psubsb %[ftmp4], %[ftmp9], %[ftmp6] \n\t" @@ -817,15 +864,15 @@ void vp8_mbloop_filter_vertical_edge_mmi( "paddsb %[ftmp3], %[ftmp3], %[ftmp4] \n\t" "paddsb %[ftmp3], %[ftmp3], %[ftmp4] \n\t" /* filter_value &= mask */ - "and %[ftmp0], %[ftmp0], %[ftmp3] \n\t" + "pand %[ftmp0], %[ftmp0], %[ftmp3] \n\t" /* Filter2 = filter_value & hev */ - "and %[ftmp3], %[ftmp1], %[ftmp0] \n\t" + "pand %[ftmp3], %[ftmp1], %[ftmp0] \n\t" /* filter_value &= ~hev */ "pandn %[ftmp0], %[ftmp1], %[ftmp0] \n\t" "paddsb %[ftmp4], %[ftmp3], %[ff_pb_04] \n\t" - "li %[tmp0], 0x0b \n\t" - "mtc1 %[tmp0], %[ftmp12] \n\t" + "dli %[tmp0], 0x0b \n\t" + "dmtc1 %[tmp0], %[ftmp12] \n\t" "punpcklbh %[ftmp7], %[ftmp7], %[ftmp4] \n\t" "punpckhbh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" "psrah %[ftmp7], %[ftmp7], %[ftmp12] \n\t" @@ -842,8 +889,8 @@ void vp8_mbloop_filter_vertical_edge_mmi( /* ftmp6: ps0 */ "paddsb %[ftmp6], %[ftmp6], %[ftmp3] \n\t" - "li %[tmp0], 0x07 \n\t" - "mtc1 %[tmp0], %[ftmp12] \n\t" + "dli %[tmp0], 0x07 \n\t" + "dmtc1 %[tmp0], %[ftmp12] \n\t" VP8_MBLOOP_VPSRAB_ADDH "paddh %[ftmp1], %[ff_ph_0900], %[ff_ph_0900] \n\t" "paddh %[ftmp1], %[ftmp1], %[ff_ph_0900] \n\t" @@ -852,10 +899,10 @@ void vp8_mbloop_filter_vertical_edge_mmi( VP8_MBLOOP_VPSRAB_ADDT "psubsb %[ftmp4], %[ftmp9], %[ftmp3] \n\t" /* ftmp9: oq0 */ - "xor %[ftmp9], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp9], %[ftmp4], %[ff_pb_80] \n\t" "paddsb %[ftmp4], %[ftmp6], %[ftmp3] \n\t" /* ftmp6: op0 */ - "xor %[ftmp6], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp4], %[ff_pb_80] \n\t" VP8_MBLOOP_VPSRAB_ADDH "paddh %[ftmp1], %[ff_ph_0900], %[ff_ph_0900] \n\t" @@ -864,10 +911,10 @@ void vp8_mbloop_filter_vertical_edge_mmi( VP8_MBLOOP_VPSRAB_ADDT "psubsb %[ftmp4], %[ftmp10], %[ftmp3] \n\t" /* ftmp10: oq1 */ - "xor %[ftmp10], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp10], %[ftmp4], %[ff_pb_80] \n\t" "paddsb %[ftmp4], %[ftmp5], %[ftmp3] \n\t" /* ftmp5: op1 */ - "xor %[ftmp5], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp5], %[ftmp4], %[ff_pb_80] \n\t" VP8_MBLOOP_VPSRAB_ADDH "pmulhh %[ftmp7], %[ftmp7], %[ff_ph_0900] \n\t" @@ -875,10 +922,10 @@ void vp8_mbloop_filter_vertical_edge_mmi( VP8_MBLOOP_VPSRAB_ADDT "psubsb %[ftmp4], %[ftmp11], %[ftmp3] \n\t" /* ftmp11: oq2 */ - "xor %[ftmp11], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp11], %[ftmp4], %[ff_pb_80] \n\t" "paddsb %[ftmp4], %[ftmp2], %[ftmp3] \n\t" /* ftmp2: op2 */ - "xor %[ftmp2], %[ftmp4], %[ff_pb_80] \n\t" + "pxor %[ftmp2], %[ftmp4], %[ff_pb_80] \n\t" "ldc1 %[ftmp12], 0x00(%[srct]) \n\t" "ldc1 %[ftmp8], 0x08(%[srct]) \n\t" @@ -948,41 +995,58 @@ void vp8_mbloop_filter_vertical_edge_mmi( [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), [ftmp12]"=&f"(ftmp[12]), [ftmp13]"=&f"(ftmp[13]), [tmp0]"=&r"(tmp[0]), [src_ptr]"+&r"(src_ptr), - [count]"+&r"(count) + [count]"+&r"(count), + [ff_ph_003f]"=&f"(ff_ph_003f), [ff_ph_0900]"=&f"(ff_ph_0900), + [ff_pb_03]"=&f"(ff_pb_03), [ff_pb_04]"=&f"(ff_pb_04), + [ff_pb_80]"=&f"(ff_pb_80), [ff_pb_fe]"=&f"(ff_pb_fe) : [limit]"r"(limit), [blimit]"r"(blimit), [srct]"r"(srct), [thresh]"r"(thresh), - [src_pixel_step]"r"((mips_reg)src_pixel_step), - [ff_ph_003f]"f"(ff_ph_003f), [ff_ph_0900]"f"(ff_ph_0900), - [ff_pb_03]"f"(ff_pb_03), [ff_pb_04]"f"(ff_pb_04), - [ff_pb_80]"f"(ff_pb_80), [ff_pb_fe]"f"(ff_pb_fe) + [src_pixel_step]"r"((mips_reg)src_pixel_step) : "memory" ); + /* clang-format on */ } +/* clang-format off */ #define VP8_SIMPLE_HPSRAB \ "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" \ "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" \ "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" \ "psrah %[ftmp1], %[ftmp5], %[ftmp10] \n\t" \ "psllh %[ftmp1], %[ftmp1], %[ftmp8] \n\t" \ - "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" +/* clang-format on */ void vp8_loop_filter_simple_horizontal_edge_mmi(unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit) { - uint32_t tmp[1], count = 2; + uint64_t tmp[1], count = 2; mips_reg addr[2]; double ftmp[12]; + double ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_01; + /* clang-format off */ __asm__ volatile ( - "li %[tmp0], 0x08 \n\t" - "mtc1 %[tmp0], %[ftmp8] \n\t" - "li %[tmp0], 0x03 \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" - "li %[tmp0], 0x0b \n\t" - "mtc1 %[tmp0], %[ftmp10] \n\t" - "li %[tmp0], 0x01 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" + "dli %[tmp0], 0x0b \n\t" + "dmtc1 %[tmp0], %[ftmp10] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" + "dli %[tmp0], 0x08 \n\t" + "dmtc1 %[tmp0], %[ftmp8] \n\t" + "dli %[tmp0], 0x03 \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x0b \n\t" + "dmtc1 %[tmp0], %[ftmp10] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" + "dli %[tmp0], 0xfefefefefefefefe \n\t" + "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x8080808080808080 \n\t" + "dmtc1 %[tmp0], %[ff_pb_80] \n\t" + "dli %[tmp0], 0x0404040404040404 \n\t" + "dmtc1 %[tmp0], %[ff_pb_04] \n\t" + "dli %[tmp0], 0x0101010101010101 \n\t" + "dmtc1 %[tmp0], %[ff_pb_01] \n\t" "1: \n\t" "gsldlc1 %[ftmp3], 0x07(%[blimit]) \n\t" @@ -996,7 +1060,7 @@ void vp8_loop_filter_simple_horizontal_edge_mmi(unsigned char *src_ptr, "gsldlc1 %[ftmp7], 0x07(%[addr0]) \n\t" "gsldrc1 %[ftmp7], 0x00(%[addr0]) \n\t" "pasubub %[ftmp1], %[ftmp7], %[ftmp2] \n\t" - "and %[ftmp1], %[ftmp1], %[ff_pb_fe] \n\t" + "pand %[ftmp1], %[ftmp1], %[ff_pb_fe] \n\t" "psrlh %[ftmp1], %[ftmp1], %[ftmp11] \n\t" MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) @@ -1008,31 +1072,31 @@ void vp8_loop_filter_simple_horizontal_edge_mmi(unsigned char *src_ptr, "paddusb %[ftmp5], %[ftmp5], %[ftmp5] \n\t" "paddusb %[ftmp5], %[ftmp5], %[ftmp1] \n\t" "psubusb %[ftmp5], %[ftmp5], %[ftmp3] \n\t" - "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" "pcmpeqb %[ftmp5], %[ftmp5], %[ftmp3] \n\t" - "xor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" - "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" + "pxor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" + "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" "psubsb %[ftmp2], %[ftmp2], %[ftmp7] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "xor %[ftmp3], %[ftmp0], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp3], %[ftmp0], %[ff_pb_80] \n\t" "psubsb %[ftmp0], %[ftmp3], %[ftmp6] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - "and %[ftmp5], %[ftmp5], %[ftmp2] \n\t" + "pand %[ftmp5], %[ftmp5], %[ftmp2] \n\t" "paddsb %[ftmp5], %[ftmp5], %[ff_pb_04] \n\t" VP8_SIMPLE_HPSRAB "psubsb %[ftmp3], %[ftmp3], %[ftmp0] \n\t" - "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" "gssdlc1 %[ftmp3], 0x07(%[src_ptr]) \n\t" "gssdrc1 %[ftmp3], 0x00(%[src_ptr]) \n\t" "psubsb %[ftmp5], %[ftmp5], %[ff_pb_01] \n\t" VP8_SIMPLE_HPSRAB "paddsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) "gssdlc1 %[ftmp6], 0x07(%[addr1]) \n\t" "gssdrc1 %[ftmp6], 0x00(%[addr1]) \n\t" @@ -1048,30 +1112,43 @@ void vp8_loop_filter_simple_horizontal_edge_mmi(unsigned char *src_ptr, [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) + [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), + [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), + [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_01]"=&f"(ff_pb_01) : [blimit]"r"(blimit), [src_pixel_step]"r"((mips_reg)src_pixel_step), - [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)), - [ff_pb_fe]"f"(ff_pb_fe), [ff_pb_80]"f"(ff_pb_80), - [ff_pb_04]"f"(ff_pb_04), [ff_pb_01]"f"(ff_pb_01) + [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)) : "memory" ); + /* clang-format on */ } void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit) { - uint32_t tmp[1], count = 2; + uint64_t tmp[1], count = 2; mips_reg addr[2]; - DECLARE_ALIGNED(8, const uint64_t, srct[1]); - double ftmp[12]; + DECLARE_ALIGNED(8, const uint64_t, srct[2]); + double ftmp[12], ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_01; + /* clang-format off */ __asm__ volatile ( - "li %[tmp0], 0x08 \n\t" - "mtc1 %[tmp0], %[ftmp8] \n\t" - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp10] \n\t" - + "dli %[tmp0], 0x08 \n\t" + "dmtc1 %[tmp0], %[ftmp8] \n\t" + "dli %[tmp0], 0x20 \n\t" + "dmtc1 %[tmp0], %[ftmp10] \n\t" + "dli %[tmp0], 0x08 \n\t" + "dmtc1 %[tmp0], %[ftmp8] \n\t" + "dli %[tmp0], 0x20 \n\t" + "dmtc1 %[tmp0], %[ftmp10] \n\t" + "dli %[tmp0], 0xfefefefefefefefe \n\t" + "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" + "dli %[tmp0], 0x8080808080808080 \n\t" + "dmtc1 %[tmp0], %[ff_pb_80] \n\t" + "dli %[tmp0], 0x0404040404040404 \n\t" + "dmtc1 %[tmp0], %[ff_pb_04] \n\t" + "dli %[tmp0], 0x0101010101010101 \n\t" + "dmtc1 %[tmp0], %[ff_pb_01] \n\t" MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step_x4]) MMI_SUBU(%[src_ptr], %[src_ptr], 0x02) @@ -1118,10 +1195,10 @@ void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, "punpckhwd %[ftmp3], %[ftmp2], %[ftmp5] \n\t" "punpcklwd %[ftmp2], %[ftmp2], %[ftmp5] \n\t" - "li %[tmp0], 0x01 \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x01 \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "pasubub %[ftmp6], %[ftmp3], %[ftmp0] \n\t" - "and %[ftmp6], %[ftmp6], %[ff_pb_fe] \n\t" + "pand %[ftmp6], %[ftmp6], %[ff_pb_fe] \n\t" "psrlh %[ftmp6], %[ftmp6], %[ftmp9] \n\t" "pasubub %[ftmp5], %[ftmp1], %[ftmp2] \n\t" "paddusb %[ftmp5], %[ftmp5], %[ftmp5] \n\t" @@ -1130,53 +1207,53 @@ void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, "gsldlc1 %[ftmp7], 0x07(%[blimit]) \n\t" "gsldrc1 %[ftmp7], 0x00(%[blimit]) \n\t" "psubusb %[ftmp5], %[ftmp5], %[ftmp7] \n\t" - "xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" + "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" "pcmpeqb %[ftmp5], %[ftmp5], %[ftmp7] \n\t" "sdc1 %[ftmp0], 0x00(%[srct]) \n\t" "sdc1 %[ftmp3], 0x08(%[srct]) \n\t" - "xor %[ftmp0], %[ftmp0], %[ff_pb_80] \n\t" - "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ff_pb_80] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" "psubsb %[ftmp0], %[ftmp0], %[ftmp3] \n\t" - "xor %[ftmp6], %[ftmp1], %[ff_pb_80] \n\t" - "xor %[ftmp3], %[ftmp2], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp1], %[ff_pb_80] \n\t" + "pxor %[ftmp3], %[ftmp2], %[ff_pb_80] \n\t" "psubsb %[ftmp7], %[ftmp3], %[ftmp6] \n\t" "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - "and %[ftmp5], %[ftmp5], %[ftmp0] \n\t" + "pand %[ftmp5], %[ftmp5], %[ftmp0] \n\t" "paddsb %[ftmp5], %[ftmp5], %[ff_pb_04] \n\t" - "li %[tmp0], 0x03 \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x03 \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" - "li %[tmp0], 0x0b \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x0b \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "psrah %[ftmp7], %[ftmp5], %[ftmp9] \n\t" "psllh %[ftmp7], %[ftmp7], %[ftmp8] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" "psubsb %[ftmp3], %[ftmp3], %[ftmp0] \n\t" - "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" "psubsb %[ftmp5], %[ftmp5], %[ff_pb_01] \n\t" - "li %[tmp0], 0x03 \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x03 \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" - "li %[tmp0], 0x0b \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x0b \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "psrah %[ftmp5], %[ftmp5], %[ftmp9] \n\t" "psllh %[ftmp5], %[ftmp5], %[ftmp8] \n\t" - "or %[ftmp0], %[ftmp0], %[ftmp5] \n\t" + "por %[ftmp0], %[ftmp0], %[ftmp5] \n\t" "paddsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" "ldc1 %[ftmp0], 0x00(%[srct]) \n\t" "ldc1 %[ftmp4], 0x08(%[srct]) \n\t" @@ -1195,7 +1272,7 @@ void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, "punpckhhw %[ftmp5], %[ftmp1], %[ftmp3] \n\t" "punpcklhw %[ftmp1], %[ftmp1], %[ftmp3] \n\t" - "dsrl %[ftmp0], %[ftmp0], %[ftmp10] \n\t" + "ssrld %[ftmp0], %[ftmp0], %[ftmp10] \n\t" MMI_SUBU(%[addr1], %[addr0], %[src_pixel_step_x4]) "gsswlc1 %[ftmp0], 0x03(%[addr1]) \n\t" "gsswrc1 %[ftmp0], 0x00(%[addr1]) \n\t" @@ -1203,7 +1280,7 @@ void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, "gsswlc1 %[ftmp6], 0x03(%[addr1]) \n\t" "gsswrc1 %[ftmp6], 0x00(%[addr1]) \n\t" - "dsrl %[ftmp6], %[ftmp6], %[ftmp10] \n\t" + "ssrld %[ftmp6], %[ftmp6], %[ftmp10] \n\t" "gsswlc1 %[ftmp1], 0x03(%[src_ptr]) \n\t" "gsswrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" @@ -1215,11 +1292,11 @@ void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, "gsswlc1 %[ftmp5], 0x03(%[addr1]) \n\t" "gsswrc1 %[ftmp5], 0x00(%[addr1]) \n\t" - "dsrl %[ftmp1], %[ftmp1], %[ftmp10] \n\t" + "ssrld %[ftmp1], %[ftmp1], %[ftmp10] \n\t" "gsswlc1 %[ftmp1], 0x03(%[addr0]) \n\t" "gsswrc1 %[ftmp1], 0x00(%[addr0]) \n\t" - "dsrl %[ftmp5], %[ftmp5], %[ftmp10] \n\t" + "ssrld %[ftmp5], %[ftmp5], %[ftmp10] \n\t" MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step_x2]) "gsswlc1 %[ftmp5], 0x03(%[addr1]) \n\t" "gsswrc1 %[ftmp5], 0x00(%[addr1]) \n\t" @@ -1235,16 +1312,17 @@ void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) + [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), + [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), + [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_01]"=&f"(ff_pb_01) : [blimit]"r"(blimit), [srct]"r"(srct), [src_pixel_step]"r"((mips_reg)src_pixel_step), [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)), [src_pixel_step_x4]"r"((mips_reg)(src_pixel_step<<2)), - [src_pixel_step_x8]"r"((mips_reg)(src_pixel_step<<3)), - [ff_pb_fe]"f"(ff_pb_fe), [ff_pb_80]"f"(ff_pb_80), - [ff_pb_04]"f"(ff_pb_04), [ff_pb_01]"f"(ff_pb_01) + [src_pixel_step_x8]"r"((mips_reg)(src_pixel_step<<3)) : "memory" ); + /* clang-format on */ } /* Horizontal MB filtering */ diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/sixtap_filter_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/sixtap_filter_mmi.c index 77d665d45..b85f73fdf 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/sixtap_filter_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/mmi/sixtap_filter_mmi.c @@ -70,9 +70,8 @@ static INLINE void vp8_filter_block1d_h6_mmi(unsigned char *src_ptr, unsigned int output_height, unsigned int output_width, const int16_t *vp8_filter) { - uint32_t tmp[1]; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; - + uint64_t tmp[1]; + double ff_ph_40; #if _MIPS_SIM == _ABIO32 register double fzero asm("$f0"); register double ftmp0 asm("$f2"); @@ -103,18 +102,21 @@ static INLINE void vp8_filter_block1d_h6_mmi(unsigned char *src_ptr, register double ftmp11 asm("$f12"); #endif // _MIPS_SIM == _ABIO32 + /* clang-format off */ __asm__ volatile ( + "dli %[tmp0], 0x0040004000400040 \n\t" + "dmtc1 %[tmp0], %[ff_ph_40] \n\t" "ldc1 %[ftmp0], 0x00(%[vp8_filter]) \n\t" "ldc1 %[ftmp1], 0x10(%[vp8_filter]) \n\t" "ldc1 %[ftmp2], 0x20(%[vp8_filter]) \n\t" "ldc1 %[ftmp3], 0x30(%[vp8_filter]) \n\t" "ldc1 %[ftmp4], 0x40(%[vp8_filter]) \n\t" "ldc1 %[ftmp5], 0x50(%[vp8_filter]) \n\t" - "xor %[fzero], %[fzero], %[fzero] \n\t" - "li %[tmp0], 0x07 \n\t" - "mtc1 %[tmp0], %[ftmp7] \n\t" - "li %[tmp0], 0x08 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" + "pxor %[fzero], %[fzero], %[fzero] \n\t" + "dli %[tmp0], 0x07 \n\t" + "dmtc1 %[tmp0], %[ftmp7] \n\t" + "dli %[tmp0], 0x08 \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" "1: \n\t" "gsldlc1 %[ftmp9], 0x05(%[src_ptr]) \n\t" @@ -137,12 +139,12 @@ static INLINE void vp8_filter_block1d_h6_mmi(unsigned char *src_ptr, "pmullh %[ftmp6], %[ftmp6], %[ftmp5] \n\t" "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" - "dsrl %[ftmp10], %[ftmp10], %[ftmp11] \n\t" + "ssrld %[ftmp10], %[ftmp10], %[ftmp11] \n\t" "punpcklbh %[ftmp6], %[ftmp10], %[fzero] \n\t" "pmullh %[ftmp6], %[ftmp6], %[ftmp2] \n\t" "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" - "dsrl %[ftmp10], %[ftmp10], %[ftmp11] \n\t" + "ssrld %[ftmp10], %[ftmp10], %[ftmp11] \n\t" "punpcklbh %[ftmp6], %[ftmp10], %[fzero] \n\t" "pmullh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" @@ -166,21 +168,22 @@ static INLINE void vp8_filter_block1d_h6_mmi(unsigned char *src_ptr, [ftmp9]"=&f"(ftmp9), [ftmp10]"=&f"(ftmp10), [ftmp11]"=&f"(ftmp11), [tmp0]"=&r"(tmp[0]), [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height), - [src_ptr]"+&r"(src_ptr) + [src_ptr]"+&r"(src_ptr), [ff_ph_40]"=&f"(ff_ph_40) : [src_pixels_per_line]"r"((mips_reg)src_pixels_per_line), - [vp8_filter]"r"(vp8_filter), [output_width]"r"(output_width), - [ff_ph_40]"f"(ff_ph_40) + [vp8_filter]"r"(vp8_filter), [output_width]"r"(output_width) : "memory" ); + /* clang-format on */ } /* Horizontal filter: pixel_step is always W */ static INLINE void vp8_filter_block1dc_v6_mmi( uint16_t *src_ptr, unsigned char *output_ptr, unsigned int output_height, int output_pitch, unsigned int pixels_per_line, const int16_t *vp8_filter) { - DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; - uint32_t tmp[1]; + double ff_ph_40; + uint64_t tmp[1]; mips_reg addr[1]; + #if _MIPS_SIM == _ABIO32 register double fzero asm("$f0"); register double ftmp0 asm("$f2"); @@ -215,16 +218,19 @@ static INLINE void vp8_filter_block1dc_v6_mmi( register double ftmp13 asm("$f14"); #endif // _MIPS_SIM == _ABIO32 + /* clang-format off */ __asm__ volatile ( + "dli %[tmp0], 0x0040004000400040 \n\t" + "dmtc1 %[tmp0], %[ff_ph_40] \n\t" "ldc1 %[ftmp0], 0x00(%[vp8_filter]) \n\t" "ldc1 %[ftmp1], 0x10(%[vp8_filter]) \n\t" "ldc1 %[ftmp2], 0x20(%[vp8_filter]) \n\t" "ldc1 %[ftmp3], 0x30(%[vp8_filter]) \n\t" "ldc1 %[ftmp4], 0x40(%[vp8_filter]) \n\t" "ldc1 %[ftmp5], 0x50(%[vp8_filter]) \n\t" - "xor %[fzero], %[fzero], %[fzero] \n\t" - "li %[tmp0], 0x07 \n\t" - "mtc1 %[tmp0], %[ftmp13] \n\t" + "pxor %[fzero], %[fzero], %[fzero] \n\t" + "dli %[tmp0], 0x07 \n\t" + "dmtc1 %[tmp0], %[ftmp13] \n\t" /* In order to make full use of memory load delay slot, * Operation of memory loading and calculating has been rearranged. @@ -285,15 +291,16 @@ static INLINE void vp8_filter_block1dc_v6_mmi( [ftmp11]"=&f"(ftmp11), [ftmp12]"=&f"(ftmp12), [ftmp13]"=&f"(ftmp13), [tmp0]"=&r"(tmp[0]), [addr0]"=&r"(addr[0]), [src_ptr]"+&r"(src_ptr), - [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height) + [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height), + [ff_ph_40]"=&f"(ff_ph_40) : [pixels_per_line]"r"((mips_reg)pixels_per_line), [pixels_per_line_x2]"r"((mips_reg)(pixels_per_line<<1)), [pixels_per_line_x4]"r"((mips_reg)(pixels_per_line<<2)), [vp8_filter]"r"(vp8_filter), - [output_pitch]"r"((mips_reg)output_pitch), - [ff_ph_40]"f"(ff_ph_40) + [output_pitch]"r"((mips_reg)output_pitch) : "memory" ); + /* clang-format on */ } /* When xoffset == 0, vp8_filter= {0,0,128,0,0,0}, @@ -313,8 +320,9 @@ static INLINE void vp8_filter_block1d_h6_filter0_mmi( register double ftmp1 asm("$f2"); #endif // _MIPS_SIM == _ABIO32 + /* clang-format off */ __asm__ volatile ( - "xor %[fzero], %[fzero], %[fzero] \n\t" + "pxor %[fzero], %[fzero], %[fzero] \n\t" "1: \n\t" "gsldlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" @@ -335,6 +343,7 @@ static INLINE void vp8_filter_block1d_h6_filter0_mmi( [output_width]"r"(output_width) : "memory" ); + /* clang-format on */ } static INLINE void vp8_filter_block1dc_v6_filter0_mmi( @@ -350,8 +359,9 @@ static INLINE void vp8_filter_block1dc_v6_filter0_mmi( register double ftmp1 asm("$f2"); #endif // _MIPS_SIM == _ABIO32 + /* clang-format on */ __asm__ volatile ( - "xor %[fzero], %[fzero], %[fzero] \n\t" + "pxor %[fzero], %[fzero], %[fzero] \n\t" "1: \n\t" "gsldlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" @@ -371,6 +381,7 @@ static INLINE void vp8_filter_block1dc_v6_filter0_mmi( [output_pitch]"r"((mips_reg)output_pitch) : "memory" ); + /* clang-format on */ } #define sixtapNxM(n, m) \ diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/msa/vp8_macros_msa.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/msa/vp8_macros_msa.h index 14f83799f..ddc881a7f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/msa/vp8_macros_msa.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/mips/msa/vp8_macros_msa.h @@ -122,10 +122,10 @@ const uint8_t *psrc_m = (const uint8_t *)(psrc); \ uint32_t val_m; \ \ - asm volatile("ulw %[val_m], %[psrc_m] \n\t" \ - \ - : [val_m] "=r"(val_m) \ - : [psrc_m] "m"(*psrc_m)); \ + asm volatile("lwr %[val_m], 0(%[psrc_m]) \n\t" \ + "lwl %[val_m], 3(%[psrc_m]) \n\t" \ + : [val_m] "=&r"(val_m) \ + : [psrc_m] "r"(psrc_m)); \ \ val_m; \ }) @@ -136,10 +136,10 @@ const uint8_t *psrc_m = (const uint8_t *)(psrc); \ uint64_t val_m = 0; \ \ - asm volatile("uld %[val_m], %[psrc_m] \n\t" \ - \ - : [val_m] "=r"(val_m) \ - : [psrc_m] "m"(*psrc_m)); \ + asm volatile("ldr %[val_m], 0(%[psrc_m]) \n\t" \ + "ldl %[val_m], 7(%[psrc_m]) \n\t" \ + : [val_m] "=&r"(val_m) \ + : [psrc_m] "r"(psrc_m)); \ \ val_m; \ }) diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/threading.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/threading.h index f92136938..1cfb9fec5 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/threading.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/threading.h @@ -171,17 +171,20 @@ static inline int sem_destroy(sem_t *sem) { #define sem_wait(sem) (semaphore_wait(*sem)) #define sem_post(sem) semaphore_signal(*sem) #define sem_destroy(sem) semaphore_destroy(mach_task_self(), *sem) -#define thread_sleep(nms) -/* { struct timespec ts;ts.tv_sec=0; ts.tv_nsec = - 1000*nms;nanosleep(&ts, NULL);} */ #else #include #include -#define thread_sleep(nms) sched_yield(); +#endif /* __APPLE__ */ +/* Not Windows. Assume pthreads */ + +/* thread_sleep implementation: yield unless Linux/Unix. */ +#if defined(__unix__) || defined(__APPLE__) +#define thread_sleep(nms) /* {struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ -#endif -/* Not Windows. Assume pthreads */ +#else +#define thread_sleep(nms) sched_yield(); +#endif /* __unix__ || __APPLE__ */ #endif diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/dequantize_mmx.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/dequantize_mmx.asm index bfdd99778..0a269e15f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/dequantize_mmx.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/dequantize_mmx.asm @@ -14,7 +14,7 @@ SECTION .text ;void vp8_dequantize_b_impl_mmx(short *sq, short *dq, short *q) -global sym(vp8_dequantize_b_impl_mmx) PRIVATE +globalsym(vp8_dequantize_b_impl_mmx) sym(vp8_dequantize_b_impl_mmx): push rbp mov rbp, rsp @@ -56,7 +56,7 @@ sym(vp8_dequantize_b_impl_mmx): ;short *dq, 1 ;unsigned char *dest, 2 ;int stride) 3 -global sym(vp8_dequant_idct_add_mmx) PRIVATE +globalsym(vp8_dequant_idct_add_mmx) sym(vp8_dequant_idct_add_mmx): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_mmx.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_mmx.asm index 5773d9d84..6cea86fe0 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_mmx.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_mmx.asm @@ -35,7 +35,7 @@ SECTION .text ;void vp8_short_idct4x4llm_mmx(short *input, unsigned char *pred, ;int pitch, unsigned char *dest,int stride) -global sym(vp8_short_idct4x4llm_mmx) PRIVATE +globalsym(vp8_short_idct4x4llm_mmx) sym(vp8_short_idct4x4llm_mmx): push rbp mov rbp, rsp @@ -225,7 +225,7 @@ sym(vp8_short_idct4x4llm_mmx): ;int pred_stride, ;unsigned char *dst_ptr, ;int stride) -global sym(vp8_dc_only_idct_add_mmx) PRIVATE +globalsym(vp8_dc_only_idct_add_mmx) sym(vp8_dc_only_idct_add_mmx): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_sse2.asm index 560faba00..bb79d2da3 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/idctllm_sse2.asm @@ -21,7 +21,7 @@ SECTION .text -global sym(vp8_idct_dequant_0_2x_sse2) PRIVATE +globalsym(vp8_idct_dequant_0_2x_sse2) sym(vp8_idct_dequant_0_2x_sse2): push rbp mov rbp, rsp @@ -103,7 +103,7 @@ sym(vp8_idct_dequant_0_2x_sse2): ; unsigned char *dst - 2 ; int dst_stride - 3 ; ) -global sym(vp8_idct_dequant_full_2x_sse2) PRIVATE +globalsym(vp8_idct_dequant_full_2x_sse2) sym(vp8_idct_dequant_full_2x_sse2): push rbp mov rbp, rsp @@ -360,7 +360,7 @@ sym(vp8_idct_dequant_full_2x_sse2): ; int dst_stride - 3 ; short *dc - 4 ; ) -global sym(vp8_idct_dequant_dc_0_2x_sse2) PRIVATE +globalsym(vp8_idct_dequant_dc_0_2x_sse2) sym(vp8_idct_dequant_dc_0_2x_sse2): push rbp mov rbp, rsp @@ -436,7 +436,7 @@ sym(vp8_idct_dequant_dc_0_2x_sse2): ; int dst_stride - 3 ; short *dc - 4 ; ) -global sym(vp8_idct_dequant_dc_full_2x_sse2) PRIVATE +globalsym(vp8_idct_dequant_dc_full_2x_sse2) sym(vp8_idct_dequant_dc_full_2x_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/iwalsh_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/iwalsh_sse2.asm index 0043e93b0..56f37c3e0 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/iwalsh_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/iwalsh_sse2.asm @@ -14,7 +14,7 @@ SECTION .text ;void vp8_short_inv_walsh4x4_sse2(short *input, short *mb_dqcoeff) -global sym(vp8_short_inv_walsh4x4_sse2) PRIVATE +globalsym(vp8_short_inv_walsh4x4_sse2) sym(vp8_short_inv_walsh4x4_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_block_sse2_x86_64.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_block_sse2_x86_64.asm index 6a3d05290..8d12f5385 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_block_sse2_x86_64.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_block_sse2_x86_64.asm @@ -135,7 +135,7 @@ SECTION .text ; const char *limit, ; const char *thresh ;) -global sym(vp8_loop_filter_bh_y_sse2) PRIVATE +globalsym(vp8_loop_filter_bh_y_sse2) sym(vp8_loop_filter_bh_y_sse2): %if LIBVPX_YASM_WIN64 @@ -277,7 +277,7 @@ LF_FILTER xmm0, xmm1, xmm3, xmm8, xmm4, xmm2 ; const char *thresh ;) -global sym(vp8_loop_filter_bv_y_sse2) PRIVATE +globalsym(vp8_loop_filter_bv_y_sse2) sym(vp8_loop_filter_bv_y_sse2): %if LIBVPX_YASM_WIN64 diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_sse2.asm index 2ae028fea..ce5c31313 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/loopfilter_sse2.asm @@ -288,7 +288,7 @@ SECTION .text ; const char *limit, ; const char *thresh, ;) -global sym(vp8_loop_filter_horizontal_edge_sse2) PRIVATE +globalsym(vp8_loop_filter_horizontal_edge_sse2) sym(vp8_loop_filter_horizontal_edge_sse2): push rbp mov rbp, rsp @@ -336,7 +336,7 @@ sym(vp8_loop_filter_horizontal_edge_sse2): ; const char *thresh, ; int count ;) -global sym(vp8_loop_filter_horizontal_edge_uv_sse2) PRIVATE +globalsym(vp8_loop_filter_horizontal_edge_uv_sse2) sym(vp8_loop_filter_horizontal_edge_uv_sse2): push rbp mov rbp, rsp @@ -563,7 +563,7 @@ sym(vp8_loop_filter_horizontal_edge_uv_sse2): ; const char *limit, ; const char *thresh, ;) -global sym(vp8_mbloop_filter_horizontal_edge_sse2) PRIVATE +globalsym(vp8_mbloop_filter_horizontal_edge_sse2) sym(vp8_mbloop_filter_horizontal_edge_sse2): push rbp mov rbp, rsp @@ -609,7 +609,7 @@ sym(vp8_mbloop_filter_horizontal_edge_sse2): ; const char *thresh, ; unsigned char *v ;) -global sym(vp8_mbloop_filter_horizontal_edge_uv_sse2) PRIVATE +globalsym(vp8_mbloop_filter_horizontal_edge_uv_sse2) sym(vp8_mbloop_filter_horizontal_edge_uv_sse2): push rbp mov rbp, rsp @@ -930,7 +930,7 @@ sym(vp8_mbloop_filter_horizontal_edge_uv_sse2): ; const char *limit, ; const char *thresh, ;) -global sym(vp8_loop_filter_vertical_edge_sse2) PRIVATE +globalsym(vp8_loop_filter_vertical_edge_sse2) sym(vp8_loop_filter_vertical_edge_sse2): push rbp mov rbp, rsp @@ -995,7 +995,7 @@ sym(vp8_loop_filter_vertical_edge_sse2): ; const char *thresh, ; unsigned char *v ;) -global sym(vp8_loop_filter_vertical_edge_uv_sse2) PRIVATE +globalsym(vp8_loop_filter_vertical_edge_uv_sse2) sym(vp8_loop_filter_vertical_edge_uv_sse2): push rbp mov rbp, rsp @@ -1144,7 +1144,7 @@ sym(vp8_loop_filter_vertical_edge_uv_sse2): ; const char *limit, ; const char *thresh, ;) -global sym(vp8_mbloop_filter_vertical_edge_sse2) PRIVATE +globalsym(vp8_mbloop_filter_vertical_edge_sse2) sym(vp8_mbloop_filter_vertical_edge_sse2): push rbp mov rbp, rsp @@ -1211,7 +1211,7 @@ sym(vp8_mbloop_filter_vertical_edge_sse2): ; const char *thresh, ; unsigned char *v ;) -global sym(vp8_mbloop_filter_vertical_edge_uv_sse2) PRIVATE +globalsym(vp8_mbloop_filter_vertical_edge_uv_sse2) sym(vp8_mbloop_filter_vertical_edge_uv_sse2): push rbp mov rbp, rsp @@ -1271,7 +1271,7 @@ sym(vp8_mbloop_filter_vertical_edge_uv_sse2): ; int src_pixel_step, ; const char *blimit, ;) -global sym(vp8_loop_filter_simple_horizontal_edge_sse2) PRIVATE +globalsym(vp8_loop_filter_simple_horizontal_edge_sse2) sym(vp8_loop_filter_simple_horizontal_edge_sse2): push rbp mov rbp, rsp @@ -1376,7 +1376,7 @@ sym(vp8_loop_filter_simple_horizontal_edge_sse2): ; int src_pixel_step, ; const char *blimit, ;) -global sym(vp8_loop_filter_simple_vertical_edge_sse2) PRIVATE +globalsym(vp8_loop_filter_simple_vertical_edge_sse2) sym(vp8_loop_filter_simple_vertical_edge_sse2): push rbp ; save old base pointer value. mov rbp, rsp ; set new base pointer value. diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/mfqe_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/mfqe_sse2.asm index 3fde973ad..3ec2a99ec 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/mfqe_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/mfqe_sse2.asm @@ -21,7 +21,7 @@ SECTION .text ; int dst_stride, ; int src_weight ;) -global sym(vp8_filter_by_weight16x16_sse2) PRIVATE +globalsym(vp8_filter_by_weight16x16_sse2) sym(vp8_filter_by_weight16x16_sse2): push rbp mov rbp, rsp @@ -99,7 +99,7 @@ sym(vp8_filter_by_weight16x16_sse2): ; int dst_stride, ; int src_weight ;) -global sym(vp8_filter_by_weight8x8_sse2) PRIVATE +globalsym(vp8_filter_by_weight8x8_sse2) sym(vp8_filter_by_weight8x8_sse2): push rbp mov rbp, rsp @@ -167,7 +167,7 @@ sym(vp8_filter_by_weight8x8_sse2): ; unsigned int *variance, 4 ; unsigned int *sad, 5 ;) -global sym(vp8_variance_and_sad_16x16_sse2) PRIVATE +globalsym(vp8_variance_and_sad_16x16_sse2) sym(vp8_variance_and_sad_16x16_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/recon_mmx.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/recon_mmx.asm index e6a48f6b0..01cf06683 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/recon_mmx.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/recon_mmx.asm @@ -19,7 +19,7 @@ SECTION .text ; unsigned char *dst, ; int dst_stride ; ) -global sym(vp8_copy_mem8x8_mmx) PRIVATE +globalsym(vp8_copy_mem8x8_mmx) sym(vp8_copy_mem8x8_mmx): push rbp mov rbp, rsp @@ -82,7 +82,7 @@ sym(vp8_copy_mem8x8_mmx): ; unsigned char *dst, ; int dst_stride ; ) -global sym(vp8_copy_mem8x4_mmx) PRIVATE +globalsym(vp8_copy_mem8x4_mmx) sym(vp8_copy_mem8x4_mmx): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/recon_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/recon_sse2.asm index 57f8899c7..17baf094e 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/recon_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/recon_sse2.asm @@ -19,7 +19,7 @@ SECTION .text ; unsigned char *dst, ; int dst_stride ; ) -global sym(vp8_copy_mem16x16_sse2) PRIVATE +globalsym(vp8_copy_mem16x16_sse2) sym(vp8_copy_mem16x16_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_mmx.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_mmx.asm index 67bcd0cbd..8f0f6fcc8 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_mmx.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_mmx.asm @@ -27,7 +27,7 @@ SECTION .text ; unsigned int output_width, ; short * vp8_filter ;) -global sym(vp8_filter_block1d_h6_mmx) PRIVATE +globalsym(vp8_filter_block1d_h6_mmx) sym(vp8_filter_block1d_h6_mmx): push rbp mov rbp, rsp @@ -124,7 +124,7 @@ sym(vp8_filter_block1d_h6_mmx): ; unsigned int output_width, ; short * vp8_filter ;) -global sym(vp8_filter_block1dc_v6_mmx) PRIVATE +globalsym(vp8_filter_block1dc_v6_mmx) sym(vp8_filter_block1dc_v6_mmx): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_sse2.asm index 51c015e3d..94e14aed6 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_sse2.asm @@ -33,7 +33,7 @@ SECTION .text ; unsigned int output_width, ; short *vp8_filter ;) -global sym(vp8_filter_block1d8_h6_sse2) PRIVATE +globalsym(vp8_filter_block1d8_h6_sse2) sym(vp8_filter_block1d8_h6_sse2): push rbp mov rbp, rsp @@ -153,7 +153,7 @@ sym(vp8_filter_block1d8_h6_sse2): ; even number. This function handles 8 pixels in horizontal direction, calculating ONE ; rows each iteration to take advantage of the 128 bits operations. ;*************************************************************************************/ -global sym(vp8_filter_block1d16_h6_sse2) PRIVATE +globalsym(vp8_filter_block1d16_h6_sse2) sym(vp8_filter_block1d16_h6_sse2): push rbp mov rbp, rsp @@ -333,7 +333,7 @@ sym(vp8_filter_block1d16_h6_sse2): ; Notes: filter_block1d8_v6 applies a 6 tap filter vertically to the input pixels. The ; input pixel array has output_height rows. ;*************************************************************************************/ -global sym(vp8_filter_block1d8_v6_sse2) PRIVATE +globalsym(vp8_filter_block1d8_v6_sse2) sym(vp8_filter_block1d8_v6_sse2): push rbp mov rbp, rsp @@ -428,7 +428,7 @@ sym(vp8_filter_block1d8_v6_sse2): ; Notes: filter_block1d16_v6 applies a 6 tap filter vertically to the input pixels. The ; input pixel array has output_height rows. ;*************************************************************************************/ -global sym(vp8_filter_block1d16_v6_sse2) PRIVATE +globalsym(vp8_filter_block1d16_v6_sse2) sym(vp8_filter_block1d16_v6_sse2): push rbp mov rbp, rsp @@ -538,7 +538,7 @@ sym(vp8_filter_block1d16_v6_sse2): ; const short *vp8_filter ;) ; First-pass filter only when yoffset==0 -global sym(vp8_filter_block1d8_h6_only_sse2) PRIVATE +globalsym(vp8_filter_block1d8_h6_only_sse2) sym(vp8_filter_block1d8_h6_only_sse2): push rbp mov rbp, rsp @@ -651,7 +651,7 @@ sym(vp8_filter_block1d8_h6_only_sse2): ; const short *vp8_filter ;) ; First-pass filter only when yoffset==0 -global sym(vp8_filter_block1d16_h6_only_sse2) PRIVATE +globalsym(vp8_filter_block1d16_h6_only_sse2) sym(vp8_filter_block1d16_h6_only_sse2): push rbp mov rbp, rsp @@ -816,7 +816,7 @@ sym(vp8_filter_block1d16_h6_only_sse2): ; const short *vp8_filter ;) ; Second-pass filter only when xoffset==0 -global sym(vp8_filter_block1d8_v6_only_sse2) PRIVATE +globalsym(vp8_filter_block1d8_v6_only_sse2) sym(vp8_filter_block1d8_v6_only_sse2): push rbp mov rbp, rsp @@ -908,7 +908,7 @@ sym(vp8_filter_block1d8_v6_only_sse2): ; unsigned int output_height, ; unsigned int output_width ;) -global sym(vp8_unpack_block1d16_h6_sse2) PRIVATE +globalsym(vp8_unpack_block1d16_h6_sse2) sym(vp8_unpack_block1d16_h6_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_ssse3.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_ssse3.asm index 8d55c9320..17247227d 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_ssse3.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/common/x86/subpixel_ssse3.asm @@ -35,7 +35,7 @@ SECTION .text ; unsigned int output_height, ; unsigned int vp8_filter_index ;) -global sym(vp8_filter_block1d8_h6_ssse3) PRIVATE +globalsym(vp8_filter_block1d8_h6_ssse3) sym(vp8_filter_block1d8_h6_ssse3): push rbp mov rbp, rsp @@ -178,7 +178,7 @@ vp8_filter_block1d8_h4_ssse3: ; unsigned int output_height, ; unsigned int vp8_filter_index ;) -global sym(vp8_filter_block1d16_h6_ssse3) PRIVATE +globalsym(vp8_filter_block1d16_h6_ssse3) sym(vp8_filter_block1d16_h6_ssse3): push rbp mov rbp, rsp @@ -285,7 +285,7 @@ sym(vp8_filter_block1d16_h6_ssse3): ; unsigned int output_height, ; unsigned int vp8_filter_index ;) -global sym(vp8_filter_block1d4_h6_ssse3) PRIVATE +globalsym(vp8_filter_block1d4_h6_ssse3) sym(vp8_filter_block1d4_h6_ssse3): push rbp mov rbp, rsp @@ -415,7 +415,7 @@ sym(vp8_filter_block1d4_h6_ssse3): ; unsigned int output_height, ; unsigned int vp8_filter_index ;) -global sym(vp8_filter_block1d16_v6_ssse3) PRIVATE +globalsym(vp8_filter_block1d16_v6_ssse3) sym(vp8_filter_block1d16_v6_ssse3): push rbp mov rbp, rsp @@ -603,7 +603,7 @@ sym(vp8_filter_block1d16_v6_ssse3): ; unsigned int output_height, ; unsigned int vp8_filter_index ;) -global sym(vp8_filter_block1d8_v6_ssse3) PRIVATE +globalsym(vp8_filter_block1d8_v6_ssse3) sym(vp8_filter_block1d8_v6_ssse3): push rbp mov rbp, rsp @@ -743,7 +743,7 @@ sym(vp8_filter_block1d8_v6_ssse3): ; unsigned int output_height, ; unsigned int vp8_filter_index ;) -global sym(vp8_filter_block1d4_v6_ssse3) PRIVATE +globalsym(vp8_filter_block1d4_v6_ssse3) sym(vp8_filter_block1d4_v6_ssse3): push rbp mov rbp, rsp @@ -882,7 +882,7 @@ sym(vp8_filter_block1d4_v6_ssse3): ; unsigned char *dst_ptr, ; int dst_pitch ;) -global sym(vp8_bilinear_predict16x16_ssse3) PRIVATE +globalsym(vp8_bilinear_predict16x16_ssse3) sym(vp8_bilinear_predict16x16_ssse3): push rbp mov rbp, rsp @@ -1145,7 +1145,7 @@ sym(vp8_bilinear_predict16x16_ssse3): ; unsigned char *dst_ptr, ; int dst_pitch ;) -global sym(vp8_bilinear_predict8x8_ssse3) PRIVATE +globalsym(vp8_bilinear_predict8x8_ssse3) sym(vp8_bilinear_predict8x8_ssse3): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/bitstream.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/bitstream.c index 3daa4e2c2..80cbb882f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/bitstream.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/bitstream.c @@ -222,7 +222,7 @@ void vp8_pack_tokens(vp8_writer *w, const TOKENEXTRA *p, int xcount) { validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error); - w->buffer[w->pos++] = (lowvalue >> (24 - offset)); + w->buffer[w->pos++] = (lowvalue >> (24 - offset)) & 0xff; lowvalue <<= offset; shift = count; lowvalue &= 0xffffff; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/mips/mmi/dct_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/mips/mmi/dct_mmi.c index 1f60a692d..0fd25fcda 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/mips/mmi/dct_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/mips/mmi/dct_mmi.c @@ -24,19 +24,19 @@ "punpcklhw %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ "punpcklhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "or %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ + "por %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ "punpckhhw %[ftmp6], %[ftmp1], %[ftmp0] \n\t" \ "punpckhhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "or %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ + "por %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ "punpcklhw %[ftmp7], %[ftmp3], %[ftmp0] \n\t" \ "punpcklhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "or %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ + "por %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ "punpckhhw %[ftmp8], %[ftmp3], %[ftmp0] \n\t" \ "punpckhhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "or %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ + "por %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ "punpcklwd %[ftmp1], %[ftmp5], %[ftmp7] \n\t" \ "punpckhwd %[ftmp2], %[ftmp5], %[ftmp7] \n\t" \ "punpcklwd %[ftmp3], %[ftmp6], %[ftmp8] \n\t" \ @@ -46,6 +46,7 @@ void vp8_short_fdct4x4_mmi(int16_t *input, int16_t *output, int pitch) { uint64_t tmp[1]; int16_t *ip = input; + double ff_ph_op1, ff_ph_op3; #if _MIPS_SIM == _ABIO32 register double ftmp0 asm("$f0"); @@ -83,14 +84,17 @@ void vp8_short_fdct4x4_mmi(int16_t *input, int16_t *output, int pitch) { DECLARE_ALIGNED(8, const uint64_t, ff_pw_51000) = { 0x0000c7380000c738ULL }; DECLARE_ALIGNED(8, const uint64_t, ff_pw_14500) = { 0x000038a4000038a4ULL }; DECLARE_ALIGNED(8, const uint64_t, ff_pw_7500) = { 0x00001d4c00001d4cULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_op1) = { 0x14e808a914e808a9ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_op3) = { 0xeb1808a9eb1808a9ULL }; DECLARE_ALIGNED(8, const uint64_t, ff_pw_5352) = { 0x000014e8000014e8ULL }; DECLARE_ALIGNED(8, const uint64_t, ff_pw_2217) = { 0x000008a9000008a9ULL }; DECLARE_ALIGNED(8, const uint64_t, ff_ph_8) = { 0x0008000800080008ULL }; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "dli %[tmp0], 0x14e808a914e808a9 \n\t" + "dmtc1 %[tmp0], %[ff_ph_op1] \n\t" + "dli %[tmp0], 0xeb1808a9eb1808a9 \n\t" + "dmtc1 %[tmp0], %[ff_ph_op3] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" MMI_ADDU(%[ip], %[ip], %[pitch]) @@ -129,7 +133,7 @@ void vp8_short_fdct4x4_mmi(int16_t *input, int16_t *output, int pitch) { // op[1] = (c1 * 2217 + d1 * 5352 + 14500) >> 12 MMI_LI(%[tmp0], 0x0c) - "mtc1 %[tmp0], %[ftmp11] \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" "ldc1 %[ftmp12], %[ff_pw_14500] \n\t" "punpcklhw %[ftmp9], %[ftmp7], %[ftmp8] \n\t" "pmaddhw %[ftmp5], %[ftmp9], %[ff_ph_op1] \n\t" @@ -169,7 +173,7 @@ void vp8_short_fdct4x4_mmi(int16_t *input, int16_t *output, int pitch) { "paddh %[ftmp1], %[ftmp1], %[ftmp9] \n\t" "paddh %[ftmp2], %[ftmp2], %[ftmp9] \n\t" MMI_LI(%[tmp0], 0x04) - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "psrah %[ftmp1], %[ftmp1], %[ftmp9] \n\t" "psrah %[ftmp2], %[ftmp2], %[ftmp9] \n\t" @@ -211,15 +215,16 @@ void vp8_short_fdct4x4_mmi(int16_t *input, int16_t *output, int pitch) { [ftmp3] "=&f"(ftmp3), [ftmp4] "=&f"(ftmp4), [ftmp5] "=&f"(ftmp5), [ftmp6] "=&f"(ftmp6), [ftmp7] "=&f"(ftmp7), [ftmp8] "=&f"(ftmp8), [ftmp9] "=&f"(ftmp9), [ftmp10] "=&f"(ftmp10), [ftmp11] "=&f"(ftmp11), - [ftmp12] "=&f"(ftmp12), [tmp0] "=&r"(tmp[0]), [ip]"+&r"(ip) + [ftmp12] "=&f"(ftmp12), [tmp0] "=&r"(tmp[0]), [ip]"+&r"(ip), + [ff_ph_op1] "=&f"(ff_ph_op1), [ff_ph_op3] "=&f"(ff_ph_op3) : [ff_ph_01] "m"(ff_ph_01), [ff_ph_07] "m"(ff_ph_07), - [ff_ph_op1] "f"(ff_ph_op1), [ff_ph_op3] "f"(ff_ph_op3), [ff_pw_14500] "m"(ff_pw_14500), [ff_pw_7500] "m"(ff_pw_7500), [ff_pw_12000] "m"(ff_pw_12000), [ff_pw_51000] "m"(ff_pw_51000), [ff_pw_5352]"m"(ff_pw_5352), [ff_pw_2217]"m"(ff_pw_2217), [ff_ph_8]"m"(ff_ph_8), [pitch]"r"(pitch), [output] "r"(output) : "memory" ); + /* clang-format on */ } void vp8_short_fdct8x4_mmi(int16_t *input, int16_t *output, int pitch) { @@ -228,17 +233,22 @@ void vp8_short_fdct8x4_mmi(int16_t *input, int16_t *output, int pitch) { } void vp8_short_walsh4x4_mmi(int16_t *input, int16_t *output, int pitch) { - double ftmp[13]; - uint32_t tmp[1]; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_01) = { 0x0001000100010001ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_01) = { 0x0000000100000001ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_03) = { 0x0000000300000003ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_mask) = { 0x0001000000010000ULL }; + double ftmp[13], ff_ph_01, ff_pw_01, ff_pw_03, ff_pw_mask; + uint64_t tmp[1]; + /* clang-format off */ __asm__ volatile ( + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ff_ph_01] \n\t" + "dli %[tmp0], 0x0000000100000001 \n\t" + "dmtc1 %[tmp0], %[ff_pw_01] \n\t" + "dli %[tmp0], 0x0000000300000003 \n\t" + "dmtc1 %[tmp0], %[ff_pw_03] \n\t" + "dli %[tmp0], 0x0001000000010000 \n\t" + "dmtc1 %[tmp0], %[ff_pw_mask] \n\t" MMI_LI(%[tmp0], 0x02) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" @@ -337,52 +347,52 @@ void vp8_short_walsh4x4_mmi(int16_t *input, int16_t *output, int pitch) { "psubw %[ftmp4], %[ftmp9], %[ftmp10] \n\t" MMI_LI(%[tmp0], 0x03) - "mtc1 %[tmp0], %[ftmp11] \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp1] \n\t" - "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" + "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" "paddw %[ftmp1], %[ftmp1], %[ftmp9] \n\t" "paddw %[ftmp1], %[ftmp1], %[ff_pw_03] \n\t" "psraw %[ftmp1], %[ftmp1], %[ftmp11] \n\t" "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp2] \n\t" - "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" + "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" "paddw %[ftmp2], %[ftmp2], %[ftmp9] \n\t" "paddw %[ftmp2], %[ftmp2], %[ff_pw_03] \n\t" "psraw %[ftmp2], %[ftmp2], %[ftmp11] \n\t" "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp3] \n\t" - "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" + "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" "paddw %[ftmp3], %[ftmp3], %[ftmp9] \n\t" "paddw %[ftmp3], %[ftmp3], %[ff_pw_03] \n\t" "psraw %[ftmp3], %[ftmp3], %[ftmp11] \n\t" "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp4] \n\t" - "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" + "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" "paddw %[ftmp4], %[ftmp4], %[ftmp9] \n\t" "paddw %[ftmp4], %[ftmp4], %[ff_pw_03] \n\t" "psraw %[ftmp4], %[ftmp4], %[ftmp11] \n\t" "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp5] \n\t" - "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" + "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" "paddw %[ftmp5], %[ftmp5], %[ftmp9] \n\t" "paddw %[ftmp5], %[ftmp5], %[ff_pw_03] \n\t" "psraw %[ftmp5], %[ftmp5], %[ftmp11] \n\t" "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp6] \n\t" - "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" + "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" "paddw %[ftmp6], %[ftmp6], %[ftmp9] \n\t" "paddw %[ftmp6], %[ftmp6], %[ff_pw_03] \n\t" "psraw %[ftmp6], %[ftmp6], %[ftmp11] \n\t" "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp7] \n\t" - "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" + "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" "paddw %[ftmp7], %[ftmp7], %[ftmp9] \n\t" "paddw %[ftmp7], %[ftmp7], %[ff_pw_03] \n\t" "psraw %[ftmp7], %[ftmp7], %[ftmp11] \n\t" "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp8] \n\t" - "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" + "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" "paddw %[ftmp8], %[ftmp8], %[ftmp9] \n\t" "paddw %[ftmp8], %[ftmp8], %[ff_pw_03] \n\t" "psraw %[ftmp8], %[ftmp8], %[ftmp11] \n\t" @@ -393,7 +403,7 @@ void vp8_short_walsh4x4_mmi(int16_t *input, int16_t *output, int pitch) { "packsswh %[ftmp4], %[ftmp4], %[ftmp8] \n\t" MMI_LI(%[tmp0], 0x72) - "mtc1 %[tmp0], %[ftmp11] \n\t" + "dmtc1 %[tmp0], %[ftmp11] \n\t" "pshufh %[ftmp1], %[ftmp1], %[ftmp11] \n\t" "pshufh %[ftmp2], %[ftmp2], %[ftmp11] \n\t" "pshufh %[ftmp3], %[ftmp3], %[ftmp11] \n\t" @@ -413,13 +423,12 @@ void vp8_short_walsh4x4_mmi(int16_t *input, int16_t *output, int pitch) { [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [ftmp12]"=&f"(ftmp[12]), - [tmp0]"=&r"(tmp[0]), - [ip]"+&r"(input) - : [op]"r"(output), - [ff_pw_01]"f"(ff_pw_01), [pitch]"r"((mips_reg)pitch), - [ff_pw_03]"f"(ff_pw_03), [ff_pw_mask]"f"(ff_pw_mask), - [ff_ph_01]"f"(ff_ph_01) + [ftmp12]"=&f"(ftmp[12]), [ff_pw_mask]"=&f"(ff_pw_mask), + [tmp0]"=&r"(tmp[0]), [ff_pw_01]"=&f"(ff_pw_01), + [ip]"+&r"(input), [ff_pw_03]"=&f"(ff_pw_03), + [ff_ph_01]"=&f"(ff_ph_01) + : [op]"r"(output), [pitch]"r"((mips_reg)pitch) : "memory" ); + /* clang-format on */ } diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/mips/mmi/vp8_quantize_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/mips/mmi/vp8_quantize_mmi.c index 3ccb196ff..1986444aa 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/mips/mmi/vp8_quantize_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/mips/mmi/vp8_quantize_mmi.c @@ -42,24 +42,25 @@ void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) { double ftmp[13]; uint64_t tmp[1]; - DECLARE_ALIGNED(8, const uint64_t, ones) = { 0xffffffffffffffffULL }; - int eob = 0; + int64_t eob = 0; + double ones; __asm__ volatile( // loop 0 ~ 7 - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pcmpeqh %[ones], %[ones], %[ones] \n\t" "gsldlc1 %[ftmp1], 0x07(%[coeff_ptr]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[coeff_ptr]) \n\t" - "li %[tmp0], 0x0f \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x0f \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "gsldlc1 %[ftmp2], 0x0f(%[coeff_ptr]) \n\t" "gsldrc1 %[ftmp2], 0x08(%[coeff_ptr]) \n\t" "psrah %[ftmp3], %[ftmp1], %[ftmp9] \n\t" - "xor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" + "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" "psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" "psrah %[ftmp4], %[ftmp2], %[ftmp9] \n\t" - "xor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" + "pxor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" "psubh %[ftmp2], %[ftmp2], %[ftmp4] \n\t" "gsldlc1 %[ftmp5], 0x07(%[round_ptr]) \n\t" @@ -75,8 +76,8 @@ void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) { "pmulhuh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" "pmulhuh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" - "xor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" - "xor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" + "pxor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" + "pxor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" "psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" "psubh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" "gssdlc1 %[ftmp7], 0x07(%[qcoeff_ptr]) \n\t" @@ -90,10 +91,10 @@ void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) { "gsldrc1 %[ftmp2], 0x08(%[inv_zig_zag]) \n\t" "pcmpeqh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" "pcmpeqh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "xor %[ftmp5], %[ftmp5], %[ones] \n\t" - "xor %[ftmp6], %[ftmp6], %[ones] \n\t" - "and %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "and %[ftmp6], %[ftmp6], %[ftmp2] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ones] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ones] \n\t" + "pand %[ftmp5], %[ftmp5], %[ftmp1] \n\t" + "pand %[ftmp6], %[ftmp6], %[ftmp2] \n\t" "pmaxsh %[ftmp10], %[ftmp5], %[ftmp6] \n\t" "gsldlc1 %[ftmp5], 0x07(%[dequant_ptr]) \n\t" @@ -114,10 +115,10 @@ void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) { "gsldrc1 %[ftmp2], 0x18(%[coeff_ptr]) \n\t" "psrah %[ftmp3], %[ftmp1], %[ftmp9] \n\t" - "xor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" + "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" "psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" "psrah %[ftmp4], %[ftmp2], %[ftmp9] \n\t" - "xor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" + "pxor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" "psubh %[ftmp2], %[ftmp2], %[ftmp4] \n\t" "gsldlc1 %[ftmp5], 0x17(%[round_ptr]) \n\t" @@ -133,8 +134,8 @@ void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) { "pmulhuh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" "pmulhuh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" - "xor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" - "xor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" + "pxor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" + "pxor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" "psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" "psubh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" "gssdlc1 %[ftmp7], 0x17(%[qcoeff_ptr]) \n\t" @@ -148,10 +149,10 @@ void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) { "gsldrc1 %[ftmp2], 0x18(%[inv_zig_zag]) \n\t" "pcmpeqh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" "pcmpeqh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "xor %[ftmp5], %[ftmp5], %[ones] \n\t" - "xor %[ftmp6], %[ftmp6], %[ones] \n\t" - "and %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "and %[ftmp6], %[ftmp6], %[ftmp2] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ones] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ones] \n\t" + "pand %[ftmp5], %[ftmp5], %[ftmp1] \n\t" + "pand %[ftmp6], %[ftmp6], %[ftmp2] \n\t" "pmaxsh %[ftmp11], %[ftmp5], %[ftmp6] \n\t" "gsldlc1 %[ftmp5], 0x17(%[dequant_ptr]) \n\t" @@ -165,34 +166,34 @@ void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) { "gssdlc1 %[ftmp6], 0x1f(%[dqcoeff_ptr]) \n\t" "gssdrc1 %[ftmp6], 0x18(%[dqcoeff_ptr]) \n\t" - "li %[tmp0], 0x10 \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0x10 \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" "psrlw %[ftmp11], %[ftmp10], %[ftmp9] \n\t" "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" - "li %[tmp0], 0xaa \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" + "dli %[tmp0], 0xaa \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" "pshufh %[ftmp11], %[ftmp10], %[ftmp9] \n\t" "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" - "li %[tmp0], 0xffff \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" - "and %[ftmp10], %[ftmp10], %[ftmp9] \n\t" + "dli %[tmp0], 0xffff \n\t" + "dmtc1 %[tmp0], %[ftmp9] \n\t" + "pand %[ftmp10], %[ftmp10], %[ftmp9] \n\t" "gssdlc1 %[ftmp10], 0x07(%[eob]) \n\t" "gssdrc1 %[ftmp10], 0x00(%[eob]) \n\t" : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), [ftmp8] "=&f"(ftmp[8]), [ftmp9] "=&f"(ftmp[9]), [ftmp10] "=&f"(ftmp[10]), - [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]) + [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), + [tmp0] "=&r"(tmp[0]), [ones] "=&f"(ones) : [coeff_ptr] "r"((mips_reg)coeff_ptr), [qcoeff_ptr] "r"((mips_reg)qcoeff_ptr), [dequant_ptr] "r"((mips_reg)dequant_ptr), [round_ptr] "r"((mips_reg)round_ptr), [quant_ptr] "r"((mips_reg)quant_ptr), [dqcoeff_ptr] "r"((mips_reg)dqcoeff_ptr), - [inv_zig_zag] "r"((mips_reg)inv_zig_zag), [eob] "r"((mips_reg)&eob), - [ones] "f"(ones) + [inv_zig_zag] "r"((mips_reg)inv_zig_zag), [eob] "r"((mips_reg)&eob) : "memory"); *d->eob = eob; @@ -217,7 +218,7 @@ void vp8_regular_quantize_b_mmi(BLOCK *b, BLOCKD *d) { // memset(dqcoeff_ptr, 0, 32); /* clang-format off */ __asm__ volatile ( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "gssdlc1 %[ftmp0], 0x07(%[qcoeff_ptr]) \n\t" "gssdrc1 %[ftmp0], 0x00(%[qcoeff_ptr]) \n\t" "gssdlc1 %[ftmp0], 0x0f(%[qcoeff_ptr]) \n\t" diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c index 3f5b9816d..aeed719d1 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c @@ -1430,6 +1430,7 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { VP8_COMMON *cm = &cpi->common; int last_w, last_h; unsigned int prev_number_of_layers; + unsigned int raw_target_rate; if (!cpi) return; @@ -1570,6 +1571,10 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { cpi->oxcf.maximum_buffer_size_in_ms = 240000; } + raw_target_rate = (unsigned int)((int64_t)cpi->oxcf.Width * cpi->oxcf.Height * + 8 * 3 * cpi->framerate / 1000); + if (cpi->oxcf.target_bandwidth > raw_target_rate) + cpi->oxcf.target_bandwidth = raw_target_rate; /* Convert target bandwidth from Kbit/s to Bit/s */ cpi->oxcf.target_bandwidth *= 1000; @@ -3615,7 +3620,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size, if (cpi->this_key_frame_forced) { if (cpi->active_best_quality > cpi->avg_frame_qindex * 7 / 8) { cpi->active_best_quality = cpi->avg_frame_qindex * 7 / 8; - } else if (cpi->active_best_qualityavg_frame_qindex>> 2) { + } else if (cpi->active_best_quality < (cpi->avg_frame_qindex >> 2)) { cpi->active_best_quality = cpi->avg_frame_qindex >> 2; } } @@ -4533,9 +4538,11 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size, /* Actual bits spent */ cpi->total_actual_bits += cpi->projected_frame_size; +#if 0 && CONFIG_INTERNAL_STATS /* Debug stats */ cpi->total_target_vs_actual += (cpi->this_frame_target - cpi->projected_frame_size); +#endif cpi->buffer_level = cpi->bits_off_target; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h index c02683a58..4e9ed6af1 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/treewriter.h @@ -14,6 +14,8 @@ /* Trees map alphabets into huffman-like codes suitable for an arithmetic bit coder. Timothy S Murphy 11 October 2004 */ +#include + #include "./vpx_config.h" #include "vp8/common/treecoder.h" @@ -48,7 +50,9 @@ static INLINE unsigned int vp8_cost_branch(const unsigned int ct[2], vp8_prob p) { /* Imitate existing calculation */ - return ((ct[0] * vp8_cost_zero(p)) + (ct[1] * vp8_cost_one(p))) >> 8; + return (unsigned int)(((((uint64_t)ct[0]) * vp8_cost_zero(p)) + + (((uint64_t)ct[1]) * vp8_cost_one(p))) >> + 8); } /* Small functions to write explicit values and tokens, as well as diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/block_error_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/block_error_sse2.asm index f6c6aeae7..200b4ccfe 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/block_error_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/block_error_sse2.asm @@ -14,7 +14,7 @@ SECTION .text ;int vp8_block_error_sse2(short *coeff_ptr, short *dcoef_ptr) -global sym(vp8_block_error_sse2) PRIVATE +globalsym(vp8_block_error_sse2) sym(vp8_block_error_sse2): push rbp mov rbp, rsp @@ -62,7 +62,7 @@ sym(vp8_block_error_sse2): ret ;int vp8_mbblock_error_sse2_impl(short *coeff_ptr, short *dcoef_ptr, int dc); -global sym(vp8_mbblock_error_sse2_impl) PRIVATE +globalsym(vp8_mbblock_error_sse2_impl) sym(vp8_mbblock_error_sse2_impl): push rbp mov rbp, rsp @@ -132,7 +132,7 @@ sym(vp8_mbblock_error_sse2_impl): ;int vp8_mbuverror_sse2_impl(short *s_ptr, short *d_ptr); -global sym(vp8_mbuverror_sse2_impl) PRIVATE +globalsym(vp8_mbuverror_sse2_impl) sym(vp8_mbuverror_sse2_impl): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse2.asm index 480faa255..fe78da398 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse2.asm @@ -19,7 +19,7 @@ SECTION .text ; unsigned char *dst_ptr, ; int dst_stride, ; int height); -global sym(vp8_copy32xn_sse2) PRIVATE +globalsym(vp8_copy32xn_sse2) sym(vp8_copy32xn_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse3.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse3.asm index 31ea898a3..c40b2d8bf 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse3.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/copy_sse3.asm @@ -91,7 +91,7 @@ SECTION .text ; unsigned char *dst_ptr, ; int dst_stride, ; int height); -global sym(vp8_copy32xn_sse3) PRIVATE +globalsym(vp8_copy32xn_sse3) sym(vp8_copy32xn_sse3): STACK_FRAME_CREATE_X3 diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/dct_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/dct_sse2.asm index 4d92f0341..3c28cb902 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/dct_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/dct_sse2.asm @@ -63,7 +63,7 @@ SECTION .text ;void vp8_short_fdct4x4_sse2(short *input, short *output, int pitch) -global sym(vp8_short_fdct4x4_sse2) PRIVATE +globalsym(vp8_short_fdct4x4_sse2) sym(vp8_short_fdct4x4_sse2): STACK_FRAME_CREATE @@ -168,7 +168,7 @@ sym(vp8_short_fdct4x4_sse2): STACK_FRAME_DESTROY ;void vp8_short_fdct8x4_sse2(short *input, short *output, int pitch) -global sym(vp8_short_fdct8x4_sse2) PRIVATE +globalsym(vp8_short_fdct8x4_sse2) sym(vp8_short_fdct8x4_sse2): STACK_FRAME_CREATE diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/fwalsh_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/fwalsh_sse2.asm index b5d5de4a5..938fc173f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/fwalsh_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/fwalsh_sse2.asm @@ -14,7 +14,7 @@ SECTION .text ;void vp8_short_walsh4x4_sse2(short *input, short *output, int pitch) -global sym(vp8_short_walsh4x4_sse2) PRIVATE +globalsym(vp8_short_walsh4x4_sse2) sym(vp8_short_walsh4x4_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/temporal_filter_apply_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/temporal_filter_apply_sse2.asm index d2b4711b8..67102064a 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/temporal_filter_apply_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/encoder/x86/temporal_filter_apply_sse2.asm @@ -22,7 +22,7 @@ SECTION .text ; int filter_weight, | 5 ; unsigned int *accumulator, | 6 ; unsigned short *count) | 7 -global sym(vp8_temporal_filter_apply_sse2) PRIVATE +globalsym(vp8_temporal_filter_apply_sse2) sym(vp8_temporal_filter_apply_sse2): push rbp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c index 8f7617abf..1160f51d6 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/vp8_cx_iface.c @@ -264,9 +264,12 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, const vpx_image_t *img) { switch (img->fmt) { case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_I420: break; + case VPX_IMG_FMT_I420: + case VPX_IMG_FMT_NV12: break; default: - ERROR("Invalid image format. Only YV12 and I420 images are supported"); + ERROR( + "Invalid image format. Only YV12, I420 and NV12 images are " + "supported"); } if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h)) diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/vp8_dx_iface.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/vp8_dx_iface.c index 43156a078..ba0714abe 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/vp8_dx_iface.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp8/vp8_dx_iface.c @@ -687,7 +687,7 @@ static vpx_codec_err_t vp8_set_decryptor(vpx_codec_alg_priv_t *ctx, return VPX_CODEC_OK; } -vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = { +static vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = { { VP8_SET_REFERENCE, vp8_set_reference }, { VP8_COPY_REFERENCE, vp8_get_reference }, { VP8_SET_POSTPROC, vp8_set_postproc }, diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/common/vp9_onyxc_int.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/common/vp9_onyxc_int.h index 6f9c6985f..1cfc12f6f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/common/vp9_onyxc_int.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/common/vp9_onyxc_int.h @@ -75,12 +75,10 @@ typedef struct { // TODO(angiebird): Set frame_index/frame_coding_index on the decoder side // properly. - int frame_index; // Display order in the video, it's equivalent to the - // show_idx defined in EncodeFrameInfo. -#if CONFIG_RATE_CTRL + int frame_index; // Display order in the video, it's equivalent to the + // show_idx defined in EncodeFrameInfo. int frame_coding_index; // The coding order (starting from zero) of this // frame. -#endif // CONFIG_RATE_CTRL vpx_codec_frame_buffer_t raw_frame_buffer; YV12_BUFFER_CONFIG buf; } RefCntBuffer; @@ -240,13 +238,11 @@ typedef struct VP9Common { // TODO(angiebird): current_video_frame/current_frame_coding_index into a // structure unsigned int current_video_frame; -#if CONFIG_RATE_CTRL // Each show or no show frame is assigned with a coding index based on its // coding order (starting from zero). // Current frame's coding index. int current_frame_coding_index; -#endif BITSTREAM_PROFILE profile; // VPX_BITS_8 in profile 0 or 1, VPX_BITS_10 or VPX_BITS_12 in profile 2 or 3. @@ -276,9 +272,7 @@ typedef struct VP9Common { static INLINE void init_frame_indexes(VP9_COMMON *cm) { cm->current_video_frame = 0; -#if CONFIG_RATE_CTRL cm->current_frame_coding_index = 0; -#endif // CONFIG_RATE_CTRL } static INLINE void update_frame_indexes(VP9_COMMON *cm, int show_frame) { @@ -287,9 +281,7 @@ static INLINE void update_frame_indexes(VP9_COMMON *cm, int show_frame) { // update not a real frame ++cm->current_video_frame; } -#if CONFIG_RATE_CTRL ++cm->current_frame_coding_index; -#endif // CONFIG_RATE_CTRL } typedef struct { diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm index ca0897ab9..ae7c94ea3 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm @@ -22,7 +22,7 @@ SECTION .text ; int dst_stride, ; int src_weight ;) -global sym(vp9_filter_by_weight16x16_sse2) PRIVATE +globalsym(vp9_filter_by_weight16x16_sse2) sym(vp9_filter_by_weight16x16_sse2): push rbp mov rbp, rsp @@ -100,7 +100,7 @@ sym(vp9_filter_by_weight16x16_sse2): ; int dst_stride, ; int src_weight ;) -global sym(vp9_filter_by_weight8x8_sse2) PRIVATE +globalsym(vp9_filter_by_weight8x8_sse2) sym(vp9_filter_by_weight8x8_sse2): push rbp mov rbp, rsp @@ -168,7 +168,7 @@ sym(vp9_filter_by_weight8x8_sse2): ; unsigned int *variance, 4 ; unsigned int *sad, 5 ;) -global sym(vp9_variance_and_sad_16x16_sse2) PRIVATE +globalsym(vp9_variance_and_sad_16x16_sse2) sym(vp9_variance_and_sad_16x16_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c index bcade52c4..7db8ed72d 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/decoder/vp9_decoder.c @@ -153,6 +153,11 @@ static int vp9_dec_alloc_mi(VP9_COMMON *cm, int mi_size) { } static void vp9_dec_free_mi(VP9_COMMON *cm) { +#if CONFIG_VP9_POSTPROC + // MFQE allocates an additional mip and swaps it with cm->mip. + vpx_free(cm->postproc_state.prev_mip); + cm->postproc_state.prev_mip = NULL; +#endif vpx_free(cm->mip); cm->mip = NULL; vpx_free(cm->mi_grid_base); diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c index 13f9a1fbd..dcd647658 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c @@ -3766,9 +3766,6 @@ static int wiener_var_segment(VP9_COMP *cpi, BLOCK_SIZE bsize, int mi_row, static int get_rdmult_delta(VP9_COMP *cpi, BLOCK_SIZE bsize, int mi_row, int mi_col, int orig_rdmult) { const int gf_group_index = cpi->twopass.gf_group.index; - TplDepFrame *tpl_frame = &cpi->tpl_stats[gf_group_index]; - TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr; - int tpl_stride = tpl_frame->stride; int64_t intra_cost = 0; int64_t mc_dep_cost = 0; int mi_wide = num_8x8_blocks_wide_lookup[bsize]; @@ -3779,11 +3776,18 @@ static int get_rdmult_delta(VP9_COMP *cpi, BLOCK_SIZE bsize, int mi_row, int count = 0; double r0, rk, beta; - if (tpl_frame->is_valid == 0) return orig_rdmult; - - if (cpi->twopass.gf_group.layer_depth[gf_group_index] > 1) return orig_rdmult; + TplDepFrame *tpl_frame; + TplDepStats *tpl_stats; + int tpl_stride; if (gf_group_index >= MAX_ARF_GOP_SIZE) return orig_rdmult; + tpl_frame = &cpi->tpl_stats[gf_group_index]; + + if (tpl_frame->is_valid == 0) return orig_rdmult; + tpl_stats = tpl_frame->tpl_stats_ptr; + tpl_stride = tpl_frame->stride; + + if (cpi->twopass.gf_group.layer_depth[gf_group_index] > 1) return orig_rdmult; for (row = mi_row; row < mi_row + mi_high; ++row) { for (col = mi_col; col < mi_col + mi_wide; ++col) { @@ -5086,8 +5090,8 @@ static void nonrd_pick_partition(VP9_COMP *cpi, ThreadData *td, (void)*tp_orig; - // Avoid checking for rectangular partitions for speed >= 6. - if (cpi->oxcf.speed >= 6) do_rect = 0; + // Avoid checking for rectangular partitions for speed >= 5. + if (cpi->oxcf.speed >= 5) do_rect = 0; assert(num_8x8_blocks_wide_lookup[bsize] == num_8x8_blocks_high_lookup[bsize]); diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c index b15d5f59c..8d60a0c00 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c @@ -1024,6 +1024,8 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { #if CONFIG_RATE_CTRL free_partition_info(cpi); free_motion_vector_info(cpi); + free_fp_motion_vector_info(cpi); + free_tpl_stats_info(cpi); #endif vp9_free_ref_frame_buffers(cm->buffer_pool); @@ -1523,8 +1525,29 @@ static void init_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { vp9_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height); } -static void set_rc_buffer_sizes(RATE_CONTROL *rc, - const VP9EncoderConfig *oxcf) { +void vp9_check_reset_rc_flag(VP9_COMP *cpi) { + RATE_CONTROL *rc = &cpi->rc; + + if (cpi->common.current_video_frame > + (unsigned int)cpi->svc.number_spatial_layers) { + if (cpi->use_svc) { + vp9_svc_check_reset_layer_rc_flag(cpi); + } else { + if (rc->avg_frame_bandwidth > (3 * rc->last_avg_frame_bandwidth >> 1) || + rc->avg_frame_bandwidth < (rc->last_avg_frame_bandwidth >> 1)) { + rc->rc_1_frame = 0; + rc->rc_2_frame = 0; + rc->bits_off_target = rc->optimal_buffer_level; + rc->buffer_level = rc->optimal_buffer_level; + } + } + } +} + +void vp9_set_rc_buffer_sizes(VP9_COMP *cpi) { + RATE_CONTROL *rc = &cpi->rc; + const VP9EncoderConfig *oxcf = &cpi->oxcf; + const int64_t bandwidth = oxcf->target_bandwidth; const int64_t starting = oxcf->starting_buffer_level_ms; const int64_t optimal = oxcf->optimal_buffer_level_ms; @@ -1535,6 +1558,11 @@ static void set_rc_buffer_sizes(RATE_CONTROL *rc, (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000; rc->maximum_buffer_size = (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000; + + // Under a configuration change, where maximum_buffer_size may change, + // keep buffer level clipped to the maximum allowed buffer size. + rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size); + rc->buffer_level = VPXMIN(rc->buffer_level, rc->maximum_buffer_size); } #if CONFIG_VP9_HIGHBITDEPTH @@ -1991,12 +2019,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { } cpi->encode_breakout = cpi->oxcf.encode_breakout; - set_rc_buffer_sizes(rc, &cpi->oxcf); - - // Under a configuration change, where maximum_buffer_size may change, - // keep buffer level clipped to the maximum allowed buffer size. - rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size); - rc->buffer_level = VPXMIN(rc->buffer_level, rc->maximum_buffer_size); + vp9_set_rc_buffer_sizes(cpi); // Set up frame rate and related parameters rate control values. vp9_new_framerate(cpi, cpi->framerate); @@ -2057,23 +2080,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { (int)cpi->oxcf.target_bandwidth); } - // Check for resetting the rc flags (rc_1_frame, rc_2_frame) if the - // configuration change has a large change in avg_frame_bandwidth. - // For SVC check for resetting based on spatial layer average bandwidth. - // Also reset buffer level to optimal level. - if (cm->current_video_frame > (unsigned int)cpi->svc.number_spatial_layers) { - if (cpi->use_svc) { - vp9_svc_check_reset_layer_rc_flag(cpi); - } else { - if (rc->avg_frame_bandwidth > (3 * rc->last_avg_frame_bandwidth >> 1) || - rc->avg_frame_bandwidth < (rc->last_avg_frame_bandwidth >> 1)) { - rc->rc_1_frame = 0; - rc->rc_2_frame = 0; - rc->bits_off_target = rc->optimal_buffer_level; - rc->buffer_level = rc->optimal_buffer_level; - } - } - } + vp9_check_reset_rc_flag(cpi); cpi->alt_ref_source = NULL; rc->is_src_frame_alt_ref = 0; @@ -2457,6 +2464,8 @@ VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; + vp9_extrc_init(&cpi->ext_ratectrl); + #if !CONFIG_REALTIME_ONLY if (oxcf->pass == 1) { vp9_init_first_pass(cpi); @@ -2656,6 +2665,8 @@ VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, encode_command_init(&cpi->encode_command); partition_info_init(cpi); motion_vector_info_init(cpi); + fp_motion_vector_info_init(cpi); + tpl_stats_info_init(cpi); #endif return cpi; @@ -2827,6 +2838,8 @@ void vp9_remove_compressor(VP9_COMP *cpi) { } #endif + vp9_extrc_delete(&cpi->ext_ratectrl); + vp9_remove_common(cm); vp9_free_ref_frame_buffers(cm->buffer_pool); #if CONFIG_VP9_POSTPROC @@ -3309,6 +3322,13 @@ static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) { return; } + if (cpi->loopfilter_ctrl == NO_LOOPFILTER || + (!is_reference_frame && cpi->loopfilter_ctrl == LOOPFILTER_REFERENCE)) { + lf->filter_level = 0; + vpx_extend_frame_inner_borders(cm->frame_to_show); + return; + } + if (xd->lossless) { lf->filter_level = 0; lf->last_filt_level = 0; @@ -3742,15 +3762,19 @@ static void set_frame_size(VP9_COMP *cpi) { } #endif // !CONFIG_REALTIME_ONLY - if (oxcf->pass == 0 && oxcf->rc_mode == VPX_CBR && !cpi->use_svc && + if (oxcf->pass == 0 && oxcf->rc_mode == VPX_CBR && oxcf->resize_mode == RESIZE_DYNAMIC && cpi->resize_pending != 0) { - oxcf->scaled_frame_width = - (oxcf->width * cpi->resize_scale_num) / cpi->resize_scale_den; - oxcf->scaled_frame_height = - (oxcf->height * cpi->resize_scale_num) / cpi->resize_scale_den; - // There has been a change in frame size. - vp9_set_size_literal(cpi, oxcf->scaled_frame_width, - oxcf->scaled_frame_height); + // For SVC scaled width/height will have been set (svc->resize_set=1) + // in get_svc_params based on the layer width/height. + if (!cpi->use_svc || !cpi->svc.resize_set) { + oxcf->scaled_frame_width = + (oxcf->width * cpi->resize_scale_num) / cpi->resize_scale_den; + oxcf->scaled_frame_height = + (oxcf->height * cpi->resize_scale_num) / cpi->resize_scale_den; + // There has been a change in frame size. + vp9_set_size_literal(cpi, oxcf->scaled_frame_width, + oxcf->scaled_frame_height); + } // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed. set_mv_search_params(cpi); @@ -4035,8 +4059,11 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size, // For 1 pass CBR SVC, only ZEROMV is allowed for spatial reference frame // when svc->force_zero_mode_spatial_ref = 1. Under those conditions we can // avoid this frame-level upsampling (for non intra_only frames). + // For SVC single_layer mode, dynamic resize is allowed and we need to + // scale references for this case. if (frame_is_intra_only(cm) == 0 && - !(is_one_pass_cbr_svc(cpi) && svc->force_zero_mode_spatial_ref)) { + ((svc->single_layer_svc && cpi->oxcf.resize_mode == RESIZE_DYNAMIC) || + !(is_one_pass_cbr_svc(cpi) && svc->force_zero_mode_spatial_ref))) { vp9_scale_references(cpi); } @@ -4181,6 +4208,27 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size, return 1; } +static int get_ref_frame_flags(const VP9_COMP *cpi) { + const int *const map = cpi->common.ref_frame_map; + const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx]; + const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx]; + const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx]; + int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; + + if (gold_is_last) flags &= ~VP9_GOLD_FLAG; + + if (cpi->rc.frames_till_gf_update_due == INT_MAX && + (cpi->svc.number_temporal_layers == 1 && + cpi->svc.number_spatial_layers == 1)) + flags &= ~VP9_GOLD_FLAG; + + if (alt_is_last) flags &= ~VP9_ALT_FLAG; + + if (gold_is_alt) flags &= ~VP9_ALT_FLAG; + + return flags; +} + #if !CONFIG_REALTIME_ONLY #define MAX_QSTEP_ADJ 4 static int get_qstep_adj(int rate_excess, int rate_limit) { @@ -4189,8 +4237,149 @@ static int get_qstep_adj(int rate_excess, int rate_limit) { return VPXMIN(qstep, MAX_QSTEP_ADJ); } -static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, - uint8_t *dest) { +#if CONFIG_RATE_CTRL +static void init_rq_history(RATE_QINDEX_HISTORY *rq_history) { + rq_history->recode_count = 0; + rq_history->q_index_high = 255; + rq_history->q_index_low = 0; +} + +static void update_rq_history(RATE_QINDEX_HISTORY *rq_history, int target_bits, + int actual_bits, int q_index) { + rq_history->q_index_history[rq_history->recode_count] = q_index; + rq_history->rate_history[rq_history->recode_count] = actual_bits; + if (actual_bits <= target_bits) { + rq_history->q_index_high = q_index; + } + if (actual_bits >= target_bits) { + rq_history->q_index_low = q_index; + } + rq_history->recode_count += 1; +} + +static int guess_q_index_from_model(const RATE_QSTEP_MODEL *rq_model, + int target_bits) { + // The model predicts bits as follows. + // target_bits = bias - ratio * log2(q_step) + // Given the target_bits, we compute the q_step as follows. + double q_step; + assert(rq_model->ratio > 0); + q_step = pow(2.0, (rq_model->bias - target_bits) / rq_model->ratio); + // TODO(angiebird): Make this function support highbitdepth. + return vp9_convert_q_to_qindex(q_step, VPX_BITS_8); +} + +static int guess_q_index_linear(int prev_q_index, int target_bits, + int actual_bits, int gap) { + int q_index = prev_q_index; + if (actual_bits < target_bits) { + q_index -= gap; + q_index = VPXMAX(q_index, 0); + } else { + q_index += gap; + q_index = VPXMIN(q_index, 255); + } + return q_index; +} + +static double get_bits_percent_diff(int target_bits, int actual_bits) { + double diff; + target_bits = VPXMAX(target_bits, 1); + diff = abs(target_bits - actual_bits) * 1. / target_bits; + return diff * 100; +} + +static int rq_model_predict_q_index(const RATE_QSTEP_MODEL *rq_model, + const RATE_QINDEX_HISTORY *rq_history, + int target_bits) { + int q_index = 128; + if (rq_history->recode_count > 0) { + const int actual_bits = + rq_history->rate_history[rq_history->recode_count - 1]; + const int prev_q_index = + rq_history->q_index_history[rq_history->recode_count - 1]; + const double percent_diff = get_bits_percent_diff(target_bits, actual_bits); + if (percent_diff > 50) { + // Binary search. + // When the actual_bits and target_bits are far apart, binary search + // q_index is faster. + q_index = (rq_history->q_index_low + rq_history->q_index_high) / 2; + } else { + if (rq_model->ready) { + q_index = guess_q_index_from_model(rq_model, target_bits); + } else { + // TODO(angiebird): Find a better way to set the gap. + q_index = + guess_q_index_linear(prev_q_index, target_bits, actual_bits, 20); + } + } + } else { + if (rq_model->ready) { + q_index = guess_q_index_from_model(rq_model, target_bits); + } + } + + assert(rq_history->q_index_low <= rq_history->q_index_high); + if (q_index <= rq_history->q_index_low) { + q_index = rq_history->q_index_low + 1; + } + if (q_index >= rq_history->q_index_high) { + q_index = rq_history->q_index_high - 1; + } + return q_index; +} + +static void rq_model_update(const RATE_QINDEX_HISTORY *rq_history, + int target_bits, RATE_QSTEP_MODEL *rq_model) { + const int recode_count = rq_history->recode_count; + const double delta = 0.00001; + if (recode_count >= 2) { + const int q_index1 = rq_history->q_index_history[recode_count - 2]; + const int q_index2 = rq_history->q_index_history[recode_count - 1]; + const int r1 = rq_history->rate_history[recode_count - 2]; + const int r2 = rq_history->rate_history[recode_count - 1]; + int valid = 0; + // lower q_index should yield higher bit rate + if (q_index1 < q_index2) { + valid = r1 > r2; + } else if (q_index1 > q_index2) { + valid = r1 < r2; + } + // Only update the model when the q_index and rate behave normally. + if (valid) { + // Fit the ratio and bias of rq_model based on last two recode histories. + const double s1 = vp9_convert_qindex_to_q(q_index1, VPX_BITS_8); + const double s2 = vp9_convert_qindex_to_q(q_index2, VPX_BITS_8); + if (fabs(log2(s1) - log2(s2)) > delta) { + rq_model->ratio = (r2 - r1) / (log2(s1) - log2(s2)); + rq_model->bias = r1 + (rq_model->ratio) * log2(s1); + if (rq_model->ratio > delta && rq_model->bias > delta) { + rq_model->ready = 1; + } + } + } + } else if (recode_count == 1) { + if (rq_model->ready) { + // Update the ratio only when the initial model exists and we only have + // one recode history. + const int prev_q = rq_history->q_index_history[recode_count - 1]; + const double prev_q_step = vp9_convert_qindex_to_q(prev_q, VPX_BITS_8); + if (fabs(log2(prev_q_step)) > delta) { + const int actual_bits = rq_history->rate_history[recode_count - 1]; + rq_model->ratio = + rq_model->ratio + (target_bits - actual_bits) / log2(prev_q_step); + } + } + } +} +#endif // CONFIG_RATE_CTRL + +static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest +#if CONFIG_RATE_CTRL + , + RATE_QINDEX_HISTORY *rq_history +#endif // CONFIG_RATE_CTRL +) { const VP9EncoderConfig *const oxcf = &cpi->oxcf; VP9_COMMON *const cm = &cpi->common; RATE_CONTROL *const rc = &cpi->rc; @@ -4208,6 +4397,14 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, int qrange_adj = 1; #endif +#if CONFIG_RATE_CTRL + const FRAME_UPDATE_TYPE update_type = + cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index]; + const ENCODE_FRAME_TYPE frame_type = get_encode_frame_type(update_type); + RATE_QSTEP_MODEL *rq_model = &cpi->rq_model[frame_type]; + init_rq_history(rq_history); +#endif // CONFIG_RATE_CTRL + if (cm->show_existing_frame) { rc->this_frame_target = 0; if (is_psnr_calc_enabled(cpi)) set_raw_source_frame(cpi); @@ -4254,6 +4451,11 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, loop_at_this_size = 0; } +#if CONFIG_RATE_CTRL + if (cpi->encode_command.use_external_target_frame_bits) { + q = rq_model_predict_q_index(rq_model, rq_history, rc->this_frame_target); + } +#endif // CONFIG_RATE_CTRL // Decide frame size bounds first time through. if (loop_count == 0) { vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target, @@ -4300,6 +4502,19 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, q = cpi->encode_command.external_quantize_index; } #endif + if (cpi->ext_ratectrl.ready) { + const GF_GROUP *gf_group = &cpi->twopass.gf_group; + vpx_rc_encodeframe_decision_t encode_frame_decision; + FRAME_UPDATE_TYPE update_type = gf_group->update_type[gf_group->index]; + const int ref_frame_flags = get_ref_frame_flags(cpi); + RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES]; + get_ref_frame_bufs(cpi, ref_frame_bufs); + vp9_extrc_get_encodeframe_decision( + &cpi->ext_ratectrl, cm->current_video_frame, + cm->current_frame_coding_index, update_type, ref_frame_bufs, + ref_frame_flags, &encode_frame_decision); + q = encode_frame_decision.q_index; + } vp9_set_quantizer(cpi, q); @@ -4339,6 +4554,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1; } + if (cpi->ext_ratectrl.ready) { + break; + } #if CONFIG_RATE_CTRL // This part needs to be after save_coding_context() because // restore_coding_context will be called in the end of this function. @@ -4347,7 +4565,28 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, if (cpi->encode_command.use_external_quantize_index) { break; } -#endif + + if (cpi->encode_command.use_external_target_frame_bits) { + const double percent_diff = get_bits_percent_diff( + rc->this_frame_target, rc->projected_frame_size); + update_rq_history(rq_history, rc->this_frame_target, + rc->projected_frame_size, q); + loop_count += 1; + + rq_model_update(rq_history, rc->this_frame_target, rq_model); + + // Check if we hit the target bitrate. + if (percent_diff <= cpi->encode_command.target_frame_bits_error_percent || + rq_history->recode_count >= RATE_CTRL_MAX_RECODE_NUM || + rq_history->q_index_low >= rq_history->q_index_high) { + break; + } + + loop = 1; + restore_coding_context(cpi); + continue; + } +#endif // CONFIG_RATE_CTRL if (oxcf->rc_mode == VPX_Q) { loop = 0; @@ -4562,27 +4801,6 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, } #endif // !CONFIG_REALTIME_ONLY -static int get_ref_frame_flags(const VP9_COMP *cpi) { - const int *const map = cpi->common.ref_frame_map; - const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx]; - const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx]; - const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx]; - int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; - - if (gold_is_last) flags &= ~VP9_GOLD_FLAG; - - if (cpi->rc.frames_till_gf_update_due == INT_MAX && - (cpi->svc.number_temporal_layers == 1 && - cpi->svc.number_spatial_layers == 1)) - flags &= ~VP9_GOLD_FLAG; - - if (alt_is_last) flags &= ~VP9_ALT_FLAG; - - if (gold_is_alt) flags &= ~VP9_ALT_FLAG; - - return flags; -} - static void set_ext_overrides(VP9_COMP *cpi) { // Overrides the defaults with the externally supplied values with // vp9_update_reference() and vp9_update_entropy() calls @@ -4887,9 +5105,7 @@ static void set_frame_index(VP9_COMP *cpi, VP9_COMMON *cm) { const GF_GROUP *const gf_group = &cpi->twopass.gf_group; ref_buffer->frame_index = cm->current_video_frame + gf_group->arf_src_offset[gf_group->index]; -#if CONFIG_RATE_CTRL ref_buffer->frame_coding_index = cm->current_frame_coding_index; -#endif // CONFIG_RATE_CTRL } } @@ -5092,6 +5308,7 @@ static void update_encode_frame_result( #if CONFIG_RATE_CTRL const PARTITION_INFO *partition_info, const MOTION_VECTOR_INFO *motion_vector_info, + const TplDepStats *tpl_stats_info, #endif // CONFIG_RATE_CTRL ENCODE_FRAME_RESULT *encode_frame_result); #endif // !CONFIG_REALTIME_ONLY @@ -5197,8 +5414,12 @@ static void encode_frame_to_data_rate( if (!encode_without_recode_loop(cpi, size, dest)) return; } else { #if !CONFIG_REALTIME_ONLY +#if CONFIG_RATE_CTRL + encode_with_recode_loop(cpi, size, dest, &encode_frame_result->rq_history); +#else // CONFIG_RATE_CTRL encode_with_recode_loop(cpi, size, dest); -#endif +#endif // CONFIG_RATE_CTRL +#endif // !CONFIG_REALTIME_ONLY } // TODO(jingning): When using show existing frame mode, we assume that the @@ -5263,6 +5484,13 @@ static void encode_frame_to_data_rate( // build the bitstream vp9_pack_bitstream(cpi, dest, size); + { + const RefCntBuffer *coded_frame_buf = + get_ref_cnt_buffer(cm, cm->new_fb_idx); + vp9_extrc_update_encodeframe_result( + &cpi->ext_ratectrl, (*size) << 3, cpi->Source, &coded_frame_buf->buf, + cm->bit_depth, cpi->oxcf.input_bit_depth); + } #if CONFIG_REALTIME_ONLY (void)encode_frame_result; assert(encode_frame_result == NULL); @@ -5293,9 +5521,9 @@ static void encode_frame_to_data_rate( ref_frame_flags, cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index], cpi->Source, coded_frame_buf, ref_frame_bufs, vp9_get_quantizer(cpi), - cpi->oxcf.input_bit_depth, cm->bit_depth, cpi->td.counts, + cm->bit_depth, cpi->oxcf.input_bit_depth, cpi->td.counts, #if CONFIG_RATE_CTRL - cpi->partition_info, cpi->motion_vector_info, + cpi->partition_info, cpi->motion_vector_info, cpi->tpl_stats_info, #endif // CONFIG_RATE_CTRL encode_frame_result); } @@ -5450,6 +5678,11 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, unsigned int *frame_flags, ENCODE_FRAME_RESULT *encode_frame_result) { cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; + + if (cpi->common.current_frame_coding_index == 0) { + vp9_extrc_send_firstpass_stats(&cpi->ext_ratectrl, + &cpi->twopass.first_pass_info); + } #if CONFIG_MISMATCH_DEBUG mismatch_move_frame_idx_w(); #endif @@ -7141,6 +7374,48 @@ static void free_tpl_buffer(VP9_COMP *cpi) { } } +#if CONFIG_RATE_CTRL +static void accumulate_frame_tpl_stats(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + const GF_GROUP *gf_group = &cpi->twopass.gf_group; + int show_frame_count = 0; + int frame_idx; + // Accumulate tpl stats for each frame in the current group of picture. + for (frame_idx = 1; frame_idx < gf_group->gf_group_size; ++frame_idx) { + TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx]; + TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr; + const int tpl_stride = tpl_frame->stride; + int64_t intra_cost_base = 0; + int64_t inter_cost_base = 0; + int64_t mc_dep_cost_base = 0; + int64_t mc_ref_cost_base = 0; + int64_t mc_flow_base = 0; + int row, col; + + if (!tpl_frame->is_valid) continue; + + for (row = 0; row < cm->mi_rows && tpl_frame->is_valid; ++row) { + for (col = 0; col < cm->mi_cols; ++col) { + TplDepStats *this_stats = &tpl_stats[row * tpl_stride + col]; + intra_cost_base += this_stats->intra_cost; + inter_cost_base += this_stats->inter_cost; + mc_dep_cost_base += this_stats->mc_dep_cost; + mc_ref_cost_base += this_stats->mc_ref_cost; + mc_flow_base += this_stats->mc_flow; + } + } + + cpi->tpl_stats_info[show_frame_count].intra_cost = intra_cost_base; + cpi->tpl_stats_info[show_frame_count].inter_cost = inter_cost_base; + cpi->tpl_stats_info[show_frame_count].mc_dep_cost = mc_dep_cost_base; + cpi->tpl_stats_info[show_frame_count].mc_ref_cost = mc_ref_cost_base; + cpi->tpl_stats_info[show_frame_count].mc_flow = mc_flow_base; + + ++show_frame_count; + } +} +#endif // CONFIG_RATE_CTRL + static void setup_tpl_stats(VP9_COMP *cpi) { GF_PICTURE gf_picture[MAX_ARF_GOP_SIZE]; const GF_GROUP *gf_group = &cpi->twopass.gf_group; @@ -7163,6 +7438,34 @@ static void setup_tpl_stats(VP9_COMP *cpi) { dump_tpl_stats(cpi, tpl_group_frames, gf_group, gf_picture, cpi->tpl_bsize); #endif // DUMP_TPL_STATS #endif // CONFIG_NON_GREEDY_MV + +#if CONFIG_RATE_CTRL + accumulate_frame_tpl_stats(cpi); +#endif // CONFIG_RATE_CTRL +} + +void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags, + RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], + int *ref_frame_coding_indexes, + int *ref_frame_valid_list) { + if (update_type != KF_UPDATE) { + const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG, + VP9_GOLD_FLAG, + VP9_ALT_FLAG }; + int i; + for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { + assert(ref_frame_bufs[i] != NULL); + ref_frame_coding_indexes[i] = ref_frame_bufs[i]->frame_coding_index; + ref_frame_valid_list[i] = (ref_frame_flags & inter_ref_flags[i]) != 0; + } + } else { + // No reference frame is available when this is a key frame. + int i; + for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { + ref_frame_coding_indexes[i] = -1; + ref_frame_valid_list[i] = 0; + } + } } #if !CONFIG_REALTIME_ONLY @@ -7312,6 +7615,7 @@ static void yv12_buffer_to_image_buffer(const YV12_BUFFER_CONFIG *yv12_buffer, } } #endif // CONFIG_RATE_CTRL + static void update_encode_frame_result( int ref_frame_flags, FRAME_UPDATE_TYPE update_type, const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf, @@ -7320,12 +7624,13 @@ static void update_encode_frame_result( #if CONFIG_RATE_CTRL const PARTITION_INFO *partition_info, const MOTION_VECTOR_INFO *motion_vector_info, + const TplDepStats *tpl_stats_info, #endif // CONFIG_RATE_CTRL ENCODE_FRAME_RESULT *encode_frame_result) { #if CONFIG_RATE_CTRL PSNR_STATS psnr; #if CONFIG_VP9_HIGHBITDEPTH - vpx_calc_highbd_psnr(source_frame, coded_frame_buf->buf, &psnr, bit_depth, + vpx_calc_highbd_psnr(source_frame, &coded_frame_buf->buf, &psnr, bit_depth, input_bit_depth); #else // CONFIG_VP9_HIGHBITDEPTH (void)bit_depth; @@ -7334,31 +7639,16 @@ static void update_encode_frame_result( #endif // CONFIG_VP9_HIGHBITDEPTH encode_frame_result->frame_coding_index = coded_frame_buf->frame_coding_index; - if (update_type != KF_UPDATE) { - const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG, - VP9_GOLD_FLAG, - VP9_ALT_FLAG }; - int i; - for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { - assert(ref_frame_bufs[i] != NULL); - encode_frame_result->ref_frame_coding_indexes[i] = - ref_frame_bufs[i]->frame_coding_index; - encode_frame_result->ref_frame_valid_list[i] = - (ref_frame_flags & inter_ref_flags[i]) != 0; - } - } else { - // No reference frame is available when this is a key frame. - int i; - for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { - encode_frame_result->ref_frame_coding_indexes[i] = -1; - encode_frame_result->ref_frame_valid_list[i] = 0; - } - } + vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs, + encode_frame_result->ref_frame_coding_indexes, + encode_frame_result->ref_frame_valid_list); + encode_frame_result->psnr = psnr.psnr[0]; encode_frame_result->sse = psnr.sse[0]; copy_frame_counts(counts, &encode_frame_result->frame_counts); encode_frame_result->partition_info = partition_info; encode_frame_result->motion_vector_info = motion_vector_info; + encode_frame_result->tpl_stats_info = tpl_stats_info; if (encode_frame_result->coded_frame.allocated) { yv12_buffer_to_image_buffer(&coded_frame_buf->buf, &encode_frame_result->coded_frame); @@ -7384,6 +7674,7 @@ void vp9_init_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result) { encode_frame_result->frame_coding_index = -1; vp9_zero(encode_frame_result->coded_frame); encode_frame_result->coded_frame.allocated = 0; + init_rq_history(&encode_frame_result->rq_history); #endif // CONFIG_RATE_CTRL } diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h index a237b74f9..8763a5e78 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.h @@ -15,6 +15,7 @@ #include "./vpx_config.h" #include "vpx/internal/vpx_codec_internal.h" +#include "vpx/vpx_ext_ratectrl.h" #include "vpx/vp8cx.h" #if CONFIG_INTERNAL_STATS #include "vpx_dsp/ssim.h" @@ -38,6 +39,7 @@ #include "vp9/encoder/vp9_context_tree.h" #include "vp9/encoder/vp9_encodemb.h" #include "vp9/encoder/vp9_ethread.h" +#include "vp9/encoder/vp9_ext_ratectrl.h" #include "vp9/encoder/vp9_firstpass.h" #include "vp9/encoder/vp9_job_queue.h" #include "vp9/encoder/vp9_lookahead.h" @@ -147,6 +149,12 @@ typedef enum { kVeryHighSad = 6, } CONTENT_STATE_SB; +typedef enum { + LOOPFILTER_ALL = 0, + LOOPFILTER_REFERENCE = 1, // Disable loopfilter on non reference frames. + NO_LOOPFILTER = 2, // Disable loopfilter on all frames. +} LOOPFILTER_CONTROL; + typedef struct VP9EncoderConfig { BITSTREAM_PROFILE profile; vpx_bit_depth_t bit_depth; // Codec bit-depth. @@ -532,24 +540,83 @@ typedef struct MOTION_VECTOR_INFO { int_mv mv[2]; } MOTION_VECTOR_INFO; +typedef struct GOP_COMMAND { + int use; // use this command to set gop or not. If not, use vp9's decision. + int show_frame_count; + int use_alt_ref; +} GOP_COMMAND; + +static INLINE void gop_command_on(GOP_COMMAND *gop_command, + int show_frame_count, int use_alt_ref) { + gop_command->use = 1; + gop_command->show_frame_count = show_frame_count; + gop_command->use_alt_ref = use_alt_ref; +} + +static INLINE void gop_command_off(GOP_COMMAND *gop_command) { + gop_command->use = 0; + gop_command->show_frame_count = 0; + gop_command->use_alt_ref = 0; +} + +static INLINE int gop_command_coding_frame_count( + const GOP_COMMAND *gop_command) { + if (gop_command->use == 0) { + assert(0); + return -1; + } + return gop_command->show_frame_count + gop_command->use_alt_ref; +} + +// TODO(angiebird): See if we can merge this one with FrameType in +// simple_encode.h +typedef enum ENCODE_FRAME_TYPE { + ENCODE_FRAME_TYPE_KEY, + ENCODE_FRAME_TYPE_INTER, + ENCODE_FRAME_TYPE_ALTREF, + ENCODE_FRAME_TYPE_OVERLAY, + ENCODE_FRAME_TYPE_GOLDEN, + ENCODE_FRAME_TYPES, +} ENCODE_FRAME_TYPE; + +// TODO(angiebird): Merge this function with get_frame_type_from_update_type() +static INLINE ENCODE_FRAME_TYPE +get_encode_frame_type(FRAME_UPDATE_TYPE update_type) { + switch (update_type) { + case KF_UPDATE: return ENCODE_FRAME_TYPE_KEY; + case ARF_UPDATE: return ENCODE_FRAME_TYPE_ALTREF; + case GF_UPDATE: return ENCODE_FRAME_TYPE_GOLDEN; + case OVERLAY_UPDATE: return ENCODE_FRAME_TYPE_OVERLAY; + case LF_UPDATE: return ENCODE_FRAME_TYPE_INTER; + default: + fprintf(stderr, "Unsupported update_type %d\n", update_type); + abort(); + return ENCODE_FRAME_TYPE_INTER; + } +} + +typedef struct RATE_QSTEP_MODEL { + // The rq model predicts the bit usage as follows. + // rate = bias - ratio * log2(q_step) + int ready; + double bias; + double ratio; +} RATE_QSTEP_MODEL; + typedef struct ENCODE_COMMAND { int use_external_quantize_index; int external_quantize_index; - // A list of binary flags set from the external controller. - // Each binary flag indicates whether the frame is an arf or not. - const int *external_arf_indexes; + + int use_external_target_frame_bits; + int target_frame_bits; + double target_frame_bits_error_percent; + + GOP_COMMAND gop_command; } ENCODE_COMMAND; -static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) { - vp9_zero(*encode_command); - encode_command->use_external_quantize_index = 0; - encode_command->external_quantize_index = -1; - encode_command->external_arf_indexes = NULL; -} - -static INLINE void encode_command_set_external_arf_indexes( - ENCODE_COMMAND *encode_command, const int *external_arf_indexes) { - encode_command->external_arf_indexes = external_arf_indexes; +static INLINE void encode_command_set_gop_command( + ENCODE_COMMAND *encode_command, GOP_COMMAND gop_command) { + encode_command->gop_command = gop_command; } static INLINE void encode_command_set_external_quantize_index( @@ -564,9 +631,35 @@ static INLINE void encode_command_reset_external_quantize_index( encode_command->external_quantize_index = -1; } +static INLINE void encode_command_set_target_frame_bits( + ENCODE_COMMAND *encode_command, int target_frame_bits, + double target_frame_bits_error_percent) { + encode_command->use_external_target_frame_bits = 1; + encode_command->target_frame_bits = target_frame_bits; + encode_command->target_frame_bits_error_percent = + target_frame_bits_error_percent; +} + +static INLINE void encode_command_reset_target_frame_bits( + ENCODE_COMMAND *encode_command) { + encode_command->use_external_target_frame_bits = 0; + encode_command->target_frame_bits = -1; + encode_command->target_frame_bits_error_percent = 0; +} + +static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) { + vp9_zero(*encode_command); + encode_command_reset_external_quantize_index(encode_command); + encode_command_reset_target_frame_bits(encode_command); + gop_command_off(&encode_command->gop_command); +} + // Returns number of units in size of 4, if not multiple not a multiple of 4, // round it up. For example, size is 7, return 2. static INLINE int get_num_unit_4x4(int size) { return (size + 3) >> 2; } +// Returns number of units in size of 16, if not multiple not a multiple of 16, +// round it up. For example, size is 17, return 2. +static INLINE int get_num_unit_16x16(int size) { return (size + 15) >> 4; } #endif // CONFIG_RATE_CTRL typedef struct VP9_COMP { @@ -873,11 +966,18 @@ typedef struct VP9_COMP { int multi_layer_arf; vpx_roi_map_t roi; + + LOOPFILTER_CONTROL loopfilter_ctrl; #if CONFIG_RATE_CTRL ENCODE_COMMAND encode_command; PARTITION_INFO *partition_info; MOTION_VECTOR_INFO *motion_vector_info; + MOTION_VECTOR_INFO *fp_motion_vector_info; + TplDepStats *tpl_stats_info; + + RATE_QSTEP_MODEL rq_model[ENCODE_FRAME_TYPES]; #endif + EXT_RATECTRL ext_ratectrl; } VP9_COMP; #if CONFIG_RATE_CTRL @@ -902,6 +1002,13 @@ static INLINE void free_partition_info(struct VP9_COMP *cpi) { cpi->partition_info = NULL; } +static INLINE void reset_mv_info(MOTION_VECTOR_INFO *mv_info) { + mv_info->ref_frame[0] = NONE; + mv_info->ref_frame[1] = NONE; + mv_info->mv[0].as_int = INVALID_MV; + mv_info->mv[1].as_int = INVALID_MV; +} + // Allocates memory for the motion vector information. // The unit size is each 4x4 block. // Only called once in vp9_create_compressor(). @@ -923,6 +1030,53 @@ static INLINE void free_motion_vector_info(struct VP9_COMP *cpi) { cpi->motion_vector_info = NULL; } +// Allocates memory for the tpl stats information. +// Only called once in vp9_create_compressor(). +static INLINE void tpl_stats_info_init(struct VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + CHECK_MEM_ERROR( + cm, cpi->tpl_stats_info, + (TplDepStats *)vpx_calloc(MAX_LAG_BUFFERS, sizeof(TplDepStats))); + memset(cpi->tpl_stats_info, 0, MAX_LAG_BUFFERS * sizeof(TplDepStats)); +} + +// Frees memory of the tpl stats information. +// Only called once in dealloc_compressor_data(). +static INLINE void free_tpl_stats_info(struct VP9_COMP *cpi) { + vpx_free(cpi->tpl_stats_info); + cpi->tpl_stats_info = NULL; +} + +// Allocates memory for the first pass motion vector information. +// The unit size is each 16x16 block. +// Only called once in vp9_create_compressor(). +static INLINE void fp_motion_vector_info_init(struct VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + const int unit_width = get_num_unit_16x16(cpi->frame_info.frame_width); + const int unit_height = get_num_unit_16x16(cpi->frame_info.frame_height); + CHECK_MEM_ERROR(cm, cpi->fp_motion_vector_info, + (MOTION_VECTOR_INFO *)vpx_calloc(unit_width * unit_height, + sizeof(MOTION_VECTOR_INFO))); +} + +static INLINE void fp_motion_vector_info_reset( + int frame_width, int frame_height, + MOTION_VECTOR_INFO *fp_motion_vector_info) { + const int unit_width = get_num_unit_16x16(frame_width); + const int unit_height = get_num_unit_16x16(frame_height); + int i; + for (i = 0; i < unit_width * unit_height; ++i) { + reset_mv_info(fp_motion_vector_info + i); + } +} + +// Frees memory of the first pass motion vector information. +// Only called once in dealloc_compressor_data(). +static INLINE void free_fp_motion_vector_info(struct VP9_COMP *cpi) { + vpx_free(cpi->fp_motion_vector_info); + cpi->fp_motion_vector_info = NULL; +} + // This is the c-version counter part of ImageBuffer typedef struct IMAGE_BUFFER { int allocated; @@ -930,6 +1084,17 @@ typedef struct IMAGE_BUFFER { int plane_height[3]; uint8_t *plane_buffer[3]; } IMAGE_BUFFER; + +#define RATE_CTRL_MAX_RECODE_NUM 7 + +typedef struct RATE_QINDEX_HISTORY { + int recode_count; + int q_index_history[RATE_CTRL_MAX_RECODE_NUM]; + int rate_history[RATE_CTRL_MAX_RECODE_NUM]; + int q_index_high; + int q_index_low; +} RATE_QINDEX_HISTORY; + #endif // CONFIG_RATE_CTRL typedef struct ENCODE_FRAME_RESULT { @@ -944,7 +1109,9 @@ typedef struct ENCODE_FRAME_RESULT { FRAME_COUNTS frame_counts; const PARTITION_INFO *partition_info; const MOTION_VECTOR_INFO *motion_vector_info; + const TplDepStats *tpl_stats_info; IMAGE_BUFFER coded_frame; + RATE_QINDEX_HISTORY rq_history; #endif // CONFIG_RATE_CTRL int quantize_index; } ENCODE_FRAME_RESULT; @@ -1000,6 +1167,14 @@ int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width, void vp9_set_svc(VP9_COMP *cpi, int use_svc); +// Check for resetting the rc flags (rc_1_frame, rc_2_frame) if the +// configuration change has a large change in avg_frame_bandwidth. +// For SVC check for resetting based on spatial layer average bandwidth. +// Also reset buffer level to optimal level. +void vp9_check_reset_rc_flag(VP9_COMP *cpi); + +void vp9_set_rc_buffer_sizes(VP9_COMP *cpi); + static INLINE int stack_pop(int *stack, int stack_size) { int idx; const int r = stack[0]; @@ -1112,6 +1287,11 @@ void vp9_scale_references(VP9_COMP *cpi); void vp9_update_reference_frames(VP9_COMP *cpi); +void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags, + RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], + int *ref_frame_coding_indexes, + int *ref_frame_valid_list); + void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv); YV12_BUFFER_CONFIG *vp9_svc_twostage_scale( diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.c new file mode 100644 index 000000000..94c2addd2 --- /dev/null +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2020 The WebM 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 "vp9/encoder/vp9_ext_ratectrl.h" +#include "vp9/encoder/vp9_encoder.h" +#include "vp9/common/vp9_common.h" +#include "vpx_dsp/psnr.h" + +void vp9_extrc_init(EXT_RATECTRL *ext_ratectrl) { vp9_zero(*ext_ratectrl); } + +void vp9_extrc_create(vpx_rc_funcs_t funcs, vpx_rc_config_t ratectrl_config, + EXT_RATECTRL *ext_ratectrl) { + vpx_rc_firstpass_stats_t *rc_firstpass_stats; + vp9_extrc_delete(ext_ratectrl); + ext_ratectrl->funcs = funcs; + ext_ratectrl->ratectrl_config = ratectrl_config; + ext_ratectrl->funcs.create_model(ext_ratectrl->funcs.priv, + &ext_ratectrl->ratectrl_config, + &ext_ratectrl->model); + rc_firstpass_stats = &ext_ratectrl->rc_firstpass_stats; + rc_firstpass_stats->num_frames = ratectrl_config.show_frame_count; + rc_firstpass_stats->frame_stats = + vpx_malloc(sizeof(*rc_firstpass_stats->frame_stats) * + rc_firstpass_stats->num_frames); + ext_ratectrl->ready = 1; +} + +void vp9_extrc_delete(EXT_RATECTRL *ext_ratectrl) { + if (ext_ratectrl->ready) { + ext_ratectrl->funcs.delete_model(ext_ratectrl->model); + vpx_free(ext_ratectrl->rc_firstpass_stats.frame_stats); + } + vp9_extrc_init(ext_ratectrl); +} + +static void gen_rc_firstpass_stats(const FIRSTPASS_STATS *stats, + vpx_rc_frame_stats_t *rc_frame_stats) { + rc_frame_stats->frame = stats->frame; + rc_frame_stats->weight = stats->weight; + rc_frame_stats->intra_error = stats->intra_error; + rc_frame_stats->coded_error = stats->coded_error; + rc_frame_stats->sr_coded_error = stats->sr_coded_error; + rc_frame_stats->frame_noise_energy = stats->frame_noise_energy; + rc_frame_stats->pcnt_inter = stats->pcnt_inter; + rc_frame_stats->pcnt_motion = stats->pcnt_motion; + rc_frame_stats->pcnt_second_ref = stats->pcnt_second_ref; + rc_frame_stats->pcnt_neutral = stats->pcnt_neutral; + rc_frame_stats->pcnt_intra_low = stats->pcnt_intra_low; + rc_frame_stats->pcnt_intra_high = stats->pcnt_intra_high; + rc_frame_stats->intra_skip_pct = stats->intra_skip_pct; + rc_frame_stats->intra_smooth_pct = stats->intra_smooth_pct; + rc_frame_stats->inactive_zone_rows = stats->inactive_zone_rows; + rc_frame_stats->inactive_zone_cols = stats->inactive_zone_cols; + rc_frame_stats->MVr = stats->MVr; + rc_frame_stats->mvr_abs = stats->mvr_abs; + rc_frame_stats->MVc = stats->MVc; + rc_frame_stats->mvc_abs = stats->mvc_abs; + rc_frame_stats->MVrv = stats->MVrv; + rc_frame_stats->MVcv = stats->MVcv; + rc_frame_stats->mv_in_out_count = stats->mv_in_out_count; + rc_frame_stats->duration = stats->duration; + rc_frame_stats->count = stats->count; +} + +void vp9_extrc_send_firstpass_stats(EXT_RATECTRL *ext_ratectrl, + const FIRST_PASS_INFO *first_pass_info) { + if (ext_ratectrl->ready) { + vpx_rc_firstpass_stats_t *rc_firstpass_stats = + &ext_ratectrl->rc_firstpass_stats; + int i; + assert(rc_firstpass_stats->num_frames == first_pass_info->num_frames); + for (i = 0; i < rc_firstpass_stats->num_frames; ++i) { + gen_rc_firstpass_stats(&first_pass_info->stats[i], + &rc_firstpass_stats->frame_stats[i]); + } + ext_ratectrl->funcs.send_firstpass_stats(ext_ratectrl->model, + rc_firstpass_stats); + } +} + +static int extrc_get_frame_type(FRAME_UPDATE_TYPE update_type) { + // TODO(angiebird): Add unit test to make sure this function behaves like + // get_frame_type_from_update_type() + // TODO(angiebird): Merge this function with get_frame_type_from_update_type() + switch (update_type) { + case KF_UPDATE: return 0; // kFrameTypeKey; + case ARF_UPDATE: return 2; // kFrameTypeAltRef; + case GF_UPDATE: return 4; // kFrameTypeGolden; + case OVERLAY_UPDATE: return 3; // kFrameTypeOverlay; + case LF_UPDATE: return 1; // kFrameTypeInter; + default: + fprintf(stderr, "Unsupported update_type %d\n", update_type); + abort(); + return 1; + } +} + +void vp9_extrc_get_encodeframe_decision( + EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index, + FRAME_UPDATE_TYPE update_type, + RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int ref_frame_flags, + vpx_rc_encodeframe_decision_t *encode_frame_decision) { + if (ext_ratectrl->ready) { + vpx_rc_encodeframe_info_t encode_frame_info; + encode_frame_info.show_index = show_index; + encode_frame_info.coding_index = coding_index; + encode_frame_info.frame_type = extrc_get_frame_type(update_type); + + vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs, + encode_frame_info.ref_frame_coding_indexes, + encode_frame_info.ref_frame_valid_list); + + ext_ratectrl->funcs.get_encodeframe_decision( + ext_ratectrl->model, &encode_frame_info, encode_frame_decision); + } +} + +void vp9_extrc_update_encodeframe_result(EXT_RATECTRL *ext_ratectrl, + int64_t bit_count, + const YV12_BUFFER_CONFIG *source_frame, + const YV12_BUFFER_CONFIG *coded_frame, + uint32_t bit_depth, + uint32_t input_bit_depth) { + if (ext_ratectrl->ready) { + PSNR_STATS psnr; + vpx_rc_encodeframe_result_t encode_frame_result; + encode_frame_result.bit_count = bit_count; + encode_frame_result.pixel_count = + source_frame->y_width * source_frame->y_height + + 2 * source_frame->uv_width * source_frame->uv_height; +#if CONFIG_VP9_HIGHBITDEPTH + vpx_calc_highbd_psnr(source_frame, coded_frame, &psnr, bit_depth, + input_bit_depth); +#else + (void)bit_depth; + (void)input_bit_depth; + vpx_calc_psnr(source_frame, coded_frame, &psnr); +#endif + encode_frame_result.sse = psnr.sse[0]; + ext_ratectrl->funcs.update_encodeframe_result(ext_ratectrl->model, + &encode_frame_result); + } +} diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.h new file mode 100644 index 000000000..fb6cfe1ac --- /dev/null +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 The WebM 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. + */ + +#ifndef VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ +#define VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ + +#include "vpx/vpx_ext_ratectrl.h" +#include "vp9/encoder/vp9_firstpass.h" + +typedef struct EXT_RATECTRL { + int ready; + vpx_rc_model_t model; + vpx_rc_funcs_t funcs; + vpx_rc_config_t ratectrl_config; + vpx_rc_firstpass_stats_t rc_firstpass_stats; +} EXT_RATECTRL; + +void vp9_extrc_init(EXT_RATECTRL *ext_ratectrl); + +void vp9_extrc_create(vpx_rc_funcs_t funcs, vpx_rc_config_t ratectrl_config, + EXT_RATECTRL *ext_ratectrl); + +void vp9_extrc_delete(EXT_RATECTRL *ext_ratectrl); + +void vp9_extrc_send_firstpass_stats(EXT_RATECTRL *ext_ratectrl, + const FIRST_PASS_INFO *first_pass_info); + +void vp9_extrc_get_encodeframe_decision( + EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index, + FRAME_UPDATE_TYPE update_type, + RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int ref_frame_flags, + vpx_rc_encodeframe_decision_t *encode_frame_decision); + +void vp9_extrc_update_encodeframe_result(EXT_RATECTRL *ext_ratectrl, + int64_t bit_count, + const YV12_BUFFER_CONFIG *source_frame, + const YV12_BUFFER_CONFIG *coded_frame, + uint32_t bit_depth, + uint32_t input_bit_depth); + +#endif // VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c index f8e24610a..dcb62e876 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_extend.c @@ -18,18 +18,26 @@ static void copy_and_extend_plane(const uint8_t *src, int src_pitch, uint8_t *dst, int dst_pitch, int w, int h, int extend_top, int extend_left, - int extend_bottom, int extend_right) { - int i, linesize; + int extend_bottom, int extend_right, + int interleave_step) { + int i, j, linesize; + const int step = interleave_step < 1 ? 1 : interleave_step; // copy the left and right most columns out const uint8_t *src_ptr1 = src; - const uint8_t *src_ptr2 = src + w - 1; + const uint8_t *src_ptr2 = src + (w - 1) * step; uint8_t *dst_ptr1 = dst - extend_left; uint8_t *dst_ptr2 = dst + w; for (i = 0; i < h; i++) { memset(dst_ptr1, src_ptr1[0], extend_left); - memcpy(dst_ptr1 + extend_left, src_ptr1, w); + if (step == 1) { + memcpy(dst_ptr1 + extend_left, src_ptr1, w); + } else { + for (j = 0; j < w; j++) { + dst_ptr1[extend_left + j] = src_ptr1[step * j]; + } + } memset(dst_ptr2, src_ptr2[0], extend_right); src_ptr1 += src_pitch; src_ptr2 += src_pitch; @@ -122,6 +130,8 @@ void vp9_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src, const int el_uv = el_y >> uv_width_subsampling; const int eb_uv = eb_y >> uv_height_subsampling; const int er_uv = er_y >> uv_width_subsampling; + // detect nv12 colorspace + const int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1; #if CONFIG_VP9_HIGHBITDEPTH if (src->flags & YV12_FLAG_HIGHBITDEPTH) { @@ -142,15 +152,15 @@ void vp9_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src, copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, src->y_crop_width, src->y_crop_height, - et_y, el_y, eb_y, er_y); + et_y, el_y, eb_y, er_y, 1); copy_and_extend_plane(src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride, src->uv_crop_width, src->uv_crop_height, - et_uv, el_uv, eb_uv, er_uv); + et_uv, el_uv, eb_uv, er_uv, chroma_step); copy_and_extend_plane(src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride, src->uv_crop_width, src->uv_crop_height, - et_uv, el_uv, eb_uv, er_uv); + et_uv, el_uv, eb_uv, er_uv, chroma_step); } void vp9_copy_and_extend_frame_with_rect(const YV12_BUFFER_CONFIG *src, @@ -176,16 +186,18 @@ void vp9_copy_and_extend_frame_with_rect(const YV12_BUFFER_CONFIG *src, const int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1); const int srch_uv = ROUND_POWER_OF_TWO(srch, 1); const int srcw_uv = ROUND_POWER_OF_TWO(srcw, 1); + // detect nv12 colorspace + const int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1; copy_and_extend_plane(src->y_buffer + src_y_offset, src->y_stride, dst->y_buffer + dst_y_offset, dst->y_stride, srcw, srch, - et_y, el_y, eb_y, er_y); + et_y, el_y, eb_y, er_y, 1); copy_and_extend_plane(src->u_buffer + src_uv_offset, src->uv_stride, dst->u_buffer + dst_uv_offset, dst->uv_stride, srcw_uv, - srch_uv, et_uv, el_uv, eb_uv, er_uv); + srch_uv, et_uv, el_uv, eb_uv, er_uv, chroma_step); copy_and_extend_plane(src->v_buffer + src_uv_offset, src->uv_stride, dst->v_buffer + dst_uv_offset, dst->uv_stride, srcw_uv, - srch_uv, et_uv, el_uv, eb_uv, er_uv); + srch_uv, et_uv, el_uv, eb_uv, er_uv, chroma_step); } diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c index 0bda4b7d6..de954f757 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.c @@ -389,6 +389,29 @@ static int get_search_range(const VP9_COMP *cpi) { return sr; } +// Reduce limits to keep the motion search within MV_MAX of ref_mv. Not doing +// this can be problematic for big videos (8K) and may cause assert failure +// (or memory violation) in mv_cost. Limits are only modified if they would +// be non-empty. Returns 1 if limits are non-empty. +static int intersect_limits_with_mv_max(MvLimits *mv_limits, const MV *ref_mv) { + const int row_min = + VPXMAX(mv_limits->row_min, (ref_mv->row + 7 - MV_MAX) >> 3); + const int row_max = + VPXMIN(mv_limits->row_max, (ref_mv->row - 1 + MV_MAX) >> 3); + const int col_min = + VPXMAX(mv_limits->col_min, (ref_mv->col + 7 - MV_MAX) >> 3); + const int col_max = + VPXMIN(mv_limits->col_max, (ref_mv->col - 1 + MV_MAX) >> 3); + if (row_min > row_max || col_min > col_max) { + return 0; + } + mv_limits->row_min = row_min; + mv_limits->row_max = row_max; + mv_limits->col_min = col_min; + mv_limits->col_max = col_max; + return 1; +} + static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x, const MV *ref_mv, MV *best_mv, int *best_motion_err) { @@ -403,9 +426,14 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x, int step_param = 3; int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; const int sr = get_search_range(cpi); + const MvLimits tmp_mv_limits = x->mv_limits; step_param += sr; further_steps -= sr; + if (!intersect_limits_with_mv_max(&x->mv_limits, ref_mv)) { + return; + } + // Override the default variance function to use MSE. v_fn_ptr.vf = get_block_variance_fn(bsize); #if CONFIG_VP9_HIGHBITDEPTH @@ -451,6 +479,7 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x, } } } + x->mv_limits = tmp_mv_limits; } static BLOCK_SIZE get_bsize(const VP9_COMMON *cm, int mb_row, int mb_col) { @@ -810,6 +839,22 @@ static void accumulate_fp_mb_row_stat(TileDataEnc *this_tile, fp_acc_data->image_data_start_row); } +#if CONFIG_RATE_CTRL +static void store_fp_motion_vector(VP9_COMP *cpi, const MV *mv, + const int mb_row, const int mb_col, + MV_REFERENCE_FRAME frame_type, + const int mv_idx) { + VP9_COMMON *const cm = &cpi->common; + const int mb_index = mb_row * cm->mb_cols + mb_col; + MOTION_VECTOR_INFO *this_motion_vector_info = + &cpi->fp_motion_vector_info[mb_index]; + this_motion_vector_info->ref_frame[mv_idx] = frame_type; + if (frame_type != INTRA_FRAME) { + this_motion_vector_info->mv[mv_idx].as_mv = *mv; + } +} +#endif // CONFIG_RATE_CTRL + #define NZ_MOTION_PENALTY 128 #define INTRA_MODE_PENALTY 1024 void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, @@ -1044,6 +1089,11 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, struct buf_2d unscaled_last_source_buf_2d; vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize]; +#if CONFIG_RATE_CTRL + // Store zero mv as default + store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0); +#endif // CONFIG_RAGE_CTRL + xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset; #if CONFIG_VP9_HIGHBITDEPTH if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { @@ -1108,6 +1158,9 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, vp9_get_mvpred_var(x, &tmp_mv, &zero_mv, &v_fn_ptr, 0); } } +#if CONFIG_RATE_CTRL + store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0); +#endif // CONFIG_RAGE_CTRL // Search in an older reference frame. if ((cm->current_video_frame > 1) && gld_yv12 != NULL) { @@ -1129,6 +1182,9 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, #endif // CONFIG_VP9_HIGHBITDEPTH first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &gf_motion_error); +#if CONFIG_RATE_CTRL + store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col, GOLDEN_FRAME, 1); +#endif // CONFIG_RAGE_CTRL if (gf_motion_error < motion_error && gf_motion_error < this_error) ++(fp_acc_data->second_ref_count); @@ -1302,6 +1358,9 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, } } else { fp_acc_data->sr_coded_error += (int64_t)this_error; +#if CONFIG_RATE_CTRL + store_fp_motion_vector(cpi, NULL, mb_row, mb_col, INTRA_FRAME, 0); +#endif // CONFIG_RAGE_CTRL } fp_acc_data->coded_error += (int64_t)this_error; @@ -1328,6 +1387,12 @@ static void first_pass_encode(VP9_COMP *cpi, FIRSTPASS_DATA *fp_acc_data) { // Tiling is ignored in the first pass. vp9_tile_init(tile, cm, 0, 0); +#if CONFIG_RATE_CTRL + fp_motion_vector_info_reset(cpi->frame_info.frame_width, + cpi->frame_info.frame_height, + cpi->fp_motion_vector_info); +#endif + for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { best_ref_mv = zero_mv; vp9_first_pass_encode_tile_mb_row(cpi, &cpi->td, fp_acc_data, &tile_data, @@ -2479,9 +2544,6 @@ typedef struct RANGE { * structs. */ static int get_gop_coding_frame_num( -#if CONFIG_RATE_CTRL - const int *external_arf_indexes, -#endif int *use_alt_ref, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc, int gf_start_show_idx, const RANGE *active_gf_interval, @@ -2497,24 +2559,6 @@ static int get_gop_coding_frame_num( (frame_info->frame_height + frame_info->frame_width) / 4.0; double zero_motion_accumulator = 1.0; int gop_coding_frames; -#if CONFIG_RATE_CTRL - (void)mv_ratio_accumulator_thresh; - (void)active_gf_interval; - (void)gop_intra_factor; - - if (external_arf_indexes != NULL && rc->frames_to_key > 1) { - // gop_coding_frames = 1 is necessary to filter out the overlay frame, - // since the arf is in this group of picture and its overlay is in the next. - gop_coding_frames = 1; - *use_alt_ref = 1; - while (gop_coding_frames < rc->frames_to_key) { - const int frame_index = gf_start_show_idx + gop_coding_frames; - ++gop_coding_frames; - if (external_arf_indexes[frame_index] == 1) break; - } - return gop_coding_frames; - } -#endif // CONFIG_RATE_CTRL *use_alt_ref = 1; gop_coding_frames = 0; @@ -2741,15 +2785,26 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { gop_intra_factor = 1.0; } - { - gop_coding_frames = get_gop_coding_frame_num( #if CONFIG_RATE_CTRL - cpi->encode_command.external_arf_indexes, -#endif - &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx, - &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames); - use_alt_ref &= allow_alt_ref; + { + const GOP_COMMAND *gop_command = &cpi->encode_command.gop_command; + assert(allow_alt_ref == 1); + if (gop_command->use) { + gop_coding_frames = gop_command_coding_frame_count(gop_command); + use_alt_ref = gop_command->use_alt_ref; + } else { + gop_coding_frames = get_gop_coding_frame_num( + &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx, + &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames); + use_alt_ref &= allow_alt_ref; + } } +#else + gop_coding_frames = get_gop_coding_frame_num( + &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx, + &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames); + use_alt_ref &= allow_alt_ref; +#endif // Was the group length constrained by the requirement for a new KF? rc->constrained_gf_group = (gop_coding_frames >= rc->frames_to_key) ? 1 : 0; @@ -3675,6 +3730,7 @@ void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame, int *use_alt_ref, int *coding_frame_count, int *first_show_idx, int *last_gop_use_alt_ref) { + const GOP_COMMAND *gop_command = &cpi->encode_command.gop_command; // We make a copy of rc here because we want to get information from the // encoder without changing its state. // TODO(angiebird): Avoid copying rc here. @@ -3697,14 +3753,19 @@ void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame, *first_is_key_frame = 1; } - *coding_frame_count = vp9_get_gop_coding_frame_count( - cpi->encode_command.external_arf_indexes, &cpi->oxcf, &cpi->frame_info, - &cpi->twopass.first_pass_info, &rc, *first_show_idx, multi_layer_arf, - allow_alt_ref, *first_is_key_frame, *last_gop_use_alt_ref, use_alt_ref); + if (gop_command->use) { + *coding_frame_count = gop_command_coding_frame_count(gop_command); + *use_alt_ref = gop_command->use_alt_ref; + assert(*coding_frame_count < rc.frames_to_key); + } else { + *coding_frame_count = vp9_get_gop_coding_frame_count( + &cpi->oxcf, &cpi->frame_info, &cpi->twopass.first_pass_info, &rc, + *first_show_idx, multi_layer_arf, allow_alt_ref, *first_is_key_frame, + *last_gop_use_alt_ref, use_alt_ref); + } } -int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, - const VP9EncoderConfig *oxcf, +int vp9_get_gop_coding_frame_count(const VP9EncoderConfig *oxcf, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc, int show_idx, @@ -3727,9 +3788,6 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, } frame_count = get_gop_coding_frame_num( -#if CONFIG_RATE_CTRL - external_arf_indexes, -#endif use_alt_ref, frame_info, first_pass_info, rc, show_idx, &active_gf_interval, gop_intra_factor, oxcf->lag_in_frames); *use_alt_ref &= allow_alt_ref; @@ -3738,8 +3796,7 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, // Under CONFIG_RATE_CTRL, once the first_pass_info is ready, the number of // coding frames (including show frame and alt ref) can be determined. -int vp9_get_coding_frame_num(const int *external_arf_indexes, - const VP9EncoderConfig *oxcf, +int vp9_get_coding_frame_num(const VP9EncoderConfig *oxcf, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, int multi_layer_arf, int allow_alt_ref) { @@ -3750,7 +3807,6 @@ int vp9_get_coding_frame_num(const int *external_arf_indexes, int show_idx = 0; int last_gop_use_alt_ref = 0; vp9_rc_init(oxcf, 1, &rc); - rc.static_scene_max_gf_interval = 250; while (show_idx < first_pass_info->num_frames) { int use_alt_ref; @@ -3763,9 +3819,8 @@ int vp9_get_coding_frame_num(const int *external_arf_indexes, } gop_coding_frame_count = vp9_get_gop_coding_frame_count( - external_arf_indexes, oxcf, frame_info, first_pass_info, &rc, show_idx, - multi_layer_arf, allow_alt_ref, first_is_key_frame, - last_gop_use_alt_ref, &use_alt_ref); + oxcf, frame_info, first_pass_info, &rc, show_idx, multi_layer_arf, + allow_alt_ref, first_is_key_frame, last_gop_use_alt_ref, &use_alt_ref); rc.source_alt_ref_active = use_alt_ref; last_gop_use_alt_ref = use_alt_ref; @@ -3777,6 +3832,30 @@ int vp9_get_coding_frame_num(const int *external_arf_indexes, } return coding_frame_num; } + +void vp9_get_key_frame_map(const VP9EncoderConfig *oxcf, + const FRAME_INFO *frame_info, + const FIRST_PASS_INFO *first_pass_info, + int *key_frame_map) { + int show_idx = 0; + RATE_CONTROL rc; + vp9_rc_init(oxcf, 1, &rc); + + // key_frame_map points to an int array with size equal to + // first_pass_info->num_frames, which is also the number of show frames in the + // video. + memset(key_frame_map, 0, + sizeof(*key_frame_map) * first_pass_info->num_frames); + while (show_idx < first_pass_info->num_frames) { + int key_frame_group_size; + key_frame_map[show_idx] = 1; + key_frame_group_size = vp9_get_frames_to_next_key( + oxcf, frame_info, first_pass_info, show_idx, rc.min_gf_interval); + assert(key_frame_group_size > 0); + show_idx += key_frame_group_size; + } + assert(show_idx == first_pass_info->num_frames); +} #endif // CONFIG_RATE_CTRL FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass) { diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h index dcaf2eec6..b1047eab2 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_firstpass.h @@ -264,7 +264,6 @@ void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi, /*!\brief Call this function before coding a new group of pictures to get * information about it. - * \param[in] external_arf_indexes External arf indexs passed in * \param[in] oxcf Encoder config * \param[in] frame_info Frame info * \param[in] first_pass_info First pass stats @@ -279,8 +278,7 @@ void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi, * * \return Returns coding frame count */ -int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, - const struct VP9EncoderConfig *oxcf, +int vp9_get_gop_coding_frame_count(const struct VP9EncoderConfig *oxcf, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc, int show_idx, @@ -288,11 +286,20 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, int first_is_key_frame, int last_gop_use_alt_ref, int *use_alt_ref); -int vp9_get_coding_frame_num(const int *external_arf_indexes, - const struct VP9EncoderConfig *oxcf, +int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, int multi_layer_arf, int allow_alt_ref); + +/*!\brief Compute a key frame binary map indicates whether key frames appear + * in the corresponding positions. The passed in key_frame_map must point to an + * integer array with length equal to first_pass_info->num_frames, which is the + * number of show frames in the video. + */ +void vp9_get_key_frame_map(const struct VP9EncoderConfig *oxcf, + const FRAME_INFO *frame_info, + const FIRST_PASS_INFO *first_pass_info, + int *key_frame_map); #endif // CONFIG_RATE_CTRL FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass); diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_pickmode.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_pickmode.c index 23c943c21..695fd484f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_pickmode.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_pickmode.c @@ -1127,7 +1127,7 @@ static INLINE void update_thresh_freq_fact_row_mt( } static INLINE void update_thresh_freq_fact( - VP9_COMP *cpi, TileDataEnc *tile_data, int source_variance, + VP9_COMP *cpi, TileDataEnc *tile_data, unsigned int source_variance, BLOCK_SIZE bsize, MV_REFERENCE_FRAME ref_frame, THR_MODES best_mode_idx, PREDICTION_MODE mode) { THR_MODES thr_mode_idx = mode_idx[ref_frame][mode_offset(mode)]; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c index ef64cc6c5..4b87ff2f0 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.c @@ -249,7 +249,7 @@ int vp9_rc_clamp_iframe_target_size(const VP9_COMP *const cpi, int target) { // way for CBR mode, for the buffering updates below. Look into removing one // of these (i.e., bits_off_target). // Update the buffer level before encoding with the per-frame-bandwidth, -static void update_buffer_level_preencode(VP9_COMP *cpi) { +void vp9_update_buffer_level_preencode(VP9_COMP *cpi) { RATE_CONTROL *const rc = &cpi->rc; rc->bits_off_target += rc->avg_frame_bandwidth; // Clip the buffer level to the maximum specified buffer size. @@ -431,11 +431,17 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { rc->max_gf_interval = vp9_rc_get_default_max_gf_interval( oxcf->init_framerate, rc->min_gf_interval); rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2; + if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) { + rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL; + } else { + rc->static_scene_max_gf_interval = MAX_STATIC_GF_GROUP_LENGTH; + } rc->force_max_q = 0; rc->last_post_encode_dropped_scene_change = 0; rc->use_post_encode_drop = 0; rc->ext_use_post_encode_drop = 0; + rc->disable_overshoot_maxq_cbr = 0; rc->arf_active_best_quality_adjustment_factor = 1.0; rc->arf_increase_active_best_quality = 0; rc->preserve_arf_as_gld = 0; @@ -1690,8 +1696,10 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, int frame_target, } else { // For very small rate targets where the fractional adjustment // may be tiny make sure there is at least a minimum range. - const int tol_low = (cpi->sf.recode_tolerance_low * frame_target) / 100; - const int tol_high = (cpi->sf.recode_tolerance_high * frame_target) / 100; + const int tol_low = + (int)(((int64_t)cpi->sf.recode_tolerance_low * frame_target) / 100); + const int tol_high = + (int)(((int64_t)cpi->sf.recode_tolerance_high * frame_target) / 100); *frame_under_shoot_limit = VPXMAX(frame_target - tol_low - 100, 0); *frame_over_shoot_limit = VPXMIN(frame_target + tol_high + 100, cpi->rc.max_frame_bandwidth); @@ -1706,9 +1714,16 @@ void vp9_rc_set_frame_target(VP9_COMP *cpi, int target) { // Modify frame size target when down-scaling. if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && - rc->frame_size_selector != UNSCALED) + rc->frame_size_selector != UNSCALED) { rc->this_frame_target = (int)(rc->this_frame_target * rate_thresh_mult[rc->frame_size_selector]); + } + +#if CONFIG_RATE_CTRL + if (cpi->encode_command.use_external_target_frame_bits) { + rc->this_frame_target = cpi->encode_command.target_frame_bits; + } +#endif // Target rate per SB64 (including partial SB64s. rc->sb64_target_rate = (int)(((int64_t)rc->this_frame_target * 64 * 64) / @@ -1981,6 +1996,7 @@ void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) { cpi->rc.rc_2_frame = 0; cpi->rc.rc_1_frame = 0; cpi->rc.last_avg_frame_bandwidth = cpi->rc.avg_frame_bandwidth; + cpi->rc.last_q[INTER_FRAME] = cpi->common.base_qindex; // For SVC on dropped frame when framedrop_mode != LAYER_DROP: // in this mode the whole superframe may be dropped if only a single layer // has buffer underflow (below threshold). Since this can then lead to @@ -2098,7 +2114,7 @@ void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) { vp9_cyclic_refresh_update_parameters(cpi); } -static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { +int vp9_calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { const VP9EncoderConfig *oxcf = &cpi->oxcf; const RATE_CONTROL *rc = &cpi->rc; const SVC *const svc = &cpi->svc; @@ -2147,7 +2163,7 @@ static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { return VPXMAX(min_frame_target, target); } -static int calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { +int vp9_calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { const RATE_CONTROL *rc = &cpi->rc; const VP9EncoderConfig *oxcf = &cpi->oxcf; const SVC *const svc = &cpi->svc; @@ -2253,7 +2269,7 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG); // Assumption here is that LAST_FRAME is being updated for a keyframe. // Thus no change in update flags. - target = calc_iframe_target_size_one_pass_cbr(cpi); + target = vp9_calc_iframe_target_size_one_pass_cbr(cpi); } } else { cm->frame_type = INTER_FRAME; @@ -2266,7 +2282,7 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { (svc->spatial_layer_id == 0 && cm->current_video_frame > 0) ? 0 : svc->layer_context[svc->temporal_layer_id].is_key_frame; - target = calc_pframe_target_size_one_pass_cbr(cpi); + target = vp9_calc_pframe_target_size_one_pass_cbr(cpi); } } @@ -2275,7 +2291,7 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { svc->layer_context[layer].is_key_frame == 1) { cm->frame_type = KEY_FRAME; cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG); - target = calc_iframe_target_size_one_pass_cbr(cpi); + target = vp9_calc_iframe_target_size_one_pass_cbr(cpi); } // Set the buffer idx and refresh flags for key frames in simulcast mode. // Note the buffer slot for long-term reference is set below (line 2255), @@ -2360,7 +2376,7 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { } if (svc->set_intra_only_frame) { set_intra_only_frame(cpi); - target = calc_iframe_target_size_one_pass_cbr(cpi); + target = vp9_calc_iframe_target_size_one_pass_cbr(cpi); } // Any update/change of global cyclic refresh parameters (amount/delta-qp) // should be done here, before the frame qp is selected. @@ -2371,7 +2387,8 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { if (cm->show_frame) update_buffer_level_svc_preencode(cpi); if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && svc->single_layer_svc == 1 && - svc->spatial_layer_id == svc->first_spatial_layer_to_encode) { + svc->spatial_layer_id == svc->first_spatial_layer_to_encode && + svc->temporal_layer_id == 0) { LAYER_CONTEXT *lc = NULL; cpi->resize_pending = vp9_resize_one_pass_cbr(cpi); if (cpi->resize_pending) { @@ -2385,6 +2402,11 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { cpi->resize_scale_num * lc->scaling_factor_num; lc->scaling_factor_den_resize = cpi->resize_scale_den * lc->scaling_factor_den; + // Reset rate control for all temporal layers. + lc->rc.buffer_level = lc->rc.optimal_buffer_level; + lc->rc.bits_off_target = lc->rc.optimal_buffer_level; + lc->rc.rate_correction_factors[INTER_FRAME] = + rc->rate_correction_factors[INTER_FRAME]; } // Set the size for this current temporal layer. lc = &svc->layer_context[svc->spatial_layer_id * @@ -2394,9 +2416,11 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { lc->scaling_factor_num_resize, lc->scaling_factor_den_resize, &width, &height); vp9_set_size_literal(cpi, width, height); + svc->resize_set = 1; } } else { cpi->resize_pending = 0; + svc->resize_set = 0; } } @@ -2433,13 +2457,13 @@ void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) { vp9_cyclic_refresh_update_parameters(cpi); if (frame_is_intra_only(cm)) - target = calc_iframe_target_size_one_pass_cbr(cpi); + target = vp9_calc_iframe_target_size_one_pass_cbr(cpi); else - target = calc_pframe_target_size_one_pass_cbr(cpi); + target = vp9_calc_pframe_target_size_one_pass_cbr(cpi); vp9_rc_set_frame_target(cpi, target); - if (cm->show_frame) update_buffer_level_preencode(cpi); + if (cm->show_frame) vp9_update_buffer_level_preencode(cpi); if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC) cpi->resize_pending = vp9_resize_one_pass_cbr(cpi); @@ -2657,6 +2681,7 @@ int vp9_resize_one_pass_cbr(VP9_COMP *cpi) { int min_width = (320 * 4) / 3; int min_height = (180 * 4) / 3; int down_size_on = 1; + int force_downsize_rate = 0; cpi->resize_scale_num = 1; cpi->resize_scale_den = 1; // Don't resize on key frame; reset the counters on key frame. @@ -2677,11 +2702,32 @@ int vp9_resize_one_pass_cbr(VP9_COMP *cpi) { } #endif + // Force downsize based on per-frame-bandwidth, for extreme case, + // for HD input. + if (cpi->resize_state == ORIG && cm->width * cm->height >= 1280 * 720) { + if (rc->avg_frame_bandwidth < 300000 / 30) { + resize_action = DOWN_ONEHALF; + cpi->resize_state = ONE_HALF; + force_downsize_rate = 1; + } else if (rc->avg_frame_bandwidth < 400000 / 30) { + resize_action = ONEHALFONLY_RESIZE ? DOWN_ONEHALF : DOWN_THREEFOUR; + cpi->resize_state = ONEHALFONLY_RESIZE ? ONE_HALF : THREE_QUARTER; + force_downsize_rate = 1; + } + } else if (cpi->resize_state == THREE_QUARTER && + cm->width * cm->height >= 960 * 540) { + if (rc->avg_frame_bandwidth < 300000 / 30) { + resize_action = DOWN_ONEHALF; + cpi->resize_state = ONE_HALF; + force_downsize_rate = 1; + } + } + // Resize based on average buffer underflow and QP over some window. // Ignore samples close to key frame, since QP is usually high after key. - if (cpi->rc.frames_since_key > 2 * cpi->framerate) { - const int window = (int)(4 * cpi->framerate); - cpi->resize_avg_qp += cm->base_qindex; + if (!force_downsize_rate && cpi->rc.frames_since_key > cpi->framerate) { + const int window = VPXMIN(30, (int)(2 * cpi->framerate)); + cpi->resize_avg_qp += rc->last_q[INTER_FRAME]; if (cpi->rc.buffer_level < (int)(30 * rc->optimal_buffer_level / 100)) ++cpi->resize_buffer_underflow; ++cpi->resize_count; @@ -2742,7 +2788,7 @@ int vp9_resize_one_pass_cbr(VP9_COMP *cpi) { // Reset buffer level to optimal, update target size. rc->buffer_level = rc->optimal_buffer_level; rc->bits_off_target = rc->optimal_buffer_level; - rc->this_frame_target = calc_pframe_target_size_one_pass_cbr(cpi); + rc->this_frame_target = vp9_calc_pframe_target_size_one_pass_cbr(cpi); // Get the projected qindex, based on the scaled target frame size (scaled // so target_bits_per_mb in vp9_rc_regulate_q will be correct target). target_bits_per_frame = (resize_action >= 0) @@ -2960,7 +3006,7 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) { int scene_cut_force_key_frame = 0; int num_zero_temp_sad = 0; uint64_t avg_sad_current = 0; - uint32_t min_thresh = 10000; + uint32_t min_thresh = 20000; // ~5 * 64 * 64 float thresh = 8.0f; uint32_t thresh_key = 140000; if (cpi->oxcf.speed <= 5) thresh_key = 240000; @@ -3217,7 +3263,7 @@ int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) { int tl = 0; int sl = 0; SVC *svc = &cpi->svc; - for (sl = 0; sl < svc->first_spatial_layer_to_encode; ++sl) { + for (sl = 0; sl < VPXMAX(1, svc->first_spatial_layer_to_encode); ++sl) { for (tl = 0; tl < svc->number_temporal_layers; ++tl) { const int layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers); diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.h index fa070f9be..0120f90a0 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_ratectrl.h @@ -195,7 +195,8 @@ typedef struct { int use_post_encode_drop; // External flag to enable post encode frame dropping, controlled by user. int ext_use_post_encode_drop; - + // Flag to disable CBR feature to increase Q on overshoot detection. + int disable_overshoot_maxq_cbr; int damped_adjustment[RATE_FACTOR_LEVELS]; double arf_active_best_quality_adjustment_factor; int arf_increase_active_best_quality; @@ -252,6 +253,9 @@ int vp9_rc_get_default_max_gf_interval(double framerate, int min_gf_interval); // encode_frame_to_data_rate() function. void vp9_rc_get_one_pass_vbr_params(struct VP9_COMP *cpi); void vp9_rc_get_one_pass_cbr_params(struct VP9_COMP *cpi); +int vp9_calc_pframe_target_size_one_pass_cbr(const struct VP9_COMP *cpi); +int vp9_calc_iframe_target_size_one_pass_cbr(const struct VP9_COMP *cpi); +void vp9_update_buffer_level_preencode(struct VP9_COMP *cpi); void vp9_rc_get_svc_params(struct VP9_COMP *cpi); // Post encode update of the rate control parameters based diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c index 39b99d50c..37de4e483 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c @@ -4443,6 +4443,7 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, TileDataEnc *tile_data, tmp_best_sse = total_sse; tmp_best_skippable = skippable; tmp_best_mbmode = *mi; + x->sum_y_eobs[TX_4X4] = 0; for (i = 0; i < 4; i++) { tmp_best_bmodes[i] = xd->mi[0]->bmi[i]; x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i]; @@ -4476,6 +4477,11 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, TileDataEnc *tile_data, &rate, &rate_y, &distortion, &skippable, &total_sse, (int)this_rd_thresh, seg_mvs, bsi, 0, mi_row, mi_col); if (tmp_rd == INT64_MAX) continue; + x->sum_y_eobs[TX_4X4] = 0; + for (i = 0; i < 4; i++) { + x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i]; + x->sum_y_eobs[TX_4X4] += x->plane[0].eobs[i]; + } } else { total_sse = tmp_best_sse; rate = tmp_best_rate; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_speed_features.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_speed_features.c index 7a26c4176..585c9604c 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_speed_features.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_speed_features.c @@ -621,7 +621,7 @@ static void set_rt_speed_feature_framesize_independent( // increase in encoding time. if (cpi->use_svc && svc->spatial_layer_id > 0) sf->nonrd_keyframe = 1; if (cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG && - cpi->oxcf.rc_mode == VPX_CBR) { + cpi->oxcf.rc_mode == VPX_CBR && !cpi->rc.disable_overshoot_maxq_cbr) { if (cm->width * cm->height <= 352 * 288 && !cpi->use_svc && cpi->oxcf.content != VP9E_CONTENT_SCREEN) sf->overshoot_detection_cbr_rt = RE_ENCODE_MAXQ; @@ -634,6 +634,7 @@ static void set_rt_speed_feature_framesize_independent( sf->use_compound_nonrd_pickmode = 1; } if (cm->width * cm->height > 1280 * 720) sf->cb_pred_filter_search = 1; + if (!cpi->external_resize) sf->use_source_sad = 1; } if (speed >= 6) { @@ -646,8 +647,6 @@ static void set_rt_speed_feature_framesize_independent( sf->mv.reduce_first_step_size = 1; sf->skip_encode_sb = 0; - if (!cpi->external_resize) sf->use_source_sad = 1; - if (sf->use_source_sad) { sf->adapt_partition_source_sad = 1; sf->adapt_partition_thresh = @@ -669,7 +668,7 @@ static void set_rt_speed_feature_framesize_independent( sf->base_mv_aggressive = 1; } if (cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG && - cpi->oxcf.rc_mode == VPX_CBR) + cpi->oxcf.rc_mode == VPX_CBR && !cpi->rc.disable_overshoot_maxq_cbr) sf->overshoot_detection_cbr_rt = FAST_DETECTION_MAXQ; } @@ -728,7 +727,10 @@ static void set_rt_speed_feature_framesize_independent( if (speed >= 8) { sf->adaptive_rd_thresh = 4; sf->skip_encode_sb = 1; - sf->nonrd_keyframe = 1; + if (cpi->svc.number_spatial_layers > 1 && !cpi->svc.simulcast_mode) + sf->nonrd_keyframe = 0; + else + sf->nonrd_keyframe = 1; if (!cpi->use_svc) cpi->max_copied_frame = 4; if (cpi->row_mt && cpi->oxcf.max_threads > 1) sf->adaptive_rd_thresh_row_mt = 1; @@ -787,6 +789,15 @@ static void set_rt_speed_feature_framesize_independent( if (cm->width * cm->height >= 640 * 360) sf->variance_part_thresh_mult = 2; } + // Disable split to 8x8 for low-resolution at very high Q. + // For variance partition (speed >= 6). Ignore the first few frames + // as avg_frame_qindex starts at max_q (worst_quality). + if (cm->frame_type != KEY_FRAME && cm->width * cm->height <= 320 * 240 && + sf->partition_search_type == VAR_BASED_PARTITION && + cpi->rc.avg_frame_qindex[INTER_FRAME] > 208 && + cpi->common.current_video_frame > 8) + sf->disable_16x16part_nonkey = 1; + if (sf->nonrd_use_ml_partition) sf->partition_search_type = ML_BASED_PARTITION; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c index 1466d3a2b..b6c7c74e1 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.c @@ -56,6 +56,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { svc->num_encoded_top_layer = 0; svc->simulcast_mode = 0; svc->single_layer_svc = 0; + svc->resize_set = 0; for (i = 0; i < REF_FRAMES; ++i) { svc->fb_idx_spatial_layer_id[i] = 0xff; @@ -356,6 +357,7 @@ void vp9_restore_layer_context(VP9_COMP *const cpi) { if (is_one_pass_cbr_svc(cpi) && lc->speed > 0) { cpi->oxcf.speed = lc->speed; } + cpi->loopfilter_ctrl = lc->loopfilter_ctrl; // Reset the frames_since_key and frames_to_key counters to their values // before the layer restore. Keep these defined for the stream (not layer). if (cpi->svc.number_temporal_layers > 1 || @@ -770,9 +772,7 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { if (svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF && svc->number_spatial_layers > 1 && svc->number_spatial_layers <= 3 && - svc->number_temporal_layers <= 3 && - !(svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->use_set_ref_frame_config)) + svc->number_temporal_layers <= 3) svc->simulcast_mode = 1; else svc->simulcast_mode = 0; @@ -866,8 +866,9 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { } } - // Reset the drop flags for all spatial layers, on the base layer. - if (svc->spatial_layer_id == 0) { + // Reset the drop flags for all spatial layers, on the + // first_spatial_layer_to_encode. + if (svc->spatial_layer_id == svc->first_spatial_layer_to_encode) { vp9_zero(svc->drop_spatial_layer); // TODO(jianj/marpan): Investigate why setting svc->lst/gld/alt_fb_idx // causes an issue with frame dropping and temporal layers, when the frame @@ -1261,7 +1262,7 @@ static void vp9_svc_update_ref_frame_bypass_mode(VP9_COMP *const cpi) { BufferPool *const pool = cm->buffer_pool; int i; for (i = 0; i < REF_FRAMES; i++) { - if (cm->frame_type == KEY_FRAME || + if ((cm->frame_type == KEY_FRAME && !svc->simulcast_mode) || svc->update_buffer_slot[svc->spatial_layer_id] & (1 << i)) { ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[i], cm->new_fb_idx); svc->fb_idx_spatial_layer_id[i] = svc->spatial_layer_id; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.h index 7e46500b5..b12e7e01a 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/encoder/vp9_svc_layercontext.h @@ -71,6 +71,7 @@ typedef struct { int actual_num_seg2_blocks; int counter_encode_maxq_scene_change; uint8_t speed; + int loopfilter_ctrl; } LAYER_CONTEXT; typedef struct SVC { @@ -198,6 +199,7 @@ typedef struct SVC { // Flag to indicate SVC is dynamically switched to a single layer. int single_layer_svc; + int resize_set; } SVC; struct VP9_COMP; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.cc b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.cc new file mode 100644 index 000000000..47f9f3ba3 --- /dev/null +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.cc @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2020 The WebM 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 "vp9/ratectrl_rtc.h" + +#include + +#include "vp9/encoder/vp9_encoder.h" +#include "vp9/encoder/vp9_picklpf.h" +#include "vpx/vp8cx.h" +#include "vpx/vpx_codec.h" + +namespace libvpx { + +std::unique_ptr VP9RateControlRTC::Create( + const VP9RateControlRtcConfig &cfg) { + std::unique_ptr rc_api(new (std::nothrow) + VP9RateControlRTC()); + if (!rc_api) return nullptr; + rc_api->cpi_ = static_cast(vpx_memalign(32, sizeof(*cpi_))); + if (rc_api->cpi_ == nullptr) { + return nullptr; + } + rc_api->InitRateControl(cfg); + return rc_api; +} + +void VP9RateControlRTC::InitRateControl(const VP9RateControlRtcConfig &rc_cfg) { + VP9_COMMON *cm = &cpi_->common; + VP9EncoderConfig *oxcf = &cpi_->oxcf; + RATE_CONTROL *const rc = &cpi_->rc; + cm->profile = PROFILE_0; + cm->bit_depth = VPX_BITS_8; + cm->show_frame = 1; + oxcf->rc_mode = VPX_CBR; + oxcf->pass = 0; + oxcf->aq_mode = NO_AQ; + oxcf->content = VP9E_CONTENT_DEFAULT; + oxcf->drop_frames_water_mark = 0; + + UpdateRateControl(rc_cfg); + + cpi_->use_svc = (cpi_->svc.number_spatial_layers > 1 || + cpi_->svc.number_temporal_layers > 1) + ? 1 + : 0; + + rc->rc_1_frame = 0; + rc->rc_2_frame = 0; + vp9_rc_init_minq_luts(); + vp9_rc_init(oxcf, 0, rc); + cpi_->sf.use_nonrd_pick_mode = 1; + cm->current_video_frame = 0; +} + +void VP9RateControlRTC::UpdateRateControl( + const VP9RateControlRtcConfig &rc_cfg) { + VP9_COMMON *cm = &cpi_->common; + VP9EncoderConfig *oxcf = &cpi_->oxcf; + RATE_CONTROL *const rc = &cpi_->rc; + + cm->width = rc_cfg.width; + cm->height = rc_cfg.height; + oxcf->width = rc_cfg.width; + oxcf->height = rc_cfg.height; + oxcf->worst_allowed_q = vp9_quantizer_to_qindex(rc_cfg.max_quantizer); + oxcf->best_allowed_q = vp9_quantizer_to_qindex(rc_cfg.min_quantizer); + rc->worst_quality = oxcf->worst_allowed_q; + rc->best_quality = oxcf->best_allowed_q; + oxcf->target_bandwidth = 1000 * rc_cfg.target_bandwidth; + oxcf->starting_buffer_level_ms = rc_cfg.buf_initial_sz; + oxcf->optimal_buffer_level_ms = rc_cfg.buf_optimal_sz; + oxcf->maximum_buffer_size_ms = rc_cfg.buf_sz; + oxcf->under_shoot_pct = rc_cfg.undershoot_pct; + oxcf->over_shoot_pct = rc_cfg.overshoot_pct; + oxcf->ss_number_layers = rc_cfg.ss_number_layers; + oxcf->ts_number_layers = rc_cfg.ts_number_layers; + oxcf->temporal_layering_mode = (VP9E_TEMPORAL_LAYERING_MODE)( + (rc_cfg.ts_number_layers > 1) ? rc_cfg.ts_number_layers : 0); + + cpi_->oxcf.rc_max_intra_bitrate_pct = rc_cfg.max_intra_bitrate_pct; + cpi_->framerate = rc_cfg.framerate; + cpi_->svc.number_spatial_layers = rc_cfg.ss_number_layers; + cpi_->svc.number_temporal_layers = rc_cfg.ts_number_layers; + + for (int sl = 0; sl < cpi_->svc.number_spatial_layers; ++sl) { + for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) { + const int layer = + LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers); + LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer]; + RATE_CONTROL *const lrc = &lc->rc; + oxcf->layer_target_bitrate[layer] = + 1000 * rc_cfg.layer_target_bitrate[layer]; + lrc->worst_quality = + vp9_quantizer_to_qindex(rc_cfg.max_quantizers[layer]); + lrc->best_quality = vp9_quantizer_to_qindex(rc_cfg.min_quantizers[layer]); + lc->scaling_factor_num = rc_cfg.scaling_factor_num[sl]; + lc->scaling_factor_den = rc_cfg.scaling_factor_den[sl]; + oxcf->ts_rate_decimator[tl] = rc_cfg.ts_rate_decimator[tl]; + } + } + vp9_set_rc_buffer_sizes(cpi_); + vp9_new_framerate(cpi_, cpi_->framerate); + if (cpi_->svc.number_temporal_layers > 1 || + cpi_->svc.number_spatial_layers > 1) { + if (cm->current_video_frame == 0) vp9_init_layer_context(cpi_); + vp9_update_layer_context_change_config(cpi_, + (int)cpi_->oxcf.target_bandwidth); + } + vp9_check_reset_rc_flag(cpi_); +} + +void VP9RateControlRTC::ComputeQP(const VP9FrameParamsQpRTC &frame_params) { + VP9_COMMON *const cm = &cpi_->common; + int width, height; + cpi_->svc.spatial_layer_id = frame_params.spatial_layer_id; + cpi_->svc.temporal_layer_id = frame_params.temporal_layer_id; + if (cpi_->svc.number_spatial_layers > 1) { + const int layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id, + cpi_->svc.temporal_layer_id, + cpi_->svc.number_temporal_layers); + LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer]; + get_layer_resolution(cpi_->oxcf.width, cpi_->oxcf.height, + lc->scaling_factor_num, lc->scaling_factor_den, &width, + &height); + cm->width = width; + cm->height = height; + } + vp9_set_mb_mi(cm, cm->width, cm->height); + cm->frame_type = frame_params.frame_type; + cpi_->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0; + cpi_->sf.use_nonrd_pick_mode = 1; + if (cpi_->svc.number_spatial_layers == 1 && + cpi_->svc.number_temporal_layers == 1) { + int target; + if (frame_is_intra_only(cm)) + target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_); + else + target = vp9_calc_pframe_target_size_one_pass_cbr(cpi_); + vp9_rc_set_frame_target(cpi_, target); + vp9_update_buffer_level_preencode(cpi_); + } else { + vp9_update_temporal_layer_framerate(cpi_); + vp9_restore_layer_context(cpi_); + vp9_rc_get_svc_params(cpi_); + } + int bottom_index, top_index; + cpi_->common.base_qindex = + vp9_rc_pick_q_and_bounds(cpi_, &bottom_index, &top_index); +} + +int VP9RateControlRTC::GetQP() const { return cpi_->common.base_qindex; } + +int VP9RateControlRTC::GetLoopfilterLevel() const { + struct loopfilter *const lf = &cpi_->common.lf; + vp9_pick_filter_level(nullptr, cpi_, LPF_PICK_FROM_Q); + return lf->filter_level; +} + +void VP9RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) { + vp9_rc_postencode_update(cpi_, encoded_frame_size); + if (cpi_->svc.number_spatial_layers > 1 || + cpi_->svc.number_temporal_layers > 1) + vp9_save_layer_context(cpi_); + cpi_->common.current_video_frame++; +} + +} // namespace libvpx diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h new file mode 100644 index 000000000..72ea40fd6 --- /dev/null +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2020 The WebM 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. + */ + +#ifndef VPX_VP9_RATECTRL_RTC_H_ +#define VPX_VP9_RATECTRL_RTC_H_ + +#include +#include + +#include "vp9/common/vp9_entropymode.h" +#include "vp9/common/vp9_enums.h" +#include "vp9/common/vp9_onyxc_int.h" +#include "vp9/vp9_iface_common.h" +#include "vp9/encoder/vp9_encoder.h" +#include "vp9/encoder/vp9_firstpass.h" +#include "vp9/vp9_cx_iface.h" +#include "vpx_mem/vpx_mem.h" + +namespace libvpx { + +struct VP9RateControlRtcConfig { + int width; + int height; + // 0-63 + int max_quantizer; + int min_quantizer; + int64_t target_bandwidth; + int64_t buf_initial_sz; + int64_t buf_optimal_sz; + int64_t buf_sz; + int undershoot_pct; + int overshoot_pct; + int max_intra_bitrate_pct; + double framerate; + // Number of spatial layers + int ss_number_layers; + // Number of temporal layers + int ts_number_layers; + int max_quantizers[VPX_MAX_LAYERS]; + int min_quantizers[VPX_MAX_LAYERS]; + int scaling_factor_num[VPX_SS_MAX_LAYERS]; + int scaling_factor_den[VPX_SS_MAX_LAYERS]; + int layer_target_bitrate[VPX_MAX_LAYERS]; + int ts_rate_decimator[VPX_TS_MAX_LAYERS]; +}; + +struct VP9FrameParamsQpRTC { + FRAME_TYPE frame_type; + int spatial_layer_id; + int temporal_layer_id; +}; + +// This interface allows using VP9 real-time rate control without initializing +// the encoder. To use this interface, you need to link with libvp9rc.a. +// +// #include "vp9/ratectrl_rtc.h" +// VP9RateControlRTC rc_api; +// VP9RateControlRtcConfig cfg; +// VP9FrameParamsQpRTC frame_params; +// +// YourFunctionToInitializeConfig(cfg); +// rc_api.InitRateControl(cfg); +// // start encoding +// while (frame_to_encode) { +// if (config_changed) +// rc_api.UpdateRateControl(cfg); +// YourFunctionToFillFrameParams(frame_params); +// rc_api.ComputeQP(frame_params); +// YourFunctionToUseQP(rc_api.GetQP()); +// YourFunctionToUseLoopfilter(rc_api.GetLoopfilterLevel()); +// // After encoding +// rc_api.PostEncode(encoded_frame_size); +// } +class VP9RateControlRTC { + public: + static std::unique_ptr Create( + const VP9RateControlRtcConfig &cfg); + ~VP9RateControlRTC() { + if (cpi_) { + for (int sl = 0; sl < cpi_->svc.number_spatial_layers; sl++) { + for (int tl = 0; tl < cpi_->svc.number_temporal_layers; tl++) { + int layer = LAYER_IDS_TO_IDX(sl, tl, cpi_->oxcf.ts_number_layers); + LAYER_CONTEXT *const lc = &cpi_->svc.layer_context[layer]; + vpx_free(lc->map); + vpx_free(lc->last_coded_q_map); + vpx_free(lc->consec_zero_mv); + } + } + vpx_free(cpi_); + } + } + + void UpdateRateControl(const VP9RateControlRtcConfig &rc_cfg); + // GetQP() needs to be called after ComputeQP() to get the latest QP + int GetQP() const; + int GetLoopfilterLevel() const; + void ComputeQP(const VP9FrameParamsQpRTC &frame_params); + // Feedback to rate control with the size of current encoded frame + void PostEncodeUpdate(uint64_t encoded_frame_size); + + private: + VP9RateControlRTC() {} + void InitRateControl(const VP9RateControlRtcConfig &cfg); + VP9_COMP *cpi_; +}; + +} // namespace libvpx + +#endif // VPX_VP9_RATECTRL_RTC_H_ diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/simple_encode.cc b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/simple_encode.cc index c417a2589..afda6e203 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/simple_encode.cc +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/simple_encode.cc @@ -90,12 +90,20 @@ static int img_read(vpx_image_t *img, FILE *file) { return 1; } +// Assume every config in VP9EncoderConfig is less than 100 characters. +#define ENCODE_CONFIG_BUF_SIZE 100 +struct EncodeConfig { + char name[ENCODE_CONFIG_BUF_SIZE]; + char value[ENCODE_CONFIG_BUF_SIZE]; +}; + class SimpleEncode::EncodeImpl { public: VP9_COMP *cpi; vpx_img_fmt_t img_fmt; vpx_image_t tmp_img; std::vector first_pass_stats; + std::vector encode_config_list; }; static VP9_COMP *init_encoder(const VP9EncoderConfig *oxcf, @@ -167,7 +175,8 @@ static RefFrameType mv_ref_frame_to_ref_frame_type( static void update_motion_vector_info( const MOTION_VECTOR_INFO *input_motion_vector_info, const int num_rows_4x4, - const int num_cols_4x4, MotionVectorInfo *output_motion_vector_info) { + const int num_cols_4x4, MotionVectorInfo *output_motion_vector_info, + int motion_vector_scale) { const int num_units_4x4 = num_rows_4x4 * num_cols_4x4; for (int i = 0; i < num_units_4x4; ++i) { const MV_REFERENCE_FRAME *in_ref_frame = @@ -185,16 +194,34 @@ static void update_motion_vector_info( mv_ref_frame_to_ref_frame_type(in_ref_frame[1]); output_motion_vector_info[i].mv_row[0] = (double)input_motion_vector_info[i].mv[0].as_mv.row / - kMotionVectorPrecision; + motion_vector_scale; output_motion_vector_info[i].mv_column[0] = (double)input_motion_vector_info[i].mv[0].as_mv.col / - kMotionVectorPrecision; + motion_vector_scale; output_motion_vector_info[i].mv_row[1] = (double)input_motion_vector_info[i].mv[1].as_mv.row / - kMotionVectorPrecision; + motion_vector_scale; output_motion_vector_info[i].mv_column[1] = (double)input_motion_vector_info[i].mv[1].as_mv.col / - kMotionVectorPrecision; + motion_vector_scale; + } +} + +static void update_tpl_stats_info(const TplDepStats *input_tpl_stats_info, + const int show_frame_count, + TplStatsInfo *output_tpl_stats_info) { + int frame_idx; + for (frame_idx = 0; frame_idx < show_frame_count; ++frame_idx) { + output_tpl_stats_info[frame_idx].intra_cost = + input_tpl_stats_info[frame_idx].intra_cost; + output_tpl_stats_info[frame_idx].inter_cost = + input_tpl_stats_info[frame_idx].inter_cost; + output_tpl_stats_info[frame_idx].mc_flow = + input_tpl_stats_info[frame_idx].mc_flow; + output_tpl_stats_info[frame_idx].mc_dep_cost = + input_tpl_stats_info[frame_idx].mc_dep_cost; + output_tpl_stats_info[frame_idx].mc_ref_cost = + input_tpl_stats_info[frame_idx].mc_ref_cost; } } @@ -471,12 +498,13 @@ static bool init_encode_frame_result(EncodeFrameResult *encode_frame_result, encode_frame_result->coding_data.reset( new (std::nothrow) uint8_t[max_coding_data_byte_size]); - encode_frame_result->num_rows_4x4 = get_num_unit_4x4(frame_width); - encode_frame_result->num_cols_4x4 = get_num_unit_4x4(frame_height); + encode_frame_result->num_rows_4x4 = get_num_unit_4x4(frame_height); + encode_frame_result->num_cols_4x4 = get_num_unit_4x4(frame_width); encode_frame_result->partition_info.resize(encode_frame_result->num_rows_4x4 * encode_frame_result->num_cols_4x4); encode_frame_result->motion_vector_info.resize( encode_frame_result->num_rows_4x4 * encode_frame_result->num_cols_4x4); + encode_frame_result->tpl_stats_info.resize(MAX_LAG_BUFFERS); if (encode_frame_result->coding_data.get() == nullptr) { return false; @@ -485,8 +513,20 @@ static bool init_encode_frame_result(EncodeFrameResult *encode_frame_result, frame_height, img_fmt); } +static void encode_frame_result_update_rq_history( + const RATE_QINDEX_HISTORY *rq_history, + EncodeFrameResult *encode_frame_result) { + encode_frame_result->recode_count = rq_history->recode_count; + for (int i = 0; i < encode_frame_result->recode_count; ++i) { + const int q_index = rq_history->q_index_history[i]; + const int rate = rq_history->rate_history[i]; + encode_frame_result->q_index_history.push_back(q_index); + encode_frame_result->rate_history.push_back(rate); + } +} + static void update_encode_frame_result( - EncodeFrameResult *encode_frame_result, + EncodeFrameResult *encode_frame_result, const int show_frame_count, const ENCODE_FRAME_RESULT *encode_frame_info) { encode_frame_result->coding_data_bit_size = encode_frame_result->coding_data_byte_size * 8; @@ -511,9 +551,16 @@ static void update_encode_frame_result( update_motion_vector_info(encode_frame_info->motion_vector_info, encode_frame_result->num_rows_4x4, encode_frame_result->num_cols_4x4, - &encode_frame_result->motion_vector_info[0]); + &encode_frame_result->motion_vector_info[0], + kMotionVectorSubPixelPrecision); update_frame_counts(&encode_frame_info->frame_counts, &encode_frame_result->frame_counts); + if (encode_frame_result->frame_type == kFrameTypeAltRef) { + update_tpl_stats_info(encode_frame_info->tpl_stats_info, show_frame_count, + &encode_frame_result->tpl_stats_info[0]); + } + encode_frame_result_update_rq_history(&encode_frame_info->rq_history, + encode_frame_result); } static void IncreaseGroupOfPictureIndex(GroupOfPicture *group_of_picture) { @@ -612,6 +659,9 @@ static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref, group_of_picture->show_frame_count = coding_frame_count - use_alt_ref; group_of_picture->start_show_index = first_show_idx; group_of_picture->start_coding_index = start_coding_index; + group_of_picture->first_is_key_frame = first_is_key_frame; + group_of_picture->use_alt_ref = use_alt_ref; + group_of_picture->last_gop_use_alt_ref = last_gop_use_alt_ref; // We need to make a copy of start reference frame info because we // use it to simulate the ref frame update. @@ -692,6 +742,50 @@ static void UpdateGroupOfPicture(const VP9_COMP *cpi, int start_coding_index, start_ref_frame_info, group_of_picture); } +#define SET_STRUCT_VALUE(config, structure, ret, field) \ + if (strcmp(config.name, #field) == 0) { \ + structure->field = atoi(config.value); \ + ret = 1; \ + } + +static void UpdateEncodeConfig(const EncodeConfig &config, + VP9EncoderConfig *oxcf) { + int ret = 0; + SET_STRUCT_VALUE(config, oxcf, ret, key_freq); + SET_STRUCT_VALUE(config, oxcf, ret, two_pass_vbrmin_section); + SET_STRUCT_VALUE(config, oxcf, ret, two_pass_vbrmax_section); + SET_STRUCT_VALUE(config, oxcf, ret, under_shoot_pct); + SET_STRUCT_VALUE(config, oxcf, ret, over_shoot_pct); + SET_STRUCT_VALUE(config, oxcf, ret, max_threads); + SET_STRUCT_VALUE(config, oxcf, ret, frame_parallel_decoding_mode); + SET_STRUCT_VALUE(config, oxcf, ret, tile_columns); + SET_STRUCT_VALUE(config, oxcf, ret, arnr_max_frames); + SET_STRUCT_VALUE(config, oxcf, ret, arnr_strength); + SET_STRUCT_VALUE(config, oxcf, ret, lag_in_frames); + SET_STRUCT_VALUE(config, oxcf, ret, encode_breakout); + SET_STRUCT_VALUE(config, oxcf, ret, enable_tpl_model); + SET_STRUCT_VALUE(config, oxcf, ret, enable_auto_arf); + if (ret == 0) { + fprintf(stderr, "Ignored unsupported encode_config %s\n", config.name); + } +} + +static VP9EncoderConfig GetEncodeConfig( + int frame_width, int frame_height, vpx_rational_t frame_rate, + int target_bitrate, int encode_speed, vpx_enc_pass enc_pass, + const std::vector &encode_config_list) { + VP9EncoderConfig oxcf = + vp9_get_encoder_config(frame_width, frame_height, frame_rate, + target_bitrate, encode_speed, enc_pass); + for (const auto &config : encode_config_list) { + UpdateEncodeConfig(config, &oxcf); + } + if (enc_pass == VPX_RC_FIRST_PASS) { + oxcf.lag_in_frames = 0; + } + return oxcf; +} + SimpleEncode::SimpleEncode(int frame_width, int frame_height, int frame_rate_num, int frame_rate_den, int target_bitrate, int num_frames, @@ -703,6 +797,7 @@ SimpleEncode::SimpleEncode(int frame_width, int frame_height, frame_rate_den_ = frame_rate_den; target_bitrate_ = target_bitrate; num_frames_ = num_frames; + encode_speed_ = 0; frame_coding_index_ = 0; show_frame_count_ = 0; @@ -724,16 +819,55 @@ SimpleEncode::SimpleEncode(int frame_width, int frame_height, InitRefFrameInfo(&ref_frame_info_); } +void SimpleEncode::SetEncodeSpeed(int encode_speed) { + encode_speed_ = encode_speed; +} + +StatusCode SimpleEncode::SetEncodeConfig(const char *name, const char *value) { + if (name == nullptr || value == nullptr) { + fprintf(stderr, "SetEncodeConfig: null pointer, name %p value %p\n", name, + value); + return StatusError; + } + EncodeConfig config; + snprintf(config.name, ENCODE_CONFIG_BUF_SIZE, "%s", name); + snprintf(config.value, ENCODE_CONFIG_BUF_SIZE, "%s", value); + impl_ptr_->encode_config_list.push_back(config); + return StatusOk; +} + +StatusCode SimpleEncode::DumpEncodeConfigs(int pass, FILE *fp) { + if (fp == nullptr) { + fprintf(stderr, "DumpEncodeConfigs: null pointer, fp %p\n", fp); + return StatusError; + } + vpx_enc_pass enc_pass; + if (pass == 1) { + enc_pass = VPX_RC_FIRST_PASS; + } else { + enc_pass = VPX_RC_LAST_PASS; + } + const vpx_rational_t frame_rate = + make_vpx_rational(frame_rate_num_, frame_rate_den_); + const VP9EncoderConfig oxcf = + GetEncodeConfig(frame_width_, frame_height_, frame_rate, target_bitrate_, + encode_speed_, enc_pass, impl_ptr_->encode_config_list); + vp9_dump_encoder_config(&oxcf, fp); + return StatusOk; +} + void SimpleEncode::ComputeFirstPassStats() { vpx_rational_t frame_rate = make_vpx_rational(frame_rate_num_, frame_rate_den_); - const VP9EncoderConfig oxcf = - vp9_get_encoder_config(frame_width_, frame_height_, frame_rate, - target_bitrate_, VPX_RC_FIRST_PASS); + const VP9EncoderConfig oxcf = GetEncodeConfig( + frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, + VPX_RC_FIRST_PASS, impl_ptr_->encode_config_list); VP9_COMP *cpi = init_encoder(&oxcf, impl_ptr_->img_fmt); struct lookahead_ctx *lookahead = cpi->lookahead; int i; int use_highbitdepth = 0; + const int num_rows_16x16 = get_num_unit_16x16(frame_height_); + const int num_cols_16x16 = get_num_unit_16x16(frame_width_); #if CONFIG_VP9_HIGHBITDEPTH use_highbitdepth = cpi->common.use_highbitdepth; #endif @@ -766,6 +900,12 @@ void SimpleEncode::ComputeFirstPassStats() { // vp9_get_compressed_data only generates first pass stats not // compresses data assert(size == 0); + // Get vp9 first pass motion vector info. + std::vector mv_info(num_rows_16x16 * num_cols_16x16); + update_motion_vector_info(cpi->fp_motion_vector_info, num_rows_16x16, + num_cols_16x16, mv_info.data(), + kMotionVectorFullPixelPrecision); + fp_motion_vector_info_.push_back(mv_info); } impl_ptr_->first_pass_stats.push_back(vp9_get_frame_stats(&cpi->twopass)); } @@ -776,6 +916,9 @@ void SimpleEncode::ComputeFirstPassStats() { free_encoder(cpi); rewind(in_file_); vpx_img_free(&img); + + // Generate key_frame_map based on impl_ptr_->first_pass_stats. + key_frame_map_ = ComputeKeyFrameMap(); } std::vector> SimpleEncode::ObserveFirstPassStats() { @@ -800,9 +943,44 @@ std::vector> SimpleEncode::ObserveFirstPassStats() { return output_stats; } -void SimpleEncode::SetExternalGroupOfPicture( - std::vector external_arf_indexes) { - external_arf_indexes_ = external_arf_indexes; +std::vector> +SimpleEncode::ObserveFirstPassMotionVectors() { + return fp_motion_vector_info_; +} + +void SimpleEncode::SetExternalGroupOfPicturesMap(int *gop_map, + int gop_map_size) { + for (int i = 0; i < gop_map_size; ++i) { + gop_map_.push_back(gop_map[i]); + } + // The following will check and modify gop_map_ to make sure the + // gop_map_ satisfies the constraints. + // 1) Each key frame position should be at the start of a gop. + // 2) The last gop should not use an alt ref. + assert(gop_map_.size() == key_frame_map_.size()); + int last_gop_start = 0; + for (int i = 0; static_cast(i) < gop_map_.size(); ++i) { + if (key_frame_map_[i] == 1 && gop_map_[i] == 0) { + fprintf(stderr, "Add an extra gop start at show_idx %d\n", i); + // Insert a gop start at key frame location. + gop_map_[i] |= kGopMapFlagStart; + gop_map_[i] |= kGopMapFlagUseAltRef; + } + if (gop_map_[i] & kGopMapFlagStart) { + last_gop_start = i; + } + } + if (gop_map_[last_gop_start] & kGopMapFlagUseAltRef) { + fprintf(stderr, + "Last group of pictures starting at show_idx %d shouldn't use alt " + "ref\n", + last_gop_start); + gop_map_[last_gop_start] &= ~kGopMapFlagUseAltRef; + } +} + +std::vector SimpleEncode::ObserveExternalGroupOfPicturesMap() { + return gop_map_; } template @@ -813,13 +991,40 @@ T *GetVectorData(const std::vector &v) { return const_cast(v.data()); } +static GOP_COMMAND GetGopCommand(const std::vector &gop_map, + int start_show_index) { + GOP_COMMAND gop_command; + if (gop_map.size() > 0) { + assert(static_cast(start_show_index) < gop_map.size()); + assert((gop_map[start_show_index] & kGopMapFlagStart) != 0); + int end_show_index = start_show_index + 1; + // gop_map[end_show_index] & kGopMapFlagStart == 0 means this is + // the start of a gop. + while (static_cast(end_show_index) < gop_map.size() && + (gop_map[end_show_index] & kGopMapFlagStart) == 0) { + ++end_show_index; + } + const int show_frame_count = end_show_index - start_show_index; + int use_alt_ref = (gop_map[start_show_index] & kGopMapFlagUseAltRef) != 0; + if (static_cast(end_show_index) == gop_map.size()) { + // This is the last gop group, there must be no altref. + use_alt_ref = 0; + } + gop_command_on(&gop_command, show_frame_count, use_alt_ref); + } else { + gop_command_off(&gop_command); + } + return gop_command; +} + void SimpleEncode::StartEncode() { assert(impl_ptr_->first_pass_stats.size() > 0); vpx_rational_t frame_rate = make_vpx_rational(frame_rate_num_, frame_rate_den_); - VP9EncoderConfig oxcf = - vp9_get_encoder_config(frame_width_, frame_height_, frame_rate, - target_bitrate_, VPX_RC_LAST_PASS); + VP9EncoderConfig oxcf = GetEncodeConfig( + frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, + VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); + vpx_fixed_buf_t stats; stats.buf = GetVectorData(impl_ptr_->first_pass_stats); stats.sz = sizeof(impl_ptr_->first_pass_stats[0]) * @@ -834,11 +1039,10 @@ void SimpleEncode::StartEncode() { frame_coding_index_ = 0; show_frame_count_ = 0; - encode_command_set_external_arf_indexes(&impl_ptr_->cpi->encode_command, - GetVectorData(external_arf_indexes_)); - UpdateKeyFrameGroup(show_frame_count_); + const GOP_COMMAND gop_command = GetGopCommand(gop_map_, show_frame_count_); + encode_command_set_gop_command(&impl_ptr_->cpi->encode_command, gop_command); UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, &group_of_picture_); rewind(in_file_); @@ -914,6 +1118,9 @@ void SimpleEncode::PostUpdateState( IncreaseGroupOfPictureIndex(&group_of_picture_); if (IsGroupOfPictureFinished(group_of_picture_)) { + const GOP_COMMAND gop_command = GetGopCommand(gop_map_, show_frame_count_); + encode_command_set_gop_command(&impl_ptr_->cpi->encode_command, + gop_command); // This function needs to be called after ref_frame_info_ is updated // properly in PostUpdateRefFrameInfo() and UpdateKeyFrameGroup(). UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, @@ -985,7 +1192,10 @@ void SimpleEncode::EncodeFrame(EncodeFrameResult *encode_frame_result) { abort(); } - update_encode_frame_result(encode_frame_result, &encode_frame_info); + const GroupOfPicture group_of_picture = this->ObserveGroupOfPicture(); + const int show_frame_count = group_of_picture.show_frame_count; + update_encode_frame_result(encode_frame_result, show_frame_count, + &encode_frame_info); PostUpdateState(*encode_frame_result); } else { // TODO(angiebird): Clean up encode_frame_result. @@ -1002,26 +1212,73 @@ void SimpleEncode::EncodeFrameWithQuantizeIndex( encode_command_reset_external_quantize_index(&impl_ptr_->cpi->encode_command); } +void SimpleEncode::EncodeFrameWithTargetFrameBits( + EncodeFrameResult *encode_frame_result, int target_frame_bits, + double percent_diff) { + encode_command_set_target_frame_bits(&impl_ptr_->cpi->encode_command, + target_frame_bits, percent_diff); + EncodeFrame(encode_frame_result); + encode_command_reset_target_frame_bits(&impl_ptr_->cpi->encode_command); +} + +static int GetCodingFrameNumFromGopMap(const std::vector &gop_map) { + int start_show_index = 0; + int coding_frame_count = 0; + while (static_cast(start_show_index) < gop_map.size()) { + const GOP_COMMAND gop_command = GetGopCommand(gop_map, start_show_index); + start_show_index += gop_command.show_frame_count; + coding_frame_count += gop_command_coding_frame_count(&gop_command); + } + assert(start_show_index == gop_map.size()); + return coding_frame_count; +} + int SimpleEncode::GetCodingFrameNum() const { - assert(impl_ptr_->first_pass_stats.size() - 1 > 0); + assert(impl_ptr_->first_pass_stats.size() > 0); + if (gop_map_.size() > 0) { + return GetCodingFrameNumFromGopMap(gop_map_); + } + // These are the default settings for now. const int multi_layer_arf = 0; const int allow_alt_ref = 1; vpx_rational_t frame_rate = make_vpx_rational(frame_rate_num_, frame_rate_den_); - const VP9EncoderConfig oxcf = - vp9_get_encoder_config(frame_width_, frame_height_, frame_rate, - target_bitrate_, VPX_RC_LAST_PASS); + const VP9EncoderConfig oxcf = GetEncodeConfig( + frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, + VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); FRAME_INFO frame_info = vp9_get_frame_info(&oxcf); FIRST_PASS_INFO first_pass_info; fps_init_first_pass_info(&first_pass_info, GetVectorData(impl_ptr_->first_pass_stats), num_frames_); - return vp9_get_coding_frame_num(external_arf_indexes_.data(), &oxcf, - &frame_info, &first_pass_info, + return vp9_get_coding_frame_num(&oxcf, &frame_info, &first_pass_info, multi_layer_arf, allow_alt_ref); } +std::vector SimpleEncode::ComputeKeyFrameMap() const { + // The last entry of first_pass_stats is the overall stats. + assert(impl_ptr_->first_pass_stats.size() == num_frames_ + 1); + vpx_rational_t frame_rate = + make_vpx_rational(frame_rate_num_, frame_rate_den_); + const VP9EncoderConfig oxcf = GetEncodeConfig( + frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, + VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); + FRAME_INFO frame_info = vp9_get_frame_info(&oxcf); + FIRST_PASS_INFO first_pass_info; + fps_init_first_pass_info(&first_pass_info, + GetVectorData(impl_ptr_->first_pass_stats), + num_frames_); + std::vector key_frame_map(num_frames_, 0); + vp9_get_key_frame_map(&oxcf, &frame_info, &first_pass_info, + GetVectorData(key_frame_map)); + return key_frame_map; +} + +std::vector SimpleEncode::ObserveKeyFrameMap() const { + return key_frame_map_; +} + uint64_t SimpleEncode::GetFramePixelCount() const { assert(frame_width_ % 2 == 0); assert(frame_height_ % 2 == 0); diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/simple_encode.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/simple_encode.h index 4221a7015..380e8118f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/simple_encode.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/simple_encode.h @@ -19,13 +19,18 @@ namespace vp9 { +enum StatusCode { + StatusOk = 0, + StatusError, +}; + // TODO(angiebird): Add description for each frame type. enum FrameType { kFrameTypeKey = 0, - kFrameTypeInter, - kFrameTypeAltRef, - kFrameTypeOverlay, - kFrameTypeGolden, + kFrameTypeInter = 1, + kFrameTypeAltRef = 2, + kFrameTypeOverlay = 3, + kFrameTypeGolden = 4, }; // TODO(angiebird): Add description for each reference frame type. @@ -39,6 +44,14 @@ enum RefFrameType { kRefFrameTypeNone = -1, }; +enum GopMapFlag { + kGopMapFlagStart = + 1 << 0, // Indicate this location is the start of a group of pictures. + kGopMapFlagUseAltRef = + 1 << 1, // Indicate this group of pictures will use an alt ref. Only set + // this flag when kGopMapFlagStart is set. +}; + // The frame is split to 4x4 blocks. // This structure contains the information of each 4x4 block. struct PartitionInfo { @@ -50,9 +63,12 @@ struct PartitionInfo { int height; // prediction block height }; -constexpr int kMotionVectorPrecision = 8; +constexpr int kMotionVectorSubPixelPrecision = 8; +constexpr int kMotionVectorFullPixelPrecision = 1; -// The frame is split to 4x4 blocks. +// In the first pass. The frame is split to 16x16 blocks. +// This structure contains the information of each 16x16 block. +// In the second pass. The frame is split to 4x4 blocks. // This structure contains the information of each 4x4 block. struct MotionVectorInfo { // Number of valid motion vectors, always 0 if this block is in the key frame. @@ -60,8 +76,8 @@ struct MotionVectorInfo { int mv_count; // The reference frame for motion vectors. If the second motion vector does // not exist (mv_count = 1), the reference frame is kNoneRefFrame. - // Otherwise, the reference frame is either kLastFrame, or kGoldenFrame, - // or kAltRefFrame. + // Otherwise, the reference frame is either kRefFrameTypeLast, or + // kRefFrameTypePast, or kRefFrameTypeFuture. RefFrameType ref_frame[2]; // The row offset of motion vectors in the unit of pixel. // If the second motion vector does not exist, the value is 0. @@ -71,6 +87,24 @@ struct MotionVectorInfo { double mv_column[2]; }; +// Accumulated tpl stats of all blocks in one frame. +// For each frame, the tpl stats are computed per 32x32 block. +struct TplStatsInfo { + // Intra complexity: the sum of absolute transform difference (SATD) of + // intra predicted residuals. + int64_t intra_cost; + // Inter complexity: the SATD of inter predicted residuals. + int64_t inter_cost; + // Motion compensated information flow. It measures how much information + // is propagated from the current frame to other frames. + int64_t mc_flow; + // Motion compensated dependency cost. It equals to its own intra_cost + // plus the mc_flow. + int64_t mc_dep_cost; + // Motion compensated reference cost. + int64_t mc_ref_cost; +}; + struct RefFrameInfo { int coding_indexes[kRefFrameTypeMax]; @@ -237,7 +271,7 @@ struct EncodeFrameResult { std::vector partition_info; // A vector of the motion vector information of the frame. // The number of elements is |num_rows_4x4| * |num_cols_4x4|. - // The frame is divided 4x4 blocks of |num_rows_4x4| rows and + // The frame is divided into 4x4 blocks of |num_rows_4x4| rows and // |num_cols_4x4| columns. // Each 4x4 block contains 0 motion vector if this is an intra predicted // frame (for example, the key frame). If the frame is inter predicted, @@ -245,7 +279,25 @@ struct EncodeFrameResult { // Similar to partition info, all 4x4 blocks inside the same partition block // share the same motion vector information. std::vector motion_vector_info; + // A vector of the tpl stats information. + // The tpl stats measure the complexity of a frame, as well as the + // informatioin propagated along the motion trajactory between frames, in + // the reference frame structure. + // The tpl stats could be used as a more accurate spatial and temporal + // complexity measure in addition to the first pass stats. + // The vector contains tpl stats for all show frames in a GOP. + // The tpl stats stored in the vector is according to the encoding order. + // For example, suppose there are N show frames for the current GOP. + // Then tpl_stats_info[0] stores the information of the first frame to be + // encoded for this GOP, i.e, the AltRef frame. + std::vector tpl_stats_info; ImageBuffer coded_frame; + + // recode_count, q_index_history and rate_history are only available when + // EncodeFrameWithTargetFrameBits() is used. + int recode_count; + std::vector q_index_history; + std::vector rate_history; }; struct GroupOfPicture { @@ -255,6 +307,7 @@ struct GroupOfPicture { // triggered when the coded frame is the last one in the previous group of // pictures. std::vector encode_frame_list; + // Indicates the index of the next coding frame in encode_frame_list. // In other words, EncodeFrameInfo of the next coding frame can be // obtained with encode_frame_list[next_encode_frame_index]. @@ -263,13 +316,25 @@ struct GroupOfPicture { // will be increased after each EncodeFrame()/EncodeFrameWithQuantizeIndex() // call. int next_encode_frame_index; + // Number of show frames in this group of pictures. int show_frame_count; + // The show index/timestamp of the earliest show frame in the group of // pictures. int start_show_index; - // The coding index of the first coding frame in the group of picture. + + // The coding index of the first coding frame in the group of pictures. int start_coding_index; + + // Indicates whether this group of pictures starts with a key frame. + int first_is_key_frame; + + // Indicates whether this group of pictures uses an alt ref. + int use_alt_ref; + + // Indicates whether previous group of pictures used an alt ref. + int last_gop_use_alt_ref; }; class SimpleEncode { @@ -283,8 +348,44 @@ class SimpleEncode { SimpleEncode(SimpleEncode &) = delete; SimpleEncode &operator=(const SimpleEncode &) = delete; - // Makes encoder compute the first pass stats and store it internally for - // future encode. + // Adjusts the encoder's coding speed. + // If this function is not called, the encoder will use default encode_speed + // 0. Call this function before ComputeFirstPassStats() if needed. + // The encode_speed is equivalent to --cpu-used of the vpxenc command. + // The encode_speed's range should be [0, 9]. + // Setting the encode_speed to a higher level will yield faster coding + // at the cost of lower compression efficiency. + void SetEncodeSpeed(int encode_speed); + + // Set encoder config + // The following configs in VP9EncoderConfig are allowed to change in this + // function. See https://ffmpeg.org/ffmpeg-codecs.html#libvpx for each + // config's meaning. + // Configs in VP9EncoderConfig: Equivalent configs in ffmpeg: + // 1 key_freq -g + // 2 two_pass_vbrmin_section -minrate * 100LL / bit_rate + // 3 two_pass_vbrmax_section -maxrate * 100LL / bit_rate + // 4 under_shoot_pct -undershoot-pct + // 5 over_shoot_pct -overshoot-pct + // 6 max_threads -threads + // 7 frame_parallel_decoding_mode -frame-parallel + // 8 tile_column -tile-columns + // 9 arnr_max_frames -arnr-maxframes + // 10 arnr_strength -arnr-strength + // 11 lag_in_frames -rc_lookahead + // 12 encode_breakout -static-thresh + // 13 enable_tpl_model -enable-tpl + // 14 enable_auto_arf -auto-alt-ref + StatusCode SetEncodeConfig(const char *name, const char *value); + + // A debug function that dumps configs from VP9EncoderConfig + // pass = 1: first pass, pass = 2: second pass + // fp: file pointer for dumping config + StatusCode DumpEncodeConfigs(int pass, FILE *fp); + + // Makes encoder compute the first pass stats and store it at + // impl_ptr_->first_pass_stats. key_frame_map_ is also computed based on the + // first pass stats. void ComputeFirstPassStats(); // Outputs the first pass stats represented by a 2-D vector. @@ -293,13 +394,38 @@ class SimpleEncode { // values. For details, please check FIRSTPASS_STATS in vp9_firstpass.h std::vector> ObserveFirstPassStats(); - // Sets arf indexes for the video from external input. - // The arf index determines whether a frame is arf or not. - // Therefore it also determines the group of picture size. - // If set, VP9 will use the external arf index to make decision. + // Outputs the first pass motion vectors represented by a 2-D vector. + // One can use the frame index at first dimension to retrieve the mvs for + // each video frame. The frame is divided into 16x16 blocks. The number of + // elements is round_up(|num_rows_4x4| / 4) * round_up(|num_cols_4x4| / 4). + std::vector> ObserveFirstPassMotionVectors(); + + // Ouputs a copy of key_frame_map_, a binary vector with size equal to the + // number of show frames in the video. For each entry in the vector, 1 + // indicates the position is a key frame and 0 indicates it's not a key frame. + // This function should be called after ComputeFirstPassStats() + std::vector ObserveKeyFrameMap() const; + + // Sets group of pictures map for coding the entire video. + // Each entry in the gop_map corresponds to a show frame in the video. + // Therefore, the size of gop_map should equal to the number of show frames in + // the entire video. + // If a given entry's kGopMapFlagStart is set, it means this is the start of a + // gop. Once kGopMapFlagStart is set, one can set kGopMapFlagUseAltRef to + // indicate whether this gop use altref. + // If a given entry is zero, it means it's in the middle of a gop. // This function should be called only once after ComputeFirstPassStats(), // before StartEncode(). - void SetExternalGroupOfPicture(std::vector external_arf_indexes); + // This API will check and modify the gop_map to satisfy the following + // constraints. + // 1) Each key frame position should be at the start of a gop. + // 2) The last gop should not use an alt ref. + void SetExternalGroupOfPicturesMap(int *gop_map, int gop_map_size); + + // Observe the group of pictures map set through + // SetExternalGroupOfPicturesMap(). This function should be called after + // SetExternalGroupOfPicturesMap(). + std::vector ObserveExternalGroupOfPicturesMap(); // Initializes the encoder for actual encoding. // This function should be called after ComputeFirstPassStats(). @@ -332,6 +458,17 @@ class SimpleEncode { void EncodeFrameWithQuantizeIndex(EncodeFrameResult *encode_frame_result, int quantize_index); + // Encode a frame with target frame bits usage. + // The encoder will find a quantize index to make the actual frame bits usage + // match the target. EncodeFrameWithTargetFrameBits() will recode the frame + // up to 7 times to find a q_index to make the actual_frame_bits satisfy the + // following inequality. |actual_frame_bits - target_frame_bits| * 100 / + // target_frame_bits + // <= percent_diff. + void EncodeFrameWithTargetFrameBits(EncodeFrameResult *encode_frame_result, + int target_frame_bits, + double percent_diff); + // Gets the number of coding frames for the video. The coding frames include // show frame and no show frame. // This function should be called after ComputeFirstPassStats(). @@ -341,6 +478,12 @@ class SimpleEncode { uint64_t GetFramePixelCount() const; private: + // Compute the key frame locations of the video based on first pass stats. + // The results are returned as a binary vector with 1s indicating keyframes + // and 0s indicating non keyframes. + // It has to be called after impl_ptr_->first_pass_stats is computed. + std::vector ComputeKeyFrameMap() const; + // Updates key_frame_group_size_, reset key_frame_group_index_ and init // ref_frame_info_. void UpdateKeyFrameGroup(int key_frame_show_index); @@ -358,12 +501,14 @@ class SimpleEncode { int frame_rate_den_; int target_bitrate_; int num_frames_; + int encode_speed_; std::FILE *in_file_; std::FILE *out_file_; std::unique_ptr impl_ptr_; - std::vector external_arf_indexes_; + std::vector key_frame_map_; + std::vector gop_map_; GroupOfPicture group_of_picture_; // The key frame group size includes one key frame plus the number of @@ -387,6 +532,17 @@ class SimpleEncode { // frame appears? // Reference frames info of the to-be-coded frame. RefFrameInfo ref_frame_info_; + + // A 2-D vector of motion vector information of the frame collected + // from the first pass. The first dimension is the frame index. + // Each frame is divided into 16x16 blocks. The number of elements is + // round_up(|num_rows_4x4| / 4) * round_up(|num_cols_4x4| / 4). + // Each 16x16 block contains 0 motion vector if this is an intra predicted + // frame (for example, the key frame). If the frame is inter predicted, + // each 16x16 block contains either 1 or 2 motion vectors. + // The first motion vector is always from the LAST_FRAME. + // The second motion vector is always from the GOLDEN_FRAME. + std::vector> fp_motion_vector_info_; }; } // namespace vp9 diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c index 2ca2114ec..a73683dfe 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c @@ -13,6 +13,7 @@ #include "./vpx_config.h" #include "vpx/vpx_encoder.h" +#include "vpx/vpx_ext_ratectrl.h" #include "vpx_dsp/psnr.h" #include "vpx_ports/vpx_once.h" #include "vpx_ports/static_assert.h" @@ -355,13 +356,14 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, switch (img->fmt) { case VPX_IMG_FMT_YV12: case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_I42016: break; + case VPX_IMG_FMT_I42016: + case VPX_IMG_FMT_NV12: break; case VPX_IMG_FMT_I422: case VPX_IMG_FMT_I444: case VPX_IMG_FMT_I440: if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) { ERROR( - "Invalid image format. I422, I444, I440 images are " + "Invalid image format. I422, I444, I440, NV12 images are " "not supported in profile."); } break; @@ -391,6 +393,7 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, static int get_image_bps(const vpx_image_t *img) { switch (img->fmt) { case VPX_IMG_FMT_YV12: + case VPX_IMG_FMT_NV12: case VPX_IMG_FMT_I420: return 12; case VPX_IMG_FMT_I422: return 16; case VPX_IMG_FMT_I444: return 24; @@ -468,10 +471,11 @@ static vpx_rational64_t get_g_timebase_in_ts(vpx_rational_t g_timebase) { } static vpx_codec_err_t set_encoder_config( - VP9EncoderConfig *oxcf, const vpx_codec_enc_cfg_t *cfg, + VP9EncoderConfig *oxcf, vpx_codec_enc_cfg_t *cfg, const struct vp9_extracfg *extra_cfg) { const int is_vbr = cfg->rc_end_usage == VPX_VBR; int sl, tl; + unsigned int raw_target_rate; oxcf->profile = cfg->g_profile; oxcf->max_threads = (int)cfg->g_threads; oxcf->width = cfg->g_w; @@ -498,8 +502,14 @@ static vpx_codec_err_t set_encoder_config( cfg->g_pass == VPX_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames; oxcf->rc_mode = cfg->rc_end_usage; + raw_target_rate = + (unsigned int)((int64_t)oxcf->width * oxcf->height * oxcf->bit_depth * 3 * + oxcf->init_framerate / 1000); + // Cap target bitrate to raw rate + cfg->rc_target_bitrate = VPXMIN(raw_target_rate, cfg->rc_target_bitrate); + // Convert target bandwidth from Kbit/s to Bit/s - oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate; + oxcf->target_bandwidth = 1000 * (int64_t)cfg->rc_target_bitrate; oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct; oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct; oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct; @@ -624,7 +634,7 @@ static vpx_codec_err_t set_encoder_config( } if (get_level_index(oxcf->target_level) >= 0) config_target_level(oxcf); - // vp9_dump_encoder_config(oxcf); + // vp9_dump_encoder_config(oxcf, stderr); return VPX_CODEC_OK; } @@ -698,6 +708,10 @@ static vpx_codec_err_t ctrl_set_cpuused(vpx_codec_alg_priv_t *ctx, extra_cfg.cpu_used = CAST(VP8E_SET_CPUUSED, args); extra_cfg.cpu_used = VPXMIN(9, extra_cfg.cpu_used); extra_cfg.cpu_used = VPXMAX(-9, extra_cfg.cpu_used); +#if CONFIG_REALTIME_ONLY + if (extra_cfg.cpu_used > -5 && extra_cfg.cpu_used < 5) + extra_cfg.cpu_used = (extra_cfg.cpu_used > 0) ? 5 : -5; +#endif return update_extra_cfg(ctx, &extra_cfg); } @@ -1559,6 +1573,7 @@ static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx, lc->scaling_factor_num = params->scaling_factor_num[sl]; lc->scaling_factor_den = params->scaling_factor_den[sl]; lc->speed = params->speed_per_layer[sl]; + lc->loopfilter_ctrl = params->loopfilter_ctrl[sl]; } } @@ -1703,6 +1718,48 @@ static vpx_codec_err_t ctrl_set_postencode_drop(vpx_codec_alg_priv_t *ctx, return VPX_CODEC_OK; } +static vpx_codec_err_t ctrl_set_disable_overshoot_maxq_cbr( + vpx_codec_alg_priv_t *ctx, va_list args) { + VP9_COMP *const cpi = ctx->cpi; + const unsigned int data = va_arg(args, unsigned int); + cpi->rc.disable_overshoot_maxq_cbr = data; + return VPX_CODEC_OK; +} + +static vpx_codec_err_t ctrl_set_disable_loopfilter(vpx_codec_alg_priv_t *ctx, + va_list args) { + VP9_COMP *const cpi = ctx->cpi; + const unsigned int data = va_arg(args, unsigned int); + cpi->loopfilter_ctrl = data; + return VPX_CODEC_OK; +} + +static vpx_codec_err_t ctrl_set_external_rate_control(vpx_codec_alg_priv_t *ctx, + va_list args) { + vpx_rc_funcs_t funcs = *CAST(VP9E_SET_EXTERNAL_RATE_CONTROL, args); + VP9_COMP *cpi = ctx->cpi; + EXT_RATECTRL *ext_ratectrl = &cpi->ext_ratectrl; + const VP9EncoderConfig *oxcf = &cpi->oxcf; + // TODO(angiebird): Check the possibility of this flag being set at pass == 1 + if (oxcf->pass == 2) { + const FRAME_INFO *frame_info = &cpi->frame_info; + vpx_rc_config_t ratectrl_config; + + ratectrl_config.frame_width = frame_info->frame_width; + ratectrl_config.frame_height = frame_info->frame_height; + ratectrl_config.show_frame_count = cpi->twopass.first_pass_info.num_frames; + + // TODO(angiebird): Double check whether this is the proper way to set up + // target_bitrate and frame_rate. + ratectrl_config.target_bitrate_kbps = (int)(oxcf->target_bandwidth / 1000); + ratectrl_config.frame_rate_num = oxcf->g_timebase.den; + ratectrl_config.frame_rate_den = oxcf->g_timebase.num; + + vp9_extrc_create(funcs, ratectrl_config, ext_ratectrl); + } + return VPX_CODEC_OK; +} + static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { { VP8_COPY_REFERENCE, ctrl_copy_reference }, @@ -1747,12 +1804,15 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { { VP9E_SET_TARGET_LEVEL, ctrl_set_target_level }, { VP9E_SET_ROW_MT, ctrl_set_row_mt }, { VP9E_SET_POSTENCODE_DROP, ctrl_set_postencode_drop }, + { VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, ctrl_set_disable_overshoot_maxq_cbr }, { VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test }, { VP9E_SET_SVC_INTER_LAYER_PRED, ctrl_set_svc_inter_layer_pred }, { VP9E_SET_SVC_FRAME_DROP_LAYER, ctrl_set_svc_frame_drop_layer }, { VP9E_SET_SVC_GF_TEMPORAL_REF, ctrl_set_svc_gf_temporal_ref }, { VP9E_SET_SVC_SPATIAL_LAYER_SYNC, ctrl_set_svc_spatial_layer_sync }, { VP9E_SET_DELTA_Q_UV, ctrl_set_delta_q_uv }, + { VP9E_SET_DISABLE_LOOPFILTER, ctrl_set_disable_loopfilter }, + { VP9E_SET_EXTERNAL_RATE_CONTROL, ctrl_set_external_rate_control }, // Getters { VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer }, @@ -1886,7 +1946,7 @@ static vp9_extracfg get_extra_cfg() { VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, vpx_rational_t frame_rate, - int target_bitrate, + int target_bitrate, int encode_speed, vpx_enc_pass enc_pass) { /* This function will generate the same VP9EncoderConfig used by the * vpxenc command given below. @@ -1897,6 +1957,7 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, * HEIGHT: frame_height * FPS: frame_rate * BITRATE: target_bitrate + * CPU_USED:encode_speed * * INPUT, OUTPUT, LIMIT will not affect VP9EncoderConfig * @@ -1908,9 +1969,10 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, * BITRATE=600 * FPS=30/1 * LIMIT=150 + * CPU_USED=0 * ./vpxenc --limit=$LIMIT --width=$WIDTH --height=$HEIGHT --fps=$FPS * --lag-in-frames=25 \ - * --codec=vp9 --good --cpu-used=0 --threads=0 --profile=0 \ + * --codec=vp9 --good --cpu-used=CPU_USED --threads=0 --profile=0 \ * --min-q=0 --max-q=63 --auto-alt-ref=1 --passes=2 --kf-max-dist=150 \ * --kf-min-dist=0 --drop-frame=0 --static-thresh=0 --bias-pct=50 \ * --minsection-pct=0 --maxsection-pct=150 --arnr-maxframes=7 --psnr \ @@ -1933,49 +1995,50 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, oxcf.tile_columns = 0; oxcf.frame_parallel_decoding_mode = 0; oxcf.two_pass_vbrmax_section = 150; + oxcf.speed = abs(encode_speed); return oxcf; } -#define DUMP_STRUCT_VALUE(struct, value) \ - printf(#value " %" PRId64 "\n", (int64_t)(struct)->value) +#define DUMP_STRUCT_VALUE(fp, structure, value) \ + fprintf(fp, #value " %" PRId64 "\n", (int64_t)(structure)->value) -void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) { - DUMP_STRUCT_VALUE(oxcf, profile); - DUMP_STRUCT_VALUE(oxcf, bit_depth); - DUMP_STRUCT_VALUE(oxcf, width); - DUMP_STRUCT_VALUE(oxcf, height); - DUMP_STRUCT_VALUE(oxcf, input_bit_depth); - DUMP_STRUCT_VALUE(oxcf, init_framerate); +void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp) { + DUMP_STRUCT_VALUE(fp, oxcf, profile); + DUMP_STRUCT_VALUE(fp, oxcf, bit_depth); + DUMP_STRUCT_VALUE(fp, oxcf, width); + DUMP_STRUCT_VALUE(fp, oxcf, height); + DUMP_STRUCT_VALUE(fp, oxcf, input_bit_depth); + DUMP_STRUCT_VALUE(fp, oxcf, init_framerate); // TODO(angiebird): dump g_timebase // TODO(angiebird): dump g_timebase_in_ts - DUMP_STRUCT_VALUE(oxcf, target_bandwidth); + DUMP_STRUCT_VALUE(fp, oxcf, target_bandwidth); - DUMP_STRUCT_VALUE(oxcf, noise_sensitivity); - DUMP_STRUCT_VALUE(oxcf, sharpness); - DUMP_STRUCT_VALUE(oxcf, speed); - DUMP_STRUCT_VALUE(oxcf, rc_max_intra_bitrate_pct); - DUMP_STRUCT_VALUE(oxcf, rc_max_inter_bitrate_pct); - DUMP_STRUCT_VALUE(oxcf, gf_cbr_boost_pct); + DUMP_STRUCT_VALUE(fp, oxcf, noise_sensitivity); + DUMP_STRUCT_VALUE(fp, oxcf, sharpness); + DUMP_STRUCT_VALUE(fp, oxcf, speed); + DUMP_STRUCT_VALUE(fp, oxcf, rc_max_intra_bitrate_pct); + DUMP_STRUCT_VALUE(fp, oxcf, rc_max_inter_bitrate_pct); + DUMP_STRUCT_VALUE(fp, oxcf, gf_cbr_boost_pct); - DUMP_STRUCT_VALUE(oxcf, mode); - DUMP_STRUCT_VALUE(oxcf, pass); + DUMP_STRUCT_VALUE(fp, oxcf, mode); + DUMP_STRUCT_VALUE(fp, oxcf, pass); // Key Framing Operations - DUMP_STRUCT_VALUE(oxcf, auto_key); - DUMP_STRUCT_VALUE(oxcf, key_freq); + DUMP_STRUCT_VALUE(fp, oxcf, auto_key); + DUMP_STRUCT_VALUE(fp, oxcf, key_freq); - DUMP_STRUCT_VALUE(oxcf, lag_in_frames); + DUMP_STRUCT_VALUE(fp, oxcf, lag_in_frames); // ---------------------------------------------------------------- // DATARATE CONTROL OPTIONS // vbr, cbr, constrained quality or constant quality - DUMP_STRUCT_VALUE(oxcf, rc_mode); + DUMP_STRUCT_VALUE(fp, oxcf, rc_mode); // buffer targeting aggressiveness - DUMP_STRUCT_VALUE(oxcf, under_shoot_pct); - DUMP_STRUCT_VALUE(oxcf, over_shoot_pct); + DUMP_STRUCT_VALUE(fp, oxcf, under_shoot_pct); + DUMP_STRUCT_VALUE(fp, oxcf, over_shoot_pct); // buffering parameters // TODO(angiebird): dump tarting_buffer_level_ms @@ -1983,37 +2046,37 @@ void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) { // TODO(angiebird): dump maximum_buffer_size_ms // Frame drop threshold. - DUMP_STRUCT_VALUE(oxcf, drop_frames_water_mark); + DUMP_STRUCT_VALUE(fp, oxcf, drop_frames_water_mark); // controlling quality - DUMP_STRUCT_VALUE(oxcf, fixed_q); - DUMP_STRUCT_VALUE(oxcf, worst_allowed_q); - DUMP_STRUCT_VALUE(oxcf, best_allowed_q); - DUMP_STRUCT_VALUE(oxcf, cq_level); - DUMP_STRUCT_VALUE(oxcf, aq_mode); + DUMP_STRUCT_VALUE(fp, oxcf, fixed_q); + DUMP_STRUCT_VALUE(fp, oxcf, worst_allowed_q); + DUMP_STRUCT_VALUE(fp, oxcf, best_allowed_q); + DUMP_STRUCT_VALUE(fp, oxcf, cq_level); + DUMP_STRUCT_VALUE(fp, oxcf, aq_mode); // Special handling of Adaptive Quantization for AltRef frames - DUMP_STRUCT_VALUE(oxcf, alt_ref_aq); + DUMP_STRUCT_VALUE(fp, oxcf, alt_ref_aq); // Internal frame size scaling. - DUMP_STRUCT_VALUE(oxcf, resize_mode); - DUMP_STRUCT_VALUE(oxcf, scaled_frame_width); - DUMP_STRUCT_VALUE(oxcf, scaled_frame_height); + DUMP_STRUCT_VALUE(fp, oxcf, resize_mode); + DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_width); + DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_height); // Enable feature to reduce the frame quantization every x frames. - DUMP_STRUCT_VALUE(oxcf, frame_periodic_boost); + DUMP_STRUCT_VALUE(fp, oxcf, frame_periodic_boost); // two pass datarate control - DUMP_STRUCT_VALUE(oxcf, two_pass_vbrbias); - DUMP_STRUCT_VALUE(oxcf, two_pass_vbrmin_section); - DUMP_STRUCT_VALUE(oxcf, two_pass_vbrmax_section); - DUMP_STRUCT_VALUE(oxcf, vbr_corpus_complexity); + DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrbias); + DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmin_section); + DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmax_section); + DUMP_STRUCT_VALUE(fp, oxcf, vbr_corpus_complexity); // END DATARATE CONTROL OPTIONS // ---------------------------------------------------------------- // Spatial and temporal scalability. - DUMP_STRUCT_VALUE(oxcf, ss_number_layers); - DUMP_STRUCT_VALUE(oxcf, ts_number_layers); + DUMP_STRUCT_VALUE(fp, oxcf, ss_number_layers); + DUMP_STRUCT_VALUE(fp, oxcf, ts_number_layers); // Bitrate allocation for spatial layers. // TODO(angiebird): dump layer_target_bitrate[VPX_MAX_LAYERS] @@ -2021,25 +2084,25 @@ void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) { // TODO(angiebird): dump ss_enable_auto_arf[VPX_SS_MAX_LAYERS] // TODO(angiebird): dump ts_rate_decimator[VPX_TS_MAX_LAYERS] - DUMP_STRUCT_VALUE(oxcf, enable_auto_arf); - DUMP_STRUCT_VALUE(oxcf, encode_breakout); - DUMP_STRUCT_VALUE(oxcf, error_resilient_mode); - DUMP_STRUCT_VALUE(oxcf, frame_parallel_decoding_mode); + DUMP_STRUCT_VALUE(fp, oxcf, enable_auto_arf); + DUMP_STRUCT_VALUE(fp, oxcf, encode_breakout); + DUMP_STRUCT_VALUE(fp, oxcf, error_resilient_mode); + DUMP_STRUCT_VALUE(fp, oxcf, frame_parallel_decoding_mode); - DUMP_STRUCT_VALUE(oxcf, arnr_max_frames); - DUMP_STRUCT_VALUE(oxcf, arnr_strength); + DUMP_STRUCT_VALUE(fp, oxcf, arnr_max_frames); + DUMP_STRUCT_VALUE(fp, oxcf, arnr_strength); - DUMP_STRUCT_VALUE(oxcf, min_gf_interval); - DUMP_STRUCT_VALUE(oxcf, max_gf_interval); + DUMP_STRUCT_VALUE(fp, oxcf, min_gf_interval); + DUMP_STRUCT_VALUE(fp, oxcf, max_gf_interval); - DUMP_STRUCT_VALUE(oxcf, tile_columns); - DUMP_STRUCT_VALUE(oxcf, tile_rows); + DUMP_STRUCT_VALUE(fp, oxcf, tile_columns); + DUMP_STRUCT_VALUE(fp, oxcf, tile_rows); - DUMP_STRUCT_VALUE(oxcf, enable_tpl_model); + DUMP_STRUCT_VALUE(fp, oxcf, enable_tpl_model); - DUMP_STRUCT_VALUE(oxcf, max_threads); + DUMP_STRUCT_VALUE(fp, oxcf, max_threads); - DUMP_STRUCT_VALUE(oxcf, target_level); + DUMP_STRUCT_VALUE(fp, oxcf, target_level); // TODO(angiebird): dump two_pass_stats_in @@ -2047,19 +2110,19 @@ void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) { // TODO(angiebird): dump firstpass_mb_stats_in #endif - DUMP_STRUCT_VALUE(oxcf, tuning); - DUMP_STRUCT_VALUE(oxcf, content); + DUMP_STRUCT_VALUE(fp, oxcf, tuning); + DUMP_STRUCT_VALUE(fp, oxcf, content); #if CONFIG_VP9_HIGHBITDEPTH - DUMP_STRUCT_VALUE(oxcf, use_highbitdepth); + DUMP_STRUCT_VALUE(fp, oxcf, use_highbitdepth); #endif - DUMP_STRUCT_VALUE(oxcf, color_space); - DUMP_STRUCT_VALUE(oxcf, color_range); - DUMP_STRUCT_VALUE(oxcf, render_width); - DUMP_STRUCT_VALUE(oxcf, render_height); - DUMP_STRUCT_VALUE(oxcf, temporal_layering_mode); + DUMP_STRUCT_VALUE(fp, oxcf, color_space); + DUMP_STRUCT_VALUE(fp, oxcf, color_range); + DUMP_STRUCT_VALUE(fp, oxcf, render_width); + DUMP_STRUCT_VALUE(fp, oxcf, render_height); + DUMP_STRUCT_VALUE(fp, oxcf, temporal_layering_mode); - DUMP_STRUCT_VALUE(oxcf, row_mt); - DUMP_STRUCT_VALUE(oxcf, motion_vector_unit_test); + DUMP_STRUCT_VALUE(fp, oxcf, row_mt); + DUMP_STRUCT_VALUE(fp, oxcf, motion_vector_unit_test); } FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf) { diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.h index 08569fcc9..01338adb4 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.h @@ -19,10 +19,10 @@ extern "C" { VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, vpx_rational_t frame_rate, - int target_bitrate, + int target_bitrate, int encode_speed, vpx_enc_pass enc_pass); -void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf); +void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp); FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf); diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c index 74d08a587..8d031694d 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c @@ -88,8 +88,9 @@ vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, yv12->y_width = img->d_w; yv12->y_height = img->d_h; - yv12->uv_width = - img->x_chroma_shift == 1 ? (1 + yv12->y_width) / 2 : yv12->y_width; + yv12->uv_width = img->x_chroma_shift == 1 || img->fmt == VPX_IMG_FMT_NV12 + ? (1 + yv12->y_width) / 2 + : yv12->y_width; yv12->uv_height = img->y_chroma_shift == 1 ? (1 + yv12->y_height) / 2 : yv12->y_height; yv12->uv_crop_width = yv12->uv_width; @@ -127,5 +128,9 @@ vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, #endif // CONFIG_VP9_HIGHBITDEPTH yv12->subsampling_x = img->x_chroma_shift; yv12->subsampling_y = img->y_chroma_shift; + // When reading the data, UV are in one plane for NV12 format, thus + // x_chroma_shift is 0. After converting, UV are in separate planes, and + // subsampling_x should be set to 1. + if (img->fmt == VPX_IMG_FMT_NV12) yv12->subsampling_x = 1; return VPX_CODEC_OK; } diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9cx.mk b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9cx.mk index ad774505c..38e99165a 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9cx.mk +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vp9/vp9cx.mk @@ -18,9 +18,6 @@ VP9_CX_SRCS_REMOVE-no += $(VP9_COMMON_SRCS_REMOVE-no) VP9_CX_SRCS-yes += vp9_cx_iface.c VP9_CX_SRCS-yes += vp9_cx_iface.h -VP9_CX_SRCS-$(CONFIG_RATE_CTRL) += simple_encode.cc -VP9_CX_SRCS-$(CONFIG_RATE_CTRL) += simple_encode.h - VP9_CX_SRCS-yes += encoder/vp9_bitstream.c VP9_CX_SRCS-yes += encoder/vp9_context_tree.c VP9_CX_SRCS-yes += encoder/vp9_context_tree.h @@ -99,6 +96,8 @@ VP9_CX_SRCS-yes += encoder/vp9_skin_detection.c VP9_CX_SRCS-yes += encoder/vp9_skin_detection.h VP9_CX_SRCS-yes += encoder/vp9_noise_estimate.c VP9_CX_SRCS-yes += encoder/vp9_noise_estimate.h +VP9_CX_SRCS-yes += encoder/vp9_ext_ratectrl.c +VP9_CX_SRCS-yes += encoder/vp9_ext_ratectrl.h ifeq ($(CONFIG_VP9_POSTPROC),yes) VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += common/vp9_postproc.h VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += common/vp9_postproc.c diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/internal/vpx_codec_internal.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/internal/vpx_codec_internal.h index 9eed85e5d..4ef93057f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/internal/vpx_codec_internal.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/internal/vpx_codec_internal.h @@ -27,13 +27,15 @@ * * * An application instantiates a specific decoder instance by using - * vpx_codec_init() and a pointer to the algorithm's interface structure: + * vpx_codec_dec_init() and a pointer to the algorithm's interface structure: *
  *     my_app.c:
  *       extern vpx_codec_iface_t my_codec;
  *       {
  *           vpx_codec_ctx_t algo;
- *           res = vpx_codec_init(&algo, &my_codec);
+ *           int threads = 4;
+ *           vpx_codec_dec_cfg_t cfg = { threads, 0, 0 };
+ *           res = vpx_codec_dec_init(&algo, &my_codec, &cfg, 0);
  *       }
  *     
* @@ -66,7 +68,7 @@ typedef struct vpx_codec_priv_enc_mr_cfg vpx_codec_priv_enc_mr_cfg_t; /*!\brief init function pointer prototype * * Performs algorithm-specific initialization of the decoder context. This - * function is called by the generic vpx_codec_init() wrapper function, so + * function is called by vpx_codec_dec_init() and vpx_codec_enc_init(), so * plugins implementing this interface may trust the input parameters to be * properly initialized. * @@ -175,16 +177,15 @@ typedef const struct vpx_codec_ctrl_fn_map { /*!\brief decode data function pointer prototype * * Processes a buffer of coded data. If the processing results in a new - * decoded frame becoming available, #VPX_CODEC_CB_PUT_SLICE and - * #VPX_CODEC_CB_PUT_FRAME events are generated as appropriate. This - * function is called by the generic vpx_codec_decode() wrapper function, - * so plugins implementing this interface may trust the input parameters - * to be properly initialized. + * decoded frame becoming available, put_slice and put_frame callbacks + * are invoked as appropriate. This function is called by the generic + * vpx_codec_decode() wrapper function, so plugins implementing this + * interface may trust the input parameters to be properly initialized. * * \param[in] ctx Pointer to this instance's context * \param[in] data Pointer to this block of new coded data. If - * NULL, a #VPX_CODEC_CB_PUT_FRAME event is posted - * for the previously decoded frame. + * NULL, the put_frame callback is invoked for + * the previously decoded frame. * \param[in] data_sz Size of the coded data, in bytes. * * \return Returns #VPX_CODEC_OK if the coded data was processed completely diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_codec.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_codec.c index 10331aa21..114b94e19 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_codec.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_codec.c @@ -97,7 +97,7 @@ vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t *ctx, int ctrl_id, ...) { res = VPX_CODEC_INCAPABLE; - for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++) { + for (entry = ctx->iface->ctrl_maps; entry->fn; entry++) { if (!entry->ctrl_id || entry->ctrl_id == ctrl_id) { va_list ap; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_decoder.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_decoder.c index fc1c2bcca..427cd1bf4 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_decoder.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_decoder.c @@ -138,9 +138,10 @@ vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx, if (!ctx || !cb) res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv || - !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME)) + else if (!ctx->iface || !ctx->priv) res = VPX_CODEC_ERROR; + else if (!(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME)) + res = VPX_CODEC_INCAPABLE; else { ctx->priv->dec.put_frame_cb.u.put_frame = cb; ctx->priv->dec.put_frame_cb.user_priv = user_priv; @@ -157,9 +158,10 @@ vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx, if (!ctx || !cb) res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv || - !(ctx->iface->caps & VPX_CODEC_CAP_PUT_SLICE)) + else if (!ctx->iface || !ctx->priv) res = VPX_CODEC_ERROR; + else if (!(ctx->iface->caps & VPX_CODEC_CAP_PUT_SLICE)) + res = VPX_CODEC_INCAPABLE; else { ctx->priv->dec.put_slice_cb.u.put_slice = cb; ctx->priv->dec.put_slice_cb.user_priv = user_priv; @@ -176,9 +178,10 @@ vpx_codec_err_t vpx_codec_set_frame_buffer_functions( if (!ctx || !cb_get || !cb_release) { res = VPX_CODEC_INVALID_PARAM; - } else if (!ctx->iface || !ctx->priv || - !(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) { + } else if (!ctx->iface || !ctx->priv) { res = VPX_CODEC_ERROR; + } else if (!(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) { + res = VPX_CODEC_INCAPABLE; } else { res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release, cb_priv); diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c index a7c6ec0ce..ff496b5d3 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/src/vpx_image.c @@ -39,7 +39,8 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt, /* Get sample size for this format */ switch (fmt) { case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_YV12: bps = 12; break; + case VPX_IMG_FMT_YV12: + case VPX_IMG_FMT_NV12: bps = 12; break; case VPX_IMG_FMT_I422: case VPX_IMG_FMT_I440: bps = 16; break; case VPX_IMG_FMT_I444: bps = 24; break; @@ -51,6 +52,8 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt, } /* Get chroma shift values for this format */ + // For VPX_IMG_FMT_NV12, xcs needs to be 0 such that UV data is all read at + // one time. switch (fmt) { case VPX_IMG_FMT_I420: case VPX_IMG_FMT_YV12: @@ -62,6 +65,7 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt, switch (fmt) { case VPX_IMG_FMT_I420: + case VPX_IMG_FMT_NV12: case VPX_IMG_FMT_I440: case VPX_IMG_FMT_YV12: case VPX_IMG_FMT_I42016: @@ -173,7 +177,12 @@ int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y, data + x * bytes_per_sample + y * img->stride[VPX_PLANE_Y]; data += img->h * img->stride[VPX_PLANE_Y]; - if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) { + if (img->fmt == VPX_IMG_FMT_NV12) { + img->planes[VPX_PLANE_U] = + data + (x >> img->x_chroma_shift) + + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U]; + img->planes[VPX_PLANE_V] = img->planes[VPX_PLANE_U] + 1; + } else if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) { img->planes[VPX_PLANE_U] = data + (x >> img->x_chroma_shift) * bytes_per_sample + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U]; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vp8cx.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vp8cx.h index dcdd710c0..37ad07d33 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vp8cx.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vp8cx.h @@ -17,6 +17,7 @@ */ #include "./vp8.h" #include "./vpx_encoder.h" +#include "./vpx_ext_ratectrl.h" /*!\file * \brief Provides definitions for using VP8 or VP9 encoder algorithm within the @@ -684,6 +685,33 @@ enum vp8e_enc_control_id { * Supported in codecs: VP9 */ VP9E_SET_DELTA_Q_UV, + + /*!\brief Codec control function to disable increase Q on overshoot in CBR. + * + * 0: On (default), 1: Disable. + * + * Supported in codecs: VP9 + */ + VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, + + /*!\brief Codec control function to disable loopfilter. + * + * 0: Loopfilter on all frames, 1: Disable on non reference frames. + * 2: Disable on all frames. + * + * Supported in codecs: VP9 + */ + VP9E_SET_DISABLE_LOOPFILTER, + + /*!\brief Codec control function to enable external rate control library. + * + * args[0]: path of the rate control library + * + * args[1]: private config of the rate control library + * + * Supported in codecs: VP9 + */ + VP9E_SET_EXTERNAL_RATE_CONTROL, }; /*!\brief vpx 1-D scaling mode @@ -1034,6 +1062,15 @@ VPX_CTRL_USE_TYPE(VP9E_SET_POSTENCODE_DROP, unsigned int) VPX_CTRL_USE_TYPE(VP9E_SET_DELTA_Q_UV, int) #define VPX_CTRL_VP9E_SET_DELTA_Q_UV +VPX_CTRL_USE_TYPE(VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, int) +#define VPX_CTRL_VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR + +VPX_CTRL_USE_TYPE(VP9E_SET_DISABLE_LOOPFILTER, int) +#define VPX_CTRL_VP9E_SET_DISABLE_LOOPFILTER + +VPX_CTRL_USE_TYPE(VP9E_SET_EXTERNAL_RATE_CONTROL, vpx_rc_funcs_t *) +#define VPX_CTRL_VP9E_SET_EXTERNAL_RATE_CONTROL + /*!\endcond */ /*! @} - end defgroup vp8_encoder */ #ifdef __cplusplus diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_codec.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_codec.h index 6371a6ca2..b0a931e01 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_codec.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_codec.h @@ -22,13 +22,16 @@ * video codec algorithm. * * An application instantiates a specific codec instance by using - * vpx_codec_init() and a pointer to the algorithm's interface structure: + * vpx_codec_dec_init() or vpx_codec_enc_init() and a pointer to the + * algorithm's interface structure: *
  *     my_app.c:
  *       extern vpx_codec_iface_t my_codec;
  *       {
  *           vpx_codec_ctx_t algo;
- *           res = vpx_codec_init(&algo, &my_codec);
+ *           int threads = 4;
+ *           vpx_codec_dec_cfg_t cfg = { threads, 0, 0 };
+ *           res = vpx_codec_dec_init(&algo, &my_codec, &cfg, 0);
  *       }
  *     
* diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_codec.mk b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_codec.mk index 4ed77ad6d..350dc247b 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_codec.mk +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_codec.mk @@ -24,6 +24,7 @@ API_DOC_SRCS-$(CONFIG_VP8_DECODER) += vp8dx.h API_DOC_SRCS-yes += vpx_codec.h API_DOC_SRCS-yes += vpx_decoder.h API_DOC_SRCS-yes += vpx_encoder.h +API_DOC_SRCS-yes += vpx_ext_ratectrl.h API_DOC_SRCS-yes += vpx_frame_buffer.h API_DOC_SRCS-yes += vpx_image.h @@ -39,3 +40,4 @@ API_SRCS-yes += vpx_codec.mk API_SRCS-yes += vpx_frame_buffer.h API_SRCS-yes += vpx_image.h API_SRCS-yes += vpx_integer.h +API_SRCS-yes += vpx_ext_ratectrl.h diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_decoder.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_decoder.h index f113f7196..39e5f585f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_decoder.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_decoder.h @@ -58,6 +58,10 @@ extern "C" { #define VPX_CODEC_CAP_ERROR_CONCEALMENT 0x80000 /*!\brief Can receive encoded frames one fragment at a time */ #define VPX_CODEC_CAP_INPUT_FRAGMENTS 0x100000 +/*!\brief Can support frame-based multi-threading */ +#define VPX_CODEC_CAP_FRAME_THREADING 0x200000 +/*!brief Can support external frame buffers */ +#define VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x400000 /*! \brief Initialization-time Feature Enabling * @@ -66,11 +70,6 @@ extern "C" { * * The available flags are specified by VPX_CODEC_USE_* defines. */ -/*!\brief Can support frame-based multi-threading */ -#define VPX_CODEC_CAP_FRAME_THREADING 0x200000 -/*!brief Can support external frame buffers */ -#define VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x400000 - #define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded frame */ /*!\brief Conceal errors in decoded frames */ #define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 @@ -185,8 +184,8 @@ vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx, /*!\brief Decode data * * Processes a buffer of coded data. If the processing results in a new - * decoded frame becoming available, PUT_SLICE and PUT_FRAME events may be - * generated, as appropriate. Encoded data \ref MUST be passed in DTS (decode + * decoded frame becoming available, put_slice and put_frame callbacks may be + * invoked, as appropriate. Encoded data \ref MUST be passed in DTS (decode * time stamp) order. Frames produced will always be in PTS (presentation * time stamp) order. * If the decoder is configured with VPX_CODEC_USE_INPUT_FRAGMENTS enabled, @@ -199,8 +198,8 @@ vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx, * * \param[in] ctx Pointer to this instance's context * \param[in] data Pointer to this block of new coded data. If - * NULL, a VPX_CODEC_CB_PUT_FRAME event is posted - * for the previously decoded frame. + * NULL, the put_frame callback is invoked for + * the previously decoded frame. * \param[in] data_sz Size of the coded data, in bytes. * \param[in] user_priv Application specific data to associate with * this frame. @@ -236,11 +235,10 @@ vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter); /*!\defgroup cap_put_frame Frame-Based Decoding Functions * - * The following functions are required to be implemented for all decoders - * that advertise the VPX_CODEC_CAP_PUT_FRAME capability. Calling these - * functions - * for codecs that don't advertise this capability will result in an error - * code being returned, usually VPX_CODEC_ERROR + * The following function is required to be implemented for all decoders + * that advertise the VPX_CODEC_CAP_PUT_FRAME capability. Calling this + * function for codecs that don't advertise this capability will result in + * an error code being returned, usually VPX_CODEC_INCAPABLE. * @{ */ @@ -264,8 +262,9 @@ typedef void (*vpx_codec_put_frame_cb_fn_t)(void *user_priv, * \retval #VPX_CODEC_OK * Callback successfully registered. * \retval #VPX_CODEC_ERROR - * Decoder context not initialized, or algorithm not capable of - * posting slice completion. + * Decoder context not initialized. + * \retval #VPX_CODEC_INCAPABLE + * Algorithm not capable of posting frame completion. */ vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx, vpx_codec_put_frame_cb_fn_t cb, @@ -275,18 +274,17 @@ vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx, /*!\defgroup cap_put_slice Slice-Based Decoding Functions * - * The following functions are required to be implemented for all decoders - * that advertise the VPX_CODEC_CAP_PUT_SLICE capability. Calling these - * functions - * for codecs that don't advertise this capability will result in an error - * code being returned, usually VPX_CODEC_ERROR + * The following function is required to be implemented for all decoders + * that advertise the VPX_CODEC_CAP_PUT_SLICE capability. Calling this + * function for codecs that don't advertise this capability will result in + * an error code being returned, usually VPX_CODEC_INCAPABLE. * @{ */ /*!\brief put slice callback prototype * * This callback is invoked by the decoder to notify the application of - * the availability of partially decoded image data. The + * the availability of partially decoded image data. */ typedef void (*vpx_codec_put_slice_cb_fn_t)(void *user_priv, const vpx_image_t *img, @@ -305,8 +303,9 @@ typedef void (*vpx_codec_put_slice_cb_fn_t)(void *user_priv, * \retval #VPX_CODEC_OK * Callback successfully registered. * \retval #VPX_CODEC_ERROR - * Decoder context not initialized, or algorithm not capable of - * posting slice completion. + * Decoder context not initialized. + * \retval #VPX_CODEC_INCAPABLE + * Algorithm not capable of posting slice completion. */ vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx, vpx_codec_put_slice_cb_fn_t cb, @@ -316,10 +315,10 @@ vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx, /*!\defgroup cap_external_frame_buffer External Frame Buffer Functions * - * The following section is required to be implemented for all decoders + * The following function is required to be implemented for all decoders * that advertise the VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER capability. * Calling this function for codecs that don't advertise this capability - * will result in an error code being returned, usually VPX_CODEC_ERROR. + * will result in an error code being returned, usually VPX_CODEC_INCAPABLE. * * \note * Currently this only works with VP9. @@ -344,8 +343,9 @@ vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx, * \retval #VPX_CODEC_INVALID_PARAM * One or more of the callbacks were NULL. * \retval #VPX_CODEC_ERROR - * Decoder context not initialized, or algorithm not capable of - * using external frame buffers. + * Decoder context not initialized. + * \retval #VPX_CODEC_INCAPABLE + * Algorithm not capable of using external frame buffers. * * \note * When decoding VP9, the application may be required to pass in at least diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_encoder.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_encoder.h index c84d40f7f..39b2aef62 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_encoder.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_encoder.h @@ -705,6 +705,7 @@ typedef struct vpx_svc_parameters { int scaling_factor_den[VPX_MAX_LAYERS]; /**< Scaling factor-denominator */ int speed_per_layer[VPX_MAX_LAYERS]; /**< Speed setting for each sl */ int temporal_layering_mode; /**< Temporal layering mode */ + int loopfilter_ctrl[VPX_MAX_LAYERS]; /**< Loopfilter ctrl for each sl */ } vpx_svc_extra_cfg_t; /*!\brief Initialize an encoder instance diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_ext_ratectrl.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_ext_ratectrl.h new file mode 100644 index 000000000..bb3caa614 --- /dev/null +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_ext_ratectrl.h @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2020 The WebM 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. + */ + +#ifndef VPX_VPX_VPX_EXT_RATECTRL_H_ +#define VPX_VPX_VPX_EXT_RATECTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "./vpx_integer.h" + +/*!\brief Abstract rate control model handler + * + * The encoder will receive the model handler from create_model() defined in + * vpx_rc_funcs_t. + */ +typedef void *vpx_rc_model_t; + +/*!\brief Encode frame decision made by the external rate control model + * + * The encoder will receive the decision from the external rate control model + * through get_encodeframe_decision() defined in vpx_rc_funcs_t. + */ +typedef struct vpx_rc_encodeframe_decision { + int q_index; /**< Quantizer step index [0..255]*/ +} vpx_rc_encodeframe_decision_t; + +/*!\brief Information for the frame to be encoded. + * + * The encoder will send the information to external rate control model through + * get_encodeframe_decision() defined in vpx_rc_funcs_t. + * + */ +typedef struct vpx_rc_encodeframe_info { + /*! + * 0: Key frame + * 1: Inter frame + * 2: Alternate reference frame + * 3: Overlay frame + * 4: Golden frame + */ + int frame_type; + int show_index; /**< display index, starts from zero*/ + int coding_index; /**< coding index, starts from zero*/ + int ref_frame_coding_indexes[3]; /**< three reference frames' coding indices*/ + /*! + * The validity of the three reference frames. + * 0: Invalid + * 1: Valid + */ + int ref_frame_valid_list[3]; +} vpx_rc_encodeframe_info_t; + +/*!\brief Frame coding result + * + * The encoder will send the result to the external rate control model through + * update_encodeframe_result() defined in vpx_rc_funcs_t. + */ +typedef struct vpx_rc_encodeframe_result { + int64_t sse; /**< sum of squared error of the reconstructed frame */ + int64_t bit_count; /**< number of bits spent on coding the frame*/ + int64_t pixel_count; /**< number of pixels in YUV planes of the frame*/ +} vpx_rc_encodeframe_result_t; + +/*!\brief Status returned by rate control callback functions. + */ +typedef enum vpx_rc_status { + VPX_RC_OK = 0, + VPX_RC_ERROR = 1, +} vpx_rc_status_t; + +/*!\brief First pass frame stats + * This is a mirror of vp9's FIRSTPASS_STATS except that spatial_layer_id is + * omitted + */ +typedef struct vpx_rc_frame_stats { + /*! + * Frame number in display order, if stats are for a single frame. + * No real meaning for a collection of frames. + */ + double frame; + /*! + * Weight assigned to this frame (or total weight for the collection of + * frames) currently based on intra factor and brightness factor. This is used + * to distribute bits between easier and harder frames. + */ + double weight; + /*! + * Intra prediction error. + */ + double intra_error; + /*! + * Best of intra pred error and inter pred error using last frame as ref. + */ + double coded_error; + /*! + * Best of intra pred error and inter pred error using golden frame as ref. + */ + double sr_coded_error; + /*! + * Estimate the noise energy of the current frame. + */ + double frame_noise_energy; + /*! + * Percentage of blocks with inter pred error < intra pred error. + */ + double pcnt_inter; + /*! + * Percentage of blocks using (inter prediction and) non-zero motion vectors. + */ + double pcnt_motion; + /*! + * Percentage of blocks where golden frame was better than last or intra: + * inter pred error using golden frame < inter pred error using last frame and + * inter pred error using golden frame < intra pred error + */ + double pcnt_second_ref; + /*! + * Percentage of blocks where intra and inter prediction errors were very + * close. Note that this is a 'weighted count', that is, the so blocks may be + * weighted by how close the two errors were. + */ + double pcnt_neutral; + /*! + * Percentage of blocks that have intra error < inter error and inter error < + * LOW_I_THRESH LOW_I_THRESH = 24000 using bit_depth 8 LOW_I_THRESH = 24000 << + * 4 using bit_depth 10 LOW_I_THRESH = 24000 << 8 using bit_depth 12 + */ + double pcnt_intra_low; + /*! + * Percentage of blocks that have intra error < inter error and intra error < + * LOW_I_THRESH but inter error >= LOW_I_THRESH LOW_I_THRESH = 24000 using + * bit_depth 8 LOW_I_THRESH = 24000 << 4 using bit_depth 10 LOW_I_THRESH = + * 24000 << 8 using bit_depth 12 + */ + double pcnt_intra_high; + /*! + * Percentage of blocks that have almost no intra error residual + * (i.e. are in effect completely flat and untextured in the intra + * domain). In natural videos this is uncommon, but it is much more + * common in animations, graphics and screen content, so may be used + * as a signal to detect these types of content. + */ + double intra_skip_pct; + /*! + * Percentage of blocks that have intra error < SMOOTH_INTRA_THRESH + * SMOOTH_INTRA_THRESH = 4000 using bit_depth 8 + * SMOOTH_INTRA_THRESH = 4000 << 4 using bit_depth 10 + * SMOOTH_INTRA_THRESH = 4000 << 8 using bit_depth 12 + */ + double intra_smooth_pct; + /*! + * Image mask rows top and bottom. + */ + double inactive_zone_rows; + /*! + * Image mask columns at left and right edges. + */ + double inactive_zone_cols; + /*! + * Average of row motion vectors. + */ + double MVr; + /*! + * Mean of absolute value of row motion vectors. + */ + double mvr_abs; + /*! + * Mean of column motion vectors. + */ + double MVc; + /*! + * Mean of absolute value of column motion vectors. + */ + double mvc_abs; + /*! + * Variance of row motion vectors. + */ + double MVrv; + /*! + * Variance of column motion vectors. + */ + double MVcv; + /*! + * Value in range [-1,1] indicating fraction of row and column motion vectors + * that point inwards (negative MV value) or outwards (positive MV value). + * For example, value of 1 indicates, all row/column MVs are inwards. + */ + double mv_in_out_count; + /*! + * Duration of the frame / collection of frames. + */ + double duration; + /*! + * 1.0 if stats are for a single frame, OR + * Number of frames in this collection for which the stats are accumulated. + */ + double count; +} vpx_rc_frame_stats_t; + +/*!\brief Collection of first pass frame stats + */ +typedef struct vpx_rc_firstpass_stats { + /*! + * Pointer to first pass frame stats. + * The pointed array of vpx_rc_frame_stats_t should have length equal to + * number of show frames in the video. + */ + vpx_rc_frame_stats_t *frame_stats; + /*! + * Number of show frames in the video. + */ + int num_frames; +} vpx_rc_firstpass_stats_t; + +/*!\brief Encode config sent to external rate control model + */ +typedef struct vpx_rc_config { + int frame_width; /**< frame width */ + int frame_height; /**< frame height */ + int show_frame_count; /**< number of visible frames in the video */ + /*! + * Target bitrate in kilobytes per second + */ + int target_bitrate_kbps; + int frame_rate_num; /**< numerator of frame rate */ + int frame_rate_den; /**< denominator of frame rate */ +} vpx_rc_config_t; + +/*!\brief Create an external rate control model callback prototype + * + * This callback is invoked by the encoder to create an external rate control + * model. + * + * \param[in] priv Callback's private data + * \param[in] ratectrl_config Pointer to vpx_rc_config_t + * \param[out] rate_ctrl_model_pt Pointer to vpx_rc_model_t + */ +typedef vpx_rc_status_t (*vpx_rc_create_model_cb_fn_t)( + void *priv, const vpx_rc_config_t *ratectrl_config, + vpx_rc_model_t *rate_ctrl_model_pt); + +/*!\brief Send first pass stats to the external rate control model callback + * prototype + * + * This callback is invoked by the encoder to send first pass stats to the + * external rate control model. + * + * \param[in] rate_ctrl_model rate control model + * \param[in] first_pass_stats first pass stats + */ +typedef vpx_rc_status_t (*vpx_rc_send_firstpass_stats_cb_fn_t)( + vpx_rc_model_t rate_ctrl_model, + const vpx_rc_firstpass_stats_t *first_pass_stats); + +/*!\brief Receive encode frame decision callback prototype + * + * This callback is invoked by the encoder to receive encode frame decision from + * the external rate control model. + * + * \param[in] rate_ctrl_model rate control model + * \param[in] encode_frame_info information of the coding frame + * \param[out] frame_decision encode decision of the coding frame + */ +typedef vpx_rc_status_t (*vpx_rc_get_encodeframe_decision_cb_fn_t)( + vpx_rc_model_t rate_ctrl_model, + const vpx_rc_encodeframe_info_t *encode_frame_info, + vpx_rc_encodeframe_decision_t *frame_decision); + +/*!\brief Update encode frame result callback prototype + * + * This callback is invoked by the encoder to update encode frame result to the + * external rate control model. + * + * \param[in] rate_ctrl_model rate control model + * \param[out] encode_frame_result encode result of the coding frame + */ +typedef vpx_rc_status_t (*vpx_rc_update_encodeframe_result_cb_fn_t)( + vpx_rc_model_t rate_ctrl_model, + const vpx_rc_encodeframe_result_t *encode_frame_result); + +/*!\brief Delete the external rate control model callback prototype + * + * This callback is invoked by the encoder to delete the external rate control + * model. + * + * \param[in] rate_ctrl_model rate control model + */ +typedef vpx_rc_status_t (*vpx_rc_delete_model_cb_fn_t)( + vpx_rc_model_t rate_ctrl_model); + +/*!\brief Callback function set for external rate control. + * + * The user can enable external rate control by registering + * a set of callback functions with the codec control flag + * VP9E_SET_EXTERNAL_RATE_CONTROL. + */ +typedef struct vpx_rc_funcs { + /*! + * Create an external rate control model. + */ + vpx_rc_create_model_cb_fn_t create_model; + /*! + * Send first pass stats to the external rate control model. + */ + vpx_rc_send_firstpass_stats_cb_fn_t send_firstpass_stats; + /*! + * Get encodeframe decision from the external rate control model. + */ + vpx_rc_get_encodeframe_decision_cb_fn_t get_encodeframe_decision; + /*! + * Update encodeframe result to the external rate control model. + */ + vpx_rc_update_encodeframe_result_cb_fn_t update_encodeframe_result; + /*! + * Delete the external rate control model. + */ + vpx_rc_delete_model_cb_fn_t delete_model; + /*! + * Private data for the external rate control model. + */ + void *priv; +} vpx_rc_funcs_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VPX_VPX_VPX_EXT_RATECTRL_H_ diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_image.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_image.h index 98be5966a..bc23be50c 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_image.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx/vpx_image.h @@ -43,6 +43,7 @@ typedef enum vpx_img_fmt { VPX_IMG_FMT_I422 = VPX_IMG_FMT_PLANAR | 5, VPX_IMG_FMT_I444 = VPX_IMG_FMT_PLANAR | 6, VPX_IMG_FMT_I440 = VPX_IMG_FMT_PLANAR | 7, + VPX_IMG_FMT_NV12 = VPX_IMG_FMT_PLANAR | 9, VPX_IMG_FMT_I42016 = VPX_IMG_FMT_I420 | VPX_IMG_FMT_HIGHBITDEPTH, VPX_IMG_FMT_I42216 = VPX_IMG_FMT_I422 | VPX_IMG_FMT_HIGHBITDEPTH, VPX_IMG_FMT_I44416 = VPX_IMG_FMT_I444 | VPX_IMG_FMT_HIGHBITDEPTH, diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/macros_msa.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/macros_msa.h index a3a5a4dfe..3c2f50c79 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/macros_msa.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/macros_msa.h @@ -88,10 +88,10 @@ const uint8_t *psrc_lw_m = (const uint8_t *)(psrc); \ uint32_t val_lw_m; \ \ - __asm__ __volatile__("ulw %[val_lw_m], %[psrc_lw_m] \n\t" \ - \ - : [val_lw_m] "=r"(val_lw_m) \ - : [psrc_lw_m] "m"(*psrc_lw_m)); \ + __asm__ __volatile__("lwr %[val_lw_m], 0(%[psrc_lw_m]) \n\t" \ + "lwl %[val_lw_m], 3(%[psrc_lw_m]) \n\t" \ + : [val_lw_m] "=&r"(val_lw_m) \ + : [psrc_lw_m] "r"(psrc_lw_m)); \ \ val_lw_m; \ }) @@ -102,10 +102,10 @@ const uint8_t *psrc_ld_m = (const uint8_t *)(psrc); \ uint64_t val_ld_m = 0; \ \ - __asm__ __volatile__("uld %[val_ld_m], %[psrc_ld_m] \n\t" \ - \ - : [val_ld_m] "=r"(val_ld_m) \ - : [psrc_ld_m] "m"(*psrc_ld_m)); \ + __asm__ __volatile__("ldr %[val_ld_m], 0(%[psrc_ld_m]) \n\t" \ + "ldl %[val_ld_m], 7(%[psrc_ld_m]) \n\t" \ + : [val_ld_m] "=&r"(val_ld_m) \ + : [psrc_ld_m] "r"(psrc_ld_m)); \ \ val_ld_m; \ }) diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/sad_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/sad_mmi.c index 4368db5fd..eaca4773f 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/sad_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/sad_mmi.c @@ -364,8 +364,9 @@ static inline unsigned int vpx_sad64x(const uint8_t *src, int src_stride, double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; mips_reg l_counter = counter; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_REF_ABS_SUB_64 @@ -383,6 +384,7 @@ static inline unsigned int vpx_sad64x(const uint8_t *src, int src_stride, : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -405,9 +407,11 @@ static inline unsigned int vpx_sad_avg64x(const uint8_t *src, int src_stride, unsigned int sad; double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; mips_reg l_counter = counter; + mips_reg l_second_pred = (mips_reg)second_pred; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_AVGREF_ABS_SUB_64 @@ -424,11 +428,12 @@ static inline unsigned int vpx_sad_avg64x(const uint8_t *src, int src_stride, : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"((mips_reg)second_pred), + [second_pred]"+&r"(l_second_pred), [sad]"=&r"(sad) : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -450,8 +455,9 @@ static inline unsigned int vpx_sad32x(const uint8_t *src, int src_stride, double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; mips_reg l_counter = counter; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_REF_ABS_SUB_32 @@ -469,6 +475,7 @@ static inline unsigned int vpx_sad32x(const uint8_t *src, int src_stride, : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -493,9 +500,11 @@ static inline unsigned int vpx_sad_avg32x(const uint8_t *src, int src_stride, unsigned int sad; double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; mips_reg l_counter = counter; + mips_reg l_second_pred = (mips_reg)second_pred; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_AVGREF_ABS_SUB_32 @@ -512,11 +521,12 @@ static inline unsigned int vpx_sad_avg32x(const uint8_t *src, int src_stride, : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"((mips_reg)second_pred), + [second_pred]"+&r"(l_second_pred), [sad]"=&r"(sad) : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -539,8 +549,9 @@ static inline unsigned int vpx_sad16x(const uint8_t *src, int src_stride, double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; mips_reg l_counter = counter; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_REF_ABS_SUB_16 @@ -558,6 +569,7 @@ static inline unsigned int vpx_sad16x(const uint8_t *src, int src_stride, : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -586,9 +598,11 @@ static inline unsigned int vpx_sad_avg16x(const uint8_t *src, int src_stride, unsigned int sad; double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; mips_reg l_counter = counter; + mips_reg l_second_pred = (mips_reg)second_pred; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" + "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_AVGREF_ABS_SUB_16 @@ -605,11 +619,12 @@ static inline unsigned int vpx_sad_avg16x(const uint8_t *src, int src_stride, : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"((mips_reg)second_pred), + [second_pred]"+&r"(l_second_pred), [sad]"=&r"(sad) : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -632,8 +647,9 @@ static inline unsigned int vpx_sad8x(const uint8_t *src, int src_stride, double ftmp1, ftmp2, ftmp3; mips_reg l_counter = counter; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_REF_ABS_SUB_8 @@ -651,6 +667,7 @@ static inline unsigned int vpx_sad8x(const uint8_t *src, int src_stride, : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -679,9 +696,11 @@ static inline unsigned int vpx_sad_avg8x(const uint8_t *src, int src_stride, unsigned int sad; double ftmp1, ftmp2, ftmp3; mips_reg l_counter = counter; + mips_reg l_second_pred = (mips_reg)second_pred; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_AVGREF_ABS_SUB_8 @@ -697,11 +716,12 @@ static inline unsigned int vpx_sad_avg8x(const uint8_t *src, int src_stride, "mfc1 %[sad], %[ftmp3] \n\t" : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"((mips_reg)second_pred), + [second_pred]"+&r"(l_second_pred), [sad]"=&r"(sad) : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -724,8 +744,9 @@ static inline unsigned int vpx_sad4x(const uint8_t *src, int src_stride, double ftmp1, ftmp2, ftmp3; mips_reg l_counter = counter; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_REF_ABS_SUB_4 @@ -743,6 +764,7 @@ static inline unsigned int vpx_sad4x(const uint8_t *src, int src_stride, : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } @@ -767,9 +789,11 @@ static inline unsigned int vpx_sad_avg4x(const uint8_t *src, int src_stride, unsigned int sad; double ftmp1, ftmp2, ftmp3; mips_reg l_counter = counter; + mips_reg l_second_pred = (mips_reg)second_pred; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" + "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" "1: \n\t" // Include two loop body, to reduce loop time. SAD_SRC_AVGREF_ABS_SUB_4 @@ -785,11 +809,12 @@ static inline unsigned int vpx_sad_avg4x(const uint8_t *src, int src_stride, "mfc1 %[sad], %[ftmp3] \n\t" : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"((mips_reg)second_pred), + [second_pred]"+&r"(l_second_pred), [sad]"=&r"(sad) : [src_stride]"r"((mips_reg)src_stride), [ref_stride]"r"((mips_reg)ref_stride) ); + /* clang-format on */ return sad; } diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/subtract_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/subtract_mmi.c index 9f361704a..8bd7e6977 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/subtract_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/subtract_mmi.c @@ -24,7 +24,7 @@ void vpx_subtract_block_mmi(int rows, int cols, int16_t *diff, switch (rows) { case 4: __asm__ volatile( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" #if _MIPS_SIM == _ABIO32 "ulw %[tmp0], 0x00(%[src]) \n\t" "mtc1 %[tmp0], %[ftmp1] \n\t" @@ -118,7 +118,7 @@ void vpx_subtract_block_mmi(int rows, int cols, int16_t *diff, break; case 8: __asm__ volatile( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "li %[tmp0], 0x02 \n\t" "1: \n\t" "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" @@ -206,7 +206,7 @@ void vpx_subtract_block_mmi(int rows, int cols, int16_t *diff, break; case 16: __asm__ volatile( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "li %[tmp0], 0x08 \n\t" "1: \n\t" "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/variance_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/variance_mmi.c index c1780c33a..c2adcfa01 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/variance_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/variance_mmi.c @@ -150,7 +150,7 @@ static const uint8_t bilinear_filters[8][2] = { "psrlh %[ftmp2], %[ftmp2], %[ftmp6] \n\t" \ \ /* store: temp2[0] ~ temp2[3] */ \ - "and %[ftmp2], %[ftmp2], %[mask] \n\t" \ + "pand %[ftmp2], %[ftmp2], %[mask] \n\t" \ "packushb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" \ "gssdrc1 %[ftmp2], 0x00(%[temp2_ptr]) \n\t" @@ -163,7 +163,7 @@ static const uint8_t bilinear_filters[8][2] = { "psrlh %[ftmp4], %[ftmp4], %[ftmp6] \n\t" \ \ /* store: temp2[0] ~ temp2[3] */ \ - "and %[ftmp4], %[ftmp4], %[mask] \n\t" \ + "pand %[ftmp4], %[ftmp4], %[mask] \n\t" \ "packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t" \ "gssdrc1 %[ftmp4], 0x00(%[temp2_ptr]) \n\t" @@ -225,8 +225,8 @@ static const uint8_t bilinear_filters[8][2] = { "psrlh %[ftmp3], %[ftmp3], %[ftmp14] \n\t" \ \ /* store: temp2[0] ~ temp2[7] */ \ - "and %[ftmp2], %[ftmp2], %[mask] \n\t" \ - "and %[ftmp3], %[ftmp3], %[mask] \n\t" \ + "pand %[ftmp2], %[ftmp2], %[mask] \n\t" \ + "pand %[ftmp3], %[ftmp3], %[mask] \n\t" \ "packushb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" \ "gssdlc1 %[ftmp2], 0x07(%[temp2_ptr]) \n\t" \ "gssdrc1 %[ftmp2], 0x00(%[temp2_ptr]) \n\t" @@ -247,8 +247,8 @@ static const uint8_t bilinear_filters[8][2] = { "psrlh %[ftmp9], %[ftmp9], %[ftmp14] \n\t" \ \ /* store: temp2[0] ~ temp2[7] */ \ - "and %[ftmp8], %[ftmp8], %[mask] \n\t" \ - "and %[ftmp9], %[ftmp9], %[mask] \n\t" \ + "pand %[ftmp8], %[ftmp8], %[mask] \n\t" \ + "pand %[ftmp9], %[ftmp9], %[mask] \n\t" \ "packushb %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ "gssdlc1 %[ftmp8], 0x07(%[temp2_ptr]) \n\t" \ "gssdrc1 %[ftmp8], 0x00(%[temp2_ptr]) \n\t" @@ -319,8 +319,8 @@ static const uint8_t bilinear_filters[8][2] = { "psrlh %[ftmp5], %[ftmp5], %[ftmp14] \n\t" \ \ /* store: temp2[8] ~ temp2[15] */ \ - "and %[ftmp4], %[ftmp4], %[mask] \n\t" \ - "and %[ftmp5], %[ftmp5], %[mask] \n\t" \ + "pand %[ftmp4], %[ftmp4], %[mask] \n\t" \ + "pand %[ftmp5], %[ftmp5], %[mask] \n\t" \ "packushb %[ftmp4], %[ftmp4], %[ftmp5] \n\t" \ "gssdlc1 %[ftmp4], 0x0f(%[temp2_ptr]) \n\t" \ "gssdrc1 %[ftmp4], 0x08(%[temp2_ptr]) \n\t" @@ -343,8 +343,8 @@ static const uint8_t bilinear_filters[8][2] = { "psrlh %[ftmp11], %[ftmp11], %[ftmp14] \n\t" \ \ /* store: temp2[8] ~ temp2[15] */ \ - "and %[ftmp10], %[ftmp10], %[mask] \n\t" \ - "and %[ftmp11], %[ftmp11], %[mask] \n\t" \ + "pand %[ftmp10], %[ftmp10], %[mask] \n\t" \ + "pand %[ftmp11], %[ftmp11], %[mask] \n\t" \ "packushb %[ftmp10], %[ftmp10], %[ftmp11] \n\t" \ "gssdlc1 %[ftmp10], 0x0f(%[temp2_ptr]) \n\t" \ "gssdrc1 %[ftmp10], 0x08(%[temp2_ptr]) \n\t" @@ -414,13 +414,14 @@ static inline uint32_t vpx_variance64x(const uint8_t *src_ptr, int src_stride, *sse = 0; + /* clang-format off */ __asm__ volatile ( "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp11] \n\t" MMI_L(%[tmp0], %[high], 0x00) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" - "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" "1: \n\t" "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" @@ -478,7 +479,7 @@ static inline uint32_t vpx_variance64x(const uint8_t *src_ptr, int src_stride, "mfc1 %[tmp1], %[ftmp9] \n\t" "mfhc1 %[tmp2], %[ftmp9] \n\t" "addu %[sum], %[tmp1], %[tmp2] \n\t" - "dsrl %[ftmp1], %[ftmp10], %[ftmp11] \n\t" + "ssrld %[ftmp1], %[ftmp10], %[ftmp11] \n\t" "paddw %[ftmp1], %[ftmp1], %[ftmp10] \n\t" "swc1 %[ftmp1], 0x00(%[sse]) \n\t" : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), @@ -496,6 +497,7 @@ static inline uint32_t vpx_variance64x(const uint8_t *src_ptr, int src_stride, [high]"r"(&high), [sse]"r"(sse) : "memory" ); + /* clang-format on */ return *sse - (((int64_t)sum * sum) / (64 * high)); } @@ -519,13 +521,14 @@ uint32_t vpx_variance32x64_mmi(const uint8_t *src_ptr, int src_stride, *sse = 0; + /* clang-format off */ __asm__ volatile ( "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp11] \n\t" "li %[tmp0], 0x40 \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" - "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" "1: \n\t" "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" @@ -559,7 +562,7 @@ uint32_t vpx_variance32x64_mmi(const uint8_t *src_ptr, int src_stride, "mfc1 %[tmp1], %[ftmp9] \n\t" "mfhc1 %[tmp2], %[ftmp9] \n\t" "addu %[sum], %[tmp1], %[tmp2] \n\t" - "dsrl %[ftmp1], %[ftmp10], %[ftmp11] \n\t" + "ssrld %[ftmp1], %[ftmp10], %[ftmp11] \n\t" "paddw %[ftmp1], %[ftmp1], %[ftmp10] \n\t" "swc1 %[ftmp1], 0x00(%[sse]) \n\t" : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), @@ -577,6 +580,7 @@ uint32_t vpx_variance32x64_mmi(const uint8_t *src_ptr, int src_stride, [sse]"r"(sse) : "memory" ); + /* clang-format on */ return *sse - (((int64_t)sum * sum) / 2048); } @@ -590,14 +594,15 @@ static inline uint32_t vpx_variance32x(const uint8_t *src_ptr, int src_stride, *sse = 0; + /* clang-format off */ __asm__ volatile ( "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp11] \n\t" MMI_L(%[tmp0], %[high], 0x00) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "xor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" + "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" "1: \n\t" "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" @@ -625,7 +630,7 @@ static inline uint32_t vpx_variance32x(const uint8_t *src_ptr, int src_stride, MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) "bnez %[tmp0], 1b \n\t" - "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" + "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" "swc1 %[ftmp9], 0x00(%[sse]) \n\t" @@ -636,7 +641,7 @@ static inline uint32_t vpx_variance32x(const uint8_t *src_ptr, int src_stride, "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" - "dsrl %[ftmp0], %[ftmp3], %[ftmp11] \n\t" + "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" "swc1 %[ftmp0], 0x00(%[sum]) \n\t" @@ -653,6 +658,7 @@ static inline uint32_t vpx_variance32x(const uint8_t *src_ptr, int src_stride, [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) : "memory" ); + /* clang-format on */ return *sse - (((int64_t)sum * sum) / (32 * high)); } @@ -676,14 +682,15 @@ static inline uint32_t vpx_variance16x(const uint8_t *src_ptr, int src_stride, *sse = 0; + /* clang-format off */ __asm__ volatile ( "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp11] \n\t" MMI_L(%[tmp0], %[high], 0x00) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "xor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" + "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" "1: \n\t" "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" @@ -701,7 +708,7 @@ static inline uint32_t vpx_variance16x(const uint8_t *src_ptr, int src_stride, MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) "bnez %[tmp0], 1b \n\t" - "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" + "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" "swc1 %[ftmp9], 0x00(%[sse]) \n\t" @@ -712,7 +719,7 @@ static inline uint32_t vpx_variance16x(const uint8_t *src_ptr, int src_stride, "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" - "dsrl %[ftmp0], %[ftmp3], %[ftmp11] \n\t" + "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" "swc1 %[ftmp0], 0x00(%[sum]) \n\t" @@ -729,6 +736,7 @@ static inline uint32_t vpx_variance16x(const uint8_t *src_ptr, int src_stride, [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) : "memory" ); + /* clang-format on */ return *sse - (((int64_t)sum * sum) / (16 * high)); } @@ -753,14 +761,15 @@ static inline uint32_t vpx_variance8x(const uint8_t *src_ptr, int src_stride, *sse = 0; + /* clang-format off */ __asm__ volatile ( "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp11] \n\t" MMI_L(%[tmp0], %[high], 0x00) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "xor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" + "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" + "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" "1: \n\t" "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" @@ -773,7 +782,7 @@ static inline uint32_t vpx_variance8x(const uint8_t *src_ptr, int src_stride, MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) "bnez %[tmp0], 1b \n\t" - "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" + "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" "swc1 %[ftmp9], 0x00(%[sse]) \n\t" @@ -784,7 +793,7 @@ static inline uint32_t vpx_variance8x(const uint8_t *src_ptr, int src_stride, "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" - "dsrl %[ftmp0], %[ftmp3], %[ftmp11] \n\t" + "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" "swc1 %[ftmp0], 0x00(%[sum]) \n\t" @@ -801,6 +810,7 @@ static inline uint32_t vpx_variance8x(const uint8_t *src_ptr, int src_stride, [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) : "memory" ); + /* clang-format on */ return *sse - (((int64_t)sum * sum) / (8 * high)); } @@ -825,14 +835,15 @@ static inline uint32_t vpx_variance4x(const uint8_t *src_ptr, int src_stride, *sse = 0; + /* clang-format off */ __asm__ volatile ( "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp10] \n\t" MMI_L(%[tmp0], %[high], 0x00) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp6], %[ftmp6], %[ftmp6] \n\t" - "xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp6], %[ftmp6], %[ftmp6] \n\t" + "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" "1: \n\t" "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" @@ -845,7 +856,7 @@ static inline uint32_t vpx_variance4x(const uint8_t *src_ptr, int src_stride, MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) "bnez %[tmp0], 1b \n\t" - "dsrl %[ftmp9], %[ftmp6], %[ftmp10] \n\t" + "ssrld %[ftmp9], %[ftmp6], %[ftmp10] \n\t" "paddw %[ftmp9], %[ftmp9], %[ftmp6] \n\t" "swc1 %[ftmp9], 0x00(%[sse]) \n\t" @@ -856,7 +867,7 @@ static inline uint32_t vpx_variance4x(const uint8_t *src_ptr, int src_stride, "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" - "dsrl %[ftmp0], %[ftmp3], %[ftmp10] \n\t" + "ssrld %[ftmp0], %[ftmp3], %[ftmp10] \n\t" "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" "swc1 %[ftmp0], 0x00(%[sum]) \n\t" : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), @@ -872,6 +883,7 @@ static inline uint32_t vpx_variance4x(const uint8_t *src_ptr, int src_stride, [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) : "memory" ); + /* clang-format on */ return *sse - (((int64_t)sum * sum) / (4 * high)); } @@ -894,12 +906,13 @@ static inline uint32_t vpx_mse16x(const uint8_t *src_ptr, int src_stride, *sse = 0; + /* clang-format off */ __asm__ volatile ( "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp11] \n\t" MMI_L(%[tmp0], %[high], 0x00) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" "1: \n\t" VARIANCE_SSE_16 @@ -909,7 +922,7 @@ static inline uint32_t vpx_mse16x(const uint8_t *src_ptr, int src_stride, MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) "bnez %[tmp0], 1b \n\t" - "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" + "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" "swc1 %[ftmp9], 0x00(%[sse]) \n\t" : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), @@ -925,6 +938,7 @@ static inline uint32_t vpx_mse16x(const uint8_t *src_ptr, int src_stride, [high]"r"(&high), [sse]"r"(sse) : "memory" ); + /* clang-format on */ return *sse; } @@ -947,12 +961,13 @@ static inline uint32_t vpx_mse8x(const uint8_t *src_ptr, int src_stride, *sse = 0; + /* clang-format off */ __asm__ volatile ( "li %[tmp0], 0x20 \n\t" "mtc1 %[tmp0], %[ftmp11] \n\t" MMI_L(%[tmp0], %[high], 0x00) - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" "1: \n\t" VARIANCE_SSE_8 @@ -962,7 +977,7 @@ static inline uint32_t vpx_mse8x(const uint8_t *src_ptr, int src_stride, MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) "bnez %[tmp0], 1b \n\t" - "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" + "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" "swc1 %[ftmp9], 0x00(%[sse]) \n\t" : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), @@ -978,6 +993,7 @@ static inline uint32_t vpx_mse8x(const uint8_t *src_ptr, int src_stride, [high]"r"(&high), [sse]"r"(sse) : "memory" ); + /* clang-format on */ return *sse; } @@ -1021,22 +1037,39 @@ static inline void var_filter_block2d_bil_16x(const uint8_t *src_ptr, uint8_t *temp2_ptr = temp2; mips_reg l_counter = counter; double ftmp[15]; + double ff_ph_40, mask; + double filter_x0, filter_x1, filter_y0, filter_y1; mips_reg tmp[2]; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; - DECLARE_ALIGNED(8, const uint64_t, mask) = { 0x00ff00ff00ff00ffULL }; + uint64_t x0, x1, y0, y1, all; const uint8_t *filter_x = bilinear_filters[x_offset]; const uint8_t *filter_y = bilinear_filters[y_offset]; + x0 = (uint64_t)filter_x[0]; + x1 = (uint64_t)filter_x[1]; + y0 = (uint64_t)filter_y[0]; + y1 = (uint64_t)filter_y[1]; + all = x0 | x1 << 8 | y0 << 16 | y1 << 24; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + MMI_MTC1(%[all], %[ftmp14]) + "punpcklbh %[ftmp14], %[ftmp14], %[ftmp0] \n\t" + "pshufh %[filter_x0], %[ftmp14], %[ftmp0] \n\t" + MMI_LI(%[tmp0], 0x10) + MMI_MTC1(%[tmp0], %[mask]) + "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" + "pshufh %[filter_x1], %[ftmp14], %[ftmp0] \n\t" + "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" + "pshufh %[filter_y0], %[ftmp14], %[ftmp0] \n\t" + "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" + "pshufh %[filter_y1], %[ftmp14], %[ftmp0] \n\t" MMI_LI(%[tmp0], 0x07) MMI_MTC1(%[tmp0], %[ftmp14]) - "pshufh %[filter_x0], %[filter_x0], %[ftmp0] \n\t" - "pshufh %[filter_x1], %[filter_x1], %[ftmp0] \n\t" - "pshufh %[filter_y0], %[filter_y0], %[ftmp0] \n\t" - "pshufh %[filter_y1], %[filter_y1], %[ftmp0] \n\t" - + MMI_LI(%[tmp0], 0x0040004000400040) + MMI_MTC1(%[tmp0], %[ff_ph_40]) + MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) + MMI_MTC1(%[tmp0], %[mask]) // fdata3: fdata3[0] ~ fdata3[15] VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_A @@ -1072,15 +1105,13 @@ static inline void var_filter_block2d_bil_16x(const uint8_t *src_ptr, [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), [ftmp13] "=&f"(ftmp[13]), [ftmp14] "=&f"(ftmp[14]), [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), [temp2_ptr] "+&r"(temp2_ptr), - [counter]"+&r"(l_counter) - : [filter_x0] "f"((uint64_t)filter_x[0]), - [filter_x1] "f"((uint64_t)filter_x[1]), - [filter_y0] "f"((uint64_t)filter_y[0]), - [filter_y1] "f"((uint64_t)filter_y[1]), - [src_stride] "r"((mips_reg)src_stride), [ff_ph_40] "f"(ff_ph_40), - [mask] "f"(mask) + [counter]"+&r"(l_counter), [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), + [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), + [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) + : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) : "memory" ); + /* clang-format on */ } #define SUBPIX_VAR16XN(H) \ @@ -1105,19 +1136,38 @@ static inline void var_filter_block2d_bil_8x(const uint8_t *src_ptr, mips_reg l_counter = counter; double ftmp[15]; mips_reg tmp[2]; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; - DECLARE_ALIGNED(8, const uint64_t, mask) = { 0x00ff00ff00ff00ffULL }; + double ff_ph_40, mask; + uint64_t x0, x1, y0, y1, all; + double filter_x0, filter_x1, filter_y0, filter_y1; const uint8_t *filter_x = bilinear_filters[x_offset]; const uint8_t *filter_y = bilinear_filters[y_offset]; + x0 = (uint64_t)filter_x[0]; + x1 = (uint64_t)filter_x[1]; + y0 = (uint64_t)filter_y[0]; + y1 = (uint64_t)filter_y[1]; + all = x0 | x1 << 8 | y0 << 16 | y1 << 24; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + MMI_MTC1(%[all], %[ftmp14]) + "punpcklbh %[ftmp14], %[ftmp14], %[ftmp0] \n\t" + "pshufh %[filter_x0], %[ftmp14], %[ftmp0] \n\t" + MMI_LI(%[tmp0], 0x10) + MMI_MTC1(%[tmp0], %[mask]) + "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" + "pshufh %[filter_x1], %[ftmp14], %[ftmp0] \n\t" + "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" + "pshufh %[filter_y0], %[ftmp14], %[ftmp0] \n\t" + "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" + "pshufh %[filter_y1], %[ftmp14], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" MMI_LI(%[tmp0], 0x07) MMI_MTC1(%[tmp0], %[ftmp14]) - "pshufh %[filter_x0], %[filter_x0], %[ftmp0] \n\t" - "pshufh %[filter_x1], %[filter_x1], %[ftmp0] \n\t" - "pshufh %[filter_y0], %[filter_y0], %[ftmp0] \n\t" - "pshufh %[filter_y1], %[filter_y1], %[ftmp0] \n\t" + MMI_LI(%[tmp0], 0x0040004000400040) + MMI_MTC1(%[tmp0], %[ff_ph_40]) + MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) + MMI_MTC1(%[tmp0], %[mask]) // fdata3: fdata3[0] ~ fdata3[7] VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_A @@ -1154,15 +1204,13 @@ static inline void var_filter_block2d_bil_8x(const uint8_t *src_ptr, [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), [ftmp13] "=&f"(ftmp[13]), [ftmp14] "=&f"(ftmp[14]), [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), [temp2_ptr] "+&r"(temp2_ptr), - [counter]"+&r"(l_counter) - : [filter_x0] "f"((uint64_t)filter_x[0]), - [filter_x1] "f"((uint64_t)filter_x[1]), - [filter_y0] "f"((uint64_t)filter_y[0]), - [filter_y1] "f"((uint64_t)filter_y[1]), - [src_stride] "r"((mips_reg)src_stride), [ff_ph_40] "f"(ff_ph_40), - [mask] "f"(mask) + [counter]"+&r"(l_counter), [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), + [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), + [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) + : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) : "memory" ); + /* clang-format on */ } #define SUBPIX_VAR8XN(H) \ @@ -1188,19 +1236,38 @@ static inline void var_filter_block2d_bil_4x(const uint8_t *src_ptr, mips_reg l_counter = counter; double ftmp[7]; mips_reg tmp[2]; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; - DECLARE_ALIGNED(8, const uint64_t, mask) = { 0x00ff00ff00ff00ffULL }; + double ff_ph_40, mask; + uint64_t x0, x1, y0, y1, all; + double filter_x0, filter_x1, filter_y0, filter_y1; const uint8_t *filter_x = bilinear_filters[x_offset]; const uint8_t *filter_y = bilinear_filters[y_offset]; + x0 = (uint64_t)filter_x[0]; + x1 = (uint64_t)filter_x[1]; + y0 = (uint64_t)filter_y[0]; + y1 = (uint64_t)filter_y[1]; + all = x0 | x1 << 8 | y0 << 16 | y1 << 24; + /* clang-format off */ __asm__ volatile ( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + MMI_MTC1(%[all], %[ftmp6]) + "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" + "pshufh %[filter_x0], %[ftmp6], %[ftmp0] \n\t" + MMI_LI(%[tmp0], 0x10) + MMI_MTC1(%[tmp0], %[mask]) + "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" + "pshufh %[filter_x1], %[ftmp6], %[ftmp0] \n\t" + "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" + "pshufh %[filter_y0], %[ftmp6], %[ftmp0] \n\t" + "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" + "pshufh %[filter_y1], %[ftmp6], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" MMI_LI(%[tmp0], 0x07) MMI_MTC1(%[tmp0], %[ftmp6]) - "pshufh %[filter_x0], %[filter_x0], %[ftmp0] \n\t" - "pshufh %[filter_x1], %[filter_x1], %[ftmp0] \n\t" - "pshufh %[filter_y0], %[filter_y0], %[ftmp0] \n\t" - "pshufh %[filter_y1], %[filter_y1], %[ftmp0] \n\t" + MMI_LI(%[tmp0], 0x0040004000400040) + MMI_MTC1(%[tmp0], %[ff_ph_40]) + MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) + MMI_MTC1(%[tmp0], %[mask]) // fdata3: fdata3[0] ~ fdata3[3] VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_A @@ -1232,15 +1299,14 @@ static inline void var_filter_block2d_bil_4x(const uint8_t *src_ptr, : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), [ftmp6] "=&f"(ftmp[6]), [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), - [temp2_ptr] "+&r"(temp2_ptr), [counter]"+&r"(l_counter) - : [filter_x0] "f"((uint64_t)filter_x[0]), - [filter_x1] "f"((uint64_t)filter_x[1]), - [filter_y0] "f"((uint64_t)filter_y[0]), - [filter_y1] "f"((uint64_t)filter_y[1]), - [src_stride] "r"((mips_reg)src_stride), [ff_ph_40] "f"(ff_ph_40), - [mask] "f"(mask) + [temp2_ptr] "+&r"(temp2_ptr), [counter]"+&r"(l_counter), + [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), + [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), + [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) + : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) : "memory" ); + /* clang-format on */ } #define SUBPIX_VAR4XN(H) \ diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/vpx_convolve8_mmi.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/vpx_convolve8_mmi.c index ba9ceb866..cb7bca558 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/vpx_convolve8_mmi.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/mips/vpx_convolve8_mmi.c @@ -105,7 +105,7 @@ static void convolve_horiz_mmi(const uint8_t *src, ptrdiff_t src_stride, /* clang-format off */ __asm__ volatile( "move %[tmp1], %[width] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "gsldlc1 %[filter1], 0x03(%[filter]) \n\t" "gsldrc1 %[filter1], 0x00(%[filter]) \n\t" "gsldlc1 %[filter2], 0x0b(%[filter]) \n\t" @@ -178,7 +178,7 @@ static void convolve_vert_mmi(const uint8_t *src, ptrdiff_t src_stride, (void)y_step_q4; __asm__ volatile( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "gsldlc1 %[ftmp4], 0x03(%[filter]) \n\t" "gsldrc1 %[ftmp4], 0x00(%[filter]) \n\t" "gsldlc1 %[ftmp5], 0x0b(%[filter]) \n\t" @@ -271,7 +271,7 @@ static void convolve_avg_horiz_mmi(const uint8_t *src, ptrdiff_t src_stride, __asm__ volatile( "move %[tmp1], %[width] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "gsldlc1 %[filter1], 0x03(%[filter]) \n\t" "gsldrc1 %[filter1], 0x00(%[filter]) \n\t" "gsldlc1 %[filter2], 0x0b(%[filter]) \n\t" @@ -354,7 +354,7 @@ static void convolve_avg_vert_mmi(const uint8_t *src, ptrdiff_t src_stride, (void)y_step_q4; __asm__ volatile( - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "gsldlc1 %[ftmp4], 0x03(%[filter]) \n\t" "gsldrc1 %[ftmp4], 0x00(%[filter]) \n\t" "gsldlc1 %[ftmp5], 0x0b(%[filter]) \n\t" @@ -467,7 +467,7 @@ void vpx_convolve_avg_mmi(const uint8_t *src, ptrdiff_t src_stride, __asm__ volatile( "move %[tmp1], %[width] \n\t" - "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" + "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" "li %[tmp0], 0x10001 \n\t" MMI_MTC1(%[tmp0], %[ftmp3]) "punpcklhw %[ftmp3], %[ftmp3], %[ftmp3] \n\t" diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/add_noise_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/add_noise_sse2.asm index 80cced4ce..f51718cf9 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/add_noise_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/add_noise_sse2.asm @@ -16,7 +16,7 @@ SECTION .text ;void vpx_plane_add_noise_sse2(uint8_t *start, const int8_t *noise, ; int blackclamp, int whiteclamp, ; int width, int height, int pitch) -global sym(vpx_plane_add_noise_sse2) PRIVATE +globalsym(vpx_plane_add_noise_sse2) sym(vpx_plane_add_noise_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/deblock_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/deblock_sse2.asm index 9d8e5e3e0..b3af677d2 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/deblock_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/deblock_sse2.asm @@ -95,7 +95,7 @@ SECTION .text ; int *flimits, ; int size ;) -global sym(vpx_post_proc_down_and_across_mb_row_sse2) PRIVATE +globalsym(vpx_post_proc_down_and_across_mb_row_sse2) sym(vpx_post_proc_down_and_across_mb_row_sse2): push rbp mov rbp, rsp @@ -235,7 +235,7 @@ sym(vpx_post_proc_down_and_across_mb_row_sse2): ;void vpx_mbpost_proc_across_ip_sse2(unsigned char *src, ; int pitch, int rows, int cols,int flimit) -global sym(vpx_mbpost_proc_across_ip_sse2) PRIVATE +globalsym(vpx_mbpost_proc_across_ip_sse2) sym(vpx_mbpost_proc_across_ip_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm index a256a59ec..5bee51fa0 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm @@ -22,7 +22,7 @@ SECTION .text ; unsigned int * SSE, ; int * Sum ;) -global sym(vpx_highbd_calc16x16var_sse2) PRIVATE +globalsym(vpx_highbd_calc16x16var_sse2) sym(vpx_highbd_calc16x16var_sse2): push rbp mov rbp, rsp @@ -175,7 +175,7 @@ sym(vpx_highbd_calc16x16var_sse2): ; unsigned int * SSE, ; int * Sum ;) -global sym(vpx_highbd_calc8x8var_sse2) PRIVATE +globalsym(vpx_highbd_calc8x8var_sse2) sym(vpx_highbd_calc8x8var_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse3.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse3.asm index 175dcc089..acbd2e4fa 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse3.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse3.asm @@ -173,7 +173,7 @@ SECTION .text ; unsigned char *ref_ptr, ; int ref_stride, ; int *results) -global sym(vpx_sad16x16x3_sse3) PRIVATE +globalsym(vpx_sad16x16x3_sse3) sym(vpx_sad16x16x3_sse3): STACK_FRAME_CREATE_X3 @@ -215,7 +215,7 @@ sym(vpx_sad16x16x3_sse3): ; unsigned char *ref_ptr, ; int ref_stride, ; int *results) -global sym(vpx_sad16x8x3_sse3) PRIVATE +globalsym(vpx_sad16x8x3_sse3) sym(vpx_sad16x8x3_sse3): STACK_FRAME_CREATE_X3 @@ -253,7 +253,7 @@ sym(vpx_sad16x8x3_sse3): ; unsigned char *ref_ptr, ; int ref_stride, ; int *results) -global sym(vpx_sad8x16x3_sse3) PRIVATE +globalsym(vpx_sad8x16x3_sse3) sym(vpx_sad8x16x3_sse3): STACK_FRAME_CREATE_X3 @@ -282,7 +282,7 @@ sym(vpx_sad8x16x3_sse3): ; unsigned char *ref_ptr, ; int ref_stride, ; int *results) -global sym(vpx_sad8x8x3_sse3) PRIVATE +globalsym(vpx_sad8x8x3_sse3) sym(vpx_sad8x8x3_sse3): STACK_FRAME_CREATE_X3 @@ -307,7 +307,7 @@ sym(vpx_sad8x8x3_sse3): ; unsigned char *ref_ptr, ; int ref_stride, ; int *results) -global sym(vpx_sad4x4x3_sse3) PRIVATE +globalsym(vpx_sad4x4x3_sse3) sym(vpx_sad4x4x3_sse3): STACK_FRAME_CREATE_X3 diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse4.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse4.asm index 03999dfca..0818ed5f0 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse4.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_sse4.asm @@ -173,7 +173,7 @@ SECTION .text ; const unsigned char *ref_ptr, ; int ref_stride, ; unsigned short *sad_array); -global sym(vpx_sad16x16x8_sse4_1) PRIVATE +globalsym(vpx_sad16x16x8_sse4_1) sym(vpx_sad16x16x8_sse4_1): push rbp mov rbp, rsp @@ -214,7 +214,7 @@ sym(vpx_sad16x16x8_sse4_1): ; int ref_stride, ; unsigned short *sad_array ;); -global sym(vpx_sad16x8x8_sse4_1) PRIVATE +globalsym(vpx_sad16x8x8_sse4_1) sym(vpx_sad16x8x8_sse4_1): push rbp mov rbp, rsp @@ -251,7 +251,7 @@ sym(vpx_sad16x8x8_sse4_1): ; int ref_stride, ; unsigned short *sad_array ;); -global sym(vpx_sad8x8x8_sse4_1) PRIVATE +globalsym(vpx_sad8x8x8_sse4_1) sym(vpx_sad8x8x8_sse4_1): push rbp mov rbp, rsp @@ -288,7 +288,7 @@ sym(vpx_sad8x8x8_sse4_1): ; int ref_stride, ; unsigned short *sad_array ;); -global sym(vpx_sad8x16x8_sse4_1) PRIVATE +globalsym(vpx_sad8x16x8_sse4_1) sym(vpx_sad8x16x8_sse4_1): push rbp mov rbp, rsp @@ -329,7 +329,7 @@ sym(vpx_sad8x16x8_sse4_1): ; int ref_stride, ; unsigned short *sad_array ;); -global sym(vpx_sad4x4x8_sse4_1) PRIVATE +globalsym(vpx_sad4x4x8_sse4_1) sym(vpx_sad4x4x8_sse4_1): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_ssse3.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_ssse3.asm index 7cf93cf51..a5bc6d730 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_ssse3.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/sad_ssse3.asm @@ -154,7 +154,7 @@ SECTION .text ; unsigned char *ref_ptr, ; int ref_stride, ; int *results) -global sym(vpx_sad16x16x3_ssse3) PRIVATE +globalsym(vpx_sad16x16x3_ssse3) sym(vpx_sad16x16x3_ssse3): push rbp mov rbp, rsp @@ -267,7 +267,7 @@ sym(vpx_sad16x16x3_ssse3): ; unsigned char *ref_ptr, ; int ref_stride, ; int *results) -global sym(vpx_sad16x8x3_ssse3) PRIVATE +globalsym(vpx_sad16x8x3_ssse3) sym(vpx_sad16x8x3_ssse3): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm index 300fa8aab..41ffbb07e 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm @@ -64,7 +64,7 @@ SECTION .text ; or pavgb At this point this is just meant to be first pass for calculating ; all the parms needed for 16x16 ssim so we can play with dssim as distortion ; in mode selection code. -global sym(vpx_ssim_parms_16x16_sse2) PRIVATE +globalsym(vpx_ssim_parms_16x16_sse2) sym(vpx_ssim_parms_16x16_sse2): push rbp mov rbp, rsp @@ -154,7 +154,7 @@ sym(vpx_ssim_parms_16x16_sse2): ; or pavgb At this point this is just meant to be first pass for calculating ; all the parms needed for 16x16 ssim so we can play with dssim as distortion ; in mode selection code. -global sym(vpx_ssim_parms_8x8_sse2) PRIVATE +globalsym(vpx_ssim_parms_8x8_sse2) sym(vpx_ssim_parms_8x8_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/transpose_sse2.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/transpose_sse2.h index 6e07871b1..b4f1190d7 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/transpose_sse2.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/transpose_sse2.h @@ -16,7 +16,7 @@ #include "./vpx_config.h" static INLINE __m128i transpose_8bit_4x4(const __m128i *const in) { - // Unpack 16 bit elements. Goes from: + // Unpack 8 bit elements. Goes from: // in[0]: 00 01 02 03 // in[1]: 10 11 12 13 // in[2]: 20 21 22 23 @@ -27,7 +27,7 @@ static INLINE __m128i transpose_8bit_4x4(const __m128i *const in) { const __m128i a0 = _mm_unpacklo_epi8(in[0], in[1]); const __m128i a1 = _mm_unpacklo_epi8(in[2], in[3]); - // Unpack 32 bit elements resulting in: + // Unpack 16 bit elements resulting in: // 00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33 return _mm_unpacklo_epi16(a0, a1); } diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm index c57149657..fc301fb39 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm @@ -208,7 +208,7 @@ SECTION .text ; unsigned int output_height, ; short *filter ;) -global sym(vpx_highbd_filter_block1d4_v8_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d4_v8_sse2) sym(vpx_highbd_filter_block1d4_v8_sse2): push rbp mov rbp, rsp @@ -278,7 +278,7 @@ sym(vpx_highbd_filter_block1d4_v8_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_highbd_filter_block1d8_v8_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d8_v8_sse2) sym(vpx_highbd_filter_block1d8_v8_sse2): push rbp mov rbp, rsp @@ -337,7 +337,7 @@ sym(vpx_highbd_filter_block1d8_v8_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_highbd_filter_block1d16_v8_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d16_v8_sse2) sym(vpx_highbd_filter_block1d16_v8_sse2): push rbp mov rbp, rsp @@ -391,7 +391,7 @@ sym(vpx_highbd_filter_block1d16_v8_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d4_v8_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d4_v8_avg_sse2) sym(vpx_highbd_filter_block1d4_v8_avg_sse2): push rbp mov rbp, rsp @@ -452,7 +452,7 @@ sym(vpx_highbd_filter_block1d4_v8_avg_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d8_v8_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d8_v8_avg_sse2) sym(vpx_highbd_filter_block1d8_v8_avg_sse2): push rbp mov rbp, rsp @@ -501,7 +501,7 @@ sym(vpx_highbd_filter_block1d8_v8_avg_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d16_v8_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d16_v8_avg_sse2) sym(vpx_highbd_filter_block1d16_v8_avg_sse2): push rbp mov rbp, rsp @@ -563,7 +563,7 @@ sym(vpx_highbd_filter_block1d16_v8_avg_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_highbd_filter_block1d4_h8_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d4_h8_sse2) sym(vpx_highbd_filter_block1d4_h8_sse2): push rbp mov rbp, rsp @@ -638,7 +638,7 @@ sym(vpx_highbd_filter_block1d4_h8_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_highbd_filter_block1d8_h8_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d8_h8_sse2) sym(vpx_highbd_filter_block1d8_h8_sse2): push rbp mov rbp, rsp @@ -704,7 +704,7 @@ sym(vpx_highbd_filter_block1d8_h8_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_highbd_filter_block1d16_h8_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d16_h8_sse2) sym(vpx_highbd_filter_block1d16_h8_sse2): push rbp mov rbp, rsp @@ -772,7 +772,7 @@ sym(vpx_highbd_filter_block1d16_h8_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d4_h8_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d4_h8_avg_sse2) sym(vpx_highbd_filter_block1d4_h8_avg_sse2): push rbp mov rbp, rsp @@ -838,7 +838,7 @@ sym(vpx_highbd_filter_block1d4_h8_avg_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d8_h8_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d8_h8_avg_sse2) sym(vpx_highbd_filter_block1d8_h8_avg_sse2): push rbp mov rbp, rsp @@ -895,7 +895,7 @@ sym(vpx_highbd_filter_block1d8_h8_avg_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d16_h8_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d16_h8_avg_sse2) sym(vpx_highbd_filter_block1d16_h8_avg_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm index ec18d370e..bd51c75bc 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm @@ -173,7 +173,7 @@ SECTION .text -global sym(vpx_highbd_filter_block1d4_v2_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d4_v2_sse2) sym(vpx_highbd_filter_block1d4_v2_sse2): push rbp mov rbp, rsp @@ -198,7 +198,7 @@ sym(vpx_highbd_filter_block1d4_v2_sse2): ret %if VPX_ARCH_X86_64 -global sym(vpx_highbd_filter_block1d8_v2_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d8_v2_sse2) sym(vpx_highbd_filter_block1d8_v2_sse2): push rbp mov rbp, rsp @@ -224,7 +224,7 @@ sym(vpx_highbd_filter_block1d8_v2_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d16_v2_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d16_v2_sse2) sym(vpx_highbd_filter_block1d16_v2_sse2): push rbp mov rbp, rsp @@ -253,7 +253,7 @@ sym(vpx_highbd_filter_block1d16_v2_sse2): ret %endif -global sym(vpx_highbd_filter_block1d4_v2_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d4_v2_avg_sse2) sym(vpx_highbd_filter_block1d4_v2_avg_sse2): push rbp mov rbp, rsp @@ -278,7 +278,7 @@ sym(vpx_highbd_filter_block1d4_v2_avg_sse2): ret %if VPX_ARCH_X86_64 -global sym(vpx_highbd_filter_block1d8_v2_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d8_v2_avg_sse2) sym(vpx_highbd_filter_block1d8_v2_avg_sse2): push rbp mov rbp, rsp @@ -304,7 +304,7 @@ sym(vpx_highbd_filter_block1d8_v2_avg_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d16_v2_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d16_v2_avg_sse2) sym(vpx_highbd_filter_block1d16_v2_avg_sse2): push rbp mov rbp, rsp @@ -333,7 +333,7 @@ sym(vpx_highbd_filter_block1d16_v2_avg_sse2): ret %endif -global sym(vpx_highbd_filter_block1d4_h2_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d4_h2_sse2) sym(vpx_highbd_filter_block1d4_h2_sse2): push rbp mov rbp, rsp @@ -359,7 +359,7 @@ sym(vpx_highbd_filter_block1d4_h2_sse2): ret %if VPX_ARCH_X86_64 -global sym(vpx_highbd_filter_block1d8_h2_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d8_h2_sse2) sym(vpx_highbd_filter_block1d8_h2_sse2): push rbp mov rbp, rsp @@ -385,7 +385,7 @@ sym(vpx_highbd_filter_block1d8_h2_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d16_h2_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d16_h2_sse2) sym(vpx_highbd_filter_block1d16_h2_sse2): push rbp mov rbp, rsp @@ -414,7 +414,7 @@ sym(vpx_highbd_filter_block1d16_h2_sse2): ret %endif -global sym(vpx_highbd_filter_block1d4_h2_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d4_h2_avg_sse2) sym(vpx_highbd_filter_block1d4_h2_avg_sse2): push rbp mov rbp, rsp @@ -440,7 +440,7 @@ sym(vpx_highbd_filter_block1d4_h2_avg_sse2): ret %if VPX_ARCH_X86_64 -global sym(vpx_highbd_filter_block1d8_h2_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d8_h2_avg_sse2) sym(vpx_highbd_filter_block1d8_h2_avg_sse2): push rbp mov rbp, rsp @@ -466,7 +466,7 @@ sym(vpx_highbd_filter_block1d8_h2_avg_sse2): pop rbp ret -global sym(vpx_highbd_filter_block1d16_h2_avg_sse2) PRIVATE +globalsym(vpx_highbd_filter_block1d16_h2_avg_sse2) sym(vpx_highbd_filter_block1d16_h2_avg_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm index 8497e1721..c8455e13a 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm @@ -187,7 +187,7 @@ SECTION .text ; unsigned int output_height, ; short *filter ;) -global sym(vpx_filter_block1d4_v8_sse2) PRIVATE +globalsym(vpx_filter_block1d4_v8_sse2) sym(vpx_filter_block1d4_v8_sse2): push rbp mov rbp, rsp @@ -254,7 +254,7 @@ sym(vpx_filter_block1d4_v8_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_filter_block1d8_v8_sse2) PRIVATE +globalsym(vpx_filter_block1d8_v8_sse2) sym(vpx_filter_block1d8_v8_sse2): push rbp mov rbp, rsp @@ -313,7 +313,7 @@ sym(vpx_filter_block1d8_v8_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_filter_block1d16_v8_sse2) PRIVATE +globalsym(vpx_filter_block1d16_v8_sse2) sym(vpx_filter_block1d16_v8_sse2): push rbp mov rbp, rsp @@ -367,7 +367,7 @@ sym(vpx_filter_block1d16_v8_sse2): pop rbp ret -global sym(vpx_filter_block1d4_v8_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d4_v8_avg_sse2) sym(vpx_filter_block1d4_v8_avg_sse2): push rbp mov rbp, rsp @@ -425,7 +425,7 @@ sym(vpx_filter_block1d4_v8_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d8_v8_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d8_v8_avg_sse2) sym(vpx_filter_block1d8_v8_avg_sse2): push rbp mov rbp, rsp @@ -474,7 +474,7 @@ sym(vpx_filter_block1d8_v8_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d16_v8_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d16_v8_avg_sse2) sym(vpx_filter_block1d16_v8_avg_sse2): push rbp mov rbp, rsp @@ -536,7 +536,7 @@ sym(vpx_filter_block1d16_v8_avg_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_filter_block1d4_h8_sse2) PRIVATE +globalsym(vpx_filter_block1d4_h8_sse2) sym(vpx_filter_block1d4_h8_sse2): push rbp mov rbp, rsp @@ -610,7 +610,7 @@ sym(vpx_filter_block1d4_h8_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_filter_block1d8_h8_sse2) PRIVATE +globalsym(vpx_filter_block1d8_h8_sse2) sym(vpx_filter_block1d8_h8_sse2): push rbp mov rbp, rsp @@ -685,7 +685,7 @@ sym(vpx_filter_block1d8_h8_sse2): ; unsigned int output_height, ; short *filter ;) -global sym(vpx_filter_block1d16_h8_sse2) PRIVATE +globalsym(vpx_filter_block1d16_h8_sse2) sym(vpx_filter_block1d16_h8_sse2): push rbp mov rbp, rsp @@ -771,7 +771,7 @@ sym(vpx_filter_block1d16_h8_sse2): pop rbp ret -global sym(vpx_filter_block1d4_h8_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d4_h8_avg_sse2) sym(vpx_filter_block1d4_h8_avg_sse2): push rbp mov rbp, rsp @@ -836,7 +836,7 @@ sym(vpx_filter_block1d4_h8_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d8_h8_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d8_h8_avg_sse2) sym(vpx_filter_block1d8_h8_avg_sse2): push rbp mov rbp, rsp @@ -902,7 +902,7 @@ sym(vpx_filter_block1d8_h8_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d16_h8_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d16_h8_avg_sse2) sym(vpx_filter_block1d16_h8_avg_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm index 6d79492e4..65790b1c2 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm @@ -133,7 +133,7 @@ SECTION .text -global sym(vpx_filter_block1d4_v2_sse2) PRIVATE +globalsym(vpx_filter_block1d4_v2_sse2) sym(vpx_filter_block1d4_v2_sse2): push rbp mov rbp, rsp @@ -157,7 +157,7 @@ sym(vpx_filter_block1d4_v2_sse2): pop rbp ret -global sym(vpx_filter_block1d8_v2_sse2) PRIVATE +globalsym(vpx_filter_block1d8_v2_sse2) sym(vpx_filter_block1d8_v2_sse2): push rbp mov rbp, rsp @@ -183,7 +183,7 @@ sym(vpx_filter_block1d8_v2_sse2): pop rbp ret -global sym(vpx_filter_block1d16_v2_sse2) PRIVATE +globalsym(vpx_filter_block1d16_v2_sse2) sym(vpx_filter_block1d16_v2_sse2): push rbp mov rbp, rsp @@ -211,7 +211,7 @@ sym(vpx_filter_block1d16_v2_sse2): pop rbp ret -global sym(vpx_filter_block1d4_v2_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d4_v2_avg_sse2) sym(vpx_filter_block1d4_v2_avg_sse2): push rbp mov rbp, rsp @@ -235,7 +235,7 @@ sym(vpx_filter_block1d4_v2_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d8_v2_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d8_v2_avg_sse2) sym(vpx_filter_block1d8_v2_avg_sse2): push rbp mov rbp, rsp @@ -261,7 +261,7 @@ sym(vpx_filter_block1d8_v2_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d16_v2_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d16_v2_avg_sse2) sym(vpx_filter_block1d16_v2_avg_sse2): push rbp mov rbp, rsp @@ -289,7 +289,7 @@ sym(vpx_filter_block1d16_v2_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d4_h2_sse2) PRIVATE +globalsym(vpx_filter_block1d4_h2_sse2) sym(vpx_filter_block1d4_h2_sse2): push rbp mov rbp, rsp @@ -314,7 +314,7 @@ sym(vpx_filter_block1d4_h2_sse2): pop rbp ret -global sym(vpx_filter_block1d8_h2_sse2) PRIVATE +globalsym(vpx_filter_block1d8_h2_sse2) sym(vpx_filter_block1d8_h2_sse2): push rbp mov rbp, rsp @@ -341,7 +341,7 @@ sym(vpx_filter_block1d8_h2_sse2): pop rbp ret -global sym(vpx_filter_block1d16_h2_sse2) PRIVATE +globalsym(vpx_filter_block1d16_h2_sse2) sym(vpx_filter_block1d16_h2_sse2): push rbp mov rbp, rsp @@ -369,7 +369,7 @@ sym(vpx_filter_block1d16_h2_sse2): pop rbp ret -global sym(vpx_filter_block1d4_h2_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d4_h2_avg_sse2) sym(vpx_filter_block1d4_h2_avg_sse2): push rbp mov rbp, rsp @@ -394,7 +394,7 @@ sym(vpx_filter_block1d4_h2_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d8_h2_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d8_h2_avg_sse2) sym(vpx_filter_block1d8_h2_avg_sse2): push rbp mov rbp, rsp @@ -421,7 +421,7 @@ sym(vpx_filter_block1d8_h2_avg_sse2): pop rbp ret -global sym(vpx_filter_block1d16_h2_avg_sse2) PRIVATE +globalsym(vpx_filter_block1d16_h2_avg_sse2) sym(vpx_filter_block1d16_h2_avg_sse2): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm index 8c9c817be..32e3cd3d9 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm @@ -107,7 +107,7 @@ SECTION .text -global sym(vpx_filter_block1d4_v2_ssse3) PRIVATE +globalsym(vpx_filter_block1d4_v2_ssse3) sym(vpx_filter_block1d4_v2_ssse3): push rbp mov rbp, rsp @@ -131,7 +131,7 @@ sym(vpx_filter_block1d4_v2_ssse3): pop rbp ret -global sym(vpx_filter_block1d8_v2_ssse3) PRIVATE +globalsym(vpx_filter_block1d8_v2_ssse3) sym(vpx_filter_block1d8_v2_ssse3): push rbp mov rbp, rsp @@ -157,7 +157,7 @@ sym(vpx_filter_block1d8_v2_ssse3): pop rbp ret -global sym(vpx_filter_block1d16_v2_ssse3) PRIVATE +globalsym(vpx_filter_block1d16_v2_ssse3) sym(vpx_filter_block1d16_v2_ssse3): push rbp mov rbp, rsp @@ -184,7 +184,7 @@ sym(vpx_filter_block1d16_v2_ssse3): pop rbp ret -global sym(vpx_filter_block1d4_v2_avg_ssse3) PRIVATE +globalsym(vpx_filter_block1d4_v2_avg_ssse3) sym(vpx_filter_block1d4_v2_avg_ssse3): push rbp mov rbp, rsp @@ -208,7 +208,7 @@ sym(vpx_filter_block1d4_v2_avg_ssse3): pop rbp ret -global sym(vpx_filter_block1d8_v2_avg_ssse3) PRIVATE +globalsym(vpx_filter_block1d8_v2_avg_ssse3) sym(vpx_filter_block1d8_v2_avg_ssse3): push rbp mov rbp, rsp @@ -234,7 +234,7 @@ sym(vpx_filter_block1d8_v2_avg_ssse3): pop rbp ret -global sym(vpx_filter_block1d16_v2_avg_ssse3) PRIVATE +globalsym(vpx_filter_block1d16_v2_avg_ssse3) sym(vpx_filter_block1d16_v2_avg_ssse3): push rbp mov rbp, rsp @@ -261,7 +261,7 @@ sym(vpx_filter_block1d16_v2_avg_ssse3): pop rbp ret -global sym(vpx_filter_block1d4_h2_ssse3) PRIVATE +globalsym(vpx_filter_block1d4_h2_ssse3) sym(vpx_filter_block1d4_h2_ssse3): push rbp mov rbp, rsp @@ -286,7 +286,7 @@ sym(vpx_filter_block1d4_h2_ssse3): pop rbp ret -global sym(vpx_filter_block1d8_h2_ssse3) PRIVATE +globalsym(vpx_filter_block1d8_h2_ssse3) sym(vpx_filter_block1d8_h2_ssse3): push rbp mov rbp, rsp @@ -313,7 +313,7 @@ sym(vpx_filter_block1d8_h2_ssse3): pop rbp ret -global sym(vpx_filter_block1d16_h2_ssse3) PRIVATE +globalsym(vpx_filter_block1d16_h2_ssse3) sym(vpx_filter_block1d16_h2_ssse3): push rbp mov rbp, rsp @@ -340,7 +340,7 @@ sym(vpx_filter_block1d16_h2_ssse3): pop rbp ret -global sym(vpx_filter_block1d4_h2_avg_ssse3) PRIVATE +globalsym(vpx_filter_block1d4_h2_avg_ssse3) sym(vpx_filter_block1d4_h2_avg_ssse3): push rbp mov rbp, rsp @@ -365,7 +365,7 @@ sym(vpx_filter_block1d4_h2_avg_ssse3): pop rbp ret -global sym(vpx_filter_block1d8_h2_avg_ssse3) PRIVATE +globalsym(vpx_filter_block1d8_h2_avg_ssse3) sym(vpx_filter_block1d8_h2_avg_ssse3): push rbp mov rbp, rsp @@ -392,7 +392,7 @@ sym(vpx_filter_block1d8_h2_avg_ssse3): pop rbp ret -global sym(vpx_filter_block1d16_h2_avg_ssse3) PRIVATE +globalsym(vpx_filter_block1d16_h2_avg_ssse3) sym(vpx_filter_block1d16_h2_avg_ssse3): push rbp mov rbp, rsp diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/asmdefs_mmi.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/asmdefs_mmi.h index 28355bf9f..400a51cc3 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/asmdefs_mmi.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/asmdefs_mmi.h @@ -34,7 +34,7 @@ "ld " #reg ", " #bias "(" #addr ") \n\t" #define MMI_SRL(reg1, reg2, shift) \ - "dsrl " #reg1 ", " #reg2 ", " #shift " \n\t" + "ssrld " #reg1 ", " #reg2 ", " #shift " \n\t" #define MMI_SLL(reg1, reg2, shift) \ "dsll " #reg1 ", " #reg2 ", " #shift " \n\t" @@ -63,7 +63,7 @@ "lw " #reg ", " #bias "(" #addr ") \n\t" #define MMI_SRL(reg1, reg2, shift) \ - "srl " #reg1 ", " #reg2 ", " #shift " \n\t" + "ssrlw " #reg1 ", " #reg2 ", " #shift " \n\t" #define MMI_SLL(reg1, reg2, shift) \ "sll " #reg1 ", " #reg2 ", " #shift " \n\t" diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/emms_mmx.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/emms_mmx.asm index 9f33590a2..b31b25ebd 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/emms_mmx.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/emms_mmx.asm @@ -12,7 +12,7 @@ %include "vpx_ports/x86_abi_support.asm" section .text -global sym(vpx_clear_system_state) PRIVATE +globalsym(vpx_clear_system_state) sym(vpx_clear_system_state): emms ret diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/float_control_word.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/float_control_word.asm index 256dae084..bb75b7a31 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/float_control_word.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/float_control_word.asm @@ -14,7 +14,7 @@ section .text %if LIBVPX_YASM_WIN64 -global sym(vpx_winx64_fldcw) PRIVATE +globalsym(vpx_winx64_fldcw) sym(vpx_winx64_fldcw): sub rsp, 8 mov [rsp], rcx ; win x64 specific @@ -23,7 +23,7 @@ sym(vpx_winx64_fldcw): ret -global sym(vpx_winx64_fstcw) PRIVATE +globalsym(vpx_winx64_fstcw) sym(vpx_winx64_fstcw): sub rsp, 8 fstcw [rsp] diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_null.cc b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/mips.h similarity index 52% rename from TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_null.cc rename to TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/mips.h index 6b1ccb322..bdc7525f7 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_null.cc +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/mips.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2020 The WebM 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 @@ -8,14 +8,20 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/desktop_capture/desktop_capturer.h" +#ifndef VPX_PORTS_MIPS_H_ +#define VPX_PORTS_MIPS_H_ -namespace webrtc { +#ifdef __cplusplus +extern "C" { +#endif -// static -std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( - const DesktopCaptureOptions& options) { - return nullptr; -} +#define HAS_MMI 0x01 +#define HAS_MSA 0x02 -} // namespace webrtc +int mips_cpu_caps(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VPX_PORTS_MIPS_H_ diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/mips_cpudetect.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/mips_cpudetect.c new file mode 100644 index 000000000..e0eca2d48 --- /dev/null +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/mips_cpudetect.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 The WebM 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 +#include +#include "./vpx_config.h" +#include "vpx_ports/mips.h" + +#if CONFIG_RUNTIME_CPU_DETECT +#if defined(__mips__) && defined(__linux__) +int mips_cpu_caps(void) { + char cpuinfo_line[512]; + int flag = 0x0; + FILE *f = fopen("/proc/cpuinfo", "r"); + if (!f) { + // Assume nothing if /proc/cpuinfo is unavailable. + // This will occur for Chrome sandbox for Pepper or Render process. + return 0; + } + while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { + if (memcmp(cpuinfo_line, "cpu model", 9) == 0) { + // Workaround early kernel without mmi in ASEs line. + if (strstr(cpuinfo_line, "Loongson-3")) { + flag |= HAS_MMI; + } else if (strstr(cpuinfo_line, "Loongson-2K")) { + flag |= HAS_MMI | HAS_MSA; + } + } + if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) { + if (strstr(cpuinfo_line, "loongson-mmi") && + strstr(cpuinfo_line, "loongson-ext")) { + flag |= HAS_MMI; + } + if (strstr(cpuinfo_line, "msa")) { + flag |= HAS_MSA; + } + // ASEs is the last line, so we can break here. + break; + } + } + fclose(f); + return flag; +} +#else /* end __mips__ && __linux__ */ +#error \ + "--enable-runtime-cpu-detect selected, but no CPU detection method " \ +"available for your platform. Reconfigure with --disable-runtime-cpu-detect." +#endif +#else /* end CONFIG_RUNTIME_CPU_DETECT */ +int mips_cpu_caps(void) { return 0; } +#endif diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/vpx_ports.mk b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/vpx_ports.mk index 233177369..e5001be49 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/vpx_ports.mk +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/vpx_ports.mk @@ -42,6 +42,9 @@ PORTS_SRCS-$(VPX_ARCH_ARM) += arm.h PORTS_SRCS-$(VPX_ARCH_PPC) += ppc_cpudetect.c PORTS_SRCS-$(VPX_ARCH_PPC) += ppc.h +PORTS_SRCS-$(VPX_ARCH_MIPS) += mips_cpudetect.c +PORTS_SRCS-$(VPX_ARCH_MIPS) += mips.h + ifeq ($(VPX_ARCH_MIPS), yes) PORTS_SRCS-yes += asmdefs_mmi.h endif diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/x86_abi_support.asm b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/x86_abi_support.asm index 7e1230ba3..6b2d6b968 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/x86_abi_support.asm +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpx_ports/x86_abi_support.asm @@ -16,6 +16,17 @@ ; In general, we make the source use 64 bit syntax, then twiddle with it using ; the preprocessor to get the 32 bit syntax on 32 bit platforms. ; +%ifidn __OUTPUT_FORMAT__,elf32 +%define ABI_IS_32BIT 1 +%elifidn __OUTPUT_FORMAT__,macho32 +%define ABI_IS_32BIT 1 +%elifidn __OUTPUT_FORMAT__,win32 +%define ABI_IS_32BIT 1 +%elifidn __OUTPUT_FORMAT__,aout +%define ABI_IS_32BIT 1 +%else +%define ABI_IS_32BIT 0 +%endif %if ABI_IS_32BIT %define rax eax @@ -78,34 +89,51 @@ %define LIBVPX_YASM_WIN64 0 %endif +; Declare groups of platforms +%ifidn __OUTPUT_FORMAT__,elf32 + %define LIBVPX_ELF 1 +%elifidn __OUTPUT_FORMAT__,elfx32 + %define LIBVPX_ELF 1 +%elifidn __OUTPUT_FORMAT__,elf64 + %define LIBVPX_ELF 1 +%else + %define LIBVPX_ELF 0 +%endif + +%ifidn __OUTPUT_FORMAT__,macho32 + %define LIBVPX_MACHO 1 +%elifidn __OUTPUT_FORMAT__,macho64 + %define LIBVPX_MACHO 1 +%else + %define LIBVPX_MACHO 0 +%endif + ; sym() ; Return the proper symbol name for the target ABI. ; ; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols ; with C linkage be prefixed with an underscore. ; -%ifidn __OUTPUT_FORMAT__,elf32 -%define sym(x) x -%elifidn __OUTPUT_FORMAT__,elf64 -%define sym(x) x -%elifidn __OUTPUT_FORMAT__,elfx32 -%define sym(x) x -%elif LIBVPX_YASM_WIN64 -%define sym(x) x +%if LIBVPX_ELF || LIBVPX_YASM_WIN64 + %define sym(x) x %else -%define sym(x) _ %+ x + ; Mach-O / COFF + %define sym(x) _ %+ x %endif -; PRIVATE -; Macro for the attribute to hide a global symbol for the target ABI. -; This is only active if CHROMIUM is defined. +; globalsym() +; Return a global declaration with the proper decoration for the target ABI. ; -; Chromium doesn't like exported global symbols due to symbol clashing with -; plugins among other things. +; When CHROMIUM is defined, include attributes to hide the symbol from the +; global namespace. ; -; Requires Chromium's patched copy of yasm: -; http://src.chromium.org/viewvc/chrome?view=rev&revision=73761 -; http://www.tortall.net/projects/yasm/ticket/236 +; Chromium doesn't like exported global symbols due to symbol clashing with +; plugins among other things. +; +; Requires Chromium's patched copy of yasm: +; http://src.chromium.org/viewvc/chrome?view=rev&revision=73761 +; http://www.tortall.net/projects/yasm/ticket/236 +; or nasm > 2.14. ; %ifdef CHROMIUM %ifdef __NASM_VER__ @@ -115,19 +143,16 @@ %endif %endif - %ifidn __OUTPUT_FORMAT__,elf32 - %define PRIVATE :hidden - %elifidn __OUTPUT_FORMAT__,elf64 - %define PRIVATE :hidden - %elifidn __OUTPUT_FORMAT__,elfx32 - %define PRIVATE :hidden - %elif LIBVPX_YASM_WIN64 - %define PRIVATE + %if LIBVPX_ELF + %define globalsym(x) global sym(x) %+ :function hidden + %elif LIBVPX_MACHO + %define globalsym(x) global sym(x) %+ :private_extern %else - %define PRIVATE :private_extern + ; COFF / PE32+ + %define globalsym(x) global sym(x) %endif %else - %define PRIVATE + %define globalsym(x) global sym(x) %endif ; arg() diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpxenc.c b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpxenc.c index 50c36bedd..5d7546eb2 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpxenc.c +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpxenc.c @@ -95,6 +95,8 @@ static const arg_def_t debugmode = ARG_DEF("D", "debug", 0, "Debug mode (makes output deterministic)"); static const arg_def_t outputfile = ARG_DEF("o", "output", 1, "Output filename"); +static const arg_def_t use_nv12 = + ARG_DEF(NULL, "nv12", 0, "Input file is NV12 "); static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, "Input file is YV12 "); static const arg_def_t use_i420 = @@ -220,7 +222,8 @@ static const arg_def_t error_resilient = static const arg_def_t lag_in_frames = ARG_DEF(NULL, "lag-in-frames", 1, "Max number of frames to lag"); -static const arg_def_t *global_args[] = { &use_yv12, +static const arg_def_t *global_args[] = { &use_nv12, + &use_yv12, &use_i420, &use_i422, &use_i444, @@ -462,6 +465,13 @@ static const arg_def_t target_level = ARG_DEF( static const arg_def_t row_mt = ARG_DEF(NULL, "row-mt", 1, "Enable row based non-deterministic multi-threading in VP9"); + +static const arg_def_t disable_loopfilter = + ARG_DEF(NULL, "disable-loopfilter", 1, + "Control Loopfilter in VP9\n" + "0: Loopfilter on for all frames (default)\n" + "1: Loopfilter off for non reference frames\n" + "2: Loopfilter off for all frames"); #endif #if CONFIG_VP9_ENCODER @@ -492,6 +502,10 @@ static const arg_def_t *vp9_args[] = { &cpu_used_vp9, &max_gf_interval, &target_level, &row_mt, + &disable_loopfilter, +// NOTE: The entries above have a corresponding entry in vp9_arg_ctrl_map. The +// entries below do not have a corresponding entry in vp9_arg_ctrl_map. They +// must be listed at the end of vp9_args. #if CONFIG_VP9_HIGHBITDEPTH &bitdeptharg, &inbitdeptharg, @@ -524,6 +538,7 @@ static const int vp9_arg_ctrl_map[] = { VP8E_SET_CPUUSED, VP9E_SET_MAX_GF_INTERVAL, VP9E_SET_TARGET_LEVEL, VP9E_SET_ROW_MT, + VP9E_SET_DISABLE_LOOPFILTER, 0 }; #endif @@ -696,6 +711,8 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { global->deadline = VPX_DL_REALTIME; else if (arg_match(&arg, &use_yv12, argi)) global->color_type = YV12; + else if (arg_match(&arg, &use_nv12, argi)) + global->color_type = NV12; else if (arg_match(&arg, &use_i420, argi)) global->color_type = I420; else if (arg_match(&arg, &use_i422, argi)) @@ -1642,6 +1659,7 @@ int main(int argc, const char **argv_) { case I444: input.fmt = VPX_IMG_FMT_I444; break; case I440: input.fmt = VPX_IMG_FMT_I440; break; case YV12: input.fmt = VPX_IMG_FMT_YV12; break; + case NV12: input.fmt = VPX_IMG_FMT_NV12; break; } { diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpxenc.h b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpxenc.h index b780aedca..be54840f7 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpxenc.h +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/vpxenc.h @@ -28,6 +28,7 @@ typedef enum { I444, // 4:4:4 8+ bit-depth I440, // 4:4:0 8+ bit-depth YV12, // 4:2:0 with uv flipped, only 8-bit depth + NV12, // 4:2:0 with uv interleaved } ColorInputType; struct VpxInterface; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/webmdec.cc b/TMessagesProj/jni/third_party/libvpx/source/libvpx/webmdec.cc index d609075a9..68c6f4782 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/webmdec.cc +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/webmdec.cc @@ -19,25 +19,25 @@ namespace { void reset(struct WebmInputContext *const webm_ctx) { - if (webm_ctx->reader != NULL) { + if (webm_ctx->reader != nullptr) { mkvparser::MkvReader *const reader = reinterpret_cast(webm_ctx->reader); delete reader; } - if (webm_ctx->segment != NULL) { + if (webm_ctx->segment != nullptr) { mkvparser::Segment *const segment = reinterpret_cast(webm_ctx->segment); delete segment; } - if (webm_ctx->buffer != NULL) { + if (webm_ctx->buffer != nullptr) { delete[] webm_ctx->buffer; } - webm_ctx->reader = NULL; - webm_ctx->segment = NULL; - webm_ctx->buffer = NULL; - webm_ctx->cluster = NULL; - webm_ctx->block_entry = NULL; - webm_ctx->block = NULL; + webm_ctx->reader = nullptr; + webm_ctx->segment = nullptr; + webm_ctx->buffer = nullptr; + webm_ctx->cluster = nullptr; + webm_ctx->block_entry = nullptr; + webm_ctx->block = nullptr; webm_ctx->block_frame_index = 0; webm_ctx->video_track_index = 0; webm_ctx->timestamp_ns = 0; @@ -84,7 +84,7 @@ int file_is_webm(struct WebmInputContext *webm_ctx, } const mkvparser::Tracks *const tracks = segment->GetTracks(); - const mkvparser::VideoTrack *video_track = NULL; + const mkvparser::VideoTrack *video_track = nullptr; for (unsigned long i = 0; i < tracks->GetTracksCount(); ++i) { const mkvparser::Track *const track = tracks->GetTrackByIndex(i); if (track->GetType() == mkvparser::Track::kVideo) { @@ -94,7 +94,7 @@ int file_is_webm(struct WebmInputContext *webm_ctx, } } - if (video_track == NULL || video_track->GetCodecId() == NULL) { + if (video_track == nullptr || video_track->GetCodecId() == nullptr) { rewind_and_reset(webm_ctx, vpx_ctx); return 0; } @@ -137,12 +137,12 @@ int webm_read_frame(struct WebmInputContext *webm_ctx, uint8_t **buffer, do { long status = 0; bool get_new_block = false; - if (block_entry == NULL && !block_entry_eos) { + if (block_entry == nullptr && !block_entry_eos) { status = cluster->GetFirst(block_entry); get_new_block = true; } else if (block_entry_eos || block_entry->EOS()) { cluster = segment->GetNext(cluster); - if (cluster == NULL || cluster->EOS()) { + if (cluster == nullptr || cluster->EOS()) { *buffer_size = 0; webm_ctx->reached_eos = 1; return 1; @@ -150,22 +150,22 @@ int webm_read_frame(struct WebmInputContext *webm_ctx, uint8_t **buffer, status = cluster->GetFirst(block_entry); block_entry_eos = false; get_new_block = true; - } else if (block == NULL || + } else if (block == nullptr || webm_ctx->block_frame_index == block->GetFrameCount() || block->GetTrackNumber() != webm_ctx->video_track_index) { status = cluster->GetNext(block_entry, block_entry); - if (block_entry == NULL || block_entry->EOS()) { + if (block_entry == nullptr || block_entry->EOS()) { block_entry_eos = true; continue; } get_new_block = true; } - if (status || block_entry == NULL) { + if (status || block_entry == nullptr) { return -1; } if (get_new_block) { block = block_entry->GetBlock(); - if (block == NULL) return -1; + if (block == nullptr) return -1; webm_ctx->block_frame_index = 0; } } while (block_entry_eos || @@ -181,7 +181,7 @@ int webm_read_frame(struct WebmInputContext *webm_ctx, uint8_t **buffer, if (frame.len > static_cast(*buffer_size)) { delete[] * buffer; *buffer = new uint8_t[frame.len]; - if (*buffer == NULL) { + if (*buffer == nullptr) { return -1; } webm_ctx->buffer = *buffer; @@ -198,7 +198,7 @@ int webm_read_frame(struct WebmInputContext *webm_ctx, uint8_t **buffer, int webm_guess_framerate(struct WebmInputContext *webm_ctx, struct VpxInputContext *vpx_ctx) { uint32_t i = 0; - uint8_t *buffer = NULL; + uint8_t *buffer = nullptr; size_t buffer_size = 0; while (webm_ctx->timestamp_ns < 1000000000 && i < 50) { if (webm_read_frame(webm_ctx, &buffer, &buffer_size)) { @@ -212,8 +212,8 @@ int webm_guess_framerate(struct WebmInputContext *webm_ctx, delete[] buffer; get_first_cluster(webm_ctx); - webm_ctx->block = NULL; - webm_ctx->block_entry = NULL; + webm_ctx->block = nullptr; + webm_ctx->block_entry = nullptr; webm_ctx->block_frame_index = 0; webm_ctx->timestamp_ns = 0; webm_ctx->reached_eos = 0; diff --git a/TMessagesProj/jni/third_party/libvpx/source/libvpx/webmenc.cc b/TMessagesProj/jni/third_party/libvpx/source/libvpx/webmenc.cc index 66606674b..c718ab5a9 100644 --- a/TMessagesProj/jni/third_party/libvpx/source/libvpx/webmenc.cc +++ b/TMessagesProj/jni/third_party/libvpx/source/libvpx/webmenc.cc @@ -90,6 +90,6 @@ void write_webm_file_footer(struct WebmOutputContext *webm_ctx) { segment->Finalize(); delete segment; delete writer; - webm_ctx->writer = NULL; - webm_ctx->segment = NULL; + webm_ctx->writer = nullptr; + webm_ctx->segment = nullptr; } diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv.h index de652836e..aeffd5ef7 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv.h @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef INCLUDE_LIBYUV_H_ // NOLINT +#ifndef INCLUDE_LIBYUV_H_ #define INCLUDE_LIBYUV_H_ #include "libyuv/basic_types.h" @@ -29,4 +29,4 @@ #include "libyuv/version.h" #include "libyuv/video_common.h" -#endif // INCLUDE_LIBYUV_H_ NOLINT +#endif // INCLUDE_LIBYUV_H_ diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert.h index f571142fa..026b153ce 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert.h @@ -42,6 +42,21 @@ int I444ToI420(const uint8_t* src_y, int width, int height); +// Convert I444 to NV12. +LIBYUV_API +int I444ToNV12(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height); + // Convert I444 to NV21. LIBYUV_API int I444ToNV21(const uint8_t* src_y, @@ -248,19 +263,6 @@ int AYUVToNV21(const uint8_t* src_ayuv, int width, int height); -// Convert M420 to I420. -LIBYUV_API -int M420ToI420(const uint8_t* src_m420, - int src_stride_m420, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - // Convert Android420 to I420. LIBYUV_API int Android420ToI420(const uint8_t* src_y, @@ -418,7 +420,15 @@ int RGB24ToJ400(const uint8_t* src_rgb24, int width, int height); -#ifdef HAVE_JPEG +// RGB big endian (rgb in memory) to J400. +LIBYUV_API +int RAWToJ400(const uint8_t* src_raw, + int src_stride_raw, + uint8_t* dst_yj, + int dst_stride_yj, + int width, + int height); + // src_width/height provided by capture. // dst_width/height for clipping determine final size. LIBYUV_API @@ -448,13 +458,25 @@ int MJPGToNV21(const uint8_t* sample, int dst_width, int dst_height); +// JPEG to NV12 +LIBYUV_API +int MJPGToNV12(const uint8_t* sample, + size_t sample_size, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int src_width, + int src_height, + int dst_width, + int dst_height); + // Query size of MJPG in pixels. LIBYUV_API int MJPGSize(const uint8_t* sample, size_t sample_size, int* width, int* height); -#endif // Convert camera sample to I420 with cropping, rotation and vertical flip. // "src_size" is needed to parse MJPG. diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_argb.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_argb.h index bf776348f..715a3dad9 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_argb.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_argb.h @@ -15,16 +15,41 @@ #include "libyuv/rotate.h" // For enum RotationMode. -// TODO(fbarchard): This set of functions should exactly match convert.h -// TODO(fbarchard): Add tests. Create random content of right size and convert -// with C vs Opt and or to I420 and compare. -// TODO(fbarchard): Some of these functions lack parameter setting. - #ifdef __cplusplus namespace libyuv { extern "C" { #endif +// Conversion matrix for YUV to RGB +LIBYUV_API extern const struct YuvConstants kYuvI601Constants; // BT.601 +LIBYUV_API extern const struct YuvConstants kYuvJPEGConstants; // JPeg +LIBYUV_API extern const struct YuvConstants kYuvH709Constants; // BT.709 +LIBYUV_API extern const struct YuvConstants kYuv2020Constants; // BT.2020 + +// Conversion matrix for YVU to BGR +LIBYUV_API extern const struct YuvConstants kYvuI601Constants; // BT.601 +LIBYUV_API extern const struct YuvConstants kYvuJPEGConstants; // JPeg +LIBYUV_API extern const struct YuvConstants kYvuH709Constants; // BT.709 +LIBYUV_API extern const struct YuvConstants kYvu2020Constants; // BT.2020 + +// Macros for end swapped destination Matrix conversions. +// Swap UV and pass mirrored kYvuJPEGConstants matrix. +// TODO(fbarchard): Add macro for each Matrix function. +#define kYuvI601ConstantsVU kYvuI601Constants +#define kYuvJPEGConstantsVU kYvuJPEGConstants +#define kYuvH709ConstantsVU kYvuH709Constants +#define kYuv2020ConstantsVU kYvu2020Constants +#define NV12ToABGRMatrix(a, b, c, d, e, f, g, h, i) \ + NV21ToARGBMatrix(a, b, c, d, e, f, g##VU, h, i) +#define NV21ToABGRMatrix(a, b, c, d, e, f, g, h, i) \ + NV12ToARGBMatrix(a, b, c, d, e, f, g##VU, h, i) +#define NV12ToRAWMatrix(a, b, c, d, e, f, g, h, i) \ + NV21ToRGB24Matrix(a, b, c, d, e, f, g##VU, h, i) +#define NV21ToRAWMatrix(a, b, c, d, e, f, g, h, i) \ + NV12ToRGB24Matrix(a, b, c, d, e, f, g##VU, h, i) +#define I420AlphaToABGRMatrix(a, b, c, d, e, f, g, h, i, j, k, l, m, n) \ + I420AlphaToARGBMatrix(a, b, e, f, c, d, g, h, i, j, k##VU, l, m, n) + // Alias. #define ARGBToARGB ARGBCopy @@ -657,15 +682,6 @@ int NV21ToRAW(const uint8_t* src_y, int width, int height); -// Convert M420 to ARGB. -LIBYUV_API -int M420ToARGB(const uint8_t* src_m420, - int src_stride_m420, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - // Convert YUY2 to ARGB. LIBYUV_API int YUY2ToARGB(const uint8_t* src_yuy2, @@ -956,7 +972,6 @@ int AR30ToAB30(const uint8_t* src_ar30, int width, int height); -#ifdef HAVE_JPEG // src_width/height provided by capture // dst_width/height for clipping determine final size. LIBYUV_API @@ -968,7 +983,6 @@ int MJPGToARGB(const uint8_t* sample, int src_height, int dst_width, int dst_height); -#endif // Convert Android420 to ARGB. LIBYUV_API @@ -998,6 +1012,561 @@ int Android420ToABGR(const uint8_t* src_y, int width, int height); +// Convert NV12 to RGB565. +LIBYUV_API +int NV12ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height); + +// Convert I422 to BGRA. +LIBYUV_API +int I422ToBGRA(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_bgra, + int dst_stride_bgra, + int width, + int height); + +// Convert I422 to ABGR. +LIBYUV_API +int I422ToABGR(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_abgr, + int dst_stride_abgr, + int width, + int height); + +// Convert I422 to RGBA. +LIBYUV_API +int I422ToRGBA(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgba, + int dst_stride_rgba, + int width, + int height); + +LIBYUV_API +int I420ToARGB(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height); + +LIBYUV_API +int I420ToBGRA(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_bgra, + int dst_stride_bgra, + int width, + int height); + +LIBYUV_API +int I420ToABGR(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_abgr, + int dst_stride_abgr, + int width, + int height); + +LIBYUV_API +int I420ToRGBA(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgba, + int dst_stride_rgba, + int width, + int height); + +LIBYUV_API +int I420ToRGB24(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + int width, + int height); + +LIBYUV_API +int I420ToRAW(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_raw, + int dst_stride_raw, + int width, + int height); + +LIBYUV_API +int H420ToRGB24(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + int width, + int height); + +LIBYUV_API +int H420ToRAW(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_raw, + int dst_stride_raw, + int width, + int height); + +LIBYUV_API +int J420ToRGB24(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + int width, + int height); + +LIBYUV_API +int J420ToRAW(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_raw, + int dst_stride_raw, + int width, + int height); + +LIBYUV_API +int I420ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height); + +LIBYUV_API +int J420ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height); + +LIBYUV_API +int H420ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height); + +LIBYUV_API +int I422ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height); + +// Convert I420 To RGB565 with 4x4 dither matrix (16 bytes). +// Values in dither matrix from 0 to 7 recommended. +// The order of the dither matrix is first byte is upper left. + +LIBYUV_API +int I420ToRGB565Dither(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + const uint8_t* dither4x4, + int width, + int height); + +LIBYUV_API +int I420ToARGB1555(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb1555, + int dst_stride_argb1555, + int width, + int height); + +LIBYUV_API +int I420ToARGB4444(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb4444, + int dst_stride_argb4444, + int width, + int height); + +// Convert I420 to AR30. +LIBYUV_API +int I420ToAR30(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + int width, + int height); + +// Convert H420 to AR30. +LIBYUV_API +int H420ToAR30(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + int width, + int height); + +// Convert I420 to ARGB with matrix. +LIBYUV_API +int I420ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I422 to ARGB with matrix. +LIBYUV_API +int I422ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I444 to ARGB with matrix. +LIBYUV_API +int I444ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// multiply 10 bit yuv into high bits to allow any number of bits. +LIBYUV_API +int I010ToAR30Matrix(const uint16_t* src_y, + int src_stride_y, + const uint16_t* src_u, + int src_stride_u, + const uint16_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// multiply 10 bit yuv into high bits to allow any number of bits. +LIBYUV_API +int I210ToAR30Matrix(const uint16_t* src_y, + int src_stride_y, + const uint16_t* src_u, + int src_stride_u, + const uint16_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert 10 bit YUV to ARGB with matrix. +LIBYUV_API +int I010ToARGBMatrix(const uint16_t* src_y, + int src_stride_y, + const uint16_t* src_u, + int src_stride_u, + const uint16_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert 10 bit 422 YUV to ARGB with matrix. +LIBYUV_API +int I210ToARGBMatrix(const uint16_t* src_y, + int src_stride_y, + const uint16_t* src_u, + int src_stride_u, + const uint16_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I420 with Alpha to preattenuated ARGB with matrix. +LIBYUV_API +int I420AlphaToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + const uint8_t* src_a, + int src_stride_a, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height, + int attenuate); + +// Convert NV12 to ARGB with matrix. +LIBYUV_API +int NV12ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert NV21 to ARGB with matrix. +LIBYUV_API +int NV21ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_vu, + int src_stride_vu, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert NV12 to RGB565 with matrix. +LIBYUV_API +int NV12ToRGB565Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert NV12 to RGB24 with matrix. +LIBYUV_API +int NV12ToRGB24Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert NV21 to RGB24 with matrix. +LIBYUV_API +int NV21ToRGB24Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_vu, + int src_stride_vu, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert Android420 to ARGB with matrix. +LIBYUV_API +int Android420ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + int src_pixel_stride_uv, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I422 to RGBA with matrix. +LIBYUV_API +int I422ToRGBAMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgba, + int dst_stride_rgba, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I422 to RGBA with matrix. +LIBYUV_API +int I420ToRGBAMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgba, + int dst_stride_rgba, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I420 to RGB24 with matrix. +LIBYUV_API +int I420ToRGB24Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I420 to RGB565 with specified color matrix. +LIBYUV_API +int I420ToRGB565Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I420 to AR30 with matrix. +LIBYUV_API +int I420ToAR30Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + const struct YuvConstants* yuvconstants, + int width, + int height); + +// Convert I400 (grey) to ARGB. Reverse of ARGBToI400. +LIBYUV_API +int I400ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height); + // Convert camera sample to ARGB with cropping, rotation and vertical flip. // "sample_size" is needed to parse MJPG. // "dst_stride_argb" number of bytes in a row of the dst_argb plane. diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_from.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_from.h index afc43939a..5140ed4f3 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_from.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_from.h @@ -132,6 +132,10 @@ int I420ToUYVY(const uint8_t* src_y, int width, int height); +// The following are from convert_argb.h +// DEPRECATED: The prototypes will be removed in future. Use convert_argb.h + +// Convert I420 to ARGB. LIBYUV_API int I420ToARGB(const uint8_t* src_y, int src_stride_y, @@ -144,18 +148,7 @@ int I420ToARGB(const uint8_t* src_y, int width, int height); -LIBYUV_API -int I420ToBGRA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height); - +// Convert I420 to ABGR. LIBYUV_API int I420ToABGR(const uint8_t* src_y, int src_stride_y, @@ -168,205 +161,6 @@ int I420ToABGR(const uint8_t* src_y, int width, int height); -LIBYUV_API -int I420ToRGBA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height); - -LIBYUV_API -int I420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -LIBYUV_API -int I420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height); - -LIBYUV_API -int H420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -LIBYUV_API -int H420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height); - -LIBYUV_API -int J420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -LIBYUV_API -int J420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height); - -LIBYUV_API -int I420ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height); - -LIBYUV_API -int J420ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height); - -LIBYUV_API -int H420ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height); - -LIBYUV_API -int I422ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height); - -// Convert I420 To RGB565 with 4x4 dither matrix (16 bytes). -// Values in dither matrix from 0 to 7 recommended. -// The order of the dither matrix is first byte is upper left. - -LIBYUV_API -int I420ToRGB565Dither(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - const uint8_t* dither4x4, - int width, - int height); - -LIBYUV_API -int I420ToARGB1555(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb1555, - int dst_stride_argb1555, - int width, - int height); - -LIBYUV_API -int I420ToARGB4444(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb4444, - int dst_stride_argb4444, - int width, - int height); - -// Convert I420 to AR30. -LIBYUV_API -int I420ToAR30(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height); - -// Convert H420 to AR30. -LIBYUV_API -int H420ToAR30(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height); - // Convert I420 to specified format. // "dst_sample_stride" is bytes in a row for the destination. Pass 0 if the // buffer has contiguous rows. Can be negative. A multiple of 16 is optimal. diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_from_argb.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_from_argb.h index 057182448..d992363ce 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_from_argb.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/convert_from_argb.h @@ -77,6 +77,10 @@ int ARGBToAR30(const uint8_t* src_argb, int width, int height); +// Aliases +#define ABGRToRGB24 ARGBToRAW +#define ABGRToRAW ARGBToRGB24 + // Convert ARGB To RGB24. LIBYUV_API int ARGBToRGB24(const uint8_t* src_argb, @@ -281,17 +285,6 @@ int ABGRToNV21(const uint8_t* src_abgr, int width, int height); -// Convert ARGB To NV21. -LIBYUV_API -int ARGBToNV21(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_vu, - int dst_stride_vu, - int width, - int height); - // Convert ARGB To YUY2. LIBYUV_API int ARGBToYUY2(const uint8_t* src_argb, diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/cpu_id.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/cpu_id.h index b01cd25c5..3e27cc107 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/cpu_id.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/cpu_id.h @@ -71,6 +71,8 @@ static __inline int TestCpuFlag(int test_flag) { // Internal function for parsing /proc/cpuinfo. LIBYUV_API int ArmCpuCaps(const char* cpuinfo_name); +LIBYUV_API +int MipsCpuCaps(const char* cpuinfo_name); // For testing, allow CPU flags to be disabled. // ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3. diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/macros_msa.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/macros_msa.h index 29997ce11..4e232b66b 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/macros_msa.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/macros_msa.h @@ -140,6 +140,9 @@ #define LD_B(RTYPE, psrc) *((RTYPE*)(psrc)) /* NOLINT */ #define LD_UB(...) LD_B(const v16u8, __VA_ARGS__) +#define LD_H(RTYPE, psrc) *((RTYPE*)(psrc)) /* NOLINT */ +#define LD_UH(...) LD_H(const v8u16, __VA_ARGS__) + #define ST_B(RTYPE, in, pdst) *((RTYPE*)(pdst)) = (in) /* NOLINT */ #define ST_UB(...) ST_B(v16u8, __VA_ARGS__) diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/planar_functions.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/planar_functions.h index 5299fe2c0..9e0038f47 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/planar_functions.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/planar_functions.h @@ -105,6 +105,19 @@ void MergeUVPlane(const uint8_t* src_u, int width, int height); +// Scale U and V to half width and height and merge into interleaved UV plane. +// width and height are source size, allowing odd sizes. +// Use for converting I444 or I422 to NV12. +LIBYUV_API +void HalfMergeUVPlane(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height); + // Swap U and V channels in interleaved UV plane. LIBYUV_API void SwapUVPlane(const uint8_t* src_uv, @@ -301,6 +314,22 @@ int I400Mirror(const uint8_t* src_y, int width, int height); +// Alias +#define NV12ToNV12Mirror NV12Mirror + +// NV12 mirror. +LIBYUV_API +int NV12Mirror(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height); + // Alias #define ARGBToARGBMirror ARGBMirror @@ -313,56 +342,35 @@ int ARGBMirror(const uint8_t* src_argb, int width, int height); -// Convert NV12 to RGB565. +// Alias +#define RGB24ToRGB24Mirror RGB24Mirror + +// RGB24 mirror. LIBYUV_API -int NV12ToRGB565(const uint8_t* src_y, +int RGB24Mirror(const uint8_t* src_rgb24, + int src_stride_rgb24, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + int width, + int height); + +// Mirror a plane of data. +LIBYUV_API +void MirrorPlane(const uint8_t* src_y, int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_rgb565, - int dst_stride_rgb565, + uint8_t* dst_y, + int dst_stride_y, int width, int height); -// I422ToARGB is in convert_argb.h -// Convert I422 to BGRA. +// Mirror a plane of UV data. LIBYUV_API -int I422ToBGRA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height); - -// Convert I422 to ABGR. -LIBYUV_API -int I422ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert I422 to RGBA. -LIBYUV_API -int I422ToRGBA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height); +void MirrorUVPlane(const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height); // Alias #define RGB24ToRAW RAWToRGB24 @@ -743,6 +751,19 @@ int ARGBBlur(const uint8_t* src_argb, int height, int radius); +// Gaussian 5x5 blur a float plane. +// Coefficients of 1, 4, 6, 4, 1. +// Each destination pixel is a blur of the 5x5 +// pixels from the source. +// Source edges are clamped. +LIBYUV_API +int GaussPlane_F32(const float* src, + int src_stride, + float* dst, + int dst_stride, + int width, + int height); + // Multiply ARGB image by ARGB value. LIBYUV_API int ARGBShade(const uint8_t* src_argb, diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/rotate.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/rotate.h index c64e0216d..308882242 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/rotate.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/rotate.h @@ -118,6 +118,10 @@ void RotatePlane270(const uint8_t* src, int width, int height); +// Rotations for when U and V are interleaved. +// These functions take one input pointer and +// split the data into two buffers while +// rotating them. Deprecated. LIBYUV_API void RotateUV90(const uint8_t* src, int src_stride, @@ -128,10 +132,6 @@ void RotateUV90(const uint8_t* src, int width, int height); -// Rotations for when U and V are interleaved. -// These functions take one input pointer and -// split the data into two buffers while -// rotating them. Deprecated. LIBYUV_API void RotateUV180(const uint8_t* src, int src_stride, diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/row.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/row.h index b721858f1..a27788c1f 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/row.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/row.h @@ -98,7 +98,6 @@ extern "C" { #define HAS_COPYROW_SSE2 #define HAS_H422TOARGBROW_SSSE3 #define HAS_HALFFLOATROW_SSE2 -#define HAS_I400TOARGBROW_SSE2 #define HAS_I422TOARGB1555ROW_SSSE3 #define HAS_I422TOARGB4444ROW_SSSE3 #define HAS_I422TOARGBROW_SSSE3 @@ -112,7 +111,7 @@ extern "C" { #define HAS_J422TOARGBROW_SSSE3 #define HAS_MERGEUVROW_SSE2 #define HAS_MIRRORROW_SSSE3 -#define HAS_MIRRORUVROW_SSSE3 +#define HAS_MIRRORSPLITUVROW_SSSE3 #define HAS_NV12TOARGBROW_SSSE3 #define HAS_NV12TORGB24ROW_SSSE3 #define HAS_NV12TORGB565ROW_SSSE3 @@ -123,6 +122,8 @@ extern "C" { #define HAS_RAWTOYROW_SSSE3 #define HAS_RGB24TOARGBROW_SSSE3 #define HAS_RGB24TOYROW_SSSE3 +#define HAS_RGB24TOYJROW_SSSE3 +#define HAS_RAWTOYJROW_SSSE3 #define HAS_RGB565TOARGBROW_SSE2 #define HAS_RGBATOUVROW_SSSE3 #define HAS_RGBATOYROW_SSSE3 @@ -194,11 +195,12 @@ extern "C" { #define HAS_ARGBTOUVROW_AVX2 #define HAS_ARGBTOYJROW_AVX2 #define HAS_ARGBTOYROW_AVX2 +#define HAS_RGB24TOYJROW_AVX2 +#define HAS_RAWTOYJROW_AVX2 #define HAS_COPYROW_AVX #define HAS_H422TOARGBROW_AVX2 #define HAS_HALFFLOATROW_AVX2 // #define HAS_HALFFLOATROW_F16C // Enable to test halffloat cast -#define HAS_I400TOARGBROW_AVX2 #define HAS_I422TOARGB1555ROW_AVX2 #define HAS_I422TOARGB4444ROW_AVX2 #define HAS_I422TOARGBROW_AVX2 @@ -269,12 +271,16 @@ extern "C" { #define HAS_ARGBTOAR30ROW_SSSE3 #define HAS_CONVERT16TO8ROW_SSSE3 #define HAS_CONVERT8TO16ROW_SSE2 -// I210 is for H010. 2 = 422. I for 601 vs H for 709. +#define HAS_HALFMERGEUVROW_SSSE3 #define HAS_I210TOAR30ROW_SSSE3 #define HAS_I210TOARGBROW_SSSE3 +#define HAS_I400TOARGBROW_SSE2 #define HAS_I422TOAR30ROW_SSSE3 #define HAS_MERGERGBROW_SSSE3 +#define HAS_MIRRORUVROW_AVX2 +#define HAS_MIRRORUVROW_SSSE3 #define HAS_RAWTORGBAROW_SSSE3 +#define HAS_RGB24MIRRORROW_SSSE3 #define HAS_RGBATOYJROW_SSSE3 #define HAS_SPLITRGBROW_SSSE3 #define HAS_SWAPUVROW_SSSE3 @@ -293,8 +299,10 @@ extern "C" { #define HAS_ARGBTORGB24ROW_AVX2 #define HAS_CONVERT16TO8ROW_AVX2 #define HAS_CONVERT8TO16ROW_AVX2 +#define HAS_HALFMERGEUVROW_AVX2 #define HAS_I210TOAR30ROW_AVX2 #define HAS_I210TOARGBROW_AVX2 +#define HAS_I400TOARGBROW_AVX2 #define HAS_I422TOAR30ROW_AVX2 #define HAS_I422TOUYVYROW_AVX2 #define HAS_I422TOYUY2ROW_AVX2 @@ -338,7 +346,6 @@ extern "C" { #define HAS_ARGBTOUVJROW_NEON #define HAS_ARGBTOUVROW_NEON #define HAS_ARGBTOYJROW_NEON -#define HAS_RGBATOYJROW_NEON #define HAS_ARGBTOYROW_NEON #define HAS_AYUVTOUVROW_NEON #define HAS_AYUVTOVUROW_NEON @@ -348,6 +355,7 @@ extern "C" { #define HAS_BYTETOFLOATROW_NEON #define HAS_COPYROW_NEON #define HAS_HALFFLOATROW_NEON +#define HAS_HALFMERGEUVROW_NEON #define HAS_I400TOARGBROW_NEON #define HAS_I422ALPHATOARGBROW_NEON #define HAS_I422TOARGB1555ROW_NEON @@ -363,6 +371,7 @@ extern "C" { #define HAS_MERGEUVROW_NEON #define HAS_MIRRORROW_NEON #define HAS_MIRRORUVROW_NEON +#define HAS_MIRRORSPLITUVROW_NEON #define HAS_NV12TOARGBROW_NEON #define HAS_NV12TORGB24ROW_NEON #define HAS_NV12TORGB565ROW_NEON @@ -370,17 +379,20 @@ extern "C" { #define HAS_NV21TORGB24ROW_NEON #define HAS_NV21TOYUV24ROW_NEON #define HAS_RAWTOARGBROW_NEON -#define HAS_RAWTORGBAROW_NEON #define HAS_RAWTORGB24ROW_NEON +#define HAS_RAWTORGBAROW_NEON #define HAS_RAWTOUVROW_NEON +#define HAS_RAWTOYJROW_NEON #define HAS_RAWTOYROW_NEON #define HAS_RGB24TOARGBROW_NEON #define HAS_RGB24TOUVROW_NEON +#define HAS_RGB24TOYJROW_NEON #define HAS_RGB24TOYROW_NEON #define HAS_RGB565TOARGBROW_NEON #define HAS_RGB565TOUVROW_NEON #define HAS_RGB565TOYROW_NEON #define HAS_RGBATOUVROW_NEON +#define HAS_RGBATOYJROW_NEON #define HAS_RGBATOYROW_NEON #define HAS_SETROW_NEON #define HAS_SPLITRGBROW_NEON @@ -402,6 +414,7 @@ extern "C" { #define HAS_ARGBCOLORMATRIXROW_NEON #define HAS_ARGBGRAYROW_NEON #define HAS_ARGBMIRRORROW_NEON +#define HAS_RGB24MIRRORROW_NEON #define HAS_ARGBMULTIPLYROW_NEON #define HAS_ARGBQUANTIZEROW_NEON #define HAS_ARGBSEPIAROW_NEON @@ -419,6 +432,9 @@ extern "C" { // The following are available on AArch64 platforms: #if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) #define HAS_SCALESUMSAMPLES_NEON +#define HAS_GAUSSROW_F32_NEON +#define HAS_GAUSSCOL_F32_NEON + #endif #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) #define HAS_ABGRTOUVROW_MSA @@ -470,6 +486,7 @@ extern "C" { #define HAS_MERGEUVROW_MSA #define HAS_MIRRORROW_MSA #define HAS_MIRRORUVROW_MSA +#define HAS_MIRRORSPLITUVROW_MSA #define HAS_NV12TOARGBROW_MSA #define HAS_NV12TORGB565ROW_MSA #define HAS_NV21TOARGBROW_MSA @@ -552,7 +569,7 @@ extern "C" { #define HAS_MERGERGBROW_MMI #define HAS_MERGEUVROW_MMI #define HAS_MIRRORROW_MMI -#define HAS_MIRRORUVROW_MMI +#define HAS_MIRRORSPLITUVROW_MMI #define HAS_RAWTOARGBROW_MMI #define HAS_RAWTORGB24ROW_MMI #define HAS_RAWTOUVROW_MMI @@ -601,6 +618,7 @@ extern "C" { #endif typedef __declspec(align(16)) int16_t vec16[8]; typedef __declspec(align(16)) int32_t vec32[4]; +typedef __declspec(align(16)) float vecf32[4]; typedef __declspec(align(16)) int8_t vec8[16]; typedef __declspec(align(16)) uint16_t uvec16[8]; typedef __declspec(align(16)) uint32_t uvec32[4]; @@ -620,6 +638,7 @@ typedef __declspec(align(32)) uint8_t ulvec8[32]; #endif typedef int16_t __attribute__((vector_size(16))) vec16; typedef int32_t __attribute__((vector_size(16))) vec32; +typedef float __attribute__((vector_size(16))) vecf32; typedef int8_t __attribute__((vector_size(16))) vec8; typedef uint16_t __attribute__((vector_size(16))) uvec16; typedef uint32_t __attribute__((vector_size(16))) uvec32; @@ -634,6 +653,7 @@ typedef uint8_t __attribute__((vector_size(32))) ulvec8; #define SIMD_ALIGNED(var) var typedef int16_t vec16[8]; typedef int32_t vec32[4]; +typedef float vecf32[4]; typedef int8_t vec8[16]; typedef uint16_t uvec16[8]; typedef uint32_t uvec32[4]; @@ -674,6 +694,7 @@ struct YuvConstants { int16_t kUVBiasG[16]; int16_t kUVBiasR[16]; int16_t kYToRgb[16]; + int16_t kYBiasToRgb[16]; }; // Offsets into YuvConstants structure @@ -684,20 +705,10 @@ struct YuvConstants { #define KUVBIASG 128 #define KUVBIASR 160 #define KYTORGB 192 +#define KYBIASTORGB 224 + #endif -// Conversion matrix for YUV to RGB -extern const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants); // BT.601 -extern const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants); // JPeg -extern const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants); // BT.709 -extern const struct YuvConstants SIMD_ALIGNED(kYuv2020Constants); // BT.2020 - -// Conversion matrix for YVU to BGR -extern const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants); // BT.601 -extern const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants); // JPeg -extern const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants); // BT.709 -extern const struct YuvConstants SIMD_ALIGNED(kYvu2020Constants); // BT.2020 - #define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a)-1))) #define align_buffer_64(var, size) \ @@ -965,7 +976,11 @@ void BGRAToYRow_SSSE3(const uint8_t* src_bgra, uint8_t* dst_y, int width); void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width); void RGBAToYRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width); void RGB24ToYRow_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); +void RGB24ToYJRow_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); void RAWToYRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); +void RAWToYJRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); +void RGB24ToYJRow_AVX2(const uint8_t* src_rgb24, uint8_t* dst_y, int width); +void RAWToYJRow_AVX2(const uint8_t* src_raw, uint8_t* dst_y, int width); void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); void RGBAToYJRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width); @@ -1134,7 +1149,9 @@ void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width); void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width); void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width); void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width); +void RGB24ToYJRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_yj, int width); void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width); +void RAWToYJRow_NEON(const uint8_t* src_raw, uint8_t* dst_yj, int width); void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width); void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, uint8_t* dst_y, @@ -1165,7 +1182,9 @@ void BGRAToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); void ABGRToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); void RGBAToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); void RGB24ToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); +void RGB24ToYJRow_C(const uint8_t* src_argb, uint8_t* dst_yj, int width); void RAWToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); +void RAWToYJRow_C(const uint8_t* src_argb, uint8_t* dst_yj, int width); void RGB565ToYRow_C(const uint8_t* src_rgb565, uint8_t* dst_y, int width); void ARGB1555ToYRow_C(const uint8_t* src_argb1555, uint8_t* dst_y, int width); void ARGB4444ToYRow_C(const uint8_t* src_argb4444, uint8_t* dst_y, int width); @@ -1175,8 +1194,14 @@ void RGBAToYJRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void BGRAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ABGRToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void RGBAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGB24ToYRow_Any_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); -void RAWToYRow_Any_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); +void RGB24ToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void RGB24ToYJRow_Any_SSSE3(const uint8_t* src_ptr, + uint8_t* dst_ptr, + int width); +void RAWToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void RAWToYJRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void RGB24ToYJRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void RAWToYJRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void RGBAToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); @@ -1184,7 +1209,9 @@ void BGRAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ABGRToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void RGBAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void RGB24ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void RGB24ToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void RAWToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void RAWToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void RGB565ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGB1555ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, @@ -1542,27 +1569,36 @@ void MirrorRow_Any_SSE2(const uint8_t* src, uint8_t* dst, int width); void MirrorRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorRow_Any_MMI(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void MirrorUVRow_AVX2(const uint8_t* src_uv, uint8_t* dst_uv, int width); +void MirrorUVRow_SSSE3(const uint8_t* src_uv, uint8_t* dst_uv, int width); +void MirrorUVRow_NEON(const uint8_t* src_uv, uint8_t* dst_uv, int width); +void MirrorUVRow_MSA(const uint8_t* src_uv, uint8_t* dst_uv, int width); +void MirrorUVRow_C(const uint8_t* src_uv, uint8_t* dst_uv, int width); +void MirrorUVRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void MirrorUVRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void MirrorUVRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void MirrorUVRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_MSA(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_MMI(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_C(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); +void MirrorSplitUVRow_SSSE3(const uint8_t* src, + uint8_t* dst_u, + uint8_t* dst_v, + int width); +void MirrorSplitUVRow_NEON(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width); +void MirrorSplitUVRow_MSA(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width); +void MirrorSplitUVRow_MMI(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width); +void MirrorSplitUVRow_C(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width); void ARGBMirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width); void ARGBMirrorRow_SSE2(const uint8_t* src, uint8_t* dst, int width); @@ -1582,6 +1618,16 @@ void ARGBMirrorRow_Any_NEON(const uint8_t* src_ptr, void ARGBMirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBMirrorRow_Any_MMI(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void RGB24MirrorRow_SSSE3(const uint8_t* src, uint8_t* dst, int width); +void RGB24MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width); +void RGB24MirrorRow_C(const uint8_t* src, uint8_t* dst, int width); +void RGB24MirrorRow_Any_SSSE3(const uint8_t* src_ptr, + uint8_t* dst_ptr, + int width); +void RGB24MirrorRow_Any_NEON(const uint8_t* src_ptr, + uint8_t* dst_ptr, + int width); + void SplitUVRow_C(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v, @@ -1672,6 +1718,34 @@ void MergeUVRow_Any_MMI(const uint8_t* y_buf, uint8_t* dst_ptr, int width); +void HalfMergeUVRow_C(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width); + +void HalfMergeUVRow_NEON(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width); + +void HalfMergeUVRow_SSSE3(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width); + +void HalfMergeUVRow_AVX2(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width); + void SplitRGBRow_C(const uint8_t* src_rgb, uint8_t* dst_r, uint8_t* dst_g, @@ -2728,23 +2802,50 @@ void I422ToRGB24Row_Any_AVX2(const uint8_t* y_buf, const struct YuvConstants* yuvconstants, int width); -void I400ToARGBRow_C(const uint8_t* src_y, uint8_t* rgb_buf, int width); -void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* dst_argb, int width); -void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* dst_argb, int width); -void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width); -void I400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width); -void I400ToARGBRow_MMI(const uint8_t* src_y, uint8_t* dst_argb, int width); +void I400ToARGBRow_C(const uint8_t* src_y, + uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, + int width); +void I400ToARGBRow_SSE2(const uint8_t* y_buf, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); +void I400ToARGBRow_AVX2(const uint8_t* y_buf, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); +void I400ToARGBRow_NEON(const uint8_t* src_y, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); +void I400ToARGBRow_MSA(const uint8_t* src_y, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); +void I400ToARGBRow_MMI(const uint8_t* src_y, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); void I400ToARGBRow_Any_SSE2(const uint8_t* src_ptr, uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, int width); void I400ToARGBRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, int width); void I400ToARGBRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, int width); -void I400ToARGBRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void I400ToARGBRow_Any_MMI(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void I400ToARGBRow_Any_MSA(const uint8_t* src_ptr, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); +void I400ToARGBRow_Any_MMI(const uint8_t* src_ptr, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); // ARGB preattenuated alpha blend. void ARGBBlendRow_SSSE3(const uint8_t* src_argb0, @@ -4256,6 +4357,25 @@ void UYVYToARGBRow_Any_MMI(const uint8_t* src_ptr, const struct YuvConstants* yuvconstants, int width); +void GaussRow_F32_NEON(const float* src, float* dst, int width); +void GaussRow_F32_C(const float* src, float* dst, int width); + +void GaussCol_F32_NEON(const float* src0, + const float* src1, + const float* src2, + const float* src3, + const float* src4, + float* dst, + int width); + +void GaussCol_F32_C(const float* src0, + const float* src1, + const float* src2, + const float* src3, + const float* src4, + float* dst, + int width); + #ifdef __cplusplus } // extern "C" } // namespace libyuv diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale.h index 23ba1634f..add5a9eb6 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale.h @@ -145,6 +145,31 @@ int I444Scale_16(const uint16_t* src_y, int dst_height, enum FilterMode filtering); +// Scales an NV12 image from the src width and height to the +// dst width and height. +// If filtering is kFilterNone, a simple nearest-neighbor algorithm is +// used. This produces basic (blocky) quality at the fastest speed. +// If filtering is kFilterBilinear, interpolation is used to produce a better +// quality image, at the expense of speed. +// kFilterBox is not supported for the UV channel and will be treated as +// bilinear. +// Returns 0 if successful. + +LIBYUV_API +int NV12Scale(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + int src_width, + int src_height, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int dst_width, + int dst_height, + enum FilterMode filtering); + #ifdef __cplusplus // Legacy API. Deprecated. LIBYUV_API diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale_row.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale_row.h index dd20718a8..a386d4998 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale_row.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale_row.h @@ -72,6 +72,22 @@ extern "C" { #define HAS_SCALEROWDOWN4_SSSE3 #endif +// The following are available for gcc/clang x86 platforms: +// TODO(fbarchard): Port to Visual C +#if !defined(LIBYUV_DISABLE_X86) && \ + (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) +#define HAS_SCALEUVROWDOWN2BOX_SSSE3 +#endif + +// The following are available for gcc/clang x86 platforms, but +// require clang 3.4 or gcc 4.7. +// TODO(fbarchard): Port to Visual C +#if !defined(LIBYUV_DISABLE_X86) && \ + (defined(__x86_64__) || defined(__i386__)) && !defined(_MSC_VER) && \ + (defined(CLANG_HAS_AVX2) || defined(GCC_HAS_AVX2)) +#define HAS_SCALEUVROWDOWN2BOX_AVX2 +#endif + // The following are available on all x86 platforms, but // require VS2012, clang 3.4 or gcc 4.7. // The code supports NaCL but requires a new compiler and validator. @@ -96,6 +112,8 @@ extern "C" { #define HAS_SCALEROWDOWN34_NEON #define HAS_SCALEROWDOWN38_NEON #define HAS_SCALEROWDOWN4_NEON +#define HAS_SCALEUVROWDOWN2BOX_NEON +#define HAS_SCALEUVROWDOWNEVEN_NEON #endif #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) @@ -376,6 +394,53 @@ void ScaleARGBFilterCols64_C(uint8_t* dst_argb, int dst_width, int x32, int dx); +void ScaleUVRowDown2_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Linear_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Box_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEven_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEvenBox_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVCols_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x, + int dx); +void ScaleUVCols64_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x32, + int dx); +void ScaleUVColsUp2_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int, + int); +void ScaleUVFilterCols_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x, + int dx); +void ScaleUVFilterCols64_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x32, + int dx); // Specialized scalers for x86. void ScaleRowDown2_SSSE3(const uint8_t* src_ptr, @@ -782,6 +847,192 @@ void ScaleARGBRowDownEvenBox_Any_MMI(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width); +// UV Row functions +void ScaleUVRowDown2_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Linear_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Box_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Box_AVX2(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst, + int dst_width); +void ScaleUVRowDown2Linear_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Box_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst, + int dst_width); +void ScaleUVRowDown2_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Linear_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Box_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Linear_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2Box_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDown2_Any_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Linear_Any_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Box_Any_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Box_Any_AVX2(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2_Any_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Linear_Any_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Box_Any_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2_Any_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Linear_Any_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Box_Any_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2_Any_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Linear_Any_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDown2Box_Any_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDownEven_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEvenBox_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEven_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEvenBox_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEven_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int32_t src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEvenBox_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEven_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int32_t src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEvenBox_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width); +void ScaleUVRowDownEven_Any_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDownEvenBox_Any_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDownEven_Any_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDownEvenBox_Any_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDownEven_Any_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int32_t src_stepx, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDownEvenBox_Any_MSA(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDownEven_Any_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int32_t src_stepx, + uint8_t* dst_ptr, + int dst_width); +void ScaleUVRowDownEvenBox_Any_MMI(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_ptr, + int dst_width); + // ScaleRowDown2Box also used by planar functions // NEON downscalers with interpolation. diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale_uv.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale_uv.h new file mode 100644 index 000000000..1b6327aae --- /dev/null +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/scale_uv.h @@ -0,0 +1,38 @@ +/* + * Copyright 2020 The LibYuv 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. + */ + +#ifndef INCLUDE_LIBYUV_SCALE_UV_H_ +#define INCLUDE_LIBYUV_SCALE_UV_H_ + +#include "libyuv/basic_types.h" +#include "libyuv/scale.h" // For FilterMode + +#ifdef __cplusplus +namespace libyuv { +extern "C" { +#endif + +LIBYUV_API +int UVScale(const uint8_t* src_uv, + int src_stride_uv, + int src_width, + int src_height, + uint8_t* dst_uv, + int dst_stride_uv, + int dst_width, + int dst_height, + enum FilterMode filtering); + +#ifdef __cplusplus +} // extern "C" +} // namespace libyuv +#endif + +#endif // INCLUDE_LIBYUV_SCALE_UV_H_ diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/version.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/version.h index 4c446ba3d..1d085960e 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/version.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1741 +#define LIBYUV_VERSION 1767 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/TMessagesProj/jni/third_party/libyuv/include/libyuv/video_common.h b/TMessagesProj/jni/third_party/libyuv/include/libyuv/video_common.h index 666eb3439..b9823d71d 100644 --- a/TMessagesProj/jni/third_party/libyuv/include/libyuv/video_common.h +++ b/TMessagesProj/jni/third_party/libyuv/include/libyuv/video_common.h @@ -62,7 +62,7 @@ enum FourCC { FOURCC_I010 = FOURCC('I', '0', '1', '0'), // bt.601 10 bit 420 FOURCC_I210 = FOURCC('I', '0', '1', '0'), // bt.601 10 bit 422 - // 1 Secondary YUV format: row biplanar. + // 1 Secondary YUV format: row biplanar. deprecated. FOURCC_M420 = FOURCC('M', '4', '2', '0'), // 11 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc @@ -86,10 +86,14 @@ enum FourCC { FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'), FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'), FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'), // Linux version of I420. - FOURCC_J420 = FOURCC('J', '4', '2', '0'), // jpeg (bt.601 full), unofficial fourcc - FOURCC_J422 = FOURCC('J', '4', '2', '2'), // jpeg (bt.601 full), unofficial fourcc - FOURCC_J444 = FOURCC('J', '4', '4', '4'), // jpeg (bt.601 full), unofficial fourcc - FOURCC_J400 = FOURCC('J', '4', '0', '0'), // jpeg (bt.601 full), unofficial fourcc + FOURCC_J420 = + FOURCC('J', '4', '2', '0'), // jpeg (bt.601 full), unofficial fourcc + FOURCC_J422 = + FOURCC('J', '4', '2', '2'), // jpeg (bt.601 full), unofficial fourcc + FOURCC_J444 = + FOURCC('J', '4', '4', '4'), // jpeg (bt.601 full), unofficial fourcc + FOURCC_J400 = + FOURCC('J', '4', '0', '0'), // jpeg (bt.601 full), unofficial fourcc FOURCC_H420 = FOURCC('H', '4', '2', '0'), // bt.709, unofficial fourcc FOURCC_H422 = FOURCC('H', '4', '2', '2'), // bt.709, unofficial fourcc FOURCC_H444 = FOURCC('H', '4', '4', '4'), // bt.709, unofficial fourcc @@ -144,7 +148,7 @@ enum FourCCBpp { FOURCC_BPP_NV12 = 12, FOURCC_BPP_YUY2 = 16, FOURCC_BPP_UYVY = 16, - FOURCC_BPP_M420 = 12, + FOURCC_BPP_M420 = 12, // deprecated FOURCC_BPP_Q420 = 12, FOURCC_BPP_ARGB = 32, FOURCC_BPP_BGRA = 32, diff --git a/TMessagesProj/jni/third_party/libyuv/source/compare.cc b/TMessagesProj/jni/third_party/libyuv/source/compare.cc index 7f4828104..e93aba1b5 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/compare.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/compare.cc @@ -149,16 +149,16 @@ uint64_t ComputeHammingDistance(const uint8_t* src_a, HammingDistance = HammingDistance_AVX2; } #endif -#if defined(HAS_HAMMINGDISTANCE_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - HammingDistance = HammingDistance_MSA; - } -#endif #if defined(HAS_HAMMINGDISTANCE_MMI) if (TestCpuFlag(kCpuHasMMI)) { HammingDistance = HammingDistance_MMI; } #endif +#if defined(HAS_HAMMINGDISTANCE_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + HammingDistance = HammingDistance_MSA; + } +#endif #ifdef _OPENMP #pragma omp parallel for reduction(+ : diff) @@ -211,16 +211,16 @@ uint64_t ComputeSumSquareError(const uint8_t* src_a, SumSquareError = SumSquareError_AVX2; } #endif -#if defined(HAS_SUMSQUAREERROR_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SumSquareError = SumSquareError_MSA; - } -#endif #if defined(HAS_SUMSQUAREERROR_MMI) if (TestCpuFlag(kCpuHasMMI)) { SumSquareError = SumSquareError_MMI; } #endif +#if defined(HAS_SUMSQUAREERROR_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SumSquareError = SumSquareError_MSA; + } +#endif #ifdef _OPENMP #pragma omp parallel for reduction(+ : sse) #endif diff --git a/TMessagesProj/jni/third_party/libyuv/source/compare_gcc.cc b/TMessagesProj/jni/third_party/libyuv/source/compare_gcc.cc index 676527c1b..6700f9697 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/compare_gcc.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/compare_gcc.cc @@ -29,38 +29,38 @@ uint32_t HammingDistance_SSE42(const uint8_t* src_a, uint64_t diff = 0u; asm volatile( - "xor %3,%3 \n" - "xor %%r8,%%r8 \n" - "xor %%r9,%%r9 \n" - "xor %%r10,%%r10 \n" + "xor %3,%3 \n" + "xor %%r8,%%r8 \n" + "xor %%r9,%%r9 \n" + "xor %%r10,%%r10 \n" // Process 32 bytes per loop. LABELALIGN "1: \n" - "mov (%0),%%rcx \n" - "mov 0x8(%0),%%rdx \n" - "xor (%1),%%rcx \n" - "xor 0x8(%1),%%rdx \n" - "popcnt %%rcx,%%rcx \n" - "popcnt %%rdx,%%rdx \n" - "mov 0x10(%0),%%rsi \n" - "mov 0x18(%0),%%rdi \n" - "xor 0x10(%1),%%rsi \n" - "xor 0x18(%1),%%rdi \n" - "popcnt %%rsi,%%rsi \n" - "popcnt %%rdi,%%rdi \n" - "add $0x20,%0 \n" - "add $0x20,%1 \n" - "add %%rcx,%3 \n" - "add %%rdx,%%r8 \n" - "add %%rsi,%%r9 \n" - "add %%rdi,%%r10 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "mov (%0),%%rcx \n" + "mov 0x8(%0),%%rdx \n" + "xor (%1),%%rcx \n" + "xor 0x8(%1),%%rdx \n" + "popcnt %%rcx,%%rcx \n" + "popcnt %%rdx,%%rdx \n" + "mov 0x10(%0),%%rsi \n" + "mov 0x18(%0),%%rdi \n" + "xor 0x10(%1),%%rsi \n" + "xor 0x18(%1),%%rdi \n" + "popcnt %%rsi,%%rsi \n" + "popcnt %%rdi,%%rdi \n" + "add $0x20,%0 \n" + "add $0x20,%1 \n" + "add %%rcx,%3 \n" + "add %%rdx,%%r8 \n" + "add %%rsi,%%r9 \n" + "add %%rdi,%%r10 \n" + "sub $0x20,%2 \n" + "jg 1b \n" - "add %%r8, %3 \n" - "add %%r9, %3 \n" - "add %%r10, %3 \n" + "add %%r8, %3 \n" + "add %%r9, %3 \n" + "add %%r10, %3 \n" : "+r"(src_a), // %0 "+r"(src_b), // %1 "+r"(count), // %2 @@ -80,26 +80,26 @@ uint32_t HammingDistance_SSE42(const uint8_t* src_a, // Process 16 bytes per loop. LABELALIGN "1: \n" - "mov (%0),%%ecx \n" - "mov 0x4(%0),%%edx \n" - "xor (%1),%%ecx \n" - "xor 0x4(%1),%%edx \n" - "popcnt %%ecx,%%ecx \n" - "add %%ecx,%3 \n" - "popcnt %%edx,%%edx \n" - "add %%edx,%3 \n" - "mov 0x8(%0),%%ecx \n" - "mov 0xc(%0),%%edx \n" - "xor 0x8(%1),%%ecx \n" - "xor 0xc(%1),%%edx \n" - "popcnt %%ecx,%%ecx \n" - "add %%ecx,%3 \n" - "popcnt %%edx,%%edx \n" - "add %%edx,%3 \n" - "add $0x10,%0 \n" - "add $0x10,%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "mov (%0),%%ecx \n" + "mov 0x4(%0),%%edx \n" + "xor (%1),%%ecx \n" + "xor 0x4(%1),%%edx \n" + "popcnt %%ecx,%%ecx \n" + "add %%ecx,%3 \n" + "popcnt %%edx,%%edx \n" + "add %%edx,%3 \n" + "mov 0x8(%0),%%ecx \n" + "mov 0xc(%0),%%edx \n" + "xor 0x8(%1),%%ecx \n" + "xor 0xc(%1),%%edx \n" + "popcnt %%ecx,%%ecx \n" + "add %%ecx,%3 \n" + "popcnt %%edx,%%edx \n" + "add %%edx,%3 \n" + "add $0x10,%0 \n" + "add $0x10,%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_a), // %0 "+r"(src_b), // %1 "+r"(count), // %2 @@ -121,46 +121,46 @@ uint32_t HammingDistance_SSSE3(const uint8_t* src_a, uint32_t diff = 0u; asm volatile( - "movdqa %4,%%xmm2 \n" - "movdqa %5,%%xmm3 \n" - "pxor %%xmm0,%%xmm0 \n" - "pxor %%xmm1,%%xmm1 \n" - "sub %0,%1 \n" + "movdqa %4,%%xmm2 \n" + "movdqa %5,%%xmm3 \n" + "pxor %%xmm0,%%xmm0 \n" + "pxor %%xmm1,%%xmm1 \n" + "sub %0,%1 \n" LABELALIGN "1: \n" - "movdqa (%0),%%xmm4 \n" - "movdqa 0x10(%0), %%xmm5 \n" - "pxor (%0,%1), %%xmm4 \n" - "movdqa %%xmm4,%%xmm6 \n" - "pand %%xmm2,%%xmm6 \n" - "psrlw $0x4,%%xmm4 \n" - "movdqa %%xmm3,%%xmm7 \n" - "pshufb %%xmm6,%%xmm7 \n" - "pand %%xmm2,%%xmm4 \n" - "movdqa %%xmm3,%%xmm6 \n" - "pshufb %%xmm4,%%xmm6 \n" - "paddb %%xmm7,%%xmm6 \n" - "pxor 0x10(%0,%1),%%xmm5 \n" - "add $0x20,%0 \n" - "movdqa %%xmm5,%%xmm4 \n" - "pand %%xmm2,%%xmm5 \n" - "psrlw $0x4,%%xmm4 \n" - "movdqa %%xmm3,%%xmm7 \n" - "pshufb %%xmm5,%%xmm7 \n" - "pand %%xmm2,%%xmm4 \n" - "movdqa %%xmm3,%%xmm5 \n" - "pshufb %%xmm4,%%xmm5 \n" - "paddb %%xmm7,%%xmm5 \n" - "paddb %%xmm5,%%xmm6 \n" - "psadbw %%xmm1,%%xmm6 \n" - "paddd %%xmm6,%%xmm0 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "movdqa (%0),%%xmm4 \n" + "movdqa 0x10(%0), %%xmm5 \n" + "pxor (%0,%1), %%xmm4 \n" + "movdqa %%xmm4,%%xmm6 \n" + "pand %%xmm2,%%xmm6 \n" + "psrlw $0x4,%%xmm4 \n" + "movdqa %%xmm3,%%xmm7 \n" + "pshufb %%xmm6,%%xmm7 \n" + "pand %%xmm2,%%xmm4 \n" + "movdqa %%xmm3,%%xmm6 \n" + "pshufb %%xmm4,%%xmm6 \n" + "paddb %%xmm7,%%xmm6 \n" + "pxor 0x10(%0,%1),%%xmm5 \n" + "add $0x20,%0 \n" + "movdqa %%xmm5,%%xmm4 \n" + "pand %%xmm2,%%xmm5 \n" + "psrlw $0x4,%%xmm4 \n" + "movdqa %%xmm3,%%xmm7 \n" + "pshufb %%xmm5,%%xmm7 \n" + "pand %%xmm2,%%xmm4 \n" + "movdqa %%xmm3,%%xmm5 \n" + "pshufb %%xmm4,%%xmm5 \n" + "paddb %%xmm7,%%xmm5 \n" + "paddb %%xmm5,%%xmm6 \n" + "psadbw %%xmm1,%%xmm6 \n" + "paddd %%xmm6,%%xmm0 \n" + "sub $0x20,%2 \n" + "jg 1b \n" - "pshufd $0xaa,%%xmm0,%%xmm1 \n" - "paddd %%xmm1,%%xmm0 \n" - "movd %%xmm0, %3 \n" + "pshufd $0xaa,%%xmm0,%%xmm1 \n" + "paddd %%xmm1,%%xmm0 \n" + "movd %%xmm0, %3 \n" : "+r"(src_a), // %0 "+r"(src_b), // %1 "+r"(count), // %2 @@ -182,40 +182,40 @@ uint32_t HammingDistance_AVX2(const uint8_t* src_a, asm volatile( "vbroadcastf128 %4,%%ymm2 \n" "vbroadcastf128 %5,%%ymm3 \n" - "vpxor %%ymm0,%%ymm0,%%ymm0 \n" - "vpxor %%ymm1,%%ymm1,%%ymm1 \n" - "sub %0,%1 \n" + "vpxor %%ymm0,%%ymm0,%%ymm0 \n" + "vpxor %%ymm1,%%ymm1,%%ymm1 \n" + "sub %0,%1 \n" LABELALIGN "1: \n" - "vmovdqa (%0),%%ymm4 \n" - "vmovdqa 0x20(%0), %%ymm5 \n" - "vpxor (%0,%1), %%ymm4, %%ymm4 \n" - "vpand %%ymm2,%%ymm4,%%ymm6 \n" - "vpsrlw $0x4,%%ymm4,%%ymm4 \n" - "vpshufb %%ymm6,%%ymm3,%%ymm6 \n" - "vpand %%ymm2,%%ymm4,%%ymm4 \n" - "vpshufb %%ymm4,%%ymm3,%%ymm4 \n" - "vpaddb %%ymm4,%%ymm6,%%ymm6 \n" - "vpxor 0x20(%0,%1),%%ymm5,%%ymm4 \n" - "add $0x40,%0 \n" - "vpand %%ymm2,%%ymm4,%%ymm5 \n" - "vpsrlw $0x4,%%ymm4,%%ymm4 \n" - "vpshufb %%ymm5,%%ymm3,%%ymm5 \n" - "vpand %%ymm2,%%ymm4,%%ymm4 \n" - "vpshufb %%ymm4,%%ymm3,%%ymm4 \n" - "vpaddb %%ymm5,%%ymm4,%%ymm4 \n" - "vpaddb %%ymm6,%%ymm4,%%ymm4 \n" - "vpsadbw %%ymm1,%%ymm4,%%ymm4 \n" - "vpaddd %%ymm0,%%ymm4,%%ymm0 \n" - "sub $0x40,%2 \n" - "jg 1b \n" + "vmovdqa (%0),%%ymm4 \n" + "vmovdqa 0x20(%0), %%ymm5 \n" + "vpxor (%0,%1), %%ymm4, %%ymm4 \n" + "vpand %%ymm2,%%ymm4,%%ymm6 \n" + "vpsrlw $0x4,%%ymm4,%%ymm4 \n" + "vpshufb %%ymm6,%%ymm3,%%ymm6 \n" + "vpand %%ymm2,%%ymm4,%%ymm4 \n" + "vpshufb %%ymm4,%%ymm3,%%ymm4 \n" + "vpaddb %%ymm4,%%ymm6,%%ymm6 \n" + "vpxor 0x20(%0,%1),%%ymm5,%%ymm4 \n" + "add $0x40,%0 \n" + "vpand %%ymm2,%%ymm4,%%ymm5 \n" + "vpsrlw $0x4,%%ymm4,%%ymm4 \n" + "vpshufb %%ymm5,%%ymm3,%%ymm5 \n" + "vpand %%ymm2,%%ymm4,%%ymm4 \n" + "vpshufb %%ymm4,%%ymm3,%%ymm4 \n" + "vpaddb %%ymm5,%%ymm4,%%ymm4 \n" + "vpaddb %%ymm6,%%ymm4,%%ymm4 \n" + "vpsadbw %%ymm1,%%ymm4,%%ymm4 \n" + "vpaddd %%ymm0,%%ymm4,%%ymm0 \n" + "sub $0x40,%2 \n" + "jg 1b \n" - "vpermq $0xb1,%%ymm0,%%ymm1 \n" - "vpaddd %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xaa,%%ymm0,%%ymm1 \n" - "vpaddd %%ymm1,%%ymm0,%%ymm0 \n" - "vmovd %%xmm0, %3 \n" + "vpermq $0xb1,%%ymm0,%%ymm1 \n" + "vpaddd %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xaa,%%ymm0,%%ymm1 \n" + "vpaddd %%ymm1,%%ymm0,%%ymm0 \n" + "vmovd %%xmm0, %3 \n" "vzeroupper \n" : "+r"(src_a), // %0 "+r"(src_b), // %1 @@ -234,34 +234,34 @@ uint32_t SumSquareError_SSE2(const uint8_t* src_a, int count) { uint32_t sse; asm volatile( - "pxor %%xmm0,%%xmm0 \n" - "pxor %%xmm5,%%xmm5 \n" + "pxor %%xmm0,%%xmm0 \n" + "pxor %%xmm5,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "movdqu (%1),%%xmm2 \n" - "lea 0x10(%1),%1 \n" - "movdqa %%xmm1,%%xmm3 \n" - "psubusb %%xmm2,%%xmm1 \n" - "psubusb %%xmm3,%%xmm2 \n" - "por %%xmm2,%%xmm1 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "punpckhbw %%xmm5,%%xmm2 \n" - "pmaddwd %%xmm1,%%xmm1 \n" - "pmaddwd %%xmm2,%%xmm2 \n" - "paddd %%xmm1,%%xmm0 \n" - "paddd %%xmm2,%%xmm0 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm1 \n" + "lea 0x10(%0),%0 \n" + "movdqu (%1),%%xmm2 \n" + "lea 0x10(%1),%1 \n" + "movdqa %%xmm1,%%xmm3 \n" + "psubusb %%xmm2,%%xmm1 \n" + "psubusb %%xmm3,%%xmm2 \n" + "por %%xmm2,%%xmm1 \n" + "movdqa %%xmm1,%%xmm2 \n" + "punpcklbw %%xmm5,%%xmm1 \n" + "punpckhbw %%xmm5,%%xmm2 \n" + "pmaddwd %%xmm1,%%xmm1 \n" + "pmaddwd %%xmm2,%%xmm2 \n" + "paddd %%xmm1,%%xmm0 \n" + "paddd %%xmm2,%%xmm0 \n" + "sub $0x10,%2 \n" + "jg 1b \n" - "pshufd $0xee,%%xmm0,%%xmm1 \n" - "paddd %%xmm1,%%xmm0 \n" - "pshufd $0x1,%%xmm0,%%xmm1 \n" - "paddd %%xmm1,%%xmm0 \n" - "movd %%xmm0,%3 \n" + "pshufd $0xee,%%xmm0,%%xmm1 \n" + "paddd %%xmm1,%%xmm0 \n" + "pshufd $0x1,%%xmm0,%%xmm1 \n" + "paddd %%xmm1,%%xmm0 \n" + "movd %%xmm0,%3 \n" : "+r"(src_a), // %0 "+r"(src_b), // %1 @@ -301,44 +301,44 @@ static const uvec32 kHashMul3 = { uint32_t HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed) { uint32_t hash; asm volatile( - "movd %2,%%xmm0 \n" - "pxor %%xmm7,%%xmm7 \n" - "movdqa %4,%%xmm6 \n" + "movd %2,%%xmm0 \n" + "pxor %%xmm7,%%xmm7 \n" + "movdqa %4,%%xmm6 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "pmulld %%xmm6,%%xmm0 \n" - "movdqa %5,%%xmm5 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklbw %%xmm7,%%xmm2 \n" - "movdqa %%xmm2,%%xmm3 \n" - "punpcklwd %%xmm7,%%xmm3 \n" - "pmulld %%xmm5,%%xmm3 \n" - "movdqa %6,%%xmm5 \n" - "movdqa %%xmm2,%%xmm4 \n" - "punpckhwd %%xmm7,%%xmm4 \n" - "pmulld %%xmm5,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "punpckhbw %%xmm7,%%xmm1 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklwd %%xmm7,%%xmm2 \n" - "pmulld %%xmm5,%%xmm2 \n" - "movdqa %8,%%xmm5 \n" - "punpckhwd %%xmm7,%%xmm1 \n" - "pmulld %%xmm5,%%xmm1 \n" - "paddd %%xmm4,%%xmm3 \n" - "paddd %%xmm2,%%xmm1 \n" - "paddd %%xmm3,%%xmm1 \n" - "pshufd $0xe,%%xmm1,%%xmm2 \n" - "paddd %%xmm2,%%xmm1 \n" - "pshufd $0x1,%%xmm1,%%xmm2 \n" - "paddd %%xmm2,%%xmm1 \n" - "paddd %%xmm1,%%xmm0 \n" - "sub $0x10,%1 \n" - "jg 1b \n" - "movd %%xmm0,%3 \n" + "movdqu (%0),%%xmm1 \n" + "lea 0x10(%0),%0 \n" + "pmulld %%xmm6,%%xmm0 \n" + "movdqa %5,%%xmm5 \n" + "movdqa %%xmm1,%%xmm2 \n" + "punpcklbw %%xmm7,%%xmm2 \n" + "movdqa %%xmm2,%%xmm3 \n" + "punpcklwd %%xmm7,%%xmm3 \n" + "pmulld %%xmm5,%%xmm3 \n" + "movdqa %6,%%xmm5 \n" + "movdqa %%xmm2,%%xmm4 \n" + "punpckhwd %%xmm7,%%xmm4 \n" + "pmulld %%xmm5,%%xmm4 \n" + "movdqa %7,%%xmm5 \n" + "punpckhbw %%xmm7,%%xmm1 \n" + "movdqa %%xmm1,%%xmm2 \n" + "punpcklwd %%xmm7,%%xmm2 \n" + "pmulld %%xmm5,%%xmm2 \n" + "movdqa %8,%%xmm5 \n" + "punpckhwd %%xmm7,%%xmm1 \n" + "pmulld %%xmm5,%%xmm1 \n" + "paddd %%xmm4,%%xmm3 \n" + "paddd %%xmm2,%%xmm1 \n" + "paddd %%xmm3,%%xmm1 \n" + "pshufd $0xe,%%xmm1,%%xmm2 \n" + "paddd %%xmm2,%%xmm1 \n" + "pshufd $0x1,%%xmm1,%%xmm2 \n" + "paddd %%xmm2,%%xmm1 \n" + "paddd %%xmm1,%%xmm0 \n" + "sub $0x10,%1 \n" + "jg 1b \n" + "movd %%xmm0,%3 \n" : "+r"(src), // %0 "+r"(count), // %1 "+rm"(seed), // %2 diff --git a/TMessagesProj/jni/third_party/libyuv/source/compare_neon.cc b/TMessagesProj/jni/third_party/libyuv/source/compare_neon.cc index 2a2181e0c..afdd60121 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/compare_neon.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/compare_neon.cc @@ -29,24 +29,24 @@ uint32_t HammingDistance_NEON(const uint8_t* src_a, uint32_t diff; asm volatile( - "vmov.u16 q4, #0 \n" // accumulator + "vmov.u16 q4, #0 \n" // accumulator "1: \n" - "vld1.8 {q0, q1}, [%0]! \n" - "vld1.8 {q2, q3}, [%1]! \n" - "veor.32 q0, q0, q2 \n" - "veor.32 q1, q1, q3 \n" - "vcnt.i8 q0, q0 \n" - "vcnt.i8 q1, q1 \n" - "subs %2, %2, #32 \n" - "vadd.u8 q0, q0, q1 \n" // 16 byte counts - "vpadal.u8 q4, q0 \n" // 8 shorts - "bgt 1b \n" + "vld1.8 {q0, q1}, [%0]! \n" + "vld1.8 {q2, q3}, [%1]! \n" + "veor.32 q0, q0, q2 \n" + "veor.32 q1, q1, q3 \n" + "vcnt.i8 q0, q0 \n" + "vcnt.i8 q1, q1 \n" + "subs %2, %2, #32 \n" + "vadd.u8 q0, q0, q1 \n" // 16 byte counts + "vpadal.u8 q4, q0 \n" // 8 shorts + "bgt 1b \n" - "vpaddl.u16 q0, q4 \n" // 4 ints - "vpadd.u32 d0, d0, d1 \n" - "vpadd.u32 d0, d0, d0 \n" - "vmov.32 %3, d0[0] \n" + "vpaddl.u16 q0, q4 \n" // 4 ints + "vpadd.u32 d0, d0, d1 \n" + "vpadd.u32 d0, d0, d0 \n" + "vmov.32 %3, d0[0] \n" : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(diff) : @@ -59,29 +59,29 @@ uint32_t SumSquareError_NEON(const uint8_t* src_a, int count) { uint32_t sse; asm volatile( - "vmov.u8 q8, #0 \n" - "vmov.u8 q10, #0 \n" - "vmov.u8 q9, #0 \n" - "vmov.u8 q11, #0 \n" + "vmov.u8 q8, #0 \n" + "vmov.u8 q10, #0 \n" + "vmov.u8 q9, #0 \n" + "vmov.u8 q11, #0 \n" "1: \n" - "vld1.8 {q0}, [%0]! \n" - "vld1.8 {q1}, [%1]! \n" - "subs %2, %2, #16 \n" - "vsubl.u8 q2, d0, d2 \n" - "vsubl.u8 q3, d1, d3 \n" - "vmlal.s16 q8, d4, d4 \n" - "vmlal.s16 q9, d6, d6 \n" - "vmlal.s16 q10, d5, d5 \n" - "vmlal.s16 q11, d7, d7 \n" - "bgt 1b \n" + "vld1.8 {q0}, [%0]! \n" + "vld1.8 {q1}, [%1]! \n" + "subs %2, %2, #16 \n" + "vsubl.u8 q2, d0, d2 \n" + "vsubl.u8 q3, d1, d3 \n" + "vmlal.s16 q8, d4, d4 \n" + "vmlal.s16 q9, d6, d6 \n" + "vmlal.s16 q10, d5, d5 \n" + "vmlal.s16 q11, d7, d7 \n" + "bgt 1b \n" - "vadd.u32 q8, q8, q9 \n" - "vadd.u32 q10, q10, q11 \n" - "vadd.u32 q11, q8, q10 \n" - "vpaddl.u32 q1, q11 \n" - "vadd.u64 d0, d2, d3 \n" - "vmov.32 %3, d0[0] \n" + "vadd.u32 q8, q8, q9 \n" + "vadd.u32 q10, q10, q11 \n" + "vadd.u32 q11, q8, q10 \n" + "vpaddl.u32 q1, q11 \n" + "vadd.u64 d0, d2, d3 \n" + "vmov.32 %3, d0[0] \n" : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(sse) : : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"); diff --git a/TMessagesProj/jni/third_party/libyuv/source/compare_neon64.cc b/TMessagesProj/jni/third_party/libyuv/source/compare_neon64.cc index 6e8f672ab..70fb9b914 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/compare_neon64.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/compare_neon64.cc @@ -27,22 +27,24 @@ uint32_t HammingDistance_NEON(const uint8_t* src_a, int count) { uint32_t diff; asm volatile( - "movi v4.8h, #0 \n" + "movi v4.8h, #0 \n" "1: \n" - "ld1 {v0.16b, v1.16b}, [%0], #32 \n" - "ld1 {v2.16b, v3.16b}, [%1], #32 \n" - "eor v0.16b, v0.16b, v2.16b \n" - "eor v1.16b, v1.16b, v3.16b \n" - "cnt v0.16b, v0.16b \n" - "cnt v1.16b, v1.16b \n" - "subs %w2, %w2, #32 \n" - "add v0.16b, v0.16b, v1.16b \n" - "uadalp v4.8h, v0.16b \n" - "b.gt 1b \n" + "ld1 {v0.16b, v1.16b}, [%0], #32 \n" + "ld1 {v2.16b, v3.16b}, [%1], #32 \n" + "eor v0.16b, v0.16b, v2.16b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "eor v1.16b, v1.16b, v3.16b \n" + "cnt v0.16b, v0.16b \n" + "prfm pldl1keep, [%1, 448] \n" + "cnt v1.16b, v1.16b \n" + "subs %w2, %w2, #32 \n" + "add v0.16b, v0.16b, v1.16b \n" + "uadalp v4.8h, v0.16b \n" + "b.gt 1b \n" - "uaddlv s4, v4.8h \n" - "fmov %w3, s4 \n" + "uaddlv s4, v4.8h \n" + "fmov %w3, s4 \n" : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(diff) : : "cc", "v0", "v1", "v2", "v3", "v4"); @@ -54,28 +56,30 @@ uint32_t SumSquareError_NEON(const uint8_t* src_a, int count) { uint32_t sse; asm volatile( - "eor v16.16b, v16.16b, v16.16b \n" - "eor v18.16b, v18.16b, v18.16b \n" - "eor v17.16b, v17.16b, v17.16b \n" - "eor v19.16b, v19.16b, v19.16b \n" + "eor v16.16b, v16.16b, v16.16b \n" + "eor v18.16b, v18.16b, v18.16b \n" + "eor v17.16b, v17.16b, v17.16b \n" + "eor v19.16b, v19.16b, v19.16b \n" "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" - "ld1 {v1.16b}, [%1], #16 \n" - "subs %w2, %w2, #16 \n" - "usubl v2.8h, v0.8b, v1.8b \n" - "usubl2 v3.8h, v0.16b, v1.16b \n" - "smlal v16.4s, v2.4h, v2.4h \n" - "smlal v17.4s, v3.4h, v3.4h \n" - "smlal2 v18.4s, v2.8h, v2.8h \n" - "smlal2 v19.4s, v3.8h, v3.8h \n" - "b.gt 1b \n" + "ld1 {v0.16b}, [%0], #16 \n" + "ld1 {v1.16b}, [%1], #16 \n" + "subs %w2, %w2, #16 \n" + "usubl v2.8h, v0.8b, v1.8b \n" + "usubl2 v3.8h, v0.16b, v1.16b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "smlal v16.4s, v2.4h, v2.4h \n" + "smlal v17.4s, v3.4h, v3.4h \n" + "prfm pldl1keep, [%1, 448] \n" + "smlal2 v18.4s, v2.8h, v2.8h \n" + "smlal2 v19.4s, v3.8h, v3.8h \n" + "b.gt 1b \n" - "add v16.4s, v16.4s, v17.4s \n" - "add v18.4s, v18.4s, v19.4s \n" - "add v19.4s, v16.4s, v18.4s \n" - "addv s0, v19.4s \n" - "fmov %w3, s0 \n" + "add v16.4s, v16.4s, v17.4s \n" + "add v18.4s, v18.4s, v19.4s \n" + "add v19.4s, v16.4s, v18.4s \n" + "addv s0, v19.4s \n" + "fmov %w3, s0 \n" : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(sse) : : "cc", "v0", "v1", "v2", "v3", "v16", "v17", "v18", "v19"); diff --git a/TMessagesProj/jni/third_party/libyuv/source/convert.cc b/TMessagesProj/jni/third_party/libyuv/source/convert.cc index 614fa4824..98258b9bc 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/convert.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/convert.cc @@ -320,14 +320,6 @@ int I422ToNV21(const uint8_t* src_y, } } #endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow = MergeUVRow_Any_MSA; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow = MergeUVRow_MSA; - } - } -#endif #if defined(HAS_MERGEUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { MergeUVRow = MergeUVRow_Any_MMI; @@ -336,6 +328,14 @@ int I422ToNV21(const uint8_t* src_y, } } #endif +#if defined(HAS_MERGEUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MergeUVRow = MergeUVRow_Any_MSA; + if (IS_ALIGNED(halfwidth, 16)) { + MergeUVRow = MergeUVRow_MSA; + } + } +#endif #if defined(HAS_INTERPOLATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { InterpolateRow = InterpolateRow_Any_SSSE3; @@ -360,14 +360,6 @@ int I422ToNV21(const uint8_t* src_y, } } #endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif #if defined(HAS_INTERPOLATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { InterpolateRow = InterpolateRow_Any_MMI; @@ -376,6 +368,14 @@ int I422ToNV21(const uint8_t* src_y, } } #endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + InterpolateRow = InterpolateRow_MSA; + } + } +#endif if (dst_y) { CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, halfwidth, height); @@ -426,7 +426,41 @@ int I444ToI420(const uint8_t* src_y, dst_v, dst_stride_v, width, height, width, height); } -// TODO(fbarchard): Implement row conversion. +LIBYUV_API +int I444ToNV12(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height) { + if (!src_y || !src_u || !src_v || !dst_y || !dst_uv || width <= 0 || + height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_y = src_y + (height - 1) * src_stride_y; + src_u = src_u + (height - 1) * src_stride_u; + src_v = src_v + (height - 1) * src_stride_v; + src_stride_y = -src_stride_y; + src_stride_u = -src_stride_u; + src_stride_v = -src_stride_v; + } + if (dst_y) { + CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); + } + HalfMergeUVPlane(src_u, src_stride_u, src_v, src_stride_v, dst_uv, + dst_stride_uv, width, height); + return 0; +} + LIBYUV_API int I444ToNV21(const uint8_t* src_y, int src_stride_y, @@ -440,30 +474,9 @@ int I444ToNV21(const uint8_t* src_y, int dst_stride_vu, int width, int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (height - 1) * src_stride_u; - src_v = src_v + (height - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - // Allocate u and v buffers - align_buffer_64(plane_u, halfwidth * halfheight * 2); - uint8_t* plane_v = plane_u + halfwidth * halfheight; - - I444ToI420(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, - dst_y, dst_stride_y, plane_u, halfwidth, plane_v, halfwidth, width, - height); - MergeUVPlane(plane_v, halfwidth, plane_u, halfwidth, dst_vu, dst_stride_vu, - halfwidth, halfheight); - free_aligned_buffer_64(plane_u); - return 0; + return I444ToNV12(src_y, src_stride_y, src_v, src_stride_v, src_u, + src_stride_u, dst_y, dst_stride_y, dst_vu, dst_stride_vu, + width, height); } // I400 is greyscale typically used in MJPG @@ -527,120 +540,8 @@ int I400ToNV21(const uint8_t* src_y, return 0; } -static void CopyPlane2(const uint8_t* src, - int src_stride_0, - int src_stride_1, - uint8_t* dst, - int dst_stride, - int width, - int height) { - int y; - void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C; -#if defined(HAS_COPYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; - } -#endif -#if defined(HAS_COPYROW_AVX) - if (TestCpuFlag(kCpuHasAVX)) { - CopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX; - } -#endif -#if defined(HAS_COPYROW_ERMS) - if (TestCpuFlag(kCpuHasERMS)) { - CopyRow = CopyRow_ERMS; - } -#endif -#if defined(HAS_COPYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON; - } -#endif - - // Copy plane - for (y = 0; y < height - 1; y += 2) { - CopyRow(src, dst, width); - CopyRow(src + src_stride_0, dst + dst_stride, width); - src += src_stride_0 + src_stride_1; - dst += dst_stride * 2; - } - if (height & 1) { - CopyRow(src, dst, width); - } -} - -// Support converting from FOURCC_M420 -// Useful for bandwidth constrained transports like USB 1.0 and 2.0 and for -// easy conversion to I420. -// M420 format description: -// M420 is row biplanar 420: 2 rows of Y and 1 row of UV. -// Chroma is half width / half height. (420) -// src_stride_m420 is row planar. Normally this will be the width in pixels. -// The UV plane is half width, but 2 values, so src_stride_m420 applies to -// this as well as the two Y planes. -static int X420ToI420(const uint8_t* src_y, - int src_stride_y0, - int src_stride_y1, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_uv || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - if (dst_y) { - dst_y = dst_y + (height - 1) * dst_stride_y; - } - dst_u = dst_u + (halfheight - 1) * dst_stride_u; - dst_v = dst_v + (halfheight - 1) * dst_stride_v; - dst_stride_y = -dst_stride_y; - dst_stride_u = -dst_stride_u; - dst_stride_v = -dst_stride_v; - } - // Coalesce rows. - if (src_stride_y0 == width && src_stride_y1 == width && - dst_stride_y == width) { - width *= height; - height = 1; - src_stride_y0 = src_stride_y1 = dst_stride_y = 0; - } - // Coalesce rows. - if (src_stride_uv == halfwidth * 2 && dst_stride_u == halfwidth && - dst_stride_v == halfwidth) { - halfwidth *= halfheight; - halfheight = 1; - src_stride_uv = dst_stride_u = dst_stride_v = 0; - } - - if (dst_y) { - if (src_stride_y0 == src_stride_y1) { - CopyPlane(src_y, src_stride_y0, dst_y, dst_stride_y, width, height); - } else { - CopyPlane2(src_y, src_stride_y0, src_stride_y1, dst_y, dst_stride_y, - width, height); - } - } - - // Split UV plane - NV12 / NV21 - SplitUVPlane(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, dst_stride_v, - halfwidth, halfheight); - - return 0; -} - // Convert NV12 to I420. +// TODO(fbarchard): Consider inverting destination. Faster on ARM with prfm. LIBYUV_API int NV12ToI420(const uint8_t* src_y, int src_stride_y, @@ -654,9 +555,43 @@ int NV12ToI420(const uint8_t* src_y, int dst_stride_v, int width, int height) { - return X420ToI420(src_y, src_stride_y, src_stride_y, src_uv, src_stride_uv, - dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, width, height); + int halfwidth = (width + 1) >> 1; + int halfheight = (height + 1) >> 1; + if (!src_uv || !dst_u || !dst_v || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + halfheight = (height + 1) >> 1; + src_y = src_y + (height - 1) * src_stride_y; + src_uv = src_uv + (halfheight - 1) * src_stride_uv; + src_stride_y = -src_stride_y; + src_stride_uv = -src_stride_uv; + } + // Coalesce rows. + if (src_stride_y == width && dst_stride_y == width) { + width *= height; + height = 1; + src_stride_y = dst_stride_y = 0; + } + // Coalesce rows. + if (src_stride_uv == halfwidth * 2 && dst_stride_u == halfwidth && + dst_stride_v == halfwidth) { + halfwidth *= halfheight; + halfheight = 1; + src_stride_uv = dst_stride_u = dst_stride_v = 0; + } + + if (dst_y) { + CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); + } + + // Split UV plane - NV12 / NV21 + SplitUVPlane(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, dst_stride_v, + halfwidth, halfheight); + + return 0; } // Convert NV21 to I420. Same as NV12 but u and v pointers swapped. @@ -673,26 +608,8 @@ int NV21ToI420(const uint8_t* src_y, int dst_stride_v, int width, int height) { - return X420ToI420(src_y, src_stride_y, src_stride_y, src_vu, src_stride_vu, - dst_y, dst_stride_y, dst_v, dst_stride_v, dst_u, - dst_stride_u, width, height); -} - -// Convert M420 to I420. -LIBYUV_API -int M420ToI420(const uint8_t* src_m420, - int src_stride_m420, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - return X420ToI420(src_m420, src_stride_m420, src_stride_m420 * 2, - src_m420 + src_stride_m420 * 2, src_stride_m420 * 3, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, + return NV12ToI420(src_y, src_stride_y, src_vu, src_stride_vu, dst_y, + dst_stride_y, dst_v, dst_stride_v, dst_u, dst_stride_u, width, height); } @@ -750,17 +667,7 @@ int YUY2ToI420(const uint8_t* src_yuy2, } } #endif -#if defined(HAS_YUY2TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - YUY2ToYRow = YUY2ToYRow_Any_MSA; - YUY2ToUVRow = YUY2ToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - YUY2ToYRow = YUY2ToYRow_MSA; - YUY2ToUVRow = YUY2ToUVRow_MSA; - } - } -#endif -#if defined(HAS_YUY2TOYROW_MMI) +#if defined(HAS_YUY2TOYROW_MMI) && defined(HAS_YUY2TOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { YUY2ToYRow = YUY2ToYRow_Any_MMI; YUY2ToUVRow = YUY2ToUVRow_Any_MMI; @@ -772,6 +679,16 @@ int YUY2ToI420(const uint8_t* src_yuy2, } } #endif +#if defined(HAS_YUY2TOYROW_MSA) && defined(HAS_YUY2TOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + YUY2ToYRow = YUY2ToYRow_Any_MSA; + YUY2ToUVRow = YUY2ToUVRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + YUY2ToYRow = YUY2ToYRow_MSA; + YUY2ToUVRow = YUY2ToUVRow_MSA; + } + } +#endif for (y = 0; y < height - 1; y += 2) { YUY2ToUVRow(src_yuy2, src_stride_yuy2, dst_u, dst_v, width); @@ -843,6 +760,16 @@ int UYVYToI420(const uint8_t* src_uyvy, } } #endif +#if defined(HAS_UYVYTOYROW_MMI) && defined(HAS_UYVYTOUVROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + UYVYToYRow = UYVYToYRow_Any_MMI; + UYVYToUVRow = UYVYToUVRow_Any_MMI; + if (IS_ALIGNED(width, 16)) { + UYVYToYRow = UYVYToYRow_MMI; + UYVYToUVRow = UYVYToUVRow_MMI; + } + } +#endif #if defined(HAS_UYVYTOYROW_MSA) if (TestCpuFlag(kCpuHasMSA)) { UYVYToYRow = UYVYToYRow_Any_MSA; @@ -853,16 +780,6 @@ int UYVYToI420(const uint8_t* src_uyvy, } } #endif -#if defined(HAS_UYVYTOYROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - UYVYToYRow = UYVYToYRow_Any_MMI; - UYVYToUVRow = UYVYToUVRow_Any_MMI; - if (IS_ALIGNED(width, 16)) { - UYVYToYRow = UYVYToYRow_MMI; - UYVYToUVRow = UYVYToUVRow_MMI; - } - } -#endif for (y = 0; y < height - 1; y += 2) { UYVYToUVRow(src_uyvy, src_stride_uyvy, dst_u, dst_v, width); @@ -1081,38 +998,30 @@ int ARGBToI420(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOYROW_MMI) +#if defined(HAS_ARGBTOYROW_MMI) && defined(HAS_ARGBTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYRow = ARGBToYRow_Any_MMI; + ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ARGBToYRow = ARGBToYRow_MMI; } - } -#endif -#if defined(HAS_ARGBTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { ARGBToUVRow = ARGBToUVRow_MMI; } } #endif +#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + ARGBToUVRow = ARGBToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_MSA; + } + } +#endif for (y = 0; y < height - 1; y += 2) { ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width); @@ -1183,38 +1092,28 @@ int BGRAToI420(const uint8_t* src_bgra, } } #endif -#if defined(HAS_BGRATOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - BGRAToYRow = BGRAToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - BGRAToYRow = BGRAToYRow_MSA; - } - } -#endif -#if defined(HAS_BGRATOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - BGRAToUVRow = BGRAToUVRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - BGRAToUVRow = BGRAToUVRow_MSA; - } - } -#endif -#if defined(HAS_BGRATOYROW_MMI) +#if defined(HAS_BGRATOYROW_MMI) && defined(HAS_BGRATOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { BGRAToYRow = BGRAToYRow_Any_MMI; + BGRAToUVRow = BGRAToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { BGRAToYRow = BGRAToYRow_MMI; } - } -#endif -#if defined(HAS_BGRATOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - BGRAToUVRow = BGRAToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { BGRAToUVRow = BGRAToUVRow_MMI; } } #endif +#if defined(HAS_BGRATOYROW_MSA) && defined(HAS_BGRATOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + BGRAToYRow = BGRAToYRow_Any_MSA; + BGRAToUVRow = BGRAToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + BGRAToYRow = BGRAToYRow_MSA; + BGRAToUVRow = BGRAToUVRow_MSA; + } + } +#endif for (y = 0; y < height - 1; y += 2) { BGRAToUVRow(src_bgra, src_stride_bgra, dst_u, dst_v, width); @@ -1269,6 +1168,16 @@ int ABGRToI420(const uint8_t* src_abgr, } } #endif +#if defined(HAS_ABGRTOYROW_AVX2) && defined(HAS_ABGRTOUVROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ABGRToUVRow = ABGRToUVRow_Any_AVX2; + ABGRToYRow = ABGRToYRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + ABGRToUVRow = ABGRToUVRow_AVX2; + ABGRToYRow = ABGRToYRow_AVX2; + } + } +#endif #if defined(HAS_ABGRTOYROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { ABGRToYRow = ABGRToYRow_Any_NEON; @@ -1285,38 +1194,28 @@ int ABGRToI420(const uint8_t* src_abgr, } } #endif -#if defined(HAS_ABGRTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ABGRToYRow = ABGRToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ABGRToYRow = ABGRToYRow_MSA; - } - } -#endif -#if defined(HAS_ABGRTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ABGRToUVRow = ABGRToUVRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ABGRToUVRow = ABGRToUVRow_MSA; - } - } -#endif -#if defined(HAS_ABGRTOYROW_MMI) +#if defined(HAS_ABGRTOYROW_MMI) && defined(HAS_ABGRTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ABGRToYRow = ABGRToYRow_Any_MMI; + ABGRToUVRow = ABGRToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ABGRToYRow = ABGRToYRow_MMI; } - } -#endif -#if defined(HAS_ABGRTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ABGRToUVRow = ABGRToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { ABGRToUVRow = ABGRToUVRow_MMI; } } #endif +#if defined(HAS_ABGRTOYROW_MSA) && defined(HAS_ABGRTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ABGRToYRow = ABGRToYRow_Any_MSA; + ABGRToUVRow = ABGRToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ABGRToYRow = ABGRToYRow_MSA; + ABGRToUVRow = ABGRToUVRow_MSA; + } + } +#endif for (y = 0; y < height - 1; y += 2) { ABGRToUVRow(src_abgr, src_stride_abgr, dst_u, dst_v, width); @@ -1387,38 +1286,28 @@ int RGBAToI420(const uint8_t* src_rgba, } } #endif -#if defined(HAS_RGBATOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGBAToYRow = RGBAToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGBAToYRow = RGBAToYRow_MSA; - } - } -#endif -#if defined(HAS_RGBATOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGBAToUVRow = RGBAToUVRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGBAToUVRow = RGBAToUVRow_MSA; - } - } -#endif -#if defined(HAS_RGBATOYROW_MMI) +#if defined(HAS_RGBATOYROW_MMI) && defined(HAS_RGBATOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RGBAToYRow = RGBAToYRow_Any_MMI; + RGBAToUVRow = RGBAToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { RGBAToYRow = RGBAToYRow_MMI; } - } -#endif -#if defined(HAS_RGBATOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - RGBAToUVRow = RGBAToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { RGBAToUVRow = RGBAToUVRow_MMI; } } #endif +#if defined(HAS_RGBATOYROW_MSA) && defined(HAS_RGBATOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RGBAToYRow = RGBAToYRow_Any_MSA; + RGBAToUVRow = RGBAToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RGBAToYRow = RGBAToYRow_MSA; + RGBAToUVRow = RGBAToUVRow_MSA; + } + } +#endif for (y = 0; y < height - 1; y += 2) { RGBAToUVRow(src_rgba, src_stride_rgba, dst_u, dst_v, width); @@ -1487,16 +1376,9 @@ int RGB24ToI420(const uint8_t* src_rgb24, } } } -#elif defined(HAS_RGB24TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB24ToUVRow = RGB24ToUVRow_Any_MSA; - RGB24ToYRow = RGB24ToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB24ToYRow = RGB24ToYRow_MSA; - RGB24ToUVRow = RGB24ToUVRow_MSA; - } - } -#elif defined(HAS_RGB24TOYROW_MMI) +// MMI and MSA version does direct RGB24 to YUV. +#elif (defined(HAS_RGB24TOYROW_MMI) || defined(HAS_RGB24TOYROW_MSA)) +#if defined(HAS_RGB24TOYROW_MMI) && defined(HAS_RGB24TOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RGB24ToUVRow = RGB24ToUVRow_Any_MMI; RGB24ToYRow = RGB24ToYRow_Any_MMI; @@ -1507,6 +1389,17 @@ int RGB24ToI420(const uint8_t* src_rgb24, } } } +#endif +#if defined(HAS_RGB24TOYROW_MSA) && defined(HAS_RGB24TOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RGB24ToUVRow = RGB24ToUVRow_Any_MSA; + RGB24ToYRow = RGB24ToYRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RGB24ToYRow = RGB24ToYRow_MSA; + RGB24ToUVRow = RGB24ToUVRow_MSA; + } + } +#endif // Other platforms do intermediate conversion from RGB24 to ARGB. #else #if defined(HAS_RGB24TOARGBROW_SSSE3) @@ -1598,8 +1491,8 @@ int RGB24ToJ420(const uint8_t* src_rgb24, int width, int height) { int y; -#if (defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) +#if (defined(HAS_RGB24TOYJROW_NEON) && defined(HAS_RGB24TOUVJROW_NEON)) || \ + defined(HAS_RGB24TOYJROW_MSA) || defined(HAS_RGB24TOYJROW_MMI) void (*RGB24ToUVJRow)(const uint8_t* src_rgb24, int src_stride_rgb24, uint8_t* dst_u, uint8_t* dst_v, int width) = RGB24ToUVJRow_C; @@ -1625,7 +1518,7 @@ int RGB24ToJ420(const uint8_t* src_rgb24, } // Neon version does direct RGB24 to YUV. -#if defined(HAS_RGB24TOYJROW_NEON) +#if defined(HAS_RGB24TOYJROW_NEON) && defined(HAS_RGB24TOUVJROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { RGB24ToUVJRow = RGB24ToUVJRow_Any_NEON; RGB24ToYJRow = RGB24ToYJRow_Any_NEON; @@ -1636,16 +1529,9 @@ int RGB24ToJ420(const uint8_t* src_rgb24, } } } -#elif defined(HAS_RGB24TOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB24ToUVJRow = RGB24ToUVJRow_Any_MSA; - RGB24ToYJRow = RGB24ToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB24ToYJRow = RGB24ToYJRow_MSA; - RGB24ToUVJRow = RGB24ToUVJRow_MSA; - } - } -#elif defined(HAS_RGB24TOYJROW_MMI) +// MMI and MSA version does direct RGB24 to YUV. +#elif (defined(HAS_RGB24TOYJROW_MMI) || defined(HAS_RGB24TOYJROW_MSA)) +#if defined(HAS_RGB24TOYJROW_MMI) && defined(HAS_RGB24TOUVJROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RGB24ToUVJRow = RGB24ToUVJRow_Any_MMI; RGB24ToYJRow = RGB24ToYJRow_Any_MMI; @@ -1656,7 +1542,17 @@ int RGB24ToJ420(const uint8_t* src_rgb24, } } } -// Other platforms do intermediate conversion from RGB24 to ARGB. +#endif +#if defined(HAS_RGB24TOYJROW_MSA) && defined(HAS_RGB24TOUVJROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RGB24ToUVJRow = RGB24ToUVJRow_Any_MSA; + RGB24ToYJRow = RGB24ToYJRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RGB24ToYJRow = RGB24ToYJRow_MSA; + RGB24ToUVJRow = RGB24ToUVJRow_MSA; + } + } +#endif #else #if defined(HAS_RGB24TOARGBROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { @@ -1689,16 +1585,16 @@ int RGB24ToJ420(const uint8_t* src_rgb24, #endif { -#if !(defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) +#if !((defined(HAS_RGB24TOYJROW_NEON) && defined(HAS_RGB24TOUVJROW_NEON)) || \ + defined(HAS_RGB24TOYJROW_MSA) || defined(HAS_RGB24TOYJROW_MMI)) // Allocate 2 rows of ARGB. const int kRowSize = (width * 4 + 31) & ~31; align_buffer_64(row, kRowSize * 2); #endif for (y = 0; y < height - 1; y += 2) { -#if (defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) +#if ((defined(HAS_RGB24TOYJROW_NEON) && defined(HAS_RGB24TOUVJROW_NEON)) || \ + defined(HAS_RGB24TOYJROW_MSA) || defined(HAS_RGB24TOYJROW_MMI)) RGB24ToUVJRow(src_rgb24, src_stride_rgb24, dst_u, dst_v, width); RGB24ToYJRow(src_rgb24, dst_y, width); RGB24ToYJRow(src_rgb24 + src_stride_rgb24, dst_y + dst_stride_y, width); @@ -1715,8 +1611,8 @@ int RGB24ToJ420(const uint8_t* src_rgb24, dst_v += dst_stride_v; } if (height & 1) { -#if (defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) +#if ((defined(HAS_RGB24TOYJROW_NEON) && defined(HAS_RGB24TOUVJROW_NEON)) || \ + defined(HAS_RGB24TOYJROW_MSA) || defined(HAS_RGB24TOYJROW_MMI)) RGB24ToUVJRow(src_rgb24, 0, dst_u, dst_v, width); RGB24ToYJRow(src_rgb24, dst_y, width); #else @@ -1725,8 +1621,8 @@ int RGB24ToJ420(const uint8_t* src_rgb24, ARGBToYJRow(row, dst_y, width); #endif } -#if !(defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) +#if !((defined(HAS_RGB24TOYJROW_NEON) && defined(HAS_RGB24TOUVJROW_NEON)) || \ + defined(HAS_RGB24TOYJROW_MSA) || defined(HAS_RGB24TOYJROW_MMI)) free_aligned_buffer_64(row); #endif } @@ -1746,8 +1642,8 @@ int RAWToI420(const uint8_t* src_raw, int width, int height) { int y; -#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || \ - defined(HAS_RAWTOYROW_MMI)) +#if (defined(HAS_RAWTOYROW_NEON) && defined(HAS_RAWTOUVROW_NEON)) || \ + defined(HAS_RAWTOYROW_MSA) || defined(HAS_RAWTOYROW_MMI) void (*RAWToUVRow)(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_u, uint8_t* dst_v, int width) = RAWToUVRow_C; void (*RAWToYRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) = @@ -1772,7 +1668,7 @@ int RAWToI420(const uint8_t* src_raw, } // Neon version does direct RAW to YUV. -#if defined(HAS_RAWTOYROW_NEON) +#if defined(HAS_RAWTOYROW_NEON) && defined(HAS_RAWTOUVROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { RAWToUVRow = RAWToUVRow_Any_NEON; RAWToYRow = RAWToYRow_Any_NEON; @@ -1783,16 +1679,9 @@ int RAWToI420(const uint8_t* src_raw, } } } -#elif defined(HAS_RAWTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RAWToUVRow = RAWToUVRow_Any_MSA; - RAWToYRow = RAWToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RAWToYRow = RAWToYRow_MSA; - RAWToUVRow = RAWToUVRow_MSA; - } - } -#elif defined(HAS_RAWTOYROW_MMI) +// MMI and MSA version does direct RAW to YUV. +#elif (defined(HAS_RAWTOYROW_MMI) || defined(HAS_RAWTOYROW_MSA)) +#if defined(HAS_RAWTOYROW_MMI) && defined(HAS_RAWTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RAWToUVRow = RAWToUVRow_Any_MMI; RAWToYRow = RAWToYRow_Any_MMI; @@ -1803,6 +1692,17 @@ int RAWToI420(const uint8_t* src_raw, } } } +#endif +#if defined(HAS_RAWTOYROW_MSA) && defined(HAS_RAWTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RAWToUVRow = RAWToUVRow_Any_MSA; + RAWToYRow = RAWToYRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RAWToYRow = RAWToYRow_MSA; + RAWToUVRow = RAWToUVRow_MSA; + } + } +#endif // Other platforms do intermediate conversion from RAW to ARGB. #else #if defined(HAS_RAWTOARGBROW_SSSE3) @@ -1931,16 +1831,9 @@ int RGB565ToI420(const uint8_t* src_rgb565, } } } -#elif defined(HAS_RGB565TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB565ToUVRow = RGB565ToUVRow_Any_MSA; - RGB565ToYRow = RGB565ToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB565ToYRow = RGB565ToYRow_MSA; - RGB565ToUVRow = RGB565ToUVRow_MSA; - } - } -#elif defined(HAS_RGB565TOYROW_MMI) +// MMI and MSA version does direct RGB565 to YUV. +#elif (defined(HAS_RGB565TOYROW_MMI) || defined(HAS_RGB565TOYROW_MSA)) +#if defined(HAS_RGB565TOYROW_MMI) && defined(HAS_RGB565TOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RGB565ToUVRow = RGB565ToUVRow_Any_MMI; RGB565ToYRow = RGB565ToYRow_Any_MMI; @@ -1951,6 +1844,17 @@ int RGB565ToI420(const uint8_t* src_rgb565, } } } +#endif +#if defined(HAS_RGB565TOYROW_MSA) && defined(HAS_RGB565TOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RGB565ToUVRow = RGB565ToUVRow_Any_MSA; + RGB565ToYRow = RGB565ToYRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RGB565ToYRow = RGB565ToYRow_MSA; + RGB565ToUVRow = RGB565ToUVRow_MSA; + } + } +#endif // Other platforms do intermediate conversion from RGB565 to ARGB. #else #if defined(HAS_RGB565TOARGBROW_SSE2) @@ -2086,16 +1990,9 @@ int ARGB1555ToI420(const uint8_t* src_argb1555, } } } -#elif defined(HAS_ARGB1555TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGB1555ToUVRow = ARGB1555ToUVRow_Any_MSA; - ARGB1555ToYRow = ARGB1555ToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGB1555ToYRow = ARGB1555ToYRow_MSA; - ARGB1555ToUVRow = ARGB1555ToUVRow_MSA; - } - } -#elif defined(HAS_ARGB1555TOYROW_MMI) +// MMI and MSA version does direct ARGB1555 to YUV. +#elif (defined(HAS_ARGB1555TOYROW_MMI) || defined(HAS_ARGB1555TOYROW_MSA)) +#if defined(HAS_ARGB1555TOYROW_MMI) && defined(HAS_ARGB1555TOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGB1555ToUVRow = ARGB1555ToUVRow_Any_MMI; ARGB1555ToYRow = ARGB1555ToYRow_Any_MMI; @@ -2106,6 +2003,17 @@ int ARGB1555ToI420(const uint8_t* src_argb1555, } } } +#endif +#if defined(HAS_ARGB1555TOYROW_MSA) && defined(HAS_ARGB1555TOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGB1555ToUVRow = ARGB1555ToUVRow_Any_MSA; + ARGB1555ToYRow = ARGB1555ToYRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGB1555ToYRow = ARGB1555ToYRow_MSA; + ARGB1555ToUVRow = ARGB1555ToUVRow_MSA; + } + } +#endif // Other platforms do intermediate conversion from ARGB1555 to ARGB. #else #if defined(HAS_ARGB1555TOARGBROW_SSE2) @@ -2243,7 +2151,7 @@ int ARGB4444ToI420(const uint8_t* src_argb4444, } } } -#elif defined(HAS_ARGB4444TOYROW_MMI) +#elif defined(HAS_ARGB4444TOYROW_MMI) && defined(HAS_ARGB4444TOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGB4444ToUVRow = ARGB4444ToUVRow_Any_MMI; ARGB4444ToYRow = ARGB4444ToYRow_Any_MMI; @@ -2300,19 +2208,7 @@ int ARGB4444ToI420(const uint8_t* src_argb4444, } } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } - } -#endif -#if defined(HAS_ARGBTOYROW_MMI) +#if defined(HAS_ARGBTOYROW_MMI) && defined(HAS_ARGBTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToUVRow = ARGBToUVRow_Any_MMI; ARGBToYRow = ARGBToYRow_Any_MMI; @@ -2324,6 +2220,18 @@ int ARGB4444ToI420(const uint8_t* src_argb4444, } } #endif +#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToUVRow = ARGBToUVRow_Any_MSA; + ARGBToYRow = ARGBToYRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_MSA; + } + } + } +#endif #endif { @@ -2378,27 +2286,38 @@ int RGB24ToJ400(const uint8_t* src_rgb24, int width, int height) { int y; -#if (defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) void (*RGB24ToYJRow)(const uint8_t* src_rgb24, uint8_t* dst_yj, int width) = RGB24ToYJRow_C; -#else - void (*RGB24ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = - RGB24ToARGBRow_C; - void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_yj, int width) = - ARGBToYJRow_C; -#endif if (!src_rgb24 || !dst_yj || width <= 0 || height == 0) { return -1; } - // Negative height means invert the image. if (height < 0) { height = -height; src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; src_stride_rgb24 = -src_stride_rgb24; } - -// Neon version does direct RGB24 to YUV. + // Coalesce rows. + if (src_stride_rgb24 == width * 3 && dst_stride_yj == width) { + width *= height; + height = 1; + src_stride_rgb24 = dst_stride_yj = 0; + } +#if defined(HAS_RGB24TOYJROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + RGB24ToYJRow = RGB24ToYJRow_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + RGB24ToYJRow = RGB24ToYJRow_SSSE3; + } + } +#endif +#if defined(HAS_RGB24TOYJROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + RGB24ToYJRow = RGB24ToYJRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + RGB24ToYJRow = RGB24ToYJRow_AVX2; + } + } +#endif #if defined(HAS_RGB24TOYJROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { RGB24ToYJRow = RGB24ToYJRow_Any_NEON; @@ -2406,83 +2325,102 @@ int RGB24ToJ400(const uint8_t* src_rgb24, RGB24ToYJRow = RGB24ToYJRow_NEON; } } -#elif defined(HAS_RGB24TOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB24ToYJRow = RGB24ToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB24ToYJRow = RGB24ToYJRow_MSA; - } - } -#elif defined(HAS_RGB24TOYJROW_MMI) +#endif +#if defined(HAS_RGB24TOYJROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RGB24ToYJRow = RGB24ToYJRow_Any_MMI; if (IS_ALIGNED(width, 8)) { RGB24ToYJRow = RGB24ToYJRow_MMI; } } -// Other platforms do intermediate conversion from RGB24 to ARGB. -#else -#if defined(HAS_RGB24TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3; +#endif +#if defined(HAS_RGB24TOYJROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RGB24ToYJRow = RGB24ToYJRow_Any_MSA; if (IS_ALIGNED(width, 16)) { - RGB24ToARGBRow = RGB24ToARGBRow_SSSE3; + RGB24ToYJRow = RGB24ToYJRow_MSA; } } #endif -#if defined(HAS_ARGBTOYJROW_SSSE3) + + for (y = 0; y < height; ++y) { + RGB24ToYJRow(src_rgb24, dst_yj, width); + src_rgb24 += src_stride_rgb24; + dst_yj += dst_stride_yj; + } + return 0; +} + +// Convert RAW to J400. +LIBYUV_API +int RAWToJ400(const uint8_t* src_raw, + int src_stride_raw, + uint8_t* dst_yj, + int dst_stride_yj, + int width, + int height) { + int y; + void (*RAWToYJRow)(const uint8_t* src_raw, uint8_t* dst_yj, int width) = + RAWToYJRow_C; + if (!src_raw || !dst_yj || width <= 0 || height == 0) { + return -1; + } + if (height < 0) { + height = -height; + src_raw = src_raw + (height - 1) * src_stride_raw; + src_stride_raw = -src_stride_raw; + } + // Coalesce rows. + if (src_stride_raw == width * 3 && dst_stride_yj == width) { + width *= height; + height = 1; + src_stride_raw = dst_stride_yj = 0; + } +#if defined(HAS_RAWTOYJROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToYJRow = ARGBToYJRow_Any_SSSE3; + RAWToYJRow = RAWToYJRow_Any_SSSE3; if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_SSSE3; + RAWToYJRow = RAWToYJRow_SSSE3; } } #endif -#if defined(HAS_ARGBTOYJROW_AVX2) +#if defined(HAS_RAWTOYJROW_AVX2) if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToYJRow = ARGBToYJRow_Any_AVX2; + RAWToYJRow = RAWToYJRow_Any_AVX2; if (IS_ALIGNED(width, 32)) { - ARGBToYJRow = ARGBToYJRow_AVX2; + RAWToYJRow = RAWToYJRow_AVX2; } } #endif +#if defined(HAS_RAWTOYJROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + RAWToYJRow = RAWToYJRow_Any_NEON; + if (IS_ALIGNED(width, 8)) { + RAWToYJRow = RAWToYJRow_NEON; + } + } +#endif +#if defined(HAS_RAWTOYJROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + RAWToYJRow = RAWToYJRow_Any_MMI; + if (IS_ALIGNED(width, 8)) { + RAWToYJRow = RAWToYJRow_MMI; + } + } +#endif +#if defined(HAS_RAWTOYJROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RAWToYJRow = RAWToYJRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RAWToYJRow = RAWToYJRow_MSA; + } + } #endif - { -#if !(defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) - // Allocate 2 rows of ARGB. - const int kRowSize = (width * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); -#endif - - for (y = 0; y < height - 1; y += 2) { -#if (defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) - RGB24ToYJRow(src_rgb24, dst_yj, width); - RGB24ToYJRow(src_rgb24 + src_stride_rgb24, dst_yj + dst_stride_yj, width); -#else - RGB24ToARGBRow(src_rgb24, row, width); - RGB24ToARGBRow(src_rgb24 + src_stride_rgb24, row + kRowSize, width); - ARGBToYJRow(row, dst_yj, width); - ARGBToYJRow(row + kRowSize, dst_yj + dst_stride_yj, width); -#endif - src_rgb24 += src_stride_rgb24 * 2; - dst_yj += dst_stride_yj * 2; - } - if (height & 1) { -#if (defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) - RGB24ToYJRow(src_rgb24, dst_yj, width); -#else - RGB24ToARGBRow(src_rgb24, row, width); - ARGBToYJRow(row, dst_yj, width); -#endif - } -#if !(defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ - defined(HAS_RGB24TOYJROW_MMI)) - free_aligned_buffer_64(row); -#endif + for (y = 0; y < height; ++y) { + RAWToYJRow(src_raw, dst_yj, width); + src_raw += src_stride_raw; + dst_yj += dst_stride_yj; } return 0; } diff --git a/TMessagesProj/jni/third_party/libyuv/source/convert_argb.cc b/TMessagesProj/jni/third_party/libyuv/source/convert_argb.cc index 4217b1dc9..5e7225faf 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/convert_argb.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/convert_argb.cc @@ -47,18 +47,19 @@ int ARGBCopy(const uint8_t* src_argb, return 0; } -// Convert I420 to ARGB with matrix -static int I420ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert I420 to ARGB with matrix. +LIBYUV_API +int I420ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, uint8_t* rgb_buf, @@ -97,14 +98,6 @@ static int I420ToARGBMatrix(const uint8_t* src_y, } } #endif -#if defined(HAS_I422TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGBRow = I422ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_MSA; - } - } -#endif #if defined(HAS_I422TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422ToARGBRow = I422ToARGBRow_Any_MMI; @@ -113,6 +106,14 @@ static int I420ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToARGBRow = I422ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToARGBRow = I422ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { I422ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); @@ -270,18 +271,19 @@ int U420ToABGR(const uint8_t* src_y, width, height); } -// Convert I422 to ARGB with matrix -static int I422ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert I422 to ARGB with matrix. +LIBYUV_API +int I422ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, uint8_t* rgb_buf, @@ -327,14 +329,6 @@ static int I422ToARGBMatrix(const uint8_t* src_y, } } #endif -#if defined(HAS_I422TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGBRow = I422ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_MSA; - } - } -#endif #if defined(HAS_I422TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422ToARGBRow = I422ToARGBRow_Any_MMI; @@ -343,6 +337,14 @@ static int I422ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToARGBRow = I422ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToARGBRow = I422ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { I422ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); @@ -498,18 +500,19 @@ int U422ToABGR(const uint8_t* src_y, width, height); } -// Convert I444 to ARGB with matrix -static int I444ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert I444 to ARGB with matrix. +LIBYUV_API +int I444ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*I444ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, uint8_t* rgb_buf, @@ -555,14 +558,6 @@ static int I444ToARGBMatrix(const uint8_t* src_y, } } #endif -#if defined(HAS_I444TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I444ToARGBRow = I444ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I444ToARGBRow = I444ToARGBRow_MSA; - } - } -#endif #if defined(HAS_I444TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I444ToARGBRow = I444ToARGBRow_Any_MMI; @@ -571,6 +566,14 @@ static int I444ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I444TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I444ToARGBRow = I444ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I444ToARGBRow = I444ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { I444ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); @@ -726,20 +729,21 @@ int U444ToABGR(const uint8_t* src_y, width, height); } -// Convert 10 bit YUV to ARGB with matrix +// Convert 10 bit YUV to ARGB with matrix. // TODO(fbarchard): Consider passing scale multiplier to I210ToARGB to // multiply 10 bit yuv into high bits to allow any number of bits. -static int I010ToAR30Matrix(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - const struct YuvConstants* yuvconstants, - int width, - int height) { +LIBYUV_API +int I010ToAR30Matrix(const uint16_t* src_y, + int src_stride_y, + const uint16_t* src_u, + int src_stride_u, + const uint16_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*I210ToAR30Row)(const uint16_t* y_buf, const uint16_t* u_buf, const uint16_t* v_buf, uint8_t* rgb_buf, @@ -884,20 +888,21 @@ int U010ToAB30(const uint16_t* src_y, &kYuv2020Constants, width, height); } -// Convert 10 bit YUV to ARGB with matrix +// Convert 10 bit YUV to ARGB with matrix. // TODO(fbarchard): Consider passing scale multiplier to I210ToARGB to // multiply 10 bit yuv into high bits to allow any number of bits. -static int I210ToAR30Matrix(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - const struct YuvConstants* yuvconstants, - int width, - int height) { +LIBYUV_API +int I210ToAR30Matrix(const uint16_t* src_y, + int src_stride_y, + const uint16_t* src_u, + int src_stride_u, + const uint16_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*I210ToAR30Row)(const uint16_t* y_buf, const uint16_t* u_buf, const uint16_t* v_buf, uint8_t* rgb_buf, @@ -1040,18 +1045,19 @@ int U210ToAB30(const uint16_t* src_y, &kYuv2020Constants, width, height); } -// Convert 10 bit YUV to ARGB with matrix -static int I010ToARGBMatrix(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert 10 bit YUV to ARGB with matrix. +LIBYUV_API +int I010ToARGBMatrix(const uint16_t* src_y, + int src_stride_y, + const uint16_t* src_u, + int src_stride_u, + const uint16_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*I210ToARGBRow)(const uint16_t* y_buf, const uint16_t* u_buf, const uint16_t* v_buf, uint8_t* rgb_buf, @@ -1210,18 +1216,19 @@ int U010ToABGR(const uint16_t* src_y, width, height); } -// Convert 10 bit 422 YUV to ARGB with matrix -static int I210ToARGBMatrix(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert 10 bit 422 YUV to ARGB with matrix. +LIBYUV_API +int I210ToARGBMatrix(const uint16_t* src_y, + int src_stride_y, + const uint16_t* src_u, + int src_stride_u, + const uint16_t* src_v, + int src_stride_v, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*I210ToARGBRow)(const uint16_t* y_buf, const uint16_t* u_buf, const uint16_t* v_buf, uint8_t* rgb_buf, @@ -1270,9 +1277,6 @@ static int I210ToARGBMatrix(const uint16_t* src_y, return 0; } - - - // Convert I210 to ARGB. LIBYUV_API int I210ToARGB(const uint16_t* src_y, @@ -1381,21 +1385,22 @@ int U210ToABGR(const uint16_t* src_y, width, height); } -// Convert I420 with Alpha to preattenuated ARGB. -static int I420AlphaToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - const uint8_t* src_a, - int src_stride_a, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height, - int attenuate) { +// Convert I420 with Alpha to preattenuated ARGB with matrix. +LIBYUV_API +int I420AlphaToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + const uint8_t* src_a, + int src_stride_a, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height, + int attenuate) { int y; void (*I422AlphaToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, const uint8_t* a_buf, @@ -1437,14 +1442,6 @@ static int I420AlphaToARGBMatrix(const uint8_t* src_y, } } #endif -#if defined(HAS_I422ALPHATOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_MSA; - } - } -#endif #if defined(HAS_I422ALPHATOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422AlphaToARGBRow = I422AlphaToARGBRow_Any_MMI; @@ -1453,6 +1450,14 @@ static int I420AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422ALPHATOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422AlphaToARGBRow = I422AlphaToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422AlphaToARGBRow = I422AlphaToARGBRow_MSA; + } + } +#endif #if defined(HAS_ARGBATTENUATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; @@ -1477,14 +1482,6 @@ static int I420AlphaToARGBMatrix(const uint8_t* src_y, } } #endif -#if defined(HAS_ARGBATTENUATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBAttenuateRow = ARGBAttenuateRow_MSA; - } - } -#endif #if defined(HAS_ARGBATTENUATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBAttenuateRow = ARGBAttenuateRow_Any_MMI; @@ -1493,6 +1490,14 @@ static int I420AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBAttenuateRow = ARGBAttenuateRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBAttenuateRow = ARGBAttenuateRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { I422AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants, @@ -1554,16 +1559,18 @@ int I420AlphaToABGR(const uint8_t* src_y, width, height, attenuate); } -// Convert I400 to ARGB. +// Convert I400 to ARGB with matrix. LIBYUV_API -int I400ToARGB(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { +int I400ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; - void (*I400ToARGBRow)(const uint8_t* y_buf, uint8_t* rgb_buf, int width) = + void (*I400ToARGBRow)(const uint8_t* y_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = I400ToARGBRow_C; if (!src_y || !dst_argb || width <= 0 || height == 0) { return -1; @@ -1604,14 +1611,6 @@ int I400ToARGB(const uint8_t* src_y, } } #endif -#if defined(HAS_I400TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I400ToARGBRow = I400ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - I400ToARGBRow = I400ToARGBRow_MSA; - } - } -#endif #if defined(HAS_I400TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I400ToARGBRow = I400ToARGBRow_Any_MMI; @@ -1620,15 +1619,35 @@ int I400ToARGB(const uint8_t* src_y, } } #endif +#if defined(HAS_I400TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I400ToARGBRow = I400ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + I400ToARGBRow = I400ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { - I400ToARGBRow(src_y, dst_argb, width); + I400ToARGBRow(src_y, dst_argb, yuvconstants, width); dst_argb += dst_stride_argb; src_y += src_stride_y; } return 0; } +// Convert I400 to ARGB. +LIBYUV_API +int I400ToARGB(const uint8_t* src_y, + int src_stride_y, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height) { + return I400ToARGBMatrix(src_y, src_stride_y, dst_argb, dst_stride_argb, + &kYuvI601Constants, width, height); +} + // Convert J400 to ARGB. LIBYUV_API int J400ToARGB(const uint8_t* src_y, @@ -1679,14 +1698,6 @@ int J400ToARGB(const uint8_t* src_y, } } #endif -#if defined(HAS_J400TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - J400ToARGBRow = J400ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - J400ToARGBRow = J400ToARGBRow_MSA; - } - } -#endif #if defined(HAS_J400TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { J400ToARGBRow = J400ToARGBRow_Any_MMI; @@ -1694,6 +1705,14 @@ int J400ToARGB(const uint8_t* src_y, J400ToARGBRow = J400ToARGBRow_MMI; } } +#endif +#if defined(HAS_J400TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + J400ToARGBRow = J400ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + J400ToARGBRow = J400ToARGBRow_MSA; + } + } #endif for (y = 0; y < height; ++y) { J400ToARGBRow(src_y, dst_argb, width); @@ -1817,14 +1836,6 @@ int RGB24ToARGB(const uint8_t* src_rgb24, } } #endif -#if defined(HAS_RGB24TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB24ToARGBRow = RGB24ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB24ToARGBRow = RGB24ToARGBRow_MSA; - } - } -#endif #if defined(HAS_RGB24TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RGB24ToARGBRow = RGB24ToARGBRow_Any_MMI; @@ -1833,6 +1844,14 @@ int RGB24ToARGB(const uint8_t* src_rgb24, } } #endif +#if defined(HAS_RGB24TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RGB24ToARGBRow = RGB24ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RGB24ToARGBRow = RGB24ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { RGB24ToARGBRow(src_rgb24, dst_argb, width); @@ -1884,14 +1903,6 @@ int RAWToARGB(const uint8_t* src_raw, } } #endif -#if defined(HAS_RAWTOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RAWToARGBRow = RAWToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RAWToARGBRow = RAWToARGBRow_MSA; - } - } -#endif #if defined(HAS_RAWTOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RAWToARGBRow = RAWToARGBRow_Any_MMI; @@ -1900,6 +1911,14 @@ int RAWToARGB(const uint8_t* src_raw, } } #endif +#if defined(HAS_RAWTOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RAWToARGBRow = RAWToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RAWToARGBRow = RAWToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { RAWToARGBRow(src_raw, dst_argb, width); @@ -2010,14 +2029,6 @@ int RGB565ToARGB(const uint8_t* src_rgb565, } } #endif -#if defined(HAS_RGB565TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB565ToARGBRow = RGB565ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB565ToARGBRow = RGB565ToARGBRow_MSA; - } - } -#endif #if defined(HAS_RGB565TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RGB565ToARGBRow = RGB565ToARGBRow_Any_MMI; @@ -2026,6 +2037,14 @@ int RGB565ToARGB(const uint8_t* src_rgb565, } } #endif +#if defined(HAS_RGB565TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RGB565ToARGBRow = RGB565ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RGB565ToARGBRow = RGB565ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { RGB565ToARGBRow(src_rgb565, dst_argb, width); @@ -2085,14 +2104,6 @@ int ARGB1555ToARGB(const uint8_t* src_argb1555, } } #endif -#if defined(HAS_ARGB1555TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_MSA; - } - } -#endif #if defined(HAS_ARGB1555TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_MMI; @@ -2101,6 +2112,14 @@ int ARGB1555ToARGB(const uint8_t* src_argb1555, } } #endif +#if defined(HAS_ARGB1555TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGB1555ToARGBRow = ARGB1555ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGB1555ToARGBRow(src_argb1555, dst_argb, width); @@ -2160,14 +2179,6 @@ int ARGB4444ToARGB(const uint8_t* src_argb4444, } } #endif -#if defined(HAS_ARGB4444TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_MSA; - } - } -#endif #if defined(HAS_ARGB4444TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MMI; @@ -2176,6 +2187,14 @@ int ARGB4444ToARGB(const uint8_t* src_argb4444, } } #endif +#if defined(HAS_ARGB4444TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGB4444ToARGBRow = ARGB4444ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGB4444ToARGBRow(src_argb4444, dst_argb, width); @@ -2281,16 +2300,17 @@ int AR30ToAB30(const uint8_t* src_ar30, return 0; } -// Convert NV12 to ARGB with matrix -static int NV12ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert NV12 to ARGB with matrix. +LIBYUV_API +int NV12ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*NV12ToARGBRow)( const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, @@ -2328,14 +2348,6 @@ static int NV12ToARGBMatrix(const uint8_t* src_y, } } #endif -#if defined(HAS_NV12TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - NV12ToARGBRow = NV12ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_MSA; - } - } -#endif #if defined(HAS_NV12TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { NV12ToARGBRow = NV12ToARGBRow_Any_MMI; @@ -2344,6 +2356,14 @@ static int NV12ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_NV12TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + NV12ToARGBRow = NV12ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + NV12ToARGBRow = NV12ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { NV12ToARGBRow(src_y, src_uv, dst_argb, yuvconstants, width); @@ -2356,16 +2376,17 @@ static int NV12ToARGBMatrix(const uint8_t* src_y, return 0; } -// Convert NV21 to ARGB with matrix -static int NV21ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert NV21 to ARGB with matrix. +LIBYUV_API +int NV21ToARGBMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_vu, + int src_stride_vu, + uint8_t* dst_argb, + int dst_stride_argb, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*NV21ToARGBRow)( const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, @@ -2403,14 +2424,6 @@ static int NV21ToARGBMatrix(const uint8_t* src_y, } } #endif -#if defined(HAS_NV21TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - NV21ToARGBRow = NV21ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - NV21ToARGBRow = NV21ToARGBRow_MSA; - } - } -#endif #if defined(HAS_NV21TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { NV21ToARGBRow = NV21ToARGBRow_Any_MMI; @@ -2419,6 +2432,14 @@ static int NV21ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_NV21TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + NV21ToARGBRow = NV21ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + NV21ToARGBRow = NV21ToARGBRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { NV21ToARGBRow(src_y, src_vu, dst_argb, yuvconstants, width); @@ -2490,16 +2511,17 @@ int NV21ToABGR(const uint8_t* src_y, } // TODO(fbarchard): Consider SSSE3 2 step conversion. -// Convert NV12 to RGB24 with matrix -static int NV12ToRGB24Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert NV12 to RGB24 with matrix. +LIBYUV_API +int NV12ToRGB24Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*NV12ToRGB24Row)( const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, @@ -2557,16 +2579,17 @@ static int NV12ToRGB24Matrix(const uint8_t* src_y, return 0; } -// Convert NV21 to RGB24 with matrix -static int NV21ToRGB24Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - const struct YuvConstants* yuvconstants, - int width, - int height) { +// Convert NV21 to RGB24 with matrix. +LIBYUV_API +int NV21ToRGB24Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_vu, + int src_stride_vu, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + const struct YuvConstants* yuvconstants, + int width, + int height) { int y; void (*NV21ToRGB24Row)( const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, @@ -2730,83 +2753,6 @@ int NV21ToYUV24(const uint8_t* src_y, return 0; } -// Convert M420 to ARGB. -LIBYUV_API -int M420ToARGB(const uint8_t* src_m420, - int src_stride_m420, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*NV12ToARGBRow)( - const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = NV12ToARGBRow_C; - if (!src_m420 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } -#if defined(HAS_NV12TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - NV12ToARGBRow = NV12ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - NV12ToARGBRow = NV12ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - NV12ToARGBRow = NV12ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - NV12ToARGBRow = NV12ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_MSA; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - NV12ToARGBRow = NV12ToARGBRow_Any_MMI; - if (IS_ALIGNED(width, 4)) { - NV12ToARGBRow = NV12ToARGBRow_MMI; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, - &kYuvI601Constants, width); - NV12ToARGBRow(src_m420 + src_stride_m420, src_m420 + src_stride_m420 * 2, - dst_argb + dst_stride_argb, &kYuvI601Constants, width); - dst_argb += dst_stride_argb * 2; - src_m420 += src_stride_m420 * 3; - } - if (height & 1) { - NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, - &kYuvI601Constants, width); - } - return 0; -} - // Convert YUY2 to ARGB. LIBYUV_API int YUY2ToARGB(const uint8_t* src_yuy2, @@ -2858,14 +2804,6 @@ int YUY2ToARGB(const uint8_t* src_yuy2, } } #endif -#if defined(HAS_YUY2TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - YUY2ToARGBRow = YUY2ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - YUY2ToARGBRow = YUY2ToARGBRow_MSA; - } - } -#endif #if defined(HAS_YUY2TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { YUY2ToARGBRow = YUY2ToARGBRow_Any_MMI; @@ -2873,6 +2811,14 @@ int YUY2ToARGB(const uint8_t* src_yuy2, YUY2ToARGBRow = YUY2ToARGBRow_MMI; } } +#endif +#if defined(HAS_YUY2TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + YUY2ToARGBRow = YUY2ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + YUY2ToARGBRow = YUY2ToARGBRow_MSA; + } + } #endif for (y = 0; y < height; ++y) { YUY2ToARGBRow(src_yuy2, dst_argb, &kYuvI601Constants, width); @@ -2933,14 +2879,6 @@ int UYVYToARGB(const uint8_t* src_uyvy, } } #endif -#if defined(HAS_UYVYTOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - UYVYToARGBRow = UYVYToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - UYVYToARGBRow = UYVYToARGBRow_MSA; - } - } -#endif #if defined(HAS_UYVYTOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { UYVYToARGBRow = UYVYToARGBRow_Any_MMI; @@ -2948,6 +2886,14 @@ int UYVYToARGB(const uint8_t* src_uyvy, UYVYToARGBRow = UYVYToARGBRow_MMI; } } +#endif +#if defined(HAS_UYVYTOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + UYVYToARGBRow = UYVYToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + UYVYToARGBRow = UYVYToARGBRow_MSA; + } + } #endif for (y = 0; y < height; ++y) { UYVYToARGBRow(src_uyvy, dst_argb, &kYuvI601Constants, width); @@ -2971,7 +2917,7 @@ static void WeavePixels(const uint8_t* src_u, } } -// Convert Android420 to ARGB. +// Convert Android420 to ARGB with matrix. LIBYUV_API int Android420ToARGBMatrix(const uint8_t* src_y, int src_stride_y, @@ -3072,6 +3018,1107 @@ int Android420ToABGR(const uint8_t* src_y, height); } +// Convert I422 to RGBA with matrix. +LIBYUV_API +int I422ToRGBAMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgba, + int dst_stride_rgba, + const struct YuvConstants* yuvconstants, + int width, + int height) { + int y; + void (*I422ToRGBARow)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = + I422ToRGBARow_C; + if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba; + dst_stride_rgba = -dst_stride_rgba; + } +#if defined(HAS_I422TORGBAROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToRGBARow = I422ToRGBARow_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + I422ToRGBARow = I422ToRGBARow_SSSE3; + } + } +#endif +#if defined(HAS_I422TORGBAROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToRGBARow = I422ToRGBARow_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + I422ToRGBARow = I422ToRGBARow_AVX2; + } + } +#endif +#if defined(HAS_I422TORGBAROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + I422ToRGBARow = I422ToRGBARow_Any_NEON; + if (IS_ALIGNED(width, 8)) { + I422ToRGBARow = I422ToRGBARow_NEON; + } + } +#endif +#if defined(HAS_I422TORGBAROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + I422ToRGBARow = I422ToRGBARow_Any_MMI; + if (IS_ALIGNED(width, 4)) { + I422ToRGBARow = I422ToRGBARow_MMI; + } + } +#endif +#if defined(HAS_I422TORGBAROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToRGBARow = I422ToRGBARow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToRGBARow = I422ToRGBARow_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width); + dst_rgba += dst_stride_rgba; + src_y += src_stride_y; + src_u += src_stride_u; + src_v += src_stride_v; + } + return 0; +} + +// Convert I422 to RGBA. +LIBYUV_API +int I422ToRGBA(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgba, + int dst_stride_rgba, + int width, + int height) { + return I422ToRGBAMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_rgba, dst_stride_rgba, + &kYuvI601Constants, width, height); +} + +// Convert I422 to BGRA. +LIBYUV_API +int I422ToBGRA(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_bgra, + int dst_stride_bgra, + int width, + int height) { + return I422ToRGBAMatrix(src_y, src_stride_y, src_v, + src_stride_v, // Swap U and V + src_u, src_stride_u, dst_bgra, dst_stride_bgra, + &kYvuI601Constants, // Use Yvu matrix + width, height); +} + +// Convert NV12 to RGB565 with matrix. +LIBYUV_API +int NV12ToRGB565Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + const struct YuvConstants* yuvconstants, + int width, + int height) { + int y; + void (*NV12ToRGB565Row)( + const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = NV12ToRGB565Row_C; + if (!src_y || !src_uv || !dst_rgb565 || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; + dst_stride_rgb565 = -dst_stride_rgb565; + } +#if defined(HAS_NV12TORGB565ROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + NV12ToRGB565Row = NV12ToRGB565Row_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + NV12ToRGB565Row = NV12ToRGB565Row_SSSE3; + } + } +#endif +#if defined(HAS_NV12TORGB565ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + NV12ToRGB565Row = NV12ToRGB565Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + NV12ToRGB565Row = NV12ToRGB565Row_AVX2; + } + } +#endif +#if defined(HAS_NV12TORGB565ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + NV12ToRGB565Row = NV12ToRGB565Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + NV12ToRGB565Row = NV12ToRGB565Row_NEON; + } + } +#endif +#if defined(HAS_NV12TORGB565ROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + NV12ToRGB565Row = NV12ToRGB565Row_Any_MMI; + if (IS_ALIGNED(width, 4)) { + NV12ToRGB565Row = NV12ToRGB565Row_MMI; + } + } +#endif +#if defined(HAS_NV12TORGB565ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + NV12ToRGB565Row = NV12ToRGB565Row_Any_MSA; + if (IS_ALIGNED(width, 8)) { + NV12ToRGB565Row = NV12ToRGB565Row_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + NV12ToRGB565Row(src_y, src_uv, dst_rgb565, yuvconstants, width); + dst_rgb565 += dst_stride_rgb565; + src_y += src_stride_y; + if (y & 1) { + src_uv += src_stride_uv; + } + } + return 0; +} + +// Convert NV12 to RGB565. +LIBYUV_API +int NV12ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height) { + return NV12ToRGB565Matrix(src_y, src_stride_y, src_uv, src_stride_uv, + dst_rgb565, dst_stride_rgb565, &kYuvI601Constants, + width, height); +} + +// Convert I422 to RGBA with matrix. +LIBYUV_API +int I420ToRGBAMatrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgba, + int dst_stride_rgba, + const struct YuvConstants* yuvconstants, + int width, + int height) { + int y; + void (*I422ToRGBARow)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = + I422ToRGBARow_C; + if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba; + dst_stride_rgba = -dst_stride_rgba; + } +#if defined(HAS_I422TORGBAROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToRGBARow = I422ToRGBARow_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + I422ToRGBARow = I422ToRGBARow_SSSE3; + } + } +#endif +#if defined(HAS_I422TORGBAROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToRGBARow = I422ToRGBARow_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + I422ToRGBARow = I422ToRGBARow_AVX2; + } + } +#endif +#if defined(HAS_I422TORGBAROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + I422ToRGBARow = I422ToRGBARow_Any_NEON; + if (IS_ALIGNED(width, 8)) { + I422ToRGBARow = I422ToRGBARow_NEON; + } + } +#endif +#if defined(HAS_I422TORGBAROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + I422ToRGBARow = I422ToRGBARow_Any_MMI; + if (IS_ALIGNED(width, 4)) { + I422ToRGBARow = I422ToRGBARow_MMI; + } + } +#endif +#if defined(HAS_I422TORGBAROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToRGBARow = I422ToRGBARow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToRGBARow = I422ToRGBARow_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width); + dst_rgba += dst_stride_rgba; + src_y += src_stride_y; + if (y & 1) { + src_u += src_stride_u; + src_v += src_stride_v; + } + } + return 0; +} + +// Convert I420 to RGBA. +LIBYUV_API +int I420ToRGBA(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgba, + int dst_stride_rgba, + int width, + int height) { + return I420ToRGBAMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_rgba, dst_stride_rgba, + &kYuvI601Constants, width, height); +} + +// Convert I420 to BGRA. +LIBYUV_API +int I420ToBGRA(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_bgra, + int dst_stride_bgra, + int width, + int height) { + return I420ToRGBAMatrix(src_y, src_stride_y, src_v, + src_stride_v, // Swap U and V + src_u, src_stride_u, dst_bgra, dst_stride_bgra, + &kYvuI601Constants, // Use Yvu matrix + width, height); +} + +// Convert I420 to RGB24 with matrix. +LIBYUV_API +int I420ToRGB24Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + const struct YuvConstants* yuvconstants, + int width, + int height) { + int y; + void (*I422ToRGB24Row)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = + I422ToRGB24Row_C; + if (!src_y || !src_u || !src_v || !dst_rgb24 || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24; + dst_stride_rgb24 = -dst_stride_rgb24; + } +#if defined(HAS_I422TORGB24ROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToRGB24Row = I422ToRGB24Row_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + I422ToRGB24Row = I422ToRGB24Row_SSSE3; + } + } +#endif +#if defined(HAS_I422TORGB24ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToRGB24Row = I422ToRGB24Row_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + I422ToRGB24Row = I422ToRGB24Row_AVX2; + } + } +#endif +#if defined(HAS_I422TORGB24ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + I422ToRGB24Row = I422ToRGB24Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + I422ToRGB24Row = I422ToRGB24Row_NEON; + } + } +#endif +#if defined(HAS_I422TORGB24ROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + I422ToRGB24Row = I422ToRGB24Row_Any_MMI; + if (IS_ALIGNED(width, 4)) { + I422ToRGB24Row = I422ToRGB24Row_MMI; + } + } +#endif +#if defined(HAS_I422TORGB24ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToRGB24Row = I422ToRGB24Row_Any_MSA; + if (IS_ALIGNED(width, 16)) { + I422ToRGB24Row = I422ToRGB24Row_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + I422ToRGB24Row(src_y, src_u, src_v, dst_rgb24, yuvconstants, width); + dst_rgb24 += dst_stride_rgb24; + src_y += src_stride_y; + if (y & 1) { + src_u += src_stride_u; + src_v += src_stride_v; + } + } + return 0; +} + +// Convert I420 to RGB24. +LIBYUV_API +int I420ToRGB24(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + int width, + int height) { + return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_rgb24, dst_stride_rgb24, + &kYuvI601Constants, width, height); +} + +// Convert I420 to RAW. +LIBYUV_API +int I420ToRAW(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_raw, + int dst_stride_raw, + int width, + int height) { + return I420ToRGB24Matrix(src_y, src_stride_y, src_v, + src_stride_v, // Swap U and V + src_u, src_stride_u, dst_raw, dst_stride_raw, + &kYvuI601Constants, // Use Yvu matrix + width, height); +} + +// Convert J420 to RGB24. +LIBYUV_API +int J420ToRGB24(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + int width, + int height) { + return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_rgb24, dst_stride_rgb24, + &kYuvJPEGConstants, width, height); +} + +// Convert J420 to RAW. +LIBYUV_API +int J420ToRAW(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_raw, + int dst_stride_raw, + int width, + int height) { + return I420ToRGB24Matrix(src_y, src_stride_y, src_v, + src_stride_v, // Swap U and V + src_u, src_stride_u, dst_raw, dst_stride_raw, + &kYvuJPEGConstants, // Use Yvu matrix + width, height); +} + +// Convert H420 to RGB24. +LIBYUV_API +int H420ToRGB24(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + int width, + int height) { + return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_rgb24, dst_stride_rgb24, + &kYuvH709Constants, width, height); +} + +// Convert H420 to RAW. +LIBYUV_API +int H420ToRAW(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_raw, + int dst_stride_raw, + int width, + int height) { + return I420ToRGB24Matrix(src_y, src_stride_y, src_v, + src_stride_v, // Swap U and V + src_u, src_stride_u, dst_raw, dst_stride_raw, + &kYvuH709Constants, // Use Yvu matrix + width, height); +} + +// Convert I420 to ARGB1555. +LIBYUV_API +int I420ToARGB1555(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb1555, + int dst_stride_argb1555, + int width, + int height) { + int y; + void (*I422ToARGB1555Row)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, + int width) = I422ToARGB1555Row_C; + if (!src_y || !src_u || !src_v || !dst_argb1555 || width <= 0 || + height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_argb1555 = dst_argb1555 + (height - 1) * dst_stride_argb1555; + dst_stride_argb1555 = -dst_stride_argb1555; + } +#if defined(HAS_I422TOARGB1555ROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToARGB1555Row = I422ToARGB1555Row_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + I422ToARGB1555Row = I422ToARGB1555Row_SSSE3; + } + } +#endif +#if defined(HAS_I422TOARGB1555ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToARGB1555Row = I422ToARGB1555Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + I422ToARGB1555Row = I422ToARGB1555Row_AVX2; + } + } +#endif +#if defined(HAS_I422TOARGB1555ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + I422ToARGB1555Row = I422ToARGB1555Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + I422ToARGB1555Row = I422ToARGB1555Row_NEON; + } + } +#endif +#if defined(HAS_I422TOARGB1555ROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + I422ToARGB1555Row = I422ToARGB1555Row_Any_MMI; + if (IS_ALIGNED(width, 4)) { + I422ToARGB1555Row = I422ToARGB1555Row_MMI; + } + } +#endif +#if defined(HAS_I422TOARGB1555ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToARGB1555Row = I422ToARGB1555Row_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToARGB1555Row = I422ToARGB1555Row_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + I422ToARGB1555Row(src_y, src_u, src_v, dst_argb1555, &kYuvI601Constants, + width); + dst_argb1555 += dst_stride_argb1555; + src_y += src_stride_y; + if (y & 1) { + src_u += src_stride_u; + src_v += src_stride_v; + } + } + return 0; +} + +// Convert I420 to ARGB4444. +LIBYUV_API +int I420ToARGB4444(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_argb4444, + int dst_stride_argb4444, + int width, + int height) { + int y; + void (*I422ToARGB4444Row)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, + int width) = I422ToARGB4444Row_C; + if (!src_y || !src_u || !src_v || !dst_argb4444 || width <= 0 || + height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_argb4444 = dst_argb4444 + (height - 1) * dst_stride_argb4444; + dst_stride_argb4444 = -dst_stride_argb4444; + } +#if defined(HAS_I422TOARGB4444ROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToARGB4444Row = I422ToARGB4444Row_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + I422ToARGB4444Row = I422ToARGB4444Row_SSSE3; + } + } +#endif +#if defined(HAS_I422TOARGB4444ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToARGB4444Row = I422ToARGB4444Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + I422ToARGB4444Row = I422ToARGB4444Row_AVX2; + } + } +#endif +#if defined(HAS_I422TOARGB4444ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + I422ToARGB4444Row = I422ToARGB4444Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + I422ToARGB4444Row = I422ToARGB4444Row_NEON; + } + } +#endif +#if defined(HAS_I422TOARGB4444ROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + I422ToARGB4444Row = I422ToARGB4444Row_Any_MMI; + if (IS_ALIGNED(width, 4)) { + I422ToARGB4444Row = I422ToARGB4444Row_MMI; + } + } +#endif +#if defined(HAS_I422TOARGB4444ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToARGB4444Row = I422ToARGB4444Row_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToARGB4444Row = I422ToARGB4444Row_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + I422ToARGB4444Row(src_y, src_u, src_v, dst_argb4444, &kYuvI601Constants, + width); + dst_argb4444 += dst_stride_argb4444; + src_y += src_stride_y; + if (y & 1) { + src_u += src_stride_u; + src_v += src_stride_v; + } + } + return 0; +} + +// Convert I420 to RGB565 with specified color matrix. +LIBYUV_API +int I420ToRGB565Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + const struct YuvConstants* yuvconstants, + int width, + int height) { + int y; + void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = + I422ToRGB565Row_C; + if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; + dst_stride_rgb565 = -dst_stride_rgb565; + } +#if defined(HAS_I422TORGB565ROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToRGB565Row = I422ToRGB565Row_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + I422ToRGB565Row = I422ToRGB565Row_SSSE3; + } + } +#endif +#if defined(HAS_I422TORGB565ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToRGB565Row = I422ToRGB565Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + I422ToRGB565Row = I422ToRGB565Row_AVX2; + } + } +#endif +#if defined(HAS_I422TORGB565ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + I422ToRGB565Row = I422ToRGB565Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + I422ToRGB565Row = I422ToRGB565Row_NEON; + } + } +#endif +#if defined(HAS_I422TORGB565ROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + I422ToRGB565Row = I422ToRGB565Row_Any_MMI; + if (IS_ALIGNED(width, 4)) { + I422ToRGB565Row = I422ToRGB565Row_MMI; + } + } +#endif +#if defined(HAS_I422TORGB565ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToRGB565Row = I422ToRGB565Row_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToRGB565Row = I422ToRGB565Row_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + I422ToRGB565Row(src_y, src_u, src_v, dst_rgb565, yuvconstants, width); + dst_rgb565 += dst_stride_rgb565; + src_y += src_stride_y; + if (y & 1) { + src_u += src_stride_u; + src_v += src_stride_v; + } + } + return 0; +} + +// Convert I420 to RGB565. +LIBYUV_API +int I420ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height) { + return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_rgb565, dst_stride_rgb565, + &kYuvI601Constants, width, height); +} + +// Convert J420 to RGB565. +LIBYUV_API +int J420ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height) { + return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_rgb565, dst_stride_rgb565, + &kYuvJPEGConstants, width, height); +} + +// Convert H420 to RGB565. +LIBYUV_API +int H420ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height) { + return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_rgb565, dst_stride_rgb565, + &kYuvH709Constants, width, height); +} + +// Convert I422 to RGB565. +LIBYUV_API +int I422ToRGB565(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + int width, + int height) { + int y; + void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = + I422ToRGB565Row_C; + if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; + dst_stride_rgb565 = -dst_stride_rgb565; + } +#if defined(HAS_I422TORGB565ROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToRGB565Row = I422ToRGB565Row_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + I422ToRGB565Row = I422ToRGB565Row_SSSE3; + } + } +#endif +#if defined(HAS_I422TORGB565ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToRGB565Row = I422ToRGB565Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + I422ToRGB565Row = I422ToRGB565Row_AVX2; + } + } +#endif +#if defined(HAS_I422TORGB565ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + I422ToRGB565Row = I422ToRGB565Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + I422ToRGB565Row = I422ToRGB565Row_NEON; + } + } +#endif +#if defined(HAS_I422TORGB565ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToRGB565Row = I422ToRGB565Row_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToRGB565Row = I422ToRGB565Row_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + I422ToRGB565Row(src_y, src_u, src_v, dst_rgb565, &kYuvI601Constants, width); + dst_rgb565 += dst_stride_rgb565; + src_y += src_stride_y; + src_u += src_stride_u; + src_v += src_stride_v; + } + return 0; +} + +// Ordered 8x8 dither for 888 to 565. Values from 0 to 7. +static const uint8_t kDither565_4x4[16] = { + 0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2, +}; + +// Convert I420 to RGB565 with dithering. +LIBYUV_API +int I420ToRGB565Dither(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_rgb565, + int dst_stride_rgb565, + const uint8_t* dither4x4, + int width, + int height) { + int y; + void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = + I422ToARGBRow_C; + void (*ARGBToRGB565DitherRow)(const uint8_t* src_argb, uint8_t* dst_rgb, + const uint32_t dither4, int width) = + ARGBToRGB565DitherRow_C; + if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; + dst_stride_rgb565 = -dst_stride_rgb565; + } + if (!dither4x4) { + dither4x4 = kDither565_4x4; + } +#if defined(HAS_I422TOARGBROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToARGBRow = I422ToARGBRow_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + I422ToARGBRow = I422ToARGBRow_SSSE3; + } + } +#endif +#if defined(HAS_I422TOARGBROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToARGBRow = I422ToARGBRow_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + I422ToARGBRow = I422ToARGBRow_AVX2; + } + } +#endif +#if defined(HAS_I422TOARGBROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + I422ToARGBRow = I422ToARGBRow_Any_NEON; + if (IS_ALIGNED(width, 8)) { + I422ToARGBRow = I422ToARGBRow_NEON; + } + } +#endif +#if defined(HAS_I422TOARGBROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + I422ToARGBRow = I422ToARGBRow_Any_MMI; + if (IS_ALIGNED(width, 4)) { + I422ToARGBRow = I422ToARGBRow_MMI; + } + } +#endif +#if defined(HAS_I422TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToARGBRow = I422ToARGBRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + I422ToARGBRow = I422ToARGBRow_MSA; + } + } +#endif +#if defined(HAS_ARGBTORGB565DITHERROW_SSE2) + if (TestCpuFlag(kCpuHasSSE2)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_SSE2; + if (IS_ALIGNED(width, 4)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_SSE2; + } + } +#endif +#if defined(HAS_ARGBTORGB565DITHERROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_AVX2; + if (IS_ALIGNED(width, 8)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_AVX2; + } + } +#endif +#if defined(HAS_ARGBTORGB565DITHERROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_NEON; + if (IS_ALIGNED(width, 8)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_NEON; + } + } +#endif +#if defined(HAS_ARGBTORGB565DITHERROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MMI; + if (IS_ALIGNED(width, 4)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MMI; + } + } +#endif +#if defined(HAS_ARGBTORGB565DITHERROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MSA; + } + } +#endif + { + // Allocate a row of argb. + align_buffer_64(row_argb, width * 4); + for (y = 0; y < height; ++y) { + I422ToARGBRow(src_y, src_u, src_v, row_argb, &kYuvI601Constants, width); + ARGBToRGB565DitherRow(row_argb, dst_rgb565, + *(const uint32_t*)(dither4x4 + ((y & 3) << 2)), + width); + dst_rgb565 += dst_stride_rgb565; + src_y += src_stride_y; + if (y & 1) { + src_u += src_stride_u; + src_v += src_stride_v; + } + } + free_aligned_buffer_64(row_argb); + } + return 0; +} + +// Convert I420 to AR30 with matrix. +LIBYUV_API +int I420ToAR30Matrix(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + const struct YuvConstants* yuvconstants, + int width, + int height) { + int y; + void (*I422ToAR30Row)(const uint8_t* y_buf, const uint8_t* u_buf, + const uint8_t* v_buf, uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, int width) = + I422ToAR30Row_C; + + if (!src_y || !src_u || !src_v || !dst_ar30 || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_ar30 = dst_ar30 + (height - 1) * dst_stride_ar30; + dst_stride_ar30 = -dst_stride_ar30; + } + +#if defined(HAS_I422TOAR30ROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + I422ToAR30Row = I422ToAR30Row_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + I422ToAR30Row = I422ToAR30Row_SSSE3; + } + } +#endif +#if defined(HAS_I422TOAR30ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + I422ToAR30Row = I422ToAR30Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + I422ToAR30Row = I422ToAR30Row_AVX2; + } + } +#endif + + for (y = 0; y < height; ++y) { + I422ToAR30Row(src_y, src_u, src_v, dst_ar30, yuvconstants, width); + dst_ar30 += dst_stride_ar30; + src_y += src_stride_y; + if (y & 1) { + src_u += src_stride_u; + src_v += src_stride_v; + } + } + return 0; +} + +// Convert I420 to AR30. +LIBYUV_API +int I420ToAR30(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + int width, + int height) { + return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_ar30, dst_stride_ar30, + &kYuvI601Constants, width, height); +} + +// Convert H420 to AR30. +LIBYUV_API +int H420ToAR30(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + int width, + int height) { + return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_ar30, dst_stride_ar30, + &kYvuH709Constants, width, height); +} + #ifdef __cplusplus } // extern "C" } // namespace libyuv diff --git a/TMessagesProj/jni/third_party/libyuv/source/convert_from.cc b/TMessagesProj/jni/third_party/libyuv/source/convert_from.cc index 0c95f1f29..f2cfc1d8f 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/convert_from.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/convert_from.cc @@ -294,14 +294,6 @@ int I420ToYUY2(const uint8_t* src_y, } } #endif -#if defined(HAS_I422TOYUY2ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToYUY2Row = I422ToYUY2Row_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToYUY2Row = I422ToYUY2Row_MSA; - } - } -#endif #if defined(HAS_I422TOYUY2ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422ToYUY2Row = I422ToYUY2Row_Any_MMI; @@ -310,6 +302,14 @@ int I420ToYUY2(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOYUY2ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToYUY2Row = I422ToYUY2Row_Any_MSA; + if (IS_ALIGNED(width, 32)) { + I422ToYUY2Row = I422ToYUY2Row_MSA; + } + } +#endif for (y = 0; y < height - 1; y += 2) { I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width); @@ -381,14 +381,6 @@ int I422ToUYVY(const uint8_t* src_y, } } #endif -#if defined(HAS_I422TOUYVYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToUYVYRow = I422ToUYVYRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_MSA; - } - } -#endif #if defined(HAS_I422TOUYVYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422ToUYVYRow = I422ToUYVYRow_Any_MMI; @@ -397,6 +389,14 @@ int I422ToUYVY(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOUYVYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToUYVYRow = I422ToUYVYRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + I422ToUYVYRow = I422ToUYVYRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width); @@ -456,14 +456,6 @@ int I420ToUYVY(const uint8_t* src_y, } } #endif -#if defined(HAS_I422TOUYVYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToUYVYRow = I422ToUYVYRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_MSA; - } - } -#endif #if defined(HAS_I422TOUYVYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422ToUYVYRow = I422ToUYVYRow_Any_MMI; @@ -472,6 +464,14 @@ int I420ToUYVY(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOUYVYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToUYVYRow = I422ToUYVYRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + I422ToUYVYRow = I422ToUYVYRow_MSA; + } + } +#endif for (y = 0; y < height - 1; y += 2) { I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width); @@ -488,7 +488,6 @@ int I420ToUYVY(const uint8_t* src_y, return 0; } -// TODO(fbarchard): test negative height for invert. LIBYUV_API int I420ToNV12(const uint8_t* src_y, int src_stride_y, @@ -502,12 +501,23 @@ int I420ToNV12(const uint8_t* src_y, int dst_stride_uv, int width, int height) { + int halfwidth = (width + 1) / 2; + int halfheight = (height + 1) / 2; if (!src_y || !src_u || !src_v || !dst_y || !dst_uv || width <= 0 || height == 0) { return -1; } - int halfwidth = (width + 1) / 2; - int halfheight = height > 0 ? (height + 1) / 2 : (height - 1) / 2; + // Negative height means invert the image. + if (height < 0) { + height = -height; + halfheight = (height + 1) >> 1; + src_y = src_y + (height - 1) * src_stride_y; + src_u = src_u + (halfheight - 1) * src_stride_u; + src_v = src_v + (halfheight - 1) * src_stride_v; + src_stride_y = -src_stride_y; + src_stride_u = -src_stride_u; + src_stride_v = -src_stride_v; + } if (dst_y) { CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } @@ -534,899 +544,6 @@ int I420ToNV21(const uint8_t* src_y, width, height); } -// Convert I422 to RGBA with matrix -static int I420ToRGBAMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToRGBARow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGBARow_C; - if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba; - dst_stride_rgba = -dst_stride_rgba; - } -#if defined(HAS_I422TORGBAROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGBARow = I422ToRGBARow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGBAROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGBARow = I422ToRGBARow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGBARow = I422ToRGBARow_AVX2; - } - } -#endif -#if defined(HAS_I422TORGBAROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGBARow = I422ToRGBARow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_NEON; - } - } -#endif -#if defined(HAS_I422TORGBAROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGBARow = I422ToRGBARow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_MSA; - } - } -#endif -#if defined(HAS_I422TORGBAROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - I422ToRGBARow = I422ToRGBARow_Any_MMI; - if (IS_ALIGNED(width, 4)) { - I422ToRGBARow = I422ToRGBARow_MMI; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width); - dst_rgba += dst_stride_rgba; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to RGBA. -LIBYUV_API -int I420ToRGBA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height) { - return I420ToRGBAMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgba, dst_stride_rgba, - &kYuvI601Constants, width, height); -} - -// Convert I420 to BGRA. -LIBYUV_API -int I420ToBGRA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height) { - return I420ToRGBAMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_bgra, dst_stride_bgra, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert I420 to RGB24 with matrix -static int I420ToRGB24Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToRGB24Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGB24Row_C; - if (!src_y || !src_u || !src_v || !dst_rgb24 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24; - dst_stride_rgb24 = -dst_stride_rgb24; - } -#if defined(HAS_I422TORGB24ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGB24Row = I422ToRGB24Row_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - I422ToRGB24Row = I422ToRGB24Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGB24ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGB24Row = I422ToRGB24Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - I422ToRGB24Row = I422ToRGB24Row_AVX2; - } - } -#endif -#if defined(HAS_I422TORGB24ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGB24Row = I422ToRGB24Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGB24Row = I422ToRGB24Row_NEON; - } - } -#endif -#if defined(HAS_I422TORGB24ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGB24Row = I422ToRGB24Row_Any_MSA; - if (IS_ALIGNED(width, 16)) { - I422ToRGB24Row = I422ToRGB24Row_MSA; - } - } -#endif -#if defined(HAS_I422TORGB24ROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - I422ToRGB24Row = I422ToRGB24Row_Any_MMI; - if (IS_ALIGNED(width, 4)) { - I422ToRGB24Row = I422ToRGB24Row_MMI; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGB24Row(src_y, src_u, src_v, dst_rgb24, yuvconstants, width); - dst_rgb24 += dst_stride_rgb24; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to RGB24. -LIBYUV_API -int I420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgb24, dst_stride_rgb24, - &kYuvI601Constants, width, height); -} - -// Convert I420 to RAW. -LIBYUV_API -int I420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_raw, dst_stride_raw, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert J420 to RGB24. -LIBYUV_API -int J420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgb24, dst_stride_rgb24, - &kYuvJPEGConstants, width, height); -} - -// Convert J420 to RAW. -LIBYUV_API -int J420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_raw, dst_stride_raw, - &kYvuJPEGConstants, // Use Yvu matrix - width, height); -} - -// Convert H420 to RGB24. -LIBYUV_API -int H420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgb24, dst_stride_rgb24, - &kYuvH709Constants, width, height); -} - -// Convert H420 to RAW. -LIBYUV_API -int H420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_raw, dst_stride_raw, - &kYvuH709Constants, // Use Yvu matrix - width, height); -} - -// Convert I420 to ARGB1555. -LIBYUV_API -int I420ToARGB1555(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb1555, - int dst_stride_argb1555, - int width, - int height) { - int y; - void (*I422ToARGB1555Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) = I422ToARGB1555Row_C; - if (!src_y || !src_u || !src_v || !dst_argb1555 || width <= 0 || - height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb1555 = dst_argb1555 + (height - 1) * dst_stride_argb1555; - dst_stride_argb1555 = -dst_stride_argb1555; - } -#if defined(HAS_I422TOARGB1555ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToARGB1555Row = I422ToARGB1555Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGB1555ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToARGB1555Row = I422ToARGB1555Row_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGB1555ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToARGB1555Row = I422ToARGB1555Row_NEON; - } - } -#endif -#if defined(HAS_I422TOARGB1555ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGB1555Row = I422ToARGB1555Row_MSA; - } - } -#endif -#if defined(HAS_I422TOARGB1555ROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_MMI; - if (IS_ALIGNED(width, 4)) { - I422ToARGB1555Row = I422ToARGB1555Row_MMI; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToARGB1555Row(src_y, src_u, src_v, dst_argb1555, &kYuvI601Constants, - width); - dst_argb1555 += dst_stride_argb1555; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to ARGB4444. -LIBYUV_API -int I420ToARGB4444(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb4444, - int dst_stride_argb4444, - int width, - int height) { - int y; - void (*I422ToARGB4444Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) = I422ToARGB4444Row_C; - if (!src_y || !src_u || !src_v || !dst_argb4444 || width <= 0 || - height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb4444 = dst_argb4444 + (height - 1) * dst_stride_argb4444; - dst_stride_argb4444 = -dst_stride_argb4444; - } -#if defined(HAS_I422TOARGB4444ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToARGB4444Row = I422ToARGB4444Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGB4444ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToARGB4444Row = I422ToARGB4444Row_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGB4444ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToARGB4444Row = I422ToARGB4444Row_NEON; - } - } -#endif -#if defined(HAS_I422TOARGB4444ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGB4444Row = I422ToARGB4444Row_MSA; - } - } -#endif -#if defined(HAS_I422TOARGB4444ROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_MMI; - if (IS_ALIGNED(width, 4)) { - I422ToARGB4444Row = I422ToARGB4444Row_MMI; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToARGB4444Row(src_y, src_u, src_v, dst_argb4444, &kYuvI601Constants, - width); - dst_argb4444 += dst_stride_argb4444; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to RGB565 with specified color matrix. -LIBYUV_API -int I420ToRGB565Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGB565Row_C; - if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; - dst_stride_rgb565 = -dst_stride_rgb565; - } -#if defined(HAS_I422TORGB565ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGB565Row = I422ToRGB565Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGB565Row = I422ToRGB565Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGB565Row = I422ToRGB565Row_AVX2; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGB565Row = I422ToRGB565Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_NEON; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGB565Row = I422ToRGB565Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_MSA; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - I422ToRGB565Row = I422ToRGB565Row_Any_MMI; - if (IS_ALIGNED(width, 4)) { - I422ToRGB565Row = I422ToRGB565Row_MMI; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGB565Row(src_y, src_u, src_v, dst_rgb565, yuvconstants, width); - dst_rgb565 += dst_stride_rgb565; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to RGB565. -LIBYUV_API -int I420ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgb565, dst_stride_rgb565, - &kYuvI601Constants, width, height); -} - -// Convert J420 to RGB565. -LIBYUV_API -int J420ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgb565, dst_stride_rgb565, - &kYuvJPEGConstants, width, height); -} - -// Convert H420 to RGB565. -LIBYUV_API -int H420ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgb565, dst_stride_rgb565, - &kYuvH709Constants, width, height); -} - -// Convert I422 to RGB565. -LIBYUV_API -int I422ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - int y; - void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGB565Row_C; - if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; - dst_stride_rgb565 = -dst_stride_rgb565; - } -#if defined(HAS_I422TORGB565ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGB565Row = I422ToRGB565Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGB565Row = I422ToRGB565Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGB565Row = I422ToRGB565Row_AVX2; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGB565Row = I422ToRGB565Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_NEON; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGB565Row = I422ToRGB565Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGB565Row(src_y, src_u, src_v, dst_rgb565, &kYuvI601Constants, width); - dst_rgb565 += dst_stride_rgb565; - src_y += src_stride_y; - src_u += src_stride_u; - src_v += src_stride_v; - } - return 0; -} - -// Ordered 8x8 dither for 888 to 565. Values from 0 to 7. -static const uint8_t kDither565_4x4[16] = { - 0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2, -}; - -// Convert I420 to RGB565 with dithering. -LIBYUV_API -int I420ToRGB565Dither(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - const uint8_t* dither4x4, - int width, - int height) { - int y; - void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToARGBRow_C; - void (*ARGBToRGB565DitherRow)(const uint8_t* src_argb, uint8_t* dst_rgb, - const uint32_t dither4, int width) = - ARGBToRGB565DitherRow_C; - if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; - dst_stride_rgb565 = -dst_stride_rgb565; - } - if (!dither4x4) { - dither4x4 = kDither565_4x4; - } -#if defined(HAS_I422TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGBRow = I422ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGBRow = I422ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToARGBRow = I422ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGBRow = I422ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_I422TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGBRow = I422ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_MSA; - } - } -#endif -#if defined(HAS_I422TOARGBROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - I422ToARGBRow = I422ToARGBRow_Any_MMI; - if (IS_ALIGNED(width, 4)) { - I422ToARGBRow = I422ToARGBRow_MMI; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MMI; - if (IS_ALIGNED(width, 4)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MMI; - } - } -#endif - { - // Allocate a row of argb. - align_buffer_64(row_argb, width * 4); - for (y = 0; y < height; ++y) { - I422ToARGBRow(src_y, src_u, src_v, row_argb, &kYuvI601Constants, width); - ARGBToRGB565DitherRow(row_argb, dst_rgb565, - *(const uint32_t*)(dither4x4 + ((y & 3) << 2)), - width); - dst_rgb565 += dst_stride_rgb565; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - free_aligned_buffer_64(row_argb); - } - return 0; -} - -// Convert I420 to AR30 with matrix -static int I420ToAR30Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToAR30Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToAR30Row_C; - - if (!src_y || !src_u || !src_v || !dst_ar30 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_ar30 = dst_ar30 + (height - 1) * dst_stride_ar30; - dst_stride_ar30 = -dst_stride_ar30; - } - -#if defined(HAS_I422TOAR30ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToAR30Row = I422ToAR30Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToAR30Row = I422ToAR30Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TOAR30ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToAR30Row = I422ToAR30Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToAR30Row = I422ToAR30Row_AVX2; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToAR30Row(src_y, src_u, src_v, dst_ar30, yuvconstants, width); - dst_ar30 += dst_stride_ar30; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to AR30. -LIBYUV_API -int I420ToAR30(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height) { - return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_ar30, dst_stride_ar30, - &kYuvI601Constants, width, height); -} - -// Convert H420 to AR30. -LIBYUV_API -int H420ToAR30(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height) { - return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_ar30, dst_stride_ar30, - &kYvuH709Constants, width, height); -} - // Convert I420 to specified format LIBYUV_API int ConvertFromI420(const uint8_t* y, @@ -1528,7 +645,6 @@ int ConvertFromI420(const uint8_t* y, height); break; } - // TODO(fbarchard): Add M420. // Triplanar formats case FOURCC_I420: case FOURCC_YV12: { diff --git a/TMessagesProj/jni/third_party/libyuv/source/convert_from_argb.cc b/TMessagesProj/jni/third_party/libyuv/source/convert_from_argb.cc index de301ebbc..4ba4bb5e0 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/convert_from_argb.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/convert_from_argb.cc @@ -68,14 +68,6 @@ int ARGBToI444(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOUV444ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUV444Row = ARGBToUV444Row_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToUV444Row = ARGBToUV444Row_MSA; - } - } -#endif #if defined(HAS_ARGBTOUV444ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToUV444Row = ARGBToUV444Row_Any_MMI; @@ -84,6 +76,14 @@ int ARGBToI444(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOUV444ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToUV444Row = ARGBToUV444Row_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToUV444Row = ARGBToUV444Row_MSA; + } + } +#endif #if defined(HAS_ARGBTOYROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { ARGBToYRow = ARGBToYRow_Any_SSSE3; @@ -108,14 +108,6 @@ int ARGBToI444(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif #if defined(HAS_ARGBTOYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYRow = ARGBToYRow_Any_MMI; @@ -124,6 +116,14 @@ int ARGBToI444(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToUV444Row(src_argb, dst_u, dst_v, width); @@ -207,36 +207,28 @@ int ARGBToI422(const uint8_t* src_argb, } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; +#if defined(HAS_ARGBTOYROW_MMI) && defined(HAS_ARGBTOUVROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + ARGBToYRow = ARGBToYRow_Any_MMI; + ARGBToUVRow = ARGBToUVRow_Any_MMI; + if (IS_ALIGNED(width, 8)) { + ARGBToYRow = ARGBToYRow_MMI; } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToUVRow = ARGBToUVRow_MMI; } } #endif -#if defined(HAS_ARGBTOYROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToYRow = ARGBToYRow_Any_MMI; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_MMI; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToUVRow = ARGBToUVRow_Any_MMI; +#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + ARGBToUVRow = ARGBToUVRow_Any_MSA; if (IS_ALIGNED(width, 16)) { - ARGBToUVRow = ARGBToUVRow_MMI; + ARGBToYRow = ARGBToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_MSA; } } #endif @@ -315,38 +307,30 @@ int ARGBToNV12(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOYROW_MMI) +#if defined(HAS_ARGBTOYROW_MMI) && defined(HAS_ARGBTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYRow = ARGBToYRow_Any_MMI; + ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ARGBToYRow = ARGBToYRow_MMI; } - } -#endif -#if defined(HAS_ARGBTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { ARGBToUVRow = ARGBToUVRow_MMI; } } #endif +#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + ARGBToUVRow = ARGBToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_MSA; + } + } +#endif #if defined(HAS_MERGEUVROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeUVRow_ = MergeUVRow_Any_SSE2; @@ -371,14 +355,6 @@ int ARGBToNV12(const uint8_t* src_argb, } } #endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow_ = MergeUVRow_Any_MSA; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_MSA; - } - } -#endif #if defined(HAS_MERGEUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { MergeUVRow_ = MergeUVRow_Any_MMI; @@ -386,6 +362,14 @@ int ARGBToNV12(const uint8_t* src_argb, MergeUVRow_ = MergeUVRow_MMI; } } +#endif +#if defined(HAS_MERGEUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MergeUVRow_ = MergeUVRow_Any_MSA; + if (IS_ALIGNED(halfwidth, 16)) { + MergeUVRow_ = MergeUVRow_MSA; + } + } #endif { // Allocate a rows of uv. @@ -475,39 +459,30 @@ int ARGBToNV21(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOYROW_MMI) +#if defined(HAS_ARGBTOYROW_MMI) && defined(HAS_ARGBTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYRow = ARGBToYRow_Any_MMI; + ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ARGBToYRow = ARGBToYRow_MMI; } - } -#endif -#if defined(HAS_ARGBTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { ARGBToUVRow = ARGBToUVRow_MMI; } } #endif - +#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + ARGBToUVRow = ARGBToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_MSA; + } + } +#endif #if defined(HAS_MERGEUVROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeUVRow_ = MergeUVRow_Any_SSE2; @@ -532,14 +507,6 @@ int ARGBToNV21(const uint8_t* src_argb, } } #endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow_ = MergeUVRow_Any_MSA; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_MSA; - } - } -#endif #if defined(HAS_MERGEUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { MergeUVRow_ = MergeUVRow_Any_MMI; @@ -547,6 +514,14 @@ int ARGBToNV21(const uint8_t* src_argb, MergeUVRow_ = MergeUVRow_MMI; } } +#endif +#if defined(HAS_MERGEUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MergeUVRow_ = MergeUVRow_Any_MSA; + if (IS_ALIGNED(halfwidth, 16)) { + MergeUVRow_ = MergeUVRow_MSA; + } + } #endif { // Allocate a rows of uv. @@ -635,38 +610,30 @@ int ABGRToNV12(const uint8_t* src_abgr, } } #endif -#if defined(HAS_ABGRTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ABGRToYRow = ABGRToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ABGRToYRow = ABGRToYRow_MSA; - } - } -#endif -#if defined(HAS_ABGRTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ABGRToUVRow = ABGRToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ABGRToUVRow = ABGRToUVRow_MSA; - } - } -#endif -#if defined(HAS_ABGRTOYROW_MMI) +#if defined(HAS_ABGRTOYROW_MMI) && defined(HAS_ABGRTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ABGRToYRow = ABGRToYRow_Any_MMI; + ABGRToUVRow = ABGRToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ABGRToYRow = ABGRToYRow_MMI; } - } -#endif -#if defined(HAS_ABGRTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ABGRToUVRow = ABGRToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { ABGRToUVRow = ABGRToUVRow_MMI; } } #endif +#if defined(HAS_ABGRTOYROW_MSA) && defined(HAS_ABGRTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ABGRToYRow = ABGRToYRow_Any_MSA; + ABGRToUVRow = ABGRToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ABGRToYRow = ABGRToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ABGRToUVRow = ABGRToUVRow_MSA; + } + } +#endif #if defined(HAS_MERGEUVROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeUVRow_ = MergeUVRow_Any_SSE2; @@ -691,14 +658,6 @@ int ABGRToNV12(const uint8_t* src_abgr, } } #endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow_ = MergeUVRow_Any_MSA; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_MSA; - } - } -#endif #if defined(HAS_MERGEUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { MergeUVRow_ = MergeUVRow_Any_MMI; @@ -706,6 +665,14 @@ int ABGRToNV12(const uint8_t* src_abgr, MergeUVRow_ = MergeUVRow_MMI; } } +#endif +#if defined(HAS_MERGEUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MergeUVRow_ = MergeUVRow_Any_MSA; + if (IS_ALIGNED(halfwidth, 16)) { + MergeUVRow_ = MergeUVRow_MSA; + } + } #endif { // Allocate a rows of uv. @@ -795,39 +762,30 @@ int ABGRToNV21(const uint8_t* src_abgr, } } #endif -#if defined(HAS_ABGRTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ABGRToYRow = ABGRToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ABGRToYRow = ABGRToYRow_MSA; - } - } -#endif -#if defined(HAS_ABGRTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ABGRToUVRow = ABGRToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ABGRToUVRow = ABGRToUVRow_MSA; - } - } -#endif -#if defined(HAS_ABGRTOYROW_MMI) +#if defined(HAS_ABGRTOYROW_MMI) && defined(HAS_ABGRTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ABGRToYRow = ABGRToYRow_Any_MMI; + ABGRToUVRow = ABGRToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ABGRToYRow = ABGRToYRow_MMI; } - } -#endif -#if defined(HAS_ABGRTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ABGRToUVRow = ABGRToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { ABGRToUVRow = ABGRToUVRow_MMI; } } #endif - +#if defined(HAS_ABGRTOYROW_MSA) && defined(HAS_ABGRTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ABGRToYRow = ABGRToYRow_Any_MSA; + ABGRToUVRow = ABGRToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ABGRToYRow = ABGRToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ABGRToUVRow = ABGRToUVRow_MSA; + } + } +#endif #if defined(HAS_MERGEUVROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeUVRow_ = MergeUVRow_Any_SSE2; @@ -852,14 +810,6 @@ int ABGRToNV21(const uint8_t* src_abgr, } } #endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow_ = MergeUVRow_Any_MSA; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_MSA; - } - } -#endif #if defined(HAS_MERGEUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { MergeUVRow_ = MergeUVRow_Any_MMI; @@ -867,6 +817,14 @@ int ABGRToNV21(const uint8_t* src_abgr, MergeUVRow_ = MergeUVRow_MMI; } } +#endif +#if defined(HAS_MERGEUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MergeUVRow_ = MergeUVRow_Any_MSA; + if (IS_ALIGNED(halfwidth, 16)) { + MergeUVRow_ = MergeUVRow_MSA; + } + } #endif { // Allocate a rows of uv. @@ -961,38 +919,30 @@ int ARGBToYUY2(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOYROW_MMI) +#if defined(HAS_ARGBTOYROW_MMI) && defined(HAS_ARGBTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYRow = ARGBToYRow_Any_MMI; + ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ARGBToYRow = ARGBToYRow_MMI; } - } -#endif -#if defined(HAS_ARGBTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { ARGBToUVRow = ARGBToUVRow_MMI; } } #endif +#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + ARGBToUVRow = ARGBToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_MSA; + } + } +#endif #if defined(HAS_I422TOYUY2ROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { I422ToYUY2Row = I422ToYUY2Row_Any_SSE2; @@ -1017,14 +967,6 @@ int ARGBToYUY2(const uint8_t* src_argb, } } #endif -#if defined(HAS_I422TOYUY2ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToYUY2Row = I422ToYUY2Row_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToYUY2Row = I422ToYUY2Row_MSA; - } - } -#endif #if defined(HAS_I422TOYUY2ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422ToYUY2Row = I422ToYUY2Row_Any_MMI; @@ -1033,6 +975,14 @@ int ARGBToYUY2(const uint8_t* src_argb, } } #endif +#if defined(HAS_I422TOYUY2ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToYUY2Row = I422ToYUY2Row_Any_MSA; + if (IS_ALIGNED(width, 32)) { + I422ToYUY2Row = I422ToYUY2Row_MSA; + } + } +#endif { // Allocate a rows of yuv. @@ -1122,38 +1072,30 @@ int ARGBToUYVY(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOYROW_MMI) +#if defined(HAS_ARGBTOYROW_MMI) && defined(HAS_ARGBTOUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYRow = ARGBToYRow_Any_MMI; + ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ARGBToYRow = ARGBToYRow_MMI; } - } -#endif -#if defined(HAS_ARGBTOUVROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToUVRow = ARGBToUVRow_Any_MMI; if (IS_ALIGNED(width, 16)) { ARGBToUVRow = ARGBToUVRow_MMI; } } #endif +#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + ARGBToUVRow = ARGBToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_MSA; + } + } +#endif #if defined(HAS_I422TOUYVYROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { I422ToUYVYRow = I422ToUYVYRow_Any_SSE2; @@ -1178,14 +1120,6 @@ int ARGBToUYVY(const uint8_t* src_argb, } } #endif -#if defined(HAS_I422TOUYVYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToUYVYRow = I422ToUYVYRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_MSA; - } - } -#endif #if defined(HAS_I422TOUYVYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422ToUYVYRow = I422ToUYVYRow_Any_MMI; @@ -1194,6 +1128,14 @@ int ARGBToUYVY(const uint8_t* src_argb, } } #endif +#if defined(HAS_I422TOUYVYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToUYVYRow = I422ToUYVYRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + I422ToUYVYRow = I422ToUYVYRow_MSA; + } + } +#endif { // Allocate a rows of yuv. @@ -1263,14 +1205,6 @@ int ARGBToI400(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif #if defined(HAS_ARGBTOYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYRow = ARGBToYRow_Any_MMI; @@ -1279,6 +1213,14 @@ int ARGBToI400(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToYRow(src_argb, dst_y, width); @@ -1361,14 +1303,6 @@ int ARGBToRGB24(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTORGB24ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRGB24Row = ARGBToRGB24Row_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToRGB24Row = ARGBToRGB24Row_MSA; - } - } -#endif #if defined(HAS_ARGBTORGB24ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToRGB24Row = ARGBToRGB24Row_Any_MMI; @@ -1377,6 +1311,14 @@ int ARGBToRGB24(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTORGB24ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToRGB24Row = ARGBToRGB24Row_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToRGB24Row = ARGBToRGB24Row_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToRGB24Row(src_argb, dst_rgb24, width); @@ -1435,14 +1377,6 @@ int ARGBToRAW(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTORAWROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRAWRow = ARGBToRAWRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToRAWRow = ARGBToRAWRow_MSA; - } - } -#endif #if defined(HAS_ARGBTORAWROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToRAWRow = ARGBToRAWRow_Any_MMI; @@ -1451,6 +1385,14 @@ int ARGBToRAW(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTORAWROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToRAWRow = ARGBToRAWRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToRAWRow = ARGBToRAWRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToRAWRow(src_argb, dst_raw, width); @@ -1513,14 +1455,6 @@ int ARGBToRGB565Dither(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTORGB565DITHERROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MSA; - } - } -#endif #if defined(HAS_ARGBTORGB565DITHERROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MMI; @@ -1529,6 +1463,14 @@ int ARGBToRGB565Dither(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTORGB565DITHERROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToRGB565DitherRow(src_argb, dst_rgb565, @@ -1590,14 +1532,6 @@ int ARGBToRGB565(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTORGB565ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRGB565Row = ARGBToRGB565Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565Row = ARGBToRGB565Row_MSA; - } - } -#endif #if defined(HAS_ARGBTORGB565ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToRGB565Row = ARGBToRGB565Row_Any_MMI; @@ -1606,6 +1540,14 @@ int ARGBToRGB565(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTORGB565ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToRGB565Row = ARGBToRGB565Row_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBToRGB565Row = ARGBToRGB565Row_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToRGB565Row(src_argb, dst_rgb565, width); @@ -1664,14 +1606,6 @@ int ARGBToARGB1555(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOARGB1555ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_MSA; - } - } -#endif #if defined(HAS_ARGBTOARGB1555ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToARGB1555Row = ARGBToARGB1555Row_Any_MMI; @@ -1680,6 +1614,14 @@ int ARGBToARGB1555(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOARGB1555ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToARGB1555Row = ARGBToARGB1555Row_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBToARGB1555Row = ARGBToARGB1555Row_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToARGB1555Row(src_argb, dst_argb1555, width); @@ -1738,14 +1680,6 @@ int ARGBToARGB4444(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOARGB4444ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_MSA; - } - } -#endif #if defined(HAS_ARGBTOARGB4444ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToARGB4444Row = ARGBToARGB4444Row_Any_MMI; @@ -1754,6 +1688,14 @@ int ARGBToARGB4444(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOARGB4444ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToARGB4444Row = ARGBToARGB4444Row_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBToARGB4444Row = ARGBToARGB4444Row_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToARGB4444Row(src_argb, dst_argb4444, width); @@ -1922,35 +1864,27 @@ int ARGBToJ420(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYJRow = ARGBToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_MMI) +#if defined(HAS_ARGBTOYJROW_MMI) && defined(HAS_ARGBTOUVJROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYJRow = ARGBToYJRow_Any_MMI; + ARGBToUVJRow = ARGBToUVJRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ARGBToYJRow = ARGBToYJRow_MMI; } - } -#endif -#if defined(HAS_ARGBTOUVJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVJRow = ARGBToUVJRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVJRow = ARGBToUVJRow_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToUVJRow = ARGBToUVJRow_MMI; } } #endif -#if defined(HAS_ARGBTOUVJROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToUVJRow = ARGBToUVJRow_Any_MMI; +#if defined(HAS_ARGBTOYJROW_MSA) && defined(HAS_ARGBTOUVJROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYJRow = ARGBToYJRow_Any_MSA; + ARGBToUVJRow = ARGBToUVJRow_Any_MSA; if (IS_ALIGNED(width, 16)) { - ARGBToUVJRow = ARGBToUVJRow_MMI; + ARGBToYJRow = ARGBToYJRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVJRow = ARGBToUVJRow_MSA; } } #endif @@ -2039,35 +1973,27 @@ int ARGBToJ422(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYJRow = ARGBToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_MMI) +#if defined(HAS_ARGBTOYJROW_MMI) && defined(HAS_ARGBTOUVJROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYJRow = ARGBToYJRow_Any_MMI; + ARGBToUVJRow = ARGBToUVJRow_Any_MMI; if (IS_ALIGNED(width, 8)) { ARGBToYJRow = ARGBToYJRow_MMI; } - } -#endif -#if defined(HAS_ARGBTOUVJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVJRow = ARGBToUVJRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVJRow = ARGBToUVJRow_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToUVJRow = ARGBToUVJRow_MMI; } } #endif -#if defined(HAS_ARGBTOUVJROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - ARGBToUVJRow = ARGBToUVJRow_Any_MMI; +#if defined(HAS_ARGBTOYJROW_MSA) && defined(HAS_ARGBTOUVJROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYJRow = ARGBToYJRow_Any_MSA; + ARGBToUVJRow = ARGBToUVJRow_Any_MSA; if (IS_ALIGNED(width, 16)) { - ARGBToUVJRow = ARGBToUVJRow_MMI; + ARGBToYJRow = ARGBToYJRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVJRow = ARGBToUVJRow_MSA; } } #endif @@ -2132,14 +2058,6 @@ int ARGBToJ400(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYJRow = ARGBToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_MSA; - } - } -#endif #if defined(HAS_ARGBTOYJROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYJRow = ARGBToYJRow_Any_MMI; @@ -2148,6 +2066,14 @@ int ARGBToJ400(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYJROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYJRow = ARGBToYJRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYJRow = ARGBToYJRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBToYJRow(src_argb, dst_yj, width); @@ -2206,14 +2132,6 @@ int RGBAToJ400(const uint8_t* src_rgba, } } #endif -#if defined(HAS_RGBATOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGBAToYJRow = RGBAToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGBAToYJRow = RGBAToYJRow_MSA; - } - } -#endif #if defined(HAS_RGBATOYJROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RGBAToYJRow = RGBAToYJRow_Any_MMI; @@ -2222,6 +2140,14 @@ int RGBAToJ400(const uint8_t* src_rgba, } } #endif +#if defined(HAS_RGBATOYJROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RGBAToYJRow = RGBAToYJRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RGBAToYJRow = RGBAToYJRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { RGBAToYJRow(src_rgba, dst_yj, width); diff --git a/TMessagesProj/jni/third_party/libyuv/source/convert_jpeg.cc b/TMessagesProj/jni/third_party/libyuv/source/convert_jpeg.cc index f440c7c2e..d7556ee91 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/convert_jpeg.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/convert_jpeg.cc @@ -328,6 +328,140 @@ int MJPGToNV21(const uint8_t* src_mjpg, return ret ? 0 : 1; } +static void JpegI420ToNV12(void* opaque, + const uint8_t* const* data, + const int* strides, + int rows) { + NV21Buffers* dest = (NV21Buffers*)(opaque); + // Use NV21 with VU swapped. + I420ToNV21(data[0], strides[0], data[2], strides[2], data[1], strides[1], + dest->y, dest->y_stride, dest->vu, dest->vu_stride, dest->w, rows); + dest->y += rows * dest->y_stride; + dest->vu += ((rows + 1) >> 1) * dest->vu_stride; + dest->h -= rows; +} + +static void JpegI422ToNV12(void* opaque, + const uint8_t* const* data, + const int* strides, + int rows) { + NV21Buffers* dest = (NV21Buffers*)(opaque); + // Use NV21 with VU swapped. + I422ToNV21(data[0], strides[0], data[2], strides[2], data[1], strides[1], + dest->y, dest->y_stride, dest->vu, dest->vu_stride, dest->w, rows); + dest->y += rows * dest->y_stride; + dest->vu += ((rows + 1) >> 1) * dest->vu_stride; + dest->h -= rows; +} + +static void JpegI444ToNV12(void* opaque, + const uint8_t* const* data, + const int* strides, + int rows) { + NV21Buffers* dest = (NV21Buffers*)(opaque); + // Use NV21 with VU swapped. + I444ToNV21(data[0], strides[0], data[2], strides[2], data[1], strides[1], + dest->y, dest->y_stride, dest->vu, dest->vu_stride, dest->w, rows); + dest->y += rows * dest->y_stride; + dest->vu += ((rows + 1) >> 1) * dest->vu_stride; + dest->h -= rows; +} + +static void JpegI400ToNV12(void* opaque, + const uint8_t* const* data, + const int* strides, + int rows) { + NV21Buffers* dest = (NV21Buffers*)(opaque); + // Use NV21 since there is no UV plane. + I400ToNV21(data[0], strides[0], dest->y, dest->y_stride, dest->vu, + dest->vu_stride, dest->w, rows); + dest->y += rows * dest->y_stride; + dest->vu += ((rows + 1) >> 1) * dest->vu_stride; + dest->h -= rows; +} + +// MJPG (Motion JPEG) to NV12. +LIBYUV_API +int MJPGToNV12(const uint8_t* sample, + size_t sample_size, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int src_width, + int src_height, + int dst_width, + int dst_height) { + if (sample_size == kUnknownDataSize) { + // ERROR: MJPEG frame size unknown + return -1; + } + + // TODO(fbarchard): Port MJpeg to C. + MJpegDecoder mjpeg_decoder; + LIBYUV_BOOL ret = mjpeg_decoder.LoadFrame(sample, sample_size); + if (ret && (mjpeg_decoder.GetWidth() != src_width || + mjpeg_decoder.GetHeight() != src_height)) { + // ERROR: MJPEG frame has unexpected dimensions + mjpeg_decoder.UnloadFrame(); + return 1; // runtime failure + } + if (ret) { + // Use NV21Buffers but with UV instead of VU. + NV21Buffers bufs = {dst_y, dst_stride_y, dst_uv, + dst_stride_uv, dst_width, dst_height}; + // YUV420 + if (mjpeg_decoder.GetColorSpace() == MJpegDecoder::kColorSpaceYCbCr && + mjpeg_decoder.GetNumComponents() == 3 && + mjpeg_decoder.GetVertSampFactor(0) == 2 && + mjpeg_decoder.GetHorizSampFactor(0) == 2 && + mjpeg_decoder.GetVertSampFactor(1) == 1 && + mjpeg_decoder.GetHorizSampFactor(1) == 1 && + mjpeg_decoder.GetVertSampFactor(2) == 1 && + mjpeg_decoder.GetHorizSampFactor(2) == 1) { + ret = mjpeg_decoder.DecodeToCallback(&JpegI420ToNV12, &bufs, dst_width, + dst_height); + // YUV422 + } else if (mjpeg_decoder.GetColorSpace() == + MJpegDecoder::kColorSpaceYCbCr && + mjpeg_decoder.GetNumComponents() == 3 && + mjpeg_decoder.GetVertSampFactor(0) == 1 && + mjpeg_decoder.GetHorizSampFactor(0) == 2 && + mjpeg_decoder.GetVertSampFactor(1) == 1 && + mjpeg_decoder.GetHorizSampFactor(1) == 1 && + mjpeg_decoder.GetVertSampFactor(2) == 1 && + mjpeg_decoder.GetHorizSampFactor(2) == 1) { + ret = mjpeg_decoder.DecodeToCallback(&JpegI422ToNV12, &bufs, dst_width, + dst_height); + // YUV444 + } else if (mjpeg_decoder.GetColorSpace() == + MJpegDecoder::kColorSpaceYCbCr && + mjpeg_decoder.GetNumComponents() == 3 && + mjpeg_decoder.GetVertSampFactor(0) == 1 && + mjpeg_decoder.GetHorizSampFactor(0) == 1 && + mjpeg_decoder.GetVertSampFactor(1) == 1 && + mjpeg_decoder.GetHorizSampFactor(1) == 1 && + mjpeg_decoder.GetVertSampFactor(2) == 1 && + mjpeg_decoder.GetHorizSampFactor(2) == 1) { + ret = mjpeg_decoder.DecodeToCallback(&JpegI444ToNV12, &bufs, dst_width, + dst_height); + // YUV400 + } else if (mjpeg_decoder.GetColorSpace() == + MJpegDecoder::kColorSpaceGrayscale && + mjpeg_decoder.GetNumComponents() == 1 && + mjpeg_decoder.GetVertSampFactor(0) == 1 && + mjpeg_decoder.GetHorizSampFactor(0) == 1) { + ret = mjpeg_decoder.DecodeToCallback(&JpegI400ToNV12, &bufs, dst_width, + dst_height); + } else { + // Unknown colorspace. + mjpeg_decoder.UnloadFrame(); + return 1; + } + } + return ret ? 0 : 1; +} + struct ARGBBuffers { uint8_t* argb; int argb_stride; diff --git a/TMessagesProj/jni/third_party/libyuv/source/convert_to_argb.cc b/TMessagesProj/jni/third_party/libyuv/source/convert_to_argb.cc index c08f61013..84df16c8c 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/convert_to_argb.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/convert_to_argb.cc @@ -180,12 +180,6 @@ int ConvertToARGB(const uint8_t* sample, r = NV21ToARGB(src, src_width, src_uv, aligned_src_width, dst_argb, dst_stride_argb, crop_width, inv_crop_height); break; - case FOURCC_M420: - src = sample + (src_width * crop_y) * 12 / 8 + crop_x; - r = M420ToARGB(src, src_width, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - // Triplanar formats case FOURCC_I420: case FOURCC_YV12: { diff --git a/TMessagesProj/jni/third_party/libyuv/source/convert_to_i420.cc b/TMessagesProj/jni/third_party/libyuv/source/convert_to_i420.cc index 584be0ac3..ac6eeab24 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/convert_to_i420.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/convert_to_i420.cc @@ -179,11 +179,6 @@ int ConvertToI420(const uint8_t* sample, dst_stride_y, dst_v, dst_stride_v, dst_u, dst_stride_u, crop_width, inv_crop_height, rotation); break; - case FOURCC_M420: - src = sample + (src_width * crop_y) * 12 / 8 + crop_x; - r = M420ToI420(src, src_width, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, crop_width, inv_crop_height); - break; // Triplanar formats case FOURCC_I420: case FOURCC_YV12: { diff --git a/TMessagesProj/jni/third_party/libyuv/source/cpu_id.cc b/TMessagesProj/jni/third_party/libyuv/source/cpu_id.cc index 48e2b6152..fe89452b7 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/cpu_id.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/cpu_id.cc @@ -75,9 +75,9 @@ void CpuId(int info_eax, int info_ecx, int* cpu_info) { asm volatile( #if defined(__i386__) && defined(__PIC__) // Preserve ebx for fpic 32 bit. - "mov %%ebx, %%edi \n" + "mov %%ebx, %%edi \n" "cpuid \n" - "xchg %%edi, %%ebx \n" + "xchg %%edi, %%ebx \n" : "=D"(info_ebx), #else "cpuid \n" @@ -163,44 +163,38 @@ LIBYUV_API SAFEBUFFERS int ArmCpuCaps(const char* cpuinfo_name) { } // TODO(fbarchard): Consider read_msa_ir(). -// TODO(fbarchard): Add unittest. -LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name, - const char ase[]) { +LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name) { char cpuinfo_line[512]; + int flag = 0x0; FILE* f = fopen(cpuinfo_name, "r"); if (!f) { - // ase enabled if /proc/cpuinfo is unavailable. - if (strcmp(ase, " msa") == 0) { - return kCpuHasMSA; - } - if (strcmp(ase, " mmi") == 0) { - return kCpuHasMMI; - } + // Assume nothing if /proc/cpuinfo is unavailable. + // This will occur for Chrome sandbox for Pepper or Render process. return 0; } while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { + if (memcmp(cpuinfo_line, "cpu model", 9) == 0) { + // Workaround early kernel without mmi in ASEs line. + if (strstr(cpuinfo_line, "Loongson-3")) { + flag |= kCpuHasMMI; + } else if (strstr(cpuinfo_line, "Loongson-2K")) { + flag |= kCpuHasMMI | kCpuHasMSA; + } + } if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) { - char* p = strstr(cpuinfo_line, ase); - if (p) { - fclose(f); - if (strcmp(ase, " msa") == 0) { - return kCpuHasMSA; - } - return 0; + if (strstr(cpuinfo_line, "loongson-mmi") && + strstr(cpuinfo_line, "loongson-ext")) { + flag |= kCpuHasMMI; } - } else if (memcmp(cpuinfo_line, "cpu model", 9) == 0) { - char* p = strstr(cpuinfo_line, "Loongson-3"); - if (p) { - fclose(f); - if (strcmp(ase, " mmi") == 0) { - return kCpuHasMMI; - } - return 0; + if (strstr(cpuinfo_line, "msa")) { + flag |= kCpuHasMSA; } + // ASEs is the last line, so we can break here. + break; } } fclose(f); - return 0; + return flag; } static SAFEBUFFERS int GetCpuFlags(void) { @@ -242,11 +236,7 @@ static SAFEBUFFERS int GetCpuFlags(void) { } #endif #if defined(__mips__) && defined(__linux__) -#if defined(__mips_msa) - cpu_info = MipsCpuCaps("/proc/cpuinfo", " msa"); -#elif defined(_MIPS_ARCH_LOONGSON3A) - cpu_info = MipsCpuCaps("/proc/cpuinfo", " mmi"); -#endif + cpu_info = MipsCpuCaps("/proc/cpuinfo"); cpu_info |= kCpuHasMIPS; #endif #if defined(__arm__) || defined(__aarch64__) diff --git a/TMessagesProj/jni/third_party/libyuv/source/planar_functions.cc b/TMessagesProj/jni/third_party/libyuv/source/planar_functions.cc index 1aa151b62..d5cd7e680 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/planar_functions.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/planar_functions.cc @@ -402,14 +402,6 @@ void SplitUVPlane(const uint8_t* src_uv, } } #endif -#if defined(HAS_SPLITUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SplitUVRow = SplitUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_MSA; - } - } -#endif #if defined(HAS_SPLITUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SplitUVRow = SplitUVRow_Any_MMI; @@ -418,6 +410,14 @@ void SplitUVPlane(const uint8_t* src_uv, } } #endif +#if defined(HAS_SPLITUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SplitUVRow = SplitUVRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + SplitUVRow = SplitUVRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { // Copy a row of UV. @@ -477,14 +477,6 @@ void MergeUVPlane(const uint8_t* src_u, } } #endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow = MergeUVRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - MergeUVRow = MergeUVRow_MSA; - } - } -#endif #if defined(HAS_MERGEUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { MergeUVRow = MergeUVRow_Any_MMI; @@ -493,6 +485,14 @@ void MergeUVPlane(const uint8_t* src_u, } } #endif +#if defined(HAS_MERGEUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MergeUVRow = MergeUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + MergeUVRow = MergeUVRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { // Merge a row of U and V into a row of UV. @@ -579,6 +579,15 @@ int NV21ToNV12(const uint8_t* src_y, if (dst_y) { CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } + + // Negative height means invert the image. + if (height < 0) { + height = -height; + halfheight = (height + 1) >> 1; + src_vu = src_vu + (halfheight - 1) * src_stride_vu; + src_stride_vu = -src_stride_vu; + } + SwapUVPlane(src_vu, src_stride_vu, dst_uv, dst_stride_uv, halfwidth, halfheight); return 0; @@ -625,14 +634,6 @@ void SplitRGBPlane(const uint8_t* src_rgb, } } #endif -#if defined(HAS_SPLITRGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SplitRGBRow = SplitRGBRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SplitRGBRow = SplitRGBRow_NEON; - } - } -#endif #if defined(HAS_SPLITRGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SplitRGBRow = SplitRGBRow_Any_MMI; @@ -641,6 +642,14 @@ void SplitRGBPlane(const uint8_t* src_rgb, } } #endif +#if defined(HAS_SPLITRGBROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + SplitRGBRow = SplitRGBRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + SplitRGBRow = SplitRGBRow_NEON; + } + } +#endif for (y = 0; y < height; ++y) { // Copy a row of RGB. @@ -716,70 +725,6 @@ void MergeRGBPlane(const uint8_t* src_r, } } -// Mirror a plane of data. -void MirrorPlane(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - int y; - void (*MirrorRow)(const uint8_t* src, uint8_t* dst, int width) = MirrorRow_C; - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } -#if defined(HAS_MIRRORROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MirrorRow = MirrorRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - MirrorRow = MirrorRow_NEON; - } - } -#endif -#if defined(HAS_MIRRORROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - MirrorRow = MirrorRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - MirrorRow = MirrorRow_SSSE3; - } - } -#endif -#if defined(HAS_MIRRORROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - MirrorRow = MirrorRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - MirrorRow = MirrorRow_AVX2; - } - } -#endif -#if defined(HAS_MIRRORROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MirrorRow = MirrorRow_Any_MSA; - if (IS_ALIGNED(width, 64)) { - MirrorRow = MirrorRow_MSA; - } - } -#endif -#if defined(HAS_MIRRORROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - MirrorRow = MirrorRow_Any_MMI; - if (IS_ALIGNED(width, 8)) { - MirrorRow = MirrorRow_MMI; - } - } -#endif - - // Mirror plane - for (y = 0; y < height; ++y) { - MirrorRow(src_y, dst_y, width); - src_y += src_stride_y; - dst_y += dst_stride_y; - } -} - // Convert YUY2 to I422. LIBYUV_API int YUY2ToI422(const uint8_t* src_yuy2, @@ -844,17 +789,7 @@ int YUY2ToI422(const uint8_t* src_yuy2, } } #endif -#if defined(HAS_YUY2TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - YUY2ToYRow = YUY2ToYRow_Any_MSA; - YUY2ToUV422Row = YUY2ToUV422Row_Any_MSA; - if (IS_ALIGNED(width, 32)) { - YUY2ToYRow = YUY2ToYRow_MSA; - YUY2ToUV422Row = YUY2ToUV422Row_MSA; - } - } -#endif -#if defined(HAS_YUY2TOYROW_MMI) +#if defined(HAS_YUY2TOYROW_MMI) && defined(HAS_YUY2TOUV422ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { YUY2ToYRow = YUY2ToYRow_Any_MMI; YUY2ToUV422Row = YUY2ToUV422Row_Any_MMI; @@ -864,6 +799,16 @@ int YUY2ToI422(const uint8_t* src_yuy2, } } #endif +#if defined(HAS_YUY2TOYROW_MSA) && defined(HAS_YUY2TOUV422ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + YUY2ToYRow = YUY2ToYRow_Any_MSA; + YUY2ToUV422Row = YUY2ToUV422Row_Any_MSA; + if (IS_ALIGNED(width, 32)) { + YUY2ToYRow = YUY2ToYRow_MSA; + YUY2ToUV422Row = YUY2ToUV422Row_MSA; + } + } +#endif for (y = 0; y < height; ++y) { YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width); @@ -940,17 +885,7 @@ int UYVYToI422(const uint8_t* src_uyvy, } } #endif -#if defined(HAS_UYVYTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - UYVYToYRow = UYVYToYRow_Any_MSA; - UYVYToUV422Row = UYVYToUV422Row_Any_MSA; - if (IS_ALIGNED(width, 32)) { - UYVYToYRow = UYVYToYRow_MSA; - UYVYToUV422Row = UYVYToUV422Row_MSA; - } - } -#endif -#if defined(HAS_UYVYTOYROW_MMI) +#if defined(HAS_UYVYTOYROW_MMI) && defined(HAS_UYVYTOUV422ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { UYVYToYRow = UYVYToYRow_Any_MMI; UYVYToUV422Row = UYVYToUV422Row_Any_MMI; @@ -960,6 +895,16 @@ int UYVYToI422(const uint8_t* src_uyvy, } } #endif +#if defined(HAS_UYVYTOYROW_MSA) && defined(HAS_UYVYTOUV422ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + UYVYToYRow = UYVYToYRow_Any_MSA; + UYVYToUV422Row = UYVYToUV422Row_Any_MSA; + if (IS_ALIGNED(width, 32)) { + UYVYToYRow = UYVYToYRow_MSA; + UYVYToUV422Row = UYVYToUV422Row_MSA; + } + } +#endif for (y = 0; y < height; ++y) { UYVYToUV422Row(src_uyvy, dst_u, dst_v, width); @@ -1022,14 +967,6 @@ int YUY2ToY(const uint8_t* src_yuy2, } } #endif -#if defined(HAS_YUY2TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - YUY2ToYRow = YUY2ToYRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - YUY2ToYRow = YUY2ToYRow_MSA; - } - } -#endif #if defined(HAS_YUY2TOYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { YUY2ToYRow = YUY2ToYRow_Any_MMI; @@ -1038,6 +975,14 @@ int YUY2ToY(const uint8_t* src_yuy2, } } #endif +#if defined(HAS_YUY2TOYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + YUY2ToYRow = YUY2ToYRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + YUY2ToYRow = YUY2ToYRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { YUY2ToYRow(src_yuy2, dst_y, width); @@ -1047,6 +992,130 @@ int YUY2ToY(const uint8_t* src_yuy2, return 0; } +// Mirror a plane of data. +// See Also I400Mirror +LIBYUV_API +void MirrorPlane(const uint8_t* src_y, + int src_stride_y, + uint8_t* dst_y, + int dst_stride_y, + int width, + int height) { + int y; + void (*MirrorRow)(const uint8_t* src, uint8_t* dst, int width) = MirrorRow_C; + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_y = src_y + (height - 1) * src_stride_y; + src_stride_y = -src_stride_y; + } +#if defined(HAS_MIRRORROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MirrorRow = MirrorRow_Any_NEON; + if (IS_ALIGNED(width, 32)) { + MirrorRow = MirrorRow_NEON; + } + } +#endif +#if defined(HAS_MIRRORROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + MirrorRow = MirrorRow_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + MirrorRow = MirrorRow_SSSE3; + } + } +#endif +#if defined(HAS_MIRRORROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MirrorRow = MirrorRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + MirrorRow = MirrorRow_AVX2; + } + } +#endif +#if defined(HAS_MIRRORROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + MirrorRow = MirrorRow_Any_MMI; + if (IS_ALIGNED(width, 8)) { + MirrorRow = MirrorRow_MMI; + } + } +#endif +#if defined(HAS_MIRRORROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MirrorRow = MirrorRow_Any_MSA; + if (IS_ALIGNED(width, 64)) { + MirrorRow = MirrorRow_MSA; + } + } +#endif + + // Mirror plane + for (y = 0; y < height; ++y) { + MirrorRow(src_y, dst_y, width); + src_y += src_stride_y; + dst_y += dst_stride_y; + } +} + +// Mirror a plane of UV data. +LIBYUV_API +void MirrorUVPlane(const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height) { + int y; + void (*MirrorUVRow)(const uint8_t* src, uint8_t* dst, int width) = + MirrorUVRow_C; + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_uv = src_uv + (height - 1) * src_stride_uv; + src_stride_uv = -src_stride_uv; + } +#if defined(HAS_MIRRORUVROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MirrorUVRow = MirrorUVRow_Any_NEON; + if (IS_ALIGNED(width, 32)) { + MirrorUVRow = MirrorUVRow_NEON; + } + } +#endif +#if defined(HAS_MIRRORUVROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + MirrorUVRow = MirrorUVRow_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + MirrorUVRow = MirrorUVRow_SSSE3; + } + } +#endif +#if defined(HAS_MIRRORUVROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MirrorUVRow = MirrorUVRow_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + MirrorUVRow = MirrorUVRow_AVX2; + } + } +#endif +#if defined(HAS_MIRRORUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MirrorUVRow = MirrorUVRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + MirrorUVRow = MirrorUVRow_MSA; + } + } +#endif + + // MirrorUV plane + for (y = 0; y < height; ++y) { + MirrorUVRow(src_uv, dst_uv, width); + src_uv += src_stride_uv; + dst_uv += dst_stride_uv; + } +} + // Mirror I400 with optional flipping LIBYUV_API int I400Mirror(const uint8_t* src_y, @@ -1087,7 +1156,7 @@ int I420Mirror(const uint8_t* src_y, int height) { int halfwidth = (width + 1) >> 1; int halfheight = (height + 1) >> 1; - if (!src_y || !src_u || !src_v || !dst_y || !dst_u || !dst_v || width <= 0 || + if (!src_y || !src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { return -1; } @@ -1111,6 +1180,41 @@ int I420Mirror(const uint8_t* src_y, return 0; } +// NV12 mirror. +LIBYUV_API +int NV12Mirror(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height) { + int halfwidth = (width + 1) >> 1; + int halfheight = (height + 1) >> 1; + if (!src_y || !src_uv || !dst_uv || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + halfheight = (height + 1) >> 1; + src_y = src_y + (height - 1) * src_stride_y; + src_uv = src_uv + (halfheight - 1) * src_stride_uv; + src_stride_y = -src_stride_y; + src_stride_uv = -src_stride_uv; + } + + if (dst_y) { + MirrorPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); + } + MirrorUVPlane(src_uv, src_stride_uv, dst_uv, dst_stride_uv, halfwidth, + halfheight); + return 0; +} + // ARGB mirror. LIBYUV_API int ARGBMirror(const uint8_t* src_argb, @@ -1134,7 +1238,7 @@ int ARGBMirror(const uint8_t* src_argb, #if defined(HAS_ARGBMIRRORROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { ARGBMirrorRow = ARGBMirrorRow_Any_NEON; - if (IS_ALIGNED(width, 4)) { + if (IS_ALIGNED(width, 8)) { ARGBMirrorRow = ARGBMirrorRow_NEON; } } @@ -1155,14 +1259,6 @@ int ARGBMirror(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBMIRRORROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBMirrorRow = ARGBMirrorRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBMirrorRow = ARGBMirrorRow_MSA; - } - } -#endif #if defined(HAS_ARGBMIRRORROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBMirrorRow = ARGBMirrorRow_Any_MMI; @@ -1171,6 +1267,14 @@ int ARGBMirror(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBMIRRORROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBMirrorRow = ARGBMirrorRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBMirrorRow = ARGBMirrorRow_MSA; + } + } +#endif // Mirror plane for (y = 0; y < height; ++y) { @@ -1181,6 +1285,52 @@ int ARGBMirror(const uint8_t* src_argb, return 0; } +// RGB24 mirror. +LIBYUV_API +int RGB24Mirror(const uint8_t* src_rgb24, + int src_stride_rgb24, + uint8_t* dst_rgb24, + int dst_stride_rgb24, + int width, + int height) { + int y; + void (*RGB24MirrorRow)(const uint8_t* src, uint8_t* dst, int width) = + RGB24MirrorRow_C; + if (!src_rgb24 || !dst_rgb24 || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; + src_stride_rgb24 = -src_stride_rgb24; + } +#if defined(HAS_RGB24MIRRORROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + RGB24MirrorRow = RGB24MirrorRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + RGB24MirrorRow = RGB24MirrorRow_NEON; + } + } +#endif +#if defined(HAS_RGB24MIRRORROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + RGB24MirrorRow = RGB24MirrorRow_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + RGB24MirrorRow = RGB24MirrorRow_SSSE3; + } + } +#endif + + // Mirror plane + for (y = 0; y < height; ++y) { + RGB24MirrorRow(src_rgb24, dst_rgb24, width); + src_rgb24 += src_stride_rgb24; + dst_rgb24 += dst_stride_rgb24; + } + return 0; +} + // Get a blender that optimized for the CPU and pixel count. // As there are 6 blenders to choose from, the caller should try to use // the same blend function for all pixels if possible. @@ -1199,15 +1349,15 @@ ARGBBlendRow GetARGBBlend() { ARGBBlendRow = ARGBBlendRow_NEON; } #endif -#if defined(HAS_ARGBBLENDROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBBlendRow = ARGBBlendRow_MSA; - } -#endif #if defined(HAS_ARGBBLENDROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBBlendRow = ARGBBlendRow_MMI; } +#endif +#if defined(HAS_ARGBBLENDROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBBlendRow = ARGBBlendRow_MSA; + } #endif return ARGBBlendRow; } @@ -1517,14 +1667,6 @@ int ARGBMultiply(const uint8_t* src_argb0, } } #endif -#if defined(HAS_ARGBMULTIPLYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBMultiplyRow = ARGBMultiplyRow_Any_MSA; - if (IS_ALIGNED(width, 4)) { - ARGBMultiplyRow = ARGBMultiplyRow_MSA; - } - } -#endif #if defined(HAS_ARGBMULTIPLYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBMultiplyRow = ARGBMultiplyRow_Any_MMI; @@ -1533,6 +1675,14 @@ int ARGBMultiply(const uint8_t* src_argb0, } } #endif +#if defined(HAS_ARGBMULTIPLYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBMultiplyRow = ARGBMultiplyRow_Any_MSA; + if (IS_ALIGNED(width, 4)) { + ARGBMultiplyRow = ARGBMultiplyRow_MSA; + } + } +#endif // Multiply plane for (y = 0; y < height; ++y) { @@ -1602,14 +1752,6 @@ int ARGBAdd(const uint8_t* src_argb0, } } #endif -#if defined(HAS_ARGBADDROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBAddRow = ARGBAddRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBAddRow = ARGBAddRow_MSA; - } - } -#endif #if defined(HAS_ARGBADDROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBAddRow = ARGBAddRow_Any_MMI; @@ -1618,6 +1760,14 @@ int ARGBAdd(const uint8_t* src_argb0, } } #endif +#if defined(HAS_ARGBADDROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBAddRow = ARGBAddRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBAddRow = ARGBAddRow_MSA; + } + } +#endif // Add plane for (y = 0; y < height; ++y) { @@ -1682,14 +1832,6 @@ int ARGBSubtract(const uint8_t* src_argb0, } } #endif -#if defined(HAS_ARGBSUBTRACTROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBSubtractRow = ARGBSubtractRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBSubtractRow = ARGBSubtractRow_MSA; - } - } -#endif #if defined(HAS_ARGBSUBTRACTROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBSubtractRow = ARGBSubtractRow_Any_MMI; @@ -1698,6 +1840,14 @@ int ARGBSubtract(const uint8_t* src_argb0, } } #endif +#if defined(HAS_ARGBSUBTRACTROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBSubtractRow = ARGBSubtractRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBSubtractRow = ARGBSubtractRow_MSA; + } + } +#endif // Subtract plane for (y = 0; y < height; ++y) { @@ -1708,193 +1858,6 @@ int ARGBSubtract(const uint8_t* src_argb0, } return 0; } -// Convert I422 to RGBA with matrix -static int I422ToRGBAMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToRGBARow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGBARow_C; - if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba; - dst_stride_rgba = -dst_stride_rgba; - } -#if defined(HAS_I422TORGBAROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGBARow = I422ToRGBARow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGBAROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGBARow = I422ToRGBARow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGBARow = I422ToRGBARow_AVX2; - } - } -#endif -#if defined(HAS_I422TORGBAROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGBARow = I422ToRGBARow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_NEON; - } - } -#endif -#if defined(HAS_I422TORGBAROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGBARow = I422ToRGBARow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_MSA; - } - } -#endif -#if defined(HAS_I422TORGBAROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - I422ToRGBARow = I422ToRGBARow_Any_MMI; - if (IS_ALIGNED(width, 4)) { - I422ToRGBARow = I422ToRGBARow_MMI; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width); - dst_rgba += dst_stride_rgba; - src_y += src_stride_y; - src_u += src_stride_u; - src_v += src_stride_v; - } - return 0; -} - -// Convert I422 to RGBA. -LIBYUV_API -int I422ToRGBA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height) { - return I422ToRGBAMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgba, dst_stride_rgba, - &kYuvI601Constants, width, height); -} - -// Convert I422 to BGRA. -LIBYUV_API -int I422ToBGRA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height) { - return I422ToRGBAMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_bgra, dst_stride_bgra, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert NV12 to RGB565. -LIBYUV_API -int NV12ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - int y; - void (*NV12ToRGB565Row)( - const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = NV12ToRGB565Row_C; - if (!src_y || !src_uv || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; - dst_stride_rgb565 = -dst_stride_rgb565; - } -#if defined(HAS_NV12TORGB565ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - NV12ToRGB565Row = NV12ToRGB565Row_SSSE3; - } - } -#endif -#if defined(HAS_NV12TORGB565ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - NV12ToRGB565Row = NV12ToRGB565Row_AVX2; - } - } -#endif -#if defined(HAS_NV12TORGB565ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - NV12ToRGB565Row = NV12ToRGB565Row_NEON; - } - } -#endif -#if defined(HAS_NV12TORGB565ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - NV12ToRGB565Row = NV12ToRGB565Row_MSA; - } - } -#endif -#if defined(HAS_NV12TORGB565ROW_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_MMI; - if (IS_ALIGNED(width, 4)) { - NV12ToRGB565Row = NV12ToRGB565Row_MMI; - } - } -#endif - - for (y = 0; y < height; ++y) { - NV12ToRGB565Row(src_y, src_uv, dst_rgb565, &kYuvI601Constants, width); - dst_rgb565 += dst_stride_rgb565; - src_y += src_stride_y; - if (y & 1) { - src_uv += src_stride_uv; - } - } - return 0; -} // Convert RAW to RGB24. LIBYUV_API @@ -1938,14 +1901,6 @@ int RAWToRGB24(const uint8_t* src_raw, } } #endif -#if defined(HAS_RAWTORGB24ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RAWToRGB24Row = RAWToRGB24Row_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RAWToRGB24Row = RAWToRGB24Row_MSA; - } - } -#endif #if defined(HAS_RAWTORGB24ROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { RAWToRGB24Row = RAWToRGB24Row_Any_MMI; @@ -1954,6 +1909,14 @@ int RAWToRGB24(const uint8_t* src_raw, } } #endif +#if defined(HAS_RAWTORGB24ROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + RAWToRGB24Row = RAWToRGB24Row_Any_MSA; + if (IS_ALIGNED(width, 16)) { + RAWToRGB24Row = RAWToRGB24Row_MSA; + } + } +#endif for (y = 0; y < height; ++y) { RAWToRGB24Row(src_raw, dst_rgb24, width); @@ -2089,14 +2052,6 @@ int ARGBRect(uint8_t* dst_argb, ARGBSetRow = ARGBSetRow_X86; } #endif -#if defined(HAS_ARGBSETROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBSetRow = ARGBSetRow_Any_MSA; - if (IS_ALIGNED(width, 4)) { - ARGBSetRow = ARGBSetRow_MSA; - } - } -#endif #if defined(HAS_ARGBSETROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBSetRow = ARGBSetRow_Any_MMI; @@ -2105,6 +2060,14 @@ int ARGBRect(uint8_t* dst_argb, } } #endif +#if defined(HAS_ARGBSETROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBSetRow = ARGBSetRow_Any_MSA; + if (IS_ALIGNED(width, 4)) { + ARGBSetRow = ARGBSetRow_MSA; + } + } +#endif // Set plane for (y = 0; y < height; ++y) { @@ -2175,14 +2138,6 @@ int ARGBAttenuate(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBATTENUATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBAttenuateRow = ARGBAttenuateRow_MSA; - } - } -#endif #if defined(HAS_ARGBATTENUATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBAttenuateRow = ARGBAttenuateRow_Any_MMI; @@ -2191,6 +2146,14 @@ int ARGBAttenuate(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBATTENUATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBAttenuateRow = ARGBAttenuateRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBAttenuateRow = ARGBAttenuateRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBAttenuateRow(src_argb, dst_argb, width); @@ -2286,16 +2249,16 @@ int ARGBGrayTo(const uint8_t* src_argb, ARGBGrayRow = ARGBGrayRow_NEON; } #endif -#if defined(HAS_ARGBGRAYROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBGrayRow = ARGBGrayRow_MSA; - } -#endif #if defined(HAS_ARGBGRAYROW_MMI) if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(width, 2)) { ARGBGrayRow = ARGBGrayRow_MMI; } #endif +#if defined(HAS_ARGBGRAYROW_MSA) + if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { + ARGBGrayRow = ARGBGrayRow_MSA; + } +#endif for (y = 0; y < height; ++y) { ARGBGrayRow(src_argb, dst_argb, width); @@ -2336,16 +2299,16 @@ int ARGBGray(uint8_t* dst_argb, ARGBGrayRow = ARGBGrayRow_NEON; } #endif -#if defined(HAS_ARGBGRAYROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBGrayRow = ARGBGrayRow_MSA; - } -#endif #if defined(HAS_ARGBGRAYROW_MMI) if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(width, 2)) { ARGBGrayRow = ARGBGrayRow_MMI; } #endif +#if defined(HAS_ARGBGRAYROW_MSA) + if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { + ARGBGrayRow = ARGBGrayRow_MSA; + } +#endif for (y = 0; y < height; ++y) { ARGBGrayRow(dst, dst, width); @@ -2384,16 +2347,16 @@ int ARGBSepia(uint8_t* dst_argb, ARGBSepiaRow = ARGBSepiaRow_NEON; } #endif -#if defined(HAS_ARGBSEPIAROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBSepiaRow = ARGBSepiaRow_MSA; - } -#endif #if defined(HAS_ARGBSEPIAROW_MMI) if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(width, 2)) { ARGBSepiaRow = ARGBSepiaRow_MMI; } #endif +#if defined(HAS_ARGBSEPIAROW_MSA) + if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { + ARGBSepiaRow = ARGBSepiaRow_MSA; + } +#endif for (y = 0; y < height; ++y) { ARGBSepiaRow(dst, width); @@ -2440,15 +2403,15 @@ int ARGBColorMatrix(const uint8_t* src_argb, ARGBColorMatrixRow = ARGBColorMatrixRow_NEON; } #endif -#if defined(HAS_ARGBCOLORMATRIXROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBColorMatrixRow = ARGBColorMatrixRow_MSA; - } -#endif #if defined(HAS_ARGBCOLORMATRIXROW_MMI) if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(width, 2)) { ARGBColorMatrixRow = ARGBColorMatrixRow_MMI; } +#endif +#if defined(HAS_ARGBCOLORMATRIXROW_MSA) + if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { + ARGBColorMatrixRow = ARGBColorMatrixRow_MSA; + } #endif for (y = 0; y < height; ++y) { ARGBColorMatrixRow(src_argb, dst_argb, matrix_argb, width); @@ -2814,16 +2777,16 @@ int ARGBShade(const uint8_t* src_argb, ARGBShadeRow = ARGBShadeRow_NEON; } #endif -#if defined(HAS_ARGBSHADEROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 4)) { - ARGBShadeRow = ARGBShadeRow_MSA; - } -#endif #if defined(HAS_ARGBSHADEROW_MMI) if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(width, 2)) { ARGBShadeRow = ARGBShadeRow_MMI; } #endif +#if defined(HAS_ARGBSHADEROW_MSA) + if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 4)) { + ARGBShadeRow = ARGBShadeRow_MSA; + } +#endif for (y = 0; y < height; ++y) { ARGBShadeRow(src_argb, dst_argb, width, value); @@ -2887,14 +2850,6 @@ int InterpolatePlane(const uint8_t* src0, } } #endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif #if defined(HAS_INTERPOLATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { InterpolateRow = InterpolateRow_Any_MMI; @@ -2903,6 +2858,14 @@ int InterpolatePlane(const uint8_t* src0, } } #endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + InterpolateRow = InterpolateRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { InterpolateRow(dst, src0, src1 - src0, width, interpolation); @@ -3018,14 +2981,6 @@ int ARGBShuffle(const uint8_t* src_bgra, } } #endif -#if defined(HAS_ARGBSHUFFLEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBShuffleRow = ARGBShuffleRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBShuffleRow = ARGBShuffleRow_MSA; - } - } -#endif #if defined(HAS_ARGBSHUFFLEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBShuffleRow = ARGBShuffleRow_Any_MMI; @@ -3034,6 +2989,14 @@ int ARGBShuffle(const uint8_t* src_bgra, } } #endif +#if defined(HAS_ARGBSHUFFLEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBShuffleRow = ARGBShuffleRow_Any_MSA; + if (IS_ALIGNED(width, 8)) { + ARGBShuffleRow = ARGBShuffleRow_MSA; + } + } +#endif for (y = 0; y < height; ++y) { ARGBShuffleRow(src_bgra, dst_argb, shuffler, width); @@ -3043,6 +3006,80 @@ int ARGBShuffle(const uint8_t* src_bgra, return 0; } +// Gauss blur a float plane using Gaussian 5x5 filter with +// coefficients of 1, 4, 6, 4, 1. +// Each destination pixel is a blur of the 5x5 +// pixels from the source. +// Source edges are clamped. +// Edge is 2 pixels on each side, and interior is multiple of 4. +LIBYUV_API +int GaussPlane_F32(const float* src, + int src_stride, + float* dst, + int dst_stride, + int width, + int height) { + int y; + void (*GaussCol_F32)(const float* src0, const float* src1, const float* src2, + const float* src3, const float* src4, float* dst, + int width) = GaussCol_F32_C; + void (*GaussRow_F32)(const float* src, float* dst, int width) = + GaussRow_F32_C; + if (!src || !dst || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src = src + (height - 1) * src_stride; + src_stride = -src_stride; + } + +#if defined(HAS_GAUSSCOL_F32_NEON) + if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { + GaussCol_F32 = GaussCol_F32_NEON; + } +#endif +#if defined(HAS_GAUSSROW_F32_NEON) + if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { + GaussRow_F32 = GaussRow_F32_NEON; + } +#endif + { + // 2 pixels on each side, but aligned out to 16 bytes. + align_buffer_64(rowbuf, (4 + width + 4) * 4); + memset(rowbuf, 0, 16); + memset(rowbuf + (4 + width) * 4, 0, 16); + float* row = (float*)(rowbuf + 16); + const float* src0 = src; + const float* src1 = src; + const float* src2 = src; + const float* src3 = src2 + ((height > 1) ? src_stride : 0); + const float* src4 = src3 + ((height > 2) ? src_stride : 0); + + for (y = 0; y < height; ++y) { + GaussCol_F32(src0, src1, src2, src3, src4, row, width); + + // Extrude edge by 2 floats + row[-2] = row[-1] = row[0]; + row[width + 1] = row[width] = row[width - 1]; + + GaussRow_F32(row - 2, dst, width); + + src0 = src1; + src1 = src2; + src2 = src3; + src3 = src4; + if ((y + 2) < (height - 1)) { + src4 += src_stride; + } + dst += dst_stride; + } + free_aligned_buffer_64(rowbuf); + } + return 0; +} + // Sobel ARGB effect. static int ARGBSobelize(const uint8_t* src_argb, int src_stride_argb, @@ -3097,14 +3134,6 @@ static int ARGBSobelize(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBTOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYJRow = ARGBToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_MSA; - } - } -#endif #if defined(HAS_ARGBTOYJROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBToYJRow = ARGBToYJRow_Any_MMI; @@ -3113,6 +3142,14 @@ static int ARGBSobelize(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYJROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYJRow = ARGBToYJRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYJRow = ARGBToYJRow_MSA; + } + } +#endif #if defined(HAS_SOBELYROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { @@ -3124,16 +3161,16 @@ static int ARGBSobelize(const uint8_t* src_argb, SobelYRow = SobelYRow_NEON; } #endif -#if defined(HAS_SOBELYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelYRow = SobelYRow_MSA; - } -#endif #if defined(HAS_SOBELYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SobelYRow = SobelYRow_MMI; } #endif +#if defined(HAS_SOBELYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SobelYRow = SobelYRow_MSA; + } +#endif #if defined(HAS_SOBELXROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { SobelXRow = SobelXRow_SSE2; @@ -3144,15 +3181,15 @@ static int ARGBSobelize(const uint8_t* src_argb, SobelXRow = SobelXRow_NEON; } #endif -#if defined(HAS_SOBELXROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelXRow = SobelXRow_MSA; - } -#endif #if defined(HAS_SOBELXROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SobelXRow = SobelXRow_MMI; } +#endif +#if defined(HAS_SOBELXROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SobelXRow = SobelXRow_MSA; + } #endif { // 3 rows with edges before/after. @@ -3228,14 +3265,6 @@ int ARGBSobel(const uint8_t* src_argb, } } #endif -#if defined(HAS_SOBELROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelRow = SobelRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - SobelRow = SobelRow_MSA; - } - } -#endif #if defined(HAS_SOBELROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SobelRow = SobelRow_Any_MMI; @@ -3243,6 +3272,14 @@ int ARGBSobel(const uint8_t* src_argb, SobelRow = SobelRow_MMI; } } +#endif +#if defined(HAS_SOBELROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SobelRow = SobelRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + SobelRow = SobelRow_MSA; + } + } #endif return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, height, SobelRow); @@ -3274,14 +3311,6 @@ int ARGBSobelToPlane(const uint8_t* src_argb, } } #endif -#if defined(HAS_SOBELTOPLANEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelToPlaneRow = SobelToPlaneRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - SobelToPlaneRow = SobelToPlaneRow_MSA; - } - } -#endif #if defined(HAS_SOBELTOPLANEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SobelToPlaneRow = SobelToPlaneRow_Any_MMI; @@ -3289,6 +3318,14 @@ int ARGBSobelToPlane(const uint8_t* src_argb, SobelToPlaneRow = SobelToPlaneRow_MMI; } } +#endif +#if defined(HAS_SOBELTOPLANEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SobelToPlaneRow = SobelToPlaneRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + SobelToPlaneRow = SobelToPlaneRow_MSA; + } + } #endif return ARGBSobelize(src_argb, src_stride_argb, dst_y, dst_stride_y, width, height, SobelToPlaneRow); @@ -3321,14 +3358,6 @@ int ARGBSobelXY(const uint8_t* src_argb, } } #endif -#if defined(HAS_SOBELXYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelXYRow = SobelXYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - SobelXYRow = SobelXYRow_MSA; - } - } -#endif #if defined(HAS_SOBELXYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SobelXYRow = SobelXYRow_Any_MMI; @@ -3336,6 +3365,14 @@ int ARGBSobelXY(const uint8_t* src_argb, SobelXYRow = SobelXYRow_MMI; } } +#endif +#if defined(HAS_SOBELXYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SobelXYRow = SobelXYRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + SobelXYRow = SobelXYRow_MSA; + } + } #endif return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, height, SobelXYRow); @@ -3634,18 +3671,18 @@ int ARGBExtractAlpha(const uint8_t* src_argb, : ARGBExtractAlphaRow_Any_NEON; } #endif -#if defined(HAS_ARGBEXTRACTALPHAROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_MSA - : ARGBExtractAlphaRow_Any_MSA; - } -#endif #if defined(HAS_ARGBEXTRACTALPHAROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBExtractAlphaRow = IS_ALIGNED(width, 8) ? ARGBExtractAlphaRow_MMI : ARGBExtractAlphaRow_Any_MMI; } #endif +#if defined(HAS_ARGBEXTRACTALPHAROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_MSA + : ARGBExtractAlphaRow_Any_MSA; + } +#endif for (int y = 0; y < height; ++y) { ARGBExtractAlphaRow(src_argb, dst_a, width); @@ -3766,14 +3803,6 @@ int YUY2ToNV12(const uint8_t* src_yuy2, } } #endif -#if defined(HAS_SPLITUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SplitUVRow = SplitUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_MSA; - } - } -#endif #if defined(HAS_SPLITUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SplitUVRow = SplitUVRow_Any_MMI; @@ -3782,6 +3811,14 @@ int YUY2ToNV12(const uint8_t* src_yuy2, } } #endif +#if defined(HAS_SPLITUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SplitUVRow = SplitUVRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + SplitUVRow = SplitUVRow_MSA; + } + } +#endif #if defined(HAS_INTERPOLATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { InterpolateRow = InterpolateRow_Any_SSSE3; @@ -3806,14 +3843,6 @@ int YUY2ToNV12(const uint8_t* src_yuy2, } } #endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif #if defined(HAS_INTERPOLATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { InterpolateRow = InterpolateRow_Any_MMI; @@ -3822,6 +3851,14 @@ int YUY2ToNV12(const uint8_t* src_yuy2, } } #endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + InterpolateRow = InterpolateRow_MSA; + } + } +#endif { int awidth = halfwidth * 2; @@ -3898,14 +3935,6 @@ int UYVYToNV12(const uint8_t* src_uyvy, } } #endif -#if defined(HAS_SPLITUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SplitUVRow = SplitUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_MSA; - } - } -#endif #if defined(HAS_SPLITUVROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { SplitUVRow = SplitUVRow_Any_MMI; @@ -3914,6 +3943,14 @@ int UYVYToNV12(const uint8_t* src_uyvy, } } #endif +#if defined(HAS_SPLITUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + SplitUVRow = SplitUVRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + SplitUVRow = SplitUVRow_MSA; + } + } +#endif #if defined(HAS_INTERPOLATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { InterpolateRow = InterpolateRow_Any_SSSE3; @@ -3938,14 +3975,6 @@ int UYVYToNV12(const uint8_t* src_uyvy, } } #endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif #if defined(HAS_INTERPOLATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { InterpolateRow = InterpolateRow_Any_MMI; @@ -3954,6 +3983,14 @@ int UYVYToNV12(const uint8_t* src_uyvy, } } #endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + InterpolateRow = InterpolateRow_MSA; + } + } +#endif { int awidth = halfwidth * 2; @@ -3981,6 +4018,56 @@ int UYVYToNV12(const uint8_t* src_uyvy, return 0; } +// width and height are src size allowing odd size handling. +LIBYUV_API +void HalfMergeUVPlane(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int dst_stride_uv, + int width, + int height) { + int y; + void (*HalfMergeUVRow)(const uint8_t* src_u, int src_stride_u, + const uint8_t* src_v, int src_stride_v, + uint8_t* dst_uv, int width) = HalfMergeUVRow_C; + + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_u = src_u + (height - 1) * src_stride_u; + src_v = src_v + (height - 1) * src_stride_v; + src_stride_u = -src_stride_u; + src_stride_v = -src_stride_v; + } +#if defined(HAS_HALFMERGEUVROW_NEON) + if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) { + HalfMergeUVRow = HalfMergeUVRow_NEON; + } +#endif +#if defined(HAS_HALFMERGEUVROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) { + HalfMergeUVRow = HalfMergeUVRow_SSSE3; + } +#endif +#if defined(HAS_HALFMERGEUVROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2) && IS_ALIGNED(width, 32)) { + HalfMergeUVRow = HalfMergeUVRow_AVX2; + } +#endif + for (y = 0; y < height - 1; y += 2) { + // Merge a row of U and V into a row of UV. + HalfMergeUVRow(src_u, src_stride_u, src_v, src_stride_v, dst_uv, width); + src_u += src_stride_u * 2; + src_v += src_stride_v * 2; + dst_uv += dst_stride_uv; + } + if (height & 1) { + HalfMergeUVRow(src_u, 0, src_v, 0, dst_uv, width); + } +} + #ifdef __cplusplus } // extern "C" } // namespace libyuv diff --git a/TMessagesProj/jni/third_party/libyuv/source/rotate.cc b/TMessagesProj/jni/third_party/libyuv/source/rotate.cc index d414186a5..32904e473 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/rotate.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/rotate.cc @@ -36,6 +36,15 @@ void TransposePlane(const uint8_t* src, void (*TransposeWx8)(const uint8_t* src, int src_stride, uint8_t* dst, int dst_stride, int width) = TransposeWx8_C; #endif + +#if defined(HAS_TRANSPOSEWX16_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + TransposeWx16 = TransposeWx16_Any_MSA; + if (IS_ALIGNED(width, 16)) { + TransposeWx16 = TransposeWx16_MSA; + } + } +#else #if defined(HAS_TRANSPOSEWX8_NEON) if (TestCpuFlag(kCpuHasNEON)) { TransposeWx8 = TransposeWx8_NEON; @@ -62,14 +71,7 @@ void TransposePlane(const uint8_t* src, } } #endif -#if defined(HAS_TRANSPOSEWX16_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - TransposeWx16 = TransposeWx16_Any_MSA; - if (IS_ALIGNED(width, 16)) { - TransposeWx16 = TransposeWx16_MSA; - } - } -#endif +#endif /* defined(HAS_TRANSPOSEWX16_MSA) */ #if defined(HAS_TRANSPOSEWX16_MSA) // Work across the source in 16x16 tiles @@ -142,7 +144,7 @@ void RotatePlane180(const uint8_t* src, #if defined(HAS_MIRRORROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { MirrorRow = MirrorRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { + if (IS_ALIGNED(width, 32)) { MirrorRow = MirrorRow_NEON; } } @@ -163,14 +165,6 @@ void RotatePlane180(const uint8_t* src, } } #endif -#if defined(HAS_MIRRORROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MirrorRow = MirrorRow_Any_MSA; - if (IS_ALIGNED(width, 64)) { - MirrorRow = MirrorRow_MSA; - } - } -#endif #if defined(HAS_MIRRORROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { MirrorRow = MirrorRow_Any_MMI; @@ -179,6 +173,14 @@ void RotatePlane180(const uint8_t* src, } } #endif +#if defined(HAS_MIRRORROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + MirrorRow = MirrorRow_Any_MSA; + if (IS_ALIGNED(width, 64)) { + MirrorRow = MirrorRow_MSA; + } + } +#endif #if defined(HAS_COPYROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; @@ -207,11 +209,11 @@ void RotatePlane180(const uint8_t* src, // Odd height will harmlessly mirror the middle row twice. for (y = 0; y < half_height; ++y) { - MirrorRow(src, row, width); // Mirror first row into a buffer - src += src_stride; + CopyRow(src, row, width); // Copy first row into buffer MirrorRow(src_bot, dst, width); // Mirror last row into first row + MirrorRow(row, dst_bot, width); // Mirror buffer into last row + src += src_stride; dst += dst_stride; - CopyRow(row, dst_bot, width); // Copy first mirrored row into last src_bot -= src_stride; dst_bot -= dst_stride; } @@ -237,6 +239,15 @@ void TransposeUV(const uint8_t* src, int dst_stride_a, uint8_t* dst_b, int dst_stride_b, int width) = TransposeUVWx8_C; #endif + +#if defined(HAS_TRANSPOSEUVWX16_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + TransposeUVWx16 = TransposeUVWx16_Any_MSA; + if (IS_ALIGNED(width, 8)) { + TransposeUVWx16 = TransposeUVWx16_MSA; + } + } +#else #if defined(HAS_TRANSPOSEUVWX8_NEON) if (TestCpuFlag(kCpuHasNEON)) { TransposeUVWx8 = TransposeUVWx8_NEON; @@ -258,14 +269,7 @@ void TransposeUV(const uint8_t* src, } } #endif -#if defined(HAS_TRANSPOSEUVWX16_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - TransposeUVWx16 = TransposeUVWx16_Any_MSA; - if (IS_ALIGNED(width, 8)) { - TransposeUVWx16 = TransposeUVWx16_MSA; - } - } -#endif +#endif /* defined(HAS_TRANSPOSEUVWX16_MSA) */ #if defined(HAS_TRANSPOSEUVWX16_MSA) // Work through the source in 8x8 tiles. @@ -340,26 +344,26 @@ void RotateUV180(const uint8_t* src, int width, int height) { int i; - void (*MirrorUVRow)(const uint8_t* src, uint8_t* dst_u, uint8_t* dst_v, - int width) = MirrorUVRow_C; -#if defined(HAS_MIRRORUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - MirrorUVRow = MirrorUVRow_NEON; + void (*MirrorSplitUVRow)(const uint8_t* src, uint8_t* dst_u, uint8_t* dst_v, + int width) = MirrorSplitUVRow_C; +#if defined(HAS_MIRRORSPLITUVROW_NEON) + if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) { + MirrorSplitUVRow = MirrorSplitUVRow_NEON; } #endif -#if defined(HAS_MIRRORUVROW_SSSE3) +#if defined(HAS_MIRRORSPLITUVROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) { - MirrorUVRow = MirrorUVRow_SSSE3; + MirrorSplitUVRow = MirrorSplitUVRow_SSSE3; } #endif -#if defined(HAS_MIRRORUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 32)) { - MirrorUVRow = MirrorUVRow_MSA; - } -#endif -#if defined(HAS_MIRRORUVROW_MMI) +#if defined(HAS_MIRRORSPLITUVROW_MMI) if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(width, 8)) { - MirrorUVRow = MirrorUVRow_MMI; + MirrorSplitUVRow = MirrorSplitUVRow_MMI; + } +#endif +#if defined(HAS_MIRRORSPLITUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 32)) { + MirrorSplitUVRow = MirrorSplitUVRow_MSA; } #endif @@ -367,7 +371,7 @@ void RotateUV180(const uint8_t* src, dst_b += dst_stride_b * (height - 1); for (i = 0; i < height; ++i) { - MirrorUVRow(src, dst_a, dst_b, width); + MirrorSplitUVRow(src, dst_a, dst_b, width); src += src_stride; dst_a -= dst_stride_a; dst_b -= dst_stride_b; diff --git a/TMessagesProj/jni/third_party/libyuv/source/rotate_argb.cc b/TMessagesProj/jni/third_party/libyuv/source/rotate_argb.cc index a93fd55f9..ae6538860 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/rotate_argb.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/rotate_argb.cc @@ -21,17 +21,21 @@ namespace libyuv { extern "C" { #endif -static void ARGBTranspose(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { +static int ARGBTranspose(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height) { int i; int src_pixel_step = src_stride_argb >> 2; void (*ScaleARGBRowDownEven)( const uint8_t* src_argb, ptrdiff_t src_stride_argb, int src_step, uint8_t* dst_argb, int dst_width) = ScaleARGBRowDownEven_C; + // Check stride is a multiple of 4. + if (src_stride_argb & 3) { + return -1; + } #if defined(HAS_SCALEARGBROWDOWNEVEN_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_SSE2; @@ -48,14 +52,6 @@ static void ARGBTranspose(const uint8_t* src_argb, } } #endif -#if defined(HAS_SCALEARGBROWDOWNEVEN_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_MSA; - if (IS_ALIGNED(height, 4)) { // Width of dest. - ScaleARGBRowDownEven = ScaleARGBRowDownEven_MSA; - } - } -#endif #if defined(HAS_SCALEARGBROWDOWNEVEN_MMI) if (TestCpuFlag(kCpuHasMMI)) { ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_MMI; @@ -64,50 +60,59 @@ static void ARGBTranspose(const uint8_t* src_argb, } } #endif +#if defined(HAS_SCALEARGBROWDOWNEVEN_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_MSA; + if (IS_ALIGNED(height, 4)) { // Width of dest. + ScaleARGBRowDownEven = ScaleARGBRowDownEven_MSA; + } + } +#endif for (i = 0; i < width; ++i) { // column of source to row of dest. ScaleARGBRowDownEven(src_argb, 0, src_pixel_step, dst_argb, height); dst_argb += dst_stride_argb; src_argb += 4; } + return 0; } -void ARGBRotate90(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { +static int ARGBRotate90(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height) { // Rotate by 90 is a ARGBTranspose with the source read // from bottom to top. So set the source pointer to the end // of the buffer and flip the sign of the source stride. src_argb += src_stride_argb * (height - 1); src_stride_argb = -src_stride_argb; - ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); + return ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, + width, height); } -void ARGBRotate270(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { +static int ARGBRotate270(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height) { // Rotate by 270 is a ARGBTranspose with the destination written // from bottom to top. So set the destination pointer to the end // of the buffer and flip the sign of the destination stride. dst_argb += dst_stride_argb * (width - 1); dst_stride_argb = -dst_stride_argb; - ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); + return ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, + width, height); } -void ARGBRotate180(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { +static int ARGBRotate180(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height) { // Swap first and last row and mirror the content. Uses a temporary row. align_buffer_64(row, width * 4); const uint8_t* src_bot = src_argb + src_stride_argb * (height - 1); @@ -121,7 +126,7 @@ void ARGBRotate180(const uint8_t* src_argb, #if defined(HAS_ARGBMIRRORROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { ARGBMirrorRow = ARGBMirrorRow_Any_NEON; - if (IS_ALIGNED(width, 4)) { + if (IS_ALIGNED(width, 8)) { ARGBMirrorRow = ARGBMirrorRow_NEON; } } @@ -142,14 +147,6 @@ void ARGBRotate180(const uint8_t* src_argb, } } #endif -#if defined(HAS_ARGBMIRRORROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBMirrorRow = ARGBMirrorRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBMirrorRow = ARGBMirrorRow_MSA; - } - } -#endif #if defined(HAS_ARGBMIRRORROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ARGBMirrorRow = ARGBMirrorRow_Any_MMI; @@ -158,6 +155,14 @@ void ARGBRotate180(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBMIRRORROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBMirrorRow = ARGBMirrorRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBMirrorRow = ARGBMirrorRow_MSA; + } + } +#endif #if defined(HAS_COPYROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { CopyRow = IS_ALIGNED(width * 4, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; @@ -190,6 +195,7 @@ void ARGBRotate180(const uint8_t* src_argb, dst_bot -= dst_stride_argb; } free_aligned_buffer_64(row); + return 0; } LIBYUV_API @@ -217,17 +223,14 @@ int ARGBRotate(const uint8_t* src_argb, return ARGBCopy(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, height); case kRotate90: - ARGBRotate90(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); - return 0; + return ARGBRotate90(src_argb, src_stride_argb, dst_argb, dst_stride_argb, + width, height); case kRotate270: - ARGBRotate270(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); - return 0; + return ARGBRotate270(src_argb, src_stride_argb, dst_argb, dst_stride_argb, + width, height); case kRotate180: - ARGBRotate180(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); - return 0; + return ARGBRotate180(src_argb, src_stride_argb, dst_argb, dst_stride_argb, + width, height); default: break; } diff --git a/TMessagesProj/jni/third_party/libyuv/source/rotate_gcc.cc b/TMessagesProj/jni/third_party/libyuv/source/rotate_gcc.cc index 04e19e29e..fd359d4ae 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/rotate_gcc.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/rotate_gcc.cc @@ -31,75 +31,75 @@ void TransposeWx8_SSSE3(const uint8_t* src, // Read in the data from the source pointer. // First round of bit swap. LABELALIGN - "1: \n" - "movq (%0),%%xmm0 \n" - "movq (%0,%3),%%xmm1 \n" - "lea (%0,%3,2),%0 \n" - "punpcklbw %%xmm1,%%xmm0 \n" - "movq (%0),%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "palignr $0x8,%%xmm1,%%xmm1 \n" - "movq (%0,%3),%%xmm3 \n" - "lea (%0,%3,2),%0 \n" - "punpcklbw %%xmm3,%%xmm2 \n" - "movdqa %%xmm2,%%xmm3 \n" - "movq (%0),%%xmm4 \n" - "palignr $0x8,%%xmm3,%%xmm3 \n" - "movq (%0,%3),%%xmm5 \n" - "lea (%0,%3,2),%0 \n" - "punpcklbw %%xmm5,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "movq (%0),%%xmm6 \n" - "palignr $0x8,%%xmm5,%%xmm5 \n" - "movq (%0,%3),%%xmm7 \n" - "lea (%0,%3,2),%0 \n" - "punpcklbw %%xmm7,%%xmm6 \n" - "neg %3 \n" - "movdqa %%xmm6,%%xmm7 \n" - "lea 0x8(%0,%3,8),%0 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "neg %3 \n" + "1: \n" + "movq (%0),%%xmm0 \n" + "movq (%0,%3),%%xmm1 \n" + "lea (%0,%3,2),%0 \n" + "punpcklbw %%xmm1,%%xmm0 \n" + "movq (%0),%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "palignr $0x8,%%xmm1,%%xmm1 \n" + "movq (%0,%3),%%xmm3 \n" + "lea (%0,%3,2),%0 \n" + "punpcklbw %%xmm3,%%xmm2 \n" + "movdqa %%xmm2,%%xmm3 \n" + "movq (%0),%%xmm4 \n" + "palignr $0x8,%%xmm3,%%xmm3 \n" + "movq (%0,%3),%%xmm5 \n" + "lea (%0,%3,2),%0 \n" + "punpcklbw %%xmm5,%%xmm4 \n" + "movdqa %%xmm4,%%xmm5 \n" + "movq (%0),%%xmm6 \n" + "palignr $0x8,%%xmm5,%%xmm5 \n" + "movq (%0,%3),%%xmm7 \n" + "lea (%0,%3,2),%0 \n" + "punpcklbw %%xmm7,%%xmm6 \n" + "neg %3 \n" + "movdqa %%xmm6,%%xmm7 \n" + "lea 0x8(%0,%3,8),%0 \n" + "palignr $0x8,%%xmm7,%%xmm7 \n" + "neg %3 \n" // Second round of bit swap. - "punpcklwd %%xmm2,%%xmm0 \n" - "punpcklwd %%xmm3,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "movdqa %%xmm1,%%xmm3 \n" - "palignr $0x8,%%xmm2,%%xmm2 \n" - "palignr $0x8,%%xmm3,%%xmm3 \n" - "punpcklwd %%xmm6,%%xmm4 \n" - "punpcklwd %%xmm7,%%xmm5 \n" - "movdqa %%xmm4,%%xmm6 \n" - "movdqa %%xmm5,%%xmm7 \n" - "palignr $0x8,%%xmm6,%%xmm6 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" + "punpcklwd %%xmm2,%%xmm0 \n" + "punpcklwd %%xmm3,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "movdqa %%xmm1,%%xmm3 \n" + "palignr $0x8,%%xmm2,%%xmm2 \n" + "palignr $0x8,%%xmm3,%%xmm3 \n" + "punpcklwd %%xmm6,%%xmm4 \n" + "punpcklwd %%xmm7,%%xmm5 \n" + "movdqa %%xmm4,%%xmm6 \n" + "movdqa %%xmm5,%%xmm7 \n" + "palignr $0x8,%%xmm6,%%xmm6 \n" + "palignr $0x8,%%xmm7,%%xmm7 \n" // Third round of bit swap. // Write to the destination pointer. - "punpckldq %%xmm4,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "movdqa %%xmm0,%%xmm4 \n" - "palignr $0x8,%%xmm4,%%xmm4 \n" - "movq %%xmm4,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm6,%%xmm2 \n" - "movdqa %%xmm2,%%xmm6 \n" - "movq %%xmm2,(%1) \n" - "palignr $0x8,%%xmm6,%%xmm6 \n" - "punpckldq %%xmm5,%%xmm1 \n" - "movq %%xmm6,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "movdqa %%xmm1,%%xmm5 \n" - "movq %%xmm1,(%1) \n" - "palignr $0x8,%%xmm5,%%xmm5 \n" - "movq %%xmm5,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm7,%%xmm3 \n" - "movq %%xmm3,(%1) \n" - "movdqa %%xmm3,%%xmm7 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "sub $0x8,%2 \n" - "movq %%xmm7,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "jg 1b \n" + "punpckldq %%xmm4,%%xmm0 \n" + "movq %%xmm0,(%1) \n" + "movdqa %%xmm0,%%xmm4 \n" + "palignr $0x8,%%xmm4,%%xmm4 \n" + "movq %%xmm4,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "punpckldq %%xmm6,%%xmm2 \n" + "movdqa %%xmm2,%%xmm6 \n" + "movq %%xmm2,(%1) \n" + "palignr $0x8,%%xmm6,%%xmm6 \n" + "punpckldq %%xmm5,%%xmm1 \n" + "movq %%xmm6,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "movdqa %%xmm1,%%xmm5 \n" + "movq %%xmm1,(%1) \n" + "palignr $0x8,%%xmm5,%%xmm5 \n" + "movq %%xmm5,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "punpckldq %%xmm7,%%xmm3 \n" + "movq %%xmm3,(%1) \n" + "movdqa %%xmm3,%%xmm7 \n" + "palignr $0x8,%%xmm7,%%xmm7 \n" + "sub $0x8,%2 \n" + "movq %%xmm7,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -121,127 +121,127 @@ void TransposeWx8_Fast_SSSE3(const uint8_t* src, // Read in the data from the source pointer. // First round of bit swap. LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu (%0,%3),%%xmm1 \n" - "lea (%0,%3,2),%0 \n" - "movdqa %%xmm0,%%xmm8 \n" - "punpcklbw %%xmm1,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm8 \n" - "movdqu (%0),%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm8,%%xmm9 \n" - "palignr $0x8,%%xmm1,%%xmm1 \n" - "palignr $0x8,%%xmm9,%%xmm9 \n" - "movdqu (%0,%3),%%xmm3 \n" - "lea (%0,%3,2),%0 \n" - "movdqa %%xmm2,%%xmm10 \n" - "punpcklbw %%xmm3,%%xmm2 \n" - "punpckhbw %%xmm3,%%xmm10 \n" - "movdqa %%xmm2,%%xmm3 \n" - "movdqa %%xmm10,%%xmm11 \n" - "movdqu (%0),%%xmm4 \n" - "palignr $0x8,%%xmm3,%%xmm3 \n" - "palignr $0x8,%%xmm11,%%xmm11 \n" - "movdqu (%0,%3),%%xmm5 \n" - "lea (%0,%3,2),%0 \n" - "movdqa %%xmm4,%%xmm12 \n" - "punpcklbw %%xmm5,%%xmm4 \n" - "punpckhbw %%xmm5,%%xmm12 \n" - "movdqa %%xmm4,%%xmm5 \n" - "movdqa %%xmm12,%%xmm13 \n" - "movdqu (%0),%%xmm6 \n" - "palignr $0x8,%%xmm5,%%xmm5 \n" - "palignr $0x8,%%xmm13,%%xmm13 \n" - "movdqu (%0,%3),%%xmm7 \n" - "lea (%0,%3,2),%0 \n" - "movdqa %%xmm6,%%xmm14 \n" - "punpcklbw %%xmm7,%%xmm6 \n" - "punpckhbw %%xmm7,%%xmm14 \n" - "neg %3 \n" - "movdqa %%xmm6,%%xmm7 \n" - "movdqa %%xmm14,%%xmm15 \n" - "lea 0x10(%0,%3,8),%0 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "palignr $0x8,%%xmm15,%%xmm15 \n" - "neg %3 \n" + "1: \n" + "movdqu (%0),%%xmm0 \n" + "movdqu (%0,%3),%%xmm1 \n" + "lea (%0,%3,2),%0 \n" + "movdqa %%xmm0,%%xmm8 \n" + "punpcklbw %%xmm1,%%xmm0 \n" + "punpckhbw %%xmm1,%%xmm8 \n" + "movdqu (%0),%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm8,%%xmm9 \n" + "palignr $0x8,%%xmm1,%%xmm1 \n" + "palignr $0x8,%%xmm9,%%xmm9 \n" + "movdqu (%0,%3),%%xmm3 \n" + "lea (%0,%3,2),%0 \n" + "movdqa %%xmm2,%%xmm10 \n" + "punpcklbw %%xmm3,%%xmm2 \n" + "punpckhbw %%xmm3,%%xmm10 \n" + "movdqa %%xmm2,%%xmm3 \n" + "movdqa %%xmm10,%%xmm11 \n" + "movdqu (%0),%%xmm4 \n" + "palignr $0x8,%%xmm3,%%xmm3 \n" + "palignr $0x8,%%xmm11,%%xmm11 \n" + "movdqu (%0,%3),%%xmm5 \n" + "lea (%0,%3,2),%0 \n" + "movdqa %%xmm4,%%xmm12 \n" + "punpcklbw %%xmm5,%%xmm4 \n" + "punpckhbw %%xmm5,%%xmm12 \n" + "movdqa %%xmm4,%%xmm5 \n" + "movdqa %%xmm12,%%xmm13 \n" + "movdqu (%0),%%xmm6 \n" + "palignr $0x8,%%xmm5,%%xmm5 \n" + "palignr $0x8,%%xmm13,%%xmm13 \n" + "movdqu (%0,%3),%%xmm7 \n" + "lea (%0,%3,2),%0 \n" + "movdqa %%xmm6,%%xmm14 \n" + "punpcklbw %%xmm7,%%xmm6 \n" + "punpckhbw %%xmm7,%%xmm14 \n" + "neg %3 \n" + "movdqa %%xmm6,%%xmm7 \n" + "movdqa %%xmm14,%%xmm15 \n" + "lea 0x10(%0,%3,8),%0 \n" + "palignr $0x8,%%xmm7,%%xmm7 \n" + "palignr $0x8,%%xmm15,%%xmm15 \n" + "neg %3 \n" // Second round of bit swap. - "punpcklwd %%xmm2,%%xmm0 \n" - "punpcklwd %%xmm3,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "movdqa %%xmm1,%%xmm3 \n" - "palignr $0x8,%%xmm2,%%xmm2 \n" - "palignr $0x8,%%xmm3,%%xmm3 \n" - "punpcklwd %%xmm6,%%xmm4 \n" - "punpcklwd %%xmm7,%%xmm5 \n" - "movdqa %%xmm4,%%xmm6 \n" - "movdqa %%xmm5,%%xmm7 \n" - "palignr $0x8,%%xmm6,%%xmm6 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "punpcklwd %%xmm10,%%xmm8 \n" - "punpcklwd %%xmm11,%%xmm9 \n" - "movdqa %%xmm8,%%xmm10 \n" - "movdqa %%xmm9,%%xmm11 \n" - "palignr $0x8,%%xmm10,%%xmm10 \n" - "palignr $0x8,%%xmm11,%%xmm11 \n" - "punpcklwd %%xmm14,%%xmm12 \n" - "punpcklwd %%xmm15,%%xmm13 \n" - "movdqa %%xmm12,%%xmm14 \n" - "movdqa %%xmm13,%%xmm15 \n" - "palignr $0x8,%%xmm14,%%xmm14 \n" - "palignr $0x8,%%xmm15,%%xmm15 \n" + "punpcklwd %%xmm2,%%xmm0 \n" + "punpcklwd %%xmm3,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "movdqa %%xmm1,%%xmm3 \n" + "palignr $0x8,%%xmm2,%%xmm2 \n" + "palignr $0x8,%%xmm3,%%xmm3 \n" + "punpcklwd %%xmm6,%%xmm4 \n" + "punpcklwd %%xmm7,%%xmm5 \n" + "movdqa %%xmm4,%%xmm6 \n" + "movdqa %%xmm5,%%xmm7 \n" + "palignr $0x8,%%xmm6,%%xmm6 \n" + "palignr $0x8,%%xmm7,%%xmm7 \n" + "punpcklwd %%xmm10,%%xmm8 \n" + "punpcklwd %%xmm11,%%xmm9 \n" + "movdqa %%xmm8,%%xmm10 \n" + "movdqa %%xmm9,%%xmm11 \n" + "palignr $0x8,%%xmm10,%%xmm10 \n" + "palignr $0x8,%%xmm11,%%xmm11 \n" + "punpcklwd %%xmm14,%%xmm12 \n" + "punpcklwd %%xmm15,%%xmm13 \n" + "movdqa %%xmm12,%%xmm14 \n" + "movdqa %%xmm13,%%xmm15 \n" + "palignr $0x8,%%xmm14,%%xmm14 \n" + "palignr $0x8,%%xmm15,%%xmm15 \n" // Third round of bit swap. // Write to the destination pointer. - "punpckldq %%xmm4,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "movdqa %%xmm0,%%xmm4 \n" - "palignr $0x8,%%xmm4,%%xmm4 \n" - "movq %%xmm4,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm6,%%xmm2 \n" - "movdqa %%xmm2,%%xmm6 \n" - "movq %%xmm2,(%1) \n" - "palignr $0x8,%%xmm6,%%xmm6 \n" - "punpckldq %%xmm5,%%xmm1 \n" - "movq %%xmm6,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "movdqa %%xmm1,%%xmm5 \n" - "movq %%xmm1,(%1) \n" - "palignr $0x8,%%xmm5,%%xmm5 \n" - "movq %%xmm5,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm7,%%xmm3 \n" - "movq %%xmm3,(%1) \n" - "movdqa %%xmm3,%%xmm7 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "movq %%xmm7,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm12,%%xmm8 \n" - "movq %%xmm8,(%1) \n" - "movdqa %%xmm8,%%xmm12 \n" - "palignr $0x8,%%xmm12,%%xmm12 \n" - "movq %%xmm12,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm14,%%xmm10 \n" - "movdqa %%xmm10,%%xmm14 \n" - "movq %%xmm10,(%1) \n" - "palignr $0x8,%%xmm14,%%xmm14 \n" - "punpckldq %%xmm13,%%xmm9 \n" - "movq %%xmm14,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "movdqa %%xmm9,%%xmm13 \n" - "movq %%xmm9,(%1) \n" - "palignr $0x8,%%xmm13,%%xmm13 \n" - "movq %%xmm13,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm15,%%xmm11 \n" - "movq %%xmm11,(%1) \n" - "movdqa %%xmm11,%%xmm15 \n" - "palignr $0x8,%%xmm15,%%xmm15 \n" - "sub $0x10,%2 \n" - "movq %%xmm15,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "jg 1b \n" + "punpckldq %%xmm4,%%xmm0 \n" + "movq %%xmm0,(%1) \n" + "movdqa %%xmm0,%%xmm4 \n" + "palignr $0x8,%%xmm4,%%xmm4 \n" + "movq %%xmm4,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "punpckldq %%xmm6,%%xmm2 \n" + "movdqa %%xmm2,%%xmm6 \n" + "movq %%xmm2,(%1) \n" + "palignr $0x8,%%xmm6,%%xmm6 \n" + "punpckldq %%xmm5,%%xmm1 \n" + "movq %%xmm6,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "movdqa %%xmm1,%%xmm5 \n" + "movq %%xmm1,(%1) \n" + "palignr $0x8,%%xmm5,%%xmm5 \n" + "movq %%xmm5,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "punpckldq %%xmm7,%%xmm3 \n" + "movq %%xmm3,(%1) \n" + "movdqa %%xmm3,%%xmm7 \n" + "palignr $0x8,%%xmm7,%%xmm7 \n" + "movq %%xmm7,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "punpckldq %%xmm12,%%xmm8 \n" + "movq %%xmm8,(%1) \n" + "movdqa %%xmm8,%%xmm12 \n" + "palignr $0x8,%%xmm12,%%xmm12 \n" + "movq %%xmm12,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "punpckldq %%xmm14,%%xmm10 \n" + "movdqa %%xmm10,%%xmm14 \n" + "movq %%xmm10,(%1) \n" + "palignr $0x8,%%xmm14,%%xmm14 \n" + "punpckldq %%xmm13,%%xmm9 \n" + "movq %%xmm14,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "movdqa %%xmm9,%%xmm13 \n" + "movq %%xmm9,(%1) \n" + "palignr $0x8,%%xmm13,%%xmm13 \n" + "movq %%xmm13,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "punpckldq %%xmm15,%%xmm11 \n" + "movq %%xmm11,(%1) \n" + "movdqa %%xmm11,%%xmm15 \n" + "palignr $0x8,%%xmm15,%%xmm15 \n" + "sub $0x10,%2 \n" + "movq %%xmm15,(%1,%4) \n" + "lea (%1,%4,2),%1 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -266,95 +266,95 @@ void TransposeUVWx8_SSE2(const uint8_t* src, // Read in the data from the source pointer. // First round of bit swap. LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu (%0,%4),%%xmm1 \n" - "lea (%0,%4,2),%0 \n" - "movdqa %%xmm0,%%xmm8 \n" - "punpcklbw %%xmm1,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm8 \n" - "movdqa %%xmm8,%%xmm1 \n" - "movdqu (%0),%%xmm2 \n" - "movdqu (%0,%4),%%xmm3 \n" - "lea (%0,%4,2),%0 \n" - "movdqa %%xmm2,%%xmm8 \n" - "punpcklbw %%xmm3,%%xmm2 \n" - "punpckhbw %%xmm3,%%xmm8 \n" - "movdqa %%xmm8,%%xmm3 \n" - "movdqu (%0),%%xmm4 \n" - "movdqu (%0,%4),%%xmm5 \n" - "lea (%0,%4,2),%0 \n" - "movdqa %%xmm4,%%xmm8 \n" - "punpcklbw %%xmm5,%%xmm4 \n" - "punpckhbw %%xmm5,%%xmm8 \n" - "movdqa %%xmm8,%%xmm5 \n" - "movdqu (%0),%%xmm6 \n" - "movdqu (%0,%4),%%xmm7 \n" - "lea (%0,%4,2),%0 \n" - "movdqa %%xmm6,%%xmm8 \n" - "punpcklbw %%xmm7,%%xmm6 \n" - "neg %4 \n" - "lea 0x10(%0,%4,8),%0 \n" - "punpckhbw %%xmm7,%%xmm8 \n" - "movdqa %%xmm8,%%xmm7 \n" - "neg %4 \n" + "1: \n" + "movdqu (%0),%%xmm0 \n" + "movdqu (%0,%4),%%xmm1 \n" + "lea (%0,%4,2),%0 \n" + "movdqa %%xmm0,%%xmm8 \n" + "punpcklbw %%xmm1,%%xmm0 \n" + "punpckhbw %%xmm1,%%xmm8 \n" + "movdqa %%xmm8,%%xmm1 \n" + "movdqu (%0),%%xmm2 \n" + "movdqu (%0,%4),%%xmm3 \n" + "lea (%0,%4,2),%0 \n" + "movdqa %%xmm2,%%xmm8 \n" + "punpcklbw %%xmm3,%%xmm2 \n" + "punpckhbw %%xmm3,%%xmm8 \n" + "movdqa %%xmm8,%%xmm3 \n" + "movdqu (%0),%%xmm4 \n" + "movdqu (%0,%4),%%xmm5 \n" + "lea (%0,%4,2),%0 \n" + "movdqa %%xmm4,%%xmm8 \n" + "punpcklbw %%xmm5,%%xmm4 \n" + "punpckhbw %%xmm5,%%xmm8 \n" + "movdqa %%xmm8,%%xmm5 \n" + "movdqu (%0),%%xmm6 \n" + "movdqu (%0,%4),%%xmm7 \n" + "lea (%0,%4,2),%0 \n" + "movdqa %%xmm6,%%xmm8 \n" + "punpcklbw %%xmm7,%%xmm6 \n" + "neg %4 \n" + "lea 0x10(%0,%4,8),%0 \n" + "punpckhbw %%xmm7,%%xmm8 \n" + "movdqa %%xmm8,%%xmm7 \n" + "neg %4 \n" // Second round of bit swap. - "movdqa %%xmm0,%%xmm8 \n" - "movdqa %%xmm1,%%xmm9 \n" - "punpckhwd %%xmm2,%%xmm8 \n" - "punpckhwd %%xmm3,%%xmm9 \n" - "punpcklwd %%xmm2,%%xmm0 \n" - "punpcklwd %%xmm3,%%xmm1 \n" - "movdqa %%xmm8,%%xmm2 \n" - "movdqa %%xmm9,%%xmm3 \n" - "movdqa %%xmm4,%%xmm8 \n" - "movdqa %%xmm5,%%xmm9 \n" - "punpckhwd %%xmm6,%%xmm8 \n" - "punpckhwd %%xmm7,%%xmm9 \n" - "punpcklwd %%xmm6,%%xmm4 \n" - "punpcklwd %%xmm7,%%xmm5 \n" - "movdqa %%xmm8,%%xmm6 \n" - "movdqa %%xmm9,%%xmm7 \n" + "movdqa %%xmm0,%%xmm8 \n" + "movdqa %%xmm1,%%xmm9 \n" + "punpckhwd %%xmm2,%%xmm8 \n" + "punpckhwd %%xmm3,%%xmm9 \n" + "punpcklwd %%xmm2,%%xmm0 \n" + "punpcklwd %%xmm3,%%xmm1 \n" + "movdqa %%xmm8,%%xmm2 \n" + "movdqa %%xmm9,%%xmm3 \n" + "movdqa %%xmm4,%%xmm8 \n" + "movdqa %%xmm5,%%xmm9 \n" + "punpckhwd %%xmm6,%%xmm8 \n" + "punpckhwd %%xmm7,%%xmm9 \n" + "punpcklwd %%xmm6,%%xmm4 \n" + "punpcklwd %%xmm7,%%xmm5 \n" + "movdqa %%xmm8,%%xmm6 \n" + "movdqa %%xmm9,%%xmm7 \n" // Third round of bit swap. // Write to the destination pointer. - "movdqa %%xmm0,%%xmm8 \n" - "punpckldq %%xmm4,%%xmm0 \n" - "movlpd %%xmm0,(%1) \n" // Write back U channel - "movhpd %%xmm0,(%2) \n" // Write back V channel - "punpckhdq %%xmm4,%%xmm8 \n" - "movlpd %%xmm8,(%1,%5) \n" - "lea (%1,%5,2),%1 \n" - "movhpd %%xmm8,(%2,%6) \n" - "lea (%2,%6,2),%2 \n" - "movdqa %%xmm2,%%xmm8 \n" - "punpckldq %%xmm6,%%xmm2 \n" - "movlpd %%xmm2,(%1) \n" - "movhpd %%xmm2,(%2) \n" - "punpckhdq %%xmm6,%%xmm8 \n" - "movlpd %%xmm8,(%1,%5) \n" - "lea (%1,%5,2),%1 \n" - "movhpd %%xmm8,(%2,%6) \n" - "lea (%2,%6,2),%2 \n" - "movdqa %%xmm1,%%xmm8 \n" - "punpckldq %%xmm5,%%xmm1 \n" - "movlpd %%xmm1,(%1) \n" - "movhpd %%xmm1,(%2) \n" - "punpckhdq %%xmm5,%%xmm8 \n" - "movlpd %%xmm8,(%1,%5) \n" - "lea (%1,%5,2),%1 \n" - "movhpd %%xmm8,(%2,%6) \n" - "lea (%2,%6,2),%2 \n" - "movdqa %%xmm3,%%xmm8 \n" - "punpckldq %%xmm7,%%xmm3 \n" - "movlpd %%xmm3,(%1) \n" - "movhpd %%xmm3,(%2) \n" - "punpckhdq %%xmm7,%%xmm8 \n" - "sub $0x8,%3 \n" - "movlpd %%xmm8,(%1,%5) \n" - "lea (%1,%5,2),%1 \n" - "movhpd %%xmm8,(%2,%6) \n" - "lea (%2,%6,2),%2 \n" - "jg 1b \n" + "movdqa %%xmm0,%%xmm8 \n" + "punpckldq %%xmm4,%%xmm0 \n" + "movlpd %%xmm0,(%1) \n" // Write back U channel + "movhpd %%xmm0,(%2) \n" // Write back V channel + "punpckhdq %%xmm4,%%xmm8 \n" + "movlpd %%xmm8,(%1,%5) \n" + "lea (%1,%5,2),%1 \n" + "movhpd %%xmm8,(%2,%6) \n" + "lea (%2,%6,2),%2 \n" + "movdqa %%xmm2,%%xmm8 \n" + "punpckldq %%xmm6,%%xmm2 \n" + "movlpd %%xmm2,(%1) \n" + "movhpd %%xmm2,(%2) \n" + "punpckhdq %%xmm6,%%xmm8 \n" + "movlpd %%xmm8,(%1,%5) \n" + "lea (%1,%5,2),%1 \n" + "movhpd %%xmm8,(%2,%6) \n" + "lea (%2,%6,2),%2 \n" + "movdqa %%xmm1,%%xmm8 \n" + "punpckldq %%xmm5,%%xmm1 \n" + "movlpd %%xmm1,(%1) \n" + "movhpd %%xmm1,(%2) \n" + "punpckhdq %%xmm5,%%xmm8 \n" + "movlpd %%xmm8,(%1,%5) \n" + "lea (%1,%5,2),%1 \n" + "movhpd %%xmm8,(%2,%6) \n" + "lea (%2,%6,2),%2 \n" + "movdqa %%xmm3,%%xmm8 \n" + "punpckldq %%xmm7,%%xmm3 \n" + "movlpd %%xmm3,(%1) \n" + "movhpd %%xmm3,(%2) \n" + "punpckhdq %%xmm7,%%xmm8 \n" + "sub $0x8,%3 \n" + "movlpd %%xmm8,(%1,%5) \n" + "lea (%1,%5,2),%1 \n" + "movhpd %%xmm8,(%2,%6) \n" + "lea (%2,%6,2),%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst_a), // %1 "+r"(dst_b), // %2 diff --git a/TMessagesProj/jni/third_party/libyuv/source/rotate_neon.cc b/TMessagesProj/jni/third_party/libyuv/source/rotate_neon.cc index fdc0dd476..844df2bf3 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/rotate_neon.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/rotate_neon.cc @@ -38,52 +38,52 @@ void TransposeWx8_NEON(const uint8_t* src, // handle 8x8 blocks. this should be the majority of the plane "1: \n" - "mov %0, %1 \n" + "mov %0, %1 \n" - "vld1.8 {d0}, [%0], %2 \n" - "vld1.8 {d1}, [%0], %2 \n" - "vld1.8 {d2}, [%0], %2 \n" - "vld1.8 {d3}, [%0], %2 \n" - "vld1.8 {d4}, [%0], %2 \n" - "vld1.8 {d5}, [%0], %2 \n" - "vld1.8 {d6}, [%0], %2 \n" - "vld1.8 {d7}, [%0] \n" + "vld1.8 {d0}, [%0], %2 \n" + "vld1.8 {d1}, [%0], %2 \n" + "vld1.8 {d2}, [%0], %2 \n" + "vld1.8 {d3}, [%0], %2 \n" + "vld1.8 {d4}, [%0], %2 \n" + "vld1.8 {d5}, [%0], %2 \n" + "vld1.8 {d6}, [%0], %2 \n" + "vld1.8 {d7}, [%0] \n" - "vtrn.8 d1, d0 \n" - "vtrn.8 d3, d2 \n" - "vtrn.8 d5, d4 \n" - "vtrn.8 d7, d6 \n" + "vtrn.8 d1, d0 \n" + "vtrn.8 d3, d2 \n" + "vtrn.8 d5, d4 \n" + "vtrn.8 d7, d6 \n" - "vtrn.16 d1, d3 \n" - "vtrn.16 d0, d2 \n" - "vtrn.16 d5, d7 \n" - "vtrn.16 d4, d6 \n" + "vtrn.16 d1, d3 \n" + "vtrn.16 d0, d2 \n" + "vtrn.16 d5, d7 \n" + "vtrn.16 d4, d6 \n" - "vtrn.32 d1, d5 \n" - "vtrn.32 d0, d4 \n" - "vtrn.32 d3, d7 \n" - "vtrn.32 d2, d6 \n" + "vtrn.32 d1, d5 \n" + "vtrn.32 d0, d4 \n" + "vtrn.32 d3, d7 \n" + "vtrn.32 d2, d6 \n" - "vrev16.8 q0, q0 \n" - "vrev16.8 q1, q1 \n" - "vrev16.8 q2, q2 \n" - "vrev16.8 q3, q3 \n" + "vrev16.8 q0, q0 \n" + "vrev16.8 q1, q1 \n" + "vrev16.8 q2, q2 \n" + "vrev16.8 q3, q3 \n" - "mov %0, %3 \n" + "mov %0, %3 \n" - "vst1.8 {d1}, [%0], %4 \n" - "vst1.8 {d0}, [%0], %4 \n" - "vst1.8 {d3}, [%0], %4 \n" - "vst1.8 {d2}, [%0], %4 \n" - "vst1.8 {d5}, [%0], %4 \n" - "vst1.8 {d4}, [%0], %4 \n" - "vst1.8 {d7}, [%0], %4 \n" - "vst1.8 {d6}, [%0] \n" + "vst1.8 {d1}, [%0], %4 \n" + "vst1.8 {d0}, [%0], %4 \n" + "vst1.8 {d3}, [%0], %4 \n" + "vst1.8 {d2}, [%0], %4 \n" + "vst1.8 {d5}, [%0], %4 \n" + "vst1.8 {d4}, [%0], %4 \n" + "vst1.8 {d7}, [%0], %4 \n" + "vst1.8 {d6}, [%0] \n" - "add %1, #8 \n" // src += 8 - "add %3, %3, %4, lsl #3 \n" // dst += 8 * dst_stride - "subs %5, #8 \n" // w -= 8 - "bge 1b \n" + "add %1, #8 \n" // src += 8 + "add %3, %3, %4, lsl #3 \n" // dst += 8 * dst_stride + "subs %5, #8 \n" // w -= 8 + "bge 1b \n" // add 8 back to counter. if the result is 0 there are // no residuals. @@ -208,68 +208,70 @@ void TransposeUVWx8_NEON(const uint8_t* src, // handle 8x8 blocks. this should be the majority of the plane "1: \n" - "mov %0, %1 \n" + "mov %0, %1 \n" - "vld2.8 {d0, d1}, [%0], %2 \n" - "vld2.8 {d2, d3}, [%0], %2 \n" - "vld2.8 {d4, d5}, [%0], %2 \n" - "vld2.8 {d6, d7}, [%0], %2 \n" - "vld2.8 {d16, d17}, [%0], %2 \n" - "vld2.8 {d18, d19}, [%0], %2 \n" - "vld2.8 {d20, d21}, [%0], %2 \n" - "vld2.8 {d22, d23}, [%0] \n" + "vld2.8 {d0, d1}, [%0], %2 \n" + "vld2.8 {d2, d3}, [%0], %2 \n" + "vld2.8 {d4, d5}, [%0], %2 \n" + "vld2.8 {d6, d7}, [%0], %2 \n" + "vld2.8 {d16, d17}, [%0], %2 \n" + "vld2.8 {d18, d19}, [%0], %2 \n" + "vld2.8 {d20, d21}, [%0], %2 \n" + "vld2.8 {d22, d23}, [%0] \n" - "vtrn.8 q1, q0 \n" - "vtrn.8 q3, q2 \n" - "vtrn.8 q9, q8 \n" - "vtrn.8 q11, q10 \n" + "vtrn.8 q1, q0 \n" + "vtrn.8 q3, q2 \n" + "vtrn.8 q9, q8 \n" + "vtrn.8 q11, q10 \n" - "vtrn.16 q1, q3 \n" - "vtrn.16 q0, q2 \n" - "vtrn.16 q9, q11 \n" - "vtrn.16 q8, q10 \n" + "vtrn.16 q1, q3 \n" + "vtrn.16 q0, q2 \n" + "vtrn.16 q9, q11 \n" + "vtrn.16 q8, q10 \n" - "vtrn.32 q1, q9 \n" - "vtrn.32 q0, q8 \n" - "vtrn.32 q3, q11 \n" - "vtrn.32 q2, q10 \n" + "vtrn.32 q1, q9 \n" + "vtrn.32 q0, q8 \n" + "vtrn.32 q3, q11 \n" + "vtrn.32 q2, q10 \n" - "vrev16.8 q0, q0 \n" - "vrev16.8 q1, q1 \n" - "vrev16.8 q2, q2 \n" - "vrev16.8 q3, q3 \n" - "vrev16.8 q8, q8 \n" - "vrev16.8 q9, q9 \n" - "vrev16.8 q10, q10 \n" - "vrev16.8 q11, q11 \n" + "vrev16.8 q0, q0 \n" + "vrev16.8 q1, q1 \n" + "vrev16.8 q2, q2 \n" + "vrev16.8 q3, q3 \n" + "vrev16.8 q8, q8 \n" + "vrev16.8 q9, q9 \n" + "vrev16.8 q10, q10 \n" + "vrev16.8 q11, q11 \n" - "mov %0, %3 \n" + "mov %0, %3 \n" - "vst1.8 {d2}, [%0], %4 \n" - "vst1.8 {d0}, [%0], %4 \n" - "vst1.8 {d6}, [%0], %4 \n" - "vst1.8 {d4}, [%0], %4 \n" - "vst1.8 {d18}, [%0], %4 \n" - "vst1.8 {d16}, [%0], %4 \n" - "vst1.8 {d22}, [%0], %4 \n" - "vst1.8 {d20}, [%0] \n" + "vst1.8 {d2}, [%0], %4 \n" + "vst1.8 {d0}, [%0], %4 \n" + "vst1.8 {d6}, [%0], %4 \n" + "vst1.8 {d4}, [%0], %4 \n" + "vst1.8 {d18}, [%0], %4 \n" + "vst1.8 {d16}, [%0], %4 \n" + "vst1.8 {d22}, [%0], %4 \n" + "vst1.8 {d20}, [%0] \n" - "mov %0, %5 \n" + "mov %0, %5 \n" - "vst1.8 {d3}, [%0], %6 \n" - "vst1.8 {d1}, [%0], %6 \n" - "vst1.8 {d7}, [%0], %6 \n" - "vst1.8 {d5}, [%0], %6 \n" - "vst1.8 {d19}, [%0], %6 \n" - "vst1.8 {d17}, [%0], %6 \n" - "vst1.8 {d23}, [%0], %6 \n" - "vst1.8 {d21}, [%0] \n" + "vst1.8 {d3}, [%0], %6 \n" + "vst1.8 {d1}, [%0], %6 \n" + "vst1.8 {d7}, [%0], %6 \n" + "vst1.8 {d5}, [%0], %6 \n" + "vst1.8 {d19}, [%0], %6 \n" + "vst1.8 {d17}, [%0], %6 \n" + "vst1.8 {d23}, [%0], %6 \n" + "vst1.8 {d21}, [%0] \n" - "add %1, #8*2 \n" // src += 8*2 - "add %3, %3, %4, lsl #3 \n" // dst_a += 8 * dst_stride_a - "add %5, %5, %6, lsl #3 \n" // dst_b += 8 * dst_stride_b - "subs %7, #8 \n" // w -= 8 - "bge 1b \n" + "add %1, #8*2 \n" // src += 8*2 + "add %3, %3, %4, lsl #3 \n" // dst_a += 8 * + // dst_stride_a + "add %5, %5, %6, lsl #3 \n" // dst_b += 8 * + // dst_stride_b + "subs %7, #8 \n" // w -= 8 + "bge 1b \n" // add 8 back to counter. if the result is 0 there are // no residuals. diff --git a/TMessagesProj/jni/third_party/libyuv/source/rotate_neon64.cc b/TMessagesProj/jni/third_party/libyuv/source/rotate_neon64.cc index f469baacf..43c158173 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/rotate_neon64.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/rotate_neon64.cc @@ -34,58 +34,74 @@ void TransposeWx8_NEON(const uint8_t* src, // loops are on blocks of 8. loop will stop when // counter gets to or below 0. starting the counter // at w-8 allow for this - "sub %w3, %w3, #8 \n" + "sub %w3, %w3, #8 \n" // handle 8x8 blocks. this should be the majority of the plane - "1: \n" + "1: \n" "mov %0, %1 \n" - "ld1 {v0.8b}, [%0], %5 \n" - "ld1 {v1.8b}, [%0], %5 \n" - "ld1 {v2.8b}, [%0], %5 \n" - "ld1 {v3.8b}, [%0], %5 \n" - "ld1 {v4.8b}, [%0], %5 \n" - "ld1 {v5.8b}, [%0], %5 \n" - "ld1 {v6.8b}, [%0], %5 \n" - "ld1 {v7.8b}, [%0] \n" + "ld1 {v0.8b}, [%0], %5 \n" + "ld1 {v1.8b}, [%0], %5 \n" + "ld1 {v2.8b}, [%0], %5 \n" + "ld1 {v3.8b}, [%0], %5 \n" + "ld1 {v4.8b}, [%0], %5 \n" + "ld1 {v5.8b}, [%0], %5 \n" + "ld1 {v6.8b}, [%0], %5 \n" + "ld1 {v7.8b}, [%0] \n" + "mov %0, %1 \n" - "trn2 v16.8b, v0.8b, v1.8b \n" - "trn1 v17.8b, v0.8b, v1.8b \n" - "trn2 v18.8b, v2.8b, v3.8b \n" - "trn1 v19.8b, v2.8b, v3.8b \n" - "trn2 v20.8b, v4.8b, v5.8b \n" - "trn1 v21.8b, v4.8b, v5.8b \n" - "trn2 v22.8b, v6.8b, v7.8b \n" - "trn1 v23.8b, v6.8b, v7.8b \n" + "trn2 v16.8b, v0.8b, v1.8b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "trn1 v17.8b, v0.8b, v1.8b \n" + "add %0, %0, %5 \n" + "trn2 v18.8b, v2.8b, v3.8b \n" + "prfm pldl1keep, [%0, 448] \n" // row 1 + "trn1 v19.8b, v2.8b, v3.8b \n" + "add %0, %0, %5 \n" + "trn2 v20.8b, v4.8b, v5.8b \n" + "prfm pldl1keep, [%0, 448] \n" // row 2 + "trn1 v21.8b, v4.8b, v5.8b \n" + "add %0, %0, %5 \n" + "trn2 v22.8b, v6.8b, v7.8b \n" + "prfm pldl1keep, [%0, 448] \n" // row 3 + "trn1 v23.8b, v6.8b, v7.8b \n" + "add %0, %0, %5 \n" - "trn2 v3.4h, v17.4h, v19.4h \n" - "trn1 v1.4h, v17.4h, v19.4h \n" - "trn2 v2.4h, v16.4h, v18.4h \n" - "trn1 v0.4h, v16.4h, v18.4h \n" - "trn2 v7.4h, v21.4h, v23.4h \n" - "trn1 v5.4h, v21.4h, v23.4h \n" - "trn2 v6.4h, v20.4h, v22.4h \n" - "trn1 v4.4h, v20.4h, v22.4h \n" + "trn2 v3.4h, v17.4h, v19.4h \n" + "prfm pldl1keep, [%0, 448] \n" // row 4 + "trn1 v1.4h, v17.4h, v19.4h \n" + "add %0, %0, %5 \n" + "trn2 v2.4h, v16.4h, v18.4h \n" + "prfm pldl1keep, [%0, 448] \n" // row 5 + "trn1 v0.4h, v16.4h, v18.4h \n" + "add %0, %0, %5 \n" + "trn2 v7.4h, v21.4h, v23.4h \n" + "prfm pldl1keep, [%0, 448] \n" // row 6 + "trn1 v5.4h, v21.4h, v23.4h \n" + "add %0, %0, %5 \n" + "trn2 v6.4h, v20.4h, v22.4h \n" + "prfm pldl1keep, [%0, 448] \n" // row 7 + "trn1 v4.4h, v20.4h, v22.4h \n" - "trn2 v21.2s, v1.2s, v5.2s \n" - "trn1 v17.2s, v1.2s, v5.2s \n" - "trn2 v20.2s, v0.2s, v4.2s \n" - "trn1 v16.2s, v0.2s, v4.2s \n" - "trn2 v23.2s, v3.2s, v7.2s \n" - "trn1 v19.2s, v3.2s, v7.2s \n" - "trn2 v22.2s, v2.2s, v6.2s \n" - "trn1 v18.2s, v2.2s, v6.2s \n" + "trn2 v21.2s, v1.2s, v5.2s \n" + "trn1 v17.2s, v1.2s, v5.2s \n" + "trn2 v20.2s, v0.2s, v4.2s \n" + "trn1 v16.2s, v0.2s, v4.2s \n" + "trn2 v23.2s, v3.2s, v7.2s \n" + "trn1 v19.2s, v3.2s, v7.2s \n" + "trn2 v22.2s, v2.2s, v6.2s \n" + "trn1 v18.2s, v2.2s, v6.2s \n" "mov %0, %2 \n" - "st1 {v17.8b}, [%0], %6 \n" - "st1 {v16.8b}, [%0], %6 \n" - "st1 {v19.8b}, [%0], %6 \n" - "st1 {v18.8b}, [%0], %6 \n" - "st1 {v21.8b}, [%0], %6 \n" - "st1 {v20.8b}, [%0], %6 \n" - "st1 {v23.8b}, [%0], %6 \n" - "st1 {v22.8b}, [%0] \n" + "st1 {v17.8b}, [%0], %6 \n" + "st1 {v16.8b}, [%0], %6 \n" + "st1 {v19.8b}, [%0], %6 \n" + "st1 {v18.8b}, [%0], %6 \n" + "st1 {v21.8b}, [%0], %6 \n" + "st1 {v20.8b}, [%0], %6 \n" + "st1 {v23.8b}, [%0], %6 \n" + "st1 {v22.8b}, [%0] \n" "add %1, %1, #8 \n" // src += 8 "add %2, %2, %6, lsl #3 \n" // dst += 8 * dst_stride @@ -94,33 +110,33 @@ void TransposeWx8_NEON(const uint8_t* src, // add 8 back to counter. if the result is 0 there are // no residuals. - "adds %w3, %w3, #8 \n" - "b.eq 4f \n" + "adds %w3, %w3, #8 \n" + "b.eq 4f \n" // some residual, so between 1 and 7 lines left to transpose - "cmp %w3, #2 \n" - "b.lt 3f \n" + "cmp %w3, #2 \n" + "b.lt 3f \n" - "cmp %w3, #4 \n" - "b.lt 2f \n" + "cmp %w3, #4 \n" + "b.lt 2f \n" // 4x8 block - "mov %0, %1 \n" - "ld1 {v0.s}[0], [%0], %5 \n" - "ld1 {v0.s}[1], [%0], %5 \n" - "ld1 {v0.s}[2], [%0], %5 \n" - "ld1 {v0.s}[3], [%0], %5 \n" - "ld1 {v1.s}[0], [%0], %5 \n" - "ld1 {v1.s}[1], [%0], %5 \n" - "ld1 {v1.s}[2], [%0], %5 \n" - "ld1 {v1.s}[3], [%0] \n" + "mov %0, %1 \n" + "ld1 {v0.s}[0], [%0], %5 \n" + "ld1 {v0.s}[1], [%0], %5 \n" + "ld1 {v0.s}[2], [%0], %5 \n" + "ld1 {v0.s}[3], [%0], %5 \n" + "ld1 {v1.s}[0], [%0], %5 \n" + "ld1 {v1.s}[1], [%0], %5 \n" + "ld1 {v1.s}[2], [%0], %5 \n" + "ld1 {v1.s}[3], [%0] \n" - "mov %0, %2 \n" + "mov %0, %2 \n" - "ld1 {v2.16b}, [%4] \n" + "ld1 {v2.16b}, [%4] \n" - "tbl v3.16b, {v0.16b}, v2.16b \n" - "tbl v0.16b, {v1.16b}, v2.16b \n" + "tbl v3.16b, {v0.16b}, v2.16b \n" + "tbl v0.16b, {v1.16b}, v2.16b \n" // TODO(frkoenig): Rework shuffle above to // write out with 4 instead of 8 writes. @@ -212,89 +228,90 @@ void TransposeUVWx8_NEON(const uint8_t* src, // loops are on blocks of 8. loop will stop when // counter gets to or below 0. starting the counter // at w-8 allow for this - "sub %w4, %w4, #8 \n" + "sub %w4, %w4, #8 \n" // handle 8x8 blocks. this should be the majority of the plane "1: \n" - "mov %0, %1 \n" + "mov %0, %1 \n" - "ld1 {v0.16b}, [%0], %5 \n" - "ld1 {v1.16b}, [%0], %5 \n" - "ld1 {v2.16b}, [%0], %5 \n" - "ld1 {v3.16b}, [%0], %5 \n" - "ld1 {v4.16b}, [%0], %5 \n" - "ld1 {v5.16b}, [%0], %5 \n" - "ld1 {v6.16b}, [%0], %5 \n" - "ld1 {v7.16b}, [%0] \n" + "ld1 {v0.16b}, [%0], %5 \n" + "ld1 {v1.16b}, [%0], %5 \n" + "ld1 {v2.16b}, [%0], %5 \n" + "ld1 {v3.16b}, [%0], %5 \n" + "ld1 {v4.16b}, [%0], %5 \n" + "ld1 {v5.16b}, [%0], %5 \n" + "ld1 {v6.16b}, [%0], %5 \n" + "ld1 {v7.16b}, [%0] \n" + "mov %0, %1 \n" - "trn1 v16.16b, v0.16b, v1.16b \n" - "trn2 v17.16b, v0.16b, v1.16b \n" - "trn1 v18.16b, v2.16b, v3.16b \n" - "trn2 v19.16b, v2.16b, v3.16b \n" - "trn1 v20.16b, v4.16b, v5.16b \n" - "trn2 v21.16b, v4.16b, v5.16b \n" - "trn1 v22.16b, v6.16b, v7.16b \n" - "trn2 v23.16b, v6.16b, v7.16b \n" + "trn1 v16.16b, v0.16b, v1.16b \n" + "trn2 v17.16b, v0.16b, v1.16b \n" + "trn1 v18.16b, v2.16b, v3.16b \n" + "trn2 v19.16b, v2.16b, v3.16b \n" + "trn1 v20.16b, v4.16b, v5.16b \n" + "trn2 v21.16b, v4.16b, v5.16b \n" + "trn1 v22.16b, v6.16b, v7.16b \n" + "trn2 v23.16b, v6.16b, v7.16b \n" - "trn1 v0.8h, v16.8h, v18.8h \n" - "trn2 v1.8h, v16.8h, v18.8h \n" - "trn1 v2.8h, v20.8h, v22.8h \n" - "trn2 v3.8h, v20.8h, v22.8h \n" - "trn1 v4.8h, v17.8h, v19.8h \n" - "trn2 v5.8h, v17.8h, v19.8h \n" - "trn1 v6.8h, v21.8h, v23.8h \n" - "trn2 v7.8h, v21.8h, v23.8h \n" + "trn1 v0.8h, v16.8h, v18.8h \n" + "trn2 v1.8h, v16.8h, v18.8h \n" + "trn1 v2.8h, v20.8h, v22.8h \n" + "trn2 v3.8h, v20.8h, v22.8h \n" + "trn1 v4.8h, v17.8h, v19.8h \n" + "trn2 v5.8h, v17.8h, v19.8h \n" + "trn1 v6.8h, v21.8h, v23.8h \n" + "trn2 v7.8h, v21.8h, v23.8h \n" - "trn1 v16.4s, v0.4s, v2.4s \n" - "trn2 v17.4s, v0.4s, v2.4s \n" - "trn1 v18.4s, v1.4s, v3.4s \n" - "trn2 v19.4s, v1.4s, v3.4s \n" - "trn1 v20.4s, v4.4s, v6.4s \n" - "trn2 v21.4s, v4.4s, v6.4s \n" - "trn1 v22.4s, v5.4s, v7.4s \n" - "trn2 v23.4s, v5.4s, v7.4s \n" + "trn1 v16.4s, v0.4s, v2.4s \n" + "trn2 v17.4s, v0.4s, v2.4s \n" + "trn1 v18.4s, v1.4s, v3.4s \n" + "trn2 v19.4s, v1.4s, v3.4s \n" + "trn1 v20.4s, v4.4s, v6.4s \n" + "trn2 v21.4s, v4.4s, v6.4s \n" + "trn1 v22.4s, v5.4s, v7.4s \n" + "trn2 v23.4s, v5.4s, v7.4s \n" - "mov %0, %2 \n" + "mov %0, %2 \n" - "st1 {v16.d}[0], [%0], %6 \n" - "st1 {v18.d}[0], [%0], %6 \n" - "st1 {v17.d}[0], [%0], %6 \n" - "st1 {v19.d}[0], [%0], %6 \n" - "st1 {v16.d}[1], [%0], %6 \n" - "st1 {v18.d}[1], [%0], %6 \n" - "st1 {v17.d}[1], [%0], %6 \n" - "st1 {v19.d}[1], [%0] \n" + "st1 {v16.d}[0], [%0], %6 \n" + "st1 {v18.d}[0], [%0], %6 \n" + "st1 {v17.d}[0], [%0], %6 \n" + "st1 {v19.d}[0], [%0], %6 \n" + "st1 {v16.d}[1], [%0], %6 \n" + "st1 {v18.d}[1], [%0], %6 \n" + "st1 {v17.d}[1], [%0], %6 \n" + "st1 {v19.d}[1], [%0] \n" - "mov %0, %3 \n" + "mov %0, %3 \n" - "st1 {v20.d}[0], [%0], %7 \n" - "st1 {v22.d}[0], [%0], %7 \n" - "st1 {v21.d}[0], [%0], %7 \n" - "st1 {v23.d}[0], [%0], %7 \n" - "st1 {v20.d}[1], [%0], %7 \n" - "st1 {v22.d}[1], [%0], %7 \n" - "st1 {v21.d}[1], [%0], %7 \n" - "st1 {v23.d}[1], [%0] \n" + "st1 {v20.d}[0], [%0], %7 \n" + "st1 {v22.d}[0], [%0], %7 \n" + "st1 {v21.d}[0], [%0], %7 \n" + "st1 {v23.d}[0], [%0], %7 \n" + "st1 {v20.d}[1], [%0], %7 \n" + "st1 {v22.d}[1], [%0], %7 \n" + "st1 {v21.d}[1], [%0], %7 \n" + "st1 {v23.d}[1], [%0] \n" - "add %1, %1, #16 \n" // src += 8*2 - "add %2, %2, %6, lsl #3 \n" // dst_a += 8 * + "add %1, %1, #16 \n" // src += 8*2 + "add %2, %2, %6, lsl #3 \n" // dst_a += 8 * // dst_stride_a - "add %3, %3, %7, lsl #3 \n" // dst_b += 8 * + "add %3, %3, %7, lsl #3 \n" // dst_b += 8 * // dst_stride_b - "subs %w4, %w4, #8 \n" // w -= 8 - "b.ge 1b \n" + "subs %w4, %w4, #8 \n" // w -= 8 + "b.ge 1b \n" // add 8 back to counter. if the result is 0 there are // no residuals. - "adds %w4, %w4, #8 \n" - "b.eq 4f \n" + "adds %w4, %w4, #8 \n" + "b.eq 4f \n" // some residual, so between 1 and 7 lines left to transpose - "cmp %w4, #2 \n" - "b.lt 3f \n" + "cmp %w4, #2 \n" + "b.lt 3f \n" - "cmp %w4, #4 \n" - "b.lt 2f \n" + "cmp %w4, #4 \n" + "b.lt 2f \n" // TODO(frkoenig): Clean this up // 4x8 block diff --git a/TMessagesProj/jni/third_party/libyuv/source/row_any.cc b/TMessagesProj/jni/third_party/libyuv/source/row_any.cc index 9b29b2bfb..7216373bc 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/row_any.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/row_any.cc @@ -546,12 +546,6 @@ ANY11(J400ToARGBRow_Any_SSE2, J400ToARGBRow_SSE2, 0, 1, 4, 7) #if defined(HAS_J400TOARGBROW_AVX2) ANY11(J400ToARGBRow_Any_AVX2, J400ToARGBRow_AVX2, 0, 1, 4, 15) #endif -#if defined(HAS_I400TOARGBROW_SSE2) -ANY11(I400ToARGBRow_Any_SSE2, I400ToARGBRow_SSE2, 0, 1, 4, 7) -#endif -#if defined(HAS_I400TOARGBROW_AVX2) -ANY11(I400ToARGBRow_Any_AVX2, I400ToARGBRow_AVX2, 0, 1, 4, 15) -#endif #if defined(HAS_RGB24TOARGBROW_SSSE3) ANY11(RGB24ToARGBRow_Any_SSSE3, RGB24ToARGBRow_SSSE3, 0, 3, 4, 15) ANY11(RAWToARGBRow_Any_SSSE3, RAWToARGBRow_SSSE3, 0, 3, 4, 15) @@ -581,7 +575,6 @@ ANY11(ARGBToRGB565Row_Any_NEON, ARGBToRGB565Row_NEON, 0, 4, 2, 7) ANY11(ARGBToARGB1555Row_Any_NEON, ARGBToARGB1555Row_NEON, 0, 4, 2, 7) ANY11(ARGBToARGB4444Row_Any_NEON, ARGBToARGB4444Row_NEON, 0, 4, 2, 7) ANY11(J400ToARGBRow_Any_NEON, J400ToARGBRow_NEON, 0, 1, 4, 7) -ANY11(I400ToARGBRow_Any_NEON, I400ToARGBRow_NEON, 0, 1, 4, 7) #endif #if defined(HAS_ARGBTORGB24ROW_MSA) ANY11(ARGBToRGB24Row_Any_MSA, ARGBToRGB24Row_MSA, 0, 4, 3, 15) @@ -590,7 +583,6 @@ ANY11(ARGBToRGB565Row_Any_MSA, ARGBToRGB565Row_MSA, 0, 4, 2, 7) ANY11(ARGBToARGB1555Row_Any_MSA, ARGBToARGB1555Row_MSA, 0, 4, 2, 7) ANY11(ARGBToARGB4444Row_Any_MSA, ARGBToARGB4444Row_MSA, 0, 4, 2, 7) ANY11(J400ToARGBRow_Any_MSA, J400ToARGBRow_MSA, 0, 1, 4, 15) -ANY11(I400ToARGBRow_Any_MSA, I400ToARGBRow_MSA, 0, 1, 4, 15) #endif #if defined(HAS_ARGBTORGB24ROW_MMI) ANY11(ARGBToRGB24Row_Any_MMI, ARGBToRGB24Row_MMI, 0, 4, 3, 3) @@ -599,7 +591,6 @@ ANY11(ARGBToRGB565Row_Any_MMI, ARGBToRGB565Row_MMI, 0, 4, 2, 3) ANY11(ARGBToARGB1555Row_Any_MMI, ARGBToARGB1555Row_MMI, 0, 4, 2, 3) ANY11(ARGBToARGB4444Row_Any_MMI, ARGBToARGB4444Row_MMI, 0, 4, 2, 3) ANY11(J400ToARGBRow_Any_MMI, J400ToARGBRow_MMI, 0, 1, 4, 3) -ANY11(I400ToARGBRow_Any_MMI, I400ToARGBRow_MMI, 0, 1, 4, 7) #endif #if defined(HAS_RAWTORGB24ROW_NEON) ANY11(RAWToRGB24Row_Any_NEON, RAWToRGB24Row_NEON, 0, 3, 3, 7) @@ -695,6 +686,15 @@ ANY11(RGBAToYRow_Any_MMI, RGBAToYRow_MMI, 0, 4, 1, 7) #ifdef HAS_RGB24TOYROW_NEON ANY11(RGB24ToYRow_Any_NEON, RGB24ToYRow_NEON, 0, 3, 1, 7) #endif +#ifdef HAS_RGB24TOYJROW_AVX2 +ANY11(RGB24ToYJRow_Any_AVX2, RGB24ToYJRow_AVX2, 0, 3, 1, 31) +#endif +#ifdef HAS_RGB24TOYJROW_SSSE3 +ANY11(RGB24ToYJRow_Any_SSSE3, RGB24ToYJRow_SSSE3, 0, 3, 1, 15) +#endif +#ifdef HAS_RGB24TOYJROW_NEON +ANY11(RGB24ToYJRow_Any_NEON, RGB24ToYJRow_NEON, 0, 3, 1, 7) +#endif #ifdef HAS_RGB24TOYROW_MSA ANY11(RGB24ToYRow_Any_MSA, RGB24ToYRow_MSA, 0, 3, 1, 15) #endif @@ -704,6 +704,15 @@ ANY11(RGB24ToYRow_Any_MMI, RGB24ToYRow_MMI, 0, 3, 1, 7) #ifdef HAS_RAWTOYROW_NEON ANY11(RAWToYRow_Any_NEON, RAWToYRow_NEON, 0, 3, 1, 7) #endif +#ifdef HAS_RAWTOYJROW_AVX2 +ANY11(RAWToYJRow_Any_AVX2, RAWToYJRow_AVX2, 0, 3, 1, 31) +#endif +#ifdef HAS_RAWTOYJROW_SSSE3 +ANY11(RAWToYJRow_Any_SSSE3, RAWToYJRow_SSSE3, 0, 3, 1, 15) +#endif +#ifdef HAS_RAWTOYJROW_NEON +ANY11(RAWToYJRow_Any_NEON, RAWToYJRow_NEON, 0, 3, 1, 7) +#endif #ifdef HAS_RAWTOYROW_MSA ANY11(RAWToYRow_Any_MSA, RAWToYRow_MSA, 0, 3, 1, 15) #endif @@ -901,6 +910,47 @@ ANY11B(ARGBCopyYToAlphaRow_Any_MMI, ARGBCopyYToAlphaRow_MMI, 0, 1, 4, 7) memcpy(dst_ptr + n * BPP, temp + 64, r * BPP); \ } +#if defined(HAS_I400TOARGBROW_SSE2) +ANY11P(I400ToARGBRow_Any_SSE2, + I400ToARGBRow_SSE2, + const struct YuvConstants*, + 1, + 4, + 7) +#endif +#if defined(HAS_I400TOARGBROW_AVX2) +ANY11P(I400ToARGBRow_Any_AVX2, + I400ToARGBRow_AVX2, + const struct YuvConstants*, + 1, + 4, + 15) +#endif +#if defined(HAS_I400TOARGBROW_NEON) +ANY11P(I400ToARGBRow_Any_NEON, + I400ToARGBRow_NEON, + const struct YuvConstants*, + 1, + 4, + 7) +#endif +#if defined(HAS_I400TOARGBROW_MSA) +ANY11P(I400ToARGBRow_Any_MSA, + I400ToARGBRow_MSA, + const struct YuvConstants*, + 1, + 4, + 15) +#endif +#if defined(HAS_I400TOARGBROW_MMI) +ANY11P(I400ToARGBRow_Any_MMI, + I400ToARGBRow_MMI, + const struct YuvConstants*, + 1, + 4, + 7) +#endif + #if defined(HAS_ARGBTORGB565DITHERROW_SSE2) ANY11P(ARGBToRGB565DitherRow_Any_SSE2, ARGBToRGB565DitherRow_SSE2, @@ -1156,7 +1206,7 @@ ANY11M(MirrorRow_Any_AVX2, MirrorRow_AVX2, 1, 31) ANY11M(MirrorRow_Any_SSSE3, MirrorRow_SSSE3, 1, 15) #endif #ifdef HAS_MIRRORROW_NEON -ANY11M(MirrorRow_Any_NEON, MirrorRow_NEON, 1, 15) +ANY11M(MirrorRow_Any_NEON, MirrorRow_NEON, 1, 31) #endif #ifdef HAS_MIRRORROW_MSA ANY11M(MirrorRow_Any_MSA, MirrorRow_MSA, 1, 63) @@ -1164,6 +1214,18 @@ ANY11M(MirrorRow_Any_MSA, MirrorRow_MSA, 1, 63) #ifdef HAS_MIRRORROW_MMI ANY11M(MirrorRow_Any_MMI, MirrorRow_MMI, 1, 7) #endif +#ifdef HAS_MIRRORUVROW_AVX2 +ANY11M(MirrorUVRow_Any_AVX2, MirrorUVRow_AVX2, 2, 15) +#endif +#ifdef HAS_MIRRORUVROW_SSSE3 +ANY11M(MirrorUVRow_Any_SSSE3, MirrorUVRow_SSSE3, 2, 7) +#endif +#ifdef HAS_MIRRORUVROW_NEON +ANY11M(MirrorUVRow_Any_NEON, MirrorUVRow_NEON, 2, 31) +#endif +#ifdef HAS_MIRRORUVROW_MSA +ANY11M(MirrorUVRow_Any_MSA, MirrorUVRow_MSA, 2, 7) +#endif #ifdef HAS_ARGBMIRRORROW_AVX2 ANY11M(ARGBMirrorRow_Any_AVX2, ARGBMirrorRow_AVX2, 4, 7) #endif @@ -1171,7 +1233,7 @@ ANY11M(ARGBMirrorRow_Any_AVX2, ARGBMirrorRow_AVX2, 4, 7) ANY11M(ARGBMirrorRow_Any_SSE2, ARGBMirrorRow_SSE2, 4, 3) #endif #ifdef HAS_ARGBMIRRORROW_NEON -ANY11M(ARGBMirrorRow_Any_NEON, ARGBMirrorRow_NEON, 4, 3) +ANY11M(ARGBMirrorRow_Any_NEON, ARGBMirrorRow_NEON, 4, 7) #endif #ifdef HAS_ARGBMIRRORROW_MSA ANY11M(ARGBMirrorRow_Any_MSA, ARGBMirrorRow_MSA, 4, 15) @@ -1179,12 +1241,19 @@ ANY11M(ARGBMirrorRow_Any_MSA, ARGBMirrorRow_MSA, 4, 15) #ifdef HAS_ARGBMIRRORROW_MMI ANY11M(ARGBMirrorRow_Any_MMI, ARGBMirrorRow_MMI, 4, 1) #endif +#ifdef HAS_RGB24MIRRORROW_SSSE3 +ANY11M(RGB24MirrorRow_Any_SSSE3, RGB24MirrorRow_SSSE3, 3, 15) +#endif +#ifdef HAS_RGB24MIRRORROW_NEON +ANY11M(RGB24MirrorRow_Any_NEON, RGB24MirrorRow_NEON, 3, 15) +#endif #undef ANY11M // Any 1 plane. (memset) #define ANY1(NAMEANY, ANY_SIMD, T, BPP, MASK) \ void NAMEANY(uint8_t* dst_ptr, T v32, int width) { \ SIMD_ALIGNED(uint8_t temp[64]); \ + memset(temp, 0, 64); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1371,7 +1440,7 @@ ANY12S(ARGBToUVJRow_Any_MMI, ARGBToUVJRow_MMI, 0, 4, 15) ANY12S(BGRAToUVRow_Any_NEON, BGRAToUVRow_NEON, 0, 4, 15) #endif #ifdef HAS_BGRATOUVROW_MSA -ANY12S(BGRAToUVRow_Any_MSA, BGRAToUVRow_MSA, 0, 4, 31) +ANY12S(BGRAToUVRow_Any_MSA, BGRAToUVRow_MSA, 0, 4, 15) #endif #ifdef HAS_BGRATOUVROW_MMI ANY12S(BGRAToUVRow_Any_MMI, BGRAToUVRow_MMI, 0, 4, 15) @@ -1380,7 +1449,7 @@ ANY12S(BGRAToUVRow_Any_MMI, BGRAToUVRow_MMI, 0, 4, 15) ANY12S(ABGRToUVRow_Any_NEON, ABGRToUVRow_NEON, 0, 4, 15) #endif #ifdef HAS_ABGRTOUVROW_MSA -ANY12S(ABGRToUVRow_Any_MSA, ABGRToUVRow_MSA, 0, 4, 31) +ANY12S(ABGRToUVRow_Any_MSA, ABGRToUVRow_MSA, 0, 4, 15) #endif #ifdef HAS_ABGRTOUVROW_MMI ANY12S(ABGRToUVRow_Any_MMI, ABGRToUVRow_MMI, 0, 4, 15) @@ -1389,7 +1458,7 @@ ANY12S(ABGRToUVRow_Any_MMI, ABGRToUVRow_MMI, 0, 4, 15) ANY12S(RGBAToUVRow_Any_NEON, RGBAToUVRow_NEON, 0, 4, 15) #endif #ifdef HAS_RGBATOUVROW_MSA -ANY12S(RGBAToUVRow_Any_MSA, RGBAToUVRow_MSA, 0, 4, 31) +ANY12S(RGBAToUVRow_Any_MSA, RGBAToUVRow_MSA, 0, 4, 15) #endif #ifdef HAS_RGBATOUVROW_MMI ANY12S(RGBAToUVRow_Any_MMI, RGBAToUVRow_MMI, 0, 4, 15) diff --git a/TMessagesProj/jni/third_party/libyuv/source/row_common.cc b/TMessagesProj/jni/third_party/libyuv/source/row_common.cc index 70aa2e13c..79aed5c78 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/row_common.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/row_common.cc @@ -14,6 +14,7 @@ #include // For memcpy and memset. #include "libyuv/basic_types.h" +#include "libyuv/convert_argb.h" // For kYuvI601Constants #ifdef __cplusplus namespace libyuv { @@ -26,10 +27,11 @@ extern "C" { (defined(_M_IX86) || (defined(_M_X64) && !defined(__clang__))) #define LIBYUV_RGB7 1 #endif -// mips use 7 bit RGBToY -#if (!defined(LIBYUV_DISABLE_MMI) && defined(_MIPS_ARCH_LOONGSON3A)) || \ - (!defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)) -#define LIBYUV_RGB7 1 + +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ + defined(_M_IX86) +#define LIBYUV_ARGBTOUV_PAVGB 1 +#define LIBYUV_RGBTOU_TRUNCATE 1 #endif // llvm x86 is poor at ternary operator, so use branchless min/max. @@ -37,19 +39,19 @@ extern "C" { #define USE_BRANCHLESS 1 #if USE_BRANCHLESS static __inline int32_t clamp0(int32_t v) { - return ((-(v) >> 31) & (v)); + return -(v >= 0) & v; } - +// TODO(fbarchard): make clamp255 preserve negative values. static __inline int32_t clamp255(int32_t v) { - return (((255 - (v)) >> 31) | (v)) & 255; + return (-(v >= 255) | v) & 255; } static __inline int32_t clamp1023(int32_t v) { - return (((1023 - (v)) >> 31) | (v)) & 1023; + return (-(v >= 1023) | v) & 1023; } static __inline uint32_t Abs(int32_t v) { - int m = v >> 31; + int m = -(v < 0); return (v + m) ^ m; } #else // USE_BRANCHLESS @@ -208,7 +210,8 @@ void ARGB4444ToARGBRow_C(const uint8_t* src_argb4444, void AR30ToARGBRow_C(const uint8_t* src_ar30, uint8_t* dst_argb, int width) { int x; for (x = 0; x < width; ++x) { - uint32_t ar30 = *(const uint32_t*)src_ar30; + uint32_t ar30; + memcpy(&ar30, src_ar30, sizeof ar30); uint32_t b = (ar30 >> 2) & 0xff; uint32_t g = (ar30 >> 12) & 0xff; uint32_t r = (ar30 >> 22) & 0xff; @@ -222,7 +225,8 @@ void AR30ToARGBRow_C(const uint8_t* src_ar30, uint8_t* dst_argb, int width) { void AR30ToABGRRow_C(const uint8_t* src_ar30, uint8_t* dst_abgr, int width) { int x; for (x = 0; x < width; ++x) { - uint32_t ar30 = *(const uint32_t*)src_ar30; + uint32_t ar30; + memcpy(&ar30, src_ar30, sizeof ar30); uint32_t b = (ar30 >> 2) & 0xff; uint32_t g = (ar30 >> 12) & 0xff; uint32_t r = (ar30 >> 22) & 0xff; @@ -236,7 +240,8 @@ void AR30ToABGRRow_C(const uint8_t* src_ar30, uint8_t* dst_abgr, int width) { void AR30ToAB30Row_C(const uint8_t* src_ar30, uint8_t* dst_ab30, int width) { int x; for (x = 0; x < width; ++x) { - uint32_t ar30 = *(const uint32_t*)src_ar30; + uint32_t ar30; + memcpy(&ar30, src_ar30, sizeof ar30); uint32_t b = ar30 & 0x3ff; uint32_t ga = ar30 & 0xc00ffc00; uint32_t r = (ar30 >> 20) & 0x3ff; @@ -425,14 +430,38 @@ static __inline int RGBToY(uint8_t r, uint8_t g, uint8_t b) { } #endif +#define AVGB(a, b) (((a) + (b) + 1) >> 1) + +#ifdef LIBYUV_RGBTOU_TRUNCATE +static __inline int RGBToU(uint8_t r, uint8_t g, uint8_t b) { + return (112 * b - 74 * g - 38 * r + 0x8000) >> 8; +} +static __inline int RGBToV(uint8_t r, uint8_t g, uint8_t b) { + return (112 * r - 94 * g - 18 * b + 0x8000) >> 8; +} +#else +// TODO(fbarchard): Add rounding to SIMD and use this static __inline int RGBToU(uint8_t r, uint8_t g, uint8_t b) { return (112 * b - 74 * g - 38 * r + 0x8080) >> 8; } static __inline int RGBToV(uint8_t r, uint8_t g, uint8_t b) { return (112 * r - 94 * g - 18 * b + 0x8080) >> 8; } +#endif + +#if !defined(LIBYUV_ARGBTOUV_PAVGB) +static __inline int RGB2xToU(uint16_t r, uint16_t g, uint16_t b) { + return ((112 / 2) * b - (74 / 2) * g - (38 / 2) * r + 0x8080) >> 8; +} +static __inline int RGB2xToV(uint16_t r, uint16_t g, uint16_t b) { + return ((112 / 2) * r - (94 / 2) * g - (18 / 2) * b + 0x8080) >> 8; +} +#endif // ARGBToY_C and ARGBToUV_C +// Intel version mimic SSE/AVX which does 2 pavgb +#if LIBYUV_ARGBTOUV_PAVGB + #define MAKEROWY(NAME, R, G, B, BPP) \ void NAME##ToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \ int x; \ @@ -447,15 +476,12 @@ static __inline int RGBToV(uint8_t r, uint8_t g, uint8_t b) { const uint8_t* src_rgb1 = src_rgb0 + src_stride_rgb; \ int x; \ for (x = 0; x < width - 1; x += 2) { \ - uint8_t ab = (src_rgb0[B] + src_rgb0[B + BPP] + src_rgb1[B] + \ - src_rgb1[B + BPP]) >> \ - 2; \ - uint8_t ag = (src_rgb0[G] + src_rgb0[G + BPP] + src_rgb1[G] + \ - src_rgb1[G + BPP]) >> \ - 2; \ - uint8_t ar = (src_rgb0[R] + src_rgb0[R + BPP] + src_rgb1[R] + \ - src_rgb1[R + BPP]) >> \ - 2; \ + uint8_t ab = AVGB(AVGB(src_rgb0[B], src_rgb1[B]), \ + AVGB(src_rgb0[B + BPP], src_rgb1[B + BPP])); \ + uint8_t ag = AVGB(AVGB(src_rgb0[G], src_rgb1[G]), \ + AVGB(src_rgb0[G + BPP], src_rgb1[G + BPP])); \ + uint8_t ar = AVGB(AVGB(src_rgb0[R], src_rgb1[R]), \ + AVGB(src_rgb0[R + BPP], src_rgb1[R + BPP])); \ dst_u[0] = RGBToU(ar, ag, ab); \ dst_v[0] = RGBToV(ar, ag, ab); \ src_rgb0 += BPP * 2; \ @@ -464,13 +490,54 @@ static __inline int RGBToV(uint8_t r, uint8_t g, uint8_t b) { dst_v += 1; \ } \ if (width & 1) { \ - uint8_t ab = (src_rgb0[B] + src_rgb1[B]) >> 1; \ - uint8_t ag = (src_rgb0[G] + src_rgb1[G]) >> 1; \ - uint8_t ar = (src_rgb0[R] + src_rgb1[R]) >> 1; \ + uint8_t ab = AVGB(src_rgb0[B], src_rgb1[B]); \ + uint8_t ag = AVGB(src_rgb0[G], src_rgb1[G]); \ + uint8_t ar = AVGB(src_rgb0[R], src_rgb1[R]); \ dst_u[0] = RGBToU(ar, ag, ab); \ dst_v[0] = RGBToV(ar, ag, ab); \ } \ } +#else +// ARM version does sum / 2 then multiply by 2x smaller coefficients +#define MAKEROWY(NAME, R, G, B, BPP) \ + void NAME##ToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \ + int x; \ + for (x = 0; x < width; ++x) { \ + dst_y[0] = RGBToY(src_argb0[R], src_argb0[G], src_argb0[B]); \ + src_argb0 += BPP; \ + dst_y += 1; \ + } \ + } \ + void NAME##ToUVRow_C(const uint8_t* src_rgb0, int src_stride_rgb, \ + uint8_t* dst_u, uint8_t* dst_v, int width) { \ + const uint8_t* src_rgb1 = src_rgb0 + src_stride_rgb; \ + int x; \ + for (x = 0; x < width - 1; x += 2) { \ + uint16_t ab = (src_rgb0[B] + src_rgb0[B + BPP] + src_rgb1[B] + \ + src_rgb1[B + BPP] + 1) >> \ + 1; \ + uint16_t ag = (src_rgb0[G] + src_rgb0[G + BPP] + src_rgb1[G] + \ + src_rgb1[G + BPP] + 1) >> \ + 1; \ + uint16_t ar = (src_rgb0[R] + src_rgb0[R + BPP] + src_rgb1[R] + \ + src_rgb1[R + BPP] + 1) >> \ + 1; \ + dst_u[0] = RGB2xToU(ar, ag, ab); \ + dst_v[0] = RGB2xToV(ar, ag, ab); \ + src_rgb0 += BPP * 2; \ + src_rgb1 += BPP * 2; \ + dst_u += 1; \ + dst_v += 1; \ + } \ + if (width & 1) { \ + uint16_t ab = src_rgb0[B] + src_rgb1[B]; \ + uint16_t ag = src_rgb0[G] + src_rgb1[G]; \ + uint16_t ar = src_rgb0[R] + src_rgb1[R]; \ + dst_u[0] = RGB2xToU(ar, ag, ab); \ + dst_v[0] = RGB2xToV(ar, ag, ab); \ + } \ + } +#endif MAKEROWY(ARGB, 2, 1, 0, 4) MAKEROWY(BGRA, 1, 2, 3, 4) @@ -517,16 +584,25 @@ static __inline int RGBToYJ(uint8_t r, uint8_t g, uint8_t b) { } #endif +#if defined(LIBYUV_ARGBTOUV_PAVGB) static __inline int RGBToUJ(uint8_t r, uint8_t g, uint8_t b) { return (127 * b - 84 * g - 43 * r + 0x8080) >> 8; } static __inline int RGBToVJ(uint8_t r, uint8_t g, uint8_t b) { return (127 * r - 107 * g - 20 * b + 0x8080) >> 8; } - -#define AVGB(a, b) (((a) + (b) + 1) >> 1) +#else +static __inline int RGB2xToUJ(uint16_t r, uint16_t g, uint16_t b) { + return ((127 / 2) * b - (84 / 2) * g - (43 / 2) * r + 0x8080) >> 8; +} +static __inline int RGB2xToVJ(uint16_t r, uint16_t g, uint16_t b) { + return ((127 / 2) * r - (107 / 2) * g - (20 / 2) * b + 0x8080) >> 8; +} +#endif // ARGBToYJ_C and ARGBToUVJ_C +// Intel version mimic SSE/AVX which does 2 pavgb +#if LIBYUV_ARGBTOUV_PAVGB #define MAKEROWYJ(NAME, R, G, B, BPP) \ void NAME##ToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \ int x; \ @@ -562,9 +638,53 @@ static __inline int RGBToVJ(uint8_t r, uint8_t g, uint8_t b) { dst_v[0] = RGBToVJ(ar, ag, ab); \ } \ } +#else +// ARM version does sum / 2 then multiply by 2x smaller coefficients +#define MAKEROWYJ(NAME, R, G, B, BPP) \ + void NAME##ToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \ + int x; \ + for (x = 0; x < width; ++x) { \ + dst_y[0] = RGBToYJ(src_argb0[R], src_argb0[G], src_argb0[B]); \ + src_argb0 += BPP; \ + dst_y += 1; \ + } \ + } \ + void NAME##ToUVJRow_C(const uint8_t* src_rgb0, int src_stride_rgb, \ + uint8_t* dst_u, uint8_t* dst_v, int width) { \ + const uint8_t* src_rgb1 = src_rgb0 + src_stride_rgb; \ + int x; \ + for (x = 0; x < width - 1; x += 2) { \ + uint16_t ab = (src_rgb0[B] + src_rgb0[B + BPP] + src_rgb1[B] + \ + src_rgb1[B + BPP] + 1) >> \ + 1; \ + uint16_t ag = (src_rgb0[G] + src_rgb0[G + BPP] + src_rgb1[G] + \ + src_rgb1[G + BPP] + 1) >> \ + 1; \ + uint16_t ar = (src_rgb0[R] + src_rgb0[R + BPP] + src_rgb1[R] + \ + src_rgb1[R + BPP] + 1) >> \ + 1; \ + dst_u[0] = RGB2xToUJ(ar, ag, ab); \ + dst_v[0] = RGB2xToVJ(ar, ag, ab); \ + src_rgb0 += BPP * 2; \ + src_rgb1 += BPP * 2; \ + dst_u += 1; \ + dst_v += 1; \ + } \ + if (width & 1) { \ + uint16_t ab = (src_rgb0[B] + src_rgb1[B]); \ + uint16_t ag = (src_rgb0[G] + src_rgb1[G]); \ + uint16_t ar = (src_rgb0[R] + src_rgb1[R]); \ + dst_u[0] = RGB2xToUJ(ar, ag, ab); \ + dst_v[0] = RGB2xToVJ(ar, ag, ab); \ + } \ + } + +#endif MAKEROWYJ(ARGB, 2, 1, 0, 4) MAKEROWYJ(RGBA, 3, 2, 1, 4) +MAKEROWYJ(RGB24, 2, 1, 0, 3) +MAKEROWYJ(RAW, 0, 1, 2, 3) #undef MAKEROWYJ void RGB565ToYRow_C(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { @@ -632,13 +752,34 @@ void RGB565ToUVRow_C(const uint8_t* src_rgb565, uint8_t b3 = next_rgb565[2] & 0x1f; uint8_t g3 = (next_rgb565[2] >> 5) | ((next_rgb565[3] & 0x07) << 3); uint8_t r3 = next_rgb565[3] >> 3; - uint8_t b = (b0 + b1 + b2 + b3); // 565 * 4 = 787. - uint8_t g = (g0 + g1 + g2 + g3); - uint8_t r = (r0 + r1 + r2 + r3); - b = (b << 1) | (b >> 6); // 787 -> 888. - r = (r << 1) | (r >> 6); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); + + b0 = (b0 << 3) | (b0 >> 2); + g0 = (g0 << 2) | (g0 >> 4); + r0 = (r0 << 3) | (r0 >> 2); + b1 = (b1 << 3) | (b1 >> 2); + g1 = (g1 << 2) | (g1 >> 4); + r1 = (r1 << 3) | (r1 >> 2); + b2 = (b2 << 3) | (b2 >> 2); + g2 = (g2 << 2) | (g2 >> 4); + r2 = (r2 << 3) | (r2 >> 2); + b3 = (b3 << 3) | (b3 >> 2); + g3 = (g3 << 2) | (g3 >> 4); + r3 = (r3 << 3) | (r3 >> 2); + +#if LIBYUV_ARGBTOUV_PAVGB + uint8_t ab = AVGB(AVGB(b0, b2), AVGB(b1, b3)); + uint8_t ag = AVGB(AVGB(g0, g2), AVGB(g1, g3)); + uint8_t ar = AVGB(AVGB(r0, r2), AVGB(r1, r3)); + dst_u[0] = RGBToU(ar, ag, ab); + dst_v[0] = RGBToV(ar, ag, ab); +#else + uint16_t b = (b0 + b1 + b2 + b3 + 1) >> 1; + uint16_t g = (g0 + g1 + g2 + g3 + 1) >> 1; + uint16_t r = (r0 + r1 + r2 + r3 + 1) >> 1; + dst_u[0] = RGB2xToU(r, g, b); + dst_v[0] = RGB2xToV(r, g, b); +#endif + src_rgb565 += 4; next_rgb565 += 4; dst_u += 1; @@ -651,14 +792,27 @@ void RGB565ToUVRow_C(const uint8_t* src_rgb565, uint8_t b2 = next_rgb565[0] & 0x1f; uint8_t g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3); uint8_t r2 = next_rgb565[1] >> 3; - uint8_t b = (b0 + b2); // 565 * 2 = 676. - uint8_t g = (g0 + g2); - uint8_t r = (r0 + r2); - b = (b << 2) | (b >> 4); // 676 -> 888 - g = (g << 1) | (g >> 6); - r = (r << 2) | (r >> 4); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); + + b0 = (b0 << 3) | (b0 >> 2); + g0 = (g0 << 2) | (g0 >> 4); + r0 = (r0 << 3) | (r0 >> 2); + b2 = (b2 << 3) | (b2 >> 2); + g2 = (g2 << 2) | (g2 >> 4); + r2 = (r2 << 3) | (r2 >> 2); + +#if LIBYUV_ARGBTOUV_PAVGB + uint8_t ab = AVGB(b0, b2); + uint8_t ag = AVGB(g0, g2); + uint8_t ar = AVGB(r0, r2); + dst_u[0] = RGBToU(ar, ag, ab); + dst_v[0] = RGBToV(ar, ag, ab); +#else + uint16_t b = b0 + b2; + uint16_t g = g0 + g2; + uint16_t r = r0 + r2; + dst_u[0] = RGB2xToU(r, g, b); + dst_v[0] = RGB2xToV(r, g, b); +#endif } } @@ -682,14 +836,34 @@ void ARGB1555ToUVRow_C(const uint8_t* src_argb1555, uint8_t b3 = next_argb1555[2] & 0x1f; uint8_t g3 = (next_argb1555[2] >> 5) | ((next_argb1555[3] & 0x03) << 3); uint8_t r3 = (next_argb1555[3] & 0x7c) >> 2; - uint8_t b = (b0 + b1 + b2 + b3); // 555 * 4 = 777. - uint8_t g = (g0 + g1 + g2 + g3); - uint8_t r = (r0 + r1 + r2 + r3); - b = (b << 1) | (b >> 6); // 777 -> 888. - g = (g << 1) | (g >> 6); - r = (r << 1) | (r >> 6); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); + + b0 = (b0 << 3) | (b0 >> 2); + g0 = (g0 << 3) | (g0 >> 2); + r0 = (r0 << 3) | (r0 >> 2); + b1 = (b1 << 3) | (b1 >> 2); + g1 = (g1 << 3) | (g1 >> 2); + r1 = (r1 << 3) | (r1 >> 2); + b2 = (b2 << 3) | (b2 >> 2); + g2 = (g2 << 3) | (g2 >> 2); + r2 = (r2 << 3) | (r2 >> 2); + b3 = (b3 << 3) | (b3 >> 2); + g3 = (g3 << 3) | (g3 >> 2); + r3 = (r3 << 3) | (r3 >> 2); + +#if LIBYUV_ARGBTOUV_PAVGB + uint8_t ab = AVGB(AVGB(b0, b2), AVGB(b1, b3)); + uint8_t ag = AVGB(AVGB(g0, g2), AVGB(g1, g3)); + uint8_t ar = AVGB(AVGB(r0, r2), AVGB(r1, r3)); + dst_u[0] = RGBToU(ar, ag, ab); + dst_v[0] = RGBToV(ar, ag, ab); +#else + uint16_t b = (b0 + b1 + b2 + b3 + 1) >> 1; + uint16_t g = (g0 + g1 + g2 + g3 + 1) >> 1; + uint16_t r = (r0 + r1 + r2 + r3 + 1) >> 1; + dst_u[0] = RGB2xToU(r, g, b); + dst_v[0] = RGB2xToV(r, g, b); +#endif + src_argb1555 += 4; next_argb1555 += 4; dst_u += 1; @@ -702,14 +876,27 @@ void ARGB1555ToUVRow_C(const uint8_t* src_argb1555, uint8_t b2 = next_argb1555[0] & 0x1f; uint8_t g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3); uint8_t r2 = next_argb1555[1] >> 3; - uint8_t b = (b0 + b2); // 555 * 2 = 666. - uint8_t g = (g0 + g2); - uint8_t r = (r0 + r2); - b = (b << 2) | (b >> 4); // 666 -> 888. - g = (g << 2) | (g >> 4); - r = (r << 2) | (r >> 4); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); + + b0 = (b0 << 3) | (b0 >> 2); + g0 = (g0 << 3) | (g0 >> 2); + r0 = (r0 << 3) | (r0 >> 2); + b2 = (b2 << 3) | (b2 >> 2); + g2 = (g2 << 3) | (g2 >> 2); + r2 = (r2 << 3) | (r2 >> 2); + +#if LIBYUV_ARGBTOUV_PAVGB + uint8_t ab = AVGB(b0, b2); + uint8_t ag = AVGB(g0, g2); + uint8_t ar = AVGB(r0, r2); + dst_u[0] = RGBToU(ar, ag, ab); + dst_v[0] = RGBToV(ar, ag, ab); +#else + uint16_t b = b0 + b2; + uint16_t g = g0 + g2; + uint16_t r = r0 + r2; + dst_u[0] = RGB2xToU(r, g, b); + dst_v[0] = RGB2xToV(r, g, b); +#endif } } @@ -733,14 +920,34 @@ void ARGB4444ToUVRow_C(const uint8_t* src_argb4444, uint8_t b3 = next_argb4444[2] & 0x0f; uint8_t g3 = next_argb4444[2] >> 4; uint8_t r3 = next_argb4444[3] & 0x0f; - uint8_t b = (b0 + b1 + b2 + b3); // 444 * 4 = 666. - uint8_t g = (g0 + g1 + g2 + g3); - uint8_t r = (r0 + r1 + r2 + r3); - b = (b << 2) | (b >> 4); // 666 -> 888. - g = (g << 2) | (g >> 4); - r = (r << 2) | (r >> 4); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); + + b0 = (b0 << 4) | b0; + g0 = (g0 << 4) | g0; + r0 = (r0 << 4) | r0; + b1 = (b1 << 4) | b1; + g1 = (g1 << 4) | g1; + r1 = (r1 << 4) | r1; + b2 = (b2 << 4) | b2; + g2 = (g2 << 4) | g2; + r2 = (r2 << 4) | r2; + b3 = (b3 << 4) | b3; + g3 = (g3 << 4) | g3; + r3 = (r3 << 4) | r3; + +#if LIBYUV_ARGBTOUV_PAVGB + uint8_t ab = AVGB(AVGB(b0, b2), AVGB(b1, b3)); + uint8_t ag = AVGB(AVGB(g0, g2), AVGB(g1, g3)); + uint8_t ar = AVGB(AVGB(r0, r2), AVGB(r1, r3)); + dst_u[0] = RGBToU(ar, ag, ab); + dst_v[0] = RGBToV(ar, ag, ab); +#else + uint16_t b = (b0 + b1 + b2 + b3 + 1) >> 1; + uint16_t g = (g0 + g1 + g2 + g3 + 1) >> 1; + uint16_t r = (r0 + r1 + r2 + r3 + 1) >> 1; + dst_u[0] = RGB2xToU(r, g, b); + dst_v[0] = RGB2xToV(r, g, b); +#endif + src_argb4444 += 4; next_argb4444 += 4; dst_u += 1; @@ -753,14 +960,27 @@ void ARGB4444ToUVRow_C(const uint8_t* src_argb4444, uint8_t b2 = next_argb4444[0] & 0x0f; uint8_t g2 = next_argb4444[0] >> 4; uint8_t r2 = next_argb4444[1] & 0x0f; - uint8_t b = (b0 + b2); // 444 * 2 = 555. - uint8_t g = (g0 + g2); - uint8_t r = (r0 + r2); - b = (b << 3) | (b >> 2); // 555 -> 888. - g = (g << 3) | (g >> 2); - r = (r << 3) | (r >> 2); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); + + b0 = (b0 << 4) | b0; + g0 = (g0 << 4) | g0; + r0 = (r0 << 4) | r0; + b2 = (b2 << 4) | b2; + g2 = (g2 << 4) | g2; + r2 = (r2 << 4) | r2; + +#if LIBYUV_ARGBTOUV_PAVGB + uint8_t ab = AVGB(b0, b2); + uint8_t ag = AVGB(g0, g2); + uint8_t ar = AVGB(r0, r2); + dst_u[0] = RGBToU(ar, ag, ab); + dst_v[0] = RGBToV(ar, ag, ab); +#else + uint16_t b = b0 + b2; + uint16_t g = g0 + g2; + uint16_t r = r0 + r2; + dst_u[0] = RGB2xToU(r, g, b); + dst_v[0] = RGB2xToV(r, g, b); +#endif } } @@ -1136,26 +1356,26 @@ const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, {UG, VG, UG, VG, UG, VG, UG, VG}, {UG, VG, UG, VG, UG, VG, UG, VG}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BB, BG, BR, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, {VG, UG, VG, UG, VG, UG, VG, UG}, {VG, UG, VG, UG, VG, UG, VG, UG}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BR, BG, BB, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; #elif defined(__arm__) // 32 bit arm const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { {-UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0}, {UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BB, BG, BR, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { {-VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0}, {VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BR, BG, BB, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; #else const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { {UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, @@ -1167,7 +1387,9 @@ const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; + {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}, + {YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, + YGB}}; const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { {VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0}, @@ -1178,7 +1400,9 @@ const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; + {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}, + {YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, + YGB}}; #endif #undef BB @@ -1217,26 +1441,26 @@ const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, {UG, VG, UG, VG, UG, VG, UG, VG}, {UG, VG, UG, VG, UG, VG, UG, VG}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BB, BG, BR, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, {VG, UG, VG, UG, VG, UG, VG, UG}, {VG, UG, VG, UG, VG, UG, VG, UG}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BR, BG, BB, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; #elif defined(__arm__) const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { {-UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0}, {UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BB, BG, BR, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { {-VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0}, {VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BR, BG, BB, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; #else const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { {UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, @@ -1248,7 +1472,9 @@ const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; + {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}, + {YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, + YGB}}; const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { {VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0}, @@ -1259,7 +1485,9 @@ const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; + {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}, + {YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, + YGB}}; #endif #undef BB @@ -1300,26 +1528,26 @@ const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, {UG, VG, UG, VG, UG, VG, UG, VG}, {UG, VG, UG, VG, UG, VG, UG, VG}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BB, BG, BR, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, {VG, UG, VG, UG, VG, UG, VG, UG}, {VG, UG, VG, UG, VG, UG, VG, UG}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BR, BG, BB, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; #elif defined(__arm__) const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { {-UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0}, {UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BB, BG, BR, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { {-VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0}, {VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BR, BG, BB, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; #else const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { {UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, @@ -1331,7 +1559,9 @@ const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; + {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}, + {YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, + YGB}}; const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { {VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0}, @@ -1342,7 +1572,9 @@ const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; + {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}, + {YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, + YGB}}; #endif #undef BB @@ -1357,7 +1589,7 @@ const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { // BT.2020 YUV to RGB reference // R = (Y - 16) * 1.164384 - V * -1.67867 -// G = (Y - 16) * 1.164384 - U * 0.187326 - V * -0.65042 +// G = (Y - 16) * 1.164384 - U * 0.187326 - V * 0.65042 // B = (Y - 16) * 1.164384 - U * -2.14177 // Y contribution to R,G,B. Scale and bias. @@ -1365,6 +1597,7 @@ const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { #define YGB -1160 /* 1.164384 * 64 * -16 + 64 / 2 */ // TODO(fbarchard): Improve accuracy; the B channel is off by 7%. +// U and V contributions to R,G,B. #define UB -128 /* max(-128, round(-2.142 * 64)) */ #define UG 12 /* round(0.187326 * 64) */ #define VG 42 /* round(0.65042 * 64) */ @@ -1381,26 +1614,26 @@ const struct YuvConstants SIMD_ALIGNED(kYuv2020Constants) = { {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, {UG, VG, UG, VG, UG, VG, UG, VG}, {UG, VG, UG, VG, UG, VG, UG, VG}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BB, BG, BR, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; const struct YuvConstants SIMD_ALIGNED(kYvu2020Constants) = { {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, {VG, UG, VG, UG, VG, UG, VG, UG}, {VG, UG, VG, UG, VG, UG, VG, UG}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BR, BG, BB, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; #elif defined(__arm__) const struct YuvConstants SIMD_ALIGNED(kYuv2020Constants) = { {-UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0}, {UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BB, BG, BR, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; const struct YuvConstants SIMD_ALIGNED(kYvu2020Constants) = { {-VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0}, {VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; + {BR, BG, BB, YGB, 0, 0, 0, 0}, + {0x0101 * YG, YG, 0, 0}}; #else const struct YuvConstants SIMD_ALIGNED(kYuv2020Constants) = { {UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, @@ -1412,7 +1645,9 @@ const struct YuvConstants SIMD_ALIGNED(kYuv2020Constants) = { {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; + {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}, + {YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, + YGB}}; const struct YuvConstants SIMD_ALIGNED(kYvu2020Constants) = { {VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0}, @@ -1423,7 +1658,9 @@ const struct YuvConstants SIMD_ALIGNED(kYvu2020Constants) = { {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; + {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}, + {YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, YGB, + YGB}}; #endif #undef BB @@ -1438,7 +1675,6 @@ const struct YuvConstants SIMD_ALIGNED(kYvu2020Constants) = { // C reference code that mimics the YUV assembly. // Reads 8 bit YUV and leaves result as 16 bit. - static __inline void YuvPixel(uint8_t y, uint8_t u, uint8_t v, @@ -1454,7 +1690,7 @@ static __inline void YuvPixel(uint8_t y, int bb = yuvconstants->kUVBiasBGR[0]; int bg = yuvconstants->kUVBiasBGR[1]; int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; + int yg = yuvconstants->kYToRgb[1]; #elif defined(__arm__) int ub = -yuvconstants->kUVToRB[0]; int ug = yuvconstants->kUVToG[0]; @@ -1463,7 +1699,7 @@ static __inline void YuvPixel(uint8_t y, int bb = yuvconstants->kUVBiasBGR[0]; int bg = yuvconstants->kUVBiasBGR[1]; int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; + int yg = yuvconstants->kYToRgb[1]; #else int ub = yuvconstants->kUVToB[0]; int ug = yuvconstants->kUVToG[0]; @@ -1497,7 +1733,7 @@ static __inline void YuvPixel8_16(uint8_t y, int bb = yuvconstants->kUVBiasBGR[0]; int bg = yuvconstants->kUVBiasBGR[1]; int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; + int yg = yuvconstants->kYToRgb[1]; #elif defined(__arm__) int ub = -yuvconstants->kUVToRB[0]; int ug = yuvconstants->kUVToG[0]; @@ -1506,7 +1742,7 @@ static __inline void YuvPixel8_16(uint8_t y, int bb = yuvconstants->kUVBiasBGR[0]; int bg = yuvconstants->kUVBiasBGR[1]; int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; + int yg = yuvconstants->kYToRgb[1]; #else int ub = yuvconstants->kUVToB[0]; int ug = yuvconstants->kUVToG[0]; @@ -1541,7 +1777,7 @@ static __inline void YuvPixel16(int16_t y, int bb = yuvconstants->kUVBiasBGR[0]; int bg = yuvconstants->kUVBiasBGR[1]; int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; + int yg = yuvconstants->kYToRgb[1]; #elif defined(__arm__) int ub = -yuvconstants->kUVToRB[0]; int ug = yuvconstants->kUVToG[0]; @@ -1550,7 +1786,7 @@ static __inline void YuvPixel16(int16_t y, int bb = yuvconstants->kUVBiasBGR[0]; int bg = yuvconstants->kUVBiasBGR[1]; int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; + int yg = yuvconstants->kYToRgb[1]; #else int ub = yuvconstants->kUVToB[0]; int ug = yuvconstants->kUVToG[0]; @@ -1588,21 +1824,26 @@ static __inline void YuvPixel10(uint16_t y, *r = Clamp(r16 >> 6); } -// Y contribution to R,G,B. Scale and bias. -#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */ -#define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */ - // C reference code that mimics the YUV assembly. -static __inline void YPixel(uint8_t y, uint8_t* b, uint8_t* g, uint8_t* r) { - uint32_t y1 = (uint32_t)(y * 0x0101 * YG) >> 16; - *b = Clamp((int32_t)(y1 + YGB) >> 6); - *g = Clamp((int32_t)(y1 + YGB) >> 6); - *r = Clamp((int32_t)(y1 + YGB) >> 6); +// Reads 8 bit YUV and leaves result as 16 bit. +static __inline void YPixel(uint8_t y, + uint8_t* b, + uint8_t* g, + uint8_t* r, + const struct YuvConstants* yuvconstants) { +#if defined(__aarch64__) || defined(__arm__) + int ygb = yuvconstants->kUVBiasBGR[3]; + int yg = yuvconstants->kYToRgb[1]; +#else + int ygb = yuvconstants->kYBiasToRgb[0]; + int yg = yuvconstants->kYToRgb[0]; +#endif + uint32_t y1 = (uint32_t)(y * 0x0101 * yg) >> 16; + *b = Clamp(((int32_t)(y1) + ygb) >> 6); + *g = Clamp(((int32_t)(y1) + ygb) >> 6); + *r = Clamp(((int32_t)(y1) + ygb) >> 6); } -#undef YG -#undef YGB - #if !defined(LIBYUV_DISABLE_NEON) && \ (defined(__ARM_NEON__) || defined(__aarch64__) || defined(LIBYUV_NEON)) // C mimic assembly. @@ -2136,18 +2377,21 @@ void I422ToRGBARow_C(const uint8_t* src_y, } } -void I400ToARGBRow_C(const uint8_t* src_y, uint8_t* rgb_buf, int width) { +void I400ToARGBRow_C(const uint8_t* src_y, + uint8_t* rgb_buf, + const struct YuvConstants* yuvconstants, + int width) { int x; for (x = 0; x < width - 1; x += 2) { - YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); + YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants); rgb_buf[3] = 255; - YPixel(src_y[1], rgb_buf + 4, rgb_buf + 5, rgb_buf + 6); + YPixel(src_y[1], rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, yuvconstants); rgb_buf[7] = 255; src_y += 2; rgb_buf += 8; // Advance 2 pixels. } if (width & 1) { - YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); + YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, yuvconstants); rgb_buf[3] = 255; } } @@ -2165,10 +2409,21 @@ void MirrorRow_C(const uint8_t* src, uint8_t* dst, int width) { } } -void MirrorUVRow_C(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorUVRow_C(const uint8_t* src_uv, uint8_t* dst_uv, int width) { + int x; + src_uv += (width - 1) << 1; + for (x = 0; x < width; ++x) { + dst_uv[0] = src_uv[0]; + dst_uv[1] = src_uv[1]; + src_uv -= 2; + dst_uv += 2; + } +} + +void MirrorSplitUVRow_C(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { int x; src_uv += (width - 1) << 1; for (x = 0; x < width - 1; x += 2) { @@ -2199,6 +2454,21 @@ void ARGBMirrorRow_C(const uint8_t* src, uint8_t* dst, int width) { } } +void RGB24MirrorRow_C(const uint8_t* src_rgb24, uint8_t* dst_rgb24, int width) { + int x; + src_rgb24 += width * 3 - 3; + for (x = 0; x < width; ++x) { + uint8_t b = src_rgb24[0]; + uint8_t g = src_rgb24[1]; + uint8_t r = src_rgb24[2]; + dst_rgb24[0] = b; + dst_rgb24[1] = g; + dst_rgb24[2] = r; + src_rgb24 -= 3; + dst_rgb24 += 3; + } +} + void SplitUVRow_C(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v, @@ -2338,10 +2608,9 @@ void SetRow_C(uint8_t* dst, uint8_t v8, int width) { } void ARGBSetRow_C(uint8_t* dst_argb, uint32_t v32, int width) { - uint32_t* d = (uint32_t*)(dst_argb); int x; for (x = 0; x < width; ++x) { - d[x] = v32; + memcpy(dst_argb + x * sizeof v32, &v32, sizeof v32); } } @@ -2439,7 +2708,7 @@ void UYVYToYRow_C(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { } } -#define BLEND(f, b, a) (((256 - a) * b) >> 8) + f +#define BLEND(f, b, a) clamp255((((256 - a) * b) >> 8) + f) // Blend src_argb0 over src_argb1 and store to dst_argb. // dst_argb may be src_argb0 or src_argb1. @@ -2515,10 +2784,14 @@ void BlendPlaneRow_C(const uint8_t* src0, } #undef UBLEND +#if defined(__aarch64__) || defined(__arm__) +#define ATTENUATE(f, a) (f * a + 128) >> 8 +#else +// This code mimics the SSSE3 version for better testability. #define ATTENUATE(f, a) (a | (a << 8)) * (f | (f << 8)) >> 24 +#endif // Multiply source RGB by alpha and store to destination. -// This code mimics the SSSE3 version for better testability. void ARGBAttenuateRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width) { int i; for (i = 0; i < width - 1; i += 2) { @@ -3305,6 +3578,70 @@ void NV12ToRGB565Row_AVX2(const uint8_t* src_y, } #endif +#ifdef HAS_RGB24TOYJROW_AVX2 +// Convert 16 RGB24 pixels (64 bytes) to 16 YJ values. +void RGB24ToYJRow_AVX2(const uint8_t* src_rgb24, uint8_t* dst_yj, int width) { + // Row buffer for intermediate ARGB pixels. + SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); + while (width > 0) { + int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; + RGB24ToARGBRow_SSSE3(src_rgb24, row, twidth); + ARGBToYJRow_AVX2(row, dst_yj, twidth); + src_rgb24 += twidth * 3; + dst_yj += twidth; + width -= twidth; + } +} +#endif // HAS_RGB24TOYJROW_AVX2 + +#ifdef HAS_RAWTOYJROW_AVX2 +// Convert 16 RAW pixels (64 bytes) to 16 YJ values. +void RAWToYJRow_AVX2(const uint8_t* src_raw, uint8_t* dst_yj, int width) { + // Row buffer for intermediate ARGB pixels. + SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); + while (width > 0) { + int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; + RAWToARGBRow_SSSE3(src_raw, row, twidth); + ARGBToYJRow_AVX2(row, dst_yj, twidth); + src_raw += twidth * 3; + dst_yj += twidth; + width -= twidth; + } +} +#endif // HAS_RAWTOYJROW_AVX2 + +#ifdef HAS_RGB24TOYJROW_SSSE3 +// Convert 16 RGB24 pixels (64 bytes) to 16 YJ values. +void RGB24ToYJRow_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_yj, int width) { + // Row buffer for intermediate ARGB pixels. + SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); + while (width > 0) { + int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; + RGB24ToARGBRow_SSSE3(src_rgb24, row, twidth); + ARGBToYJRow_SSSE3(row, dst_yj, twidth); + src_rgb24 += twidth * 3; + dst_yj += twidth; + width -= twidth; + } +} +#endif // HAS_RGB24TOYJROW_SSSE3 + +#ifdef HAS_RAWTOYJROW_SSSE3 +// Convert 16 RAW pixels (64 bytes) to 16 YJ values. +void RAWToYJRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_yj, int width) { + // Row buffer for intermediate ARGB pixels. + SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); + while (width > 0) { + int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; + RAWToARGBRow_SSSE3(src_raw, row, twidth); + ARGBToYJRow_SSSE3(row, dst_yj, twidth); + src_raw += twidth * 3; + dst_yj += twidth; + width -= twidth; + } +} +#endif // HAS_RAWTOYJROW_SSSE3 + float ScaleSumSamples_C(const float* src, float* dst, float scale, int width) { float fsum = 0.f; int i; @@ -3358,6 +3695,29 @@ void GaussCol_C(const uint16_t* src0, } } +void GaussRow_F32_C(const float* src, float* dst, int width) { + int i; + for (i = 0; i < width; ++i) { + *dst++ = (src[0] + src[1] * 4 + src[2] * 6 + src[3] * 4 + src[4]) * + (1.0f / 256.0f); + ++src; + } +} + +// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. +void GaussCol_F32_C(const float* src0, + const float* src1, + const float* src2, + const float* src3, + const float* src4, + float* dst, + int width) { + int i; + for (i = 0; i < width; ++i) { + *dst++ = *src0++ + *src1++ * 4 + *src2++ * 6 + *src3++ * 4 + *src4++; + } +} + // Convert biplanar NV21 to packed YUV24 void NV21ToYUV24Row_C(const uint8_t* src_y, const uint8_t* src_vu, @@ -3459,6 +3819,30 @@ void SwapUVRow_C(const uint8_t* src_uv, uint8_t* dst_vu, int width) { } } +void HalfMergeUVRow_C(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width) { + int x; + for (x = 0; x < width - 1; x += 2) { + dst_uv[0] = (src_u[0] + src_u[1] + src_u[src_stride_u] + + src_u[src_stride_u + 1] + 2) >> + 2; + dst_uv[1] = (src_v[0] + src_v[1] + src_v[src_stride_v] + + src_v[src_stride_v + 1] + 2) >> + 2; + src_u += 2; + src_v += 2; + dst_uv += 2; + } + if (width & 1) { + dst_uv[0] = (src_u[0] + src_u[src_stride_u] + 1) >> 1; + dst_uv[1] = (src_v[0] + src_v[src_stride_v] + 1) >> 1; + } +} + #ifdef __cplusplus } // extern "C" } // namespace libyuv diff --git a/TMessagesProj/jni/third_party/libyuv/source/row_gcc.cc b/TMessagesProj/jni/third_party/libyuv/source/row_gcc.cc index 3088bb755..a107c30e7 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/row_gcc.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/row_gcc.cc @@ -159,24 +159,24 @@ static const lvec8 kShuffleNV21 = { #ifdef HAS_J400TOARGBROW_SSE2 void J400ToARGBRow_SSE2(const uint8_t* src_y, uint8_t* dst_argb, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0x18,%%xmm5 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "pslld $0x18,%%xmm5 \n" LABELALIGN "1: \n" - "movq (%0),%%xmm0 \n" - "lea 0x8(%0),%0 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklwd %%xmm0,%%xmm0 \n" - "punpckhwd %%xmm1,%%xmm1 \n" - "por %%xmm5,%%xmm0 \n" - "por %%xmm5,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movq (%0),%%xmm0 \n" + "lea 0x8(%0),%0 \n" + "punpcklbw %%xmm0,%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklwd %%xmm0,%%xmm0 \n" + "punpckhwd %%xmm1,%%xmm1 \n" + "por %%xmm5,%%xmm0 \n" + "por %%xmm5,%%xmm1 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu %%xmm1,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src_y), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -190,35 +190,35 @@ void RGB24ToARGBRow_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_argb, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" // 0xff000000 - "pslld $0x18,%%xmm5 \n" - "movdqa %3,%%xmm4 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" // 0xff000000 + "pslld $0x18,%%xmm5 \n" + "movdqa %3,%%xmm4 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm3 \n" - "lea 0x30(%0),%0 \n" - "movdqa %%xmm3,%%xmm2 \n" - "palignr $0x8,%%xmm1,%%xmm2 \n" - "pshufb %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm2 \n" - "palignr $0xc,%%xmm0,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "movdqu %%xmm2,0x20(%1) \n" - "por %%xmm5,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "palignr $0x4,%%xmm3,%%xmm3 \n" - "pshufb %%xmm4,%%xmm3 \n" - "movdqu %%xmm1,0x10(%1) \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm3,0x30(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm3 \n" + "lea 0x30(%0),%0 \n" + "movdqa %%xmm3,%%xmm2 \n" + "palignr $0x8,%%xmm1,%%xmm2 \n" + "pshufb %%xmm4,%%xmm2 \n" + "por %%xmm5,%%xmm2 \n" + "palignr $0xc,%%xmm0,%%xmm1 \n" + "pshufb %%xmm4,%%xmm0 \n" + "movdqu %%xmm2,0x20(%1) \n" + "por %%xmm5,%%xmm0 \n" + "pshufb %%xmm4,%%xmm1 \n" + "movdqu %%xmm0,(%1) \n" + "por %%xmm5,%%xmm1 \n" + "palignr $0x4,%%xmm3,%%xmm3 \n" + "pshufb %%xmm4,%%xmm3 \n" + "movdqu %%xmm1,0x10(%1) \n" + "por %%xmm5,%%xmm3 \n" + "movdqu %%xmm3,0x30(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_rgb24), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -228,35 +228,35 @@ void RGB24ToARGBRow_SSSE3(const uint8_t* src_rgb24, void RAWToARGBRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_argb, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" // 0xff000000 - "pslld $0x18,%%xmm5 \n" - "movdqa %3,%%xmm4 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" // 0xff000000 + "pslld $0x18,%%xmm5 \n" + "movdqa %3,%%xmm4 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm3 \n" - "lea 0x30(%0),%0 \n" - "movdqa %%xmm3,%%xmm2 \n" - "palignr $0x8,%%xmm1,%%xmm2 \n" - "pshufb %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm2 \n" - "palignr $0xc,%%xmm0,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "movdqu %%xmm2,0x20(%1) \n" - "por %%xmm5,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "palignr $0x4,%%xmm3,%%xmm3 \n" - "pshufb %%xmm4,%%xmm3 \n" - "movdqu %%xmm1,0x10(%1) \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm3,0x30(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm3 \n" + "lea 0x30(%0),%0 \n" + "movdqa %%xmm3,%%xmm2 \n" + "palignr $0x8,%%xmm1,%%xmm2 \n" + "pshufb %%xmm4,%%xmm2 \n" + "por %%xmm5,%%xmm2 \n" + "palignr $0xc,%%xmm0,%%xmm1 \n" + "pshufb %%xmm4,%%xmm0 \n" + "movdqu %%xmm2,0x20(%1) \n" + "por %%xmm5,%%xmm0 \n" + "pshufb %%xmm4,%%xmm1 \n" + "movdqu %%xmm0,(%1) \n" + "por %%xmm5,%%xmm1 \n" + "palignr $0x4,%%xmm3,%%xmm3 \n" + "pshufb %%xmm4,%%xmm3 \n" + "movdqu %%xmm1,0x10(%1) \n" + "por %%xmm5,%%xmm3 \n" + "movdqu %%xmm3,0x30(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_raw), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -267,35 +267,35 @@ void RAWToARGBRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_argb, int width) { // Same code as RAWToARGB with different shuffler and A in low bits void RAWToRGBARow_SSSE3(const uint8_t* src_raw, uint8_t* dst_rgba, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" // 0x000000ff - "psrld $0x18,%%xmm5 \n" - "movdqa %3,%%xmm4 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" // 0x000000ff + "psrld $0x18,%%xmm5 \n" + "movdqa %3,%%xmm4 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm3 \n" - "lea 0x30(%0),%0 \n" - "movdqa %%xmm3,%%xmm2 \n" - "palignr $0x8,%%xmm1,%%xmm2 \n" - "pshufb %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm2 \n" - "palignr $0xc,%%xmm0,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "movdqu %%xmm2,0x20(%1) \n" - "por %%xmm5,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "palignr $0x4,%%xmm3,%%xmm3 \n" - "pshufb %%xmm4,%%xmm3 \n" - "movdqu %%xmm1,0x10(%1) \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm3,0x30(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm3 \n" + "lea 0x30(%0),%0 \n" + "movdqa %%xmm3,%%xmm2 \n" + "palignr $0x8,%%xmm1,%%xmm2 \n" + "pshufb %%xmm4,%%xmm2 \n" + "por %%xmm5,%%xmm2 \n" + "palignr $0xc,%%xmm0,%%xmm1 \n" + "pshufb %%xmm4,%%xmm0 \n" + "movdqu %%xmm2,0x20(%1) \n" + "por %%xmm5,%%xmm0 \n" + "pshufb %%xmm4,%%xmm1 \n" + "movdqu %%xmm0,(%1) \n" + "por %%xmm5,%%xmm1 \n" + "palignr $0x4,%%xmm3,%%xmm3 \n" + "pshufb %%xmm4,%%xmm3 \n" + "movdqu %%xmm1,0x10(%1) \n" + "por %%xmm5,%%xmm3 \n" + "movdqu %%xmm3,0x30(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_raw), // %0 "+r"(dst_rgba), // %1 "+r"(width) // %2 @@ -307,25 +307,25 @@ void RAWToRGB24Row_SSSE3(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { asm volatile( - "movdqa %3,%%xmm3 \n" - "movdqa %4,%%xmm4 \n" - "movdqa %5,%%xmm5 \n" + "movdqa %3,%%xmm3 \n" + "movdqa %4,%%xmm4 \n" + "movdqa %5,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x4(%0),%%xmm1 \n" - "movdqu 0x8(%0),%%xmm2 \n" - "lea 0x18(%0),%0 \n" - "pshufb %%xmm3,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "pshufb %%xmm5,%%xmm2 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x8(%1) \n" - "movq %%xmm2,0x10(%1) \n" - "lea 0x18(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x4(%0),%%xmm1 \n" + "movdqu 0x8(%0),%%xmm2 \n" + "lea 0x18(%0),%0 \n" + "pshufb %%xmm3,%%xmm0 \n" + "pshufb %%xmm4,%%xmm1 \n" + "pshufb %%xmm5,%%xmm2 \n" + "movq %%xmm0,(%1) \n" + "movq %%xmm1,0x8(%1) \n" + "movq %%xmm2,0x10(%1) \n" + "lea 0x18(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src_raw), // %0 "+r"(dst_rgb24), // %1 "+r"(width) // %2 @@ -337,44 +337,44 @@ void RAWToRGB24Row_SSSE3(const uint8_t* src_raw, void RGB565ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "mov $0x1080108,%%eax \n" - "movd %%eax,%%xmm5 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "mov $0x20802080,%%eax \n" - "movd %%eax,%%xmm6 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "pcmpeqb %%xmm3,%%xmm3 \n" - "psllw $0xb,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "psllw $0xa,%%xmm4 \n" - "psrlw $0x5,%%xmm4 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" - "psllw $0x8,%%xmm7 \n" - "sub %0,%1 \n" - "sub %0,%1 \n" + "mov $0x1080108,%%eax \n" + "movd %%eax,%%xmm5 \n" + "pshufd $0x0,%%xmm5,%%xmm5 \n" + "mov $0x20802080,%%eax \n" + "movd %%eax,%%xmm6 \n" + "pshufd $0x0,%%xmm6,%%xmm6 \n" + "pcmpeqb %%xmm3,%%xmm3 \n" + "psllw $0xb,%%xmm3 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psllw $0xa,%%xmm4 \n" + "psrlw $0x5,%%xmm4 \n" + "pcmpeqb %%xmm7,%%xmm7 \n" + "psllw $0x8,%%xmm7 \n" + "sub %0,%1 \n" + "sub %0,%1 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pand %%xmm3,%%xmm1 \n" - "psllw $0xb,%%xmm2 \n" - "pmulhuw %%xmm5,%%xmm1 \n" - "pmulhuw %%xmm5,%%xmm2 \n" - "psllw $0x8,%%xmm1 \n" - "por %%xmm2,%%xmm1 \n" - "pand %%xmm4,%%xmm0 \n" - "pmulhuw %%xmm6,%%xmm0 \n" - "por %%xmm7,%%xmm0 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklbw %%xmm0,%%xmm1 \n" - "punpckhbw %%xmm0,%%xmm2 \n" - "movdqu %%xmm1,0x00(%1,%0,2) \n" - "movdqu %%xmm2,0x10(%1,%0,2) \n" - "lea 0x10(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "pand %%xmm3,%%xmm1 \n" + "psllw $0xb,%%xmm2 \n" + "pmulhuw %%xmm5,%%xmm1 \n" + "pmulhuw %%xmm5,%%xmm2 \n" + "psllw $0x8,%%xmm1 \n" + "por %%xmm2,%%xmm1 \n" + "pand %%xmm4,%%xmm0 \n" + "pmulhuw %%xmm6,%%xmm0 \n" + "por %%xmm7,%%xmm0 \n" + "movdqa %%xmm1,%%xmm2 \n" + "punpcklbw %%xmm0,%%xmm1 \n" + "punpckhbw %%xmm0,%%xmm2 \n" + "movdqu %%xmm1,0x00(%1,%0,2) \n" + "movdqu %%xmm2,0x10(%1,%0,2) \n" + "lea 0x10(%0),%0 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -385,47 +385,47 @@ void RGB565ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { void ARGB1555ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "mov $0x1080108,%%eax \n" - "movd %%eax,%%xmm5 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "mov $0x42004200,%%eax \n" - "movd %%eax,%%xmm6 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "pcmpeqb %%xmm3,%%xmm3 \n" - "psllw $0xb,%%xmm3 \n" - "movdqa %%xmm3,%%xmm4 \n" - "psrlw $0x6,%%xmm4 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" - "psllw $0x8,%%xmm7 \n" - "sub %0,%1 \n" - "sub %0,%1 \n" + "mov $0x1080108,%%eax \n" + "movd %%eax,%%xmm5 \n" + "pshufd $0x0,%%xmm5,%%xmm5 \n" + "mov $0x42004200,%%eax \n" + "movd %%eax,%%xmm6 \n" + "pshufd $0x0,%%xmm6,%%xmm6 \n" + "pcmpeqb %%xmm3,%%xmm3 \n" + "psllw $0xb,%%xmm3 \n" + "movdqa %%xmm3,%%xmm4 \n" + "psrlw $0x6,%%xmm4 \n" + "pcmpeqb %%xmm7,%%xmm7 \n" + "psllw $0x8,%%xmm7 \n" + "sub %0,%1 \n" + "sub %0,%1 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "psllw $0x1,%%xmm1 \n" - "psllw $0xb,%%xmm2 \n" - "pand %%xmm3,%%xmm1 \n" - "pmulhuw %%xmm5,%%xmm2 \n" - "pmulhuw %%xmm5,%%xmm1 \n" - "psllw $0x8,%%xmm1 \n" - "por %%xmm2,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pand %%xmm4,%%xmm0 \n" - "psraw $0x8,%%xmm2 \n" - "pmulhuw %%xmm6,%%xmm0 \n" - "pand %%xmm7,%%xmm2 \n" - "por %%xmm2,%%xmm0 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklbw %%xmm0,%%xmm1 \n" - "punpckhbw %%xmm0,%%xmm2 \n" - "movdqu %%xmm1,0x00(%1,%0,2) \n" - "movdqu %%xmm2,0x10(%1,%0,2) \n" - "lea 0x10(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "psllw $0x1,%%xmm1 \n" + "psllw $0xb,%%xmm2 \n" + "pand %%xmm3,%%xmm1 \n" + "pmulhuw %%xmm5,%%xmm2 \n" + "pmulhuw %%xmm5,%%xmm1 \n" + "psllw $0x8,%%xmm1 \n" + "por %%xmm2,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "pand %%xmm4,%%xmm0 \n" + "psraw $0x8,%%xmm2 \n" + "pmulhuw %%xmm6,%%xmm0 \n" + "pand %%xmm7,%%xmm2 \n" + "por %%xmm2,%%xmm0 \n" + "movdqa %%xmm1,%%xmm2 \n" + "punpcklbw %%xmm0,%%xmm1 \n" + "punpckhbw %%xmm0,%%xmm2 \n" + "movdqu %%xmm1,0x00(%1,%0,2) \n" + "movdqu %%xmm2,0x10(%1,%0,2) \n" + "lea 0x10(%0),%0 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -436,34 +436,34 @@ void ARGB1555ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { void ARGB4444ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "mov $0xf0f0f0f,%%eax \n" - "movd %%eax,%%xmm4 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "pslld $0x4,%%xmm5 \n" - "sub %0,%1 \n" - "sub %0,%1 \n" + "mov $0xf0f0f0f,%%eax \n" + "movd %%eax,%%xmm4 \n" + "pshufd $0x0,%%xmm4,%%xmm4 \n" + "movdqa %%xmm4,%%xmm5 \n" + "pslld $0x4,%%xmm5 \n" + "sub %0,%1 \n" + "sub %0,%1 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pand %%xmm4,%%xmm0 \n" - "pand %%xmm5,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm2,%%xmm3 \n" - "psllw $0x4,%%xmm1 \n" - "psrlw $0x4,%%xmm3 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm3,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm2,%%xmm0 \n" - "punpckhbw %%xmm2,%%xmm1 \n" - "movdqu %%xmm0,0x00(%1,%0,2) \n" - "movdqu %%xmm1,0x10(%1,%0,2) \n" - "lea 0x10(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqa %%xmm0,%%xmm2 \n" + "pand %%xmm4,%%xmm0 \n" + "pand %%xmm5,%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm2,%%xmm3 \n" + "psllw $0x4,%%xmm1 \n" + "psrlw $0x4,%%xmm3 \n" + "por %%xmm1,%%xmm0 \n" + "por %%xmm3,%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklbw %%xmm2,%%xmm0 \n" + "punpckhbw %%xmm2,%%xmm1 \n" + "movdqu %%xmm0,0x00(%1,%0,2) \n" + "movdqu %%xmm1,0x10(%1,%0,2) \n" + "lea 0x10(%0),%0 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -474,35 +474,35 @@ void ARGB4444ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { void ARGBToRGB24Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "movdqa %3,%%xmm6 \n" + "movdqa %3,%%xmm6 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "pshufb %%xmm6,%%xmm0 \n" - "pshufb %%xmm6,%%xmm1 \n" - "pshufb %%xmm6,%%xmm2 \n" - "pshufb %%xmm6,%%xmm3 \n" - "movdqa %%xmm1,%%xmm4 \n" - "psrldq $0x4,%%xmm1 \n" - "pslldq $0xc,%%xmm4 \n" - "movdqa %%xmm2,%%xmm5 \n" - "por %%xmm4,%%xmm0 \n" - "pslldq $0x8,%%xmm5 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "psrldq $0x8,%%xmm2 \n" - "pslldq $0x4,%%xmm3 \n" - "por %%xmm3,%%xmm2 \n" - "movdqu %%xmm1,0x10(%1) \n" - "movdqu %%xmm2,0x20(%1) \n" - "lea 0x30(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x30(%0),%%xmm3 \n" + "lea 0x40(%0),%0 \n" + "pshufb %%xmm6,%%xmm0 \n" + "pshufb %%xmm6,%%xmm1 \n" + "pshufb %%xmm6,%%xmm2 \n" + "pshufb %%xmm6,%%xmm3 \n" + "movdqa %%xmm1,%%xmm4 \n" + "psrldq $0x4,%%xmm1 \n" + "pslldq $0xc,%%xmm4 \n" + "movdqa %%xmm2,%%xmm5 \n" + "por %%xmm4,%%xmm0 \n" + "pslldq $0x8,%%xmm5 \n" + "movdqu %%xmm0,(%1) \n" + "por %%xmm5,%%xmm1 \n" + "psrldq $0x8,%%xmm2 \n" + "pslldq $0x4,%%xmm3 \n" + "por %%xmm3,%%xmm2 \n" + "movdqu %%xmm1,0x10(%1) \n" + "movdqu %%xmm2,0x20(%1) \n" + "lea 0x30(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -513,35 +513,35 @@ void ARGBToRGB24Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { void ARGBToRAWRow_SSSE3(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "movdqa %3,%%xmm6 \n" + "movdqa %3,%%xmm6 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "pshufb %%xmm6,%%xmm0 \n" - "pshufb %%xmm6,%%xmm1 \n" - "pshufb %%xmm6,%%xmm2 \n" - "pshufb %%xmm6,%%xmm3 \n" - "movdqa %%xmm1,%%xmm4 \n" - "psrldq $0x4,%%xmm1 \n" - "pslldq $0xc,%%xmm4 \n" - "movdqa %%xmm2,%%xmm5 \n" - "por %%xmm4,%%xmm0 \n" - "pslldq $0x8,%%xmm5 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "psrldq $0x8,%%xmm2 \n" - "pslldq $0x4,%%xmm3 \n" - "por %%xmm3,%%xmm2 \n" - "movdqu %%xmm1,0x10(%1) \n" - "movdqu %%xmm2,0x20(%1) \n" - "lea 0x30(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x30(%0),%%xmm3 \n" + "lea 0x40(%0),%0 \n" + "pshufb %%xmm6,%%xmm0 \n" + "pshufb %%xmm6,%%xmm1 \n" + "pshufb %%xmm6,%%xmm2 \n" + "pshufb %%xmm6,%%xmm3 \n" + "movdqa %%xmm1,%%xmm4 \n" + "psrldq $0x4,%%xmm1 \n" + "pslldq $0xc,%%xmm4 \n" + "movdqa %%xmm2,%%xmm5 \n" + "por %%xmm4,%%xmm0 \n" + "pslldq $0x8,%%xmm5 \n" + "movdqu %%xmm0,(%1) \n" + "por %%xmm5,%%xmm1 \n" + "psrldq $0x8,%%xmm2 \n" + "pslldq $0x4,%%xmm3 \n" + "por %%xmm3,%%xmm2 \n" + "movdqu %%xmm1,0x10(%1) \n" + "movdqu %%xmm2,0x20(%1) \n" + "lea 0x30(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -556,37 +556,37 @@ static const lvec32 kPermdRGB24_AVX = {0, 1, 2, 4, 5, 6, 3, 7}; void ARGBToRGB24Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( "vbroadcastf128 %3,%%ymm6 \n" - "vmovdqa %4,%%ymm7 \n" + "vmovdqa %4,%%ymm7 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vpshufb %%ymm6,%%ymm0,%%ymm0 \n" // xxx0yyy0 - "vpshufb %%ymm6,%%ymm1,%%ymm1 \n" - "vpshufb %%ymm6,%%ymm2,%%ymm2 \n" - "vpshufb %%ymm6,%%ymm3,%%ymm3 \n" - "vpermd %%ymm0,%%ymm7,%%ymm0 \n" // pack to 24 bytes - "vpermd %%ymm1,%%ymm7,%%ymm1 \n" - "vpermd %%ymm2,%%ymm7,%%ymm2 \n" - "vpermd %%ymm3,%%ymm7,%%ymm3 \n" - "vpermq $0x3f,%%ymm1,%%ymm4 \n" // combine 24 + 8 - "vpor %%ymm4,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "vpermq $0xf9,%%ymm1,%%ymm1 \n" // combine 16 + 16 - "vpermq $0x4f,%%ymm2,%%ymm4 \n" - "vpor %%ymm4,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "vpermq $0xfe,%%ymm2,%%ymm2 \n" // combine 8 + 24 - "vpermq $0x93,%%ymm3,%%ymm3 \n" - "vpor %%ymm3,%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm2,0x40(%1) \n" - "lea 0x60(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vmovdqu 0x40(%0),%%ymm2 \n" + "vmovdqu 0x60(%0),%%ymm3 \n" + "lea 0x80(%0),%0 \n" + "vpshufb %%ymm6,%%ymm0,%%ymm0 \n" // xxx0yyy0 + "vpshufb %%ymm6,%%ymm1,%%ymm1 \n" + "vpshufb %%ymm6,%%ymm2,%%ymm2 \n" + "vpshufb %%ymm6,%%ymm3,%%ymm3 \n" + "vpermd %%ymm0,%%ymm7,%%ymm0 \n" // pack to 24 bytes + "vpermd %%ymm1,%%ymm7,%%ymm1 \n" + "vpermd %%ymm2,%%ymm7,%%ymm2 \n" + "vpermd %%ymm3,%%ymm7,%%ymm3 \n" + "vpermq $0x3f,%%ymm1,%%ymm4 \n" // combine 24 + 8 + "vpor %%ymm4,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "vpermq $0xf9,%%ymm1,%%ymm1 \n" // combine 16 + 16 + "vpermq $0x4f,%%ymm2,%%ymm4 \n" + "vpor %%ymm4,%%ymm1,%%ymm1 \n" + "vmovdqu %%ymm1,0x20(%1) \n" + "vpermq $0xfe,%%ymm2,%%ymm2 \n" // combine 8 + 24 + "vpermq $0x93,%%ymm3,%%ymm3 \n" + "vpor %%ymm3,%%ymm2,%%ymm2 \n" + "vmovdqu %%ymm2,0x40(%1) \n" + "lea 0x60(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -615,26 +615,26 @@ static const ulvec8 kPermARGBToRGB24_2 = { void ARGBToRGB24Row_AVX512VBMI(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "vmovdqa %3,%%ymm5 \n" - "vmovdqa %4,%%ymm6 \n" - "vmovdqa %5,%%ymm7 \n" + "vmovdqa %3,%%ymm5 \n" + "vmovdqa %4,%%ymm6 \n" + "vmovdqa %5,%%ymm7 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vpermt2b %%ymm1,%%ymm5,%%ymm0 \n" - "vpermt2b %%ymm2,%%ymm6,%%ymm1 \n" - "vpermt2b %%ymm3,%%ymm7,%%ymm2 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "vmovdqu %%ymm2,0x40(%1) \n" - "lea 0x60(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vmovdqu 0x40(%0),%%ymm2 \n" + "vmovdqu 0x60(%0),%%ymm3 \n" + "lea 0x80(%0),%0 \n" + "vpermt2b %%ymm1,%%ymm5,%%ymm0 \n" + "vpermt2b %%ymm2,%%ymm6,%%ymm1 \n" + "vpermt2b %%ymm3,%%ymm7,%%ymm2 \n" + "vmovdqu %%ymm0,(%1) \n" + "vmovdqu %%ymm1,0x20(%1) \n" + "vmovdqu %%ymm2,0x40(%1) \n" + "lea 0x60(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -650,37 +650,37 @@ void ARGBToRGB24Row_AVX512VBMI(const uint8_t* src, uint8_t* dst, int width) { void ARGBToRAWRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( "vbroadcastf128 %3,%%ymm6 \n" - "vmovdqa %4,%%ymm7 \n" + "vmovdqa %4,%%ymm7 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vpshufb %%ymm6,%%ymm0,%%ymm0 \n" // xxx0yyy0 - "vpshufb %%ymm6,%%ymm1,%%ymm1 \n" - "vpshufb %%ymm6,%%ymm2,%%ymm2 \n" - "vpshufb %%ymm6,%%ymm3,%%ymm3 \n" - "vpermd %%ymm0,%%ymm7,%%ymm0 \n" // pack to 24 bytes - "vpermd %%ymm1,%%ymm7,%%ymm1 \n" - "vpermd %%ymm2,%%ymm7,%%ymm2 \n" - "vpermd %%ymm3,%%ymm7,%%ymm3 \n" - "vpermq $0x3f,%%ymm1,%%ymm4 \n" // combine 24 + 8 - "vpor %%ymm4,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "vpermq $0xf9,%%ymm1,%%ymm1 \n" // combine 16 + 16 - "vpermq $0x4f,%%ymm2,%%ymm4 \n" - "vpor %%ymm4,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "vpermq $0xfe,%%ymm2,%%ymm2 \n" // combine 8 + 24 - "vpermq $0x93,%%ymm3,%%ymm3 \n" - "vpor %%ymm3,%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm2,0x40(%1) \n" - "lea 0x60(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vmovdqu 0x40(%0),%%ymm2 \n" + "vmovdqu 0x60(%0),%%ymm3 \n" + "lea 0x80(%0),%0 \n" + "vpshufb %%ymm6,%%ymm0,%%ymm0 \n" // xxx0yyy0 + "vpshufb %%ymm6,%%ymm1,%%ymm1 \n" + "vpshufb %%ymm6,%%ymm2,%%ymm2 \n" + "vpshufb %%ymm6,%%ymm3,%%ymm3 \n" + "vpermd %%ymm0,%%ymm7,%%ymm0 \n" // pack to 24 bytes + "vpermd %%ymm1,%%ymm7,%%ymm1 \n" + "vpermd %%ymm2,%%ymm7,%%ymm2 \n" + "vpermd %%ymm3,%%ymm7,%%ymm3 \n" + "vpermq $0x3f,%%ymm1,%%ymm4 \n" // combine 24 + 8 + "vpor %%ymm4,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "vpermq $0xf9,%%ymm1,%%ymm1 \n" // combine 16 + 16 + "vpermq $0x4f,%%ymm2,%%ymm4 \n" + "vpor %%ymm4,%%ymm1,%%ymm1 \n" + "vmovdqu %%ymm1,0x20(%1) \n" + "vpermq $0xfe,%%ymm2,%%ymm2 \n" // combine 8 + 24 + "vpermq $0x93,%%ymm3,%%ymm3 \n" + "vpor %%ymm3,%%ymm2,%%ymm2 \n" + "vmovdqu %%ymm2,0x40(%1) \n" + "lea 0x60(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -694,34 +694,34 @@ void ARGBToRAWRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { void ARGBToRGB565Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "pcmpeqb %%xmm3,%%xmm3 \n" - "psrld $0x1b,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrld $0x1a,%%xmm4 \n" - "pslld $0x5,%%xmm4 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0xb,%%xmm5 \n" + "pcmpeqb %%xmm3,%%xmm3 \n" + "psrld $0x1b,%%xmm3 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psrld $0x1a,%%xmm4 \n" + "pslld $0x5,%%xmm4 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "pslld $0xb,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pslld $0x8,%%xmm0 \n" - "psrld $0x3,%%xmm1 \n" - "psrld $0x5,%%xmm2 \n" - "psrad $0x10,%%xmm0 \n" - "pand %%xmm3,%%xmm1 \n" - "pand %%xmm4,%%xmm2 \n" - "pand %%xmm5,%%xmm0 \n" - "por %%xmm2,%%xmm1 \n" - "por %%xmm1,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "pslld $0x8,%%xmm0 \n" + "psrld $0x3,%%xmm1 \n" + "psrld $0x5,%%xmm2 \n" + "psrad $0x10,%%xmm0 \n" + "pand %%xmm3,%%xmm1 \n" + "pand %%xmm4,%%xmm2 \n" + "pand %%xmm5,%%xmm0 \n" + "por %%xmm2,%%xmm1 \n" + "por %%xmm1,%%xmm0 \n" + "packssdw %%xmm0,%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "movq %%xmm0,(%1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -734,40 +734,40 @@ void ARGBToRGB565DitherRow_SSE2(const uint8_t* src, const uint32_t dither4, int width) { asm volatile( - "movd %3,%%xmm6 \n" - "punpcklbw %%xmm6,%%xmm6 \n" - "movdqa %%xmm6,%%xmm7 \n" - "punpcklwd %%xmm6,%%xmm6 \n" - "punpckhwd %%xmm7,%%xmm7 \n" - "pcmpeqb %%xmm3,%%xmm3 \n" - "psrld $0x1b,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrld $0x1a,%%xmm4 \n" - "pslld $0x5,%%xmm4 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0xb,%%xmm5 \n" + "movd %3,%%xmm6 \n" + "punpcklbw %%xmm6,%%xmm6 \n" + "movdqa %%xmm6,%%xmm7 \n" + "punpcklwd %%xmm6,%%xmm6 \n" + "punpckhwd %%xmm7,%%xmm7 \n" + "pcmpeqb %%xmm3,%%xmm3 \n" + "psrld $0x1b,%%xmm3 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psrld $0x1a,%%xmm4 \n" + "pslld $0x5,%%xmm4 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "pslld $0xb,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "paddusb %%xmm6,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pslld $0x8,%%xmm0 \n" - "psrld $0x3,%%xmm1 \n" - "psrld $0x5,%%xmm2 \n" - "psrad $0x10,%%xmm0 \n" - "pand %%xmm3,%%xmm1 \n" - "pand %%xmm4,%%xmm2 \n" - "pand %%xmm5,%%xmm0 \n" - "por %%xmm2,%%xmm1 \n" - "por %%xmm1,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "paddusb %%xmm6,%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "pslld $0x8,%%xmm0 \n" + "psrld $0x3,%%xmm1 \n" + "psrld $0x5,%%xmm2 \n" + "psrad $0x10,%%xmm0 \n" + "pand %%xmm3,%%xmm1 \n" + "pand %%xmm4,%%xmm2 \n" + "pand %%xmm5,%%xmm0 \n" + "por %%xmm2,%%xmm1 \n" + "por %%xmm1,%%xmm0 \n" + "packssdw %%xmm0,%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "movq %%xmm0,(%1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -783,35 +783,35 @@ void ARGBToRGB565DitherRow_AVX2(const uint8_t* src, int width) { asm volatile( "vbroadcastss %3,%%xmm6 \n" - "vpunpcklbw %%xmm6,%%xmm6,%%xmm6 \n" - "vpermq $0xd8,%%ymm6,%%ymm6 \n" - "vpunpcklwd %%ymm6,%%ymm6,%%ymm6 \n" - "vpcmpeqb %%ymm3,%%ymm3,%%ymm3 \n" - "vpsrld $0x1b,%%ymm3,%%ymm3 \n" - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpsrld $0x1a,%%ymm4,%%ymm4 \n" - "vpslld $0x5,%%ymm4,%%ymm4 \n" - "vpslld $0xb,%%ymm3,%%ymm5 \n" + "vpunpcklbw %%xmm6,%%xmm6,%%xmm6 \n" + "vpermq $0xd8,%%ymm6,%%ymm6 \n" + "vpunpcklwd %%ymm6,%%ymm6,%%ymm6 \n" + "vpcmpeqb %%ymm3,%%ymm3,%%ymm3 \n" + "vpsrld $0x1b,%%ymm3,%%ymm3 \n" + "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" + "vpsrld $0x1a,%%ymm4,%%ymm4 \n" + "vpslld $0x5,%%ymm4,%%ymm4 \n" + "vpslld $0xb,%%ymm3,%%ymm5 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vpaddusb %%ymm6,%%ymm0,%%ymm0 \n" - "vpsrld $0x5,%%ymm0,%%ymm2 \n" - "vpsrld $0x3,%%ymm0,%%ymm1 \n" - "vpsrld $0x8,%%ymm0,%%ymm0 \n" - "vpand %%ymm4,%%ymm2,%%ymm2 \n" - "vpand %%ymm3,%%ymm1,%%ymm1 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpor %%ymm2,%%ymm1,%%ymm1 \n" - "vpor %%ymm1,%%ymm0,%%ymm0 \n" - "vpackusdw %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "lea 0x20(%0),%0 \n" - "vmovdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vpaddusb %%ymm6,%%ymm0,%%ymm0 \n" + "vpsrld $0x5,%%ymm0,%%ymm2 \n" + "vpsrld $0x3,%%ymm0,%%ymm1 \n" + "vpsrld $0x8,%%ymm0,%%ymm0 \n" + "vpand %%ymm4,%%ymm2,%%ymm2 \n" + "vpand %%ymm3,%%ymm1,%%ymm1 \n" + "vpand %%ymm5,%%ymm0,%%ymm0 \n" + "vpor %%ymm2,%%ymm1,%%ymm1 \n" + "vpor %%ymm1,%%ymm0,%%ymm0 \n" + "vpackusdw %%ymm0,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "lea 0x20(%0),%0 \n" + "vmovdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -824,38 +824,38 @@ void ARGBToRGB565DitherRow_AVX2(const uint8_t* src, void ARGBToARGB1555Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrld $0x1b,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "pslld $0x5,%%xmm5 \n" - "movdqa %%xmm4,%%xmm6 \n" - "pslld $0xa,%%xmm6 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" - "pslld $0xf,%%xmm7 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psrld $0x1b,%%xmm4 \n" + "movdqa %%xmm4,%%xmm5 \n" + "pslld $0x5,%%xmm5 \n" + "movdqa %%xmm4,%%xmm6 \n" + "pslld $0xa,%%xmm6 \n" + "pcmpeqb %%xmm7,%%xmm7 \n" + "pslld $0xf,%%xmm7 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "movdqa %%xmm0,%%xmm3 \n" - "psrad $0x10,%%xmm0 \n" - "psrld $0x3,%%xmm1 \n" - "psrld $0x6,%%xmm2 \n" - "psrld $0x9,%%xmm3 \n" - "pand %%xmm7,%%xmm0 \n" - "pand %%xmm4,%%xmm1 \n" - "pand %%xmm5,%%xmm2 \n" - "pand %%xmm6,%%xmm3 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm3,%%xmm2 \n" - "por %%xmm2,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "movdqa %%xmm0,%%xmm3 \n" + "psrad $0x10,%%xmm0 \n" + "psrld $0x3,%%xmm1 \n" + "psrld $0x6,%%xmm2 \n" + "psrld $0x9,%%xmm3 \n" + "pand %%xmm7,%%xmm0 \n" + "pand %%xmm4,%%xmm1 \n" + "pand %%xmm5,%%xmm2 \n" + "pand %%xmm6,%%xmm3 \n" + "por %%xmm1,%%xmm0 \n" + "por %%xmm3,%%xmm2 \n" + "por %%xmm2,%%xmm0 \n" + "packssdw %%xmm0,%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "movq %%xmm0,(%1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -865,26 +865,26 @@ void ARGBToARGB1555Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { void ARGBToARGB4444Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psllw $0xc,%%xmm4 \n" - "movdqa %%xmm4,%%xmm3 \n" - "psrlw $0x8,%%xmm3 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psllw $0xc,%%xmm4 \n" + "movdqa %%xmm4,%%xmm3 \n" + "psrlw $0x8,%%xmm3 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm3,%%xmm0 \n" - "pand %%xmm4,%%xmm1 \n" - "psrlq $0x4,%%xmm0 \n" - "psrlq $0x8,%%xmm1 \n" - "por %%xmm1,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "pand %%xmm3,%%xmm0 \n" + "pand %%xmm4,%%xmm1 \n" + "psrlq $0x4,%%xmm0 \n" + "psrlq $0x8,%%xmm1 \n" + "por %%xmm1,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "movq %%xmm0,(%1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -928,31 +928,31 @@ static const uint32_t kMulAG10 = 64 * 65536 + 1028; void ARGBToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "movdqa %3,%%xmm2 \n" // shuffler for RB - "movd %4,%%xmm3 \n" // multipler for RB - "movd %5,%%xmm4 \n" // mask for R10 B10 - "movd %6,%%xmm5 \n" // mask for AG - "movd %7,%%xmm6 \n" // multipler for AG - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "sub %0,%1 \n" + "movdqa %3,%%xmm2 \n" // shuffler for RB + "movd %4,%%xmm3 \n" // multipler for RB + "movd %5,%%xmm4 \n" // mask for R10 B10 + "movd %6,%%xmm5 \n" // mask for AG + "movd %7,%%xmm6 \n" // multipler for AG + "pshufd $0x0,%%xmm3,%%xmm3 \n" + "pshufd $0x0,%%xmm4,%%xmm4 \n" + "pshufd $0x0,%%xmm5,%%xmm5 \n" + "pshufd $0x0,%%xmm6,%%xmm6 \n" + "sub %0,%1 \n" - "1: \n" - "movdqu (%0),%%xmm0 \n" // fetch 4 ARGB pixels - "movdqa %%xmm0,%%xmm1 \n" - "pshufb %%xmm2,%%xmm1 \n" // R0B0 - "pand %%xmm5,%%xmm0 \n" // A0G0 - "pmulhuw %%xmm3,%%xmm1 \n" // X2 R16 X4 B10 - "pmulhuw %%xmm6,%%xmm0 \n" // X10 A2 X10 G10 - "pand %%xmm4,%%xmm1 \n" // X2 R10 X10 B10 - "pslld $10,%%xmm0 \n" // A2 x10 G10 x10 - "por %%xmm1,%%xmm0 \n" // A2 R10 G10 B10 - "movdqu %%xmm0,(%1,%0) \n" // store 4 AR30 pixels - "add $0x10,%0 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "1: \n" + "movdqu (%0),%%xmm0 \n" // fetch 4 ARGB pixels + "movdqa %%xmm0,%%xmm1 \n" + "pshufb %%xmm2,%%xmm1 \n" // R0B0 + "pand %%xmm5,%%xmm0 \n" // A0G0 + "pmulhuw %%xmm3,%%xmm1 \n" // X2 R16 X4 B10 + "pmulhuw %%xmm6,%%xmm0 \n" // X10 A2 X10 G10 + "pand %%xmm4,%%xmm1 \n" // X2 R10 X10 B10 + "pslld $10,%%xmm0 \n" // A2 x10 G10 x10 + "por %%xmm1,%%xmm0 \n" // A2 R10 G10 B10 + "movdqu %%xmm0,(%1,%0) \n" // store 4 AR30 pixels + "add $0x10,%0 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -967,31 +967,31 @@ void ARGBToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { void ABGRToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "movdqa %3,%%xmm2 \n" // shuffler for RB - "movd %4,%%xmm3 \n" // multipler for RB - "movd %5,%%xmm4 \n" // mask for R10 B10 - "movd %6,%%xmm5 \n" // mask for AG - "movd %7,%%xmm6 \n" // multipler for AG - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "sub %0,%1 \n" + "movdqa %3,%%xmm2 \n" // shuffler for RB + "movd %4,%%xmm3 \n" // multipler for RB + "movd %5,%%xmm4 \n" // mask for R10 B10 + "movd %6,%%xmm5 \n" // mask for AG + "movd %7,%%xmm6 \n" // multipler for AG + "pshufd $0x0,%%xmm3,%%xmm3 \n" + "pshufd $0x0,%%xmm4,%%xmm4 \n" + "pshufd $0x0,%%xmm5,%%xmm5 \n" + "pshufd $0x0,%%xmm6,%%xmm6 \n" + "sub %0,%1 \n" - "1: \n" - "movdqu (%0),%%xmm0 \n" // fetch 4 ABGR pixels - "movdqa %%xmm0,%%xmm1 \n" - "pshufb %%xmm2,%%xmm1 \n" // R0B0 - "pand %%xmm5,%%xmm0 \n" // A0G0 - "pmulhuw %%xmm3,%%xmm1 \n" // X2 R16 X4 B10 - "pmulhuw %%xmm6,%%xmm0 \n" // X10 A2 X10 G10 - "pand %%xmm4,%%xmm1 \n" // X2 R10 X10 B10 - "pslld $10,%%xmm0 \n" // A2 x10 G10 x10 - "por %%xmm1,%%xmm0 \n" // A2 R10 G10 B10 - "movdqu %%xmm0,(%1,%0) \n" // store 4 AR30 pixels - "add $0x10,%0 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "1: \n" + "movdqu (%0),%%xmm0 \n" // fetch 4 ABGR pixels + "movdqa %%xmm0,%%xmm1 \n" + "pshufb %%xmm2,%%xmm1 \n" // R0B0 + "pand %%xmm5,%%xmm0 \n" // A0G0 + "pmulhuw %%xmm3,%%xmm1 \n" // X2 R16 X4 B10 + "pmulhuw %%xmm6,%%xmm0 \n" // X10 A2 X10 G10 + "pand %%xmm4,%%xmm1 \n" // X2 R10 X10 B10 + "pslld $10,%%xmm0 \n" // A2 x10 G10 x10 + "por %%xmm1,%%xmm0 \n" // A2 R10 G10 B10 + "movdqu %%xmm0,(%1,%0) \n" // store 4 AR30 pixels + "add $0x10,%0 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -1008,25 +1008,25 @@ void ABGRToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { void ARGBToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( "vbroadcastf128 %3,%%ymm2 \n" // shuffler for RB - "vbroadcastss %4,%%ymm3 \n" // multipler for RB - "vbroadcastss %5,%%ymm4 \n" // mask for R10 B10 - "vbroadcastss %6,%%ymm5 \n" // mask for AG - "vbroadcastss %7,%%ymm6 \n" // multipler for AG - "sub %0,%1 \n" + "vbroadcastss %4,%%ymm3 \n" // multipler for RB + "vbroadcastss %5,%%ymm4 \n" // mask for R10 B10 + "vbroadcastss %6,%%ymm5 \n" // mask for AG + "vbroadcastss %7,%%ymm6 \n" // multipler for AG + "sub %0,%1 \n" "1: \n" - "vmovdqu (%0),%%ymm0 \n" // fetch 8 ARGB pixels - "vpshufb %%ymm2,%%ymm0,%%ymm1 \n" // R0B0 - "vpand %%ymm5,%%ymm0,%%ymm0 \n" // A0G0 - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" // X2 R16 X4 B10 - "vpmulhuw %%ymm6,%%ymm0,%%ymm0 \n" // X10 A2 X10 G10 - "vpand %%ymm4,%%ymm1,%%ymm1 \n" // X2 R10 X10 B10 - "vpslld $10,%%ymm0,%%ymm0 \n" // A2 x10 G10 x10 - "vpor %%ymm1,%%ymm0,%%ymm0 \n" // A2 R10 G10 B10 - "vmovdqu %%ymm0,(%1,%0) \n" // store 8 AR30 pixels - "add $0x20,%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" // fetch 8 ARGB pixels + "vpshufb %%ymm2,%%ymm0,%%ymm1 \n" // R0B0 + "vpand %%ymm5,%%ymm0,%%ymm0 \n" // A0G0 + "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" // X2 R16 X4 B10 + "vpmulhuw %%ymm6,%%ymm0,%%ymm0 \n" // X10 A2 X10 G10 + "vpand %%ymm4,%%ymm1,%%ymm1 \n" // X2 R10 X10 B10 + "vpslld $10,%%ymm0,%%ymm0 \n" // A2 x10 G10 x10 + "vpor %%ymm1,%%ymm0,%%ymm0 \n" // A2 R10 G10 B10 + "vmovdqu %%ymm0,(%1,%0) \n" // store 8 AR30 pixels + "add $0x20,%0 \n" + "sub $0x8,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 @@ -1045,25 +1045,25 @@ void ARGBToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( "vbroadcastf128 %3,%%ymm2 \n" // shuffler for RB - "vbroadcastss %4,%%ymm3 \n" // multipler for RB - "vbroadcastss %5,%%ymm4 \n" // mask for R10 B10 - "vbroadcastss %6,%%ymm5 \n" // mask for AG - "vbroadcastss %7,%%ymm6 \n" // multipler for AG - "sub %0,%1 \n" + "vbroadcastss %4,%%ymm3 \n" // multipler for RB + "vbroadcastss %5,%%ymm4 \n" // mask for R10 B10 + "vbroadcastss %6,%%ymm5 \n" // mask for AG + "vbroadcastss %7,%%ymm6 \n" // multipler for AG + "sub %0,%1 \n" "1: \n" - "vmovdqu (%0),%%ymm0 \n" // fetch 8 ABGR pixels - "vpshufb %%ymm2,%%ymm0,%%ymm1 \n" // R0B0 - "vpand %%ymm5,%%ymm0,%%ymm0 \n" // A0G0 - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" // X2 R16 X4 B10 - "vpmulhuw %%ymm6,%%ymm0,%%ymm0 \n" // X10 A2 X10 G10 - "vpand %%ymm4,%%ymm1,%%ymm1 \n" // X2 R10 X10 B10 - "vpslld $10,%%ymm0,%%ymm0 \n" // A2 x10 G10 x10 - "vpor %%ymm1,%%ymm0,%%ymm0 \n" // A2 R10 G10 B10 - "vmovdqu %%ymm0,(%1,%0) \n" // store 8 AR30 pixels - "add $0x20,%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" // fetch 8 ABGR pixels + "vpshufb %%ymm2,%%ymm0,%%ymm1 \n" // R0B0 + "vpand %%ymm5,%%ymm0,%%ymm0 \n" // A0G0 + "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" // X2 R16 X4 B10 + "vpmulhuw %%ymm6,%%ymm0,%%ymm0 \n" // X10 A2 X10 G10 + "vpand %%ymm4,%%ymm1,%%ymm1 \n" // X2 R10 X10 B10 + "vpslld $10,%%ymm0,%%ymm0 \n" // A2 x10 G10 x10 + "vpor %%ymm1,%%ymm0,%%ymm0 \n" // A2 R10 G10 B10 + "vmovdqu %%ymm0,(%1,%0) \n" // store 8 AR30 pixels + "add $0x20,%0 \n" + "sub $0x8,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 @@ -1078,6 +1078,8 @@ void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { } #endif +// clang-format off + // TODO(mraptis): Consider passing R, G, B multipliers as parameter. // round parameter is register containing value to add before shift. #define RGBTOY(round) \ @@ -1101,10 +1103,9 @@ void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { "lea 0x40(%0),%0 \n" \ "phaddw %%xmm0,%%xmm6 \n" \ "phaddw %%xmm2,%%xmm1 \n" \ - "paddw %%" #round \ - ",%%xmm6 \n" \ - "paddw %%" #round \ - ",%%xmm1 \n" \ + "prefetcht0 1280(%0) \n" \ + "paddw %%" #round ",%%xmm6 \n" \ + "paddw %%" #round ",%%xmm1 \n" \ "psrlw $0x8,%%xmm6 \n" \ "psrlw $0x8,%%xmm1 \n" \ "packuswb %%xmm1,%%xmm6 \n" \ @@ -1130,10 +1131,9 @@ void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { "lea 0x80(%0),%0 \n" \ "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" /* mutates. */ \ "vphaddw %%ymm3,%%ymm2,%%ymm2 \n" \ - "vpaddw %%" #round \ - ",%%ymm0,%%ymm0 \n" /* Add .5 for rounding. */ \ - "vpaddw %%" #round \ - ",%%ymm2,%%ymm2 \n" \ + "prefetcht0 1280(%0) \n" \ + "vpaddw %%" #round ",%%ymm0,%%ymm0 \n" /* Add .5 for rounding. */ \ + "vpaddw %%" #round ",%%ymm2,%%ymm2 \n" \ "vpsrlw $0x8,%%ymm0,%%ymm0 \n" \ "vpsrlw $0x8,%%ymm2,%%ymm2 \n" \ "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" /* mutates. */ \ @@ -1144,13 +1144,15 @@ void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { "jg 1b \n" \ "vzeroupper \n" +// clang-format on + #ifdef HAS_ARGBTOYROW_SSSE3 // Convert 16 ARGB pixels (64 bytes) to 16 Y values. void ARGBToYRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - "movdqa %5,%%xmm7 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" + "movdqa %5,%%xmm7 \n" LABELALIGN RGBTOY(xmm7) : "+r"(src_argb), // %0 @@ -1169,8 +1171,8 @@ void ARGBToYRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width) { // Same as ARGBToYRow but different coefficients, no add 16. void ARGBToYJRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" LABELALIGN RGBTOY(xmm5) : "+r"(src_argb), // %0 @@ -1187,8 +1189,8 @@ void ARGBToYJRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width) { // Same as ARGBToYRow but different coefficients, no add 16. void RGBAToYJRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width) { asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" LABELALIGN RGBTOY(xmm5) : "+r"(src_rgba), // %0 @@ -1210,7 +1212,7 @@ void ARGBToYRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width) { "vbroadcastf128 %3,%%ymm4 \n" "vbroadcastf128 %4,%%ymm5 \n" "vbroadcastf128 %5,%%ymm7 \n" - "vmovdqu %6,%%ymm6 \n" + "vmovdqu %6,%%ymm6 \n" LABELALIGN RGBTOY_AVX2(ymm7) : "+r"(src_argb), // %0 @@ -1232,7 +1234,7 @@ void ABGRToYRow_AVX2(const uint8_t* src_abgr, uint8_t* dst_y, int width) { "vbroadcastf128 %3,%%ymm4 \n" "vbroadcastf128 %4,%%ymm5 \n" "vbroadcastf128 %5,%%ymm7 \n" - "vmovdqu %6,%%ymm6 \n" + "vmovdqu %6,%%ymm6 \n" LABELALIGN RGBTOY_AVX2(ymm7) : "+r"(src_abgr), // %0 @@ -1253,7 +1255,7 @@ void ARGBToYJRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( "vbroadcastf128 %3,%%ymm4 \n" "vbroadcastf128 %4,%%ymm5 \n" - "vmovdqu %5,%%ymm6 \n" + "vmovdqu %5,%%ymm6 \n" LABELALIGN RGBTOY_AVX2(ymm5) : "+r"(src_argb), // %0 @@ -1273,7 +1275,7 @@ void RGBAToYJRow_AVX2(const uint8_t* src_rgba, uint8_t* dst_y, int width) { asm volatile( "vbroadcastf128 %3,%%ymm4 \n" "vbroadcastf128 %4,%%ymm5 \n" - "vmovdqu %5,%%ymm6 \n" + "vmovdqu %5,%%ymm6 \n" LABELALIGN RGBTOY_AVX2( ymm5) "vzeroupper \n" @@ -1294,52 +1296,52 @@ void ARGBToUVRow_SSSE3(const uint8_t* src_argb0, uint8_t* dst_v, int width) { asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" + "movdqa %5,%%xmm3 \n" + "movdqa %6,%%xmm4 \n" + "movdqa %7,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x10(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x20(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqu 0x30(%0),%%xmm6 \n" + "movdqu 0x30(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" - "lea 0x40(%0),%0 \n" - "movdqa %%xmm0,%%xmm7 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqa %%xmm2,%%xmm7 \n" - "shufps $0x88,%%xmm6,%%xmm2 \n" - "shufps $0xdd,%%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "phaddw %%xmm2,%%xmm0 \n" - "phaddw %%xmm6,%%xmm1 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm1 \n" - "packsswb %%xmm1,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movlps %%xmm0,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "lea 0x40(%0),%0 \n" + "movdqa %%xmm0,%%xmm7 \n" + "shufps $0x88,%%xmm1,%%xmm0 \n" + "shufps $0xdd,%%xmm1,%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqa %%xmm2,%%xmm7 \n" + "shufps $0x88,%%xmm6,%%xmm2 \n" + "shufps $0xdd,%%xmm6,%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm2,%%xmm6 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm3,%%xmm1 \n" + "pmaddubsw %%xmm3,%%xmm6 \n" + "phaddw %%xmm2,%%xmm0 \n" + "phaddw %%xmm6,%%xmm1 \n" + "psraw $0x8,%%xmm0 \n" + "psraw $0x8,%%xmm1 \n" + "packsswb %%xmm1,%%xmm0 \n" + "paddb %%xmm5,%%xmm0 \n" + "movlps %%xmm0,(%1) \n" + "movhps %%xmm0,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_argb0), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1366,44 +1368,44 @@ void ARGBToUVRow_AVX2(const uint8_t* src_argb0, "vbroadcastf128 %5,%%ymm5 \n" "vbroadcastf128 %6,%%ymm6 \n" "vbroadcastf128 %7,%%ymm7 \n" - "sub %1,%2 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" - "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" - "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" - "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" - "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" - "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" - "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vmovdqu 0x40(%0),%%ymm2 \n" + "vmovdqu 0x60(%0),%%ymm3 \n" + "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" + "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" + "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" + "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" + "lea 0x80(%0),%0 \n" + "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" + "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" + "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" + "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" + "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" + "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" - "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" - "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" - "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpsraw $0x8,%%ymm1,%%ymm1 \n" - "vpsraw $0x8,%%ymm0,%%ymm0 \n" - "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpshufb %8,%%ymm0,%%ymm0 \n" - "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" + "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" + "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" + "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" + "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" + "vpsraw $0x8,%%ymm1,%%ymm1 \n" + "vpsraw $0x8,%%ymm0,%%ymm0 \n" + "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpshufb %8,%%ymm0,%%ymm0 \n" + "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" "vextractf128 $0x0,%%ymm0,(%1) \n" "vextractf128 $0x1,%%ymm0,0x0(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "lea 0x10(%1),%1 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb0), // %0 "+r"(dst_u), // %1 @@ -1429,44 +1431,44 @@ void ABGRToUVRow_AVX2(const uint8_t* src_abgr0, "vbroadcastf128 %5,%%ymm5 \n" "vbroadcastf128 %6,%%ymm6 \n" "vbroadcastf128 %7,%%ymm7 \n" - "sub %1,%2 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" - "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" - "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" - "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" - "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" - "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" - "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vmovdqu 0x40(%0),%%ymm2 \n" + "vmovdqu 0x60(%0),%%ymm3 \n" + "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" + "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" + "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" + "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" + "lea 0x80(%0),%0 \n" + "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" + "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" + "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" + "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" + "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" + "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" - "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" - "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" - "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpsraw $0x8,%%ymm1,%%ymm1 \n" - "vpsraw $0x8,%%ymm0,%%ymm0 \n" - "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpshufb %8,%%ymm0,%%ymm0 \n" - "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" + "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" + "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" + "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" + "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" + "vpsraw $0x8,%%ymm1,%%ymm1 \n" + "vpsraw $0x8,%%ymm0,%%ymm0 \n" + "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpshufb %8,%%ymm0,%%ymm0 \n" + "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" "vextractf128 $0x0,%%ymm0,(%1) \n" "vextractf128 $0x1,%%ymm0,0x0(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "lea 0x10(%1),%1 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_abgr0), // %0 "+r"(dst_u), // %1 @@ -1492,45 +1494,45 @@ void ARGBToUVJRow_AVX2(const uint8_t* src_argb0, "vbroadcastf128 %5,%%ymm5 \n" "vbroadcastf128 %6,%%ymm6 \n" "vbroadcastf128 %7,%%ymm7 \n" - "sub %1,%2 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" - "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" - "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" - "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" - "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" - "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" - "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vmovdqu 0x40(%0),%%ymm2 \n" + "vmovdqu 0x60(%0),%%ymm3 \n" + "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" + "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" + "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" + "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" + "lea 0x80(%0),%0 \n" + "vshufps $0x88,%%ymm1,%%ymm0,%%ymm4 \n" + "vshufps $0xdd,%%ymm1,%%ymm0,%%ymm0 \n" + "vpavgb %%ymm4,%%ymm0,%%ymm0 \n" + "vshufps $0x88,%%ymm3,%%ymm2,%%ymm4 \n" + "vshufps $0xdd,%%ymm3,%%ymm2,%%ymm2 \n" + "vpavgb %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" - "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" - "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" - "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm5,%%ymm1,%%ymm1 \n" - "vpsraw $0x8,%%ymm1,%%ymm1 \n" - "vpsraw $0x8,%%ymm0,%%ymm0 \n" - "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpshufb %8,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm7,%%ymm0,%%ymm1 \n" + "vpmaddubsw %%ymm7,%%ymm2,%%ymm3 \n" + "vpmaddubsw %%ymm6,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm6,%%ymm2,%%ymm2 \n" + "vphaddw %%ymm3,%%ymm1,%%ymm1 \n" + "vphaddw %%ymm2,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm5,%%ymm1,%%ymm1 \n" + "vpsraw $0x8,%%ymm1,%%ymm1 \n" + "vpsraw $0x8,%%ymm0,%%ymm0 \n" + "vpacksswb %%ymm0,%%ymm1,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpshufb %8,%%ymm0,%%ymm0 \n" "vextractf128 $0x0,%%ymm0,(%1) \n" "vextractf128 $0x1,%%ymm0,0x0(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "lea 0x10(%1),%1 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb0), // %0 "+r"(dst_u), // %1 @@ -1553,53 +1555,53 @@ void ARGBToUVJRow_SSSE3(const uint8_t* src_argb0, uint8_t* dst_v, int width) { asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" + "movdqa %5,%%xmm3 \n" + "movdqa %6,%%xmm4 \n" + "movdqa %7,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x10(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x20(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqu 0x30(%0),%%xmm6 \n" + "movdqu 0x30(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" - "lea 0x40(%0),%0 \n" - "movdqa %%xmm0,%%xmm7 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqa %%xmm2,%%xmm7 \n" - "shufps $0x88,%%xmm6,%%xmm2 \n" - "shufps $0xdd,%%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "phaddw %%xmm2,%%xmm0 \n" - "phaddw %%xmm6,%%xmm1 \n" - "paddw %%xmm5,%%xmm0 \n" - "paddw %%xmm5,%%xmm1 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm1 \n" - "packsswb %%xmm1,%%xmm0 \n" - "movlps %%xmm0,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "lea 0x40(%0),%0 \n" + "movdqa %%xmm0,%%xmm7 \n" + "shufps $0x88,%%xmm1,%%xmm0 \n" + "shufps $0xdd,%%xmm1,%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqa %%xmm2,%%xmm7 \n" + "shufps $0x88,%%xmm6,%%xmm2 \n" + "shufps $0xdd,%%xmm6,%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm2,%%xmm6 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm3,%%xmm1 \n" + "pmaddubsw %%xmm3,%%xmm6 \n" + "phaddw %%xmm2,%%xmm0 \n" + "phaddw %%xmm6,%%xmm1 \n" + "paddw %%xmm5,%%xmm0 \n" + "paddw %%xmm5,%%xmm1 \n" + "psraw $0x8,%%xmm0 \n" + "psraw $0x8,%%xmm1 \n" + "packsswb %%xmm1,%%xmm0 \n" + "movlps %%xmm0,(%1) \n" + "movhps %%xmm0,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_argb0), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1618,47 +1620,47 @@ void ARGBToUV444Row_SSSE3(const uint8_t* src_argb, uint8_t* dst_v, int width) { asm volatile( - "movdqa %4,%%xmm3 \n" - "movdqa %5,%%xmm4 \n" - "movdqa %6,%%xmm5 \n" - "sub %1,%2 \n" + "movdqa %4,%%xmm3 \n" + "movdqa %5,%%xmm4 \n" + "movdqa %6,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm6 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm6,%%xmm2 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm2 \n" - "packsswb %%xmm2,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "pmaddubsw %%xmm3,%%xmm0 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm2 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm6,%%xmm2 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm2 \n" - "packsswb %%xmm2,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "lea 0x40(%0),%0 \n" - "movdqu %%xmm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x30(%0),%%xmm6 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm1 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm4,%%xmm6 \n" + "phaddw %%xmm1,%%xmm0 \n" + "phaddw %%xmm6,%%xmm2 \n" + "psraw $0x8,%%xmm0 \n" + "psraw $0x8,%%xmm2 \n" + "packsswb %%xmm2,%%xmm0 \n" + "paddb %%xmm5,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x30(%0),%%xmm6 \n" + "pmaddubsw %%xmm3,%%xmm0 \n" + "pmaddubsw %%xmm3,%%xmm1 \n" + "pmaddubsw %%xmm3,%%xmm2 \n" + "pmaddubsw %%xmm3,%%xmm6 \n" + "phaddw %%xmm1,%%xmm0 \n" + "phaddw %%xmm6,%%xmm2 \n" + "psraw $0x8,%%xmm0 \n" + "psraw $0x8,%%xmm2 \n" + "packsswb %%xmm2,%%xmm0 \n" + "paddb %%xmm5,%%xmm0 \n" + "lea 0x40(%0),%0 \n" + "movdqu %%xmm0,0x00(%1,%2,1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1672,9 +1674,9 @@ void ARGBToUV444Row_SSSE3(const uint8_t* src_argb, void BGRAToYRow_SSSE3(const uint8_t* src_bgra, uint8_t* dst_y, int width) { asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - "movdqa %5,%%xmm7 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" + "movdqa %5,%%xmm7 \n" LABELALIGN RGBTOY(xmm7) : "+r"(src_bgra), // %0 @@ -1693,52 +1695,52 @@ void BGRAToUVRow_SSSE3(const uint8_t* src_bgra0, uint8_t* dst_v, int width) { asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" + "movdqa %5,%%xmm3 \n" + "movdqa %6,%%xmm4 \n" + "movdqa %7,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x10(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x20(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqu 0x30(%0),%%xmm6 \n" + "movdqu 0x30(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" - "lea 0x40(%0),%0 \n" - "movdqa %%xmm0,%%xmm7 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqa %%xmm2,%%xmm7 \n" - "shufps $0x88,%%xmm6,%%xmm2 \n" - "shufps $0xdd,%%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "phaddw %%xmm2,%%xmm0 \n" - "phaddw %%xmm6,%%xmm1 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm1 \n" - "packsswb %%xmm1,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movlps %%xmm0,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "lea 0x40(%0),%0 \n" + "movdqa %%xmm0,%%xmm7 \n" + "shufps $0x88,%%xmm1,%%xmm0 \n" + "shufps $0xdd,%%xmm1,%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqa %%xmm2,%%xmm7 \n" + "shufps $0x88,%%xmm6,%%xmm2 \n" + "shufps $0xdd,%%xmm6,%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm2,%%xmm6 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm3,%%xmm1 \n" + "pmaddubsw %%xmm3,%%xmm6 \n" + "phaddw %%xmm2,%%xmm0 \n" + "phaddw %%xmm6,%%xmm1 \n" + "psraw $0x8,%%xmm0 \n" + "psraw $0x8,%%xmm1 \n" + "packsswb %%xmm1,%%xmm0 \n" + "paddb %%xmm5,%%xmm0 \n" + "movlps %%xmm0,(%1) \n" + "movhps %%xmm0,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_bgra0), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1752,9 +1754,9 @@ void BGRAToUVRow_SSSE3(const uint8_t* src_bgra0, void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width) { asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - "movdqa %5,%%xmm7 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" + "movdqa %5,%%xmm7 \n" LABELALIGN RGBTOY(xmm7) : "+r"(src_abgr), // %0 @@ -1769,9 +1771,9 @@ void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width) { void RGBAToYRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width) { asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - "movdqa %5,%%xmm7 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" + "movdqa %5,%%xmm7 \n" LABELALIGN RGBTOY(xmm7) : "+r"(src_rgba), // %0 @@ -1790,52 +1792,52 @@ void ABGRToUVRow_SSSE3(const uint8_t* src_abgr0, uint8_t* dst_v, int width) { asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" + "movdqa %5,%%xmm3 \n" + "movdqa %6,%%xmm4 \n" + "movdqa %7,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x10(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x20(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqu 0x30(%0),%%xmm6 \n" + "movdqu 0x30(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" - "lea 0x40(%0),%0 \n" - "movdqa %%xmm0,%%xmm7 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqa %%xmm2,%%xmm7 \n" - "shufps $0x88,%%xmm6,%%xmm2 \n" - "shufps $0xdd,%%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "phaddw %%xmm2,%%xmm0 \n" - "phaddw %%xmm6,%%xmm1 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm1 \n" - "packsswb %%xmm1,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movlps %%xmm0,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "lea 0x40(%0),%0 \n" + "movdqa %%xmm0,%%xmm7 \n" + "shufps $0x88,%%xmm1,%%xmm0 \n" + "shufps $0xdd,%%xmm1,%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqa %%xmm2,%%xmm7 \n" + "shufps $0x88,%%xmm6,%%xmm2 \n" + "shufps $0xdd,%%xmm6,%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm2,%%xmm6 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm3,%%xmm1 \n" + "pmaddubsw %%xmm3,%%xmm6 \n" + "phaddw %%xmm2,%%xmm0 \n" + "phaddw %%xmm6,%%xmm1 \n" + "psraw $0x8,%%xmm0 \n" + "psraw $0x8,%%xmm1 \n" + "packsswb %%xmm1,%%xmm0 \n" + "paddb %%xmm5,%%xmm0 \n" + "movlps %%xmm0,(%1) \n" + "movhps %%xmm0,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_abgr0), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1853,52 +1855,52 @@ void RGBAToUVRow_SSSE3(const uint8_t* src_rgba0, uint8_t* dst_v, int width) { asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" + "movdqa %5,%%xmm3 \n" + "movdqa %6,%%xmm4 \n" + "movdqa %7,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x10(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x20(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqu 0x30(%0),%%xmm6 \n" + "movdqu 0x30(%0,%4,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" - "lea 0x40(%0),%0 \n" - "movdqa %%xmm0,%%xmm7 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqa %%xmm2,%%xmm7 \n" - "shufps $0x88,%%xmm6,%%xmm2 \n" - "shufps $0xdd,%%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "phaddw %%xmm2,%%xmm0 \n" - "phaddw %%xmm6,%%xmm1 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm1 \n" - "packsswb %%xmm1,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movlps %%xmm0,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "lea 0x40(%0),%0 \n" + "movdqa %%xmm0,%%xmm7 \n" + "shufps $0x88,%%xmm1,%%xmm0 \n" + "shufps $0xdd,%%xmm1,%%xmm7 \n" + "pavgb %%xmm7,%%xmm0 \n" + "movdqa %%xmm2,%%xmm7 \n" + "shufps $0x88,%%xmm6,%%xmm2 \n" + "shufps $0xdd,%%xmm6,%%xmm7 \n" + "pavgb %%xmm7,%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm2,%%xmm6 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm3,%%xmm1 \n" + "pmaddubsw %%xmm3,%%xmm6 \n" + "phaddw %%xmm2,%%xmm0 \n" + "phaddw %%xmm6,%%xmm1 \n" + "psraw $0x8,%%xmm0 \n" + "psraw $0x8,%%xmm1 \n" + "packsswb %%xmm1,%%xmm0 \n" + "paddb %%xmm5,%%xmm0 \n" + "movlps %%xmm0,(%1) \n" + "movhps %%xmm0,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_rgba0), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -2115,16 +2117,16 @@ void OMITFP I444ToARGBRow_SSSE3(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" + "sub %[u_buf],%[v_buf] \n" + "pcmpeqb %%xmm5,%%xmm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUV444 YUVTORGB(yuvconstants) STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2144,27 +2146,27 @@ void OMITFP I422ToRGB24Row_SSSE3(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP(yuvconstants) - "movdqa %[kShuffleMaskARGBToRGB24_0],%%xmm5 \n" - "movdqa %[kShuffleMaskARGBToRGB24],%%xmm6 \n" - "sub %[u_buf],%[v_buf] \n" + "movdqa %[kShuffleMaskARGBToRGB24_0],%%xmm5 \n" + "movdqa %[kShuffleMaskARGBToRGB24],%%xmm6 \n" + "sub %[u_buf],%[v_buf] \n" LABELALIGN - "1: \n" + "1: \n" READYUV422 YUVTORGB(yuvconstants) - "punpcklbw %%xmm1,%%xmm0 \n" - "punpcklbw %%xmm2,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklwd %%xmm2,%%xmm0 \n" - "punpckhwd %%xmm2,%%xmm1 \n" - "pshufb %%xmm5,%%xmm0 \n" - "pshufb %%xmm6,%%xmm1 \n" - "palignr $0xc,%%xmm0,%%xmm1 \n" - "movq %%xmm0,(%[dst_rgb24]) \n" - "movdqu %%xmm1,0x8(%[dst_rgb24]) \n" - "lea 0x18(%[dst_rgb24]),%[dst_rgb24] \n" - "subl $0x8,%[width] \n" - "jg 1b \n" + "punpcklbw %%xmm1,%%xmm0 \n" + "punpcklbw %%xmm2,%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklwd %%xmm2,%%xmm0 \n" + "punpckhwd %%xmm2,%%xmm1 \n" + "pshufb %%xmm5,%%xmm0 \n" + "pshufb %%xmm6,%%xmm1 \n" + "palignr $0xc,%%xmm0,%%xmm1 \n" + "movq %%xmm0,(%[dst_rgb24]) \n" + "movdqu %%xmm1,0x8(%[dst_rgb24]) \n" + "lea 0x18(%[dst_rgb24]),%[dst_rgb24] \n" + "subl $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2190,16 +2192,16 @@ void OMITFP I422ToARGBRow_SSSE3(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" + "sub %[u_buf],%[v_buf] \n" + "pcmpeqb %%xmm5,%%xmm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUV422 YUVTORGB(yuvconstants) STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2219,21 +2221,21 @@ void OMITFP I422ToAR30Row_SSSE3(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" // AR30 constants - "psrlw $14,%%xmm5 \n" - "psllw $4,%%xmm5 \n" // 2 alpha bits - "pxor %%xmm6,%%xmm6 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" // 0 for min - "psrlw $6,%%xmm7 \n" // 1023 for max + "sub %[u_buf],%[v_buf] \n" + "pcmpeqb %%xmm5,%%xmm5 \n" // AR30 constants + "psrlw $14,%%xmm5 \n" + "psllw $4,%%xmm5 \n" // 2 alpha bits + "pxor %%xmm6,%%xmm6 \n" + "pcmpeqb %%xmm7,%%xmm7 \n" // 0 for min + "psrlw $6,%%xmm7 \n" // 1023 for max LABELALIGN - "1: \n" + "1: \n" READYUV422 YUVTORGB16(yuvconstants) STOREAR30 - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2254,16 +2256,16 @@ void OMITFP I210ToARGBRow_SSSE3(const uint16_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" + "sub %[u_buf],%[v_buf] \n" + "pcmpeqb %%xmm5,%%xmm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUV210 YUVTORGB(yuvconstants) STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2284,21 +2286,21 @@ void OMITFP I210ToAR30Row_SSSE3(const uint16_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $14,%%xmm5 \n" - "psllw $4,%%xmm5 \n" // 2 alpha bits - "pxor %%xmm6,%%xmm6 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" // 0 for min - "psrlw $6,%%xmm7 \n" // 1023 for max + "sub %[u_buf],%[v_buf] \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psrlw $14,%%xmm5 \n" + "psllw $4,%%xmm5 \n" // 2 alpha bits + "pxor %%xmm6,%%xmm6 \n" + "pcmpeqb %%xmm7,%%xmm7 \n" // 0 for min + "psrlw $6,%%xmm7 \n" // 1023 for max LABELALIGN - "1: \n" + "1: \n" READYUV210 YUVTORGB16(yuvconstants) STOREAR30 - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2321,15 +2323,15 @@ void OMITFP I422AlphaToARGBRow_SSSE3(const uint8_t* y_buf, // clang-format off asm volatile ( YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" + "sub %[u_buf],%[v_buf] \n" LABELALIGN - "1: \n" + "1: \n" READYUVA422 YUVTORGB(yuvconstants) STOREARGB - "subl $0x8,%[width] \n" - "jg 1b \n" + "subl $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2356,15 +2358,15 @@ void OMITFP NV12ToARGBRow_SSSE3(const uint8_t* y_buf, // clang-format off asm volatile ( YUVTORGB_SETUP(yuvconstants) - "pcmpeqb %%xmm5,%%xmm5 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" LABELALIGN - "1: \n" + "1: \n" READNV12 YUVTORGB(yuvconstants) STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [uv_buf]"+r"(uv_buf), // %[uv_buf] [dst_argb]"+r"(dst_argb), // %[dst_argb] @@ -2384,15 +2386,15 @@ void OMITFP NV21ToARGBRow_SSSE3(const uint8_t* y_buf, // clang-format off asm volatile ( YUVTORGB_SETUP(yuvconstants) - "pcmpeqb %%xmm5,%%xmm5 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" LABELALIGN - "1: \n" + "1: \n" READNV21 YUVTORGB(yuvconstants) STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [vu_buf]"+r"(vu_buf), // %[vu_buf] [dst_argb]"+r"(dst_argb), // %[dst_argb] @@ -2412,15 +2414,15 @@ void OMITFP YUY2ToARGBRow_SSSE3(const uint8_t* yuy2_buf, // clang-format off asm volatile ( YUVTORGB_SETUP(yuvconstants) - "pcmpeqb %%xmm5,%%xmm5 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUY2 YUVTORGB(yuvconstants) STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [yuy2_buf]"+r"(yuy2_buf), // %[yuy2_buf] [dst_argb]"+r"(dst_argb), // %[dst_argb] [width]"+rm"(width) // %[width] @@ -2440,15 +2442,15 @@ void OMITFP UYVYToARGBRow_SSSE3(const uint8_t* uyvy_buf, // clang-format off asm volatile ( YUVTORGB_SETUP(yuvconstants) - "pcmpeqb %%xmm5,%%xmm5 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" LABELALIGN - "1: \n" + "1: \n" READUYVY YUVTORGB(yuvconstants) STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [uyvy_buf]"+r"(uyvy_buf), // %[uyvy_buf] [dst_argb]"+r"(dst_argb), // %[dst_argb] [width]"+rm"(width) // %[width] @@ -2469,16 +2471,16 @@ void OMITFP I422ToRGBARow_SSSE3(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" + "sub %[u_buf],%[v_buf] \n" + "pcmpeqb %%xmm5,%%xmm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUV422 YUVTORGB(yuvconstants) STORERGBA - "sub $0x8,%[width] \n" - "jg 1b \n" + "sub $0x8,%[width] \n" + "jg 1b \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2693,17 +2695,17 @@ void OMITFP I444ToARGBRow_AVX2(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "sub %[u_buf],%[v_buf] \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUV444_AVX2 YUVTORGB_AVX2(yuvconstants) STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" + "sub $0x10,%[width] \n" + "jg 1b \n" + "vzeroupper \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2727,18 +2729,18 @@ void OMITFP I422ToARGBRow_AVX2(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "sub %[u_buf],%[v_buf] \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUV422_AVX2 YUVTORGB_AVX2(yuvconstants) STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" + "sub $0x10,%[width] \n" + "jg 1b \n" - "vzeroupper \n" + "vzeroupper \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2762,23 +2764,23 @@ void OMITFP I422ToAR30Row_AVX2(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" // AR30 constants - "vpsrlw $14,%%ymm5,%%ymm5 \n" - "vpsllw $4,%%ymm5,%%ymm5 \n" // 2 alpha bits - "vpxor %%ymm6,%%ymm6,%%ymm6 \n" // 0 for min - "vpcmpeqb %%ymm7,%%ymm7,%%ymm7 \n" // 1023 for max - "vpsrlw $6,%%ymm7,%%ymm7 \n" + "sub %[u_buf],%[v_buf] \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" // AR30 constants + "vpsrlw $14,%%ymm5,%%ymm5 \n" + "vpsllw $4,%%ymm5,%%ymm5 \n" // 2 alpha bits + "vpxor %%ymm6,%%ymm6,%%ymm6 \n" // 0 for min + "vpcmpeqb %%ymm7,%%ymm7,%%ymm7 \n" // 1023 for max + "vpsrlw $6,%%ymm7,%%ymm7 \n" LABELALIGN - "1: \n" + "1: \n" READYUV422_AVX2 YUVTORGB16_AVX2(yuvconstants) STOREAR30_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" + "sub $0x10,%[width] \n" + "jg 1b \n" - "vzeroupper \n" + "vzeroupper \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2802,18 +2804,18 @@ void OMITFP I210ToARGBRow_AVX2(const uint16_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "sub %[u_buf],%[v_buf] \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUV210_AVX2 YUVTORGB_AVX2(yuvconstants) STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" + "sub $0x10,%[width] \n" + "jg 1b \n" - "vzeroupper \n" + "vzeroupper \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2837,23 +2839,23 @@ void OMITFP I210ToAR30Row_AVX2(const uint16_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" // AR30 constants - "vpsrlw $14,%%ymm5,%%ymm5 \n" - "vpsllw $4,%%ymm5,%%ymm5 \n" // 2 alpha bits - "vpxor %%ymm6,%%ymm6,%%ymm6 \n" // 0 for min - "vpcmpeqb %%ymm7,%%ymm7,%%ymm7 \n" // 1023 for max - "vpsrlw $6,%%ymm7,%%ymm7 \n" + "sub %[u_buf],%[v_buf] \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" // AR30 constants + "vpsrlw $14,%%ymm5,%%ymm5 \n" + "vpsllw $4,%%ymm5,%%ymm5 \n" // 2 alpha bits + "vpxor %%ymm6,%%ymm6,%%ymm6 \n" // 0 for min + "vpcmpeqb %%ymm7,%%ymm7,%%ymm7 \n" // 1023 for max + "vpsrlw $6,%%ymm7,%%ymm7 \n" LABELALIGN - "1: \n" + "1: \n" READYUV210_AVX2 YUVTORGB16_AVX2(yuvconstants) STOREAR30_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" + "sub $0x10,%[width] \n" + "jg 1b \n" - "vzeroupper \n" + "vzeroupper \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2879,16 +2881,16 @@ void OMITFP I422AlphaToARGBRow_AVX2(const uint8_t* y_buf, // clang-format off asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" + "sub %[u_buf],%[v_buf] \n" LABELALIGN - "1: \n" + "1: \n" READYUVA422_AVX2 YUVTORGB_AVX2(yuvconstants) STOREARGB_AVX2 - "subl $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" + "subl $0x10,%[width] \n" + "jg 1b \n" + "vzeroupper \n" : [y_buf]"+r"(y_buf), // %[y_buf] [u_buf]"+r"(u_buf), // %[u_buf] [v_buf]"+r"(v_buf), // %[v_buf] @@ -2918,11 +2920,11 @@ void OMITFP I422ToRGBARow_AVX2(const uint8_t* y_buf, int width) { asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "sub %[u_buf],%[v_buf] \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUV422_AVX2 YUVTORGB_AVX2(yuvconstants) @@ -2962,16 +2964,16 @@ void OMITFP NV12ToARGBRow_AVX2(const uint8_t* y_buf, // clang-format off asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN - "1: \n" + "1: \n" READNV12_AVX2 YUVTORGB_AVX2(yuvconstants) STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" + "sub $0x10,%[width] \n" + "jg 1b \n" + "vzeroupper \n" : [y_buf]"+r"(y_buf), // %[y_buf] [uv_buf]"+r"(uv_buf), // %[uv_buf] [dst_argb]"+r"(dst_argb), // %[dst_argb] @@ -2995,16 +2997,16 @@ void OMITFP NV21ToARGBRow_AVX2(const uint8_t* y_buf, // clang-format off asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN - "1: \n" + "1: \n" READNV21_AVX2 YUVTORGB_AVX2(yuvconstants) STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" + "sub $0x10,%[width] \n" + "jg 1b \n" + "vzeroupper \n" : [y_buf]"+r"(y_buf), // %[y_buf] [vu_buf]"+r"(vu_buf), // %[vu_buf] [dst_argb]"+r"(dst_argb), // %[dst_argb] @@ -3028,16 +3030,16 @@ void OMITFP YUY2ToARGBRow_AVX2(const uint8_t* yuy2_buf, // clang-format off asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN - "1: \n" + "1: \n" READYUY2_AVX2 YUVTORGB_AVX2(yuvconstants) STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" + "sub $0x10,%[width] \n" + "jg 1b \n" + "vzeroupper \n" : [yuy2_buf]"+r"(yuy2_buf), // %[yuy2_buf] [dst_argb]"+r"(dst_argb), // %[dst_argb] [width]"+rm"(width) // %[width] @@ -3061,16 +3063,16 @@ void OMITFP UYVYToARGBRow_AVX2(const uint8_t* uyvy_buf, // clang-format off asm volatile ( YUVTORGB_SETUP_AVX2(yuvconstants) - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN - "1: \n" + "1: \n" READUYVY_AVX2 YUVTORGB_AVX2(yuvconstants) STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" + "sub $0x10,%[width] \n" + "jg 1b \n" + "vzeroupper \n" : [uyvy_buf]"+r"(uyvy_buf), // %[uyvy_buf] [dst_argb]"+r"(dst_argb), // %[dst_argb] [width]"+rm"(width) // %[width] @@ -3085,17 +3087,15 @@ void OMITFP UYVYToARGBRow_AVX2(const uint8_t* uyvy_buf, #endif // HAS_UYVYTOARGBROW_AVX2 #ifdef HAS_I400TOARGBROW_SSE2 -void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { +void I400ToARGBRow_SSE2(const uint8_t* y_buf, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { asm volatile( - "mov $0x4a354a35,%%eax \n" // 4a35 = 18997 = 1.164 - "movd %%eax,%%xmm2 \n" - "pshufd $0x0,%%xmm2,%%xmm2 \n" - "mov $0x04880488,%%eax \n" // 0488 = 1160 = 1.164 * - // 16 - "movd %%eax,%%xmm3 \n" - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "pslld $0x18,%%xmm4 \n" + "movdqa 192(%3),%%xmm2 \n" // yg = 18997 = 1.164 + "movdqa 224(%3),%%xmm3 \n" // ygb = 1160 = 1.164 * 16 + "pcmpeqb %%xmm4,%%xmm4 \n" // 0xff000000 + "pslld $0x18,%%xmm4 \n" LABELALIGN "1: \n" @@ -3104,8 +3104,8 @@ void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { "lea 0x8(%0),%0 \n" "punpcklbw %%xmm0,%%xmm0 \n" "pmulhuw %%xmm2,%%xmm0 \n" - "psubusw %%xmm3,%%xmm0 \n" - "psrlw $6, %%xmm0 \n" + "paddsw %%xmm3,%%xmm0 \n" + "psraw $6, %%xmm0 \n" "packuswb %%xmm0,%%xmm0 \n" // Step 2: Weave into ARGB @@ -3121,28 +3121,26 @@ void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { "sub $0x8,%2 \n" "jg 1b \n" - : "+r"(y_buf), // %0 - "+r"(dst_argb), // %1 - "+rm"(width) // %2 - : - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); + : "+r"(y_buf), // %0 + "+r"(dst_argb), // %1 + "+rm"(width) // %2 + : "r"(yuvconstants) // %3 + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); } #endif // HAS_I400TOARGBROW_SSE2 #ifdef HAS_I400TOARGBROW_AVX2 // 16 pixels of Y converted to 16 pixels of ARGB (64 bytes). // note: vpunpcklbw mutates and vpackuswb unmutates. -void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { +void I400ToARGBRow_AVX2(const uint8_t* y_buf, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { asm volatile( - "mov $0x4a354a35,%%eax \n" // 0488 = 1160 = 1.164 * - // 16 - "vmovd %%eax,%%xmm2 \n" - "vbroadcastss %%xmm2,%%ymm2 \n" - "mov $0x4880488,%%eax \n" // 4a35 = 18997 = 1.164 - "vmovd %%eax,%%xmm3 \n" - "vbroadcastss %%xmm3,%%ymm3 \n" - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpslld $0x18,%%ymm4,%%ymm4 \n" + "vmovdqa 192(%3),%%ymm2 \n" // yg = 18997 = 1.164 + "vmovdqa 224(%3),%%ymm3 \n" // ygb = -1160 = 1.164*16 + "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" // 0xff000000 + "vpslld $0x18,%%ymm4,%%ymm4 \n" LABELALIGN "1: \n" @@ -3152,8 +3150,8 @@ void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { "vpermq $0xd8,%%ymm0,%%ymm0 \n" "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpsubusw %%ymm3,%%ymm0,%%ymm0 \n" - "vpsrlw $0x6,%%ymm0,%%ymm0 \n" + "vpaddsw %%ymm3,%%ymm0,%%ymm0 \n" + "vpsraw $0x6,%%ymm0,%%ymm0 \n" "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" "vpunpcklbw %%ymm0,%%ymm0,%%ymm1 \n" "vpermq $0xd8,%%ymm1,%%ymm1 \n" @@ -3163,15 +3161,15 @@ void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { "vpor %%ymm4,%%ymm1,%%ymm1 \n" "vmovdqu %%ymm0,(%1) \n" "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" + "lea 0x40(%1),%1 \n" "sub $0x10,%2 \n" "jg 1b \n" "vzeroupper \n" - : "+r"(y_buf), // %0 - "+r"(dst_argb), // %1 - "+rm"(width) // %2 - : - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); + : "+r"(y_buf), // %0 + "+r"(dst_argb), // %1 + "+rm"(width) // %2 + : "r"(yuvconstants) // %3 + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); } #endif // HAS_I400TOARGBROW_AVX2 @@ -3184,16 +3182,16 @@ void MirrorRow_SSSE3(const uint8_t* src, uint8_t* dst, int width) { intptr_t temp_width = (intptr_t)(width); asm volatile( - "movdqa %3,%%xmm5 \n" + "movdqa %3,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu -0x10(%0,%2,1),%%xmm0 \n" - "pshufb %%xmm5,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu -0x10(%0,%2,1),%%xmm0 \n" + "pshufb %%xmm5,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(temp_width) // %2 @@ -3211,13 +3209,13 @@ void MirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { LABELALIGN "1: \n" - "vmovdqu -0x20(%0,%2,1),%%ymm0 \n" - "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" - "vpermq $0x4e,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu -0x20(%0,%2,1),%%ymm0 \n" + "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" + "vpermq $0x4e,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -3228,55 +3226,154 @@ void MirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { #endif // HAS_MIRRORROW_AVX2 #ifdef HAS_MIRRORUVROW_SSSE3 -// Shuffle table for reversing the bytes of UV channels. -static const uvec8 kShuffleMirrorUV = {14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, - 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u}; -void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +// Shuffle table for reversing the UV. +static const uvec8 kShuffleMirrorUV = {14u, 15u, 12u, 13u, 10u, 11u, 8u, 9u, + 6u, 7u, 4u, 5u, 2u, 3u, 0u, 1u}; + +void MirrorUVRow_SSSE3(const uint8_t* src_uv, uint8_t* dst_uv, int width) { intptr_t temp_width = (intptr_t)(width); asm volatile( - "movdqa %4,%%xmm1 \n" - "lea -0x10(%0,%3,2),%0 \n" - "sub %1,%2 \n" + + "movdqa %3,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea -0x10(%0),%0 \n" - "pshufb %%xmm1,%%xmm0 \n" - "movlpd %%xmm0,(%1) \n" - "movhpd %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $8,%3 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(temp_width) // %3 - : "m"(kShuffleMirrorUV) // %4 - : "memory", "cc", "xmm0", "xmm1"); + "movdqu -0x10(%0,%2,2),%%xmm0 \n" + "pshufb %%xmm5,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" + : "+r"(src_uv), // %0 + "+r"(dst_uv), // %1 + "+r"(temp_width) // %2 + : "m"(kShuffleMirrorUV) // %3 + : "memory", "cc", "xmm0", "xmm5"); } #endif // HAS_MIRRORUVROW_SSSE3 +#ifdef HAS_MIRRORUVROW_AVX2 +void MirrorUVRow_AVX2(const uint8_t* src_uv, uint8_t* dst_uv, int width) { + intptr_t temp_width = (intptr_t)(width); + asm volatile( + + "vbroadcastf128 %3,%%ymm5 \n" + + LABELALIGN + "1: \n" + "vmovdqu -0x20(%0,%2,2),%%ymm0 \n" + "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" + "vpermq $0x4e,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" + "vzeroupper \n" + : "+r"(src_uv), // %0 + "+r"(dst_uv), // %1 + "+r"(temp_width) // %2 + : "m"(kShuffleMirrorUV) // %3 + : "memory", "cc", "xmm0", "xmm5"); +} +#endif // HAS_MIRRORUVROW_AVX2 + +#ifdef HAS_MIRRORSPLITUVROW_SSSE3 +// Shuffle table for reversing the bytes of UV channels. +static const uvec8 kShuffleMirrorSplitUV = {14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, + 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u}; +void MirrorSplitUVRow_SSSE3(const uint8_t* src, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + intptr_t temp_width = (intptr_t)(width); + asm volatile( + "movdqa %4,%%xmm1 \n" + "lea -0x10(%0,%3,2),%0 \n" + "sub %1,%2 \n" + + LABELALIGN + "1: \n" + "movdqu (%0),%%xmm0 \n" + "lea -0x10(%0),%0 \n" + "pshufb %%xmm1,%%xmm0 \n" + "movlpd %%xmm0,(%1) \n" + "movhpd %%xmm0,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $8,%3 \n" + "jg 1b \n" + : "+r"(src), // %0 + "+r"(dst_u), // %1 + "+r"(dst_v), // %2 + "+r"(temp_width) // %3 + : "m"(kShuffleMirrorSplitUV) // %4 + : "memory", "cc", "xmm0", "xmm1"); +} +#endif // HAS_MIRRORSPLITUVROW_SSSE3 + +#ifdef HAS_RGB24MIRRORROW_SSSE3 + +// Shuffle first 5 pixels to last 5 mirrored. first byte zero +static const uvec8 kShuffleMirrorRGB0 = {128u, 12u, 13u, 14u, 9u, 10u, 11u, 6u, + 7u, 8u, 3u, 4u, 5u, 0u, 1u, 2u}; + +// Shuffle last 5 pixels to first 5 mirrored. last byte zero +static const uvec8 kShuffleMirrorRGB1 = { + 13u, 14u, 15u, 10u, 11u, 12u, 7u, 8u, 9u, 4u, 5u, 6u, 1u, 2u, 3u, 128u}; + +// Shuffle 5 pixels at a time (15 bytes) +void RGB24MirrorRow_SSSE3(const uint8_t* src_rgb24, + uint8_t* dst_rgb24, + int width) { + intptr_t temp_width = (intptr_t)(width); + src_rgb24 += width * 3 - 48; + asm volatile( + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" + + LABELALIGN + "1: \n" + "movdqu (%0),%%xmm0 \n" // first 5 + "movdqu 15(%0),%%xmm1 \n" // next 5 + "movdqu 30(%0),%%xmm2 \n" // next 5 + "movdqu 32(%0),%%xmm3 \n" // last 1 special + "pshufb %%xmm4,%%xmm0 \n" + "pshufb %%xmm4,%%xmm1 \n" + "pshufb %%xmm4,%%xmm2 \n" + "pshufb %%xmm5,%%xmm3 \n" + "lea -0x30(%0),%0 \n" + "movdqu %%xmm0,32(%1) \n" // last 5 + "movdqu %%xmm1,17(%1) \n" // next 5 + "movdqu %%xmm2,2(%1) \n" // next 5 + "movlpd %%xmm3,0(%1) \n" // first 1 + "lea 0x30(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" + : "+r"(src_rgb24), // %0 + "+r"(dst_rgb24), // %1 + "+r"(temp_width) // %2 + : "m"(kShuffleMirrorRGB0), // %3 + "m"(kShuffleMirrorRGB1) // %4 + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); +} +#endif // HAS_RGB24MIRRORROW_SSSE3 + #ifdef HAS_ARGBMIRRORROW_SSE2 void ARGBMirrorRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { intptr_t temp_width = (intptr_t)(width); asm volatile( - "lea -0x10(%0,%2,4),%0 \n" + "lea -0x10(%0,%2,4),%0 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "pshufd $0x1b,%%xmm0,%%xmm0 \n" - "lea -0x10(%0),%0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "pshufd $0x1b,%%xmm0,%%xmm0 \n" + "lea -0x10(%0),%0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(temp_width) // %2 @@ -3292,15 +3389,15 @@ void ARGBMirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { intptr_t temp_width = (intptr_t)(width); asm volatile( - "vmovdqu %3,%%ymm5 \n" + "vmovdqu %3,%%ymm5 \n" LABELALIGN "1: \n" - "vpermd -0x20(%0,%2,4),%%ymm5,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "vpermd -0x20(%0,%2,4),%%ymm5,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -3316,28 +3413,28 @@ void SplitUVRow_AVX2(const uint8_t* src_uv, uint8_t* dst_v, int width) { asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpsrlw $0x8,%%ymm5,%%ymm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm2 \n" - "vpsrlw $0x8,%%ymm1,%%ymm3 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm3,%%ymm2,%%ymm2 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm2,0x00(%1,%2,1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpsrlw $0x8,%%ymm0,%%ymm2 \n" + "vpsrlw $0x8,%%ymm1,%%ymm3 \n" + "vpand %%ymm5,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm3,%%ymm2,%%ymm2 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm2,%%ymm2 \n" + "vmovdqu %%ymm0,(%1) \n" + "vmovdqu %%ymm2,0x00(%1,%2,1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_uv), // %0 "+r"(dst_u), // %1 @@ -3354,28 +3451,28 @@ void SplitUVRow_SSE2(const uint8_t* src_uv, uint8_t* dst_v, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psrlw $0x8,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "movdqa %%xmm1,%%xmm3 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "psrlw $0x8,%%xmm2 \n" - "psrlw $0x8,%%xmm3 \n" - "packuswb %%xmm3,%%xmm2 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm2,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "movdqa %%xmm0,%%xmm2 \n" + "movdqa %%xmm1,%%xmm3 \n" + "pand %%xmm5,%%xmm0 \n" + "pand %%xmm5,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "psrlw $0x8,%%xmm2 \n" + "psrlw $0x8,%%xmm3 \n" + "packuswb %%xmm3,%%xmm2 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu %%xmm2,0x00(%1,%2,1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_uv), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -3392,22 +3489,22 @@ void MergeUVRow_AVX2(const uint8_t* src_u, int width) { asm volatile( - "sub %0,%1 \n" + "sub %0,%1 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x00(%0,%1,1),%%ymm1 \n" - "lea 0x20(%0),%0 \n" - "vpunpcklbw %%ymm1,%%ymm0,%%ymm2 \n" - "vpunpckhbw %%ymm1,%%ymm0,%%ymm0 \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x00(%0,%1,1),%%ymm1 \n" + "lea 0x20(%0),%0 \n" + "vpunpcklbw %%ymm1,%%ymm0,%%ymm2 \n" + "vpunpckhbw %%ymm1,%%ymm0,%%ymm0 \n" "vextractf128 $0x0,%%ymm2,(%2) \n" "vextractf128 $0x0,%%ymm0,0x10(%2) \n" "vextractf128 $0x1,%%ymm2,0x20(%2) \n" "vextractf128 $0x1,%%ymm0,0x30(%2) \n" - "lea 0x40(%2),%2 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "lea 0x40(%2),%2 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_u), // %0 "+r"(src_v), // %1 @@ -3425,21 +3522,21 @@ void MergeUVRow_SSE2(const uint8_t* src_u, int width) { asm volatile( - "sub %0,%1 \n" + "sub %0,%1 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%1,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "punpcklbw %%xmm1,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm2 \n" - "movdqu %%xmm0,(%2) \n" - "movdqu %%xmm2,0x10(%2) \n" - "lea 0x20(%2),%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%1,1),%%xmm1 \n" + "lea 0x10(%0),%0 \n" + "movdqa %%xmm0,%%xmm2 \n" + "punpcklbw %%xmm1,%%xmm0 \n" + "punpckhbw %%xmm1,%%xmm2 \n" + "movdqu %%xmm0,(%2) \n" + "movdqu %%xmm2,0x10(%2) \n" + "lea 0x20(%2),%2 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_u), // %0 "+r"(src_v), // %1 "+r"(dst_uv), // %2 @@ -3462,30 +3559,30 @@ void MergeUVRow_16_AVX2(const uint16_t* src_u, int width) { // clang-format off asm volatile ( - "vmovd %4,%%xmm3 \n" - "vpunpcklwd %%xmm3,%%xmm3,%%xmm3 \n" - "vbroadcastss %%xmm3,%%ymm3 \n" - "sub %0,%1 \n" + "vmovd %4,%%xmm3 \n" + "vpunpcklwd %%xmm3,%%xmm3,%%xmm3 \n" + "vbroadcastss %%xmm3,%%ymm3 \n" + "sub %0,%1 \n" // 16 pixels per loop. LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu (%0,%1,1),%%ymm1 \n" - "add $0x20,%0 \n" + "1: \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu (%0,%1,1),%%ymm1 \n" + "add $0x20,%0 \n" - "vpmullw %%ymm3,%%ymm0,%%ymm0 \n" - "vpmullw %%ymm3,%%ymm1,%%ymm1 \n" - "vpunpcklwd %%ymm1,%%ymm0,%%ymm2 \n" // mutates - "vpunpckhwd %%ymm1,%%ymm0,%%ymm0 \n" - "vextractf128 $0x0,%%ymm2,(%2) \n" - "vextractf128 $0x0,%%ymm0,0x10(%2) \n" - "vextractf128 $0x1,%%ymm2,0x20(%2) \n" - "vextractf128 $0x1,%%ymm0,0x30(%2) \n" - "add $0x40,%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - "vzeroupper \n" + "vpmullw %%ymm3,%%ymm0,%%ymm0 \n" + "vpmullw %%ymm3,%%ymm1,%%ymm1 \n" + "vpunpcklwd %%ymm1,%%ymm0,%%ymm2 \n" // mutates + "vpunpckhwd %%ymm1,%%ymm0,%%ymm0 \n" + "vextractf128 $0x0,%%ymm2,(%2) \n" + "vextractf128 $0x0,%%ymm0,0x10(%2) \n" + "vextractf128 $0x1,%%ymm2,0x20(%2) \n" + "vextractf128 $0x1,%%ymm0,0x30(%2) \n" + "add $0x40,%2 \n" + "sub $0x10,%3 \n" + "jg 1b \n" + "vzeroupper \n" : "+r"(src_u), // %0 "+r"(src_v), // %1 "+r"(dst_uv), // %2 @@ -3508,24 +3605,24 @@ void MultiplyRow_16_AVX2(const uint16_t* src_y, int width) { // clang-format off asm volatile ( - "vmovd %3,%%xmm3 \n" - "vpunpcklwd %%xmm3,%%xmm3,%%xmm3 \n" - "vbroadcastss %%xmm3,%%ymm3 \n" - "sub %0,%1 \n" + "vmovd %3,%%xmm3 \n" + "vpunpcklwd %%xmm3,%%xmm3,%%xmm3 \n" + "vbroadcastss %%xmm3,%%ymm3 \n" + "sub %0,%1 \n" // 16 pixels per loop. LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vpmullw %%ymm3,%%ymm0,%%ymm0 \n" - "vpmullw %%ymm3,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm0,(%0,%1) \n" - "vmovdqu %%ymm1,0x20(%0,%1) \n" - "add $0x40,%0 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" + "1: \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vpmullw %%ymm3,%%ymm0,%%ymm0 \n" + "vpmullw %%ymm3,%%ymm1,%%ymm1 \n" + "vmovdqu %%ymm0,(%0,%1) \n" + "vmovdqu %%ymm1,0x20(%0,%1) \n" + "add $0x40,%0 \n" + "sub $0x20,%2 \n" + "jg 1b \n" + "vzeroupper \n" : "+r"(src_y), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -3546,23 +3643,23 @@ void Convert16To8Row_SSSE3(const uint16_t* src_y, int width) { // clang-format off asm volatile ( - "movd %3,%%xmm2 \n" - "punpcklwd %%xmm2,%%xmm2 \n" - "pshufd $0x0,%%xmm2,%%xmm2 \n" + "movd %3,%%xmm2 \n" + "punpcklwd %%xmm2,%%xmm2 \n" + "pshufd $0x0,%%xmm2,%%xmm2 \n" // 32 pixels per loop. LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "add $0x20,%0 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "add $0x10,%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "1: \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "add $0x20,%0 \n" + "pmulhuw %%xmm2,%%xmm0 \n" + "pmulhuw %%xmm2,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "add $0x10,%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_y), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -3578,25 +3675,25 @@ void Convert16To8Row_AVX2(const uint16_t* src_y, int width) { // clang-format off asm volatile ( - "vmovd %3,%%xmm2 \n" - "vpunpcklwd %%xmm2,%%xmm2,%%xmm2 \n" - "vbroadcastss %%xmm2,%%ymm2 \n" + "vmovd %3,%%xmm2 \n" + "vpunpcklwd %%xmm2,%%xmm2,%%xmm2 \n" + "vbroadcastss %%xmm2,%%ymm2 \n" // 32 pixels per loop. LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "add $0x40,%0 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm2,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" // mutates - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "add $0x20,%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" + "1: \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "add $0x40,%0 \n" + "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" + "vpmulhuw %%ymm2,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" // mutates + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "add $0x20,%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" + "vzeroupper \n" : "+r"(src_y), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -3617,25 +3714,25 @@ void Convert8To16Row_SSE2(const uint8_t* src_y, int width) { // clang-format off asm volatile ( - "movd %3,%%xmm2 \n" - "punpcklwd %%xmm2,%%xmm2 \n" - "pshufd $0x0,%%xmm2,%%xmm2 \n" + "movd %3,%%xmm2 \n" + "punpcklwd %%xmm2,%%xmm2 \n" + "pshufd $0x0,%%xmm2,%%xmm2 \n" // 32 pixels per loop. LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "add $0x10,%0 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "add $0x20,%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "1: \n" + "movdqu (%0),%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklbw %%xmm0,%%xmm0 \n" + "punpckhbw %%xmm1,%%xmm1 \n" + "add $0x10,%0 \n" + "pmulhuw %%xmm2,%%xmm0 \n" + "pmulhuw %%xmm2,%%xmm1 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu %%xmm1,0x10(%1) \n" + "add $0x20,%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_y), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -3651,26 +3748,26 @@ void Convert8To16Row_AVX2(const uint8_t* src_y, int width) { // clang-format off asm volatile ( - "vmovd %3,%%xmm2 \n" - "vpunpcklwd %%xmm2,%%xmm2,%%xmm2 \n" - "vbroadcastss %%xmm2,%%ymm2 \n" + "vmovd %3,%%xmm2 \n" + "vpunpcklwd %%xmm2,%%xmm2,%%xmm2 \n" + "vbroadcastss %%xmm2,%%ymm2 \n" // 32 pixels per loop. LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "add $0x20,%0 \n" - "vpunpckhbw %%ymm0,%%ymm0,%%ymm1 \n" - "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm2,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "add $0x40,%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" + "1: \n" + "vmovdqu (%0),%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "add $0x20,%0 \n" + "vpunpckhbw %%ymm0,%%ymm0,%%ymm1 \n" + "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" + "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" + "vpmulhuw %%ymm2,%%ymm1,%%ymm1 \n" + "vmovdqu %%ymm0,(%1) \n" + "vmovdqu %%ymm1,0x20(%1) \n" + "add $0x40,%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" + "vzeroupper \n" : "+r"(src_y), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -3722,41 +3819,41 @@ void SplitRGBRow_SSSE3(const uint8_t* src_rgb, LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "pshufb %5, %%xmm0 \n" - "pshufb %6, %%xmm1 \n" - "pshufb %7, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "pshufb %5, %%xmm0 \n" + "pshufb %6, %%xmm1 \n" + "pshufb %7, %%xmm2 \n" + "por %%xmm1,%%xmm0 \n" + "por %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "pshufb %8, %%xmm0 \n" - "pshufb %9, %%xmm1 \n" - "pshufb %10, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "pshufb %8, %%xmm0 \n" + "pshufb %9, %%xmm1 \n" + "pshufb %10, %%xmm2 \n" + "por %%xmm1,%%xmm0 \n" + "por %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "pshufb %11, %%xmm0 \n" - "pshufb %12, %%xmm1 \n" - "pshufb %13, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%3) \n" - "lea 0x10(%3),%3 \n" - "lea 0x30(%0),%0 \n" - "sub $0x10,%4 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "pshufb %11, %%xmm0 \n" + "pshufb %12, %%xmm1 \n" + "pshufb %13, %%xmm2 \n" + "por %%xmm1,%%xmm0 \n" + "por %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%3) \n" + "lea 0x10(%3),%3 \n" + "lea 0x30(%0),%0 \n" + "sub $0x10,%4 \n" + "jg 1b \n" : "+r"(src_rgb), // %0 "+r"(dst_r), // %1 "+r"(dst_g), // %2 @@ -3817,42 +3914,42 @@ void MergeRGBRow_SSSE3(const uint8_t* src_r, LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu (%1),%%xmm1 \n" - "movdqu (%2),%%xmm2 \n" - "pshufb %5, %%xmm0 \n" - "pshufb %6, %%xmm1 \n" - "pshufb %7, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%3) \n" + "movdqu (%0),%%xmm0 \n" + "movdqu (%1),%%xmm1 \n" + "movdqu (%2),%%xmm2 \n" + "pshufb %5, %%xmm0 \n" + "pshufb %6, %%xmm1 \n" + "pshufb %7, %%xmm2 \n" + "por %%xmm1,%%xmm0 \n" + "por %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%3) \n" - "movdqu (%0),%%xmm0 \n" - "movdqu (%1),%%xmm1 \n" - "movdqu (%2),%%xmm2 \n" - "pshufb %8, %%xmm0 \n" - "pshufb %9, %%xmm1 \n" - "pshufb %10, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,16(%3) \n" + "movdqu (%0),%%xmm0 \n" + "movdqu (%1),%%xmm1 \n" + "movdqu (%2),%%xmm2 \n" + "pshufb %8, %%xmm0 \n" + "pshufb %9, %%xmm1 \n" + "pshufb %10, %%xmm2 \n" + "por %%xmm1,%%xmm0 \n" + "por %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,16(%3) \n" - "movdqu (%0),%%xmm0 \n" - "movdqu (%1),%%xmm1 \n" - "movdqu (%2),%%xmm2 \n" - "pshufb %11, %%xmm0 \n" - "pshufb %12, %%xmm1 \n" - "pshufb %13, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,32(%3) \n" + "movdqu (%0),%%xmm0 \n" + "movdqu (%1),%%xmm1 \n" + "movdqu (%2),%%xmm2 \n" + "pshufb %11, %%xmm0 \n" + "pshufb %12, %%xmm1 \n" + "pshufb %13, %%xmm2 \n" + "por %%xmm1,%%xmm0 \n" + "por %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,32(%3) \n" - "lea 0x10(%0),%0 \n" - "lea 0x10(%1),%1 \n" - "lea 0x10(%2),%2 \n" - "lea 0x30(%3),%3 \n" - "sub $0x10,%4 \n" - "jg 1b \n" + "lea 0x10(%0),%0 \n" + "lea 0x10(%1),%1 \n" + "lea 0x10(%2),%2 \n" + "lea 0x30(%3),%3 \n" + "sub $0x10,%4 \n" + "jg 1b \n" : "+r"(src_r), // %0 "+r"(src_g), // %1 "+r"(src_b), // %2 @@ -3874,35 +3971,35 @@ void MergeRGBRow_SSSE3(const uint8_t* src_r, #ifdef HAS_COPYROW_SSE2 void CopyRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "test $0xf,%0 \n" - "jne 2f \n" - "test $0xf,%1 \n" - "jne 2f \n" + "test $0xf,%0 \n" + "jne 2f \n" + "test $0xf,%1 \n" + "jne 2f \n" LABELALIGN "1: \n" - "movdqa (%0),%%xmm0 \n" - "movdqa 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "movdqa %%xmm0,(%1) \n" - "movdqa %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "jmp 9f \n" + "movdqa (%0),%%xmm0 \n" + "movdqa 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "movdqa %%xmm0,(%1) \n" + "movdqa %%xmm1,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" + "jmp 9f \n" LABELALIGN "2: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 2b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu %%xmm1,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 2b \n" - LABELALIGN "9: \n" + LABELALIGN "9: \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -3917,14 +4014,14 @@ void CopyRow_AVX(const uint8_t* src, uint8_t* dst, int width) { LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x40,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vmovdqu %%ymm0,(%1) \n" + "vmovdqu %%ymm1,0x20(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x40,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -3939,7 +4036,7 @@ void CopyRow_ERMS(const uint8_t* src, uint8_t* dst, int width) { size_t width_tmp = (size_t)(width); asm volatile( - "rep movsb \n" + "rep movsb \n" : "+S"(src), // %0 "+D"(dst), // %1 "+c"(width_tmp) // %2 @@ -3952,29 +4049,29 @@ void CopyRow_ERMS(const uint8_t* src, uint8_t* dst, int width) { // width in pixels void ARGBCopyAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "pcmpeqb %%xmm0,%%xmm0 \n" - "pslld $0x18,%%xmm0 \n" - "pcmpeqb %%xmm1,%%xmm1 \n" - "psrld $0x8,%%xmm1 \n" + "pcmpeqb %%xmm0,%%xmm0 \n" + "pslld $0x18,%%xmm0 \n" + "pcmpeqb %%xmm1,%%xmm1 \n" + "psrld $0x8,%%xmm1 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm2 \n" - "movdqu 0x10(%0),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "movdqu (%1),%%xmm4 \n" - "movdqu 0x10(%1),%%xmm5 \n" - "pand %%xmm0,%%xmm2 \n" - "pand %%xmm0,%%xmm3 \n" - "pand %%xmm1,%%xmm4 \n" - "pand %%xmm1,%%xmm5 \n" - "por %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm2,(%1) \n" - "movdqu %%xmm3,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm2 \n" + "movdqu 0x10(%0),%%xmm3 \n" + "lea 0x20(%0),%0 \n" + "movdqu (%1),%%xmm4 \n" + "movdqu 0x10(%1),%%xmm5 \n" + "pand %%xmm0,%%xmm2 \n" + "pand %%xmm0,%%xmm3 \n" + "pand %%xmm1,%%xmm4 \n" + "pand %%xmm1,%%xmm5 \n" + "por %%xmm4,%%xmm2 \n" + "por %%xmm5,%%xmm3 \n" + "movdqu %%xmm2,(%1) \n" + "movdqu %%xmm3,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -3987,21 +4084,21 @@ void ARGBCopyAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { // width in pixels void ARGBCopyAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" - "vpsrld $0x8,%%ymm0,%%ymm0 \n" + "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" + "vpsrld $0x8,%%ymm0,%%ymm0 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm1 \n" - "vmovdqu 0x20(%0),%%ymm2 \n" - "lea 0x40(%0),%0 \n" - "vpblendvb %%ymm0,(%1),%%ymm1,%%ymm1 \n" - "vpblendvb %%ymm0,0x20(%1),%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm1,(%1) \n" - "vmovdqu %%ymm2,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm1 \n" + "vmovdqu 0x20(%0),%%ymm2 \n" + "lea 0x40(%0),%0 \n" + "vpblendvb %%ymm0,(%1),%%ymm1,%%ymm1 \n" + "vpblendvb %%ymm0,0x20(%1),%%ymm2,%%ymm2 \n" + "vmovdqu %%ymm1,(%1) \n" + "vmovdqu %%ymm2,0x20(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -4020,17 +4117,17 @@ void ARGBExtractAlphaRow_SSE2(const uint8_t* src_argb, LABELALIGN "1: \n" - "movdqu (%0), %%xmm0 \n" - "movdqu 0x10(%0), %%xmm1 \n" - "lea 0x20(%0), %0 \n" - "psrld $0x18, %%xmm0 \n" - "psrld $0x18, %%xmm1 \n" - "packssdw %%xmm1, %%xmm0 \n" - "packuswb %%xmm0, %%xmm0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1), %1 \n" - "sub $0x8, %2 \n" - "jg 1b \n" + "movdqu (%0), %%xmm0 \n" + "movdqu 0x10(%0), %%xmm1 \n" + "lea 0x20(%0), %0 \n" + "psrld $0x18, %%xmm0 \n" + "psrld $0x18, %%xmm1 \n" + "packssdw %%xmm1, %%xmm0 \n" + "packuswb %%xmm0, %%xmm0 \n" + "movq %%xmm0,(%1) \n" + "lea 0x8(%1), %1 \n" + "sub $0x8, %2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_a), // %1 "+rm"(width) // %2 @@ -4048,28 +4145,28 @@ void ARGBExtractAlphaRow_AVX2(const uint8_t* src_argb, uint8_t* dst_a, int width) { asm volatile( - "vmovdqa %3,%%ymm4 \n" + "vmovdqa %3,%%ymm4 \n" "vbroadcastf128 %4,%%ymm5 \n" LABELALIGN "1: \n" - "vmovdqu (%0), %%ymm0 \n" - "vmovdqu 0x20(%0), %%ymm1 \n" - "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" // vpsrld $0x18, %%ymm0 - "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" - "vmovdqu 0x40(%0), %%ymm2 \n" - "vmovdqu 0x60(%0), %%ymm3 \n" - "lea 0x80(%0), %0 \n" - "vpackssdw %%ymm1, %%ymm0, %%ymm0 \n" // mutates - "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" - "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" - "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // mutates - "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. - "vpermd %%ymm0,%%ymm4,%%ymm0 \n" // unmutate. - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20, %2 \n" - "jg 1b \n" + "vmovdqu (%0), %%ymm0 \n" + "vmovdqu 0x20(%0), %%ymm1 \n" + "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" // vpsrld $0x18, %%ymm0 + "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" + "vmovdqu 0x40(%0), %%ymm2 \n" + "vmovdqu 0x60(%0), %%ymm3 \n" + "lea 0x80(%0), %0 \n" + "vpackssdw %%ymm1, %%ymm0, %%ymm0 \n" // mutates + "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" + "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" + "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // mutates + "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. + "vpermd %%ymm0,%%ymm4,%%ymm0 \n" // unmutate. + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20, %2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb), // %0 "+r"(dst_a), // %1 @@ -4084,31 +4181,31 @@ void ARGBExtractAlphaRow_AVX2(const uint8_t* src_argb, // width in pixels void ARGBCopyYToAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "pcmpeqb %%xmm0,%%xmm0 \n" - "pslld $0x18,%%xmm0 \n" - "pcmpeqb %%xmm1,%%xmm1 \n" - "psrld $0x8,%%xmm1 \n" + "pcmpeqb %%xmm0,%%xmm0 \n" + "pslld $0x18,%%xmm0 \n" + "pcmpeqb %%xmm1,%%xmm1 \n" + "psrld $0x8,%%xmm1 \n" LABELALIGN "1: \n" - "movq (%0),%%xmm2 \n" - "lea 0x8(%0),%0 \n" - "punpcklbw %%xmm2,%%xmm2 \n" - "punpckhwd %%xmm2,%%xmm3 \n" - "punpcklwd %%xmm2,%%xmm2 \n" - "movdqu (%1),%%xmm4 \n" - "movdqu 0x10(%1),%%xmm5 \n" - "pand %%xmm0,%%xmm2 \n" - "pand %%xmm0,%%xmm3 \n" - "pand %%xmm1,%%xmm4 \n" - "pand %%xmm1,%%xmm5 \n" - "por %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm2,(%1) \n" - "movdqu %%xmm3,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movq (%0),%%xmm2 \n" + "lea 0x8(%0),%0 \n" + "punpcklbw %%xmm2,%%xmm2 \n" + "punpckhwd %%xmm2,%%xmm3 \n" + "punpcklwd %%xmm2,%%xmm2 \n" + "movdqu (%1),%%xmm4 \n" + "movdqu 0x10(%1),%%xmm5 \n" + "pand %%xmm0,%%xmm2 \n" + "pand %%xmm0,%%xmm3 \n" + "pand %%xmm1,%%xmm4 \n" + "pand %%xmm1,%%xmm5 \n" + "por %%xmm4,%%xmm2 \n" + "por %%xmm5,%%xmm3 \n" + "movdqu %%xmm2,(%1) \n" + "movdqu %%xmm3,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -4121,23 +4218,23 @@ void ARGBCopyYToAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { // width in pixels void ARGBCopyYToAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { asm volatile( - "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" - "vpsrld $0x8,%%ymm0,%%ymm0 \n" + "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" + "vpsrld $0x8,%%ymm0,%%ymm0 \n" LABELALIGN "1: \n" - "vpmovzxbd (%0),%%ymm1 \n" - "vpmovzxbd 0x8(%0),%%ymm2 \n" - "lea 0x10(%0),%0 \n" - "vpslld $0x18,%%ymm1,%%ymm1 \n" - "vpslld $0x18,%%ymm2,%%ymm2 \n" - "vpblendvb %%ymm0,(%1),%%ymm1,%%ymm1 \n" - "vpblendvb %%ymm0,0x20(%1),%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm1,(%1) \n" - "vmovdqu %%ymm2,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "vpmovzxbd (%0),%%ymm1 \n" + "vpmovzxbd 0x8(%0),%%ymm2 \n" + "lea 0x10(%0),%0 \n" + "vpslld $0x18,%%ymm1,%%ymm1 \n" + "vpslld $0x18,%%ymm2,%%ymm2 \n" + "vpblendvb %%ymm0,(%1),%%ymm1,%%ymm1 \n" + "vpblendvb %%ymm0,0x20(%1),%%ymm2,%%ymm2 \n" + "vmovdqu %%ymm1,(%1) \n" + "vmovdqu %%ymm2,0x20(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 "+r"(dst), // %1 @@ -4153,7 +4250,7 @@ void SetRow_X86(uint8_t* dst, uint8_t v8, int width) { const uint32_t v32 = v8 * 0x01010101u; // Duplicate byte to all bytes. asm volatile( - "rep stosl \n" + "rep stosl \n" : "+D"(dst), // %0 "+c"(width_tmp) // %1 : "a"(v32) // %2 @@ -4164,7 +4261,7 @@ void SetRow_ERMS(uint8_t* dst, uint8_t v8, int width) { size_t width_tmp = (size_t)(width); asm volatile( - "rep stosb \n" + "rep stosb \n" : "+D"(dst), // %0 "+c"(width_tmp) // %1 : "a"(v8) // %2 @@ -4175,7 +4272,7 @@ void ARGBSetRow_X86(uint8_t* dst_argb, uint32_t v32, int width) { size_t width_tmp = (size_t)(width); asm volatile( - "rep stosl \n" + "rep stosl \n" : "+D"(dst_argb), // %0 "+c"(width_tmp) // %1 : "a"(v32) // %2 @@ -4186,21 +4283,21 @@ void ARGBSetRow_X86(uint8_t* dst_argb, uint32_t v32, int width) { #ifdef HAS_YUY2TOYROW_SSE2 void YUY2ToYRow_SSE2(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psrlw $0x8,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "pand %%xmm5,%%xmm0 \n" + "pand %%xmm5,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -4214,32 +4311,32 @@ void YUY2ToUVRow_SSE2(const uint8_t* src_yuy2, uint8_t* dst_v, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psrlw $0x8,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%4,1),%%xmm2 \n" - "movdqu 0x10(%0,%4,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm2,%%xmm0 \n" - "pavgb %%xmm3,%%xmm1 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x00(%0,%4,1),%%xmm2 \n" + "movdqu 0x10(%0,%4,1),%%xmm3 \n" + "lea 0x20(%0),%0 \n" + "pavgb %%xmm2,%%xmm0 \n" + "pavgb %%xmm3,%%xmm1 \n" + "psrlw $0x8,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "pand %%xmm5,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm1 \n" + "movq %%xmm0,(%1) \n" + "movq %%xmm1,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -4253,28 +4350,28 @@ void YUY2ToUV422Row_SSE2(const uint8_t* src_yuy2, uint8_t* dst_v, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psrlw $0x8,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "psrlw $0x8,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "pand %%xmm5,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm1 \n" + "movq %%xmm0,(%1) \n" + "movq %%xmm1,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -4288,16 +4385,16 @@ void UYVYToYRow_SSE2(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "psrlw $0x8,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -4311,32 +4408,32 @@ void UYVYToUVRow_SSE2(const uint8_t* src_uyvy, uint8_t* dst_v, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psrlw $0x8,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%4,1),%%xmm2 \n" - "movdqu 0x10(%0,%4,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm2,%%xmm0 \n" - "pavgb %%xmm3,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x00(%0,%4,1),%%xmm2 \n" + "movdqu 0x10(%0,%4,1),%%xmm3 \n" + "lea 0x20(%0),%0 \n" + "pavgb %%xmm2,%%xmm0 \n" + "pavgb %%xmm3,%%xmm1 \n" + "pand %%xmm5,%%xmm0 \n" + "pand %%xmm5,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "pand %%xmm5,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm1 \n" + "movq %%xmm0,(%1) \n" + "movq %%xmm1,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -4350,28 +4447,28 @@ void UYVYToUV422Row_SSE2(const uint8_t* src_uyvy, uint8_t* dst_v, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psrlw $0x8,%%xmm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "pand %%xmm5,%%xmm0 \n" + "pand %%xmm5,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "pand %%xmm5,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm1 \n" + "movq %%xmm0,(%1) \n" + "movq %%xmm1,0x00(%1,%2,1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -4384,22 +4481,22 @@ void UYVYToUV422Row_SSE2(const uint8_t* src_uyvy, #ifdef HAS_YUY2TOYROW_AVX2 void YUY2ToYRow_AVX2(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpsrlw $0x8,%%ymm5,%%ymm5 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpand %%ymm5,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_yuy2), // %0 "+r"(dst_y), // %1 @@ -4414,32 +4511,32 @@ void YUY2ToUVRow_AVX2(const uint8_t* src_yuy2, uint8_t* dst_v, int width) { asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpsrlw $0x8,%%ymm5,%%ymm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm0,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" + "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpsrlw $0x8,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm0,%%ymm1 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm1,%%ymm1 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" "vextractf128 $0x0,%%ymm1,(%1) \n" "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "lea 0x10(%1),%1 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_yuy2), // %0 "+r"(dst_u), // %1 @@ -4454,30 +4551,30 @@ void YUY2ToUV422Row_AVX2(const uint8_t* src_yuy2, uint8_t* dst_v, int width) { asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpsrlw $0x8,%%ymm5,%%ymm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm0,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpsrlw $0x8,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm0,%%ymm1 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm1,%%ymm1 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" "vextractf128 $0x0,%%ymm1,(%1) \n" "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "lea 0x10(%1),%1 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_yuy2), // %0 "+r"(dst_u), // %1 @@ -4492,17 +4589,17 @@ void UYVYToYRow_AVX2(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpsrlw $0x8,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_uyvy), // %0 "+r"(dst_y), // %1 @@ -4516,32 +4613,32 @@ void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, uint8_t* dst_v, int width) { asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpsrlw $0x8,%%ymm5,%%ymm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm0,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" + "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpand %%ymm5,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm0,%%ymm1 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm1,%%ymm1 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" "vextractf128 $0x0,%%ymm1,(%1) \n" "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "lea 0x10(%1),%1 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_uyvy), // %0 "+r"(dst_u), // %1 @@ -4556,30 +4653,30 @@ void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, uint8_t* dst_v, int width) { asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpsrlw $0x8,%%ymm5,%%ymm5 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm0,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpand %%ymm5,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm0,%%ymm1 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm1,%%ymm1 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" "vextractf128 $0x0,%%ymm1,(%1) \n" "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" + "lea 0x10(%1),%1 \n" + "sub $0x20,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_uyvy), // %0 "+r"(dst_u), // %1 @@ -4601,71 +4698,71 @@ void ARGBBlendRow_SSSE3(const uint8_t* src_argb0, uint8_t* dst_argb, int width) { asm volatile( - "pcmpeqb %%xmm7,%%xmm7 \n" - "psrlw $0xf,%%xmm7 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "psrlw $0x8,%%xmm6 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "psllw $0x8,%%xmm5 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "pslld $0x18,%%xmm4 \n" - "sub $0x4,%3 \n" - "jl 49f \n" + "pcmpeqb %%xmm7,%%xmm7 \n" + "psrlw $0xf,%%xmm7 \n" + "pcmpeqb %%xmm6,%%xmm6 \n" + "psrlw $0x8,%%xmm6 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psllw $0x8,%%xmm5 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "pslld $0x18,%%xmm4 \n" + "sub $0x4,%3 \n" + "jl 49f \n" // 4 pixel loop. LABELALIGN "40: \n" - "movdqu (%0),%%xmm3 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm3,%%xmm0 \n" - "pxor %%xmm4,%%xmm3 \n" - "movdqu (%1),%%xmm2 \n" - "pshufb %4,%%xmm3 \n" - "pand %%xmm6,%%xmm2 \n" - "paddw %%xmm7,%%xmm3 \n" - "pmullw %%xmm3,%%xmm2 \n" - "movdqu (%1),%%xmm1 \n" - "lea 0x10(%1),%1 \n" - "psrlw $0x8,%%xmm1 \n" - "por %%xmm4,%%xmm0 \n" - "pmullw %%xmm3,%%xmm1 \n" - "psrlw $0x8,%%xmm2 \n" - "paddusb %%xmm2,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jge 40b \n" + "movdqu (%0),%%xmm3 \n" + "lea 0x10(%0),%0 \n" + "movdqa %%xmm3,%%xmm0 \n" + "pxor %%xmm4,%%xmm3 \n" + "movdqu (%1),%%xmm2 \n" + "pshufb %4,%%xmm3 \n" + "pand %%xmm6,%%xmm2 \n" + "paddw %%xmm7,%%xmm3 \n" + "pmullw %%xmm3,%%xmm2 \n" + "movdqu (%1),%%xmm1 \n" + "lea 0x10(%1),%1 \n" + "psrlw $0x8,%%xmm1 \n" + "por %%xmm4,%%xmm0 \n" + "pmullw %%xmm3,%%xmm1 \n" + "psrlw $0x8,%%xmm2 \n" + "paddusb %%xmm2,%%xmm0 \n" + "pand %%xmm5,%%xmm1 \n" + "paddusb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%3 \n" + "jge 40b \n" "49: \n" - "add $0x3,%3 \n" - "jl 99f \n" + "add $0x3,%3 \n" + "jl 99f \n" // 1 pixel loop. "91: \n" - "movd (%0),%%xmm3 \n" - "lea 0x4(%0),%0 \n" - "movdqa %%xmm3,%%xmm0 \n" - "pxor %%xmm4,%%xmm3 \n" - "movd (%1),%%xmm2 \n" - "pshufb %4,%%xmm3 \n" - "pand %%xmm6,%%xmm2 \n" - "paddw %%xmm7,%%xmm3 \n" - "pmullw %%xmm3,%%xmm2 \n" - "movd (%1),%%xmm1 \n" - "lea 0x4(%1),%1 \n" - "psrlw $0x8,%%xmm1 \n" - "por %%xmm4,%%xmm0 \n" - "pmullw %%xmm3,%%xmm1 \n" - "psrlw $0x8,%%xmm2 \n" - "paddusb %%xmm2,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movd %%xmm0,(%2) \n" - "lea 0x4(%2),%2 \n" - "sub $0x1,%3 \n" - "jge 91b \n" + "movd (%0),%%xmm3 \n" + "lea 0x4(%0),%0 \n" + "movdqa %%xmm3,%%xmm0 \n" + "pxor %%xmm4,%%xmm3 \n" + "movd (%1),%%xmm2 \n" + "pshufb %4,%%xmm3 \n" + "pand %%xmm6,%%xmm2 \n" + "paddw %%xmm7,%%xmm3 \n" + "pmullw %%xmm3,%%xmm2 \n" + "movd (%1),%%xmm1 \n" + "lea 0x4(%1),%1 \n" + "psrlw $0x8,%%xmm1 \n" + "por %%xmm4,%%xmm0 \n" + "pmullw %%xmm3,%%xmm1 \n" + "psrlw $0x8,%%xmm2 \n" + "paddusb %%xmm2,%%xmm0 \n" + "pand %%xmm5,%%xmm1 \n" + "paddusb %%xmm1,%%xmm0 \n" + "movd %%xmm0,(%2) \n" + "lea 0x4(%2),%2 \n" + "sub $0x1,%3 \n" + "jge 91b \n" "99: \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 @@ -4689,36 +4786,36 @@ void BlendPlaneRow_SSSE3(const uint8_t* src0, uint8_t* dst, int width) { asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psllw $0x8,%%xmm5 \n" - "mov $0x80808080,%%eax \n" - "movd %%eax,%%xmm6 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "mov $0x807f807f,%%eax \n" - "movd %%eax,%%xmm7 \n" - "pshufd $0x0,%%xmm7,%%xmm7 \n" - "sub %2,%0 \n" - "sub %2,%1 \n" - "sub %2,%3 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psllw $0x8,%%xmm5 \n" + "mov $0x80808080,%%eax \n" + "movd %%eax,%%xmm6 \n" + "pshufd $0x0,%%xmm6,%%xmm6 \n" + "mov $0x807f807f,%%eax \n" + "movd %%eax,%%xmm7 \n" + "pshufd $0x0,%%xmm7,%%xmm7 \n" + "sub %2,%0 \n" + "sub %2,%1 \n" + "sub %2,%3 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movq (%2),%%xmm0 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "pxor %%xmm5,%%xmm0 \n" - "movq (%0,%2,1),%%xmm1 \n" - "movq (%1,%2,1),%%xmm2 \n" - "punpcklbw %%xmm2,%%xmm1 \n" - "psubb %%xmm6,%%xmm1 \n" - "pmaddubsw %%xmm1,%%xmm0 \n" - "paddw %%xmm7,%%xmm0 \n" - "psrlw $0x8,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%3,%2,1) \n" - "lea 0x8(%2),%2 \n" - "sub $0x8,%4 \n" - "jg 1b \n" + "movq (%2),%%xmm0 \n" + "punpcklbw %%xmm0,%%xmm0 \n" + "pxor %%xmm5,%%xmm0 \n" + "movq (%0,%2,1),%%xmm1 \n" + "movq (%1,%2,1),%%xmm2 \n" + "punpcklbw %%xmm2,%%xmm1 \n" + "psubb %%xmm6,%%xmm1 \n" + "pmaddubsw %%xmm1,%%xmm0 \n" + "paddw %%xmm7,%%xmm0 \n" + "psrlw $0x8,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movq %%xmm0,(%3,%2,1) \n" + "lea 0x8(%2),%2 \n" + "sub $0x8,%4 \n" + "jg 1b \n" : "+r"(src0), // %0 "+r"(src1), // %1 "+r"(alpha), // %2 @@ -4741,43 +4838,43 @@ void BlendPlaneRow_AVX2(const uint8_t* src0, uint8_t* dst, int width) { asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsllw $0x8,%%ymm5,%%ymm5 \n" - "mov $0x80808080,%%eax \n" - "vmovd %%eax,%%xmm6 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpsllw $0x8,%%ymm5,%%ymm5 \n" + "mov $0x80808080,%%eax \n" + "vmovd %%eax,%%xmm6 \n" "vbroadcastss %%xmm6,%%ymm6 \n" - "mov $0x807f807f,%%eax \n" - "vmovd %%eax,%%xmm7 \n" + "mov $0x807f807f,%%eax \n" + "vmovd %%eax,%%xmm7 \n" "vbroadcastss %%xmm7,%%ymm7 \n" - "sub %2,%0 \n" - "sub %2,%1 \n" - "sub %2,%3 \n" + "sub %2,%0 \n" + "sub %2,%1 \n" + "sub %2,%3 \n" // 32 pixel loop. LABELALIGN "1: \n" - "vmovdqu (%2),%%ymm0 \n" - "vpunpckhbw %%ymm0,%%ymm0,%%ymm3 \n" - "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" - "vpxor %%ymm5,%%ymm3,%%ymm3 \n" - "vpxor %%ymm5,%%ymm0,%%ymm0 \n" - "vmovdqu (%0,%2,1),%%ymm1 \n" - "vmovdqu (%1,%2,1),%%ymm2 \n" - "vpunpckhbw %%ymm2,%%ymm1,%%ymm4 \n" - "vpunpcklbw %%ymm2,%%ymm1,%%ymm1 \n" - "vpsubb %%ymm6,%%ymm4,%%ymm4 \n" - "vpsubb %%ymm6,%%ymm1,%%ymm1 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpmaddubsw %%ymm1,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm7,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm7,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm3,%%ymm3 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm3,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%3,%2,1) \n" - "lea 0x20(%2),%2 \n" - "sub $0x20,%4 \n" - "jg 1b \n" + "vmovdqu (%2),%%ymm0 \n" + "vpunpckhbw %%ymm0,%%ymm0,%%ymm3 \n" + "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" + "vpxor %%ymm5,%%ymm3,%%ymm3 \n" + "vpxor %%ymm5,%%ymm0,%%ymm0 \n" + "vmovdqu (%0,%2,1),%%ymm1 \n" + "vmovdqu (%1,%2,1),%%ymm2 \n" + "vpunpckhbw %%ymm2,%%ymm1,%%ymm4 \n" + "vpunpcklbw %%ymm2,%%ymm1,%%ymm1 \n" + "vpsubb %%ymm6,%%ymm4,%%ymm4 \n" + "vpsubb %%ymm6,%%ymm1,%%ymm1 \n" + "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" + "vpmaddubsw %%ymm1,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm7,%%ymm3,%%ymm3 \n" + "vpaddw %%ymm7,%%ymm0,%%ymm0 \n" + "vpsrlw $0x8,%%ymm3,%%ymm3 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm3,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%3,%2,1) \n" + "lea 0x20(%2),%2 \n" + "sub $0x20,%4 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src0), // %0 "+r"(src1), // %1 @@ -4791,7 +4888,7 @@ void BlendPlaneRow_AVX2(const uint8_t* src0, #endif // HAS_BLENDPLANEROW_AVX2 #ifdef HAS_ARGBATTENUATEROW_SSSE3 -// Shuffle table duplicating alpha +// Shuffle table duplicating alpha. static const uvec8 kShuffleAlpha0 = {3u, 3u, 3u, 3u, 3u, 3u, 128u, 128u, 7u, 7u, 7u, 7u, 7u, 7u, 128u, 128u}; static const uvec8 kShuffleAlpha1 = {11u, 11u, 11u, 11u, 11u, 11u, 128u, 128u, @@ -4801,35 +4898,35 @@ void ARGBAttenuateRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_argb, int width) { asm volatile( - "pcmpeqb %%xmm3,%%xmm3 \n" - "pslld $0x18,%%xmm3 \n" - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" + "pcmpeqb %%xmm3,%%xmm3 \n" + "pslld $0x18,%%xmm3 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" // 4 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "pshufb %%xmm4,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "punpcklbw %%xmm1,%%xmm1 \n" - "pmulhuw %%xmm1,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "pshufb %%xmm5,%%xmm1 \n" - "movdqu (%0),%%xmm2 \n" - "punpckhbw %%xmm2,%%xmm2 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "movdqu (%0),%%xmm2 \n" - "lea 0x10(%0),%0 \n" - "pand %%xmm3,%%xmm2 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "pshufb %%xmm4,%%xmm0 \n" + "movdqu (%0),%%xmm1 \n" + "punpcklbw %%xmm1,%%xmm1 \n" + "pmulhuw %%xmm1,%%xmm0 \n" + "movdqu (%0),%%xmm1 \n" + "pshufb %%xmm5,%%xmm1 \n" + "movdqu (%0),%%xmm2 \n" + "punpckhbw %%xmm2,%%xmm2 \n" + "pmulhuw %%xmm2,%%xmm1 \n" + "movdqu (%0),%%xmm2 \n" + "lea 0x10(%0),%0 \n" + "pand %%xmm3,%%xmm2 \n" + "psrlw $0x8,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "por %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -4850,29 +4947,29 @@ void ARGBAttenuateRow_AVX2(const uint8_t* src_argb, int width) { asm volatile( "vbroadcastf128 %3,%%ymm4 \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpslld $0x18,%%ymm5,%%ymm5 \n" - "sub %0,%1 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpslld $0x18,%%ymm5,%%ymm5 \n" + "sub %0,%1 \n" // 8 pixel loop. LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm6 \n" - "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" - "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" - "vpshufb %%ymm4,%%ymm0,%%ymm2 \n" - "vpshufb %%ymm4,%%ymm1,%%ymm3 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" - "vpand %%ymm5,%%ymm6,%%ymm6 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpor %%ymm6,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,0x00(%0,%1,1) \n" - "lea 0x20(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm6 \n" + "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" + "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" + "vpshufb %%ymm4,%%ymm0,%%ymm2 \n" + "vpshufb %%ymm4,%%ymm1,%%ymm3 \n" + "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" + "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" + "vpand %%ymm5,%%ymm6,%%ymm6 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpsrlw $0x8,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpor %%ymm6,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,0x00(%0,%1,1) \n" + "lea 0x20(%0),%0 \n" + "sub $0x8,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 @@ -4892,32 +4989,32 @@ void ARGBUnattenuateRow_SSE2(const uint8_t* src_argb, // 4 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movzb 0x03(%0),%3 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "movd 0x00(%4,%3,4),%%xmm2 \n" - "movzb 0x07(%0),%3 \n" - "movd 0x00(%4,%3,4),%%xmm3 \n" - "pshuflw $0x40,%%xmm2,%%xmm2 \n" - "pshuflw $0x40,%%xmm3,%%xmm3 \n" - "movlhps %%xmm3,%%xmm2 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "movzb 0x0b(%0),%3 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "movd 0x00(%4,%3,4),%%xmm2 \n" - "movzb 0x0f(%0),%3 \n" - "movd 0x00(%4,%3,4),%%xmm3 \n" - "pshuflw $0x40,%%xmm2,%%xmm2 \n" - "pshuflw $0x40,%%xmm3,%%xmm3 \n" - "movlhps %%xmm3,%%xmm2 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movzb 0x03(%0),%3 \n" + "punpcklbw %%xmm0,%%xmm0 \n" + "movd 0x00(%4,%3,4),%%xmm2 \n" + "movzb 0x07(%0),%3 \n" + "movd 0x00(%4,%3,4),%%xmm3 \n" + "pshuflw $0x40,%%xmm2,%%xmm2 \n" + "pshuflw $0x40,%%xmm3,%%xmm3 \n" + "movlhps %%xmm3,%%xmm2 \n" + "pmulhuw %%xmm2,%%xmm0 \n" + "movdqu (%0),%%xmm1 \n" + "movzb 0x0b(%0),%3 \n" + "punpckhbw %%xmm1,%%xmm1 \n" + "movd 0x00(%4,%3,4),%%xmm2 \n" + "movzb 0x0f(%0),%3 \n" + "movd 0x00(%4,%3,4),%%xmm3 \n" + "pshuflw $0x40,%%xmm2,%%xmm2 \n" + "pshuflw $0x40,%%xmm3,%%xmm3 \n" + "movlhps %%xmm3,%%xmm2 \n" + "pmulhuw %%xmm2,%%xmm1 \n" + "lea 0x10(%0),%0 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width), // %2 @@ -4937,52 +5034,52 @@ void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, int width) { uintptr_t alpha; asm volatile( - "sub %0,%1 \n" + "sub %0,%1 \n" "vbroadcastf128 %5,%%ymm5 \n" // 8 pixel loop. LABELALIGN "1: \n" // replace VPGATHER - "movzb 0x03(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm0 \n" - "movzb 0x07(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm1 \n" - "movzb 0x0b(%0),%3 \n" - "vpunpckldq %%xmm1,%%xmm0,%%xmm6 \n" - "vmovd 0x00(%4,%3,4),%%xmm2 \n" - "movzb 0x0f(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm3 \n" - "movzb 0x13(%0),%3 \n" - "vpunpckldq %%xmm3,%%xmm2,%%xmm7 \n" - "vmovd 0x00(%4,%3,4),%%xmm0 \n" - "movzb 0x17(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm1 \n" - "movzb 0x1b(%0),%3 \n" - "vpunpckldq %%xmm1,%%xmm0,%%xmm0 \n" - "vmovd 0x00(%4,%3,4),%%xmm2 \n" - "movzb 0x1f(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm3 \n" - "vpunpckldq %%xmm3,%%xmm2,%%xmm2 \n" + "movzb 0x03(%0),%3 \n" + "vmovd 0x00(%4,%3,4),%%xmm0 \n" + "movzb 0x07(%0),%3 \n" + "vmovd 0x00(%4,%3,4),%%xmm1 \n" + "movzb 0x0b(%0),%3 \n" + "vpunpckldq %%xmm1,%%xmm0,%%xmm6 \n" + "vmovd 0x00(%4,%3,4),%%xmm2 \n" + "movzb 0x0f(%0),%3 \n" + "vmovd 0x00(%4,%3,4),%%xmm3 \n" + "movzb 0x13(%0),%3 \n" + "vpunpckldq %%xmm3,%%xmm2,%%xmm7 \n" + "vmovd 0x00(%4,%3,4),%%xmm0 \n" + "movzb 0x17(%0),%3 \n" + "vmovd 0x00(%4,%3,4),%%xmm1 \n" + "movzb 0x1b(%0),%3 \n" + "vpunpckldq %%xmm1,%%xmm0,%%xmm0 \n" + "vmovd 0x00(%4,%3,4),%%xmm2 \n" + "movzb 0x1f(%0),%3 \n" + "vmovd 0x00(%4,%3,4),%%xmm3 \n" + "vpunpckldq %%xmm3,%%xmm2,%%xmm2 \n" "vpunpcklqdq %%xmm7,%%xmm6,%%xmm3 \n" "vpunpcklqdq %%xmm2,%%xmm0,%%xmm0 \n" "vinserti128 $0x1,%%xmm0,%%ymm3,%%ymm3 \n" // end of VPGATHER - "vmovdqu (%0),%%ymm6 \n" - "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" - "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" - "vpunpcklwd %%ymm3,%%ymm3,%%ymm2 \n" - "vpunpckhwd %%ymm3,%%ymm3,%%ymm3 \n" - "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" - "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,0x00(%0,%1,1) \n" - "lea 0x20(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm6 \n" + "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" + "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" + "vpunpcklwd %%ymm3,%%ymm3,%%ymm2 \n" + "vpunpckhwd %%ymm3,%%ymm3,%%ymm3 \n" + "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" + "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" + "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" + "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,0x00(%0,%1,1) \n" + "lea 0x20(%0),%0 \n" + "sub $0x8,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 @@ -4999,42 +5096,42 @@ void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, // Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels void ARGBGrayRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_argb, int width) { asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "psubb %%xmm5,%%xmm0 \n" - "psubb %%xmm5,%%xmm1 \n" - "movdqu %%xmm4,%%xmm6 \n" - "pmaddubsw %%xmm0,%%xmm6 \n" - "movdqu %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm1,%%xmm0 \n" - "phaddw %%xmm0,%%xmm6 \n" - "paddw %%xmm5,%%xmm6 \n" - "psrlw $0x8,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movdqu (%0),%%xmm2 \n" - "movdqu 0x10(%0),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "psrld $0x18,%%xmm2 \n" - "psrld $0x18,%%xmm3 \n" - "packuswb %%xmm3,%%xmm2 \n" - "packuswb %%xmm2,%%xmm2 \n" - "movdqa %%xmm6,%%xmm3 \n" - "punpcklbw %%xmm6,%%xmm6 \n" - "punpcklbw %%xmm2,%%xmm3 \n" - "movdqa %%xmm6,%%xmm1 \n" - "punpcklwd %%xmm3,%%xmm6 \n" - "punpckhwd %%xmm3,%%xmm1 \n" - "movdqu %%xmm6,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "psubb %%xmm5,%%xmm0 \n" + "psubb %%xmm5,%%xmm1 \n" + "movdqu %%xmm4,%%xmm6 \n" + "pmaddubsw %%xmm0,%%xmm6 \n" + "movdqu %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm1,%%xmm0 \n" + "phaddw %%xmm0,%%xmm6 \n" + "paddw %%xmm5,%%xmm6 \n" + "psrlw $0x8,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "movdqu (%0),%%xmm2 \n" + "movdqu 0x10(%0),%%xmm3 \n" + "lea 0x20(%0),%0 \n" + "psrld $0x18,%%xmm2 \n" + "psrld $0x18,%%xmm3 \n" + "packuswb %%xmm3,%%xmm2 \n" + "packuswb %%xmm2,%%xmm2 \n" + "movdqa %%xmm6,%%xmm3 \n" + "punpcklbw %%xmm6,%%xmm6 \n" + "punpcklbw %%xmm2,%%xmm3 \n" + "movdqa %%xmm6,%%xmm1 \n" + "punpcklwd %%xmm3,%%xmm6 \n" + "punpckhwd %%xmm3,%%xmm1 \n" + "movdqu %%xmm6,(%1) \n" + "movdqu %%xmm1,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -5061,50 +5158,50 @@ static const vec8 kARGBToSepiaR = {24, 98, 50, 0, 24, 98, 50, 0, // Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels. void ARGBSepiaRow_SSSE3(uint8_t* dst_argb, int width) { asm volatile( - "movdqa %2,%%xmm2 \n" - "movdqa %3,%%xmm3 \n" - "movdqa %4,%%xmm4 \n" + "movdqa %2,%%xmm2 \n" + "movdqa %3,%%xmm3 \n" + "movdqa %4,%%xmm4 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm6 \n" - "pmaddubsw %%xmm2,%%xmm0 \n" - "pmaddubsw %%xmm2,%%xmm6 \n" - "phaddw %%xmm6,%%xmm0 \n" - "psrlw $0x7,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movdqu (%0),%%xmm5 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm5 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "phaddw %%xmm1,%%xmm5 \n" - "psrlw $0x7,%%xmm5 \n" - "packuswb %%xmm5,%%xmm5 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "movdqu (%0),%%xmm5 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm5 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "phaddw %%xmm1,%%xmm5 \n" - "psrlw $0x7,%%xmm5 \n" - "packuswb %%xmm5,%%xmm5 \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "psrld $0x18,%%xmm6 \n" - "psrld $0x18,%%xmm1 \n" - "packuswb %%xmm1,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "punpcklbw %%xmm6,%%xmm5 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklwd %%xmm5,%%xmm0 \n" - "punpckhwd %%xmm5,%%xmm1 \n" - "movdqu %%xmm0,(%0) \n" - "movdqu %%xmm1,0x10(%0) \n" - "lea 0x20(%0),%0 \n" - "sub $0x8,%1 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm6 \n" + "pmaddubsw %%xmm2,%%xmm0 \n" + "pmaddubsw %%xmm2,%%xmm6 \n" + "phaddw %%xmm6,%%xmm0 \n" + "psrlw $0x7,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movdqu (%0),%%xmm5 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "pmaddubsw %%xmm3,%%xmm5 \n" + "pmaddubsw %%xmm3,%%xmm1 \n" + "phaddw %%xmm1,%%xmm5 \n" + "psrlw $0x7,%%xmm5 \n" + "packuswb %%xmm5,%%xmm5 \n" + "punpcklbw %%xmm5,%%xmm0 \n" + "movdqu (%0),%%xmm5 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "pmaddubsw %%xmm4,%%xmm5 \n" + "pmaddubsw %%xmm4,%%xmm1 \n" + "phaddw %%xmm1,%%xmm5 \n" + "psrlw $0x7,%%xmm5 \n" + "packuswb %%xmm5,%%xmm5 \n" + "movdqu (%0),%%xmm6 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "psrld $0x18,%%xmm6 \n" + "psrld $0x18,%%xmm1 \n" + "packuswb %%xmm1,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "punpcklbw %%xmm6,%%xmm5 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklwd %%xmm5,%%xmm0 \n" + "punpckhwd %%xmm5,%%xmm1 \n" + "movdqu %%xmm0,(%0) \n" + "movdqu %%xmm1,0x10(%0) \n" + "lea 0x20(%0),%0 \n" + "sub $0x8,%1 \n" + "jg 1b \n" : "+r"(dst_argb), // %0 "+r"(width) // %1 : "m"(kARGBToSepiaB), // %2 @@ -5122,54 +5219,54 @@ void ARGBColorMatrixRow_SSSE3(const uint8_t* src_argb, const int8_t* matrix_argb, int width) { asm volatile( - "movdqu (%3),%%xmm5 \n" - "pshufd $0x00,%%xmm5,%%xmm2 \n" - "pshufd $0x55,%%xmm5,%%xmm3 \n" - "pshufd $0xaa,%%xmm5,%%xmm4 \n" - "pshufd $0xff,%%xmm5,%%xmm5 \n" + "movdqu (%3),%%xmm5 \n" + "pshufd $0x00,%%xmm5,%%xmm2 \n" + "pshufd $0x55,%%xmm5,%%xmm3 \n" + "pshufd $0xaa,%%xmm5,%%xmm4 \n" + "pshufd $0xff,%%xmm5,%%xmm5 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm7 \n" - "pmaddubsw %%xmm2,%%xmm0 \n" - "pmaddubsw %%xmm2,%%xmm7 \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "phaddsw %%xmm7,%%xmm0 \n" - "phaddsw %%xmm1,%%xmm6 \n" - "psraw $0x6,%%xmm0 \n" - "psraw $0x6,%%xmm6 \n" - "packuswb %%xmm0,%%xmm0 \n" - "packuswb %%xmm6,%%xmm6 \n" - "punpcklbw %%xmm6,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "movdqu 0x10(%0),%%xmm7 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm7 \n" - "phaddsw %%xmm7,%%xmm1 \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x10(%0),%%xmm7 \n" - "pmaddubsw %%xmm5,%%xmm6 \n" - "pmaddubsw %%xmm5,%%xmm7 \n" - "phaddsw %%xmm7,%%xmm6 \n" - "psraw $0x6,%%xmm1 \n" - "psraw $0x6,%%xmm6 \n" - "packuswb %%xmm1,%%xmm1 \n" - "packuswb %%xmm6,%%xmm6 \n" - "punpcklbw %%xmm6,%%xmm1 \n" - "movdqa %%xmm0,%%xmm6 \n" - "punpcklwd %%xmm1,%%xmm0 \n" - "punpckhwd %%xmm1,%%xmm6 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm6,0x10(%1) \n" - "lea 0x20(%0),%0 \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm7 \n" + "pmaddubsw %%xmm2,%%xmm0 \n" + "pmaddubsw %%xmm2,%%xmm7 \n" + "movdqu (%0),%%xmm6 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "pmaddubsw %%xmm3,%%xmm6 \n" + "pmaddubsw %%xmm3,%%xmm1 \n" + "phaddsw %%xmm7,%%xmm0 \n" + "phaddsw %%xmm1,%%xmm6 \n" + "psraw $0x6,%%xmm0 \n" + "psraw $0x6,%%xmm6 \n" + "packuswb %%xmm0,%%xmm0 \n" + "packuswb %%xmm6,%%xmm6 \n" + "punpcklbw %%xmm6,%%xmm0 \n" + "movdqu (%0),%%xmm1 \n" + "movdqu 0x10(%0),%%xmm7 \n" + "pmaddubsw %%xmm4,%%xmm1 \n" + "pmaddubsw %%xmm4,%%xmm7 \n" + "phaddsw %%xmm7,%%xmm1 \n" + "movdqu (%0),%%xmm6 \n" + "movdqu 0x10(%0),%%xmm7 \n" + "pmaddubsw %%xmm5,%%xmm6 \n" + "pmaddubsw %%xmm5,%%xmm7 \n" + "phaddsw %%xmm7,%%xmm6 \n" + "psraw $0x6,%%xmm1 \n" + "psraw $0x6,%%xmm6 \n" + "packuswb %%xmm1,%%xmm1 \n" + "packuswb %%xmm6,%%xmm6 \n" + "punpcklbw %%xmm6,%%xmm1 \n" + "movdqa %%xmm0,%%xmm6 \n" + "punpcklwd %%xmm1,%%xmm0 \n" + "punpckhwd %%xmm1,%%xmm6 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu %%xmm6,0x10(%1) \n" + "lea 0x20(%0),%0 \n" + "lea 0x20(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -5187,40 +5284,40 @@ void ARGBQuantizeRow_SSE2(uint8_t* dst_argb, int interval_offset, int width) { asm volatile( - "movd %2,%%xmm2 \n" - "movd %3,%%xmm3 \n" - "movd %4,%%xmm4 \n" - "pshuflw $0x40,%%xmm2,%%xmm2 \n" - "pshufd $0x44,%%xmm2,%%xmm2 \n" - "pshuflw $0x40,%%xmm3,%%xmm3 \n" - "pshufd $0x44,%%xmm3,%%xmm3 \n" - "pshuflw $0x40,%%xmm4,%%xmm4 \n" - "pshufd $0x44,%%xmm4,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "pslld $0x18,%%xmm6 \n" + "movd %2,%%xmm2 \n" + "movd %3,%%xmm3 \n" + "movd %4,%%xmm4 \n" + "pshuflw $0x40,%%xmm2,%%xmm2 \n" + "pshufd $0x44,%%xmm2,%%xmm2 \n" + "pshuflw $0x40,%%xmm3,%%xmm3 \n" + "pshufd $0x44,%%xmm3,%%xmm3 \n" + "pshuflw $0x40,%%xmm4,%%xmm4 \n" + "pshufd $0x44,%%xmm4,%%xmm4 \n" + "pxor %%xmm5,%%xmm5 \n" + "pcmpeqb %%xmm6,%%xmm6 \n" + "pslld $0x18,%%xmm6 \n" // 4 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "punpckhbw %%xmm5,%%xmm1 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "pmullw %%xmm3,%%xmm0 \n" - "movdqu (%0),%%xmm7 \n" - "pmullw %%xmm3,%%xmm1 \n" - "pand %%xmm6,%%xmm7 \n" - "paddw %%xmm4,%%xmm0 \n" - "paddw %%xmm4,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "por %%xmm7,%%xmm0 \n" - "movdqu %%xmm0,(%0) \n" - "lea 0x10(%0),%0 \n" - "sub $0x4,%1 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "punpcklbw %%xmm5,%%xmm0 \n" + "pmulhuw %%xmm2,%%xmm0 \n" + "movdqu (%0),%%xmm1 \n" + "punpckhbw %%xmm5,%%xmm1 \n" + "pmulhuw %%xmm2,%%xmm1 \n" + "pmullw %%xmm3,%%xmm0 \n" + "movdqu (%0),%%xmm7 \n" + "pmullw %%xmm3,%%xmm1 \n" + "pand %%xmm6,%%xmm7 \n" + "paddw %%xmm4,%%xmm0 \n" + "paddw %%xmm4,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "por %%xmm7,%%xmm0 \n" + "movdqu %%xmm0,(%0) \n" + "lea 0x10(%0),%0 \n" + "sub $0x4,%1 \n" + "jg 1b \n" : "+r"(dst_argb), // %0 "+r"(width) // %1 : "r"(scale), // %2 @@ -5238,27 +5335,27 @@ void ARGBShadeRow_SSE2(const uint8_t* src_argb, int width, uint32_t value) { asm volatile( - "movd %3,%%xmm2 \n" - "punpcklbw %%xmm2,%%xmm2 \n" - "punpcklqdq %%xmm2,%%xmm2 \n" + "movd %3,%%xmm2 \n" + "punpcklbw %%xmm2,%%xmm2 \n" + "punpcklqdq %%xmm2,%%xmm2 \n" // 4 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklbw %%xmm0,%%xmm0 \n" + "punpckhbw %%xmm1,%%xmm1 \n" + "pmulhuw %%xmm2,%%xmm0 \n" + "pmulhuw %%xmm2,%%xmm1 \n" + "psrlw $0x8,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -5275,28 +5372,28 @@ void ARGBMultiplyRow_SSE2(const uint8_t* src_argb0, int width) { asm volatile( - "pxor %%xmm5,%%xmm5 \n" + "pxor %%xmm5,%%xmm5 \n" // 4 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movdqu (%1),%%xmm2 \n" - "lea 0x10(%1),%1 \n" - "movdqu %%xmm0,%%xmm1 \n" - "movdqu %%xmm2,%%xmm3 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "punpckhbw %%xmm5,%%xmm3 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "pmulhuw %%xmm3,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "movdqu (%1),%%xmm2 \n" + "lea 0x10(%1),%1 \n" + "movdqu %%xmm0,%%xmm1 \n" + "movdqu %%xmm2,%%xmm3 \n" + "punpcklbw %%xmm0,%%xmm0 \n" + "punpckhbw %%xmm1,%%xmm1 \n" + "punpcklbw %%xmm5,%%xmm2 \n" + "punpckhbw %%xmm5,%%xmm3 \n" + "pmulhuw %%xmm2,%%xmm0 \n" + "pmulhuw %%xmm3,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%3 \n" + "jg 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -5314,26 +5411,26 @@ void ARGBMultiplyRow_AVX2(const uint8_t* src_argb0, int width) { asm volatile( - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" + "vpxor %%ymm5,%%ymm5,%%ymm5 \n" // 4 pixel loop. LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm1 \n" - "lea 0x20(%0),%0 \n" - "vmovdqu (%1),%%ymm3 \n" - "lea 0x20(%1),%1 \n" - "vpunpcklbw %%ymm1,%%ymm1,%%ymm0 \n" - "vpunpckhbw %%ymm1,%%ymm1,%%ymm1 \n" - "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" - "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%2) \n" - "lea 0x20(%2),%2 \n" - "sub $0x8,%3 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm1 \n" + "lea 0x20(%0),%0 \n" + "vmovdqu (%1),%%ymm3 \n" + "lea 0x20(%1),%1 \n" + "vpunpcklbw %%ymm1,%%ymm1,%%ymm0 \n" + "vpunpckhbw %%ymm1,%%ymm1,%%ymm1 \n" + "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" + "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" + "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" + "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%2) \n" + "lea 0x20(%2),%2 \n" + "sub $0x8,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 @@ -5359,15 +5456,15 @@ void ARGBAddRow_SSE2(const uint8_t* src_argb0, // 4 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movdqu (%1),%%xmm1 \n" - "lea 0x10(%1),%1 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "movdqu (%1),%%xmm1 \n" + "lea 0x10(%1),%1 \n" + "paddusb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%3 \n" + "jg 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -5387,14 +5484,14 @@ void ARGBAddRow_AVX2(const uint8_t* src_argb0, // 4 pixel loop. LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "lea 0x20(%0),%0 \n" - "vpaddusb (%1),%%ymm0,%%ymm0 \n" - "lea 0x20(%1),%1 \n" - "vmovdqu %%ymm0,(%2) \n" - "lea 0x20(%2),%2 \n" - "sub $0x8,%3 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "lea 0x20(%0),%0 \n" + "vpaddusb (%1),%%ymm0,%%ymm0 \n" + "lea 0x20(%1),%1 \n" + "vmovdqu %%ymm0,(%2) \n" + "lea 0x20(%2),%2 \n" + "sub $0x8,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 @@ -5415,15 +5512,15 @@ void ARGBSubtractRow_SSE2(const uint8_t* src_argb0, // 4 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movdqu (%1),%%xmm1 \n" - "lea 0x10(%1),%1 \n" - "psubusb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "movdqu (%1),%%xmm1 \n" + "lea 0x10(%1),%1 \n" + "psubusb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%3 \n" + "jg 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -5443,14 +5540,14 @@ void ARGBSubtractRow_AVX2(const uint8_t* src_argb0, // 4 pixel loop. LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "lea 0x20(%0),%0 \n" - "vpsubusb (%1),%%ymm0,%%ymm0 \n" - "lea 0x20(%1),%1 \n" - "vmovdqu %%ymm0,(%2) \n" - "lea 0x20(%2),%2 \n" - "sub $0x8,%3 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "lea 0x20(%0),%0 \n" + "vpsubusb (%1),%%ymm0,%%ymm0 \n" + "lea 0x20(%1),%1 \n" + "vmovdqu %%ymm0,(%2) \n" + "lea 0x20(%2),%2 \n" + "sub $0x8,%3 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 @@ -5472,40 +5569,40 @@ void SobelXRow_SSE2(const uint8_t* src_y0, uint8_t* dst_sobelx, int width) { asm volatile( - "sub %0,%1 \n" - "sub %0,%2 \n" - "sub %0,%3 \n" - "pxor %%xmm5,%%xmm5 \n" + "sub %0,%1 \n" + "sub %0,%2 \n" + "sub %0,%3 \n" + "pxor %%xmm5,%%xmm5 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movq (%0),%%xmm0 \n" - "movq 0x2(%0),%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "psubw %%xmm1,%%xmm0 \n" - "movq 0x00(%0,%1,1),%%xmm1 \n" - "movq 0x02(%0,%1,1),%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "psubw %%xmm2,%%xmm1 \n" - "movq 0x00(%0,%2,1),%%xmm2 \n" - "movq 0x02(%0,%2,1),%%xmm3 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm3 \n" - "psubw %%xmm3,%%xmm2 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm1,%%xmm0 \n" - "paddw %%xmm1,%%xmm0 \n" - "pxor %%xmm1,%%xmm1 \n" - "psubw %%xmm0,%%xmm1 \n" - "pmaxsw %%xmm1,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,0x00(%0,%3,1) \n" - "lea 0x8(%0),%0 \n" - "sub $0x8,%4 \n" - "jg 1b \n" + "movq (%0),%%xmm0 \n" + "movq 0x2(%0),%%xmm1 \n" + "punpcklbw %%xmm5,%%xmm0 \n" + "punpcklbw %%xmm5,%%xmm1 \n" + "psubw %%xmm1,%%xmm0 \n" + "movq 0x00(%0,%1,1),%%xmm1 \n" + "movq 0x02(%0,%1,1),%%xmm2 \n" + "punpcklbw %%xmm5,%%xmm1 \n" + "punpcklbw %%xmm5,%%xmm2 \n" + "psubw %%xmm2,%%xmm1 \n" + "movq 0x00(%0,%2,1),%%xmm2 \n" + "movq 0x02(%0,%2,1),%%xmm3 \n" + "punpcklbw %%xmm5,%%xmm2 \n" + "punpcklbw %%xmm5,%%xmm3 \n" + "psubw %%xmm3,%%xmm2 \n" + "paddw %%xmm2,%%xmm0 \n" + "paddw %%xmm1,%%xmm0 \n" + "paddw %%xmm1,%%xmm0 \n" + "pxor %%xmm1,%%xmm1 \n" + "psubw %%xmm0,%%xmm1 \n" + "pmaxsw %%xmm1,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movq %%xmm0,0x00(%0,%3,1) \n" + "lea 0x8(%0),%0 \n" + "sub $0x8,%4 \n" + "jg 1b \n" : "+r"(src_y0), // %0 "+r"(src_y1), // %1 "+r"(src_y2), // %2 @@ -5526,39 +5623,39 @@ void SobelYRow_SSE2(const uint8_t* src_y0, uint8_t* dst_sobely, int width) { asm volatile( - "sub %0,%1 \n" - "sub %0,%2 \n" - "pxor %%xmm5,%%xmm5 \n" + "sub %0,%1 \n" + "sub %0,%2 \n" + "pxor %%xmm5,%%xmm5 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movq (%0),%%xmm0 \n" - "movq 0x00(%0,%1,1),%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "psubw %%xmm1,%%xmm0 \n" - "movq 0x1(%0),%%xmm1 \n" - "movq 0x01(%0,%1,1),%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "psubw %%xmm2,%%xmm1 \n" - "movq 0x2(%0),%%xmm2 \n" - "movq 0x02(%0,%1,1),%%xmm3 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm3 \n" - "psubw %%xmm3,%%xmm2 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm1,%%xmm0 \n" - "paddw %%xmm1,%%xmm0 \n" - "pxor %%xmm1,%%xmm1 \n" - "psubw %%xmm0,%%xmm1 \n" - "pmaxsw %%xmm1,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,0x00(%0,%2,1) \n" - "lea 0x8(%0),%0 \n" - "sub $0x8,%3 \n" - "jg 1b \n" + "movq (%0),%%xmm0 \n" + "movq 0x00(%0,%1,1),%%xmm1 \n" + "punpcklbw %%xmm5,%%xmm0 \n" + "punpcklbw %%xmm5,%%xmm1 \n" + "psubw %%xmm1,%%xmm0 \n" + "movq 0x1(%0),%%xmm1 \n" + "movq 0x01(%0,%1,1),%%xmm2 \n" + "punpcklbw %%xmm5,%%xmm1 \n" + "punpcklbw %%xmm5,%%xmm2 \n" + "psubw %%xmm2,%%xmm1 \n" + "movq 0x2(%0),%%xmm2 \n" + "movq 0x02(%0,%1,1),%%xmm3 \n" + "punpcklbw %%xmm5,%%xmm2 \n" + "punpcklbw %%xmm5,%%xmm3 \n" + "psubw %%xmm3,%%xmm2 \n" + "paddw %%xmm2,%%xmm0 \n" + "paddw %%xmm1,%%xmm0 \n" + "paddw %%xmm1,%%xmm0 \n" + "pxor %%xmm1,%%xmm1 \n" + "psubw %%xmm0,%%xmm1 \n" + "pmaxsw %%xmm1,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movq %%xmm0,0x00(%0,%2,1) \n" + "lea 0x8(%0),%0 \n" + "sub $0x8,%3 \n" + "jg 1b \n" : "+r"(src_y0), // %0 "+r"(src_y1), // %1 "+r"(dst_sobely), // %2 @@ -5579,37 +5676,37 @@ void SobelRow_SSE2(const uint8_t* src_sobelx, uint8_t* dst_argb, int width) { asm volatile( - "sub %0,%1 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0x18,%%xmm5 \n" + "sub %0,%1 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "pslld $0x18,%%xmm5 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%1,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "punpcklbw %%xmm0,%%xmm2 \n" - "punpckhbw %%xmm0,%%xmm0 \n" - "movdqa %%xmm2,%%xmm1 \n" - "punpcklwd %%xmm2,%%xmm1 \n" - "punpckhwd %%xmm2,%%xmm2 \n" - "por %%xmm5,%%xmm1 \n" - "por %%xmm5,%%xmm2 \n" - "movdqa %%xmm0,%%xmm3 \n" - "punpcklwd %%xmm0,%%xmm3 \n" - "punpckhwd %%xmm0,%%xmm0 \n" - "por %%xmm5,%%xmm3 \n" - "por %%xmm5,%%xmm0 \n" - "movdqu %%xmm1,(%2) \n" - "movdqu %%xmm2,0x10(%2) \n" - "movdqu %%xmm3,0x20(%2) \n" - "movdqu %%xmm0,0x30(%2) \n" - "lea 0x40(%2),%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%1,1),%%xmm1 \n" + "lea 0x10(%0),%0 \n" + "paddusb %%xmm1,%%xmm0 \n" + "movdqa %%xmm0,%%xmm2 \n" + "punpcklbw %%xmm0,%%xmm2 \n" + "punpckhbw %%xmm0,%%xmm0 \n" + "movdqa %%xmm2,%%xmm1 \n" + "punpcklwd %%xmm2,%%xmm1 \n" + "punpckhwd %%xmm2,%%xmm2 \n" + "por %%xmm5,%%xmm1 \n" + "por %%xmm5,%%xmm2 \n" + "movdqa %%xmm0,%%xmm3 \n" + "punpcklwd %%xmm0,%%xmm3 \n" + "punpckhwd %%xmm0,%%xmm0 \n" + "por %%xmm5,%%xmm3 \n" + "por %%xmm5,%%xmm0 \n" + "movdqu %%xmm1,(%2) \n" + "movdqu %%xmm2,0x10(%2) \n" + "movdqu %%xmm3,0x20(%2) \n" + "movdqu %%xmm0,0x30(%2) \n" + "lea 0x40(%2),%2 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_argb), // %2 @@ -5626,21 +5723,21 @@ void SobelToPlaneRow_SSE2(const uint8_t* src_sobelx, uint8_t* dst_y, int width) { asm volatile( - "sub %0,%1 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0x18,%%xmm5 \n" + "sub %0,%1 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "pslld $0x18,%%xmm5 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%1,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%1,1),%%xmm1 \n" + "lea 0x10(%0),%0 \n" + "paddusb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_y), // %2 @@ -5661,36 +5758,36 @@ void SobelXYRow_SSE2(const uint8_t* src_sobelx, uint8_t* dst_argb, int width) { asm volatile( - "sub %0,%1 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" + "sub %0,%1 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" // 8 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%1,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "paddusb %%xmm1,%%xmm2 \n" - "movdqa %%xmm0,%%xmm3 \n" - "punpcklbw %%xmm5,%%xmm3 \n" - "punpckhbw %%xmm5,%%xmm0 \n" - "movdqa %%xmm1,%%xmm4 \n" - "punpcklbw %%xmm2,%%xmm4 \n" - "punpckhbw %%xmm2,%%xmm1 \n" - "movdqa %%xmm4,%%xmm6 \n" - "punpcklwd %%xmm3,%%xmm6 \n" - "punpckhwd %%xmm3,%%xmm4 \n" - "movdqa %%xmm1,%%xmm7 \n" - "punpcklwd %%xmm0,%%xmm7 \n" - "punpckhwd %%xmm0,%%xmm1 \n" - "movdqu %%xmm6,(%2) \n" - "movdqu %%xmm4,0x10(%2) \n" - "movdqu %%xmm7,0x20(%2) \n" - "movdqu %%xmm1,0x30(%2) \n" - "lea 0x40(%2),%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%1,1),%%xmm1 \n" + "lea 0x10(%0),%0 \n" + "movdqa %%xmm0,%%xmm2 \n" + "paddusb %%xmm1,%%xmm2 \n" + "movdqa %%xmm0,%%xmm3 \n" + "punpcklbw %%xmm5,%%xmm3 \n" + "punpckhbw %%xmm5,%%xmm0 \n" + "movdqa %%xmm1,%%xmm4 \n" + "punpcklbw %%xmm2,%%xmm4 \n" + "punpckhbw %%xmm2,%%xmm1 \n" + "movdqa %%xmm4,%%xmm6 \n" + "punpcklwd %%xmm3,%%xmm6 \n" + "punpckhwd %%xmm3,%%xmm4 \n" + "movdqa %%xmm1,%%xmm7 \n" + "punpcklwd %%xmm0,%%xmm7 \n" + "punpckhwd %%xmm0,%%xmm1 \n" + "movdqu %%xmm6,(%2) \n" + "movdqu %%xmm4,0x10(%2) \n" + "movdqu %%xmm7,0x20(%2) \n" + "movdqu %%xmm1,0x30(%2) \n" + "lea 0x40(%2),%2 \n" + "sub $0x10,%3 \n" + "jg 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_argb), // %2 @@ -5709,67 +5806,67 @@ void ComputeCumulativeSumRow_SSE2(const uint8_t* row, const int32_t* previous_cumsum, int width) { asm volatile( - "pxor %%xmm0,%%xmm0 \n" - "pxor %%xmm1,%%xmm1 \n" - "sub $0x4,%3 \n" - "jl 49f \n" - "test $0xf,%1 \n" - "jne 49f \n" + "pxor %%xmm0,%%xmm0 \n" + "pxor %%xmm1,%%xmm1 \n" + "sub $0x4,%3 \n" + "jl 49f \n" + "test $0xf,%1 \n" + "jne 49f \n" // 4 pixel loop. LABELALIGN "40: \n" - "movdqu (%0),%%xmm2 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm2,%%xmm4 \n" - "punpcklbw %%xmm1,%%xmm2 \n" - "movdqa %%xmm2,%%xmm3 \n" - "punpcklwd %%xmm1,%%xmm2 \n" - "punpckhwd %%xmm1,%%xmm3 \n" - "punpckhbw %%xmm1,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "punpcklwd %%xmm1,%%xmm4 \n" - "punpckhwd %%xmm1,%%xmm5 \n" - "paddd %%xmm2,%%xmm0 \n" - "movdqu (%2),%%xmm2 \n" - "paddd %%xmm0,%%xmm2 \n" - "paddd %%xmm3,%%xmm0 \n" - "movdqu 0x10(%2),%%xmm3 \n" - "paddd %%xmm0,%%xmm3 \n" - "paddd %%xmm4,%%xmm0 \n" - "movdqu 0x20(%2),%%xmm4 \n" - "paddd %%xmm0,%%xmm4 \n" - "paddd %%xmm5,%%xmm0 \n" - "movdqu 0x30(%2),%%xmm5 \n" - "lea 0x40(%2),%2 \n" - "paddd %%xmm0,%%xmm5 \n" - "movdqu %%xmm2,(%1) \n" - "movdqu %%xmm3,0x10(%1) \n" - "movdqu %%xmm4,0x20(%1) \n" - "movdqu %%xmm5,0x30(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x4,%3 \n" - "jge 40b \n" + "movdqu (%0),%%xmm2 \n" + "lea 0x10(%0),%0 \n" + "movdqa %%xmm2,%%xmm4 \n" + "punpcklbw %%xmm1,%%xmm2 \n" + "movdqa %%xmm2,%%xmm3 \n" + "punpcklwd %%xmm1,%%xmm2 \n" + "punpckhwd %%xmm1,%%xmm3 \n" + "punpckhbw %%xmm1,%%xmm4 \n" + "movdqa %%xmm4,%%xmm5 \n" + "punpcklwd %%xmm1,%%xmm4 \n" + "punpckhwd %%xmm1,%%xmm5 \n" + "paddd %%xmm2,%%xmm0 \n" + "movdqu (%2),%%xmm2 \n" + "paddd %%xmm0,%%xmm2 \n" + "paddd %%xmm3,%%xmm0 \n" + "movdqu 0x10(%2),%%xmm3 \n" + "paddd %%xmm0,%%xmm3 \n" + "paddd %%xmm4,%%xmm0 \n" + "movdqu 0x20(%2),%%xmm4 \n" + "paddd %%xmm0,%%xmm4 \n" + "paddd %%xmm5,%%xmm0 \n" + "movdqu 0x30(%2),%%xmm5 \n" + "lea 0x40(%2),%2 \n" + "paddd %%xmm0,%%xmm5 \n" + "movdqu %%xmm2,(%1) \n" + "movdqu %%xmm3,0x10(%1) \n" + "movdqu %%xmm4,0x20(%1) \n" + "movdqu %%xmm5,0x30(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x4,%3 \n" + "jge 40b \n" "49: \n" - "add $0x3,%3 \n" - "jl 19f \n" + "add $0x3,%3 \n" + "jl 19f \n" // 1 pixel loop. LABELALIGN "10: \n" - "movd (%0),%%xmm2 \n" - "lea 0x4(%0),%0 \n" - "punpcklbw %%xmm1,%%xmm2 \n" - "punpcklwd %%xmm1,%%xmm2 \n" - "paddd %%xmm2,%%xmm0 \n" - "movdqu (%2),%%xmm2 \n" - "lea 0x10(%2),%2 \n" - "paddd %%xmm0,%%xmm2 \n" - "movdqu %%xmm2,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x1,%3 \n" - "jge 10b \n" + "movd (%0),%%xmm2 \n" + "lea 0x4(%0),%0 \n" + "punpcklbw %%xmm1,%%xmm2 \n" + "punpcklwd %%xmm1,%%xmm2 \n" + "paddd %%xmm2,%%xmm0 \n" + "movdqu (%2),%%xmm2 \n" + "lea 0x10(%2),%2 \n" + "paddd %%xmm0,%%xmm2 \n" + "movdqu %%xmm2,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x1,%3 \n" + "jge 10b \n" "19: \n" : "+r"(row), // %0 @@ -5789,119 +5886,119 @@ void CumulativeSumToAverageRow_SSE2(const int32_t* topleft, uint8_t* dst, int count) { asm volatile( - "movd %5,%%xmm5 \n" - "cvtdq2ps %%xmm5,%%xmm5 \n" - "rcpss %%xmm5,%%xmm4 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "sub $0x4,%3 \n" - "jl 49f \n" - "cmpl $0x80,%5 \n" - "ja 40f \n" + "movd %5,%%xmm5 \n" + "cvtdq2ps %%xmm5,%%xmm5 \n" + "rcpss %%xmm5,%%xmm4 \n" + "pshufd $0x0,%%xmm4,%%xmm4 \n" + "sub $0x4,%3 \n" + "jl 49f \n" + "cmpl $0x80,%5 \n" + "ja 40f \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "psrld $0x10,%%xmm6 \n" - "cvtdq2ps %%xmm6,%%xmm6 \n" - "addps %%xmm6,%%xmm5 \n" - "mulps %%xmm4,%%xmm5 \n" - "cvtps2dq %%xmm5,%%xmm5 \n" - "packssdw %%xmm5,%%xmm5 \n" + "pshufd $0x0,%%xmm5,%%xmm5 \n" + "pcmpeqb %%xmm6,%%xmm6 \n" + "psrld $0x10,%%xmm6 \n" + "cvtdq2ps %%xmm6,%%xmm6 \n" + "addps %%xmm6,%%xmm5 \n" + "mulps %%xmm4,%%xmm5 \n" + "cvtps2dq %%xmm5,%%xmm5 \n" + "packssdw %%xmm5,%%xmm5 \n" // 4 pixel small loop. LABELALIGN "4: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "psubd 0x00(%0,%4,4),%%xmm0 \n" - "psubd 0x10(%0,%4,4),%%xmm1 \n" - "psubd 0x20(%0,%4,4),%%xmm2 \n" - "psubd 0x30(%0,%4,4),%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "psubd (%1),%%xmm0 \n" - "psubd 0x10(%1),%%xmm1 \n" - "psubd 0x20(%1),%%xmm2 \n" - "psubd 0x30(%1),%%xmm3 \n" - "paddd 0x00(%1,%4,4),%%xmm0 \n" - "paddd 0x10(%1,%4,4),%%xmm1 \n" - "paddd 0x20(%1,%4,4),%%xmm2 \n" - "paddd 0x30(%1,%4,4),%%xmm3 \n" - "lea 0x40(%1),%1 \n" - "packssdw %%xmm1,%%xmm0 \n" - "packssdw %%xmm3,%%xmm2 \n" - "pmulhuw %%xmm5,%%xmm0 \n" - "pmulhuw %%xmm5,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jge 4b \n" - "jmp 49f \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x30(%0),%%xmm3 \n" + "psubd 0x00(%0,%4,4),%%xmm0 \n" + "psubd 0x10(%0,%4,4),%%xmm1 \n" + "psubd 0x20(%0,%4,4),%%xmm2 \n" + "psubd 0x30(%0,%4,4),%%xmm3 \n" + "lea 0x40(%0),%0 \n" + "psubd (%1),%%xmm0 \n" + "psubd 0x10(%1),%%xmm1 \n" + "psubd 0x20(%1),%%xmm2 \n" + "psubd 0x30(%1),%%xmm3 \n" + "paddd 0x00(%1,%4,4),%%xmm0 \n" + "paddd 0x10(%1,%4,4),%%xmm1 \n" + "paddd 0x20(%1,%4,4),%%xmm2 \n" + "paddd 0x30(%1,%4,4),%%xmm3 \n" + "lea 0x40(%1),%1 \n" + "packssdw %%xmm1,%%xmm0 \n" + "packssdw %%xmm3,%%xmm2 \n" + "pmulhuw %%xmm5,%%xmm0 \n" + "pmulhuw %%xmm5,%%xmm2 \n" + "packuswb %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%3 \n" + "jge 4b \n" + "jmp 49f \n" // 4 pixel loop LABELALIGN "40: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "psubd 0x00(%0,%4,4),%%xmm0 \n" - "psubd 0x10(%0,%4,4),%%xmm1 \n" - "psubd 0x20(%0,%4,4),%%xmm2 \n" - "psubd 0x30(%0,%4,4),%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "psubd (%1),%%xmm0 \n" - "psubd 0x10(%1),%%xmm1 \n" - "psubd 0x20(%1),%%xmm2 \n" - "psubd 0x30(%1),%%xmm3 \n" - "paddd 0x00(%1,%4,4),%%xmm0 \n" - "paddd 0x10(%1,%4,4),%%xmm1 \n" - "paddd 0x20(%1,%4,4),%%xmm2 \n" - "paddd 0x30(%1,%4,4),%%xmm3 \n" - "lea 0x40(%1),%1 \n" - "cvtdq2ps %%xmm0,%%xmm0 \n" - "cvtdq2ps %%xmm1,%%xmm1 \n" - "mulps %%xmm4,%%xmm0 \n" - "mulps %%xmm4,%%xmm1 \n" - "cvtdq2ps %%xmm2,%%xmm2 \n" - "cvtdq2ps %%xmm3,%%xmm3 \n" - "mulps %%xmm4,%%xmm2 \n" - "mulps %%xmm4,%%xmm3 \n" - "cvtps2dq %%xmm0,%%xmm0 \n" - "cvtps2dq %%xmm1,%%xmm1 \n" - "cvtps2dq %%xmm2,%%xmm2 \n" - "cvtps2dq %%xmm3,%%xmm3 \n" - "packssdw %%xmm1,%%xmm0 \n" - "packssdw %%xmm3,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jge 40b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x20(%0),%%xmm2 \n" + "movdqu 0x30(%0),%%xmm3 \n" + "psubd 0x00(%0,%4,4),%%xmm0 \n" + "psubd 0x10(%0,%4,4),%%xmm1 \n" + "psubd 0x20(%0,%4,4),%%xmm2 \n" + "psubd 0x30(%0,%4,4),%%xmm3 \n" + "lea 0x40(%0),%0 \n" + "psubd (%1),%%xmm0 \n" + "psubd 0x10(%1),%%xmm1 \n" + "psubd 0x20(%1),%%xmm2 \n" + "psubd 0x30(%1),%%xmm3 \n" + "paddd 0x00(%1,%4,4),%%xmm0 \n" + "paddd 0x10(%1,%4,4),%%xmm1 \n" + "paddd 0x20(%1,%4,4),%%xmm2 \n" + "paddd 0x30(%1,%4,4),%%xmm3 \n" + "lea 0x40(%1),%1 \n" + "cvtdq2ps %%xmm0,%%xmm0 \n" + "cvtdq2ps %%xmm1,%%xmm1 \n" + "mulps %%xmm4,%%xmm0 \n" + "mulps %%xmm4,%%xmm1 \n" + "cvtdq2ps %%xmm2,%%xmm2 \n" + "cvtdq2ps %%xmm3,%%xmm3 \n" + "mulps %%xmm4,%%xmm2 \n" + "mulps %%xmm4,%%xmm3 \n" + "cvtps2dq %%xmm0,%%xmm0 \n" + "cvtps2dq %%xmm1,%%xmm1 \n" + "cvtps2dq %%xmm2,%%xmm2 \n" + "cvtps2dq %%xmm3,%%xmm3 \n" + "packssdw %%xmm1,%%xmm0 \n" + "packssdw %%xmm3,%%xmm2 \n" + "packuswb %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%3 \n" + "jge 40b \n" "49: \n" - "add $0x3,%3 \n" - "jl 19f \n" + "add $0x3,%3 \n" + "jl 19f \n" // 1 pixel loop LABELALIGN "10: \n" - "movdqu (%0),%%xmm0 \n" - "psubd 0x00(%0,%4,4),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "psubd (%1),%%xmm0 \n" - "paddd 0x00(%1,%4,4),%%xmm0 \n" - "lea 0x10(%1),%1 \n" - "cvtdq2ps %%xmm0,%%xmm0 \n" - "mulps %%xmm4,%%xmm0 \n" - "cvtps2dq %%xmm0,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movd %%xmm0,(%2) \n" - "lea 0x4(%2),%2 \n" - "sub $0x1,%3 \n" - "jge 10b \n" + "movdqu (%0),%%xmm0 \n" + "psubd 0x00(%0,%4,4),%%xmm0 \n" + "lea 0x10(%0),%0 \n" + "psubd (%1),%%xmm0 \n" + "paddd 0x00(%1,%4,4),%%xmm0 \n" + "lea 0x10(%1),%1 \n" + "cvtdq2ps %%xmm0,%%xmm0 \n" + "mulps %%xmm4,%%xmm0 \n" + "cvtps2dq %%xmm0,%%xmm0 \n" + "packssdw %%xmm0,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movd %%xmm0,(%2) \n" + "lea 0x4(%2),%2 \n" + "sub $0x1,%3 \n" + "jge 10b \n" "19: \n" : "+r"(topleft), // %0 "+r"(botleft), // %1 @@ -5924,70 +6021,70 @@ void ARGBAffineRow_SSE2(const uint8_t* src_argb, intptr_t src_argb_stride_temp = src_argb_stride; intptr_t temp; asm volatile( - "movq (%3),%%xmm2 \n" - "movq 0x08(%3),%%xmm7 \n" - "shl $0x10,%1 \n" - "add $0x4,%1 \n" - "movd %1,%%xmm5 \n" - "sub $0x4,%4 \n" - "jl 49f \n" + "movq (%3),%%xmm2 \n" + "movq 0x08(%3),%%xmm7 \n" + "shl $0x10,%1 \n" + "add $0x4,%1 \n" + "movd %1,%%xmm5 \n" + "sub $0x4,%4 \n" + "jl 49f \n" - "pshufd $0x44,%%xmm7,%%xmm7 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "movdqa %%xmm2,%%xmm0 \n" - "addps %%xmm7,%%xmm0 \n" - "movlhps %%xmm0,%%xmm2 \n" - "movdqa %%xmm7,%%xmm4 \n" - "addps %%xmm4,%%xmm4 \n" - "movdqa %%xmm2,%%xmm3 \n" - "addps %%xmm4,%%xmm3 \n" - "addps %%xmm4,%%xmm4 \n" + "pshufd $0x44,%%xmm7,%%xmm7 \n" + "pshufd $0x0,%%xmm5,%%xmm5 \n" + "movdqa %%xmm2,%%xmm0 \n" + "addps %%xmm7,%%xmm0 \n" + "movlhps %%xmm0,%%xmm2 \n" + "movdqa %%xmm7,%%xmm4 \n" + "addps %%xmm4,%%xmm4 \n" + "movdqa %%xmm2,%%xmm3 \n" + "addps %%xmm4,%%xmm3 \n" + "addps %%xmm4,%%xmm4 \n" // 4 pixel loop LABELALIGN "40: \n" - "cvttps2dq %%xmm2,%%xmm0 \n" // x,y float->int first 2 - "cvttps2dq %%xmm3,%%xmm1 \n" // x,y float->int next 2 - "packssdw %%xmm1,%%xmm0 \n" // x, y as 8 shorts - "pmaddwd %%xmm5,%%xmm0 \n" // off = x*4 + y*stride - "movd %%xmm0,%k1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movd %%xmm0,%k5 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movd 0x00(%0,%1,1),%%xmm1 \n" - "movd 0x00(%0,%5,1),%%xmm6 \n" - "punpckldq %%xmm6,%%xmm1 \n" - "addps %%xmm4,%%xmm2 \n" - "movq %%xmm1,(%2) \n" - "movd %%xmm0,%k1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movd %%xmm0,%k5 \n" - "movd 0x00(%0,%1,1),%%xmm0 \n" - "movd 0x00(%0,%5,1),%%xmm6 \n" - "punpckldq %%xmm6,%%xmm0 \n" - "addps %%xmm4,%%xmm3 \n" - "movq %%xmm0,0x08(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%4 \n" - "jge 40b \n" + "cvttps2dq %%xmm2,%%xmm0 \n" // x,y float->int first 2 + "cvttps2dq %%xmm3,%%xmm1 \n" // x,y float->int next 2 + "packssdw %%xmm1,%%xmm0 \n" // x, y as 8 shorts + "pmaddwd %%xmm5,%%xmm0 \n" // off = x*4 + y*stride + "movd %%xmm0,%k1 \n" + "pshufd $0x39,%%xmm0,%%xmm0 \n" + "movd %%xmm0,%k5 \n" + "pshufd $0x39,%%xmm0,%%xmm0 \n" + "movd 0x00(%0,%1,1),%%xmm1 \n" + "movd 0x00(%0,%5,1),%%xmm6 \n" + "punpckldq %%xmm6,%%xmm1 \n" + "addps %%xmm4,%%xmm2 \n" + "movq %%xmm1,(%2) \n" + "movd %%xmm0,%k1 \n" + "pshufd $0x39,%%xmm0,%%xmm0 \n" + "movd %%xmm0,%k5 \n" + "movd 0x00(%0,%1,1),%%xmm0 \n" + "movd 0x00(%0,%5,1),%%xmm6 \n" + "punpckldq %%xmm6,%%xmm0 \n" + "addps %%xmm4,%%xmm3 \n" + "movq %%xmm0,0x08(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%4 \n" + "jge 40b \n" "49: \n" - "add $0x3,%4 \n" - "jl 19f \n" + "add $0x3,%4 \n" + "jl 19f \n" // 1 pixel loop LABELALIGN "10: \n" - "cvttps2dq %%xmm2,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "pmaddwd %%xmm5,%%xmm0 \n" - "addps %%xmm7,%%xmm2 \n" - "movd %%xmm0,%k1 \n" - "movd 0x00(%0,%1,1),%%xmm0 \n" - "movd %%xmm0,(%2) \n" - "lea 0x04(%2),%2 \n" - "sub $0x1,%4 \n" - "jge 10b \n" + "cvttps2dq %%xmm2,%%xmm0 \n" + "packssdw %%xmm0,%%xmm0 \n" + "pmaddwd %%xmm5,%%xmm0 \n" + "addps %%xmm7,%%xmm2 \n" + "movd %%xmm0,%k1 \n" + "movd 0x00(%0,%1,1),%%xmm0 \n" + "movd %%xmm0,(%2) \n" + "lea 0x04(%2),%2 \n" + "sub $0x1,%4 \n" + "jge 10b \n" "19: \n" : "+r"(src_argb), // %0 "+r"(src_argb_stride_temp), // %1 @@ -6009,68 +6106,68 @@ void InterpolateRow_SSSE3(uint8_t* dst_ptr, int dst_width, int source_y_fraction) { asm volatile( - "sub %1,%0 \n" - "cmp $0x0,%3 \n" - "je 100f \n" - "cmp $0x80,%3 \n" - "je 50f \n" + "sub %1,%0 \n" + "cmp $0x0,%3 \n" + "je 100f \n" + "cmp $0x80,%3 \n" + "je 50f \n" - "movd %3,%%xmm0 \n" - "neg %3 \n" - "add $0x100,%3 \n" - "movd %3,%%xmm5 \n" - "punpcklbw %%xmm0,%%xmm5 \n" - "punpcklwd %%xmm5,%%xmm5 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "mov $0x80808080,%%eax \n" - "movd %%eax,%%xmm4 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" + "movd %3,%%xmm0 \n" + "neg %3 \n" + "add $0x100,%3 \n" + "movd %3,%%xmm5 \n" + "punpcklbw %%xmm0,%%xmm5 \n" + "punpcklwd %%xmm5,%%xmm5 \n" + "pshufd $0x0,%%xmm5,%%xmm5 \n" + "mov $0x80808080,%%eax \n" + "movd %%eax,%%xmm4 \n" + "pshufd $0x0,%%xmm4,%%xmm4 \n" // General purpose row blend. LABELALIGN "1: \n" - "movdqu (%1),%%xmm0 \n" - "movdqu 0x00(%1,%4,1),%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm2,%%xmm0 \n" - "punpckhbw %%xmm2,%%xmm1 \n" - "psubb %%xmm4,%%xmm0 \n" - "psubb %%xmm4,%%xmm1 \n" - "movdqa %%xmm5,%%xmm2 \n" - "movdqa %%xmm5,%%xmm3 \n" - "pmaddubsw %%xmm0,%%xmm2 \n" - "pmaddubsw %%xmm1,%%xmm3 \n" - "paddw %%xmm4,%%xmm2 \n" - "paddw %%xmm4,%%xmm3 \n" - "psrlw $0x8,%%xmm2 \n" - "psrlw $0x8,%%xmm3 \n" - "packuswb %%xmm3,%%xmm2 \n" - "movdqu %%xmm2,0x00(%1,%0,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "jmp 99f \n" + "movdqu (%1),%%xmm0 \n" + "movdqu 0x00(%1,%4,1),%%xmm2 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklbw %%xmm2,%%xmm0 \n" + "punpckhbw %%xmm2,%%xmm1 \n" + "psubb %%xmm4,%%xmm0 \n" + "psubb %%xmm4,%%xmm1 \n" + "movdqa %%xmm5,%%xmm2 \n" + "movdqa %%xmm5,%%xmm3 \n" + "pmaddubsw %%xmm0,%%xmm2 \n" + "pmaddubsw %%xmm1,%%xmm3 \n" + "paddw %%xmm4,%%xmm2 \n" + "paddw %%xmm4,%%xmm3 \n" + "psrlw $0x8,%%xmm2 \n" + "psrlw $0x8,%%xmm3 \n" + "packuswb %%xmm3,%%xmm2 \n" + "movdqu %%xmm2,0x00(%1,%0,1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" + "jmp 99f \n" // Blend 50 / 50. LABELALIGN "50: \n" - "movdqu (%1),%%xmm0 \n" - "movdqu 0x00(%1,%4,1),%%xmm1 \n" - "pavgb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,0x00(%1,%0,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 50b \n" - "jmp 99f \n" + "movdqu (%1),%%xmm0 \n" + "movdqu 0x00(%1,%4,1),%%xmm1 \n" + "pavgb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,0x00(%1,%0,1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 50b \n" + "jmp 99f \n" // Blend 100 / 0 - Copy row unchanged. LABELALIGN "100: \n" - "movdqu (%1),%%xmm0 \n" - "movdqu %%xmm0,0x00(%1,%0,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 100b \n" + "movdqu (%1),%%xmm0 \n" + "movdqu %%xmm0,0x00(%1,%0,1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 100b \n" "99: \n" : "+r"(dst_ptr), // %0 @@ -6090,61 +6187,61 @@ void InterpolateRow_AVX2(uint8_t* dst_ptr, int dst_width, int source_y_fraction) { asm volatile( - "cmp $0x0,%3 \n" - "je 100f \n" - "sub %1,%0 \n" - "cmp $0x80,%3 \n" - "je 50f \n" + "cmp $0x0,%3 \n" + "je 100f \n" + "sub %1,%0 \n" + "cmp $0x80,%3 \n" + "je 50f \n" - "vmovd %3,%%xmm0 \n" - "neg %3 \n" - "add $0x100,%3 \n" - "vmovd %3,%%xmm5 \n" - "vpunpcklbw %%xmm0,%%xmm5,%%xmm5 \n" - "vpunpcklwd %%xmm5,%%xmm5,%%xmm5 \n" + "vmovd %3,%%xmm0 \n" + "neg %3 \n" + "add $0x100,%3 \n" + "vmovd %3,%%xmm5 \n" + "vpunpcklbw %%xmm0,%%xmm5,%%xmm5 \n" + "vpunpcklwd %%xmm5,%%xmm5,%%xmm5 \n" "vbroadcastss %%xmm5,%%ymm5 \n" - "mov $0x80808080,%%eax \n" - "vmovd %%eax,%%xmm4 \n" + "mov $0x80808080,%%eax \n" + "vmovd %%eax,%%xmm4 \n" "vbroadcastss %%xmm4,%%ymm4 \n" // General purpose row blend. LABELALIGN "1: \n" - "vmovdqu (%1),%%ymm0 \n" - "vmovdqu 0x00(%1,%4,1),%%ymm2 \n" - "vpunpckhbw %%ymm2,%%ymm0,%%ymm1 \n" - "vpunpcklbw %%ymm2,%%ymm0,%%ymm0 \n" - "vpsubb %%ymm4,%%ymm1,%%ymm1 \n" - "vpsubb %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm1,%%ymm5,%%ymm1 \n" - "vpmaddubsw %%ymm0,%%ymm5,%%ymm0 \n" - "vpaddw %%ymm4,%%ymm1,%%ymm1 \n" - "vpaddw %%ymm4,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,0x00(%1,%0,1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "jmp 99f \n" + "vmovdqu (%1),%%ymm0 \n" + "vmovdqu 0x00(%1,%4,1),%%ymm2 \n" + "vpunpckhbw %%ymm2,%%ymm0,%%ymm1 \n" + "vpunpcklbw %%ymm2,%%ymm0,%%ymm0 \n" + "vpsubb %%ymm4,%%ymm1,%%ymm1 \n" + "vpsubb %%ymm4,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm1,%%ymm5,%%ymm1 \n" + "vpmaddubsw %%ymm0,%%ymm5,%%ymm0 \n" + "vpaddw %%ymm4,%%ymm1,%%ymm1 \n" + "vpaddw %%ymm4,%%ymm0,%%ymm0 \n" + "vpsrlw $0x8,%%ymm1,%%ymm1 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,0x00(%1,%0,1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" + "jmp 99f \n" // Blend 50 / 50. LABELALIGN "50: \n" - "vmovdqu (%1),%%ymm0 \n" - "vpavgb 0x00(%1,%4,1),%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,0x00(%1,%0,1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 50b \n" - "jmp 99f \n" + "vmovdqu (%1),%%ymm0 \n" + "vpavgb 0x00(%1,%4,1),%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,0x00(%1,%0,1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 50b \n" + "jmp 99f \n" // Blend 100 / 0 - Copy row unchanged. LABELALIGN "100: \n" - "rep movsb \n" - "jmp 999f \n" + "rep movsb \n" + "jmp 999f \n" "99: \n" "vzeroupper \n" @@ -6166,20 +6263,20 @@ void ARGBShuffleRow_SSSE3(const uint8_t* src_argb, int width) { asm volatile( - "movdqu (%3),%%xmm5 \n" + "movdqu (%3),%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pshufb %%xmm5,%%xmm0 \n" - "pshufb %%xmm5,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "pshufb %%xmm5,%%xmm0 \n" + "pshufb %%xmm5,%%xmm1 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu %%xmm1,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -6200,16 +6297,16 @@ void ARGBShuffleRow_AVX2(const uint8_t* src_argb, LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" - "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" + "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" + "vmovdqu %%ymm0,(%1) \n" + "vmovdqu %%ymm1,0x20(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 @@ -6227,24 +6324,24 @@ void I422ToYUY2Row_SSE2(const uint8_t* src_y, int width) { asm volatile( - "sub %1,%2 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movq (%1),%%xmm2 \n" - "movq 0x00(%1,%2,1),%%xmm1 \n" - "add $0x8,%1 \n" - "punpcklbw %%xmm1,%%xmm2 \n" - "movdqu (%0),%%xmm0 \n" - "add $0x10,%0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm2,%%xmm0 \n" - "punpckhbw %%xmm2,%%xmm1 \n" - "movdqu %%xmm0,(%3) \n" - "movdqu %%xmm1,0x10(%3) \n" - "lea 0x20(%3),%3 \n" - "sub $0x10,%4 \n" - "jg 1b \n" + "movq (%1),%%xmm2 \n" + "movq 0x00(%1,%2,1),%%xmm1 \n" + "add $0x8,%1 \n" + "punpcklbw %%xmm1,%%xmm2 \n" + "movdqu (%0),%%xmm0 \n" + "add $0x10,%0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklbw %%xmm2,%%xmm0 \n" + "punpckhbw %%xmm2,%%xmm1 \n" + "movdqu %%xmm0,(%3) \n" + "movdqu %%xmm1,0x10(%3) \n" + "lea 0x20(%3),%3 \n" + "sub $0x10,%4 \n" + "jg 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -6263,24 +6360,24 @@ void I422ToUYVYRow_SSE2(const uint8_t* src_y, int width) { asm volatile( - "sub %1,%2 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "movq (%1),%%xmm2 \n" - "movq 0x00(%1,%2,1),%%xmm1 \n" - "add $0x8,%1 \n" - "punpcklbw %%xmm1,%%xmm2 \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm2,%%xmm1 \n" - "add $0x10,%0 \n" - "punpcklbw %%xmm0,%%xmm1 \n" - "punpckhbw %%xmm0,%%xmm2 \n" - "movdqu %%xmm1,(%3) \n" - "movdqu %%xmm2,0x10(%3) \n" - "lea 0x20(%3),%3 \n" - "sub $0x10,%4 \n" - "jg 1b \n" + "movq (%1),%%xmm2 \n" + "movq 0x00(%1,%2,1),%%xmm1 \n" + "add $0x8,%1 \n" + "punpcklbw %%xmm1,%%xmm2 \n" + "movdqu (%0),%%xmm0 \n" + "movdqa %%xmm2,%%xmm1 \n" + "add $0x10,%0 \n" + "punpcklbw %%xmm0,%%xmm1 \n" + "punpckhbw %%xmm0,%%xmm2 \n" + "movdqu %%xmm1,(%3) \n" + "movdqu %%xmm2,0x10(%3) \n" + "lea 0x20(%3),%3 \n" + "sub $0x10,%4 \n" + "jg 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -6299,26 +6396,26 @@ void I422ToYUY2Row_AVX2(const uint8_t* src_y, int width) { asm volatile( - "sub %1,%2 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vpmovzxbw (%1),%%ymm1 \n" - "vpmovzxbw 0x00(%1,%2,1),%%ymm2 \n" - "add $0x10,%1 \n" - "vpsllw $0x8,%%ymm2,%%ymm2 \n" - "vpor %%ymm1,%%ymm2,%%ymm2 \n" - "vmovdqu (%0),%%ymm0 \n" - "add $0x20,%0 \n" - "vpunpcklbw %%ymm2,%%ymm0,%%ymm1 \n" - "vpunpckhbw %%ymm2,%%ymm0,%%ymm2 \n" + "vpmovzxbw (%1),%%ymm1 \n" + "vpmovzxbw 0x00(%1,%2,1),%%ymm2 \n" + "add $0x10,%1 \n" + "vpsllw $0x8,%%ymm2,%%ymm2 \n" + "vpor %%ymm1,%%ymm2,%%ymm2 \n" + "vmovdqu (%0),%%ymm0 \n" + "add $0x20,%0 \n" + "vpunpcklbw %%ymm2,%%ymm0,%%ymm1 \n" + "vpunpckhbw %%ymm2,%%ymm0,%%ymm2 \n" "vextractf128 $0x0,%%ymm1,(%3) \n" "vextractf128 $0x0,%%ymm2,0x10(%3) \n" "vextractf128 $0x1,%%ymm1,0x20(%3) \n" "vextractf128 $0x1,%%ymm2,0x30(%3) \n" - "lea 0x40(%3),%3 \n" - "sub $0x20,%4 \n" - "jg 1b \n" + "lea 0x40(%3),%3 \n" + "sub $0x20,%4 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 @@ -6338,26 +6435,26 @@ void I422ToUYVYRow_AVX2(const uint8_t* src_y, int width) { asm volatile( - "sub %1,%2 \n" + "sub %1,%2 \n" LABELALIGN "1: \n" - "vpmovzxbw (%1),%%ymm1 \n" - "vpmovzxbw 0x00(%1,%2,1),%%ymm2 \n" - "add $0x10,%1 \n" - "vpsllw $0x8,%%ymm2,%%ymm2 \n" - "vpor %%ymm1,%%ymm2,%%ymm2 \n" - "vmovdqu (%0),%%ymm0 \n" - "add $0x20,%0 \n" - "vpunpcklbw %%ymm0,%%ymm2,%%ymm1 \n" - "vpunpckhbw %%ymm0,%%ymm2,%%ymm2 \n" + "vpmovzxbw (%1),%%ymm1 \n" + "vpmovzxbw 0x00(%1,%2,1),%%ymm2 \n" + "add $0x10,%1 \n" + "vpsllw $0x8,%%ymm2,%%ymm2 \n" + "vpor %%ymm1,%%ymm2,%%ymm2 \n" + "vmovdqu (%0),%%ymm0 \n" + "add $0x20,%0 \n" + "vpunpcklbw %%ymm0,%%ymm2,%%ymm1 \n" + "vpunpckhbw %%ymm0,%%ymm2,%%ymm2 \n" "vextractf128 $0x0,%%ymm1,(%3) \n" "vextractf128 $0x0,%%ymm2,0x10(%3) \n" "vextractf128 $0x1,%%ymm1,0x20(%3) \n" "vextractf128 $0x1,%%ymm2,0x30(%3) \n" - "lea 0x40(%3),%3 \n" - "sub $0x20,%4 \n" - "jg 1b \n" + "lea 0x40(%3),%3 \n" + "sub $0x20,%4 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 @@ -6376,47 +6473,47 @@ void ARGBPolynomialRow_SSE2(const uint8_t* src_argb, int width) { asm volatile( - "pxor %%xmm3,%%xmm3 \n" + "pxor %%xmm3,%%xmm3 \n" // 2 pixel loop. LABELALIGN "1: \n" - "movq (%0),%%xmm0 \n" - "lea 0x8(%0),%0 \n" - "punpcklbw %%xmm3,%%xmm0 \n" - "movdqa %%xmm0,%%xmm4 \n" - "punpcklwd %%xmm3,%%xmm0 \n" - "punpckhwd %%xmm3,%%xmm4 \n" - "cvtdq2ps %%xmm0,%%xmm0 \n" - "cvtdq2ps %%xmm4,%%xmm4 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm4,%%xmm5 \n" - "mulps 0x10(%3),%%xmm0 \n" - "mulps 0x10(%3),%%xmm4 \n" - "addps (%3),%%xmm0 \n" - "addps (%3),%%xmm4 \n" - "movdqa %%xmm1,%%xmm2 \n" - "movdqa %%xmm5,%%xmm6 \n" - "mulps %%xmm1,%%xmm2 \n" - "mulps %%xmm5,%%xmm6 \n" - "mulps %%xmm2,%%xmm1 \n" - "mulps %%xmm6,%%xmm5 \n" - "mulps 0x20(%3),%%xmm2 \n" - "mulps 0x20(%3),%%xmm6 \n" - "mulps 0x30(%3),%%xmm1 \n" - "mulps 0x30(%3),%%xmm5 \n" - "addps %%xmm2,%%xmm0 \n" - "addps %%xmm6,%%xmm4 \n" - "addps %%xmm1,%%xmm0 \n" - "addps %%xmm5,%%xmm4 \n" - "cvttps2dq %%xmm0,%%xmm0 \n" - "cvttps2dq %%xmm4,%%xmm4 \n" - "packuswb %%xmm4,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x2,%2 \n" - "jg 1b \n" + "movq (%0),%%xmm0 \n" + "lea 0x8(%0),%0 \n" + "punpcklbw %%xmm3,%%xmm0 \n" + "movdqa %%xmm0,%%xmm4 \n" + "punpcklwd %%xmm3,%%xmm0 \n" + "punpckhwd %%xmm3,%%xmm4 \n" + "cvtdq2ps %%xmm0,%%xmm0 \n" + "cvtdq2ps %%xmm4,%%xmm4 \n" + "movdqa %%xmm0,%%xmm1 \n" + "movdqa %%xmm4,%%xmm5 \n" + "mulps 0x10(%3),%%xmm0 \n" + "mulps 0x10(%3),%%xmm4 \n" + "addps (%3),%%xmm0 \n" + "addps (%3),%%xmm4 \n" + "movdqa %%xmm1,%%xmm2 \n" + "movdqa %%xmm5,%%xmm6 \n" + "mulps %%xmm1,%%xmm2 \n" + "mulps %%xmm5,%%xmm6 \n" + "mulps %%xmm2,%%xmm1 \n" + "mulps %%xmm6,%%xmm5 \n" + "mulps 0x20(%3),%%xmm2 \n" + "mulps 0x20(%3),%%xmm6 \n" + "mulps 0x30(%3),%%xmm1 \n" + "mulps 0x30(%3),%%xmm5 \n" + "addps %%xmm2,%%xmm0 \n" + "addps %%xmm6,%%xmm4 \n" + "addps %%xmm1,%%xmm0 \n" + "addps %%xmm5,%%xmm4 \n" + "cvttps2dq %%xmm0,%%xmm0 \n" + "cvttps2dq %%xmm4,%%xmm4 \n" + "packuswb %%xmm4,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movq %%xmm0,(%1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x2,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -6512,27 +6609,27 @@ void HalfFloatRow_AVX2(const uint16_t* src, int width) { scale *= kScaleBias; asm volatile( - "vbroadcastss %3, %%ymm4 \n" - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" - "sub %0,%1 \n" + "vbroadcastss %3, %%ymm4 \n" + "vpxor %%ymm5,%%ymm5,%%ymm5 \n" + "sub %0,%1 \n" // 16 pixel loop. LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm2 \n" // 16 shorts - "add $0x20,%0 \n" - "vpunpckhwd %%ymm5,%%ymm2,%%ymm3 \n" // mutates - "vpunpcklwd %%ymm5,%%ymm2,%%ymm2 \n" - "vcvtdq2ps %%ymm3,%%ymm3 \n" - "vcvtdq2ps %%ymm2,%%ymm2 \n" - "vmulps %%ymm3,%%ymm4,%%ymm3 \n" - "vmulps %%ymm2,%%ymm4,%%ymm2 \n" - "vpsrld $0xd,%%ymm3,%%ymm3 \n" - "vpsrld $0xd,%%ymm2,%%ymm2 \n" - "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // unmutates - "vmovdqu %%ymm2,-0x20(%0,%1,1) \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm2 \n" // 16 shorts + "add $0x20,%0 \n" + "vpunpckhwd %%ymm5,%%ymm2,%%ymm3 \n" // mutates + "vpunpcklwd %%ymm5,%%ymm2,%%ymm2 \n" + "vcvtdq2ps %%ymm3,%%ymm3 \n" + "vcvtdq2ps %%ymm2,%%ymm2 \n" + "vmulps %%ymm3,%%ymm4,%%ymm3 \n" + "vmulps %%ymm2,%%ymm4,%%ymm2 \n" + "vpsrld $0xd,%%ymm3,%%ymm3 \n" + "vpsrld $0xd,%%ymm2,%%ymm2 \n" + "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // unmutates + "vmovdqu %%ymm2,-0x20(%0,%1,1) \n" + "sub $0x10,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src), // %0 @@ -6553,8 +6650,8 @@ void HalfFloatRow_F16C(const uint16_t* src, float scale, int width) { asm volatile( - "vbroadcastss %3, %%ymm4 \n" - "sub %0,%1 \n" + "vbroadcastss %3, %%ymm4 \n" + "sub %0,%1 \n" // 16 pixel loop. LABELALIGN @@ -6588,7 +6685,7 @@ void HalfFloatRow_F16C(const uint16_t* src, #ifdef HAS_HALFFLOATROW_F16C void HalfFloat1Row_F16C(const uint16_t* src, uint16_t* dst, float, int width) { asm volatile( - "sub %0,%1 \n" + "sub %0,%1 \n" // 16 pixel loop. LABELALIGN "1: \n" @@ -6622,21 +6719,21 @@ void ARGBColorTableRow_X86(uint8_t* dst_argb, // 1 pixel loop. LABELALIGN "1: \n" - "movzb (%0),%1 \n" - "lea 0x4(%0),%0 \n" - "movzb 0x00(%3,%1,4),%1 \n" - "mov %b1,-0x4(%0) \n" - "movzb -0x3(%0),%1 \n" - "movzb 0x01(%3,%1,4),%1 \n" - "mov %b1,-0x3(%0) \n" - "movzb -0x2(%0),%1 \n" - "movzb 0x02(%3,%1,4),%1 \n" - "mov %b1,-0x2(%0) \n" - "movzb -0x1(%0),%1 \n" - "movzb 0x03(%3,%1,4),%1 \n" - "mov %b1,-0x1(%0) \n" - "dec %2 \n" - "jg 1b \n" + "movzb (%0),%1 \n" + "lea 0x4(%0),%0 \n" + "movzb 0x00(%3,%1,4),%1 \n" + "mov %b1,-0x4(%0) \n" + "movzb -0x3(%0),%1 \n" + "movzb 0x01(%3,%1,4),%1 \n" + "mov %b1,-0x3(%0) \n" + "movzb -0x2(%0),%1 \n" + "movzb 0x02(%3,%1,4),%1 \n" + "mov %b1,-0x2(%0) \n" + "movzb -0x1(%0),%1 \n" + "movzb 0x03(%3,%1,4),%1 \n" + "mov %b1,-0x1(%0) \n" + "dec %2 \n" + "jg 1b \n" : "+r"(dst_argb), // %0 "=&d"(pixel_temp), // %1 "+r"(width) // %2 @@ -6655,18 +6752,18 @@ void RGBColorTableRow_X86(uint8_t* dst_argb, // 1 pixel loop. LABELALIGN "1: \n" - "movzb (%0),%1 \n" - "lea 0x4(%0),%0 \n" - "movzb 0x00(%3,%1,4),%1 \n" - "mov %b1,-0x4(%0) \n" - "movzb -0x3(%0),%1 \n" - "movzb 0x01(%3,%1,4),%1 \n" - "mov %b1,-0x3(%0) \n" - "movzb -0x2(%0),%1 \n" - "movzb 0x02(%3,%1,4),%1 \n" - "mov %b1,-0x2(%0) \n" - "dec %2 \n" - "jg 1b \n" + "movzb (%0),%1 \n" + "lea 0x4(%0),%0 \n" + "movzb 0x00(%3,%1,4),%1 \n" + "mov %b1,-0x4(%0) \n" + "movzb -0x3(%0),%1 \n" + "movzb 0x01(%3,%1,4),%1 \n" + "mov %b1,-0x3(%0) \n" + "movzb -0x2(%0),%1 \n" + "movzb 0x02(%3,%1,4),%1 \n" + "mov %b1,-0x2(%0) \n" + "dec %2 \n" + "jg 1b \n" : "+r"(dst_argb), // %0 "=&d"(pixel_temp), // %1 "+r"(width) // %2 @@ -6685,86 +6782,86 @@ void ARGBLumaColorTableRow_SSSE3(const uint8_t* src_argb, uintptr_t pixel_temp; uintptr_t table_temp; asm volatile( - "movd %6,%%xmm3 \n" - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "psllw $0x8,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" + "movd %6,%%xmm3 \n" + "pshufd $0x0,%%xmm3,%%xmm3 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psllw $0x8,%%xmm4 \n" + "pxor %%xmm5,%%xmm5 \n" // 4 pixel loop. LABELALIGN "1: \n" - "movdqu (%2),%%xmm0 \n" - "pmaddubsw %%xmm3,%%xmm0 \n" - "phaddw %%xmm0,%%xmm0 \n" - "pand %%xmm4,%%xmm0 \n" - "punpcklwd %%xmm5,%%xmm0 \n" - "movd %%xmm0,%k1 \n" // 32 bit offset - "add %5,%1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" + "movdqu (%2),%%xmm0 \n" + "pmaddubsw %%xmm3,%%xmm0 \n" + "phaddw %%xmm0,%%xmm0 \n" + "pand %%xmm4,%%xmm0 \n" + "punpcklwd %%xmm5,%%xmm0 \n" + "movd %%xmm0,%k1 \n" // 32 bit offset + "add %5,%1 \n" + "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movzb (%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,(%3) \n" - "movzb 0x1(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x1(%3) \n" - "movzb 0x2(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x2(%3) \n" - "movzb 0x3(%2),%0 \n" - "mov %b0,0x3(%3) \n" + "movzb (%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,(%3) \n" + "movzb 0x1(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0x1(%3) \n" + "movzb 0x2(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0x2(%3) \n" + "movzb 0x3(%2),%0 \n" + "mov %b0,0x3(%3) \n" - "movd %%xmm0,%k1 \n" // 32 bit offset - "add %5,%1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" + "movd %%xmm0,%k1 \n" // 32 bit offset + "add %5,%1 \n" + "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movzb 0x4(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x4(%3) \n" - "movzb 0x5(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x5(%3) \n" - "movzb 0x6(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x6(%3) \n" - "movzb 0x7(%2),%0 \n" - "mov %b0,0x7(%3) \n" + "movzb 0x4(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0x4(%3) \n" + "movzb 0x5(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0x5(%3) \n" + "movzb 0x6(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0x6(%3) \n" + "movzb 0x7(%2),%0 \n" + "mov %b0,0x7(%3) \n" - "movd %%xmm0,%k1 \n" // 32 bit offset - "add %5,%1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" + "movd %%xmm0,%k1 \n" // 32 bit offset + "add %5,%1 \n" + "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movzb 0x8(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x8(%3) \n" - "movzb 0x9(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x9(%3) \n" - "movzb 0xa(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0xa(%3) \n" - "movzb 0xb(%2),%0 \n" - "mov %b0,0xb(%3) \n" + "movzb 0x8(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0x8(%3) \n" + "movzb 0x9(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0x9(%3) \n" + "movzb 0xa(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0xa(%3) \n" + "movzb 0xb(%2),%0 \n" + "mov %b0,0xb(%3) \n" - "movd %%xmm0,%k1 \n" // 32 bit offset - "add %5,%1 \n" + "movd %%xmm0,%k1 \n" // 32 bit offset + "add %5,%1 \n" - "movzb 0xc(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0xc(%3) \n" - "movzb 0xd(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0xd(%3) \n" - "movzb 0xe(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0xe(%3) \n" - "movzb 0xf(%2),%0 \n" - "mov %b0,0xf(%3) \n" - "lea 0x10(%2),%2 \n" - "lea 0x10(%3),%3 \n" - "sub $0x4,%4 \n" - "jg 1b \n" + "movzb 0xc(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0xc(%3) \n" + "movzb 0xd(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0xd(%3) \n" + "movzb 0xe(%2),%0 \n" + "movzb 0x00(%1,%0,1),%0 \n" + "mov %b0,0xe(%3) \n" + "movzb 0xf(%2),%0 \n" + "mov %b0,0xf(%3) \n" + "lea 0x10(%2),%2 \n" + "lea 0x10(%3),%3 \n" + "sub $0x4,%4 \n" + "jg 1b \n" : "=&d"(pixel_temp), // %0 "=&a"(table_temp), // %1 "+r"(src_argb), // %2 @@ -6837,46 +6934,47 @@ void NV21ToYUV24Row_AVX2(const uint8_t* src_y, src_y_ptr = (uint8_t*)src_y; asm volatile( - "vmovdqu %5, %%ymm0 \n" // init blend value - "vmovdqu %6, %%ymm1 \n" // init blend value - "vmovdqu %7, %%ymm2 \n" // init blend value - // "sub $0x20, %3 \n" //sub 32 from width for final loop + "vmovdqu %5, %%ymm0 \n" // init blend value + "vmovdqu %6, %%ymm1 \n" // init blend value + "vmovdqu %7, %%ymm2 \n" // init blend value + // "sub $0x20, %3 \n" //sub 32 from + // width for final loop LABELALIGN - "1: \n" // label 1 - "vmovdqu (%0,%4), %%ymm3 \n" // src_y - "vmovdqu 1(%1,%4), %%ymm4 \n" // src_uv+1 - "vmovdqu (%1), %%ymm5 \n" // src_uv - "vpshufb %8, %%ymm3, %%ymm13 \n" // y, kSHUF0 for shuf - "vpshufb %9, %%ymm4, %%ymm14 \n" // uv+1, kSHUF1 for - // shuf - "vpshufb %10, %%ymm5, %%ymm15 \n" // uv, kSHUF2 for - // shuf - "vpshufb %11, %%ymm3, %%ymm3 \n" // y kSHUF3 for shuf - "vpshufb %12, %%ymm4, %%ymm4 \n" // uv+1 kSHUF4 for - // shuf - "vpblendvb %%ymm0, %%ymm14, %%ymm13, %%ymm12 \n" // blend 0 - "vpblendvb %%ymm0, %%ymm13, %%ymm14, %%ymm14 \n" // blend 0 - "vpblendvb %%ymm2, %%ymm15, %%ymm12, %%ymm12 \n" // blend 2 - "vpblendvb %%ymm1, %%ymm15, %%ymm14, %%ymm13 \n" // blend 1 - "vpshufb %13, %%ymm5, %%ymm15 \n" // shuffle const - "vpor %%ymm4, %%ymm3, %%ymm5 \n" // get results - "vmovdqu %%ymm12, 0x20(%2) \n" // store dst_yuv+20h - "vpor %%ymm15, %%ymm5, %%ymm3 \n" // get results - "add $0x20, %4 \n" // add to src buffer - // ptr - "vinserti128 $0x1, %%xmm3, %%ymm13, %%ymm4 \n" // insert - "vperm2i128 $0x31, %%ymm13, %%ymm3, %%ymm5 \n" // insert - "vmovdqu %%ymm4, (%2) \n" // store dst_yuv - "vmovdqu %%ymm5, 0x40(%2) \n" // store dst_yuv+40h - "add $0x60,%2 \n" // add to dst buffer - // ptr - // "cmp %3, %4 \n" //(width64 - + "1: \n" // label 1 + "vmovdqu (%0,%4), %%ymm3 \n" // src_y + "vmovdqu 1(%1,%4), %%ymm4 \n" // src_uv+1 + "vmovdqu (%1), %%ymm5 \n" // src_uv + "vpshufb %8, %%ymm3, %%ymm13 \n" // y, kSHUF0 for shuf + "vpshufb %9, %%ymm4, %%ymm14 \n" // uv+1, kSHUF1 for + // shuf + "vpshufb %10, %%ymm5, %%ymm15 \n" // uv, kSHUF2 for + // shuf + "vpshufb %11, %%ymm3, %%ymm3 \n" // y kSHUF3 for shuf + "vpshufb %12, %%ymm4, %%ymm4 \n" // uv+1 kSHUF4 for + // shuf + "vpblendvb %%ymm0, %%ymm14, %%ymm13, %%ymm12 \n" // blend 0 + "vpblendvb %%ymm0, %%ymm13, %%ymm14, %%ymm14 \n" // blend 0 + "vpblendvb %%ymm2, %%ymm15, %%ymm12, %%ymm12 \n" // blend 2 + "vpblendvb %%ymm1, %%ymm15, %%ymm14, %%ymm13 \n" // blend 1 + "vpshufb %13, %%ymm5, %%ymm15 \n" // shuffle const + "vpor %%ymm4, %%ymm3, %%ymm5 \n" // get results + "vmovdqu %%ymm12, 0x20(%2) \n" // store dst_yuv+20h + "vpor %%ymm15, %%ymm5, %%ymm3 \n" // get results + "add $0x20, %4 \n" // add to src buffer + // ptr + "vinserti128 $0x1, %%xmm3, %%ymm13, %%ymm4 \n" // insert + "vperm2i128 $0x31, %%ymm13, %%ymm3, %%ymm5 \n" // insert + "vmovdqu %%ymm4, (%2) \n" // store dst_yuv + "vmovdqu %%ymm5, 0x40(%2) \n" // store dst_yuv+40h + "add $0x60,%2 \n" // add to dst buffer + // ptr + // "cmp %3, %4 \n" //(width64 - // 32 bytes) and src_offset - "sub $0x20,%3 \n" // 32 pixels per loop - "jg 1b \n" - "vzeroupper \n" // sse-avx2 - // transistions + "sub $0x20,%3 \n" // 32 pixels per loop + "jg 1b \n" + "vzeroupper \n" // sse-avx2 + // transistions : "+r"(src_y), //%0 "+r"(src_vu), //%1 @@ -6907,20 +7005,20 @@ static const uvec8 kShuffleUVToVU = {1u, 0u, 3u, 2u, 5u, 4u, 7u, 6u, void SwapUVRow_SSSE3(const uint8_t* src_uv, uint8_t* dst_vu, int width) { asm volatile( - "movdqu %3,%%xmm5 \n" + "movdqu %3,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pshufb %%xmm5,%%xmm0 \n" - "pshufb %%xmm5,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "pshufb %%xmm5,%%xmm0 \n" + "pshufb %%xmm5,%%xmm1 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu %%xmm1,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_uv), // %0 "+r"(dst_vu), // %1 "+r"(width) // %2 @@ -6937,16 +7035,16 @@ void SwapUVRow_AVX2(const uint8_t* src_uv, uint8_t* dst_vu, int width) { LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" - "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" + "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" + "vmovdqu %%ymm0,(%1) \n" + "vmovdqu %%ymm1,0x20(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_uv), // %0 "+r"(dst_vu), // %1 @@ -6956,6 +7054,119 @@ void SwapUVRow_AVX2(const uint8_t* src_uv, uint8_t* dst_vu, int width) { } #endif // HAS_SWAPUVROW_AVX2 +void HalfMergeUVRow_SSSE3(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width) { + asm volatile( + "pcmpeqb %%xmm4,%%xmm4 \n" + "psrlw $0xf,%%xmm4 \n" + "packuswb %%xmm4,%%xmm4 \n" + "pxor %%xmm5,%%xmm5 \n" + + LABELALIGN + "1: \n" + "movdqu (%0),%%xmm0 \n" // load 16 U values + "movdqu (%1),%%xmm1 \n" // load 16 V values + "movdqu 0(%0,%4,1),%%xmm2 \n" // 16 from next row + "movdqu 0(%1,%5,1),%%xmm3 \n" + "lea 0x10(%0),%0 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" // half size + "pmaddubsw %%xmm4,%%xmm1 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm4,%%xmm3 \n" + "lea 0x10(%1),%1 \n" + "paddw %%xmm2,%%xmm0 \n" + "paddw %%xmm3,%%xmm1 \n" + "psrlw $0x1,%%xmm0 \n" + "psrlw $0x1,%%xmm1 \n" + "pavgw %%xmm5,%%xmm0 \n" + "pavgw %%xmm5,%%xmm1 \n" + "packuswb %%xmm0,%%xmm0 \n" + "packuswb %%xmm1,%%xmm1 \n" + "punpcklbw %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" // store 8 UV pixels + "lea 0x10(%2),%2 \n" + "sub $0x10,%3 \n" // 16 src pixels per loop + "jg 1b \n" + : "+r"(src_u), // %0 + "+r"(src_v), // %1 + "+r"(dst_uv), // %2 + "+r"(width) // %3 + : "r"((intptr_t)(src_stride_u)), // %4 + "r"((intptr_t)(src_stride_v)) // %5 + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); +} + +void HalfMergeUVRow_AVX2(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width) { + asm volatile( + "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" + "vpsrlw $0xf,%%ymm4,%%ymm4 \n" + "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" + "vpxor %%ymm5,%%ymm5,%%ymm5 \n" + + LABELALIGN + "1: \n" + "vmovdqu (%0),%%ymm0 \n" // load 32 U values + "vmovdqu (%1),%%ymm1 \n" // load 32 V values + "vmovdqu 0(%0,%4,1),%%ymm2 \n" // 32 from next row + "vmovdqu 0(%1,%5,1),%%ymm3 \n" + "lea 0x20(%0),%0 \n" + "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" // half size + "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" + "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" + "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" + "lea 0x20(%1),%1 \n" + "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" + "vpsrlw $0x1,%%ymm0,%%ymm0 \n" + "vpsrlw $0x1,%%ymm1,%%ymm1 \n" + "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" + "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" + "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%2) \n" // store 16 UV pixels + "lea 0x20(%2),%2 \n" + "sub $0x20,%3 \n" // 32 src pixels per loop + "jg 1b \n" + "vzeroupper \n" + : "+r"(src_u), // %0 + "+r"(src_v), // %1 + "+r"(dst_uv), // %2 + "+r"(width) // %3 + : "r"((intptr_t)(src_stride_u)), // %4 + "r"((intptr_t)(src_stride_v)) // %5 + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); +} + +void ClampFloatToZero_SSE2(const float* src_x, float* dst_y, int width) { + asm volatile( + "pxor %%xmm1,%%xmm1 \n" + + LABELALIGN + "1: \n" + "movd (%0),%%xmm0 \n" // load float + "maxss %%xmm1, %%xmm0 \n" // clamp to zero + "add 4, %0 \n" + "movd %%xmm0, (%1) \n" // store float + "add 4, %1 \n" + "sub $0x4,%2 \n" // 1 float per loop + "jg 1b \n" + : "+r"(src_x), // %0 + "+r"(dst_y), // %1 + "+r"(width) // %2 + : + : "memory", "cc", "xmm0", "xmm1"); +} + #endif // defined(__x86_64__) || defined(__i386__) #ifdef __cplusplus diff --git a/TMessagesProj/jni/third_party/libyuv/source/row_mmi.cc b/TMessagesProj/jni/third_party/libyuv/source/row_mmi.cc index 50cfca726..9a8e2cb2d 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/row_mmi.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/row_mmi.cc @@ -21,6 +21,8 @@ extern "C" { // This module is for Mips MMI. #if !defined(LIBYUV_DISABLE_MMI) && defined(_MIPS_ARCH_LOONGSON3A) +// clang-format off + void RGB24ToARGBRow_MMI(const uint8_t* src_rgb24, uint8_t* dst_argb, int width) { @@ -688,12 +690,15 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, uint8_t* dst_v, int width) { uint64_t src_rgb1; - uint64_t ftmp[12]; + uint64_t ftmp[13]; + uint64_t tmp[1]; const uint64_t value = 0x4040; - const uint64_t mask_u = 0x0026004a00700002; - const uint64_t mask_v = 0x00020070005e0012; + const uint64_t mask_u = 0x0013002500380002; + const uint64_t mask_v = 0x00020038002f0009; __asm__ volatile( + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ftmp12] \n\t" "1: \n\t" "daddu %[src_rgb1], %[src_rgb0], %[src_stride_rgb] \n\t" "gsldrc1 %[src0], 0x00(%[src_rgb0]) \n\t" @@ -707,7 +712,8 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[dest0_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest0_u], %[dest0_u], %[value] \n\t" "pinsrh_3 %[dest0_v], %[src0], %[value] \n\t" @@ -725,7 +731,8 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_3 %[src_hi], %[src0], %[value] \n\t" @@ -752,7 +759,8 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[dest1_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest1_u], %[dest1_u], %[value] \n\t" "pinsrh_3 %[dest1_v], %[src0], %[value] \n\t" @@ -770,7 +778,8 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_3 %[src_hi], %[src0], %[value] \n\t" @@ -797,7 +806,8 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[dest2_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest2_u], %[dest2_u], %[value] \n\t" "pinsrh_3 %[dest2_v], %[src0], %[value] \n\t" @@ -815,7 +825,8 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_3 %[src_hi], %[src0], %[value] \n\t" @@ -842,7 +853,8 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[dest3_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest3_u], %[dest3_u], %[value] \n\t" "pinsrh_3 %[dest3_v], %[src0], %[value] \n\t" @@ -860,7 +872,8 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_3 %[src_hi], %[src0], %[value] \n\t" @@ -898,11 +911,12 @@ void ARGBToUVRow_MMI(const uint8_t* src_rgb0, [dest0_u] "=&f"(ftmp[4]), [dest0_v] "=&f"(ftmp[5]), [dest1_u] "=&f"(ftmp[6]), [dest1_v] "=&f"(ftmp[7]), [dest2_u] "=&f"(ftmp[8]), [dest2_v] "=&f"(ftmp[9]), - [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]) + [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]), + [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]) : [src_rgb0] "r"(src_rgb0), [src_stride_rgb] "r"(src_stride_rgb), [dst_u] "r"(dst_u), [dst_v] "r"(dst_v), [width] "r"(width), [mask_u] "f"(mask_u), [mask_v] "f"(mask_v), [value] "f"(value), - [zero] "f"(0x00), [eight] "f"(0x08), [two] "f"(0x02), + [zero] "f"(0x00), [eight] "f"(0x08), [one] "f"(0x01), [sixteen] "f"(0x10) : "memory"); } @@ -992,12 +1006,15 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, uint8_t* dst_v, int width) { uint64_t src_rgb1; - uint64_t ftmp[12]; + uint64_t ftmp[13]; + uint64_t tmp[1]; const uint64_t value = 0x4040; - const uint64_t mask_u = 0x00020070004a0026; - const uint64_t mask_v = 0x0012005e00700002; + const uint64_t mask_u = 0x0002003800250013; + const uint64_t mask_v = 0x0009002f00380002; __asm__ volatile( + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ftmp12] \n\t" "1: \n\t" "daddu %[src_rgb1], %[src_rgb0], %[src_stride_rgb] \n\t" "gsldrc1 %[src0], 0x00(%[src_rgb0]) \n\t" @@ -1011,7 +1028,8 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsrl %[dest0_u], %[src0], %[sixteen] \n\t" "pinsrh_3 %[dest0_u], %[dest0_u], %[value] \n\t" "pinsrh_0 %[dest0_v], %[src0], %[value] \n\t" @@ -1029,7 +1047,8 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsrl %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_3 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_0 %[src_hi], %[src0], %[value] \n\t" @@ -1056,7 +1075,8 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsrl %[dest1_u], %[src0], %[sixteen] \n\t" "pinsrh_3 %[dest1_u], %[dest1_u], %[value] \n\t" "pinsrh_0 %[dest1_v], %[src0], %[value] \n\t" @@ -1074,7 +1094,8 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsrl %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_3 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_0 %[src_hi], %[src0], %[value] \n\t" @@ -1101,7 +1122,8 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsrl %[dest2_u], %[src0], %[sixteen] \n\t" "pinsrh_3 %[dest2_u], %[dest2_u], %[value] \n\t" "pinsrh_0 %[dest2_v], %[src0], %[value] \n\t" @@ -1119,7 +1141,8 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsrl %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_3 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_0 %[src_hi], %[src0], %[value] \n\t" @@ -1146,7 +1169,8 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsrl %[dest3_u], %[src0], %[sixteen] \n\t" "pinsrh_3 %[dest3_u], %[dest3_u], %[value] \n\t" "pinsrh_0 %[dest3_v], %[src0], %[value] \n\t" @@ -1164,7 +1188,8 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsrl %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_3 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_0 %[src_hi], %[src0], %[value] \n\t" @@ -1202,11 +1227,12 @@ void BGRAToUVRow_MMI(const uint8_t* src_rgb0, [dest0_u] "=&f"(ftmp[4]), [dest0_v] "=&f"(ftmp[5]), [dest1_u] "=&f"(ftmp[6]), [dest1_v] "=&f"(ftmp[7]), [dest2_u] "=&f"(ftmp[8]), [dest2_v] "=&f"(ftmp[9]), - [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]) + [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]), + [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]) : [src_rgb0] "r"(src_rgb0), [src_stride_rgb] "r"(src_stride_rgb), [dst_u] "r"(dst_u), [dst_v] "r"(dst_v), [width] "r"(width), [mask_u] "f"(mask_u), [mask_v] "f"(mask_v), [value] "f"(value), - [zero] "f"(0x00), [eight] "f"(0x08), [two] "f"(0x02), + [zero] "f"(0x00), [eight] "f"(0x08), [one] "f"(0x01), [sixteen] "f"(0x10) : "memory"); } @@ -1296,12 +1322,15 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, uint8_t* dst_v, int width) { uint64_t src_rgb1; - uint64_t ftmp[12]; + uint64_t ftmp[13]; + uint64_t tmp[1]; const uint64_t value = 0x4040; - const uint64_t mask_u = 0x00020070004a0026; - const uint64_t mask_v = 0x0012005e00700002; + const uint64_t mask_u = 0x0002003800250013; + const uint64_t mask_v = 0x0009002F00380002; __asm__ volatile( + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ftmp12] \n\t" "1: \n\t" "daddu %[src_rgb1], %[src_rgb0], %[src_stride_rgb] \n\t" "gsldrc1 %[src0], 0x00(%[src_rgb0]) \n\t" @@ -1315,7 +1344,8 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[dest0_u], %[src0], %[value] \n\t" "dsll %[dest0_v], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest0_v], %[dest0_v], %[value] \n\t" @@ -1333,7 +1363,8 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[src_lo], %[src0], %[value] \n\t" "dsll %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_hi], %[src_hi], %[value] \n\t" @@ -1360,7 +1391,8 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[dest1_u], %[src0], %[value] \n\t" "dsll %[dest1_v], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest1_v], %[dest1_v], %[value] \n\t" @@ -1378,7 +1410,8 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[src_lo], %[src0], %[value] \n\t" "dsll %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_hi], %[src_hi], %[value] \n\t" @@ -1405,7 +1438,8 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[dest2_u], %[src0], %[value] \n\t" "dsll %[dest2_v], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest2_v], %[dest2_v], %[value] \n\t" @@ -1423,7 +1457,8 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[src_lo], %[src0], %[value] \n\t" "dsll %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_hi], %[src_hi], %[value] \n\t" @@ -1450,7 +1485,8 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[dest3_u], %[src0], %[value] \n\t" "dsll %[dest3_v], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest3_v], %[dest3_v], %[value] \n\t" @@ -1468,7 +1504,8 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[src_lo], %[src0], %[value] \n\t" "dsll %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_hi], %[src_hi], %[value] \n\t" @@ -1506,11 +1543,12 @@ void ABGRToUVRow_MMI(const uint8_t* src_rgb0, [dest0_u] "=&f"(ftmp[4]), [dest0_v] "=&f"(ftmp[5]), [dest1_u] "=&f"(ftmp[6]), [dest1_v] "=&f"(ftmp[7]), [dest2_u] "=&f"(ftmp[8]), [dest2_v] "=&f"(ftmp[9]), - [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]) + [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]), + [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]) : [src_rgb0] "r"(src_rgb0), [src_stride_rgb] "r"(src_stride_rgb), [dst_u] "r"(dst_u), [dst_v] "r"(dst_v), [width] "r"(width), [mask_u] "f"(mask_u), [mask_v] "f"(mask_v), [value] "f"(value), - [zero] "f"(0x00), [eight] "f"(0x08), [two] "f"(0x02), + [zero] "f"(0x00), [eight] "f"(0x08), [one] "f"(0x01), [sixteen] "f"(0x10) : "memory"); } @@ -1600,12 +1638,15 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, uint8_t* dst_v, int width) { uint64_t src_rgb1; - uint64_t ftmp[12]; + uint64_t ftmp[13]; + uint64_t tmp[1]; const uint64_t value = 0x4040; - const uint64_t mask_u = 0x0026004a00700002; - const uint64_t mask_v = 0x00020070005e0012; + const uint64_t mask_u = 0x0013002500380002; + const uint64_t mask_v = 0x00020038002f0009; __asm__ volatile( + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ftmp12] \n\t" "1: \n\t" "daddu %[src_rgb1], %[src_rgb0], %[src_stride_rgb] \n\t" "gsldrc1 %[src0], 0x00(%[src_rgb0]) \n\t" @@ -1619,7 +1660,8 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_0 %[dest0_u], %[src0], %[value] \n\t" "dsrl %[dest0_v], %[src0], %[sixteen] \n\t" "pinsrh_3 %[dest0_v], %[dest0_v], %[value] \n\t" @@ -1637,7 +1679,8 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_0 %[src_lo], %[src0], %[value] \n\t" "dsrl %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_3 %[src_hi], %[src_hi], %[value] \n\t" @@ -1664,7 +1707,8 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_0 %[dest1_u], %[src0], %[value] \n\t" "dsrl %[dest1_v], %[src0], %[sixteen] \n\t" "pinsrh_3 %[dest1_v], %[dest1_v], %[value] \n\t" @@ -1682,7 +1726,8 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_0 %[src_lo], %[src0], %[value] \n\t" "dsrl %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_3 %[src_hi], %[src_hi], %[value] \n\t" @@ -1709,7 +1754,8 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_0 %[dest2_u], %[src0], %[value] \n\t" "dsrl %[dest2_v], %[src0], %[sixteen] \n\t" "pinsrh_3 %[dest2_v], %[dest2_v], %[value] \n\t" @@ -1727,7 +1773,8 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_0 %[src_lo], %[src0], %[value] \n\t" "dsrl %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_3 %[src_hi], %[src_hi], %[value] \n\t" @@ -1754,7 +1801,8 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_0 %[dest3_u], %[src0], %[value] \n\t" "dsrl %[dest3_v], %[src0], %[sixteen] \n\t" "pinsrh_3 %[dest3_v], %[dest3_v], %[value] \n\t" @@ -1772,7 +1820,8 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, "paddh %[src0], %[src0], %[src_lo] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_0 %[src_lo], %[src0], %[value] \n\t" "dsrl %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_3 %[src_hi], %[src_hi], %[value] \n\t" @@ -1810,11 +1859,12 @@ void RGBAToUVRow_MMI(const uint8_t* src_rgb0, [dest0_u] "=&f"(ftmp[4]), [dest0_v] "=&f"(ftmp[5]), [dest1_u] "=&f"(ftmp[6]), [dest1_v] "=&f"(ftmp[7]), [dest2_u] "=&f"(ftmp[8]), [dest2_v] "=&f"(ftmp[9]), - [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]) + [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]), + [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]) : [src_rgb0] "r"(src_rgb0), [src_stride_rgb] "r"(src_stride_rgb), [dst_u] "r"(dst_u), [dst_v] "r"(dst_v), [width] "r"(width), [mask_u] "f"(mask_u), [mask_v] "f"(mask_v), [value] "f"(value), - [zero] "f"(0x00), [eight] "f"(0x08), [two] "f"(0x02), + [zero] "f"(0x00), [eight] "f"(0x08), [one] "f"(0x01), [sixteen] "f"(0x10) : "memory"); } @@ -1908,12 +1958,15 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, uint8_t* dst_v, int width) { uint64_t src_rgb1; - uint64_t ftmp[12]; + uint64_t ftmp[13]; + uint64_t tmp[1]; const uint64_t value = 0x4040; - const uint64_t mask_u = 0x0026004a00700002; - const uint64_t mask_v = 0x00020070005e0012; + const uint64_t mask_u = 0x0013002500380002; + const uint64_t mask_v = 0x00020038002f0009; __asm__ volatile( + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ftmp12] \n\t" "1: \n\t" "daddu %[src_rgb1], %[src_rgb0], %[src_stride_rgb] \n\t" "gsldrc1 %[src0], 0x00(%[src_rgb0]) \n\t" @@ -1929,7 +1982,8 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[dest0_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest0_u], %[dest0_u], %[value] \n\t" "pinsrh_3 %[dest0_v], %[src0], %[value] \n\t" @@ -1949,7 +2003,8 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_3 %[src_hi], %[src0], %[value] \n\t" @@ -1978,7 +2033,8 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[dest1_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest1_u], %[dest1_u], %[value] \n\t" "pinsrh_3 %[dest1_v], %[src0], %[value] \n\t" @@ -1998,7 +2054,8 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_3 %[src_hi], %[src0], %[value] \n\t" @@ -2027,7 +2084,8 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[dest2_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest2_u], %[dest2_u], %[value] \n\t" "pinsrh_3 %[dest2_v], %[src0], %[value] \n\t" @@ -2047,7 +2105,8 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_3 %[src_hi], %[src0], %[value] \n\t" @@ -2076,7 +2135,8 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[dest3_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest3_u], %[dest3_u], %[value] \n\t" "pinsrh_3 %[dest3_v], %[src0], %[value] \n\t" @@ -2096,7 +2156,8 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" "pinsrh_3 %[src_hi], %[src0], %[value] \n\t" @@ -2134,11 +2195,12 @@ void RGB24ToUVRow_MMI(const uint8_t* src_rgb0, [dest0_u] "=&f"(ftmp[4]), [dest0_v] "=&f"(ftmp[5]), [dest1_u] "=&f"(ftmp[6]), [dest1_v] "=&f"(ftmp[7]), [dest2_u] "=&f"(ftmp[8]), [dest2_v] "=&f"(ftmp[9]), - [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]) + [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]), + [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]) : [src_rgb0] "r"(src_rgb0), [src_stride_rgb] "r"(src_stride_rgb), [dst_u] "r"(dst_u), [dst_v] "r"(dst_v), [width] "r"(width), [mask_u] "f"(mask_u), [mask_v] "f"(mask_v), [value] "f"(value), - [zero] "f"(0x00), [eight] "f"(0x08), [two] "f"(0x02), + [zero] "f"(0x00), [eight] "f"(0x08), [one] "f"(0x01), [sixteen] "f"(0x10) : "memory"); } @@ -2232,12 +2294,15 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, uint8_t* dst_v, int width) { uint64_t src_rgb1; - uint64_t ftmp[12]; + uint64_t ftmp[13]; + uint64_t tmp[1]; const uint64_t value = 0x4040; - const uint64_t mask_u = 0x00020070004a0026; - const uint64_t mask_v = 0x0012005e00700002; + const uint64_t mask_u = 0x0002003800250013; + const uint64_t mask_v = 0x0009002f00380002; __asm__ volatile( + "dli %[tmp0], 0x0001000100010001 \n\t" + "dmtc1 %[tmp0], %[ftmp12] \n\t" "1: \n\t" "daddu %[src_rgb1], %[src_rgb0], %[src_stride_rgb] \n\t" "gsldrc1 %[src0], 0x00(%[src_rgb0]) \n\t" @@ -2253,7 +2318,8 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[dest0_u], %[src0], %[value] \n\t" "dsll %[dest0_v], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest0_v], %[dest0_v], %[value] \n\t" @@ -2273,7 +2339,8 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[src_lo], %[src0], %[value] \n\t" "dsll %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_hi], %[src_hi], %[value] \n\t" @@ -2302,7 +2369,8 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[dest1_u], %[src0], %[value] \n\t" "dsll %[dest1_v], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest1_v], %[dest1_v], %[value] \n\t" @@ -2322,7 +2390,8 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[src_lo], %[src0], %[value] \n\t" "dsll %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_hi], %[src_hi], %[value] \n\t" @@ -2351,7 +2420,8 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[dest2_u], %[src0], %[value] \n\t" "dsll %[dest2_v], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest2_v], %[dest2_v], %[value] \n\t" @@ -2371,7 +2441,8 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[src_lo], %[src0], %[value] \n\t" "dsll %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_hi], %[src_hi], %[value] \n\t" @@ -2400,7 +2471,8 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[dest3_u], %[src0], %[value] \n\t" "dsll %[dest3_v], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest3_v], %[dest3_v], %[value] \n\t" @@ -2420,7 +2492,8 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, "dsll %[src1], %[src1], %[eight] \n\t" "punpckhbh %[src_hi], %[src1], %[zero] \n\t" "paddh %[src0], %[src0], %[src_hi] \n\t" - "psrlh %[src0], %[src0], %[two] \n\t" + "paddh %[src0], %[src0], %[ftmp12] \n\t" + "psrlh %[src0], %[src0], %[one] \n\t" "pinsrh_3 %[src_lo], %[src0], %[value] \n\t" "dsll %[src_hi], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_hi], %[src_hi], %[value] \n\t" @@ -2458,11 +2531,12 @@ void RAWToUVRow_MMI(const uint8_t* src_rgb0, [dest0_u] "=&f"(ftmp[4]), [dest0_v] "=&f"(ftmp[5]), [dest1_u] "=&f"(ftmp[6]), [dest1_v] "=&f"(ftmp[7]), [dest2_u] "=&f"(ftmp[8]), [dest2_v] "=&f"(ftmp[9]), - [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]) + [dest3_u] "=&f"(ftmp[10]), [dest3_v] "=&f"(ftmp[11]), + [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]) : [src_rgb0] "r"(src_rgb0), [src_stride_rgb] "r"(src_stride_rgb), [dst_u] "r"(dst_u), [dst_v] "r"(dst_v), [width] "r"(width), [mask_u] "f"(mask_u), [mask_v] "f"(mask_v), [value] "f"(value), - [zero] "f"(0x00), [eight] "f"(0x08), [two] "f"(0x02), + [zero] "f"(0x00), [eight] "f"(0x08), [one] "f"(0x01), [sixteen] "f"(0x10) : "memory"); } @@ -2471,10 +2545,10 @@ void ARGBToYJRow_MMI(const uint8_t* src_argb0, uint8_t* dst_y, int width) { uint64_t src, src_hi, src_lo; uint64_t dest, dest0, dest1, dest2, dest3; uint64_t tmp0, tmp1; - const uint64_t shift = 0x07; - const uint64_t value = 0x0040; + const uint64_t shift = 0x08; + const uint64_t value = 0x80; const uint64_t mask0 = 0x0; - const uint64_t mask1 = 0x00010026004B000FULL; + const uint64_t mask1 = 0x0001004D0096001DULL; __asm__ volatile( "1: \n\t" @@ -2558,8 +2632,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, uint64_t src_rgb1; uint64_t ftmp[12]; const uint64_t value = 0x4040; - const uint64_t mask_u = 0x002b0054007f0002; - const uint64_t mask_v = 0x0002007f006b0014; + const uint64_t mask_u = 0x0015002a003f0002; + const uint64_t mask_v = 0x0002003f0035000a; __asm__ volatile( "1: \n\t" @@ -2572,8 +2646,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, "punpckhbh %[src_hi], %[src0], %[zero] \n\t" "punpcklbh %[src0], %[src1], %[zero] \n\t" "punpckhbh %[src1], %[src1], %[zero] \n\t" - "pavgh %[src0], %[src_lo], %[src0] \n\t" - "pavgh %[src1], %[src_hi], %[src1] \n\t" + "paddh %[src0], %[src_lo], %[src0] \n\t" + "paddh %[src1], %[src_hi], %[src1] \n\t" "pavgh %[src0], %[src0], %[src1] \n\t" "dsll %[dest0_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest0_u], %[dest0_u], %[value] \n\t" @@ -2589,8 +2663,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, "punpckhbh %[src_hi], %[src0], %[zero] \n\t" "punpcklbh %[src0], %[src1], %[zero] \n\t" "punpckhbh %[src1], %[src1], %[zero] \n\t" - "pavgh %[src0], %[src_lo], %[src0] \n\t" - "pavgh %[src1], %[src_hi], %[src1] \n\t" + "paddh %[src0], %[src_lo], %[src0] \n\t" + "paddh %[src1], %[src_hi], %[src1] \n\t" "pavgh %[src0], %[src0], %[src1] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" @@ -2615,8 +2689,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, "punpckhbh %[src_hi], %[src0], %[zero] \n\t" "punpcklbh %[src0], %[src1], %[zero] \n\t" "punpckhbh %[src1], %[src1], %[zero] \n\t" - "pavgh %[src0], %[src_lo], %[src0] \n\t" - "pavgh %[src1], %[src_hi], %[src1] \n\t" + "paddh %[src0], %[src_lo], %[src0] \n\t" + "paddh %[src1], %[src_hi], %[src1] \n\t" "pavgh %[src0], %[src0], %[src1] \n\t" "dsll %[dest1_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest1_u], %[dest1_u], %[value] \n\t" @@ -2632,8 +2706,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, "punpckhbh %[src_hi], %[src0], %[zero] \n\t" "punpcklbh %[src0], %[src1], %[zero] \n\t" "punpckhbh %[src1], %[src1], %[zero] \n\t" - "pavgh %[src0], %[src_lo], %[src0] \n\t" - "pavgh %[src1], %[src_hi], %[src1] \n\t" + "paddh %[src0], %[src_lo], %[src0] \n\t" + "paddh %[src1], %[src_hi], %[src1] \n\t" "pavgh %[src0], %[src0], %[src1] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" @@ -2658,8 +2732,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, "punpckhbh %[src_hi], %[src0], %[zero] \n\t" "punpcklbh %[src0], %[src1], %[zero] \n\t" "punpckhbh %[src1], %[src1], %[zero] \n\t" - "pavgh %[src0], %[src_lo], %[src0] \n\t" - "pavgh %[src1], %[src_hi], %[src1] \n\t" + "paddh %[src0], %[src_lo], %[src0] \n\t" + "paddh %[src1], %[src_hi], %[src1] \n\t" "pavgh %[src0], %[src0], %[src1] \n\t" "dsll %[dest2_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest2_u], %[dest2_u], %[value] \n\t" @@ -2675,8 +2749,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, "punpckhbh %[src_hi], %[src0], %[zero] \n\t" "punpcklbh %[src0], %[src1], %[zero] \n\t" "punpckhbh %[src1], %[src1], %[zero] \n\t" - "pavgh %[src0], %[src_lo], %[src0] \n\t" - "pavgh %[src1], %[src_hi], %[src1] \n\t" + "paddh %[src0], %[src_lo], %[src0] \n\t" + "paddh %[src1], %[src_hi], %[src1] \n\t" "pavgh %[src0], %[src0], %[src1] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" @@ -2701,8 +2775,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, "punpckhbh %[src_hi], %[src0], %[zero] \n\t" "punpcklbh %[src0], %[src1], %[zero] \n\t" "punpckhbh %[src1], %[src1], %[zero] \n\t" - "pavgh %[src0], %[src_lo], %[src0] \n\t" - "pavgh %[src1], %[src_hi], %[src1] \n\t" + "paddh %[src0], %[src_lo], %[src0] \n\t" + "paddh %[src1], %[src_hi], %[src1] \n\t" "pavgh %[src0], %[src0], %[src1] \n\t" "dsll %[dest3_u], %[src0], %[sixteen] \n\t" "pinsrh_0 %[dest3_u], %[dest3_u], %[value] \n\t" @@ -2718,8 +2792,8 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, "punpckhbh %[src_hi], %[src0], %[zero] \n\t" "punpcklbh %[src0], %[src1], %[zero] \n\t" "punpckhbh %[src1], %[src1], %[zero] \n\t" - "pavgh %[src0], %[src_lo], %[src0] \n\t" - "pavgh %[src1], %[src_hi], %[src1] \n\t" + "paddh %[src0], %[src_lo], %[src0] \n\t" + "paddh %[src1], %[src_hi], %[src1] \n\t" "pavgh %[src0], %[src0], %[src1] \n\t" "dsll %[src_lo], %[src0], %[sixteen] \n\t" "pinsrh_0 %[src_lo], %[src_lo], %[value] \n\t" @@ -2762,7 +2836,7 @@ void ARGBToUVJRow_MMI(const uint8_t* src_rgb0, : [src_rgb0] "r"(src_rgb0), [src_stride_rgb] "r"(src_stride_rgb), [dst_u] "r"(dst_u), [dst_v] "r"(dst_v), [width] "r"(width), [mask_u] "f"(mask_u), [mask_v] "f"(mask_v), [value] "f"(value), - [zero] "f"(0x00), [eight] "f"(0x08), [two] "f"(0x02), + [zero] "f"(0x00), [eight] "f"(0x08), [sixteen] "f"(0x10) : "memory"); } @@ -4052,10 +4126,10 @@ void ARGBGrayRow_MMI(const uint8_t* src_argb, uint8_t* dst_argb, int width) { uint64_t tmp0, tmp1; const uint64_t mask0 = 0x0; const uint64_t mask1 = 0x01; - const uint64_t mask2 = 0x00400026004B000FULL; + const uint64_t mask2 = 0x0080004D0096001DULL; const uint64_t mask3 = 0xFF000000FF000000ULL; const uint64_t mask4 = ~mask3; - const uint64_t shift = 0x07; + const uint64_t shift = 0x08; __asm__ volatile( "1: \n\t" @@ -4778,7 +4852,9 @@ void J400ToARGBRow_MMI(const uint8_t* src_y, uint8_t* dst_argb, int width) { : "memory"); } -void I400ToARGBRow_MMI(const uint8_t* src_y, uint8_t* rgb_buf, int width) { +// TODO - respect YuvConstants +void I400ToARGBRow_MMI(const uint8_t* src_y, uint8_t* rgb_buf, + const struct YuvConstants*, int width) { uint64_t src, src_lo, src_hi, dest, dest_lo, dest_hi; const uint64_t mask0 = 0x0; const uint64_t mask1 = 0x55; @@ -4912,10 +4988,10 @@ void MirrorRow_MMI(const uint8_t* src, uint8_t* dst, int width) { : "memory"); } -void MirrorUVRow_MMI(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorSplitUVRow_MMI(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { uint64_t src0, src1, dest0, dest1; const uint64_t mask0 = 0x00ff00ff00ff00ffULL; const uint64_t mask1 = 0x1b; @@ -6040,90 +6116,93 @@ void I444ToARGBRow_MMI(const uint8_t* src_y, uint8_t* rgb_buf, const struct YuvConstants* yuvconstants, int width) { - uint64_t y, u, v; - uint64_t b_vec[2], g_vec[2], r_vec[2]; + uint64_t y,u,v; + uint64_t b_vec[2],g_vec[2],r_vec[2]; uint64_t mask = 0xff00ff00ff00ff00ULL; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; - __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" // yg - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" // bb - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" // ub - "or %[ub], %[ub], %[mask] \n\t" // must - // sign - // extension - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" // bg - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" // ug - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" // vg - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" // br - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" // vr - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask] \n\t" // sign - // extension + uint64_t ub,ug,vg,vr,bb,bg,br,yg; + __asm__ volatile ( + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t"//yg + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t"//bb + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t"//ub + "or %[ub], %[ub], %[mask] \n\t"//must sign extension + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t"//bg + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t"//ug + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t"//vg + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t"//br + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t"//vr + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask] \n\t"//sign extension - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" // y*0x0101 - "pmulhuh %[y], %[y], %[yg] \n\t" // y1 + "punpcklbh %[y], %[y], %[y] \n\t"//y*0x0101 + "pmulhuh %[y], %[y], %[yg] \n\t"//y1 - "punpcklbh %[u], %[u], %[zero] \n\t" // u - "paddsh %[b_vec0], %[y], %[bb] \n\t" - "pmullh %[b_vec1], %[u], %[ub] \n\t" - "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" - "psrah %[b_vec0], %[b_vec0], %[six] \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t"//u + "paddsh %[b_vec0], %[y], %[bb] \n\t" + "pmullh %[b_vec1], %[u], %[ub] \n\t" + "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" + "psrah %[b_vec0], %[b_vec0], %[six] \n\t" - "punpcklbh %[v], %[v], %[zero] \n\t" // v - "paddsh %[g_vec0], %[y], %[bg] \n\t" - "pmullh %[g_vec1], %[u], %[ug] \n\t" // u*ug - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "pmullh %[g_vec1], %[v], %[vg] \n\t" // v*vg - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "psrah %[g_vec0], %[g_vec0], %[six] \n\t" + "punpcklbh %[v], %[v], %[zero] \n\t"//v + "paddsh %[g_vec0], %[y], %[bg] \n\t" + "pmullh %[g_vec1], %[u], %[ug] \n\t"//u*ug + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "pmullh %[g_vec1], %[v], %[vg] \n\t"//v*vg + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "psrah %[g_vec0], %[g_vec0], %[six] \n\t" - "paddsh %[r_vec0], %[y], %[br] \n\t" - "pmullh %[r_vec1], %[v], %[vr] \n\t" // v*vr - "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" - "psrah %[r_vec0], %[r_vec0], %[six] \n\t" + "paddsh %[r_vec0], %[y], %[br] \n\t" + "pmullh %[r_vec1], %[v], %[vr] \n\t"//v*vr + "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" + "psrah %[r_vec0], %[r_vec0], %[six] \n\t" - "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t" // rrrrbbbb - "packushb %[g_vec0], %[g_vec0], %[alpha] \n\t" // ffffgggg - "punpcklwd %[g_vec0], %[g_vec0], %[alpha] \n\t" - "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t" // gbgbgbgb - "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t" // frfrfrfr - "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t" // frgbfrgb - "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t" // frgbfrgb - "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[g_vec1], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" + "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t"//rrrrbbbb + "packushb %[g_vec0], %[g_vec0], %[alpha] \n\t"//ffffgggg + "punpcklwd %[g_vec0], %[g_vec0], %[alpha] \n\t" + "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t"//gbgbgbgb + "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t"//frfrfrfr + "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t"//frgbfrgb + "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t"//frgbfrgb + "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec1], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x04 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x04 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec0] "=&f"(b_vec[0]), - [b_vec1] "=&f"(b_vec[1]), [g_vec0] "=&f"(g_vec[0]), - [g_vec1] "=&f"(g_vec[1]), [r_vec0] "=&f"(r_vec[0]), - [r_vec1] "=&f"(r_vec[1]), [ub] "=&f"(ub), [ug] "=&f"(ug), - [vg] "=&f"(vg), [vr] "=&f"(vr), [bb] "=&f"(bb), [bg] "=&f"(bg), - [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [rgbbuf_ptr] "r"(rgb_buf), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [zero] "f"(0x00), [alpha] "f"(-1), [six] "f"(0x6), - [five] "f"(0x55), [mask] "f"(mask) - : "memory"); + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x04 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x04 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" + : [y]"=&f"(y), + [u]"=&f"(u), [v]"=&f"(v), + [b_vec0]"=&f"(b_vec[0]), [b_vec1]"=&f"(b_vec[1]), + [g_vec0]"=&f"(g_vec[0]), [g_vec1]"=&f"(g_vec[1]), + [r_vec0]"=&f"(r_vec[0]), [r_vec1]"=&f"(r_vec[1]), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [alpha]"f"(-1), + [six]"f"(0x6), [five]"f"(0x55), + [mask]"f"(mask) + : "memory" + ); } // Also used for 420 @@ -6133,96 +6212,99 @@ void I422ToARGBRow_MMI(const uint8_t* src_y, uint8_t* rgb_buf, const struct YuvConstants* yuvconstants, int width) { - uint64_t y, u, v; - uint64_t b_vec[2], g_vec[2], r_vec[2]; + uint64_t y,u,v; + uint64_t b_vec[2],g_vec[2],r_vec[2]; uint64_t mask = 0xff00ff00ff00ff00ULL; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" // yg - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" // bb - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" // ub - "or %[ub], %[ub], %[mask] \n\t" // must - // sign - // extension - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" // bg - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" // ug - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" // vg - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" // br - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" // vr - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask] \n\t" // sign - // extension + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t"//yg + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t"//bb + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t"//ub + "or %[ub], %[ub], %[mask] \n\t"//must sign extension + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t"//bg + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t"//ug + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t"//vg + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t"//br + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t"//vr + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask] \n\t"//sign extension - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" // y*0x0101 - "pmulhuh %[y], %[y], %[yg] \n\t" // y1 + "punpcklbh %[y], %[y], %[y] \n\t"//y*0x0101 + "pmulhuh %[y], %[y], %[yg] \n\t"//y1 - // u3|u2|u1|u0 --> u1|u1|u0|u0 - "punpcklbh %[u], %[u], %[u] \n\t" // u - "punpcklbh %[u], %[u], %[zero] \n\t" - "paddsh %[b_vec0], %[y], %[bb] \n\t" - "pmullh %[b_vec1], %[u], %[ub] \n\t" - "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" - "psrah %[b_vec0], %[b_vec0], %[six] \n\t" + //u3|u2|u1|u0 --> u1|u1|u0|u0 + "punpcklbh %[u], %[u], %[u] \n\t"//u + "punpcklbh %[u], %[u], %[zero] \n\t" + "paddsh %[b_vec0], %[y], %[bb] \n\t" + "pmullh %[b_vec1], %[u], %[ub] \n\t" + "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" + "psrah %[b_vec0], %[b_vec0], %[six] \n\t" - // v3|v2|v1|v0 --> v1|v1|v0|v0 - "punpcklbh %[v], %[v], %[v] \n\t" // v - "punpcklbh %[v], %[v], %[zero] \n\t" - "paddsh %[g_vec0], %[y], %[bg] \n\t" - "pmullh %[g_vec1], %[u], %[ug] \n\t" // u*ug - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "pmullh %[g_vec1], %[v], %[vg] \n\t" // v*vg - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "psrah %[g_vec0], %[g_vec0], %[six] \n\t" + //v3|v2|v1|v0 --> v1|v1|v0|v0 + "punpcklbh %[v], %[v], %[v] \n\t"//v + "punpcklbh %[v], %[v], %[zero] \n\t" + "paddsh %[g_vec0], %[y], %[bg] \n\t" + "pmullh %[g_vec1], %[u], %[ug] \n\t"//u*ug + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "pmullh %[g_vec1], %[v], %[vg] \n\t"//v*vg + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "psrah %[g_vec0], %[g_vec0], %[six] \n\t" - "paddsh %[r_vec0], %[y], %[br] \n\t" - "pmullh %[r_vec1], %[v], %[vr] \n\t" // v*vr - "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" - "psrah %[r_vec0], %[r_vec0], %[six] \n\t" + "paddsh %[r_vec0], %[y], %[br] \n\t" + "pmullh %[r_vec1], %[v], %[vr] \n\t"//v*vr + "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" + "psrah %[r_vec0], %[r_vec0], %[six] \n\t" - "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t" // rrrrbbbb - "packushb %[g_vec0], %[g_vec0], %[alpha] \n\t" // ffffgggg - "punpcklwd %[g_vec0], %[g_vec0], %[alpha] \n\t" - "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t" // gbgbgbgb - "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t" // frfrfrfr - "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t" // frgbfrgb - "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t" // frgbfrgb - "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[g_vec1], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" + "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t"//rrrrbbbb + "packushb %[g_vec0], %[g_vec0], %[alpha] \n\t"//ffffgggg + "punpcklwd %[g_vec0], %[g_vec0], %[alpha] \n\t" + "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t"//gbgbgbgb + "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t"//frfrfrfr + "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t"//frgbfrgb + "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t"//frgbfrgb + "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec1], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec0] "=&f"(b_vec[0]), - [b_vec1] "=&f"(b_vec[1]), [g_vec0] "=&f"(g_vec[0]), - [g_vec1] "=&f"(g_vec[1]), [r_vec0] "=&f"(r_vec[0]), - [r_vec1] "=&f"(r_vec[1]), [ub] "=&f"(ub), [ug] "=&f"(ug), - [vg] "=&f"(vg), [vr] "=&f"(vr), [bb] "=&f"(bb), [bg] "=&f"(bg), - [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [rgbbuf_ptr] "r"(rgb_buf), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [zero] "f"(0x00), [alpha] "f"(-1), [six] "f"(0x6), - [five] "f"(0x55), [mask] "f"(mask) - : "memory"); + : [y]"=&f"(y), + [u]"=&f"(u), [v]"=&f"(v), + [b_vec0]"=&f"(b_vec[0]), [b_vec1]"=&f"(b_vec[1]), + [g_vec0]"=&f"(g_vec[0]), [g_vec1]"=&f"(g_vec[1]), + [r_vec0]"=&f"(r_vec[0]), [r_vec1]"=&f"(r_vec[1]), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [alpha]"f"(-1), + [six]"f"(0x6), [five]"f"(0x55), + [mask]"f"(mask) + : "memory" + ); } // 10 bit YUV to ARGB @@ -6232,96 +6314,102 @@ void I210ToARGBRow_MMI(const uint16_t* src_y, uint8_t* rgb_buf, const struct YuvConstants* yuvconstants, int width) { - uint64_t y, u, v; - uint64_t b_vec[2], g_vec[2], r_vec[2]; + uint64_t y,u,v; + uint64_t b_vec[2],g_vec[2],r_vec[2]; uint64_t mask = 0xff00ff00ff00ff00ULL; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask] \n\t" - "1: \n\t" - "gsldlc1 %[y], 0x07(%[y_ptr]) \n\t" - "gsldrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "1: \n\t" + "gsldlc1 %[y], 0x07(%[y_ptr]) \n\t" + "gsldrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "psllh %[y], %[y], %[six] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "psllh %[y], %[y], %[six] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "punpcklhw %[u], %[u], %[u] \n\t" - "psrah %[u], %[u], %[two] \n\t" - "punpcklhw %[v], %[v], %[v] \n\t" - "psrah %[v], %[v], %[two] \n\t" - "pminsh %[u], %[u], %[mask1] \n\t" - "pminsh %[v], %[v], %[mask1] \n\t" + "punpcklhw %[u], %[u], %[u] \n\t" + "psrah %[u], %[u], %[two] \n\t" + "punpcklhw %[v], %[v], %[v] \n\t" + "psrah %[v], %[v], %[two] \n\t" + "pminsh %[u], %[u], %[mask1] \n\t" + "pminsh %[v], %[v], %[mask1] \n\t" - "paddsh %[b_vec0], %[y], %[bb] \n\t" - "pmullh %[b_vec1], %[u], %[ub] \n\t" - "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" + "paddsh %[b_vec0], %[y], %[bb] \n\t" + "pmullh %[b_vec1], %[u], %[ub] \n\t" + "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" - "paddsh %[g_vec0], %[y], %[bg] \n\t" - "pmullh %[g_vec1], %[u], %[ug] \n\t" - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "pmullh %[g_vec1], %[v], %[vg] \n\t" - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "paddsh %[g_vec0], %[y], %[bg] \n\t" + "pmullh %[g_vec1], %[u], %[ug] \n\t" + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "pmullh %[g_vec1], %[v], %[vg] \n\t" + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "paddsh %[r_vec0], %[y], %[br] \n\t" - "pmullh %[r_vec1], %[v], %[vr] \n\t" - "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" + "paddsh %[r_vec0], %[y], %[br] \n\t" + "pmullh %[r_vec1], %[v], %[vr] \n\t" + "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" - "psrah %[b_vec0], %[b_vec0], %[six] \n\t" - "psrah %[g_vec0], %[g_vec0], %[six] \n\t" - "psrah %[r_vec0], %[r_vec0], %[six] \n\t" + "psrah %[b_vec0], %[b_vec0], %[six] \n\t" + "psrah %[g_vec0], %[g_vec0], %[six] \n\t" + "psrah %[r_vec0], %[r_vec0], %[six] \n\t" - "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t" - "packushb %[g_vec0], %[g_vec0], %[alpha] \n\t" - "punpcklwd %[g_vec0], %[g_vec0], %[alpha] \n\t" - "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t" - "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t" - "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t" - "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t" - "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[g_vec1], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" + "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t" + "packushb %[g_vec0], %[g_vec0], %[alpha] \n\t" + "punpcklwd %[g_vec0], %[g_vec0], %[alpha] \n\t" + "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t" + "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t" + "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t" + "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t" + "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec1], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x08 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x04 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x04 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x08 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x04 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x04 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec0] "=&f"(b_vec[0]), - [b_vec1] "=&f"(b_vec[1]), [g_vec0] "=&f"(g_vec[0]), - [g_vec1] "=&f"(g_vec[1]), [r_vec0] "=&f"(r_vec[0]), - [r_vec1] "=&f"(r_vec[1]), [ub] "=&f"(ub), [ug] "=&f"(ug), - [vg] "=&f"(vg), [vr] "=&f"(vr), [bb] "=&f"(bb), [bg] "=&f"(bg), - [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [rgbbuf_ptr] "r"(rgb_buf), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [zero] "f"(0x00), [alpha] "f"(-1), [six] "f"(0x6), - [five] "f"(0x55), [mask] "f"(mask), [two] "f"(0x02), - [mask1] "f"(0x00ff00ff00ff00ff) - : "memory"); + : [y]"=&f"(y), + [u]"=&f"(u), [v]"=&f"(v), + [b_vec0]"=&f"(b_vec[0]), [b_vec1]"=&f"(b_vec[1]), + [g_vec0]"=&f"(g_vec[0]), [g_vec1]"=&f"(g_vec[1]), + [r_vec0]"=&f"(r_vec[0]), [r_vec1]"=&f"(r_vec[1]), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [alpha]"f"(-1), + [six]"f"(0x6), [five]"f"(0x55), + [mask]"f"(mask), [two]"f"(0x02), + [mask1]"f"(0x00ff00ff00ff00ff) + : "memory" + ); } void I422AlphaToARGBRow_MMI(const uint8_t* src_y, @@ -6331,96 +6419,102 @@ void I422AlphaToARGBRow_MMI(const uint8_t* src_y, uint8_t* rgb_buf, const struct YuvConstants* yuvconstants, int width) { - uint64_t y, u, v, a; - uint64_t b_vec[2], g_vec[2], r_vec[2]; + uint64_t y,u,v,a; + uint64_t b_vec[2],g_vec[2],r_vec[2]; uint64_t mask = 0xff00ff00ff00ff00ULL; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "gslwlc1 %[a], 0x03(%[a_ptr]) \n\t" - "gslwrc1 %[a], 0x00(%[a_ptr]) \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "gslwlc1 %[a], 0x03(%[a_ptr]) \n\t" + "gslwrc1 %[a], 0x00(%[a_ptr]) \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" // y*0x0101 - "pmulhuh %[y], %[y], %[yg] \n\t" // y1 + "punpcklbh %[y], %[y], %[y] \n\t"//y*0x0101 + "pmulhuh %[y], %[y], %[yg] \n\t"//y1 - // u3|u2|u1|u0 --> u1|u1|u0|u0 - "punpcklbh %[u], %[u], %[u] \n\t" // u - "punpcklbh %[u], %[u], %[zero] \n\t" - "paddsh %[b_vec0], %[y], %[bb] \n\t" - "pmullh %[b_vec1], %[u], %[ub] \n\t" - "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" - "psrah %[b_vec0], %[b_vec0], %[six] \n\t" + //u3|u2|u1|u0 --> u1|u1|u0|u0 + "punpcklbh %[u], %[u], %[u] \n\t"//u + "punpcklbh %[u], %[u], %[zero] \n\t" + "paddsh %[b_vec0], %[y], %[bb] \n\t" + "pmullh %[b_vec1], %[u], %[ub] \n\t" + "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" + "psrah %[b_vec0], %[b_vec0], %[six] \n\t" - // v3|v2|v1|v0 --> v1|v1|v0|v0 - "punpcklbh %[v], %[v], %[v] \n\t" - "punpcklbh %[v], %[v], %[zero] \n\t" - "paddsh %[g_vec0], %[y], %[bg] \n\t" - "pmullh %[g_vec1], %[u], %[ug] \n\t" - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "pmullh %[g_vec1], %[v], %[vg] \n\t" - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "psrah %[g_vec0], %[g_vec0], %[six] \n\t" + //v3|v2|v1|v0 --> v1|v1|v0|v0 + "punpcklbh %[v], %[v], %[v] \n\t" + "punpcklbh %[v], %[v], %[zero] \n\t" + "paddsh %[g_vec0], %[y], %[bg] \n\t" + "pmullh %[g_vec1], %[u], %[ug] \n\t" + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "pmullh %[g_vec1], %[v], %[vg] \n\t" + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "psrah %[g_vec0], %[g_vec0], %[six] \n\t" - "paddsh %[r_vec0], %[y], %[br] \n\t" - "pmullh %[r_vec1], %[v], %[vr] \n\t" - "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" - "psrah %[r_vec0], %[r_vec0], %[six] \n\t" + "paddsh %[r_vec0], %[y], %[br] \n\t" + "pmullh %[r_vec1], %[v], %[vr] \n\t" + "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" + "psrah %[r_vec0], %[r_vec0], %[six] \n\t" - "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t" // rrrrbbbb - "packushb %[g_vec0], %[g_vec0], %[a] \n\t" - "punpcklwd %[g_vec0], %[g_vec0], %[a] \n\t" // aaaagggg - "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t" - "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t" - "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t" - "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t" - "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[g_vec1], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" + "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t"//rrrrbbbb + "packushb %[g_vec0], %[g_vec0], %[a] \n\t" + "punpcklwd %[g_vec0], %[g_vec0], %[a] \n\t"//aaaagggg + "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t" + "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t" + "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t" + "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t" + "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec1], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[a_ptr], %[a_ptr], 0x04 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[a_ptr], %[a_ptr], 0x04 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [a] "=&f"(a), - [b_vec0] "=&f"(b_vec[0]), [b_vec1] "=&f"(b_vec[1]), - [g_vec0] "=&f"(g_vec[0]), [g_vec1] "=&f"(g_vec[1]), - [r_vec0] "=&f"(r_vec[0]), [r_vec1] "=&f"(r_vec[1]), [ub] "=&f"(ub), - [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), [bb] "=&f"(bb), - [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [rgbbuf_ptr] "r"(rgb_buf), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [a_ptr] "r"(src_a), [zero] "f"(0x00), - [six] "f"(0x6), [five] "f"(0x55), [mask] "f"(mask) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), [a]"=&f"(a), + [b_vec0]"=&f"(b_vec[0]), [b_vec1]"=&f"(b_vec[1]), + [g_vec0]"=&f"(g_vec[0]), [g_vec1]"=&f"(g_vec[1]), + [r_vec0]"=&f"(r_vec[0]), [r_vec1]"=&f"(r_vec[1]), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [a_ptr]"r"(src_a), [zero]"f"(0x00), + [six]"f"(0x6), [five]"f"(0x55), + [mask]"f"(mask) + : "memory" + ); } void I422ToRGB24Row_MMI(const uint8_t* src_y, @@ -6429,105 +6523,113 @@ void I422ToRGB24Row_MMI(const uint8_t* src_y, uint8_t* rgb_buf, const struct YuvConstants* yuvconstants, int width) { - uint64_t y, u, v; - uint64_t b_vec[2], g_vec[2], r_vec[2]; + uint64_t y,u,v; + uint64_t b_vec[2],g_vec[2],r_vec[2]; uint64_t mask = 0xff00ff00ff00ff00ULL; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" // y*0x0101 - "pmulhuh %[y], %[y], %[yg] \n\t" // y1 + "punpcklbh %[y], %[y], %[y] \n\t"//y*0x0101 + "pmulhuh %[y], %[y], %[yg] \n\t"//y1 - // u3|u2|u1|u0 --> u1|u1|u0|u0 - "punpcklbh %[u], %[u], %[u] \n\t" // u - "punpcklbh %[u], %[u], %[zero] \n\t" - "paddsh %[b_vec0], %[y], %[bb] \n\t" - "pmullh %[b_vec1], %[u], %[ub] \n\t" - "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" - "psrah %[b_vec0], %[b_vec0], %[six] \n\t" + //u3|u2|u1|u0 --> u1|u1|u0|u0 + "punpcklbh %[u], %[u], %[u] \n\t"//u + "punpcklbh %[u], %[u], %[zero] \n\t" + "paddsh %[b_vec0], %[y], %[bb] \n\t" + "pmullh %[b_vec1], %[u], %[ub] \n\t" + "psubsh %[b_vec0], %[b_vec0], %[b_vec1] \n\t" + "psrah %[b_vec0], %[b_vec0], %[six] \n\t" - // v3|v2|v1|v0 --> v1|v1|v0|v0 - "punpcklbh %[v], %[v], %[v] \n\t" - "punpcklbh %[v], %[v], %[zero] \n\t" - "paddsh %[g_vec0], %[y], %[bg] \n\t" - "pmullh %[g_vec1], %[u], %[ug] \n\t" - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "pmullh %[g_vec1], %[v], %[vg] \n\t" - "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" - "psrah %[g_vec0], %[g_vec0], %[six] \n\t" + //v3|v2|v1|v0 --> v1|v1|v0|v0 + "punpcklbh %[v], %[v], %[v] \n\t" + "punpcklbh %[v], %[v], %[zero] \n\t" + "paddsh %[g_vec0], %[y], %[bg] \n\t" + "pmullh %[g_vec1], %[u], %[ug] \n\t" + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "pmullh %[g_vec1], %[v], %[vg] \n\t" + "psubsh %[g_vec0], %[g_vec0], %[g_vec1] \n\t" + "psrah %[g_vec0], %[g_vec0], %[six] \n\t" - "paddsh %[r_vec0], %[y], %[br] \n\t" - "pmullh %[r_vec1], %[v], %[vr] \n\t" - "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" - "psrah %[r_vec0], %[r_vec0], %[six] \n\t" + "paddsh %[r_vec0], %[y], %[br] \n\t" + "pmullh %[r_vec1], %[v], %[vr] \n\t" + "psubsh %[r_vec0], %[r_vec0], %[r_vec1] \n\t" + "psrah %[r_vec0], %[r_vec0], %[six] \n\t" - "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t" - "packushb %[g_vec0], %[g_vec0], %[zero] \n\t" - "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t" - "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t" - "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t" - "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t" + "packushb %[r_vec0], %[b_vec0], %[r_vec0] \n\t" + "packushb %[g_vec0], %[g_vec0], %[zero] \n\t" + "punpcklbh %[b_vec0], %[r_vec0], %[g_vec0] \n\t" + "punpckhbh %[r_vec0], %[r_vec0], %[g_vec0] \n\t" + "punpcklhw %[g_vec0], %[b_vec0], %[r_vec0] \n\t" + "punpckhhw %[g_vec1], %[b_vec0], %[r_vec0] \n\t" - "punpckhwd %[r_vec0], %[g_vec0], %[g_vec0] \n\t" - "psllw %[r_vec1], %[r_vec0], %[lmove1] \n\t" - "or %[g_vec0], %[g_vec0], %[r_vec1] \n\t" - "psrlw %[r_vec1], %[r_vec0], %[rmove1] \n\t" - "pextrh %[r_vec1], %[r_vec1], %[zero] \n\t" - "pinsrh_2 %[g_vec0], %[g_vec0], %[r_vec1] \n\t" - "pextrh %[r_vec1], %[g_vec1], %[zero] \n\t" - "pinsrh_3 %[g_vec0], %[g_vec0], %[r_vec1] \n\t" - "pextrh %[r_vec1], %[g_vec1], %[one] \n\t" - "punpckhwd %[g_vec1], %[g_vec1], %[g_vec1] \n\t" - "psllw %[g_vec1], %[g_vec1], %[rmove1] \n\t" - "or %[g_vec1], %[g_vec1], %[r_vec1] \n\t" - "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" - "gsswlc1 %[g_vec1], 0x0b(%[rgbbuf_ptr]) \n\t" - "gsswrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" + "punpckhwd %[r_vec0], %[g_vec0], %[g_vec0] \n\t" + "psllw %[r_vec1], %[r_vec0], %[lmove1] \n\t" + "or %[g_vec0], %[g_vec0], %[r_vec1] \n\t" + "psrlw %[r_vec1], %[r_vec0], %[rmove1] \n\t" + "pextrh %[r_vec1], %[r_vec1], %[zero] \n\t" + "pinsrh_2 %[g_vec0], %[g_vec0], %[r_vec1] \n\t" + "pextrh %[r_vec1], %[g_vec1], %[zero] \n\t" + "pinsrh_3 %[g_vec0], %[g_vec0], %[r_vec1] \n\t" + "pextrh %[r_vec1], %[g_vec1], %[one] \n\t" + "punpckhwd %[g_vec1], %[g_vec1], %[g_vec1] \n\t" + "psllw %[g_vec1], %[g_vec1], %[rmove1] \n\t" + "or %[g_vec1], %[g_vec1], %[r_vec1] \n\t" + "gssdlc1 %[g_vec0], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec0], 0x00(%[rgbbuf_ptr]) \n\t" + "gsswlc1 %[g_vec1], 0x0b(%[rgbbuf_ptr]) \n\t" + "gsswrc1 %[g_vec1], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x0c \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec0] "=&f"(b_vec[0]), - [b_vec1] "=&f"(b_vec[1]), [g_vec0] "=&f"(g_vec[0]), - [g_vec1] "=&f"(g_vec[1]), [r_vec0] "=&f"(r_vec[0]), - [r_vec1] "=&f"(r_vec[1]), [ub] "=&f"(ub), [ug] "=&f"(ug), - [vg] "=&f"(vg), [vr] "=&f"(vr), [bb] "=&f"(bb), [bg] "=&f"(bg), - [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [rgbbuf_ptr] "r"(rgb_buf), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [zero] "f"(0x00), [five] "f"(0x55), [six] "f"(0x6), - [mask] "f"(mask), [lmove1] "f"(0x18), [rmove1] "f"(0x8), [one] "f"(0x1) - : "memory"); + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x0c \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" + + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec0]"=&f"(b_vec[0]), [b_vec1]"=&f"(b_vec[1]), + [g_vec0]"=&f"(g_vec[0]), [g_vec1]"=&f"(g_vec[1]), + [r_vec0]"=&f"(r_vec[0]), [r_vec1]"=&f"(r_vec[1]), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask]"f"(mask), + [lmove1]"f"(0x18), [rmove1]"f"(0x8), + [one]"f"(0x1) + : "memory" + ); } void I422ToARGB4444Row_MMI(const uint8_t* src_y, @@ -6538,103 +6640,110 @@ void I422ToARGB4444Row_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" // y*0x0101 - "pmulhuh %[y], %[y], %[yg] \n\t" // y1 + "punpcklbh %[y], %[y], %[y] \n\t"//y*0x0101 + "pmulhuh %[y], %[y], %[yg] \n\t"//y1 - // u3|u2|u1|u0 --> u1|u1|u0|u0 - "punpcklbh %[u], %[u], %[u] \n\t" // u - "punpcklbh %[u], %[u], %[zero] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + //u3|u2|u1|u0 --> u1|u1|u0|u0 + "punpcklbh %[u], %[u], %[u] \n\t"//u + "punpcklbh %[u], %[u], %[zero] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - // v3|v2|v1|v0 --> v1|v1|v0|v0 - "punpcklbh %[v], %[v], %[v] \n\t" - "punpcklbh %[v], %[v], %[zero] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + //v3|v2|v1|v0 --> v1|v1|v0|v0 + "punpcklbh %[v], %[v], %[v] \n\t" + "punpcklbh %[v], %[v], %[zero] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "and %[g_vec], %[g_vec], %[mask1] \n\t" - "psrlw %[g_vec], %[g_vec], %[four] \n\t" - "psrlw %[r_vec], %[g_vec], %[four] \n\t" - "or %[g_vec], %[g_vec], %[r_vec] \n\t" - "punpcklbh %[r_vec], %[alpha], %[zero] \n\t" - "and %[g_vec], %[g_vec], %[r_vec] \n\t" + "and %[g_vec], %[g_vec], %[mask1] \n\t" + "psrlw %[g_vec], %[g_vec], %[four] \n\t" + "psrlw %[r_vec], %[g_vec], %[four] \n\t" + "or %[g_vec], %[g_vec], %[r_vec] \n\t" + "punpcklbh %[r_vec], %[alpha], %[zero] \n\t" + "and %[g_vec], %[g_vec], %[r_vec] \n\t" - "and %[b_vec], %[b_vec], %[mask1] \n\t" - "psrlw %[b_vec], %[b_vec], %[four] \n\t" - "psrlw %[r_vec], %[b_vec], %[four] \n\t" - "or %[b_vec], %[b_vec], %[r_vec] \n\t" - "punpcklbh %[r_vec], %[alpha], %[zero] \n\t" - "and %[b_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[b_vec] \n\t" + "and %[b_vec], %[b_vec], %[mask1] \n\t" + "psrlw %[b_vec], %[b_vec], %[four] \n\t" + "psrlw %[r_vec], %[b_vec], %[four] \n\t" + "or %[b_vec], %[b_vec], %[r_vec] \n\t" + "punpcklbh %[r_vec], %[alpha], %[zero] \n\t" + "and %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[b_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[dst_argb4444]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[dst_argb4444]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[dst_argb4444]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[dst_argb4444]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" - "daddiu %[dst_argb4444], %[dst_argb4444], 0x08 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" + "daddiu %[dst_argb4444], %[dst_argb4444], 0x08 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [dst_argb4444] "r"(dst_argb4444), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [zero] "f"(0x00), [five] "f"(0x55), [six] "f"(0x6), - [mask] "f"(0xff00ff00ff00ff00), [four] "f"(0x4), - [mask1] "f"(0xf0f0f0f0f0f0f0f0), [alpha] "f"(-1) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [dst_argb4444]"r"(dst_argb4444), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask]"f"(0xff00ff00ff00ff00), + [four]"f"(0x4), [mask1]"f"(0xf0f0f0f0f0f0f0f0), + [alpha]"f"(-1) + : "memory" + ); } void I422ToARGB1555Row_MMI(const uint8_t* src_y, @@ -6645,118 +6754,125 @@ void I422ToARGB1555Row_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "punpcklbh %[y], %[y], %[y] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - // u3|u2|u1|u0 --> u1|u1|u0|u0 - "punpcklbh %[u], %[u], %[u] \n\t" - "punpcklbh %[u], %[u], %[zero] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + //u3|u2|u1|u0 --> u1|u1|u0|u0 + "punpcklbh %[u], %[u], %[u] \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - // v3|v2|v1|v0 --> v1|v1|v0|v0 - "punpcklbh %[v], %[v], %[v] \n\t" - "punpcklbh %[v], %[v], %[zero] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + //v3|v2|v1|v0 --> v1|v1|v0|v0 + "punpcklbh %[v], %[v], %[v] \n\t" + "punpcklbh %[v], %[v], %[zero] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "psrlw %[temp], %[g_vec], %[three] \n\t" - "and %[g_vec], %[temp], %[mask2] \n\t" - "psrlw %[temp], %[temp], %[eight] \n\t" - "and %[r_vec], %[temp], %[mask2] \n\t" - "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" - "or %[g_vec], %[g_vec], %[r_vec] \n\t" - "psrlw %[temp], %[temp], %[eight] \n\t" - "and %[r_vec], %[temp], %[mask2] \n\t" - "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" - "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" - "or %[g_vec], %[g_vec], %[r_vec] \n\t" - "or %[g_vec], %[g_vec], %[mask3] \n\t" + "psrlw %[temp], %[g_vec], %[three] \n\t" + "and %[g_vec], %[temp], %[mask2] \n\t" + "psrlw %[temp], %[temp], %[eight] \n\t" + "and %[r_vec], %[temp], %[mask2] \n\t" + "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" + "or %[g_vec], %[g_vec], %[r_vec] \n\t" + "psrlw %[temp], %[temp], %[eight] \n\t" + "and %[r_vec], %[temp], %[mask2] \n\t" + "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" + "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" + "or %[g_vec], %[g_vec], %[r_vec] \n\t" + "or %[g_vec], %[g_vec], %[mask3] \n\t" - "psrlw %[temp], %[b_vec], %[three] \n\t" - "and %[b_vec], %[temp], %[mask2] \n\t" - "psrlw %[temp], %[temp], %[eight] \n\t" - "and %[r_vec], %[temp], %[mask2] \n\t" - "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" - "or %[b_vec], %[b_vec], %[r_vec] \n\t" - "psrlw %[temp], %[temp], %[eight] \n\t" - "and %[r_vec], %[temp], %[mask2] \n\t" - "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" - "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" - "or %[b_vec], %[b_vec], %[r_vec] \n\t" - "or %[b_vec], %[b_vec], %[mask3] \n\t" + "psrlw %[temp], %[b_vec], %[three] \n\t" + "and %[b_vec], %[temp], %[mask2] \n\t" + "psrlw %[temp], %[temp], %[eight] \n\t" + "and %[r_vec], %[temp], %[mask2] \n\t" + "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" + "or %[b_vec], %[b_vec], %[r_vec] \n\t" + "psrlw %[temp], %[temp], %[eight] \n\t" + "and %[r_vec], %[temp], %[mask2] \n\t" + "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" + "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" + "or %[b_vec], %[b_vec], %[r_vec] \n\t" + "or %[b_vec], %[b_vec], %[mask3] \n\t" - "punpcklhw %[r_vec], %[g_vec], %[b_vec] \n\t" - "punpckhhw %[b_vec], %[g_vec], %[b_vec] \n\t" - "punpcklhw %[g_vec], %[r_vec], %[b_vec] \n\t" + "punpcklhw %[r_vec], %[g_vec], %[b_vec] \n\t" + "punpckhhw %[b_vec], %[g_vec], %[b_vec] \n\t" + "punpcklhw %[g_vec], %[r_vec], %[b_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[dst_argb1555]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[dst_argb1555]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[dst_argb1555]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[dst_argb1555]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" - "daddiu %[dst_argb1555], %[dst_argb1555], 0x08 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" + "daddiu %[dst_argb1555], %[dst_argb1555], 0x08 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [dst_argb1555] "r"(dst_argb1555), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [zero] "f"(0x00), [five] "f"(0x55), [six] "f"(0x6), - [mask1] "f"(0xff00ff00ff00ff00), [three] "f"(0x3), - [mask2] "f"(0x1f0000001f), [eight] "f"(0x8), - [mask3] "f"(0x800000008000), [lmove5] "f"(0x5) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [dst_argb1555]"r"(dst_argb1555), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [three]"f"(0x3), [mask2]"f"(0x1f0000001f), + [eight]"f"(0x8), [mask3]"f"(0x800000008000), + [lmove5]"f"(0x5) + : "memory" + ); } void I422ToRGB565Row_MMI(const uint8_t* src_y, @@ -6767,120 +6883,127 @@ void I422ToRGB565Row_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "punpcklbh %[y], %[y], %[y] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - // u3|u2|u1|u0 --> u1|u1|u0|u0 - "punpcklbh %[u], %[u], %[u] \n\t" - "punpcklbh %[u], %[u], %[zero] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + //u3|u2|u1|u0 --> u1|u1|u0|u0 + "punpcklbh %[u], %[u], %[u] \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - // v3|v2|v1|v0 --> v1|v1|v0|v0 - "punpcklbh %[v], %[v], %[v] \n\t" - "punpcklbh %[v], %[v], %[zero] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + //v3|v2|v1|v0 --> v1|v1|v0|v0 + "punpcklbh %[v], %[v], %[v] \n\t" + "punpcklbh %[v], %[v], %[zero] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "psrlh %[temp], %[g_vec], %[three] \n\t" - "and %[g_vec], %[temp], %[mask2] \n\t" - "psrlw %[temp], %[temp], %[seven] \n\t" - "psrlw %[r_vec], %[mask1], %[eight] \n\t" - "and %[r_vec], %[temp], %[r_vec] \n\t" - "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" - "or %[g_vec], %[g_vec], %[r_vec] \n\t" - "paddb %[r_vec], %[three], %[six] \n\t" - "psrlw %[temp], %[temp], %[r_vec] \n\t" - "and %[r_vec], %[temp], %[mask2] \n\t" - "paddb %[temp], %[three], %[eight] \n\t" - "psllw %[r_vec], %[r_vec], %[temp] \n\t" - "or %[g_vec], %[g_vec], %[r_vec] \n\t" + "psrlh %[temp], %[g_vec], %[three] \n\t" + "and %[g_vec], %[temp], %[mask2] \n\t" + "psrlw %[temp], %[temp], %[seven] \n\t" + "psrlw %[r_vec], %[mask1], %[eight] \n\t" + "and %[r_vec], %[temp], %[r_vec] \n\t" + "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" + "or %[g_vec], %[g_vec], %[r_vec] \n\t" + "paddb %[r_vec], %[three], %[six] \n\t" + "psrlw %[temp], %[temp], %[r_vec] \n\t" + "and %[r_vec], %[temp], %[mask2] \n\t" + "paddb %[temp], %[three], %[eight] \n\t" + "psllw %[r_vec], %[r_vec], %[temp] \n\t" + "or %[g_vec], %[g_vec], %[r_vec] \n\t" - "psrlh %[temp], %[b_vec], %[three] \n\t" - "and %[b_vec], %[temp], %[mask2] \n\t" - "psrlw %[temp], %[temp], %[seven] \n\t" - "psrlw %[r_vec], %[mask1], %[eight] \n\t" - "and %[r_vec], %[temp], %[r_vec] \n\t" - "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" - "or %[b_vec], %[b_vec], %[r_vec] \n\t" - "paddb %[r_vec], %[three], %[six] \n\t" - "psrlw %[temp], %[temp], %[r_vec] \n\t" - "and %[r_vec], %[temp], %[mask2] \n\t" - "paddb %[temp], %[three], %[eight] \n\t" - "psllw %[r_vec], %[r_vec], %[temp] \n\t" - "or %[b_vec], %[b_vec], %[r_vec] \n\t" + "psrlh %[temp], %[b_vec], %[three] \n\t" + "and %[b_vec], %[temp], %[mask2] \n\t" + "psrlw %[temp], %[temp], %[seven] \n\t" + "psrlw %[r_vec], %[mask1], %[eight] \n\t" + "and %[r_vec], %[temp], %[r_vec] \n\t" + "psllw %[r_vec], %[r_vec], %[lmove5] \n\t" + "or %[b_vec], %[b_vec], %[r_vec] \n\t" + "paddb %[r_vec], %[three], %[six] \n\t" + "psrlw %[temp], %[temp], %[r_vec] \n\t" + "and %[r_vec], %[temp], %[mask2] \n\t" + "paddb %[temp], %[three], %[eight] \n\t" + "psllw %[r_vec], %[r_vec], %[temp] \n\t" + "or %[b_vec], %[b_vec], %[r_vec] \n\t" - "punpcklhw %[r_vec], %[g_vec], %[b_vec] \n\t" - "punpckhhw %[b_vec], %[g_vec], %[b_vec] \n\t" - "punpcklhw %[g_vec], %[r_vec], %[b_vec] \n\t" + "punpcklhw %[r_vec], %[g_vec], %[b_vec] \n\t" + "punpckhhw %[b_vec], %[g_vec], %[b_vec] \n\t" + "punpcklhw %[g_vec], %[r_vec], %[b_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[dst_rgb565]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[dst_rgb565]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[dst_rgb565]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[dst_rgb565]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" - "daddiu %[dst_rgb565], %[dst_rgb565], 0x08 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" + "daddiu %[dst_rgb565], %[dst_rgb565], 0x08 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [dst_rgb565] "r"(dst_rgb565), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [zero] "f"(0x00), [five] "f"(0x55), [six] "f"(0x6), - [mask1] "f"(0xff00ff00ff00ff00), [three] "f"(0x3), - [mask2] "f"(0x1f0000001f), [eight] "f"(0x8), [seven] "f"(0x7), - [lmove5] "f"(0x5) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [dst_rgb565]"r"(dst_rgb565), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [three]"f"(0x3), [mask2]"f"(0x1f0000001f), + [eight]"f"(0x8), [seven]"f"(0x7), + [lmove5]"f"(0x5) + : "memory" + ); } void NV12ToARGBRow_MMI(const uint8_t* src_y, @@ -6890,83 +7013,91 @@ void NV12ToARGBRow_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[uv_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[uv_ptr]) \n\t" - "punpcklbh %[u], %[u], %[zero] \n\t" - "pshufh %[v], %[u], %[vshu] \n\t" - "pshufh %[u], %[u], %[ushu] \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[uv_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[uv_ptr]) \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t" + "pshufh %[v], %[u], %[vshu] \n\t" + "pshufh %[u], %[u], %[ushu] \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "punpcklbh %[y], %[y], %[y] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[uv_ptr], %[uv_ptr], 0x04 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[uv_ptr], %[uv_ptr], 0x04 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [uv_ptr] "r"(src_uv), [rgbbuf_ptr] "r"(rgb_buf), - [yuvcons_ptr] "r"(yuvconstants), [width] "r"(width), [zero] "f"(0x00), - [five] "f"(0x55), [six] "f"(0x6), [mask1] "f"(0xff00ff00ff00ff00), - [ushu] "f"(0xA0), [vshu] "f"(0xf5), [alpha] "f"(-1) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [uv_ptr]"r"(src_uv), + [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [ushu]"f"(0xA0), [vshu]"f"(0xf5), + [alpha]"f"(-1) + : "memory" + ); } void NV21ToARGBRow_MMI(const uint8_t* src_y, @@ -6976,83 +7107,91 @@ void NV21ToARGBRow_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[vu_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[vu_ptr]) \n\t" - "punpcklbh %[u], %[u], %[zero] \n\t" - "pshufh %[v], %[u], %[ushu] \n\t" - "pshufh %[u], %[u], %[vshu] \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[vu_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[vu_ptr]) \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t" + "pshufh %[v], %[u], %[ushu] \n\t" + "pshufh %[u], %[u], %[vshu] \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "punpcklbh %[y], %[y], %[y] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[vu_ptr], %[vu_ptr], 0x04 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[vu_ptr], %[vu_ptr], 0x04 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [vu_ptr] "r"(src_vu), [rgbbuf_ptr] "r"(rgb_buf), - [yuvcons_ptr] "r"(yuvconstants), [width] "r"(width), [zero] "f"(0x00), - [five] "f"(0x55), [six] "f"(0x6), [mask1] "f"(0xff00ff00ff00ff00), - [ushu] "f"(0xA0), [vshu] "f"(0xf5), [alpha] "f"(-1) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [vu_ptr]"r"(src_vu), + [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [ushu]"f"(0xA0), [vshu]"f"(0xf5), + [alpha]"f"(-1) + : "memory" + ); } void NV12ToRGB24Row_MMI(const uint8_t* src_y, @@ -7062,95 +7201,103 @@ void NV12ToRGB24Row_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[uv_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[uv_ptr]) \n\t" - "punpcklbh %[u], %[u], %[zero] \n\t" - "pshufh %[v], %[u], %[vshu] \n\t" - "pshufh %[u], %[u], %[ushu] \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[uv_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[uv_ptr]) \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t" + "pshufh %[v], %[u], %[vshu] \n\t" + "pshufh %[u], %[u], %[ushu] \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "punpcklbh %[y], %[y], %[y] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "punpckhwd %[r_vec], %[g_vec], %[g_vec] \n\t" - "psllw %[temp], %[r_vec], %[lmove1] \n\t" - "or %[g_vec], %[g_vec], %[temp] \n\t" - "psrlw %[temp], %[r_vec], %[rmove1] \n\t" - "pextrh %[temp], %[temp], %[zero] \n\t" - "pinsrh_2 %[g_vec], %[g_vec], %[temp] \n\t" - "pextrh %[temp], %[b_vec], %[zero] \n\t" - "pinsrh_3 %[g_vec], %[g_vec], %[temp] \n\t" - "pextrh %[temp], %[b_vec], %[one] \n\t" - "punpckhwd %[b_vec], %[b_vec], %[b_vec] \n\t" - "psllw %[b_vec], %[b_vec], %[rmove1] \n\t" - "or %[b_vec], %[b_vec], %[temp] \n\t" - "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" - "gsswlc1 %[b_vec], 0x0b(%[rgbbuf_ptr]) \n\t" - "gsswrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" + "punpckhwd %[r_vec], %[g_vec], %[g_vec] \n\t" + "psllw %[temp], %[r_vec], %[lmove1] \n\t" + "or %[g_vec], %[g_vec], %[temp] \n\t" + "psrlw %[temp], %[r_vec], %[rmove1] \n\t" + "pextrh %[temp], %[temp], %[zero] \n\t" + "pinsrh_2 %[g_vec], %[g_vec], %[temp] \n\t" + "pextrh %[temp], %[b_vec], %[zero] \n\t" + "pinsrh_3 %[g_vec], %[g_vec], %[temp] \n\t" + "pextrh %[temp], %[b_vec], %[one] \n\t" + "punpckhwd %[b_vec], %[b_vec], %[b_vec] \n\t" + "psllw %[b_vec], %[b_vec], %[rmove1] \n\t" + "or %[b_vec], %[b_vec], %[temp] \n\t" + "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" + "gsswlc1 %[b_vec], 0x0b(%[rgbbuf_ptr]) \n\t" + "gsswrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[uv_ptr], %[uv_ptr], 0x04 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x0C \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[uv_ptr], %[uv_ptr], 0x04 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x0C \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [uv_ptr] "r"(src_uv), [rgbbuf_ptr] "r"(rgb_buf), - [yuvcons_ptr] "r"(yuvconstants), [width] "r"(width), [zero] "f"(0x00), - [five] "f"(0x55), [six] "f"(0x6), [mask1] "f"(0xff00ff00ff00ff00), - [ushu] "f"(0xA0), [vshu] "f"(0xf5), [alpha] "f"(-1), [lmove1] "f"(0x18), - [one] "f"(0x1), [rmove1] "f"(0x8) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [uv_ptr]"r"(src_uv), + [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [ushu]"f"(0xA0), [vshu]"f"(0xf5), + [alpha]"f"(-1), [lmove1]"f"(0x18), + [one]"f"(0x1), [rmove1]"f"(0x8) + : "memory" + ); } void NV21ToRGB24Row_MMI(const uint8_t* src_y, @@ -7160,95 +7307,103 @@ void NV21ToRGB24Row_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[vu_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[vu_ptr]) \n\t" - "punpcklbh %[u], %[u], %[zero] \n\t" - "pshufh %[v], %[u], %[ushu] \n\t" - "pshufh %[u], %[u], %[vshu] \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[vu_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[vu_ptr]) \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t" + "pshufh %[v], %[u], %[ushu] \n\t" + "pshufh %[u], %[u], %[vshu] \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "punpcklbh %[y], %[y], %[y] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "punpckhwd %[r_vec], %[g_vec], %[g_vec] \n\t" - "psllw %[temp], %[r_vec], %[lmove1] \n\t" - "or %[g_vec], %[g_vec], %[temp] \n\t" - "psrlw %[temp], %[r_vec], %[rmove1] \n\t" - "pextrh %[temp], %[temp], %[zero] \n\t" - "pinsrh_2 %[g_vec], %[g_vec], %[temp] \n\t" - "pextrh %[temp], %[b_vec], %[zero] \n\t" - "pinsrh_3 %[g_vec], %[g_vec], %[temp] \n\t" - "pextrh %[temp], %[b_vec], %[one] \n\t" - "punpckhwd %[b_vec], %[b_vec], %[b_vec] \n\t" - "psllw %[b_vec], %[b_vec], %[rmove1] \n\t" - "or %[b_vec], %[b_vec], %[temp] \n\t" - "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" - "gsswlc1 %[b_vec], 0x0b(%[rgbbuf_ptr]) \n\t" - "gsswrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" + "punpckhwd %[r_vec], %[g_vec], %[g_vec] \n\t" + "psllw %[temp], %[r_vec], %[lmove1] \n\t" + "or %[g_vec], %[g_vec], %[temp] \n\t" + "psrlw %[temp], %[r_vec], %[rmove1] \n\t" + "pextrh %[temp], %[temp], %[zero] \n\t" + "pinsrh_2 %[g_vec], %[g_vec], %[temp] \n\t" + "pextrh %[temp], %[b_vec], %[zero] \n\t" + "pinsrh_3 %[g_vec], %[g_vec], %[temp] \n\t" + "pextrh %[temp], %[b_vec], %[one] \n\t" + "punpckhwd %[b_vec], %[b_vec], %[b_vec] \n\t" + "psllw %[b_vec], %[b_vec], %[rmove1] \n\t" + "or %[b_vec], %[b_vec], %[temp] \n\t" + "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" + "gsswlc1 %[b_vec], 0x0b(%[rgbbuf_ptr]) \n\t" + "gsswrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[vu_ptr], %[vu_ptr], 0x04 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x0C \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[vu_ptr], %[vu_ptr], 0x04 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x0C \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [vu_ptr] "r"(src_vu), [rgbbuf_ptr] "r"(rgb_buf), - [yuvcons_ptr] "r"(yuvconstants), [width] "r"(width), [zero] "f"(0x00), - [five] "f"(0x55), [six] "f"(0x6), [mask1] "f"(0xff00ff00ff00ff00), - [ushu] "f"(0xA0), [vshu] "f"(0xf5), [lmove1] "f"(0x18), - [rmove1] "f"(0x8), [one] "f"(0x1) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [vu_ptr]"r"(src_vu), + [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [ushu]"f"(0xA0), [vshu]"f"(0xf5), + [lmove1]"f"(0x18), [rmove1]"f"(0x8), + [one]"f"(0x1) + : "memory" + ); } void NV12ToRGB565Row_MMI(const uint8_t* src_y, @@ -7258,115 +7413,123 @@ void NV12ToRGB565Row_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[uv_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[uv_ptr]) \n\t" - "punpcklbh %[u], %[u], %[zero] \n\t" - "pshufh %[v], %[u], %[vshu] \n\t" - "pshufh %[u], %[u], %[ushu] \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[uv_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[uv_ptr]) \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t" + "pshufh %[v], %[u], %[vshu] \n\t" + "pshufh %[u], %[u], %[ushu] \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "punpcklbh %[y], %[y], %[y] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "psrlh %[temp], %[g_vec], %[three] \n\t" - "and %[g_vec], %[temp], %[mask2] \n\t" - "psrlw %[temp], %[temp], %[seven] \n\t" - "psrlw %[r_vec], %[mask1], %[eight] \n\t" - "and %[r_vec], %[temp], %[r_vec] \n\t" - "psubb %[y], %[eight], %[three] \n\t" // 5 - "psllw %[r_vec], %[r_vec], %[y] \n\t" - "or %[g_vec], %[g_vec], %[r_vec] \n\t" - "paddb %[r_vec], %[three], %[six] \n\t" - "psrlw %[temp], %[temp], %[r_vec] \n\t" - "and %[r_vec], %[temp], %[mask2] \n\t" - "paddb %[temp], %[three], %[eight] \n\t" - "psllw %[r_vec], %[r_vec], %[temp] \n\t" - "or %[g_vec], %[g_vec], %[r_vec] \n\t" + "psrlh %[temp], %[g_vec], %[three] \n\t" + "and %[g_vec], %[temp], %[mask2] \n\t" + "psrlw %[temp], %[temp], %[seven] \n\t" + "psrlw %[r_vec], %[mask1], %[eight] \n\t" + "and %[r_vec], %[temp], %[r_vec] \n\t" + "psubb %[y], %[eight], %[three] \n\t"//5 + "psllw %[r_vec], %[r_vec], %[y] \n\t" + "or %[g_vec], %[g_vec], %[r_vec] \n\t" + "paddb %[r_vec], %[three], %[six] \n\t" + "psrlw %[temp], %[temp], %[r_vec] \n\t" + "and %[r_vec], %[temp], %[mask2] \n\t" + "paddb %[temp], %[three], %[eight] \n\t" + "psllw %[r_vec], %[r_vec], %[temp] \n\t" + "or %[g_vec], %[g_vec], %[r_vec] \n\t" - "psrlh %[temp], %[b_vec], %[three] \n\t" - "and %[b_vec], %[temp], %[mask2] \n\t" - "psrlw %[temp], %[temp], %[seven] \n\t" - "psrlw %[r_vec], %[mask1], %[eight] \n\t" - "and %[r_vec], %[temp], %[r_vec] \n\t" - "psubb %[y], %[eight], %[three] \n\t" // 5 - "psllw %[r_vec], %[r_vec], %[y] \n\t" - "or %[b_vec], %[b_vec], %[r_vec] \n\t" - "paddb %[r_vec], %[three], %[six] \n\t" - "psrlw %[temp], %[temp], %[r_vec] \n\t" - "and %[r_vec], %[temp], %[mask2] \n\t" - "paddb %[temp], %[three], %[eight] \n\t" - "psllw %[r_vec], %[r_vec], %[temp] \n\t" - "or %[b_vec], %[b_vec], %[r_vec] \n\t" + "psrlh %[temp], %[b_vec], %[three] \n\t" + "and %[b_vec], %[temp], %[mask2] \n\t" + "psrlw %[temp], %[temp], %[seven] \n\t" + "psrlw %[r_vec], %[mask1], %[eight] \n\t" + "and %[r_vec], %[temp], %[r_vec] \n\t" + "psubb %[y], %[eight], %[three] \n\t"//5 + "psllw %[r_vec], %[r_vec], %[y] \n\t" + "or %[b_vec], %[b_vec], %[r_vec] \n\t" + "paddb %[r_vec], %[three], %[six] \n\t" + "psrlw %[temp], %[temp], %[r_vec] \n\t" + "and %[r_vec], %[temp], %[mask2] \n\t" + "paddb %[temp], %[three], %[eight] \n\t" + "psllw %[r_vec], %[r_vec], %[temp] \n\t" + "or %[b_vec], %[b_vec], %[r_vec] \n\t" - "punpcklhw %[r_vec], %[g_vec], %[b_vec] \n\t" - "punpckhhw %[b_vec], %[g_vec], %[b_vec] \n\t" - "punpcklhw %[g_vec], %[r_vec], %[b_vec] \n\t" + "punpcklhw %[r_vec], %[g_vec], %[b_vec] \n\t" + "punpckhhw %[b_vec], %[g_vec], %[b_vec] \n\t" + "punpcklhw %[g_vec], %[r_vec], %[b_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[dst_rgb565]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[dst_rgb565]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[dst_rgb565]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[dst_rgb565]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[uv_ptr], %[uv_ptr], 0x04 \n\t" - "daddiu %[dst_rgb565], %[dst_rgb565], 0x08 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[uv_ptr], %[uv_ptr], 0x04 \n\t" + "daddiu %[dst_rgb565], %[dst_rgb565], 0x08 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [uv_ptr] "r"(src_uv), [dst_rgb565] "r"(dst_rgb565), - [yuvcons_ptr] "r"(yuvconstants), [width] "r"(width), [zero] "f"(0x00), - [five] "f"(0x55), [six] "f"(0x6), [mask1] "f"(0xff00ff00ff00ff00), - [ushu] "f"(0xA0), [vshu] "f"(0xf5), [three] "f"(0x3), - [mask2] "f"(0x1f0000001f), [eight] "f"(0x8), [seven] "f"(0x7) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [uv_ptr]"r"(src_uv), + [dst_rgb565]"r"(dst_rgb565), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [ushu]"f"(0xA0), [vshu]"f"(0xf5), + [three]"f"(0x3), [mask2]"f"(0x1f0000001f), + [eight]"f"(0x8), [seven]"f"(0x7) + : "memory" + ); } void YUY2ToARGBRow_MMI(const uint8_t* src_yuy2, @@ -7375,83 +7538,90 @@ void YUY2ToARGBRow_MMI(const uint8_t* src_yuy2, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gsldlc1 %[y], 0x07(%[yuy2_ptr]) \n\t" - "gsldrc1 %[y], 0x00(%[yuy2_ptr]) \n\t" - "psrlh %[temp], %[y], %[eight] \n\t" - "pshufh %[u], %[temp], %[ushu] \n\t" - "pshufh %[v], %[temp], %[vshu] \n\t" + "1: \n\t" + "gsldlc1 %[y], 0x07(%[yuy2_ptr]) \n\t" + "gsldrc1 %[y], 0x00(%[yuy2_ptr]) \n\t" + "psrlh %[temp], %[y], %[eight] \n\t" + "pshufh %[u], %[temp], %[ushu] \n\t" + "pshufh %[v], %[temp], %[vshu] \n\t" - "psrlh %[temp], %[mask1], %[eight] \n\t" - "and %[y], %[y], %[temp] \n\t" - "psllh %[temp], %[y], %[eight] \n\t" - "or %[y], %[y], %[temp] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "psrlh %[temp], %[mask1], %[eight] \n\t" + "and %[y], %[y], %[temp] \n\t" + "psllh %[temp], %[y], %[eight] \n\t" + "or %[y], %[y], %[temp] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[yuy2_ptr], %[yuy2_ptr], 0x08 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[yuy2_ptr], %[yuy2_ptr], 0x08 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [yuy2_ptr] "r"(src_yuy2), [rgbbuf_ptr] "r"(rgb_buf), - [yuvcons_ptr] "r"(yuvconstants), [width] "r"(width), [zero] "f"(0x00), - [five] "f"(0x55), [six] "f"(0x6), [mask1] "f"(0xff00ff00ff00ff00), - [ushu] "f"(0xA0), [vshu] "f"(0xf5), [alpha] "f"(-1), [eight] "f"(0x8) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [yuy2_ptr]"r"(src_yuy2), [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [ushu]"f"(0xA0), [vshu]"f"(0xf5), + [alpha]"f"(-1), [eight]"f"(0x8) + : "memory" + ); } void UYVYToARGBRow_MMI(const uint8_t* src_uyvy, @@ -7460,83 +7630,90 @@ void UYVYToARGBRow_MMI(const uint8_t* src_uyvy, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gsldlc1 %[y], 0x07(%[uyvy_ptr]) \n\t" - "gsldrc1 %[y], 0x00(%[uyvy_ptr]) \n\t" - "psrlh %[temp], %[mask1], %[eight] \n\t" - "and %[temp], %[y], %[temp] \n\t" - "pshufh %[u], %[temp], %[ushu] \n\t" - "pshufh %[v], %[temp], %[vshu] \n\t" + "1: \n\t" + "gsldlc1 %[y], 0x07(%[uyvy_ptr]) \n\t" + "gsldrc1 %[y], 0x00(%[uyvy_ptr]) \n\t" + "psrlh %[temp], %[mask1], %[eight] \n\t" + "and %[temp], %[y], %[temp] \n\t" + "pshufh %[u], %[temp], %[ushu] \n\t" + "pshufh %[v], %[temp], %[vshu] \n\t" - "psrlh %[y], %[y], %[eight] \n\t" - "psllh %[temp], %[y], %[eight] \n\t" - "or %[y], %[y], %[temp] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "psrlh %[y], %[y], %[eight] \n\t" + "psllh %[temp], %[y], %[eight] \n\t" + "or %[y], %[y], %[temp] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" - "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" - "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklwd %[g_vec], %[g_vec], %[alpha] \n\t" + "punpcklbh %[b_vec], %[r_vec], %[g_vec] \n\t" + "punpckhbh %[r_vec], %[r_vec], %[g_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[uyvy_ptr], %[uyvy_ptr], 0x08 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[uyvy_ptr], %[uyvy_ptr], 0x08 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [uyvy_ptr] "r"(src_uyvy), [rgbbuf_ptr] "r"(rgb_buf), - [yuvcons_ptr] "r"(yuvconstants), [width] "r"(width), [zero] "f"(0x00), - [five] "f"(0x55), [six] "f"(0x6), [mask1] "f"(0xff00ff00ff00ff00), - [ushu] "f"(0xA0), [vshu] "f"(0xf5), [alpha] "f"(-1), [eight] "f"(0x8) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [uyvy_ptr]"r"(src_uyvy), [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [ushu]"f"(0xA0), [vshu]"f"(0xf5), + [alpha]"f"(-1), [eight]"f"(0x8) + : "memory" + ); } void I422ToRGBARow_MMI(const uint8_t* src_y, @@ -7547,105 +7724,114 @@ void I422ToRGBARow_MMI(const uint8_t* src_y, int width) { uint64_t y, u, v; uint64_t b_vec, g_vec, r_vec, temp; - uint64_t ub, ug, vg, vr, bb, bg, br, yg; + uint64_t ub,ug,vg,vr,bb,bg,br,yg; __asm__ volatile( - "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" - "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" - "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" - "or %[ub], %[ub], %[mask1] \n\t" - "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" - "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[ug], %[ug], %[zero] \n\t" - "pshufh %[ug], %[ug], %[zero] \n\t" - "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vg], %[vg], %[zero] \n\t" - "pshufh %[vg], %[vg], %[five] \n\t" - "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" - "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" - "punpcklbh %[vr], %[vr], %[zero] \n\t" - "pshufh %[vr], %[vr], %[five] \n\t" - "or %[vr], %[vr], %[mask1] \n\t" + "ldc1 %[yg], 0xc0(%[yuvcons_ptr]) \n\t" + "ldc1 %[bb], 0x60(%[yuvcons_ptr]) \n\t" + "ldc1 %[ub], 0x00(%[yuvcons_ptr]) \n\t" + "or %[ub], %[ub], %[mask1] \n\t" + "ldc1 %[bg], 0x80(%[yuvcons_ptr]) \n\t" + "ldc1 %[ug], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[ug], %[ug], %[zero] \n\t" + "pshufh %[ug], %[ug], %[zero] \n\t" + "ldc1 %[vg], 0x20(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vg], %[vg], %[zero] \n\t" + "pshufh %[vg], %[vg], %[five] \n\t" + "ldc1 %[br], 0xa0(%[yuvcons_ptr]) \n\t" + "ldc1 %[vr], 0x40(%[yuvcons_ptr]) \n\t" + "punpcklbh %[vr], %[vr], %[zero] \n\t" + "pshufh %[vr], %[vr], %[five] \n\t" + "or %[vr], %[vr], %[mask1] \n\t" - "1: \n\t" - "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" - "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" - "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" - "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" - "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" - "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" + "1: \n\t" + "gslwlc1 %[y], 0x03(%[y_ptr]) \n\t" + "gslwrc1 %[y], 0x00(%[y_ptr]) \n\t" + "gslwlc1 %[u], 0x03(%[u_ptr]) \n\t" + "gslwrc1 %[u], 0x00(%[u_ptr]) \n\t" + "gslwlc1 %[v], 0x03(%[v_ptr]) \n\t" + "gslwrc1 %[v], 0x00(%[v_ptr]) \n\t" - "punpcklbh %[y], %[y], %[y] \n\t" - "pmulhuh %[y], %[y], %[yg] \n\t" + "punpcklbh %[y], %[y], %[y] \n\t" + "pmulhuh %[y], %[y], %[yg] \n\t" - "punpcklbh %[u], %[u], %[u] \n\t" - "punpcklbh %[u], %[u], %[zero] \n\t" - "paddsh %[b_vec], %[y], %[bb] \n\t" - "pmullh %[temp], %[u], %[ub] \n\t" - "psubsh %[b_vec], %[b_vec], %[temp] \n\t" - "psrah %[b_vec], %[b_vec], %[six] \n\t" + "punpcklbh %[u], %[u], %[u] \n\t" + "punpcklbh %[u], %[u], %[zero] \n\t" + "paddsh %[b_vec], %[y], %[bb] \n\t" + "pmullh %[temp], %[u], %[ub] \n\t" + "psubsh %[b_vec], %[b_vec], %[temp] \n\t" + "psrah %[b_vec], %[b_vec], %[six] \n\t" - "punpcklbh %[v], %[v], %[v] \n\t" - "punpcklbh %[v], %[v], %[zero] \n\t" - "paddsh %[g_vec], %[y], %[bg] \n\t" - "pmullh %[temp], %[u], %[ug] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "pmullh %[temp], %[v], %[vg] \n\t" - "psubsh %[g_vec], %[g_vec], %[temp] \n\t" - "psrah %[g_vec], %[g_vec], %[six] \n\t" + "punpcklbh %[v], %[v], %[v] \n\t" + "punpcklbh %[v], %[v], %[zero] \n\t" + "paddsh %[g_vec], %[y], %[bg] \n\t" + "pmullh %[temp], %[u], %[ug] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "pmullh %[temp], %[v], %[vg] \n\t" + "psubsh %[g_vec], %[g_vec], %[temp] \n\t" + "psrah %[g_vec], %[g_vec], %[six] \n\t" - "paddsh %[r_vec], %[y], %[br] \n\t" - "pmullh %[temp], %[v], %[vr] \n\t" - "psubsh %[r_vec], %[r_vec], %[temp] \n\t" - "psrah %[r_vec], %[r_vec], %[six] \n\t" + "paddsh %[r_vec], %[y], %[br] \n\t" + "pmullh %[temp], %[v], %[vr] \n\t" + "psubsh %[r_vec], %[r_vec], %[temp] \n\t" + "psrah %[r_vec], %[r_vec], %[six] \n\t" - "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" - "packushb %[g_vec], %[g_vec], %[zero] \n\t" - "punpcklwd %[g_vec], %[alpha], %[g_vec] \n\t" - "punpcklbh %[b_vec], %[g_vec], %[r_vec] \n\t" - "punpckhbh %[r_vec], %[g_vec], %[r_vec] \n\t" - "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" - "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[r_vec], %[b_vec], %[r_vec] \n\t" + "packushb %[g_vec], %[g_vec], %[zero] \n\t" + "punpcklwd %[g_vec], %[alpha], %[g_vec] \n\t" + "punpcklbh %[b_vec], %[g_vec], %[r_vec] \n\t" + "punpckhbh %[r_vec], %[g_vec], %[r_vec] \n\t" + "punpcklhw %[g_vec], %[b_vec], %[r_vec] \n\t" + "punpckhhw %[b_vec], %[b_vec], %[r_vec] \n\t" - "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" - "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" - "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[g_vec], 0x07(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[g_vec], 0x00(%[rgbbuf_ptr]) \n\t" + "gssdlc1 %[b_vec], 0x0f(%[rgbbuf_ptr]) \n\t" + "gssdrc1 %[b_vec], 0x08(%[rgbbuf_ptr]) \n\t" - "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" - "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" - "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" - "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "bnez %[width], 1b \n\t" + "daddiu %[y_ptr], %[y_ptr], 0x04 \n\t" + "daddiu %[u_ptr], %[u_ptr], 0x02 \n\t" + "daddiu %[v_ptr], %[v_ptr], 0x02 \n\t" + "daddiu %[rgbbuf_ptr], %[rgbbuf_ptr], 0x10 \n\t" + "daddi %[width], %[width], -0x04 \n\t" + "bnez %[width], 1b \n\t" - : [y] "=&f"(y), [u] "=&f"(u), [v] "=&f"(v), [b_vec] "=&f"(b_vec), - [g_vec] "=&f"(g_vec), [r_vec] "=&f"(r_vec), [temp] "=&f"(temp), - [ub] "=&f"(ub), [ug] "=&f"(ug), [vg] "=&f"(vg), [vr] "=&f"(vr), - [bb] "=&f"(bb), [bg] "=&f"(bg), [br] "=&f"(br), [yg] "=&f"(yg) - : [y_ptr] "r"(src_y), [u_ptr] "r"(src_u), [v_ptr] "r"(src_v), - [rgbbuf_ptr] "r"(rgb_buf), [yuvcons_ptr] "r"(yuvconstants), - [width] "r"(width), [zero] "f"(0x00), [five] "f"(0x55), [six] "f"(0x6), - [mask1] "f"(0xff00ff00ff00ff00), [alpha] "f"(-1) - : "memory"); + : [y]"=&f"(y), [u]"=&f"(u), + [v]"=&f"(v), + [b_vec]"=&f"(b_vec), [g_vec]"=&f"(g_vec), + [r_vec]"=&f"(r_vec), [temp]"=&f"(temp), + [ub]"=&f"(ub), [ug]"=&f"(ug), + [vg]"=&f"(vg), [vr]"=&f"(vr), + [bb]"=&f"(bb), [bg]"=&f"(bg), + [br]"=&f"(br), [yg]"=&f"(yg) + : [y_ptr]"r"(src_y), [u_ptr]"r"(src_u), + [v_ptr]"r"(src_v), [rgbbuf_ptr]"r"(rgb_buf), + [yuvcons_ptr]"r"(yuvconstants), [width]"r"(width), + [zero]"f"(0x00), [five]"f"(0x55), + [six]"f"(0x6), [mask1]"f"(0xff00ff00ff00ff00), + [alpha]"f"(-1) + : "memory" + ); } void ARGBSetRow_MMI(uint8_t* dst_argb, uint32_t v32, int width) { - __asm__ volatile( - "punpcklwd %[v32], %[v32], %[v32] \n\t" - "1: \n\t" - "gssdlc1 %[v32], 0x07(%[dst_ptr]) \n\t" - "gssdrc1 %[v32], 0x00(%[dst_ptr]) \n\t" - "gssdlc1 %[v32], 0x0f(%[dst_ptr]) \n\t" - "gssdrc1 %[v32], 0x08(%[dst_ptr]) \n\t" + __asm__ volatile ( + "punpcklwd %[v32], %[v32], %[v32] \n\t" + "1: \n\t" + "gssdlc1 %[v32], 0x07(%[dst_ptr]) \n\t" + "gssdrc1 %[v32], 0x00(%[dst_ptr]) \n\t" + "gssdlc1 %[v32], 0x0f(%[dst_ptr]) \n\t" + "gssdrc1 %[v32], 0x08(%[dst_ptr]) \n\t" - "daddi %[width], %[width], -0x04 \n\t" - "daddiu %[dst_ptr], %[dst_ptr], 0x10 \n\t" - "bnez %[width], 1b \n\t" - : [v32] "+&f"(v32) - : [dst_ptr] "r"(dst_argb), [width] "r"(width) - : "memory"); + "daddi %[width], %[width], -0x04 \n\t" + "daddiu %[dst_ptr], %[dst_ptr], 0x10 \n\t" + "bnez %[width], 1b \n\t" + : [v32]"+&f"(v32) + : [dst_ptr]"r"(dst_argb), [width]"r"(width) + : "memory" + ); } +// clang-format on // 10 bit YUV to ARGB #endif // !defined(LIBYUV_DISABLE_MMI) && defined(_MIPS_ARCH_LOONGSON3A) diff --git a/TMessagesProj/jni/third_party/libyuv/source/row_msa.cc b/TMessagesProj/jni/third_party/libyuv/source/row_msa.cc index 5c0239a37..fe6df93a6 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/row_msa.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/row_msa.cc @@ -155,11 +155,10 @@ extern "C" { } // Loads current and next row of ARGB input and averages it to calculate U and V -#define READ_ARGB(s_ptr, t_ptr, argb0, argb1, argb2, argb3) \ +#define READ_ARGB(s_ptr, t_ptr, argb0, argb1, argb2, argb3, const_0x0101) \ { \ v16u8 src0_m, src1_m, src2_m, src3_m, src4_m, src5_m, src6_m, src7_m; \ v16u8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - v16u8 vec8_m, vec9_m; \ v8u16 reg0_m, reg1_m, reg2_m, reg3_m, reg4_m, reg5_m, reg6_m, reg7_m; \ v8u16 reg8_m, reg9_m; \ \ @@ -195,81 +194,81 @@ extern "C" { reg1_m = (v8u16)__msa_pckev_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg0_m += (v8u16)__msa_pckod_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m += (v8u16)__msa_pckod_d((v2i64)reg7_m, (v2i64)reg3_m); \ - reg8_m = (v8u16)__msa_srai_h((v8i16)reg8_m, 2); \ - reg9_m = (v8u16)__msa_srai_h((v8i16)reg9_m, 2); \ - reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, 2); \ - reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \ - argb0 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \ - argb1 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ - src0_m = (v16u8)__msa_ld_b((void*)s, 64); \ - src1_m = (v16u8)__msa_ld_b((void*)s, 80); \ - src2_m = (v16u8)__msa_ld_b((void*)s, 96); \ - src3_m = (v16u8)__msa_ld_b((void*)s, 112); \ - src4_m = (v16u8)__msa_ld_b((void*)t, 64); \ - src5_m = (v16u8)__msa_ld_b((void*)t, 80); \ - src6_m = (v16u8)__msa_ld_b((void*)t, 96); \ - src7_m = (v16u8)__msa_ld_b((void*)t, 112); \ - vec2_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \ - vec3_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \ - vec4_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \ - vec5_m = (v16u8)__msa_ilvr_b((v16i8)src3_m, (v16i8)src7_m); \ - vec6_m = (v16u8)__msa_ilvl_b((v16i8)src0_m, (v16i8)src4_m); \ - vec7_m = (v16u8)__msa_ilvl_b((v16i8)src1_m, (v16i8)src5_m); \ - vec8_m = (v16u8)__msa_ilvl_b((v16i8)src2_m, (v16i8)src6_m); \ - vec9_m = (v16u8)__msa_ilvl_b((v16i8)src3_m, (v16i8)src7_m); \ - reg0_m = __msa_hadd_u_h(vec2_m, vec2_m); \ - reg1_m = __msa_hadd_u_h(vec3_m, vec3_m); \ - reg2_m = __msa_hadd_u_h(vec4_m, vec4_m); \ - reg3_m = __msa_hadd_u_h(vec5_m, vec5_m); \ - reg4_m = __msa_hadd_u_h(vec6_m, vec6_m); \ - reg5_m = __msa_hadd_u_h(vec7_m, vec7_m); \ - reg6_m = __msa_hadd_u_h(vec8_m, vec8_m); \ - reg7_m = __msa_hadd_u_h(vec9_m, vec9_m); \ - reg8_m = (v8u16)__msa_pckev_d((v2i64)reg4_m, (v2i64)reg0_m); \ - reg9_m = (v8u16)__msa_pckev_d((v2i64)reg5_m, (v2i64)reg1_m); \ - reg8_m += (v8u16)__msa_pckod_d((v2i64)reg4_m, (v2i64)reg0_m); \ - reg9_m += (v8u16)__msa_pckod_d((v2i64)reg5_m, (v2i64)reg1_m); \ - reg0_m = (v8u16)__msa_pckev_d((v2i64)reg6_m, (v2i64)reg2_m); \ - reg1_m = (v8u16)__msa_pckev_d((v2i64)reg7_m, (v2i64)reg3_m); \ - reg0_m += (v8u16)__msa_pckod_d((v2i64)reg6_m, (v2i64)reg2_m); \ - reg1_m += (v8u16)__msa_pckod_d((v2i64)reg7_m, (v2i64)reg3_m); \ - reg8_m = (v8u16)__msa_srai_h((v8i16)reg8_m, 2); \ - reg9_m = (v8u16)__msa_srai_h((v8i16)reg9_m, 2); \ - reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, 2); \ - reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \ - argb2 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \ - argb3 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ + reg8_m += const_0x0101; \ + reg9_m += const_0x0101; \ + reg0_m += const_0x0101; \ + reg1_m += const_0x0101; \ + argb0 = (v8u16)__msa_srai_h((v8i16)reg8_m, 1); \ + argb1 = (v8u16)__msa_srai_h((v8i16)reg9_m, 1); \ + argb2 = (v8u16)__msa_srai_h((v8i16)reg0_m, 1); \ + argb3 = (v8u16)__msa_srai_h((v8i16)reg1_m, 1); \ + } + +#define ARGBTOUV(argb0, argb1, argb2, argb3, const0, const1, const2, const3, \ + shf0, shf1, shf2, shf3, shift, u_out, v_out) \ + { \ + v8u16 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ + v4u32 reg0_m, reg1_m, reg2_m, reg3_m; \ + \ + vec0_m = (v8u16)__msa_vshf_h(shf0, (v16i8)argb1, (v16i8)argb0); \ + vec1_m = (v8u16)__msa_vshf_h(shf0, (v16i8)argb3, (v16i8)argb2); \ + vec2_m = (v8u16)__msa_vshf_h(shf1, (v16i8)argb1, (v16i8)argb0); \ + vec3_m = (v8u16)__msa_vshf_h(shf1, (v16i8)argb3, (v16i8)argb2); \ + vec4_m = (v8u16)__msa_vshf_h(shf2, (v16i8)argb1, (v16i8)argb0); \ + vec5_m = (v8u16)__msa_vshf_h(shf2, (v16i8)argb3, (v16i8)argb2); \ + vec6_m = (v8u16)__msa_vshf_h(shf3, (v16i8)argb1, (v16i8)argb0); \ + vec7_m = (v8u16)__msa_vshf_h(shf3, (v16i8)argb3, (v16i8)argb2); \ + reg0_m = __msa_dotp_u_w(vec0_m, const0); \ + reg1_m = __msa_dotp_u_w(vec1_m, const0); \ + reg2_m = __msa_dotp_u_w(vec4_m, const0); \ + reg3_m = __msa_dotp_u_w(vec5_m, const0); \ + reg0_m += const1; \ + reg1_m += const1; \ + reg2_m += const1; \ + reg3_m += const1; \ + reg0_m -= (v4u32)__msa_dotp_u_w(vec2_m, const2); \ + reg1_m -= (v4u32)__msa_dotp_u_w(vec3_m, const2); \ + reg2_m -= (v4u32)__msa_dotp_u_w(vec6_m, const3); \ + reg3_m -= (v4u32)__msa_dotp_u_w(vec7_m, const3); \ + reg0_m = __msa_srl_w(reg0_m, shift); \ + reg1_m = __msa_srl_w(reg1_m, shift); \ + reg2_m = __msa_srl_w(reg2_m, shift); \ + reg3_m = __msa_srl_w(reg3_m, shift); \ + u_out = (v8u16)__msa_pckev_h((v8i16)reg1_m, (v8i16)reg0_m); \ + v_out = (v8u16)__msa_pckev_h((v8i16)reg3_m, (v8i16)reg2_m); \ } // Takes ARGB input and calculates U and V. -#define ARGBTOUV(argb0, argb1, argb2, argb3, const0, const1, const2, const3, \ - shf0, shf1, shf2, shf3, v_out, u_out) \ - { \ - v16u8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - v8u16 reg0_m, reg1_m, reg2_m, reg3_m; \ - \ - vec0_m = (v16u8)__msa_vshf_b(shf0, (v16i8)argb1, (v16i8)argb0); \ - vec1_m = (v16u8)__msa_vshf_b(shf0, (v16i8)argb3, (v16i8)argb2); \ - vec2_m = (v16u8)__msa_vshf_b(shf1, (v16i8)argb1, (v16i8)argb0); \ - vec3_m = (v16u8)__msa_vshf_b(shf1, (v16i8)argb3, (v16i8)argb2); \ - vec4_m = (v16u8)__msa_vshf_b(shf2, (v16i8)argb1, (v16i8)argb0); \ - vec5_m = (v16u8)__msa_vshf_b(shf2, (v16i8)argb3, (v16i8)argb2); \ - vec6_m = (v16u8)__msa_vshf_b(shf3, (v16i8)argb1, (v16i8)argb0); \ - vec7_m = (v16u8)__msa_vshf_b(shf3, (v16i8)argb3, (v16i8)argb2); \ - reg0_m = __msa_dotp_u_h(vec0_m, const1); \ - reg1_m = __msa_dotp_u_h(vec1_m, const1); \ - reg2_m = __msa_dotp_u_h(vec4_m, const1); \ - reg3_m = __msa_dotp_u_h(vec5_m, const1); \ - reg0_m += const3; \ - reg1_m += const3; \ - reg2_m += const3; \ - reg3_m += const3; \ - reg0_m -= __msa_dotp_u_h(vec2_m, const0); \ - reg1_m -= __msa_dotp_u_h(vec3_m, const0); \ - reg2_m -= __msa_dotp_u_h(vec6_m, const2); \ - reg3_m -= __msa_dotp_u_h(vec7_m, const2); \ - v_out = (v16u8)__msa_pckod_b((v16i8)reg1_m, (v16i8)reg0_m); \ - u_out = (v16u8)__msa_pckod_b((v16i8)reg3_m, (v16i8)reg2_m); \ +#define ARGBTOUV_H(argb0, argb1, argb2, argb3, const0, const1, const2, const3, \ + shf0, shf1, shf2, shf3, v_out, u_out) \ + { \ + v8u16 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ + v4u32 reg0_m, reg1_m, reg2_m, reg3_m; \ + \ + vec0_m = __msa_vshf_h(shf0, (v16i8)argb1, (v16i8)argb0); \ + vec1_m = __msa_vshf_h(shf0, (v16i8)argb3, (v16i8)argb2); \ + vec2_m = __msa_vshf_h(shf1, (v16i8)argb1, (v16i8)argb0); \ + vec3_m = __msa_vshf_h(shf1, (v16i8)argb3, (v16i8)argb2); \ + vec4_m = __msa_vshf_h(shf2, (v16i8)argb1, (v16i8)argb0); \ + vec5_m = __msa_vshf_h(shf2, (v16i8)argb3, (v16i8)argb2); \ + vec6_m = __msa_vshf_h(shf3, (v16i8)argb1, (v16i8)argb0); \ + vec7_m = __msa_vshf_h(shf3, (v16i8)argb3, (v16i8)argb2); \ + reg0_m = __msa_dotp_u_w(vec0_m, const1); \ + reg1_m = __msa_dotp_u_w(vec1_m, const1); \ + reg2_m = __msa_dotp_u_w(vec4_m, const1); \ + reg3_m = __msa_dotp_u_w(vec5_m, const1); \ + reg0_m += (v4u32)const3; \ + reg1_m += (v4u32)const3; \ + reg2_m += (v4u32)const3; \ + reg3_m += (v4u32)const3; \ + reg0_m -= __msa_dotp_u_w(vec2_m, const0); \ + reg1_m -= __msa_dotp_u_w(vec3_m, const0); \ + reg2_m -= __msa_dotp_u_w(vec6_m, const2); \ + reg3_m -= __msa_dotp_u_w(vec7_m, const2); \ + u_out = (v16u8)__msa_pckev_h((v8i16)reg3_m, (v8i16)reg2_m); \ + v_out = (v16u8)__msa_pckev_h((v8i16)reg1_m, (v8i16)reg0_m); \ + u_out = (v16u8)__msa_pckod_b((v16i8)u_out, (v16i8)u_out); \ + v_out = (v16u8)__msa_pckod_b((v16i8)v_out, (v16i8)v_out); \ } // Load I444 pixel data @@ -302,6 +301,20 @@ void MirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { } } +void MirrorUVRow_MSA(const uint8_t* src_uv, uint8_t* dst_uv, int width) { + int x; + v8u16 src, dst; + v8u16 shuffler = {7, 6, 5, 4, 3, 2, 1, 0}; + src_uv += (width - 8) << 1; + for (x = 0; x < width; x += 8) { + src = LD_UH(src_uv); + dst = __msa_vshf_h(shuffler, src, src); + ST_UH(dst, dst_uv); + src_uv -= 16; + dst_uv += 16; + } +} + void ARGBMirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { int x; v16u8 src0, src1, src2, src3; @@ -825,12 +838,13 @@ void ARGBToUVRow_MSA(const uint8_t* src_argb0, v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; v8u16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9; v16u8 dst0, dst1; - v8u16 const_0x70 = (v8u16)__msa_ldi_h(0x70); - v8u16 const_0x4A = (v8u16)__msa_ldi_h(0x4A); - v8u16 const_0x26 = (v8u16)__msa_ldi_h(0x26); - v8u16 const_0x5E = (v8u16)__msa_ldi_h(0x5E); - v8u16 const_0x12 = (v8u16)__msa_ldi_h(0x12); + v8u16 const_0x70 = (v8u16)__msa_ldi_h(0x38); + v8u16 const_0x4A = (v8u16)__msa_ldi_h(0x25); + v8u16 const_0x26 = (v8u16)__msa_ldi_h(0x13); + v8u16 const_0x5E = (v8u16)__msa_ldi_h(0x2f); + v8u16 const_0x12 = (v8u16)__msa_ldi_h(0x09); v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); + v8u16 const_0x0001 = (v8u16)__msa_fill_h(0x0001); for (x = 0; x < width; x += 32) { src0 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 0); @@ -889,12 +903,18 @@ void ARGBToUVRow_MSA(const uint8_t* src_argb0, reg3 += __msa_hadd_u_h(vec5, vec5); reg4 += __msa_hadd_u_h(vec0, vec0); reg5 += __msa_hadd_u_h(vec1, vec1); - reg0 = (v8u16)__msa_srai_h((v8i16)reg0, 2); - reg1 = (v8u16)__msa_srai_h((v8i16)reg1, 2); - reg2 = (v8u16)__msa_srai_h((v8i16)reg2, 2); - reg3 = (v8u16)__msa_srai_h((v8i16)reg3, 2); - reg4 = (v8u16)__msa_srai_h((v8i16)reg4, 2); - reg5 = (v8u16)__msa_srai_h((v8i16)reg5, 2); + reg0 += const_0x0001; + reg1 += const_0x0001; + reg2 += const_0x0001; + reg3 += const_0x0001; + reg4 += const_0x0001; + reg5 += const_0x0001; + reg0 = (v8u16)__msa_srai_h((v8i16)reg0, 1); + reg1 = (v8u16)__msa_srai_h((v8i16)reg1, 1); + reg2 = (v8u16)__msa_srai_h((v8i16)reg2, 1); + reg3 = (v8u16)__msa_srai_h((v8i16)reg3, 1); + reg4 = (v8u16)__msa_srai_h((v8i16)reg4, 1); + reg5 = (v8u16)__msa_srai_h((v8i16)reg5, 1); reg6 = reg0 * const_0x70; reg7 = reg1 * const_0x70; reg8 = reg2 * const_0x4A; @@ -1412,17 +1432,17 @@ void ARGBGrayRow_MSA(const uint8_t* src_argb, uint8_t* dst_argb, int width) { int x; v16u8 src0, src1, vec0, vec1, dst0, dst1; v8u16 reg0; - v16u8 const_0x26 = (v16u8)__msa_ldi_h(0x26); - v16u8 const_0x4B0F = (v16u8)__msa_fill_h(0x4B0F); + v16u8 const_0x4D = (v16u8)__msa_ldi_h(0x4D); + v16u8 const_0x961D = (v16u8)__msa_fill_h(0x961D); for (x = 0; x < width; x += 8) { src0 = (v16u8)__msa_ld_b((v16u8*)src_argb, 0); src1 = (v16u8)__msa_ld_b((v16u8*)src_argb, 16); vec0 = (v16u8)__msa_pckev_h((v8i16)src1, (v8i16)src0); vec1 = (v16u8)__msa_pckod_h((v8i16)src1, (v8i16)src0); - reg0 = __msa_dotp_u_h(vec0, const_0x4B0F); - reg0 = __msa_dpadd_u_h(reg0, vec1, const_0x26); - reg0 = (v8u16)__msa_srari_h((v8i16)reg0, 7); + reg0 = __msa_dotp_u_h(vec0, const_0x961D); + reg0 = __msa_dpadd_u_h(reg0, vec1, const_0x4D); + reg0 = (v8u16)__msa_srari_h((v8i16)reg0, 8); vec0 = (v16u8)__msa_ilvev_b((v16i8)reg0, (v16i8)reg0); vec1 = (v16u8)__msa_ilvod_b((v16i8)vec1, (v16i8)vec0); dst0 = (v16u8)__msa_ilvr_b((v16i8)vec1, (v16i8)vec0); @@ -2031,12 +2051,13 @@ void RGB24ToUVRow_MSA(const uint8_t* src_rgb0, v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; v8i16 reg0, reg1, reg2, reg3; v16u8 dst0; - v8u16 const_0x70 = (v8u16)__msa_fill_h(0x70); - v8u16 const_0x4A = (v8u16)__msa_fill_h(0x4A); - v8u16 const_0x26 = (v8u16)__msa_fill_h(0x26); - v8u16 const_0x5E = (v8u16)__msa_fill_h(0x5E); - v8u16 const_0x12 = (v8u16)__msa_fill_h(0x12); + v8u16 const_0x70 = (v8u16)__msa_fill_h(0x38); + v8u16 const_0x4A = (v8u16)__msa_fill_h(0x25); + v8u16 const_0x26 = (v8u16)__msa_fill_h(0x13); + v8u16 const_0x5E = (v8u16)__msa_fill_h(0x2f); + v8u16 const_0x12 = (v8u16)__msa_fill_h(0x09); v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); + v8u16 const_0x0001 = (v8u16)__msa_fill_h(0x0001); v16i8 mask = {0, 1, 2, 16, 3, 4, 5, 17, 6, 7, 8, 18, 9, 10, 11, 19}; v16i8 zero = {0}; @@ -2085,10 +2106,14 @@ void RGB24ToUVRow_MSA(const uint8_t* src_rgb0, reg1 += (v8i16)__msa_pckod_d((v2i64)vec3, (v2i64)vec2); reg2 += (v8i16)__msa_pckod_d((v2i64)vec5, (v2i64)vec4); reg3 += (v8i16)__msa_pckod_d((v2i64)vec7, (v2i64)vec6); - reg0 = __msa_srai_h((v8i16)reg0, 2); - reg1 = __msa_srai_h((v8i16)reg1, 2); - reg2 = __msa_srai_h((v8i16)reg2, 2); - reg3 = __msa_srai_h((v8i16)reg3, 2); + reg0 += const_0x0001; + reg1 += const_0x0001; + reg2 += const_0x0001; + reg3 += const_0x0001; + reg0 = __msa_srai_h((v8i16)reg0, 1); + reg1 = __msa_srai_h((v8i16)reg1, 1); + reg2 = __msa_srai_h((v8i16)reg2, 1); + reg3 = __msa_srai_h((v8i16)reg3, 1); vec4 = (v8u16)__msa_pckev_h(reg1, reg0); vec5 = (v8u16)__msa_pckev_h(reg3, reg2); vec6 = (v8u16)__msa_pckod_h(reg1, reg0); @@ -2136,12 +2161,13 @@ void RAWToUVRow_MSA(const uint8_t* src_rgb0, v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; v8i16 reg0, reg1, reg2, reg3; v16u8 dst0; - v8u16 const_0x70 = (v8u16)__msa_fill_h(0x70); - v8u16 const_0x4A = (v8u16)__msa_fill_h(0x4A); - v8u16 const_0x26 = (v8u16)__msa_fill_h(0x26); - v8u16 const_0x5E = (v8u16)__msa_fill_h(0x5E); - v8u16 const_0x12 = (v8u16)__msa_fill_h(0x12); + v8u16 const_0x70 = (v8u16)__msa_fill_h(0x38); + v8u16 const_0x4A = (v8u16)__msa_fill_h(0x25); + v8u16 const_0x26 = (v8u16)__msa_fill_h(0x13); + v8u16 const_0x5E = (v8u16)__msa_fill_h(0x2f); + v8u16 const_0x12 = (v8u16)__msa_fill_h(0x09); v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); + v8u16 const_0x0001 = (v8u16)__msa_fill_h(0x0001); v16i8 mask = {0, 1, 2, 16, 3, 4, 5, 17, 6, 7, 8, 18, 9, 10, 11, 19}; v16i8 zero = {0}; @@ -2190,10 +2216,14 @@ void RAWToUVRow_MSA(const uint8_t* src_rgb0, reg1 += (v8i16)__msa_pckod_d((v2i64)vec3, (v2i64)vec2); reg2 += (v8i16)__msa_pckod_d((v2i64)vec5, (v2i64)vec4); reg3 += (v8i16)__msa_pckod_d((v2i64)vec7, (v2i64)vec6); - reg0 = __msa_srai_h(reg0, 2); - reg1 = __msa_srai_h(reg1, 2); - reg2 = __msa_srai_h(reg2, 2); - reg3 = __msa_srai_h(reg3, 2); + reg0 += const_0x0001; + reg1 += const_0x0001; + reg2 += const_0x0001; + reg3 += const_0x0001; + reg0 = __msa_srai_h(reg0, 1); + reg1 = __msa_srai_h(reg1, 1); + reg2 = __msa_srai_h(reg2, 1); + reg3 = __msa_srai_h(reg3, 1); vec4 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); vec5 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); vec6 = (v8u16)__msa_pckod_h((v8i16)reg1, (v8i16)reg0); @@ -2419,16 +2449,16 @@ void SobelXYRow_MSA(const uint8_t* src_sobelx, void ARGBToYJRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { int x; v16u8 src0, src1, src2, src3, dst0; - v16u8 const_0x4B0F = (v16u8)__msa_fill_h(0x4B0F); - v16u8 const_0x26 = (v16u8)__msa_fill_h(0x26); - v8u16 const_0x40 = (v8u16)__msa_fill_h(0x40); + v16u8 const_0x961D = (v16u8)__msa_fill_h(0x961D); + v16u8 const_0x4D = (v16u8)__msa_fill_h(0x4D); + v8u16 const_0x80 = (v8u16)__msa_fill_h(0x80); for (x = 0; x < width; x += 16) { src0 = (v16u8)__msa_ld_b((void*)src_argb0, 0); src1 = (v16u8)__msa_ld_b((void*)src_argb0, 16); src2 = (v16u8)__msa_ld_b((void*)src_argb0, 32); src3 = (v16u8)__msa_ld_b((void*)src_argb0, 48); - ARGBTOY(src0, src1, src2, src3, const_0x4B0F, const_0x26, const_0x40, 7, + ARGBTOY(src0, src1, src2, src3, const_0x961D, const_0x4D, const_0x80, 8, dst0); ST_UB(dst0, dst_y); src_argb0 += 64; @@ -2504,61 +2534,123 @@ void ARGBToUVJRow_MSA(const uint8_t* src_rgb0, int x; const uint8_t* s = src_rgb0; const uint8_t* t = src_rgb0 + src_stride_rgb; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 vec0, vec1, vec2, vec3; - v16u8 dst0, dst1; - v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; - v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}; - v16i8 shuffler2 = {0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23, 24, 27, 28, 31}; - v16i8 shuffler3 = {1, 2, 5, 6, 9, 10, 13, 14, 17, 18, 21, 22, 25, 26, 29, 30}; - v16u8 const_0x7F = (v16u8)__msa_fill_h(0x7F); - v16u8 const_0x6B14 = (v16u8)__msa_fill_h(0x6B14); - v16u8 const_0x2B54 = (v16u8)__msa_fill_h(0x2B54); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); + v8u16 src0, src1, src2, src3, src4, src5, src6, src7; + v8u16 vec0, vec1, vec2, vec3; + v8u16 dst0, dst1, dst2, dst3; + v16u8 zero = {0}; + v8i16 shuffler0 = {0, 3, 4, 7, 8, 11, 12, 15}; + v8i16 shuffler1 = {1, 2, 5, 6, 9, 10, 13, 14}; + v8i16 shuffler2 = {2, 3, 6, 7, 10, 11, 14, 15}; + v8i16 shuffler3 = {0, 1, 4, 5, 8, 9, 12, 13}; + v8u16 const_0x0000003f = (v8u16)__msa_fill_w(0x0000003f); + v4u32 const_0x00008080 = (v8u16)__msa_fill_w(0x00008080); + v8u16 const_0x0015002a = (v8u16)__msa_fill_w(0x0015002a); + v8u16 const_0x0035000a = (v8u16)__msa_fill_w(0x0035000a); + v4i32 shift = __msa_fill_w(0x00000008); for (x = 0; x < width; x += 32) { - src0 = (v16u8)__msa_ld_b((void*)s, 0); - src1 = (v16u8)__msa_ld_b((void*)s, 16); - src2 = (v16u8)__msa_ld_b((void*)s, 32); - src3 = (v16u8)__msa_ld_b((void*)s, 48); - src4 = (v16u8)__msa_ld_b((void*)t, 0); - src5 = (v16u8)__msa_ld_b((void*)t, 16); - src6 = (v16u8)__msa_ld_b((void*)t, 32); - src7 = (v16u8)__msa_ld_b((void*)t, 48); - src0 = __msa_aver_u_b(src0, src4); - src1 = __msa_aver_u_b(src1, src5); - src2 = __msa_aver_u_b(src2, src6); - src3 = __msa_aver_u_b(src3, src7); - src4 = (v16u8)__msa_pckev_w((v4i32)src1, (v4i32)src0); - src5 = (v16u8)__msa_pckev_w((v4i32)src3, (v4i32)src2); - src6 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0); - src7 = (v16u8)__msa_pckod_w((v4i32)src3, (v4i32)src2); - vec0 = __msa_aver_u_b(src4, src6); - vec1 = __msa_aver_u_b(src5, src7); - src0 = (v16u8)__msa_ld_b((void*)s, 64); - src1 = (v16u8)__msa_ld_b((void*)s, 80); - src2 = (v16u8)__msa_ld_b((void*)s, 96); - src3 = (v16u8)__msa_ld_b((void*)s, 112); - src4 = (v16u8)__msa_ld_b((void*)t, 64); - src5 = (v16u8)__msa_ld_b((void*)t, 80); - src6 = (v16u8)__msa_ld_b((void*)t, 96); - src7 = (v16u8)__msa_ld_b((void*)t, 112); - src0 = __msa_aver_u_b(src0, src4); - src1 = __msa_aver_u_b(src1, src5); - src2 = __msa_aver_u_b(src2, src6); - src3 = __msa_aver_u_b(src3, src7); - src4 = (v16u8)__msa_pckev_w((v4i32)src1, (v4i32)src0); - src5 = (v16u8)__msa_pckev_w((v4i32)src3, (v4i32)src2); - src6 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0); - src7 = (v16u8)__msa_pckod_w((v4i32)src3, (v4i32)src2); - vec2 = __msa_aver_u_b(src4, src6); - vec3 = __msa_aver_u_b(src5, src7); - ARGBTOUV(vec0, vec1, vec2, vec3, const_0x6B14, const_0x7F, const_0x2B54, - const_0x8080, shuffler1, shuffler0, shuffler2, shuffler3, dst0, - dst1); - ST_UB(dst0, dst_v); - ST_UB(dst1, dst_u); + src1 = __msa_ld_b((void*)s, 0); + src3 = __msa_ld_b((void*)s, 16); + src5 = __msa_ld_b((void*)t, 0); + src7 = __msa_ld_b((void*)t, 16); + src0 = __msa_ilvr_b(zero, src1); + src1 = __msa_ilvl_b(zero, src1); + src2 = __msa_ilvr_b(zero, src3); + src3 = __msa_ilvl_b(zero, src3); + src4 = __msa_ilvr_b(zero, src5); + src5 = __msa_ilvl_b(zero, src5); + src6 = __msa_ilvr_b(zero, src7); + src7 = __msa_ilvl_b(zero, src7); + src0 += src4; + src1 += src5; + src2 += src6; + src3 += src7; + src4 = __msa_ilvev_d(src1, src0); + src5 = __msa_ilvod_d(src1, src0); + src6 = __msa_ilvev_d(src3, src2); + src7 = __msa_ilvod_d(src3, src2); + vec0 = __msa_aver_u_h(src4, src5); + vec1 = __msa_aver_u_h(src6, src7); + + src1 = __msa_ld_b((void*)s, 32); + src3 = __msa_ld_b((void*)s, 48); + src5 = __msa_ld_b((void*)t, 32); + src7 = __msa_ld_b((void*)t, 48); + src0 = __msa_ilvr_b(zero, src1); + src1 = __msa_ilvl_b(zero, src1); + src2 = __msa_ilvr_b(zero, src3); + src3 = __msa_ilvl_b(zero, src3); + src4 = __msa_ilvr_b(zero, src5); + src5 = __msa_ilvl_b(zero, src5); + src6 = __msa_ilvr_b(zero, src7); + src7 = __msa_ilvl_b(zero, src7); + src0 += src4; + src1 += src5; + src2 += src6; + src3 += src7; + src4 = __msa_ilvev_d(src1, src0); + src5 = __msa_ilvod_d(src1, src0); + src6 = __msa_ilvev_d(src3, src2); + src7 = __msa_ilvod_d(src3, src2); + vec2 = __msa_aver_u_h(src4, src5); + vec3 = __msa_aver_u_h(src6, src7); + ARGBTOUV(vec0, vec1, vec2, vec3, const_0x0000003f, const_0x00008080, + const_0x0015002a, const_0x0035000a, shuffler0, shuffler1, + shuffler2, shuffler3, shift, dst0, dst1); + + src1 = __msa_ld_b((void*)s, 64); + src3 = __msa_ld_b((void*)s, 80); + src5 = __msa_ld_b((void*)t, 64); + src7 = __msa_ld_b((void*)t, 80); + src0 = __msa_ilvr_b(zero, src1); + src1 = __msa_ilvl_b(zero, src1); + src2 = __msa_ilvr_b(zero, src3); + src3 = __msa_ilvl_b(zero, src3); + src4 = __msa_ilvr_b(zero, src5); + src5 = __msa_ilvl_b(zero, src5); + src6 = __msa_ilvr_b(zero, src7); + src7 = __msa_ilvl_b(zero, src7); + src0 += src4; + src1 += src5; + src2 += src6; + src3 += src7; + src4 = __msa_ilvev_d(src1, src0); + src5 = __msa_ilvod_d(src1, src0); + src6 = __msa_ilvev_d(src3, src2); + src7 = __msa_ilvod_d(src3, src2); + vec0 = __msa_aver_u_h(src4, src5); + vec1 = __msa_aver_u_h(src6, src7); + + src1 = __msa_ld_b((void*)s, 96); + src3 = __msa_ld_b((void*)s, 112); + src5 = __msa_ld_b((void*)t, 96); + src7 = __msa_ld_b((void*)t, 112); + src0 = __msa_ilvr_b(zero, src1); + src1 = __msa_ilvl_b(zero, src1); + src2 = __msa_ilvr_b(zero, src3); + src3 = __msa_ilvl_b(zero, src3); + src4 = __msa_ilvr_b(zero, src5); + src5 = __msa_ilvl_b(zero, src5); + src6 = __msa_ilvr_b(zero, src7); + src7 = __msa_ilvl_b(zero, src7); + src0 += src4; + src1 += src5; + src2 += src6; + src3 += src7; + src4 = __msa_ilvev_d(src1, src0); + src5 = __msa_ilvod_d(src1, src0); + src6 = __msa_ilvev_d(src3, src2); + src7 = __msa_ilvod_d(src3, src2); + vec2 = __msa_aver_u_h(src4, src5); + vec3 = __msa_aver_u_h(src6, src7); + ARGBTOUV(vec0, vec1, vec2, vec3, const_0x0000003f, const_0x00008080, + const_0x0015002a, const_0x0035000a, shuffler0, shuffler1, + shuffler2, shuffler3, shift, dst2, dst3); + + dst0 = (v8u16)__msa_pckev_b(dst2, dst0); + dst1 = (v8u16)__msa_pckev_b(dst3, dst1); + ST_UB(dst0, dst_u); + ST_UB(dst1, dst_v); s += 128; t += 128; dst_v += 16; @@ -2574,28 +2666,30 @@ void BGRAToUVRow_MSA(const uint8_t* src_rgb0, int x; const uint8_t* s = src_rgb0; const uint8_t* t = src_rgb0 + src_stride_rgb; - v16u8 dst0, dst1, vec0, vec1, vec2, vec3; - v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; - v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}; - v16i8 shuffler2 = {0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23, 24, 27, 28, 31}; - v16i8 shuffler3 = {2, 1, 6, 5, 10, 9, 14, 13, 18, 17, 22, 21, 26, 25, 30, 29}; - v16u8 const_0x125E = (v16u8)__msa_fill_h(0x125E); - v16u8 const_0x7000 = (v16u8)__msa_fill_h(0x7000); - v16u8 const_0x264A = (v16u8)__msa_fill_h(0x264A); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); + const uint8_t unused = 0xf; + v8u16 src0, src1, src2, src3; + v16u8 dst0, dst1; + v8i16 shuffler0 = {1, unused, 5, unused, 9, unused, 13, unused}; + v8i16 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15}; + v8i16 shuffler2 = {3, unused, 7, unused, 11, unused, 15, unused}; + v8i16 shuffler3 = {1, 2, 5, 6, 9, 10, 13, 14}; + v8u16 const_0x09002f = (v8u16)__msa_fill_w(0x09002f); + v8u16 const_0x000038 = (v8u16)__msa_fill_w(0x0038); + v8u16 const_0x250013 = (v8u16)__msa_fill_w(0x250013); + v4u32 const_0x008080 = (v4u32)__msa_fill_w(0x8080); + v8u16 const_0x0001 = (v8u16)__msa_fill_h(0x0001); - for (x = 0; x < width; x += 32) { - READ_ARGB(s, t, vec0, vec1, vec2, vec3); - ARGBTOUV(vec0, vec1, vec2, vec3, const_0x125E, const_0x7000, const_0x264A, - const_0x8080, shuffler0, shuffler1, shuffler2, shuffler3, dst0, - dst1); - ST_UB(dst0, dst_v); - ST_UB(dst1, dst_u); - s += 128; - t += 128; - dst_v += 16; - dst_u += 16; + for (x = 0; x < width; x += 16) { + READ_ARGB(s, t, src0, src1, src2, src3, const_0x0001); + ARGBTOUV_H(src0, src1, src2, src3, const_0x09002f, const_0x000038, + const_0x250013, const_0x008080, shuffler0, shuffler1, shuffler2, + shuffler3, dst0, dst1); + *((uint64_t*)dst_v) = __msa_copy_u_d((v2i64)dst0, 0); + *((uint64_t*)dst_u) = __msa_copy_u_d((v2i64)dst1, 0); + s += 64; + t += 64; + dst_u += 8; + dst_v += 8; } } @@ -2607,29 +2701,30 @@ void ABGRToUVRow_MSA(const uint8_t* src_rgb0, int x; const uint8_t* s = src_rgb0; const uint8_t* t = src_rgb0 + src_stride_rgb; - v16u8 src0, src1, src2, src3; + const uint8_t unused = 0xf; + v8u16 src0, src1, src2, src3; v16u8 dst0, dst1; - v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; - v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}; - v16i8 shuffler2 = {0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23, 24, 27, 28, 31}; - v16i8 shuffler3 = {1, 2, 5, 6, 9, 10, 13, 14, 17, 18, 21, 22, 25, 26, 29, 30}; - v16u8 const_0x4A26 = (v16u8)__msa_fill_h(0x4A26); - v16u8 const_0x0070 = (v16u8)__msa_fill_h(0x0070); - v16u8 const_0x125E = (v16u8)__msa_fill_h(0x125E); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); + v8i16 shuffler0 = {0, unused, 4, unused, 8, unused, 12, unused}; + v8i16 shuffler1 = {1, 2, 5, 6, 9, 10, 13, 14}; + v8i16 shuffler2 = {2, unused, 6, unused, 10, unused, 14, unused}; + v8i16 shuffler3 = {0, 1, 4, 5, 8, 9, 12, 13}; + v8u16 const_0x09002f = (v8u16)__msa_fill_w(0x09002f); + v8u16 const_0x000038 = (v8u16)__msa_fill_w(0x0038); + v8u16 const_0x250013 = (v8u16)__msa_fill_w(0x250013); + v4u32 const_0x008080 = (v4u32)__msa_fill_w(0x8080); + v8u16 const_0x0001 = (v8u16)__msa_fill_h(0x0001); - for (x = 0; x < width; x += 32) { - READ_ARGB(s, t, src0, src1, src2, src3); - ARGBTOUV(src0, src1, src2, src3, const_0x4A26, const_0x0070, const_0x125E, - const_0x8080, shuffler1, shuffler0, shuffler2, shuffler3, dst0, - dst1); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - s += 128; - t += 128; - dst_u += 16; - dst_v += 16; + for (x = 0; x < width; x += 16) { + READ_ARGB(s, t, src0, src1, src2, src3, const_0x0001); + ARGBTOUV_H(src0, src1, src2, src3, const_0x09002f, const_0x000038, + const_0x250013, const_0x008080, shuffler0, shuffler1, shuffler2, + shuffler3, dst0, dst1); + *((uint64_t*)dst_v) = __msa_copy_u_d((v2i64)dst0, 0); + *((uint64_t*)dst_u) = __msa_copy_u_d((v2i64)dst1, 0); + s += 64; + t += 64; + dst_u += 8; + dst_v += 8; } } @@ -2641,28 +2736,30 @@ void RGBAToUVRow_MSA(const uint8_t* src_rgb0, int x; const uint8_t* s = src_rgb0; const uint8_t* t = src_rgb0 + src_stride_rgb; - v16u8 dst0, dst1, vec0, vec1, vec2, vec3; - v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; - v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}; - v16i8 shuffler2 = {0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23, 24, 27, 28, 31}; - v16i8 shuffler3 = {2, 1, 6, 5, 10, 9, 14, 13, 18, 17, 22, 21, 26, 25, 30, 29}; - v16u8 const_0x125E = (v16u8)__msa_fill_h(0x264A); - v16u8 const_0x7000 = (v16u8)__msa_fill_h(0x7000); - v16u8 const_0x264A = (v16u8)__msa_fill_h(0x125E); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); + const uint8_t unused = 0xf; + v8u16 src0, src1, src2, src3; + v16u8 dst0, dst1; + v8i16 shuffler0 = {3, unused, 7, unused, 11, unused, 15, unused}; + v8i16 shuffler1 = {2, 1, 6, 5, 10, 9, 14, 13}; + v8i16 shuffler2 = {1, unused, 5, unused, 9, unused, 13, unused}; + v8i16 shuffler3 = {3, 2, 7, 6, 11, 10, 15, 14}; + v8u16 const_0x09002f = (v8u16)__msa_fill_w(0x09002f); + v8u16 const_0x000038 = (v8u16)__msa_fill_w(0x0038); + v8u16 const_0x250013 = (v8u16)__msa_fill_w(0x250013); + v4u32 const_0x008080 = (v4u32)__msa_fill_w(0x8080); + v8u16 const_0x0001 = (v8u16)__msa_fill_h(0x0001); - for (x = 0; x < width; x += 32) { - READ_ARGB(s, t, vec0, vec1, vec2, vec3); - ARGBTOUV(vec0, vec1, vec2, vec3, const_0x125E, const_0x7000, const_0x264A, - const_0x8080, shuffler0, shuffler1, shuffler2, shuffler3, dst0, - dst1); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - s += 128; - t += 128; - dst_u += 16; - dst_v += 16; + for (x = 0; x < width; x += 16) { + READ_ARGB(s, t, src0, src1, src2, src3, const_0x0001); + ARGBTOUV_H(src0, src1, src2, src3, const_0x09002f, const_0x000038, + const_0x250013, const_0x008080, shuffler0, shuffler1, shuffler2, + shuffler3, dst0, dst1); + *((uint64_t*)dst_v) = __msa_copy_u_d((v2i64)dst0, 0); + *((uint64_t*)dst_u) = __msa_copy_u_d((v2i64)dst1, 0); + s += 64; + t += 64; + dst_u += 8; + dst_v += 8; } } @@ -2734,13 +2831,24 @@ void I444ToARGBRow_MSA(const uint8_t* src_y, } } -void I400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width) { +// TODO - respect YuvConstants +void I400ToARGBRow_MSA(const uint8_t* src_y, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { int x; +#if defined(__aarch64__) || defined(__arm__) + int ygb = yuvconstants->kUVBiasBGR[3]; + int yg = yuvconstants->kYToRgb[1]; +#else + int ygb = yuvconstants->kYBiasToRgb[0]; + int yg = yuvconstants->kYToRgb[0]; +#endif v16u8 src0, res0, res1, res2, res3, res4, dst0, dst1, dst2, dst3; v8i16 vec0, vec1; v4i32 reg0, reg1, reg2, reg3; - v4i32 vec_yg = __msa_fill_w(0x4A35); - v8i16 vec_ygb = __msa_fill_h(0xFB78); + v4i32 vec_yg = __msa_fill_w(yg); + v8i16 vec_ygb = __msa_fill_h(ygb); v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); v8i16 max = __msa_ldi_h(0xFF); v8i16 zero = {0}; @@ -3006,7 +3114,7 @@ void ARGBBlendRow_MSA(const uint8_t* src_argb0, uint8_t* dst_argb, int width) { int x; - v16u8 src0, src1, src2, src3, dst0, dst1; + v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3; v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; v8u16 vec8, vec9, vec10, vec11, vec12, vec13; v8u16 const_256 = (v8u16)__msa_ldi_h(256); @@ -3051,12 +3159,12 @@ void ARGBBlendRow_MSA(const uint8_t* src_argb0, vec9 = (v8u16)__msa_srai_h((v8i16)vec9, 8); vec10 = (v8u16)__msa_srai_h((v8i16)vec10, 8); vec11 = (v8u16)__msa_srai_h((v8i16)vec11, 8); - vec0 += vec8; - vec1 += vec9; - vec2 += vec10; - vec3 += vec11; dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); + dst2 = (v16u8)__msa_pckev_b((v16i8)vec9, (v16i8)vec8); + dst3 = (v16u8)__msa_pckev_b((v16i8)vec11, (v16i8)vec10); + dst0 = (v16u8)__msa_adds_u_b(dst0, dst2); + dst1 = (v16u8)__msa_adds_u_b(dst1, dst3); dst0 = __msa_bmnz_v(dst0, const_255, mask); dst1 = __msa_bmnz_v(dst1, const_255, mask); ST_UB2(dst0, dst1, dst_argb, 16); @@ -3082,7 +3190,7 @@ void ARGBQuantizeRow_MSA(uint8_t* dst_argb, v16i8 mask = {0, 1, 2, 19, 4, 5, 6, 23, 8, 9, 10, 27, 12, 13, 14, 31}; v16i8 zero = {0}; - for (x = 0; x < width; x += 8) { + for (x = 0; x < width; x += 16) { src0 = (v16u8)__msa_ld_b((void*)dst_argb, 0); src1 = (v16u8)__msa_ld_b((void*)dst_argb, 16); src2 = (v16u8)__msa_ld_b((void*)dst_argb, 32); @@ -3315,10 +3423,10 @@ void SetRow_MSA(uint8_t* dst, uint8_t v8, int width) { } } -void MirrorUVRow_MSA(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorSplitUVRow_MSA(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { int x; v16u8 src0, src1, src2, src3; v16u8 dst0, dst1, dst2, dst3; diff --git a/TMessagesProj/jni/third_party/libyuv/source/row_neon.cc b/TMessagesProj/jni/third_party/libyuv/source/row_neon.cc index 1cf8eefea..a5aeaabfb 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/row_neon.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/row_neon.cc @@ -114,11 +114,11 @@ void I444ToARGBRow_NEON(const uint8_t* src_y, int width) { asm volatile( YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" + "vmov.u8 d23, #255 \n" "1: \n" READYUV444 YUVTORGB - "subs %4, %4, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%3]! \n" - "bgt 1b \n" + "subs %4, %4, #8 \n" + "vst4.8 {d20, d21, d22, d23}, [%3]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -140,11 +140,11 @@ void I422ToARGBRow_NEON(const uint8_t* src_y, int width) { asm volatile( YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" + "vmov.u8 d23, #255 \n" "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%3]! \n" - "bgt 1b \n" + "subs %4, %4, #8 \n" + "vst4.8 {d20, d21, d22, d23}, [%3]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -168,10 +168,10 @@ void I422AlphaToARGBRow_NEON(const uint8_t* src_y, asm volatile( YUVTORGB_SETUP "1: \n" READYUV422 YUVTORGB - "subs %5, %5, #8 \n" - "vld1.8 {d23}, [%3]! \n" - "vst4.8 {d20, d21, d22, d23}, [%4]! \n" - "bgt 1b \n" + "subs %5, %5, #8 \n" + "vld1.8 {d23}, [%3]! \n" + "vst4.8 {d20, d21, d22, d23}, [%4]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -195,10 +195,10 @@ void I422ToRGBARow_NEON(const uint8_t* src_y, asm volatile( YUVTORGB_SETUP "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vmov.u8 d19, #255 \n" // YUVTORGB modified d19 - "vst4.8 {d19, d20, d21, d22}, [%3]! \n" - "bgt 1b \n" + "subs %4, %4, #8 \n" + "vmov.u8 d19, #255 \n" // YUVTORGB modified d19 + "vst4.8 {d19, d20, d21, d22}, [%3]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -221,9 +221,9 @@ void I422ToRGB24Row_NEON(const uint8_t* src_y, asm volatile( YUVTORGB_SETUP "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vst3.8 {d20, d21, d22}, [%3]! \n" - "bgt 1b \n" + "subs %4, %4, #8 \n" + "vst3.8 {d20, d21, d22}, [%3]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -253,9 +253,9 @@ void I422ToRGB565Row_NEON(const uint8_t* src_y, asm volatile( YUVTORGB_SETUP "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" ARGBTORGB565 - "vst1.8 {q0}, [%3]! \n" // store 8 pixels RGB565. - "bgt 1b \n" + "subs %4, %4, #8 \n" ARGBTORGB565 + "vst1.8 {q0}, [%3]! \n" // store 8 pixels RGB565. + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -287,10 +287,10 @@ void I422ToARGB1555Row_NEON(const uint8_t* src_y, asm volatile( YUVTORGB_SETUP "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vmov.u8 d23, #255 \n" ARGBTOARGB1555 - "vst1.8 {q0}, [%3]! \n" // store 8 pixels - "bgt 1b \n" + "subs %4, %4, #8 \n" + "vmov.u8 d23, #255 \n" ARGBTOARGB1555 + "vst1.8 {q0}, [%3]! \n" // store 8 pixels + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -321,14 +321,14 @@ void I422ToARGB4444Row_NEON(const uint8_t* src_y, int width) { asm volatile( YUVTORGB_SETUP - "vmov.u8 d4, #0x0f \n" // vbic bits to clear + "vmov.u8 d4, #0x0f \n" // vbic bits to clear "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vmov.u8 d23, #255 \n" ARGBTOARGB4444 - "vst1.8 {q0}, [%3]! \n" // store 8 pixels - "bgt 1b \n" + "subs %4, %4, #8 \n" + "vmov.u8 d23, #255 \n" ARGBTOARGB4444 + "vst1.8 {q0}, [%3]! \n" // store 8 pixels + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -342,35 +342,38 @@ void I422ToARGB4444Row_NEON(const uint8_t* src_y, "q12", "q13", "q14", "q15"); } -void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { +void I400ToARGBRow_NEON(const uint8_t* src_y, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { asm volatile( YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" + "vmov.u8 d23, #255 \n" "1: \n" READYUV400 YUVTORGB - "subs %2, %2, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%1]! \n" - "bgt 1b \n" + "subs %2, %2, #8 \n" + "vst4.8 {d20, d21, d22, d23}, [%1]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 - : [kUVToRB] "r"(&kYuvI601Constants.kUVToRB), - [kUVToG] "r"(&kYuvI601Constants.kUVToG), - [kUVBiasBGR] "r"(&kYuvI601Constants.kUVBiasBGR), - [kYToRgb] "r"(&kYuvI601Constants.kYToRgb) + : [kUVToRB] "r"(&yuvconstants->kUVToRB), + [kUVToG] "r"(&yuvconstants->kUVToG), + [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), + [kYToRgb] "r"(&yuvconstants->kYToRgb) : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"); } void J400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d23, #255 \n" + "vmov.u8 d23, #255 \n" "1: \n" - "vld1.8 {d20}, [%0]! \n" - "vmov d21, d20 \n" - "vmov d22, d20 \n" - "subs %2, %2, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%1]! \n" - "bgt 1b \n" + "vld1.8 {d20}, [%0]! \n" + "vmov d21, d20 \n" + "vmov d22, d20 \n" + "subs %2, %2, #8 \n" + "vst4.8 {d20, d21, d22, d23}, [%1]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -384,11 +387,11 @@ void NV12ToARGBRow_NEON(const uint8_t* src_y, const struct YuvConstants* yuvconstants, int width) { asm volatile(YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" + "vmov.u8 d23, #255 \n" "1: \n" READNV12 YUVTORGB - "subs %3, %3, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%2]! \n" - "bgt 1b \n" + "subs %3, %3, #8 \n" + "vst4.8 {d20, d21, d22, d23}, [%2]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_uv), // %1 "+r"(dst_argb), // %2 @@ -407,11 +410,11 @@ void NV21ToARGBRow_NEON(const uint8_t* src_y, const struct YuvConstants* yuvconstants, int width) { asm volatile(YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" + "vmov.u8 d23, #255 \n" "1: \n" READNV21 YUVTORGB - "subs %3, %3, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%2]! \n" - "bgt 1b \n" + "subs %3, %3, #8 \n" + "vst4.8 {d20, d21, d22, d23}, [%2]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_vu), // %1 "+r"(dst_argb), // %2 @@ -436,9 +439,9 @@ void NV12ToRGB24Row_NEON(const uint8_t* src_y, "1: \n" READNV12 YUVTORGB - "subs %3, %3, #8 \n" - "vst3.8 {d20, d21, d22}, [%2]! \n" - "bgt 1b \n" + "subs %3, %3, #8 \n" + "vst3.8 {d20, d21, d22}, [%2]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_uv), // %1 "+r"(dst_rgb24), // %2 @@ -463,9 +466,9 @@ void NV21ToRGB24Row_NEON(const uint8_t* src_y, "1: \n" READNV21 YUVTORGB - "subs %3, %3, #8 \n" - "vst3.8 {d20, d21, d22}, [%2]! \n" - "bgt 1b \n" + "subs %3, %3, #8 \n" + "vst3.8 {d20, d21, d22}, [%2]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_vu), // %1 "+r"(dst_rgb24), // %2 @@ -486,9 +489,9 @@ void NV12ToRGB565Row_NEON(const uint8_t* src_y, asm volatile( YUVTORGB_SETUP "1: \n" READNV12 YUVTORGB - "subs %3, %3, #8 \n" ARGBTORGB565 - "vst1.8 {q0}, [%2]! \n" // store 8 pixels RGB565. - "bgt 1b \n" + "subs %3, %3, #8 \n" ARGBTORGB565 + "vst1.8 {q0}, [%2]! \n" // store 8 pixels RGB565. + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_uv), // %1 "+r"(dst_rgb565), // %2 @@ -506,11 +509,11 @@ void YUY2ToARGBRow_NEON(const uint8_t* src_yuy2, const struct YuvConstants* yuvconstants, int width) { asm volatile(YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" + "vmov.u8 d23, #255 \n" "1: \n" READYUY2 YUVTORGB - "subs %2, %2, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%1]! \n" - "bgt 1b \n" + "subs %2, %2, #8 \n" + "vst4.8 {d20, d21, d22, d23}, [%1]! \n" + "bgt 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -527,11 +530,11 @@ void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, const struct YuvConstants* yuvconstants, int width) { asm volatile(YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" + "vmov.u8 d23, #255 \n" "1: \n" READUYVY YUVTORGB - "subs %2, %2, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%1]! \n" - "bgt 1b \n" + "subs %2, %2, #8 \n" + "vst4.8 {d20, d21, d22, d23}, [%1]! \n" + "bgt 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -550,11 +553,11 @@ void SplitUVRow_NEON(const uint8_t* src_uv, int width) { asm volatile( "1: \n" - "vld2.8 {q0, q1}, [%0]! \n" // load 16 pairs of UV - "subs %3, %3, #16 \n" // 16 processed per loop - "vst1.8 {q0}, [%1]! \n" // store U - "vst1.8 {q1}, [%2]! \n" // store V - "bgt 1b \n" + "vld2.8 {q0, q1}, [%0]! \n" // load 16 pairs of UV + "subs %3, %3, #16 \n" // 16 processed per loop + "vst1.8 {q0}, [%1]! \n" // store U + "vst1.8 {q1}, [%2]! \n" // store V + "bgt 1b \n" : "+r"(src_uv), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -571,11 +574,11 @@ void MergeUVRow_NEON(const uint8_t* src_u, int width) { asm volatile( "1: \n" - "vld1.8 {q0}, [%0]! \n" // load U - "vld1.8 {q1}, [%1]! \n" // load V - "subs %3, %3, #16 \n" // 16 processed per loop - "vst2.8 {q0, q1}, [%2]! \n" // store 16 pairs of UV - "bgt 1b \n" + "vld1.8 {q0}, [%0]! \n" // load U + "vld1.8 {q1}, [%1]! \n" // load V + "subs %3, %3, #16 \n" // 16 processed per loop + "vst2.8 {q0, q1}, [%2]! \n" // store 16 pairs of UV + "bgt 1b \n" : "+r"(src_u), // %0 "+r"(src_v), // %1 "+r"(dst_uv), // %2 @@ -593,13 +596,13 @@ void SplitRGBRow_NEON(const uint8_t* src_rgb, int width) { asm volatile( "1: \n" - "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RGB - "vld3.8 {d1, d3, d5}, [%0]! \n" // next 8 RGB - "subs %4, %4, #16 \n" // 16 processed per loop - "vst1.8 {q0}, [%1]! \n" // store R - "vst1.8 {q1}, [%2]! \n" // store G - "vst1.8 {q2}, [%3]! \n" // store B - "bgt 1b \n" + "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RGB + "vld3.8 {d1, d3, d5}, [%0]! \n" // next 8 RGB + "subs %4, %4, #16 \n" // 16 processed per loop + "vst1.8 {q0}, [%1]! \n" // store R + "vst1.8 {q1}, [%2]! \n" // store G + "vst1.8 {q2}, [%3]! \n" // store B + "bgt 1b \n" : "+r"(src_rgb), // %0 "+r"(dst_r), // %1 "+r"(dst_g), // %2 @@ -618,13 +621,13 @@ void MergeRGBRow_NEON(const uint8_t* src_r, int width) { asm volatile( "1: \n" - "vld1.8 {q0}, [%0]! \n" // load R - "vld1.8 {q1}, [%1]! \n" // load G - "vld1.8 {q2}, [%2]! \n" // load B - "subs %4, %4, #16 \n" // 16 processed per loop - "vst3.8 {d0, d2, d4}, [%3]! \n" // store 8 RGB - "vst3.8 {d1, d3, d5}, [%3]! \n" // next 8 RGB - "bgt 1b \n" + "vld1.8 {q0}, [%0]! \n" // load R + "vld1.8 {q1}, [%1]! \n" // load G + "vld1.8 {q2}, [%2]! \n" // load B + "subs %4, %4, #16 \n" // 16 processed per loop + "vst3.8 {d0, d2, d4}, [%3]! \n" // store 8 RGB + "vst3.8 {d1, d3, d5}, [%3]! \n" // next 8 RGB + "bgt 1b \n" : "+r"(src_r), // %0 "+r"(src_g), // %1 "+r"(src_b), // %2 @@ -639,10 +642,10 @@ void MergeRGBRow_NEON(const uint8_t* src_r, void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width) { asm volatile( "1: \n" - "vld1.8 {d0, d1, d2, d3}, [%0]! \n" // load 32 - "subs %2, %2, #32 \n" // 32 processed per loop - "vst1.8 {d0, d1, d2, d3}, [%1]! \n" // store 32 - "bgt 1b \n" + "vld1.8 {d0, d1, d2, d3}, [%0]! \n" // load 32 + "subs %2, %2, #32 \n" // 32 processed per loop + "vst1.8 {d0, d1, d2, d3}, [%1]! \n" // store 32 + "bgt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 // Output registers @@ -654,11 +657,11 @@ void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width) { // SetRow writes 'width' bytes using an 8 bit value repeated. void SetRow_NEON(uint8_t* dst, uint8_t v8, int width) { asm volatile( - "vdup.8 q0, %2 \n" // duplicate 16 bytes + "vdup.8 q0, %2 \n" // duplicate 16 bytes "1: \n" - "subs %1, %1, #16 \n" // 16 bytes per loop - "vst1.8 {q0}, [%0]! \n" // store - "bgt 1b \n" + "subs %1, %1, #16 \n" // 16 bytes per loop + "vst1.8 {q0}, [%0]! \n" // store + "bgt 1b \n" : "+r"(dst), // %0 "+r"(width) // %1 : "r"(v8) // %2 @@ -668,11 +671,11 @@ void SetRow_NEON(uint8_t* dst, uint8_t v8, int width) { // ARGBSetRow writes 'width' pixels using an 32 bit value repeated. void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width) { asm volatile( - "vdup.u32 q0, %2 \n" // duplicate 4 ints + "vdup.u32 q0, %2 \n" // duplicate 4 ints "1: \n" - "subs %1, %1, #4 \n" // 4 pixels per loop - "vst1.8 {q0}, [%0]! \n" // store - "bgt 1b \n" + "subs %1, %1, #4 \n" // 4 pixels per loop + "vst1.8 {q0}, [%0]! \n" // store + "bgt 1b \n" : "+r"(dst), // %0 "+r"(width) // %1 : "r"(v32) // %2 @@ -682,41 +685,62 @@ void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width) { void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { asm volatile( // Start at end of source row. - "mov r3, #-16 \n" - "add %0, %0, %2 \n" - "sub %0, #16 \n" + "add %0, %0, %2 \n" + "sub %0, %0, #32 \n" // 32 bytes per loop "1: \n" - "vld1.8 {q0}, [%0], r3 \n" // src -= 16 - "subs %2, #16 \n" // 16 pixels per loop. - "vrev64.8 q0, q0 \n" - "vst1.8 {d1}, [%1]! \n" // dst += 16 - "vst1.8 {d0}, [%1]! \n" - "bgt 1b \n" + "vld1.8 {q1, q2}, [%0], %3 \n" // src -= 32 + "subs %2, #32 \n" // 32 pixels per loop. + "vrev64.8 q0, q2 \n" + "vrev64.8 q1, q1 \n" + "vswp d0, d1 \n" + "vswp d2, d3 \n" + "vst1.8 {q0, q1}, [%1]! \n" // dst += 32 + "bgt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 - : - : "cc", "memory", "r3", "q0"); + : "r"(-32) // %3 + : "cc", "memory", "q0", "q1", "q2"); } -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +void MirrorUVRow_NEON(const uint8_t* src_uv, uint8_t* dst_uv, int width) { asm volatile( // Start at end of source row. - "mov r12, #-16 \n" - "add %0, %0, %3, lsl #1 \n" - "sub %0, #16 \n" + "mov r12, #-16 \n" + "add %0, %0, %2, lsl #1 \n" + "sub %0, #16 \n" "1: \n" - "vld2.8 {d0, d1}, [%0], r12 \n" // src -= 16 - "subs %3, #8 \n" // 8 pixels per loop. - "vrev64.8 q0, q0 \n" - "vst1.8 {d0}, [%1]! \n" // dst += 8 - "vst1.8 {d1}, [%2]! \n" - "bgt 1b \n" + "vld2.8 {d0, d1}, [%0], r12 \n" // src -= 16 + "subs %2, #8 \n" // 8 pixels per loop. + "vrev64.8 q0, q0 \n" + "vst2.8 {d0, d1}, [%1]! \n" // dst += 16 + "bgt 1b \n" + : "+r"(src_uv), // %0 + "+r"(dst_uv), // %1 + "+r"(width) // %2 + : + : "cc", "memory", "r12", "q0"); +} + +void MirrorSplitUVRow_NEON(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + asm volatile( + // Start at end of source row. + "mov r12, #-16 \n" + "add %0, %0, %3, lsl #1 \n" + "sub %0, #16 \n" + + "1: \n" + "vld2.8 {d0, d1}, [%0], r12 \n" // src -= 16 + "subs %3, #8 \n" // 8 pixels per loop. + "vrev64.8 q0, q0 \n" + "vst1.8 {d0}, [%1]! \n" // dst += 8 + "vst1.8 {d1}, [%2]! \n" + "bgt 1b \n" : "+r"(src_uv), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -725,37 +749,57 @@ void MirrorUVRow_NEON(const uint8_t* src_uv, : "cc", "memory", "r12", "q0"); } -void ARGBMirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { +void ARGBMirrorRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { asm volatile( - // Start at end of source row. - "mov r3, #-16 \n" - "add %0, %0, %2, lsl #2 \n" - "sub %0, #16 \n" + "add %0, %0, %2, lsl #2 \n" + "sub %0, #32 \n" "1: \n" - "vld1.8 {q0}, [%0], r3 \n" // src -= 16 - "subs %2, #4 \n" // 4 pixels per loop. - "vrev64.32 q0, q0 \n" - "vst1.8 {d1}, [%1]! \n" // dst += 16 - "vst1.8 {d0}, [%1]! \n" - "bgt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "r3", "q0"); + "vld4.8 {d0, d1, d2, d3}, [%0], %3 \n" // src -= 32 + "subs %2, #8 \n" // 8 pixels per loop. + "vrev64.8 d0, d0 \n" + "vrev64.8 d1, d1 \n" + "vrev64.8 d2, d2 \n" + "vrev64.8 d3, d3 \n" + "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // dst += 32 + "bgt 1b \n" + : "+r"(src_argb), // %0 + "+r"(dst_argb), // %1 + "+r"(width) // %2 + : "r"(-32) // %3 + : "cc", "memory", "d0", "d1", "d2", "d3"); +} + +void RGB24MirrorRow_NEON(const uint8_t* src_rgb24, + uint8_t* dst_rgb24, + int width) { + src_rgb24 += width * 3 - 24; + asm volatile( + "1: \n" + "vld3.8 {d0, d1, d2}, [%0], %3 \n" // src -= 24 + "subs %2, #8 \n" // 8 pixels per loop. + "vrev64.8 d0, d0 \n" + "vrev64.8 d1, d1 \n" + "vrev64.8 d2, d2 \n" + "vst3.8 {d0, d1, d2}, [%1]! \n" // dst += 24 + "bgt 1b \n" + : "+r"(src_rgb24), // %0 + "+r"(dst_rgb24), // %1 + "+r"(width) // %2 + : "r"(-24) // %3 + : "cc", "memory", "d0", "d1", "d2"); } void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d4, #255 \n" // Alpha + "vmov.u8 d4, #255 \n" // Alpha "1: \n" - "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RGB24. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vst4.8 {d1, d2, d3, d4}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" + "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RGB24. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vst4.8 {d1, d2, d3, d4}, [%1]! \n" // store 8 pixels of ARGB. + "bgt 1b \n" : "+r"(src_rgb24), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -766,13 +810,13 @@ void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d4, #255 \n" // Alpha + "vmov.u8 d4, #255 \n" // Alpha "1: \n" - "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vswp.u8 d1, d3 \n" // swap R, B - "vst4.8 {d1, d2, d3, d4}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" + "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vswp.u8 d1, d3 \n" // swap R, B + "vst4.8 {d1, d2, d3, d4}, [%1]! \n" // store 8 pixels of ARGB. + "bgt 1b \n" : "+r"(src_raw), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -783,13 +827,13 @@ void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width) { void RAWToRGBARow_NEON(const uint8_t* src_raw, uint8_t* dst_rgba, int width) { asm volatile( - "vmov.u8 d0, #255 \n" // Alpha + "vmov.u8 d0, #255 \n" // Alpha "1: \n" - "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vswp.u8 d1, d3 \n" // swap R, B - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of RGBA. - "bgt 1b \n" + "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vswp.u8 d1, d3 \n" // swap R, B + "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of RGBA. + "bgt 1b \n" : "+r"(src_raw), // %0 "+r"(dst_rgba), // %1 "+r"(width) // %2 @@ -800,12 +844,12 @@ void RAWToRGBARow_NEON(const uint8_t* src_raw, uint8_t* dst_rgba, int width) { void RAWToRGB24Row_NEON(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { asm volatile( "1: \n" - "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vswp.u8 d1, d3 \n" // swap R, B - "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of + "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vswp.u8 d1, d3 \n" // swap R, B + "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of // RGB24. - "bgt 1b \n" + "bgt 1b \n" : "+r"(src_raw), // %0 "+r"(dst_rgb24), // %1 "+r"(width) // %2 @@ -830,13 +874,13 @@ void RGB565ToARGBRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d3, #255 \n" // Alpha + "vmov.u8 d3, #255 \n" // Alpha "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. RGB565TOARGB - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" + "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. + "bgt 1b \n" : "+r"(src_rgb565), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -876,13 +920,13 @@ void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d3, #255 \n" // Alpha + "vmov.u8 d3, #255 \n" // Alpha "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. ARGB1555TOARGB - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" + "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. + "bgt 1b \n" : "+r"(src_argb1555), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -905,13 +949,13 @@ void ARGB4444ToARGBRow_NEON(const uint8_t* src_argb4444, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d3, #255 \n" // Alpha + "vmov.u8 d3, #255 \n" // Alpha "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. ARGB4444TOARGB - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" + "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. + "bgt 1b \n" : "+r"(src_argb4444), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -925,11 +969,11 @@ void ARGBToRGB24Row_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "vld4.8 {d1, d2, d3, d4}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of + "vld4.8 {d1, d2, d3, d4}, [%0]! \n" // load 8 pixels of ARGB. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of // RGB24. - "bgt 1b \n" + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_rgb24), // %1 "+r"(width) // %2 @@ -941,11 +985,11 @@ void ARGBToRGB24Row_NEON(const uint8_t* src_argb, void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width) { asm volatile( "1: \n" - "vld4.8 {d1, d2, d3, d4}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vswp.u8 d1, d3 \n" // swap R, B - "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of RAW. - "bgt 1b \n" + "vld4.8 {d1, d2, d3, d4}, [%0]! \n" // load 8 pixels of ARGB. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vswp.u8 d1, d3 \n" // swap R, B + "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of RAW. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_raw), // %1 "+r"(width) // %2 @@ -957,10 +1001,10 @@ void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width) { void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { asm volatile( "1: \n" - "vld2.8 {q0, q1}, [%0]! \n" // load 16 pixels of YUY2. - "subs %2, %2, #16 \n" // 16 processed per loop. - "vst1.8 {q0}, [%1]! \n" // store 16 pixels of Y. - "bgt 1b \n" + "vld2.8 {q0, q1}, [%0]! \n" // load 16 pixels of YUY2. + "subs %2, %2, #16 \n" // 16 processed per loop. + "vst1.8 {q0}, [%1]! \n" // store 16 pixels of Y. + "bgt 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -972,10 +1016,10 @@ void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { void UYVYToYRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { asm volatile( "1: \n" - "vld2.8 {q0, q1}, [%0]! \n" // load 16 pixels of UYVY. - "subs %2, %2, #16 \n" // 16 processed per loop. - "vst1.8 {q1}, [%1]! \n" // store 16 pixels of Y. - "bgt 1b \n" + "vld2.8 {q0, q1}, [%0]! \n" // load 16 pixels of UYVY. + "subs %2, %2, #16 \n" // 16 processed per loop. + "vst1.8 {q1}, [%1]! \n" // store 16 pixels of Y. + "bgt 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -990,11 +1034,11 @@ void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, int width) { asm volatile( "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of YUY2. - "subs %3, %3, #16 \n" // 16 pixels = 8 UVs. - "vst1.8 {d1}, [%1]! \n" // store 8 U. - "vst1.8 {d3}, [%2]! \n" // store 8 V. - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of YUY2. + "subs %3, %3, #16 \n" // 16 pixels = 8 UVs. + "vst1.8 {d1}, [%1]! \n" // store 8 U. + "vst1.8 {d3}, [%2]! \n" // store 8 V. + "bgt 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1010,11 +1054,11 @@ void UYVYToUV422Row_NEON(const uint8_t* src_uyvy, int width) { asm volatile( "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of UYVY. - "subs %3, %3, #16 \n" // 16 pixels = 8 UVs. - "vst1.8 {d0}, [%1]! \n" // store 8 U. - "vst1.8 {d2}, [%2]! \n" // store 8 V. - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of UYVY. + "subs %3, %3, #16 \n" // 16 pixels = 8 UVs. + "vst1.8 {d0}, [%1]! \n" // store 8 U. + "vst1.8 {d2}, [%2]! \n" // store 8 V. + "bgt 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1030,16 +1074,16 @@ void YUY2ToUVRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_v, int width) { asm volatile( - "add %1, %0, %1 \n" // stride + src_yuy2 + "add %1, %0, %1 \n" // stride + src_yuy2 "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of YUY2. - "subs %4, %4, #16 \n" // 16 pixels = 8 UVs. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load next row YUY2. - "vrhadd.u8 d1, d1, d5 \n" // average rows of U - "vrhadd.u8 d3, d3, d7 \n" // average rows of V - "vst1.8 {d1}, [%2]! \n" // store 8 U. - "vst1.8 {d3}, [%3]! \n" // store 8 V. - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of YUY2. + "subs %4, %4, #16 \n" // 16 pixels = 8 UVs. + "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load next row YUY2. + "vrhadd.u8 d1, d1, d5 \n" // average rows of U + "vrhadd.u8 d3, d3, d7 \n" // average rows of V + "vst1.8 {d1}, [%2]! \n" // store 8 U. + "vst1.8 {d3}, [%3]! \n" // store 8 V. + "bgt 1b \n" : "+r"(src_yuy2), // %0 "+r"(stride_yuy2), // %1 "+r"(dst_u), // %2 @@ -1057,16 +1101,16 @@ void UYVYToUVRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_v, int width) { asm volatile( - "add %1, %0, %1 \n" // stride + src_uyvy + "add %1, %0, %1 \n" // stride + src_uyvy "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of UYVY. - "subs %4, %4, #16 \n" // 16 pixels = 8 UVs. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load next row UYVY. - "vrhadd.u8 d0, d0, d4 \n" // average rows of U - "vrhadd.u8 d2, d2, d6 \n" // average rows of V - "vst1.8 {d0}, [%2]! \n" // store 8 U. - "vst1.8 {d2}, [%3]! \n" // store 8 V. - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of UYVY. + "subs %4, %4, #16 \n" // 16 pixels = 8 UVs. + "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load next row UYVY. + "vrhadd.u8 d0, d0, d4 \n" // average rows of U + "vrhadd.u8 d2, d2, d6 \n" // average rows of V + "vst1.8 {d0}, [%2]! \n" // store 8 U. + "vst1.8 {d2}, [%3]! \n" // store 8 V. + "bgt 1b \n" : "+r"(src_uyvy), // %0 "+r"(stride_uyvy), // %1 "+r"(dst_u), // %2 @@ -1084,14 +1128,14 @@ void ARGBShuffleRow_NEON(const uint8_t* src_argb, const uint8_t* shuffler, int width) { asm volatile( - "vld1.8 {q2}, [%3] \n" // shuffler + "vld1.8 {q2}, [%3] \n" // shuffler "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 4 pixels. - "subs %2, %2, #4 \n" // 4 processed per loop - "vtbl.8 d2, {d0, d1}, d4 \n" // look up 2 first pixels - "vtbl.8 d3, {d0, d1}, d5 \n" // look up 2 next pixels - "vst1.8 {q1}, [%1]! \n" // store 4. - "bgt 1b \n" + "vld1.8 {q0}, [%0]! \n" // load 4 pixels. + "subs %2, %2, #4 \n" // 4 processed per loop + "vtbl.8 d2, {d0, d1}, d4 \n" // look up 2 first pixels + "vtbl.8 d3, {d0, d1}, d5 \n" // look up 2 next pixels + "vst1.8 {q1}, [%1]! \n" // store 4. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -1107,12 +1151,12 @@ void I422ToYUY2Row_NEON(const uint8_t* src_y, int width) { asm volatile( "1: \n" - "vld2.8 {d0, d2}, [%0]! \n" // load 16 Ys - "vld1.8 {d1}, [%1]! \n" // load 8 Us - "vld1.8 {d3}, [%2]! \n" // load 8 Vs - "subs %4, %4, #16 \n" // 16 pixels - "vst4.8 {d0, d1, d2, d3}, [%3]! \n" // Store 8 YUY2/16 pixels. - "bgt 1b \n" + "vld2.8 {d0, d2}, [%0]! \n" // load 16 Ys + "vld1.8 {d1}, [%1]! \n" // load 8 Us + "vld1.8 {d3}, [%2]! \n" // load 8 Vs + "subs %4, %4, #16 \n" // 16 pixels + "vst4.8 {d0, d1, d2, d3}, [%3]! \n" // Store 8 YUY2/16 pixels. + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -1129,12 +1173,12 @@ void I422ToUYVYRow_NEON(const uint8_t* src_y, int width) { asm volatile( "1: \n" - "vld2.8 {d1, d3}, [%0]! \n" // load 16 Ys - "vld1.8 {d0}, [%1]! \n" // load 8 Us - "vld1.8 {d2}, [%2]! \n" // load 8 Vs - "subs %4, %4, #16 \n" // 16 pixels - "vst4.8 {d0, d1, d2, d3}, [%3]! \n" // Store 8 UYVY/16 pixels. - "bgt 1b \n" + "vld2.8 {d1, d3}, [%0]! \n" // load 16 Ys + "vld1.8 {d0}, [%1]! \n" // load 8 Us + "vld1.8 {d2}, [%2]! \n" // load 8 Vs + "subs %4, %4, #16 \n" // 16 pixels + "vst4.8 {d0, d1, d2, d3}, [%3]! \n" // Store 8 UYVY/16 pixels. + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -1149,11 +1193,11 @@ void ARGBToRGB565Row_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. + "subs %2, %2, #8 \n" // 8 processed per loop. ARGBTORGB565 - "vst1.8 {q0}, [%1]! \n" // store 8 pixels RGB565. - "bgt 1b \n" + "vst1.8 {q0}, [%1]! \n" // store 8 pixels RGB565. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_rgb565), // %1 "+r"(width) // %2 @@ -1166,16 +1210,16 @@ void ARGBToRGB565DitherRow_NEON(const uint8_t* src_argb, const uint32_t dither4, int width) { asm volatile( - "vdup.32 d2, %2 \n" // dither4 + "vdup.32 d2, %2 \n" // dither4 "1: \n" - "vld4.8 {d20, d21, d22, d23}, [%1]! \n" // load 8 pixels of ARGB. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqadd.u8 d20, d20, d2 \n" - "vqadd.u8 d21, d21, d2 \n" - "vqadd.u8 d22, d22, d2 \n" // add for dither + "vld4.8 {d20, d21, d22, d23}, [%1]! \n" // load 8 pixels of ARGB. + "subs %3, %3, #8 \n" // 8 processed per loop. + "vqadd.u8 d20, d20, d2 \n" + "vqadd.u8 d21, d21, d2 \n" + "vqadd.u8 d22, d22, d2 \n" // add for dither ARGBTORGB565 - "vst1.8 {q0}, [%0]! \n" // store 8 RGB565. - "bgt 1b \n" + "vst1.8 {q0}, [%0]! \n" // store 8 RGB565. + "bgt 1b \n" : "+r"(dst_rgb) // %0 : "r"(src_argb), // %1 "r"(dither4), // %2 @@ -1188,11 +1232,11 @@ void ARGBToARGB1555Row_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. + "subs %2, %2, #8 \n" // 8 processed per loop. ARGBTOARGB1555 - "vst1.8 {q0}, [%1]! \n" // store 8 ARGB1555. - "bgt 1b \n" + "vst1.8 {q0}, [%1]! \n" // store 8 ARGB1555. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb1555), // %1 "+r"(width) // %2 @@ -1204,14 +1248,14 @@ void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, uint8_t* dst_argb4444, int width) { asm volatile( - "vmov.u8 d4, #0x0f \n" // bits to clear with + "vmov.u8 d4, #0x0f \n" // bits to clear with // vbic. "1: \n" - "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. + "subs %2, %2, #8 \n" // 8 processed per loop. ARGBTOARGB4444 - "vst1.8 {q0}, [%1]! \n" // store 8 ARGB4444. - "bgt 1b \n" + "vst1.8 {q0}, [%1]! \n" // store 8 ARGB4444. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb4444), // %1 "+r"(width) // %2 @@ -1221,20 +1265,20 @@ void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d24, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d25, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d26, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d27, #16 \n" // Add 16 constant + "vmov.u8 d24, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d25, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d26, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d27, #16 \n" // Add 16 constant "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q2, d0, d24 \n" // B + "vmlal.u8 q2, d1, d25 \n" // G + "vmlal.u8 q2, d2, d26 \n" // R "vqrshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d27 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d27 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1247,11 +1291,11 @@ void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels - "subs %2, %2, #16 \n" // 16 processed per loop - "vst1.8 {q3}, [%1]! \n" // store 16 A's. - "bgt 1b \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels + "subs %2, %2, #16 \n" // 16 processed per loop + "vst1.8 {q3}, [%1]! \n" // store 16 A's. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_a), // %1 "+r"(width) // %2 @@ -1262,18 +1306,18 @@ void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d24, #29 \n" // B * 0.1140 coefficient - "vmov.u8 d25, #150 \n" // G * 0.5870 coefficient - "vmov.u8 d26, #77 \n" // R * 0.2990 coefficient + "vmov.u8 d24, #29 \n" // B * 0.1140 coefficient + "vmov.u8 d25, #150 \n" // G * 0.5870 coefficient + "vmov.u8 d26, #77 \n" // R * 0.2990 coefficient "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q2, d0, d24 \n" // B + "vmlal.u8 q2, d1, d25 \n" // G + "vmlal.u8 q2, d2, d26 \n" // R "vqrshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit Y - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1283,18 +1327,18 @@ void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { void RGBAToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d24, #29 \n" // B * 0.1140 coefficient - "vmov.u8 d25, #150 \n" // G * 0.5870 coefficient - "vmov.u8 d26, #77 \n" // R * 0.2990 coefficient + "vmov.u8 d24, #29 \n" // B * 0.1140 coefficient + "vmov.u8 d25, #150 \n" // G * 0.5870 coefficient + "vmov.u8 d26, #77 \n" // R * 0.2990 coefficient "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 RGBA pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d1, d24 \n" // B - "vmlal.u8 q2, d2, d25 \n" // G - "vmlal.u8 q2, d3, d26 \n" // R + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 RGBA pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q2, d1, d24 \n" // B + "vmlal.u8 q2, d2, d25 \n" // G + "vmlal.u8 q2, d3, d26 \n" // R "vqrshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit Y - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1308,32 +1352,32 @@ void ARGBToUV444Row_NEON(const uint8_t* src_argb, uint8_t* dst_v, int width) { asm volatile( - "vmov.u8 d24, #112 \n" // UB / VR 0.875 + "vmov.u8 d24, #112 \n" // UB / VR 0.875 // coefficient - "vmov.u8 d25, #74 \n" // UG -0.5781 coefficient - "vmov.u8 d26, #38 \n" // UR -0.2969 coefficient - "vmov.u8 d27, #18 \n" // VB -0.1406 coefficient - "vmov.u8 d28, #94 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 + "vmov.u8 d25, #74 \n" // UG -0.5781 coefficient + "vmov.u8 d26, #38 \n" // UR -0.2969 coefficient + "vmov.u8 d27, #18 \n" // VB -0.1406 coefficient + "vmov.u8 d28, #94 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d24 \n" // B - "vmlsl.u8 q2, d1, d25 \n" // G - "vmlsl.u8 q2, d2, d26 \n" // R - "vadd.u16 q2, q2, q15 \n" // +128 -> unsigned + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. + "subs %3, %3, #8 \n" // 8 processed per loop. + "vmull.u8 q2, d0, d24 \n" // B + "vmlsl.u8 q2, d1, d25 \n" // G + "vmlsl.u8 q2, d2, d26 \n" // R + "vadd.u16 q2, q2, q15 \n" // +128 -> unsigned - "vmull.u8 q3, d2, d24 \n" // R - "vmlsl.u8 q3, d1, d28 \n" // G - "vmlsl.u8 q3, d0, d27 \n" // B - "vadd.u16 q3, q3, q15 \n" // +128 -> unsigned + "vmull.u8 q3, d2, d24 \n" // R + "vmlsl.u8 q3, d1, d28 \n" // G + "vmlsl.u8 q3, d0, d27 \n" // B + "vadd.u16 q3, q3, q15 \n" // +128 -> unsigned "vqshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit U "vqshrn.u16 d1, q3, #8 \n" // 16 bit to 8 bit V - "vst1.8 {d0}, [%1]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%2]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%2]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1365,34 +1409,34 @@ void ARGBToUVRow_NEON(const uint8_t* src_argb, uint8_t* dst_v, int width) { asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_argb - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels. - "vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ARGB pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ARGB pixels. - "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. + "add %1, %0, %1 \n" // src_stride + src_argb + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 + "1: \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels. + "vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. + "vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts. + "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ARGB pixels. + "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ARGB pixels. + "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" + "vrshr.u16 q0, q0, #1 \n" // 2x average + "vrshr.u16 q1, q1, #1 \n" + "vrshr.u16 q2, q2, #1 \n" - "subs %4, %4, #16 \n" // 32 processed per loop. + "subs %4, %4, #16 \n" // 16 processed per loop. RGBTOUV(q0, q1, q2) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(src_stride_argb), // %1 "+r"(dst_u), // %2 @@ -1411,34 +1455,34 @@ void ARGBToUVJRow_NEON(const uint8_t* src_argb, uint8_t* dst_v, int width) { asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_argb - "vmov.s16 q10, #127 / 2 \n" // UB / VR 0.500 coefficient - "vmov.s16 q11, #84 / 2 \n" // UG -0.33126 coefficient - "vmov.s16 q12, #43 / 2 \n" // UR -0.16874 coefficient - "vmov.s16 q13, #20 / 2 \n" // VB -0.08131 coefficient - "vmov.s16 q14, #107 / 2 \n" // VG -0.41869 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels. - "vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ARGB pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ARGB pixels. - "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. + "add %1, %0, %1 \n" // src_stride + src_argb + "vmov.s16 q10, #127 / 2 \n" // UB / VR 0.500 coefficient + "vmov.s16 q11, #84 / 2 \n" // UG -0.33126 coefficient + "vmov.s16 q12, #43 / 2 \n" // UR -0.16874 coefficient + "vmov.s16 q13, #20 / 2 \n" // VB -0.08131 coefficient + "vmov.s16 q14, #107 / 2 \n" // VG -0.41869 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 + "1: \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels. + "vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. + "vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts. + "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ARGB pixels. + "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ARGB pixels. + "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" + "vrshr.u16 q0, q0, #1 \n" // 2x average + "vrshr.u16 q1, q1, #1 \n" + "vrshr.u16 q2, q2, #1 \n" - "subs %4, %4, #16 \n" // 32 processed per loop. + "subs %4, %4, #16 \n" // 16 processed per loop. RGBTOUV(q0, q1, q2) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(src_stride_argb), // %1 "+r"(dst_u), // %2 @@ -1456,34 +1500,34 @@ void BGRAToUVRow_NEON(const uint8_t* src_bgra, uint8_t* dst_v, int width) { asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_bgra - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 BGRA pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 BGRA pixels. - "vpaddl.u8 q3, q3 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q2, q2 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // R 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more BGRA pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 BGRA pixels. - "vpadal.u8 q3, q7 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q2, q6 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // R 16 bytes -> 8 shorts. + "add %1, %0, %1 \n" // src_stride + src_bgra + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 + "1: \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 BGRA pixels. + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 BGRA pixels. + "vpaddl.u8 q3, q3 \n" // B 16 bytes -> 8 shorts. + "vpaddl.u8 q2, q2 \n" // G 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // R 16 bytes -> 8 shorts. + "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more BGRA pixels. + "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 BGRA pixels. + "vpadal.u8 q3, q7 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q2, q6 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q1, q5 \n" // R 16 bytes -> 8 shorts. - "vrshr.u16 q1, q1, #1 \n" // 2x average - "vrshr.u16 q2, q2, #1 \n" - "vrshr.u16 q3, q3, #1 \n" + "vrshr.u16 q1, q1, #1 \n" // 2x average + "vrshr.u16 q2, q2, #1 \n" + "vrshr.u16 q3, q3, #1 \n" - "subs %4, %4, #16 \n" // 32 processed per loop. + "subs %4, %4, #16 \n" // 16 processed per loop. RGBTOUV(q3, q2, q1) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_bgra), // %0 "+r"(src_stride_bgra), // %1 "+r"(dst_u), // %2 @@ -1501,34 +1545,34 @@ void ABGRToUVRow_NEON(const uint8_t* src_abgr, uint8_t* dst_v, int width) { asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_abgr - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ABGR pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ABGR pixels. - "vpaddl.u8 q2, q2 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q0, q0 \n" // R 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ABGR pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ABGR pixels. - "vpadal.u8 q2, q6 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q0, q4 \n" // R 16 bytes -> 8 shorts. + "add %1, %0, %1 \n" // src_stride + src_abgr + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 + "1: \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ABGR pixels. + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ABGR pixels. + "vpaddl.u8 q2, q2 \n" // B 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. + "vpaddl.u8 q0, q0 \n" // R 16 bytes -> 8 shorts. + "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ABGR pixels. + "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ABGR pixels. + "vpadal.u8 q2, q6 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q0, q4 \n" // R 16 bytes -> 8 shorts. - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" + "vrshr.u16 q0, q0, #1 \n" // 2x average + "vrshr.u16 q1, q1, #1 \n" + "vrshr.u16 q2, q2, #1 \n" - "subs %4, %4, #16 \n" // 32 processed per loop. + "subs %4, %4, #16 \n" // 16 processed per loop. RGBTOUV(q2, q1, q0) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_abgr), // %0 "+r"(src_stride_abgr), // %1 "+r"(dst_u), // %2 @@ -1546,34 +1590,34 @@ void RGBAToUVRow_NEON(const uint8_t* src_rgba, uint8_t* dst_v, int width) { asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_rgba - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 RGBA pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 RGBA pixels. - "vpaddl.u8 q0, q1 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q2 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q2, q3 \n" // R 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more RGBA pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 RGBA pixels. - "vpadal.u8 q0, q5 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q6 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q7 \n" // R 16 bytes -> 8 shorts. + "add %1, %0, %1 \n" // src_stride + src_rgba + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 + "1: \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 RGBA pixels. + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 RGBA pixels. + "vpaddl.u8 q0, q1 \n" // B 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q2 \n" // G 16 bytes -> 8 shorts. + "vpaddl.u8 q2, q3 \n" // R 16 bytes -> 8 shorts. + "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more RGBA pixels. + "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 RGBA pixels. + "vpadal.u8 q0, q5 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q6 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q2, q7 \n" // R 16 bytes -> 8 shorts. - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" + "vrshr.u16 q0, q0, #1 \n" // 2x average + "vrshr.u16 q1, q1, #1 \n" + "vrshr.u16 q2, q2, #1 \n" - "subs %4, %4, #16 \n" // 32 processed per loop. + "subs %4, %4, #16 \n" // 16 processed per loop. RGBTOUV(q0, q1, q2) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_rgba), // %0 "+r"(src_stride_rgba), // %1 "+r"(dst_u), // %2 @@ -1591,34 +1635,34 @@ void RGB24ToUVRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_v, int width) { asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_rgb24 - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RGB24 pixels. - "vld3.8 {d1, d3, d5}, [%0]! \n" // load next 8 RGB24 pixels. - "vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts. - "vld3.8 {d8, d10, d12}, [%1]! \n" // load 8 more RGB24 pixels. - "vld3.8 {d9, d11, d13}, [%1]! \n" // load last 8 RGB24 pixels. - "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. + "add %1, %0, %1 \n" // src_stride + src_rgb24 + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 + "1: \n" + "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RGB24 pixels. + "vld3.8 {d1, d3, d5}, [%0]! \n" // load next 8 RGB24 pixels. + "vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. + "vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts. + "vld3.8 {d8, d10, d12}, [%1]! \n" // load 8 more RGB24 pixels. + "vld3.8 {d9, d11, d13}, [%1]! \n" // load last 8 RGB24 pixels. + "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" + "vrshr.u16 q0, q0, #1 \n" // 2x average + "vrshr.u16 q1, q1, #1 \n" + "vrshr.u16 q2, q2, #1 \n" - "subs %4, %4, #16 \n" // 32 processed per loop. + "subs %4, %4, #16 \n" // 16 processed per loop. RGBTOUV(q0, q1, q2) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_rgb24), // %0 "+r"(src_stride_rgb24), // %1 "+r"(dst_u), // %2 @@ -1636,34 +1680,34 @@ void RAWToUVRow_NEON(const uint8_t* src_raw, uint8_t* dst_v, int width) { asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_raw - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RAW pixels. - "vld3.8 {d1, d3, d5}, [%0]! \n" // load next 8 RAW pixels. - "vpaddl.u8 q2, q2 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q0, q0 \n" // R 16 bytes -> 8 shorts. - "vld3.8 {d8, d10, d12}, [%1]! \n" // load 8 more RAW pixels. - "vld3.8 {d9, d11, d13}, [%1]! \n" // load last 8 RAW pixels. - "vpadal.u8 q2, q6 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q0, q4 \n" // R 16 bytes -> 8 shorts. + "add %1, %0, %1 \n" // src_stride + src_raw + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 coefficient + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 + "1: \n" + "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RAW pixels. + "vld3.8 {d1, d3, d5}, [%0]! \n" // load next 8 RAW pixels. + "vpaddl.u8 q2, q2 \n" // B 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. + "vpaddl.u8 q0, q0 \n" // R 16 bytes -> 8 shorts. + "vld3.8 {d8, d10, d12}, [%1]! \n" // load 8 more RAW pixels. + "vld3.8 {d9, d11, d13}, [%1]! \n" // load last 8 RAW pixels. + "vpadal.u8 q2, q6 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q0, q4 \n" // R 16 bytes -> 8 shorts. - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" + "vrshr.u16 q0, q0, #1 \n" // 2x average + "vrshr.u16 q1, q1, #1 \n" + "vrshr.u16 q2, q2, #1 \n" - "subs %4, %4, #16 \n" // 32 processed per loop. + "subs %4, %4, #16 \n" // 16 processed per loop. RGBTOUV(q2, q1, q0) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_raw), // %0 "+r"(src_stride_raw), // %1 "+r"(dst_u), // %2 @@ -1682,55 +1726,55 @@ void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_v, int width) { asm volatile( - "add %1, %0, %1 \n" // src_stride + src_argb - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 + "add %1, %0, %1 \n" // src_stride + src_argb + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 // coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. + "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. RGB565TOARGB - "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%0]! \n" // next 8 RGB565 pixels. + "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. + "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. + "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. + "vld1.8 {q0}, [%0]! \n" // next 8 RGB565 pixels. RGB565TOARGB - "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. + "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. + "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. + "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // load 8 RGB565 pixels. + "vld1.8 {q0}, [%1]! \n" // load 8 RGB565 pixels. RGB565TOARGB - "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // next 8 RGB565 pixels. + "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. + "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. + "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. + "vld1.8 {q0}, [%1]! \n" // next 8 RGB565 pixels. RGB565TOARGB - "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. + "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. + "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. + "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - "vrshr.u16 q4, q4, #1 \n" // 2x average - "vrshr.u16 q5, q5, #1 \n" - "vrshr.u16 q6, q6, #1 \n" + "vrshr.u16 q4, q4, #1 \n" // 2x average + "vrshr.u16 q5, q5, #1 \n" + "vrshr.u16 q6, q6, #1 \n" - "subs %4, %4, #16 \n" // 16 processed per loop. - "vmul.s16 q8, q4, q10 \n" // B - "vmls.s16 q8, q5, q11 \n" // G - "vmls.s16 q8, q6, q12 \n" // R - "vadd.u16 q8, q8, q15 \n" // +128 -> unsigned - "vmul.s16 q9, q6, q10 \n" // R - "vmls.s16 q9, q5, q14 \n" // G - "vmls.s16 q9, q4, q13 \n" // B - "vadd.u16 q9, q9, q15 \n" // +128 -> unsigned + "subs %4, %4, #16 \n" // 16 processed per loop. + "vmul.s16 q8, q4, q10 \n" // B + "vmls.s16 q8, q5, q11 \n" // G + "vmls.s16 q8, q6, q12 \n" // R + "vadd.u16 q8, q8, q15 \n" // +128 -> unsigned + "vmul.s16 q9, q6, q10 \n" // R + "vmls.s16 q9, q5, q14 \n" // G + "vmls.s16 q9, q4, q13 \n" // B + "vadd.u16 q9, q9, q15 \n" // +128 -> unsigned "vqshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit U "vqshrn.u16 d1, q9, #8 \n" // 16 bit to 8 bit V - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_rgb565), // %0 "+r"(src_stride_rgb565), // %1 "+r"(dst_u), // %2 @@ -1748,55 +1792,55 @@ void ARGB1555ToUVRow_NEON(const uint8_t* src_argb1555, uint8_t* dst_v, int width) { asm volatile( - "add %1, %0, %1 \n" // src_stride + src_argb - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 + "add %1, %0, %1 \n" // src_stride + src_argb + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 // coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. + "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. RGB555TOARGB - "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%0]! \n" // next 8 ARGB1555 pixels. + "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. + "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. + "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. + "vld1.8 {q0}, [%0]! \n" // next 8 ARGB1555 pixels. RGB555TOARGB - "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. + "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. + "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. + "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // load 8 ARGB1555 pixels. + "vld1.8 {q0}, [%1]! \n" // load 8 ARGB1555 pixels. RGB555TOARGB - "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // next 8 ARGB1555 pixels. + "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. + "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. + "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. + "vld1.8 {q0}, [%1]! \n" // next 8 ARGB1555 pixels. RGB555TOARGB - "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. + "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. + "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. + "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - "vrshr.u16 q4, q4, #1 \n" // 2x average - "vrshr.u16 q5, q5, #1 \n" - "vrshr.u16 q6, q6, #1 \n" + "vrshr.u16 q4, q4, #1 \n" // 2x average + "vrshr.u16 q5, q5, #1 \n" + "vrshr.u16 q6, q6, #1 \n" - "subs %4, %4, #16 \n" // 16 processed per loop. - "vmul.s16 q8, q4, q10 \n" // B - "vmls.s16 q8, q5, q11 \n" // G - "vmls.s16 q8, q6, q12 \n" // R - "vadd.u16 q8, q8, q15 \n" // +128 -> unsigned - "vmul.s16 q9, q6, q10 \n" // R - "vmls.s16 q9, q5, q14 \n" // G - "vmls.s16 q9, q4, q13 \n" // B - "vadd.u16 q9, q9, q15 \n" // +128 -> unsigned + "subs %4, %4, #16 \n" // 16 processed per loop. + "vmul.s16 q8, q4, q10 \n" // B + "vmls.s16 q8, q5, q11 \n" // G + "vmls.s16 q8, q6, q12 \n" // R + "vadd.u16 q8, q8, q15 \n" // +128 -> unsigned + "vmul.s16 q9, q6, q10 \n" // R + "vmls.s16 q9, q5, q14 \n" // G + "vmls.s16 q9, q4, q13 \n" // B + "vadd.u16 q9, q9, q15 \n" // +128 -> unsigned "vqshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit U "vqshrn.u16 d1, q9, #8 \n" // 16 bit to 8 bit V - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_argb1555), // %0 "+r"(src_stride_argb1555), // %1 "+r"(dst_u), // %2 @@ -1814,55 +1858,46 @@ void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, uint8_t* dst_v, int width) { asm volatile( - "add %1, %0, %1 \n" // src_stride + src_argb - "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 + "add %1, %0, %1 \n" // src_stride + src_argb + "vmov.s16 q10, #112 / 2 \n" // UB / VR 0.875 // coefficient - "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient - "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient - "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient - "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 + "vmov.s16 q11, #74 / 2 \n" // UG -0.5781 coefficient + "vmov.s16 q12, #38 / 2 \n" // UR -0.2969 coefficient + "vmov.s16 q13, #18 / 2 \n" // VB -0.1406 coefficient + "vmov.s16 q14, #94 / 2 \n" // VG -0.7344 coefficient + "vmov.u16 q15, #0x8080 \n" // 128.5 "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. + "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. ARGB4444TOARGB - "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%0]! \n" // next 8 ARGB4444 pixels. + "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. + "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. + "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. + "vld1.8 {q0}, [%0]! \n" // next 8 ARGB4444 pixels. ARGB4444TOARGB - "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. + "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. + "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. + "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // load 8 ARGB4444 pixels. + "vld1.8 {q0}, [%1]! \n" // load 8 ARGB4444 pixels. ARGB4444TOARGB - "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // next 8 ARGB4444 pixels. + "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. + "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. + "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. + "vld1.8 {q0}, [%1]! \n" // next 8 ARGB4444 pixels. ARGB4444TOARGB - "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. + "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. + "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. + "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - "vrshr.u16 q4, q4, #1 \n" // 2x average - "vrshr.u16 q5, q5, #1 \n" - "vrshr.u16 q6, q6, #1 \n" + "vrshr.u16 q0, q4, #1 \n" // 2x average + "vrshr.u16 q1, q5, #1 \n" + "vrshr.u16 q2, q6, #1 \n" - "subs %4, %4, #16 \n" // 16 processed per loop. - "vmul.s16 q8, q4, q10 \n" // B - "vmls.s16 q8, q5, q11 \n" // G - "vmls.s16 q8, q6, q12 \n" // R - "vadd.u16 q8, q8, q15 \n" // +128 -> unsigned - "vmul.s16 q9, q6, q10 \n" // R - "vmls.s16 q9, q5, q14 \n" // G - "vmls.s16 q9, q4, q13 \n" // B - "vadd.u16 q9, q9, q15 \n" // +128 -> unsigned - "vqshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit U - "vqshrn.u16 d1, q9, #8 \n" // 16 bit to 8 bit V - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" + "subs %4, %4, #16 \n" // 16 processed per loop. + RGBTOUV(q0, q1, q2) + "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. + "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. + "bgt 1b \n" : "+r"(src_argb4444), // %0 "+r"(src_stride_argb4444), // %1 "+r"(dst_u), // %2 @@ -1875,21 +1910,21 @@ void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d24, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d25, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d26, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d27, #16 \n" // Add 16 constant + "vmov.u8 d24, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d25, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d26, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d27, #16 \n" // Add 16 constant "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. RGB565TOARGB - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R + "vmull.u8 q2, d0, d24 \n" // B + "vmlal.u8 q2, d1, d25 \n" // G + "vmlal.u8 q2, d2, d26 \n" // R "vqrshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d27 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d27 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_rgb565), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1901,21 +1936,21 @@ void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d24, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d25, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d26, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d27, #16 \n" // Add 16 constant + "vmov.u8 d24, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d25, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d26, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d27, #16 \n" // Add 16 constant "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. ARGB1555TOARGB - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R + "vmull.u8 q2, d0, d24 \n" // B + "vmlal.u8 q2, d1, d25 \n" // G + "vmlal.u8 q2, d2, d26 \n" // R "vqrshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d27 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d27 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_argb1555), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1927,21 +1962,21 @@ void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d24, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d25, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d26, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d27, #16 \n" // Add 16 constant + "vmov.u8 d24, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d25, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d26, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d27, #16 \n" // Add 16 constant "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. + "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. ARGB4444TOARGB - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R + "vmull.u8 q2, d0, d24 \n" // B + "vmlal.u8 q2, d1, d25 \n" // G + "vmlal.u8 q2, d2, d26 \n" // R "vqrshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d27 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d27 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_argb4444), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1951,20 +1986,20 @@ void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d6, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d4, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant + "vmov.u8 d6, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d4, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d7, #16 \n" // Add 16 constant "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of BGRA. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d1, d4 \n" // R - "vmlal.u8 q8, d2, d5 \n" // G - "vmlal.u8 q8, d3, d6 \n" // B + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of BGRA. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q8, d1, d4 \n" // R + "vmlal.u8 q8, d2, d5 \n" // G + "vmlal.u8 q8, d3, d6 \n" // B "vqrshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d7 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_bgra), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1974,20 +2009,20 @@ void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width) { void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d6, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d4, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant + "vmov.u8 d6, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d4, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d7, #16 \n" // Add 16 constant "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ABGR. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d0, d4 \n" // R - "vmlal.u8 q8, d1, d5 \n" // G - "vmlal.u8 q8, d2, d6 \n" // B + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ABGR. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q8, d0, d4 \n" // R + "vmlal.u8 q8, d1, d5 \n" // G + "vmlal.u8 q8, d2, d6 \n" // B "vqrshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d7 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_abgr), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1997,20 +2032,20 @@ void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width) { void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d4, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d6, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant + "vmov.u8 d4, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d6, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d7, #16 \n" // Add 16 constant "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of RGBA. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d1, d4 \n" // B - "vmlal.u8 q8, d2, d5 \n" // G - "vmlal.u8 q8, d3, d6 \n" // R + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of RGBA. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q8, d1, d4 \n" // B + "vmlal.u8 q8, d2, d5 \n" // G + "vmlal.u8 q8, d3, d6 \n" // R "vqrshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d7 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_rgba), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2020,20 +2055,20 @@ void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width) { void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d4, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d6, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant + "vmov.u8 d4, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d6, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d7, #16 \n" // Add 16 constant "1: \n" - "vld3.8 {d0, d1, d2}, [%0]! \n" // load 8 pixels of RGB24. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d0, d4 \n" // B - "vmlal.u8 q8, d1, d5 \n" // G - "vmlal.u8 q8, d2, d6 \n" // R + "vld3.8 {d0, d1, d2}, [%0]! \n" // load 8 pixels of RGB24. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q8, d0, d4 \n" // B + "vmlal.u8 q8, d1, d5 \n" // G + "vmlal.u8 q8, d2, d6 \n" // R "vqrshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d7 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_rgb24), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2043,20 +2078,20 @@ void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width) { asm volatile( - "vmov.u8 d6, #25 \n" // B * 0.1016 coefficient - "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient - "vmov.u8 d4, #66 \n" // R * 0.2578 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant + "vmov.u8 d6, #25 \n" // B * 0.1016 coefficient + "vmov.u8 d5, #129 \n" // G * 0.5078 coefficient + "vmov.u8 d4, #66 \n" // R * 0.2578 coefficient + "vmov.u8 d7, #16 \n" // Add 16 constant "1: \n" - "vld3.8 {d0, d1, d2}, [%0]! \n" // load 8 pixels of RAW. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d0, d4 \n" // B - "vmlal.u8 q8, d1, d5 \n" // G - "vmlal.u8 q8, d2, d6 \n" // R + "vld3.8 {d0, d1, d2}, [%0]! \n" // load 8 pixels of RAW. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q8, d0, d4 \n" // B + "vmlal.u8 q8, d1, d5 \n" // G + "vmlal.u8 q8, d2, d6 \n" // R "vqrshrn.u16 d0, q8, #8 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" + "vqadd.u8 d0, d7 \n" + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" : "+r"(src_raw), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2064,6 +2099,48 @@ void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width) { : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); } +void RGB24ToYJRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_yj, int width) { + asm volatile( + "vmov.u8 d4, #29 \n" // B * 0.1140 coefficient + "vmov.u8 d5, #150 \n" // G * 0.5870 coefficient + "vmov.u8 d6, #77 \n" // R * 0.2990 coefficient + "1: \n" + "vld3.8 {d0, d1, d2}, [%0]! \n" // load 8 pixels of RGB24. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q4, d0, d4 \n" // B + "vmlal.u8 q4, d1, d5 \n" // G + "vmlal.u8 q4, d2, d6 \n" // R + "vqrshrn.u16 d0, q4, #8 \n" // 16 bit to 8 bit Y + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" + : "+r"(src_rgb24), // %0 + "+r"(dst_yj), // %1 + "+r"(width) // %2 + : + : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "q4"); +} + +void RAWToYJRow_NEON(const uint8_t* src_raw, uint8_t* dst_yj, int width) { + asm volatile( + "vmov.u8 d6, #29 \n" // B * 0.1140 coefficient + "vmov.u8 d5, #150 \n" // G * 0.5870 coefficient + "vmov.u8 d4, #77 \n" // R * 0.2990 coefficient + "1: \n" + "vld3.8 {d0, d1, d2}, [%0]! \n" // load 8 pixels of RAW. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q4, d0, d4 \n" // B + "vmlal.u8 q4, d1, d5 \n" // G + "vmlal.u8 q4, d2, d6 \n" // R + "vqrshrn.u16 d0, q4, #8 \n" // 16 bit to 8 bit Y + "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. + "bgt 1b \n" + : "+r"(src_raw), // %0 + "+r"(dst_yj), // %1 + "+r"(width) // %2 + : + : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "q4"); +} + // Bilinear filter 16x2 -> 16x1 void InterpolateRow_NEON(uint8_t* dst_ptr, const uint8_t* src_ptr, @@ -2072,46 +2149,46 @@ void InterpolateRow_NEON(uint8_t* dst_ptr, int source_y_fraction) { int y1_fraction = source_y_fraction; asm volatile( - "cmp %4, #0 \n" - "beq 100f \n" - "add %2, %1 \n" - "cmp %4, #128 \n" - "beq 50f \n" + "cmp %4, #0 \n" + "beq 100f \n" + "add %2, %1 \n" + "cmp %4, #128 \n" + "beq 50f \n" - "vdup.8 d5, %4 \n" - "rsb %4, #256 \n" - "vdup.8 d4, %4 \n" + "vdup.8 d5, %4 \n" + "rsb %4, #256 \n" + "vdup.8 d4, %4 \n" // General purpose row blend. "1: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vmull.u8 q13, d0, d4 \n" - "vmull.u8 q14, d1, d4 \n" - "vmlal.u8 q13, d2, d5 \n" - "vmlal.u8 q14, d3, d5 \n" - "vrshrn.u16 d0, q13, #8 \n" - "vrshrn.u16 d1, q14, #8 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 1b \n" - "b 99f \n" + "vld1.8 {q0}, [%1]! \n" + "vld1.8 {q1}, [%2]! \n" + "subs %3, %3, #16 \n" + "vmull.u8 q13, d0, d4 \n" + "vmull.u8 q14, d1, d4 \n" + "vmlal.u8 q13, d2, d5 \n" + "vmlal.u8 q14, d3, d5 \n" + "vrshrn.u16 d0, q13, #8 \n" + "vrshrn.u16 d1, q14, #8 \n" + "vst1.8 {q0}, [%0]! \n" + "bgt 1b \n" + "b 99f \n" // Blend 50 / 50. "50: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vrhadd.u8 q0, q1 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 50b \n" - "b 99f \n" + "vld1.8 {q0}, [%1]! \n" + "vld1.8 {q1}, [%2]! \n" + "subs %3, %3, #16 \n" + "vrhadd.u8 q0, q1 \n" + "vst1.8 {q0}, [%0]! \n" + "bgt 50b \n" + "b 99f \n" // Blend 100 / 0 - Copy row unchanged. "100: \n" - "vld1.8 {q0}, [%1]! \n" - "subs %3, %3, #16 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 100b \n" + "vld1.8 {q0}, [%1]! \n" + "subs %3, %3, #16 \n" + "vst1.8 {q0}, [%0]! \n" + "bgt 100b \n" "99: \n" : "+r"(dst_ptr), // %0 @@ -2129,51 +2206,51 @@ void ARGBBlendRow_NEON(const uint8_t* src_argb0, uint8_t* dst_argb, int width) { asm volatile( - "subs %3, #8 \n" - "blt 89f \n" + "subs %3, #8 \n" + "blt 89f \n" // Blend 8 pixels. "8: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ARGB0. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 pixels of ARGB1. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vmull.u8 q10, d4, d3 \n" // db * a - "vmull.u8 q11, d5, d3 \n" // dg * a - "vmull.u8 q12, d6, d3 \n" // dr * a + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ARGB0. + "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 pixels of ARGB1. + "subs %3, %3, #8 \n" // 8 processed per loop. + "vmull.u8 q10, d4, d3 \n" // db * a + "vmull.u8 q11, d5, d3 \n" // dg * a + "vmull.u8 q12, d6, d3 \n" // dr * a "vqrshrn.u16 d20, q10, #8 \n" // db >>= 8 "vqrshrn.u16 d21, q11, #8 \n" // dg >>= 8 "vqrshrn.u16 d22, q12, #8 \n" // dr >>= 8 - "vqsub.u8 q2, q2, q10 \n" // dbg - dbg * a / 256 - "vqsub.u8 d6, d6, d22 \n" // dr - dr * a / 256 - "vqadd.u8 q0, q0, q2 \n" // + sbg - "vqadd.u8 d2, d2, d6 \n" // + sr - "vmov.u8 d3, #255 \n" // a = 255 - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 pixels of ARGB. - "bge 8b \n" + "vqsub.u8 q2, q2, q10 \n" // dbg - dbg * a / 256 + "vqsub.u8 d6, d6, d22 \n" // dr - dr * a / 256 + "vqadd.u8 q0, q0, q2 \n" // + sbg + "vqadd.u8 d2, d2, d6 \n" // + sr + "vmov.u8 d3, #255 \n" // a = 255 + "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 pixels of ARGB. + "bge 8b \n" "89: \n" - "adds %3, #8-1 \n" - "blt 99f \n" + "adds %3, #8-1 \n" + "blt 99f \n" // Blend 1 pixels. "1: \n" - "vld4.8 {d0[0],d1[0],d2[0],d3[0]}, [%0]! \n" // load 1 pixel ARGB0. - "vld4.8 {d4[0],d5[0],d6[0],d7[0]}, [%1]! \n" // load 1 pixel ARGB1. - "subs %3, %3, #1 \n" // 1 processed per loop. - "vmull.u8 q10, d4, d3 \n" // db * a - "vmull.u8 q11, d5, d3 \n" // dg * a - "vmull.u8 q12, d6, d3 \n" // dr * a - "vqrshrn.u16 d20, q10, #8 \n" // db >>= 8 - "vqrshrn.u16 d21, q11, #8 \n" // dg >>= 8 - "vqrshrn.u16 d22, q12, #8 \n" // dr >>= 8 - "vqsub.u8 q2, q2, q10 \n" // dbg - dbg * a / 256 - "vqsub.u8 d6, d6, d22 \n" // dr - dr * a / 256 - "vqadd.u8 q0, q0, q2 \n" // + sbg - "vqadd.u8 d2, d2, d6 \n" // + sr - "vmov.u8 d3, #255 \n" // a = 255 - "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [%2]! \n" // store 1 pixel. - "bge 1b \n" + "vld4.8 {d0[0],d1[0],d2[0],d3[0]}, [%0]! \n" // load 1 pixel ARGB0. + "vld4.8 {d4[0],d5[0],d6[0],d7[0]}, [%1]! \n" // load 1 pixel ARGB1. + "subs %3, %3, #1 \n" // 1 processed per loop. + "vmull.u8 q10, d4, d3 \n" // db * a + "vmull.u8 q11, d5, d3 \n" // dg * a + "vmull.u8 q12, d6, d3 \n" // dr * a + "vqrshrn.u16 d20, q10, #8 \n" // db >>= 8 + "vqrshrn.u16 d21, q11, #8 \n" // dg >>= 8 + "vqrshrn.u16 d22, q12, #8 \n" // dr >>= 8 + "vqsub.u8 q2, q2, q10 \n" // dbg - dbg * a / 256 + "vqsub.u8 d6, d6, d22 \n" // dr - dr * a / 256 + "vqadd.u8 q0, q0, q2 \n" // + sbg + "vqadd.u8 d2, d2, d6 \n" // + sr + "vmov.u8 d3, #255 \n" // a = 255 + "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [%2]! \n" // store 1 pixel. + "bge 1b \n" - "99: \n" + "99: \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 @@ -2190,16 +2267,16 @@ void ARGBAttenuateRow_NEON(const uint8_t* src_argb, asm volatile( // Attenuate 8 pixels. "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q10, d0, d3 \n" // b * a - "vmull.u8 q11, d1, d3 \n" // g * a - "vmull.u8 q12, d2, d3 \n" // r * a + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ARGB. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q10, d0, d3 \n" // b * a + "vmull.u8 q11, d1, d3 \n" // g * a + "vmull.u8 q12, d2, d3 \n" // r * a "vqrshrn.u16 d0, q10, #8 \n" // b >>= 8 "vqrshrn.u16 d1, q11, #8 \n" // g >>= 8 "vqrshrn.u16 d2, q12, #8 \n" // r >>= 8 - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" + "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -2215,32 +2292,32 @@ void ARGBQuantizeRow_NEON(uint8_t* dst_argb, int interval_offset, int width) { asm volatile( - "vdup.u16 q8, %2 \n" - "vshr.u16 q8, q8, #1 \n" // scale >>= 1 - "vdup.u16 q9, %3 \n" // interval multiply. - "vdup.u16 q10, %4 \n" // interval add + "vdup.u16 q8, %2 \n" + "vshr.u16 q8, q8, #1 \n" // scale >>= 1 + "vdup.u16 q9, %3 \n" // interval multiply. + "vdup.u16 q10, %4 \n" // interval add // 8 pixel loop. "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0] \n" // load 8 pixels of ARGB. - "subs %1, %1, #8 \n" // 8 processed per loop. - "vmovl.u8 q0, d0 \n" // b (0 .. 255) - "vmovl.u8 q1, d2 \n" - "vmovl.u8 q2, d4 \n" + "vld4.8 {d0, d2, d4, d6}, [%0] \n" // load 8 pixels of ARGB. + "subs %1, %1, #8 \n" // 8 processed per loop. + "vmovl.u8 q0, d0 \n" // b (0 .. 255) + "vmovl.u8 q1, d2 \n" + "vmovl.u8 q2, d4 \n" "vqdmulh.s16 q0, q0, q8 \n" // b * scale "vqdmulh.s16 q1, q1, q8 \n" // g "vqdmulh.s16 q2, q2, q8 \n" // r - "vmul.u16 q0, q0, q9 \n" // b * interval_size - "vmul.u16 q1, q1, q9 \n" // g - "vmul.u16 q2, q2, q9 \n" // r - "vadd.u16 q0, q0, q10 \n" // b + interval_offset - "vadd.u16 q1, q1, q10 \n" // g - "vadd.u16 q2, q2, q10 \n" // r - "vqmovn.u16 d0, q0 \n" - "vqmovn.u16 d2, q1 \n" - "vqmovn.u16 d4, q2 \n" - "vst4.8 {d0, d2, d4, d6}, [%0]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" + "vmul.u16 q0, q0, q9 \n" // b * interval_size + "vmul.u16 q1, q1, q9 \n" // g + "vmul.u16 q2, q2, q9 \n" // r + "vadd.u16 q0, q0, q10 \n" // b + interval_offset + "vadd.u16 q1, q1, q10 \n" // g + "vadd.u16 q2, q2, q10 \n" // r + "vqmovn.u16 d0, q0 \n" + "vqmovn.u16 d2, q1 \n" + "vqmovn.u16 d4, q2 \n" + "vst4.8 {d0, d2, d4, d6}, [%0]! \n" // store 8 pixels of ARGB. + "bgt 1b \n" : "+r"(dst_argb), // %0 "+r"(width) // %1 : "r"(scale), // %2 @@ -2257,28 +2334,28 @@ void ARGBShadeRow_NEON(const uint8_t* src_argb, int width, uint32_t value) { asm volatile( - "vdup.u32 q0, %3 \n" // duplicate scale value. - "vzip.u8 d0, d1 \n" // d0 aarrggbb. - "vshr.u16 q0, q0, #1 \n" // scale / 2. + "vdup.u32 q0, %3 \n" // duplicate scale value. + "vzip.u8 d0, d1 \n" // d0 aarrggbb. + "vshr.u16 q0, q0, #1 \n" // scale / 2. // 8 pixel loop. "1: \n" - "vld4.8 {d20, d22, d24, d26}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmovl.u8 q10, d20 \n" // b (0 .. 255) - "vmovl.u8 q11, d22 \n" - "vmovl.u8 q12, d24 \n" - "vmovl.u8 q13, d26 \n" + "vld4.8 {d20, d22, d24, d26}, [%0]! \n" // load 8 pixels of ARGB. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmovl.u8 q10, d20 \n" // b (0 .. 255) + "vmovl.u8 q11, d22 \n" + "vmovl.u8 q12, d24 \n" + "vmovl.u8 q13, d26 \n" "vqrdmulh.s16 q10, q10, d0[0] \n" // b * scale * 2 "vqrdmulh.s16 q11, q11, d0[1] \n" // g "vqrdmulh.s16 q12, q12, d0[2] \n" // r "vqrdmulh.s16 q13, q13, d0[3] \n" // a - "vqmovn.u16 d20, q10 \n" - "vqmovn.u16 d22, q11 \n" - "vqmovn.u16 d24, q12 \n" - "vqmovn.u16 d26, q13 \n" - "vst4.8 {d20, d22, d24, d26}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" + "vqmovn.u16 d20, q10 \n" + "vqmovn.u16 d22, q11 \n" + "vqmovn.u16 d24, q12 \n" + "vqmovn.u16 d26, q13 \n" + "vst4.8 {d20, d22, d24, d26}, [%1]! \n" // store 8 pixels of ARGB. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -2291,20 +2368,20 @@ void ARGBShadeRow_NEON(const uint8_t* src_argb, // C code is (29 * b + 150 * g + 77 * r + 128) >> 8; void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d24, #29 \n" // B * 0.1140 coefficient - "vmov.u8 d25, #150 \n" // G * 0.5870 coefficient - "vmov.u8 d26, #77 \n" // R * 0.2990 coefficient + "vmov.u8 d24, #29 \n" // B * 0.1140 coefficient + "vmov.u8 d25, #150 \n" // G * 0.5870 coefficient + "vmov.u8 d26, #77 \n" // R * 0.2990 coefficient "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmull.u8 q2, d0, d24 \n" // B + "vmlal.u8 q2, d1, d25 \n" // G + "vmlal.u8 q2, d2, d26 \n" // R "vqrshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit B - "vmov d1, d0 \n" // G - "vmov d2, d0 \n" // R - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 ARGB pixels. - "bgt 1b \n" + "vmov d1, d0 \n" // G + "vmov d2, d0 \n" // R + "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 ARGB pixels. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -2318,32 +2395,32 @@ void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { // r = (r * 50 + g * 98 + b * 24) >> 7 void ARGBSepiaRow_NEON(uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d20, #17 \n" // BB coefficient - "vmov.u8 d21, #68 \n" // BG coefficient - "vmov.u8 d22, #35 \n" // BR coefficient - "vmov.u8 d24, #22 \n" // GB coefficient - "vmov.u8 d25, #88 \n" // GG coefficient - "vmov.u8 d26, #45 \n" // GR coefficient - "vmov.u8 d28, #24 \n" // BB coefficient - "vmov.u8 d29, #98 \n" // BG coefficient - "vmov.u8 d30, #50 \n" // BR coefficient + "vmov.u8 d20, #17 \n" // BB coefficient + "vmov.u8 d21, #68 \n" // BG coefficient + "vmov.u8 d22, #35 \n" // BR coefficient + "vmov.u8 d24, #22 \n" // GB coefficient + "vmov.u8 d25, #88 \n" // GG coefficient + "vmov.u8 d26, #45 \n" // GR coefficient + "vmov.u8 d28, #24 \n" // BB coefficient + "vmov.u8 d29, #98 \n" // BG coefficient + "vmov.u8 d30, #50 \n" // BR coefficient "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0] \n" // load 8 ARGB pixels. - "subs %1, %1, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d20 \n" // B to Sepia B - "vmlal.u8 q2, d1, d21 \n" // G - "vmlal.u8 q2, d2, d22 \n" // R - "vmull.u8 q3, d0, d24 \n" // B to Sepia G - "vmlal.u8 q3, d1, d25 \n" // G - "vmlal.u8 q3, d2, d26 \n" // R - "vmull.u8 q8, d0, d28 \n" // B to Sepia R - "vmlal.u8 q8, d1, d29 \n" // G - "vmlal.u8 q8, d2, d30 \n" // R - "vqshrn.u16 d0, q2, #7 \n" // 16 bit to 8 bit B - "vqshrn.u16 d1, q3, #7 \n" // 16 bit to 8 bit G - "vqshrn.u16 d2, q8, #7 \n" // 16 bit to 8 bit R - "vst4.8 {d0, d1, d2, d3}, [%0]! \n" // store 8 ARGB pixels. - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0] \n" // load 8 ARGB pixels. + "subs %1, %1, #8 \n" // 8 processed per loop. + "vmull.u8 q2, d0, d20 \n" // B to Sepia B + "vmlal.u8 q2, d1, d21 \n" // G + "vmlal.u8 q2, d2, d22 \n" // R + "vmull.u8 q3, d0, d24 \n" // B to Sepia G + "vmlal.u8 q3, d1, d25 \n" // G + "vmlal.u8 q3, d2, d26 \n" // R + "vmull.u8 q8, d0, d28 \n" // B to Sepia R + "vmlal.u8 q8, d1, d29 \n" // G + "vmlal.u8 q8, d2, d30 \n" // R + "vqshrn.u16 d0, q2, #7 \n" // 16 bit to 8 bit B + "vqshrn.u16 d1, q3, #7 \n" // 16 bit to 8 bit G + "vqshrn.u16 d2, q8, #7 \n" // 16 bit to 8 bit R + "vst4.8 {d0, d1, d2, d3}, [%0]! \n" // store 8 ARGB pixels. + "bgt 1b \n" : "+r"(dst_argb), // %0 "+r"(width) // %1 : @@ -2359,51 +2436,51 @@ void ARGBColorMatrixRow_NEON(const uint8_t* src_argb, const int8_t* matrix_argb, int width) { asm volatile( - "vld1.8 {q2}, [%3] \n" // load 3 ARGB vectors. - "vmovl.s8 q0, d4 \n" // B,G coefficients s16. - "vmovl.s8 q1, d5 \n" // R,A coefficients s16. + "vld1.8 {q2}, [%3] \n" // load 3 ARGB vectors. + "vmovl.s8 q0, d4 \n" // B,G coefficients s16. + "vmovl.s8 q1, d5 \n" // R,A coefficients s16. "1: \n" - "vld4.8 {d16, d18, d20, d22}, [%0]! \n" // load 8 ARGB pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmovl.u8 q8, d16 \n" // b (0 .. 255) 16 bit - "vmovl.u8 q9, d18 \n" // g - "vmovl.u8 q10, d20 \n" // r - "vmovl.u8 q11, d22 \n" // a - "vmul.s16 q12, q8, d0[0] \n" // B = B * Matrix B - "vmul.s16 q13, q8, d1[0] \n" // G = B * Matrix G - "vmul.s16 q14, q8, d2[0] \n" // R = B * Matrix R - "vmul.s16 q15, q8, d3[0] \n" // A = B * Matrix A - "vmul.s16 q4, q9, d0[1] \n" // B += G * Matrix B - "vmul.s16 q5, q9, d1[1] \n" // G += G * Matrix G - "vmul.s16 q6, q9, d2[1] \n" // R += G * Matrix R - "vmul.s16 q7, q9, d3[1] \n" // A += G * Matrix A - "vqadd.s16 q12, q12, q4 \n" // Accumulate B - "vqadd.s16 q13, q13, q5 \n" // Accumulate G - "vqadd.s16 q14, q14, q6 \n" // Accumulate R - "vqadd.s16 q15, q15, q7 \n" // Accumulate A - "vmul.s16 q4, q10, d0[2] \n" // B += R * Matrix B - "vmul.s16 q5, q10, d1[2] \n" // G += R * Matrix G - "vmul.s16 q6, q10, d2[2] \n" // R += R * Matrix R - "vmul.s16 q7, q10, d3[2] \n" // A += R * Matrix A - "vqadd.s16 q12, q12, q4 \n" // Accumulate B - "vqadd.s16 q13, q13, q5 \n" // Accumulate G - "vqadd.s16 q14, q14, q6 \n" // Accumulate R - "vqadd.s16 q15, q15, q7 \n" // Accumulate A - "vmul.s16 q4, q11, d0[3] \n" // B += A * Matrix B - "vmul.s16 q5, q11, d1[3] \n" // G += A * Matrix G - "vmul.s16 q6, q11, d2[3] \n" // R += A * Matrix R - "vmul.s16 q7, q11, d3[3] \n" // A += A * Matrix A - "vqadd.s16 q12, q12, q4 \n" // Accumulate B - "vqadd.s16 q13, q13, q5 \n" // Accumulate G - "vqadd.s16 q14, q14, q6 \n" // Accumulate R - "vqadd.s16 q15, q15, q7 \n" // Accumulate A + "vld4.8 {d16, d18, d20, d22}, [%0]! \n" // load 8 ARGB pixels. + "subs %2, %2, #8 \n" // 8 processed per loop. + "vmovl.u8 q8, d16 \n" // b (0 .. 255) 16 bit + "vmovl.u8 q9, d18 \n" // g + "vmovl.u8 q10, d20 \n" // r + "vmovl.u8 q11, d22 \n" // a + "vmul.s16 q12, q8, d0[0] \n" // B = B * Matrix B + "vmul.s16 q13, q8, d1[0] \n" // G = B * Matrix G + "vmul.s16 q14, q8, d2[0] \n" // R = B * Matrix R + "vmul.s16 q15, q8, d3[0] \n" // A = B * Matrix A + "vmul.s16 q4, q9, d0[1] \n" // B += G * Matrix B + "vmul.s16 q5, q9, d1[1] \n" // G += G * Matrix G + "vmul.s16 q6, q9, d2[1] \n" // R += G * Matrix R + "vmul.s16 q7, q9, d3[1] \n" // A += G * Matrix A + "vqadd.s16 q12, q12, q4 \n" // Accumulate B + "vqadd.s16 q13, q13, q5 \n" // Accumulate G + "vqadd.s16 q14, q14, q6 \n" // Accumulate R + "vqadd.s16 q15, q15, q7 \n" // Accumulate A + "vmul.s16 q4, q10, d0[2] \n" // B += R * Matrix B + "vmul.s16 q5, q10, d1[2] \n" // G += R * Matrix G + "vmul.s16 q6, q10, d2[2] \n" // R += R * Matrix R + "vmul.s16 q7, q10, d3[2] \n" // A += R * Matrix A + "vqadd.s16 q12, q12, q4 \n" // Accumulate B + "vqadd.s16 q13, q13, q5 \n" // Accumulate G + "vqadd.s16 q14, q14, q6 \n" // Accumulate R + "vqadd.s16 q15, q15, q7 \n" // Accumulate A + "vmul.s16 q4, q11, d0[3] \n" // B += A * Matrix B + "vmul.s16 q5, q11, d1[3] \n" // G += A * Matrix G + "vmul.s16 q6, q11, d2[3] \n" // R += A * Matrix R + "vmul.s16 q7, q11, d3[3] \n" // A += A * Matrix A + "vqadd.s16 q12, q12, q4 \n" // Accumulate B + "vqadd.s16 q13, q13, q5 \n" // Accumulate G + "vqadd.s16 q14, q14, q6 \n" // Accumulate R + "vqadd.s16 q15, q15, q7 \n" // Accumulate A "vqshrun.s16 d16, q12, #6 \n" // 16 bit to 8 bit B "vqshrun.s16 d18, q13, #6 \n" // 16 bit to 8 bit G "vqshrun.s16 d20, q14, #6 \n" // 16 bit to 8 bit R "vqshrun.s16 d22, q15, #6 \n" // 16 bit to 8 bit A - "vst4.8 {d16, d18, d20, d22}, [%1]! \n" // store 8 ARGB pixels. - "bgt 1b \n" + "vst4.8 {d16, d18, d20, d22}, [%1]! \n" // store 8 ARGB pixels. + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -2420,19 +2497,19 @@ void ARGBMultiplyRow_NEON(const uint8_t* src_argb0, asm volatile( // 8 pixel loop. "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d1, d3, d5, d7}, [%1]! \n" // load 8 more ARGB - "subs %3, %3, #8 \n" // 8 processed per loop. - "vmull.u8 q0, d0, d1 \n" // multiply B - "vmull.u8 q1, d2, d3 \n" // multiply G - "vmull.u8 q2, d4, d5 \n" // multiply R - "vmull.u8 q3, d6, d7 \n" // multiply A - "vrshrn.u16 d0, q0, #8 \n" // 16 bit to 8 bit B - "vrshrn.u16 d1, q1, #8 \n" // 16 bit to 8 bit G - "vrshrn.u16 d2, q2, #8 \n" // 16 bit to 8 bit R - "vrshrn.u16 d3, q3, #8 \n" // 16 bit to 8 bit A - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. + "vld4.8 {d1, d3, d5, d7}, [%1]! \n" // load 8 more ARGB + "subs %3, %3, #8 \n" // 8 processed per loop. + "vmull.u8 q0, d0, d1 \n" // multiply B + "vmull.u8 q1, d2, d3 \n" // multiply G + "vmull.u8 q2, d4, d5 \n" // multiply R + "vmull.u8 q3, d6, d7 \n" // multiply A + "vrshrn.u16 d0, q0, #8 \n" // 16 bit to 8 bit B + "vrshrn.u16 d1, q1, #8 \n" // 16 bit to 8 bit G + "vrshrn.u16 d2, q2, #8 \n" // 16 bit to 8 bit R + "vrshrn.u16 d3, q3, #8 \n" // 16 bit to 8 bit A + "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. + "bgt 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -2449,13 +2526,13 @@ void ARGBAddRow_NEON(const uint8_t* src_argb0, asm volatile( // 8 pixel loop. "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 more ARGB - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqadd.u8 q0, q0, q2 \n" // add B, G - "vqadd.u8 q1, q1, q3 \n" // add R, A - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. + "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 more ARGB + "subs %3, %3, #8 \n" // 8 processed per loop. + "vqadd.u8 q0, q0, q2 \n" // add B, G + "vqadd.u8 q1, q1, q3 \n" // add R, A + "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. + "bgt 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -2472,13 +2549,13 @@ void ARGBSubtractRow_NEON(const uint8_t* src_argb0, asm volatile( // 8 pixel loop. "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 more ARGB - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqsub.u8 q0, q0, q2 \n" // subtract B, G - "vqsub.u8 q1, q1, q3 \n" // subtract R, A - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. + "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 more ARGB + "subs %3, %3, #8 \n" // 8 processed per loop. + "vqsub.u8 q0, q0, q2 \n" // subtract B, G + "vqsub.u8 q1, q1, q3 \n" // subtract R, A + "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. + "bgt 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -2497,17 +2574,17 @@ void SobelRow_NEON(const uint8_t* src_sobelx, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d3, #255 \n" // alpha + "vmov.u8 d3, #255 \n" // alpha // 8 pixel loop. "1: \n" - "vld1.8 {d0}, [%0]! \n" // load 8 sobelx. - "vld1.8 {d1}, [%1]! \n" // load 8 sobely. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqadd.u8 d0, d0, d1 \n" // add - "vmov.u8 d1, d0 \n" - "vmov.u8 d2, d0 \n" - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" + "vld1.8 {d0}, [%0]! \n" // load 8 sobelx. + "vld1.8 {d1}, [%1]! \n" // load 8 sobely. + "subs %3, %3, #8 \n" // 8 processed per loop. + "vqadd.u8 d0, d0, d1 \n" // add + "vmov.u8 d1, d0 \n" + "vmov.u8 d2, d0 \n" + "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. + "bgt 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_argb), // %2 @@ -2524,12 +2601,12 @@ void SobelToPlaneRow_NEON(const uint8_t* src_sobelx, asm volatile( // 16 pixel loop. "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 16 sobelx. - "vld1.8 {q1}, [%1]! \n" // load 16 sobely. - "subs %3, %3, #16 \n" // 16 processed per loop. - "vqadd.u8 q0, q0, q1 \n" // add - "vst1.8 {q0}, [%2]! \n" // store 16 pixels. - "bgt 1b \n" + "vld1.8 {q0}, [%0]! \n" // load 16 sobelx. + "vld1.8 {q1}, [%1]! \n" // load 16 sobely. + "subs %3, %3, #16 \n" // 16 processed per loop. + "vqadd.u8 q0, q0, q1 \n" // add + "vst1.8 {q0}, [%2]! \n" // store 16 pixels. + "bgt 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_y), // %2 @@ -2548,15 +2625,15 @@ void SobelXYRow_NEON(const uint8_t* src_sobelx, uint8_t* dst_argb, int width) { asm volatile( - "vmov.u8 d3, #255 \n" // alpha + "vmov.u8 d3, #255 \n" // alpha // 8 pixel loop. "1: \n" - "vld1.8 {d2}, [%0]! \n" // load 8 sobelx. - "vld1.8 {d0}, [%1]! \n" // load 8 sobely. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqadd.u8 d1, d0, d2 \n" // add - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" + "vld1.8 {d2}, [%0]! \n" // load 8 sobelx. + "vld1.8 {d0}, [%1]! \n" // load 8 sobely. + "subs %3, %3, #8 \n" // 8 processed per loop. + "vqadd.u8 d1, d0, d2 \n" // add + "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. + "bgt 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_argb), // %2 @@ -2576,23 +2653,23 @@ void SobelXRow_NEON(const uint8_t* src_y0, int width) { asm volatile( "1: \n" - "vld1.8 {d0}, [%0],%5 \n" // top - "vld1.8 {d1}, [%0],%6 \n" - "vsubl.u8 q0, d0, d1 \n" - "vld1.8 {d2}, [%1],%5 \n" // center * 2 - "vld1.8 {d3}, [%1],%6 \n" - "vsubl.u8 q1, d2, d3 \n" - "vadd.s16 q0, q0, q1 \n" - "vadd.s16 q0, q0, q1 \n" - "vld1.8 {d2}, [%2],%5 \n" // bottom - "vld1.8 {d3}, [%2],%6 \n" - "subs %4, %4, #8 \n" // 8 pixels - "vsubl.u8 q1, d2, d3 \n" - "vadd.s16 q0, q0, q1 \n" - "vabs.s16 q0, q0 \n" - "vqmovn.u16 d0, q0 \n" - "vst1.8 {d0}, [%3]! \n" // store 8 sobelx - "bgt 1b \n" + "vld1.8 {d0}, [%0],%5 \n" // top + "vld1.8 {d1}, [%0],%6 \n" + "vsubl.u8 q0, d0, d1 \n" + "vld1.8 {d2}, [%1],%5 \n" // center * 2 + "vld1.8 {d3}, [%1],%6 \n" + "vsubl.u8 q1, d2, d3 \n" + "vadd.s16 q0, q0, q1 \n" + "vadd.s16 q0, q0, q1 \n" + "vld1.8 {d2}, [%2],%5 \n" // bottom + "vld1.8 {d3}, [%2],%6 \n" + "subs %4, %4, #8 \n" // 8 pixels + "vsubl.u8 q1, d2, d3 \n" + "vadd.s16 q0, q0, q1 \n" + "vabs.s16 q0, q0 \n" + "vqmovn.u16 d0, q0 \n" + "vst1.8 {d0}, [%3]! \n" // store 8 sobelx + "bgt 1b \n" : "+r"(src_y0), // %0 "+r"(src_y1), // %1 "+r"(src_y2), // %2 @@ -2614,23 +2691,23 @@ void SobelYRow_NEON(const uint8_t* src_y0, int width) { asm volatile( "1: \n" - "vld1.8 {d0}, [%0],%4 \n" // left - "vld1.8 {d1}, [%1],%4 \n" - "vsubl.u8 q0, d0, d1 \n" - "vld1.8 {d2}, [%0],%4 \n" // center * 2 - "vld1.8 {d3}, [%1],%4 \n" - "vsubl.u8 q1, d2, d3 \n" - "vadd.s16 q0, q0, q1 \n" - "vadd.s16 q0, q0, q1 \n" - "vld1.8 {d2}, [%0],%5 \n" // right - "vld1.8 {d3}, [%1],%5 \n" - "subs %3, %3, #8 \n" // 8 pixels - "vsubl.u8 q1, d2, d3 \n" - "vadd.s16 q0, q0, q1 \n" - "vabs.s16 q0, q0 \n" - "vqmovn.u16 d0, q0 \n" - "vst1.8 {d0}, [%2]! \n" // store 8 sobely - "bgt 1b \n" + "vld1.8 {d0}, [%0],%4 \n" // left + "vld1.8 {d1}, [%1],%4 \n" + "vsubl.u8 q0, d0, d1 \n" + "vld1.8 {d2}, [%0],%4 \n" // center * 2 + "vld1.8 {d3}, [%1],%4 \n" + "vsubl.u8 q1, d2, d3 \n" + "vadd.s16 q0, q0, q1 \n" + "vadd.s16 q0, q0, q1 \n" + "vld1.8 {d2}, [%0],%5 \n" // right + "vld1.8 {d3}, [%1],%5 \n" + "subs %3, %3, #8 \n" // 8 pixels + "vsubl.u8 q1, d2, d3 \n" + "vadd.s16 q0, q0, q1 \n" + "vabs.s16 q0, q0 \n" + "vqmovn.u16 d0, q0 \n" + "vst1.8 {d0}, [%2]! \n" // store 8 sobely + "bgt 1b \n" : "+r"(src_y0), // %0 "+r"(src_y1), // %1 "+r"(dst_sobely), // %2 @@ -2652,18 +2729,18 @@ void HalfFloat1Row_NEON(const uint16_t* src, asm volatile( "1: \n" - "vld1.8 {q1}, [%0]! \n" // load 8 shorts - "subs %2, %2, #8 \n" // 8 pixels per loop - "vmovl.u16 q2, d2 \n" // 8 int's - "vmovl.u16 q3, d3 \n" - "vcvt.f32.u32 q2, q2 \n" // 8 floats - "vcvt.f32.u32 q3, q3 \n" - "vmul.f32 q2, q2, %y3 \n" // adjust exponent - "vmul.f32 q3, q3, %y3 \n" - "vqshrn.u32 d2, q2, #13 \n" // isolate halffloat - "vqshrn.u32 d3, q3, #13 \n" - "vst1.8 {q1}, [%1]! \n" - "bgt 1b \n" + "vld1.8 {q1}, [%0]! \n" // load 8 shorts + "subs %2, %2, #8 \n" // 8 pixels per loop + "vmovl.u16 q2, d2 \n" // 8 int's + "vmovl.u16 q3, d3 \n" + "vcvt.f32.u32 q2, q2 \n" // 8 floats + "vcvt.f32.u32 q3, q3 \n" + "vmul.f32 q2, q2, %y3 \n" // adjust exponent + "vmul.f32 q3, q3, %y3 \n" + "vqshrn.u32 d2, q2, #13 \n" // isolate halffloat + "vqshrn.u32 d3, q3, #13 \n" + "vst1.8 {q1}, [%1]! \n" + "bgt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -2678,18 +2755,18 @@ void HalfFloatRow_NEON(const uint16_t* src, asm volatile( "1: \n" - "vld1.8 {q1}, [%0]! \n" // load 8 shorts - "subs %2, %2, #8 \n" // 8 pixels per loop - "vmovl.u16 q2, d2 \n" // 8 int's - "vmovl.u16 q3, d3 \n" - "vcvt.f32.u32 q2, q2 \n" // 8 floats - "vcvt.f32.u32 q3, q3 \n" - "vmul.f32 q2, q2, %y3 \n" // adjust exponent - "vmul.f32 q3, q3, %y3 \n" - "vqshrn.u32 d2, q2, #13 \n" // isolate halffloat - "vqshrn.u32 d3, q3, #13 \n" - "vst1.8 {q1}, [%1]! \n" - "bgt 1b \n" + "vld1.8 {q1}, [%0]! \n" // load 8 shorts + "subs %2, %2, #8 \n" // 8 pixels per loop + "vmovl.u16 q2, d2 \n" // 8 int's + "vmovl.u16 q3, d3 \n" + "vcvt.f32.u32 q2, q2 \n" // 8 floats + "vcvt.f32.u32 q3, q3 \n" + "vmul.f32 q2, q2, %y3 \n" // adjust exponent + "vmul.f32 q3, q3, %y3 \n" + "vqshrn.u32 d2, q2, #13 \n" // isolate halffloat + "vqshrn.u32 d3, q3, #13 \n" + "vst1.8 {q1}, [%1]! \n" + "bgt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -2704,17 +2781,17 @@ void ByteToFloatRow_NEON(const uint8_t* src, asm volatile( "1: \n" - "vld1.8 {d2}, [%0]! \n" // load 8 bytes - "subs %2, %2, #8 \n" // 8 pixels per loop - "vmovl.u8 q1, d2 \n" // 8 shorts - "vmovl.u16 q2, d2 \n" // 8 ints - "vmovl.u16 q3, d3 \n" - "vcvt.f32.u32 q2, q2 \n" // 8 floats - "vcvt.f32.u32 q3, q3 \n" - "vmul.f32 q2, q2, %y3 \n" // scale - "vmul.f32 q3, q3, %y3 \n" - "vst1.8 {q2, q3}, [%1]! \n" // store 8 floats - "bgt 1b \n" + "vld1.8 {d2}, [%0]! \n" // load 8 bytes + "subs %2, %2, #8 \n" // 8 pixels per loop + "vmovl.u8 q1, d2 \n" // 8 shorts + "vmovl.u16 q2, d2 \n" // 8 ints + "vmovl.u16 q3, d3 \n" + "vcvt.f32.u32 q2, q2 \n" // 8 floats + "vcvt.f32.u32 q3, q3 \n" + "vmul.f32 q2, q2, %y3 \n" // scale + "vmul.f32 q3, q3, %y3 \n" + "vst1.8 {q2, q3}, [%1]! \n" // store 8 floats + "bgt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -2731,26 +2808,26 @@ void GaussCol_NEON(const uint16_t* src0, uint32_t* dst, int width) { asm volatile( - "vmov.u16 d6, #4 \n" // constant 4 - "vmov.u16 d7, #6 \n" // constant 6 + "vmov.u16 d6, #4 \n" // constant 4 + "vmov.u16 d7, #6 \n" // constant 6 "1: \n" - "vld1.16 {q1}, [%0]! \n" // load 8 samples, 5 rows - "vld1.16 {q2}, [%4]! \n" - "vaddl.u16 q0, d2, d4 \n" // * 1 - "vaddl.u16 q1, d3, d5 \n" // * 1 - "vld1.16 {q2}, [%1]! \n" - "vmlal.u16 q0, d4, d6 \n" // * 4 - "vmlal.u16 q1, d5, d6 \n" // * 4 - "vld1.16 {q2}, [%2]! \n" - "vmlal.u16 q0, d4, d7 \n" // * 6 - "vmlal.u16 q1, d5, d7 \n" // * 6 - "vld1.16 {q2}, [%3]! \n" - "vmlal.u16 q0, d4, d6 \n" // * 4 - "vmlal.u16 q1, d5, d6 \n" // * 4 - "subs %6, %6, #8 \n" // 8 processed per loop - "vst1.32 {q0, q1}, [%5]! \n" // store 8 samples - "bgt 1b \n" + "vld1.16 {q1}, [%0]! \n" // load 8 samples, 5 rows + "vld1.16 {q2}, [%4]! \n" + "vaddl.u16 q0, d2, d4 \n" // * 1 + "vaddl.u16 q1, d3, d5 \n" // * 1 + "vld1.16 {q2}, [%1]! \n" + "vmlal.u16 q0, d4, d6 \n" // * 4 + "vmlal.u16 q1, d5, d6 \n" // * 4 + "vld1.16 {q2}, [%2]! \n" + "vmlal.u16 q0, d4, d7 \n" // * 6 + "vmlal.u16 q1, d5, d7 \n" // * 6 + "vld1.16 {q2}, [%3]! \n" + "vmlal.u16 q0, d4, d6 \n" // * 4 + "vmlal.u16 q1, d5, d6 \n" // * 4 + "subs %6, %6, #8 \n" // 8 processed per loop + "vst1.32 {q0, q1}, [%5]! \n" // store 8 samples + "bgt 1b \n" : "+r"(src0), // %0 "+r"(src1), // %1 "+r"(src2), // %2 @@ -2768,8 +2845,8 @@ void GaussRow_NEON(const uint32_t* src, uint16_t* dst, int width) { const uint32_t* src2 = src + 2; const uint32_t* src3 = src + 3; asm volatile( - "vmov.u32 q10, #4 \n" // constant 4 - "vmov.u32 q11, #6 \n" // constant 6 + "vmov.u32 q10, #4 \n" // constant 4 + "vmov.u32 q11, #6 \n" // constant 6 "1: \n" "vld1.32 {q0, q1}, [%0]! \n" // load 12 source samples @@ -2807,16 +2884,16 @@ void NV21ToYUV24Row_NEON(const uint8_t* src_y, int width) { asm volatile( "1: \n" - "vld1.8 {q2}, [%0]! \n" // load 16 Y values - "vld2.8 {d0, d2}, [%1]! \n" // load 8 VU values - "vmov d1, d0 \n" - "vzip.u8 d0, d1 \n" // VV - "vmov d3, d2 \n" - "vzip.u8 d2, d3 \n" // UU - "subs %3, %3, #16 \n" // 16 pixels per loop - "vst3.8 {d0, d2, d4}, [%2]! \n" // store 16 YUV pixels - "vst3.8 {d1, d3, d5}, [%2]! \n" - "bgt 1b \n" + "vld1.8 {q2}, [%0]! \n" // load 16 Y values + "vld2.8 {d0, d2}, [%1]! \n" // load 8 VU values + "vmov d1, d0 \n" + "vzip.u8 d0, d1 \n" // VV + "vmov d3, d2 \n" + "vzip.u8 d2, d3 \n" // UU + "subs %3, %3, #16 \n" // 16 pixels per loop + "vst3.8 {d0, d2, d4}, [%2]! \n" // store 16 YUV pixels + "vst3.8 {d1, d3, d5}, [%2]! \n" + "bgt 1b \n" : "+r"(src_y), // %0 "+r"(src_vu), // %1 "+r"(dst_yuv24), // %2 @@ -2830,24 +2907,24 @@ void AYUVToUVRow_NEON(const uint8_t* src_ayuv, uint8_t* dst_uv, int width) { asm volatile( - "add %1, %0, %1 \n" // src_stride + src_AYUV + "add %1, %0, %1 \n" // src_stride + src_AYUV "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 AYUV pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 AYUV + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 AYUV pixels. + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 AYUV // pixels. - "vpaddl.u8 q0, q0 \n" // V 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // U 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more AYUV + "vpaddl.u8 q0, q0 \n" // V 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // U 16 bytes -> 8 shorts. + "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more AYUV // pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 AYUV + "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 AYUV // pixels. - "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. "vqrshrun.s16 d1, q0, #2 \n" // 2x2 average "vqrshrun.s16 d0, q1, #2 \n" - "subs %3, %3, #16 \n" // 16 processed per loop. - "vst2.8 {d0, d1}, [%2]! \n" // store 8 pixels UV. - "bgt 1b \n" + "subs %3, %3, #16 \n" // 16 processed per loop. + "vst2.8 {d0, d1}, [%2]! \n" // store 8 pixels UV. + "bgt 1b \n" : "+r"(src_ayuv), // %0 "+r"(src_stride_ayuv), // %1 "+r"(dst_uv), // %2 @@ -2861,24 +2938,24 @@ void AYUVToVURow_NEON(const uint8_t* src_ayuv, uint8_t* dst_vu, int width) { asm volatile( - "add %1, %0, %1 \n" // src_stride + src_AYUV + "add %1, %0, %1 \n" // src_stride + src_AYUV "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 AYUV pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 AYUV + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 AYUV pixels. + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 AYUV // pixels. - "vpaddl.u8 q0, q0 \n" // V 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // U 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more AYUV + "vpaddl.u8 q0, q0 \n" // V 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // U 16 bytes -> 8 shorts. + "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more AYUV // pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 AYUV + "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 AYUV // pixels. - "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. "vqrshrun.s16 d0, q0, #2 \n" // 2x2 average "vqrshrun.s16 d1, q1, #2 \n" - "subs %3, %3, #16 \n" // 16 processed per loop. - "vst2.8 {d0, d1}, [%2]! \n" // store 8 pixels VU. - "bgt 1b \n" + "subs %3, %3, #16 \n" // 16 processed per loop. + "vst2.8 {d0, d1}, [%2]! \n" // store 8 pixels VU. + "bgt 1b \n" : "+r"(src_ayuv), // %0 "+r"(src_stride_ayuv), // %1 "+r"(dst_vu), // %2 @@ -2892,11 +2969,11 @@ void AYUVToVURow_NEON(const uint8_t* src_ayuv, void AYUVToYRow_NEON(const uint8_t* src_ayuv, uint8_t* dst_y, int width) { asm volatile( "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 AYUV pixels - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 AYUV pixels - "subs %2, %2, #16 \n" // 16 processed per loop - "vst1.8 {q2}, [%1]! \n" // store 16 Y's. - "bgt 1b \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 AYUV pixels + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 AYUV pixels + "subs %2, %2, #16 \n" // 16 processed per loop + "vst1.8 {q2}, [%1]! \n" // store 16 Y's. + "bgt 1b \n" : "+r"(src_ayuv), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2908,12 +2985,12 @@ void AYUVToYRow_NEON(const uint8_t* src_ayuv, uint8_t* dst_y, int width) { void SwapUVRow_NEON(const uint8_t* src_uv, uint8_t* dst_vu, int width) { asm volatile( "1: \n" - "vld2.8 {d0, d2}, [%0]! \n" // load 16 UV values - "vld2.8 {d1, d3}, [%0]! \n" - "vorr.u8 q2, q0, q0 \n" // move U after V - "subs %2, %2, #16 \n" // 16 pixels per loop - "vst2.8 {q1, q2}, [%1]! \n" // store 16 VU pixels - "bgt 1b \n" + "vld2.8 {d0, d2}, [%0]! \n" // load 16 UV values + "vld2.8 {d1, d3}, [%0]! \n" + "vorr.u8 q2, q0, q0 \n" // move U after V + "subs %2, %2, #16 \n" // 16 pixels per loop + "vst2.8 {q1, q2}, [%1]! \n" // store 16 VU pixels + "bgt 1b \n" : "+r"(src_uv), // %0 "+r"(dst_vu), // %1 "+r"(width) // %2 @@ -2921,6 +2998,39 @@ void SwapUVRow_NEON(const uint8_t* src_uv, uint8_t* dst_vu, int width) { : "cc", "memory", "q0", "q1", "q2"); } +void HalfMergeUVRow_NEON(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width) { + const uint8_t* src_u_1 = src_u + src_stride_u; + const uint8_t* src_v_1 = src_v + src_stride_v; + asm volatile( + "1: \n" + "vld1.8 {q0}, [%0]! \n" // load 16 U values + "vld1.8 {q1}, [%2]! \n" // load 16 V values + "vld1.8 {q2}, [%1]! \n" + "vld1.8 {q3}, [%3]! \n" + "vpaddl.u8 q0, q0 \n" // half size + "vpaddl.u8 q1, q1 \n" + "vpadal.u8 q0, q2 \n" + "vpadal.u8 q1, q3 \n" + "vqrshrn.u16 d0, q0, #2 \n" + "vqrshrn.u16 d1, q1, #2 \n" + "subs %5, %5, #16 \n" // 16 src pixels per loop + "vst2.8 {d0, d1}, [%4]! \n" // store 8 UV pixels + "bgt 1b \n" + : "+r"(src_u), // %0 + "+r"(src_u_1), // %1 + "+r"(src_v), // %2 + "+r"(src_v_1), // %3 + "+r"(dst_uv), // %4 + "+r"(width) // %5 + : + : "cc", "memory", "q0", "q1", "q2", "q3"); +} + #endif // !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__).. #ifdef __cplusplus diff --git a/TMessagesProj/jni/third_party/libyuv/source/row_neon64.cc b/TMessagesProj/jni/third_party/libyuv/source/row_neon64.cc index 866e7bfc6..d5258a3ae 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/row_neon64.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/row_neon64.cc @@ -68,13 +68,13 @@ extern "C" { "uzp2 v3.8b, v2.8b, v2.8b \n" \ "ins v1.s[1], v3.s[0] \n" -#define YUVTORGB_SETUP \ - "ld1r {v24.8h}, [%[kUVBiasBGR]], #2 \n" \ - "ld1r {v25.8h}, [%[kUVBiasBGR]], #2 \n" \ - "ld1r {v26.8h}, [%[kUVBiasBGR]] \n" \ - "ld1r {v31.4s}, [%[kYToRgb]] \n" \ - "ld2 {v27.8h, v28.8h}, [%[kUVToRB]] \n" \ - "ld2 {v29.8h, v30.8h}, [%[kUVToG]] \n" +#define YUVTORGB_SETUP \ + "ld3r {v24.8h, v25.8h, v26.8h}, [%[kUVBiasBGR]] \n" \ + "ld1r {v31.4s}, [%[kYToRgb]] \n" \ + "ld2 {v27.8h, v28.8h}, [%[kUVToRB]] \n" \ + "ld2 {v29.8h, v30.8h}, [%[kUVToG]] \n" + +// clang-format off #define YUVTORGB(vR, vG, vB) \ "uxtl v0.8h, v0.8b \n" /* Extract Y */ \ @@ -89,29 +89,23 @@ extern "C" { "mov v2.d[0], v1.d[1] \n" /* Extract V */ \ "uxtl v2.8h, v2.8b \n" \ "uxtl v1.8h, v1.8b \n" /* Extract U */ \ - "mul v3.8h, v1.8h, v27.8h \n" \ - "mul v5.8h, v1.8h, v29.8h \n" \ - "mul v6.8h, v2.8h, v30.8h \n" \ - "mul v7.8h, v2.8h, v28.8h \n" \ + "mul v3.8h, v27.8h, v1.8h \n" \ + "mul v5.8h, v29.8h, v1.8h \n" \ + "mul v6.8h, v30.8h, v2.8h \n" \ + "mul v7.8h, v28.8h, v2.8h \n" \ "sqadd v6.8h, v6.8h, v5.8h \n" \ - "sqadd " #vB \ - ".8h, v24.8h, v0.8h \n" /* B */ \ - "sqadd " #vG \ - ".8h, v25.8h, v0.8h \n" /* G */ \ - "sqadd " #vR \ - ".8h, v26.8h, v0.8h \n" /* R */ \ - "sqadd " #vB ".8h, " #vB \ - ".8h, v3.8h \n" /* B */ \ - "sqsub " #vG ".8h, " #vG \ - ".8h, v6.8h \n" /* G */ \ - "sqadd " #vR ".8h, " #vR \ - ".8h, v7.8h \n" /* R */ \ - "sqshrun " #vB ".8b, " #vB \ - ".8h, #6 \n" /* B */ \ - "sqshrun " #vG ".8b, " #vG \ - ".8h, #6 \n" /* G */ \ + "sqadd " #vB ".8h, v24.8h, v0.8h \n" /* B */ \ + "sqadd " #vG ".8h, v25.8h, v0.8h \n" /* G */ \ + "sqadd " #vR ".8h, v26.8h, v0.8h \n" /* R */ \ + "sqadd " #vB ".8h, " #vB ".8h, v3.8h \n" /* B */ \ + "sqsub " #vG ".8h, " #vG ".8h, v6.8h \n" /* G */ \ + "sqadd " #vR ".8h, " #vR ".8h, v7.8h \n" /* R */ \ + "sqshrun " #vB ".8b, " #vB ".8h, #6 \n" /* B */ \ + "sqshrun " #vG ".8b, " #vG ".8h, #6 \n" /* G */ \ "sqshrun " #vR ".8b, " #vR ".8h, #6 \n" /* R */ +// clang-format on + void I444ToARGBRow_NEON(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -120,13 +114,16 @@ void I444ToARGBRow_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "movi v23.8b, #255 \n" /* A */ - "1: \n" + "movi v23.8b, #255 \n" /* A */ + "1: \n" READYUV444 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "subs %w4, %w4, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%1, 448] \n" + "prfm pldl1keep, [%2, 448] \n" + "subs %w4, %w4, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -149,13 +146,17 @@ void I422ToARGBRow_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "movi v23.8b, #255 \n" /* A */ - "1: \n" + "movi v23.8b, #255 \n" /* A */ + + "1: \n" READYUV422 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "subs %w4, %w4, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%1, 128] \n" + "prfm pldl1keep, [%2, 128] \n" + "subs %w4, %w4, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -179,13 +180,17 @@ void I422AlphaToARGBRow_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "1: \n" + "1: \n" READYUV422 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "ld1 {v23.8b}, [%3], #8 \n" - "subs %w5, %w5, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%4], #32 \n" - "b.gt 1b \n" + "ld1 {v23.8b}, [%3], #8 \n" + "prfm pldl1keep, [%1, 128] \n" + "prfm pldl1keep, [%2, 128] \n" + "prfm pldl1keep, [%3, 448] \n" + "subs %w5, %w5, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%4], #32 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -209,13 +214,16 @@ void I422ToRGBARow_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "movi v20.8b, #255 \n" /* A */ - "1: \n" + "movi v20.8b, #255 \n" /* A */ + "1: \n" READYUV422 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v23, v22, v21) - "subs %w4, %w4, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%1, 128] \n" + "prfm pldl1keep, [%2, 128] \n" + "subs %w4, %w4, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -238,12 +246,15 @@ void I422ToRGB24Row_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "1: \n" + "1: \n" READYUV422 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "subs %w4, %w4, #8 \n" - "st3 {v20.8b,v21.8b,v22.8b}, [%3], #24 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%1, 128] \n" + "prfm pldl1keep, [%2, 128] \n" + "subs %w4, %w4, #8 \n" + "st3 {v20.8b,v21.8b,v22.8b}, [%3], #24 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -265,6 +276,8 @@ void I422ToRGB24Row_NEON(const uint8_t* src_y, "sri v0.8h, v21.8h, #5 \n" /* RG */ \ "sri v0.8h, v20.8h, #11 \n" /* RGB */ +// clang-format off + void I422ToRGB565Row_NEON(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -272,13 +285,17 @@ void I422ToRGB565Row_NEON(const uint8_t* src_y, const struct YuvConstants* yuvconstants, int width) { asm volatile( - YUVTORGB_SETUP - "1: \n" READYUV422 YUVTORGB( - v22, v21, - v20) "subs %w4, %w4, #8 \n" ARGBTORGB565 - "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels - // RGB565. - "b.gt 1b \n" + YUVTORGB_SETUP + "1: \n" + READYUV422 + YUVTORGB(v22, v21, v20) + "prfm pldl1keep, [%0, 448] \n" + "subs %w4, %w4, #8 \n" + ARGBTORGB565 + "prfm pldl1keep, [%1, 128] \n" + "prfm pldl1keep, [%2, 128] \n" + "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels RGB565. + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -308,14 +325,18 @@ void I422ToARGB1555Row_NEON(const uint8_t* src_y, const struct YuvConstants* yuvconstants, int width) { asm volatile( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" READYUV422 YUVTORGB( - v22, v21, - v20) "subs %w4, %w4, #8 \n" ARGBTOARGB1555 - "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels - // RGB565. - "b.gt 1b \n" + YUVTORGB_SETUP + "movi v23.8b, #255 \n" + "1: \n" + READYUV422 + YUVTORGB(v22, v21, v20) + "prfm pldl1keep, [%0, 448] \n" + "subs %w4, %w4, #8 \n" + ARGBTOARGB1555 + "prfm pldl1keep, [%1, 128] \n" + "prfm pldl1keep, [%2, 128] \n" + "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels RGB565. + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -328,6 +349,7 @@ void I422ToARGB1555Row_NEON(const uint8_t* src_y, : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"); } +// clang-format on #define ARGBTOARGB4444 \ /* Input v20.8b<=B, v21.8b<=G, v22.8b<=R, v23.8b<=A, v4.8b<=0x0f */ \ @@ -347,15 +369,18 @@ void I422ToARGB4444Row_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "movi v4.16b, #0x0f \n" // bits to clear with vbic. - "1: \n" + "movi v4.16b, #0x0f \n" // bits to clear with vbic. + "1: \n" READYUV422 YUVTORGB(v22, v21, v20) - "subs %w4, %w4, #8 \n" - "movi v23.8b, #255 \n" + "prfm pldl1keep, [%0, 448] \n" + "subs %w4, %w4, #8 \n" + "movi v23.8b, #255 \n" ARGBTOARGB4444 - "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels ARGB4444. - "b.gt 1b \n" + "prfm pldl1keep, [%1, 128] \n" + "prfm pldl1keep, [%2, 128] \n" + "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels ARGB4444. + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -370,23 +395,27 @@ void I422ToARGB4444Row_NEON(const uint8_t* src_y, ); } -void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { +void I400ToARGBRow_NEON(const uint8_t* src_y, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { asm volatile ( YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" + "movi v23.8b, #255 \n" + "1: \n" READYUV400 YUVTORGB(v22, v21, v20) - "subs %w2, %w2, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 - : [kUVToRB]"r"(&kYuvI601Constants.kUVToRB), - [kUVToG]"r"(&kYuvI601Constants.kUVToG), - [kUVBiasBGR]"r"(&kYuvI601Constants.kUVBiasBGR), - [kYToRgb]"r"(&kYuvI601Constants.kYToRgb) + : [kUVToRB]"r"(&yuvconstants->kUVToRB), + [kUVToG]"r"(&yuvconstants->kUVToG), + [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), + [kYToRgb]"r"(&yuvconstants->kYToRgb) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" ); @@ -394,14 +423,15 @@ void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { void J400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { asm volatile( - "movi v23.8b, #255 \n" + "movi v23.8b, #255 \n" "1: \n" - "ld1 {v20.8b}, [%0], #8 \n" - "orr v21.8b, v20.8b, v20.8b \n" - "orr v22.8b, v20.8b, v20.8b \n" - "subs %w2, %w2, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" - "b.gt 1b \n" + "ld1 {v20.8b}, [%0], #8 \n" + "prfm pldl1keep, [%0, 448] \n" + "orr v21.8b, v20.8b, v20.8b \n" + "orr v22.8b, v20.8b, v20.8b \n" + "subs %w2, %w2, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -416,13 +446,15 @@ void NV12ToARGBRow_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" + "movi v23.8b, #255 \n" + "1: \n" READNV12 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "subs %w3, %w3, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%2], #32 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%1, 256] \n" + "subs %w3, %w3, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%2], #32 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_uv), // %1 "+r"(dst_argb), // %2 @@ -443,13 +475,15 @@ void NV21ToARGBRow_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" + "movi v23.8b, #255 \n" + "1: \n" READNV21 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "subs %w3, %w3, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%2], #32 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%1, 256] \n" + "subs %w3, %w3, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%2], #32 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_vu), // %1 "+r"(dst_argb), // %2 @@ -470,12 +504,14 @@ void NV12ToRGB24Row_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "1: \n" + "1: \n" READNV12 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "subs %w3, %w3, #8 \n" - "st3 {v20.8b,v21.8b,v22.8b}, [%2], #24 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%1, 256] \n" + "subs %w3, %w3, #8 \n" + "st3 {v20.8b,v21.8b,v22.8b}, [%2], #24 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_uv), // %1 "+r"(dst_rgb24), // %2 @@ -496,12 +532,14 @@ void NV21ToRGB24Row_NEON(const uint8_t* src_y, int width) { asm volatile ( YUVTORGB_SETUP - "1: \n" + "1: \n" READNV21 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "subs %w3, %w3, #8 \n" - "st3 {v20.8b,v21.8b,v22.8b}, [%2], #24 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%1, 256] \n" + "subs %w3, %w3, #8 \n" + "st3 {v20.8b,v21.8b,v22.8b}, [%2], #24 \n" + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_vu), // %1 "+r"(dst_rgb24), // %2 @@ -521,13 +559,13 @@ void NV12ToRGB565Row_NEON(const uint8_t* src_y, const struct YuvConstants* yuvconstants, int width) { asm volatile( - YUVTORGB_SETUP - "1: \n" READNV12 YUVTORGB( - v22, v21, - v20) "subs %w3, %w3, #8 \n" ARGBTORGB565 - "st1 {v0.8h}, [%2], 16 \n" // store 8 pixels - // RGB565. - "b.gt 1b \n" + YUVTORGB_SETUP "1: \n" READNV12 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB( + v22, v21, v20) ARGBTORGB565 + "prfm pldl1keep, [%1, 256] \n" + "subs %w3, %w3, #8 \n" + "st1 {v0.8h}, [%2], 16 \n" // store 8 pixels + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_uv), // %1 "+r"(dst_rgb565), // %2 @@ -546,13 +584,14 @@ void YUY2ToARGBRow_NEON(const uint8_t* src_yuy2, int width) { asm volatile ( YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" + "movi v23.8b, #255 \n" + "1: \n" READYUY2 + "prfm pldl1keep, [%0, 448] \n" YUVTORGB(v22, v21, v20) - "subs %w2, %w2, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" - "b.gt 1b \n" + "subs %w2, %w2, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" + "b.gt 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -571,13 +610,14 @@ void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, int width) { asm volatile ( YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" + "movi v23.8b, #255 \n" + "1: \n" READUYVY YUVTORGB(v22, v21, v20) - "subs %w2, %w2, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], 32 \n" - "b.gt 1b \n" + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" + "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], 32 \n" + "b.gt 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -597,11 +637,12 @@ void SplitUVRow_NEON(const uint8_t* src_uv, int width) { asm volatile( "1: \n" - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pairs of UV - "subs %w3, %w3, #16 \n" // 16 processed per loop - "st1 {v0.16b}, [%1], #16 \n" // store U - "st1 {v1.16b}, [%2], #16 \n" // store V - "b.gt 1b \n" + "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pairs of UV + "prfm pldl1keep, [%0, 448] \n" + "subs %w3, %w3, #16 \n" // 16 processed per loop + "st1 {v0.16b}, [%1], #16 \n" // store U + "st1 {v1.16b}, [%2], #16 \n" // store V + "b.gt 1b \n" : "+r"(src_uv), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -618,11 +659,13 @@ void MergeUVRow_NEON(const uint8_t* src_u, int width) { asm volatile( "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load U - "ld1 {v1.16b}, [%1], #16 \n" // load V - "subs %w3, %w3, #16 \n" // 16 processed per loop - "st2 {v0.16b,v1.16b}, [%2], #32 \n" // store 16 pairs of UV - "b.gt 1b \n" + "ld1 {v0.16b}, [%0], #16 \n" // load U + "ld1 {v1.16b}, [%1], #16 \n" // load V + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #16 \n" // 16 processed per loop + "st2 {v0.16b,v1.16b}, [%2], #32 \n" // store 16 pairs of UV + "b.gt 1b \n" : "+r"(src_u), // %0 "+r"(src_v), // %1 "+r"(dst_uv), // %2 @@ -640,12 +683,13 @@ void SplitRGBRow_NEON(const uint8_t* src_rgb, int width) { asm volatile( "1: \n" - "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \n" // load 16 RGB - "subs %w4, %w4, #16 \n" // 16 processed per loop - "st1 {v0.16b}, [%1], #16 \n" // store R - "st1 {v1.16b}, [%2], #16 \n" // store G - "st1 {v2.16b}, [%3], #16 \n" // store B - "b.gt 1b \n" + "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \n" // load 16 RGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w4, %w4, #16 \n" // 16 processed per loop + "st1 {v0.16b}, [%1], #16 \n" // store R + "st1 {v1.16b}, [%2], #16 \n" // store G + "st1 {v2.16b}, [%3], #16 \n" // store B + "b.gt 1b \n" : "+r"(src_rgb), // %0 "+r"(dst_r), // %1 "+r"(dst_g), // %2 @@ -664,12 +708,16 @@ void MergeRGBRow_NEON(const uint8_t* src_r, int width) { asm volatile( "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load R - "ld1 {v1.16b}, [%1], #16 \n" // load G - "ld1 {v2.16b}, [%2], #16 \n" // load B - "subs %w4, %w4, #16 \n" // 16 processed per loop - "st3 {v0.16b,v1.16b,v2.16b}, [%3], #48 \n" // store 16 RGB - "b.gt 1b \n" + "ld1 {v0.16b}, [%0], #16 \n" // load R + "ld1 {v1.16b}, [%1], #16 \n" // load G + "ld1 {v2.16b}, [%2], #16 \n" // load B + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "prfm pldl1keep, [%2, 448] \n" + "subs %w4, %w4, #16 \n" // 16 processed per loop + "st3 {v0.16b,v1.16b,v2.16b}, [%3], #48 \n" // store 16 RGB + "prfm pldl1keep, [%0, 448] \n" + "b.gt 1b \n" : "+r"(src_r), // %0 "+r"(src_g), // %1 "+r"(src_b), // %2 @@ -684,10 +732,11 @@ void MergeRGBRow_NEON(const uint8_t* src_r, void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width) { asm volatile( "1: \n" - "ldp q0, q1, [%0], #32 \n" - "subs %w2, %w2, #32 \n" // 32 processed per loop - "stp q0, q1, [%1], #32 \n" - "b.gt 1b \n" + "ldp q0, q1, [%0], #32 \n" + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #32 \n" // 32 processed per loop + "stp q0, q1, [%1], #32 \n" + "b.gt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 // Output registers @@ -699,11 +748,11 @@ void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width) { // SetRow writes 'width' bytes using an 8 bit value repeated. void SetRow_NEON(uint8_t* dst, uint8_t v8, int width) { asm volatile( - "dup v0.16b, %w2 \n" // duplicate 16 bytes + "dup v0.16b, %w2 \n" // duplicate 16 bytes "1: \n" - "subs %w1, %w1, #16 \n" // 16 bytes per loop - "st1 {v0.16b}, [%0], #16 \n" // store - "b.gt 1b \n" + "subs %w1, %w1, #16 \n" // 16 bytes per loop + "st1 {v0.16b}, [%0], #16 \n" // store + "b.gt 1b \n" : "+r"(dst), // %0 "+r"(width) // %1 : "r"(v8) // %2 @@ -712,89 +761,157 @@ void SetRow_NEON(uint8_t* dst, uint8_t v8, int width) { void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width) { asm volatile( - "dup v0.4s, %w2 \n" // duplicate 4 ints + "dup v0.4s, %w2 \n" // duplicate 4 ints "1: \n" - "subs %w1, %w1, #4 \n" // 4 ints per loop - "st1 {v0.16b}, [%0], #16 \n" // store - "b.gt 1b \n" + "subs %w1, %w1, #4 \n" // 4 ints per loop + "st1 {v0.16b}, [%0], #16 \n" // store + "b.gt 1b \n" : "+r"(dst), // %0 "+r"(width) // %1 : "r"(v32) // %2 : "cc", "memory", "v0"); } +// Shuffle table for reversing the bytes. +static const uvec8 kShuffleMirror = {15u, 14u, 13u, 12u, 11u, 10u, 9u, 8u, + 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; + void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { asm volatile( // Start at end of source row. - "add %0, %0, %w2, sxtw \n" - "sub %0, %0, #16 \n" + "ld1 {v3.16b}, [%3] \n" // shuffler + "add %0, %0, %w2, sxtw \n" + "sub %0, %0, #32 \n" "1: \n" - "ld1 {v0.16b}, [%0], %3 \n" // src -= 16 - "subs %w2, %w2, #16 \n" // 16 pixels per loop. - "rev64 v0.16b, v0.16b \n" - "st1 {v0.D}[1], [%1], #8 \n" // dst += 16 - "st1 {v0.D}[0], [%1], #8 \n" - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "r"((ptrdiff_t)-16) // %3 - : "cc", "memory", "v0"); + "ldr q2, [%0, 16] \n" + "ldr q1, [%0], -32 \n" // src -= 32 + "subs %w2, %w2, #32 \n" // 32 pixels per loop. + "tbl v0.16b, {v2.16b}, v3.16b \n" + "tbl v1.16b, {v1.16b}, v3.16b \n" + "st1 {v0.16b, v1.16b}, [%1], #32 \n" // store 32 pixels + "b.gt 1b \n" + : "+r"(src), // %0 + "+r"(dst), // %1 + "+r"(width) // %2 + : "r"(&kShuffleMirror) // %3 + : "cc", "memory", "v0", "v1", "v2", "v3"); } -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +// Shuffle table for reversing the UV. +static const uvec8 kShuffleMirrorUV = {14u, 15u, 12u, 13u, 10u, 11u, 8u, 9u, + 6u, 7u, 4u, 5u, 2u, 3u, 0u, 1u}; + +void MirrorUVRow_NEON(const uint8_t* src_uv, uint8_t* dst_uv, int width) { asm volatile( // Start at end of source row. - "add %0, %0, %w3, sxtw #1 \n" - "sub %0, %0, #16 \n" + "ld1 {v4.16b}, [%3] \n" // shuffler + "add %0, %0, %w2, sxtw #1 \n" + "sub %0, %0, #32 \n" "1: \n" - "ld2 {v0.8b, v1.8b}, [%0], %4 \n" // src -= 16 - "subs %w3, %w3, #8 \n" // 8 pixels per loop. - "rev64 v0.8b, v0.8b \n" - "rev64 v1.8b, v1.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // dst += 8 - "st1 {v1.8b}, [%2], #8 \n" - "b.gt 1b \n" - : "+r"(src_uv), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : "r"((ptrdiff_t)-16) // %4 - : "cc", "memory", "v0", "v1"); + "ldr q1, [%0, 16] \n" + "ldr q0, [%0], -32 \n" // src -= 32 + "subs %w2, %w2, #16 \n" // 16 pixels per loop. + "tbl v2.16b, {v1.16b}, v4.16b \n" + "tbl v3.16b, {v0.16b}, v4.16b \n" + "st1 {v2.16b, v3.16b}, [%1], #32 \n" // dst += 32 + "b.gt 1b \n" + : "+r"(src_uv), // %0 + "+r"(dst_uv), // %1 + "+r"(width) // %2 + : "r"(&kShuffleMirrorUV) // %3 + : "cc", "memory", "v0", "v1", "v2", "v3", "v4"); } -void ARGBMirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { +void MirrorSplitUVRow_NEON(const uint8_t* src_uv, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { asm volatile( // Start at end of source row. - "add %0, %0, %w2, sxtw #2 \n" - "sub %0, %0, #16 \n" + "ld1 {v4.16b}, [%4] \n" // shuffler + "add %0, %0, %w3, sxtw #1 \n" + "sub %0, %0, #32 \n" "1: \n" - "ld1 {v0.16b}, [%0], %3 \n" // src -= 16 - "subs %w2, %w2, #4 \n" // 4 pixels per loop. - "rev64 v0.4s, v0.4s \n" - "st1 {v0.D}[1], [%1], #8 \n" // dst += 16 - "st1 {v0.D}[0], [%1], #8 \n" - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "r"((ptrdiff_t)-16) // %3 - : "cc", "memory", "v0"); + "ldr q1, [%0, 16] \n" + "ldr q0, [%0], -32 \n" // src -= 32 + "subs %w3, %w3, #16 \n" // 16 pixels per loop. + "tbl v2.16b, {v1.16b}, v4.16b \n" + "tbl v3.16b, {v0.16b}, v4.16b \n" + "uzp1 v0.16b, v2.16b, v3.16b \n" // U + "uzp2 v1.16b, v2.16b, v3.16b \n" // V + "st1 {v0.16b}, [%1], #16 \n" // dst += 16 + "st1 {v1.16b}, [%2], #16 \n" + "b.gt 1b \n" + : "+r"(src_uv), // %0 + "+r"(dst_u), // %1 + "+r"(dst_v), // %2 + "+r"(width) // %3 + : "r"(&kShuffleMirrorUV) // %4 + : "cc", "memory", "v0", "v1", "v2", "v3", "v4"); +} + +// Shuffle table for reversing the ARGB. +static const uvec8 kShuffleMirrorARGB = {12u, 13u, 14u, 15u, 8u, 9u, 10u, 11u, + 4u, 5u, 6u, 7u, 0u, 1u, 2u, 3u}; + +void ARGBMirrorRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { + asm volatile( + // Start at end of source row. + "ld1 {v4.16b}, [%3] \n" // shuffler + "add %0, %0, %w2, sxtw #2 \n" + "sub %0, %0, #32 \n" + "1: \n" + "ldr q1, [%0, 16] \n" + "ldr q0, [%0], -32 \n" // src -= 32 + "subs %w2, %w2, #8 \n" // 8 pixels per loop. + "tbl v2.16b, {v1.16b}, v4.16b \n" + "tbl v3.16b, {v0.16b}, v4.16b \n" + "st1 {v2.16b, v3.16b}, [%1], #32 \n" // dst += 32 + "b.gt 1b \n" + : "+r"(src_argb), // %0 + "+r"(dst_argb), // %1 + "+r"(width) // %2 + : "r"(&kShuffleMirrorARGB) // %3 + : "cc", "memory", "v0", "v1", "v2", "v3", "v4"); +} + +void RGB24MirrorRow_NEON(const uint8_t* src_rgb24, + uint8_t* dst_rgb24, + int width) { + asm volatile( + "ld1 {v3.16b}, [%4] \n" // shuffler + "add %0, %0, %w2, sxtw #1 \n" // Start at end of row. + "add %0, %0, %w2, sxtw \n" + "sub %0, %0, #48 \n" + + "1: \n" + "ld3 {v0.16b, v1.16b, v2.16b}, [%0], %3 \n" // src -= 48 + "subs %w2, %w2, #16 \n" // 16 pixels per loop. + "tbl v0.16b, {v0.16b}, v3.16b \n" + "tbl v1.16b, {v1.16b}, v3.16b \n" + "tbl v2.16b, {v2.16b}, v3.16b \n" + "st3 {v0.16b, v1.16b, v2.16b}, [%1], #48 \n" // dst += 48 + "b.gt 1b \n" + : "+r"(src_rgb24), // %0 + "+r"(dst_rgb24), // %1 + "+r"(width) // %2 + : "r"((ptrdiff_t)-48), // %3 + "r"(&kShuffleMirror) // %4 + : "cc", "memory", "v0", "v1", "v2", "v3"); } void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_argb, int width) { asm volatile( - "movi v4.8b, #255 \n" // Alpha + "movi v4.8b, #255 \n" // Alpha "1: \n" - "ld3 {v1.8b,v2.8b,v3.8b}, [%0], #24 \n" // load 8 pixels of RGB24. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "st4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%1], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld3 {v1.8b,v2.8b,v3.8b}, [%0], #24 \n" // load 8 pixels of + // RGB24. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "st4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%1], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_rgb24), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -805,14 +922,15 @@ void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width) { asm volatile( - "movi v5.8b, #255 \n" // Alpha + "movi v5.8b, #255 \n" // Alpha "1: \n" - "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // read r g b - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "orr v3.8b, v1.8b, v1.8b \n" // move g - "orr v4.8b, v0.8b, v0.8b \n" // move r - "st4 {v2.8b,v3.8b,v4.8b,v5.8b}, [%1], #32 \n" // store b g r a - "b.gt 1b \n" + "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // read r g b + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "orr v3.8b, v1.8b, v1.8b \n" // move g + "orr v4.8b, v0.8b, v0.8b \n" // move r + "st4 {v2.8b,v3.8b,v4.8b,v5.8b}, [%1], #32 \n" // store b g r a + "b.gt 1b \n" : "+r"(src_raw), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -823,14 +941,15 @@ void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width) { void RAWToRGBARow_NEON(const uint8_t* src_raw, uint8_t* dst_rgba, int width) { asm volatile( - "movi v0.8b, #255 \n" // Alpha + "movi v0.8b, #255 \n" // Alpha "1: \n" - "ld3 {v3.8b,v4.8b,v5.8b}, [%0], #24 \n" // read r g b - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "orr v2.8b, v4.8b, v4.8b \n" // move g - "orr v1.8b, v5.8b, v5.8b \n" // move r - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store a b g r - "b.gt 1b \n" + "ld3 {v3.8b,v4.8b,v5.8b}, [%0], #24 \n" // read r g b + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "orr v2.8b, v4.8b, v4.8b \n" // move g + "orr v1.8b, v5.8b, v5.8b \n" // move r + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store a b g r + "b.gt 1b \n" : "+r"(src_raw), // %0 "+r"(dst_rgba), // %1 "+r"(width) // %2 @@ -842,12 +961,13 @@ void RAWToRGBARow_NEON(const uint8_t* src_raw, uint8_t* dst_rgba, int width) { void RAWToRGB24Row_NEON(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { asm volatile( "1: \n" - "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // read r g b - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "orr v3.8b, v1.8b, v1.8b \n" // move g - "orr v4.8b, v0.8b, v0.8b \n" // move r - "st3 {v2.8b,v3.8b,v4.8b}, [%1], #24 \n" // store b g r - "b.gt 1b \n" + "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // read r g b + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "orr v3.8b, v1.8b, v1.8b \n" // move g + "orr v4.8b, v0.8b, v0.8b \n" // move r + "st3 {v2.8b,v3.8b,v4.8b}, [%1], #24 \n" // store b g r + "b.gt 1b \n" : "+r"(src_raw), // %0 "+r"(dst_rgb24), // %1 "+r"(width) // %2 @@ -873,13 +993,14 @@ void RGB565ToARGBRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_argb, int width) { asm volatile( - "movi v3.8b, #255 \n" // Alpha + "movi v3.8b, #255 \n" // Alpha "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. RGB565TOARGB - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_rgb565), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -929,14 +1050,14 @@ void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, uint8_t* dst_argb, int width) { asm volatile( - "movi v3.8b, #255 \n" // Alpha + "movi v3.8b, #255 \n" // Alpha "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. ARGB1555TOARGB - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB - // pixels - "b.gt 1b \n" + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_argb1555), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -945,6 +1066,8 @@ void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, ); } +// Convert v0.8h to b = v0.8b g = v1.8b r = v2.8b +// clobbers v3 #define ARGB4444TOARGB \ "shrn v1.8b, v0.8h, #8 \n" /* v1(l) AR */ \ "xtn2 v1.16b, v0.8h \n" /* v1(h) GB */ \ @@ -962,12 +1085,12 @@ void ARGB4444ToARGBRow_NEON(const uint8_t* src_argb4444, int width) { asm volatile( "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. ARGB4444TOARGB - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB - // pixels - "b.gt 1b \n" + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_argb4444), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -981,11 +1104,12 @@ void ARGBToRGB24Row_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "ld4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "st3 {v1.8b,v2.8b,v3.8b}, [%1], #24 \n" // store 8 pixels of - // RGB24. - "b.gt 1b \n" + "ld4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n" // load 8 ARGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "st3 {v1.8b,v2.8b,v3.8b}, [%1], #24 \n" // store 8 pixels of + // RGB24 + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_rgb24), // %1 "+r"(width) // %2 @@ -997,12 +1121,13 @@ void ARGBToRGB24Row_NEON(const uint8_t* src_argb, void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width) { asm volatile( "1: \n" - "ld4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n" // load b g r a - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "orr v4.8b, v2.8b, v2.8b \n" // mov g - "orr v5.8b, v1.8b, v1.8b \n" // mov b - "st3 {v3.8b,v4.8b,v5.8b}, [%1], #24 \n" // store r g b - "b.gt 1b \n" + "ld4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n" // load b g r a + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "orr v4.8b, v2.8b, v2.8b \n" // mov g + "orr v5.8b, v1.8b, v1.8b \n" // mov b + "st3 {v3.8b,v4.8b,v5.8b}, [%1], #24 \n" // store r g b + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_raw), // %1 "+r"(width) // %2 @@ -1014,10 +1139,11 @@ void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width) { void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { asm volatile( "1: \n" - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pixels of YUY2. - "subs %w2, %w2, #16 \n" // 16 processed per loop. - "st1 {v0.16b}, [%1], #16 \n" // store 16 pixels of Y. - "b.gt 1b \n" + "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pixels of YUY2. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #16 \n" // 16 processed per loop. + "st1 {v0.16b}, [%1], #16 \n" // store 16 pixels of Y. + "b.gt 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1029,10 +1155,11 @@ void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { void UYVYToYRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { asm volatile( "1: \n" - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pixels of UYVY. - "subs %w2, %w2, #16 \n" // 16 processed per loop. - "st1 {v1.16b}, [%1], #16 \n" // store 16 pixels of Y. - "b.gt 1b \n" + "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pixels of UYVY. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #16 \n" // 16 processed per loop. + "st1 {v1.16b}, [%1], #16 \n" // store 16 pixels of Y. + "b.gt 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1047,11 +1174,12 @@ void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, int width) { asm volatile( "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 YUY2 - "subs %w3, %w3, #16 \n" // 16 pixels = 8 UVs. - "st1 {v1.8b}, [%1], #8 \n" // store 8 U. - "st1 {v3.8b}, [%2], #8 \n" // store 8 V. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 YUY2 + "prfm pldl1keep, [%0, 448] \n" + "subs %w3, %w3, #16 \n" // 16 pixels = 8 UVs. + "st1 {v1.8b}, [%1], #8 \n" // store 8 U. + "st1 {v3.8b}, [%2], #8 \n" // store 8 V. + "b.gt 1b \n" : "+r"(src_yuy2), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1067,11 +1195,12 @@ void UYVYToUV422Row_NEON(const uint8_t* src_uyvy, int width) { asm volatile( "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 UYVY - "subs %w3, %w3, #16 \n" // 16 pixels = 8 UVs. - "st1 {v0.8b}, [%1], #8 \n" // store 8 U. - "st1 {v2.8b}, [%2], #8 \n" // store 8 V. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 UYVY + "prfm pldl1keep, [%0, 448] \n" + "subs %w3, %w3, #16 \n" // 16 pixels = 8 UVs. + "st1 {v0.8b}, [%1], #8 \n" // store 8 U. + "st1 {v2.8b}, [%2], #8 \n" // store 8 V. + "b.gt 1b \n" : "+r"(src_uyvy), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1089,14 +1218,15 @@ void YUY2ToUVRow_NEON(const uint8_t* src_yuy2, const uint8_t* src_yuy2b = src_yuy2 + stride_yuy2; asm volatile( "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 pixels - "subs %w4, %w4, #16 \n" // 16 pixels = 8 UVs. - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load next row - "urhadd v1.8b, v1.8b, v5.8b \n" // average rows of U - "urhadd v3.8b, v3.8b, v7.8b \n" // average rows of V - "st1 {v1.8b}, [%2], #8 \n" // store 8 U. - "st1 {v3.8b}, [%3], #8 \n" // store 8 V. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 pixels + "prfm pldl1keep, [%0, 448] \n" + "subs %w4, %w4, #16 \n" // 16 pixels = 8 UVs. + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load next row + "urhadd v1.8b, v1.8b, v5.8b \n" // average rows of U + "urhadd v3.8b, v3.8b, v7.8b \n" // average rows of V + "st1 {v1.8b}, [%2], #8 \n" // store 8 U. + "st1 {v3.8b}, [%3], #8 \n" // store 8 V. + "b.gt 1b \n" : "+r"(src_yuy2), // %0 "+r"(src_yuy2b), // %1 "+r"(dst_u), // %2 @@ -1116,14 +1246,15 @@ void UYVYToUVRow_NEON(const uint8_t* src_uyvy, const uint8_t* src_uyvyb = src_uyvy + stride_uyvy; asm volatile( "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 pixels - "subs %w4, %w4, #16 \n" // 16 pixels = 8 UVs. - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load next row - "urhadd v0.8b, v0.8b, v4.8b \n" // average rows of U - "urhadd v2.8b, v2.8b, v6.8b \n" // average rows of V - "st1 {v0.8b}, [%2], #8 \n" // store 8 U. - "st1 {v2.8b}, [%3], #8 \n" // store 8 V. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 pixels + "prfm pldl1keep, [%0, 448] \n" + "subs %w4, %w4, #16 \n" // 16 pixels = 8 UVs. + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load next row + "urhadd v0.8b, v0.8b, v4.8b \n" // average rows of U + "urhadd v2.8b, v2.8b, v6.8b \n" // average rows of V + "st1 {v0.8b}, [%2], #8 \n" // store 8 U. + "st1 {v2.8b}, [%3], #8 \n" // store 8 V. + "b.gt 1b \n" : "+r"(src_uyvy), // %0 "+r"(src_uyvyb), // %1 "+r"(dst_u), // %2 @@ -1141,13 +1272,14 @@ void ARGBShuffleRow_NEON(const uint8_t* src_argb, const uint8_t* shuffler, int width) { asm volatile( - "ld1 {v2.16b}, [%3] \n" // shuffler + "ld1 {v2.16b}, [%3] \n" // shuffler "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 4 pixels. - "subs %w2, %w2, #4 \n" // 4 processed per loop - "tbl v1.16b, {v0.16b}, v2.16b \n" // look up 4 pixels - "st1 {v1.16b}, [%1], #16 \n" // store 4. - "b.gt 1b \n" + "ld1 {v0.16b}, [%0], #16 \n" // load 4 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #4 \n" // 4 processed per loop + "tbl v1.16b, {v0.16b}, v2.16b \n" // look up 4 pixels + "st1 {v1.16b}, [%1], #16 \n" // store 4. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -1163,13 +1295,14 @@ void I422ToYUY2Row_NEON(const uint8_t* src_y, int width) { asm volatile( "1: \n" - "ld2 {v0.8b, v1.8b}, [%0], #16 \n" // load 16 Ys - "orr v2.8b, v1.8b, v1.8b \n" - "ld1 {v1.8b}, [%1], #8 \n" // load 8 Us - "ld1 {v3.8b}, [%2], #8 \n" // load 8 Vs - "subs %w4, %w4, #16 \n" // 16 pixels - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%3], #32 \n" // Store 16 pixels. - "b.gt 1b \n" + "ld2 {v0.8b, v1.8b}, [%0], #16 \n" // load 16 Ys + "prfm pldl1keep, [%0, 448] \n" + "orr v2.8b, v1.8b, v1.8b \n" + "ld1 {v1.8b}, [%1], #8 \n" // load 8 Us + "ld1 {v3.8b}, [%2], #8 \n" // load 8 Vs + "subs %w4, %w4, #16 \n" // 16 pixels + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%3], #32 \n" // Store 16 pixels. + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -1186,13 +1319,14 @@ void I422ToUYVYRow_NEON(const uint8_t* src_y, int width) { asm volatile( "1: \n" - "ld2 {v1.8b,v2.8b}, [%0], #16 \n" // load 16 Ys - "orr v3.8b, v2.8b, v2.8b \n" - "ld1 {v0.8b}, [%1], #8 \n" // load 8 Us - "ld1 {v2.8b}, [%2], #8 \n" // load 8 Vs - "subs %w4, %w4, #16 \n" // 16 pixels - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%3], #32 \n" // Store 16 pixels. - "b.gt 1b \n" + "ld2 {v1.8b,v2.8b}, [%0], #16 \n" // load 16 Ys + "prfm pldl1keep, [%0, 448] \n" + "orr v3.8b, v2.8b, v2.8b \n" + "ld1 {v0.8b}, [%1], #8 \n" // load 8 Us + "ld1 {v2.8b}, [%2], #8 \n" // load 8 Vs + "subs %w4, %w4, #16 \n" // 16 pixels + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%3], #32 \n" // Store 16 pixels. + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_u), // %1 "+r"(src_v), // %2 @@ -1207,11 +1341,13 @@ void ARGBToRGB565Row_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 pixels - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 + // pixels + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. ARGBTORGB565 - "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels RGB565. - "b.gt 1b \n" + "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels RGB565. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_rgb565), // %1 "+r"(width) // %2 @@ -1224,15 +1360,17 @@ void ARGBToRGB565DitherRow_NEON(const uint8_t* src_argb, const uint32_t dither4, int width) { asm volatile( - "dup v1.4s, %w2 \n" // dither4 + "dup v1.4s, %w2 \n" // dither4 "1: \n" - "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" // load 8 pixels - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqadd v20.8b, v20.8b, v1.8b \n" - "uqadd v21.8b, v21.8b, v1.8b \n" - "uqadd v22.8b, v22.8b, v1.8b \n" ARGBTORGB565 - "st1 {v0.16b}, [%0], #16 \n" // store 8 pixels RGB565. - "b.gt 1b \n" + "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" // load 8 + // pixels + "prfm pldl1keep, [%0, 448] \n" + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "uqadd v20.8b, v20.8b, v1.8b \n" + "uqadd v21.8b, v21.8b, v1.8b \n" + "uqadd v22.8b, v22.8b, v1.8b \n" ARGBTORGB565 + "st1 {v0.16b}, [%0], #16 \n" // store 8 pixels RGB565. + "b.gt 1b \n" : "+r"(dst_rgb) // %0 : "r"(src_argb), // %1 "r"(dither4), // %2 @@ -1245,12 +1383,13 @@ void ARGBToARGB1555Row_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 pixels - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 + // pixels + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. ARGBTOARGB1555 - "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels - // ARGB1555. - "b.gt 1b \n" + "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb1555), // %1 "+r"(width) // %2 @@ -1262,15 +1401,16 @@ void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, uint8_t* dst_argb4444, int width) { asm volatile( - "movi v4.16b, #0x0f \n" // bits to clear with + "movi v4.16b, #0x0f \n" // bits to clear with // vbic. "1: \n" - "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 pixels - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 + // pixels + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. ARGBTOARGB4444 - "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels - // ARGB4444. - "b.gt 1b \n" + "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb4444), // %1 "+r"(width) // %2 @@ -1280,20 +1420,21 @@ void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( - "movi v4.8b, #25 \n" // B * 0.1016 coefficient - "movi v5.8b, #129 \n" // G * 0.5078 coefficient - "movi v6.8b, #66 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant + "movi v4.8b, #25 \n" // B * 0.1016 coefficient + "movi v5.8b, #129 \n" // G * 0.5078 coefficient + "movi v6.8b, #66 \n" // R * 0.2578 coefficient + "movi v7.8b, #16 \n" // Add 16 constant "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v3.8h, v0.8b, v4.8b \n" // B - "umlal v3.8h, v1.8b, v5.8b \n" // G - "umlal v3.8h, v2.8b, v6.8b \n" // R - "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v3.8h, v0.8b, v4.8b \n" // B + "umlal v3.8h, v1.8b, v5.8b \n" // G + "umlal v3.8h, v2.8b, v6.8b \n" // R + "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v7.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1306,11 +1447,11 @@ void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 - // pixels - "subs %w2, %w2, #16 \n" // 16 processed per loop - "st1 {v3.16b}, [%1], #16 \n" // store 16 A's. - "b.gt 1b \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #16 \n" // 16 processed per loop + "st1 {v3.16b}, [%1], #16 \n" // store 16 A's. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_a), // %1 "+r"(width) // %2 @@ -1321,18 +1462,19 @@ void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( - "movi v4.8b, #29 \n" // B * 0.1140 coefficient - "movi v5.8b, #150 \n" // G * 0.5870 coefficient - "movi v6.8b, #77 \n" // R * 0.2990 coefficient + "movi v4.8b, #29 \n" // B * 0.1140 coefficient + "movi v5.8b, #150 \n" // G * 0.5870 coefficient + "movi v6.8b, #77 \n" // R * 0.2990 coefficient "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v3.8h, v0.8b, v4.8b \n" // B - "umlal v3.8h, v1.8b, v5.8b \n" // G - "umlal v3.8h, v2.8b, v6.8b \n" // R - "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v3.8h, v0.8b, v4.8b \n" // B + "umlal v3.8h, v1.8b, v5.8b \n" // G + "umlal v3.8h, v2.8b, v6.8b \n" // R + "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1342,18 +1484,19 @@ void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { void RGBAToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { asm volatile( - "movi v4.8b, #29 \n" // B * 0.1140 coefficient - "movi v5.8b, #150 \n" // G * 0.5870 coefficient - "movi v6.8b, #77 \n" // R * 0.2990 coefficient + "movi v4.8b, #29 \n" // B * 0.1140 coefficient + "movi v5.8b, #150 \n" // G * 0.5870 coefficient + "movi v6.8b, #77 \n" // R * 0.2990 coefficient "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 RGBA - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v0.8h, v1.8b, v4.8b \n" // B - "umlal v0.8h, v2.8b, v5.8b \n" // G - "umlal v0.8h, v3.8b, v6.8b \n" // R - "uqrshrn v3.8b, v0.8h, #8 \n" // 16 bit to 8 bit Y - "st1 {v3.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 RGBA + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v0.8h, v1.8b, v4.8b \n" // B + "umlal v0.8h, v2.8b, v5.8b \n" // G + "umlal v0.8h, v3.8b, v6.8b \n" // R + "uqrshrn v3.8b, v0.8h, #8 \n" // 16 bit to 8 bit Y + "st1 {v3.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1367,33 +1510,33 @@ void ARGBToUV444Row_NEON(const uint8_t* src_argb, uint8_t* dst_v, int width) { asm volatile( - "movi v24.8b, #112 \n" // UB / VR 0.875 + "movi v24.8b, #112 \n" // UB / VR 0.875 // coefficient - "movi v25.8b, #74 \n" // UG -0.5781 coefficient - "movi v26.8b, #38 \n" // UR -0.2969 coefficient - "movi v27.8b, #18 \n" // VB -0.1406 coefficient - "movi v28.8b, #94 \n" // VG -0.7344 coefficient - "movi v29.16b,#0x80 \n" // 128.5 + "movi v25.8b, #74 \n" // UG -0.5781 coefficient + "movi v26.8b, #38 \n" // UR -0.2969 coefficient + "movi v27.8b, #18 \n" // VB -0.1406 coefficient + "movi v28.8b, #94 \n" // VG -0.7344 coefficient + "movi v29.16b,#0x80 \n" // 128.5 "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - // pixels. - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "umull v4.8h, v0.8b, v24.8b \n" // B - "umlsl v4.8h, v1.8b, v25.8b \n" // G - "umlsl v4.8h, v2.8b, v26.8b \n" // R - "add v4.8h, v4.8h, v29.8h \n" // +128 -> unsigned + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "umull v4.8h, v0.8b, v24.8b \n" // B + "umlsl v4.8h, v1.8b, v25.8b \n" // G + "umlsl v4.8h, v2.8b, v26.8b \n" // R + "add v4.8h, v4.8h, v29.8h \n" // +128 -> unsigned - "umull v3.8h, v2.8b, v24.8b \n" // R - "umlsl v3.8h, v1.8b, v28.8b \n" // G - "umlsl v3.8h, v0.8b, v27.8b \n" // B - "add v3.8h, v3.8h, v29.8h \n" // +128 -> unsigned + "umull v3.8h, v2.8b, v24.8b \n" // R + "umlsl v3.8h, v1.8b, v28.8b \n" // G + "umlsl v3.8h, v0.8b, v27.8b \n" // B + "add v3.8h, v3.8h, v29.8h \n" // +128 -> unsigned - "uqshrn v0.8b, v4.8h, #8 \n" // 16 bit to 8 bit U - "uqshrn v1.8b, v3.8h, #8 \n" // 16 bit to 8 bit V + "uqshrn v0.8b, v4.8h, #8 \n" // 16 bit to 8 bit U + "uqshrn v1.8b, v3.8h, #8 \n" // 16 bit to 8 bit V - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%2], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%2], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_u), // %1 "+r"(dst_v), // %2 @@ -1437,26 +1580,28 @@ void ARGBToUVRow_NEON(const uint8_t* src_argb, const uint8_t* src_argb_1 = src_argb + src_stride_argb; asm volatile ( RGBTOUV_SETUP_REG - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. - "uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts. + "1: \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts. + "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. + "uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 - "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. + "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 + "prfm pldl1keep, [%1, 448] \n" + "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. + "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. + "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" + "urshr v0.8h, v0.8h, #1 \n" // 2x average + "urshr v1.8h, v1.8h, #1 \n" + "urshr v2.8h, v2.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 32 processed per loop. + "subs %w4, %w4, #16 \n" // 16 processed per loop. RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(src_argb_1), // %1 "+r"(dst_u), // %2 @@ -1468,7 +1613,6 @@ void ARGBToUVRow_NEON(const uint8_t* src_argb, ); } -// TODO(fbarchard): Subsample match C code. void ARGBToUVJRow_NEON(const uint8_t* src_argb, int src_stride_argb, uint8_t* dst_u, @@ -1476,31 +1620,33 @@ void ARGBToUVJRow_NEON(const uint8_t* src_argb, int width) { const uint8_t* src_argb_1 = src_argb + src_stride_argb; asm volatile ( - "movi v20.8h, #63, lsl #0 \n" // UB/VR coeff (0.500) / 2 - "movi v21.8h, #42, lsl #0 \n" // UG coeff (-0.33126) / 2 - "movi v22.8h, #21, lsl #0 \n" // UR coeff (-0.16874) / 2 - "movi v23.8h, #10, lsl #0 \n" // VB coeff (-0.08131) / 2 - "movi v24.8h, #53, lsl #0 \n" // VG coeff (-0.41869) / 2 - "movi v25.16b, #0x80 \n" // 128.5 (0x8080 in 16-bit) - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. - "uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 - "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. + "movi v20.8h, #63, lsl #0 \n" // UB/VR coeff (0.500) / 2 + "movi v21.8h, #42, lsl #0 \n" // UG coeff (-0.33126) / 2 + "movi v22.8h, #21, lsl #0 \n" // UR coeff (-0.16874) / 2 + "movi v23.8h, #10, lsl #0 \n" // VB coeff (-0.08131) / 2 + "movi v24.8h, #53, lsl #0 \n" // VG coeff (-0.41869) / 2 + "movi v25.16b, #0x80 \n" // 128.5 (0x8080 in 16-bit) + "1: \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts. + "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. + "uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts. + "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 + "prfm pldl1keep, [%1, 448] \n" + "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. + "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. + "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" + "urshr v0.8h, v0.8h, #1 \n" // 2x average + "urshr v1.8h, v1.8h, #1 \n" + "urshr v2.8h, v2.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 32 processed per loop. + "subs %w4, %w4, #16 \n" // 32 processed per loop. RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(src_argb_1), // %1 "+r"(dst_u), // %2 @@ -1520,25 +1666,27 @@ void BGRAToUVRow_NEON(const uint8_t* src_bgra, const uint8_t* src_bgra_1 = src_bgra + src_stride_bgra; asm volatile ( RGBTOUV_SETUP_REG - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. - "uaddlp v0.8h, v3.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v3.8h, v2.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v2.8h, v1.16b \n" // R 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more - "uadalp v0.8h, v7.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v3.8h, v6.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v5.16b \n" // R 16 bytes -> 8 shorts. + "1: \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v0.8h, v3.16b \n" // B 16 bytes -> 8 shorts. + "uaddlp v3.8h, v2.16b \n" // G 16 bytes -> 8 shorts. + "uaddlp v2.8h, v1.16b \n" // R 16 bytes -> 8 shorts. + "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more + "prfm pldl1keep, [%1, 448] \n" + "uadalp v0.8h, v7.16b \n" // B 16 bytes -> 8 shorts. + "uadalp v3.8h, v6.16b \n" // G 16 bytes -> 8 shorts. + "uadalp v2.8h, v5.16b \n" // R 16 bytes -> 8 shorts. - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v3.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" + "urshr v0.8h, v0.8h, #1 \n" // 2x average + "urshr v1.8h, v3.8h, #1 \n" + "urshr v2.8h, v2.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 32 processed per loop. + "subs %w4, %w4, #16 \n" // 32 processed per loop. RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_bgra), // %0 "+r"(src_bgra_1), // %1 "+r"(dst_u), // %2 @@ -1558,25 +1706,27 @@ void ABGRToUVRow_NEON(const uint8_t* src_abgr, const uint8_t* src_abgr_1 = src_abgr + src_stride_abgr; asm volatile ( RGBTOUV_SETUP_REG - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. - "uaddlp v3.8h, v2.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v2.8h, v1.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v1.8h, v0.16b \n" // R 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more. - "uadalp v3.8h, v6.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v2.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v1.8h, v4.16b \n" // R 16 bytes -> 8 shorts. + "1: \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v3.8h, v2.16b \n" // B 16 bytes -> 8 shorts. + "uaddlp v2.8h, v1.16b \n" // G 16 bytes -> 8 shorts. + "uaddlp v1.8h, v0.16b \n" // R 16 bytes -> 8 shorts. + "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more. + "prfm pldl1keep, [%1, 448] \n" + "uadalp v3.8h, v6.16b \n" // B 16 bytes -> 8 shorts. + "uadalp v2.8h, v5.16b \n" // G 16 bytes -> 8 shorts. + "uadalp v1.8h, v4.16b \n" // R 16 bytes -> 8 shorts. - "urshr v0.8h, v3.8h, #1 \n" // 2x average - "urshr v2.8h, v2.8h, #1 \n" - "urshr v1.8h, v1.8h, #1 \n" + "urshr v0.8h, v3.8h, #1 \n" // 2x average + "urshr v2.8h, v2.8h, #1 \n" + "urshr v1.8h, v1.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 32 processed per loop. + "subs %w4, %w4, #16 \n" // 32 processed per loop. RGBTOUV(v0.8h, v2.8h, v1.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_abgr), // %0 "+r"(src_abgr_1), // %1 "+r"(dst_u), // %2 @@ -1596,25 +1746,27 @@ void RGBAToUVRow_NEON(const uint8_t* src_rgba, const uint8_t* src_rgba_1 = src_rgba + src_stride_rgba; asm volatile ( RGBTOUV_SETUP_REG - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. - "uaddlp v0.8h, v1.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v1.8h, v2.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v2.8h, v3.16b \n" // R 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more. - "uadalp v0.8h, v5.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v6.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v7.16b \n" // R 16 bytes -> 8 shorts. + "1: \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v0.8h, v1.16b \n" // B 16 bytes -> 8 shorts. + "uaddlp v1.8h, v2.16b \n" // G 16 bytes -> 8 shorts. + "uaddlp v2.8h, v3.16b \n" // R 16 bytes -> 8 shorts. + "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more. + "prfm pldl1keep, [%1, 448] \n" + "uadalp v0.8h, v5.16b \n" // B 16 bytes -> 8 shorts. + "uadalp v1.8h, v6.16b \n" // G 16 bytes -> 8 shorts. + "uadalp v2.8h, v7.16b \n" // R 16 bytes -> 8 shorts. - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" + "urshr v0.8h, v0.8h, #1 \n" // 2x average + "urshr v1.8h, v1.8h, #1 \n" + "urshr v2.8h, v2.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 32 processed per loop. + "subs %w4, %w4, #16 \n" // 32 processed per loop. RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_rgba), // %0 "+r"(src_rgba_1), // %1 "+r"(dst_u), // %2 @@ -1634,25 +1786,27 @@ void RGB24ToUVRow_NEON(const uint8_t* src_rgb24, const uint8_t* src_rgb24_1 = src_rgb24 + src_stride_rgb24; asm volatile ( RGBTOUV_SETUP_REG - "1: \n" - "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \n" // load 16 pixels. - "uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts. - "ld3 {v4.16b,v5.16b,v6.16b}, [%1], #48 \n" // load 16 more. - "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. + "1: \n" + "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \n" // load 16 pixels. + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts. + "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. + "uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts. + "ld3 {v4.16b,v5.16b,v6.16b}, [%1], #48 \n" // load 16 more. + "prfm pldl1keep, [%1, 448] \n" + "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. + "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. + "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" + "urshr v0.8h, v0.8h, #1 \n" // 2x average + "urshr v1.8h, v1.8h, #1 \n" + "urshr v2.8h, v2.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 32 processed per loop. + "subs %w4, %w4, #16 \n" // 32 processed per loop. RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_rgb24), // %0 "+r"(src_rgb24_1), // %1 "+r"(dst_u), // %2 @@ -1672,25 +1826,27 @@ void RAWToUVRow_NEON(const uint8_t* src_raw, const uint8_t* src_raw_1 = src_raw + src_stride_raw; asm volatile ( RGBTOUV_SETUP_REG - "1: \n" - "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \n" // load 8 RAW pixels. - "uaddlp v2.8h, v2.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v0.8h, v0.16b \n" // R 16 bytes -> 8 shorts. - "ld3 {v4.16b,v5.16b,v6.16b}, [%1], #48 \n" // load 8 more RAW pixels - "uadalp v2.8h, v6.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v0.8h, v4.16b \n" // R 16 bytes -> 8 shorts. + "1: \n" + "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \n" // load 8 RAW pixels. + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v2.8h, v2.16b \n" // B 16 bytes -> 8 shorts. + "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. + "uaddlp v0.8h, v0.16b \n" // R 16 bytes -> 8 shorts. + "ld3 {v4.16b,v5.16b,v6.16b}, [%1], #48 \n" // load 8 more RAW pixels + "prfm pldl1keep, [%1, 448] \n" + "uadalp v2.8h, v6.16b \n" // B 16 bytes -> 8 shorts. + "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. + "uadalp v0.8h, v4.16b \n" // R 16 bytes -> 8 shorts. - "urshr v2.8h, v2.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v0.8h, v0.8h, #1 \n" + "urshr v2.8h, v2.8h, #1 \n" // 2x average + "urshr v1.8h, v1.8h, #1 \n" + "urshr v0.8h, v0.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 32 processed per loop. + "subs %w4, %w4, #16 \n" // 32 processed per loop. RGBTOUV(v2.8h, v1.8h, v0.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_raw), // %0 "+r"(src_raw_1), // %1 "+r"(dst_u), // %2 @@ -1702,7 +1858,7 @@ void RAWToUVRow_NEON(const uint8_t* src_raw, ); } -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. +// 16x2 pixels -> 8x1. width is number of rgb pixels. e.g. 16. void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, int src_stride_rgb565, uint8_t* dst_u, @@ -1710,67 +1866,54 @@ void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, int width) { const uint8_t* src_rgb565_1 = src_rgb565 + src_stride_rgb565; asm volatile( - "movi v22.8h, #56, lsl #0 \n" // UB / VR coeff (0.875) / - // 2 - "movi v23.8h, #37, lsl #0 \n" // UG coeff (-0.5781) / 2 - "movi v24.8h, #19, lsl #0 \n" // UR coeff (-0.2969) / 2 - "movi v25.8h, #9 , lsl #0 \n" // VB coeff (-0.1406) / 2 - "movi v26.8h, #47, lsl #0 \n" // VG coeff (-0.7344) / 2 - "movi v27.16b, #0x80 \n" // 128.5 0x8080 in 16bit + RGBTOUV_SETUP_REG "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. + "prfm pldl1keep, [%0, 448] \n" RGB565TOARGB - "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v18.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v20.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%0], #16 \n" // next 8 RGB565 pixels. + "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uaddlp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uaddlp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "ld1 {v0.16b}, [%0], #16 \n" // next 8 RGB565 pixels. RGB565TOARGB - "uaddlp v17.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v19.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v21.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "uaddlp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uaddlp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uaddlp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // load 8 RGB565 pixels. + "ld1 {v0.16b}, [%1], #16 \n" // load 8 RGB565 pixels. + "prfm pldl1keep, [%1, 448] \n" RGB565TOARGB - "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v18.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v20.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // next 8 RGB565 pixels. + "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uadalp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uadalp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "ld1 {v0.16b}, [%1], #16 \n" // next 8 RGB565 pixels. RGB565TOARGB - "uadalp v17.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v19.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v21.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "uadalp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uadalp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uadalp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ins v16.D[1], v17.D[0] \n" - "ins v18.D[1], v19.D[0] \n" - "ins v20.D[1], v21.D[0] \n" + "ins v16.D[1], v26.D[0] \n" + "ins v17.D[1], v27.D[0] \n" + "ins v18.D[1], v28.D[0] \n" - "urshr v4.8h, v16.8h, #1 \n" // 2x average - "urshr v5.8h, v18.8h, #1 \n" - "urshr v6.8h, v20.8h, #1 \n" + "urshr v0.8h, v16.8h, #1 \n" // 2x average + "urshr v1.8h, v17.8h, #1 \n" + "urshr v2.8h, v18.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 16 processed per loop. - "mul v16.8h, v4.8h, v22.8h \n" // B - "mls v16.8h, v5.8h, v23.8h \n" // G - "mls v16.8h, v6.8h, v24.8h \n" // R - "add v16.8h, v16.8h, v27.8h \n" // +128 -> unsigned - "mul v17.8h, v6.8h, v22.8h \n" // R - "mls v17.8h, v5.8h, v26.8h \n" // G - "mls v17.8h, v4.8h, v25.8h \n" // B - "add v17.8h, v17.8h, v27.8h \n" // +128 -> unsigned - "uqshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit U - "uqshrn v1.8b, v17.8h, #8 \n" // 16 bit to 8 bit V - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "subs %w4, %w4, #16 \n" // 16 processed per loop. + RGBTOUV(v0.8h, v1.8h, v2.8h) + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_rgb565), // %0 "+r"(src_rgb565_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 + "+r"(dst_u), // %2 + "+r"(dst_v), // %3 + "+r"(width) // %4 : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", - "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", - "v27"); + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v16", "v17", + "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", + "v28"); } // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. @@ -1783,50 +1926,43 @@ void ARGB1555ToUVRow_NEON(const uint8_t* src_argb1555, asm volatile( RGBTOUV_SETUP_REG "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. + "prfm pldl1keep, [%0, 448] \n" RGB555TOARGB - "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%0], #16 \n" // next 8 ARGB1555 pixels. + "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uaddlp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uaddlp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "ld1 {v0.16b}, [%0], #16 \n" // next 8 ARGB1555 pixels. RGB555TOARGB - "uaddlp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "uaddlp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uaddlp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uaddlp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // load 8 ARGB1555 pixels. + "ld1 {v0.16b}, [%1], #16 \n" // load 8 ARGB1555 pixels. + "prfm pldl1keep, [%1, 448] \n" RGB555TOARGB - "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // next 8 ARGB1555 pixels. + "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uadalp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uadalp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "ld1 {v0.16b}, [%1], #16 \n" // next 8 ARGB1555 pixels. RGB555TOARGB - "uadalp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "uadalp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uadalp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uadalp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ins v16.D[1], v26.D[0] \n" - "ins v17.D[1], v27.D[0] \n" - "ins v18.D[1], v28.D[0] \n" + "ins v16.D[1], v26.D[0] \n" + "ins v17.D[1], v27.D[0] \n" + "ins v18.D[1], v28.D[0] \n" - "urshr v4.8h, v16.8h, #1 \n" // 2x average - "urshr v5.8h, v17.8h, #1 \n" - "urshr v6.8h, v18.8h, #1 \n" + "urshr v0.8h, v16.8h, #1 \n" // 2x average + "urshr v1.8h, v17.8h, #1 \n" + "urshr v2.8h, v18.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 16 processed per loop. - "mul v2.8h, v4.8h, v20.8h \n" // B - "mls v2.8h, v5.8h, v21.8h \n" // G - "mls v2.8h, v6.8h, v22.8h \n" // R - "add v2.8h, v2.8h, v25.8h \n" // +128 -> unsigned - "mul v3.8h, v6.8h, v20.8h \n" // R - "mls v3.8h, v5.8h, v24.8h \n" // G - "mls v3.8h, v4.8h, v23.8h \n" // B - "add v3.8h, v3.8h, v25.8h \n" // +128 -> unsigned - "uqshrn v0.8b, v2.8h, #8 \n" // 16 bit to 8 bit U - "uqshrn v1.8b, v3.8h, #8 \n" // 16 bit to 8 bit V - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "subs %w4, %w4, #16 \n" // 16 processed per loop. + RGBTOUV(v0.8h, v1.8h, v2.8h) + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_argb1555), // %0 "+r"(src_argb1555_1), // %1 "+r"(dst_u), // %2 @@ -1846,52 +1982,45 @@ void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, int width) { const uint8_t* src_argb4444_1 = src_argb4444 + src_stride_argb4444; asm volatile( - RGBTOUV_SETUP_REG + RGBTOUV_SETUP_REG // sets v20-v25 "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. + "prfm pldl1keep, [%0, 448] \n" ARGB4444TOARGB - "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%0], #16 \n" // next 8 ARGB4444 pixels. + "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uaddlp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uaddlp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "ld1 {v0.16b}, [%0], #16 \n" // next 8 ARGB4444 pixels. ARGB4444TOARGB - "uaddlp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "uaddlp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uaddlp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uaddlp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // load 8 ARGB4444 pixels. + "ld1 {v0.16b}, [%1], #16 \n" // load 8 ARGB4444 pixels. + "prfm pldl1keep, [%1, 448] \n" ARGB4444TOARGB - "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // next 8 ARGB4444 pixels. + "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uadalp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uadalp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "ld1 {v0.16b}, [%1], #16 \n" // next 8 ARGB4444 pixels. ARGB4444TOARGB - "uadalp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. + "uadalp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. + "uadalp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. + "uadalp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ins v16.D[1], v26.D[0] \n" - "ins v17.D[1], v27.D[0] \n" - "ins v18.D[1], v28.D[0] \n" + "ins v16.D[1], v26.D[0] \n" + "ins v17.D[1], v27.D[0] \n" + "ins v18.D[1], v28.D[0] \n" - "urshr v4.8h, v16.8h, #1 \n" // 2x average - "urshr v5.8h, v17.8h, #1 \n" - "urshr v6.8h, v18.8h, #1 \n" + "urshr v0.8h, v16.8h, #1 \n" // 2x average + "urshr v1.8h, v17.8h, #1 \n" + "urshr v2.8h, v18.8h, #1 \n" - "subs %w4, %w4, #16 \n" // 16 processed per loop. - "mul v2.8h, v4.8h, v20.8h \n" // B - "mls v2.8h, v5.8h, v21.8h \n" // G - "mls v2.8h, v6.8h, v22.8h \n" // R - "add v2.8h, v2.8h, v25.8h \n" // +128 -> unsigned - "mul v3.8h, v6.8h, v20.8h \n" // R - "mls v3.8h, v5.8h, v24.8h \n" // G - "mls v3.8h, v4.8h, v23.8h \n" // B - "add v3.8h, v3.8h, v25.8h \n" // +128 -> unsigned - "uqshrn v0.8b, v2.8h, #8 \n" // 16 bit to 8 bit U - "uqshrn v1.8b, v3.8h, #8 \n" // 16 bit to 8 bit V - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" + "subs %w4, %w4, #16 \n" // 16 processed per loop. + RGBTOUV(v0.8h, v1.8h, v2.8h) + "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. + "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. + "b.gt 1b \n" : "+r"(src_argb4444), // %0 "+r"(src_argb4444_1), // %1 "+r"(dst_u), // %2 @@ -1907,21 +2036,22 @@ void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { asm volatile( - "movi v24.8b, #25 \n" // B * 0.1016 coefficient - "movi v25.8b, #129 \n" // G * 0.5078 coefficient - "movi v26.8b, #66 \n" // R * 0.2578 coefficient - "movi v27.8b, #16 \n" // Add 16 constant + "movi v24.8b, #25 \n" // B * 0.1016 coefficient + "movi v25.8b, #129 \n" // G * 0.5078 coefficient + "movi v26.8b, #66 \n" // R * 0.2578 coefficient + "movi v27.8b, #16 \n" // Add 16 constant "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. RGB565TOARGB - "umull v3.8h, v0.8b, v24.8b \n" // B - "umlal v3.8h, v1.8b, v25.8b \n" // G - "umlal v3.8h, v2.8b, v26.8b \n" // R - "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v27.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "umull v3.8h, v0.8b, v24.8b \n" // B + "umlal v3.8h, v1.8b, v25.8b \n" // G + "umlal v3.8h, v2.8b, v26.8b \n" // R + "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v27.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_rgb565), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1934,21 +2064,22 @@ void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, uint8_t* dst_y, int width) { asm volatile( - "movi v4.8b, #25 \n" // B * 0.1016 coefficient - "movi v5.8b, #129 \n" // G * 0.5078 coefficient - "movi v6.8b, #66 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant + "movi v4.8b, #25 \n" // B * 0.1016 coefficient + "movi v5.8b, #129 \n" // G * 0.5078 coefficient + "movi v6.8b, #66 \n" // R * 0.2578 coefficient + "movi v7.8b, #16 \n" // Add 16 constant "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. ARGB1555TOARGB - "umull v3.8h, v0.8b, v4.8b \n" // B - "umlal v3.8h, v1.8b, v5.8b \n" // G - "umlal v3.8h, v2.8b, v6.8b \n" // R - "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "umull v3.8h, v0.8b, v4.8b \n" // B + "umlal v3.8h, v1.8b, v5.8b \n" // G + "umlal v3.8h, v2.8b, v6.8b \n" // R + "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v7.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_argb1555), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1960,21 +2091,22 @@ void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, uint8_t* dst_y, int width) { asm volatile( - "movi v24.8b, #25 \n" // B * 0.1016 coefficient - "movi v25.8b, #129 \n" // G * 0.5078 coefficient - "movi v26.8b, #66 \n" // R * 0.2578 coefficient - "movi v27.8b, #16 \n" // Add 16 constant + "movi v24.8b, #25 \n" // B * 0.1016 coefficient + "movi v25.8b, #129 \n" // G * 0.5078 coefficient + "movi v26.8b, #66 \n" // R * 0.2578 coefficient + "movi v27.8b, #16 \n" // Add 16 constant "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. + "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. ARGB4444TOARGB - "umull v3.8h, v0.8b, v24.8b \n" // B - "umlal v3.8h, v1.8b, v25.8b \n" // G - "umlal v3.8h, v2.8b, v26.8b \n" // R - "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v27.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "umull v3.8h, v0.8b, v24.8b \n" // B + "umlal v3.8h, v1.8b, v25.8b \n" // G + "umlal v3.8h, v2.8b, v26.8b \n" // R + "uqrshrn v0.8b, v3.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v27.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_argb4444), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -1984,20 +2116,21 @@ void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width) { asm volatile( - "movi v4.8b, #66 \n" // R * 0.2578 coefficient - "movi v5.8b, #129 \n" // G * 0.5078 coefficient - "movi v6.8b, #25 \n" // B * 0.1016 coefficient - "movi v7.8b, #16 \n" // Add 16 constant + "movi v4.8b, #66 \n" // R * 0.2578 coefficient + "movi v5.8b, #129 \n" // G * 0.5078 coefficient + "movi v6.8b, #25 \n" // B * 0.1016 coefficient + "movi v7.8b, #16 \n" // Add 16 constant "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v1.8b, v4.8b \n" // R - "umlal v16.8h, v2.8b, v5.8b \n" // G - "umlal v16.8h, v3.8b, v6.8b \n" // B - "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v16.8h, v1.8b, v4.8b \n" // R + "umlal v16.8h, v2.8b, v5.8b \n" // G + "umlal v16.8h, v3.8b, v6.8b \n" // B + "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v7.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_bgra), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2007,20 +2140,21 @@ void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width) { void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width) { asm volatile( - "movi v6.8b, #25 \n" // B * 0.1016 coefficient - "movi v5.8b, #129 \n" // G * 0.5078 coefficient - "movi v4.8b, #66 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant + "movi v6.8b, #25 \n" // B * 0.1016 coefficient + "movi v5.8b, #129 \n" // G * 0.5078 coefficient + "movi v4.8b, #66 \n" // R * 0.2578 coefficient + "movi v7.8b, #16 \n" // Add 16 constant "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v0.8b, v4.8b \n" // R - "umlal v16.8h, v1.8b, v5.8b \n" // G - "umlal v16.8h, v2.8b, v6.8b \n" // B - "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v16.8h, v0.8b, v4.8b \n" // R + "umlal v16.8h, v1.8b, v5.8b \n" // G + "umlal v16.8h, v2.8b, v6.8b \n" // B + "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v7.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_abgr), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2030,20 +2164,21 @@ void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width) { void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width) { asm volatile( - "movi v4.8b, #25 \n" // B * 0.1016 coefficient - "movi v5.8b, #129 \n" // G * 0.5078 coefficient - "movi v6.8b, #66 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant + "movi v4.8b, #25 \n" // B * 0.1016 coefficient + "movi v5.8b, #129 \n" // G * 0.5078 coefficient + "movi v6.8b, #66 \n" // R * 0.2578 coefficient + "movi v7.8b, #16 \n" // Add 16 constant "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v1.8b, v4.8b \n" // B - "umlal v16.8h, v2.8b, v5.8b \n" // G - "umlal v16.8h, v3.8b, v6.8b \n" // R - "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v16.8h, v1.8b, v4.8b \n" // B + "umlal v16.8h, v2.8b, v5.8b \n" // G + "umlal v16.8h, v3.8b, v6.8b \n" // R + "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v7.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_rgba), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2053,20 +2188,21 @@ void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width) { void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { asm volatile( - "movi v4.8b, #25 \n" // B * 0.1016 coefficient - "movi v5.8b, #129 \n" // G * 0.5078 coefficient - "movi v6.8b, #66 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant + "movi v4.8b, #25 \n" // B * 0.1016 coefficient + "movi v5.8b, #129 \n" // G * 0.5078 coefficient + "movi v6.8b, #66 \n" // R * 0.2578 coefficient + "movi v7.8b, #16 \n" // Add 16 constant "1: \n" - "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v0.8b, v4.8b \n" // B - "umlal v16.8h, v1.8b, v5.8b \n" // G - "umlal v16.8h, v2.8b, v6.8b \n" // R - "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // load 8 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v16.8h, v0.8b, v4.8b \n" // B + "umlal v16.8h, v1.8b, v5.8b \n" // G + "umlal v16.8h, v2.8b, v6.8b \n" // R + "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v7.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_rgb24), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2076,20 +2212,21 @@ void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width) { asm volatile( - "movi v6.8b, #25 \n" // B * 0.1016 coefficient - "movi v5.8b, #129 \n" // G * 0.5078 coefficient - "movi v4.8b, #66 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant + "movi v6.8b, #25 \n" // B * 0.1016 coefficient + "movi v5.8b, #129 \n" // G * 0.5078 coefficient + "movi v4.8b, #66 \n" // R * 0.2578 coefficient + "movi v7.8b, #16 \n" // Add 16 constant "1: \n" - "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v0.8b, v4.8b \n" // B - "umlal v16.8h, v1.8b, v5.8b \n" // G - "umlal v16.8h, v2.8b, v6.8b \n" // R - "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" + "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // load 8 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v16.8h, v0.8b, v4.8b \n" // B + "umlal v16.8h, v1.8b, v5.8b \n" // G + "umlal v16.8h, v2.8b, v6.8b \n" // R + "uqrshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit Y + "uqadd v0.8b, v0.8b, v7.8b \n" + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" : "+r"(src_raw), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -2097,6 +2234,50 @@ void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width) { : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); } +void RGB24ToYJRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_yj, int width) { + asm volatile( + "movi v4.8b, #29 \n" // B * 0.1140 coefficient + "movi v5.8b, #150 \n" // G * 0.5870 coefficient + "movi v6.8b, #77 \n" // R * 0.2990 coefficient + "1: \n" + "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // load 8 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v0.8h, v0.8b, v4.8b \n" // B + "umlal v0.8h, v1.8b, v5.8b \n" // G + "umlal v0.8h, v2.8b, v6.8b \n" // R + "uqrshrn v0.8b, v0.8h, #8 \n" // 16 bit to 8 bit Y + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" + : "+r"(src_rgb24), // %0 + "+r"(dst_yj), // %1 + "+r"(width) // %2 + : + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"); +} + +void RAWToYJRow_NEON(const uint8_t* src_raw, uint8_t* dst_yj, int width) { + asm volatile( + "movi v6.8b, #29 \n" // B * 0.1140 coefficient + "movi v5.8b, #150 \n" // G * 0.5870 coefficient + "movi v4.8b, #77 \n" // R * 0.2990 coefficient + "1: \n" + "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // load 8 pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v0.8h, v0.8b, v4.8b \n" // B + "umlal v0.8h, v1.8b, v5.8b \n" // G + "umlal v0.8h, v2.8b, v6.8b \n" // R + "uqrshrn v0.8b, v0.8h, #8 \n" // 16 bit to 8 bit Y + "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. + "b.gt 1b \n" + : "+r"(src_raw), // %0 + "+r"(dst_yj), // %1 + "+r"(width) // %2 + : + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"); +} + // Bilinear filter 16x2 -> 16x1 void InterpolateRow_NEON(uint8_t* dst_ptr, const uint8_t* src_ptr, @@ -2107,44 +2288,49 @@ void InterpolateRow_NEON(uint8_t* dst_ptr, int y0_fraction = 256 - y1_fraction; const uint8_t* src_ptr1 = src_ptr + src_stride; asm volatile( - "cmp %w4, #0 \n" - "b.eq 100f \n" - "cmp %w4, #128 \n" - "b.eq 50f \n" + "cmp %w4, #0 \n" + "b.eq 100f \n" + "cmp %w4, #128 \n" + "b.eq 50f \n" - "dup v5.16b, %w4 \n" - "dup v4.16b, %w5 \n" + "dup v5.16b, %w4 \n" + "dup v4.16b, %w5 \n" // General purpose row blend. "1: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "umull v2.8h, v0.8b, v4.8b \n" - "umull2 v3.8h, v0.16b, v4.16b \n" - "umlal v2.8h, v1.8b, v5.8b \n" - "umlal2 v3.8h, v1.16b, v5.16b \n" - "rshrn v0.8b, v2.8h, #8 \n" - "rshrn2 v0.16b, v3.8h, #8 \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 1b \n" - "b 99f \n" + "ld1 {v0.16b}, [%1], #16 \n" + "ld1 {v1.16b}, [%2], #16 \n" + "prfm pldl1keep, [%1, 448] \n" + "prfm pldl1keep, [%2, 448] \n" + "subs %w3, %w3, #16 \n" + "umull v2.8h, v0.8b, v4.8b \n" + "umull2 v3.8h, v0.16b, v4.16b \n" + "umlal v2.8h, v1.8b, v5.8b \n" + "umlal2 v3.8h, v1.16b, v5.16b \n" + "rshrn v0.8b, v2.8h, #8 \n" + "rshrn2 v0.16b, v3.8h, #8 \n" + "st1 {v0.16b}, [%0], #16 \n" + "b.gt 1b \n" + "b 99f \n" // Blend 50 / 50. "50: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 50b \n" - "b 99f \n" + "ld1 {v0.16b}, [%1], #16 \n" + "ld1 {v1.16b}, [%2], #16 \n" + "prfm pldl1keep, [%1, 448] \n" + "prfm pldl1keep, [%2, 448] \n" + "subs %w3, %w3, #16 \n" + "urhadd v0.16b, v0.16b, v1.16b \n" + "st1 {v0.16b}, [%0], #16 \n" + "b.gt 50b \n" + "b 99f \n" // Blend 100 / 0 - Copy row unchanged. "100: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "subs %w3, %w3, #16 \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 100b \n" + "ld1 {v0.16b}, [%1], #16 \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #16 \n" + "st1 {v0.16b}, [%0], #16 \n" + "b.gt 100b \n" "99: \n" : "+r"(dst_ptr), // %0 @@ -2163,56 +2349,60 @@ void ARGBBlendRow_NEON(const uint8_t* src_argb0, uint8_t* dst_argb, int width) { asm volatile( - "subs %w3, %w3, #8 \n" - "b.lt 89f \n" + "subs %w3, %w3, #8 \n" + "b.lt 89f \n" // Blend 8 pixels. "8: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB0 - // pixels - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 ARGB1 - // pixels - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "umull v16.8h, v4.8b, v3.8b \n" // db * a - "umull v17.8h, v5.8b, v3.8b \n" // dg * a - "umull v18.8h, v6.8b, v3.8b \n" // dr * a - "uqrshrn v16.8b, v16.8h, #8 \n" // db >>= 8 - "uqrshrn v17.8b, v17.8h, #8 \n" // dg >>= 8 - "uqrshrn v18.8b, v18.8h, #8 \n" // dr >>= 8 - "uqsub v4.8b, v4.8b, v16.8b \n" // db - (db * a / 256) - "uqsub v5.8b, v5.8b, v17.8b \n" // dg - (dg * a / 256) - "uqsub v6.8b, v6.8b, v18.8b \n" // dr - (dr * a / 256) - "uqadd v0.8b, v0.8b, v4.8b \n" // + sb - "uqadd v1.8b, v1.8b, v5.8b \n" // + sg - "uqadd v2.8b, v2.8b, v6.8b \n" // + sr - "movi v3.8b, #255 \n" // a = 255 - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - // pixels - "b.ge 8b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB0 + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 ARGB1 + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "umull v16.8h, v4.8b, v3.8b \n" // db * a + "umull v17.8h, v5.8b, v3.8b \n" // dg * a + "umull v18.8h, v6.8b, v3.8b \n" // dr * a + "uqrshrn v16.8b, v16.8h, #8 \n" // db >>= 8 + "uqrshrn v17.8b, v17.8h, #8 \n" // dg >>= 8 + "uqrshrn v18.8b, v18.8h, #8 \n" // dr >>= 8 + "uqsub v4.8b, v4.8b, v16.8b \n" // db - (db * a / 256) + "uqsub v5.8b, v5.8b, v17.8b \n" // dg - (dg * a / 256) + "uqsub v6.8b, v6.8b, v18.8b \n" // dr - (dr * a / 256) + "uqadd v0.8b, v0.8b, v4.8b \n" // + sb + "uqadd v1.8b, v1.8b, v5.8b \n" // + sg + "uqadd v2.8b, v2.8b, v6.8b \n" // + sr + "movi v3.8b, #255 \n" // a = 255 + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB + // pixels + "b.ge 8b \n" "89: \n" - "adds %w3, %w3, #8-1 \n" - "b.lt 99f \n" + "adds %w3, %w3, #8-1 \n" + "b.lt 99f \n" // Blend 1 pixels. "1: \n" - "ld4 {v0.b,v1.b,v2.b,v3.b}[0], [%0], #4 \n" // load 1 pixel ARGB0. - "ld4 {v4.b,v5.b,v6.b,v7.b}[0], [%1], #4 \n" // load 1 pixel ARGB1. - "subs %w3, %w3, #1 \n" // 1 processed per loop. - "umull v16.8h, v4.8b, v3.8b \n" // db * a - "umull v17.8h, v5.8b, v3.8b \n" // dg * a - "umull v18.8h, v6.8b, v3.8b \n" // dr * a - "uqrshrn v16.8b, v16.8h, #8 \n" // db >>= 8 - "uqrshrn v17.8b, v17.8h, #8 \n" // dg >>= 8 - "uqrshrn v18.8b, v18.8h, #8 \n" // dr >>= 8 - "uqsub v4.8b, v4.8b, v16.8b \n" // db - (db * a / 256) - "uqsub v5.8b, v5.8b, v17.8b \n" // dg - (dg * a / 256) - "uqsub v6.8b, v6.8b, v18.8b \n" // dr - (dr * a / 256) - "uqadd v0.8b, v0.8b, v4.8b \n" // + sb - "uqadd v1.8b, v1.8b, v5.8b \n" // + sg - "uqadd v2.8b, v2.8b, v6.8b \n" // + sr - "movi v3.8b, #255 \n" // a = 255 - "st4 {v0.b,v1.b,v2.b,v3.b}[0], [%2], #4 \n" // store 1 pixel. - "b.ge 1b \n" + "ld4 {v0.b,v1.b,v2.b,v3.b}[0], [%0], #4 \n" // load 1 pixel + // ARGB0. + "ld4 {v4.b,v5.b,v6.b,v7.b}[0], [%1], #4 \n" // load 1 pixel + // ARGB1. + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #1 \n" // 1 processed per loop. + "umull v16.8h, v4.8b, v3.8b \n" // db * a + "umull v17.8h, v5.8b, v3.8b \n" // dg * a + "umull v18.8h, v6.8b, v3.8b \n" // dr * a + "uqrshrn v16.8b, v16.8h, #8 \n" // db >>= 8 + "uqrshrn v17.8b, v17.8h, #8 \n" // dg >>= 8 + "uqrshrn v18.8b, v18.8h, #8 \n" // dr >>= 8 + "uqsub v4.8b, v4.8b, v16.8b \n" // db - (db * a / 256) + "uqsub v5.8b, v5.8b, v17.8b \n" // dg - (dg * a / 256) + "uqsub v6.8b, v6.8b, v18.8b \n" // dr - (dr * a / 256) + "uqadd v0.8b, v0.8b, v4.8b \n" // + sb + "uqadd v1.8b, v1.8b, v5.8b \n" // + sg + "uqadd v2.8b, v2.8b, v6.8b \n" // + sr + "movi v3.8b, #255 \n" // a = 255 + "st4 {v0.b,v1.b,v2.b,v3.b}[0], [%2], #4 \n" // store 1 pixel. + "b.ge 1b \n" "99: \n" @@ -2232,17 +2422,17 @@ void ARGBAttenuateRow_NEON(const uint8_t* src_argb, asm volatile( // Attenuate 8 pixels. "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v4.8h, v0.8b, v3.8b \n" // b * a - "umull v5.8h, v1.8b, v3.8b \n" // g * a - "umull v6.8h, v2.8b, v3.8b \n" // r * a - "uqrshrn v0.8b, v4.8h, #8 \n" // b >>= 8 - "uqrshrn v1.8b, v5.8h, #8 \n" // g >>= 8 - "uqrshrn v2.8b, v6.8h, #8 \n" // r >>= 8 - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB - // pixels - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v4.8h, v0.8b, v3.8b \n" // b * a + "umull v5.8h, v1.8b, v3.8b \n" // g * a + "umull v6.8h, v2.8b, v3.8b \n" // r * a + "uqrshrn v0.8b, v4.8h, #8 \n" // b >>= 8 + "uqrshrn v1.8b, v5.8h, #8 \n" // g >>= 8 + "uqrshrn v2.8b, v6.8h, #8 \n" // r >>= 8 + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -2258,32 +2448,33 @@ void ARGBQuantizeRow_NEON(uint8_t* dst_argb, int interval_offset, int width) { asm volatile( - "dup v4.8h, %w2 \n" - "ushr v4.8h, v4.8h, #1 \n" // scale >>= 1 - "dup v5.8h, %w3 \n" // interval multiply. - "dup v6.8h, %w4 \n" // interval add + "dup v4.8h, %w2 \n" + "ushr v4.8h, v4.8h, #1 \n" // scale >>= 1 + "dup v5.8h, %w3 \n" // interval multiply. + "dup v6.8h, %w4 \n" // interval add // 8 pixel loop. "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0] \n" // load 8 ARGB. - "subs %w1, %w1, #8 \n" // 8 processed per loop. - "uxtl v0.8h, v0.8b \n" // b (0 .. 255) - "uxtl v1.8h, v1.8b \n" - "uxtl v2.8h, v2.8b \n" - "sqdmulh v0.8h, v0.8h, v4.8h \n" // b * scale - "sqdmulh v1.8h, v1.8h, v4.8h \n" // g - "sqdmulh v2.8h, v2.8h, v4.8h \n" // r - "mul v0.8h, v0.8h, v5.8h \n" // b * interval_size - "mul v1.8h, v1.8h, v5.8h \n" // g - "mul v2.8h, v2.8h, v5.8h \n" // r - "add v0.8h, v0.8h, v6.8h \n" // b + interval_offset - "add v1.8h, v1.8h, v6.8h \n" // g - "add v2.8h, v2.8h, v6.8h \n" // r - "uqxtn v0.8b, v0.8h \n" - "uqxtn v1.8b, v1.8h \n" - "uqxtn v2.8b, v2.8h \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0] \n" // load 8 ARGB. + "prfm pldl1keep, [%0, 448] \n" + "subs %w1, %w1, #8 \n" // 8 processed per loop. + "uxtl v0.8h, v0.8b \n" // b (0 .. 255) + "uxtl v1.8h, v1.8b \n" + "uxtl v2.8h, v2.8b \n" + "sqdmulh v0.8h, v0.8h, v4.8h \n" // b * scale + "sqdmulh v1.8h, v1.8h, v4.8h \n" // g + "sqdmulh v2.8h, v2.8h, v4.8h \n" // r + "mul v0.8h, v0.8h, v5.8h \n" // b * interval_size + "mul v1.8h, v1.8h, v5.8h \n" // g + "mul v2.8h, v2.8h, v5.8h \n" // r + "add v0.8h, v0.8h, v6.8h \n" // b + interval_offset + "add v1.8h, v1.8h, v6.8h \n" // g + "add v2.8h, v2.8h, v6.8h \n" // r + "uqxtn v0.8b, v0.8h \n" + "uqxtn v1.8b, v1.8h \n" + "uqxtn v2.8b, v2.8h \n" + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(dst_argb), // %0 "+r"(width) // %1 : "r"(scale), // %2 @@ -2300,28 +2491,29 @@ void ARGBShadeRow_NEON(const uint8_t* src_argb, int width, uint32_t value) { asm volatile( - "dup v0.4s, %w3 \n" // duplicate scale value. - "zip1 v0.8b, v0.8b, v0.8b \n" // v0.8b aarrggbb. - "ushr v0.8h, v0.8h, #1 \n" // scale / 2. + "dup v0.4s, %w3 \n" // duplicate scale value. + "zip1 v0.8b, v0.8b, v0.8b \n" // v0.8b aarrggbb. + "ushr v0.8h, v0.8h, #1 \n" // scale / 2. // 8 pixel loop. "1: \n" - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "uxtl v4.8h, v4.8b \n" // b (0 .. 255) - "uxtl v5.8h, v5.8b \n" - "uxtl v6.8h, v6.8b \n" - "uxtl v7.8h, v7.8b \n" - "sqrdmulh v4.8h, v4.8h, v0.h[0] \n" // b * scale * 2 - "sqrdmulh v5.8h, v5.8h, v0.h[1] \n" // g - "sqrdmulh v6.8h, v6.8h, v0.h[2] \n" // r - "sqrdmulh v7.8h, v7.8h, v0.h[3] \n" // a - "uqxtn v4.8b, v4.8h \n" - "uqxtn v5.8b, v5.8h \n" - "uqxtn v6.8b, v6.8h \n" - "uqxtn v7.8b, v7.8h \n" - "st4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%0], #32 \n" // load 8 ARGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "uxtl v4.8h, v4.8b \n" // b (0 .. 255) + "uxtl v5.8h, v5.8b \n" + "uxtl v6.8h, v6.8b \n" + "uxtl v7.8h, v7.8b \n" + "sqrdmulh v4.8h, v4.8h, v0.h[0] \n" // b * scale * 2 + "sqrdmulh v5.8h, v5.8h, v0.h[1] \n" // g + "sqrdmulh v6.8h, v6.8h, v0.h[2] \n" // r + "sqrdmulh v7.8h, v7.8h, v0.h[3] \n" // a + "uqxtn v4.8b, v4.8h \n" + "uqxtn v5.8b, v5.8h \n" + "uqxtn v6.8b, v6.8h \n" + "uqxtn v7.8b, v7.8h \n" + "st4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -2334,20 +2526,21 @@ void ARGBShadeRow_NEON(const uint8_t* src_argb, // C code is (29 * b + 150 * g + 77 * r + 128) >> 8; void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { asm volatile( - "movi v24.8b, #29 \n" // B * 0.1140 coefficient - "movi v25.8b, #150 \n" // G * 0.5870 coefficient - "movi v26.8b, #77 \n" // R * 0.2990 coefficient + "movi v24.8b, #29 \n" // B * 0.1140 coefficient + "movi v25.8b, #150 \n" // G * 0.5870 coefficient + "movi v26.8b, #77 \n" // R * 0.2990 coefficient "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v4.8h, v0.8b, v24.8b \n" // B - "umlal v4.8h, v1.8b, v25.8b \n" // G - "umlal v4.8h, v2.8b, v26.8b \n" // R - "uqrshrn v0.8b, v4.8h, #8 \n" // 16 bit to 8 bit B - "orr v1.8b, v0.8b, v0.8b \n" // G - "orr v2.8b, v0.8b, v0.8b \n" // R - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 pixels. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "umull v4.8h, v0.8b, v24.8b \n" // B + "umlal v4.8h, v1.8b, v25.8b \n" // G + "umlal v4.8h, v2.8b, v26.8b \n" // R + "uqrshrn v0.8b, v4.8h, #8 \n" // 16 bit to 8 bit B + "orr v1.8b, v0.8b, v0.8b \n" // G + "orr v2.8b, v0.8b, v0.8b \n" // R + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 pixels. + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -2362,32 +2555,33 @@ void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { void ARGBSepiaRow_NEON(uint8_t* dst_argb, int width) { asm volatile( - "movi v20.8b, #17 \n" // BB coefficient - "movi v21.8b, #68 \n" // BG coefficient - "movi v22.8b, #35 \n" // BR coefficient - "movi v24.8b, #22 \n" // GB coefficient - "movi v25.8b, #88 \n" // GG coefficient - "movi v26.8b, #45 \n" // GR coefficient - "movi v28.8b, #24 \n" // BB coefficient - "movi v29.8b, #98 \n" // BG coefficient - "movi v30.8b, #50 \n" // BR coefficient + "movi v20.8b, #17 \n" // BB coefficient + "movi v21.8b, #68 \n" // BG coefficient + "movi v22.8b, #35 \n" // BR coefficient + "movi v24.8b, #22 \n" // GB coefficient + "movi v25.8b, #88 \n" // GG coefficient + "movi v26.8b, #45 \n" // GR coefficient + "movi v28.8b, #24 \n" // BB coefficient + "movi v29.8b, #98 \n" // BG coefficient + "movi v30.8b, #50 \n" // BR coefficient "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0] \n" // load 8 ARGB pixels. - "subs %w1, %w1, #8 \n" // 8 processed per loop. - "umull v4.8h, v0.8b, v20.8b \n" // B to Sepia B - "umlal v4.8h, v1.8b, v21.8b \n" // G - "umlal v4.8h, v2.8b, v22.8b \n" // R - "umull v5.8h, v0.8b, v24.8b \n" // B to Sepia G - "umlal v5.8h, v1.8b, v25.8b \n" // G - "umlal v5.8h, v2.8b, v26.8b \n" // R - "umull v6.8h, v0.8b, v28.8b \n" // B to Sepia R - "umlal v6.8h, v1.8b, v29.8b \n" // G - "umlal v6.8h, v2.8b, v30.8b \n" // R - "uqshrn v0.8b, v4.8h, #7 \n" // 16 bit to 8 bit B - "uqshrn v1.8b, v5.8h, #7 \n" // 16 bit to 8 bit G - "uqshrn v2.8b, v6.8h, #7 \n" // 16 bit to 8 bit R - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // store 8 pixels. - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0] \n" // load 8 ARGB pixels. + "prfm pldl1keep, [%0, 448] \n" + "subs %w1, %w1, #8 \n" // 8 processed per loop. + "umull v4.8h, v0.8b, v20.8b \n" // B to Sepia B + "umlal v4.8h, v1.8b, v21.8b \n" // G + "umlal v4.8h, v2.8b, v22.8b \n" // R + "umull v5.8h, v0.8b, v24.8b \n" // B to Sepia G + "umlal v5.8h, v1.8b, v25.8b \n" // G + "umlal v5.8h, v2.8b, v26.8b \n" // R + "umull v6.8h, v0.8b, v28.8b \n" // B to Sepia R + "umlal v6.8h, v1.8b, v29.8b \n" // G + "umlal v6.8h, v2.8b, v30.8b \n" // R + "uqshrn v0.8b, v4.8h, #7 \n" // 16 bit to 8 bit B + "uqshrn v1.8b, v5.8h, #7 \n" // 16 bit to 8 bit G + "uqshrn v2.8b, v6.8h, #7 \n" // 16 bit to 8 bit R + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // store 8 pixels. + "b.gt 1b \n" : "+r"(dst_argb), // %0 "+r"(width) // %1 : @@ -2403,51 +2597,52 @@ void ARGBColorMatrixRow_NEON(const uint8_t* src_argb, const int8_t* matrix_argb, int width) { asm volatile( - "ld1 {v2.16b}, [%3] \n" // load 3 ARGB vectors. - "sxtl v0.8h, v2.8b \n" // B,G coefficients s16. - "sxtl2 v1.8h, v2.16b \n" // R,A coefficients s16. + "ld1 {v2.16b}, [%3] \n" // load 3 ARGB vectors. + "sxtl v0.8h, v2.8b \n" // B,G coefficients s16. + "sxtl2 v1.8h, v2.16b \n" // R,A coefficients s16. "1: \n" - "ld4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "uxtl v16.8h, v16.8b \n" // b (0 .. 255) 16 bit - "uxtl v17.8h, v17.8b \n" // g - "uxtl v18.8h, v18.8b \n" // r - "uxtl v19.8h, v19.8b \n" // a - "mul v22.8h, v16.8h, v0.h[0] \n" // B = B * Matrix B - "mul v23.8h, v16.8h, v0.h[4] \n" // G = B * Matrix G - "mul v24.8h, v16.8h, v1.h[0] \n" // R = B * Matrix R - "mul v25.8h, v16.8h, v1.h[4] \n" // A = B * Matrix A - "mul v4.8h, v17.8h, v0.h[1] \n" // B += G * Matrix B - "mul v5.8h, v17.8h, v0.h[5] \n" // G += G * Matrix G - "mul v6.8h, v17.8h, v1.h[1] \n" // R += G * Matrix R - "mul v7.8h, v17.8h, v1.h[5] \n" // A += G * Matrix A - "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B - "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G - "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R - "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A - "mul v4.8h, v18.8h, v0.h[2] \n" // B += R * Matrix B - "mul v5.8h, v18.8h, v0.h[6] \n" // G += R * Matrix G - "mul v6.8h, v18.8h, v1.h[2] \n" // R += R * Matrix R - "mul v7.8h, v18.8h, v1.h[6] \n" // A += R * Matrix A - "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B - "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G - "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R - "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A - "mul v4.8h, v19.8h, v0.h[3] \n" // B += A * Matrix B - "mul v5.8h, v19.8h, v0.h[7] \n" // G += A * Matrix G - "mul v6.8h, v19.8h, v1.h[3] \n" // R += A * Matrix R - "mul v7.8h, v19.8h, v1.h[7] \n" // A += A * Matrix A - "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B - "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G - "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R - "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A - "sqshrun v16.8b, v22.8h, #6 \n" // 16 bit to 8 bit B - "sqshrun v17.8b, v23.8h, #6 \n" // 16 bit to 8 bit G - "sqshrun v18.8b, v24.8h, #6 \n" // 16 bit to 8 bit R - "sqshrun v19.8b, v25.8h, #6 \n" // 16 bit to 8 bit A - "st4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%1], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%0], #32 \n" // load 8 ARGB + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop. + "uxtl v16.8h, v16.8b \n" // b (0 .. 255) 16 bit + "uxtl v17.8h, v17.8b \n" // g + "uxtl v18.8h, v18.8b \n" // r + "uxtl v19.8h, v19.8b \n" // a + "mul v22.8h, v16.8h, v0.h[0] \n" // B = B * Matrix B + "mul v23.8h, v16.8h, v0.h[4] \n" // G = B * Matrix G + "mul v24.8h, v16.8h, v1.h[0] \n" // R = B * Matrix R + "mul v25.8h, v16.8h, v1.h[4] \n" // A = B * Matrix A + "mul v4.8h, v17.8h, v0.h[1] \n" // B += G * Matrix B + "mul v5.8h, v17.8h, v0.h[5] \n" // G += G * Matrix G + "mul v6.8h, v17.8h, v1.h[1] \n" // R += G * Matrix R + "mul v7.8h, v17.8h, v1.h[5] \n" // A += G * Matrix A + "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B + "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G + "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R + "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A + "mul v4.8h, v18.8h, v0.h[2] \n" // B += R * Matrix B + "mul v5.8h, v18.8h, v0.h[6] \n" // G += R * Matrix G + "mul v6.8h, v18.8h, v1.h[2] \n" // R += R * Matrix R + "mul v7.8h, v18.8h, v1.h[6] \n" // A += R * Matrix A + "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B + "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G + "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R + "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A + "mul v4.8h, v19.8h, v0.h[3] \n" // B += A * Matrix B + "mul v5.8h, v19.8h, v0.h[7] \n" // G += A * Matrix G + "mul v6.8h, v19.8h, v1.h[3] \n" // R += A * Matrix R + "mul v7.8h, v19.8h, v1.h[7] \n" // A += A * Matrix A + "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B + "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G + "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R + "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A + "sqshrun v16.8b, v22.8h, #6 \n" // 16 bit to 8 bit B + "sqshrun v17.8b, v23.8h, #6 \n" // 16 bit to 8 bit G + "sqshrun v18.8b, v24.8h, #6 \n" // 16 bit to 8 bit R + "sqshrun v19.8b, v25.8h, #6 \n" // 16 bit to 8 bit A + "st4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%1], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(width) // %2 @@ -2465,19 +2660,21 @@ void ARGBMultiplyRow_NEON(const uint8_t* src_argb0, asm volatile( // 8 pixel loop. "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "umull v0.8h, v0.8b, v4.8b \n" // multiply B - "umull v1.8h, v1.8b, v5.8b \n" // multiply G - "umull v2.8h, v2.8b, v6.8b \n" // multiply R - "umull v3.8h, v3.8b, v7.8b \n" // multiply A - "rshrn v0.8b, v0.8h, #8 \n" // 16 bit to 8 bit B - "rshrn v1.8b, v1.8h, #8 \n" // 16 bit to 8 bit G - "rshrn v2.8b, v2.8h, #8 \n" // 16 bit to 8 bit R - "rshrn v3.8b, v3.8h, #8 \n" // 16 bit to 8 bit A - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "umull v0.8h, v0.8b, v4.8b \n" // multiply B + "umull v1.8h, v1.8b, v5.8b \n" // multiply G + "umull v2.8h, v2.8b, v6.8b \n" // multiply R + "umull v3.8h, v3.8b, v7.8b \n" // multiply A + "rshrn v0.8b, v0.8h, #8 \n" // 16 bit to 8 bit B + "rshrn v1.8b, v1.8h, #8 \n" // 16 bit to 8 bit G + "rshrn v2.8b, v2.8h, #8 \n" // 16 bit to 8 bit R + "rshrn v3.8b, v3.8h, #8 \n" // 16 bit to 8 bit A + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -2494,15 +2691,17 @@ void ARGBAddRow_NEON(const uint8_t* src_argb0, asm volatile( // 8 pixel loop. "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqadd v0.8b, v0.8b, v4.8b \n" - "uqadd v1.8b, v1.8b, v5.8b \n" - "uqadd v2.8b, v2.8b, v6.8b \n" - "uqadd v3.8b, v3.8b, v7.8b \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "uqadd v0.8b, v0.8b, v4.8b \n" + "uqadd v1.8b, v1.8b, v5.8b \n" + "uqadd v2.8b, v2.8b, v6.8b \n" + "uqadd v3.8b, v3.8b, v7.8b \n" + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -2519,15 +2718,17 @@ void ARGBSubtractRow_NEON(const uint8_t* src_argb0, asm volatile( // 8 pixel loop. "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqsub v0.8b, v0.8b, v4.8b \n" - "uqsub v1.8b, v1.8b, v5.8b \n" - "uqsub v2.8b, v2.8b, v6.8b \n" - "uqsub v3.8b, v3.8b, v7.8b \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "uqsub v0.8b, v0.8b, v4.8b \n" + "uqsub v1.8b, v1.8b, v5.8b \n" + "uqsub v2.8b, v2.8b, v6.8b \n" + "uqsub v3.8b, v3.8b, v7.8b \n" + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_argb0), // %0 "+r"(src_argb1), // %1 "+r"(dst_argb), // %2 @@ -2546,17 +2747,19 @@ void SobelRow_NEON(const uint8_t* src_sobelx, uint8_t* dst_argb, int width) { asm volatile( - "movi v3.8b, #255 \n" // alpha + "movi v3.8b, #255 \n" // alpha // 8 pixel loop. "1: \n" - "ld1 {v0.8b}, [%0], #8 \n" // load 8 sobelx. - "ld1 {v1.8b}, [%1], #8 \n" // load 8 sobely. - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqadd v0.8b, v0.8b, v1.8b \n" // add - "orr v1.8b, v0.8b, v0.8b \n" - "orr v2.8b, v0.8b, v0.8b \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld1 {v0.8b}, [%0], #8 \n" // load 8 sobelx. + "ld1 {v1.8b}, [%1], #8 \n" // load 8 sobely. + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "uqadd v0.8b, v0.8b, v1.8b \n" // add + "orr v1.8b, v0.8b, v0.8b \n" + "orr v2.8b, v0.8b, v0.8b \n" + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_argb), // %2 @@ -2573,12 +2776,14 @@ void SobelToPlaneRow_NEON(const uint8_t* src_sobelx, asm volatile( // 16 pixel loop. "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 16 sobelx. - "ld1 {v1.16b}, [%1], #16 \n" // load 16 sobely. - "subs %w3, %w3, #16 \n" // 16 processed per loop. - "uqadd v0.16b, v0.16b, v1.16b \n" // add - "st1 {v0.16b}, [%2], #16 \n" // store 16 pixels. - "b.gt 1b \n" + "ld1 {v0.16b}, [%0], #16 \n" // load 16 sobelx. + "ld1 {v1.16b}, [%1], #16 \n" // load 16 sobely. + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #16 \n" // 16 processed per loop. + "uqadd v0.16b, v0.16b, v1.16b \n" // add + "st1 {v0.16b}, [%2], #16 \n" // store 16 pixels. + "b.gt 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_y), // %2 @@ -2597,15 +2802,17 @@ void SobelXYRow_NEON(const uint8_t* src_sobelx, uint8_t* dst_argb, int width) { asm volatile( - "movi v3.8b, #255 \n" // alpha + "movi v3.8b, #255 \n" // alpha // 8 pixel loop. "1: \n" - "ld1 {v2.8b}, [%0], #8 \n" // load 8 sobelx. - "ld1 {v0.8b}, [%1], #8 \n" // load 8 sobely. - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqadd v1.8b, v0.8b, v2.8b \n" // add - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" + "ld1 {v2.8b}, [%0], #8 \n" // load 8 sobelx. + "ld1 {v0.8b}, [%1], #8 \n" // load 8 sobely. + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "uqadd v1.8b, v0.8b, v2.8b \n" // add + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB + "b.gt 1b \n" : "+r"(src_sobelx), // %0 "+r"(src_sobely), // %1 "+r"(dst_argb), // %2 @@ -2625,23 +2832,26 @@ void SobelXRow_NEON(const uint8_t* src_y0, int width) { asm volatile( "1: \n" - "ld1 {v0.8b}, [%0],%5 \n" // top - "ld1 {v1.8b}, [%0],%6 \n" - "usubl v0.8h, v0.8b, v1.8b \n" - "ld1 {v2.8b}, [%1],%5 \n" // center * 2 - "ld1 {v3.8b}, [%1],%6 \n" - "usubl v1.8h, v2.8b, v3.8b \n" - "add v0.8h, v0.8h, v1.8h \n" - "add v0.8h, v0.8h, v1.8h \n" - "ld1 {v2.8b}, [%2],%5 \n" // bottom - "ld1 {v3.8b}, [%2],%6 \n" - "subs %w4, %w4, #8 \n" // 8 pixels - "usubl v1.8h, v2.8b, v3.8b \n" - "add v0.8h, v0.8h, v1.8h \n" - "abs v0.8h, v0.8h \n" - "uqxtn v0.8b, v0.8h \n" - "st1 {v0.8b}, [%3], #8 \n" // store 8 sobelx - "b.gt 1b \n" + "ld1 {v0.8b}, [%0],%5 \n" // top + "ld1 {v1.8b}, [%0],%6 \n" + "prfm pldl1keep, [%0, 448] \n" + "usubl v0.8h, v0.8b, v1.8b \n" + "ld1 {v2.8b}, [%1],%5 \n" // center * 2 + "ld1 {v3.8b}, [%1],%6 \n" + "prfm pldl1keep, [%1, 448] \n" + "usubl v1.8h, v2.8b, v3.8b \n" + "add v0.8h, v0.8h, v1.8h \n" + "add v0.8h, v0.8h, v1.8h \n" + "ld1 {v2.8b}, [%2],%5 \n" // bottom + "ld1 {v3.8b}, [%2],%6 \n" + "prfm pldl1keep, [%2, 448] \n" + "subs %w4, %w4, #8 \n" // 8 pixels + "usubl v1.8h, v2.8b, v3.8b \n" + "add v0.8h, v0.8h, v1.8h \n" + "abs v0.8h, v0.8h \n" + "uqxtn v0.8b, v0.8h \n" + "st1 {v0.8b}, [%3], #8 \n" // store 8 sobelx + "b.gt 1b \n" : "+r"(src_y0), // %0 "+r"(src_y1), // %1 "+r"(src_y2), // %2 @@ -2663,23 +2873,25 @@ void SobelYRow_NEON(const uint8_t* src_y0, int width) { asm volatile( "1: \n" - "ld1 {v0.8b}, [%0],%4 \n" // left - "ld1 {v1.8b}, [%1],%4 \n" - "usubl v0.8h, v0.8b, v1.8b \n" - "ld1 {v2.8b}, [%0],%4 \n" // center * 2 - "ld1 {v3.8b}, [%1],%4 \n" - "usubl v1.8h, v2.8b, v3.8b \n" - "add v0.8h, v0.8h, v1.8h \n" - "add v0.8h, v0.8h, v1.8h \n" - "ld1 {v2.8b}, [%0],%5 \n" // right - "ld1 {v3.8b}, [%1],%5 \n" - "subs %w3, %w3, #8 \n" // 8 pixels - "usubl v1.8h, v2.8b, v3.8b \n" - "add v0.8h, v0.8h, v1.8h \n" - "abs v0.8h, v0.8h \n" - "uqxtn v0.8b, v0.8h \n" - "st1 {v0.8b}, [%2], #8 \n" // store 8 sobely - "b.gt 1b \n" + "ld1 {v0.8b}, [%0],%4 \n" // left + "ld1 {v1.8b}, [%1],%4 \n" + "usubl v0.8h, v0.8b, v1.8b \n" + "ld1 {v2.8b}, [%0],%4 \n" // center * 2 + "ld1 {v3.8b}, [%1],%4 \n" + "usubl v1.8h, v2.8b, v3.8b \n" + "add v0.8h, v0.8h, v1.8h \n" + "add v0.8h, v0.8h, v1.8h \n" + "ld1 {v2.8b}, [%0],%5 \n" // right + "ld1 {v3.8b}, [%1],%5 \n" + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "subs %w3, %w3, #8 \n" // 8 pixels + "usubl v1.8h, v2.8b, v3.8b \n" + "add v0.8h, v0.8h, v1.8h \n" + "abs v0.8h, v0.8h \n" + "uqxtn v0.8b, v0.8h \n" + "st1 {v0.8b}, [%2], #8 \n" // store 8 sobely + "b.gt 1b \n" : "+r"(src_y0), // %0 "+r"(src_y1), // %1 "+r"(dst_sobely), // %2 @@ -2697,16 +2909,17 @@ void HalfFloat1Row_NEON(const uint16_t* src, int width) { asm volatile( "1: \n" - "ld1 {v1.16b}, [%0], #16 \n" // load 8 shorts - "subs %w2, %w2, #8 \n" // 8 pixels per loop - "uxtl v2.4s, v1.4h \n" // 8 int's - "uxtl2 v3.4s, v1.8h \n" - "scvtf v2.4s, v2.4s \n" // 8 floats - "scvtf v3.4s, v3.4s \n" - "fcvtn v1.4h, v2.4s \n" // 8 half floats - "fcvtn2 v1.8h, v3.4s \n" - "st1 {v1.16b}, [%1], #16 \n" // store 8 shorts - "b.gt 1b \n" + "ld1 {v1.16b}, [%0], #16 \n" // load 8 shorts + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 pixels per loop + "uxtl v2.4s, v1.4h \n" // 8 int's + "uxtl2 v3.4s, v1.8h \n" + "scvtf v2.4s, v2.4s \n" // 8 floats + "scvtf v3.4s, v3.4s \n" + "fcvtn v1.4h, v2.4s \n" // 8 half floats + "fcvtn2 v1.8h, v3.4s \n" + "st1 {v1.16b}, [%1], #16 \n" // store 8 shorts + "b.gt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -2720,18 +2933,19 @@ void HalfFloatRow_NEON(const uint16_t* src, int width) { asm volatile( "1: \n" - "ld1 {v1.16b}, [%0], #16 \n" // load 8 shorts - "subs %w2, %w2, #8 \n" // 8 pixels per loop - "uxtl v2.4s, v1.4h \n" // 8 int's - "uxtl2 v3.4s, v1.8h \n" - "scvtf v2.4s, v2.4s \n" // 8 floats - "scvtf v3.4s, v3.4s \n" - "fmul v2.4s, v2.4s, %3.s[0] \n" // adjust exponent - "fmul v3.4s, v3.4s, %3.s[0] \n" - "uqshrn v1.4h, v2.4s, #13 \n" // isolate halffloat - "uqshrn2 v1.8h, v3.4s, #13 \n" - "st1 {v1.16b}, [%1], #16 \n" // store 8 shorts - "b.gt 1b \n" + "ld1 {v1.16b}, [%0], #16 \n" // load 8 shorts + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 pixels per loop + "uxtl v2.4s, v1.4h \n" // 8 int's + "uxtl2 v3.4s, v1.8h \n" + "scvtf v2.4s, v2.4s \n" // 8 floats + "scvtf v3.4s, v3.4s \n" + "fmul v2.4s, v2.4s, %3.s[0] \n" // adjust exponent + "fmul v3.4s, v3.4s, %3.s[0] \n" + "uqshrn v1.4h, v2.4s, #13 \n" // isolate halffloat + "uqshrn2 v1.8h, v3.4s, #13 \n" + "st1 {v1.16b}, [%1], #16 \n" // store 8 shorts + "b.gt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -2745,17 +2959,18 @@ void ByteToFloatRow_NEON(const uint8_t* src, int width) { asm volatile( "1: \n" - "ld1 {v1.8b}, [%0], #8 \n" // load 8 bytes - "subs %w2, %w2, #8 \n" // 8 pixels per loop - "uxtl v1.8h, v1.8b \n" // 8 shorts - "uxtl v2.4s, v1.4h \n" // 8 ints - "uxtl2 v3.4s, v1.8h \n" - "scvtf v2.4s, v2.4s \n" // 8 floats - "scvtf v3.4s, v3.4s \n" - "fmul v2.4s, v2.4s, %3.s[0] \n" // scale - "fmul v3.4s, v3.4s, %3.s[0] \n" - "st1 {v2.16b, v3.16b}, [%1], #32 \n" // store 8 floats - "b.gt 1b \n" + "ld1 {v1.8b}, [%0], #8 \n" // load 8 bytes + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 pixels per loop + "uxtl v1.8h, v1.8b \n" // 8 shorts + "uxtl v2.4s, v1.4h \n" // 8 ints + "uxtl2 v3.4s, v1.8h \n" + "scvtf v2.4s, v2.4s \n" // 8 floats + "scvtf v3.4s, v3.4s \n" + "fmul v2.4s, v2.4s, %3.s[0] \n" // scale + "fmul v3.4s, v3.4s, %3.s[0] \n" + "st1 {v2.16b, v3.16b}, [%1], #32 \n" // store 8 floats + "b.gt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -2769,20 +2984,21 @@ float ScaleMaxSamples_NEON(const float* src, int width) { float fmax; asm volatile( - "movi v5.4s, #0 \n" // max - "movi v6.4s, #0 \n" + "movi v5.4s, #0 \n" // max + "movi v6.4s, #0 \n" "1: \n" - "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples - "subs %w2, %w2, #8 \n" // 8 processed per loop - "fmul v3.4s, v1.4s, %4.s[0] \n" // scale - "fmul v4.4s, v2.4s, %4.s[0] \n" // scale - "fmax v5.4s, v5.4s, v1.4s \n" // max - "fmax v6.4s, v6.4s, v2.4s \n" - "st1 {v3.4s, v4.4s}, [%1], #32 \n" // store 8 samples - "b.gt 1b \n" - "fmax v5.4s, v5.4s, v6.4s \n" // max - "fmaxv %s3, v5.4s \n" // signed max acculator + "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop + "fmul v3.4s, v1.4s, %4.s[0] \n" // scale + "fmul v4.4s, v2.4s, %4.s[0] \n" // scale + "fmax v5.4s, v5.4s, v1.4s \n" // max + "fmax v6.4s, v6.4s, v2.4s \n" + "st1 {v3.4s, v4.4s}, [%1], #32 \n" // store 8 samples + "b.gt 1b \n" + "fmax v5.4s, v5.4s, v6.4s \n" // max + "fmaxv %s3, v5.4s \n" // signed max acculator : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width), // %2 @@ -2798,21 +3014,22 @@ float ScaleSumSamples_NEON(const float* src, int width) { float fsum; asm volatile( - "movi v5.4s, #0 \n" // max - "movi v6.4s, #0 \n" // max + "movi v5.4s, #0 \n" // max + "movi v6.4s, #0 \n" // max "1: \n" - "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples - "subs %w2, %w2, #8 \n" // 8 processed per loop - "fmul v3.4s, v1.4s, %4.s[0] \n" // scale - "fmul v4.4s, v2.4s, %4.s[0] \n" - "fmla v5.4s, v1.4s, v1.4s \n" // sum of squares - "fmla v6.4s, v2.4s, v2.4s \n" - "st1 {v3.4s, v4.4s}, [%1], #32 \n" // store 8 samples - "b.gt 1b \n" - "faddp v5.4s, v5.4s, v6.4s \n" - "faddp v5.4s, v5.4s, v5.4s \n" - "faddp %3.4s, v5.4s, v5.4s \n" // sum + "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop + "fmul v3.4s, v1.4s, %4.s[0] \n" // scale + "fmul v4.4s, v2.4s, %4.s[0] \n" + "fmla v5.4s, v1.4s, v1.4s \n" // sum of squares + "fmla v6.4s, v2.4s, v2.4s \n" + "st1 {v3.4s, v4.4s}, [%1], #32 \n" // store 8 samples + "b.gt 1b \n" + "faddp v5.4s, v5.4s, v6.4s \n" + "faddp v5.4s, v5.4s, v5.4s \n" + "faddp %3.4s, v5.4s, v5.4s \n" // sum : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width), // %2 @@ -2825,12 +3042,13 @@ float ScaleSumSamples_NEON(const float* src, void ScaleSamples_NEON(const float* src, float* dst, float scale, int width) { asm volatile( "1: \n" - "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples - "subs %w2, %w2, #8 \n" // 8 processed per loop - "fmul v1.4s, v1.4s, %3.s[0] \n" // scale - "fmul v2.4s, v2.4s, %3.s[0] \n" // scale - "st1 {v1.4s, v2.4s}, [%1], #32 \n" // store 8 samples - "b.gt 1b \n" + "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop + "fmul v1.4s, v1.4s, %3.s[0] \n" // scale + "fmul v2.4s, v2.4s, %3.s[0] \n" // scale + "st1 {v1.4s, v2.4s}, [%1], #32 \n" // store 8 samples + "b.gt 1b \n" : "+r"(src), // %0 "+r"(dst), // %1 "+r"(width) // %2 @@ -2847,26 +3065,31 @@ void GaussCol_NEON(const uint16_t* src0, uint32_t* dst, int width) { asm volatile( - "movi v6.8h, #4 \n" // constant 4 - "movi v7.8h, #6 \n" // constant 6 + "movi v6.8h, #4 \n" // constant 4 + "movi v7.8h, #6 \n" // constant 6 "1: \n" - "ld1 {v1.8h}, [%0], #16 \n" // load 8 samples, 5 rows - "ld1 {v2.8h}, [%4], #16 \n" - "uaddl v0.4s, v1.4h, v2.4h \n" // * 1 - "uaddl2 v1.4s, v1.8h, v2.8h \n" // * 1 - "ld1 {v2.8h}, [%1], #16 \n" - "umlal v0.4s, v2.4h, v6.4h \n" // * 4 - "umlal2 v1.4s, v2.8h, v6.8h \n" // * 4 - "ld1 {v2.8h}, [%2], #16 \n" - "umlal v0.4s, v2.4h, v7.4h \n" // * 6 - "umlal2 v1.4s, v2.8h, v7.8h \n" // * 6 - "ld1 {v2.8h}, [%3], #16 \n" - "umlal v0.4s, v2.4h, v6.4h \n" // * 4 - "umlal2 v1.4s, v2.8h, v6.8h \n" // * 4 - "subs %w6, %w6, #8 \n" // 8 processed per loop - "st1 {v0.4s,v1.4s}, [%5], #32 \n" // store 8 samples - "b.gt 1b \n" + "ld1 {v1.8h}, [%0], #16 \n" // load 8 samples, 5 rows + "ld1 {v2.8h}, [%4], #16 \n" + "uaddl v0.4s, v1.4h, v2.4h \n" // * 1 + "prfm pldl1keep, [%0, 448] \n" + "uaddl2 v1.4s, v1.8h, v2.8h \n" // * 1 + "ld1 {v2.8h}, [%1], #16 \n" + "umlal v0.4s, v2.4h, v6.4h \n" // * 4 + "prfm pldl1keep, [%1, 448] \n" + "umlal2 v1.4s, v2.8h, v6.8h \n" // * 4 + "ld1 {v2.8h}, [%2], #16 \n" + "umlal v0.4s, v2.4h, v7.4h \n" // * 6 + "prfm pldl1keep, [%2, 448] \n" + "umlal2 v1.4s, v2.8h, v7.8h \n" // * 6 + "ld1 {v2.8h}, [%3], #16 \n" + "umlal v0.4s, v2.4h, v6.4h \n" // * 4 + "prfm pldl1keep, [%3, 448] \n" + "umlal2 v1.4s, v2.8h, v6.8h \n" // * 4 + "subs %w6, %w6, #8 \n" // 8 processed per loop + "st1 {v0.4s,v1.4s}, [%5], #32 \n" // store 8 samples + "prfm pldl1keep, [%4, 448] \n" + "b.gt 1b \n" : "+r"(src0), // %0 "+r"(src1), // %1 "+r"(src2), // %2 @@ -2884,27 +3107,28 @@ void GaussRow_NEON(const uint32_t* src, uint16_t* dst, int width) { const uint32_t* src2 = src + 2; const uint32_t* src3 = src + 3; asm volatile( - "movi v6.4s, #4 \n" // constant 4 - "movi v7.4s, #6 \n" // constant 6 + "movi v6.4s, #4 \n" // constant 4 + "movi v7.4s, #6 \n" // constant 6 "1: \n" - "ld1 {v0.4s,v1.4s,v2.4s}, [%0], %6 \n" // load 12 source samples - "add v0.4s, v0.4s, v1.4s \n" // * 1 - "add v1.4s, v1.4s, v2.4s \n" // * 1 - "ld1 {v2.4s,v3.4s}, [%2], #32 \n" - "mla v0.4s, v2.4s, v7.4s \n" // * 6 - "mla v1.4s, v3.4s, v7.4s \n" // * 6 - "ld1 {v2.4s,v3.4s}, [%1], #32 \n" - "ld1 {v4.4s,v5.4s}, [%3], #32 \n" - "add v2.4s, v2.4s, v4.4s \n" // add rows for * 4 - "add v3.4s, v3.4s, v5.4s \n" - "mla v0.4s, v2.4s, v6.4s \n" // * 4 - "mla v1.4s, v3.4s, v6.4s \n" // * 4 - "subs %w5, %w5, #8 \n" // 8 processed per loop - "uqrshrn v0.4h, v0.4s, #8 \n" // round and pack - "uqrshrn2 v0.8h, v1.4s, #8 \n" - "st1 {v0.8h}, [%4], #16 \n" // store 8 samples - "b.gt 1b \n" + "ld1 {v0.4s,v1.4s,v2.4s}, [%0], %6 \n" // load 12 source samples + "add v0.4s, v0.4s, v1.4s \n" // * 1 + "add v1.4s, v1.4s, v2.4s \n" // * 1 + "ld1 {v2.4s,v3.4s}, [%2], #32 \n" + "mla v0.4s, v2.4s, v7.4s \n" // * 6 + "mla v1.4s, v3.4s, v7.4s \n" // * 6 + "ld1 {v2.4s,v3.4s}, [%1], #32 \n" + "ld1 {v4.4s,v5.4s}, [%3], #32 \n" + "add v2.4s, v2.4s, v4.4s \n" // add rows for * 4 + "add v3.4s, v3.4s, v5.4s \n" + "prfm pldl1keep, [%0, 448] \n" + "mla v0.4s, v2.4s, v6.4s \n" // * 4 + "mla v1.4s, v3.4s, v6.4s \n" // * 4 + "subs %w5, %w5, #8 \n" // 8 processed per loop + "uqrshrn v0.4h, v0.4s, #8 \n" // round and pack + "uqrshrn2 v0.8h, v1.4s, #8 \n" + "st1 {v0.8h}, [%4], #16 \n" // store 8 samples + "b.gt 1b \n" : "+r"(src), // %0 "+r"(src1), // %1 "+r"(src2), // %2 @@ -2915,6 +3139,87 @@ void GaussRow_NEON(const uint32_t* src, uint16_t* dst, int width) { : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); } +static const vecf32 kGaussCoefficients = {4.0f, 6.0f, 1.0f / 256.0f, 0.0f}; + +// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. +void GaussCol_F32_NEON(const float* src0, + const float* src1, + const float* src2, + const float* src3, + const float* src4, + float* dst, + int width) { + asm volatile( + "ld2r {v6.4s, v7.4s}, [%7] \n" // constants 4 and 6 + + "1: \n" + "ld1 {v0.4s, v1.4s}, [%0], #32 \n" // load 8 samples, 5 rows + "ld1 {v2.4s, v3.4s}, [%1], #32 \n" + "fmla v0.4s, v2.4s, v6.4s \n" // * 4 + "ld1 {v4.4s, v5.4s}, [%2], #32 \n" + "fmla v1.4s, v3.4s, v6.4s \n" + "prfm pldl1keep, [%0, 448] \n" + "fmla v0.4s, v4.4s, v7.4s \n" // * 6 + "ld1 {v2.4s, v3.4s}, [%3], #32 \n" + "fmla v1.4s, v5.4s, v7.4s \n" + "prfm pldl1keep, [%1, 448] \n" + "fmla v0.4s, v2.4s, v6.4s \n" // * 4 + "ld1 {v4.4s, v5.4s}, [%4], #32 \n" + "fmla v1.4s, v3.4s, v6.4s \n" + "prfm pldl1keep, [%2, 448] \n" + "fadd v0.4s, v0.4s, v4.4s \n" // * 1 + "prfm pldl1keep, [%3, 448] \n" + "fadd v1.4s, v1.4s, v5.4s \n" + "prfm pldl1keep, [%4, 448] \n" + "subs %w6, %w6, #8 \n" // 8 processed per loop + "st1 {v0.4s, v1.4s}, [%5], #32 \n" // store 8 samples + "b.gt 1b \n" + : "+r"(src0), // %0 + "+r"(src1), // %1 + "+r"(src2), // %2 + "+r"(src3), // %3 + "+r"(src4), // %4 + "+r"(dst), // %5 + "+r"(width) // %6 + : "r"(&kGaussCoefficients) // %7 + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); +} + +// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. +void GaussRow_F32_NEON(const float* src, float* dst, int width) { + asm volatile( + "ld3r {v6.4s, v7.4s, v8.4s}, [%3] \n" // constants 4, 6, 1/256 + + "1: \n" + "ld1 {v0.4s, v1.4s, v2.4s}, [%0], %4 \n" // load 12 samples, 5 + // rows + "fadd v0.4s, v0.4s, v1.4s \n" // * 1 + "ld1 {v4.4s, v5.4s}, [%0], %5 \n" + "fadd v1.4s, v1.4s, v2.4s \n" + "fmla v0.4s, v4.4s, v7.4s \n" // * 6 + "ld1 {v2.4s, v3.4s}, [%0], %4 \n" + "fmla v1.4s, v5.4s, v7.4s \n" + "ld1 {v4.4s, v5.4s}, [%0], %6 \n" + "fadd v2.4s, v2.4s, v4.4s \n" + "fadd v3.4s, v3.4s, v5.4s \n" + "fmla v0.4s, v2.4s, v6.4s \n" // * 4 + "fmla v1.4s, v3.4s, v6.4s \n" + "prfm pldl1keep, [%0, 448] \n" + "fmul v0.4s, v0.4s, v8.4s \n" // / 256 + "fmul v1.4s, v1.4s, v8.4s \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop + "st1 {v0.4s, v1.4s}, [%1], #32 \n" // store 8 samples + "b.gt 1b \n" + : "+r"(src), // %0 + "+r"(dst), // %1 + "+r"(width) // %2 + : "r"(&kGaussCoefficients), // %3 + "r"(8LL), // %4 + "r"(-4LL), // %5 + "r"(20LL) // %6 + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8"); +} + // Convert biplanar NV21 to packed YUV24 void NV21ToYUV24Row_NEON(const uint8_t* src_y, const uint8_t* src_vu, @@ -2922,13 +3227,15 @@ void NV21ToYUV24Row_NEON(const uint8_t* src_y, int width) { asm volatile( "1: \n" - "ld1 {v2.16b}, [%0], #16 \n" // load 16 Y values - "ld2 {v0.8b, v1.8b}, [%1], #16 \n" // load 8 VU values - "zip1 v0.16b, v0.16b, v0.16b \n" // replicate V values - "zip1 v1.16b, v1.16b, v1.16b \n" // replicate U values - "subs %w3, %w3, #16 \n" // 16 pixels per loop - "st3 {v0.16b,v1.16b,v2.16b}, [%2], #48 \n" // store 16 YUV pixels - "b.gt 1b \n" + "ld1 {v2.16b}, [%0], #16 \n" // load 16 Y values + "ld2 {v0.8b, v1.8b}, [%1], #16 \n" // load 8 VU values + "prfm pldl1keep, [%0, 448] \n" + "prfm pldl1keep, [%1, 448] \n" + "zip1 v0.16b, v0.16b, v0.16b \n" // replicate V values + "zip1 v1.16b, v1.16b, v1.16b \n" // replicate U values + "subs %w3, %w3, #16 \n" // 16 pixels per loop + "st3 {v0.16b,v1.16b,v2.16b}, [%2], #48 \n" // store 16 YUV pixels + "b.gt 1b \n" : "+r"(src_y), // %0 "+r"(src_vu), // %1 "+r"(dst_yuv24), // %2 @@ -2945,17 +3252,19 @@ void AYUVToUVRow_NEON(const uint8_t* src_ayuv, asm volatile( "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 ayuv - "uaddlp v0.8h, v0.16b \n" // V 16 bytes -> 8 shorts. - "uaddlp v1.8h, v1.16b \n" // U 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 - "uadalp v0.8h, v4.16b \n" // V 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // U 16 bytes -> 8 shorts. - "uqrshrn v3.8b, v0.8h, #2 \n" // 2x2 average - "uqrshrn v2.8b, v1.8h, #2 \n" - "subs %w3, %w3, #16 \n" // 16 processed per loop. - "st2 {v2.8b,v3.8b}, [%2], #16 \n" // store 8 pixels UV. - "b.gt 1b \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 ayuv + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v0.8h, v0.16b \n" // V 16 bytes -> 8 shorts. + "uaddlp v1.8h, v1.16b \n" // U 16 bytes -> 8 shorts. + "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 + "prfm pldl1keep, [%1, 448] \n" + "uadalp v0.8h, v4.16b \n" // V 16 bytes -> 8 shorts. + "uadalp v1.8h, v5.16b \n" // U 16 bytes -> 8 shorts. + "uqrshrn v3.8b, v0.8h, #2 \n" // 2x2 average + "uqrshrn v2.8b, v1.8h, #2 \n" + "subs %w3, %w3, #16 \n" // 16 processed per loop. + "st2 {v2.8b,v3.8b}, [%2], #16 \n" // store 8 pixels UV. + "b.gt 1b \n" : "+r"(src_ayuv), // %0 "+r"(src_ayuv_1), // %1 "+r"(dst_uv), // %2 @@ -2972,18 +3281,19 @@ void AYUVToVURow_NEON(const uint8_t* src_ayuv, asm volatile( "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 - // pixels. - "uaddlp v0.8h, v0.16b \n" // V 16 bytes -> 8 shorts. - "uaddlp v1.8h, v1.16b \n" // U 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 - "uadalp v0.8h, v4.16b \n" // V 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // U 16 bytes -> 8 shorts. - "uqrshrn v0.8b, v0.8h, #2 \n" // 2x2 average - "uqrshrn v1.8b, v1.8h, #2 \n" - "subs %w3, %w3, #16 \n" // 16 processed per loop. - "st2 {v0.8b,v1.8b}, [%2], #16 \n" // store 8 pixels VU. - "b.gt 1b \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 ayuv + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v0.8h, v0.16b \n" // V 16 bytes -> 8 shorts. + "uaddlp v1.8h, v1.16b \n" // U 16 bytes -> 8 shorts. + "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 + "prfm pldl1keep, [%1, 448] \n" + "uadalp v0.8h, v4.16b \n" // V 16 bytes -> 8 shorts. + "uadalp v1.8h, v5.16b \n" // U 16 bytes -> 8 shorts. + "uqrshrn v0.8b, v0.8h, #2 \n" // 2x2 average + "uqrshrn v1.8b, v1.8h, #2 \n" + "subs %w3, %w3, #16 \n" // 16 processed per loop. + "st2 {v0.8b,v1.8b}, [%2], #16 \n" // store 8 pixels VU. + "b.gt 1b \n" : "+r"(src_ayuv), // %0 "+r"(src_ayuv_1), // %1 "+r"(dst_vu), // %2 @@ -2996,11 +3306,11 @@ void AYUVToVURow_NEON(const uint8_t* src_ayuv, void AYUVToYRow_NEON(const uint8_t* src_ayuv, uint8_t* dst_y, int width) { asm volatile( "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 - // pixels - "subs %w2, %w2, #16 \n" // 16 pixels per loop - "st1 {v2.16b}, [%1], #16 \n" // store 16 Y pixels - "b.gt 1b \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #16 \n" // 16 pixels per loop + "st1 {v2.16b}, [%1], #16 \n" // store 16 Y pixels + "b.gt 1b \n" : "+r"(src_ayuv), // %0 "+r"(dst_y), // %1 "+r"(width) // %2 @@ -3008,22 +3318,67 @@ void AYUVToYRow_NEON(const uint8_t* src_ayuv, uint8_t* dst_y, int width) { : "cc", "memory", "v0", "v1", "v2", "v3"); } +// Shuffle table for swapping UV bytes. +static const uvec8 kShuffleSwapUV = {1u, 0u, 3u, 2u, 5u, 4u, 7u, 6u, + 9u, 8u, 11u, 10u, 13u, 12u, 15u, 14u}; + // Convert UV plane of NV12 to VU of NV21. void SwapUVRow_NEON(const uint8_t* src_uv, uint8_t* dst_vu, int width) { asm volatile( + "ld1 {v2.16b}, [%3] \n" // shuffler "1: \n" - "ld2 {v0.16b, v1.16b}, [%0], #32 \n" // load 16 UV values - "orr v2.16b, v0.16b, v0.16b \n" // move U after V - "subs %w2, %w2, #16 \n" // 16 pixels per loop - "st2 {v1.16b, v2.16b}, [%1], #32 \n" // store 16 VU pixels - "b.gt 1b \n" - : "+r"(src_uv), // %0 - "+r"(dst_vu), // %1 - "+r"(width) // %2 - : + "ld1 {v0.16b}, [%0], 16 \n" // load 16 UV values + "ld1 {v1.16b}, [%0], 16 \n" + "prfm pldl1keep, [%0, 448] \n" + "subs %w2, %w2, #16 \n" // 16 pixels per loop + "tbl v0.16b, {v0.16b}, v2.16b \n" + "tbl v1.16b, {v1.16b}, v2.16b \n" + "stp q0, q1, [%1], 32 \n" // store 16 VU pixels + "b.gt 1b \n" + : "+r"(src_uv), // %0 + "+r"(dst_vu), // %1 + "+r"(width) // %2 + : "r"(&kShuffleSwapUV) // %3 : "cc", "memory", "v0", "v1", "v2"); } +void HalfMergeUVRow_NEON(const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_uv, + int width) { + const uint8_t* src_u_1 = src_u + src_stride_u; + const uint8_t* src_v_1 = src_v + src_stride_v; + asm volatile( + "1: \n" + "ld1 {v0.16b}, [%0], #16 \n" // load 16 U values + "ld1 {v1.16b}, [%2], #16 \n" // load 16 V values + "ld1 {v2.16b}, [%1], #16 \n" + "ld1 {v3.16b}, [%3], #16 \n" + "uaddlp v0.8h, v0.16b \n" // half size + "prfm pldl1keep, [%0, 448] \n" + "uaddlp v1.8h, v1.16b \n" + "prfm pldl1keep, [%2, 448] \n" + "uadalp v0.8h, v2.16b \n" + "prfm pldl1keep, [%1, 448] \n" + "uadalp v1.8h, v3.16b \n" + "prfm pldl1keep, [%3, 448] \n" + "uqrshrn v0.8b, v0.8h, #2 \n" + "uqrshrn v1.8b, v1.8h, #2 \n" + "subs %w5, %w5, #16 \n" // 16 src pixels per loop + "st2 {v0.8b, v1.8b}, [%4], #16 \n" // store 8 UV pixels + "b.gt 1b \n" + : "+r"(src_u), // %0 + "+r"(src_u_1), // %1 + "+r"(src_v), // %2 + "+r"(src_v_1), // %3 + "+r"(dst_uv), // %4 + "+r"(width) // %5 + : + : "cc", "memory", "v0", "v1", "v2", "v3"); +} + #endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) #ifdef __cplusplus diff --git a/TMessagesProj/jni/third_party/libyuv/source/row_win.cc b/TMessagesProj/jni/third_party/libyuv/source/row_win.cc index f976d4026..9afcf060a 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/row_win.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/row_win.cc @@ -2898,10 +2898,12 @@ __declspec(naked) void I422ToRGBARow_SSSE3( } #endif // HAS_I422TOARGBROW_SSSE3 +// I400ToARGBRow_SSE2 is disabled due to new yuvconstant parameter #ifdef HAS_I400TOARGBROW_SSE2 // 8 pixels of Y converted to 8 pixels of ARGB (32 bytes). __declspec(naked) void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* rgb_buf, + const struct YuvConstants*, int width) { __asm { mov eax, 0x4a354a35 // 4a35 = 18997 = round(1.164 * 64 * 256) @@ -2949,6 +2951,7 @@ __declspec(naked) void I400ToARGBRow_SSE2(const uint8_t* y_buf, // note: vpunpcklbw mutates and vpackuswb unmutates. __declspec(naked) void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* rgb_buf, + const struct YuvConstants*, int width) { __asm { mov eax, 0x4a354a35 // 4a35 = 18997 = round(1.164 * 64 * 256) @@ -3045,15 +3048,15 @@ __declspec(naked) void MirrorRow_AVX2(const uint8_t* src, } #endif // HAS_MIRRORROW_AVX2 -#ifdef HAS_MIRRORUVROW_SSSE3 +#ifdef HAS_MIRRORSPLITUVROW_SSSE3 // Shuffle table for reversing the bytes of UV channels. static const uvec8 kShuffleMirrorUV = {14u, 12u, 10u, 8u, 6u, 4u, 2u, 0u, 15u, 13u, 11u, 9u, 7u, 5u, 3u, 1u}; -__declspec(naked) void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { +__declspec(naked) void MirrorSplitUVRow_SSSE3(const uint8_t* src, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { __asm { push edi mov eax, [esp + 4 + 4] // src @@ -3078,7 +3081,7 @@ __declspec(naked) void MirrorUVRow_SSSE3(const uint8_t* src, ret } } -#endif // HAS_MIRRORUVROW_SSSE3 +#endif // HAS_MIRRORSPLITUVROW_SSSE3 #ifdef HAS_ARGBMIRRORROW_SSE2 __declspec(naked) void ARGBMirrorRow_SSE2(const uint8_t* src, diff --git a/TMessagesProj/jni/third_party/libyuv/source/scale.cc b/TMessagesProj/jni/third_party/libyuv/source/scale.cc index 5034c5032..cf3c03325 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/scale.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/scale.cc @@ -17,6 +17,7 @@ #include "libyuv/planar_functions.h" // For CopyPlane #include "libyuv/row.h" #include "libyuv/scale_row.h" +#include "libyuv/scale_uv.h" // For UVScale #ifdef __cplusplus namespace libyuv { @@ -103,21 +104,6 @@ static void ScalePlaneDown2(int src_width, } } #endif -#if defined(HAS_SCALEROWDOWN2_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleRowDown2 = - filtering == kFilterNone - ? ScaleRowDown2_Any_MSA - : (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_MSA - : ScaleRowDown2Box_Any_MSA); - if (IS_ALIGNED(dst_width, 32)) { - ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_MSA - : (filtering == kFilterLinear - ? ScaleRowDown2Linear_MSA - : ScaleRowDown2Box_MSA); - } - } -#endif #if defined(HAS_SCALEROWDOWN2_MMI) if (TestCpuFlag(kCpuHasMMI)) { ScaleRowDown2 = @@ -133,6 +119,21 @@ static void ScalePlaneDown2(int src_width, } } #endif +#if defined(HAS_SCALEROWDOWN2_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleRowDown2 = + filtering == kFilterNone + ? ScaleRowDown2_Any_MSA + : (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_MSA + : ScaleRowDown2Box_Any_MSA); + if (IS_ALIGNED(dst_width, 32)) { + ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_MSA + : (filtering == kFilterLinear + ? ScaleRowDown2Linear_MSA + : ScaleRowDown2Box_MSA); + } + } +#endif if (filtering == kFilterLinear) { src_stride = 0; @@ -255,15 +256,6 @@ static void ScalePlaneDown4(int src_width, } } #endif -#if defined(HAS_SCALEROWDOWN4_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleRowDown4 = - filtering ? ScaleRowDown4Box_Any_MSA : ScaleRowDown4_Any_MSA; - if (IS_ALIGNED(dst_width, 16)) { - ScaleRowDown4 = filtering ? ScaleRowDown4Box_MSA : ScaleRowDown4_MSA; - } - } -#endif #if defined(HAS_SCALEROWDOWN4_MMI) if (TestCpuFlag(kCpuHasMMI)) { ScaleRowDown4 = @@ -273,6 +265,15 @@ static void ScalePlaneDown4(int src_width, } } #endif +#if defined(HAS_SCALEROWDOWN4_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleRowDown4 = + filtering ? ScaleRowDown4Box_Any_MSA : ScaleRowDown4_Any_MSA; + if (IS_ALIGNED(dst_width, 16)) { + ScaleRowDown4 = filtering ? ScaleRowDown4Box_MSA : ScaleRowDown4_MSA; + } + } +#endif if (filtering == kFilterLinear) { src_stride = 0; @@ -378,6 +379,18 @@ static void ScalePlaneDown34(int src_width, } } #endif +#if defined(HAS_SCALEROWDOWN34_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + if (!filtering) { + ScaleRowDown34_0 = ScaleRowDown34_Any_MMI; + ScaleRowDown34_1 = ScaleRowDown34_Any_MMI; + if (dst_width % 24 == 0) { + ScaleRowDown34_0 = ScaleRowDown34_MMI; + ScaleRowDown34_1 = ScaleRowDown34_MMI; + } + } + } +#endif #if defined(HAS_SCALEROWDOWN34_MSA) if (TestCpuFlag(kCpuHasMSA)) { if (!filtering) { @@ -398,18 +411,6 @@ static void ScalePlaneDown34(int src_width, } } #endif -#if defined(HAS_SCALEROWDOWN34_MMI) - if (TestCpuFlag(kCpuHasMMI)) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_Any_MMI; - ScaleRowDown34_1 = ScaleRowDown34_Any_MMI; - if (dst_width % 24 == 0) { - ScaleRowDown34_0 = ScaleRowDown34_MMI; - ScaleRowDown34_1 = ScaleRowDown34_MMI; - } - } - } -#endif #if defined(HAS_SCALEROWDOWN34_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { if (!filtering) { @@ -890,14 +891,6 @@ static void ScalePlaneBox(int src_width, } } #endif -#if defined(HAS_SCALEADDROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleAddRow = ScaleAddRow_Any_MSA; - if (IS_ALIGNED(src_width, 16)) { - ScaleAddRow = ScaleAddRow_MSA; - } - } -#endif #if defined(HAS_SCALEADDROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { ScaleAddRow = ScaleAddRow_Any_MMI; @@ -906,6 +899,14 @@ static void ScalePlaneBox(int src_width, } } #endif +#if defined(HAS_SCALEADDROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleAddRow = ScaleAddRow_Any_MSA; + if (IS_ALIGNED(src_width, 16)) { + ScaleAddRow = ScaleAddRow_MSA; + } + } +#endif for (j = 0; j < dst_height; ++j) { int boxheight; @@ -1042,14 +1043,6 @@ void ScalePlaneBilinearDown(int src_width, } } #endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(src_width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif #if defined(HAS_INTERPOLATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { InterpolateRow = InterpolateRow_Any_MMI; @@ -1058,6 +1051,14 @@ void ScalePlaneBilinearDown(int src_width, } } #endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(src_width, 32)) { + InterpolateRow = InterpolateRow_MSA; + } + } +#endif #if defined(HAS_SCALEFILTERCOLS_SSSE3) if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { @@ -1670,7 +1671,7 @@ void ScalePlane_16(const uint16_t* src, } if (dst_width == src_width && filtering != kFilterBox) { int dy = FixedDiv(src_height, dst_height); - // Arbitrary scale vertically, but unscaled vertically. + // Arbitrary scale vertically, but unscaled horizontally. ScalePlaneVertical_16(src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, 0, 0, dy, 1, filtering); return; @@ -1869,6 +1870,40 @@ int I444Scale_16(const uint16_t* src_y, return 0; } +// Scale an NV12 image. +// This function in turn calls a scaling function for each plane. + +LIBYUV_API +int NV12Scale(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_uv, + int src_stride_uv, + int src_width, + int src_height, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_uv, + int dst_stride_uv, + int dst_width, + int dst_height, + enum FilterMode filtering) { + int src_halfwidth = SUBSAMPLE(src_width, 1, 1); + int src_halfheight = SUBSAMPLE(src_height, 1, 1); + int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); + int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); + if (!src_y || !src_uv || src_width == 0 || src_height == 0 || + src_width > 32768 || src_height > 32768 || !dst_y || !dst_uv || + dst_width <= 0 || dst_height <= 0) { + return -1; + } + + ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, + dst_width, dst_height, filtering); + UVScale(src_uv, src_stride_uv, src_halfwidth, src_halfheight, dst_uv, + dst_stride_uv, dst_halfwidth, dst_halfheight, filtering); + return 0; +} + // Deprecated api LIBYUV_API int Scale(const uint8_t* src_y, diff --git a/TMessagesProj/jni/third_party/libyuv/source/scale_any.cc b/TMessagesProj/jni/third_party/libyuv/source/scale_any.cc index d780cb1ff..c93d70c5f 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/scale_any.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/scale_any.cc @@ -20,49 +20,6 @@ namespace libyuv { extern "C" { #endif -// Definition for ScaleFilterCols, ScaleARGBCols and ScaleARGBFilterCols -#define CANY(NAMEANY, TERP_SIMD, TERP_C, BPP, MASK) \ - void NAMEANY(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, \ - int dx) { \ - int r = dst_width & MASK; \ - int n = dst_width & ~MASK; \ - if (n > 0) { \ - TERP_SIMD(dst_ptr, src_ptr, n, x, dx); \ - } \ - TERP_C(dst_ptr + n * BPP, src_ptr, r, x + n * dx, dx); \ - } - -#ifdef HAS_SCALEFILTERCOLS_NEON -CANY(ScaleFilterCols_Any_NEON, ScaleFilterCols_NEON, ScaleFilterCols_C, 1, 7) -#endif -#ifdef HAS_SCALEFILTERCOLS_MSA -CANY(ScaleFilterCols_Any_MSA, ScaleFilterCols_MSA, ScaleFilterCols_C, 1, 15) -#endif -#ifdef HAS_SCALEARGBCOLS_NEON -CANY(ScaleARGBCols_Any_NEON, ScaleARGBCols_NEON, ScaleARGBCols_C, 4, 7) -#endif -#ifdef HAS_SCALEARGBCOLS_MSA -CANY(ScaleARGBCols_Any_MSA, ScaleARGBCols_MSA, ScaleARGBCols_C, 4, 3) -#endif -#ifdef HAS_SCALEARGBCOLS_MMI -CANY(ScaleARGBCols_Any_MMI, ScaleARGBCols_MMI, ScaleARGBCols_C, 4, 0) -#endif -#ifdef HAS_SCALEARGBFILTERCOLS_NEON -CANY(ScaleARGBFilterCols_Any_NEON, - ScaleARGBFilterCols_NEON, - ScaleARGBFilterCols_C, - 4, - 3) -#endif -#ifdef HAS_SCALEARGBFILTERCOLS_MSA -CANY(ScaleARGBFilterCols_Any_MSA, - ScaleARGBFilterCols_MSA, - ScaleARGBFilterCols_C, - 4, - 7) -#endif -#undef CANY - // Fixed scale down. // Mask may be non-power of 2, so use MOD #define SDANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \ @@ -113,6 +70,22 @@ SDODD(ScaleRowDown2Box_Odd_SSSE3, 1, 15) #endif +#ifdef HAS_SCALEUVROWDOWN2BOX_SSSE3 +SDANY(ScaleUVRowDown2Box_Any_SSSE3, + ScaleUVRowDown2Box_SSSE3, + ScaleUVRowDown2Box_C, + 2, + 2, + 4) +#endif +#ifdef HAS_SCALEUVROWDOWN2BOX_AVX2 +SDANY(ScaleUVRowDown2Box_Any_AVX2, + ScaleUVRowDown2Box_AVX2, + ScaleUVRowDown2Box_C, + 2, + 2, + 8) +#endif #ifdef HAS_SCALEROWDOWN2_AVX2 SDANY(ScaleRowDown2_Any_AVX2, ScaleRowDown2_AVX2, ScaleRowDown2_C, 2, 1, 31) SDANY(ScaleRowDown2Linear_Any_AVX2, @@ -155,6 +128,15 @@ SDODD(ScaleRowDown2Box_Odd_NEON, 1, 15) #endif +#ifdef HAS_SCALEUVROWDOWN2BOX_NEON +SDANY(ScaleUVRowDown2Box_Any_NEON, + ScaleUVRowDown2Box_NEON, + ScaleUVRowDown2Box_C, + 2, + 2, + 8) +#endif + #ifdef HAS_SCALEROWDOWN2_MSA SDANY(ScaleRowDown2_Any_MSA, ScaleRowDown2_MSA, ScaleRowDown2_C, 2, 1, 31) SDANY(ScaleRowDown2Linear_Any_MSA, @@ -508,6 +490,13 @@ SDAANY(ScaleARGBRowDownEvenBox_Any_MMI, 4, 1) #endif +#ifdef HAS_SCALEUVROWDOWNEVEN_NEON +SDAANY(ScaleUVRowDownEven_Any_NEON, + ScaleUVRowDownEven_NEON, + ScaleUVRowDownEven_C, + 2, + 3) +#endif #ifdef SASIMDONLY // This also works and uses memcpy and SIMD instead of C, but is slower on ARM @@ -577,6 +566,49 @@ SAANY(ScaleAddRow_Any_MMI, ScaleAddRow_MMI, ScaleAddRow_C, 7) #endif // SASIMDONLY +// Definition for ScaleFilterCols, ScaleARGBCols and ScaleARGBFilterCols +#define CANY(NAMEANY, TERP_SIMD, TERP_C, BPP, MASK) \ + void NAMEANY(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, \ + int dx) { \ + int r = dst_width & MASK; \ + int n = dst_width & ~MASK; \ + if (n > 0) { \ + TERP_SIMD(dst_ptr, src_ptr, n, x, dx); \ + } \ + TERP_C(dst_ptr + n * BPP, src_ptr, r, x + n * dx, dx); \ + } + +#ifdef HAS_SCALEFILTERCOLS_NEON +CANY(ScaleFilterCols_Any_NEON, ScaleFilterCols_NEON, ScaleFilterCols_C, 1, 7) +#endif +#ifdef HAS_SCALEFILTERCOLS_MSA +CANY(ScaleFilterCols_Any_MSA, ScaleFilterCols_MSA, ScaleFilterCols_C, 1, 15) +#endif +#ifdef HAS_SCALEARGBCOLS_NEON +CANY(ScaleARGBCols_Any_NEON, ScaleARGBCols_NEON, ScaleARGBCols_C, 4, 7) +#endif +#ifdef HAS_SCALEARGBCOLS_MSA +CANY(ScaleARGBCols_Any_MSA, ScaleARGBCols_MSA, ScaleARGBCols_C, 4, 3) +#endif +#ifdef HAS_SCALEARGBCOLS_MMI +CANY(ScaleARGBCols_Any_MMI, ScaleARGBCols_MMI, ScaleARGBCols_C, 4, 0) +#endif +#ifdef HAS_SCALEARGBFILTERCOLS_NEON +CANY(ScaleARGBFilterCols_Any_NEON, + ScaleARGBFilterCols_NEON, + ScaleARGBFilterCols_C, + 4, + 3) +#endif +#ifdef HAS_SCALEARGBFILTERCOLS_MSA +CANY(ScaleARGBFilterCols_Any_MSA, + ScaleARGBFilterCols_MSA, + ScaleARGBFilterCols_C, + 4, + 7) +#endif +#undef CANY + #ifdef __cplusplus } // extern "C" } // namespace libyuv diff --git a/TMessagesProj/jni/third_party/libyuv/source/scale_argb.cc b/TMessagesProj/jni/third_party/libyuv/source/scale_argb.cc index 58aa5ebbe..451d4ec4d 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/scale_argb.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/scale_argb.cc @@ -95,22 +95,6 @@ static void ScaleARGBDown2(int src_width, } } #endif -#if defined(HAS_SCALEARGBROWDOWN2_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBRowDown2 = - filtering == kFilterNone - ? ScaleARGBRowDown2_Any_MSA - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_Any_MSA - : ScaleARGBRowDown2Box_Any_MSA); - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBRowDown2 = - filtering == kFilterNone - ? ScaleARGBRowDown2_MSA - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_MSA - : ScaleARGBRowDown2Box_MSA); - } - } -#endif #if defined(HAS_SCALEARGBROWDOWN2_MMI) if (TestCpuFlag(kCpuHasMMI)) { ScaleARGBRowDown2 = @@ -127,6 +111,22 @@ static void ScaleARGBDown2(int src_width, } } #endif +#if defined(HAS_SCALEARGBROWDOWN2_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleARGBRowDown2 = + filtering == kFilterNone + ? ScaleARGBRowDown2_Any_MSA + : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_Any_MSA + : ScaleARGBRowDown2Box_Any_MSA); + if (IS_ALIGNED(dst_width, 4)) { + ScaleARGBRowDown2 = + filtering == kFilterNone + ? ScaleARGBRowDown2_MSA + : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_MSA + : ScaleARGBRowDown2Box_MSA); + } + } +#endif if (filtering == kFilterLinear) { src_stride = 0; @@ -243,16 +243,6 @@ static void ScaleARGBDownEven(int src_width, } } #endif -#if defined(HAS_SCALEARGBROWDOWNEVEN_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_Any_MSA - : ScaleARGBRowDownEven_Any_MSA; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBRowDownEven = - filtering ? ScaleARGBRowDownEvenBox_MSA : ScaleARGBRowDownEven_MSA; - } - } -#endif #if defined(HAS_SCALEARGBROWDOWNEVEN_MMI) if (TestCpuFlag(kCpuHasMMI)) { ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_Any_MMI @@ -263,6 +253,16 @@ static void ScaleARGBDownEven(int src_width, } } #endif +#if defined(HAS_SCALEARGBROWDOWNEVEN_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_Any_MSA + : ScaleARGBRowDownEven_Any_MSA; + if (IS_ALIGNED(dst_width, 4)) { + ScaleARGBRowDownEven = + filtering ? ScaleARGBRowDownEvenBox_MSA : ScaleARGBRowDownEven_MSA; + } + } +#endif if (filtering == kFilterLinear) { src_stride = 0; @@ -436,14 +436,6 @@ static void ScaleARGBBilinearUp(int src_width, } } #endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(dst_width, 8)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif #if defined(HAS_INTERPOLATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { InterpolateRow = InterpolateRow_Any_MMI; @@ -451,6 +443,14 @@ static void ScaleARGBBilinearUp(int src_width, InterpolateRow = InterpolateRow_MMI; } } +#endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(dst_width, 8)) { + InterpolateRow = InterpolateRow_MSA; + } + } #endif if (src_width >= 32768) { ScaleARGBFilterCols = @@ -490,14 +490,6 @@ static void ScaleARGBBilinearUp(int src_width, } } #endif -#if defined(HAS_SCALEARGBCOLS_MSA) - if (!filtering && TestCpuFlag(kCpuHasMSA)) { - ScaleARGBFilterCols = ScaleARGBCols_Any_MSA; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBFilterCols = ScaleARGBCols_MSA; - } - } -#endif #if defined(HAS_SCALEARGBCOLS_MMI) if (!filtering && TestCpuFlag(kCpuHasMMI)) { ScaleARGBFilterCols = ScaleARGBCols_Any_MMI; @@ -505,6 +497,14 @@ static void ScaleARGBBilinearUp(int src_width, ScaleARGBFilterCols = ScaleARGBCols_MMI; } } +#endif +#if defined(HAS_SCALEARGBCOLS_MSA) + if (!filtering && TestCpuFlag(kCpuHasMSA)) { + ScaleARGBFilterCols = ScaleARGBCols_Any_MSA; + if (IS_ALIGNED(dst_width, 4)) { + ScaleARGBFilterCols = ScaleARGBCols_MSA; + } + } #endif if (!filtering && src_width * 2 == dst_width && x < 0x8000) { ScaleARGBFilterCols = ScaleARGBColsUp2_C; @@ -619,14 +619,6 @@ static void ScaleYUVToARGBBilinearUp(int src_width, } } #endif -#if defined(HAS_I422TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGBRow = I422ToARGBRow_Any_MSA; - if (IS_ALIGNED(src_width, 8)) { - I422ToARGBRow = I422ToARGBRow_MSA; - } - } -#endif #if defined(HAS_I422TOARGBROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { I422ToARGBRow = I422ToARGBRow_Any_MMI; @@ -635,6 +627,14 @@ static void ScaleYUVToARGBBilinearUp(int src_width, } } #endif +#if defined(HAS_I422TOARGBROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + I422ToARGBRow = I422ToARGBRow_Any_MSA; + if (IS_ALIGNED(src_width, 8)) { + I422ToARGBRow = I422ToARGBRow_MSA; + } + } +#endif void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, ptrdiff_t src_stride, int dst_width, @@ -713,14 +713,6 @@ static void ScaleYUVToARGBBilinearUp(int src_width, } } #endif -#if defined(HAS_SCALEARGBCOLS_MSA) - if (!filtering && TestCpuFlag(kCpuHasMSA)) { - ScaleARGBFilterCols = ScaleARGBCols_Any_MSA; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBFilterCols = ScaleARGBCols_MSA; - } - } -#endif #if defined(HAS_SCALEARGBCOLS_MMI) if (!filtering && TestCpuFlag(kCpuHasMMI)) { ScaleARGBFilterCols = ScaleARGBCols_Any_MMI; @@ -728,6 +720,14 @@ static void ScaleYUVToARGBBilinearUp(int src_width, ScaleARGBFilterCols = ScaleARGBCols_MMI; } } +#endif +#if defined(HAS_SCALEARGBCOLS_MSA) + if (!filtering && TestCpuFlag(kCpuHasMSA)) { + ScaleARGBFilterCols = ScaleARGBCols_Any_MSA; + if (IS_ALIGNED(dst_width, 4)) { + ScaleARGBFilterCols = ScaleARGBCols_MSA; + } + } #endif if (!filtering && src_width * 2 == dst_width && x < 0x8000) { ScaleARGBFilterCols = ScaleARGBColsUp2_C; @@ -857,14 +857,6 @@ static void ScaleARGBSimple(int src_width, } } #endif -#if defined(HAS_SCALEARGBCOLS_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBCols = ScaleARGBCols_Any_MSA; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBCols = ScaleARGBCols_MSA; - } - } -#endif #if defined(HAS_SCALEARGBCOLS_MMI) if (TestCpuFlag(kCpuHasMMI)) { ScaleARGBCols = ScaleARGBCols_Any_MMI; @@ -872,6 +864,14 @@ static void ScaleARGBSimple(int src_width, ScaleARGBCols = ScaleARGBCols_MMI; } } +#endif +#if defined(HAS_SCALEARGBCOLS_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleARGBCols = ScaleARGBCols_Any_MSA; + if (IS_ALIGNED(dst_width, 4)) { + ScaleARGBCols = ScaleARGBCols_MSA; + } + } #endif if (src_width * 2 == dst_width && x < 0x8000) { ScaleARGBCols = ScaleARGBColsUp2_C; @@ -981,7 +981,7 @@ static void ScaleARGB(const uint8_t* src, } } if (dx == 0x10000 && (x & 0xffff) == 0) { - // Arbitrary scale vertically, but unscaled vertically. + // Arbitrary scale vertically, but unscaled horizontally. ScalePlaneVertical(src_height, clip_width, clip_height, src_stride, dst_stride, src, dst, x, y, dy, 4, filtering); return; diff --git a/TMessagesProj/jni/third_party/libyuv/source/scale_common.cc b/TMessagesProj/jni/third_party/libyuv/source/scale_common.cc index 636902717..fd4cbd038 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/scale_common.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/scale_common.cc @@ -776,6 +776,8 @@ void ScaleAddRow_16_C(const uint16_t* src_ptr, } } +// ARGB scale row functions + void ScaleARGBRowDown2_C(const uint8_t* src_argb, ptrdiff_t src_stride, uint8_t* dst_argb, @@ -1018,6 +1020,235 @@ void ScaleARGBFilterCols64_C(uint8_t* dst_argb, #undef BLENDERC #undef BLENDER +// UV scale row functions +// same as ARGB but 2 channels + +void ScaleUVRowDown2_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width) { + const uint16_t* src = (const uint16_t*)(src_uv); + uint16_t* dst = (uint16_t*)(dst_uv); + int x; + (void)src_stride; + for (x = 0; x < dst_width - 1; x += 2) { + dst[0] = src[1]; + dst[1] = src[3]; + src += 2; + dst += 2; + } + if (dst_width & 1) { + dst[0] = src[1]; + } +} + +void ScaleUVRowDown2Linear_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width) { + int x; + (void)src_stride; + for (x = 0; x < dst_width; ++x) { + dst_uv[0] = (src_uv[0] + src_uv[2] + 1) >> 1; + dst_uv[1] = (src_uv[1] + src_uv[3] + 1) >> 1; + src_uv += 4; + dst_uv += 2; + } +} + +void ScaleUVRowDown2Box_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + uint8_t* dst_uv, + int dst_width) { + int x; + for (x = 0; x < dst_width; ++x) { + dst_uv[0] = (src_uv[0] + src_uv[2] + src_uv[src_stride] + + src_uv[src_stride + 2] + 2) >> + 2; + dst_uv[1] = (src_uv[1] + src_uv[3] + src_uv[src_stride + 1] + + src_uv[src_stride + 3] + 2) >> + 2; + src_uv += 4; + dst_uv += 2; + } +} + +void ScaleUVRowDownEven_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width) { + const uint16_t* src = (const uint16_t*)(src_uv); + uint16_t* dst = (uint16_t*)(dst_uv); + (void)src_stride; + int x; + for (x = 0; x < dst_width - 1; x += 2) { + dst[0] = src[0]; + dst[1] = src[src_stepx]; + src += src_stepx * 2; + dst += 2; + } + if (dst_width & 1) { + dst[0] = src[0]; + } +} + +void ScaleUVRowDownEvenBox_C(const uint8_t* src_uv, + ptrdiff_t src_stride, + int src_stepx, + uint8_t* dst_uv, + int dst_width) { + int x; + for (x = 0; x < dst_width; ++x) { + dst_uv[0] = (src_uv[0] + src_uv[2] + src_uv[src_stride] + + src_uv[src_stride + 2] + 2) >> + 2; + dst_uv[1] = (src_uv[1] + src_uv[3] + src_uv[src_stride + 1] + + src_uv[src_stride + 3] + 2) >> + 2; + src_uv += src_stepx * 2; + dst_uv += 2; + } +} + +// Scales a single row of pixels using point sampling. +void ScaleUVCols_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x, + int dx) { + const uint16_t* src = (const uint16_t*)(src_uv); + uint16_t* dst = (uint16_t*)(dst_uv); + int j; + for (j = 0; j < dst_width - 1; j += 2) { + dst[0] = src[x >> 16]; + x += dx; + dst[1] = src[x >> 16]; + x += dx; + dst += 2; + } + if (dst_width & 1) { + dst[0] = src[x >> 16]; + } +} + +void ScaleUVCols64_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x32, + int dx) { + int64_t x = (int64_t)(x32); + const uint16_t* src = (const uint16_t*)(src_uv); + uint16_t* dst = (uint16_t*)(dst_uv); + int j; + for (j = 0; j < dst_width - 1; j += 2) { + dst[0] = src[x >> 16]; + x += dx; + dst[1] = src[x >> 16]; + x += dx; + dst += 2; + } + if (dst_width & 1) { + dst[0] = src[x >> 16]; + } +} + +// Scales a single row of pixels up by 2x using point sampling. +void ScaleUVColsUp2_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x, + int dx) { + const uint16_t* src = (const uint16_t*)(src_uv); + uint16_t* dst = (uint16_t*)(dst_uv); + int j; + (void)x; + (void)dx; + for (j = 0; j < dst_width - 1; j += 2) { + dst[1] = dst[0] = src[0]; + src += 1; + dst += 2; + } + if (dst_width & 1) { + dst[0] = src[0]; + } +} + +// TODO(fbarchard): Replace 0x7f ^ f with 128-f. bug=607. +// Mimics SSSE3 blender +#define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b)*f) >> 7 +#define BLENDERC(a, b, f, s) \ + (uint16_t)(BLENDER1(((a) >> s) & 255, ((b) >> s) & 255, f) << s) +#define BLENDER(a, b, f) BLENDERC(a, b, f, 8) | BLENDERC(a, b, f, 0) + +void ScaleUVFilterCols_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x, + int dx) { + const uint16_t* src = (const uint16_t*)(src_uv); + uint16_t* dst = (uint16_t*)(dst_uv); + int j; + for (j = 0; j < dst_width - 1; j += 2) { + int xi = x >> 16; + int xf = (x >> 9) & 0x7f; + uint16_t a = src[xi]; + uint16_t b = src[xi + 1]; + dst[0] = BLENDER(a, b, xf); + x += dx; + xi = x >> 16; + xf = (x >> 9) & 0x7f; + a = src[xi]; + b = src[xi + 1]; + dst[1] = BLENDER(a, b, xf); + x += dx; + dst += 2; + } + if (dst_width & 1) { + int xi = x >> 16; + int xf = (x >> 9) & 0x7f; + uint16_t a = src[xi]; + uint16_t b = src[xi + 1]; + dst[0] = BLENDER(a, b, xf); + } +} + +void ScaleUVFilterCols64_C(uint8_t* dst_uv, + const uint8_t* src_uv, + int dst_width, + int x32, + int dx) { + int64_t x = (int64_t)(x32); + const uint16_t* src = (const uint16_t*)(src_uv); + uint16_t* dst = (uint16_t*)(dst_uv); + int j; + for (j = 0; j < dst_width - 1; j += 2) { + int64_t xi = x >> 16; + int xf = (x >> 9) & 0x7f; + uint16_t a = src[xi]; + uint16_t b = src[xi + 1]; + dst[0] = BLENDER(a, b, xf); + x += dx; + xi = x >> 16; + xf = (x >> 9) & 0x7f; + a = src[xi]; + b = src[xi + 1]; + dst[1] = BLENDER(a, b, xf); + x += dx; + dst += 2; + } + if (dst_width & 1) { + int64_t xi = x >> 16; + int xf = (x >> 9) & 0x7f; + uint16_t a = src[xi]; + uint16_t b = src[xi + 1]; + dst[0] = BLENDER(a, b, xf); + } +} +#undef BLENDER1 +#undef BLENDERC +#undef BLENDER + // Scale plane vertically with bilinear interpolation. void ScalePlaneVertical(int src_height, int dst_width, @@ -1067,14 +1298,6 @@ void ScalePlaneVertical(int src_height, } } #endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(dst_width_bytes, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif #if defined(HAS_INTERPOLATEROW_MMI) if (TestCpuFlag(kCpuHasMMI)) { InterpolateRow = InterpolateRow_Any_MMI; @@ -1082,6 +1305,14 @@ void ScalePlaneVertical(int src_height, InterpolateRow = InterpolateRow_MMI; } } +#endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(dst_width_bytes, 32)) { + InterpolateRow = InterpolateRow_MSA; + } + } #endif for (j = 0; j < dst_height; ++j) { int yi; diff --git a/TMessagesProj/jni/third_party/libyuv/source/scale_gcc.cc b/TMessagesProj/jni/third_party/libyuv/source/scale_gcc.cc index 90a49f30d..e575ee18b 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/scale_gcc.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/scale_gcc.cc @@ -102,16 +102,16 @@ void ScaleRowDown2_SSSE3(const uint8_t* src_ptr, // 16 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "psrlw $0x8,%%xmm0 \n" + "psrlw $0x8,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -125,25 +125,25 @@ void ScaleRowDown2Linear_SSSE3(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrlw $0xf,%%xmm4 \n" - "packuswb %%xmm4,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psrlw $0xf,%%xmm4 \n" + "packuswb %%xmm4,%%xmm4 \n" + "pxor %%xmm5,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pavgw %%xmm5,%%xmm0 \n" - "pavgw %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm1 \n" + "pavgw %%xmm5,%%xmm0 \n" + "pavgw %%xmm5,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -156,33 +156,33 @@ void ScaleRowDown2Box_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrlw $0xf,%%xmm4 \n" - "packuswb %%xmm4,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psrlw $0xf,%%xmm4 \n" + "packuswb %%xmm4,%%xmm4 \n" + "pxor %%xmm5,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%3,1),%%xmm2 \n" - "movdqu 0x10(%0,%3,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm3,%%xmm1 \n" - "psrlw $0x1,%%xmm0 \n" - "psrlw $0x1,%%xmm1 \n" - "pavgw %%xmm5,%%xmm0 \n" - "pavgw %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x00(%0,%3,1),%%xmm2 \n" + "movdqu 0x10(%0,%3,1),%%xmm3 \n" + "lea 0x20(%0),%0 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm1 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm4,%%xmm3 \n" + "paddw %%xmm2,%%xmm0 \n" + "paddw %%xmm3,%%xmm1 \n" + "psrlw $0x1,%%xmm0 \n" + "psrlw $0x1,%%xmm1 \n" + "pavgw %%xmm5,%%xmm0 \n" + "pavgw %%xmm5,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -200,17 +200,17 @@ void ScaleRowDown2_AVX2(const uint8_t* src_ptr, LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpsrlw $0x8,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 @@ -225,26 +225,26 @@ void ScaleRowDown2Linear_AVX2(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpsrlw $0xf,%%ymm4,%%ymm4 \n" - "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" + "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" + "vpsrlw $0xf,%%ymm4,%%ymm4 \n" + "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" + "vpxor %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" - "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" - "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" + "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" + "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 @@ -258,34 +258,34 @@ void ScaleRowDown2Box_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpsrlw $0xf,%%ymm4,%%ymm4 \n" - "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" + "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" + "vpsrlw $0xf,%%ymm4,%%ymm4 \n" + "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" + "vpxor %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" - "vmovdqu 0x20(%0,%3,1),%%ymm3 \n" - "lea 0x40(%0),%0 \n" - "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vpsrlw $0x1,%%ymm0,%%ymm0 \n" - "vpsrlw $0x1,%%ymm1,%%ymm1 \n" - "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" - "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" + "vmovdqu 0x20(%0,%3,1),%%ymm3 \n" + "lea 0x40(%0),%0 \n" + "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" + "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" + "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" + "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" + "vpsrlw $0x1,%%ymm0,%%ymm0 \n" + "vpsrlw $0x1,%%ymm1,%%ymm1 \n" + "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" + "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu %%ymm0,(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 @@ -301,24 +301,24 @@ void ScaleRowDown4_SSSE3(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrld $0x18,%%xmm5 \n" - "pslld $0x10,%%xmm5 \n" + "pcmpeqb %%xmm5,%%xmm5 \n" + "psrld $0x18,%%xmm5 \n" + "pslld $0x10,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "psrlw $0x8,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "pand %%xmm5,%%xmm0 \n" + "pand %%xmm5,%%xmm1 \n" + "packuswb %%xmm1,%%xmm0 \n" + "psrlw $0x8,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movq %%xmm0,(%1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -332,46 +332,46 @@ void ScaleRowDown4Box_SSSE3(const uint8_t* src_ptr, int dst_width) { intptr_t stridex3; asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrlw $0xf,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "packuswb %%xmm4,%%xmm4 \n" - "psllw $0x3,%%xmm5 \n" - "lea 0x00(%4,%4,2),%3 \n" + "pcmpeqb %%xmm4,%%xmm4 \n" + "psrlw $0xf,%%xmm4 \n" + "movdqa %%xmm4,%%xmm5 \n" + "packuswb %%xmm4,%%xmm4 \n" + "psllw $0x3,%%xmm5 \n" + "lea 0x00(%4,%4,2),%3 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%4,1),%%xmm2 \n" - "movdqu 0x10(%0,%4,1),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm3,%%xmm1 \n" - "movdqu 0x00(%0,%4,2),%%xmm2 \n" - "movdqu 0x10(%0,%4,2),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm3,%%xmm1 \n" - "movdqu 0x00(%0,%3,1),%%xmm2 \n" - "movdqu 0x10(%0,%3,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm3,%%xmm1 \n" - "phaddw %%xmm1,%%xmm0 \n" - "paddw %%xmm5,%%xmm0 \n" - "psrlw $0x4,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x00(%0,%4,1),%%xmm2 \n" + "movdqu 0x10(%0,%4,1),%%xmm3 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" + "pmaddubsw %%xmm4,%%xmm1 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm4,%%xmm3 \n" + "paddw %%xmm2,%%xmm0 \n" + "paddw %%xmm3,%%xmm1 \n" + "movdqu 0x00(%0,%4,2),%%xmm2 \n" + "movdqu 0x10(%0,%4,2),%%xmm3 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm4,%%xmm3 \n" + "paddw %%xmm2,%%xmm0 \n" + "paddw %%xmm3,%%xmm1 \n" + "movdqu 0x00(%0,%3,1),%%xmm2 \n" + "movdqu 0x10(%0,%3,1),%%xmm3 \n" + "lea 0x20(%0),%0 \n" + "pmaddubsw %%xmm4,%%xmm2 \n" + "pmaddubsw %%xmm4,%%xmm3 \n" + "paddw %%xmm2,%%xmm0 \n" + "paddw %%xmm3,%%xmm1 \n" + "phaddw %%xmm1,%%xmm0 \n" + "paddw %%xmm5,%%xmm0 \n" + "psrlw $0x4,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movq %%xmm0,(%1) \n" + "lea 0x8(%1),%1 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width), // %2 @@ -387,26 +387,26 @@ void ScaleRowDown4_AVX2(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrld $0x18,%%ymm5,%%ymm5 \n" - "vpslld $0x10,%%ymm5,%%ymm5 \n" + "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" + "vpsrld $0x18,%%ymm5,%%ymm5 \n" + "vpslld $0x10,%%ymm5,%%ymm5 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "lea 0x40(%0),%0 \n" + "vpand %%ymm5,%%ymm0,%%ymm0 \n" + "vpand %%ymm5,%%ymm1,%%ymm1 \n" + "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpsrlw $0x8,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 @@ -420,46 +420,46 @@ void ScaleRowDown4Box_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpsrlw $0xf,%%ymm4,%%ymm4 \n" - "vpsllw $0x3,%%ymm4,%%ymm5 \n" - "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" + "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" + "vpsrlw $0xf,%%ymm4,%%ymm4 \n" + "vpsllw $0x3,%%ymm4,%%ymm5 \n" + "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" - "vmovdqu 0x20(%0,%3,1),%%ymm3 \n" - "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vmovdqu 0x00(%0,%3,2),%%ymm2 \n" - "vmovdqu 0x20(%0,%3,2),%%ymm3 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vmovdqu 0x00(%0,%4,1),%%ymm2 \n" - "vmovdqu 0x20(%0,%4,1),%%ymm3 \n" - "lea 0x40(%0),%0 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" - "vpsrlw $0x4,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm0 \n" + "vmovdqu 0x20(%0),%%ymm1 \n" + "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" + "vmovdqu 0x20(%0,%3,1),%%ymm3 \n" + "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" + "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" + "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" + "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" + "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" + "vmovdqu 0x00(%0,%3,2),%%ymm2 \n" + "vmovdqu 0x20(%0,%3,2),%%ymm3 \n" + "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" + "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" + "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" + "vmovdqu 0x00(%0,%4,1),%%ymm2 \n" + "vmovdqu 0x20(%0,%4,1),%%ymm3 \n" + "lea 0x40(%0),%0 \n" + "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" + "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" + "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" + "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" + "vpsrlw $0x4,%%ymm0,%%ymm0 \n" + "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" + "vpermq $0xd8,%%ymm0,%%ymm0 \n" + "vmovdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 @@ -476,9 +476,9 @@ void ScaleRowDown34_SSSE3(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "movdqa %0,%%xmm3 \n" - "movdqa %1,%%xmm4 \n" - "movdqa %2,%%xmm5 \n" + "movdqa %0,%%xmm3 \n" + "movdqa %1,%%xmm4 \n" + "movdqa %2,%%xmm5 \n" : : "m"(kShuf0), // %0 "m"(kShuf1), // %1 @@ -488,20 +488,20 @@ void ScaleRowDown34_SSSE3(const uint8_t* src_ptr, LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm2 \n" - "lea 0x20(%0),%0 \n" - "movdqa %%xmm2,%%xmm1 \n" - "palignr $0x8,%%xmm0,%%xmm1 \n" - "pshufb %%xmm3,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "pshufb %%xmm5,%%xmm2 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x8(%1) \n" - "movq %%xmm2,0x10(%1) \n" - "lea 0x18(%1),%1 \n" - "sub $0x18,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm2 \n" + "lea 0x20(%0),%0 \n" + "movdqa %%xmm2,%%xmm1 \n" + "palignr $0x8,%%xmm0,%%xmm1 \n" + "pshufb %%xmm3,%%xmm0 \n" + "pshufb %%xmm4,%%xmm1 \n" + "pshufb %%xmm5,%%xmm2 \n" + "movq %%xmm0,(%1) \n" + "movq %%xmm1,0x8(%1) \n" + "movq %%xmm2,0x10(%1) \n" + "lea 0x18(%1),%1 \n" + "sub $0x18,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -514,18 +514,18 @@ void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "movdqa %0,%%xmm2 \n" // kShuf01 - "movdqa %1,%%xmm3 \n" // kShuf11 - "movdqa %2,%%xmm4 \n" // kShuf21 + "movdqa %0,%%xmm2 \n" // kShuf01 + "movdqa %1,%%xmm3 \n" // kShuf11 + "movdqa %2,%%xmm4 \n" // kShuf21 : : "m"(kShuf01), // %0 "m"(kShuf11), // %1 "m"(kShuf21) // %2 ); asm volatile( - "movdqa %0,%%xmm5 \n" // kMadd01 - "movdqa %1,%%xmm0 \n" // kMadd11 - "movdqa %2,%%xmm1 \n" // kRound34 + "movdqa %0,%%xmm5 \n" // kMadd01 + "movdqa %1,%%xmm0 \n" // kMadd11 + "movdqa %2,%%xmm1 \n" // kRound34 : : "m"(kMadd01), // %0 "m"(kMadd11), // %1 @@ -535,37 +535,37 @@ void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr, LABELALIGN "1: \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x00(%0,%3,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm5,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,(%1) \n" - "movdqu 0x8(%0),%%xmm6 \n" - "movdqu 0x8(%0,%3,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm3,%%xmm6 \n" - "pmaddubsw %%xmm0,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,0x8(%1) \n" - "movdqu 0x10(%0),%%xmm6 \n" - "movdqu 0x10(%0,%3,1),%%xmm7 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm4,%%xmm6 \n" - "pmaddubsw %4,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,0x10(%1) \n" - "lea 0x18(%1),%1 \n" - "sub $0x18,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm6 \n" + "movdqu 0x00(%0,%3,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" + "pshufb %%xmm2,%%xmm6 \n" + "pmaddubsw %%xmm5,%%xmm6 \n" + "paddsw %%xmm1,%%xmm6 \n" + "psrlw $0x2,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "movq %%xmm6,(%1) \n" + "movdqu 0x8(%0),%%xmm6 \n" + "movdqu 0x8(%0,%3,1),%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" + "pshufb %%xmm3,%%xmm6 \n" + "pmaddubsw %%xmm0,%%xmm6 \n" + "paddsw %%xmm1,%%xmm6 \n" + "psrlw $0x2,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "movq %%xmm6,0x8(%1) \n" + "movdqu 0x10(%0),%%xmm6 \n" + "movdqu 0x10(%0,%3,1),%%xmm7 \n" + "lea 0x20(%0),%0 \n" + "pavgb %%xmm7,%%xmm6 \n" + "pshufb %%xmm4,%%xmm6 \n" + "pmaddubsw %4,%%xmm6 \n" + "paddsw %%xmm1,%%xmm6 \n" + "psrlw $0x2,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "movq %%xmm6,0x10(%1) \n" + "lea 0x18(%1),%1 \n" + "sub $0x18,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -580,18 +580,18 @@ void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "movdqa %0,%%xmm2 \n" // kShuf01 - "movdqa %1,%%xmm3 \n" // kShuf11 - "movdqa %2,%%xmm4 \n" // kShuf21 + "movdqa %0,%%xmm2 \n" // kShuf01 + "movdqa %1,%%xmm3 \n" // kShuf11 + "movdqa %2,%%xmm4 \n" // kShuf21 : : "m"(kShuf01), // %0 "m"(kShuf11), // %1 "m"(kShuf21) // %2 ); asm volatile( - "movdqa %0,%%xmm5 \n" // kMadd01 - "movdqa %1,%%xmm0 \n" // kMadd11 - "movdqa %2,%%xmm1 \n" // kRound34 + "movdqa %0,%%xmm5 \n" // kMadd01 + "movdqa %1,%%xmm0 \n" // kMadd11 + "movdqa %2,%%xmm1 \n" // kRound34 : : "m"(kMadd01), // %0 "m"(kMadd11), // %1 @@ -602,40 +602,40 @@ void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr, LABELALIGN "1: \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x00(%0,%3,1),%%xmm7 \n" - "pavgb %%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm5,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,(%1) \n" - "movdqu 0x8(%0),%%xmm6 \n" - "movdqu 0x8(%0,%3,1),%%xmm7 \n" - "pavgb %%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm3,%%xmm6 \n" - "pmaddubsw %%xmm0,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,0x8(%1) \n" - "movdqu 0x10(%0),%%xmm6 \n" - "movdqu 0x10(%0,%3,1),%%xmm7 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm4,%%xmm6 \n" - "pmaddubsw %4,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,0x10(%1) \n" - "lea 0x18(%1),%1 \n" - "sub $0x18,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm6 \n" + "movdqu 0x00(%0,%3,1),%%xmm7 \n" + "pavgb %%xmm6,%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" + "pshufb %%xmm2,%%xmm6 \n" + "pmaddubsw %%xmm5,%%xmm6 \n" + "paddsw %%xmm1,%%xmm6 \n" + "psrlw $0x2,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "movq %%xmm6,(%1) \n" + "movdqu 0x8(%0),%%xmm6 \n" + "movdqu 0x8(%0,%3,1),%%xmm7 \n" + "pavgb %%xmm6,%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" + "pshufb %%xmm3,%%xmm6 \n" + "pmaddubsw %%xmm0,%%xmm6 \n" + "paddsw %%xmm1,%%xmm6 \n" + "psrlw $0x2,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "movq %%xmm6,0x8(%1) \n" + "movdqu 0x10(%0),%%xmm6 \n" + "movdqu 0x10(%0,%3,1),%%xmm7 \n" + "lea 0x20(%0),%0 \n" + "pavgb %%xmm6,%%xmm7 \n" + "pavgb %%xmm7,%%xmm6 \n" + "pshufb %%xmm4,%%xmm6 \n" + "pmaddubsw %4,%%xmm6 \n" + "paddsw %%xmm1,%%xmm6 \n" + "psrlw $0x2,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "movq %%xmm6,0x10(%1) \n" + "lea 0x18(%1),%1 \n" + "sub $0x18,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -651,23 +651,23 @@ void ScaleRowDown38_SSSE3(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" + "movdqa %3,%%xmm4 \n" + "movdqa %4,%%xmm5 \n" LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pshufb %%xmm4,%%xmm0 \n" - "pshufb %%xmm5,%%xmm1 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "movhlps %%xmm0,%%xmm1 \n" - "movd %%xmm1,0x8(%1) \n" - "lea 0xc(%1),%1 \n" - "sub $0xc,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "pshufb %%xmm4,%%xmm0 \n" + "pshufb %%xmm5,%%xmm1 \n" + "paddusb %%xmm1,%%xmm0 \n" + "movq %%xmm0,(%1) \n" + "movhlps %%xmm0,%%xmm1 \n" + "movd %%xmm1,0x8(%1) \n" + "lea 0xc(%1),%1 \n" + "sub $0xc,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -681,10 +681,10 @@ void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "movdqa %0,%%xmm2 \n" - "movdqa %1,%%xmm3 \n" - "movdqa %2,%%xmm4 \n" - "movdqa %3,%%xmm5 \n" + "movdqa %0,%%xmm2 \n" + "movdqa %1,%%xmm3 \n" + "movdqa %2,%%xmm4 \n" + "movdqa %3,%%xmm5 \n" : : "m"(kShufAb0), // %0 "m"(kShufAb1), // %1 @@ -695,25 +695,25 @@ void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr, LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%3,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "pavgb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pshufb %%xmm2,%%xmm1 \n" - "movdqa %%xmm0,%%xmm6 \n" - "pshufb %%xmm3,%%xmm6 \n" - "paddusw %%xmm6,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "paddusw %%xmm0,%%xmm1 \n" - "pmulhuw %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movd %%xmm1,(%1) \n" - "psrlq $0x10,%%xmm1 \n" - "movd %%xmm1,0x2(%1) \n" - "lea 0x6(%1),%1 \n" - "sub $0x6,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%3,1),%%xmm1 \n" + "lea 0x10(%0),%0 \n" + "pavgb %%xmm1,%%xmm0 \n" + "movdqa %%xmm0,%%xmm1 \n" + "pshufb %%xmm2,%%xmm1 \n" + "movdqa %%xmm0,%%xmm6 \n" + "pshufb %%xmm3,%%xmm6 \n" + "paddusw %%xmm6,%%xmm1 \n" + "pshufb %%xmm4,%%xmm0 \n" + "paddusw %%xmm0,%%xmm1 \n" + "pmulhuw %%xmm5,%%xmm1 \n" + "packuswb %%xmm1,%%xmm1 \n" + "movd %%xmm1,(%1) \n" + "psrlq $0x10,%%xmm1 \n" + "movd %%xmm1,0x2(%1) \n" + "lea 0x6(%1),%1 \n" + "sub $0x6,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -726,10 +726,10 @@ void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "movdqa %0,%%xmm2 \n" - "movdqa %1,%%xmm3 \n" - "movdqa %2,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" + "movdqa %0,%%xmm2 \n" + "movdqa %1,%%xmm3 \n" + "movdqa %2,%%xmm4 \n" + "pxor %%xmm5,%%xmm5 \n" : : "m"(kShufAc), // %0 "m"(kShufAc3), // %1 @@ -739,44 +739,44 @@ void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr, LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%3,1),%%xmm6 \n" - "movhlps %%xmm0,%%xmm1 \n" - "movhlps %%xmm6,%%xmm7 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm6 \n" - "punpcklbw %%xmm5,%%xmm7 \n" - "paddusw %%xmm6,%%xmm0 \n" - "paddusw %%xmm7,%%xmm1 \n" - "movdqu 0x00(%0,%3,2),%%xmm6 \n" - "lea 0x10(%0),%0 \n" - "movhlps %%xmm6,%%xmm7 \n" - "punpcklbw %%xmm5,%%xmm6 \n" - "punpcklbw %%xmm5,%%xmm7 \n" - "paddusw %%xmm6,%%xmm0 \n" - "paddusw %%xmm7,%%xmm1 \n" - "movdqa %%xmm0,%%xmm6 \n" - "psrldq $0x2,%%xmm0 \n" - "paddusw %%xmm0,%%xmm6 \n" - "psrldq $0x2,%%xmm0 \n" - "paddusw %%xmm0,%%xmm6 \n" - "pshufb %%xmm2,%%xmm6 \n" - "movdqa %%xmm1,%%xmm7 \n" - "psrldq $0x2,%%xmm1 \n" - "paddusw %%xmm1,%%xmm7 \n" - "psrldq $0x2,%%xmm1 \n" - "paddusw %%xmm1,%%xmm7 \n" - "pshufb %%xmm3,%%xmm7 \n" - "paddusw %%xmm7,%%xmm6 \n" - "pmulhuw %%xmm4,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movd %%xmm6,(%1) \n" - "psrlq $0x10,%%xmm6 \n" - "movd %%xmm6,0x2(%1) \n" - "lea 0x6(%1),%1 \n" - "sub $0x6,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x00(%0,%3,1),%%xmm6 \n" + "movhlps %%xmm0,%%xmm1 \n" + "movhlps %%xmm6,%%xmm7 \n" + "punpcklbw %%xmm5,%%xmm0 \n" + "punpcklbw %%xmm5,%%xmm1 \n" + "punpcklbw %%xmm5,%%xmm6 \n" + "punpcklbw %%xmm5,%%xmm7 \n" + "paddusw %%xmm6,%%xmm0 \n" + "paddusw %%xmm7,%%xmm1 \n" + "movdqu 0x00(%0,%3,2),%%xmm6 \n" + "lea 0x10(%0),%0 \n" + "movhlps %%xmm6,%%xmm7 \n" + "punpcklbw %%xmm5,%%xmm6 \n" + "punpcklbw %%xmm5,%%xmm7 \n" + "paddusw %%xmm6,%%xmm0 \n" + "paddusw %%xmm7,%%xmm1 \n" + "movdqa %%xmm0,%%xmm6 \n" + "psrldq $0x2,%%xmm0 \n" + "paddusw %%xmm0,%%xmm6 \n" + "psrldq $0x2,%%xmm0 \n" + "paddusw %%xmm0,%%xmm6 \n" + "pshufb %%xmm2,%%xmm6 \n" + "movdqa %%xmm1,%%xmm7 \n" + "psrldq $0x2,%%xmm1 \n" + "paddusw %%xmm1,%%xmm7 \n" + "psrldq $0x2,%%xmm1 \n" + "paddusw %%xmm1,%%xmm7 \n" + "pshufb %%xmm3,%%xmm7 \n" + "paddusw %%xmm7,%%xmm6 \n" + "pmulhuw %%xmm4,%%xmm6 \n" + "packuswb %%xmm6,%%xmm6 \n" + "movd %%xmm6,(%1) \n" + "psrlq $0x10,%%xmm6 \n" + "movd %%xmm6,0x2(%1) \n" + "lea 0x6(%1),%1 \n" + "sub $0x6,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -791,25 +791,25 @@ void ScaleAddRow_SSE2(const uint8_t* src_ptr, int src_width) { asm volatile( - "pxor %%xmm5,%%xmm5 \n" + "pxor %%xmm5,%%xmm5 \n" // 16 pixel loop. LABELALIGN "1: \n" - "movdqu (%0),%%xmm3 \n" - "lea 0x10(%0),%0 \n" // src_ptr += 16 - "movdqu (%1),%%xmm0 \n" - "movdqu 0x10(%1),%%xmm1 \n" - "movdqa %%xmm3,%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "punpckhbw %%xmm5,%%xmm3 \n" - "paddusw %%xmm2,%%xmm0 \n" - "paddusw %%xmm3,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm3 \n" + "lea 0x10(%0),%0 \n" // src_ptr += 16 + "movdqu (%1),%%xmm0 \n" + "movdqu 0x10(%1),%%xmm1 \n" + "movdqa %%xmm3,%%xmm2 \n" + "punpcklbw %%xmm5,%%xmm2 \n" + "punpckhbw %%xmm5,%%xmm3 \n" + "paddusw %%xmm2,%%xmm0 \n" + "paddusw %%xmm3,%%xmm1 \n" + "movdqu %%xmm0,(%1) \n" + "movdqu %%xmm1,0x10(%1) \n" + "lea 0x20(%1),%1 \n" + "sub $0x10,%2 \n" + "jg 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(src_width) // %2 @@ -824,22 +824,22 @@ void ScaleAddRow_AVX2(const uint8_t* src_ptr, int src_width) { asm volatile( - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" + "vpxor %%ymm5,%%ymm5,%%ymm5 \n" LABELALIGN "1: \n" - "vmovdqu (%0),%%ymm3 \n" - "lea 0x20(%0),%0 \n" // src_ptr += 32 - "vpermq $0xd8,%%ymm3,%%ymm3 \n" - "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" - "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" - "vpaddusw (%1),%%ymm2,%%ymm0 \n" - "vpaddusw 0x20(%1),%%ymm3,%%ymm1 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "vmovdqu (%0),%%ymm3 \n" + "lea 0x20(%0),%0 \n" // src_ptr += 32 + "vpermq $0xd8,%%ymm3,%%ymm3 \n" + "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" + "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" + "vpaddusw (%1),%%ymm2,%%ymm0 \n" + "vpaddusw 0x20(%1),%%ymm3,%%ymm1 \n" + "vmovdqu %%ymm0,(%1) \n" + "vmovdqu %%ymm1,0x20(%1) \n" + "lea 0x40(%1),%1 \n" + "sub $0x20,%2 \n" + "jg 1b \n" "vzeroupper \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 @@ -866,69 +866,69 @@ void ScaleFilterCols_SSSE3(uint8_t* dst_ptr, int dx) { intptr_t x0, x1, temp_pixel; asm volatile( - "movd %6,%%xmm2 \n" - "movd %7,%%xmm3 \n" - "movl $0x04040000,%k2 \n" - "movd %k2,%%xmm5 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "psrlw $0x9,%%xmm6 \n" // 0x007f007f - "pcmpeqb %%xmm7,%%xmm7 \n" - "psrlw $15,%%xmm7 \n" // 0x00010001 + "movd %6,%%xmm2 \n" + "movd %7,%%xmm3 \n" + "movl $0x04040000,%k2 \n" + "movd %k2,%%xmm5 \n" + "pcmpeqb %%xmm6,%%xmm6 \n" + "psrlw $0x9,%%xmm6 \n" // 0x007f007f + "pcmpeqb %%xmm7,%%xmm7 \n" + "psrlw $15,%%xmm7 \n" // 0x00010001 - "pextrw $0x1,%%xmm2,%k3 \n" - "subl $0x2,%5 \n" - "jl 29f \n" - "movdqa %%xmm2,%%xmm0 \n" - "paddd %%xmm3,%%xmm0 \n" - "punpckldq %%xmm0,%%xmm2 \n" - "punpckldq %%xmm3,%%xmm3 \n" - "paddd %%xmm3,%%xmm3 \n" - "pextrw $0x3,%%xmm2,%k4 \n" + "pextrw $0x1,%%xmm2,%k3 \n" + "subl $0x2,%5 \n" + "jl 29f \n" + "movdqa %%xmm2,%%xmm0 \n" + "paddd %%xmm3,%%xmm0 \n" + "punpckldq %%xmm0,%%xmm2 \n" + "punpckldq %%xmm3,%%xmm3 \n" + "paddd %%xmm3,%%xmm3 \n" + "pextrw $0x3,%%xmm2,%k4 \n" LABELALIGN "2: \n" - "movdqa %%xmm2,%%xmm1 \n" - "paddd %%xmm3,%%xmm2 \n" - "movzwl 0x00(%1,%3,1),%k2 \n" - "movd %k2,%%xmm0 \n" - "psrlw $0x9,%%xmm1 \n" - "movzwl 0x00(%1,%4,1),%k2 \n" - "movd %k2,%%xmm4 \n" - "pshufb %%xmm5,%%xmm1 \n" - "punpcklwd %%xmm4,%%xmm0 \n" - "psubb %8,%%xmm0 \n" // make pixels signed. - "pxor %%xmm6,%%xmm1 \n" // 128 - f = (f ^ 127 ) + + "movdqa %%xmm2,%%xmm1 \n" + "paddd %%xmm3,%%xmm2 \n" + "movzwl 0x00(%1,%3,1),%k2 \n" + "movd %k2,%%xmm0 \n" + "psrlw $0x9,%%xmm1 \n" + "movzwl 0x00(%1,%4,1),%k2 \n" + "movd %k2,%%xmm4 \n" + "pshufb %%xmm5,%%xmm1 \n" + "punpcklwd %%xmm4,%%xmm0 \n" + "psubb %8,%%xmm0 \n" // make pixels signed. + "pxor %%xmm6,%%xmm1 \n" // 128 - f = (f ^ 127 ) + // 1 - "paddusb %%xmm7,%%xmm1 \n" - "pmaddubsw %%xmm0,%%xmm1 \n" - "pextrw $0x1,%%xmm2,%k3 \n" - "pextrw $0x3,%%xmm2,%k4 \n" - "paddw %9,%%xmm1 \n" // make pixels unsigned. - "psrlw $0x7,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movd %%xmm1,%k2 \n" - "mov %w2,(%0) \n" - "lea 0x2(%0),%0 \n" - "subl $0x2,%5 \n" - "jge 2b \n" + "paddusb %%xmm7,%%xmm1 \n" + "pmaddubsw %%xmm0,%%xmm1 \n" + "pextrw $0x1,%%xmm2,%k3 \n" + "pextrw $0x3,%%xmm2,%k4 \n" + "paddw %9,%%xmm1 \n" // make pixels unsigned. + "psrlw $0x7,%%xmm1 \n" + "packuswb %%xmm1,%%xmm1 \n" + "movd %%xmm1,%k2 \n" + "mov %w2,(%0) \n" + "lea 0x2(%0),%0 \n" + "subl $0x2,%5 \n" + "jge 2b \n" LABELALIGN "29: \n" - "addl $0x1,%5 \n" - "jl 99f \n" - "movzwl 0x00(%1,%3,1),%k2 \n" - "movd %k2,%%xmm0 \n" - "psrlw $0x9,%%xmm2 \n" - "pshufb %%xmm5,%%xmm2 \n" - "psubb %8,%%xmm0 \n" // make pixels signed. - "pxor %%xmm6,%%xmm2 \n" - "paddusb %%xmm7,%%xmm2 \n" - "pmaddubsw %%xmm0,%%xmm2 \n" - "paddw %9,%%xmm2 \n" // make pixels unsigned. - "psrlw $0x7,%%xmm2 \n" - "packuswb %%xmm2,%%xmm2 \n" - "movd %%xmm2,%k2 \n" - "mov %b2,(%0) \n" + "addl $0x1,%5 \n" + "jl 99f \n" + "movzwl 0x00(%1,%3,1),%k2 \n" + "movd %k2,%%xmm0 \n" + "psrlw $0x9,%%xmm2 \n" + "pshufb %%xmm5,%%xmm2 \n" + "psubb %8,%%xmm0 \n" // make pixels signed. + "pxor %%xmm6,%%xmm2 \n" + "paddusb %%xmm7,%%xmm2 \n" + "pmaddubsw %%xmm0,%%xmm2 \n" + "paddw %9,%%xmm2 \n" // make pixels unsigned. + "psrlw $0x7,%%xmm2 \n" + "packuswb %%xmm2,%%xmm2 \n" + "movd %%xmm2,%k2 \n" + "mov %b2,(%0) \n" "99: \n" : "+r"(dst_ptr), // %0 "+r"(src_ptr), // %1 @@ -966,16 +966,16 @@ void ScaleColsUp2_SSE2(uint8_t* dst_ptr, LABELALIGN "1: \n" - "movdqu (%1),%%xmm0 \n" - "lea 0x10(%1),%1 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "movdqu %%xmm0,(%0) \n" - "movdqu %%xmm1,0x10(%0) \n" - "lea 0x20(%0),%0 \n" - "sub $0x20,%2 \n" - "jg 1b \n" + "movdqu (%1),%%xmm0 \n" + "lea 0x10(%1),%1 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpcklbw %%xmm0,%%xmm0 \n" + "punpckhbw %%xmm1,%%xmm1 \n" + "movdqu %%xmm0,(%0) \n" + "movdqu %%xmm1,0x10(%0) \n" + "lea 0x20(%0),%0 \n" + "sub $0x20,%2 \n" + "jg 1b \n" : "+r"(dst_ptr), // %0 "+r"(src_ptr), // %1 @@ -993,14 +993,14 @@ void ScaleARGBRowDown2_SSE2(const uint8_t* src_argb, LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "shufps $0xdd,%%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "shufps $0xdd,%%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(dst_width) // %2 @@ -1017,17 +1017,17 @@ void ScaleARGBRowDown2Linear_SSE2(const uint8_t* src_argb, LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm2 \n" - "pavgb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "lea 0x20(%0),%0 \n" + "movdqa %%xmm0,%%xmm2 \n" + "shufps $0x88,%%xmm1,%%xmm0 \n" + "shufps $0xdd,%%xmm1,%%xmm2 \n" + "pavgb %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(dst_width) // %2 @@ -1043,21 +1043,21 @@ void ScaleARGBRowDown2Box_SSE2(const uint8_t* src_argb, LABELALIGN "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%3,1),%%xmm2 \n" - "movdqu 0x10(%0,%3,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm2,%%xmm0 \n" - "pavgb %%xmm3,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm2 \n" - "pavgb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" + "movdqu (%0),%%xmm0 \n" + "movdqu 0x10(%0),%%xmm1 \n" + "movdqu 0x00(%0,%3,1),%%xmm2 \n" + "movdqu 0x10(%0,%3,1),%%xmm3 \n" + "lea 0x20(%0),%0 \n" + "pavgb %%xmm2,%%xmm0 \n" + "pavgb %%xmm3,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "shufps $0x88,%%xmm1,%%xmm0 \n" + "shufps $0xdd,%%xmm1,%%xmm2 \n" + "pavgb %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" + "sub $0x4,%2 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(dst_width) // %2 @@ -1076,23 +1076,23 @@ void ScaleARGBRowDownEven_SSE2(const uint8_t* src_argb, intptr_t src_stepx_x12; (void)src_stride; asm volatile( - "lea 0x00(,%1,4),%1 \n" - "lea 0x00(%1,%1,2),%4 \n" + "lea 0x00(,%1,4),%1 \n" + "lea 0x00(%1,%1,2),%4 \n" LABELALIGN "1: \n" - "movd (%0),%%xmm0 \n" - "movd 0x00(%0,%1,1),%%xmm1 \n" - "punpckldq %%xmm1,%%xmm0 \n" - "movd 0x00(%0,%1,2),%%xmm2 \n" - "movd 0x00(%0,%4,1),%%xmm3 \n" - "lea 0x00(%0,%1,4),%0 \n" - "punpckldq %%xmm3,%%xmm2 \n" - "punpcklqdq %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jg 1b \n" + "movd (%0),%%xmm0 \n" + "movd 0x00(%0,%1,1),%%xmm1 \n" + "punpckldq %%xmm1,%%xmm0 \n" + "movd 0x00(%0,%1,2),%%xmm2 \n" + "movd 0x00(%0,%4,1),%%xmm3 \n" + "lea 0x00(%0,%1,4),%0 \n" + "punpckldq %%xmm3,%%xmm2 \n" + "punpcklqdq %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%3 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(src_stepx_x4), // %1 "+r"(dst_argb), // %2 @@ -1113,32 +1113,32 @@ void ScaleARGBRowDownEvenBox_SSE2(const uint8_t* src_argb, intptr_t src_stepx_x12; intptr_t row1 = (intptr_t)(src_stride); asm volatile( - "lea 0x00(,%1,4),%1 \n" - "lea 0x00(%1,%1,2),%4 \n" - "lea 0x00(%0,%5,1),%5 \n" + "lea 0x00(,%1,4),%1 \n" + "lea 0x00(%1,%1,2),%4 \n" + "lea 0x00(%0,%5,1),%5 \n" LABELALIGN "1: \n" - "movq (%0),%%xmm0 \n" - "movhps 0x00(%0,%1,1),%%xmm0 \n" - "movq 0x00(%0,%1,2),%%xmm1 \n" - "movhps 0x00(%0,%4,1),%%xmm1 \n" - "lea 0x00(%0,%1,4),%0 \n" - "movq (%5),%%xmm2 \n" - "movhps 0x00(%5,%1,1),%%xmm2 \n" - "movq 0x00(%5,%1,2),%%xmm3 \n" - "movhps 0x00(%5,%4,1),%%xmm3 \n" - "lea 0x00(%5,%1,4),%5 \n" - "pavgb %%xmm2,%%xmm0 \n" - "pavgb %%xmm3,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm2 \n" - "pavgb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jg 1b \n" + "movq (%0),%%xmm0 \n" + "movhps 0x00(%0,%1,1),%%xmm0 \n" + "movq 0x00(%0,%1,2),%%xmm1 \n" + "movhps 0x00(%0,%4,1),%%xmm1 \n" + "lea 0x00(%0,%1,4),%0 \n" + "movq (%5),%%xmm2 \n" + "movhps 0x00(%5,%1,1),%%xmm2 \n" + "movq 0x00(%5,%1,2),%%xmm3 \n" + "movhps 0x00(%5,%4,1),%%xmm3 \n" + "lea 0x00(%5,%1,4),%5 \n" + "pavgb %%xmm2,%%xmm0 \n" + "pavgb %%xmm3,%%xmm1 \n" + "movdqa %%xmm0,%%xmm2 \n" + "shufps $0x88,%%xmm1,%%xmm0 \n" + "shufps $0xdd,%%xmm1,%%xmm2 \n" + "pavgb %%xmm2,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%3 \n" + "jg 1b \n" : "+r"(src_argb), // %0 "+r"(src_stepx_x4), // %1 "+r"(dst_argb), // %2 @@ -1156,56 +1156,56 @@ void ScaleARGBCols_SSE2(uint8_t* dst_argb, int dx) { intptr_t x0, x1; asm volatile( - "movd %5,%%xmm2 \n" - "movd %6,%%xmm3 \n" - "pshufd $0x0,%%xmm2,%%xmm2 \n" - "pshufd $0x11,%%xmm3,%%xmm0 \n" - "paddd %%xmm0,%%xmm2 \n" - "paddd %%xmm3,%%xmm3 \n" - "pshufd $0x5,%%xmm3,%%xmm0 \n" - "paddd %%xmm0,%%xmm2 \n" - "paddd %%xmm3,%%xmm3 \n" - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pextrw $0x1,%%xmm2,%k0 \n" - "pextrw $0x3,%%xmm2,%k1 \n" - "cmp $0x0,%4 \n" - "jl 99f \n" - "sub $0x4,%4 \n" - "jl 49f \n" + "movd %5,%%xmm2 \n" + "movd %6,%%xmm3 \n" + "pshufd $0x0,%%xmm2,%%xmm2 \n" + "pshufd $0x11,%%xmm3,%%xmm0 \n" + "paddd %%xmm0,%%xmm2 \n" + "paddd %%xmm3,%%xmm3 \n" + "pshufd $0x5,%%xmm3,%%xmm0 \n" + "paddd %%xmm0,%%xmm2 \n" + "paddd %%xmm3,%%xmm3 \n" + "pshufd $0x0,%%xmm3,%%xmm3 \n" + "pextrw $0x1,%%xmm2,%k0 \n" + "pextrw $0x3,%%xmm2,%k1 \n" + "cmp $0x0,%4 \n" + "jl 99f \n" + "sub $0x4,%4 \n" + "jl 49f \n" LABELALIGN "40: \n" - "movd 0x00(%3,%0,4),%%xmm0 \n" - "movd 0x00(%3,%1,4),%%xmm1 \n" - "pextrw $0x5,%%xmm2,%k0 \n" - "pextrw $0x7,%%xmm2,%k1 \n" - "paddd %%xmm3,%%xmm2 \n" - "punpckldq %%xmm1,%%xmm0 \n" - "movd 0x00(%3,%0,4),%%xmm1 \n" - "movd 0x00(%3,%1,4),%%xmm4 \n" - "pextrw $0x1,%%xmm2,%k0 \n" - "pextrw $0x3,%%xmm2,%k1 \n" - "punpckldq %%xmm4,%%xmm1 \n" - "punpcklqdq %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%4 \n" - "jge 40b \n" + "movd 0x00(%3,%0,4),%%xmm0 \n" + "movd 0x00(%3,%1,4),%%xmm1 \n" + "pextrw $0x5,%%xmm2,%k0 \n" + "pextrw $0x7,%%xmm2,%k1 \n" + "paddd %%xmm3,%%xmm2 \n" + "punpckldq %%xmm1,%%xmm0 \n" + "movd 0x00(%3,%0,4),%%xmm1 \n" + "movd 0x00(%3,%1,4),%%xmm4 \n" + "pextrw $0x1,%%xmm2,%k0 \n" + "pextrw $0x3,%%xmm2,%k1 \n" + "punpckldq %%xmm4,%%xmm1 \n" + "punpcklqdq %%xmm1,%%xmm0 \n" + "movdqu %%xmm0,(%2) \n" + "lea 0x10(%2),%2 \n" + "sub $0x4,%4 \n" + "jge 40b \n" "49: \n" - "test $0x2,%4 \n" - "je 29f \n" - "movd 0x00(%3,%0,4),%%xmm0 \n" - "movd 0x00(%3,%1,4),%%xmm1 \n" - "pextrw $0x5,%%xmm2,%k0 \n" - "punpckldq %%xmm1,%%xmm0 \n" - "movq %%xmm0,(%2) \n" - "lea 0x8(%2),%2 \n" + "test $0x2,%4 \n" + "je 29f \n" + "movd 0x00(%3,%0,4),%%xmm0 \n" + "movd 0x00(%3,%1,4),%%xmm1 \n" + "pextrw $0x5,%%xmm2,%k0 \n" + "punpckldq %%xmm1,%%xmm0 \n" + "movq %%xmm0,(%2) \n" + "lea 0x8(%2),%2 \n" "29: \n" - "test $0x1,%4 \n" - "je 99f \n" - "movd 0x00(%3,%0,4),%%xmm0 \n" - "movd %%xmm0,(%2) \n" + "test $0x1,%4 \n" + "je 99f \n" + "movd 0x00(%3,%0,4),%%xmm0 \n" + "movd %%xmm0,(%2) \n" "99: \n" : "=&a"(x0), // %0 "=&d"(x1), // %1 @@ -1230,16 +1230,16 @@ void ScaleARGBColsUp2_SSE2(uint8_t* dst_argb, LABELALIGN "1: \n" - "movdqu (%1),%%xmm0 \n" - "lea 0x10(%1),%1 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpckldq %%xmm0,%%xmm0 \n" - "punpckhdq %%xmm1,%%xmm1 \n" - "movdqu %%xmm0,(%0) \n" - "movdqu %%xmm1,0x10(%0) \n" - "lea 0x20(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" + "movdqu (%1),%%xmm0 \n" + "lea 0x10(%1),%1 \n" + "movdqa %%xmm0,%%xmm1 \n" + "punpckldq %%xmm0,%%xmm0 \n" + "punpckhdq %%xmm1,%%xmm1 \n" + "movdqu %%xmm0,(%0) \n" + "movdqu %%xmm1,0x10(%0) \n" + "lea 0x20(%0),%0 \n" + "sub $0x8,%2 \n" + "jg 1b \n" : "+r"(dst_argb), // %0 "+r"(src_argb), // %1 @@ -1267,63 +1267,64 @@ void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb, int dx) { intptr_t x0, x1; asm volatile( - "movdqa %0,%%xmm4 \n" - "movdqa %1,%%xmm5 \n" + "movdqa %0,%%xmm4 \n" + "movdqa %1,%%xmm5 \n" : : "m"(kShuffleColARGB), // %0 "m"(kShuffleFractions) // %1 ); asm volatile( - "movd %5,%%xmm2 \n" - "movd %6,%%xmm3 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "psrlw $0x9,%%xmm6 \n" - "pextrw $0x1,%%xmm2,%k3 \n" - "sub $0x2,%2 \n" - "jl 29f \n" - "movdqa %%xmm2,%%xmm0 \n" - "paddd %%xmm3,%%xmm0 \n" - "punpckldq %%xmm0,%%xmm2 \n" - "punpckldq %%xmm3,%%xmm3 \n" - "paddd %%xmm3,%%xmm3 \n" - "pextrw $0x3,%%xmm2,%k4 \n" + "movd %5,%%xmm2 \n" + "movd %6,%%xmm3 \n" + "pcmpeqb %%xmm6,%%xmm6 \n" + "psrlw $0x9,%%xmm6 \n" + "pextrw $0x1,%%xmm2,%k3 \n" + "sub $0x2,%2 \n" + "jl 29f \n" + "movdqa %%xmm2,%%xmm0 \n" + "paddd %%xmm3,%%xmm0 \n" + "punpckldq %%xmm0,%%xmm2 \n" + "punpckldq %%xmm3,%%xmm3 \n" + "paddd %%xmm3,%%xmm3 \n" + "pextrw $0x3,%%xmm2,%k4 \n" LABELALIGN "2: \n" - "movdqa %%xmm2,%%xmm1 \n" - "paddd %%xmm3,%%xmm2 \n" - "movq 0x00(%1,%3,4),%%xmm0 \n" - "psrlw $0x9,%%xmm1 \n" - "movhps 0x00(%1,%4,4),%%xmm0 \n" - "pshufb %%xmm5,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "pxor %%xmm6,%%xmm1 \n" - "pmaddubsw %%xmm1,%%xmm0 \n" - "psrlw $0x7,%%xmm0 \n" - "pextrw $0x1,%%xmm2,%k3 \n" - "pextrw $0x3,%%xmm2,%k4 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%0) \n" - "lea 0x8(%0),%0 \n" - "sub $0x2,%2 \n" - "jge 2b \n" + "movdqa %%xmm2,%%xmm1 \n" + "paddd %%xmm3,%%xmm2 \n" + "movq 0x00(%1,%3,4),%%xmm0 \n" + "psrlw $0x9,%%xmm1 \n" + "movhps 0x00(%1,%4,4),%%xmm0 \n" + "pshufb %%xmm5,%%xmm1 \n" + "pshufb %%xmm4,%%xmm0 \n" + "pxor %%xmm6,%%xmm1 \n" + "pmaddubsw %%xmm1,%%xmm0 \n" + "psrlw $0x7,%%xmm0 \n" + "pextrw $0x1,%%xmm2,%k3 \n" + "pextrw $0x3,%%xmm2,%k4 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movq %%xmm0,(%0) \n" + "lea 0x8(%0),%0 \n" + "sub $0x2,%2 \n" + "jge 2b \n" LABELALIGN "29: \n" - "add $0x1,%2 \n" - "jl 99f \n" - "psrlw $0x9,%%xmm2 \n" - "movq 0x00(%1,%3,4),%%xmm0 \n" - "pshufb %%xmm5,%%xmm2 \n" - "pshufb %%xmm4,%%xmm0 \n" - "pxor %%xmm6,%%xmm2 \n" - "pmaddubsw %%xmm2,%%xmm0 \n" - "psrlw $0x7,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movd %%xmm0,(%0) \n" + "add $0x1,%2 \n" + "jl 99f \n" + "psrlw $0x9,%%xmm2 \n" + "movq 0x00(%1,%3,4),%%xmm0 \n" + "pshufb %%xmm5,%%xmm2 \n" + "pshufb %%xmm4,%%xmm0 \n" + "pxor %%xmm6,%%xmm2 \n" + "pmaddubsw %%xmm2,%%xmm0 \n" + "psrlw $0x7,%%xmm0 \n" + "packuswb %%xmm0,%%xmm0 \n" + "movd %%xmm0,(%0) \n" - LABELALIGN "99: \n" // clang-format error. + LABELALIGN + "99: \n" // clang-format error. : "+r"(dst_argb), // %0 "+r"(src_argb), // %1 @@ -1339,10 +1340,10 @@ void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb, int FixedDiv_X86(int num, int div) { asm volatile( "cdq \n" - "shld $0x10,%%eax,%%edx \n" - "shl $0x10,%%eax \n" - "idiv %1 \n" - "mov %0, %%eax \n" + "shld $0x10,%%eax,%%edx \n" + "shl $0x10,%%eax \n" + "idiv %1 \n" + "mov %0, %%eax \n" : "+a"(num) // %0 : "c"(div) // %1 : "memory", "cc", "edx"); @@ -1353,19 +1354,108 @@ int FixedDiv_X86(int num, int div) { int FixedDiv1_X86(int num, int div) { asm volatile( "cdq \n" - "shld $0x10,%%eax,%%edx \n" - "shl $0x10,%%eax \n" - "sub $0x10001,%%eax \n" - "sbb $0x0,%%edx \n" - "sub $0x1,%1 \n" - "idiv %1 \n" - "mov %0, %%eax \n" + "shld $0x10,%%eax,%%edx \n" + "shl $0x10,%%eax \n" + "sub $0x10001,%%eax \n" + "sbb $0x0,%%edx \n" + "sub $0x1,%1 \n" + "idiv %1 \n" + "mov %0, %%eax \n" : "+a"(num) // %0 : "c"(div) // %1 : "memory", "cc", "edx"); return num; } +#ifdef HAS_SCALEUVROWDOWN2BOX_SSSE3 +// Shuffle table for splitting UV into upper and lower part of register. +static const uvec8 kShuffleSplitUV = {0u, 2u, 4u, 6u, 8u, 10u, 12u, 14u, + 1u, 3u, 5u, 7u, 9u, 11u, 13u, 15u}; +static const uvec8 kShuffleMergeUV = {0u, 8u, 2u, 10u, 4u, 12u, + 6u, 14u, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80}; + +void ScaleUVRowDown2Box_SSSE3(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width) { + asm volatile( + "pcmpeqb %%xmm4,%%xmm4 \n" // 01010101 + "psrlw $0xf,%%xmm4 \n" + "packuswb %%xmm4,%%xmm4 \n" + "pxor %%xmm5, %%xmm5 \n" // zero + "movdqa %4,%%xmm1 \n" // split shuffler + "movdqa %5,%%xmm3 \n" // merge shuffler + + LABELALIGN + "1: \n" + "movdqu (%0),%%xmm0 \n" // 8 UV row 0 + "movdqu 0x00(%0,%3,1),%%xmm2 \n" // 8 UV row 1 + "lea 0x10(%0),%0 \n" + "pshufb %%xmm1,%%xmm0 \n" // uuuuvvvv + "pshufb %%xmm1,%%xmm2 \n" + "pmaddubsw %%xmm4,%%xmm0 \n" // horizontal add + "pmaddubsw %%xmm4,%%xmm2 \n" + "paddw %%xmm2,%%xmm0 \n" // vertical add + "psrlw $0x1,%%xmm0 \n" // round + "pavgw %%xmm5,%%xmm0 \n" + "pshufb %%xmm3,%%xmm0 \n" // merge uv + "movq %%xmm0,(%1) \n" + "lea 0x8(%1),%1 \n" // 4 UV + "sub $0x4,%2 \n" + "jg 1b \n" + : "+r"(src_ptr), // %0 + "+r"(dst_ptr), // %1 + "+r"(dst_width) // %2 + : "r"((intptr_t)(src_stride)), // %3 + "m"(kShuffleSplitUV), // %4 + "m"(kShuffleMergeUV) // %5 + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); +} +#endif // HAS_SCALEUVROWDOWN2BOX_SSSE3 + +#ifdef HAS_SCALEUVROWDOWN2BOX_AVX2 +void ScaleUVRowDown2Box_AVX2(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst_ptr, + int dst_width) { + asm volatile( + "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" // 01010101 + "vpsrlw $0xf,%%ymm4,%%ymm4 \n" + "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" + "vpxor %%ymm5,%%ymm5,%%ymm5 \n" // zero + "vbroadcastf128 %4,%%ymm1 \n" // split shuffler + "vbroadcastf128 %5,%%ymm3 \n" // merge shuffler + + LABELALIGN + "1: \n" + "vmovdqu (%0),%%ymm0 \n" // 16 UV row 0 + "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" // 16 UV row 1 + "lea 0x20(%0),%0 \n" + "vpshufb %%ymm1,%%ymm0,%%ymm0 \n" // uuuuvvvv + "vpshufb %%ymm1,%%ymm2,%%ymm2 \n" + "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" // horizontal add + "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" + "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" // vertical add + "vpsrlw $0x1,%%ymm0,%%ymm0 \n" // round + "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" + "vpshufb %%ymm3,%%ymm0,%%ymm0 \n" // merge uv + "vpermq $0xd8,%%ymm0,%%ymm0 \n" // combine qwords + "vmovdqu %%xmm0,(%1) \n" + "lea 0x10(%1),%1 \n" // 8 UV + "sub $0x8,%2 \n" + "jg 1b \n" + "vzeroupper \n" + : "+r"(src_ptr), // %0 + "+r"(dst_ptr), // %1 + "+r"(dst_width) // %2 + : "r"((intptr_t)(src_stride)), // %3 + "m"(kShuffleSplitUV), // %4 + "m"(kShuffleMergeUV) // %5 + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); +} +#endif // HAS_SCALEUVROWDOWN2BOX_AVX2 + #endif // defined(__x86_64__) || defined(__i386__) #ifdef __cplusplus diff --git a/TMessagesProj/jni/third_party/libyuv/source/scale_neon.cc b/TMessagesProj/jni/third_party/libyuv/source/scale_neon.cc index 366b155ba..572b4bfa9 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/scale_neon.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/scale_neon.cc @@ -31,10 +31,10 @@ void ScaleRowDown2_NEON(const uint8_t* src_ptr, asm volatile( "1: \n" // load even pixels into q0, odd into q1 - "vld2.8 {q0, q1}, [%0]! \n" - "subs %2, %2, #16 \n" // 16 processed per loop - "vst1.8 {q1}, [%1]! \n" // store odd pixels - "bgt 1b \n" + "vld2.8 {q0, q1}, [%0]! \n" + "subs %2, %2, #16 \n" // 16 processed per loop + "vst1.8 {q1}, [%1]! \n" // store odd pixels + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst), // %1 "+r"(dst_width) // %2 @@ -51,11 +51,11 @@ void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr, (void)src_stride; asm volatile( "1: \n" - "vld2.8 {q0, q1}, [%0]! \n" // load 32 pixels - "subs %2, %2, #16 \n" // 16 processed per loop - "vrhadd.u8 q0, q0, q1 \n" // rounding half add - "vst1.8 {q0}, [%1]! \n" - "bgt 1b \n" + "vld2.8 {q0, q1}, [%0]! \n" // load 32 pixels + "subs %2, %2, #16 \n" // 16 processed per loop + "vrhadd.u8 q0, q0, q1 \n" // rounding half add + "vst1.8 {q0}, [%1]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst), // %1 "+r"(dst_width) // %2 @@ -71,21 +71,21 @@ void ScaleRowDown2Box_NEON(const uint8_t* src_ptr, int dst_width) { asm volatile( // change the stride to row 2 pointer - "add %1, %0 \n" + "add %1, %0 \n" "1: \n" - "vld1.8 {q0, q1}, [%0]! \n" // load row 1 and post inc - "vld1.8 {q2, q3}, [%1]! \n" // load row 2 and post inc - "subs %3, %3, #16 \n" // 16 processed per loop - "vpaddl.u8 q0, q0 \n" // row 1 add adjacent - "vpaddl.u8 q1, q1 \n" - "vpadal.u8 q0, q2 \n" // row 2 add adjacent + + "vld1.8 {q0, q1}, [%0]! \n" // load row 1 and post inc + "vld1.8 {q2, q3}, [%1]! \n" // load row 2 and post inc + "subs %3, %3, #16 \n" // 16 processed per loop + "vpaddl.u8 q0, q0 \n" // row 1 add adjacent + "vpaddl.u8 q1, q1 \n" + "vpadal.u8 q0, q2 \n" // row 2 add adjacent + // row1 - "vpadal.u8 q1, q3 \n" - "vrshrn.u16 d0, q0, #2 \n" // downshift, round and + "vpadal.u8 q1, q3 \n" + "vrshrn.u16 d0, q0, #2 \n" // downshift, round and // pack - "vrshrn.u16 d1, q1, #2 \n" - "vst1.8 {q0}, [%2]! \n" - "bgt 1b \n" + "vrshrn.u16 d1, q1, #2 \n" + "vst1.8 {q0}, [%2]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(src_stride), // %1 "+r"(dst), // %2 @@ -102,10 +102,10 @@ void ScaleRowDown4_NEON(const uint8_t* src_ptr, (void)src_stride; asm volatile( "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 - "subs %2, %2, #8 \n" // 8 processed per loop - "vst1.8 {d2}, [%1]! \n" - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 + "subs %2, %2, #8 \n" // 8 processed per loop + "vst1.8 {d2}, [%1]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -122,20 +122,20 @@ void ScaleRowDown4Box_NEON(const uint8_t* src_ptr, const uint8_t* src_ptr3 = src_ptr + src_stride * 3; asm volatile( "1: \n" - "vld1.8 {q0}, [%0]! \n" // load up 16x4 - "vld1.8 {q1}, [%3]! \n" - "vld1.8 {q2}, [%4]! \n" - "vld1.8 {q3}, [%5]! \n" - "subs %2, %2, #4 \n" - "vpaddl.u8 q0, q0 \n" - "vpadal.u8 q0, q1 \n" - "vpadal.u8 q0, q2 \n" - "vpadal.u8 q0, q3 \n" - "vpaddl.u16 q0, q0 \n" - "vrshrn.u32 d0, q0, #4 \n" // divide by 16 w/rounding - "vmovn.u16 d0, q0 \n" - "vst1.32 {d0[0]}, [%1]! \n" - "bgt 1b \n" + "vld1.8 {q0}, [%0]! \n" // load up 16x4 + "vld1.8 {q1}, [%3]! \n" + "vld1.8 {q2}, [%4]! \n" + "vld1.8 {q3}, [%5]! \n" + "subs %2, %2, #4 \n" + "vpaddl.u8 q0, q0 \n" + "vpadal.u8 q0, q1 \n" + "vpadal.u8 q0, q2 \n" + "vpadal.u8 q0, q3 \n" + "vpaddl.u16 q0, q0 \n" + "vrshrn.u32 d0, q0, #4 \n" // divide by 16 w/rounding + "vmovn.u16 d0, q0 \n" + "vst1.32 {d0[0]}, [%1]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width), // %2 @@ -156,11 +156,11 @@ void ScaleRowDown34_NEON(const uint8_t* src_ptr, (void)src_stride; asm volatile( "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 - "subs %2, %2, #24 \n" - "vmov d2, d3 \n" // order d0, d1, d2 - "vst3.8 {d0, d1, d2}, [%1]! \n" - "bgt 1b \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 + "subs %2, %2, #24 \n" + "vmov d2, d3 \n" // order d0, d1, d2 + "vst3.8 {d0, d1, d2}, [%1]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -173,49 +173,49 @@ void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "vmov.u8 d24, #3 \n" - "add %3, %0 \n" + "vmov.u8 d24, #3 \n" + "add %3, %0 \n" "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 - "vld4.8 {d4, d5, d6, d7}, [%3]! \n" // src line 1 - "subs %2, %2, #24 \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 + "vld4.8 {d4, d5, d6, d7}, [%3]! \n" // src line 1 + "subs %2, %2, #24 \n" // filter src line 0 with src line 1 // expand chars to shorts to allow for room // when adding lines together - "vmovl.u8 q8, d4 \n" - "vmovl.u8 q9, d5 \n" - "vmovl.u8 q10, d6 \n" - "vmovl.u8 q11, d7 \n" + "vmovl.u8 q8, d4 \n" + "vmovl.u8 q9, d5 \n" + "vmovl.u8 q10, d6 \n" + "vmovl.u8 q11, d7 \n" // 3 * line_0 + line_1 - "vmlal.u8 q8, d0, d24 \n" - "vmlal.u8 q9, d1, d24 \n" - "vmlal.u8 q10, d2, d24 \n" - "vmlal.u8 q11, d3, d24 \n" + "vmlal.u8 q8, d0, d24 \n" + "vmlal.u8 q9, d1, d24 \n" + "vmlal.u8 q10, d2, d24 \n" + "vmlal.u8 q11, d3, d24 \n" // (3 * line_0 + line_1) >> 2 - "vqrshrn.u16 d0, q8, #2 \n" - "vqrshrn.u16 d1, q9, #2 \n" - "vqrshrn.u16 d2, q10, #2 \n" - "vqrshrn.u16 d3, q11, #2 \n" + "vqrshrn.u16 d0, q8, #2 \n" + "vqrshrn.u16 d1, q9, #2 \n" + "vqrshrn.u16 d2, q10, #2 \n" + "vqrshrn.u16 d3, q11, #2 \n" // a0 = (src[0] * 3 + s[1] * 1) >> 2 - "vmovl.u8 q8, d1 \n" - "vmlal.u8 q8, d0, d24 \n" - "vqrshrn.u16 d0, q8, #2 \n" + "vmovl.u8 q8, d1 \n" + "vmlal.u8 q8, d0, d24 \n" + "vqrshrn.u16 d0, q8, #2 \n" // a1 = (src[1] * 1 + s[2] * 1) >> 1 - "vrhadd.u8 d1, d1, d2 \n" + "vrhadd.u8 d1, d1, d2 \n" // a2 = (src[2] * 1 + s[3] * 3) >> 2 - "vmovl.u8 q8, d2 \n" - "vmlal.u8 q8, d3, d24 \n" - "vqrshrn.u16 d2, q8, #2 \n" + "vmovl.u8 q8, d2 \n" + "vmlal.u8 q8, d3, d24 \n" + "vqrshrn.u16 d2, q8, #2 \n" - "vst3.8 {d0, d1, d2}, [%1]! \n" + "vst3.8 {d0, d1, d2}, [%1]! \n" - "bgt 1b \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width), // %2 @@ -230,31 +230,31 @@ void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "vmov.u8 d24, #3 \n" - "add %3, %0 \n" + "vmov.u8 d24, #3 \n" + "add %3, %0 \n" "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 - "vld4.8 {d4, d5, d6, d7}, [%3]! \n" // src line 1 - "subs %2, %2, #24 \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 + "vld4.8 {d4, d5, d6, d7}, [%3]! \n" // src line 1 + "subs %2, %2, #24 \n" // average src line 0 with src line 1 - "vrhadd.u8 q0, q0, q2 \n" - "vrhadd.u8 q1, q1, q3 \n" + "vrhadd.u8 q0, q0, q2 \n" + "vrhadd.u8 q1, q1, q3 \n" // a0 = (src[0] * 3 + s[1] * 1) >> 2 - "vmovl.u8 q3, d1 \n" - "vmlal.u8 q3, d0, d24 \n" - "vqrshrn.u16 d0, q3, #2 \n" + "vmovl.u8 q3, d1 \n" + "vmlal.u8 q3, d0, d24 \n" + "vqrshrn.u16 d0, q3, #2 \n" // a1 = (src[1] * 1 + s[2] * 1) >> 1 - "vrhadd.u8 d1, d1, d2 \n" + "vrhadd.u8 d1, d1, d2 \n" // a2 = (src[2] * 1 + s[3] * 3) >> 2 - "vmovl.u8 q3, d2 \n" - "vmlal.u8 q3, d3, d24 \n" - "vqrshrn.u16 d2, q3, #2 \n" + "vmovl.u8 q3, d2 \n" + "vmlal.u8 q3, d3, d24 \n" + "vqrshrn.u16 d2, q3, #2 \n" - "vst3.8 {d0, d1, d2}, [%1]! \n" - "bgt 1b \n" + "vst3.8 {d0, d1, d2}, [%1]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width), // %2 @@ -282,15 +282,15 @@ void ScaleRowDown38_NEON(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "vld1.8 {q3}, [%3] \n" + "vld1.8 {q3}, [%3] \n" "1: \n" - "vld1.8 {d0, d1, d2, d3}, [%0]! \n" - "subs %2, %2, #12 \n" - "vtbl.u8 d4, {d0, d1, d2, d3}, d6 \n" - "vtbl.u8 d5, {d0, d1, d2, d3}, d7 \n" - "vst1.8 {d4}, [%1]! \n" - "vst1.32 {d5[0]}, [%1]! \n" - "bgt 1b \n" + "vld1.8 {d0, d1, d2, d3}, [%0]! \n" + "subs %2, %2, #12 \n" + "vtbl.u8 d4, {d0, d1, d2, d3}, d6 \n" + "vtbl.u8 d5, {d0, d1, d2, d3}, d7 \n" + "vst1.8 {d4}, [%1]! \n" + "vst1.32 {d5[0]}, [%1]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -306,57 +306,57 @@ void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, const uint8_t* src_ptr1 = src_ptr + src_stride * 2; asm volatile( - "vld1.16 {q13}, [%5] \n" - "vld1.8 {q14}, [%6] \n" - "vld1.8 {q15}, [%7] \n" - "add %3, %0 \n" + "vld1.16 {q13}, [%5] \n" + "vld1.8 {q14}, [%6] \n" + "vld1.8 {q15}, [%7] \n" + "add %3, %0 \n" "1: \n" // d0 = 00 40 01 41 02 42 03 43 // d1 = 10 50 11 51 12 52 13 53 // d2 = 20 60 21 61 22 62 23 63 // d3 = 30 70 31 71 32 72 33 73 - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" - "vld4.8 {d4, d5, d6, d7}, [%3]! \n" - "vld4.8 {d16, d17, d18, d19}, [%4]! \n" - "subs %2, %2, #12 \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" + "vld4.8 {d4, d5, d6, d7}, [%3]! \n" + "vld4.8 {d16, d17, d18, d19}, [%4]! \n" + "subs %2, %2, #12 \n" // Shuffle the input data around to get align the data // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 // d0 = 00 10 01 11 02 12 03 13 // d1 = 40 50 41 51 42 52 43 53 - "vtrn.u8 d0, d1 \n" - "vtrn.u8 d4, d5 \n" - "vtrn.u8 d16, d17 \n" + "vtrn.u8 d0, d1 \n" + "vtrn.u8 d4, d5 \n" + "vtrn.u8 d16, d17 \n" // d2 = 20 30 21 31 22 32 23 33 // d3 = 60 70 61 71 62 72 63 73 - "vtrn.u8 d2, d3 \n" - "vtrn.u8 d6, d7 \n" - "vtrn.u8 d18, d19 \n" + "vtrn.u8 d2, d3 \n" + "vtrn.u8 d6, d7 \n" + "vtrn.u8 d18, d19 \n" // d0 = 00+10 01+11 02+12 03+13 // d2 = 40+50 41+51 42+52 43+53 - "vpaddl.u8 q0, q0 \n" - "vpaddl.u8 q2, q2 \n" - "vpaddl.u8 q8, q8 \n" + "vpaddl.u8 q0, q0 \n" + "vpaddl.u8 q2, q2 \n" + "vpaddl.u8 q8, q8 \n" // d3 = 60+70 61+71 62+72 63+73 - "vpaddl.u8 d3, d3 \n" - "vpaddl.u8 d7, d7 \n" - "vpaddl.u8 d19, d19 \n" + "vpaddl.u8 d3, d3 \n" + "vpaddl.u8 d7, d7 \n" + "vpaddl.u8 d19, d19 \n" // combine source lines - "vadd.u16 q0, q2 \n" - "vadd.u16 q0, q8 \n" - "vadd.u16 d4, d3, d7 \n" - "vadd.u16 d4, d19 \n" + "vadd.u16 q0, q2 \n" + "vadd.u16 q0, q8 \n" + "vadd.u16 d4, d3, d7 \n" + "vadd.u16 d4, d19 \n" // dst_ptr[3] = (s[6 + st * 0] + s[7 + st * 0] // + s[6 + st * 1] + s[7 + st * 1] // + s[6 + st * 2] + s[7 + st * 2]) / 6 "vqrdmulh.s16 q2, q2, q13 \n" - "vmovn.u16 d4, q2 \n" + "vmovn.u16 d4, q2 \n" // Shuffle 2,3 reg around so that 2 can be added to the // 0,1 reg and 3 can be added to the 4,5 reg. This @@ -364,24 +364,24 @@ void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, // registers are already expanded. Then do transposes // to get aligned. // q2 = xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 - "vmovl.u8 q1, d2 \n" - "vmovl.u8 q3, d6 \n" - "vmovl.u8 q9, d18 \n" + "vmovl.u8 q1, d2 \n" + "vmovl.u8 q3, d6 \n" + "vmovl.u8 q9, d18 \n" // combine source lines - "vadd.u16 q1, q3 \n" - "vadd.u16 q1, q9 \n" + "vadd.u16 q1, q3 \n" + "vadd.u16 q1, q9 \n" // d4 = xx 20 xx 30 xx 22 xx 32 // d5 = xx 21 xx 31 xx 23 xx 33 - "vtrn.u32 d2, d3 \n" + "vtrn.u32 d2, d3 \n" // d4 = xx 20 xx 21 xx 22 xx 23 // d5 = xx 30 xx 31 xx 32 xx 33 - "vtrn.u16 d2, d3 \n" + "vtrn.u16 d2, d3 \n" // 0+1+2, 3+4+5 - "vadd.u16 q0, q1 \n" + "vadd.u16 q0, q1 \n" // Need to divide, but can't downshift as the the value // isn't a power of 2. So multiply by 65536 / n @@ -390,14 +390,14 @@ void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, // Align for table lookup, vtbl requires registers to // be adjacent - "vmov.u8 d2, d4 \n" + "vmov.u8 d2, d4 \n" - "vtbl.u8 d3, {d0, d1, d2}, d28 \n" - "vtbl.u8 d4, {d0, d1, d2}, d29 \n" + "vtbl.u8 d3, {d0, d1, d2}, d28 \n" + "vtbl.u8 d4, {d0, d1, d2}, d29 \n" - "vst1.8 {d3}, [%1]! \n" - "vst1.32 {d4[0]}, [%1]! \n" - "bgt 1b \n" + "vst1.8 {d3}, [%1]! \n" + "vst1.32 {d4[0]}, [%1]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width), // %2 @@ -416,46 +416,46 @@ void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "vld1.16 {q13}, [%4] \n" - "vld1.8 {q14}, [%5] \n" - "add %3, %0 \n" + "vld1.16 {q13}, [%4] \n" + "vld1.8 {q14}, [%5] \n" + "add %3, %0 \n" "1: \n" // d0 = 00 40 01 41 02 42 03 43 // d1 = 10 50 11 51 12 52 13 53 // d2 = 20 60 21 61 22 62 23 63 // d3 = 30 70 31 71 32 72 33 73 - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" - "vld4.8 {d4, d5, d6, d7}, [%3]! \n" - "subs %2, %2, #12 \n" + "vld4.8 {d0, d1, d2, d3}, [%0]! \n" + "vld4.8 {d4, d5, d6, d7}, [%3]! \n" + "subs %2, %2, #12 \n" // Shuffle the input data around to get align the data // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 // d0 = 00 10 01 11 02 12 03 13 // d1 = 40 50 41 51 42 52 43 53 - "vtrn.u8 d0, d1 \n" - "vtrn.u8 d4, d5 \n" + "vtrn.u8 d0, d1 \n" + "vtrn.u8 d4, d5 \n" // d2 = 20 30 21 31 22 32 23 33 // d3 = 60 70 61 71 62 72 63 73 - "vtrn.u8 d2, d3 \n" - "vtrn.u8 d6, d7 \n" + "vtrn.u8 d2, d3 \n" + "vtrn.u8 d6, d7 \n" // d0 = 00+10 01+11 02+12 03+13 // d2 = 40+50 41+51 42+52 43+53 - "vpaddl.u8 q0, q0 \n" - "vpaddl.u8 q2, q2 \n" + "vpaddl.u8 q0, q0 \n" + "vpaddl.u8 q2, q2 \n" // d3 = 60+70 61+71 62+72 63+73 - "vpaddl.u8 d3, d3 \n" - "vpaddl.u8 d7, d7 \n" + "vpaddl.u8 d3, d3 \n" + "vpaddl.u8 d7, d7 \n" // combine source lines - "vadd.u16 q0, q2 \n" - "vadd.u16 d4, d3, d7 \n" + "vadd.u16 q0, q2 \n" + "vadd.u16 d4, d3, d7 \n" // dst_ptr[3] = (s[6] + s[7] + s[6+st] + s[7+st]) / 4 - "vqrshrn.u16 d4, q2, #2 \n" + "vqrshrn.u16 d4, q2, #2 \n" // Shuffle 2,3 reg around so that 2 can be added to the // 0,1 reg and 3 can be added to the 4,5 reg. This @@ -463,22 +463,22 @@ void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, // registers are already expanded. Then do transposes // to get aligned. // q2 = xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 - "vmovl.u8 q1, d2 \n" - "vmovl.u8 q3, d6 \n" + "vmovl.u8 q1, d2 \n" + "vmovl.u8 q3, d6 \n" // combine source lines - "vadd.u16 q1, q3 \n" + "vadd.u16 q1, q3 \n" // d4 = xx 20 xx 30 xx 22 xx 32 // d5 = xx 21 xx 31 xx 23 xx 33 - "vtrn.u32 d2, d3 \n" + "vtrn.u32 d2, d3 \n" // d4 = xx 20 xx 21 xx 22 xx 23 // d5 = xx 30 xx 31 xx 32 xx 33 - "vtrn.u16 d2, d3 \n" + "vtrn.u16 d2, d3 \n" // 0+1+2, 3+4+5 - "vadd.u16 q0, q1 \n" + "vadd.u16 q0, q1 \n" // Need to divide, but can't downshift as the the value // isn't a power of 2. So multiply by 65536 / n @@ -487,14 +487,14 @@ void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, // Align for table lookup, vtbl requires registers to // be adjacent - "vmov.u8 d2, d4 \n" + "vmov.u8 d2, d4 \n" - "vtbl.u8 d3, {d0, d1, d2}, d28 \n" - "vtbl.u8 d4, {d0, d1, d2}, d29 \n" + "vtbl.u8 d3, {d0, d1, d2}, d28 \n" + "vtbl.u8 d4, {d0, d1, d2}, d29 \n" - "vst1.8 {d3}, [%1]! \n" - "vst1.32 {d4[0]}, [%1]! \n" - "bgt 1b \n" + "vst1.8 {d3}, [%1]! \n" + "vst1.32 {d4[0]}, [%1]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width), // %2 @@ -511,13 +511,13 @@ void ScaleAddRow_NEON(const uint8_t* src_ptr, int src_width) { asm volatile( "1: \n" - "vld1.16 {q1, q2}, [%1] \n" // load accumulator - "vld1.8 {q0}, [%0]! \n" // load 16 bytes - "vaddw.u8 q2, q2, d1 \n" // add - "vaddw.u8 q1, q1, d0 \n" - "vst1.16 {q1, q2}, [%1]! \n" // store accumulator - "subs %2, %2, #16 \n" // 16 processed per loop - "bgt 1b \n" + "vld1.16 {q1, q2}, [%1] \n" // load accumulator + "vld1.8 {q0}, [%0]! \n" // load 16 bytes + "vaddw.u8 q2, q2, d1 \n" // add + "vaddw.u8 q1, q1, d0 \n" + "vst1.16 {q1, q2}, [%1]! \n" // store accumulator + "subs %2, %2, #16 \n" // 16 processed per loop + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(src_width) // %2 @@ -547,17 +547,17 @@ void ScaleFilterCols_NEON(uint8_t* dst_ptr, int* tmp = dx_offset; const uint8_t* src_tmp = src_ptr; asm volatile ( - "vdup.32 q0, %3 \n" // x - "vdup.32 q1, %4 \n" // dx - "vld1.32 {q2}, [%5] \n" // 0 1 2 3 - "vshl.i32 q3, q1, #2 \n" // 4 * dx - "vmul.s32 q1, q1, q2 \n" + "vdup.32 q0, %3 \n" // x + "vdup.32 q1, %4 \n" // dx + "vld1.32 {q2}, [%5] \n" // 0 1 2 3 + "vshl.i32 q3, q1, #2 \n" // 4 * dx + "vmul.s32 q1, q1, q2 \n" // x , x + 1 * dx, x + 2 * dx, x + 3 * dx - "vadd.s32 q1, q1, q0 \n" + "vadd.s32 q1, q1, q0 \n" // x + 4 * dx, x + 5 * dx, x + 6 * dx, x + 7 * dx - "vadd.s32 q2, q1, q3 \n" - "vshl.i32 q0, q3, #1 \n" // 8 * dx - "1: \n" + "vadd.s32 q2, q1, q3 \n" + "vshl.i32 q0, q3, #1 \n" // 8 * dx + "1: \n" LOAD2_DATA8_LANE(0) LOAD2_DATA8_LANE(1) LOAD2_DATA8_LANE(2) @@ -566,27 +566,27 @@ void ScaleFilterCols_NEON(uint8_t* dst_ptr, LOAD2_DATA8_LANE(5) LOAD2_DATA8_LANE(6) LOAD2_DATA8_LANE(7) - "vmov q10, q1 \n" - "vmov q11, q2 \n" - "vuzp.16 q10, q11 \n" - "vmovl.u8 q8, d6 \n" - "vmovl.u8 q9, d7 \n" - "vsubl.s16 q11, d18, d16 \n" - "vsubl.s16 q12, d19, d17 \n" - "vmovl.u16 q13, d20 \n" - "vmovl.u16 q10, d21 \n" - "vmul.s32 q11, q11, q13 \n" - "vmul.s32 q12, q12, q10 \n" - "vrshrn.s32 d18, q11, #16 \n" - "vrshrn.s32 d19, q12, #16 \n" - "vadd.s16 q8, q8, q9 \n" - "vmovn.s16 d6, q8 \n" + "vmov q10, q1 \n" + "vmov q11, q2 \n" + "vuzp.16 q10, q11 \n" + "vmovl.u8 q8, d6 \n" + "vmovl.u8 q9, d7 \n" + "vsubl.s16 q11, d18, d16 \n" + "vsubl.s16 q12, d19, d17 \n" + "vmovl.u16 q13, d20 \n" + "vmovl.u16 q10, d21 \n" + "vmul.s32 q11, q11, q13 \n" + "vmul.s32 q12, q12, q10 \n" + "vrshrn.s32 d18, q11, #16 \n" + "vrshrn.s32 d19, q12, #16 \n" + "vadd.s16 q8, q8, q9 \n" + "vmovn.s16 d6, q8 \n" - "vst1.8 {d6}, [%0]! \n" // store pixels - "vadd.s32 q1, q1, q0 \n" - "vadd.s32 q2, q2, q0 \n" - "subs %2, %2, #8 \n" // 8 processed per loop - "bgt 1b \n" + "vst1.8 {d6}, [%0]! \n" // store pixels + "vadd.s32 q1, q1, q0 \n" + "vadd.s32 q2, q2, q0 \n" + "subs %2, %2, #8 \n" // 8 processed per loop + "bgt 1b \n" : "+r"(dst_ptr), // %0 "+r"(src_ptr), // %1 "+r"(dst_width), // %2 @@ -609,75 +609,75 @@ void ScaleFilterRows_NEON(uint8_t* dst_ptr, int dst_width, int source_y_fraction) { asm volatile( - "cmp %4, #0 \n" - "beq 100f \n" - "add %2, %1 \n" - "cmp %4, #64 \n" - "beq 75f \n" - "cmp %4, #128 \n" - "beq 50f \n" - "cmp %4, #192 \n" - "beq 25f \n" + "cmp %4, #0 \n" + "beq 100f \n" + "add %2, %1 \n" + "cmp %4, #64 \n" + "beq 75f \n" + "cmp %4, #128 \n" + "beq 50f \n" + "cmp %4, #192 \n" + "beq 25f \n" - "vdup.8 d5, %4 \n" - "rsb %4, #256 \n" - "vdup.8 d4, %4 \n" + "vdup.8 d5, %4 \n" + "rsb %4, #256 \n" + "vdup.8 d4, %4 \n" // General purpose row blend. "1: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vmull.u8 q13, d0, d4 \n" - "vmull.u8 q14, d1, d4 \n" - "vmlal.u8 q13, d2, d5 \n" - "vmlal.u8 q14, d3, d5 \n" - "vrshrn.u16 d0, q13, #8 \n" - "vrshrn.u16 d1, q14, #8 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 1b \n" - "b 99f \n" + "vld1.8 {q0}, [%1]! \n" + "vld1.8 {q1}, [%2]! \n" + "subs %3, %3, #16 \n" + "vmull.u8 q13, d0, d4 \n" + "vmull.u8 q14, d1, d4 \n" + "vmlal.u8 q13, d2, d5 \n" + "vmlal.u8 q14, d3, d5 \n" + "vrshrn.u16 d0, q13, #8 \n" + "vrshrn.u16 d1, q14, #8 \n" + "vst1.8 {q0}, [%0]! \n" + "bgt 1b \n" + "b 99f \n" // Blend 25 / 75. "25: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vrhadd.u8 q0, q1 \n" - "vrhadd.u8 q0, q1 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 25b \n" - "b 99f \n" + "vld1.8 {q0}, [%1]! \n" + "vld1.8 {q1}, [%2]! \n" + "subs %3, %3, #16 \n" + "vrhadd.u8 q0, q1 \n" + "vrhadd.u8 q0, q1 \n" + "vst1.8 {q0}, [%0]! \n" + "bgt 25b \n" + "b 99f \n" // Blend 50 / 50. "50: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vrhadd.u8 q0, q1 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 50b \n" - "b 99f \n" + "vld1.8 {q0}, [%1]! \n" + "vld1.8 {q1}, [%2]! \n" + "subs %3, %3, #16 \n" + "vrhadd.u8 q0, q1 \n" + "vst1.8 {q0}, [%0]! \n" + "bgt 50b \n" + "b 99f \n" // Blend 75 / 25. "75: \n" - "vld1.8 {q1}, [%1]! \n" - "vld1.8 {q0}, [%2]! \n" - "subs %3, %3, #16 \n" - "vrhadd.u8 q0, q1 \n" - "vrhadd.u8 q0, q1 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 75b \n" - "b 99f \n" + "vld1.8 {q1}, [%1]! \n" + "vld1.8 {q0}, [%2]! \n" + "subs %3, %3, #16 \n" + "vrhadd.u8 q0, q1 \n" + "vrhadd.u8 q0, q1 \n" + "vst1.8 {q0}, [%0]! \n" + "bgt 75b \n" + "b 99f \n" // Blend 100 / 0 - Copy row unchanged. "100: \n" - "vld1.8 {q0}, [%1]! \n" - "subs %3, %3, #16 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 100b \n" + "vld1.8 {q0}, [%1]! \n" + "subs %3, %3, #16 \n" + "vst1.8 {q0}, [%0]! \n" + "bgt 100b \n" "99: \n" - "vst1.8 {d1[7]}, [%0] \n" + "vst1.8 {d1[7]}, [%0] \n" : "+r"(dst_ptr), // %0 "+r"(src_ptr), // %1 "+r"(src_stride), // %2 @@ -694,12 +694,12 @@ void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr, (void)src_stride; asm volatile( "1: \n" - "vld4.32 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.32 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB - "subs %2, %2, #8 \n" // 8 processed per loop - "vmov q2, q1 \n" // load next 8 ARGB - "vst2.32 {q2, q3}, [%1]! \n" // store odd pixels - "bgt 1b \n" + "vld4.32 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. + "vld4.32 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB + "subs %2, %2, #8 \n" // 8 processed per loop + "vmov q2, q1 \n" // load next 8 ARGB + "vst2.32 {q2, q3}, [%1]! \n" // store odd pixels + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst), // %1 "+r"(dst_width) // %2 @@ -722,13 +722,13 @@ void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb, (void)src_stride; asm volatile( "1: \n" - "vld4.32 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.32 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB - "subs %2, %2, #8 \n" // 8 processed per loop - "vrhadd.u8 q0, q0, q1 \n" // rounding half add - "vrhadd.u8 q1, q2, q3 \n" // rounding half add - "vst2.32 {q0, q1}, [%1]! \n" - "bgt 1b \n" + "vld4.32 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. + "vld4.32 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB + "subs %2, %2, #8 \n" // 8 processed per loop + "vrhadd.u8 q0, q0, q1 \n" // rounding half add + "vrhadd.u8 q1, q2, q3 \n" // rounding half add + "vst2.32 {q0, q1}, [%1]! \n" + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(dst_width) // %2 @@ -743,27 +743,27 @@ void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr, int dst_width) { asm volatile( // change the stride to row 2 pointer - "add %1, %1, %0 \n" + "add %1, %1, %0 \n" "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB - "subs %3, %3, #8 \n" // 8 processed per loop. - "vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts. - "vpaddl.u8 q3, q3 \n" // A 16 bytes -> 8 shorts. - "vld4.8 {d16, d18, d20, d22}, [%1]! \n" // load 8 more ARGB - "vld4.8 {d17, d19, d21, d23}, [%1]! \n" // load last 8 ARGB - "vpadal.u8 q0, q8 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q9 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q10 \n" // R 16 bytes -> 8 shorts. - "vpadal.u8 q3, q11 \n" // A 16 bytes -> 8 shorts. - "vrshrn.u16 d0, q0, #2 \n" // round and pack to bytes - "vrshrn.u16 d1, q1, #2 \n" - "vrshrn.u16 d2, q2, #2 \n" - "vrshrn.u16 d3, q3, #2 \n" - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" - "bgt 1b \n" + "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. + "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB + "subs %3, %3, #8 \n" // 8 processed per loop. + "vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. + "vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts. + "vpaddl.u8 q3, q3 \n" // A 16 bytes -> 8 shorts. + "vld4.8 {d16, d18, d20, d22}, [%1]! \n" // load 8 more ARGB + "vld4.8 {d17, d19, d21, d23}, [%1]! \n" // load last 8 ARGB + "vpadal.u8 q0, q8 \n" // B 16 bytes -> 8 shorts. + "vpadal.u8 q1, q9 \n" // G 16 bytes -> 8 shorts. + "vpadal.u8 q2, q10 \n" // R 16 bytes -> 8 shorts. + "vpadal.u8 q3, q11 \n" // A 16 bytes -> 8 shorts. + "vrshrn.u16 d0, q0, #2 \n" // round and pack to bytes + "vrshrn.u16 d1, q1, #2 \n" + "vrshrn.u16 d2, q2, #2 \n" + "vrshrn.u16 d3, q3, #2 \n" + "vst4.8 {d0, d1, d2, d3}, [%2]! \n" + "bgt 1b \n" : "+r"(src_ptr), // %0 "+r"(src_stride), // %1 "+r"(dst), // %2 @@ -781,15 +781,15 @@ void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb, int dst_width) { (void)src_stride; asm volatile( - "mov r12, %3, lsl #2 \n" + "mov r12, %3, lsl #2 \n" "1: \n" - "vld1.32 {d0[0]}, [%0], r12 \n" - "vld1.32 {d0[1]}, [%0], r12 \n" - "vld1.32 {d1[0]}, [%0], r12 \n" - "vld1.32 {d1[1]}, [%0], r12 \n" - "subs %2, %2, #4 \n" // 4 pixels per loop. - "vst1.8 {q0}, [%1]! \n" - "bgt 1b \n" + "vld1.32 {d0[0]}, [%0], r12 \n" + "vld1.32 {d0[1]}, [%0], r12 \n" + "vld1.32 {d1[0]}, [%0], r12 \n" + "vld1.32 {d1[1]}, [%0], r12 \n" + "subs %2, %2, #4 \n" // 4 pixels per loop. + "vst1.8 {q0}, [%1]! \n" + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(dst_width) // %2 @@ -805,30 +805,30 @@ void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int dst_width) { asm volatile( - "mov r12, %4, lsl #2 \n" - "add %1, %1, %0 \n" + "mov r12, %4, lsl #2 \n" + "add %1, %1, %0 \n" "1: \n" - "vld1.8 {d0}, [%0], r12 \n" // 4 2x2 blocks -> 2x1 - "vld1.8 {d1}, [%1], r12 \n" - "vld1.8 {d2}, [%0], r12 \n" - "vld1.8 {d3}, [%1], r12 \n" - "vld1.8 {d4}, [%0], r12 \n" - "vld1.8 {d5}, [%1], r12 \n" - "vld1.8 {d6}, [%0], r12 \n" - "vld1.8 {d7}, [%1], r12 \n" - "vaddl.u8 q0, d0, d1 \n" - "vaddl.u8 q1, d2, d3 \n" - "vaddl.u8 q2, d4, d5 \n" - "vaddl.u8 q3, d6, d7 \n" - "vswp.8 d1, d2 \n" // ab_cd -> ac_bd - "vswp.8 d5, d6 \n" // ef_gh -> eg_fh - "vadd.u16 q0, q0, q1 \n" // (a+b)_(c+d) - "vadd.u16 q2, q2, q3 \n" // (e+f)_(g+h) - "vrshrn.u16 d0, q0, #2 \n" // first 2 pixels. - "vrshrn.u16 d1, q2, #2 \n" // next 2 pixels. - "subs %3, %3, #4 \n" // 4 pixels per loop. - "vst1.8 {q0}, [%2]! \n" - "bgt 1b \n" + "vld1.8 {d0}, [%0], r12 \n" // 4 2x2 blocks -> 2x1 + "vld1.8 {d1}, [%1], r12 \n" + "vld1.8 {d2}, [%0], r12 \n" + "vld1.8 {d3}, [%1], r12 \n" + "vld1.8 {d4}, [%0], r12 \n" + "vld1.8 {d5}, [%1], r12 \n" + "vld1.8 {d6}, [%0], r12 \n" + "vld1.8 {d7}, [%1], r12 \n" + "vaddl.u8 q0, d0, d1 \n" + "vaddl.u8 q1, d2, d3 \n" + "vaddl.u8 q2, d4, d5 \n" + "vaddl.u8 q3, d6, d7 \n" + "vswp.8 d1, d2 \n" // ab_cd -> ac_bd + "vswp.8 d5, d6 \n" // ef_gh -> eg_fh + "vadd.u16 q0, q0, q1 \n" // (a+b)_(c+d) + "vadd.u16 q2, q2, q3 \n" // (e+f)_(g+h) + "vrshrn.u16 d0, q0, #2 \n" // first 2 pixels. + "vrshrn.u16 d1, q2, #2 \n" // next 2 pixels. + "subs %3, %3, #4 \n" // 4 pixels per loop. + "vst1.8 {q0}, [%2]! \n" + "bgt 1b \n" : "+r"(src_argb), // %0 "+r"(src_stride), // %1 "+r"(dst_argb), // %2 @@ -865,8 +865,8 @@ void ScaleARGBCols_NEON(uint8_t* dst_argb, LOAD1_DATA32_LANE(d3, 1) // clang-format on "vst1.32 {q0, q1}, [%0]! \n" // store pixels - "subs %2, %2, #8 \n" // 8 processed per loop - "bgt 1b \n" + "subs %2, %2, #8 \n" // 8 processed per loop + "bgt 1b \n" : "+r"(dst_argb), // %0 "+r"(src_argb), // %1 "+r"(dst_width), // %2 @@ -897,16 +897,16 @@ void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, int* tmp = dx_offset; const uint8_t* src_tmp = src_argb; asm volatile ( - "vdup.32 q0, %3 \n" // x - "vdup.32 q1, %4 \n" // dx - "vld1.32 {q2}, [%5] \n" // 0 1 2 3 - "vshl.i32 q9, q1, #2 \n" // 4 * dx - "vmul.s32 q1, q1, q2 \n" - "vmov.i8 q3, #0x7f \n" // 0x7F - "vmov.i16 q15, #0x7f \n" // 0x7F + "vdup.32 q0, %3 \n" // x + "vdup.32 q1, %4 \n" // dx + "vld1.32 {q2}, [%5] \n" // 0 1 2 3 + "vshl.i32 q9, q1, #2 \n" // 4 * dx + "vmul.s32 q1, q1, q2 \n" + "vmov.i8 q3, #0x7f \n" // 0x7F + "vmov.i16 q15, #0x7f \n" // 0x7F // x , x + 1 * dx, x + 2 * dx, x + 3 * dx - "vadd.s32 q8, q1, q0 \n" - "1: \n" + "vadd.s32 q8, q1, q0 \n" + "1: \n" // d0, d1: a // d2, d3: b LOAD2_DATA32_LANE(d0, d2, 0) @@ -950,6 +950,64 @@ void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, #undef LOAD2_DATA32_LANE +void ScaleUVRowDown2Box_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst, + int dst_width) { + asm volatile( + // change the stride to row 2 pointer + "add %1, %1, %0 \n" + "1: \n" + "vld2.8 {d0, d2}, [%0]! \n" // load 8 UV pixels. + "vld2.8 {d1, d3}, [%0]! \n" // load next 8 UV + "subs %3, %3, #8 \n" // 8 processed per loop. + "vpaddl.u8 q0, q0 \n" // U 16 bytes -> 8 shorts. + "vpaddl.u8 q1, q1 \n" // V 16 bytes -> 8 shorts. + "vld2.8 {d16, d18}, [%1]! \n" // load 8 more UV + "vld2.8 {d17, d19}, [%1]! \n" // load last 8 UV + "vpadal.u8 q0, q8 \n" // U 16 bytes -> 8 shorts. + "vpadal.u8 q1, q9 \n" // V 16 bytes -> 8 shorts. + "vrshrn.u16 d0, q0, #2 \n" // round and pack to bytes + "vrshrn.u16 d1, q1, #2 \n" + "vst2.8 {d0, d1}, [%2]! \n" + "bgt 1b \n" + : "+r"(src_ptr), // %0 + "+r"(src_stride), // %1 + "+r"(dst), // %2 + "+r"(dst_width) // %3 + : + : "memory", "cc", "q0", "q1", "q8", "q9"); +} + +// Reads 4 pixels at a time. +void ScaleUVRowDownEven_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, // pixel step + uint8_t* dst_ptr, + int dst_width) { + const uint8_t* src1_ptr = src_ptr + src_stepx * 2; + const uint8_t* src2_ptr = src_ptr + src_stepx * 4; + const uint8_t* src3_ptr = src_ptr + src_stepx * 6; + (void)src_stride; + asm volatile( + "1: \n" + "vld1.16 {d0[0]}, [%0], %6 \n" + "vld1.16 {d0[1]}, [%1], %6 \n" + "vld1.16 {d0[2]}, [%2], %6 \n" + "vld1.16 {d0[3]}, [%3], %6 \n" + "subs %5, %5, #4 \n" // 4 pixels per loop. + "vst1.8 {d0}, [%4]! \n" + "bgt 1b \n" + : "+r"(src_ptr), // %0 + "+r"(src1_ptr), // %1 + "+r"(src2_ptr), // %2 + "+r"(src3_ptr), // %3 + "+r"(dst_ptr), // %4 + "+r"(dst_width) // %5 + : "r"(src_stepx * 8) // %6 + : "memory", "cc", "d0"); +} + #endif // defined(__ARM_NEON__) && !defined(__aarch64__) #ifdef __cplusplus diff --git a/TMessagesProj/jni/third_party/libyuv/source/scale_neon64.cc b/TMessagesProj/jni/third_party/libyuv/source/scale_neon64.cc index 0a7b80ce1..185591cb5 100644 --- a/TMessagesProj/jni/third_party/libyuv/source/scale_neon64.cc +++ b/TMessagesProj/jni/third_party/libyuv/source/scale_neon64.cc @@ -29,10 +29,11 @@ void ScaleRowDown2_NEON(const uint8_t* src_ptr, asm volatile( "1: \n" // load even pixels into v0, odd into v1 - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" - "subs %w2, %w2, #16 \n" // 16 processed per loop - "st1 {v1.16b}, [%1], #16 \n" // store odd pixels - "b.gt 1b \n" + "ld2 {v0.16b,v1.16b}, [%0], #32 \n" + "subs %w2, %w2, #16 \n" // 16 processed per loop + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "st1 {v1.16b}, [%1], #16 \n" // store odd pixels + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst), // %1 "+r"(dst_width) // %2 @@ -50,11 +51,12 @@ void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr, asm volatile( "1: \n" // load even pixels into v0, odd into v1 - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" - "subs %w2, %w2, #16 \n" // 16 processed per loop - "urhadd v0.16b, v0.16b, v1.16b \n" // rounding half add - "st1 {v0.16b}, [%1], #16 \n" - "b.gt 1b \n" + "ld2 {v0.16b,v1.16b}, [%0], #32 \n" + "subs %w2, %w2, #16 \n" // 16 processed per loop + "urhadd v0.16b, v0.16b, v1.16b \n" // rounding half add + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "st1 {v0.16b}, [%1], #16 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst), // %1 "+r"(dst_width) // %2 @@ -70,19 +72,21 @@ void ScaleRowDown2Box_NEON(const uint8_t* src_ptr, int dst_width) { asm volatile( // change the stride to row 2 pointer - "add %1, %1, %0 \n" + "add %1, %1, %0 \n" "1: \n" - "ld1 {v0.16b, v1.16b}, [%0], #32 \n" // load row 1 and post inc - "ld1 {v2.16b, v3.16b}, [%1], #32 \n" // load row 2 and post inc - "subs %w3, %w3, #16 \n" // 16 processed per loop - "uaddlp v0.8h, v0.16b \n" // row 1 add adjacent - "uaddlp v1.8h, v1.16b \n" - "uadalp v0.8h, v2.16b \n" // += row 2 add adjacent - "uadalp v1.8h, v3.16b \n" - "rshrn v0.8b, v0.8h, #2 \n" // round and pack - "rshrn2 v0.16b, v1.8h, #2 \n" - "st1 {v0.16b}, [%2], #16 \n" - "b.gt 1b \n" + "ld1 {v0.16b, v1.16b}, [%0], #32 \n" // load row 1 and post inc + "ld1 {v2.16b, v3.16b}, [%1], #32 \n" // load row 2 and post inc + "subs %w3, %w3, #16 \n" // 16 processed per loop + "uaddlp v0.8h, v0.16b \n" // row 1 add adjacent + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "uaddlp v1.8h, v1.16b \n" + "prfm pldl1keep, [%1, 448] \n" + "uadalp v0.8h, v2.16b \n" // += row 2 add adjacent + "uadalp v1.8h, v3.16b \n" + "rshrn v0.8b, v0.8h, #2 \n" // round and pack + "rshrn2 v0.16b, v1.8h, #2 \n" + "st1 {v0.16b}, [%2], #16 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(src_stride), // %1 "+r"(dst), // %2 @@ -99,10 +103,11 @@ void ScaleRowDown4_NEON(const uint8_t* src_ptr, (void)src_stride; asm volatile( "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 - "subs %w2, %w2, #8 \n" // 8 processed per loop - "st1 {v2.8b}, [%1], #8 \n" - "b.gt 1b \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 + "subs %w2, %w2, #8 \n" // 8 processed per loop + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "st1 {v2.8b}, [%1], #8 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -119,19 +124,23 @@ void ScaleRowDown4Box_NEON(const uint8_t* src_ptr, const uint8_t* src_ptr3 = src_ptr + src_stride * 3; asm volatile( "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load up 16x4 - "ld1 {v1.16b}, [%2], #16 \n" - "ld1 {v2.16b}, [%3], #16 \n" - "ld1 {v3.16b}, [%4], #16 \n" - "subs %w5, %w5, #4 \n" - "uaddlp v0.8h, v0.16b \n" - "uadalp v0.8h, v1.16b \n" - "uadalp v0.8h, v2.16b \n" - "uadalp v0.8h, v3.16b \n" - "addp v0.8h, v0.8h, v0.8h \n" - "rshrn v0.8b, v0.8h, #4 \n" // divide by 16 w/rounding - "st1 {v0.s}[0], [%1], #4 \n" - "b.gt 1b \n" + "ld1 {v0.16b}, [%0], #16 \n" // load up 16x4 + "ld1 {v1.16b}, [%2], #16 \n" + "ld1 {v2.16b}, [%3], #16 \n" + "ld1 {v3.16b}, [%4], #16 \n" + "subs %w5, %w5, #4 \n" + "uaddlp v0.8h, v0.16b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "uadalp v0.8h, v1.16b \n" + "prfm pldl1keep, [%2, 448] \n" + "uadalp v0.8h, v2.16b \n" + "prfm pldl1keep, [%3, 448] \n" + "uadalp v0.8h, v3.16b \n" + "prfm pldl1keep, [%4, 448] \n" + "addp v0.8h, v0.8h, v0.8h \n" + "rshrn v0.8b, v0.8h, #4 \n" // divide by 16 w/rounding + "st1 {v0.s}[0], [%1], #4 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(src_ptr1), // %2 @@ -151,12 +160,13 @@ void ScaleRowDown34_NEON(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 - "subs %w2, %w2, #24 \n" - "orr v2.16b, v3.16b, v3.16b \n" // order v0,v1,v2 - "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" - "b.gt 1b \n" + "1: \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 + "subs %w2, %w2, #24 \n" + "orr v2.16b, v3.16b, v3.16b \n" // order v0,v1,v2 + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -169,49 +179,51 @@ void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "movi v20.8b, #3 \n" - "add %3, %3, %0 \n" - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32 \n" // src line 1 - "subs %w2, %w2, #24 \n" + "movi v20.8b, #3 \n" + "add %3, %3, %0 \n" + "1: \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32 \n" // src line 1 + "subs %w2, %w2, #24 \n" // filter src line 0 with src line 1 // expand chars to shorts to allow for room // when adding lines together - "ushll v16.8h, v4.8b, #0 \n" - "ushll v17.8h, v5.8b, #0 \n" - "ushll v18.8h, v6.8b, #0 \n" - "ushll v19.8h, v7.8b, #0 \n" + "ushll v16.8h, v4.8b, #0 \n" + "ushll v17.8h, v5.8b, #0 \n" + "ushll v18.8h, v6.8b, #0 \n" + "ushll v19.8h, v7.8b, #0 \n" // 3 * line_0 + line_1 - "umlal v16.8h, v0.8b, v20.8b \n" - "umlal v17.8h, v1.8b, v20.8b \n" - "umlal v18.8h, v2.8b, v20.8b \n" - "umlal v19.8h, v3.8b, v20.8b \n" + "umlal v16.8h, v0.8b, v20.8b \n" + "umlal v17.8h, v1.8b, v20.8b \n" + "umlal v18.8h, v2.8b, v20.8b \n" + "umlal v19.8h, v3.8b, v20.8b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead // (3 * line_0 + line_1) >> 2 - "uqrshrn v0.8b, v16.8h, #2 \n" - "uqrshrn v1.8b, v17.8h, #2 \n" - "uqrshrn v2.8b, v18.8h, #2 \n" - "uqrshrn v3.8b, v19.8h, #2 \n" + "uqrshrn v0.8b, v16.8h, #2 \n" + "uqrshrn v1.8b, v17.8h, #2 \n" + "uqrshrn v2.8b, v18.8h, #2 \n" + "uqrshrn v3.8b, v19.8h, #2 \n" + "prfm pldl1keep, [%3, 448] \n" // a0 = (src[0] * 3 + s[1] * 1) >> 2 - "ushll v16.8h, v1.8b, #0 \n" - "umlal v16.8h, v0.8b, v20.8b \n" - "uqrshrn v0.8b, v16.8h, #2 \n" + "ushll v16.8h, v1.8b, #0 \n" + "umlal v16.8h, v0.8b, v20.8b \n" + "uqrshrn v0.8b, v16.8h, #2 \n" // a1 = (src[1] * 1 + s[2] * 1) >> 1 - "urhadd v1.8b, v1.8b, v2.8b \n" + "urhadd v1.8b, v1.8b, v2.8b \n" // a2 = (src[2] * 1 + s[3] * 3) >> 2 - "ushll v16.8h, v2.8b, #0 \n" - "umlal v16.8h, v3.8b, v20.8b \n" - "uqrshrn v2.8b, v16.8h, #2 \n" + "ushll v16.8h, v2.8b, #0 \n" + "umlal v16.8h, v3.8b, v20.8b \n" + "uqrshrn v2.8b, v16.8h, #2 \n" - "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" + "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" - "b.gt 1b \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width), // %2 @@ -226,33 +238,35 @@ void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int dst_width) { asm volatile( - "movi v20.8b, #3 \n" - "add %3, %3, %0 \n" - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32 \n" // src line 1 - "subs %w2, %w2, #24 \n" + "movi v20.8b, #3 \n" + "add %3, %3, %0 \n" + "1: \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32 \n" // src line 1 + "subs %w2, %w2, #24 \n" // average src line 0 with src line 1 - "urhadd v0.8b, v0.8b, v4.8b \n" - "urhadd v1.8b, v1.8b, v5.8b \n" - "urhadd v2.8b, v2.8b, v6.8b \n" - "urhadd v3.8b, v3.8b, v7.8b \n" + "urhadd v0.8b, v0.8b, v4.8b \n" + "urhadd v1.8b, v1.8b, v5.8b \n" + "urhadd v2.8b, v2.8b, v6.8b \n" + "urhadd v3.8b, v3.8b, v7.8b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead // a0 = (src[0] * 3 + s[1] * 1) >> 2 - "ushll v4.8h, v1.8b, #0 \n" - "umlal v4.8h, v0.8b, v20.8b \n" - "uqrshrn v0.8b, v4.8h, #2 \n" + "ushll v4.8h, v1.8b, #0 \n" + "umlal v4.8h, v0.8b, v20.8b \n" + "uqrshrn v0.8b, v4.8h, #2 \n" + "prfm pldl1keep, [%3, 448] \n" // a1 = (src[1] * 1 + s[2] * 1) >> 1 - "urhadd v1.8b, v1.8b, v2.8b \n" + "urhadd v1.8b, v1.8b, v2.8b \n" // a2 = (src[2] * 1 + s[3] * 3) >> 2 - "ushll v4.8h, v2.8b, #0 \n" - "umlal v4.8h, v3.8b, v20.8b \n" - "uqrshrn v2.8b, v4.8h, #2 \n" + "ushll v4.8h, v2.8b, #0 \n" + "umlal v4.8h, v3.8b, v20.8b \n" + "uqrshrn v2.8b, v4.8h, #2 \n" - "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" - "b.gt 1b \n" + "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width), // %2 @@ -279,14 +293,15 @@ void ScaleRowDown38_NEON(const uint8_t* src_ptr, int dst_width) { (void)src_stride; asm volatile( - "ld1 {v3.16b}, [%3] \n" - "1: \n" - "ld1 {v0.16b,v1.16b}, [%0], #32 \n" - "subs %w2, %w2, #12 \n" - "tbl v2.16b, {v0.16b,v1.16b}, v3.16b \n" - "st1 {v2.8b}, [%1], #8 \n" - "st1 {v2.s}[2], [%1], #4 \n" - "b.gt 1b \n" + "ld1 {v3.16b}, [%3] \n" + "1: \n" + "ld1 {v0.16b,v1.16b}, [%0], #32 \n" + "subs %w2, %w2, #12 \n" + "tbl v2.16b, {v0.16b,v1.16b}, v3.16b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "st1 {v2.8b}, [%1], #8 \n" + "st1 {v2.s}[2], [%1], #4 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(dst_width) // %2 @@ -303,68 +318,68 @@ void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, ptrdiff_t tmp_src_stride = src_stride; asm volatile( - "ld1 {v29.8h}, [%5] \n" - "ld1 {v30.16b}, [%6] \n" - "ld1 {v31.8h}, [%7] \n" - "add %2, %2, %0 \n" - "1: \n" + "ld1 {v29.8h}, [%5] \n" + "ld1 {v30.16b}, [%6] \n" + "ld1 {v31.8h}, [%7] \n" + "add %2, %2, %0 \n" + "1: \n" // 00 40 01 41 02 42 03 43 // 10 50 11 51 12 52 13 53 // 20 60 21 61 22 62 23 63 // 30 70 31 71 32 72 33 73 - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32 \n" - "ld4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%3], #32 \n" - "subs %w4, %w4, #12 \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32 \n" + "ld4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%3], #32 \n" + "subs %w4, %w4, #12 \n" // Shuffle the input data around to get align the data // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 // 00 10 01 11 02 12 03 13 // 40 50 41 51 42 52 43 53 - "trn1 v20.8b, v0.8b, v1.8b \n" - "trn2 v21.8b, v0.8b, v1.8b \n" - "trn1 v22.8b, v4.8b, v5.8b \n" - "trn2 v23.8b, v4.8b, v5.8b \n" - "trn1 v24.8b, v16.8b, v17.8b \n" - "trn2 v25.8b, v16.8b, v17.8b \n" + "trn1 v20.8b, v0.8b, v1.8b \n" + "trn2 v21.8b, v0.8b, v1.8b \n" + "trn1 v22.8b, v4.8b, v5.8b \n" + "trn2 v23.8b, v4.8b, v5.8b \n" + "trn1 v24.8b, v16.8b, v17.8b \n" + "trn2 v25.8b, v16.8b, v17.8b \n" // 20 30 21 31 22 32 23 33 // 60 70 61 71 62 72 63 73 - "trn1 v0.8b, v2.8b, v3.8b \n" - "trn2 v1.8b, v2.8b, v3.8b \n" - "trn1 v4.8b, v6.8b, v7.8b \n" - "trn2 v5.8b, v6.8b, v7.8b \n" - "trn1 v16.8b, v18.8b, v19.8b \n" - "trn2 v17.8b, v18.8b, v19.8b \n" + "trn1 v0.8b, v2.8b, v3.8b \n" + "trn2 v1.8b, v2.8b, v3.8b \n" + "trn1 v4.8b, v6.8b, v7.8b \n" + "trn2 v5.8b, v6.8b, v7.8b \n" + "trn1 v16.8b, v18.8b, v19.8b \n" + "trn2 v17.8b, v18.8b, v19.8b \n" // 00+10 01+11 02+12 03+13 // 40+50 41+51 42+52 43+53 - "uaddlp v20.4h, v20.8b \n" - "uaddlp v21.4h, v21.8b \n" - "uaddlp v22.4h, v22.8b \n" - "uaddlp v23.4h, v23.8b \n" - "uaddlp v24.4h, v24.8b \n" - "uaddlp v25.4h, v25.8b \n" + "uaddlp v20.4h, v20.8b \n" + "uaddlp v21.4h, v21.8b \n" + "uaddlp v22.4h, v22.8b \n" + "uaddlp v23.4h, v23.8b \n" + "uaddlp v24.4h, v24.8b \n" + "uaddlp v25.4h, v25.8b \n" // 60+70 61+71 62+72 63+73 - "uaddlp v1.4h, v1.8b \n" - "uaddlp v5.4h, v5.8b \n" - "uaddlp v17.4h, v17.8b \n" + "uaddlp v1.4h, v1.8b \n" + "uaddlp v5.4h, v5.8b \n" + "uaddlp v17.4h, v17.8b \n" // combine source lines - "add v20.4h, v20.4h, v22.4h \n" - "add v21.4h, v21.4h, v23.4h \n" - "add v20.4h, v20.4h, v24.4h \n" - "add v21.4h, v21.4h, v25.4h \n" - "add v2.4h, v1.4h, v5.4h \n" - "add v2.4h, v2.4h, v17.4h \n" + "add v20.4h, v20.4h, v22.4h \n" + "add v21.4h, v21.4h, v23.4h \n" + "add v20.4h, v20.4h, v24.4h \n" + "add v21.4h, v21.4h, v25.4h \n" + "add v2.4h, v1.4h, v5.4h \n" + "add v2.4h, v2.4h, v17.4h \n" // dst_ptr[3] = (s[6 + st * 0] + s[7 + st * 0] // + s[6 + st * 1] + s[7 + st * 1] // + s[6 + st * 2] + s[7 + st * 2]) / 6 - "sqrdmulh v2.8h, v2.8h, v29.8h \n" - "xtn v2.8b, v2.8h \n" + "sqrdmulh v2.8h, v2.8h, v29.8h \n" + "xtn v2.8b, v2.8h \n" // Shuffle 2,3 reg around so that 2 can be added to the // 0,1 reg and 3 can be added to the 4,5 reg. This @@ -372,35 +387,38 @@ void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, // registers are already expanded. Then do transposes // to get aligned. // xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 - "ushll v16.8h, v16.8b, #0 \n" - "uaddl v0.8h, v0.8b, v4.8b \n" + "ushll v16.8h, v16.8b, #0 \n" + "uaddl v0.8h, v0.8b, v4.8b \n" // combine source lines - "add v0.8h, v0.8h, v16.8h \n" + "add v0.8h, v0.8h, v16.8h \n" // xx 20 xx 21 xx 22 xx 23 // xx 30 xx 31 xx 32 xx 33 - "trn1 v1.8h, v0.8h, v0.8h \n" - "trn2 v4.8h, v0.8h, v0.8h \n" - "xtn v0.4h, v1.4s \n" - "xtn v4.4h, v4.4s \n" + "trn1 v1.8h, v0.8h, v0.8h \n" + "trn2 v4.8h, v0.8h, v0.8h \n" + "xtn v0.4h, v1.4s \n" + "xtn v4.4h, v4.4s \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead // 0+1+2, 3+4+5 - "add v20.8h, v20.8h, v0.8h \n" - "add v21.8h, v21.8h, v4.8h \n" + "add v20.8h, v20.8h, v0.8h \n" + "add v21.8h, v21.8h, v4.8h \n" + "prfm pldl1keep, [%2, 448] \n" // Need to divide, but can't downshift as the the value // isn't a power of 2. So multiply by 65536 / n // and take the upper 16 bits. - "sqrdmulh v0.8h, v20.8h, v31.8h \n" - "sqrdmulh v1.8h, v21.8h, v31.8h \n" + "sqrdmulh v0.8h, v20.8h, v31.8h \n" + "sqrdmulh v1.8h, v21.8h, v31.8h \n" + "prfm pldl1keep, [%3, 448] \n" // Align for table lookup, vtbl requires registers to be adjacent - "tbl v3.16b, {v0.16b, v1.16b, v2.16b}, v30.16b \n" + "tbl v3.16b, {v0.16b, v1.16b, v2.16b}, v30.16b \n" - "st1 {v3.8b}, [%1], #8 \n" - "st1 {v3.s}[2], [%1], #4 \n" - "b.gt 1b \n" + "st1 {v3.8b}, [%1], #8 \n" + "st1 {v3.s}[2], [%1], #4 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(tmp_src_stride), // %2 @@ -422,53 +440,53 @@ void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, // TODO(fbarchard): use src_stride directly for clang 3.5+. ptrdiff_t tmp_src_stride = src_stride; asm volatile( - "ld1 {v30.8h}, [%4] \n" - "ld1 {v31.16b}, [%5] \n" - "add %2, %2, %0 \n" - "1: \n" + "ld1 {v30.8h}, [%4] \n" + "ld1 {v31.16b}, [%5] \n" + "add %2, %2, %0 \n" + "1: \n" // 00 40 01 41 02 42 03 43 // 10 50 11 51 12 52 13 53 // 20 60 21 61 22 62 23 63 // 30 70 31 71 32 72 33 73 - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32 \n" - "subs %w3, %w3, #12 \n" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" + "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32 \n" + "subs %w3, %w3, #12 \n" // Shuffle the input data around to get align the data // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 // 00 10 01 11 02 12 03 13 // 40 50 41 51 42 52 43 53 - "trn1 v16.8b, v0.8b, v1.8b \n" - "trn2 v17.8b, v0.8b, v1.8b \n" - "trn1 v18.8b, v4.8b, v5.8b \n" - "trn2 v19.8b, v4.8b, v5.8b \n" + "trn1 v16.8b, v0.8b, v1.8b \n" + "trn2 v17.8b, v0.8b, v1.8b \n" + "trn1 v18.8b, v4.8b, v5.8b \n" + "trn2 v19.8b, v4.8b, v5.8b \n" // 20 30 21 31 22 32 23 33 // 60 70 61 71 62 72 63 73 - "trn1 v0.8b, v2.8b, v3.8b \n" - "trn2 v1.8b, v2.8b, v3.8b \n" - "trn1 v4.8b, v6.8b, v7.8b \n" - "trn2 v5.8b, v6.8b, v7.8b \n" + "trn1 v0.8b, v2.8b, v3.8b \n" + "trn2 v1.8b, v2.8b, v3.8b \n" + "trn1 v4.8b, v6.8b, v7.8b \n" + "trn2 v5.8b, v6.8b, v7.8b \n" // 00+10 01+11 02+12 03+13 // 40+50 41+51 42+52 43+53 - "uaddlp v16.4h, v16.8b \n" - "uaddlp v17.4h, v17.8b \n" - "uaddlp v18.4h, v18.8b \n" - "uaddlp v19.4h, v19.8b \n" + "uaddlp v16.4h, v16.8b \n" + "uaddlp v17.4h, v17.8b \n" + "uaddlp v18.4h, v18.8b \n" + "uaddlp v19.4h, v19.8b \n" // 60+70 61+71 62+72 63+73 - "uaddlp v1.4h, v1.8b \n" - "uaddlp v5.4h, v5.8b \n" + "uaddlp v1.4h, v1.8b \n" + "uaddlp v5.4h, v5.8b \n" // combine source lines - "add v16.4h, v16.4h, v18.4h \n" - "add v17.4h, v17.4h, v19.4h \n" - "add v2.4h, v1.4h, v5.4h \n" + "add v16.4h, v16.4h, v18.4h \n" + "add v17.4h, v17.4h, v19.4h \n" + "add v2.4h, v1.4h, v5.4h \n" // dst_ptr[3] = (s[6] + s[7] + s[6+st] + s[7+st]) / 4 - "uqrshrn v2.8b, v2.8h, #2 \n" + "uqrshrn v2.8b, v2.8h, #2 \n" // Shuffle 2,3 reg around so that 2 can be added to the // 0,1 reg and 3 can be added to the 4,5 reg. This @@ -478,33 +496,35 @@ void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, // xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 // combine source lines - "uaddl v0.8h, v0.8b, v4.8b \n" + "uaddl v0.8h, v0.8b, v4.8b \n" // xx 20 xx 21 xx 22 xx 23 // xx 30 xx 31 xx 32 xx 33 - "trn1 v1.8h, v0.8h, v0.8h \n" - "trn2 v4.8h, v0.8h, v0.8h \n" - "xtn v0.4h, v1.4s \n" - "xtn v4.4h, v4.4s \n" + "trn1 v1.8h, v0.8h, v0.8h \n" + "trn2 v4.8h, v0.8h, v0.8h \n" + "xtn v0.4h, v1.4s \n" + "xtn v4.4h, v4.4s \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead // 0+1+2, 3+4+5 - "add v16.8h, v16.8h, v0.8h \n" - "add v17.8h, v17.8h, v4.8h \n" + "add v16.8h, v16.8h, v0.8h \n" + "add v17.8h, v17.8h, v4.8h \n" + "prfm pldl1keep, [%2, 448] \n" // Need to divide, but can't downshift as the the value // isn't a power of 2. So multiply by 65536 / n // and take the upper 16 bits. - "sqrdmulh v0.8h, v16.8h, v30.8h \n" - "sqrdmulh v1.8h, v17.8h, v30.8h \n" + "sqrdmulh v0.8h, v16.8h, v30.8h \n" + "sqrdmulh v1.8h, v17.8h, v30.8h \n" // Align for table lookup, vtbl requires registers to // be adjacent - "tbl v3.16b, {v0.16b, v1.16b, v2.16b}, v31.16b \n" + "tbl v3.16b, {v0.16b, v1.16b, v2.16b}, v31.16b \n" - "st1 {v3.8b}, [%1], #8 \n" - "st1 {v3.s}[2], [%1], #4 \n" - "b.gt 1b \n" + "st1 {v3.8b}, [%1], #8 \n" + "st1 {v3.s}[2], [%1], #4 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(tmp_src_stride), // %2 @@ -522,13 +542,14 @@ void ScaleAddRow_NEON(const uint8_t* src_ptr, int src_width) { asm volatile( "1: \n" - "ld1 {v1.8h, v2.8h}, [%1] \n" // load accumulator - "ld1 {v0.16b}, [%0], #16 \n" // load 16 bytes - "uaddw2 v2.8h, v2.8h, v0.16b \n" // add - "uaddw v1.8h, v1.8h, v0.8b \n" - "st1 {v1.8h, v2.8h}, [%1], #32 \n" // store accumulator - "subs %w2, %w2, #16 \n" // 16 processed per loop - "b.gt 1b \n" + "ld1 {v1.8h, v2.8h}, [%1] \n" // load accumulator + "ld1 {v0.16b}, [%0], #16 \n" // load 16 bytes + "uaddw2 v2.8h, v2.8h, v0.16b \n" // add + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "uaddw v1.8h, v1.8h, v0.8b \n" + "st1 {v1.8h, v2.8h}, [%1], #32 \n" // store accumulator + "subs %w2, %w2, #16 \n" // 16 processed per loop + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst_ptr), // %1 "+r"(src_width) // %2 @@ -560,17 +581,17 @@ void ScaleFilterCols_NEON(uint8_t* dst_ptr, int64_t x64 = (int64_t)x; // NOLINT int64_t dx64 = (int64_t)dx; // NOLINT asm volatile ( - "dup v0.4s, %w3 \n" // x - "dup v1.4s, %w4 \n" // dx - "ld1 {v2.4s}, [%5] \n" // 0 1 2 3 - "shl v3.4s, v1.4s, #2 \n" // 4 * dx - "mul v1.4s, v1.4s, v2.4s \n" + "dup v0.4s, %w3 \n" // x + "dup v1.4s, %w4 \n" // dx + "ld1 {v2.4s}, [%5] \n" // 0 1 2 3 + "shl v3.4s, v1.4s, #2 \n" // 4 * dx + "mul v1.4s, v1.4s, v2.4s \n" // x , x + 1 * dx, x + 2 * dx, x + 3 * dx - "add v1.4s, v1.4s, v0.4s \n" + "add v1.4s, v1.4s, v0.4s \n" // x + 4 * dx, x + 5 * dx, x + 6 * dx, x + 7 * dx - "add v2.4s, v1.4s, v3.4s \n" - "shl v0.4s, v3.4s, #1 \n" // 8 * dx - "1: \n" + "add v2.4s, v1.4s, v3.4s \n" + "shl v0.4s, v3.4s, #1 \n" // 8 * dx + "1: \n" LOAD2_DATA8_LANE(0) LOAD2_DATA8_LANE(1) LOAD2_DATA8_LANE(2) @@ -579,27 +600,27 @@ void ScaleFilterCols_NEON(uint8_t* dst_ptr, LOAD2_DATA8_LANE(5) LOAD2_DATA8_LANE(6) LOAD2_DATA8_LANE(7) - "mov v6.16b, v1.16b \n" - "mov v7.16b, v2.16b \n" - "uzp1 v6.8h, v6.8h, v7.8h \n" - "ushll v4.8h, v4.8b, #0 \n" - "ushll v5.8h, v5.8b, #0 \n" - "ssubl v16.4s, v5.4h, v4.4h \n" - "ssubl2 v17.4s, v5.8h, v4.8h \n" - "ushll v7.4s, v6.4h, #0 \n" - "ushll2 v6.4s, v6.8h, #0 \n" - "mul v16.4s, v16.4s, v7.4s \n" - "mul v17.4s, v17.4s, v6.4s \n" - "rshrn v6.4h, v16.4s, #16 \n" - "rshrn2 v6.8h, v17.4s, #16 \n" - "add v4.8h, v4.8h, v6.8h \n" - "xtn v4.8b, v4.8h \n" + "mov v6.16b, v1.16b \n" + "mov v7.16b, v2.16b \n" + "uzp1 v6.8h, v6.8h, v7.8h \n" + "ushll v4.8h, v4.8b, #0 \n" + "ushll v5.8h, v5.8b, #0 \n" + "ssubl v16.4s, v5.4h, v4.4h \n" + "ssubl2 v17.4s, v5.8h, v4.8h \n" + "ushll v7.4s, v6.4h, #0 \n" + "ushll2 v6.4s, v6.8h, #0 \n" + "mul v16.4s, v16.4s, v7.4s \n" + "mul v17.4s, v17.4s, v6.4s \n" + "rshrn v6.4h, v16.4s, #16 \n" + "rshrn2 v6.8h, v17.4s, #16 \n" + "add v4.8h, v4.8h, v6.8h \n" + "xtn v4.8b, v4.8h \n" - "st1 {v4.8b}, [%0], #8 \n" // store pixels - "add v1.4s, v1.4s, v0.4s \n" - "add v2.4s, v2.4s, v0.4s \n" - "subs %w2, %w2, #8 \n" // 8 processed per loop - "b.gt 1b \n" + "st1 {v4.8b}, [%0], #8 \n" // store pixels + "add v1.4s, v1.4s, v0.4s \n" + "add v2.4s, v2.4s, v0.4s \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop + "b.gt 1b \n" : "+r"(dst_ptr), // %0 "+r"(src_ptr), // %1 "+r"(dst_width), // %2 @@ -623,74 +644,83 @@ void ScaleFilterRows_NEON(uint8_t* dst_ptr, int source_y_fraction) { int y_fraction = 256 - source_y_fraction; asm volatile( - "cmp %w4, #0 \n" - "b.eq 100f \n" - "add %2, %2, %1 \n" - "cmp %w4, #64 \n" - "b.eq 75f \n" - "cmp %w4, #128 \n" - "b.eq 50f \n" - "cmp %w4, #192 \n" - "b.eq 25f \n" + "cmp %w4, #0 \n" + "b.eq 100f \n" + "add %2, %2, %1 \n" + "cmp %w4, #64 \n" + "b.eq 75f \n" + "cmp %w4, #128 \n" + "b.eq 50f \n" + "cmp %w4, #192 \n" + "b.eq 25f \n" - "dup v5.8b, %w4 \n" - "dup v4.8b, %w5 \n" + "dup v5.8b, %w4 \n" + "dup v4.8b, %w5 \n" // General purpose row blend. "1: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "umull v6.8h, v0.8b, v4.8b \n" - "umull2 v7.8h, v0.16b, v4.16b \n" - "umlal v6.8h, v1.8b, v5.8b \n" - "umlal2 v7.8h, v1.16b, v5.16b \n" - "rshrn v0.8b, v6.8h, #8 \n" - "rshrn2 v0.16b, v7.8h, #8 \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 1b \n" - "b 99f \n" + "ld1 {v0.16b}, [%1], #16 \n" + "ld1 {v1.16b}, [%2], #16 \n" + "subs %w3, %w3, #16 \n" + "umull v6.8h, v0.8b, v4.8b \n" + "umull2 v7.8h, v0.16b, v4.16b \n" + "prfm pldl1keep, [%1, 448] \n" // prefetch 7 lines ahead + "umlal v6.8h, v1.8b, v5.8b \n" + "umlal2 v7.8h, v1.16b, v5.16b \n" + "prfm pldl1keep, [%2, 448] \n" + "rshrn v0.8b, v6.8h, #8 \n" + "rshrn2 v0.16b, v7.8h, #8 \n" + "st1 {v0.16b}, [%0], #16 \n" + "b.gt 1b \n" + "b 99f \n" // Blend 25 / 75. "25: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 25b \n" - "b 99f \n" + "ld1 {v0.16b}, [%1], #16 \n" + "ld1 {v1.16b}, [%2], #16 \n" + "subs %w3, %w3, #16 \n" + "urhadd v0.16b, v0.16b, v1.16b \n" + "prfm pldl1keep, [%1, 448] \n" // prefetch 7 lines ahead + "urhadd v0.16b, v0.16b, v1.16b \n" + "prfm pldl1keep, [%2, 448] \n" + "st1 {v0.16b}, [%0], #16 \n" + "b.gt 25b \n" + "b 99f \n" // Blend 50 / 50. "50: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 50b \n" - "b 99f \n" + "ld1 {v0.16b}, [%1], #16 \n" + "ld1 {v1.16b}, [%2], #16 \n" + "subs %w3, %w3, #16 \n" + "prfm pldl1keep, [%1, 448] \n" // prefetch 7 lines ahead + "urhadd v0.16b, v0.16b, v1.16b \n" + "prfm pldl1keep, [%2, 448] \n" + "st1 {v0.16b}, [%0], #16 \n" + "b.gt 50b \n" + "b 99f \n" // Blend 75 / 25. "75: \n" - "ld1 {v1.16b}, [%1], #16 \n" - "ld1 {v0.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 75b \n" - "b 99f \n" + "ld1 {v1.16b}, [%1], #16 \n" + "ld1 {v0.16b}, [%2], #16 \n" + "subs %w3, %w3, #16 \n" + "urhadd v0.16b, v0.16b, v1.16b \n" + "prfm pldl1keep, [%1, 448] \n" // prefetch 7 lines ahead + "urhadd v0.16b, v0.16b, v1.16b \n" + "prfm pldl1keep, [%2, 448] \n" + "st1 {v0.16b}, [%0], #16 \n" + "b.gt 75b \n" + "b 99f \n" // Blend 100 / 0 - Copy row unchanged. "100: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "subs %w3, %w3, #16 \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 100b \n" + "ld1 {v0.16b}, [%1], #16 \n" + "subs %w3, %w3, #16 \n" + "prfm pldl1keep, [%1, 448] \n" // prefetch 7 lines ahead + "st1 {v0.16b}, [%0], #16 \n" + "b.gt 100b \n" "99: \n" - "st1 {v0.b}[15], [%0] \n" + "st1 {v0.b}[15], [%0] \n" : "+r"(dst_ptr), // %0 "+r"(src_ptr), // %1 "+r"(src_stride), // %2 @@ -709,11 +739,12 @@ void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr, asm volatile( "1: \n" // load 16 ARGB pixels with even pixels into q0/q2, odd into q1/q3 - "ld4 {v0.4s,v1.4s,v2.4s,v3.4s}, [%0], #64 \n" - "subs %w2, %w2, #8 \n" // 8 processed per loop - "mov v2.16b, v3.16b \n" - "st2 {v1.4s,v2.4s}, [%1], #32 \n" // store 8 odd pixels - "b.gt 1b \n" + "ld4 {v0.4s,v1.4s,v2.4s,v3.4s}, [%0], #64 \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop + "mov v2.16b, v3.16b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "st2 {v1.4s,v2.4s}, [%1], #32 \n" // store 8 odd pixels + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(dst), // %1 "+r"(dst_width) // %2 @@ -730,13 +761,14 @@ void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb, asm volatile( "1: \n" // load 16 ARGB pixels with even pixels into q0/q2, odd into q1/q3 - "ld4 {v0.4s,v1.4s,v2.4s,v3.4s}, [%0], #64 \n" - "subs %w2, %w2, #8 \n" // 8 processed per loop + "ld4 {v0.4s,v1.4s,v2.4s,v3.4s}, [%0], #64 \n" + "subs %w2, %w2, #8 \n" // 8 processed per loop - "urhadd v0.16b, v0.16b, v1.16b \n" // rounding half add - "urhadd v1.16b, v2.16b, v3.16b \n" - "st2 {v0.4s,v1.4s}, [%1], #32 \n" // store 8 pixels - "b.gt 1b \n" + "urhadd v0.16b, v0.16b, v1.16b \n" // rounding half add + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "urhadd v1.16b, v2.16b, v3.16b \n" + "st2 {v0.4s,v1.4s}, [%1], #32 \n" // store 8 pixels + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(dst_width) // %2 @@ -751,25 +783,27 @@ void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr, int dst_width) { asm volatile( // change the stride to row 2 pointer - "add %1, %1, %0 \n" + "add %1, %1, %0 \n" "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 8 ARGB - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts. - "uaddlp v3.8h, v3.16b \n" // A 16 bytes -> 8 shorts. - "ld4 {v16.16b,v17.16b,v18.16b,v19.16b}, [%1], #64 \n" // load 8 - "uadalp v0.8h, v16.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v17.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v18.16b \n" // R 16 bytes -> 8 shorts. - "uadalp v3.8h, v19.16b \n" // A 16 bytes -> 8 shorts. - "rshrn v0.8b, v0.8h, #2 \n" // round and pack - "rshrn v1.8b, v1.8h, #2 \n" - "rshrn v2.8b, v2.8h, #2 \n" - "rshrn v3.8b, v3.8h, #2 \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" - "b.gt 1b \n" + "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 ARGB + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "uaddlp v0.8h, v0.16b \n" // B 16 bytes -> 8 shorts. + "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. + "uaddlp v2.8h, v2.16b \n" // R 16 bytes -> 8 shorts. + "uaddlp v3.8h, v3.16b \n" // A 16 bytes -> 8 shorts. + "ld4 {v16.16b,v17.16b,v18.16b,v19.16b}, [%1], #64 \n" // load 8 + "uadalp v0.8h, v16.16b \n" // B 16 bytes -> 8 shorts. + "uadalp v1.8h, v17.16b \n" // G 16 bytes -> 8 shorts. + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "uadalp v2.8h, v18.16b \n" // R 16 bytes -> 8 shorts. + "uadalp v3.8h, v19.16b \n" // A 16 bytes -> 8 shorts. + "prfm pldl1keep, [%1, 448] \n" + "rshrn v0.8b, v0.8h, #2 \n" // round and pack + "rshrn v1.8b, v1.8h, #2 \n" + "rshrn v2.8b, v2.8h, #2 \n" + "rshrn v3.8b, v3.8h, #2 \n" + "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(src_stride), // %1 "+r"(dst), // %2 @@ -788,13 +822,14 @@ void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb, (void)src_stride; asm volatile( "1: \n" - "ld1 {v0.s}[0], [%0], %3 \n" - "ld1 {v0.s}[1], [%0], %3 \n" - "ld1 {v0.s}[2], [%0], %3 \n" - "ld1 {v0.s}[3], [%0], %3 \n" - "subs %w2, %w2, #4 \n" // 4 pixels per loop. - "st1 {v0.16b}, [%1], #16 \n" - "b.gt 1b \n" + "ld1 {v0.s}[0], [%0], %3 \n" + "ld1 {v0.s}[1], [%0], %3 \n" + "ld1 {v0.s}[2], [%0], %3 \n" + "ld1 {v0.s}[3], [%0], %3 \n" + "subs %w2, %w2, #4 \n" // 4 pixels per loop. + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "st1 {v0.16b}, [%1], #16 \n" + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb), // %1 "+r"(dst_width) // %2 @@ -812,33 +847,35 @@ void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int dst_width) { asm volatile( - "add %1, %1, %0 \n" + "add %1, %1, %0 \n" "1: \n" - "ld1 {v0.8b}, [%0], %4 \n" // Read 4 2x2 -> 2x1 - "ld1 {v1.8b}, [%1], %4 \n" - "ld1 {v2.8b}, [%0], %4 \n" - "ld1 {v3.8b}, [%1], %4 \n" - "ld1 {v4.8b}, [%0], %4 \n" - "ld1 {v5.8b}, [%1], %4 \n" - "ld1 {v6.8b}, [%0], %4 \n" - "ld1 {v7.8b}, [%1], %4 \n" - "uaddl v0.8h, v0.8b, v1.8b \n" - "uaddl v2.8h, v2.8b, v3.8b \n" - "uaddl v4.8h, v4.8b, v5.8b \n" - "uaddl v6.8h, v6.8b, v7.8b \n" - "mov v16.d[1], v0.d[1] \n" // ab_cd -> ac_bd - "mov v0.d[1], v2.d[0] \n" - "mov v2.d[0], v16.d[1] \n" - "mov v16.d[1], v4.d[1] \n" // ef_gh -> eg_fh - "mov v4.d[1], v6.d[0] \n" - "mov v6.d[0], v16.d[1] \n" - "add v0.8h, v0.8h, v2.8h \n" // (a+b)_(c+d) - "add v4.8h, v4.8h, v6.8h \n" // (e+f)_(g+h) - "rshrn v0.8b, v0.8h, #2 \n" // first 2 pixels. - "rshrn2 v0.16b, v4.8h, #2 \n" // next 2 pixels. - "subs %w3, %w3, #4 \n" // 4 pixels per loop. - "st1 {v0.16b}, [%2], #16 \n" - "b.gt 1b \n" + "ld1 {v0.8b}, [%0], %4 \n" // Read 4 2x2 -> 2x1 + "ld1 {v1.8b}, [%1], %4 \n" + "ld1 {v2.8b}, [%0], %4 \n" + "ld1 {v3.8b}, [%1], %4 \n" + "ld1 {v4.8b}, [%0], %4 \n" + "ld1 {v5.8b}, [%1], %4 \n" + "ld1 {v6.8b}, [%0], %4 \n" + "ld1 {v7.8b}, [%1], %4 \n" + "uaddl v0.8h, v0.8b, v1.8b \n" + "uaddl v2.8h, v2.8b, v3.8b \n" + "uaddl v4.8h, v4.8b, v5.8b \n" + "uaddl v6.8h, v6.8b, v7.8b \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "mov v16.d[1], v0.d[1] \n" // ab_cd -> ac_bd + "mov v0.d[1], v2.d[0] \n" + "mov v2.d[0], v16.d[1] \n" + "mov v16.d[1], v4.d[1] \n" // ef_gh -> eg_fh + "mov v4.d[1], v6.d[0] \n" + "mov v6.d[0], v16.d[1] \n" + "prfm pldl1keep, [%1, 448] \n" + "add v0.8h, v0.8h, v2.8h \n" // (a+b)_(c+d) + "add v4.8h, v4.8h, v6.8h \n" // (e+f)_(g+h) + "rshrn v0.8b, v0.8h, #2 \n" // first 2 pixels. + "rshrn2 v0.16b, v4.8h, #2 \n" // next 2 pixels. + "subs %w3, %w3, #4 \n" // 4 pixels per loop. + "st1 {v0.16b}, [%2], #16 \n" + "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(src_stride), // %1 "+r"(dst_argb), // %2 @@ -875,10 +912,11 @@ void ScaleARGBCols_NEON(uint8_t* dst_argb, LOAD1_DATA32_LANE(v1, 1) LOAD1_DATA32_LANE(v1, 2) LOAD1_DATA32_LANE(v1, 3) + "prfm pldl1keep, [%1, 448] \n" // prefetch 7 lines ahead // clang-format on - "st1 {v0.4s, v1.4s}, [%0], #32 \n" // store pixels - "subs %w2, %w2, #8 \n" // 8 processed per loop - "b.gt 1b \n" + "st1 {v0.4s, v1.4s}, [%0], #32 \n" // store pixels + "subs %w2, %w2, #8 \n" // 8 processed per loop + "b.gt 1b \n" : "+r"(dst_argb), // %0 "+r"(src_argb), // %1 "+r"(dst_width), // %2 @@ -911,16 +949,16 @@ void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, int64_t x64 = (int64_t)x; // NOLINT int64_t dx64 = (int64_t)dx; // NOLINT asm volatile ( - "dup v0.4s, %w3 \n" // x - "dup v1.4s, %w4 \n" // dx - "ld1 {v2.4s}, [%5] \n" // 0 1 2 3 - "shl v6.4s, v1.4s, #2 \n" // 4 * dx - "mul v1.4s, v1.4s, v2.4s \n" - "movi v3.16b, #0x7f \n" // 0x7F - "movi v4.8h, #0x7f \n" // 0x7F + "dup v0.4s, %w3 \n" // x + "dup v1.4s, %w4 \n" // dx + "ld1 {v2.4s}, [%5] \n" // 0 1 2 3 + "shl v6.4s, v1.4s, #2 \n" // 4 * dx + "mul v1.4s, v1.4s, v2.4s \n" + "movi v3.16b, #0x7f \n" // 0x7F + "movi v4.8h, #0x7f \n" // 0x7F // x , x + 1 * dx, x + 2 * dx, x + 3 * dx - "add v5.4s, v1.4s, v0.4s \n" - "1: \n" + "add v5.4s, v1.4s, v0.4s \n" + "1: \n" // d0, d1: a // d2, d3: b LOAD2_DATA32_LANE(v0, v1, 0) @@ -941,15 +979,15 @@ void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, "umull2 v17.8h, v0.16b, v7.16b \n" "umull v18.8h, v1.8b, v2.8b \n" "umull2 v19.8h, v1.16b, v2.16b \n" + "prfm pldl1keep, [%1, 448] \n" // prefetch 7 lines ahead "add v16.8h, v16.8h, v18.8h \n" "add v17.8h, v17.8h, v19.8h \n" "shrn v0.8b, v16.8h, #7 \n" "shrn2 v0.16b, v17.8h, #7 \n" - "st1 {v0.4s}, [%0], #16 \n" // store pixels "add v5.4s, v5.4s, v6.4s \n" "subs %w2, %w2, #4 \n" // 4 processed per loop - "b.gt 1b \n" + "b.gt 1b \n" : "+r"(dst_argb), // %0 "+r"(src_argb), // %1 "+r"(dst_width), // %2 @@ -972,19 +1010,21 @@ void ScaleRowDown2Box_16_NEON(const uint16_t* src_ptr, int dst_width) { asm volatile( // change the stride to row 2 pointer - "add %1, %0, %1, lsl #1 \n" // ptr + stide * 2 + "add %1, %0, %1, lsl #1 \n" // ptr + stide * 2 "1: \n" - "ld1 {v0.8h, v1.8h}, [%0], #32 \n" // load row 1 and post inc - "ld1 {v2.8h, v3.8h}, [%1], #32 \n" // load row 2 and post inc - "subs %w3, %w3, #8 \n" // 8 processed per loop - "uaddlp v0.4s, v0.8h \n" // row 1 add adjacent - "uaddlp v1.4s, v1.8h \n" - "uadalp v0.4s, v2.8h \n" // +row 2 add adjacent - "uadalp v1.4s, v3.8h \n" - "rshrn v0.4h, v0.4s, #2 \n" // round and pack - "rshrn2 v0.8h, v1.4s, #2 \n" - "st1 {v0.8h}, [%2], #16 \n" - "b.gt 1b \n" + "ld1 {v0.8h, v1.8h}, [%0], #32 \n" // load row 1 and post inc + "ld1 {v2.8h, v3.8h}, [%1], #32 \n" // load row 2 and post inc + "subs %w3, %w3, #8 \n" // 8 processed per loop + "uaddlp v0.4s, v0.8h \n" // row 1 add adjacent + "uaddlp v1.4s, v1.8h \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "uadalp v0.4s, v2.8h \n" // +row 2 add adjacent + "uadalp v1.4s, v3.8h \n" + "prfm pldl1keep, [%1, 448] \n" + "rshrn v0.4h, v0.4s, #2 \n" // round and pack + "rshrn2 v0.8h, v1.4s, #2 \n" + "st1 {v0.8h}, [%2], #16 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(src_stride), // %1 "+r"(dst), // %2 @@ -1001,38 +1041,40 @@ void ScaleRowUp2_16_NEON(const uint16_t* src_ptr, uint16_t* dst, int dst_width) { asm volatile( - "add %1, %0, %1, lsl #1 \n" // ptr + stide * 2 - "movi v0.8h, #9 \n" // constants - "movi v1.4s, #3 \n" + "add %1, %0, %1, lsl #1 \n" // ptr + stide * 2 + "movi v0.8h, #9 \n" // constants + "movi v1.4s, #3 \n" "1: \n" - "ld1 {v3.8h}, [%0], %4 \n" // TL read first 8 - "ld1 {v4.8h}, [%0], %5 \n" // TR read 8 offset by 1 - "ld1 {v5.8h}, [%1], %4 \n" // BL read 8 from next row - "ld1 {v6.8h}, [%1], %5 \n" // BR offset by 1 - "subs %w3, %w3, #16 \n" // 16 dst pixels per loop - "umull v16.4s, v3.4h, v0.4h \n" - "umull2 v7.4s, v3.8h, v0.8h \n" - "umull v18.4s, v4.4h, v0.4h \n" - "umull2 v17.4s, v4.8h, v0.8h \n" - "uaddw v16.4s, v16.4s, v6.4h \n" - "uaddl2 v19.4s, v6.8h, v3.8h \n" - "uaddl v3.4s, v6.4h, v3.4h \n" - "uaddw2 v6.4s, v7.4s, v6.8h \n" - "uaddl2 v7.4s, v5.8h, v4.8h \n" - "uaddl v4.4s, v5.4h, v4.4h \n" - "uaddw v18.4s, v18.4s, v5.4h \n" - "mla v16.4s, v4.4s, v1.4s \n" - "mla v18.4s, v3.4s, v1.4s \n" - "mla v6.4s, v7.4s, v1.4s \n" - "uaddw2 v4.4s, v17.4s, v5.8h \n" - "uqrshrn v16.4h, v16.4s, #4 \n" - "mla v4.4s, v19.4s, v1.4s \n" - "uqrshrn2 v16.8h, v6.4s, #4 \n" - "uqrshrn v17.4h, v18.4s, #4 \n" - "uqrshrn2 v17.8h, v4.4s, #4 \n" - "st2 {v16.8h-v17.8h}, [%2], #32 \n" - "b.gt 1b \n" + "ld1 {v3.8h}, [%0], %4 \n" // TL read first 8 + "ld1 {v4.8h}, [%0], %5 \n" // TR read 8 offset by 1 + "ld1 {v5.8h}, [%1], %4 \n" // BL read 8 from next row + "ld1 {v6.8h}, [%1], %5 \n" // BR offset by 1 + "subs %w3, %w3, #16 \n" // 16 dst pixels per loop + "umull v16.4s, v3.4h, v0.4h \n" + "umull2 v7.4s, v3.8h, v0.8h \n" + "umull v18.4s, v4.4h, v0.4h \n" + "umull2 v17.4s, v4.8h, v0.8h \n" + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "uaddw v16.4s, v16.4s, v6.4h \n" + "uaddl2 v19.4s, v6.8h, v3.8h \n" + "uaddl v3.4s, v6.4h, v3.4h \n" + "uaddw2 v6.4s, v7.4s, v6.8h \n" + "uaddl2 v7.4s, v5.8h, v4.8h \n" + "uaddl v4.4s, v5.4h, v4.4h \n" + "uaddw v18.4s, v18.4s, v5.4h \n" + "prfm pldl1keep, [%1, 448] \n" + "mla v16.4s, v4.4s, v1.4s \n" + "mla v18.4s, v3.4s, v1.4s \n" + "mla v6.4s, v7.4s, v1.4s \n" + "uaddw2 v4.4s, v17.4s, v5.8h \n" + "uqrshrn v16.4h, v16.4s, #4 \n" + "mla v4.4s, v19.4s, v1.4s \n" + "uqrshrn2 v16.8h, v6.4s, #4 \n" + "uqrshrn v17.4h, v18.4s, #4 \n" + "uqrshrn2 v17.8h, v4.4s, #4 \n" + "st2 {v16.8h-v17.8h}, [%2], #32 \n" + "b.gt 1b \n" : "+r"(src_ptr), // %0 "+r"(src_stride), // %1 "+r"(dst), // %2 @@ -1044,6 +1086,64 @@ void ScaleRowUp2_16_NEON(const uint16_t* src_ptr, ); } +void ScaleUVRowDown2Box_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + uint8_t* dst, + int dst_width) { + asm volatile( + // change the stride to row 2 pointer + "add %1, %1, %0 \n" + "1: \n" + "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 UV + "subs %w3, %w3, #8 \n" // 8 processed per loop. + "uaddlp v0.8h, v0.16b \n" // U 16 bytes -> 8 shorts. + "uaddlp v1.8h, v1.16b \n" // V 16 bytes -> 8 shorts. + "ld2 {v16.16b,v17.16b}, [%1], #32 \n" // load 16 + "uadalp v0.8h, v16.16b \n" // U 16 bytes -> 8 shorts. + "uadalp v1.8h, v17.16b \n" // V 16 bytes -> 8 shorts. + "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead + "rshrn v0.8b, v0.8h, #2 \n" // round and pack + "prfm pldl1keep, [%1, 448] \n" + "rshrn v1.8b, v1.8h, #2 \n" + "st2 {v0.8b,v1.8b}, [%2], #16 \n" + "b.gt 1b \n" + : "+r"(src_ptr), // %0 + "+r"(src_stride), // %1 + "+r"(dst), // %2 + "+r"(dst_width) // %3 + : + : "memory", "cc", "v0", "v1", "v16", "v17"); +} + +// Reads 4 pixels at a time. +void ScaleUVRowDownEven_NEON(const uint8_t* src_ptr, + ptrdiff_t src_stride, + int src_stepx, // pixel step + uint8_t* dst_ptr, + int dst_width) { + const uint8_t* src1_ptr = src_ptr + src_stepx * 2; + const uint8_t* src2_ptr = src_ptr + src_stepx * 4; + const uint8_t* src3_ptr = src_ptr + src_stepx * 6; + (void)src_stride; + asm volatile( + "1: \n" + "ld1 {v0.h}[0], [%0], %6 \n" + "ld1 {v1.h}[0], [%1], %6 \n" + "ld1 {v2.h}[0], [%2], %6 \n" + "ld1 {v3.h}[0], [%3], %6 \n" + "subs %w5, %w5, #4 \n" // 4 pixels per loop. + "st4 {v0.h, v1.h, v2.h, v3.h}[0], [%4], #8 \n" + "b.gt 1b \n" + : "+r"(src_ptr), // %0 + "+r"(src1_ptr), // %1 + "+r"(src2_ptr), // %2 + "+r"(src3_ptr), // %3 + "+r"(dst_ptr), // %4 + "+r"(dst_width) // %5 + : "r"((int64_t)(src_stepx * 8)) // %6 + : "memory", "cc", "v0", "v1", "v2", "v3"); +} + #endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) #ifdef __cplusplus diff --git a/TMessagesProj/jni/third_party/libyuv/source/scale_uv.cc b/TMessagesProj/jni/third_party/libyuv/source/scale_uv.cc new file mode 100644 index 000000000..b0469f09b --- /dev/null +++ b/TMessagesProj/jni/third_party/libyuv/source/scale_uv.cc @@ -0,0 +1,891 @@ +/* + * Copyright 2020 The LibYuv 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 "libyuv/scale.h" + +#include +#include + +#include "libyuv/cpu_id.h" +#include "libyuv/planar_functions.h" // For CopyUV +#include "libyuv/row.h" +#include "libyuv/scale_row.h" + +#ifdef __cplusplus +namespace libyuv { +extern "C" { +#endif + +// Macros to enable specialized scalers + +#ifndef HAS_SCALEUVDOWN2 +#define HAS_SCALEUVDOWN2 1 +#endif +#ifndef HAS_SCALEUVDOWN4BOX +#define HAS_SCALEUVDOWN4BOX 1 +#endif +#ifndef HAS_SCALEUVDOWNEVEN +#define HAS_SCALEUVDOWNEVEN 1 +#endif +#ifndef HAS_SCALEUVBILINEARDOWN +#define HAS_SCALEUVBILINEARDOWN 1 +#endif +#ifndef HAS_SCALEUVBILINEARUP +#define HAS_SCALEUVBILINEARUP 1 +#endif +#ifndef HAS_UVCOPY +#define HAS_UVCOPY 1 +#endif +#ifndef HAS_SCALEPLANEVERTICAL +#define HAS_SCALEPLANEVERTICAL 1 +#endif + +static __inline int Abs(int v) { + return v >= 0 ? v : -v; +} + +// ScaleUV, 1/2 +// This is an optimized version for scaling down a UV to 1/2 of +// its original size. +#if HAS_SCALEUVDOWN2 +static void ScaleUVDown2(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy, + enum FilterMode filtering) { + int j; + int row_stride = src_stride * (dy >> 16); + void (*ScaleUVRowDown2)(const uint8_t* src_uv, ptrdiff_t src_stride, + uint8_t* dst_uv, int dst_width) = + filtering == kFilterNone + ? ScaleUVRowDown2_C + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_C + : ScaleUVRowDown2Box_C); + (void)src_width; + (void)src_height; + (void)dx; + assert(dx == 65536 * 2); // Test scale factor of 2. + assert((dy & 0x1ffff) == 0); // Test vertical scale is multiple of 2. + // Advance to odd row, even column. + if (filtering == kFilterBilinear) { + src_uv += (y >> 16) * src_stride + (x >> 16) * 2; + } else { + src_uv += (y >> 16) * src_stride + ((x >> 16) - 1) * 2; + } + +#if defined(HAS_SCALEUVROWDOWN2BOX_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && filtering) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_Any_SSSE3; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_SSSE3; + } + } +#endif +#if defined(HAS_SCALEUVROWDOWN2BOX_AVX2) + if (TestCpuFlag(kCpuHasAVX2) && filtering) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_Any_AVX2; + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_AVX2; + } + } +#endif +#if defined(HAS_SCALEUVROWDOWN2BOX_NEON) + if (TestCpuFlag(kCpuHasNEON) && filtering) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_Any_NEON; + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_NEON; + } + } +#endif + +// This code is not enabled. Only box filter is available at this time. +#if defined(HAS_SCALEUVROWDOWN2_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ScaleUVRowDown2 = + filtering == kFilterNone + ? ScaleUVRowDown2_Any_SSSE3 + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_Any_SSSE3 + : ScaleUVRowDown2Box_Any_SSSE3); + if (IS_ALIGNED(dst_width, 2)) { + ScaleUVRowDown2 = + filtering == kFilterNone + ? ScaleUVRowDown2_SSSE3 + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_SSSE3 + : ScaleUVRowDown2Box_SSSE3); + } + } +#endif +// This code is not enabled. Only box filter is available at this time. +#if defined(HAS_SCALEUVROWDOWN2_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ScaleUVRowDown2 = + filtering == kFilterNone + ? ScaleUVRowDown2_Any_NEON + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_Any_NEON + : ScaleUVRowDown2Box_Any_NEON); + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVRowDown2 = + filtering == kFilterNone + ? ScaleUVRowDown2_NEON + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_NEON + : ScaleUVRowDown2Box_NEON); + } + } +#endif +#if defined(HAS_SCALEUVROWDOWN2_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + ScaleUVRowDown2 = + filtering == kFilterNone + ? ScaleUVRowDown2_Any_MMI + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_Any_MMI + : ScaleUVRowDown2Box_Any_MMI); + if (IS_ALIGNED(dst_width, 2)) { + ScaleUVRowDown2 = + filtering == kFilterNone + ? ScaleUVRowDown2_MMI + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_MMI + : ScaleUVRowDown2Box_MMI); + } + } +#endif +#if defined(HAS_SCALEUVROWDOWN2_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleUVRowDown2 = + filtering == kFilterNone + ? ScaleUVRowDown2_Any_MSA + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_Any_MSA + : ScaleUVRowDown2Box_Any_MSA); + if (IS_ALIGNED(dst_width, 2)) { + ScaleUVRowDown2 = + filtering == kFilterNone + ? ScaleUVRowDown2_MSA + : (filtering == kFilterLinear ? ScaleUVRowDown2Linear_MSA + : ScaleUVRowDown2Box_MSA); + } + } +#endif + + if (filtering == kFilterLinear) { + src_stride = 0; + } + for (j = 0; j < dst_height; ++j) { + ScaleUVRowDown2(src_uv, src_stride, dst_uv, dst_width); + src_uv += row_stride; + dst_uv += dst_stride; + } +} +#endif // HAS_SCALEUVDOWN2 + +// ScaleUV, 1/4 +// This is an optimized version for scaling down a UV to 1/4 of +// its original size. +#if HAS_SCALEUVDOWN4BOX +static void ScaleUVDown4Box(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy) { + int j; + // Allocate 2 rows of UV. + const int kRowSize = (dst_width * 2 * 2 + 15) & ~15; + align_buffer_64(row, kRowSize * 2); + int row_stride = src_stride * (dy >> 16); + void (*ScaleUVRowDown2)(const uint8_t* src_uv, ptrdiff_t src_stride, + uint8_t* dst_uv, int dst_width) = + ScaleUVRowDown2Box_C; + // Advance to odd row, even column. + src_uv += (y >> 16) * src_stride + (x >> 16) * 2; + (void)src_width; + (void)src_height; + (void)dx; + assert(dx == 65536 * 4); // Test scale factor of 4. + assert((dy & 0x3ffff) == 0); // Test vertical scale is multiple of 4. + +#if defined(HAS_SCALEUVROWDOWN2BOX_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_Any_SSSE3; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_SSSE3; + } + } +#endif +#if defined(HAS_SCALEUVROWDOWN2BOX_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_Any_AVX2; + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_AVX2; + } + } +#endif +#if defined(HAS_SCALEUVROWDOWN2BOX_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_Any_NEON; + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVRowDown2 = ScaleUVRowDown2Box_NEON; + } + } +#endif + + for (j = 0; j < dst_height; ++j) { + ScaleUVRowDown2(src_uv, src_stride, row, dst_width * 2); + ScaleUVRowDown2(src_uv + src_stride * 2, src_stride, row + kRowSize, + dst_width * 2); + ScaleUVRowDown2(row, kRowSize, dst_uv, dst_width); + src_uv += row_stride; + dst_uv += dst_stride; + } + free_aligned_buffer_64(row); +} +#endif // HAS_SCALEUVDOWN4BOX + +// ScaleUV Even +// This is an optimized version for scaling down a UV to even +// multiple of its original size. +#if HAS_SCALEUVDOWNEVEN +static void ScaleUVDownEven(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy, + enum FilterMode filtering) { + int j; + int col_step = dx >> 16; + int row_stride = (dy >> 16) * src_stride; + void (*ScaleUVRowDownEven)(const uint8_t* src_uv, ptrdiff_t src_stride, + int src_step, uint8_t* dst_uv, int dst_width) = + filtering ? ScaleUVRowDownEvenBox_C : ScaleUVRowDownEven_C; + (void)src_width; + (void)src_height; + assert(IS_ALIGNED(src_width, 2)); + assert(IS_ALIGNED(src_height, 2)); + src_uv += (y >> 16) * src_stride + (x >> 16) * 2; +#if defined(HAS_SCALEUVROWDOWNEVEN_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ScaleUVRowDownEven = filtering ? ScaleUVRowDownEvenBox_Any_SSSE3 + : ScaleUVRowDownEven_Any_SSSE3; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVRowDownEven = + filtering ? ScaleUVRowDownEvenBox_SSE2 : ScaleUVRowDownEven_SSSE3; + } + } +#endif +#if defined(HAS_SCALEUVROWDOWNEVEN_NEON) + if (TestCpuFlag(kCpuHasNEON) && !filtering) { + ScaleUVRowDownEven = ScaleUVRowDownEven_Any_NEON; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVRowDownEven = ScaleUVRowDownEven_NEON; + } + } +#endif// TODO(fbarchard): Enable Box filter +#if defined(HAS_SCALEUVROWDOWNEVENBOX_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ScaleUVRowDownEven = filtering ? ScaleUVRowDownEvenBox_Any_NEON + : ScaleUVRowDownEven_Any_NEON; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVRowDownEven = + filtering ? ScaleUVRowDownEvenBox_NEON : ScaleUVRowDownEven_NEON; + } + } +#endif +#if defined(HAS_SCALEUVROWDOWNEVEN_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + ScaleUVRowDownEven = + filtering ? ScaleUVRowDownEvenBox_Any_MMI : ScaleUVRowDownEven_Any_MMI; + if (IS_ALIGNED(dst_width, 2)) { + ScaleUVRowDownEven = + filtering ? ScaleUVRowDownEvenBox_MMI : ScaleUVRowDownEven_MMI; + } + } +#endif +#if defined(HAS_SCALEUVROWDOWNEVEN_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleUVRowDownEven = + filtering ? ScaleUVRowDownEvenBox_Any_MSA : ScaleUVRowDownEven_Any_MSA; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVRowDownEven = + filtering ? ScaleUVRowDownEvenBox_MSA : ScaleUVRowDownEven_MSA; + } + } +#endif + + if (filtering == kFilterLinear) { + src_stride = 0; + } + for (j = 0; j < dst_height; ++j) { + ScaleUVRowDownEven(src_uv, src_stride, col_step, dst_uv, dst_width); + src_uv += row_stride; + dst_uv += dst_stride; + } +} +#endif + +// Scale UV down with bilinear interpolation. +#if HAS_SCALEUVBILINEARDOWN +static void ScaleUVBilinearDown(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy, + enum FilterMode filtering) { + int j; + void (*InterpolateRow)(uint8_t * dst_uv, const uint8_t* src_uv, + ptrdiff_t src_stride, int dst_width, + int source_y_fraction) = InterpolateRow_C; + void (*ScaleUVFilterCols)(uint8_t * dst_uv, const uint8_t* src_uv, + int dst_width, int x, int dx) = + (src_width >= 32768) ? ScaleUVFilterCols64_C : ScaleUVFilterCols_C; + int64_t xlast = x + (int64_t)(dst_width - 1) * dx; + int64_t xl = (dx >= 0) ? x : xlast; + int64_t xr = (dx >= 0) ? xlast : x; + int clip_src_width; + xl = (xl >> 16) & ~3; // Left edge aligned. + xr = (xr >> 16) + 1; // Right most pixel used. Bilinear uses 2 pixels. + xr = (xr + 1 + 3) & ~3; // 1 beyond 4 pixel aligned right most pixel. + if (xr > src_width) { + xr = src_width; + } + clip_src_width = (int)(xr - xl) * 2; // Width aligned to 2. + src_uv += xl * 2; + x -= (int)(xl << 16); +#if defined(HAS_INTERPOLATEROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + InterpolateRow = InterpolateRow_Any_SSSE3; + if (IS_ALIGNED(clip_src_width, 16)) { + InterpolateRow = InterpolateRow_SSSE3; + } + } +#endif +#if defined(HAS_INTERPOLATEROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + InterpolateRow = InterpolateRow_Any_AVX2; + if (IS_ALIGNED(clip_src_width, 32)) { + InterpolateRow = InterpolateRow_AVX2; + } + } +#endif +#if defined(HAS_INTERPOLATEROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + InterpolateRow = InterpolateRow_Any_NEON; + if (IS_ALIGNED(clip_src_width, 16)) { + InterpolateRow = InterpolateRow_NEON; + } + } +#endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(clip_src_width, 32)) { + InterpolateRow = InterpolateRow_MSA; + } + } +#endif +#if defined(HAS_SCALEUVFILTERCOLS_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { + ScaleUVFilterCols = ScaleUVFilterCols_SSSE3; + } +#endif +#if defined(HAS_SCALEUVFILTERCOLS_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ScaleUVFilterCols = ScaleUVFilterCols_Any_NEON; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVFilterCols = ScaleUVFilterCols_NEON; + } + } +#endif +#if defined(HAS_SCALEUVFILTERCOLS_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleUVFilterCols = ScaleUVFilterCols_Any_MSA; + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVFilterCols = ScaleUVFilterCols_MSA; + } + } +#endif + // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. + // Allocate a row of UV. + { + align_buffer_64(row, clip_src_width * 2); + + const int max_y = (src_height - 1) << 16; + if (y > max_y) { + y = max_y; + } + for (j = 0; j < dst_height; ++j) { + int yi = y >> 16; + const uint8_t* src = src_uv + yi * src_stride; + if (filtering == kFilterLinear) { + ScaleUVFilterCols(dst_uv, src, dst_width, x, dx); + } else { + int yf = (y >> 8) & 255; + InterpolateRow(row, src, src_stride, clip_src_width, yf); + ScaleUVFilterCols(dst_uv, row, dst_width, x, dx); + } + dst_uv += dst_stride; + y += dy; + if (y > max_y) { + y = max_y; + } + } + free_aligned_buffer_64(row); + } +} +#endif + +// Scale UV up with bilinear interpolation. +#if HAS_SCALEUVBILINEARUP +static void ScaleUVBilinearUp(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy, + enum FilterMode filtering) { + int j; + void (*InterpolateRow)(uint8_t * dst_uv, const uint8_t* src_uv, + ptrdiff_t src_stride, int dst_width, + int source_y_fraction) = InterpolateRow_C; + void (*ScaleUVFilterCols)(uint8_t * dst_uv, const uint8_t* src_uv, + int dst_width, int x, int dx) = + filtering ? ScaleUVFilterCols_C : ScaleUVCols_C; + const int max_y = (src_height - 1) << 16; +#if defined(HAS_INTERPOLATEROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + InterpolateRow = InterpolateRow_Any_SSSE3; + if (IS_ALIGNED(dst_width, 4)) { + InterpolateRow = InterpolateRow_SSSE3; + } + } +#endif +#if defined(HAS_INTERPOLATEROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + InterpolateRow = InterpolateRow_Any_AVX2; + if (IS_ALIGNED(dst_width, 8)) { + InterpolateRow = InterpolateRow_AVX2; + } + } +#endif +#if defined(HAS_INTERPOLATEROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + InterpolateRow = InterpolateRow_Any_NEON; + if (IS_ALIGNED(dst_width, 4)) { + InterpolateRow = InterpolateRow_NEON; + } + } +#endif +#if defined(HAS_INTERPOLATEROW_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + InterpolateRow = InterpolateRow_Any_MMI; + if (IS_ALIGNED(dst_width, 2)) { + InterpolateRow = InterpolateRow_MMI; + } + } +#endif +#if defined(HAS_INTERPOLATEROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + InterpolateRow = InterpolateRow_Any_MSA; + if (IS_ALIGNED(dst_width, 8)) { + InterpolateRow = InterpolateRow_MSA; + } + } +#endif + if (src_width >= 32768) { + ScaleUVFilterCols = filtering ? ScaleUVFilterCols64_C : ScaleUVCols64_C; + } +#if defined(HAS_SCALEUVFILTERCOLS_SSSE3) + if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { + ScaleUVFilterCols = ScaleUVFilterCols_SSSE3; + } +#endif +#if defined(HAS_SCALEUVFILTERCOLS_NEON) + if (filtering && TestCpuFlag(kCpuHasNEON)) { + ScaleUVFilterCols = ScaleUVFilterCols_Any_NEON; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVFilterCols = ScaleUVFilterCols_NEON; + } + } +#endif +#if defined(HAS_SCALEUVFILTERCOLS_MSA) + if (filtering && TestCpuFlag(kCpuHasMSA)) { + ScaleUVFilterCols = ScaleUVFilterCols_Any_MSA; + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVFilterCols = ScaleUVFilterCols_MSA; + } + } +#endif +#if defined(HAS_SCALEUVCOLS_SSSE3) + if (!filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { + ScaleUVFilterCols = ScaleUVCols_SSSE3; + } +#endif +#if defined(HAS_SCALEUVCOLS_NEON) + if (!filtering && TestCpuFlag(kCpuHasNEON)) { + ScaleUVFilterCols = ScaleUVCols_Any_NEON; + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVFilterCols = ScaleUVCols_NEON; + } + } +#endif +#if defined(HAS_SCALEUVCOLS_MMI) + if (!filtering && TestCpuFlag(kCpuHasMMI)) { + ScaleUVFilterCols = ScaleUVCols_Any_MMI; + if (IS_ALIGNED(dst_width, 1)) { + ScaleUVFilterCols = ScaleUVCols_MMI; + } + } +#endif +#if defined(HAS_SCALEUVCOLS_MSA) + if (!filtering && TestCpuFlag(kCpuHasMSA)) { + ScaleUVFilterCols = ScaleUVCols_Any_MSA; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVFilterCols = ScaleUVCols_MSA; + } + } +#endif + if (!filtering && src_width * 2 == dst_width && x < 0x8000) { + ScaleUVFilterCols = ScaleUVColsUp2_C; +#if defined(HAS_SCALEUVCOLSUP2_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(dst_width, 8)) { + ScaleUVFilterCols = ScaleUVColsUp2_SSSE3; + } +#endif +#if defined(HAS_SCALEUVCOLSUP2_MMI) + if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(dst_width, 4)) { + ScaleUVFilterCols = ScaleUVColsUp2_MMI; + } +#endif + } + + if (y > max_y) { + y = max_y; + } + + { + int yi = y >> 16; + const uint8_t* src = src_uv + yi * src_stride; + + // Allocate 2 rows of UV. + const int kRowSize = (dst_width * 2 + 15) & ~15; + align_buffer_64(row, kRowSize * 2); + + uint8_t* rowptr = row; + int rowstride = kRowSize; + int lasty = yi; + + ScaleUVFilterCols(rowptr, src, dst_width, x, dx); + if (src_height > 1) { + src += src_stride; + } + ScaleUVFilterCols(rowptr + rowstride, src, dst_width, x, dx); + src += src_stride; + + for (j = 0; j < dst_height; ++j) { + yi = y >> 16; + if (yi != lasty) { + if (y > max_y) { + y = max_y; + yi = y >> 16; + src = src_uv + yi * src_stride; + } + if (yi != lasty) { + ScaleUVFilterCols(rowptr, src, dst_width, x, dx); + rowptr += rowstride; + rowstride = -rowstride; + lasty = yi; + src += src_stride; + } + } + if (filtering == kFilterLinear) { + InterpolateRow(dst_uv, rowptr, 0, dst_width * 2, 0); + } else { + int yf = (y >> 8) & 255; + InterpolateRow(dst_uv, rowptr, rowstride, dst_width * 2, yf); + } + dst_uv += dst_stride; + y += dy; + } + free_aligned_buffer_64(row); + } +} +#endif // HAS_SCALEUVBILINEARUP + +// Scale UV to/from any dimensions, without interpolation. +// Fixed point math is used for performance: The upper 16 bits +// of x and dx is the integer part of the source position and +// the lower 16 bits are the fixed decimal part. + +static void ScaleUVSimple(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy) { + int j; + void (*ScaleUVCols)(uint8_t * dst_uv, const uint8_t* src_uv, int dst_width, + int x, int dx) = + (src_width >= 32768) ? ScaleUVCols64_C : ScaleUVCols_C; + (void)src_height; +#if defined(HAS_SCALEUVCOLS_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { + ScaleUVCols = ScaleUVCols_SSSE3; + } +#endif +#if defined(HAS_SCALEUVCOLS_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ScaleUVCols = ScaleUVCols_Any_NEON; + if (IS_ALIGNED(dst_width, 8)) { + ScaleUVCols = ScaleUVCols_NEON; + } + } +#endif +#if defined(HAS_SCALEUVCOLS_MMI) + if (TestCpuFlag(kCpuHasMMI)) { + ScaleUVCols = ScaleUVCols_Any_MMI; + if (IS_ALIGNED(dst_width, 1)) { + ScaleUVCols = ScaleUVCols_MMI; + } + } +#endif +#if defined(HAS_SCALEUVCOLS_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ScaleUVCols = ScaleUVCols_Any_MSA; + if (IS_ALIGNED(dst_width, 4)) { + ScaleUVCols = ScaleUVCols_MSA; + } + } +#endif + if (src_width * 2 == dst_width && x < 0x8000) { + ScaleUVCols = ScaleUVColsUp2_C; +#if defined(HAS_SCALEUVCOLSUP2_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(dst_width, 8)) { + ScaleUVCols = ScaleUVColsUp2_SSSE3; + } +#endif +#if defined(HAS_SCALEUVCOLSUP2_MMI) + if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(dst_width, 4)) { + ScaleUVCols = ScaleUVColsUp2_MMI; + } +#endif + } + + for (j = 0; j < dst_height; ++j) { + ScaleUVCols(dst_uv, src_uv + (y >> 16) * src_stride, dst_width, x, dx); + dst_uv += dst_stride; + y += dy; + } +} + +// Copy UV with optional flipping +#if HAS_UVCOPY +static int UVCopy(const uint8_t* src_UV, + int src_stride_UV, + uint8_t* dst_UV, + int dst_stride_UV, + int width, + int height) { + if (!src_UV || !dst_UV || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_UV = src_UV + (height - 1) * src_stride_UV; + src_stride_UV = -src_stride_UV; + } + + CopyPlane(src_UV, src_stride_UV, dst_UV, dst_stride_UV, width * 2, height); + return 0; +} +#endif // HAS_UVCOPY + +// Scale a UV plane (from NV12) +// This function in turn calls a scaling function +// suitable for handling the desired resolutions. +static void ScaleUV(const uint8_t* src, + int src_stride, + int src_width, + int src_height, + uint8_t* dst, + int dst_stride, + int dst_width, + int dst_height, + int clip_x, + int clip_y, + int clip_width, + int clip_height, + enum FilterMode filtering) { + // Initial source x/y coordinate and step values as 16.16 fixed point. + int x = 0; + int y = 0; + int dx = 0; + int dy = 0; + // UV does not support box filter yet, but allow the user to pass it. + // Simplify filtering when possible. + filtering = ScaleFilterReduce(src_width, src_height, dst_width, dst_height, + filtering); + + // Negative src_height means invert the image. + if (src_height < 0) { + src_height = -src_height; + src = src + (src_height - 1) * src_stride; + src_stride = -src_stride; + } + ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, + &dx, &dy); + src_width = Abs(src_width); + if (clip_x) { + int64_t clipf = (int64_t)(clip_x)*dx; + x += (clipf & 0xffff); + src += (clipf >> 16) * 2; + dst += clip_x * 2; + } + if (clip_y) { + int64_t clipf = (int64_t)(clip_y)*dy; + y += (clipf & 0xffff); + src += (clipf >> 16) * src_stride; + dst += clip_y * dst_stride; + } + + // Special case for integer step values. + if (((dx | dy) & 0xffff) == 0) { + if (!dx || !dy) { // 1 pixel wide and/or tall. + filtering = kFilterNone; + } else { + // Optimized even scale down. ie 2, 4, 6, 8, 10x. + if (!(dx & 0x10000) && !(dy & 0x10000)) { +#if HAS_SCALEUVDOWN2 + if (dx == 0x20000) { + // Optimized 1/2 downsample. + ScaleUVDown2(src_width, src_height, clip_width, clip_height, + src_stride, dst_stride, src, dst, x, dx, y, dy, + filtering); + return; + } +#endif +#if HAS_SCALEUVDOWN4BOX + if (dx == 0x40000 && filtering == kFilterBox) { + // Optimized 1/4 box downsample. + ScaleUVDown4Box(src_width, src_height, clip_width, clip_height, + src_stride, dst_stride, src, dst, x, dx, y, dy); + return; + } +#endif +#if HAS_SCALEUVDOWNEVEN + ScaleUVDownEven(src_width, src_height, clip_width, clip_height, + src_stride, dst_stride, src, dst, x, dx, y, dy, + filtering); + return; +#endif + } + // Optimized odd scale down. ie 3, 5, 7, 9x. + if ((dx & 0x10000) && (dy & 0x10000)) { + filtering = kFilterNone; +#ifdef HAS_UVCOPY + if (dx == 0x10000 && dy == 0x10000) { + // Straight copy. + UVCopy(src + (y >> 16) * src_stride + (x >> 16) * 2, src_stride, dst, + dst_stride, clip_width, clip_height); + return; + } +#endif + } + } + } + // HAS_SCALEPLANEVERTICAL + if (dx == 0x10000 && (x & 0xffff) == 0) { + // Arbitrary scale vertically, but unscaled horizontally. + ScalePlaneVertical(src_height, clip_width, clip_height, src_stride, + dst_stride, src, dst, x, y, dy, 4, filtering); + return; + } + +#if HAS_SCALEUVBILINEARUP + if (filtering && dy < 65536) { + ScaleUVBilinearUp(src_width, src_height, clip_width, clip_height, + src_stride, dst_stride, src, dst, x, dx, y, dy, + filtering); + return; + } +#endif +#if HAS_SCALEUVBILINEARDOWN + if (filtering) { + ScaleUVBilinearDown(src_width, src_height, clip_width, clip_height, + src_stride, dst_stride, src, dst, x, dx, y, dy, + filtering); + return; + } +#endif + ScaleUVSimple(src_width, src_height, clip_width, clip_height, src_stride, + dst_stride, src, dst, x, dx, y, dy); +} + +// Scale an UV image. +LIBYUV_API +int UVScale(const uint8_t* src_uv, + int src_stride_uv, + int src_width, + int src_height, + uint8_t* dst_uv, + int dst_stride_uv, + int dst_width, + int dst_height, + enum FilterMode filtering) { + if (!src_uv || src_width == 0 || src_height == 0 || src_width > 32768 || + src_height > 32768 || !dst_uv || dst_width <= 0 || dst_height <= 0) { + return -1; + } + ScaleUV(src_uv, src_stride_uv, src_width, src_height, dst_uv, dst_stride_uv, + dst_width, dst_height, 0, 0, dst_width, dst_height, filtering); + return 0; +} + +#ifdef __cplusplus +} // extern "C" +} // namespace libyuv +#endif diff --git a/TMessagesProj/jni/voip/CMakeLists.txt b/TMessagesProj/jni/voip/CMakeLists.txt index bd97ae2ac..3873854aa 100644 --- a/TMessagesProj/jni/voip/CMakeLists.txt +++ b/TMessagesProj/jni/voip/CMakeLists.txt @@ -221,6 +221,8 @@ add_library(tgcalls_tp STATIC third_party/libvpx/source/libvpx/vp9/encoder/vp9_temporal_filter.c third_party/libvpx/source/libvpx/vp9/encoder/vp9_tokenize.c third_party/libvpx/source/libvpx/vp9/encoder/vp9_treewriter.c + third_party/libvpx/source/libvpx/vp9/encoder/vp9_ext_ratectrl.c + third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.cc third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c third_party/libvpx/source/libvpx/vp9/vp9_dx_iface.c third_party/libvpx/source/libvpx/vp9/vp9_iface_common.c @@ -738,6 +740,7 @@ add_library(tgcalls STATIC voip/tgcalls/JsonConfig.cpp voip/tgcalls/reference/InstanceImplReference.cpp voip/tgcalls/legacy/InstanceImplLegacy.cpp + voip/tgcalls/group/GroupInstanceImpl.cpp voip/webrtc/rtc_base/async_invoker.cc voip/webrtc/rtc_base/async_packet_socket.cc @@ -801,7 +804,6 @@ add_library(tgcalls STATIC voip/webrtc/rtc_base/numerics/moving_average.cc voip/webrtc/rtc_base/numerics/sample_counter.cc voip/webrtc/rtc_base/numerics/sample_stats.cc - voip/webrtc/rtc_base/numerics/samples_stats_counter.cc voip/webrtc/rtc_base/openssl_adapter.cc voip/webrtc/rtc_base/openssl_certificate.cc voip/webrtc/rtc_base/openssl_digest.cc @@ -837,8 +839,6 @@ add_library(tgcalls STATIC voip/webrtc/rtc_base/strings/audio_format_to_string.cc voip/webrtc/rtc_base/strings/string_builder.cc voip/webrtc/rtc_base/strings/string_format.cc - voip/webrtc/rtc_base/synchronization/rw_lock_posix.cc - voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.cc voip/webrtc/rtc_base/synchronization/mutex.cc voip/webrtc/rtc_base/synchronization/yield.cc voip/webrtc/rtc_base/synchronization/sequence_checker.cc @@ -860,6 +860,7 @@ add_library(tgcalls STATIC voip/webrtc/rtc_base/unique_id_generator.cc voip/webrtc/rtc_base/weak_ptr.cc voip/webrtc/rtc_base/zero_memory.cc + voip/webrtc/rtc_base/callback_list.cc voip/webrtc/rtc_base/deprecated/recursive_critical_section.cc voip/webrtc/rtc_base/deprecated/signal_thread.cc voip/webrtc/api/audio/audio_frame.cc @@ -934,6 +935,7 @@ add_library(tgcalls STATIC voip/webrtc/api/video/video_adaptation_counters.cc voip/webrtc/api/video/video_frame_metadata.cc voip/webrtc/api/voip/voip_engine_factory.cc + voip/webrtc/api/numerics/samples_stats_counter.cc voip/webrtc/call/adaptation/adaptation_constraint.cc voip/webrtc/call/adaptation/broadcast_resource_listener.cc voip/webrtc/call/adaptation/degradation_preference_provider.cc @@ -964,6 +966,7 @@ add_library(tgcalls STATIC voip/webrtc/api/video/video_content_type.cc voip/webrtc/api/video/video_frame.cc voip/webrtc/api/video/video_frame_buffer.cc + voip/webrtc/api/video/nv12_buffer.cc voip/webrtc/api/video/video_source_interface.cc voip/webrtc/api/video/video_stream_decoder_create.cc voip/webrtc/api/video/video_stream_encoder_create.cc @@ -981,6 +984,7 @@ add_library(tgcalls STATIC voip/webrtc/api/video_codecs/vp8_frame_config.cc voip/webrtc/api/video_codecs/vp8_temporal_layers.cc voip/webrtc/api/video_codecs/vp8_temporal_layers_factory.cc + voip/webrtc/api/video_codecs/spatial_layer.cc voip/webrtc/pc/audio_rtp_receiver.cc voip/webrtc/pc/audio_track.cc voip/webrtc/pc/channel.cc @@ -1037,6 +1041,12 @@ add_library(tgcalls STATIC voip/webrtc/pc/video_track_source.cc voip/webrtc/pc/webrtc_sdp.cc voip/webrtc/pc/webrtc_session_description_factory.cc + voip/webrtc/pc/connection_context.cc + voip/webrtc/pc/peer_connection_message_handler.cc + voip/webrtc/pc/rtp_transmission_manager.cc + voip/webrtc/pc/sdp_offer_answer.cc + voip/webrtc/pc/transceiver_list.cc + voip/webrtc/pc/usage_pattern.cc voip/webrtc/media/base/adapted_video_track_source.cc voip/webrtc/media/base/codec.cc voip/webrtc/media/base/h264_profile_level_id.cc @@ -1176,9 +1186,6 @@ add_library(tgcalls STATIC voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.cc voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc voip/webrtc/modules/audio_coding/codecs/opus/opus_interface.cc - voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.cc - voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.cc - voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.cc voip/webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc voip/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc voip/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b_common.cc @@ -1353,6 +1360,7 @@ add_library(tgcalls STATIC voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.cc voip/webrtc/modules/audio_processing/aec3/suppression_filter.cc voip/webrtc/modules/audio_processing/aec3/suppression_gain.cc + voip/webrtc/modules/audio_processing/aec3/transparent_mode.cc voip/webrtc/modules/audio_processing/aec_dump/null_aec_dump_factory.cc voip/webrtc/modules/audio_processing/aecm/aecm_core.cc voip/webrtc/modules/audio_processing/aecm/aecm_core_c.cc @@ -1367,7 +1375,6 @@ add_library(tgcalls STATIC voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc - voip/webrtc/modules/audio_processing/agc2/agc2_common.cc voip/webrtc/modules/audio_processing/agc2/agc2_testing_common.cc voip/webrtc/modules/audio_processing/agc2/biquad_filter.cc voip/webrtc/modules/audio_processing/agc2/compute_interpolated_gain_curve.cc @@ -1472,7 +1479,6 @@ add_library(tgcalls STATIC voip/webrtc/modules/congestion_controller/goog_cc/robust_throughput_estimator.cc voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc voip/webrtc/modules/congestion_controller/goog_cc/trendline_estimator.cc - voip/webrtc/modules/include/module_common_types.cc voip/webrtc/modules/pacing/bitrate_prober.cc voip/webrtc/modules/pacing/interval_budget.cc voip/webrtc/modules/pacing/paced_sender.cc @@ -1575,6 +1581,7 @@ add_library(tgcalls STATIC voip/webrtc/modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.cc voip/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc voip/webrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc + voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.cc voip/webrtc/modules/utility/source/helpers_android.cc voip/webrtc/modules/utility/source/jvm_android.cc voip/webrtc/modules/utility/source/process_thread_impl.cc @@ -1646,10 +1653,23 @@ add_library(tgcalls STATIC voip/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc voip/webrtc/modules/video_coding/codecs/vp8/temporal_layers_checker.cc voip/webrtc/modules/video_coding/codecs/vp9/svc_config.cc - voip/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc voip/webrtc/modules/video_coding/codecs/vp9/vp9.cc voip/webrtc/modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.cc voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc + voip/webrtc/modules/video_coding/svc/create_scalability_structure.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1h.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2_key_shift.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_l3t1.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.cc + voip/webrtc/modules/video_coding/svc/scalability_structure_s2t1.cc + voip/webrtc/modules/video_coding/svc/scalable_video_controller_no_layering.cc + voip/webrtc/modules/video_coding/svc/svc_rate_allocator.cc voip/webrtc/modules/video_processing/util/denoiser_filter.cc voip/webrtc/modules/video_processing/util/denoiser_filter_c.cc voip/webrtc/modules/video_processing/util/noise_estimation.cc @@ -1751,11 +1771,11 @@ add_library(tgcalls STATIC voip/webrtc/common_video/h265/h265_pps_parser.cc voip/webrtc/common_video/h265/h265_sps_parser.cc voip/webrtc/common_video/h265/h265_vps_parser.cc - voip/webrtc/common_video/i420_buffer_pool.cc voip/webrtc/common_video/incoming_video_stream.cc voip/webrtc/common_video/libyuv/webrtc_libyuv.cc voip/webrtc/common_video/video_frame_buffer.cc voip/webrtc/common_video/video_render_frames.cc + voip/webrtc/common_video/video_frame_buffer_pool.cc voip/webrtc/p2p/base/async_stun_tcp_socket.cc voip/webrtc/p2p/base/basic_async_resolver_factory.cc voip/webrtc/p2p/base/basic_ice_controller.cc @@ -1792,6 +1812,7 @@ add_library(tgcalls STATIC voip/webrtc/video/adaptation/quality_rampup_experiment_helper.cc voip/webrtc/modules/video_coding/deprecated/nack_module.cc voip/webrtc/modules/video_coding/nack_module2.cc + voip/webrtc/modules/async_audio_processing/async_audio_processing.cc voip/webrtc/logging/rtc_event_log/encoder/blob_encoding.cc voip/webrtc/logging/rtc_event_log/encoder/delta_encoding.cc voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_common.cc @@ -1830,6 +1851,8 @@ add_library(tgcalls STATIC voip/webrtc/video/adaptation/quality_scaler_resource.cc voip/webrtc/video/adaptation/video_stream_encoder_resource.cc voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.cc + voip/webrtc/video/adaptation/balanced_constraint.cc + voip/webrtc/video/adaptation/bitrate_constraint.cc voip/webrtc/video/buffered_frame_decryptor.cc voip/webrtc/video/call_stats.cc voip/webrtc/video/encoder_bitrate_adjuster.cc @@ -1864,6 +1887,7 @@ add_library(tgcalls STATIC voip/webrtc/video/rtp_streams_synchronizer2.cc voip/webrtc/video/receive_statistics_proxy2.cc voip/webrtc/video/call_stats2.cc + voip/webrtc/video/alignment_adjuster.cc voip/webrtc/audio/audio_level.cc voip/webrtc/audio/audio_receive_stream.cc voip/webrtc/audio/audio_send_stream.cc diff --git a/TMessagesProj/jni/voip/org_telegram_messenger_voip_Instance.cpp b/TMessagesProj/jni/voip/org_telegram_messenger_voip_Instance.cpp index 8a852a6b0..b1e6485fb 100644 --- a/TMessagesProj/jni/voip/org_telegram_messenger_voip_Instance.cpp +++ b/TMessagesProj/jni/voip/org_telegram_messenger_voip_Instance.cpp @@ -10,6 +10,9 @@ #include #include #include +#include + +#include #include "pc/video_track.h" #include "legacy/InstanceImplLegacy.h" @@ -69,12 +72,14 @@ public: struct InstanceHolder { std::unique_ptr nativeInstance; + std::unique_ptr groupNativeInstance; jobject javaInstance; std::shared_ptr _videoCapture; std::shared_ptr _platformContext; }; jclass TrafficStatsClass; +jclass FingerprintClass; jclass FinalStateClass; jclass NativeInstanceClass; jmethodID FinalStateInitMethod; @@ -87,10 +92,6 @@ InstanceHolder *getInstanceHolder(JNIEnv *env, jobject obj) { return reinterpret_cast(getInstanceHolderId(env, obj)); } -Instance *getInstance(JNIEnv *env, jobject obj) { - return getInstanceHolder(env, obj)->nativeInstance.get(); -} - jint throwNewJavaException(JNIEnv *env, const char *className, const char *message) { return env->ThrowNew(env->FindClass(className), message); } @@ -220,6 +221,14 @@ jobject asJavaFinalState(JNIEnv *env, const FinalState &finalState) { return env->NewObject(FinalStateClass, FinalStateInitMethod, persistentState, debugLog, trafficStats, isRatingSuggested); } +jobject asJavaFingerprint(JNIEnv *env, std::string hash, std::string setup, std::string fingerprint) { + jstring hashStr = env->NewStringUTF(hash.c_str()); + jstring setupStr = env->NewStringUTF(setup.c_str()); + jstring fingerprintStr = env->NewStringUTF(fingerprint.c_str()); + jmethodID initMethodId = env->GetMethodID(FingerprintClass, "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); + return env->NewObject(FingerprintClass, initMethodId, hashStr, setupStr, fingerprintStr); +} + extern "C" { bool webrtcLoaded = false; @@ -237,10 +246,129 @@ void initWebRTC(JNIEnv *env) { NativeInstanceClass = static_cast(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/NativeInstance"))); TrafficStatsClass = static_cast(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/Instance$TrafficStats"))); + FingerprintClass = static_cast(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/Instance$Fingerprint"))); FinalStateClass = static_cast(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/Instance$FinalState"))); FinalStateInitMethod = env->GetMethodID(FinalStateClass, "", "([BLjava/lang/String;Lorg/telegram/messenger/voip/Instance$TrafficStats;Z)V"); } +JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeGroupNativeInstance(JNIEnv *env, jclass clazz, jobject instanceObj, jboolean highQuality) { + initWebRTC(env); + + jobject globalRef = env->NewGlobalRef(instanceObj); + std::shared_ptr platformContext = std::make_shared(env); + + GroupInstanceDescriptor descriptor = { + .networkStateUpdated = [globalRef](bool state) { + tgvoip::jni::DoWithJNI([globalRef, state](JNIEnv *env) { + env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onNetworkStateUpdated", "(Z)V"), state); + }); + }, + .audioLevelsUpdated = [globalRef](GroupLevelsUpdate const &update) { + tgvoip::jni::DoWithJNI([globalRef, update](JNIEnv *env) { + unsigned int size = update.updates.size(); + jintArray intArray = env->NewIntArray(size); + jfloatArray floatArray = env->NewFloatArray(size); + jbooleanArray boolArray = env->NewBooleanArray(size); + + jint intFill[size]; + jfloat floatFill[size]; + jboolean boolFill[size]; + for (int a = 0; a < size; a++) { + intFill[a] = update.updates[a].ssrc; + floatFill[a] = update.updates[a].value.level; + boolFill[a] = update.updates[a].value.voice; + } + env->SetIntArrayRegion(intArray, 0, size, intFill); + env->SetFloatArrayRegion(floatArray, 0, size, floatFill); + env->SetBooleanArrayRegion(boolArray, 0, size, boolFill); + + env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onAudioLevelsUpdated", "([I[F[Z)V"), intArray, floatArray, boolArray); + env->DeleteLocalRef(intArray); + env->DeleteLocalRef(floatArray); + env->DeleteLocalRef(boolArray); + }); + }, + .platformContext = platformContext + }; + + auto *holder = new InstanceHolder; + holder->groupNativeInstance = std::make_unique(std::move(descriptor)); + holder->javaInstance = globalRef; + holder->_platformContext = platformContext; + holder->groupNativeInstance->emitJoinPayload([globalRef](const GroupJoinPayload& payload) { + JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded(); + jobjectArray array = env->NewObjectArray(payload.fingerprints.size(), FingerprintClass, 0); + for (int a = 0; a < payload.fingerprints.size(); a++) { + env->SetObjectArrayElement(array, a, asJavaFingerprint(env, payload.fingerprints[a].hash, payload.fingerprints[a].setup, payload.fingerprints[a].fingerprint)); + } + env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onEmitJoinPayload", "(Ljava/lang/String;Ljava/lang/String;[Lorg/telegram/messenger/voip/Instance$Fingerprint;I)V"), env->NewStringUTF(payload.ufrag.c_str()), env->NewStringUTF(payload.pwd.c_str()), array, (jint) payload.ssrc); + }); + return reinterpret_cast(holder); +} + +JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setJoinResponsePayload(JNIEnv *env, jobject obj, jstring ufrag, jstring pwd, jobjectArray fingerprints, jobjectArray candidates) { + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->groupNativeInstance == nullptr) { + return; + } + std::vector fingerprintsArray; + std::vector candidatesArray; + + jsize size = env->GetArrayLength(fingerprints); + for (int i = 0; i < size; i++) { + JavaObject fingerprintObject(env, env->GetObjectArrayElement(fingerprints, i)); + fingerprintsArray.push_back( + { + .hash = tgvoip::jni::JavaStringToStdString(env, fingerprintObject.getStringField("hash")), + .setup = tgvoip::jni::JavaStringToStdString(env, fingerprintObject.getStringField("setup")), + .fingerprint = tgvoip::jni::JavaStringToStdString(env, fingerprintObject.getStringField("fingerprint")) + }); + } + size = env->GetArrayLength(candidates); + for (int i = 0; i < size; i++) { + JavaObject candidateObject(env, env->GetObjectArrayElement(candidates, i)); + candidatesArray.push_back( + { + .port = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("port")), + .protocol = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("protocol")), + .network = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("network")), + .generation = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("generation")), + .id = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("id")), + .component = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("component")), + .foundation = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("foundation")), + .priority = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("priority")), + .ip = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("ip")), + .type = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("type")), + .tcpType = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("tcpType")), + .relAddr = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("relAddr")), + .relPort = tgvoip::jni::JavaStringToStdString(env, candidateObject.getStringField("relPort")), + }); + } + + instance->groupNativeInstance->setJoinResponsePayload( + { + .ufrag = tgvoip::jni::JavaStringToStdString(env, ufrag), + .pwd = tgvoip::jni::JavaStringToStdString(env, pwd), + .fingerprints = fingerprintsArray, + .candidates = candidatesArray, + }); +} + +JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_removeSsrcs(JNIEnv *env, jobject obj, jintArray ssrcs) { + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->groupNativeInstance == nullptr) { + return; + } + jsize size = env->GetArrayLength(ssrcs); + + std::vector ssrcsArray; + ssrcsArray.resize(size); + for (int i = 0; i < size; i++) { + env->GetIntArrayRegion(ssrcs, 0, size, reinterpret_cast(ssrcsArray.data())); + } + instance->groupNativeInstance->removeSsrcs(ssrcsArray); +} + JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNativeInstance(JNIEnv *env, jclass clazz, jstring version, jobject instanceObj, jobject config, jstring persistentStateFilePath, jobjectArray endpoints, jobject proxyClass, jint networkType, jobject encryptionKey, jobject remoteSink, jlong videoCapturer, jfloat aspectRatio) { initWebRTC(env); @@ -369,43 +497,83 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setBuffer } JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setNetworkType(JNIEnv *env, jobject obj, jint networkType) { - getInstance(env, obj)->setNetworkType(parseNetworkType(networkType)); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return; + } + instance->nativeInstance->setNetworkType(parseNetworkType(networkType)); } JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setMuteMicrophone(JNIEnv *env, jobject obj, jboolean muteMicrophone) { - getInstance(env, obj)->setMuteMicrophone(muteMicrophone); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance != nullptr) { + instance->nativeInstance->setMuteMicrophone(muteMicrophone); + } else if (instance->groupNativeInstance != nullptr) { + instance->groupNativeInstance->setIsMuted(muteMicrophone); + } } JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setAudioOutputGainControlEnabled(JNIEnv *env, jobject obj, jboolean enabled) { - getInstance(env, obj)->setAudioOutputGainControlEnabled(enabled); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return; + } + instance->nativeInstance->setAudioOutputGainControlEnabled(enabled); } JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setEchoCancellationStrength(JNIEnv *env, jobject obj, jint strength) { - getInstance(env, obj)->setEchoCancellationStrength(strength); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return; + } + instance->nativeInstance->setEchoCancellationStrength(strength); } JNIEXPORT jstring JNICALL Java_org_telegram_messenger_voip_NativeInstance_getLastError(JNIEnv *env, jobject obj) { - return env->NewStringUTF(getInstance(env, obj)->getLastError().c_str()); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return nullptr; + } + return env->NewStringUTF(instance->nativeInstance->getLastError().c_str()); } JNIEXPORT jstring JNICALL Java_org_telegram_messenger_voip_NativeInstance_getDebugInfo(JNIEnv *env, jobject obj) { - return env->NewStringUTF(getInstance(env, obj)->getDebugInfo().c_str()); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return nullptr; + } + return env->NewStringUTF(instance->nativeInstance->getDebugInfo().c_str()); } JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_getPreferredRelayId(JNIEnv *env, jobject obj) { - return getInstance(env, obj)->getPreferredRelayId(); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return 0; + } + return instance->nativeInstance->getPreferredRelayId(); } JNIEXPORT jobject JNICALL Java_org_telegram_messenger_voip_NativeInstance_getTrafficStats(JNIEnv *env, jobject obj) { - return asJavaTrafficStats(env, getInstance(env, obj)->getTrafficStats()); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return nullptr; + } + return asJavaTrafficStats(env, instance->nativeInstance->getTrafficStats()); } JNIEXPORT jbyteArray JNICALL Java_org_telegram_messenger_voip_NativeInstance_getPersistentState(JNIEnv *env, jobject obj) { - return copyVectorToJavaByteArray(env, getInstance(env, obj)->getPersistentState().value); + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return nullptr; + } + return copyVectorToJavaByteArray(env, instance->nativeInstance->getPersistentState().value); } JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_stopNative(JNIEnv *env, jobject obj) { InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return; + } instance->nativeInstance->stop([instance](FinalState finalState) { JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded(); const std::string &path = tgvoip::jni::JavaStringToStdString(env, JavaObject(env, instance->javaInstance).getStringField("persistentStateFilePath")); @@ -416,6 +584,17 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_stopNativ }); } +JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_stopGroupNative(JNIEnv *env, jobject obj) { + InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->groupNativeInstance == nullptr) { + return; + } + instance->groupNativeInstance->stop(); + instance->groupNativeInstance.reset(); + env->DeleteGlobalRef(instance->javaInstance); + delete instance; +} + JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_createVideoCapturer(JNIEnv *env, jclass clazz, jobject localSink, jboolean front) { initWebRTC(env); std::unique_ptr capture = tgcalls::VideoCaptureInterface::Create(front ? "front" : "back", std::make_shared(env)); @@ -441,6 +620,9 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setVideoS JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_switchCamera(JNIEnv *env, jobject obj, jboolean front) { InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return; + } if (instance->_videoCapture == nullptr) { return; } @@ -449,6 +631,9 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_switchCam JNIEXPORT void Java_org_telegram_messenger_voip_NativeInstance_setVideoState(JNIEnv *env, jobject obj, jint state) { InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return; + } if (instance->_videoCapture == nullptr) { return; } @@ -457,6 +642,9 @@ JNIEXPORT void Java_org_telegram_messenger_voip_NativeInstance_setVideoState(JNI JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setupOutgoingVideo(JNIEnv *env, jobject obj, jobject localSink, jboolean front) { InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return; + } if (instance->_videoCapture) { return; } @@ -468,6 +656,9 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setupOutg JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onSignalingDataReceive(JNIEnv *env, jobject obj, jbyteArray value) { InstanceHolder *instance = getInstanceHolder(env, obj); + if (instance->nativeInstance == nullptr) { + return; + } auto *valueBytes = (uint8_t *) env->GetByteArrayElements(value, nullptr); const size_t size = env->GetArrayLength(value); @@ -477,5 +668,4 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_onSignali env->ReleaseByteArrayElements(value, (jbyte *) valueBytes, JNI_ABORT); } - } \ No newline at end of file diff --git a/TMessagesProj/jni/voip/tgcalls/CryptoHelper.cpp b/TMessagesProj/jni/voip/tgcalls/CryptoHelper.cpp index 67603734e..a9c8cd3af 100644 --- a/TMessagesProj/jni/voip/tgcalls/CryptoHelper.cpp +++ b/TMessagesProj/jni/voip/tgcalls/CryptoHelper.cpp @@ -1,6 +1,7 @@ #include "CryptoHelper.h" #include +#include namespace tgcalls { diff --git a/TMessagesProj/jni/voip/tgcalls/Instance.h b/TMessagesProj/jni/voip/tgcalls/Instance.h index 6a48907cd..f91c270a1 100644 --- a/TMessagesProj/jni/voip/tgcalls/Instance.h +++ b/TMessagesProj/jni/voip/tgcalls/Instance.h @@ -23,11 +23,13 @@ namespace tgcalls { class VideoCaptureInterface; class PlatformContext; +struct FilePath { #ifndef _WIN32 -using FilePath = std::string; + std::string data; #else -using FilePath = std::wstring; + std::wstring data; #endif +}; struct Proxy { std::string host; @@ -217,6 +219,7 @@ struct Descriptor { std::shared_ptr videoCapture; std::function stateUpdated; std::function signalBarsUpdated; + std::function audioLevelUpdated; std::function remoteBatteryLevelIsLowUpdated; std::function remoteMediaStateUpdated; std::function remotePrefferedAspectRatioUpdated; diff --git a/TMessagesProj/jni/voip/tgcalls/InstanceImpl.cpp b/TMessagesProj/jni/voip/tgcalls/InstanceImpl.cpp index 0abdecdd6..508954928 100644 --- a/TMessagesProj/jni/voip/tgcalls/InstanceImpl.cpp +++ b/TMessagesProj/jni/voip/tgcalls/InstanceImpl.cpp @@ -25,11 +25,11 @@ rtc::Thread *getManagerThread() { } // namespace InstanceImpl::InstanceImpl(Descriptor &&descriptor) -: _logSink(std::make_unique(descriptor.config)) { +: _logSink(std::make_unique(descriptor.config.logPath)) { rtc::LogMessage::LogToDebug(rtc::LS_INFO); rtc::LogMessage::SetLogToStderr(false); rtc::LogMessage::AddLogToStream(_logSink.get(), rtc::LS_INFO); - + auto networkType = descriptor.initialNetworkType; _manager.reset(new ThreadLocalObject(getManagerThread(), [descriptor = std::move(descriptor)]() mutable { @@ -38,7 +38,7 @@ InstanceImpl::InstanceImpl(Descriptor &&descriptor) _manager->perform(RTC_FROM_HERE, [](Manager *manager) { manager->start(); }); - + setNetworkType(networkType); } @@ -74,7 +74,7 @@ void InstanceImpl::setNetworkType(NetworkType networkType) { default: break; } - + _manager->perform(RTC_FROM_HERE, [isLowCostNetwork](Manager *manager) { manager->setIsLocalNetworkLowCost(isLowCostNetwork); }); @@ -154,7 +154,7 @@ PersistentState InstanceImpl::getPersistentState() { void InstanceImpl::stop(std::function completion) { std::string debugLog = _logSink->result(); - + _manager->perform(RTC_FROM_HERE, [completion, debugLog = std::move(debugLog)](Manager *manager) { manager->getNetworkStats([completion, debugLog = std::move(debugLog)](TrafficStats stats, CallStats callStats) { FinalState finalState; @@ -162,7 +162,7 @@ void InstanceImpl::stop(std::function completion) { finalState.isRatingSuggested = false; finalState.trafficStats = stats; finalState.callStats = callStats; - + completion(finalState); }); }); diff --git a/TMessagesProj/jni/voip/tgcalls/LogSinkImpl.cpp b/TMessagesProj/jni/voip/tgcalls/LogSinkImpl.cpp index 77755c319..b7e53e07f 100644 --- a/TMessagesProj/jni/voip/tgcalls/LogSinkImpl.cpp +++ b/TMessagesProj/jni/voip/tgcalls/LogSinkImpl.cpp @@ -11,9 +11,9 @@ namespace tgcalls { -LogSinkImpl::LogSinkImpl(const Config &config) { - if (!config.logPath.empty()) { - _file.open(config.logPath); +LogSinkImpl::LogSinkImpl(const FilePath &logPath) { + if (!logPath.data.empty()) { + _file.open(logPath.data); } } @@ -64,7 +64,7 @@ void LogSinkImpl::OnLogMessage(const std::string &message) { << ":" << timeinfo.tm_sec << ":" << milliseconds << " " << message; - + #if DEBUG printf("%d-%d-%d %d:%d:%d:%d %s\n", timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, milliseconds, message.c_str()); #endif diff --git a/TMessagesProj/jni/voip/tgcalls/LogSinkImpl.h b/TMessagesProj/jni/voip/tgcalls/LogSinkImpl.h index 5c6aa1d11..5d480ffb0 100644 --- a/TMessagesProj/jni/voip/tgcalls/LogSinkImpl.h +++ b/TMessagesProj/jni/voip/tgcalls/LogSinkImpl.h @@ -6,11 +6,11 @@ namespace tgcalls { -struct Config; +struct FilePath; class LogSinkImpl final : public rtc::LogSink { public: - LogSinkImpl(const Config &config); + LogSinkImpl(const FilePath &logPath); void OnLogMessage(const std::string &msg, rtc::LoggingSeverity severity, const char *tag) override; void OnLogMessage(const std::string &message, rtc::LoggingSeverity severity) override; diff --git a/TMessagesProj/jni/voip/tgcalls/Manager.cpp b/TMessagesProj/jni/voip/tgcalls/Manager.cpp index affc0c346..a789d088c 100644 --- a/TMessagesProj/jni/voip/tgcalls/Manager.cpp +++ b/TMessagesProj/jni/voip/tgcalls/Manager.cpp @@ -27,11 +27,11 @@ rtc::Thread *makeMediaThread() { } void dumpStatsLog(const FilePath &path, const CallStats &stats) { - if (path.empty()) { + if (path.data.empty()) { return; } std::ofstream file; - file.open(path); + file.open(path.data); file << "{"; file << "\"v\":\"" << 1 << "\""; @@ -112,6 +112,7 @@ _enableStunMarking(descriptor.config.enableStunMarking), _protocolVersion(descriptor.config.protocolVersion), _statsLogPath(descriptor.config.statsLogPath), _rtcServers(std::move(descriptor.rtcServers)), +_proxy(std::move(descriptor.proxy)), _mediaDevicesConfig(std::move(descriptor.mediaDevicesConfig)), _videoCapture(std::move(descriptor.videoCapture)), _stateUpdated(std::move(descriptor.stateUpdated)), @@ -120,6 +121,7 @@ _remoteBatteryLevelIsLowUpdated(std::move(descriptor.remoteBatteryLevelIsLowUpda _remotePrefferedAspectRatioUpdated(std::move(descriptor.remotePrefferedAspectRatioUpdated)), _signalingDataEmitted(std::move(descriptor.signalingDataEmitted)), _signalBarsUpdated(std::move(descriptor.signalBarsUpdated)), +_audioLevelUpdated(std::move(descriptor.audioLevelUpdated)), _enableHighBitrateVideo(descriptor.config.enableHighBitrateVideo), _dataSaving(descriptor.config.dataSaving), _platformContext(descriptor.platformContext) { @@ -177,7 +179,7 @@ void Manager::start() { strong->_sendSignalingMessage(std::move(message)); }); }; - _networkManager.reset(new ThreadLocalObject(getNetworkThread(), [weak, thread, sendSignalingMessage, encryptionKey = _encryptionKey, enableP2P = _enableP2P, enableTCP = _enableTCP, enableStunMarking = _enableStunMarking, rtcServers = _rtcServers] { + _networkManager.reset(new ThreadLocalObject(getNetworkThread(), [weak, thread, sendSignalingMessage, encryptionKey = _encryptionKey, enableP2P = _enableP2P, enableTCP = _enableTCP, enableStunMarking = _enableStunMarking, rtcServers = _rtcServers, proxy = std::move(_proxy)] () mutable { return new NetworkManager( getNetworkThread(), encryptionKey, @@ -185,6 +187,7 @@ void Manager::start() { enableTCP, enableStunMarking, rtcServers, + std::move(proxy), [=](const NetworkManager::State &state) { thread->PostTask(RTC_FROM_HERE, [=] { const auto strong = weak.lock(); @@ -242,7 +245,7 @@ void Manager::start() { }); })); bool isOutgoing = _encryptionKey.isOutgoing; - _mediaManager.reset(new ThreadLocalObject(getMediaThread(), [weak, isOutgoing, protocolVersion = _protocolVersion, thread, sendSignalingMessage, videoCapture = _videoCapture, mediaDevicesConfig = _mediaDevicesConfig, enableHighBitrateVideo = _enableHighBitrateVideo, signalBarsUpdated = _signalBarsUpdated, preferredCodecs = _preferredCodecs, platformContext = _platformContext]() { + _mediaManager.reset(new ThreadLocalObject(getMediaThread(), [weak, isOutgoing, protocolVersion = _protocolVersion, thread, sendSignalingMessage, videoCapture = _videoCapture, mediaDevicesConfig = _mediaDevicesConfig, enableHighBitrateVideo = _enableHighBitrateVideo, signalBarsUpdated = _signalBarsUpdated, audioLevelUpdated = _audioLevelUpdated, preferredCodecs = _preferredCodecs, platformContext = _platformContext]() { return new MediaManager( getMediaThread(), isOutgoing, @@ -260,6 +263,7 @@ void Manager::start() { }); }, signalBarsUpdated, + audioLevelUpdated, enableHighBitrateVideo, preferredCodecs, platformContext); diff --git a/TMessagesProj/jni/voip/tgcalls/Manager.h b/TMessagesProj/jni/voip/tgcalls/Manager.h index bc720fbb9..621936c1a 100644 --- a/TMessagesProj/jni/voip/tgcalls/Manager.h +++ b/TMessagesProj/jni/voip/tgcalls/Manager.h @@ -57,6 +57,7 @@ private: ProtocolVersion _protocolVersion = ProtocolVersion::V0; FilePath _statsLogPath; std::vector _rtcServers; + std::unique_ptr _proxy; MediaDevicesConfig _mediaDevicesConfig; std::shared_ptr _videoCapture; std::function _stateUpdated; @@ -65,6 +66,7 @@ private: std::function _remotePrefferedAspectRatioUpdated; std::function &)> _signalingDataEmitted; std::function _signalBarsUpdated; + std::function _audioLevelUpdated; std::function _sendSignalingMessage; std::function _sendTransportMessage; std::unique_ptr> _networkManager; diff --git a/TMessagesProj/jni/voip/tgcalls/MediaManager.cpp b/TMessagesProj/jni/voip/tgcalls/MediaManager.cpp index 1a7eed12b..64377fcbb 100644 --- a/TMessagesProj/jni/voip/tgcalls/MediaManager.cpp +++ b/TMessagesProj/jni/voip/tgcalls/MediaManager.cpp @@ -17,6 +17,8 @@ #include "api/video/builtin_video_bitrate_allocator_factory.h" #include "call/call.h" #include "modules/rtp_rtcp/source/rtp_utility.h" +#include "api/call/audio_sink.h" +#include "modules/audio_processing/audio_buffer.h" namespace tgcalls { namespace { @@ -82,6 +84,47 @@ private: }; +class AudioTrackSinkInterfaceImpl: public webrtc::AudioSinkInterface { +private: + std::function _update; + + int _peakCount = 0; + uint16_t _peak = 0; + +public: + AudioTrackSinkInterfaceImpl(std::function update) : + _update(update) { + } + + virtual ~AudioTrackSinkInterfaceImpl() { + } + + virtual void OnData(const Data& audio) override { + if (audio.channels == 1) { + int16_t *samples = (int16_t *)audio.data; + int numberOfSamplesInFrame = (int)audio.samples_per_channel; + + for (int i = 0; i < numberOfSamplesInFrame; i++) { + int16_t sample = samples[i]; + if (sample < 0) { + sample = -sample; + } + if (_peak < sample) { + _peak = sample; + } + _peakCount += 1; + } + + if (_peakCount >= 1200) { + float level = ((float)(_peak)) / 4000.0f; + _peak = 0; + _peakCount = 0; + _update(level); + } + } + } +}; + rtc::Thread *MediaManager::getWorkerThread() { static rtc::Thread *value = makeWorkerThread(); return value; @@ -96,6 +139,7 @@ MediaManager::MediaManager( std::function sendSignalingMessage, std::function sendTransportMessage, std::function signalBarsUpdated, + std::function audioLevelUpdated, bool enableHighBitrateVideo, std::vector preferredCodecs, std::shared_ptr platformContext) : @@ -105,6 +149,7 @@ _taskQueueFactory(webrtc::CreateDefaultTaskQueueFactory()), _sendSignalingMessage(std::move(sendSignalingMessage)), _sendTransportMessage(std::move(sendTransportMessage)), _signalBarsUpdated(std::move(signalBarsUpdated)), +_audioLevelUpdated(std::move(audioLevelUpdated)), _protocolVersion(protocolVersion), _outgoingVideoState(videoCapture ? VideoState::Active : VideoState::Inactive), _videoCapture(std::move(videoCapture)), @@ -264,6 +309,27 @@ rtc::scoped_refptr MediaManager::createAudioDeviceMod } void MediaManager::start() { + const auto weak = std::weak_ptr(shared_from_this()); + + // Here we hope that thread outlives the sink + rtc::Thread *thread = _thread; + std::unique_ptr incomingSink(new AudioTrackSinkInterfaceImpl([weak, thread](float level) { + thread->PostTask(RTC_FROM_HERE, [weak, level] { + if (const auto strong = weak.lock()) { + strong->_currentAudioLevel = level; + } + }); + })); + std::unique_ptr outgoingSink(new AudioTrackSinkInterfaceImpl([weak, thread](float level) { + thread->PostTask(RTC_FROM_HERE, [weak, level] { + if (const auto strong = weak.lock()) { + strong->_currentMyAudioLevel = level; + } + }); + })); + _audioChannel->SetRawAudioSink(_ssrcAudio.incoming, std::move(incomingSink)); + _audioChannel->SetRawAudioSink(_ssrcAudio.outgoing, std::move(outgoingSink)); + _sendSignalingMessage({ _myVideoFormats }); if (_videoCapture != nullptr) { @@ -271,6 +337,9 @@ void MediaManager::start() { } beginStatsTimer(3000); + if (_audioLevelUpdated != nullptr) { + beginLevelsTimer(50); + } } MediaManager::~MediaManager() { @@ -369,6 +438,21 @@ void MediaManager::beginStatsTimer(int timeoutMs) { }, timeoutMs); } +void MediaManager::beginLevelsTimer(int timeoutMs) { + const auto weak = std::weak_ptr(shared_from_this()); + _thread->PostDelayedTask(RTC_FROM_HERE, [weak]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + + float effectiveLevel = fmaxf(strong->_currentAudioLevel, strong->_currentMyAudioLevel); + strong->_audioLevelUpdated(effectiveLevel); + + strong->beginLevelsTimer(50); + }, timeoutMs); +} + void MediaManager::collectStats() { auto stats = _call->GetStats(); float bitrateNorm = 16.0f; diff --git a/TMessagesProj/jni/voip/tgcalls/MediaManager.h b/TMessagesProj/jni/voip/tgcalls/MediaManager.h index 1bd372a33..154a7f2cf 100644 --- a/TMessagesProj/jni/voip/tgcalls/MediaManager.h +++ b/TMessagesProj/jni/voip/tgcalls/MediaManager.h @@ -47,6 +47,7 @@ public: std::function sendSignalingMessage, std::function sendTransportMessage, std::function signalBarsUpdated, + std::function audioLevelUpdated, bool enableHighBitrateVideo, std::vector preferredCodecs, std::shared_ptr platformContext); @@ -115,6 +116,7 @@ private: rtc::scoped_refptr createAudioDeviceModule(); void beginStatsTimer(int timeoutMs); + void beginLevelsTimer(int timeoutMs); void collectStats(); rtc::Thread *_thread = nullptr; @@ -124,6 +126,7 @@ private: std::function _sendSignalingMessage; std::function _sendTransportMessage; std::function _signalBarsUpdated; + std::function _audioLevelUpdated; SSRC _ssrcAudio; SSRC _ssrcVideo; @@ -158,6 +161,9 @@ private: bool _enableHighBitrateVideo = false; bool _isLowCostNetwork = false; bool _isDataSavingActive = false; + + float _currentAudioLevel = 0.0f; + float _currentMyAudioLevel = 0.0f; std::unique_ptr _audioNetworkInterface; std::unique_ptr _videoNetworkInterface; diff --git a/TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp b/TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp index 4df4b14c7..e1fd6624f 100644 --- a/TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp +++ b/TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp @@ -23,6 +23,41 @@ extern "C" { namespace tgcalls { +class TgCallsCryptStringImpl : public rtc::CryptStringImpl { +public: + TgCallsCryptStringImpl(std::string const &value) : + _value(value) { + } + + virtual ~TgCallsCryptStringImpl() override { + } + + virtual size_t GetLength() const override { + return _value.size(); + } + + virtual void CopyTo(char* dest, bool nullterminate) const override { + memcpy(dest, _value.data(), _value.size()); + if (nullterminate) { + dest[_value.size()] = 0; + } + } + virtual std::string UrlEncode() const override { + return _value; + } + virtual CryptStringImpl* Copy() const override { + return new TgCallsCryptStringImpl(_value); + } + + virtual void CopyRawTo(std::vector* dest) const override { + dest->resize(_value.size()); + memcpy(dest->data(), _value.data(), _value.size()); + } + +private: + std::string _value; +}; + class TurnCustomizerImpl : public webrtc::TurnCustomizer { public: TurnCustomizerImpl() { @@ -48,6 +83,7 @@ NetworkManager::NetworkManager( bool enableTCP, bool enableStunMarking, std::vector const &rtcServers, + std::unique_ptr proxy, std::function stateUpdated, std::function transportMessageReceived, std::function sendSignalingMessage, @@ -57,6 +93,7 @@ _enableP2P(enableP2P), _enableTCP(enableTCP), _enableStunMarking(enableStunMarking), _rtcServers(rtcServers), +_proxy(std::move(proxy)), _transport( EncryptedConnection::Type::Transport, encryptionKey, @@ -100,6 +137,16 @@ void NetworkManager::start() { flags |= cricket::PORTALLOCATOR_DISABLE_UDP; flags |= cricket::PORTALLOCATOR_DISABLE_STUN; } + + if (_proxy) { + rtc::ProxyInfo proxyInfo; + proxyInfo.type = rtc::ProxyType::PROXY_SOCKS5; + proxyInfo.address = rtc::SocketAddress(_proxy->host, _proxy->port); + proxyInfo.username = _proxy->login; + proxyInfo.password = rtc::CryptString(TgCallsCryptStringImpl(_proxy->password)); + _portAllocator->set_proxy("t/1.0", proxyInfo); + } + _portAllocator->set_flags(_portAllocator->flags() | flags); _portAllocator->Initialize(); diff --git a/TMessagesProj/jni/voip/tgcalls/NetworkManager.h b/TMessagesProj/jni/voip/tgcalls/NetworkManager.h index 7f657f0bf..53c53d28a 100644 --- a/TMessagesProj/jni/voip/tgcalls/NetworkManager.h +++ b/TMessagesProj/jni/voip/tgcalls/NetworkManager.h @@ -55,6 +55,7 @@ public: bool enableTCP, bool enableStunMarking, std::vector const &rtcServers, + std::unique_ptr proxy, std::function stateUpdated, std::function transportMessageReceived, std::function sendSignalingMessage, @@ -85,6 +86,7 @@ private: bool _enableTCP = false; bool _enableStunMarking = false; std::vector _rtcServers; + std::unique_ptr _proxy; EncryptedConnection _transport; bool _isOutgoing = false; std::function _stateUpdated; diff --git a/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceImpl.cpp b/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceImpl.cpp new file mode 100644 index 000000000..fcd5be934 --- /dev/null +++ b/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceImpl.cpp @@ -0,0 +1,2125 @@ +#include "GroupInstanceImpl.h" + +#include +#include "api/scoped_refptr.h" +#include "rtc_base/thread.h" +#include "rtc_base/logging.h" +#include "api/peer_connection_interface.h" +#include "api/task_queue/default_task_queue_factory.h" +#include "media/engine/webrtc_media_engine.h" +#include "api/audio_codecs/audio_decoder_factory_template.h" +#include "api/audio_codecs/audio_encoder_factory_template.h" +#include "api/audio_codecs/opus/audio_decoder_opus.h" +#include "api/audio_codecs/opus/audio_encoder_opus.h" +#include "api/audio_codecs/builtin_audio_encoder_factory.h" +#include "api/audio_codecs/builtin_audio_decoder_factory.h" +#include "api/rtc_event_log/rtc_event_log_factory.h" +#include "api/peer_connection_interface.h" +#include "api/video_track_source_proxy.h" +#include "system_wrappers/include/field_trial.h" +#include "api/stats/rtcstats_objects.h" +#include "modules/audio_processing/audio_buffer.h" +#include "common_audio/include/audio_util.h" +#include "common_audio/vad/include/webrtc_vad.h" +#include "modules/audio_processing/agc2/vad_with_level.h" + +#include "ThreadLocalObject.h" +#include "Manager.h" +#include "NetworkManager.h" +#include "VideoCaptureInterfaceImpl.h" +#include "platform/PlatformInterface.h" +#include "LogSinkImpl.h" + +#include +#include +#include + +namespace tgcalls { + +namespace { + +static std::vector splitSdpLines(std::string const &sdp) { + std::vector result; + + std::istringstream sdpStream(sdp); + + std::string s; + while (std::getline(sdpStream, s, '\n')) { + if (s.size() == 0) { + continue; + } + if (s[s.size() - 1] == '\r') { + s.resize(s.size() - 1); + } + result.push_back(s); + } + + return result; +} + +static std::vector splitFingerprintLines(std::string const &line) { + std::vector result; + + std::istringstream sdpStream(line); + + std::string s; + while (std::getline(sdpStream, s, ' ')) { + if (s.size() == 0) { + continue; + } + result.push_back(s); + } + + return result; +} + +static std::vector getLines(std::vector const &lines, std::string prefix) { + std::vector result; + + for (auto &line : lines) { + if (line.find(prefix) == 0) { + auto cleanLine = line; + cleanLine.replace(0, prefix.size(), ""); + result.push_back(cleanLine); + } + } + + return result; +} + +static absl::optional parseSdpIntoJoinPayload(std::string const &sdp) { + GroupJoinPayload result; + + auto lines = splitSdpLines(sdp); + + std::vector audioLines; + bool isAudioLine = false; + for (auto &line : lines) { + if (line.find("m=audio") == 0) { + isAudioLine = true; + } + if (isAudioLine) { + audioLines.push_back(line); + } + } + + /*std::vector audioSources; + for (auto &line : getLines(audioLines, "a=ssrc:")) { + std::istringstream iss(line); + uint32_t value = 0; + iss >> value; + if (std::find(audioSources.begin(), audioSources.end(), value) == audioSources.end()) { + audioSources.push_back(value); + } + } + + if (audioSources.size() != 1) { + return absl::nullopt; + } + result.ssrc = audioSources[0];*/ + result.ssrc = 0; + + auto ufragLines = getLines(lines, "a=ice-ufrag:"); + if (ufragLines.size() != 1) { + return absl::nullopt; + } + result.ufrag = ufragLines[0]; + + auto pwdLines = getLines(lines, "a=ice-pwd:"); + if (pwdLines.size() != 1) { + return absl::nullopt; + } + result.pwd = pwdLines[0]; + + for (auto &line : getLines(lines, "a=fingerprint:")) { + auto fingerprintComponents = splitFingerprintLines(line); + if (fingerprintComponents.size() != 2) { + continue; + } + + GroupJoinPayloadFingerprint fingerprint; + fingerprint.hash = fingerprintComponents[0]; + fingerprint.fingerprint = fingerprintComponents[1]; + fingerprint.setup = "active"; + result.fingerprints.push_back(fingerprint); + } + + return result; +} + +struct StreamSpec { + bool isMain = false; + uint32_t streamId = 0; + uint32_t audioSsrcOrZero = 0; + bool isRemoved = false; +}; + +static void appendSdp(std::vector &lines, std::string const &line) { + lines.push_back(line); +} + +static std::string createSdp(uint32_t sessionId, GroupJoinResponsePayload const &payload, bool isAnswer, std::vector const &bundleStreams) { + std::vector sdp; + + appendSdp(sdp, "v=0"); + + std::ostringstream sessionIdString; + sessionIdString << "o=- "; + sessionIdString << sessionId; + sessionIdString << " 2 IN IP4 0.0.0.0"; + appendSdp(sdp, sessionIdString.str()); + + appendSdp(sdp, "s=-"); + appendSdp(sdp, "t=0 0"); + + std::ostringstream bundleString; + bundleString << "a=group:BUNDLE"; + for (auto &stream : bundleStreams) { + bundleString << " "; + if (stream.isMain) { + bundleString << "0"; + } else { + bundleString << "audio"; + bundleString << stream.streamId; + } + } + appendSdp(sdp, bundleString.str()); + + appendSdp(sdp, "a=ice-lite"); + + for (auto &stream : bundleStreams) { + std::ostringstream audioMidString; + if (stream.isMain) { + audioMidString << "0"; + } else { + audioMidString << "audio"; + audioMidString << stream.streamId; + } + + std::ostringstream mLineString; + mLineString << "m=audio "; + if (stream.isMain) { + mLineString << "1"; + } else { + mLineString << "0"; + } + mLineString << " RTP/SAVPF 111 126"; + + appendSdp(sdp, mLineString.str()); + + if (stream.isMain) { + appendSdp(sdp, "c=IN IP4 0.0.0.0"); + } + + std::ostringstream mLineMidString; + mLineMidString << "a=mid:"; + mLineMidString << audioMidString.str(); + appendSdp(sdp, mLineMidString.str()); + + if (stream.isMain) { + std::ostringstream ufragString; + ufragString << "a=ice-ufrag:"; + ufragString << payload.ufrag; + appendSdp(sdp, ufragString.str()); + + std::ostringstream pwdString; + pwdString << "a=ice-pwd:"; + pwdString << payload.pwd; + appendSdp(sdp, pwdString.str()); + + for (auto &fingerprint : payload.fingerprints) { + std::ostringstream fingerprintString; + fingerprintString << "a=fingerprint:"; + fingerprintString << fingerprint.hash; + fingerprintString << " "; + fingerprintString << fingerprint.fingerprint; + appendSdp(sdp, fingerprintString.str()); + appendSdp(sdp, "a=setup:passive"); + } + + for (auto &candidate : payload.candidates) { + std::ostringstream candidateString; + candidateString << "a=candidate:"; + candidateString << candidate.foundation; + candidateString << " "; + candidateString << candidate.component; + candidateString << " "; + candidateString << candidate.protocol; + candidateString << " "; + candidateString << candidate.priority; + candidateString << " "; + candidateString << candidate.ip; + candidateString << " "; + candidateString << candidate.port; + candidateString << " "; + candidateString << "typ "; + candidateString << candidate.type; + candidateString << " "; + + if (candidate.type == "srflx" || candidate.type == "prflx" || candidate.type == "relay") { + if (candidate.relAddr.size() != 0 && candidate.relPort.size() != 0) { + candidateString << "raddr "; + candidateString << candidate.relAddr; + candidateString << " "; + candidateString << "rport "; + candidateString << candidate.relPort; + candidateString << " "; + } + } + + if (candidate.protocol == "tcp") { + if (candidate.tcpType.size() != 0) { + candidateString << "tcptype "; + candidateString << candidate.tcpType; + candidateString << " "; + } + } + + candidateString << "generation "; + candidateString << candidate.generation; + + appendSdp(sdp, candidateString.str()); + } + } + + appendSdp(sdp, "a=rtpmap:111 opus/48000/2"); + appendSdp(sdp, "a=rtpmap:126 telephone-event/8000"); + appendSdp(sdp, "a=fmtp:111 minptime=10; useinbandfec=1"); + appendSdp(sdp, "a=rtcp:1 IN IP4 0.0.0.0"); + appendSdp(sdp, "a=rtcp-mux"); + appendSdp(sdp, "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level"); + appendSdp(sdp, "a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"); + appendSdp(sdp, "a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"); + appendSdp(sdp, "a=rtcp-fb:111 transport-cc"); + + if (isAnswer && stream.isMain) { + appendSdp(sdp, "a=recvonly"); + } else { + if (stream.isMain) { + appendSdp(sdp, "a=sendrecv"); + } else { + appendSdp(sdp, "a=sendonly"); + appendSdp(sdp, "a=bundle-only"); + } + + /*std::ostringstream ssrcGroupString; + ssrcGroupString << "a=ssrc-group:FID "; + ssrcGroupString << stream.audioSsrc; + appendSdp(sdp, ssrcGroupString.str());*/ + + if (stream.isRemoved) { + appendSdp(sdp, "a=inactive"); + } else { + std::ostringstream cnameString; + cnameString << "a=ssrc:"; + cnameString << stream.audioSsrcOrZero; + cnameString << " cname:stream"; + cnameString << stream.streamId; + appendSdp(sdp, cnameString.str()); + + std::ostringstream msidString; + msidString << "a=ssrc:"; + msidString << stream.audioSsrcOrZero; + msidString << " msid:stream"; + msidString << stream.streamId; + msidString << " audio" << stream.streamId; + appendSdp(sdp, msidString.str()); + + std::ostringstream mslabelString; + mslabelString << "a=ssrc:"; + mslabelString << stream.audioSsrcOrZero; + mslabelString << " mslabel:audio"; + mslabelString << stream.streamId; + appendSdp(sdp, mslabelString.str()); + + std::ostringstream labelString; + labelString << "a=ssrc:"; + labelString << stream.audioSsrcOrZero; + labelString << " label:audio"; + labelString << stream.streamId; + appendSdp(sdp, labelString.str()); + } + } + } + + std::ostringstream result; + for (auto &line : sdp) { + result << line << "\n"; + } + + return result.str(); +} + +static std::string parseJoinResponseIntoSdp(uint32_t sessionId, uint32_t mainStreamAudioSsrc, GroupJoinResponsePayload const &payload, bool isAnswer, std::vector const &allOtherSsrcs, std::set const &activeOtherSsrcs) { + + std::vector bundleStreams; + + StreamSpec mainStream; + mainStream.isMain = true; + mainStream.streamId = 0; + mainStream.audioSsrcOrZero = mainStreamAudioSsrc; + mainStream.isRemoved = false; + bundleStreams.push_back(mainStream); + + uint32_t numStreamsToAllocate = (uint32_t)allOtherSsrcs.size(); + /*if (numStreamsToAllocate < 10) { + numStreamsToAllocate = 10; + }*/ + + for (uint32_t i = 0; i < numStreamsToAllocate; i++) { + StreamSpec stream; + stream.isMain = false; + if (i < allOtherSsrcs.size()) { + uint32_t ssrc = allOtherSsrcs[i]; + stream.audioSsrcOrZero = ssrc; + stream.isRemoved = activeOtherSsrcs.find(ssrc) == activeOtherSsrcs.end(); + stream.streamId = ssrc; + } else { + stream.audioSsrcOrZero = 0; + stream.isRemoved = true; + stream.streamId = 1 + (uint32_t)i; + } + bundleStreams.push_back(stream); + } + + return createSdp(sessionId, payload, isAnswer, bundleStreams); +} + +rtc::Thread *makeNetworkThread() { + static std::unique_ptr value = rtc::Thread::CreateWithSocketServer(); + value->SetName("WebRTC-Group-Network", nullptr); + value->Start(); + return value.get(); +} + +rtc::Thread *getNetworkThread() { + static rtc::Thread *value = makeNetworkThread(); + return value; +} + +rtc::Thread *makeWorkerThread() { + static std::unique_ptr value = rtc::Thread::Create(); + value->SetName("WebRTC-Group-Worker", nullptr); + value->Start(); + return value.get(); +} + +rtc::Thread *getWorkerThread() { + static rtc::Thread *value = makeWorkerThread(); + return value; +} + +rtc::Thread *getSignalingThread() { + return Manager::getMediaThread(); +} + +rtc::Thread *getMediaThread() { + return Manager::getMediaThread(); +} + +class FrameEncryptorImpl : public webrtc::FrameEncryptorInterface { +public: + FrameEncryptorImpl() { + } + + virtual int Encrypt(cricket::MediaType media_type, + uint32_t ssrc, + rtc::ArrayView additional_data, + rtc::ArrayView frame, + rtc::ArrayView encrypted_frame, + size_t* bytes_written) override { + memcpy(encrypted_frame.data(), frame.data(), frame.size()); + for (auto it = encrypted_frame.begin(); it != encrypted_frame.end(); it++) { + *it ^= 123; + } + *bytes_written = frame.size(); + return 0; + } + + virtual size_t GetMaxCiphertextByteSize(cricket::MediaType media_type, + size_t frame_size) override { + return frame_size; + } +}; + +class FrameDecryptorImpl : public webrtc::FrameDecryptorInterface { +public: + FrameDecryptorImpl() { + } + + virtual webrtc::FrameDecryptorInterface::Result Decrypt(cricket::MediaType media_type, + const std::vector& csrcs, + rtc::ArrayView additional_data, + rtc::ArrayView encrypted_frame, + rtc::ArrayView frame) override { + memcpy(frame.data(), encrypted_frame.data(), encrypted_frame.size()); + for (auto it = frame.begin(); it != frame.end(); it++) { + *it ^= 123; + } + return webrtc::FrameDecryptorInterface::Result(webrtc::FrameDecryptorInterface::Status::kOk, encrypted_frame.size()); + } + + virtual size_t GetMaxPlaintextByteSize(cricket::MediaType media_type, + size_t encrypted_frame_size) override { + return encrypted_frame_size; + } +}; + +class PeerConnectionObserverImpl : public webrtc::PeerConnectionObserver { +private: + std::function _discoveredIceCandidate; + std::function _connectionStateChanged; + std::function)> _onTrackAdded; + std::function)> _onTrackRemoved; + std::function _onMissingSsrc; + +public: + PeerConnectionObserverImpl( + std::function discoveredIceCandidate, + std::function connectionStateChanged, + std::function)> onTrackAdded, + std::function)> onTrackRemoved, + std::function onMissingSsrc + ) : + _discoveredIceCandidate(discoveredIceCandidate), + _connectionStateChanged(connectionStateChanged), + _onTrackAdded(onTrackAdded), + _onTrackRemoved(onTrackRemoved), + _onMissingSsrc(onMissingSsrc) { + } + + virtual void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override { + } + + virtual void OnAddStream(rtc::scoped_refptr stream) override { + } + + virtual void OnRemoveStream(rtc::scoped_refptr stream) override { + } + + virtual void OnDataChannel(rtc::scoped_refptr data_channel) override { + } + + virtual void OnRenegotiationNeeded() override { + } + + virtual void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override { + bool isConnected = false; + switch (new_state) { + case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionConnected: + case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionCompleted: + isConnected = true; + break; + default: + break; + } + _connectionStateChanged(isConnected); + } + + virtual void OnStandardizedIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override { + } + + virtual void OnConnectionChange(webrtc::PeerConnectionInterface::PeerConnectionState new_state) override { + } + + virtual void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override { + } + + virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override { + std::string sdp; + candidate->ToString(&sdp); + _discoveredIceCandidate(sdp, candidate->sdp_mline_index(), candidate->sdp_mid()); + } + + virtual void OnIceCandidateError(const std::string& host_candidate, const std::string& url, int error_code, const std::string& error_text) override { + } + + virtual void OnIceCandidateError(const std::string& address, + int port, + const std::string& url, + int error_code, + const std::string& error_text) override { + } + + virtual void OnIceCandidatesRemoved(const std::vector& candidates) override { + } + + virtual void OnIceConnectionReceivingChange(bool receiving) override { + } + + virtual void OnIceSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent& event) override { + } + + virtual void OnAddTrack(rtc::scoped_refptr receiver, const std::vector>& streams) override { + } + + virtual void OnTrack(rtc::scoped_refptr transceiver) override { + /*if (transceiver->receiver()) { + rtc::scoped_refptr decryptor(new rtc::RefCountedObject()); + transceiver->receiver()->SetFrameDecryptor(decryptor); + }*/ + + _onTrackAdded(transceiver); + } + + virtual void OnRemoveTrack(rtc::scoped_refptr receiver) override { + _onTrackRemoved(receiver); + } + + virtual void OnInterestingUsage(int usage_pattern) override { + } + + virtual void OnErrorDemuxingPacket(uint32_t ssrc) override { + _onMissingSsrc(ssrc); + } +}; + +class RTCStatsCollectorCallbackImpl : public webrtc::RTCStatsCollectorCallback { +public: + RTCStatsCollectorCallbackImpl(std::function &)> completion) : + _completion(completion) { + } + + virtual void OnStatsDelivered(const rtc::scoped_refptr &report) override { + _completion(report); + } + +private: + std::function &)> _completion; +}; + +static const int kVadResultHistoryLength = 8; + +class CombinedVad { +private: + webrtc::VadLevelAnalyzer _vadWithLevel; + float _vadResultHistory[kVadResultHistoryLength]; + +public: + CombinedVad() { + for (int i = 0; i < kVadResultHistoryLength; i++) { + _vadResultHistory[i] = 0.0f; + } + } + + ~CombinedVad() { + } + + bool update(webrtc::AudioBuffer *buffer) { + webrtc::AudioFrameView frameView(buffer->channels(), buffer->num_channels(), buffer->num_frames()); + auto result = _vadWithLevel.AnalyzeFrame(frameView); + for (int i = 1; i < kVadResultHistoryLength; i++) { + _vadResultHistory[i - 1] = _vadResultHistory[i]; + } + _vadResultHistory[kVadResultHistoryLength - 1] = result.speech_probability; + + float movingAverage = 0.0f; + for (int i = 0; i < kVadResultHistoryLength; i++) { + movingAverage += _vadResultHistory[i]; + } + movingAverage /= (float)kVadResultHistoryLength; + + bool vadResult = false; + if (movingAverage > 0.8f) { + vadResult = true; + } + + return vadResult; + } +}; + +class AudioTrackSinkInterfaceImpl: public webrtc::AudioTrackSinkInterface { +private: + std::function _update; + + int _peakCount = 0; + uint16_t _peak = 0; + + CombinedVad _vad; + +public: + AudioTrackSinkInterfaceImpl(std::function update) : + _update(update) { + } + + virtual ~AudioTrackSinkInterfaceImpl() { + } + + virtual void OnData(const void *audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels, size_t number_of_frames) override { + if (bits_per_sample == 16 && number_of_channels == 1) { + int16_t *samples = (int16_t *)audio_data; + int numberOfSamplesInFrame = (int)number_of_frames; + + webrtc::AudioBuffer buffer(sample_rate, 1, 48000, 1, 48000, 1); + webrtc::StreamConfig config(sample_rate, 1); + buffer.CopyFrom(samples, config); + + bool vadResult = _vad.update(&buffer); + + for (int i = 0; i < numberOfSamplesInFrame; i++) { + int16_t sample = samples[i]; + if (sample < 0) { + sample = -sample; + } + if (_peak < sample) { + _peak = sample; + } + _peakCount += 1; + } + + if (_peakCount >= 1200) { + float level = ((float)(_peak)) / 4000.0f; + _peak = 0; + _peakCount = 0; + _update(level, vadResult); + } + } + } +}; + +class CreateSessionDescriptionObserverImpl : public webrtc::CreateSessionDescriptionObserver { +private: + std::function _completion; + +public: + CreateSessionDescriptionObserverImpl(std::function completion) : + _completion(completion) { + } + + virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { + if (desc) { + std::string sdp; + desc->ToString(&sdp); + + _completion(sdp, desc->type()); + } + } + + virtual void OnFailure(webrtc::RTCError error) override { + } +}; + +class SetSessionDescriptionObserverImpl : public webrtc::SetSessionDescriptionObserver { +private: + std::function _completion; + std::function _error; + +public: + SetSessionDescriptionObserverImpl(std::function completion, std::function error) : + _completion(completion), _error(error) { + } + + virtual void OnSuccess() override { + _completion(); + } + + virtual void OnFailure(webrtc::RTCError error) override { + _error(error); + } +}; + +class AudioCaptureAnalyzer : public webrtc::CustomAudioAnalyzer { +private: + void Initialize(int sample_rate_hz, int num_channels) override { + + } + // Analyzes the given capture or render signal. + void Analyze(const webrtc::AudioBuffer* audio) override { + _analyze(audio); + } + // Returns a string representation of the module state. + std::string ToString() const override { + return "analyzing"; + } + + std::function _analyze; + +public: + AudioCaptureAnalyzer(std::function analyze) : + _analyze(analyze) { + } + + virtual ~AudioCaptureAnalyzer() = default; +}; + +class WrappedAudioDeviceModule : public webrtc::AudioDeviceModule { +private: + rtc::scoped_refptr _impl; + +public: + WrappedAudioDeviceModule(rtc::scoped_refptr impl) : + _impl(impl) { + } + + virtual ~WrappedAudioDeviceModule() { + } + + virtual int32_t ActiveAudioLayer(AudioLayer *audioLayer) const override { + return _impl->ActiveAudioLayer(audioLayer); + } + + virtual int32_t RegisterAudioCallback(webrtc::AudioTransport *audioCallback) override { + return _impl->RegisterAudioCallback(audioCallback); + } + + virtual int32_t Init() override { + return _impl->Init(); + } + + virtual int32_t Terminate() override { + return _impl->Terminate(); + } + + virtual bool Initialized() const override { + return _impl->Initialized(); + } + + virtual int16_t PlayoutDevices() override { + return _impl->PlayoutDevices(); + } + + virtual int16_t RecordingDevices() override { + return _impl->RecordingDevices(); + } + + virtual int32_t PlayoutDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], char guid[webrtc::kAdmMaxGuidSize]) override { + return _impl->PlayoutDeviceName(index, name, guid); + } + + virtual int32_t RecordingDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], char guid[webrtc::kAdmMaxGuidSize]) override { + return _impl->RecordingDeviceName(index, name, guid); + } + + virtual int32_t SetPlayoutDevice(uint16_t index) override { + return _impl->SetPlayoutDevice(index); + } + + virtual int32_t SetPlayoutDevice(WindowsDeviceType device) override { + return _impl->SetPlayoutDevice(device); + } + + virtual int32_t SetRecordingDevice(uint16_t index) override { + return _impl->SetRecordingDevice(index); + } + + virtual int32_t SetRecordingDevice(WindowsDeviceType device) override { + return _impl->SetRecordingDevice(device); + } + + virtual int32_t PlayoutIsAvailable(bool *available) override { + return _impl->PlayoutIsAvailable(available); + } + + virtual int32_t InitPlayout() override { + return _impl->InitPlayout(); + } + + virtual bool PlayoutIsInitialized() const override { + return _impl->PlayoutIsInitialized(); + } + + virtual int32_t RecordingIsAvailable(bool *available) override { + return _impl->RecordingIsAvailable(available); + } + + virtual int32_t InitRecording() override { + return _impl->InitRecording(); + } + + virtual bool RecordingIsInitialized() const override { + return _impl->RecordingIsInitialized(); + } + + virtual int32_t StartPlayout() override { + return _impl->StartPlayout(); + } + + virtual int32_t StopPlayout() override { + return _impl->StopPlayout(); + } + + virtual bool Playing() const override { + return _impl->Playing(); + } + + virtual int32_t StartRecording() override { + return _impl->StartRecording(); + } + + virtual int32_t StopRecording() override { + return _impl->StopRecording(); + } + + virtual bool Recording() const override { + return _impl->Recording(); + } + + virtual int32_t InitSpeaker() override { + return _impl->InitSpeaker(); + } + + virtual bool SpeakerIsInitialized() const override { + return _impl->SpeakerIsInitialized(); + } + + virtual int32_t InitMicrophone() override { + return _impl->InitMicrophone(); + } + + virtual bool MicrophoneIsInitialized() const override { + return _impl->MicrophoneIsInitialized(); + } + + virtual int32_t SpeakerVolumeIsAvailable(bool *available) override { + return _impl->SpeakerVolumeIsAvailable(available); + } + + virtual int32_t SetSpeakerVolume(uint32_t volume) override { + return _impl->SetSpeakerVolume(volume); + } + + virtual int32_t SpeakerVolume(uint32_t* volume) const override { + return _impl->SpeakerVolume(volume); + } + + virtual int32_t MaxSpeakerVolume(uint32_t *maxVolume) const override { + return _impl->MaxSpeakerVolume(maxVolume); + } + + virtual int32_t MinSpeakerVolume(uint32_t *minVolume) const override { + return _impl->MinSpeakerVolume(minVolume); + } + + virtual int32_t MicrophoneVolumeIsAvailable(bool *available) override { + return _impl->MicrophoneVolumeIsAvailable(available); + } + + virtual int32_t SetMicrophoneVolume(uint32_t volume) override { + return _impl->SetMicrophoneVolume(volume); + } + + virtual int32_t MicrophoneVolume(uint32_t *volume) const override { + return _impl->MicrophoneVolume(volume); + } + + virtual int32_t MaxMicrophoneVolume(uint32_t *maxVolume) const override { + return _impl->MaxMicrophoneVolume(maxVolume); + } + + virtual int32_t MinMicrophoneVolume(uint32_t *minVolume) const override { + return _impl->MinMicrophoneVolume(minVolume); + } + + virtual int32_t SpeakerMuteIsAvailable(bool *available) override { + return _impl->SpeakerMuteIsAvailable(available); + } + + virtual int32_t SetSpeakerMute(bool enable) override { + return _impl->SetSpeakerMute(enable); + } + + virtual int32_t SpeakerMute(bool *enabled) const override { + return _impl->SpeakerMute(enabled); + } + + virtual int32_t MicrophoneMuteIsAvailable(bool *available) override { + return _impl->MicrophoneMuteIsAvailable(available); + } + + virtual int32_t SetMicrophoneMute(bool enable) override { + return _impl->SetMicrophoneMute(enable); + } + + virtual int32_t MicrophoneMute(bool *enabled) const override { + return _impl->MicrophoneMute(enabled); + } + + virtual int32_t StereoPlayoutIsAvailable(bool *available) const override { + return _impl->StereoPlayoutIsAvailable(available); + } + + virtual int32_t SetStereoPlayout(bool enable) override { + return _impl->SetStereoPlayout(enable); + } + + virtual int32_t StereoPlayout(bool *enabled) const override { + return _impl->StereoPlayout(enabled); + } + + virtual int32_t StereoRecordingIsAvailable(bool *available) const override { + return _impl->StereoRecordingIsAvailable(available); + } + + virtual int32_t SetStereoRecording(bool enable) override { + return _impl->SetStereoRecording(enable); + } + + virtual int32_t StereoRecording(bool *enabled) const override { + return _impl->StereoRecording(enabled); + } + + virtual int32_t PlayoutDelay(uint16_t* delayMS) const override { + return _impl->PlayoutDelay(delayMS); + } + + virtual bool BuiltInAECIsAvailable() const override { + return _impl->BuiltInAECIsAvailable(); + } + + virtual bool BuiltInAGCIsAvailable() const override { + return _impl->BuiltInAGCIsAvailable(); + } + + virtual bool BuiltInNSIsAvailable() const override { + return _impl->BuiltInNSIsAvailable(); + } + + virtual int32_t EnableBuiltInAEC(bool enable) override { + return _impl->EnableBuiltInAEC(enable); + } + + virtual int32_t EnableBuiltInAGC(bool enable) override { + return _impl->EnableBuiltInAGC(enable); + } + + virtual int32_t EnableBuiltInNS(bool enable) override { + return _impl->EnableBuiltInNS(enable); + } + + virtual int32_t GetPlayoutUnderrunCount() const override { + return _impl->GetPlayoutUnderrunCount(); + } + +#if defined(WEBRTC_IOS) + virtual int GetPlayoutAudioParameters(webrtc::AudioParameters *params) const override { + return _impl->GetPlayoutAudioParameters(params); + } + virtual int GetRecordAudioParameters(webrtc::AudioParameters *params) const override { + return _impl->GetRecordAudioParameters(params); + } +#endif // WEBRTC_IOS +}; + +template +void split(const std::string &s, char delim, Out result) { + std::istringstream iss(s); + std::string item; + while (std::getline(iss, item, delim)) { + *result++ = item; + } +} + +std::vector split(const std::string &s, char delim) { + std::vector elems; + split(s, delim, std::back_inserter(elems)); + return elems; +} + +std::string adjustLocalDescription(const std::string &sdp) { + std::vector lines = split(sdp, '\n'); + + std::string pattern = "c=IN "; + + bool foundAudio = false; + std::stringstream result; + for (const auto &it : lines) { + result << it << "\n"; + if (!foundAudio && it.compare(0, pattern.size(), pattern) == 0) { + foundAudio = true; + result << "b=AS:" << 32 << "\n"; + } + } + + return result.str(); +} + +} // namespace + + + +class GroupInstanceManager : public std::enable_shared_from_this { +public: + GroupInstanceManager(GroupInstanceDescriptor &&descriptor) : + _networkStateUpdated(descriptor.networkStateUpdated), + _audioLevelsUpdated(descriptor.audioLevelsUpdated), + _initialInputDeviceId(descriptor.initialInputDeviceId), + _initialOutputDeviceId(descriptor.initialOutputDeviceId), + _platformContext(descriptor.platformContext) { + auto generator = std::mt19937(std::random_device()()); + auto distribution = std::uniform_int_distribution(); + do { + _mainStreamAudioSsrc = distribution(generator); + } while (!_mainStreamAudioSsrc); + } + + ~GroupInstanceManager() { + assert(getMediaThread()->IsCurrent()); + + destroyAudioDeviceModule(); + if (_peerConnection) { + _peerConnection->Close(); + } + } + + void generateAndInsertFakeIncomingSsrc() { + // At least on Windows recording can't be started without playout. + // We keep a fake incoming stream, so that playout is always started. + auto generator = std::mt19937(std::random_device()()); + auto distribution = std::uniform_int_distribution(); + while (true) { + _fakeIncomingSsrc = distribution(generator); + if (_fakeIncomingSsrc != 0 + && _fakeIncomingSsrc != _mainStreamAudioSsrc + && std::find(_allOtherSsrcs.begin(), _allOtherSsrcs.end(), _fakeIncomingSsrc) == _allOtherSsrcs.end()) { + break; + } + } + _activeOtherSsrcs.emplace(_fakeIncomingSsrc); + _allOtherSsrcs.emplace_back(_fakeIncomingSsrc); + } + + bool createAudioDeviceModule( + const webrtc::PeerConnectionFactoryDependencies &dependencies) { + _adm_thread = dependencies.worker_thread; + if (!_adm_thread) { + return false; + } + _adm_thread->Invoke(RTC_FROM_HERE, [&] { + const auto check = [&](webrtc::AudioDeviceModule::AudioLayer layer) { + auto result = webrtc::AudioDeviceModule::Create( + layer, + dependencies.task_queue_factory.get()); + return (result && (result->Init() == 0)) ? result : nullptr; + }; + if (auto result = check(webrtc::AudioDeviceModule::kPlatformDefaultAudio)) { + _adm_use_withAudioDeviceModule = new rtc::RefCountedObject(result); +#ifdef WEBRTC_LINUX + } else if (auto result = check(webrtc::AudioDeviceModule::kLinuxAlsaAudio)) { + _adm_use_withAudioDeviceModule = new rtc::RefCountedObject(result); +#endif // WEBRTC_LINUX + } + }); + return (_adm_use_withAudioDeviceModule != nullptr); + } + void destroyAudioDeviceModule() { + if (!_adm_thread) { + return; + } + _adm_thread->Invoke(RTC_FROM_HERE, [&] { + _adm_use_withAudioDeviceModule = nullptr; + }); + } + + void start() { + const auto weak = std::weak_ptr(shared_from_this()); + + webrtc::field_trial::InitFieldTrialsFromString( + //"WebRTC-Audio-SendSideBwe/Enabled/" + "WebRTC-Audio-Allocation/min:6kbps,max:32kbps/" + "WebRTC-Audio-OpusMinPacketLossRate/Enabled-1/" + //"WebRTC-FlexFEC-03/Enabled/" + //"WebRTC-FlexFEC-03-Advertised/Enabled/" + "WebRTC-PcFactoryDefaultBitrates/min:6kbps,start:32kbps,max:32kbps/" + ); + + PlatformInterface::SharedInstance()->configurePlatformAudio(); + + webrtc::PeerConnectionFactoryDependencies dependencies; + dependencies.network_thread = getNetworkThread(); + dependencies.worker_thread = getWorkerThread(); + dependencies.signaling_thread = getSignalingThread(); + dependencies.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory(); + + if (!createAudioDeviceModule(dependencies)) { + return; + } + + cricket::MediaEngineDependencies mediaDeps; + mediaDeps.task_queue_factory = dependencies.task_queue_factory.get(); + mediaDeps.audio_encoder_factory = webrtc::CreateAudioEncoderFactory(); + mediaDeps.audio_decoder_factory = webrtc::CreateAudioDecoderFactory(); + mediaDeps.video_encoder_factory = PlatformInterface::SharedInstance()->makeVideoEncoderFactory(_platformContext); + mediaDeps.video_decoder_factory = PlatformInterface::SharedInstance()->makeVideoDecoderFactory(_platformContext); + mediaDeps.adm = _adm_use_withAudioDeviceModule; + + std::shared_ptr myVad(new CombinedVad()); + + auto analyzer = new AudioCaptureAnalyzer([&, weak, myVad](const webrtc::AudioBuffer* buffer) { + if (!buffer) { + return; + } + if (buffer->num_channels() != 1) { + return; + } + + float peak = 0; + int peakCount = 0; + const float *samples = buffer->channels_const()[0]; + for (int i = 0; i < buffer->num_frames(); i++) { + float sample = samples[i]; + if (sample < 0) { + sample = -sample; + } + if (peak < sample) { + peak = sample; + } + peakCount += 1; + } + + bool vadStatus = myVad->update((webrtc::AudioBuffer *)buffer); + + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, peak, peakCount, vadStatus](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + + strong->_myAudioLevelPeakCount += peakCount; + if (strong->_myAudioLevelPeak < peak) { + strong->_myAudioLevelPeak = peak; + } + if (strong->_myAudioLevelPeakCount >= 1200) { + float level = strong->_myAudioLevelPeak / 4000.0f; + if (strong->_isMuted) { + level = 0.0f; + } + strong->_myAudioLevelPeak = 0; + strong->_myAudioLevelPeakCount = 0; + strong->_myAudioLevel = GroupLevelValue{ + level, + vadStatus, + }; + } + }); + }); + + webrtc::AudioProcessingBuilder builder; + builder.SetCaptureAnalyzer(std::unique_ptr(analyzer)); + webrtc::AudioProcessing *apm = builder.Create(); + + webrtc::AudioProcessing::Config audioConfig; + webrtc::AudioProcessing::Config::NoiseSuppression noiseSuppression; + noiseSuppression.enabled = true; + noiseSuppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kHigh; + audioConfig.noise_suppression = noiseSuppression; + + audioConfig.high_pass_filter.enabled = true; + + audioConfig.voice_detection.enabled = true; + + apm->ApplyConfig(audioConfig); + + mediaDeps.audio_processing = apm; + + mediaDeps.onUnknownAudioSsrc = [weak](uint32_t ssrc) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, ssrc](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + strong->onMissingSsrc(ssrc); + }); + }; + + dependencies.media_engine = cricket::CreateMediaEngine(std::move(mediaDeps)); + dependencies.call_factory = webrtc::CreateCallFactory(); + dependencies.event_log_factory = + std::make_unique(dependencies.task_queue_factory.get()); + dependencies.network_controller_factory = nullptr; + + _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies)); + + webrtc::PeerConnectionInterface::RTCConfiguration config; + config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; + //config.continual_gathering_policy = webrtc::PeerConnectionInterface::ContinualGatheringPolicy::GATHER_CONTINUALLY; + config.audio_jitter_buffer_fast_accelerate = true; + config.prioritize_most_likely_ice_candidate_pairs = true; + config.presume_writable_when_fully_relayed = true; + //config.audio_jitter_buffer_enable_rtx_handling = true; + + /*webrtc::CryptoOptions cryptoOptions; + webrtc::CryptoOptions::SFrame sframe; + sframe.require_frame_encryption = true; + cryptoOptions.sframe = sframe; + config.crypto_options = cryptoOptions;*/ + + _observer.reset(new PeerConnectionObserverImpl( + [weak](std::string sdp, int mid, std::string sdpMid) { + /*getMediaThread()->PostTask(RTC_FROM_HERE, [weak, sdp, mid, sdpMid](){ + auto strong = weak.lock(); + if (strong) { + //strong->emitIceCandidate(sdp, mid, sdpMid); + } + });*/ + }, + [weak](bool isConnected) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, isConnected](){ + auto strong = weak.lock(); + if (strong) { + strong->updateIsConnected(isConnected); + } + }); + }, + [weak](rtc::scoped_refptr transceiver) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, transceiver](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + strong->onTrackAdded(transceiver); + }); + }, + [weak](rtc::scoped_refptr receiver) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, receiver](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + strong->onTrackRemoved(receiver); + }); + }, + [weak](uint32_t ssrc) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, ssrc](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + strong->onMissingSsrc(ssrc); + }); + } + )); + _peerConnection = _nativeFactory->CreatePeerConnection(config, nullptr, nullptr, _observer.get()); + assert(_peerConnection != nullptr); + + cricket::AudioOptions options; + rtc::scoped_refptr audioSource = _nativeFactory->CreateAudioSource(options); + std::stringstream name; + name << "audio"; + name << 0; + std::vector streamIds; + streamIds.push_back(name.str()); + _localAudioTrack = _nativeFactory->CreateAudioTrack(name.str(), audioSource); + _localAudioTrack->set_enabled(false); + auto addedTrack = _peerConnection->AddTrack(_localAudioTrack, streamIds); + + if (addedTrack.ok()) { + _localAudioTrackSender = addedTrack.value(); + for (auto &it : _peerConnection->GetTransceivers()) { + if (it->media_type() == cricket::MediaType::MEDIA_TYPE_AUDIO) { + if (_localAudioTrackSender.get() == it->sender().get()) { + it->SetDirection(webrtc::RtpTransceiverDirection::kRecvOnly); + } + + break; + } + } + } + + setAudioInputDevice(_initialInputDeviceId); + setAudioOutputDevice(_initialOutputDeviceId); + + // At least on Windows recording doesn't work without started playout. + withAudioDeviceModule([weak](webrtc::AudioDeviceModule *adm) { +#ifdef WEBRTC_WIN + // At least on Windows starting/stopping playout while recording + // is active leads to errors in recording and assertion violation. + adm->EnableBuiltInAEC(false); +#endif // WEBRTC_WIN + + if (adm->InitPlayout()) { + adm->StartPlayout(); + } else { + getMediaThread()->PostDelayedTask(RTC_FROM_HERE, [weak](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + strong->withAudioDeviceModule([](webrtc::AudioDeviceModule *adm) { + if (adm->InitPlayout()) { + adm->StartPlayout(); + } + }); + }, 2000); + } + }); + + //beginStatsTimer(100); + beginLevelsTimer(50); + } + + + void setAudioInputDevice(std::string id) { +#if !defined(WEBRTC_IOS) && !defined(WEBRTC_ANDROID) + withAudioDeviceModule([&](webrtc::AudioDeviceModule *adm) { + const auto recording = adm->Recording(); + if (recording) { + adm->StopRecording(); + } + const auto finish = [&] { + if (recording) { + adm->InitRecording(); + adm->StartRecording(); + } + }; + if (id == "default" || id.empty()) { + if (const auto result = adm->SetRecordingDevice(webrtc::AudioDeviceModule::kDefaultCommunicationDevice)) { + RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << "): SetRecordingDevice(kDefaultCommunicationDevice) failed: " << result << "."; + } else { + RTC_LOG(LS_INFO) << "setAudioInputDevice(" << id << "): SetRecordingDevice(kDefaultCommunicationDevice) success."; + } + return finish(); + } + const auto count = adm + ? adm->RecordingDevices() + : int16_t(-666); + if (count <= 0) { + RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << "): Could not get recording devices count: " << count << "."; + return finish(); + } + for (auto i = 0; i != count; ++i) { + char name[webrtc::kAdmMaxDeviceNameSize + 1] = { 0 }; + char guid[webrtc::kAdmMaxGuidSize + 1] = { 0 }; + adm->RecordingDeviceName(i, name, guid); + if (id == guid) { + const auto result = adm->SetRecordingDevice(i); + if (result != 0) { + RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << ") name '" << std::string(name) << "' failed: " << result << "."; + } else { + RTC_LOG(LS_INFO) << "setAudioInputDevice(" << id << ") name '" << std::string(name) << "' success."; + } + return finish(); + } + } + RTC_LOG(LS_ERROR) << "setAudioInputDevice(" << id << "): Could not find recording device."; + return finish(); + }); +#endif + } + + void setAudioOutputDevice(std::string id) { +#if !defined(WEBRTC_IOS) && !defined(WEBRTC_ANDROID) + withAudioDeviceModule([&](webrtc::AudioDeviceModule *adm) { + const auto playing = adm->Playing(); + if (playing) { + adm->StopPlayout(); + } + const auto finish = [&] { + if (playing) { + adm->InitPlayout(); + adm->StartPlayout(); + } + }; + if (id == "default" || id.empty()) { + if (const auto result = adm->SetPlayoutDevice(webrtc::AudioDeviceModule::kDefaultCommunicationDevice)) { + RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << "): SetPlayoutDevice(kDefaultCommunicationDevice) failed: " << result << "."; + } else { + RTC_LOG(LS_INFO) << "setAudioOutputDevice(" << id << "): SetPlayoutDevice(kDefaultCommunicationDevice) success."; + } + return finish(); + } + const auto count = adm + ? adm->PlayoutDevices() + : int16_t(-666); + if (count <= 0) { + RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << "): Could not get playout devices count: " << count << "."; + return finish(); + } + for (auto i = 0; i != count; ++i) { + char name[webrtc::kAdmMaxDeviceNameSize + 1] = { 0 }; + char guid[webrtc::kAdmMaxGuidSize + 1] = { 0 }; + adm->PlayoutDeviceName(i, name, guid); + if (id == guid) { + const auto result = adm->SetPlayoutDevice(i); + if (result != 0) { + RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << ") name '" << std::string(name) << "' failed: " << result << "."; + } else { + RTC_LOG(LS_INFO) << "setAudioOutputDevice(" << id << ") name '" << std::string(name) << "' success."; + } + return finish(); + } + } + RTC_LOG(LS_ERROR) << "setAudioOutputDevice(" << id << "): Could not find playout device."; + return finish(); + }); +#endif + } + + void updateIsConnected(bool isConnected) { + _isConnected = isConnected; + + auto timestamp = rtc::TimeMillis(); + + _isConnectedUpdateValidTaskId++; + + if (!isConnected && _appliedOfferTimestamp > timestamp - 1000) { + auto taskId = _isConnectedUpdateValidTaskId; + const auto weak = std::weak_ptr(shared_from_this()); + getMediaThread()->PostDelayedTask(RTC_FROM_HERE, [weak, taskId]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + if (strong->_isConnectedUpdateValidTaskId == taskId) { + strong->_networkStateUpdated(strong->_isConnected); + } + }, 1000); + } else { + _networkStateUpdated(_isConnected); + } + } + + void stop() { + _peerConnection->Close(); + } + + void emitJoinPayload(std::function completion) { + const auto weak = std::weak_ptr(shared_from_this()); + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; + rtc::scoped_refptr observer(new rtc::RefCountedObject([weak, completion](std::string sdp, std::string type) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, sdp, type, completion](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + + auto lines = splitSdpLines(sdp); + std::vector resultSdp; + + std::ostringstream generatedSsrcStringStream; + generatedSsrcStringStream << strong->_mainStreamAudioSsrc; + auto generatedSsrcString = generatedSsrcStringStream.str(); + + for (auto &line : lines) { + auto adjustedLine = line; + if (adjustedLine.find("a=ssrc:") == 0) { + int startIndex = 7; + int i = startIndex; + while (i < adjustedLine.size()) { + if (!isdigit(adjustedLine[i])) { + break; + } + i++; + } + if (i >= startIndex) { + adjustedLine.replace(startIndex, i - startIndex, generatedSsrcString); + } + } + appendSdp(resultSdp, adjustedLine); + } + + std::ostringstream result; + for (auto &line : resultSdp) { + result << line << "\n"; + } + + auto adjustedSdp = result.str(); + + RTC_LOG(LoggingSeverity::WARNING) << "----- setLocalDescription join -----"; + RTC_LOG(LoggingSeverity::WARNING) << adjustedSdp; + RTC_LOG(LoggingSeverity::WARNING) << "-----"; + + webrtc::SdpParseError error; + webrtc::SessionDescriptionInterface *sessionDescription = webrtc::CreateSessionDescription(type, adjustLocalDescription(adjustedSdp), &error); + if (sessionDescription != nullptr) { + rtc::scoped_refptr observer(new rtc::RefCountedObject([weak, adjustedSdp, completion]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + auto payload = parseSdpIntoJoinPayload(adjustedSdp); + if (payload) { + payload->ssrc = strong->_mainStreamAudioSsrc; + completion(payload.value()); + } + }, [](webrtc::RTCError error) { + })); + strong->_peerConnection->SetLocalDescription(observer, sessionDescription); + } else { + return; + } + }); + })); + _peerConnection->CreateOffer(observer, options); + } + + void setJoinResponsePayload(GroupJoinResponsePayload payload) { + _joinPayload = payload; + auto sdp = parseJoinResponseIntoSdp(_sessionId, _mainStreamAudioSsrc, payload, true, _allOtherSsrcs, _activeOtherSsrcs); + setOfferSdp(sdp, true, true, false); + } + + void removeSsrcs(std::vector ssrcs) { + if (!_joinPayload) { + return; + } + + bool updated = false; + for (auto ssrc : ssrcs) { + if (std::find(_allOtherSsrcs.begin(), _allOtherSsrcs.end(), ssrc) != _allOtherSsrcs.end() && std::find(_activeOtherSsrcs.begin(), _activeOtherSsrcs.end(), ssrc) != _activeOtherSsrcs.end()) { + if (!_fakeIncomingSsrc || ssrc == _fakeIncomingSsrc) { + generateAndInsertFakeIncomingSsrc(); + } + _activeOtherSsrcs.erase(ssrc); + updated = true; + } + } + + if (updated) { + auto sdp = parseJoinResponseIntoSdp(_sessionId, _mainStreamAudioSsrc, _joinPayload.value(), false, _allOtherSsrcs, _activeOtherSsrcs); + setOfferSdp(sdp, false, false, false); + } + } + + void addSsrcsInternal(std::vector const &ssrcs, bool completeMissingSsrcSetup) { + if (!_joinPayload) { + if (completeMissingSsrcSetup) { + completeProcessingMissingSsrcs(); + } + return; + } + + for (auto ssrc : ssrcs) { + if (std::find(_allOtherSsrcs.begin(), _allOtherSsrcs.end(), ssrc) == _allOtherSsrcs.end()) { + _allOtherSsrcs.push_back(ssrc); + _activeOtherSsrcs.insert(ssrc); + } + } + + auto sdp = parseJoinResponseIntoSdp(_sessionId, _mainStreamAudioSsrc, _joinPayload.value(), false, _allOtherSsrcs, _activeOtherSsrcs); + setOfferSdp(sdp, false, false, completeMissingSsrcSetup); + } + + void applyLocalSdp() { + const auto weak = std::weak_ptr(shared_from_this()); + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; + rtc::scoped_refptr observer(new rtc::RefCountedObject([weak](std::string sdp, std::string type) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, sdp, type](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + + auto lines = splitSdpLines(sdp); + std::vector resultSdp; + + std::ostringstream generatedSsrcStringStream; + generatedSsrcStringStream << strong->_mainStreamAudioSsrc; + auto generatedSsrcString = generatedSsrcStringStream.str(); + + for (auto &line : lines) { + auto adjustedLine = line; + if (adjustedLine.find("a=ssrc:") == 0) { + int startIndex = 7; + int i = startIndex; + while (i < adjustedLine.size()) { + if (!isdigit(adjustedLine[i])) { + break; + } + i++; + } + if (i >= startIndex) { + adjustedLine.replace(startIndex, i - startIndex, generatedSsrcString); + } + } + appendSdp(resultSdp, adjustedLine); + } + + std::ostringstream result; + for (auto &line : resultSdp) { + result << line << "\n"; + } + + auto adjustedSdp = result.str(); + + RTC_LOG(LoggingSeverity::WARNING) << "----- setLocalDescription applyLocalSdp -----"; + RTC_LOG(LoggingSeverity::WARNING) << adjustedSdp; + RTC_LOG(LoggingSeverity::WARNING) << "-----"; + + webrtc::SdpParseError error; + webrtc::SessionDescriptionInterface *sessionDescription = webrtc::CreateSessionDescription(type, adjustLocalDescription(adjustedSdp), &error); + if (sessionDescription != nullptr) { + rtc::scoped_refptr observer(new rtc::RefCountedObject([weak, adjustedSdp]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + + if (!strong->_joinPayload) { + return; + } + + auto sdp = parseJoinResponseIntoSdp(strong->_sessionId, strong->_mainStreamAudioSsrc, strong->_joinPayload.value(), true, strong->_allOtherSsrcs, strong->_activeOtherSsrcs); + strong->setOfferSdp(sdp, false, true, false); + }, [](webrtc::RTCError error) { + })); + strong->_peerConnection->SetLocalDescription(observer, sessionDescription); + } else { + return; + } + }); + })); + _peerConnection->CreateOffer(observer, options); + } + + void setOfferSdp(std::string const &offerSdp, bool isInitialJoinAnswer, bool isAnswer, bool completeMissingSsrcSetup) { + if (!isAnswer && _appliedRemoteRescription == offerSdp) { + if (completeMissingSsrcSetup) { + completeProcessingMissingSsrcs(); + } + return; + } + _appliedRemoteRescription = offerSdp; + + RTC_LOG(LoggingSeverity::WARNING) << "----- setOfferSdp " << (isAnswer ? "answer" : "offer") << " -----"; + RTC_LOG(LoggingSeverity::WARNING) << offerSdp; + RTC_LOG(LoggingSeverity::WARNING) << "-----"; + + webrtc::SdpParseError error; + webrtc::SessionDescriptionInterface *sessionDescription = webrtc::CreateSessionDescription(isAnswer ? "answer" : "offer", adjustLocalDescription(offerSdp), &error); + if (!sessionDescription) { + if (completeMissingSsrcSetup) { + completeProcessingMissingSsrcs(); + } + return; + } + + if (!isAnswer) { + _appliedOfferTimestamp = rtc::TimeMillis(); + } + + const auto weak = std::weak_ptr(shared_from_this()); + rtc::scoped_refptr observer(new rtc::RefCountedObject([weak, isInitialJoinAnswer, isAnswer, completeMissingSsrcSetup]() { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, isInitialJoinAnswer, isAnswer, completeMissingSsrcSetup](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + if (!isAnswer) { + strong->emitAnswer(completeMissingSsrcSetup); + } else { + if (isInitialJoinAnswer) { + strong->completedInitialSetup(); + } + + if (completeMissingSsrcSetup) { + strong->completeProcessingMissingSsrcs(); + } + } + }); + }, [weak, completeMissingSsrcSetup](webrtc::RTCError error) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, completeMissingSsrcSetup](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + if (completeMissingSsrcSetup) { + strong->completeProcessingMissingSsrcs(); + } + }); + })); + + _peerConnection->SetRemoteDescription(observer, sessionDescription); + } + + void beginStatsTimer(int timeoutMs) { + const auto weak = std::weak_ptr(shared_from_this()); + getMediaThread()->PostDelayedTask(RTC_FROM_HERE, [weak]() { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + strong->collectStats(); + }); + }, timeoutMs); + } + + void beginLevelsTimer(int timeoutMs) { + const auto weak = std::weak_ptr(shared_from_this()); + getMediaThread()->PostDelayedTask(RTC_FROM_HERE, [weak]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + + GroupLevelsUpdate levelsUpdate; + levelsUpdate.updates.reserve(strong->_audioLevels.size() + 1); + for (auto &it : strong->_audioLevels) { + if (it.second.level > 0.001f) { + levelsUpdate.updates.push_back(GroupLevelUpdate{ + it.first, + it.second, + }); + } + } + levelsUpdate.updates.push_back(GroupLevelUpdate{ 0, strong->_myAudioLevel }); + + strong->_audioLevels.clear(); + strong->_audioLevelsUpdated(levelsUpdate); + + strong->beginLevelsTimer(50); + }, timeoutMs); + } + + void collectStats() { + const auto weak = std::weak_ptr(shared_from_this()); + + rtc::scoped_refptr observer(new rtc::RefCountedObject([weak](const rtc::scoped_refptr &stats) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, stats](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + strong->reportStats(stats); + strong->beginStatsTimer(100); + }); + })); + _peerConnection->GetStats(observer); + } + + void reportStats(const rtc::scoped_refptr &stats) { + } + + void onTrackAdded(rtc::scoped_refptr transceiver) { + if (transceiver->direction() == webrtc::RtpTransceiverDirection::kRecvOnly && transceiver->media_type() == cricket::MediaType::MEDIA_TYPE_AUDIO) { + if (transceiver->mid()) { + auto streamId = transceiver->mid().value(); + if (streamId.find("audio") != 0) { + return; + } + streamId.replace(0, 5, ""); + std::istringstream iss(streamId); + uint32_t ssrc = 0; + iss >> ssrc; + + auto remoteAudioTrack = static_cast(transceiver->receiver()->track().get()); + if (_audioTrackSinks.find(ssrc) == _audioTrackSinks.end()) { + const auto weak = std::weak_ptr(shared_from_this()); + std::shared_ptr sink(new AudioTrackSinkInterfaceImpl([weak, ssrc](float level, bool hasSpeech) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, ssrc, level, hasSpeech]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + auto current = strong->_audioLevels.find(ssrc); + if (current != strong->_audioLevels.end()) { + if (current->second.level < level) { + strong->_audioLevels[ssrc] = GroupLevelValue{ + level, + hasSpeech, + }; + } + } else { + strong->_audioLevels.emplace( + ssrc, + GroupLevelValue{ + level, + hasSpeech, + }); + } + }); + })); + _audioTrackSinks[ssrc] = sink; + remoteAudioTrack->AddSink(sink.get()); + } + } + } + } + + void onTrackRemoved(rtc::scoped_refptr receiver) { + } + + void onMissingSsrc(uint32_t ssrc) { + if (_processedMissingSsrcs.find(ssrc) == _processedMissingSsrcs.end()) { + _processedMissingSsrcs.insert(ssrc); + + _missingSsrcQueue.insert(ssrc); + if (!_isProcessingMissingSsrcs) { + beginProcessingMissingSsrcs(); + } + } + } + + void beginProcessingMissingSsrcs() { + if (_isProcessingMissingSsrcs) { + return; + } + _isProcessingMissingSsrcs = true; + auto timestamp = rtc::TimeMillis(); + if (timestamp > _missingSsrcsProcessedTimestamp + 200) { + applyMissingSsrcs(); + } else { + const auto weak = std::weak_ptr(shared_from_this()); + getMediaThread()->PostDelayedTask(RTC_FROM_HERE, [weak]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + strong->applyMissingSsrcs(); + }, 200); + } + } + + void applyMissingSsrcs() { + assert(_isProcessingMissingSsrcs); + if (_missingSsrcQueue.size() == 0) { + completeProcessingMissingSsrcs(); + return; + } + + std::vector addSsrcs; + for (auto ssrc : _missingSsrcQueue) { + addSsrcs.push_back(ssrc); + } + _missingSsrcQueue.clear(); + + const auto weak = std::weak_ptr(shared_from_this()); + addSsrcsInternal(addSsrcs, true); + } + + void completeProcessingMissingSsrcs() { + assert(_isProcessingMissingSsrcs); + _isProcessingMissingSsrcs = false; + _missingSsrcsProcessedTimestamp = rtc::TimeMillis(); + + if (_missingSsrcQueue.size() != 0) { + beginProcessingMissingSsrcs(); + } + } + + void completedInitialSetup() { + //beginDebugSsrcTimer(1000); + } + + uint32_t _nextTestSsrc = 100; + + void beginDebugSsrcTimer(int timeout) { + const auto weak = std::weak_ptr(shared_from_this()); + getMediaThread()->PostDelayedTask(RTC_FROM_HERE, [weak]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + + if (strong->_nextTestSsrc >= 100 + 50) { + return; + } + + strong->_nextTestSsrc++; + strong->onMissingSsrc(strong->_nextTestSsrc); + + strong->beginDebugSsrcTimer(20); + }, timeout); + } + + void setIsMuted(bool isMuted) { + if (!_localAudioTrackSender) { + return; + } + if (_isMuted == isMuted) { + return; + } + + for (auto &it : _peerConnection->GetTransceivers()) { + if (it->media_type() == cricket::MediaType::MEDIA_TYPE_AUDIO) { + if (_localAudioTrackSender.get() == it->sender().get()) { + if (isMuted) { + /*if (it->direction() == webrtc::RtpTransceiverDirection::kSendRecv) { + it->SetDirection(webrtc::RtpTransceiverDirection::kRecvOnly); + + applyLocalSdp(); + + break; + }*/ + } else { + if (it->direction() == webrtc::RtpTransceiverDirection::kRecvOnly) { + it->SetDirection(webrtc::RtpTransceiverDirection::kSendRecv); + + applyLocalSdp(); + + break; + } + } + } + + break; + } + } + + _isMuted = isMuted; + _localAudioTrack->set_enabled(!isMuted); + + RTC_LOG(LoggingSeverity::WARNING) << "setIsMuted: " << isMuted; + } + + void emitAnswer(bool completeMissingSsrcSetup) { + const auto weak = std::weak_ptr(shared_from_this()); + + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; + rtc::scoped_refptr observer(new rtc::RefCountedObject([weak, completeMissingSsrcSetup](std::string sdp, std::string type) { + getMediaThread()->PostTask(RTC_FROM_HERE, [weak, sdp, type, completeMissingSsrcSetup](){ + auto strong = weak.lock(); + if (!strong) { + return; + } + + RTC_LOG(LoggingSeverity::WARNING) << "----- setLocalDescription answer -----"; + RTC_LOG(LoggingSeverity::WARNING) << sdp; + RTC_LOG(LoggingSeverity::WARNING) << "-----"; + + webrtc::SdpParseError error; + webrtc::SessionDescriptionInterface *sessionDescription = webrtc::CreateSessionDescription(type, adjustLocalDescription(sdp), &error); + if (sessionDescription != nullptr) { + rtc::scoped_refptr observer(new rtc::RefCountedObject([weak, sdp, completeMissingSsrcSetup]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + + if (completeMissingSsrcSetup) { + strong->completeProcessingMissingSsrcs(); + } + }, [weak, completeMissingSsrcSetup](webrtc::RTCError error) { + auto strong = weak.lock(); + if (!strong) { + return; + } + + if (completeMissingSsrcSetup) { + strong->completeProcessingMissingSsrcs(); + } + })); + strong->_peerConnection->SetLocalDescription(observer, sessionDescription); + } else { + if (completeMissingSsrcSetup) { + strong->completeProcessingMissingSsrcs(); + } + } + }); + })); + _peerConnection->CreateAnswer(observer, options); + } + +private: + void withAudioDeviceModule(std::function callback) { + _adm_thread->Invoke(RTC_FROM_HERE, [&] { + callback(_adm_use_withAudioDeviceModule.get()); + }); + } + + std::function _networkStateUpdated; + std::function _audioLevelsUpdated; + + int32_t _myAudioLevelPeakCount = 0; + float _myAudioLevelPeak = 0; + GroupLevelValue _myAudioLevel; + + std::string _initialInputDeviceId; + std::string _initialOutputDeviceId; + + uint32_t _sessionId = 6543245; + uint32_t _mainStreamAudioSsrc = 0; + uint32_t _fakeIncomingSsrc = 0; + absl::optional _joinPayload; + + int64_t _appliedOfferTimestamp = 0; + bool _isConnected = false; + int _isConnectedUpdateValidTaskId = 0; + + bool _isMuted = true; + + std::vector _allOtherSsrcs; + std::set _activeOtherSsrcs; + std::set _processedMissingSsrcs; + + int64_t _missingSsrcsProcessedTimestamp = 0; + bool _isProcessingMissingSsrcs = false; + std::set _missingSsrcQueue; + + std::string _appliedRemoteRescription; + + rtc::scoped_refptr _nativeFactory; + std::unique_ptr _observer; + rtc::scoped_refptr _peerConnection; + std::unique_ptr _localAudioTrackSink; + rtc::scoped_refptr _localAudioTrack; + rtc::scoped_refptr _localAudioTrackSender; + + rtc::Thread *_adm_thread = nullptr; + rtc::scoped_refptr _adm_use_withAudioDeviceModule; + + std::map> _audioTrackSinks; + std::map _audioLevels; + + std::shared_ptr _platformContext; +}; + +GroupInstanceImpl::GroupInstanceImpl(GroupInstanceDescriptor &&descriptor) +: _logSink(std::make_unique(descriptor.config.logPath)) { + rtc::LogMessage::LogToDebug(rtc::LS_INFO); + rtc::LogMessage::SetLogToStderr(true); + if (_logSink) { + rtc::LogMessage::AddLogToStream(_logSink.get(), rtc::LS_INFO); + } + + _manager.reset(new ThreadLocalObject(getMediaThread(), [descriptor = std::move(descriptor)]() mutable { + return new GroupInstanceManager(std::move(descriptor)); + })); + _manager->perform(RTC_FROM_HERE, [](GroupInstanceManager *manager) { + manager->start(); + }); +} + +GroupInstanceImpl::~GroupInstanceImpl() { + if (_logSink) { + rtc::LogMessage::RemoveLogToStream(_logSink.get()); + } + _manager = nullptr; + + // Wait until _manager is destroyed, otherwise there is a race condition + // in destruction of PeerConnection on media thread and network thread. + getMediaThread()->Invoke(RTC_FROM_HERE, [] {}); +} + +void GroupInstanceImpl::stop() { + _manager->perform(RTC_FROM_HERE, [](GroupInstanceManager *manager) { + manager->stop(); + }); +} + +void GroupInstanceImpl::emitJoinPayload(std::function completion) { + _manager->perform(RTC_FROM_HERE, [completion](GroupInstanceManager *manager) { + manager->emitJoinPayload(completion); + }); +} + +void GroupInstanceImpl::setJoinResponsePayload(GroupJoinResponsePayload payload) { + _manager->perform(RTC_FROM_HERE, [payload](GroupInstanceManager *manager) { + manager->setJoinResponsePayload(payload); + }); +} + +void GroupInstanceImpl::removeSsrcs(std::vector ssrcs) { + _manager->perform(RTC_FROM_HERE, [ssrcs](GroupInstanceManager *manager) { + manager->removeSsrcs(ssrcs); + }); +} + +void GroupInstanceImpl::setIsMuted(bool isMuted) { + _manager->perform(RTC_FROM_HERE, [isMuted](GroupInstanceManager *manager) { + manager->setIsMuted(isMuted); + }); +} + +void GroupInstanceImpl::setAudioInputDevice(std::string id) { + _manager->perform(RTC_FROM_HERE, [id](GroupInstanceManager *manager) { + manager->setAudioInputDevice(id); + }); +} +void GroupInstanceImpl::setAudioOutputDevice(std::string id) { + _manager->perform(RTC_FROM_HERE, [id](GroupInstanceManager *manager) { + manager->setAudioOutputDevice(id); + }); +} + +} // namespace tgcalls diff --git a/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceImpl.h b/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceImpl.h new file mode 100644 index 000000000..8a8ed96ae --- /dev/null +++ b/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceImpl.h @@ -0,0 +1,120 @@ +#ifndef TGCALLS_GROUP_INSTANCE_IMPL_H +#define TGCALLS_GROUP_INSTANCE_IMPL_H + +#include +#include +#include +#include +#include + +#include "../Instance.h" + +namespace webrtc { +class AudioDeviceModule; +class TaskQueueFactory; +} + +namespace tgcalls { + +class LogSinkImpl; +class GroupInstanceManager; + +struct GroupConfig { + FilePath logPath; +}; + +struct GroupLevelValue { + float level = 0.; + bool voice = false; +}; + +struct GroupLevelUpdate { + uint32_t ssrc = 0; + GroupLevelValue value; +}; + +struct GroupLevelsUpdate { + std::vector updates; +}; + +struct GroupInstanceDescriptor { + GroupConfig config; + std::function networkStateUpdated; + std::function audioLevelsUpdated; + std::string initialInputDeviceId; + std::string initialOutputDeviceId; + bool debugIgnoreMissingSsrcs = false; + std::shared_ptr platformContext; +}; + +struct GroupJoinPayloadFingerprint { + std::string hash; + std::string setup; + std::string fingerprint; +}; + +struct GroupJoinPayload { + std::string ufrag; + std::string pwd; + std::vector fingerprints; + + uint32_t ssrc = 0; +}; + +struct GroupJoinResponseCandidate { + std::string port; + std::string protocol; + std::string network; + std::string generation; + std::string id; + std::string component; + std::string foundation; + std::string priority; + std::string ip; + std::string type; + + std::string tcpType; + std::string relAddr; + std::string relPort; +}; + +struct GroupJoinResponsePayload { + std::string ufrag; + std::string pwd; + std::vector fingerprints; + std::vector candidates; +}; + +template +class ThreadLocalObject; + +class GroupInstanceImpl final { +public: + explicit GroupInstanceImpl(GroupInstanceDescriptor &&descriptor); + ~GroupInstanceImpl(); + + void stop(); + + void emitJoinPayload(std::function completion); + void setJoinResponsePayload(GroupJoinResponsePayload payload); + void removeSsrcs(std::vector ssrcs); + + void setIsMuted(bool isMuted); + void setAudioOutputDevice(std::string id); + void setAudioInputDevice(std::string id); + + struct AudioDevice { + enum class Type {Input, Output}; + std::string name; + std::string guid; + }; + static std::vector getAudioDevices(AudioDevice::Type type); +private: + std::unique_ptr> _manager; + std::unique_ptr _logSink; + +}; + +} // namespace tgcalls + +#endif diff --git a/TMessagesProj/jni/voip/tgcalls/legacy/InstanceImplLegacy.cpp b/TMessagesProj/jni/voip/tgcalls/legacy/InstanceImplLegacy.cpp index 03735d5ca..ef66e29ba 100644 --- a/TMessagesProj/jni/voip/tgcalls/legacy/InstanceImplLegacy.cpp +++ b/TMessagesProj/jni/voip/tgcalls/legacy/InstanceImplLegacy.cpp @@ -138,7 +138,7 @@ onSignalBarsUpdated_(std::move(descriptor.signalBarsUpdated)) { descriptor.config.enableCallUpgrade ); mappedConfig.enableVolumeControl = descriptor.config.enableVolumeControl; - mappedConfig.logFilePath = descriptor.config.logPath; + mappedConfig.logFilePath = descriptor.config.logPath.data; mappedConfig.statsDumpFilePath = {}; controller_->SetConfig(mappedConfig); diff --git a/TMessagesProj/jni/voip/tgcalls/reference/InstanceImplReference.cpp b/TMessagesProj/jni/voip/tgcalls/reference/InstanceImplReference.cpp index aaa9e7dfe..4ab539429 100644 --- a/TMessagesProj/jni/voip/tgcalls/reference/InstanceImplReference.cpp +++ b/TMessagesProj/jni/voip/tgcalls/reference/InstanceImplReference.cpp @@ -934,7 +934,7 @@ private: }; InstanceImplReference::InstanceImplReference(Descriptor &&descriptor) : - logSink_(std::make_unique(descriptor.config)) { + logSink_(std::make_unique(descriptor.config.logPath)) { rtc::LogMessage::AddLogToStream(logSink_.get(), rtc::LS_INFO); internal_.reset(new ThreadLocalObject(getMediaThread(), [descriptor = std::move(descriptor)]() { diff --git a/TMessagesProj/jni/voip/webrtc/api/adaptation/resource.cc b/TMessagesProj/jni/voip/webrtc/api/adaptation/resource.cc index 0a9c83a31..dac03fe01 100644 --- a/TMessagesProj/jni/voip/webrtc/api/adaptation/resource.cc +++ b/TMessagesProj/jni/voip/webrtc/api/adaptation/resource.cc @@ -10,6 +10,8 @@ #include "api/adaptation/resource.h" +#include "rtc_base/checks.h" + namespace webrtc { const char* ResourceUsageStateToString(ResourceUsageState usage_state) { @@ -19,6 +21,7 @@ const char* ResourceUsageStateToString(ResourceUsageState usage_state) { case ResourceUsageState::kUnderuse: return "kUnderuse"; } + RTC_CHECK_NOTREACHED(); } ResourceListener::~ResourceListener() {} diff --git a/TMessagesProj/jni/voip/webrtc/api/array_view.h b/TMessagesProj/jni/voip/webrtc/api/array_view.h index a66369a3d..df365cb74 100644 --- a/TMessagesProj/jni/voip/webrtc/api/array_view.h +++ b/TMessagesProj/jni/voip/webrtc/api/array_view.h @@ -13,6 +13,7 @@ #include #include +#include #include #include "rtc_base/checks.h" @@ -258,6 +259,18 @@ class ArrayView final : public impl::ArrayViewBase { T* end() const { return this->data() + this->size(); } const T* cbegin() const { return this->data(); } const T* cend() const { return this->data() + this->size(); } + std::reverse_iterator rbegin() const { + return std::make_reverse_iterator(end()); + } + std::reverse_iterator rend() const { + return std::make_reverse_iterator(begin()); + } + std::reverse_iterator crbegin() const { + return std::make_reverse_iterator(cend()); + } + std::reverse_iterator crend() const { + return std::make_reverse_iterator(cbegin()); + } ArrayView subview(size_t offset, size_t size) const { return offset < this->size() diff --git a/TMessagesProj/jni/voip/webrtc/api/audio/audio_frame_processor.h b/TMessagesProj/jni/voip/webrtc/api/audio/audio_frame_processor.h new file mode 100644 index 000000000..bc21d1485 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/audio/audio_frame_processor.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef API_AUDIO_AUDIO_FRAME_PROCESSOR_H_ +#define API_AUDIO_AUDIO_FRAME_PROCESSOR_H_ + +#include +#include + +namespace webrtc { + +class AudioFrame; + +// If passed into PeerConnectionFactory, will be used for additional +// processing of captured audio frames, performed before encoding. +// Implementations must be thread-safe. +class AudioFrameProcessor { + public: + using OnAudioFrameCallback = std::function)>; + virtual ~AudioFrameProcessor() = default; + + // Processes the frame received from WebRTC, is called by WebRTC off the + // realtime audio capturing path. AudioFrameProcessor must reply with + // processed frames by calling |sink_callback| if it was provided in SetSink() + // call. |sink_callback| can be called in the context of Process(). + virtual void Process(std::unique_ptr frame) = 0; + + // Atomically replaces the current sink with the new one. Before the + // first call to this function, or if the provided |sink_callback| is nullptr, + // processed frames are simply discarded. + virtual void SetSink(OnAudioFrameCallback sink_callback) = 0; +}; + +} // namespace webrtc + +#endif // API_AUDIO_AUDIO_FRAME_PROCESSOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/audio/echo_canceller3_config.h b/TMessagesProj/jni/voip/webrtc/api/audio/echo_canceller3_config.h index a50562553..3ed11ff8b 100644 --- a/TMessagesProj/jni/voip/webrtc/api/audio/echo_canceller3_config.h +++ b/TMessagesProj/jni/voip/webrtc/api/audio/echo_canceller3_config.h @@ -143,6 +143,7 @@ struct RTC_EXPORT EchoCanceller3Config { float noise_gate_slope = 0.3f; size_t render_pre_window_size = 1; size_t render_post_window_size = 1; + bool model_reverb_in_nonlinear_mode = true; } echo_model; struct ComfortNoise { @@ -215,11 +216,12 @@ struct RTC_EXPORT EchoCanceller3Config { struct HighBandsSuppression { float enr_threshold = 1.f; float max_gain_during_echo = 1.f; - float anti_howling_activation_threshold = 25.f; - float anti_howling_gain = 0.01f; + float anti_howling_activation_threshold = 400.f; + float anti_howling_gain = 1.f; } high_bands_suppression; float floor_first_increase = 0.00001f; + bool conservative_hf_suppression = false; } suppressor; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/audio/echo_canceller3_config_json.cc b/TMessagesProj/jni/voip/webrtc/api/audio/echo_canceller3_config_json.cc index f5c124967..907b47271 100644 --- a/TMessagesProj/jni/voip/webrtc/api/audio/echo_canceller3_config_json.cc +++ b/TMessagesProj/jni/voip/webrtc/api/audio/echo_canceller3_config_json.cc @@ -302,6 +302,8 @@ void Aec3ConfigFromJsonString(absl::string_view json_string, &cfg.echo_model.render_pre_window_size); ReadParam(section, "render_post_window_size", &cfg.echo_model.render_post_window_size); + ReadParam(section, "model_reverb_in_nonlinear_mode", + &cfg.echo_model.model_reverb_in_nonlinear_mode); } if (rtc::GetValueFromJsonObject(aec3_root, "comfort_noise", §ion)) { @@ -381,6 +383,8 @@ void Aec3ConfigFromJsonString(absl::string_view json_string, ReadParam(section, "floor_first_increase", &cfg.suppressor.floor_first_increase); + ReadParam(section, "conservative_hf_suppression", + &cfg.suppressor.conservative_hf_suppression); } } @@ -585,7 +589,9 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) { ost << "\"render_pre_window_size\": " << config.echo_model.render_pre_window_size << ","; ost << "\"render_post_window_size\": " - << config.echo_model.render_post_window_size; + << config.echo_model.render_post_window_size << ","; + ost << "\"model_reverb_in_nonlinear_mode\": " + << (config.echo_model.model_reverb_in_nonlinear_mode ? "true" : "false"); ost << "},"; ost << "\"comfort_noise\": {"; @@ -672,7 +678,10 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) { ost << "\"anti_howling_gain\": " << config.suppressor.high_bands_suppression.anti_howling_gain; ost << "},"; - ost << "\"floor_first_increase\": " << config.suppressor.floor_first_increase; + ost << "\"floor_first_increase\": " << config.suppressor.floor_first_increase + << ","; + ost << "\"conservative_hf_suppression\": " + << config.suppressor.conservative_hf_suppression; ost << "}"; ost << "}"; ost << "}"; diff --git a/TMessagesProj/jni/voip/webrtc/api/audio_codecs/audio_decoder_factory.h b/TMessagesProj/jni/voip/webrtc/api/audio_codecs/audio_decoder_factory.h index c36a0e103..2811f6704 100644 --- a/TMessagesProj/jni/voip/webrtc/api/audio_codecs/audio_decoder_factory.h +++ b/TMessagesProj/jni/voip/webrtc/api/audio_codecs/audio_decoder_factory.h @@ -38,6 +38,8 @@ class AudioDecoderFactory : public rtc::RefCountInterface { // communication between the AudioEncoder and AudioDecoder instances, which is // needed for some codecs with built-in bandwidth adaptation.) // + // Returns null if the format isn't supported. + // // Note: Implementations need to be robust against combinations other than // one encoder, one decoder getting the same ID; such decoders must still // work. diff --git a/TMessagesProj/jni/voip/webrtc/api/audio_codecs/audio_encoder_factory.h b/TMessagesProj/jni/voip/webrtc/api/audio_codecs/audio_encoder_factory.h index 48995a876..6128b1b6f 100644 --- a/TMessagesProj/jni/voip/webrtc/api/audio_codecs/audio_encoder_factory.h +++ b/TMessagesProj/jni/voip/webrtc/api/audio_codecs/audio_encoder_factory.h @@ -44,6 +44,8 @@ class AudioEncoderFactory : public rtc::RefCountInterface { // communication between the AudioEncoder and AudioDecoder instances, which is // needed for some codecs with built-in bandwidth adaptation.) // + // Returns null if the format isn't supported. + // // Note: Implementations need to be robust against combinations other than // one encoder, one decoder getting the same ID; such encoders must still // work. diff --git a/TMessagesProj/jni/voip/webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc b/TMessagesProj/jni/voip/webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc index bd653b797..035b0dc34 100644 --- a/TMessagesProj/jni/voip/webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc +++ b/TMessagesProj/jni/voip/webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc @@ -32,7 +32,7 @@ int GetIlbcBitrate(int ptime) { // 50 bytes per frame of 30 ms => (approx) 13333 bits/s. return 13333; default: - FATAL(); + RTC_CHECK_NOTREACHED(); } } } // namespace diff --git a/TMessagesProj/jni/voip/webrtc/api/create_peerconnection_factory.cc b/TMessagesProj/jni/voip/webrtc/api/create_peerconnection_factory.cc index 622315007..008fce3e8 100644 --- a/TMessagesProj/jni/voip/webrtc/api/create_peerconnection_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/api/create_peerconnection_factory.cc @@ -18,6 +18,7 @@ #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/scoped_refptr.h" #include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" #include "media/base/media_engine.h" #include "media/engine/webrtc_media_engine.h" #include "modules/audio_device/include/audio_device.h" @@ -36,7 +37,8 @@ rtc::scoped_refptr CreatePeerConnectionFactory( std::unique_ptr video_encoder_factory, std::unique_ptr video_decoder_factory, rtc::scoped_refptr audio_mixer, - rtc::scoped_refptr audio_processing) { + rtc::scoped_refptr audio_processing, + AudioFrameProcessor* audio_frame_processor) { PeerConnectionFactoryDependencies dependencies; dependencies.network_thread = network_thread; dependencies.worker_thread = worker_thread; @@ -45,12 +47,14 @@ rtc::scoped_refptr CreatePeerConnectionFactory( dependencies.call_factory = CreateCallFactory(); dependencies.event_log_factory = std::make_unique( dependencies.task_queue_factory.get()); + dependencies.trials = std::make_unique(); cricket::MediaEngineDependencies media_dependencies; media_dependencies.task_queue_factory = dependencies.task_queue_factory.get(); media_dependencies.adm = std::move(default_adm); media_dependencies.audio_encoder_factory = std::move(audio_encoder_factory); media_dependencies.audio_decoder_factory = std::move(audio_decoder_factory); + media_dependencies.audio_frame_processor = audio_frame_processor; if (audio_processing) { media_dependencies.audio_processing = std::move(audio_processing); } else { @@ -59,6 +63,7 @@ rtc::scoped_refptr CreatePeerConnectionFactory( media_dependencies.audio_mixer = std::move(audio_mixer); media_dependencies.video_encoder_factory = std::move(video_encoder_factory); media_dependencies.video_decoder_factory = std::move(video_decoder_factory); + media_dependencies.trials = dependencies.trials.get(); dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_dependencies)); diff --git a/TMessagesProj/jni/voip/webrtc/api/create_peerconnection_factory.h b/TMessagesProj/jni/voip/webrtc/api/create_peerconnection_factory.h index ac50736b8..4eb0a00e5 100644 --- a/TMessagesProj/jni/voip/webrtc/api/create_peerconnection_factory.h +++ b/TMessagesProj/jni/voip/webrtc/api/create_peerconnection_factory.h @@ -31,6 +31,7 @@ class Thread; namespace webrtc { class AudioDeviceModule; +class AudioFrameProcessor; class AudioProcessing; // Create a new instance of PeerConnectionFactoryInterface with optional video @@ -47,7 +48,8 @@ CreatePeerConnectionFactory( std::unique_ptr video_encoder_factory, std::unique_ptr video_decoder_factory, rtc::scoped_refptr audio_mixer, - rtc::scoped_refptr audio_processing); + rtc::scoped_refptr audio_processing, + AudioFrameProcessor* audio_frame_processor = nullptr); } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/media_stream_proxy.h b/TMessagesProj/jni/voip/webrtc/api/media_stream_proxy.h index 516967998..8ee33ca0e 100644 --- a/TMessagesProj/jni/voip/webrtc/api/media_stream_proxy.h +++ b/TMessagesProj/jni/voip/webrtc/api/media_stream_proxy.h @@ -22,7 +22,7 @@ namespace webrtc { // are called on is an implementation detail. BEGIN_SIGNALING_PROXY_MAP(MediaStream) PROXY_SIGNALING_THREAD_DESTRUCTOR() -PROXY_CONSTMETHOD0(std::string, id) +BYPASS_PROXY_CONSTMETHOD0(std::string, id) PROXY_METHOD0(AudioTrackVector, GetAudioTracks) PROXY_METHOD0(VideoTrackVector, GetVideoTracks) PROXY_METHOD1(rtc::scoped_refptr, diff --git a/TMessagesProj/jni/voip/webrtc/pc/media_stream_track.h b/TMessagesProj/jni/voip/webrtc/api/media_stream_track.h similarity index 88% rename from TMessagesProj/jni/voip/webrtc/pc/media_stream_track.h rename to TMessagesProj/jni/voip/webrtc/api/media_stream_track.h index 358d89a25..738f03414 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/media_stream_track.h +++ b/TMessagesProj/jni/voip/webrtc/api/media_stream_track.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef PC_MEDIA_STREAM_TRACK_H_ -#define PC_MEDIA_STREAM_TRACK_H_ +#ifndef API_MEDIA_STREAM_TRACK_H_ +#define API_MEDIA_STREAM_TRACK_H_ #include @@ -38,6 +38,7 @@ class MediaStreamTrack : public Notifier { } return fire_on_change; } + void set_ended() { set_state(MediaStreamTrackInterface::TrackState::kEnded); } protected: explicit MediaStreamTrack(const std::string& id) @@ -53,10 +54,10 @@ class MediaStreamTrack : public Notifier { private: bool enabled_; - std::string id_; + const std::string id_; MediaStreamTrackInterface::TrackState state_; }; } // namespace webrtc -#endif // PC_MEDIA_STREAM_TRACK_H_ +#endif // API_MEDIA_STREAM_TRACK_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/media_stream_track_proxy.h b/TMessagesProj/jni/voip/webrtc/api/media_stream_track_proxy.h index d3dc25504..59dcb7724 100644 --- a/TMessagesProj/jni/voip/webrtc/api/media_stream_track_proxy.h +++ b/TMessagesProj/jni/voip/webrtc/api/media_stream_track_proxy.h @@ -26,8 +26,8 @@ namespace webrtc { BEGIN_SIGNALING_PROXY_MAP(AudioTrack) PROXY_SIGNALING_THREAD_DESTRUCTOR() -PROXY_CONSTMETHOD0(std::string, kind) -PROXY_CONSTMETHOD0(std::string, id) +BYPASS_PROXY_CONSTMETHOD0(std::string, kind) +BYPASS_PROXY_CONSTMETHOD0(std::string, id) PROXY_CONSTMETHOD0(TrackState, state) PROXY_CONSTMETHOD0(bool, enabled) PROXY_CONSTMETHOD0(AudioSourceInterface*, GetSource) @@ -42,8 +42,8 @@ END_PROXY_MAP() BEGIN_PROXY_MAP(VideoTrack) PROXY_SIGNALING_THREAD_DESTRUCTOR() -PROXY_CONSTMETHOD0(std::string, kind) -PROXY_CONSTMETHOD0(std::string, id) +BYPASS_PROXY_CONSTMETHOD0(std::string, kind) +BYPASS_PROXY_CONSTMETHOD0(std::string, id) PROXY_CONSTMETHOD0(TrackState, state) PROXY_CONSTMETHOD0(bool, enabled) PROXY_METHOD1(bool, set_enabled, bool) diff --git a/TMessagesProj/jni/voip/webrtc/api/media_types.cc b/TMessagesProj/jni/voip/webrtc/api/media_types.cc index 6bc693860..3453ce390 100644 --- a/TMessagesProj/jni/voip/webrtc/api/media_types.cc +++ b/TMessagesProj/jni/voip/webrtc/api/media_types.cc @@ -26,10 +26,12 @@ std::string MediaTypeToString(MediaType type) { return kMediaTypeVideo; case MEDIA_TYPE_DATA: return kMediaTypeData; + case MEDIA_TYPE_UNSUPPORTED: + // Unsupported media stores the m= differently. + RTC_NOTREACHED(); + return ""; } - FATAL(); - // Not reachable; avoids compile warning. - return ""; + RTC_CHECK_NOTREACHED(); } } // namespace cricket diff --git a/TMessagesProj/jni/voip/webrtc/api/media_types.h b/TMessagesProj/jni/voip/webrtc/api/media_types.h index 8c6ba3d1e..b2ff08c0c 100644 --- a/TMessagesProj/jni/voip/webrtc/api/media_types.h +++ b/TMessagesProj/jni/voip/webrtc/api/media_types.h @@ -20,7 +20,12 @@ namespace cricket { -enum MediaType { MEDIA_TYPE_AUDIO, MEDIA_TYPE_VIDEO, MEDIA_TYPE_DATA }; +enum MediaType { + MEDIA_TYPE_AUDIO, + MEDIA_TYPE_VIDEO, + MEDIA_TYPE_DATA, + MEDIA_TYPE_UNSUPPORTED +}; extern const char kMediaTypeAudio[]; extern const char kMediaTypeVideo[]; diff --git a/TMessagesProj/jni/voip/webrtc/api/neteq/neteq.h b/TMessagesProj/jni/voip/webrtc/api/neteq/neteq.h index 15ad3aac0..9781377ca 100644 --- a/TMessagesProj/jni/voip/webrtc/api/neteq/neteq.h +++ b/TMessagesProj/jni/voip/webrtc/api/neteq/neteq.h @@ -36,7 +36,6 @@ struct NetEqNetworkStatistics { uint16_t preferred_buffer_size_ms; // Target buffer size in ms. uint16_t jitter_peaks_found; // 1 if adding extra delay due to peaky // jitter; 0 otherwise. - uint16_t packet_loss_rate; // Loss rate (network + late) in Q14. uint16_t expand_rate; // Fraction (of original stream) of synthesized // audio inserted through expansion (in Q14). uint16_t speech_expand_rate; // Fraction (of original stream) of synthesized @@ -49,7 +48,6 @@ struct NetEqNetworkStatistics { // decoding (in Q14). uint16_t secondary_discarded_rate; // Fraction of discarded FEC/RED data (in // Q14). - size_t added_zero_samples; // Number of zero samples added in "off" mode. // Statistics for packet waiting times, i.e., the time between a packet // arrives until it is decoded. int mean_waiting_time_ms; @@ -274,6 +272,9 @@ class NetEq { // after the call. virtual int NetworkStatistics(NetEqNetworkStatistics* stats) = 0; + // Current values only, not resetting any state. + virtual NetEqNetworkStatistics CurrentNetworkStatistics() const = 0; + // Returns a copy of this class's lifetime statistics. These statistics are // never reset. virtual NetEqLifetimeStatistics GetLifetimeStatistics() const = 0; diff --git a/TMessagesProj/jni/voip/webrtc/api/neteq/neteq_controller.h b/TMessagesProj/jni/voip/webrtc/api/neteq/neteq_controller.h index 1d47eaca7..2c09c3e15 100644 --- a/TMessagesProj/jni/voip/webrtc/api/neteq/neteq_controller.h +++ b/TMessagesProj/jni/voip/webrtc/api/neteq/neteq_controller.h @@ -97,6 +97,14 @@ class NetEqController { size_t sync_buffer_samples; }; + struct PacketArrivedInfo { + size_t packet_length_samples; + uint32_t main_timestamp; + uint16_t main_sequence_number; + bool is_cng_or_dtmf; + bool is_dtx; + }; + virtual ~NetEqController() = default; // Resets object to a clean state. @@ -152,16 +160,17 @@ class NetEqController { virtual void AddSampleMemory(int32_t value) = 0; // Returns the target buffer level in ms. - virtual int TargetLevelMs() = 0; + virtual int TargetLevelMs() const = 0; // Notify the NetEqController that a packet has arrived. Returns the relative // arrival delay, if it can be computed. - virtual absl::optional PacketArrived(bool last_cng_or_dtmf, - size_t packet_length_samples, + virtual absl::optional PacketArrived(int fs_hz, bool should_update_stats, - uint16_t main_sequence_number, - uint32_t main_timestamp, - int fs_hz) = 0; + const PacketArrivedInfo& info) = 0; + + // Notify the NetEqController that we are currently in muted state. + // TODO(ivoc): Make pure virtual when downstream is updated. + virtual void NotifyMutedState() {} // Returns true if a peak was found. virtual bool PeakFound() const = 0; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/samples_stats_counter.cc b/TMessagesProj/jni/voip/webrtc/api/numerics/samples_stats_counter.cc similarity index 97% rename from TMessagesProj/jni/voip/webrtc/rtc_base/numerics/samples_stats_counter.cc rename to TMessagesProj/jni/voip/webrtc/api/numerics/samples_stats_counter.cc index 9b98a3181..36871a671 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/samples_stats_counter.cc +++ b/TMessagesProj/jni/voip/webrtc/api/numerics/samples_stats_counter.cc @@ -8,8 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "rtc_base/numerics/samples_stats_counter.h" +#include "api/numerics/samples_stats_counter.h" +#include #include #include "absl/algorithm/container.h" diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/samples_stats_counter.h b/TMessagesProj/jni/voip/webrtc/api/numerics/samples_stats_counter.h similarity index 92% rename from TMessagesProj/jni/voip/webrtc/rtc_base/numerics/samples_stats_counter.h rename to TMessagesProj/jni/voip/webrtc/api/numerics/samples_stats_counter.h index a4ec443d3..283c1e4ed 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/samples_stats_counter.h +++ b/TMessagesProj/jni/voip/webrtc/api/numerics/samples_stats_counter.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef RTC_BASE_NUMERICS_SAMPLES_STATS_COUNTER_H_ -#define RTC_BASE_NUMERICS_SAMPLES_STATS_COUNTER_H_ +#ifndef API_NUMERICS_SAMPLES_STATS_COUNTER_H_ +#define API_NUMERICS_SAMPLES_STATS_COUNTER_H_ #include @@ -45,6 +45,8 @@ class SamplesStatsCounter { // Returns if there are any values in O(1) time. bool IsEmpty() const { return samples_.empty(); } + // Returns the amount of samples added into counter in O(1) time. + int64_t NumSamples() const { return stats_.Size(); } // Returns min in O(1) time. This function may not be called if there are no // samples. @@ -98,7 +100,7 @@ class SamplesStatsCounter { } private: - RunningStatistics stats_; + webrtc_impl::RunningStatistics stats_; std::vector samples_; bool sorted_ = false; }; @@ -116,4 +118,4 @@ SamplesStatsCounter operator/(const SamplesStatsCounter& counter, double value); } // namespace webrtc -#endif // RTC_BASE_NUMERICS_SAMPLES_STATS_COUNTER_H_ +#endif // API_NUMERICS_SAMPLES_STATS_COUNTER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/peer_connection_interface.h b/TMessagesProj/jni/voip/webrtc/api/peer_connection_interface.h index 09317b828..c5b04b25e 100644 --- a/TMessagesProj/jni/voip/webrtc/api/peer_connection_interface.h +++ b/TMessagesProj/jni/voip/webrtc/api/peer_connection_interface.h @@ -105,6 +105,7 @@ #include "api/transport/bitrate_settings.h" #include "api/transport/enums.h" #include "api/transport/network_control.h" +#include "api/transport/sctp_transport_factory_interface.h" #include "api/transport/webrtc_key_value_config.h" #include "api/turn_customizer.h" #include "media/base/media_config.h" @@ -639,6 +640,9 @@ class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface { // Whether network condition based codec switching is allowed. absl::optional allow_codec_switching; + // The delay before doing a usage histogram report for long-lived + // PeerConnections. Used for testing only. + absl::optional report_usage_pattern_delay_ms; // // Don't forget to update operator== if adding something. // @@ -1003,6 +1007,16 @@ class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface { virtual void SetRemoteDescription(SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc) {} + // According to spec, we must only fire "negotiationneeded" if the Operations + // Chain is empty. This method takes care of validating an event previously + // generated with PeerConnectionObserver::OnNegotiationNeededEvent() to make + // sure that even if there was a delay (e.g. due to a PostTask) between the + // event being generated and the time of firing, the Operations Chain is empty + // and the event is still valid to be fired. + virtual bool ShouldFireNegotiationNeededEvent(uint32_t event_id) { + return true; + } + virtual PeerConnectionInterface::RTCConfiguration GetConfiguration() = 0; // Sets the PeerConnection's global configuration to |config|. @@ -1176,7 +1190,17 @@ class PeerConnectionObserver { // Triggered when renegotiation is needed. For example, an ICE restart // has begun. - virtual void OnRenegotiationNeeded() = 0; + // TODO(hbos): Delete in favor of OnNegotiationNeededEvent() when downstream + // projects have migrated. + virtual void OnRenegotiationNeeded() {} + // Used to fire spec-compliant onnegotiationneeded events, which should only + // fire when the Operations Chain is empty. The observer is responsible for + // queuing a task (e.g. Chromium: jump to main thread) to maybe fire the + // event. The event identified using |event_id| must only fire if + // PeerConnection::ShouldFireNegotiationNeededEvent() returns true since it is + // possible for the event to become invalidated by operations subsequently + // chained. + virtual void OnNegotiationNeededEvent(uint32_t event_id) {} // Called any time the legacy IceConnectionState changes. // @@ -1272,8 +1296,25 @@ class PeerConnectionObserver { // The heuristics for defining what constitutes "interesting" are // implementation-defined. virtual void OnInterestingUsage(int usage_pattern) {} + + virtual void OnErrorDemuxingPacket(uint32_t ssrc) {} }; +class ErrorDemuxingPacketObserver : public rtc::RefCountInterface { +public: + ErrorDemuxingPacketObserver(PeerConnectionObserver *observer) : + observer_(observer) { + } + + void OnErrorDemuxingPacket(uint32_t ssrc) { + observer_->OnErrorDemuxingPacket(ssrc); + } + +private: + PeerConnectionObserver *observer_ = nullptr; +}; + + // PeerConnectionDependencies holds all of PeerConnections dependencies. // A dependency is distinct from a configuration as it defines significant // executable code that can be provided by a user of the API. @@ -1343,6 +1384,7 @@ struct RTC_EXPORT PeerConnectionFactoryDependencies final { // used. std::unique_ptr network_monitor_factory; std::unique_ptr neteq_factory; + std::unique_ptr sctp_factory; std::unique_ptr trials; }; diff --git a/TMessagesProj/jni/voip/webrtc/api/peer_connection_proxy.h b/TMessagesProj/jni/voip/webrtc/api/peer_connection_proxy.h index 0cc3b3b8e..2d4cb5cad 100644 --- a/TMessagesProj/jni/voip/webrtc/api/peer_connection_proxy.h +++ b/TMessagesProj/jni/voip/webrtc/api/peer_connection_proxy.h @@ -116,6 +116,7 @@ PROXY_METHOD2(void, SetRemoteDescription, SetSessionDescriptionObserver*, SessionDescriptionInterface*) +PROXY_METHOD1(bool, ShouldFireNegotiationNeededEvent, uint32_t) PROXY_METHOD0(PeerConnectionInterface::RTCConfiguration, GetConfiguration) PROXY_METHOD1(RTCError, SetConfiguration, diff --git a/TMessagesProj/jni/voip/webrtc/api/proxy.cc b/TMessagesProj/jni/voip/webrtc/api/proxy.cc index e668285ba..67318e7da 100644 --- a/TMessagesProj/jni/voip/webrtc/api/proxy.cc +++ b/TMessagesProj/jni/voip/webrtc/api/proxy.cc @@ -10,28 +10,3 @@ #include "api/proxy.h" -namespace webrtc { -namespace internal { - -SynchronousMethodCall::SynchronousMethodCall(rtc::MessageHandler* proxy) - : proxy_(proxy) {} - -SynchronousMethodCall::~SynchronousMethodCall() = default; - -void SynchronousMethodCall::Invoke(const rtc::Location& posted_from, - rtc::Thread* t) { - if (t->IsCurrent()) { - proxy_->OnMessage(nullptr); - } else { - t->Post(posted_from, this, 0); - e_.Wait(rtc::Event::kForever); - } -} - -void SynchronousMethodCall::OnMessage(rtc::Message*) { - proxy_->OnMessage(nullptr); - e_.Set(); -} - -} // namespace internal -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/proxy.h b/TMessagesProj/jni/voip/webrtc/api/proxy.h index 0e5d622eb..05f7414bc 100644 --- a/TMessagesProj/jni/voip/webrtc/api/proxy.h +++ b/TMessagesProj/jni/voip/webrtc/api/proxy.h @@ -59,6 +59,8 @@ #include #include "api/scoped_refptr.h" +#include "api/task_queue/queued_task.h" +#include "api/task_queue/task_queue_base.h" #include "rtc_base/event.h" #include "rtc_base/message_handler.h" #include "rtc_base/ref_counted_object.h" @@ -96,27 +98,8 @@ class ReturnType { void moved_result() {} }; -namespace internal { - -class RTC_EXPORT SynchronousMethodCall : public rtc::MessageData, - public rtc::MessageHandler { - public: - explicit SynchronousMethodCall(rtc::MessageHandler* proxy); - ~SynchronousMethodCall() override; - - void Invoke(const rtc::Location& posted_from, rtc::Thread* t); - - private: - void OnMessage(rtc::Message*) override; - - rtc::Event e_; - rtc::MessageHandler* proxy_; -}; - -} // namespace internal - template -class MethodCall : public rtc::Message, public rtc::MessageHandler { +class MethodCall : public QueuedTask { public: typedef R (C::*Method)(Args...); MethodCall(C* c, Method m, Args&&... args) @@ -125,12 +108,21 @@ class MethodCall : public rtc::Message, public rtc::MessageHandler { args_(std::forward_as_tuple(std::forward(args)...)) {} R Marshal(const rtc::Location& posted_from, rtc::Thread* t) { - internal::SynchronousMethodCall(this).Invoke(posted_from, t); + if (t->IsCurrent()) { + Invoke(std::index_sequence_for()); + } else { + t->PostTask(std::unique_ptr(this)); + event_.Wait(rtc::Event::kForever); + } return r_.moved_result(); } private: - void OnMessage(rtc::Message*) { Invoke(std::index_sequence_for()); } + bool Run() override { + Invoke(std::index_sequence_for()); + event_.Set(); + return false; + } template void Invoke(std::index_sequence) { @@ -141,10 +133,11 @@ class MethodCall : public rtc::Message, public rtc::MessageHandler { Method m_; ReturnType r_; std::tuple args_; + rtc::Event event_; }; template -class ConstMethodCall : public rtc::Message, public rtc::MessageHandler { +class ConstMethodCall : public QueuedTask { public: typedef R (C::*Method)(Args...) const; ConstMethodCall(const C* c, Method m, Args&&... args) @@ -153,12 +146,21 @@ class ConstMethodCall : public rtc::Message, public rtc::MessageHandler { args_(std::forward_as_tuple(std::forward(args)...)) {} R Marshal(const rtc::Location& posted_from, rtc::Thread* t) { - internal::SynchronousMethodCall(this).Invoke(posted_from, t); + if (t->IsCurrent()) { + Invoke(std::index_sequence_for()); + } else { + t->PostTask(std::unique_ptr(this)); + event_.Wait(rtc::Event::kForever); + } return r_.moved_result(); } private: - void OnMessage(rtc::Message*) { Invoke(std::index_sequence_for()); } + bool Run() override { + Invoke(std::index_sequence_for()); + event_.Set(); + return false; + } template void Invoke(std::index_sequence) { @@ -169,6 +171,7 @@ class ConstMethodCall : public rtc::Message, public rtc::MessageHandler { Method m_; ReturnType r_; std::tuple args_; + rtc::Event event_; }; // Helper macros to reduce code duplication. diff --git a/TMessagesProj/jni/voip/webrtc/api/rtc_error.h b/TMessagesProj/jni/voip/webrtc/api/rtc_error.h index b8cb7f0bc..d24737c25 100644 --- a/TMessagesProj/jni/voip/webrtc/api/rtc_error.h +++ b/TMessagesProj/jni/voip/webrtc/api/rtc_error.h @@ -137,7 +137,7 @@ class RTC_EXPORT RTCError { RTCErrorDetailType error_detail() const { return error_detail_; } void set_error_detail(RTCErrorDetailType detail) { error_detail_ = detail; } - absl::optional sctp_cause_code() { return sctp_cause_code_; } + absl::optional sctp_cause_code() const { return sctp_cause_code_; } void set_sctp_cause_code(uint16_t cause_code) { sctp_cause_code_ = cause_code; } diff --git a/TMessagesProj/jni/voip/webrtc/api/rtc_event_log/rtc_event_log_factory.cc b/TMessagesProj/jni/voip/webrtc/api/rtc_event_log/rtc_event_log_factory.cc index 201358439..fdf267b7b 100644 --- a/TMessagesProj/jni/voip/webrtc/api/rtc_event_log/rtc_event_log_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/api/rtc_event_log/rtc_event_log_factory.cc @@ -14,6 +14,7 @@ #include #include "rtc_base/checks.h" +#include "system_wrappers/include/field_trial.h" #ifdef WEBRTC_ENABLE_RTC_EVENT_LOG #include "logging/rtc_event_log/rtc_event_log_impl.h" @@ -29,6 +30,9 @@ RtcEventLogFactory::RtcEventLogFactory(TaskQueueFactory* task_queue_factory) std::unique_ptr RtcEventLogFactory::CreateRtcEventLog( RtcEventLog::EncodingType encoding_type) { #ifdef WEBRTC_ENABLE_RTC_EVENT_LOG + if (field_trial::IsEnabled("WebRTC-RtcEventLogKillSwitch")) { + return std::make_unique(); + } return std::make_unique(encoding_type, task_queue_factory_); #else return std::make_unique(); diff --git a/TMessagesProj/jni/voip/webrtc/api/rtp_headers.h b/TMessagesProj/jni/voip/webrtc/api/rtp_headers.h index 454149ca6..b9a97c885 100644 --- a/TMessagesProj/jni/voip/webrtc/api/rtp_headers.h +++ b/TMessagesProj/jni/voip/webrtc/api/rtp_headers.h @@ -23,7 +23,6 @@ #include "api/video/video_content_type.h" #include "api/video/video_rotation.h" #include "api/video/video_timing.h" -#include "common_types.h" // NOLINT (build/include) namespace webrtc { @@ -142,7 +141,7 @@ struct RTPHeaderExtension { bool has_video_timing; VideoSendTiming video_timing; - PlayoutDelay playout_delay = {-1, -1}; + VideoPlayoutDelay playout_delay; // For identification of a stream when ssrc is not signaled. See // https://tools.ietf.org/html/draft-ietf-avtext-rid-09 diff --git a/TMessagesProj/jni/voip/webrtc/api/rtp_parameters.cc b/TMessagesProj/jni/voip/webrtc/api/rtp_parameters.cc index 28acb68be..92f99e9bb 100644 --- a/TMessagesProj/jni/voip/webrtc/api/rtp_parameters.cc +++ b/TMessagesProj/jni/voip/webrtc/api/rtp_parameters.cc @@ -30,6 +30,7 @@ const char* DegradationPreferenceToString( case DegradationPreference::BALANCED: return "balanced"; } + RTC_CHECK_NOTREACHED(); } const double kDefaultBitratePriority = 1.0; @@ -121,6 +122,7 @@ constexpr char RtpExtension::kVideoContentTypeUri[]; constexpr char RtpExtension::kVideoTimingUri[]; constexpr char RtpExtension::kGenericFrameDescriptorUri00[]; constexpr char RtpExtension::kDependencyDescriptorUri[]; +constexpr char RtpExtension::kVideoLayersAllocationUri[]; constexpr char RtpExtension::kTransportSequenceNumberUri[]; constexpr char RtpExtension::kTransportSequenceNumberV2Uri[]; constexpr char RtpExtension::kPlayoutDelayUri[]; @@ -161,7 +163,8 @@ bool RtpExtension::IsSupportedForVideo(absl::string_view uri) { uri == webrtc::RtpExtension::kDependencyDescriptorUri || uri == webrtc::RtpExtension::kColorSpaceUri || uri == webrtc::RtpExtension::kRidUri || - uri == webrtc::RtpExtension::kRepairedRidUri; + uri == webrtc::RtpExtension::kRepairedRidUri || + uri == webrtc::RtpExtension::kVideoLayersAllocationUri; } bool RtpExtension::IsEncryptionSupported(absl::string_view uri) { @@ -183,7 +186,8 @@ bool RtpExtension::IsEncryptionSupported(absl::string_view uri) { uri == webrtc::RtpExtension::kVideoContentTypeUri || uri == webrtc::RtpExtension::kMidUri || uri == webrtc::RtpExtension::kRidUri || - uri == webrtc::RtpExtension::kRepairedRidUri; + uri == webrtc::RtpExtension::kRepairedRidUri || + uri == webrtc::RtpExtension::kVideoLayersAllocationUri; } const RtpExtension* RtpExtension::FindHeaderExtensionByUri( diff --git a/TMessagesProj/jni/voip/webrtc/api/rtp_parameters.h b/TMessagesProj/jni/voip/webrtc/api/rtp_parameters.h index b667bf812..df0e7a93b 100644 --- a/TMessagesProj/jni/voip/webrtc/api/rtp_parameters.h +++ b/TMessagesProj/jni/voip/webrtc/api/rtp_parameters.h @@ -318,6 +318,10 @@ struct RTC_EXPORT RtpExtension { "https://aomediacodec.github.io/av1-rtp-spec/" "#dependency-descriptor-rtp-header-extension"; + // Experimental extension for signalling target bitrate per layer. + static constexpr char kVideoLayersAllocationUri[] = + "http://www.webrtc.org/experiments/rtp-hdrext/video-layers-allocation00"; + // Header extension for transport sequence number, see url for details: // http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions static constexpr char kTransportSequenceNumberUri[] = @@ -461,6 +465,9 @@ struct RTC_EXPORT RtpEncodingParameters { // For video, scale the resolution down by this factor. absl::optional scale_resolution_down_by; + // https://w3c.github.io/webrtc-svc/#rtcrtpencodingparameters + absl::optional scalability_mode; + // For an RtpSender, set to true to cause this encoding to be encoded and // sent, and false for it not to be encoded and sent. This allows control // across multiple encodings of a sender for turning simulcast layers on and diff --git a/TMessagesProj/jni/voip/webrtc/api/rtp_receiver_interface.h b/TMessagesProj/jni/voip/webrtc/api/rtp_receiver_interface.h index a15864e34..786ea3ace 100644 --- a/TMessagesProj/jni/voip/webrtc/api/rtp_receiver_interface.h +++ b/TMessagesProj/jni/voip/webrtc/api/rtp_receiver_interface.h @@ -128,8 +128,8 @@ PROXY_CONSTMETHOD0(rtc::scoped_refptr, dtls_transport) PROXY_CONSTMETHOD0(std::vector, stream_ids) PROXY_CONSTMETHOD0(std::vector>, streams) -PROXY_CONSTMETHOD0(cricket::MediaType, media_type) -PROXY_CONSTMETHOD0(std::string, id) +BYPASS_PROXY_CONSTMETHOD0(cricket::MediaType, media_type) +BYPASS_PROXY_CONSTMETHOD0(std::string, id) PROXY_CONSTMETHOD0(RtpParameters, GetParameters) PROXY_METHOD1(void, SetObserver, RtpReceiverObserverInterface*) PROXY_METHOD1(void, SetJitterBufferMinimumDelay, absl::optional) diff --git a/TMessagesProj/jni/voip/webrtc/api/rtp_sender_interface.h b/TMessagesProj/jni/voip/webrtc/api/rtp_sender_interface.h index bdbd6dc64..a33b80042 100644 --- a/TMessagesProj/jni/voip/webrtc/api/rtp_sender_interface.h +++ b/TMessagesProj/jni/voip/webrtc/api/rtp_sender_interface.h @@ -110,8 +110,8 @@ PROXY_METHOD1(bool, SetTrack, MediaStreamTrackInterface*) PROXY_CONSTMETHOD0(rtc::scoped_refptr, track) PROXY_CONSTMETHOD0(rtc::scoped_refptr, dtls_transport) PROXY_CONSTMETHOD0(uint32_t, ssrc) -PROXY_CONSTMETHOD0(cricket::MediaType, media_type) -PROXY_CONSTMETHOD0(std::string, id) +BYPASS_PROXY_CONSTMETHOD0(cricket::MediaType, media_type) +BYPASS_PROXY_CONSTMETHOD0(std::string, id) PROXY_CONSTMETHOD0(std::vector, stream_ids) PROXY_CONSTMETHOD0(std::vector, init_send_encodings) PROXY_CONSTMETHOD0(RtpParameters, GetParameters) diff --git a/TMessagesProj/jni/voip/webrtc/api/rtp_transceiver_interface.h b/TMessagesProj/jni/voip/webrtc/api/rtp_transceiver_interface.h index cdda34b19..fd3555fb4 100644 --- a/TMessagesProj/jni/voip/webrtc/api/rtp_transceiver_interface.h +++ b/TMessagesProj/jni/voip/webrtc/api/rtp_transceiver_interface.h @@ -111,7 +111,8 @@ class RTC_EXPORT RtpTransceiverInterface : public rtc::RefCountInterface { // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction // TODO(hta): Deprecate SetDirection without error and rename // SetDirectionWithError to SetDirection, remove default implementations. - virtual void SetDirection(RtpTransceiverDirection new_direction); + RTC_DEPRECATED virtual void SetDirection( + RtpTransceiverDirection new_direction); virtual RTCError SetDirectionWithError(RtpTransceiverDirection new_direction); // The current_direction attribute indicates the current direction negotiated diff --git a/TMessagesProj/jni/voip/webrtc/api/stats/rtc_stats_report.h b/TMessagesProj/jni/voip/webrtc/api/stats/rtc_stats_report.h index dc1593769..94bd813b0 100644 --- a/TMessagesProj/jni/voip/webrtc/api/stats/rtc_stats_report.h +++ b/TMessagesProj/jni/voip/webrtc/api/stats/rtc_stats_report.h @@ -84,8 +84,8 @@ class RTC_EXPORT RTCStatsReport : public rtc::RefCountInterface { // Removes the stats object from the report, returning ownership of it or null // if there is no object with |id|. std::unique_ptr Take(const std::string& id); - // Takes ownership of all the stats in |victim|, leaving it empty. - void TakeMembersFrom(rtc::scoped_refptr victim); + // Takes ownership of all the stats in |other|, leaving it empty. + void TakeMembersFrom(rtc::scoped_refptr other); // Stats iterators. Stats are ordered lexicographically on |RTCStats::id|. ConstIterator begin() const; diff --git a/TMessagesProj/jni/voip/webrtc/api/stats/rtcstats_objects.h b/TMessagesProj/jni/voip/webrtc/api/stats/rtcstats_objects.h index 7d8f5f5f9..ee3d70727 100644 --- a/TMessagesProj/jni/voip/webrtc/api/stats/rtcstats_objects.h +++ b/TMessagesProj/jni/voip/webrtc/api/stats/rtcstats_objects.h @@ -115,6 +115,7 @@ class RTC_EXPORT RTCCodecStats final : public RTCStats { RTCCodecStats(const RTCCodecStats& other); ~RTCCodecStats() override; + RTCStatsMember transport_id; RTCStatsMember payload_type; RTCStatsMember mime_type; RTCStatsMember clock_rate; diff --git a/TMessagesProj/jni/voip/webrtc/api/test/compile_all_headers.cc b/TMessagesProj/jni/voip/webrtc/api/test/compile_all_headers.cc index 4cece5b28..6f0674299 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/compile_all_headers.cc +++ b/TMessagesProj/jni/voip/webrtc/api/test/compile_all_headers.cc @@ -31,10 +31,13 @@ #include "api/test/fake_frame_decryptor.h" #include "api/test/fake_frame_encryptor.h" #include "api/test/mock_audio_mixer.h" +#include "api/test/mock_data_channel.h" #include "api/test/mock_frame_decryptor.h" #include "api/test/mock_frame_encryptor.h" +#include "api/test/mock_media_stream_interface.h" #include "api/test/mock_peer_connection_factory_interface.h" #include "api/test/mock_peerconnectioninterface.h" +#include "api/test/mock_rtp_transceiver.h" #include "api/test/mock_rtpreceiver.h" #include "api/test/mock_rtpsender.h" #include "api/test/mock_transformable_video_frame.h" diff --git a/TMessagesProj/jni/voip/webrtc/api/test/create_peer_connection_quality_test_frame_generator.cc b/TMessagesProj/jni/voip/webrtc/api/test/create_peer_connection_quality_test_frame_generator.cc new file mode 100644 index 000000000..7f0ba20c8 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/test/create_peer_connection_quality_test_frame_generator.cc @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020 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 "api/test/create_peer_connection_quality_test_frame_generator.h" + +#include +#include + +#include "api/test/create_frame_generator.h" +#include "api/test/peerconnection_quality_test_fixture.h" +#include "rtc_base/checks.h" +#include "test/testsupport/file_utils.h" + +namespace webrtc { +namespace webrtc_pc_e2e { + +using VideoConfig = + ::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::VideoConfig; +using ScreenShareConfig = ::webrtc::webrtc_pc_e2e:: + PeerConnectionE2EQualityTestFixture::ScreenShareConfig; + +void ValidateScreenShareConfig(const VideoConfig& video_config, + const ScreenShareConfig& screen_share_config) { + if (screen_share_config.slides_yuv_file_names.empty()) { + if (screen_share_config.scrolling_params) { + // If we have scrolling params, then its |source_width| and |source_heigh| + // will be used as width and height of video input, so we have to validate + // it against width and height of default input. + RTC_CHECK_EQ(screen_share_config.scrolling_params->source_width, + kDefaultSlidesWidth); + RTC_CHECK_EQ(screen_share_config.scrolling_params->source_height, + kDefaultSlidesHeight); + } else { + RTC_CHECK_EQ(video_config.width, kDefaultSlidesWidth); + RTC_CHECK_EQ(video_config.height, kDefaultSlidesHeight); + } + } + if (screen_share_config.scrolling_params) { + RTC_CHECK_LE(screen_share_config.scrolling_params->duration, + screen_share_config.slide_change_interval); + RTC_CHECK_GE(screen_share_config.scrolling_params->source_width, + video_config.width); + RTC_CHECK_GE(screen_share_config.scrolling_params->source_height, + video_config.height); + } +} + +std::unique_ptr CreateSquareFrameGenerator( + const VideoConfig& video_config, + absl::optional type) { + return test::CreateSquareFrameGenerator( + video_config.width, video_config.height, std::move(type), absl::nullopt); +} + +std::unique_ptr CreateFromYuvFileFrameGenerator( + const VideoConfig& video_config, + std::string filename) { + return test::CreateFromYuvFileFrameGenerator( + {std::move(filename)}, video_config.width, video_config.height, + /*frame_repeat_count=*/1); +} + +std::unique_ptr CreateScreenShareFrameGenerator( + const VideoConfig& video_config, + const ScreenShareConfig& screen_share_config) { + ValidateScreenShareConfig(video_config, screen_share_config); + if (screen_share_config.generate_slides) { + return test::CreateSlideFrameGenerator( + video_config.width, video_config.height, + screen_share_config.slide_change_interval.seconds() * video_config.fps); + } + std::vector slides = screen_share_config.slides_yuv_file_names; + if (slides.empty()) { + // If slides is empty we need to add default slides as source. In such case + // video width and height is validated to be equal to kDefaultSlidesWidth + // and kDefaultSlidesHeight. + slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv")); + slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv")); + slides.push_back(test::ResourcePath("photo_1850_1110", "yuv")); + slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv")); + } + if (!screen_share_config.scrolling_params) { + // Cycle image every slide_change_interval seconds. + return test::CreateFromYuvFileFrameGenerator( + slides, video_config.width, video_config.height, + screen_share_config.slide_change_interval.seconds() * video_config.fps); + } + + TimeDelta pause_duration = screen_share_config.slide_change_interval - + screen_share_config.scrolling_params->duration; + RTC_DCHECK(pause_duration >= TimeDelta::Zero()); + return test::CreateScrollingInputFromYuvFilesFrameGenerator( + Clock::GetRealTimeClock(), slides, + screen_share_config.scrolling_params->source_width, + screen_share_config.scrolling_params->source_height, video_config.width, + video_config.height, screen_share_config.scrolling_params->duration.ms(), + pause_duration.ms()); +} + +} // namespace webrtc_pc_e2e +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/test/create_peer_connection_quality_test_frame_generator.h b/TMessagesProj/jni/voip/webrtc/api/test/create_peer_connection_quality_test_frame_generator.h new file mode 100644 index 000000000..ff8733120 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/test/create_peer_connection_quality_test_frame_generator.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef API_TEST_CREATE_PEER_CONNECTION_QUALITY_TEST_FRAME_GENERATOR_H_ +#define API_TEST_CREATE_PEER_CONNECTION_QUALITY_TEST_FRAME_GENERATOR_H_ + +#include +#include + +#include "absl/types/optional.h" +#include "api/test/frame_generator_interface.h" +#include "api/test/peerconnection_quality_test_fixture.h" + +namespace webrtc { +namespace webrtc_pc_e2e { + +// Creates a frame generator that produces frames with small squares that move +// randomly towards the lower right corner. |type| has the default value +// FrameGeneratorInterface::OutputType::I420. video_config specifies frame +// weight and height. +std::unique_ptr CreateSquareFrameGenerator( + const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config, + absl::optional type); + +// Creates a frame generator that plays frames from the yuv file. +std::unique_ptr CreateFromYuvFileFrameGenerator( + const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config, + std::string filename); + +// Creates a proper frame generator for testing screen sharing. +std::unique_ptr CreateScreenShareFrameGenerator( + const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config, + const PeerConnectionE2EQualityTestFixture::ScreenShareConfig& + screen_share_config); + +} // namespace webrtc_pc_e2e +} // namespace webrtc + +#endif // API_TEST_CREATE_PEER_CONNECTION_QUALITY_TEST_FRAME_GENERATOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/test/dummy_peer_connection.h b/TMessagesProj/jni/voip/webrtc/api/test/dummy_peer_connection.h index 0ca7d3f1b..4d17aeddd 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/dummy_peer_connection.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/dummy_peer_connection.h @@ -36,7 +36,7 @@ class DummyPeerConnection : public PeerConnectionInterface { bool AddStream(MediaStreamInterface* stream) override { return false; } void RemoveStream(MediaStreamInterface* stream) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } RTCErrorOr> AddTrack( @@ -100,17 +100,17 @@ class DummyPeerConnection : public PeerConnectionInterface { } void GetStats(RTCStatsCollectorCallback* callback) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } void GetStats( rtc::scoped_refptr selector, rtc::scoped_refptr callback) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } void GetStats( rtc::scoped_refptr selector, rtc::scoped_refptr callback) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } void ClearStatsCache() override {} @@ -145,33 +145,33 @@ class DummyPeerConnection : public PeerConnectionInterface { return nullptr; } - void RestartIce() override { FATAL() << "Not implemented"; } + void RestartIce() override { RTC_CHECK_NOTREACHED(); } // Create a new offer. // The CreateSessionDescriptionObserver callback will be called when done. void CreateOffer(CreateSessionDescriptionObserver* observer, const RTCOfferAnswerOptions& options) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } void CreateAnswer(CreateSessionDescriptionObserver* observer, const RTCOfferAnswerOptions& options) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } void SetLocalDescription(SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } void SetRemoteDescription(SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } void SetRemoteDescription( std::unique_ptr desc, rtc::scoped_refptr observer) override { - FATAL() << "Not implemented"; + RTC_CHECK_NOTREACHED(); } PeerConnectionInterface::RTCConfiguration GetConfiguration() override { @@ -194,10 +194,8 @@ class DummyPeerConnection : public PeerConnectionInterface { return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented"); } - void SetAudioPlayout(bool playout) override { FATAL() << "Not implemented"; } - void SetAudioRecording(bool recording) override { - FATAL() << "Not implemented"; - } + void SetAudioPlayout(bool playout) override { RTC_CHECK_NOTREACHED(); } + void SetAudioRecording(bool recording) override { RTC_CHECK_NOTREACHED(); } rtc::scoped_refptr LookupDtlsTransportByMid( const std::string& mid) override { @@ -235,7 +233,7 @@ class DummyPeerConnection : public PeerConnectionInterface { return false; } - void StopRtcEventLog() { FATAL() << "Not implemented"; } + void StopRtcEventLog() { RTC_CHECK_NOTREACHED(); } void Close() override {} diff --git a/TMessagesProj/jni/voip/webrtc/api/test/frame_generator_interface.cc b/TMessagesProj/jni/voip/webrtc/api/test/frame_generator_interface.cc new file mode 100644 index 000000000..356fe3af5 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/test/frame_generator_interface.cc @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 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 "api/test/frame_generator_interface.h" + +namespace webrtc { +namespace test { + +// static +const char* FrameGeneratorInterface::OutputTypeToString( + FrameGeneratorInterface::OutputType type) { + switch (type) { + case OutputType::kI420: + return "I420"; + case OutputType::kI420A: + return "I420A"; + case OutputType::kI010: + return "I010"; + case OutputType::kNV12: + return "NV12"; + default: + RTC_NOTREACHED(); + } +} + +} // namespace test +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/test/frame_generator_interface.h b/TMessagesProj/jni/voip/webrtc/api/test/frame_generator_interface.h index 691b6ee3f..90e60deba 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/frame_generator_interface.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/frame_generator_interface.h @@ -32,7 +32,8 @@ class FrameGeneratorInterface { absl::optional update_rect; }; - enum class OutputType { kI420, kI420A, kI010 }; + enum class OutputType { kI420, kI420A, kI010, kNV12 }; + static const char* OutputTypeToString(OutputType type); virtual ~FrameGeneratorInterface() = default; diff --git a/TMessagesProj/jni/voip/webrtc/api/test/mock_data_channel.h b/TMessagesProj/jni/voip/webrtc/api/test/mock_data_channel.h new file mode 100644 index 000000000..9346ffd63 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/test/mock_data_channel.h @@ -0,0 +1,60 @@ +/* + * Copyright 2020 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. + */ + +#ifndef API_TEST_MOCK_DATA_CHANNEL_H_ +#define API_TEST_MOCK_DATA_CHANNEL_H_ + +#include + +#include "api/data_channel_interface.h" +#include "test/gmock.h" + +namespace webrtc { + +class MockDataChannelInterface final + : public rtc::RefCountedObject { + public: + static rtc::scoped_refptr Create() { + return new MockDataChannelInterface(); + } + + MOCK_METHOD(void, + RegisterObserver, + (DataChannelObserver * observer), + (override)); + MOCK_METHOD(void, UnregisterObserver, (), (override)); + MOCK_METHOD(std::string, label, (), (const, override)); + MOCK_METHOD(bool, reliable, (), (const, override)); + MOCK_METHOD(bool, ordered, (), (const, override)); + MOCK_METHOD(uint16_t, maxRetransmitTime, (), (const, override)); + MOCK_METHOD(uint16_t, maxRetransmits, (), (const, override)); + MOCK_METHOD(absl::optional, maxRetransmitsOpt, (), (const, override)); + MOCK_METHOD(absl::optional, maxPacketLifeTime, (), (const, override)); + MOCK_METHOD(std::string, protocol, (), (const, override)); + MOCK_METHOD(bool, negotiated, (), (const, override)); + MOCK_METHOD(int, id, (), (const, override)); + MOCK_METHOD(Priority, priority, (), (const, override)); + MOCK_METHOD(DataState, state, (), (const, override)); + MOCK_METHOD(RTCError, error, (), (const, override)); + MOCK_METHOD(uint32_t, messages_sent, (), (const, override)); + MOCK_METHOD(uint64_t, bytes_sent, (), (const, override)); + MOCK_METHOD(uint32_t, messages_received, (), (const, override)); + MOCK_METHOD(uint64_t, bytes_received, (), (const, override)); + MOCK_METHOD(uint64_t, buffered_amount, (), (const, override)); + MOCK_METHOD(void, Close, (), (override)); + MOCK_METHOD(bool, Send, (const DataBuffer& buffer), (override)); + + protected: + MockDataChannelInterface() = default; +}; + +} // namespace webrtc + +#endif // API_TEST_MOCK_DATA_CHANNEL_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/test/mock_media_stream_interface.h b/TMessagesProj/jni/voip/webrtc/api/test/mock_media_stream_interface.h new file mode 100644 index 000000000..29521e6e2 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/test/mock_media_stream_interface.h @@ -0,0 +1,89 @@ +/* + * Copyright 2020 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. + */ + +#ifndef API_TEST_MOCK_MEDIA_STREAM_INTERFACE_H_ +#define API_TEST_MOCK_MEDIA_STREAM_INTERFACE_H_ + +#include + +#include "api/media_stream_interface.h" +#include "test/gmock.h" + +namespace webrtc { + +class MockAudioSource final + : public rtc::RefCountedObject { + public: + static rtc::scoped_refptr Create() { + return new MockAudioSource(); + } + + MOCK_METHOD(void, + RegisterObserver, + (ObserverInterface * observer), + (override)); + MOCK_METHOD(void, + UnregisterObserver, + (ObserverInterface * observer), + (override)); + MOCK_METHOD(SourceState, state, (), (const, override)); + MOCK_METHOD(bool, remote, (), (const, override)); + MOCK_METHOD(void, SetVolume, (double volume), (override)); + MOCK_METHOD(void, + RegisterAudioObserver, + (AudioObserver * observer), + (override)); + MOCK_METHOD(void, + UnregisterAudioObserver, + (AudioObserver * observer), + (override)); + MOCK_METHOD(void, AddSink, (AudioTrackSinkInterface * sink), (override)); + MOCK_METHOD(void, RemoveSink, (AudioTrackSinkInterface * sink), (override)); + MOCK_METHOD(const cricket::AudioOptions, options, (), (const, override)); + + private: + MockAudioSource() = default; +}; + +class MockAudioTrack final : public rtc::RefCountedObject { + public: + static rtc::scoped_refptr Create() { + return new MockAudioTrack(); + } + + MOCK_METHOD(void, + RegisterObserver, + (ObserverInterface * observer), + (override)); + MOCK_METHOD(void, + UnregisterObserver, + (ObserverInterface * observer), + (override)); + MOCK_METHOD(std::string, kind, (), (const, override)); + MOCK_METHOD(std::string, id, (), (const override)); + MOCK_METHOD(bool, enabled, (), (const, override)); + MOCK_METHOD(bool, set_enabled, (bool enable), (override)); + MOCK_METHOD(TrackState, state, (), (const, override)); + MOCK_METHOD(AudioSourceInterface*, GetSource, (), (const, override)); + MOCK_METHOD(void, AddSink, (AudioTrackSinkInterface * sink), (override)); + MOCK_METHOD(void, RemoveSink, (AudioTrackSinkInterface * sink), (override)); + MOCK_METHOD(bool, GetSignalLevel, (int* level), (override)); + MOCK_METHOD(rtc::scoped_refptr, + GetAudioProcessor, + (), + (override)); + + private: + MockAudioTrack() = default; +}; + +} // namespace webrtc + +#endif // API_TEST_MOCK_MEDIA_STREAM_INTERFACE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/test/mock_peer_connection_factory_interface.h b/TMessagesProj/jni/voip/webrtc/api/test/mock_peer_connection_factory_interface.h index 19c3f4063..7319cebbc 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/mock_peer_connection_factory_interface.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/mock_peer_connection_factory_interface.h @@ -22,7 +22,7 @@ namespace webrtc { class MockPeerConnectionFactoryInterface final : public rtc::RefCountedObject { public: - rtc::scoped_refptr Create() { + static rtc::scoped_refptr Create() { return new MockPeerConnectionFactoryInterface(); } diff --git a/TMessagesProj/jni/voip/webrtc/api/test/mock_rtp_transceiver.h b/TMessagesProj/jni/voip/webrtc/api/test/mock_rtp_transceiver.h new file mode 100644 index 000000000..a0a08c477 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/test/mock_rtp_transceiver.h @@ -0,0 +1,85 @@ +/* + * Copyright 2020 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. + */ + +#ifndef API_TEST_MOCK_RTP_TRANSCEIVER_H_ +#define API_TEST_MOCK_RTP_TRANSCEIVER_H_ + +#include +#include + +#include "api/rtp_transceiver_interface.h" +#include "test/gmock.h" + +namespace webrtc { + +class MockRtpTransceiver final + : public rtc::RefCountedObject { + public: + static rtc::scoped_refptr Create() { + return new MockRtpTransceiver(); + } + + MOCK_METHOD(cricket::MediaType, media_type, (), (const, override)); + MOCK_METHOD(absl::optional, mid, (), (const, override)); + MOCK_METHOD(rtc::scoped_refptr, + sender, + (), + (const, override)); + MOCK_METHOD(rtc::scoped_refptr, + receiver, + (), + (const, override)); + MOCK_METHOD(bool, stopped, (), (const, override)); + MOCK_METHOD(bool, stopping, (), (const, override)); + MOCK_METHOD(RtpTransceiverDirection, direction, (), (const, override)); + MOCK_METHOD(void, + SetDirection, + (RtpTransceiverDirection new_direction), + (override)); + MOCK_METHOD(RTCError, + SetDirectionWithError, + (RtpTransceiverDirection new_direction), + (override)); + MOCK_METHOD(absl::optional, + current_direction, + (), + (const, override)); + MOCK_METHOD(absl::optional, + fired_direction, + (), + (const, override)); + MOCK_METHOD(RTCError, StopStandard, (), (override)); + MOCK_METHOD(void, StopInternal, (), (override)); + MOCK_METHOD(void, Stop, (), (override)); + MOCK_METHOD(RTCError, + SetCodecPreferences, + (rtc::ArrayView codecs), + (override)); + MOCK_METHOD(std::vector, + codec_preferences, + (), + (const, override)); + MOCK_METHOD(std::vector, + HeaderExtensionsToOffer, + (), + (const, override)); + MOCK_METHOD(webrtc::RTCError, + SetOfferedRtpHeaderExtensions, + (rtc::ArrayView + header_extensions_to_offer), + (override)); + + private: + MockRtpTransceiver() = default; +}; + +} // namespace webrtc + +#endif // API_TEST_MOCK_RTP_TRANSCEIVER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/test/neteq_simulator_factory.cc b/TMessagesProj/jni/voip/webrtc/api/test/neteq_simulator_factory.cc index ea5be8517..82b27e546 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/neteq_simulator_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/api/test/neteq_simulator_factory.cc @@ -21,6 +21,24 @@ namespace webrtc { namespace test { +namespace { +NetEqTestFactory::Config convertConfig( + const NetEqSimulatorFactory::Config& simulation_config, + absl::string_view replacement_audio_filename) { + NetEqTestFactory::Config config; + config.replacement_audio_file = std::string(replacement_audio_filename); + config.max_nr_packets_in_buffer = simulation_config.max_nr_packets_in_buffer; + config.initial_dummy_packets = simulation_config.initial_dummy_packets; + config.skip_get_audio_events = simulation_config.skip_get_audio_events; + config.field_trial_string = simulation_config.field_trial_string; + config.output_audio_filename = simulation_config.output_audio_filename; + config.pythonplot = simulation_config.python_plot_filename.has_value(); + config.plot_scripts_basename = simulation_config.python_plot_filename; + config.textlog = simulation_config.text_log_filename.has_value(); + config.textlog_filename = simulation_config.text_log_filename; + return config; +} +} // namespace NetEqSimulatorFactory::NetEqSimulatorFactory() : factory_(std::make_unique()) {} @@ -31,13 +49,8 @@ std::unique_ptr NetEqSimulatorFactory::CreateSimulatorFromFile( absl::string_view event_log_filename, absl::string_view replacement_audio_filename, Config simulation_config) { - NetEqTestFactory::Config config; - config.replacement_audio_file = std::string(replacement_audio_filename); - config.max_nr_packets_in_buffer = simulation_config.max_nr_packets_in_buffer; - config.initial_dummy_packets = simulation_config.initial_dummy_packets; - config.skip_get_audio_events = simulation_config.skip_get_audio_events; - config.field_trial_string = simulation_config.field_trial_string; - config.output_audio_filename = simulation_config.output_audio_filename; + NetEqTestFactory::Config config = + convertConfig(simulation_config, replacement_audio_filename); return factory_->InitializeTestFromFile( std::string(event_log_filename), simulation_config.neteq_factory, config); } @@ -47,12 +60,8 @@ NetEqSimulatorFactory::CreateSimulatorFromString( absl::string_view event_log_file_contents, absl::string_view replacement_audio_filename, Config simulation_config) { - NetEqTestFactory::Config config; - config.replacement_audio_file = std::string(replacement_audio_filename); - config.max_nr_packets_in_buffer = simulation_config.max_nr_packets_in_buffer; - config.initial_dummy_packets = simulation_config.initial_dummy_packets; - config.skip_get_audio_events = simulation_config.skip_get_audio_events; - config.field_trial_string = simulation_config.field_trial_string; + NetEqTestFactory::Config config = + convertConfig(simulation_config, replacement_audio_filename); return factory_->InitializeTestFromString( std::string(event_log_file_contents), simulation_config.neteq_factory, config); diff --git a/TMessagesProj/jni/voip/webrtc/api/test/neteq_simulator_factory.h b/TMessagesProj/jni/voip/webrtc/api/test/neteq_simulator_factory.h index b3c77b140..2a716e665 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/neteq_simulator_factory.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/neteq_simulator_factory.h @@ -44,6 +44,10 @@ class NetEqSimulatorFactory { std::string field_trial_string; // A filename for the generated output audio file. absl::optional output_audio_filename; + // A filename for the python plot. + absl::optional python_plot_filename; + // A filename for the text log. + absl::optional text_log_filename; // A custom NetEqFactory can be used. NetEqFactory* neteq_factory = nullptr; }; diff --git a/TMessagesProj/jni/voip/webrtc/api/test/network_emulation/network_emulation_interfaces.h b/TMessagesProj/jni/voip/webrtc/api/test/network_emulation/network_emulation_interfaces.h index db1f9ada6..36fb99654 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/network_emulation/network_emulation_interfaces.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/network_emulation/network_emulation_interfaces.h @@ -16,6 +16,7 @@ #include "absl/types/optional.h" #include "api/array_view.h" +#include "api/numerics/samples_stats_counter.h" #include "api/units/data_rate.h" #include "api/units/data_size.h" #include "api/units/timestamp.h" @@ -69,6 +70,12 @@ class EmulatedNetworkOutgoingStats { virtual DataSize BytesSent() const = 0; + // Returns the timestamped sizes of all sent packets if + // EmulatedEndpointConfig::stats_gatherming_mode was set to + // StatsGatheringMode::kDebug; otherwise, the returned value will be empty. + // Returned reference is valid until the next call to a non-const method. + virtual const SamplesStatsCounter& SentPacketsSizeCounter() const = 0; + virtual DataSize FirstSentPacketSize() const = 0; // Returns time of the first packet sent or infinite value if no packets were @@ -91,10 +98,21 @@ class EmulatedNetworkIncomingStats { virtual int64_t PacketsReceived() const = 0; // Total amount of bytes in received packets. virtual DataSize BytesReceived() const = 0; + // Returns the timestamped sizes of all received packets if + // EmulatedEndpointConfig::stats_gatherming_mode was set to + // StatsGatheringMode::kDebug; otherwise, the returned value will be empty. + // Returned reference is valid until the next call to a non-const method. + virtual const SamplesStatsCounter& ReceivedPacketsSizeCounter() const = 0; // Total amount of packets that were received, but no destination was found. virtual int64_t PacketsDropped() const = 0; // Total amount of bytes in dropped packets. virtual DataSize BytesDropped() const = 0; + // Returns the timestamped sizes of all packets that were received, + // but no destination was found if + // EmulatedEndpointConfig::stats_gatherming_mode was set to + // StatsGatheringMode::kDebug; otherwise, the returned value will be empty. + // Returned reference is valid until the next call to a non-const method. + virtual const SamplesStatsCounter& DroppedPacketsSizeCounter() const = 0; virtual DataSize FirstReceivedPacketSize() const = 0; @@ -120,6 +138,17 @@ class EmulatedNetworkStats { virtual int64_t PacketsSent() const = 0; virtual DataSize BytesSent() const = 0; + // Returns the timestamped sizes of all sent packets if + // EmulatedEndpointConfig::stats_gatherming_mode was set to + // StatsGatheringMode::kDebug; otherwise, the returned value will be empty. + // Returned reference is valid until the next call to a non-const method. + virtual const SamplesStatsCounter& SentPacketsSizeCounter() const = 0; + // Returns the timestamped duration between packet was received on + // network interface and was dispatched to the network in microseconds if + // EmulatedEndpointConfig::stats_gatherming_mode was set to + // StatsGatheringMode::kDebug; otherwise, the returned value will be empty. + // Returned reference is valid until the next call to a non-const method. + virtual const SamplesStatsCounter& SentPacketsQueueWaitTimeUs() const = 0; virtual DataSize FirstSentPacketSize() const = 0; // Returns time of the first packet sent or infinite value if no packets were @@ -134,10 +163,21 @@ class EmulatedNetworkStats { virtual int64_t PacketsReceived() const = 0; // Total amount of bytes in received packets. virtual DataSize BytesReceived() const = 0; + // Returns the timestamped sizes of all received packets if + // EmulatedEndpointConfig::stats_gatherming_mode was set to + // StatsGatheringMode::kDebug; otherwise, the returned value will be empty. + // Returned reference is valid until the next call to a non-const method. + virtual const SamplesStatsCounter& ReceivedPacketsSizeCounter() const = 0; // Total amount of packets that were received, but no destination was found. virtual int64_t PacketsDropped() const = 0; // Total amount of bytes in dropped packets. virtual DataSize BytesDropped() const = 0; + // Returns counter with timestamped sizes of all packets that were received, + // but no destination was found if + // EmulatedEndpointConfig::stats_gatherming_mode was set to + // StatsGatheringMode::kDebug; otherwise, the returned value will be empty. + // Returned reference is valid until the next call to a non-const method. + virtual const SamplesStatsCounter& DroppedPacketsSizeCounter() const = 0; virtual DataSize FirstReceivedPacketSize() const = 0; // Returns time of the first packet received or infinite value if no packets @@ -159,7 +199,8 @@ class EmulatedNetworkStats { }; // EmulatedEndpoint is an abstraction for network interface on device. Instances -// of this are created by NetworkEmulationManager::CreateEndpoint. +// of this are created by NetworkEmulationManager::CreateEndpoint and +// thread safe. class EmulatedEndpoint : public EmulatedNetworkReceiverInterface { public: // Send packet into network. diff --git a/TMessagesProj/jni/voip/webrtc/api/test/network_emulation_manager.h b/TMessagesProj/jni/voip/webrtc/api/test/network_emulation_manager.h index 90441e4f2..8619f3630 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/network_emulation_manager.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/network_emulation_manager.h @@ -13,6 +13,7 @@ #include #include +#include #include #include "api/array_view.h" @@ -46,6 +47,13 @@ class EmulatedRoute; struct EmulatedEndpointConfig { enum class IpAddressFamily { kIpv4, kIpv6 }; + enum class StatsGatheringMode { + // Gather main network stats counters. + kDefault, + // kDefault + also gather per packet statistics. In this mode more memory + // will be used. + kDebug + }; IpAddressFamily generated_ip_family = IpAddressFamily::kIpv4; // If specified will be used as IP address for endpoint node. Must be unique @@ -56,8 +64,40 @@ struct EmulatedEndpointConfig { bool start_as_enabled = true; // Network type which will be used to represent endpoint to WebRTC. rtc::AdapterType type = rtc::AdapterType::ADAPTER_TYPE_UNKNOWN; + StatsGatheringMode stats_gathering_mode = StatsGatheringMode::kDefault; }; +struct EmulatedTURNServerConfig { + EmulatedEndpointConfig client_config; + EmulatedEndpointConfig peer_config; +}; + +// EmulatedTURNServer is an abstraction for a TURN server. +class EmulatedTURNServerInterface { + public: + struct IceServerConfig { + std::string username; + std::string password; + std::string url; + }; + + virtual ~EmulatedTURNServerInterface() {} + + // Get an IceServer configuration suitable to add to a PeerConnection. + virtual IceServerConfig GetIceServerConfig() const = 0; + + // Get non-null client endpoint, an endpoint that accepts TURN allocations. + // This shall typically be connected to one or more webrtc endpoint. + virtual EmulatedEndpoint* GetClientEndpoint() const = 0; + + // Returns socket address, which client should use to connect to TURN server + // and do TURN allocation. + virtual rtc::SocketAddress GetClientEndpointAddress() const = 0; + + // Get non-null peer endpoint, that is "connected to the internet". + // This shall typically be connected to another TURN server. + virtual EmulatedEndpoint* GetPeerEndpoint() const = 0; +}; // Provide interface to obtain all required objects to inject network emulation // layer into PeerConnection. Also contains information about network interfaces @@ -79,7 +119,8 @@ class EmulatedNetworkManagerInterface { virtual std::vector endpoints() const = 0; // Passes summarized network stats for endpoints for this manager into - // specified |stats_callback|. + // specified |stats_callback|. Callback will be executed on network emulation + // internal task queue. virtual void GetStats( std::function)> stats_callback) const = 0; @@ -194,12 +235,20 @@ class NetworkEmulationManager { CreateEmulatedNetworkManagerInterface( const std::vector& endpoints) = 0; - // Passes summarized network stats for specified |endpoints| into specifield - // |stats_callback|. + // Passes summarized network stats for specified |endpoints| into specified + // |stats_callback|. Callback will be executed on network emulation + // internal task queue. virtual void GetStats( rtc::ArrayView endpoints, std::function)> stats_callback) = 0; + + // Create a EmulatedTURNServer. + // The TURN server has 2 endpoints that need to be connected with routes, + // - GetClientEndpoint() - the endpoint that accepts TURN allocations. + // - GetPeerEndpoint() - the endpoint that is "connected to the internet". + virtual EmulatedTURNServerInterface* CreateTURNServer( + EmulatedTURNServerConfig config) = 0; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/test/simulcast_test_fixture.h b/TMessagesProj/jni/voip/webrtc/api/test/simulcast_test_fixture.h index 5270d1330..cd470703c 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/simulcast_test_fixture.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/simulcast_test_fixture.h @@ -34,6 +34,8 @@ class SimulcastTestFixture { virtual void TestSpatioTemporalLayers321PatternEncoder() = 0; virtual void TestStrideEncodeDecode() = 0; virtual void TestDecodeWidthHeightSet() = 0; + virtual void + TestEncoderInfoForDefaultTemporalLayerProfileHasFpsAllocation() = 0; }; } // namespace test diff --git a/TMessagesProj/jni/voip/webrtc/api/test/videocodec_test_fixture.h b/TMessagesProj/jni/voip/webrtc/api/test/videocodec_test_fixture.h index 2ed40910b..395c5cb80 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/videocodec_test_fixture.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/videocodec_test_fixture.h @@ -138,6 +138,9 @@ class VideoCodecTestFixture { bool save_encoded_ivf = false; bool save_decoded_y4m = false; } visualization_params; + + // Enables quality analysis for dropped frames. + bool analyze_quality_of_dropped_frames = false; }; virtual ~VideoCodecTestFixture() = default; diff --git a/TMessagesProj/jni/voip/webrtc/api/test/videocodec_test_stats.h b/TMessagesProj/jni/voip/webrtc/api/test/videocodec_test_stats.h index 63e15768d..df1aed73a 100644 --- a/TMessagesProj/jni/voip/webrtc/api/test/videocodec_test_stats.h +++ b/TMessagesProj/jni/voip/webrtc/api/test/videocodec_test_stats.h @@ -67,6 +67,7 @@ class VideoCodecTestStats { int qp = -1; // Quality. + bool quality_analysis_successful = false; float psnr_y = 0.0f; float psnr_u = 0.0f; float psnr_v = 0.0f; diff --git a/TMessagesProj/jni/voip/webrtc/api/transport/network_control.h b/TMessagesProj/jni/voip/webrtc/api/transport/network_control.h index 6fc1f7c0d..c2b005e71 100644 --- a/TMessagesProj/jni/voip/webrtc/api/transport/network_control.h +++ b/TMessagesProj/jni/voip/webrtc/api/transport/network_control.h @@ -61,42 +61,42 @@ class NetworkControllerInterface { virtual ~NetworkControllerInterface() = default; // Called when network availabilty changes. - virtual NetworkControlUpdate OnNetworkAvailability(NetworkAvailability) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkAvailability( + NetworkAvailability) = 0; // Called when the receiving or sending endpoint changes address. - virtual NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkRouteChange( + NetworkRouteChange) = 0; // Called periodically with a periodicy as specified by // NetworkControllerFactoryInterface::GetProcessInterval. - virtual NetworkControlUpdate OnProcessInterval(ProcessInterval) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnProcessInterval( + ProcessInterval) = 0; // Called when remotely calculated bitrate is received. - virtual NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnRemoteBitrateReport( + RemoteBitrateReport) = 0; // Called round trip time has been calculated by protocol specific mechanisms. - virtual NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnRoundTripTimeUpdate( + RoundTripTimeUpdate) = 0; // Called when a packet is sent on the network. - virtual NetworkControlUpdate OnSentPacket(SentPacket) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnSentPacket( + SentPacket) = 0; // Called when a packet is received from the remote client. - virtual NetworkControlUpdate OnReceivedPacket(ReceivedPacket) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnReceivedPacket( + ReceivedPacket) = 0; // Called when the stream specific configuration has been updated. - virtual NetworkControlUpdate OnStreamsConfig(StreamsConfig) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnStreamsConfig( + StreamsConfig) = 0; // Called when target transfer rate constraints has been changed. - virtual NetworkControlUpdate OnTargetRateConstraints(TargetRateConstraints) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTargetRateConstraints( + TargetRateConstraints) = 0; // Called when a protocol specific calculation of packet loss has been made. - virtual NetworkControlUpdate OnTransportLossReport(TransportLossReport) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTransportLossReport( + TransportLossReport) = 0; // Called with per packet feedback regarding receive time. - virtual NetworkControlUpdate OnTransportPacketsFeedback( - TransportPacketsFeedback) ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTransportPacketsFeedback( + TransportPacketsFeedback) = 0; // Called with network state estimate updates. - virtual NetworkControlUpdate OnNetworkStateEstimate(NetworkStateEstimate) - ABSL_MUST_USE_RESULT = 0; + ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkStateEstimate( + NetworkStateEstimate) = 0; }; // NetworkControllerFactoryInterface is an interface for creating a network diff --git a/TMessagesProj/jni/voip/webrtc/api/transport/sctp_transport_factory_interface.h b/TMessagesProj/jni/voip/webrtc/api/transport/sctp_transport_factory_interface.h new file mode 100644 index 000000000..912be3a37 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/transport/sctp_transport_factory_interface.h @@ -0,0 +1,42 @@ +/* + * Copyright 2020 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. + */ + +#ifndef API_TRANSPORT_SCTP_TRANSPORT_FACTORY_INTERFACE_H_ +#define API_TRANSPORT_SCTP_TRANSPORT_FACTORY_INTERFACE_H_ + +#include + +// These classes are not part of the API, and are treated as opaque pointers. +namespace cricket { +class SctpTransportInternal; +} // namespace cricket + +namespace rtc { +class PacketTransportInternal; +} // namespace rtc + +namespace webrtc { + +// Factory class which can be used to allow fake SctpTransports to be injected +// for testing. An application is not intended to implement this interface nor +// 'cricket::SctpTransportInternal' because SctpTransportInternal is not +// guaranteed to remain stable in future WebRTC versions. +class SctpTransportFactoryInterface { + public: + virtual ~SctpTransportFactoryInterface() = default; + + // Create an SCTP transport using |channel| for the underlying transport. + virtual std::unique_ptr CreateSctpTransport( + rtc::PacketTransportInternal* channel) = 0; +}; + +} // namespace webrtc + +#endif // API_TRANSPORT_SCTP_TRANSPORT_FACTORY_INTERFACE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/transport/stun.cc b/TMessagesProj/jni/voip/webrtc/api/transport/stun.cc index b083f1583..c3f589a69 100644 --- a/TMessagesProj/jni/voip/webrtc/api/transport/stun.cc +++ b/TMessagesProj/jni/voip/webrtc/api/transport/stun.cc @@ -11,8 +11,9 @@ #include "api/transport/stun.h" #include - #include +#include +#include #include #include @@ -25,8 +26,14 @@ using rtc::ByteBufferReader; using rtc::ByteBufferWriter; +namespace cricket { + namespace { +const int k127Utf8CharactersLengthInBytes = 508; +const int kDefaultMaxAttributeLength = 508; +const int kMessageIntegrityAttributeLength = 20; + uint32_t ReduceTransactionId(const std::string& transaction_id) { RTC_DCHECK(transaction_id.length() == cricket::kStunTransactionIdLength || transaction_id.length() == @@ -40,9 +47,46 @@ uint32_t ReduceTransactionId(const std::string& transaction_id) { return result; } -} // namespace +// Check the maximum length of a BYTE_STRING attribute against specifications. +bool LengthValid(int type, int length) { + // "Less than 509 bytes" is intended to indicate a maximum of 127 + // UTF-8 characters, which may take up to 4 bytes per character. + switch (type) { + case STUN_ATTR_USERNAME: + return length <= + k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.3 + case STUN_ATTR_MESSAGE_INTEGRITY: + return length == + kMessageIntegrityAttributeLength; // RFC 8489 section 14.5 + case STUN_ATTR_REALM: + return length <= + k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.9 + case STUN_ATTR_NONCE: + return length <= + k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.10 + case STUN_ATTR_SOFTWARE: + return length <= + k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.14 + case STUN_ATTR_ORIGIN: + // 0x802F is unassigned by IANA. + // RESPONSE-ORIGIN is defined in RFC 5780 section 7.3, but does not + // specify a maximum length. It's an URL, so return an arbitrary + // restriction. + return length <= kDefaultMaxAttributeLength; + case STUN_ATTR_DATA: + // No length restriction in RFC; it's the content of an UDP datagram, + // which in theory can be up to 65.535 bytes. + // TODO(bugs.webrtc.org/12179): Write a test to find the real limit. + return length <= 65535; + default: + // Return an arbitrary restriction for all other types. + return length <= kDefaultMaxAttributeLength; + } + RTC_NOTREACHED(); + return true; +} -namespace cricket { +} // namespace const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[] = "Try Alternate Server"; const char STUN_ERROR_REASON_BAD_REQUEST[] = "Bad Request"; @@ -555,7 +599,7 @@ StunAttributeValueType StunMessage::GetAttributeValueType(int type) const { return STUN_VALUE_BYTE_STRING; case STUN_ATTR_RETRANSMIT_COUNT: return STUN_VALUE_UINT32; - case STUN_ATTR_LAST_ICE_CHECK_RECEIVED: + case STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED: return STUN_VALUE_BYTE_STRING; case STUN_ATTR_GOOG_MISC_INFO: return STUN_VALUE_UINT16_LIST; @@ -993,6 +1037,10 @@ bool StunByteStringAttribute::Read(ByteBufferReader* buf) { } bool StunByteStringAttribute::Write(ByteBufferWriter* buf) const { + // Check that length is legal according to specs + if (!LengthValid(type(), length())) { + return false; + } buf->WriteBytes(bytes_, length()); WritePadding(buf); return true; @@ -1309,7 +1357,7 @@ StunMessage* TurnMessage::CreateNew() const { StunAttributeValueType IceMessage::GetAttributeValueType(int type) const { switch (type) { case STUN_ATTR_PRIORITY: - case STUN_ATTR_NETWORK_INFO: + case STUN_ATTR_GOOG_NETWORK_INFO: case STUN_ATTR_NOMINATION: return STUN_VALUE_UINT32; case STUN_ATTR_USE_CANDIDATE: diff --git a/TMessagesProj/jni/voip/webrtc/api/transport/stun.h b/TMessagesProj/jni/voip/webrtc/api/transport/stun.h index 51ca30653..8893b2a1f 100644 --- a/TMessagesProj/jni/voip/webrtc/api/transport/stun.h +++ b/TMessagesProj/jni/voip/webrtc/api/transport/stun.h @@ -16,11 +16,13 @@ #include #include - +#include #include #include #include +#include "absl/strings/string_view.h" +#include "api/array_view.h" #include "rtc_base/byte_buffer.h" #include "rtc_base/ip_address.h" #include "rtc_base/socket_address.h" @@ -133,7 +135,6 @@ class StunAddressAttribute; class StunAttribute; class StunByteStringAttribute; class StunErrorCodeAttribute; - class StunUInt16ListAttribute; class StunUInt32Attribute; class StunUInt64Attribute; @@ -667,11 +668,16 @@ enum IceAttributeType { STUN_ATTR_NOMINATION = 0xC001, // UInt32 // UInt32. The higher 16 bits are the network ID. The lower 16 bits are the // network cost. - STUN_ATTR_NETWORK_INFO = 0xC057, + STUN_ATTR_GOOG_NETWORK_INFO = 0xC057, // Experimental: Transaction ID of the last connectivity check received. - STUN_ATTR_LAST_ICE_CHECK_RECEIVED = 0xC058, + STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED = 0xC058, // Uint16List. Miscellaneous attributes for future extension. STUN_ATTR_GOOG_MISC_INFO = 0xC059, + // Obsolete. + STUN_ATTR_GOOG_OBSOLETE_1 = 0xC05A, + STUN_ATTR_GOOG_CONNECTION_ID = 0xC05B, // Not yet implemented. + STUN_ATTR_GOOG_DELTA = 0xC05C, // Not yet implemented. + STUN_ATTR_GOOG_DELTA_ACK = 0xC05D, // Not yet implemented. // MESSAGE-INTEGRITY truncated to 32-bit. STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32 = 0xC060, }; diff --git a/TMessagesProj/jni/voip/webrtc/api/uma_metrics.h b/TMessagesProj/jni/voip/webrtc/api/uma_metrics.h index 8436d4f9e..30543b68b 100644 --- a/TMessagesProj/jni/voip/webrtc/api/uma_metrics.h +++ b/TMessagesProj/jni/voip/webrtc/api/uma_metrics.h @@ -8,42 +8,34 @@ * be found in the AUTHORS file in the root of the source tree. */ -// This file contains enums related to IPv4/IPv6 metrics. +// This file contains enums related to Chrome UMA histograms. See +// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#requirements +// for requirements when adding or changing metrics. #ifndef API_UMA_METRICS_H_ #define API_UMA_METRICS_H_ -#include "rtc_base/ref_count.h" - namespace webrtc { -// Currently this contains information related to WebRTC network/transport -// information. - -// The difference between PeerConnectionEnumCounter and -// PeerConnectionMetricsName is that the "EnumCounter" is only counting the -// occurrences of events, while "Name" has a value associated with it which is -// used to form a histogram. - -// This enum is backed by Chromium's histograms.xml, -// chromium/src/tools/metrics/histograms/histograms.xml -// Existing values cannot be re-ordered and new enums must be added -// before kBoundary. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum PeerConnectionAddressFamilyCounter { - kPeerConnection_IPv4, - kPeerConnection_IPv6, - kBestConnections_IPv4, - kBestConnections_IPv6, - kPeerConnectionAddressFamilyCounter_Max, + kPeerConnection_IPv4 = 0, + kPeerConnection_IPv6 = 1, + kBestConnections_IPv4 = 2, + kBestConnections_IPv6 = 3, + kPeerConnectionAddressFamilyCounter_Max }; // This enum defines types for UMA samples, which will have a range. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum PeerConnectionMetricsName { - kNetworkInterfaces_IPv4, // Number of IPv4 interfaces. - kNetworkInterfaces_IPv6, // Number of IPv6 interfaces. - kTimeToConnect, // In milliseconds. - kLocalCandidates_IPv4, // Number of IPv4 local candidates. - kLocalCandidates_IPv6, // Number of IPv6 local candidates. + kNetworkInterfaces_IPv4 = 0, // Number of IPv4 interfaces. + kNetworkInterfaces_IPv6 = 1, // Number of IPv6 interfaces. + kTimeToConnect = 2, // In milliseconds. + kLocalCandidates_IPv4 = 3, // Number of IPv4 local candidates. + kLocalCandidates_IPv6 = 4, // Number of IPv6 local candidates. kPeerConnectionMetricsName_Max }; @@ -51,109 +43,134 @@ enum PeerConnectionMetricsName { // _. It is recorded based on the // type of candidate pair used when the PeerConnection first goes to a completed // state. When BUNDLE is enabled, only the first transport gets recorded. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum IceCandidatePairType { // HostHost is deprecated. It was replaced with the set of types at the bottom // to report private or public host IP address. - kIceCandidatePairHostHost, - kIceCandidatePairHostSrflx, - kIceCandidatePairHostRelay, - kIceCandidatePairHostPrflx, - kIceCandidatePairSrflxHost, - kIceCandidatePairSrflxSrflx, - kIceCandidatePairSrflxRelay, - kIceCandidatePairSrflxPrflx, - kIceCandidatePairRelayHost, - kIceCandidatePairRelaySrflx, - kIceCandidatePairRelayRelay, - kIceCandidatePairRelayPrflx, - kIceCandidatePairPrflxHost, - kIceCandidatePairPrflxSrflx, - kIceCandidatePairPrflxRelay, + kIceCandidatePairHostHost = 0, + kIceCandidatePairHostSrflx = 1, + kIceCandidatePairHostRelay = 2, + kIceCandidatePairHostPrflx = 3, + kIceCandidatePairSrflxHost = 4, + kIceCandidatePairSrflxSrflx = 5, + kIceCandidatePairSrflxRelay = 6, + kIceCandidatePairSrflxPrflx = 7, + kIceCandidatePairRelayHost = 8, + kIceCandidatePairRelaySrflx = 9, + kIceCandidatePairRelayRelay = 10, + kIceCandidatePairRelayPrflx = 11, + kIceCandidatePairPrflxHost = 12, + kIceCandidatePairPrflxSrflx = 13, + kIceCandidatePairPrflxRelay = 14, // The following 9 types tell whether local and remote hosts have hostname, // private or public IP addresses. - kIceCandidatePairHostPrivateHostPrivate, - kIceCandidatePairHostPrivateHostPublic, - kIceCandidatePairHostPublicHostPrivate, - kIceCandidatePairHostPublicHostPublic, - kIceCandidatePairHostNameHostName, - kIceCandidatePairHostNameHostPrivate, - kIceCandidatePairHostNameHostPublic, - kIceCandidatePairHostPrivateHostName, - kIceCandidatePairHostPublicHostName, + kIceCandidatePairHostPrivateHostPrivate = 15, + kIceCandidatePairHostPrivateHostPublic = 16, + kIceCandidatePairHostPublicHostPrivate = 17, + kIceCandidatePairHostPublicHostPublic = 18, + kIceCandidatePairHostNameHostName = 19, + kIceCandidatePairHostNameHostPrivate = 20, + kIceCandidatePairHostNameHostPublic = 21, + kIceCandidatePairHostPrivateHostName = 22, + kIceCandidatePairHostPublicHostName = 23, kIceCandidatePairMax }; +// The difference between PeerConnectionEnumCounter and +// PeerConnectionMetricsName is that the "EnumCounter" is only counting the +// occurrences of events, while "Name" has a value associated with it which is +// used to form a histogram. + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum KeyExchangeProtocolType { - kEnumCounterKeyProtocolDtls, - kEnumCounterKeyProtocolSdes, + kEnumCounterKeyProtocolDtls = 0, + kEnumCounterKeyProtocolSdes = 1, kEnumCounterKeyProtocolMax }; +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum KeyExchangeProtocolMedia { - kEnumCounterKeyProtocolMediaTypeDtlsAudio, - kEnumCounterKeyProtocolMediaTypeDtlsVideo, - kEnumCounterKeyProtocolMediaTypeDtlsData, - kEnumCounterKeyProtocolMediaTypeSdesAudio, - kEnumCounterKeyProtocolMediaTypeSdesVideo, - kEnumCounterKeyProtocolMediaTypeSdesData, + kEnumCounterKeyProtocolMediaTypeDtlsAudio = 0, + kEnumCounterKeyProtocolMediaTypeDtlsVideo = 1, + kEnumCounterKeyProtocolMediaTypeDtlsData = 2, + kEnumCounterKeyProtocolMediaTypeSdesAudio = 3, + kEnumCounterKeyProtocolMediaTypeSdesVideo = 4, + kEnumCounterKeyProtocolMediaTypeSdesData = 5, kEnumCounterKeyProtocolMediaTypeMax }; +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum SdpSemanticRequested { - kSdpSemanticRequestDefault, - kSdpSemanticRequestPlanB, - kSdpSemanticRequestUnifiedPlan, + kSdpSemanticRequestDefault = 0, + kSdpSemanticRequestPlanB = 1, + kSdpSemanticRequestUnifiedPlan = 2, kSdpSemanticRequestMax }; +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum SdpSemanticNegotiated { - kSdpSemanticNegotiatedNone, - kSdpSemanticNegotiatedPlanB, - kSdpSemanticNegotiatedUnifiedPlan, - kSdpSemanticNegotiatedMixed, + kSdpSemanticNegotiatedNone = 0, + kSdpSemanticNegotiatedPlanB = 1, + kSdpSemanticNegotiatedUnifiedPlan = 2, + kSdpSemanticNegotiatedMixed = 3, kSdpSemanticNegotiatedMax }; // Metric which records the format of the received SDP for tracking how much the // difference between Plan B and Unified Plan affect users. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum SdpFormatReceived { // No audio or video tracks. This is worth special casing since it seems to be // the most common scenario (data-channel only). - kSdpFormatReceivedNoTracks, + kSdpFormatReceivedNoTracks = 0, // No more than one audio and one video track. Should be compatible with both // Plan B and Unified Plan endpoints. - kSdpFormatReceivedSimple, + kSdpFormatReceivedSimple = 1, // More than one audio track or more than one video track in the Plan B format // (e.g., one audio media section with multiple streams). - kSdpFormatReceivedComplexPlanB, + kSdpFormatReceivedComplexPlanB = 2, // More than one audio track or more than one video track in the Unified Plan // format (e.g., two audio media sections). - kSdpFormatReceivedComplexUnifiedPlan, + kSdpFormatReceivedComplexUnifiedPlan = 3, kSdpFormatReceivedMax }; // Metric for counting the outcome of adding an ICE candidate +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum AddIceCandidateResult { - kAddIceCandidateSuccess, - kAddIceCandidateFailClosed, - kAddIceCandidateFailNoRemoteDescription, - kAddIceCandidateFailNullCandidate, - kAddIceCandidateFailNotValid, - kAddIceCandidateFailNotReady, - kAddIceCandidateFailInAddition, - kAddIceCandidateFailNotUsable, + kAddIceCandidateSuccess = 0, + kAddIceCandidateFailClosed = 1, + kAddIceCandidateFailNoRemoteDescription = 2, + kAddIceCandidateFailNullCandidate = 3, + kAddIceCandidateFailNotValid = 4, + kAddIceCandidateFailNotReady = 5, + kAddIceCandidateFailInAddition = 6, + kAddIceCandidateFailNotUsable = 7, kAddIceCandidateMax }; // Metric for recording which api surface was used to enable simulcast. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum SimulcastApiVersion { - kSimulcastApiVersionNone, - kSimulcastApiVersionLegacy, - kSimulcastApiVersionSpecCompliant, - kSimulcastApiVersionMax, + kSimulcastApiVersionNone = 0, + kSimulcastApiVersionLegacy = 1, + kSimulcastApiVersionSpecCompliant = 2, + kSimulcastApiVersionMax }; +// When adding new metrics please consider using the style described in +// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#usage +// instead of the legacy enums used above. + } // namespace webrtc #endif // API_UMA_METRICS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/video/builtin_video_bitrate_allocator_factory.cc b/TMessagesProj/jni/voip/webrtc/api/video/builtin_video_bitrate_allocator_factory.cc index 96b2545d2..593bca60f 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/builtin_video_bitrate_allocator_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/api/video/builtin_video_bitrate_allocator_factory.cc @@ -15,7 +15,7 @@ #include "absl/base/macros.h" #include "api/video/video_bitrate_allocator.h" #include "api/video_codecs/video_codec.h" -#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h" +#include "modules/video_coding/svc/svc_rate_allocator.h" #include "modules/video_coding/utility/simulcast_rate_allocator.h" namespace webrtc { @@ -30,16 +30,14 @@ class BuiltinVideoBitrateAllocatorFactory std::unique_ptr CreateVideoBitrateAllocator( const VideoCodec& codec) override { - std::unique_ptr rate_allocator; switch (codec.codecType) { + case kVideoCodecAV1: case kVideoCodecVP9: - rate_allocator.reset(new SvcRateAllocator(codec)); - break; - // TODO: add an allocator here for H.265 + // TODO: add an allocator here for H.265 + return std::make_unique(codec); default: - rate_allocator.reset(new SimulcastRateAllocator(codec)); + return std::make_unique(codec); } - return rate_allocator; } }; diff --git a/TMessagesProj/jni/voip/webrtc/api/video/encoded_image.cc b/TMessagesProj/jni/voip/webrtc/api/video/encoded_image.cc index 13d57ef5f..1c73bdabe 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/encoded_image.cc +++ b/TMessagesProj/jni/voip/webrtc/api/video/encoded_image.cc @@ -61,7 +61,7 @@ void EncodedImageBuffer::Realloc(size_t size) { size_ = size; } -EncodedImage::EncodedImage() : EncodedImage(nullptr, 0, 0) {} +EncodedImage::EncodedImage() = default; EncodedImage::EncodedImage(EncodedImage&&) = default; EncodedImage::EncodedImage(const EncodedImage&) = default; diff --git a/TMessagesProj/jni/voip/webrtc/api/video/encoded_image.h b/TMessagesProj/jni/voip/webrtc/api/video/encoded_image.h index 35c2584df..650766ab6 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/encoded_image.h +++ b/TMessagesProj/jni/voip/webrtc/api/video/encoded_image.h @@ -25,7 +25,6 @@ #include "api/video/video_frame_type.h" #include "api/video/video_rotation.h" #include "api/video/video_timing.h" -#include "common_types.h" // NOLINT(build/include_directory) #include "rtc_base/checks.h" #include "rtc_base/deprecation.h" #include "rtc_base/ref_count.h" @@ -73,9 +72,8 @@ class RTC_EXPORT EncodedImage { public: EncodedImage(); EncodedImage(EncodedImage&&); - // Discouraged: potentially expensive. EncodedImage(const EncodedImage&); - EncodedImage(uint8_t* buffer, size_t length, size_t capacity); + RTC_DEPRECATED EncodedImage(uint8_t* buffer, size_t length, size_t capacity); ~EncodedImage(); @@ -130,11 +128,6 @@ class RTC_EXPORT EncodedImage { RTC_DCHECK_LE(new_size, new_size == 0 ? 0 : capacity()); size_ = new_size; } - // TODO(nisse): Delete, provide only read-only access to the buffer. - size_t capacity() const { - return buffer_ ? capacity_ : (encoded_data_ ? encoded_data_->size() : 0); - } - void SetEncodedData( rtc::scoped_refptr encoded_data) { encoded_data_ = encoded_data; @@ -154,11 +147,6 @@ class RTC_EXPORT EncodedImage { return encoded_data_; } - // TODO(nisse): Delete, provide only read-only access to the buffer. - uint8_t* data() { - return buffer_ ? buffer_ - : (encoded_data_ ? encoded_data_->data() : nullptr); - } const uint8_t* data() const { return buffer_ ? buffer_ : (encoded_data_ ? encoded_data_->data() : nullptr); @@ -177,13 +165,12 @@ class RTC_EXPORT EncodedImage { VideoFrameType _frameType = VideoFrameType::kVideoFrameDelta; VideoRotation rotation_ = kVideoRotation_0; VideoContentType content_type_ = VideoContentType::UNSPECIFIED; - bool _completeFrame = false; int qp_ = -1; // Quantizer value. // When an application indicates non-zero values here, it is taken as an // indication that all future frames will be constrained with those limits // until the application indicates a change again. - PlayoutDelay playout_delay_ = {-1, -1}; + VideoPlayoutDelay playout_delay_; struct Timing { uint8_t flags = VideoSendTiming::kInvalid; @@ -198,14 +185,18 @@ class RTC_EXPORT EncodedImage { } timing_; private: + size_t capacity() const { + return buffer_ ? capacity_ : (encoded_data_ ? encoded_data_->size() : 0); + } + // TODO(bugs.webrtc.org/9378): We're transitioning to always owning the // encoded data. rtc::scoped_refptr encoded_data_; - size_t size_; // Size of encoded frame data. + size_t size_ = 0; // Size of encoded frame data. // Non-null when used with an un-owned buffer. - uint8_t* buffer_; + uint8_t* buffer_ = nullptr; // Allocated size of _buffer; relevant only if it's non-null. - size_t capacity_; + size_t capacity_ = 0; uint32_t timestamp_rtp_ = 0; absl::optional spatial_index_; std::map spatial_layer_frame_size_bytes_; diff --git a/TMessagesProj/jni/voip/webrtc/api/video/nv12_buffer.cc b/TMessagesProj/jni/voip/webrtc/api/video/nv12_buffer.cc new file mode 100644 index 000000000..cfa85ac52 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/video/nv12_buffer.cc @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2020 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 "api/video/nv12_buffer.h" + +#include "api/video/i420_buffer.h" +#include "rtc_base/checks.h" +#include "rtc_base/ref_counted_object.h" +#include "third_party/libyuv/include/libyuv/convert.h" +#include "third_party/libyuv/include/libyuv/scale.h" + +namespace webrtc { + +namespace { + +static const int kBufferAlignment = 64; + +int NV12DataSize(int height, int stride_y, int stride_uv) { + return stride_y * height + stride_uv * ((height + 1) / 2); +} + +} // namespace + +NV12Buffer::NV12Buffer(int width, int height) + : NV12Buffer(width, height, width, width + width % 2) {} + +NV12Buffer::NV12Buffer(int width, int height, int stride_y, int stride_uv) + : width_(width), + height_(height), + stride_y_(stride_y), + stride_uv_(stride_uv), + data_(static_cast( + AlignedMalloc(NV12DataSize(height_, stride_y_, stride_uv), + kBufferAlignment))) { + RTC_DCHECK_GT(width, 0); + RTC_DCHECK_GT(height, 0); + RTC_DCHECK_GE(stride_y, width); + RTC_DCHECK_GE(stride_uv, (width + width % 2)); +} + +NV12Buffer::~NV12Buffer() = default; + +// static +rtc::scoped_refptr NV12Buffer::Create(int width, int height) { + return new rtc::RefCountedObject(width, height); +} + +// static +rtc::scoped_refptr NV12Buffer::Create(int width, + int height, + int stride_y, + int stride_uv) { + return new rtc::RefCountedObject(width, height, stride_y, + stride_uv); +} + +// static +rtc::scoped_refptr NV12Buffer::Copy( + const I420BufferInterface& i420_buffer) { + rtc::scoped_refptr buffer = + NV12Buffer::Create(i420_buffer.width(), i420_buffer.height()); + libyuv::I420ToNV12( + i420_buffer.DataY(), i420_buffer.StrideY(), i420_buffer.DataU(), + i420_buffer.StrideU(), i420_buffer.DataV(), i420_buffer.StrideV(), + buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataUV(), + buffer->StrideUV(), buffer->width(), buffer->height()); + return buffer; +} + +rtc::scoped_refptr NV12Buffer::ToI420() { + rtc::scoped_refptr i420_buffer = + I420Buffer::Create(width(), height()); + libyuv::NV12ToI420(DataY(), StrideY(), DataUV(), StrideUV(), + i420_buffer->MutableDataY(), i420_buffer->StrideY(), + i420_buffer->MutableDataU(), i420_buffer->StrideU(), + i420_buffer->MutableDataV(), i420_buffer->StrideV(), + width(), height()); + return i420_buffer; +} + +int NV12Buffer::width() const { + return width_; +} +int NV12Buffer::height() const { + return height_; +} + +int NV12Buffer::StrideY() const { + return stride_y_; +} +int NV12Buffer::StrideUV() const { + return stride_uv_; +} + +const uint8_t* NV12Buffer::DataY() const { + return data_.get(); +} + +const uint8_t* NV12Buffer::DataUV() const { + return data_.get() + UVOffset(); +} + +uint8_t* NV12Buffer::MutableDataY() { + return data_.get(); +} + +uint8_t* NV12Buffer::MutableDataUV() { + return data_.get() + UVOffset(); +} + +size_t NV12Buffer::UVOffset() const { + return stride_y_ * height_; +} + +void NV12Buffer::InitializeData() { + memset(data_.get(), 0, NV12DataSize(height_, stride_y_, stride_uv_)); +} + +void NV12Buffer::CropAndScaleFrom(const NV12BufferInterface& src, + int offset_x, + int offset_y, + int crop_width, + int crop_height) { + RTC_CHECK_LE(crop_width, src.width()); + RTC_CHECK_LE(crop_height, src.height()); + RTC_CHECK_LE(crop_width + offset_x, src.width()); + RTC_CHECK_LE(crop_height + offset_y, src.height()); + RTC_CHECK_GE(offset_x, 0); + RTC_CHECK_GE(offset_y, 0); + + // Make sure offset is even so that u/v plane becomes aligned. + const int uv_offset_x = offset_x / 2; + const int uv_offset_y = offset_y / 2; + offset_x = uv_offset_x * 2; + offset_y = uv_offset_y * 2; + + const uint8_t* y_plane = src.DataY() + src.StrideY() * offset_y + offset_x; + const uint8_t* uv_plane = + src.DataUV() + src.StrideUV() * uv_offset_y + uv_offset_x * 2; + + // kFilterBox is unsupported in libyuv, so using kFilterBilinear instead. + int res = libyuv::NV12Scale(y_plane, src.StrideY(), uv_plane, src.StrideUV(), + crop_width, crop_height, MutableDataY(), + StrideY(), MutableDataUV(), StrideUV(), width(), + height(), libyuv::kFilterBilinear); + + RTC_DCHECK_EQ(res, 0); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/video/nv12_buffer.h b/TMessagesProj/jni/voip/webrtc/api/video/nv12_buffer.h new file mode 100644 index 000000000..cb989e84b --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/video/nv12_buffer.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef API_VIDEO_NV12_BUFFER_H_ +#define API_VIDEO_NV12_BUFFER_H_ + +#include +#include + +#include "api/scoped_refptr.h" +#include "api/video/video_frame_buffer.h" +#include "rtc_base/memory/aligned_malloc.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +// NV12 is a biplanar encoding format, with full-resolution Y and +// half-resolution interleved UV. More information can be found at +// http://msdn.microsoft.com/library/windows/desktop/dd206750.aspx#nv12. +class RTC_EXPORT NV12Buffer : public NV12BufferInterface { + public: + static rtc::scoped_refptr Create(int width, int height); + static rtc::scoped_refptr Create(int width, + int height, + int stride_y, + int stride_uv); + static rtc::scoped_refptr Copy( + const I420BufferInterface& i420_buffer); + + rtc::scoped_refptr ToI420() override; + + int width() const override; + int height() const override; + + int StrideY() const override; + int StrideUV() const override; + + const uint8_t* DataY() const override; + const uint8_t* DataUV() const override; + + uint8_t* MutableDataY(); + uint8_t* MutableDataUV(); + + // Sets all three planes to all zeros. Used to work around for + // quirks in memory checkers + // (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and + // ffmpeg (http://crbug.com/390941). + // TODO(nisse): Deprecated. Should be deleted if/when those issues + // are resolved in a better way. Or in the mean time, use SetBlack. + void InitializeData(); + + // Scale the cropped area of |src| to the size of |this| buffer, and + // write the result into |this|. + void CropAndScaleFrom(const NV12BufferInterface& src, + int offset_x, + int offset_y, + int crop_width, + int crop_height); + + protected: + NV12Buffer(int width, int height); + NV12Buffer(int width, int height, int stride_y, int stride_uv); + + ~NV12Buffer() override; + + private: + size_t UVOffset() const; + + const int width_; + const int height_; + const int stride_y_; + const int stride_uv_; + const std::unique_ptr data_; +}; + +} // namespace webrtc + +#endif // API_VIDEO_NV12_BUFFER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/video/test/mock_recordable_encoded_frame.h b/TMessagesProj/jni/voip/webrtc/api/video/test/mock_recordable_encoded_frame.h deleted file mode 100644 index 2178932d2..000000000 --- a/TMessagesProj/jni/voip/webrtc/api/video/test/mock_recordable_encoded_frame.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ - -#ifndef API_VIDEO_TEST_MOCK_RECORDABLE_ENCODED_FRAME_H_ -#define API_VIDEO_TEST_MOCK_RECORDABLE_ENCODED_FRAME_H_ - -#include "api/video/recordable_encoded_frame.h" -#include "test/gmock.h" - -namespace webrtc { -class MockRecordableEncodedFrame : public RecordableEncodedFrame { - public: - MOCK_METHOD(rtc::scoped_refptr, - encoded_buffer, - (), - (const, override)); - MOCK_METHOD(absl::optional, - color_space, - (), - (const, override)); - MOCK_METHOD(VideoCodecType, codec, (), (const, override)); - MOCK_METHOD(bool, is_key_frame, (), (const, override)); - MOCK_METHOD(EncodedResolution, resolution, (), (const, override)); - MOCK_METHOD(Timestamp, render_time, (), (const, override)); -}; -} // namespace webrtc -#endif // API_VIDEO_TEST_MOCK_RECORDABLE_ENCODED_FRAME_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_codec_constants.h b/TMessagesProj/jni/voip/webrtc/api/video/video_codec_constants.h index 6b6feee4c..5859f9b4c 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/video_codec_constants.h +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_codec_constants.h @@ -17,6 +17,7 @@ enum : int { kMaxEncoderBuffers = 8 }; enum : int { kMaxSimulcastStreams = 3 }; enum : int { kMaxSpatialLayers = 5 }; enum : int { kMaxTemporalStreams = 4 }; +enum : int { kMaxPreferredPixelFormats = 5 }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_frame.h b/TMessagesProj/jni/voip/webrtc/api/video/video_frame.h index 08c939d91..e62aae8e5 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/video_frame.h +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_frame.h @@ -186,6 +186,16 @@ class RTC_EXPORT VideoFrame { color_space_ = color_space; } + // max_composition_delay_in_frames() is used in an experiment of a low-latency + // renderer algorithm see crbug.com/1138888. + absl::optional max_composition_delay_in_frames() const { + return max_composition_delay_in_frames_; + } + void set_max_composition_delay_in_frames( + absl::optional max_composition_delay_in_frames) { + max_composition_delay_in_frames_ = max_composition_delay_in_frames; + } + // Get render time in milliseconds. // TODO(nisse): Deprecated. Migrate all users to timestamp_us(). int64_t render_time_ms() const; @@ -255,6 +265,7 @@ class RTC_EXPORT VideoFrame { int64_t timestamp_us_; VideoRotation rotation_; absl::optional color_space_; + absl::optional max_composition_delay_in_frames_; // Updated since the last frame area. If present it means that the bounding // box of all the changes is within the rectangular area and is close to it. // If absent, it means that there's no information about the change at all and diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_frame_buffer.cc b/TMessagesProj/jni/voip/webrtc/api/video/video_frame_buffer.cc index b9fd9cd92..64f339448 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/video_frame_buffer.cc +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_frame_buffer.cc @@ -10,10 +10,25 @@ #include "api/video/video_frame_buffer.h" +#include "api/video/i420_buffer.h" #include "rtc_base/checks.h" namespace webrtc { +rtc::scoped_refptr VideoFrameBuffer::CropAndScale( + int offset_x, + int offset_y, + int crop_width, + int crop_height, + int scaled_width, + int scaled_height) { + rtc::scoped_refptr result = + I420Buffer::Create(scaled_width, scaled_height); + result->CropAndScaleFrom(*this->ToI420(), offset_x, offset_y, crop_width, + crop_height); + return result; +} + const I420BufferInterface* VideoFrameBuffer::GetI420() const { // Overridden by subclasses that can return an I420 buffer without any // conversion, in particular, I420BufferInterface. @@ -35,10 +50,40 @@ const I010BufferInterface* VideoFrameBuffer::GetI010() const { return static_cast(this); } +const NV12BufferInterface* VideoFrameBuffer::GetNV12() const { + RTC_CHECK(type() == Type::kNV12); + return static_cast(this); +} + +rtc::scoped_refptr VideoFrameBuffer::GetMappedFrameBuffer( + rtc::ArrayView types) { + RTC_CHECK(type() == Type::kNative); + return nullptr; +} + VideoFrameBuffer::Type I420BufferInterface::type() const { return Type::kI420; } +const char* VideoFrameBufferTypeToString(VideoFrameBuffer::Type type) { + switch (type) { + case VideoFrameBuffer::Type::kNative: + return "kNative"; + case VideoFrameBuffer::Type::kI420: + return "kI420"; + case VideoFrameBuffer::Type::kI420A: + return "kI420A"; + case VideoFrameBuffer::Type::kI444: + return "kI444"; + case VideoFrameBuffer::Type::kI010: + return "kI010"; + case VideoFrameBuffer::Type::kNV12: + return "kNV12"; + default: + RTC_NOTREACHED(); + } +} + int I420BufferInterface::ChromaWidth() const { return (width() + 1) / 2; } @@ -83,4 +128,15 @@ int I010BufferInterface::ChromaHeight() const { return (height() + 1) / 2; } +VideoFrameBuffer::Type NV12BufferInterface::type() const { + return Type::kNV12; +} + +int NV12BufferInterface::ChromaWidth() const { + return (width() + 1) / 2; +} + +int NV12BufferInterface::ChromaHeight() const { + return (height() + 1) / 2; +} } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_frame_buffer.h b/TMessagesProj/jni/voip/webrtc/api/video/video_frame_buffer.h index d87a4230a..67b879732 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/video_frame_buffer.h +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_frame_buffer.h @@ -13,6 +13,7 @@ #include +#include "api/array_view.h" #include "api/scoped_refptr.h" #include "rtc_base/ref_count.h" #include "rtc_base/system/rtc_export.h" @@ -23,6 +24,7 @@ class I420BufferInterface; class I420ABufferInterface; class I444BufferInterface; class I010BufferInterface; +class NV12BufferInterface; // Base class for frame buffers of different types of pixel format and storage. // The tag in type() indicates how the data is represented, and each type is @@ -50,6 +52,7 @@ class RTC_EXPORT VideoFrameBuffer : public rtc::RefCountInterface { kI420A, kI444, kI010, + kNV12, }; // This function specifies in what pixel format the data is stored in. @@ -72,18 +75,50 @@ class RTC_EXPORT VideoFrameBuffer : public rtc::RefCountInterface { // WebrtcVideoFrameAdapter in Chrome - it's I420 buffer backed by a shared // memory buffer. Therefore it must have type kNative. Yet, ToI420() // doesn't affect binary data at all. Another example is any I420A buffer. + // TODO(https://crbug.com/webrtc/12021): Make this method non-virtual and + // behave as the other GetXXX methods below. virtual const I420BufferInterface* GetI420() const; + // A format specific scale function. Default implementation works by + // converting to I420. But more efficient implementations may override it, + // especially for kNative. + // First, the image is cropped to |crop_width| and |crop_height| and then + // scaled to |scaled_width| and |scaled_height|. + virtual rtc::scoped_refptr CropAndScale(int offset_x, + int offset_y, + int crop_width, + int crop_height, + int scaled_width, + int scaled_height); + + // Alias for common use case. + rtc::scoped_refptr Scale(int scaled_width, + int scaled_height) { + return CropAndScale(0, 0, width(), height(), scaled_width, scaled_height); + } + // These functions should only be called if type() is of the correct type. // Calling with a different type will result in a crash. const I420ABufferInterface* GetI420A() const; const I444BufferInterface* GetI444() const; const I010BufferInterface* GetI010() const; + const NV12BufferInterface* GetNV12() const; + + // From a kNative frame, returns a VideoFrameBuffer with a pixel format in + // the list of types that is in the main memory with a pixel perfect + // conversion for encoding with a software encoder. Returns nullptr if the + // frame type is not supported, mapping is not possible, or if the kNative + // frame has not implemented this method. Only callable if type() is kNative. + virtual rtc::scoped_refptr GetMappedFrameBuffer( + rtc::ArrayView types); protected: ~VideoFrameBuffer() override {} }; +// Update when VideoFrameBuffer::Type is updated. +const char* VideoFrameBufferTypeToString(VideoFrameBuffer::Type type); + // This interface represents planar formats. class PlanarYuvBuffer : public VideoFrameBuffer { public: @@ -175,6 +210,42 @@ class I010BufferInterface : public PlanarYuv16BBuffer { ~I010BufferInterface() override {} }; +class BiplanarYuvBuffer : public VideoFrameBuffer { + public: + virtual int ChromaWidth() const = 0; + virtual int ChromaHeight() const = 0; + + // Returns the number of steps(in terms of Data*() return type) between + // successive rows for a given plane. + virtual int StrideY() const = 0; + virtual int StrideUV() const = 0; + + protected: + ~BiplanarYuvBuffer() override {} +}; + +class BiplanarYuv8Buffer : public BiplanarYuvBuffer { + public: + virtual const uint8_t* DataY() const = 0; + virtual const uint8_t* DataUV() const = 0; + + protected: + ~BiplanarYuv8Buffer() override {} +}; + +// Represents Type::kNV12. NV12 is full resolution Y and half-resolution +// interleved UV. +class RTC_EXPORT NV12BufferInterface : public BiplanarYuv8Buffer { + public: + Type type() const override; + + int ChromaWidth() const final; + int ChromaHeight() const final; + + protected: + ~NV12BufferInterface() override {} +}; + } // namespace webrtc #endif // API_VIDEO_VIDEO_FRAME_BUFFER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_layers_allocation.h b/TMessagesProj/jni/voip/webrtc/api/video/video_layers_allocation.h new file mode 100644 index 000000000..39734151a --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_layers_allocation.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef API_VIDEO_VIDEO_LAYERS_ALLOCATION_H_ +#define API_VIDEO_VIDEO_LAYERS_ALLOCATION_H_ + +#include + +#include "absl/container/inlined_vector.h" +#include "api/units/data_rate.h" + +namespace webrtc { + +// This struct contains additional stream-level information needed by a +// Selective Forwarding Middlebox to make relay decisions of RTP streams. +struct VideoLayersAllocation { + static constexpr int kMaxSpatialIds = 4; + static constexpr int kMaxTemporalIds = 4; + + friend bool operator==(const VideoLayersAllocation& lhs, + const VideoLayersAllocation& rhs) { + return lhs.rtp_stream_index == rhs.rtp_stream_index && + lhs.resolution_and_frame_rate_is_valid == + rhs.resolution_and_frame_rate_is_valid && + lhs.active_spatial_layers == rhs.active_spatial_layers; + } + + friend bool operator!=(const VideoLayersAllocation& lhs, + const VideoLayersAllocation& rhs) { + return !(lhs == rhs); + } + + struct SpatialLayer { + friend bool operator==(const SpatialLayer& lhs, const SpatialLayer& rhs) { + return lhs.rtp_stream_index == rhs.rtp_stream_index && + lhs.spatial_id == rhs.spatial_id && + lhs.target_bitrate_per_temporal_layer == + rhs.target_bitrate_per_temporal_layer && + lhs.width == rhs.width && lhs.height == rhs.height && + lhs.frame_rate_fps == rhs.frame_rate_fps; + } + + friend bool operator!=(const SpatialLayer& lhs, const SpatialLayer& rhs) { + return !(lhs == rhs); + } + int rtp_stream_index = 0; + // Index of the spatial layer per `rtp_stream_index`. + int spatial_id = 0; + // Target bitrate per decode target. + absl::InlinedVector + target_bitrate_per_temporal_layer; + + // These fields are only valid if `resolution_and_frame_rate_is_valid` is + // true + uint16_t width = 0; + uint16_t height = 0; + // Max frame rate used in any temporal layer of this spatial layer. + uint8_t frame_rate_fps = 0; + }; + + // Index of the rtp stream this allocation is sent on. Used for mapping + // a SpatialLayer to a rtp stream. + int rtp_stream_index = 0; + bool resolution_and_frame_rate_is_valid = false; + absl::InlinedVector active_spatial_layers; +}; + +} // namespace webrtc + +#endif // API_VIDEO_VIDEO_LAYERS_ALLOCATION_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_stream_decoder.h b/TMessagesProj/jni/voip/webrtc/api/video/video_stream_decoder.h index 8f27fa4db..4bf8b985c 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/video_stream_decoder.h +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_stream_decoder.h @@ -17,6 +17,7 @@ #include "api/units/time_delta.h" #include "api/video/encoded_frame.h" +#include "api/video/video_content_type.h" #include "api/video/video_frame.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder_factory.h" @@ -29,6 +30,11 @@ class VideoStreamDecoderInterface { public: virtual ~Callbacks() = default; + struct FrameInfo { + absl::optional qp; + VideoContentType content_type; + }; + // Called when the VideoStreamDecoder enters a non-decodable state. virtual void OnNonDecodableState() = 0; @@ -36,10 +42,8 @@ class VideoStreamDecoderInterface { virtual void OnContinuousUntil( const video_coding::VideoLayerFrameId& key) = 0; - // Called with the decoded frame. - virtual void OnDecodedFrame(VideoFrame decodedImage, - absl::optional decode_time_ms, - absl::optional qp) = 0; + virtual void OnDecodedFrame(VideoFrame frame, + const FrameInfo& frame_info) = 0; }; virtual ~VideoStreamDecoderInterface() = default; diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_stream_encoder_interface.h b/TMessagesProj/jni/voip/webrtc/api/video/video_stream_encoder_interface.h index d8dd8e159..34fa6421c 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/video_stream_encoder_interface.h +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_stream_encoder_interface.h @@ -19,6 +19,7 @@ #include "api/scoped_refptr.h" #include "api/units/data_rate.h" #include "api/video/video_bitrate_allocator.h" +#include "api/video/video_layers_allocation.h" #include "api/video/video_sink_interface.h" #include "api/video/video_source_interface.h" #include "api/video_codecs/video_encoder.h" @@ -49,6 +50,12 @@ class VideoStreamEncoderInterface : public rtc::VideoSinkInterface { bool is_svc, VideoEncoderConfig::ContentType content_type, int min_transmit_bitrate_bps) = 0; + + virtual void OnBitrateAllocationUpdated( + const VideoBitrateAllocation& allocation) = 0; + + virtual void OnVideoLayersAllocationUpdated( + VideoLayersAllocation allocation) = 0; }; // If the resource is overusing, the VideoStreamEncoder will try to reduce @@ -110,11 +117,6 @@ class VideoStreamEncoderInterface : public rtc::VideoSinkInterface { int64_t round_trip_time_ms, double cwnd_reduce_ratio) = 0; - // Register observer for the bitrate allocation between the temporal - // and spatial layers. - virtual void SetBitrateAllocationObserver( - VideoBitrateAllocationObserver* bitrate_observer) = 0; - // Set a FecControllerOverride, through which the encoder may override // decisions made by FecController. virtual void SetFecControllerOverride( diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_stream_encoder_settings.h b/TMessagesProj/jni/voip/webrtc/api/video/video_stream_encoder_settings.h index 743524b35..cbeed3d07 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/video_stream_encoder_settings.h +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_stream_encoder_settings.h @@ -39,6 +39,12 @@ class EncoderSwitchRequestCallback { }; struct VideoStreamEncoderSettings { + enum class BitrateAllocationCallbackType { + kVideoBitrateAllocation, + kVideoBitrateAllocationWhenScreenSharing, + kVideoLayersAllocation + }; + explicit VideoStreamEncoderSettings( const VideoEncoder::Capabilities& capabilities) : capabilities(capabilities) {} @@ -59,6 +65,11 @@ struct VideoStreamEncoderSettings { // Negotiated capabilities which the VideoEncoder may expect the other // side to use. VideoEncoder::Capabilities capabilities; + + // TODO(bugs.webrtc.org/12000): Reporting of VideoBitrateAllocation is beeing + // deprecated. Instead VideoLayersAllocation should be reported. + BitrateAllocationCallbackType allocation_cb_type = + BitrateAllocationCallbackType::kVideoBitrateAllocationWhenScreenSharing; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/video/video_timing.h b/TMessagesProj/jni/voip/webrtc/api/video/video_timing.h index 4cc75dd0b..fbd92254a 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video/video_timing.h +++ b/TMessagesProj/jni/voip/webrtc/api/video/video_timing.h @@ -100,6 +100,30 @@ struct TimingFrameInfo { uint8_t flags; // Flags indicating validity and/or why tracing was triggered. }; +// Minimum and maximum playout delay values from capture to render. +// These are best effort values. +// +// A value < 0 indicates no change from previous valid value. +// +// min = max = 0 indicates that the receiver should try and render +// frame as soon as possible. +// +// min = x, max = y indicates that the receiver is free to adapt +// in the range (x, y) based on network jitter. +struct VideoPlayoutDelay { + VideoPlayoutDelay() = default; + VideoPlayoutDelay(int min_ms, int max_ms) : min_ms(min_ms), max_ms(max_ms) {} + int min_ms = -1; + int max_ms = -1; + + bool operator==(const VideoPlayoutDelay& rhs) const { + return min_ms == rhs.min_ms && max_ms == rhs.max_ms; + } +}; + +// TODO(bugs.webrtc.org/7660): Old name, delete after downstream use is updated. +using PlayoutDelay = VideoPlayoutDelay; + } // namespace webrtc #endif // API_VIDEO_VIDEO_TIMING_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/spatial_layer.cc b/TMessagesProj/jni/voip/webrtc/api/video_codecs/spatial_layer.cc new file mode 100644 index 000000000..25ccdfeb4 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/spatial_layer.cc @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020 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 "api/video_codecs/spatial_layer.h" + +namespace webrtc { + +bool SpatialLayer::operator==(const SpatialLayer& other) const { + return (width == other.width && height == other.height && + maxFramerate == other.maxFramerate && + numberOfTemporalLayers == other.numberOfTemporalLayers && + maxBitrate == other.maxBitrate && + targetBitrate == other.targetBitrate && + minBitrate == other.minBitrate && qpMax == other.qpMax && + active == other.active); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/spatial_layer.h b/TMessagesProj/jni/voip/webrtc/api/video_codecs/spatial_layer.h new file mode 100644 index 000000000..5a1b42542 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/spatial_layer.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef API_VIDEO_CODECS_SPATIAL_LAYER_H_ +#define API_VIDEO_CODECS_SPATIAL_LAYER_H_ + +namespace webrtc { + +struct SpatialLayer { + bool operator==(const SpatialLayer& other) const; + bool operator!=(const SpatialLayer& other) const { return !(*this == other); } + + unsigned short width; // NOLINT(runtime/int) + unsigned short height; // NOLINT(runtime/int) + float maxFramerate; // fps. + unsigned char numberOfTemporalLayers; + unsigned int maxBitrate; // kilobits/sec. + unsigned int targetBitrate; // kilobits/sec. + unsigned int minBitrate; // kilobits/sec. + unsigned int qpMax; // minimum quality + bool active; // encoded and sent. +}; + +} // namespace webrtc +#endif // API_VIDEO_CODECS_SPATIAL_LAYER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_codec.cc b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_codec.cc index a21e692aa..d7ee165e6 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_codec.cc +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_codec.cc @@ -70,19 +70,8 @@ bool VideoCodecH265::operator==(const VideoCodecH265& other) const { } #endif -bool SpatialLayer::operator==(const SpatialLayer& other) const { - return (width == other.width && height == other.height && - maxFramerate == other.maxFramerate && - numberOfTemporalLayers == other.numberOfTemporalLayers && - maxBitrate == other.maxBitrate && - targetBitrate == other.targetBitrate && - minBitrate == other.minBitrate && qpMax == other.qpMax && - active == other.active); -} - VideoCodec::VideoCodec() : codecType(kVideoCodecGeneric), - plType(0), width(0), height(0), startBitrate(0), @@ -162,6 +151,7 @@ const char* CodecTypeToPayloadString(VideoCodecType type) { default: return kPayloadNameGeneric; } + RTC_CHECK_NOTREACHED(); } VideoCodecType PayloadStringToCodecType(const std::string& name) { diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_codec.h b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_codec.h index 52315282b..14da6006e 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_codec.h +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_codec.h @@ -16,10 +16,11 @@ #include +#include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/video/video_bitrate_allocation.h" #include "api/video/video_codec_type.h" -#include "common_types.h" // NOLINT(build/include_directory) +#include "api/video_codecs/spatial_layer.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { @@ -121,11 +122,16 @@ class RTC_EXPORT VideoCodec { public: VideoCodec(); + // Scalability mode as described in + // https://www.w3.org/TR/webrtc-svc/#scalabilitymodes* + // or value 'NONE' to indicate no scalability. + absl::string_view ScalabilityMode() const { return scalability_mode_; } + void SetScalabilityMode(absl::string_view scalability_mode) { + scalability_mode_ = std::string(scalability_mode); + } + // Public variables. TODO(hta): Make them private with accessors. VideoCodecType codecType; - // TODO(nisse): Unused in webrtc, delete as soon as downstream projects are - // updated. - unsigned char plType; // TODO(nisse): Change to int, for consistency. uint16_t width; @@ -143,7 +149,7 @@ class RTC_EXPORT VideoCodec { unsigned int qpMax; unsigned char numberOfSimulcastStreams; - SimulcastStream simulcastStream[kMaxSimulcastStreams]; + SpatialLayer simulcastStream[kMaxSimulcastStreams]; SpatialLayer spatialLayers[kMaxSpatialLayers]; VideoCodecMode mode; @@ -193,6 +199,7 @@ class RTC_EXPORT VideoCodec { // TODO(hta): Consider replacing the union with a pointer type. // This will allow removing the VideoCodec* types from this file. VideoCodecUnion codec_specific_; + std::string scalability_mode_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder.cc b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder.cc index 3f881e261..b03933a5c 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder.cc +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder.cc @@ -18,19 +18,6 @@ namespace webrtc { -EncodedImageCallback::Result EncodedImageCallback::OnEncodedImage( - const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* /*fragmentation*/) { - return OnEncodedImage(encoded_image, codec_specific_info); -} - -EncodedImageCallback::Result EncodedImageCallback::OnEncodedImage( - const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info) { - return OnEncodedImage(encoded_image, codec_specific_info, nullptr); -} - // TODO(mflodman): Add default complexity for VP9 and VP9. VideoCodecVP8 VideoEncoder::GetDefaultVp8Settings() { VideoCodecVP8 vp8_settings; @@ -124,6 +111,7 @@ bool VideoEncoder::ResolutionBitrateLimits::operator==( VideoEncoder::EncoderInfo::EncoderInfo() : scaling_settings(VideoEncoder::ScalingSettings::kOff), requested_resolution_alignment(1), + apply_alignment_to_all_simulcast_layers(false), supports_native_handle(false), implementation_name("unknown"), has_trusted_rate_controller(false), @@ -132,7 +120,8 @@ VideoEncoder::EncoderInfo::EncoderInfo() fps_allocation{absl::InlinedVector( 1, kMaxFramerateFraction)}, - supports_simulcast(false) {} + supports_simulcast(false), + preferred_pixel_formats{VideoFrameBuffer::Type::kI420} {} VideoEncoder::EncoderInfo::EncoderInfo(const EncoderInfo&) = default; @@ -153,6 +142,8 @@ std::string VideoEncoder::EncoderInfo::ToString() const { oss << "min_pixels_per_frame = " << scaling_settings.min_pixels_per_frame << " }"; oss << ", requested_resolution_alignment = " << requested_resolution_alignment + << ", apply_alignment_to_all_simulcast_layers = " + << apply_alignment_to_all_simulcast_layers << ", supports_native_handle = " << supports_native_handle << ", implementation_name = '" << implementation_name << "'" @@ -196,7 +187,15 @@ std::string VideoEncoder::EncoderInfo::ToString() const { } oss << "] " ", supports_simulcast = " - << supports_simulcast << "}"; + << supports_simulcast; + oss << ", preferred_pixel_formats = ["; + for (size_t i = 0; i < preferred_pixel_formats.size(); ++i) { + if (i > 0) + oss << ", "; + oss << VideoFrameBufferTypeToString(preferred_pixel_formats.at(i)); + } + oss << "]"; + oss << "}"; return oss.str(); } diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder.h b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder.h index e8af1dd75..3c9c2376a 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder.h +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder.h @@ -30,7 +30,6 @@ namespace webrtc { -class RTPFragmentationHeader; // TODO(pbos): Expose these through a public (root) header or change these APIs. struct CodecSpecificInfo; @@ -73,16 +72,9 @@ class RTC_EXPORT EncodedImageCallback { }; // Callback function which is called when an image has been encoded. - // Deprecated, use OnEncodedImage below instead, see bugs.webrtc.org/6471 - virtual Result OnEncodedImage(const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* fragmentation); - - // Callback function which is called when an image has been encoded. - // TODO(bugs.webrtc.org/6471): Make pure virtual - // when OnEncodedImage above is deleted. - virtual Result OnEncodedImage(const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info); + virtual Result OnEncodedImage( + const EncodedImage& encoded_image, + const CodecSpecificInfo* codec_specific_info) = 0; virtual void OnDroppedFrame(DropReason reason) {} }; @@ -182,6 +174,15 @@ class RTC_EXPORT VideoEncoder { // requirements the encoder has on the incoming video frame buffers. int requested_resolution_alignment; + // Same as above but if true, each simulcast layer should also be divisible + // by |requested_resolution_alignment|. + // Note that scale factors |scale_resolution_down_by| may be adjusted so a + // common multiple is not too large to avoid largely cropped frames and + // possibly with an aspect ratio far from the original. + // Warning: large values of scale_resolution_down_by could be changed + // considerably, especially if |requested_resolution_alignment| is large. + bool apply_alignment_to_all_simulcast_layers; + // If true, encoder supports working with a native handle (e.g. texture // handle for hw codecs) rather than requiring a raw I420 buffer. bool supports_native_handle; @@ -253,6 +254,12 @@ class RTC_EXPORT VideoEncoder { // in such case the encoder should return // WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED. bool supports_simulcast; + + // The list of pixel formats preferred by the encoder. It is assumed that if + // the list is empty and supports_native_handle is false, then {I420} is the + // preferred pixel format. The order of the formats does not matter. + absl::InlinedVector + preferred_pixel_formats; }; struct RTC_EXPORT RateControlParameters { @@ -266,6 +273,9 @@ class RTC_EXPORT VideoEncoder { // Target bitrate, per spatial/temporal layer. // A target bitrate of 0bps indicates a layer should not be encoded at all. + VideoBitrateAllocation target_bitrate; + // Adjusted target bitrate, per spatial/temporal layer. May be lower or + // higher than the target depending on encoder behaviour. VideoBitrateAllocation bitrate; // Target framerate, in fps. A value <= 0.0 is invalid and should be // interpreted as framerate target not available. In this case the encoder @@ -377,7 +387,7 @@ class RTC_EXPORT VideoEncoder { // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise. virtual int32_t Release() = 0; - // Encode an I420 image (as a part of a video stream). The encoded image + // Encode an image (as a part of a video stream). The encoded image // will be returned to the user through the encode complete callback. // // Input: diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_config.cc b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_config.cc index 1185e2ced..45d579503 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_config.cc +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_config.cc @@ -43,6 +43,7 @@ std::string VideoStream::ToString() const { ss << ", num_temporal_layers: " << num_temporal_layers.value_or(1); ss << ", bitrate_priority: " << bitrate_priority.value_or(0); ss << ", active: " << active; + ss << ", scale_down_by: " << scale_resolution_down_by; return ss.str(); } diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_config.h b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_config.h index b613218d4..81de62daf 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_config.h +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_config.h @@ -64,6 +64,8 @@ struct VideoStream { // between multiple streams. absl::optional bitrate_priority; + absl::optional scalability_mode; + // If this stream is enabled by the user, or not. bool active; }; diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_factory.h b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_factory.h index 0a3c1aee6..22430eb19 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_factory.h +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_factory.h @@ -28,8 +28,6 @@ class VideoEncoderFactory { public: // TODO(magjed): Try to get rid of this struct. struct CodecInfo { - // TODO(nisse): Unused in webrtc, delete as soon as downstream use is fixed. - bool is_hardware_accelerated = false; // |has_internal_source| is true if encoders created by this factory of the // given codec will use internal camera sources, meaning that they don't // require/expect frames to be delivered via webrtc::VideoEncoder::Encode. diff --git a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc index 354e8c25a..94a18171a 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc +++ b/TMessagesProj/jni/voip/webrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc @@ -56,7 +56,7 @@ struct ForcedFallbackParams { bool SupportsTemporalBasedSwitch(const VideoCodec& codec) const { return enable_temporal_based_switch && - SimulcastUtility::NumberOfTemporalLayers(codec, 0) > 1; + SimulcastUtility::NumberOfTemporalLayers(codec, 0) != 1; } bool enable_temporal_based_switch = false; @@ -162,6 +162,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder { case EncoderState::kForcedFallback: return fallback_encoder_.get(); } + RTC_CHECK_NOTREACHED(); } // Updates encoder with last observed parameters, such as callbacks, rates, @@ -345,7 +346,9 @@ int32_t VideoEncoderSoftwareFallbackWrapper::Encode( case EncoderState::kForcedFallback: return fallback_encoder_->Encode(frame, frame_types); } + RTC_CHECK_NOTREACHED(); } + int32_t VideoEncoderSoftwareFallbackWrapper::EncodeWithMainEncoder( const VideoFrame& frame, const std::vector* frame_types) { @@ -367,9 +370,12 @@ int32_t VideoEncoderSoftwareFallbackWrapper::EncodeWithMainEncoder( RTC_LOG(LS_ERROR) << "Failed to convert from to I420"; return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE; } - rtc::scoped_refptr dst_buffer = - I420Buffer::Create(codec_settings_.width, codec_settings_.height); - dst_buffer->ScaleFrom(*src_buffer); + rtc::scoped_refptr dst_buffer = + src_buffer->Scale(codec_settings_.width, codec_settings_.height); + if (!dst_buffer) { + RTC_LOG(LS_ERROR) << "Failed to scale video frame."; + return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE; + } VideoFrame scaled_frame = frame; scaled_frame.set_video_frame_buffer(dst_buffer); scaled_frame.set_update_rect(VideoFrame::UpdateRect{ @@ -456,7 +462,7 @@ bool VideoEncoderSoftwareFallbackWrapper::TryInitForcedFallbackEncoder() { } if (encoder_state_ == EncoderState::kMainEncoderUsed && - encoder_->GetEncoderInfo().fps_allocation[0].size() > 1) { + encoder_->GetEncoderInfo().fps_allocation[0].size() != 1) { // Primary encoder already supports temporal layers, use that instead. return true; } @@ -465,7 +471,7 @@ bool VideoEncoderSoftwareFallbackWrapper::TryInitForcedFallbackEncoder() { if (fallback_encoder_->InitEncode(&codec_settings_, encoder_settings_.value()) == WEBRTC_VIDEO_CODEC_OK) { - if (fallback_encoder_->GetEncoderInfo().fps_allocation[0].size() > 1) { + if (fallback_encoder_->GetEncoderInfo().fps_allocation[0].size() != 1) { // Fallback encoder available and supports temporal layers, use it! if (encoder_state_ == EncoderState::kMainEncoderUsed) { // Main encoder initialized but does not support temporal layers, diff --git a/TMessagesProj/jni/voip/webrtc/api/video_track_source_proxy.h b/TMessagesProj/jni/voip/webrtc/api/video_track_source_proxy.h index 528b7cf70..692ff6493 100644 --- a/TMessagesProj/jni/voip/webrtc/api/video_track_source_proxy.h +++ b/TMessagesProj/jni/voip/webrtc/api/video_track_source_proxy.h @@ -23,8 +23,8 @@ namespace webrtc { BEGIN_PROXY_MAP(VideoTrackSource) PROXY_SIGNALING_THREAD_DESTRUCTOR() PROXY_CONSTMETHOD0(SourceState, state) -PROXY_CONSTMETHOD0(bool, remote) -PROXY_CONSTMETHOD0(bool, is_screencast) +BYPASS_PROXY_CONSTMETHOD0(bool, remote) +BYPASS_PROXY_CONSTMETHOD0(bool, is_screencast) PROXY_CONSTMETHOD0(absl::optional, needs_denoising) PROXY_METHOD1(bool, GetStats, Stats*) PROXY_WORKER_METHOD2(void, diff --git a/TMessagesProj/jni/voip/webrtc/api/voip/voip_dtmf.h b/TMessagesProj/jni/voip/webrtc/api/voip/voip_dtmf.h new file mode 100644 index 000000000..56817bae5 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/voip/voip_dtmf.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef API_VOIP_VOIP_DTMF_H_ +#define API_VOIP_VOIP_DTMF_H_ + +#include "api/voip/voip_base.h" + +namespace webrtc { + +// DTMF events and their event codes as defined in +// https://tools.ietf.org/html/rfc4733#section-7 +enum class DtmfEvent : uint8_t { + kDigitZero = 0, + kDigitOne, + kDigitTwo, + kDigitThree, + kDigitFour, + kDigitFive, + kDigitSix, + kDigitSeven, + kDigitEight, + kDigitNine, + kAsterisk, + kHash, + kLetterA, + kLetterB, + kLetterC, + kLetterD +}; + +// VoipDtmf interface provides DTMF related interfaces such +// as sending DTMF events to the remote endpoint. +class VoipDtmf { + public: + // Register the payload type and sample rate for DTMF (RFC 4733) payload. + // Must be called exactly once prior to calling SendDtmfEvent after payload + // type has been negotiated with remote. + virtual void RegisterTelephoneEventType(ChannelId channel_id, + int rtp_payload_type, + int sample_rate_hz) = 0; + + // Send DTMF named event as specified by + // https://tools.ietf.org/html/rfc4733#section-3.2 + // |duration_ms| specifies the duration of DTMF packets that will be emitted + // in place of real RTP packets instead. + // Must be called after RegisterTelephoneEventType and VoipBase::StartSend + // have been called. + // Returns true if the requested DTMF event is successfully scheduled. + virtual bool SendDtmfEvent(ChannelId channel_id, + DtmfEvent dtmf_event, + int duration_ms) = 0; + + protected: + virtual ~VoipDtmf() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_DTMF_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine.h b/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine.h index 81c97c02e..69c0a8504 100644 --- a/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine.h +++ b/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine.h @@ -16,6 +16,9 @@ namespace webrtc { class VoipBase; class VoipCodec; class VoipNetwork; +class VoipDtmf; +class VoipStatistics; +class VoipVolumeControl; // VoipEngine is the main interface serving as the entry point for all VoIP // APIs. A single instance of VoipEngine should suffice the most of the need for @@ -80,6 +83,16 @@ class VoipEngine { // VoipCodec provides codec configuration APIs for encoder and decoders. virtual VoipCodec& Codec() = 0; + + // VoipDtmf provides DTMF event APIs to register and send DTMF events. + virtual VoipDtmf& Dtmf() = 0; + + // VoipStatistics provides performance metrics around audio decoding module + // and jitter buffer (NetEq). + virtual VoipStatistics& Statistics() = 0; + + // VoipVolumeControl provides various input/output volume control. + virtual VoipVolumeControl& VolumeControl() = 0; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine_factory.cc b/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine_factory.cc index 6ac3c8621..88f63f9c9 100644 --- a/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine_factory.cc @@ -27,18 +27,11 @@ std::unique_ptr CreateVoipEngine(VoipEngineConfig config) { RTC_DLOG(INFO) << "No audio processing functionality provided."; } - auto voip_core = std::make_unique(); - - if (!voip_core->Init(std::move(config.encoder_factory), - std::move(config.decoder_factory), - std::move(config.task_queue_factory), - std::move(config.audio_device_module), - std::move(config.audio_processing))) { - RTC_DLOG(LS_ERROR) << "Failed to initialize VoIP core."; - return nullptr; - } - - return voip_core; + return std::make_unique(std::move(config.encoder_factory), + std::move(config.decoder_factory), + std::move(config.task_queue_factory), + std::move(config.audio_device_module), + std::move(config.audio_processing)); } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine_factory.h b/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine_factory.h index 658ebfac8..62fe8011a 100644 --- a/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine_factory.h +++ b/TMessagesProj/jni/voip/webrtc/api/voip/voip_engine_factory.h @@ -61,9 +61,6 @@ struct VoipEngineConfig { }; // Creates a VoipEngine instance with provided VoipEngineConfig. -// This could return nullptr if AudioDeviceModule (ADM) initialization fails -// during construction of VoipEngine which would render VoipEngine -// nonfunctional. std::unique_ptr CreateVoipEngine(VoipEngineConfig config); } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/api/voip/voip_statistics.h b/TMessagesProj/jni/voip/webrtc/api/voip/voip_statistics.h new file mode 100644 index 000000000..cf01e95e9 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/voip/voip_statistics.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef API_VOIP_VOIP_STATISTICS_H_ +#define API_VOIP_VOIP_STATISTICS_H_ + +#include "api/neteq/neteq.h" +#include "api/voip/voip_base.h" + +namespace webrtc { + +struct IngressStatistics { + // Stats included from api/neteq/neteq.h. + NetEqLifetimeStatistics neteq_stats; + + // Represents the total duration in seconds of all samples that have been + // received. + // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalsamplesduration + double total_duration = 0.0; +}; + +// VoipStatistics interface provides the interfaces for querying metrics around +// the jitter buffer (NetEq) performance. +class VoipStatistics { + public: + // Gets the audio ingress statistics. Returns absl::nullopt when channel_id is + // invalid. + virtual absl::optional GetIngressStatistics( + ChannelId channel_id) = 0; + + protected: + virtual ~VoipStatistics() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_STATISTICS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/api/voip/voip_volume_control.h b/TMessagesProj/jni/voip/webrtc/api/voip/voip_volume_control.h new file mode 100644 index 000000000..54e446715 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/api/voip/voip_volume_control.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef API_VOIP_VOIP_VOLUME_CONTROL_H_ +#define API_VOIP_VOIP_VOLUME_CONTROL_H_ + +#include "api/voip/voip_base.h" + +namespace webrtc { + +struct VolumeInfo { + // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-audiolevel + double audio_level = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-totalaudioenergy + double total_energy = 0.0; + // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-totalsamplesduration + double total_duration = 0.0; +}; + +// VoipVolumeControl interface. +// +// This sub-API supports functions related to the input (microphone) and output +// (speaker) device. +// +// Caller must ensure that ChannelId is valid otherwise it will result in no-op +// with error logging. +class VoipVolumeControl { + public: + // Mute/unmutes the microphone input sample before encoding process. Note that + // mute doesn't affect audio input level and energy values as input sample is + // silenced after the measurement. + virtual void SetInputMuted(ChannelId channel_id, bool enable) = 0; + + // Gets the microphone volume info. + // Returns absl::nullopt if |channel_id| is invalid. + virtual absl::optional GetInputVolumeInfo( + ChannelId channel_id) = 0; + + // Gets the speaker volume info. + // Returns absl::nullopt if |channel_id| is invalid. + virtual absl::optional GetOutputVolumeInfo( + ChannelId channel_id) = 0; + + protected: + virtual ~VoipVolumeControl() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_VOLUME_CONTROL_H_ diff --git a/TMessagesProj/jni/voip/webrtc/audio/audio_receive_stream.cc b/TMessagesProj/jni/voip/webrtc/audio/audio_receive_stream.cc index 6bc0d4137..54c8a0297 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/audio_receive_stream.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/audio_receive_stream.cc @@ -173,7 +173,8 @@ void AudioReceiveStream::Stop() { audio_state()->RemoveReceivingStream(this); } -webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const { +webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats( + bool get_and_clear_legacy_stats) const { RTC_DCHECK_RUN_ON(&worker_thread_checker_); webrtc::AudioReceiveStream::Stats stats; stats.remote_ssrc = config_.rtp.remote_ssrc; @@ -210,7 +211,7 @@ webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const { rtc::TimeMillis()); // Get jitter buffer and total delay (alg + jitter + playout) stats. - auto ns = channel_receive_->GetNetworkStatistics(); + auto ns = channel_receive_->GetNetworkStatistics(get_and_clear_legacy_stats); stats.fec_packets_received = ns.fecPacketsReceived; stats.fec_packets_discarded = ns.fecPacketsDiscarded; stats.jitter_buffer_ms = ns.currentBufferSize; @@ -329,7 +330,7 @@ void AudioReceiveStream::SetEstimatedPlayoutNtpTimestampMs( time_ms); } -void AudioReceiveStream::SetMinimumPlayoutDelay(int delay_ms) { +bool AudioReceiveStream::SetMinimumPlayoutDelay(int delay_ms) { RTC_DCHECK_RUN_ON(&module_process_thread_checker_); return channel_receive_->SetMinimumPlayoutDelay(delay_ms); } @@ -349,14 +350,6 @@ void AudioReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) { channel_receive_->ReceivedRTCPPacket(packet, length); } -void AudioReceiveStream::OnRtpPacket(const RtpPacketReceived& packet) { - // TODO(solenberg): Tests call this function on a network thread, libjingle - // calls on the worker thread. We should move towards always using a network - // thread. Then this check can be enabled. - // RTC_DCHECK(!thread_checker_.IsCurrent()); - channel_receive_->OnRtpPacket(packet); -} - const webrtc::AudioReceiveStream::Config& AudioReceiveStream::config() const { RTC_DCHECK_RUN_ON(&worker_thread_checker_); return config_; diff --git a/TMessagesProj/jni/voip/webrtc/audio/audio_receive_stream.h b/TMessagesProj/jni/voip/webrtc/audio/audio_receive_stream.h index c197aa883..32f8b60d5 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/audio_receive_stream.h +++ b/TMessagesProj/jni/voip/webrtc/audio/audio_receive_stream.h @@ -21,7 +21,6 @@ #include "call/audio_receive_stream.h" #include "call/syncable.h" #include "modules/rtp_rtcp/source/source_tracker.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/thread_checker.h" #include "system_wrappers/include/clock.h" @@ -61,25 +60,25 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream, const rtc::scoped_refptr& audio_state, webrtc::RtcEventLog* event_log, std::unique_ptr channel_receive); + + AudioReceiveStream() = delete; + AudioReceiveStream(const AudioReceiveStream&) = delete; + AudioReceiveStream& operator=(const AudioReceiveStream&) = delete; + ~AudioReceiveStream() override; // webrtc::AudioReceiveStream implementation. void Reconfigure(const webrtc::AudioReceiveStream::Config& config) override; void Start() override; void Stop() override; - webrtc::AudioReceiveStream::Stats GetStats() const override; + webrtc::AudioReceiveStream::Stats GetStats( + bool get_and_clear_legacy_stats) const override; void SetSink(AudioSinkInterface* sink) override; void SetGain(float gain) override; bool SetBaseMinimumPlayoutDelayMs(int delay_ms) override; int GetBaseMinimumPlayoutDelayMs() const override; std::vector GetSources() const override; - // TODO(nisse): We don't formally implement RtpPacketSinkInterface, and this - // method shouldn't be needed. But it's currently used by the - // AudioReceiveStreamTest.ReceiveRtpPacket unittest. Figure out if that test - // shuld be refactored or deleted, and then delete this method. - void OnRtpPacket(const RtpPacketReceived& packet); - // AudioMixer::Source AudioFrameInfo GetAudioFrameWithInfo(int sample_rate_hz, AudioFrame* audio_frame) override; @@ -93,7 +92,7 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream, int64_t* time_ms) const override; void SetEstimatedPlayoutNtpTimestampMs(int64_t ntp_timestamp_ms, int64_t time_ms) override; - void SetMinimumPlayoutDelay(int delay_ms) override; + bool SetMinimumPlayoutDelay(int delay_ms) override; void AssociateSendStream(AudioSendStream* send_stream); void DeliverRtcp(const uint8_t* packet, size_t length); @@ -118,8 +117,6 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream, bool playing_ RTC_GUARDED_BY(worker_thread_checker_) = false; std::unique_ptr rtp_stream_receiver_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioReceiveStream); }; } // namespace internal } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/audio/audio_send_stream.cc b/TMessagesProj/jni/voip/webrtc/audio/audio_send_stream.cc index 1856902d5..1c0a32f86 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/audio_send_stream.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/audio_send_stream.cc @@ -149,7 +149,7 @@ AudioSendStream::AudioSendStream( enable_audio_alr_probing_( !field_trial::IsDisabled("WebRTC-Audio-AlrProbing")), send_side_bwe_with_overhead_( - field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), + !field_trial::IsDisabled("WebRTC-SendSideBwe-WithOverhead")), config_(Config(/*send_transport=*/nullptr)), audio_state_(audio_state), channel_send_(std::move(channel_send)), @@ -638,11 +638,11 @@ bool AudioSendStream::SetupSendCodec(const Config& new_config) { if (new_config.audio_network_adaptor_config) { if (encoder->EnableAudioNetworkAdaptor( *new_config.audio_network_adaptor_config, event_log_)) { - RTC_DLOG(LS_INFO) << "Audio network adaptor enabled on SSRC " - << new_config.rtp.ssrc; + RTC_LOG(LS_INFO) << "Audio network adaptor enabled on SSRC " + << new_config.rtp.ssrc; } else { - RTC_DLOG(LS_INFO) << "Failed to enable Audio network adaptor on SSRC " - << new_config.rtp.ssrc; + RTC_LOG(LS_INFO) << "Failed to enable Audio network adaptor on SSRC " + << new_config.rtp.ssrc; } } @@ -734,21 +734,29 @@ void AudioSendStream::ReconfigureANA(const Config& new_config) { return; } if (new_config.audio_network_adaptor_config) { + // This lock needs to be acquired before CallEncoder, since it aquires + // another lock and we need to maintain the same order at all call sites to + // avoid deadlock. + MutexLock lock(&overhead_per_packet_lock_); + size_t overhead = GetPerPacketOverheadBytes(); channel_send_->CallEncoder([&](AudioEncoder* encoder) { if (encoder->EnableAudioNetworkAdaptor( *new_config.audio_network_adaptor_config, event_log_)) { - RTC_DLOG(LS_INFO) << "Audio network adaptor enabled on SSRC " - << new_config.rtp.ssrc; + RTC_LOG(LS_INFO) << "Audio network adaptor enabled on SSRC " + << new_config.rtp.ssrc; + if (overhead > 0) { + encoder->OnReceivedOverhead(overhead); + } } else { - RTC_DLOG(LS_INFO) << "Failed to enable Audio network adaptor on SSRC " - << new_config.rtp.ssrc; + RTC_LOG(LS_INFO) << "Failed to enable Audio network adaptor on SSRC " + << new_config.rtp.ssrc; } }); } else { channel_send_->CallEncoder( [&](AudioEncoder* encoder) { encoder->DisableAudioNetworkAdaptor(); }); - RTC_DLOG(LS_INFO) << "Audio network adaptor disabled on SSRC " - << new_config.rtp.ssrc; + RTC_LOG(LS_INFO) << "Audio network adaptor disabled on SSRC " + << new_config.rtp.ssrc; } } diff --git a/TMessagesProj/jni/voip/webrtc/audio/audio_send_stream.h b/TMessagesProj/jni/voip/webrtc/audio/audio_send_stream.h index 7bc318312..12fcb9f21 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/audio_send_stream.h +++ b/TMessagesProj/jni/voip/webrtc/audio/audio_send_stream.h @@ -21,7 +21,6 @@ #include "call/audio_state.h" #include "call/bitrate_allocator.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/experiments/struct_parameters_parser.h" #include "rtc_base/race_checker.h" #include "rtc_base/synchronization/mutex.h" @@ -75,6 +74,11 @@ class AudioSendStream final : public webrtc::AudioSendStream, RtcEventLog* event_log, const absl::optional& suspended_rtp_state, std::unique_ptr channel_send); + + AudioSendStream() = delete; + AudioSendStream(const AudioSendStream&) = delete; + AudioSendStream& operator=(const AudioSendStream&) = delete; + ~AudioSendStream() override; // webrtc::AudioSendStream implementation. @@ -206,8 +210,6 @@ class AudioSendStream final : public webrtc::AudioSendStream, size_t total_packet_overhead_bytes_ RTC_GUARDED_BY(worker_queue_) = 0; absl::optional> frame_length_range_ RTC_GUARDED_BY(worker_queue_); - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream); }; } // namespace internal } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/audio/audio_state.cc b/TMessagesProj/jni/voip/webrtc/audio/audio_state.cc index 73366e20a..566bae131 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/audio_state.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/audio_state.cc @@ -28,7 +28,9 @@ namespace internal { AudioState::AudioState(const AudioState::Config& config) : config_(config), - audio_transport_(config_.audio_mixer, config_.audio_processing.get()) { + audio_transport_(config_.audio_mixer, + config_.audio_processing.get(), + config_.async_audio_processing_factory.get()) { process_thread_checker_.Detach(); RTC_DCHECK(config_.audio_mixer); RTC_DCHECK(config_.audio_device_module); diff --git a/TMessagesProj/jni/voip/webrtc/audio/audio_state.h b/TMessagesProj/jni/voip/webrtc/audio/audio_state.h index 70c720832..5e766428d 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/audio_state.h +++ b/TMessagesProj/jni/voip/webrtc/audio/audio_state.h @@ -18,7 +18,6 @@ #include "audio/audio_transport_impl.h" #include "audio/null_audio_poller.h" #include "call/audio_state.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/ref_count.h" #include "rtc_base/thread_checker.h" @@ -32,6 +31,11 @@ namespace internal { class AudioState : public webrtc::AudioState { public: explicit AudioState(const AudioState::Config& config); + + AudioState() = delete; + AudioState(const AudioState&) = delete; + AudioState& operator=(const AudioState&) = delete; + ~AudioState() override; AudioProcessing* audio_processing() override; @@ -82,8 +86,6 @@ class AudioState : public webrtc::AudioState { size_t num_channels = 0; }; std::map sending_streams_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioState); }; } // namespace internal } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/audio/audio_transport_impl.cc b/TMessagesProj/jni/voip/webrtc/audio/audio_transport_impl.cc index 11b37ffcf..8710ced9b 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/audio_transport_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/audio_transport_impl.cc @@ -17,6 +17,7 @@ #include "audio/remix_resample.h" #include "audio/utility/audio_frame_operations.h" #include "call/audio_sender.h" +#include "modules/async_audio_processing/async_audio_processing.h" #include "modules/audio_processing/include/audio_frame_proxies.h" #include "rtc_base/checks.h" @@ -83,9 +84,19 @@ int Resample(const AudioFrame& frame, } } // namespace -AudioTransportImpl::AudioTransportImpl(AudioMixer* mixer, - AudioProcessing* audio_processing) - : audio_processing_(audio_processing), mixer_(mixer) { +AudioTransportImpl::AudioTransportImpl( + AudioMixer* mixer, + AudioProcessing* audio_processing, + AsyncAudioProcessing::Factory* async_audio_processing_factory) + : audio_processing_(audio_processing), + async_audio_processing_( + async_audio_processing_factory + ? async_audio_processing_factory->CreateAsyncAudioProcessing( + [this](std::unique_ptr frame) { + this->SendProcessedData(std::move(frame)); + }) + : nullptr), + mixer_(mixer) { RTC_DCHECK(mixer); } @@ -151,23 +162,34 @@ int32_t AudioTransportImpl::RecordedDataIsAvailable( { MutexLock lock(&capture_lock_); typing_noise_detected_ = typing_detected; - - RTC_DCHECK_GT(audio_frame->samples_per_channel_, 0); - if (!audio_senders_.empty()) { - auto it = audio_senders_.begin(); - while (++it != audio_senders_.end()) { - std::unique_ptr audio_frame_copy(new AudioFrame()); - audio_frame_copy->CopyFrom(*audio_frame); - (*it)->SendAudioData(std::move(audio_frame_copy)); - } - // Send the original frame to the first stream w/o copying. - (*audio_senders_.begin())->SendAudioData(std::move(audio_frame)); - } } + RTC_DCHECK_GT(audio_frame->samples_per_channel_, 0); + if (async_audio_processing_) + async_audio_processing_->Process(std::move(audio_frame)); + else + SendProcessedData(std::move(audio_frame)); + return 0; } +void AudioTransportImpl::SendProcessedData( + std::unique_ptr audio_frame) { + RTC_DCHECK_GT(audio_frame->samples_per_channel_, 0); + MutexLock lock(&capture_lock_); + if (audio_senders_.empty()) + return; + + auto it = audio_senders_.begin(); + while (++it != audio_senders_.end()) { + auto audio_frame_copy = std::make_unique(); + audio_frame_copy->CopyFrom(*audio_frame); + (*it)->SendAudioData(std::move(audio_frame_copy)); + } + // Send the original frame to the first stream w/o copying. + (*audio_senders_.begin())->SendAudioData(std::move(audio_frame)); +} + // Mix all received streams, feed the result to the AudioProcessing module, then // resample the result to the requested output rate. int32_t AudioTransportImpl::NeedMorePlayData(const size_t nSamples, diff --git a/TMessagesProj/jni/voip/webrtc/audio/audio_transport_impl.h b/TMessagesProj/jni/voip/webrtc/audio/audio_transport_impl.h index 1643a2997..f3ca2fa84 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/audio_transport_impl.h +++ b/TMessagesProj/jni/voip/webrtc/audio/audio_transport_impl.h @@ -11,15 +11,16 @@ #ifndef AUDIO_AUDIO_TRANSPORT_IMPL_H_ #define AUDIO_AUDIO_TRANSPORT_IMPL_H_ +#include #include #include "api/audio/audio_mixer.h" #include "api/scoped_refptr.h" #include "common_audio/resampler/include/push_resampler.h" +#include "modules/async_audio_processing/async_audio_processing.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" #include "modules/audio_processing/typing_detection.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -29,7 +30,15 @@ class AudioSender; class AudioTransportImpl : public AudioTransport { public: - AudioTransportImpl(AudioMixer* mixer, AudioProcessing* audio_processing); + AudioTransportImpl( + AudioMixer* mixer, + AudioProcessing* audio_processing, + AsyncAudioProcessing::Factory* async_audio_processing_factory); + + AudioTransportImpl() = delete; + AudioTransportImpl(const AudioTransportImpl&) = delete; + AudioTransportImpl& operator=(const AudioTransportImpl&) = delete; + ~AudioTransportImpl() override; int32_t RecordedDataIsAvailable(const void* audioSamples, @@ -67,10 +76,16 @@ class AudioTransportImpl : public AudioTransport { bool typing_noise_detected() const; private: + void SendProcessedData(std::unique_ptr audio_frame); + // Shared. AudioProcessing* audio_processing_ = nullptr; // Capture side. + + // Thread-safe. + const std::unique_ptr async_audio_processing_; + mutable Mutex capture_lock_; std::vector audio_senders_ RTC_GUARDED_BY(capture_lock_); int send_sample_rate_hz_ RTC_GUARDED_BY(capture_lock_) = 8000; @@ -81,12 +96,11 @@ class AudioTransportImpl : public AudioTransport { TypingDetection typing_detection_; // Render side. + rtc::scoped_refptr mixer_; AudioFrame mixed_frame_; // Converts mixed audio to the audio device output rate. PushResampler render_resampler_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioTransportImpl); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/audio/channel_receive.cc b/TMessagesProj/jni/voip/webrtc/audio/channel_receive.cc index 9cbaabbbb..2788dacf7 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/channel_receive.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/channel_receive.cc @@ -128,12 +128,13 @@ class ChannelReceive : public ChannelReceiveInterface { double GetTotalOutputDuration() const override; // Stats. - NetworkStatistics GetNetworkStatistics() const override; + NetworkStatistics GetNetworkStatistics( + bool get_and_clear_legacy_stats) const override; AudioDecodingCallStats GetDecodingCallStatistics() const override; // Audio+Video Sync. uint32_t GetDelayEstimate() const override; - void SetMinimumPlayoutDelay(int delayMs) override; + bool SetMinimumPlayoutDelay(int delayMs) override; bool GetPlayoutRtpTimestamp(uint32_t* rtp_timestamp, int64_t* time_ms) const override; void SetEstimatedPlayoutNtpTimestampMs(int64_t ntp_timestamp_ms, @@ -801,10 +802,11 @@ void ChannelReceive::SetDepacketizerToDecoderFrameTransformer( InitFrameTransformerDelegate(std::move(frame_transformer)); } -NetworkStatistics ChannelReceive::GetNetworkStatistics() const { +NetworkStatistics ChannelReceive::GetNetworkStatistics( + bool get_and_clear_legacy_stats) const { RTC_DCHECK(worker_thread_checker_.IsCurrent()); NetworkStatistics stats; - acm_receiver_.GetNetworkStatistics(&stats); + acm_receiver_.GetNetworkStatistics(&stats, get_and_clear_legacy_stats); return stats; } @@ -822,7 +824,7 @@ uint32_t ChannelReceive::GetDelayEstimate() const { return acm_receiver_.FilteredCurrentDelayMs() + playout_delay_ms_; } -void ChannelReceive::SetMinimumPlayoutDelay(int delay_ms) { +bool ChannelReceive::SetMinimumPlayoutDelay(int delay_ms) { RTC_DCHECK(module_process_thread_checker_.IsCurrent()); // Limit to range accepted by both VoE and ACM, so we're at least getting as // close as possible, instead of failing. @@ -831,7 +833,9 @@ void ChannelReceive::SetMinimumPlayoutDelay(int delay_ms) { if (acm_receiver_.SetMinimumDelay(delay_ms) != 0) { RTC_DLOG(LS_ERROR) << "SetMinimumPlayoutDelay() failed to set min playout delay"; + return false; } + return true; } bool ChannelReceive::GetPlayoutRtpTimestamp(uint32_t* rtp_timestamp, diff --git a/TMessagesProj/jni/voip/webrtc/audio/channel_receive.h b/TMessagesProj/jni/voip/webrtc/audio/channel_receive.h index bc02ff302..eef2db425 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/channel_receive.h +++ b/TMessagesProj/jni/voip/webrtc/audio/channel_receive.h @@ -99,12 +99,13 @@ class ChannelReceiveInterface : public RtpPacketSinkInterface { virtual double GetTotalOutputDuration() const = 0; // Stats. - virtual NetworkStatistics GetNetworkStatistics() const = 0; + virtual NetworkStatistics GetNetworkStatistics( + bool get_and_clear_legacy_stats) const = 0; virtual AudioDecodingCallStats GetDecodingCallStatistics() const = 0; // Audio+Video Sync. virtual uint32_t GetDelayEstimate() const = 0; - virtual void SetMinimumPlayoutDelay(int delay_ms) = 0; + virtual bool SetMinimumPlayoutDelay(int delay_ms) = 0; virtual bool GetPlayoutRtpTimestamp(uint32_t* rtp_timestamp, int64_t* time_ms) const = 0; virtual void SetEstimatedPlayoutNtpTimestampMs(int64_t ntp_timestamp_ms, diff --git a/TMessagesProj/jni/voip/webrtc/audio/mock_voe_channel_proxy.h b/TMessagesProj/jni/voip/webrtc/audio/mock_voe_channel_proxy.h index 542358f68..52e5b2fc8 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/mock_voe_channel_proxy.h +++ b/TMessagesProj/jni/voip/webrtc/audio/mock_voe_channel_proxy.h @@ -35,7 +35,10 @@ class MockChannelReceive : public voe::ChannelReceiveInterface { (override)); MOCK_METHOD(void, ResetReceiverCongestionControlObjects, (), (override)); MOCK_METHOD(CallReceiveStatistics, GetRTCPStatistics, (), (const, override)); - MOCK_METHOD(NetworkStatistics, GetNetworkStatistics, (), (const, override)); + MOCK_METHOD(NetworkStatistics, + GetNetworkStatistics, + (bool), + (const, override)); MOCK_METHOD(AudioDecodingCallStats, GetDecodingCallStatistics, (), @@ -76,7 +79,7 @@ class MockChannelReceive : public voe::ChannelReceiveInterface { GetSyncInfo, (), (const, override)); - MOCK_METHOD(void, SetMinimumPlayoutDelay, (int delay_ms), (override)); + MOCK_METHOD(bool, SetMinimumPlayoutDelay, (int delay_ms), (override)); MOCK_METHOD(bool, SetBaseMinimumPlayoutDelayMs, (int delay_ms), (override)); MOCK_METHOD(int, GetBaseMinimumPlayoutDelayMs, (), (const, override)); MOCK_METHOD((absl::optional>), diff --git a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_channel.cc b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_channel.cc index 43d4d0f15..dc53acf3a 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_channel.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_channel.cc @@ -129,4 +129,34 @@ void AudioChannel::StopPlay() { } } +IngressStatistics AudioChannel::GetIngressStatistics() { + IngressStatistics ingress_stats; + NetworkStatistics stats = ingress_->GetNetworkStatistics(); + ingress_stats.neteq_stats.total_samples_received = stats.totalSamplesReceived; + ingress_stats.neteq_stats.concealed_samples = stats.concealedSamples; + ingress_stats.neteq_stats.concealment_events = stats.concealmentEvents; + ingress_stats.neteq_stats.jitter_buffer_delay_ms = stats.jitterBufferDelayMs; + ingress_stats.neteq_stats.jitter_buffer_emitted_count = + stats.jitterBufferEmittedCount; + ingress_stats.neteq_stats.jitter_buffer_target_delay_ms = + stats.jitterBufferTargetDelayMs; + ingress_stats.neteq_stats.inserted_samples_for_deceleration = + stats.insertedSamplesForDeceleration; + ingress_stats.neteq_stats.removed_samples_for_acceleration = + stats.removedSamplesForAcceleration; + ingress_stats.neteq_stats.silent_concealed_samples = + stats.silentConcealedSamples; + ingress_stats.neteq_stats.fec_packets_received = stats.fecPacketsReceived; + ingress_stats.neteq_stats.fec_packets_discarded = stats.fecPacketsDiscarded; + ingress_stats.neteq_stats.delayed_packet_outage_samples = + stats.delayedPacketOutageSamples; + ingress_stats.neteq_stats.relative_packet_arrival_delay_ms = + stats.relativePacketArrivalDelayMs; + ingress_stats.neteq_stats.interruption_count = stats.interruptionCount; + ingress_stats.neteq_stats.total_interruption_duration_ms = + stats.totalInterruptionDurationMs; + ingress_stats.total_duration = ingress_->GetOutputTotalDuration(); + return ingress_stats; +} + } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_channel.h b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_channel.h index 12138ee67..5bc748359 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_channel.h +++ b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_channel.h @@ -18,6 +18,7 @@ #include "api/task_queue/task_queue_factory.h" #include "api/voip/voip_base.h" +#include "api/voip/voip_statistics.h" #include "audio/voip/audio_egress.h" #include "audio/voip/audio_ingress.h" #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" @@ -63,6 +64,13 @@ class AudioChannel : public rtc::RefCountInterface { absl::optional GetEncoderFormat() const { return egress_->GetEncoderFormat(); } + void RegisterTelephoneEventType(int rtp_payload_type, int sample_rate_hz) { + egress_->RegisterTelephoneEventType(rtp_payload_type, sample_rate_hz); + } + bool SendTelephoneEvent(int dtmf_event, int duration_ms) { + return egress_->SendTelephoneEvent(dtmf_event, duration_ms); + } + void SetMute(bool enable) { egress_->SetMute(enable); } // APIs relayed to AudioIngress. bool IsPlaying() const { return ingress_->IsPlaying(); } @@ -75,6 +83,28 @@ class AudioChannel : public rtc::RefCountInterface { void SetReceiveCodecs(const std::map& codecs) { ingress_->SetReceiveCodecs(codecs); } + IngressStatistics GetIngressStatistics(); + + // See comments on the methods used from AudioEgress and AudioIngress. + // Conversion to double is following what is done in + // DoubleAudioLevelFromIntAudioLevel method in rtc_stats_collector.cc to be + // consistent. + double GetInputAudioLevel() const { + return egress_->GetInputAudioLevel() / 32767.0; + } + double GetInputTotalEnergy() const { return egress_->GetInputTotalEnergy(); } + double GetInputTotalDuration() const { + return egress_->GetInputTotalDuration(); + } + double GetOutputAudioLevel() const { + return ingress_->GetOutputAudioLevel() / 32767.0; + } + double GetOutputTotalEnergy() const { + return ingress_->GetOutputTotalEnergy(); + } + double GetOutputTotalDuration() const { + return ingress_->GetOutputTotalDuration(); + } private: // ChannelId that this audio channel belongs for logging purpose. diff --git a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_egress.cc b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_egress.cc index 90e069e1c..1162824c9 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_egress.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_egress.cc @@ -80,6 +80,12 @@ void AudioEgress::SendAudioData(std::unique_ptr audio_frame) { return; } + double duration_seconds = + static_cast(audio_frame->samples_per_channel_) / + audio_frame->sample_rate_hz_; + + input_audio_level_.ComputeLevel(*audio_frame, duration_seconds); + AudioFrameOperations::Mute(audio_frame.get(), encoder_context_.previously_muted_, encoder_context_.mute_); diff --git a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_egress.h b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_egress.h index 6b2d37471..fcd9ed0f2 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_egress.h +++ b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_egress.h @@ -16,6 +16,7 @@ #include "api/audio_codecs/audio_format.h" #include "api/task_queue/task_queue_factory.h" +#include "audio/audio_level.h" #include "audio/utility/audio_frame_operations.h" #include "call/audio_sender.h" #include "modules/audio_coding/include/audio_coding_module.h" @@ -89,6 +90,16 @@ class AudioEgress : public AudioSender, public AudioPacketizationCallback { // otherwise false when the dtmf queue reached maximum of 20 events. bool SendTelephoneEvent(int dtmf_event, int duration_ms); + // See comments on LevelFullRange, TotalEnergy, TotalDuration from + // audio/audio_level.h. + int GetInputAudioLevel() const { return input_audio_level_.LevelFullRange(); } + double GetInputTotalEnergy() const { + return input_audio_level_.TotalEnergy(); + } + double GetInputTotalDuration() const { + return input_audio_level_.TotalDuration(); + } + // Implementation of AudioSender interface. void SendAudioData(std::unique_ptr audio_frame) override; @@ -119,6 +130,9 @@ class AudioEgress : public AudioSender, public AudioPacketizationCallback { // Synchronization is handled internally by AudioCodingModule. const std::unique_ptr audio_coding_; + // Synchronization is handled internally by voe::AudioLevel. + voe::AudioLevel input_audio_level_; + // Struct that holds all variables used by encoder task queue. struct EncoderContext { // Offset used to mark rtp timestamp in sample rate unit in diff --git a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_ingress.cc b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_ingress.cc index 0bddb4280..07def9955 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_ingress.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_ingress.cc @@ -73,6 +73,12 @@ AudioMixer::Source::AudioFrameInfo AudioIngress::GetAudioFrameWithInfo( constexpr double kAudioSampleDurationSeconds = 0.01; output_audio_level_.ComputeLevel(*audio_frame, kAudioSampleDurationSeconds); + // If caller invoked StopPlay(), then mute the frame. + if (!playing_) { + AudioFrameOperations::Mute(audio_frame); + muted = true; + } + // Set first rtp timestamp with first audio frame with valid timestamp. if (first_rtp_timestamp_ < 0 && audio_frame->timestamp_ != 0) { first_rtp_timestamp_ = audio_frame->timestamp_; @@ -127,10 +133,6 @@ void AudioIngress::SetReceiveCodecs( } void AudioIngress::ReceivedRTPPacket(rtc::ArrayView rtp_packet) { - if (!IsPlaying()) { - return; - } - RtpPacketReceived rtp_packet_received; rtp_packet_received.Parse(rtp_packet.data(), rtp_packet.size()); diff --git a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_ingress.h b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_ingress.h index d09de606d..d3680e0f0 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/voip/audio_ingress.h +++ b/TMessagesProj/jni/voip/webrtc/audio/voip/audio_ingress.h @@ -68,13 +68,15 @@ class AudioIngress : public AudioMixer::Source { void ReceivedRTPPacket(rtc::ArrayView rtp_packet); void ReceivedRTCPPacket(rtc::ArrayView rtcp_packet); - // Retrieve highest speech output level in last 100 ms. Note that - // this isn't RMS but absolute raw audio level on int16_t sample unit. - // Therefore, the return value will vary between 0 ~ 0xFFFF. This type of - // value may be useful to be used for measuring active speaker gauge. - int GetSpeechOutputLevelFullRange() const { + // See comments on LevelFullRange, TotalEnergy, TotalDuration from + // audio/audio_level.h. + int GetOutputAudioLevel() const { return output_audio_level_.LevelFullRange(); } + double GetOutputTotalEnergy() { return output_audio_level_.TotalEnergy(); } + double GetOutputTotalDuration() { + return output_audio_level_.TotalDuration(); + } // Returns network round trip time (RTT) measued by RTCP exchange with // remote media endpoint. RTT value -1 indicates that it's not initialized. @@ -82,12 +84,8 @@ class AudioIngress : public AudioMixer::Source { NetworkStatistics GetNetworkStatistics() const { NetworkStatistics stats; - acm_receiver_.GetNetworkStatistics(&stats); - return stats; - } - AudioDecodingCallStats GetDecodingStatistics() const { - AudioDecodingCallStats stats; - acm_receiver_.GetDecodingCallStatistics(&stats); + acm_receiver_.GetNetworkStatistics(&stats, + /*get_and_clear_legacy_stats=*/false); return stats; } diff --git a/TMessagesProj/jni/voip/webrtc/audio/voip/voip_core.cc b/TMessagesProj/jni/voip/webrtc/audio/voip/voip_core.cc index 639022363..ac29fbf6d 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/voip/voip_core.cc +++ b/TMessagesProj/jni/voip/webrtc/audio/voip/voip_core.cc @@ -37,29 +37,39 @@ static constexpr int kMaxChannelId = 100000; } // namespace -bool VoipCore::Init(rtc::scoped_refptr encoder_factory, - rtc::scoped_refptr decoder_factory, - std::unique_ptr task_queue_factory, - rtc::scoped_refptr audio_device_module, - rtc::scoped_refptr audio_processing) { +VoipCore::VoipCore(rtc::scoped_refptr encoder_factory, + rtc::scoped_refptr decoder_factory, + std::unique_ptr task_queue_factory, + rtc::scoped_refptr audio_device_module, + rtc::scoped_refptr audio_processing, + std::unique_ptr process_thread) { encoder_factory_ = std::move(encoder_factory); decoder_factory_ = std::move(decoder_factory); task_queue_factory_ = std::move(task_queue_factory); audio_device_module_ = std::move(audio_device_module); + audio_processing_ = std::move(audio_processing); + process_thread_ = std::move(process_thread); - process_thread_ = ProcessThread::Create("ModuleProcessThread"); - audio_mixer_ = AudioMixerImpl::Create(); - - if (audio_processing) { - audio_processing_ = std::move(audio_processing); - AudioProcessing::Config apm_config = audio_processing_->GetConfig(); - apm_config.echo_canceller.enabled = true; - audio_processing_->ApplyConfig(apm_config); + if (!process_thread_) { + process_thread_ = ProcessThread::Create("ModuleProcessThread"); } + audio_mixer_ = AudioMixerImpl::Create(); // AudioTransportImpl depends on audio mixer and audio processing instances. audio_transport_ = std::make_unique( - audio_mixer_.get(), audio_processing_.get()); + audio_mixer_.get(), audio_processing_.get(), nullptr); +} + +bool VoipCore::InitializeIfNeeded() { + // |audio_device_module_| internally owns a lock and the whole logic here + // needs to be executed atomically once using another lock in VoipCore. + // Further changes in this method will need to make sure that no deadlock is + // introduced in the future. + MutexLock lock(&lock_); + + if (initialized_) { + return true; + } // Initialize ADM. if (audio_device_module_->Init() != 0) { @@ -72,7 +82,6 @@ bool VoipCore::Init(rtc::scoped_refptr encoder_factory, // recording device functioning (e.g webinar where only speaker is available). // It's also possible that there are other audio devices available that may // work. - // TODO(natim@webrtc.org): consider moving this part out of initialization. // Initialize default speaker device. if (audio_device_module_->SetPlayoutDevice(kAudioDeviceId) != 0) { @@ -113,13 +122,15 @@ bool VoipCore::Init(rtc::scoped_refptr encoder_factory, RTC_LOG(LS_WARNING) << "Unable to register audio callback."; } + initialized_ = true; + return true; } absl::optional VoipCore::CreateChannel( Transport* transport, absl::optional local_ssrc) { - absl::optional channel; + absl::optional channel_id; // Set local ssrc to random if not set by caller. if (!local_ssrc) { @@ -127,16 +138,22 @@ absl::optional VoipCore::CreateChannel( local_ssrc = random.Rand(); } - rtc::scoped_refptr audio_channel = + rtc::scoped_refptr channel = new rtc::RefCountedObject( transport, local_ssrc.value(), task_queue_factory_.get(), process_thread_.get(), audio_mixer_.get(), decoder_factory_); + // Check if we need to start the process thread. + bool start_process_thread = false; + { MutexLock lock(&lock_); - channel = static_cast(next_channel_id_); - channels_[*channel] = audio_channel; + // Start process thread if the channel is the first one. + start_process_thread = channels_.empty(); + + channel_id = static_cast(next_channel_id_); + channels_[*channel_id] = channel; next_channel_id_++; if (next_channel_id_ >= kMaxChannelId) { next_channel_id_ = 0; @@ -144,41 +161,64 @@ absl::optional VoipCore::CreateChannel( } // Set ChannelId in audio channel for logging/debugging purpose. - audio_channel->SetId(*channel); + channel->SetId(*channel_id); - return channel; + if (start_process_thread) { + process_thread_->Start(); + } + + return channel_id; } -void VoipCore::ReleaseChannel(ChannelId channel) { +void VoipCore::ReleaseChannel(ChannelId channel_id) { // Destroy channel outside of the lock. - rtc::scoped_refptr audio_channel; + rtc::scoped_refptr channel; + + bool no_channels_after_release = false; + { MutexLock lock(&lock_); - auto iter = channels_.find(channel); + auto iter = channels_.find(channel_id); if (iter != channels_.end()) { - audio_channel = std::move(iter->second); + channel = std::move(iter->second); channels_.erase(iter); } + + no_channels_after_release = channels_.empty(); } - if (!audio_channel) { - RTC_LOG(LS_WARNING) << "Channel " << channel << " not found"; + + if (!channel) { + RTC_LOG(LS_WARNING) << "Channel " << channel_id << " not found"; + } + + if (no_channels_after_release) { + // Release audio channel first to have it DeRegisterModule first. + channel = nullptr; + process_thread_->Stop(); + + // Make sure to stop playout on ADM if it is playing. + if (audio_device_module_->Playing()) { + if (audio_device_module_->StopPlayout() != 0) { + RTC_LOG(LS_WARNING) << "StopPlayout failed"; + } + } } } -rtc::scoped_refptr VoipCore::GetChannel(ChannelId channel) { - rtc::scoped_refptr audio_channel; +rtc::scoped_refptr VoipCore::GetChannel(ChannelId channel_id) { + rtc::scoped_refptr channel; { MutexLock lock(&lock_); - auto iter = channels_.find(channel); + auto iter = channels_.find(channel_id); if (iter != channels_.end()) { - audio_channel = iter->second; + channel = iter->second; } } - if (!audio_channel) { - RTC_LOG(LS_ERROR) << "Channel " << channel << " not found"; + if (!channel) { + RTC_LOG(LS_ERROR) << "Channel " << channel_id << " not found"; } - return audio_channel; + return channel; } bool VoipCore::UpdateAudioTransportWithSenders() { @@ -216,6 +256,11 @@ bool VoipCore::UpdateAudioTransportWithSenders() { // Depending on availability of senders, turn on or off ADM recording. if (!audio_senders.empty()) { + // Initialize audio device module and default device if needed. + if (!InitializeIfNeeded()) { + return false; + } + if (!audio_device_module_->Recording()) { if (audio_device_module_->InitRecording() != 0) { RTC_LOG(LS_ERROR) << "InitRecording failed"; @@ -236,29 +281,45 @@ bool VoipCore::UpdateAudioTransportWithSenders() { return true; } -bool VoipCore::StartSend(ChannelId channel) { - auto audio_channel = GetChannel(channel); - if (!audio_channel || !audio_channel->StartSend()) { +bool VoipCore::StartSend(ChannelId channel_id) { + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (!channel || !channel->StartSend()) { return false; } return UpdateAudioTransportWithSenders(); } -bool VoipCore::StopSend(ChannelId channel) { - auto audio_channel = GetChannel(channel); - if (!audio_channel) { +bool VoipCore::StopSend(ChannelId channel_id) { + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (!channel) { return false; } - audio_channel->StopSend(); + channel->StopSend(); return UpdateAudioTransportWithSenders(); } -bool VoipCore::StartPlayout(ChannelId channel) { - auto audio_channel = GetChannel(channel); - if (!audio_channel || !audio_channel->StartPlay()) { +bool VoipCore::StartPlayout(ChannelId channel_id) { + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (!channel) { + return false; + } + + if (channel->IsPlaying()) { + return true; + } + + if (!channel->StartPlay()) { + return false; + } + + // Initialize audio device module and default device if needed. + if (!InitializeIfNeeded()) { return false; } @@ -275,69 +336,119 @@ bool VoipCore::StartPlayout(ChannelId channel) { return true; } -bool VoipCore::StopPlayout(ChannelId channel) { - auto audio_channel = GetChannel(channel); - if (!audio_channel) { +bool VoipCore::StopPlayout(ChannelId channel_id) { + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (!channel) { return false; } - audio_channel->StopPlay(); + channel->StopPlay(); - bool stop_device = true; - { - MutexLock lock(&lock_); - for (auto kv : channels_) { - rtc::scoped_refptr& channel = kv.second; - if (channel->IsPlaying()) { - stop_device = false; - break; - } - } - } - - if (stop_device && audio_device_module_->Playing()) { - if (audio_device_module_->StopPlayout() != 0) { - RTC_LOG(LS_ERROR) << "StopPlayout failed"; - return false; - } - } return true; } -void VoipCore::ReceivedRTPPacket(ChannelId channel, +void VoipCore::ReceivedRTPPacket(ChannelId channel_id, rtc::ArrayView rtp_packet) { - // Failure to locate channel is logged internally in GetChannel. - if (auto audio_channel = GetChannel(channel)) { - audio_channel->ReceivedRTPPacket(rtp_packet); + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (channel) { + channel->ReceivedRTPPacket(rtp_packet); } } -void VoipCore::ReceivedRTCPPacket(ChannelId channel, +void VoipCore::ReceivedRTCPPacket(ChannelId channel_id, rtc::ArrayView rtcp_packet) { - // Failure to locate channel is logged internally in GetChannel. - if (auto audio_channel = GetChannel(channel)) { - audio_channel->ReceivedRTCPPacket(rtcp_packet); + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (channel) { + channel->ReceivedRTCPPacket(rtcp_packet); } } -void VoipCore::SetSendCodec(ChannelId channel, +void VoipCore::SetSendCodec(ChannelId channel_id, int payload_type, const SdpAudioFormat& encoder_format) { - // Failure to locate channel is logged internally in GetChannel. - if (auto audio_channel = GetChannel(channel)) { + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (channel) { auto encoder = encoder_factory_->MakeAudioEncoder( payload_type, encoder_format, absl::nullopt); - audio_channel->SetEncoder(payload_type, encoder_format, std::move(encoder)); + channel->SetEncoder(payload_type, encoder_format, std::move(encoder)); } } void VoipCore::SetReceiveCodecs( - ChannelId channel, + ChannelId channel_id, const std::map& decoder_specs) { - // Failure to locate channel is logged internally in GetChannel. - if (auto audio_channel = GetChannel(channel)) { - audio_channel->SetReceiveCodecs(decoder_specs); + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (channel) { + channel->SetReceiveCodecs(decoder_specs); } } +void VoipCore::RegisterTelephoneEventType(ChannelId channel_id, + int rtp_payload_type, + int sample_rate_hz) { + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (channel) { + channel->RegisterTelephoneEventType(rtp_payload_type, sample_rate_hz); + } +} + +bool VoipCore::SendDtmfEvent(ChannelId channel_id, + DtmfEvent dtmf_event, + int duration_ms) { + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (channel) { + return channel->SendTelephoneEvent(static_cast(dtmf_event), + duration_ms); + } + return false; +} + +absl::optional VoipCore::GetIngressStatistics( + ChannelId channel_id) { + rtc::scoped_refptr channel = GetChannel(channel_id); + + if (channel) { + return channel->GetIngressStatistics(); + } + return absl::nullopt; +} + +void VoipCore::SetInputMuted(ChannelId channel_id, bool enable) { + rtc::scoped_refptr channel = GetChannel(channel_id); + if (channel) { + channel->SetMute(enable); + } +} + +absl::optional VoipCore::GetInputVolumeInfo(ChannelId channel_id) { + rtc::scoped_refptr channel = GetChannel(channel_id); + if (channel) { + VolumeInfo input_volume; + input_volume.audio_level = channel->GetInputAudioLevel(); + input_volume.total_energy = channel->GetInputTotalEnergy(); + input_volume.total_duration = channel->GetInputTotalDuration(); + return input_volume; + } + return absl::nullopt; +} + +absl::optional VoipCore::GetOutputVolumeInfo(ChannelId channel_id) { + rtc::scoped_refptr channel = GetChannel(channel_id); + if (channel) { + VolumeInfo output_volume; + output_volume.audio_level = channel->GetOutputAudioLevel(); + output_volume.total_energy = channel->GetOutputTotalEnergy(); + output_volume.total_duration = channel->GetOutputTotalDuration(); + return output_volume; + } + return absl::nullopt; +} + } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/audio/voip/voip_core.h b/TMessagesProj/jni/voip/webrtc/audio/voip/voip_core.h index 22a655998..5ebf4381c 100644 --- a/TMessagesProj/jni/voip/webrtc/audio/voip/voip_core.h +++ b/TMessagesProj/jni/voip/webrtc/audio/voip/voip_core.h @@ -23,8 +23,11 @@ #include "api/task_queue/task_queue_factory.h" #include "api/voip/voip_base.h" #include "api/voip/voip_codec.h" +#include "api/voip/voip_dtmf.h" #include "api/voip/voip_engine.h" #include "api/voip/voip_network.h" +#include "api/voip/voip_statistics.h" +#include "api/voip/voip_volume_control.h" #include "audio/audio_transport_impl.h" #include "audio/voip/audio_channel.h" #include "modules/audio_device/include/audio_device.h" @@ -45,53 +48,86 @@ namespace webrtc { class VoipCore : public VoipEngine, public VoipBase, public VoipNetwork, - public VoipCodec { + public VoipCodec, + public VoipDtmf, + public VoipStatistics, + public VoipVolumeControl { public: + // Construct VoipCore with provided arguments. + // ProcessThread implementation can be injected by |process_thread| + // (mainly for testing purpose) and when set to nullptr, default + // implementation will be used. + VoipCore(rtc::scoped_refptr encoder_factory, + rtc::scoped_refptr decoder_factory, + std::unique_ptr task_queue_factory, + rtc::scoped_refptr audio_device_module, + rtc::scoped_refptr audio_processing, + std::unique_ptr process_thread = nullptr); ~VoipCore() override = default; - // Initialize VoipCore components with provided arguments. - // Returns false only when |audio_device_module| fails to initialize which - // would presumably render further processing useless. - // TODO(natim@webrtc.org): Need to report audio device errors to user layer. - bool Init(rtc::scoped_refptr encoder_factory, - rtc::scoped_refptr decoder_factory, - std::unique_ptr task_queue_factory, - rtc::scoped_refptr audio_device_module, - rtc::scoped_refptr audio_processing); - // Implements VoipEngine interfaces. VoipBase& Base() override { return *this; } VoipNetwork& Network() override { return *this; } VoipCodec& Codec() override { return *this; } + VoipDtmf& Dtmf() override { return *this; } + VoipStatistics& Statistics() override { return *this; } + VoipVolumeControl& VolumeControl() override { return *this; } // Implements VoipBase interfaces. absl::optional CreateChannel( Transport* transport, absl::optional local_ssrc) override; - void ReleaseChannel(ChannelId channel) override; - bool StartSend(ChannelId channel) override; - bool StopSend(ChannelId channel) override; - bool StartPlayout(ChannelId channel) override; - bool StopPlayout(ChannelId channel) override; + void ReleaseChannel(ChannelId channel_id) override; + bool StartSend(ChannelId channel_id) override; + bool StopSend(ChannelId channel_id) override; + bool StartPlayout(ChannelId channel_id) override; + bool StopPlayout(ChannelId channel_id) override; // Implements VoipNetwork interfaces. - void ReceivedRTPPacket(ChannelId channel, + void ReceivedRTPPacket(ChannelId channel_id, rtc::ArrayView rtp_packet) override; - void ReceivedRTCPPacket(ChannelId channel, + void ReceivedRTCPPacket(ChannelId channel_id, rtc::ArrayView rtcp_packet) override; // Implements VoipCodec interfaces. - void SetSendCodec(ChannelId channel, + void SetSendCodec(ChannelId channel_id, int payload_type, const SdpAudioFormat& encoder_format) override; void SetReceiveCodecs( - ChannelId channel, + ChannelId channel_id, const std::map& decoder_specs) override; + // Implements VoipDtmf interfaces. + void RegisterTelephoneEventType(ChannelId channel_id, + int rtp_payload_type, + int sample_rate_hz) override; + bool SendDtmfEvent(ChannelId channel_id, + DtmfEvent dtmf_event, + int duration_ms) override; + + // Implements VoipStatistics interfaces. + absl::optional GetIngressStatistics( + ChannelId channel_id) override; + + // Implements VoipVolumeControl interfaces. + void SetInputMuted(ChannelId channel_id, bool enable) override; + absl::optional GetInputVolumeInfo(ChannelId channel_id) override; + absl::optional GetOutputVolumeInfo(ChannelId channel_id) override; + private: + // Initialize ADM and default audio device if needed. + // Returns true if ADM is successfully initialized or already in such state + // (e.g called more than once). Returns false when ADM fails to initialize + // which would presumably render further processing useless. Note that such + // failure won't necessarily succeed in next initialization attempt as it + // would mean changing the ADM implementation. From Android N and onwards, the + // mobile app may not be able to gain microphone access when in background + // mode. Therefore it would be better to delay the logic as late as possible. + bool InitializeIfNeeded(); + // Fetches the corresponding AudioChannel assigned with given |channel|. // Returns nullptr if not found. - rtc::scoped_refptr GetChannel(ChannelId channel); + rtc::scoped_refptr GetChannel(ChannelId channel_id); // Updates AudioTransportImpl with a new set of actively sending AudioSender // (AudioEgress). This needs to be invoked whenever StartSend/StopSend is @@ -104,7 +140,7 @@ class VoipCore : public VoipEngine, rtc::scoped_refptr decoder_factory_; std::unique_ptr task_queue_factory_; - // Synchronization is handled internally by AudioProessing. + // Synchronization is handled internally by AudioProcessing. // Must be placed before |audio_device_module_| for proper destruction. rtc::scoped_refptr audio_processing_; @@ -132,6 +168,9 @@ class VoipCore : public VoipEngine, // ChannelId. std::unordered_map> channels_ RTC_GUARDED_BY(lock_); + + // Boolean flag to ensure initialization only occurs once. + bool initialized_ RTC_GUARDED_BY(lock_) = false; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/fake_task.cc b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/fake_task.cc deleted file mode 100644 index 1199bb955..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/fake_task.cc +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/task/sequence_manager/test/fake_task.h" - -namespace base { -namespace sequence_manager { - -FakeTask::FakeTask() : FakeTask(0 /* task_type */) {} - -FakeTask::FakeTask(TaskType task_type) - : Task(internal::PostedTask(nullptr, - OnceClosure(), - FROM_HERE, - TimeDelta(), - Nestable::kNestable, - task_type), - TimeTicks(), - EnqueueOrder(), - EnqueueOrder(), - internal::WakeUpResolution::kLow) {} - -FakeTaskTiming::FakeTaskTiming() - : TaskTiming(false /* has_wall_time */, false /* has_thread_time */) {} - -FakeTaskTiming::FakeTaskTiming(TimeTicks start, TimeTicks end) - : FakeTaskTiming() { - has_wall_time_ = true; - start_time_ = start; - end_time_ = end; - state_ = State::Finished; -} - -FakeTaskTiming::FakeTaskTiming(TimeTicks start, - TimeTicks end, - ThreadTicks thread_start, - ThreadTicks thread_end) - : FakeTaskTiming(start, end) { - has_thread_time_ = true; - start_thread_time_ = thread_start; - end_thread_time_ = thread_end; - state_ = State::Finished; -} - -} // namespace sequence_manager -} // namespace base diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/fake_task.h b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/fake_task.h deleted file mode 100644 index 134e2da7a..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/fake_task.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_SEQUENCE_MANAGER_TEST_FAKE_TASK_H_ -#define BASE_TASK_SEQUENCE_MANAGER_TEST_FAKE_TASK_H_ - -#include "base/task/sequence_manager/task_queue.h" -#include "base/task/sequence_manager/tasks.h" - -namespace base { -namespace sequence_manager { - -class FakeTask : public Task { - public: - FakeTask(); - explicit FakeTask(TaskType task_type); -}; - -class FakeTaskTiming : public TaskQueue::TaskTiming { - public: - FakeTaskTiming(); - FakeTaskTiming(TimeTicks start, TimeTicks end); - FakeTaskTiming(TimeTicks start, - TimeTicks end, - ThreadTicks thread_start, - ThreadTicks thread_end); -}; - -} // namespace sequence_manager -} // namespace base - -#endif // BASE_TASK_SEQUENCE_MANAGER_TEST_FAKE_TASK_H_ diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_domain.cc b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_domain.cc deleted file mode 100644 index b6b37332c..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_domain.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/task/sequence_manager/test/mock_time_domain.h" - -namespace base { -namespace sequence_manager { - -MockTimeDomain::MockTimeDomain(TimeTicks initial_now_ticks) - : now_ticks_(initial_now_ticks) {} - -MockTimeDomain::~MockTimeDomain() = default; - -LazyNow MockTimeDomain::CreateLazyNow() const { - return LazyNow(now_ticks_); -} - -TimeTicks MockTimeDomain::Now() const { - return now_ticks_; -} - -void MockTimeDomain::SetNowTicks(TimeTicks now_ticks) { - now_ticks_ = now_ticks; -} - -Optional MockTimeDomain::DelayTillNextTask(LazyNow* lazy_now) { - return nullopt; -} - -bool MockTimeDomain::MaybeFastForwardToNextTask(bool quit_when_idle_requested) { - return false; -} - -void MockTimeDomain::SetNextDelayedDoWork(LazyNow* lazy_now, - TimeTicks run_time) {} - -const char* MockTimeDomain::GetName() const { - return "MockTimeDomain"; -} - -} // namespace sequence_manager -} // namespace base diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_domain.h b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_domain.h deleted file mode 100644 index c9070edd7..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_domain.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_DOMAIN_H_ -#define BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_DOMAIN_H_ - -#include "base/task/sequence_manager/time_domain.h" - -namespace base { -namespace sequence_manager { - -// TimeDomain with a mock clock and not invoking SequenceManager. -// NOTE: All methods are main thread only. -class MockTimeDomain : public TimeDomain { - public: - explicit MockTimeDomain(TimeTicks initial_now_ticks); - ~MockTimeDomain() override; - - void SetNowTicks(TimeTicks now_ticks); - - // TimeDomain implementation: - LazyNow CreateLazyNow() const override; - TimeTicks Now() const override; - Optional DelayTillNextTask(LazyNow* lazy_now) override; - void SetNextDelayedDoWork(LazyNow* lazy_now, TimeTicks run_time) override; - bool MaybeFastForwardToNextTask(bool quit_when_idle_requested) override; - const char* GetName() const override; - - private: - TimeTicks now_ticks_; - - DISALLOW_COPY_AND_ASSIGN(MockTimeDomain); -}; - -} // namespace sequence_manager -} // namespace base - -#endif // BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_DOMAIN_H_ diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_message_pump.cc b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_message_pump.cc deleted file mode 100644 index 66b6f2cb6..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_message_pump.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/task/sequence_manager/test/mock_time_message_pump.h" - -#include - -#include "base/auto_reset.h" -#include "base/test/simple_test_tick_clock.h" - -namespace base { -namespace sequence_manager { - -MockTimeMessagePump::MockTimeMessagePump(SimpleTestTickClock* clock) - : clock_(clock) {} - -MockTimeMessagePump::~MockTimeMessagePump() {} - -bool MockTimeMessagePump::MaybeAdvanceTime(TimeTicks target_time) { - auto now = clock_->NowTicks(); - - if (target_time <= now) - return true; - - TimeTicks next_now; - - if (!target_time.is_max()) { - next_now = std::min(allow_advance_until_, target_time); - } else if (allow_advance_until_ == TimeTicks::Max()) { - next_now = now; - } else { - next_now = allow_advance_until_; - } - - if (now < next_now) { - clock_->SetNowTicks(next_now); - return true; - } - return false; -} - -void MockTimeMessagePump::Run(Delegate* delegate) { - AutoReset auto_reset_keep_running(&keep_running_, true); - - for (;;) { - Delegate::NextWorkInfo info = delegate->DoSomeWork(); - - if (!keep_running_ || quit_after_do_some_work_) - break; - - if (info.is_immediate()) - continue; - - bool have_immediate_work = delegate->DoIdleWork(); - - if (!keep_running_) - break; - - if (have_immediate_work) - continue; - - if (MaybeAdvanceTime(info.delayed_run_time)) - continue; - - next_wake_up_time_ = info.delayed_run_time; - - if (stop_when_message_pump_is_idle_) - return; - - NOTREACHED() << "Pump would go to sleep. Probably not what you wanted, " - "consider rewriting your test."; - } -} - -void MockTimeMessagePump::Quit() { - keep_running_ = false; -} - -void MockTimeMessagePump::ScheduleWork() {} - -void MockTimeMessagePump::ScheduleDelayedWork( - const TimeTicks& delayed_work_time) { - next_wake_up_time_ = delayed_work_time; -} - -} // namespace sequence_manager -} // namespace base diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_message_pump.h b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_message_pump.h deleted file mode 100644 index 223dfa569..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/mock_time_message_pump.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_MESSAGE_PUMP_H_ -#define BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_MESSAGE_PUMP_H_ - -#include "base/callback.h" -#include "base/message_loop/message_pump.h" -#include "base/optional.h" -#include "base/synchronization/waitable_event.h" -#include "base/time/time.h" - -namespace base { - -class SimpleTestTickClock; - -namespace sequence_manager { - -// MessagePump implementation that uses a SimpleTestTickClock to keep track of -// time and will advance it as needed to keep running tasks. -// -// This pump will actually check fail if it ever has to go to sleep as this -// would indicate that the unit test might block indefinitely. -// TODO(carlscab): In the future we could consider sleeping if there is no -// outstanding |delayed_work_time_|, because we could be woken up by concurrent -// ScheduleWork() calls. -class MockTimeMessagePump : public MessagePump { - public: - explicit MockTimeMessagePump(SimpleTestTickClock* clock); - ~MockTimeMessagePump() override; - - // MessagePump implementation - void Run(Delegate* delegate) override; - void Quit() override; - void ScheduleWork() override; - void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override; - - // Returns the time at which the pump would have to wake up to be perform - // work. - TimeTicks next_wake_up_time() const { return next_wake_up_time_; } - - // Quits after the first call to Delegate::DoSomeWork(). Useful - // for tests that want to make sure certain things happen during a DoSomeWork - // call. - void SetQuitAfterDoSomeWork(bool quit_after_do_some_work) { - quit_after_do_some_work_ = quit_after_do_some_work; - } - - // Allows this instance to advance the SimpleTestTickClock up to but not over - // |advance_until| when idle (i.e. when a regular pump would go to sleep). - // The clock will allways be advanced to |advance_until|, even if there are no - // tasks requiring it (i.e. delayed tasks to be run after - // |advance_until|) except for a value of TimeTicks::Max() which will advance - // the clock as long as there is pending delayed work. - void SetAllowTimeToAutoAdvanceUntil(TimeTicks advance_until) { - allow_advance_until_ = advance_until; - } - - // Quit when this pump's Delegate is out of work (i.e. when a regular pump - // would go to sleep) and we are not allowed to advance the clock anymore. - void SetStopWhenMessagePumpIsIdle(bool stop_when_message_pump_is_idle) { - stop_when_message_pump_is_idle_ = stop_when_message_pump_is_idle; - } - - private: - // Returns true if the clock was indeed advanced and thus we should attempt - // another iteration of the DoSomeWork-DoIdleWork-loop. - bool MaybeAdvanceTime(TimeTicks target_time); - - SimpleTestTickClock* const clock_; - // This flag is set to false when Run should return. - bool keep_running_ = true; - - bool stop_when_message_pump_is_idle_ = false; - bool quit_after_do_some_work_ = false; - - TimeTicks next_wake_up_time_{TimeTicks::Max()}; - - TimeTicks allow_advance_until_ = TimeTicks::Min(); -}; - -} // namespace sequence_manager -} // namespace base - -#endif // BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_MESSAGE_PUMP_H_ diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/sequence_manager_for_test.cc b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/sequence_manager_for_test.cc deleted file mode 100644 index 4bb4b3cee..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/sequence_manager_for_test.cc +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/task/sequence_manager/test/sequence_manager_for_test.h" - -#include "base/task/sequence_manager/thread_controller_impl.h" - -namespace base { -namespace sequence_manager { - -namespace { - -class ThreadControllerForTest : public internal::ThreadControllerImpl { - public: - ThreadControllerForTest( - internal::SequenceManagerImpl* funneled_sequence_manager, - scoped_refptr task_runner, - const TickClock* time_source) - : ThreadControllerImpl(funneled_sequence_manager, - std::move(task_runner), - time_source) {} - - void AddNestingObserver(RunLoop::NestingObserver* observer) override { - if (!funneled_sequence_manager_) - return; - ThreadControllerImpl::AddNestingObserver(observer); - } - - void RemoveNestingObserver(RunLoop::NestingObserver* observer) override { - if (!funneled_sequence_manager_) - return; - ThreadControllerImpl::RemoveNestingObserver(observer); - } - - ~ThreadControllerForTest() override = default; -}; - -} // namespace - -SequenceManagerForTest::SequenceManagerForTest( - std::unique_ptr thread_controller, - SequenceManager::Settings settings) - : SequenceManagerImpl(std::move(thread_controller), std::move(settings)) {} - -// static -std::unique_ptr SequenceManagerForTest::Create( - SequenceManagerImpl* funneled_sequence_manager, - scoped_refptr task_runner, - const TickClock* clock, - SequenceManager::Settings settings) { - std::unique_ptr manager(new SequenceManagerForTest( - std::make_unique(funneled_sequence_manager, - std::move(task_runner), clock), - std::move(settings))); - manager->BindToCurrentThread(); - return manager; -} - -// static -std::unique_ptr SequenceManagerForTest::Create( - std::unique_ptr thread_controller, - SequenceManager::Settings settings) { - std::unique_ptr manager(new SequenceManagerForTest( - std::move(thread_controller), std::move(settings))); - manager->BindToCurrentThread(); - return manager; -} - -// static -std::unique_ptr -SequenceManagerForTest::CreateOnCurrentThread( - SequenceManager::Settings settings) { - return Create(CreateThreadControllerImplForCurrentThread(settings.clock), - std::move(settings)); -} - -size_t SequenceManagerForTest::ActiveQueuesCount() const { - return main_thread_only().active_queues.size(); -} - -bool SequenceManagerForTest::HasImmediateWork() const { - return main_thread_only().selector.GetHighestPendingPriority().has_value(); -} - -size_t SequenceManagerForTest::PendingTasksCount() const { - size_t task_count = 0; - for (auto* const queue : main_thread_only().active_queues) - task_count += queue->GetNumberOfPendingTasks(); - return task_count; -} - -size_t SequenceManagerForTest::QueuesToDeleteCount() const { - return main_thread_only().queues_to_delete.size(); -} - -size_t SequenceManagerForTest::QueuesToShutdownCount() { - return main_thread_only().queues_to_gracefully_shutdown.size(); -} - -} // namespace sequence_manager -} // namespace base diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/sequence_manager_for_test.h b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/sequence_manager_for_test.h deleted file mode 100644 index bb4cf3f6e..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/sequence_manager_for_test.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_SEQUENCE_MANAGER_TEST_SEQUENCE_MANAGER_FOR_TEST_H_ -#define BASE_TASK_SEQUENCE_MANAGER_TEST_SEQUENCE_MANAGER_FOR_TEST_H_ - -#include - -#include "base/single_thread_task_runner.h" -#include "base/task/sequence_manager/sequence_manager.h" -#include "base/task/sequence_manager/sequence_manager_impl.h" -#include "base/time/tick_clock.h" - -namespace base { - -namespace sequence_manager { - -class SequenceManagerForTest : public internal::SequenceManagerImpl { - public: - ~SequenceManagerForTest() override = default; - - // Creates SequenceManagerForTest using ThreadControllerImpl constructed with - // the given arguments. ThreadControllerImpl is slightly overridden to skip - // nesting observers registration if message loop is absent. - static std::unique_ptr Create( - SequenceManagerImpl* funneled_sequence_manager, - scoped_refptr task_runner, - const TickClock* clock, - // Since most test calls are in Blink, randomised sampling is enabled - // by default in the test SequenceManager, as opposed to production code. - SequenceManager::Settings settings = - SequenceManager::Settings::Builder() - .SetRandomisedSamplingEnabled(true) - .Build()); - - // Creates SequenceManagerForTest using the provided ThreadController. - static std::unique_ptr Create( - std::unique_ptr thread_controller, - SequenceManager::Settings settings = - SequenceManager::Settings::Builder() - .SetRandomisedSamplingEnabled(true) - .Build()); - - static std::unique_ptr CreateOnCurrentThread( - SequenceManager::Settings); - - size_t ActiveQueuesCount() const; - bool HasImmediateWork() const; - size_t PendingTasksCount() const; - size_t QueuesToDeleteCount() const; - size_t QueuesToShutdownCount(); - - using internal::SequenceManagerImpl:: - CreateThreadControllerImplForCurrentThread; - using internal::SequenceManagerImpl::GetNextSequenceNumber; - using internal::SequenceManagerImpl::MoveReadyDelayedTasksToWorkQueues; - using internal::SequenceManagerImpl::ReloadEmptyWorkQueues; - - private: - explicit SequenceManagerForTest( - std::unique_ptr thread_controller, - SequenceManager::Settings settings); -}; - -} // namespace sequence_manager -} // namespace base - -#endif // BASE_TASK_SEQUENCE_MANAGER_TEST_SEQUENCE_MANAGER_FOR_TEST_H_ diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_queue.cc b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_queue.cc deleted file mode 100644 index c67585254..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_queue.cc +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/task/sequence_manager/test/test_task_queue.h" - -#include "base/task/sequence_manager/task_queue_impl.h" - -namespace base { -namespace sequence_manager { - -TestTaskQueue::TestTaskQueue(std::unique_ptr impl, - const TaskQueue::Spec& spec) - : TaskQueue(std::move(impl), spec) {} - -TestTaskQueue::~TestTaskQueue() = default; - -WeakPtr TestTaskQueue::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -} // namespace sequence_manager -} // namespace base diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_queue.h b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_queue.h deleted file mode 100644 index 6749f8c72..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_queue.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_SEQUENCE_MANAGER_TEST_TEST_TASK_QUEUE_H_ -#define BASE_TASK_SEQUENCE_MANAGER_TEST_TEST_TASK_QUEUE_H_ - -#include "base/memory/weak_ptr.h" -#include "base/task/sequence_manager/task_queue.h" - -namespace base { -namespace sequence_manager { - -class TestTaskQueue : public TaskQueue { - public: - explicit TestTaskQueue(std::unique_ptr impl, - const TaskQueue::Spec& spec); - - using TaskQueue::GetTaskQueueImpl; - - WeakPtr GetWeakPtr(); - - private: - ~TestTaskQueue() override; // Ref-counted. - - // Used to ensure that task queue is deleted in tests. - WeakPtrFactory weak_factory_{this}; -}; - -} // namespace sequence_manager -} // namespace base - -#endif // BASE_TASK_SEQUENCE_MANAGER_TEST_TEST_TASK_QUEUE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_time_observer.h b/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_time_observer.h deleted file mode 100644 index 54e4ff45f..000000000 --- a/TMessagesProj/jni/voip/webrtc/base/task/sequence_manager/test/test_task_time_observer.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_SEQUENCE_MANAGER_TEST_TEST_TASK_TIME_OBSERVER_H_ -#define BASE_TASK_SEQUENCE_MANAGER_TEST_TEST_TASK_TIME_OBSERVER_H_ - -#include "base/task/sequence_manager/task_time_observer.h" -#include "base/time/time.h" - -namespace base { -namespace sequence_manager { - -class TestTaskTimeObserver : public TaskTimeObserver { - public: - void WillProcessTask(TimeTicks start_time) override {} - void DidProcessTask(TimeTicks start_time, TimeTicks end_time) override {} -}; - -} // namespace sequence_manager -} // namespace base - -#endif // BASE_TASK_SEQUENCE_MANAGER_TEST_TEST_TASK_TIME_OBSERVER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/call/OWNERS b/TMessagesProj/jni/voip/webrtc/call/OWNERS index 1be02c2e4..f863b939b 100644 --- a/TMessagesProj/jni/voip/webrtc/call/OWNERS +++ b/TMessagesProj/jni/voip/webrtc/call/OWNERS @@ -2,3 +2,4 @@ mflodman@webrtc.org stefan@webrtc.org srte@webrtc.org terelius@webrtc.org +sprang@webrtc.org diff --git a/TMessagesProj/jni/voip/webrtc/call/adaptation/adaptation_constraint.h b/TMessagesProj/jni/voip/webrtc/call/adaptation/adaptation_constraint.h index 9ff15d6b8..9ad6414cd 100644 --- a/TMessagesProj/jni/voip/webrtc/call/adaptation/adaptation_constraint.h +++ b/TMessagesProj/jni/voip/webrtc/call/adaptation/adaptation_constraint.h @@ -14,7 +14,6 @@ #include #include "api/adaptation/resource.h" -#include "api/scoped_refptr.h" #include "call/adaptation/video_source_restrictions.h" #include "call/adaptation/video_stream_input_state.h" @@ -34,8 +33,7 @@ class AdaptationConstraint { virtual bool IsAdaptationUpAllowed( const VideoStreamInputState& input_state, const VideoSourceRestrictions& restrictions_before, - const VideoSourceRestrictions& restrictions_after, - rtc::scoped_refptr reason_resource) const = 0; + const VideoSourceRestrictions& restrictions_after) const = 0; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/call/adaptation/degradation_preference_provider.h b/TMessagesProj/jni/voip/webrtc/call/adaptation/degradation_preference_provider.h index 035fed1e5..1f75901cc 100644 --- a/TMessagesProj/jni/voip/webrtc/call/adaptation/degradation_preference_provider.h +++ b/TMessagesProj/jni/voip/webrtc/call/adaptation/degradation_preference_provider.h @@ -15,7 +15,6 @@ namespace webrtc { -// Thread-safe retrieval of degradation preferences. class DegradationPreferenceProvider { public: virtual ~DegradationPreferenceProvider(); diff --git a/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor.cc b/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor.cc index b988479d6..ac1b1db17 100644 --- a/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor.cc +++ b/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor.cc @@ -27,34 +27,34 @@ namespace webrtc { ResourceAdaptationProcessor::ResourceListenerDelegate::ResourceListenerDelegate( ResourceAdaptationProcessor* processor) - : resource_adaptation_queue_(nullptr), processor_(processor) {} + : task_queue_(nullptr), processor_(processor) {} -void ResourceAdaptationProcessor::ResourceListenerDelegate:: - SetResourceAdaptationQueue(TaskQueueBase* resource_adaptation_queue) { - RTC_DCHECK(!resource_adaptation_queue_); - RTC_DCHECK(resource_adaptation_queue); - resource_adaptation_queue_ = resource_adaptation_queue; - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); +void ResourceAdaptationProcessor::ResourceListenerDelegate::SetTaskQueue( + TaskQueueBase* task_queue) { + RTC_DCHECK(!task_queue_); + RTC_DCHECK(task_queue); + task_queue_ = task_queue; + RTC_DCHECK_RUN_ON(task_queue_); } void ResourceAdaptationProcessor::ResourceListenerDelegate:: OnProcessorDestroyed() { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); processor_ = nullptr; } void ResourceAdaptationProcessor::ResourceListenerDelegate:: OnResourceUsageStateMeasured(rtc::scoped_refptr resource, ResourceUsageState usage_state) { - if (!resource_adaptation_queue_->IsCurrent()) { - resource_adaptation_queue_->PostTask(ToQueuedTask( + if (!task_queue_->IsCurrent()) { + task_queue_->PostTask(ToQueuedTask( [this_ref = rtc::scoped_refptr(this), resource, usage_state] { this_ref->OnResourceUsageStateMeasured(resource, usage_state); })); return; } - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); if (processor_) { processor_->OnResourceUsageStateMeasured(resource, usage_state); } @@ -69,12 +69,10 @@ ResourceAdaptationProcessor::MitigationResultAndLogMessage:: : result(result), message(std::move(message)) {} ResourceAdaptationProcessor::ResourceAdaptationProcessor( - VideoStreamEncoderObserver* encoder_stats_observer, VideoStreamAdapter* stream_adapter) - : resource_adaptation_queue_(nullptr), + : task_queue_(nullptr), resource_listener_delegate_( new rtc::RefCountedObject(this)), - encoder_stats_observer_(encoder_stats_observer), resources_(), stream_adapter_(stream_adapter), last_reported_source_restrictions_(), @@ -83,7 +81,7 @@ ResourceAdaptationProcessor::ResourceAdaptationProcessor( } ResourceAdaptationProcessor::~ResourceAdaptationProcessor() { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); RTC_DCHECK(resources_.empty()) << "There are resource(s) attached to a ResourceAdaptationProcessor " << "being destroyed."; @@ -91,30 +89,29 @@ ResourceAdaptationProcessor::~ResourceAdaptationProcessor() { resource_listener_delegate_->OnProcessorDestroyed(); } -void ResourceAdaptationProcessor::SetResourceAdaptationQueue( - TaskQueueBase* resource_adaptation_queue) { - RTC_DCHECK(!resource_adaptation_queue_); - RTC_DCHECK(resource_adaptation_queue); - resource_adaptation_queue_ = resource_adaptation_queue; - resource_listener_delegate_->SetResourceAdaptationQueue( - resource_adaptation_queue); - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); - // Now that we have the adaptation queue we can attach as adaptation listener. +void ResourceAdaptationProcessor::SetTaskQueue(TaskQueueBase* task_queue) { + RTC_DCHECK(!task_queue_); + RTC_DCHECK(task_queue); + task_queue_ = task_queue; + resource_listener_delegate_->SetTaskQueue(task_queue); + RTC_DCHECK_RUN_ON(task_queue_); + // Now that we have the queue we can attach as adaptation listener. stream_adapter_->AddRestrictionsListener(this); } void ResourceAdaptationProcessor::AddResourceLimitationsListener( ResourceLimitationsListener* limitations_listener) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); RTC_DCHECK(std::find(resource_limitations_listeners_.begin(), resource_limitations_listeners_.end(), limitations_listener) == resource_limitations_listeners_.end()); resource_limitations_listeners_.push_back(limitations_listener); } + void ResourceAdaptationProcessor::RemoveResourceLimitationsListener( ResourceLimitationsListener* limitations_listener) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); auto it = std::find(resource_limitations_listeners_.begin(), resource_limitations_listeners_.end(), limitations_listener); @@ -132,6 +129,7 @@ void ResourceAdaptationProcessor::AddResource( resources_.push_back(resource); } resource->SetResourceListener(resource_listener_delegate_); + RTC_LOG(INFO) << "Registered resource \"" << resource->Name() << "\"."; } std::vector> @@ -157,12 +155,12 @@ void ResourceAdaptationProcessor::RemoveResource( void ResourceAdaptationProcessor::RemoveLimitationsImposedByResource( rtc::scoped_refptr resource) { - if (!resource_adaptation_queue_->IsCurrent()) { - resource_adaptation_queue_->PostTask(ToQueuedTask( + if (!task_queue_->IsCurrent()) { + task_queue_->PostTask(ToQueuedTask( [this, resource]() { RemoveLimitationsImposedByResource(resource); })); return; } - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); auto resource_adaptation_limits = adaptation_limits_by_resources_.find(resource); if (resource_adaptation_limits != adaptation_limits_by_resources_.end()) { @@ -200,7 +198,7 @@ void ResourceAdaptationProcessor::RemoveLimitationsImposedByResource( void ResourceAdaptationProcessor::OnResourceUsageStateMeasured( rtc::scoped_refptr resource, ResourceUsageState usage_state) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); RTC_DCHECK(resource); // |resource| could have been removed after signalling. { @@ -242,9 +240,9 @@ void ResourceAdaptationProcessor::OnResourceUsageStateMeasured( ResourceAdaptationProcessor::MitigationResultAndLogMessage ResourceAdaptationProcessor::OnResourceUnderuse( rtc::scoped_refptr reason_resource) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); // How can this stream be adapted up? - Adaptation adaptation = stream_adapter_->GetAdaptationUp(reason_resource); + Adaptation adaptation = stream_adapter_->GetAdaptationUp(); if (adaptation.status() != Adaptation::Status::kValid) { rtc::StringBuilder message; message << "Not adapting up because VideoStreamAdapter returned " @@ -298,11 +296,15 @@ ResourceAdaptationProcessor::OnResourceUnderuse( ResourceAdaptationProcessor::MitigationResultAndLogMessage ResourceAdaptationProcessor::OnResourceOveruse( rtc::scoped_refptr reason_resource) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); // How can this stream be adapted up? Adaptation adaptation = stream_adapter_->GetAdaptationDown(); - if (adaptation.min_pixel_limit_reached()) { - encoder_stats_observer_->OnMinPixelLimitReached(); + if (adaptation.status() == Adaptation::Status::kLimitReached) { + // Add resource as most limited. + VideoStreamAdapter::RestrictionsWithCounters restrictions; + std::tie(std::ignore, restrictions) = FindMostLimitedResources(); + UpdateResourceLimitations(reason_resource, restrictions.restrictions, + restrictions.counters); } if (adaptation.status() != Adaptation::Status::kValid) { rtc::StringBuilder message; @@ -373,7 +375,7 @@ void ResourceAdaptationProcessor::OnVideoSourceRestrictionsUpdated( const VideoAdaptationCounters& adaptation_counters, rtc::scoped_refptr reason, const VideoSourceRestrictions& unfiltered_restrictions) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(task_queue_); if (reason) { UpdateResourceLimitations(reason, unfiltered_restrictions, adaptation_counters); diff --git a/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor.h b/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor.h index 9e5dd6c64..c84d359fe 100644 --- a/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor.h +++ b/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor.h @@ -54,13 +54,11 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface, public VideoSourceRestrictionsListener, public ResourceListener { public: - ResourceAdaptationProcessor( - VideoStreamEncoderObserver* encoder_stats_observer, + explicit ResourceAdaptationProcessor( VideoStreamAdapter* video_stream_adapter); ~ResourceAdaptationProcessor() override; - void SetResourceAdaptationQueue( - TaskQueueBase* resource_adaptation_queue) override; + void SetTaskQueue(TaskQueueBase* task_queue) override; // ResourceAdaptationProcessorInterface implementation. void AddResourceLimitationsListener( @@ -92,7 +90,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface, public: explicit ResourceListenerDelegate(ResourceAdaptationProcessor* processor); - void SetResourceAdaptationQueue(TaskQueueBase* resource_adaptation_queue); + void SetTaskQueue(TaskQueueBase* task_queue); void OnProcessorDestroyed(); // ResourceListener implementation. @@ -100,9 +98,8 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface, ResourceUsageState usage_state) override; private: - TaskQueueBase* resource_adaptation_queue_; - ResourceAdaptationProcessor* processor_ - RTC_GUARDED_BY(resource_adaptation_queue_); + TaskQueueBase* task_queue_; + ResourceAdaptationProcessor* processor_ RTC_GUARDED_BY(task_queue_); }; enum class MitigationResult { @@ -130,7 +127,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface, void UpdateResourceLimitations(rtc::scoped_refptr reason_resource, const VideoSourceRestrictions& restrictions, const VideoAdaptationCounters& counters) - RTC_RUN_ON(resource_adaptation_queue_); + RTC_RUN_ON(task_queue_); // Searches |adaptation_limits_by_resources_| for each resource with the // highest total adaptation counts. Adaptation up may only occur if the @@ -139,35 +136,31 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface, // corresponding adaptation of that resource. std::pair>, VideoStreamAdapter::RestrictionsWithCounters> - FindMostLimitedResources() const RTC_RUN_ON(resource_adaptation_queue_); + FindMostLimitedResources() const RTC_RUN_ON(task_queue_); void RemoveLimitationsImposedByResource( rtc::scoped_refptr resource); - TaskQueueBase* resource_adaptation_queue_; + TaskQueueBase* task_queue_; rtc::scoped_refptr resource_listener_delegate_; // Input and output. - VideoStreamEncoderObserver* const encoder_stats_observer_ - RTC_GUARDED_BY(resource_adaptation_queue_); mutable Mutex resources_lock_; std::vector> resources_ RTC_GUARDED_BY(resources_lock_); std::vector resource_limitations_listeners_ - RTC_GUARDED_BY(resource_adaptation_queue_); + RTC_GUARDED_BY(task_queue_); // Purely used for statistics, does not ensure mapped resources stay alive. std::map, VideoStreamAdapter::RestrictionsWithCounters> - adaptation_limits_by_resources_ - RTC_GUARDED_BY(resource_adaptation_queue_); + adaptation_limits_by_resources_ RTC_GUARDED_BY(task_queue_); // Responsible for generating and applying possible adaptations. - VideoStreamAdapter* const stream_adapter_ - RTC_GUARDED_BY(resource_adaptation_queue_); + VideoStreamAdapter* const stream_adapter_ RTC_GUARDED_BY(task_queue_); VideoSourceRestrictions last_reported_source_restrictions_ - RTC_GUARDED_BY(resource_adaptation_queue_); + RTC_GUARDED_BY(task_queue_); // Keeps track of previous mitigation results per resource since the last // successful adaptation. Used to avoid RTC_LOG spam. std::map previous_mitigation_results_ - RTC_GUARDED_BY(resource_adaptation_queue_); + RTC_GUARDED_BY(task_queue_); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor_interface.h b/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor_interface.h index de940c859..8b1f94b73 100644 --- a/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor_interface.h +++ b/TMessagesProj/jni/voip/webrtc/call/adaptation/resource_adaptation_processor_interface.h @@ -47,8 +47,7 @@ class ResourceAdaptationProcessorInterface { public: virtual ~ResourceAdaptationProcessorInterface(); - virtual void SetResourceAdaptationQueue( - TaskQueueBase* resource_adaptation_queue) = 0; + virtual void SetTaskQueue(TaskQueueBase* task_queue) = 0; virtual void AddResourceLimitationsListener( ResourceLimitationsListener* limitations_listener) = 0; diff --git a/TMessagesProj/jni/voip/webrtc/call/adaptation/video_stream_adapter.cc b/TMessagesProj/jni/voip/webrtc/call/adaptation/video_stream_adapter.cc index 6209c0584..4fc4743a3 100644 --- a/TMessagesProj/jni/voip/webrtc/call/adaptation/video_stream_adapter.cc +++ b/TMessagesProj/jni/voip/webrtc/call/adaptation/video_stream_adapter.cc @@ -108,6 +108,12 @@ bool CanIncreaseFrameRateTo(int max_frame_rate, std::numeric_limits::max())); } +bool MinPixelLimitReached(const VideoStreamInputState& input_state) { + return input_state.frame_size_pixels().has_value() && + GetLowerResolutionThan(input_state.frame_size_pixels().value()) < + input_state.min_pixels_per_frame(); +} + } // namespace VideoSourceRestrictionsListener::~VideoSourceRestrictionsListener() = default; @@ -156,28 +162,21 @@ const char* Adaptation::StatusToString(Adaptation::Status status) { case Status::kRejectedByConstraint: return "kRejectedByConstraint"; } + RTC_CHECK_NOTREACHED(); } Adaptation::Adaptation(int validation_id, VideoSourceRestrictions restrictions, VideoAdaptationCounters counters, - VideoStreamInputState input_state, - bool min_pixel_limit_reached) + VideoStreamInputState input_state) : validation_id_(validation_id), status_(Status::kValid), - min_pixel_limit_reached_(min_pixel_limit_reached), input_state_(std::move(input_state)), restrictions_(std::move(restrictions)), counters_(std::move(counters)) {} -Adaptation::Adaptation(int validation_id, - Status invalid_status, - VideoStreamInputState input_state, - bool min_pixel_limit_reached) - : validation_id_(validation_id), - status_(invalid_status), - min_pixel_limit_reached_(min_pixel_limit_reached), - input_state_(std::move(input_state)) { +Adaptation::Adaptation(int validation_id, Status invalid_status) + : validation_id_(validation_id), status_(invalid_status) { RTC_DCHECK_NE(status_, Status::kValid); } @@ -185,10 +184,6 @@ Adaptation::Status Adaptation::status() const { return status_; } -bool Adaptation::min_pixel_limit_reached() const { - return min_pixel_limit_reached_; -} - const VideoStreamInputState& Adaptation::input_state() const { return input_state_; } @@ -202,14 +197,16 @@ const VideoAdaptationCounters& Adaptation::counters() const { } VideoStreamAdapter::VideoStreamAdapter( - VideoStreamInputStateProvider* input_state_provider) + VideoStreamInputStateProvider* input_state_provider, + VideoStreamEncoderObserver* encoder_stats_observer) : input_state_provider_(input_state_provider), - balanced_settings_(), + encoder_stats_observer_(encoder_stats_observer), adaptation_validation_id_(0), degradation_preference_(DegradationPreference::DISABLED), - awaiting_frame_size_change_(absl::nullopt), - last_video_source_restrictions_() { + awaiting_frame_size_change_(absl::nullopt) { sequence_checker_.Detach(); + RTC_DCHECK(input_state_provider_); + RTC_DCHECK(encoder_stats_observer_); } VideoStreamAdapter::~VideoStreamAdapter() { @@ -299,17 +296,11 @@ void VideoStreamAdapter::SetDegradationPreference( struct VideoStreamAdapter::RestrictionsOrStateVisitor { Adaptation operator()(const RestrictionsWithCounters& r) const { return Adaptation(adaptation_validation_id, r.restrictions, r.counters, - input_state, min_pixel_limit_reached()); + input_state); } Adaptation operator()(const Adaptation::Status& status) const { RTC_DCHECK_NE(status, Adaptation::Status::kValid); - return Adaptation(adaptation_validation_id, status, input_state, - min_pixel_limit_reached()); - } - bool min_pixel_limit_reached() const { - return input_state.frame_size_pixels().has_value() && - GetLowerResolutionThan(input_state.frame_size_pixels().value()) < - input_state.min_pixels_per_frame(); + return Adaptation(adaptation_validation_id, status); } const int adaptation_validation_id; @@ -326,17 +317,16 @@ Adaptation VideoStreamAdapter::RestrictionsOrStateToAdaptation( } Adaptation VideoStreamAdapter::GetAdaptationUp( - const VideoStreamInputState& input_state, - rtc::scoped_refptr resource) const { + const VideoStreamInputState& input_state) const { RestrictionsOrState step = GetAdaptationUpStep(input_state); // If an adaptation proposed, check with the constraints that it is ok. if (absl::holds_alternative(step)) { RestrictionsWithCounters restrictions = absl::get(step); for (const auto* constraint : adaptation_constraints_) { - if (!constraint->IsAdaptationUpAllowed( - input_state, current_restrictions_.restrictions, - restrictions.restrictions, resource)) { + if (!constraint->IsAdaptationUpAllowed(input_state, + current_restrictions_.restrictions, + restrictions.restrictions)) { RTC_LOG(INFO) << "Not adapting up because constraint \"" << constraint->Name() << "\" disallowed it"; step = Adaptation::Status::kRejectedByConstraint; @@ -346,13 +336,11 @@ Adaptation VideoStreamAdapter::GetAdaptationUp( return RestrictionsOrStateToAdaptation(step, input_state); } -Adaptation VideoStreamAdapter::GetAdaptationUp( - rtc::scoped_refptr resource) { +Adaptation VideoStreamAdapter::GetAdaptationUp() { RTC_DCHECK_RUN_ON(&sequence_checker_); - RTC_DCHECK(resource); VideoStreamInputState input_state = input_state_provider_->InputState(); ++adaptation_validation_id_; - Adaptation adaptation = GetAdaptationUp(input_state, resource); + Adaptation adaptation = GetAdaptationUp(input_state); return adaptation; } @@ -394,6 +382,7 @@ VideoStreamAdapter::RestrictionsOrState VideoStreamAdapter::GetAdaptationUpStep( case DegradationPreference::DISABLED: return Adaptation::Status::kAdaptationDisabled; } + RTC_CHECK_NOTREACHED(); } Adaptation VideoStreamAdapter::GetAdaptationDown() { @@ -402,7 +391,9 @@ Adaptation VideoStreamAdapter::GetAdaptationDown() { ++adaptation_validation_id_; RestrictionsOrState restrictions_or_state = GetAdaptationDownStep(input_state, current_restrictions_); - + if (MinPixelLimitReached(input_state)) { + encoder_stats_observer_->OnMinPixelLimitReached(); + } // Check for min_fps if (degradation_preference_ == DegradationPreference::BALANCED && absl::holds_alternative( @@ -471,6 +462,7 @@ VideoStreamAdapter::GetAdaptationDownStep( case DegradationPreference::DISABLED: return Adaptation::Status::kAdaptationDisabled; } + RTC_CHECK_NOTREACHED(); } VideoStreamAdapter::RestrictionsOrState VideoStreamAdapter::DecreaseResolution( @@ -608,9 +600,8 @@ Adaptation VideoStreamAdapter::GetAdaptDownResolution() { return RestrictionsOrStateToAdaptation( GetAdaptDownResolutionStepForBalanced(input_state), input_state); } - default: - RTC_NOTREACHED(); } + RTC_CHECK_NOTREACHED(); } VideoStreamAdapter::RestrictionsOrState @@ -667,7 +658,7 @@ Adaptation VideoStreamAdapter::GetAdaptationTo( RTC_DCHECK_RUN_ON(&sequence_checker_); VideoStreamInputState input_state = input_state_provider_->InputState(); return Adaptation(adaptation_validation_id_, restrictions, counters, - input_state, false); + input_state); } void VideoStreamAdapter::BroadcastVideoRestrictionsUpdate( diff --git a/TMessagesProj/jni/voip/webrtc/call/adaptation/video_stream_adapter.h b/TMessagesProj/jni/voip/webrtc/call/adaptation/video_stream_adapter.h index 1f6f252b3..3c3595759 100644 --- a/TMessagesProj/jni/voip/webrtc/call/adaptation/video_stream_adapter.h +++ b/TMessagesProj/jni/voip/webrtc/call/adaptation/video_stream_adapter.h @@ -20,6 +20,7 @@ #include "api/adaptation/resource.h" #include "api/rtp_parameters.h" #include "api/video/video_adaptation_counters.h" +#include "api/video/video_stream_encoder_observer.h" #include "call/adaptation/adaptation_constraint.h" #include "call/adaptation/degradation_preference_provider.h" #include "call/adaptation/video_source_restrictions.h" @@ -87,8 +88,6 @@ class Adaptation final { const VideoStreamInputState& input_state() const; const VideoSourceRestrictions& restrictions() const; const VideoAdaptationCounters& counters() const; - // Used for stats reporting. - bool min_pixel_limit_reached() const; private: friend class VideoStreamAdapter; @@ -97,13 +96,9 @@ class Adaptation final { Adaptation(int validation_id, VideoSourceRestrictions restrictions, VideoAdaptationCounters counters, - VideoStreamInputState input_state, - bool min_pixel_limit_reached); + VideoStreamInputState input_state); // Constructor when adaptation is not valid. Status MUST NOT be kValid. - Adaptation(int validation_id, - Status invalid_status, - VideoStreamInputState input_state, - bool min_pixel_limit_reached); + Adaptation(int validation_id, Status invalid_status); // An Adaptation can become invalidated if the state of VideoStreamAdapter is // modified before the Adaptation is applied. To guard against this, this ID @@ -111,7 +106,6 @@ class Adaptation final { // TODO(https://crbug.com/webrtc/11700): Remove the validation_id_. const int validation_id_; const Status status_; - const bool min_pixel_limit_reached_; // Input state when adaptation was made. const VideoStreamInputState input_state_; const VideoSourceRestrictions restrictions_; @@ -126,8 +120,8 @@ class Adaptation final { // 3. Modify the stream's restrictions in one of the valid ways. class VideoStreamAdapter { public: - explicit VideoStreamAdapter( - VideoStreamInputStateProvider* input_state_provider); + VideoStreamAdapter(VideoStreamInputStateProvider* input_state_provider, + VideoStreamEncoderObserver* encoder_stats_observer); ~VideoStreamAdapter(); VideoSourceRestrictions source_restrictions() const; @@ -148,9 +142,7 @@ class VideoStreamAdapter { // Returns an adaptation that we are guaranteed to be able to apply, or a // status code indicating the reason why we cannot adapt. - // TODO(https://crbug.com/webrtc/11771) |resource| is needed by the - // AdaptationConstraint resources. Remove this parameter when it's removed. - Adaptation GetAdaptationUp(rtc::scoped_refptr resource); + Adaptation GetAdaptationUp(); Adaptation GetAdaptationDown(); Adaptation GetAdaptationTo(const VideoAdaptationCounters& counters, const VideoSourceRestrictions& restrictions); @@ -194,10 +186,7 @@ class VideoStreamAdapter { const RestrictionsWithCounters& restrictions) const RTC_RUN_ON(&sequence_checker_); - // TODO(https://crbug.com/webrtc/11771) |resource| is needed by the - // AdaptationConstraint resources. Remove this parameter when it's removed. - Adaptation GetAdaptationUp(const VideoStreamInputState& input_state, - rtc::scoped_refptr resource) const + Adaptation GetAdaptationUp(const VideoStreamInputState& input_state) const RTC_RUN_ON(&sequence_checker_); Adaptation GetAdaptationDown(const VideoStreamInputState& input_state) const RTC_RUN_ON(&sequence_checker_); @@ -229,6 +218,8 @@ class VideoStreamAdapter { // Gets the input state which is the basis of all adaptations. // Thread safe. VideoStreamInputStateProvider* input_state_provider_; + // Used to signal when min pixel limit has been reached. + VideoStreamEncoderObserver* const encoder_stats_observer_; // Decides the next adaptation target in DegradationPreference::BALANCED. const BalancedDegradationSettings balanced_settings_; // To guard against applying adaptations that have become invalidated, an diff --git a/TMessagesProj/jni/voip/webrtc/call/audio_receive_stream.h b/TMessagesProj/jni/voip/webrtc/call/audio_receive_stream.h index d4012bf7e..eee62e9a8 100644 --- a/TMessagesProj/jni/voip/webrtc/call/audio_receive_stream.h +++ b/TMessagesProj/jni/voip/webrtc/call/audio_receive_stream.h @@ -167,7 +167,8 @@ class AudioReceiveStream { // When a stream is stopped, it can't receive, process or deliver packets. virtual void Stop() = 0; - virtual Stats GetStats() const = 0; + virtual Stats GetStats(bool get_and_clear_legacy_stats) const = 0; + Stats GetStats() { return GetStats(/*get_and_clear_legacy_stats=*/true); } // Sets an audio sink that receives unmixed audio from the receive stream. // Ownership of the sink is managed by the caller. diff --git a/TMessagesProj/jni/voip/webrtc/call/audio_send_stream.cc b/TMessagesProj/jni/voip/webrtc/call/audio_send_stream.cc index 1f5bf0518..5acdc9618 100644 --- a/TMessagesProj/jni/voip/webrtc/call/audio_send_stream.cc +++ b/TMessagesProj/jni/voip/webrtc/call/audio_send_stream.cc @@ -34,6 +34,9 @@ std::string AudioSendStream::Config::ToString() const { ss << ", send_transport: " << (send_transport ? "(Transport)" : "null"); ss << ", min_bitrate_bps: " << min_bitrate_bps; ss << ", max_bitrate_bps: " << max_bitrate_bps; + ss << ", has audio_network_adaptor_config: " + << (audio_network_adaptor_config ? "true" : "false"); + ss << ", has_dscp: " << (has_dscp ? "true" : "false"); ss << ", send_codec_spec: " << (send_codec_spec ? send_codec_spec->ToString() : ""); ss << '}'; diff --git a/TMessagesProj/jni/voip/webrtc/call/audio_state.h b/TMessagesProj/jni/voip/webrtc/call/audio_state.h index 89267c5ab..79fb5cf98 100644 --- a/TMessagesProj/jni/voip/webrtc/call/audio_state.h +++ b/TMessagesProj/jni/voip/webrtc/call/audio_state.h @@ -12,6 +12,7 @@ #include "api/audio/audio_mixer.h" #include "api/scoped_refptr.h" +#include "modules/async_audio_processing/async_audio_processing.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" #include "rtc_base/ref_count.h" @@ -37,6 +38,9 @@ class AudioState : public rtc::RefCountInterface { // TODO(solenberg): Temporary: audio device module. rtc::scoped_refptr audio_device_module; + + rtc::scoped_refptr + async_audio_processing_factory; }; virtual AudioProcessing* audio_processing() = 0; diff --git a/TMessagesProj/jni/voip/webrtc/call/call.cc b/TMessagesProj/jni/voip/webrtc/call/call.cc index ace83bee9..e814cff5b 100644 --- a/TMessagesProj/jni/voip/webrtc/call/call.cc +++ b/TMessagesProj/jni/voip/webrtc/call/call.cc @@ -260,6 +260,8 @@ class Call final : public webrtc::Call, Stats GetStats() const override; + const WebRtcKeyValueConfig& trials() const override; + // Implements PacketReceiver. DeliveryStatus DeliverPacket(MediaType media_type, rtc::CopyOnWriteBuffer packet, @@ -306,7 +308,9 @@ class Call final : public webrtc::Call, void UpdateHistograms(); void UpdateAggregateNetworkState(); - void RegisterRateObserver(); + // Ensure that necessary process threads are started, and any required + // callbacks have been registered. + void EnsureStarted() RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); rtc::TaskQueue* send_transport_queue() const { return transport_send_ptr_->GetWorkerQueue(); @@ -433,8 +437,7 @@ class Call final : public webrtc::Call, // last ensures that it is destroyed first and any running tasks are finished. std::unique_ptr transport_send_; - bool is_target_rate_observer_registered_ RTC_GUARDED_BY(worker_thread_) = - false; + bool is_started_ RTC_GUARDED_BY(worker_thread_) = false; RTC_DISALLOW_COPY_AND_ASSIGN(Call); }; @@ -655,19 +658,18 @@ Call::~Call() { UpdateHistograms(); } -void Call::RegisterRateObserver() { - RTC_DCHECK_RUN_ON(worker_thread_); - - if (is_target_rate_observer_registered_) +void Call::EnsureStarted() { + if (is_started_) { return; - - is_target_rate_observer_registered_ = true; + } + is_started_ = true; // This call seems to kick off a number of things, so probably better left // off being kicked off on request rather than in the ctor. transport_send_ptr_->RegisterTargetTransferRateObserver(this); module_process_thread_->EnsureStarted(); + transport_send_ptr_->EnsureStarted(); } void Call::SetClientBitratePreferences(const BitrateSettings& preferences) { @@ -762,7 +764,7 @@ webrtc::AudioSendStream* Call::CreateAudioSendStream( TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream"); RTC_DCHECK_RUN_ON(worker_thread_); - RegisterRateObserver(); + EnsureStarted(); // Stream config is logged in AudioSendStream::ConfigureStream, as it may // change during the stream's lifetime. @@ -822,7 +824,7 @@ webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream( const webrtc::AudioReceiveStream::Config& config) { TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream"); RTC_DCHECK_RUN_ON(worker_thread_); - RegisterRateObserver(); + EnsureStarted(); event_log_->Log(std::make_unique( CreateRtcLogStreamConfig(config))); AudioReceiveStream* receive_stream = new AudioReceiveStream( @@ -877,7 +879,7 @@ webrtc::VideoSendStream* Call::CreateVideoSendStream( TRACE_EVENT0("webrtc", "Call::CreateVideoSendStream"); RTC_DCHECK_RUN_ON(worker_thread_); - RegisterRateObserver(); + EnsureStarted(); video_send_delay_stats_->AddSsrcs(config); for (size_t ssrc_index = 0; ssrc_index < config.rtp.ssrcs.size(); @@ -976,7 +978,7 @@ webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream( receive_side_cc_.SetSendPeriodicFeedback( SendPeriodicFeedback(configuration.rtp.extensions)); - RegisterRateObserver(); + EnsureStarted(); TaskQueueBase* current = GetCurrentTaskQueueOrThread(); RTC_CHECK(current); @@ -1112,6 +1114,10 @@ Call::Stats Call::GetStats() const { return stats; } +const WebRtcKeyValueConfig& Call::trials() const { + return *config_.trials; +} + void Call::SignalChannelNetworkState(MediaType media, NetworkState state) { RTC_DCHECK_RUN_ON(worker_thread_); switch (media) { diff --git a/TMessagesProj/jni/voip/webrtc/call/call.h b/TMessagesProj/jni/voip/webrtc/call/call.h index 75272248c..a2b3b8959 100644 --- a/TMessagesProj/jni/voip/webrtc/call/call.h +++ b/TMessagesProj/jni/voip/webrtc/call/call.h @@ -156,6 +156,8 @@ class Call { virtual void SetClientBitratePreferences( const BitrateSettings& preferences) = 0; + virtual const WebRtcKeyValueConfig& trials() const = 0; + virtual ~Call() {} }; diff --git a/TMessagesProj/jni/voip/webrtc/call/call_perf_tests.cc b/TMessagesProj/jni/voip/webrtc/call/call_perf_tests.cc index 9214ae5d1..aa8894e9a 100644 --- a/TMessagesProj/jni/voip/webrtc/call/call_perf_tests.cc +++ b/TMessagesProj/jni/voip/webrtc/call/call_perf_tests.cc @@ -182,7 +182,6 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, std::unique_ptr audio_send_transport; std::unique_ptr video_send_transport; std::unique_ptr receive_transport; - test::NullTransport rtcp_send_transport; AudioSendStream* audio_send_stream; AudioReceiveStream* audio_receive_stream; @@ -271,7 +270,7 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, AudioReceiveStream::Config audio_recv_config; audio_recv_config.rtp.remote_ssrc = kAudioSendSsrc; audio_recv_config.rtp.local_ssrc = kAudioRecvSsrc; - audio_recv_config.rtcp_send_transport = &rtcp_send_transport; + audio_recv_config.rtcp_send_transport = receive_transport.get(); audio_recv_config.sync_group = kSyncGroup; audio_recv_config.decoder_factory = audio_decoder_factory_; audio_recv_config.decoder_map = { @@ -337,27 +336,29 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, ToQueuedTask([to_delete = observer.release()]() { delete to_delete; })); } -TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithoutClockDrift) { +TEST_F(CallPerfTest, Synchronization_PlaysOutAudioAndVideoWithoutClockDrift) { TestAudioVideoSync(FecMode::kOff, CreateOrder::kAudioFirst, DriftingClock::kNoDrift, DriftingClock::kNoDrift, DriftingClock::kNoDrift, "_video_no_drift"); } -TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithVideoNtpDrift) { +TEST_F(CallPerfTest, Synchronization_PlaysOutAudioAndVideoWithVideoNtpDrift) { TestAudioVideoSync(FecMode::kOff, CreateOrder::kAudioFirst, DriftingClock::PercentsFaster(10.0f), DriftingClock::kNoDrift, DriftingClock::kNoDrift, "_video_ntp_drift"); } -TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithAudioFasterThanVideoDrift) { +TEST_F(CallPerfTest, + Synchronization_PlaysOutAudioAndVideoWithAudioFasterThanVideoDrift) { TestAudioVideoSync(FecMode::kOff, CreateOrder::kAudioFirst, DriftingClock::kNoDrift, DriftingClock::PercentsSlower(30.0f), DriftingClock::PercentsFaster(30.0f), "_audio_faster"); } -TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithVideoFasterThanAudioDrift) { +TEST_F(CallPerfTest, + Synchronization_PlaysOutAudioAndVideoWithVideoFasterThanAudioDrift) { TestAudioVideoSync(FecMode::kOn, CreateOrder::kVideoFirst, DriftingClock::kNoDrift, DriftingClock::PercentsFaster(30.0f), @@ -509,7 +510,7 @@ void CallPerfTest::TestCaptureNtpTime( // Flaky tests, disabled on Mac and Windows due to webrtc:8291. #if !(defined(WEBRTC_MAC) || defined(WEBRTC_WIN)) -TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkDelay) { +TEST_F(CallPerfTest, Real_Estimated_CaptureNtpTimeWithNetworkDelay) { BuiltInNetworkBehaviorConfig net_config; net_config.queue_delay_ms = 100; // TODO(wu): lower the threshold as the calculation/estimatation becomes more @@ -520,7 +521,7 @@ TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkDelay) { TestCaptureNtpTime(net_config, kThresholdMs, kStartTimeMs, kRunTimeMs); } -TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkJitter) { +TEST_F(CallPerfTest, Real_Estimated_CaptureNtpTimeWithNetworkJitter) { BuiltInNetworkBehaviorConfig net_config; net_config.queue_delay_ms = 100; net_config.delay_standard_deviation_ms = 10; @@ -710,11 +711,11 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) { RunBaseTest(&test); } -TEST_F(CallPerfTest, PadsToMinTransmitBitrate) { +TEST_F(CallPerfTest, Bitrate_Kbps_PadsToMinTransmitBitrate) { TestMinTransmitBitrate(true); } -TEST_F(CallPerfTest, NoPadWithoutMinTransmitBitrate) { +TEST_F(CallPerfTest, Bitrate_Kbps_NoPadWithoutMinTransmitBitrate) { TestMinTransmitBitrate(false); } @@ -730,6 +731,11 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { static const uint32_t kInitialBitrateKbps = 400; static const uint32_t kReconfigureThresholdKbps = 600; + // We get lower bitrate than expected by this test if the following field + // trial is enabled. + test::ScopedFieldTrials field_trials( + "WebRTC-SendSideBwe-WithOverhead/Disabled/"); + class VideoStreamFactory : public VideoEncoderConfig::VideoStreamFactoryInterface { public: @@ -1003,11 +1009,11 @@ void CallPerfTest::TestMinAudioVideoBitrate(int test_bitrate_from, // TODO(bugs.webrtc.org/8878) #if defined(WEBRTC_MAC) -#define MAYBE_MinVideoAndAudioBitrate DISABLED_MinVideoAndAudioBitrate +#define MAYBE_Min_Bitrate_VideoAndAudio DISABLED_Min_Bitrate_VideoAndAudio #else -#define MAYBE_MinVideoAndAudioBitrate MinVideoAndAudioBitrate +#define MAYBE_Min_Bitrate_VideoAndAudio Min_Bitrate_VideoAndAudio #endif -TEST_F(CallPerfTest, MAYBE_MinVideoAndAudioBitrate) { +TEST_F(CallPerfTest, MAYBE_Min_Bitrate_VideoAndAudio) { TestMinAudioVideoBitrate(110, 40, -10, 10000, 70000, 200000); } diff --git a/TMessagesProj/jni/voip/webrtc/call/degraded_call.cc b/TMessagesProj/jni/voip/webrtc/call/degraded_call.cc index 007e0af36..0cd43018a 100644 --- a/TMessagesProj/jni/voip/webrtc/call/degraded_call.cc +++ b/TMessagesProj/jni/voip/webrtc/call/degraded_call.cc @@ -266,6 +266,10 @@ Call::Stats DegradedCall::GetStats() const { return call_->GetStats(); } +const WebRtcKeyValueConfig& DegradedCall::trials() const { + return call_->trials(); +} + void DegradedCall::SignalChannelNetworkState(MediaType media, NetworkState state) { call_->SignalChannelNetworkState(media, state); diff --git a/TMessagesProj/jni/voip/webrtc/call/degraded_call.h b/TMessagesProj/jni/voip/webrtc/call/degraded_call.h index ac072b715..d81c65c57 100644 --- a/TMessagesProj/jni/voip/webrtc/call/degraded_call.h +++ b/TMessagesProj/jni/voip/webrtc/call/degraded_call.h @@ -85,6 +85,8 @@ class DegradedCall : public Call, private PacketReceiver { Stats GetStats() const override; + const WebRtcKeyValueConfig& trials() const override; + void SignalChannelNetworkState(MediaType media, NetworkState state) override; void OnAudioTransportOverheadChanged( int transport_overhead_per_packet) override; diff --git a/TMessagesProj/jni/voip/webrtc/call/rtp_payload_params.cc b/TMessagesProj/jni/voip/webrtc/call/rtp_payload_params.cc index a9ab77b62..1f0815547 100644 --- a/TMessagesProj/jni/voip/webrtc/call/rtp_payload_params.cc +++ b/TMessagesProj/jni/voip/webrtc/call/rtp_payload_params.cc @@ -36,6 +36,7 @@ void PopulateRtpWithCodecSpecifics(const CodecSpecificInfo& info, absl::optional spatial_index, RTPVideoHeader* rtp) { rtp->codec = info.codecType; + rtp->is_last_frame_in_picture = info.end_of_picture; switch (info.codecType) { case kVideoCodecVP8: { auto& vp8_header = rtp->video_type_header.emplace(); @@ -85,7 +86,7 @@ void PopulateRtpWithCodecSpecifics(const CodecSpecificInfo& info, for (int i = 0; i < info.codecSpecific.VP9.num_ref_pics; ++i) { vp9_header.pid_diff[i] = info.codecSpecific.VP9.p_diff[i]; } - vp9_header.end_of_picture = info.codecSpecific.VP9.end_of_picture; + vp9_header.end_of_picture = info.end_of_picture; return; } case kVideoCodecH264: { diff --git a/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send.cc b/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send.cc index 9baf164a6..f5adae68a 100644 --- a/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send.cc +++ b/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send.cc @@ -64,6 +64,11 @@ bool IsEnabled(const WebRtcKeyValueConfig* trials, absl::string_view key) { return absl::StartsWith(trials->Lookup(key), "Enabled"); } +bool IsDisabled(const WebRtcKeyValueConfig* trials, absl::string_view key) { + RTC_DCHECK(trials != nullptr); + return absl::StartsWith(trials->Lookup(key), "Disabled"); +} + bool IsRelayed(const rtc::NetworkRoute& route) { return route.local.uses_turn() || route.remote.uses_turn(); } @@ -82,6 +87,7 @@ RtpTransportControllerSend::RtpTransportControllerSend( : clock_(clock), event_log_(event_log), bitrate_configurator_(bitrate_config), + process_thread_started_(false), process_thread_(std::move(process_thread)), use_task_queue_pacer_(IsEnabled(trials, "WebRTC-TaskQueuePacer")), process_thread_pacer_(use_task_queue_pacer_ @@ -110,7 +116,7 @@ RtpTransportControllerSend::RtpTransportControllerSend( reset_feedback_on_route_change_( !IsEnabled(trials, "WebRTC-Bwe-NoFeedbackReset")), send_side_bwe_with_overhead_( - IsEnabled(trials, "WebRTC-SendSideBwe-WithOverhead")), + !IsDisabled(trials, "WebRTC-SendSideBwe-WithOverhead")), add_pacing_to_cwin_( IsEnabled(trials, "WebRTC-AddPacingToCongestionWindowPushback")), relay_bandwidth_cap_("relay_cap", DataRate::PlusInfinity()), @@ -130,15 +136,13 @@ RtpTransportControllerSend::RtpTransportControllerSend( pacer()->SetPacingRates( DataRate::BitsPerSec(bitrate_config.start_bitrate_bps), DataRate::Zero()); - if (!use_task_queue_pacer_) { - process_thread_->Start(); + if (absl::StartsWith(trials->Lookup("WebRTC-LazyPacerStart"), "Disabled")) { + EnsureStarted(); } } RtpTransportControllerSend::~RtpTransportControllerSend() { - if (!use_task_queue_pacer_) { - process_thread_->Stop(); - } + process_thread_->Stop(); } RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender( @@ -491,6 +495,13 @@ void RtpTransportControllerSend::IncludeOverheadInPacedSender() { pacer()->SetIncludeOverhead(); } +void RtpTransportControllerSend::EnsureStarted() { + if (!use_task_queue_pacer_ && !process_thread_started_) { + process_thread_started_ = true; + process_thread_->Start(); + } +} + void RtpTransportControllerSend::OnReceivedEstimatedBitrate(uint32_t bitrate) { RemoteBitrateReport msg; msg.receive_time = Timestamp::Millis(clock_->TimeInMilliseconds()); diff --git a/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send.h b/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send.h index e7310334c..7025b0331 100644 --- a/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send.h +++ b/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send.h @@ -110,6 +110,7 @@ class RtpTransportControllerSend final void AccountForAudioPacketsInPacedSender(bool account_for_audio) override; void IncludeOverheadInPacedSender() override; + void EnsureStarted() override; // Implements RtcpBandwidthObserver interface void OnReceivedEstimatedBitrate(uint32_t bitrate) override; @@ -151,6 +152,7 @@ class RtpTransportControllerSend final std::vector> video_rtp_senders_; RtpBitrateConfigurator bitrate_configurator_; std::map network_routes_; + bool process_thread_started_; const std::unique_ptr process_thread_; const bool use_task_queue_pacer_; std::unique_ptr process_thread_pacer_; diff --git a/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send_interface.h b/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send_interface.h index f07342496..602908e2a 100644 --- a/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send_interface.h +++ b/TMessagesProj/jni/voip/webrtc/call/rtp_transport_controller_send_interface.h @@ -26,6 +26,7 @@ #include "api/transport/bitrate_settings.h" #include "api/units/timestamp.h" #include "call/rtp_config.h" +#include "common_video/frame_counts.h" #include "modules/rtp_rtcp/include/report_block_data.h" #include "modules/rtp_rtcp/include/rtcp_statistics.h" #include "modules/rtp_rtcp/include/rtp_packet_sender.h" @@ -153,6 +154,8 @@ class RtpTransportControllerSendInterface { virtual void AccountForAudioPacketsInPacedSender(bool account_for_audio) = 0; virtual void IncludeOverheadInPacedSender() = 0; + + virtual void EnsureStarted() = 0; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender.cc b/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender.cc index b2ae0352d..9dad424c8 100644 --- a/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender.cc +++ b/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender.cc @@ -197,7 +197,6 @@ std::vector CreateRtpStreamSenders( FrameEncryptorInterface* frame_encryptor, const CryptoOptions& crypto_options, rtc::scoped_refptr frame_transformer, - bool use_deferred_fec, const WebRtcKeyValueConfig& trials) { RTC_DCHECK_GT(rtp_config.ssrcs.size(), 0); @@ -245,9 +244,6 @@ std::vector CreateRtpStreamSenders( std::unique_ptr fec_generator = MaybeCreateFecGenerator(clock, rtp_config, suspended_ssrcs, i, trials); configuration.fec_generator = fec_generator.get(); - if (!use_deferred_fec) { - video_config.fec_generator = fec_generator.get(); - } configuration.rtx_send_ssrc = rtp_config.GetRtxSsrcAssociatedWithMediaSsrc(rtp_config.ssrcs[i]); @@ -331,19 +327,10 @@ RtpVideoSender::RtpVideoSender( FrameEncryptorInterface* frame_encryptor, const CryptoOptions& crypto_options, rtc::scoped_refptr frame_transformer) - : send_side_bwe_with_overhead_(absl::StartsWith( + : send_side_bwe_with_overhead_(!absl::StartsWith( field_trials_.Lookup("WebRTC-SendSideBwe-WithOverhead"), - "Enabled")), - account_for_packetization_overhead_(!absl::StartsWith( - field_trials_.Lookup("WebRTC-SubtractPacketizationOverhead"), - "Disabled")), - use_early_loss_detection_(!absl::StartsWith( - field_trials_.Lookup("WebRTC-UseEarlyLossDetection"), "Disabled")), has_packet_feedback_(TransportSeqNumExtensionConfigured(rtp_config)), - use_deferred_fec_( - absl::StartsWith(field_trials_.Lookup("WebRTC-DeferredFecGeneration"), - "Enabled")), active_(false), module_process_thread_(nullptr), suspended_ssrcs_(std::move(suspended_ssrcs)), @@ -362,7 +349,6 @@ RtpVideoSender::RtpVideoSender( frame_encryptor, crypto_options, std::move(frame_transformer), - use_deferred_fec_, field_trials_)), rtp_config_(rtp_config), codec_type_(GetVideoCodecType(rtp_config)), @@ -606,6 +592,18 @@ void RtpVideoSender::OnBitrateAllocationUpdated( } } } +void RtpVideoSender::OnVideoLayersAllocationUpdated( + const VideoLayersAllocation& allocation) { + MutexLock lock(&mutex_); + if (IsActiveLocked()) { + for (size_t i = 0; i < rtp_streams_.size(); ++i) { + VideoLayersAllocation stream_allocation = allocation; + stream_allocation.rtp_stream_index = i; + rtp_streams_[i].sender_video->SetVideoLayersAllocation( + std::move(stream_allocation)); + } + } +} bool RtpVideoSender::NackEnabled() const { const bool nack_enabled = rtp_config_.nack.rtp_history_ms > 0; @@ -789,16 +787,13 @@ void RtpVideoSender::OnBitrateUpdated(BitrateAllocationUpdate update, // since |fec_allowed_| may be toggled back on at any moment. } - uint32_t packetization_rate_bps = 0; - if (account_for_packetization_overhead_) { // Subtract packetization overhead from the encoder target. If target rate // is really low, cap the overhead at 50%. This also avoids the case where // |encoder_target_rate_bps_| is 0 due to encoder pause event while the // packetization rate is positive since packets are still flowing. - packetization_rate_bps = - std::min(GetPacketizationOverheadRate(), encoder_target_rate_bps_ / 2); - encoder_target_rate_bps_ -= packetization_rate_bps; - } + uint32_t packetization_rate_bps = + std::min(GetPacketizationOverheadRate(), encoder_target_rate_bps_ / 2); + encoder_target_rate_bps_ -= packetization_rate_bps; loss_mask_vector_.clear(); @@ -853,7 +848,6 @@ int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params, *sent_nack_rate_bps = 0; *sent_fec_rate_bps = 0; for (const RtpStreamSender& stream : rtp_streams_) { - if (use_deferred_fec_) { stream.rtp_rtcp->SetFecProtectionParams(*delta_params, *key_params); auto send_bitrate = stream.rtp_rtcp->GetSendRates(); @@ -862,17 +856,6 @@ int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params, send_bitrate[RtpPacketMediaType::kForwardErrorCorrection].bps(); *sent_nack_rate_bps += send_bitrate[RtpPacketMediaType::kRetransmission].bps(); - } else { - if (stream.fec_generator) { - stream.fec_generator->SetProtectionParameters(*delta_params, - *key_params); - *sent_fec_rate_bps += stream.fec_generator->CurrentFecRate().bps(); - } - *sent_video_rate_bps += stream.sender_video->VideoBitrateSent(); - *sent_nack_rate_bps += - stream.rtp_rtcp->GetSendRates()[RtpPacketMediaType::kRetransmission] - .bps(); - } } return 0; } @@ -899,7 +882,6 @@ void RtpVideoSender::OnPacketFeedbackVector( } } - if (use_early_loss_detection_) { // Map from SSRC to vector of RTP sequence numbers that are indicated as // lost by feedback, without being trailed by any received packets. std::map> early_loss_detected_per_ssrc; @@ -925,7 +907,6 @@ void RtpVideoSender::OnPacketFeedbackVector( rtp_sender->ReSendPacket(sequence_number); } } - } for (const auto& kv : acked_packets_per_ssrc) { const uint32_t ssrc = kv.first; diff --git a/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender.h b/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender.h index 9ec10c460..49fd3cc0d 100644 --- a/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender.h +++ b/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender.h @@ -138,7 +138,8 @@ class RtpVideoSender : public RtpVideoSenderInterface, void OnBitrateAllocationUpdated(const VideoBitrateAllocation& bitrate) RTC_LOCKS_EXCLUDED(mutex_) override; - + void OnVideoLayersAllocationUpdated( + const VideoLayersAllocation& layers) override; void OnTransportOverheadChanged(size_t transport_overhead_bytes_per_packet) RTC_LOCKS_EXCLUDED(mutex_) override; void OnBitrateUpdated(BitrateAllocationUpdate update, int framerate) @@ -171,10 +172,7 @@ class RtpVideoSender : public RtpVideoSenderInterface, const FieldTrialBasedConfig field_trials_; const bool send_side_bwe_with_overhead_; - const bool account_for_packetization_overhead_; - const bool use_early_loss_detection_; const bool has_packet_feedback_; - const bool use_deferred_fec_; // TODO(holmer): Remove mutex_ once RtpVideoSender runs on the // transport task queue. diff --git a/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender_interface.h b/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender_interface.h index bb72eb599..632c9e835 100644 --- a/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender_interface.h +++ b/TMessagesProj/jni/voip/webrtc/call/rtp_video_sender_interface.h @@ -18,6 +18,7 @@ #include "api/array_view.h" #include "api/call/bitrate_allocation.h" #include "api/fec_controller_override.h" +#include "api/video/video_layers_allocation.h" #include "call/rtp_config.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" @@ -50,6 +51,8 @@ class RtpVideoSenderInterface : public EncodedImageCallback, virtual void OnBitrateAllocationUpdated( const VideoBitrateAllocation& bitrate) = 0; + virtual void OnVideoLayersAllocationUpdated( + const VideoLayersAllocation& allocation) = 0; virtual void OnBitrateUpdated(BitrateAllocationUpdate update, int framerate) = 0; virtual void OnTransportOverheadChanged( diff --git a/TMessagesProj/jni/voip/webrtc/call/simulated_network.cc b/TMessagesProj/jni/voip/webrtc/call/simulated_network.cc index 2ed9140fa..f8a5bd893 100644 --- a/TMessagesProj/jni/voip/webrtc/call/simulated_network.cc +++ b/TMessagesProj/jni/voip/webrtc/call/simulated_network.cc @@ -77,6 +77,7 @@ bool CoDelSimulation::DropDequeuedPacket(Timestamp now, } return false; } + RTC_CHECK_NOTREACHED(); } SimulatedNetwork::SimulatedNetwork(Config config, uint64_t random_seed) diff --git a/TMessagesProj/jni/voip/webrtc/call/syncable.h b/TMessagesProj/jni/voip/webrtc/call/syncable.h index 3bbe50c8d..43b16a072 100644 --- a/TMessagesProj/jni/voip/webrtc/call/syncable.h +++ b/TMessagesProj/jni/voip/webrtc/call/syncable.h @@ -37,7 +37,7 @@ class Syncable { virtual absl::optional GetInfo() const = 0; virtual bool GetPlayoutRtpTimestamp(uint32_t* rtp_timestamp, int64_t* time_ms) const = 0; - virtual void SetMinimumPlayoutDelay(int delay_ms) = 0; + virtual bool SetMinimumPlayoutDelay(int delay_ms) = 0; virtual void SetEstimatedPlayoutNtpTimestampMs(int64_t ntp_timestamp_ms, int64_t time_ms) = 0; }; diff --git a/TMessagesProj/jni/voip/webrtc/call/video_receive_stream.h b/TMessagesProj/jni/voip/webrtc/call/video_receive_stream.h index 91c637160..7a6803d9e 100644 --- a/TMessagesProj/jni/voip/webrtc/call/video_receive_stream.h +++ b/TMessagesProj/jni/voip/webrtc/call/video_receive_stream.h @@ -32,6 +32,7 @@ #include "api/video/video_timing.h" #include "api/video_codecs/sdp_video_format.h" #include "call/rtp_config.h" +#include "common_video/frame_counts.h" #include "modules/rtp_rtcp/include/rtcp_statistics.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" diff --git a/TMessagesProj/jni/voip/webrtc/call/video_send_stream.cc b/TMessagesProj/jni/voip/webrtc/call/video_send_stream.cc index a4b674491..244d78089 100644 --- a/TMessagesProj/jni/voip/webrtc/call/video_send_stream.cc +++ b/TMessagesProj/jni/voip/webrtc/call/video_send_stream.cc @@ -28,6 +28,7 @@ const char* StreamTypeToString(VideoSendStream::StreamStats::StreamType type) { case VideoSendStream::StreamStats::StreamType::kFlexfec: return "flexfec"; } + RTC_CHECK_NOTREACHED(); } } // namespace diff --git a/TMessagesProj/jni/voip/webrtc/call/video_send_stream.h b/TMessagesProj/jni/voip/webrtc/call/video_send_stream.h index 715d5d73e..0df9e6ce0 100644 --- a/TMessagesProj/jni/voip/webrtc/call/video_send_stream.h +++ b/TMessagesProj/jni/voip/webrtc/call/video_send_stream.h @@ -31,6 +31,7 @@ #include "api/video/video_stream_encoder_settings.h" #include "api/video_codecs/video_encoder_config.h" #include "call/rtp_config.h" +#include "common_video/frame_counts.h" #include "common_video/include/quality_limitation_reason.h" #include "modules/rtp_rtcp/include/report_block_data.h" #include "modules/rtp_rtcp/include/rtcp_statistics.h" diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_avx2.cc b/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_avx2.cc new file mode 100644 index 000000000..26468e298 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_avx2.cc @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020 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_audio/fir_filter_avx2.h" + +#include +#include +#include +#include + +#include "rtc_base/checks.h" +#include "rtc_base/memory/aligned_malloc.h" + +namespace webrtc { + +FIRFilterAVX2::FIRFilterAVX2(const float* unaligned_coefficients, + size_t unaligned_coefficients_length, + size_t max_input_length) + : // Closest higher multiple of eight. + coefficients_length_((unaligned_coefficients_length + 7) & ~0x07), + state_length_(coefficients_length_ - 1), + coefficients_(static_cast( + AlignedMalloc(sizeof(float) * coefficients_length_, 32))), + state_(static_cast( + AlignedMalloc(sizeof(float) * (max_input_length + state_length_), + 32))) { + // Add zeros at the end of the coefficients. + RTC_DCHECK_GE(coefficients_length_, unaligned_coefficients_length); + size_t padding = coefficients_length_ - unaligned_coefficients_length; + memset(coefficients_.get(), 0, padding * sizeof(coefficients_[0])); + // The coefficients are reversed to compensate for the order in which the + // input samples are acquired (most recent last). + for (size_t i = 0; i < unaligned_coefficients_length; ++i) { + coefficients_[i + padding] = + unaligned_coefficients[unaligned_coefficients_length - i - 1]; + } + memset(state_.get(), 0, + (max_input_length + state_length_) * sizeof(state_[0])); +} + +FIRFilterAVX2::~FIRFilterAVX2() = default; + +void FIRFilterAVX2::Filter(const float* in, size_t length, float* out) { + RTC_DCHECK_GT(length, 0); + + memcpy(&state_[state_length_], in, length * sizeof(*in)); + + // Convolves the input signal |in| with the filter kernel |coefficients_| + // taking into account the previous state. + for (size_t i = 0; i < length; ++i) { + float* in_ptr = &state_[i]; + float* coef_ptr = coefficients_.get(); + + __m256 m_sum = _mm256_setzero_ps(); + __m256 m_in; + + // Depending on if the pointer is aligned with 32 bytes or not it is loaded + // differently. + if (reinterpret_cast(in_ptr) & 0x1F) { + for (size_t j = 0; j < coefficients_length_; j += 8) { + m_in = _mm256_loadu_ps(in_ptr + j); + m_sum = _mm256_fmadd_ps(m_in, _mm256_load_ps(coef_ptr + j), m_sum); + } + } else { + for (size_t j = 0; j < coefficients_length_; j += 8) { + m_in = _mm256_load_ps(in_ptr + j); + m_sum = _mm256_fmadd_ps(m_in, _mm256_load_ps(coef_ptr + j), m_sum); + } + } + __m128 m128_sum = _mm_add_ps(_mm256_extractf128_ps(m_sum, 0), + _mm256_extractf128_ps(m_sum, 1)); + m128_sum = _mm_add_ps(_mm_movehl_ps(m128_sum, m128_sum), m128_sum); + _mm_store_ss(out + i, + _mm_add_ss(m128_sum, _mm_shuffle_ps(m128_sum, m128_sum, 1))); + } + + // Update current state. + memmove(state_.get(), &state_[length], state_length_ * sizeof(state_[0])); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_avx2.h b/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_avx2.h new file mode 100644 index 000000000..893b60bf6 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_avx2.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef COMMON_AUDIO_FIR_FILTER_AVX2_H_ +#define COMMON_AUDIO_FIR_FILTER_AVX2_H_ + +#include + +#include + +#include "common_audio/fir_filter.h" +#include "rtc_base/memory/aligned_malloc.h" + +namespace webrtc { + +class FIRFilterAVX2 : public FIRFilter { + public: + FIRFilterAVX2(const float* coefficients, + size_t coefficients_length, + size_t max_input_length); + ~FIRFilterAVX2() override; + + void Filter(const float* in, size_t length, float* out) override; + + private: + const size_t coefficients_length_; + const size_t state_length_; + std::unique_ptr coefficients_; + std::unique_ptr state_; +}; + +} // namespace webrtc + +#endif // COMMON_AUDIO_FIR_FILTER_AVX2_H_ diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_factory.cc b/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_factory.cc index 19528e312..4ba53e2c9 100644 --- a/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/common_audio/fir_filter_factory.cc @@ -17,6 +17,7 @@ #if defined(WEBRTC_HAS_NEON) #include "common_audio/fir_filter_neon.h" #elif defined(WEBRTC_ARCH_X86_FAMILY) +#include "common_audio/fir_filter_avx2.h" #include "common_audio/fir_filter_sse.h" #include "system_wrappers/include/cpu_features_wrapper.h" // kSSE2, WebRtc_G... #endif @@ -34,18 +35,13 @@ FIRFilter* CreateFirFilter(const float* coefficients, FIRFilter* filter = nullptr; // If we know the minimum architecture at compile time, avoid CPU detection. #if defined(WEBRTC_ARCH_X86_FAMILY) -#if defined(__SSE2__) - filter = - new FIRFilterSSE2(coefficients, coefficients_length, max_input_length); -#else // x86 CPU detection required. - if (WebRtc_GetCPUInfo(kSSE2)) { + if (GetCPUInfo(kSSE2)) { filter = new FIRFilterSSE2(coefficients, coefficients_length, max_input_length); } else { filter = new FIRFilterC(coefficients, coefficients_length); } -#endif #elif defined(WEBRTC_HAS_NEON) filter = new FIRFilterNEON(coefficients, coefficients_length, max_input_length); diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler.cc b/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler.cc index 21707e9e4..154cf5b3b 100644 --- a/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler.cc +++ b/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler.cc @@ -122,28 +122,20 @@ double SincScaleFactor(double io_ratio) { const size_t SincResampler::kKernelSize; // If we know the minimum architecture at compile time, avoid CPU detection. -#if defined(WEBRTC_ARCH_X86_FAMILY) -#if defined(__SSE2__) -#define CONVOLVE_FUNC Convolve_SSE -void SincResampler::InitializeCPUSpecificFeatures() {} -#else -// x86 CPU detection required. Function will be set by -// InitializeCPUSpecificFeatures(). -// TODO(dalecurtis): Once Chrome moves to an SSE baseline this can be removed. -#define CONVOLVE_FUNC convolve_proc_ - void SincResampler::InitializeCPUSpecificFeatures() { - convolve_proc_ = WebRtc_GetCPUInfo(kSSE2) ? Convolve_SSE : Convolve_C; -} -#endif -#elif defined(WEBRTC_HAS_NEON) -#define CONVOLVE_FUNC Convolve_NEON -void SincResampler::InitializeCPUSpecificFeatures() {} +#if defined(WEBRTC_HAS_NEON) + convolve_proc_ = Convolve_NEON; +#elif defined(WEBRTC_ARCH_X86_FAMILY) + // Using AVX2 instead of SSE2 when AVX2 supported. + if (GetCPUInfo(kSSE2)) + convolve_proc_ = Convolve_SSE; + else + convolve_proc_ = Convolve_C; #else -// Unknown architecture. -#define CONVOLVE_FUNC Convolve_C -void SincResampler::InitializeCPUSpecificFeatures() {} + // Unknown architecture. + convolve_proc_ = Convolve_C; #endif +} SincResampler::SincResampler(double io_sample_rate_ratio, size_t request_frames, @@ -152,24 +144,20 @@ SincResampler::SincResampler(double io_sample_rate_ratio, read_cb_(read_cb), request_frames_(request_frames), input_buffer_size_(request_frames_ + kKernelSize), - // Create input buffers with a 16-byte alignment for SSE optimizations. + // Create input buffers with a 32-byte alignment for SIMD optimizations. kernel_storage_(static_cast( - AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))), + AlignedMalloc(sizeof(float) * kKernelStorageSize, 32))), kernel_pre_sinc_storage_(static_cast( - AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))), + AlignedMalloc(sizeof(float) * kKernelStorageSize, 32))), kernel_window_storage_(static_cast( - AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))), + AlignedMalloc(sizeof(float) * kKernelStorageSize, 32))), input_buffer_(static_cast( - AlignedMalloc(sizeof(float) * input_buffer_size_, 16))), -#if defined(WEBRTC_ARCH_X86_FAMILY) && !defined(__SSE2__) + AlignedMalloc(sizeof(float) * input_buffer_size_, 32))), convolve_proc_(nullptr), -#endif r1_(input_buffer_.get()), r2_(input_buffer_.get() + kKernelSize / 2) { -#if defined(WEBRTC_ARCH_X86_FAMILY) && !defined(__SSE2__) InitializeCPUSpecificFeatures(); RTC_DCHECK(convolve_proc_); -#endif RTC_DCHECK_GT(request_frames_, 0); Flush(); RTC_DCHECK_GT(block_size_, kKernelSize); @@ -302,10 +290,10 @@ void SincResampler::Resample(size_t frames, float* destination) { const float* const k1 = kernel_ptr + offset_idx * kKernelSize; const float* const k2 = k1 + kKernelSize; - // Ensure |k1|, |k2| are 16-byte aligned for SIMD usage. Should always be - // true so long as kKernelSize is a multiple of 16. - RTC_DCHECK_EQ(0, reinterpret_cast(k1) % 16); - RTC_DCHECK_EQ(0, reinterpret_cast(k2) % 16); + // Ensure |k1|, |k2| are 32-byte aligned for SIMD usage. Should always be + // true so long as kKernelSize is a multiple of 32. + RTC_DCHECK_EQ(0, reinterpret_cast(k1) % 32); + RTC_DCHECK_EQ(0, reinterpret_cast(k2) % 32); // Initialize input pointer based on quantized |virtual_source_idx_|. const float* const input_ptr = r1_ + source_idx; @@ -314,7 +302,7 @@ void SincResampler::Resample(size_t frames, float* destination) { const double kernel_interpolation_factor = virtual_offset_idx - offset_idx; *destination++ = - CONVOLVE_FUNC(input_ptr, k1, k2, kernel_interpolation_factor); + convolve_proc_(input_ptr, k1, k2, kernel_interpolation_factor); // Advance the virtual index. virtual_source_idx_ += current_io_ratio; diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler.h b/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler.h index 5181c18da..a72a0c62c 100644 --- a/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler.h +++ b/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler.h @@ -112,6 +112,10 @@ class SincResampler { const float* k1, const float* k2, double kernel_interpolation_factor); + static float Convolve_AVX2(const float* input_ptr, + const float* k1, + const float* k2, + double kernel_interpolation_factor); #elif defined(WEBRTC_HAS_NEON) static float Convolve_NEON(const float* input_ptr, const float* k1, @@ -155,13 +159,11 @@ class SincResampler { // TODO(ajm): Move to using a global static which must only be initialized // once by the user. We're not doing this initially, because we don't have // e.g. a LazyInstance helper in webrtc. -#if defined(WEBRTC_ARCH_X86_FAMILY) && !defined(__SSE2__) typedef float (*ConvolveProc)(const float*, const float*, const float*, double); ConvolveProc convolve_proc_; -#endif // Pointers to the various regions inside |input_buffer_|. See the diagram at // the top of the .cc file for more information. diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler_avx2.cc b/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler_avx2.cc new file mode 100644 index 000000000..3eb5d4a1b --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/common_audio/resampler/sinc_resampler_avx2.cc @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 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 +#include +#include +#include + +#include "common_audio/resampler/sinc_resampler.h" + +namespace webrtc { + +float SincResampler::Convolve_AVX2(const float* input_ptr, + const float* k1, + const float* k2, + double kernel_interpolation_factor) { + __m256 m_input; + __m256 m_sums1 = _mm256_setzero_ps(); + __m256 m_sums2 = _mm256_setzero_ps(); + + // Based on |input_ptr| alignment, we need to use loadu or load. Unrolling + // these loops has not been tested or benchmarked. + bool aligned_input = (reinterpret_cast(input_ptr) & 0x1F) == 0; + if (!aligned_input) { + for (size_t i = 0; i < kKernelSize; i += 8) { + m_input = _mm256_loadu_ps(input_ptr + i); + m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1); + m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2); + } + } else { + for (size_t i = 0; i < kKernelSize; i += 8) { + m_input = _mm256_load_ps(input_ptr + i); + m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1); + m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2); + } + } + + // Linearly interpolate the two "convolutions". + __m128 m128_sums1 = _mm_add_ps(_mm256_extractf128_ps(m_sums1, 0), + _mm256_extractf128_ps(m_sums1, 1)); + __m128 m128_sums2 = _mm_add_ps(_mm256_extractf128_ps(m_sums2, 0), + _mm256_extractf128_ps(m_sums2, 1)); + m128_sums1 = _mm_mul_ps( + m128_sums1, + _mm_set_ps1(static_cast(1.0 - kernel_interpolation_factor))); + m128_sums2 = _mm_mul_ps( + m128_sums2, _mm_set_ps1(static_cast(kernel_interpolation_factor))); + m128_sums1 = _mm_add_ps(m128_sums1, m128_sums2); + + // Sum components together. + float result; + m128_sums2 = _mm_add_ps(_mm_movehl_ps(m128_sums1, m128_sums1), m128_sums1); + _mm_store_ss(&result, _mm_add_ss(m128_sums2, + _mm_shuffle_ps(m128_sums2, m128_sums2, 1))); + + return result; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/smoothing_filter.h b/TMessagesProj/jni/voip/webrtc/common_audio/smoothing_filter.h index e5f561ecf..e96d52a6f 100644 --- a/TMessagesProj/jni/voip/webrtc/common_audio/smoothing_filter.h +++ b/TMessagesProj/jni/voip/webrtc/common_audio/smoothing_filter.h @@ -14,7 +14,6 @@ #include #include "absl/types/optional.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -42,6 +41,11 @@ class SmoothingFilterImpl final : public SmoothingFilter { // will be set to |init_time_ms| first and can be changed through // |SetTimeConstantMs|. explicit SmoothingFilterImpl(int init_time_ms); + + SmoothingFilterImpl() = delete; + SmoothingFilterImpl(const SmoothingFilterImpl&) = delete; + SmoothingFilterImpl& operator=(const SmoothingFilterImpl&) = delete; + ~SmoothingFilterImpl() override; void AddSample(float sample) override; @@ -64,8 +68,6 @@ class SmoothingFilterImpl final : public SmoothingFilter { float alpha_; float state_; int64_t last_state_time_ms_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SmoothingFilterImpl); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/third_party/ooura/fft_size_128/ooura_fft.cc b/TMessagesProj/jni/voip/webrtc/common_audio/third_party/ooura/fft_size_128/ooura_fft.cc index 6b6d6f1fd..693312012 100644 --- a/TMessagesProj/jni/voip/webrtc/common_audio/third_party/ooura/fft_size_128/ooura_fft.cc +++ b/TMessagesProj/jni/voip/webrtc/common_audio/third_party/ooura/fft_size_128/ooura_fft.cc @@ -323,7 +323,7 @@ OouraFft::OouraFft(bool sse2_available) { OouraFft::OouraFft() { #if defined(WEBRTC_ARCH_X86_FAMILY) - use_sse2_ = (WebRtc_GetCPUInfo(kSSE2) != 0); + use_sse2_ = (GetCPUInfo(kSSE2) != 0); #else use_sse2_ = false; #endif diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/vad/vad_unittest.h b/TMessagesProj/jni/voip/webrtc/common_audio/vad/vad_unittest.h new file mode 100644 index 000000000..ee642063a --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/common_audio/vad/vad_unittest.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012 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. + */ + +#ifndef COMMON_AUDIO_VAD_VAD_UNITTEST_H_ +#define COMMON_AUDIO_VAD_VAD_UNITTEST_H_ + +#include // size_t + +#include "test/gtest.h" + +namespace webrtc { +namespace test { + +// Modes we support +const int kModes[] = {0, 1, 2, 3}; +const size_t kModesSize = sizeof(kModes) / sizeof(*kModes); + +// Rates we support. +const int kRates[] = {8000, 12000, 16000, 24000, 32000, 48000}; +const size_t kRatesSize = sizeof(kRates) / sizeof(*kRates); + +// Frame lengths we support. +const size_t kMaxFrameLength = 1440; +const size_t kFrameLengths[] = { + 80, 120, 160, 240, 320, 480, 640, 960, kMaxFrameLength}; +const size_t kFrameLengthsSize = sizeof(kFrameLengths) / sizeof(*kFrameLengths); + +} // namespace test +} // namespace webrtc + +class VadTest : public ::testing::Test { + protected: + VadTest(); + void SetUp() override; + void TearDown() override; + + // Returns true if the rate and frame length combination is valid. + bool ValidRatesAndFrameLengths(int rate, size_t frame_length); +}; + +#endif // COMMON_AUDIO_VAD_VAD_UNITTEST_H_ diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/wav_header.cc b/TMessagesProj/jni/voip/webrtc/common_audio/wav_header.cc index d3dca9055..ce119f109 100644 --- a/TMessagesProj/jni/voip/webrtc/common_audio/wav_header.cc +++ b/TMessagesProj/jni/voip/webrtc/common_audio/wav_header.cc @@ -132,7 +132,7 @@ uint16_t MapWavFormatToHeaderField(WavFormat format) { case WavFormat::kWavFormatMuLaw: return 7; } - RTC_CHECK(false); + RTC_CHECK_NOTREACHED(); } WavFormat MapHeaderFieldToWavFormat(uint16_t format_header_value) { @@ -278,10 +278,8 @@ size_t GetFormatBytesPerSample(WavFormat format) { return 1; case WavFormat::kWavFormatIeeeFloat: return 4; - default: - RTC_CHECK(false); - return 2; } + RTC_CHECK_NOTREACHED(); } bool CheckWavParameters(size_t num_channels, diff --git a/TMessagesProj/jni/voip/webrtc/common_audio/window_generator.h b/TMessagesProj/jni/voip/webrtc/common_audio/window_generator.h index 0cbe24a40..c0a89c4f9 100644 --- a/TMessagesProj/jni/voip/webrtc/common_audio/window_generator.h +++ b/TMessagesProj/jni/voip/webrtc/common_audio/window_generator.h @@ -13,18 +13,17 @@ #include -#include "rtc_base/constructor_magic.h" - namespace webrtc { // Helper class with generators for various signal transform windows. class WindowGenerator { public: + WindowGenerator() = delete; + WindowGenerator(const WindowGenerator&) = delete; + WindowGenerator& operator=(const WindowGenerator&) = delete; + static void Hanning(int length, float* window); static void KaiserBesselDerived(float alpha, size_t length, float* window); - - private: - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WindowGenerator); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/common_video/frame_counts.h b/TMessagesProj/jni/voip/webrtc/common_video/frame_counts.h new file mode 100644 index 000000000..663fda4a2 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/common_video/frame_counts.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef COMMON_VIDEO_FRAME_COUNTS_H_ +#define COMMON_VIDEO_FRAME_COUNTS_H_ + +namespace webrtc { + +struct FrameCounts { + FrameCounts() : key_frames(0), delta_frames(0) {} + int key_frames; + int delta_frames; +}; + +// Callback, used to notify an observer whenever frame counts have been updated. +class FrameCountObserver { + public: + virtual ~FrameCountObserver() {} + virtual void FrameCountUpdated(const FrameCounts& frame_counts, + uint32_t ssrc) = 0; +}; + +} // namespace webrtc + +#endif // COMMON_VIDEO_FRAME_COUNTS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/common_video/h264/OWNERS b/TMessagesProj/jni/voip/webrtc/common_video/h264/OWNERS new file mode 100644 index 000000000..361ed7e84 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/common_video/h264/OWNERS @@ -0,0 +1 @@ +ssilkin@webrtc.org diff --git a/TMessagesProj/jni/voip/webrtc/common_video/h264/sps_vui_rewriter.cc b/TMessagesProj/jni/voip/webrtc/common_video/h264/sps_vui_rewriter.cc index 3fc794fb2..0d16be825 100644 --- a/TMessagesProj/jni/voip/webrtc/common_video/h264/sps_vui_rewriter.cc +++ b/TMessagesProj/jni/voip/webrtc/common_video/h264/sps_vui_rewriter.cc @@ -210,7 +210,7 @@ SpsVuiRewriter::ParseResult SpsVuiRewriter::ParseAndRewriteSps( return result; } -rtc::Buffer SpsVuiRewriter::ParseOutgoingBitstreamAndRewriteSps( +rtc::Buffer SpsVuiRewriter::ParseOutgoingBitstreamAndRewrite( rtc::ArrayView buffer, const webrtc::ColorSpace* color_space) { std::vector nalus = @@ -225,8 +225,6 @@ rtc::Buffer SpsVuiRewriter::ParseOutgoingBitstreamAndRewriteSps( const uint8_t* start_code_ptr = buffer.data() + nalu.start_offset; const size_t start_code_length = nalu.payload_start_offset - nalu.start_offset; - output_buffer.AppendData(start_code_ptr, start_code_length); - const uint8_t* nalu_ptr = buffer.data() + nalu.payload_start_offset; const size_t nalu_length = nalu.payload_size; @@ -253,12 +251,17 @@ rtc::Buffer SpsVuiRewriter::ParseOutgoingBitstreamAndRewriteSps( nalu_ptr + H264::kNaluTypeSize, nalu_length - H264::kNaluTypeSize, &sps, color_space, &output_nalu, Direction::kOutgoing); if (result == ParseResult::kVuiRewritten) { + output_buffer.AppendData(start_code_ptr, start_code_length); output_buffer.AppendData(output_nalu.data(), output_nalu.size()); continue; } + } else if (H264::ParseNaluType(nalu_ptr[0]) == H264::NaluType::kAud) { + // Skip the access unit delimiter copy. + continue; } - // vui wasn't rewritten, copy the nal unit as is. + // vui wasn't rewritten and it is not aud, copy the nal unit as is. + output_buffer.AppendData(start_code_ptr, start_code_length); output_buffer.AppendData(nalu_ptr, nalu_length); } return output_buffer; diff --git a/TMessagesProj/jni/voip/webrtc/common_video/h264/sps_vui_rewriter.h b/TMessagesProj/jni/voip/webrtc/common_video/h264/sps_vui_rewriter.h index 9e79c3f31..311db30d5 100644 --- a/TMessagesProj/jni/voip/webrtc/common_video/h264/sps_vui_rewriter.h +++ b/TMessagesProj/jni/voip/webrtc/common_video/h264/sps_vui_rewriter.h @@ -50,8 +50,9 @@ class SpsVuiRewriter : private SpsParser { rtc::Buffer* destination, Direction Direction); - // Parses NAL units from |buffer| and rewrites VUI in SPS blocks if necessary. - static rtc::Buffer ParseOutgoingBitstreamAndRewriteSps( + // Parses NAL units from |buffer|, strips AUD blocks and rewrites VUI in SPS + // blocks if necessary. + static rtc::Buffer ParseOutgoingBitstreamAndRewrite( rtc::ArrayView buffer, const ColorSpace* color_space); diff --git a/TMessagesProj/jni/voip/webrtc/common_video/i420_buffer_pool.cc b/TMessagesProj/jni/voip/webrtc/common_video/i420_buffer_pool.cc deleted file mode 100644 index d13da6a17..000000000 --- a/TMessagesProj/jni/voip/webrtc/common_video/i420_buffer_pool.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2015 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/include/i420_buffer_pool.h" - -#include - -#include "rtc_base/checks.h" - -namespace webrtc { - -I420BufferPool::I420BufferPool() : I420BufferPool(false) {} -I420BufferPool::I420BufferPool(bool zero_initialize) - : I420BufferPool(zero_initialize, std::numeric_limits::max()) {} -I420BufferPool::I420BufferPool(bool zero_initialize, - size_t max_number_of_buffers) - : zero_initialize_(zero_initialize), - max_number_of_buffers_(max_number_of_buffers) {} -I420BufferPool::~I420BufferPool() = default; - -void I420BufferPool::Release() { - buffers_.clear(); -} - -bool I420BufferPool::Resize(size_t max_number_of_buffers) { - RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); - size_t used_buffers_count = 0; - for (const rtc::scoped_refptr& buffer : buffers_) { - // If the buffer is in use, the ref count will be >= 2, one from the list we - // are looping over and one from the application. If the ref count is 1, - // then the list we are looping over holds the only reference and it's safe - // to reuse. - if (!buffer->HasOneRef()) { - used_buffers_count++; - } - } - if (used_buffers_count > max_number_of_buffers) { - return false; - } - max_number_of_buffers_ = max_number_of_buffers; - - size_t buffers_to_purge = buffers_.size() - max_number_of_buffers_; - auto iter = buffers_.begin(); - while (iter != buffers_.end() && buffers_to_purge > 0) { - if ((*iter)->HasOneRef()) { - iter = buffers_.erase(iter); - buffers_to_purge--; - } else { - ++iter; - } - } - return true; -} - -rtc::scoped_refptr I420BufferPool::CreateBuffer(int width, - int height) { - // Default stride_y is width, default uv stride is width / 2 (rounding up). - return CreateBuffer(width, height, width, (width + 1) / 2, (width + 1) / 2); -} - -rtc::scoped_refptr I420BufferPool::CreateBuffer(int width, - int height, - int stride_y, - int stride_u, - int stride_v) { - RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); - // Release buffers with wrong resolution. - for (auto it = buffers_.begin(); it != buffers_.end();) { - const auto& buffer = *it; - if (buffer->width() != width || buffer->height() != height || - buffer->StrideY() != stride_y || buffer->StrideU() != stride_u || - buffer->StrideV() != stride_v) { - it = buffers_.erase(it); - } else { - ++it; - } - } - // Look for a free buffer. - for (const rtc::scoped_refptr& buffer : buffers_) { - // If the buffer is in use, the ref count will be >= 2, one from the list we - // are looping over and one from the application. If the ref count is 1, - // then the list we are looping over holds the only reference and it's safe - // to reuse. - if (buffer->HasOneRef()) - return buffer; - } - - if (buffers_.size() >= max_number_of_buffers_) - return nullptr; - // Allocate new buffer. - rtc::scoped_refptr buffer = - new PooledI420Buffer(width, height, stride_y, stride_u, stride_v); - if (zero_initialize_) - buffer->InitializeData(); - buffers_.push_back(buffer); - return buffer; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/common_video/include/i420_buffer_pool.h b/TMessagesProj/jni/voip/webrtc/common_video/include/video_frame_buffer_pool.h similarity index 53% rename from TMessagesProj/jni/voip/webrtc/common_video/include/i420_buffer_pool.h rename to TMessagesProj/jni/voip/webrtc/common_video/include/video_frame_buffer_pool.h index 44f482179..6af117577 100644 --- a/TMessagesProj/jni/voip/webrtc/common_video/include/i420_buffer_pool.h +++ b/TMessagesProj/jni/voip/webrtc/common_video/include/video_frame_buffer_pool.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef COMMON_VIDEO_INCLUDE_I420_BUFFER_POOL_H_ -#define COMMON_VIDEO_INCLUDE_I420_BUFFER_POOL_H_ +#ifndef COMMON_VIDEO_INCLUDE_VIDEO_FRAME_BUFFER_POOL_H_ +#define COMMON_VIDEO_INCLUDE_VIDEO_FRAME_BUFFER_POOL_H_ #include @@ -17,36 +17,33 @@ #include "api/scoped_refptr.h" #include "api/video/i420_buffer.h" +#include "api/video/nv12_buffer.h" #include "rtc_base/race_checker.h" #include "rtc_base/ref_counted_object.h" namespace webrtc { -// Simple buffer pool to avoid unnecessary allocations of I420Buffer objects. -// The pool manages the memory of the I420Buffer returned from CreateBuffer. -// When the I420Buffer is destructed, the memory is returned to the pool for use -// by subsequent calls to CreateBuffer. If the resolution passed to CreateBuffer -// changes, old buffers will be purged from the pool. -// Note that CreateBuffer will crash if more than kMaxNumberOfFramesBeforeCrash -// are created. This is to prevent memory leaks where frames are not returned. -class I420BufferPool { +// Simple buffer pool to avoid unnecessary allocations of video frame buffers. +// The pool manages the memory of the I420Buffer/NV12Buffer returned from +// Create(I420|NV12)Buffer. When the buffer is destructed, the memory is +// returned to the pool for use by subsequent calls to Create(I420|NV12)Buffer. +// If the resolution passed to Create(I420|NV12)Buffer changes or requested +// pixel format changes, old buffers will be purged from the pool. +// Note that Create(I420|NV12)Buffer will crash if more than +// kMaxNumberOfFramesBeforeCrash are created. This is to prevent memory leaks +// where frames are not returned. +class VideoFrameBufferPool { public: - I420BufferPool(); - explicit I420BufferPool(bool zero_initialize); - I420BufferPool(bool zero_initialze, size_t max_number_of_buffers); - ~I420BufferPool(); + VideoFrameBufferPool(); + explicit VideoFrameBufferPool(bool zero_initialize); + VideoFrameBufferPool(bool zero_initialize, size_t max_number_of_buffers); + ~VideoFrameBufferPool(); // Returns a buffer from the pool. If no suitable buffer exist in the pool // and there are less than |max_number_of_buffers| pending, a buffer is // created. Returns null otherwise. - rtc::scoped_refptr CreateBuffer(int width, int height); - - // Returns a buffer from the pool with the explicitly specified stride. - rtc::scoped_refptr CreateBuffer(int width, - int height, - int stride_y, - int stride_u, - int stride_v); + rtc::scoped_refptr CreateI420Buffer(int width, int height); + rtc::scoped_refptr CreateNV12Buffer(int width, int height); // Changes the max amount of buffers in the pool to the new value. // Returns true if change was successful and false if the amount of already @@ -58,12 +55,11 @@ class I420BufferPool { void Release(); private: - // Explicitly use a RefCountedObject to get access to HasOneRef, - // needed by the pool to check exclusive access. - using PooledI420Buffer = rtc::RefCountedObject; + rtc::scoped_refptr + GetExistingBuffer(int width, int height, VideoFrameBuffer::Type type); rtc::RaceChecker race_checker_; - std::list> buffers_; + std::list> buffers_; // If true, newly allocated buffers are zero-initialized. Note that recycled // buffers are not zero'd before reuse. This is required of buffers used by // FFmpeg according to http://crbug.com/390941, which only requires it for the @@ -76,4 +72,4 @@ class I420BufferPool { } // namespace webrtc -#endif // COMMON_VIDEO_INCLUDE_I420_BUFFER_POOL_H_ +#endif // COMMON_VIDEO_INCLUDE_VIDEO_FRAME_BUFFER_POOL_H_ diff --git a/TMessagesProj/jni/voip/webrtc/common_video/video_frame_buffer_pool.cc b/TMessagesProj/jni/voip/webrtc/common_video/video_frame_buffer_pool.cc new file mode 100644 index 000000000..6df240d9f --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/common_video/video_frame_buffer_pool.cc @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2015 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/include/video_frame_buffer_pool.h" + +#include + +#include "rtc_base/checks.h" + +namespace webrtc { + +namespace { +bool HasOneRef(const rtc::scoped_refptr& buffer) { + // Cast to rtc::RefCountedObject is safe because this function is only called + // on locally created VideoFrameBuffers, which are either + // |rtc::RefCountedObject| or |rtc::RefCountedObject|. + switch (buffer->type()) { + case VideoFrameBuffer::Type::kI420: { + return static_cast*>(buffer.get()) + ->HasOneRef(); + } + case VideoFrameBuffer::Type::kNV12: { + return static_cast*>(buffer.get()) + ->HasOneRef(); + } + default: + RTC_NOTREACHED(); + } + return false; +} + +} // namespace + +VideoFrameBufferPool::VideoFrameBufferPool() : VideoFrameBufferPool(false) {} + +VideoFrameBufferPool::VideoFrameBufferPool(bool zero_initialize) + : VideoFrameBufferPool(zero_initialize, + std::numeric_limits::max()) {} + +VideoFrameBufferPool::VideoFrameBufferPool(bool zero_initialize, + size_t max_number_of_buffers) + : zero_initialize_(zero_initialize), + max_number_of_buffers_(max_number_of_buffers) {} + +VideoFrameBufferPool::~VideoFrameBufferPool() = default; + +void VideoFrameBufferPool::Release() { + buffers_.clear(); +} + +bool VideoFrameBufferPool::Resize(size_t max_number_of_buffers) { + RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); + size_t used_buffers_count = 0; + for (const rtc::scoped_refptr& buffer : buffers_) { + // If the buffer is in use, the ref count will be >= 2, one from the list we + // are looping over and one from the application. If the ref count is 1, + // then the list we are looping over holds the only reference and it's safe + // to reuse. + if (!HasOneRef(buffer)) { + used_buffers_count++; + } + } + if (used_buffers_count > max_number_of_buffers) { + return false; + } + max_number_of_buffers_ = max_number_of_buffers; + + size_t buffers_to_purge = buffers_.size() - max_number_of_buffers_; + auto iter = buffers_.begin(); + while (iter != buffers_.end() && buffers_to_purge > 0) { + if (HasOneRef(*iter)) { + iter = buffers_.erase(iter); + buffers_to_purge--; + } else { + ++iter; + } + } + return true; +} + +rtc::scoped_refptr VideoFrameBufferPool::CreateI420Buffer( + int width, + int height) { + RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); + + rtc::scoped_refptr existing_buffer = + GetExistingBuffer(width, height, VideoFrameBuffer::Type::kI420); + if (existing_buffer) { + // Cast is safe because the only way kI420 buffer is created is + // in the same function below, where |RefCountedObject| is + // created. + rtc::RefCountedObject* raw_buffer = + static_cast*>(existing_buffer.get()); + // Creates a new scoped_refptr, which is also pointing to the same + // RefCountedObject as buffer, increasing ref count. + return rtc::scoped_refptr(raw_buffer); + } + + if (buffers_.size() >= max_number_of_buffers_) + return nullptr; + // Allocate new buffer. + rtc::scoped_refptr buffer = + new rtc::RefCountedObject(width, height); + + if (zero_initialize_) + buffer->InitializeData(); + + buffers_.push_back(buffer); + return buffer; +} + +rtc::scoped_refptr VideoFrameBufferPool::CreateNV12Buffer( + int width, + int height) { + RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); + + rtc::scoped_refptr existing_buffer = + GetExistingBuffer(width, height, VideoFrameBuffer::Type::kNV12); + if (existing_buffer) { + // Cast is safe because the only way kI420 buffer is created is + // in the same function below, where |RefCountedObject| is + // created. + rtc::RefCountedObject* raw_buffer = + static_cast*>(existing_buffer.get()); + // Creates a new scoped_refptr, which is also pointing to the same + // RefCountedObject as buffer, increasing ref count. + return rtc::scoped_refptr(raw_buffer); + } + + if (buffers_.size() >= max_number_of_buffers_) + return nullptr; + // Allocate new buffer. + rtc::scoped_refptr buffer = + new rtc::RefCountedObject(width, height); + + if (zero_initialize_) + buffer->InitializeData(); + + buffers_.push_back(buffer); + return buffer; +} + +rtc::scoped_refptr VideoFrameBufferPool::GetExistingBuffer( + int width, + int height, + VideoFrameBuffer::Type type) { + // Release buffers with wrong resolution or different type. + for (auto it = buffers_.begin(); it != buffers_.end();) { + const auto& buffer = *it; + if (buffer->width() != width || buffer->height() != height || + buffer->type() != type) { + it = buffers_.erase(it); + } else { + ++it; + } + } + // Look for a free buffer. + for (const rtc::scoped_refptr& buffer : buffers_) { + // If the buffer is in use, the ref count will be >= 2, one from the list we + // are looping over and one from the application. If the ref count is 1, + // then the list we are looping over holds the only reference and it's safe + // to reuse. + if (HasOneRef(buffer)) { + RTC_CHECK(buffer->type() == type); + return buffer; + } + } + return nullptr; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc index d16badaad..143df8821 100644 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc @@ -696,8 +696,7 @@ std::string RtcEventLogEncoderLegacy::EncodeRtcpPacket( rtcp::CommonHeader header; const uint8_t* block_begin = packet.data(); const uint8_t* packet_end = packet.data() + packet.size(); - RTC_DCHECK(packet.size() <= IP_PACKET_SIZE); - uint8_t buffer[IP_PACKET_SIZE]; + std::vector buffer(packet.size()); uint32_t buffer_length = 0; while (block_begin < packet_end) { if (!header.Parse(block_begin, packet_end - block_begin)) { @@ -716,7 +715,7 @@ std::string RtcEventLogEncoderLegacy::EncodeRtcpPacket( // We log sender reports, receiver reports, bye messages // inter-arrival jitter, third-party loss reports, payload-specific // feedback and extended reports. - memcpy(buffer + buffer_length, block_begin, block_size); + memcpy(buffer.data() + buffer_length, block_begin, block_size); buffer_length += block_size; break; case rtcp::App::kPacketType: @@ -729,7 +728,8 @@ std::string RtcEventLogEncoderLegacy::EncodeRtcpPacket( block_begin += block_size; } - rtclog_event.mutable_rtcp_packet()->set_packet_data(buffer, buffer_length); + rtclog_event.mutable_rtcp_packet()->set_packet_data(buffer.data(), + buffer_length); return Serialize(&rtclog_event); } diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc index bc68af29d..7f1b0c7d6 100644 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc @@ -290,11 +290,9 @@ rtclog2::IceCandidatePairEvent::IceCandidatePairEventType ConvertToProtoFormat( } // Copies all RTCP blocks except APP, SDES and unknown from |packet| to -// |buffer|. |buffer| must have space for |IP_PACKET_SIZE| bytes. |packet| must -// be at most |IP_PACKET_SIZE| bytes long. +// |buffer|. |buffer| must have space for at least |packet.size()| bytes. size_t RemoveNonWhitelistedRtcpBlocks(const rtc::Buffer& packet, uint8_t* buffer) { - RTC_DCHECK(packet.size() <= IP_PACKET_SIZE); RTC_DCHECK(buffer != nullptr); rtcp::CommonHeader header; const uint8_t* block_begin = packet.data(); @@ -348,10 +346,10 @@ void EncodeRtcpPacket(rtc::ArrayView batch, const EventType* const base_event = batch[0]; proto_batch->set_timestamp_ms(base_event->timestamp_ms()); { - uint8_t buffer[IP_PACKET_SIZE]; + std::vector buffer(base_event->packet().size()); size_t buffer_length = - RemoveNonWhitelistedRtcpBlocks(base_event->packet(), buffer); - proto_batch->set_raw_packet(buffer, buffer_length); + RemoveNonWhitelistedRtcpBlocks(base_event->packet(), buffer.data()); + proto_batch->set_raw_packet(buffer.data(), buffer_length); } if (batch.size() == 1) { @@ -700,7 +698,8 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch( std::vector bwe_loss_based_updates; std::vector dtls_transport_states; std::vector dtls_writable_states; - std::vector frames_decoded; + std::map> + frames_decoded; std::vector generic_acks_received; std::vector generic_packets_received; std::vector generic_packets_sent; @@ -886,8 +885,7 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch( case RtcEvent::Type::FrameDecoded: { auto* rtc_event = static_cast(it->get()); - // TODO(terelius): Group by SSRC - frames_decoded.push_back(rtc_event); + frames_decoded[rtc_event->ssrc()].emplace_back(rtc_event); break; } } @@ -903,7 +901,9 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch( EncodeBweUpdateLossBased(bwe_loss_based_updates, &event_stream); EncodeDtlsTransportState(dtls_transport_states, &event_stream); EncodeDtlsWritableState(dtls_writable_states, &event_stream); - EncodeFramesDecoded(frames_decoded, &event_stream); + for (const auto& kv : frames_decoded) { + EncodeFramesDecoded(kv.second, &event_stream); + } EncodeGenericAcksReceived(generic_acks_received, &event_stream); EncodeGenericPacketsReceived(generic_packets_received, &event_stream); EncodeGenericPacketsSent(generic_packets_sent, &event_stream); @@ -1409,7 +1409,7 @@ void RtcEventLogEncoderNewFormat::EncodeRemoteEstimate( // link_capacity_lower_kbps for (size_t i = 0; i < values.size(); ++i) { const auto* event = batch[i + 1]; - if (base_event->link_capacity_lower_.IsFinite()) { + if (event->link_capacity_lower_.IsFinite()) { values[i] = event->link_capacity_lower_.kbps(); } else { values[i].reset(); @@ -1423,7 +1423,7 @@ void RtcEventLogEncoderNewFormat::EncodeRemoteEstimate( // link_capacity_upper_kbps for (size_t i = 0; i < values.size(); ++i) { const auto* event = batch[i + 1]; - if (base_event->link_capacity_upper_.IsFinite()) { + if (event->link_capacity_upper_.IsFinite()) { values[i] = event->link_capacity_upper_.kbps(); } else { values[i].reset(); @@ -1464,7 +1464,7 @@ void RtcEventLogEncoderNewFormat::EncodeRtpPacketIncoming( } void RtcEventLogEncoderNewFormat::EncodeFramesDecoded( - rtc::ArrayView batch, + rtc::ArrayView batch, rtclog2::EventStream* event_stream) { if (batch.empty()) { return; diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h index fdbe8fe85..6af34bc6c 100644 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h @@ -95,8 +95,9 @@ class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder { void EncodeDtlsWritableState( rtc::ArrayView batch, rtclog2::EventStream* event_stream); - void EncodeFramesDecoded(rtc::ArrayView batch, - rtclog2::EventStream* event_stream); + void EncodeFramesDecoded( + rtc::ArrayView batch, + rtclog2::EventStream* event_stream); void EncodeGenericAcksReceived( rtc::ArrayView batch, rtclog2::EventStream* event_stream); diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/logged_events.cc b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/logged_events.cc index 3cba8bab2..dd0a8aae2 100644 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/logged_events.cc +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/logged_events.cc @@ -41,15 +41,17 @@ LoggedPacketInfo::LoggedPacketInfo(const LoggedPacketInfo&) = default; LoggedPacketInfo::~LoggedPacketInfo() {} LoggedRtcpPacket::LoggedRtcpPacket(int64_t timestamp_us, - const uint8_t* packet, - size_t total_length) - : timestamp_us(timestamp_us), raw_data(packet, packet + total_length) {} + const std::vector& packet) + : timestamp_us(timestamp_us), raw_data(packet) {} + LoggedRtcpPacket::LoggedRtcpPacket(int64_t timestamp_us, const std::string& packet) : timestamp_us(timestamp_us), raw_data(packet.size()) { memcpy(raw_data.data(), packet.data(), packet.size()); } + LoggedRtcpPacket::LoggedRtcpPacket(const LoggedRtcpPacket& rhs) = default; + LoggedRtcpPacket::~LoggedRtcpPacket() = default; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/logged_events.h b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/logged_events.h index 4bd33f62b..192f7cf81 100644 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/logged_events.h +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/logged_events.h @@ -309,9 +309,7 @@ struct LoggedRtpPacketOutgoing { }; struct LoggedRtcpPacket { - LoggedRtcpPacket(int64_t timestamp_us, - const uint8_t* packet, - size_t total_length); + LoggedRtcpPacket(int64_t timestamp_us, const std::vector& packet); LoggedRtcpPacket(int64_t timestamp_us, const std::string& packet); LoggedRtcpPacket(const LoggedRtcpPacket&); ~LoggedRtcpPacket(); @@ -325,9 +323,8 @@ struct LoggedRtcpPacket { struct LoggedRtcpPacketIncoming { LoggedRtcpPacketIncoming(int64_t timestamp_us, - const uint8_t* packet, - size_t total_length) - : rtcp(timestamp_us, packet, total_length) {} + const std::vector& packet) + : rtcp(timestamp_us, packet) {} LoggedRtcpPacketIncoming(uint64_t timestamp_us, const std::string& packet) : rtcp(timestamp_us, packet) {} @@ -339,9 +336,8 @@ struct LoggedRtcpPacketIncoming { struct LoggedRtcpPacketOutgoing { LoggedRtcpPacketOutgoing(int64_t timestamp_us, - const uint8_t* packet, - size_t total_length) - : rtcp(timestamp_us, packet, total_length) {} + const std::vector& packet) + : rtcp(timestamp_us, packet) {} LoggedRtcpPacketOutgoing(uint64_t timestamp_us, const std::string& packet) : rtcp(timestamp_us, packet) {} diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log.pb.cc b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log.pb.cc deleted file mode 100644 index 4e459c144..000000000 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log.pb.cc +++ /dev/null @@ -1,9708 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: rtc_event_log.proto - -#include "rtc_event_log.pb.h" - -#include - -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) -#include -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AlrState_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AudioNetworkAdaptation_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AudioPlayoutEvent_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_AudioReceiveConfig_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_AudioSendConfig_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeCluster_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeResult_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DecoderConfig_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DelayBasedBweUpdate_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_EncoderConfig_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<15> scc_info_Event_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IceCandidatePairConfig_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IceCandidatePairEvent_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_LossBasedBweUpdate_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtcpPacket_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtpPacket_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtxConfig_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_RtxMap_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_VideoReceiveConfig_rtc_5fevent_5flog_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_VideoSendConfig_rtc_5fevent_5flog_2eproto; -namespace webrtc { -namespace rtclog { -class EventStreamDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _EventStream_default_instance_; -class EventDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; - const ::webrtc::rtclog::RtpPacket* rtp_packet_; - const ::webrtc::rtclog::RtcpPacket* rtcp_packet_; - const ::webrtc::rtclog::AudioPlayoutEvent* audio_playout_event_; - const ::webrtc::rtclog::LossBasedBweUpdate* loss_based_bwe_update_; - const ::webrtc::rtclog::DelayBasedBweUpdate* delay_based_bwe_update_; - const ::webrtc::rtclog::VideoReceiveConfig* video_receiver_config_; - const ::webrtc::rtclog::VideoSendConfig* video_sender_config_; - const ::webrtc::rtclog::AudioReceiveConfig* audio_receiver_config_; - const ::webrtc::rtclog::AudioSendConfig* audio_sender_config_; - const ::webrtc::rtclog::AudioNetworkAdaptation* audio_network_adaptation_; - const ::webrtc::rtclog::BweProbeCluster* probe_cluster_; - const ::webrtc::rtclog::BweProbeResult* probe_result_; - const ::webrtc::rtclog::AlrState* alr_state_; - const ::webrtc::rtclog::IceCandidatePairConfig* ice_candidate_pair_config_; - const ::webrtc::rtclog::IceCandidatePairEvent* ice_candidate_pair_event_; -} _Event_default_instance_; -class RtpPacketDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _RtpPacket_default_instance_; -class RtcpPacketDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _RtcpPacket_default_instance_; -class AudioPlayoutEventDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AudioPlayoutEvent_default_instance_; -class LossBasedBweUpdateDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _LossBasedBweUpdate_default_instance_; -class DelayBasedBweUpdateDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _DelayBasedBweUpdate_default_instance_; -class VideoReceiveConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _VideoReceiveConfig_default_instance_; -class DecoderConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _DecoderConfig_default_instance_; -class RtpHeaderExtensionDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _RtpHeaderExtension_default_instance_; -class RtxConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _RtxConfig_default_instance_; -class RtxMapDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _RtxMap_default_instance_; -class VideoSendConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _VideoSendConfig_default_instance_; -class EncoderConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _EncoderConfig_default_instance_; -class AudioReceiveConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AudioReceiveConfig_default_instance_; -class AudioSendConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AudioSendConfig_default_instance_; -class AudioNetworkAdaptationDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AudioNetworkAdaptation_default_instance_; -class BweProbeClusterDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _BweProbeCluster_default_instance_; -class BweProbeResultDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _BweProbeResult_default_instance_; -class AlrStateDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AlrState_default_instance_; -class IceCandidatePairConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _IceCandidatePairConfig_default_instance_; -class IceCandidatePairEventDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _IceCandidatePairEvent_default_instance_; -} // namespace rtclog -} // namespace webrtc -static void InitDefaultsscc_info_AlrState_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_AlrState_default_instance_; - new (ptr) ::webrtc::rtclog::AlrState(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::AlrState::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AlrState_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_AlrState_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_AudioNetworkAdaptation_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_AudioNetworkAdaptation_default_instance_; - new (ptr) ::webrtc::rtclog::AudioNetworkAdaptation(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::AudioNetworkAdaptation::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AudioNetworkAdaptation_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_AudioNetworkAdaptation_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_AudioPlayoutEvent_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_AudioPlayoutEvent_default_instance_; - new (ptr) ::webrtc::rtclog::AudioPlayoutEvent(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::AudioPlayoutEvent::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AudioPlayoutEvent_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_AudioPlayoutEvent_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_AudioReceiveConfig_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_AudioReceiveConfig_default_instance_; - new (ptr) ::webrtc::rtclog::AudioReceiveConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::AudioReceiveConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_AudioReceiveConfig_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsscc_info_AudioReceiveConfig_rtc_5fevent_5flog_2eproto}, { - &scc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto.base,}}; - -static void InitDefaultsscc_info_AudioSendConfig_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_AudioSendConfig_default_instance_; - new (ptr) ::webrtc::rtclog::AudioSendConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::AudioSendConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_AudioSendConfig_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsscc_info_AudioSendConfig_rtc_5fevent_5flog_2eproto}, { - &scc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto.base,}}; - -static void InitDefaultsscc_info_BweProbeCluster_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_BweProbeCluster_default_instance_; - new (ptr) ::webrtc::rtclog::BweProbeCluster(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::BweProbeCluster::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeCluster_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_BweProbeCluster_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_BweProbeResult_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_BweProbeResult_default_instance_; - new (ptr) ::webrtc::rtclog::BweProbeResult(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::BweProbeResult::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeResult_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_BweProbeResult_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_DecoderConfig_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_DecoderConfig_default_instance_; - new (ptr) ::webrtc::rtclog::DecoderConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::DecoderConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DecoderConfig_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_DecoderConfig_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_DelayBasedBweUpdate_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_DelayBasedBweUpdate_default_instance_; - new (ptr) ::webrtc::rtclog::DelayBasedBweUpdate(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::DelayBasedBweUpdate::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DelayBasedBweUpdate_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_DelayBasedBweUpdate_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_EncoderConfig_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_EncoderConfig_default_instance_; - new (ptr) ::webrtc::rtclog::EncoderConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::EncoderConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_EncoderConfig_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_EncoderConfig_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_Event_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_Event_default_instance_; - new (ptr) ::webrtc::rtclog::Event(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::Event::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<15> scc_info_Event_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 15, InitDefaultsscc_info_Event_rtc_5fevent_5flog_2eproto}, { - &scc_info_RtpPacket_rtc_5fevent_5flog_2eproto.base, - &scc_info_RtcpPacket_rtc_5fevent_5flog_2eproto.base, - &scc_info_AudioPlayoutEvent_rtc_5fevent_5flog_2eproto.base, - &scc_info_LossBasedBweUpdate_rtc_5fevent_5flog_2eproto.base, - &scc_info_DelayBasedBweUpdate_rtc_5fevent_5flog_2eproto.base, - &scc_info_VideoReceiveConfig_rtc_5fevent_5flog_2eproto.base, - &scc_info_VideoSendConfig_rtc_5fevent_5flog_2eproto.base, - &scc_info_AudioReceiveConfig_rtc_5fevent_5flog_2eproto.base, - &scc_info_AudioSendConfig_rtc_5fevent_5flog_2eproto.base, - &scc_info_AudioNetworkAdaptation_rtc_5fevent_5flog_2eproto.base, - &scc_info_BweProbeCluster_rtc_5fevent_5flog_2eproto.base, - &scc_info_BweProbeResult_rtc_5fevent_5flog_2eproto.base, - &scc_info_AlrState_rtc_5fevent_5flog_2eproto.base, - &scc_info_IceCandidatePairConfig_rtc_5fevent_5flog_2eproto.base, - &scc_info_IceCandidatePairEvent_rtc_5fevent_5flog_2eproto.base,}}; - -static void InitDefaultsscc_info_EventStream_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_EventStream_default_instance_; - new (ptr) ::webrtc::rtclog::EventStream(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::EventStream::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EventStream_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsscc_info_EventStream_rtc_5fevent_5flog_2eproto}, { - &scc_info_Event_rtc_5fevent_5flog_2eproto.base,}}; - -static void InitDefaultsscc_info_IceCandidatePairConfig_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_IceCandidatePairConfig_default_instance_; - new (ptr) ::webrtc::rtclog::IceCandidatePairConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::IceCandidatePairConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IceCandidatePairConfig_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_IceCandidatePairConfig_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_IceCandidatePairEvent_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_IceCandidatePairEvent_default_instance_; - new (ptr) ::webrtc::rtclog::IceCandidatePairEvent(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::IceCandidatePairEvent::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IceCandidatePairEvent_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_IceCandidatePairEvent_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_LossBasedBweUpdate_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_LossBasedBweUpdate_default_instance_; - new (ptr) ::webrtc::rtclog::LossBasedBweUpdate(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::LossBasedBweUpdate::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_LossBasedBweUpdate_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_LossBasedBweUpdate_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_RtcpPacket_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_RtcpPacket_default_instance_; - new (ptr) ::webrtc::rtclog::RtcpPacket(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::RtcpPacket::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtcpPacket_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_RtcpPacket_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_RtpHeaderExtension_default_instance_; - new (ptr) ::webrtc::rtclog::RtpHeaderExtension(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::RtpHeaderExtension::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_RtpPacket_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_RtpPacket_default_instance_; - new (ptr) ::webrtc::rtclog::RtpPacket(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::RtpPacket::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtpPacket_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_RtpPacket_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_RtxConfig_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_RtxConfig_default_instance_; - new (ptr) ::webrtc::rtclog::RtxConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::RtxConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtxConfig_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_RtxConfig_rtc_5fevent_5flog_2eproto}, {}}; - -static void InitDefaultsscc_info_RtxMap_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_RtxMap_default_instance_; - new (ptr) ::webrtc::rtclog::RtxMap(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::RtxMap::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_RtxMap_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsscc_info_RtxMap_rtc_5fevent_5flog_2eproto}, { - &scc_info_RtxConfig_rtc_5fevent_5flog_2eproto.base,}}; - -static void InitDefaultsscc_info_VideoReceiveConfig_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_VideoReceiveConfig_default_instance_; - new (ptr) ::webrtc::rtclog::VideoReceiveConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::VideoReceiveConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_VideoReceiveConfig_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsscc_info_VideoReceiveConfig_rtc_5fevent_5flog_2eproto}, { - &scc_info_RtxMap_rtc_5fevent_5flog_2eproto.base, - &scc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto.base, - &scc_info_DecoderConfig_rtc_5fevent_5flog_2eproto.base,}}; - -static void InitDefaultsscc_info_VideoSendConfig_rtc_5fevent_5flog_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog::_VideoSendConfig_default_instance_; - new (ptr) ::webrtc::rtclog::VideoSendConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog::VideoSendConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_VideoSendConfig_rtc_5fevent_5flog_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsscc_info_VideoSendConfig_rtc_5fevent_5flog_2eproto}, { - &scc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto.base, - &scc_info_EncoderConfig_rtc_5fevent_5flog_2eproto.base,}}; - -namespace webrtc { -namespace rtclog { -bool Event_EventType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed Event_EventType_strings[18] = {}; - -static const char Event_EventType_names[] = - "ALR_STATE_EVENT" - "AUDIO_NETWORK_ADAPTATION_EVENT" - "AUDIO_PLAYOUT_EVENT" - "AUDIO_RECEIVER_CONFIG_EVENT" - "AUDIO_SENDER_CONFIG_EVENT" - "BWE_PROBE_CLUSTER_CREATED_EVENT" - "BWE_PROBE_RESULT_EVENT" - "DELAY_BASED_BWE_UPDATE" - "ICE_CANDIDATE_PAIR_CONFIG" - "ICE_CANDIDATE_PAIR_EVENT" - "LOG_END" - "LOG_START" - "LOSS_BASED_BWE_UPDATE" - "RTCP_EVENT" - "RTP_EVENT" - "UNKNOWN_EVENT" - "VIDEO_RECEIVER_CONFIG_EVENT" - "VIDEO_SENDER_CONFIG_EVENT"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry Event_EventType_entries[] = { - { {Event_EventType_names + 0, 15}, 19 }, - { {Event_EventType_names + 15, 30}, 16 }, - { {Event_EventType_names + 45, 19}, 5 }, - { {Event_EventType_names + 64, 27}, 10 }, - { {Event_EventType_names + 91, 25}, 11 }, - { {Event_EventType_names + 116, 31}, 17 }, - { {Event_EventType_names + 147, 22}, 18 }, - { {Event_EventType_names + 169, 22}, 7 }, - { {Event_EventType_names + 191, 25}, 20 }, - { {Event_EventType_names + 216, 24}, 21 }, - { {Event_EventType_names + 240, 7}, 2 }, - { {Event_EventType_names + 247, 9}, 1 }, - { {Event_EventType_names + 256, 21}, 6 }, - { {Event_EventType_names + 277, 10}, 4 }, - { {Event_EventType_names + 287, 9}, 3 }, - { {Event_EventType_names + 296, 13}, 0 }, - { {Event_EventType_names + 309, 27}, 8 }, - { {Event_EventType_names + 336, 25}, 9 }, -}; - -static const int Event_EventType_entries_by_number[] = { - 15, // 0 -> UNKNOWN_EVENT - 11, // 1 -> LOG_START - 10, // 2 -> LOG_END - 14, // 3 -> RTP_EVENT - 13, // 4 -> RTCP_EVENT - 2, // 5 -> AUDIO_PLAYOUT_EVENT - 12, // 6 -> LOSS_BASED_BWE_UPDATE - 7, // 7 -> DELAY_BASED_BWE_UPDATE - 16, // 8 -> VIDEO_RECEIVER_CONFIG_EVENT - 17, // 9 -> VIDEO_SENDER_CONFIG_EVENT - 3, // 10 -> AUDIO_RECEIVER_CONFIG_EVENT - 4, // 11 -> AUDIO_SENDER_CONFIG_EVENT - 1, // 16 -> AUDIO_NETWORK_ADAPTATION_EVENT - 5, // 17 -> BWE_PROBE_CLUSTER_CREATED_EVENT - 6, // 18 -> BWE_PROBE_RESULT_EVENT - 0, // 19 -> ALR_STATE_EVENT - 8, // 20 -> ICE_CANDIDATE_PAIR_CONFIG - 9, // 21 -> ICE_CANDIDATE_PAIR_EVENT -}; - -const std::string& Event_EventType_Name( - Event_EventType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - Event_EventType_entries, - Event_EventType_entries_by_number, - 18, Event_EventType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - Event_EventType_entries, - Event_EventType_entries_by_number, - 18, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - Event_EventType_strings[idx].get(); -} -bool Event_EventType_Parse( - const std::string& name, Event_EventType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - Event_EventType_entries, 18, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr Event_EventType Event::UNKNOWN_EVENT; -constexpr Event_EventType Event::LOG_START; -constexpr Event_EventType Event::LOG_END; -constexpr Event_EventType Event::RTP_EVENT; -constexpr Event_EventType Event::RTCP_EVENT; -constexpr Event_EventType Event::AUDIO_PLAYOUT_EVENT; -constexpr Event_EventType Event::LOSS_BASED_BWE_UPDATE; -constexpr Event_EventType Event::DELAY_BASED_BWE_UPDATE; -constexpr Event_EventType Event::VIDEO_RECEIVER_CONFIG_EVENT; -constexpr Event_EventType Event::VIDEO_SENDER_CONFIG_EVENT; -constexpr Event_EventType Event::AUDIO_RECEIVER_CONFIG_EVENT; -constexpr Event_EventType Event::AUDIO_SENDER_CONFIG_EVENT; -constexpr Event_EventType Event::AUDIO_NETWORK_ADAPTATION_EVENT; -constexpr Event_EventType Event::BWE_PROBE_CLUSTER_CREATED_EVENT; -constexpr Event_EventType Event::BWE_PROBE_RESULT_EVENT; -constexpr Event_EventType Event::ALR_STATE_EVENT; -constexpr Event_EventType Event::ICE_CANDIDATE_PAIR_CONFIG; -constexpr Event_EventType Event::ICE_CANDIDATE_PAIR_EVENT; -constexpr Event_EventType Event::EventType_MIN; -constexpr Event_EventType Event::EventType_MAX; -constexpr int Event::EventType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool DelayBasedBweUpdate_DetectorState_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DelayBasedBweUpdate_DetectorState_strings[3] = {}; - -static const char DelayBasedBweUpdate_DetectorState_names[] = - "BWE_NORMAL" - "BWE_OVERUSING" - "BWE_UNDERUSING"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry DelayBasedBweUpdate_DetectorState_entries[] = { - { {DelayBasedBweUpdate_DetectorState_names + 0, 10}, 0 }, - { {DelayBasedBweUpdate_DetectorState_names + 10, 13}, 2 }, - { {DelayBasedBweUpdate_DetectorState_names + 23, 14}, 1 }, -}; - -static const int DelayBasedBweUpdate_DetectorState_entries_by_number[] = { - 0, // 0 -> BWE_NORMAL - 2, // 1 -> BWE_UNDERUSING - 1, // 2 -> BWE_OVERUSING -}; - -const std::string& DelayBasedBweUpdate_DetectorState_Name( - DelayBasedBweUpdate_DetectorState value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - DelayBasedBweUpdate_DetectorState_entries, - DelayBasedBweUpdate_DetectorState_entries_by_number, - 3, DelayBasedBweUpdate_DetectorState_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - DelayBasedBweUpdate_DetectorState_entries, - DelayBasedBweUpdate_DetectorState_entries_by_number, - 3, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - DelayBasedBweUpdate_DetectorState_strings[idx].get(); -} -bool DelayBasedBweUpdate_DetectorState_Parse( - const std::string& name, DelayBasedBweUpdate_DetectorState* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - DelayBasedBweUpdate_DetectorState_entries, 3, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr DelayBasedBweUpdate_DetectorState DelayBasedBweUpdate::BWE_NORMAL; -constexpr DelayBasedBweUpdate_DetectorState DelayBasedBweUpdate::BWE_UNDERUSING; -constexpr DelayBasedBweUpdate_DetectorState DelayBasedBweUpdate::BWE_OVERUSING; -constexpr DelayBasedBweUpdate_DetectorState DelayBasedBweUpdate::DetectorState_MIN; -constexpr DelayBasedBweUpdate_DetectorState DelayBasedBweUpdate::DetectorState_MAX; -constexpr int DelayBasedBweUpdate::DetectorState_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool VideoReceiveConfig_RtcpMode_IsValid(int value) { - switch (value) { - case 1: - case 2: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed VideoReceiveConfig_RtcpMode_strings[2] = {}; - -static const char VideoReceiveConfig_RtcpMode_names[] = - "RTCP_COMPOUND" - "RTCP_REDUCEDSIZE"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry VideoReceiveConfig_RtcpMode_entries[] = { - { {VideoReceiveConfig_RtcpMode_names + 0, 13}, 1 }, - { {VideoReceiveConfig_RtcpMode_names + 13, 16}, 2 }, -}; - -static const int VideoReceiveConfig_RtcpMode_entries_by_number[] = { - 0, // 1 -> RTCP_COMPOUND - 1, // 2 -> RTCP_REDUCEDSIZE -}; - -const std::string& VideoReceiveConfig_RtcpMode_Name( - VideoReceiveConfig_RtcpMode value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - VideoReceiveConfig_RtcpMode_entries, - VideoReceiveConfig_RtcpMode_entries_by_number, - 2, VideoReceiveConfig_RtcpMode_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - VideoReceiveConfig_RtcpMode_entries, - VideoReceiveConfig_RtcpMode_entries_by_number, - 2, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - VideoReceiveConfig_RtcpMode_strings[idx].get(); -} -bool VideoReceiveConfig_RtcpMode_Parse( - const std::string& name, VideoReceiveConfig_RtcpMode* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - VideoReceiveConfig_RtcpMode_entries, 2, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr VideoReceiveConfig_RtcpMode VideoReceiveConfig::RTCP_COMPOUND; -constexpr VideoReceiveConfig_RtcpMode VideoReceiveConfig::RTCP_REDUCEDSIZE; -constexpr VideoReceiveConfig_RtcpMode VideoReceiveConfig::RtcpMode_MIN; -constexpr VideoReceiveConfig_RtcpMode VideoReceiveConfig::RtcpMode_MAX; -constexpr int VideoReceiveConfig::RtcpMode_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool BweProbeResult_ResultType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed BweProbeResult_ResultType_strings[4] = {}; - -static const char BweProbeResult_ResultType_names[] = - "INVALID_SEND_RECEIVE_INTERVAL" - "INVALID_SEND_RECEIVE_RATIO" - "SUCCESS" - "TIMEOUT"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry BweProbeResult_ResultType_entries[] = { - { {BweProbeResult_ResultType_names + 0, 29}, 1 }, - { {BweProbeResult_ResultType_names + 29, 26}, 2 }, - { {BweProbeResult_ResultType_names + 55, 7}, 0 }, - { {BweProbeResult_ResultType_names + 62, 7}, 3 }, -}; - -static const int BweProbeResult_ResultType_entries_by_number[] = { - 2, // 0 -> SUCCESS - 0, // 1 -> INVALID_SEND_RECEIVE_INTERVAL - 1, // 2 -> INVALID_SEND_RECEIVE_RATIO - 3, // 3 -> TIMEOUT -}; - -const std::string& BweProbeResult_ResultType_Name( - BweProbeResult_ResultType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - BweProbeResult_ResultType_entries, - BweProbeResult_ResultType_entries_by_number, - 4, BweProbeResult_ResultType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - BweProbeResult_ResultType_entries, - BweProbeResult_ResultType_entries_by_number, - 4, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - BweProbeResult_ResultType_strings[idx].get(); -} -bool BweProbeResult_ResultType_Parse( - const std::string& name, BweProbeResult_ResultType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - BweProbeResult_ResultType_entries, 4, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr BweProbeResult_ResultType BweProbeResult::SUCCESS; -constexpr BweProbeResult_ResultType BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL; -constexpr BweProbeResult_ResultType BweProbeResult::INVALID_SEND_RECEIVE_RATIO; -constexpr BweProbeResult_ResultType BweProbeResult::TIMEOUT; -constexpr BweProbeResult_ResultType BweProbeResult::ResultType_MIN; -constexpr BweProbeResult_ResultType BweProbeResult::ResultType_MAX; -constexpr int BweProbeResult::ResultType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_IceCandidatePairConfigType_strings[4] = {}; - -static const char IceCandidatePairConfig_IceCandidatePairConfigType_names[] = - "ADDED" - "DESTROYED" - "SELECTED" - "UPDATED"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_IceCandidatePairConfigType_entries[] = { - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 0, 5}, 0 }, - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 5, 9}, 2 }, - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 14, 8}, 3 }, - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 22, 7}, 1 }, -}; - -static const int IceCandidatePairConfig_IceCandidatePairConfigType_entries_by_number[] = { - 0, // 0 -> ADDED - 3, // 1 -> UPDATED - 1, // 2 -> DESTROYED - 2, // 3 -> SELECTED -}; - -const std::string& IceCandidatePairConfig_IceCandidatePairConfigType_Name( - IceCandidatePairConfig_IceCandidatePairConfigType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_IceCandidatePairConfigType_entries, - IceCandidatePairConfig_IceCandidatePairConfigType_entries_by_number, - 4, IceCandidatePairConfig_IceCandidatePairConfigType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_IceCandidatePairConfigType_entries, - IceCandidatePairConfig_IceCandidatePairConfigType_entries_by_number, - 4, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_IceCandidatePairConfigType_strings[idx].get(); -} -bool IceCandidatePairConfig_IceCandidatePairConfigType_Parse( - const std::string& name, IceCandidatePairConfig_IceCandidatePairConfigType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_IceCandidatePairConfigType_entries, 4, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::ADDED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::UPDATED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::DESTROYED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::SELECTED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::IceCandidatePairConfigType_MIN; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::IceCandidatePairConfigType_MAX; -constexpr int IceCandidatePairConfig::IceCandidatePairConfigType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_IceCandidateType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_IceCandidateType_strings[5] = {}; - -static const char IceCandidatePairConfig_IceCandidateType_names[] = - "LOCAL" - "PRFLX" - "RELAY" - "STUN" - "UNKNOWN_CANDIDATE_TYPE"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_IceCandidateType_entries[] = { - { {IceCandidatePairConfig_IceCandidateType_names + 0, 5}, 0 }, - { {IceCandidatePairConfig_IceCandidateType_names + 5, 5}, 2 }, - { {IceCandidatePairConfig_IceCandidateType_names + 10, 5}, 3 }, - { {IceCandidatePairConfig_IceCandidateType_names + 15, 4}, 1 }, - { {IceCandidatePairConfig_IceCandidateType_names + 19, 22}, 4 }, -}; - -static const int IceCandidatePairConfig_IceCandidateType_entries_by_number[] = { - 0, // 0 -> LOCAL - 3, // 1 -> STUN - 1, // 2 -> PRFLX - 2, // 3 -> RELAY - 4, // 4 -> UNKNOWN_CANDIDATE_TYPE -}; - -const std::string& IceCandidatePairConfig_IceCandidateType_Name( - IceCandidatePairConfig_IceCandidateType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_IceCandidateType_entries, - IceCandidatePairConfig_IceCandidateType_entries_by_number, - 5, IceCandidatePairConfig_IceCandidateType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_IceCandidateType_entries, - IceCandidatePairConfig_IceCandidateType_entries_by_number, - 5, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_IceCandidateType_strings[idx].get(); -} -bool IceCandidatePairConfig_IceCandidateType_Parse( - const std::string& name, IceCandidatePairConfig_IceCandidateType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_IceCandidateType_entries, 5, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::LOCAL; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::STUN; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::PRFLX; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::RELAY; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::IceCandidateType_MIN; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::IceCandidateType_MAX; -constexpr int IceCandidatePairConfig::IceCandidateType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_Protocol_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_Protocol_strings[5] = {}; - -static const char IceCandidatePairConfig_Protocol_names[] = - "SSLTCP" - "TCP" - "TLS" - "UDP" - "UNKNOWN_PROTOCOL"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_Protocol_entries[] = { - { {IceCandidatePairConfig_Protocol_names + 0, 6}, 2 }, - { {IceCandidatePairConfig_Protocol_names + 6, 3}, 1 }, - { {IceCandidatePairConfig_Protocol_names + 9, 3}, 3 }, - { {IceCandidatePairConfig_Protocol_names + 12, 3}, 0 }, - { {IceCandidatePairConfig_Protocol_names + 15, 16}, 4 }, -}; - -static const int IceCandidatePairConfig_Protocol_entries_by_number[] = { - 3, // 0 -> UDP - 1, // 1 -> TCP - 0, // 2 -> SSLTCP - 2, // 3 -> TLS - 4, // 4 -> UNKNOWN_PROTOCOL -}; - -const std::string& IceCandidatePairConfig_Protocol_Name( - IceCandidatePairConfig_Protocol value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_Protocol_entries, - IceCandidatePairConfig_Protocol_entries_by_number, - 5, IceCandidatePairConfig_Protocol_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_Protocol_entries, - IceCandidatePairConfig_Protocol_entries_by_number, - 5, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_Protocol_strings[idx].get(); -} -bool IceCandidatePairConfig_Protocol_Parse( - const std::string& name, IceCandidatePairConfig_Protocol* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_Protocol_entries, 5, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::UDP; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::TCP; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::SSLTCP; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::TLS; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::UNKNOWN_PROTOCOL; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::Protocol_MIN; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::Protocol_MAX; -constexpr int IceCandidatePairConfig::Protocol_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_AddressFamily_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_AddressFamily_strings[3] = {}; - -static const char IceCandidatePairConfig_AddressFamily_names[] = - "IPV4" - "IPV6" - "UNKNOWN_ADDRESS_FAMILY"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_AddressFamily_entries[] = { - { {IceCandidatePairConfig_AddressFamily_names + 0, 4}, 0 }, - { {IceCandidatePairConfig_AddressFamily_names + 4, 4}, 1 }, - { {IceCandidatePairConfig_AddressFamily_names + 8, 22}, 2 }, -}; - -static const int IceCandidatePairConfig_AddressFamily_entries_by_number[] = { - 0, // 0 -> IPV4 - 1, // 1 -> IPV6 - 2, // 2 -> UNKNOWN_ADDRESS_FAMILY -}; - -const std::string& IceCandidatePairConfig_AddressFamily_Name( - IceCandidatePairConfig_AddressFamily value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_AddressFamily_entries, - IceCandidatePairConfig_AddressFamily_entries_by_number, - 3, IceCandidatePairConfig_AddressFamily_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_AddressFamily_entries, - IceCandidatePairConfig_AddressFamily_entries_by_number, - 3, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_AddressFamily_strings[idx].get(); -} -bool IceCandidatePairConfig_AddressFamily_Parse( - const std::string& name, IceCandidatePairConfig_AddressFamily* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_AddressFamily_entries, 3, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::IPV4; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::IPV6; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::AddressFamily_MIN; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::AddressFamily_MAX; -constexpr int IceCandidatePairConfig::AddressFamily_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_NetworkType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_NetworkType_strings[6] = {}; - -static const char IceCandidatePairConfig_NetworkType_names[] = - "CELLULAR" - "ETHERNET" - "LOOPBACK" - "UNKNOWN_NETWORK_TYPE" - "VPN" - "WIFI"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_NetworkType_entries[] = { - { {IceCandidatePairConfig_NetworkType_names + 0, 8}, 4 }, - { {IceCandidatePairConfig_NetworkType_names + 8, 8}, 0 }, - { {IceCandidatePairConfig_NetworkType_names + 16, 8}, 1 }, - { {IceCandidatePairConfig_NetworkType_names + 24, 20}, 5 }, - { {IceCandidatePairConfig_NetworkType_names + 44, 3}, 3 }, - { {IceCandidatePairConfig_NetworkType_names + 47, 4}, 2 }, -}; - -static const int IceCandidatePairConfig_NetworkType_entries_by_number[] = { - 1, // 0 -> ETHERNET - 2, // 1 -> LOOPBACK - 5, // 2 -> WIFI - 4, // 3 -> VPN - 0, // 4 -> CELLULAR - 3, // 5 -> UNKNOWN_NETWORK_TYPE -}; - -const std::string& IceCandidatePairConfig_NetworkType_Name( - IceCandidatePairConfig_NetworkType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_NetworkType_entries, - IceCandidatePairConfig_NetworkType_entries_by_number, - 6, IceCandidatePairConfig_NetworkType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_NetworkType_entries, - IceCandidatePairConfig_NetworkType_entries_by_number, - 6, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_NetworkType_strings[idx].get(); -} -bool IceCandidatePairConfig_NetworkType_Parse( - const std::string& name, IceCandidatePairConfig_NetworkType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_NetworkType_entries, 6, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::ETHERNET; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::LOOPBACK; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::WIFI; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::VPN; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::CELLULAR; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::NetworkType_MIN; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::NetworkType_MAX; -constexpr int IceCandidatePairConfig::NetworkType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairEvent_IceCandidatePairEventType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairEvent_IceCandidatePairEventType_strings[4] = {}; - -static const char IceCandidatePairEvent_IceCandidatePairEventType_names[] = - "CHECK_RECEIVED" - "CHECK_RESPONSE_RECEIVED" - "CHECK_RESPONSE_SENT" - "CHECK_SENT"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairEvent_IceCandidatePairEventType_entries[] = { - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 0, 14}, 1 }, - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 14, 23}, 3 }, - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 37, 19}, 2 }, - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 56, 10}, 0 }, -}; - -static const int IceCandidatePairEvent_IceCandidatePairEventType_entries_by_number[] = { - 3, // 0 -> CHECK_SENT - 0, // 1 -> CHECK_RECEIVED - 2, // 2 -> CHECK_RESPONSE_SENT - 1, // 3 -> CHECK_RESPONSE_RECEIVED -}; - -const std::string& IceCandidatePairEvent_IceCandidatePairEventType_Name( - IceCandidatePairEvent_IceCandidatePairEventType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairEvent_IceCandidatePairEventType_entries, - IceCandidatePairEvent_IceCandidatePairEventType_entries_by_number, - 4, IceCandidatePairEvent_IceCandidatePairEventType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairEvent_IceCandidatePairEventType_entries, - IceCandidatePairEvent_IceCandidatePairEventType_entries_by_number, - 4, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairEvent_IceCandidatePairEventType_strings[idx].get(); -} -bool IceCandidatePairEvent_IceCandidatePairEventType_Parse( - const std::string& name, IceCandidatePairEvent_IceCandidatePairEventType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairEvent_IceCandidatePairEventType_entries, 4, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::CHECK_SENT; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::CHECK_RECEIVED; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::CHECK_RESPONSE_SENT; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::IceCandidatePairEventType_MIN; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::IceCandidatePairEventType_MAX; -constexpr int IceCandidatePairEvent::IceCandidatePairEventType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool MediaType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed MediaType_strings[4] = {}; - -static const char MediaType_names[] = - "ANY" - "AUDIO" - "DATA" - "VIDEO"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry MediaType_entries[] = { - { {MediaType_names + 0, 3}, 0 }, - { {MediaType_names + 3, 5}, 1 }, - { {MediaType_names + 8, 4}, 3 }, - { {MediaType_names + 12, 5}, 2 }, -}; - -static const int MediaType_entries_by_number[] = { - 0, // 0 -> ANY - 1, // 1 -> AUDIO - 3, // 2 -> VIDEO - 2, // 3 -> DATA -}; - -const std::string& MediaType_Name( - MediaType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - MediaType_entries, - MediaType_entries_by_number, - 4, MediaType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - MediaType_entries, - MediaType_entries_by_number, - 4, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - MediaType_strings[idx].get(); -} -bool MediaType_Parse( - const std::string& name, MediaType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - MediaType_entries, 4, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} - -// =================================================================== - -void EventStream::InitAsDefaultInstance() { -} -class EventStream::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); -}; - -EventStream::EventStream() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.EventStream) -} -EventStream::EventStream(const EventStream& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), - stream_(from.stream_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.EventStream) -} - -void EventStream::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_EventStream_rtc_5fevent_5flog_2eproto.base); -} - -EventStream::~EventStream() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.EventStream) - SharedDtor(); -} - -void EventStream::SharedDtor() { -} - -void EventStream::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const EventStream& EventStream::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_EventStream_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void EventStream::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.EventStream) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - stream_.Clear(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* EventStream::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // repeated .webrtc.rtclog.Event stream = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_stream(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 10); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool EventStream::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.EventStream) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .webrtc.rtclog.Event stream = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (10 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_stream())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.EventStream) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.EventStream) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void EventStream::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.EventStream) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // repeated .webrtc.rtclog.Event stream = 1; - for (unsigned int i = 0, - n = static_cast(this->stream_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 1, - this->stream(static_cast(i)), - output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.EventStream) -} - -size_t EventStream::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.EventStream) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // repeated .webrtc.rtclog.Event stream = 1; - { - unsigned int count = static_cast(this->stream_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->stream(static_cast(i))); - } - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void EventStream::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void EventStream::MergeFrom(const EventStream& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.EventStream) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - stream_.MergeFrom(from.stream_); -} - -void EventStream::CopyFrom(const EventStream& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.EventStream) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EventStream::IsInitialized() const { - return true; -} - -void EventStream::InternalSwap(EventStream* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - CastToBase(&stream_)->InternalSwap(CastToBase(&other->stream_)); -} - -std::string EventStream::GetTypeName() const { - return "webrtc.rtclog.EventStream"; -} - - -// =================================================================== - -void Event::InitAsDefaultInstance() { -} -class Event::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_us(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static const ::webrtc::rtclog::RtpPacket& rtp_packet(const Event* msg); - static const ::webrtc::rtclog::RtcpPacket& rtcp_packet(const Event* msg); - static const ::webrtc::rtclog::AudioPlayoutEvent& audio_playout_event(const Event* msg); - static const ::webrtc::rtclog::LossBasedBweUpdate& loss_based_bwe_update(const Event* msg); - static const ::webrtc::rtclog::DelayBasedBweUpdate& delay_based_bwe_update(const Event* msg); - static const ::webrtc::rtclog::VideoReceiveConfig& video_receiver_config(const Event* msg); - static const ::webrtc::rtclog::VideoSendConfig& video_sender_config(const Event* msg); - static const ::webrtc::rtclog::AudioReceiveConfig& audio_receiver_config(const Event* msg); - static const ::webrtc::rtclog::AudioSendConfig& audio_sender_config(const Event* msg); - static const ::webrtc::rtclog::AudioNetworkAdaptation& audio_network_adaptation(const Event* msg); - static const ::webrtc::rtclog::BweProbeCluster& probe_cluster(const Event* msg); - static const ::webrtc::rtclog::BweProbeResult& probe_result(const Event* msg); - static const ::webrtc::rtclog::AlrState& alr_state(const Event* msg); - static const ::webrtc::rtclog::IceCandidatePairConfig& ice_candidate_pair_config(const Event* msg); - static const ::webrtc::rtclog::IceCandidatePairEvent& ice_candidate_pair_event(const Event* msg); -}; - -const ::webrtc::rtclog::RtpPacket& -Event::_Internal::rtp_packet(const Event* msg) { - return *msg->subtype_.rtp_packet_; -} -const ::webrtc::rtclog::RtcpPacket& -Event::_Internal::rtcp_packet(const Event* msg) { - return *msg->subtype_.rtcp_packet_; -} -const ::webrtc::rtclog::AudioPlayoutEvent& -Event::_Internal::audio_playout_event(const Event* msg) { - return *msg->subtype_.audio_playout_event_; -} -const ::webrtc::rtclog::LossBasedBweUpdate& -Event::_Internal::loss_based_bwe_update(const Event* msg) { - return *msg->subtype_.loss_based_bwe_update_; -} -const ::webrtc::rtclog::DelayBasedBweUpdate& -Event::_Internal::delay_based_bwe_update(const Event* msg) { - return *msg->subtype_.delay_based_bwe_update_; -} -const ::webrtc::rtclog::VideoReceiveConfig& -Event::_Internal::video_receiver_config(const Event* msg) { - return *msg->subtype_.video_receiver_config_; -} -const ::webrtc::rtclog::VideoSendConfig& -Event::_Internal::video_sender_config(const Event* msg) { - return *msg->subtype_.video_sender_config_; -} -const ::webrtc::rtclog::AudioReceiveConfig& -Event::_Internal::audio_receiver_config(const Event* msg) { - return *msg->subtype_.audio_receiver_config_; -} -const ::webrtc::rtclog::AudioSendConfig& -Event::_Internal::audio_sender_config(const Event* msg) { - return *msg->subtype_.audio_sender_config_; -} -const ::webrtc::rtclog::AudioNetworkAdaptation& -Event::_Internal::audio_network_adaptation(const Event* msg) { - return *msg->subtype_.audio_network_adaptation_; -} -const ::webrtc::rtclog::BweProbeCluster& -Event::_Internal::probe_cluster(const Event* msg) { - return *msg->subtype_.probe_cluster_; -} -const ::webrtc::rtclog::BweProbeResult& -Event::_Internal::probe_result(const Event* msg) { - return *msg->subtype_.probe_result_; -} -const ::webrtc::rtclog::AlrState& -Event::_Internal::alr_state(const Event* msg) { - return *msg->subtype_.alr_state_; -} -const ::webrtc::rtclog::IceCandidatePairConfig& -Event::_Internal::ice_candidate_pair_config(const Event* msg) { - return *msg->subtype_.ice_candidate_pair_config_; -} -const ::webrtc::rtclog::IceCandidatePairEvent& -Event::_Internal::ice_candidate_pair_event(const Event* msg) { - return *msg->subtype_.ice_candidate_pair_event_; -} -void Event::set_allocated_rtp_packet(::webrtc::rtclog::RtpPacket* rtp_packet) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (rtp_packet) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - rtp_packet = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, rtp_packet, submessage_arena); - } - set_has_rtp_packet(); - subtype_.rtp_packet_ = rtp_packet; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.rtp_packet) -} -void Event::set_allocated_rtcp_packet(::webrtc::rtclog::RtcpPacket* rtcp_packet) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (rtcp_packet) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - rtcp_packet = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, rtcp_packet, submessage_arena); - } - set_has_rtcp_packet(); - subtype_.rtcp_packet_ = rtcp_packet; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.rtcp_packet) -} -void Event::set_allocated_audio_playout_event(::webrtc::rtclog::AudioPlayoutEvent* audio_playout_event) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (audio_playout_event) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - audio_playout_event = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, audio_playout_event, submessage_arena); - } - set_has_audio_playout_event(); - subtype_.audio_playout_event_ = audio_playout_event; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.audio_playout_event) -} -void Event::set_allocated_loss_based_bwe_update(::webrtc::rtclog::LossBasedBweUpdate* loss_based_bwe_update) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (loss_based_bwe_update) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - loss_based_bwe_update = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, loss_based_bwe_update, submessage_arena); - } - set_has_loss_based_bwe_update(); - subtype_.loss_based_bwe_update_ = loss_based_bwe_update; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.loss_based_bwe_update) -} -void Event::set_allocated_delay_based_bwe_update(::webrtc::rtclog::DelayBasedBweUpdate* delay_based_bwe_update) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (delay_based_bwe_update) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - delay_based_bwe_update = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, delay_based_bwe_update, submessage_arena); - } - set_has_delay_based_bwe_update(); - subtype_.delay_based_bwe_update_ = delay_based_bwe_update; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.delay_based_bwe_update) -} -void Event::set_allocated_video_receiver_config(::webrtc::rtclog::VideoReceiveConfig* video_receiver_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (video_receiver_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - video_receiver_config = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, video_receiver_config, submessage_arena); - } - set_has_video_receiver_config(); - subtype_.video_receiver_config_ = video_receiver_config; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.video_receiver_config) -} -void Event::set_allocated_video_sender_config(::webrtc::rtclog::VideoSendConfig* video_sender_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (video_sender_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - video_sender_config = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, video_sender_config, submessage_arena); - } - set_has_video_sender_config(); - subtype_.video_sender_config_ = video_sender_config; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.video_sender_config) -} -void Event::set_allocated_audio_receiver_config(::webrtc::rtclog::AudioReceiveConfig* audio_receiver_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (audio_receiver_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - audio_receiver_config = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, audio_receiver_config, submessage_arena); - } - set_has_audio_receiver_config(); - subtype_.audio_receiver_config_ = audio_receiver_config; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.audio_receiver_config) -} -void Event::set_allocated_audio_sender_config(::webrtc::rtclog::AudioSendConfig* audio_sender_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (audio_sender_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - audio_sender_config = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, audio_sender_config, submessage_arena); - } - set_has_audio_sender_config(); - subtype_.audio_sender_config_ = audio_sender_config; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.audio_sender_config) -} -void Event::set_allocated_audio_network_adaptation(::webrtc::rtclog::AudioNetworkAdaptation* audio_network_adaptation) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (audio_network_adaptation) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - audio_network_adaptation = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, audio_network_adaptation, submessage_arena); - } - set_has_audio_network_adaptation(); - subtype_.audio_network_adaptation_ = audio_network_adaptation; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.audio_network_adaptation) -} -void Event::set_allocated_probe_cluster(::webrtc::rtclog::BweProbeCluster* probe_cluster) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (probe_cluster) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - probe_cluster = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, probe_cluster, submessage_arena); - } - set_has_probe_cluster(); - subtype_.probe_cluster_ = probe_cluster; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.probe_cluster) -} -void Event::set_allocated_probe_result(::webrtc::rtclog::BweProbeResult* probe_result) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (probe_result) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - probe_result = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, probe_result, submessage_arena); - } - set_has_probe_result(); - subtype_.probe_result_ = probe_result; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.probe_result) -} -void Event::set_allocated_alr_state(::webrtc::rtclog::AlrState* alr_state) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (alr_state) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - alr_state = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, alr_state, submessage_arena); - } - set_has_alr_state(); - subtype_.alr_state_ = alr_state; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.alr_state) -} -void Event::set_allocated_ice_candidate_pair_config(::webrtc::rtclog::IceCandidatePairConfig* ice_candidate_pair_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (ice_candidate_pair_config) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - ice_candidate_pair_config = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, ice_candidate_pair_config, submessage_arena); - } - set_has_ice_candidate_pair_config(); - subtype_.ice_candidate_pair_config_ = ice_candidate_pair_config; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.ice_candidate_pair_config) -} -void Event::set_allocated_ice_candidate_pair_event(::webrtc::rtclog::IceCandidatePairEvent* ice_candidate_pair_event) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - clear_subtype(); - if (ice_candidate_pair_event) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - ice_candidate_pair_event = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, ice_candidate_pair_event, submessage_arena); - } - set_has_ice_candidate_pair_event(); - subtype_.ice_candidate_pair_event_ = ice_candidate_pair_event; - } - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.Event.ice_candidate_pair_event) -} -Event::Event() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.Event) -} -Event::Event(const Event& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_us_, &from.timestamp_us_, - static_cast(reinterpret_cast(&type_) - - reinterpret_cast(×tamp_us_)) + sizeof(type_)); - clear_has_subtype(); - switch (from.subtype_case()) { - case kRtpPacket: { - mutable_rtp_packet()->::webrtc::rtclog::RtpPacket::MergeFrom(from.rtp_packet()); - break; - } - case kRtcpPacket: { - mutable_rtcp_packet()->::webrtc::rtclog::RtcpPacket::MergeFrom(from.rtcp_packet()); - break; - } - case kAudioPlayoutEvent: { - mutable_audio_playout_event()->::webrtc::rtclog::AudioPlayoutEvent::MergeFrom(from.audio_playout_event()); - break; - } - case kLossBasedBweUpdate: { - mutable_loss_based_bwe_update()->::webrtc::rtclog::LossBasedBweUpdate::MergeFrom(from.loss_based_bwe_update()); - break; - } - case kDelayBasedBweUpdate: { - mutable_delay_based_bwe_update()->::webrtc::rtclog::DelayBasedBweUpdate::MergeFrom(from.delay_based_bwe_update()); - break; - } - case kVideoReceiverConfig: { - mutable_video_receiver_config()->::webrtc::rtclog::VideoReceiveConfig::MergeFrom(from.video_receiver_config()); - break; - } - case kVideoSenderConfig: { - mutable_video_sender_config()->::webrtc::rtclog::VideoSendConfig::MergeFrom(from.video_sender_config()); - break; - } - case kAudioReceiverConfig: { - mutable_audio_receiver_config()->::webrtc::rtclog::AudioReceiveConfig::MergeFrom(from.audio_receiver_config()); - break; - } - case kAudioSenderConfig: { - mutable_audio_sender_config()->::webrtc::rtclog::AudioSendConfig::MergeFrom(from.audio_sender_config()); - break; - } - case kAudioNetworkAdaptation: { - mutable_audio_network_adaptation()->::webrtc::rtclog::AudioNetworkAdaptation::MergeFrom(from.audio_network_adaptation()); - break; - } - case kProbeCluster: { - mutable_probe_cluster()->::webrtc::rtclog::BweProbeCluster::MergeFrom(from.probe_cluster()); - break; - } - case kProbeResult: { - mutable_probe_result()->::webrtc::rtclog::BweProbeResult::MergeFrom(from.probe_result()); - break; - } - case kAlrState: { - mutable_alr_state()->::webrtc::rtclog::AlrState::MergeFrom(from.alr_state()); - break; - } - case kIceCandidatePairConfig: { - mutable_ice_candidate_pair_config()->::webrtc::rtclog::IceCandidatePairConfig::MergeFrom(from.ice_candidate_pair_config()); - break; - } - case kIceCandidatePairEvent: { - mutable_ice_candidate_pair_event()->::webrtc::rtclog::IceCandidatePairEvent::MergeFrom(from.ice_candidate_pair_event()); - break; - } - case SUBTYPE_NOT_SET: { - break; - } - } - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.Event) -} - -void Event::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Event_rtc_5fevent_5flog_2eproto.base); - ::memset(×tamp_us_, 0, static_cast( - reinterpret_cast(&type_) - - reinterpret_cast(×tamp_us_)) + sizeof(type_)); - clear_has_subtype(); -} - -Event::~Event() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.Event) - SharedDtor(); -} - -void Event::SharedDtor() { - if (has_subtype()) { - clear_subtype(); - } -} - -void Event::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const Event& Event::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_Event_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void Event::clear_subtype() { -// @@protoc_insertion_point(one_of_clear_start:webrtc.rtclog.Event) - switch (subtype_case()) { - case kRtpPacket: { - delete subtype_.rtp_packet_; - break; - } - case kRtcpPacket: { - delete subtype_.rtcp_packet_; - break; - } - case kAudioPlayoutEvent: { - delete subtype_.audio_playout_event_; - break; - } - case kLossBasedBweUpdate: { - delete subtype_.loss_based_bwe_update_; - break; - } - case kDelayBasedBweUpdate: { - delete subtype_.delay_based_bwe_update_; - break; - } - case kVideoReceiverConfig: { - delete subtype_.video_receiver_config_; - break; - } - case kVideoSenderConfig: { - delete subtype_.video_sender_config_; - break; - } - case kAudioReceiverConfig: { - delete subtype_.audio_receiver_config_; - break; - } - case kAudioSenderConfig: { - delete subtype_.audio_sender_config_; - break; - } - case kAudioNetworkAdaptation: { - delete subtype_.audio_network_adaptation_; - break; - } - case kProbeCluster: { - delete subtype_.probe_cluster_; - break; - } - case kProbeResult: { - delete subtype_.probe_result_; - break; - } - case kAlrState: { - delete subtype_.alr_state_; - break; - } - case kIceCandidatePairConfig: { - delete subtype_.ice_candidate_pair_config_; - break; - } - case kIceCandidatePairEvent: { - delete subtype_.ice_candidate_pair_event_; - break; - } - case SUBTYPE_NOT_SET: { - break; - } - } - _oneof_case_[0] = SUBTYPE_NOT_SET; -} - - -void Event::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.Event) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - ::memset(×tamp_us_, 0, static_cast( - reinterpret_cast(&type_) - - reinterpret_cast(×tamp_us_)) + sizeof(type_)); - } - clear_subtype(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* Event::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_us = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_us(&has_bits); - timestamp_us_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.Event.EventType type = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::Event_EventType_IsValid(val))) { - set_type(static_cast<::webrtc::rtclog::Event_EventType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(2, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.RtpPacket rtp_packet = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { - ptr = ctx->ParseMessage(mutable_rtp_packet(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.RtcpPacket rtcp_packet = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) { - ptr = ctx->ParseMessage(mutable_rtcp_packet(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.AudioPlayoutEvent audio_playout_event = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ctx->ParseMessage(mutable_audio_playout_event(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.LossBasedBweUpdate loss_based_bwe_update = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ctx->ParseMessage(mutable_loss_based_bwe_update(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.DelayBasedBweUpdate delay_based_bwe_update = 7; - case 7: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr = ctx->ParseMessage(mutable_delay_based_bwe_update(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.VideoReceiveConfig video_receiver_config = 8; - case 8: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { - ptr = ctx->ParseMessage(mutable_video_receiver_config(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.VideoSendConfig video_sender_config = 9; - case 9: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 74)) { - ptr = ctx->ParseMessage(mutable_video_sender_config(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.AudioReceiveConfig audio_receiver_config = 10; - case 10: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 82)) { - ptr = ctx->ParseMessage(mutable_audio_receiver_config(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.AudioSendConfig audio_sender_config = 11; - case 11: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 90)) { - ptr = ctx->ParseMessage(mutable_audio_sender_config(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.AudioNetworkAdaptation audio_network_adaptation = 16; - case 16: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 130)) { - ptr = ctx->ParseMessage(mutable_audio_network_adaptation(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.BweProbeCluster probe_cluster = 17; - case 17: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 138)) { - ptr = ctx->ParseMessage(mutable_probe_cluster(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.BweProbeResult probe_result = 18; - case 18: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 146)) { - ptr = ctx->ParseMessage(mutable_probe_result(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.AlrState alr_state = 19; - case 19: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 154)) { - ptr = ctx->ParseMessage(mutable_alr_state(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairConfig ice_candidate_pair_config = 20; - case 20: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 162)) { - ptr = ctx->ParseMessage(mutable_ice_candidate_pair_config(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairEvent ice_candidate_pair_event = 21; - case 21: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 170)) { - ptr = ctx->ParseMessage(mutable_ice_candidate_pair_event(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool Event::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.Event) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_us = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_us(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_us_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.Event.EventType type = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::Event_EventType_IsValid(value)) { - set_type(static_cast< ::webrtc::rtclog::Event_EventType >(value)); - } else { - unknown_fields_stream.WriteVarint32(16u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.RtpPacket rtp_packet = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (26 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_rtp_packet())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.RtcpPacket rtcp_packet = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (34 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_rtcp_packet())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.AudioPlayoutEvent audio_playout_event = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (42 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_audio_playout_event())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.LossBasedBweUpdate loss_based_bwe_update = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (50 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_loss_based_bwe_update())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.DelayBasedBweUpdate delay_based_bwe_update = 7; - case 7: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (58 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_delay_based_bwe_update())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.VideoReceiveConfig video_receiver_config = 8; - case 8: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (66 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_video_receiver_config())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.VideoSendConfig video_sender_config = 9; - case 9: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (74 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_video_sender_config())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.AudioReceiveConfig audio_receiver_config = 10; - case 10: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (82 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_audio_receiver_config())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.AudioSendConfig audio_sender_config = 11; - case 11: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (90 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_audio_sender_config())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.AudioNetworkAdaptation audio_network_adaptation = 16; - case 16: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (130 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_audio_network_adaptation())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.BweProbeCluster probe_cluster = 17; - case 17: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (138 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_probe_cluster())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.BweProbeResult probe_result = 18; - case 18: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (146 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_probe_result())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.AlrState alr_state = 19; - case 19: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (154 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_alr_state())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairConfig ice_candidate_pair_config = 20; - case 20: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (162 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_ice_candidate_pair_config())); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairEvent ice_candidate_pair_event = 21; - case 21: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (170 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_ice_candidate_pair_event())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.Event) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.Event) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void Event::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.Event) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_us = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_us(), output); - } - - // optional .webrtc.rtclog.Event.EventType type = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 2, this->type(), output); - } - - switch (subtype_case()) { - case kRtpPacket: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 3, _Internal::rtp_packet(this), output); - break; - case kRtcpPacket: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 4, _Internal::rtcp_packet(this), output); - break; - case kAudioPlayoutEvent: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 5, _Internal::audio_playout_event(this), output); - break; - case kLossBasedBweUpdate: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 6, _Internal::loss_based_bwe_update(this), output); - break; - case kDelayBasedBweUpdate: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 7, _Internal::delay_based_bwe_update(this), output); - break; - case kVideoReceiverConfig: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 8, _Internal::video_receiver_config(this), output); - break; - case kVideoSenderConfig: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 9, _Internal::video_sender_config(this), output); - break; - case kAudioReceiverConfig: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 10, _Internal::audio_receiver_config(this), output); - break; - case kAudioSenderConfig: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 11, _Internal::audio_sender_config(this), output); - break; - case kAudioNetworkAdaptation: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 16, _Internal::audio_network_adaptation(this), output); - break; - case kProbeCluster: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 17, _Internal::probe_cluster(this), output); - break; - case kProbeResult: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 18, _Internal::probe_result(this), output); - break; - case kAlrState: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 19, _Internal::alr_state(this), output); - break; - case kIceCandidatePairConfig: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 20, _Internal::ice_candidate_pair_config(this), output); - break; - case kIceCandidatePairEvent: - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 21, _Internal::ice_candidate_pair_event(this), output); - break; - default: ; - } - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.Event) -} - -size_t Event::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.Event) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional int64 timestamp_us = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_us()); - } - - // optional .webrtc.rtclog.Event.EventType type = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->type()); - } - - } - switch (subtype_case()) { - // optional .webrtc.rtclog.RtpPacket rtp_packet = 3; - case kRtpPacket: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.rtp_packet_); - break; - } - // optional .webrtc.rtclog.RtcpPacket rtcp_packet = 4; - case kRtcpPacket: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.rtcp_packet_); - break; - } - // optional .webrtc.rtclog.AudioPlayoutEvent audio_playout_event = 5; - case kAudioPlayoutEvent: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.audio_playout_event_); - break; - } - // optional .webrtc.rtclog.LossBasedBweUpdate loss_based_bwe_update = 6; - case kLossBasedBweUpdate: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.loss_based_bwe_update_); - break; - } - // optional .webrtc.rtclog.DelayBasedBweUpdate delay_based_bwe_update = 7; - case kDelayBasedBweUpdate: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.delay_based_bwe_update_); - break; - } - // optional .webrtc.rtclog.VideoReceiveConfig video_receiver_config = 8; - case kVideoReceiverConfig: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.video_receiver_config_); - break; - } - // optional .webrtc.rtclog.VideoSendConfig video_sender_config = 9; - case kVideoSenderConfig: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.video_sender_config_); - break; - } - // optional .webrtc.rtclog.AudioReceiveConfig audio_receiver_config = 10; - case kAudioReceiverConfig: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.audio_receiver_config_); - break; - } - // optional .webrtc.rtclog.AudioSendConfig audio_sender_config = 11; - case kAudioSenderConfig: { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.audio_sender_config_); - break; - } - // optional .webrtc.rtclog.AudioNetworkAdaptation audio_network_adaptation = 16; - case kAudioNetworkAdaptation: { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.audio_network_adaptation_); - break; - } - // optional .webrtc.rtclog.BweProbeCluster probe_cluster = 17; - case kProbeCluster: { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.probe_cluster_); - break; - } - // optional .webrtc.rtclog.BweProbeResult probe_result = 18; - case kProbeResult: { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.probe_result_); - break; - } - // optional .webrtc.rtclog.AlrState alr_state = 19; - case kAlrState: { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.alr_state_); - break; - } - // optional .webrtc.rtclog.IceCandidatePairConfig ice_candidate_pair_config = 20; - case kIceCandidatePairConfig: { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.ice_candidate_pair_config_); - break; - } - // optional .webrtc.rtclog.IceCandidatePairEvent ice_candidate_pair_event = 21; - case kIceCandidatePairEvent: { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *subtype_.ice_candidate_pair_event_); - break; - } - case SUBTYPE_NOT_SET: { - break; - } - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void Event::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void Event::MergeFrom(const Event& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.Event) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - timestamp_us_ = from.timestamp_us_; - } - if (cached_has_bits & 0x00000002u) { - type_ = from.type_; - } - _has_bits_[0] |= cached_has_bits; - } - switch (from.subtype_case()) { - case kRtpPacket: { - mutable_rtp_packet()->::webrtc::rtclog::RtpPacket::MergeFrom(from.rtp_packet()); - break; - } - case kRtcpPacket: { - mutable_rtcp_packet()->::webrtc::rtclog::RtcpPacket::MergeFrom(from.rtcp_packet()); - break; - } - case kAudioPlayoutEvent: { - mutable_audio_playout_event()->::webrtc::rtclog::AudioPlayoutEvent::MergeFrom(from.audio_playout_event()); - break; - } - case kLossBasedBweUpdate: { - mutable_loss_based_bwe_update()->::webrtc::rtclog::LossBasedBweUpdate::MergeFrom(from.loss_based_bwe_update()); - break; - } - case kDelayBasedBweUpdate: { - mutable_delay_based_bwe_update()->::webrtc::rtclog::DelayBasedBweUpdate::MergeFrom(from.delay_based_bwe_update()); - break; - } - case kVideoReceiverConfig: { - mutable_video_receiver_config()->::webrtc::rtclog::VideoReceiveConfig::MergeFrom(from.video_receiver_config()); - break; - } - case kVideoSenderConfig: { - mutable_video_sender_config()->::webrtc::rtclog::VideoSendConfig::MergeFrom(from.video_sender_config()); - break; - } - case kAudioReceiverConfig: { - mutable_audio_receiver_config()->::webrtc::rtclog::AudioReceiveConfig::MergeFrom(from.audio_receiver_config()); - break; - } - case kAudioSenderConfig: { - mutable_audio_sender_config()->::webrtc::rtclog::AudioSendConfig::MergeFrom(from.audio_sender_config()); - break; - } - case kAudioNetworkAdaptation: { - mutable_audio_network_adaptation()->::webrtc::rtclog::AudioNetworkAdaptation::MergeFrom(from.audio_network_adaptation()); - break; - } - case kProbeCluster: { - mutable_probe_cluster()->::webrtc::rtclog::BweProbeCluster::MergeFrom(from.probe_cluster()); - break; - } - case kProbeResult: { - mutable_probe_result()->::webrtc::rtclog::BweProbeResult::MergeFrom(from.probe_result()); - break; - } - case kAlrState: { - mutable_alr_state()->::webrtc::rtclog::AlrState::MergeFrom(from.alr_state()); - break; - } - case kIceCandidatePairConfig: { - mutable_ice_candidate_pair_config()->::webrtc::rtclog::IceCandidatePairConfig::MergeFrom(from.ice_candidate_pair_config()); - break; - } - case kIceCandidatePairEvent: { - mutable_ice_candidate_pair_event()->::webrtc::rtclog::IceCandidatePairEvent::MergeFrom(from.ice_candidate_pair_event()); - break; - } - case SUBTYPE_NOT_SET: { - break; - } - } -} - -void Event::CopyFrom(const Event& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.Event) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Event::IsInitialized() const { - return true; -} - -void Event::InternalSwap(Event* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_us_, other->timestamp_us_); - swap(type_, other->type_); - swap(subtype_, other->subtype_); - swap(_oneof_case_[0], other->_oneof_case_[0]); -} - -std::string Event::GetTypeName() const { - return "webrtc.rtclog.Event"; -} - - -// =================================================================== - -void RtpPacket::InitAsDefaultInstance() { -} -class RtpPacket::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_incoming(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_type(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_packet_length(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_header(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_probe_cluster_id(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } -}; - -RtpPacket::RtpPacket() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.RtpPacket) -} -RtpPacket::RtpPacket(const RtpPacket& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - header_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_header()) { - header_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.header_); - } - ::memcpy(&incoming_, &from.incoming_, - static_cast(reinterpret_cast(&probe_cluster_id_) - - reinterpret_cast(&incoming_)) + sizeof(probe_cluster_id_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.RtpPacket) -} - -void RtpPacket::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_RtpPacket_rtc_5fevent_5flog_2eproto.base); - header_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&incoming_, 0, static_cast( - reinterpret_cast(&probe_cluster_id_) - - reinterpret_cast(&incoming_)) + sizeof(probe_cluster_id_)); -} - -RtpPacket::~RtpPacket() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.RtpPacket) - SharedDtor(); -} - -void RtpPacket::SharedDtor() { - header_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void RtpPacket::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const RtpPacket& RtpPacket::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_RtpPacket_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void RtpPacket::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.RtpPacket) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - header_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x0000001eu) { - ::memset(&incoming_, 0, static_cast( - reinterpret_cast(&probe_cluster_id_) - - reinterpret_cast(&incoming_)) + sizeof(probe_cluster_id_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* RtpPacket::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional bool incoming = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_incoming(&has_bits); - incoming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::MediaType_IsValid(val))) { - set_type(static_cast<::webrtc::rtclog::MediaType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(2, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional uint32 packet_length = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_packet_length(&has_bits); - packet_length_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes header = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_header(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 probe_cluster_id = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - _Internal::set_has_probe_cluster_id(&has_bits); - probe_cluster_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool RtpPacket::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.RtpPacket) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional bool incoming = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_incoming(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &incoming_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::MediaType_IsValid(value)) { - set_type(static_cast< ::webrtc::rtclog::MediaType >(value)); - } else { - unknown_fields_stream.WriteVarint32(16u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 packet_length = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_packet_length(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &packet_length_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes header = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (34 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_header())); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 probe_cluster_id = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - _Internal::set_has_probe_cluster_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &probe_cluster_id_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.RtpPacket) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.RtpPacket) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void RtpPacket::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.RtpPacket) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional bool incoming = 1; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(1, this->incoming(), output); - } - - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 2, this->type(), output); - } - - // optional uint32 packet_length = 3; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->packet_length(), output); - } - - // optional bytes header = 4; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 4, this->header(), output); - } - - // optional int32 probe_cluster_id = 5; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(5, this->probe_cluster_id(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.RtpPacket) -} - -size_t RtpPacket::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.RtpPacket) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional bytes header = 4; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->header()); - } - - // optional bool incoming = 1; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + 1; - } - - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->type()); - } - - // optional uint32 packet_length = 3; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->packet_length()); - } - - // optional int32 probe_cluster_id = 5; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->probe_cluster_id()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void RtpPacket::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void RtpPacket::MergeFrom(const RtpPacket& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.RtpPacket) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - header_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.header_); - } - if (cached_has_bits & 0x00000002u) { - incoming_ = from.incoming_; - } - if (cached_has_bits & 0x00000004u) { - type_ = from.type_; - } - if (cached_has_bits & 0x00000008u) { - packet_length_ = from.packet_length_; - } - if (cached_has_bits & 0x00000010u) { - probe_cluster_id_ = from.probe_cluster_id_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void RtpPacket::CopyFrom(const RtpPacket& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.RtpPacket) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RtpPacket::IsInitialized() const { - return true; -} - -void RtpPacket::InternalSwap(RtpPacket* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - header_.Swap(&other->header_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(incoming_, other->incoming_); - swap(type_, other->type_); - swap(packet_length_, other->packet_length_); - swap(probe_cluster_id_, other->probe_cluster_id_); -} - -std::string RtpPacket::GetTypeName() const { - return "webrtc.rtclog.RtpPacket"; -} - - -// =================================================================== - -void RtcpPacket::InitAsDefaultInstance() { -} -class RtcpPacket::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_incoming(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_type(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_packet_data(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -RtcpPacket::RtcpPacket() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.RtcpPacket) -} -RtcpPacket::RtcpPacket(const RtcpPacket& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - packet_data_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_packet_data()) { - packet_data_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_data_); - } - ::memcpy(&incoming_, &from.incoming_, - static_cast(reinterpret_cast(&type_) - - reinterpret_cast(&incoming_)) + sizeof(type_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.RtcpPacket) -} - -void RtcpPacket::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_RtcpPacket_rtc_5fevent_5flog_2eproto.base); - packet_data_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&incoming_, 0, static_cast( - reinterpret_cast(&type_) - - reinterpret_cast(&incoming_)) + sizeof(type_)); -} - -RtcpPacket::~RtcpPacket() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.RtcpPacket) - SharedDtor(); -} - -void RtcpPacket::SharedDtor() { - packet_data_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void RtcpPacket::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const RtcpPacket& RtcpPacket::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_RtcpPacket_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void RtcpPacket::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.RtcpPacket) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - packet_data_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000006u) { - ::memset(&incoming_, 0, static_cast( - reinterpret_cast(&type_) - - reinterpret_cast(&incoming_)) + sizeof(type_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* RtcpPacket::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional bool incoming = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_incoming(&has_bits); - incoming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::MediaType_IsValid(val))) { - set_type(static_cast<::webrtc::rtclog::MediaType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(2, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional bytes packet_data = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_packet_data(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool RtcpPacket::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.RtcpPacket) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional bool incoming = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_incoming(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &incoming_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::MediaType_IsValid(value)) { - set_type(static_cast< ::webrtc::rtclog::MediaType >(value)); - } else { - unknown_fields_stream.WriteVarint32(16u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional bytes packet_data = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (26 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_packet_data())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.RtcpPacket) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.RtcpPacket) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void RtcpPacket::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.RtcpPacket) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional bool incoming = 1; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(1, this->incoming(), output); - } - - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 2, this->type(), output); - } - - // optional bytes packet_data = 3; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 3, this->packet_data(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.RtcpPacket) -} - -size_t RtcpPacket::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.RtcpPacket) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - // optional bytes packet_data = 3; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->packet_data()); - } - - // optional bool incoming = 1; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + 1; - } - - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->type()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void RtcpPacket::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void RtcpPacket::MergeFrom(const RtcpPacket& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.RtcpPacket) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - packet_data_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_data_); - } - if (cached_has_bits & 0x00000002u) { - incoming_ = from.incoming_; - } - if (cached_has_bits & 0x00000004u) { - type_ = from.type_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void RtcpPacket::CopyFrom(const RtcpPacket& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.RtcpPacket) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RtcpPacket::IsInitialized() const { - return true; -} - -void RtcpPacket::InternalSwap(RtcpPacket* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - packet_data_.Swap(&other->packet_data_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(incoming_, other->incoming_); - swap(type_, other->type_); -} - -std::string RtcpPacket::GetTypeName() const { - return "webrtc.rtclog.RtcpPacket"; -} - - -// =================================================================== - -void AudioPlayoutEvent::InitAsDefaultInstance() { -} -class AudioPlayoutEvent::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_local_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -AudioPlayoutEvent::AudioPlayoutEvent() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.AudioPlayoutEvent) -} -AudioPlayoutEvent::AudioPlayoutEvent(const AudioPlayoutEvent& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - local_ssrc_ = from.local_ssrc_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.AudioPlayoutEvent) -} - -void AudioPlayoutEvent::SharedCtor() { - local_ssrc_ = 0u; -} - -AudioPlayoutEvent::~AudioPlayoutEvent() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.AudioPlayoutEvent) - SharedDtor(); -} - -void AudioPlayoutEvent::SharedDtor() { -} - -void AudioPlayoutEvent::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AudioPlayoutEvent& AudioPlayoutEvent::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AudioPlayoutEvent_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void AudioPlayoutEvent::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.AudioPlayoutEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - local_ssrc_ = 0u; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AudioPlayoutEvent::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional uint32 local_ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_local_ssrc(&has_bits); - local_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AudioPlayoutEvent::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.AudioPlayoutEvent) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional uint32 local_ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_local_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &local_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.AudioPlayoutEvent) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.AudioPlayoutEvent) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AudioPlayoutEvent::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.AudioPlayoutEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional uint32 local_ssrc = 2; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->local_ssrc(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.AudioPlayoutEvent) -} - -size_t AudioPlayoutEvent::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.AudioPlayoutEvent) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // optional uint32 local_ssrc = 2; - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->local_ssrc()); - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AudioPlayoutEvent::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AudioPlayoutEvent::MergeFrom(const AudioPlayoutEvent& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.AudioPlayoutEvent) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - if (from.has_local_ssrc()) { - set_local_ssrc(from.local_ssrc()); - } -} - -void AudioPlayoutEvent::CopyFrom(const AudioPlayoutEvent& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.AudioPlayoutEvent) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AudioPlayoutEvent::IsInitialized() const { - return true; -} - -void AudioPlayoutEvent::InternalSwap(AudioPlayoutEvent* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(local_ssrc_, other->local_ssrc_); -} - -std::string AudioPlayoutEvent::GetTypeName() const { - return "webrtc.rtclog.AudioPlayoutEvent"; -} - - -// =================================================================== - -void LossBasedBweUpdate::InitAsDefaultInstance() { -} -class LossBasedBweUpdate::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_fraction_loss(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_total_packets(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -LossBasedBweUpdate::LossBasedBweUpdate() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.LossBasedBweUpdate) -} -LossBasedBweUpdate::LossBasedBweUpdate(const LossBasedBweUpdate& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&bitrate_bps_, &from.bitrate_bps_, - static_cast(reinterpret_cast(&total_packets_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(total_packets_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.LossBasedBweUpdate) -} - -void LossBasedBweUpdate::SharedCtor() { - ::memset(&bitrate_bps_, 0, static_cast( - reinterpret_cast(&total_packets_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(total_packets_)); -} - -LossBasedBweUpdate::~LossBasedBweUpdate() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.LossBasedBweUpdate) - SharedDtor(); -} - -void LossBasedBweUpdate::SharedDtor() { -} - -void LossBasedBweUpdate::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const LossBasedBweUpdate& LossBasedBweUpdate::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_LossBasedBweUpdate_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void LossBasedBweUpdate::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.LossBasedBweUpdate) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - ::memset(&bitrate_bps_, 0, static_cast( - reinterpret_cast(&total_packets_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(total_packets_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* LossBasedBweUpdate::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int32 bitrate_bps = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 fraction_loss = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_fraction_loss(&has_bits); - fraction_loss_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 total_packets = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_total_packets(&has_bits); - total_packets_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool LossBasedBweUpdate::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.LossBasedBweUpdate) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int32 bitrate_bps = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 fraction_loss = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_fraction_loss(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &fraction_loss_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 total_packets = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_total_packets(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &total_packets_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.LossBasedBweUpdate) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.LossBasedBweUpdate) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void LossBasedBweUpdate::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.LossBasedBweUpdate) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int32 bitrate_bps = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(1, this->bitrate_bps(), output); - } - - // optional uint32 fraction_loss = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->fraction_loss(), output); - } - - // optional int32 total_packets = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(3, this->total_packets(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.LossBasedBweUpdate) -} - -size_t LossBasedBweUpdate::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.LossBasedBweUpdate) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - // optional int32 bitrate_bps = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->bitrate_bps()); - } - - // optional uint32 fraction_loss = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->fraction_loss()); - } - - // optional int32 total_packets = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->total_packets()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void LossBasedBweUpdate::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void LossBasedBweUpdate::MergeFrom(const LossBasedBweUpdate& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.LossBasedBweUpdate) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - bitrate_bps_ = from.bitrate_bps_; - } - if (cached_has_bits & 0x00000002u) { - fraction_loss_ = from.fraction_loss_; - } - if (cached_has_bits & 0x00000004u) { - total_packets_ = from.total_packets_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void LossBasedBweUpdate::CopyFrom(const LossBasedBweUpdate& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.LossBasedBweUpdate) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool LossBasedBweUpdate::IsInitialized() const { - return true; -} - -void LossBasedBweUpdate::InternalSwap(LossBasedBweUpdate* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(bitrate_bps_, other->bitrate_bps_); - swap(fraction_loss_, other->fraction_loss_); - swap(total_packets_, other->total_packets_); -} - -std::string LossBasedBweUpdate::GetTypeName() const { - return "webrtc.rtclog.LossBasedBweUpdate"; -} - - -// =================================================================== - -void DelayBasedBweUpdate::InitAsDefaultInstance() { -} -class DelayBasedBweUpdate::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_detector_state(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -DelayBasedBweUpdate::DelayBasedBweUpdate() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.DelayBasedBweUpdate) -} -DelayBasedBweUpdate::DelayBasedBweUpdate(const DelayBasedBweUpdate& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&bitrate_bps_, &from.bitrate_bps_, - static_cast(reinterpret_cast(&detector_state_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(detector_state_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.DelayBasedBweUpdate) -} - -void DelayBasedBweUpdate::SharedCtor() { - ::memset(&bitrate_bps_, 0, static_cast( - reinterpret_cast(&detector_state_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(detector_state_)); -} - -DelayBasedBweUpdate::~DelayBasedBweUpdate() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.DelayBasedBweUpdate) - SharedDtor(); -} - -void DelayBasedBweUpdate::SharedDtor() { -} - -void DelayBasedBweUpdate::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const DelayBasedBweUpdate& DelayBasedBweUpdate::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_DelayBasedBweUpdate_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void DelayBasedBweUpdate::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.DelayBasedBweUpdate) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - ::memset(&bitrate_bps_, 0, static_cast( - reinterpret_cast(&detector_state_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(detector_state_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* DelayBasedBweUpdate::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int32 bitrate_bps = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.DelayBasedBweUpdate.DetectorState detector_state = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::DelayBasedBweUpdate_DetectorState_IsValid(val))) { - set_detector_state(static_cast<::webrtc::rtclog::DelayBasedBweUpdate_DetectorState>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(2, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool DelayBasedBweUpdate::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.DelayBasedBweUpdate) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int32 bitrate_bps = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.DelayBasedBweUpdate.DetectorState detector_state = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::DelayBasedBweUpdate_DetectorState_IsValid(value)) { - set_detector_state(static_cast< ::webrtc::rtclog::DelayBasedBweUpdate_DetectorState >(value)); - } else { - unknown_fields_stream.WriteVarint32(16u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.DelayBasedBweUpdate) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.DelayBasedBweUpdate) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void DelayBasedBweUpdate::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.DelayBasedBweUpdate) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int32 bitrate_bps = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(1, this->bitrate_bps(), output); - } - - // optional .webrtc.rtclog.DelayBasedBweUpdate.DetectorState detector_state = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 2, this->detector_state(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.DelayBasedBweUpdate) -} - -size_t DelayBasedBweUpdate::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.DelayBasedBweUpdate) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional int32 bitrate_bps = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->bitrate_bps()); - } - - // optional .webrtc.rtclog.DelayBasedBweUpdate.DetectorState detector_state = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->detector_state()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void DelayBasedBweUpdate::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void DelayBasedBweUpdate::MergeFrom(const DelayBasedBweUpdate& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.DelayBasedBweUpdate) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - bitrate_bps_ = from.bitrate_bps_; - } - if (cached_has_bits & 0x00000002u) { - detector_state_ = from.detector_state_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void DelayBasedBweUpdate::CopyFrom(const DelayBasedBweUpdate& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.DelayBasedBweUpdate) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DelayBasedBweUpdate::IsInitialized() const { - return true; -} - -void DelayBasedBweUpdate::InternalSwap(DelayBasedBweUpdate* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(bitrate_bps_, other->bitrate_bps_); - swap(detector_state_, other->detector_state_); -} - -std::string DelayBasedBweUpdate::GetTypeName() const { - return "webrtc.rtclog.DelayBasedBweUpdate"; -} - - -// =================================================================== - -void VideoReceiveConfig::InitAsDefaultInstance() { -} -class VideoReceiveConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_remote_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_local_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_rtcp_mode(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_remb(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -VideoReceiveConfig::VideoReceiveConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.VideoReceiveConfig) -} -VideoReceiveConfig::VideoReceiveConfig(const VideoReceiveConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), - rtx_map_(from.rtx_map_), - header_extensions_(from.header_extensions_), - decoders_(from.decoders_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&remote_ssrc_, &from.remote_ssrc_, - static_cast(reinterpret_cast(&rtcp_mode_) - - reinterpret_cast(&remote_ssrc_)) + sizeof(rtcp_mode_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.VideoReceiveConfig) -} - -void VideoReceiveConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_VideoReceiveConfig_rtc_5fevent_5flog_2eproto.base); - ::memset(&remote_ssrc_, 0, static_cast( - reinterpret_cast(&remb_) - - reinterpret_cast(&remote_ssrc_)) + sizeof(remb_)); - rtcp_mode_ = 1; -} - -VideoReceiveConfig::~VideoReceiveConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.VideoReceiveConfig) - SharedDtor(); -} - -void VideoReceiveConfig::SharedDtor() { -} - -void VideoReceiveConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const VideoReceiveConfig& VideoReceiveConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_VideoReceiveConfig_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void VideoReceiveConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.VideoReceiveConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - rtx_map_.Clear(); - header_extensions_.Clear(); - decoders_.Clear(); - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - ::memset(&remote_ssrc_, 0, static_cast( - reinterpret_cast(&remb_) - - reinterpret_cast(&remote_ssrc_)) + sizeof(remb_)); - rtcp_mode_ = 1; - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* VideoReceiveConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional uint32 remote_ssrc = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_remote_ssrc(&has_bits); - remote_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 local_ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_local_ssrc(&has_bits); - local_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.VideoReceiveConfig.RtcpMode rtcp_mode = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::VideoReceiveConfig_RtcpMode_IsValid(val))) { - set_rtcp_mode(static_cast<::webrtc::rtclog::VideoReceiveConfig_RtcpMode>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(3, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional bool remb = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_remb(&has_bits); - remb_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog.RtxMap rtx_map = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_rtx_map(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 42); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_header_extensions(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 50); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog.DecoderConfig decoders = 7; - case 7: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_decoders(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 58); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool VideoReceiveConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.VideoReceiveConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional uint32 remote_ssrc = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_remote_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &remote_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 local_ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_local_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &local_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.VideoReceiveConfig.RtcpMode rtcp_mode = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::VideoReceiveConfig_RtcpMode_IsValid(value)) { - set_rtcp_mode(static_cast< ::webrtc::rtclog::VideoReceiveConfig_RtcpMode >(value)); - } else { - unknown_fields_stream.WriteVarint32(24u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional bool remb = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_remb(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &remb_))); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog.RtxMap rtx_map = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (42 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_rtx_map())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (50 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_header_extensions())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog.DecoderConfig decoders = 7; - case 7: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (58 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_decoders())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.VideoReceiveConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.VideoReceiveConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void VideoReceiveConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.VideoReceiveConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional uint32 remote_ssrc = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(1, this->remote_ssrc(), output); - } - - // optional uint32 local_ssrc = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->local_ssrc(), output); - } - - // optional .webrtc.rtclog.VideoReceiveConfig.RtcpMode rtcp_mode = 3; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 3, this->rtcp_mode(), output); - } - - // optional bool remb = 4; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(4, this->remb(), output); - } - - // repeated .webrtc.rtclog.RtxMap rtx_map = 5; - for (unsigned int i = 0, - n = static_cast(this->rtx_map_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 5, - this->rtx_map(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 6; - for (unsigned int i = 0, - n = static_cast(this->header_extensions_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 6, - this->header_extensions(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog.DecoderConfig decoders = 7; - for (unsigned int i = 0, - n = static_cast(this->decoders_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 7, - this->decoders(static_cast(i)), - output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.VideoReceiveConfig) -} - -size_t VideoReceiveConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.VideoReceiveConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // repeated .webrtc.rtclog.RtxMap rtx_map = 5; - { - unsigned int count = static_cast(this->rtx_map_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->rtx_map(static_cast(i))); - } - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 6; - { - unsigned int count = static_cast(this->header_extensions_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->header_extensions(static_cast(i))); - } - } - - // repeated .webrtc.rtclog.DecoderConfig decoders = 7; - { - unsigned int count = static_cast(this->decoders_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->decoders(static_cast(i))); - } - } - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - // optional uint32 remote_ssrc = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->remote_ssrc()); - } - - // optional uint32 local_ssrc = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->local_ssrc()); - } - - // optional bool remb = 4; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + 1; - } - - // optional .webrtc.rtclog.VideoReceiveConfig.RtcpMode rtcp_mode = 3; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->rtcp_mode()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void VideoReceiveConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void VideoReceiveConfig::MergeFrom(const VideoReceiveConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.VideoReceiveConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - rtx_map_.MergeFrom(from.rtx_map_); - header_extensions_.MergeFrom(from.header_extensions_); - decoders_.MergeFrom(from.decoders_); - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - if (cached_has_bits & 0x00000001u) { - remote_ssrc_ = from.remote_ssrc_; - } - if (cached_has_bits & 0x00000002u) { - local_ssrc_ = from.local_ssrc_; - } - if (cached_has_bits & 0x00000004u) { - remb_ = from.remb_; - } - if (cached_has_bits & 0x00000008u) { - rtcp_mode_ = from.rtcp_mode_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void VideoReceiveConfig::CopyFrom(const VideoReceiveConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.VideoReceiveConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool VideoReceiveConfig::IsInitialized() const { - return true; -} - -void VideoReceiveConfig::InternalSwap(VideoReceiveConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - CastToBase(&rtx_map_)->InternalSwap(CastToBase(&other->rtx_map_)); - CastToBase(&header_extensions_)->InternalSwap(CastToBase(&other->header_extensions_)); - CastToBase(&decoders_)->InternalSwap(CastToBase(&other->decoders_)); - swap(remote_ssrc_, other->remote_ssrc_); - swap(local_ssrc_, other->local_ssrc_); - swap(remb_, other->remb_); - swap(rtcp_mode_, other->rtcp_mode_); -} - -std::string VideoReceiveConfig::GetTypeName() const { - return "webrtc.rtclog.VideoReceiveConfig"; -} - - -// =================================================================== - -void DecoderConfig::InitAsDefaultInstance() { -} -class DecoderConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_payload_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -DecoderConfig::DecoderConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.DecoderConfig) -} -DecoderConfig::DecoderConfig(const DecoderConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_name()) { - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); - } - payload_type_ = from.payload_type_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.DecoderConfig) -} - -void DecoderConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_DecoderConfig_rtc_5fevent_5flog_2eproto.base); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_type_ = 0; -} - -DecoderConfig::~DecoderConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.DecoderConfig) - SharedDtor(); -} - -void DecoderConfig::SharedDtor() { - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void DecoderConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const DecoderConfig& DecoderConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_DecoderConfig_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void DecoderConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.DecoderConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - name_.ClearNonDefaultToEmptyNoArena(); - } - payload_type_ = 0; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* DecoderConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional string name = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_name(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 payload_type = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_payload_type(&has_bits); - payload_type_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool DecoderConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.DecoderConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (10 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 payload_type = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_payload_type(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &payload_type_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.DecoderConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.DecoderConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void DecoderConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.DecoderConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - // optional int32 payload_type = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->payload_type(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.DecoderConfig) -} - -size_t DecoderConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.DecoderConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional int32 payload_type = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->payload_type()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void DecoderConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void DecoderConfig::MergeFrom(const DecoderConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.DecoderConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); - } - if (cached_has_bits & 0x00000002u) { - payload_type_ = from.payload_type_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void DecoderConfig::CopyFrom(const DecoderConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.DecoderConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DecoderConfig::IsInitialized() const { - return true; -} - -void DecoderConfig::InternalSwap(DecoderConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(payload_type_, other->payload_type_); -} - -std::string DecoderConfig::GetTypeName() const { - return "webrtc.rtclog.DecoderConfig"; -} - - -// =================================================================== - -void RtpHeaderExtension::InitAsDefaultInstance() { -} -class RtpHeaderExtension::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_id(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -RtpHeaderExtension::RtpHeaderExtension() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.RtpHeaderExtension) -} -RtpHeaderExtension::RtpHeaderExtension(const RtpHeaderExtension& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_name()) { - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); - } - id_ = from.id_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.RtpHeaderExtension) -} - -void RtpHeaderExtension::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto.base); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - id_ = 0; -} - -RtpHeaderExtension::~RtpHeaderExtension() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.RtpHeaderExtension) - SharedDtor(); -} - -void RtpHeaderExtension::SharedDtor() { - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void RtpHeaderExtension::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const RtpHeaderExtension& RtpHeaderExtension::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_RtpHeaderExtension_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void RtpHeaderExtension::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.RtpHeaderExtension) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - name_.ClearNonDefaultToEmptyNoArena(); - } - id_ = 0; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* RtpHeaderExtension::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional string name = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_name(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 id = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_id(&has_bits); - id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool RtpHeaderExtension::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.RtpHeaderExtension) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (10 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 id = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &id_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.RtpHeaderExtension) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.RtpHeaderExtension) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void RtpHeaderExtension::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.RtpHeaderExtension) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - // optional int32 id = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->id(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.RtpHeaderExtension) -} - -size_t RtpHeaderExtension::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.RtpHeaderExtension) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional int32 id = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->id()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void RtpHeaderExtension::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void RtpHeaderExtension::MergeFrom(const RtpHeaderExtension& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.RtpHeaderExtension) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); - } - if (cached_has_bits & 0x00000002u) { - id_ = from.id_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void RtpHeaderExtension::CopyFrom(const RtpHeaderExtension& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.RtpHeaderExtension) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RtpHeaderExtension::IsInitialized() const { - return true; -} - -void RtpHeaderExtension::InternalSwap(RtpHeaderExtension* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(id_, other->id_); -} - -std::string RtpHeaderExtension::GetTypeName() const { - return "webrtc.rtclog.RtpHeaderExtension"; -} - - -// =================================================================== - -void RtxConfig::InitAsDefaultInstance() { -} -class RtxConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_rtx_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_rtx_payload_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -RtxConfig::RtxConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.RtxConfig) -} -RtxConfig::RtxConfig(const RtxConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&rtx_ssrc_, &from.rtx_ssrc_, - static_cast(reinterpret_cast(&rtx_payload_type_) - - reinterpret_cast(&rtx_ssrc_)) + sizeof(rtx_payload_type_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.RtxConfig) -} - -void RtxConfig::SharedCtor() { - ::memset(&rtx_ssrc_, 0, static_cast( - reinterpret_cast(&rtx_payload_type_) - - reinterpret_cast(&rtx_ssrc_)) + sizeof(rtx_payload_type_)); -} - -RtxConfig::~RtxConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.RtxConfig) - SharedDtor(); -} - -void RtxConfig::SharedDtor() { -} - -void RtxConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const RtxConfig& RtxConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_RtxConfig_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void RtxConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.RtxConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - ::memset(&rtx_ssrc_, 0, static_cast( - reinterpret_cast(&rtx_payload_type_) - - reinterpret_cast(&rtx_ssrc_)) + sizeof(rtx_payload_type_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* RtxConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional uint32 rtx_ssrc = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_rtx_ssrc(&has_bits); - rtx_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 rtx_payload_type = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_rtx_payload_type(&has_bits); - rtx_payload_type_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool RtxConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.RtxConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional uint32 rtx_ssrc = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_rtx_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &rtx_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 rtx_payload_type = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_rtx_payload_type(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &rtx_payload_type_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.RtxConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.RtxConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void RtxConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.RtxConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional uint32 rtx_ssrc = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(1, this->rtx_ssrc(), output); - } - - // optional int32 rtx_payload_type = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->rtx_payload_type(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.RtxConfig) -} - -size_t RtxConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.RtxConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional uint32 rtx_ssrc = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->rtx_ssrc()); - } - - // optional int32 rtx_payload_type = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->rtx_payload_type()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void RtxConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void RtxConfig::MergeFrom(const RtxConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.RtxConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - rtx_ssrc_ = from.rtx_ssrc_; - } - if (cached_has_bits & 0x00000002u) { - rtx_payload_type_ = from.rtx_payload_type_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void RtxConfig::CopyFrom(const RtxConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.RtxConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RtxConfig::IsInitialized() const { - return true; -} - -void RtxConfig::InternalSwap(RtxConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(rtx_ssrc_, other->rtx_ssrc_); - swap(rtx_payload_type_, other->rtx_payload_type_); -} - -std::string RtxConfig::GetTypeName() const { - return "webrtc.rtclog.RtxConfig"; -} - - -// =================================================================== - -void RtxMap::InitAsDefaultInstance() { - ::webrtc::rtclog::_RtxMap_default_instance_._instance.get_mutable()->config_ = const_cast< ::webrtc::rtclog::RtxConfig*>( - ::webrtc::rtclog::RtxConfig::internal_default_instance()); -} -class RtxMap::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_payload_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static const ::webrtc::rtclog::RtxConfig& config(const RtxMap* msg); - static void set_has_config(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -const ::webrtc::rtclog::RtxConfig& -RtxMap::_Internal::config(const RtxMap* msg) { - return *msg->config_; -} -RtxMap::RtxMap() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.RtxMap) -} -RtxMap::RtxMap(const RtxMap& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from.has_config()) { - config_ = new ::webrtc::rtclog::RtxConfig(*from.config_); - } else { - config_ = nullptr; - } - payload_type_ = from.payload_type_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.RtxMap) -} - -void RtxMap::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_RtxMap_rtc_5fevent_5flog_2eproto.base); - ::memset(&config_, 0, static_cast( - reinterpret_cast(&payload_type_) - - reinterpret_cast(&config_)) + sizeof(payload_type_)); -} - -RtxMap::~RtxMap() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.RtxMap) - SharedDtor(); -} - -void RtxMap::SharedDtor() { - if (this != internal_default_instance()) delete config_; -} - -void RtxMap::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const RtxMap& RtxMap::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_RtxMap_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void RtxMap::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.RtxMap) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(config_ != nullptr); - config_->Clear(); - } - payload_type_ = 0; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* RtxMap::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int32 payload_type = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_payload_type(&has_bits); - payload_type_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.RtxConfig config = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) { - ptr = ctx->ParseMessage(mutable_config(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool RtxMap::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.RtxMap) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int32 payload_type = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_payload_type(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &payload_type_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.RtxConfig config = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (18 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_config())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.RtxMap) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.RtxMap) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void RtxMap::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.RtxMap) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int32 payload_type = 1; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(1, this->payload_type(), output); - } - - // optional .webrtc.rtclog.RtxConfig config = 2; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 2, _Internal::config(this), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.RtxMap) -} - -size_t RtxMap::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.RtxMap) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional .webrtc.rtclog.RtxConfig config = 2; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *config_); - } - - // optional int32 payload_type = 1; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->payload_type()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void RtxMap::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void RtxMap::MergeFrom(const RtxMap& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.RtxMap) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - mutable_config()->::webrtc::rtclog::RtxConfig::MergeFrom(from.config()); - } - if (cached_has_bits & 0x00000002u) { - payload_type_ = from.payload_type_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void RtxMap::CopyFrom(const RtxMap& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.RtxMap) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RtxMap::IsInitialized() const { - return true; -} - -void RtxMap::InternalSwap(RtxMap* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(config_, other->config_); - swap(payload_type_, other->payload_type_); -} - -std::string RtxMap::GetTypeName() const { - return "webrtc.rtclog.RtxMap"; -} - - -// =================================================================== - -void VideoSendConfig::InitAsDefaultInstance() { - ::webrtc::rtclog::_VideoSendConfig_default_instance_._instance.get_mutable()->encoder_ = const_cast< ::webrtc::rtclog::EncoderConfig*>( - ::webrtc::rtclog::EncoderConfig::internal_default_instance()); -} -class VideoSendConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_rtx_payload_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static const ::webrtc::rtclog::EncoderConfig& encoder(const VideoSendConfig* msg); - static void set_has_encoder(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -const ::webrtc::rtclog::EncoderConfig& -VideoSendConfig::_Internal::encoder(const VideoSendConfig* msg) { - return *msg->encoder_; -} -VideoSendConfig::VideoSendConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.VideoSendConfig) -} -VideoSendConfig::VideoSendConfig(const VideoSendConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), - ssrcs_(from.ssrcs_), - header_extensions_(from.header_extensions_), - rtx_ssrcs_(from.rtx_ssrcs_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from.has_encoder()) { - encoder_ = new ::webrtc::rtclog::EncoderConfig(*from.encoder_); - } else { - encoder_ = nullptr; - } - rtx_payload_type_ = from.rtx_payload_type_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.VideoSendConfig) -} - -void VideoSendConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_VideoSendConfig_rtc_5fevent_5flog_2eproto.base); - ::memset(&encoder_, 0, static_cast( - reinterpret_cast(&rtx_payload_type_) - - reinterpret_cast(&encoder_)) + sizeof(rtx_payload_type_)); -} - -VideoSendConfig::~VideoSendConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.VideoSendConfig) - SharedDtor(); -} - -void VideoSendConfig::SharedDtor() { - if (this != internal_default_instance()) delete encoder_; -} - -void VideoSendConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const VideoSendConfig& VideoSendConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_VideoSendConfig_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void VideoSendConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.VideoSendConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - ssrcs_.Clear(); - header_extensions_.Clear(); - rtx_ssrcs_.Clear(); - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(encoder_ != nullptr); - encoder_->Clear(); - } - rtx_payload_type_ = 0; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* VideoSendConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // repeated uint32 ssrcs = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - ptr -= 1; - do { - ptr += 1; - add_ssrcs(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr)); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 8); - } else if (static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedUInt32Parser(mutable_ssrcs(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_header_extensions(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 18); - } else goto handle_unusual; - continue; - // repeated uint32 rtx_ssrcs = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - ptr -= 1; - do { - ptr += 1; - add_rtx_ssrcs(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr)); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 24); - } else if (static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedUInt32Parser(mutable_rtx_ssrcs(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 rtx_payload_type = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_rtx_payload_type(&has_bits); - rtx_payload_type_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.EncoderConfig encoder = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ctx->ParseMessage(mutable_encoder(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool VideoSendConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.VideoSendConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated uint32 ssrcs = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadRepeatedPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - 1, 8u, input, this->mutable_ssrcs()))); - } else if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (10 & 0xFF)) { - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPackedPrimitiveNoInline< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, this->mutable_ssrcs()))); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (18 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_header_extensions())); - } else { - goto handle_unusual; - } - break; - } - - // repeated uint32 rtx_ssrcs = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadRepeatedPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - 1, 24u, input, this->mutable_rtx_ssrcs()))); - } else if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (26 & 0xFF)) { - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPackedPrimitiveNoInline< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, this->mutable_rtx_ssrcs()))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 rtx_payload_type = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_rtx_payload_type(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &rtx_payload_type_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.EncoderConfig encoder = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (42 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_encoder())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.VideoSendConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.VideoSendConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void VideoSendConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.VideoSendConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // repeated uint32 ssrcs = 1; - for (int i = 0, n = this->ssrcs_size(); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32( - 1, this->ssrcs(i), output); - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - for (unsigned int i = 0, - n = static_cast(this->header_extensions_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 2, - this->header_extensions(static_cast(i)), - output); - } - - // repeated uint32 rtx_ssrcs = 3; - for (int i = 0, n = this->rtx_ssrcs_size(); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32( - 3, this->rtx_ssrcs(i), output); - } - - cached_has_bits = _has_bits_[0]; - // optional int32 rtx_payload_type = 4; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(4, this->rtx_payload_type(), output); - } - - // optional .webrtc.rtclog.EncoderConfig encoder = 5; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 5, _Internal::encoder(this), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.VideoSendConfig) -} - -size_t VideoSendConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.VideoSendConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // repeated uint32 ssrcs = 1; - { - size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - UInt32Size(this->ssrcs_); - total_size += 1 * - ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->ssrcs_size()); - total_size += data_size; - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - { - unsigned int count = static_cast(this->header_extensions_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->header_extensions(static_cast(i))); - } - } - - // repeated uint32 rtx_ssrcs = 3; - { - size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - UInt32Size(this->rtx_ssrcs_); - total_size += 1 * - ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->rtx_ssrcs_size()); - total_size += data_size; - } - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional .webrtc.rtclog.EncoderConfig encoder = 5; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *encoder_); - } - - // optional int32 rtx_payload_type = 4; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->rtx_payload_type()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void VideoSendConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void VideoSendConfig::MergeFrom(const VideoSendConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.VideoSendConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - ssrcs_.MergeFrom(from.ssrcs_); - header_extensions_.MergeFrom(from.header_extensions_); - rtx_ssrcs_.MergeFrom(from.rtx_ssrcs_); - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - mutable_encoder()->::webrtc::rtclog::EncoderConfig::MergeFrom(from.encoder()); - } - if (cached_has_bits & 0x00000002u) { - rtx_payload_type_ = from.rtx_payload_type_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void VideoSendConfig::CopyFrom(const VideoSendConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.VideoSendConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool VideoSendConfig::IsInitialized() const { - return true; -} - -void VideoSendConfig::InternalSwap(VideoSendConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - ssrcs_.InternalSwap(&other->ssrcs_); - CastToBase(&header_extensions_)->InternalSwap(CastToBase(&other->header_extensions_)); - rtx_ssrcs_.InternalSwap(&other->rtx_ssrcs_); - swap(encoder_, other->encoder_); - swap(rtx_payload_type_, other->rtx_payload_type_); -} - -std::string VideoSendConfig::GetTypeName() const { - return "webrtc.rtclog.VideoSendConfig"; -} - - -// =================================================================== - -void EncoderConfig::InitAsDefaultInstance() { -} -class EncoderConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_payload_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -EncoderConfig::EncoderConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.EncoderConfig) -} -EncoderConfig::EncoderConfig(const EncoderConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_name()) { - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); - } - payload_type_ = from.payload_type_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.EncoderConfig) -} - -void EncoderConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_EncoderConfig_rtc_5fevent_5flog_2eproto.base); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_type_ = 0; -} - -EncoderConfig::~EncoderConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.EncoderConfig) - SharedDtor(); -} - -void EncoderConfig::SharedDtor() { - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void EncoderConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const EncoderConfig& EncoderConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_EncoderConfig_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void EncoderConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.EncoderConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - name_.ClearNonDefaultToEmptyNoArena(); - } - payload_type_ = 0; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* EncoderConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional string name = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_name(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 payload_type = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_payload_type(&has_bits); - payload_type_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool EncoderConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.EncoderConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (10 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 payload_type = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_payload_type(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &payload_type_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.EncoderConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.EncoderConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void EncoderConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.EncoderConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - // optional int32 payload_type = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->payload_type(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.EncoderConfig) -} - -size_t EncoderConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.EncoderConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional int32 payload_type = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->payload_type()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void EncoderConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void EncoderConfig::MergeFrom(const EncoderConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.EncoderConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); - } - if (cached_has_bits & 0x00000002u) { - payload_type_ = from.payload_type_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void EncoderConfig::CopyFrom(const EncoderConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.EncoderConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EncoderConfig::IsInitialized() const { - return true; -} - -void EncoderConfig::InternalSwap(EncoderConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(payload_type_, other->payload_type_); -} - -std::string EncoderConfig::GetTypeName() const { - return "webrtc.rtclog.EncoderConfig"; -} - - -// =================================================================== - -void AudioReceiveConfig::InitAsDefaultInstance() { -} -class AudioReceiveConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_remote_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_local_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -AudioReceiveConfig::AudioReceiveConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.AudioReceiveConfig) -} -AudioReceiveConfig::AudioReceiveConfig(const AudioReceiveConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), - header_extensions_(from.header_extensions_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&remote_ssrc_, &from.remote_ssrc_, - static_cast(reinterpret_cast(&local_ssrc_) - - reinterpret_cast(&remote_ssrc_)) + sizeof(local_ssrc_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.AudioReceiveConfig) -} - -void AudioReceiveConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_AudioReceiveConfig_rtc_5fevent_5flog_2eproto.base); - ::memset(&remote_ssrc_, 0, static_cast( - reinterpret_cast(&local_ssrc_) - - reinterpret_cast(&remote_ssrc_)) + sizeof(local_ssrc_)); -} - -AudioReceiveConfig::~AudioReceiveConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.AudioReceiveConfig) - SharedDtor(); -} - -void AudioReceiveConfig::SharedDtor() { -} - -void AudioReceiveConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AudioReceiveConfig& AudioReceiveConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AudioReceiveConfig_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void AudioReceiveConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.AudioReceiveConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - header_extensions_.Clear(); - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - ::memset(&remote_ssrc_, 0, static_cast( - reinterpret_cast(&local_ssrc_) - - reinterpret_cast(&remote_ssrc_)) + sizeof(local_ssrc_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AudioReceiveConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional uint32 remote_ssrc = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_remote_ssrc(&has_bits); - remote_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 local_ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_local_ssrc(&has_bits); - local_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_header_extensions(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 26); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AudioReceiveConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.AudioReceiveConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional uint32 remote_ssrc = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_remote_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &remote_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 local_ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_local_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &local_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (26 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_header_extensions())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.AudioReceiveConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.AudioReceiveConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AudioReceiveConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.AudioReceiveConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional uint32 remote_ssrc = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(1, this->remote_ssrc(), output); - } - - // optional uint32 local_ssrc = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->local_ssrc(), output); - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 3; - for (unsigned int i = 0, - n = static_cast(this->header_extensions_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 3, - this->header_extensions(static_cast(i)), - output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.AudioReceiveConfig) -} - -size_t AudioReceiveConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.AudioReceiveConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 3; - { - unsigned int count = static_cast(this->header_extensions_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->header_extensions(static_cast(i))); - } - } - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional uint32 remote_ssrc = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->remote_ssrc()); - } - - // optional uint32 local_ssrc = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->local_ssrc()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AudioReceiveConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AudioReceiveConfig::MergeFrom(const AudioReceiveConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.AudioReceiveConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - header_extensions_.MergeFrom(from.header_extensions_); - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - remote_ssrc_ = from.remote_ssrc_; - } - if (cached_has_bits & 0x00000002u) { - local_ssrc_ = from.local_ssrc_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void AudioReceiveConfig::CopyFrom(const AudioReceiveConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.AudioReceiveConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AudioReceiveConfig::IsInitialized() const { - return true; -} - -void AudioReceiveConfig::InternalSwap(AudioReceiveConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - CastToBase(&header_extensions_)->InternalSwap(CastToBase(&other->header_extensions_)); - swap(remote_ssrc_, other->remote_ssrc_); - swap(local_ssrc_, other->local_ssrc_); -} - -std::string AudioReceiveConfig::GetTypeName() const { - return "webrtc.rtclog.AudioReceiveConfig"; -} - - -// =================================================================== - -void AudioSendConfig::InitAsDefaultInstance() { -} -class AudioSendConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -AudioSendConfig::AudioSendConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.AudioSendConfig) -} -AudioSendConfig::AudioSendConfig(const AudioSendConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), - header_extensions_(from.header_extensions_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ssrc_ = from.ssrc_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.AudioSendConfig) -} - -void AudioSendConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_AudioSendConfig_rtc_5fevent_5flog_2eproto.base); - ssrc_ = 0u; -} - -AudioSendConfig::~AudioSendConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.AudioSendConfig) - SharedDtor(); -} - -void AudioSendConfig::SharedDtor() { -} - -void AudioSendConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AudioSendConfig& AudioSendConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AudioSendConfig_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void AudioSendConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.AudioSendConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - header_extensions_.Clear(); - ssrc_ = 0u; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AudioSendConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional uint32 ssrc = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_ssrc(&has_bits); - ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_header_extensions(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 18); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AudioSendConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.AudioSendConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional uint32 ssrc = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (18 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_header_extensions())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.AudioSendConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.AudioSendConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AudioSendConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.AudioSendConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional uint32 ssrc = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(1, this->ssrc(), output); - } - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - for (unsigned int i = 0, - n = static_cast(this->header_extensions_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 2, - this->header_extensions(static_cast(i)), - output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.AudioSendConfig) -} - -size_t AudioSendConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.AudioSendConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - { - unsigned int count = static_cast(this->header_extensions_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->header_extensions(static_cast(i))); - } - } - - // optional uint32 ssrc = 1; - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->ssrc()); - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AudioSendConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AudioSendConfig::MergeFrom(const AudioSendConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.AudioSendConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - header_extensions_.MergeFrom(from.header_extensions_); - if (from.has_ssrc()) { - set_ssrc(from.ssrc()); - } -} - -void AudioSendConfig::CopyFrom(const AudioSendConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.AudioSendConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AudioSendConfig::IsInitialized() const { - return true; -} - -void AudioSendConfig::InternalSwap(AudioSendConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - CastToBase(&header_extensions_)->InternalSwap(CastToBase(&other->header_extensions_)); - swap(ssrc_, other->ssrc_); -} - -std::string AudioSendConfig::GetTypeName() const { - return "webrtc.rtclog.AudioSendConfig"; -} - - -// =================================================================== - -void AudioNetworkAdaptation::InitAsDefaultInstance() { -} -class AudioNetworkAdaptation::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_frame_length_ms(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_uplink_packet_loss_fraction(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_enable_fec(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_enable_dtx(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_num_channels(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } -}; - -AudioNetworkAdaptation::AudioNetworkAdaptation() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.AudioNetworkAdaptation) -} -AudioNetworkAdaptation::AudioNetworkAdaptation(const AudioNetworkAdaptation& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&bitrate_bps_, &from.bitrate_bps_, - static_cast(reinterpret_cast(&num_channels_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(num_channels_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.AudioNetworkAdaptation) -} - -void AudioNetworkAdaptation::SharedCtor() { - ::memset(&bitrate_bps_, 0, static_cast( - reinterpret_cast(&num_channels_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(num_channels_)); -} - -AudioNetworkAdaptation::~AudioNetworkAdaptation() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.AudioNetworkAdaptation) - SharedDtor(); -} - -void AudioNetworkAdaptation::SharedDtor() { -} - -void AudioNetworkAdaptation::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AudioNetworkAdaptation& AudioNetworkAdaptation::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AudioNetworkAdaptation_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void AudioNetworkAdaptation::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.AudioNetworkAdaptation) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { - ::memset(&bitrate_bps_, 0, static_cast( - reinterpret_cast(&num_channels_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(num_channels_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AudioNetworkAdaptation::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int32 bitrate_bps = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 frame_length_ms = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_frame_length_ms(&has_bits); - frame_length_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional float uplink_packet_loss_fraction = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 29)) { - _Internal::set_has_uplink_packet_loss_fraction(&has_bits); - uplink_packet_loss_fraction_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad(ptr); - ptr += sizeof(float); - } else goto handle_unusual; - continue; - // optional bool enable_fec = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_enable_fec(&has_bits); - enable_fec_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool enable_dtx = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - _Internal::set_has_enable_dtx(&has_bits); - enable_dtx_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 num_channels = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 48)) { - _Internal::set_has_num_channels(&has_bits); - num_channels_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AudioNetworkAdaptation::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.AudioNetworkAdaptation) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int32 bitrate_bps = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 frame_length_ms = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_frame_length_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &frame_length_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional float uplink_packet_loss_fraction = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (29 & 0xFF)) { - _Internal::set_has_uplink_packet_loss_fraction(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - float, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_FLOAT>( - input, &uplink_packet_loss_fraction_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool enable_fec = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_enable_fec(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &enable_fec_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool enable_dtx = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - _Internal::set_has_enable_dtx(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &enable_dtx_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 num_channels = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (48 & 0xFF)) { - _Internal::set_has_num_channels(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &num_channels_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.AudioNetworkAdaptation) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.AudioNetworkAdaptation) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AudioNetworkAdaptation::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.AudioNetworkAdaptation) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int32 bitrate_bps = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(1, this->bitrate_bps(), output); - } - - // optional int32 frame_length_ms = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->frame_length_ms(), output); - } - - // optional float uplink_packet_loss_fraction = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFloat(3, this->uplink_packet_loss_fraction(), output); - } - - // optional bool enable_fec = 4; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(4, this->enable_fec(), output); - } - - // optional bool enable_dtx = 5; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(5, this->enable_dtx(), output); - } - - // optional uint32 num_channels = 6; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(6, this->num_channels(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.AudioNetworkAdaptation) -} - -size_t AudioNetworkAdaptation::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.AudioNetworkAdaptation) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { - // optional int32 bitrate_bps = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->bitrate_bps()); - } - - // optional int32 frame_length_ms = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->frame_length_ms()); - } - - // optional float uplink_packet_loss_fraction = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + 4; - } - - // optional bool enable_fec = 4; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + 1; - } - - // optional bool enable_dtx = 5; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + 1; - } - - // optional uint32 num_channels = 6; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->num_channels()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AudioNetworkAdaptation::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AudioNetworkAdaptation::MergeFrom(const AudioNetworkAdaptation& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.AudioNetworkAdaptation) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { - if (cached_has_bits & 0x00000001u) { - bitrate_bps_ = from.bitrate_bps_; - } - if (cached_has_bits & 0x00000002u) { - frame_length_ms_ = from.frame_length_ms_; - } - if (cached_has_bits & 0x00000004u) { - uplink_packet_loss_fraction_ = from.uplink_packet_loss_fraction_; - } - if (cached_has_bits & 0x00000008u) { - enable_fec_ = from.enable_fec_; - } - if (cached_has_bits & 0x00000010u) { - enable_dtx_ = from.enable_dtx_; - } - if (cached_has_bits & 0x00000020u) { - num_channels_ = from.num_channels_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void AudioNetworkAdaptation::CopyFrom(const AudioNetworkAdaptation& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.AudioNetworkAdaptation) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AudioNetworkAdaptation::IsInitialized() const { - return true; -} - -void AudioNetworkAdaptation::InternalSwap(AudioNetworkAdaptation* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(bitrate_bps_, other->bitrate_bps_); - swap(frame_length_ms_, other->frame_length_ms_); - swap(uplink_packet_loss_fraction_, other->uplink_packet_loss_fraction_); - swap(enable_fec_, other->enable_fec_); - swap(enable_dtx_, other->enable_dtx_); - swap(num_channels_, other->num_channels_); -} - -std::string AudioNetworkAdaptation::GetTypeName() const { - return "webrtc.rtclog.AudioNetworkAdaptation"; -} - - -// =================================================================== - -void BweProbeCluster::InitAsDefaultInstance() { -} -class BweProbeCluster::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_id(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_min_packets(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_min_bytes(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } -}; - -BweProbeCluster::BweProbeCluster() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.BweProbeCluster) -} -BweProbeCluster::BweProbeCluster(const BweProbeCluster& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&id_, &from.id_, - static_cast(reinterpret_cast(&min_bytes_) - - reinterpret_cast(&id_)) + sizeof(min_bytes_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.BweProbeCluster) -} - -void BweProbeCluster::SharedCtor() { - ::memset(&id_, 0, static_cast( - reinterpret_cast(&min_bytes_) - - reinterpret_cast(&id_)) + sizeof(min_bytes_)); -} - -BweProbeCluster::~BweProbeCluster() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.BweProbeCluster) - SharedDtor(); -} - -void BweProbeCluster::SharedDtor() { -} - -void BweProbeCluster::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const BweProbeCluster& BweProbeCluster::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_BweProbeCluster_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void BweProbeCluster::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.BweProbeCluster) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - ::memset(&id_, 0, static_cast( - reinterpret_cast(&min_bytes_) - - reinterpret_cast(&id_)) + sizeof(min_bytes_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* BweProbeCluster::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int32 id = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_id(&has_bits); - id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 bitrate_bps = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 min_packets = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_min_packets(&has_bits); - min_packets_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 min_bytes = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_min_bytes(&has_bits); - min_bytes_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool BweProbeCluster::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.BweProbeCluster) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int32 id = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 bitrate_bps = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 min_packets = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_min_packets(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &min_packets_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 min_bytes = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_min_bytes(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &min_bytes_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.BweProbeCluster) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.BweProbeCluster) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void BweProbeCluster::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.BweProbeCluster) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int32 id = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(1, this->id(), output); - } - - // optional int32 bitrate_bps = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->bitrate_bps(), output); - } - - // optional uint32 min_packets = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->min_packets(), output); - } - - // optional uint32 min_bytes = 4; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->min_bytes(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.BweProbeCluster) -} - -size_t BweProbeCluster::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.BweProbeCluster) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - // optional int32 id = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->id()); - } - - // optional int32 bitrate_bps = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->bitrate_bps()); - } - - // optional uint32 min_packets = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->min_packets()); - } - - // optional uint32 min_bytes = 4; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->min_bytes()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void BweProbeCluster::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void BweProbeCluster::MergeFrom(const BweProbeCluster& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.BweProbeCluster) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - if (cached_has_bits & 0x00000001u) { - id_ = from.id_; - } - if (cached_has_bits & 0x00000002u) { - bitrate_bps_ = from.bitrate_bps_; - } - if (cached_has_bits & 0x00000004u) { - min_packets_ = from.min_packets_; - } - if (cached_has_bits & 0x00000008u) { - min_bytes_ = from.min_bytes_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void BweProbeCluster::CopyFrom(const BweProbeCluster& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.BweProbeCluster) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool BweProbeCluster::IsInitialized() const { - return true; -} - -void BweProbeCluster::InternalSwap(BweProbeCluster* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(id_, other->id_); - swap(bitrate_bps_, other->bitrate_bps_); - swap(min_packets_, other->min_packets_); - swap(min_bytes_, other->min_bytes_); -} - -std::string BweProbeCluster::GetTypeName() const { - return "webrtc.rtclog.BweProbeCluster"; -} - - -// =================================================================== - -void BweProbeResult::InitAsDefaultInstance() { -} -class BweProbeResult::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_id(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_result(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -BweProbeResult::BweProbeResult() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.BweProbeResult) -} -BweProbeResult::BweProbeResult(const BweProbeResult& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&id_, &from.id_, - static_cast(reinterpret_cast(&bitrate_bps_) - - reinterpret_cast(&id_)) + sizeof(bitrate_bps_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.BweProbeResult) -} - -void BweProbeResult::SharedCtor() { - ::memset(&id_, 0, static_cast( - reinterpret_cast(&bitrate_bps_) - - reinterpret_cast(&id_)) + sizeof(bitrate_bps_)); -} - -BweProbeResult::~BweProbeResult() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.BweProbeResult) - SharedDtor(); -} - -void BweProbeResult::SharedDtor() { -} - -void BweProbeResult::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const BweProbeResult& BweProbeResult::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_BweProbeResult_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void BweProbeResult::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.BweProbeResult) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - ::memset(&id_, 0, static_cast( - reinterpret_cast(&bitrate_bps_) - - reinterpret_cast(&id_)) + sizeof(bitrate_bps_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* BweProbeResult::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int32 id = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_id(&has_bits); - id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.BweProbeResult.ResultType result = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::BweProbeResult_ResultType_IsValid(val))) { - set_result(static_cast<::webrtc::rtclog::BweProbeResult_ResultType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(2, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional int32 bitrate_bps = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool BweProbeResult::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.BweProbeResult) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int32 id = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.BweProbeResult.ResultType result = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::BweProbeResult_ResultType_IsValid(value)) { - set_result(static_cast< ::webrtc::rtclog::BweProbeResult_ResultType >(value)); - } else { - unknown_fields_stream.WriteVarint32(16u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional int32 bitrate_bps = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.BweProbeResult) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.BweProbeResult) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void BweProbeResult::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.BweProbeResult) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int32 id = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(1, this->id(), output); - } - - // optional .webrtc.rtclog.BweProbeResult.ResultType result = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 2, this->result(), output); - } - - // optional int32 bitrate_bps = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(3, this->bitrate_bps(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.BweProbeResult) -} - -size_t BweProbeResult::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.BweProbeResult) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - // optional int32 id = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->id()); - } - - // optional .webrtc.rtclog.BweProbeResult.ResultType result = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->result()); - } - - // optional int32 bitrate_bps = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->bitrate_bps()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void BweProbeResult::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void BweProbeResult::MergeFrom(const BweProbeResult& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.BweProbeResult) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - id_ = from.id_; - } - if (cached_has_bits & 0x00000002u) { - result_ = from.result_; - } - if (cached_has_bits & 0x00000004u) { - bitrate_bps_ = from.bitrate_bps_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void BweProbeResult::CopyFrom(const BweProbeResult& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.BweProbeResult) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool BweProbeResult::IsInitialized() const { - return true; -} - -void BweProbeResult::InternalSwap(BweProbeResult* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(id_, other->id_); - swap(result_, other->result_); - swap(bitrate_bps_, other->bitrate_bps_); -} - -std::string BweProbeResult::GetTypeName() const { - return "webrtc.rtclog.BweProbeResult"; -} - - -// =================================================================== - -void AlrState::InitAsDefaultInstance() { -} -class AlrState::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_in_alr(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -AlrState::AlrState() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.AlrState) -} -AlrState::AlrState(const AlrState& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - in_alr_ = from.in_alr_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.AlrState) -} - -void AlrState::SharedCtor() { - in_alr_ = false; -} - -AlrState::~AlrState() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.AlrState) - SharedDtor(); -} - -void AlrState::SharedDtor() { -} - -void AlrState::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AlrState& AlrState::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AlrState_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void AlrState::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.AlrState) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - in_alr_ = false; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AlrState::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional bool in_alr = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_in_alr(&has_bits); - in_alr_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AlrState::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.AlrState) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional bool in_alr = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_in_alr(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &in_alr_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.AlrState) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.AlrState) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AlrState::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.AlrState) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional bool in_alr = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(1, this->in_alr(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.AlrState) -} - -size_t AlrState::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.AlrState) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // optional bool in_alr = 1; - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + 1; - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AlrState::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AlrState::MergeFrom(const AlrState& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.AlrState) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - if (from.has_in_alr()) { - set_in_alr(from.in_alr()); - } -} - -void AlrState::CopyFrom(const AlrState& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.AlrState) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AlrState::IsInitialized() const { - return true; -} - -void AlrState::InternalSwap(AlrState* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(in_alr_, other->in_alr_); -} - -std::string AlrState::GetTypeName() const { - return "webrtc.rtclog.AlrState"; -} - - -// =================================================================== - -void IceCandidatePairConfig::InitAsDefaultInstance() { -} -class IceCandidatePairConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_config_type(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_candidate_pair_id(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_local_candidate_type(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_local_relay_protocol(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_local_network_type(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_local_address_family(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_remote_candidate_type(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_remote_address_family(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_candidate_pair_protocol(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } -}; - -IceCandidatePairConfig::IceCandidatePairConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.IceCandidatePairConfig) -} -IceCandidatePairConfig::IceCandidatePairConfig(const IceCandidatePairConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&config_type_, &from.config_type_, - static_cast(reinterpret_cast(&candidate_pair_protocol_) - - reinterpret_cast(&config_type_)) + sizeof(candidate_pair_protocol_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.IceCandidatePairConfig) -} - -void IceCandidatePairConfig::SharedCtor() { - ::memset(&config_type_, 0, static_cast( - reinterpret_cast(&candidate_pair_protocol_) - - reinterpret_cast(&config_type_)) + sizeof(candidate_pair_protocol_)); -} - -IceCandidatePairConfig::~IceCandidatePairConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.IceCandidatePairConfig) - SharedDtor(); -} - -void IceCandidatePairConfig::SharedDtor() { -} - -void IceCandidatePairConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const IceCandidatePairConfig& IceCandidatePairConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_IceCandidatePairConfig_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void IceCandidatePairConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.IceCandidatePairConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - ::memset(&config_type_, 0, static_cast( - reinterpret_cast(&remote_address_family_) - - reinterpret_cast(&config_type_)) + sizeof(remote_address_family_)); - } - candidate_pair_protocol_ = 0; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* IceCandidatePairConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(val))) { - set_config_type(static_cast<::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(1, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional uint32 candidate_pair_id = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_candidate_pair_id(&has_bits); - candidate_pair_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType local_candidate_type = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType_IsValid(val))) { - set_local_candidate_type(static_cast<::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(3, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol local_relay_protocol = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairConfig_Protocol_IsValid(val))) { - set_local_relay_protocol(static_cast<::webrtc::rtclog::IceCandidatePairConfig_Protocol>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(4, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairConfig.NetworkType local_network_type = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairConfig_NetworkType_IsValid(val))) { - set_local_network_type(static_cast<::webrtc::rtclog::IceCandidatePairConfig_NetworkType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(5, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily local_address_family = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 48)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairConfig_AddressFamily_IsValid(val))) { - set_local_address_family(static_cast<::webrtc::rtclog::IceCandidatePairConfig_AddressFamily>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(6, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 7; - case 7: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 56)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType_IsValid(val))) { - set_remote_candidate_type(static_cast<::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(7, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily remote_address_family = 8; - case 8: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 64)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairConfig_AddressFamily_IsValid(val))) { - set_remote_address_family(static_cast<::webrtc::rtclog::IceCandidatePairConfig_AddressFamily>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(8, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol candidate_pair_protocol = 9; - case 9: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 72)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairConfig_Protocol_IsValid(val))) { - set_candidate_pair_protocol(static_cast<::webrtc::rtclog::IceCandidatePairConfig_Protocol>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(9, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool IceCandidatePairConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.IceCandidatePairConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(value)) { - set_config_type(static_cast< ::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType >(value)); - } else { - unknown_fields_stream.WriteVarint32(8u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 candidate_pair_id = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_candidate_pair_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &candidate_pair_id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType local_candidate_type = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType_IsValid(value)) { - set_local_candidate_type(static_cast< ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType >(value)); - } else { - unknown_fields_stream.WriteVarint32(24u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol local_relay_protocol = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairConfig_Protocol_IsValid(value)) { - set_local_relay_protocol(static_cast< ::webrtc::rtclog::IceCandidatePairConfig_Protocol >(value)); - } else { - unknown_fields_stream.WriteVarint32(32u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.NetworkType local_network_type = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairConfig_NetworkType_IsValid(value)) { - set_local_network_type(static_cast< ::webrtc::rtclog::IceCandidatePairConfig_NetworkType >(value)); - } else { - unknown_fields_stream.WriteVarint32(40u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily local_address_family = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (48 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairConfig_AddressFamily_IsValid(value)) { - set_local_address_family(static_cast< ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily >(value)); - } else { - unknown_fields_stream.WriteVarint32(48u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 7; - case 7: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (56 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType_IsValid(value)) { - set_remote_candidate_type(static_cast< ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType >(value)); - } else { - unknown_fields_stream.WriteVarint32(56u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily remote_address_family = 8; - case 8: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (64 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairConfig_AddressFamily_IsValid(value)) { - set_remote_address_family(static_cast< ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily >(value)); - } else { - unknown_fields_stream.WriteVarint32(64u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol candidate_pair_protocol = 9; - case 9: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (72 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairConfig_Protocol_IsValid(value)) { - set_candidate_pair_protocol(static_cast< ::webrtc::rtclog::IceCandidatePairConfig_Protocol >(value)); - } else { - unknown_fields_stream.WriteVarint32(72u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.IceCandidatePairConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.IceCandidatePairConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void IceCandidatePairConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.IceCandidatePairConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 1, this->config_type(), output); - } - - // optional uint32 candidate_pair_id = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->candidate_pair_id(), output); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType local_candidate_type = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 3, this->local_candidate_type(), output); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol local_relay_protocol = 4; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 4, this->local_relay_protocol(), output); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.NetworkType local_network_type = 5; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 5, this->local_network_type(), output); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily local_address_family = 6; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 6, this->local_address_family(), output); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 7; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 7, this->remote_candidate_type(), output); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily remote_address_family = 8; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 8, this->remote_address_family(), output); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol candidate_pair_protocol = 9; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 9, this->candidate_pair_protocol(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.IceCandidatePairConfig) -} - -size_t IceCandidatePairConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.IceCandidatePairConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->config_type()); - } - - // optional uint32 candidate_pair_id = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->candidate_pair_id()); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType local_candidate_type = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->local_candidate_type()); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol local_relay_protocol = 4; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->local_relay_protocol()); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.NetworkType local_network_type = 5; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->local_network_type()); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily local_address_family = 6; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->local_address_family()); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 7; - if (cached_has_bits & 0x00000040u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->remote_candidate_type()); - } - - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily remote_address_family = 8; - if (cached_has_bits & 0x00000080u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->remote_address_family()); - } - - } - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol candidate_pair_protocol = 9; - if (cached_has_bits & 0x00000100u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->candidate_pair_protocol()); - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void IceCandidatePairConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void IceCandidatePairConfig::MergeFrom(const IceCandidatePairConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.IceCandidatePairConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - config_type_ = from.config_type_; - } - if (cached_has_bits & 0x00000002u) { - candidate_pair_id_ = from.candidate_pair_id_; - } - if (cached_has_bits & 0x00000004u) { - local_candidate_type_ = from.local_candidate_type_; - } - if (cached_has_bits & 0x00000008u) { - local_relay_protocol_ = from.local_relay_protocol_; - } - if (cached_has_bits & 0x00000010u) { - local_network_type_ = from.local_network_type_; - } - if (cached_has_bits & 0x00000020u) { - local_address_family_ = from.local_address_family_; - } - if (cached_has_bits & 0x00000040u) { - remote_candidate_type_ = from.remote_candidate_type_; - } - if (cached_has_bits & 0x00000080u) { - remote_address_family_ = from.remote_address_family_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00000100u) { - set_candidate_pair_protocol(from.candidate_pair_protocol()); - } -} - -void IceCandidatePairConfig::CopyFrom(const IceCandidatePairConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.IceCandidatePairConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool IceCandidatePairConfig::IsInitialized() const { - return true; -} - -void IceCandidatePairConfig::InternalSwap(IceCandidatePairConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(config_type_, other->config_type_); - swap(candidate_pair_id_, other->candidate_pair_id_); - swap(local_candidate_type_, other->local_candidate_type_); - swap(local_relay_protocol_, other->local_relay_protocol_); - swap(local_network_type_, other->local_network_type_); - swap(local_address_family_, other->local_address_family_); - swap(remote_candidate_type_, other->remote_candidate_type_); - swap(remote_address_family_, other->remote_address_family_); - swap(candidate_pair_protocol_, other->candidate_pair_protocol_); -} - -std::string IceCandidatePairConfig::GetTypeName() const { - return "webrtc.rtclog.IceCandidatePairConfig"; -} - - -// =================================================================== - -void IceCandidatePairEvent::InitAsDefaultInstance() { -} -class IceCandidatePairEvent::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_event_type(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_candidate_pair_id(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -IceCandidatePairEvent::IceCandidatePairEvent() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog.IceCandidatePairEvent) -} -IceCandidatePairEvent::IceCandidatePairEvent(const IceCandidatePairEvent& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&event_type_, &from.event_type_, - static_cast(reinterpret_cast(&candidate_pair_id_) - - reinterpret_cast(&event_type_)) + sizeof(candidate_pair_id_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog.IceCandidatePairEvent) -} - -void IceCandidatePairEvent::SharedCtor() { - ::memset(&event_type_, 0, static_cast( - reinterpret_cast(&candidate_pair_id_) - - reinterpret_cast(&event_type_)) + sizeof(candidate_pair_id_)); -} - -IceCandidatePairEvent::~IceCandidatePairEvent() { - // @@protoc_insertion_point(destructor:webrtc.rtclog.IceCandidatePairEvent) - SharedDtor(); -} - -void IceCandidatePairEvent::SharedDtor() { -} - -void IceCandidatePairEvent::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const IceCandidatePairEvent& IceCandidatePairEvent::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_IceCandidatePairEvent_rtc_5fevent_5flog_2eproto.base); - return *internal_default_instance(); -} - - -void IceCandidatePairEvent::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog.IceCandidatePairEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - ::memset(&event_type_, 0, static_cast( - reinterpret_cast(&candidate_pair_id_) - - reinterpret_cast(&event_type_)) + sizeof(candidate_pair_id_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* IceCandidatePairEvent::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional .webrtc.rtclog.IceCandidatePairEvent.IceCandidatePairEventType event_type = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType_IsValid(val))) { - set_event_type(static_cast<::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(1, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional uint32 candidate_pair_id = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_candidate_pair_id(&has_bits); - candidate_pair_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool IceCandidatePairEvent::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog.IceCandidatePairEvent) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional .webrtc.rtclog.IceCandidatePairEvent.IceCandidatePairEventType event_type = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType_IsValid(value)) { - set_event_type(static_cast< ::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType >(value)); - } else { - unknown_fields_stream.WriteVarint32(8u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 candidate_pair_id = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_candidate_pair_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &candidate_pair_id_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog.IceCandidatePairEvent) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog.IceCandidatePairEvent) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void IceCandidatePairEvent::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog.IceCandidatePairEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional .webrtc.rtclog.IceCandidatePairEvent.IceCandidatePairEventType event_type = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 1, this->event_type(), output); - } - - // optional uint32 candidate_pair_id = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->candidate_pair_id(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog.IceCandidatePairEvent) -} - -size_t IceCandidatePairEvent::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog.IceCandidatePairEvent) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional .webrtc.rtclog.IceCandidatePairEvent.IceCandidatePairEventType event_type = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->event_type()); - } - - // optional uint32 candidate_pair_id = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->candidate_pair_id()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void IceCandidatePairEvent::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void IceCandidatePairEvent::MergeFrom(const IceCandidatePairEvent& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog.IceCandidatePairEvent) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - event_type_ = from.event_type_; - } - if (cached_has_bits & 0x00000002u) { - candidate_pair_id_ = from.candidate_pair_id_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void IceCandidatePairEvent::CopyFrom(const IceCandidatePairEvent& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog.IceCandidatePairEvent) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool IceCandidatePairEvent::IsInitialized() const { - return true; -} - -void IceCandidatePairEvent::InternalSwap(IceCandidatePairEvent* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(event_type_, other->event_type_); - swap(candidate_pair_id_, other->candidate_pair_id_); -} - -std::string IceCandidatePairEvent::GetTypeName() const { - return "webrtc.rtclog.IceCandidatePairEvent"; -} - - -// @@protoc_insertion_point(namespace_scope) -} // namespace rtclog -} // namespace webrtc -PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::EventStream* Arena::CreateMaybeMessage< ::webrtc::rtclog::EventStream >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::EventStream >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::Event* Arena::CreateMaybeMessage< ::webrtc::rtclog::Event >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::Event >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::RtpPacket* Arena::CreateMaybeMessage< ::webrtc::rtclog::RtpPacket >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::RtpPacket >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::RtcpPacket* Arena::CreateMaybeMessage< ::webrtc::rtclog::RtcpPacket >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::RtcpPacket >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::AudioPlayoutEvent* Arena::CreateMaybeMessage< ::webrtc::rtclog::AudioPlayoutEvent >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::AudioPlayoutEvent >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::LossBasedBweUpdate* Arena::CreateMaybeMessage< ::webrtc::rtclog::LossBasedBweUpdate >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::LossBasedBweUpdate >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::DelayBasedBweUpdate* Arena::CreateMaybeMessage< ::webrtc::rtclog::DelayBasedBweUpdate >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::DelayBasedBweUpdate >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::VideoReceiveConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog::VideoReceiveConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::VideoReceiveConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::DecoderConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog::DecoderConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::DecoderConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::RtpHeaderExtension* Arena::CreateMaybeMessage< ::webrtc::rtclog::RtpHeaderExtension >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::RtpHeaderExtension >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::RtxConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog::RtxConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::RtxConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::RtxMap* Arena::CreateMaybeMessage< ::webrtc::rtclog::RtxMap >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::RtxMap >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::VideoSendConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog::VideoSendConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::VideoSendConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::EncoderConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog::EncoderConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::EncoderConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::AudioReceiveConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog::AudioReceiveConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::AudioReceiveConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::AudioSendConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog::AudioSendConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::AudioSendConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::AudioNetworkAdaptation* Arena::CreateMaybeMessage< ::webrtc::rtclog::AudioNetworkAdaptation >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::AudioNetworkAdaptation >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::BweProbeCluster* Arena::CreateMaybeMessage< ::webrtc::rtclog::BweProbeCluster >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::BweProbeCluster >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::BweProbeResult* Arena::CreateMaybeMessage< ::webrtc::rtclog::BweProbeResult >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::BweProbeResult >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::AlrState* Arena::CreateMaybeMessage< ::webrtc::rtclog::AlrState >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::AlrState >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::IceCandidatePairConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog::IceCandidatePairConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::IceCandidatePairConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog::IceCandidatePairEvent* Arena::CreateMaybeMessage< ::webrtc::rtclog::IceCandidatePairEvent >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog::IceCandidatePairEvent >(arena); -} -PROTOBUF_NAMESPACE_CLOSE - -// @@protoc_insertion_point(global_scope) -#include diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log.pb.h b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log.pb.h deleted file mode 100644 index d92dbb608..000000000 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log.pb.h +++ /dev/null @@ -1,6496 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: rtc_event_log.proto - -#ifndef GOOGLE_PROTOBUF_INCLUDED_rtc_5fevent_5flog_2eproto -#define GOOGLE_PROTOBUF_INCLUDED_rtc_5fevent_5flog_2eproto - -#include -#include - -#include -#if PROTOBUF_VERSION < 3009000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3009000 < PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: export -#include // IWYU pragma: export -#include -// @@protoc_insertion_point(includes) -#include -#define PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog_2eproto -PROTOBUF_NAMESPACE_OPEN -namespace internal { -class AnyMetadata; -} // namespace internal -PROTOBUF_NAMESPACE_CLOSE - -// Internal implementation detail -- do not use these members. -struct TableStruct_rtc_5fevent_5flog_2eproto { - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[22] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; - static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[]; -}; -namespace webrtc { -namespace rtclog { -class AlrState; -class AlrStateDefaultTypeInternal; -extern AlrStateDefaultTypeInternal _AlrState_default_instance_; -class AudioNetworkAdaptation; -class AudioNetworkAdaptationDefaultTypeInternal; -extern AudioNetworkAdaptationDefaultTypeInternal _AudioNetworkAdaptation_default_instance_; -class AudioPlayoutEvent; -class AudioPlayoutEventDefaultTypeInternal; -extern AudioPlayoutEventDefaultTypeInternal _AudioPlayoutEvent_default_instance_; -class AudioReceiveConfig; -class AudioReceiveConfigDefaultTypeInternal; -extern AudioReceiveConfigDefaultTypeInternal _AudioReceiveConfig_default_instance_; -class AudioSendConfig; -class AudioSendConfigDefaultTypeInternal; -extern AudioSendConfigDefaultTypeInternal _AudioSendConfig_default_instance_; -class BweProbeCluster; -class BweProbeClusterDefaultTypeInternal; -extern BweProbeClusterDefaultTypeInternal _BweProbeCluster_default_instance_; -class BweProbeResult; -class BweProbeResultDefaultTypeInternal; -extern BweProbeResultDefaultTypeInternal _BweProbeResult_default_instance_; -class DecoderConfig; -class DecoderConfigDefaultTypeInternal; -extern DecoderConfigDefaultTypeInternal _DecoderConfig_default_instance_; -class DelayBasedBweUpdate; -class DelayBasedBweUpdateDefaultTypeInternal; -extern DelayBasedBweUpdateDefaultTypeInternal _DelayBasedBweUpdate_default_instance_; -class EncoderConfig; -class EncoderConfigDefaultTypeInternal; -extern EncoderConfigDefaultTypeInternal _EncoderConfig_default_instance_; -class Event; -class EventDefaultTypeInternal; -extern EventDefaultTypeInternal _Event_default_instance_; -class EventStream; -class EventStreamDefaultTypeInternal; -extern EventStreamDefaultTypeInternal _EventStream_default_instance_; -class IceCandidatePairConfig; -class IceCandidatePairConfigDefaultTypeInternal; -extern IceCandidatePairConfigDefaultTypeInternal _IceCandidatePairConfig_default_instance_; -class IceCandidatePairEvent; -class IceCandidatePairEventDefaultTypeInternal; -extern IceCandidatePairEventDefaultTypeInternal _IceCandidatePairEvent_default_instance_; -class LossBasedBweUpdate; -class LossBasedBweUpdateDefaultTypeInternal; -extern LossBasedBweUpdateDefaultTypeInternal _LossBasedBweUpdate_default_instance_; -class RtcpPacket; -class RtcpPacketDefaultTypeInternal; -extern RtcpPacketDefaultTypeInternal _RtcpPacket_default_instance_; -class RtpHeaderExtension; -class RtpHeaderExtensionDefaultTypeInternal; -extern RtpHeaderExtensionDefaultTypeInternal _RtpHeaderExtension_default_instance_; -class RtpPacket; -class RtpPacketDefaultTypeInternal; -extern RtpPacketDefaultTypeInternal _RtpPacket_default_instance_; -class RtxConfig; -class RtxConfigDefaultTypeInternal; -extern RtxConfigDefaultTypeInternal _RtxConfig_default_instance_; -class RtxMap; -class RtxMapDefaultTypeInternal; -extern RtxMapDefaultTypeInternal _RtxMap_default_instance_; -class VideoReceiveConfig; -class VideoReceiveConfigDefaultTypeInternal; -extern VideoReceiveConfigDefaultTypeInternal _VideoReceiveConfig_default_instance_; -class VideoSendConfig; -class VideoSendConfigDefaultTypeInternal; -extern VideoSendConfigDefaultTypeInternal _VideoSendConfig_default_instance_; -} // namespace rtclog -} // namespace webrtc -PROTOBUF_NAMESPACE_OPEN -template<> ::webrtc::rtclog::AlrState* Arena::CreateMaybeMessage<::webrtc::rtclog::AlrState>(Arena*); -template<> ::webrtc::rtclog::AudioNetworkAdaptation* Arena::CreateMaybeMessage<::webrtc::rtclog::AudioNetworkAdaptation>(Arena*); -template<> ::webrtc::rtclog::AudioPlayoutEvent* Arena::CreateMaybeMessage<::webrtc::rtclog::AudioPlayoutEvent>(Arena*); -template<> ::webrtc::rtclog::AudioReceiveConfig* Arena::CreateMaybeMessage<::webrtc::rtclog::AudioReceiveConfig>(Arena*); -template<> ::webrtc::rtclog::AudioSendConfig* Arena::CreateMaybeMessage<::webrtc::rtclog::AudioSendConfig>(Arena*); -template<> ::webrtc::rtclog::BweProbeCluster* Arena::CreateMaybeMessage<::webrtc::rtclog::BweProbeCluster>(Arena*); -template<> ::webrtc::rtclog::BweProbeResult* Arena::CreateMaybeMessage<::webrtc::rtclog::BweProbeResult>(Arena*); -template<> ::webrtc::rtclog::DecoderConfig* Arena::CreateMaybeMessage<::webrtc::rtclog::DecoderConfig>(Arena*); -template<> ::webrtc::rtclog::DelayBasedBweUpdate* Arena::CreateMaybeMessage<::webrtc::rtclog::DelayBasedBweUpdate>(Arena*); -template<> ::webrtc::rtclog::EncoderConfig* Arena::CreateMaybeMessage<::webrtc::rtclog::EncoderConfig>(Arena*); -template<> ::webrtc::rtclog::Event* Arena::CreateMaybeMessage<::webrtc::rtclog::Event>(Arena*); -template<> ::webrtc::rtclog::EventStream* Arena::CreateMaybeMessage<::webrtc::rtclog::EventStream>(Arena*); -template<> ::webrtc::rtclog::IceCandidatePairConfig* Arena::CreateMaybeMessage<::webrtc::rtclog::IceCandidatePairConfig>(Arena*); -template<> ::webrtc::rtclog::IceCandidatePairEvent* Arena::CreateMaybeMessage<::webrtc::rtclog::IceCandidatePairEvent>(Arena*); -template<> ::webrtc::rtclog::LossBasedBweUpdate* Arena::CreateMaybeMessage<::webrtc::rtclog::LossBasedBweUpdate>(Arena*); -template<> ::webrtc::rtclog::RtcpPacket* Arena::CreateMaybeMessage<::webrtc::rtclog::RtcpPacket>(Arena*); -template<> ::webrtc::rtclog::RtpHeaderExtension* Arena::CreateMaybeMessage<::webrtc::rtclog::RtpHeaderExtension>(Arena*); -template<> ::webrtc::rtclog::RtpPacket* Arena::CreateMaybeMessage<::webrtc::rtclog::RtpPacket>(Arena*); -template<> ::webrtc::rtclog::RtxConfig* Arena::CreateMaybeMessage<::webrtc::rtclog::RtxConfig>(Arena*); -template<> ::webrtc::rtclog::RtxMap* Arena::CreateMaybeMessage<::webrtc::rtclog::RtxMap>(Arena*); -template<> ::webrtc::rtclog::VideoReceiveConfig* Arena::CreateMaybeMessage<::webrtc::rtclog::VideoReceiveConfig>(Arena*); -template<> ::webrtc::rtclog::VideoSendConfig* Arena::CreateMaybeMessage<::webrtc::rtclog::VideoSendConfig>(Arena*); -PROTOBUF_NAMESPACE_CLOSE -namespace webrtc { -namespace rtclog { - -enum Event_EventType : int { - Event_EventType_UNKNOWN_EVENT = 0, - Event_EventType_LOG_START = 1, - Event_EventType_LOG_END = 2, - Event_EventType_RTP_EVENT = 3, - Event_EventType_RTCP_EVENT = 4, - Event_EventType_AUDIO_PLAYOUT_EVENT = 5, - Event_EventType_LOSS_BASED_BWE_UPDATE = 6, - Event_EventType_DELAY_BASED_BWE_UPDATE = 7, - Event_EventType_VIDEO_RECEIVER_CONFIG_EVENT = 8, - Event_EventType_VIDEO_SENDER_CONFIG_EVENT = 9, - Event_EventType_AUDIO_RECEIVER_CONFIG_EVENT = 10, - Event_EventType_AUDIO_SENDER_CONFIG_EVENT = 11, - Event_EventType_AUDIO_NETWORK_ADAPTATION_EVENT = 16, - Event_EventType_BWE_PROBE_CLUSTER_CREATED_EVENT = 17, - Event_EventType_BWE_PROBE_RESULT_EVENT = 18, - Event_EventType_ALR_STATE_EVENT = 19, - Event_EventType_ICE_CANDIDATE_PAIR_CONFIG = 20, - Event_EventType_ICE_CANDIDATE_PAIR_EVENT = 21 -}; -bool Event_EventType_IsValid(int value); -constexpr Event_EventType Event_EventType_EventType_MIN = Event_EventType_UNKNOWN_EVENT; -constexpr Event_EventType Event_EventType_EventType_MAX = Event_EventType_ICE_CANDIDATE_PAIR_EVENT; -constexpr int Event_EventType_EventType_ARRAYSIZE = Event_EventType_EventType_MAX + 1; - -const std::string& Event_EventType_Name(Event_EventType value); -template -inline const std::string& Event_EventType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function Event_EventType_Name."); - return Event_EventType_Name(static_cast(enum_t_value)); -} -bool Event_EventType_Parse( - const std::string& name, Event_EventType* value); -enum DelayBasedBweUpdate_DetectorState : int { - DelayBasedBweUpdate_DetectorState_BWE_NORMAL = 0, - DelayBasedBweUpdate_DetectorState_BWE_UNDERUSING = 1, - DelayBasedBweUpdate_DetectorState_BWE_OVERUSING = 2 -}; -bool DelayBasedBweUpdate_DetectorState_IsValid(int value); -constexpr DelayBasedBweUpdate_DetectorState DelayBasedBweUpdate_DetectorState_DetectorState_MIN = DelayBasedBweUpdate_DetectorState_BWE_NORMAL; -constexpr DelayBasedBweUpdate_DetectorState DelayBasedBweUpdate_DetectorState_DetectorState_MAX = DelayBasedBweUpdate_DetectorState_BWE_OVERUSING; -constexpr int DelayBasedBweUpdate_DetectorState_DetectorState_ARRAYSIZE = DelayBasedBweUpdate_DetectorState_DetectorState_MAX + 1; - -const std::string& DelayBasedBweUpdate_DetectorState_Name(DelayBasedBweUpdate_DetectorState value); -template -inline const std::string& DelayBasedBweUpdate_DetectorState_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function DelayBasedBweUpdate_DetectorState_Name."); - return DelayBasedBweUpdate_DetectorState_Name(static_cast(enum_t_value)); -} -bool DelayBasedBweUpdate_DetectorState_Parse( - const std::string& name, DelayBasedBweUpdate_DetectorState* value); -enum VideoReceiveConfig_RtcpMode : int { - VideoReceiveConfig_RtcpMode_RTCP_COMPOUND = 1, - VideoReceiveConfig_RtcpMode_RTCP_REDUCEDSIZE = 2 -}; -bool VideoReceiveConfig_RtcpMode_IsValid(int value); -constexpr VideoReceiveConfig_RtcpMode VideoReceiveConfig_RtcpMode_RtcpMode_MIN = VideoReceiveConfig_RtcpMode_RTCP_COMPOUND; -constexpr VideoReceiveConfig_RtcpMode VideoReceiveConfig_RtcpMode_RtcpMode_MAX = VideoReceiveConfig_RtcpMode_RTCP_REDUCEDSIZE; -constexpr int VideoReceiveConfig_RtcpMode_RtcpMode_ARRAYSIZE = VideoReceiveConfig_RtcpMode_RtcpMode_MAX + 1; - -const std::string& VideoReceiveConfig_RtcpMode_Name(VideoReceiveConfig_RtcpMode value); -template -inline const std::string& VideoReceiveConfig_RtcpMode_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function VideoReceiveConfig_RtcpMode_Name."); - return VideoReceiveConfig_RtcpMode_Name(static_cast(enum_t_value)); -} -bool VideoReceiveConfig_RtcpMode_Parse( - const std::string& name, VideoReceiveConfig_RtcpMode* value); -enum BweProbeResult_ResultType : int { - BweProbeResult_ResultType_SUCCESS = 0, - BweProbeResult_ResultType_INVALID_SEND_RECEIVE_INTERVAL = 1, - BweProbeResult_ResultType_INVALID_SEND_RECEIVE_RATIO = 2, - BweProbeResult_ResultType_TIMEOUT = 3 -}; -bool BweProbeResult_ResultType_IsValid(int value); -constexpr BweProbeResult_ResultType BweProbeResult_ResultType_ResultType_MIN = BweProbeResult_ResultType_SUCCESS; -constexpr BweProbeResult_ResultType BweProbeResult_ResultType_ResultType_MAX = BweProbeResult_ResultType_TIMEOUT; -constexpr int BweProbeResult_ResultType_ResultType_ARRAYSIZE = BweProbeResult_ResultType_ResultType_MAX + 1; - -const std::string& BweProbeResult_ResultType_Name(BweProbeResult_ResultType value); -template -inline const std::string& BweProbeResult_ResultType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function BweProbeResult_ResultType_Name."); - return BweProbeResult_ResultType_Name(static_cast(enum_t_value)); -} -bool BweProbeResult_ResultType_Parse( - const std::string& name, BweProbeResult_ResultType* value); -enum IceCandidatePairConfig_IceCandidatePairConfigType : int { - IceCandidatePairConfig_IceCandidatePairConfigType_ADDED = 0, - IceCandidatePairConfig_IceCandidatePairConfigType_UPDATED = 1, - IceCandidatePairConfig_IceCandidatePairConfigType_DESTROYED = 2, - IceCandidatePairConfig_IceCandidatePairConfigType_SELECTED = 3 -}; -bool IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(int value); -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MIN = IceCandidatePairConfig_IceCandidatePairConfigType_ADDED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MAX = IceCandidatePairConfig_IceCandidatePairConfigType_SELECTED; -constexpr int IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_ARRAYSIZE = IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MAX + 1; - -const std::string& IceCandidatePairConfig_IceCandidatePairConfigType_Name(IceCandidatePairConfig_IceCandidatePairConfigType value); -template -inline const std::string& IceCandidatePairConfig_IceCandidatePairConfigType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_IceCandidatePairConfigType_Name."); - return IceCandidatePairConfig_IceCandidatePairConfigType_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_IceCandidatePairConfigType_Parse( - const std::string& name, IceCandidatePairConfig_IceCandidatePairConfigType* value); -enum IceCandidatePairConfig_IceCandidateType : int { - IceCandidatePairConfig_IceCandidateType_LOCAL = 0, - IceCandidatePairConfig_IceCandidateType_STUN = 1, - IceCandidatePairConfig_IceCandidateType_PRFLX = 2, - IceCandidatePairConfig_IceCandidateType_RELAY = 3, - IceCandidatePairConfig_IceCandidateType_UNKNOWN_CANDIDATE_TYPE = 4 -}; -bool IceCandidatePairConfig_IceCandidateType_IsValid(int value); -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig_IceCandidateType_IceCandidateType_MIN = IceCandidatePairConfig_IceCandidateType_LOCAL; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig_IceCandidateType_IceCandidateType_MAX = IceCandidatePairConfig_IceCandidateType_UNKNOWN_CANDIDATE_TYPE; -constexpr int IceCandidatePairConfig_IceCandidateType_IceCandidateType_ARRAYSIZE = IceCandidatePairConfig_IceCandidateType_IceCandidateType_MAX + 1; - -const std::string& IceCandidatePairConfig_IceCandidateType_Name(IceCandidatePairConfig_IceCandidateType value); -template -inline const std::string& IceCandidatePairConfig_IceCandidateType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_IceCandidateType_Name."); - return IceCandidatePairConfig_IceCandidateType_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_IceCandidateType_Parse( - const std::string& name, IceCandidatePairConfig_IceCandidateType* value); -enum IceCandidatePairConfig_Protocol : int { - IceCandidatePairConfig_Protocol_UDP = 0, - IceCandidatePairConfig_Protocol_TCP = 1, - IceCandidatePairConfig_Protocol_SSLTCP = 2, - IceCandidatePairConfig_Protocol_TLS = 3, - IceCandidatePairConfig_Protocol_UNKNOWN_PROTOCOL = 4 -}; -bool IceCandidatePairConfig_Protocol_IsValid(int value); -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig_Protocol_Protocol_MIN = IceCandidatePairConfig_Protocol_UDP; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig_Protocol_Protocol_MAX = IceCandidatePairConfig_Protocol_UNKNOWN_PROTOCOL; -constexpr int IceCandidatePairConfig_Protocol_Protocol_ARRAYSIZE = IceCandidatePairConfig_Protocol_Protocol_MAX + 1; - -const std::string& IceCandidatePairConfig_Protocol_Name(IceCandidatePairConfig_Protocol value); -template -inline const std::string& IceCandidatePairConfig_Protocol_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_Protocol_Name."); - return IceCandidatePairConfig_Protocol_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_Protocol_Parse( - const std::string& name, IceCandidatePairConfig_Protocol* value); -enum IceCandidatePairConfig_AddressFamily : int { - IceCandidatePairConfig_AddressFamily_IPV4 = 0, - IceCandidatePairConfig_AddressFamily_IPV6 = 1, - IceCandidatePairConfig_AddressFamily_UNKNOWN_ADDRESS_FAMILY = 2 -}; -bool IceCandidatePairConfig_AddressFamily_IsValid(int value); -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig_AddressFamily_AddressFamily_MIN = IceCandidatePairConfig_AddressFamily_IPV4; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig_AddressFamily_AddressFamily_MAX = IceCandidatePairConfig_AddressFamily_UNKNOWN_ADDRESS_FAMILY; -constexpr int IceCandidatePairConfig_AddressFamily_AddressFamily_ARRAYSIZE = IceCandidatePairConfig_AddressFamily_AddressFamily_MAX + 1; - -const std::string& IceCandidatePairConfig_AddressFamily_Name(IceCandidatePairConfig_AddressFamily value); -template -inline const std::string& IceCandidatePairConfig_AddressFamily_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_AddressFamily_Name."); - return IceCandidatePairConfig_AddressFamily_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_AddressFamily_Parse( - const std::string& name, IceCandidatePairConfig_AddressFamily* value); -enum IceCandidatePairConfig_NetworkType : int { - IceCandidatePairConfig_NetworkType_ETHERNET = 0, - IceCandidatePairConfig_NetworkType_LOOPBACK = 1, - IceCandidatePairConfig_NetworkType_WIFI = 2, - IceCandidatePairConfig_NetworkType_VPN = 3, - IceCandidatePairConfig_NetworkType_CELLULAR = 4, - IceCandidatePairConfig_NetworkType_UNKNOWN_NETWORK_TYPE = 5 -}; -bool IceCandidatePairConfig_NetworkType_IsValid(int value); -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig_NetworkType_NetworkType_MIN = IceCandidatePairConfig_NetworkType_ETHERNET; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig_NetworkType_NetworkType_MAX = IceCandidatePairConfig_NetworkType_UNKNOWN_NETWORK_TYPE; -constexpr int IceCandidatePairConfig_NetworkType_NetworkType_ARRAYSIZE = IceCandidatePairConfig_NetworkType_NetworkType_MAX + 1; - -const std::string& IceCandidatePairConfig_NetworkType_Name(IceCandidatePairConfig_NetworkType value); -template -inline const std::string& IceCandidatePairConfig_NetworkType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_NetworkType_Name."); - return IceCandidatePairConfig_NetworkType_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_NetworkType_Parse( - const std::string& name, IceCandidatePairConfig_NetworkType* value); -enum IceCandidatePairEvent_IceCandidatePairEventType : int { - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_SENT = 0, - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RECEIVED = 1, - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_SENT = 2, - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_RECEIVED = 3 -}; -bool IceCandidatePairEvent_IceCandidatePairEventType_IsValid(int value); -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MIN = IceCandidatePairEvent_IceCandidatePairEventType_CHECK_SENT; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MAX = IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_RECEIVED; -constexpr int IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_ARRAYSIZE = IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MAX + 1; - -const std::string& IceCandidatePairEvent_IceCandidatePairEventType_Name(IceCandidatePairEvent_IceCandidatePairEventType value); -template -inline const std::string& IceCandidatePairEvent_IceCandidatePairEventType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairEvent_IceCandidatePairEventType_Name."); - return IceCandidatePairEvent_IceCandidatePairEventType_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairEvent_IceCandidatePairEventType_Parse( - const std::string& name, IceCandidatePairEvent_IceCandidatePairEventType* value); -enum MediaType : int { - ANY = 0, - AUDIO = 1, - VIDEO = 2, - DATA = 3 -}; -bool MediaType_IsValid(int value); -constexpr MediaType MediaType_MIN = ANY; -constexpr MediaType MediaType_MAX = DATA; -constexpr int MediaType_ARRAYSIZE = MediaType_MAX + 1; - -const std::string& MediaType_Name(MediaType value); -template -inline const std::string& MediaType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function MediaType_Name."); - return MediaType_Name(static_cast(enum_t_value)); -} -bool MediaType_Parse( - const std::string& name, MediaType* value); -// =================================================================== - -class EventStream : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.EventStream) */ { - public: - EventStream(); - virtual ~EventStream(); - - EventStream(const EventStream& from); - EventStream(EventStream&& from) noexcept - : EventStream() { - *this = ::std::move(from); - } - - inline EventStream& operator=(const EventStream& from) { - CopyFrom(from); - return *this; - } - inline EventStream& operator=(EventStream&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const EventStream& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const EventStream* internal_default_instance() { - return reinterpret_cast( - &_EventStream_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(EventStream& a, EventStream& b) { - a.Swap(&b); - } - inline void Swap(EventStream* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline EventStream* New() const final { - return CreateMaybeMessage(nullptr); - } - - EventStream* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const EventStream& from); - void MergeFrom(const EventStream& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(EventStream* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.EventStream"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kStreamFieldNumber = 1, - }; - // repeated .webrtc.rtclog.Event stream = 1; - int stream_size() const; - void clear_stream(); - ::webrtc::rtclog::Event* mutable_stream(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::Event >* - mutable_stream(); - const ::webrtc::rtclog::Event& stream(int index) const; - ::webrtc::rtclog::Event* add_stream(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::Event >& - stream() const; - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.EventStream) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::Event > stream_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class Event : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.Event) */ { - public: - Event(); - virtual ~Event(); - - Event(const Event& from); - Event(Event&& from) noexcept - : Event() { - *this = ::std::move(from); - } - - inline Event& operator=(const Event& from) { - CopyFrom(from); - return *this; - } - inline Event& operator=(Event&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const Event& default_instance(); - - enum SubtypeCase { - kRtpPacket = 3, - kRtcpPacket = 4, - kAudioPlayoutEvent = 5, - kLossBasedBweUpdate = 6, - kDelayBasedBweUpdate = 7, - kVideoReceiverConfig = 8, - kVideoSenderConfig = 9, - kAudioReceiverConfig = 10, - kAudioSenderConfig = 11, - kAudioNetworkAdaptation = 16, - kProbeCluster = 17, - kProbeResult = 18, - kAlrState = 19, - kIceCandidatePairConfig = 20, - kIceCandidatePairEvent = 21, - SUBTYPE_NOT_SET = 0, - }; - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const Event* internal_default_instance() { - return reinterpret_cast( - &_Event_default_instance_); - } - static constexpr int kIndexInFileMessages = - 1; - - friend void swap(Event& a, Event& b) { - a.Swap(&b); - } - inline void Swap(Event* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline Event* New() const final { - return CreateMaybeMessage(nullptr); - } - - Event* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const Event& from); - void MergeFrom(const Event& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(Event* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.Event"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef Event_EventType EventType; - static constexpr EventType UNKNOWN_EVENT = - Event_EventType_UNKNOWN_EVENT; - static constexpr EventType LOG_START = - Event_EventType_LOG_START; - static constexpr EventType LOG_END = - Event_EventType_LOG_END; - static constexpr EventType RTP_EVENT = - Event_EventType_RTP_EVENT; - static constexpr EventType RTCP_EVENT = - Event_EventType_RTCP_EVENT; - static constexpr EventType AUDIO_PLAYOUT_EVENT = - Event_EventType_AUDIO_PLAYOUT_EVENT; - static constexpr EventType LOSS_BASED_BWE_UPDATE = - Event_EventType_LOSS_BASED_BWE_UPDATE; - static constexpr EventType DELAY_BASED_BWE_UPDATE = - Event_EventType_DELAY_BASED_BWE_UPDATE; - static constexpr EventType VIDEO_RECEIVER_CONFIG_EVENT = - Event_EventType_VIDEO_RECEIVER_CONFIG_EVENT; - static constexpr EventType VIDEO_SENDER_CONFIG_EVENT = - Event_EventType_VIDEO_SENDER_CONFIG_EVENT; - static constexpr EventType AUDIO_RECEIVER_CONFIG_EVENT = - Event_EventType_AUDIO_RECEIVER_CONFIG_EVENT; - static constexpr EventType AUDIO_SENDER_CONFIG_EVENT = - Event_EventType_AUDIO_SENDER_CONFIG_EVENT; - static constexpr EventType AUDIO_NETWORK_ADAPTATION_EVENT = - Event_EventType_AUDIO_NETWORK_ADAPTATION_EVENT; - static constexpr EventType BWE_PROBE_CLUSTER_CREATED_EVENT = - Event_EventType_BWE_PROBE_CLUSTER_CREATED_EVENT; - static constexpr EventType BWE_PROBE_RESULT_EVENT = - Event_EventType_BWE_PROBE_RESULT_EVENT; - static constexpr EventType ALR_STATE_EVENT = - Event_EventType_ALR_STATE_EVENT; - static constexpr EventType ICE_CANDIDATE_PAIR_CONFIG = - Event_EventType_ICE_CANDIDATE_PAIR_CONFIG; - static constexpr EventType ICE_CANDIDATE_PAIR_EVENT = - Event_EventType_ICE_CANDIDATE_PAIR_EVENT; - static inline bool EventType_IsValid(int value) { - return Event_EventType_IsValid(value); - } - static constexpr EventType EventType_MIN = - Event_EventType_EventType_MIN; - static constexpr EventType EventType_MAX = - Event_EventType_EventType_MAX; - static constexpr int EventType_ARRAYSIZE = - Event_EventType_EventType_ARRAYSIZE; - template - static inline const std::string& EventType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function EventType_Name."); - return Event_EventType_Name(enum_t_value); - } - static inline bool EventType_Parse(const std::string& name, - EventType* value) { - return Event_EventType_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampUsFieldNumber = 1, - kTypeFieldNumber = 2, - kRtpPacketFieldNumber = 3, - kRtcpPacketFieldNumber = 4, - kAudioPlayoutEventFieldNumber = 5, - kLossBasedBweUpdateFieldNumber = 6, - kDelayBasedBweUpdateFieldNumber = 7, - kVideoReceiverConfigFieldNumber = 8, - kVideoSenderConfigFieldNumber = 9, - kAudioReceiverConfigFieldNumber = 10, - kAudioSenderConfigFieldNumber = 11, - kAudioNetworkAdaptationFieldNumber = 16, - kProbeClusterFieldNumber = 17, - kProbeResultFieldNumber = 18, - kAlrStateFieldNumber = 19, - kIceCandidatePairConfigFieldNumber = 20, - kIceCandidatePairEventFieldNumber = 21, - }; - // optional int64 timestamp_us = 1; - bool has_timestamp_us() const; - void clear_timestamp_us(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_us() const; - void set_timestamp_us(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional .webrtc.rtclog.Event.EventType type = 2; - bool has_type() const; - void clear_type(); - ::webrtc::rtclog::Event_EventType type() const; - void set_type(::webrtc::rtclog::Event_EventType value); - - // optional .webrtc.rtclog.RtpPacket rtp_packet = 3; - bool has_rtp_packet() const; - void clear_rtp_packet(); - const ::webrtc::rtclog::RtpPacket& rtp_packet() const; - ::webrtc::rtclog::RtpPacket* release_rtp_packet(); - ::webrtc::rtclog::RtpPacket* mutable_rtp_packet(); - void set_allocated_rtp_packet(::webrtc::rtclog::RtpPacket* rtp_packet); - - // optional .webrtc.rtclog.RtcpPacket rtcp_packet = 4; - bool has_rtcp_packet() const; - void clear_rtcp_packet(); - const ::webrtc::rtclog::RtcpPacket& rtcp_packet() const; - ::webrtc::rtclog::RtcpPacket* release_rtcp_packet(); - ::webrtc::rtclog::RtcpPacket* mutable_rtcp_packet(); - void set_allocated_rtcp_packet(::webrtc::rtclog::RtcpPacket* rtcp_packet); - - // optional .webrtc.rtclog.AudioPlayoutEvent audio_playout_event = 5; - bool has_audio_playout_event() const; - void clear_audio_playout_event(); - const ::webrtc::rtclog::AudioPlayoutEvent& audio_playout_event() const; - ::webrtc::rtclog::AudioPlayoutEvent* release_audio_playout_event(); - ::webrtc::rtclog::AudioPlayoutEvent* mutable_audio_playout_event(); - void set_allocated_audio_playout_event(::webrtc::rtclog::AudioPlayoutEvent* audio_playout_event); - - // optional .webrtc.rtclog.LossBasedBweUpdate loss_based_bwe_update = 6; - bool has_loss_based_bwe_update() const; - void clear_loss_based_bwe_update(); - const ::webrtc::rtclog::LossBasedBweUpdate& loss_based_bwe_update() const; - ::webrtc::rtclog::LossBasedBweUpdate* release_loss_based_bwe_update(); - ::webrtc::rtclog::LossBasedBweUpdate* mutable_loss_based_bwe_update(); - void set_allocated_loss_based_bwe_update(::webrtc::rtclog::LossBasedBweUpdate* loss_based_bwe_update); - - // optional .webrtc.rtclog.DelayBasedBweUpdate delay_based_bwe_update = 7; - bool has_delay_based_bwe_update() const; - void clear_delay_based_bwe_update(); - const ::webrtc::rtclog::DelayBasedBweUpdate& delay_based_bwe_update() const; - ::webrtc::rtclog::DelayBasedBweUpdate* release_delay_based_bwe_update(); - ::webrtc::rtclog::DelayBasedBweUpdate* mutable_delay_based_bwe_update(); - void set_allocated_delay_based_bwe_update(::webrtc::rtclog::DelayBasedBweUpdate* delay_based_bwe_update); - - // optional .webrtc.rtclog.VideoReceiveConfig video_receiver_config = 8; - bool has_video_receiver_config() const; - void clear_video_receiver_config(); - const ::webrtc::rtclog::VideoReceiveConfig& video_receiver_config() const; - ::webrtc::rtclog::VideoReceiveConfig* release_video_receiver_config(); - ::webrtc::rtclog::VideoReceiveConfig* mutable_video_receiver_config(); - void set_allocated_video_receiver_config(::webrtc::rtclog::VideoReceiveConfig* video_receiver_config); - - // optional .webrtc.rtclog.VideoSendConfig video_sender_config = 9; - bool has_video_sender_config() const; - void clear_video_sender_config(); - const ::webrtc::rtclog::VideoSendConfig& video_sender_config() const; - ::webrtc::rtclog::VideoSendConfig* release_video_sender_config(); - ::webrtc::rtclog::VideoSendConfig* mutable_video_sender_config(); - void set_allocated_video_sender_config(::webrtc::rtclog::VideoSendConfig* video_sender_config); - - // optional .webrtc.rtclog.AudioReceiveConfig audio_receiver_config = 10; - bool has_audio_receiver_config() const; - void clear_audio_receiver_config(); - const ::webrtc::rtclog::AudioReceiveConfig& audio_receiver_config() const; - ::webrtc::rtclog::AudioReceiveConfig* release_audio_receiver_config(); - ::webrtc::rtclog::AudioReceiveConfig* mutable_audio_receiver_config(); - void set_allocated_audio_receiver_config(::webrtc::rtclog::AudioReceiveConfig* audio_receiver_config); - - // optional .webrtc.rtclog.AudioSendConfig audio_sender_config = 11; - bool has_audio_sender_config() const; - void clear_audio_sender_config(); - const ::webrtc::rtclog::AudioSendConfig& audio_sender_config() const; - ::webrtc::rtclog::AudioSendConfig* release_audio_sender_config(); - ::webrtc::rtclog::AudioSendConfig* mutable_audio_sender_config(); - void set_allocated_audio_sender_config(::webrtc::rtclog::AudioSendConfig* audio_sender_config); - - // optional .webrtc.rtclog.AudioNetworkAdaptation audio_network_adaptation = 16; - bool has_audio_network_adaptation() const; - void clear_audio_network_adaptation(); - const ::webrtc::rtclog::AudioNetworkAdaptation& audio_network_adaptation() const; - ::webrtc::rtclog::AudioNetworkAdaptation* release_audio_network_adaptation(); - ::webrtc::rtclog::AudioNetworkAdaptation* mutable_audio_network_adaptation(); - void set_allocated_audio_network_adaptation(::webrtc::rtclog::AudioNetworkAdaptation* audio_network_adaptation); - - // optional .webrtc.rtclog.BweProbeCluster probe_cluster = 17; - bool has_probe_cluster() const; - void clear_probe_cluster(); - const ::webrtc::rtclog::BweProbeCluster& probe_cluster() const; - ::webrtc::rtclog::BweProbeCluster* release_probe_cluster(); - ::webrtc::rtclog::BweProbeCluster* mutable_probe_cluster(); - void set_allocated_probe_cluster(::webrtc::rtclog::BweProbeCluster* probe_cluster); - - // optional .webrtc.rtclog.BweProbeResult probe_result = 18; - bool has_probe_result() const; - void clear_probe_result(); - const ::webrtc::rtclog::BweProbeResult& probe_result() const; - ::webrtc::rtclog::BweProbeResult* release_probe_result(); - ::webrtc::rtclog::BweProbeResult* mutable_probe_result(); - void set_allocated_probe_result(::webrtc::rtclog::BweProbeResult* probe_result); - - // optional .webrtc.rtclog.AlrState alr_state = 19; - bool has_alr_state() const; - void clear_alr_state(); - const ::webrtc::rtclog::AlrState& alr_state() const; - ::webrtc::rtclog::AlrState* release_alr_state(); - ::webrtc::rtclog::AlrState* mutable_alr_state(); - void set_allocated_alr_state(::webrtc::rtclog::AlrState* alr_state); - - // optional .webrtc.rtclog.IceCandidatePairConfig ice_candidate_pair_config = 20; - bool has_ice_candidate_pair_config() const; - void clear_ice_candidate_pair_config(); - const ::webrtc::rtclog::IceCandidatePairConfig& ice_candidate_pair_config() const; - ::webrtc::rtclog::IceCandidatePairConfig* release_ice_candidate_pair_config(); - ::webrtc::rtclog::IceCandidatePairConfig* mutable_ice_candidate_pair_config(); - void set_allocated_ice_candidate_pair_config(::webrtc::rtclog::IceCandidatePairConfig* ice_candidate_pair_config); - - // optional .webrtc.rtclog.IceCandidatePairEvent ice_candidate_pair_event = 21; - bool has_ice_candidate_pair_event() const; - void clear_ice_candidate_pair_event(); - const ::webrtc::rtclog::IceCandidatePairEvent& ice_candidate_pair_event() const; - ::webrtc::rtclog::IceCandidatePairEvent* release_ice_candidate_pair_event(); - ::webrtc::rtclog::IceCandidatePairEvent* mutable_ice_candidate_pair_event(); - void set_allocated_ice_candidate_pair_event(::webrtc::rtclog::IceCandidatePairEvent* ice_candidate_pair_event); - - void clear_subtype(); - SubtypeCase subtype_case() const; - // @@protoc_insertion_point(class_scope:webrtc.rtclog.Event) - private: - class _Internal; - void set_has_rtp_packet(); - void set_has_rtcp_packet(); - void set_has_audio_playout_event(); - void set_has_loss_based_bwe_update(); - void set_has_delay_based_bwe_update(); - void set_has_video_receiver_config(); - void set_has_video_sender_config(); - void set_has_audio_receiver_config(); - void set_has_audio_sender_config(); - void set_has_audio_network_adaptation(); - void set_has_probe_cluster(); - void set_has_probe_result(); - void set_has_alr_state(); - void set_has_ice_candidate_pair_config(); - void set_has_ice_candidate_pair_event(); - - inline bool has_subtype() const; - inline void clear_has_subtype(); - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_us_; - int type_; - union SubtypeUnion { - SubtypeUnion() {} - ::webrtc::rtclog::RtpPacket* rtp_packet_; - ::webrtc::rtclog::RtcpPacket* rtcp_packet_; - ::webrtc::rtclog::AudioPlayoutEvent* audio_playout_event_; - ::webrtc::rtclog::LossBasedBweUpdate* loss_based_bwe_update_; - ::webrtc::rtclog::DelayBasedBweUpdate* delay_based_bwe_update_; - ::webrtc::rtclog::VideoReceiveConfig* video_receiver_config_; - ::webrtc::rtclog::VideoSendConfig* video_sender_config_; - ::webrtc::rtclog::AudioReceiveConfig* audio_receiver_config_; - ::webrtc::rtclog::AudioSendConfig* audio_sender_config_; - ::webrtc::rtclog::AudioNetworkAdaptation* audio_network_adaptation_; - ::webrtc::rtclog::BweProbeCluster* probe_cluster_; - ::webrtc::rtclog::BweProbeResult* probe_result_; - ::webrtc::rtclog::AlrState* alr_state_; - ::webrtc::rtclog::IceCandidatePairConfig* ice_candidate_pair_config_; - ::webrtc::rtclog::IceCandidatePairEvent* ice_candidate_pair_event_; - } subtype_; - ::PROTOBUF_NAMESPACE_ID::uint32 _oneof_case_[1]; - - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class RtpPacket : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.RtpPacket) */ { - public: - RtpPacket(); - virtual ~RtpPacket(); - - RtpPacket(const RtpPacket& from); - RtpPacket(RtpPacket&& from) noexcept - : RtpPacket() { - *this = ::std::move(from); - } - - inline RtpPacket& operator=(const RtpPacket& from) { - CopyFrom(from); - return *this; - } - inline RtpPacket& operator=(RtpPacket&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const RtpPacket& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const RtpPacket* internal_default_instance() { - return reinterpret_cast( - &_RtpPacket_default_instance_); - } - static constexpr int kIndexInFileMessages = - 2; - - friend void swap(RtpPacket& a, RtpPacket& b) { - a.Swap(&b); - } - inline void Swap(RtpPacket* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline RtpPacket* New() const final { - return CreateMaybeMessage(nullptr); - } - - RtpPacket* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const RtpPacket& from); - void MergeFrom(const RtpPacket& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(RtpPacket* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.RtpPacket"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kHeaderFieldNumber = 4, - kIncomingFieldNumber = 1, - kTypeFieldNumber = 2, - kPacketLengthFieldNumber = 3, - kProbeClusterIdFieldNumber = 5, - }; - // optional bytes header = 4; - bool has_header() const; - void clear_header(); - const std::string& header() const; - void set_header(const std::string& value); - void set_header(std::string&& value); - void set_header(const char* value); - void set_header(const void* value, size_t size); - std::string* mutable_header(); - std::string* release_header(); - void set_allocated_header(std::string* header); - - // optional bool incoming = 1; - bool has_incoming() const; - void clear_incoming(); - bool incoming() const; - void set_incoming(bool value); - - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - PROTOBUF_DEPRECATED bool has_type() const; - PROTOBUF_DEPRECATED void clear_type(); - PROTOBUF_DEPRECATED ::webrtc::rtclog::MediaType type() const; - PROTOBUF_DEPRECATED void set_type(::webrtc::rtclog::MediaType value); - - // optional uint32 packet_length = 3; - bool has_packet_length() const; - void clear_packet_length(); - ::PROTOBUF_NAMESPACE_ID::uint32 packet_length() const; - void set_packet_length(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional int32 probe_cluster_id = 5; - bool has_probe_cluster_id() const; - void clear_probe_cluster_id(); - ::PROTOBUF_NAMESPACE_ID::int32 probe_cluster_id() const; - void set_probe_cluster_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.RtpPacket) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr header_; - bool incoming_; - int type_; - ::PROTOBUF_NAMESPACE_ID::uint32 packet_length_; - ::PROTOBUF_NAMESPACE_ID::int32 probe_cluster_id_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class RtcpPacket : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.RtcpPacket) */ { - public: - RtcpPacket(); - virtual ~RtcpPacket(); - - RtcpPacket(const RtcpPacket& from); - RtcpPacket(RtcpPacket&& from) noexcept - : RtcpPacket() { - *this = ::std::move(from); - } - - inline RtcpPacket& operator=(const RtcpPacket& from) { - CopyFrom(from); - return *this; - } - inline RtcpPacket& operator=(RtcpPacket&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const RtcpPacket& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const RtcpPacket* internal_default_instance() { - return reinterpret_cast( - &_RtcpPacket_default_instance_); - } - static constexpr int kIndexInFileMessages = - 3; - - friend void swap(RtcpPacket& a, RtcpPacket& b) { - a.Swap(&b); - } - inline void Swap(RtcpPacket* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline RtcpPacket* New() const final { - return CreateMaybeMessage(nullptr); - } - - RtcpPacket* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const RtcpPacket& from); - void MergeFrom(const RtcpPacket& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(RtcpPacket* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.RtcpPacket"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kPacketDataFieldNumber = 3, - kIncomingFieldNumber = 1, - kTypeFieldNumber = 2, - }; - // optional bytes packet_data = 3; - bool has_packet_data() const; - void clear_packet_data(); - const std::string& packet_data() const; - void set_packet_data(const std::string& value); - void set_packet_data(std::string&& value); - void set_packet_data(const char* value); - void set_packet_data(const void* value, size_t size); - std::string* mutable_packet_data(); - std::string* release_packet_data(); - void set_allocated_packet_data(std::string* packet_data); - - // optional bool incoming = 1; - bool has_incoming() const; - void clear_incoming(); - bool incoming() const; - void set_incoming(bool value); - - // optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; - PROTOBUF_DEPRECATED bool has_type() const; - PROTOBUF_DEPRECATED void clear_type(); - PROTOBUF_DEPRECATED ::webrtc::rtclog::MediaType type() const; - PROTOBUF_DEPRECATED void set_type(::webrtc::rtclog::MediaType value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.RtcpPacket) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr packet_data_; - bool incoming_; - int type_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class AudioPlayoutEvent : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.AudioPlayoutEvent) */ { - public: - AudioPlayoutEvent(); - virtual ~AudioPlayoutEvent(); - - AudioPlayoutEvent(const AudioPlayoutEvent& from); - AudioPlayoutEvent(AudioPlayoutEvent&& from) noexcept - : AudioPlayoutEvent() { - *this = ::std::move(from); - } - - inline AudioPlayoutEvent& operator=(const AudioPlayoutEvent& from) { - CopyFrom(from); - return *this; - } - inline AudioPlayoutEvent& operator=(AudioPlayoutEvent&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AudioPlayoutEvent& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AudioPlayoutEvent* internal_default_instance() { - return reinterpret_cast( - &_AudioPlayoutEvent_default_instance_); - } - static constexpr int kIndexInFileMessages = - 4; - - friend void swap(AudioPlayoutEvent& a, AudioPlayoutEvent& b) { - a.Swap(&b); - } - inline void Swap(AudioPlayoutEvent* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AudioPlayoutEvent* New() const final { - return CreateMaybeMessage(nullptr); - } - - AudioPlayoutEvent* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AudioPlayoutEvent& from); - void MergeFrom(const AudioPlayoutEvent& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AudioPlayoutEvent* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.AudioPlayoutEvent"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kLocalSsrcFieldNumber = 2, - }; - // optional uint32 local_ssrc = 2; - bool has_local_ssrc() const; - void clear_local_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc() const; - void set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.AudioPlayoutEvent) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class LossBasedBweUpdate : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.LossBasedBweUpdate) */ { - public: - LossBasedBweUpdate(); - virtual ~LossBasedBweUpdate(); - - LossBasedBweUpdate(const LossBasedBweUpdate& from); - LossBasedBweUpdate(LossBasedBweUpdate&& from) noexcept - : LossBasedBweUpdate() { - *this = ::std::move(from); - } - - inline LossBasedBweUpdate& operator=(const LossBasedBweUpdate& from) { - CopyFrom(from); - return *this; - } - inline LossBasedBweUpdate& operator=(LossBasedBweUpdate&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const LossBasedBweUpdate& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const LossBasedBweUpdate* internal_default_instance() { - return reinterpret_cast( - &_LossBasedBweUpdate_default_instance_); - } - static constexpr int kIndexInFileMessages = - 5; - - friend void swap(LossBasedBweUpdate& a, LossBasedBweUpdate& b) { - a.Swap(&b); - } - inline void Swap(LossBasedBweUpdate* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline LossBasedBweUpdate* New() const final { - return CreateMaybeMessage(nullptr); - } - - LossBasedBweUpdate* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const LossBasedBweUpdate& from); - void MergeFrom(const LossBasedBweUpdate& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(LossBasedBweUpdate* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.LossBasedBweUpdate"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kBitrateBpsFieldNumber = 1, - kFractionLossFieldNumber = 2, - kTotalPacketsFieldNumber = 3, - }; - // optional int32 bitrate_bps = 1; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional uint32 fraction_loss = 2; - bool has_fraction_loss() const; - void clear_fraction_loss(); - ::PROTOBUF_NAMESPACE_ID::uint32 fraction_loss() const; - void set_fraction_loss(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional int32 total_packets = 3; - bool has_total_packets() const; - void clear_total_packets(); - ::PROTOBUF_NAMESPACE_ID::int32 total_packets() const; - void set_total_packets(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.LossBasedBweUpdate) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps_; - ::PROTOBUF_NAMESPACE_ID::uint32 fraction_loss_; - ::PROTOBUF_NAMESPACE_ID::int32 total_packets_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class DelayBasedBweUpdate : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.DelayBasedBweUpdate) */ { - public: - DelayBasedBweUpdate(); - virtual ~DelayBasedBweUpdate(); - - DelayBasedBweUpdate(const DelayBasedBweUpdate& from); - DelayBasedBweUpdate(DelayBasedBweUpdate&& from) noexcept - : DelayBasedBweUpdate() { - *this = ::std::move(from); - } - - inline DelayBasedBweUpdate& operator=(const DelayBasedBweUpdate& from) { - CopyFrom(from); - return *this; - } - inline DelayBasedBweUpdate& operator=(DelayBasedBweUpdate&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const DelayBasedBweUpdate& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const DelayBasedBweUpdate* internal_default_instance() { - return reinterpret_cast( - &_DelayBasedBweUpdate_default_instance_); - } - static constexpr int kIndexInFileMessages = - 6; - - friend void swap(DelayBasedBweUpdate& a, DelayBasedBweUpdate& b) { - a.Swap(&b); - } - inline void Swap(DelayBasedBweUpdate* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline DelayBasedBweUpdate* New() const final { - return CreateMaybeMessage(nullptr); - } - - DelayBasedBweUpdate* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const DelayBasedBweUpdate& from); - void MergeFrom(const DelayBasedBweUpdate& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(DelayBasedBweUpdate* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.DelayBasedBweUpdate"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef DelayBasedBweUpdate_DetectorState DetectorState; - static constexpr DetectorState BWE_NORMAL = - DelayBasedBweUpdate_DetectorState_BWE_NORMAL; - static constexpr DetectorState BWE_UNDERUSING = - DelayBasedBweUpdate_DetectorState_BWE_UNDERUSING; - static constexpr DetectorState BWE_OVERUSING = - DelayBasedBweUpdate_DetectorState_BWE_OVERUSING; - static inline bool DetectorState_IsValid(int value) { - return DelayBasedBweUpdate_DetectorState_IsValid(value); - } - static constexpr DetectorState DetectorState_MIN = - DelayBasedBweUpdate_DetectorState_DetectorState_MIN; - static constexpr DetectorState DetectorState_MAX = - DelayBasedBweUpdate_DetectorState_DetectorState_MAX; - static constexpr int DetectorState_ARRAYSIZE = - DelayBasedBweUpdate_DetectorState_DetectorState_ARRAYSIZE; - template - static inline const std::string& DetectorState_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function DetectorState_Name."); - return DelayBasedBweUpdate_DetectorState_Name(enum_t_value); - } - static inline bool DetectorState_Parse(const std::string& name, - DetectorState* value) { - return DelayBasedBweUpdate_DetectorState_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kBitrateBpsFieldNumber = 1, - kDetectorStateFieldNumber = 2, - }; - // optional int32 bitrate_bps = 1; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional .webrtc.rtclog.DelayBasedBweUpdate.DetectorState detector_state = 2; - bool has_detector_state() const; - void clear_detector_state(); - ::webrtc::rtclog::DelayBasedBweUpdate_DetectorState detector_state() const; - void set_detector_state(::webrtc::rtclog::DelayBasedBweUpdate_DetectorState value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.DelayBasedBweUpdate) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps_; - int detector_state_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class VideoReceiveConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.VideoReceiveConfig) */ { - public: - VideoReceiveConfig(); - virtual ~VideoReceiveConfig(); - - VideoReceiveConfig(const VideoReceiveConfig& from); - VideoReceiveConfig(VideoReceiveConfig&& from) noexcept - : VideoReceiveConfig() { - *this = ::std::move(from); - } - - inline VideoReceiveConfig& operator=(const VideoReceiveConfig& from) { - CopyFrom(from); - return *this; - } - inline VideoReceiveConfig& operator=(VideoReceiveConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const VideoReceiveConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const VideoReceiveConfig* internal_default_instance() { - return reinterpret_cast( - &_VideoReceiveConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 7; - - friend void swap(VideoReceiveConfig& a, VideoReceiveConfig& b) { - a.Swap(&b); - } - inline void Swap(VideoReceiveConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline VideoReceiveConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - VideoReceiveConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const VideoReceiveConfig& from); - void MergeFrom(const VideoReceiveConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(VideoReceiveConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.VideoReceiveConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef VideoReceiveConfig_RtcpMode RtcpMode; - static constexpr RtcpMode RTCP_COMPOUND = - VideoReceiveConfig_RtcpMode_RTCP_COMPOUND; - static constexpr RtcpMode RTCP_REDUCEDSIZE = - VideoReceiveConfig_RtcpMode_RTCP_REDUCEDSIZE; - static inline bool RtcpMode_IsValid(int value) { - return VideoReceiveConfig_RtcpMode_IsValid(value); - } - static constexpr RtcpMode RtcpMode_MIN = - VideoReceiveConfig_RtcpMode_RtcpMode_MIN; - static constexpr RtcpMode RtcpMode_MAX = - VideoReceiveConfig_RtcpMode_RtcpMode_MAX; - static constexpr int RtcpMode_ARRAYSIZE = - VideoReceiveConfig_RtcpMode_RtcpMode_ARRAYSIZE; - template - static inline const std::string& RtcpMode_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function RtcpMode_Name."); - return VideoReceiveConfig_RtcpMode_Name(enum_t_value); - } - static inline bool RtcpMode_Parse(const std::string& name, - RtcpMode* value) { - return VideoReceiveConfig_RtcpMode_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kRtxMapFieldNumber = 5, - kHeaderExtensionsFieldNumber = 6, - kDecodersFieldNumber = 7, - kRemoteSsrcFieldNumber = 1, - kLocalSsrcFieldNumber = 2, - kRembFieldNumber = 4, - kRtcpModeFieldNumber = 3, - }; - // repeated .webrtc.rtclog.RtxMap rtx_map = 5; - int rtx_map_size() const; - void clear_rtx_map(); - ::webrtc::rtclog::RtxMap* mutable_rtx_map(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtxMap >* - mutable_rtx_map(); - const ::webrtc::rtclog::RtxMap& rtx_map(int index) const; - ::webrtc::rtclog::RtxMap* add_rtx_map(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtxMap >& - rtx_map() const; - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 6; - int header_extensions_size() const; - void clear_header_extensions(); - ::webrtc::rtclog::RtpHeaderExtension* mutable_header_extensions(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >* - mutable_header_extensions(); - const ::webrtc::rtclog::RtpHeaderExtension& header_extensions(int index) const; - ::webrtc::rtclog::RtpHeaderExtension* add_header_extensions(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >& - header_extensions() const; - - // repeated .webrtc.rtclog.DecoderConfig decoders = 7; - int decoders_size() const; - void clear_decoders(); - ::webrtc::rtclog::DecoderConfig* mutable_decoders(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::DecoderConfig >* - mutable_decoders(); - const ::webrtc::rtclog::DecoderConfig& decoders(int index) const; - ::webrtc::rtclog::DecoderConfig* add_decoders(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::DecoderConfig >& - decoders() const; - - // optional uint32 remote_ssrc = 1; - bool has_remote_ssrc() const; - void clear_remote_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 remote_ssrc() const; - void set_remote_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 local_ssrc = 2; - bool has_local_ssrc() const; - void clear_local_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc() const; - void set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional bool remb = 4; - bool has_remb() const; - void clear_remb(); - bool remb() const; - void set_remb(bool value); - - // optional .webrtc.rtclog.VideoReceiveConfig.RtcpMode rtcp_mode = 3; - bool has_rtcp_mode() const; - void clear_rtcp_mode(); - ::webrtc::rtclog::VideoReceiveConfig_RtcpMode rtcp_mode() const; - void set_rtcp_mode(::webrtc::rtclog::VideoReceiveConfig_RtcpMode value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.VideoReceiveConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtxMap > rtx_map_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension > header_extensions_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::DecoderConfig > decoders_; - ::PROTOBUF_NAMESPACE_ID::uint32 remote_ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc_; - bool remb_; - int rtcp_mode_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class DecoderConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.DecoderConfig) */ { - public: - DecoderConfig(); - virtual ~DecoderConfig(); - - DecoderConfig(const DecoderConfig& from); - DecoderConfig(DecoderConfig&& from) noexcept - : DecoderConfig() { - *this = ::std::move(from); - } - - inline DecoderConfig& operator=(const DecoderConfig& from) { - CopyFrom(from); - return *this; - } - inline DecoderConfig& operator=(DecoderConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const DecoderConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const DecoderConfig* internal_default_instance() { - return reinterpret_cast( - &_DecoderConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 8; - - friend void swap(DecoderConfig& a, DecoderConfig& b) { - a.Swap(&b); - } - inline void Swap(DecoderConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline DecoderConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - DecoderConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const DecoderConfig& from); - void MergeFrom(const DecoderConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(DecoderConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.DecoderConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kNameFieldNumber = 1, - kPayloadTypeFieldNumber = 2, - }; - // optional string name = 1; - bool has_name() const; - void clear_name(); - const std::string& name() const; - void set_name(const std::string& value); - void set_name(std::string&& value); - void set_name(const char* value); - void set_name(const char* value, size_t size); - std::string* mutable_name(); - std::string* release_name(); - void set_allocated_name(std::string* name); - - // optional int32 payload_type = 2; - bool has_payload_type() const; - void clear_payload_type(); - ::PROTOBUF_NAMESPACE_ID::int32 payload_type() const; - void set_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.DecoderConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; - ::PROTOBUF_NAMESPACE_ID::int32 payload_type_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class RtpHeaderExtension : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.RtpHeaderExtension) */ { - public: - RtpHeaderExtension(); - virtual ~RtpHeaderExtension(); - - RtpHeaderExtension(const RtpHeaderExtension& from); - RtpHeaderExtension(RtpHeaderExtension&& from) noexcept - : RtpHeaderExtension() { - *this = ::std::move(from); - } - - inline RtpHeaderExtension& operator=(const RtpHeaderExtension& from) { - CopyFrom(from); - return *this; - } - inline RtpHeaderExtension& operator=(RtpHeaderExtension&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const RtpHeaderExtension& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const RtpHeaderExtension* internal_default_instance() { - return reinterpret_cast( - &_RtpHeaderExtension_default_instance_); - } - static constexpr int kIndexInFileMessages = - 9; - - friend void swap(RtpHeaderExtension& a, RtpHeaderExtension& b) { - a.Swap(&b); - } - inline void Swap(RtpHeaderExtension* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline RtpHeaderExtension* New() const final { - return CreateMaybeMessage(nullptr); - } - - RtpHeaderExtension* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const RtpHeaderExtension& from); - void MergeFrom(const RtpHeaderExtension& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(RtpHeaderExtension* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.RtpHeaderExtension"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kNameFieldNumber = 1, - kIdFieldNumber = 2, - }; - // optional string name = 1; - bool has_name() const; - void clear_name(); - const std::string& name() const; - void set_name(const std::string& value); - void set_name(std::string&& value); - void set_name(const char* value); - void set_name(const char* value, size_t size); - std::string* mutable_name(); - std::string* release_name(); - void set_allocated_name(std::string* name); - - // optional int32 id = 2; - bool has_id() const; - void clear_id(); - ::PROTOBUF_NAMESPACE_ID::int32 id() const; - void set_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.RtpHeaderExtension) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; - ::PROTOBUF_NAMESPACE_ID::int32 id_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class RtxConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.RtxConfig) */ { - public: - RtxConfig(); - virtual ~RtxConfig(); - - RtxConfig(const RtxConfig& from); - RtxConfig(RtxConfig&& from) noexcept - : RtxConfig() { - *this = ::std::move(from); - } - - inline RtxConfig& operator=(const RtxConfig& from) { - CopyFrom(from); - return *this; - } - inline RtxConfig& operator=(RtxConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const RtxConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const RtxConfig* internal_default_instance() { - return reinterpret_cast( - &_RtxConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 10; - - friend void swap(RtxConfig& a, RtxConfig& b) { - a.Swap(&b); - } - inline void Swap(RtxConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline RtxConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - RtxConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const RtxConfig& from); - void MergeFrom(const RtxConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(RtxConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.RtxConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kRtxSsrcFieldNumber = 1, - kRtxPayloadTypeFieldNumber = 2, - }; - // optional uint32 rtx_ssrc = 1; - bool has_rtx_ssrc() const; - void clear_rtx_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 rtx_ssrc() const; - void set_rtx_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional int32 rtx_payload_type = 2; - bool has_rtx_payload_type() const; - void clear_rtx_payload_type(); - ::PROTOBUF_NAMESPACE_ID::int32 rtx_payload_type() const; - void set_rtx_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.RtxConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::uint32 rtx_ssrc_; - ::PROTOBUF_NAMESPACE_ID::int32 rtx_payload_type_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class RtxMap : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.RtxMap) */ { - public: - RtxMap(); - virtual ~RtxMap(); - - RtxMap(const RtxMap& from); - RtxMap(RtxMap&& from) noexcept - : RtxMap() { - *this = ::std::move(from); - } - - inline RtxMap& operator=(const RtxMap& from) { - CopyFrom(from); - return *this; - } - inline RtxMap& operator=(RtxMap&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const RtxMap& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const RtxMap* internal_default_instance() { - return reinterpret_cast( - &_RtxMap_default_instance_); - } - static constexpr int kIndexInFileMessages = - 11; - - friend void swap(RtxMap& a, RtxMap& b) { - a.Swap(&b); - } - inline void Swap(RtxMap* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline RtxMap* New() const final { - return CreateMaybeMessage(nullptr); - } - - RtxMap* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const RtxMap& from); - void MergeFrom(const RtxMap& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(RtxMap* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.RtxMap"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kConfigFieldNumber = 2, - kPayloadTypeFieldNumber = 1, - }; - // optional .webrtc.rtclog.RtxConfig config = 2; - bool has_config() const; - void clear_config(); - const ::webrtc::rtclog::RtxConfig& config() const; - ::webrtc::rtclog::RtxConfig* release_config(); - ::webrtc::rtclog::RtxConfig* mutable_config(); - void set_allocated_config(::webrtc::rtclog::RtxConfig* config); - - // optional int32 payload_type = 1; - bool has_payload_type() const; - void clear_payload_type(); - ::PROTOBUF_NAMESPACE_ID::int32 payload_type() const; - void set_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.RtxMap) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::webrtc::rtclog::RtxConfig* config_; - ::PROTOBUF_NAMESPACE_ID::int32 payload_type_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class VideoSendConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.VideoSendConfig) */ { - public: - VideoSendConfig(); - virtual ~VideoSendConfig(); - - VideoSendConfig(const VideoSendConfig& from); - VideoSendConfig(VideoSendConfig&& from) noexcept - : VideoSendConfig() { - *this = ::std::move(from); - } - - inline VideoSendConfig& operator=(const VideoSendConfig& from) { - CopyFrom(from); - return *this; - } - inline VideoSendConfig& operator=(VideoSendConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const VideoSendConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const VideoSendConfig* internal_default_instance() { - return reinterpret_cast( - &_VideoSendConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 12; - - friend void swap(VideoSendConfig& a, VideoSendConfig& b) { - a.Swap(&b); - } - inline void Swap(VideoSendConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline VideoSendConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - VideoSendConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const VideoSendConfig& from); - void MergeFrom(const VideoSendConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(VideoSendConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.VideoSendConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kSsrcsFieldNumber = 1, - kHeaderExtensionsFieldNumber = 2, - kRtxSsrcsFieldNumber = 3, - kEncoderFieldNumber = 5, - kRtxPayloadTypeFieldNumber = 4, - }; - // repeated uint32 ssrcs = 1; - int ssrcs_size() const; - void clear_ssrcs(); - ::PROTOBUF_NAMESPACE_ID::uint32 ssrcs(int index) const; - void set_ssrcs(int index, ::PROTOBUF_NAMESPACE_ID::uint32 value); - void add_ssrcs(::PROTOBUF_NAMESPACE_ID::uint32 value); - const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 >& - ssrcs() const; - ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 >* - mutable_ssrcs(); - - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - int header_extensions_size() const; - void clear_header_extensions(); - ::webrtc::rtclog::RtpHeaderExtension* mutable_header_extensions(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >* - mutable_header_extensions(); - const ::webrtc::rtclog::RtpHeaderExtension& header_extensions(int index) const; - ::webrtc::rtclog::RtpHeaderExtension* add_header_extensions(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >& - header_extensions() const; - - // repeated uint32 rtx_ssrcs = 3; - int rtx_ssrcs_size() const; - void clear_rtx_ssrcs(); - ::PROTOBUF_NAMESPACE_ID::uint32 rtx_ssrcs(int index) const; - void set_rtx_ssrcs(int index, ::PROTOBUF_NAMESPACE_ID::uint32 value); - void add_rtx_ssrcs(::PROTOBUF_NAMESPACE_ID::uint32 value); - const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 >& - rtx_ssrcs() const; - ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 >* - mutable_rtx_ssrcs(); - - // optional .webrtc.rtclog.EncoderConfig encoder = 5; - bool has_encoder() const; - void clear_encoder(); - const ::webrtc::rtclog::EncoderConfig& encoder() const; - ::webrtc::rtclog::EncoderConfig* release_encoder(); - ::webrtc::rtclog::EncoderConfig* mutable_encoder(); - void set_allocated_encoder(::webrtc::rtclog::EncoderConfig* encoder); - - // optional int32 rtx_payload_type = 4; - bool has_rtx_payload_type() const; - void clear_rtx_payload_type(); - ::PROTOBUF_NAMESPACE_ID::int32 rtx_payload_type() const; - void set_rtx_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.VideoSendConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 > ssrcs_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension > header_extensions_; - ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 > rtx_ssrcs_; - ::webrtc::rtclog::EncoderConfig* encoder_; - ::PROTOBUF_NAMESPACE_ID::int32 rtx_payload_type_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class EncoderConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.EncoderConfig) */ { - public: - EncoderConfig(); - virtual ~EncoderConfig(); - - EncoderConfig(const EncoderConfig& from); - EncoderConfig(EncoderConfig&& from) noexcept - : EncoderConfig() { - *this = ::std::move(from); - } - - inline EncoderConfig& operator=(const EncoderConfig& from) { - CopyFrom(from); - return *this; - } - inline EncoderConfig& operator=(EncoderConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const EncoderConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const EncoderConfig* internal_default_instance() { - return reinterpret_cast( - &_EncoderConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 13; - - friend void swap(EncoderConfig& a, EncoderConfig& b) { - a.Swap(&b); - } - inline void Swap(EncoderConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline EncoderConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - EncoderConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const EncoderConfig& from); - void MergeFrom(const EncoderConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(EncoderConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.EncoderConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kNameFieldNumber = 1, - kPayloadTypeFieldNumber = 2, - }; - // optional string name = 1; - bool has_name() const; - void clear_name(); - const std::string& name() const; - void set_name(const std::string& value); - void set_name(std::string&& value); - void set_name(const char* value); - void set_name(const char* value, size_t size); - std::string* mutable_name(); - std::string* release_name(); - void set_allocated_name(std::string* name); - - // optional int32 payload_type = 2; - bool has_payload_type() const; - void clear_payload_type(); - ::PROTOBUF_NAMESPACE_ID::int32 payload_type() const; - void set_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.EncoderConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; - ::PROTOBUF_NAMESPACE_ID::int32 payload_type_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class AudioReceiveConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.AudioReceiveConfig) */ { - public: - AudioReceiveConfig(); - virtual ~AudioReceiveConfig(); - - AudioReceiveConfig(const AudioReceiveConfig& from); - AudioReceiveConfig(AudioReceiveConfig&& from) noexcept - : AudioReceiveConfig() { - *this = ::std::move(from); - } - - inline AudioReceiveConfig& operator=(const AudioReceiveConfig& from) { - CopyFrom(from); - return *this; - } - inline AudioReceiveConfig& operator=(AudioReceiveConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AudioReceiveConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AudioReceiveConfig* internal_default_instance() { - return reinterpret_cast( - &_AudioReceiveConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 14; - - friend void swap(AudioReceiveConfig& a, AudioReceiveConfig& b) { - a.Swap(&b); - } - inline void Swap(AudioReceiveConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AudioReceiveConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - AudioReceiveConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AudioReceiveConfig& from); - void MergeFrom(const AudioReceiveConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AudioReceiveConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.AudioReceiveConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kHeaderExtensionsFieldNumber = 3, - kRemoteSsrcFieldNumber = 1, - kLocalSsrcFieldNumber = 2, - }; - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 3; - int header_extensions_size() const; - void clear_header_extensions(); - ::webrtc::rtclog::RtpHeaderExtension* mutable_header_extensions(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >* - mutable_header_extensions(); - const ::webrtc::rtclog::RtpHeaderExtension& header_extensions(int index) const; - ::webrtc::rtclog::RtpHeaderExtension* add_header_extensions(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >& - header_extensions() const; - - // optional uint32 remote_ssrc = 1; - bool has_remote_ssrc() const; - void clear_remote_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 remote_ssrc() const; - void set_remote_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 local_ssrc = 2; - bool has_local_ssrc() const; - void clear_local_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc() const; - void set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.AudioReceiveConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension > header_extensions_; - ::PROTOBUF_NAMESPACE_ID::uint32 remote_ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class AudioSendConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.AudioSendConfig) */ { - public: - AudioSendConfig(); - virtual ~AudioSendConfig(); - - AudioSendConfig(const AudioSendConfig& from); - AudioSendConfig(AudioSendConfig&& from) noexcept - : AudioSendConfig() { - *this = ::std::move(from); - } - - inline AudioSendConfig& operator=(const AudioSendConfig& from) { - CopyFrom(from); - return *this; - } - inline AudioSendConfig& operator=(AudioSendConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AudioSendConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AudioSendConfig* internal_default_instance() { - return reinterpret_cast( - &_AudioSendConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 15; - - friend void swap(AudioSendConfig& a, AudioSendConfig& b) { - a.Swap(&b); - } - inline void Swap(AudioSendConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AudioSendConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - AudioSendConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AudioSendConfig& from); - void MergeFrom(const AudioSendConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AudioSendConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.AudioSendConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kHeaderExtensionsFieldNumber = 2, - kSsrcFieldNumber = 1, - }; - // repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; - int header_extensions_size() const; - void clear_header_extensions(); - ::webrtc::rtclog::RtpHeaderExtension* mutable_header_extensions(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >* - mutable_header_extensions(); - const ::webrtc::rtclog::RtpHeaderExtension& header_extensions(int index) const; - ::webrtc::rtclog::RtpHeaderExtension* add_header_extensions(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >& - header_extensions() const; - - // optional uint32 ssrc = 1; - bool has_ssrc() const; - void clear_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc() const; - void set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.AudioSendConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension > header_extensions_; - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class AudioNetworkAdaptation : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.AudioNetworkAdaptation) */ { - public: - AudioNetworkAdaptation(); - virtual ~AudioNetworkAdaptation(); - - AudioNetworkAdaptation(const AudioNetworkAdaptation& from); - AudioNetworkAdaptation(AudioNetworkAdaptation&& from) noexcept - : AudioNetworkAdaptation() { - *this = ::std::move(from); - } - - inline AudioNetworkAdaptation& operator=(const AudioNetworkAdaptation& from) { - CopyFrom(from); - return *this; - } - inline AudioNetworkAdaptation& operator=(AudioNetworkAdaptation&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AudioNetworkAdaptation& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AudioNetworkAdaptation* internal_default_instance() { - return reinterpret_cast( - &_AudioNetworkAdaptation_default_instance_); - } - static constexpr int kIndexInFileMessages = - 16; - - friend void swap(AudioNetworkAdaptation& a, AudioNetworkAdaptation& b) { - a.Swap(&b); - } - inline void Swap(AudioNetworkAdaptation* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AudioNetworkAdaptation* New() const final { - return CreateMaybeMessage(nullptr); - } - - AudioNetworkAdaptation* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AudioNetworkAdaptation& from); - void MergeFrom(const AudioNetworkAdaptation& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AudioNetworkAdaptation* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.AudioNetworkAdaptation"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kBitrateBpsFieldNumber = 1, - kFrameLengthMsFieldNumber = 2, - kUplinkPacketLossFractionFieldNumber = 3, - kEnableFecFieldNumber = 4, - kEnableDtxFieldNumber = 5, - kNumChannelsFieldNumber = 6, - }; - // optional int32 bitrate_bps = 1; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 frame_length_ms = 2; - bool has_frame_length_ms() const; - void clear_frame_length_ms(); - ::PROTOBUF_NAMESPACE_ID::int32 frame_length_ms() const; - void set_frame_length_ms(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional float uplink_packet_loss_fraction = 3; - bool has_uplink_packet_loss_fraction() const; - void clear_uplink_packet_loss_fraction(); - float uplink_packet_loss_fraction() const; - void set_uplink_packet_loss_fraction(float value); - - // optional bool enable_fec = 4; - bool has_enable_fec() const; - void clear_enable_fec(); - bool enable_fec() const; - void set_enable_fec(bool value); - - // optional bool enable_dtx = 5; - bool has_enable_dtx() const; - void clear_enable_dtx(); - bool enable_dtx() const; - void set_enable_dtx(bool value); - - // optional uint32 num_channels = 6; - bool has_num_channels() const; - void clear_num_channels(); - ::PROTOBUF_NAMESPACE_ID::uint32 num_channels() const; - void set_num_channels(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.AudioNetworkAdaptation) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps_; - ::PROTOBUF_NAMESPACE_ID::int32 frame_length_ms_; - float uplink_packet_loss_fraction_; - bool enable_fec_; - bool enable_dtx_; - ::PROTOBUF_NAMESPACE_ID::uint32 num_channels_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class BweProbeCluster : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.BweProbeCluster) */ { - public: - BweProbeCluster(); - virtual ~BweProbeCluster(); - - BweProbeCluster(const BweProbeCluster& from); - BweProbeCluster(BweProbeCluster&& from) noexcept - : BweProbeCluster() { - *this = ::std::move(from); - } - - inline BweProbeCluster& operator=(const BweProbeCluster& from) { - CopyFrom(from); - return *this; - } - inline BweProbeCluster& operator=(BweProbeCluster&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const BweProbeCluster& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const BweProbeCluster* internal_default_instance() { - return reinterpret_cast( - &_BweProbeCluster_default_instance_); - } - static constexpr int kIndexInFileMessages = - 17; - - friend void swap(BweProbeCluster& a, BweProbeCluster& b) { - a.Swap(&b); - } - inline void Swap(BweProbeCluster* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline BweProbeCluster* New() const final { - return CreateMaybeMessage(nullptr); - } - - BweProbeCluster* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const BweProbeCluster& from); - void MergeFrom(const BweProbeCluster& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(BweProbeCluster* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.BweProbeCluster"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kIdFieldNumber = 1, - kBitrateBpsFieldNumber = 2, - kMinPacketsFieldNumber = 3, - kMinBytesFieldNumber = 4, - }; - // optional int32 id = 1; - bool has_id() const; - void clear_id(); - ::PROTOBUF_NAMESPACE_ID::int32 id() const; - void set_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 bitrate_bps = 2; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional uint32 min_packets = 3; - bool has_min_packets() const; - void clear_min_packets(); - ::PROTOBUF_NAMESPACE_ID::uint32 min_packets() const; - void set_min_packets(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 min_bytes = 4; - bool has_min_bytes() const; - void clear_min_bytes(); - ::PROTOBUF_NAMESPACE_ID::uint32 min_bytes() const; - void set_min_bytes(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.BweProbeCluster) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int32 id_; - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps_; - ::PROTOBUF_NAMESPACE_ID::uint32 min_packets_; - ::PROTOBUF_NAMESPACE_ID::uint32 min_bytes_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class BweProbeResult : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.BweProbeResult) */ { - public: - BweProbeResult(); - virtual ~BweProbeResult(); - - BweProbeResult(const BweProbeResult& from); - BweProbeResult(BweProbeResult&& from) noexcept - : BweProbeResult() { - *this = ::std::move(from); - } - - inline BweProbeResult& operator=(const BweProbeResult& from) { - CopyFrom(from); - return *this; - } - inline BweProbeResult& operator=(BweProbeResult&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const BweProbeResult& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const BweProbeResult* internal_default_instance() { - return reinterpret_cast( - &_BweProbeResult_default_instance_); - } - static constexpr int kIndexInFileMessages = - 18; - - friend void swap(BweProbeResult& a, BweProbeResult& b) { - a.Swap(&b); - } - inline void Swap(BweProbeResult* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline BweProbeResult* New() const final { - return CreateMaybeMessage(nullptr); - } - - BweProbeResult* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const BweProbeResult& from); - void MergeFrom(const BweProbeResult& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(BweProbeResult* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.BweProbeResult"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef BweProbeResult_ResultType ResultType; - static constexpr ResultType SUCCESS = - BweProbeResult_ResultType_SUCCESS; - static constexpr ResultType INVALID_SEND_RECEIVE_INTERVAL = - BweProbeResult_ResultType_INVALID_SEND_RECEIVE_INTERVAL; - static constexpr ResultType INVALID_SEND_RECEIVE_RATIO = - BweProbeResult_ResultType_INVALID_SEND_RECEIVE_RATIO; - static constexpr ResultType TIMEOUT = - BweProbeResult_ResultType_TIMEOUT; - static inline bool ResultType_IsValid(int value) { - return BweProbeResult_ResultType_IsValid(value); - } - static constexpr ResultType ResultType_MIN = - BweProbeResult_ResultType_ResultType_MIN; - static constexpr ResultType ResultType_MAX = - BweProbeResult_ResultType_ResultType_MAX; - static constexpr int ResultType_ARRAYSIZE = - BweProbeResult_ResultType_ResultType_ARRAYSIZE; - template - static inline const std::string& ResultType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function ResultType_Name."); - return BweProbeResult_ResultType_Name(enum_t_value); - } - static inline bool ResultType_Parse(const std::string& name, - ResultType* value) { - return BweProbeResult_ResultType_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kIdFieldNumber = 1, - kResultFieldNumber = 2, - kBitrateBpsFieldNumber = 3, - }; - // optional int32 id = 1; - bool has_id() const; - void clear_id(); - ::PROTOBUF_NAMESPACE_ID::int32 id() const; - void set_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional .webrtc.rtclog.BweProbeResult.ResultType result = 2; - bool has_result() const; - void clear_result(); - ::webrtc::rtclog::BweProbeResult_ResultType result() const; - void set_result(::webrtc::rtclog::BweProbeResult_ResultType value); - - // optional int32 bitrate_bps = 3; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.BweProbeResult) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int32 id_; - int result_; - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class AlrState : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.AlrState) */ { - public: - AlrState(); - virtual ~AlrState(); - - AlrState(const AlrState& from); - AlrState(AlrState&& from) noexcept - : AlrState() { - *this = ::std::move(from); - } - - inline AlrState& operator=(const AlrState& from) { - CopyFrom(from); - return *this; - } - inline AlrState& operator=(AlrState&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AlrState& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AlrState* internal_default_instance() { - return reinterpret_cast( - &_AlrState_default_instance_); - } - static constexpr int kIndexInFileMessages = - 19; - - friend void swap(AlrState& a, AlrState& b) { - a.Swap(&b); - } - inline void Swap(AlrState* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AlrState* New() const final { - return CreateMaybeMessage(nullptr); - } - - AlrState* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AlrState& from); - void MergeFrom(const AlrState& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AlrState* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.AlrState"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kInAlrFieldNumber = 1, - }; - // optional bool in_alr = 1; - bool has_in_alr() const; - void clear_in_alr(); - bool in_alr() const; - void set_in_alr(bool value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.AlrState) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - bool in_alr_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class IceCandidatePairConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.IceCandidatePairConfig) */ { - public: - IceCandidatePairConfig(); - virtual ~IceCandidatePairConfig(); - - IceCandidatePairConfig(const IceCandidatePairConfig& from); - IceCandidatePairConfig(IceCandidatePairConfig&& from) noexcept - : IceCandidatePairConfig() { - *this = ::std::move(from); - } - - inline IceCandidatePairConfig& operator=(const IceCandidatePairConfig& from) { - CopyFrom(from); - return *this; - } - inline IceCandidatePairConfig& operator=(IceCandidatePairConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const IceCandidatePairConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const IceCandidatePairConfig* internal_default_instance() { - return reinterpret_cast( - &_IceCandidatePairConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 20; - - friend void swap(IceCandidatePairConfig& a, IceCandidatePairConfig& b) { - a.Swap(&b); - } - inline void Swap(IceCandidatePairConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline IceCandidatePairConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - IceCandidatePairConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const IceCandidatePairConfig& from); - void MergeFrom(const IceCandidatePairConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(IceCandidatePairConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.IceCandidatePairConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfigType; - static constexpr IceCandidatePairConfigType ADDED = - IceCandidatePairConfig_IceCandidatePairConfigType_ADDED; - static constexpr IceCandidatePairConfigType UPDATED = - IceCandidatePairConfig_IceCandidatePairConfigType_UPDATED; - static constexpr IceCandidatePairConfigType DESTROYED = - IceCandidatePairConfig_IceCandidatePairConfigType_DESTROYED; - static constexpr IceCandidatePairConfigType SELECTED = - IceCandidatePairConfig_IceCandidatePairConfigType_SELECTED; - static inline bool IceCandidatePairConfigType_IsValid(int value) { - return IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(value); - } - static constexpr IceCandidatePairConfigType IceCandidatePairConfigType_MIN = - IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MIN; - static constexpr IceCandidatePairConfigType IceCandidatePairConfigType_MAX = - IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MAX; - static constexpr int IceCandidatePairConfigType_ARRAYSIZE = - IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_ARRAYSIZE; - template - static inline const std::string& IceCandidatePairConfigType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfigType_Name."); - return IceCandidatePairConfig_IceCandidatePairConfigType_Name(enum_t_value); - } - static inline bool IceCandidatePairConfigType_Parse(const std::string& name, - IceCandidatePairConfigType* value) { - return IceCandidatePairConfig_IceCandidatePairConfigType_Parse(name, value); - } - - typedef IceCandidatePairConfig_IceCandidateType IceCandidateType; - static constexpr IceCandidateType LOCAL = - IceCandidatePairConfig_IceCandidateType_LOCAL; - static constexpr IceCandidateType STUN = - IceCandidatePairConfig_IceCandidateType_STUN; - static constexpr IceCandidateType PRFLX = - IceCandidatePairConfig_IceCandidateType_PRFLX; - static constexpr IceCandidateType RELAY = - IceCandidatePairConfig_IceCandidateType_RELAY; - static constexpr IceCandidateType UNKNOWN_CANDIDATE_TYPE = - IceCandidatePairConfig_IceCandidateType_UNKNOWN_CANDIDATE_TYPE; - static inline bool IceCandidateType_IsValid(int value) { - return IceCandidatePairConfig_IceCandidateType_IsValid(value); - } - static constexpr IceCandidateType IceCandidateType_MIN = - IceCandidatePairConfig_IceCandidateType_IceCandidateType_MIN; - static constexpr IceCandidateType IceCandidateType_MAX = - IceCandidatePairConfig_IceCandidateType_IceCandidateType_MAX; - static constexpr int IceCandidateType_ARRAYSIZE = - IceCandidatePairConfig_IceCandidateType_IceCandidateType_ARRAYSIZE; - template - static inline const std::string& IceCandidateType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidateType_Name."); - return IceCandidatePairConfig_IceCandidateType_Name(enum_t_value); - } - static inline bool IceCandidateType_Parse(const std::string& name, - IceCandidateType* value) { - return IceCandidatePairConfig_IceCandidateType_Parse(name, value); - } - - typedef IceCandidatePairConfig_Protocol Protocol; - static constexpr Protocol UDP = - IceCandidatePairConfig_Protocol_UDP; - static constexpr Protocol TCP = - IceCandidatePairConfig_Protocol_TCP; - static constexpr Protocol SSLTCP = - IceCandidatePairConfig_Protocol_SSLTCP; - static constexpr Protocol TLS = - IceCandidatePairConfig_Protocol_TLS; - static constexpr Protocol UNKNOWN_PROTOCOL = - IceCandidatePairConfig_Protocol_UNKNOWN_PROTOCOL; - static inline bool Protocol_IsValid(int value) { - return IceCandidatePairConfig_Protocol_IsValid(value); - } - static constexpr Protocol Protocol_MIN = - IceCandidatePairConfig_Protocol_Protocol_MIN; - static constexpr Protocol Protocol_MAX = - IceCandidatePairConfig_Protocol_Protocol_MAX; - static constexpr int Protocol_ARRAYSIZE = - IceCandidatePairConfig_Protocol_Protocol_ARRAYSIZE; - template - static inline const std::string& Protocol_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function Protocol_Name."); - return IceCandidatePairConfig_Protocol_Name(enum_t_value); - } - static inline bool Protocol_Parse(const std::string& name, - Protocol* value) { - return IceCandidatePairConfig_Protocol_Parse(name, value); - } - - typedef IceCandidatePairConfig_AddressFamily AddressFamily; - static constexpr AddressFamily IPV4 = - IceCandidatePairConfig_AddressFamily_IPV4; - static constexpr AddressFamily IPV6 = - IceCandidatePairConfig_AddressFamily_IPV6; - static constexpr AddressFamily UNKNOWN_ADDRESS_FAMILY = - IceCandidatePairConfig_AddressFamily_UNKNOWN_ADDRESS_FAMILY; - static inline bool AddressFamily_IsValid(int value) { - return IceCandidatePairConfig_AddressFamily_IsValid(value); - } - static constexpr AddressFamily AddressFamily_MIN = - IceCandidatePairConfig_AddressFamily_AddressFamily_MIN; - static constexpr AddressFamily AddressFamily_MAX = - IceCandidatePairConfig_AddressFamily_AddressFamily_MAX; - static constexpr int AddressFamily_ARRAYSIZE = - IceCandidatePairConfig_AddressFamily_AddressFamily_ARRAYSIZE; - template - static inline const std::string& AddressFamily_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function AddressFamily_Name."); - return IceCandidatePairConfig_AddressFamily_Name(enum_t_value); - } - static inline bool AddressFamily_Parse(const std::string& name, - AddressFamily* value) { - return IceCandidatePairConfig_AddressFamily_Parse(name, value); - } - - typedef IceCandidatePairConfig_NetworkType NetworkType; - static constexpr NetworkType ETHERNET = - IceCandidatePairConfig_NetworkType_ETHERNET; - static constexpr NetworkType LOOPBACK = - IceCandidatePairConfig_NetworkType_LOOPBACK; - static constexpr NetworkType WIFI = - IceCandidatePairConfig_NetworkType_WIFI; - static constexpr NetworkType VPN = - IceCandidatePairConfig_NetworkType_VPN; - static constexpr NetworkType CELLULAR = - IceCandidatePairConfig_NetworkType_CELLULAR; - static constexpr NetworkType UNKNOWN_NETWORK_TYPE = - IceCandidatePairConfig_NetworkType_UNKNOWN_NETWORK_TYPE; - static inline bool NetworkType_IsValid(int value) { - return IceCandidatePairConfig_NetworkType_IsValid(value); - } - static constexpr NetworkType NetworkType_MIN = - IceCandidatePairConfig_NetworkType_NetworkType_MIN; - static constexpr NetworkType NetworkType_MAX = - IceCandidatePairConfig_NetworkType_NetworkType_MAX; - static constexpr int NetworkType_ARRAYSIZE = - IceCandidatePairConfig_NetworkType_NetworkType_ARRAYSIZE; - template - static inline const std::string& NetworkType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function NetworkType_Name."); - return IceCandidatePairConfig_NetworkType_Name(enum_t_value); - } - static inline bool NetworkType_Parse(const std::string& name, - NetworkType* value) { - return IceCandidatePairConfig_NetworkType_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kConfigTypeFieldNumber = 1, - kCandidatePairIdFieldNumber = 2, - kLocalCandidateTypeFieldNumber = 3, - kLocalRelayProtocolFieldNumber = 4, - kLocalNetworkTypeFieldNumber = 5, - kLocalAddressFamilyFieldNumber = 6, - kRemoteCandidateTypeFieldNumber = 7, - kRemoteAddressFamilyFieldNumber = 8, - kCandidatePairProtocolFieldNumber = 9, - }; - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 1; - bool has_config_type() const; - void clear_config_type(); - ::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType config_type() const; - void set_config_type(::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType value); - - // optional uint32 candidate_pair_id = 2; - bool has_candidate_pair_id() const; - void clear_candidate_pair_id(); - ::PROTOBUF_NAMESPACE_ID::uint32 candidate_pair_id() const; - void set_candidate_pair_id(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType local_candidate_type = 3; - bool has_local_candidate_type() const; - void clear_local_candidate_type(); - ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType local_candidate_type() const; - void set_local_candidate_type(::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType value); - - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol local_relay_protocol = 4; - bool has_local_relay_protocol() const; - void clear_local_relay_protocol(); - ::webrtc::rtclog::IceCandidatePairConfig_Protocol local_relay_protocol() const; - void set_local_relay_protocol(::webrtc::rtclog::IceCandidatePairConfig_Protocol value); - - // optional .webrtc.rtclog.IceCandidatePairConfig.NetworkType local_network_type = 5; - bool has_local_network_type() const; - void clear_local_network_type(); - ::webrtc::rtclog::IceCandidatePairConfig_NetworkType local_network_type() const; - void set_local_network_type(::webrtc::rtclog::IceCandidatePairConfig_NetworkType value); - - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily local_address_family = 6; - bool has_local_address_family() const; - void clear_local_address_family(); - ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily local_address_family() const; - void set_local_address_family(::webrtc::rtclog::IceCandidatePairConfig_AddressFamily value); - - // optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 7; - bool has_remote_candidate_type() const; - void clear_remote_candidate_type(); - ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType remote_candidate_type() const; - void set_remote_candidate_type(::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType value); - - // optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily remote_address_family = 8; - bool has_remote_address_family() const; - void clear_remote_address_family(); - ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily remote_address_family() const; - void set_remote_address_family(::webrtc::rtclog::IceCandidatePairConfig_AddressFamily value); - - // optional .webrtc.rtclog.IceCandidatePairConfig.Protocol candidate_pair_protocol = 9; - bool has_candidate_pair_protocol() const; - void clear_candidate_pair_protocol(); - ::webrtc::rtclog::IceCandidatePairConfig_Protocol candidate_pair_protocol() const; - void set_candidate_pair_protocol(::webrtc::rtclog::IceCandidatePairConfig_Protocol value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.IceCandidatePairConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - int config_type_; - ::PROTOBUF_NAMESPACE_ID::uint32 candidate_pair_id_; - int local_candidate_type_; - int local_relay_protocol_; - int local_network_type_; - int local_address_family_; - int remote_candidate_type_; - int remote_address_family_; - int candidate_pair_protocol_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// ------------------------------------------------------------------- - -class IceCandidatePairEvent : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog.IceCandidatePairEvent) */ { - public: - IceCandidatePairEvent(); - virtual ~IceCandidatePairEvent(); - - IceCandidatePairEvent(const IceCandidatePairEvent& from); - IceCandidatePairEvent(IceCandidatePairEvent&& from) noexcept - : IceCandidatePairEvent() { - *this = ::std::move(from); - } - - inline IceCandidatePairEvent& operator=(const IceCandidatePairEvent& from) { - CopyFrom(from); - return *this; - } - inline IceCandidatePairEvent& operator=(IceCandidatePairEvent&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const IceCandidatePairEvent& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const IceCandidatePairEvent* internal_default_instance() { - return reinterpret_cast( - &_IceCandidatePairEvent_default_instance_); - } - static constexpr int kIndexInFileMessages = - 21; - - friend void swap(IceCandidatePairEvent& a, IceCandidatePairEvent& b) { - a.Swap(&b); - } - inline void Swap(IceCandidatePairEvent* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline IceCandidatePairEvent* New() const final { - return CreateMaybeMessage(nullptr); - } - - IceCandidatePairEvent* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const IceCandidatePairEvent& from); - void MergeFrom(const IceCandidatePairEvent& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(IceCandidatePairEvent* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog.IceCandidatePairEvent"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEventType; - static constexpr IceCandidatePairEventType CHECK_SENT = - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_SENT; - static constexpr IceCandidatePairEventType CHECK_RECEIVED = - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RECEIVED; - static constexpr IceCandidatePairEventType CHECK_RESPONSE_SENT = - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_SENT; - static constexpr IceCandidatePairEventType CHECK_RESPONSE_RECEIVED = - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_RECEIVED; - static inline bool IceCandidatePairEventType_IsValid(int value) { - return IceCandidatePairEvent_IceCandidatePairEventType_IsValid(value); - } - static constexpr IceCandidatePairEventType IceCandidatePairEventType_MIN = - IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MIN; - static constexpr IceCandidatePairEventType IceCandidatePairEventType_MAX = - IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MAX; - static constexpr int IceCandidatePairEventType_ARRAYSIZE = - IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_ARRAYSIZE; - template - static inline const std::string& IceCandidatePairEventType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairEventType_Name."); - return IceCandidatePairEvent_IceCandidatePairEventType_Name(enum_t_value); - } - static inline bool IceCandidatePairEventType_Parse(const std::string& name, - IceCandidatePairEventType* value) { - return IceCandidatePairEvent_IceCandidatePairEventType_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kEventTypeFieldNumber = 1, - kCandidatePairIdFieldNumber = 2, - }; - // optional .webrtc.rtclog.IceCandidatePairEvent.IceCandidatePairEventType event_type = 1; - bool has_event_type() const; - void clear_event_type(); - ::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType event_type() const; - void set_event_type(::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType value); - - // optional uint32 candidate_pair_id = 2; - bool has_candidate_pair_id() const; - void clear_candidate_pair_id(); - ::PROTOBUF_NAMESPACE_ID::uint32 candidate_pair_id() const; - void set_candidate_pair_id(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog.IceCandidatePairEvent) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - int event_type_; - ::PROTOBUF_NAMESPACE_ID::uint32 candidate_pair_id_; - friend struct ::TableStruct_rtc_5fevent_5flog_2eproto; -}; -// =================================================================== - - -// =================================================================== - -#ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // __GNUC__ -// EventStream - -// repeated .webrtc.rtclog.Event stream = 1; -inline int EventStream::stream_size() const { - return stream_.size(); -} -inline void EventStream::clear_stream() { - stream_.Clear(); -} -inline ::webrtc::rtclog::Event* EventStream::mutable_stream(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.EventStream.stream) - return stream_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::Event >* -EventStream::mutable_stream() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.EventStream.stream) - return &stream_; -} -inline const ::webrtc::rtclog::Event& EventStream::stream(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.EventStream.stream) - return stream_.Get(index); -} -inline ::webrtc::rtclog::Event* EventStream::add_stream() { - // @@protoc_insertion_point(field_add:webrtc.rtclog.EventStream.stream) - return stream_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::Event >& -EventStream::stream() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.EventStream.stream) - return stream_; -} - -// ------------------------------------------------------------------- - -// Event - -// optional int64 timestamp_us = 1; -inline bool Event::has_timestamp_us() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void Event::clear_timestamp_us() { - timestamp_us_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 Event::timestamp_us() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.timestamp_us) - return timestamp_us_; -} -inline void Event::set_timestamp_us(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_us_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.Event.timestamp_us) -} - -// optional .webrtc.rtclog.Event.EventType type = 2; -inline bool Event::has_type() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void Event::clear_type() { - type_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::webrtc::rtclog::Event_EventType Event::type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.type) - return static_cast< ::webrtc::rtclog::Event_EventType >(type_); -} -inline void Event::set_type(::webrtc::rtclog::Event_EventType value) { - assert(::webrtc::rtclog::Event_EventType_IsValid(value)); - _has_bits_[0] |= 0x00000002u; - type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.Event.type) -} - -// optional .webrtc.rtclog.RtpPacket rtp_packet = 3; -inline bool Event::has_rtp_packet() const { - return subtype_case() == kRtpPacket; -} -inline void Event::set_has_rtp_packet() { - _oneof_case_[0] = kRtpPacket; -} -inline void Event::clear_rtp_packet() { - if (has_rtp_packet()) { - delete subtype_.rtp_packet_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::RtpPacket* Event::release_rtp_packet() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.rtp_packet) - if (has_rtp_packet()) { - clear_has_subtype(); - ::webrtc::rtclog::RtpPacket* temp = subtype_.rtp_packet_; - subtype_.rtp_packet_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::RtpPacket& Event::rtp_packet() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.rtp_packet) - return has_rtp_packet() - ? *subtype_.rtp_packet_ - : *reinterpret_cast< ::webrtc::rtclog::RtpPacket*>(&::webrtc::rtclog::_RtpPacket_default_instance_); -} -inline ::webrtc::rtclog::RtpPacket* Event::mutable_rtp_packet() { - if (!has_rtp_packet()) { - clear_subtype(); - set_has_rtp_packet(); - subtype_.rtp_packet_ = CreateMaybeMessage< ::webrtc::rtclog::RtpPacket >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.rtp_packet) - return subtype_.rtp_packet_; -} - -// optional .webrtc.rtclog.RtcpPacket rtcp_packet = 4; -inline bool Event::has_rtcp_packet() const { - return subtype_case() == kRtcpPacket; -} -inline void Event::set_has_rtcp_packet() { - _oneof_case_[0] = kRtcpPacket; -} -inline void Event::clear_rtcp_packet() { - if (has_rtcp_packet()) { - delete subtype_.rtcp_packet_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::RtcpPacket* Event::release_rtcp_packet() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.rtcp_packet) - if (has_rtcp_packet()) { - clear_has_subtype(); - ::webrtc::rtclog::RtcpPacket* temp = subtype_.rtcp_packet_; - subtype_.rtcp_packet_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::RtcpPacket& Event::rtcp_packet() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.rtcp_packet) - return has_rtcp_packet() - ? *subtype_.rtcp_packet_ - : *reinterpret_cast< ::webrtc::rtclog::RtcpPacket*>(&::webrtc::rtclog::_RtcpPacket_default_instance_); -} -inline ::webrtc::rtclog::RtcpPacket* Event::mutable_rtcp_packet() { - if (!has_rtcp_packet()) { - clear_subtype(); - set_has_rtcp_packet(); - subtype_.rtcp_packet_ = CreateMaybeMessage< ::webrtc::rtclog::RtcpPacket >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.rtcp_packet) - return subtype_.rtcp_packet_; -} - -// optional .webrtc.rtclog.AudioPlayoutEvent audio_playout_event = 5; -inline bool Event::has_audio_playout_event() const { - return subtype_case() == kAudioPlayoutEvent; -} -inline void Event::set_has_audio_playout_event() { - _oneof_case_[0] = kAudioPlayoutEvent; -} -inline void Event::clear_audio_playout_event() { - if (has_audio_playout_event()) { - delete subtype_.audio_playout_event_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::AudioPlayoutEvent* Event::release_audio_playout_event() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.audio_playout_event) - if (has_audio_playout_event()) { - clear_has_subtype(); - ::webrtc::rtclog::AudioPlayoutEvent* temp = subtype_.audio_playout_event_; - subtype_.audio_playout_event_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::AudioPlayoutEvent& Event::audio_playout_event() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.audio_playout_event) - return has_audio_playout_event() - ? *subtype_.audio_playout_event_ - : *reinterpret_cast< ::webrtc::rtclog::AudioPlayoutEvent*>(&::webrtc::rtclog::_AudioPlayoutEvent_default_instance_); -} -inline ::webrtc::rtclog::AudioPlayoutEvent* Event::mutable_audio_playout_event() { - if (!has_audio_playout_event()) { - clear_subtype(); - set_has_audio_playout_event(); - subtype_.audio_playout_event_ = CreateMaybeMessage< ::webrtc::rtclog::AudioPlayoutEvent >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.audio_playout_event) - return subtype_.audio_playout_event_; -} - -// optional .webrtc.rtclog.LossBasedBweUpdate loss_based_bwe_update = 6; -inline bool Event::has_loss_based_bwe_update() const { - return subtype_case() == kLossBasedBweUpdate; -} -inline void Event::set_has_loss_based_bwe_update() { - _oneof_case_[0] = kLossBasedBweUpdate; -} -inline void Event::clear_loss_based_bwe_update() { - if (has_loss_based_bwe_update()) { - delete subtype_.loss_based_bwe_update_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::LossBasedBweUpdate* Event::release_loss_based_bwe_update() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.loss_based_bwe_update) - if (has_loss_based_bwe_update()) { - clear_has_subtype(); - ::webrtc::rtclog::LossBasedBweUpdate* temp = subtype_.loss_based_bwe_update_; - subtype_.loss_based_bwe_update_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::LossBasedBweUpdate& Event::loss_based_bwe_update() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.loss_based_bwe_update) - return has_loss_based_bwe_update() - ? *subtype_.loss_based_bwe_update_ - : *reinterpret_cast< ::webrtc::rtclog::LossBasedBweUpdate*>(&::webrtc::rtclog::_LossBasedBweUpdate_default_instance_); -} -inline ::webrtc::rtclog::LossBasedBweUpdate* Event::mutable_loss_based_bwe_update() { - if (!has_loss_based_bwe_update()) { - clear_subtype(); - set_has_loss_based_bwe_update(); - subtype_.loss_based_bwe_update_ = CreateMaybeMessage< ::webrtc::rtclog::LossBasedBweUpdate >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.loss_based_bwe_update) - return subtype_.loss_based_bwe_update_; -} - -// optional .webrtc.rtclog.DelayBasedBweUpdate delay_based_bwe_update = 7; -inline bool Event::has_delay_based_bwe_update() const { - return subtype_case() == kDelayBasedBweUpdate; -} -inline void Event::set_has_delay_based_bwe_update() { - _oneof_case_[0] = kDelayBasedBweUpdate; -} -inline void Event::clear_delay_based_bwe_update() { - if (has_delay_based_bwe_update()) { - delete subtype_.delay_based_bwe_update_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::DelayBasedBweUpdate* Event::release_delay_based_bwe_update() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.delay_based_bwe_update) - if (has_delay_based_bwe_update()) { - clear_has_subtype(); - ::webrtc::rtclog::DelayBasedBweUpdate* temp = subtype_.delay_based_bwe_update_; - subtype_.delay_based_bwe_update_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::DelayBasedBweUpdate& Event::delay_based_bwe_update() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.delay_based_bwe_update) - return has_delay_based_bwe_update() - ? *subtype_.delay_based_bwe_update_ - : *reinterpret_cast< ::webrtc::rtclog::DelayBasedBweUpdate*>(&::webrtc::rtclog::_DelayBasedBweUpdate_default_instance_); -} -inline ::webrtc::rtclog::DelayBasedBweUpdate* Event::mutable_delay_based_bwe_update() { - if (!has_delay_based_bwe_update()) { - clear_subtype(); - set_has_delay_based_bwe_update(); - subtype_.delay_based_bwe_update_ = CreateMaybeMessage< ::webrtc::rtclog::DelayBasedBweUpdate >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.delay_based_bwe_update) - return subtype_.delay_based_bwe_update_; -} - -// optional .webrtc.rtclog.VideoReceiveConfig video_receiver_config = 8; -inline bool Event::has_video_receiver_config() const { - return subtype_case() == kVideoReceiverConfig; -} -inline void Event::set_has_video_receiver_config() { - _oneof_case_[0] = kVideoReceiverConfig; -} -inline void Event::clear_video_receiver_config() { - if (has_video_receiver_config()) { - delete subtype_.video_receiver_config_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::VideoReceiveConfig* Event::release_video_receiver_config() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.video_receiver_config) - if (has_video_receiver_config()) { - clear_has_subtype(); - ::webrtc::rtclog::VideoReceiveConfig* temp = subtype_.video_receiver_config_; - subtype_.video_receiver_config_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::VideoReceiveConfig& Event::video_receiver_config() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.video_receiver_config) - return has_video_receiver_config() - ? *subtype_.video_receiver_config_ - : *reinterpret_cast< ::webrtc::rtclog::VideoReceiveConfig*>(&::webrtc::rtclog::_VideoReceiveConfig_default_instance_); -} -inline ::webrtc::rtclog::VideoReceiveConfig* Event::mutable_video_receiver_config() { - if (!has_video_receiver_config()) { - clear_subtype(); - set_has_video_receiver_config(); - subtype_.video_receiver_config_ = CreateMaybeMessage< ::webrtc::rtclog::VideoReceiveConfig >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.video_receiver_config) - return subtype_.video_receiver_config_; -} - -// optional .webrtc.rtclog.VideoSendConfig video_sender_config = 9; -inline bool Event::has_video_sender_config() const { - return subtype_case() == kVideoSenderConfig; -} -inline void Event::set_has_video_sender_config() { - _oneof_case_[0] = kVideoSenderConfig; -} -inline void Event::clear_video_sender_config() { - if (has_video_sender_config()) { - delete subtype_.video_sender_config_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::VideoSendConfig* Event::release_video_sender_config() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.video_sender_config) - if (has_video_sender_config()) { - clear_has_subtype(); - ::webrtc::rtclog::VideoSendConfig* temp = subtype_.video_sender_config_; - subtype_.video_sender_config_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::VideoSendConfig& Event::video_sender_config() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.video_sender_config) - return has_video_sender_config() - ? *subtype_.video_sender_config_ - : *reinterpret_cast< ::webrtc::rtclog::VideoSendConfig*>(&::webrtc::rtclog::_VideoSendConfig_default_instance_); -} -inline ::webrtc::rtclog::VideoSendConfig* Event::mutable_video_sender_config() { - if (!has_video_sender_config()) { - clear_subtype(); - set_has_video_sender_config(); - subtype_.video_sender_config_ = CreateMaybeMessage< ::webrtc::rtclog::VideoSendConfig >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.video_sender_config) - return subtype_.video_sender_config_; -} - -// optional .webrtc.rtclog.AudioReceiveConfig audio_receiver_config = 10; -inline bool Event::has_audio_receiver_config() const { - return subtype_case() == kAudioReceiverConfig; -} -inline void Event::set_has_audio_receiver_config() { - _oneof_case_[0] = kAudioReceiverConfig; -} -inline void Event::clear_audio_receiver_config() { - if (has_audio_receiver_config()) { - delete subtype_.audio_receiver_config_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::AudioReceiveConfig* Event::release_audio_receiver_config() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.audio_receiver_config) - if (has_audio_receiver_config()) { - clear_has_subtype(); - ::webrtc::rtclog::AudioReceiveConfig* temp = subtype_.audio_receiver_config_; - subtype_.audio_receiver_config_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::AudioReceiveConfig& Event::audio_receiver_config() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.audio_receiver_config) - return has_audio_receiver_config() - ? *subtype_.audio_receiver_config_ - : *reinterpret_cast< ::webrtc::rtclog::AudioReceiveConfig*>(&::webrtc::rtclog::_AudioReceiveConfig_default_instance_); -} -inline ::webrtc::rtclog::AudioReceiveConfig* Event::mutable_audio_receiver_config() { - if (!has_audio_receiver_config()) { - clear_subtype(); - set_has_audio_receiver_config(); - subtype_.audio_receiver_config_ = CreateMaybeMessage< ::webrtc::rtclog::AudioReceiveConfig >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.audio_receiver_config) - return subtype_.audio_receiver_config_; -} - -// optional .webrtc.rtclog.AudioSendConfig audio_sender_config = 11; -inline bool Event::has_audio_sender_config() const { - return subtype_case() == kAudioSenderConfig; -} -inline void Event::set_has_audio_sender_config() { - _oneof_case_[0] = kAudioSenderConfig; -} -inline void Event::clear_audio_sender_config() { - if (has_audio_sender_config()) { - delete subtype_.audio_sender_config_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::AudioSendConfig* Event::release_audio_sender_config() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.audio_sender_config) - if (has_audio_sender_config()) { - clear_has_subtype(); - ::webrtc::rtclog::AudioSendConfig* temp = subtype_.audio_sender_config_; - subtype_.audio_sender_config_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::AudioSendConfig& Event::audio_sender_config() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.audio_sender_config) - return has_audio_sender_config() - ? *subtype_.audio_sender_config_ - : *reinterpret_cast< ::webrtc::rtclog::AudioSendConfig*>(&::webrtc::rtclog::_AudioSendConfig_default_instance_); -} -inline ::webrtc::rtclog::AudioSendConfig* Event::mutable_audio_sender_config() { - if (!has_audio_sender_config()) { - clear_subtype(); - set_has_audio_sender_config(); - subtype_.audio_sender_config_ = CreateMaybeMessage< ::webrtc::rtclog::AudioSendConfig >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.audio_sender_config) - return subtype_.audio_sender_config_; -} - -// optional .webrtc.rtclog.AudioNetworkAdaptation audio_network_adaptation = 16; -inline bool Event::has_audio_network_adaptation() const { - return subtype_case() == kAudioNetworkAdaptation; -} -inline void Event::set_has_audio_network_adaptation() { - _oneof_case_[0] = kAudioNetworkAdaptation; -} -inline void Event::clear_audio_network_adaptation() { - if (has_audio_network_adaptation()) { - delete subtype_.audio_network_adaptation_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::AudioNetworkAdaptation* Event::release_audio_network_adaptation() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.audio_network_adaptation) - if (has_audio_network_adaptation()) { - clear_has_subtype(); - ::webrtc::rtclog::AudioNetworkAdaptation* temp = subtype_.audio_network_adaptation_; - subtype_.audio_network_adaptation_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::AudioNetworkAdaptation& Event::audio_network_adaptation() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.audio_network_adaptation) - return has_audio_network_adaptation() - ? *subtype_.audio_network_adaptation_ - : *reinterpret_cast< ::webrtc::rtclog::AudioNetworkAdaptation*>(&::webrtc::rtclog::_AudioNetworkAdaptation_default_instance_); -} -inline ::webrtc::rtclog::AudioNetworkAdaptation* Event::mutable_audio_network_adaptation() { - if (!has_audio_network_adaptation()) { - clear_subtype(); - set_has_audio_network_adaptation(); - subtype_.audio_network_adaptation_ = CreateMaybeMessage< ::webrtc::rtclog::AudioNetworkAdaptation >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.audio_network_adaptation) - return subtype_.audio_network_adaptation_; -} - -// optional .webrtc.rtclog.BweProbeCluster probe_cluster = 17; -inline bool Event::has_probe_cluster() const { - return subtype_case() == kProbeCluster; -} -inline void Event::set_has_probe_cluster() { - _oneof_case_[0] = kProbeCluster; -} -inline void Event::clear_probe_cluster() { - if (has_probe_cluster()) { - delete subtype_.probe_cluster_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::BweProbeCluster* Event::release_probe_cluster() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.probe_cluster) - if (has_probe_cluster()) { - clear_has_subtype(); - ::webrtc::rtclog::BweProbeCluster* temp = subtype_.probe_cluster_; - subtype_.probe_cluster_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::BweProbeCluster& Event::probe_cluster() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.probe_cluster) - return has_probe_cluster() - ? *subtype_.probe_cluster_ - : *reinterpret_cast< ::webrtc::rtclog::BweProbeCluster*>(&::webrtc::rtclog::_BweProbeCluster_default_instance_); -} -inline ::webrtc::rtclog::BweProbeCluster* Event::mutable_probe_cluster() { - if (!has_probe_cluster()) { - clear_subtype(); - set_has_probe_cluster(); - subtype_.probe_cluster_ = CreateMaybeMessage< ::webrtc::rtclog::BweProbeCluster >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.probe_cluster) - return subtype_.probe_cluster_; -} - -// optional .webrtc.rtclog.BweProbeResult probe_result = 18; -inline bool Event::has_probe_result() const { - return subtype_case() == kProbeResult; -} -inline void Event::set_has_probe_result() { - _oneof_case_[0] = kProbeResult; -} -inline void Event::clear_probe_result() { - if (has_probe_result()) { - delete subtype_.probe_result_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::BweProbeResult* Event::release_probe_result() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.probe_result) - if (has_probe_result()) { - clear_has_subtype(); - ::webrtc::rtclog::BweProbeResult* temp = subtype_.probe_result_; - subtype_.probe_result_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::BweProbeResult& Event::probe_result() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.probe_result) - return has_probe_result() - ? *subtype_.probe_result_ - : *reinterpret_cast< ::webrtc::rtclog::BweProbeResult*>(&::webrtc::rtclog::_BweProbeResult_default_instance_); -} -inline ::webrtc::rtclog::BweProbeResult* Event::mutable_probe_result() { - if (!has_probe_result()) { - clear_subtype(); - set_has_probe_result(); - subtype_.probe_result_ = CreateMaybeMessage< ::webrtc::rtclog::BweProbeResult >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.probe_result) - return subtype_.probe_result_; -} - -// optional .webrtc.rtclog.AlrState alr_state = 19; -inline bool Event::has_alr_state() const { - return subtype_case() == kAlrState; -} -inline void Event::set_has_alr_state() { - _oneof_case_[0] = kAlrState; -} -inline void Event::clear_alr_state() { - if (has_alr_state()) { - delete subtype_.alr_state_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::AlrState* Event::release_alr_state() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.alr_state) - if (has_alr_state()) { - clear_has_subtype(); - ::webrtc::rtclog::AlrState* temp = subtype_.alr_state_; - subtype_.alr_state_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::AlrState& Event::alr_state() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.alr_state) - return has_alr_state() - ? *subtype_.alr_state_ - : *reinterpret_cast< ::webrtc::rtclog::AlrState*>(&::webrtc::rtclog::_AlrState_default_instance_); -} -inline ::webrtc::rtclog::AlrState* Event::mutable_alr_state() { - if (!has_alr_state()) { - clear_subtype(); - set_has_alr_state(); - subtype_.alr_state_ = CreateMaybeMessage< ::webrtc::rtclog::AlrState >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.alr_state) - return subtype_.alr_state_; -} - -// optional .webrtc.rtclog.IceCandidatePairConfig ice_candidate_pair_config = 20; -inline bool Event::has_ice_candidate_pair_config() const { - return subtype_case() == kIceCandidatePairConfig; -} -inline void Event::set_has_ice_candidate_pair_config() { - _oneof_case_[0] = kIceCandidatePairConfig; -} -inline void Event::clear_ice_candidate_pair_config() { - if (has_ice_candidate_pair_config()) { - delete subtype_.ice_candidate_pair_config_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::IceCandidatePairConfig* Event::release_ice_candidate_pair_config() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.ice_candidate_pair_config) - if (has_ice_candidate_pair_config()) { - clear_has_subtype(); - ::webrtc::rtclog::IceCandidatePairConfig* temp = subtype_.ice_candidate_pair_config_; - subtype_.ice_candidate_pair_config_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::IceCandidatePairConfig& Event::ice_candidate_pair_config() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.ice_candidate_pair_config) - return has_ice_candidate_pair_config() - ? *subtype_.ice_candidate_pair_config_ - : *reinterpret_cast< ::webrtc::rtclog::IceCandidatePairConfig*>(&::webrtc::rtclog::_IceCandidatePairConfig_default_instance_); -} -inline ::webrtc::rtclog::IceCandidatePairConfig* Event::mutable_ice_candidate_pair_config() { - if (!has_ice_candidate_pair_config()) { - clear_subtype(); - set_has_ice_candidate_pair_config(); - subtype_.ice_candidate_pair_config_ = CreateMaybeMessage< ::webrtc::rtclog::IceCandidatePairConfig >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.ice_candidate_pair_config) - return subtype_.ice_candidate_pair_config_; -} - -// optional .webrtc.rtclog.IceCandidatePairEvent ice_candidate_pair_event = 21; -inline bool Event::has_ice_candidate_pair_event() const { - return subtype_case() == kIceCandidatePairEvent; -} -inline void Event::set_has_ice_candidate_pair_event() { - _oneof_case_[0] = kIceCandidatePairEvent; -} -inline void Event::clear_ice_candidate_pair_event() { - if (has_ice_candidate_pair_event()) { - delete subtype_.ice_candidate_pair_event_; - clear_has_subtype(); - } -} -inline ::webrtc::rtclog::IceCandidatePairEvent* Event::release_ice_candidate_pair_event() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.Event.ice_candidate_pair_event) - if (has_ice_candidate_pair_event()) { - clear_has_subtype(); - ::webrtc::rtclog::IceCandidatePairEvent* temp = subtype_.ice_candidate_pair_event_; - subtype_.ice_candidate_pair_event_ = nullptr; - return temp; - } else { - return nullptr; - } -} -inline const ::webrtc::rtclog::IceCandidatePairEvent& Event::ice_candidate_pair_event() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.Event.ice_candidate_pair_event) - return has_ice_candidate_pair_event() - ? *subtype_.ice_candidate_pair_event_ - : *reinterpret_cast< ::webrtc::rtclog::IceCandidatePairEvent*>(&::webrtc::rtclog::_IceCandidatePairEvent_default_instance_); -} -inline ::webrtc::rtclog::IceCandidatePairEvent* Event::mutable_ice_candidate_pair_event() { - if (!has_ice_candidate_pair_event()) { - clear_subtype(); - set_has_ice_candidate_pair_event(); - subtype_.ice_candidate_pair_event_ = CreateMaybeMessage< ::webrtc::rtclog::IceCandidatePairEvent >( - GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.Event.ice_candidate_pair_event) - return subtype_.ice_candidate_pair_event_; -} - -inline bool Event::has_subtype() const { - return subtype_case() != SUBTYPE_NOT_SET; -} -inline void Event::clear_has_subtype() { - _oneof_case_[0] = SUBTYPE_NOT_SET; -} -inline Event::SubtypeCase Event::subtype_case() const { - return Event::SubtypeCase(_oneof_case_[0]); -} -// ------------------------------------------------------------------- - -// RtpPacket - -// optional bool incoming = 1; -inline bool RtpPacket::has_incoming() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void RtpPacket::clear_incoming() { - incoming_ = false; - _has_bits_[0] &= ~0x00000002u; -} -inline bool RtpPacket::incoming() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtpPacket.incoming) - return incoming_; -} -inline void RtpPacket::set_incoming(bool value) { - _has_bits_[0] |= 0x00000002u; - incoming_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtpPacket.incoming) -} - -// optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; -inline bool RtpPacket::has_type() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void RtpPacket::clear_type() { - type_ = 0; - _has_bits_[0] &= ~0x00000004u; -} -inline ::webrtc::rtclog::MediaType RtpPacket::type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtpPacket.type) - return static_cast< ::webrtc::rtclog::MediaType >(type_); -} -inline void RtpPacket::set_type(::webrtc::rtclog::MediaType value) { - assert(::webrtc::rtclog::MediaType_IsValid(value)); - _has_bits_[0] |= 0x00000004u; - type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtpPacket.type) -} - -// optional uint32 packet_length = 3; -inline bool RtpPacket::has_packet_length() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void RtpPacket::clear_packet_length() { - packet_length_ = 0u; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 RtpPacket::packet_length() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtpPacket.packet_length) - return packet_length_; -} -inline void RtpPacket::set_packet_length(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000008u; - packet_length_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtpPacket.packet_length) -} - -// optional bytes header = 4; -inline bool RtpPacket::has_header() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void RtpPacket::clear_header() { - header_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& RtpPacket::header() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtpPacket.header) - return header_.GetNoArena(); -} -inline void RtpPacket::set_header(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - header_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtpPacket.header) -} -inline void RtpPacket::set_header(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - header_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog.RtpPacket.header) -} -inline void RtpPacket::set_header(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - header_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog.RtpPacket.header) -} -inline void RtpPacket::set_header(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - header_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog.RtpPacket.header) -} -inline std::string* RtpPacket::mutable_header() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.RtpPacket.header) - return header_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* RtpPacket::release_header() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.RtpPacket.header) - if (!has_header()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return header_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void RtpPacket::set_allocated_header(std::string* header) { - if (header != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - header_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), header); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.RtpPacket.header) -} - -// optional int32 probe_cluster_id = 5; -inline bool RtpPacket::has_probe_cluster_id() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void RtpPacket::clear_probe_cluster_id() { - probe_cluster_id_ = 0; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtpPacket::probe_cluster_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtpPacket.probe_cluster_id) - return probe_cluster_id_; -} -inline void RtpPacket::set_probe_cluster_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000010u; - probe_cluster_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtpPacket.probe_cluster_id) -} - -// ------------------------------------------------------------------- - -// RtcpPacket - -// optional bool incoming = 1; -inline bool RtcpPacket::has_incoming() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void RtcpPacket::clear_incoming() { - incoming_ = false; - _has_bits_[0] &= ~0x00000002u; -} -inline bool RtcpPacket::incoming() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtcpPacket.incoming) - return incoming_; -} -inline void RtcpPacket::set_incoming(bool value) { - _has_bits_[0] |= 0x00000002u; - incoming_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtcpPacket.incoming) -} - -// optional .webrtc.rtclog.MediaType type = 2 [deprecated = true]; -inline bool RtcpPacket::has_type() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void RtcpPacket::clear_type() { - type_ = 0; - _has_bits_[0] &= ~0x00000004u; -} -inline ::webrtc::rtclog::MediaType RtcpPacket::type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtcpPacket.type) - return static_cast< ::webrtc::rtclog::MediaType >(type_); -} -inline void RtcpPacket::set_type(::webrtc::rtclog::MediaType value) { - assert(::webrtc::rtclog::MediaType_IsValid(value)); - _has_bits_[0] |= 0x00000004u; - type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtcpPacket.type) -} - -// optional bytes packet_data = 3; -inline bool RtcpPacket::has_packet_data() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void RtcpPacket::clear_packet_data() { - packet_data_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& RtcpPacket::packet_data() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtcpPacket.packet_data) - return packet_data_.GetNoArena(); -} -inline void RtcpPacket::set_packet_data(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - packet_data_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtcpPacket.packet_data) -} -inline void RtcpPacket::set_packet_data(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - packet_data_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog.RtcpPacket.packet_data) -} -inline void RtcpPacket::set_packet_data(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - packet_data_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog.RtcpPacket.packet_data) -} -inline void RtcpPacket::set_packet_data(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - packet_data_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog.RtcpPacket.packet_data) -} -inline std::string* RtcpPacket::mutable_packet_data() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.RtcpPacket.packet_data) - return packet_data_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* RtcpPacket::release_packet_data() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.RtcpPacket.packet_data) - if (!has_packet_data()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return packet_data_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void RtcpPacket::set_allocated_packet_data(std::string* packet_data) { - if (packet_data != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - packet_data_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), packet_data); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.RtcpPacket.packet_data) -} - -// ------------------------------------------------------------------- - -// AudioPlayoutEvent - -// optional uint32 local_ssrc = 2; -inline bool AudioPlayoutEvent::has_local_ssrc() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AudioPlayoutEvent::clear_local_ssrc() { - local_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioPlayoutEvent::local_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioPlayoutEvent.local_ssrc) - return local_ssrc_; -} -inline void AudioPlayoutEvent::set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000001u; - local_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioPlayoutEvent.local_ssrc) -} - -// ------------------------------------------------------------------- - -// LossBasedBweUpdate - -// optional int32 bitrate_bps = 1; -inline bool LossBasedBweUpdate::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void LossBasedBweUpdate::clear_bitrate_bps() { - bitrate_bps_ = 0; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 LossBasedBweUpdate::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.LossBasedBweUpdate.bitrate_bps) - return bitrate_bps_; -} -inline void LossBasedBweUpdate::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000001u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.LossBasedBweUpdate.bitrate_bps) -} - -// optional uint32 fraction_loss = 2; -inline bool LossBasedBweUpdate::has_fraction_loss() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void LossBasedBweUpdate::clear_fraction_loss() { - fraction_loss_ = 0u; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 LossBasedBweUpdate::fraction_loss() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.LossBasedBweUpdate.fraction_loss) - return fraction_loss_; -} -inline void LossBasedBweUpdate::set_fraction_loss(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000002u; - fraction_loss_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.LossBasedBweUpdate.fraction_loss) -} - -// optional int32 total_packets = 3; -inline bool LossBasedBweUpdate::has_total_packets() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void LossBasedBweUpdate::clear_total_packets() { - total_packets_ = 0; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 LossBasedBweUpdate::total_packets() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.LossBasedBweUpdate.total_packets) - return total_packets_; -} -inline void LossBasedBweUpdate::set_total_packets(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000004u; - total_packets_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.LossBasedBweUpdate.total_packets) -} - -// ------------------------------------------------------------------- - -// DelayBasedBweUpdate - -// optional int32 bitrate_bps = 1; -inline bool DelayBasedBweUpdate::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void DelayBasedBweUpdate::clear_bitrate_bps() { - bitrate_bps_ = 0; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 DelayBasedBweUpdate::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.DelayBasedBweUpdate.bitrate_bps) - return bitrate_bps_; -} -inline void DelayBasedBweUpdate::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000001u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.DelayBasedBweUpdate.bitrate_bps) -} - -// optional .webrtc.rtclog.DelayBasedBweUpdate.DetectorState detector_state = 2; -inline bool DelayBasedBweUpdate::has_detector_state() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void DelayBasedBweUpdate::clear_detector_state() { - detector_state_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::webrtc::rtclog::DelayBasedBweUpdate_DetectorState DelayBasedBweUpdate::detector_state() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.DelayBasedBweUpdate.detector_state) - return static_cast< ::webrtc::rtclog::DelayBasedBweUpdate_DetectorState >(detector_state_); -} -inline void DelayBasedBweUpdate::set_detector_state(::webrtc::rtclog::DelayBasedBweUpdate_DetectorState value) { - assert(::webrtc::rtclog::DelayBasedBweUpdate_DetectorState_IsValid(value)); - _has_bits_[0] |= 0x00000002u; - detector_state_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.DelayBasedBweUpdate.detector_state) -} - -// ------------------------------------------------------------------- - -// VideoReceiveConfig - -// optional uint32 remote_ssrc = 1; -inline bool VideoReceiveConfig::has_remote_ssrc() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void VideoReceiveConfig::clear_remote_ssrc() { - remote_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoReceiveConfig::remote_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoReceiveConfig.remote_ssrc) - return remote_ssrc_; -} -inline void VideoReceiveConfig::set_remote_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000001u; - remote_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.VideoReceiveConfig.remote_ssrc) -} - -// optional uint32 local_ssrc = 2; -inline bool VideoReceiveConfig::has_local_ssrc() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void VideoReceiveConfig::clear_local_ssrc() { - local_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoReceiveConfig::local_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoReceiveConfig.local_ssrc) - return local_ssrc_; -} -inline void VideoReceiveConfig::set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000002u; - local_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.VideoReceiveConfig.local_ssrc) -} - -// optional .webrtc.rtclog.VideoReceiveConfig.RtcpMode rtcp_mode = 3; -inline bool VideoReceiveConfig::has_rtcp_mode() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void VideoReceiveConfig::clear_rtcp_mode() { - rtcp_mode_ = 1; - _has_bits_[0] &= ~0x00000008u; -} -inline ::webrtc::rtclog::VideoReceiveConfig_RtcpMode VideoReceiveConfig::rtcp_mode() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoReceiveConfig.rtcp_mode) - return static_cast< ::webrtc::rtclog::VideoReceiveConfig_RtcpMode >(rtcp_mode_); -} -inline void VideoReceiveConfig::set_rtcp_mode(::webrtc::rtclog::VideoReceiveConfig_RtcpMode value) { - assert(::webrtc::rtclog::VideoReceiveConfig_RtcpMode_IsValid(value)); - _has_bits_[0] |= 0x00000008u; - rtcp_mode_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.VideoReceiveConfig.rtcp_mode) -} - -// optional bool remb = 4; -inline bool VideoReceiveConfig::has_remb() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void VideoReceiveConfig::clear_remb() { - remb_ = false; - _has_bits_[0] &= ~0x00000004u; -} -inline bool VideoReceiveConfig::remb() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoReceiveConfig.remb) - return remb_; -} -inline void VideoReceiveConfig::set_remb(bool value) { - _has_bits_[0] |= 0x00000004u; - remb_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.VideoReceiveConfig.remb) -} - -// repeated .webrtc.rtclog.RtxMap rtx_map = 5; -inline int VideoReceiveConfig::rtx_map_size() const { - return rtx_map_.size(); -} -inline void VideoReceiveConfig::clear_rtx_map() { - rtx_map_.Clear(); -} -inline ::webrtc::rtclog::RtxMap* VideoReceiveConfig::mutable_rtx_map(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.VideoReceiveConfig.rtx_map) - return rtx_map_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtxMap >* -VideoReceiveConfig::mutable_rtx_map() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.VideoReceiveConfig.rtx_map) - return &rtx_map_; -} -inline const ::webrtc::rtclog::RtxMap& VideoReceiveConfig::rtx_map(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoReceiveConfig.rtx_map) - return rtx_map_.Get(index); -} -inline ::webrtc::rtclog::RtxMap* VideoReceiveConfig::add_rtx_map() { - // @@protoc_insertion_point(field_add:webrtc.rtclog.VideoReceiveConfig.rtx_map) - return rtx_map_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtxMap >& -VideoReceiveConfig::rtx_map() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.VideoReceiveConfig.rtx_map) - return rtx_map_; -} - -// repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 6; -inline int VideoReceiveConfig::header_extensions_size() const { - return header_extensions_.size(); -} -inline void VideoReceiveConfig::clear_header_extensions() { - header_extensions_.Clear(); -} -inline ::webrtc::rtclog::RtpHeaderExtension* VideoReceiveConfig::mutable_header_extensions(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.VideoReceiveConfig.header_extensions) - return header_extensions_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >* -VideoReceiveConfig::mutable_header_extensions() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.VideoReceiveConfig.header_extensions) - return &header_extensions_; -} -inline const ::webrtc::rtclog::RtpHeaderExtension& VideoReceiveConfig::header_extensions(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoReceiveConfig.header_extensions) - return header_extensions_.Get(index); -} -inline ::webrtc::rtclog::RtpHeaderExtension* VideoReceiveConfig::add_header_extensions() { - // @@protoc_insertion_point(field_add:webrtc.rtclog.VideoReceiveConfig.header_extensions) - return header_extensions_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >& -VideoReceiveConfig::header_extensions() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.VideoReceiveConfig.header_extensions) - return header_extensions_; -} - -// repeated .webrtc.rtclog.DecoderConfig decoders = 7; -inline int VideoReceiveConfig::decoders_size() const { - return decoders_.size(); -} -inline void VideoReceiveConfig::clear_decoders() { - decoders_.Clear(); -} -inline ::webrtc::rtclog::DecoderConfig* VideoReceiveConfig::mutable_decoders(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.VideoReceiveConfig.decoders) - return decoders_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::DecoderConfig >* -VideoReceiveConfig::mutable_decoders() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.VideoReceiveConfig.decoders) - return &decoders_; -} -inline const ::webrtc::rtclog::DecoderConfig& VideoReceiveConfig::decoders(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoReceiveConfig.decoders) - return decoders_.Get(index); -} -inline ::webrtc::rtclog::DecoderConfig* VideoReceiveConfig::add_decoders() { - // @@protoc_insertion_point(field_add:webrtc.rtclog.VideoReceiveConfig.decoders) - return decoders_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::DecoderConfig >& -VideoReceiveConfig::decoders() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.VideoReceiveConfig.decoders) - return decoders_; -} - -// ------------------------------------------------------------------- - -// DecoderConfig - -// optional string name = 1; -inline bool DecoderConfig::has_name() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void DecoderConfig::clear_name() { - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& DecoderConfig::name() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.DecoderConfig.name) - return name_.GetNoArena(); -} -inline void DecoderConfig::set_name(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog.DecoderConfig.name) -} -inline void DecoderConfig::set_name(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog.DecoderConfig.name) -} -inline void DecoderConfig::set_name(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog.DecoderConfig.name) -} -inline void DecoderConfig::set_name(const char* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog.DecoderConfig.name) -} -inline std::string* DecoderConfig::mutable_name() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.DecoderConfig.name) - return name_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* DecoderConfig::release_name() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.DecoderConfig.name) - if (!has_name()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void DecoderConfig::set_allocated_name(std::string* name) { - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.DecoderConfig.name) -} - -// optional int32 payload_type = 2; -inline bool DecoderConfig::has_payload_type() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void DecoderConfig::clear_payload_type() { - payload_type_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 DecoderConfig::payload_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.DecoderConfig.payload_type) - return payload_type_; -} -inline void DecoderConfig::set_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - payload_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.DecoderConfig.payload_type) -} - -// ------------------------------------------------------------------- - -// RtpHeaderExtension - -// optional string name = 1; -inline bool RtpHeaderExtension::has_name() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void RtpHeaderExtension::clear_name() { - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& RtpHeaderExtension::name() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtpHeaderExtension.name) - return name_.GetNoArena(); -} -inline void RtpHeaderExtension::set_name(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtpHeaderExtension.name) -} -inline void RtpHeaderExtension::set_name(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog.RtpHeaderExtension.name) -} -inline void RtpHeaderExtension::set_name(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog.RtpHeaderExtension.name) -} -inline void RtpHeaderExtension::set_name(const char* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog.RtpHeaderExtension.name) -} -inline std::string* RtpHeaderExtension::mutable_name() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.RtpHeaderExtension.name) - return name_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* RtpHeaderExtension::release_name() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.RtpHeaderExtension.name) - if (!has_name()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void RtpHeaderExtension::set_allocated_name(std::string* name) { - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.RtpHeaderExtension.name) -} - -// optional int32 id = 2; -inline bool RtpHeaderExtension::has_id() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void RtpHeaderExtension::clear_id() { - id_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtpHeaderExtension::id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtpHeaderExtension.id) - return id_; -} -inline void RtpHeaderExtension::set_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtpHeaderExtension.id) -} - -// ------------------------------------------------------------------- - -// RtxConfig - -// optional uint32 rtx_ssrc = 1; -inline bool RtxConfig::has_rtx_ssrc() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void RtxConfig::clear_rtx_ssrc() { - rtx_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 RtxConfig::rtx_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtxConfig.rtx_ssrc) - return rtx_ssrc_; -} -inline void RtxConfig::set_rtx_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000001u; - rtx_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtxConfig.rtx_ssrc) -} - -// optional int32 rtx_payload_type = 2; -inline bool RtxConfig::has_rtx_payload_type() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void RtxConfig::clear_rtx_payload_type() { - rtx_payload_type_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtxConfig::rtx_payload_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtxConfig.rtx_payload_type) - return rtx_payload_type_; -} -inline void RtxConfig::set_rtx_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - rtx_payload_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtxConfig.rtx_payload_type) -} - -// ------------------------------------------------------------------- - -// RtxMap - -// optional int32 payload_type = 1; -inline bool RtxMap::has_payload_type() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void RtxMap::clear_payload_type() { - payload_type_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtxMap::payload_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtxMap.payload_type) - return payload_type_; -} -inline void RtxMap::set_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - payload_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.RtxMap.payload_type) -} - -// optional .webrtc.rtclog.RtxConfig config = 2; -inline bool RtxMap::has_config() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void RtxMap::clear_config() { - if (config_ != nullptr) config_->Clear(); - _has_bits_[0] &= ~0x00000001u; -} -inline const ::webrtc::rtclog::RtxConfig& RtxMap::config() const { - const ::webrtc::rtclog::RtxConfig* p = config_; - // @@protoc_insertion_point(field_get:webrtc.rtclog.RtxMap.config) - return p != nullptr ? *p : *reinterpret_cast( - &::webrtc::rtclog::_RtxConfig_default_instance_); -} -inline ::webrtc::rtclog::RtxConfig* RtxMap::release_config() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.RtxMap.config) - _has_bits_[0] &= ~0x00000001u; - ::webrtc::rtclog::RtxConfig* temp = config_; - config_ = nullptr; - return temp; -} -inline ::webrtc::rtclog::RtxConfig* RtxMap::mutable_config() { - _has_bits_[0] |= 0x00000001u; - if (config_ == nullptr) { - auto* p = CreateMaybeMessage<::webrtc::rtclog::RtxConfig>(GetArenaNoVirtual()); - config_ = p; - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.RtxMap.config) - return config_; -} -inline void RtxMap::set_allocated_config(::webrtc::rtclog::RtxConfig* config) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - if (message_arena == nullptr) { - delete config_; - } - if (config) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - config = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, config, submessage_arena); - } - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - config_ = config; - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.RtxMap.config) -} - -// ------------------------------------------------------------------- - -// VideoSendConfig - -// repeated uint32 ssrcs = 1; -inline int VideoSendConfig::ssrcs_size() const { - return ssrcs_.size(); -} -inline void VideoSendConfig::clear_ssrcs() { - ssrcs_.Clear(); -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoSendConfig::ssrcs(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoSendConfig.ssrcs) - return ssrcs_.Get(index); -} -inline void VideoSendConfig::set_ssrcs(int index, ::PROTOBUF_NAMESPACE_ID::uint32 value) { - ssrcs_.Set(index, value); - // @@protoc_insertion_point(field_set:webrtc.rtclog.VideoSendConfig.ssrcs) -} -inline void VideoSendConfig::add_ssrcs(::PROTOBUF_NAMESPACE_ID::uint32 value) { - ssrcs_.Add(value); - // @@protoc_insertion_point(field_add:webrtc.rtclog.VideoSendConfig.ssrcs) -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 >& -VideoSendConfig::ssrcs() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.VideoSendConfig.ssrcs) - return ssrcs_; -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 >* -VideoSendConfig::mutable_ssrcs() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.VideoSendConfig.ssrcs) - return &ssrcs_; -} - -// repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; -inline int VideoSendConfig::header_extensions_size() const { - return header_extensions_.size(); -} -inline void VideoSendConfig::clear_header_extensions() { - header_extensions_.Clear(); -} -inline ::webrtc::rtclog::RtpHeaderExtension* VideoSendConfig::mutable_header_extensions(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.VideoSendConfig.header_extensions) - return header_extensions_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >* -VideoSendConfig::mutable_header_extensions() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.VideoSendConfig.header_extensions) - return &header_extensions_; -} -inline const ::webrtc::rtclog::RtpHeaderExtension& VideoSendConfig::header_extensions(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoSendConfig.header_extensions) - return header_extensions_.Get(index); -} -inline ::webrtc::rtclog::RtpHeaderExtension* VideoSendConfig::add_header_extensions() { - // @@protoc_insertion_point(field_add:webrtc.rtclog.VideoSendConfig.header_extensions) - return header_extensions_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >& -VideoSendConfig::header_extensions() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.VideoSendConfig.header_extensions) - return header_extensions_; -} - -// repeated uint32 rtx_ssrcs = 3; -inline int VideoSendConfig::rtx_ssrcs_size() const { - return rtx_ssrcs_.size(); -} -inline void VideoSendConfig::clear_rtx_ssrcs() { - rtx_ssrcs_.Clear(); -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoSendConfig::rtx_ssrcs(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoSendConfig.rtx_ssrcs) - return rtx_ssrcs_.Get(index); -} -inline void VideoSendConfig::set_rtx_ssrcs(int index, ::PROTOBUF_NAMESPACE_ID::uint32 value) { - rtx_ssrcs_.Set(index, value); - // @@protoc_insertion_point(field_set:webrtc.rtclog.VideoSendConfig.rtx_ssrcs) -} -inline void VideoSendConfig::add_rtx_ssrcs(::PROTOBUF_NAMESPACE_ID::uint32 value) { - rtx_ssrcs_.Add(value); - // @@protoc_insertion_point(field_add:webrtc.rtclog.VideoSendConfig.rtx_ssrcs) -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 >& -VideoSendConfig::rtx_ssrcs() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.VideoSendConfig.rtx_ssrcs) - return rtx_ssrcs_; -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::uint32 >* -VideoSendConfig::mutable_rtx_ssrcs() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.VideoSendConfig.rtx_ssrcs) - return &rtx_ssrcs_; -} - -// optional int32 rtx_payload_type = 4; -inline bool VideoSendConfig::has_rtx_payload_type() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void VideoSendConfig::clear_rtx_payload_type() { - rtx_payload_type_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 VideoSendConfig::rtx_payload_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoSendConfig.rtx_payload_type) - return rtx_payload_type_; -} -inline void VideoSendConfig::set_rtx_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - rtx_payload_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.VideoSendConfig.rtx_payload_type) -} - -// optional .webrtc.rtclog.EncoderConfig encoder = 5; -inline bool VideoSendConfig::has_encoder() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void VideoSendConfig::clear_encoder() { - if (encoder_ != nullptr) encoder_->Clear(); - _has_bits_[0] &= ~0x00000001u; -} -inline const ::webrtc::rtclog::EncoderConfig& VideoSendConfig::encoder() const { - const ::webrtc::rtclog::EncoderConfig* p = encoder_; - // @@protoc_insertion_point(field_get:webrtc.rtclog.VideoSendConfig.encoder) - return p != nullptr ? *p : *reinterpret_cast( - &::webrtc::rtclog::_EncoderConfig_default_instance_); -} -inline ::webrtc::rtclog::EncoderConfig* VideoSendConfig::release_encoder() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.VideoSendConfig.encoder) - _has_bits_[0] &= ~0x00000001u; - ::webrtc::rtclog::EncoderConfig* temp = encoder_; - encoder_ = nullptr; - return temp; -} -inline ::webrtc::rtclog::EncoderConfig* VideoSendConfig::mutable_encoder() { - _has_bits_[0] |= 0x00000001u; - if (encoder_ == nullptr) { - auto* p = CreateMaybeMessage<::webrtc::rtclog::EncoderConfig>(GetArenaNoVirtual()); - encoder_ = p; - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.VideoSendConfig.encoder) - return encoder_; -} -inline void VideoSendConfig::set_allocated_encoder(::webrtc::rtclog::EncoderConfig* encoder) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - if (message_arena == nullptr) { - delete encoder_; - } - if (encoder) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - encoder = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, encoder, submessage_arena); - } - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - encoder_ = encoder; - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.VideoSendConfig.encoder) -} - -// ------------------------------------------------------------------- - -// EncoderConfig - -// optional string name = 1; -inline bool EncoderConfig::has_name() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void EncoderConfig::clear_name() { - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& EncoderConfig::name() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.EncoderConfig.name) - return name_.GetNoArena(); -} -inline void EncoderConfig::set_name(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog.EncoderConfig.name) -} -inline void EncoderConfig::set_name(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog.EncoderConfig.name) -} -inline void EncoderConfig::set_name(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog.EncoderConfig.name) -} -inline void EncoderConfig::set_name(const char* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog.EncoderConfig.name) -} -inline std::string* EncoderConfig::mutable_name() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.EncoderConfig.name) - return name_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* EncoderConfig::release_name() { - // @@protoc_insertion_point(field_release:webrtc.rtclog.EncoderConfig.name) - if (!has_name()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void EncoderConfig::set_allocated_name(std::string* name) { - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog.EncoderConfig.name) -} - -// optional int32 payload_type = 2; -inline bool EncoderConfig::has_payload_type() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void EncoderConfig::clear_payload_type() { - payload_type_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 EncoderConfig::payload_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.EncoderConfig.payload_type) - return payload_type_; -} -inline void EncoderConfig::set_payload_type(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - payload_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.EncoderConfig.payload_type) -} - -// ------------------------------------------------------------------- - -// AudioReceiveConfig - -// optional uint32 remote_ssrc = 1; -inline bool AudioReceiveConfig::has_remote_ssrc() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AudioReceiveConfig::clear_remote_ssrc() { - remote_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioReceiveConfig::remote_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioReceiveConfig.remote_ssrc) - return remote_ssrc_; -} -inline void AudioReceiveConfig::set_remote_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000001u; - remote_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioReceiveConfig.remote_ssrc) -} - -// optional uint32 local_ssrc = 2; -inline bool AudioReceiveConfig::has_local_ssrc() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void AudioReceiveConfig::clear_local_ssrc() { - local_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioReceiveConfig::local_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioReceiveConfig.local_ssrc) - return local_ssrc_; -} -inline void AudioReceiveConfig::set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000002u; - local_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioReceiveConfig.local_ssrc) -} - -// repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 3; -inline int AudioReceiveConfig::header_extensions_size() const { - return header_extensions_.size(); -} -inline void AudioReceiveConfig::clear_header_extensions() { - header_extensions_.Clear(); -} -inline ::webrtc::rtclog::RtpHeaderExtension* AudioReceiveConfig::mutable_header_extensions(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.AudioReceiveConfig.header_extensions) - return header_extensions_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >* -AudioReceiveConfig::mutable_header_extensions() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.AudioReceiveConfig.header_extensions) - return &header_extensions_; -} -inline const ::webrtc::rtclog::RtpHeaderExtension& AudioReceiveConfig::header_extensions(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioReceiveConfig.header_extensions) - return header_extensions_.Get(index); -} -inline ::webrtc::rtclog::RtpHeaderExtension* AudioReceiveConfig::add_header_extensions() { - // @@protoc_insertion_point(field_add:webrtc.rtclog.AudioReceiveConfig.header_extensions) - return header_extensions_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >& -AudioReceiveConfig::header_extensions() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.AudioReceiveConfig.header_extensions) - return header_extensions_; -} - -// ------------------------------------------------------------------- - -// AudioSendConfig - -// optional uint32 ssrc = 1; -inline bool AudioSendConfig::has_ssrc() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AudioSendConfig::clear_ssrc() { - ssrc_ = 0u; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioSendConfig::ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioSendConfig.ssrc) - return ssrc_; -} -inline void AudioSendConfig::set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000001u; - ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioSendConfig.ssrc) -} - -// repeated .webrtc.rtclog.RtpHeaderExtension header_extensions = 2; -inline int AudioSendConfig::header_extensions_size() const { - return header_extensions_.size(); -} -inline void AudioSendConfig::clear_header_extensions() { - header_extensions_.Clear(); -} -inline ::webrtc::rtclog::RtpHeaderExtension* AudioSendConfig::mutable_header_extensions(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog.AudioSendConfig.header_extensions) - return header_extensions_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >* -AudioSendConfig::mutable_header_extensions() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog.AudioSendConfig.header_extensions) - return &header_extensions_; -} -inline const ::webrtc::rtclog::RtpHeaderExtension& AudioSendConfig::header_extensions(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioSendConfig.header_extensions) - return header_extensions_.Get(index); -} -inline ::webrtc::rtclog::RtpHeaderExtension* AudioSendConfig::add_header_extensions() { - // @@protoc_insertion_point(field_add:webrtc.rtclog.AudioSendConfig.header_extensions) - return header_extensions_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog::RtpHeaderExtension >& -AudioSendConfig::header_extensions() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog.AudioSendConfig.header_extensions) - return header_extensions_; -} - -// ------------------------------------------------------------------- - -// AudioNetworkAdaptation - -// optional int32 bitrate_bps = 1; -inline bool AudioNetworkAdaptation::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AudioNetworkAdaptation::clear_bitrate_bps() { - bitrate_bps_ = 0; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 AudioNetworkAdaptation::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioNetworkAdaptation.bitrate_bps) - return bitrate_bps_; -} -inline void AudioNetworkAdaptation::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000001u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioNetworkAdaptation.bitrate_bps) -} - -// optional int32 frame_length_ms = 2; -inline bool AudioNetworkAdaptation::has_frame_length_ms() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void AudioNetworkAdaptation::clear_frame_length_ms() { - frame_length_ms_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 AudioNetworkAdaptation::frame_length_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioNetworkAdaptation.frame_length_ms) - return frame_length_ms_; -} -inline void AudioNetworkAdaptation::set_frame_length_ms(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - frame_length_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioNetworkAdaptation.frame_length_ms) -} - -// optional float uplink_packet_loss_fraction = 3; -inline bool AudioNetworkAdaptation::has_uplink_packet_loss_fraction() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void AudioNetworkAdaptation::clear_uplink_packet_loss_fraction() { - uplink_packet_loss_fraction_ = 0; - _has_bits_[0] &= ~0x00000004u; -} -inline float AudioNetworkAdaptation::uplink_packet_loss_fraction() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioNetworkAdaptation.uplink_packet_loss_fraction) - return uplink_packet_loss_fraction_; -} -inline void AudioNetworkAdaptation::set_uplink_packet_loss_fraction(float value) { - _has_bits_[0] |= 0x00000004u; - uplink_packet_loss_fraction_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioNetworkAdaptation.uplink_packet_loss_fraction) -} - -// optional bool enable_fec = 4; -inline bool AudioNetworkAdaptation::has_enable_fec() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void AudioNetworkAdaptation::clear_enable_fec() { - enable_fec_ = false; - _has_bits_[0] &= ~0x00000008u; -} -inline bool AudioNetworkAdaptation::enable_fec() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioNetworkAdaptation.enable_fec) - return enable_fec_; -} -inline void AudioNetworkAdaptation::set_enable_fec(bool value) { - _has_bits_[0] |= 0x00000008u; - enable_fec_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioNetworkAdaptation.enable_fec) -} - -// optional bool enable_dtx = 5; -inline bool AudioNetworkAdaptation::has_enable_dtx() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void AudioNetworkAdaptation::clear_enable_dtx() { - enable_dtx_ = false; - _has_bits_[0] &= ~0x00000010u; -} -inline bool AudioNetworkAdaptation::enable_dtx() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioNetworkAdaptation.enable_dtx) - return enable_dtx_; -} -inline void AudioNetworkAdaptation::set_enable_dtx(bool value) { - _has_bits_[0] |= 0x00000010u; - enable_dtx_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioNetworkAdaptation.enable_dtx) -} - -// optional uint32 num_channels = 6; -inline bool AudioNetworkAdaptation::has_num_channels() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void AudioNetworkAdaptation::clear_num_channels() { - num_channels_ = 0u; - _has_bits_[0] &= ~0x00000020u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioNetworkAdaptation::num_channels() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AudioNetworkAdaptation.num_channels) - return num_channels_; -} -inline void AudioNetworkAdaptation::set_num_channels(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000020u; - num_channels_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AudioNetworkAdaptation.num_channels) -} - -// ------------------------------------------------------------------- - -// BweProbeCluster - -// optional int32 id = 1; -inline bool BweProbeCluster::has_id() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void BweProbeCluster::clear_id() { - id_ = 0; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 BweProbeCluster::id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.BweProbeCluster.id) - return id_; -} -inline void BweProbeCluster::set_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000001u; - id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.BweProbeCluster.id) -} - -// optional int32 bitrate_bps = 2; -inline bool BweProbeCluster::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void BweProbeCluster::clear_bitrate_bps() { - bitrate_bps_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 BweProbeCluster::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.BweProbeCluster.bitrate_bps) - return bitrate_bps_; -} -inline void BweProbeCluster::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.BweProbeCluster.bitrate_bps) -} - -// optional uint32 min_packets = 3; -inline bool BweProbeCluster::has_min_packets() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void BweProbeCluster::clear_min_packets() { - min_packets_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeCluster::min_packets() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.BweProbeCluster.min_packets) - return min_packets_; -} -inline void BweProbeCluster::set_min_packets(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - min_packets_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.BweProbeCluster.min_packets) -} - -// optional uint32 min_bytes = 4; -inline bool BweProbeCluster::has_min_bytes() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void BweProbeCluster::clear_min_bytes() { - min_bytes_ = 0u; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeCluster::min_bytes() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.BweProbeCluster.min_bytes) - return min_bytes_; -} -inline void BweProbeCluster::set_min_bytes(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000008u; - min_bytes_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.BweProbeCluster.min_bytes) -} - -// ------------------------------------------------------------------- - -// BweProbeResult - -// optional int32 id = 1; -inline bool BweProbeResult::has_id() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void BweProbeResult::clear_id() { - id_ = 0; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 BweProbeResult::id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.BweProbeResult.id) - return id_; -} -inline void BweProbeResult::set_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000001u; - id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.BweProbeResult.id) -} - -// optional .webrtc.rtclog.BweProbeResult.ResultType result = 2; -inline bool BweProbeResult::has_result() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void BweProbeResult::clear_result() { - result_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::webrtc::rtclog::BweProbeResult_ResultType BweProbeResult::result() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.BweProbeResult.result) - return static_cast< ::webrtc::rtclog::BweProbeResult_ResultType >(result_); -} -inline void BweProbeResult::set_result(::webrtc::rtclog::BweProbeResult_ResultType value) { - assert(::webrtc::rtclog::BweProbeResult_ResultType_IsValid(value)); - _has_bits_[0] |= 0x00000002u; - result_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.BweProbeResult.result) -} - -// optional int32 bitrate_bps = 3; -inline bool BweProbeResult::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void BweProbeResult::clear_bitrate_bps() { - bitrate_bps_ = 0; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 BweProbeResult::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.BweProbeResult.bitrate_bps) - return bitrate_bps_; -} -inline void BweProbeResult::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000004u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.BweProbeResult.bitrate_bps) -} - -// ------------------------------------------------------------------- - -// AlrState - -// optional bool in_alr = 1; -inline bool AlrState::has_in_alr() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AlrState::clear_in_alr() { - in_alr_ = false; - _has_bits_[0] &= ~0x00000001u; -} -inline bool AlrState::in_alr() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.AlrState.in_alr) - return in_alr_; -} -inline void AlrState::set_in_alr(bool value) { - _has_bits_[0] |= 0x00000001u; - in_alr_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.AlrState.in_alr) -} - -// ------------------------------------------------------------------- - -// IceCandidatePairConfig - -// optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 1; -inline bool IceCandidatePairConfig::has_config_type() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void IceCandidatePairConfig::clear_config_type() { - config_type_ = 0; - _has_bits_[0] &= ~0x00000001u; -} -inline ::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::config_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.config_type) - return static_cast< ::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType >(config_type_); -} -inline void IceCandidatePairConfig::set_config_type(::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType value) { - assert(::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(value)); - _has_bits_[0] |= 0x00000001u; - config_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.config_type) -} - -// optional uint32 candidate_pair_id = 2; -inline bool IceCandidatePairConfig::has_candidate_pair_id() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void IceCandidatePairConfig::clear_candidate_pair_id() { - candidate_pair_id_ = 0u; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IceCandidatePairConfig::candidate_pair_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.candidate_pair_id) - return candidate_pair_id_; -} -inline void IceCandidatePairConfig::set_candidate_pair_id(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000002u; - candidate_pair_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.candidate_pair_id) -} - -// optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType local_candidate_type = 3; -inline bool IceCandidatePairConfig::has_local_candidate_type() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void IceCandidatePairConfig::clear_local_candidate_type() { - local_candidate_type_ = 0; - _has_bits_[0] &= ~0x00000004u; -} -inline ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::local_candidate_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.local_candidate_type) - return static_cast< ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType >(local_candidate_type_); -} -inline void IceCandidatePairConfig::set_local_candidate_type(::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType value) { - assert(::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType_IsValid(value)); - _has_bits_[0] |= 0x00000004u; - local_candidate_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.local_candidate_type) -} - -// optional .webrtc.rtclog.IceCandidatePairConfig.Protocol local_relay_protocol = 4; -inline bool IceCandidatePairConfig::has_local_relay_protocol() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void IceCandidatePairConfig::clear_local_relay_protocol() { - local_relay_protocol_ = 0; - _has_bits_[0] &= ~0x00000008u; -} -inline ::webrtc::rtclog::IceCandidatePairConfig_Protocol IceCandidatePairConfig::local_relay_protocol() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.local_relay_protocol) - return static_cast< ::webrtc::rtclog::IceCandidatePairConfig_Protocol >(local_relay_protocol_); -} -inline void IceCandidatePairConfig::set_local_relay_protocol(::webrtc::rtclog::IceCandidatePairConfig_Protocol value) { - assert(::webrtc::rtclog::IceCandidatePairConfig_Protocol_IsValid(value)); - _has_bits_[0] |= 0x00000008u; - local_relay_protocol_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.local_relay_protocol) -} - -// optional .webrtc.rtclog.IceCandidatePairConfig.NetworkType local_network_type = 5; -inline bool IceCandidatePairConfig::has_local_network_type() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void IceCandidatePairConfig::clear_local_network_type() { - local_network_type_ = 0; - _has_bits_[0] &= ~0x00000010u; -} -inline ::webrtc::rtclog::IceCandidatePairConfig_NetworkType IceCandidatePairConfig::local_network_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.local_network_type) - return static_cast< ::webrtc::rtclog::IceCandidatePairConfig_NetworkType >(local_network_type_); -} -inline void IceCandidatePairConfig::set_local_network_type(::webrtc::rtclog::IceCandidatePairConfig_NetworkType value) { - assert(::webrtc::rtclog::IceCandidatePairConfig_NetworkType_IsValid(value)); - _has_bits_[0] |= 0x00000010u; - local_network_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.local_network_type) -} - -// optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily local_address_family = 6; -inline bool IceCandidatePairConfig::has_local_address_family() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void IceCandidatePairConfig::clear_local_address_family() { - local_address_family_ = 0; - _has_bits_[0] &= ~0x00000020u; -} -inline ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::local_address_family() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.local_address_family) - return static_cast< ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily >(local_address_family_); -} -inline void IceCandidatePairConfig::set_local_address_family(::webrtc::rtclog::IceCandidatePairConfig_AddressFamily value) { - assert(::webrtc::rtclog::IceCandidatePairConfig_AddressFamily_IsValid(value)); - _has_bits_[0] |= 0x00000020u; - local_address_family_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.local_address_family) -} - -// optional .webrtc.rtclog.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 7; -inline bool IceCandidatePairConfig::has_remote_candidate_type() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void IceCandidatePairConfig::clear_remote_candidate_type() { - remote_candidate_type_ = 0; - _has_bits_[0] &= ~0x00000040u; -} -inline ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::remote_candidate_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.remote_candidate_type) - return static_cast< ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType >(remote_candidate_type_); -} -inline void IceCandidatePairConfig::set_remote_candidate_type(::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType value) { - assert(::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType_IsValid(value)); - _has_bits_[0] |= 0x00000040u; - remote_candidate_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.remote_candidate_type) -} - -// optional .webrtc.rtclog.IceCandidatePairConfig.AddressFamily remote_address_family = 8; -inline bool IceCandidatePairConfig::has_remote_address_family() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void IceCandidatePairConfig::clear_remote_address_family() { - remote_address_family_ = 0; - _has_bits_[0] &= ~0x00000080u; -} -inline ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::remote_address_family() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.remote_address_family) - return static_cast< ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily >(remote_address_family_); -} -inline void IceCandidatePairConfig::set_remote_address_family(::webrtc::rtclog::IceCandidatePairConfig_AddressFamily value) { - assert(::webrtc::rtclog::IceCandidatePairConfig_AddressFamily_IsValid(value)); - _has_bits_[0] |= 0x00000080u; - remote_address_family_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.remote_address_family) -} - -// optional .webrtc.rtclog.IceCandidatePairConfig.Protocol candidate_pair_protocol = 9; -inline bool IceCandidatePairConfig::has_candidate_pair_protocol() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void IceCandidatePairConfig::clear_candidate_pair_protocol() { - candidate_pair_protocol_ = 0; - _has_bits_[0] &= ~0x00000100u; -} -inline ::webrtc::rtclog::IceCandidatePairConfig_Protocol IceCandidatePairConfig::candidate_pair_protocol() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairConfig.candidate_pair_protocol) - return static_cast< ::webrtc::rtclog::IceCandidatePairConfig_Protocol >(candidate_pair_protocol_); -} -inline void IceCandidatePairConfig::set_candidate_pair_protocol(::webrtc::rtclog::IceCandidatePairConfig_Protocol value) { - assert(::webrtc::rtclog::IceCandidatePairConfig_Protocol_IsValid(value)); - _has_bits_[0] |= 0x00000100u; - candidate_pair_protocol_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairConfig.candidate_pair_protocol) -} - -// ------------------------------------------------------------------- - -// IceCandidatePairEvent - -// optional .webrtc.rtclog.IceCandidatePairEvent.IceCandidatePairEventType event_type = 1; -inline bool IceCandidatePairEvent::has_event_type() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void IceCandidatePairEvent::clear_event_type() { - event_type_ = 0; - _has_bits_[0] &= ~0x00000001u; -} -inline ::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::event_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairEvent.event_type) - return static_cast< ::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType >(event_type_); -} -inline void IceCandidatePairEvent::set_event_type(::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType value) { - assert(::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType_IsValid(value)); - _has_bits_[0] |= 0x00000001u; - event_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairEvent.event_type) -} - -// optional uint32 candidate_pair_id = 2; -inline bool IceCandidatePairEvent::has_candidate_pair_id() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void IceCandidatePairEvent::clear_candidate_pair_id() { - candidate_pair_id_ = 0u; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IceCandidatePairEvent::candidate_pair_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog.IceCandidatePairEvent.candidate_pair_id) - return candidate_pair_id_; -} -inline void IceCandidatePairEvent::set_candidate_pair_id(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000002u; - candidate_pair_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog.IceCandidatePairEvent.candidate_pair_id) -} - -#ifdef __GNUC__ - #pragma GCC diagnostic pop -#endif // __GNUC__ -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace rtclog -} // namespace webrtc - -PROTOBUF_NAMESPACE_OPEN - -template <> struct is_proto_enum< ::webrtc::rtclog::Event_EventType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::DelayBasedBweUpdate_DetectorState> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::VideoReceiveConfig_RtcpMode> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::BweProbeResult_ResultType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::IceCandidatePairConfig_IceCandidatePairConfigType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::IceCandidatePairConfig_IceCandidateType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::IceCandidatePairConfig_Protocol> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::IceCandidatePairConfig_AddressFamily> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::IceCandidatePairConfig_NetworkType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::IceCandidatePairEvent_IceCandidatePairEventType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog::MediaType> : ::std::true_type {}; - -PROTOBUF_NAMESPACE_CLOSE - -// @@protoc_insertion_point(global_scope) - -#include -#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_rtc_5fevent_5flog_2eproto diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.cc b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.cc deleted file mode 100644 index ca7036346..000000000 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.cc +++ /dev/null @@ -1,18636 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: rtc_event_log2.proto - -#include "rtc_event_log2.pb.h" - -#include - -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) -#include -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AlrState_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AudioNetworkAdaptations_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AudioPlayoutEvents_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_AudioRecvStreamConfig_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_AudioSendStreamConfig_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BeginLogEvent_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeCluster_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeResultFailure_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeResultSuccess_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DelayBasedBweUpdates_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DtlsTransportStateEvent_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DtlsWritableState_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_EndLogEvent_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Event_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_FrameDecodedEvents_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GenericAckReceived_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GenericPacketReceived_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GenericPacketSent_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IceCandidatePairConfig_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IceCandidatePairEvent_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IncomingRtcpPackets_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IncomingRtpPackets_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_LossBasedBweUpdates_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_OutgoingRtcpPackets_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_OutgoingRtpPackets_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RemoteEstimates_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RouteChange_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_VideoRecvStreamConfig_rtc_5fevent_5flog2_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_VideoSendStreamConfig_rtc_5fevent_5flog2_2eproto; -namespace webrtc { -namespace rtclog2 { -class EventStreamDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _EventStream_default_instance_; -class EventDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _Event_default_instance_; -class GenericPacketReceivedDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _GenericPacketReceived_default_instance_; -class GenericPacketSentDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _GenericPacketSent_default_instance_; -class GenericAckReceivedDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _GenericAckReceived_default_instance_; -class IncomingRtpPacketsDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _IncomingRtpPackets_default_instance_; -class OutgoingRtpPacketsDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _OutgoingRtpPackets_default_instance_; -class IncomingRtcpPacketsDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _IncomingRtcpPackets_default_instance_; -class OutgoingRtcpPacketsDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _OutgoingRtcpPackets_default_instance_; -class AudioPlayoutEventsDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AudioPlayoutEvents_default_instance_; -class FrameDecodedEventsDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _FrameDecodedEvents_default_instance_; -class BeginLogEventDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _BeginLogEvent_default_instance_; -class EndLogEventDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _EndLogEvent_default_instance_; -class LossBasedBweUpdatesDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _LossBasedBweUpdates_default_instance_; -class DelayBasedBweUpdatesDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _DelayBasedBweUpdates_default_instance_; -class RtpHeaderExtensionConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _RtpHeaderExtensionConfig_default_instance_; -class VideoRecvStreamConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _VideoRecvStreamConfig_default_instance_; -class VideoSendStreamConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _VideoSendStreamConfig_default_instance_; -class AudioRecvStreamConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AudioRecvStreamConfig_default_instance_; -class AudioSendStreamConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AudioSendStreamConfig_default_instance_; -class AudioNetworkAdaptationsDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AudioNetworkAdaptations_default_instance_; -class BweProbeClusterDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _BweProbeCluster_default_instance_; -class BweProbeResultSuccessDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _BweProbeResultSuccess_default_instance_; -class BweProbeResultFailureDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _BweProbeResultFailure_default_instance_; -class AlrStateDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _AlrState_default_instance_; -class IceCandidatePairConfigDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _IceCandidatePairConfig_default_instance_; -class IceCandidatePairEventDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _IceCandidatePairEvent_default_instance_; -class DtlsTransportStateEventDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _DtlsTransportStateEvent_default_instance_; -class DtlsWritableStateDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _DtlsWritableState_default_instance_; -class RouteChangeDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _RouteChange_default_instance_; -class RemoteEstimatesDefaultTypeInternal { - public: - ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; -} _RemoteEstimates_default_instance_; -} // namespace rtclog2 -} // namespace webrtc -static void InitDefaultsscc_info_AlrState_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_AlrState_default_instance_; - new (ptr) ::webrtc::rtclog2::AlrState(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::AlrState::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AlrState_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_AlrState_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_AudioNetworkAdaptations_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_AudioNetworkAdaptations_default_instance_; - new (ptr) ::webrtc::rtclog2::AudioNetworkAdaptations(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::AudioNetworkAdaptations::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AudioNetworkAdaptations_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_AudioNetworkAdaptations_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_AudioPlayoutEvents_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_AudioPlayoutEvents_default_instance_; - new (ptr) ::webrtc::rtclog2::AudioPlayoutEvents(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::AudioPlayoutEvents::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_AudioPlayoutEvents_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_AudioPlayoutEvents_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_AudioRecvStreamConfig_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_AudioRecvStreamConfig_default_instance_; - new (ptr) ::webrtc::rtclog2::AudioRecvStreamConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::AudioRecvStreamConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_AudioRecvStreamConfig_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsscc_info_AudioRecvStreamConfig_rtc_5fevent_5flog2_2eproto}, { - &scc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto.base,}}; - -static void InitDefaultsscc_info_AudioSendStreamConfig_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_AudioSendStreamConfig_default_instance_; - new (ptr) ::webrtc::rtclog2::AudioSendStreamConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::AudioSendStreamConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_AudioSendStreamConfig_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsscc_info_AudioSendStreamConfig_rtc_5fevent_5flog2_2eproto}, { - &scc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto.base,}}; - -static void InitDefaultsscc_info_BeginLogEvent_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_BeginLogEvent_default_instance_; - new (ptr) ::webrtc::rtclog2::BeginLogEvent(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::BeginLogEvent::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BeginLogEvent_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_BeginLogEvent_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_BweProbeCluster_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_BweProbeCluster_default_instance_; - new (ptr) ::webrtc::rtclog2::BweProbeCluster(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::BweProbeCluster::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeCluster_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_BweProbeCluster_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_BweProbeResultFailure_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_BweProbeResultFailure_default_instance_; - new (ptr) ::webrtc::rtclog2::BweProbeResultFailure(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::BweProbeResultFailure::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeResultFailure_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_BweProbeResultFailure_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_BweProbeResultSuccess_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_BweProbeResultSuccess_default_instance_; - new (ptr) ::webrtc::rtclog2::BweProbeResultSuccess(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::BweProbeResultSuccess::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BweProbeResultSuccess_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_BweProbeResultSuccess_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_DelayBasedBweUpdates_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_DelayBasedBweUpdates_default_instance_; - new (ptr) ::webrtc::rtclog2::DelayBasedBweUpdates(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::DelayBasedBweUpdates::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DelayBasedBweUpdates_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_DelayBasedBweUpdates_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_DtlsTransportStateEvent_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_DtlsTransportStateEvent_default_instance_; - new (ptr) ::webrtc::rtclog2::DtlsTransportStateEvent(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::DtlsTransportStateEvent::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DtlsTransportStateEvent_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_DtlsTransportStateEvent_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_DtlsWritableState_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_DtlsWritableState_default_instance_; - new (ptr) ::webrtc::rtclog2::DtlsWritableState(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::DtlsWritableState::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DtlsWritableState_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_DtlsWritableState_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_EndLogEvent_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_EndLogEvent_default_instance_; - new (ptr) ::webrtc::rtclog2::EndLogEvent(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::EndLogEvent::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_EndLogEvent_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_EndLogEvent_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_Event_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_Event_default_instance_; - new (ptr) ::webrtc::rtclog2::Event(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::Event::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Event_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_Event_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_EventStream_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_EventStream_default_instance_; - new (ptr) ::webrtc::rtclog2::EventStream(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::EventStream::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<29> scc_info_EventStream_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 29, InitDefaultsscc_info_EventStream_rtc_5fevent_5flog2_2eproto}, { - &scc_info_Event_rtc_5fevent_5flog2_2eproto.base, - &scc_info_IncomingRtpPackets_rtc_5fevent_5flog2_2eproto.base, - &scc_info_OutgoingRtpPackets_rtc_5fevent_5flog2_2eproto.base, - &scc_info_IncomingRtcpPackets_rtc_5fevent_5flog2_2eproto.base, - &scc_info_OutgoingRtcpPackets_rtc_5fevent_5flog2_2eproto.base, - &scc_info_AudioPlayoutEvents_rtc_5fevent_5flog2_2eproto.base, - &scc_info_FrameDecodedEvents_rtc_5fevent_5flog2_2eproto.base, - &scc_info_BeginLogEvent_rtc_5fevent_5flog2_2eproto.base, - &scc_info_EndLogEvent_rtc_5fevent_5flog2_2eproto.base, - &scc_info_LossBasedBweUpdates_rtc_5fevent_5flog2_2eproto.base, - &scc_info_DelayBasedBweUpdates_rtc_5fevent_5flog2_2eproto.base, - &scc_info_AudioNetworkAdaptations_rtc_5fevent_5flog2_2eproto.base, - &scc_info_BweProbeCluster_rtc_5fevent_5flog2_2eproto.base, - &scc_info_BweProbeResultSuccess_rtc_5fevent_5flog2_2eproto.base, - &scc_info_BweProbeResultFailure_rtc_5fevent_5flog2_2eproto.base, - &scc_info_AlrState_rtc_5fevent_5flog2_2eproto.base, - &scc_info_IceCandidatePairConfig_rtc_5fevent_5flog2_2eproto.base, - &scc_info_IceCandidatePairEvent_rtc_5fevent_5flog2_2eproto.base, - &scc_info_DtlsTransportStateEvent_rtc_5fevent_5flog2_2eproto.base, - &scc_info_DtlsWritableState_rtc_5fevent_5flog2_2eproto.base, - &scc_info_GenericPacketSent_rtc_5fevent_5flog2_2eproto.base, - &scc_info_GenericPacketReceived_rtc_5fevent_5flog2_2eproto.base, - &scc_info_GenericAckReceived_rtc_5fevent_5flog2_2eproto.base, - &scc_info_RouteChange_rtc_5fevent_5flog2_2eproto.base, - &scc_info_RemoteEstimates_rtc_5fevent_5flog2_2eproto.base, - &scc_info_AudioRecvStreamConfig_rtc_5fevent_5flog2_2eproto.base, - &scc_info_AudioSendStreamConfig_rtc_5fevent_5flog2_2eproto.base, - &scc_info_VideoRecvStreamConfig_rtc_5fevent_5flog2_2eproto.base, - &scc_info_VideoSendStreamConfig_rtc_5fevent_5flog2_2eproto.base,}}; - -static void InitDefaultsscc_info_FrameDecodedEvents_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_FrameDecodedEvents_default_instance_; - new (ptr) ::webrtc::rtclog2::FrameDecodedEvents(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::FrameDecodedEvents::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_FrameDecodedEvents_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_FrameDecodedEvents_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_GenericAckReceived_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_GenericAckReceived_default_instance_; - new (ptr) ::webrtc::rtclog2::GenericAckReceived(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::GenericAckReceived::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GenericAckReceived_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_GenericAckReceived_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_GenericPacketReceived_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_GenericPacketReceived_default_instance_; - new (ptr) ::webrtc::rtclog2::GenericPacketReceived(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::GenericPacketReceived::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GenericPacketReceived_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_GenericPacketReceived_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_GenericPacketSent_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_GenericPacketSent_default_instance_; - new (ptr) ::webrtc::rtclog2::GenericPacketSent(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::GenericPacketSent::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GenericPacketSent_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_GenericPacketSent_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_IceCandidatePairConfig_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_IceCandidatePairConfig_default_instance_; - new (ptr) ::webrtc::rtclog2::IceCandidatePairConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::IceCandidatePairConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IceCandidatePairConfig_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_IceCandidatePairConfig_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_IceCandidatePairEvent_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_IceCandidatePairEvent_default_instance_; - new (ptr) ::webrtc::rtclog2::IceCandidatePairEvent(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::IceCandidatePairEvent::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IceCandidatePairEvent_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_IceCandidatePairEvent_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_IncomingRtcpPackets_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_IncomingRtcpPackets_default_instance_; - new (ptr) ::webrtc::rtclog2::IncomingRtcpPackets(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::IncomingRtcpPackets::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IncomingRtcpPackets_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_IncomingRtcpPackets_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_IncomingRtpPackets_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_IncomingRtpPackets_default_instance_; - new (ptr) ::webrtc::rtclog2::IncomingRtpPackets(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::IncomingRtpPackets::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_IncomingRtpPackets_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_IncomingRtpPackets_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_LossBasedBweUpdates_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_LossBasedBweUpdates_default_instance_; - new (ptr) ::webrtc::rtclog2::LossBasedBweUpdates(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::LossBasedBweUpdates::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_LossBasedBweUpdates_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_LossBasedBweUpdates_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_OutgoingRtcpPackets_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_OutgoingRtcpPackets_default_instance_; - new (ptr) ::webrtc::rtclog2::OutgoingRtcpPackets(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::OutgoingRtcpPackets::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_OutgoingRtcpPackets_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_OutgoingRtcpPackets_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_OutgoingRtpPackets_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_OutgoingRtpPackets_default_instance_; - new (ptr) ::webrtc::rtclog2::OutgoingRtpPackets(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::OutgoingRtpPackets::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_OutgoingRtpPackets_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_OutgoingRtpPackets_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_RemoteEstimates_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_RemoteEstimates_default_instance_; - new (ptr) ::webrtc::rtclog2::RemoteEstimates(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::RemoteEstimates::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RemoteEstimates_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_RemoteEstimates_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_RouteChange_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_RouteChange_default_instance_; - new (ptr) ::webrtc::rtclog2::RouteChange(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::RouteChange::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RouteChange_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_RouteChange_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_RtpHeaderExtensionConfig_default_instance_; - new (ptr) ::webrtc::rtclog2::RtpHeaderExtensionConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::RtpHeaderExtensionConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto}, {}}; - -static void InitDefaultsscc_info_VideoRecvStreamConfig_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_VideoRecvStreamConfig_default_instance_; - new (ptr) ::webrtc::rtclog2::VideoRecvStreamConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::VideoRecvStreamConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_VideoRecvStreamConfig_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsscc_info_VideoRecvStreamConfig_rtc_5fevent_5flog2_2eproto}, { - &scc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto.base,}}; - -static void InitDefaultsscc_info_VideoSendStreamConfig_rtc_5fevent_5flog2_2eproto() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::webrtc::rtclog2::_VideoSendStreamConfig_default_instance_; - new (ptr) ::webrtc::rtclog2::VideoSendStreamConfig(); - ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); - } - ::webrtc::rtclog2::VideoSendStreamConfig::InitAsDefaultInstance(); -} - -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_VideoSendStreamConfig_rtc_5fevent_5flog2_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsscc_info_VideoSendStreamConfig_rtc_5fevent_5flog2_2eproto}, { - &scc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto.base,}}; - -namespace webrtc { -namespace rtclog2 { -bool FrameDecodedEvents_Codec_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed FrameDecodedEvents_Codec_strings[7] = {}; - -static const char FrameDecodedEvents_Codec_names[] = - "CODEC_AV1" - "CODEC_GENERIC" - "CODEC_H264" - "CODEC_H265" - "CODEC_UNKNOWN" - "CODEC_VP8" - "CODEC_VP9"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry FrameDecodedEvents_Codec_entries[] = { - { {FrameDecodedEvents_Codec_names + 0, 9}, 4 }, - { {FrameDecodedEvents_Codec_names + 9, 13}, 1 }, - { {FrameDecodedEvents_Codec_names + 22, 10}, 5 }, - { {FrameDecodedEvents_Codec_names + 32, 10}, 6 }, - { {FrameDecodedEvents_Codec_names + 42, 13}, 0 }, - { {FrameDecodedEvents_Codec_names + 55, 9}, 2 }, - { {FrameDecodedEvents_Codec_names + 64, 9}, 3 }, -}; - -static const int FrameDecodedEvents_Codec_entries_by_number[] = { - 4, // 0 -> CODEC_UNKNOWN - 1, // 1 -> CODEC_GENERIC - 5, // 2 -> CODEC_VP8 - 6, // 3 -> CODEC_VP9 - 0, // 4 -> CODEC_AV1 - 2, // 5 -> CODEC_H264 - 3, // 6 -> CODEC_H265 -}; - -const std::string& FrameDecodedEvents_Codec_Name( - FrameDecodedEvents_Codec value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - FrameDecodedEvents_Codec_entries, - FrameDecodedEvents_Codec_entries_by_number, - 7, FrameDecodedEvents_Codec_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - FrameDecodedEvents_Codec_entries, - FrameDecodedEvents_Codec_entries_by_number, - 7, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - FrameDecodedEvents_Codec_strings[idx].get(); -} -bool FrameDecodedEvents_Codec_Parse( - const std::string& name, FrameDecodedEvents_Codec* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - FrameDecodedEvents_Codec_entries, 7, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::CODEC_UNKNOWN; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::CODEC_GENERIC; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::CODEC_VP8; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::CODEC_VP9; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::CODEC_AV1; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::CODEC_H264; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::CODEC_H265; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::Codec_MIN; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents::Codec_MAX; -constexpr int FrameDecodedEvents::Codec_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool DelayBasedBweUpdates_DetectorState_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DelayBasedBweUpdates_DetectorState_strings[4] = {}; - -static const char DelayBasedBweUpdates_DetectorState_names[] = - "BWE_NORMAL" - "BWE_OVERUSING" - "BWE_UNDERUSING" - "BWE_UNKNOWN_STATE"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry DelayBasedBweUpdates_DetectorState_entries[] = { - { {DelayBasedBweUpdates_DetectorState_names + 0, 10}, 1 }, - { {DelayBasedBweUpdates_DetectorState_names + 10, 13}, 3 }, - { {DelayBasedBweUpdates_DetectorState_names + 23, 14}, 2 }, - { {DelayBasedBweUpdates_DetectorState_names + 37, 17}, 0 }, -}; - -static const int DelayBasedBweUpdates_DetectorState_entries_by_number[] = { - 3, // 0 -> BWE_UNKNOWN_STATE - 0, // 1 -> BWE_NORMAL - 2, // 2 -> BWE_UNDERUSING - 1, // 3 -> BWE_OVERUSING -}; - -const std::string& DelayBasedBweUpdates_DetectorState_Name( - DelayBasedBweUpdates_DetectorState value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - DelayBasedBweUpdates_DetectorState_entries, - DelayBasedBweUpdates_DetectorState_entries_by_number, - 4, DelayBasedBweUpdates_DetectorState_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - DelayBasedBweUpdates_DetectorState_entries, - DelayBasedBweUpdates_DetectorState_entries_by_number, - 4, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - DelayBasedBweUpdates_DetectorState_strings[idx].get(); -} -bool DelayBasedBweUpdates_DetectorState_Parse( - const std::string& name, DelayBasedBweUpdates_DetectorState* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - DelayBasedBweUpdates_DetectorState_entries, 4, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates::BWE_UNKNOWN_STATE; -constexpr DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates::BWE_NORMAL; -constexpr DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates::BWE_UNDERUSING; -constexpr DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates::BWE_OVERUSING; -constexpr DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates::DetectorState_MIN; -constexpr DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates::DetectorState_MAX; -constexpr int DelayBasedBweUpdates::DetectorState_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool BweProbeResultFailure_FailureReason_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed BweProbeResultFailure_FailureReason_strings[4] = {}; - -static const char BweProbeResultFailure_FailureReason_names[] = - "INVALID_SEND_RECEIVE_INTERVAL" - "INVALID_SEND_RECEIVE_RATIO" - "TIMEOUT" - "UNKNOWN"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry BweProbeResultFailure_FailureReason_entries[] = { - { {BweProbeResultFailure_FailureReason_names + 0, 29}, 1 }, - { {BweProbeResultFailure_FailureReason_names + 29, 26}, 2 }, - { {BweProbeResultFailure_FailureReason_names + 55, 7}, 3 }, - { {BweProbeResultFailure_FailureReason_names + 62, 7}, 0 }, -}; - -static const int BweProbeResultFailure_FailureReason_entries_by_number[] = { - 3, // 0 -> UNKNOWN - 0, // 1 -> INVALID_SEND_RECEIVE_INTERVAL - 1, // 2 -> INVALID_SEND_RECEIVE_RATIO - 2, // 3 -> TIMEOUT -}; - -const std::string& BweProbeResultFailure_FailureReason_Name( - BweProbeResultFailure_FailureReason value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - BweProbeResultFailure_FailureReason_entries, - BweProbeResultFailure_FailureReason_entries_by_number, - 4, BweProbeResultFailure_FailureReason_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - BweProbeResultFailure_FailureReason_entries, - BweProbeResultFailure_FailureReason_entries_by_number, - 4, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - BweProbeResultFailure_FailureReason_strings[idx].get(); -} -bool BweProbeResultFailure_FailureReason_Parse( - const std::string& name, BweProbeResultFailure_FailureReason* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - BweProbeResultFailure_FailureReason_entries, 4, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr BweProbeResultFailure_FailureReason BweProbeResultFailure::UNKNOWN; -constexpr BweProbeResultFailure_FailureReason BweProbeResultFailure::INVALID_SEND_RECEIVE_INTERVAL; -constexpr BweProbeResultFailure_FailureReason BweProbeResultFailure::INVALID_SEND_RECEIVE_RATIO; -constexpr BweProbeResultFailure_FailureReason BweProbeResultFailure::TIMEOUT; -constexpr BweProbeResultFailure_FailureReason BweProbeResultFailure::FailureReason_MIN; -constexpr BweProbeResultFailure_FailureReason BweProbeResultFailure::FailureReason_MAX; -constexpr int BweProbeResultFailure::FailureReason_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_IceCandidatePairConfigType_strings[5] = {}; - -static const char IceCandidatePairConfig_IceCandidatePairConfigType_names[] = - "ADDED" - "DESTROYED" - "SELECTED" - "UNKNOWN_CONFIG_TYPE" - "UPDATED"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_IceCandidatePairConfigType_entries[] = { - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 0, 5}, 1 }, - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 5, 9}, 3 }, - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 14, 8}, 4 }, - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 22, 19}, 0 }, - { {IceCandidatePairConfig_IceCandidatePairConfigType_names + 41, 7}, 2 }, -}; - -static const int IceCandidatePairConfig_IceCandidatePairConfigType_entries_by_number[] = { - 3, // 0 -> UNKNOWN_CONFIG_TYPE - 0, // 1 -> ADDED - 4, // 2 -> UPDATED - 1, // 3 -> DESTROYED - 2, // 4 -> SELECTED -}; - -const std::string& IceCandidatePairConfig_IceCandidatePairConfigType_Name( - IceCandidatePairConfig_IceCandidatePairConfigType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_IceCandidatePairConfigType_entries, - IceCandidatePairConfig_IceCandidatePairConfigType_entries_by_number, - 5, IceCandidatePairConfig_IceCandidatePairConfigType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_IceCandidatePairConfigType_entries, - IceCandidatePairConfig_IceCandidatePairConfigType_entries_by_number, - 5, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_IceCandidatePairConfigType_strings[idx].get(); -} -bool IceCandidatePairConfig_IceCandidatePairConfigType_Parse( - const std::string& name, IceCandidatePairConfig_IceCandidatePairConfigType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_IceCandidatePairConfigType_entries, 5, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::UNKNOWN_CONFIG_TYPE; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::ADDED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::UPDATED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::DESTROYED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::SELECTED; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::IceCandidatePairConfigType_MIN; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::IceCandidatePairConfigType_MAX; -constexpr int IceCandidatePairConfig::IceCandidatePairConfigType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_IceCandidateType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_IceCandidateType_strings[5] = {}; - -static const char IceCandidatePairConfig_IceCandidateType_names[] = - "LOCAL" - "PRFLX" - "RELAY" - "STUN" - "UNKNOWN_CANDIDATE_TYPE"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_IceCandidateType_entries[] = { - { {IceCandidatePairConfig_IceCandidateType_names + 0, 5}, 1 }, - { {IceCandidatePairConfig_IceCandidateType_names + 5, 5}, 3 }, - { {IceCandidatePairConfig_IceCandidateType_names + 10, 5}, 4 }, - { {IceCandidatePairConfig_IceCandidateType_names + 15, 4}, 2 }, - { {IceCandidatePairConfig_IceCandidateType_names + 19, 22}, 0 }, -}; - -static const int IceCandidatePairConfig_IceCandidateType_entries_by_number[] = { - 4, // 0 -> UNKNOWN_CANDIDATE_TYPE - 0, // 1 -> LOCAL - 3, // 2 -> STUN - 1, // 3 -> PRFLX - 2, // 4 -> RELAY -}; - -const std::string& IceCandidatePairConfig_IceCandidateType_Name( - IceCandidatePairConfig_IceCandidateType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_IceCandidateType_entries, - IceCandidatePairConfig_IceCandidateType_entries_by_number, - 5, IceCandidatePairConfig_IceCandidateType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_IceCandidateType_entries, - IceCandidatePairConfig_IceCandidateType_entries_by_number, - 5, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_IceCandidateType_strings[idx].get(); -} -bool IceCandidatePairConfig_IceCandidateType_Parse( - const std::string& name, IceCandidatePairConfig_IceCandidateType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_IceCandidateType_entries, 5, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::LOCAL; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::STUN; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::PRFLX; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::RELAY; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::IceCandidateType_MIN; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::IceCandidateType_MAX; -constexpr int IceCandidatePairConfig::IceCandidateType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_Protocol_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_Protocol_strings[5] = {}; - -static const char IceCandidatePairConfig_Protocol_names[] = - "SSLTCP" - "TCP" - "TLS" - "UDP" - "UNKNOWN_PROTOCOL"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_Protocol_entries[] = { - { {IceCandidatePairConfig_Protocol_names + 0, 6}, 3 }, - { {IceCandidatePairConfig_Protocol_names + 6, 3}, 2 }, - { {IceCandidatePairConfig_Protocol_names + 9, 3}, 4 }, - { {IceCandidatePairConfig_Protocol_names + 12, 3}, 1 }, - { {IceCandidatePairConfig_Protocol_names + 15, 16}, 0 }, -}; - -static const int IceCandidatePairConfig_Protocol_entries_by_number[] = { - 4, // 0 -> UNKNOWN_PROTOCOL - 3, // 1 -> UDP - 1, // 2 -> TCP - 0, // 3 -> SSLTCP - 2, // 4 -> TLS -}; - -const std::string& IceCandidatePairConfig_Protocol_Name( - IceCandidatePairConfig_Protocol value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_Protocol_entries, - IceCandidatePairConfig_Protocol_entries_by_number, - 5, IceCandidatePairConfig_Protocol_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_Protocol_entries, - IceCandidatePairConfig_Protocol_entries_by_number, - 5, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_Protocol_strings[idx].get(); -} -bool IceCandidatePairConfig_Protocol_Parse( - const std::string& name, IceCandidatePairConfig_Protocol* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_Protocol_entries, 5, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::UNKNOWN_PROTOCOL; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::UDP; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::TCP; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::SSLTCP; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::TLS; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::Protocol_MIN; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig::Protocol_MAX; -constexpr int IceCandidatePairConfig::Protocol_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_AddressFamily_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_AddressFamily_strings[3] = {}; - -static const char IceCandidatePairConfig_AddressFamily_names[] = - "IPV4" - "IPV6" - "UNKNOWN_ADDRESS_FAMILY"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_AddressFamily_entries[] = { - { {IceCandidatePairConfig_AddressFamily_names + 0, 4}, 1 }, - { {IceCandidatePairConfig_AddressFamily_names + 4, 4}, 2 }, - { {IceCandidatePairConfig_AddressFamily_names + 8, 22}, 0 }, -}; - -static const int IceCandidatePairConfig_AddressFamily_entries_by_number[] = { - 2, // 0 -> UNKNOWN_ADDRESS_FAMILY - 0, // 1 -> IPV4 - 1, // 2 -> IPV6 -}; - -const std::string& IceCandidatePairConfig_AddressFamily_Name( - IceCandidatePairConfig_AddressFamily value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_AddressFamily_entries, - IceCandidatePairConfig_AddressFamily_entries_by_number, - 3, IceCandidatePairConfig_AddressFamily_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_AddressFamily_entries, - IceCandidatePairConfig_AddressFamily_entries_by_number, - 3, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_AddressFamily_strings[idx].get(); -} -bool IceCandidatePairConfig_AddressFamily_Parse( - const std::string& name, IceCandidatePairConfig_AddressFamily* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_AddressFamily_entries, 3, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::IPV4; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::IPV6; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::AddressFamily_MIN; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::AddressFamily_MAX; -constexpr int IceCandidatePairConfig::AddressFamily_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairConfig_NetworkType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairConfig_NetworkType_strings[6] = {}; - -static const char IceCandidatePairConfig_NetworkType_names[] = - "CELLULAR" - "ETHERNET" - "LOOPBACK" - "UNKNOWN_NETWORK_TYPE" - "VPN" - "WIFI"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairConfig_NetworkType_entries[] = { - { {IceCandidatePairConfig_NetworkType_names + 0, 8}, 3 }, - { {IceCandidatePairConfig_NetworkType_names + 8, 8}, 1 }, - { {IceCandidatePairConfig_NetworkType_names + 16, 8}, 5 }, - { {IceCandidatePairConfig_NetworkType_names + 24, 20}, 0 }, - { {IceCandidatePairConfig_NetworkType_names + 44, 3}, 4 }, - { {IceCandidatePairConfig_NetworkType_names + 47, 4}, 2 }, -}; - -static const int IceCandidatePairConfig_NetworkType_entries_by_number[] = { - 3, // 0 -> UNKNOWN_NETWORK_TYPE - 1, // 1 -> ETHERNET - 5, // 2 -> WIFI - 0, // 3 -> CELLULAR - 4, // 4 -> VPN - 2, // 5 -> LOOPBACK -}; - -const std::string& IceCandidatePairConfig_NetworkType_Name( - IceCandidatePairConfig_NetworkType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairConfig_NetworkType_entries, - IceCandidatePairConfig_NetworkType_entries_by_number, - 6, IceCandidatePairConfig_NetworkType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairConfig_NetworkType_entries, - IceCandidatePairConfig_NetworkType_entries_by_number, - 6, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairConfig_NetworkType_strings[idx].get(); -} -bool IceCandidatePairConfig_NetworkType_Parse( - const std::string& name, IceCandidatePairConfig_NetworkType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairConfig_NetworkType_entries, 6, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::ETHERNET; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::WIFI; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::CELLULAR; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::VPN; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::LOOPBACK; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::NetworkType_MIN; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig::NetworkType_MAX; -constexpr int IceCandidatePairConfig::NetworkType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool IceCandidatePairEvent_IceCandidatePairEventType_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed IceCandidatePairEvent_IceCandidatePairEventType_strings[5] = {}; - -static const char IceCandidatePairEvent_IceCandidatePairEventType_names[] = - "CHECK_RECEIVED" - "CHECK_RESPONSE_RECEIVED" - "CHECK_RESPONSE_SENT" - "CHECK_SENT" - "UNKNOWN_CHECK_TYPE"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry IceCandidatePairEvent_IceCandidatePairEventType_entries[] = { - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 0, 14}, 2 }, - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 14, 23}, 4 }, - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 37, 19}, 3 }, - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 56, 10}, 1 }, - { {IceCandidatePairEvent_IceCandidatePairEventType_names + 66, 18}, 0 }, -}; - -static const int IceCandidatePairEvent_IceCandidatePairEventType_entries_by_number[] = { - 4, // 0 -> UNKNOWN_CHECK_TYPE - 3, // 1 -> CHECK_SENT - 0, // 2 -> CHECK_RECEIVED - 2, // 3 -> CHECK_RESPONSE_SENT - 1, // 4 -> CHECK_RESPONSE_RECEIVED -}; - -const std::string& IceCandidatePairEvent_IceCandidatePairEventType_Name( - IceCandidatePairEvent_IceCandidatePairEventType value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - IceCandidatePairEvent_IceCandidatePairEventType_entries, - IceCandidatePairEvent_IceCandidatePairEventType_entries_by_number, - 5, IceCandidatePairEvent_IceCandidatePairEventType_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - IceCandidatePairEvent_IceCandidatePairEventType_entries, - IceCandidatePairEvent_IceCandidatePairEventType_entries_by_number, - 5, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - IceCandidatePairEvent_IceCandidatePairEventType_strings[idx].get(); -} -bool IceCandidatePairEvent_IceCandidatePairEventType_Parse( - const std::string& name, IceCandidatePairEvent_IceCandidatePairEventType* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - IceCandidatePairEvent_IceCandidatePairEventType_entries, 5, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::UNKNOWN_CHECK_TYPE; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::CHECK_SENT; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::CHECK_RECEIVED; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::CHECK_RESPONSE_SENT; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::IceCandidatePairEventType_MIN; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::IceCandidatePairEventType_MAX; -constexpr int IceCandidatePairEvent::IceCandidatePairEventType_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -bool DtlsTransportStateEvent_DtlsTransportState_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed DtlsTransportStateEvent_DtlsTransportState_strings[6] = {}; - -static const char DtlsTransportStateEvent_DtlsTransportState_names[] = - "DTLS_TRANSPORT_CLOSED" - "DTLS_TRANSPORT_CONNECTED" - "DTLS_TRANSPORT_CONNECTING" - "DTLS_TRANSPORT_FAILED" - "DTLS_TRANSPORT_NEW" - "UNKNOWN_DTLS_TRANSPORT_STATE"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry DtlsTransportStateEvent_DtlsTransportState_entries[] = { - { {DtlsTransportStateEvent_DtlsTransportState_names + 0, 21}, 4 }, - { {DtlsTransportStateEvent_DtlsTransportState_names + 21, 24}, 3 }, - { {DtlsTransportStateEvent_DtlsTransportState_names + 45, 25}, 2 }, - { {DtlsTransportStateEvent_DtlsTransportState_names + 70, 21}, 5 }, - { {DtlsTransportStateEvent_DtlsTransportState_names + 91, 18}, 1 }, - { {DtlsTransportStateEvent_DtlsTransportState_names + 109, 28}, 0 }, -}; - -static const int DtlsTransportStateEvent_DtlsTransportState_entries_by_number[] = { - 5, // 0 -> UNKNOWN_DTLS_TRANSPORT_STATE - 4, // 1 -> DTLS_TRANSPORT_NEW - 2, // 2 -> DTLS_TRANSPORT_CONNECTING - 1, // 3 -> DTLS_TRANSPORT_CONNECTED - 0, // 4 -> DTLS_TRANSPORT_CLOSED - 3, // 5 -> DTLS_TRANSPORT_FAILED -}; - -const std::string& DtlsTransportStateEvent_DtlsTransportState_Name( - DtlsTransportStateEvent_DtlsTransportState value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - DtlsTransportStateEvent_DtlsTransportState_entries, - DtlsTransportStateEvent_DtlsTransportState_entries_by_number, - 6, DtlsTransportStateEvent_DtlsTransportState_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - DtlsTransportStateEvent_DtlsTransportState_entries, - DtlsTransportStateEvent_DtlsTransportState_entries_by_number, - 6, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - DtlsTransportStateEvent_DtlsTransportState_strings[idx].get(); -} -bool DtlsTransportStateEvent_DtlsTransportState_Parse( - const std::string& name, DtlsTransportStateEvent_DtlsTransportState* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - DtlsTransportStateEvent_DtlsTransportState_entries, 6, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} -#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::UNKNOWN_DTLS_TRANSPORT_STATE; -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::DTLS_TRANSPORT_NEW; -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::DTLS_TRANSPORT_CONNECTING; -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::DTLS_TRANSPORT_CONNECTED; -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::DTLS_TRANSPORT_CLOSED; -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::DTLS_TRANSPORT_FAILED; -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::DtlsTransportState_MIN; -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::DtlsTransportState_MAX; -constexpr int DtlsTransportStateEvent::DtlsTransportState_ARRAYSIZE; -#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) - -// =================================================================== - -void EventStream::InitAsDefaultInstance() { -} -class EventStream::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); -}; - -EventStream::EventStream() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.EventStream) -} -EventStream::EventStream(const EventStream& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), - stream_(from.stream_), - incoming_rtp_packets_(from.incoming_rtp_packets_), - outgoing_rtp_packets_(from.outgoing_rtp_packets_), - incoming_rtcp_packets_(from.incoming_rtcp_packets_), - outgoing_rtcp_packets_(from.outgoing_rtcp_packets_), - audio_playout_events_(from.audio_playout_events_), - frame_decoded_events_(from.frame_decoded_events_), - begin_log_events_(from.begin_log_events_), - end_log_events_(from.end_log_events_), - loss_based_bwe_updates_(from.loss_based_bwe_updates_), - delay_based_bwe_updates_(from.delay_based_bwe_updates_), - audio_network_adaptations_(from.audio_network_adaptations_), - probe_clusters_(from.probe_clusters_), - probe_success_(from.probe_success_), - probe_failure_(from.probe_failure_), - alr_states_(from.alr_states_), - ice_candidate_configs_(from.ice_candidate_configs_), - ice_candidate_events_(from.ice_candidate_events_), - dtls_transport_state_events_(from.dtls_transport_state_events_), - dtls_writable_states_(from.dtls_writable_states_), - generic_packets_sent_(from.generic_packets_sent_), - generic_packets_received_(from.generic_packets_received_), - generic_acks_received_(from.generic_acks_received_), - route_changes_(from.route_changes_), - remote_estimates_(from.remote_estimates_), - audio_recv_stream_configs_(from.audio_recv_stream_configs_), - audio_send_stream_configs_(from.audio_send_stream_configs_), - video_recv_stream_configs_(from.video_recv_stream_configs_), - video_send_stream_configs_(from.video_send_stream_configs_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.EventStream) -} - -void EventStream::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_EventStream_rtc_5fevent_5flog2_2eproto.base); -} - -EventStream::~EventStream() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.EventStream) - SharedDtor(); -} - -void EventStream::SharedDtor() { -} - -void EventStream::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const EventStream& EventStream::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_EventStream_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void EventStream::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.EventStream) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - stream_.Clear(); - incoming_rtp_packets_.Clear(); - outgoing_rtp_packets_.Clear(); - incoming_rtcp_packets_.Clear(); - outgoing_rtcp_packets_.Clear(); - audio_playout_events_.Clear(); - frame_decoded_events_.Clear(); - begin_log_events_.Clear(); - end_log_events_.Clear(); - loss_based_bwe_updates_.Clear(); - delay_based_bwe_updates_.Clear(); - audio_network_adaptations_.Clear(); - probe_clusters_.Clear(); - probe_success_.Clear(); - probe_failure_.Clear(); - alr_states_.Clear(); - ice_candidate_configs_.Clear(); - ice_candidate_events_.Clear(); - dtls_transport_state_events_.Clear(); - dtls_writable_states_.Clear(); - generic_packets_sent_.Clear(); - generic_packets_received_.Clear(); - generic_acks_received_.Clear(); - route_changes_.Clear(); - remote_estimates_.Clear(); - audio_recv_stream_configs_.Clear(); - audio_send_stream_configs_.Clear(); - video_recv_stream_configs_.Clear(); - video_send_stream_configs_.Clear(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* EventStream::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // repeated .webrtc.rtclog2.Event stream = 1 [deprecated = true]; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_stream(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 10); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.IncomingRtpPackets incoming_rtp_packets = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_incoming_rtp_packets(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 18); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.OutgoingRtpPackets outgoing_rtp_packets = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_outgoing_rtp_packets(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 26); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.IncomingRtcpPackets incoming_rtcp_packets = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_incoming_rtcp_packets(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 34); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.OutgoingRtcpPackets outgoing_rtcp_packets = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_outgoing_rtcp_packets(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 42); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.AudioPlayoutEvents audio_playout_events = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_audio_playout_events(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 50); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.FrameDecodedEvents frame_decoded_events = 7; - case 7: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr -= 1; - do { - ptr += 1; - ptr = ctx->ParseMessage(add_frame_decoded_events(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint8>(ptr) == 58); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.BeginLogEvent begin_log_events = 16; - case 16: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 130)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_begin_log_events(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 386); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.EndLogEvent end_log_events = 17; - case 17: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 138)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_end_log_events(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 394); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.LossBasedBweUpdates loss_based_bwe_updates = 18; - case 18: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 146)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_loss_based_bwe_updates(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 402); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.DelayBasedBweUpdates delay_based_bwe_updates = 19; - case 19: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 154)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_delay_based_bwe_updates(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 410); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.AudioNetworkAdaptations audio_network_adaptations = 20; - case 20: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 162)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_audio_network_adaptations(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 418); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.BweProbeCluster probe_clusters = 21; - case 21: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 170)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_probe_clusters(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 426); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.BweProbeResultSuccess probe_success = 22; - case 22: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 178)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_probe_success(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 434); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.BweProbeResultFailure probe_failure = 23; - case 23: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 186)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_probe_failure(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 442); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.AlrState alr_states = 24; - case 24: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 194)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_alr_states(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 450); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.IceCandidatePairConfig ice_candidate_configs = 25; - case 25: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 202)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_ice_candidate_configs(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 458); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.IceCandidatePairEvent ice_candidate_events = 26; - case 26: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 210)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_ice_candidate_events(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 466); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.DtlsTransportStateEvent dtls_transport_state_events = 27; - case 27: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 218)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_dtls_transport_state_events(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 474); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.DtlsWritableState dtls_writable_states = 28; - case 28: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 226)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_dtls_writable_states(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 482); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.GenericPacketSent generic_packets_sent = 29; - case 29: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 234)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_generic_packets_sent(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 490); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.GenericPacketReceived generic_packets_received = 30; - case 30: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 242)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_generic_packets_received(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 498); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.GenericAckReceived generic_acks_received = 31; - case 31: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 250)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_generic_acks_received(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 506); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.RouteChange route_changes = 32; - case 32: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 2)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_route_changes(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 642); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.RemoteEstimates remote_estimates = 33; - case 33: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_remote_estimates(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 650); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.AudioRecvStreamConfig audio_recv_stream_configs = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_audio_recv_stream_configs(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 1706); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.AudioSendStreamConfig audio_send_stream_configs = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_audio_send_stream_configs(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 1714); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.VideoRecvStreamConfig video_recv_stream_configs = 103; - case 103: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_video_recv_stream_configs(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 1722); - } else goto handle_unusual; - continue; - // repeated .webrtc.rtclog2.VideoSendStreamConfig video_send_stream_configs = 104; - case 104: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { - ptr -= 2; - do { - ptr += 2; - ptr = ctx->ParseMessage(add_video_send_stream_configs(), ptr); - CHK_(ptr); - if (!ctx->DataAvailable(ptr)) break; - } while (::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint16>(ptr) == 1730); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool EventStream::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.EventStream) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .webrtc.rtclog2.Event stream = 1 [deprecated = true]; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (10 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_stream())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.IncomingRtpPackets incoming_rtp_packets = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (18 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_incoming_rtp_packets())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.OutgoingRtpPackets outgoing_rtp_packets = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (26 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_outgoing_rtp_packets())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.IncomingRtcpPackets incoming_rtcp_packets = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (34 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_incoming_rtcp_packets())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.OutgoingRtcpPackets outgoing_rtcp_packets = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (42 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_outgoing_rtcp_packets())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.AudioPlayoutEvents audio_playout_events = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (50 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_audio_playout_events())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.FrameDecodedEvents frame_decoded_events = 7; - case 7: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (58 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_frame_decoded_events())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.BeginLogEvent begin_log_events = 16; - case 16: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (130 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_begin_log_events())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.EndLogEvent end_log_events = 17; - case 17: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (138 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_end_log_events())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.LossBasedBweUpdates loss_based_bwe_updates = 18; - case 18: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (146 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_loss_based_bwe_updates())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.DelayBasedBweUpdates delay_based_bwe_updates = 19; - case 19: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (154 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_delay_based_bwe_updates())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.AudioNetworkAdaptations audio_network_adaptations = 20; - case 20: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (162 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_audio_network_adaptations())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.BweProbeCluster probe_clusters = 21; - case 21: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (170 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_probe_clusters())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.BweProbeResultSuccess probe_success = 22; - case 22: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (178 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_probe_success())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.BweProbeResultFailure probe_failure = 23; - case 23: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (186 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_probe_failure())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.AlrState alr_states = 24; - case 24: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (194 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_alr_states())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.IceCandidatePairConfig ice_candidate_configs = 25; - case 25: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (202 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_ice_candidate_configs())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.IceCandidatePairEvent ice_candidate_events = 26; - case 26: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (210 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_ice_candidate_events())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.DtlsTransportStateEvent dtls_transport_state_events = 27; - case 27: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (218 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_dtls_transport_state_events())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.DtlsWritableState dtls_writable_states = 28; - case 28: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (226 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_dtls_writable_states())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.GenericPacketSent generic_packets_sent = 29; - case 29: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (234 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_generic_packets_sent())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.GenericPacketReceived generic_packets_received = 30; - case 30: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (242 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_generic_packets_received())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.GenericAckReceived generic_acks_received = 31; - case 31: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (250 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_generic_acks_received())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.RouteChange route_changes = 32; - case 32: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (258 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_route_changes())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.RemoteEstimates remote_estimates = 33; - case 33: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (266 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_remote_estimates())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.AudioRecvStreamConfig audio_recv_stream_configs = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_audio_recv_stream_configs())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.AudioSendStreamConfig audio_send_stream_configs = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_audio_send_stream_configs())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.VideoRecvStreamConfig video_recv_stream_configs = 103; - case 103: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (826 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_video_recv_stream_configs())); - } else { - goto handle_unusual; - } - break; - } - - // repeated .webrtc.rtclog2.VideoSendStreamConfig video_send_stream_configs = 104; - case 104: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (834 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, add_video_send_stream_configs())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.EventStream) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.EventStream) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void EventStream::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.EventStream) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // repeated .webrtc.rtclog2.Event stream = 1 [deprecated = true]; - for (unsigned int i = 0, - n = static_cast(this->stream_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 1, - this->stream(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.IncomingRtpPackets incoming_rtp_packets = 2; - for (unsigned int i = 0, - n = static_cast(this->incoming_rtp_packets_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 2, - this->incoming_rtp_packets(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.OutgoingRtpPackets outgoing_rtp_packets = 3; - for (unsigned int i = 0, - n = static_cast(this->outgoing_rtp_packets_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 3, - this->outgoing_rtp_packets(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.IncomingRtcpPackets incoming_rtcp_packets = 4; - for (unsigned int i = 0, - n = static_cast(this->incoming_rtcp_packets_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 4, - this->incoming_rtcp_packets(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.OutgoingRtcpPackets outgoing_rtcp_packets = 5; - for (unsigned int i = 0, - n = static_cast(this->outgoing_rtcp_packets_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 5, - this->outgoing_rtcp_packets(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.AudioPlayoutEvents audio_playout_events = 6; - for (unsigned int i = 0, - n = static_cast(this->audio_playout_events_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 6, - this->audio_playout_events(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.FrameDecodedEvents frame_decoded_events = 7; - for (unsigned int i = 0, - n = static_cast(this->frame_decoded_events_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 7, - this->frame_decoded_events(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.BeginLogEvent begin_log_events = 16; - for (unsigned int i = 0, - n = static_cast(this->begin_log_events_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 16, - this->begin_log_events(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.EndLogEvent end_log_events = 17; - for (unsigned int i = 0, - n = static_cast(this->end_log_events_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 17, - this->end_log_events(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.LossBasedBweUpdates loss_based_bwe_updates = 18; - for (unsigned int i = 0, - n = static_cast(this->loss_based_bwe_updates_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 18, - this->loss_based_bwe_updates(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.DelayBasedBweUpdates delay_based_bwe_updates = 19; - for (unsigned int i = 0, - n = static_cast(this->delay_based_bwe_updates_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 19, - this->delay_based_bwe_updates(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.AudioNetworkAdaptations audio_network_adaptations = 20; - for (unsigned int i = 0, - n = static_cast(this->audio_network_adaptations_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 20, - this->audio_network_adaptations(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.BweProbeCluster probe_clusters = 21; - for (unsigned int i = 0, - n = static_cast(this->probe_clusters_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 21, - this->probe_clusters(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.BweProbeResultSuccess probe_success = 22; - for (unsigned int i = 0, - n = static_cast(this->probe_success_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 22, - this->probe_success(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.BweProbeResultFailure probe_failure = 23; - for (unsigned int i = 0, - n = static_cast(this->probe_failure_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 23, - this->probe_failure(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.AlrState alr_states = 24; - for (unsigned int i = 0, - n = static_cast(this->alr_states_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 24, - this->alr_states(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.IceCandidatePairConfig ice_candidate_configs = 25; - for (unsigned int i = 0, - n = static_cast(this->ice_candidate_configs_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 25, - this->ice_candidate_configs(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.IceCandidatePairEvent ice_candidate_events = 26; - for (unsigned int i = 0, - n = static_cast(this->ice_candidate_events_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 26, - this->ice_candidate_events(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.DtlsTransportStateEvent dtls_transport_state_events = 27; - for (unsigned int i = 0, - n = static_cast(this->dtls_transport_state_events_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 27, - this->dtls_transport_state_events(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.DtlsWritableState dtls_writable_states = 28; - for (unsigned int i = 0, - n = static_cast(this->dtls_writable_states_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 28, - this->dtls_writable_states(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.GenericPacketSent generic_packets_sent = 29; - for (unsigned int i = 0, - n = static_cast(this->generic_packets_sent_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 29, - this->generic_packets_sent(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.GenericPacketReceived generic_packets_received = 30; - for (unsigned int i = 0, - n = static_cast(this->generic_packets_received_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 30, - this->generic_packets_received(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.GenericAckReceived generic_acks_received = 31; - for (unsigned int i = 0, - n = static_cast(this->generic_acks_received_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 31, - this->generic_acks_received(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.RouteChange route_changes = 32; - for (unsigned int i = 0, - n = static_cast(this->route_changes_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 32, - this->route_changes(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.RemoteEstimates remote_estimates = 33; - for (unsigned int i = 0, - n = static_cast(this->remote_estimates_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 33, - this->remote_estimates(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.AudioRecvStreamConfig audio_recv_stream_configs = 101; - for (unsigned int i = 0, - n = static_cast(this->audio_recv_stream_configs_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 101, - this->audio_recv_stream_configs(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.AudioSendStreamConfig audio_send_stream_configs = 102; - for (unsigned int i = 0, - n = static_cast(this->audio_send_stream_configs_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 102, - this->audio_send_stream_configs(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.VideoRecvStreamConfig video_recv_stream_configs = 103; - for (unsigned int i = 0, - n = static_cast(this->video_recv_stream_configs_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 103, - this->video_recv_stream_configs(static_cast(i)), - output); - } - - // repeated .webrtc.rtclog2.VideoSendStreamConfig video_send_stream_configs = 104; - for (unsigned int i = 0, - n = static_cast(this->video_send_stream_configs_size()); i < n; i++) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 104, - this->video_send_stream_configs(static_cast(i)), - output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.EventStream) -} - -size_t EventStream::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.EventStream) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // repeated .webrtc.rtclog2.Event stream = 1 [deprecated = true]; - { - unsigned int count = static_cast(this->stream_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->stream(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.IncomingRtpPackets incoming_rtp_packets = 2; - { - unsigned int count = static_cast(this->incoming_rtp_packets_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->incoming_rtp_packets(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.OutgoingRtpPackets outgoing_rtp_packets = 3; - { - unsigned int count = static_cast(this->outgoing_rtp_packets_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->outgoing_rtp_packets(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.IncomingRtcpPackets incoming_rtcp_packets = 4; - { - unsigned int count = static_cast(this->incoming_rtcp_packets_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->incoming_rtcp_packets(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.OutgoingRtcpPackets outgoing_rtcp_packets = 5; - { - unsigned int count = static_cast(this->outgoing_rtcp_packets_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->outgoing_rtcp_packets(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.AudioPlayoutEvents audio_playout_events = 6; - { - unsigned int count = static_cast(this->audio_playout_events_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->audio_playout_events(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.FrameDecodedEvents frame_decoded_events = 7; - { - unsigned int count = static_cast(this->frame_decoded_events_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->frame_decoded_events(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.BeginLogEvent begin_log_events = 16; - { - unsigned int count = static_cast(this->begin_log_events_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->begin_log_events(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.EndLogEvent end_log_events = 17; - { - unsigned int count = static_cast(this->end_log_events_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->end_log_events(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.LossBasedBweUpdates loss_based_bwe_updates = 18; - { - unsigned int count = static_cast(this->loss_based_bwe_updates_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->loss_based_bwe_updates(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.DelayBasedBweUpdates delay_based_bwe_updates = 19; - { - unsigned int count = static_cast(this->delay_based_bwe_updates_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->delay_based_bwe_updates(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.AudioNetworkAdaptations audio_network_adaptations = 20; - { - unsigned int count = static_cast(this->audio_network_adaptations_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->audio_network_adaptations(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.BweProbeCluster probe_clusters = 21; - { - unsigned int count = static_cast(this->probe_clusters_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->probe_clusters(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.BweProbeResultSuccess probe_success = 22; - { - unsigned int count = static_cast(this->probe_success_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->probe_success(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.BweProbeResultFailure probe_failure = 23; - { - unsigned int count = static_cast(this->probe_failure_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->probe_failure(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.AlrState alr_states = 24; - { - unsigned int count = static_cast(this->alr_states_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->alr_states(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.IceCandidatePairConfig ice_candidate_configs = 25; - { - unsigned int count = static_cast(this->ice_candidate_configs_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->ice_candidate_configs(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.IceCandidatePairEvent ice_candidate_events = 26; - { - unsigned int count = static_cast(this->ice_candidate_events_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->ice_candidate_events(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.DtlsTransportStateEvent dtls_transport_state_events = 27; - { - unsigned int count = static_cast(this->dtls_transport_state_events_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->dtls_transport_state_events(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.DtlsWritableState dtls_writable_states = 28; - { - unsigned int count = static_cast(this->dtls_writable_states_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->dtls_writable_states(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.GenericPacketSent generic_packets_sent = 29; - { - unsigned int count = static_cast(this->generic_packets_sent_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->generic_packets_sent(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.GenericPacketReceived generic_packets_received = 30; - { - unsigned int count = static_cast(this->generic_packets_received_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->generic_packets_received(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.GenericAckReceived generic_acks_received = 31; - { - unsigned int count = static_cast(this->generic_acks_received_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->generic_acks_received(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.RouteChange route_changes = 32; - { - unsigned int count = static_cast(this->route_changes_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->route_changes(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.RemoteEstimates remote_estimates = 33; - { - unsigned int count = static_cast(this->remote_estimates_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->remote_estimates(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.AudioRecvStreamConfig audio_recv_stream_configs = 101; - { - unsigned int count = static_cast(this->audio_recv_stream_configs_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->audio_recv_stream_configs(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.AudioSendStreamConfig audio_send_stream_configs = 102; - { - unsigned int count = static_cast(this->audio_send_stream_configs_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->audio_send_stream_configs(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.VideoRecvStreamConfig video_recv_stream_configs = 103; - { - unsigned int count = static_cast(this->video_recv_stream_configs_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->video_recv_stream_configs(static_cast(i))); - } - } - - // repeated .webrtc.rtclog2.VideoSendStreamConfig video_send_stream_configs = 104; - { - unsigned int count = static_cast(this->video_send_stream_configs_size()); - total_size += 2UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - this->video_send_stream_configs(static_cast(i))); - } - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void EventStream::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void EventStream::MergeFrom(const EventStream& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.EventStream) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - stream_.MergeFrom(from.stream_); - incoming_rtp_packets_.MergeFrom(from.incoming_rtp_packets_); - outgoing_rtp_packets_.MergeFrom(from.outgoing_rtp_packets_); - incoming_rtcp_packets_.MergeFrom(from.incoming_rtcp_packets_); - outgoing_rtcp_packets_.MergeFrom(from.outgoing_rtcp_packets_); - audio_playout_events_.MergeFrom(from.audio_playout_events_); - frame_decoded_events_.MergeFrom(from.frame_decoded_events_); - begin_log_events_.MergeFrom(from.begin_log_events_); - end_log_events_.MergeFrom(from.end_log_events_); - loss_based_bwe_updates_.MergeFrom(from.loss_based_bwe_updates_); - delay_based_bwe_updates_.MergeFrom(from.delay_based_bwe_updates_); - audio_network_adaptations_.MergeFrom(from.audio_network_adaptations_); - probe_clusters_.MergeFrom(from.probe_clusters_); - probe_success_.MergeFrom(from.probe_success_); - probe_failure_.MergeFrom(from.probe_failure_); - alr_states_.MergeFrom(from.alr_states_); - ice_candidate_configs_.MergeFrom(from.ice_candidate_configs_); - ice_candidate_events_.MergeFrom(from.ice_candidate_events_); - dtls_transport_state_events_.MergeFrom(from.dtls_transport_state_events_); - dtls_writable_states_.MergeFrom(from.dtls_writable_states_); - generic_packets_sent_.MergeFrom(from.generic_packets_sent_); - generic_packets_received_.MergeFrom(from.generic_packets_received_); - generic_acks_received_.MergeFrom(from.generic_acks_received_); - route_changes_.MergeFrom(from.route_changes_); - remote_estimates_.MergeFrom(from.remote_estimates_); - audio_recv_stream_configs_.MergeFrom(from.audio_recv_stream_configs_); - audio_send_stream_configs_.MergeFrom(from.audio_send_stream_configs_); - video_recv_stream_configs_.MergeFrom(from.video_recv_stream_configs_); - video_send_stream_configs_.MergeFrom(from.video_send_stream_configs_); -} - -void EventStream::CopyFrom(const EventStream& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.EventStream) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EventStream::IsInitialized() const { - return true; -} - -void EventStream::InternalSwap(EventStream* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - CastToBase(&stream_)->InternalSwap(CastToBase(&other->stream_)); - CastToBase(&incoming_rtp_packets_)->InternalSwap(CastToBase(&other->incoming_rtp_packets_)); - CastToBase(&outgoing_rtp_packets_)->InternalSwap(CastToBase(&other->outgoing_rtp_packets_)); - CastToBase(&incoming_rtcp_packets_)->InternalSwap(CastToBase(&other->incoming_rtcp_packets_)); - CastToBase(&outgoing_rtcp_packets_)->InternalSwap(CastToBase(&other->outgoing_rtcp_packets_)); - CastToBase(&audio_playout_events_)->InternalSwap(CastToBase(&other->audio_playout_events_)); - CastToBase(&frame_decoded_events_)->InternalSwap(CastToBase(&other->frame_decoded_events_)); - CastToBase(&begin_log_events_)->InternalSwap(CastToBase(&other->begin_log_events_)); - CastToBase(&end_log_events_)->InternalSwap(CastToBase(&other->end_log_events_)); - CastToBase(&loss_based_bwe_updates_)->InternalSwap(CastToBase(&other->loss_based_bwe_updates_)); - CastToBase(&delay_based_bwe_updates_)->InternalSwap(CastToBase(&other->delay_based_bwe_updates_)); - CastToBase(&audio_network_adaptations_)->InternalSwap(CastToBase(&other->audio_network_adaptations_)); - CastToBase(&probe_clusters_)->InternalSwap(CastToBase(&other->probe_clusters_)); - CastToBase(&probe_success_)->InternalSwap(CastToBase(&other->probe_success_)); - CastToBase(&probe_failure_)->InternalSwap(CastToBase(&other->probe_failure_)); - CastToBase(&alr_states_)->InternalSwap(CastToBase(&other->alr_states_)); - CastToBase(&ice_candidate_configs_)->InternalSwap(CastToBase(&other->ice_candidate_configs_)); - CastToBase(&ice_candidate_events_)->InternalSwap(CastToBase(&other->ice_candidate_events_)); - CastToBase(&dtls_transport_state_events_)->InternalSwap(CastToBase(&other->dtls_transport_state_events_)); - CastToBase(&dtls_writable_states_)->InternalSwap(CastToBase(&other->dtls_writable_states_)); - CastToBase(&generic_packets_sent_)->InternalSwap(CastToBase(&other->generic_packets_sent_)); - CastToBase(&generic_packets_received_)->InternalSwap(CastToBase(&other->generic_packets_received_)); - CastToBase(&generic_acks_received_)->InternalSwap(CastToBase(&other->generic_acks_received_)); - CastToBase(&route_changes_)->InternalSwap(CastToBase(&other->route_changes_)); - CastToBase(&remote_estimates_)->InternalSwap(CastToBase(&other->remote_estimates_)); - CastToBase(&audio_recv_stream_configs_)->InternalSwap(CastToBase(&other->audio_recv_stream_configs_)); - CastToBase(&audio_send_stream_configs_)->InternalSwap(CastToBase(&other->audio_send_stream_configs_)); - CastToBase(&video_recv_stream_configs_)->InternalSwap(CastToBase(&other->video_recv_stream_configs_)); - CastToBase(&video_send_stream_configs_)->InternalSwap(CastToBase(&other->video_send_stream_configs_)); -} - -std::string EventStream::GetTypeName() const { - return "webrtc.rtclog2.EventStream"; -} - - -// =================================================================== - -void Event::InitAsDefaultInstance() { -} -class Event::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); -}; - -Event::Event() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.Event) -} -Event::Event(const Event& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.Event) -} - -void Event::SharedCtor() { -} - -Event::~Event() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.Event) - SharedDtor(); -} - -void Event::SharedDtor() { -} - -void Event::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const Event& Event::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_Event_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void Event::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.Event) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* Event::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - default: { - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool Event::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.Event) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.Event) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.Event) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void Event::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.Event) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.Event) -} - -size_t Event::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.Event) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void Event::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void Event::MergeFrom(const Event& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.Event) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - -} - -void Event::CopyFrom(const Event& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.Event) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Event::IsInitialized() const { - return true; -} - -void Event::InternalSwap(Event* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); -} - -std::string Event::GetTypeName() const { - return "webrtc.rtclog2.Event"; -} - - -// =================================================================== - -void GenericPacketReceived::InitAsDefaultInstance() { -} -class GenericPacketReceived::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_packet_number(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_packet_length(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_packet_number_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_packet_length_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -GenericPacketReceived::GenericPacketReceived() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.GenericPacketReceived) -} -GenericPacketReceived::GenericPacketReceived(const GenericPacketReceived& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - packet_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_packet_number_deltas()) { - packet_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_number_deltas_); - } - packet_length_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_packet_length_deltas()) { - packet_length_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_length_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.GenericPacketReceived) -} - -void GenericPacketReceived::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_GenericPacketReceived_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - packet_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - packet_length_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -GenericPacketReceived::~GenericPacketReceived() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.GenericPacketReceived) - SharedDtor(); -} - -void GenericPacketReceived::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - packet_number_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - packet_length_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void GenericPacketReceived::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const GenericPacketReceived& GenericPacketReceived::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_GenericPacketReceived_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void GenericPacketReceived::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.GenericPacketReceived) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - packet_number_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - packet_length_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x00000078u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* GenericPacketReceived::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int64 packet_number = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_packet_number(&has_bits); - packet_number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 packet_length = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_packet_length(&has_bits); - packet_length_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 16; - case 16: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 128)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 17; - case 17: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 138)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes packet_number_deltas = 18; - case 18: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 146)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_packet_number_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes packet_length_deltas = 19; - case 19: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 154)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_packet_length_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool GenericPacketReceived::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.GenericPacketReceived) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int64 packet_number = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_packet_number(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, &packet_number_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 packet_length = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_packet_length(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &packet_length_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 16; - case 16: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (128 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 17; - case 17: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (138 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes packet_number_deltas = 18; - case 18: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (146 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_packet_number_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes packet_length_deltas = 19; - case 19: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (154 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_packet_length_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.GenericPacketReceived) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.GenericPacketReceived) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void GenericPacketReceived::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.GenericPacketReceived) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional int64 packet_number = 2; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(2, this->packet_number(), output); - } - - // optional int32 packet_length = 3; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(3, this->packet_length(), output); - } - - // optional uint32 number_of_deltas = 16; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(16, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 17; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 17, this->timestamp_ms_deltas(), output); - } - - // optional bytes packet_number_deltas = 18; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 18, this->packet_number_deltas(), output); - } - - // optional bytes packet_length_deltas = 19; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 19, this->packet_length_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.GenericPacketReceived) -} - -size_t GenericPacketReceived::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.GenericPacketReceived) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000007fu) { - // optional bytes timestamp_ms_deltas = 17; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes packet_number_deltas = 18; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->packet_number_deltas()); - } - - // optional bytes packet_length_deltas = 19; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->packet_length_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional int64 packet_number = 2; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->packet_number()); - } - - // optional int32 packet_length = 3; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->packet_length()); - } - - // optional uint32 number_of_deltas = 16; - if (cached_has_bits & 0x00000040u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void GenericPacketReceived::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void GenericPacketReceived::MergeFrom(const GenericPacketReceived& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.GenericPacketReceived) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000007fu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_number_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - packet_length_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_length_deltas_); - } - if (cached_has_bits & 0x00000008u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000010u) { - packet_number_ = from.packet_number_; - } - if (cached_has_bits & 0x00000020u) { - packet_length_ = from.packet_length_; - } - if (cached_has_bits & 0x00000040u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void GenericPacketReceived::CopyFrom(const GenericPacketReceived& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.GenericPacketReceived) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool GenericPacketReceived::IsInitialized() const { - return true; -} - -void GenericPacketReceived::InternalSwap(GenericPacketReceived* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - packet_number_deltas_.Swap(&other->packet_number_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - packet_length_deltas_.Swap(&other->packet_length_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(packet_number_, other->packet_number_); - swap(packet_length_, other->packet_length_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string GenericPacketReceived::GetTypeName() const { - return "webrtc.rtclog2.GenericPacketReceived"; -} - - -// =================================================================== - -void GenericPacketSent::InitAsDefaultInstance() { -} -class GenericPacketSent::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_packet_number(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_overhead_length(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_payload_length(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_padding_length(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1024u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_packet_number_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_overhead_length_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_payload_length_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_padding_length_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } -}; - -GenericPacketSent::GenericPacketSent() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.GenericPacketSent) -} -GenericPacketSent::GenericPacketSent(const GenericPacketSent& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - packet_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_packet_number_deltas()) { - packet_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_number_deltas_); - } - overhead_length_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_overhead_length_deltas()) { - overhead_length_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.overhead_length_deltas_); - } - payload_length_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_payload_length_deltas()) { - payload_length_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_length_deltas_); - } - padding_length_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_padding_length_deltas()) { - padding_length_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.padding_length_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.GenericPacketSent) -} - -void GenericPacketSent::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_GenericPacketSent_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - packet_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - overhead_length_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_length_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - padding_length_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -GenericPacketSent::~GenericPacketSent() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.GenericPacketSent) - SharedDtor(); -} - -void GenericPacketSent::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - packet_number_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - overhead_length_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_length_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - padding_length_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void GenericPacketSent::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const GenericPacketSent& GenericPacketSent::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_GenericPacketSent_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void GenericPacketSent::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.GenericPacketSent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - packet_number_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - overhead_length_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000008u) { - payload_length_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000010u) { - padding_length_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x000000e0u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&overhead_length_) - - reinterpret_cast(×tamp_ms_)) + sizeof(overhead_length_)); - } - if (cached_has_bits & 0x00000700u) { - ::memset(&payload_length_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(&payload_length_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* GenericPacketSent::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int64 packet_number = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_packet_number(&has_bits); - packet_number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 overhead_length = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_overhead_length(&has_bits); - overhead_length_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 payload_length = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_payload_length(&has_bits); - payload_length_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 padding_length = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - _Internal::set_has_padding_length(&has_bits); - padding_length_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 16; - case 16: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 128)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 17; - case 17: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 138)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes packet_number_deltas = 18; - case 18: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 146)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_packet_number_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes overhead_length_deltas = 19; - case 19: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 154)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_overhead_length_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes payload_length_deltas = 20; - case 20: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 162)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_payload_length_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes padding_length_deltas = 21; - case 21: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 170)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_padding_length_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool GenericPacketSent::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.GenericPacketSent) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int64 packet_number = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_packet_number(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, &packet_number_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 overhead_length = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_overhead_length(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &overhead_length_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 payload_length = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_payload_length(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &payload_length_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 padding_length = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - _Internal::set_has_padding_length(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &padding_length_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 16; - case 16: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (128 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 17; - case 17: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (138 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes packet_number_deltas = 18; - case 18: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (146 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_packet_number_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes overhead_length_deltas = 19; - case 19: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (154 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_overhead_length_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes payload_length_deltas = 20; - case 20: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (162 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_payload_length_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes padding_length_deltas = 21; - case 21: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (170 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_padding_length_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.GenericPacketSent) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.GenericPacketSent) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void GenericPacketSent::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.GenericPacketSent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional int64 packet_number = 2; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(2, this->packet_number(), output); - } - - // optional int32 overhead_length = 3; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(3, this->overhead_length(), output); - } - - // optional int32 payload_length = 4; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(4, this->payload_length(), output); - } - - // optional int32 padding_length = 5; - if (cached_has_bits & 0x00000200u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(5, this->padding_length(), output); - } - - // optional uint32 number_of_deltas = 16; - if (cached_has_bits & 0x00000400u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(16, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 17; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 17, this->timestamp_ms_deltas(), output); - } - - // optional bytes packet_number_deltas = 18; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 18, this->packet_number_deltas(), output); - } - - // optional bytes overhead_length_deltas = 19; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 19, this->overhead_length_deltas(), output); - } - - // optional bytes payload_length_deltas = 20; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 20, this->payload_length_deltas(), output); - } - - // optional bytes padding_length_deltas = 21; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 21, this->padding_length_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.GenericPacketSent) -} - -size_t GenericPacketSent::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.GenericPacketSent) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional bytes timestamp_ms_deltas = 17; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes packet_number_deltas = 18; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->packet_number_deltas()); - } - - // optional bytes overhead_length_deltas = 19; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->overhead_length_deltas()); - } - - // optional bytes payload_length_deltas = 20; - if (cached_has_bits & 0x00000008u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->payload_length_deltas()); - } - - // optional bytes padding_length_deltas = 21; - if (cached_has_bits & 0x00000010u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->padding_length_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional int64 packet_number = 2; - if (cached_has_bits & 0x00000040u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->packet_number()); - } - - // optional int32 overhead_length = 3; - if (cached_has_bits & 0x00000080u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->overhead_length()); - } - - } - if (cached_has_bits & 0x00000700u) { - // optional int32 payload_length = 4; - if (cached_has_bits & 0x00000100u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->payload_length()); - } - - // optional int32 padding_length = 5; - if (cached_has_bits & 0x00000200u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->padding_length()); - } - - // optional uint32 number_of_deltas = 16; - if (cached_has_bits & 0x00000400u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void GenericPacketSent::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void GenericPacketSent::MergeFrom(const GenericPacketSent& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.GenericPacketSent) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_number_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - overhead_length_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.overhead_length_deltas_); - } - if (cached_has_bits & 0x00000008u) { - _has_bits_[0] |= 0x00000008u; - payload_length_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_length_deltas_); - } - if (cached_has_bits & 0x00000010u) { - _has_bits_[0] |= 0x00000010u; - padding_length_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.padding_length_deltas_); - } - if (cached_has_bits & 0x00000020u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000040u) { - packet_number_ = from.packet_number_; - } - if (cached_has_bits & 0x00000080u) { - overhead_length_ = from.overhead_length_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00000700u) { - if (cached_has_bits & 0x00000100u) { - payload_length_ = from.payload_length_; - } - if (cached_has_bits & 0x00000200u) { - padding_length_ = from.padding_length_; - } - if (cached_has_bits & 0x00000400u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void GenericPacketSent::CopyFrom(const GenericPacketSent& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.GenericPacketSent) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool GenericPacketSent::IsInitialized() const { - return true; -} - -void GenericPacketSent::InternalSwap(GenericPacketSent* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - packet_number_deltas_.Swap(&other->packet_number_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - overhead_length_deltas_.Swap(&other->overhead_length_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - payload_length_deltas_.Swap(&other->payload_length_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - padding_length_deltas_.Swap(&other->padding_length_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(packet_number_, other->packet_number_); - swap(overhead_length_, other->overhead_length_); - swap(payload_length_, other->payload_length_); - swap(padding_length_, other->padding_length_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string GenericPacketSent::GetTypeName() const { - return "webrtc.rtclog2.GenericPacketSent"; -} - - -// =================================================================== - -void GenericAckReceived::InitAsDefaultInstance() { -} -class GenericAckReceived::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_packet_number(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_acked_packet_number(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_receive_acked_packet_time_ms(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_packet_number_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_acked_packet_number_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_receive_acked_packet_time_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } -}; - -GenericAckReceived::GenericAckReceived() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.GenericAckReceived) -} -GenericAckReceived::GenericAckReceived(const GenericAckReceived& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - packet_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_packet_number_deltas()) { - packet_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_number_deltas_); - } - acked_packet_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_acked_packet_number_deltas()) { - acked_packet_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.acked_packet_number_deltas_); - } - receive_acked_packet_time_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_receive_acked_packet_time_ms_deltas()) { - receive_acked_packet_time_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.receive_acked_packet_time_ms_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.GenericAckReceived) -} - -void GenericAckReceived::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_GenericAckReceived_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - packet_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - acked_packet_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - receive_acked_packet_time_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -GenericAckReceived::~GenericAckReceived() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.GenericAckReceived) - SharedDtor(); -} - -void GenericAckReceived::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - packet_number_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - acked_packet_number_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - receive_acked_packet_time_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void GenericAckReceived::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const GenericAckReceived& GenericAckReceived::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_GenericAckReceived_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void GenericAckReceived::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.GenericAckReceived) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - packet_number_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - acked_packet_number_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000008u) { - receive_acked_packet_time_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x000000f0u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&receive_acked_packet_time_ms_) - - reinterpret_cast(×tamp_ms_)) + sizeof(receive_acked_packet_time_ms_)); - } - number_of_deltas_ = 0u; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* GenericAckReceived::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int64 packet_number = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_packet_number(&has_bits); - packet_number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int64 acked_packet_number = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_acked_packet_number(&has_bits); - acked_packet_number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int64 receive_acked_packet_time_ms = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_receive_acked_packet_time_ms(&has_bits); - receive_acked_packet_time_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 16; - case 16: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 128)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 17; - case 17: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 138)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes packet_number_deltas = 18; - case 18: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 146)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_packet_number_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes acked_packet_number_deltas = 19; - case 19: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 154)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_acked_packet_number_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes receive_acked_packet_time_ms_deltas = 20; - case 20: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 162)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_receive_acked_packet_time_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool GenericAckReceived::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.GenericAckReceived) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int64 packet_number = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_packet_number(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, &packet_number_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int64 acked_packet_number = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_acked_packet_number(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, &acked_packet_number_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int64 receive_acked_packet_time_ms = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_receive_acked_packet_time_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, &receive_acked_packet_time_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 16; - case 16: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (128 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 17; - case 17: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (138 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes packet_number_deltas = 18; - case 18: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (146 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_packet_number_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes acked_packet_number_deltas = 19; - case 19: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (154 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_acked_packet_number_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes receive_acked_packet_time_ms_deltas = 20; - case 20: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (162 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_receive_acked_packet_time_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.GenericAckReceived) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.GenericAckReceived) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void GenericAckReceived::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.GenericAckReceived) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional int64 packet_number = 2; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(2, this->packet_number(), output); - } - - // optional int64 acked_packet_number = 3; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(3, this->acked_packet_number(), output); - } - - // optional int64 receive_acked_packet_time_ms = 4; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(4, this->receive_acked_packet_time_ms(), output); - } - - // optional uint32 number_of_deltas = 16; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(16, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 17; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 17, this->timestamp_ms_deltas(), output); - } - - // optional bytes packet_number_deltas = 18; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 18, this->packet_number_deltas(), output); - } - - // optional bytes acked_packet_number_deltas = 19; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 19, this->acked_packet_number_deltas(), output); - } - - // optional bytes receive_acked_packet_time_ms_deltas = 20; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 20, this->receive_acked_packet_time_ms_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.GenericAckReceived) -} - -size_t GenericAckReceived::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.GenericAckReceived) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional bytes timestamp_ms_deltas = 17; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes packet_number_deltas = 18; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->packet_number_deltas()); - } - - // optional bytes acked_packet_number_deltas = 19; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->acked_packet_number_deltas()); - } - - // optional bytes receive_acked_packet_time_ms_deltas = 20; - if (cached_has_bits & 0x00000008u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->receive_acked_packet_time_ms_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional int64 packet_number = 2; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->packet_number()); - } - - // optional int64 acked_packet_number = 3; - if (cached_has_bits & 0x00000040u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->acked_packet_number()); - } - - // optional int64 receive_acked_packet_time_ms = 4; - if (cached_has_bits & 0x00000080u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->receive_acked_packet_time_ms()); - } - - } - // optional uint32 number_of_deltas = 16; - if (cached_has_bits & 0x00000100u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void GenericAckReceived::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void GenericAckReceived::MergeFrom(const GenericAckReceived& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.GenericAckReceived) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.packet_number_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - acked_packet_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.acked_packet_number_deltas_); - } - if (cached_has_bits & 0x00000008u) { - _has_bits_[0] |= 0x00000008u; - receive_acked_packet_time_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.receive_acked_packet_time_ms_deltas_); - } - if (cached_has_bits & 0x00000010u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000020u) { - packet_number_ = from.packet_number_; - } - if (cached_has_bits & 0x00000040u) { - acked_packet_number_ = from.acked_packet_number_; - } - if (cached_has_bits & 0x00000080u) { - receive_acked_packet_time_ms_ = from.receive_acked_packet_time_ms_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00000100u) { - set_number_of_deltas(from.number_of_deltas()); - } -} - -void GenericAckReceived::CopyFrom(const GenericAckReceived& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.GenericAckReceived) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool GenericAckReceived::IsInitialized() const { - return true; -} - -void GenericAckReceived::InternalSwap(GenericAckReceived* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - packet_number_deltas_.Swap(&other->packet_number_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - acked_packet_number_deltas_.Swap(&other->acked_packet_number_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - receive_acked_packet_time_ms_deltas_.Swap(&other->receive_acked_packet_time_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(packet_number_, other->packet_number_); - swap(acked_packet_number_, other->acked_packet_number_); - swap(receive_acked_packet_time_ms_, other->receive_acked_packet_time_ms_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string GenericAckReceived::GetTypeName() const { - return "webrtc.rtclog2.GenericAckReceived"; -} - - -// =================================================================== - -void IncomingRtpPackets::InitAsDefaultInstance() { -} -class IncomingRtpPackets::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 32768u; - } - static void set_has_marker(HasBits* has_bits) { - (*has_bits)[0] |= 16777216u; - } - static void set_has_payload_type(HasBits* has_bits) { - (*has_bits)[0] |= 65536u; - } - static void set_has_sequence_number(HasBits* has_bits) { - (*has_bits)[0] |= 131072u; - } - static void set_has_rtp_timestamp(HasBits* has_bits) { - (*has_bits)[0] |= 262144u; - } - static void set_has_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 524288u; - } - static void set_has_payload_size(HasBits* has_bits) { - (*has_bits)[0] |= 1048576u; - } - static void set_has_header_size(HasBits* has_bits) { - (*has_bits)[0] |= 2097152u; - } - static void set_has_padding_size(HasBits* has_bits) { - (*has_bits)[0] |= 4194304u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8388608u; - } - static void set_has_transport_sequence_number(HasBits* has_bits) { - (*has_bits)[0] |= 67108864u; - } - static void set_has_transmission_time_offset(HasBits* has_bits) { - (*has_bits)[0] |= 134217728u; - } - static void set_has_absolute_send_time(HasBits* has_bits) { - (*has_bits)[0] |= 268435456u; - } - static void set_has_video_rotation(HasBits* has_bits) { - (*has_bits)[0] |= 536870912u; - } - static void set_has_audio_level(HasBits* has_bits) { - (*has_bits)[0] |= 1073741824u; - } - static void set_has_voice_activity(HasBits* has_bits) { - (*has_bits)[0] |= 33554432u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_marker_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_payload_type_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_sequence_number_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_rtp_timestamp_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_ssrc_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_payload_size_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_header_size_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_padding_size_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_transport_sequence_number_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } - static void set_has_transmission_time_offset_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1024u; - } - static void set_has_absolute_send_time_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2048u; - } - static void set_has_video_rotation_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4096u; - } - static void set_has_audio_level_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8192u; - } - static void set_has_voice_activity_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16384u; - } -}; - -IncomingRtpPackets::IncomingRtpPackets() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.IncomingRtpPackets) -} -IncomingRtpPackets::IncomingRtpPackets(const IncomingRtpPackets& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - marker_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_marker_deltas()) { - marker_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.marker_deltas_); - } - payload_type_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_payload_type_deltas()) { - payload_type_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_type_deltas_); - } - sequence_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_sequence_number_deltas()) { - sequence_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.sequence_number_deltas_); - } - rtp_timestamp_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_rtp_timestamp_deltas()) { - rtp_timestamp_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.rtp_timestamp_deltas_); - } - ssrc_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_ssrc_deltas()) { - ssrc_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.ssrc_deltas_); - } - payload_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_payload_size_deltas()) { - payload_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_size_deltas_); - } - header_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_header_size_deltas()) { - header_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.header_size_deltas_); - } - padding_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_padding_size_deltas()) { - padding_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.padding_size_deltas_); - } - transport_sequence_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_transport_sequence_number_deltas()) { - transport_sequence_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.transport_sequence_number_deltas_); - } - transmission_time_offset_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_transmission_time_offset_deltas()) { - transmission_time_offset_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.transmission_time_offset_deltas_); - } - absolute_send_time_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_absolute_send_time_deltas()) { - absolute_send_time_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.absolute_send_time_deltas_); - } - video_rotation_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_video_rotation_deltas()) { - video_rotation_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.video_rotation_deltas_); - } - audio_level_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_audio_level_deltas()) { - audio_level_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.audio_level_deltas_); - } - voice_activity_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_voice_activity_deltas()) { - voice_activity_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.voice_activity_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&audio_level_) - - reinterpret_cast(×tamp_ms_)) + sizeof(audio_level_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.IncomingRtpPackets) -} - -void IncomingRtpPackets::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_IncomingRtpPackets_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - marker_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_type_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - sequence_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - rtp_timestamp_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ssrc_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - header_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - padding_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - transport_sequence_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - transmission_time_offset_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - absolute_send_time_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - video_rotation_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - audio_level_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - voice_activity_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&audio_level_) - - reinterpret_cast(×tamp_ms_)) + sizeof(audio_level_)); -} - -IncomingRtpPackets::~IncomingRtpPackets() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.IncomingRtpPackets) - SharedDtor(); -} - -void IncomingRtpPackets::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - marker_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_type_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - sequence_number_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - rtp_timestamp_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ssrc_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_size_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - header_size_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - padding_size_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - transport_sequence_number_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - transmission_time_offset_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - absolute_send_time_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - video_rotation_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - audio_level_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - voice_activity_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void IncomingRtpPackets::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const IncomingRtpPackets& IncomingRtpPackets::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_IncomingRtpPackets_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void IncomingRtpPackets::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.IncomingRtpPackets) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - marker_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - payload_type_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000008u) { - sequence_number_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000010u) { - rtp_timestamp_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000020u) { - ssrc_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000040u) { - payload_size_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000080u) { - header_size_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x00007f00u) { - if (cached_has_bits & 0x00000100u) { - padding_size_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000200u) { - transport_sequence_number_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000400u) { - transmission_time_offset_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000800u) { - absolute_send_time_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00001000u) { - video_rotation_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00002000u) { - audio_level_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00004000u) { - voice_activity_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - timestamp_ms_ = PROTOBUF_LONGLONG(0); - if (cached_has_bits & 0x00ff0000u) { - ::memset(&payload_type_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(&payload_type_)) + sizeof(number_of_deltas_)); - } - if (cached_has_bits & 0x7f000000u) { - ::memset(&marker_, 0, static_cast( - reinterpret_cast(&audio_level_) - - reinterpret_cast(&marker_)) + sizeof(audio_level_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* IncomingRtpPackets::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool marker = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_marker(&has_bits); - marker_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 payload_type = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_payload_type(&has_bits); - payload_type_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 sequence_number = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_sequence_number(&has_bits); - sequence_number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional fixed32 rtp_timestamp = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 45)) { - _Internal::set_has_rtp_timestamp(&has_bits); - rtp_timestamp_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint32>(ptr); - ptr += sizeof(::PROTOBUF_NAMESPACE_ID::uint32); - } else goto handle_unusual; - continue; - // optional fixed32 ssrc = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 53)) { - _Internal::set_has_ssrc(&has_bits); - ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint32>(ptr); - ptr += sizeof(::PROTOBUF_NAMESPACE_ID::uint32); - } else goto handle_unusual; - continue; - // optional uint32 payload_size = 8; - case 8: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 64)) { - _Internal::set_has_payload_size(&has_bits); - payload_size_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 header_size = 9; - case 9: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 72)) { - _Internal::set_has_header_size(&has_bits); - header_size_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 padding_size = 10; - case 10: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 80)) { - _Internal::set_has_padding_size(&has_bits); - padding_size_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 11; - case 11: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 88)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 transport_sequence_number = 15; - case 15: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 120)) { - _Internal::set_has_transport_sequence_number(&has_bits); - transport_sequence_number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 transmission_time_offset = 16; - case 16: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 128)) { - _Internal::set_has_transmission_time_offset(&has_bits); - transmission_time_offset_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 absolute_send_time = 17; - case 17: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 136)) { - _Internal::set_has_absolute_send_time(&has_bits); - absolute_send_time_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 video_rotation = 18; - case 18: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 144)) { - _Internal::set_has_video_rotation(&has_bits); - video_rotation_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 audio_level = 19; - case 19: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 152)) { - _Internal::set_has_audio_level(&has_bits); - audio_level_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool voice_activity = 20; - case 20: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 160)) { - _Internal::set_has_voice_activity(&has_bits); - voice_activity_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes marker_deltas = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_marker_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes payload_type_deltas = 103; - case 103: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_payload_type_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes sequence_number_deltas = 104; - case 104: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_sequence_number_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes rtp_timestamp_deltas = 105; - case 105: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 74)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_rtp_timestamp_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes ssrc_deltas = 106; - case 106: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 82)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_ssrc_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes payload_size_deltas = 108; - case 108: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 98)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_payload_size_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes header_size_deltas = 109; - case 109: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 106)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_header_size_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes padding_size_deltas = 110; - case 110: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 114)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_padding_size_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes transport_sequence_number_deltas = 115; - case 115: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 154)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_transport_sequence_number_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes transmission_time_offset_deltas = 116; - case 116: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 162)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_transmission_time_offset_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes absolute_send_time_deltas = 117; - case 117: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 170)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_absolute_send_time_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes video_rotation_deltas = 118; - case 118: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 178)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_video_rotation_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes audio_level_deltas = 119; - case 119: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 186)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_audio_level_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes voice_activity_deltas = 120; - case 120: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 194)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_voice_activity_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool IncomingRtpPackets::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.IncomingRtpPackets) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool marker = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_marker(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &marker_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 payload_type = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_payload_type(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &payload_type_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 sequence_number = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_sequence_number(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &sequence_number_))); - } else { - goto handle_unusual; - } - break; - } - - // optional fixed32 rtp_timestamp = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (45 & 0xFF)) { - _Internal::set_has_rtp_timestamp(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_FIXED32>( - input, &rtp_timestamp_))); - } else { - goto handle_unusual; - } - break; - } - - // optional fixed32 ssrc = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (53 & 0xFF)) { - _Internal::set_has_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_FIXED32>( - input, &ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 payload_size = 8; - case 8: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (64 & 0xFF)) { - _Internal::set_has_payload_size(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &payload_size_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 header_size = 9; - case 9: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (72 & 0xFF)) { - _Internal::set_has_header_size(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &header_size_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 padding_size = 10; - case 10: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (80 & 0xFF)) { - _Internal::set_has_padding_size(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &padding_size_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 11; - case 11: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (88 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 transport_sequence_number = 15; - case 15: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (120 & 0xFF)) { - _Internal::set_has_transport_sequence_number(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &transport_sequence_number_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 transmission_time_offset = 16; - case 16: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (128 & 0xFF)) { - _Internal::set_has_transmission_time_offset(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &transmission_time_offset_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 absolute_send_time = 17; - case 17: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (136 & 0xFF)) { - _Internal::set_has_absolute_send_time(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &absolute_send_time_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 video_rotation = 18; - case 18: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (144 & 0xFF)) { - _Internal::set_has_video_rotation(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &video_rotation_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 audio_level = 19; - case 19: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (152 & 0xFF)) { - _Internal::set_has_audio_level(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &audio_level_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool voice_activity = 20; - case 20: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (160 & 0xFF)) { - _Internal::set_has_voice_activity(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &voice_activity_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes marker_deltas = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_marker_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes payload_type_deltas = 103; - case 103: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (826 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_payload_type_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes sequence_number_deltas = 104; - case 104: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (834 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_sequence_number_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes rtp_timestamp_deltas = 105; - case 105: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (842 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_rtp_timestamp_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes ssrc_deltas = 106; - case 106: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (850 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_ssrc_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes payload_size_deltas = 108; - case 108: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (866 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_payload_size_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes header_size_deltas = 109; - case 109: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (874 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_header_size_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes padding_size_deltas = 110; - case 110: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (882 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_padding_size_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes transport_sequence_number_deltas = 115; - case 115: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (922 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_transport_sequence_number_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes transmission_time_offset_deltas = 116; - case 116: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (930 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_transmission_time_offset_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes absolute_send_time_deltas = 117; - case 117: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (938 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_absolute_send_time_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes video_rotation_deltas = 118; - case 118: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (946 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_video_rotation_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes audio_level_deltas = 119; - case 119: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (954 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_audio_level_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes voice_activity_deltas = 120; - case 120: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (962 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_voice_activity_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.IncomingRtpPackets) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.IncomingRtpPackets) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void IncomingRtpPackets::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.IncomingRtpPackets) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00008000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional bool marker = 2; - if (cached_has_bits & 0x01000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(2, this->marker(), output); - } - - // optional uint32 payload_type = 3; - if (cached_has_bits & 0x00010000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->payload_type(), output); - } - - // optional uint32 sequence_number = 4; - if (cached_has_bits & 0x00020000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->sequence_number(), output); - } - - // optional fixed32 rtp_timestamp = 5; - if (cached_has_bits & 0x00040000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFixed32(5, this->rtp_timestamp(), output); - } - - // optional fixed32 ssrc = 6; - if (cached_has_bits & 0x00080000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFixed32(6, this->ssrc(), output); - } - - // optional uint32 payload_size = 8; - if (cached_has_bits & 0x00100000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(8, this->payload_size(), output); - } - - // optional uint32 header_size = 9; - if (cached_has_bits & 0x00200000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(9, this->header_size(), output); - } - - // optional uint32 padding_size = 10; - if (cached_has_bits & 0x00400000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(10, this->padding_size(), output); - } - - // optional uint32 number_of_deltas = 11; - if (cached_has_bits & 0x00800000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(11, this->number_of_deltas(), output); - } - - // optional uint32 transport_sequence_number = 15; - if (cached_has_bits & 0x04000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(15, this->transport_sequence_number(), output); - } - - // optional int32 transmission_time_offset = 16; - if (cached_has_bits & 0x08000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(16, this->transmission_time_offset(), output); - } - - // optional uint32 absolute_send_time = 17; - if (cached_has_bits & 0x10000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(17, this->absolute_send_time(), output); - } - - // optional uint32 video_rotation = 18; - if (cached_has_bits & 0x20000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(18, this->video_rotation(), output); - } - - // optional uint32 audio_level = 19; - if (cached_has_bits & 0x40000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(19, this->audio_level(), output); - } - - // optional bool voice_activity = 20; - if (cached_has_bits & 0x02000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(20, this->voice_activity(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes marker_deltas = 102; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->marker_deltas(), output); - } - - // optional bytes payload_type_deltas = 103; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 103, this->payload_type_deltas(), output); - } - - // optional bytes sequence_number_deltas = 104; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 104, this->sequence_number_deltas(), output); - } - - // optional bytes rtp_timestamp_deltas = 105; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 105, this->rtp_timestamp_deltas(), output); - } - - // optional bytes ssrc_deltas = 106; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 106, this->ssrc_deltas(), output); - } - - // optional bytes payload_size_deltas = 108; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 108, this->payload_size_deltas(), output); - } - - // optional bytes header_size_deltas = 109; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 109, this->header_size_deltas(), output); - } - - // optional bytes padding_size_deltas = 110; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 110, this->padding_size_deltas(), output); - } - - // optional bytes transport_sequence_number_deltas = 115; - if (cached_has_bits & 0x00000200u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 115, this->transport_sequence_number_deltas(), output); - } - - // optional bytes transmission_time_offset_deltas = 116; - if (cached_has_bits & 0x00000400u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 116, this->transmission_time_offset_deltas(), output); - } - - // optional bytes absolute_send_time_deltas = 117; - if (cached_has_bits & 0x00000800u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 117, this->absolute_send_time_deltas(), output); - } - - // optional bytes video_rotation_deltas = 118; - if (cached_has_bits & 0x00001000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 118, this->video_rotation_deltas(), output); - } - - // optional bytes audio_level_deltas = 119; - if (cached_has_bits & 0x00002000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 119, this->audio_level_deltas(), output); - } - - // optional bytes voice_activity_deltas = 120; - if (cached_has_bits & 0x00004000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 120, this->voice_activity_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.IncomingRtpPackets) -} - -size_t IncomingRtpPackets::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.IncomingRtpPackets) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes marker_deltas = 102; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->marker_deltas()); - } - - // optional bytes payload_type_deltas = 103; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->payload_type_deltas()); - } - - // optional bytes sequence_number_deltas = 104; - if (cached_has_bits & 0x00000008u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->sequence_number_deltas()); - } - - // optional bytes rtp_timestamp_deltas = 105; - if (cached_has_bits & 0x00000010u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->rtp_timestamp_deltas()); - } - - // optional bytes ssrc_deltas = 106; - if (cached_has_bits & 0x00000020u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->ssrc_deltas()); - } - - // optional bytes payload_size_deltas = 108; - if (cached_has_bits & 0x00000040u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->payload_size_deltas()); - } - - // optional bytes header_size_deltas = 109; - if (cached_has_bits & 0x00000080u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->header_size_deltas()); - } - - } - if (cached_has_bits & 0x0000ff00u) { - // optional bytes padding_size_deltas = 110; - if (cached_has_bits & 0x00000100u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->padding_size_deltas()); - } - - // optional bytes transport_sequence_number_deltas = 115; - if (cached_has_bits & 0x00000200u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->transport_sequence_number_deltas()); - } - - // optional bytes transmission_time_offset_deltas = 116; - if (cached_has_bits & 0x00000400u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->transmission_time_offset_deltas()); - } - - // optional bytes absolute_send_time_deltas = 117; - if (cached_has_bits & 0x00000800u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->absolute_send_time_deltas()); - } - - // optional bytes video_rotation_deltas = 118; - if (cached_has_bits & 0x00001000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->video_rotation_deltas()); - } - - // optional bytes audio_level_deltas = 119; - if (cached_has_bits & 0x00002000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->audio_level_deltas()); - } - - // optional bytes voice_activity_deltas = 120; - if (cached_has_bits & 0x00004000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->voice_activity_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00008000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - } - if (cached_has_bits & 0x00ff0000u) { - // optional uint32 payload_type = 3; - if (cached_has_bits & 0x00010000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->payload_type()); - } - - // optional uint32 sequence_number = 4; - if (cached_has_bits & 0x00020000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->sequence_number()); - } - - // optional fixed32 rtp_timestamp = 5; - if (cached_has_bits & 0x00040000u) { - total_size += 1 + 4; - } - - // optional fixed32 ssrc = 6; - if (cached_has_bits & 0x00080000u) { - total_size += 1 + 4; - } - - // optional uint32 payload_size = 8; - if (cached_has_bits & 0x00100000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->payload_size()); - } - - // optional uint32 header_size = 9; - if (cached_has_bits & 0x00200000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->header_size()); - } - - // optional uint32 padding_size = 10; - if (cached_has_bits & 0x00400000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->padding_size()); - } - - // optional uint32 number_of_deltas = 11; - if (cached_has_bits & 0x00800000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - if (cached_has_bits & 0x7f000000u) { - // optional bool marker = 2; - if (cached_has_bits & 0x01000000u) { - total_size += 1 + 1; - } - - // optional bool voice_activity = 20; - if (cached_has_bits & 0x02000000u) { - total_size += 2 + 1; - } - - // optional uint32 transport_sequence_number = 15; - if (cached_has_bits & 0x04000000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->transport_sequence_number()); - } - - // optional int32 transmission_time_offset = 16; - if (cached_has_bits & 0x08000000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->transmission_time_offset()); - } - - // optional uint32 absolute_send_time = 17; - if (cached_has_bits & 0x10000000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->absolute_send_time()); - } - - // optional uint32 video_rotation = 18; - if (cached_has_bits & 0x20000000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->video_rotation()); - } - - // optional uint32 audio_level = 19; - if (cached_has_bits & 0x40000000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->audio_level()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void IncomingRtpPackets::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void IncomingRtpPackets::MergeFrom(const IncomingRtpPackets& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.IncomingRtpPackets) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - marker_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.marker_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_type_deltas_); - } - if (cached_has_bits & 0x00000008u) { - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.sequence_number_deltas_); - } - if (cached_has_bits & 0x00000010u) { - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.rtp_timestamp_deltas_); - } - if (cached_has_bits & 0x00000020u) { - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.ssrc_deltas_); - } - if (cached_has_bits & 0x00000040u) { - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_size_deltas_); - } - if (cached_has_bits & 0x00000080u) { - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.header_size_deltas_); - } - } - if (cached_has_bits & 0x0000ff00u) { - if (cached_has_bits & 0x00000100u) { - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.padding_size_deltas_); - } - if (cached_has_bits & 0x00000200u) { - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.transport_sequence_number_deltas_); - } - if (cached_has_bits & 0x00000400u) { - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.transmission_time_offset_deltas_); - } - if (cached_has_bits & 0x00000800u) { - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.absolute_send_time_deltas_); - } - if (cached_has_bits & 0x00001000u) { - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.video_rotation_deltas_); - } - if (cached_has_bits & 0x00002000u) { - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.audio_level_deltas_); - } - if (cached_has_bits & 0x00004000u) { - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.voice_activity_deltas_); - } - if (cached_has_bits & 0x00008000u) { - timestamp_ms_ = from.timestamp_ms_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00ff0000u) { - if (cached_has_bits & 0x00010000u) { - payload_type_ = from.payload_type_; - } - if (cached_has_bits & 0x00020000u) { - sequence_number_ = from.sequence_number_; - } - if (cached_has_bits & 0x00040000u) { - rtp_timestamp_ = from.rtp_timestamp_; - } - if (cached_has_bits & 0x00080000u) { - ssrc_ = from.ssrc_; - } - if (cached_has_bits & 0x00100000u) { - payload_size_ = from.payload_size_; - } - if (cached_has_bits & 0x00200000u) { - header_size_ = from.header_size_; - } - if (cached_has_bits & 0x00400000u) { - padding_size_ = from.padding_size_; - } - if (cached_has_bits & 0x00800000u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x7f000000u) { - if (cached_has_bits & 0x01000000u) { - marker_ = from.marker_; - } - if (cached_has_bits & 0x02000000u) { - voice_activity_ = from.voice_activity_; - } - if (cached_has_bits & 0x04000000u) { - transport_sequence_number_ = from.transport_sequence_number_; - } - if (cached_has_bits & 0x08000000u) { - transmission_time_offset_ = from.transmission_time_offset_; - } - if (cached_has_bits & 0x10000000u) { - absolute_send_time_ = from.absolute_send_time_; - } - if (cached_has_bits & 0x20000000u) { - video_rotation_ = from.video_rotation_; - } - if (cached_has_bits & 0x40000000u) { - audio_level_ = from.audio_level_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void IncomingRtpPackets::CopyFrom(const IncomingRtpPackets& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.IncomingRtpPackets) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool IncomingRtpPackets::IsInitialized() const { - return true; -} - -void IncomingRtpPackets::InternalSwap(IncomingRtpPackets* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - marker_deltas_.Swap(&other->marker_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - payload_type_deltas_.Swap(&other->payload_type_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - sequence_number_deltas_.Swap(&other->sequence_number_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - rtp_timestamp_deltas_.Swap(&other->rtp_timestamp_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - ssrc_deltas_.Swap(&other->ssrc_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - payload_size_deltas_.Swap(&other->payload_size_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - header_size_deltas_.Swap(&other->header_size_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - padding_size_deltas_.Swap(&other->padding_size_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - transport_sequence_number_deltas_.Swap(&other->transport_sequence_number_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - transmission_time_offset_deltas_.Swap(&other->transmission_time_offset_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - absolute_send_time_deltas_.Swap(&other->absolute_send_time_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - video_rotation_deltas_.Swap(&other->video_rotation_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - audio_level_deltas_.Swap(&other->audio_level_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - voice_activity_deltas_.Swap(&other->voice_activity_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(payload_type_, other->payload_type_); - swap(sequence_number_, other->sequence_number_); - swap(rtp_timestamp_, other->rtp_timestamp_); - swap(ssrc_, other->ssrc_); - swap(payload_size_, other->payload_size_); - swap(header_size_, other->header_size_); - swap(padding_size_, other->padding_size_); - swap(number_of_deltas_, other->number_of_deltas_); - swap(marker_, other->marker_); - swap(voice_activity_, other->voice_activity_); - swap(transport_sequence_number_, other->transport_sequence_number_); - swap(transmission_time_offset_, other->transmission_time_offset_); - swap(absolute_send_time_, other->absolute_send_time_); - swap(video_rotation_, other->video_rotation_); - swap(audio_level_, other->audio_level_); -} - -std::string IncomingRtpPackets::GetTypeName() const { - return "webrtc.rtclog2.IncomingRtpPackets"; -} - - -// =================================================================== - -void OutgoingRtpPackets::InitAsDefaultInstance() { -} -class OutgoingRtpPackets::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 32768u; - } - static void set_has_marker(HasBits* has_bits) { - (*has_bits)[0] |= 16777216u; - } - static void set_has_payload_type(HasBits* has_bits) { - (*has_bits)[0] |= 65536u; - } - static void set_has_sequence_number(HasBits* has_bits) { - (*has_bits)[0] |= 131072u; - } - static void set_has_rtp_timestamp(HasBits* has_bits) { - (*has_bits)[0] |= 262144u; - } - static void set_has_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 524288u; - } - static void set_has_payload_size(HasBits* has_bits) { - (*has_bits)[0] |= 1048576u; - } - static void set_has_header_size(HasBits* has_bits) { - (*has_bits)[0] |= 2097152u; - } - static void set_has_padding_size(HasBits* has_bits) { - (*has_bits)[0] |= 4194304u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8388608u; - } - static void set_has_transport_sequence_number(HasBits* has_bits) { - (*has_bits)[0] |= 67108864u; - } - static void set_has_transmission_time_offset(HasBits* has_bits) { - (*has_bits)[0] |= 134217728u; - } - static void set_has_absolute_send_time(HasBits* has_bits) { - (*has_bits)[0] |= 268435456u; - } - static void set_has_video_rotation(HasBits* has_bits) { - (*has_bits)[0] |= 536870912u; - } - static void set_has_audio_level(HasBits* has_bits) { - (*has_bits)[0] |= 1073741824u; - } - static void set_has_voice_activity(HasBits* has_bits) { - (*has_bits)[0] |= 33554432u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_marker_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_payload_type_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_sequence_number_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_rtp_timestamp_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_ssrc_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_payload_size_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_header_size_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_padding_size_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_transport_sequence_number_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } - static void set_has_transmission_time_offset_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1024u; - } - static void set_has_absolute_send_time_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2048u; - } - static void set_has_video_rotation_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4096u; - } - static void set_has_audio_level_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8192u; - } - static void set_has_voice_activity_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16384u; - } -}; - -OutgoingRtpPackets::OutgoingRtpPackets() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.OutgoingRtpPackets) -} -OutgoingRtpPackets::OutgoingRtpPackets(const OutgoingRtpPackets& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - marker_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_marker_deltas()) { - marker_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.marker_deltas_); - } - payload_type_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_payload_type_deltas()) { - payload_type_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_type_deltas_); - } - sequence_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_sequence_number_deltas()) { - sequence_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.sequence_number_deltas_); - } - rtp_timestamp_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_rtp_timestamp_deltas()) { - rtp_timestamp_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.rtp_timestamp_deltas_); - } - ssrc_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_ssrc_deltas()) { - ssrc_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.ssrc_deltas_); - } - payload_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_payload_size_deltas()) { - payload_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_size_deltas_); - } - header_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_header_size_deltas()) { - header_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.header_size_deltas_); - } - padding_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_padding_size_deltas()) { - padding_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.padding_size_deltas_); - } - transport_sequence_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_transport_sequence_number_deltas()) { - transport_sequence_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.transport_sequence_number_deltas_); - } - transmission_time_offset_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_transmission_time_offset_deltas()) { - transmission_time_offset_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.transmission_time_offset_deltas_); - } - absolute_send_time_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_absolute_send_time_deltas()) { - absolute_send_time_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.absolute_send_time_deltas_); - } - video_rotation_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_video_rotation_deltas()) { - video_rotation_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.video_rotation_deltas_); - } - audio_level_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_audio_level_deltas()) { - audio_level_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.audio_level_deltas_); - } - voice_activity_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_voice_activity_deltas()) { - voice_activity_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.voice_activity_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&audio_level_) - - reinterpret_cast(×tamp_ms_)) + sizeof(audio_level_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.OutgoingRtpPackets) -} - -void OutgoingRtpPackets::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_OutgoingRtpPackets_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - marker_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_type_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - sequence_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - rtp_timestamp_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ssrc_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - header_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - padding_size_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - transport_sequence_number_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - transmission_time_offset_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - absolute_send_time_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - video_rotation_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - audio_level_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - voice_activity_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&audio_level_) - - reinterpret_cast(×tamp_ms_)) + sizeof(audio_level_)); -} - -OutgoingRtpPackets::~OutgoingRtpPackets() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.OutgoingRtpPackets) - SharedDtor(); -} - -void OutgoingRtpPackets::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - marker_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_type_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - sequence_number_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - rtp_timestamp_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ssrc_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - payload_size_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - header_size_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - padding_size_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - transport_sequence_number_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - transmission_time_offset_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - absolute_send_time_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - video_rotation_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - audio_level_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - voice_activity_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void OutgoingRtpPackets::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const OutgoingRtpPackets& OutgoingRtpPackets::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_OutgoingRtpPackets_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void OutgoingRtpPackets::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.OutgoingRtpPackets) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - marker_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - payload_type_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000008u) { - sequence_number_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000010u) { - rtp_timestamp_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000020u) { - ssrc_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000040u) { - payload_size_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000080u) { - header_size_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x00007f00u) { - if (cached_has_bits & 0x00000100u) { - padding_size_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000200u) { - transport_sequence_number_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000400u) { - transmission_time_offset_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000800u) { - absolute_send_time_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00001000u) { - video_rotation_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00002000u) { - audio_level_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00004000u) { - voice_activity_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - timestamp_ms_ = PROTOBUF_LONGLONG(0); - if (cached_has_bits & 0x00ff0000u) { - ::memset(&payload_type_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(&payload_type_)) + sizeof(number_of_deltas_)); - } - if (cached_has_bits & 0x7f000000u) { - ::memset(&marker_, 0, static_cast( - reinterpret_cast(&audio_level_) - - reinterpret_cast(&marker_)) + sizeof(audio_level_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* OutgoingRtpPackets::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool marker = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_marker(&has_bits); - marker_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 payload_type = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_payload_type(&has_bits); - payload_type_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 sequence_number = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_sequence_number(&has_bits); - sequence_number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional fixed32 rtp_timestamp = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 45)) { - _Internal::set_has_rtp_timestamp(&has_bits); - rtp_timestamp_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint32>(ptr); - ptr += sizeof(::PROTOBUF_NAMESPACE_ID::uint32); - } else goto handle_unusual; - continue; - // optional fixed32 ssrc = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 53)) { - _Internal::set_has_ssrc(&has_bits); - ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint32>(ptr); - ptr += sizeof(::PROTOBUF_NAMESPACE_ID::uint32); - } else goto handle_unusual; - continue; - // optional uint32 payload_size = 8; - case 8: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 64)) { - _Internal::set_has_payload_size(&has_bits); - payload_size_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 header_size = 9; - case 9: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 72)) { - _Internal::set_has_header_size(&has_bits); - header_size_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 padding_size = 10; - case 10: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 80)) { - _Internal::set_has_padding_size(&has_bits); - padding_size_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 11; - case 11: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 88)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 transport_sequence_number = 15; - case 15: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 120)) { - _Internal::set_has_transport_sequence_number(&has_bits); - transport_sequence_number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 transmission_time_offset = 16; - case 16: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 128)) { - _Internal::set_has_transmission_time_offset(&has_bits); - transmission_time_offset_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 absolute_send_time = 17; - case 17: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 136)) { - _Internal::set_has_absolute_send_time(&has_bits); - absolute_send_time_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 video_rotation = 18; - case 18: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 144)) { - _Internal::set_has_video_rotation(&has_bits); - video_rotation_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 audio_level = 19; - case 19: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 152)) { - _Internal::set_has_audio_level(&has_bits); - audio_level_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool voice_activity = 20; - case 20: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 160)) { - _Internal::set_has_voice_activity(&has_bits); - voice_activity_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes marker_deltas = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_marker_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes payload_type_deltas = 103; - case 103: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_payload_type_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes sequence_number_deltas = 104; - case 104: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_sequence_number_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes rtp_timestamp_deltas = 105; - case 105: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 74)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_rtp_timestamp_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes ssrc_deltas = 106; - case 106: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 82)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_ssrc_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes payload_size_deltas = 108; - case 108: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 98)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_payload_size_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes header_size_deltas = 109; - case 109: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 106)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_header_size_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes padding_size_deltas = 110; - case 110: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 114)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_padding_size_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes transport_sequence_number_deltas = 115; - case 115: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 154)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_transport_sequence_number_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes transmission_time_offset_deltas = 116; - case 116: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 162)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_transmission_time_offset_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes absolute_send_time_deltas = 117; - case 117: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 170)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_absolute_send_time_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes video_rotation_deltas = 118; - case 118: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 178)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_video_rotation_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes audio_level_deltas = 119; - case 119: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 186)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_audio_level_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes voice_activity_deltas = 120; - case 120: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 194)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_voice_activity_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool OutgoingRtpPackets::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.OutgoingRtpPackets) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool marker = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_marker(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &marker_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 payload_type = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_payload_type(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &payload_type_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 sequence_number = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_sequence_number(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &sequence_number_))); - } else { - goto handle_unusual; - } - break; - } - - // optional fixed32 rtp_timestamp = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (45 & 0xFF)) { - _Internal::set_has_rtp_timestamp(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_FIXED32>( - input, &rtp_timestamp_))); - } else { - goto handle_unusual; - } - break; - } - - // optional fixed32 ssrc = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (53 & 0xFF)) { - _Internal::set_has_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_FIXED32>( - input, &ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 payload_size = 8; - case 8: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (64 & 0xFF)) { - _Internal::set_has_payload_size(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &payload_size_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 header_size = 9; - case 9: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (72 & 0xFF)) { - _Internal::set_has_header_size(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &header_size_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 padding_size = 10; - case 10: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (80 & 0xFF)) { - _Internal::set_has_padding_size(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &padding_size_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 11; - case 11: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (88 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 transport_sequence_number = 15; - case 15: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (120 & 0xFF)) { - _Internal::set_has_transport_sequence_number(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &transport_sequence_number_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 transmission_time_offset = 16; - case 16: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (128 & 0xFF)) { - _Internal::set_has_transmission_time_offset(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &transmission_time_offset_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 absolute_send_time = 17; - case 17: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (136 & 0xFF)) { - _Internal::set_has_absolute_send_time(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &absolute_send_time_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 video_rotation = 18; - case 18: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (144 & 0xFF)) { - _Internal::set_has_video_rotation(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &video_rotation_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 audio_level = 19; - case 19: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (152 & 0xFF)) { - _Internal::set_has_audio_level(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &audio_level_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool voice_activity = 20; - case 20: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (160 & 0xFF)) { - _Internal::set_has_voice_activity(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &voice_activity_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes marker_deltas = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_marker_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes payload_type_deltas = 103; - case 103: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (826 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_payload_type_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes sequence_number_deltas = 104; - case 104: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (834 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_sequence_number_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes rtp_timestamp_deltas = 105; - case 105: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (842 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_rtp_timestamp_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes ssrc_deltas = 106; - case 106: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (850 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_ssrc_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes payload_size_deltas = 108; - case 108: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (866 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_payload_size_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes header_size_deltas = 109; - case 109: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (874 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_header_size_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes padding_size_deltas = 110; - case 110: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (882 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_padding_size_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes transport_sequence_number_deltas = 115; - case 115: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (922 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_transport_sequence_number_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes transmission_time_offset_deltas = 116; - case 116: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (930 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_transmission_time_offset_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes absolute_send_time_deltas = 117; - case 117: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (938 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_absolute_send_time_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes video_rotation_deltas = 118; - case 118: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (946 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_video_rotation_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes audio_level_deltas = 119; - case 119: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (954 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_audio_level_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes voice_activity_deltas = 120; - case 120: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (962 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_voice_activity_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.OutgoingRtpPackets) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.OutgoingRtpPackets) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void OutgoingRtpPackets::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.OutgoingRtpPackets) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00008000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional bool marker = 2; - if (cached_has_bits & 0x01000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(2, this->marker(), output); - } - - // optional uint32 payload_type = 3; - if (cached_has_bits & 0x00010000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->payload_type(), output); - } - - // optional uint32 sequence_number = 4; - if (cached_has_bits & 0x00020000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->sequence_number(), output); - } - - // optional fixed32 rtp_timestamp = 5; - if (cached_has_bits & 0x00040000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFixed32(5, this->rtp_timestamp(), output); - } - - // optional fixed32 ssrc = 6; - if (cached_has_bits & 0x00080000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFixed32(6, this->ssrc(), output); - } - - // optional uint32 payload_size = 8; - if (cached_has_bits & 0x00100000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(8, this->payload_size(), output); - } - - // optional uint32 header_size = 9; - if (cached_has_bits & 0x00200000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(9, this->header_size(), output); - } - - // optional uint32 padding_size = 10; - if (cached_has_bits & 0x00400000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(10, this->padding_size(), output); - } - - // optional uint32 number_of_deltas = 11; - if (cached_has_bits & 0x00800000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(11, this->number_of_deltas(), output); - } - - // optional uint32 transport_sequence_number = 15; - if (cached_has_bits & 0x04000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(15, this->transport_sequence_number(), output); - } - - // optional int32 transmission_time_offset = 16; - if (cached_has_bits & 0x08000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(16, this->transmission_time_offset(), output); - } - - // optional uint32 absolute_send_time = 17; - if (cached_has_bits & 0x10000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(17, this->absolute_send_time(), output); - } - - // optional uint32 video_rotation = 18; - if (cached_has_bits & 0x20000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(18, this->video_rotation(), output); - } - - // optional uint32 audio_level = 19; - if (cached_has_bits & 0x40000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(19, this->audio_level(), output); - } - - // optional bool voice_activity = 20; - if (cached_has_bits & 0x02000000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(20, this->voice_activity(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes marker_deltas = 102; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->marker_deltas(), output); - } - - // optional bytes payload_type_deltas = 103; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 103, this->payload_type_deltas(), output); - } - - // optional bytes sequence_number_deltas = 104; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 104, this->sequence_number_deltas(), output); - } - - // optional bytes rtp_timestamp_deltas = 105; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 105, this->rtp_timestamp_deltas(), output); - } - - // optional bytes ssrc_deltas = 106; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 106, this->ssrc_deltas(), output); - } - - // optional bytes payload_size_deltas = 108; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 108, this->payload_size_deltas(), output); - } - - // optional bytes header_size_deltas = 109; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 109, this->header_size_deltas(), output); - } - - // optional bytes padding_size_deltas = 110; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 110, this->padding_size_deltas(), output); - } - - // optional bytes transport_sequence_number_deltas = 115; - if (cached_has_bits & 0x00000200u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 115, this->transport_sequence_number_deltas(), output); - } - - // optional bytes transmission_time_offset_deltas = 116; - if (cached_has_bits & 0x00000400u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 116, this->transmission_time_offset_deltas(), output); - } - - // optional bytes absolute_send_time_deltas = 117; - if (cached_has_bits & 0x00000800u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 117, this->absolute_send_time_deltas(), output); - } - - // optional bytes video_rotation_deltas = 118; - if (cached_has_bits & 0x00001000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 118, this->video_rotation_deltas(), output); - } - - // optional bytes audio_level_deltas = 119; - if (cached_has_bits & 0x00002000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 119, this->audio_level_deltas(), output); - } - - // optional bytes voice_activity_deltas = 120; - if (cached_has_bits & 0x00004000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 120, this->voice_activity_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.OutgoingRtpPackets) -} - -size_t OutgoingRtpPackets::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.OutgoingRtpPackets) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes marker_deltas = 102; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->marker_deltas()); - } - - // optional bytes payload_type_deltas = 103; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->payload_type_deltas()); - } - - // optional bytes sequence_number_deltas = 104; - if (cached_has_bits & 0x00000008u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->sequence_number_deltas()); - } - - // optional bytes rtp_timestamp_deltas = 105; - if (cached_has_bits & 0x00000010u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->rtp_timestamp_deltas()); - } - - // optional bytes ssrc_deltas = 106; - if (cached_has_bits & 0x00000020u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->ssrc_deltas()); - } - - // optional bytes payload_size_deltas = 108; - if (cached_has_bits & 0x00000040u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->payload_size_deltas()); - } - - // optional bytes header_size_deltas = 109; - if (cached_has_bits & 0x00000080u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->header_size_deltas()); - } - - } - if (cached_has_bits & 0x0000ff00u) { - // optional bytes padding_size_deltas = 110; - if (cached_has_bits & 0x00000100u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->padding_size_deltas()); - } - - // optional bytes transport_sequence_number_deltas = 115; - if (cached_has_bits & 0x00000200u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->transport_sequence_number_deltas()); - } - - // optional bytes transmission_time_offset_deltas = 116; - if (cached_has_bits & 0x00000400u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->transmission_time_offset_deltas()); - } - - // optional bytes absolute_send_time_deltas = 117; - if (cached_has_bits & 0x00000800u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->absolute_send_time_deltas()); - } - - // optional bytes video_rotation_deltas = 118; - if (cached_has_bits & 0x00001000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->video_rotation_deltas()); - } - - // optional bytes audio_level_deltas = 119; - if (cached_has_bits & 0x00002000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->audio_level_deltas()); - } - - // optional bytes voice_activity_deltas = 120; - if (cached_has_bits & 0x00004000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->voice_activity_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00008000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - } - if (cached_has_bits & 0x00ff0000u) { - // optional uint32 payload_type = 3; - if (cached_has_bits & 0x00010000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->payload_type()); - } - - // optional uint32 sequence_number = 4; - if (cached_has_bits & 0x00020000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->sequence_number()); - } - - // optional fixed32 rtp_timestamp = 5; - if (cached_has_bits & 0x00040000u) { - total_size += 1 + 4; - } - - // optional fixed32 ssrc = 6; - if (cached_has_bits & 0x00080000u) { - total_size += 1 + 4; - } - - // optional uint32 payload_size = 8; - if (cached_has_bits & 0x00100000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->payload_size()); - } - - // optional uint32 header_size = 9; - if (cached_has_bits & 0x00200000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->header_size()); - } - - // optional uint32 padding_size = 10; - if (cached_has_bits & 0x00400000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->padding_size()); - } - - // optional uint32 number_of_deltas = 11; - if (cached_has_bits & 0x00800000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - if (cached_has_bits & 0x7f000000u) { - // optional bool marker = 2; - if (cached_has_bits & 0x01000000u) { - total_size += 1 + 1; - } - - // optional bool voice_activity = 20; - if (cached_has_bits & 0x02000000u) { - total_size += 2 + 1; - } - - // optional uint32 transport_sequence_number = 15; - if (cached_has_bits & 0x04000000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->transport_sequence_number()); - } - - // optional int32 transmission_time_offset = 16; - if (cached_has_bits & 0x08000000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->transmission_time_offset()); - } - - // optional uint32 absolute_send_time = 17; - if (cached_has_bits & 0x10000000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->absolute_send_time()); - } - - // optional uint32 video_rotation = 18; - if (cached_has_bits & 0x20000000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->video_rotation()); - } - - // optional uint32 audio_level = 19; - if (cached_has_bits & 0x40000000u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->audio_level()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void OutgoingRtpPackets::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void OutgoingRtpPackets::MergeFrom(const OutgoingRtpPackets& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.OutgoingRtpPackets) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - marker_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.marker_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_type_deltas_); - } - if (cached_has_bits & 0x00000008u) { - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.sequence_number_deltas_); - } - if (cached_has_bits & 0x00000010u) { - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.rtp_timestamp_deltas_); - } - if (cached_has_bits & 0x00000020u) { - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.ssrc_deltas_); - } - if (cached_has_bits & 0x00000040u) { - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.payload_size_deltas_); - } - if (cached_has_bits & 0x00000080u) { - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.header_size_deltas_); - } - } - if (cached_has_bits & 0x0000ff00u) { - if (cached_has_bits & 0x00000100u) { - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.padding_size_deltas_); - } - if (cached_has_bits & 0x00000200u) { - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.transport_sequence_number_deltas_); - } - if (cached_has_bits & 0x00000400u) { - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.transmission_time_offset_deltas_); - } - if (cached_has_bits & 0x00000800u) { - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.absolute_send_time_deltas_); - } - if (cached_has_bits & 0x00001000u) { - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.video_rotation_deltas_); - } - if (cached_has_bits & 0x00002000u) { - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.audio_level_deltas_); - } - if (cached_has_bits & 0x00004000u) { - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.voice_activity_deltas_); - } - if (cached_has_bits & 0x00008000u) { - timestamp_ms_ = from.timestamp_ms_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00ff0000u) { - if (cached_has_bits & 0x00010000u) { - payload_type_ = from.payload_type_; - } - if (cached_has_bits & 0x00020000u) { - sequence_number_ = from.sequence_number_; - } - if (cached_has_bits & 0x00040000u) { - rtp_timestamp_ = from.rtp_timestamp_; - } - if (cached_has_bits & 0x00080000u) { - ssrc_ = from.ssrc_; - } - if (cached_has_bits & 0x00100000u) { - payload_size_ = from.payload_size_; - } - if (cached_has_bits & 0x00200000u) { - header_size_ = from.header_size_; - } - if (cached_has_bits & 0x00400000u) { - padding_size_ = from.padding_size_; - } - if (cached_has_bits & 0x00800000u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x7f000000u) { - if (cached_has_bits & 0x01000000u) { - marker_ = from.marker_; - } - if (cached_has_bits & 0x02000000u) { - voice_activity_ = from.voice_activity_; - } - if (cached_has_bits & 0x04000000u) { - transport_sequence_number_ = from.transport_sequence_number_; - } - if (cached_has_bits & 0x08000000u) { - transmission_time_offset_ = from.transmission_time_offset_; - } - if (cached_has_bits & 0x10000000u) { - absolute_send_time_ = from.absolute_send_time_; - } - if (cached_has_bits & 0x20000000u) { - video_rotation_ = from.video_rotation_; - } - if (cached_has_bits & 0x40000000u) { - audio_level_ = from.audio_level_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void OutgoingRtpPackets::CopyFrom(const OutgoingRtpPackets& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.OutgoingRtpPackets) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool OutgoingRtpPackets::IsInitialized() const { - return true; -} - -void OutgoingRtpPackets::InternalSwap(OutgoingRtpPackets* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - marker_deltas_.Swap(&other->marker_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - payload_type_deltas_.Swap(&other->payload_type_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - sequence_number_deltas_.Swap(&other->sequence_number_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - rtp_timestamp_deltas_.Swap(&other->rtp_timestamp_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - ssrc_deltas_.Swap(&other->ssrc_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - payload_size_deltas_.Swap(&other->payload_size_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - header_size_deltas_.Swap(&other->header_size_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - padding_size_deltas_.Swap(&other->padding_size_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - transport_sequence_number_deltas_.Swap(&other->transport_sequence_number_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - transmission_time_offset_deltas_.Swap(&other->transmission_time_offset_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - absolute_send_time_deltas_.Swap(&other->absolute_send_time_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - video_rotation_deltas_.Swap(&other->video_rotation_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - audio_level_deltas_.Swap(&other->audio_level_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - voice_activity_deltas_.Swap(&other->voice_activity_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(payload_type_, other->payload_type_); - swap(sequence_number_, other->sequence_number_); - swap(rtp_timestamp_, other->rtp_timestamp_); - swap(ssrc_, other->ssrc_); - swap(payload_size_, other->payload_size_); - swap(header_size_, other->header_size_); - swap(padding_size_, other->padding_size_); - swap(number_of_deltas_, other->number_of_deltas_); - swap(marker_, other->marker_); - swap(voice_activity_, other->voice_activity_); - swap(transport_sequence_number_, other->transport_sequence_number_); - swap(transmission_time_offset_, other->transmission_time_offset_); - swap(absolute_send_time_, other->absolute_send_time_); - swap(video_rotation_, other->video_rotation_); - swap(audio_level_, other->audio_level_); -} - -std::string OutgoingRtpPackets::GetTypeName() const { - return "webrtc.rtclog2.OutgoingRtpPackets"; -} - - -// =================================================================== - -void IncomingRtcpPackets::InitAsDefaultInstance() { -} -class IncomingRtcpPackets::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_raw_packet(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_raw_packet_blobs(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -IncomingRtcpPackets::IncomingRtcpPackets() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.IncomingRtcpPackets) -} -IncomingRtcpPackets::IncomingRtcpPackets(const IncomingRtcpPackets& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - raw_packet_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_raw_packet()) { - raw_packet_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.raw_packet_); - } - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - raw_packet_blobs_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_raw_packet_blobs()) { - raw_packet_blobs_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.raw_packet_blobs_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.IncomingRtcpPackets) -} - -void IncomingRtcpPackets::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_IncomingRtcpPackets_rtc_5fevent_5flog2_2eproto.base); - raw_packet_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - raw_packet_blobs_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -IncomingRtcpPackets::~IncomingRtcpPackets() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.IncomingRtcpPackets) - SharedDtor(); -} - -void IncomingRtcpPackets::SharedDtor() { - raw_packet_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - raw_packet_blobs_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void IncomingRtcpPackets::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const IncomingRtcpPackets& IncomingRtcpPackets::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_IncomingRtcpPackets_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void IncomingRtcpPackets::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.IncomingRtcpPackets) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - raw_packet_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - raw_packet_blobs_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x00000018u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* IncomingRtcpPackets::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes raw_packet = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_raw_packet(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes raw_packet_blobs = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_raw_packet_blobs(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool IncomingRtcpPackets::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.IncomingRtcpPackets) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes raw_packet = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (18 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_raw_packet())); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes raw_packet_blobs = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_raw_packet_blobs())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.IncomingRtcpPackets) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.IncomingRtcpPackets) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void IncomingRtcpPackets::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.IncomingRtcpPackets) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional bytes raw_packet = 2; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 2, this->raw_packet(), output); - } - - // optional uint32 number_of_deltas = 3; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes raw_packet_blobs = 102; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->raw_packet_blobs(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.IncomingRtcpPackets) -} - -size_t IncomingRtcpPackets::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.IncomingRtcpPackets) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional bytes raw_packet = 2; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->raw_packet()); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes raw_packet_blobs = 102; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->raw_packet_blobs()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 number_of_deltas = 3; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void IncomingRtcpPackets::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void IncomingRtcpPackets::MergeFrom(const IncomingRtcpPackets& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.IncomingRtcpPackets) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - raw_packet_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.raw_packet_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.raw_packet_blobs_); - } - if (cached_has_bits & 0x00000008u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000010u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void IncomingRtcpPackets::CopyFrom(const IncomingRtcpPackets& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.IncomingRtcpPackets) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool IncomingRtcpPackets::IsInitialized() const { - return true; -} - -void IncomingRtcpPackets::InternalSwap(IncomingRtcpPackets* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - raw_packet_.Swap(&other->raw_packet_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - raw_packet_blobs_.Swap(&other->raw_packet_blobs_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string IncomingRtcpPackets::GetTypeName() const { - return "webrtc.rtclog2.IncomingRtcpPackets"; -} - - -// =================================================================== - -void OutgoingRtcpPackets::InitAsDefaultInstance() { -} -class OutgoingRtcpPackets::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_raw_packet(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_raw_packet_blobs(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -OutgoingRtcpPackets::OutgoingRtcpPackets() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.OutgoingRtcpPackets) -} -OutgoingRtcpPackets::OutgoingRtcpPackets(const OutgoingRtcpPackets& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - raw_packet_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_raw_packet()) { - raw_packet_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.raw_packet_); - } - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - raw_packet_blobs_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_raw_packet_blobs()) { - raw_packet_blobs_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.raw_packet_blobs_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.OutgoingRtcpPackets) -} - -void OutgoingRtcpPackets::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_OutgoingRtcpPackets_rtc_5fevent_5flog2_2eproto.base); - raw_packet_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - raw_packet_blobs_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -OutgoingRtcpPackets::~OutgoingRtcpPackets() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.OutgoingRtcpPackets) - SharedDtor(); -} - -void OutgoingRtcpPackets::SharedDtor() { - raw_packet_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - raw_packet_blobs_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void OutgoingRtcpPackets::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const OutgoingRtcpPackets& OutgoingRtcpPackets::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_OutgoingRtcpPackets_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void OutgoingRtcpPackets::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.OutgoingRtcpPackets) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - raw_packet_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - raw_packet_blobs_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x00000018u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* OutgoingRtcpPackets::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes raw_packet = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_raw_packet(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes raw_packet_blobs = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_raw_packet_blobs(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool OutgoingRtcpPackets::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.OutgoingRtcpPackets) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes raw_packet = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (18 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_raw_packet())); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes raw_packet_blobs = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_raw_packet_blobs())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.OutgoingRtcpPackets) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.OutgoingRtcpPackets) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void OutgoingRtcpPackets::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.OutgoingRtcpPackets) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional bytes raw_packet = 2; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 2, this->raw_packet(), output); - } - - // optional uint32 number_of_deltas = 3; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes raw_packet_blobs = 102; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->raw_packet_blobs(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.OutgoingRtcpPackets) -} - -size_t OutgoingRtcpPackets::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.OutgoingRtcpPackets) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional bytes raw_packet = 2; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->raw_packet()); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes raw_packet_blobs = 102; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->raw_packet_blobs()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 number_of_deltas = 3; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void OutgoingRtcpPackets::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void OutgoingRtcpPackets::MergeFrom(const OutgoingRtcpPackets& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.OutgoingRtcpPackets) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - raw_packet_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.raw_packet_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.raw_packet_blobs_); - } - if (cached_has_bits & 0x00000008u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000010u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void OutgoingRtcpPackets::CopyFrom(const OutgoingRtcpPackets& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.OutgoingRtcpPackets) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool OutgoingRtcpPackets::IsInitialized() const { - return true; -} - -void OutgoingRtcpPackets::InternalSwap(OutgoingRtcpPackets* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - raw_packet_.Swap(&other->raw_packet_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - raw_packet_blobs_.Swap(&other->raw_packet_blobs_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string OutgoingRtcpPackets::GetTypeName() const { - return "webrtc.rtclog2.OutgoingRtcpPackets"; -} - - -// =================================================================== - -void AudioPlayoutEvents::InitAsDefaultInstance() { -} -class AudioPlayoutEvents::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_local_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_local_ssrc_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -AudioPlayoutEvents::AudioPlayoutEvents() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.AudioPlayoutEvents) -} -AudioPlayoutEvents::AudioPlayoutEvents(const AudioPlayoutEvents& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - local_ssrc_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_local_ssrc_deltas()) { - local_ssrc_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.local_ssrc_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.AudioPlayoutEvents) -} - -void AudioPlayoutEvents::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_AudioPlayoutEvents_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - local_ssrc_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -AudioPlayoutEvents::~AudioPlayoutEvents() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.AudioPlayoutEvents) - SharedDtor(); -} - -void AudioPlayoutEvents::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - local_ssrc_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void AudioPlayoutEvents::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AudioPlayoutEvents& AudioPlayoutEvents::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AudioPlayoutEvents_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void AudioPlayoutEvents::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.AudioPlayoutEvents) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - local_ssrc_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x0000001cu) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AudioPlayoutEvents::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 local_ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_local_ssrc(&has_bits); - local_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes local_ssrc_deltas = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_local_ssrc_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AudioPlayoutEvents::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.AudioPlayoutEvents) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 local_ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_local_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &local_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes local_ssrc_deltas = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_local_ssrc_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.AudioPlayoutEvents) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.AudioPlayoutEvents) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AudioPlayoutEvents::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.AudioPlayoutEvents) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 local_ssrc = 2; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->local_ssrc(), output); - } - - // optional uint32 number_of_deltas = 3; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes local_ssrc_deltas = 102; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->local_ssrc_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.AudioPlayoutEvents) -} - -size_t AudioPlayoutEvents::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.AudioPlayoutEvents) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes local_ssrc_deltas = 102; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->local_ssrc_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 local_ssrc = 2; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->local_ssrc()); - } - - // optional uint32 number_of_deltas = 3; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AudioPlayoutEvents::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AudioPlayoutEvents::MergeFrom(const AudioPlayoutEvents& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.AudioPlayoutEvents) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - local_ssrc_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.local_ssrc_deltas_); - } - if (cached_has_bits & 0x00000004u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000008u) { - local_ssrc_ = from.local_ssrc_; - } - if (cached_has_bits & 0x00000010u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void AudioPlayoutEvents::CopyFrom(const AudioPlayoutEvents& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.AudioPlayoutEvents) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AudioPlayoutEvents::IsInitialized() const { - return true; -} - -void AudioPlayoutEvents::InternalSwap(AudioPlayoutEvents* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - local_ssrc_deltas_.Swap(&other->local_ssrc_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(local_ssrc_, other->local_ssrc_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string AudioPlayoutEvents::GetTypeName() const { - return "webrtc.rtclog2.AudioPlayoutEvents"; -} - - -// =================================================================== - -void FrameDecodedEvents::InitAsDefaultInstance() { -} -class FrameDecodedEvents::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } - static void set_has_render_time_ms(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_width(HasBits* has_bits) { - (*has_bits)[0] |= 1024u; - } - static void set_has_height(HasBits* has_bits) { - (*has_bits)[0] |= 2048u; - } - static void set_has_codec(HasBits* has_bits) { - (*has_bits)[0] |= 4096u; - } - static void set_has_qp(HasBits* has_bits) { - (*has_bits)[0] |= 8192u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16384u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_ssrc_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_render_time_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_width_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_height_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_codec_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_qp_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } -}; - -FrameDecodedEvents::FrameDecodedEvents() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.FrameDecodedEvents) -} -FrameDecodedEvents::FrameDecodedEvents(const FrameDecodedEvents& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - ssrc_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_ssrc_deltas()) { - ssrc_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.ssrc_deltas_); - } - render_time_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_render_time_ms_deltas()) { - render_time_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.render_time_ms_deltas_); - } - width_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_width_deltas()) { - width_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.width_deltas_); - } - height_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_height_deltas()) { - height_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.height_deltas_); - } - codec_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_codec_deltas()) { - codec_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.codec_deltas_); - } - qp_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_qp_deltas()) { - qp_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.qp_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.FrameDecodedEvents) -} - -void FrameDecodedEvents::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_FrameDecodedEvents_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ssrc_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - render_time_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - width_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - height_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - codec_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - qp_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -FrameDecodedEvents::~FrameDecodedEvents() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.FrameDecodedEvents) - SharedDtor(); -} - -void FrameDecodedEvents::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ssrc_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - render_time_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - width_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - height_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - codec_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - qp_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void FrameDecodedEvents::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const FrameDecodedEvents& FrameDecodedEvents::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_FrameDecodedEvents_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void FrameDecodedEvents::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.FrameDecodedEvents) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000007fu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - ssrc_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - render_time_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000008u) { - width_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000010u) { - height_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000020u) { - codec_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000040u) { - qp_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - timestamp_ms_ = PROTOBUF_LONGLONG(0); - if (cached_has_bits & 0x00007f00u) { - ::memset(&render_time_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(&render_time_ms_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* FrameDecodedEvents::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional fixed32 ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 21)) { - _Internal::set_has_ssrc(&has_bits); - ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<::PROTOBUF_NAMESPACE_ID::uint32>(ptr); - ptr += sizeof(::PROTOBUF_NAMESPACE_ID::uint32); - } else goto handle_unusual; - continue; - // optional int64 render_time_ms = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_render_time_ms(&has_bits); - render_time_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 width = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_width(&has_bits); - width_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 height = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - _Internal::set_has_height(&has_bits); - height_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.FrameDecodedEvents.Codec codec = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 48)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::FrameDecodedEvents_Codec_IsValid(val))) { - set_codec(static_cast<::webrtc::rtclog2::FrameDecodedEvents_Codec>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(6, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional uint32 qp = 7; - case 7: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 56)) { - _Internal::set_has_qp(&has_bits); - qp_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 15; - case 15: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 120)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes ssrc_deltas = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_ssrc_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes render_time_ms_deltas = 103; - case 103: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_render_time_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes width_deltas = 104; - case 104: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_width_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes height_deltas = 105; - case 105: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 74)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_height_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes codec_deltas = 106; - case 106: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 82)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_codec_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes qp_deltas = 107; - case 107: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 90)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_qp_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool FrameDecodedEvents::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.FrameDecodedEvents) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional fixed32 ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (21 & 0xFF)) { - _Internal::set_has_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_FIXED32>( - input, &ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int64 render_time_ms = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_render_time_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, &render_time_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 width = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_width(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &width_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 height = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - _Internal::set_has_height(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &height_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.FrameDecodedEvents.Codec codec = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (48 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::FrameDecodedEvents_Codec_IsValid(value)) { - set_codec(static_cast< ::webrtc::rtclog2::FrameDecodedEvents_Codec >(value)); - } else { - unknown_fields_stream.WriteVarint32(48u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 qp = 7; - case 7: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (56 & 0xFF)) { - _Internal::set_has_qp(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &qp_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 15; - case 15: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (120 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes ssrc_deltas = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_ssrc_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes render_time_ms_deltas = 103; - case 103: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (826 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_render_time_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes width_deltas = 104; - case 104: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (834 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_width_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes height_deltas = 105; - case 105: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (842 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_height_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes codec_deltas = 106; - case 106: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (850 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_codec_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes qp_deltas = 107; - case 107: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (858 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_qp_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.FrameDecodedEvents) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.FrameDecodedEvents) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void FrameDecodedEvents::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.FrameDecodedEvents) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional fixed32 ssrc = 2; - if (cached_has_bits & 0x00000200u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFixed32(2, this->ssrc(), output); - } - - // optional int64 render_time_ms = 3; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(3, this->render_time_ms(), output); - } - - // optional int32 width = 4; - if (cached_has_bits & 0x00000400u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(4, this->width(), output); - } - - // optional int32 height = 5; - if (cached_has_bits & 0x00000800u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(5, this->height(), output); - } - - // optional .webrtc.rtclog2.FrameDecodedEvents.Codec codec = 6; - if (cached_has_bits & 0x00001000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 6, this->codec(), output); - } - - // optional uint32 qp = 7; - if (cached_has_bits & 0x00002000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(7, this->qp(), output); - } - - // optional uint32 number_of_deltas = 15; - if (cached_has_bits & 0x00004000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(15, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes ssrc_deltas = 102; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->ssrc_deltas(), output); - } - - // optional bytes render_time_ms_deltas = 103; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 103, this->render_time_ms_deltas(), output); - } - - // optional bytes width_deltas = 104; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 104, this->width_deltas(), output); - } - - // optional bytes height_deltas = 105; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 105, this->height_deltas(), output); - } - - // optional bytes codec_deltas = 106; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 106, this->codec_deltas(), output); - } - - // optional bytes qp_deltas = 107; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 107, this->qp_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.FrameDecodedEvents) -} - -size_t FrameDecodedEvents::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.FrameDecodedEvents) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes ssrc_deltas = 102; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->ssrc_deltas()); - } - - // optional bytes render_time_ms_deltas = 103; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->render_time_ms_deltas()); - } - - // optional bytes width_deltas = 104; - if (cached_has_bits & 0x00000008u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->width_deltas()); - } - - // optional bytes height_deltas = 105; - if (cached_has_bits & 0x00000010u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->height_deltas()); - } - - // optional bytes codec_deltas = 106; - if (cached_has_bits & 0x00000020u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->codec_deltas()); - } - - // optional bytes qp_deltas = 107; - if (cached_has_bits & 0x00000040u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->qp_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000080u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - } - if (cached_has_bits & 0x00007f00u) { - // optional int64 render_time_ms = 3; - if (cached_has_bits & 0x00000100u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->render_time_ms()); - } - - // optional fixed32 ssrc = 2; - if (cached_has_bits & 0x00000200u) { - total_size += 1 + 4; - } - - // optional int32 width = 4; - if (cached_has_bits & 0x00000400u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->width()); - } - - // optional int32 height = 5; - if (cached_has_bits & 0x00000800u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->height()); - } - - // optional .webrtc.rtclog2.FrameDecodedEvents.Codec codec = 6; - if (cached_has_bits & 0x00001000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->codec()); - } - - // optional uint32 qp = 7; - if (cached_has_bits & 0x00002000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->qp()); - } - - // optional uint32 number_of_deltas = 15; - if (cached_has_bits & 0x00004000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void FrameDecodedEvents::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void FrameDecodedEvents::MergeFrom(const FrameDecodedEvents& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.FrameDecodedEvents) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - ssrc_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.ssrc_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - render_time_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.render_time_ms_deltas_); - } - if (cached_has_bits & 0x00000008u) { - _has_bits_[0] |= 0x00000008u; - width_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.width_deltas_); - } - if (cached_has_bits & 0x00000010u) { - _has_bits_[0] |= 0x00000010u; - height_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.height_deltas_); - } - if (cached_has_bits & 0x00000020u) { - _has_bits_[0] |= 0x00000020u; - codec_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.codec_deltas_); - } - if (cached_has_bits & 0x00000040u) { - _has_bits_[0] |= 0x00000040u; - qp_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.qp_deltas_); - } - if (cached_has_bits & 0x00000080u) { - timestamp_ms_ = from.timestamp_ms_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00007f00u) { - if (cached_has_bits & 0x00000100u) { - render_time_ms_ = from.render_time_ms_; - } - if (cached_has_bits & 0x00000200u) { - ssrc_ = from.ssrc_; - } - if (cached_has_bits & 0x00000400u) { - width_ = from.width_; - } - if (cached_has_bits & 0x00000800u) { - height_ = from.height_; - } - if (cached_has_bits & 0x00001000u) { - codec_ = from.codec_; - } - if (cached_has_bits & 0x00002000u) { - qp_ = from.qp_; - } - if (cached_has_bits & 0x00004000u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void FrameDecodedEvents::CopyFrom(const FrameDecodedEvents& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.FrameDecodedEvents) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FrameDecodedEvents::IsInitialized() const { - return true; -} - -void FrameDecodedEvents::InternalSwap(FrameDecodedEvents* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - ssrc_deltas_.Swap(&other->ssrc_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - render_time_ms_deltas_.Swap(&other->render_time_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - width_deltas_.Swap(&other->width_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - height_deltas_.Swap(&other->height_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - codec_deltas_.Swap(&other->codec_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - qp_deltas_.Swap(&other->qp_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(render_time_ms_, other->render_time_ms_); - swap(ssrc_, other->ssrc_); - swap(width_, other->width_); - swap(height_, other->height_); - swap(codec_, other->codec_); - swap(qp_, other->qp_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string FrameDecodedEvents::GetTypeName() const { - return "webrtc.rtclog2.FrameDecodedEvents"; -} - - -// =================================================================== - -void BeginLogEvent::InitAsDefaultInstance() { -} -class BeginLogEvent::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_version(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_utc_time_ms(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -BeginLogEvent::BeginLogEvent() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.BeginLogEvent) -} -BeginLogEvent::BeginLogEvent(const BeginLogEvent& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&version_) - - reinterpret_cast(×tamp_ms_)) + sizeof(version_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.BeginLogEvent) -} - -void BeginLogEvent::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&version_) - - reinterpret_cast(×tamp_ms_)) + sizeof(version_)); -} - -BeginLogEvent::~BeginLogEvent() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.BeginLogEvent) - SharedDtor(); -} - -void BeginLogEvent::SharedDtor() { -} - -void BeginLogEvent::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const BeginLogEvent& BeginLogEvent::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_BeginLogEvent_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void BeginLogEvent::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.BeginLogEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&version_) - - reinterpret_cast(×tamp_ms_)) + sizeof(version_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* BeginLogEvent::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 version = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_version(&has_bits); - version_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int64 utc_time_ms = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_utc_time_ms(&has_bits); - utc_time_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool BeginLogEvent::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.BeginLogEvent) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 version = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_version(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &version_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int64 utc_time_ms = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_utc_time_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, &utc_time_ms_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.BeginLogEvent) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.BeginLogEvent) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void BeginLogEvent::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.BeginLogEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 version = 2; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->version(), output); - } - - // optional int64 utc_time_ms = 3; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(3, this->utc_time_ms(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.BeginLogEvent) -} - -size_t BeginLogEvent::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.BeginLogEvent) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional int64 utc_time_ms = 3; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->utc_time_ms()); - } - - // optional uint32 version = 2; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->version()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void BeginLogEvent::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void BeginLogEvent::MergeFrom(const BeginLogEvent& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.BeginLogEvent) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - utc_time_ms_ = from.utc_time_ms_; - } - if (cached_has_bits & 0x00000004u) { - version_ = from.version_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void BeginLogEvent::CopyFrom(const BeginLogEvent& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.BeginLogEvent) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool BeginLogEvent::IsInitialized() const { - return true; -} - -void BeginLogEvent::InternalSwap(BeginLogEvent* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(utc_time_ms_, other->utc_time_ms_); - swap(version_, other->version_); -} - -std::string BeginLogEvent::GetTypeName() const { - return "webrtc.rtclog2.BeginLogEvent"; -} - - -// =================================================================== - -void EndLogEvent::InitAsDefaultInstance() { -} -class EndLogEvent::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -EndLogEvent::EndLogEvent() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.EndLogEvent) -} -EndLogEvent::EndLogEvent(const EndLogEvent& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_ = from.timestamp_ms_; - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.EndLogEvent) -} - -void EndLogEvent::SharedCtor() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); -} - -EndLogEvent::~EndLogEvent() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.EndLogEvent) - SharedDtor(); -} - -void EndLogEvent::SharedDtor() { -} - -void EndLogEvent::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const EndLogEvent& EndLogEvent::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_EndLogEvent_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void EndLogEvent::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.EndLogEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* EndLogEvent::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool EndLogEvent::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.EndLogEvent) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.EndLogEvent) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.EndLogEvent) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void EndLogEvent::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.EndLogEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.EndLogEvent) -} - -size_t EndLogEvent::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.EndLogEvent) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - // optional int64 timestamp_ms = 1; - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void EndLogEvent::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void EndLogEvent::MergeFrom(const EndLogEvent& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.EndLogEvent) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - if (from.has_timestamp_ms()) { - set_timestamp_ms(from.timestamp_ms()); - } -} - -void EndLogEvent::CopyFrom(const EndLogEvent& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.EndLogEvent) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EndLogEvent::IsInitialized() const { - return true; -} - -void EndLogEvent::InternalSwap(EndLogEvent* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); -} - -std::string EndLogEvent::GetTypeName() const { - return "webrtc.rtclog2.EndLogEvent"; -} - - -// =================================================================== - -void LossBasedBweUpdates::InitAsDefaultInstance() { -} -class LossBasedBweUpdates::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_fraction_loss(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_total_packets(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_bitrate_bps_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_fraction_loss_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_total_packets_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } -}; - -LossBasedBweUpdates::LossBasedBweUpdates() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.LossBasedBweUpdates) -} -LossBasedBweUpdates::LossBasedBweUpdates(const LossBasedBweUpdates& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - bitrate_bps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_bitrate_bps_deltas()) { - bitrate_bps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.bitrate_bps_deltas_); - } - fraction_loss_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_fraction_loss_deltas()) { - fraction_loss_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.fraction_loss_deltas_); - } - total_packets_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_total_packets_deltas()) { - total_packets_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.total_packets_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.LossBasedBweUpdates) -} - -void LossBasedBweUpdates::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_LossBasedBweUpdates_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - bitrate_bps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - fraction_loss_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - total_packets_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -LossBasedBweUpdates::~LossBasedBweUpdates() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.LossBasedBweUpdates) - SharedDtor(); -} - -void LossBasedBweUpdates::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - bitrate_bps_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - fraction_loss_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - total_packets_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void LossBasedBweUpdates::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const LossBasedBweUpdates& LossBasedBweUpdates::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_LossBasedBweUpdates_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void LossBasedBweUpdates::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.LossBasedBweUpdates) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - bitrate_bps_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - fraction_loss_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000008u) { - total_packets_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x000000f0u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&total_packets_) - - reinterpret_cast(×tamp_ms_)) + sizeof(total_packets_)); - } - number_of_deltas_ = 0u; - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* LossBasedBweUpdates::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 bitrate_bps = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 fraction_loss = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_fraction_loss(&has_bits); - fraction_loss_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 total_packets = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_total_packets(&has_bits); - total_packets_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes bitrate_bps_deltas = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_bitrate_bps_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes fraction_loss_deltas = 103; - case 103: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_fraction_loss_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes total_packets_deltas = 104; - case 104: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_total_packets_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool LossBasedBweUpdates::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.LossBasedBweUpdates) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 bitrate_bps = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 fraction_loss = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_fraction_loss(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &fraction_loss_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 total_packets = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_total_packets(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &total_packets_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes bitrate_bps_deltas = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_bitrate_bps_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes fraction_loss_deltas = 103; - case 103: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (826 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_fraction_loss_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes total_packets_deltas = 104; - case 104: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (834 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_total_packets_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.LossBasedBweUpdates) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.LossBasedBweUpdates) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void LossBasedBweUpdates::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.LossBasedBweUpdates) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 bitrate_bps = 2; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->bitrate_bps(), output); - } - - // optional uint32 fraction_loss = 3; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->fraction_loss(), output); - } - - // optional uint32 total_packets = 4; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->total_packets(), output); - } - - // optional uint32 number_of_deltas = 5; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(5, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes bitrate_bps_deltas = 102; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->bitrate_bps_deltas(), output); - } - - // optional bytes fraction_loss_deltas = 103; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 103, this->fraction_loss_deltas(), output); - } - - // optional bytes total_packets_deltas = 104; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 104, this->total_packets_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.LossBasedBweUpdates) -} - -size_t LossBasedBweUpdates::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.LossBasedBweUpdates) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes bitrate_bps_deltas = 102; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->bitrate_bps_deltas()); - } - - // optional bytes fraction_loss_deltas = 103; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->fraction_loss_deltas()); - } - - // optional bytes total_packets_deltas = 104; - if (cached_has_bits & 0x00000008u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->total_packets_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 bitrate_bps = 2; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->bitrate_bps()); - } - - // optional uint32 fraction_loss = 3; - if (cached_has_bits & 0x00000040u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->fraction_loss()); - } - - // optional uint32 total_packets = 4; - if (cached_has_bits & 0x00000080u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->total_packets()); - } - - } - // optional uint32 number_of_deltas = 5; - if (cached_has_bits & 0x00000100u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void LossBasedBweUpdates::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void LossBasedBweUpdates::MergeFrom(const LossBasedBweUpdates& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.LossBasedBweUpdates) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.bitrate_bps_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - fraction_loss_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.fraction_loss_deltas_); - } - if (cached_has_bits & 0x00000008u) { - _has_bits_[0] |= 0x00000008u; - total_packets_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.total_packets_deltas_); - } - if (cached_has_bits & 0x00000010u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000020u) { - bitrate_bps_ = from.bitrate_bps_; - } - if (cached_has_bits & 0x00000040u) { - fraction_loss_ = from.fraction_loss_; - } - if (cached_has_bits & 0x00000080u) { - total_packets_ = from.total_packets_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00000100u) { - set_number_of_deltas(from.number_of_deltas()); - } -} - -void LossBasedBweUpdates::CopyFrom(const LossBasedBweUpdates& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.LossBasedBweUpdates) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool LossBasedBweUpdates::IsInitialized() const { - return true; -} - -void LossBasedBweUpdates::InternalSwap(LossBasedBweUpdates* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - bitrate_bps_deltas_.Swap(&other->bitrate_bps_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - fraction_loss_deltas_.Swap(&other->fraction_loss_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - total_packets_deltas_.Swap(&other->total_packets_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(bitrate_bps_, other->bitrate_bps_); - swap(fraction_loss_, other->fraction_loss_); - swap(total_packets_, other->total_packets_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string LossBasedBweUpdates::GetTypeName() const { - return "webrtc.rtclog2.LossBasedBweUpdates"; -} - - -// =================================================================== - -void DelayBasedBweUpdates::InitAsDefaultInstance() { -} -class DelayBasedBweUpdates::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_detector_state(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_bitrate_bps_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_detector_state_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -DelayBasedBweUpdates::DelayBasedBweUpdates() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.DelayBasedBweUpdates) -} -DelayBasedBweUpdates::DelayBasedBweUpdates(const DelayBasedBweUpdates& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - bitrate_bps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_bitrate_bps_deltas()) { - bitrate_bps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.bitrate_bps_deltas_); - } - detector_state_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_detector_state_deltas()) { - detector_state_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.detector_state_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.DelayBasedBweUpdates) -} - -void DelayBasedBweUpdates::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_DelayBasedBweUpdates_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - bitrate_bps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - detector_state_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -DelayBasedBweUpdates::~DelayBasedBweUpdates() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.DelayBasedBweUpdates) - SharedDtor(); -} - -void DelayBasedBweUpdates::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - bitrate_bps_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - detector_state_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void DelayBasedBweUpdates::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const DelayBasedBweUpdates& DelayBasedBweUpdates::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_DelayBasedBweUpdates_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void DelayBasedBweUpdates::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.DelayBasedBweUpdates) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - bitrate_bps_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - detector_state_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x00000078u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* DelayBasedBweUpdates::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 bitrate_bps = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.DelayBasedBweUpdates.DetectorState detector_state = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState_IsValid(val))) { - set_detector_state(static_cast<::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(3, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes bitrate_bps_deltas = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_bitrate_bps_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes detector_state_deltas = 103; - case 103: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_detector_state_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool DelayBasedBweUpdates::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.DelayBasedBweUpdates) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 bitrate_bps = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.DelayBasedBweUpdates.DetectorState detector_state = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState_IsValid(value)) { - set_detector_state(static_cast< ::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState >(value)); - } else { - unknown_fields_stream.WriteVarint32(24u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes bitrate_bps_deltas = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_bitrate_bps_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes detector_state_deltas = 103; - case 103: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (826 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_detector_state_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.DelayBasedBweUpdates) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.DelayBasedBweUpdates) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void DelayBasedBweUpdates::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.DelayBasedBweUpdates) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 bitrate_bps = 2; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->bitrate_bps(), output); - } - - // optional .webrtc.rtclog2.DelayBasedBweUpdates.DetectorState detector_state = 3; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 3, this->detector_state(), output); - } - - // optional uint32 number_of_deltas = 4; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes bitrate_bps_deltas = 102; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->bitrate_bps_deltas(), output); - } - - // optional bytes detector_state_deltas = 103; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 103, this->detector_state_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.DelayBasedBweUpdates) -} - -size_t DelayBasedBweUpdates::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.DelayBasedBweUpdates) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000007fu) { - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes bitrate_bps_deltas = 102; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->bitrate_bps_deltas()); - } - - // optional bytes detector_state_deltas = 103; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->detector_state_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 bitrate_bps = 2; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->bitrate_bps()); - } - - // optional .webrtc.rtclog2.DelayBasedBweUpdates.DetectorState detector_state = 3; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->detector_state()); - } - - // optional uint32 number_of_deltas = 4; - if (cached_has_bits & 0x00000040u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void DelayBasedBweUpdates::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void DelayBasedBweUpdates::MergeFrom(const DelayBasedBweUpdates& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.DelayBasedBweUpdates) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000007fu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.bitrate_bps_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - detector_state_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.detector_state_deltas_); - } - if (cached_has_bits & 0x00000008u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000010u) { - bitrate_bps_ = from.bitrate_bps_; - } - if (cached_has_bits & 0x00000020u) { - detector_state_ = from.detector_state_; - } - if (cached_has_bits & 0x00000040u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void DelayBasedBweUpdates::CopyFrom(const DelayBasedBweUpdates& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.DelayBasedBweUpdates) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DelayBasedBweUpdates::IsInitialized() const { - return true; -} - -void DelayBasedBweUpdates::InternalSwap(DelayBasedBweUpdates* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - bitrate_bps_deltas_.Swap(&other->bitrate_bps_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - detector_state_deltas_.Swap(&other->detector_state_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(bitrate_bps_, other->bitrate_bps_); - swap(detector_state_, other->detector_state_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string DelayBasedBweUpdates::GetTypeName() const { - return "webrtc.rtclog2.DelayBasedBweUpdates"; -} - - -// =================================================================== - -void RtpHeaderExtensionConfig::InitAsDefaultInstance() { -} -class RtpHeaderExtensionConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_transmission_time_offset_id(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_absolute_send_time_id(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_transport_sequence_number_id(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_video_rotation_id(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_audio_level_id(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } -}; - -RtpHeaderExtensionConfig::RtpHeaderExtensionConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.RtpHeaderExtensionConfig) -} -RtpHeaderExtensionConfig::RtpHeaderExtensionConfig(const RtpHeaderExtensionConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&transmission_time_offset_id_, &from.transmission_time_offset_id_, - static_cast(reinterpret_cast(&audio_level_id_) - - reinterpret_cast(&transmission_time_offset_id_)) + sizeof(audio_level_id_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.RtpHeaderExtensionConfig) -} - -void RtpHeaderExtensionConfig::SharedCtor() { - ::memset(&transmission_time_offset_id_, 0, static_cast( - reinterpret_cast(&audio_level_id_) - - reinterpret_cast(&transmission_time_offset_id_)) + sizeof(audio_level_id_)); -} - -RtpHeaderExtensionConfig::~RtpHeaderExtensionConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.RtpHeaderExtensionConfig) - SharedDtor(); -} - -void RtpHeaderExtensionConfig::SharedDtor() { -} - -void RtpHeaderExtensionConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const RtpHeaderExtensionConfig& RtpHeaderExtensionConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_RtpHeaderExtensionConfig_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void RtpHeaderExtensionConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.RtpHeaderExtensionConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - ::memset(&transmission_time_offset_id_, 0, static_cast( - reinterpret_cast(&audio_level_id_) - - reinterpret_cast(&transmission_time_offset_id_)) + sizeof(audio_level_id_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* RtpHeaderExtensionConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int32 transmission_time_offset_id = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_transmission_time_offset_id(&has_bits); - transmission_time_offset_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 absolute_send_time_id = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_absolute_send_time_id(&has_bits); - absolute_send_time_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 transport_sequence_number_id = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_transport_sequence_number_id(&has_bits); - transport_sequence_number_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 video_rotation_id = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_video_rotation_id(&has_bits); - video_rotation_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 audio_level_id = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - _Internal::set_has_audio_level_id(&has_bits); - audio_level_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool RtpHeaderExtensionConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.RtpHeaderExtensionConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int32 transmission_time_offset_id = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_transmission_time_offset_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &transmission_time_offset_id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 absolute_send_time_id = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_absolute_send_time_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &absolute_send_time_id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 transport_sequence_number_id = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_transport_sequence_number_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &transport_sequence_number_id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 video_rotation_id = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_video_rotation_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &video_rotation_id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 audio_level_id = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - _Internal::set_has_audio_level_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &audio_level_id_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.RtpHeaderExtensionConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.RtpHeaderExtensionConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void RtpHeaderExtensionConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.RtpHeaderExtensionConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int32 transmission_time_offset_id = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(1, this->transmission_time_offset_id(), output); - } - - // optional int32 absolute_send_time_id = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->absolute_send_time_id(), output); - } - - // optional int32 transport_sequence_number_id = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(3, this->transport_sequence_number_id(), output); - } - - // optional int32 video_rotation_id = 4; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(4, this->video_rotation_id(), output); - } - - // optional int32 audio_level_id = 5; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(5, this->audio_level_id(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.RtpHeaderExtensionConfig) -} - -size_t RtpHeaderExtensionConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.RtpHeaderExtensionConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional int32 transmission_time_offset_id = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->transmission_time_offset_id()); - } - - // optional int32 absolute_send_time_id = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->absolute_send_time_id()); - } - - // optional int32 transport_sequence_number_id = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->transport_sequence_number_id()); - } - - // optional int32 video_rotation_id = 4; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->video_rotation_id()); - } - - // optional int32 audio_level_id = 5; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->audio_level_id()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void RtpHeaderExtensionConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void RtpHeaderExtensionConfig::MergeFrom(const RtpHeaderExtensionConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.RtpHeaderExtensionConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - transmission_time_offset_id_ = from.transmission_time_offset_id_; - } - if (cached_has_bits & 0x00000002u) { - absolute_send_time_id_ = from.absolute_send_time_id_; - } - if (cached_has_bits & 0x00000004u) { - transport_sequence_number_id_ = from.transport_sequence_number_id_; - } - if (cached_has_bits & 0x00000008u) { - video_rotation_id_ = from.video_rotation_id_; - } - if (cached_has_bits & 0x00000010u) { - audio_level_id_ = from.audio_level_id_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void RtpHeaderExtensionConfig::CopyFrom(const RtpHeaderExtensionConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.RtpHeaderExtensionConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RtpHeaderExtensionConfig::IsInitialized() const { - return true; -} - -void RtpHeaderExtensionConfig::InternalSwap(RtpHeaderExtensionConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(transmission_time_offset_id_, other->transmission_time_offset_id_); - swap(absolute_send_time_id_, other->absolute_send_time_id_); - swap(transport_sequence_number_id_, other->transport_sequence_number_id_); - swap(video_rotation_id_, other->video_rotation_id_); - swap(audio_level_id_, other->audio_level_id_); -} - -std::string RtpHeaderExtensionConfig::GetTypeName() const { - return "webrtc.rtclog2.RtpHeaderExtensionConfig"; -} - - -// =================================================================== - -void VideoRecvStreamConfig::InitAsDefaultInstance() { - ::webrtc::rtclog2::_VideoRecvStreamConfig_default_instance_._instance.get_mutable()->header_extensions_ = const_cast< ::webrtc::rtclog2::RtpHeaderExtensionConfig*>( - ::webrtc::rtclog2::RtpHeaderExtensionConfig::internal_default_instance()); -} -class VideoRecvStreamConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_remote_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_local_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_rtx_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static const ::webrtc::rtclog2::RtpHeaderExtensionConfig& header_extensions(const VideoRecvStreamConfig* msg); - static void set_has_header_extensions(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -const ::webrtc::rtclog2::RtpHeaderExtensionConfig& -VideoRecvStreamConfig::_Internal::header_extensions(const VideoRecvStreamConfig* msg) { - return *msg->header_extensions_; -} -VideoRecvStreamConfig::VideoRecvStreamConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.VideoRecvStreamConfig) -} -VideoRecvStreamConfig::VideoRecvStreamConfig(const VideoRecvStreamConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from.has_header_extensions()) { - header_extensions_ = new ::webrtc::rtclog2::RtpHeaderExtensionConfig(*from.header_extensions_); - } else { - header_extensions_ = nullptr; - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&rtx_ssrc_) - - reinterpret_cast(×tamp_ms_)) + sizeof(rtx_ssrc_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.VideoRecvStreamConfig) -} - -void VideoRecvStreamConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_VideoRecvStreamConfig_rtc_5fevent_5flog2_2eproto.base); - ::memset(&header_extensions_, 0, static_cast( - reinterpret_cast(&rtx_ssrc_) - - reinterpret_cast(&header_extensions_)) + sizeof(rtx_ssrc_)); -} - -VideoRecvStreamConfig::~VideoRecvStreamConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.VideoRecvStreamConfig) - SharedDtor(); -} - -void VideoRecvStreamConfig::SharedDtor() { - if (this != internal_default_instance()) delete header_extensions_; -} - -void VideoRecvStreamConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const VideoRecvStreamConfig& VideoRecvStreamConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_VideoRecvStreamConfig_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void VideoRecvStreamConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.VideoRecvStreamConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(header_extensions_ != nullptr); - header_extensions_->Clear(); - } - if (cached_has_bits & 0x0000001eu) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&rtx_ssrc_) - - reinterpret_cast(×tamp_ms_)) + sizeof(rtx_ssrc_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* VideoRecvStreamConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 remote_ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_remote_ssrc(&has_bits); - remote_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 local_ssrc = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_local_ssrc(&has_bits); - local_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 rtx_ssrc = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_rtx_ssrc(&has_bits); - rtx_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ctx->ParseMessage(mutable_header_extensions(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool VideoRecvStreamConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.VideoRecvStreamConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 remote_ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_remote_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &remote_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 local_ssrc = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_local_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &local_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 rtx_ssrc = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_rtx_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &rtx_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (42 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_header_extensions())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.VideoRecvStreamConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.VideoRecvStreamConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void VideoRecvStreamConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.VideoRecvStreamConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 remote_ssrc = 2; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->remote_ssrc(), output); - } - - // optional uint32 local_ssrc = 3; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->local_ssrc(), output); - } - - // optional uint32 rtx_ssrc = 4; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->rtx_ssrc(), output); - } - - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 5, _Internal::header_extensions(this), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.VideoRecvStreamConfig) -} - -size_t VideoRecvStreamConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.VideoRecvStreamConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *header_extensions_); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 remote_ssrc = 2; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->remote_ssrc()); - } - - // optional uint32 local_ssrc = 3; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->local_ssrc()); - } - - // optional uint32 rtx_ssrc = 4; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->rtx_ssrc()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void VideoRecvStreamConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void VideoRecvStreamConfig::MergeFrom(const VideoRecvStreamConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.VideoRecvStreamConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - mutable_header_extensions()->::webrtc::rtclog2::RtpHeaderExtensionConfig::MergeFrom(from.header_extensions()); - } - if (cached_has_bits & 0x00000002u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000004u) { - remote_ssrc_ = from.remote_ssrc_; - } - if (cached_has_bits & 0x00000008u) { - local_ssrc_ = from.local_ssrc_; - } - if (cached_has_bits & 0x00000010u) { - rtx_ssrc_ = from.rtx_ssrc_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void VideoRecvStreamConfig::CopyFrom(const VideoRecvStreamConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.VideoRecvStreamConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool VideoRecvStreamConfig::IsInitialized() const { - return true; -} - -void VideoRecvStreamConfig::InternalSwap(VideoRecvStreamConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(header_extensions_, other->header_extensions_); - swap(timestamp_ms_, other->timestamp_ms_); - swap(remote_ssrc_, other->remote_ssrc_); - swap(local_ssrc_, other->local_ssrc_); - swap(rtx_ssrc_, other->rtx_ssrc_); -} - -std::string VideoRecvStreamConfig::GetTypeName() const { - return "webrtc.rtclog2.VideoRecvStreamConfig"; -} - - -// =================================================================== - -void VideoSendStreamConfig::InitAsDefaultInstance() { - ::webrtc::rtclog2::_VideoSendStreamConfig_default_instance_._instance.get_mutable()->header_extensions_ = const_cast< ::webrtc::rtclog2::RtpHeaderExtensionConfig*>( - ::webrtc::rtclog2::RtpHeaderExtensionConfig::internal_default_instance()); -} -class VideoSendStreamConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_rtx_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static const ::webrtc::rtclog2::RtpHeaderExtensionConfig& header_extensions(const VideoSendStreamConfig* msg); - static void set_has_header_extensions(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -const ::webrtc::rtclog2::RtpHeaderExtensionConfig& -VideoSendStreamConfig::_Internal::header_extensions(const VideoSendStreamConfig* msg) { - return *msg->header_extensions_; -} -VideoSendStreamConfig::VideoSendStreamConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.VideoSendStreamConfig) -} -VideoSendStreamConfig::VideoSendStreamConfig(const VideoSendStreamConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from.has_header_extensions()) { - header_extensions_ = new ::webrtc::rtclog2::RtpHeaderExtensionConfig(*from.header_extensions_); - } else { - header_extensions_ = nullptr; - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&rtx_ssrc_) - - reinterpret_cast(×tamp_ms_)) + sizeof(rtx_ssrc_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.VideoSendStreamConfig) -} - -void VideoSendStreamConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_VideoSendStreamConfig_rtc_5fevent_5flog2_2eproto.base); - ::memset(&header_extensions_, 0, static_cast( - reinterpret_cast(&rtx_ssrc_) - - reinterpret_cast(&header_extensions_)) + sizeof(rtx_ssrc_)); -} - -VideoSendStreamConfig::~VideoSendStreamConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.VideoSendStreamConfig) - SharedDtor(); -} - -void VideoSendStreamConfig::SharedDtor() { - if (this != internal_default_instance()) delete header_extensions_; -} - -void VideoSendStreamConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const VideoSendStreamConfig& VideoSendStreamConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_VideoSendStreamConfig_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void VideoSendStreamConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.VideoSendStreamConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(header_extensions_ != nullptr); - header_extensions_->Clear(); - } - if (cached_has_bits & 0x0000000eu) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&rtx_ssrc_) - - reinterpret_cast(×tamp_ms_)) + sizeof(rtx_ssrc_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* VideoSendStreamConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_ssrc(&has_bits); - ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 rtx_ssrc = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_rtx_ssrc(&has_bits); - rtx_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) { - ptr = ctx->ParseMessage(mutable_header_extensions(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool VideoSendStreamConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.VideoSendStreamConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 rtx_ssrc = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_rtx_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &rtx_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (34 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_header_extensions())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.VideoSendStreamConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.VideoSendStreamConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void VideoSendStreamConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.VideoSendStreamConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 ssrc = 2; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->ssrc(), output); - } - - // optional uint32 rtx_ssrc = 3; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->rtx_ssrc(), output); - } - - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 4, _Internal::header_extensions(this), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.VideoSendStreamConfig) -} - -size_t VideoSendStreamConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.VideoSendStreamConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *header_extensions_); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 ssrc = 2; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->ssrc()); - } - - // optional uint32 rtx_ssrc = 3; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->rtx_ssrc()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void VideoSendStreamConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void VideoSendStreamConfig::MergeFrom(const VideoSendStreamConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.VideoSendStreamConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - if (cached_has_bits & 0x00000001u) { - mutable_header_extensions()->::webrtc::rtclog2::RtpHeaderExtensionConfig::MergeFrom(from.header_extensions()); - } - if (cached_has_bits & 0x00000002u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000004u) { - ssrc_ = from.ssrc_; - } - if (cached_has_bits & 0x00000008u) { - rtx_ssrc_ = from.rtx_ssrc_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void VideoSendStreamConfig::CopyFrom(const VideoSendStreamConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.VideoSendStreamConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool VideoSendStreamConfig::IsInitialized() const { - return true; -} - -void VideoSendStreamConfig::InternalSwap(VideoSendStreamConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(header_extensions_, other->header_extensions_); - swap(timestamp_ms_, other->timestamp_ms_); - swap(ssrc_, other->ssrc_); - swap(rtx_ssrc_, other->rtx_ssrc_); -} - -std::string VideoSendStreamConfig::GetTypeName() const { - return "webrtc.rtclog2.VideoSendStreamConfig"; -} - - -// =================================================================== - -void AudioRecvStreamConfig::InitAsDefaultInstance() { - ::webrtc::rtclog2::_AudioRecvStreamConfig_default_instance_._instance.get_mutable()->header_extensions_ = const_cast< ::webrtc::rtclog2::RtpHeaderExtensionConfig*>( - ::webrtc::rtclog2::RtpHeaderExtensionConfig::internal_default_instance()); -} -class AudioRecvStreamConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_remote_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_local_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static const ::webrtc::rtclog2::RtpHeaderExtensionConfig& header_extensions(const AudioRecvStreamConfig* msg); - static void set_has_header_extensions(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -const ::webrtc::rtclog2::RtpHeaderExtensionConfig& -AudioRecvStreamConfig::_Internal::header_extensions(const AudioRecvStreamConfig* msg) { - return *msg->header_extensions_; -} -AudioRecvStreamConfig::AudioRecvStreamConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.AudioRecvStreamConfig) -} -AudioRecvStreamConfig::AudioRecvStreamConfig(const AudioRecvStreamConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from.has_header_extensions()) { - header_extensions_ = new ::webrtc::rtclog2::RtpHeaderExtensionConfig(*from.header_extensions_); - } else { - header_extensions_ = nullptr; - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&local_ssrc_) - - reinterpret_cast(×tamp_ms_)) + sizeof(local_ssrc_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.AudioRecvStreamConfig) -} - -void AudioRecvStreamConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_AudioRecvStreamConfig_rtc_5fevent_5flog2_2eproto.base); - ::memset(&header_extensions_, 0, static_cast( - reinterpret_cast(&local_ssrc_) - - reinterpret_cast(&header_extensions_)) + sizeof(local_ssrc_)); -} - -AudioRecvStreamConfig::~AudioRecvStreamConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.AudioRecvStreamConfig) - SharedDtor(); -} - -void AudioRecvStreamConfig::SharedDtor() { - if (this != internal_default_instance()) delete header_extensions_; -} - -void AudioRecvStreamConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AudioRecvStreamConfig& AudioRecvStreamConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AudioRecvStreamConfig_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void AudioRecvStreamConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.AudioRecvStreamConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(header_extensions_ != nullptr); - header_extensions_->Clear(); - } - if (cached_has_bits & 0x0000000eu) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&local_ssrc_) - - reinterpret_cast(×tamp_ms_)) + sizeof(local_ssrc_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AudioRecvStreamConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 remote_ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_remote_ssrc(&has_bits); - remote_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 local_ssrc = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_local_ssrc(&has_bits); - local_ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ctx->ParseMessage(mutable_header_extensions(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AudioRecvStreamConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.AudioRecvStreamConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 remote_ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_remote_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &remote_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 local_ssrc = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_local_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &local_ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (42 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_header_extensions())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.AudioRecvStreamConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.AudioRecvStreamConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AudioRecvStreamConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.AudioRecvStreamConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 remote_ssrc = 2; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->remote_ssrc(), output); - } - - // optional uint32 local_ssrc = 3; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->local_ssrc(), output); - } - - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 5, _Internal::header_extensions(this), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.AudioRecvStreamConfig) -} - -size_t AudioRecvStreamConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.AudioRecvStreamConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *header_extensions_); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 remote_ssrc = 2; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->remote_ssrc()); - } - - // optional uint32 local_ssrc = 3; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->local_ssrc()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AudioRecvStreamConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AudioRecvStreamConfig::MergeFrom(const AudioRecvStreamConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.AudioRecvStreamConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - if (cached_has_bits & 0x00000001u) { - mutable_header_extensions()->::webrtc::rtclog2::RtpHeaderExtensionConfig::MergeFrom(from.header_extensions()); - } - if (cached_has_bits & 0x00000002u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000004u) { - remote_ssrc_ = from.remote_ssrc_; - } - if (cached_has_bits & 0x00000008u) { - local_ssrc_ = from.local_ssrc_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void AudioRecvStreamConfig::CopyFrom(const AudioRecvStreamConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.AudioRecvStreamConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AudioRecvStreamConfig::IsInitialized() const { - return true; -} - -void AudioRecvStreamConfig::InternalSwap(AudioRecvStreamConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(header_extensions_, other->header_extensions_); - swap(timestamp_ms_, other->timestamp_ms_); - swap(remote_ssrc_, other->remote_ssrc_); - swap(local_ssrc_, other->local_ssrc_); -} - -std::string AudioRecvStreamConfig::GetTypeName() const { - return "webrtc.rtclog2.AudioRecvStreamConfig"; -} - - -// =================================================================== - -void AudioSendStreamConfig::InitAsDefaultInstance() { - ::webrtc::rtclog2::_AudioSendStreamConfig_default_instance_._instance.get_mutable()->header_extensions_ = const_cast< ::webrtc::rtclog2::RtpHeaderExtensionConfig*>( - ::webrtc::rtclog2::RtpHeaderExtensionConfig::internal_default_instance()); -} -class AudioSendStreamConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_ssrc(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static const ::webrtc::rtclog2::RtpHeaderExtensionConfig& header_extensions(const AudioSendStreamConfig* msg); - static void set_has_header_extensions(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } -}; - -const ::webrtc::rtclog2::RtpHeaderExtensionConfig& -AudioSendStreamConfig::_Internal::header_extensions(const AudioSendStreamConfig* msg) { - return *msg->header_extensions_; -} -AudioSendStreamConfig::AudioSendStreamConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.AudioSendStreamConfig) -} -AudioSendStreamConfig::AudioSendStreamConfig(const AudioSendStreamConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from.has_header_extensions()) { - header_extensions_ = new ::webrtc::rtclog2::RtpHeaderExtensionConfig(*from.header_extensions_); - } else { - header_extensions_ = nullptr; - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&ssrc_) - - reinterpret_cast(×tamp_ms_)) + sizeof(ssrc_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.AudioSendStreamConfig) -} - -void AudioSendStreamConfig::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_AudioSendStreamConfig_rtc_5fevent_5flog2_2eproto.base); - ::memset(&header_extensions_, 0, static_cast( - reinterpret_cast(&ssrc_) - - reinterpret_cast(&header_extensions_)) + sizeof(ssrc_)); -} - -AudioSendStreamConfig::~AudioSendStreamConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.AudioSendStreamConfig) - SharedDtor(); -} - -void AudioSendStreamConfig::SharedDtor() { - if (this != internal_default_instance()) delete header_extensions_; -} - -void AudioSendStreamConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AudioSendStreamConfig& AudioSendStreamConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AudioSendStreamConfig_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void AudioSendStreamConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.AudioSendStreamConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(header_extensions_ != nullptr); - header_extensions_->Clear(); - } - if (cached_has_bits & 0x00000006u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&ssrc_) - - reinterpret_cast(×tamp_ms_)) + sizeof(ssrc_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AudioSendStreamConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 ssrc = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_ssrc(&has_bits); - ssrc_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) { - ptr = ctx->ParseMessage(mutable_header_extensions(), ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AudioSendStreamConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.AudioSendStreamConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 ssrc = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_ssrc(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &ssrc_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (34 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadMessage( - input, mutable_header_extensions())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.AudioSendStreamConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.AudioSendStreamConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AudioSendStreamConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.AudioSendStreamConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 ssrc = 2; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->ssrc(), output); - } - - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessage( - 4, _Internal::header_extensions(this), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.AudioSendStreamConfig) -} - -size_t AudioSendStreamConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.AudioSendStreamConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *header_extensions_); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 ssrc = 2; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->ssrc()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AudioSendStreamConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AudioSendStreamConfig::MergeFrom(const AudioSendStreamConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.AudioSendStreamConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - mutable_header_extensions()->::webrtc::rtclog2::RtpHeaderExtensionConfig::MergeFrom(from.header_extensions()); - } - if (cached_has_bits & 0x00000002u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000004u) { - ssrc_ = from.ssrc_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void AudioSendStreamConfig::CopyFrom(const AudioSendStreamConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.AudioSendStreamConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AudioSendStreamConfig::IsInitialized() const { - return true; -} - -void AudioSendStreamConfig::InternalSwap(AudioSendStreamConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(header_extensions_, other->header_extensions_); - swap(timestamp_ms_, other->timestamp_ms_); - swap(ssrc_, other->ssrc_); -} - -std::string AudioSendStreamConfig::GetTypeName() const { - return "webrtc.rtclog2.AudioSendStreamConfig"; -} - - -// =================================================================== - -void AudioNetworkAdaptations::InitAsDefaultInstance() { -} -class AudioNetworkAdaptations::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_frame_length_ms(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } - static void set_has_uplink_packet_loss_fraction(HasBits* has_bits) { - (*has_bits)[0] |= 1024u; - } - static void set_has_enable_fec(HasBits* has_bits) { - (*has_bits)[0] |= 2048u; - } - static void set_has_enable_dtx(HasBits* has_bits) { - (*has_bits)[0] |= 4096u; - } - static void set_has_num_channels(HasBits* has_bits) { - (*has_bits)[0] |= 8192u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16384u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_bitrate_bps_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_frame_length_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_uplink_packet_loss_fraction_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_enable_fec_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_enable_dtx_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_num_channels_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } -}; - -AudioNetworkAdaptations::AudioNetworkAdaptations() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.AudioNetworkAdaptations) -} -AudioNetworkAdaptations::AudioNetworkAdaptations(const AudioNetworkAdaptations& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - bitrate_bps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_bitrate_bps_deltas()) { - bitrate_bps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.bitrate_bps_deltas_); - } - frame_length_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_frame_length_ms_deltas()) { - frame_length_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.frame_length_ms_deltas_); - } - uplink_packet_loss_fraction_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_uplink_packet_loss_fraction_deltas()) { - uplink_packet_loss_fraction_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.uplink_packet_loss_fraction_deltas_); - } - enable_fec_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_enable_fec_deltas()) { - enable_fec_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.enable_fec_deltas_); - } - enable_dtx_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_enable_dtx_deltas()) { - enable_dtx_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.enable_dtx_deltas_); - } - num_channels_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_num_channels_deltas()) { - num_channels_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.num_channels_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.AudioNetworkAdaptations) -} - -void AudioNetworkAdaptations::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_AudioNetworkAdaptations_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - bitrate_bps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - frame_length_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - uplink_packet_loss_fraction_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - enable_fec_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - enable_dtx_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - num_channels_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -AudioNetworkAdaptations::~AudioNetworkAdaptations() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.AudioNetworkAdaptations) - SharedDtor(); -} - -void AudioNetworkAdaptations::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - bitrate_bps_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - frame_length_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - uplink_packet_loss_fraction_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - enable_fec_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - enable_dtx_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - num_channels_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void AudioNetworkAdaptations::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AudioNetworkAdaptations& AudioNetworkAdaptations::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AudioNetworkAdaptations_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void AudioNetworkAdaptations::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.AudioNetworkAdaptations) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000007fu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - bitrate_bps_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - frame_length_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000008u) { - uplink_packet_loss_fraction_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000010u) { - enable_fec_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000020u) { - enable_dtx_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000040u) { - num_channels_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - timestamp_ms_ = PROTOBUF_LONGLONG(0); - if (cached_has_bits & 0x00007f00u) { - ::memset(&bitrate_bps_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(&bitrate_bps_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AudioNetworkAdaptations::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 bitrate_bps = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional int32 frame_length_ms = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_frame_length_ms(&has_bits); - frame_length_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 uplink_packet_loss_fraction = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_uplink_packet_loss_fraction(&has_bits); - uplink_packet_loss_fraction_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool enable_fec = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - _Internal::set_has_enable_fec(&has_bits); - enable_fec_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool enable_dtx = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 48)) { - _Internal::set_has_enable_dtx(&has_bits); - enable_dtx_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 num_channels = 7; - case 7: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 56)) { - _Internal::set_has_num_channels(&has_bits); - num_channels_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 8; - case 8: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 64)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes bitrate_bps_deltas = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_bitrate_bps_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes frame_length_ms_deltas = 103; - case 103: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_frame_length_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes uplink_packet_loss_fraction_deltas = 104; - case 104: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_uplink_packet_loss_fraction_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes enable_fec_deltas = 105; - case 105: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 74)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_enable_fec_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes enable_dtx_deltas = 106; - case 106: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 82)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_enable_dtx_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes num_channels_deltas = 107; - case 107: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 90)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_num_channels_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AudioNetworkAdaptations::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.AudioNetworkAdaptations) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 bitrate_bps = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional int32 frame_length_ms = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_frame_length_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( - input, &frame_length_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 uplink_packet_loss_fraction = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_uplink_packet_loss_fraction(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &uplink_packet_loss_fraction_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool enable_fec = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - _Internal::set_has_enable_fec(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &enable_fec_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool enable_dtx = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (48 & 0xFF)) { - _Internal::set_has_enable_dtx(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &enable_dtx_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 num_channels = 7; - case 7: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (56 & 0xFF)) { - _Internal::set_has_num_channels(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &num_channels_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 8; - case 8: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (64 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes bitrate_bps_deltas = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_bitrate_bps_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes frame_length_ms_deltas = 103; - case 103: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (826 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_frame_length_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes uplink_packet_loss_fraction_deltas = 104; - case 104: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (834 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_uplink_packet_loss_fraction_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes enable_fec_deltas = 105; - case 105: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (842 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_enable_fec_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes enable_dtx_deltas = 106; - case 106: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (850 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_enable_dtx_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes num_channels_deltas = 107; - case 107: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (858 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_num_channels_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.AudioNetworkAdaptations) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.AudioNetworkAdaptations) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AudioNetworkAdaptations::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.AudioNetworkAdaptations) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional int32 bitrate_bps = 2; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->bitrate_bps(), output); - } - - // optional int32 frame_length_ms = 3; - if (cached_has_bits & 0x00000200u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(3, this->frame_length_ms(), output); - } - - // optional uint32 uplink_packet_loss_fraction = 4; - if (cached_has_bits & 0x00000400u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->uplink_packet_loss_fraction(), output); - } - - // optional bool enable_fec = 5; - if (cached_has_bits & 0x00000800u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(5, this->enable_fec(), output); - } - - // optional bool enable_dtx = 6; - if (cached_has_bits & 0x00001000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(6, this->enable_dtx(), output); - } - - // optional uint32 num_channels = 7; - if (cached_has_bits & 0x00002000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(7, this->num_channels(), output); - } - - // optional uint32 number_of_deltas = 8; - if (cached_has_bits & 0x00004000u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(8, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes bitrate_bps_deltas = 102; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->bitrate_bps_deltas(), output); - } - - // optional bytes frame_length_ms_deltas = 103; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 103, this->frame_length_ms_deltas(), output); - } - - // optional bytes uplink_packet_loss_fraction_deltas = 104; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 104, this->uplink_packet_loss_fraction_deltas(), output); - } - - // optional bytes enable_fec_deltas = 105; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 105, this->enable_fec_deltas(), output); - } - - // optional bytes enable_dtx_deltas = 106; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 106, this->enable_dtx_deltas(), output); - } - - // optional bytes num_channels_deltas = 107; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 107, this->num_channels_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.AudioNetworkAdaptations) -} - -size_t AudioNetworkAdaptations::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.AudioNetworkAdaptations) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes bitrate_bps_deltas = 102; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->bitrate_bps_deltas()); - } - - // optional bytes frame_length_ms_deltas = 103; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->frame_length_ms_deltas()); - } - - // optional bytes uplink_packet_loss_fraction_deltas = 104; - if (cached_has_bits & 0x00000008u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->uplink_packet_loss_fraction_deltas()); - } - - // optional bytes enable_fec_deltas = 105; - if (cached_has_bits & 0x00000010u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->enable_fec_deltas()); - } - - // optional bytes enable_dtx_deltas = 106; - if (cached_has_bits & 0x00000020u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->enable_dtx_deltas()); - } - - // optional bytes num_channels_deltas = 107; - if (cached_has_bits & 0x00000040u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->num_channels_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000080u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - } - if (cached_has_bits & 0x00007f00u) { - // optional int32 bitrate_bps = 2; - if (cached_has_bits & 0x00000100u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->bitrate_bps()); - } - - // optional int32 frame_length_ms = 3; - if (cached_has_bits & 0x00000200u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->frame_length_ms()); - } - - // optional uint32 uplink_packet_loss_fraction = 4; - if (cached_has_bits & 0x00000400u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->uplink_packet_loss_fraction()); - } - - // optional bool enable_fec = 5; - if (cached_has_bits & 0x00000800u) { - total_size += 1 + 1; - } - - // optional bool enable_dtx = 6; - if (cached_has_bits & 0x00001000u) { - total_size += 1 + 1; - } - - // optional uint32 num_channels = 7; - if (cached_has_bits & 0x00002000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->num_channels()); - } - - // optional uint32 number_of_deltas = 8; - if (cached_has_bits & 0x00004000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AudioNetworkAdaptations::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AudioNetworkAdaptations::MergeFrom(const AudioNetworkAdaptations& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.AudioNetworkAdaptations) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.bitrate_bps_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - frame_length_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.frame_length_ms_deltas_); - } - if (cached_has_bits & 0x00000008u) { - _has_bits_[0] |= 0x00000008u; - uplink_packet_loss_fraction_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.uplink_packet_loss_fraction_deltas_); - } - if (cached_has_bits & 0x00000010u) { - _has_bits_[0] |= 0x00000010u; - enable_fec_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.enable_fec_deltas_); - } - if (cached_has_bits & 0x00000020u) { - _has_bits_[0] |= 0x00000020u; - enable_dtx_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.enable_dtx_deltas_); - } - if (cached_has_bits & 0x00000040u) { - _has_bits_[0] |= 0x00000040u; - num_channels_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.num_channels_deltas_); - } - if (cached_has_bits & 0x00000080u) { - timestamp_ms_ = from.timestamp_ms_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00007f00u) { - if (cached_has_bits & 0x00000100u) { - bitrate_bps_ = from.bitrate_bps_; - } - if (cached_has_bits & 0x00000200u) { - frame_length_ms_ = from.frame_length_ms_; - } - if (cached_has_bits & 0x00000400u) { - uplink_packet_loss_fraction_ = from.uplink_packet_loss_fraction_; - } - if (cached_has_bits & 0x00000800u) { - enable_fec_ = from.enable_fec_; - } - if (cached_has_bits & 0x00001000u) { - enable_dtx_ = from.enable_dtx_; - } - if (cached_has_bits & 0x00002000u) { - num_channels_ = from.num_channels_; - } - if (cached_has_bits & 0x00004000u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void AudioNetworkAdaptations::CopyFrom(const AudioNetworkAdaptations& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.AudioNetworkAdaptations) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AudioNetworkAdaptations::IsInitialized() const { - return true; -} - -void AudioNetworkAdaptations::InternalSwap(AudioNetworkAdaptations* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - bitrate_bps_deltas_.Swap(&other->bitrate_bps_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - frame_length_ms_deltas_.Swap(&other->frame_length_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - uplink_packet_loss_fraction_deltas_.Swap(&other->uplink_packet_loss_fraction_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - enable_fec_deltas_.Swap(&other->enable_fec_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - enable_dtx_deltas_.Swap(&other->enable_dtx_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - num_channels_deltas_.Swap(&other->num_channels_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(bitrate_bps_, other->bitrate_bps_); - swap(frame_length_ms_, other->frame_length_ms_); - swap(uplink_packet_loss_fraction_, other->uplink_packet_loss_fraction_); - swap(enable_fec_, other->enable_fec_); - swap(enable_dtx_, other->enable_dtx_); - swap(num_channels_, other->num_channels_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string AudioNetworkAdaptations::GetTypeName() const { - return "webrtc.rtclog2.AudioNetworkAdaptations"; -} - - -// =================================================================== - -void BweProbeCluster::InitAsDefaultInstance() { -} -class BweProbeCluster::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_id(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_min_packets(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_min_bytes(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } -}; - -BweProbeCluster::BweProbeCluster() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.BweProbeCluster) -} -BweProbeCluster::BweProbeCluster(const BweProbeCluster& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&min_bytes_) - - reinterpret_cast(×tamp_ms_)) + sizeof(min_bytes_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.BweProbeCluster) -} - -void BweProbeCluster::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&min_bytes_) - - reinterpret_cast(×tamp_ms_)) + sizeof(min_bytes_)); -} - -BweProbeCluster::~BweProbeCluster() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.BweProbeCluster) - SharedDtor(); -} - -void BweProbeCluster::SharedDtor() { -} - -void BweProbeCluster::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const BweProbeCluster& BweProbeCluster::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_BweProbeCluster_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void BweProbeCluster::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.BweProbeCluster) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&min_bytes_) - - reinterpret_cast(×tamp_ms_)) + sizeof(min_bytes_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* BweProbeCluster::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 id = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_id(&has_bits); - id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 bitrate_bps = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 min_packets = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_min_packets(&has_bits); - min_packets_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 min_bytes = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - _Internal::set_has_min_bytes(&has_bits); - min_bytes_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool BweProbeCluster::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.BweProbeCluster) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 id = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 bitrate_bps = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 min_packets = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_min_packets(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &min_packets_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 min_bytes = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - _Internal::set_has_min_bytes(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &min_bytes_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.BweProbeCluster) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.BweProbeCluster) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void BweProbeCluster::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.BweProbeCluster) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 id = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->id(), output); - } - - // optional uint32 bitrate_bps = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->bitrate_bps(), output); - } - - // optional uint32 min_packets = 4; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->min_packets(), output); - } - - // optional uint32 min_bytes = 5; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(5, this->min_bytes(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.BweProbeCluster) -} - -size_t BweProbeCluster::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.BweProbeCluster) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 id = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->id()); - } - - // optional uint32 bitrate_bps = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->bitrate_bps()); - } - - // optional uint32 min_packets = 4; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->min_packets()); - } - - // optional uint32 min_bytes = 5; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->min_bytes()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void BweProbeCluster::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void BweProbeCluster::MergeFrom(const BweProbeCluster& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.BweProbeCluster) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - id_ = from.id_; - } - if (cached_has_bits & 0x00000004u) { - bitrate_bps_ = from.bitrate_bps_; - } - if (cached_has_bits & 0x00000008u) { - min_packets_ = from.min_packets_; - } - if (cached_has_bits & 0x00000010u) { - min_bytes_ = from.min_bytes_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void BweProbeCluster::CopyFrom(const BweProbeCluster& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.BweProbeCluster) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool BweProbeCluster::IsInitialized() const { - return true; -} - -void BweProbeCluster::InternalSwap(BweProbeCluster* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(id_, other->id_); - swap(bitrate_bps_, other->bitrate_bps_); - swap(min_packets_, other->min_packets_); - swap(min_bytes_, other->min_bytes_); -} - -std::string BweProbeCluster::GetTypeName() const { - return "webrtc.rtclog2.BweProbeCluster"; -} - - -// =================================================================== - -void BweProbeResultSuccess::InitAsDefaultInstance() { -} -class BweProbeResultSuccess::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_id(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_bitrate_bps(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -BweProbeResultSuccess::BweProbeResultSuccess() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.BweProbeResultSuccess) -} -BweProbeResultSuccess::BweProbeResultSuccess(const BweProbeResultSuccess& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&bitrate_bps_) - - reinterpret_cast(×tamp_ms_)) + sizeof(bitrate_bps_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.BweProbeResultSuccess) -} - -void BweProbeResultSuccess::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&bitrate_bps_) - - reinterpret_cast(×tamp_ms_)) + sizeof(bitrate_bps_)); -} - -BweProbeResultSuccess::~BweProbeResultSuccess() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.BweProbeResultSuccess) - SharedDtor(); -} - -void BweProbeResultSuccess::SharedDtor() { -} - -void BweProbeResultSuccess::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const BweProbeResultSuccess& BweProbeResultSuccess::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_BweProbeResultSuccess_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void BweProbeResultSuccess::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.BweProbeResultSuccess) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&bitrate_bps_) - - reinterpret_cast(×tamp_ms_)) + sizeof(bitrate_bps_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* BweProbeResultSuccess::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 id = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_id(&has_bits); - id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 bitrate_bps = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_bitrate_bps(&has_bits); - bitrate_bps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool BweProbeResultSuccess::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.BweProbeResultSuccess) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 id = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 bitrate_bps = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_bitrate_bps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &bitrate_bps_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.BweProbeResultSuccess) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.BweProbeResultSuccess) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void BweProbeResultSuccess::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.BweProbeResultSuccess) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 id = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->id(), output); - } - - // optional uint32 bitrate_bps = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->bitrate_bps(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.BweProbeResultSuccess) -} - -size_t BweProbeResultSuccess::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.BweProbeResultSuccess) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 id = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->id()); - } - - // optional uint32 bitrate_bps = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->bitrate_bps()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void BweProbeResultSuccess::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void BweProbeResultSuccess::MergeFrom(const BweProbeResultSuccess& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.BweProbeResultSuccess) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - id_ = from.id_; - } - if (cached_has_bits & 0x00000004u) { - bitrate_bps_ = from.bitrate_bps_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void BweProbeResultSuccess::CopyFrom(const BweProbeResultSuccess& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.BweProbeResultSuccess) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool BweProbeResultSuccess::IsInitialized() const { - return true; -} - -void BweProbeResultSuccess::InternalSwap(BweProbeResultSuccess* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(id_, other->id_); - swap(bitrate_bps_, other->bitrate_bps_); -} - -std::string BweProbeResultSuccess::GetTypeName() const { - return "webrtc.rtclog2.BweProbeResultSuccess"; -} - - -// =================================================================== - -void BweProbeResultFailure::InitAsDefaultInstance() { -} -class BweProbeResultFailure::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_id(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_failure(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -BweProbeResultFailure::BweProbeResultFailure() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.BweProbeResultFailure) -} -BweProbeResultFailure::BweProbeResultFailure(const BweProbeResultFailure& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&failure_) - - reinterpret_cast(×tamp_ms_)) + sizeof(failure_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.BweProbeResultFailure) -} - -void BweProbeResultFailure::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&failure_) - - reinterpret_cast(×tamp_ms_)) + sizeof(failure_)); -} - -BweProbeResultFailure::~BweProbeResultFailure() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.BweProbeResultFailure) - SharedDtor(); -} - -void BweProbeResultFailure::SharedDtor() { -} - -void BweProbeResultFailure::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const BweProbeResultFailure& BweProbeResultFailure::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_BweProbeResultFailure_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void BweProbeResultFailure::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.BweProbeResultFailure) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&failure_) - - reinterpret_cast(×tamp_ms_)) + sizeof(failure_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* BweProbeResultFailure::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 id = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_id(&has_bits); - id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.BweProbeResultFailure.FailureReason failure = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::BweProbeResultFailure_FailureReason_IsValid(val))) { - set_failure(static_cast<::webrtc::rtclog2::BweProbeResultFailure_FailureReason>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(3, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool BweProbeResultFailure::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.BweProbeResultFailure) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 id = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.BweProbeResultFailure.FailureReason failure = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::BweProbeResultFailure_FailureReason_IsValid(value)) { - set_failure(static_cast< ::webrtc::rtclog2::BweProbeResultFailure_FailureReason >(value)); - } else { - unknown_fields_stream.WriteVarint32(24u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.BweProbeResultFailure) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.BweProbeResultFailure) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void BweProbeResultFailure::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.BweProbeResultFailure) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 id = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->id(), output); - } - - // optional .webrtc.rtclog2.BweProbeResultFailure.FailureReason failure = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 3, this->failure(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.BweProbeResultFailure) -} - -size_t BweProbeResultFailure::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.BweProbeResultFailure) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 id = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->id()); - } - - // optional .webrtc.rtclog2.BweProbeResultFailure.FailureReason failure = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->failure()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void BweProbeResultFailure::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void BweProbeResultFailure::MergeFrom(const BweProbeResultFailure& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.BweProbeResultFailure) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - id_ = from.id_; - } - if (cached_has_bits & 0x00000004u) { - failure_ = from.failure_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void BweProbeResultFailure::CopyFrom(const BweProbeResultFailure& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.BweProbeResultFailure) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool BweProbeResultFailure::IsInitialized() const { - return true; -} - -void BweProbeResultFailure::InternalSwap(BweProbeResultFailure* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(id_, other->id_); - swap(failure_, other->failure_); -} - -std::string BweProbeResultFailure::GetTypeName() const { - return "webrtc.rtclog2.BweProbeResultFailure"; -} - - -// =================================================================== - -void AlrState::InitAsDefaultInstance() { -} -class AlrState::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_in_alr(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -AlrState::AlrState() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.AlrState) -} -AlrState::AlrState(const AlrState& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&in_alr_) - - reinterpret_cast(×tamp_ms_)) + sizeof(in_alr_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.AlrState) -} - -void AlrState::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&in_alr_) - - reinterpret_cast(×tamp_ms_)) + sizeof(in_alr_)); -} - -AlrState::~AlrState() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.AlrState) - SharedDtor(); -} - -void AlrState::SharedDtor() { -} - -void AlrState::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const AlrState& AlrState::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_AlrState_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void AlrState::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.AlrState) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&in_alr_) - - reinterpret_cast(×tamp_ms_)) + sizeof(in_alr_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* AlrState::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool in_alr = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_in_alr(&has_bits); - in_alr_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool AlrState::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.AlrState) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool in_alr = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_in_alr(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &in_alr_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.AlrState) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.AlrState) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void AlrState::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.AlrState) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional bool in_alr = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(2, this->in_alr(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.AlrState) -} - -size_t AlrState::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.AlrState) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional bool in_alr = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + 1; - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void AlrState::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void AlrState::MergeFrom(const AlrState& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.AlrState) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - in_alr_ = from.in_alr_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void AlrState::CopyFrom(const AlrState& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.AlrState) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AlrState::IsInitialized() const { - return true; -} - -void AlrState::InternalSwap(AlrState* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(in_alr_, other->in_alr_); -} - -std::string AlrState::GetTypeName() const { - return "webrtc.rtclog2.AlrState"; -} - - -// =================================================================== - -void IceCandidatePairConfig::InitAsDefaultInstance() { -} -class IceCandidatePairConfig::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_config_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_candidate_pair_id(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_local_candidate_type(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_local_relay_protocol(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_local_network_type(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_local_address_family(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_remote_candidate_type(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_remote_address_family(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_candidate_pair_protocol(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } -}; - -IceCandidatePairConfig::IceCandidatePairConfig() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.IceCandidatePairConfig) -} -IceCandidatePairConfig::IceCandidatePairConfig(const IceCandidatePairConfig& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&candidate_pair_protocol_) - - reinterpret_cast(×tamp_ms_)) + sizeof(candidate_pair_protocol_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.IceCandidatePairConfig) -} - -void IceCandidatePairConfig::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&candidate_pair_protocol_) - - reinterpret_cast(×tamp_ms_)) + sizeof(candidate_pair_protocol_)); -} - -IceCandidatePairConfig::~IceCandidatePairConfig() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.IceCandidatePairConfig) - SharedDtor(); -} - -void IceCandidatePairConfig::SharedDtor() { -} - -void IceCandidatePairConfig::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const IceCandidatePairConfig& IceCandidatePairConfig::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_IceCandidatePairConfig_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void IceCandidatePairConfig::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.IceCandidatePairConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&remote_candidate_type_) - - reinterpret_cast(×tamp_ms_)) + sizeof(remote_candidate_type_)); - } - if (cached_has_bits & 0x00000300u) { - ::memset(&remote_address_family_, 0, static_cast( - reinterpret_cast(&candidate_pair_protocol_) - - reinterpret_cast(&remote_address_family_)) + sizeof(candidate_pair_protocol_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* IceCandidatePairConfig::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(val))) { - set_config_type(static_cast<::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(2, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional uint32 candidate_pair_id = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_candidate_pair_id(&has_bits); - candidate_pair_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType local_candidate_type = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType_IsValid(val))) { - set_local_candidate_type(static_cast<::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(4, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol local_relay_protocol = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairConfig_Protocol_IsValid(val))) { - set_local_relay_protocol(static_cast<::webrtc::rtclog2::IceCandidatePairConfig_Protocol>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(5, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairConfig.NetworkType local_network_type = 6; - case 6: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 48)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairConfig_NetworkType_IsValid(val))) { - set_local_network_type(static_cast<::webrtc::rtclog2::IceCandidatePairConfig_NetworkType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(6, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily local_address_family = 7; - case 7: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 56)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily_IsValid(val))) { - set_local_address_family(static_cast<::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(7, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 8; - case 8: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 64)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType_IsValid(val))) { - set_remote_candidate_type(static_cast<::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(8, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily remote_address_family = 9; - case 9: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 72)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily_IsValid(val))) { - set_remote_address_family(static_cast<::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(9, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol candidate_pair_protocol = 10; - case 10: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 80)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairConfig_Protocol_IsValid(val))) { - set_candidate_pair_protocol(static_cast<::webrtc::rtclog2::IceCandidatePairConfig_Protocol>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(10, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool IceCandidatePairConfig::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.IceCandidatePairConfig) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(value)) { - set_config_type(static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType >(value)); - } else { - unknown_fields_stream.WriteVarint32(16u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 candidate_pair_id = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_candidate_pair_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &candidate_pair_id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType local_candidate_type = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType_IsValid(value)) { - set_local_candidate_type(static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType >(value)); - } else { - unknown_fields_stream.WriteVarint32(32u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol local_relay_protocol = 5; - case 5: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (40 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairConfig_Protocol_IsValid(value)) { - set_local_relay_protocol(static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_Protocol >(value)); - } else { - unknown_fields_stream.WriteVarint32(40u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.NetworkType local_network_type = 6; - case 6: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (48 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairConfig_NetworkType_IsValid(value)) { - set_local_network_type(static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_NetworkType >(value)); - } else { - unknown_fields_stream.WriteVarint32(48u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily local_address_family = 7; - case 7: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (56 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily_IsValid(value)) { - set_local_address_family(static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily >(value)); - } else { - unknown_fields_stream.WriteVarint32(56u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 8; - case 8: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (64 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType_IsValid(value)) { - set_remote_candidate_type(static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType >(value)); - } else { - unknown_fields_stream.WriteVarint32(64u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily remote_address_family = 9; - case 9: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (72 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily_IsValid(value)) { - set_remote_address_family(static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily >(value)); - } else { - unknown_fields_stream.WriteVarint32(72u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol candidate_pair_protocol = 10; - case 10: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (80 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairConfig_Protocol_IsValid(value)) { - set_candidate_pair_protocol(static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_Protocol >(value)); - } else { - unknown_fields_stream.WriteVarint32(80u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.IceCandidatePairConfig) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.IceCandidatePairConfig) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void IceCandidatePairConfig::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.IceCandidatePairConfig) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 2, this->config_type(), output); - } - - // optional uint32 candidate_pair_id = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->candidate_pair_id(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType local_candidate_type = 4; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 4, this->local_candidate_type(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol local_relay_protocol = 5; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 5, this->local_relay_protocol(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.NetworkType local_network_type = 6; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 6, this->local_network_type(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily local_address_family = 7; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 7, this->local_address_family(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 8; - if (cached_has_bits & 0x00000080u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 8, this->remote_candidate_type(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily remote_address_family = 9; - if (cached_has_bits & 0x00000100u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 9, this->remote_address_family(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol candidate_pair_protocol = 10; - if (cached_has_bits & 0x00000200u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 10, this->candidate_pair_protocol(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.IceCandidatePairConfig) -} - -size_t IceCandidatePairConfig::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.IceCandidatePairConfig) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->config_type()); - } - - // optional uint32 candidate_pair_id = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->candidate_pair_id()); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType local_candidate_type = 4; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->local_candidate_type()); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol local_relay_protocol = 5; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->local_relay_protocol()); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.NetworkType local_network_type = 6; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->local_network_type()); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily local_address_family = 7; - if (cached_has_bits & 0x00000040u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->local_address_family()); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 8; - if (cached_has_bits & 0x00000080u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->remote_candidate_type()); - } - - } - if (cached_has_bits & 0x00000300u) { - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily remote_address_family = 9; - if (cached_has_bits & 0x00000100u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->remote_address_family()); - } - - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol candidate_pair_protocol = 10; - if (cached_has_bits & 0x00000200u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->candidate_pair_protocol()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void IceCandidatePairConfig::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void IceCandidatePairConfig::MergeFrom(const IceCandidatePairConfig& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.IceCandidatePairConfig) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x000000ffu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - config_type_ = from.config_type_; - } - if (cached_has_bits & 0x00000004u) { - candidate_pair_id_ = from.candidate_pair_id_; - } - if (cached_has_bits & 0x00000008u) { - local_candidate_type_ = from.local_candidate_type_; - } - if (cached_has_bits & 0x00000010u) { - local_relay_protocol_ = from.local_relay_protocol_; - } - if (cached_has_bits & 0x00000020u) { - local_network_type_ = from.local_network_type_; - } - if (cached_has_bits & 0x00000040u) { - local_address_family_ = from.local_address_family_; - } - if (cached_has_bits & 0x00000080u) { - remote_candidate_type_ = from.remote_candidate_type_; - } - _has_bits_[0] |= cached_has_bits; - } - if (cached_has_bits & 0x00000300u) { - if (cached_has_bits & 0x00000100u) { - remote_address_family_ = from.remote_address_family_; - } - if (cached_has_bits & 0x00000200u) { - candidate_pair_protocol_ = from.candidate_pair_protocol_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void IceCandidatePairConfig::CopyFrom(const IceCandidatePairConfig& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.IceCandidatePairConfig) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool IceCandidatePairConfig::IsInitialized() const { - return true; -} - -void IceCandidatePairConfig::InternalSwap(IceCandidatePairConfig* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(config_type_, other->config_type_); - swap(candidate_pair_id_, other->candidate_pair_id_); - swap(local_candidate_type_, other->local_candidate_type_); - swap(local_relay_protocol_, other->local_relay_protocol_); - swap(local_network_type_, other->local_network_type_); - swap(local_address_family_, other->local_address_family_); - swap(remote_candidate_type_, other->remote_candidate_type_); - swap(remote_address_family_, other->remote_address_family_); - swap(candidate_pair_protocol_, other->candidate_pair_protocol_); -} - -std::string IceCandidatePairConfig::GetTypeName() const { - return "webrtc.rtclog2.IceCandidatePairConfig"; -} - - -// =================================================================== - -void IceCandidatePairEvent::InitAsDefaultInstance() { -} -class IceCandidatePairEvent::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_event_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_candidate_pair_id(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_transaction_id(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } -}; - -IceCandidatePairEvent::IceCandidatePairEvent() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.IceCandidatePairEvent) -} -IceCandidatePairEvent::IceCandidatePairEvent(const IceCandidatePairEvent& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&transaction_id_) - - reinterpret_cast(×tamp_ms_)) + sizeof(transaction_id_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.IceCandidatePairEvent) -} - -void IceCandidatePairEvent::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&transaction_id_) - - reinterpret_cast(×tamp_ms_)) + sizeof(transaction_id_)); -} - -IceCandidatePairEvent::~IceCandidatePairEvent() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.IceCandidatePairEvent) - SharedDtor(); -} - -void IceCandidatePairEvent::SharedDtor() { -} - -void IceCandidatePairEvent::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const IceCandidatePairEvent& IceCandidatePairEvent::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_IceCandidatePairEvent_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void IceCandidatePairEvent::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.IceCandidatePairEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&transaction_id_) - - reinterpret_cast(×tamp_ms_)) + sizeof(transaction_id_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* IceCandidatePairEvent::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.IceCandidatePairEvent.IceCandidatePairEventType event_type = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType_IsValid(val))) { - set_event_type(static_cast<::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(2, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - // optional uint32 candidate_pair_id = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_candidate_pair_id(&has_bits); - candidate_pair_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 transaction_id = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_transaction_id(&has_bits); - transaction_id_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool IceCandidatePairEvent::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.IceCandidatePairEvent) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.IceCandidatePairEvent.IceCandidatePairEventType event_type = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType_IsValid(value)) { - set_event_type(static_cast< ::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType >(value)); - } else { - unknown_fields_stream.WriteVarint32(16u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 candidate_pair_id = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_candidate_pair_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &candidate_pair_id_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 transaction_id = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_transaction_id(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &transaction_id_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.IceCandidatePairEvent) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.IceCandidatePairEvent) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void IceCandidatePairEvent::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.IceCandidatePairEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional .webrtc.rtclog2.IceCandidatePairEvent.IceCandidatePairEventType event_type = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 2, this->event_type(), output); - } - - // optional uint32 candidate_pair_id = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->candidate_pair_id(), output); - } - - // optional uint32 transaction_id = 4; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->transaction_id(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.IceCandidatePairEvent) -} - -size_t IceCandidatePairEvent::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.IceCandidatePairEvent) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional .webrtc.rtclog2.IceCandidatePairEvent.IceCandidatePairEventType event_type = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->event_type()); - } - - // optional uint32 candidate_pair_id = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->candidate_pair_id()); - } - - // optional uint32 transaction_id = 4; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->transaction_id()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void IceCandidatePairEvent::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void IceCandidatePairEvent::MergeFrom(const IceCandidatePairEvent& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.IceCandidatePairEvent) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000000fu) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - event_type_ = from.event_type_; - } - if (cached_has_bits & 0x00000004u) { - candidate_pair_id_ = from.candidate_pair_id_; - } - if (cached_has_bits & 0x00000008u) { - transaction_id_ = from.transaction_id_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void IceCandidatePairEvent::CopyFrom(const IceCandidatePairEvent& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.IceCandidatePairEvent) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool IceCandidatePairEvent::IsInitialized() const { - return true; -} - -void IceCandidatePairEvent::InternalSwap(IceCandidatePairEvent* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(event_type_, other->event_type_); - swap(candidate_pair_id_, other->candidate_pair_id_); - swap(transaction_id_, other->transaction_id_); -} - -std::string IceCandidatePairEvent::GetTypeName() const { - return "webrtc.rtclog2.IceCandidatePairEvent"; -} - - -// =================================================================== - -void DtlsTransportStateEvent::InitAsDefaultInstance() { -} -class DtlsTransportStateEvent::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_dtls_transport_state(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -DtlsTransportStateEvent::DtlsTransportStateEvent() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.DtlsTransportStateEvent) -} -DtlsTransportStateEvent::DtlsTransportStateEvent(const DtlsTransportStateEvent& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&dtls_transport_state_) - - reinterpret_cast(×tamp_ms_)) + sizeof(dtls_transport_state_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.DtlsTransportStateEvent) -} - -void DtlsTransportStateEvent::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&dtls_transport_state_) - - reinterpret_cast(×tamp_ms_)) + sizeof(dtls_transport_state_)); -} - -DtlsTransportStateEvent::~DtlsTransportStateEvent() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.DtlsTransportStateEvent) - SharedDtor(); -} - -void DtlsTransportStateEvent::SharedDtor() { -} - -void DtlsTransportStateEvent::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const DtlsTransportStateEvent& DtlsTransportStateEvent::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_DtlsTransportStateEvent_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void DtlsTransportStateEvent::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.DtlsTransportStateEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&dtls_transport_state_) - - reinterpret_cast(×tamp_ms_)) + sizeof(dtls_transport_state_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* DtlsTransportStateEvent::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional .webrtc.rtclog2.DtlsTransportStateEvent.DtlsTransportState dtls_transport_state = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - if (PROTOBUF_PREDICT_TRUE(::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState_IsValid(val))) { - set_dtls_transport_state(static_cast<::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState>(val)); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(2, val, mutable_unknown_fields()); - } - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool DtlsTransportStateEvent::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.DtlsTransportStateEvent) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional .webrtc.rtclog2.DtlsTransportStateEvent.DtlsTransportState dtls_transport_state = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - int value = 0; - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState_IsValid(value)) { - set_dtls_transport_state(static_cast< ::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState >(value)); - } else { - unknown_fields_stream.WriteVarint32(16u); - unknown_fields_stream.WriteVarint32( - static_cast<::PROTOBUF_NAMESPACE_ID::uint32>(value)); - } - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.DtlsTransportStateEvent) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.DtlsTransportStateEvent) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void DtlsTransportStateEvent::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.DtlsTransportStateEvent) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional .webrtc.rtclog2.DtlsTransportStateEvent.DtlsTransportState dtls_transport_state = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum( - 2, this->dtls_transport_state(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.DtlsTransportStateEvent) -} - -size_t DtlsTransportStateEvent::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.DtlsTransportStateEvent) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional .webrtc.rtclog2.DtlsTransportStateEvent.DtlsTransportState dtls_transport_state = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->dtls_transport_state()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void DtlsTransportStateEvent::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void DtlsTransportStateEvent::MergeFrom(const DtlsTransportStateEvent& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.DtlsTransportStateEvent) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - dtls_transport_state_ = from.dtls_transport_state_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void DtlsTransportStateEvent::CopyFrom(const DtlsTransportStateEvent& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.DtlsTransportStateEvent) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DtlsTransportStateEvent::IsInitialized() const { - return true; -} - -void DtlsTransportStateEvent::InternalSwap(DtlsTransportStateEvent* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(dtls_transport_state_, other->dtls_transport_state_); -} - -std::string DtlsTransportStateEvent::GetTypeName() const { - return "webrtc.rtclog2.DtlsTransportStateEvent"; -} - - -// =================================================================== - -void DtlsWritableState::InitAsDefaultInstance() { -} -class DtlsWritableState::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_writable(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -DtlsWritableState::DtlsWritableState() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.DtlsWritableState) -} -DtlsWritableState::DtlsWritableState(const DtlsWritableState& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&writable_) - - reinterpret_cast(×tamp_ms_)) + sizeof(writable_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.DtlsWritableState) -} - -void DtlsWritableState::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&writable_) - - reinterpret_cast(×tamp_ms_)) + sizeof(writable_)); -} - -DtlsWritableState::~DtlsWritableState() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.DtlsWritableState) - SharedDtor(); -} - -void DtlsWritableState::SharedDtor() { -} - -void DtlsWritableState::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const DtlsWritableState& DtlsWritableState::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_DtlsWritableState_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void DtlsWritableState::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.DtlsWritableState) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&writable_) - - reinterpret_cast(×tamp_ms_)) + sizeof(writable_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* DtlsWritableState::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool writable = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_writable(&has_bits); - writable_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool DtlsWritableState::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.DtlsWritableState) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool writable = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_writable(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &writable_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.DtlsWritableState) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.DtlsWritableState) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void DtlsWritableState::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.DtlsWritableState) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional bool writable = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(2, this->writable(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.DtlsWritableState) -} - -size_t DtlsWritableState::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.DtlsWritableState) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional bool writable = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + 1; - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void DtlsWritableState::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void DtlsWritableState::MergeFrom(const DtlsWritableState& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.DtlsWritableState) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - writable_ = from.writable_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void DtlsWritableState::CopyFrom(const DtlsWritableState& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.DtlsWritableState) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DtlsWritableState::IsInitialized() const { - return true; -} - -void DtlsWritableState::InternalSwap(DtlsWritableState* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(writable_, other->writable_); -} - -std::string DtlsWritableState::GetTypeName() const { - return "webrtc.rtclog2.DtlsWritableState"; -} - - -// =================================================================== - -void RouteChange::InitAsDefaultInstance() { -} -class RouteChange::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_connected(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_overhead(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -RouteChange::RouteChange() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.RouteChange) -} -RouteChange::RouteChange(const RouteChange& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&overhead_) - - reinterpret_cast(×tamp_ms_)) + sizeof(overhead_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.RouteChange) -} - -void RouteChange::SharedCtor() { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&overhead_) - - reinterpret_cast(×tamp_ms_)) + sizeof(overhead_)); -} - -RouteChange::~RouteChange() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.RouteChange) - SharedDtor(); -} - -void RouteChange::SharedDtor() { -} - -void RouteChange::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const RouteChange& RouteChange::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_RouteChange_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void RouteChange::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.RouteChange) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&overhead_) - - reinterpret_cast(×tamp_ms_)) + sizeof(overhead_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* RouteChange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bool connected = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_connected(&has_bits); - connected_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 overhead = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_overhead(&has_bits); - overhead_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool RouteChange::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.RouteChange) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bool connected = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_connected(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - bool, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_BOOL>( - input, &connected_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 overhead = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_overhead(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &overhead_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.RouteChange) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.RouteChange) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void RouteChange::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.RouteChange) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional bool connected = 2; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBool(2, this->connected(), output); - } - - // optional uint32 overhead = 3; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->overhead(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.RouteChange) -} - -size_t RouteChange::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.RouteChange) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional bool connected = 2; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + 1; - } - - // optional uint32 overhead = 3; - if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->overhead()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void RouteChange::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void RouteChange::MergeFrom(const RouteChange& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.RouteChange) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000002u) { - connected_ = from.connected_; - } - if (cached_has_bits & 0x00000004u) { - overhead_ = from.overhead_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void RouteChange::CopyFrom(const RouteChange& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.RouteChange) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RouteChange::IsInitialized() const { - return true; -} - -void RouteChange::InternalSwap(RouteChange* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - swap(timestamp_ms_, other->timestamp_ms_); - swap(connected_, other->connected_); - swap(overhead_, other->overhead_); -} - -std::string RouteChange::GetTypeName() const { - return "webrtc.rtclog2.RouteChange"; -} - - -// =================================================================== - -void RemoteEstimates::InitAsDefaultInstance() { -} -class RemoteEstimates::_Internal { - public: - using HasBits = decltype(std::declval()._has_bits_); - static void set_has_timestamp_ms(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_link_capacity_lower_kbps(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_link_capacity_upper_kbps(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_number_of_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_timestamp_ms_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_link_capacity_lower_kbps_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_link_capacity_upper_kbps_deltas(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } -}; - -RemoteEstimates::RemoteEstimates() - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:webrtc.rtclog2.RemoteEstimates) -} -RemoteEstimates::RemoteEstimates(const RemoteEstimates& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_timestamp_ms_deltas()) { - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - link_capacity_lower_kbps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_link_capacity_lower_kbps_deltas()) { - link_capacity_lower_kbps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.link_capacity_lower_kbps_deltas_); - } - link_capacity_upper_kbps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (from.has_link_capacity_upper_kbps_deltas()) { - link_capacity_upper_kbps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.link_capacity_upper_kbps_deltas_); - } - ::memcpy(×tamp_ms_, &from.timestamp_ms_, - static_cast(reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - // @@protoc_insertion_point(copy_constructor:webrtc.rtclog2.RemoteEstimates) -} - -void RemoteEstimates::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_RemoteEstimates_rtc_5fevent_5flog2_2eproto.base); - timestamp_ms_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - link_capacity_lower_kbps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - link_capacity_upper_kbps_deltas_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); -} - -RemoteEstimates::~RemoteEstimates() { - // @@protoc_insertion_point(destructor:webrtc.rtclog2.RemoteEstimates) - SharedDtor(); -} - -void RemoteEstimates::SharedDtor() { - timestamp_ms_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - link_capacity_lower_kbps_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - link_capacity_upper_kbps_deltas_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} - -void RemoteEstimates::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const RemoteEstimates& RemoteEstimates::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_RemoteEstimates_rtc_5fevent_5flog2_2eproto.base); - return *internal_default_instance(); -} - - -void RemoteEstimates::Clear() { -// @@protoc_insertion_point(message_clear_start:webrtc.rtclog2.RemoteEstimates) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { - if (cached_has_bits & 0x00000001u) { - timestamp_ms_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000002u) { - link_capacity_lower_kbps_deltas_.ClearNonDefaultToEmptyNoArena(); - } - if (cached_has_bits & 0x00000004u) { - link_capacity_upper_kbps_deltas_.ClearNonDefaultToEmptyNoArena(); - } - } - if (cached_has_bits & 0x00000078u) { - ::memset(×tamp_ms_, 0, static_cast( - reinterpret_cast(&number_of_deltas_) - - reinterpret_cast(×tamp_ms_)) + sizeof(number_of_deltas_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -const char* RemoteEstimates::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - CHK_(ptr); - switch (tag >> 3) { - // optional int64 timestamp_ms = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { - _Internal::set_has_timestamp_ms(&has_bits); - timestamp_ms_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 link_capacity_lower_kbps = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { - _Internal::set_has_link_capacity_lower_kbps(&has_bits); - link_capacity_lower_kbps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 link_capacity_upper_kbps = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { - _Internal::set_has_link_capacity_upper_kbps(&has_bits); - link_capacity_upper_kbps_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional uint32 number_of_deltas = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { - _Internal::set_has_number_of_deltas(&has_bits); - number_of_deltas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes timestamp_ms_deltas = 101; - case 101: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_timestamp_ms_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes link_capacity_lower_kbps_deltas = 102; - case 102: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_link_capacity_lower_kbps_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - // optional bytes link_capacity_upper_kbps_deltas = 103; - case 103: - if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(mutable_link_capacity_upper_kbps_deltas(), ptr, ctx); - CHK_(ptr); - } else goto handle_unusual; - continue; - default: { - handle_unusual: - if ((tag & 7) == 4 || tag == 0) { - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); - CHK_(ptr != nullptr); - continue; - } - } // switch - } // while -success: - _has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} -#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER -bool RemoteEstimates::MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ::PROTOBUF_NAMESPACE_ID::internal::LiteUnknownFieldSetter unknown_fields_setter( - &_internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::io::StringOutputStream unknown_fields_output( - unknown_fields_setter.buffer()); - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream unknown_fields_stream( - &unknown_fields_output, false); - // @@protoc_insertion_point(parse_start:webrtc.rtclog2.RemoteEstimates) - for (;;) { - ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int64 timestamp_ms = 1; - case 1: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) { - _Internal::set_has_timestamp_ms(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::int64, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT64>( - input, ×tamp_ms_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 link_capacity_lower_kbps = 2; - case 2: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { - _Internal::set_has_link_capacity_lower_kbps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &link_capacity_lower_kbps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 link_capacity_upper_kbps = 3; - case 3: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) { - _Internal::set_has_link_capacity_upper_kbps(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &link_capacity_upper_kbps_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint32 number_of_deltas = 4; - case 4: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (32 & 0xFF)) { - _Internal::set_has_number_of_deltas(&_has_bits_); - DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< - ::PROTOBUF_NAMESPACE_ID::uint32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT32>( - input, &number_of_deltas_))); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes timestamp_ms_deltas = 101; - case 101: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (810 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_timestamp_ms_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes link_capacity_lower_kbps_deltas = 102; - case 102: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (818 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_link_capacity_lower_kbps_deltas())); - } else { - goto handle_unusual; - } - break; - } - - // optional bytes link_capacity_upper_kbps_deltas = 103; - case 103: { - if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (826 & 0xFF)) { - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadBytes( - input, this->mutable_link_capacity_upper_kbps_deltas())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SkipField( - input, tag, &unknown_fields_stream)); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:webrtc.rtclog2.RemoteEstimates) - return true; -failure: - // @@protoc_insertion_point(parse_failure:webrtc.rtclog2.RemoteEstimates) - return false; -#undef DO_ -} -#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - -void RemoteEstimates::SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:webrtc.rtclog2.RemoteEstimates) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64(1, this->timestamp_ms(), output); - } - - // optional uint32 link_capacity_lower_kbps = 2; - if (cached_has_bits & 0x00000010u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(2, this->link_capacity_lower_kbps(), output); - } - - // optional uint32 link_capacity_upper_kbps = 3; - if (cached_has_bits & 0x00000020u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(3, this->link_capacity_upper_kbps(), output); - } - - // optional uint32 number_of_deltas = 4; - if (cached_has_bits & 0x00000040u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32(4, this->number_of_deltas(), output); - } - - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 101, this->timestamp_ms_deltas(), output); - } - - // optional bytes link_capacity_lower_kbps_deltas = 102; - if (cached_has_bits & 0x00000002u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 102, this->link_capacity_lower_kbps_deltas(), output); - } - - // optional bytes link_capacity_upper_kbps_deltas = 103; - if (cached_has_bits & 0x00000004u) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBytesMaybeAliased( - 103, this->link_capacity_upper_kbps_deltas(), output); - } - - output->WriteRaw(_internal_metadata_.unknown_fields().data(), - static_cast(_internal_metadata_.unknown_fields().size())); - // @@protoc_insertion_point(serialize_end:webrtc.rtclog2.RemoteEstimates) -} - -size_t RemoteEstimates::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:webrtc.rtclog2.RemoteEstimates) - size_t total_size = 0; - - total_size += _internal_metadata_.unknown_fields().size(); - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x0000007fu) { - // optional bytes timestamp_ms_deltas = 101; - if (cached_has_bits & 0x00000001u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->timestamp_ms_deltas()); - } - - // optional bytes link_capacity_lower_kbps_deltas = 102; - if (cached_has_bits & 0x00000002u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->link_capacity_lower_kbps_deltas()); - } - - // optional bytes link_capacity_upper_kbps_deltas = 103; - if (cached_has_bits & 0x00000004u) { - total_size += 2 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( - this->link_capacity_upper_kbps_deltas()); - } - - // optional int64 timestamp_ms = 1; - if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->timestamp_ms()); - } - - // optional uint32 link_capacity_lower_kbps = 2; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->link_capacity_lower_kbps()); - } - - // optional uint32 link_capacity_upper_kbps = 3; - if (cached_has_bits & 0x00000020u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->link_capacity_upper_kbps()); - } - - // optional uint32 number_of_deltas = 4; - if (cached_has_bits & 0x00000040u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->number_of_deltas()); - } - - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void RemoteEstimates::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast( - &from)); -} - -void RemoteEstimates::MergeFrom(const RemoteEstimates& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:webrtc.rtclog2.RemoteEstimates) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x0000007fu) { - if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.timestamp_ms_deltas_); - } - if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - link_capacity_lower_kbps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.link_capacity_lower_kbps_deltas_); - } - if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - link_capacity_upper_kbps_deltas_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.link_capacity_upper_kbps_deltas_); - } - if (cached_has_bits & 0x00000008u) { - timestamp_ms_ = from.timestamp_ms_; - } - if (cached_has_bits & 0x00000010u) { - link_capacity_lower_kbps_ = from.link_capacity_lower_kbps_; - } - if (cached_has_bits & 0x00000020u) { - link_capacity_upper_kbps_ = from.link_capacity_upper_kbps_; - } - if (cached_has_bits & 0x00000040u) { - number_of_deltas_ = from.number_of_deltas_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void RemoteEstimates::CopyFrom(const RemoteEstimates& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:webrtc.rtclog2.RemoteEstimates) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RemoteEstimates::IsInitialized() const { - return true; -} - -void RemoteEstimates::InternalSwap(RemoteEstimates* other) { - using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - timestamp_ms_deltas_.Swap(&other->timestamp_ms_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - link_capacity_lower_kbps_deltas_.Swap(&other->link_capacity_lower_kbps_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - link_capacity_upper_kbps_deltas_.Swap(&other->link_capacity_upper_kbps_deltas_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(timestamp_ms_, other->timestamp_ms_); - swap(link_capacity_lower_kbps_, other->link_capacity_lower_kbps_); - swap(link_capacity_upper_kbps_, other->link_capacity_upper_kbps_); - swap(number_of_deltas_, other->number_of_deltas_); -} - -std::string RemoteEstimates::GetTypeName() const { - return "webrtc.rtclog2.RemoteEstimates"; -} - - -// @@protoc_insertion_point(namespace_scope) -} // namespace rtclog2 -} // namespace webrtc -PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::EventStream* Arena::CreateMaybeMessage< ::webrtc::rtclog2::EventStream >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::EventStream >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::Event* Arena::CreateMaybeMessage< ::webrtc::rtclog2::Event >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::Event >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::GenericPacketReceived* Arena::CreateMaybeMessage< ::webrtc::rtclog2::GenericPacketReceived >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::GenericPacketReceived >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::GenericPacketSent* Arena::CreateMaybeMessage< ::webrtc::rtclog2::GenericPacketSent >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::GenericPacketSent >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::GenericAckReceived* Arena::CreateMaybeMessage< ::webrtc::rtclog2::GenericAckReceived >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::GenericAckReceived >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::IncomingRtpPackets* Arena::CreateMaybeMessage< ::webrtc::rtclog2::IncomingRtpPackets >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::IncomingRtpPackets >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::OutgoingRtpPackets* Arena::CreateMaybeMessage< ::webrtc::rtclog2::OutgoingRtpPackets >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::OutgoingRtpPackets >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::IncomingRtcpPackets* Arena::CreateMaybeMessage< ::webrtc::rtclog2::IncomingRtcpPackets >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::IncomingRtcpPackets >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::OutgoingRtcpPackets* Arena::CreateMaybeMessage< ::webrtc::rtclog2::OutgoingRtcpPackets >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::OutgoingRtcpPackets >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::AudioPlayoutEvents* Arena::CreateMaybeMessage< ::webrtc::rtclog2::AudioPlayoutEvents >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::AudioPlayoutEvents >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::FrameDecodedEvents* Arena::CreateMaybeMessage< ::webrtc::rtclog2::FrameDecodedEvents >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::FrameDecodedEvents >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::BeginLogEvent* Arena::CreateMaybeMessage< ::webrtc::rtclog2::BeginLogEvent >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::BeginLogEvent >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::EndLogEvent* Arena::CreateMaybeMessage< ::webrtc::rtclog2::EndLogEvent >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::EndLogEvent >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::LossBasedBweUpdates* Arena::CreateMaybeMessage< ::webrtc::rtclog2::LossBasedBweUpdates >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::LossBasedBweUpdates >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::DelayBasedBweUpdates* Arena::CreateMaybeMessage< ::webrtc::rtclog2::DelayBasedBweUpdates >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::DelayBasedBweUpdates >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::RtpHeaderExtensionConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog2::RtpHeaderExtensionConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::RtpHeaderExtensionConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::VideoRecvStreamConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog2::VideoRecvStreamConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::VideoRecvStreamConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::VideoSendStreamConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog2::VideoSendStreamConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::VideoSendStreamConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::AudioRecvStreamConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog2::AudioRecvStreamConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::AudioRecvStreamConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::AudioSendStreamConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog2::AudioSendStreamConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::AudioSendStreamConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::AudioNetworkAdaptations* Arena::CreateMaybeMessage< ::webrtc::rtclog2::AudioNetworkAdaptations >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::AudioNetworkAdaptations >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::BweProbeCluster* Arena::CreateMaybeMessage< ::webrtc::rtclog2::BweProbeCluster >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::BweProbeCluster >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::BweProbeResultSuccess* Arena::CreateMaybeMessage< ::webrtc::rtclog2::BweProbeResultSuccess >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::BweProbeResultSuccess >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::BweProbeResultFailure* Arena::CreateMaybeMessage< ::webrtc::rtclog2::BweProbeResultFailure >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::BweProbeResultFailure >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::AlrState* Arena::CreateMaybeMessage< ::webrtc::rtclog2::AlrState >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::AlrState >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::IceCandidatePairConfig* Arena::CreateMaybeMessage< ::webrtc::rtclog2::IceCandidatePairConfig >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::IceCandidatePairConfig >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::IceCandidatePairEvent* Arena::CreateMaybeMessage< ::webrtc::rtclog2::IceCandidatePairEvent >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::IceCandidatePairEvent >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::DtlsTransportStateEvent* Arena::CreateMaybeMessage< ::webrtc::rtclog2::DtlsTransportStateEvent >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::DtlsTransportStateEvent >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::DtlsWritableState* Arena::CreateMaybeMessage< ::webrtc::rtclog2::DtlsWritableState >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::DtlsWritableState >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::RouteChange* Arena::CreateMaybeMessage< ::webrtc::rtclog2::RouteChange >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::RouteChange >(arena); -} -template<> PROTOBUF_NOINLINE ::webrtc::rtclog2::RemoteEstimates* Arena::CreateMaybeMessage< ::webrtc::rtclog2::RemoteEstimates >(Arena* arena) { - return Arena::CreateInternal< ::webrtc::rtclog2::RemoteEstimates >(arena); -} -PROTOBUF_NAMESPACE_CLOSE - -// @@protoc_insertion_point(global_scope) -#include diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h deleted file mode 100644 index a6291e618..000000000 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h +++ /dev/null @@ -1,14921 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: rtc_event_log2.proto - -#ifndef GOOGLE_PROTOBUF_INCLUDED_rtc_5fevent_5flog2_2eproto -#define GOOGLE_PROTOBUF_INCLUDED_rtc_5fevent_5flog2_2eproto - -#include -#include - -#include -#if PROTOBUF_VERSION < 3009000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3009000 < PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: export -#include // IWYU pragma: export -#include -// @@protoc_insertion_point(includes) -#include -#define PROTOBUF_INTERNAL_EXPORT_rtc_5fevent_5flog2_2eproto -PROTOBUF_NAMESPACE_OPEN -namespace internal { -class AnyMetadata; -} // namespace internal -PROTOBUF_NAMESPACE_CLOSE - -// Internal implementation detail -- do not use these members. -struct TableStruct_rtc_5fevent_5flog2_2eproto { - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[31] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; - static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[]; -}; -namespace webrtc { -namespace rtclog2 { -class AlrState; -class AlrStateDefaultTypeInternal; -extern AlrStateDefaultTypeInternal _AlrState_default_instance_; -class AudioNetworkAdaptations; -class AudioNetworkAdaptationsDefaultTypeInternal; -extern AudioNetworkAdaptationsDefaultTypeInternal _AudioNetworkAdaptations_default_instance_; -class AudioPlayoutEvents; -class AudioPlayoutEventsDefaultTypeInternal; -extern AudioPlayoutEventsDefaultTypeInternal _AudioPlayoutEvents_default_instance_; -class AudioRecvStreamConfig; -class AudioRecvStreamConfigDefaultTypeInternal; -extern AudioRecvStreamConfigDefaultTypeInternal _AudioRecvStreamConfig_default_instance_; -class AudioSendStreamConfig; -class AudioSendStreamConfigDefaultTypeInternal; -extern AudioSendStreamConfigDefaultTypeInternal _AudioSendStreamConfig_default_instance_; -class BeginLogEvent; -class BeginLogEventDefaultTypeInternal; -extern BeginLogEventDefaultTypeInternal _BeginLogEvent_default_instance_; -class BweProbeCluster; -class BweProbeClusterDefaultTypeInternal; -extern BweProbeClusterDefaultTypeInternal _BweProbeCluster_default_instance_; -class BweProbeResultFailure; -class BweProbeResultFailureDefaultTypeInternal; -extern BweProbeResultFailureDefaultTypeInternal _BweProbeResultFailure_default_instance_; -class BweProbeResultSuccess; -class BweProbeResultSuccessDefaultTypeInternal; -extern BweProbeResultSuccessDefaultTypeInternal _BweProbeResultSuccess_default_instance_; -class DelayBasedBweUpdates; -class DelayBasedBweUpdatesDefaultTypeInternal; -extern DelayBasedBweUpdatesDefaultTypeInternal _DelayBasedBweUpdates_default_instance_; -class DtlsTransportStateEvent; -class DtlsTransportStateEventDefaultTypeInternal; -extern DtlsTransportStateEventDefaultTypeInternal _DtlsTransportStateEvent_default_instance_; -class DtlsWritableState; -class DtlsWritableStateDefaultTypeInternal; -extern DtlsWritableStateDefaultTypeInternal _DtlsWritableState_default_instance_; -class EndLogEvent; -class EndLogEventDefaultTypeInternal; -extern EndLogEventDefaultTypeInternal _EndLogEvent_default_instance_; -class Event; -class EventDefaultTypeInternal; -extern EventDefaultTypeInternal _Event_default_instance_; -class EventStream; -class EventStreamDefaultTypeInternal; -extern EventStreamDefaultTypeInternal _EventStream_default_instance_; -class FrameDecodedEvents; -class FrameDecodedEventsDefaultTypeInternal; -extern FrameDecodedEventsDefaultTypeInternal _FrameDecodedEvents_default_instance_; -class GenericAckReceived; -class GenericAckReceivedDefaultTypeInternal; -extern GenericAckReceivedDefaultTypeInternal _GenericAckReceived_default_instance_; -class GenericPacketReceived; -class GenericPacketReceivedDefaultTypeInternal; -extern GenericPacketReceivedDefaultTypeInternal _GenericPacketReceived_default_instance_; -class GenericPacketSent; -class GenericPacketSentDefaultTypeInternal; -extern GenericPacketSentDefaultTypeInternal _GenericPacketSent_default_instance_; -class IceCandidatePairConfig; -class IceCandidatePairConfigDefaultTypeInternal; -extern IceCandidatePairConfigDefaultTypeInternal _IceCandidatePairConfig_default_instance_; -class IceCandidatePairEvent; -class IceCandidatePairEventDefaultTypeInternal; -extern IceCandidatePairEventDefaultTypeInternal _IceCandidatePairEvent_default_instance_; -class IncomingRtcpPackets; -class IncomingRtcpPacketsDefaultTypeInternal; -extern IncomingRtcpPacketsDefaultTypeInternal _IncomingRtcpPackets_default_instance_; -class IncomingRtpPackets; -class IncomingRtpPacketsDefaultTypeInternal; -extern IncomingRtpPacketsDefaultTypeInternal _IncomingRtpPackets_default_instance_; -class LossBasedBweUpdates; -class LossBasedBweUpdatesDefaultTypeInternal; -extern LossBasedBweUpdatesDefaultTypeInternal _LossBasedBweUpdates_default_instance_; -class OutgoingRtcpPackets; -class OutgoingRtcpPacketsDefaultTypeInternal; -extern OutgoingRtcpPacketsDefaultTypeInternal _OutgoingRtcpPackets_default_instance_; -class OutgoingRtpPackets; -class OutgoingRtpPacketsDefaultTypeInternal; -extern OutgoingRtpPacketsDefaultTypeInternal _OutgoingRtpPackets_default_instance_; -class RemoteEstimates; -class RemoteEstimatesDefaultTypeInternal; -extern RemoteEstimatesDefaultTypeInternal _RemoteEstimates_default_instance_; -class RouteChange; -class RouteChangeDefaultTypeInternal; -extern RouteChangeDefaultTypeInternal _RouteChange_default_instance_; -class RtpHeaderExtensionConfig; -class RtpHeaderExtensionConfigDefaultTypeInternal; -extern RtpHeaderExtensionConfigDefaultTypeInternal _RtpHeaderExtensionConfig_default_instance_; -class VideoRecvStreamConfig; -class VideoRecvStreamConfigDefaultTypeInternal; -extern VideoRecvStreamConfigDefaultTypeInternal _VideoRecvStreamConfig_default_instance_; -class VideoSendStreamConfig; -class VideoSendStreamConfigDefaultTypeInternal; -extern VideoSendStreamConfigDefaultTypeInternal _VideoSendStreamConfig_default_instance_; -} // namespace rtclog2 -} // namespace webrtc -PROTOBUF_NAMESPACE_OPEN -template<> ::webrtc::rtclog2::AlrState* Arena::CreateMaybeMessage<::webrtc::rtclog2::AlrState>(Arena*); -template<> ::webrtc::rtclog2::AudioNetworkAdaptations* Arena::CreateMaybeMessage<::webrtc::rtclog2::AudioNetworkAdaptations>(Arena*); -template<> ::webrtc::rtclog2::AudioPlayoutEvents* Arena::CreateMaybeMessage<::webrtc::rtclog2::AudioPlayoutEvents>(Arena*); -template<> ::webrtc::rtclog2::AudioRecvStreamConfig* Arena::CreateMaybeMessage<::webrtc::rtclog2::AudioRecvStreamConfig>(Arena*); -template<> ::webrtc::rtclog2::AudioSendStreamConfig* Arena::CreateMaybeMessage<::webrtc::rtclog2::AudioSendStreamConfig>(Arena*); -template<> ::webrtc::rtclog2::BeginLogEvent* Arena::CreateMaybeMessage<::webrtc::rtclog2::BeginLogEvent>(Arena*); -template<> ::webrtc::rtclog2::BweProbeCluster* Arena::CreateMaybeMessage<::webrtc::rtclog2::BweProbeCluster>(Arena*); -template<> ::webrtc::rtclog2::BweProbeResultFailure* Arena::CreateMaybeMessage<::webrtc::rtclog2::BweProbeResultFailure>(Arena*); -template<> ::webrtc::rtclog2::BweProbeResultSuccess* Arena::CreateMaybeMessage<::webrtc::rtclog2::BweProbeResultSuccess>(Arena*); -template<> ::webrtc::rtclog2::DelayBasedBweUpdates* Arena::CreateMaybeMessage<::webrtc::rtclog2::DelayBasedBweUpdates>(Arena*); -template<> ::webrtc::rtclog2::DtlsTransportStateEvent* Arena::CreateMaybeMessage<::webrtc::rtclog2::DtlsTransportStateEvent>(Arena*); -template<> ::webrtc::rtclog2::DtlsWritableState* Arena::CreateMaybeMessage<::webrtc::rtclog2::DtlsWritableState>(Arena*); -template<> ::webrtc::rtclog2::EndLogEvent* Arena::CreateMaybeMessage<::webrtc::rtclog2::EndLogEvent>(Arena*); -template<> ::webrtc::rtclog2::Event* Arena::CreateMaybeMessage<::webrtc::rtclog2::Event>(Arena*); -template<> ::webrtc::rtclog2::EventStream* Arena::CreateMaybeMessage<::webrtc::rtclog2::EventStream>(Arena*); -template<> ::webrtc::rtclog2::FrameDecodedEvents* Arena::CreateMaybeMessage<::webrtc::rtclog2::FrameDecodedEvents>(Arena*); -template<> ::webrtc::rtclog2::GenericAckReceived* Arena::CreateMaybeMessage<::webrtc::rtclog2::GenericAckReceived>(Arena*); -template<> ::webrtc::rtclog2::GenericPacketReceived* Arena::CreateMaybeMessage<::webrtc::rtclog2::GenericPacketReceived>(Arena*); -template<> ::webrtc::rtclog2::GenericPacketSent* Arena::CreateMaybeMessage<::webrtc::rtclog2::GenericPacketSent>(Arena*); -template<> ::webrtc::rtclog2::IceCandidatePairConfig* Arena::CreateMaybeMessage<::webrtc::rtclog2::IceCandidatePairConfig>(Arena*); -template<> ::webrtc::rtclog2::IceCandidatePairEvent* Arena::CreateMaybeMessage<::webrtc::rtclog2::IceCandidatePairEvent>(Arena*); -template<> ::webrtc::rtclog2::IncomingRtcpPackets* Arena::CreateMaybeMessage<::webrtc::rtclog2::IncomingRtcpPackets>(Arena*); -template<> ::webrtc::rtclog2::IncomingRtpPackets* Arena::CreateMaybeMessage<::webrtc::rtclog2::IncomingRtpPackets>(Arena*); -template<> ::webrtc::rtclog2::LossBasedBweUpdates* Arena::CreateMaybeMessage<::webrtc::rtclog2::LossBasedBweUpdates>(Arena*); -template<> ::webrtc::rtclog2::OutgoingRtcpPackets* Arena::CreateMaybeMessage<::webrtc::rtclog2::OutgoingRtcpPackets>(Arena*); -template<> ::webrtc::rtclog2::OutgoingRtpPackets* Arena::CreateMaybeMessage<::webrtc::rtclog2::OutgoingRtpPackets>(Arena*); -template<> ::webrtc::rtclog2::RemoteEstimates* Arena::CreateMaybeMessage<::webrtc::rtclog2::RemoteEstimates>(Arena*); -template<> ::webrtc::rtclog2::RouteChange* Arena::CreateMaybeMessage<::webrtc::rtclog2::RouteChange>(Arena*); -template<> ::webrtc::rtclog2::RtpHeaderExtensionConfig* Arena::CreateMaybeMessage<::webrtc::rtclog2::RtpHeaderExtensionConfig>(Arena*); -template<> ::webrtc::rtclog2::VideoRecvStreamConfig* Arena::CreateMaybeMessage<::webrtc::rtclog2::VideoRecvStreamConfig>(Arena*); -template<> ::webrtc::rtclog2::VideoSendStreamConfig* Arena::CreateMaybeMessage<::webrtc::rtclog2::VideoSendStreamConfig>(Arena*); -PROTOBUF_NAMESPACE_CLOSE -namespace webrtc { -namespace rtclog2 { - -enum FrameDecodedEvents_Codec : int { - FrameDecodedEvents_Codec_CODEC_UNKNOWN = 0, - FrameDecodedEvents_Codec_CODEC_GENERIC = 1, - FrameDecodedEvents_Codec_CODEC_VP8 = 2, - FrameDecodedEvents_Codec_CODEC_VP9 = 3, - FrameDecodedEvents_Codec_CODEC_AV1 = 4, - FrameDecodedEvents_Codec_CODEC_H264 = 5, - FrameDecodedEvents_Codec_CODEC_H265 = 6 -}; -bool FrameDecodedEvents_Codec_IsValid(int value); -constexpr FrameDecodedEvents_Codec FrameDecodedEvents_Codec_Codec_MIN = FrameDecodedEvents_Codec_CODEC_UNKNOWN; -constexpr FrameDecodedEvents_Codec FrameDecodedEvents_Codec_Codec_MAX = FrameDecodedEvents_Codec_CODEC_H265; -constexpr int FrameDecodedEvents_Codec_Codec_ARRAYSIZE = FrameDecodedEvents_Codec_Codec_MAX + 1; - -const std::string& FrameDecodedEvents_Codec_Name(FrameDecodedEvents_Codec value); -template -inline const std::string& FrameDecodedEvents_Codec_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function FrameDecodedEvents_Codec_Name."); - return FrameDecodedEvents_Codec_Name(static_cast(enum_t_value)); -} -bool FrameDecodedEvents_Codec_Parse( - const std::string& name, FrameDecodedEvents_Codec* value); -enum DelayBasedBweUpdates_DetectorState : int { - DelayBasedBweUpdates_DetectorState_BWE_UNKNOWN_STATE = 0, - DelayBasedBweUpdates_DetectorState_BWE_NORMAL = 1, - DelayBasedBweUpdates_DetectorState_BWE_UNDERUSING = 2, - DelayBasedBweUpdates_DetectorState_BWE_OVERUSING = 3 -}; -bool DelayBasedBweUpdates_DetectorState_IsValid(int value); -constexpr DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates_DetectorState_DetectorState_MIN = DelayBasedBweUpdates_DetectorState_BWE_UNKNOWN_STATE; -constexpr DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates_DetectorState_DetectorState_MAX = DelayBasedBweUpdates_DetectorState_BWE_OVERUSING; -constexpr int DelayBasedBweUpdates_DetectorState_DetectorState_ARRAYSIZE = DelayBasedBweUpdates_DetectorState_DetectorState_MAX + 1; - -const std::string& DelayBasedBweUpdates_DetectorState_Name(DelayBasedBweUpdates_DetectorState value); -template -inline const std::string& DelayBasedBweUpdates_DetectorState_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function DelayBasedBweUpdates_DetectorState_Name."); - return DelayBasedBweUpdates_DetectorState_Name(static_cast(enum_t_value)); -} -bool DelayBasedBweUpdates_DetectorState_Parse( - const std::string& name, DelayBasedBweUpdates_DetectorState* value); -enum BweProbeResultFailure_FailureReason : int { - BweProbeResultFailure_FailureReason_UNKNOWN = 0, - BweProbeResultFailure_FailureReason_INVALID_SEND_RECEIVE_INTERVAL = 1, - BweProbeResultFailure_FailureReason_INVALID_SEND_RECEIVE_RATIO = 2, - BweProbeResultFailure_FailureReason_TIMEOUT = 3 -}; -bool BweProbeResultFailure_FailureReason_IsValid(int value); -constexpr BweProbeResultFailure_FailureReason BweProbeResultFailure_FailureReason_FailureReason_MIN = BweProbeResultFailure_FailureReason_UNKNOWN; -constexpr BweProbeResultFailure_FailureReason BweProbeResultFailure_FailureReason_FailureReason_MAX = BweProbeResultFailure_FailureReason_TIMEOUT; -constexpr int BweProbeResultFailure_FailureReason_FailureReason_ARRAYSIZE = BweProbeResultFailure_FailureReason_FailureReason_MAX + 1; - -const std::string& BweProbeResultFailure_FailureReason_Name(BweProbeResultFailure_FailureReason value); -template -inline const std::string& BweProbeResultFailure_FailureReason_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function BweProbeResultFailure_FailureReason_Name."); - return BweProbeResultFailure_FailureReason_Name(static_cast(enum_t_value)); -} -bool BweProbeResultFailure_FailureReason_Parse( - const std::string& name, BweProbeResultFailure_FailureReason* value); -enum IceCandidatePairConfig_IceCandidatePairConfigType : int { - IceCandidatePairConfig_IceCandidatePairConfigType_UNKNOWN_CONFIG_TYPE = 0, - IceCandidatePairConfig_IceCandidatePairConfigType_ADDED = 1, - IceCandidatePairConfig_IceCandidatePairConfigType_UPDATED = 2, - IceCandidatePairConfig_IceCandidatePairConfigType_DESTROYED = 3, - IceCandidatePairConfig_IceCandidatePairConfigType_SELECTED = 4 -}; -bool IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(int value); -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MIN = IceCandidatePairConfig_IceCandidatePairConfigType_UNKNOWN_CONFIG_TYPE; -constexpr IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MAX = IceCandidatePairConfig_IceCandidatePairConfigType_SELECTED; -constexpr int IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_ARRAYSIZE = IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MAX + 1; - -const std::string& IceCandidatePairConfig_IceCandidatePairConfigType_Name(IceCandidatePairConfig_IceCandidatePairConfigType value); -template -inline const std::string& IceCandidatePairConfig_IceCandidatePairConfigType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_IceCandidatePairConfigType_Name."); - return IceCandidatePairConfig_IceCandidatePairConfigType_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_IceCandidatePairConfigType_Parse( - const std::string& name, IceCandidatePairConfig_IceCandidatePairConfigType* value); -enum IceCandidatePairConfig_IceCandidateType : int { - IceCandidatePairConfig_IceCandidateType_UNKNOWN_CANDIDATE_TYPE = 0, - IceCandidatePairConfig_IceCandidateType_LOCAL = 1, - IceCandidatePairConfig_IceCandidateType_STUN = 2, - IceCandidatePairConfig_IceCandidateType_PRFLX = 3, - IceCandidatePairConfig_IceCandidateType_RELAY = 4 -}; -bool IceCandidatePairConfig_IceCandidateType_IsValid(int value); -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig_IceCandidateType_IceCandidateType_MIN = IceCandidatePairConfig_IceCandidateType_UNKNOWN_CANDIDATE_TYPE; -constexpr IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig_IceCandidateType_IceCandidateType_MAX = IceCandidatePairConfig_IceCandidateType_RELAY; -constexpr int IceCandidatePairConfig_IceCandidateType_IceCandidateType_ARRAYSIZE = IceCandidatePairConfig_IceCandidateType_IceCandidateType_MAX + 1; - -const std::string& IceCandidatePairConfig_IceCandidateType_Name(IceCandidatePairConfig_IceCandidateType value); -template -inline const std::string& IceCandidatePairConfig_IceCandidateType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_IceCandidateType_Name."); - return IceCandidatePairConfig_IceCandidateType_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_IceCandidateType_Parse( - const std::string& name, IceCandidatePairConfig_IceCandidateType* value); -enum IceCandidatePairConfig_Protocol : int { - IceCandidatePairConfig_Protocol_UNKNOWN_PROTOCOL = 0, - IceCandidatePairConfig_Protocol_UDP = 1, - IceCandidatePairConfig_Protocol_TCP = 2, - IceCandidatePairConfig_Protocol_SSLTCP = 3, - IceCandidatePairConfig_Protocol_TLS = 4 -}; -bool IceCandidatePairConfig_Protocol_IsValid(int value); -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig_Protocol_Protocol_MIN = IceCandidatePairConfig_Protocol_UNKNOWN_PROTOCOL; -constexpr IceCandidatePairConfig_Protocol IceCandidatePairConfig_Protocol_Protocol_MAX = IceCandidatePairConfig_Protocol_TLS; -constexpr int IceCandidatePairConfig_Protocol_Protocol_ARRAYSIZE = IceCandidatePairConfig_Protocol_Protocol_MAX + 1; - -const std::string& IceCandidatePairConfig_Protocol_Name(IceCandidatePairConfig_Protocol value); -template -inline const std::string& IceCandidatePairConfig_Protocol_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_Protocol_Name."); - return IceCandidatePairConfig_Protocol_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_Protocol_Parse( - const std::string& name, IceCandidatePairConfig_Protocol* value); -enum IceCandidatePairConfig_AddressFamily : int { - IceCandidatePairConfig_AddressFamily_UNKNOWN_ADDRESS_FAMILY = 0, - IceCandidatePairConfig_AddressFamily_IPV4 = 1, - IceCandidatePairConfig_AddressFamily_IPV6 = 2 -}; -bool IceCandidatePairConfig_AddressFamily_IsValid(int value); -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig_AddressFamily_AddressFamily_MIN = IceCandidatePairConfig_AddressFamily_UNKNOWN_ADDRESS_FAMILY; -constexpr IceCandidatePairConfig_AddressFamily IceCandidatePairConfig_AddressFamily_AddressFamily_MAX = IceCandidatePairConfig_AddressFamily_IPV6; -constexpr int IceCandidatePairConfig_AddressFamily_AddressFamily_ARRAYSIZE = IceCandidatePairConfig_AddressFamily_AddressFamily_MAX + 1; - -const std::string& IceCandidatePairConfig_AddressFamily_Name(IceCandidatePairConfig_AddressFamily value); -template -inline const std::string& IceCandidatePairConfig_AddressFamily_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_AddressFamily_Name."); - return IceCandidatePairConfig_AddressFamily_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_AddressFamily_Parse( - const std::string& name, IceCandidatePairConfig_AddressFamily* value); -enum IceCandidatePairConfig_NetworkType : int { - IceCandidatePairConfig_NetworkType_UNKNOWN_NETWORK_TYPE = 0, - IceCandidatePairConfig_NetworkType_ETHERNET = 1, - IceCandidatePairConfig_NetworkType_WIFI = 2, - IceCandidatePairConfig_NetworkType_CELLULAR = 3, - IceCandidatePairConfig_NetworkType_VPN = 4, - IceCandidatePairConfig_NetworkType_LOOPBACK = 5 -}; -bool IceCandidatePairConfig_NetworkType_IsValid(int value); -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig_NetworkType_NetworkType_MIN = IceCandidatePairConfig_NetworkType_UNKNOWN_NETWORK_TYPE; -constexpr IceCandidatePairConfig_NetworkType IceCandidatePairConfig_NetworkType_NetworkType_MAX = IceCandidatePairConfig_NetworkType_LOOPBACK; -constexpr int IceCandidatePairConfig_NetworkType_NetworkType_ARRAYSIZE = IceCandidatePairConfig_NetworkType_NetworkType_MAX + 1; - -const std::string& IceCandidatePairConfig_NetworkType_Name(IceCandidatePairConfig_NetworkType value); -template -inline const std::string& IceCandidatePairConfig_NetworkType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfig_NetworkType_Name."); - return IceCandidatePairConfig_NetworkType_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairConfig_NetworkType_Parse( - const std::string& name, IceCandidatePairConfig_NetworkType* value); -enum IceCandidatePairEvent_IceCandidatePairEventType : int { - IceCandidatePairEvent_IceCandidatePairEventType_UNKNOWN_CHECK_TYPE = 0, - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_SENT = 1, - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RECEIVED = 2, - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_SENT = 3, - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_RECEIVED = 4 -}; -bool IceCandidatePairEvent_IceCandidatePairEventType_IsValid(int value); -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MIN = IceCandidatePairEvent_IceCandidatePairEventType_UNKNOWN_CHECK_TYPE; -constexpr IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MAX = IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_RECEIVED; -constexpr int IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_ARRAYSIZE = IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MAX + 1; - -const std::string& IceCandidatePairEvent_IceCandidatePairEventType_Name(IceCandidatePairEvent_IceCandidatePairEventType value); -template -inline const std::string& IceCandidatePairEvent_IceCandidatePairEventType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairEvent_IceCandidatePairEventType_Name."); - return IceCandidatePairEvent_IceCandidatePairEventType_Name(static_cast(enum_t_value)); -} -bool IceCandidatePairEvent_IceCandidatePairEventType_Parse( - const std::string& name, IceCandidatePairEvent_IceCandidatePairEventType* value); -enum DtlsTransportStateEvent_DtlsTransportState : int { - DtlsTransportStateEvent_DtlsTransportState_UNKNOWN_DTLS_TRANSPORT_STATE = 0, - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_NEW = 1, - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_CONNECTING = 2, - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_CONNECTED = 3, - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_CLOSED = 4, - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_FAILED = 5 -}; -bool DtlsTransportStateEvent_DtlsTransportState_IsValid(int value); -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent_DtlsTransportState_DtlsTransportState_MIN = DtlsTransportStateEvent_DtlsTransportState_UNKNOWN_DTLS_TRANSPORT_STATE; -constexpr DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent_DtlsTransportState_DtlsTransportState_MAX = DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_FAILED; -constexpr int DtlsTransportStateEvent_DtlsTransportState_DtlsTransportState_ARRAYSIZE = DtlsTransportStateEvent_DtlsTransportState_DtlsTransportState_MAX + 1; - -const std::string& DtlsTransportStateEvent_DtlsTransportState_Name(DtlsTransportStateEvent_DtlsTransportState value); -template -inline const std::string& DtlsTransportStateEvent_DtlsTransportState_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function DtlsTransportStateEvent_DtlsTransportState_Name."); - return DtlsTransportStateEvent_DtlsTransportState_Name(static_cast(enum_t_value)); -} -bool DtlsTransportStateEvent_DtlsTransportState_Parse( - const std::string& name, DtlsTransportStateEvent_DtlsTransportState* value); -// =================================================================== - -class EventStream : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.EventStream) */ { - public: - EventStream(); - virtual ~EventStream(); - - EventStream(const EventStream& from); - EventStream(EventStream&& from) noexcept - : EventStream() { - *this = ::std::move(from); - } - - inline EventStream& operator=(const EventStream& from) { - CopyFrom(from); - return *this; - } - inline EventStream& operator=(EventStream&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const EventStream& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const EventStream* internal_default_instance() { - return reinterpret_cast( - &_EventStream_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(EventStream& a, EventStream& b) { - a.Swap(&b); - } - inline void Swap(EventStream* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline EventStream* New() const final { - return CreateMaybeMessage(nullptr); - } - - EventStream* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const EventStream& from); - void MergeFrom(const EventStream& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(EventStream* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.EventStream"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kStreamFieldNumber = 1, - kIncomingRtpPacketsFieldNumber = 2, - kOutgoingRtpPacketsFieldNumber = 3, - kIncomingRtcpPacketsFieldNumber = 4, - kOutgoingRtcpPacketsFieldNumber = 5, - kAudioPlayoutEventsFieldNumber = 6, - kFrameDecodedEventsFieldNumber = 7, - kBeginLogEventsFieldNumber = 16, - kEndLogEventsFieldNumber = 17, - kLossBasedBweUpdatesFieldNumber = 18, - kDelayBasedBweUpdatesFieldNumber = 19, - kAudioNetworkAdaptationsFieldNumber = 20, - kProbeClustersFieldNumber = 21, - kProbeSuccessFieldNumber = 22, - kProbeFailureFieldNumber = 23, - kAlrStatesFieldNumber = 24, - kIceCandidateConfigsFieldNumber = 25, - kIceCandidateEventsFieldNumber = 26, - kDtlsTransportStateEventsFieldNumber = 27, - kDtlsWritableStatesFieldNumber = 28, - kGenericPacketsSentFieldNumber = 29, - kGenericPacketsReceivedFieldNumber = 30, - kGenericAcksReceivedFieldNumber = 31, - kRouteChangesFieldNumber = 32, - kRemoteEstimatesFieldNumber = 33, - kAudioRecvStreamConfigsFieldNumber = 101, - kAudioSendStreamConfigsFieldNumber = 102, - kVideoRecvStreamConfigsFieldNumber = 103, - kVideoSendStreamConfigsFieldNumber = 104, - }; - // repeated .webrtc.rtclog2.Event stream = 1 [deprecated = true]; - PROTOBUF_DEPRECATED int stream_size() const; - PROTOBUF_DEPRECATED void clear_stream(); - PROTOBUF_DEPRECATED ::webrtc::rtclog2::Event* mutable_stream(int index); - PROTOBUF_DEPRECATED ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::Event >* - mutable_stream(); - PROTOBUF_DEPRECATED const ::webrtc::rtclog2::Event& stream(int index) const; - PROTOBUF_DEPRECATED ::webrtc::rtclog2::Event* add_stream(); - PROTOBUF_DEPRECATED const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::Event >& - stream() const; - - // repeated .webrtc.rtclog2.IncomingRtpPackets incoming_rtp_packets = 2; - int incoming_rtp_packets_size() const; - void clear_incoming_rtp_packets(); - ::webrtc::rtclog2::IncomingRtpPackets* mutable_incoming_rtp_packets(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtpPackets >* - mutable_incoming_rtp_packets(); - const ::webrtc::rtclog2::IncomingRtpPackets& incoming_rtp_packets(int index) const; - ::webrtc::rtclog2::IncomingRtpPackets* add_incoming_rtp_packets(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtpPackets >& - incoming_rtp_packets() const; - - // repeated .webrtc.rtclog2.OutgoingRtpPackets outgoing_rtp_packets = 3; - int outgoing_rtp_packets_size() const; - void clear_outgoing_rtp_packets(); - ::webrtc::rtclog2::OutgoingRtpPackets* mutable_outgoing_rtp_packets(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtpPackets >* - mutable_outgoing_rtp_packets(); - const ::webrtc::rtclog2::OutgoingRtpPackets& outgoing_rtp_packets(int index) const; - ::webrtc::rtclog2::OutgoingRtpPackets* add_outgoing_rtp_packets(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtpPackets >& - outgoing_rtp_packets() const; - - // repeated .webrtc.rtclog2.IncomingRtcpPackets incoming_rtcp_packets = 4; - int incoming_rtcp_packets_size() const; - void clear_incoming_rtcp_packets(); - ::webrtc::rtclog2::IncomingRtcpPackets* mutable_incoming_rtcp_packets(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtcpPackets >* - mutable_incoming_rtcp_packets(); - const ::webrtc::rtclog2::IncomingRtcpPackets& incoming_rtcp_packets(int index) const; - ::webrtc::rtclog2::IncomingRtcpPackets* add_incoming_rtcp_packets(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtcpPackets >& - incoming_rtcp_packets() const; - - // repeated .webrtc.rtclog2.OutgoingRtcpPackets outgoing_rtcp_packets = 5; - int outgoing_rtcp_packets_size() const; - void clear_outgoing_rtcp_packets(); - ::webrtc::rtclog2::OutgoingRtcpPackets* mutable_outgoing_rtcp_packets(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtcpPackets >* - mutable_outgoing_rtcp_packets(); - const ::webrtc::rtclog2::OutgoingRtcpPackets& outgoing_rtcp_packets(int index) const; - ::webrtc::rtclog2::OutgoingRtcpPackets* add_outgoing_rtcp_packets(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtcpPackets >& - outgoing_rtcp_packets() const; - - // repeated .webrtc.rtclog2.AudioPlayoutEvents audio_playout_events = 6; - int audio_playout_events_size() const; - void clear_audio_playout_events(); - ::webrtc::rtclog2::AudioPlayoutEvents* mutable_audio_playout_events(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioPlayoutEvents >* - mutable_audio_playout_events(); - const ::webrtc::rtclog2::AudioPlayoutEvents& audio_playout_events(int index) const; - ::webrtc::rtclog2::AudioPlayoutEvents* add_audio_playout_events(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioPlayoutEvents >& - audio_playout_events() const; - - // repeated .webrtc.rtclog2.FrameDecodedEvents frame_decoded_events = 7; - int frame_decoded_events_size() const; - void clear_frame_decoded_events(); - ::webrtc::rtclog2::FrameDecodedEvents* mutable_frame_decoded_events(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::FrameDecodedEvents >* - mutable_frame_decoded_events(); - const ::webrtc::rtclog2::FrameDecodedEvents& frame_decoded_events(int index) const; - ::webrtc::rtclog2::FrameDecodedEvents* add_frame_decoded_events(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::FrameDecodedEvents >& - frame_decoded_events() const; - - // repeated .webrtc.rtclog2.BeginLogEvent begin_log_events = 16; - int begin_log_events_size() const; - void clear_begin_log_events(); - ::webrtc::rtclog2::BeginLogEvent* mutable_begin_log_events(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BeginLogEvent >* - mutable_begin_log_events(); - const ::webrtc::rtclog2::BeginLogEvent& begin_log_events(int index) const; - ::webrtc::rtclog2::BeginLogEvent* add_begin_log_events(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BeginLogEvent >& - begin_log_events() const; - - // repeated .webrtc.rtclog2.EndLogEvent end_log_events = 17; - int end_log_events_size() const; - void clear_end_log_events(); - ::webrtc::rtclog2::EndLogEvent* mutable_end_log_events(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::EndLogEvent >* - mutable_end_log_events(); - const ::webrtc::rtclog2::EndLogEvent& end_log_events(int index) const; - ::webrtc::rtclog2::EndLogEvent* add_end_log_events(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::EndLogEvent >& - end_log_events() const; - - // repeated .webrtc.rtclog2.LossBasedBweUpdates loss_based_bwe_updates = 18; - int loss_based_bwe_updates_size() const; - void clear_loss_based_bwe_updates(); - ::webrtc::rtclog2::LossBasedBweUpdates* mutable_loss_based_bwe_updates(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::LossBasedBweUpdates >* - mutable_loss_based_bwe_updates(); - const ::webrtc::rtclog2::LossBasedBweUpdates& loss_based_bwe_updates(int index) const; - ::webrtc::rtclog2::LossBasedBweUpdates* add_loss_based_bwe_updates(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::LossBasedBweUpdates >& - loss_based_bwe_updates() const; - - // repeated .webrtc.rtclog2.DelayBasedBweUpdates delay_based_bwe_updates = 19; - int delay_based_bwe_updates_size() const; - void clear_delay_based_bwe_updates(); - ::webrtc::rtclog2::DelayBasedBweUpdates* mutable_delay_based_bwe_updates(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DelayBasedBweUpdates >* - mutable_delay_based_bwe_updates(); - const ::webrtc::rtclog2::DelayBasedBweUpdates& delay_based_bwe_updates(int index) const; - ::webrtc::rtclog2::DelayBasedBweUpdates* add_delay_based_bwe_updates(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DelayBasedBweUpdates >& - delay_based_bwe_updates() const; - - // repeated .webrtc.rtclog2.AudioNetworkAdaptations audio_network_adaptations = 20; - int audio_network_adaptations_size() const; - void clear_audio_network_adaptations(); - ::webrtc::rtclog2::AudioNetworkAdaptations* mutable_audio_network_adaptations(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioNetworkAdaptations >* - mutable_audio_network_adaptations(); - const ::webrtc::rtclog2::AudioNetworkAdaptations& audio_network_adaptations(int index) const; - ::webrtc::rtclog2::AudioNetworkAdaptations* add_audio_network_adaptations(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioNetworkAdaptations >& - audio_network_adaptations() const; - - // repeated .webrtc.rtclog2.BweProbeCluster probe_clusters = 21; - int probe_clusters_size() const; - void clear_probe_clusters(); - ::webrtc::rtclog2::BweProbeCluster* mutable_probe_clusters(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeCluster >* - mutable_probe_clusters(); - const ::webrtc::rtclog2::BweProbeCluster& probe_clusters(int index) const; - ::webrtc::rtclog2::BweProbeCluster* add_probe_clusters(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeCluster >& - probe_clusters() const; - - // repeated .webrtc.rtclog2.BweProbeResultSuccess probe_success = 22; - int probe_success_size() const; - void clear_probe_success(); - ::webrtc::rtclog2::BweProbeResultSuccess* mutable_probe_success(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultSuccess >* - mutable_probe_success(); - const ::webrtc::rtclog2::BweProbeResultSuccess& probe_success(int index) const; - ::webrtc::rtclog2::BweProbeResultSuccess* add_probe_success(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultSuccess >& - probe_success() const; - - // repeated .webrtc.rtclog2.BweProbeResultFailure probe_failure = 23; - int probe_failure_size() const; - void clear_probe_failure(); - ::webrtc::rtclog2::BweProbeResultFailure* mutable_probe_failure(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultFailure >* - mutable_probe_failure(); - const ::webrtc::rtclog2::BweProbeResultFailure& probe_failure(int index) const; - ::webrtc::rtclog2::BweProbeResultFailure* add_probe_failure(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultFailure >& - probe_failure() const; - - // repeated .webrtc.rtclog2.AlrState alr_states = 24; - int alr_states_size() const; - void clear_alr_states(); - ::webrtc::rtclog2::AlrState* mutable_alr_states(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AlrState >* - mutable_alr_states(); - const ::webrtc::rtclog2::AlrState& alr_states(int index) const; - ::webrtc::rtclog2::AlrState* add_alr_states(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AlrState >& - alr_states() const; - - // repeated .webrtc.rtclog2.IceCandidatePairConfig ice_candidate_configs = 25; - int ice_candidate_configs_size() const; - void clear_ice_candidate_configs(); - ::webrtc::rtclog2::IceCandidatePairConfig* mutable_ice_candidate_configs(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairConfig >* - mutable_ice_candidate_configs(); - const ::webrtc::rtclog2::IceCandidatePairConfig& ice_candidate_configs(int index) const; - ::webrtc::rtclog2::IceCandidatePairConfig* add_ice_candidate_configs(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairConfig >& - ice_candidate_configs() const; - - // repeated .webrtc.rtclog2.IceCandidatePairEvent ice_candidate_events = 26; - int ice_candidate_events_size() const; - void clear_ice_candidate_events(); - ::webrtc::rtclog2::IceCandidatePairEvent* mutable_ice_candidate_events(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairEvent >* - mutable_ice_candidate_events(); - const ::webrtc::rtclog2::IceCandidatePairEvent& ice_candidate_events(int index) const; - ::webrtc::rtclog2::IceCandidatePairEvent* add_ice_candidate_events(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairEvent >& - ice_candidate_events() const; - - // repeated .webrtc.rtclog2.DtlsTransportStateEvent dtls_transport_state_events = 27; - int dtls_transport_state_events_size() const; - void clear_dtls_transport_state_events(); - ::webrtc::rtclog2::DtlsTransportStateEvent* mutable_dtls_transport_state_events(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsTransportStateEvent >* - mutable_dtls_transport_state_events(); - const ::webrtc::rtclog2::DtlsTransportStateEvent& dtls_transport_state_events(int index) const; - ::webrtc::rtclog2::DtlsTransportStateEvent* add_dtls_transport_state_events(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsTransportStateEvent >& - dtls_transport_state_events() const; - - // repeated .webrtc.rtclog2.DtlsWritableState dtls_writable_states = 28; - int dtls_writable_states_size() const; - void clear_dtls_writable_states(); - ::webrtc::rtclog2::DtlsWritableState* mutable_dtls_writable_states(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsWritableState >* - mutable_dtls_writable_states(); - const ::webrtc::rtclog2::DtlsWritableState& dtls_writable_states(int index) const; - ::webrtc::rtclog2::DtlsWritableState* add_dtls_writable_states(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsWritableState >& - dtls_writable_states() const; - - // repeated .webrtc.rtclog2.GenericPacketSent generic_packets_sent = 29; - int generic_packets_sent_size() const; - void clear_generic_packets_sent(); - ::webrtc::rtclog2::GenericPacketSent* mutable_generic_packets_sent(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketSent >* - mutable_generic_packets_sent(); - const ::webrtc::rtclog2::GenericPacketSent& generic_packets_sent(int index) const; - ::webrtc::rtclog2::GenericPacketSent* add_generic_packets_sent(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketSent >& - generic_packets_sent() const; - - // repeated .webrtc.rtclog2.GenericPacketReceived generic_packets_received = 30; - int generic_packets_received_size() const; - void clear_generic_packets_received(); - ::webrtc::rtclog2::GenericPacketReceived* mutable_generic_packets_received(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketReceived >* - mutable_generic_packets_received(); - const ::webrtc::rtclog2::GenericPacketReceived& generic_packets_received(int index) const; - ::webrtc::rtclog2::GenericPacketReceived* add_generic_packets_received(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketReceived >& - generic_packets_received() const; - - // repeated .webrtc.rtclog2.GenericAckReceived generic_acks_received = 31; - int generic_acks_received_size() const; - void clear_generic_acks_received(); - ::webrtc::rtclog2::GenericAckReceived* mutable_generic_acks_received(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericAckReceived >* - mutable_generic_acks_received(); - const ::webrtc::rtclog2::GenericAckReceived& generic_acks_received(int index) const; - ::webrtc::rtclog2::GenericAckReceived* add_generic_acks_received(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericAckReceived >& - generic_acks_received() const; - - // repeated .webrtc.rtclog2.RouteChange route_changes = 32; - int route_changes_size() const; - void clear_route_changes(); - ::webrtc::rtclog2::RouteChange* mutable_route_changes(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RouteChange >* - mutable_route_changes(); - const ::webrtc::rtclog2::RouteChange& route_changes(int index) const; - ::webrtc::rtclog2::RouteChange* add_route_changes(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RouteChange >& - route_changes() const; - - // repeated .webrtc.rtclog2.RemoteEstimates remote_estimates = 33; - int remote_estimates_size() const; - void clear_remote_estimates(); - ::webrtc::rtclog2::RemoteEstimates* mutable_remote_estimates(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RemoteEstimates >* - mutable_remote_estimates(); - const ::webrtc::rtclog2::RemoteEstimates& remote_estimates(int index) const; - ::webrtc::rtclog2::RemoteEstimates* add_remote_estimates(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RemoteEstimates >& - remote_estimates() const; - - // repeated .webrtc.rtclog2.AudioRecvStreamConfig audio_recv_stream_configs = 101; - int audio_recv_stream_configs_size() const; - void clear_audio_recv_stream_configs(); - ::webrtc::rtclog2::AudioRecvStreamConfig* mutable_audio_recv_stream_configs(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioRecvStreamConfig >* - mutable_audio_recv_stream_configs(); - const ::webrtc::rtclog2::AudioRecvStreamConfig& audio_recv_stream_configs(int index) const; - ::webrtc::rtclog2::AudioRecvStreamConfig* add_audio_recv_stream_configs(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioRecvStreamConfig >& - audio_recv_stream_configs() const; - - // repeated .webrtc.rtclog2.AudioSendStreamConfig audio_send_stream_configs = 102; - int audio_send_stream_configs_size() const; - void clear_audio_send_stream_configs(); - ::webrtc::rtclog2::AudioSendStreamConfig* mutable_audio_send_stream_configs(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioSendStreamConfig >* - mutable_audio_send_stream_configs(); - const ::webrtc::rtclog2::AudioSendStreamConfig& audio_send_stream_configs(int index) const; - ::webrtc::rtclog2::AudioSendStreamConfig* add_audio_send_stream_configs(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioSendStreamConfig >& - audio_send_stream_configs() const; - - // repeated .webrtc.rtclog2.VideoRecvStreamConfig video_recv_stream_configs = 103; - int video_recv_stream_configs_size() const; - void clear_video_recv_stream_configs(); - ::webrtc::rtclog2::VideoRecvStreamConfig* mutable_video_recv_stream_configs(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoRecvStreamConfig >* - mutable_video_recv_stream_configs(); - const ::webrtc::rtclog2::VideoRecvStreamConfig& video_recv_stream_configs(int index) const; - ::webrtc::rtclog2::VideoRecvStreamConfig* add_video_recv_stream_configs(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoRecvStreamConfig >& - video_recv_stream_configs() const; - - // repeated .webrtc.rtclog2.VideoSendStreamConfig video_send_stream_configs = 104; - int video_send_stream_configs_size() const; - void clear_video_send_stream_configs(); - ::webrtc::rtclog2::VideoSendStreamConfig* mutable_video_send_stream_configs(int index); - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoSendStreamConfig >* - mutable_video_send_stream_configs(); - const ::webrtc::rtclog2::VideoSendStreamConfig& video_send_stream_configs(int index) const; - ::webrtc::rtclog2::VideoSendStreamConfig* add_video_send_stream_configs(); - const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoSendStreamConfig >& - video_send_stream_configs() const; - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.EventStream) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::Event > stream_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtpPackets > incoming_rtp_packets_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtpPackets > outgoing_rtp_packets_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtcpPackets > incoming_rtcp_packets_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtcpPackets > outgoing_rtcp_packets_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioPlayoutEvents > audio_playout_events_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::FrameDecodedEvents > frame_decoded_events_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BeginLogEvent > begin_log_events_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::EndLogEvent > end_log_events_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::LossBasedBweUpdates > loss_based_bwe_updates_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DelayBasedBweUpdates > delay_based_bwe_updates_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioNetworkAdaptations > audio_network_adaptations_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeCluster > probe_clusters_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultSuccess > probe_success_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultFailure > probe_failure_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AlrState > alr_states_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairConfig > ice_candidate_configs_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairEvent > ice_candidate_events_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsTransportStateEvent > dtls_transport_state_events_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsWritableState > dtls_writable_states_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketSent > generic_packets_sent_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketReceived > generic_packets_received_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericAckReceived > generic_acks_received_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RouteChange > route_changes_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RemoteEstimates > remote_estimates_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioRecvStreamConfig > audio_recv_stream_configs_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioSendStreamConfig > audio_send_stream_configs_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoRecvStreamConfig > video_recv_stream_configs_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoSendStreamConfig > video_send_stream_configs_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class Event : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.Event) */ { - public: - Event(); - virtual ~Event(); - - Event(const Event& from); - Event(Event&& from) noexcept - : Event() { - *this = ::std::move(from); - } - - inline Event& operator=(const Event& from) { - CopyFrom(from); - return *this; - } - inline Event& operator=(Event&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const Event& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const Event* internal_default_instance() { - return reinterpret_cast( - &_Event_default_instance_); - } - static constexpr int kIndexInFileMessages = - 1; - - friend void swap(Event& a, Event& b) { - a.Swap(&b); - } - inline void Swap(Event* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline Event* New() const final { - return CreateMaybeMessage(nullptr); - } - - Event* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const Event& from); - void MergeFrom(const Event& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(Event* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.Event"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.Event) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class GenericPacketReceived : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.GenericPacketReceived) */ { - public: - GenericPacketReceived(); - virtual ~GenericPacketReceived(); - - GenericPacketReceived(const GenericPacketReceived& from); - GenericPacketReceived(GenericPacketReceived&& from) noexcept - : GenericPacketReceived() { - *this = ::std::move(from); - } - - inline GenericPacketReceived& operator=(const GenericPacketReceived& from) { - CopyFrom(from); - return *this; - } - inline GenericPacketReceived& operator=(GenericPacketReceived&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const GenericPacketReceived& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const GenericPacketReceived* internal_default_instance() { - return reinterpret_cast( - &_GenericPacketReceived_default_instance_); - } - static constexpr int kIndexInFileMessages = - 2; - - friend void swap(GenericPacketReceived& a, GenericPacketReceived& b) { - a.Swap(&b); - } - inline void Swap(GenericPacketReceived* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline GenericPacketReceived* New() const final { - return CreateMaybeMessage(nullptr); - } - - GenericPacketReceived* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const GenericPacketReceived& from); - void MergeFrom(const GenericPacketReceived& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(GenericPacketReceived* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.GenericPacketReceived"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 17, - kPacketNumberDeltasFieldNumber = 18, - kPacketLengthDeltasFieldNumber = 19, - kTimestampMsFieldNumber = 1, - kPacketNumberFieldNumber = 2, - kPacketLengthFieldNumber = 3, - kNumberOfDeltasFieldNumber = 16, - }; - // optional bytes timestamp_ms_deltas = 17; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes packet_number_deltas = 18; - bool has_packet_number_deltas() const; - void clear_packet_number_deltas(); - const std::string& packet_number_deltas() const; - void set_packet_number_deltas(const std::string& value); - void set_packet_number_deltas(std::string&& value); - void set_packet_number_deltas(const char* value); - void set_packet_number_deltas(const void* value, size_t size); - std::string* mutable_packet_number_deltas(); - std::string* release_packet_number_deltas(); - void set_allocated_packet_number_deltas(std::string* packet_number_deltas); - - // optional bytes packet_length_deltas = 19; - bool has_packet_length_deltas() const; - void clear_packet_length_deltas(); - const std::string& packet_length_deltas() const; - void set_packet_length_deltas(const std::string& value); - void set_packet_length_deltas(std::string&& value); - void set_packet_length_deltas(const char* value); - void set_packet_length_deltas(const void* value, size_t size); - std::string* mutable_packet_length_deltas(); - std::string* release_packet_length_deltas(); - void set_allocated_packet_length_deltas(std::string* packet_length_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int64 packet_number = 2; - bool has_packet_number() const; - void clear_packet_number(); - ::PROTOBUF_NAMESPACE_ID::int64 packet_number() const; - void set_packet_number(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int32 packet_length = 3; - bool has_packet_length() const; - void clear_packet_length(); - ::PROTOBUF_NAMESPACE_ID::int32 packet_length() const; - void set_packet_length(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional uint32 number_of_deltas = 16; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.GenericPacketReceived) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr packet_number_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr packet_length_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::int64 packet_number_; - ::PROTOBUF_NAMESPACE_ID::int32 packet_length_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class GenericPacketSent : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.GenericPacketSent) */ { - public: - GenericPacketSent(); - virtual ~GenericPacketSent(); - - GenericPacketSent(const GenericPacketSent& from); - GenericPacketSent(GenericPacketSent&& from) noexcept - : GenericPacketSent() { - *this = ::std::move(from); - } - - inline GenericPacketSent& operator=(const GenericPacketSent& from) { - CopyFrom(from); - return *this; - } - inline GenericPacketSent& operator=(GenericPacketSent&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const GenericPacketSent& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const GenericPacketSent* internal_default_instance() { - return reinterpret_cast( - &_GenericPacketSent_default_instance_); - } - static constexpr int kIndexInFileMessages = - 3; - - friend void swap(GenericPacketSent& a, GenericPacketSent& b) { - a.Swap(&b); - } - inline void Swap(GenericPacketSent* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline GenericPacketSent* New() const final { - return CreateMaybeMessage(nullptr); - } - - GenericPacketSent* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const GenericPacketSent& from); - void MergeFrom(const GenericPacketSent& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(GenericPacketSent* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.GenericPacketSent"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 17, - kPacketNumberDeltasFieldNumber = 18, - kOverheadLengthDeltasFieldNumber = 19, - kPayloadLengthDeltasFieldNumber = 20, - kPaddingLengthDeltasFieldNumber = 21, - kTimestampMsFieldNumber = 1, - kPacketNumberFieldNumber = 2, - kOverheadLengthFieldNumber = 3, - kPayloadLengthFieldNumber = 4, - kPaddingLengthFieldNumber = 5, - kNumberOfDeltasFieldNumber = 16, - }; - // optional bytes timestamp_ms_deltas = 17; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes packet_number_deltas = 18; - bool has_packet_number_deltas() const; - void clear_packet_number_deltas(); - const std::string& packet_number_deltas() const; - void set_packet_number_deltas(const std::string& value); - void set_packet_number_deltas(std::string&& value); - void set_packet_number_deltas(const char* value); - void set_packet_number_deltas(const void* value, size_t size); - std::string* mutable_packet_number_deltas(); - std::string* release_packet_number_deltas(); - void set_allocated_packet_number_deltas(std::string* packet_number_deltas); - - // optional bytes overhead_length_deltas = 19; - bool has_overhead_length_deltas() const; - void clear_overhead_length_deltas(); - const std::string& overhead_length_deltas() const; - void set_overhead_length_deltas(const std::string& value); - void set_overhead_length_deltas(std::string&& value); - void set_overhead_length_deltas(const char* value); - void set_overhead_length_deltas(const void* value, size_t size); - std::string* mutable_overhead_length_deltas(); - std::string* release_overhead_length_deltas(); - void set_allocated_overhead_length_deltas(std::string* overhead_length_deltas); - - // optional bytes payload_length_deltas = 20; - bool has_payload_length_deltas() const; - void clear_payload_length_deltas(); - const std::string& payload_length_deltas() const; - void set_payload_length_deltas(const std::string& value); - void set_payload_length_deltas(std::string&& value); - void set_payload_length_deltas(const char* value); - void set_payload_length_deltas(const void* value, size_t size); - std::string* mutable_payload_length_deltas(); - std::string* release_payload_length_deltas(); - void set_allocated_payload_length_deltas(std::string* payload_length_deltas); - - // optional bytes padding_length_deltas = 21; - bool has_padding_length_deltas() const; - void clear_padding_length_deltas(); - const std::string& padding_length_deltas() const; - void set_padding_length_deltas(const std::string& value); - void set_padding_length_deltas(std::string&& value); - void set_padding_length_deltas(const char* value); - void set_padding_length_deltas(const void* value, size_t size); - std::string* mutable_padding_length_deltas(); - std::string* release_padding_length_deltas(); - void set_allocated_padding_length_deltas(std::string* padding_length_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int64 packet_number = 2; - bool has_packet_number() const; - void clear_packet_number(); - ::PROTOBUF_NAMESPACE_ID::int64 packet_number() const; - void set_packet_number(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int32 overhead_length = 3; - bool has_overhead_length() const; - void clear_overhead_length(); - ::PROTOBUF_NAMESPACE_ID::int32 overhead_length() const; - void set_overhead_length(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 payload_length = 4; - bool has_payload_length() const; - void clear_payload_length(); - ::PROTOBUF_NAMESPACE_ID::int32 payload_length() const; - void set_payload_length(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 padding_length = 5; - bool has_padding_length() const; - void clear_padding_length(); - ::PROTOBUF_NAMESPACE_ID::int32 padding_length() const; - void set_padding_length(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional uint32 number_of_deltas = 16; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.GenericPacketSent) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr packet_number_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr overhead_length_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr payload_length_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr padding_length_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::int64 packet_number_; - ::PROTOBUF_NAMESPACE_ID::int32 overhead_length_; - ::PROTOBUF_NAMESPACE_ID::int32 payload_length_; - ::PROTOBUF_NAMESPACE_ID::int32 padding_length_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class GenericAckReceived : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.GenericAckReceived) */ { - public: - GenericAckReceived(); - virtual ~GenericAckReceived(); - - GenericAckReceived(const GenericAckReceived& from); - GenericAckReceived(GenericAckReceived&& from) noexcept - : GenericAckReceived() { - *this = ::std::move(from); - } - - inline GenericAckReceived& operator=(const GenericAckReceived& from) { - CopyFrom(from); - return *this; - } - inline GenericAckReceived& operator=(GenericAckReceived&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const GenericAckReceived& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const GenericAckReceived* internal_default_instance() { - return reinterpret_cast( - &_GenericAckReceived_default_instance_); - } - static constexpr int kIndexInFileMessages = - 4; - - friend void swap(GenericAckReceived& a, GenericAckReceived& b) { - a.Swap(&b); - } - inline void Swap(GenericAckReceived* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline GenericAckReceived* New() const final { - return CreateMaybeMessage(nullptr); - } - - GenericAckReceived* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const GenericAckReceived& from); - void MergeFrom(const GenericAckReceived& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(GenericAckReceived* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.GenericAckReceived"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 17, - kPacketNumberDeltasFieldNumber = 18, - kAckedPacketNumberDeltasFieldNumber = 19, - kReceiveAckedPacketTimeMsDeltasFieldNumber = 20, - kTimestampMsFieldNumber = 1, - kPacketNumberFieldNumber = 2, - kAckedPacketNumberFieldNumber = 3, - kReceiveAckedPacketTimeMsFieldNumber = 4, - kNumberOfDeltasFieldNumber = 16, - }; - // optional bytes timestamp_ms_deltas = 17; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes packet_number_deltas = 18; - bool has_packet_number_deltas() const; - void clear_packet_number_deltas(); - const std::string& packet_number_deltas() const; - void set_packet_number_deltas(const std::string& value); - void set_packet_number_deltas(std::string&& value); - void set_packet_number_deltas(const char* value); - void set_packet_number_deltas(const void* value, size_t size); - std::string* mutable_packet_number_deltas(); - std::string* release_packet_number_deltas(); - void set_allocated_packet_number_deltas(std::string* packet_number_deltas); - - // optional bytes acked_packet_number_deltas = 19; - bool has_acked_packet_number_deltas() const; - void clear_acked_packet_number_deltas(); - const std::string& acked_packet_number_deltas() const; - void set_acked_packet_number_deltas(const std::string& value); - void set_acked_packet_number_deltas(std::string&& value); - void set_acked_packet_number_deltas(const char* value); - void set_acked_packet_number_deltas(const void* value, size_t size); - std::string* mutable_acked_packet_number_deltas(); - std::string* release_acked_packet_number_deltas(); - void set_allocated_acked_packet_number_deltas(std::string* acked_packet_number_deltas); - - // optional bytes receive_acked_packet_time_ms_deltas = 20; - bool has_receive_acked_packet_time_ms_deltas() const; - void clear_receive_acked_packet_time_ms_deltas(); - const std::string& receive_acked_packet_time_ms_deltas() const; - void set_receive_acked_packet_time_ms_deltas(const std::string& value); - void set_receive_acked_packet_time_ms_deltas(std::string&& value); - void set_receive_acked_packet_time_ms_deltas(const char* value); - void set_receive_acked_packet_time_ms_deltas(const void* value, size_t size); - std::string* mutable_receive_acked_packet_time_ms_deltas(); - std::string* release_receive_acked_packet_time_ms_deltas(); - void set_allocated_receive_acked_packet_time_ms_deltas(std::string* receive_acked_packet_time_ms_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int64 packet_number = 2; - bool has_packet_number() const; - void clear_packet_number(); - ::PROTOBUF_NAMESPACE_ID::int64 packet_number() const; - void set_packet_number(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int64 acked_packet_number = 3; - bool has_acked_packet_number() const; - void clear_acked_packet_number(); - ::PROTOBUF_NAMESPACE_ID::int64 acked_packet_number() const; - void set_acked_packet_number(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int64 receive_acked_packet_time_ms = 4; - bool has_receive_acked_packet_time_ms() const; - void clear_receive_acked_packet_time_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 receive_acked_packet_time_ms() const; - void set_receive_acked_packet_time_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 number_of_deltas = 16; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.GenericAckReceived) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr packet_number_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr acked_packet_number_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr receive_acked_packet_time_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::int64 packet_number_; - ::PROTOBUF_NAMESPACE_ID::int64 acked_packet_number_; - ::PROTOBUF_NAMESPACE_ID::int64 receive_acked_packet_time_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class IncomingRtpPackets : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.IncomingRtpPackets) */ { - public: - IncomingRtpPackets(); - virtual ~IncomingRtpPackets(); - - IncomingRtpPackets(const IncomingRtpPackets& from); - IncomingRtpPackets(IncomingRtpPackets&& from) noexcept - : IncomingRtpPackets() { - *this = ::std::move(from); - } - - inline IncomingRtpPackets& operator=(const IncomingRtpPackets& from) { - CopyFrom(from); - return *this; - } - inline IncomingRtpPackets& operator=(IncomingRtpPackets&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const IncomingRtpPackets& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const IncomingRtpPackets* internal_default_instance() { - return reinterpret_cast( - &_IncomingRtpPackets_default_instance_); - } - static constexpr int kIndexInFileMessages = - 5; - - friend void swap(IncomingRtpPackets& a, IncomingRtpPackets& b) { - a.Swap(&b); - } - inline void Swap(IncomingRtpPackets* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline IncomingRtpPackets* New() const final { - return CreateMaybeMessage(nullptr); - } - - IncomingRtpPackets* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const IncomingRtpPackets& from); - void MergeFrom(const IncomingRtpPackets& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(IncomingRtpPackets* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.IncomingRtpPackets"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 101, - kMarkerDeltasFieldNumber = 102, - kPayloadTypeDeltasFieldNumber = 103, - kSequenceNumberDeltasFieldNumber = 104, - kRtpTimestampDeltasFieldNumber = 105, - kSsrcDeltasFieldNumber = 106, - kPayloadSizeDeltasFieldNumber = 108, - kHeaderSizeDeltasFieldNumber = 109, - kPaddingSizeDeltasFieldNumber = 110, - kTransportSequenceNumberDeltasFieldNumber = 115, - kTransmissionTimeOffsetDeltasFieldNumber = 116, - kAbsoluteSendTimeDeltasFieldNumber = 117, - kVideoRotationDeltasFieldNumber = 118, - kAudioLevelDeltasFieldNumber = 119, - kVoiceActivityDeltasFieldNumber = 120, - kTimestampMsFieldNumber = 1, - kPayloadTypeFieldNumber = 3, - kSequenceNumberFieldNumber = 4, - kRtpTimestampFieldNumber = 5, - kSsrcFieldNumber = 6, - kPayloadSizeFieldNumber = 8, - kHeaderSizeFieldNumber = 9, - kPaddingSizeFieldNumber = 10, - kNumberOfDeltasFieldNumber = 11, - kMarkerFieldNumber = 2, - kVoiceActivityFieldNumber = 20, - kTransportSequenceNumberFieldNumber = 15, - kTransmissionTimeOffsetFieldNumber = 16, - kAbsoluteSendTimeFieldNumber = 17, - kVideoRotationFieldNumber = 18, - kAudioLevelFieldNumber = 19, - }; - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes marker_deltas = 102; - bool has_marker_deltas() const; - void clear_marker_deltas(); - const std::string& marker_deltas() const; - void set_marker_deltas(const std::string& value); - void set_marker_deltas(std::string&& value); - void set_marker_deltas(const char* value); - void set_marker_deltas(const void* value, size_t size); - std::string* mutable_marker_deltas(); - std::string* release_marker_deltas(); - void set_allocated_marker_deltas(std::string* marker_deltas); - - // optional bytes payload_type_deltas = 103; - bool has_payload_type_deltas() const; - void clear_payload_type_deltas(); - const std::string& payload_type_deltas() const; - void set_payload_type_deltas(const std::string& value); - void set_payload_type_deltas(std::string&& value); - void set_payload_type_deltas(const char* value); - void set_payload_type_deltas(const void* value, size_t size); - std::string* mutable_payload_type_deltas(); - std::string* release_payload_type_deltas(); - void set_allocated_payload_type_deltas(std::string* payload_type_deltas); - - // optional bytes sequence_number_deltas = 104; - bool has_sequence_number_deltas() const; - void clear_sequence_number_deltas(); - const std::string& sequence_number_deltas() const; - void set_sequence_number_deltas(const std::string& value); - void set_sequence_number_deltas(std::string&& value); - void set_sequence_number_deltas(const char* value); - void set_sequence_number_deltas(const void* value, size_t size); - std::string* mutable_sequence_number_deltas(); - std::string* release_sequence_number_deltas(); - void set_allocated_sequence_number_deltas(std::string* sequence_number_deltas); - - // optional bytes rtp_timestamp_deltas = 105; - bool has_rtp_timestamp_deltas() const; - void clear_rtp_timestamp_deltas(); - const std::string& rtp_timestamp_deltas() const; - void set_rtp_timestamp_deltas(const std::string& value); - void set_rtp_timestamp_deltas(std::string&& value); - void set_rtp_timestamp_deltas(const char* value); - void set_rtp_timestamp_deltas(const void* value, size_t size); - std::string* mutable_rtp_timestamp_deltas(); - std::string* release_rtp_timestamp_deltas(); - void set_allocated_rtp_timestamp_deltas(std::string* rtp_timestamp_deltas); - - // optional bytes ssrc_deltas = 106; - bool has_ssrc_deltas() const; - void clear_ssrc_deltas(); - const std::string& ssrc_deltas() const; - void set_ssrc_deltas(const std::string& value); - void set_ssrc_deltas(std::string&& value); - void set_ssrc_deltas(const char* value); - void set_ssrc_deltas(const void* value, size_t size); - std::string* mutable_ssrc_deltas(); - std::string* release_ssrc_deltas(); - void set_allocated_ssrc_deltas(std::string* ssrc_deltas); - - // optional bytes payload_size_deltas = 108; - bool has_payload_size_deltas() const; - void clear_payload_size_deltas(); - const std::string& payload_size_deltas() const; - void set_payload_size_deltas(const std::string& value); - void set_payload_size_deltas(std::string&& value); - void set_payload_size_deltas(const char* value); - void set_payload_size_deltas(const void* value, size_t size); - std::string* mutable_payload_size_deltas(); - std::string* release_payload_size_deltas(); - void set_allocated_payload_size_deltas(std::string* payload_size_deltas); - - // optional bytes header_size_deltas = 109; - bool has_header_size_deltas() const; - void clear_header_size_deltas(); - const std::string& header_size_deltas() const; - void set_header_size_deltas(const std::string& value); - void set_header_size_deltas(std::string&& value); - void set_header_size_deltas(const char* value); - void set_header_size_deltas(const void* value, size_t size); - std::string* mutable_header_size_deltas(); - std::string* release_header_size_deltas(); - void set_allocated_header_size_deltas(std::string* header_size_deltas); - - // optional bytes padding_size_deltas = 110; - bool has_padding_size_deltas() const; - void clear_padding_size_deltas(); - const std::string& padding_size_deltas() const; - void set_padding_size_deltas(const std::string& value); - void set_padding_size_deltas(std::string&& value); - void set_padding_size_deltas(const char* value); - void set_padding_size_deltas(const void* value, size_t size); - std::string* mutable_padding_size_deltas(); - std::string* release_padding_size_deltas(); - void set_allocated_padding_size_deltas(std::string* padding_size_deltas); - - // optional bytes transport_sequence_number_deltas = 115; - bool has_transport_sequence_number_deltas() const; - void clear_transport_sequence_number_deltas(); - const std::string& transport_sequence_number_deltas() const; - void set_transport_sequence_number_deltas(const std::string& value); - void set_transport_sequence_number_deltas(std::string&& value); - void set_transport_sequence_number_deltas(const char* value); - void set_transport_sequence_number_deltas(const void* value, size_t size); - std::string* mutable_transport_sequence_number_deltas(); - std::string* release_transport_sequence_number_deltas(); - void set_allocated_transport_sequence_number_deltas(std::string* transport_sequence_number_deltas); - - // optional bytes transmission_time_offset_deltas = 116; - bool has_transmission_time_offset_deltas() const; - void clear_transmission_time_offset_deltas(); - const std::string& transmission_time_offset_deltas() const; - void set_transmission_time_offset_deltas(const std::string& value); - void set_transmission_time_offset_deltas(std::string&& value); - void set_transmission_time_offset_deltas(const char* value); - void set_transmission_time_offset_deltas(const void* value, size_t size); - std::string* mutable_transmission_time_offset_deltas(); - std::string* release_transmission_time_offset_deltas(); - void set_allocated_transmission_time_offset_deltas(std::string* transmission_time_offset_deltas); - - // optional bytes absolute_send_time_deltas = 117; - bool has_absolute_send_time_deltas() const; - void clear_absolute_send_time_deltas(); - const std::string& absolute_send_time_deltas() const; - void set_absolute_send_time_deltas(const std::string& value); - void set_absolute_send_time_deltas(std::string&& value); - void set_absolute_send_time_deltas(const char* value); - void set_absolute_send_time_deltas(const void* value, size_t size); - std::string* mutable_absolute_send_time_deltas(); - std::string* release_absolute_send_time_deltas(); - void set_allocated_absolute_send_time_deltas(std::string* absolute_send_time_deltas); - - // optional bytes video_rotation_deltas = 118; - bool has_video_rotation_deltas() const; - void clear_video_rotation_deltas(); - const std::string& video_rotation_deltas() const; - void set_video_rotation_deltas(const std::string& value); - void set_video_rotation_deltas(std::string&& value); - void set_video_rotation_deltas(const char* value); - void set_video_rotation_deltas(const void* value, size_t size); - std::string* mutable_video_rotation_deltas(); - std::string* release_video_rotation_deltas(); - void set_allocated_video_rotation_deltas(std::string* video_rotation_deltas); - - // optional bytes audio_level_deltas = 119; - bool has_audio_level_deltas() const; - void clear_audio_level_deltas(); - const std::string& audio_level_deltas() const; - void set_audio_level_deltas(const std::string& value); - void set_audio_level_deltas(std::string&& value); - void set_audio_level_deltas(const char* value); - void set_audio_level_deltas(const void* value, size_t size); - std::string* mutable_audio_level_deltas(); - std::string* release_audio_level_deltas(); - void set_allocated_audio_level_deltas(std::string* audio_level_deltas); - - // optional bytes voice_activity_deltas = 120; - bool has_voice_activity_deltas() const; - void clear_voice_activity_deltas(); - const std::string& voice_activity_deltas() const; - void set_voice_activity_deltas(const std::string& value); - void set_voice_activity_deltas(std::string&& value); - void set_voice_activity_deltas(const char* value); - void set_voice_activity_deltas(const void* value, size_t size); - std::string* mutable_voice_activity_deltas(); - std::string* release_voice_activity_deltas(); - void set_allocated_voice_activity_deltas(std::string* voice_activity_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 payload_type = 3; - bool has_payload_type() const; - void clear_payload_type(); - ::PROTOBUF_NAMESPACE_ID::uint32 payload_type() const; - void set_payload_type(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 sequence_number = 4; - bool has_sequence_number() const; - void clear_sequence_number(); - ::PROTOBUF_NAMESPACE_ID::uint32 sequence_number() const; - void set_sequence_number(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional fixed32 rtp_timestamp = 5; - bool has_rtp_timestamp() const; - void clear_rtp_timestamp(); - ::PROTOBUF_NAMESPACE_ID::uint32 rtp_timestamp() const; - void set_rtp_timestamp(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional fixed32 ssrc = 6; - bool has_ssrc() const; - void clear_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc() const; - void set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 payload_size = 8; - bool has_payload_size() const; - void clear_payload_size(); - ::PROTOBUF_NAMESPACE_ID::uint32 payload_size() const; - void set_payload_size(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 header_size = 9; - bool has_header_size() const; - void clear_header_size(); - ::PROTOBUF_NAMESPACE_ID::uint32 header_size() const; - void set_header_size(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 padding_size = 10; - bool has_padding_size() const; - void clear_padding_size(); - ::PROTOBUF_NAMESPACE_ID::uint32 padding_size() const; - void set_padding_size(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 number_of_deltas = 11; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional bool marker = 2; - bool has_marker() const; - void clear_marker(); - bool marker() const; - void set_marker(bool value); - - // optional bool voice_activity = 20; - bool has_voice_activity() const; - void clear_voice_activity(); - bool voice_activity() const; - void set_voice_activity(bool value); - - // optional uint32 transport_sequence_number = 15; - bool has_transport_sequence_number() const; - void clear_transport_sequence_number(); - ::PROTOBUF_NAMESPACE_ID::uint32 transport_sequence_number() const; - void set_transport_sequence_number(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional int32 transmission_time_offset = 16; - bool has_transmission_time_offset() const; - void clear_transmission_time_offset(); - ::PROTOBUF_NAMESPACE_ID::int32 transmission_time_offset() const; - void set_transmission_time_offset(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional uint32 absolute_send_time = 17; - bool has_absolute_send_time() const; - void clear_absolute_send_time(); - ::PROTOBUF_NAMESPACE_ID::uint32 absolute_send_time() const; - void set_absolute_send_time(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 video_rotation = 18; - bool has_video_rotation() const; - void clear_video_rotation(); - ::PROTOBUF_NAMESPACE_ID::uint32 video_rotation() const; - void set_video_rotation(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 audio_level = 19; - bool has_audio_level() const; - void clear_audio_level(); - ::PROTOBUF_NAMESPACE_ID::uint32 audio_level() const; - void set_audio_level(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.IncomingRtpPackets) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr marker_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr payload_type_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr sequence_number_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr rtp_timestamp_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr ssrc_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr payload_size_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr header_size_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr padding_size_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr transport_sequence_number_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr transmission_time_offset_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr absolute_send_time_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr video_rotation_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr audio_level_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr voice_activity_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 payload_type_; - ::PROTOBUF_NAMESPACE_ID::uint32 sequence_number_; - ::PROTOBUF_NAMESPACE_ID::uint32 rtp_timestamp_; - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 payload_size_; - ::PROTOBUF_NAMESPACE_ID::uint32 header_size_; - ::PROTOBUF_NAMESPACE_ID::uint32 padding_size_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - bool marker_; - bool voice_activity_; - ::PROTOBUF_NAMESPACE_ID::uint32 transport_sequence_number_; - ::PROTOBUF_NAMESPACE_ID::int32 transmission_time_offset_; - ::PROTOBUF_NAMESPACE_ID::uint32 absolute_send_time_; - ::PROTOBUF_NAMESPACE_ID::uint32 video_rotation_; - ::PROTOBUF_NAMESPACE_ID::uint32 audio_level_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class OutgoingRtpPackets : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.OutgoingRtpPackets) */ { - public: - OutgoingRtpPackets(); - virtual ~OutgoingRtpPackets(); - - OutgoingRtpPackets(const OutgoingRtpPackets& from); - OutgoingRtpPackets(OutgoingRtpPackets&& from) noexcept - : OutgoingRtpPackets() { - *this = ::std::move(from); - } - - inline OutgoingRtpPackets& operator=(const OutgoingRtpPackets& from) { - CopyFrom(from); - return *this; - } - inline OutgoingRtpPackets& operator=(OutgoingRtpPackets&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const OutgoingRtpPackets& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const OutgoingRtpPackets* internal_default_instance() { - return reinterpret_cast( - &_OutgoingRtpPackets_default_instance_); - } - static constexpr int kIndexInFileMessages = - 6; - - friend void swap(OutgoingRtpPackets& a, OutgoingRtpPackets& b) { - a.Swap(&b); - } - inline void Swap(OutgoingRtpPackets* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline OutgoingRtpPackets* New() const final { - return CreateMaybeMessage(nullptr); - } - - OutgoingRtpPackets* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const OutgoingRtpPackets& from); - void MergeFrom(const OutgoingRtpPackets& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(OutgoingRtpPackets* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.OutgoingRtpPackets"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 101, - kMarkerDeltasFieldNumber = 102, - kPayloadTypeDeltasFieldNumber = 103, - kSequenceNumberDeltasFieldNumber = 104, - kRtpTimestampDeltasFieldNumber = 105, - kSsrcDeltasFieldNumber = 106, - kPayloadSizeDeltasFieldNumber = 108, - kHeaderSizeDeltasFieldNumber = 109, - kPaddingSizeDeltasFieldNumber = 110, - kTransportSequenceNumberDeltasFieldNumber = 115, - kTransmissionTimeOffsetDeltasFieldNumber = 116, - kAbsoluteSendTimeDeltasFieldNumber = 117, - kVideoRotationDeltasFieldNumber = 118, - kAudioLevelDeltasFieldNumber = 119, - kVoiceActivityDeltasFieldNumber = 120, - kTimestampMsFieldNumber = 1, - kPayloadTypeFieldNumber = 3, - kSequenceNumberFieldNumber = 4, - kRtpTimestampFieldNumber = 5, - kSsrcFieldNumber = 6, - kPayloadSizeFieldNumber = 8, - kHeaderSizeFieldNumber = 9, - kPaddingSizeFieldNumber = 10, - kNumberOfDeltasFieldNumber = 11, - kMarkerFieldNumber = 2, - kVoiceActivityFieldNumber = 20, - kTransportSequenceNumberFieldNumber = 15, - kTransmissionTimeOffsetFieldNumber = 16, - kAbsoluteSendTimeFieldNumber = 17, - kVideoRotationFieldNumber = 18, - kAudioLevelFieldNumber = 19, - }; - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes marker_deltas = 102; - bool has_marker_deltas() const; - void clear_marker_deltas(); - const std::string& marker_deltas() const; - void set_marker_deltas(const std::string& value); - void set_marker_deltas(std::string&& value); - void set_marker_deltas(const char* value); - void set_marker_deltas(const void* value, size_t size); - std::string* mutable_marker_deltas(); - std::string* release_marker_deltas(); - void set_allocated_marker_deltas(std::string* marker_deltas); - - // optional bytes payload_type_deltas = 103; - bool has_payload_type_deltas() const; - void clear_payload_type_deltas(); - const std::string& payload_type_deltas() const; - void set_payload_type_deltas(const std::string& value); - void set_payload_type_deltas(std::string&& value); - void set_payload_type_deltas(const char* value); - void set_payload_type_deltas(const void* value, size_t size); - std::string* mutable_payload_type_deltas(); - std::string* release_payload_type_deltas(); - void set_allocated_payload_type_deltas(std::string* payload_type_deltas); - - // optional bytes sequence_number_deltas = 104; - bool has_sequence_number_deltas() const; - void clear_sequence_number_deltas(); - const std::string& sequence_number_deltas() const; - void set_sequence_number_deltas(const std::string& value); - void set_sequence_number_deltas(std::string&& value); - void set_sequence_number_deltas(const char* value); - void set_sequence_number_deltas(const void* value, size_t size); - std::string* mutable_sequence_number_deltas(); - std::string* release_sequence_number_deltas(); - void set_allocated_sequence_number_deltas(std::string* sequence_number_deltas); - - // optional bytes rtp_timestamp_deltas = 105; - bool has_rtp_timestamp_deltas() const; - void clear_rtp_timestamp_deltas(); - const std::string& rtp_timestamp_deltas() const; - void set_rtp_timestamp_deltas(const std::string& value); - void set_rtp_timestamp_deltas(std::string&& value); - void set_rtp_timestamp_deltas(const char* value); - void set_rtp_timestamp_deltas(const void* value, size_t size); - std::string* mutable_rtp_timestamp_deltas(); - std::string* release_rtp_timestamp_deltas(); - void set_allocated_rtp_timestamp_deltas(std::string* rtp_timestamp_deltas); - - // optional bytes ssrc_deltas = 106; - bool has_ssrc_deltas() const; - void clear_ssrc_deltas(); - const std::string& ssrc_deltas() const; - void set_ssrc_deltas(const std::string& value); - void set_ssrc_deltas(std::string&& value); - void set_ssrc_deltas(const char* value); - void set_ssrc_deltas(const void* value, size_t size); - std::string* mutable_ssrc_deltas(); - std::string* release_ssrc_deltas(); - void set_allocated_ssrc_deltas(std::string* ssrc_deltas); - - // optional bytes payload_size_deltas = 108; - bool has_payload_size_deltas() const; - void clear_payload_size_deltas(); - const std::string& payload_size_deltas() const; - void set_payload_size_deltas(const std::string& value); - void set_payload_size_deltas(std::string&& value); - void set_payload_size_deltas(const char* value); - void set_payload_size_deltas(const void* value, size_t size); - std::string* mutable_payload_size_deltas(); - std::string* release_payload_size_deltas(); - void set_allocated_payload_size_deltas(std::string* payload_size_deltas); - - // optional bytes header_size_deltas = 109; - bool has_header_size_deltas() const; - void clear_header_size_deltas(); - const std::string& header_size_deltas() const; - void set_header_size_deltas(const std::string& value); - void set_header_size_deltas(std::string&& value); - void set_header_size_deltas(const char* value); - void set_header_size_deltas(const void* value, size_t size); - std::string* mutable_header_size_deltas(); - std::string* release_header_size_deltas(); - void set_allocated_header_size_deltas(std::string* header_size_deltas); - - // optional bytes padding_size_deltas = 110; - bool has_padding_size_deltas() const; - void clear_padding_size_deltas(); - const std::string& padding_size_deltas() const; - void set_padding_size_deltas(const std::string& value); - void set_padding_size_deltas(std::string&& value); - void set_padding_size_deltas(const char* value); - void set_padding_size_deltas(const void* value, size_t size); - std::string* mutable_padding_size_deltas(); - std::string* release_padding_size_deltas(); - void set_allocated_padding_size_deltas(std::string* padding_size_deltas); - - // optional bytes transport_sequence_number_deltas = 115; - bool has_transport_sequence_number_deltas() const; - void clear_transport_sequence_number_deltas(); - const std::string& transport_sequence_number_deltas() const; - void set_transport_sequence_number_deltas(const std::string& value); - void set_transport_sequence_number_deltas(std::string&& value); - void set_transport_sequence_number_deltas(const char* value); - void set_transport_sequence_number_deltas(const void* value, size_t size); - std::string* mutable_transport_sequence_number_deltas(); - std::string* release_transport_sequence_number_deltas(); - void set_allocated_transport_sequence_number_deltas(std::string* transport_sequence_number_deltas); - - // optional bytes transmission_time_offset_deltas = 116; - bool has_transmission_time_offset_deltas() const; - void clear_transmission_time_offset_deltas(); - const std::string& transmission_time_offset_deltas() const; - void set_transmission_time_offset_deltas(const std::string& value); - void set_transmission_time_offset_deltas(std::string&& value); - void set_transmission_time_offset_deltas(const char* value); - void set_transmission_time_offset_deltas(const void* value, size_t size); - std::string* mutable_transmission_time_offset_deltas(); - std::string* release_transmission_time_offset_deltas(); - void set_allocated_transmission_time_offset_deltas(std::string* transmission_time_offset_deltas); - - // optional bytes absolute_send_time_deltas = 117; - bool has_absolute_send_time_deltas() const; - void clear_absolute_send_time_deltas(); - const std::string& absolute_send_time_deltas() const; - void set_absolute_send_time_deltas(const std::string& value); - void set_absolute_send_time_deltas(std::string&& value); - void set_absolute_send_time_deltas(const char* value); - void set_absolute_send_time_deltas(const void* value, size_t size); - std::string* mutable_absolute_send_time_deltas(); - std::string* release_absolute_send_time_deltas(); - void set_allocated_absolute_send_time_deltas(std::string* absolute_send_time_deltas); - - // optional bytes video_rotation_deltas = 118; - bool has_video_rotation_deltas() const; - void clear_video_rotation_deltas(); - const std::string& video_rotation_deltas() const; - void set_video_rotation_deltas(const std::string& value); - void set_video_rotation_deltas(std::string&& value); - void set_video_rotation_deltas(const char* value); - void set_video_rotation_deltas(const void* value, size_t size); - std::string* mutable_video_rotation_deltas(); - std::string* release_video_rotation_deltas(); - void set_allocated_video_rotation_deltas(std::string* video_rotation_deltas); - - // optional bytes audio_level_deltas = 119; - bool has_audio_level_deltas() const; - void clear_audio_level_deltas(); - const std::string& audio_level_deltas() const; - void set_audio_level_deltas(const std::string& value); - void set_audio_level_deltas(std::string&& value); - void set_audio_level_deltas(const char* value); - void set_audio_level_deltas(const void* value, size_t size); - std::string* mutable_audio_level_deltas(); - std::string* release_audio_level_deltas(); - void set_allocated_audio_level_deltas(std::string* audio_level_deltas); - - // optional bytes voice_activity_deltas = 120; - bool has_voice_activity_deltas() const; - void clear_voice_activity_deltas(); - const std::string& voice_activity_deltas() const; - void set_voice_activity_deltas(const std::string& value); - void set_voice_activity_deltas(std::string&& value); - void set_voice_activity_deltas(const char* value); - void set_voice_activity_deltas(const void* value, size_t size); - std::string* mutable_voice_activity_deltas(); - std::string* release_voice_activity_deltas(); - void set_allocated_voice_activity_deltas(std::string* voice_activity_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 payload_type = 3; - bool has_payload_type() const; - void clear_payload_type(); - ::PROTOBUF_NAMESPACE_ID::uint32 payload_type() const; - void set_payload_type(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 sequence_number = 4; - bool has_sequence_number() const; - void clear_sequence_number(); - ::PROTOBUF_NAMESPACE_ID::uint32 sequence_number() const; - void set_sequence_number(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional fixed32 rtp_timestamp = 5; - bool has_rtp_timestamp() const; - void clear_rtp_timestamp(); - ::PROTOBUF_NAMESPACE_ID::uint32 rtp_timestamp() const; - void set_rtp_timestamp(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional fixed32 ssrc = 6; - bool has_ssrc() const; - void clear_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc() const; - void set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 payload_size = 8; - bool has_payload_size() const; - void clear_payload_size(); - ::PROTOBUF_NAMESPACE_ID::uint32 payload_size() const; - void set_payload_size(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 header_size = 9; - bool has_header_size() const; - void clear_header_size(); - ::PROTOBUF_NAMESPACE_ID::uint32 header_size() const; - void set_header_size(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 padding_size = 10; - bool has_padding_size() const; - void clear_padding_size(); - ::PROTOBUF_NAMESPACE_ID::uint32 padding_size() const; - void set_padding_size(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 number_of_deltas = 11; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional bool marker = 2; - bool has_marker() const; - void clear_marker(); - bool marker() const; - void set_marker(bool value); - - // optional bool voice_activity = 20; - bool has_voice_activity() const; - void clear_voice_activity(); - bool voice_activity() const; - void set_voice_activity(bool value); - - // optional uint32 transport_sequence_number = 15; - bool has_transport_sequence_number() const; - void clear_transport_sequence_number(); - ::PROTOBUF_NAMESPACE_ID::uint32 transport_sequence_number() const; - void set_transport_sequence_number(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional int32 transmission_time_offset = 16; - bool has_transmission_time_offset() const; - void clear_transmission_time_offset(); - ::PROTOBUF_NAMESPACE_ID::int32 transmission_time_offset() const; - void set_transmission_time_offset(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional uint32 absolute_send_time = 17; - bool has_absolute_send_time() const; - void clear_absolute_send_time(); - ::PROTOBUF_NAMESPACE_ID::uint32 absolute_send_time() const; - void set_absolute_send_time(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 video_rotation = 18; - bool has_video_rotation() const; - void clear_video_rotation(); - ::PROTOBUF_NAMESPACE_ID::uint32 video_rotation() const; - void set_video_rotation(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 audio_level = 19; - bool has_audio_level() const; - void clear_audio_level(); - ::PROTOBUF_NAMESPACE_ID::uint32 audio_level() const; - void set_audio_level(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.OutgoingRtpPackets) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr marker_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr payload_type_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr sequence_number_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr rtp_timestamp_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr ssrc_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr payload_size_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr header_size_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr padding_size_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr transport_sequence_number_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr transmission_time_offset_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr absolute_send_time_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr video_rotation_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr audio_level_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr voice_activity_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 payload_type_; - ::PROTOBUF_NAMESPACE_ID::uint32 sequence_number_; - ::PROTOBUF_NAMESPACE_ID::uint32 rtp_timestamp_; - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 payload_size_; - ::PROTOBUF_NAMESPACE_ID::uint32 header_size_; - ::PROTOBUF_NAMESPACE_ID::uint32 padding_size_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - bool marker_; - bool voice_activity_; - ::PROTOBUF_NAMESPACE_ID::uint32 transport_sequence_number_; - ::PROTOBUF_NAMESPACE_ID::int32 transmission_time_offset_; - ::PROTOBUF_NAMESPACE_ID::uint32 absolute_send_time_; - ::PROTOBUF_NAMESPACE_ID::uint32 video_rotation_; - ::PROTOBUF_NAMESPACE_ID::uint32 audio_level_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class IncomingRtcpPackets : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.IncomingRtcpPackets) */ { - public: - IncomingRtcpPackets(); - virtual ~IncomingRtcpPackets(); - - IncomingRtcpPackets(const IncomingRtcpPackets& from); - IncomingRtcpPackets(IncomingRtcpPackets&& from) noexcept - : IncomingRtcpPackets() { - *this = ::std::move(from); - } - - inline IncomingRtcpPackets& operator=(const IncomingRtcpPackets& from) { - CopyFrom(from); - return *this; - } - inline IncomingRtcpPackets& operator=(IncomingRtcpPackets&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const IncomingRtcpPackets& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const IncomingRtcpPackets* internal_default_instance() { - return reinterpret_cast( - &_IncomingRtcpPackets_default_instance_); - } - static constexpr int kIndexInFileMessages = - 7; - - friend void swap(IncomingRtcpPackets& a, IncomingRtcpPackets& b) { - a.Swap(&b); - } - inline void Swap(IncomingRtcpPackets* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline IncomingRtcpPackets* New() const final { - return CreateMaybeMessage(nullptr); - } - - IncomingRtcpPackets* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const IncomingRtcpPackets& from); - void MergeFrom(const IncomingRtcpPackets& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(IncomingRtcpPackets* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.IncomingRtcpPackets"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kRawPacketFieldNumber = 2, - kTimestampMsDeltasFieldNumber = 101, - kRawPacketBlobsFieldNumber = 102, - kTimestampMsFieldNumber = 1, - kNumberOfDeltasFieldNumber = 3, - }; - // optional bytes raw_packet = 2; - bool has_raw_packet() const; - void clear_raw_packet(); - const std::string& raw_packet() const; - void set_raw_packet(const std::string& value); - void set_raw_packet(std::string&& value); - void set_raw_packet(const char* value); - void set_raw_packet(const void* value, size_t size); - std::string* mutable_raw_packet(); - std::string* release_raw_packet(); - void set_allocated_raw_packet(std::string* raw_packet); - - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes raw_packet_blobs = 102; - bool has_raw_packet_blobs() const; - void clear_raw_packet_blobs(); - const std::string& raw_packet_blobs() const; - void set_raw_packet_blobs(const std::string& value); - void set_raw_packet_blobs(std::string&& value); - void set_raw_packet_blobs(const char* value); - void set_raw_packet_blobs(const void* value, size_t size); - std::string* mutable_raw_packet_blobs(); - std::string* release_raw_packet_blobs(); - void set_allocated_raw_packet_blobs(std::string* raw_packet_blobs); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 number_of_deltas = 3; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.IncomingRtcpPackets) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr raw_packet_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr raw_packet_blobs_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class OutgoingRtcpPackets : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.OutgoingRtcpPackets) */ { - public: - OutgoingRtcpPackets(); - virtual ~OutgoingRtcpPackets(); - - OutgoingRtcpPackets(const OutgoingRtcpPackets& from); - OutgoingRtcpPackets(OutgoingRtcpPackets&& from) noexcept - : OutgoingRtcpPackets() { - *this = ::std::move(from); - } - - inline OutgoingRtcpPackets& operator=(const OutgoingRtcpPackets& from) { - CopyFrom(from); - return *this; - } - inline OutgoingRtcpPackets& operator=(OutgoingRtcpPackets&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const OutgoingRtcpPackets& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const OutgoingRtcpPackets* internal_default_instance() { - return reinterpret_cast( - &_OutgoingRtcpPackets_default_instance_); - } - static constexpr int kIndexInFileMessages = - 8; - - friend void swap(OutgoingRtcpPackets& a, OutgoingRtcpPackets& b) { - a.Swap(&b); - } - inline void Swap(OutgoingRtcpPackets* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline OutgoingRtcpPackets* New() const final { - return CreateMaybeMessage(nullptr); - } - - OutgoingRtcpPackets* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const OutgoingRtcpPackets& from); - void MergeFrom(const OutgoingRtcpPackets& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(OutgoingRtcpPackets* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.OutgoingRtcpPackets"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kRawPacketFieldNumber = 2, - kTimestampMsDeltasFieldNumber = 101, - kRawPacketBlobsFieldNumber = 102, - kTimestampMsFieldNumber = 1, - kNumberOfDeltasFieldNumber = 3, - }; - // optional bytes raw_packet = 2; - bool has_raw_packet() const; - void clear_raw_packet(); - const std::string& raw_packet() const; - void set_raw_packet(const std::string& value); - void set_raw_packet(std::string&& value); - void set_raw_packet(const char* value); - void set_raw_packet(const void* value, size_t size); - std::string* mutable_raw_packet(); - std::string* release_raw_packet(); - void set_allocated_raw_packet(std::string* raw_packet); - - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes raw_packet_blobs = 102; - bool has_raw_packet_blobs() const; - void clear_raw_packet_blobs(); - const std::string& raw_packet_blobs() const; - void set_raw_packet_blobs(const std::string& value); - void set_raw_packet_blobs(std::string&& value); - void set_raw_packet_blobs(const char* value); - void set_raw_packet_blobs(const void* value, size_t size); - std::string* mutable_raw_packet_blobs(); - std::string* release_raw_packet_blobs(); - void set_allocated_raw_packet_blobs(std::string* raw_packet_blobs); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 number_of_deltas = 3; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.OutgoingRtcpPackets) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr raw_packet_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr raw_packet_blobs_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class AudioPlayoutEvents : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.AudioPlayoutEvents) */ { - public: - AudioPlayoutEvents(); - virtual ~AudioPlayoutEvents(); - - AudioPlayoutEvents(const AudioPlayoutEvents& from); - AudioPlayoutEvents(AudioPlayoutEvents&& from) noexcept - : AudioPlayoutEvents() { - *this = ::std::move(from); - } - - inline AudioPlayoutEvents& operator=(const AudioPlayoutEvents& from) { - CopyFrom(from); - return *this; - } - inline AudioPlayoutEvents& operator=(AudioPlayoutEvents&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AudioPlayoutEvents& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AudioPlayoutEvents* internal_default_instance() { - return reinterpret_cast( - &_AudioPlayoutEvents_default_instance_); - } - static constexpr int kIndexInFileMessages = - 9; - - friend void swap(AudioPlayoutEvents& a, AudioPlayoutEvents& b) { - a.Swap(&b); - } - inline void Swap(AudioPlayoutEvents* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AudioPlayoutEvents* New() const final { - return CreateMaybeMessage(nullptr); - } - - AudioPlayoutEvents* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AudioPlayoutEvents& from); - void MergeFrom(const AudioPlayoutEvents& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AudioPlayoutEvents* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.AudioPlayoutEvents"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 101, - kLocalSsrcDeltasFieldNumber = 102, - kTimestampMsFieldNumber = 1, - kLocalSsrcFieldNumber = 2, - kNumberOfDeltasFieldNumber = 3, - }; - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes local_ssrc_deltas = 102; - bool has_local_ssrc_deltas() const; - void clear_local_ssrc_deltas(); - const std::string& local_ssrc_deltas() const; - void set_local_ssrc_deltas(const std::string& value); - void set_local_ssrc_deltas(std::string&& value); - void set_local_ssrc_deltas(const char* value); - void set_local_ssrc_deltas(const void* value, size_t size); - std::string* mutable_local_ssrc_deltas(); - std::string* release_local_ssrc_deltas(); - void set_allocated_local_ssrc_deltas(std::string* local_ssrc_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 local_ssrc = 2; - bool has_local_ssrc() const; - void clear_local_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc() const; - void set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 number_of_deltas = 3; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.AudioPlayoutEvents) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr local_ssrc_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class FrameDecodedEvents : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.FrameDecodedEvents) */ { - public: - FrameDecodedEvents(); - virtual ~FrameDecodedEvents(); - - FrameDecodedEvents(const FrameDecodedEvents& from); - FrameDecodedEvents(FrameDecodedEvents&& from) noexcept - : FrameDecodedEvents() { - *this = ::std::move(from); - } - - inline FrameDecodedEvents& operator=(const FrameDecodedEvents& from) { - CopyFrom(from); - return *this; - } - inline FrameDecodedEvents& operator=(FrameDecodedEvents&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const FrameDecodedEvents& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const FrameDecodedEvents* internal_default_instance() { - return reinterpret_cast( - &_FrameDecodedEvents_default_instance_); - } - static constexpr int kIndexInFileMessages = - 10; - - friend void swap(FrameDecodedEvents& a, FrameDecodedEvents& b) { - a.Swap(&b); - } - inline void Swap(FrameDecodedEvents* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline FrameDecodedEvents* New() const final { - return CreateMaybeMessage(nullptr); - } - - FrameDecodedEvents* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const FrameDecodedEvents& from); - void MergeFrom(const FrameDecodedEvents& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(FrameDecodedEvents* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.FrameDecodedEvents"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef FrameDecodedEvents_Codec Codec; - static constexpr Codec CODEC_UNKNOWN = - FrameDecodedEvents_Codec_CODEC_UNKNOWN; - static constexpr Codec CODEC_GENERIC = - FrameDecodedEvents_Codec_CODEC_GENERIC; - static constexpr Codec CODEC_VP8 = - FrameDecodedEvents_Codec_CODEC_VP8; - static constexpr Codec CODEC_VP9 = - FrameDecodedEvents_Codec_CODEC_VP9; - static constexpr Codec CODEC_AV1 = - FrameDecodedEvents_Codec_CODEC_AV1; - static constexpr Codec CODEC_H264 = - FrameDecodedEvents_Codec_CODEC_H264; - static constexpr Codec CODEC_H265 = - FrameDecodedEvents_Codec_CODEC_H265; - static inline bool Codec_IsValid(int value) { - return FrameDecodedEvents_Codec_IsValid(value); - } - static constexpr Codec Codec_MIN = - FrameDecodedEvents_Codec_Codec_MIN; - static constexpr Codec Codec_MAX = - FrameDecodedEvents_Codec_Codec_MAX; - static constexpr int Codec_ARRAYSIZE = - FrameDecodedEvents_Codec_Codec_ARRAYSIZE; - template - static inline const std::string& Codec_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function Codec_Name."); - return FrameDecodedEvents_Codec_Name(enum_t_value); - } - static inline bool Codec_Parse(const std::string& name, - Codec* value) { - return FrameDecodedEvents_Codec_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 101, - kSsrcDeltasFieldNumber = 102, - kRenderTimeMsDeltasFieldNumber = 103, - kWidthDeltasFieldNumber = 104, - kHeightDeltasFieldNumber = 105, - kCodecDeltasFieldNumber = 106, - kQpDeltasFieldNumber = 107, - kTimestampMsFieldNumber = 1, - kRenderTimeMsFieldNumber = 3, - kSsrcFieldNumber = 2, - kWidthFieldNumber = 4, - kHeightFieldNumber = 5, - kCodecFieldNumber = 6, - kQpFieldNumber = 7, - kNumberOfDeltasFieldNumber = 15, - }; - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes ssrc_deltas = 102; - bool has_ssrc_deltas() const; - void clear_ssrc_deltas(); - const std::string& ssrc_deltas() const; - void set_ssrc_deltas(const std::string& value); - void set_ssrc_deltas(std::string&& value); - void set_ssrc_deltas(const char* value); - void set_ssrc_deltas(const void* value, size_t size); - std::string* mutable_ssrc_deltas(); - std::string* release_ssrc_deltas(); - void set_allocated_ssrc_deltas(std::string* ssrc_deltas); - - // optional bytes render_time_ms_deltas = 103; - bool has_render_time_ms_deltas() const; - void clear_render_time_ms_deltas(); - const std::string& render_time_ms_deltas() const; - void set_render_time_ms_deltas(const std::string& value); - void set_render_time_ms_deltas(std::string&& value); - void set_render_time_ms_deltas(const char* value); - void set_render_time_ms_deltas(const void* value, size_t size); - std::string* mutable_render_time_ms_deltas(); - std::string* release_render_time_ms_deltas(); - void set_allocated_render_time_ms_deltas(std::string* render_time_ms_deltas); - - // optional bytes width_deltas = 104; - bool has_width_deltas() const; - void clear_width_deltas(); - const std::string& width_deltas() const; - void set_width_deltas(const std::string& value); - void set_width_deltas(std::string&& value); - void set_width_deltas(const char* value); - void set_width_deltas(const void* value, size_t size); - std::string* mutable_width_deltas(); - std::string* release_width_deltas(); - void set_allocated_width_deltas(std::string* width_deltas); - - // optional bytes height_deltas = 105; - bool has_height_deltas() const; - void clear_height_deltas(); - const std::string& height_deltas() const; - void set_height_deltas(const std::string& value); - void set_height_deltas(std::string&& value); - void set_height_deltas(const char* value); - void set_height_deltas(const void* value, size_t size); - std::string* mutable_height_deltas(); - std::string* release_height_deltas(); - void set_allocated_height_deltas(std::string* height_deltas); - - // optional bytes codec_deltas = 106; - bool has_codec_deltas() const; - void clear_codec_deltas(); - const std::string& codec_deltas() const; - void set_codec_deltas(const std::string& value); - void set_codec_deltas(std::string&& value); - void set_codec_deltas(const char* value); - void set_codec_deltas(const void* value, size_t size); - std::string* mutable_codec_deltas(); - std::string* release_codec_deltas(); - void set_allocated_codec_deltas(std::string* codec_deltas); - - // optional bytes qp_deltas = 107; - bool has_qp_deltas() const; - void clear_qp_deltas(); - const std::string& qp_deltas() const; - void set_qp_deltas(const std::string& value); - void set_qp_deltas(std::string&& value); - void set_qp_deltas(const char* value); - void set_qp_deltas(const void* value, size_t size); - std::string* mutable_qp_deltas(); - std::string* release_qp_deltas(); - void set_allocated_qp_deltas(std::string* qp_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int64 render_time_ms = 3; - bool has_render_time_ms() const; - void clear_render_time_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 render_time_ms() const; - void set_render_time_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional fixed32 ssrc = 2; - bool has_ssrc() const; - void clear_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc() const; - void set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional int32 width = 4; - bool has_width() const; - void clear_width(); - ::PROTOBUF_NAMESPACE_ID::int32 width() const; - void set_width(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 height = 5; - bool has_height() const; - void clear_height(); - ::PROTOBUF_NAMESPACE_ID::int32 height() const; - void set_height(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional .webrtc.rtclog2.FrameDecodedEvents.Codec codec = 6; - bool has_codec() const; - void clear_codec(); - ::webrtc::rtclog2::FrameDecodedEvents_Codec codec() const; - void set_codec(::webrtc::rtclog2::FrameDecodedEvents_Codec value); - - // optional uint32 qp = 7; - bool has_qp() const; - void clear_qp(); - ::PROTOBUF_NAMESPACE_ID::uint32 qp() const; - void set_qp(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 number_of_deltas = 15; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.FrameDecodedEvents) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr ssrc_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr render_time_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr width_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr height_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr codec_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr qp_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::int64 render_time_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc_; - ::PROTOBUF_NAMESPACE_ID::int32 width_; - ::PROTOBUF_NAMESPACE_ID::int32 height_; - int codec_; - ::PROTOBUF_NAMESPACE_ID::uint32 qp_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class BeginLogEvent : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.BeginLogEvent) */ { - public: - BeginLogEvent(); - virtual ~BeginLogEvent(); - - BeginLogEvent(const BeginLogEvent& from); - BeginLogEvent(BeginLogEvent&& from) noexcept - : BeginLogEvent() { - *this = ::std::move(from); - } - - inline BeginLogEvent& operator=(const BeginLogEvent& from) { - CopyFrom(from); - return *this; - } - inline BeginLogEvent& operator=(BeginLogEvent&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const BeginLogEvent& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const BeginLogEvent* internal_default_instance() { - return reinterpret_cast( - &_BeginLogEvent_default_instance_); - } - static constexpr int kIndexInFileMessages = - 11; - - friend void swap(BeginLogEvent& a, BeginLogEvent& b) { - a.Swap(&b); - } - inline void Swap(BeginLogEvent* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline BeginLogEvent* New() const final { - return CreateMaybeMessage(nullptr); - } - - BeginLogEvent* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const BeginLogEvent& from); - void MergeFrom(const BeginLogEvent& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(BeginLogEvent* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.BeginLogEvent"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kUtcTimeMsFieldNumber = 3, - kVersionFieldNumber = 2, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int64 utc_time_ms = 3; - bool has_utc_time_ms() const; - void clear_utc_time_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 utc_time_ms() const; - void set_utc_time_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 version = 2; - bool has_version() const; - void clear_version(); - ::PROTOBUF_NAMESPACE_ID::uint32 version() const; - void set_version(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.BeginLogEvent) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::int64 utc_time_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 version_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class EndLogEvent : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.EndLogEvent) */ { - public: - EndLogEvent(); - virtual ~EndLogEvent(); - - EndLogEvent(const EndLogEvent& from); - EndLogEvent(EndLogEvent&& from) noexcept - : EndLogEvent() { - *this = ::std::move(from); - } - - inline EndLogEvent& operator=(const EndLogEvent& from) { - CopyFrom(from); - return *this; - } - inline EndLogEvent& operator=(EndLogEvent&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const EndLogEvent& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const EndLogEvent* internal_default_instance() { - return reinterpret_cast( - &_EndLogEvent_default_instance_); - } - static constexpr int kIndexInFileMessages = - 12; - - friend void swap(EndLogEvent& a, EndLogEvent& b) { - a.Swap(&b); - } - inline void Swap(EndLogEvent* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline EndLogEvent* New() const final { - return CreateMaybeMessage(nullptr); - } - - EndLogEvent* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const EndLogEvent& from); - void MergeFrom(const EndLogEvent& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(EndLogEvent* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.EndLogEvent"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.EndLogEvent) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class LossBasedBweUpdates : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.LossBasedBweUpdates) */ { - public: - LossBasedBweUpdates(); - virtual ~LossBasedBweUpdates(); - - LossBasedBweUpdates(const LossBasedBweUpdates& from); - LossBasedBweUpdates(LossBasedBweUpdates&& from) noexcept - : LossBasedBweUpdates() { - *this = ::std::move(from); - } - - inline LossBasedBweUpdates& operator=(const LossBasedBweUpdates& from) { - CopyFrom(from); - return *this; - } - inline LossBasedBweUpdates& operator=(LossBasedBweUpdates&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const LossBasedBweUpdates& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const LossBasedBweUpdates* internal_default_instance() { - return reinterpret_cast( - &_LossBasedBweUpdates_default_instance_); - } - static constexpr int kIndexInFileMessages = - 13; - - friend void swap(LossBasedBweUpdates& a, LossBasedBweUpdates& b) { - a.Swap(&b); - } - inline void Swap(LossBasedBweUpdates* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline LossBasedBweUpdates* New() const final { - return CreateMaybeMessage(nullptr); - } - - LossBasedBweUpdates* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const LossBasedBweUpdates& from); - void MergeFrom(const LossBasedBweUpdates& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(LossBasedBweUpdates* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.LossBasedBweUpdates"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 101, - kBitrateBpsDeltasFieldNumber = 102, - kFractionLossDeltasFieldNumber = 103, - kTotalPacketsDeltasFieldNumber = 104, - kTimestampMsFieldNumber = 1, - kBitrateBpsFieldNumber = 2, - kFractionLossFieldNumber = 3, - kTotalPacketsFieldNumber = 4, - kNumberOfDeltasFieldNumber = 5, - }; - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes bitrate_bps_deltas = 102; - bool has_bitrate_bps_deltas() const; - void clear_bitrate_bps_deltas(); - const std::string& bitrate_bps_deltas() const; - void set_bitrate_bps_deltas(const std::string& value); - void set_bitrate_bps_deltas(std::string&& value); - void set_bitrate_bps_deltas(const char* value); - void set_bitrate_bps_deltas(const void* value, size_t size); - std::string* mutable_bitrate_bps_deltas(); - std::string* release_bitrate_bps_deltas(); - void set_allocated_bitrate_bps_deltas(std::string* bitrate_bps_deltas); - - // optional bytes fraction_loss_deltas = 103; - bool has_fraction_loss_deltas() const; - void clear_fraction_loss_deltas(); - const std::string& fraction_loss_deltas() const; - void set_fraction_loss_deltas(const std::string& value); - void set_fraction_loss_deltas(std::string&& value); - void set_fraction_loss_deltas(const char* value); - void set_fraction_loss_deltas(const void* value, size_t size); - std::string* mutable_fraction_loss_deltas(); - std::string* release_fraction_loss_deltas(); - void set_allocated_fraction_loss_deltas(std::string* fraction_loss_deltas); - - // optional bytes total_packets_deltas = 104; - bool has_total_packets_deltas() const; - void clear_total_packets_deltas(); - const std::string& total_packets_deltas() const; - void set_total_packets_deltas(const std::string& value); - void set_total_packets_deltas(std::string&& value); - void set_total_packets_deltas(const char* value); - void set_total_packets_deltas(const void* value, size_t size); - std::string* mutable_total_packets_deltas(); - std::string* release_total_packets_deltas(); - void set_allocated_total_packets_deltas(std::string* total_packets_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 bitrate_bps = 2; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::uint32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 fraction_loss = 3; - bool has_fraction_loss() const; - void clear_fraction_loss(); - ::PROTOBUF_NAMESPACE_ID::uint32 fraction_loss() const; - void set_fraction_loss(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 total_packets = 4; - bool has_total_packets() const; - void clear_total_packets(); - ::PROTOBUF_NAMESPACE_ID::uint32 total_packets() const; - void set_total_packets(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 number_of_deltas = 5; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.LossBasedBweUpdates) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr bitrate_bps_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr fraction_loss_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr total_packets_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 bitrate_bps_; - ::PROTOBUF_NAMESPACE_ID::uint32 fraction_loss_; - ::PROTOBUF_NAMESPACE_ID::uint32 total_packets_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class DelayBasedBweUpdates : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.DelayBasedBweUpdates) */ { - public: - DelayBasedBweUpdates(); - virtual ~DelayBasedBweUpdates(); - - DelayBasedBweUpdates(const DelayBasedBweUpdates& from); - DelayBasedBweUpdates(DelayBasedBweUpdates&& from) noexcept - : DelayBasedBweUpdates() { - *this = ::std::move(from); - } - - inline DelayBasedBweUpdates& operator=(const DelayBasedBweUpdates& from) { - CopyFrom(from); - return *this; - } - inline DelayBasedBweUpdates& operator=(DelayBasedBweUpdates&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const DelayBasedBweUpdates& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const DelayBasedBweUpdates* internal_default_instance() { - return reinterpret_cast( - &_DelayBasedBweUpdates_default_instance_); - } - static constexpr int kIndexInFileMessages = - 14; - - friend void swap(DelayBasedBweUpdates& a, DelayBasedBweUpdates& b) { - a.Swap(&b); - } - inline void Swap(DelayBasedBweUpdates* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline DelayBasedBweUpdates* New() const final { - return CreateMaybeMessage(nullptr); - } - - DelayBasedBweUpdates* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const DelayBasedBweUpdates& from); - void MergeFrom(const DelayBasedBweUpdates& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(DelayBasedBweUpdates* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.DelayBasedBweUpdates"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef DelayBasedBweUpdates_DetectorState DetectorState; - static constexpr DetectorState BWE_UNKNOWN_STATE = - DelayBasedBweUpdates_DetectorState_BWE_UNKNOWN_STATE; - static constexpr DetectorState BWE_NORMAL = - DelayBasedBweUpdates_DetectorState_BWE_NORMAL; - static constexpr DetectorState BWE_UNDERUSING = - DelayBasedBweUpdates_DetectorState_BWE_UNDERUSING; - static constexpr DetectorState BWE_OVERUSING = - DelayBasedBweUpdates_DetectorState_BWE_OVERUSING; - static inline bool DetectorState_IsValid(int value) { - return DelayBasedBweUpdates_DetectorState_IsValid(value); - } - static constexpr DetectorState DetectorState_MIN = - DelayBasedBweUpdates_DetectorState_DetectorState_MIN; - static constexpr DetectorState DetectorState_MAX = - DelayBasedBweUpdates_DetectorState_DetectorState_MAX; - static constexpr int DetectorState_ARRAYSIZE = - DelayBasedBweUpdates_DetectorState_DetectorState_ARRAYSIZE; - template - static inline const std::string& DetectorState_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function DetectorState_Name."); - return DelayBasedBweUpdates_DetectorState_Name(enum_t_value); - } - static inline bool DetectorState_Parse(const std::string& name, - DetectorState* value) { - return DelayBasedBweUpdates_DetectorState_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 101, - kBitrateBpsDeltasFieldNumber = 102, - kDetectorStateDeltasFieldNumber = 103, - kTimestampMsFieldNumber = 1, - kBitrateBpsFieldNumber = 2, - kDetectorStateFieldNumber = 3, - kNumberOfDeltasFieldNumber = 4, - }; - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes bitrate_bps_deltas = 102; - bool has_bitrate_bps_deltas() const; - void clear_bitrate_bps_deltas(); - const std::string& bitrate_bps_deltas() const; - void set_bitrate_bps_deltas(const std::string& value); - void set_bitrate_bps_deltas(std::string&& value); - void set_bitrate_bps_deltas(const char* value); - void set_bitrate_bps_deltas(const void* value, size_t size); - std::string* mutable_bitrate_bps_deltas(); - std::string* release_bitrate_bps_deltas(); - void set_allocated_bitrate_bps_deltas(std::string* bitrate_bps_deltas); - - // optional bytes detector_state_deltas = 103; - bool has_detector_state_deltas() const; - void clear_detector_state_deltas(); - const std::string& detector_state_deltas() const; - void set_detector_state_deltas(const std::string& value); - void set_detector_state_deltas(std::string&& value); - void set_detector_state_deltas(const char* value); - void set_detector_state_deltas(const void* value, size_t size); - std::string* mutable_detector_state_deltas(); - std::string* release_detector_state_deltas(); - void set_allocated_detector_state_deltas(std::string* detector_state_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 bitrate_bps = 2; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::uint32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional .webrtc.rtclog2.DelayBasedBweUpdates.DetectorState detector_state = 3; - bool has_detector_state() const; - void clear_detector_state(); - ::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState detector_state() const; - void set_detector_state(::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState value); - - // optional uint32 number_of_deltas = 4; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.DelayBasedBweUpdates) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr bitrate_bps_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr detector_state_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 bitrate_bps_; - int detector_state_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class RtpHeaderExtensionConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.RtpHeaderExtensionConfig) */ { - public: - RtpHeaderExtensionConfig(); - virtual ~RtpHeaderExtensionConfig(); - - RtpHeaderExtensionConfig(const RtpHeaderExtensionConfig& from); - RtpHeaderExtensionConfig(RtpHeaderExtensionConfig&& from) noexcept - : RtpHeaderExtensionConfig() { - *this = ::std::move(from); - } - - inline RtpHeaderExtensionConfig& operator=(const RtpHeaderExtensionConfig& from) { - CopyFrom(from); - return *this; - } - inline RtpHeaderExtensionConfig& operator=(RtpHeaderExtensionConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const RtpHeaderExtensionConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const RtpHeaderExtensionConfig* internal_default_instance() { - return reinterpret_cast( - &_RtpHeaderExtensionConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 15; - - friend void swap(RtpHeaderExtensionConfig& a, RtpHeaderExtensionConfig& b) { - a.Swap(&b); - } - inline void Swap(RtpHeaderExtensionConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline RtpHeaderExtensionConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - RtpHeaderExtensionConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const RtpHeaderExtensionConfig& from); - void MergeFrom(const RtpHeaderExtensionConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(RtpHeaderExtensionConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.RtpHeaderExtensionConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTransmissionTimeOffsetIdFieldNumber = 1, - kAbsoluteSendTimeIdFieldNumber = 2, - kTransportSequenceNumberIdFieldNumber = 3, - kVideoRotationIdFieldNumber = 4, - kAudioLevelIdFieldNumber = 5, - }; - // optional int32 transmission_time_offset_id = 1; - bool has_transmission_time_offset_id() const; - void clear_transmission_time_offset_id(); - ::PROTOBUF_NAMESPACE_ID::int32 transmission_time_offset_id() const; - void set_transmission_time_offset_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 absolute_send_time_id = 2; - bool has_absolute_send_time_id() const; - void clear_absolute_send_time_id(); - ::PROTOBUF_NAMESPACE_ID::int32 absolute_send_time_id() const; - void set_absolute_send_time_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 transport_sequence_number_id = 3; - bool has_transport_sequence_number_id() const; - void clear_transport_sequence_number_id(); - ::PROTOBUF_NAMESPACE_ID::int32 transport_sequence_number_id() const; - void set_transport_sequence_number_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 video_rotation_id = 4; - bool has_video_rotation_id() const; - void clear_video_rotation_id(); - ::PROTOBUF_NAMESPACE_ID::int32 video_rotation_id() const; - void set_video_rotation_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 audio_level_id = 5; - bool has_audio_level_id() const; - void clear_audio_level_id(); - ::PROTOBUF_NAMESPACE_ID::int32 audio_level_id() const; - void set_audio_level_id(::PROTOBUF_NAMESPACE_ID::int32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.RtpHeaderExtensionConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int32 transmission_time_offset_id_; - ::PROTOBUF_NAMESPACE_ID::int32 absolute_send_time_id_; - ::PROTOBUF_NAMESPACE_ID::int32 transport_sequence_number_id_; - ::PROTOBUF_NAMESPACE_ID::int32 video_rotation_id_; - ::PROTOBUF_NAMESPACE_ID::int32 audio_level_id_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class VideoRecvStreamConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.VideoRecvStreamConfig) */ { - public: - VideoRecvStreamConfig(); - virtual ~VideoRecvStreamConfig(); - - VideoRecvStreamConfig(const VideoRecvStreamConfig& from); - VideoRecvStreamConfig(VideoRecvStreamConfig&& from) noexcept - : VideoRecvStreamConfig() { - *this = ::std::move(from); - } - - inline VideoRecvStreamConfig& operator=(const VideoRecvStreamConfig& from) { - CopyFrom(from); - return *this; - } - inline VideoRecvStreamConfig& operator=(VideoRecvStreamConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const VideoRecvStreamConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const VideoRecvStreamConfig* internal_default_instance() { - return reinterpret_cast( - &_VideoRecvStreamConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 16; - - friend void swap(VideoRecvStreamConfig& a, VideoRecvStreamConfig& b) { - a.Swap(&b); - } - inline void Swap(VideoRecvStreamConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline VideoRecvStreamConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - VideoRecvStreamConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const VideoRecvStreamConfig& from); - void MergeFrom(const VideoRecvStreamConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(VideoRecvStreamConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.VideoRecvStreamConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kHeaderExtensionsFieldNumber = 5, - kTimestampMsFieldNumber = 1, - kRemoteSsrcFieldNumber = 2, - kLocalSsrcFieldNumber = 3, - kRtxSsrcFieldNumber = 4, - }; - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - bool has_header_extensions() const; - void clear_header_extensions(); - const ::webrtc::rtclog2::RtpHeaderExtensionConfig& header_extensions() const; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* release_header_extensions(); - ::webrtc::rtclog2::RtpHeaderExtensionConfig* mutable_header_extensions(); - void set_allocated_header_extensions(::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 remote_ssrc = 2; - bool has_remote_ssrc() const; - void clear_remote_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 remote_ssrc() const; - void set_remote_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 local_ssrc = 3; - bool has_local_ssrc() const; - void clear_local_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc() const; - void set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 rtx_ssrc = 4; - bool has_rtx_ssrc() const; - void clear_rtx_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 rtx_ssrc() const; - void set_rtx_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.VideoRecvStreamConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 remote_ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 rtx_ssrc_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class VideoSendStreamConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.VideoSendStreamConfig) */ { - public: - VideoSendStreamConfig(); - virtual ~VideoSendStreamConfig(); - - VideoSendStreamConfig(const VideoSendStreamConfig& from); - VideoSendStreamConfig(VideoSendStreamConfig&& from) noexcept - : VideoSendStreamConfig() { - *this = ::std::move(from); - } - - inline VideoSendStreamConfig& operator=(const VideoSendStreamConfig& from) { - CopyFrom(from); - return *this; - } - inline VideoSendStreamConfig& operator=(VideoSendStreamConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const VideoSendStreamConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const VideoSendStreamConfig* internal_default_instance() { - return reinterpret_cast( - &_VideoSendStreamConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 17; - - friend void swap(VideoSendStreamConfig& a, VideoSendStreamConfig& b) { - a.Swap(&b); - } - inline void Swap(VideoSendStreamConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline VideoSendStreamConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - VideoSendStreamConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const VideoSendStreamConfig& from); - void MergeFrom(const VideoSendStreamConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(VideoSendStreamConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.VideoSendStreamConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kHeaderExtensionsFieldNumber = 4, - kTimestampMsFieldNumber = 1, - kSsrcFieldNumber = 2, - kRtxSsrcFieldNumber = 3, - }; - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - bool has_header_extensions() const; - void clear_header_extensions(); - const ::webrtc::rtclog2::RtpHeaderExtensionConfig& header_extensions() const; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* release_header_extensions(); - ::webrtc::rtclog2::RtpHeaderExtensionConfig* mutable_header_extensions(); - void set_allocated_header_extensions(::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 ssrc = 2; - bool has_ssrc() const; - void clear_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc() const; - void set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 rtx_ssrc = 3; - bool has_rtx_ssrc() const; - void clear_rtx_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 rtx_ssrc() const; - void set_rtx_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.VideoSendStreamConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 rtx_ssrc_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class AudioRecvStreamConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.AudioRecvStreamConfig) */ { - public: - AudioRecvStreamConfig(); - virtual ~AudioRecvStreamConfig(); - - AudioRecvStreamConfig(const AudioRecvStreamConfig& from); - AudioRecvStreamConfig(AudioRecvStreamConfig&& from) noexcept - : AudioRecvStreamConfig() { - *this = ::std::move(from); - } - - inline AudioRecvStreamConfig& operator=(const AudioRecvStreamConfig& from) { - CopyFrom(from); - return *this; - } - inline AudioRecvStreamConfig& operator=(AudioRecvStreamConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AudioRecvStreamConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AudioRecvStreamConfig* internal_default_instance() { - return reinterpret_cast( - &_AudioRecvStreamConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 18; - - friend void swap(AudioRecvStreamConfig& a, AudioRecvStreamConfig& b) { - a.Swap(&b); - } - inline void Swap(AudioRecvStreamConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AudioRecvStreamConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - AudioRecvStreamConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AudioRecvStreamConfig& from); - void MergeFrom(const AudioRecvStreamConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AudioRecvStreamConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.AudioRecvStreamConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kHeaderExtensionsFieldNumber = 5, - kTimestampMsFieldNumber = 1, - kRemoteSsrcFieldNumber = 2, - kLocalSsrcFieldNumber = 3, - }; - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; - bool has_header_extensions() const; - void clear_header_extensions(); - const ::webrtc::rtclog2::RtpHeaderExtensionConfig& header_extensions() const; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* release_header_extensions(); - ::webrtc::rtclog2::RtpHeaderExtensionConfig* mutable_header_extensions(); - void set_allocated_header_extensions(::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 remote_ssrc = 2; - bool has_remote_ssrc() const; - void clear_remote_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 remote_ssrc() const; - void set_remote_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 local_ssrc = 3; - bool has_local_ssrc() const; - void clear_local_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc() const; - void set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.AudioRecvStreamConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 remote_ssrc_; - ::PROTOBUF_NAMESPACE_ID::uint32 local_ssrc_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class AudioSendStreamConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.AudioSendStreamConfig) */ { - public: - AudioSendStreamConfig(); - virtual ~AudioSendStreamConfig(); - - AudioSendStreamConfig(const AudioSendStreamConfig& from); - AudioSendStreamConfig(AudioSendStreamConfig&& from) noexcept - : AudioSendStreamConfig() { - *this = ::std::move(from); - } - - inline AudioSendStreamConfig& operator=(const AudioSendStreamConfig& from) { - CopyFrom(from); - return *this; - } - inline AudioSendStreamConfig& operator=(AudioSendStreamConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AudioSendStreamConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AudioSendStreamConfig* internal_default_instance() { - return reinterpret_cast( - &_AudioSendStreamConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 19; - - friend void swap(AudioSendStreamConfig& a, AudioSendStreamConfig& b) { - a.Swap(&b); - } - inline void Swap(AudioSendStreamConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AudioSendStreamConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - AudioSendStreamConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AudioSendStreamConfig& from); - void MergeFrom(const AudioSendStreamConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AudioSendStreamConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.AudioSendStreamConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kHeaderExtensionsFieldNumber = 4, - kTimestampMsFieldNumber = 1, - kSsrcFieldNumber = 2, - }; - // optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; - bool has_header_extensions() const; - void clear_header_extensions(); - const ::webrtc::rtclog2::RtpHeaderExtensionConfig& header_extensions() const; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* release_header_extensions(); - ::webrtc::rtclog2::RtpHeaderExtensionConfig* mutable_header_extensions(); - void set_allocated_header_extensions(::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 ssrc = 2; - bool has_ssrc() const; - void clear_ssrc(); - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc() const; - void set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.AudioSendStreamConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 ssrc_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class AudioNetworkAdaptations : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.AudioNetworkAdaptations) */ { - public: - AudioNetworkAdaptations(); - virtual ~AudioNetworkAdaptations(); - - AudioNetworkAdaptations(const AudioNetworkAdaptations& from); - AudioNetworkAdaptations(AudioNetworkAdaptations&& from) noexcept - : AudioNetworkAdaptations() { - *this = ::std::move(from); - } - - inline AudioNetworkAdaptations& operator=(const AudioNetworkAdaptations& from) { - CopyFrom(from); - return *this; - } - inline AudioNetworkAdaptations& operator=(AudioNetworkAdaptations&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AudioNetworkAdaptations& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AudioNetworkAdaptations* internal_default_instance() { - return reinterpret_cast( - &_AudioNetworkAdaptations_default_instance_); - } - static constexpr int kIndexInFileMessages = - 20; - - friend void swap(AudioNetworkAdaptations& a, AudioNetworkAdaptations& b) { - a.Swap(&b); - } - inline void Swap(AudioNetworkAdaptations* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AudioNetworkAdaptations* New() const final { - return CreateMaybeMessage(nullptr); - } - - AudioNetworkAdaptations* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AudioNetworkAdaptations& from); - void MergeFrom(const AudioNetworkAdaptations& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AudioNetworkAdaptations* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.AudioNetworkAdaptations"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 101, - kBitrateBpsDeltasFieldNumber = 102, - kFrameLengthMsDeltasFieldNumber = 103, - kUplinkPacketLossFractionDeltasFieldNumber = 104, - kEnableFecDeltasFieldNumber = 105, - kEnableDtxDeltasFieldNumber = 106, - kNumChannelsDeltasFieldNumber = 107, - kTimestampMsFieldNumber = 1, - kBitrateBpsFieldNumber = 2, - kFrameLengthMsFieldNumber = 3, - kUplinkPacketLossFractionFieldNumber = 4, - kEnableFecFieldNumber = 5, - kEnableDtxFieldNumber = 6, - kNumChannelsFieldNumber = 7, - kNumberOfDeltasFieldNumber = 8, - }; - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes bitrate_bps_deltas = 102; - bool has_bitrate_bps_deltas() const; - void clear_bitrate_bps_deltas(); - const std::string& bitrate_bps_deltas() const; - void set_bitrate_bps_deltas(const std::string& value); - void set_bitrate_bps_deltas(std::string&& value); - void set_bitrate_bps_deltas(const char* value); - void set_bitrate_bps_deltas(const void* value, size_t size); - std::string* mutable_bitrate_bps_deltas(); - std::string* release_bitrate_bps_deltas(); - void set_allocated_bitrate_bps_deltas(std::string* bitrate_bps_deltas); - - // optional bytes frame_length_ms_deltas = 103; - bool has_frame_length_ms_deltas() const; - void clear_frame_length_ms_deltas(); - const std::string& frame_length_ms_deltas() const; - void set_frame_length_ms_deltas(const std::string& value); - void set_frame_length_ms_deltas(std::string&& value); - void set_frame_length_ms_deltas(const char* value); - void set_frame_length_ms_deltas(const void* value, size_t size); - std::string* mutable_frame_length_ms_deltas(); - std::string* release_frame_length_ms_deltas(); - void set_allocated_frame_length_ms_deltas(std::string* frame_length_ms_deltas); - - // optional bytes uplink_packet_loss_fraction_deltas = 104; - bool has_uplink_packet_loss_fraction_deltas() const; - void clear_uplink_packet_loss_fraction_deltas(); - const std::string& uplink_packet_loss_fraction_deltas() const; - void set_uplink_packet_loss_fraction_deltas(const std::string& value); - void set_uplink_packet_loss_fraction_deltas(std::string&& value); - void set_uplink_packet_loss_fraction_deltas(const char* value); - void set_uplink_packet_loss_fraction_deltas(const void* value, size_t size); - std::string* mutable_uplink_packet_loss_fraction_deltas(); - std::string* release_uplink_packet_loss_fraction_deltas(); - void set_allocated_uplink_packet_loss_fraction_deltas(std::string* uplink_packet_loss_fraction_deltas); - - // optional bytes enable_fec_deltas = 105; - bool has_enable_fec_deltas() const; - void clear_enable_fec_deltas(); - const std::string& enable_fec_deltas() const; - void set_enable_fec_deltas(const std::string& value); - void set_enable_fec_deltas(std::string&& value); - void set_enable_fec_deltas(const char* value); - void set_enable_fec_deltas(const void* value, size_t size); - std::string* mutable_enable_fec_deltas(); - std::string* release_enable_fec_deltas(); - void set_allocated_enable_fec_deltas(std::string* enable_fec_deltas); - - // optional bytes enable_dtx_deltas = 106; - bool has_enable_dtx_deltas() const; - void clear_enable_dtx_deltas(); - const std::string& enable_dtx_deltas() const; - void set_enable_dtx_deltas(const std::string& value); - void set_enable_dtx_deltas(std::string&& value); - void set_enable_dtx_deltas(const char* value); - void set_enable_dtx_deltas(const void* value, size_t size); - std::string* mutable_enable_dtx_deltas(); - std::string* release_enable_dtx_deltas(); - void set_allocated_enable_dtx_deltas(std::string* enable_dtx_deltas); - - // optional bytes num_channels_deltas = 107; - bool has_num_channels_deltas() const; - void clear_num_channels_deltas(); - const std::string& num_channels_deltas() const; - void set_num_channels_deltas(const std::string& value); - void set_num_channels_deltas(std::string&& value); - void set_num_channels_deltas(const char* value); - void set_num_channels_deltas(const void* value, size_t size); - std::string* mutable_num_channels_deltas(); - std::string* release_num_channels_deltas(); - void set_allocated_num_channels_deltas(std::string* num_channels_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional int32 bitrate_bps = 2; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional int32 frame_length_ms = 3; - bool has_frame_length_ms() const; - void clear_frame_length_ms(); - ::PROTOBUF_NAMESPACE_ID::int32 frame_length_ms() const; - void set_frame_length_ms(::PROTOBUF_NAMESPACE_ID::int32 value); - - // optional uint32 uplink_packet_loss_fraction = 4; - bool has_uplink_packet_loss_fraction() const; - void clear_uplink_packet_loss_fraction(); - ::PROTOBUF_NAMESPACE_ID::uint32 uplink_packet_loss_fraction() const; - void set_uplink_packet_loss_fraction(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional bool enable_fec = 5; - bool has_enable_fec() const; - void clear_enable_fec(); - bool enable_fec() const; - void set_enable_fec(bool value); - - // optional bool enable_dtx = 6; - bool has_enable_dtx() const; - void clear_enable_dtx(); - bool enable_dtx() const; - void set_enable_dtx(bool value); - - // optional uint32 num_channels = 7; - bool has_num_channels() const; - void clear_num_channels(); - ::PROTOBUF_NAMESPACE_ID::uint32 num_channels() const; - void set_num_channels(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 number_of_deltas = 8; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.AudioNetworkAdaptations) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr bitrate_bps_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr frame_length_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr uplink_packet_loss_fraction_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr enable_fec_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr enable_dtx_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr num_channels_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::int32 bitrate_bps_; - ::PROTOBUF_NAMESPACE_ID::int32 frame_length_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 uplink_packet_loss_fraction_; - bool enable_fec_; - bool enable_dtx_; - ::PROTOBUF_NAMESPACE_ID::uint32 num_channels_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class BweProbeCluster : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.BweProbeCluster) */ { - public: - BweProbeCluster(); - virtual ~BweProbeCluster(); - - BweProbeCluster(const BweProbeCluster& from); - BweProbeCluster(BweProbeCluster&& from) noexcept - : BweProbeCluster() { - *this = ::std::move(from); - } - - inline BweProbeCluster& operator=(const BweProbeCluster& from) { - CopyFrom(from); - return *this; - } - inline BweProbeCluster& operator=(BweProbeCluster&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const BweProbeCluster& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const BweProbeCluster* internal_default_instance() { - return reinterpret_cast( - &_BweProbeCluster_default_instance_); - } - static constexpr int kIndexInFileMessages = - 21; - - friend void swap(BweProbeCluster& a, BweProbeCluster& b) { - a.Swap(&b); - } - inline void Swap(BweProbeCluster* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline BweProbeCluster* New() const final { - return CreateMaybeMessage(nullptr); - } - - BweProbeCluster* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const BweProbeCluster& from); - void MergeFrom(const BweProbeCluster& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(BweProbeCluster* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.BweProbeCluster"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kIdFieldNumber = 2, - kBitrateBpsFieldNumber = 3, - kMinPacketsFieldNumber = 4, - kMinBytesFieldNumber = 5, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 id = 2; - bool has_id() const; - void clear_id(); - ::PROTOBUF_NAMESPACE_ID::uint32 id() const; - void set_id(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 bitrate_bps = 3; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::uint32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 min_packets = 4; - bool has_min_packets() const; - void clear_min_packets(); - ::PROTOBUF_NAMESPACE_ID::uint32 min_packets() const; - void set_min_packets(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 min_bytes = 5; - bool has_min_bytes() const; - void clear_min_bytes(); - ::PROTOBUF_NAMESPACE_ID::uint32 min_bytes() const; - void set_min_bytes(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.BweProbeCluster) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 id_; - ::PROTOBUF_NAMESPACE_ID::uint32 bitrate_bps_; - ::PROTOBUF_NAMESPACE_ID::uint32 min_packets_; - ::PROTOBUF_NAMESPACE_ID::uint32 min_bytes_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class BweProbeResultSuccess : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.BweProbeResultSuccess) */ { - public: - BweProbeResultSuccess(); - virtual ~BweProbeResultSuccess(); - - BweProbeResultSuccess(const BweProbeResultSuccess& from); - BweProbeResultSuccess(BweProbeResultSuccess&& from) noexcept - : BweProbeResultSuccess() { - *this = ::std::move(from); - } - - inline BweProbeResultSuccess& operator=(const BweProbeResultSuccess& from) { - CopyFrom(from); - return *this; - } - inline BweProbeResultSuccess& operator=(BweProbeResultSuccess&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const BweProbeResultSuccess& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const BweProbeResultSuccess* internal_default_instance() { - return reinterpret_cast( - &_BweProbeResultSuccess_default_instance_); - } - static constexpr int kIndexInFileMessages = - 22; - - friend void swap(BweProbeResultSuccess& a, BweProbeResultSuccess& b) { - a.Swap(&b); - } - inline void Swap(BweProbeResultSuccess* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline BweProbeResultSuccess* New() const final { - return CreateMaybeMessage(nullptr); - } - - BweProbeResultSuccess* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const BweProbeResultSuccess& from); - void MergeFrom(const BweProbeResultSuccess& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(BweProbeResultSuccess* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.BweProbeResultSuccess"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kIdFieldNumber = 2, - kBitrateBpsFieldNumber = 3, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 id = 2; - bool has_id() const; - void clear_id(); - ::PROTOBUF_NAMESPACE_ID::uint32 id() const; - void set_id(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 bitrate_bps = 3; - bool has_bitrate_bps() const; - void clear_bitrate_bps(); - ::PROTOBUF_NAMESPACE_ID::uint32 bitrate_bps() const; - void set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.BweProbeResultSuccess) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 id_; - ::PROTOBUF_NAMESPACE_ID::uint32 bitrate_bps_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class BweProbeResultFailure : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.BweProbeResultFailure) */ { - public: - BweProbeResultFailure(); - virtual ~BweProbeResultFailure(); - - BweProbeResultFailure(const BweProbeResultFailure& from); - BweProbeResultFailure(BweProbeResultFailure&& from) noexcept - : BweProbeResultFailure() { - *this = ::std::move(from); - } - - inline BweProbeResultFailure& operator=(const BweProbeResultFailure& from) { - CopyFrom(from); - return *this; - } - inline BweProbeResultFailure& operator=(BweProbeResultFailure&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const BweProbeResultFailure& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const BweProbeResultFailure* internal_default_instance() { - return reinterpret_cast( - &_BweProbeResultFailure_default_instance_); - } - static constexpr int kIndexInFileMessages = - 23; - - friend void swap(BweProbeResultFailure& a, BweProbeResultFailure& b) { - a.Swap(&b); - } - inline void Swap(BweProbeResultFailure* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline BweProbeResultFailure* New() const final { - return CreateMaybeMessage(nullptr); - } - - BweProbeResultFailure* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const BweProbeResultFailure& from); - void MergeFrom(const BweProbeResultFailure& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(BweProbeResultFailure* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.BweProbeResultFailure"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef BweProbeResultFailure_FailureReason FailureReason; - static constexpr FailureReason UNKNOWN = - BweProbeResultFailure_FailureReason_UNKNOWN; - static constexpr FailureReason INVALID_SEND_RECEIVE_INTERVAL = - BweProbeResultFailure_FailureReason_INVALID_SEND_RECEIVE_INTERVAL; - static constexpr FailureReason INVALID_SEND_RECEIVE_RATIO = - BweProbeResultFailure_FailureReason_INVALID_SEND_RECEIVE_RATIO; - static constexpr FailureReason TIMEOUT = - BweProbeResultFailure_FailureReason_TIMEOUT; - static inline bool FailureReason_IsValid(int value) { - return BweProbeResultFailure_FailureReason_IsValid(value); - } - static constexpr FailureReason FailureReason_MIN = - BweProbeResultFailure_FailureReason_FailureReason_MIN; - static constexpr FailureReason FailureReason_MAX = - BweProbeResultFailure_FailureReason_FailureReason_MAX; - static constexpr int FailureReason_ARRAYSIZE = - BweProbeResultFailure_FailureReason_FailureReason_ARRAYSIZE; - template - static inline const std::string& FailureReason_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function FailureReason_Name."); - return BweProbeResultFailure_FailureReason_Name(enum_t_value); - } - static inline bool FailureReason_Parse(const std::string& name, - FailureReason* value) { - return BweProbeResultFailure_FailureReason_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kIdFieldNumber = 2, - kFailureFieldNumber = 3, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 id = 2; - bool has_id() const; - void clear_id(); - ::PROTOBUF_NAMESPACE_ID::uint32 id() const; - void set_id(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional .webrtc.rtclog2.BweProbeResultFailure.FailureReason failure = 3; - bool has_failure() const; - void clear_failure(); - ::webrtc::rtclog2::BweProbeResultFailure_FailureReason failure() const; - void set_failure(::webrtc::rtclog2::BweProbeResultFailure_FailureReason value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.BweProbeResultFailure) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 id_; - int failure_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class AlrState : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.AlrState) */ { - public: - AlrState(); - virtual ~AlrState(); - - AlrState(const AlrState& from); - AlrState(AlrState&& from) noexcept - : AlrState() { - *this = ::std::move(from); - } - - inline AlrState& operator=(const AlrState& from) { - CopyFrom(from); - return *this; - } - inline AlrState& operator=(AlrState&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const AlrState& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const AlrState* internal_default_instance() { - return reinterpret_cast( - &_AlrState_default_instance_); - } - static constexpr int kIndexInFileMessages = - 24; - - friend void swap(AlrState& a, AlrState& b) { - a.Swap(&b); - } - inline void Swap(AlrState* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline AlrState* New() const final { - return CreateMaybeMessage(nullptr); - } - - AlrState* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const AlrState& from); - void MergeFrom(const AlrState& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(AlrState* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.AlrState"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kInAlrFieldNumber = 2, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional bool in_alr = 2; - bool has_in_alr() const; - void clear_in_alr(); - bool in_alr() const; - void set_in_alr(bool value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.AlrState) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - bool in_alr_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class IceCandidatePairConfig : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.IceCandidatePairConfig) */ { - public: - IceCandidatePairConfig(); - virtual ~IceCandidatePairConfig(); - - IceCandidatePairConfig(const IceCandidatePairConfig& from); - IceCandidatePairConfig(IceCandidatePairConfig&& from) noexcept - : IceCandidatePairConfig() { - *this = ::std::move(from); - } - - inline IceCandidatePairConfig& operator=(const IceCandidatePairConfig& from) { - CopyFrom(from); - return *this; - } - inline IceCandidatePairConfig& operator=(IceCandidatePairConfig&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const IceCandidatePairConfig& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const IceCandidatePairConfig* internal_default_instance() { - return reinterpret_cast( - &_IceCandidatePairConfig_default_instance_); - } - static constexpr int kIndexInFileMessages = - 25; - - friend void swap(IceCandidatePairConfig& a, IceCandidatePairConfig& b) { - a.Swap(&b); - } - inline void Swap(IceCandidatePairConfig* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline IceCandidatePairConfig* New() const final { - return CreateMaybeMessage(nullptr); - } - - IceCandidatePairConfig* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const IceCandidatePairConfig& from); - void MergeFrom(const IceCandidatePairConfig& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(IceCandidatePairConfig* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.IceCandidatePairConfig"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfigType; - static constexpr IceCandidatePairConfigType UNKNOWN_CONFIG_TYPE = - IceCandidatePairConfig_IceCandidatePairConfigType_UNKNOWN_CONFIG_TYPE; - static constexpr IceCandidatePairConfigType ADDED = - IceCandidatePairConfig_IceCandidatePairConfigType_ADDED; - static constexpr IceCandidatePairConfigType UPDATED = - IceCandidatePairConfig_IceCandidatePairConfigType_UPDATED; - static constexpr IceCandidatePairConfigType DESTROYED = - IceCandidatePairConfig_IceCandidatePairConfigType_DESTROYED; - static constexpr IceCandidatePairConfigType SELECTED = - IceCandidatePairConfig_IceCandidatePairConfigType_SELECTED; - static inline bool IceCandidatePairConfigType_IsValid(int value) { - return IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(value); - } - static constexpr IceCandidatePairConfigType IceCandidatePairConfigType_MIN = - IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MIN; - static constexpr IceCandidatePairConfigType IceCandidatePairConfigType_MAX = - IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_MAX; - static constexpr int IceCandidatePairConfigType_ARRAYSIZE = - IceCandidatePairConfig_IceCandidatePairConfigType_IceCandidatePairConfigType_ARRAYSIZE; - template - static inline const std::string& IceCandidatePairConfigType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairConfigType_Name."); - return IceCandidatePairConfig_IceCandidatePairConfigType_Name(enum_t_value); - } - static inline bool IceCandidatePairConfigType_Parse(const std::string& name, - IceCandidatePairConfigType* value) { - return IceCandidatePairConfig_IceCandidatePairConfigType_Parse(name, value); - } - - typedef IceCandidatePairConfig_IceCandidateType IceCandidateType; - static constexpr IceCandidateType UNKNOWN_CANDIDATE_TYPE = - IceCandidatePairConfig_IceCandidateType_UNKNOWN_CANDIDATE_TYPE; - static constexpr IceCandidateType LOCAL = - IceCandidatePairConfig_IceCandidateType_LOCAL; - static constexpr IceCandidateType STUN = - IceCandidatePairConfig_IceCandidateType_STUN; - static constexpr IceCandidateType PRFLX = - IceCandidatePairConfig_IceCandidateType_PRFLX; - static constexpr IceCandidateType RELAY = - IceCandidatePairConfig_IceCandidateType_RELAY; - static inline bool IceCandidateType_IsValid(int value) { - return IceCandidatePairConfig_IceCandidateType_IsValid(value); - } - static constexpr IceCandidateType IceCandidateType_MIN = - IceCandidatePairConfig_IceCandidateType_IceCandidateType_MIN; - static constexpr IceCandidateType IceCandidateType_MAX = - IceCandidatePairConfig_IceCandidateType_IceCandidateType_MAX; - static constexpr int IceCandidateType_ARRAYSIZE = - IceCandidatePairConfig_IceCandidateType_IceCandidateType_ARRAYSIZE; - template - static inline const std::string& IceCandidateType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidateType_Name."); - return IceCandidatePairConfig_IceCandidateType_Name(enum_t_value); - } - static inline bool IceCandidateType_Parse(const std::string& name, - IceCandidateType* value) { - return IceCandidatePairConfig_IceCandidateType_Parse(name, value); - } - - typedef IceCandidatePairConfig_Protocol Protocol; - static constexpr Protocol UNKNOWN_PROTOCOL = - IceCandidatePairConfig_Protocol_UNKNOWN_PROTOCOL; - static constexpr Protocol UDP = - IceCandidatePairConfig_Protocol_UDP; - static constexpr Protocol TCP = - IceCandidatePairConfig_Protocol_TCP; - static constexpr Protocol SSLTCP = - IceCandidatePairConfig_Protocol_SSLTCP; - static constexpr Protocol TLS = - IceCandidatePairConfig_Protocol_TLS; - static inline bool Protocol_IsValid(int value) { - return IceCandidatePairConfig_Protocol_IsValid(value); - } - static constexpr Protocol Protocol_MIN = - IceCandidatePairConfig_Protocol_Protocol_MIN; - static constexpr Protocol Protocol_MAX = - IceCandidatePairConfig_Protocol_Protocol_MAX; - static constexpr int Protocol_ARRAYSIZE = - IceCandidatePairConfig_Protocol_Protocol_ARRAYSIZE; - template - static inline const std::string& Protocol_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function Protocol_Name."); - return IceCandidatePairConfig_Protocol_Name(enum_t_value); - } - static inline bool Protocol_Parse(const std::string& name, - Protocol* value) { - return IceCandidatePairConfig_Protocol_Parse(name, value); - } - - typedef IceCandidatePairConfig_AddressFamily AddressFamily; - static constexpr AddressFamily UNKNOWN_ADDRESS_FAMILY = - IceCandidatePairConfig_AddressFamily_UNKNOWN_ADDRESS_FAMILY; - static constexpr AddressFamily IPV4 = - IceCandidatePairConfig_AddressFamily_IPV4; - static constexpr AddressFamily IPV6 = - IceCandidatePairConfig_AddressFamily_IPV6; - static inline bool AddressFamily_IsValid(int value) { - return IceCandidatePairConfig_AddressFamily_IsValid(value); - } - static constexpr AddressFamily AddressFamily_MIN = - IceCandidatePairConfig_AddressFamily_AddressFamily_MIN; - static constexpr AddressFamily AddressFamily_MAX = - IceCandidatePairConfig_AddressFamily_AddressFamily_MAX; - static constexpr int AddressFamily_ARRAYSIZE = - IceCandidatePairConfig_AddressFamily_AddressFamily_ARRAYSIZE; - template - static inline const std::string& AddressFamily_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function AddressFamily_Name."); - return IceCandidatePairConfig_AddressFamily_Name(enum_t_value); - } - static inline bool AddressFamily_Parse(const std::string& name, - AddressFamily* value) { - return IceCandidatePairConfig_AddressFamily_Parse(name, value); - } - - typedef IceCandidatePairConfig_NetworkType NetworkType; - static constexpr NetworkType UNKNOWN_NETWORK_TYPE = - IceCandidatePairConfig_NetworkType_UNKNOWN_NETWORK_TYPE; - static constexpr NetworkType ETHERNET = - IceCandidatePairConfig_NetworkType_ETHERNET; - static constexpr NetworkType WIFI = - IceCandidatePairConfig_NetworkType_WIFI; - static constexpr NetworkType CELLULAR = - IceCandidatePairConfig_NetworkType_CELLULAR; - static constexpr NetworkType VPN = - IceCandidatePairConfig_NetworkType_VPN; - static constexpr NetworkType LOOPBACK = - IceCandidatePairConfig_NetworkType_LOOPBACK; - static inline bool NetworkType_IsValid(int value) { - return IceCandidatePairConfig_NetworkType_IsValid(value); - } - static constexpr NetworkType NetworkType_MIN = - IceCandidatePairConfig_NetworkType_NetworkType_MIN; - static constexpr NetworkType NetworkType_MAX = - IceCandidatePairConfig_NetworkType_NetworkType_MAX; - static constexpr int NetworkType_ARRAYSIZE = - IceCandidatePairConfig_NetworkType_NetworkType_ARRAYSIZE; - template - static inline const std::string& NetworkType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function NetworkType_Name."); - return IceCandidatePairConfig_NetworkType_Name(enum_t_value); - } - static inline bool NetworkType_Parse(const std::string& name, - NetworkType* value) { - return IceCandidatePairConfig_NetworkType_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kConfigTypeFieldNumber = 2, - kCandidatePairIdFieldNumber = 3, - kLocalCandidateTypeFieldNumber = 4, - kLocalRelayProtocolFieldNumber = 5, - kLocalNetworkTypeFieldNumber = 6, - kLocalAddressFamilyFieldNumber = 7, - kRemoteCandidateTypeFieldNumber = 8, - kRemoteAddressFamilyFieldNumber = 9, - kCandidatePairProtocolFieldNumber = 10, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 2; - bool has_config_type() const; - void clear_config_type(); - ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType config_type() const; - void set_config_type(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType value); - - // optional uint32 candidate_pair_id = 3; - bool has_candidate_pair_id() const; - void clear_candidate_pair_id(); - ::PROTOBUF_NAMESPACE_ID::uint32 candidate_pair_id() const; - void set_candidate_pair_id(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType local_candidate_type = 4; - bool has_local_candidate_type() const; - void clear_local_candidate_type(); - ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType local_candidate_type() const; - void set_local_candidate_type(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType value); - - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol local_relay_protocol = 5; - bool has_local_relay_protocol() const; - void clear_local_relay_protocol(); - ::webrtc::rtclog2::IceCandidatePairConfig_Protocol local_relay_protocol() const; - void set_local_relay_protocol(::webrtc::rtclog2::IceCandidatePairConfig_Protocol value); - - // optional .webrtc.rtclog2.IceCandidatePairConfig.NetworkType local_network_type = 6; - bool has_local_network_type() const; - void clear_local_network_type(); - ::webrtc::rtclog2::IceCandidatePairConfig_NetworkType local_network_type() const; - void set_local_network_type(::webrtc::rtclog2::IceCandidatePairConfig_NetworkType value); - - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily local_address_family = 7; - bool has_local_address_family() const; - void clear_local_address_family(); - ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily local_address_family() const; - void set_local_address_family(::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily value); - - // optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 8; - bool has_remote_candidate_type() const; - void clear_remote_candidate_type(); - ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType remote_candidate_type() const; - void set_remote_candidate_type(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType value); - - // optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily remote_address_family = 9; - bool has_remote_address_family() const; - void clear_remote_address_family(); - ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily remote_address_family() const; - void set_remote_address_family(::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily value); - - // optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol candidate_pair_protocol = 10; - bool has_candidate_pair_protocol() const; - void clear_candidate_pair_protocol(); - ::webrtc::rtclog2::IceCandidatePairConfig_Protocol candidate_pair_protocol() const; - void set_candidate_pair_protocol(::webrtc::rtclog2::IceCandidatePairConfig_Protocol value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.IceCandidatePairConfig) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - int config_type_; - ::PROTOBUF_NAMESPACE_ID::uint32 candidate_pair_id_; - int local_candidate_type_; - int local_relay_protocol_; - int local_network_type_; - int local_address_family_; - int remote_candidate_type_; - int remote_address_family_; - int candidate_pair_protocol_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class IceCandidatePairEvent : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.IceCandidatePairEvent) */ { - public: - IceCandidatePairEvent(); - virtual ~IceCandidatePairEvent(); - - IceCandidatePairEvent(const IceCandidatePairEvent& from); - IceCandidatePairEvent(IceCandidatePairEvent&& from) noexcept - : IceCandidatePairEvent() { - *this = ::std::move(from); - } - - inline IceCandidatePairEvent& operator=(const IceCandidatePairEvent& from) { - CopyFrom(from); - return *this; - } - inline IceCandidatePairEvent& operator=(IceCandidatePairEvent&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const IceCandidatePairEvent& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const IceCandidatePairEvent* internal_default_instance() { - return reinterpret_cast( - &_IceCandidatePairEvent_default_instance_); - } - static constexpr int kIndexInFileMessages = - 26; - - friend void swap(IceCandidatePairEvent& a, IceCandidatePairEvent& b) { - a.Swap(&b); - } - inline void Swap(IceCandidatePairEvent* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline IceCandidatePairEvent* New() const final { - return CreateMaybeMessage(nullptr); - } - - IceCandidatePairEvent* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const IceCandidatePairEvent& from); - void MergeFrom(const IceCandidatePairEvent& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(IceCandidatePairEvent* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.IceCandidatePairEvent"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEventType; - static constexpr IceCandidatePairEventType UNKNOWN_CHECK_TYPE = - IceCandidatePairEvent_IceCandidatePairEventType_UNKNOWN_CHECK_TYPE; - static constexpr IceCandidatePairEventType CHECK_SENT = - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_SENT; - static constexpr IceCandidatePairEventType CHECK_RECEIVED = - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RECEIVED; - static constexpr IceCandidatePairEventType CHECK_RESPONSE_SENT = - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_SENT; - static constexpr IceCandidatePairEventType CHECK_RESPONSE_RECEIVED = - IceCandidatePairEvent_IceCandidatePairEventType_CHECK_RESPONSE_RECEIVED; - static inline bool IceCandidatePairEventType_IsValid(int value) { - return IceCandidatePairEvent_IceCandidatePairEventType_IsValid(value); - } - static constexpr IceCandidatePairEventType IceCandidatePairEventType_MIN = - IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MIN; - static constexpr IceCandidatePairEventType IceCandidatePairEventType_MAX = - IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_MAX; - static constexpr int IceCandidatePairEventType_ARRAYSIZE = - IceCandidatePairEvent_IceCandidatePairEventType_IceCandidatePairEventType_ARRAYSIZE; - template - static inline const std::string& IceCandidatePairEventType_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function IceCandidatePairEventType_Name."); - return IceCandidatePairEvent_IceCandidatePairEventType_Name(enum_t_value); - } - static inline bool IceCandidatePairEventType_Parse(const std::string& name, - IceCandidatePairEventType* value) { - return IceCandidatePairEvent_IceCandidatePairEventType_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kEventTypeFieldNumber = 2, - kCandidatePairIdFieldNumber = 3, - kTransactionIdFieldNumber = 4, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional .webrtc.rtclog2.IceCandidatePairEvent.IceCandidatePairEventType event_type = 2; - bool has_event_type() const; - void clear_event_type(); - ::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType event_type() const; - void set_event_type(::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType value); - - // optional uint32 candidate_pair_id = 3; - bool has_candidate_pair_id() const; - void clear_candidate_pair_id(); - ::PROTOBUF_NAMESPACE_ID::uint32 candidate_pair_id() const; - void set_candidate_pair_id(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 transaction_id = 4; - bool has_transaction_id() const; - void clear_transaction_id(); - ::PROTOBUF_NAMESPACE_ID::uint32 transaction_id() const; - void set_transaction_id(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.IceCandidatePairEvent) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - int event_type_; - ::PROTOBUF_NAMESPACE_ID::uint32 candidate_pair_id_; - ::PROTOBUF_NAMESPACE_ID::uint32 transaction_id_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class DtlsTransportStateEvent : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.DtlsTransportStateEvent) */ { - public: - DtlsTransportStateEvent(); - virtual ~DtlsTransportStateEvent(); - - DtlsTransportStateEvent(const DtlsTransportStateEvent& from); - DtlsTransportStateEvent(DtlsTransportStateEvent&& from) noexcept - : DtlsTransportStateEvent() { - *this = ::std::move(from); - } - - inline DtlsTransportStateEvent& operator=(const DtlsTransportStateEvent& from) { - CopyFrom(from); - return *this; - } - inline DtlsTransportStateEvent& operator=(DtlsTransportStateEvent&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const DtlsTransportStateEvent& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const DtlsTransportStateEvent* internal_default_instance() { - return reinterpret_cast( - &_DtlsTransportStateEvent_default_instance_); - } - static constexpr int kIndexInFileMessages = - 27; - - friend void swap(DtlsTransportStateEvent& a, DtlsTransportStateEvent& b) { - a.Swap(&b); - } - inline void Swap(DtlsTransportStateEvent* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline DtlsTransportStateEvent* New() const final { - return CreateMaybeMessage(nullptr); - } - - DtlsTransportStateEvent* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const DtlsTransportStateEvent& from); - void MergeFrom(const DtlsTransportStateEvent& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(DtlsTransportStateEvent* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.DtlsTransportStateEvent"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - typedef DtlsTransportStateEvent_DtlsTransportState DtlsTransportState; - static constexpr DtlsTransportState UNKNOWN_DTLS_TRANSPORT_STATE = - DtlsTransportStateEvent_DtlsTransportState_UNKNOWN_DTLS_TRANSPORT_STATE; - static constexpr DtlsTransportState DTLS_TRANSPORT_NEW = - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_NEW; - static constexpr DtlsTransportState DTLS_TRANSPORT_CONNECTING = - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_CONNECTING; - static constexpr DtlsTransportState DTLS_TRANSPORT_CONNECTED = - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_CONNECTED; - static constexpr DtlsTransportState DTLS_TRANSPORT_CLOSED = - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_CLOSED; - static constexpr DtlsTransportState DTLS_TRANSPORT_FAILED = - DtlsTransportStateEvent_DtlsTransportState_DTLS_TRANSPORT_FAILED; - static inline bool DtlsTransportState_IsValid(int value) { - return DtlsTransportStateEvent_DtlsTransportState_IsValid(value); - } - static constexpr DtlsTransportState DtlsTransportState_MIN = - DtlsTransportStateEvent_DtlsTransportState_DtlsTransportState_MIN; - static constexpr DtlsTransportState DtlsTransportState_MAX = - DtlsTransportStateEvent_DtlsTransportState_DtlsTransportState_MAX; - static constexpr int DtlsTransportState_ARRAYSIZE = - DtlsTransportStateEvent_DtlsTransportState_DtlsTransportState_ARRAYSIZE; - template - static inline const std::string& DtlsTransportState_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function DtlsTransportState_Name."); - return DtlsTransportStateEvent_DtlsTransportState_Name(enum_t_value); - } - static inline bool DtlsTransportState_Parse(const std::string& name, - DtlsTransportState* value) { - return DtlsTransportStateEvent_DtlsTransportState_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kDtlsTransportStateFieldNumber = 2, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional .webrtc.rtclog2.DtlsTransportStateEvent.DtlsTransportState dtls_transport_state = 2; - bool has_dtls_transport_state() const; - void clear_dtls_transport_state(); - ::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState dtls_transport_state() const; - void set_dtls_transport_state(::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.DtlsTransportStateEvent) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - int dtls_transport_state_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class DtlsWritableState : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.DtlsWritableState) */ { - public: - DtlsWritableState(); - virtual ~DtlsWritableState(); - - DtlsWritableState(const DtlsWritableState& from); - DtlsWritableState(DtlsWritableState&& from) noexcept - : DtlsWritableState() { - *this = ::std::move(from); - } - - inline DtlsWritableState& operator=(const DtlsWritableState& from) { - CopyFrom(from); - return *this; - } - inline DtlsWritableState& operator=(DtlsWritableState&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const DtlsWritableState& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const DtlsWritableState* internal_default_instance() { - return reinterpret_cast( - &_DtlsWritableState_default_instance_); - } - static constexpr int kIndexInFileMessages = - 28; - - friend void swap(DtlsWritableState& a, DtlsWritableState& b) { - a.Swap(&b); - } - inline void Swap(DtlsWritableState* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline DtlsWritableState* New() const final { - return CreateMaybeMessage(nullptr); - } - - DtlsWritableState* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const DtlsWritableState& from); - void MergeFrom(const DtlsWritableState& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(DtlsWritableState* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.DtlsWritableState"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kWritableFieldNumber = 2, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional bool writable = 2; - bool has_writable() const; - void clear_writable(); - bool writable() const; - void set_writable(bool value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.DtlsWritableState) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - bool writable_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class RouteChange : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.RouteChange) */ { - public: - RouteChange(); - virtual ~RouteChange(); - - RouteChange(const RouteChange& from); - RouteChange(RouteChange&& from) noexcept - : RouteChange() { - *this = ::std::move(from); - } - - inline RouteChange& operator=(const RouteChange& from) { - CopyFrom(from); - return *this; - } - inline RouteChange& operator=(RouteChange&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const RouteChange& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const RouteChange* internal_default_instance() { - return reinterpret_cast( - &_RouteChange_default_instance_); - } - static constexpr int kIndexInFileMessages = - 29; - - friend void swap(RouteChange& a, RouteChange& b) { - a.Swap(&b); - } - inline void Swap(RouteChange* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline RouteChange* New() const final { - return CreateMaybeMessage(nullptr); - } - - RouteChange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const RouteChange& from); - void MergeFrom(const RouteChange& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(RouteChange* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.RouteChange"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsFieldNumber = 1, - kConnectedFieldNumber = 2, - kOverheadFieldNumber = 3, - }; - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional bool connected = 2; - bool has_connected() const; - void clear_connected(); - bool connected() const; - void set_connected(bool value); - - // optional uint32 overhead = 3; - bool has_overhead() const; - void clear_overhead(); - ::PROTOBUF_NAMESPACE_ID::uint32 overhead() const; - void set_overhead(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.RouteChange) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - bool connected_; - ::PROTOBUF_NAMESPACE_ID::uint32 overhead_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// ------------------------------------------------------------------- - -class RemoteEstimates : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:webrtc.rtclog2.RemoteEstimates) */ { - public: - RemoteEstimates(); - virtual ~RemoteEstimates(); - - RemoteEstimates(const RemoteEstimates& from); - RemoteEstimates(RemoteEstimates&& from) noexcept - : RemoteEstimates() { - *this = ::std::move(from); - } - - inline RemoteEstimates& operator=(const RemoteEstimates& from) { - CopyFrom(from); - return *this; - } - inline RemoteEstimates& operator=(RemoteEstimates&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const std::string& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - inline std::string* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const RemoteEstimates& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const RemoteEstimates* internal_default_instance() { - return reinterpret_cast( - &_RemoteEstimates_default_instance_); - } - static constexpr int kIndexInFileMessages = - 30; - - friend void swap(RemoteEstimates& a, RemoteEstimates& b) { - a.Swap(&b); - } - inline void Swap(RemoteEstimates* other) { - if (other == this) return; - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - inline RemoteEstimates* New() const final { - return CreateMaybeMessage(nullptr); - } - - RemoteEstimates* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) - final; - void CopyFrom(const RemoteEstimates& from); - void MergeFrom(const RemoteEstimates& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - #else - bool MergePartialFromCodedStream( - ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; - #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER - void SerializeWithCachedSizes( - ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; - void DiscardUnknownFields(); - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - inline void SharedCtor(); - inline void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(RemoteEstimates* other); - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "webrtc.rtclog2.RemoteEstimates"; - } - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kTimestampMsDeltasFieldNumber = 101, - kLinkCapacityLowerKbpsDeltasFieldNumber = 102, - kLinkCapacityUpperKbpsDeltasFieldNumber = 103, - kTimestampMsFieldNumber = 1, - kLinkCapacityLowerKbpsFieldNumber = 2, - kLinkCapacityUpperKbpsFieldNumber = 3, - kNumberOfDeltasFieldNumber = 4, - }; - // optional bytes timestamp_ms_deltas = 101; - bool has_timestamp_ms_deltas() const; - void clear_timestamp_ms_deltas(); - const std::string& timestamp_ms_deltas() const; - void set_timestamp_ms_deltas(const std::string& value); - void set_timestamp_ms_deltas(std::string&& value); - void set_timestamp_ms_deltas(const char* value); - void set_timestamp_ms_deltas(const void* value, size_t size); - std::string* mutable_timestamp_ms_deltas(); - std::string* release_timestamp_ms_deltas(); - void set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas); - - // optional bytes link_capacity_lower_kbps_deltas = 102; - bool has_link_capacity_lower_kbps_deltas() const; - void clear_link_capacity_lower_kbps_deltas(); - const std::string& link_capacity_lower_kbps_deltas() const; - void set_link_capacity_lower_kbps_deltas(const std::string& value); - void set_link_capacity_lower_kbps_deltas(std::string&& value); - void set_link_capacity_lower_kbps_deltas(const char* value); - void set_link_capacity_lower_kbps_deltas(const void* value, size_t size); - std::string* mutable_link_capacity_lower_kbps_deltas(); - std::string* release_link_capacity_lower_kbps_deltas(); - void set_allocated_link_capacity_lower_kbps_deltas(std::string* link_capacity_lower_kbps_deltas); - - // optional bytes link_capacity_upper_kbps_deltas = 103; - bool has_link_capacity_upper_kbps_deltas() const; - void clear_link_capacity_upper_kbps_deltas(); - const std::string& link_capacity_upper_kbps_deltas() const; - void set_link_capacity_upper_kbps_deltas(const std::string& value); - void set_link_capacity_upper_kbps_deltas(std::string&& value); - void set_link_capacity_upper_kbps_deltas(const char* value); - void set_link_capacity_upper_kbps_deltas(const void* value, size_t size); - std::string* mutable_link_capacity_upper_kbps_deltas(); - std::string* release_link_capacity_upper_kbps_deltas(); - void set_allocated_link_capacity_upper_kbps_deltas(std::string* link_capacity_upper_kbps_deltas); - - // optional int64 timestamp_ms = 1; - bool has_timestamp_ms() const; - void clear_timestamp_ms(); - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms() const; - void set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value); - - // optional uint32 link_capacity_lower_kbps = 2; - bool has_link_capacity_lower_kbps() const; - void clear_link_capacity_lower_kbps(); - ::PROTOBUF_NAMESPACE_ID::uint32 link_capacity_lower_kbps() const; - void set_link_capacity_lower_kbps(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 link_capacity_upper_kbps = 3; - bool has_link_capacity_upper_kbps() const; - void clear_link_capacity_upper_kbps(); - ::PROTOBUF_NAMESPACE_ID::uint32 link_capacity_upper_kbps() const; - void set_link_capacity_upper_kbps(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // optional uint32 number_of_deltas = 4; - bool has_number_of_deltas() const; - void clear_number_of_deltas(); - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas() const; - void set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value); - - // @@protoc_insertion_point(class_scope:webrtc.rtclog2.RemoteEstimates) - private: - class _Internal; - - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArenaLite _internal_metadata_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr timestamp_ms_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr link_capacity_lower_kbps_deltas_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr link_capacity_upper_kbps_deltas_; - ::PROTOBUF_NAMESPACE_ID::int64 timestamp_ms_; - ::PROTOBUF_NAMESPACE_ID::uint32 link_capacity_lower_kbps_; - ::PROTOBUF_NAMESPACE_ID::uint32 link_capacity_upper_kbps_; - ::PROTOBUF_NAMESPACE_ID::uint32 number_of_deltas_; - friend struct ::TableStruct_rtc_5fevent_5flog2_2eproto; -}; -// =================================================================== - - -// =================================================================== - -#ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // __GNUC__ -// EventStream - -// repeated .webrtc.rtclog2.Event stream = 1 [deprecated = true]; -inline int EventStream::stream_size() const { - return stream_.size(); -} -inline void EventStream::clear_stream() { - stream_.Clear(); -} -inline ::webrtc::rtclog2::Event* EventStream::mutable_stream(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.stream) - return stream_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::Event >* -EventStream::mutable_stream() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.stream) - return &stream_; -} -inline const ::webrtc::rtclog2::Event& EventStream::stream(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.stream) - return stream_.Get(index); -} -inline ::webrtc::rtclog2::Event* EventStream::add_stream() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.stream) - return stream_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::Event >& -EventStream::stream() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.stream) - return stream_; -} - -// repeated .webrtc.rtclog2.IncomingRtpPackets incoming_rtp_packets = 2; -inline int EventStream::incoming_rtp_packets_size() const { - return incoming_rtp_packets_.size(); -} -inline void EventStream::clear_incoming_rtp_packets() { - incoming_rtp_packets_.Clear(); -} -inline ::webrtc::rtclog2::IncomingRtpPackets* EventStream::mutable_incoming_rtp_packets(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.incoming_rtp_packets) - return incoming_rtp_packets_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtpPackets >* -EventStream::mutable_incoming_rtp_packets() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.incoming_rtp_packets) - return &incoming_rtp_packets_; -} -inline const ::webrtc::rtclog2::IncomingRtpPackets& EventStream::incoming_rtp_packets(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.incoming_rtp_packets) - return incoming_rtp_packets_.Get(index); -} -inline ::webrtc::rtclog2::IncomingRtpPackets* EventStream::add_incoming_rtp_packets() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.incoming_rtp_packets) - return incoming_rtp_packets_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtpPackets >& -EventStream::incoming_rtp_packets() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.incoming_rtp_packets) - return incoming_rtp_packets_; -} - -// repeated .webrtc.rtclog2.OutgoingRtpPackets outgoing_rtp_packets = 3; -inline int EventStream::outgoing_rtp_packets_size() const { - return outgoing_rtp_packets_.size(); -} -inline void EventStream::clear_outgoing_rtp_packets() { - outgoing_rtp_packets_.Clear(); -} -inline ::webrtc::rtclog2::OutgoingRtpPackets* EventStream::mutable_outgoing_rtp_packets(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.outgoing_rtp_packets) - return outgoing_rtp_packets_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtpPackets >* -EventStream::mutable_outgoing_rtp_packets() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.outgoing_rtp_packets) - return &outgoing_rtp_packets_; -} -inline const ::webrtc::rtclog2::OutgoingRtpPackets& EventStream::outgoing_rtp_packets(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.outgoing_rtp_packets) - return outgoing_rtp_packets_.Get(index); -} -inline ::webrtc::rtclog2::OutgoingRtpPackets* EventStream::add_outgoing_rtp_packets() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.outgoing_rtp_packets) - return outgoing_rtp_packets_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtpPackets >& -EventStream::outgoing_rtp_packets() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.outgoing_rtp_packets) - return outgoing_rtp_packets_; -} - -// repeated .webrtc.rtclog2.IncomingRtcpPackets incoming_rtcp_packets = 4; -inline int EventStream::incoming_rtcp_packets_size() const { - return incoming_rtcp_packets_.size(); -} -inline void EventStream::clear_incoming_rtcp_packets() { - incoming_rtcp_packets_.Clear(); -} -inline ::webrtc::rtclog2::IncomingRtcpPackets* EventStream::mutable_incoming_rtcp_packets(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.incoming_rtcp_packets) - return incoming_rtcp_packets_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtcpPackets >* -EventStream::mutable_incoming_rtcp_packets() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.incoming_rtcp_packets) - return &incoming_rtcp_packets_; -} -inline const ::webrtc::rtclog2::IncomingRtcpPackets& EventStream::incoming_rtcp_packets(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.incoming_rtcp_packets) - return incoming_rtcp_packets_.Get(index); -} -inline ::webrtc::rtclog2::IncomingRtcpPackets* EventStream::add_incoming_rtcp_packets() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.incoming_rtcp_packets) - return incoming_rtcp_packets_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IncomingRtcpPackets >& -EventStream::incoming_rtcp_packets() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.incoming_rtcp_packets) - return incoming_rtcp_packets_; -} - -// repeated .webrtc.rtclog2.OutgoingRtcpPackets outgoing_rtcp_packets = 5; -inline int EventStream::outgoing_rtcp_packets_size() const { - return outgoing_rtcp_packets_.size(); -} -inline void EventStream::clear_outgoing_rtcp_packets() { - outgoing_rtcp_packets_.Clear(); -} -inline ::webrtc::rtclog2::OutgoingRtcpPackets* EventStream::mutable_outgoing_rtcp_packets(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.outgoing_rtcp_packets) - return outgoing_rtcp_packets_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtcpPackets >* -EventStream::mutable_outgoing_rtcp_packets() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.outgoing_rtcp_packets) - return &outgoing_rtcp_packets_; -} -inline const ::webrtc::rtclog2::OutgoingRtcpPackets& EventStream::outgoing_rtcp_packets(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.outgoing_rtcp_packets) - return outgoing_rtcp_packets_.Get(index); -} -inline ::webrtc::rtclog2::OutgoingRtcpPackets* EventStream::add_outgoing_rtcp_packets() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.outgoing_rtcp_packets) - return outgoing_rtcp_packets_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::OutgoingRtcpPackets >& -EventStream::outgoing_rtcp_packets() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.outgoing_rtcp_packets) - return outgoing_rtcp_packets_; -} - -// repeated .webrtc.rtclog2.AudioPlayoutEvents audio_playout_events = 6; -inline int EventStream::audio_playout_events_size() const { - return audio_playout_events_.size(); -} -inline void EventStream::clear_audio_playout_events() { - audio_playout_events_.Clear(); -} -inline ::webrtc::rtclog2::AudioPlayoutEvents* EventStream::mutable_audio_playout_events(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.audio_playout_events) - return audio_playout_events_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioPlayoutEvents >* -EventStream::mutable_audio_playout_events() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.audio_playout_events) - return &audio_playout_events_; -} -inline const ::webrtc::rtclog2::AudioPlayoutEvents& EventStream::audio_playout_events(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.audio_playout_events) - return audio_playout_events_.Get(index); -} -inline ::webrtc::rtclog2::AudioPlayoutEvents* EventStream::add_audio_playout_events() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.audio_playout_events) - return audio_playout_events_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioPlayoutEvents >& -EventStream::audio_playout_events() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.audio_playout_events) - return audio_playout_events_; -} - -// repeated .webrtc.rtclog2.FrameDecodedEvents frame_decoded_events = 7; -inline int EventStream::frame_decoded_events_size() const { - return frame_decoded_events_.size(); -} -inline void EventStream::clear_frame_decoded_events() { - frame_decoded_events_.Clear(); -} -inline ::webrtc::rtclog2::FrameDecodedEvents* EventStream::mutable_frame_decoded_events(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.frame_decoded_events) - return frame_decoded_events_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::FrameDecodedEvents >* -EventStream::mutable_frame_decoded_events() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.frame_decoded_events) - return &frame_decoded_events_; -} -inline const ::webrtc::rtclog2::FrameDecodedEvents& EventStream::frame_decoded_events(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.frame_decoded_events) - return frame_decoded_events_.Get(index); -} -inline ::webrtc::rtclog2::FrameDecodedEvents* EventStream::add_frame_decoded_events() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.frame_decoded_events) - return frame_decoded_events_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::FrameDecodedEvents >& -EventStream::frame_decoded_events() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.frame_decoded_events) - return frame_decoded_events_; -} - -// repeated .webrtc.rtclog2.BeginLogEvent begin_log_events = 16; -inline int EventStream::begin_log_events_size() const { - return begin_log_events_.size(); -} -inline void EventStream::clear_begin_log_events() { - begin_log_events_.Clear(); -} -inline ::webrtc::rtclog2::BeginLogEvent* EventStream::mutable_begin_log_events(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.begin_log_events) - return begin_log_events_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BeginLogEvent >* -EventStream::mutable_begin_log_events() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.begin_log_events) - return &begin_log_events_; -} -inline const ::webrtc::rtclog2::BeginLogEvent& EventStream::begin_log_events(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.begin_log_events) - return begin_log_events_.Get(index); -} -inline ::webrtc::rtclog2::BeginLogEvent* EventStream::add_begin_log_events() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.begin_log_events) - return begin_log_events_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BeginLogEvent >& -EventStream::begin_log_events() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.begin_log_events) - return begin_log_events_; -} - -// repeated .webrtc.rtclog2.EndLogEvent end_log_events = 17; -inline int EventStream::end_log_events_size() const { - return end_log_events_.size(); -} -inline void EventStream::clear_end_log_events() { - end_log_events_.Clear(); -} -inline ::webrtc::rtclog2::EndLogEvent* EventStream::mutable_end_log_events(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.end_log_events) - return end_log_events_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::EndLogEvent >* -EventStream::mutable_end_log_events() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.end_log_events) - return &end_log_events_; -} -inline const ::webrtc::rtclog2::EndLogEvent& EventStream::end_log_events(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.end_log_events) - return end_log_events_.Get(index); -} -inline ::webrtc::rtclog2::EndLogEvent* EventStream::add_end_log_events() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.end_log_events) - return end_log_events_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::EndLogEvent >& -EventStream::end_log_events() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.end_log_events) - return end_log_events_; -} - -// repeated .webrtc.rtclog2.LossBasedBweUpdates loss_based_bwe_updates = 18; -inline int EventStream::loss_based_bwe_updates_size() const { - return loss_based_bwe_updates_.size(); -} -inline void EventStream::clear_loss_based_bwe_updates() { - loss_based_bwe_updates_.Clear(); -} -inline ::webrtc::rtclog2::LossBasedBweUpdates* EventStream::mutable_loss_based_bwe_updates(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.loss_based_bwe_updates) - return loss_based_bwe_updates_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::LossBasedBweUpdates >* -EventStream::mutable_loss_based_bwe_updates() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.loss_based_bwe_updates) - return &loss_based_bwe_updates_; -} -inline const ::webrtc::rtclog2::LossBasedBweUpdates& EventStream::loss_based_bwe_updates(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.loss_based_bwe_updates) - return loss_based_bwe_updates_.Get(index); -} -inline ::webrtc::rtclog2::LossBasedBweUpdates* EventStream::add_loss_based_bwe_updates() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.loss_based_bwe_updates) - return loss_based_bwe_updates_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::LossBasedBweUpdates >& -EventStream::loss_based_bwe_updates() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.loss_based_bwe_updates) - return loss_based_bwe_updates_; -} - -// repeated .webrtc.rtclog2.DelayBasedBweUpdates delay_based_bwe_updates = 19; -inline int EventStream::delay_based_bwe_updates_size() const { - return delay_based_bwe_updates_.size(); -} -inline void EventStream::clear_delay_based_bwe_updates() { - delay_based_bwe_updates_.Clear(); -} -inline ::webrtc::rtclog2::DelayBasedBweUpdates* EventStream::mutable_delay_based_bwe_updates(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.delay_based_bwe_updates) - return delay_based_bwe_updates_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DelayBasedBweUpdates >* -EventStream::mutable_delay_based_bwe_updates() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.delay_based_bwe_updates) - return &delay_based_bwe_updates_; -} -inline const ::webrtc::rtclog2::DelayBasedBweUpdates& EventStream::delay_based_bwe_updates(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.delay_based_bwe_updates) - return delay_based_bwe_updates_.Get(index); -} -inline ::webrtc::rtclog2::DelayBasedBweUpdates* EventStream::add_delay_based_bwe_updates() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.delay_based_bwe_updates) - return delay_based_bwe_updates_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DelayBasedBweUpdates >& -EventStream::delay_based_bwe_updates() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.delay_based_bwe_updates) - return delay_based_bwe_updates_; -} - -// repeated .webrtc.rtclog2.AudioNetworkAdaptations audio_network_adaptations = 20; -inline int EventStream::audio_network_adaptations_size() const { - return audio_network_adaptations_.size(); -} -inline void EventStream::clear_audio_network_adaptations() { - audio_network_adaptations_.Clear(); -} -inline ::webrtc::rtclog2::AudioNetworkAdaptations* EventStream::mutable_audio_network_adaptations(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.audio_network_adaptations) - return audio_network_adaptations_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioNetworkAdaptations >* -EventStream::mutable_audio_network_adaptations() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.audio_network_adaptations) - return &audio_network_adaptations_; -} -inline const ::webrtc::rtclog2::AudioNetworkAdaptations& EventStream::audio_network_adaptations(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.audio_network_adaptations) - return audio_network_adaptations_.Get(index); -} -inline ::webrtc::rtclog2::AudioNetworkAdaptations* EventStream::add_audio_network_adaptations() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.audio_network_adaptations) - return audio_network_adaptations_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioNetworkAdaptations >& -EventStream::audio_network_adaptations() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.audio_network_adaptations) - return audio_network_adaptations_; -} - -// repeated .webrtc.rtclog2.BweProbeCluster probe_clusters = 21; -inline int EventStream::probe_clusters_size() const { - return probe_clusters_.size(); -} -inline void EventStream::clear_probe_clusters() { - probe_clusters_.Clear(); -} -inline ::webrtc::rtclog2::BweProbeCluster* EventStream::mutable_probe_clusters(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.probe_clusters) - return probe_clusters_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeCluster >* -EventStream::mutable_probe_clusters() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.probe_clusters) - return &probe_clusters_; -} -inline const ::webrtc::rtclog2::BweProbeCluster& EventStream::probe_clusters(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.probe_clusters) - return probe_clusters_.Get(index); -} -inline ::webrtc::rtclog2::BweProbeCluster* EventStream::add_probe_clusters() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.probe_clusters) - return probe_clusters_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeCluster >& -EventStream::probe_clusters() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.probe_clusters) - return probe_clusters_; -} - -// repeated .webrtc.rtclog2.BweProbeResultSuccess probe_success = 22; -inline int EventStream::probe_success_size() const { - return probe_success_.size(); -} -inline void EventStream::clear_probe_success() { - probe_success_.Clear(); -} -inline ::webrtc::rtclog2::BweProbeResultSuccess* EventStream::mutable_probe_success(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.probe_success) - return probe_success_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultSuccess >* -EventStream::mutable_probe_success() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.probe_success) - return &probe_success_; -} -inline const ::webrtc::rtclog2::BweProbeResultSuccess& EventStream::probe_success(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.probe_success) - return probe_success_.Get(index); -} -inline ::webrtc::rtclog2::BweProbeResultSuccess* EventStream::add_probe_success() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.probe_success) - return probe_success_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultSuccess >& -EventStream::probe_success() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.probe_success) - return probe_success_; -} - -// repeated .webrtc.rtclog2.BweProbeResultFailure probe_failure = 23; -inline int EventStream::probe_failure_size() const { - return probe_failure_.size(); -} -inline void EventStream::clear_probe_failure() { - probe_failure_.Clear(); -} -inline ::webrtc::rtclog2::BweProbeResultFailure* EventStream::mutable_probe_failure(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.probe_failure) - return probe_failure_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultFailure >* -EventStream::mutable_probe_failure() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.probe_failure) - return &probe_failure_; -} -inline const ::webrtc::rtclog2::BweProbeResultFailure& EventStream::probe_failure(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.probe_failure) - return probe_failure_.Get(index); -} -inline ::webrtc::rtclog2::BweProbeResultFailure* EventStream::add_probe_failure() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.probe_failure) - return probe_failure_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::BweProbeResultFailure >& -EventStream::probe_failure() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.probe_failure) - return probe_failure_; -} - -// repeated .webrtc.rtclog2.AlrState alr_states = 24; -inline int EventStream::alr_states_size() const { - return alr_states_.size(); -} -inline void EventStream::clear_alr_states() { - alr_states_.Clear(); -} -inline ::webrtc::rtclog2::AlrState* EventStream::mutable_alr_states(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.alr_states) - return alr_states_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AlrState >* -EventStream::mutable_alr_states() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.alr_states) - return &alr_states_; -} -inline const ::webrtc::rtclog2::AlrState& EventStream::alr_states(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.alr_states) - return alr_states_.Get(index); -} -inline ::webrtc::rtclog2::AlrState* EventStream::add_alr_states() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.alr_states) - return alr_states_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AlrState >& -EventStream::alr_states() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.alr_states) - return alr_states_; -} - -// repeated .webrtc.rtclog2.IceCandidatePairConfig ice_candidate_configs = 25; -inline int EventStream::ice_candidate_configs_size() const { - return ice_candidate_configs_.size(); -} -inline void EventStream::clear_ice_candidate_configs() { - ice_candidate_configs_.Clear(); -} -inline ::webrtc::rtclog2::IceCandidatePairConfig* EventStream::mutable_ice_candidate_configs(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.ice_candidate_configs) - return ice_candidate_configs_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairConfig >* -EventStream::mutable_ice_candidate_configs() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.ice_candidate_configs) - return &ice_candidate_configs_; -} -inline const ::webrtc::rtclog2::IceCandidatePairConfig& EventStream::ice_candidate_configs(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.ice_candidate_configs) - return ice_candidate_configs_.Get(index); -} -inline ::webrtc::rtclog2::IceCandidatePairConfig* EventStream::add_ice_candidate_configs() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.ice_candidate_configs) - return ice_candidate_configs_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairConfig >& -EventStream::ice_candidate_configs() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.ice_candidate_configs) - return ice_candidate_configs_; -} - -// repeated .webrtc.rtclog2.IceCandidatePairEvent ice_candidate_events = 26; -inline int EventStream::ice_candidate_events_size() const { - return ice_candidate_events_.size(); -} -inline void EventStream::clear_ice_candidate_events() { - ice_candidate_events_.Clear(); -} -inline ::webrtc::rtclog2::IceCandidatePairEvent* EventStream::mutable_ice_candidate_events(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.ice_candidate_events) - return ice_candidate_events_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairEvent >* -EventStream::mutable_ice_candidate_events() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.ice_candidate_events) - return &ice_candidate_events_; -} -inline const ::webrtc::rtclog2::IceCandidatePairEvent& EventStream::ice_candidate_events(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.ice_candidate_events) - return ice_candidate_events_.Get(index); -} -inline ::webrtc::rtclog2::IceCandidatePairEvent* EventStream::add_ice_candidate_events() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.ice_candidate_events) - return ice_candidate_events_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::IceCandidatePairEvent >& -EventStream::ice_candidate_events() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.ice_candidate_events) - return ice_candidate_events_; -} - -// repeated .webrtc.rtclog2.DtlsTransportStateEvent dtls_transport_state_events = 27; -inline int EventStream::dtls_transport_state_events_size() const { - return dtls_transport_state_events_.size(); -} -inline void EventStream::clear_dtls_transport_state_events() { - dtls_transport_state_events_.Clear(); -} -inline ::webrtc::rtclog2::DtlsTransportStateEvent* EventStream::mutable_dtls_transport_state_events(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.dtls_transport_state_events) - return dtls_transport_state_events_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsTransportStateEvent >* -EventStream::mutable_dtls_transport_state_events() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.dtls_transport_state_events) - return &dtls_transport_state_events_; -} -inline const ::webrtc::rtclog2::DtlsTransportStateEvent& EventStream::dtls_transport_state_events(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.dtls_transport_state_events) - return dtls_transport_state_events_.Get(index); -} -inline ::webrtc::rtclog2::DtlsTransportStateEvent* EventStream::add_dtls_transport_state_events() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.dtls_transport_state_events) - return dtls_transport_state_events_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsTransportStateEvent >& -EventStream::dtls_transport_state_events() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.dtls_transport_state_events) - return dtls_transport_state_events_; -} - -// repeated .webrtc.rtclog2.DtlsWritableState dtls_writable_states = 28; -inline int EventStream::dtls_writable_states_size() const { - return dtls_writable_states_.size(); -} -inline void EventStream::clear_dtls_writable_states() { - dtls_writable_states_.Clear(); -} -inline ::webrtc::rtclog2::DtlsWritableState* EventStream::mutable_dtls_writable_states(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.dtls_writable_states) - return dtls_writable_states_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsWritableState >* -EventStream::mutable_dtls_writable_states() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.dtls_writable_states) - return &dtls_writable_states_; -} -inline const ::webrtc::rtclog2::DtlsWritableState& EventStream::dtls_writable_states(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.dtls_writable_states) - return dtls_writable_states_.Get(index); -} -inline ::webrtc::rtclog2::DtlsWritableState* EventStream::add_dtls_writable_states() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.dtls_writable_states) - return dtls_writable_states_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::DtlsWritableState >& -EventStream::dtls_writable_states() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.dtls_writable_states) - return dtls_writable_states_; -} - -// repeated .webrtc.rtclog2.GenericPacketSent generic_packets_sent = 29; -inline int EventStream::generic_packets_sent_size() const { - return generic_packets_sent_.size(); -} -inline void EventStream::clear_generic_packets_sent() { - generic_packets_sent_.Clear(); -} -inline ::webrtc::rtclog2::GenericPacketSent* EventStream::mutable_generic_packets_sent(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.generic_packets_sent) - return generic_packets_sent_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketSent >* -EventStream::mutable_generic_packets_sent() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.generic_packets_sent) - return &generic_packets_sent_; -} -inline const ::webrtc::rtclog2::GenericPacketSent& EventStream::generic_packets_sent(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.generic_packets_sent) - return generic_packets_sent_.Get(index); -} -inline ::webrtc::rtclog2::GenericPacketSent* EventStream::add_generic_packets_sent() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.generic_packets_sent) - return generic_packets_sent_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketSent >& -EventStream::generic_packets_sent() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.generic_packets_sent) - return generic_packets_sent_; -} - -// repeated .webrtc.rtclog2.GenericPacketReceived generic_packets_received = 30; -inline int EventStream::generic_packets_received_size() const { - return generic_packets_received_.size(); -} -inline void EventStream::clear_generic_packets_received() { - generic_packets_received_.Clear(); -} -inline ::webrtc::rtclog2::GenericPacketReceived* EventStream::mutable_generic_packets_received(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.generic_packets_received) - return generic_packets_received_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketReceived >* -EventStream::mutable_generic_packets_received() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.generic_packets_received) - return &generic_packets_received_; -} -inline const ::webrtc::rtclog2::GenericPacketReceived& EventStream::generic_packets_received(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.generic_packets_received) - return generic_packets_received_.Get(index); -} -inline ::webrtc::rtclog2::GenericPacketReceived* EventStream::add_generic_packets_received() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.generic_packets_received) - return generic_packets_received_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericPacketReceived >& -EventStream::generic_packets_received() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.generic_packets_received) - return generic_packets_received_; -} - -// repeated .webrtc.rtclog2.GenericAckReceived generic_acks_received = 31; -inline int EventStream::generic_acks_received_size() const { - return generic_acks_received_.size(); -} -inline void EventStream::clear_generic_acks_received() { - generic_acks_received_.Clear(); -} -inline ::webrtc::rtclog2::GenericAckReceived* EventStream::mutable_generic_acks_received(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.generic_acks_received) - return generic_acks_received_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericAckReceived >* -EventStream::mutable_generic_acks_received() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.generic_acks_received) - return &generic_acks_received_; -} -inline const ::webrtc::rtclog2::GenericAckReceived& EventStream::generic_acks_received(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.generic_acks_received) - return generic_acks_received_.Get(index); -} -inline ::webrtc::rtclog2::GenericAckReceived* EventStream::add_generic_acks_received() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.generic_acks_received) - return generic_acks_received_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::GenericAckReceived >& -EventStream::generic_acks_received() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.generic_acks_received) - return generic_acks_received_; -} - -// repeated .webrtc.rtclog2.RouteChange route_changes = 32; -inline int EventStream::route_changes_size() const { - return route_changes_.size(); -} -inline void EventStream::clear_route_changes() { - route_changes_.Clear(); -} -inline ::webrtc::rtclog2::RouteChange* EventStream::mutable_route_changes(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.route_changes) - return route_changes_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RouteChange >* -EventStream::mutable_route_changes() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.route_changes) - return &route_changes_; -} -inline const ::webrtc::rtclog2::RouteChange& EventStream::route_changes(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.route_changes) - return route_changes_.Get(index); -} -inline ::webrtc::rtclog2::RouteChange* EventStream::add_route_changes() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.route_changes) - return route_changes_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RouteChange >& -EventStream::route_changes() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.route_changes) - return route_changes_; -} - -// repeated .webrtc.rtclog2.RemoteEstimates remote_estimates = 33; -inline int EventStream::remote_estimates_size() const { - return remote_estimates_.size(); -} -inline void EventStream::clear_remote_estimates() { - remote_estimates_.Clear(); -} -inline ::webrtc::rtclog2::RemoteEstimates* EventStream::mutable_remote_estimates(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.remote_estimates) - return remote_estimates_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RemoteEstimates >* -EventStream::mutable_remote_estimates() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.remote_estimates) - return &remote_estimates_; -} -inline const ::webrtc::rtclog2::RemoteEstimates& EventStream::remote_estimates(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.remote_estimates) - return remote_estimates_.Get(index); -} -inline ::webrtc::rtclog2::RemoteEstimates* EventStream::add_remote_estimates() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.remote_estimates) - return remote_estimates_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::RemoteEstimates >& -EventStream::remote_estimates() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.remote_estimates) - return remote_estimates_; -} - -// repeated .webrtc.rtclog2.AudioRecvStreamConfig audio_recv_stream_configs = 101; -inline int EventStream::audio_recv_stream_configs_size() const { - return audio_recv_stream_configs_.size(); -} -inline void EventStream::clear_audio_recv_stream_configs() { - audio_recv_stream_configs_.Clear(); -} -inline ::webrtc::rtclog2::AudioRecvStreamConfig* EventStream::mutable_audio_recv_stream_configs(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.audio_recv_stream_configs) - return audio_recv_stream_configs_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioRecvStreamConfig >* -EventStream::mutable_audio_recv_stream_configs() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.audio_recv_stream_configs) - return &audio_recv_stream_configs_; -} -inline const ::webrtc::rtclog2::AudioRecvStreamConfig& EventStream::audio_recv_stream_configs(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.audio_recv_stream_configs) - return audio_recv_stream_configs_.Get(index); -} -inline ::webrtc::rtclog2::AudioRecvStreamConfig* EventStream::add_audio_recv_stream_configs() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.audio_recv_stream_configs) - return audio_recv_stream_configs_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioRecvStreamConfig >& -EventStream::audio_recv_stream_configs() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.audio_recv_stream_configs) - return audio_recv_stream_configs_; -} - -// repeated .webrtc.rtclog2.AudioSendStreamConfig audio_send_stream_configs = 102; -inline int EventStream::audio_send_stream_configs_size() const { - return audio_send_stream_configs_.size(); -} -inline void EventStream::clear_audio_send_stream_configs() { - audio_send_stream_configs_.Clear(); -} -inline ::webrtc::rtclog2::AudioSendStreamConfig* EventStream::mutable_audio_send_stream_configs(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.audio_send_stream_configs) - return audio_send_stream_configs_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioSendStreamConfig >* -EventStream::mutable_audio_send_stream_configs() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.audio_send_stream_configs) - return &audio_send_stream_configs_; -} -inline const ::webrtc::rtclog2::AudioSendStreamConfig& EventStream::audio_send_stream_configs(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.audio_send_stream_configs) - return audio_send_stream_configs_.Get(index); -} -inline ::webrtc::rtclog2::AudioSendStreamConfig* EventStream::add_audio_send_stream_configs() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.audio_send_stream_configs) - return audio_send_stream_configs_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::AudioSendStreamConfig >& -EventStream::audio_send_stream_configs() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.audio_send_stream_configs) - return audio_send_stream_configs_; -} - -// repeated .webrtc.rtclog2.VideoRecvStreamConfig video_recv_stream_configs = 103; -inline int EventStream::video_recv_stream_configs_size() const { - return video_recv_stream_configs_.size(); -} -inline void EventStream::clear_video_recv_stream_configs() { - video_recv_stream_configs_.Clear(); -} -inline ::webrtc::rtclog2::VideoRecvStreamConfig* EventStream::mutable_video_recv_stream_configs(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.video_recv_stream_configs) - return video_recv_stream_configs_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoRecvStreamConfig >* -EventStream::mutable_video_recv_stream_configs() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.video_recv_stream_configs) - return &video_recv_stream_configs_; -} -inline const ::webrtc::rtclog2::VideoRecvStreamConfig& EventStream::video_recv_stream_configs(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.video_recv_stream_configs) - return video_recv_stream_configs_.Get(index); -} -inline ::webrtc::rtclog2::VideoRecvStreamConfig* EventStream::add_video_recv_stream_configs() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.video_recv_stream_configs) - return video_recv_stream_configs_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoRecvStreamConfig >& -EventStream::video_recv_stream_configs() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.video_recv_stream_configs) - return video_recv_stream_configs_; -} - -// repeated .webrtc.rtclog2.VideoSendStreamConfig video_send_stream_configs = 104; -inline int EventStream::video_send_stream_configs_size() const { - return video_send_stream_configs_.size(); -} -inline void EventStream::clear_video_send_stream_configs() { - video_send_stream_configs_.Clear(); -} -inline ::webrtc::rtclog2::VideoSendStreamConfig* EventStream::mutable_video_send_stream_configs(int index) { - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.EventStream.video_send_stream_configs) - return video_send_stream_configs_.Mutable(index); -} -inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoSendStreamConfig >* -EventStream::mutable_video_send_stream_configs() { - // @@protoc_insertion_point(field_mutable_list:webrtc.rtclog2.EventStream.video_send_stream_configs) - return &video_send_stream_configs_; -} -inline const ::webrtc::rtclog2::VideoSendStreamConfig& EventStream::video_send_stream_configs(int index) const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EventStream.video_send_stream_configs) - return video_send_stream_configs_.Get(index); -} -inline ::webrtc::rtclog2::VideoSendStreamConfig* EventStream::add_video_send_stream_configs() { - // @@protoc_insertion_point(field_add:webrtc.rtclog2.EventStream.video_send_stream_configs) - return video_send_stream_configs_.Add(); -} -inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::webrtc::rtclog2::VideoSendStreamConfig >& -EventStream::video_send_stream_configs() const { - // @@protoc_insertion_point(field_list:webrtc.rtclog2.EventStream.video_send_stream_configs) - return video_send_stream_configs_; -} - -// ------------------------------------------------------------------- - -// Event - -// ------------------------------------------------------------------- - -// GenericPacketReceived - -// optional int64 timestamp_ms = 1; -inline bool GenericPacketReceived::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void GenericPacketReceived::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 GenericPacketReceived::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketReceived.timestamp_ms) - return timestamp_ms_; -} -inline void GenericPacketReceived::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000008u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketReceived.timestamp_ms) -} - -// optional int64 packet_number = 2; -inline bool GenericPacketReceived::has_packet_number() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void GenericPacketReceived::clear_packet_number() { - packet_number_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 GenericPacketReceived::packet_number() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketReceived.packet_number) - return packet_number_; -} -inline void GenericPacketReceived::set_packet_number(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000010u; - packet_number_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketReceived.packet_number) -} - -// optional int32 packet_length = 3; -inline bool GenericPacketReceived::has_packet_length() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void GenericPacketReceived::clear_packet_length() { - packet_length_ = 0; - _has_bits_[0] &= ~0x00000020u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 GenericPacketReceived::packet_length() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketReceived.packet_length) - return packet_length_; -} -inline void GenericPacketReceived::set_packet_length(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000020u; - packet_length_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketReceived.packet_length) -} - -// optional uint32 number_of_deltas = 16; -inline bool GenericPacketReceived::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void GenericPacketReceived::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000040u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 GenericPacketReceived::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketReceived.number_of_deltas) - return number_of_deltas_; -} -inline void GenericPacketReceived::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000040u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketReceived.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 17; -inline bool GenericPacketReceived::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void GenericPacketReceived::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& GenericPacketReceived::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketReceived.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void GenericPacketReceived::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketReceived.timestamp_ms_deltas) -} -inline void GenericPacketReceived::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericPacketReceived.timestamp_ms_deltas) -} -inline void GenericPacketReceived::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericPacketReceived.timestamp_ms_deltas) -} -inline void GenericPacketReceived::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericPacketReceived.timestamp_ms_deltas) -} -inline std::string* GenericPacketReceived::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericPacketReceived.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericPacketReceived::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericPacketReceived.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericPacketReceived::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericPacketReceived.timestamp_ms_deltas) -} - -// optional bytes packet_number_deltas = 18; -inline bool GenericPacketReceived::has_packet_number_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void GenericPacketReceived::clear_packet_number_deltas() { - packet_number_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& GenericPacketReceived::packet_number_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketReceived.packet_number_deltas) - return packet_number_deltas_.GetNoArena(); -} -inline void GenericPacketReceived::set_packet_number_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketReceived.packet_number_deltas) -} -inline void GenericPacketReceived::set_packet_number_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericPacketReceived.packet_number_deltas) -} -inline void GenericPacketReceived::set_packet_number_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericPacketReceived.packet_number_deltas) -} -inline void GenericPacketReceived::set_packet_number_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericPacketReceived.packet_number_deltas) -} -inline std::string* GenericPacketReceived::mutable_packet_number_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericPacketReceived.packet_number_deltas) - return packet_number_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericPacketReceived::release_packet_number_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericPacketReceived.packet_number_deltas) - if (!has_packet_number_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return packet_number_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericPacketReceived::set_allocated_packet_number_deltas(std::string* packet_number_deltas) { - if (packet_number_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - packet_number_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), packet_number_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericPacketReceived.packet_number_deltas) -} - -// optional bytes packet_length_deltas = 19; -inline bool GenericPacketReceived::has_packet_length_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void GenericPacketReceived::clear_packet_length_deltas() { - packet_length_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& GenericPacketReceived::packet_length_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketReceived.packet_length_deltas) - return packet_length_deltas_.GetNoArena(); -} -inline void GenericPacketReceived::set_packet_length_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - packet_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketReceived.packet_length_deltas) -} -inline void GenericPacketReceived::set_packet_length_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - packet_length_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericPacketReceived.packet_length_deltas) -} -inline void GenericPacketReceived::set_packet_length_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - packet_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericPacketReceived.packet_length_deltas) -} -inline void GenericPacketReceived::set_packet_length_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - packet_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericPacketReceived.packet_length_deltas) -} -inline std::string* GenericPacketReceived::mutable_packet_length_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericPacketReceived.packet_length_deltas) - return packet_length_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericPacketReceived::release_packet_length_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericPacketReceived.packet_length_deltas) - if (!has_packet_length_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return packet_length_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericPacketReceived::set_allocated_packet_length_deltas(std::string* packet_length_deltas) { - if (packet_length_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - packet_length_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), packet_length_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericPacketReceived.packet_length_deltas) -} - -// ------------------------------------------------------------------- - -// GenericPacketSent - -// optional int64 timestamp_ms = 1; -inline bool GenericPacketSent::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void GenericPacketSent::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000020u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 GenericPacketSent::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.timestamp_ms) - return timestamp_ms_; -} -inline void GenericPacketSent::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000020u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.timestamp_ms) -} - -// optional int64 packet_number = 2; -inline bool GenericPacketSent::has_packet_number() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void GenericPacketSent::clear_packet_number() { - packet_number_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000040u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 GenericPacketSent::packet_number() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.packet_number) - return packet_number_; -} -inline void GenericPacketSent::set_packet_number(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000040u; - packet_number_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.packet_number) -} - -// optional int32 overhead_length = 3; -inline bool GenericPacketSent::has_overhead_length() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void GenericPacketSent::clear_overhead_length() { - overhead_length_ = 0; - _has_bits_[0] &= ~0x00000080u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 GenericPacketSent::overhead_length() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.overhead_length) - return overhead_length_; -} -inline void GenericPacketSent::set_overhead_length(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000080u; - overhead_length_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.overhead_length) -} - -// optional int32 payload_length = 4; -inline bool GenericPacketSent::has_payload_length() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void GenericPacketSent::clear_payload_length() { - payload_length_ = 0; - _has_bits_[0] &= ~0x00000100u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 GenericPacketSent::payload_length() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.payload_length) - return payload_length_; -} -inline void GenericPacketSent::set_payload_length(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000100u; - payload_length_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.payload_length) -} - -// optional int32 padding_length = 5; -inline bool GenericPacketSent::has_padding_length() const { - return (_has_bits_[0] & 0x00000200u) != 0; -} -inline void GenericPacketSent::clear_padding_length() { - padding_length_ = 0; - _has_bits_[0] &= ~0x00000200u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 GenericPacketSent::padding_length() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.padding_length) - return padding_length_; -} -inline void GenericPacketSent::set_padding_length(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000200u; - padding_length_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.padding_length) -} - -// optional uint32 number_of_deltas = 16; -inline bool GenericPacketSent::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000400u) != 0; -} -inline void GenericPacketSent::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000400u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 GenericPacketSent::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.number_of_deltas) - return number_of_deltas_; -} -inline void GenericPacketSent::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000400u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 17; -inline bool GenericPacketSent::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void GenericPacketSent::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& GenericPacketSent::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void GenericPacketSent::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.timestamp_ms_deltas) -} -inline void GenericPacketSent::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericPacketSent.timestamp_ms_deltas) -} -inline void GenericPacketSent::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericPacketSent.timestamp_ms_deltas) -} -inline void GenericPacketSent::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericPacketSent.timestamp_ms_deltas) -} -inline std::string* GenericPacketSent::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericPacketSent.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericPacketSent::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericPacketSent.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericPacketSent::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericPacketSent.timestamp_ms_deltas) -} - -// optional bytes packet_number_deltas = 18; -inline bool GenericPacketSent::has_packet_number_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void GenericPacketSent::clear_packet_number_deltas() { - packet_number_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& GenericPacketSent::packet_number_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.packet_number_deltas) - return packet_number_deltas_.GetNoArena(); -} -inline void GenericPacketSent::set_packet_number_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.packet_number_deltas) -} -inline void GenericPacketSent::set_packet_number_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericPacketSent.packet_number_deltas) -} -inline void GenericPacketSent::set_packet_number_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericPacketSent.packet_number_deltas) -} -inline void GenericPacketSent::set_packet_number_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericPacketSent.packet_number_deltas) -} -inline std::string* GenericPacketSent::mutable_packet_number_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericPacketSent.packet_number_deltas) - return packet_number_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericPacketSent::release_packet_number_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericPacketSent.packet_number_deltas) - if (!has_packet_number_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return packet_number_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericPacketSent::set_allocated_packet_number_deltas(std::string* packet_number_deltas) { - if (packet_number_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - packet_number_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), packet_number_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericPacketSent.packet_number_deltas) -} - -// optional bytes overhead_length_deltas = 19; -inline bool GenericPacketSent::has_overhead_length_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void GenericPacketSent::clear_overhead_length_deltas() { - overhead_length_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& GenericPacketSent::overhead_length_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.overhead_length_deltas) - return overhead_length_deltas_.GetNoArena(); -} -inline void GenericPacketSent::set_overhead_length_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - overhead_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.overhead_length_deltas) -} -inline void GenericPacketSent::set_overhead_length_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - overhead_length_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericPacketSent.overhead_length_deltas) -} -inline void GenericPacketSent::set_overhead_length_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - overhead_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericPacketSent.overhead_length_deltas) -} -inline void GenericPacketSent::set_overhead_length_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - overhead_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericPacketSent.overhead_length_deltas) -} -inline std::string* GenericPacketSent::mutable_overhead_length_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericPacketSent.overhead_length_deltas) - return overhead_length_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericPacketSent::release_overhead_length_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericPacketSent.overhead_length_deltas) - if (!has_overhead_length_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return overhead_length_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericPacketSent::set_allocated_overhead_length_deltas(std::string* overhead_length_deltas) { - if (overhead_length_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - overhead_length_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), overhead_length_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericPacketSent.overhead_length_deltas) -} - -// optional bytes payload_length_deltas = 20; -inline bool GenericPacketSent::has_payload_length_deltas() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void GenericPacketSent::clear_payload_length_deltas() { - payload_length_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000008u; -} -inline const std::string& GenericPacketSent::payload_length_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.payload_length_deltas) - return payload_length_deltas_.GetNoArena(); -} -inline void GenericPacketSent::set_payload_length_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000008u; - payload_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.payload_length_deltas) -} -inline void GenericPacketSent::set_payload_length_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000008u; - payload_length_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericPacketSent.payload_length_deltas) -} -inline void GenericPacketSent::set_payload_length_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000008u; - payload_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericPacketSent.payload_length_deltas) -} -inline void GenericPacketSent::set_payload_length_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000008u; - payload_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericPacketSent.payload_length_deltas) -} -inline std::string* GenericPacketSent::mutable_payload_length_deltas() { - _has_bits_[0] |= 0x00000008u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericPacketSent.payload_length_deltas) - return payload_length_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericPacketSent::release_payload_length_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericPacketSent.payload_length_deltas) - if (!has_payload_length_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000008u; - return payload_length_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericPacketSent::set_allocated_payload_length_deltas(std::string* payload_length_deltas) { - if (payload_length_deltas != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - payload_length_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), payload_length_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericPacketSent.payload_length_deltas) -} - -// optional bytes padding_length_deltas = 21; -inline bool GenericPacketSent::has_padding_length_deltas() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void GenericPacketSent::clear_padding_length_deltas() { - padding_length_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000010u; -} -inline const std::string& GenericPacketSent::padding_length_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericPacketSent.padding_length_deltas) - return padding_length_deltas_.GetNoArena(); -} -inline void GenericPacketSent::set_padding_length_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000010u; - padding_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericPacketSent.padding_length_deltas) -} -inline void GenericPacketSent::set_padding_length_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000010u; - padding_length_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericPacketSent.padding_length_deltas) -} -inline void GenericPacketSent::set_padding_length_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000010u; - padding_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericPacketSent.padding_length_deltas) -} -inline void GenericPacketSent::set_padding_length_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000010u; - padding_length_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericPacketSent.padding_length_deltas) -} -inline std::string* GenericPacketSent::mutable_padding_length_deltas() { - _has_bits_[0] |= 0x00000010u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericPacketSent.padding_length_deltas) - return padding_length_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericPacketSent::release_padding_length_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericPacketSent.padding_length_deltas) - if (!has_padding_length_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000010u; - return padding_length_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericPacketSent::set_allocated_padding_length_deltas(std::string* padding_length_deltas) { - if (padding_length_deltas != nullptr) { - _has_bits_[0] |= 0x00000010u; - } else { - _has_bits_[0] &= ~0x00000010u; - } - padding_length_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), padding_length_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericPacketSent.padding_length_deltas) -} - -// ------------------------------------------------------------------- - -// GenericAckReceived - -// optional int64 timestamp_ms = 1; -inline bool GenericAckReceived::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void GenericAckReceived::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 GenericAckReceived::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.timestamp_ms) - return timestamp_ms_; -} -inline void GenericAckReceived::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000010u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.timestamp_ms) -} - -// optional int64 packet_number = 2; -inline bool GenericAckReceived::has_packet_number() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void GenericAckReceived::clear_packet_number() { - packet_number_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000020u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 GenericAckReceived::packet_number() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.packet_number) - return packet_number_; -} -inline void GenericAckReceived::set_packet_number(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000020u; - packet_number_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.packet_number) -} - -// optional int64 acked_packet_number = 3; -inline bool GenericAckReceived::has_acked_packet_number() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void GenericAckReceived::clear_acked_packet_number() { - acked_packet_number_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000040u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 GenericAckReceived::acked_packet_number() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.acked_packet_number) - return acked_packet_number_; -} -inline void GenericAckReceived::set_acked_packet_number(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000040u; - acked_packet_number_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.acked_packet_number) -} - -// optional int64 receive_acked_packet_time_ms = 4; -inline bool GenericAckReceived::has_receive_acked_packet_time_ms() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void GenericAckReceived::clear_receive_acked_packet_time_ms() { - receive_acked_packet_time_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000080u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 GenericAckReceived::receive_acked_packet_time_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms) - return receive_acked_packet_time_ms_; -} -inline void GenericAckReceived::set_receive_acked_packet_time_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000080u; - receive_acked_packet_time_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms) -} - -// optional uint32 number_of_deltas = 16; -inline bool GenericAckReceived::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void GenericAckReceived::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000100u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 GenericAckReceived::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.number_of_deltas) - return number_of_deltas_; -} -inline void GenericAckReceived::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000100u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 17; -inline bool GenericAckReceived::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void GenericAckReceived::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& GenericAckReceived::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void GenericAckReceived::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.timestamp_ms_deltas) -} -inline void GenericAckReceived::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericAckReceived.timestamp_ms_deltas) -} -inline void GenericAckReceived::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericAckReceived.timestamp_ms_deltas) -} -inline void GenericAckReceived::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericAckReceived.timestamp_ms_deltas) -} -inline std::string* GenericAckReceived::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericAckReceived.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericAckReceived::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericAckReceived.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericAckReceived::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericAckReceived.timestamp_ms_deltas) -} - -// optional bytes packet_number_deltas = 18; -inline bool GenericAckReceived::has_packet_number_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void GenericAckReceived::clear_packet_number_deltas() { - packet_number_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& GenericAckReceived::packet_number_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.packet_number_deltas) - return packet_number_deltas_.GetNoArena(); -} -inline void GenericAckReceived::set_packet_number_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.packet_number_deltas) -} -inline void GenericAckReceived::set_packet_number_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericAckReceived.packet_number_deltas) -} -inline void GenericAckReceived::set_packet_number_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericAckReceived.packet_number_deltas) -} -inline void GenericAckReceived::set_packet_number_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericAckReceived.packet_number_deltas) -} -inline std::string* GenericAckReceived::mutable_packet_number_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericAckReceived.packet_number_deltas) - return packet_number_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericAckReceived::release_packet_number_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericAckReceived.packet_number_deltas) - if (!has_packet_number_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return packet_number_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericAckReceived::set_allocated_packet_number_deltas(std::string* packet_number_deltas) { - if (packet_number_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - packet_number_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), packet_number_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericAckReceived.packet_number_deltas) -} - -// optional bytes acked_packet_number_deltas = 19; -inline bool GenericAckReceived::has_acked_packet_number_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void GenericAckReceived::clear_acked_packet_number_deltas() { - acked_packet_number_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& GenericAckReceived::acked_packet_number_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.acked_packet_number_deltas) - return acked_packet_number_deltas_.GetNoArena(); -} -inline void GenericAckReceived::set_acked_packet_number_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - acked_packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.acked_packet_number_deltas) -} -inline void GenericAckReceived::set_acked_packet_number_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - acked_packet_number_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericAckReceived.acked_packet_number_deltas) -} -inline void GenericAckReceived::set_acked_packet_number_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - acked_packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericAckReceived.acked_packet_number_deltas) -} -inline void GenericAckReceived::set_acked_packet_number_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - acked_packet_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericAckReceived.acked_packet_number_deltas) -} -inline std::string* GenericAckReceived::mutable_acked_packet_number_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericAckReceived.acked_packet_number_deltas) - return acked_packet_number_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericAckReceived::release_acked_packet_number_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericAckReceived.acked_packet_number_deltas) - if (!has_acked_packet_number_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return acked_packet_number_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericAckReceived::set_allocated_acked_packet_number_deltas(std::string* acked_packet_number_deltas) { - if (acked_packet_number_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - acked_packet_number_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), acked_packet_number_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericAckReceived.acked_packet_number_deltas) -} - -// optional bytes receive_acked_packet_time_ms_deltas = 20; -inline bool GenericAckReceived::has_receive_acked_packet_time_ms_deltas() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void GenericAckReceived::clear_receive_acked_packet_time_ms_deltas() { - receive_acked_packet_time_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000008u; -} -inline const std::string& GenericAckReceived::receive_acked_packet_time_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms_deltas) - return receive_acked_packet_time_ms_deltas_.GetNoArena(); -} -inline void GenericAckReceived::set_receive_acked_packet_time_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000008u; - receive_acked_packet_time_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms_deltas) -} -inline void GenericAckReceived::set_receive_acked_packet_time_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000008u; - receive_acked_packet_time_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms_deltas) -} -inline void GenericAckReceived::set_receive_acked_packet_time_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000008u; - receive_acked_packet_time_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms_deltas) -} -inline void GenericAckReceived::set_receive_acked_packet_time_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000008u; - receive_acked_packet_time_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms_deltas) -} -inline std::string* GenericAckReceived::mutable_receive_acked_packet_time_ms_deltas() { - _has_bits_[0] |= 0x00000008u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms_deltas) - return receive_acked_packet_time_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* GenericAckReceived::release_receive_acked_packet_time_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms_deltas) - if (!has_receive_acked_packet_time_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000008u; - return receive_acked_packet_time_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void GenericAckReceived::set_allocated_receive_acked_packet_time_ms_deltas(std::string* receive_acked_packet_time_ms_deltas) { - if (receive_acked_packet_time_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - receive_acked_packet_time_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), receive_acked_packet_time_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.GenericAckReceived.receive_acked_packet_time_ms_deltas) -} - -// ------------------------------------------------------------------- - -// IncomingRtpPackets - -// optional int64 timestamp_ms = 1; -inline bool IncomingRtpPackets::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00008000u) != 0; -} -inline void IncomingRtpPackets::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00008000u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 IncomingRtpPackets::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms) - return timestamp_ms_; -} -inline void IncomingRtpPackets::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00008000u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms) -} - -// optional bool marker = 2; -inline bool IncomingRtpPackets::has_marker() const { - return (_has_bits_[0] & 0x01000000u) != 0; -} -inline void IncomingRtpPackets::clear_marker() { - marker_ = false; - _has_bits_[0] &= ~0x01000000u; -} -inline bool IncomingRtpPackets::marker() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.marker) - return marker_; -} -inline void IncomingRtpPackets::set_marker(bool value) { - _has_bits_[0] |= 0x01000000u; - marker_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.marker) -} - -// optional uint32 payload_type = 3; -inline bool IncomingRtpPackets::has_payload_type() const { - return (_has_bits_[0] & 0x00010000u) != 0; -} -inline void IncomingRtpPackets::clear_payload_type() { - payload_type_ = 0u; - _has_bits_[0] &= ~0x00010000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::payload_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.payload_type) - return payload_type_; -} -inline void IncomingRtpPackets::set_payload_type(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00010000u; - payload_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.payload_type) -} - -// optional uint32 sequence_number = 4; -inline bool IncomingRtpPackets::has_sequence_number() const { - return (_has_bits_[0] & 0x00020000u) != 0; -} -inline void IncomingRtpPackets::clear_sequence_number() { - sequence_number_ = 0u; - _has_bits_[0] &= ~0x00020000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::sequence_number() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.sequence_number) - return sequence_number_; -} -inline void IncomingRtpPackets::set_sequence_number(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00020000u; - sequence_number_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.sequence_number) -} - -// optional fixed32 rtp_timestamp = 5; -inline bool IncomingRtpPackets::has_rtp_timestamp() const { - return (_has_bits_[0] & 0x00040000u) != 0; -} -inline void IncomingRtpPackets::clear_rtp_timestamp() { - rtp_timestamp_ = 0u; - _has_bits_[0] &= ~0x00040000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::rtp_timestamp() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp) - return rtp_timestamp_; -} -inline void IncomingRtpPackets::set_rtp_timestamp(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00040000u; - rtp_timestamp_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp) -} - -// optional fixed32 ssrc = 6; -inline bool IncomingRtpPackets::has_ssrc() const { - return (_has_bits_[0] & 0x00080000u) != 0; -} -inline void IncomingRtpPackets::clear_ssrc() { - ssrc_ = 0u; - _has_bits_[0] &= ~0x00080000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.ssrc) - return ssrc_; -} -inline void IncomingRtpPackets::set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00080000u; - ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.ssrc) -} - -// optional uint32 payload_size = 8; -inline bool IncomingRtpPackets::has_payload_size() const { - return (_has_bits_[0] & 0x00100000u) != 0; -} -inline void IncomingRtpPackets::clear_payload_size() { - payload_size_ = 0u; - _has_bits_[0] &= ~0x00100000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::payload_size() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.payload_size) - return payload_size_; -} -inline void IncomingRtpPackets::set_payload_size(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00100000u; - payload_size_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.payload_size) -} - -// optional uint32 header_size = 9; -inline bool IncomingRtpPackets::has_header_size() const { - return (_has_bits_[0] & 0x00200000u) != 0; -} -inline void IncomingRtpPackets::clear_header_size() { - header_size_ = 0u; - _has_bits_[0] &= ~0x00200000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::header_size() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.header_size) - return header_size_; -} -inline void IncomingRtpPackets::set_header_size(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00200000u; - header_size_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.header_size) -} - -// optional uint32 padding_size = 10; -inline bool IncomingRtpPackets::has_padding_size() const { - return (_has_bits_[0] & 0x00400000u) != 0; -} -inline void IncomingRtpPackets::clear_padding_size() { - padding_size_ = 0u; - _has_bits_[0] &= ~0x00400000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::padding_size() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.padding_size) - return padding_size_; -} -inline void IncomingRtpPackets::set_padding_size(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00400000u; - padding_size_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.padding_size) -} - -// optional uint32 number_of_deltas = 11; -inline bool IncomingRtpPackets::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00800000u) != 0; -} -inline void IncomingRtpPackets::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00800000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.number_of_deltas) - return number_of_deltas_; -} -inline void IncomingRtpPackets::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00800000u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.number_of_deltas) -} - -// optional uint32 transport_sequence_number = 15; -inline bool IncomingRtpPackets::has_transport_sequence_number() const { - return (_has_bits_[0] & 0x04000000u) != 0; -} -inline void IncomingRtpPackets::clear_transport_sequence_number() { - transport_sequence_number_ = 0u; - _has_bits_[0] &= ~0x04000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::transport_sequence_number() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number) - return transport_sequence_number_; -} -inline void IncomingRtpPackets::set_transport_sequence_number(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x04000000u; - transport_sequence_number_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number) -} - -// optional int32 transmission_time_offset = 16; -inline bool IncomingRtpPackets::has_transmission_time_offset() const { - return (_has_bits_[0] & 0x08000000u) != 0; -} -inline void IncomingRtpPackets::clear_transmission_time_offset() { - transmission_time_offset_ = 0; - _has_bits_[0] &= ~0x08000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 IncomingRtpPackets::transmission_time_offset() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset) - return transmission_time_offset_; -} -inline void IncomingRtpPackets::set_transmission_time_offset(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x08000000u; - transmission_time_offset_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset) -} - -// optional uint32 absolute_send_time = 17; -inline bool IncomingRtpPackets::has_absolute_send_time() const { - return (_has_bits_[0] & 0x10000000u) != 0; -} -inline void IncomingRtpPackets::clear_absolute_send_time() { - absolute_send_time_ = 0u; - _has_bits_[0] &= ~0x10000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::absolute_send_time() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time) - return absolute_send_time_; -} -inline void IncomingRtpPackets::set_absolute_send_time(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x10000000u; - absolute_send_time_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time) -} - -// optional uint32 video_rotation = 18; -inline bool IncomingRtpPackets::has_video_rotation() const { - return (_has_bits_[0] & 0x20000000u) != 0; -} -inline void IncomingRtpPackets::clear_video_rotation() { - video_rotation_ = 0u; - _has_bits_[0] &= ~0x20000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::video_rotation() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.video_rotation) - return video_rotation_; -} -inline void IncomingRtpPackets::set_video_rotation(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x20000000u; - video_rotation_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.video_rotation) -} - -// optional uint32 audio_level = 19; -inline bool IncomingRtpPackets::has_audio_level() const { - return (_has_bits_[0] & 0x40000000u) != 0; -} -inline void IncomingRtpPackets::clear_audio_level() { - audio_level_ = 0u; - _has_bits_[0] &= ~0x40000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtpPackets::audio_level() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.audio_level) - return audio_level_; -} -inline void IncomingRtpPackets::set_audio_level(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x40000000u; - audio_level_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.audio_level) -} - -// optional bool voice_activity = 20; -inline bool IncomingRtpPackets::has_voice_activity() const { - return (_has_bits_[0] & 0x02000000u) != 0; -} -inline void IncomingRtpPackets::clear_voice_activity() { - voice_activity_ = false; - _has_bits_[0] &= ~0x02000000u; -} -inline bool IncomingRtpPackets::voice_activity() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.voice_activity) - return voice_activity_; -} -inline void IncomingRtpPackets::set_voice_activity(bool value) { - _has_bits_[0] |= 0x02000000u; - voice_activity_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.voice_activity) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool IncomingRtpPackets::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void IncomingRtpPackets::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& IncomingRtpPackets::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms_deltas) -} -inline void IncomingRtpPackets::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms_deltas) -} -inline void IncomingRtpPackets::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms_deltas) -} -inline void IncomingRtpPackets::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms_deltas) -} -inline std::string* IncomingRtpPackets::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.timestamp_ms_deltas) -} - -// optional bytes marker_deltas = 102; -inline bool IncomingRtpPackets::has_marker_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void IncomingRtpPackets::clear_marker_deltas() { - marker_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& IncomingRtpPackets::marker_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.marker_deltas) - return marker_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_marker_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - marker_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.marker_deltas) -} -inline void IncomingRtpPackets::set_marker_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - marker_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.marker_deltas) -} -inline void IncomingRtpPackets::set_marker_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - marker_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.marker_deltas) -} -inline void IncomingRtpPackets::set_marker_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - marker_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.marker_deltas) -} -inline std::string* IncomingRtpPackets::mutable_marker_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.marker_deltas) - return marker_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_marker_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.marker_deltas) - if (!has_marker_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return marker_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_marker_deltas(std::string* marker_deltas) { - if (marker_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - marker_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), marker_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.marker_deltas) -} - -// optional bytes payload_type_deltas = 103; -inline bool IncomingRtpPackets::has_payload_type_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void IncomingRtpPackets::clear_payload_type_deltas() { - payload_type_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& IncomingRtpPackets::payload_type_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.payload_type_deltas) - return payload_type_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_payload_type_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.payload_type_deltas) -} -inline void IncomingRtpPackets::set_payload_type_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.payload_type_deltas) -} -inline void IncomingRtpPackets::set_payload_type_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.payload_type_deltas) -} -inline void IncomingRtpPackets::set_payload_type_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.payload_type_deltas) -} -inline std::string* IncomingRtpPackets::mutable_payload_type_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.payload_type_deltas) - return payload_type_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_payload_type_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.payload_type_deltas) - if (!has_payload_type_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return payload_type_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_payload_type_deltas(std::string* payload_type_deltas) { - if (payload_type_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - payload_type_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), payload_type_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.payload_type_deltas) -} - -// optional bytes sequence_number_deltas = 104; -inline bool IncomingRtpPackets::has_sequence_number_deltas() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void IncomingRtpPackets::clear_sequence_number_deltas() { - sequence_number_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000008u; -} -inline const std::string& IncomingRtpPackets::sequence_number_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.sequence_number_deltas) - return sequence_number_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_sequence_number_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.sequence_number_deltas) -} -inline void IncomingRtpPackets::set_sequence_number_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.sequence_number_deltas) -} -inline void IncomingRtpPackets::set_sequence_number_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.sequence_number_deltas) -} -inline void IncomingRtpPackets::set_sequence_number_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.sequence_number_deltas) -} -inline std::string* IncomingRtpPackets::mutable_sequence_number_deltas() { - _has_bits_[0] |= 0x00000008u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.sequence_number_deltas) - return sequence_number_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_sequence_number_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.sequence_number_deltas) - if (!has_sequence_number_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000008u; - return sequence_number_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_sequence_number_deltas(std::string* sequence_number_deltas) { - if (sequence_number_deltas != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - sequence_number_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), sequence_number_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.sequence_number_deltas) -} - -// optional bytes rtp_timestamp_deltas = 105; -inline bool IncomingRtpPackets::has_rtp_timestamp_deltas() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void IncomingRtpPackets::clear_rtp_timestamp_deltas() { - rtp_timestamp_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000010u; -} -inline const std::string& IncomingRtpPackets::rtp_timestamp_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp_deltas) - return rtp_timestamp_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_rtp_timestamp_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp_deltas) -} -inline void IncomingRtpPackets::set_rtp_timestamp_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp_deltas) -} -inline void IncomingRtpPackets::set_rtp_timestamp_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp_deltas) -} -inline void IncomingRtpPackets::set_rtp_timestamp_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp_deltas) -} -inline std::string* IncomingRtpPackets::mutable_rtp_timestamp_deltas() { - _has_bits_[0] |= 0x00000010u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp_deltas) - return rtp_timestamp_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_rtp_timestamp_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp_deltas) - if (!has_rtp_timestamp_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000010u; - return rtp_timestamp_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_rtp_timestamp_deltas(std::string* rtp_timestamp_deltas) { - if (rtp_timestamp_deltas != nullptr) { - _has_bits_[0] |= 0x00000010u; - } else { - _has_bits_[0] &= ~0x00000010u; - } - rtp_timestamp_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), rtp_timestamp_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.rtp_timestamp_deltas) -} - -// optional bytes ssrc_deltas = 106; -inline bool IncomingRtpPackets::has_ssrc_deltas() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void IncomingRtpPackets::clear_ssrc_deltas() { - ssrc_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000020u; -} -inline const std::string& IncomingRtpPackets::ssrc_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.ssrc_deltas) - return ssrc_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_ssrc_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.ssrc_deltas) -} -inline void IncomingRtpPackets::set_ssrc_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.ssrc_deltas) -} -inline void IncomingRtpPackets::set_ssrc_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.ssrc_deltas) -} -inline void IncomingRtpPackets::set_ssrc_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.ssrc_deltas) -} -inline std::string* IncomingRtpPackets::mutable_ssrc_deltas() { - _has_bits_[0] |= 0x00000020u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.ssrc_deltas) - return ssrc_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_ssrc_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.ssrc_deltas) - if (!has_ssrc_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000020u; - return ssrc_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_ssrc_deltas(std::string* ssrc_deltas) { - if (ssrc_deltas != nullptr) { - _has_bits_[0] |= 0x00000020u; - } else { - _has_bits_[0] &= ~0x00000020u; - } - ssrc_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ssrc_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.ssrc_deltas) -} - -// optional bytes payload_size_deltas = 108; -inline bool IncomingRtpPackets::has_payload_size_deltas() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void IncomingRtpPackets::clear_payload_size_deltas() { - payload_size_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000040u; -} -inline const std::string& IncomingRtpPackets::payload_size_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.payload_size_deltas) - return payload_size_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_payload_size_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.payload_size_deltas) -} -inline void IncomingRtpPackets::set_payload_size_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.payload_size_deltas) -} -inline void IncomingRtpPackets::set_payload_size_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.payload_size_deltas) -} -inline void IncomingRtpPackets::set_payload_size_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.payload_size_deltas) -} -inline std::string* IncomingRtpPackets::mutable_payload_size_deltas() { - _has_bits_[0] |= 0x00000040u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.payload_size_deltas) - return payload_size_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_payload_size_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.payload_size_deltas) - if (!has_payload_size_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000040u; - return payload_size_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_payload_size_deltas(std::string* payload_size_deltas) { - if (payload_size_deltas != nullptr) { - _has_bits_[0] |= 0x00000040u; - } else { - _has_bits_[0] &= ~0x00000040u; - } - payload_size_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), payload_size_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.payload_size_deltas) -} - -// optional bytes header_size_deltas = 109; -inline bool IncomingRtpPackets::has_header_size_deltas() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void IncomingRtpPackets::clear_header_size_deltas() { - header_size_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000080u; -} -inline const std::string& IncomingRtpPackets::header_size_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.header_size_deltas) - return header_size_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_header_size_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.header_size_deltas) -} -inline void IncomingRtpPackets::set_header_size_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.header_size_deltas) -} -inline void IncomingRtpPackets::set_header_size_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.header_size_deltas) -} -inline void IncomingRtpPackets::set_header_size_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.header_size_deltas) -} -inline std::string* IncomingRtpPackets::mutable_header_size_deltas() { - _has_bits_[0] |= 0x00000080u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.header_size_deltas) - return header_size_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_header_size_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.header_size_deltas) - if (!has_header_size_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000080u; - return header_size_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_header_size_deltas(std::string* header_size_deltas) { - if (header_size_deltas != nullptr) { - _has_bits_[0] |= 0x00000080u; - } else { - _has_bits_[0] &= ~0x00000080u; - } - header_size_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), header_size_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.header_size_deltas) -} - -// optional bytes padding_size_deltas = 110; -inline bool IncomingRtpPackets::has_padding_size_deltas() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void IncomingRtpPackets::clear_padding_size_deltas() { - padding_size_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000100u; -} -inline const std::string& IncomingRtpPackets::padding_size_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.padding_size_deltas) - return padding_size_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_padding_size_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.padding_size_deltas) -} -inline void IncomingRtpPackets::set_padding_size_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.padding_size_deltas) -} -inline void IncomingRtpPackets::set_padding_size_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.padding_size_deltas) -} -inline void IncomingRtpPackets::set_padding_size_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.padding_size_deltas) -} -inline std::string* IncomingRtpPackets::mutable_padding_size_deltas() { - _has_bits_[0] |= 0x00000100u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.padding_size_deltas) - return padding_size_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_padding_size_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.padding_size_deltas) - if (!has_padding_size_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000100u; - return padding_size_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_padding_size_deltas(std::string* padding_size_deltas) { - if (padding_size_deltas != nullptr) { - _has_bits_[0] |= 0x00000100u; - } else { - _has_bits_[0] &= ~0x00000100u; - } - padding_size_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), padding_size_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.padding_size_deltas) -} - -// optional bytes transport_sequence_number_deltas = 115; -inline bool IncomingRtpPackets::has_transport_sequence_number_deltas() const { - return (_has_bits_[0] & 0x00000200u) != 0; -} -inline void IncomingRtpPackets::clear_transport_sequence_number_deltas() { - transport_sequence_number_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000200u; -} -inline const std::string& IncomingRtpPackets::transport_sequence_number_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number_deltas) - return transport_sequence_number_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_transport_sequence_number_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number_deltas) -} -inline void IncomingRtpPackets::set_transport_sequence_number_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number_deltas) -} -inline void IncomingRtpPackets::set_transport_sequence_number_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number_deltas) -} -inline void IncomingRtpPackets::set_transport_sequence_number_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number_deltas) -} -inline std::string* IncomingRtpPackets::mutable_transport_sequence_number_deltas() { - _has_bits_[0] |= 0x00000200u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number_deltas) - return transport_sequence_number_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_transport_sequence_number_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number_deltas) - if (!has_transport_sequence_number_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000200u; - return transport_sequence_number_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_transport_sequence_number_deltas(std::string* transport_sequence_number_deltas) { - if (transport_sequence_number_deltas != nullptr) { - _has_bits_[0] |= 0x00000200u; - } else { - _has_bits_[0] &= ~0x00000200u; - } - transport_sequence_number_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), transport_sequence_number_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.transport_sequence_number_deltas) -} - -// optional bytes transmission_time_offset_deltas = 116; -inline bool IncomingRtpPackets::has_transmission_time_offset_deltas() const { - return (_has_bits_[0] & 0x00000400u) != 0; -} -inline void IncomingRtpPackets::clear_transmission_time_offset_deltas() { - transmission_time_offset_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000400u; -} -inline const std::string& IncomingRtpPackets::transmission_time_offset_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset_deltas) - return transmission_time_offset_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_transmission_time_offset_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset_deltas) -} -inline void IncomingRtpPackets::set_transmission_time_offset_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset_deltas) -} -inline void IncomingRtpPackets::set_transmission_time_offset_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset_deltas) -} -inline void IncomingRtpPackets::set_transmission_time_offset_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset_deltas) -} -inline std::string* IncomingRtpPackets::mutable_transmission_time_offset_deltas() { - _has_bits_[0] |= 0x00000400u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset_deltas) - return transmission_time_offset_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_transmission_time_offset_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset_deltas) - if (!has_transmission_time_offset_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000400u; - return transmission_time_offset_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_transmission_time_offset_deltas(std::string* transmission_time_offset_deltas) { - if (transmission_time_offset_deltas != nullptr) { - _has_bits_[0] |= 0x00000400u; - } else { - _has_bits_[0] &= ~0x00000400u; - } - transmission_time_offset_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), transmission_time_offset_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.transmission_time_offset_deltas) -} - -// optional bytes absolute_send_time_deltas = 117; -inline bool IncomingRtpPackets::has_absolute_send_time_deltas() const { - return (_has_bits_[0] & 0x00000800u) != 0; -} -inline void IncomingRtpPackets::clear_absolute_send_time_deltas() { - absolute_send_time_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000800u; -} -inline const std::string& IncomingRtpPackets::absolute_send_time_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time_deltas) - return absolute_send_time_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_absolute_send_time_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time_deltas) -} -inline void IncomingRtpPackets::set_absolute_send_time_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time_deltas) -} -inline void IncomingRtpPackets::set_absolute_send_time_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time_deltas) -} -inline void IncomingRtpPackets::set_absolute_send_time_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time_deltas) -} -inline std::string* IncomingRtpPackets::mutable_absolute_send_time_deltas() { - _has_bits_[0] |= 0x00000800u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time_deltas) - return absolute_send_time_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_absolute_send_time_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time_deltas) - if (!has_absolute_send_time_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000800u; - return absolute_send_time_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_absolute_send_time_deltas(std::string* absolute_send_time_deltas) { - if (absolute_send_time_deltas != nullptr) { - _has_bits_[0] |= 0x00000800u; - } else { - _has_bits_[0] &= ~0x00000800u; - } - absolute_send_time_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), absolute_send_time_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.absolute_send_time_deltas) -} - -// optional bytes video_rotation_deltas = 118; -inline bool IncomingRtpPackets::has_video_rotation_deltas() const { - return (_has_bits_[0] & 0x00001000u) != 0; -} -inline void IncomingRtpPackets::clear_video_rotation_deltas() { - video_rotation_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00001000u; -} -inline const std::string& IncomingRtpPackets::video_rotation_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.video_rotation_deltas) - return video_rotation_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_video_rotation_deltas(const std::string& value) { - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.video_rotation_deltas) -} -inline void IncomingRtpPackets::set_video_rotation_deltas(std::string&& value) { - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.video_rotation_deltas) -} -inline void IncomingRtpPackets::set_video_rotation_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.video_rotation_deltas) -} -inline void IncomingRtpPackets::set_video_rotation_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.video_rotation_deltas) -} -inline std::string* IncomingRtpPackets::mutable_video_rotation_deltas() { - _has_bits_[0] |= 0x00001000u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.video_rotation_deltas) - return video_rotation_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_video_rotation_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.video_rotation_deltas) - if (!has_video_rotation_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00001000u; - return video_rotation_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_video_rotation_deltas(std::string* video_rotation_deltas) { - if (video_rotation_deltas != nullptr) { - _has_bits_[0] |= 0x00001000u; - } else { - _has_bits_[0] &= ~0x00001000u; - } - video_rotation_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), video_rotation_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.video_rotation_deltas) -} - -// optional bytes audio_level_deltas = 119; -inline bool IncomingRtpPackets::has_audio_level_deltas() const { - return (_has_bits_[0] & 0x00002000u) != 0; -} -inline void IncomingRtpPackets::clear_audio_level_deltas() { - audio_level_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00002000u; -} -inline const std::string& IncomingRtpPackets::audio_level_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.audio_level_deltas) - return audio_level_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_audio_level_deltas(const std::string& value) { - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.audio_level_deltas) -} -inline void IncomingRtpPackets::set_audio_level_deltas(std::string&& value) { - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.audio_level_deltas) -} -inline void IncomingRtpPackets::set_audio_level_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.audio_level_deltas) -} -inline void IncomingRtpPackets::set_audio_level_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.audio_level_deltas) -} -inline std::string* IncomingRtpPackets::mutable_audio_level_deltas() { - _has_bits_[0] |= 0x00002000u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.audio_level_deltas) - return audio_level_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_audio_level_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.audio_level_deltas) - if (!has_audio_level_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00002000u; - return audio_level_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_audio_level_deltas(std::string* audio_level_deltas) { - if (audio_level_deltas != nullptr) { - _has_bits_[0] |= 0x00002000u; - } else { - _has_bits_[0] &= ~0x00002000u; - } - audio_level_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), audio_level_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.audio_level_deltas) -} - -// optional bytes voice_activity_deltas = 120; -inline bool IncomingRtpPackets::has_voice_activity_deltas() const { - return (_has_bits_[0] & 0x00004000u) != 0; -} -inline void IncomingRtpPackets::clear_voice_activity_deltas() { - voice_activity_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00004000u; -} -inline const std::string& IncomingRtpPackets::voice_activity_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtpPackets.voice_activity_deltas) - return voice_activity_deltas_.GetNoArena(); -} -inline void IncomingRtpPackets::set_voice_activity_deltas(const std::string& value) { - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtpPackets.voice_activity_deltas) -} -inline void IncomingRtpPackets::set_voice_activity_deltas(std::string&& value) { - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtpPackets.voice_activity_deltas) -} -inline void IncomingRtpPackets::set_voice_activity_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtpPackets.voice_activity_deltas) -} -inline void IncomingRtpPackets::set_voice_activity_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtpPackets.voice_activity_deltas) -} -inline std::string* IncomingRtpPackets::mutable_voice_activity_deltas() { - _has_bits_[0] |= 0x00004000u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtpPackets.voice_activity_deltas) - return voice_activity_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtpPackets::release_voice_activity_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtpPackets.voice_activity_deltas) - if (!has_voice_activity_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00004000u; - return voice_activity_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtpPackets::set_allocated_voice_activity_deltas(std::string* voice_activity_deltas) { - if (voice_activity_deltas != nullptr) { - _has_bits_[0] |= 0x00004000u; - } else { - _has_bits_[0] &= ~0x00004000u; - } - voice_activity_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), voice_activity_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtpPackets.voice_activity_deltas) -} - -// ------------------------------------------------------------------- - -// OutgoingRtpPackets - -// optional int64 timestamp_ms = 1; -inline bool OutgoingRtpPackets::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00008000u) != 0; -} -inline void OutgoingRtpPackets::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00008000u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 OutgoingRtpPackets::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms) - return timestamp_ms_; -} -inline void OutgoingRtpPackets::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00008000u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms) -} - -// optional bool marker = 2; -inline bool OutgoingRtpPackets::has_marker() const { - return (_has_bits_[0] & 0x01000000u) != 0; -} -inline void OutgoingRtpPackets::clear_marker() { - marker_ = false; - _has_bits_[0] &= ~0x01000000u; -} -inline bool OutgoingRtpPackets::marker() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.marker) - return marker_; -} -inline void OutgoingRtpPackets::set_marker(bool value) { - _has_bits_[0] |= 0x01000000u; - marker_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.marker) -} - -// optional uint32 payload_type = 3; -inline bool OutgoingRtpPackets::has_payload_type() const { - return (_has_bits_[0] & 0x00010000u) != 0; -} -inline void OutgoingRtpPackets::clear_payload_type() { - payload_type_ = 0u; - _has_bits_[0] &= ~0x00010000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::payload_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.payload_type) - return payload_type_; -} -inline void OutgoingRtpPackets::set_payload_type(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00010000u; - payload_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.payload_type) -} - -// optional uint32 sequence_number = 4; -inline bool OutgoingRtpPackets::has_sequence_number() const { - return (_has_bits_[0] & 0x00020000u) != 0; -} -inline void OutgoingRtpPackets::clear_sequence_number() { - sequence_number_ = 0u; - _has_bits_[0] &= ~0x00020000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::sequence_number() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.sequence_number) - return sequence_number_; -} -inline void OutgoingRtpPackets::set_sequence_number(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00020000u; - sequence_number_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.sequence_number) -} - -// optional fixed32 rtp_timestamp = 5; -inline bool OutgoingRtpPackets::has_rtp_timestamp() const { - return (_has_bits_[0] & 0x00040000u) != 0; -} -inline void OutgoingRtpPackets::clear_rtp_timestamp() { - rtp_timestamp_ = 0u; - _has_bits_[0] &= ~0x00040000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::rtp_timestamp() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp) - return rtp_timestamp_; -} -inline void OutgoingRtpPackets::set_rtp_timestamp(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00040000u; - rtp_timestamp_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp) -} - -// optional fixed32 ssrc = 6; -inline bool OutgoingRtpPackets::has_ssrc() const { - return (_has_bits_[0] & 0x00080000u) != 0; -} -inline void OutgoingRtpPackets::clear_ssrc() { - ssrc_ = 0u; - _has_bits_[0] &= ~0x00080000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.ssrc) - return ssrc_; -} -inline void OutgoingRtpPackets::set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00080000u; - ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.ssrc) -} - -// optional uint32 payload_size = 8; -inline bool OutgoingRtpPackets::has_payload_size() const { - return (_has_bits_[0] & 0x00100000u) != 0; -} -inline void OutgoingRtpPackets::clear_payload_size() { - payload_size_ = 0u; - _has_bits_[0] &= ~0x00100000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::payload_size() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.payload_size) - return payload_size_; -} -inline void OutgoingRtpPackets::set_payload_size(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00100000u; - payload_size_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.payload_size) -} - -// optional uint32 header_size = 9; -inline bool OutgoingRtpPackets::has_header_size() const { - return (_has_bits_[0] & 0x00200000u) != 0; -} -inline void OutgoingRtpPackets::clear_header_size() { - header_size_ = 0u; - _has_bits_[0] &= ~0x00200000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::header_size() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.header_size) - return header_size_; -} -inline void OutgoingRtpPackets::set_header_size(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00200000u; - header_size_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.header_size) -} - -// optional uint32 padding_size = 10; -inline bool OutgoingRtpPackets::has_padding_size() const { - return (_has_bits_[0] & 0x00400000u) != 0; -} -inline void OutgoingRtpPackets::clear_padding_size() { - padding_size_ = 0u; - _has_bits_[0] &= ~0x00400000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::padding_size() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.padding_size) - return padding_size_; -} -inline void OutgoingRtpPackets::set_padding_size(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00400000u; - padding_size_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.padding_size) -} - -// optional uint32 number_of_deltas = 11; -inline bool OutgoingRtpPackets::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00800000u) != 0; -} -inline void OutgoingRtpPackets::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00800000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.number_of_deltas) - return number_of_deltas_; -} -inline void OutgoingRtpPackets::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00800000u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.number_of_deltas) -} - -// optional uint32 transport_sequence_number = 15; -inline bool OutgoingRtpPackets::has_transport_sequence_number() const { - return (_has_bits_[0] & 0x04000000u) != 0; -} -inline void OutgoingRtpPackets::clear_transport_sequence_number() { - transport_sequence_number_ = 0u; - _has_bits_[0] &= ~0x04000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::transport_sequence_number() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number) - return transport_sequence_number_; -} -inline void OutgoingRtpPackets::set_transport_sequence_number(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x04000000u; - transport_sequence_number_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number) -} - -// optional int32 transmission_time_offset = 16; -inline bool OutgoingRtpPackets::has_transmission_time_offset() const { - return (_has_bits_[0] & 0x08000000u) != 0; -} -inline void OutgoingRtpPackets::clear_transmission_time_offset() { - transmission_time_offset_ = 0; - _has_bits_[0] &= ~0x08000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 OutgoingRtpPackets::transmission_time_offset() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset) - return transmission_time_offset_; -} -inline void OutgoingRtpPackets::set_transmission_time_offset(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x08000000u; - transmission_time_offset_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset) -} - -// optional uint32 absolute_send_time = 17; -inline bool OutgoingRtpPackets::has_absolute_send_time() const { - return (_has_bits_[0] & 0x10000000u) != 0; -} -inline void OutgoingRtpPackets::clear_absolute_send_time() { - absolute_send_time_ = 0u; - _has_bits_[0] &= ~0x10000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::absolute_send_time() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time) - return absolute_send_time_; -} -inline void OutgoingRtpPackets::set_absolute_send_time(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x10000000u; - absolute_send_time_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time) -} - -// optional uint32 video_rotation = 18; -inline bool OutgoingRtpPackets::has_video_rotation() const { - return (_has_bits_[0] & 0x20000000u) != 0; -} -inline void OutgoingRtpPackets::clear_video_rotation() { - video_rotation_ = 0u; - _has_bits_[0] &= ~0x20000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::video_rotation() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.video_rotation) - return video_rotation_; -} -inline void OutgoingRtpPackets::set_video_rotation(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x20000000u; - video_rotation_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.video_rotation) -} - -// optional uint32 audio_level = 19; -inline bool OutgoingRtpPackets::has_audio_level() const { - return (_has_bits_[0] & 0x40000000u) != 0; -} -inline void OutgoingRtpPackets::clear_audio_level() { - audio_level_ = 0u; - _has_bits_[0] &= ~0x40000000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtpPackets::audio_level() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.audio_level) - return audio_level_; -} -inline void OutgoingRtpPackets::set_audio_level(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x40000000u; - audio_level_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.audio_level) -} - -// optional bool voice_activity = 20; -inline bool OutgoingRtpPackets::has_voice_activity() const { - return (_has_bits_[0] & 0x02000000u) != 0; -} -inline void OutgoingRtpPackets::clear_voice_activity() { - voice_activity_ = false; - _has_bits_[0] &= ~0x02000000u; -} -inline bool OutgoingRtpPackets::voice_activity() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.voice_activity) - return voice_activity_; -} -inline void OutgoingRtpPackets::set_voice_activity(bool value) { - _has_bits_[0] |= 0x02000000u; - voice_activity_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.voice_activity) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool OutgoingRtpPackets::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void OutgoingRtpPackets::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& OutgoingRtpPackets::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms_deltas) -} -inline void OutgoingRtpPackets::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms_deltas) -} -inline void OutgoingRtpPackets::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms_deltas) -} -inline void OutgoingRtpPackets::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.timestamp_ms_deltas) -} - -// optional bytes marker_deltas = 102; -inline bool OutgoingRtpPackets::has_marker_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void OutgoingRtpPackets::clear_marker_deltas() { - marker_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& OutgoingRtpPackets::marker_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.marker_deltas) - return marker_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_marker_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - marker_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.marker_deltas) -} -inline void OutgoingRtpPackets::set_marker_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - marker_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.marker_deltas) -} -inline void OutgoingRtpPackets::set_marker_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - marker_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.marker_deltas) -} -inline void OutgoingRtpPackets::set_marker_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - marker_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.marker_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_marker_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.marker_deltas) - return marker_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_marker_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.marker_deltas) - if (!has_marker_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return marker_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_marker_deltas(std::string* marker_deltas) { - if (marker_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - marker_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), marker_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.marker_deltas) -} - -// optional bytes payload_type_deltas = 103; -inline bool OutgoingRtpPackets::has_payload_type_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void OutgoingRtpPackets::clear_payload_type_deltas() { - payload_type_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& OutgoingRtpPackets::payload_type_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.payload_type_deltas) - return payload_type_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_payload_type_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.payload_type_deltas) -} -inline void OutgoingRtpPackets::set_payload_type_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.payload_type_deltas) -} -inline void OutgoingRtpPackets::set_payload_type_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.payload_type_deltas) -} -inline void OutgoingRtpPackets::set_payload_type_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - payload_type_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.payload_type_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_payload_type_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.payload_type_deltas) - return payload_type_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_payload_type_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.payload_type_deltas) - if (!has_payload_type_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return payload_type_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_payload_type_deltas(std::string* payload_type_deltas) { - if (payload_type_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - payload_type_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), payload_type_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.payload_type_deltas) -} - -// optional bytes sequence_number_deltas = 104; -inline bool OutgoingRtpPackets::has_sequence_number_deltas() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void OutgoingRtpPackets::clear_sequence_number_deltas() { - sequence_number_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000008u; -} -inline const std::string& OutgoingRtpPackets::sequence_number_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.sequence_number_deltas) - return sequence_number_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_sequence_number_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.sequence_number_deltas) -} -inline void OutgoingRtpPackets::set_sequence_number_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.sequence_number_deltas) -} -inline void OutgoingRtpPackets::set_sequence_number_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.sequence_number_deltas) -} -inline void OutgoingRtpPackets::set_sequence_number_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000008u; - sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.sequence_number_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_sequence_number_deltas() { - _has_bits_[0] |= 0x00000008u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.sequence_number_deltas) - return sequence_number_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_sequence_number_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.sequence_number_deltas) - if (!has_sequence_number_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000008u; - return sequence_number_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_sequence_number_deltas(std::string* sequence_number_deltas) { - if (sequence_number_deltas != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - sequence_number_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), sequence_number_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.sequence_number_deltas) -} - -// optional bytes rtp_timestamp_deltas = 105; -inline bool OutgoingRtpPackets::has_rtp_timestamp_deltas() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void OutgoingRtpPackets::clear_rtp_timestamp_deltas() { - rtp_timestamp_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000010u; -} -inline const std::string& OutgoingRtpPackets::rtp_timestamp_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp_deltas) - return rtp_timestamp_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_rtp_timestamp_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp_deltas) -} -inline void OutgoingRtpPackets::set_rtp_timestamp_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp_deltas) -} -inline void OutgoingRtpPackets::set_rtp_timestamp_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp_deltas) -} -inline void OutgoingRtpPackets::set_rtp_timestamp_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000010u; - rtp_timestamp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_rtp_timestamp_deltas() { - _has_bits_[0] |= 0x00000010u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp_deltas) - return rtp_timestamp_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_rtp_timestamp_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp_deltas) - if (!has_rtp_timestamp_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000010u; - return rtp_timestamp_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_rtp_timestamp_deltas(std::string* rtp_timestamp_deltas) { - if (rtp_timestamp_deltas != nullptr) { - _has_bits_[0] |= 0x00000010u; - } else { - _has_bits_[0] &= ~0x00000010u; - } - rtp_timestamp_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), rtp_timestamp_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.rtp_timestamp_deltas) -} - -// optional bytes ssrc_deltas = 106; -inline bool OutgoingRtpPackets::has_ssrc_deltas() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void OutgoingRtpPackets::clear_ssrc_deltas() { - ssrc_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000020u; -} -inline const std::string& OutgoingRtpPackets::ssrc_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.ssrc_deltas) - return ssrc_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_ssrc_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.ssrc_deltas) -} -inline void OutgoingRtpPackets::set_ssrc_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.ssrc_deltas) -} -inline void OutgoingRtpPackets::set_ssrc_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.ssrc_deltas) -} -inline void OutgoingRtpPackets::set_ssrc_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000020u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.ssrc_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_ssrc_deltas() { - _has_bits_[0] |= 0x00000020u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.ssrc_deltas) - return ssrc_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_ssrc_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.ssrc_deltas) - if (!has_ssrc_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000020u; - return ssrc_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_ssrc_deltas(std::string* ssrc_deltas) { - if (ssrc_deltas != nullptr) { - _has_bits_[0] |= 0x00000020u; - } else { - _has_bits_[0] &= ~0x00000020u; - } - ssrc_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ssrc_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.ssrc_deltas) -} - -// optional bytes payload_size_deltas = 108; -inline bool OutgoingRtpPackets::has_payload_size_deltas() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void OutgoingRtpPackets::clear_payload_size_deltas() { - payload_size_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000040u; -} -inline const std::string& OutgoingRtpPackets::payload_size_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.payload_size_deltas) - return payload_size_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_payload_size_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.payload_size_deltas) -} -inline void OutgoingRtpPackets::set_payload_size_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.payload_size_deltas) -} -inline void OutgoingRtpPackets::set_payload_size_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.payload_size_deltas) -} -inline void OutgoingRtpPackets::set_payload_size_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000040u; - payload_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.payload_size_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_payload_size_deltas() { - _has_bits_[0] |= 0x00000040u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.payload_size_deltas) - return payload_size_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_payload_size_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.payload_size_deltas) - if (!has_payload_size_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000040u; - return payload_size_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_payload_size_deltas(std::string* payload_size_deltas) { - if (payload_size_deltas != nullptr) { - _has_bits_[0] |= 0x00000040u; - } else { - _has_bits_[0] &= ~0x00000040u; - } - payload_size_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), payload_size_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.payload_size_deltas) -} - -// optional bytes header_size_deltas = 109; -inline bool OutgoingRtpPackets::has_header_size_deltas() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void OutgoingRtpPackets::clear_header_size_deltas() { - header_size_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000080u; -} -inline const std::string& OutgoingRtpPackets::header_size_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.header_size_deltas) - return header_size_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_header_size_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.header_size_deltas) -} -inline void OutgoingRtpPackets::set_header_size_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.header_size_deltas) -} -inline void OutgoingRtpPackets::set_header_size_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.header_size_deltas) -} -inline void OutgoingRtpPackets::set_header_size_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000080u; - header_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.header_size_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_header_size_deltas() { - _has_bits_[0] |= 0x00000080u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.header_size_deltas) - return header_size_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_header_size_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.header_size_deltas) - if (!has_header_size_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000080u; - return header_size_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_header_size_deltas(std::string* header_size_deltas) { - if (header_size_deltas != nullptr) { - _has_bits_[0] |= 0x00000080u; - } else { - _has_bits_[0] &= ~0x00000080u; - } - header_size_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), header_size_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.header_size_deltas) -} - -// optional bytes padding_size_deltas = 110; -inline bool OutgoingRtpPackets::has_padding_size_deltas() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void OutgoingRtpPackets::clear_padding_size_deltas() { - padding_size_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000100u; -} -inline const std::string& OutgoingRtpPackets::padding_size_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.padding_size_deltas) - return padding_size_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_padding_size_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.padding_size_deltas) -} -inline void OutgoingRtpPackets::set_padding_size_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.padding_size_deltas) -} -inline void OutgoingRtpPackets::set_padding_size_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.padding_size_deltas) -} -inline void OutgoingRtpPackets::set_padding_size_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000100u; - padding_size_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.padding_size_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_padding_size_deltas() { - _has_bits_[0] |= 0x00000100u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.padding_size_deltas) - return padding_size_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_padding_size_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.padding_size_deltas) - if (!has_padding_size_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000100u; - return padding_size_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_padding_size_deltas(std::string* padding_size_deltas) { - if (padding_size_deltas != nullptr) { - _has_bits_[0] |= 0x00000100u; - } else { - _has_bits_[0] &= ~0x00000100u; - } - padding_size_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), padding_size_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.padding_size_deltas) -} - -// optional bytes transport_sequence_number_deltas = 115; -inline bool OutgoingRtpPackets::has_transport_sequence_number_deltas() const { - return (_has_bits_[0] & 0x00000200u) != 0; -} -inline void OutgoingRtpPackets::clear_transport_sequence_number_deltas() { - transport_sequence_number_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000200u; -} -inline const std::string& OutgoingRtpPackets::transport_sequence_number_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number_deltas) - return transport_sequence_number_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_transport_sequence_number_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number_deltas) -} -inline void OutgoingRtpPackets::set_transport_sequence_number_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number_deltas) -} -inline void OutgoingRtpPackets::set_transport_sequence_number_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number_deltas) -} -inline void OutgoingRtpPackets::set_transport_sequence_number_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000200u; - transport_sequence_number_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_transport_sequence_number_deltas() { - _has_bits_[0] |= 0x00000200u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number_deltas) - return transport_sequence_number_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_transport_sequence_number_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number_deltas) - if (!has_transport_sequence_number_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000200u; - return transport_sequence_number_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_transport_sequence_number_deltas(std::string* transport_sequence_number_deltas) { - if (transport_sequence_number_deltas != nullptr) { - _has_bits_[0] |= 0x00000200u; - } else { - _has_bits_[0] &= ~0x00000200u; - } - transport_sequence_number_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), transport_sequence_number_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.transport_sequence_number_deltas) -} - -// optional bytes transmission_time_offset_deltas = 116; -inline bool OutgoingRtpPackets::has_transmission_time_offset_deltas() const { - return (_has_bits_[0] & 0x00000400u) != 0; -} -inline void OutgoingRtpPackets::clear_transmission_time_offset_deltas() { - transmission_time_offset_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000400u; -} -inline const std::string& OutgoingRtpPackets::transmission_time_offset_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset_deltas) - return transmission_time_offset_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_transmission_time_offset_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset_deltas) -} -inline void OutgoingRtpPackets::set_transmission_time_offset_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset_deltas) -} -inline void OutgoingRtpPackets::set_transmission_time_offset_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset_deltas) -} -inline void OutgoingRtpPackets::set_transmission_time_offset_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000400u; - transmission_time_offset_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_transmission_time_offset_deltas() { - _has_bits_[0] |= 0x00000400u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset_deltas) - return transmission_time_offset_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_transmission_time_offset_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset_deltas) - if (!has_transmission_time_offset_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000400u; - return transmission_time_offset_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_transmission_time_offset_deltas(std::string* transmission_time_offset_deltas) { - if (transmission_time_offset_deltas != nullptr) { - _has_bits_[0] |= 0x00000400u; - } else { - _has_bits_[0] &= ~0x00000400u; - } - transmission_time_offset_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), transmission_time_offset_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.transmission_time_offset_deltas) -} - -// optional bytes absolute_send_time_deltas = 117; -inline bool OutgoingRtpPackets::has_absolute_send_time_deltas() const { - return (_has_bits_[0] & 0x00000800u) != 0; -} -inline void OutgoingRtpPackets::clear_absolute_send_time_deltas() { - absolute_send_time_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000800u; -} -inline const std::string& OutgoingRtpPackets::absolute_send_time_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time_deltas) - return absolute_send_time_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_absolute_send_time_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time_deltas) -} -inline void OutgoingRtpPackets::set_absolute_send_time_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time_deltas) -} -inline void OutgoingRtpPackets::set_absolute_send_time_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time_deltas) -} -inline void OutgoingRtpPackets::set_absolute_send_time_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000800u; - absolute_send_time_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_absolute_send_time_deltas() { - _has_bits_[0] |= 0x00000800u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time_deltas) - return absolute_send_time_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_absolute_send_time_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time_deltas) - if (!has_absolute_send_time_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000800u; - return absolute_send_time_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_absolute_send_time_deltas(std::string* absolute_send_time_deltas) { - if (absolute_send_time_deltas != nullptr) { - _has_bits_[0] |= 0x00000800u; - } else { - _has_bits_[0] &= ~0x00000800u; - } - absolute_send_time_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), absolute_send_time_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.absolute_send_time_deltas) -} - -// optional bytes video_rotation_deltas = 118; -inline bool OutgoingRtpPackets::has_video_rotation_deltas() const { - return (_has_bits_[0] & 0x00001000u) != 0; -} -inline void OutgoingRtpPackets::clear_video_rotation_deltas() { - video_rotation_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00001000u; -} -inline const std::string& OutgoingRtpPackets::video_rotation_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.video_rotation_deltas) - return video_rotation_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_video_rotation_deltas(const std::string& value) { - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.video_rotation_deltas) -} -inline void OutgoingRtpPackets::set_video_rotation_deltas(std::string&& value) { - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.video_rotation_deltas) -} -inline void OutgoingRtpPackets::set_video_rotation_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.video_rotation_deltas) -} -inline void OutgoingRtpPackets::set_video_rotation_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00001000u; - video_rotation_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.video_rotation_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_video_rotation_deltas() { - _has_bits_[0] |= 0x00001000u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.video_rotation_deltas) - return video_rotation_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_video_rotation_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.video_rotation_deltas) - if (!has_video_rotation_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00001000u; - return video_rotation_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_video_rotation_deltas(std::string* video_rotation_deltas) { - if (video_rotation_deltas != nullptr) { - _has_bits_[0] |= 0x00001000u; - } else { - _has_bits_[0] &= ~0x00001000u; - } - video_rotation_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), video_rotation_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.video_rotation_deltas) -} - -// optional bytes audio_level_deltas = 119; -inline bool OutgoingRtpPackets::has_audio_level_deltas() const { - return (_has_bits_[0] & 0x00002000u) != 0; -} -inline void OutgoingRtpPackets::clear_audio_level_deltas() { - audio_level_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00002000u; -} -inline const std::string& OutgoingRtpPackets::audio_level_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.audio_level_deltas) - return audio_level_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_audio_level_deltas(const std::string& value) { - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.audio_level_deltas) -} -inline void OutgoingRtpPackets::set_audio_level_deltas(std::string&& value) { - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.audio_level_deltas) -} -inline void OutgoingRtpPackets::set_audio_level_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.audio_level_deltas) -} -inline void OutgoingRtpPackets::set_audio_level_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00002000u; - audio_level_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.audio_level_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_audio_level_deltas() { - _has_bits_[0] |= 0x00002000u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.audio_level_deltas) - return audio_level_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_audio_level_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.audio_level_deltas) - if (!has_audio_level_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00002000u; - return audio_level_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_audio_level_deltas(std::string* audio_level_deltas) { - if (audio_level_deltas != nullptr) { - _has_bits_[0] |= 0x00002000u; - } else { - _has_bits_[0] &= ~0x00002000u; - } - audio_level_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), audio_level_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.audio_level_deltas) -} - -// optional bytes voice_activity_deltas = 120; -inline bool OutgoingRtpPackets::has_voice_activity_deltas() const { - return (_has_bits_[0] & 0x00004000u) != 0; -} -inline void OutgoingRtpPackets::clear_voice_activity_deltas() { - voice_activity_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00004000u; -} -inline const std::string& OutgoingRtpPackets::voice_activity_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtpPackets.voice_activity_deltas) - return voice_activity_deltas_.GetNoArena(); -} -inline void OutgoingRtpPackets::set_voice_activity_deltas(const std::string& value) { - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtpPackets.voice_activity_deltas) -} -inline void OutgoingRtpPackets::set_voice_activity_deltas(std::string&& value) { - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtpPackets.voice_activity_deltas) -} -inline void OutgoingRtpPackets::set_voice_activity_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtpPackets.voice_activity_deltas) -} -inline void OutgoingRtpPackets::set_voice_activity_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00004000u; - voice_activity_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtpPackets.voice_activity_deltas) -} -inline std::string* OutgoingRtpPackets::mutable_voice_activity_deltas() { - _has_bits_[0] |= 0x00004000u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtpPackets.voice_activity_deltas) - return voice_activity_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtpPackets::release_voice_activity_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtpPackets.voice_activity_deltas) - if (!has_voice_activity_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00004000u; - return voice_activity_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtpPackets::set_allocated_voice_activity_deltas(std::string* voice_activity_deltas) { - if (voice_activity_deltas != nullptr) { - _has_bits_[0] |= 0x00004000u; - } else { - _has_bits_[0] &= ~0x00004000u; - } - voice_activity_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), voice_activity_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtpPackets.voice_activity_deltas) -} - -// ------------------------------------------------------------------- - -// IncomingRtcpPackets - -// optional int64 timestamp_ms = 1; -inline bool IncomingRtcpPackets::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void IncomingRtcpPackets::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 IncomingRtcpPackets::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms) - return timestamp_ms_; -} -inline void IncomingRtcpPackets::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000008u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms) -} - -// optional bytes raw_packet = 2; -inline bool IncomingRtcpPackets::has_raw_packet() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void IncomingRtcpPackets::clear_raw_packet() { - raw_packet_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& IncomingRtcpPackets::raw_packet() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtcpPackets.raw_packet) - return raw_packet_.GetNoArena(); -} -inline void IncomingRtcpPackets::set_raw_packet(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - raw_packet_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtcpPackets.raw_packet) -} -inline void IncomingRtcpPackets::set_raw_packet(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - raw_packet_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtcpPackets.raw_packet) -} -inline void IncomingRtcpPackets::set_raw_packet(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - raw_packet_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtcpPackets.raw_packet) -} -inline void IncomingRtcpPackets::set_raw_packet(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - raw_packet_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtcpPackets.raw_packet) -} -inline std::string* IncomingRtcpPackets::mutable_raw_packet() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtcpPackets.raw_packet) - return raw_packet_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtcpPackets::release_raw_packet() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtcpPackets.raw_packet) - if (!has_raw_packet()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return raw_packet_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtcpPackets::set_allocated_raw_packet(std::string* raw_packet) { - if (raw_packet != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - raw_packet_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), raw_packet); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtcpPackets.raw_packet) -} - -// optional uint32 number_of_deltas = 3; -inline bool IncomingRtcpPackets::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void IncomingRtcpPackets::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IncomingRtcpPackets::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtcpPackets.number_of_deltas) - return number_of_deltas_; -} -inline void IncomingRtcpPackets::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000010u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtcpPackets.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool IncomingRtcpPackets::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void IncomingRtcpPackets::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& IncomingRtcpPackets::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void IncomingRtcpPackets::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms_deltas) -} -inline void IncomingRtcpPackets::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms_deltas) -} -inline void IncomingRtcpPackets::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms_deltas) -} -inline void IncomingRtcpPackets::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms_deltas) -} -inline std::string* IncomingRtcpPackets::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtcpPackets::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtcpPackets::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtcpPackets.timestamp_ms_deltas) -} - -// optional bytes raw_packet_blobs = 102; -inline bool IncomingRtcpPackets::has_raw_packet_blobs() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void IncomingRtcpPackets::clear_raw_packet_blobs() { - raw_packet_blobs_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& IncomingRtcpPackets::raw_packet_blobs() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IncomingRtcpPackets.raw_packet_blobs) - return raw_packet_blobs_.GetNoArena(); -} -inline void IncomingRtcpPackets::set_raw_packet_blobs(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IncomingRtcpPackets.raw_packet_blobs) -} -inline void IncomingRtcpPackets::set_raw_packet_blobs(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.IncomingRtcpPackets.raw_packet_blobs) -} -inline void IncomingRtcpPackets::set_raw_packet_blobs(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.IncomingRtcpPackets.raw_packet_blobs) -} -inline void IncomingRtcpPackets::set_raw_packet_blobs(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.IncomingRtcpPackets.raw_packet_blobs) -} -inline std::string* IncomingRtcpPackets::mutable_raw_packet_blobs() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.IncomingRtcpPackets.raw_packet_blobs) - return raw_packet_blobs_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* IncomingRtcpPackets::release_raw_packet_blobs() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.IncomingRtcpPackets.raw_packet_blobs) - if (!has_raw_packet_blobs()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return raw_packet_blobs_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void IncomingRtcpPackets::set_allocated_raw_packet_blobs(std::string* raw_packet_blobs) { - if (raw_packet_blobs != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - raw_packet_blobs_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), raw_packet_blobs); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.IncomingRtcpPackets.raw_packet_blobs) -} - -// ------------------------------------------------------------------- - -// OutgoingRtcpPackets - -// optional int64 timestamp_ms = 1; -inline bool OutgoingRtcpPackets::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void OutgoingRtcpPackets::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 OutgoingRtcpPackets::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms) - return timestamp_ms_; -} -inline void OutgoingRtcpPackets::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000008u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms) -} - -// optional bytes raw_packet = 2; -inline bool OutgoingRtcpPackets::has_raw_packet() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void OutgoingRtcpPackets::clear_raw_packet() { - raw_packet_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& OutgoingRtcpPackets::raw_packet() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet) - return raw_packet_.GetNoArena(); -} -inline void OutgoingRtcpPackets::set_raw_packet(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - raw_packet_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet) -} -inline void OutgoingRtcpPackets::set_raw_packet(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - raw_packet_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet) -} -inline void OutgoingRtcpPackets::set_raw_packet(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - raw_packet_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet) -} -inline void OutgoingRtcpPackets::set_raw_packet(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - raw_packet_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet) -} -inline std::string* OutgoingRtcpPackets::mutable_raw_packet() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet) - return raw_packet_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtcpPackets::release_raw_packet() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet) - if (!has_raw_packet()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return raw_packet_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtcpPackets::set_allocated_raw_packet(std::string* raw_packet) { - if (raw_packet != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - raw_packet_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), raw_packet); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet) -} - -// optional uint32 number_of_deltas = 3; -inline bool OutgoingRtcpPackets::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void OutgoingRtcpPackets::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 OutgoingRtcpPackets::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtcpPackets.number_of_deltas) - return number_of_deltas_; -} -inline void OutgoingRtcpPackets::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000010u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtcpPackets.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool OutgoingRtcpPackets::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void OutgoingRtcpPackets::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& OutgoingRtcpPackets::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void OutgoingRtcpPackets::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms_deltas) -} -inline void OutgoingRtcpPackets::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms_deltas) -} -inline void OutgoingRtcpPackets::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms_deltas) -} -inline void OutgoingRtcpPackets::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms_deltas) -} -inline std::string* OutgoingRtcpPackets::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtcpPackets::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtcpPackets::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtcpPackets.timestamp_ms_deltas) -} - -// optional bytes raw_packet_blobs = 102; -inline bool OutgoingRtcpPackets::has_raw_packet_blobs() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void OutgoingRtcpPackets::clear_raw_packet_blobs() { - raw_packet_blobs_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& OutgoingRtcpPackets::raw_packet_blobs() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet_blobs) - return raw_packet_blobs_.GetNoArena(); -} -inline void OutgoingRtcpPackets::set_raw_packet_blobs(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet_blobs) -} -inline void OutgoingRtcpPackets::set_raw_packet_blobs(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet_blobs) -} -inline void OutgoingRtcpPackets::set_raw_packet_blobs(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet_blobs) -} -inline void OutgoingRtcpPackets::set_raw_packet_blobs(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - raw_packet_blobs_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet_blobs) -} -inline std::string* OutgoingRtcpPackets::mutable_raw_packet_blobs() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet_blobs) - return raw_packet_blobs_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* OutgoingRtcpPackets::release_raw_packet_blobs() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet_blobs) - if (!has_raw_packet_blobs()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return raw_packet_blobs_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void OutgoingRtcpPackets::set_allocated_raw_packet_blobs(std::string* raw_packet_blobs) { - if (raw_packet_blobs != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - raw_packet_blobs_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), raw_packet_blobs); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.OutgoingRtcpPackets.raw_packet_blobs) -} - -// ------------------------------------------------------------------- - -// AudioPlayoutEvents - -// optional int64 timestamp_ms = 1; -inline bool AudioPlayoutEvents::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void AudioPlayoutEvents::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 AudioPlayoutEvents::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms) - return timestamp_ms_; -} -inline void AudioPlayoutEvents::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000004u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms) -} - -// optional uint32 local_ssrc = 2; -inline bool AudioPlayoutEvents::has_local_ssrc() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void AudioPlayoutEvents::clear_local_ssrc() { - local_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioPlayoutEvents::local_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc) - return local_ssrc_; -} -inline void AudioPlayoutEvents::set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000008u; - local_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc) -} - -// optional uint32 number_of_deltas = 3; -inline bool AudioPlayoutEvents::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void AudioPlayoutEvents::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioPlayoutEvents::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioPlayoutEvents.number_of_deltas) - return number_of_deltas_; -} -inline void AudioPlayoutEvents::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000010u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioPlayoutEvents.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool AudioPlayoutEvents::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AudioPlayoutEvents::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& AudioPlayoutEvents::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void AudioPlayoutEvents::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms_deltas) -} -inline void AudioPlayoutEvents::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms_deltas) -} -inline void AudioPlayoutEvents::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms_deltas) -} -inline void AudioPlayoutEvents::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms_deltas) -} -inline std::string* AudioPlayoutEvents::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioPlayoutEvents::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioPlayoutEvents::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioPlayoutEvents.timestamp_ms_deltas) -} - -// optional bytes local_ssrc_deltas = 102; -inline bool AudioPlayoutEvents::has_local_ssrc_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void AudioPlayoutEvents::clear_local_ssrc_deltas() { - local_ssrc_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& AudioPlayoutEvents::local_ssrc_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc_deltas) - return local_ssrc_deltas_.GetNoArena(); -} -inline void AudioPlayoutEvents::set_local_ssrc_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - local_ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc_deltas) -} -inline void AudioPlayoutEvents::set_local_ssrc_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - local_ssrc_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc_deltas) -} -inline void AudioPlayoutEvents::set_local_ssrc_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - local_ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc_deltas) -} -inline void AudioPlayoutEvents::set_local_ssrc_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - local_ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc_deltas) -} -inline std::string* AudioPlayoutEvents::mutable_local_ssrc_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc_deltas) - return local_ssrc_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioPlayoutEvents::release_local_ssrc_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc_deltas) - if (!has_local_ssrc_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return local_ssrc_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioPlayoutEvents::set_allocated_local_ssrc_deltas(std::string* local_ssrc_deltas) { - if (local_ssrc_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - local_ssrc_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), local_ssrc_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioPlayoutEvents.local_ssrc_deltas) -} - -// ------------------------------------------------------------------- - -// FrameDecodedEvents - -// optional int64 timestamp_ms = 1; -inline bool FrameDecodedEvents::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void FrameDecodedEvents::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000080u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 FrameDecodedEvents::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms) - return timestamp_ms_; -} -inline void FrameDecodedEvents::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000080u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms) -} - -// optional fixed32 ssrc = 2; -inline bool FrameDecodedEvents::has_ssrc() const { - return (_has_bits_[0] & 0x00000200u) != 0; -} -inline void FrameDecodedEvents::clear_ssrc() { - ssrc_ = 0u; - _has_bits_[0] &= ~0x00000200u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 FrameDecodedEvents::ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.ssrc) - return ssrc_; -} -inline void FrameDecodedEvents::set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000200u; - ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.ssrc) -} - -// optional int64 render_time_ms = 3; -inline bool FrameDecodedEvents::has_render_time_ms() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void FrameDecodedEvents::clear_render_time_ms() { - render_time_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000100u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 FrameDecodedEvents::render_time_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.render_time_ms) - return render_time_ms_; -} -inline void FrameDecodedEvents::set_render_time_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000100u; - render_time_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.render_time_ms) -} - -// optional int32 width = 4; -inline bool FrameDecodedEvents::has_width() const { - return (_has_bits_[0] & 0x00000400u) != 0; -} -inline void FrameDecodedEvents::clear_width() { - width_ = 0; - _has_bits_[0] &= ~0x00000400u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 FrameDecodedEvents::width() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.width) - return width_; -} -inline void FrameDecodedEvents::set_width(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000400u; - width_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.width) -} - -// optional int32 height = 5; -inline bool FrameDecodedEvents::has_height() const { - return (_has_bits_[0] & 0x00000800u) != 0; -} -inline void FrameDecodedEvents::clear_height() { - height_ = 0; - _has_bits_[0] &= ~0x00000800u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 FrameDecodedEvents::height() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.height) - return height_; -} -inline void FrameDecodedEvents::set_height(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000800u; - height_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.height) -} - -// optional .webrtc.rtclog2.FrameDecodedEvents.Codec codec = 6; -inline bool FrameDecodedEvents::has_codec() const { - return (_has_bits_[0] & 0x00001000u) != 0; -} -inline void FrameDecodedEvents::clear_codec() { - codec_ = 0; - _has_bits_[0] &= ~0x00001000u; -} -inline ::webrtc::rtclog2::FrameDecodedEvents_Codec FrameDecodedEvents::codec() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.codec) - return static_cast< ::webrtc::rtclog2::FrameDecodedEvents_Codec >(codec_); -} -inline void FrameDecodedEvents::set_codec(::webrtc::rtclog2::FrameDecodedEvents_Codec value) { - assert(::webrtc::rtclog2::FrameDecodedEvents_Codec_IsValid(value)); - _has_bits_[0] |= 0x00001000u; - codec_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.codec) -} - -// optional uint32 qp = 7; -inline bool FrameDecodedEvents::has_qp() const { - return (_has_bits_[0] & 0x00002000u) != 0; -} -inline void FrameDecodedEvents::clear_qp() { - qp_ = 0u; - _has_bits_[0] &= ~0x00002000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 FrameDecodedEvents::qp() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.qp) - return qp_; -} -inline void FrameDecodedEvents::set_qp(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00002000u; - qp_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.qp) -} - -// optional uint32 number_of_deltas = 15; -inline bool FrameDecodedEvents::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00004000u) != 0; -} -inline void FrameDecodedEvents::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00004000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 FrameDecodedEvents::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.number_of_deltas) - return number_of_deltas_; -} -inline void FrameDecodedEvents::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00004000u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool FrameDecodedEvents::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void FrameDecodedEvents::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& FrameDecodedEvents::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void FrameDecodedEvents::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms_deltas) -} -inline void FrameDecodedEvents::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms_deltas) -} -inline void FrameDecodedEvents::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms_deltas) -} -inline void FrameDecodedEvents::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms_deltas) -} -inline std::string* FrameDecodedEvents::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* FrameDecodedEvents::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void FrameDecodedEvents::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.FrameDecodedEvents.timestamp_ms_deltas) -} - -// optional bytes ssrc_deltas = 102; -inline bool FrameDecodedEvents::has_ssrc_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void FrameDecodedEvents::clear_ssrc_deltas() { - ssrc_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& FrameDecodedEvents::ssrc_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.ssrc_deltas) - return ssrc_deltas_.GetNoArena(); -} -inline void FrameDecodedEvents::set_ssrc_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.ssrc_deltas) -} -inline void FrameDecodedEvents::set_ssrc_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - ssrc_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.FrameDecodedEvents.ssrc_deltas) -} -inline void FrameDecodedEvents::set_ssrc_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.FrameDecodedEvents.ssrc_deltas) -} -inline void FrameDecodedEvents::set_ssrc_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - ssrc_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.FrameDecodedEvents.ssrc_deltas) -} -inline std::string* FrameDecodedEvents::mutable_ssrc_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.FrameDecodedEvents.ssrc_deltas) - return ssrc_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* FrameDecodedEvents::release_ssrc_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.FrameDecodedEvents.ssrc_deltas) - if (!has_ssrc_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return ssrc_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void FrameDecodedEvents::set_allocated_ssrc_deltas(std::string* ssrc_deltas) { - if (ssrc_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - ssrc_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ssrc_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.FrameDecodedEvents.ssrc_deltas) -} - -// optional bytes render_time_ms_deltas = 103; -inline bool FrameDecodedEvents::has_render_time_ms_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void FrameDecodedEvents::clear_render_time_ms_deltas() { - render_time_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& FrameDecodedEvents::render_time_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.render_time_ms_deltas) - return render_time_ms_deltas_.GetNoArena(); -} -inline void FrameDecodedEvents::set_render_time_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - render_time_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.render_time_ms_deltas) -} -inline void FrameDecodedEvents::set_render_time_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - render_time_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.FrameDecodedEvents.render_time_ms_deltas) -} -inline void FrameDecodedEvents::set_render_time_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - render_time_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.FrameDecodedEvents.render_time_ms_deltas) -} -inline void FrameDecodedEvents::set_render_time_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - render_time_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.FrameDecodedEvents.render_time_ms_deltas) -} -inline std::string* FrameDecodedEvents::mutable_render_time_ms_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.FrameDecodedEvents.render_time_ms_deltas) - return render_time_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* FrameDecodedEvents::release_render_time_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.FrameDecodedEvents.render_time_ms_deltas) - if (!has_render_time_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return render_time_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void FrameDecodedEvents::set_allocated_render_time_ms_deltas(std::string* render_time_ms_deltas) { - if (render_time_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - render_time_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), render_time_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.FrameDecodedEvents.render_time_ms_deltas) -} - -// optional bytes width_deltas = 104; -inline bool FrameDecodedEvents::has_width_deltas() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void FrameDecodedEvents::clear_width_deltas() { - width_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000008u; -} -inline const std::string& FrameDecodedEvents::width_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.width_deltas) - return width_deltas_.GetNoArena(); -} -inline void FrameDecodedEvents::set_width_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000008u; - width_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.width_deltas) -} -inline void FrameDecodedEvents::set_width_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000008u; - width_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.FrameDecodedEvents.width_deltas) -} -inline void FrameDecodedEvents::set_width_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000008u; - width_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.FrameDecodedEvents.width_deltas) -} -inline void FrameDecodedEvents::set_width_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000008u; - width_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.FrameDecodedEvents.width_deltas) -} -inline std::string* FrameDecodedEvents::mutable_width_deltas() { - _has_bits_[0] |= 0x00000008u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.FrameDecodedEvents.width_deltas) - return width_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* FrameDecodedEvents::release_width_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.FrameDecodedEvents.width_deltas) - if (!has_width_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000008u; - return width_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void FrameDecodedEvents::set_allocated_width_deltas(std::string* width_deltas) { - if (width_deltas != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - width_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), width_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.FrameDecodedEvents.width_deltas) -} - -// optional bytes height_deltas = 105; -inline bool FrameDecodedEvents::has_height_deltas() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void FrameDecodedEvents::clear_height_deltas() { - height_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000010u; -} -inline const std::string& FrameDecodedEvents::height_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.height_deltas) - return height_deltas_.GetNoArena(); -} -inline void FrameDecodedEvents::set_height_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000010u; - height_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.height_deltas) -} -inline void FrameDecodedEvents::set_height_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000010u; - height_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.FrameDecodedEvents.height_deltas) -} -inline void FrameDecodedEvents::set_height_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000010u; - height_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.FrameDecodedEvents.height_deltas) -} -inline void FrameDecodedEvents::set_height_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000010u; - height_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.FrameDecodedEvents.height_deltas) -} -inline std::string* FrameDecodedEvents::mutable_height_deltas() { - _has_bits_[0] |= 0x00000010u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.FrameDecodedEvents.height_deltas) - return height_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* FrameDecodedEvents::release_height_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.FrameDecodedEvents.height_deltas) - if (!has_height_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000010u; - return height_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void FrameDecodedEvents::set_allocated_height_deltas(std::string* height_deltas) { - if (height_deltas != nullptr) { - _has_bits_[0] |= 0x00000010u; - } else { - _has_bits_[0] &= ~0x00000010u; - } - height_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), height_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.FrameDecodedEvents.height_deltas) -} - -// optional bytes codec_deltas = 106; -inline bool FrameDecodedEvents::has_codec_deltas() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void FrameDecodedEvents::clear_codec_deltas() { - codec_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000020u; -} -inline const std::string& FrameDecodedEvents::codec_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.codec_deltas) - return codec_deltas_.GetNoArena(); -} -inline void FrameDecodedEvents::set_codec_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000020u; - codec_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.codec_deltas) -} -inline void FrameDecodedEvents::set_codec_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000020u; - codec_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.FrameDecodedEvents.codec_deltas) -} -inline void FrameDecodedEvents::set_codec_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000020u; - codec_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.FrameDecodedEvents.codec_deltas) -} -inline void FrameDecodedEvents::set_codec_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000020u; - codec_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.FrameDecodedEvents.codec_deltas) -} -inline std::string* FrameDecodedEvents::mutable_codec_deltas() { - _has_bits_[0] |= 0x00000020u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.FrameDecodedEvents.codec_deltas) - return codec_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* FrameDecodedEvents::release_codec_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.FrameDecodedEvents.codec_deltas) - if (!has_codec_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000020u; - return codec_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void FrameDecodedEvents::set_allocated_codec_deltas(std::string* codec_deltas) { - if (codec_deltas != nullptr) { - _has_bits_[0] |= 0x00000020u; - } else { - _has_bits_[0] &= ~0x00000020u; - } - codec_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), codec_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.FrameDecodedEvents.codec_deltas) -} - -// optional bytes qp_deltas = 107; -inline bool FrameDecodedEvents::has_qp_deltas() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void FrameDecodedEvents::clear_qp_deltas() { - qp_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000040u; -} -inline const std::string& FrameDecodedEvents::qp_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.FrameDecodedEvents.qp_deltas) - return qp_deltas_.GetNoArena(); -} -inline void FrameDecodedEvents::set_qp_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000040u; - qp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.FrameDecodedEvents.qp_deltas) -} -inline void FrameDecodedEvents::set_qp_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000040u; - qp_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.FrameDecodedEvents.qp_deltas) -} -inline void FrameDecodedEvents::set_qp_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000040u; - qp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.FrameDecodedEvents.qp_deltas) -} -inline void FrameDecodedEvents::set_qp_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000040u; - qp_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.FrameDecodedEvents.qp_deltas) -} -inline std::string* FrameDecodedEvents::mutable_qp_deltas() { - _has_bits_[0] |= 0x00000040u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.FrameDecodedEvents.qp_deltas) - return qp_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* FrameDecodedEvents::release_qp_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.FrameDecodedEvents.qp_deltas) - if (!has_qp_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000040u; - return qp_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void FrameDecodedEvents::set_allocated_qp_deltas(std::string* qp_deltas) { - if (qp_deltas != nullptr) { - _has_bits_[0] |= 0x00000040u; - } else { - _has_bits_[0] &= ~0x00000040u; - } - qp_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), qp_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.FrameDecodedEvents.qp_deltas) -} - -// ------------------------------------------------------------------- - -// BeginLogEvent - -// optional int64 timestamp_ms = 1; -inline bool BeginLogEvent::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void BeginLogEvent::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 BeginLogEvent::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BeginLogEvent.timestamp_ms) - return timestamp_ms_; -} -inline void BeginLogEvent::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BeginLogEvent.timestamp_ms) -} - -// optional uint32 version = 2; -inline bool BeginLogEvent::has_version() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void BeginLogEvent::clear_version() { - version_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BeginLogEvent::version() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BeginLogEvent.version) - return version_; -} -inline void BeginLogEvent::set_version(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - version_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BeginLogEvent.version) -} - -// optional int64 utc_time_ms = 3; -inline bool BeginLogEvent::has_utc_time_ms() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void BeginLogEvent::clear_utc_time_ms() { - utc_time_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 BeginLogEvent::utc_time_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BeginLogEvent.utc_time_ms) - return utc_time_ms_; -} -inline void BeginLogEvent::set_utc_time_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000002u; - utc_time_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BeginLogEvent.utc_time_ms) -} - -// ------------------------------------------------------------------- - -// EndLogEvent - -// optional int64 timestamp_ms = 1; -inline bool EndLogEvent::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void EndLogEvent::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 EndLogEvent::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.EndLogEvent.timestamp_ms) - return timestamp_ms_; -} -inline void EndLogEvent::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.EndLogEvent.timestamp_ms) -} - -// ------------------------------------------------------------------- - -// LossBasedBweUpdates - -// optional int64 timestamp_ms = 1; -inline bool LossBasedBweUpdates::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void LossBasedBweUpdates::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 LossBasedBweUpdates::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms) - return timestamp_ms_; -} -inline void LossBasedBweUpdates::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000010u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms) -} - -// optional uint32 bitrate_bps = 2; -inline bool LossBasedBweUpdates::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void LossBasedBweUpdates::clear_bitrate_bps() { - bitrate_bps_ = 0u; - _has_bits_[0] &= ~0x00000020u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 LossBasedBweUpdates::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps) - return bitrate_bps_; -} -inline void LossBasedBweUpdates::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000020u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps) -} - -// optional uint32 fraction_loss = 3; -inline bool LossBasedBweUpdates::has_fraction_loss() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void LossBasedBweUpdates::clear_fraction_loss() { - fraction_loss_ = 0u; - _has_bits_[0] &= ~0x00000040u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 LossBasedBweUpdates::fraction_loss() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss) - return fraction_loss_; -} -inline void LossBasedBweUpdates::set_fraction_loss(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000040u; - fraction_loss_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss) -} - -// optional uint32 total_packets = 4; -inline bool LossBasedBweUpdates::has_total_packets() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void LossBasedBweUpdates::clear_total_packets() { - total_packets_ = 0u; - _has_bits_[0] &= ~0x00000080u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 LossBasedBweUpdates::total_packets() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.total_packets) - return total_packets_; -} -inline void LossBasedBweUpdates::set_total_packets(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000080u; - total_packets_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.total_packets) -} - -// optional uint32 number_of_deltas = 5; -inline bool LossBasedBweUpdates::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void LossBasedBweUpdates::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000100u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 LossBasedBweUpdates::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.number_of_deltas) - return number_of_deltas_; -} -inline void LossBasedBweUpdates::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000100u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool LossBasedBweUpdates::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void LossBasedBweUpdates::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& LossBasedBweUpdates::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void LossBasedBweUpdates::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms_deltas) -} -inline void LossBasedBweUpdates::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms_deltas) -} -inline void LossBasedBweUpdates::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms_deltas) -} -inline void LossBasedBweUpdates::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms_deltas) -} -inline std::string* LossBasedBweUpdates::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* LossBasedBweUpdates::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void LossBasedBweUpdates::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.LossBasedBweUpdates.timestamp_ms_deltas) -} - -// optional bytes bitrate_bps_deltas = 102; -inline bool LossBasedBweUpdates::has_bitrate_bps_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void LossBasedBweUpdates::clear_bitrate_bps_deltas() { - bitrate_bps_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& LossBasedBweUpdates::bitrate_bps_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps_deltas) - return bitrate_bps_deltas_.GetNoArena(); -} -inline void LossBasedBweUpdates::set_bitrate_bps_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps_deltas) -} -inline void LossBasedBweUpdates::set_bitrate_bps_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps_deltas) -} -inline void LossBasedBweUpdates::set_bitrate_bps_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps_deltas) -} -inline void LossBasedBweUpdates::set_bitrate_bps_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps_deltas) -} -inline std::string* LossBasedBweUpdates::mutable_bitrate_bps_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps_deltas) - return bitrate_bps_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* LossBasedBweUpdates::release_bitrate_bps_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps_deltas) - if (!has_bitrate_bps_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return bitrate_bps_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void LossBasedBweUpdates::set_allocated_bitrate_bps_deltas(std::string* bitrate_bps_deltas) { - if (bitrate_bps_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - bitrate_bps_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), bitrate_bps_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.LossBasedBweUpdates.bitrate_bps_deltas) -} - -// optional bytes fraction_loss_deltas = 103; -inline bool LossBasedBweUpdates::has_fraction_loss_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void LossBasedBweUpdates::clear_fraction_loss_deltas() { - fraction_loss_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& LossBasedBweUpdates::fraction_loss_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss_deltas) - return fraction_loss_deltas_.GetNoArena(); -} -inline void LossBasedBweUpdates::set_fraction_loss_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - fraction_loss_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss_deltas) -} -inline void LossBasedBweUpdates::set_fraction_loss_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - fraction_loss_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss_deltas) -} -inline void LossBasedBweUpdates::set_fraction_loss_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - fraction_loss_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss_deltas) -} -inline void LossBasedBweUpdates::set_fraction_loss_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - fraction_loss_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss_deltas) -} -inline std::string* LossBasedBweUpdates::mutable_fraction_loss_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss_deltas) - return fraction_loss_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* LossBasedBweUpdates::release_fraction_loss_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss_deltas) - if (!has_fraction_loss_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return fraction_loss_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void LossBasedBweUpdates::set_allocated_fraction_loss_deltas(std::string* fraction_loss_deltas) { - if (fraction_loss_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - fraction_loss_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), fraction_loss_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.LossBasedBweUpdates.fraction_loss_deltas) -} - -// optional bytes total_packets_deltas = 104; -inline bool LossBasedBweUpdates::has_total_packets_deltas() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void LossBasedBweUpdates::clear_total_packets_deltas() { - total_packets_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000008u; -} -inline const std::string& LossBasedBweUpdates::total_packets_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.LossBasedBweUpdates.total_packets_deltas) - return total_packets_deltas_.GetNoArena(); -} -inline void LossBasedBweUpdates::set_total_packets_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000008u; - total_packets_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.LossBasedBweUpdates.total_packets_deltas) -} -inline void LossBasedBweUpdates::set_total_packets_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000008u; - total_packets_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.LossBasedBweUpdates.total_packets_deltas) -} -inline void LossBasedBweUpdates::set_total_packets_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000008u; - total_packets_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.LossBasedBweUpdates.total_packets_deltas) -} -inline void LossBasedBweUpdates::set_total_packets_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000008u; - total_packets_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.LossBasedBweUpdates.total_packets_deltas) -} -inline std::string* LossBasedBweUpdates::mutable_total_packets_deltas() { - _has_bits_[0] |= 0x00000008u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.LossBasedBweUpdates.total_packets_deltas) - return total_packets_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* LossBasedBweUpdates::release_total_packets_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.LossBasedBweUpdates.total_packets_deltas) - if (!has_total_packets_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000008u; - return total_packets_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void LossBasedBweUpdates::set_allocated_total_packets_deltas(std::string* total_packets_deltas) { - if (total_packets_deltas != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - total_packets_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), total_packets_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.LossBasedBweUpdates.total_packets_deltas) -} - -// ------------------------------------------------------------------- - -// DelayBasedBweUpdates - -// optional int64 timestamp_ms = 1; -inline bool DelayBasedBweUpdates::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void DelayBasedBweUpdates::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 DelayBasedBweUpdates::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms) - return timestamp_ms_; -} -inline void DelayBasedBweUpdates::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000008u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms) -} - -// optional uint32 bitrate_bps = 2; -inline bool DelayBasedBweUpdates::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void DelayBasedBweUpdates::clear_bitrate_bps() { - bitrate_bps_ = 0u; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 DelayBasedBweUpdates::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps) - return bitrate_bps_; -} -inline void DelayBasedBweUpdates::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000010u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps) -} - -// optional .webrtc.rtclog2.DelayBasedBweUpdates.DetectorState detector_state = 3; -inline bool DelayBasedBweUpdates::has_detector_state() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void DelayBasedBweUpdates::clear_detector_state() { - detector_state_ = 0; - _has_bits_[0] &= ~0x00000020u; -} -inline ::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState DelayBasedBweUpdates::detector_state() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DelayBasedBweUpdates.detector_state) - return static_cast< ::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState >(detector_state_); -} -inline void DelayBasedBweUpdates::set_detector_state(::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState value) { - assert(::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState_IsValid(value)); - _has_bits_[0] |= 0x00000020u; - detector_state_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DelayBasedBweUpdates.detector_state) -} - -// optional uint32 number_of_deltas = 4; -inline bool DelayBasedBweUpdates::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void DelayBasedBweUpdates::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000040u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 DelayBasedBweUpdates::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DelayBasedBweUpdates.number_of_deltas) - return number_of_deltas_; -} -inline void DelayBasedBweUpdates::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000040u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DelayBasedBweUpdates.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool DelayBasedBweUpdates::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void DelayBasedBweUpdates::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& DelayBasedBweUpdates::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void DelayBasedBweUpdates::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms_deltas) -} -inline void DelayBasedBweUpdates::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms_deltas) -} -inline void DelayBasedBweUpdates::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms_deltas) -} -inline void DelayBasedBweUpdates::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms_deltas) -} -inline std::string* DelayBasedBweUpdates::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* DelayBasedBweUpdates::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void DelayBasedBweUpdates::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.DelayBasedBweUpdates.timestamp_ms_deltas) -} - -// optional bytes bitrate_bps_deltas = 102; -inline bool DelayBasedBweUpdates::has_bitrate_bps_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void DelayBasedBweUpdates::clear_bitrate_bps_deltas() { - bitrate_bps_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& DelayBasedBweUpdates::bitrate_bps_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps_deltas) - return bitrate_bps_deltas_.GetNoArena(); -} -inline void DelayBasedBweUpdates::set_bitrate_bps_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps_deltas) -} -inline void DelayBasedBweUpdates::set_bitrate_bps_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps_deltas) -} -inline void DelayBasedBweUpdates::set_bitrate_bps_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps_deltas) -} -inline void DelayBasedBweUpdates::set_bitrate_bps_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps_deltas) -} -inline std::string* DelayBasedBweUpdates::mutable_bitrate_bps_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps_deltas) - return bitrate_bps_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* DelayBasedBweUpdates::release_bitrate_bps_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps_deltas) - if (!has_bitrate_bps_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return bitrate_bps_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void DelayBasedBweUpdates::set_allocated_bitrate_bps_deltas(std::string* bitrate_bps_deltas) { - if (bitrate_bps_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - bitrate_bps_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), bitrate_bps_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.DelayBasedBweUpdates.bitrate_bps_deltas) -} - -// optional bytes detector_state_deltas = 103; -inline bool DelayBasedBweUpdates::has_detector_state_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void DelayBasedBweUpdates::clear_detector_state_deltas() { - detector_state_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& DelayBasedBweUpdates::detector_state_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DelayBasedBweUpdates.detector_state_deltas) - return detector_state_deltas_.GetNoArena(); -} -inline void DelayBasedBweUpdates::set_detector_state_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - detector_state_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DelayBasedBweUpdates.detector_state_deltas) -} -inline void DelayBasedBweUpdates::set_detector_state_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - detector_state_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.DelayBasedBweUpdates.detector_state_deltas) -} -inline void DelayBasedBweUpdates::set_detector_state_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - detector_state_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.DelayBasedBweUpdates.detector_state_deltas) -} -inline void DelayBasedBweUpdates::set_detector_state_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - detector_state_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.DelayBasedBweUpdates.detector_state_deltas) -} -inline std::string* DelayBasedBweUpdates::mutable_detector_state_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.DelayBasedBweUpdates.detector_state_deltas) - return detector_state_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* DelayBasedBweUpdates::release_detector_state_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.DelayBasedBweUpdates.detector_state_deltas) - if (!has_detector_state_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return detector_state_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void DelayBasedBweUpdates::set_allocated_detector_state_deltas(std::string* detector_state_deltas) { - if (detector_state_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - detector_state_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), detector_state_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.DelayBasedBweUpdates.detector_state_deltas) -} - -// ------------------------------------------------------------------- - -// RtpHeaderExtensionConfig - -// optional int32 transmission_time_offset_id = 1; -inline bool RtpHeaderExtensionConfig::has_transmission_time_offset_id() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void RtpHeaderExtensionConfig::clear_transmission_time_offset_id() { - transmission_time_offset_id_ = 0; - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtpHeaderExtensionConfig::transmission_time_offset_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RtpHeaderExtensionConfig.transmission_time_offset_id) - return transmission_time_offset_id_; -} -inline void RtpHeaderExtensionConfig::set_transmission_time_offset_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000001u; - transmission_time_offset_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RtpHeaderExtensionConfig.transmission_time_offset_id) -} - -// optional int32 absolute_send_time_id = 2; -inline bool RtpHeaderExtensionConfig::has_absolute_send_time_id() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void RtpHeaderExtensionConfig::clear_absolute_send_time_id() { - absolute_send_time_id_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtpHeaderExtensionConfig::absolute_send_time_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RtpHeaderExtensionConfig.absolute_send_time_id) - return absolute_send_time_id_; -} -inline void RtpHeaderExtensionConfig::set_absolute_send_time_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000002u; - absolute_send_time_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RtpHeaderExtensionConfig.absolute_send_time_id) -} - -// optional int32 transport_sequence_number_id = 3; -inline bool RtpHeaderExtensionConfig::has_transport_sequence_number_id() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void RtpHeaderExtensionConfig::clear_transport_sequence_number_id() { - transport_sequence_number_id_ = 0; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtpHeaderExtensionConfig::transport_sequence_number_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RtpHeaderExtensionConfig.transport_sequence_number_id) - return transport_sequence_number_id_; -} -inline void RtpHeaderExtensionConfig::set_transport_sequence_number_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000004u; - transport_sequence_number_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RtpHeaderExtensionConfig.transport_sequence_number_id) -} - -// optional int32 video_rotation_id = 4; -inline bool RtpHeaderExtensionConfig::has_video_rotation_id() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void RtpHeaderExtensionConfig::clear_video_rotation_id() { - video_rotation_id_ = 0; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtpHeaderExtensionConfig::video_rotation_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RtpHeaderExtensionConfig.video_rotation_id) - return video_rotation_id_; -} -inline void RtpHeaderExtensionConfig::set_video_rotation_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000008u; - video_rotation_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RtpHeaderExtensionConfig.video_rotation_id) -} - -// optional int32 audio_level_id = 5; -inline bool RtpHeaderExtensionConfig::has_audio_level_id() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void RtpHeaderExtensionConfig::clear_audio_level_id() { - audio_level_id_ = 0; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 RtpHeaderExtensionConfig::audio_level_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RtpHeaderExtensionConfig.audio_level_id) - return audio_level_id_; -} -inline void RtpHeaderExtensionConfig::set_audio_level_id(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000010u; - audio_level_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RtpHeaderExtensionConfig.audio_level_id) -} - -// ------------------------------------------------------------------- - -// VideoRecvStreamConfig - -// optional int64 timestamp_ms = 1; -inline bool VideoRecvStreamConfig::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void VideoRecvStreamConfig::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 VideoRecvStreamConfig::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoRecvStreamConfig.timestamp_ms) - return timestamp_ms_; -} -inline void VideoRecvStreamConfig::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.VideoRecvStreamConfig.timestamp_ms) -} - -// optional uint32 remote_ssrc = 2; -inline bool VideoRecvStreamConfig::has_remote_ssrc() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void VideoRecvStreamConfig::clear_remote_ssrc() { - remote_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoRecvStreamConfig::remote_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoRecvStreamConfig.remote_ssrc) - return remote_ssrc_; -} -inline void VideoRecvStreamConfig::set_remote_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - remote_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.VideoRecvStreamConfig.remote_ssrc) -} - -// optional uint32 local_ssrc = 3; -inline bool VideoRecvStreamConfig::has_local_ssrc() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void VideoRecvStreamConfig::clear_local_ssrc() { - local_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoRecvStreamConfig::local_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoRecvStreamConfig.local_ssrc) - return local_ssrc_; -} -inline void VideoRecvStreamConfig::set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000008u; - local_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.VideoRecvStreamConfig.local_ssrc) -} - -// optional uint32 rtx_ssrc = 4; -inline bool VideoRecvStreamConfig::has_rtx_ssrc() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void VideoRecvStreamConfig::clear_rtx_ssrc() { - rtx_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoRecvStreamConfig::rtx_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoRecvStreamConfig.rtx_ssrc) - return rtx_ssrc_; -} -inline void VideoRecvStreamConfig::set_rtx_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000010u; - rtx_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.VideoRecvStreamConfig.rtx_ssrc) -} - -// optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; -inline bool VideoRecvStreamConfig::has_header_extensions() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void VideoRecvStreamConfig::clear_header_extensions() { - if (header_extensions_ != nullptr) header_extensions_->Clear(); - _has_bits_[0] &= ~0x00000001u; -} -inline const ::webrtc::rtclog2::RtpHeaderExtensionConfig& VideoRecvStreamConfig::header_extensions() const { - const ::webrtc::rtclog2::RtpHeaderExtensionConfig* p = header_extensions_; - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoRecvStreamConfig.header_extensions) - return p != nullptr ? *p : *reinterpret_cast( - &::webrtc::rtclog2::_RtpHeaderExtensionConfig_default_instance_); -} -inline ::webrtc::rtclog2::RtpHeaderExtensionConfig* VideoRecvStreamConfig::release_header_extensions() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.VideoRecvStreamConfig.header_extensions) - _has_bits_[0] &= ~0x00000001u; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* temp = header_extensions_; - header_extensions_ = nullptr; - return temp; -} -inline ::webrtc::rtclog2::RtpHeaderExtensionConfig* VideoRecvStreamConfig::mutable_header_extensions() { - _has_bits_[0] |= 0x00000001u; - if (header_extensions_ == nullptr) { - auto* p = CreateMaybeMessage<::webrtc::rtclog2::RtpHeaderExtensionConfig>(GetArenaNoVirtual()); - header_extensions_ = p; - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.VideoRecvStreamConfig.header_extensions) - return header_extensions_; -} -inline void VideoRecvStreamConfig::set_allocated_header_extensions(::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - if (message_arena == nullptr) { - delete header_extensions_; - } - if (header_extensions) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - header_extensions = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, header_extensions, submessage_arena); - } - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - header_extensions_ = header_extensions; - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.VideoRecvStreamConfig.header_extensions) -} - -// ------------------------------------------------------------------- - -// VideoSendStreamConfig - -// optional int64 timestamp_ms = 1; -inline bool VideoSendStreamConfig::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void VideoSendStreamConfig::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 VideoSendStreamConfig::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoSendStreamConfig.timestamp_ms) - return timestamp_ms_; -} -inline void VideoSendStreamConfig::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.VideoSendStreamConfig.timestamp_ms) -} - -// optional uint32 ssrc = 2; -inline bool VideoSendStreamConfig::has_ssrc() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void VideoSendStreamConfig::clear_ssrc() { - ssrc_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoSendStreamConfig::ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoSendStreamConfig.ssrc) - return ssrc_; -} -inline void VideoSendStreamConfig::set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.VideoSendStreamConfig.ssrc) -} - -// optional uint32 rtx_ssrc = 3; -inline bool VideoSendStreamConfig::has_rtx_ssrc() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void VideoSendStreamConfig::clear_rtx_ssrc() { - rtx_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 VideoSendStreamConfig::rtx_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoSendStreamConfig.rtx_ssrc) - return rtx_ssrc_; -} -inline void VideoSendStreamConfig::set_rtx_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000008u; - rtx_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.VideoSendStreamConfig.rtx_ssrc) -} - -// optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; -inline bool VideoSendStreamConfig::has_header_extensions() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void VideoSendStreamConfig::clear_header_extensions() { - if (header_extensions_ != nullptr) header_extensions_->Clear(); - _has_bits_[0] &= ~0x00000001u; -} -inline const ::webrtc::rtclog2::RtpHeaderExtensionConfig& VideoSendStreamConfig::header_extensions() const { - const ::webrtc::rtclog2::RtpHeaderExtensionConfig* p = header_extensions_; - // @@protoc_insertion_point(field_get:webrtc.rtclog2.VideoSendStreamConfig.header_extensions) - return p != nullptr ? *p : *reinterpret_cast( - &::webrtc::rtclog2::_RtpHeaderExtensionConfig_default_instance_); -} -inline ::webrtc::rtclog2::RtpHeaderExtensionConfig* VideoSendStreamConfig::release_header_extensions() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.VideoSendStreamConfig.header_extensions) - _has_bits_[0] &= ~0x00000001u; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* temp = header_extensions_; - header_extensions_ = nullptr; - return temp; -} -inline ::webrtc::rtclog2::RtpHeaderExtensionConfig* VideoSendStreamConfig::mutable_header_extensions() { - _has_bits_[0] |= 0x00000001u; - if (header_extensions_ == nullptr) { - auto* p = CreateMaybeMessage<::webrtc::rtclog2::RtpHeaderExtensionConfig>(GetArenaNoVirtual()); - header_extensions_ = p; - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.VideoSendStreamConfig.header_extensions) - return header_extensions_; -} -inline void VideoSendStreamConfig::set_allocated_header_extensions(::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - if (message_arena == nullptr) { - delete header_extensions_; - } - if (header_extensions) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - header_extensions = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, header_extensions, submessage_arena); - } - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - header_extensions_ = header_extensions; - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.VideoSendStreamConfig.header_extensions) -} - -// ------------------------------------------------------------------- - -// AudioRecvStreamConfig - -// optional int64 timestamp_ms = 1; -inline bool AudioRecvStreamConfig::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void AudioRecvStreamConfig::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 AudioRecvStreamConfig::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioRecvStreamConfig.timestamp_ms) - return timestamp_ms_; -} -inline void AudioRecvStreamConfig::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioRecvStreamConfig.timestamp_ms) -} - -// optional uint32 remote_ssrc = 2; -inline bool AudioRecvStreamConfig::has_remote_ssrc() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void AudioRecvStreamConfig::clear_remote_ssrc() { - remote_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioRecvStreamConfig::remote_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioRecvStreamConfig.remote_ssrc) - return remote_ssrc_; -} -inline void AudioRecvStreamConfig::set_remote_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - remote_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioRecvStreamConfig.remote_ssrc) -} - -// optional uint32 local_ssrc = 3; -inline bool AudioRecvStreamConfig::has_local_ssrc() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void AudioRecvStreamConfig::clear_local_ssrc() { - local_ssrc_ = 0u; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioRecvStreamConfig::local_ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioRecvStreamConfig.local_ssrc) - return local_ssrc_; -} -inline void AudioRecvStreamConfig::set_local_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000008u; - local_ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioRecvStreamConfig.local_ssrc) -} - -// optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 5; -inline bool AudioRecvStreamConfig::has_header_extensions() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AudioRecvStreamConfig::clear_header_extensions() { - if (header_extensions_ != nullptr) header_extensions_->Clear(); - _has_bits_[0] &= ~0x00000001u; -} -inline const ::webrtc::rtclog2::RtpHeaderExtensionConfig& AudioRecvStreamConfig::header_extensions() const { - const ::webrtc::rtclog2::RtpHeaderExtensionConfig* p = header_extensions_; - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioRecvStreamConfig.header_extensions) - return p != nullptr ? *p : *reinterpret_cast( - &::webrtc::rtclog2::_RtpHeaderExtensionConfig_default_instance_); -} -inline ::webrtc::rtclog2::RtpHeaderExtensionConfig* AudioRecvStreamConfig::release_header_extensions() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioRecvStreamConfig.header_extensions) - _has_bits_[0] &= ~0x00000001u; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* temp = header_extensions_; - header_extensions_ = nullptr; - return temp; -} -inline ::webrtc::rtclog2::RtpHeaderExtensionConfig* AudioRecvStreamConfig::mutable_header_extensions() { - _has_bits_[0] |= 0x00000001u; - if (header_extensions_ == nullptr) { - auto* p = CreateMaybeMessage<::webrtc::rtclog2::RtpHeaderExtensionConfig>(GetArenaNoVirtual()); - header_extensions_ = p; - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioRecvStreamConfig.header_extensions) - return header_extensions_; -} -inline void AudioRecvStreamConfig::set_allocated_header_extensions(::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - if (message_arena == nullptr) { - delete header_extensions_; - } - if (header_extensions) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - header_extensions = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, header_extensions, submessage_arena); - } - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - header_extensions_ = header_extensions; - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioRecvStreamConfig.header_extensions) -} - -// ------------------------------------------------------------------- - -// AudioSendStreamConfig - -// optional int64 timestamp_ms = 1; -inline bool AudioSendStreamConfig::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void AudioSendStreamConfig::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 AudioSendStreamConfig::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioSendStreamConfig.timestamp_ms) - return timestamp_ms_; -} -inline void AudioSendStreamConfig::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000002u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioSendStreamConfig.timestamp_ms) -} - -// optional uint32 ssrc = 2; -inline bool AudioSendStreamConfig::has_ssrc() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void AudioSendStreamConfig::clear_ssrc() { - ssrc_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioSendStreamConfig::ssrc() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioSendStreamConfig.ssrc) - return ssrc_; -} -inline void AudioSendStreamConfig::set_ssrc(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - ssrc_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioSendStreamConfig.ssrc) -} - -// optional .webrtc.rtclog2.RtpHeaderExtensionConfig header_extensions = 4; -inline bool AudioSendStreamConfig::has_header_extensions() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AudioSendStreamConfig::clear_header_extensions() { - if (header_extensions_ != nullptr) header_extensions_->Clear(); - _has_bits_[0] &= ~0x00000001u; -} -inline const ::webrtc::rtclog2::RtpHeaderExtensionConfig& AudioSendStreamConfig::header_extensions() const { - const ::webrtc::rtclog2::RtpHeaderExtensionConfig* p = header_extensions_; - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioSendStreamConfig.header_extensions) - return p != nullptr ? *p : *reinterpret_cast( - &::webrtc::rtclog2::_RtpHeaderExtensionConfig_default_instance_); -} -inline ::webrtc::rtclog2::RtpHeaderExtensionConfig* AudioSendStreamConfig::release_header_extensions() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioSendStreamConfig.header_extensions) - _has_bits_[0] &= ~0x00000001u; - ::webrtc::rtclog2::RtpHeaderExtensionConfig* temp = header_extensions_; - header_extensions_ = nullptr; - return temp; -} -inline ::webrtc::rtclog2::RtpHeaderExtensionConfig* AudioSendStreamConfig::mutable_header_extensions() { - _has_bits_[0] |= 0x00000001u; - if (header_extensions_ == nullptr) { - auto* p = CreateMaybeMessage<::webrtc::rtclog2::RtpHeaderExtensionConfig>(GetArenaNoVirtual()); - header_extensions_ = p; - } - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioSendStreamConfig.header_extensions) - return header_extensions_; -} -inline void AudioSendStreamConfig::set_allocated_header_extensions(::webrtc::rtclog2::RtpHeaderExtensionConfig* header_extensions) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); - if (message_arena == nullptr) { - delete header_extensions_; - } - if (header_extensions) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; - if (message_arena != submessage_arena) { - header_extensions = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( - message_arena, header_extensions, submessage_arena); - } - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - header_extensions_ = header_extensions; - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioSendStreamConfig.header_extensions) -} - -// ------------------------------------------------------------------- - -// AudioNetworkAdaptations - -// optional int64 timestamp_ms = 1; -inline bool AudioNetworkAdaptations::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void AudioNetworkAdaptations::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000080u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 AudioNetworkAdaptations::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms) - return timestamp_ms_; -} -inline void AudioNetworkAdaptations::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000080u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms) -} - -// optional int32 bitrate_bps = 2; -inline bool AudioNetworkAdaptations::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void AudioNetworkAdaptations::clear_bitrate_bps() { - bitrate_bps_ = 0; - _has_bits_[0] &= ~0x00000100u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 AudioNetworkAdaptations::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps) - return bitrate_bps_; -} -inline void AudioNetworkAdaptations::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000100u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps) -} - -// optional int32 frame_length_ms = 3; -inline bool AudioNetworkAdaptations::has_frame_length_ms() const { - return (_has_bits_[0] & 0x00000200u) != 0; -} -inline void AudioNetworkAdaptations::clear_frame_length_ms() { - frame_length_ms_ = 0; - _has_bits_[0] &= ~0x00000200u; -} -inline ::PROTOBUF_NAMESPACE_ID::int32 AudioNetworkAdaptations::frame_length_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms) - return frame_length_ms_; -} -inline void AudioNetworkAdaptations::set_frame_length_ms(::PROTOBUF_NAMESPACE_ID::int32 value) { - _has_bits_[0] |= 0x00000200u; - frame_length_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms) -} - -// optional uint32 uplink_packet_loss_fraction = 4; -inline bool AudioNetworkAdaptations::has_uplink_packet_loss_fraction() const { - return (_has_bits_[0] & 0x00000400u) != 0; -} -inline void AudioNetworkAdaptations::clear_uplink_packet_loss_fraction() { - uplink_packet_loss_fraction_ = 0u; - _has_bits_[0] &= ~0x00000400u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioNetworkAdaptations::uplink_packet_loss_fraction() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction) - return uplink_packet_loss_fraction_; -} -inline void AudioNetworkAdaptations::set_uplink_packet_loss_fraction(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000400u; - uplink_packet_loss_fraction_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction) -} - -// optional bool enable_fec = 5; -inline bool AudioNetworkAdaptations::has_enable_fec() const { - return (_has_bits_[0] & 0x00000800u) != 0; -} -inline void AudioNetworkAdaptations::clear_enable_fec() { - enable_fec_ = false; - _has_bits_[0] &= ~0x00000800u; -} -inline bool AudioNetworkAdaptations::enable_fec() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec) - return enable_fec_; -} -inline void AudioNetworkAdaptations::set_enable_fec(bool value) { - _has_bits_[0] |= 0x00000800u; - enable_fec_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec) -} - -// optional bool enable_dtx = 6; -inline bool AudioNetworkAdaptations::has_enable_dtx() const { - return (_has_bits_[0] & 0x00001000u) != 0; -} -inline void AudioNetworkAdaptations::clear_enable_dtx() { - enable_dtx_ = false; - _has_bits_[0] &= ~0x00001000u; -} -inline bool AudioNetworkAdaptations::enable_dtx() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx) - return enable_dtx_; -} -inline void AudioNetworkAdaptations::set_enable_dtx(bool value) { - _has_bits_[0] |= 0x00001000u; - enable_dtx_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx) -} - -// optional uint32 num_channels = 7; -inline bool AudioNetworkAdaptations::has_num_channels() const { - return (_has_bits_[0] & 0x00002000u) != 0; -} -inline void AudioNetworkAdaptations::clear_num_channels() { - num_channels_ = 0u; - _has_bits_[0] &= ~0x00002000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioNetworkAdaptations::num_channels() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.num_channels) - return num_channels_; -} -inline void AudioNetworkAdaptations::set_num_channels(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00002000u; - num_channels_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.num_channels) -} - -// optional uint32 number_of_deltas = 8; -inline bool AudioNetworkAdaptations::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00004000u) != 0; -} -inline void AudioNetworkAdaptations::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00004000u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 AudioNetworkAdaptations::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.number_of_deltas) - return number_of_deltas_; -} -inline void AudioNetworkAdaptations::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00004000u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool AudioNetworkAdaptations::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AudioNetworkAdaptations::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& AudioNetworkAdaptations::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void AudioNetworkAdaptations::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms_deltas) -} -inline void AudioNetworkAdaptations::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms_deltas) -} -inline void AudioNetworkAdaptations::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms_deltas) -} -inline void AudioNetworkAdaptations::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms_deltas) -} -inline std::string* AudioNetworkAdaptations::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioNetworkAdaptations::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioNetworkAdaptations::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioNetworkAdaptations.timestamp_ms_deltas) -} - -// optional bytes bitrate_bps_deltas = 102; -inline bool AudioNetworkAdaptations::has_bitrate_bps_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void AudioNetworkAdaptations::clear_bitrate_bps_deltas() { - bitrate_bps_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& AudioNetworkAdaptations::bitrate_bps_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps_deltas) - return bitrate_bps_deltas_.GetNoArena(); -} -inline void AudioNetworkAdaptations::set_bitrate_bps_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps_deltas) -} -inline void AudioNetworkAdaptations::set_bitrate_bps_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps_deltas) -} -inline void AudioNetworkAdaptations::set_bitrate_bps_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps_deltas) -} -inline void AudioNetworkAdaptations::set_bitrate_bps_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - bitrate_bps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps_deltas) -} -inline std::string* AudioNetworkAdaptations::mutable_bitrate_bps_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps_deltas) - return bitrate_bps_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioNetworkAdaptations::release_bitrate_bps_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps_deltas) - if (!has_bitrate_bps_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return bitrate_bps_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioNetworkAdaptations::set_allocated_bitrate_bps_deltas(std::string* bitrate_bps_deltas) { - if (bitrate_bps_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - bitrate_bps_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), bitrate_bps_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioNetworkAdaptations.bitrate_bps_deltas) -} - -// optional bytes frame_length_ms_deltas = 103; -inline bool AudioNetworkAdaptations::has_frame_length_ms_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void AudioNetworkAdaptations::clear_frame_length_ms_deltas() { - frame_length_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& AudioNetworkAdaptations::frame_length_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms_deltas) - return frame_length_ms_deltas_.GetNoArena(); -} -inline void AudioNetworkAdaptations::set_frame_length_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - frame_length_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms_deltas) -} -inline void AudioNetworkAdaptations::set_frame_length_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - frame_length_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms_deltas) -} -inline void AudioNetworkAdaptations::set_frame_length_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - frame_length_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms_deltas) -} -inline void AudioNetworkAdaptations::set_frame_length_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - frame_length_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms_deltas) -} -inline std::string* AudioNetworkAdaptations::mutable_frame_length_ms_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms_deltas) - return frame_length_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioNetworkAdaptations::release_frame_length_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms_deltas) - if (!has_frame_length_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return frame_length_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioNetworkAdaptations::set_allocated_frame_length_ms_deltas(std::string* frame_length_ms_deltas) { - if (frame_length_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - frame_length_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), frame_length_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioNetworkAdaptations.frame_length_ms_deltas) -} - -// optional bytes uplink_packet_loss_fraction_deltas = 104; -inline bool AudioNetworkAdaptations::has_uplink_packet_loss_fraction_deltas() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void AudioNetworkAdaptations::clear_uplink_packet_loss_fraction_deltas() { - uplink_packet_loss_fraction_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000008u; -} -inline const std::string& AudioNetworkAdaptations::uplink_packet_loss_fraction_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction_deltas) - return uplink_packet_loss_fraction_deltas_.GetNoArena(); -} -inline void AudioNetworkAdaptations::set_uplink_packet_loss_fraction_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000008u; - uplink_packet_loss_fraction_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction_deltas) -} -inline void AudioNetworkAdaptations::set_uplink_packet_loss_fraction_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000008u; - uplink_packet_loss_fraction_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction_deltas) -} -inline void AudioNetworkAdaptations::set_uplink_packet_loss_fraction_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000008u; - uplink_packet_loss_fraction_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction_deltas) -} -inline void AudioNetworkAdaptations::set_uplink_packet_loss_fraction_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000008u; - uplink_packet_loss_fraction_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction_deltas) -} -inline std::string* AudioNetworkAdaptations::mutable_uplink_packet_loss_fraction_deltas() { - _has_bits_[0] |= 0x00000008u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction_deltas) - return uplink_packet_loss_fraction_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioNetworkAdaptations::release_uplink_packet_loss_fraction_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction_deltas) - if (!has_uplink_packet_loss_fraction_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000008u; - return uplink_packet_loss_fraction_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioNetworkAdaptations::set_allocated_uplink_packet_loss_fraction_deltas(std::string* uplink_packet_loss_fraction_deltas) { - if (uplink_packet_loss_fraction_deltas != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - uplink_packet_loss_fraction_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), uplink_packet_loss_fraction_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioNetworkAdaptations.uplink_packet_loss_fraction_deltas) -} - -// optional bytes enable_fec_deltas = 105; -inline bool AudioNetworkAdaptations::has_enable_fec_deltas() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void AudioNetworkAdaptations::clear_enable_fec_deltas() { - enable_fec_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000010u; -} -inline const std::string& AudioNetworkAdaptations::enable_fec_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec_deltas) - return enable_fec_deltas_.GetNoArena(); -} -inline void AudioNetworkAdaptations::set_enable_fec_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000010u; - enable_fec_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec_deltas) -} -inline void AudioNetworkAdaptations::set_enable_fec_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000010u; - enable_fec_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec_deltas) -} -inline void AudioNetworkAdaptations::set_enable_fec_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000010u; - enable_fec_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec_deltas) -} -inline void AudioNetworkAdaptations::set_enable_fec_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000010u; - enable_fec_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec_deltas) -} -inline std::string* AudioNetworkAdaptations::mutable_enable_fec_deltas() { - _has_bits_[0] |= 0x00000010u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec_deltas) - return enable_fec_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioNetworkAdaptations::release_enable_fec_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec_deltas) - if (!has_enable_fec_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000010u; - return enable_fec_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioNetworkAdaptations::set_allocated_enable_fec_deltas(std::string* enable_fec_deltas) { - if (enable_fec_deltas != nullptr) { - _has_bits_[0] |= 0x00000010u; - } else { - _has_bits_[0] &= ~0x00000010u; - } - enable_fec_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), enable_fec_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioNetworkAdaptations.enable_fec_deltas) -} - -// optional bytes enable_dtx_deltas = 106; -inline bool AudioNetworkAdaptations::has_enable_dtx_deltas() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void AudioNetworkAdaptations::clear_enable_dtx_deltas() { - enable_dtx_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000020u; -} -inline const std::string& AudioNetworkAdaptations::enable_dtx_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx_deltas) - return enable_dtx_deltas_.GetNoArena(); -} -inline void AudioNetworkAdaptations::set_enable_dtx_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000020u; - enable_dtx_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx_deltas) -} -inline void AudioNetworkAdaptations::set_enable_dtx_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000020u; - enable_dtx_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx_deltas) -} -inline void AudioNetworkAdaptations::set_enable_dtx_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000020u; - enable_dtx_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx_deltas) -} -inline void AudioNetworkAdaptations::set_enable_dtx_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000020u; - enable_dtx_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx_deltas) -} -inline std::string* AudioNetworkAdaptations::mutable_enable_dtx_deltas() { - _has_bits_[0] |= 0x00000020u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx_deltas) - return enable_dtx_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioNetworkAdaptations::release_enable_dtx_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx_deltas) - if (!has_enable_dtx_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000020u; - return enable_dtx_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioNetworkAdaptations::set_allocated_enable_dtx_deltas(std::string* enable_dtx_deltas) { - if (enable_dtx_deltas != nullptr) { - _has_bits_[0] |= 0x00000020u; - } else { - _has_bits_[0] &= ~0x00000020u; - } - enable_dtx_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), enable_dtx_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioNetworkAdaptations.enable_dtx_deltas) -} - -// optional bytes num_channels_deltas = 107; -inline bool AudioNetworkAdaptations::has_num_channels_deltas() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void AudioNetworkAdaptations::clear_num_channels_deltas() { - num_channels_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000040u; -} -inline const std::string& AudioNetworkAdaptations::num_channels_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AudioNetworkAdaptations.num_channels_deltas) - return num_channels_deltas_.GetNoArena(); -} -inline void AudioNetworkAdaptations::set_num_channels_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000040u; - num_channels_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AudioNetworkAdaptations.num_channels_deltas) -} -inline void AudioNetworkAdaptations::set_num_channels_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000040u; - num_channels_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.AudioNetworkAdaptations.num_channels_deltas) -} -inline void AudioNetworkAdaptations::set_num_channels_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000040u; - num_channels_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.AudioNetworkAdaptations.num_channels_deltas) -} -inline void AudioNetworkAdaptations::set_num_channels_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000040u; - num_channels_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.AudioNetworkAdaptations.num_channels_deltas) -} -inline std::string* AudioNetworkAdaptations::mutable_num_channels_deltas() { - _has_bits_[0] |= 0x00000040u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.AudioNetworkAdaptations.num_channels_deltas) - return num_channels_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* AudioNetworkAdaptations::release_num_channels_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.AudioNetworkAdaptations.num_channels_deltas) - if (!has_num_channels_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000040u; - return num_channels_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void AudioNetworkAdaptations::set_allocated_num_channels_deltas(std::string* num_channels_deltas) { - if (num_channels_deltas != nullptr) { - _has_bits_[0] |= 0x00000040u; - } else { - _has_bits_[0] &= ~0x00000040u; - } - num_channels_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), num_channels_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.AudioNetworkAdaptations.num_channels_deltas) -} - -// ------------------------------------------------------------------- - -// BweProbeCluster - -// optional int64 timestamp_ms = 1; -inline bool BweProbeCluster::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void BweProbeCluster::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 BweProbeCluster::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeCluster.timestamp_ms) - return timestamp_ms_; -} -inline void BweProbeCluster::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeCluster.timestamp_ms) -} - -// optional uint32 id = 2; -inline bool BweProbeCluster::has_id() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void BweProbeCluster::clear_id() { - id_ = 0u; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeCluster::id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeCluster.id) - return id_; -} -inline void BweProbeCluster::set_id(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000002u; - id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeCluster.id) -} - -// optional uint32 bitrate_bps = 3; -inline bool BweProbeCluster::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void BweProbeCluster::clear_bitrate_bps() { - bitrate_bps_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeCluster::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeCluster.bitrate_bps) - return bitrate_bps_; -} -inline void BweProbeCluster::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeCluster.bitrate_bps) -} - -// optional uint32 min_packets = 4; -inline bool BweProbeCluster::has_min_packets() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void BweProbeCluster::clear_min_packets() { - min_packets_ = 0u; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeCluster::min_packets() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeCluster.min_packets) - return min_packets_; -} -inline void BweProbeCluster::set_min_packets(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000008u; - min_packets_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeCluster.min_packets) -} - -// optional uint32 min_bytes = 5; -inline bool BweProbeCluster::has_min_bytes() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void BweProbeCluster::clear_min_bytes() { - min_bytes_ = 0u; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeCluster::min_bytes() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeCluster.min_bytes) - return min_bytes_; -} -inline void BweProbeCluster::set_min_bytes(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000010u; - min_bytes_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeCluster.min_bytes) -} - -// ------------------------------------------------------------------- - -// BweProbeResultSuccess - -// optional int64 timestamp_ms = 1; -inline bool BweProbeResultSuccess::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void BweProbeResultSuccess::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 BweProbeResultSuccess::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeResultSuccess.timestamp_ms) - return timestamp_ms_; -} -inline void BweProbeResultSuccess::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeResultSuccess.timestamp_ms) -} - -// optional uint32 id = 2; -inline bool BweProbeResultSuccess::has_id() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void BweProbeResultSuccess::clear_id() { - id_ = 0u; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeResultSuccess::id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeResultSuccess.id) - return id_; -} -inline void BweProbeResultSuccess::set_id(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000002u; - id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeResultSuccess.id) -} - -// optional uint32 bitrate_bps = 3; -inline bool BweProbeResultSuccess::has_bitrate_bps() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void BweProbeResultSuccess::clear_bitrate_bps() { - bitrate_bps_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeResultSuccess::bitrate_bps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeResultSuccess.bitrate_bps) - return bitrate_bps_; -} -inline void BweProbeResultSuccess::set_bitrate_bps(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - bitrate_bps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeResultSuccess.bitrate_bps) -} - -// ------------------------------------------------------------------- - -// BweProbeResultFailure - -// optional int64 timestamp_ms = 1; -inline bool BweProbeResultFailure::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void BweProbeResultFailure::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 BweProbeResultFailure::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeResultFailure.timestamp_ms) - return timestamp_ms_; -} -inline void BweProbeResultFailure::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeResultFailure.timestamp_ms) -} - -// optional uint32 id = 2; -inline bool BweProbeResultFailure::has_id() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void BweProbeResultFailure::clear_id() { - id_ = 0u; - _has_bits_[0] &= ~0x00000002u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 BweProbeResultFailure::id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeResultFailure.id) - return id_; -} -inline void BweProbeResultFailure::set_id(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000002u; - id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeResultFailure.id) -} - -// optional .webrtc.rtclog2.BweProbeResultFailure.FailureReason failure = 3; -inline bool BweProbeResultFailure::has_failure() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void BweProbeResultFailure::clear_failure() { - failure_ = 0; - _has_bits_[0] &= ~0x00000004u; -} -inline ::webrtc::rtclog2::BweProbeResultFailure_FailureReason BweProbeResultFailure::failure() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.BweProbeResultFailure.failure) - return static_cast< ::webrtc::rtclog2::BweProbeResultFailure_FailureReason >(failure_); -} -inline void BweProbeResultFailure::set_failure(::webrtc::rtclog2::BweProbeResultFailure_FailureReason value) { - assert(::webrtc::rtclog2::BweProbeResultFailure_FailureReason_IsValid(value)); - _has_bits_[0] |= 0x00000004u; - failure_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.BweProbeResultFailure.failure) -} - -// ------------------------------------------------------------------- - -// AlrState - -// optional int64 timestamp_ms = 1; -inline bool AlrState::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void AlrState::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 AlrState::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AlrState.timestamp_ms) - return timestamp_ms_; -} -inline void AlrState::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AlrState.timestamp_ms) -} - -// optional bool in_alr = 2; -inline bool AlrState::has_in_alr() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void AlrState::clear_in_alr() { - in_alr_ = false; - _has_bits_[0] &= ~0x00000002u; -} -inline bool AlrState::in_alr() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.AlrState.in_alr) - return in_alr_; -} -inline void AlrState::set_in_alr(bool value) { - _has_bits_[0] |= 0x00000002u; - in_alr_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.AlrState.in_alr) -} - -// ------------------------------------------------------------------- - -// IceCandidatePairConfig - -// optional int64 timestamp_ms = 1; -inline bool IceCandidatePairConfig::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void IceCandidatePairConfig::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 IceCandidatePairConfig::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.timestamp_ms) - return timestamp_ms_; -} -inline void IceCandidatePairConfig::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.timestamp_ms) -} - -// optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidatePairConfigType config_type = 2; -inline bool IceCandidatePairConfig::has_config_type() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void IceCandidatePairConfig::clear_config_type() { - config_type_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType IceCandidatePairConfig::config_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.config_type) - return static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType >(config_type_); -} -inline void IceCandidatePairConfig::set_config_type(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType value) { - assert(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType_IsValid(value)); - _has_bits_[0] |= 0x00000002u; - config_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.config_type) -} - -// optional uint32 candidate_pair_id = 3; -inline bool IceCandidatePairConfig::has_candidate_pair_id() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void IceCandidatePairConfig::clear_candidate_pair_id() { - candidate_pair_id_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IceCandidatePairConfig::candidate_pair_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.candidate_pair_id) - return candidate_pair_id_; -} -inline void IceCandidatePairConfig::set_candidate_pair_id(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - candidate_pair_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.candidate_pair_id) -} - -// optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType local_candidate_type = 4; -inline bool IceCandidatePairConfig::has_local_candidate_type() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void IceCandidatePairConfig::clear_local_candidate_type() { - local_candidate_type_ = 0; - _has_bits_[0] &= ~0x00000008u; -} -inline ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::local_candidate_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.local_candidate_type) - return static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType >(local_candidate_type_); -} -inline void IceCandidatePairConfig::set_local_candidate_type(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType value) { - assert(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType_IsValid(value)); - _has_bits_[0] |= 0x00000008u; - local_candidate_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.local_candidate_type) -} - -// optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol local_relay_protocol = 5; -inline bool IceCandidatePairConfig::has_local_relay_protocol() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void IceCandidatePairConfig::clear_local_relay_protocol() { - local_relay_protocol_ = 0; - _has_bits_[0] &= ~0x00000010u; -} -inline ::webrtc::rtclog2::IceCandidatePairConfig_Protocol IceCandidatePairConfig::local_relay_protocol() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.local_relay_protocol) - return static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_Protocol >(local_relay_protocol_); -} -inline void IceCandidatePairConfig::set_local_relay_protocol(::webrtc::rtclog2::IceCandidatePairConfig_Protocol value) { - assert(::webrtc::rtclog2::IceCandidatePairConfig_Protocol_IsValid(value)); - _has_bits_[0] |= 0x00000010u; - local_relay_protocol_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.local_relay_protocol) -} - -// optional .webrtc.rtclog2.IceCandidatePairConfig.NetworkType local_network_type = 6; -inline bool IceCandidatePairConfig::has_local_network_type() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void IceCandidatePairConfig::clear_local_network_type() { - local_network_type_ = 0; - _has_bits_[0] &= ~0x00000020u; -} -inline ::webrtc::rtclog2::IceCandidatePairConfig_NetworkType IceCandidatePairConfig::local_network_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.local_network_type) - return static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_NetworkType >(local_network_type_); -} -inline void IceCandidatePairConfig::set_local_network_type(::webrtc::rtclog2::IceCandidatePairConfig_NetworkType value) { - assert(::webrtc::rtclog2::IceCandidatePairConfig_NetworkType_IsValid(value)); - _has_bits_[0] |= 0x00000020u; - local_network_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.local_network_type) -} - -// optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily local_address_family = 7; -inline bool IceCandidatePairConfig::has_local_address_family() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void IceCandidatePairConfig::clear_local_address_family() { - local_address_family_ = 0; - _has_bits_[0] &= ~0x00000040u; -} -inline ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::local_address_family() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.local_address_family) - return static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily >(local_address_family_); -} -inline void IceCandidatePairConfig::set_local_address_family(::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily value) { - assert(::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily_IsValid(value)); - _has_bits_[0] |= 0x00000040u; - local_address_family_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.local_address_family) -} - -// optional .webrtc.rtclog2.IceCandidatePairConfig.IceCandidateType remote_candidate_type = 8; -inline bool IceCandidatePairConfig::has_remote_candidate_type() const { - return (_has_bits_[0] & 0x00000080u) != 0; -} -inline void IceCandidatePairConfig::clear_remote_candidate_type() { - remote_candidate_type_ = 0; - _has_bits_[0] &= ~0x00000080u; -} -inline ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType IceCandidatePairConfig::remote_candidate_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.remote_candidate_type) - return static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType >(remote_candidate_type_); -} -inline void IceCandidatePairConfig::set_remote_candidate_type(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType value) { - assert(::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType_IsValid(value)); - _has_bits_[0] |= 0x00000080u; - remote_candidate_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.remote_candidate_type) -} - -// optional .webrtc.rtclog2.IceCandidatePairConfig.AddressFamily remote_address_family = 9; -inline bool IceCandidatePairConfig::has_remote_address_family() const { - return (_has_bits_[0] & 0x00000100u) != 0; -} -inline void IceCandidatePairConfig::clear_remote_address_family() { - remote_address_family_ = 0; - _has_bits_[0] &= ~0x00000100u; -} -inline ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily IceCandidatePairConfig::remote_address_family() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.remote_address_family) - return static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily >(remote_address_family_); -} -inline void IceCandidatePairConfig::set_remote_address_family(::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily value) { - assert(::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily_IsValid(value)); - _has_bits_[0] |= 0x00000100u; - remote_address_family_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.remote_address_family) -} - -// optional .webrtc.rtclog2.IceCandidatePairConfig.Protocol candidate_pair_protocol = 10; -inline bool IceCandidatePairConfig::has_candidate_pair_protocol() const { - return (_has_bits_[0] & 0x00000200u) != 0; -} -inline void IceCandidatePairConfig::clear_candidate_pair_protocol() { - candidate_pair_protocol_ = 0; - _has_bits_[0] &= ~0x00000200u; -} -inline ::webrtc::rtclog2::IceCandidatePairConfig_Protocol IceCandidatePairConfig::candidate_pair_protocol() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairConfig.candidate_pair_protocol) - return static_cast< ::webrtc::rtclog2::IceCandidatePairConfig_Protocol >(candidate_pair_protocol_); -} -inline void IceCandidatePairConfig::set_candidate_pair_protocol(::webrtc::rtclog2::IceCandidatePairConfig_Protocol value) { - assert(::webrtc::rtclog2::IceCandidatePairConfig_Protocol_IsValid(value)); - _has_bits_[0] |= 0x00000200u; - candidate_pair_protocol_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairConfig.candidate_pair_protocol) -} - -// ------------------------------------------------------------------- - -// IceCandidatePairEvent - -// optional int64 timestamp_ms = 1; -inline bool IceCandidatePairEvent::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void IceCandidatePairEvent::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 IceCandidatePairEvent::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairEvent.timestamp_ms) - return timestamp_ms_; -} -inline void IceCandidatePairEvent::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairEvent.timestamp_ms) -} - -// optional .webrtc.rtclog2.IceCandidatePairEvent.IceCandidatePairEventType event_type = 2; -inline bool IceCandidatePairEvent::has_event_type() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void IceCandidatePairEvent::clear_event_type() { - event_type_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType IceCandidatePairEvent::event_type() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairEvent.event_type) - return static_cast< ::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType >(event_type_); -} -inline void IceCandidatePairEvent::set_event_type(::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType value) { - assert(::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType_IsValid(value)); - _has_bits_[0] |= 0x00000002u; - event_type_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairEvent.event_type) -} - -// optional uint32 candidate_pair_id = 3; -inline bool IceCandidatePairEvent::has_candidate_pair_id() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void IceCandidatePairEvent::clear_candidate_pair_id() { - candidate_pair_id_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IceCandidatePairEvent::candidate_pair_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairEvent.candidate_pair_id) - return candidate_pair_id_; -} -inline void IceCandidatePairEvent::set_candidate_pair_id(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - candidate_pair_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairEvent.candidate_pair_id) -} - -// optional uint32 transaction_id = 4; -inline bool IceCandidatePairEvent::has_transaction_id() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void IceCandidatePairEvent::clear_transaction_id() { - transaction_id_ = 0u; - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 IceCandidatePairEvent::transaction_id() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.IceCandidatePairEvent.transaction_id) - return transaction_id_; -} -inline void IceCandidatePairEvent::set_transaction_id(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000008u; - transaction_id_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.IceCandidatePairEvent.transaction_id) -} - -// ------------------------------------------------------------------- - -// DtlsTransportStateEvent - -// optional int64 timestamp_ms = 1; -inline bool DtlsTransportStateEvent::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void DtlsTransportStateEvent::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 DtlsTransportStateEvent::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DtlsTransportStateEvent.timestamp_ms) - return timestamp_ms_; -} -inline void DtlsTransportStateEvent::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DtlsTransportStateEvent.timestamp_ms) -} - -// optional .webrtc.rtclog2.DtlsTransportStateEvent.DtlsTransportState dtls_transport_state = 2; -inline bool DtlsTransportStateEvent::has_dtls_transport_state() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void DtlsTransportStateEvent::clear_dtls_transport_state() { - dtls_transport_state_ = 0; - _has_bits_[0] &= ~0x00000002u; -} -inline ::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState DtlsTransportStateEvent::dtls_transport_state() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DtlsTransportStateEvent.dtls_transport_state) - return static_cast< ::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState >(dtls_transport_state_); -} -inline void DtlsTransportStateEvent::set_dtls_transport_state(::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState value) { - assert(::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState_IsValid(value)); - _has_bits_[0] |= 0x00000002u; - dtls_transport_state_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DtlsTransportStateEvent.dtls_transport_state) -} - -// ------------------------------------------------------------------- - -// DtlsWritableState - -// optional int64 timestamp_ms = 1; -inline bool DtlsWritableState::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void DtlsWritableState::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 DtlsWritableState::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DtlsWritableState.timestamp_ms) - return timestamp_ms_; -} -inline void DtlsWritableState::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DtlsWritableState.timestamp_ms) -} - -// optional bool writable = 2; -inline bool DtlsWritableState::has_writable() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void DtlsWritableState::clear_writable() { - writable_ = false; - _has_bits_[0] &= ~0x00000002u; -} -inline bool DtlsWritableState::writable() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.DtlsWritableState.writable) - return writable_; -} -inline void DtlsWritableState::set_writable(bool value) { - _has_bits_[0] |= 0x00000002u; - writable_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.DtlsWritableState.writable) -} - -// ------------------------------------------------------------------- - -// RouteChange - -// optional int64 timestamp_ms = 1; -inline bool RouteChange::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void RouteChange::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000001u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 RouteChange::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RouteChange.timestamp_ms) - return timestamp_ms_; -} -inline void RouteChange::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RouteChange.timestamp_ms) -} - -// optional bool connected = 2; -inline bool RouteChange::has_connected() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void RouteChange::clear_connected() { - connected_ = false; - _has_bits_[0] &= ~0x00000002u; -} -inline bool RouteChange::connected() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RouteChange.connected) - return connected_; -} -inline void RouteChange::set_connected(bool value) { - _has_bits_[0] |= 0x00000002u; - connected_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RouteChange.connected) -} - -// optional uint32 overhead = 3; -inline bool RouteChange::has_overhead() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void RouteChange::clear_overhead() { - overhead_ = 0u; - _has_bits_[0] &= ~0x00000004u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 RouteChange::overhead() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RouteChange.overhead) - return overhead_; -} -inline void RouteChange::set_overhead(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000004u; - overhead_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RouteChange.overhead) -} - -// ------------------------------------------------------------------- - -// RemoteEstimates - -// optional int64 timestamp_ms = 1; -inline bool RemoteEstimates::has_timestamp_ms() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void RemoteEstimates::clear_timestamp_ms() { - timestamp_ms_ = PROTOBUF_LONGLONG(0); - _has_bits_[0] &= ~0x00000008u; -} -inline ::PROTOBUF_NAMESPACE_ID::int64 RemoteEstimates::timestamp_ms() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RemoteEstimates.timestamp_ms) - return timestamp_ms_; -} -inline void RemoteEstimates::set_timestamp_ms(::PROTOBUF_NAMESPACE_ID::int64 value) { - _has_bits_[0] |= 0x00000008u; - timestamp_ms_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RemoteEstimates.timestamp_ms) -} - -// optional uint32 link_capacity_lower_kbps = 2; -inline bool RemoteEstimates::has_link_capacity_lower_kbps() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void RemoteEstimates::clear_link_capacity_lower_kbps() { - link_capacity_lower_kbps_ = 0u; - _has_bits_[0] &= ~0x00000010u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 RemoteEstimates::link_capacity_lower_kbps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps) - return link_capacity_lower_kbps_; -} -inline void RemoteEstimates::set_link_capacity_lower_kbps(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000010u; - link_capacity_lower_kbps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps) -} - -// optional uint32 link_capacity_upper_kbps = 3; -inline bool RemoteEstimates::has_link_capacity_upper_kbps() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void RemoteEstimates::clear_link_capacity_upper_kbps() { - link_capacity_upper_kbps_ = 0u; - _has_bits_[0] &= ~0x00000020u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 RemoteEstimates::link_capacity_upper_kbps() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps) - return link_capacity_upper_kbps_; -} -inline void RemoteEstimates::set_link_capacity_upper_kbps(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000020u; - link_capacity_upper_kbps_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps) -} - -// optional uint32 number_of_deltas = 4; -inline bool RemoteEstimates::has_number_of_deltas() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void RemoteEstimates::clear_number_of_deltas() { - number_of_deltas_ = 0u; - _has_bits_[0] &= ~0x00000040u; -} -inline ::PROTOBUF_NAMESPACE_ID::uint32 RemoteEstimates::number_of_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RemoteEstimates.number_of_deltas) - return number_of_deltas_; -} -inline void RemoteEstimates::set_number_of_deltas(::PROTOBUF_NAMESPACE_ID::uint32 value) { - _has_bits_[0] |= 0x00000040u; - number_of_deltas_ = value; - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RemoteEstimates.number_of_deltas) -} - -// optional bytes timestamp_ms_deltas = 101; -inline bool RemoteEstimates::has_timestamp_ms_deltas() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void RemoteEstimates::clear_timestamp_ms_deltas() { - timestamp_ms_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000001u; -} -inline const std::string& RemoteEstimates::timestamp_ms_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RemoteEstimates.timestamp_ms_deltas) - return timestamp_ms_deltas_.GetNoArena(); -} -inline void RemoteEstimates::set_timestamp_ms_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RemoteEstimates.timestamp_ms_deltas) -} -inline void RemoteEstimates::set_timestamp_ms_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.RemoteEstimates.timestamp_ms_deltas) -} -inline void RemoteEstimates::set_timestamp_ms_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.RemoteEstimates.timestamp_ms_deltas) -} -inline void RemoteEstimates::set_timestamp_ms_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000001u; - timestamp_ms_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.RemoteEstimates.timestamp_ms_deltas) -} -inline std::string* RemoteEstimates::mutable_timestamp_ms_deltas() { - _has_bits_[0] |= 0x00000001u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.RemoteEstimates.timestamp_ms_deltas) - return timestamp_ms_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* RemoteEstimates::release_timestamp_ms_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.RemoteEstimates.timestamp_ms_deltas) - if (!has_timestamp_ms_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000001u; - return timestamp_ms_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void RemoteEstimates::set_allocated_timestamp_ms_deltas(std::string* timestamp_ms_deltas) { - if (timestamp_ms_deltas != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - timestamp_ms_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), timestamp_ms_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.RemoteEstimates.timestamp_ms_deltas) -} - -// optional bytes link_capacity_lower_kbps_deltas = 102; -inline bool RemoteEstimates::has_link_capacity_lower_kbps_deltas() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void RemoteEstimates::clear_link_capacity_lower_kbps_deltas() { - link_capacity_lower_kbps_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000002u; -} -inline const std::string& RemoteEstimates::link_capacity_lower_kbps_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps_deltas) - return link_capacity_lower_kbps_deltas_.GetNoArena(); -} -inline void RemoteEstimates::set_link_capacity_lower_kbps_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - link_capacity_lower_kbps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps_deltas) -} -inline void RemoteEstimates::set_link_capacity_lower_kbps_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000002u; - link_capacity_lower_kbps_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps_deltas) -} -inline void RemoteEstimates::set_link_capacity_lower_kbps_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000002u; - link_capacity_lower_kbps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps_deltas) -} -inline void RemoteEstimates::set_link_capacity_lower_kbps_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000002u; - link_capacity_lower_kbps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps_deltas) -} -inline std::string* RemoteEstimates::mutable_link_capacity_lower_kbps_deltas() { - _has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps_deltas) - return link_capacity_lower_kbps_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* RemoteEstimates::release_link_capacity_lower_kbps_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps_deltas) - if (!has_link_capacity_lower_kbps_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000002u; - return link_capacity_lower_kbps_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void RemoteEstimates::set_allocated_link_capacity_lower_kbps_deltas(std::string* link_capacity_lower_kbps_deltas) { - if (link_capacity_lower_kbps_deltas != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - link_capacity_lower_kbps_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), link_capacity_lower_kbps_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.RemoteEstimates.link_capacity_lower_kbps_deltas) -} - -// optional bytes link_capacity_upper_kbps_deltas = 103; -inline bool RemoteEstimates::has_link_capacity_upper_kbps_deltas() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void RemoteEstimates::clear_link_capacity_upper_kbps_deltas() { - link_capacity_upper_kbps_deltas_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _has_bits_[0] &= ~0x00000004u; -} -inline const std::string& RemoteEstimates::link_capacity_upper_kbps_deltas() const { - // @@protoc_insertion_point(field_get:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps_deltas) - return link_capacity_upper_kbps_deltas_.GetNoArena(); -} -inline void RemoteEstimates::set_link_capacity_upper_kbps_deltas(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - link_capacity_upper_kbps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps_deltas) -} -inline void RemoteEstimates::set_link_capacity_upper_kbps_deltas(std::string&& value) { - _has_bits_[0] |= 0x00000004u; - link_capacity_upper_kbps_deltas_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps_deltas) -} -inline void RemoteEstimates::set_link_capacity_upper_kbps_deltas(const char* value) { - GOOGLE_DCHECK(value != nullptr); - _has_bits_[0] |= 0x00000004u; - link_capacity_upper_kbps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps_deltas) -} -inline void RemoteEstimates::set_link_capacity_upper_kbps_deltas(const void* value, size_t size) { - _has_bits_[0] |= 0x00000004u; - link_capacity_upper_kbps_deltas_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps_deltas) -} -inline std::string* RemoteEstimates::mutable_link_capacity_upper_kbps_deltas() { - _has_bits_[0] |= 0x00000004u; - // @@protoc_insertion_point(field_mutable:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps_deltas) - return link_capacity_upper_kbps_deltas_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline std::string* RemoteEstimates::release_link_capacity_upper_kbps_deltas() { - // @@protoc_insertion_point(field_release:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps_deltas) - if (!has_link_capacity_upper_kbps_deltas()) { - return nullptr; - } - _has_bits_[0] &= ~0x00000004u; - return link_capacity_upper_kbps_deltas_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -} -inline void RemoteEstimates::set_allocated_link_capacity_upper_kbps_deltas(std::string* link_capacity_upper_kbps_deltas) { - if (link_capacity_upper_kbps_deltas != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - link_capacity_upper_kbps_deltas_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), link_capacity_upper_kbps_deltas); - // @@protoc_insertion_point(field_set_allocated:webrtc.rtclog2.RemoteEstimates.link_capacity_upper_kbps_deltas) -} - -#ifdef __GNUC__ - #pragma GCC diagnostic pop -#endif // __GNUC__ -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace rtclog2 -} // namespace webrtc - -PROTOBUF_NAMESPACE_OPEN - -template <> struct is_proto_enum< ::webrtc::rtclog2::FrameDecodedEvents_Codec> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::DelayBasedBweUpdates_DetectorState> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::BweProbeResultFailure_FailureReason> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidatePairConfigType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::IceCandidatePairConfig_IceCandidateType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::IceCandidatePairConfig_Protocol> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::IceCandidatePairConfig_AddressFamily> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::IceCandidatePairConfig_NetworkType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::IceCandidatePairEvent_IceCandidatePairEventType> : ::std::true_type {}; -template <> struct is_proto_enum< ::webrtc::rtclog2::DtlsTransportStateEvent_DtlsTransportState> : ::std::true_type {}; - -PROTOBUF_NAMESPACE_CLOSE - -// @@protoc_insertion_point(global_scope) - -#include -#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_rtc_5fevent_5flog2_2eproto diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_impl.cc b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_impl.cc index 4465d44c8..4a272f08c 100644 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_impl.cc @@ -39,6 +39,12 @@ constexpr size_t kMaxEventsInConfigHistory = 1000; std::unique_ptr CreateEncoder( RtcEventLog::EncodingType type) { switch (type) { + case RtcEventLog::EncodingType::Legacy: + RTC_LOG(LS_INFO) << "Creating legacy encoder for RTC event log."; + return std::make_unique(); + case RtcEventLog::EncodingType::NewFormat: + RTC_LOG(LS_INFO) << "Creating new format encoder for RTC event log."; + return std::make_unique(); default: RTC_LOG(LS_ERROR) << "Unknown RtcEventLog encoder type (" << int(type) << ")"; diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc index 3ff360a4f..24d5962aa 100644 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc @@ -680,10 +680,8 @@ ParsedRtcEventLog::ParseStatus StoreRtcpPackets( raw_packet_values[i])) { continue; } - const size_t data_size = raw_packet_values[i].size(); - const uint8_t* data = - reinterpret_cast(raw_packet_values[i].data()); - rtcp_packets->emplace_back(1000 * timestamp_ms, data, data_size); + std::string data(raw_packet_values[i]); + rtcp_packets->emplace_back(1000 * timestamp_ms, data); } return ParsedRtcEventLog::ParseStatus::Success(); } @@ -1095,8 +1093,7 @@ void ParsedRtcEventLog::Clear() { video_recv_configs_.clear(); video_send_configs_.clear(); - memset(last_incoming_rtcp_packet_, 0, IP_PACKET_SIZE); - last_incoming_rtcp_packet_length_ = 0; + last_incoming_rtcp_packet_.clear(); first_timestamp_ = std::numeric_limits::max(); last_timestamp_ = std::numeric_limits::min(); @@ -1224,7 +1221,9 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStream( StoreFirstAndLastTimestamp(bwe_probe_success_events()); StoreFirstAndLastTimestamp(bwe_delay_updates()); StoreFirstAndLastTimestamp(bwe_loss_updates()); - StoreFirstAndLastTimestamp(decoded_frames()); + for (const auto& frame_stream : decoded_frames()) { + StoreFirstAndLastTimestamp(frame_stream.second); + } StoreFirstAndLastTimestamp(dtls_transport_states()); StoreFirstAndLastTimestamp(dtls_writable_states()); StoreFirstAndLastTimestamp(ice_candidate_pair_configs()); @@ -1476,27 +1475,23 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreParsedLegacyEvent( } case rtclog::Event::RTCP_EVENT: { PacketDirection direction; - uint8_t packet[IP_PACKET_SIZE]; - size_t total_length; - auto status = GetRtcpPacket(event, &direction, packet, &total_length); + std::vector packet; + auto status = GetRtcpPacket(event, &direction, &packet); RTC_RETURN_IF_ERROR(status); RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us()); int64_t timestamp_us = event.timestamp_us(); - RTC_PARSE_CHECK_OR_RETURN_LE(total_length, IP_PACKET_SIZE); if (direction == kIncomingPacket) { // Currently incoming RTCP packets are logged twice, both for audio and // video. Only act on one of them. Compare against the previous parsed // incoming RTCP packet. - if (total_length == last_incoming_rtcp_packet_length_ && - memcmp(last_incoming_rtcp_packet_, packet, total_length) == 0) + if (packet == last_incoming_rtcp_packet_) break; incoming_rtcp_packets_.push_back( - LoggedRtcpPacketIncoming(timestamp_us, packet, total_length)); - last_incoming_rtcp_packet_length_ = total_length; - memcpy(last_incoming_rtcp_packet_, packet, total_length); + LoggedRtcpPacketIncoming(timestamp_us, packet)); + last_incoming_rtcp_packet_ = packet; } else { outgoing_rtcp_packets_.push_back( - LoggedRtcpPacketOutgoing(timestamp_us, packet, total_length)); + LoggedRtcpPacketOutgoing(timestamp_us, packet)); } break; } @@ -1655,12 +1650,10 @@ const RtpHeaderExtensionMap* ParsedRtcEventLog::GetRtpHeaderExtensionMap( return nullptr; } -// The packet must have space for at least IP_PACKET_SIZE bytes. ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::GetRtcpPacket( const rtclog::Event& event, PacketDirection* incoming, - uint8_t* packet, - size_t* length) const { + std::vector* packet) const { RTC_PARSE_CHECK_OR_RETURN(event.has_type()); RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::RTCP_EVENT); RTC_PARSE_CHECK_OR_RETURN(event.has_rtcp_packet()); @@ -1670,16 +1663,11 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::GetRtcpPacket( if (incoming != nullptr) { *incoming = rtcp_packet.incoming() ? kIncomingPacket : kOutgoingPacket; } - // Get packet length. - RTC_PARSE_CHECK_OR_RETURN(rtcp_packet.has_packet_data()); - if (length != nullptr) { - *length = rtcp_packet.packet_data().size(); - } // Get packet contents. + RTC_PARSE_CHECK_OR_RETURN(rtcp_packet.has_packet_data()); if (packet != nullptr) { - RTC_PARSE_CHECK_OR_RETURN_LE(rtcp_packet.packet_data().size(), - static_cast(IP_PACKET_SIZE)); - memcpy(packet, rtcp_packet.packet_data().data(), + packet->resize(rtcp_packet.packet_data().size()); + memcpy(packet->data(), rtcp_packet.packet_data().data(), rtcp_packet.packet_data().size()); } return ParseStatus::Success(); @@ -2160,7 +2148,7 @@ std::vector ParsedRtcEventLog::GetPacketInfos( // Add an offset to avoid |capture_ticks| to become negative in the case // of reordering. - constexpr int64_t kStartingCaptureTimeTicks = 90 * 48 * 1000; + constexpr int64_t kStartingCaptureTimeTicks = 90 * 48 * 10000; int64_t capture_ticks = kStartingCaptureTimeTicks + stream->unwrap_capture_ticks.Unwrap(rtp.header.timestamp); @@ -2813,7 +2801,7 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreFrameDecodedEvents( RTC_PARSE_CHECK_OR_RETURN_LE(proto.qp(), 255); base_frame.qp = static_cast(proto.qp()); - decoded_frames_.push_back(base_frame); + decoded_frames_[base_frame.ssrc].push_back(base_frame); const size_t number_of_deltas = proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u; @@ -2894,7 +2882,7 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreFrameDecodedEvents( std::numeric_limits::max()); frame.qp = static_cast(qp_values[i].value()); - decoded_frames_.push_back(frame); + decoded_frames_[frame.ssrc].push_back(frame); } return ParseStatus::Success(); } @@ -3017,13 +3005,11 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreGenericPacketSentEvent( RTC_PARSE_CHECK_OR_RETURN_EQ(overhead_length_values.size(), number_of_deltas); std::vector> payload_length_values = DecodeDeltas( - proto.payload_length_deltas(), ToUnsigned(proto.payload_length()), - number_of_deltas); // TODO(terelius): Remove ToUnsigned + proto.payload_length_deltas(), proto.payload_length(), number_of_deltas); RTC_PARSE_CHECK_OR_RETURN_EQ(payload_length_values.size(), number_of_deltas); std::vector> padding_length_values = DecodeDeltas( - proto.padding_length_deltas(), ToUnsigned(proto.padding_length()), - number_of_deltas); // TODO(terelius): Remove ToUnsigned + proto.padding_length_deltas(), proto.padding_length(), number_of_deltas); RTC_PARSE_CHECK_OR_RETURN_EQ(padding_length_values.size(), number_of_deltas); for (size_t i = 0; i < number_of_deltas; i++) { @@ -3087,10 +3073,10 @@ ParsedRtcEventLog::StoreGenericPacketReceivedEvent( int64_t packet_number; RTC_PARSE_CHECK_OR_RETURN( ToSigned(packet_number_values[i].value(), &packet_number)); - int32_t packet_length; - RTC_PARSE_CHECK_OR_RETURN( - ToSigned(packet_length_values[i].value(), - &packet_length)); // TODO(terelius): Remove ToSigned + RTC_PARSE_CHECK_OR_RETURN_LE(packet_length_values[i].value(), + std::numeric_limits::max()); + int32_t packet_length = + static_cast(packet_length_values[i].value()); generic_packets_received_.push_back( {timestamp_ms * 1000, packet_number, packet_length}); } diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_parser.h b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_parser.h index 542f1cc6e..dce075aff 100644 --- a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_parser.h +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_parser.h @@ -612,7 +612,8 @@ class ParsedRtcEventLog { } // Media - const std::vector& decoded_frames() const { + const std::map>& decoded_frames() + const { return decoded_frames_; } @@ -669,8 +670,7 @@ class ParsedRtcEventLog { // NB: The packet must have space for at least IP_PACKET_SIZE bytes. ParseStatus GetRtcpPacket(const rtclog::Event& event, PacketDirection* incoming, - uint8_t* packet, - size_t* length) const; + std::vector* packet) const; ParseStatusOr GetVideoReceiveConfig( const rtclog::Event& event) const; @@ -855,7 +855,7 @@ class ParsedRtcEventLog { std::vector dtls_transport_states_; std::vector dtls_writable_states_; - std::vector decoded_frames_; + std::map> decoded_frames_; std::vector ice_candidate_pair_configs_; std::vector ice_candidate_pair_events_; @@ -872,8 +872,7 @@ class ParsedRtcEventLog { std::vector route_change_events_; std::vector remote_estimate_events_; - uint8_t last_incoming_rtcp_packet_[IP_PACKET_SIZE]; - uint8_t last_incoming_rtcp_packet_length_; + std::vector last_incoming_rtcp_packet_; int64_t first_timestamp_; int64_t last_timestamp_; diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc new file mode 100644 index 000000000..1c13cc639 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -0,0 +1,1313 @@ +/* + * Copyright (c) 2016 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 "logging/rtc_event_log/rtc_event_log_unittest_helper.h" + +#include // memcmp + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/types/optional.h" +#include "api/array_view.h" +#include "api/rtp_headers.h" +#include "api/rtp_parameters.h" +#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h" +#include "modules/remote_bitrate_estimator/include/bwe_defines.h" +#include "modules/rtp_rtcp/include/rtp_cvo.h" +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" +#include "modules/rtp_rtcp/source/rtcp_packet/rrtr.h" +#include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h" +#include "modules/rtp_rtcp/source/rtp_header_extensions.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/buffer.h" +#include "rtc_base/checks.h" +#include "rtc_base/time_utils.h" +#include "system_wrappers/include/ntp_time.h" +#include "test/gtest.h" + +namespace webrtc { + +namespace test { + +namespace { + +struct ExtensionPair { + RTPExtensionType type; + const char* name; +}; + +constexpr int kMaxCsrcs = 3; + +// Maximum serialized size of a header extension, including 1 byte ID. +constexpr int kMaxExtensionSizeBytes = 4; +constexpr int kMaxNumExtensions = 5; + +constexpr ExtensionPair kExtensions[kMaxNumExtensions] = { + {RTPExtensionType::kRtpExtensionTransmissionTimeOffset, + RtpExtension::kTimestampOffsetUri}, + {RTPExtensionType::kRtpExtensionAbsoluteSendTime, + RtpExtension::kAbsSendTimeUri}, + {RTPExtensionType::kRtpExtensionTransportSequenceNumber, + RtpExtension::kTransportSequenceNumberUri}, + {RTPExtensionType::kRtpExtensionAudioLevel, RtpExtension::kAudioLevelUri}, + {RTPExtensionType::kRtpExtensionVideoRotation, + RtpExtension::kVideoRotationUri}}; + +template +void ShuffleInPlace(Random* prng, rtc::ArrayView array) { + RTC_DCHECK_LE(array.size(), std::numeric_limits::max()); + for (uint32_t i = 0; i + 1 < array.size(); i++) { + uint32_t other = prng->Rand(i, static_cast(array.size() - 1)); + std::swap(array[i], array[other]); + } +} + +absl::optional GetExtensionId(const std::vector& extensions, + const std::string& uri) { + for (const auto& extension : extensions) { + if (extension.uri == uri) + return extension.id; + } + return absl::nullopt; +} + +} // namespace + +std::unique_ptr EventGenerator::NewAlrState() { + return std::make_unique(prng_.Rand()); +} + +std::unique_ptr EventGenerator::NewAudioPlayout( + uint32_t ssrc) { + return std::make_unique(ssrc); +} + +std::unique_ptr +EventGenerator::NewAudioNetworkAdaptation() { + std::unique_ptr config = + std::make_unique(); + + config->bitrate_bps = prng_.Rand(0, 3000000); + config->enable_fec = prng_.Rand(); + config->enable_dtx = prng_.Rand(); + config->frame_length_ms = prng_.Rand(10, 120); + config->num_channels = prng_.Rand(1, 2); + config->uplink_packet_loss_fraction = prng_.Rand(); + + return std::make_unique(std::move(config)); +} + +std::unique_ptr +EventGenerator::NewBweUpdateDelayBased() { + constexpr int32_t kMaxBweBps = 20000000; + int32_t bitrate_bps = prng_.Rand(0, kMaxBweBps); + BandwidthUsage state = static_cast( + prng_.Rand(static_cast(BandwidthUsage::kLast) - 1)); + return std::make_unique(bitrate_bps, state); +} + +std::unique_ptr +EventGenerator::NewBweUpdateLossBased() { + constexpr int32_t kMaxBweBps = 20000000; + constexpr int32_t kMaxPackets = 1000; + int32_t bitrate_bps = prng_.Rand(0, kMaxBweBps); + uint8_t fraction_lost = prng_.Rand(); + int32_t total_packets = prng_.Rand(1, kMaxPackets); + + return std::make_unique( + bitrate_bps, fraction_lost, total_packets); +} + +std::unique_ptr +EventGenerator::NewDtlsTransportState() { + DtlsTransportState state = static_cast( + prng_.Rand(static_cast(DtlsTransportState::kNumValues) - 1)); + + return std::make_unique(state); +} + +std::unique_ptr +EventGenerator::NewDtlsWritableState() { + bool writable = prng_.Rand(); + return std::make_unique(writable); +} + +std::unique_ptr EventGenerator::NewFrameDecodedEvent( + uint32_t ssrc) { + constexpr int kMinRenderDelayMs = 1; + constexpr int kMaxRenderDelayMs = 2000000; + constexpr int kMaxWidth = 15360; + constexpr int kMaxHeight = 8640; + constexpr int kMinWidth = 16; + constexpr int kMinHeight = 16; + constexpr int kNumCodecTypes = 5; + + constexpr VideoCodecType kCodecList[kNumCodecTypes] = { + kVideoCodecGeneric, kVideoCodecVP8, kVideoCodecVP9, kVideoCodecAV1, + kVideoCodecH264}; + const int64_t render_time_ms = + rtc::TimeMillis() + prng_.Rand(kMinRenderDelayMs, kMaxRenderDelayMs); + const int width = prng_.Rand(kMinWidth, kMaxWidth); + const int height = prng_.Rand(kMinHeight, kMaxHeight); + const VideoCodecType codec = kCodecList[prng_.Rand(0, kNumCodecTypes - 1)]; + const uint8_t qp = prng_.Rand(); + return std::make_unique(render_time_ms, ssrc, width, + height, codec, qp); +} + +std::unique_ptr +EventGenerator::NewProbeClusterCreated() { + constexpr int kMaxBweBps = 20000000; + constexpr int kMaxNumProbes = 10000; + int id = prng_.Rand(1, kMaxNumProbes); + int bitrate_bps = prng_.Rand(0, kMaxBweBps); + int min_probes = prng_.Rand(5, 50); + int min_bytes = prng_.Rand(500, 50000); + + return std::make_unique(id, bitrate_bps, + min_probes, min_bytes); +} + +std::unique_ptr +EventGenerator::NewProbeResultFailure() { + constexpr int kMaxNumProbes = 10000; + int id = prng_.Rand(1, kMaxNumProbes); + ProbeFailureReason reason = static_cast( + prng_.Rand(static_cast(ProbeFailureReason::kLast) - 1)); + + return std::make_unique(id, reason); +} + +std::unique_ptr +EventGenerator::NewProbeResultSuccess() { + constexpr int kMaxBweBps = 20000000; + constexpr int kMaxNumProbes = 10000; + int id = prng_.Rand(1, kMaxNumProbes); + int bitrate_bps = prng_.Rand(0, kMaxBweBps); + + return std::make_unique(id, bitrate_bps); +} + +std::unique_ptr +EventGenerator::NewIceCandidatePairConfig() { + IceCandidateType local_candidate_type = static_cast( + prng_.Rand(static_cast(IceCandidateType::kNumValues) - 1)); + IceCandidateNetworkType local_network_type = + static_cast(prng_.Rand( + static_cast(IceCandidateNetworkType::kNumValues) - 1)); + IceCandidatePairAddressFamily local_address_family = + static_cast(prng_.Rand( + static_cast(IceCandidatePairAddressFamily::kNumValues) - + 1)); + IceCandidateType remote_candidate_type = static_cast( + prng_.Rand(static_cast(IceCandidateType::kNumValues) - 1)); + IceCandidatePairAddressFamily remote_address_family = + static_cast(prng_.Rand( + static_cast(IceCandidatePairAddressFamily::kNumValues) - + 1)); + IceCandidatePairProtocol protocol_type = + static_cast(prng_.Rand( + static_cast(IceCandidatePairProtocol::kNumValues) - 1)); + + IceCandidatePairDescription desc; + desc.local_candidate_type = local_candidate_type; + desc.local_relay_protocol = protocol_type; + desc.local_network_type = local_network_type; + desc.local_address_family = local_address_family; + desc.remote_candidate_type = remote_candidate_type; + desc.remote_address_family = remote_address_family; + desc.candidate_pair_protocol = protocol_type; + + IceCandidatePairConfigType type = + static_cast(prng_.Rand( + static_cast(IceCandidatePairConfigType::kNumValues) - 1)); + uint32_t pair_id = prng_.Rand(); + return std::make_unique(type, pair_id, desc); +} + +std::unique_ptr +EventGenerator::NewIceCandidatePair() { + IceCandidatePairEventType type = + static_cast(prng_.Rand( + static_cast(IceCandidatePairEventType::kNumValues) - 1)); + uint32_t pair_id = prng_.Rand(); + uint32_t transaction_id = prng_.Rand(); + + return std::make_unique(type, pair_id, + transaction_id); +} + +rtcp::ReportBlock EventGenerator::NewReportBlock() { + rtcp::ReportBlock report_block; + report_block.SetMediaSsrc(prng_.Rand()); + report_block.SetFractionLost(prng_.Rand()); + // cumulative_lost is a 3-byte signed value. + RTC_DCHECK(report_block.SetCumulativeLost( + prng_.Rand(-(1 << 23) + 1, (1 << 23) - 1))); + report_block.SetExtHighestSeqNum(prng_.Rand()); + report_block.SetJitter(prng_.Rand()); + report_block.SetLastSr(prng_.Rand()); + report_block.SetDelayLastSr(prng_.Rand()); + return report_block; +} + +rtcp::SenderReport EventGenerator::NewSenderReport() { + rtcp::SenderReport sender_report; + sender_report.SetSenderSsrc(prng_.Rand()); + sender_report.SetNtp(NtpTime(prng_.Rand(), prng_.Rand())); + sender_report.SetRtpTimestamp(prng_.Rand()); + sender_report.SetPacketCount(prng_.Rand()); + sender_report.SetOctetCount(prng_.Rand()); + sender_report.AddReportBlock(NewReportBlock()); + return sender_report; +} + +rtcp::ReceiverReport EventGenerator::NewReceiverReport() { + rtcp::ReceiverReport receiver_report; + receiver_report.SetSenderSsrc(prng_.Rand()); + receiver_report.AddReportBlock(NewReportBlock()); + return receiver_report; +} + +rtcp::ExtendedReports EventGenerator::NewExtendedReports() { + rtcp::ExtendedReports extended_report; + extended_report.SetSenderSsrc(prng_.Rand()); + + rtcp::Rrtr rrtr; + rrtr.SetNtp(NtpTime(prng_.Rand(), prng_.Rand())); + extended_report.SetRrtr(rrtr); + + rtcp::ReceiveTimeInfo time_info( + prng_.Rand(), prng_.Rand(), prng_.Rand()); + extended_report.AddDlrrItem(time_info); + + rtcp::TargetBitrate target_bitrate; + target_bitrate.AddTargetBitrate(/*spatial layer*/ prng_.Rand(0, 3), + /*temporal layer*/ prng_.Rand(0, 3), + /*bitrate kbps*/ prng_.Rand(0, 50000)); + target_bitrate.AddTargetBitrate(/*spatial layer*/ prng_.Rand(4, 7), + /*temporal layer*/ prng_.Rand(4, 7), + /*bitrate kbps*/ prng_.Rand(0, 50000)); + extended_report.SetTargetBitrate(target_bitrate); + return extended_report; +} + +rtcp::Nack EventGenerator::NewNack() { + rtcp::Nack nack; + uint16_t base_seq_no = prng_.Rand(); + std::vector nack_list; + nack_list.push_back(base_seq_no); + for (uint16_t i = 1u; i < 10u; i++) { + if (prng_.Rand()) + nack_list.push_back(base_seq_no + i); + } + nack.SetPacketIds(nack_list); + return nack; +} + +rtcp::Fir EventGenerator::NewFir() { + rtcp::Fir fir; + fir.SetSenderSsrc(prng_.Rand()); + fir.AddRequestTo(/*ssrc*/ prng_.Rand(), + /*seq num*/ prng_.Rand()); + fir.AddRequestTo(/*ssrc*/ prng_.Rand(), + /*seq num*/ prng_.Rand()); + return fir; +} + +rtcp::Pli EventGenerator::NewPli() { + rtcp::Pli pli; + pli.SetSenderSsrc(prng_.Rand()); + pli.SetMediaSsrc(prng_.Rand()); + return pli; +} + +rtcp::TransportFeedback EventGenerator::NewTransportFeedback() { + rtcp::TransportFeedback transport_feedback; + uint16_t base_seq_no = prng_.Rand(); + int64_t base_time_us = prng_.Rand(); + transport_feedback.SetBase(base_seq_no, base_time_us); + transport_feedback.AddReceivedPacket(base_seq_no, base_time_us); + int64_t time_us = base_time_us; + for (uint16_t i = 1u; i < 10u; i++) { + time_us += prng_.Rand(0, 100000); + if (prng_.Rand()) { + transport_feedback.AddReceivedPacket(base_seq_no + i, time_us); + } + } + return transport_feedback; +} + +rtcp::Remb EventGenerator::NewRemb() { + rtcp::Remb remb; + // The remb bitrate is transported as a 16-bit mantissa and an 8-bit exponent. + uint64_t bitrate_bps = prng_.Rand(0, (1 << 16) - 1) << prng_.Rand(7); + std::vector ssrcs{prng_.Rand(), prng_.Rand()}; + remb.SetSsrcs(ssrcs); + remb.SetBitrateBps(bitrate_bps); + return remb; +} + +rtcp::LossNotification EventGenerator::NewLossNotification() { + rtcp::LossNotification loss_notification; + const uint16_t last_decoded = prng_.Rand(); + const uint16_t last_received = + last_decoded + (prng_.Rand() & 0x7fff); + const bool decodability_flag = prng_.Rand(); + EXPECT_TRUE( + loss_notification.Set(last_decoded, last_received, decodability_flag)); + return loss_notification; +} + +std::unique_ptr EventGenerator::NewRouteChange() { + return std::make_unique(prng_.Rand(), + prng_.Rand(0, 128)); +} + +std::unique_ptr EventGenerator::NewRemoteEstimate() { + return std::make_unique( + DataRate::KilobitsPerSec(prng_.Rand(0, 100000)), + DataRate::KilobitsPerSec(prng_.Rand(0, 100000))); +} + +std::unique_ptr +EventGenerator::NewRtcpPacketIncoming() { + enum class SupportedRtcpTypes { + kSenderReport = 0, + kReceiverReport, + kExtendedReports, + kFir, + kPli, + kNack, + kRemb, + kTransportFeedback, + kNumValues + }; + SupportedRtcpTypes type = static_cast( + prng_.Rand(0, static_cast(SupportedRtcpTypes::kNumValues) - 1)); + switch (type) { + case SupportedRtcpTypes::kSenderReport: { + rtcp::SenderReport sender_report = NewSenderReport(); + rtc::Buffer buffer = sender_report.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kReceiverReport: { + rtcp::ReceiverReport receiver_report = NewReceiverReport(); + rtc::Buffer buffer = receiver_report.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kExtendedReports: { + rtcp::ExtendedReports extended_report = NewExtendedReports(); + rtc::Buffer buffer = extended_report.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kFir: { + rtcp::Fir fir = NewFir(); + rtc::Buffer buffer = fir.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kPli: { + rtcp::Pli pli = NewPli(); + rtc::Buffer buffer = pli.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kNack: { + rtcp::Nack nack = NewNack(); + rtc::Buffer buffer = nack.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kRemb: { + rtcp::Remb remb = NewRemb(); + rtc::Buffer buffer = remb.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kTransportFeedback: { + rtcp::TransportFeedback transport_feedback = NewTransportFeedback(); + rtc::Buffer buffer = transport_feedback.Build(); + return std::make_unique(buffer); + } + default: + RTC_NOTREACHED(); + rtc::Buffer buffer; + return std::make_unique(buffer); + } +} + +std::unique_ptr +EventGenerator::NewRtcpPacketOutgoing() { + enum class SupportedRtcpTypes { + kSenderReport = 0, + kReceiverReport, + kExtendedReports, + kFir, + kPli, + kNack, + kRemb, + kTransportFeedback, + kNumValues + }; + SupportedRtcpTypes type = static_cast( + prng_.Rand(0, static_cast(SupportedRtcpTypes::kNumValues) - 1)); + switch (type) { + case SupportedRtcpTypes::kSenderReport: { + rtcp::SenderReport sender_report = NewSenderReport(); + rtc::Buffer buffer = sender_report.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kReceiverReport: { + rtcp::ReceiverReport receiver_report = NewReceiverReport(); + rtc::Buffer buffer = receiver_report.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kExtendedReports: { + rtcp::ExtendedReports extended_report = NewExtendedReports(); + rtc::Buffer buffer = extended_report.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kFir: { + rtcp::Fir fir = NewFir(); + rtc::Buffer buffer = fir.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kPli: { + rtcp::Pli pli = NewPli(); + rtc::Buffer buffer = pli.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kNack: { + rtcp::Nack nack = NewNack(); + rtc::Buffer buffer = nack.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kRemb: { + rtcp::Remb remb = NewRemb(); + rtc::Buffer buffer = remb.Build(); + return std::make_unique(buffer); + } + case SupportedRtcpTypes::kTransportFeedback: { + rtcp::TransportFeedback transport_feedback = NewTransportFeedback(); + rtc::Buffer buffer = transport_feedback.Build(); + return std::make_unique(buffer); + } + default: + RTC_NOTREACHED(); + rtc::Buffer buffer; + return std::make_unique(buffer); + } +} + +std::unique_ptr +EventGenerator::NewGenericPacketSent() { + return std::make_unique( + sent_packet_number_++, prng_.Rand(40, 50), prng_.Rand(0, 150), + prng_.Rand(0, 1000)); +} +std::unique_ptr +EventGenerator::NewGenericPacketReceived() { + return std::make_unique( + received_packet_number_++, prng_.Rand(40, 250)); +} +std::unique_ptr +EventGenerator::NewGenericAckReceived() { + absl::optional receive_timestamp = absl::nullopt; + if (prng_.Rand(0, 2) > 0) { + receive_timestamp = prng_.Rand(0, 100000); + } + AckedPacket packet = {prng_.Rand(40, 250), receive_timestamp}; + return std::move(RtcEventGenericAckReceived::CreateLogs( + received_packet_number_++, std::vector{packet})[0]); +} + +void EventGenerator::RandomizeRtpPacket( + size_t payload_size, + size_t padding_size, + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map, + RtpPacket* rtp_packet, + bool all_configured_exts) { + constexpr int kMaxPayloadType = 127; + rtp_packet->SetPayloadType(prng_.Rand(kMaxPayloadType)); + rtp_packet->SetMarker(prng_.Rand()); + rtp_packet->SetSequenceNumber(prng_.Rand()); + rtp_packet->SetSsrc(ssrc); + rtp_packet->SetTimestamp(prng_.Rand()); + + uint32_t csrcs_count = prng_.Rand(0, kMaxCsrcs); + std::vector csrcs; + for (size_t i = 0; i < csrcs_count; i++) { + csrcs.push_back(prng_.Rand()); + } + rtp_packet->SetCsrcs(csrcs); + + if (extension_map.IsRegistered(TransmissionOffset::kId) && + (all_configured_exts || prng_.Rand())) { + rtp_packet->SetExtension(prng_.Rand(0x00ffffff)); + } + + if (extension_map.IsRegistered(AudioLevel::kId) && + (all_configured_exts || prng_.Rand())) { + rtp_packet->SetExtension(prng_.Rand(), prng_.Rand(127)); + } + + if (extension_map.IsRegistered(AbsoluteSendTime::kId) && + (all_configured_exts || prng_.Rand())) { + rtp_packet->SetExtension(prng_.Rand(0x00ffffff)); + } + + if (extension_map.IsRegistered(VideoOrientation::kId) && + (all_configured_exts || prng_.Rand())) { + rtp_packet->SetExtension(prng_.Rand(3)); + } + + if (extension_map.IsRegistered(TransportSequenceNumber::kId) && + (all_configured_exts || prng_.Rand())) { + rtp_packet->SetExtension(prng_.Rand()); + } + + RTC_CHECK_LE(rtp_packet->headers_size() + payload_size, IP_PACKET_SIZE); + + uint8_t* payload = rtp_packet->AllocatePayload(payload_size); + RTC_DCHECK(payload != nullptr); + for (size_t i = 0; i < payload_size; i++) { + payload[i] = prng_.Rand(); + } + RTC_CHECK(rtp_packet->SetPadding(padding_size)); +} + +std::unique_ptr EventGenerator::NewRtpPacketIncoming( + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map, + bool all_configured_exts) { + constexpr size_t kMaxPaddingLength = 224; + const bool padding = prng_.Rand(0, 9) == 0; // Let padding be 10% probable. + const size_t padding_size = !padding ? 0u : prng_.Rand(0u, kMaxPaddingLength); + + // 12 bytes RTP header, 4 bytes for 0xBEDE + alignment, 4 bytes per CSRC. + constexpr size_t kMaxHeaderSize = + 16 + 4 * kMaxCsrcs + kMaxExtensionSizeBytes * kMaxNumExtensions; + + // In principle, a packet can contain both padding and other payload. + // Currently, RTC eventlog encoder-parser can only maintain padding length if + // packet is full padding. + // TODO(webrtc:9730): Remove the deterministic logic for padding_size > 0. + size_t payload_size = + padding_size > 0 ? 0 + : prng_.Rand(0u, static_cast(IP_PACKET_SIZE - + 1 - padding_size - + kMaxHeaderSize)); + + RtpPacketReceived rtp_packet(&extension_map); + RandomizeRtpPacket(payload_size, padding_size, ssrc, extension_map, + &rtp_packet, all_configured_exts); + + return std::make_unique(rtp_packet); +} + +std::unique_ptr EventGenerator::NewRtpPacketOutgoing( + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map, + bool all_configured_exts) { + constexpr size_t kMaxPaddingLength = 224; + const bool padding = prng_.Rand(0, 9) == 0; // Let padding be 10% probable. + const size_t padding_size = !padding ? 0u : prng_.Rand(0u, kMaxPaddingLength); + + // 12 bytes RTP header, 4 bytes for 0xBEDE + alignment, 4 bytes per CSRC. + constexpr size_t kMaxHeaderSize = + 16 + 4 * kMaxCsrcs + kMaxExtensionSizeBytes * kMaxNumExtensions; + + // In principle,a packet can contain both padding and other payload. + // Currently, RTC eventlog encoder-parser can only maintain padding length if + // packet is full padding. + // TODO(webrtc:9730): Remove the deterministic logic for padding_size > 0. + size_t payload_size = + padding_size > 0 ? 0 + : prng_.Rand(0u, static_cast(IP_PACKET_SIZE - + 1 - padding_size - + kMaxHeaderSize)); + + RtpPacketToSend rtp_packet(&extension_map, + kMaxHeaderSize + payload_size + padding_size); + RandomizeRtpPacket(payload_size, padding_size, ssrc, extension_map, + &rtp_packet, all_configured_exts); + + int probe_cluster_id = prng_.Rand(0, 100000); + return std::make_unique(rtp_packet, + probe_cluster_id); +} + +RtpHeaderExtensionMap EventGenerator::NewRtpHeaderExtensionMap( + bool configure_all) { + RtpHeaderExtensionMap extension_map; + std::vector id(RtpExtension::kOneByteHeaderExtensionMaxId - + RtpExtension::kMinId + 1); + std::iota(id.begin(), id.end(), RtpExtension::kMinId); + ShuffleInPlace(&prng_, rtc::ArrayView(id)); + + if (configure_all || prng_.Rand()) { + extension_map.Register(id[0]); + } + if (configure_all || prng_.Rand()) { + extension_map.Register(id[1]); + } + if (configure_all || prng_.Rand()) { + extension_map.Register(id[2]); + } + if (configure_all || prng_.Rand()) { + extension_map.Register(id[3]); + } + if (configure_all || prng_.Rand()) { + extension_map.Register(id[4]); + } + + return extension_map; +} + +std::unique_ptr +EventGenerator::NewAudioReceiveStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions) { + auto config = std::make_unique(); + // Add SSRCs for the stream. + config->remote_ssrc = ssrc; + config->local_ssrc = prng_.Rand(); + // Add header extensions. + for (size_t i = 0; i < kMaxNumExtensions; i++) { + uint8_t id = extensions.GetId(kExtensions[i].type); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensions[i].name, id); + } + } + + return std::make_unique(std::move(config)); +} + +std::unique_ptr +EventGenerator::NewAudioSendStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions) { + auto config = std::make_unique(); + // Add SSRC to the stream. + config->local_ssrc = ssrc; + // Add header extensions. + for (size_t i = 0; i < kMaxNumExtensions; i++) { + uint8_t id = extensions.GetId(kExtensions[i].type); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensions[i].name, id); + } + } + return std::make_unique(std::move(config)); +} + +std::unique_ptr +EventGenerator::NewVideoReceiveStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions) { + auto config = std::make_unique(); + + // Add SSRCs for the stream. + config->remote_ssrc = ssrc; + config->local_ssrc = prng_.Rand(); + // Add extensions and settings for RTCP. + config->rtcp_mode = + prng_.Rand() ? RtcpMode::kCompound : RtcpMode::kReducedSize; + config->remb = prng_.Rand(); + config->rtx_ssrc = prng_.Rand(); + config->codecs.emplace_back(prng_.Rand() ? "VP8" : "H264", + prng_.Rand(127), prng_.Rand(127)); + // Add header extensions. + for (size_t i = 0; i < kMaxNumExtensions; i++) { + uint8_t id = extensions.GetId(kExtensions[i].type); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensions[i].name, id); + } + } + return std::make_unique(std::move(config)); +} + +std::unique_ptr +EventGenerator::NewVideoSendStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions) { + auto config = std::make_unique(); + + config->codecs.emplace_back(prng_.Rand() ? "VP8" : "H264", + prng_.Rand(127), prng_.Rand(127)); + config->local_ssrc = ssrc; + config->rtx_ssrc = prng_.Rand(); + // Add header extensions. + for (size_t i = 0; i < kMaxNumExtensions; i++) { + uint8_t id = extensions.GetId(kExtensions[i].type); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensions[i].name, id); + } + } + return std::make_unique(std::move(config)); +} + +void EventVerifier::VerifyLoggedAlrStateEvent( + const RtcEventAlrState& original_event, + const LoggedAlrStateEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.in_alr(), logged_event.in_alr); +} + +void EventVerifier::VerifyLoggedAudioPlayoutEvent( + const RtcEventAudioPlayout& original_event, + const LoggedAudioPlayoutEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.ssrc(), logged_event.ssrc); +} + +void EventVerifier::VerifyLoggedAudioNetworkAdaptationEvent( + const RtcEventAudioNetworkAdaptation& original_event, + const LoggedAudioNetworkAdaptationEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + + EXPECT_EQ(original_event.config().bitrate_bps, + logged_event.config.bitrate_bps); + EXPECT_EQ(original_event.config().enable_dtx, logged_event.config.enable_dtx); + EXPECT_EQ(original_event.config().enable_fec, logged_event.config.enable_fec); + EXPECT_EQ(original_event.config().frame_length_ms, + logged_event.config.frame_length_ms); + EXPECT_EQ(original_event.config().num_channels, + logged_event.config.num_channels); + + // uplink_packet_loss_fraction + ASSERT_EQ(original_event.config().uplink_packet_loss_fraction.has_value(), + logged_event.config.uplink_packet_loss_fraction.has_value()); + if (original_event.config().uplink_packet_loss_fraction.has_value()) { + const float original = + original_event.config().uplink_packet_loss_fraction.value(); + const float logged = + logged_event.config.uplink_packet_loss_fraction.value(); + const float uplink_packet_loss_fraction_delta = std::abs(original - logged); + EXPECT_LE(uplink_packet_loss_fraction_delta, 0.0001f); + } +} + +void EventVerifier::VerifyLoggedBweDelayBasedUpdate( + const RtcEventBweUpdateDelayBased& original_event, + const LoggedBweDelayBasedUpdate& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.bitrate_bps(), logged_event.bitrate_bps); + EXPECT_EQ(original_event.detector_state(), logged_event.detector_state); +} + +void EventVerifier::VerifyLoggedBweLossBasedUpdate( + const RtcEventBweUpdateLossBased& original_event, + const LoggedBweLossBasedUpdate& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.bitrate_bps(), logged_event.bitrate_bps); + EXPECT_EQ(original_event.fraction_loss(), logged_event.fraction_lost); + EXPECT_EQ(original_event.total_packets(), logged_event.expected_packets); +} + +void EventVerifier::VerifyLoggedBweProbeClusterCreatedEvent( + const RtcEventProbeClusterCreated& original_event, + const LoggedBweProbeClusterCreatedEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.id(), logged_event.id); + EXPECT_EQ(original_event.bitrate_bps(), logged_event.bitrate_bps); + EXPECT_EQ(original_event.min_probes(), logged_event.min_packets); + EXPECT_EQ(original_event.min_bytes(), logged_event.min_bytes); +} + +void EventVerifier::VerifyLoggedBweProbeFailureEvent( + const RtcEventProbeResultFailure& original_event, + const LoggedBweProbeFailureEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.id(), logged_event.id); + EXPECT_EQ(original_event.failure_reason(), logged_event.failure_reason); +} + +void EventVerifier::VerifyLoggedBweProbeSuccessEvent( + const RtcEventProbeResultSuccess& original_event, + const LoggedBweProbeSuccessEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.id(), logged_event.id); + EXPECT_EQ(original_event.bitrate_bps(), logged_event.bitrate_bps); +} + +void EventVerifier::VerifyLoggedDtlsTransportState( + const RtcEventDtlsTransportState& original_event, + const LoggedDtlsTransportState& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.dtls_transport_state(), + logged_event.dtls_transport_state); +} + +void EventVerifier::VerifyLoggedDtlsWritableState( + const RtcEventDtlsWritableState& original_event, + const LoggedDtlsWritableState& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.writable(), logged_event.writable); +} + +void EventVerifier::VerifyLoggedFrameDecoded( + const RtcEventFrameDecoded& original_event, + const LoggedFrameDecoded& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.ssrc(), logged_event.ssrc); + EXPECT_EQ(original_event.render_time_ms(), logged_event.render_time_ms); + EXPECT_EQ(original_event.width(), logged_event.width); + EXPECT_EQ(original_event.height(), logged_event.height); + EXPECT_EQ(original_event.codec(), logged_event.codec); + EXPECT_EQ(original_event.qp(), logged_event.qp); +} + +void EventVerifier::VerifyLoggedIceCandidatePairConfig( + const RtcEventIceCandidatePairConfig& original_event, + const LoggedIceCandidatePairConfig& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + + EXPECT_EQ(original_event.type(), logged_event.type); + EXPECT_EQ(original_event.candidate_pair_id(), logged_event.candidate_pair_id); + EXPECT_EQ(original_event.candidate_pair_desc().local_candidate_type, + logged_event.local_candidate_type); + EXPECT_EQ(original_event.candidate_pair_desc().local_relay_protocol, + logged_event.local_relay_protocol); + EXPECT_EQ(original_event.candidate_pair_desc().local_network_type, + logged_event.local_network_type); + EXPECT_EQ(original_event.candidate_pair_desc().local_address_family, + logged_event.local_address_family); + EXPECT_EQ(original_event.candidate_pair_desc().remote_candidate_type, + logged_event.remote_candidate_type); + EXPECT_EQ(original_event.candidate_pair_desc().remote_address_family, + logged_event.remote_address_family); + EXPECT_EQ(original_event.candidate_pair_desc().candidate_pair_protocol, + logged_event.candidate_pair_protocol); +} + +void EventVerifier::VerifyLoggedIceCandidatePairEvent( + const RtcEventIceCandidatePair& original_event, + const LoggedIceCandidatePairEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + + EXPECT_EQ(original_event.type(), logged_event.type); + EXPECT_EQ(original_event.candidate_pair_id(), logged_event.candidate_pair_id); + if (encoding_type_ == RtcEventLog::EncodingType::NewFormat) { + EXPECT_EQ(original_event.transaction_id(), logged_event.transaction_id); + } +} + +void VerifyLoggedRtpHeader(const RtpPacket& original_header, + const RTPHeader& logged_header) { + // Standard RTP header. + EXPECT_EQ(original_header.Marker(), logged_header.markerBit); + EXPECT_EQ(original_header.PayloadType(), logged_header.payloadType); + EXPECT_EQ(original_header.SequenceNumber(), logged_header.sequenceNumber); + EXPECT_EQ(original_header.Timestamp(), logged_header.timestamp); + EXPECT_EQ(original_header.Ssrc(), logged_header.ssrc); + + EXPECT_EQ(original_header.headers_size(), logged_header.headerLength); + + // TransmissionOffset header extension. + ASSERT_EQ(original_header.HasExtension(), + logged_header.extension.hasTransmissionTimeOffset); + if (logged_header.extension.hasTransmissionTimeOffset) { + int32_t offset; + ASSERT_TRUE(original_header.GetExtension(&offset)); + EXPECT_EQ(offset, logged_header.extension.transmissionTimeOffset); + } + + // AbsoluteSendTime header extension. + ASSERT_EQ(original_header.HasExtension(), + logged_header.extension.hasAbsoluteSendTime); + if (logged_header.extension.hasAbsoluteSendTime) { + uint32_t sendtime; + ASSERT_TRUE(original_header.GetExtension(&sendtime)); + EXPECT_EQ(sendtime, logged_header.extension.absoluteSendTime); + } + + // TransportSequenceNumber header extension. + ASSERT_EQ(original_header.HasExtension(), + logged_header.extension.hasTransportSequenceNumber); + if (logged_header.extension.hasTransportSequenceNumber) { + uint16_t seqnum; + ASSERT_TRUE(original_header.GetExtension(&seqnum)); + EXPECT_EQ(seqnum, logged_header.extension.transportSequenceNumber); + } + + // AudioLevel header extension. + ASSERT_EQ(original_header.HasExtension(), + logged_header.extension.hasAudioLevel); + if (logged_header.extension.hasAudioLevel) { + bool voice_activity; + uint8_t audio_level; + ASSERT_TRUE(original_header.GetExtension(&voice_activity, + &audio_level)); + EXPECT_EQ(voice_activity, logged_header.extension.voiceActivity); + EXPECT_EQ(audio_level, logged_header.extension.audioLevel); + } + + // VideoOrientation header extension. + ASSERT_EQ(original_header.HasExtension(), + logged_header.extension.hasVideoRotation); + if (logged_header.extension.hasVideoRotation) { + uint8_t rotation; + ASSERT_TRUE(original_header.GetExtension(&rotation)); + EXPECT_EQ(ConvertCVOByteToVideoRotation(rotation), + logged_header.extension.videoRotation); + } +} + +void EventVerifier::VerifyLoggedRouteChangeEvent( + const RtcEventRouteChange& original_event, + const LoggedRouteChangeEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.connected(), logged_event.connected); + EXPECT_EQ(original_event.overhead(), logged_event.overhead); +} + +void EventVerifier::VerifyLoggedRemoteEstimateEvent( + const RtcEventRemoteEstimate& original_event, + const LoggedRemoteEstimateEvent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.link_capacity_lower_, + logged_event.link_capacity_lower); + EXPECT_EQ(original_event.link_capacity_upper_, + logged_event.link_capacity_upper); +} + +void EventVerifier::VerifyLoggedRtpPacketIncoming( + const RtcEventRtpPacketIncoming& original_event, + const LoggedRtpPacketIncoming& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + + EXPECT_EQ(original_event.header().headers_size(), + logged_event.rtp.header_length); + + EXPECT_EQ(original_event.packet_length(), logged_event.rtp.total_length); + + // Currently, RTC eventlog encoder-parser can only maintain padding length + // if packet is full padding. + EXPECT_EQ(original_event.padding_length(), + logged_event.rtp.header.paddingLength); + + VerifyLoggedRtpHeader(original_event.header(), logged_event.rtp.header); +} + +void EventVerifier::VerifyLoggedRtpPacketOutgoing( + const RtcEventRtpPacketOutgoing& original_event, + const LoggedRtpPacketOutgoing& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + + EXPECT_EQ(original_event.header().headers_size(), + logged_event.rtp.header_length); + + EXPECT_EQ(original_event.packet_length(), logged_event.rtp.total_length); + + // Currently, RTC eventlog encoder-parser can only maintain padding length + // if packet is full padding. + EXPECT_EQ(original_event.padding_length(), + logged_event.rtp.header.paddingLength); + + // TODO(terelius): Probe cluster ID isn't parsed, used or tested. Unless + // someone has a strong reason to keep it, it'll be removed. + + VerifyLoggedRtpHeader(original_event.header(), logged_event.rtp.header); +} + +void EventVerifier::VerifyLoggedGenericPacketSent( + const RtcEventGenericPacketSent& original_event, + const LoggedGenericPacketSent& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.packet_number(), logged_event.packet_number); + EXPECT_EQ(original_event.overhead_length(), logged_event.overhead_length); + EXPECT_EQ(original_event.payload_length(), logged_event.payload_length); + EXPECT_EQ(original_event.padding_length(), logged_event.padding_length); +} + +void EventVerifier::VerifyLoggedGenericPacketReceived( + const RtcEventGenericPacketReceived& original_event, + const LoggedGenericPacketReceived& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.packet_number(), logged_event.packet_number); + EXPECT_EQ(static_cast(original_event.packet_length()), + logged_event.packet_length); +} + +void EventVerifier::VerifyLoggedGenericAckReceived( + const RtcEventGenericAckReceived& original_event, + const LoggedGenericAckReceived& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + EXPECT_EQ(original_event.packet_number(), logged_event.packet_number); + EXPECT_EQ(original_event.acked_packet_number(), + logged_event.acked_packet_number); + EXPECT_EQ(original_event.receive_acked_packet_time_ms(), + logged_event.receive_acked_packet_time_ms); +} + +void EventVerifier::VerifyLoggedRtcpPacketIncoming( + const RtcEventRtcpPacketIncoming& original_event, + const LoggedRtcpPacketIncoming& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + + ASSERT_EQ(original_event.packet().size(), logged_event.rtcp.raw_data.size()); + EXPECT_EQ( + memcmp(original_event.packet().data(), logged_event.rtcp.raw_data.data(), + original_event.packet().size()), + 0); +} + +void EventVerifier::VerifyLoggedRtcpPacketOutgoing( + const RtcEventRtcpPacketOutgoing& original_event, + const LoggedRtcpPacketOutgoing& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + + ASSERT_EQ(original_event.packet().size(), logged_event.rtcp.raw_data.size()); + EXPECT_EQ( + memcmp(original_event.packet().data(), logged_event.rtcp.raw_data.data(), + original_event.packet().size()), + 0); +} + +void EventVerifier::VerifyReportBlock( + const rtcp::ReportBlock& original_report_block, + const rtcp::ReportBlock& logged_report_block) { + EXPECT_EQ(original_report_block.source_ssrc(), + logged_report_block.source_ssrc()); + EXPECT_EQ(original_report_block.fraction_lost(), + logged_report_block.fraction_lost()); + EXPECT_EQ(original_report_block.cumulative_lost_signed(), + logged_report_block.cumulative_lost_signed()); + EXPECT_EQ(original_report_block.extended_high_seq_num(), + logged_report_block.extended_high_seq_num()); + EXPECT_EQ(original_report_block.jitter(), logged_report_block.jitter()); + EXPECT_EQ(original_report_block.last_sr(), logged_report_block.last_sr()); + EXPECT_EQ(original_report_block.delay_since_last_sr(), + logged_report_block.delay_since_last_sr()); +} + +void EventVerifier::VerifyLoggedSenderReport( + int64_t log_time_us, + const rtcp::SenderReport& original_sr, + const LoggedRtcpPacketSenderReport& logged_sr) { + EXPECT_EQ(log_time_us, logged_sr.log_time_us()); + EXPECT_EQ(original_sr.sender_ssrc(), logged_sr.sr.sender_ssrc()); + EXPECT_EQ(original_sr.ntp(), logged_sr.sr.ntp()); + EXPECT_EQ(original_sr.rtp_timestamp(), logged_sr.sr.rtp_timestamp()); + EXPECT_EQ(original_sr.sender_packet_count(), + logged_sr.sr.sender_packet_count()); + EXPECT_EQ(original_sr.sender_octet_count(), + logged_sr.sr.sender_octet_count()); + ASSERT_EQ(original_sr.report_blocks().size(), + logged_sr.sr.report_blocks().size()); + for (size_t i = 0; i < original_sr.report_blocks().size(); i++) { + VerifyReportBlock(original_sr.report_blocks()[i], + logged_sr.sr.report_blocks()[i]); + } +} + +void EventVerifier::VerifyLoggedReceiverReport( + int64_t log_time_us, + const rtcp::ReceiverReport& original_rr, + const LoggedRtcpPacketReceiverReport& logged_rr) { + EXPECT_EQ(log_time_us, logged_rr.log_time_us()); + EXPECT_EQ(original_rr.sender_ssrc(), logged_rr.rr.sender_ssrc()); + ASSERT_EQ(original_rr.report_blocks().size(), + logged_rr.rr.report_blocks().size()); + for (size_t i = 0; i < original_rr.report_blocks().size(); i++) { + VerifyReportBlock(original_rr.report_blocks()[i], + logged_rr.rr.report_blocks()[i]); + } +} + +void EventVerifier::VerifyLoggedExtendedReports( + int64_t log_time_us, + const rtcp::ExtendedReports& original_xr, + const LoggedRtcpPacketExtendedReports& logged_xr) { + EXPECT_EQ(original_xr.sender_ssrc(), logged_xr.xr.sender_ssrc()); + + EXPECT_EQ(original_xr.rrtr().has_value(), logged_xr.xr.rrtr().has_value()); + if (original_xr.rrtr().has_value() && logged_xr.xr.rrtr().has_value()) { + EXPECT_EQ(original_xr.rrtr()->ntp(), logged_xr.xr.rrtr()->ntp()); + } + + const auto& original_subblocks = original_xr.dlrr().sub_blocks(); + const auto& logged_subblocks = logged_xr.xr.dlrr().sub_blocks(); + ASSERT_EQ(original_subblocks.size(), logged_subblocks.size()); + for (size_t i = 0; i < original_subblocks.size(); i++) { + EXPECT_EQ(original_subblocks[i].ssrc, logged_subblocks[i].ssrc); + EXPECT_EQ(original_subblocks[i].last_rr, logged_subblocks[i].last_rr); + EXPECT_EQ(original_subblocks[i].delay_since_last_rr, + logged_subblocks[i].delay_since_last_rr); + } + + EXPECT_EQ(original_xr.target_bitrate().has_value(), + logged_xr.xr.target_bitrate().has_value()); + if (original_xr.target_bitrate().has_value() && + logged_xr.xr.target_bitrate().has_value()) { + const auto& original_bitrates = + original_xr.target_bitrate()->GetTargetBitrates(); + const auto& logged_bitrates = + logged_xr.xr.target_bitrate()->GetTargetBitrates(); + ASSERT_EQ(original_bitrates.size(), logged_bitrates.size()); + for (size_t i = 0; i < original_bitrates.size(); i++) { + EXPECT_EQ(original_bitrates[i].spatial_layer, + logged_bitrates[i].spatial_layer); + EXPECT_EQ(original_bitrates[i].temporal_layer, + logged_bitrates[i].temporal_layer); + EXPECT_EQ(original_bitrates[i].target_bitrate_kbps, + logged_bitrates[i].target_bitrate_kbps); + } + } +} + +void EventVerifier::VerifyLoggedFir(int64_t log_time_us, + const rtcp::Fir& original_fir, + const LoggedRtcpPacketFir& logged_fir) { + EXPECT_EQ(original_fir.sender_ssrc(), logged_fir.fir.sender_ssrc()); + + const auto& original_requests = original_fir.requests(); + const auto& logged_requests = logged_fir.fir.requests(); + ASSERT_EQ(original_requests.size(), logged_requests.size()); + for (size_t i = 0; i < original_requests.size(); i++) { + EXPECT_EQ(original_requests[i].ssrc, logged_requests[i].ssrc); + EXPECT_EQ(original_requests[i].seq_nr, logged_requests[i].seq_nr); + } +} + +void EventVerifier::VerifyLoggedPli(int64_t log_time_us, + const rtcp::Pli& original_pli, + const LoggedRtcpPacketPli& logged_pli) { + EXPECT_EQ(original_pli.sender_ssrc(), logged_pli.pli.sender_ssrc()); + EXPECT_EQ(original_pli.media_ssrc(), logged_pli.pli.media_ssrc()); +} + +void EventVerifier::VerifyLoggedNack(int64_t log_time_us, + const rtcp::Nack& original_nack, + const LoggedRtcpPacketNack& logged_nack) { + EXPECT_EQ(log_time_us, logged_nack.log_time_us()); + EXPECT_EQ(original_nack.packet_ids(), logged_nack.nack.packet_ids()); +} + +void EventVerifier::VerifyLoggedTransportFeedback( + int64_t log_time_us, + const rtcp::TransportFeedback& original_transport_feedback, + const LoggedRtcpPacketTransportFeedback& logged_transport_feedback) { + EXPECT_EQ(log_time_us, logged_transport_feedback.log_time_us()); + ASSERT_EQ( + original_transport_feedback.GetReceivedPackets().size(), + logged_transport_feedback.transport_feedback.GetReceivedPackets().size()); + for (size_t i = 0; + i < original_transport_feedback.GetReceivedPackets().size(); i++) { + EXPECT_EQ( + original_transport_feedback.GetReceivedPackets()[i].sequence_number(), + logged_transport_feedback.transport_feedback.GetReceivedPackets()[i] + .sequence_number()); + EXPECT_EQ( + original_transport_feedback.GetReceivedPackets()[i].delta_us(), + logged_transport_feedback.transport_feedback.GetReceivedPackets()[i] + .delta_us()); + } +} + +void EventVerifier::VerifyLoggedRemb(int64_t log_time_us, + const rtcp::Remb& original_remb, + const LoggedRtcpPacketRemb& logged_remb) { + EXPECT_EQ(log_time_us, logged_remb.log_time_us()); + EXPECT_EQ(original_remb.ssrcs(), logged_remb.remb.ssrcs()); + EXPECT_EQ(original_remb.bitrate_bps(), logged_remb.remb.bitrate_bps()); +} + +void EventVerifier::VerifyLoggedLossNotification( + int64_t log_time_us, + const rtcp::LossNotification& original_loss_notification, + const LoggedRtcpPacketLossNotification& logged_loss_notification) { + EXPECT_EQ(log_time_us, logged_loss_notification.log_time_us()); + EXPECT_EQ(original_loss_notification.last_decoded(), + logged_loss_notification.loss_notification.last_decoded()); + EXPECT_EQ(original_loss_notification.last_received(), + logged_loss_notification.loss_notification.last_received()); + EXPECT_EQ(original_loss_notification.decodability_flag(), + logged_loss_notification.loss_notification.decodability_flag()); +} + +void EventVerifier::VerifyLoggedStartEvent( + int64_t start_time_us, + int64_t utc_start_time_us, + const LoggedStartEvent& logged_event) const { + EXPECT_EQ(start_time_us / 1000, logged_event.log_time_ms()); + if (encoding_type_ == RtcEventLog::EncodingType::NewFormat) { + EXPECT_EQ(utc_start_time_us / 1000, logged_event.utc_start_time_ms); + } +} + +void EventVerifier::VerifyLoggedStopEvent( + int64_t stop_time_us, + const LoggedStopEvent& logged_event) const { + EXPECT_EQ(stop_time_us / 1000, logged_event.log_time_ms()); +} + +void VerifyLoggedStreamConfig(const rtclog::StreamConfig& original_config, + const rtclog::StreamConfig& logged_config) { + EXPECT_EQ(original_config.local_ssrc, logged_config.local_ssrc); + EXPECT_EQ(original_config.remote_ssrc, logged_config.remote_ssrc); + EXPECT_EQ(original_config.rtx_ssrc, logged_config.rtx_ssrc); + + EXPECT_EQ(original_config.rtp_extensions.size(), + logged_config.rtp_extensions.size()); + size_t recognized_extensions = 0; + for (size_t i = 0; i < kMaxNumExtensions; i++) { + auto original_id = + GetExtensionId(original_config.rtp_extensions, kExtensions[i].name); + auto logged_id = + GetExtensionId(logged_config.rtp_extensions, kExtensions[i].name); + EXPECT_EQ(original_id, logged_id) + << "IDs for " << kExtensions[i].name << " don't match. Original ID " + << original_id.value_or(-1) << ". Parsed ID " << logged_id.value_or(-1) + << "."; + if (original_id) { + recognized_extensions++; + } + } + EXPECT_EQ(recognized_extensions, original_config.rtp_extensions.size()); +} + +void EventVerifier::VerifyLoggedAudioRecvConfig( + const RtcEventAudioReceiveStreamConfig& original_event, + const LoggedAudioRecvConfig& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + VerifyLoggedStreamConfig(original_event.config(), logged_event.config); +} + +void EventVerifier::VerifyLoggedAudioSendConfig( + const RtcEventAudioSendStreamConfig& original_event, + const LoggedAudioSendConfig& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + VerifyLoggedStreamConfig(original_event.config(), logged_event.config); +} + +void EventVerifier::VerifyLoggedVideoRecvConfig( + const RtcEventVideoReceiveStreamConfig& original_event, + const LoggedVideoRecvConfig& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + VerifyLoggedStreamConfig(original_event.config(), logged_event.config); +} + +void EventVerifier::VerifyLoggedVideoSendConfig( + const RtcEventVideoSendStreamConfig& original_event, + const LoggedVideoSendConfig& logged_event) const { + EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); + VerifyLoggedStreamConfig(original_event.config(), logged_event.config); +} + +} // namespace test +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h new file mode 100644 index 000000000..8f564ff9d --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2016 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. + */ + +#ifndef LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_UNITTEST_HELPER_H_ +#define LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_UNITTEST_HELPER_H_ + +#include +#include + +#include + +#include "logging/rtc_event_log/events/rtc_event_alr_state.h" +#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h" +#include "logging/rtc_event_log/events/rtc_event_audio_playout.h" +#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h" +#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h" +#include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h" +#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h" +#include "logging/rtc_event_log/events/rtc_event_frame_decoded.h" +#include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h" +#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h" +#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h" +#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h" +#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" +#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h" +#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h" +#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h" +#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h" +#include "logging/rtc_event_log/events/rtc_event_route_change.h" +#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h" +#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h" +#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h" +#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" +#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h" +#include "logging/rtc_event_log/rtc_event_log_parser.h" +#include "logging/rtc_event_log/rtc_stream_config.h" +#include "modules/rtp_rtcp/include/rtp_header_extension_map.h" +#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h" +#include "modules/rtp_rtcp/source/rtcp_packet/fir.h" +#include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h" +#include "modules/rtp_rtcp/source/rtcp_packet/nack.h" +#include "modules/rtp_rtcp/source/rtcp_packet/pli.h" +#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" +#include "modules/rtp_rtcp/source/rtcp_packet/remb.h" +#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" +#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" +#include "modules/rtp_rtcp/source/rtp_packet.h" +#include "rtc_base/random.h" + +namespace webrtc { + +namespace test { + +class EventGenerator { + public: + explicit EventGenerator(uint64_t seed) : prng_(seed) {} + + std::unique_ptr NewAlrState(); + std::unique_ptr NewAudioNetworkAdaptation(); + std::unique_ptr NewAudioPlayout(uint32_t ssrc); + std::unique_ptr NewBweUpdateDelayBased(); + std::unique_ptr NewBweUpdateLossBased(); + std::unique_ptr NewDtlsTransportState(); + std::unique_ptr NewDtlsWritableState(); + std::unique_ptr NewFrameDecodedEvent(uint32_t ssrc); + std::unique_ptr NewGenericAckReceived(); + std::unique_ptr NewGenericPacketReceived(); + std::unique_ptr NewGenericPacketSent(); + std::unique_ptr NewIceCandidatePair(); + std::unique_ptr NewIceCandidatePairConfig(); + std::unique_ptr NewProbeClusterCreated(); + std::unique_ptr NewProbeResultFailure(); + std::unique_ptr NewProbeResultSuccess(); + std::unique_ptr NewRouteChange(); + std::unique_ptr NewRemoteEstimate(); + std::unique_ptr NewRtcpPacketIncoming(); + std::unique_ptr NewRtcpPacketOutgoing(); + + rtcp::SenderReport NewSenderReport(); + rtcp::ReceiverReport NewReceiverReport(); + rtcp::ExtendedReports NewExtendedReports(); + rtcp::Nack NewNack(); + rtcp::Remb NewRemb(); + rtcp::Fir NewFir(); + rtcp::Pli NewPli(); + rtcp::TransportFeedback NewTransportFeedback(); + rtcp::LossNotification NewLossNotification(); + + // |all_configured_exts| determines whether the RTP packet exhibits all + // configured extensions, or a random subset thereof. + void RandomizeRtpPacket(size_t payload_size, + size_t padding_size, + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map, + RtpPacket* rtp_packet, + bool all_configured_exts); + + // |all_configured_exts| determines whether the RTP packet exhibits all + // configured extensions, or a random subset thereof. + std::unique_ptr NewRtpPacketIncoming( + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map, + bool all_configured_exts = true); + + // |all_configured_exts| determines whether the RTP packet exhibits all + // configured extensions, or a random subset thereof. + std::unique_ptr NewRtpPacketOutgoing( + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map, + bool all_configured_exts = true); + + // |configure_all| determines whether all supported extensions are configured, + // or a random subset. + RtpHeaderExtensionMap NewRtpHeaderExtensionMap(bool configure_all = false); + + std::unique_ptr NewAudioReceiveStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions); + + std::unique_ptr NewAudioSendStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions); + + std::unique_ptr NewVideoReceiveStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions); + + std::unique_ptr NewVideoSendStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions); + + private: + rtcp::ReportBlock NewReportBlock(); + int sent_packet_number_ = 0; + int received_packet_number_ = 0; + + Random prng_; +}; + +class EventVerifier { + public: + explicit EventVerifier(RtcEventLog::EncodingType encoding_type) + : encoding_type_(encoding_type) {} + + void VerifyLoggedAlrStateEvent(const RtcEventAlrState& original_event, + const LoggedAlrStateEvent& logged_event) const; + + void VerifyLoggedAudioPlayoutEvent( + const RtcEventAudioPlayout& original_event, + const LoggedAudioPlayoutEvent& logged_event) const; + + void VerifyLoggedAudioNetworkAdaptationEvent( + const RtcEventAudioNetworkAdaptation& original_event, + const LoggedAudioNetworkAdaptationEvent& logged_event) const; + + void VerifyLoggedBweDelayBasedUpdate( + const RtcEventBweUpdateDelayBased& original_event, + const LoggedBweDelayBasedUpdate& logged_event) const; + + void VerifyLoggedBweLossBasedUpdate( + const RtcEventBweUpdateLossBased& original_event, + const LoggedBweLossBasedUpdate& logged_event) const; + + void VerifyLoggedBweProbeClusterCreatedEvent( + const RtcEventProbeClusterCreated& original_event, + const LoggedBweProbeClusterCreatedEvent& logged_event) const; + + void VerifyLoggedBweProbeFailureEvent( + const RtcEventProbeResultFailure& original_event, + const LoggedBweProbeFailureEvent& logged_event) const; + + void VerifyLoggedBweProbeSuccessEvent( + const RtcEventProbeResultSuccess& original_event, + const LoggedBweProbeSuccessEvent& logged_event) const; + + void VerifyLoggedDtlsTransportState( + const RtcEventDtlsTransportState& original_event, + const LoggedDtlsTransportState& logged_event) const; + + void VerifyLoggedDtlsWritableState( + const RtcEventDtlsWritableState& original_event, + const LoggedDtlsWritableState& logged_event) const; + + void VerifyLoggedFrameDecoded(const RtcEventFrameDecoded& original_event, + const LoggedFrameDecoded& logged_event) const; + + void VerifyLoggedIceCandidatePairConfig( + const RtcEventIceCandidatePairConfig& original_event, + const LoggedIceCandidatePairConfig& logged_event) const; + + void VerifyLoggedIceCandidatePairEvent( + const RtcEventIceCandidatePair& original_event, + const LoggedIceCandidatePairEvent& logged_event) const; + + void VerifyLoggedRouteChangeEvent( + const RtcEventRouteChange& original_event, + const LoggedRouteChangeEvent& logged_event) const; + + void VerifyLoggedRemoteEstimateEvent( + const RtcEventRemoteEstimate& original_event, + const LoggedRemoteEstimateEvent& logged_event) const; + + void VerifyLoggedRtpPacketIncoming( + const RtcEventRtpPacketIncoming& original_event, + const LoggedRtpPacketIncoming& logged_event) const; + + void VerifyLoggedRtpPacketOutgoing( + const RtcEventRtpPacketOutgoing& original_event, + const LoggedRtpPacketOutgoing& logged_event) const; + + void VerifyLoggedGenericPacketSent( + const RtcEventGenericPacketSent& original_event, + const LoggedGenericPacketSent& logged_event) const; + + void VerifyLoggedGenericPacketReceived( + const RtcEventGenericPacketReceived& original_event, + const LoggedGenericPacketReceived& logged_event) const; + + void VerifyLoggedGenericAckReceived( + const RtcEventGenericAckReceived& original_event, + const LoggedGenericAckReceived& logged_event) const; + + template + void VerifyLoggedRtpPacket(const EventType& original_event, + const ParsedType& logged_event) { + static_assert(sizeof(ParsedType) == 0, + "You have to use one of the two defined template " + "specializations of VerifyLoggedRtpPacket"); + } + + template + void VerifyLoggedRtpPacket(const RtcEventRtpPacketIncoming& original_event, + const LoggedRtpPacketIncoming& logged_event) { + VerifyLoggedRtpPacketIncoming(original_event, logged_event); + } + + template + void VerifyLoggedRtpPacket(const RtcEventRtpPacketOutgoing& original_event, + const LoggedRtpPacketOutgoing& logged_event) { + VerifyLoggedRtpPacketOutgoing(original_event, logged_event); + } + + void VerifyLoggedRtcpPacketIncoming( + const RtcEventRtcpPacketIncoming& original_event, + const LoggedRtcpPacketIncoming& logged_event) const; + + void VerifyLoggedRtcpPacketOutgoing( + const RtcEventRtcpPacketOutgoing& original_event, + const LoggedRtcpPacketOutgoing& logged_event) const; + + void VerifyLoggedSenderReport(int64_t log_time_us, + const rtcp::SenderReport& original_sr, + const LoggedRtcpPacketSenderReport& logged_sr); + void VerifyLoggedReceiverReport( + int64_t log_time_us, + const rtcp::ReceiverReport& original_rr, + const LoggedRtcpPacketReceiverReport& logged_rr); + void VerifyLoggedExtendedReports( + int64_t log_time_us, + const rtcp::ExtendedReports& original_xr, + const LoggedRtcpPacketExtendedReports& logged_xr); + void VerifyLoggedFir(int64_t log_time_us, + const rtcp::Fir& original_fir, + const LoggedRtcpPacketFir& logged_fir); + void VerifyLoggedPli(int64_t log_time_us, + const rtcp::Pli& original_pli, + const LoggedRtcpPacketPli& logged_pli); + void VerifyLoggedNack(int64_t log_time_us, + const rtcp::Nack& original_nack, + const LoggedRtcpPacketNack& logged_nack); + void VerifyLoggedTransportFeedback( + int64_t log_time_us, + const rtcp::TransportFeedback& original_transport_feedback, + const LoggedRtcpPacketTransportFeedback& logged_transport_feedback); + void VerifyLoggedRemb(int64_t log_time_us, + const rtcp::Remb& original_remb, + const LoggedRtcpPacketRemb& logged_remb); + void VerifyLoggedLossNotification( + int64_t log_time_us, + const rtcp::LossNotification& original_loss_notification, + const LoggedRtcpPacketLossNotification& logged_loss_notification); + + void VerifyLoggedStartEvent(int64_t start_time_us, + int64_t utc_start_time_us, + const LoggedStartEvent& logged_event) const; + void VerifyLoggedStopEvent(int64_t stop_time_us, + const LoggedStopEvent& logged_event) const; + + void VerifyLoggedAudioRecvConfig( + const RtcEventAudioReceiveStreamConfig& original_event, + const LoggedAudioRecvConfig& logged_event) const; + + void VerifyLoggedAudioSendConfig( + const RtcEventAudioSendStreamConfig& original_event, + const LoggedAudioSendConfig& logged_event) const; + + void VerifyLoggedVideoRecvConfig( + const RtcEventVideoReceiveStreamConfig& original_event, + const LoggedVideoRecvConfig& logged_event) const; + + void VerifyLoggedVideoSendConfig( + const RtcEventVideoSendStreamConfig& original_event, + const LoggedVideoSendConfig& logged_event) const; + + private: + void VerifyReportBlock(const rtcp::ReportBlock& original_report_block, + const rtcp::ReportBlock& logged_report_block); + + RtcEventLog::EncodingType encoding_type_; +}; + +} // namespace test +} // namespace webrtc + +#endif // LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_UNITTEST_HELPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/media/base/fake_media_engine.cc b/TMessagesProj/jni/voip/webrtc/media/base/fake_media_engine.cc index 1040757f8..734a30be7 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/fake_media_engine.cc +++ b/TMessagesProj/jni/voip/webrtc/media/base/fake_media_engine.cc @@ -183,7 +183,8 @@ absl::optional FakeVoiceMediaChannel::GetBaseMinimumPlayoutDelayMs( } return absl::nullopt; } -bool FakeVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { +bool FakeVoiceMediaChannel::GetStats(VoiceMediaInfo* info, + bool get_and_clear_legacy_stats) { return false; } void FakeVoiceMediaChannel::SetRawAudioSink( diff --git a/TMessagesProj/jni/voip/webrtc/media/base/fake_media_engine.h b/TMessagesProj/jni/voip/webrtc/media/base/fake_media_engine.h index 338c329aa..1751dd8bf 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/fake_media_engine.h +++ b/TMessagesProj/jni/voip/webrtc/media/base/fake_media_engine.h @@ -349,7 +349,7 @@ class FakeVoiceMediaChannel : public RtpHelper { absl::optional GetBaseMinimumPlayoutDelayMs( uint32_t ssrc) const override; - bool GetStats(VoiceMediaInfo* info) override; + bool GetStats(VoiceMediaInfo* info, bool get_and_clear_legacy_stats) override; void SetRawAudioSink( uint32_t ssrc, diff --git a/TMessagesProj/jni/voip/webrtc/media/base/fake_network_interface.h b/TMessagesProj/jni/voip/webrtc/media/base/fake_network_interface.h index eb08f69b5..3df83edce 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/fake_network_interface.h +++ b/TMessagesProj/jni/voip/webrtc/media/base/fake_network_interface.h @@ -28,7 +28,7 @@ namespace cricket { // Fake NetworkInterface that sends/receives RTP/RTCP packets. class FakeNetworkInterface : public MediaChannel::NetworkInterface, - public rtc::MessageHandler { + public rtc::MessageHandlerAutoCleanup { public: FakeNetworkInterface() : thread_(rtc::Thread::Current()), diff --git a/TMessagesProj/jni/voip/webrtc/media/base/media_channel.h b/TMessagesProj/jni/voip/webrtc/media/base/media_channel.h index e8400a58a..a947b4799 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/media_channel.h +++ b/TMessagesProj/jni/voip/webrtc/media/base/media_channel.h @@ -204,7 +204,8 @@ class MediaChannel : public sigslot::has_slots<> { // ssrc must be the first SSRC of the media stream if the stream uses // multiple SSRCs. virtual bool RemoveRecvStream(uint32_t ssrc) = 0; - // Resets any cached StreamParams for an unsignaled RecvStream. + // Resets any cached StreamParams for an unsignaled RecvStream, and removes + // any existing unsignaled streams. virtual void ResetUnsignaledRecvStream() = 0; // Returns the absoulte sendtime extension id value from media channel. virtual int GetRtpSendTimeExtnId() const; @@ -833,7 +834,8 @@ class VoiceMediaChannel : public MediaChannel, public Delayable { // DTMF event 0-9, *, #, A-D. virtual bool InsertDtmf(uint32_t ssrc, int event, int duration) = 0; // Gets quality stats for the channel. - virtual bool GetStats(VoiceMediaInfo* info) = 0; + virtual bool GetStats(VoiceMediaInfo* info, + bool get_and_clear_legacy_stats) = 0; virtual void SetRawAudioSink( uint32_t ssrc, diff --git a/TMessagesProj/jni/voip/webrtc/media/base/media_constants.cc b/TMessagesProj/jni/voip/webrtc/media/base/media_constants.cc index 31c9d4d1a..840da1d9b 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/media_constants.cc +++ b/TMessagesProj/jni/voip/webrtc/media/base/media_constants.cc @@ -14,7 +14,7 @@ namespace cricket { const int kVideoCodecClockrate = 90000; const int kDataCodecClockrate = 90000; -const int kDataMaxBandwidth = 30720; // bps +const int kRtpDataMaxBandwidth = 30720; // bps const float kHighSystemCpuThreshold = 0.85f; const float kLowSystemCpuThreshold = 0.65f; @@ -107,7 +107,6 @@ const char kH264CodecName[] = "H264"; #ifndef DISABLE_H265 const char kH265CodecName[] = "H265"; #endif -const char kHEVCCodecName[] = "H265X"; // RFC 6184 RTP Payload Format for H.264 video const char kH264FmtpProfileLevelId[] = "profile-level-id"; diff --git a/TMessagesProj/jni/voip/webrtc/media/base/media_constants.h b/TMessagesProj/jni/voip/webrtc/media/base/media_constants.h index e0e0ecc81..2f5733dfb 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/media_constants.h +++ b/TMessagesProj/jni/voip/webrtc/media/base/media_constants.h @@ -21,7 +21,7 @@ namespace cricket { extern const int kVideoCodecClockrate; extern const int kDataCodecClockrate; -extern const int kDataMaxBandwidth; // bps +extern const int kRtpDataMaxBandwidth; // bps // Default CPU thresholds. extern const float kHighSystemCpuThreshold; @@ -133,7 +133,6 @@ RTC_EXPORT extern const char kH264CodecName[]; #ifndef DISABLE_H265 RTC_EXPORT extern const char kH265CodecName[]; #endif -RTC_EXPORT extern const char kHEVCCodecName[]; // RFC 6184 RTP Payload Format for H.264 video RTC_EXPORT extern const char kH264FmtpProfileLevelId[]; diff --git a/TMessagesProj/jni/voip/webrtc/media/base/media_engine.cc b/TMessagesProj/jni/voip/webrtc/media/base/media_engine.cc index 805025872..36a9694cf 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/media_engine.cc +++ b/TMessagesProj/jni/voip/webrtc/media/base/media_engine.cc @@ -161,11 +161,20 @@ webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( } CompositeMediaEngine::CompositeMediaEngine( - std::unique_ptr voice_engine, + std::unique_ptr trials, + std::unique_ptr audio_engine, std::unique_ptr video_engine) - : voice_engine_(std::move(voice_engine)), + : trials_(std::move(trials)), + voice_engine_(std::move(audio_engine)), video_engine_(std::move(video_engine)) {} +CompositeMediaEngine::CompositeMediaEngine( + std::unique_ptr audio_engine, + std::unique_ptr video_engine) + : CompositeMediaEngine(nullptr, + std::move(audio_engine), + std::move(video_engine)) {} + CompositeMediaEngine::~CompositeMediaEngine() = default; bool CompositeMediaEngine::Init() { diff --git a/TMessagesProj/jni/voip/webrtc/media/base/media_engine.h b/TMessagesProj/jni/voip/webrtc/media/base/media_engine.h index 4d9cc56a1..1d8917cfc 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/media_engine.h +++ b/TMessagesProj/jni/voip/webrtc/media/base/media_engine.h @@ -19,6 +19,7 @@ #include "api/audio_codecs/audio_encoder_factory.h" #include "api/crypto/crypto_options.h" #include "api/rtp_parameters.h" +#include "api/transport/webrtc_key_value_config.h" #include "api/video/video_bitrate_allocator_factory.h" #include "call/audio_state.h" #include "media/base/codec.h" @@ -131,8 +132,12 @@ class MediaEngineInterface { // CompositeMediaEngine constructs a MediaEngine from separate // voice and video engine classes. +// Optionally owns a WebRtcKeyValueConfig trials map. class CompositeMediaEngine : public MediaEngineInterface { public: + CompositeMediaEngine(std::unique_ptr trials, + std::unique_ptr audio_engine, + std::unique_ptr video_engine); CompositeMediaEngine(std::unique_ptr audio_engine, std::unique_ptr video_engine); ~CompositeMediaEngine() override; @@ -144,6 +149,7 @@ class CompositeMediaEngine : public MediaEngineInterface { const VideoEngineInterface& video() const override; private: + const std::unique_ptr trials_; std::unique_ptr voice_engine_; std::unique_ptr video_engine_; }; diff --git a/TMessagesProj/jni/voip/webrtc/media/base/rtp_data_engine.cc b/TMessagesProj/jni/voip/webrtc/media/base/rtp_data_engine.cc index 0303cd33d..f05dffabf 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/rtp_data_engine.cc +++ b/TMessagesProj/jni/voip/webrtc/media/base/rtp_data_engine.cc @@ -62,7 +62,7 @@ RtpDataMediaChannel::RtpDataMediaChannel(const MediaConfig& config) void RtpDataMediaChannel::Construct() { sending_ = false; receiving_ = false; - send_limiter_.reset(new rtc::DataRateLimiter(kDataMaxBandwidth / 8, 1.0)); + send_limiter_.reset(new rtc::DataRateLimiter(kRtpDataMaxBandwidth / 8, 1.0)); } RtpDataMediaChannel::~RtpDataMediaChannel() { @@ -245,7 +245,7 @@ void RtpDataMediaChannel::OnPacketReceived(rtc::CopyOnWriteBuffer packet, bool RtpDataMediaChannel::SetMaxSendBandwidth(int bps) { if (bps <= 0) { - bps = kDataMaxBandwidth; + bps = kRtpDataMaxBandwidth; } send_limiter_.reset(new rtc::DataRateLimiter(bps / 8, 1.0)); RTC_LOG(LS_INFO) << "RtpDataMediaChannel::SetSendBandwidth to " << bps diff --git a/TMessagesProj/jni/voip/webrtc/media/base/rtp_utils.cc b/TMessagesProj/jni/voip/webrtc/media/base/rtp_utils.cc index 4a2b3267c..471417522 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/rtp_utils.cc +++ b/TMessagesProj/jni/voip/webrtc/media/base/rtp_utils.cc @@ -323,6 +323,7 @@ absl::string_view RtpPacketTypeToString(RtpPacketType packet_type) { case RtpPacketType::kUnknown: return "Unknown"; } + RTC_CHECK_NOTREACHED(); } RtpPacketType InferRtpPacketType(rtc::ArrayView packet) { diff --git a/TMessagesProj/jni/voip/webrtc/media/base/video_adapter.cc b/TMessagesProj/jni/voip/webrtc/media/base/video_adapter.cc index 73e77cc37..ddcf4cac8 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/video_adapter.cc +++ b/TMessagesProj/jni/voip/webrtc/media/base/video_adapter.cc @@ -349,4 +349,22 @@ void VideoAdapter::OnSinkWants(const rtc::VideoSinkWants& sink_wants) { source_resolution_alignment_, sink_wants.resolution_alignment); } +int VideoAdapter::GetTargetPixels() const { + webrtc::MutexLock lock(&mutex_); + return resolution_request_target_pixel_count_; +} + +float VideoAdapter::GetMaxFramerate() const { + webrtc::MutexLock lock(&mutex_); + // Minimum of |max_fps_| and |max_framerate_request_| is used to throttle + // frame-rate. + int framerate = std::min(max_framerate_request_, + max_fps_.value_or(max_framerate_request_)); + if (framerate == std::numeric_limits::max()) { + return std::numeric_limits::infinity(); + } else { + return max_framerate_request_; + } +} + } // namespace cricket diff --git a/TMessagesProj/jni/voip/webrtc/media/base/video_adapter.h b/TMessagesProj/jni/voip/webrtc/media/base/video_adapter.h index 2c4263276..3ed58954e 100644 --- a/TMessagesProj/jni/voip/webrtc/media/base/video_adapter.h +++ b/TMessagesProj/jni/voip/webrtc/media/base/video_adapter.h @@ -20,6 +20,7 @@ #include "media/base/video_common.h" #include "rtc_base/constructor_magic.h" #include "rtc_base/synchronization/mutex.h" +#include "rtc_base/system/rtc_export.h" #include "rtc_base/thread_annotations.h" namespace cricket { @@ -28,7 +29,7 @@ namespace cricket { // specified input and output formats. The adaptation includes dropping frames // to reduce frame rate and scaling frames. // VideoAdapter is thread safe. -class VideoAdapter { +class RTC_EXPORT VideoAdapter { public: VideoAdapter(); // The source requests output frames whose width and height are divisible @@ -97,6 +98,14 @@ class VideoAdapter { void OnSinkWants(const rtc::VideoSinkWants& sink_wants) RTC_LOCKS_EXCLUDED(mutex_); + // Returns maximum image area, which shouldn't impose any adaptations. + // Can return |numeric_limits::max()| if no limit is set. + int GetTargetPixels() const; + + // Returns current frame-rate limit. + // Can return |numeric_limits::infinity()| if no limit is set. + float GetMaxFramerate() const; + private: // Determine if frame should be dropped based on input fps and requested fps. bool KeepFrame(int64_t in_timestamp_ns) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); @@ -136,7 +145,7 @@ class VideoAdapter { int max_framerate_request_ RTC_GUARDED_BY(mutex_); // The critical section to protect the above variables. - webrtc::Mutex mutex_; + mutable webrtc::Mutex mutex_; RTC_DISALLOW_COPY_AND_ASSIGN(VideoAdapter); }; diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/fake_video_codec_factory.cc b/TMessagesProj/jni/voip/webrtc/media/engine/fake_video_codec_factory.cc index 63a1d5096..6f4f796b1 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/fake_video_codec_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/media/engine/fake_video_codec_factory.cc @@ -15,7 +15,6 @@ #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_encoder.h" -#include "modules/include/module_common_types.h" #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/checks.h" diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/fake_webrtc_call.cc b/TMessagesProj/jni/voip/webrtc/media/engine/fake_webrtc_call.cc index cb62d9fc0..e320880b2 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/fake_webrtc_call.cc +++ b/TMessagesProj/jni/voip/webrtc/media/engine/fake_webrtc_call.cc @@ -100,7 +100,8 @@ void FakeAudioReceiveStream::Reconfigure( config_ = config; } -webrtc::AudioReceiveStream::Stats FakeAudioReceiveStream::GetStats() const { +webrtc::AudioReceiveStream::Stats FakeAudioReceiveStream::GetStats( + bool get_and_clear_legacy_stats) const { return stats_; } diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/fake_webrtc_call.h b/TMessagesProj/jni/voip/webrtc/media/engine/fake_webrtc_call.h index 97eb49c89..385bbcd76 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/fake_webrtc_call.h +++ b/TMessagesProj/jni/voip/webrtc/media/engine/fake_webrtc_call.h @@ -24,6 +24,7 @@ #include #include +#include "api/transport/field_trial_based_config.h" #include "api/video/video_frame.h" #include "call/audio_receive_stream.h" #include "call/audio_send_stream.h" @@ -104,7 +105,8 @@ class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream { void Start() override { started_ = true; } void Stop() override { started_ = false; } - webrtc::AudioReceiveStream::Stats GetStats() const override; + webrtc::AudioReceiveStream::Stats GetStats( + bool get_and_clear_legacy_stats) const override; void SetSink(webrtc::AudioSinkInterface* sink) override; void SetGain(float gain) override; bool SetBaseMinimumPlayoutDelayMs(int delay_ms) override { @@ -361,6 +363,10 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver { webrtc::Call::Stats GetStats() const override; + const webrtc::WebRtcKeyValueConfig& trials() const override { + return trials_; + } + void SignalChannelNetworkState(webrtc::MediaType media, webrtc::NetworkState state) override; void OnAudioTransportOverheadChanged( @@ -384,6 +390,7 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver { int num_created_send_streams_; int num_created_receive_streams_; + webrtc::FieldTrialBasedConfig trials_; }; } // namespace cricket diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/simulcast.cc b/TMessagesProj/jni/voip/webrtc/media/engine/simulcast.cc index 6e63ec6f7..f74d4adfb 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/simulcast.cc +++ b/TMessagesProj/jni/voip/webrtc/media/engine/simulcast.cc @@ -16,6 +16,7 @@ #include #include +#include "absl/strings/match.h" #include "absl/types/optional.h" #include "api/video/video_codec_constants.h" #include "media/base/media_constants.h" @@ -26,7 +27,6 @@ #include "rtc_base/experiments/normalize_simulcast_size_experiment.h" #include "rtc_base/experiments/rate_control_settings.h" #include "rtc_base/logging.h" -#include "system_wrappers/include/field_trial.h" namespace cricket { @@ -103,7 +103,9 @@ constexpr const SimulcastFormat kSimulcastFormats[] = { const int kMaxScreenshareSimulcastLayers = 2; // Multiway: Number of temporal layers for each simulcast stream. -int DefaultNumberOfTemporalLayers(int simulcast_id, bool screenshare) { +int DefaultNumberOfTemporalLayers(int simulcast_id, + bool screenshare, + const webrtc::WebRtcKeyValueConfig& trials) { RTC_CHECK_GE(simulcast_id, 0); RTC_CHECK_LT(simulcast_id, webrtc::kMaxSimulcastStreams); @@ -114,10 +116,8 @@ int DefaultNumberOfTemporalLayers(int simulcast_id, bool screenshare) { : kDefaultNumTemporalLayers; const std::string group_name = - screenshare ? webrtc::field_trial::FindFullName( - "WebRTC-VP8ScreenshareTemporalLayers") - : webrtc::field_trial::FindFullName( - "WebRTC-VP8ConferenceTemporalLayers"); + screenshare ? trials.Lookup("WebRTC-VP8ScreenshareTemporalLayers") + : trials.Lookup("WebRTC-VP8ConferenceTemporalLayers"); if (group_name.empty()) return default_num_temporal_layers; @@ -231,9 +231,10 @@ webrtc::DataRate GetTotalMaxBitrate( size_t LimitSimulcastLayerCount(int width, int height, size_t need_layers, - size_t layer_count) { - if (!webrtc::field_trial::IsDisabled( - kUseLegacySimulcastLayerLimitFieldTrial)) { + size_t layer_count, + const webrtc::WebRtcKeyValueConfig& trials) { + if (!absl::StartsWith(trials.Lookup(kUseLegacySimulcastLayerLimitFieldTrial), + "Disabled")) { size_t adaptive_layer_count = std::max( need_layers, kSimulcastFormats[FindSimulcastFormatIndex(width, height)].max_layers); @@ -254,27 +255,28 @@ std::vector GetSimulcastConfig( double bitrate_priority, int max_qp, bool is_screenshare_with_conference_mode, - bool temporal_layers_supported) { + bool temporal_layers_supported, + const webrtc::WebRtcKeyValueConfig& trials) { RTC_DCHECK_LE(min_layers, max_layers); RTC_DCHECK(max_layers > 1 || is_screenshare_with_conference_mode); const bool base_heavy_tl3_rate_alloc = - webrtc::RateControlSettings::ParseFromFieldTrials() + webrtc::RateControlSettings::ParseFromKeyValueConfig(&trials) .Vp8BaseHeavyTl3RateAllocation(); if (is_screenshare_with_conference_mode) { return GetScreenshareLayers(max_layers, width, height, bitrate_priority, max_qp, temporal_layers_supported, - base_heavy_tl3_rate_alloc); + base_heavy_tl3_rate_alloc, trials); } else { // Some applications rely on the old behavior limiting the simulcast layer // count based on the resolution automatically, which they can get through // the WebRTC-LegacySimulcastLayerLimit field trial until they update. max_layers = - LimitSimulcastLayerCount(width, height, min_layers, max_layers); + LimitSimulcastLayerCount(width, height, min_layers, max_layers, trials); return GetNormalSimulcastLayers(max_layers, width, height, bitrate_priority, max_qp, temporal_layers_supported, - base_heavy_tl3_rate_alloc); + base_heavy_tl3_rate_alloc, trials); } } @@ -285,7 +287,8 @@ std::vector GetNormalSimulcastLayers( double bitrate_priority, int max_qp, bool temporal_layers_supported, - bool base_heavy_tl3_rate_alloc) { + bool base_heavy_tl3_rate_alloc, + const webrtc::WebRtcKeyValueConfig& trials) { std::vector layers(layer_count); // Format width and height has to be divisible by |2 ^ num_simulcast_layers - @@ -300,11 +303,13 @@ std::vector GetNormalSimulcastLayers( // TODO(pbos): Fill actual temporal-layer bitrate thresholds. layers[s].max_qp = max_qp; layers[s].num_temporal_layers = - temporal_layers_supported ? DefaultNumberOfTemporalLayers(s, false) : 1; + temporal_layers_supported + ? DefaultNumberOfTemporalLayers(s, false, trials) + : 1; layers[s].max_bitrate_bps = FindSimulcastMaxBitrate(width, height).bps(); layers[s].target_bitrate_bps = FindSimulcastTargetBitrate(width, height).bps(); - int num_temporal_layers = DefaultNumberOfTemporalLayers(s, false); + int num_temporal_layers = DefaultNumberOfTemporalLayers(s, false, trials); if (s == 0) { // If alternative temporal rate allocation is selected, adjust the // bitrate of the lowest simulcast stream so that absolute bitrate for @@ -356,7 +361,8 @@ std::vector GetScreenshareLayers( double bitrate_priority, int max_qp, bool temporal_layers_supported, - bool base_heavy_tl3_rate_alloc) { + bool base_heavy_tl3_rate_alloc, + const webrtc::WebRtcKeyValueConfig& trials) { auto max_screenshare_layers = kMaxScreenshareSimulcastLayers; size_t num_simulcast_layers = std::min(max_layers, max_screenshare_layers); @@ -379,7 +385,8 @@ std::vector GetScreenshareLayers( // restrictions. The base simulcast layer will still use legacy setup. if (num_simulcast_layers == kMaxScreenshareSimulcastLayers) { // Add optional upper simulcast layer. - const int num_temporal_layers = DefaultNumberOfTemporalLayers(1, true); + const int num_temporal_layers = + DefaultNumberOfTemporalLayers(1, true, trials); int max_bitrate_bps; bool using_boosted_bitrate = false; if (!temporal_layers_supported) { @@ -389,7 +396,7 @@ std::vector GetScreenshareLayers( kScreenshareHighStreamMaxBitrate.bps() * webrtc::SimulcastRateAllocator::GetTemporalRateAllocation( num_temporal_layers, 0, base_heavy_tl3_rate_alloc)); - } else if (DefaultNumberOfTemporalLayers(1, true) != 3 || + } else if (DefaultNumberOfTemporalLayers(1, true, trials) != 3 || base_heavy_tl3_rate_alloc) { // Experimental temporal layer mode used, use increased max bitrate. max_bitrate_bps = kScreenshareHighStreamMaxBitrate.bps(); @@ -409,18 +416,12 @@ std::vector GetScreenshareLayers( layers[1].max_qp = max_qp; layers[1].max_framerate = kDefaultVideoMaxFramerate; layers[1].num_temporal_layers = - temporal_layers_supported ? DefaultNumberOfTemporalLayers(1, true) : 1; + temporal_layers_supported + ? DefaultNumberOfTemporalLayers(1, true, trials) + : 1; layers[1].min_bitrate_bps = using_boosted_bitrate ? kScreenshareHighStreamMinBitrate.bps() : layers[0].target_bitrate_bps * 2; - - // Cap max bitrate so it isn't overly high for the given resolution. - int resolution_limited_bitrate = - std::max(FindSimulcastMaxBitrate(width, height).bps(), - layers[1].min_bitrate_bps); - max_bitrate_bps = - std::min(max_bitrate_bps, resolution_limited_bitrate); - layers[1].target_bitrate_bps = max_bitrate_bps; layers[1].max_bitrate_bps = max_bitrate_bps; } diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/simulcast.h b/TMessagesProj/jni/voip/webrtc/media/engine/simulcast.h index 28b08560a..5defa525d 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/simulcast.h +++ b/TMessagesProj/jni/voip/webrtc/media/engine/simulcast.h @@ -15,6 +15,7 @@ #include +#include "api/transport/webrtc_key_value_config.h" #include "api/units/data_rate.h" #include "api/video_codecs/video_encoder_config.h" @@ -41,7 +42,8 @@ std::vector GetSimulcastConfig( double bitrate_priority, int max_qp, bool is_screenshare_with_conference_mode, - bool temporal_layers_supported); + bool temporal_layers_supported, + const webrtc::WebRtcKeyValueConfig& trials); // Gets the simulcast config layers for a non-screensharing case. std::vector GetNormalSimulcastLayers( @@ -51,7 +53,8 @@ std::vector GetNormalSimulcastLayers( double bitrate_priority, int max_qp, bool temporal_layers_supported, - bool base_heavy_tl3_rate_alloc); + bool base_heavy_tl3_rate_alloc, + const webrtc::WebRtcKeyValueConfig& trials); // Gets simulcast config layers for screenshare settings. std::vector GetScreenshareLayers( @@ -61,7 +64,8 @@ std::vector GetScreenshareLayers( double bitrate_priority, int max_qp, bool temporal_layers_supported, - bool base_heavy_tl3_rate_alloc); + bool base_heavy_tl3_rate_alloc, + const webrtc::WebRtcKeyValueConfig& trials); } // namespace cricket diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/simulcast_encoder_adapter.cc b/TMessagesProj/jni/voip/webrtc/media/engine/simulcast_encoder_adapter.cc index 60baed9da..e0c0ff7bc 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/simulcast_encoder_adapter.cc +++ b/TMessagesProj/jni/voip/webrtc/media/engine/simulcast_encoder_adapter.cc @@ -103,8 +103,8 @@ int VerifyCodec(const webrtc::VideoCodec* inst) { return WEBRTC_VIDEO_CODEC_OK; } -bool StreamResolutionCompare(const webrtc::SimulcastStream& a, - const webrtc::SimulcastStream& b) { +bool StreamResolutionCompare(const webrtc::SpatialLayer& a, + const webrtc::SpatialLayer& b) { return std::tie(a.height, a.width, a.maxBitrate, a.maxFramerate) < std::tie(b.height, b.width, b.maxBitrate, b.maxFramerate); } @@ -120,10 +120,9 @@ class AdapterEncodedImageCallback : public webrtc::EncodedImageCallback { EncodedImageCallback::Result OnEncodedImage( const webrtc::EncodedImage& encoded_image, - const webrtc::CodecSpecificInfo* codec_specific_info, - const webrtc::RTPFragmentationHeader* fragmentation) override { + const webrtc::CodecSpecificInfo* codec_specific_info) override { return adapter_->OnEncodedImage(stream_idx_, encoded_image, - codec_specific_info, fragmentation); + codec_specific_info); } private: @@ -157,8 +156,6 @@ SimulcastEncoderAdapter::SimulcastEncoderAdapter( // The adapter is typically created on the worker thread, but operated on // the encoder task queue. encoder_queue_.Detach(); - - memset(&codec_, 0, sizeof(webrtc::VideoCodec)); } SimulcastEncoderAdapter::~SimulcastEncoderAdapter() { @@ -243,10 +240,6 @@ int SimulcastEncoderAdapter::InitEncode( RTC_DCHECK_LT(lowest_resolution_stream_index, number_of_streams); RTC_DCHECK_LT(highest_resolution_stream_index, number_of_streams); - const SdpVideoFormat format( - codec_.codecType == webrtc::kVideoCodecVP8 ? "VP8" : "H264", - video_format_.parameters); - for (int i = 0; i < number_of_streams; ++i) { // If an existing encoder instance exists, reuse it. // TODO(brandtr): Set initial RTP state (e.g., picture_id/tl0_pic_idx) here, @@ -256,10 +249,10 @@ int SimulcastEncoderAdapter::InitEncode( encoder = std::move(stored_encoders_.top()); stored_encoders_.pop(); } else { - encoder = primary_encoder_factory_->CreateVideoEncoder(format); + encoder = primary_encoder_factory_->CreateVideoEncoder(video_format_); if (fallback_encoder_factory_ != nullptr) { encoder = CreateVideoEncoderSoftwareFallbackWrapper( - fallback_encoder_factory_->CreateVideoEncoder(format), + fallback_encoder_factory_->CreateVideoEncoder(video_format_), std::move(encoder), i == lowest_resolution_stream_index && prefer_temporal_support_on_base_layer_); @@ -378,7 +371,7 @@ int SimulcastEncoderAdapter::Encode( } // Temporary thay may hold the result of texture to i420 buffer conversion. - rtc::scoped_refptr src_buffer; + rtc::scoped_refptr src_buffer; int src_width = input_image.width(); int src_height = input_image.height(); for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) { @@ -434,12 +427,14 @@ int SimulcastEncoderAdapter::Encode( } } else { if (src_buffer == nullptr) { - src_buffer = input_image.video_frame_buffer()->ToI420(); + src_buffer = input_image.video_frame_buffer(); + } + rtc::scoped_refptr dst_buffer = + src_buffer->Scale(dst_width, dst_height); + if (!dst_buffer) { + RTC_LOG(LS_ERROR) << "Failed to scale video frame"; + return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE; } - rtc::scoped_refptr dst_buffer = - I420Buffer::Create(dst_width, dst_height); - - dst_buffer->ScaleFrom(*src_buffer); // UpdateRect is not propagated to lower simulcast layers currently. // TODO(ilnik): Consider scaling UpdateRect together with the buffer. @@ -559,15 +554,14 @@ void SimulcastEncoderAdapter::OnLossNotification( EncodedImageCallback::Result SimulcastEncoderAdapter::OnEncodedImage( size_t stream_idx, const EncodedImage& encodedImage, - const CodecSpecificInfo* codecSpecificInfo, - const RTPFragmentationHeader* fragmentation) { + const CodecSpecificInfo* codecSpecificInfo) { EncodedImage stream_image(encodedImage); CodecSpecificInfo stream_codec_specific = *codecSpecificInfo; stream_image.SetSpatialIndex(stream_idx); - return encoded_complete_callback_->OnEncodedImage( - stream_image, &stream_codec_specific, fragmentation); + return encoded_complete_callback_->OnEncodedImage(stream_image, + &stream_codec_specific); } void SimulcastEncoderAdapter::PopulateStreamCodec( @@ -644,6 +638,7 @@ VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const { VideoEncoder::EncoderInfo encoder_info; encoder_info.implementation_name = "SimulcastEncoderAdapter"; encoder_info.requested_resolution_alignment = 1; + encoder_info.apply_alignment_to_all_simulcast_layers = false; encoder_info.supports_native_handle = true; encoder_info.scaling_settings.thresholds = absl::nullopt; if (streaminfos_.empty()) { @@ -695,6 +690,9 @@ VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const { encoder_info.requested_resolution_alignment = cricket::LeastCommonMultiple( encoder_info.requested_resolution_alignment, encoder_impl_info.requested_resolution_alignment); + if (encoder_impl_info.apply_alignment_to_all_simulcast_layers) { + encoder_info.apply_alignment_to_all_simulcast_layers = true; + } if (num_active_streams == 1 && codec_.simulcastStream[i].active) { encoder_info.scaling_settings = encoder_impl_info.scaling_settings; } diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/simulcast_encoder_adapter.h b/TMessagesProj/jni/voip/webrtc/media/engine/simulcast_encoder_adapter.h index a4cf86315..5b2c02757 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/simulcast_encoder_adapter.h +++ b/TMessagesProj/jni/voip/webrtc/media/engine/simulcast_encoder_adapter.h @@ -70,8 +70,7 @@ class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder { EncodedImageCallback::Result OnEncodedImage( size_t stream_idx, const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* fragmentation); + const CodecSpecificInfo* codec_specific_info); EncoderInfo GetEncoderInfo() const override; diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_media_engine.cc b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_media_engine.cc index b026b9d7c..17176512c 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_media_engine.cc +++ b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_media_engine.cc @@ -14,8 +14,8 @@ #include #include "absl/algorithm/container.h" +#include "absl/strings/match.h" #include "media/engine/webrtc_voice_engine.h" -#include "system_wrappers/include/field_trial.h" #ifdef HAVE_WEBRTC_VIDEO #include "media/engine/webrtc_video_engine.h" @@ -27,20 +27,29 @@ namespace cricket { std::unique_ptr CreateMediaEngine( MediaEngineDependencies dependencies) { + // TODO(sprang): Make populating |dependencies.trials| mandatory and remove + // these fallbacks. + std::unique_ptr fallback_trials( + dependencies.trials ? nullptr : new webrtc::FieldTrialBasedConfig()); + const webrtc::WebRtcKeyValueConfig& trials = + dependencies.trials ? *dependencies.trials : *fallback_trials; auto audio_engine = std::make_unique( dependencies.task_queue_factory, std::move(dependencies.adm), std::move(dependencies.audio_encoder_factory), std::move(dependencies.audio_decoder_factory), std::move(dependencies.audio_mixer), - std::move(dependencies.audio_processing)); + std::move(dependencies.audio_processing), + std::move(dependencies.onUnknownAudioSsrc), + dependencies.audio_frame_processor, trials); #ifdef HAVE_WEBRTC_VIDEO auto video_engine = std::make_unique( std::move(dependencies.video_encoder_factory), - std::move(dependencies.video_decoder_factory)); + std::move(dependencies.video_decoder_factory), trials); #else auto video_engine = std::make_unique(); #endif - return std::make_unique(std::move(audio_engine), + return std::make_unique(std::move(fallback_trials), + std::move(audio_engine), std::move(video_engine)); } @@ -87,7 +96,8 @@ bool ValidateRtpExtensions( std::vector FilterRtpExtensions( const std::vector& extensions, bool (*supported)(absl::string_view), - bool filter_redundant_extensions) { + bool filter_redundant_extensions, + const webrtc::WebRtcKeyValueConfig& trials) { RTC_DCHECK(ValidateRtpExtensions(extensions)); RTC_DCHECK(supported); std::vector result; @@ -121,7 +131,8 @@ std::vector FilterRtpExtensions( result.erase(it, result.end()); // Keep just the highest priority extension of any in the following lists. - if (webrtc::field_trial::IsEnabled("WebRTC-FilterAbsSendTimeExtension")) { + if (absl::StartsWith(trials.Lookup("WebRTC-FilterAbsSendTimeExtension"), + "Enabled")) { static const char* const kBweExtensionPriorities[] = { webrtc::RtpExtension::kTransportSequenceNumberUri, webrtc::RtpExtension::kAbsSendTimeUri, diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_media_engine.h b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_media_engine.h index dbb2a5fbb..2bfd6b29b 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_media_engine.h +++ b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_media_engine.h @@ -15,12 +15,14 @@ #include #include +#include "api/audio/audio_frame_processor.h" #include "api/audio/audio_mixer.h" #include "api/audio_codecs/audio_decoder_factory.h" #include "api/audio_codecs/audio_encoder_factory.h" #include "api/rtp_parameters.h" #include "api/task_queue/task_queue_factory.h" #include "api/transport/bitrate_settings.h" +#include "api/transport/webrtc_key_value_config.h" #include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_encoder_factory.h" #include "media/base/codec.h" @@ -45,9 +47,14 @@ struct MediaEngineDependencies { rtc::scoped_refptr audio_decoder_factory; rtc::scoped_refptr audio_mixer; rtc::scoped_refptr audio_processing; + webrtc::AudioFrameProcessor* audio_frame_processor = nullptr; std::unique_ptr video_encoder_factory; std::unique_ptr video_decoder_factory; + + std::function onUnknownAudioSsrc = nullptr; + + const webrtc::WebRtcKeyValueConfig* trials = nullptr; }; // CreateMediaEngine may be called on any thread, though the engine is @@ -66,7 +73,8 @@ bool ValidateRtpExtensions(const std::vector& extensions); std::vector FilterRtpExtensions( const std::vector& extensions, bool (*supported)(absl::string_view), - bool filter_redundant_extensions); + bool filter_redundant_extensions, + const webrtc::WebRtcKeyValueConfig& trials); webrtc::BitrateConstraints GetBitrateConfigForCodec(const Codec& codec); diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_video_engine.cc b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_video_engine.cc index 14e73b70c..8a916c4c7 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_video_engine.cc +++ b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_video_engine.cc @@ -35,12 +35,13 @@ #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/field_trial_units.h" #include "rtc_base/experiments/min_video_bitrate_experiment.h" +#include "rtc_base/experiments/normalize_simulcast_size_experiment.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/strings/string_builder.h" +#include "rtc_base/thread.h" #include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" -#include "system_wrappers/include/field_trial.h" namespace cricket { @@ -61,23 +62,27 @@ const char* StreamTypeToString( return nullptr; } -// If this field trial is enabled, we will enable sending FlexFEC and disable -// sending ULPFEC whenever the former has been negotiated in the SDPs. -bool IsFlexfecFieldTrialEnabled() { - return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03"); +bool IsEnabled(const webrtc::WebRtcKeyValueConfig& trials, + absl::string_view name) { + return absl::StartsWith(trials.Lookup(name), "Enabled"); } -// If this field trial is enabled, the "flexfec-03" codec will be advertised -// as being supported. This means that "flexfec-03" will appear in the default -// SDP offer, and we therefore need to be ready to receive FlexFEC packets from -// the remote. It also means that FlexFEC SSRCs will be generated by -// MediaSession and added as "a=ssrc:" and "a=ssrc-group:" lines in the local -// SDP. -bool IsFlexfecAdvertisedFieldTrialEnabled() { - return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03-Advertised"); +bool PowerOfTwo(int value) { + return (value > 0) && ((value & (value - 1)) == 0); } -void AddDefaultFeedbackParams(VideoCodec* codec) { +bool IsScaleFactorsPowerOfTwo(const webrtc::VideoEncoderConfig& config) { + for (const auto& layer : config.simulcast_layers) { + double scale = std::max(layer.scale_resolution_down_by, 1.0); + if (std::round(scale) != scale || !PowerOfTwo(scale)) { + return false; + } + } + return true; +} + +void AddDefaultFeedbackParams(VideoCodec* codec, + const webrtc::WebRtcKeyValueConfig& trials) { // Don't add any feedback params for RED and ULPFEC. if (codec->name == kRedCodecName || codec->name == kUlpfecCodecName) return; @@ -91,7 +96,7 @@ void AddDefaultFeedbackParams(VideoCodec* codec) { codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); if (codec->name == kVp8CodecName && - webrtc::field_trial::IsEnabled("WebRTC-RtcpLossNotification")) { + IsEnabled(trials, "WebRTC-RtcpLossNotification")) { codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamLntf, kParamValueEmpty)); } } @@ -101,7 +106,8 @@ void AddDefaultFeedbackParams(VideoCodec* codec) { // codecs for recognized codecs (VP8, VP9, H264, and RED). It will also add // default feedback params to the codecs. std::vector AssignPayloadTypesAndDefaultCodecs( - std::vector input_formats) { + std::vector input_formats, + const webrtc::WebRtcKeyValueConfig& trials) { if (input_formats.empty()) return std::vector(); static const int kFirstDynamicPayloadType = 96; @@ -111,7 +117,7 @@ std::vector AssignPayloadTypesAndDefaultCodecs( input_formats.push_back(webrtc::SdpVideoFormat(kRedCodecName)); input_formats.push_back(webrtc::SdpVideoFormat(kUlpfecCodecName)); - if (IsFlexfecAdvertisedFieldTrialEnabled()) { + if (IsEnabled(trials, "WebRTC-FlexFEC-03-Advertised")) { webrtc::SdpVideoFormat flexfec_format(kFlexfecCodecName); // This value is currently arbitrarily set to 10 seconds. (The unit // is microseconds.) This parameter MUST be present in the SDP, but @@ -125,7 +131,7 @@ std::vector AssignPayloadTypesAndDefaultCodecs( for (const webrtc::SdpVideoFormat& format : input_formats) { VideoCodec codec(format); codec.id = payload_type; - AddDefaultFeedbackParams(&codec); + AddDefaultFeedbackParams(&codec, trials); output_codecs.push_back(codec); // Increment payload type. @@ -159,7 +165,8 @@ std::vector AssignPayloadTypesAndDefaultCodecs( template std::vector GetPayloadTypesAndDefaultCodecs( const T* factory, - bool is_decoder_factory) { + bool is_decoder_factory, + const webrtc::WebRtcKeyValueConfig& trials) { if (!factory) { return {}; } @@ -170,7 +177,8 @@ std::vector GetPayloadTypesAndDefaultCodecs( AddH264ConstrainedBaselineProfileToSupportedFormats(&supported_formats); } - return AssignPayloadTypesAndDefaultCodecs(std::move(supported_formats)); + return AssignPayloadTypesAndDefaultCodecs(std::move(supported_formats), + trials); } bool IsTemporalLayersSupported(const std::string& codec_name) { @@ -245,11 +253,11 @@ static bool ValidateStreamParams(const StreamParams& sp) { } // Returns true if the given codec is disallowed from doing simulcast. -bool IsCodecDisabledForSimulcast(const std::string& codec_name) { - return !webrtc::field_trial::IsDisabled("WebRTC-H264Simulcast") +bool IsCodecDisabledForSimulcast(const std::string& codec_name, + const webrtc::WebRtcKeyValueConfig& trials) { + return !absl::StartsWith(trials.Lookup("WebRTC-H264Simulcast"), "Disabled") ? absl::EqualsIgnoreCase(codec_name, kVp9CodecName) : absl::EqualsIgnoreCase(codec_name, kH264CodecName) || - absl::EqualsIgnoreCase(codec_name, kH265CodecName) || absl::EqualsIgnoreCase(codec_name, kVp9CodecName); } @@ -273,9 +281,11 @@ static int GetMaxDefaultVideoBitrateKbps(int width, return max_bitrate; } -bool GetVp9LayersFromFieldTrialGroup(size_t* num_spatial_layers, - size_t* num_temporal_layers) { - std::string group = webrtc::field_trial::FindFullName("WebRTC-SupportVP9SVC"); +bool GetVp9LayersFromFieldTrialGroup( + size_t* num_spatial_layers, + size_t* num_temporal_layers, + const webrtc::WebRtcKeyValueConfig& trials) { + std::string group = trials.Lookup("WebRTC-SupportVP9SVC"); if (group.empty()) return false; @@ -294,19 +304,21 @@ bool GetVp9LayersFromFieldTrialGroup(size_t* num_spatial_layers, return true; } -absl::optional GetVp9SpatialLayersFromFieldTrial() { +absl::optional GetVp9SpatialLayersFromFieldTrial( + const webrtc::WebRtcKeyValueConfig& trials) { size_t num_sl; size_t num_tl; - if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl)) { + if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl, trials)) { return num_sl; } return absl::nullopt; } -absl::optional GetVp9TemporalLayersFromFieldTrial() { +absl::optional GetVp9TemporalLayersFromFieldTrial( + const webrtc::WebRtcKeyValueConfig& trials) { size_t num_sl; size_t num_tl; - if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl)) { + if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl, trials)) { return num_tl; } return absl::nullopt; @@ -468,14 +480,14 @@ WebRtcVideoChannel::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( const size_t default_num_spatial_layers = parameters_.config.rtp.ssrcs.size(); const size_t num_spatial_layers = - GetVp9SpatialLayersFromFieldTrial().value_or( - default_num_spatial_layers); + GetVp9SpatialLayersFromFieldTrial(call_->trials()) + .value_or(default_num_spatial_layers); const size_t default_num_temporal_layers = num_spatial_layers > 1 ? kConferenceDefaultNumTemporalLayers : 1; const size_t num_temporal_layers = - GetVp9TemporalLayersFromFieldTrial().value_or( - default_num_temporal_layers); + GetVp9TemporalLayersFromFieldTrial(call_->trials()) + .value_or(default_num_temporal_layers); vp9_settings.numberOfSpatialLayers = std::min( num_spatial_layers, kConferenceMaxNumSpatialLayers); @@ -497,7 +509,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( {"onkeypic", webrtc::InterLayerPredMode::kOnKeyPic}}); webrtc::ParseFieldTrial( {&interlayer_pred_experiment_enabled, &inter_layer_pred_mode}, - webrtc::field_trial::FindFullName("WebRTC-Vp9InterLayerPred")); + call_->trials().Lookup("WebRTC-Vp9InterLayerPred")); if (interlayer_pred_experiment_enabled) { vp9_settings.interLayerPred = inter_layer_pred_mode; } else { @@ -568,9 +580,11 @@ void DefaultUnsignalledSsrcHandler::SetDefaultSink( WebRtcVideoEngine::WebRtcVideoEngine( std::unique_ptr video_encoder_factory, - std::unique_ptr video_decoder_factory) + std::unique_ptr video_decoder_factory, + const webrtc::WebRtcKeyValueConfig& trials) : decoder_factory_(std::move(video_decoder_factory)), - encoder_factory_(std::move(video_encoder_factory)) { + encoder_factory_(std::move(video_encoder_factory)), + trials_(trials) { RTC_LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()"; } @@ -591,12 +605,12 @@ VideoMediaChannel* WebRtcVideoEngine::CreateMediaChannel( } std::vector WebRtcVideoEngine::send_codecs() const { return GetPayloadTypesAndDefaultCodecs(encoder_factory_.get(), - /*is_decoder_factory=*/false); + /*is_decoder_factory=*/false, trials_); } std::vector WebRtcVideoEngine::recv_codecs() const { return GetPayloadTypesAndDefaultCodecs(decoder_factory_.get(), - /*is_decoder_factory=*/true); + /*is_decoder_factory=*/true, trials_); } std::vector @@ -615,11 +629,22 @@ WebRtcVideoEngine::GetRtpHeaderExtensions() const { webrtc::RtpExtension::kRidUri, webrtc::RtpExtension::kRepairedRidUri}) { result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv); } + result.emplace_back(webrtc::RtpExtension::kGenericFrameDescriptorUri00, id++, + IsEnabled(trials_, "WebRTC-GenericDescriptorAdvertised") + ? webrtc::RtpTransceiverDirection::kSendRecv + : webrtc::RtpTransceiverDirection::kStopped); result.emplace_back( - webrtc::RtpExtension::kGenericFrameDescriptorUri00, id, - webrtc::field_trial::IsEnabled("WebRTC-GenericDescriptorAdvertised") + webrtc::RtpExtension::kDependencyDescriptorUri, id++, + IsEnabled(trials_, "WebRTC-DependencyDescriptorAdvertised") ? webrtc::RtpTransceiverDirection::kSendRecv : webrtc::RtpTransceiverDirection::kStopped); + + result.emplace_back( + webrtc::RtpExtension::kVideoLayersAllocationUri, id++, + IsEnabled(trials_, "WebRTC-VideoLayersAllocationAdvertised") + ? webrtc::RtpTransceiverDirection::kSendRecv + : webrtc::RtpTransceiverDirection::kStopped); + return result; } @@ -641,12 +666,13 @@ WebRtcVideoChannel::WebRtcVideoChannel( bitrate_allocator_factory_(bitrate_allocator_factory), default_send_options_(options), last_stats_log_ms_(-1), - discard_unknown_ssrc_packets_(webrtc::field_trial::IsEnabled( - "WebRTC-Video-DiscardPacketsWithUnknownSsrc")), + discard_unknown_ssrc_packets_( + IsEnabled(call_->trials(), + "WebRTC-Video-DiscardPacketsWithUnknownSsrc")), crypto_options_(crypto_options), unknown_ssrc_packet_buffer_( - webrtc::field_trial::IsEnabled( - "WebRTC-Video-BufferPacketsWithUnknownSsrc") + IsEnabled(call_->trials(), + "WebRTC-Video-BufferPacketsWithUnknownSsrc") ? new UnhandledPacketsBuffer() : nullptr) { RTC_DCHECK(thread_checker_.IsCurrent()); @@ -654,7 +680,7 @@ WebRtcVideoChannel::WebRtcVideoChannel( rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; sending_ = false; recv_codecs_ = MapCodecs(GetPayloadTypesAndDefaultCodecs( - decoder_factory_, /*is_decoder_factory=*/true)); + decoder_factory_, /*is_decoder_factory=*/true, call_->trials())); recv_flexfec_payload_type_ = recv_codecs_.empty() ? 0 : recv_codecs_.front().flexfec_payload_type; } @@ -748,7 +774,7 @@ bool WebRtcVideoChannel::GetChangedSendParameters( } // Never enable sending FlexFEC, unless we are in the experiment. - if (!IsFlexfecFieldTrialEnabled()) { + if (!IsEnabled(call_->trials(), "WebRTC-FlexFEC-03")) { RTC_LOG(LS_INFO) << "WebRTC-FlexFEC-03 field trial is not enabled."; for (VideoCodecSettings& codec : negotiated_codecs) codec.flexfec_payload_type = -1; @@ -768,7 +794,8 @@ bool WebRtcVideoChannel::GetChangedSendParameters( changed_params->extmap_allow_mixed = params.extmap_allow_mixed; } std::vector filtered_extensions = FilterRtpExtensions( - params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true); + params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true, + call_->trials()); if (!send_rtp_extensions_ || (*send_rtp_extensions_ != filtered_extensions)) { changed_params->rtp_header_extensions = absl::optional>(filtered_extensions); @@ -822,97 +849,85 @@ bool WebRtcVideoChannel::SetSendParameters(const VideoSendParameters& params) { } void WebRtcVideoChannel::RequestEncoderFallback() { - invoker_.AsyncInvoke( - RTC_FROM_HERE, worker_thread_, [this] { - RTC_DCHECK_RUN_ON(&thread_checker_); - if (negotiated_codecs_.size() <= 1) { - RTC_LOG(LS_WARNING) - << "Encoder failed but no fallback codec is available"; - return; - } + RTC_DCHECK_RUN_ON(&thread_checker_); + if (negotiated_codecs_.size() <= 1) { + RTC_LOG(LS_WARNING) << "Encoder failed but no fallback codec is available"; + return; + } - ChangedSendParameters params; - params.negotiated_codecs = negotiated_codecs_; - params.negotiated_codecs->erase(params.negotiated_codecs->begin()); - params.send_codec = params.negotiated_codecs->front(); - ApplyChangedParams(params); - }); + ChangedSendParameters params; + params.negotiated_codecs = negotiated_codecs_; + params.negotiated_codecs->erase(params.negotiated_codecs->begin()); + params.send_codec = params.negotiated_codecs->front(); + ApplyChangedParams(params); } void WebRtcVideoChannel::RequestEncoderSwitch( const EncoderSwitchRequestCallback::Config& conf) { - invoker_.AsyncInvoke(RTC_FROM_HERE, worker_thread_, [this, conf] { - RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_DCHECK_RUN_ON(&thread_checker_); - if (!allow_codec_switching_) { - RTC_LOG(LS_INFO) << "Encoder switch requested but codec switching has" - " not been enabled yet."; - requested_encoder_switch_ = conf; - return; - } + if (!allow_codec_switching_) { + RTC_LOG(LS_INFO) << "Encoder switch requested but codec switching has" + " not been enabled yet."; + requested_encoder_switch_ = conf; + return; + } - for (const VideoCodecSettings& codec_setting : negotiated_codecs_) { - if (codec_setting.codec.name == conf.codec_name) { - if (conf.param) { - auto it = codec_setting.codec.params.find(*conf.param); + for (const VideoCodecSettings& codec_setting : negotiated_codecs_) { + if (codec_setting.codec.name == conf.codec_name) { + if (conf.param) { + auto it = codec_setting.codec.params.find(*conf.param); + if (it == codec_setting.codec.params.end()) + continue; - if (it == codec_setting.codec.params.end()) { - continue; - } + if (conf.value && it->second != *conf.value) + continue; + } - if (conf.value && it->second != *conf.value) { - continue; - } - } - - if (send_codec_ == codec_setting) { - // Already using this codec, no switch required. - return; - } - - ChangedSendParameters params; - params.send_codec = codec_setting; - ApplyChangedParams(params); + if (send_codec_ == codec_setting) { + // Already using this codec, no switch required. return; } - } - RTC_LOG(LS_WARNING) << "Requested encoder with codec_name:" - << conf.codec_name - << ", param:" << conf.param.value_or("none") - << " and value:" << conf.value.value_or("none") - << "not found. No switch performed."; - }); + ChangedSendParameters params; + params.send_codec = codec_setting; + ApplyChangedParams(params); + return; + } + } + + RTC_LOG(LS_WARNING) << "Requested encoder with codec_name:" << conf.codec_name + << ", param:" << conf.param.value_or("none") + << " and value:" << conf.value.value_or("none") + << "not found. No switch performed."; } void WebRtcVideoChannel::RequestEncoderSwitch( const webrtc::SdpVideoFormat& format) { - invoker_.AsyncInvoke(RTC_FROM_HERE, worker_thread_, [this, format] { - RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_DCHECK_RUN_ON(&thread_checker_); - for (const VideoCodecSettings& codec_setting : negotiated_codecs_) { - if (IsSameCodec(format.name, format.parameters, codec_setting.codec.name, - codec_setting.codec.params)) { - VideoCodecSettings new_codec_setting = codec_setting; - for (const auto& kv : format.parameters) { - new_codec_setting.codec.params[kv.first] = kv.second; - } + for (const VideoCodecSettings& codec_setting : negotiated_codecs_) { + if (IsSameCodec(format.name, format.parameters, codec_setting.codec.name, + codec_setting.codec.params)) { + VideoCodecSettings new_codec_setting = codec_setting; + for (const auto& kv : format.parameters) { + new_codec_setting.codec.params[kv.first] = kv.second; + } - if (send_codec_ == new_codec_setting) { - // Already using this codec, no switch required. - return; - } - - ChangedSendParameters params; - params.send_codec = new_codec_setting; - ApplyChangedParams(params); + if (send_codec_ == new_codec_setting) { + // Already using this codec, no switch required. return; } - } - RTC_LOG(LS_WARNING) << "Encoder switch failed: SdpVideoFormat " - << format.ToString() << " not negotiated."; - }); + ChangedSendParameters params; + params.send_codec = new_codec_setting; + ApplyChangedParams(params); + return; + } + } + + RTC_LOG(LS_WARNING) << "Encoder switch failed: SdpVideoFormat " + << format.ToString() << " not negotiated."; } bool WebRtcVideoChannel::ApplyChangedParams( @@ -1120,7 +1135,8 @@ bool WebRtcVideoChannel::GetChangedRecvParameters( if (params.is_stream_active) { const std::vector local_supported_codecs = GetPayloadTypesAndDefaultCodecs(decoder_factory_, - /*is_decoder_factory=*/true); + /*is_decoder_factory=*/true, + call_->trials()); for (const VideoCodecSettings& mapped_codec : mapped_codecs) { if (!FindMatchingCodec(local_supported_codecs, mapped_codec.codec)) { RTC_LOG(LS_ERROR) @@ -1138,7 +1154,8 @@ bool WebRtcVideoChannel::GetChangedRecvParameters( // Handle RTP header extensions. std::vector filtered_extensions = FilterRtpExtensions( - params.extensions, webrtc::RtpExtension::IsSupportedForVideo, false); + params.extensions, webrtc::RtpExtension::IsSupportedForVideo, false, + call_->trials()); if (filtered_extensions != recv_rtp_extensions_) { changed_params->rtp_header_extensions = absl::optional>(filtered_extensions); @@ -1292,6 +1309,21 @@ bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) { video_config_.periodic_alr_bandwidth_probing; config.encoder_settings.experiment_cpu_load_estimator = video_config_.experiment_cpu_load_estimator; + using TargetBitrateType = + webrtc::VideoStreamEncoderSettings::BitrateAllocationCallbackType; + if (send_rtp_extensions_ && + webrtc::RtpExtension::FindHeaderExtensionByUri( + *send_rtp_extensions_, + webrtc::RtpExtension::kVideoLayersAllocationUri)) { + config.encoder_settings.allocation_cb_type = + TargetBitrateType::kVideoLayersAllocation; + } else if (IsEnabled(call_->trials(), "WebRTC-Target-Bitrate-Rtcp")) { + config.encoder_settings.allocation_cb_type = + TargetBitrateType::kVideoBitrateAllocation; + } else { + config.encoder_settings.allocation_cb_type = + TargetBitrateType::kVideoBitrateAllocationWhenScreenSharing; + } config.encoder_settings.encoder_factory = encoder_factory_; config.encoder_settings.bitrate_allocator_factory = bitrate_allocator_factory_; @@ -1467,7 +1499,7 @@ void WebRtcVideoChannel::ConfigureReceiverRtp( // TODO(brandtr): Generalize when we add support for multistream protection. flexfec_config->payload_type = recv_flexfec_payload_type_; - if (IsFlexfecAdvertisedFieldTrialEnabled() && + if (IsEnabled(call_->trials(), "WebRTC-FlexFEC-03-Advertised") && sp.GetFecFrSsrc(ssrc, &flexfec_config->remote_ssrc)) { flexfec_config->protected_media_ssrcs = {ssrc}; flexfec_config->local_ssrc = config->rtp.local_ssrc; @@ -1700,7 +1732,7 @@ void WebRtcVideoChannel::BackfillBufferedPackets( int delivery_packet_error_cnt = 0; webrtc::PacketReceiver* receiver = this->call_->Receiver(); unknown_ssrc_packet_buffer_->BackfillPackets( - ssrcs, [&](uint32_t ssrc, int64_t packet_time_us, + ssrcs, [&](uint32_t /*ssrc*/, int64_t packet_time_us, rtc::CopyOnWriteBuffer packet) { switch (receiver->DeliverPacket(webrtc::MediaType::VIDEO, packet, packet_time_us)) { @@ -1760,13 +1792,14 @@ void WebRtcVideoChannel::SetInterface(NetworkInterface* iface) { // The group should be a positive integer with an explicit size, in // which case that is used as UDP recevie buffer size. All other values shall // result in the default value being used. - const std::string group_name = - webrtc::field_trial::FindFullName("WebRTC-IncreasedReceivebuffers"); + const std::string group_name_recv_buf_size = + call_->trials().Lookup("WebRTC-IncreasedReceivebuffers"); int recv_buffer_size = kVideoRtpRecvBufferSize; - if (!group_name.empty() && - (sscanf(group_name.c_str(), "%d", &recv_buffer_size) != 1 || + if (!group_name_recv_buf_size.empty() && + (sscanf(group_name_recv_buf_size.c_str(), "%d", &recv_buffer_size) != 1 || recv_buffer_size <= 0)) { - RTC_LOG(LS_WARNING) << "Invalid receive buffer size: " << group_name; + RTC_LOG(LS_WARNING) << "Invalid receive buffer size: " + << group_name_recv_buf_size; recv_buffer_size = kVideoRtpRecvBufferSize; } @@ -1777,8 +1810,19 @@ void WebRtcVideoChannel::SetInterface(NetworkInterface* iface) { // In b/15152257, we are seeing a significant number of packets discarded // due to lack of socket buffer space, although it's not yet clear what the // ideal value should be. + const std::string group_name_send_buf_size = + call_->trials().Lookup("WebRTC-SendBufferSizeBytes"); + int send_buffer_size = kVideoRtpSendBufferSize; + if (!group_name_send_buf_size.empty() && + (sscanf(group_name_send_buf_size.c_str(), "%d", &send_buffer_size) != 1 || + send_buffer_size <= 0)) { + RTC_LOG(LS_WARNING) << "Invalid send buffer size: " + << group_name_send_buf_size; + send_buffer_size = kVideoRtpSendBufferSize; + } + MediaChannel::SetOption(NetworkInterface::ST_RTP, rtc::Socket::OPT_SNDBUF, - kVideoRtpSendBufferSize); + send_buffer_size); } void WebRtcVideoChannel::SetFrameDecryptor( @@ -1804,18 +1848,16 @@ void WebRtcVideoChannel::SetFrameEncryptor( } void WebRtcVideoChannel::SetVideoCodecSwitchingEnabled(bool enabled) { - invoker_.AsyncInvoke(RTC_FROM_HERE, worker_thread_, [this, enabled] { - RTC_DCHECK_RUN_ON(&thread_checker_); - allow_codec_switching_ = enabled; - if (allow_codec_switching_) { - RTC_LOG(LS_INFO) << "Encoder switching enabled."; - if (requested_encoder_switch_) { - RTC_LOG(LS_INFO) << "Executing cached video encoder switch request."; - RequestEncoderSwitch(*requested_encoder_switch_); - requested_encoder_switch_.reset(); - } + RTC_DCHECK_RUN_ON(&thread_checker_); + allow_codec_switching_ = enabled; + if (allow_codec_switching_) { + RTC_LOG(LS_INFO) << "Encoder switching enabled."; + if (requested_encoder_switch_) { + RTC_LOG(LS_INFO) << "Executing cached video encoder switch request."; + RequestEncoderSwitch(*requested_encoder_switch_); + requested_encoder_switch_.reset(); } - }); + } } bool WebRtcVideoChannel::SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, @@ -1946,12 +1988,11 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( enable_cpu_overuse_detection_(enable_cpu_overuse_detection), source_(nullptr), stream_(nullptr), - encoder_sink_(nullptr), parameters_(std::move(config), options, max_bitrate_bps, codec_settings), rtp_parameters_(CreateRtpParametersWithEncodings(sp)), sending_(false), - disable_automatic_resize_(webrtc::field_trial::IsEnabled( - "WebRTC-Video-DisableAutomaticResize")) { + disable_automatic_resize_( + IsEnabled(call->trials(), "WebRTC-Video-DisableAutomaticResize")) { // Maximum packet size may come in RtpConfig from external transport, for // example from QuicTransportInterface implementation, so do not exceed // given max_packet_size. @@ -1972,7 +2013,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( // FlexFEC SSRCs. // TODO(brandtr): This code needs to be generalized when we add support for // multistream protection. - if (IsFlexfecFieldTrialEnabled()) { + if (IsEnabled(call_->trials(), "WebRTC-FlexFEC-03")) { uint32_t flexfec_ssrc; bool flexfec_enabled = false; for (uint32_t primary_ssrc : parameters_.config.rtp.ssrcs) { @@ -2047,7 +2088,7 @@ bool WebRtcVideoChannel::WebRtcVideoSendStream::SetVideoSend( // Switch to the new source. source_ = source; if (source && stream_) { - stream_->SetSource(this, GetDegradationPreference()); + stream_->SetSource(source_, GetDegradationPreference()); } return true; } @@ -2077,8 +2118,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetDegradationPreference() const { webrtc::VideoTrackInterface::ContentHint::kText) { degradation_preference = webrtc::DegradationPreference::MAINTAIN_RESOLUTION; - } else if (webrtc::field_trial::IsEnabled( - "WebRTC-Video-BalancedDegradation")) { + } else if (IsEnabled(call_->trials(), "WebRTC-Video-BalancedDegradation")) { // Standard wants balanced by default, but it needs to be tuned first. degradation_preference = webrtc::DegradationPreference::BALANCED; } else { @@ -2221,9 +2261,11 @@ webrtc::RTCError WebRtcVideoChannel::WebRtcVideoSendStream::SetRtpParameters( // TODO(bugs.webrtc.org/8807): The bitrate priority really doesn't require an // entire encoder reconfiguration, it just needs to update the bitrate // allocator. - bool reconfigure_encoder = - new_param || (new_parameters.encodings[0].bitrate_priority != - rtp_parameters_.encodings[0].bitrate_priority); + bool reconfigure_encoder = new_param || + (new_parameters.encodings[0].bitrate_priority != + rtp_parameters_.encodings[0].bitrate_priority) || + new_parameters.encodings[0].scalability_mode != + rtp_parameters_.encodings[0].scalability_mode; // TODO(bugs.webrtc.org/8807): The active field as well should not require // a full encoder reconfiguration, but it needs to update both the bitrate @@ -2247,7 +2289,7 @@ webrtc::RTCError WebRtcVideoChannel::WebRtcVideoSendStream::SetRtpParameters( } if (new_degradation_preference) { if (source_ && stream_) { - stream_->SetSource(this, GetDegradationPreference()); + stream_->SetSource(source_, GetDegradationPreference()); } } return webrtc::RTCError::OK(); @@ -2329,7 +2371,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig( // or a screencast (and not in simulcast screenshare experiment), only // configure a single stream. encoder_config.number_of_streams = parameters_.config.rtp.ssrcs.size(); - if (IsCodecDisabledForSimulcast(codec.name)) { + if (IsCodecDisabledForSimulcast(codec.name, call_->trials())) { encoder_config.number_of_streams = 1; } @@ -2382,6 +2424,8 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig( for (size_t i = 0; i < encoder_config.simulcast_layers.size(); ++i) { encoder_config.simulcast_layers[i].active = rtp_parameters_.encodings[i].active; + encoder_config.simulcast_layers[i].scalability_mode = + rtp_parameters_.encodings[i].scalability_mode; if (rtp_parameters_.encodings[i].min_bitrate_bps) { encoder_config.simulcast_layers[i].min_bitrate_bps = *rtp_parameters_.encodings[i].min_bitrate_bps; @@ -2446,38 +2490,6 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetSend(bool send) { UpdateSendState(); } -void WebRtcVideoChannel::WebRtcVideoSendStream::RemoveSink( - rtc::VideoSinkInterface* sink) { - RTC_DCHECK_RUN_ON(&thread_checker_); - RTC_DCHECK(encoder_sink_ == sink); - encoder_sink_ = nullptr; - source_->RemoveSink(sink); -} - -void WebRtcVideoChannel::WebRtcVideoSendStream::AddOrUpdateSink( - rtc::VideoSinkInterface* sink, - const rtc::VideoSinkWants& wants) { - if (worker_thread_ == rtc::Thread::Current()) { - // AddOrUpdateSink is called on |worker_thread_| if this is the first - // registration of |sink|. - RTC_DCHECK_RUN_ON(&thread_checker_); - encoder_sink_ = sink; - source_->AddOrUpdateSink(encoder_sink_, wants); - } else { - // Subsequent calls to AddOrUpdateSink will happen on the encoder task - // queue. - invoker_.AsyncInvoke( - RTC_FROM_HERE, worker_thread_, [this, sink, wants] { - RTC_DCHECK_RUN_ON(&thread_checker_); - // |sink| may be invalidated after this task was posted since - // RemoveSink is called on the worker thread. - bool encoder_sink_valid = (sink == encoder_sink_); - if (source_ && encoder_sink_valid) { - source_->AddOrUpdateSink(encoder_sink_, wants); - } - }); - } -} std::vector WebRtcVideoChannel::WebRtcVideoSendStream::GetPerLayerVideoSenderInfos( bool log_stats) { @@ -2698,7 +2710,7 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::RecreateWebRtcStream() { parameters_.encoder_config.encoder_specific_settings = NULL; if (source_) { - stream_->SetSource(this, GetDegradationPreference()); + stream_->SetSource(source_, GetDegradationPreference()); } // Call stream_->Start() if necessary conditions are met. @@ -2924,8 +2936,7 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateWebRtcVideoStream() { MaybeAssociateFlexfecWithVideo(); stream_->Start(); - if (webrtc::field_trial::IsEnabled( - "WebRTC-Video-BufferPacketsWithUnknownSsrc")) { + if (IsEnabled(call_->trials(), "WebRTC-Video-BufferPacketsWithUnknownSsrc")) { channel_->BackfillBufferedPackets(stream_params_.ssrcs); } } @@ -3376,15 +3387,18 @@ void WebRtcVideoChannel::SetDepacketizerToDecoderFrameTransformer( // TODO(bugs.webrtc.org/8785): Consider removing max_qp as member of // EncoderStreamFactory and instead set this value individually for each stream // in the VideoEncoderConfig.simulcast_layers. -EncoderStreamFactory::EncoderStreamFactory(std::string codec_name, - int max_qp, - bool is_screenshare, - bool conference_mode) +EncoderStreamFactory::EncoderStreamFactory( + std::string codec_name, + int max_qp, + bool is_screenshare, + bool conference_mode, + const webrtc::WebRtcKeyValueConfig* trials) : codec_name_(codec_name), max_qp_(max_qp), is_screenshare_(is_screenshare), - conference_mode_(conference_mode) {} + conference_mode_(conference_mode), + trials_(trials ? *trials : fallback_trials_) {} std::vector EncoderStreamFactory::CreateEncoderStreams( int width, @@ -3399,8 +3413,7 @@ std::vector EncoderStreamFactory::CreateEncoderStreams( if (encoder_config.number_of_streams > 1 || ((absl::EqualsIgnoreCase(codec_name_, kVp8CodecName) || - absl::EqualsIgnoreCase(codec_name_, kH264CodecName) || - absl::EqualsIgnoreCase(codec_name_, kH265CodecName)) && + absl::EqualsIgnoreCase(codec_name_, kH264CodecName)) && is_screenshare_ && conference_mode_)) { return CreateSimulcastOrConferenceModeScreenshareStreams( width, height, encoder_config, experimental_min_bitrate); @@ -3507,7 +3520,7 @@ EncoderStreamFactory::CreateSimulcastOrConferenceModeScreenshareStreams( encoder_config.number_of_streams, width, height, encoder_config.bitrate_priority, max_qp_, is_screenshare_ && conference_mode_, - temporal_layers_supported); + temporal_layers_supported, trials_); // Allow an experiment to override the minimum bitrate for the lowest // spatial layer. The experiment's configuration has the lowest priority. if (experimental_min_bitrate) { @@ -3520,10 +3533,22 @@ EncoderStreamFactory::CreateSimulcastOrConferenceModeScreenshareStreams( encoder_config.simulcast_layers, [](const webrtc::VideoStream& layer) { return layer.scale_resolution_down_by != -1.; }); + + bool default_scale_factors_used = true; + if (has_scale_resolution_down_by) { + default_scale_factors_used = IsScaleFactorsPowerOfTwo(encoder_config); + } + const bool norm_size_configured = + webrtc::NormalizeSimulcastSizeExperiment::GetBase2Exponent().has_value(); const int normalized_width = - NormalizeSimulcastSize(width, encoder_config.number_of_streams); + (default_scale_factors_used || norm_size_configured) + ? NormalizeSimulcastSize(width, encoder_config.number_of_streams) + : width; const int normalized_height = - NormalizeSimulcastSize(height, encoder_config.number_of_streams); + (default_scale_factors_used || norm_size_configured) + ? NormalizeSimulcastSize(height, encoder_config.number_of_streams) + : height; + for (size_t i = 0; i < layers.size(); ++i) { layers[i].active = encoder_config.simulcast_layers[i].active; // Update with configured num temporal layers if supported by codec. @@ -3575,10 +3600,18 @@ EncoderStreamFactory::CreateSimulcastOrConferenceModeScreenshareStreams( std::max(layers[i].max_bitrate_bps, layers[i].min_bitrate_bps); } else if (encoder_config.simulcast_layers[i].max_bitrate_bps > 0) { // Only max bitrate is configured, make sure min/target are below max. + // Keep target bitrate if it is set explicitly in encoding config. + // Otherwise set target bitrate to 3/4 of the max bitrate + // or the one calculated from GetSimulcastConfig() which is larger. layers[i].min_bitrate_bps = std::min(layers[i].min_bitrate_bps, layers[i].max_bitrate_bps); - layers[i].target_bitrate_bps = - std::min(layers[i].target_bitrate_bps, layers[i].max_bitrate_bps); + if (encoder_config.simulcast_layers[i].target_bitrate_bps <= 0) { + layers[i].target_bitrate_bps = std::max( + layers[i].target_bitrate_bps, layers[i].max_bitrate_bps * 3 / 4); + } + layers[i].target_bitrate_bps = std::max( + std::min(layers[i].target_bitrate_bps, layers[i].max_bitrate_bps), + layers[i].min_bitrate_bps); } if (i == layers.size() - 1) { is_highest_layer_max_bitrate_configured = diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_video_engine.h b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_video_engine.h index 3705ebf01..321a5a8c2 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_video_engine.h +++ b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_video_engine.h @@ -19,6 +19,7 @@ #include "absl/types/optional.h" #include "api/call/transport.h" +#include "api/transport/field_trial_based_config.h" #include "api/video/video_bitrate_allocator_factory.h" #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" @@ -31,7 +32,6 @@ #include "media/base/media_engine.h" #include "media/engine/constants.h" #include "media/engine/unhandled_packets_buffer.h" -#include "rtc_base/async_invoker.h" #include "rtc_base/network_route.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -98,7 +98,8 @@ class WebRtcVideoEngine : public VideoEngineInterface { // and external hardware codecs. WebRtcVideoEngine( std::unique_ptr video_encoder_factory, - std::unique_ptr video_decoder_factory); + std::unique_ptr video_decoder_factory, + const webrtc::WebRtcKeyValueConfig& trials); ~WebRtcVideoEngine() override; @@ -120,6 +121,7 @@ class WebRtcVideoEngine : public VideoEngineInterface { const std::unique_ptr encoder_factory_; const std::unique_ptr bitrate_allocator_factory_; + const webrtc::WebRtcKeyValueConfig& trials_; }; class WebRtcVideoChannel : public VideoMediaChannel, @@ -319,8 +321,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, const std::vector& codecs); // Wrapper for the sender part. - class WebRtcVideoSendStream - : public rtc::VideoSourceInterface { + class WebRtcVideoSendStream { public: WebRtcVideoSendStream( webrtc::Call* call, @@ -332,7 +333,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, const absl::optional& codec_settings, const absl::optional>& rtp_extensions, const VideoSendParameters& send_params); - virtual ~WebRtcVideoSendStream(); + ~WebRtcVideoSendStream(); void SetSendParameters(const ChangedSendParameters& send_params); webrtc::RTCError SetRtpParameters(const webrtc::RtpParameters& parameters); @@ -341,14 +342,6 @@ class WebRtcVideoChannel : public VideoMediaChannel, void SetFrameEncryptor( rtc::scoped_refptr frame_encryptor); - // Implements rtc::VideoSourceInterface. - // WebRtcVideoSendStream acts as a source to the webrtc::VideoSendStream - // in |stream_|. This is done to proxy VideoSinkWants from the encoder to - // the worker thread. - void AddOrUpdateSink(rtc::VideoSinkInterface* sink, - const rtc::VideoSinkWants& wants) override; - void RemoveSink(rtc::VideoSinkInterface* sink) override; - bool SetVideoSend(const VideoOptions* options, rtc::VideoSourceInterface* source); @@ -414,8 +407,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, RTC_GUARDED_BY(&thread_checker_); webrtc::VideoSendStream* stream_ RTC_GUARDED_BY(&thread_checker_); - rtc::VideoSinkInterface* encoder_sink_ - RTC_GUARDED_BY(&thread_checker_); + // Contains settings that are the same for all streams in the MediaChannel, // such as codecs, header extensions, and the global bitrate limit for the // entire channel. @@ -429,11 +421,6 @@ class WebRtcVideoChannel : public VideoMediaChannel, bool sending_ RTC_GUARDED_BY(&thread_checker_); - // In order for the |invoker_| to protect other members from being - // destructed as they are used in asynchronous tasks it has to be destructed - // first. - rtc::AsyncInvoker invoker_; - // TODO(asapersson): investigate why setting // DegrationPreferences::MAINTAIN_RESOLUTION isn't sufficient to disable // downscaling everywhere in the pipeline. @@ -566,7 +553,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, void FillSendAndReceiveCodecStats(VideoMediaInfo* video_media_info) RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_); - rtc::Thread* worker_thread_; + rtc::Thread* const worker_thread_; rtc::ThreadChecker thread_checker_; uint32_t rtcp_receiver_report_ssrc_ RTC_GUARDED_BY(thread_checker_); @@ -639,10 +626,6 @@ class WebRtcVideoChannel : public VideoMediaChannel, bool allow_codec_switching_ = false; absl::optional requested_encoder_switch_; - - // In order for the |invoker_| to protect other members from being destructed - // as they are used in asynchronous tasks it has to be destructed first. - rtc::AsyncInvoker invoker_; }; class EncoderStreamFactory @@ -651,7 +634,18 @@ class EncoderStreamFactory EncoderStreamFactory(std::string codec_name, int max_qp, bool is_screenshare, - bool conference_mode); + bool conference_mode) + : EncoderStreamFactory(codec_name, + max_qp, + is_screenshare, + conference_mode, + nullptr) {} + + EncoderStreamFactory(std::string codec_name, + int max_qp, + bool is_screenshare, + bool conference_mode, + const webrtc::WebRtcKeyValueConfig* trials); private: std::vector CreateEncoderStreams( @@ -678,6 +672,8 @@ class EncoderStreamFactory // Allows a screenshare specific configuration, which enables temporal // layering and various settings. const bool conference_mode_; + const webrtc::FieldTrialBasedConfig fallback_trials_; + const webrtc::WebRtcKeyValueConfig& trials_; }; } // namespace cricket diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_voice_engine.cc b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_voice_engine.cc index 749f2506a..fc526f12a 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_voice_engine.cc +++ b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_voice_engine.cc @@ -12,27 +12,30 @@ #include #include +#include #include #include #include #include "absl/algorithm/container.h" #include "absl/strings/match.h" +#include "api/audio/audio_frame_processor.h" #include "api/audio_codecs/audio_codec_pair_id.h" #include "api/call/audio_sink.h" +#include "api/transport/webrtc_key_value_config.h" #include "media/base/audio_source.h" #include "media/base/media_constants.h" #include "media/base/stream_params.h" #include "media/engine/adm_helpers.h" #include "media/engine/payload_type_mapper.h" #include "media/engine/webrtc_media_engine.h" +#include "modules/async_audio_processing/async_audio_processing.h" #include "modules/audio_device/audio_device_impl.h" #include "modules/audio_mixer/audio_mixer_impl.h" #include "modules/audio_processing/aec_dump/aec_dump_factory.h" #include "modules/audio_processing/include/audio_processing.h" #include "rtc_base/arraysize.h" #include "rtc_base/byte_order.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/field_trial_units.h" #include "rtc_base/experiments/struct_parameters_parser.h" @@ -45,7 +48,6 @@ #include "rtc_base/strings/string_format.h" #include "rtc_base/third_party/base64/base64.h" #include "rtc_base/trace_event.h" -#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/metrics.h" #if WEBRTC_ENABLE_PROTOBUF @@ -111,12 +113,6 @@ std::string ToString(const AudioCodec& codec) { return ss.Release(); } -// If this field trial is enabled, we will negotiate and use RFC 2198 -// redundancy for opus audio. -bool IsAudioRedForOpusFieldTrialEnabled() { - return webrtc::field_trial::IsEnabled("WebRTC-Audio-Red-For-Opus"); -} - bool IsCodec(const AudioCodec& codec, const char* ref_name) { return absl::EqualsIgnoreCase(codec.name, ref_name); } @@ -203,6 +199,11 @@ absl::optional ComputeSendBitrate(int max_send_bitrate_bps, } } +bool IsEnabled(const webrtc::WebRtcKeyValueConfig& config, + absl::string_view trial) { + return absl::StartsWith(config.Lookup(trial), "Enabled"); +} + struct AdaptivePtimeConfig { bool enabled = false; webrtc::DataRate min_payload_bitrate = webrtc::DataRate::KilobitsPerSec(16); @@ -219,9 +220,8 @@ struct AdaptivePtimeConfig { "use_slow_adaptation", &use_slow_adaptation); } - AdaptivePtimeConfig() { - Parser()->Parse( - webrtc::field_trial::FindFullName("WebRTC-Audio-AdaptivePtime")); + explicit AdaptivePtimeConfig(const webrtc::WebRtcKeyValueConfig& trials) { + Parser()->Parse(trials.Lookup("WebRTC-Audio-AdaptivePtime")); #if WEBRTC_ENABLE_PROTOBUF webrtc::audio_network_adaptor::config::ControllerManager config; auto* frame_length_controller = @@ -243,13 +243,22 @@ WebRtcVoiceEngine::WebRtcVoiceEngine( const rtc::scoped_refptr& encoder_factory, const rtc::scoped_refptr& decoder_factory, rtc::scoped_refptr audio_mixer, - rtc::scoped_refptr audio_processing) + rtc::scoped_refptr audio_processing, + std::function onUnknownAudioSsrc, + webrtc::AudioFrameProcessor* audio_frame_processor, + const webrtc::WebRtcKeyValueConfig& trials) : task_queue_factory_(task_queue_factory), adm_(adm), encoder_factory_(encoder_factory), decoder_factory_(decoder_factory), audio_mixer_(audio_mixer), - apm_(audio_processing) { + apm_(audio_processing), + onUnknownAudioSsrc_(onUnknownAudioSsrc), + audio_frame_processor_(audio_frame_processor), + audio_red_for_opus_trial_enabled_( + IsEnabled(trials, "WebRTC-Audio-Red-For-Opus")), + minimized_remsampling_on_mobile_trial_enabled_( + IsEnabled(trials, "WebRTC-Audio-MinimizeResamplingOnMobile")) { // This may be called from any thread, so detach thread checkers. worker_thread_checker_.Detach(); signal_thread_checker_.Detach(); @@ -315,6 +324,10 @@ void WebRtcVoiceEngine::Init() { } config.audio_processing = apm_; config.audio_device_module = adm_; + if (audio_frame_processor_) + config.async_audio_processing_factory = + new rtc::RefCountedObject( + *audio_frame_processor_, *task_queue_factory_); audio_state_ = webrtc::AudioState::Create(config); } @@ -415,8 +428,7 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { // performed inside the audio processing module on mobile platforms by // whenever possible turning off the fixed AGC mode and the high-pass filter. // (https://bugs.chromium.org/p/webrtc/issues/detail?id=6181). - if (webrtc::field_trial::IsEnabled( - "WebRTC-Audio-MinimizeResamplingOnMobile")) { + if (minimized_remsampling_on_mobile_trial_enabled_) { options.auto_gain_control = false; RTC_LOG(LS_INFO) << "Disable AGC according to field trial."; if (!(options.noise_suppression.value_or(false) || @@ -581,7 +593,6 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { apm_config.voice_detection.enabled = *options.typing_detection; } - ap->SetExtraOptions(config); ap->ApplyConfig(apm_config); return true; } @@ -723,8 +734,7 @@ std::vector WebRtcVoiceEngine::CollectCodecs( out.push_back(codec); - if (codec.name == kOpusCodecName && - IsAudioRedForOpusFieldTrialEnabled()) { + if (codec.name == kOpusCodecName && audio_red_for_opus_trial_enabled_) { map_format({kRedCodecName, 48000, 2}, &out); } } @@ -768,7 +778,8 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream const absl::optional codec_pair_id, rtc::scoped_refptr frame_encryptor, const webrtc::CryptoOptions& crypto_options) - : call_(call), + : adaptive_ptime_config_(call->trials()), + call_(call), config_(send_transport), max_send_bitrate_bps_(max_send_bitrate_bps), rtp_parameters_(CreateRtpParametersWithOneEncoding()) { @@ -801,6 +812,10 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream stream_ = call_->CreateAudioSendStream(config_); } + WebRtcAudioSendStream() = delete; + WebRtcAudioSendStream(const WebRtcAudioSendStream&) = delete; + WebRtcAudioSendStream& operator=(const WebRtcAudioSendStream&) = delete; + ~WebRtcAudioSendStream() override { RTC_DCHECK(worker_thread_checker_.IsCurrent()); ClearSource(); @@ -1142,8 +1157,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream // TODO(webrtc:11717): Remove this once audio_network_adaptor in AudioOptions // has been removed. absl::optional audio_network_adaptor_config_from_options_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); }; class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { @@ -1192,6 +1205,10 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { RecreateAudioReceiveStream(); } + WebRtcAudioReceiveStream() = delete; + WebRtcAudioReceiveStream(const WebRtcAudioReceiveStream&) = delete; + WebRtcAudioReceiveStream& operator=(const WebRtcAudioReceiveStream&) = delete; + ~WebRtcAudioReceiveStream() { RTC_DCHECK(worker_thread_checker_.IsCurrent()); call_->DestroyAudioReceiveStream(stream_); @@ -1250,10 +1267,11 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { } } - webrtc::AudioReceiveStream::Stats GetStats() const { + webrtc::AudioReceiveStream::Stats GetStats( + bool get_and_clear_legacy_stats) const { RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_DCHECK(stream_); - return stream_->GetStats(); + return stream_->GetStats(get_and_clear_legacy_stats); } void SetRawAudioSink(std::unique_ptr sink) { @@ -1354,8 +1372,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { bool playout_ = false; float output_volume_ = 1.0; std::unique_ptr raw_audio_sink_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); }; WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel( @@ -1368,7 +1384,9 @@ WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel( engine_(engine), call_(call), audio_config_(config.audio), - crypto_options_(crypto_options) { + crypto_options_(crypto_options), + audio_red_for_opus_trial_enabled_( + IsEnabled(call->trials(), "WebRTC-Audio-Red-For-Opus")) { RTC_LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; RTC_DCHECK(call); engine->RegisterChannel(this); @@ -1415,7 +1433,8 @@ bool WebRtcVoiceMediaChannel::SetSendParameters( } std::vector filtered_extensions = FilterRtpExtensions( - params.extensions, webrtc::RtpExtension::IsSupportedForAudio, true); + params.extensions, webrtc::RtpExtension::IsSupportedForAudio, true, + call_->trials()); if (send_rtp_extensions_ != filtered_extensions) { send_rtp_extensions_.swap(filtered_extensions); for (auto& it : send_streams_) { @@ -1452,7 +1471,8 @@ bool WebRtcVoiceMediaChannel::SetRecvParameters( return false; } std::vector filtered_extensions = FilterRtpExtensions( - params.extensions, webrtc::RtpExtension::IsSupportedForAudio, false); + params.extensions, webrtc::RtpExtension::IsSupportedForAudio, false, + call_->trials()); if (recv_rtp_extensions_ != filtered_extensions) { recv_rtp_extensions_.swap(filtered_extensions); for (auto& it : recv_streams_) { @@ -1628,7 +1648,7 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs( } auto format = AudioCodecToSdpAudioFormat(codec); if (!IsCodec(codec, kCnCodecName) && !IsCodec(codec, kDtmfCodecName) && - (!IsAudioRedForOpusFieldTrialEnabled() || + (!audio_red_for_opus_trial_enabled_ || !IsCodec(codec, kRedCodecName)) && !engine()->decoder_factory_->IsSupportedDecoder(format)) { RTC_LOG(LS_ERROR) << "Unsupported codec: " << rtc::ToString(format); @@ -1782,7 +1802,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs( } } - if (IsAudioRedForOpusFieldTrialEnabled()) { + if (audio_red_for_opus_trial_enabled_) { // Loop through the codecs to find the RED codec that matches opus // with respect to clockrate and number of channels. size_t red_codec_position = 0; @@ -2029,6 +2049,11 @@ void WebRtcVoiceMediaChannel::ResetUnsignaledRecvStream() { RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_LOG(LS_INFO) << "ResetUnsignaledRecvStream."; unsignaled_stream_params_ = StreamParams(); + // Create a copy since RemoveRecvStream will modify |unsignaled_recv_ssrcs_|. + std::vector to_remove = unsignaled_recv_ssrcs_; + for (uint32_t ssrc : to_remove) { + RemoveRecvStream(ssrc); + } } bool WebRtcVoiceMediaChannel::SetLocalSource(uint32_t ssrc, @@ -2199,6 +2224,10 @@ void WebRtcVoiceMediaChannel::OnPacketReceived(rtc::CopyOnWriteBuffer packet, } RTC_DCHECK(!absl::c_linear_search(unsignaled_recv_ssrcs_, ssrc)); + if (engine()->onUnknownAudioSsrc_) { + engine()->onUnknownAudioSsrc_(ssrc); + } + // Add new stream. StreamParams sp = unsignaled_stream_params_; sp.ssrcs.push_back(ssrc); @@ -2296,7 +2325,8 @@ void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); } -bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { +bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info, + bool get_and_clear_legacy_stats) { TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::GetStats"); RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_DCHECK(info); @@ -2349,7 +2379,8 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { continue; } } - webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); + webrtc::AudioReceiveStream::Stats stats = + stream.second->GetStats(get_and_clear_legacy_stats); VoiceReceiverInfo rinfo; rinfo.add_ssrc(stats.remote_ssrc); rinfo.payload_bytes_rcvd = stats.payload_bytes_rcvd; diff --git a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_voice_engine.h b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_voice_engine.h index 86a7a495f..b212b3a3f 100644 --- a/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_voice_engine.h +++ b/TMessagesProj/jni/voip/webrtc/media/engine/webrtc_voice_engine.h @@ -20,16 +20,21 @@ #include "api/scoped_refptr.h" #include "api/task_queue/task_queue_factory.h" #include "api/transport/rtp/rtp_source.h" +#include "api/transport/webrtc_key_value_config.h" #include "call/audio_state.h" #include "call/call.h" #include "media/base/media_engine.h" #include "media/base/rtp_utils.h" +#include "modules/async_audio_processing/async_audio_processing.h" #include "rtc_base/buffer.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/network_route.h" #include "rtc_base/task_queue.h" #include "rtc_base/thread_checker.h" +namespace webrtc { +class AudioFrameProcessor; +} + namespace cricket { class AudioDeviceModule; @@ -49,7 +54,15 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { const rtc::scoped_refptr& encoder_factory, const rtc::scoped_refptr& decoder_factory, rtc::scoped_refptr audio_mixer, - rtc::scoped_refptr audio_processing); + rtc::scoped_refptr audio_processing, + std::function onUnknownAudioSsrc, + webrtc::AudioFrameProcessor* audio_frame_processor, + const webrtc::WebRtcKeyValueConfig& trials); + + WebRtcVoiceEngine() = delete; + WebRtcVoiceEngine(const WebRtcVoiceEngine&) = delete; + WebRtcVoiceEngine& operator=(const WebRtcVoiceEngine&) = delete; + ~WebRtcVoiceEngine() override; // Does initialization that needs to occur on the worker thread. @@ -110,6 +123,8 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { rtc::scoped_refptr audio_mixer_; // The audio processing module. rtc::scoped_refptr apm_; + // Asynchronous audio processing. + webrtc::AudioFrameProcessor* const audio_frame_processor_; // The primary instance of WebRtc VoiceEngine. rtc::scoped_refptr audio_state_; std::vector send_codecs_; @@ -119,8 +134,7 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { bool initialized_ = false; // Cache experimental_ns and apply in case they are missing in the audio - // options. We need to do this because SetExtraOptions() will revert to - // defaults for options which are not provided. + // options. absl::optional experimental_ns_; // Jitter buffer settings for new streams. size_t audio_jitter_buffer_max_packets_ = 200; @@ -128,7 +142,12 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { int audio_jitter_buffer_min_delay_ms_ = 0; bool audio_jitter_buffer_enable_rtx_handling_ = false; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcVoiceEngine); + std::function onUnknownAudioSsrc_ = nullptr; + + // If this field trial is enabled, we will negotiate and use RFC 2198 + // redundancy for opus audio. + const bool audio_red_for_opus_trial_enabled_; + const bool minimized_remsampling_on_mobile_trial_enabled_; }; // WebRtcVoiceMediaChannel is an implementation of VoiceMediaChannel that uses @@ -141,6 +160,11 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, const AudioOptions& options, const webrtc::CryptoOptions& crypto_options, webrtc::Call* call); + + WebRtcVoiceMediaChannel() = delete; + WebRtcVoiceMediaChannel(const WebRtcVoiceMediaChannel&) = delete; + WebRtcVoiceMediaChannel& operator=(const WebRtcVoiceMediaChannel&) = delete; + ~WebRtcVoiceMediaChannel() override; const AudioOptions& options() const { return options_; } @@ -196,7 +220,7 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, void OnNetworkRouteChanged(const std::string& transport_name, const rtc::NetworkRoute& network_route) override; void OnReadyToSend(bool ready) override; - bool GetStats(VoiceMediaInfo* info) override; + bool GetStats(VoiceMediaInfo* info, bool get_and_clear_legacy_stats) override; // Set the audio sink for an existing stream. void SetRawAudioSink( @@ -332,7 +356,7 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, rtc::scoped_refptr unsignaled_frame_decryptor_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcVoiceMediaChannel); + const bool audio_red_for_opus_trial_enabled_; }; } // namespace cricket diff --git a/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport.cc b/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport.cc index 2d51623c8..527934d02 100644 --- a/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport.cc +++ b/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport.cc @@ -58,6 +58,7 @@ static constexpr size_t kSctpMtu = 1200; // Set the initial value of the static SCTP Data Engines reference count. ABSL_CONST_INIT int g_usrsctp_usage_count = 0; +ABSL_CONST_INIT bool g_usrsctp_initialized_ = false; ABSL_CONST_INIT webrtc::GlobalMutex g_usrsctp_lock_(absl::kConstInit); // DataMessageType is used for the SCTP "Payload Protocol Identifier", as @@ -262,9 +263,19 @@ class SctpTransport::UsrSctpWrapper { public: static void InitializeUsrSctp() { RTC_LOG(LS_INFO) << __FUNCTION__; - // First argument is udp_encapsulation_port, which is not releveant for our - // AF_CONN use of sctp. - usrsctp_init(0, &UsrSctpWrapper::OnSctpOutboundPacket, &DebugSctpPrintf); + // UninitializeUsrSctp tries to call usrsctp_finish in a loop for three + // seconds; if that failed and we were left in a still-initialized state, we + // don't want to call usrsctp_init again as that will result in undefined + // behavior. + if (g_usrsctp_initialized_) { + RTC_LOG(LS_WARNING) << "Not reinitializing usrsctp since last attempt at " + "usrsctp_finish failed."; + } else { + // First argument is udp_encapsulation_port, which is not releveant for + // our AF_CONN use of sctp. + usrsctp_init(0, &UsrSctpWrapper::OnSctpOutboundPacket, &DebugSctpPrintf); + g_usrsctp_initialized_ = true; + } // To turn on/off detailed SCTP debugging. You will also need to have the // SCTP_DEBUG cpp defines flag, which can be turned on in media/BUILD.gn. @@ -318,6 +329,7 @@ class SctpTransport::UsrSctpWrapper { // closed. Wait and try again until it succeeds for up to 3 seconds. for (size_t i = 0; i < 300; ++i) { if (usrsctp_finish() == 0) { + g_usrsctp_initialized_ = false; delete g_transport_map_; g_transport_map_ = nullptr; return; @@ -394,7 +406,17 @@ class SctpTransport::UsrSctpWrapper { struct sctp_rcvinfo rcv, int flags, void* ulp_info) { - SctpTransport* transport = static_cast(ulp_info); + SctpTransport* transport = GetTransportFromSocket(sock); + if (!transport) { + RTC_LOG(LS_ERROR) + << "OnSctpInboundPacket: Failed to get transport for socket " << sock + << "; possibly was already destroyed."; + free(data); + return 0; + } + // Sanity check that both methods of getting the SctpTransport pointer + // yield the same result. + RTC_CHECK_EQ(transport, static_cast(ulp_info)); int result = transport->OnDataOrNotificationFromSctp(data, length, rcv, flags); free(data); @@ -427,6 +449,8 @@ class SctpTransport::UsrSctpWrapper { return transport; } + // TODO(crbug.com/webrtc/11899): This is a legacy callback signature, remove + // when usrsctp is updated. static int SendThresholdCallback(struct socket* sock, uint32_t sb_free) { // Fired on our I/O thread. SctpTransport::OnPacketReceived() gets // a packet containing acknowledgments, which goes into usrsctp_conninput, @@ -435,12 +459,32 @@ class SctpTransport::UsrSctpWrapper { if (!transport) { RTC_LOG(LS_ERROR) << "SendThresholdCallback: Failed to get transport for socket " - << sock; + << sock << "; possibly was already destroyed."; return 0; } transport->OnSendThresholdCallback(); return 0; } + + static int SendThresholdCallback(struct socket* sock, + uint32_t sb_free, + void* ulp_info) { + // Fired on our I/O thread. SctpTransport::OnPacketReceived() gets + // a packet containing acknowledgments, which goes into usrsctp_conninput, + // and then back here. + SctpTransport* transport = GetTransportFromSocket(sock); + if (!transport) { + RTC_LOG(LS_ERROR) + << "SendThresholdCallback: Failed to get transport for socket " + << sock << "; possibly was already destroyed."; + return 0; + } + // Sanity check that both methods of getting the SctpTransport pointer + // yield the same result. + RTC_CHECK_EQ(transport, static_cast(ulp_info)); + transport->OnSendThresholdCallback(); + return 0; + } }; SctpTransport::SctpTransport(rtc::Thread* network_thread, @@ -870,9 +914,11 @@ bool SctpTransport::ConfigureSctpSocket() { } // Subscribe to SCTP event notifications. + // TODO(crbug.com/1137936): Subscribe to SCTP_SEND_FAILED_EVENT once deadlock + // is fixed upstream, or we switch to the upcall API: + // https://github.com/sctplab/usrsctp/issues/537 int event_types[] = {SCTP_ASSOC_CHANGE, SCTP_PEER_ADDR_CHANGE, - SCTP_SEND_FAILED_EVENT, SCTP_SENDER_DRY_EVENT, - SCTP_STREAM_RESET_EVENT}; + SCTP_SENDER_DRY_EVENT, SCTP_STREAM_RESET_EVENT}; struct sctp_event event = {0}; event.se_assoc_id = SCTP_ALL_ASSOC; event.se_on = 1; @@ -1102,8 +1148,8 @@ int SctpTransport::OnDataOrNotificationFromSctp(void* data, // If data is NULL, the SCTP association has been closed. if (!data) { RTC_LOG(LS_INFO) << debug_name_ - << "->OnSctpInboundPacket(...): " - "No data, closing."; + << "->OnDataOrNotificationFromSctp(...): " + "No data; association closed."; return kSctpSuccessReturn; } @@ -1112,9 +1158,10 @@ int SctpTransport::OnDataOrNotificationFromSctp(void* data, // be handled early and entirely separate from the reassembly // process. if (flags & MSG_NOTIFICATION) { - RTC_LOG(LS_VERBOSE) << debug_name_ - << "->OnSctpInboundPacket(...): SCTP notification" - << " length=" << length; + RTC_LOG(LS_VERBOSE) + << debug_name_ + << "->OnDataOrNotificationFromSctp(...): SCTP notification" + << " length=" << length; // Copy and dispatch asynchronously rtc::CopyOnWriteBuffer notification(reinterpret_cast(data), @@ -1128,7 +1175,7 @@ int SctpTransport::OnDataOrNotificationFromSctp(void* data, // Log data chunk const uint32_t ppid = rtc::NetworkToHost32(rcv.rcv_ppid); RTC_LOG(LS_VERBOSE) << debug_name_ - << "->OnSctpInboundPacket(...): SCTP data chunk" + << "->OnDataOrNotificationFromSctp(...): SCTP data chunk" << " length=" << length << ", sid=" << rcv.rcv_sid << ", ppid=" << ppid << ", ssn=" << rcv.rcv_ssn << ", cum-tsn=" << rcv.rcv_cumtsn @@ -1219,14 +1266,31 @@ void SctpTransport::OnDataFromSctpToTransport( void SctpTransport::OnNotificationFromSctp( const rtc::CopyOnWriteBuffer& buffer) { RTC_DCHECK_RUN_ON(network_thread_); + if (buffer.size() < sizeof(sctp_notification::sn_header)) { + RTC_LOG(LS_ERROR) << "SCTP notification is shorter than header size: " + << buffer.size(); + return; + } + const sctp_notification& notification = reinterpret_cast(*buffer.data()); - RTC_DCHECK(notification.sn_header.sn_length == buffer.size()); + if (buffer.size() != notification.sn_header.sn_length) { + RTC_LOG(LS_ERROR) << "SCTP notification length (" << buffer.size() + << ") does not match sn_length field (" + << notification.sn_header.sn_length << ")."; + return; + } // TODO(ldixon): handle notifications appropriately. switch (notification.sn_header.sn_type) { case SCTP_ASSOC_CHANGE: RTC_LOG(LS_VERBOSE) << "SCTP_ASSOC_CHANGE"; + if (buffer.size() < sizeof(notification.sn_assoc_change)) { + RTC_LOG(LS_ERROR) + << "SCTP_ASSOC_CHANGE notification has less than required length: " + << buffer.size(); + return; + } OnNotificationAssocChange(notification.sn_assoc_change); break; case SCTP_REMOTE_ERROR: @@ -1253,6 +1317,12 @@ void SctpTransport::OnNotificationFromSctp( RTC_LOG(LS_INFO) << "SCTP_NOTIFICATIONS_STOPPED_EVENT"; break; case SCTP_SEND_FAILED_EVENT: { + if (buffer.size() < sizeof(notification.sn_send_failed_event)) { + RTC_LOG(LS_ERROR) << "SCTP_SEND_FAILED_EVENT notification has less " + "than required length: " + << buffer.size(); + return; + } const struct sctp_send_failed_event& ssfe = notification.sn_send_failed_event; RTC_LOG(LS_WARNING) << "SCTP_SEND_FAILED_EVENT: message with" @@ -1265,6 +1335,12 @@ void SctpTransport::OnNotificationFromSctp( break; } case SCTP_STREAM_RESET_EVENT: + if (buffer.size() < sizeof(notification.sn_strreset_event)) { + RTC_LOG(LS_ERROR) << "SCTP_STREAM_RESET_EVENT notification has less " + "than required length: " + << buffer.size(); + return; + } OnStreamResetEvent(¬ification.sn_strreset_event); break; case SCTP_ASSOC_RESET_EVENT: diff --git a/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport.h b/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport.h index 38029ffeb..54542af6b 100644 --- a/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport.h +++ b/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport.h @@ -21,6 +21,7 @@ #include #include "absl/types/optional.h" +#include "api/transport/sctp_transport_factory_interface.h" #include "rtc_base/async_invoker.h" #include "rtc_base/buffer.h" #include "rtc_base/constructor_magic.h" @@ -283,7 +284,7 @@ class SctpTransport : public SctpTransportInternal, RTC_DISALLOW_COPY_AND_ASSIGN(SctpTransport); }; -class SctpTransportFactory : public SctpTransportInternalFactory { +class SctpTransportFactory : public webrtc::SctpTransportFactoryInterface { public: explicit SctpTransportFactory(rtc::Thread* network_thread) : network_thread_(network_thread) {} diff --git a/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport_internal.h b/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport_internal.h index b0e0e0f7e..dc8ac4558 100644 --- a/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport_internal.h +++ b/TMessagesProj/jni/voip/webrtc/media/sctp/sctp_transport_internal.h @@ -142,18 +142,6 @@ class SctpTransportInternal { virtual void set_debug_name_for_testing(const char* debug_name) = 0; }; -// Factory class which can be used to allow fake SctpTransports to be injected -// for testing. Or, theoretically, SctpTransportInternal implementations that -// use something other than usrsctp. -class SctpTransportInternalFactory { - public: - virtual ~SctpTransportInternalFactory() {} - - // Create an SCTP transport using |channel| for the underlying transport. - virtual std::unique_ptr CreateSctpTransport( - rtc::PacketTransportInternal* channel) = 0; -}; - } // namespace cricket #endif // MEDIA_SCTP_SCTP_TRANSPORT_INTERNAL_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/async_audio_processing/async_audio_processing.cc b/TMessagesProj/jni/voip/webrtc/modules/async_audio_processing/async_audio_processing.cc new file mode 100644 index 000000000..9452f3bcf --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/async_audio_processing/async_audio_processing.cc @@ -0,0 +1,61 @@ + +/* + * Copyright (c) 2020 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/async_audio_processing/async_audio_processing.h" + +#include + +#include "api/audio/audio_frame.h" +#include "api/task_queue/task_queue_factory.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +AsyncAudioProcessing::Factory::~Factory() = default; +AsyncAudioProcessing::Factory::Factory(AudioFrameProcessor& frame_processor, + TaskQueueFactory& task_queue_factory) + : frame_processor_(frame_processor), + task_queue_factory_(task_queue_factory) {} + +std::unique_ptr +AsyncAudioProcessing::Factory::CreateAsyncAudioProcessing( + AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback) { + return std::make_unique( + frame_processor_, task_queue_factory_, + std::move(on_frame_processed_callback)); +} + +AsyncAudioProcessing::~AsyncAudioProcessing() { + frame_processor_.SetSink(nullptr); +} + +AsyncAudioProcessing::AsyncAudioProcessing( + AudioFrameProcessor& frame_processor, + TaskQueueFactory& task_queue_factory, + AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback) + : on_frame_processed_callback_(std::move(on_frame_processed_callback)), + frame_processor_(frame_processor), + task_queue_(task_queue_factory.CreateTaskQueue( + "AsyncAudioProcessing", + TaskQueueFactory::Priority::NORMAL)) { + frame_processor_.SetSink([this](std::unique_ptr frame) { + task_queue_.PostTask([this, frame = std::move(frame)]() mutable { + on_frame_processed_callback_(std::move(frame)); + }); + }); +} + +void AsyncAudioProcessing::Process(std::unique_ptr frame) { + task_queue_.PostTask([this, frame = std::move(frame)]() mutable { + frame_processor_.Process(std::move(frame)); + }); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/async_audio_processing/async_audio_processing.h b/TMessagesProj/jni/voip/webrtc/modules/async_audio_processing/async_audio_processing.h new file mode 100644 index 000000000..7e09d69f1 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/async_audio_processing/async_audio_processing.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef MODULES_ASYNC_AUDIO_PROCESSING_ASYNC_AUDIO_PROCESSING_H_ +#define MODULES_ASYNC_AUDIO_PROCESSING_ASYNC_AUDIO_PROCESSING_H_ + +#include + +#include "api/audio/audio_frame_processor.h" +#include "rtc_base/ref_count.h" +#include "rtc_base/task_queue.h" + +namespace webrtc { + +class AudioFrame; +class TaskQueueFactory; + +// Helper class taking care of interactions with AudioFrameProcessor +// in asynchronous manner. Offloads AudioFrameProcessor::Process calls +// to a dedicated task queue. Makes sure that it's always safe for +// AudioFrameProcessor to pass processed frames back to its sink. +class AsyncAudioProcessing final { + public: + // Helper class passing AudioFrameProcessor and TaskQueueFactory into + // AsyncAudioProcessing constructor. + class Factory : public rtc::RefCountInterface { + public: + Factory(const Factory&) = delete; + Factory& operator=(const Factory&) = delete; + + ~Factory(); + Factory(AudioFrameProcessor& frame_processor, + TaskQueueFactory& task_queue_factory); + + std::unique_ptr CreateAsyncAudioProcessing( + AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback); + + private: + AudioFrameProcessor& frame_processor_; + TaskQueueFactory& task_queue_factory_; + }; + + AsyncAudioProcessing(const AsyncAudioProcessing&) = delete; + AsyncAudioProcessing& operator=(const AsyncAudioProcessing&) = delete; + + ~AsyncAudioProcessing(); + + // Creates AsyncAudioProcessing which will pass audio frames to + // |frame_processor| on |task_queue_| and reply with processed frames passed + // into |on_frame_processed_callback|, which is posted back onto + // |task_queue_|. |task_queue_| is created using the provided + // |task_queue_factory|. + AsyncAudioProcessing( + AudioFrameProcessor& frame_processor, + TaskQueueFactory& task_queue_factory, + AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback); + + // Accepts |frame| for asynchronous processing. Thread-safe. + void Process(std::unique_ptr frame); + + private: + AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback_; + AudioFrameProcessor& frame_processor_; + rtc::TaskQueue task_queue_; +}; + +} // namespace webrtc + +#endif // MODULES_ASYNC_AUDIO_PROCESSING_ASYNC_AUDIO_PROCESSING_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/acm2/acm_receiver.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/acm2/acm_receiver.cc index 33142c783..0e615cae8 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/acm2/acm_receiver.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/acm2/acm_receiver.cc @@ -244,26 +244,37 @@ absl::optional> AcmReceiver::LastDecoder() return std::make_pair(last_decoder_->payload_type, last_decoder_->sdp_format); } -void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) const { +void AcmReceiver::GetNetworkStatistics( + NetworkStatistics* acm_stat, + bool get_and_clear_legacy_stats /* = true */) const { NetEqNetworkStatistics neteq_stat; - // NetEq function always returns zero, so we don't check the return value. - neteq_->NetworkStatistics(&neteq_stat); + if (get_and_clear_legacy_stats) { + // NetEq function always returns zero, so we don't check the return value. + neteq_->NetworkStatistics(&neteq_stat); + acm_stat->currentExpandRate = neteq_stat.expand_rate; + acm_stat->currentSpeechExpandRate = neteq_stat.speech_expand_rate; + acm_stat->currentPreemptiveRate = neteq_stat.preemptive_rate; + acm_stat->currentAccelerateRate = neteq_stat.accelerate_rate; + acm_stat->currentSecondaryDecodedRate = neteq_stat.secondary_decoded_rate; + acm_stat->currentSecondaryDiscardedRate = + neteq_stat.secondary_discarded_rate; + acm_stat->meanWaitingTimeMs = neteq_stat.mean_waiting_time_ms; + acm_stat->maxWaitingTimeMs = neteq_stat.max_waiting_time_ms; + } else { + neteq_stat = neteq_->CurrentNetworkStatistics(); + acm_stat->currentExpandRate = 0; + acm_stat->currentSpeechExpandRate = 0; + acm_stat->currentPreemptiveRate = 0; + acm_stat->currentAccelerateRate = 0; + acm_stat->currentSecondaryDecodedRate = 0; + acm_stat->currentSecondaryDiscardedRate = 0; + acm_stat->meanWaitingTimeMs = -1; + acm_stat->maxWaitingTimeMs = 1; + } acm_stat->currentBufferSize = neteq_stat.current_buffer_size_ms; acm_stat->preferredBufferSize = neteq_stat.preferred_buffer_size_ms; acm_stat->jitterPeaksFound = neteq_stat.jitter_peaks_found ? true : false; - acm_stat->currentPacketLossRate = neteq_stat.packet_loss_rate; - acm_stat->currentExpandRate = neteq_stat.expand_rate; - acm_stat->currentSpeechExpandRate = neteq_stat.speech_expand_rate; - acm_stat->currentPreemptiveRate = neteq_stat.preemptive_rate; - acm_stat->currentAccelerateRate = neteq_stat.accelerate_rate; - acm_stat->currentSecondaryDecodedRate = neteq_stat.secondary_decoded_rate; - acm_stat->currentSecondaryDiscardedRate = neteq_stat.secondary_discarded_rate; - acm_stat->addedSamples = neteq_stat.added_zero_samples; - acm_stat->meanWaitingTimeMs = neteq_stat.mean_waiting_time_ms; - acm_stat->medianWaitingTimeMs = neteq_stat.median_waiting_time_ms; - acm_stat->minWaitingTimeMs = neteq_stat.min_waiting_time_ms; - acm_stat->maxWaitingTimeMs = neteq_stat.max_waiting_time_ms; NetEqLifetimeStatistics neteq_lifetime_stat = neteq_->GetLifetimeStatistics(); acm_stat->totalSamplesReceived = neteq_lifetime_stat.total_samples_received; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/acm2/acm_receiver.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/acm2/acm_receiver.h index d451a94ef..19dc57758 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/acm2/acm_receiver.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/acm2/acm_receiver.h @@ -138,7 +138,8 @@ class AcmReceiver { // Output: // - statistics : The current network statistics. // - void GetNetworkStatistics(NetworkStatistics* statistics) const; + void GetNetworkStatistics(NetworkStatistics* statistics, + bool get_and_clear_legacy_stats = true) const; // // Flushes the NetEq packet and speech buffers. diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc index eee6f403a..40c865906 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.cc @@ -53,11 +53,6 @@ void BitrateController::MakeDecision(AudioEncoderRuntimeConfig* config) { // Decision on |bitrate_bps| should not have been made. RTC_DCHECK(!config->bitrate_bps); if (target_audio_bitrate_bps_ && overhead_bytes_per_packet_) { - // Current implementation of BitrateController can only work when - // |metrics.target_audio_bitrate_bps| includes overhead is enabled. This is - // currently governed by the following field trial. - RTC_DCHECK( - webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")); if (config->frame_length_ms) frame_length_ms_ = *config->frame_length_ms; int offset = config->last_fl_change_increase diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc index 032de2024..9fbf42cee 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc @@ -34,7 +34,7 @@ int GetIlbcBitrate(int ptime) { // 50 bytes per frame of 30 ms => (approx) 13333 bits/s. return 13333; default: - FATAL(); + RTC_CHECK_NOTREACHED(); } } @@ -144,7 +144,7 @@ size_t AudioEncoderIlbcImpl::RequiredOutputSizeBytes() const { case 6: return 2 * 50; default: - FATAL(); + RTC_CHECK_NOTREACHED(); } } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c index 326c766a9..8ebe51308 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c @@ -260,9 +260,10 @@ size_t WebRtcIlbcfix_DecodePlc(IlbcDecoderInstance* iLBCdec_inst, for (i=0;iblockl], &dummy, - (IlbcDecoder*)iLBCdec_inst, 0)); + (IlbcDecoder*)iLBCdec_inst, 0); + RTC_CHECK_EQ(result, 0); } return (noOfLostFrames*((IlbcDecoder*)iLBCdec_inst)->blockl); } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h index d99e9c893..8bde0e34a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h @@ -93,7 +93,7 @@ class AudioEncoderIsacT final : public AudioEncoder { // Cache the value of the "WebRTC-SendSideBwe-WithOverhead" field trial. const bool send_side_bwe_with_overhead_ = - field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead"); + !field_trial::IsDisabled("WebRTC-SendSideBwe-WithOverhead"); // When we send a packet, expect this many bytes of headers to be added to it. // Start out with a reasonable default that we can use until we receive a real diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c index 36fbdd6bb..067d8f358 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c @@ -26,7 +26,6 @@ #include "modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h" #include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h" #include "modules/audio_coding/codecs/isac/fix/source/structs.h" -#include "system_wrappers/include/cpu_features_wrapper.h" // Declare function pointers. FilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc index 2b1692071..203cb5aeb 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc @@ -356,7 +356,7 @@ AudioEncoderOpusImpl::AudioEncoderOpusImpl( std::unique_ptr bitrate_smoother) : payload_type_(payload_type), send_side_bwe_with_overhead_( - webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), + !webrtc::field_trial::IsDisabled("WebRTC-SendSideBwe-WithOverhead")), use_stable_target_for_adaptation_(!webrtc::field_trial::IsDisabled( "WebRTC-Audio-StableTargetAdaptation")), adjust_bandwidth_( @@ -367,7 +367,8 @@ AudioEncoderOpusImpl::AudioEncoderOpusImpl( inst_(nullptr), packet_loss_fraction_smoother_(new PacketLossFractionSmoother()), audio_network_adaptor_creator_(audio_network_adaptor_creator), - bitrate_smoother_(std::move(bitrate_smoother)) { + bitrate_smoother_(std::move(bitrate_smoother)), + consecutive_dtx_frames_(0) { RTC_DCHECK(0 <= payload_type && payload_type <= 127); // Sanity check of the redundant payload type field that we want to get rid @@ -589,7 +590,6 @@ AudioEncoder::EncodedInfo AudioEncoderOpusImpl::EncodeImpl( Num10msFramesPerPacket() * SamplesPer10msFrame()); const size_t max_encoded_bytes = SufficientOutputBufferSize(); - const size_t start_offset_bytes = encoded->size(); EncodedInfo info; info.encoded_bytes = encoded->AppendData( max_encoded_bytes, [&](rtc::ArrayView encoded) { @@ -604,6 +604,8 @@ AudioEncoder::EncodedInfo AudioEncoderOpusImpl::EncodeImpl( }); input_buffer_.clear(); + bool dtx_frame = (info.encoded_bytes <= 2); + // Will use new packet size for next encoding. config_.frame_size_ms = next_frame_length_ms_; @@ -618,18 +620,14 @@ AudioEncoder::EncodedInfo AudioEncoderOpusImpl::EncodeImpl( info.encoded_timestamp = first_timestamp_in_buffer_; info.payload_type = payload_type_; info.send_even_if_empty = true; // Allows Opus to send empty packets. + // After 20 DTX frames (MAX_CONSECUTIVE_DTX) Opus will send a frame + // coding the background noise. Avoid flagging this frame as speech + // (even though there is a probability of the frame being speech). + info.speech = !dtx_frame && (consecutive_dtx_frames_ != 20); info.encoder_type = CodecType::kOpus; - // Extract the VAD result from the encoded packet. - int has_voice = WebRtcOpus_PacketHasVoiceActivity( - &encoded->data()[start_offset_bytes], info.encoded_bytes); - if (has_voice == -1) { - // CELT mode packet or there was an error. This had set the speech flag to - // true historically. - info.speech = true; - } else { - info.speech = has_voice; - } + // Increase or reset DTX counter. + consecutive_dtx_frames_ = (dtx_frame) ? (consecutive_dtx_frames_ + 1) : (0); return info; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h index dc955cec2..ab954feba 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h @@ -172,6 +172,7 @@ class AudioEncoderOpusImpl final : public AudioEncoder { absl::optional overhead_bytes_per_packet_; const std::unique_ptr bitrate_smoother_; absl::optional bitrate_smoother_last_update_time_; + int consecutive_dtx_frames_; friend struct AudioEncoderOpus; RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderOpusImpl); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_fec_test.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_fec_test.cc new file mode 100644 index 000000000..1923647fb --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_fec_test.cc @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2014 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 + +#include "modules/audio_coding/codecs/opus/opus_interface.h" +#include "rtc_base/format_macros.h" +#include "test/gtest.h" +#include "test/testsupport/file_utils.h" + +using std::get; +using std::string; +using std::tuple; +using ::testing::TestWithParam; + +namespace webrtc { + +// Define coding parameter as . +typedef tuple coding_param; +typedef struct mode mode; + +struct mode { + bool fec; + uint8_t target_packet_loss_rate; +}; + +const int kOpusBlockDurationMs = 20; +const int kOpusSamplingKhz = 48; + +class OpusFecTest : public TestWithParam { + protected: + OpusFecTest(); + + void SetUp() override; + void TearDown() override; + + virtual void EncodeABlock(); + + virtual void DecodeABlock(bool lost_previous, bool lost_current); + + int block_duration_ms_; + int sampling_khz_; + size_t block_length_sample_; + + size_t channels_; + int bit_rate_; + + size_t data_pointer_; + size_t loop_length_samples_; + size_t max_bytes_; + size_t encoded_bytes_; + + WebRtcOpusEncInst* opus_encoder_; + WebRtcOpusDecInst* opus_decoder_; + + string in_filename_; + + std::unique_ptr in_data_; + std::unique_ptr out_data_; + std::unique_ptr bit_stream_; +}; + +void OpusFecTest::SetUp() { + channels_ = get<0>(GetParam()); + bit_rate_ = get<1>(GetParam()); + printf("Coding %" RTC_PRIuS " channel signal at %d bps.\n", channels_, + bit_rate_); + + in_filename_ = test::ResourcePath(get<2>(GetParam()), get<3>(GetParam())); + + FILE* fp = fopen(in_filename_.c_str(), "rb"); + ASSERT_FALSE(fp == NULL); + + // Obtain file size. + fseek(fp, 0, SEEK_END); + loop_length_samples_ = ftell(fp) / sizeof(int16_t); + rewind(fp); + + // Allocate memory to contain the whole file. + in_data_.reset( + new int16_t[loop_length_samples_ + block_length_sample_ * channels_]); + + // Copy the file into the buffer. + ASSERT_EQ(fread(&in_data_[0], sizeof(int16_t), loop_length_samples_, fp), + loop_length_samples_); + fclose(fp); + + // The audio will be used in a looped manner. To ease the acquisition of an + // audio frame that crosses the end of the excerpt, we add an extra block + // length of samples to the end of the array, starting over again from the + // beginning of the array. Audio frames cross the end of the excerpt always + // appear as a continuum of memory. + memcpy(&in_data_[loop_length_samples_], &in_data_[0], + block_length_sample_ * channels_ * sizeof(int16_t)); + + // Maximum number of bytes in output bitstream. + max_bytes_ = block_length_sample_ * channels_ * sizeof(int16_t); + + out_data_.reset(new int16_t[2 * block_length_sample_ * channels_]); + bit_stream_.reset(new uint8_t[max_bytes_]); + + // If channels_ == 1, use Opus VOIP mode, otherwise, audio mode. + int app = channels_ == 1 ? 0 : 1; + + // Create encoder memory. + EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, app, 48000)); + EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_, 48000)); + // Set bitrate. + EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, bit_rate_)); +} + +void OpusFecTest::TearDown() { + // Free memory. + EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); + EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); +} + +OpusFecTest::OpusFecTest() + : block_duration_ms_(kOpusBlockDurationMs), + sampling_khz_(kOpusSamplingKhz), + block_length_sample_( + static_cast(block_duration_ms_ * sampling_khz_)), + data_pointer_(0), + max_bytes_(0), + encoded_bytes_(0), + opus_encoder_(NULL), + opus_decoder_(NULL) {} + +void OpusFecTest::EncodeABlock() { + int value = + WebRtcOpus_Encode(opus_encoder_, &in_data_[data_pointer_], + block_length_sample_, max_bytes_, &bit_stream_[0]); + EXPECT_GT(value, 0); + + encoded_bytes_ = static_cast(value); +} + +void OpusFecTest::DecodeABlock(bool lost_previous, bool lost_current) { + int16_t audio_type; + int value_1 = 0, value_2 = 0; + + if (lost_previous) { + // Decode previous frame. + if (!lost_current && + WebRtcOpus_PacketHasFec(&bit_stream_[0], encoded_bytes_) == 1) { + value_1 = + WebRtcOpus_DecodeFec(opus_decoder_, &bit_stream_[0], encoded_bytes_, + &out_data_[0], &audio_type); + } else { + // Call decoder PLC. + while (value_1 < static_cast(block_length_sample_)) { + int ret = WebRtcOpus_Decode(opus_decoder_, NULL, 0, &out_data_[value_1], + &audio_type); + EXPECT_EQ(ret, sampling_khz_ * 10); // Should return 10 ms of samples. + value_1 += ret; + } + } + EXPECT_EQ(static_cast(block_length_sample_), value_1); + } + + if (!lost_current) { + // Decode current frame. + value_2 = WebRtcOpus_Decode(opus_decoder_, &bit_stream_[0], encoded_bytes_, + &out_data_[value_1 * channels_], &audio_type); + EXPECT_EQ(static_cast(block_length_sample_), value_2); + } +} + +TEST_P(OpusFecTest, RandomPacketLossTest) { + const int kDurationMs = 200000; + int time_now_ms, fec_frames; + int actual_packet_loss_rate; + bool lost_current, lost_previous; + mode mode_set[3] = {{true, 0}, {false, 0}, {true, 50}}; + + lost_current = false; + for (int i = 0; i < 3; i++) { + if (mode_set[i].fec) { + EXPECT_EQ(0, WebRtcOpus_EnableFec(opus_encoder_)); + EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate( + opus_encoder_, mode_set[i].target_packet_loss_rate)); + printf("FEC is ON, target at packet loss rate %d percent.\n", + mode_set[i].target_packet_loss_rate); + } else { + EXPECT_EQ(0, WebRtcOpus_DisableFec(opus_encoder_)); + printf("FEC is OFF.\n"); + } + // In this test, we let the target packet loss rate match the actual rate. + actual_packet_loss_rate = mode_set[i].target_packet_loss_rate; + // Run every mode a certain time. + time_now_ms = 0; + fec_frames = 0; + while (time_now_ms < kDurationMs) { + // Encode & decode. + EncodeABlock(); + + // Check if payload has FEC. + int fec = WebRtcOpus_PacketHasFec(&bit_stream_[0], encoded_bytes_); + + // If FEC is disabled or the target packet loss rate is set to 0, there + // should be no FEC in the bit stream. + if (!mode_set[i].fec || mode_set[i].target_packet_loss_rate == 0) { + EXPECT_EQ(fec, 0); + } else if (fec == 1) { + fec_frames++; + } + + lost_previous = lost_current; + lost_current = rand() < actual_packet_loss_rate * (RAND_MAX / 100); + DecodeABlock(lost_previous, lost_current); + + time_now_ms += block_duration_ms_; + + // |data_pointer_| is incremented and wrapped across + // |loop_length_samples_|. + data_pointer_ = (data_pointer_ + block_length_sample_ * channels_) % + loop_length_samples_; + } + if (mode_set[i].fec) { + printf("%.2f percent frames has FEC.\n", + static_cast(fec_frames) * block_duration_ms_ / 2000); + } + } +} + +const coding_param param_set[] = { + std::make_tuple(1, + 64000, + string("audio_coding/testfile32kHz"), + string("pcm")), + std::make_tuple(1, + 32000, + string("audio_coding/testfile32kHz"), + string("pcm")), + std::make_tuple(2, + 64000, + string("audio_coding/teststereo32kHz"), + string("pcm"))}; + +// 64 kbps, stereo +INSTANTIATE_TEST_SUITE_P(AllTest, OpusFecTest, ::testing::ValuesIn(param_set)); + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_interface.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_interface.cc index 455f17546..ca39ed823 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_interface.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_interface.cc @@ -767,7 +767,7 @@ int WebRtcOpus_PacketHasVoiceActivity(const uint8_t* payload, int silk_frames = WebRtcOpus_NumSilkFrames(payload); if (silk_frames == 0) - return 0; + return -1; const int channels = opus_packet_get_nb_channels(payload); RTC_DCHECK(channels == 1 || channels == 2); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc new file mode 100644 index 000000000..4477e8a5f --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2014 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/audio_coding/codecs/opus/opus_interface.h" +#include "modules/audio_coding/codecs/tools/audio_codec_speed_test.h" + +using ::std::string; + +namespace webrtc { + +static const int kOpusBlockDurationMs = 20; +static const int kOpusSamplingKhz = 48; + +class OpusSpeedTest : public AudioCodecSpeedTest { + protected: + OpusSpeedTest(); + void SetUp() override; + void TearDown() override; + float EncodeABlock(int16_t* in_data, + uint8_t* bit_stream, + size_t max_bytes, + size_t* encoded_bytes) override; + float DecodeABlock(const uint8_t* bit_stream, + size_t encoded_bytes, + int16_t* out_data) override; + WebRtcOpusEncInst* opus_encoder_; + WebRtcOpusDecInst* opus_decoder_; +}; + +OpusSpeedTest::OpusSpeedTest() + : AudioCodecSpeedTest(kOpusBlockDurationMs, + kOpusSamplingKhz, + kOpusSamplingKhz), + opus_encoder_(NULL), + opus_decoder_(NULL) {} + +void OpusSpeedTest::SetUp() { + AudioCodecSpeedTest::SetUp(); + // If channels_ == 1, use Opus VOIP mode, otherwise, audio mode. + int app = channels_ == 1 ? 0 : 1; + /* Create encoder memory. */ + EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, app, 48000)); + EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_, 48000)); + /* Set bitrate. */ + EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, bit_rate_)); +} + +void OpusSpeedTest::TearDown() { + AudioCodecSpeedTest::TearDown(); + /* Free memory. */ + EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); + EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); +} + +float OpusSpeedTest::EncodeABlock(int16_t* in_data, + uint8_t* bit_stream, + size_t max_bytes, + size_t* encoded_bytes) { + clock_t clocks = clock(); + int value = WebRtcOpus_Encode(opus_encoder_, in_data, input_length_sample_, + max_bytes, bit_stream); + clocks = clock() - clocks; + EXPECT_GT(value, 0); + *encoded_bytes = static_cast(value); + return 1000.0 * clocks / CLOCKS_PER_SEC; +} + +float OpusSpeedTest::DecodeABlock(const uint8_t* bit_stream, + size_t encoded_bytes, + int16_t* out_data) { + int value; + int16_t audio_type; + clock_t clocks = clock(); + value = WebRtcOpus_Decode(opus_decoder_, bit_stream, encoded_bytes, out_data, + &audio_type); + clocks = clock() - clocks; + EXPECT_EQ(output_length_sample_, static_cast(value)); + return 1000.0 * clocks / CLOCKS_PER_SEC; +} + +/* Test audio length in second. */ +constexpr size_t kDurationSec = 400; + +#define ADD_TEST(complexity) \ + TEST_P(OpusSpeedTest, OpusSetComplexityTest##complexity) { \ + /* Set complexity. */ \ + printf("Setting complexity to %d ...\n", complexity); \ + EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, complexity)); \ + EncodeDecode(kDurationSec); \ + } + +ADD_TEST(10) +ADD_TEST(9) +ADD_TEST(8) +ADD_TEST(7) +ADD_TEST(6) +ADD_TEST(5) +ADD_TEST(4) +ADD_TEST(3) +ADD_TEST(2) +ADD_TEST(1) +ADD_TEST(0) + +#define ADD_BANDWIDTH_TEST(bandwidth) \ + TEST_P(OpusSpeedTest, OpusSetBandwidthTest##bandwidth) { \ + /* Set bandwidth. */ \ + printf("Setting bandwidth to %d ...\n", bandwidth); \ + EXPECT_EQ(0, WebRtcOpus_SetBandwidth(opus_encoder_, bandwidth)); \ + EncodeDecode(kDurationSec); \ + } + +ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_NARROWBAND) +ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_MEDIUMBAND) +ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_WIDEBAND) +ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_SUPERWIDEBAND) +ADD_BANDWIDTH_TEST(OPUS_BANDWIDTH_FULLBAND) + +// List all test cases: (channel, bit rat, filename, extension). +const coding_param param_set[] = { + std::make_tuple(1, + 64000, + string("audio_coding/speech_mono_32_48kHz"), + string("pcm"), + true), + std::make_tuple(1, + 32000, + string("audio_coding/speech_mono_32_48kHz"), + string("pcm"), + true), + std::make_tuple(2, + 64000, + string("audio_coding/music_stereo_48kHz"), + string("pcm"), + true)}; + +INSTANTIATE_TEST_SUITE_P(AllTest, + OpusSpeedTest, + ::testing::ValuesIn(param_set)); + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.cc deleted file mode 100644 index 2a71b43d2..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2015 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/audio_coding/codecs/opus/test/audio_ring_buffer.h" - -#include "common_audio/ring_buffer.h" -#include "rtc_base/checks.h" - -// This is a simple multi-channel wrapper over the ring_buffer.h C interface. - -namespace webrtc { - -AudioRingBuffer::AudioRingBuffer(size_t channels, size_t max_frames) { - buffers_.reserve(channels); - for (size_t i = 0; i < channels; ++i) - buffers_.push_back(WebRtc_CreateBuffer(max_frames, sizeof(float))); -} - -AudioRingBuffer::~AudioRingBuffer() { - for (auto* buf : buffers_) - WebRtc_FreeBuffer(buf); -} - -void AudioRingBuffer::Write(const float* const* data, - size_t channels, - size_t frames) { - RTC_DCHECK_EQ(buffers_.size(), channels); - for (size_t i = 0; i < channels; ++i) { - const size_t written = WebRtc_WriteBuffer(buffers_[i], data[i], frames); - RTC_CHECK_EQ(written, frames); - } -} - -void AudioRingBuffer::Read(float* const* data, size_t channels, size_t frames) { - RTC_DCHECK_EQ(buffers_.size(), channels); - for (size_t i = 0; i < channels; ++i) { - const size_t read = - WebRtc_ReadBuffer(buffers_[i], nullptr, data[i], frames); - RTC_CHECK_EQ(read, frames); - } -} - -size_t AudioRingBuffer::ReadFramesAvailable() const { - // All buffers have the same amount available. - return WebRtc_available_read(buffers_[0]); -} - -size_t AudioRingBuffer::WriteFramesAvailable() const { - // All buffers have the same amount available. - return WebRtc_available_write(buffers_[0]); -} - -void AudioRingBuffer::MoveReadPositionForward(size_t frames) { - for (auto* buf : buffers_) { - const size_t moved = - static_cast(WebRtc_MoveReadPtr(buf, static_cast(frames))); - RTC_CHECK_EQ(moved, frames); - } -} - -void AudioRingBuffer::MoveReadPositionBackward(size_t frames) { - for (auto* buf : buffers_) { - const size_t moved = static_cast( - -WebRtc_MoveReadPtr(buf, -static_cast(frames))); - RTC_CHECK_EQ(moved, frames); - } -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.h deleted file mode 100644 index a89dfd8ca..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/audio_ring_buffer.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015 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. - */ -#ifndef MODULES_AUDIO_CODING_CODECS_OPUS_TEST_AUDIO_RING_BUFFER_H_ -#define MODULES_AUDIO_CODING_CODECS_OPUS_TEST_AUDIO_RING_BUFFER_H_ - -#include - -#include -#include - -struct RingBuffer; - -namespace webrtc { - -// A ring buffer tailored for float deinterleaved audio. Any operation that -// cannot be performed as requested will cause a crash (e.g. insufficient data -// in the buffer to fulfill a read request.) -class AudioRingBuffer final { - public: - // Specify the number of channels and maximum number of frames the buffer will - // contain. - AudioRingBuffer(size_t channels, size_t max_frames); - ~AudioRingBuffer(); - - // Copies |data| to the buffer and advances the write pointer. |channels| must - // be the same as at creation time. - void Write(const float* const* data, size_t channels, size_t frames); - - // Copies from the buffer to |data| and advances the read pointer. |channels| - // must be the same as at creation time. - void Read(float* const* data, size_t channels, size_t frames); - - size_t ReadFramesAvailable() const; - size_t WriteFramesAvailable() const; - - // Moves the read position. The forward version advances the read pointer - // towards the write pointer and the backward verison withdraws the read - // pointer away from the write pointer (i.e. flushing and stuffing the buffer - // respectively.) - void MoveReadPositionForward(size_t frames); - void MoveReadPositionBackward(size_t frames); - - private: - // TODO(kwiberg): Use std::vector> instead. - std::vector buffers_; -}; - -} // namespace webrtc - -#endif // MODULES_AUDIO_CODING_CODECS_OPUS_TEST_AUDIO_RING_BUFFER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.cc deleted file mode 100644 index 7f102b54a..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2014 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/audio_coding/codecs/opus/test/blocker.h" - -#include - -#include "rtc_base/checks.h" - -namespace { - -// Adds |a| and |b| frame by frame into |result| (basically matrix addition). -void AddFrames(const float* const* a, - size_t a_start_index, - const float* const* b, - int b_start_index, - size_t num_frames, - size_t num_channels, - float* const* result, - size_t result_start_index) { - for (size_t i = 0; i < num_channels; ++i) { - for (size_t j = 0; j < num_frames; ++j) { - result[i][j + result_start_index] = - a[i][j + a_start_index] + b[i][j + b_start_index]; - } - } -} - -// Copies |src| into |dst| channel by channel. -void CopyFrames(const float* const* src, - size_t src_start_index, - size_t num_frames, - size_t num_channels, - float* const* dst, - size_t dst_start_index) { - for (size_t i = 0; i < num_channels; ++i) { - memcpy(&dst[i][dst_start_index], &src[i][src_start_index], - num_frames * sizeof(dst[i][dst_start_index])); - } -} - -// Moves |src| into |dst| channel by channel. -void MoveFrames(const float* const* src, - size_t src_start_index, - size_t num_frames, - size_t num_channels, - float* const* dst, - size_t dst_start_index) { - for (size_t i = 0; i < num_channels; ++i) { - memmove(&dst[i][dst_start_index], &src[i][src_start_index], - num_frames * sizeof(dst[i][dst_start_index])); - } -} - -void ZeroOut(float* const* buffer, - size_t starting_idx, - size_t num_frames, - size_t num_channels) { - for (size_t i = 0; i < num_channels; ++i) { - memset(&buffer[i][starting_idx], 0, - num_frames * sizeof(buffer[i][starting_idx])); - } -} - -// Pointwise multiplies each channel of |frames| with |window|. Results are -// stored in |frames|. -void ApplyWindow(const float* window, - size_t num_frames, - size_t num_channels, - float* const* frames) { - for (size_t i = 0; i < num_channels; ++i) { - for (size_t j = 0; j < num_frames; ++j) { - frames[i][j] = frames[i][j] * window[j]; - } - } -} - -size_t gcd(size_t a, size_t b) { - size_t tmp; - while (b) { - tmp = a; - a = b; - b = tmp % b; - } - return a; -} - -} // namespace - -namespace webrtc { - -Blocker::Blocker(size_t chunk_size, - size_t block_size, - size_t num_input_channels, - size_t num_output_channels, - const float* window, - size_t shift_amount, - BlockerCallback* callback) - : chunk_size_(chunk_size), - block_size_(block_size), - num_input_channels_(num_input_channels), - num_output_channels_(num_output_channels), - initial_delay_(block_size_ - gcd(chunk_size, shift_amount)), - frame_offset_(0), - input_buffer_(num_input_channels_, chunk_size_ + initial_delay_), - output_buffer_(chunk_size_ + initial_delay_, num_output_channels_), - input_block_(block_size_, num_input_channels_), - output_block_(block_size_, num_output_channels_), - window_(new float[block_size_]), - shift_amount_(shift_amount), - callback_(callback) { - RTC_CHECK_LE(num_output_channels_, num_input_channels_); - RTC_CHECK_LE(shift_amount_, block_size_); - - memcpy(window_.get(), window, block_size_ * sizeof(*window_.get())); - input_buffer_.MoveReadPositionBackward(initial_delay_); -} - -Blocker::~Blocker() = default; - -// When block_size < chunk_size the input and output buffers look like this: -// -// delay* chunk_size chunk_size + delay* -// buffer: <-------------|---------------------|---------------|> -// _a_ _b_ _c_ -// -// On each call to ProcessChunk(): -// 1. New input gets read into sections _b_ and _c_ of the input buffer. -// 2. We block starting from frame_offset. -// 3. We block until we reach a block |bl| that doesn't contain any frames -// from sections _a_ or _b_ of the input buffer. -// 4. We window the current block, fire the callback for processing, window -// again, and overlap/add to the output buffer. -// 5. We copy sections _a_ and _b_ of the output buffer into output. -// 6. For both the input and the output buffers, we copy section _c_ into -// section _a_. -// 7. We set the new frame_offset to be the difference between the first frame -// of |bl| and the border between sections _b_ and _c_. -// -// When block_size > chunk_size the input and output buffers look like this: -// -// chunk_size delay* chunk_size + delay* -// buffer: <-------------|---------------------|---------------|> -// _a_ _b_ _c_ -// -// On each call to ProcessChunk(): -// The procedure is the same as above, except for: -// 1. New input gets read into section _c_ of the input buffer. -// 3. We block until we reach a block |bl| that doesn't contain any frames -// from section _a_ of the input buffer. -// 5. We copy section _a_ of the output buffer into output. -// 6. For both the input and the output buffers, we copy sections _b_ and _c_ -// into section _a_ and _b_. -// 7. We set the new frame_offset to be the difference between the first frame -// of |bl| and the border between sections _a_ and _b_. -// -// * delay here refers to inintial_delay_ -// -// TODO(claguna): Look at using ring buffers to eliminate some copies. -void Blocker::ProcessChunk(const float* const* input, - size_t chunk_size, - size_t num_input_channels, - size_t num_output_channels, - float* const* output) { - RTC_CHECK_EQ(chunk_size, chunk_size_); - RTC_CHECK_EQ(num_input_channels, num_input_channels_); - RTC_CHECK_EQ(num_output_channels, num_output_channels_); - - input_buffer_.Write(input, num_input_channels, chunk_size_); - size_t first_frame_in_block = frame_offset_; - - // Loop through blocks. - while (first_frame_in_block < chunk_size_) { - input_buffer_.Read(input_block_.channels(), num_input_channels, - block_size_); - input_buffer_.MoveReadPositionBackward(block_size_ - shift_amount_); - - ApplyWindow(window_.get(), block_size_, num_input_channels_, - input_block_.channels()); - callback_->ProcessBlock(input_block_.channels(), block_size_, - num_input_channels_, num_output_channels_, - output_block_.channels()); - ApplyWindow(window_.get(), block_size_, num_output_channels_, - output_block_.channels()); - - AddFrames(output_buffer_.channels(), first_frame_in_block, - output_block_.channels(), 0, block_size_, num_output_channels_, - output_buffer_.channels(), first_frame_in_block); - - first_frame_in_block += shift_amount_; - } - - // Copy output buffer to output - CopyFrames(output_buffer_.channels(), 0, chunk_size_, num_output_channels_, - output, 0); - - // Copy output buffer [chunk_size_, chunk_size_ + initial_delay] - // to output buffer [0, initial_delay], zero the rest. - MoveFrames(output_buffer_.channels(), chunk_size, initial_delay_, - num_output_channels_, output_buffer_.channels(), 0); - ZeroOut(output_buffer_.channels(), initial_delay_, chunk_size_, - num_output_channels_); - - // Calculate new starting frames. - frame_offset_ = first_frame_in_block - chunk_size_; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.h deleted file mode 100644 index 26177bcad..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/blocker.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2014 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. - */ - -#ifndef MODULES_AUDIO_CODING_CODECS_OPUS_TEST_BLOCKER_H_ -#define MODULES_AUDIO_CODING_CODECS_OPUS_TEST_BLOCKER_H_ - -#include - -#include "common_audio/channel_buffer.h" -#include "modules/audio_coding/codecs/opus/test/audio_ring_buffer.h" - -namespace webrtc { - -// The callback function to process audio in the time domain. Input has already -// been windowed, and output will be windowed. The number of input channels -// must be >= the number of output channels. -class BlockerCallback { - public: - virtual ~BlockerCallback() {} - - virtual void ProcessBlock(const float* const* input, - size_t num_frames, - size_t num_input_channels, - size_t num_output_channels, - float* const* output) = 0; -}; - -// The main purpose of Blocker is to abstract away the fact that often we -// receive a different number of audio frames than our transform takes. For -// example, most FFTs work best when the fft-size is a power of 2, but suppose -// we receive 20ms of audio at a sample rate of 48000. That comes to 960 frames -// of audio, which is not a power of 2. Blocker allows us to specify the -// transform and all other necessary processing via the Process() callback -// function without any constraints on the transform-size -// (read: |block_size_|) or received-audio-size (read: |chunk_size_|). -// We handle this for the multichannel audio case, allowing for different -// numbers of input and output channels (for example, beamforming takes 2 or -// more input channels and returns 1 output channel). Audio signals are -// represented as deinterleaved floats in the range [-1, 1]. -// -// Blocker is responsible for: -// - blocking audio while handling potential discontinuities on the edges -// of chunks -// - windowing blocks before sending them to Process() -// - windowing processed blocks, and overlap-adding them together before -// sending back a processed chunk -// -// To use blocker: -// 1. Impelment a BlockerCallback object |bc|. -// 2. Instantiate a Blocker object |b|, passing in |bc|. -// 3. As you receive audio, call b.ProcessChunk() to get processed audio. -// -// A small amount of delay is added to the first received chunk to deal with -// the difference in chunk/block sizes. This delay is <= chunk_size. -// -// Ownership of window is retained by the caller. That is, Blocker makes a -// copy of window and does not attempt to delete it. -class Blocker { - public: - Blocker(size_t chunk_size, - size_t block_size, - size_t num_input_channels, - size_t num_output_channels, - const float* window, - size_t shift_amount, - BlockerCallback* callback); - ~Blocker(); - - void ProcessChunk(const float* const* input, - size_t chunk_size, - size_t num_input_channels, - size_t num_output_channels, - float* const* output); - - size_t initial_delay() const { return initial_delay_; } - - private: - const size_t chunk_size_; - const size_t block_size_; - const size_t num_input_channels_; - const size_t num_output_channels_; - - // The number of frames of delay to add at the beginning of the first chunk. - const size_t initial_delay_; - - // The frame index into the input buffer where the first block should be read - // from. This is necessary because shift_amount_ is not necessarily a - // multiple of chunk_size_, so blocks won't line up at the start of the - // buffer. - size_t frame_offset_; - - // Since blocks nearly always overlap, there are certain blocks that require - // frames from the end of one chunk and the beginning of the next chunk. The - // input and output buffers are responsible for saving those frames between - // calls to ProcessChunk(). - // - // Both contain |initial delay| + |chunk_size| frames. The input is a fairly - // standard FIFO, but due to the overlap-add it's harder to use an - // AudioRingBuffer for the output. - AudioRingBuffer input_buffer_; - ChannelBuffer output_buffer_; - - // Space for the input block (can't wrap because of windowing). - ChannelBuffer input_block_; - - // Space for the output block (can't wrap because of overlap/add). - ChannelBuffer output_block_; - - std::unique_ptr window_; - - // The amount of frames between the start of contiguous blocks. For example, - // |shift_amount_| = |block_size_| / 2 for a Hann window. - size_t shift_amount_; - - BlockerCallback* callback_; -}; - -} // namespace webrtc - -#endif // MODULES_AUDIO_CODING_CODECS_OPUS_TEST_BLOCKER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.cc deleted file mode 100644 index b1a6526bb..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2014 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/audio_coding/codecs/opus/test/lapped_transform.h" - -#include -#include -#include - -#include "common_audio/real_fourier.h" -#include "rtc_base/checks.h" - -namespace webrtc { - -void LappedTransform::BlockThunk::ProcessBlock(const float* const* input, - size_t num_frames, - size_t num_input_channels, - size_t num_output_channels, - float* const* output) { - RTC_CHECK_EQ(num_input_channels, parent_->num_in_channels_); - RTC_CHECK_EQ(num_output_channels, parent_->num_out_channels_); - RTC_CHECK_EQ(parent_->block_length_, num_frames); - - for (size_t i = 0; i < num_input_channels; ++i) { - memcpy(parent_->real_buf_.Row(i), input[i], num_frames * sizeof(*input[0])); - parent_->fft_->Forward(parent_->real_buf_.Row(i), - parent_->cplx_pre_.Row(i)); - } - - size_t block_length = - RealFourier::ComplexLength(RealFourier::FftOrder(num_frames)); - RTC_CHECK_EQ(parent_->cplx_length_, block_length); - parent_->block_processor_->ProcessAudioBlock( - parent_->cplx_pre_.Array(), num_input_channels, parent_->cplx_length_, - num_output_channels, parent_->cplx_post_.Array()); - - for (size_t i = 0; i < num_output_channels; ++i) { - parent_->fft_->Inverse(parent_->cplx_post_.Row(i), - parent_->real_buf_.Row(i)); - memcpy(output[i], parent_->real_buf_.Row(i), - num_frames * sizeof(*input[0])); - } -} - -LappedTransform::LappedTransform(size_t num_in_channels, - size_t num_out_channels, - size_t chunk_length, - const float* window, - size_t block_length, - size_t shift_amount, - Callback* callback) - : blocker_callback_(this), - num_in_channels_(num_in_channels), - num_out_channels_(num_out_channels), - block_length_(block_length), - chunk_length_(chunk_length), - block_processor_(callback), - blocker_(chunk_length_, - block_length_, - num_in_channels_, - num_out_channels_, - window, - shift_amount, - &blocker_callback_), - fft_(RealFourier::Create(RealFourier::FftOrder(block_length_))), - cplx_length_(RealFourier::ComplexLength(fft_->order())), - real_buf_(num_in_channels, - block_length_, - RealFourier::kFftBufferAlignment), - cplx_pre_(num_in_channels, - cplx_length_, - RealFourier::kFftBufferAlignment), - cplx_post_(num_out_channels, - cplx_length_, - RealFourier::kFftBufferAlignment) { - RTC_CHECK(num_in_channels_ > 0); - RTC_CHECK_GT(block_length_, 0); - RTC_CHECK_GT(chunk_length_, 0); - RTC_CHECK(block_processor_); - - // block_length_ power of 2? - RTC_CHECK_EQ(0, block_length_ & (block_length_ - 1)); -} - -LappedTransform::~LappedTransform() = default; - -void LappedTransform::ProcessChunk(const float* const* in_chunk, - float* const* out_chunk) { - blocker_.ProcessChunk(in_chunk, chunk_length_, num_in_channels_, - num_out_channels_, out_chunk); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.h deleted file mode 100644 index 3620df383..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/opus/test/lapped_transform.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2014 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. - */ - -#ifndef MODULES_AUDIO_CODING_CODECS_OPUS_TEST_LAPPED_TRANSFORM_H_ -#define MODULES_AUDIO_CODING_CODECS_OPUS_TEST_LAPPED_TRANSFORM_H_ - -#include -#include - -#include "common_audio/real_fourier.h" -#include "modules/audio_coding/codecs/opus/test/blocker.h" -#include "rtc_base/memory/aligned_malloc.h" - -namespace webrtc { - -// Wrapper class for aligned arrays. Every row (and the first dimension) are -// aligned to the given byte alignment. -template -class AlignedArray { - public: - AlignedArray(size_t rows, size_t cols, size_t alignment) - : rows_(rows), cols_(cols) { - RTC_CHECK_GT(alignment, 0); - head_row_ = - static_cast(AlignedMalloc(rows_ * sizeof(*head_row_), alignment)); - for (size_t i = 0; i < rows_; ++i) { - head_row_[i] = static_cast( - AlignedMalloc(cols_ * sizeof(**head_row_), alignment)); - } - } - - ~AlignedArray() { - for (size_t i = 0; i < rows_; ++i) { - AlignedFree(head_row_[i]); - } - AlignedFree(head_row_); - } - - T* const* Array() { return head_row_; } - - const T* const* Array() const { return head_row_; } - - T* Row(size_t row) { - RTC_CHECK_LE(row, rows_); - return head_row_[row]; - } - - const T* Row(size_t row) const { - RTC_CHECK_LE(row, rows_); - return head_row_[row]; - } - - private: - size_t rows_; - size_t cols_; - T** head_row_; -}; - -// Helper class for audio processing modules which operate on frequency domain -// input derived from the windowed time domain audio stream. -// -// The input audio chunk is sliced into possibly overlapping blocks, multiplied -// by a window and transformed with an FFT implementation. The transformed data -// is supplied to the given callback for processing. The processed output is -// then inverse transformed into the time domain and spliced back into a chunk -// which constitutes the final output of this processing module. -class LappedTransform { - public: - class Callback { - public: - virtual ~Callback() {} - - virtual void ProcessAudioBlock(const std::complex* const* in_block, - size_t num_in_channels, - size_t frames, - size_t num_out_channels, - std::complex* const* out_block) = 0; - }; - - // Construct a transform instance. |chunk_length| is the number of samples in - // each channel. |window| defines the window, owned by the caller (a copy is - // made internally); |window| should have length equal to |block_length|. - // |block_length| defines the length of a block, in samples. - // |shift_amount| is in samples. |callback| is the caller-owned audio - // processing function called for each block of the input chunk. - LappedTransform(size_t num_in_channels, - size_t num_out_channels, - size_t chunk_length, - const float* window, - size_t block_length, - size_t shift_amount, - Callback* callback); - ~LappedTransform(); - - // Main audio processing helper method. Internally slices |in_chunk| into - // blocks, transforms them to frequency domain, calls the callback for each - // block and returns a de-blocked time domain chunk of audio through - // |out_chunk|. Both buffers are caller-owned. - void ProcessChunk(const float* const* in_chunk, float* const* out_chunk); - - // Get the chunk length. - // - // The chunk length is the number of samples per channel that must be passed - // to ProcessChunk via the parameter in_chunk. - // - // Returns the same chunk_length passed to the LappedTransform constructor. - size_t chunk_length() const { return chunk_length_; } - - // Get the number of input channels. - // - // This is the number of arrays that must be passed to ProcessChunk via - // in_chunk. - // - // Returns the same num_in_channels passed to the LappedTransform constructor. - size_t num_in_channels() const { return num_in_channels_; } - - // Get the number of output channels. - // - // This is the number of arrays that must be passed to ProcessChunk via - // out_chunk. - // - // Returns the same num_out_channels passed to the LappedTransform - // constructor. - size_t num_out_channels() const { return num_out_channels_; } - - // Returns the initial delay. - // - // This is the delay introduced by the |blocker_| to be able to get and return - // chunks of |chunk_length|, but process blocks of |block_length|. - size_t initial_delay() const { return blocker_.initial_delay(); } - - private: - // Internal middleware callback, given to the blocker. Transforms each block - // and hands it over to the processing method given at construction time. - class BlockThunk : public BlockerCallback { - public: - explicit BlockThunk(LappedTransform* parent) : parent_(parent) {} - - void ProcessBlock(const float* const* input, - size_t num_frames, - size_t num_input_channels, - size_t num_output_channels, - float* const* output) override; - - private: - LappedTransform* const parent_; - } blocker_callback_; - - const size_t num_in_channels_; - const size_t num_out_channels_; - - const size_t block_length_; - const size_t chunk_length_; - - Callback* const block_processor_; - Blocker blocker_; - - // TODO(alessiob): Replace RealFourier with a different FFT library. - std::unique_ptr fft_; - const size_t cplx_length_; - AlignedArray real_buf_; - AlignedArray > cplx_pre_; - AlignedArray > cplx_post_; -}; - -} // namespace webrtc - -#endif // MODULES_AUDIO_CODING_CODECS_OPUS_TEST_LAPPED_TRANSFORM_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.cc new file mode 100644 index 000000000..3d5ba0b7c --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.cc @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2014 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/audio_coding/codecs/tools/audio_codec_speed_test.h" + +#include "rtc_base/format_macros.h" +#include "test/gtest.h" +#include "test/testsupport/file_utils.h" + +using ::std::get; + +namespace webrtc { + +AudioCodecSpeedTest::AudioCodecSpeedTest(int block_duration_ms, + int input_sampling_khz, + int output_sampling_khz) + : block_duration_ms_(block_duration_ms), + input_sampling_khz_(input_sampling_khz), + output_sampling_khz_(output_sampling_khz), + input_length_sample_( + static_cast(block_duration_ms_ * input_sampling_khz_)), + output_length_sample_( + static_cast(block_duration_ms_ * output_sampling_khz_)), + data_pointer_(0), + loop_length_samples_(0), + max_bytes_(0), + encoded_bytes_(0), + encoding_time_ms_(0.0), + decoding_time_ms_(0.0), + out_file_(NULL) {} + +void AudioCodecSpeedTest::SetUp() { + channels_ = get<0>(GetParam()); + bit_rate_ = get<1>(GetParam()); + in_filename_ = test::ResourcePath(get<2>(GetParam()), get<3>(GetParam())); + save_out_data_ = get<4>(GetParam()); + + FILE* fp = fopen(in_filename_.c_str(), "rb"); + assert(fp != NULL); + + // Obtain file size. + fseek(fp, 0, SEEK_END); + loop_length_samples_ = ftell(fp) / sizeof(int16_t); + rewind(fp); + + // Allocate memory to contain the whole file. + in_data_.reset( + new int16_t[loop_length_samples_ + input_length_sample_ * channels_]); + + data_pointer_ = 0; + + // Copy the file into the buffer. + ASSERT_EQ(fread(&in_data_[0], sizeof(int16_t), loop_length_samples_, fp), + loop_length_samples_); + fclose(fp); + + // Add an extra block length of samples to the end of the array, starting + // over again from the beginning of the array. This is done to simplify + // the reading process when reading over the end of the loop. + memcpy(&in_data_[loop_length_samples_], &in_data_[0], + input_length_sample_ * channels_ * sizeof(int16_t)); + + max_bytes_ = input_length_sample_ * channels_ * sizeof(int16_t); + out_data_.reset(new int16_t[output_length_sample_ * channels_]); + bit_stream_.reset(new uint8_t[max_bytes_]); + + if (save_out_data_) { + std::string out_filename = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + + // Erase '/' + size_t found; + while ((found = out_filename.find('/')) != std::string::npos) + out_filename.replace(found, 1, "_"); + + out_filename = test::OutputPath() + out_filename + ".pcm"; + + out_file_ = fopen(out_filename.c_str(), "wb"); + assert(out_file_ != NULL); + + printf("Output to be saved in %s.\n", out_filename.c_str()); + } +} + +void AudioCodecSpeedTest::TearDown() { + if (save_out_data_) { + fclose(out_file_); + } +} + +void AudioCodecSpeedTest::EncodeDecode(size_t audio_duration_sec) { + size_t time_now_ms = 0; + float time_ms; + + printf("Coding %d kHz-sampled %" RTC_PRIuS "-channel audio at %d bps ...\n", + input_sampling_khz_, channels_, bit_rate_); + + while (time_now_ms < audio_duration_sec * 1000) { + // Encode & decode. + time_ms = EncodeABlock(&in_data_[data_pointer_], &bit_stream_[0], + max_bytes_, &encoded_bytes_); + encoding_time_ms_ += time_ms; + time_ms = DecodeABlock(&bit_stream_[0], encoded_bytes_, &out_data_[0]); + decoding_time_ms_ += time_ms; + if (save_out_data_) { + fwrite(&out_data_[0], sizeof(int16_t), output_length_sample_ * channels_, + out_file_); + } + data_pointer_ = (data_pointer_ + input_length_sample_ * channels_) % + loop_length_samples_; + time_now_ms += block_duration_ms_; + } + + printf("Encoding: %.2f%% real time,\nDecoding: %.2f%% real time.\n", + (encoding_time_ms_ / audio_duration_sec) / 10.0, + (decoding_time_ms_ / audio_duration_sec) / 10.0); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h new file mode 100644 index 000000000..59c2f1605 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014 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. + */ + +#ifndef MODULES_AUDIO_CODING_CODECS_TOOLS_AUDIO_CODEC_SPEED_TEST_H_ +#define MODULES_AUDIO_CODING_CODECS_TOOLS_AUDIO_CODEC_SPEED_TEST_H_ + +#include +#include + +#include "test/gtest.h" + +namespace webrtc { + +// Define coding parameter as +// . +typedef std::tuple coding_param; + +class AudioCodecSpeedTest : public ::testing::TestWithParam { + protected: + AudioCodecSpeedTest(int block_duration_ms, + int input_sampling_khz, + int output_sampling_khz); + virtual void SetUp(); + virtual void TearDown(); + + // EncodeABlock(...) does the following: + // 1. encodes a block of audio, saved in |in_data|, + // 2. save the bit stream to |bit_stream| of |max_bytes| bytes in size, + // 3. assign |encoded_bytes| with the length of the bit stream (in bytes), + // 4. return the cost of time (in millisecond) spent on actual encoding. + virtual float EncodeABlock(int16_t* in_data, + uint8_t* bit_stream, + size_t max_bytes, + size_t* encoded_bytes) = 0; + + // DecodeABlock(...) does the following: + // 1. decodes the bit stream in |bit_stream| with a length of |encoded_bytes| + // (in bytes), + // 2. save the decoded audio in |out_data|, + // 3. return the cost of time (in millisecond) spent on actual decoding. + virtual float DecodeABlock(const uint8_t* bit_stream, + size_t encoded_bytes, + int16_t* out_data) = 0; + + // Encoding and decode an audio of |audio_duration| (in seconds) and + // record the runtime for encoding and decoding separately. + void EncodeDecode(size_t audio_duration); + + int block_duration_ms_; + int input_sampling_khz_; + int output_sampling_khz_; + + // Number of samples-per-channel in a frame. + size_t input_length_sample_; + + // Expected output number of samples-per-channel in a frame. + size_t output_length_sample_; + + std::unique_ptr in_data_; + std::unique_ptr out_data_; + size_t data_pointer_; + size_t loop_length_samples_; + std::unique_ptr bit_stream_; + + // Maximum number of bytes in output bitstream for a frame of audio. + size_t max_bytes_; + + size_t encoded_bytes_; + float encoding_time_ms_; + float decoding_time_ms_; + FILE* out_file_; + + size_t channels_; + + // Bit rate is in bit-per-second. + int bit_rate_; + + std::string in_filename_; + + // Determines whether to save the output to file. + bool save_out_data_; +}; + +} // namespace webrtc + +#endif // MODULES_AUDIO_CODING_CODECS_TOOLS_AUDIO_CODEC_SPEED_TEST_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h index a5d4b246c..07aa8c956 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h @@ -97,12 +97,6 @@ struct NetworkStatistics { uint64_t fecPacketsReceived; uint64_t fecPacketsDiscarded; // Stats below DO NOT correspond directly to anything in the WebRTC stats - // Loss rate (network + late); fraction between 0 and 1, scaled to Q14. - uint16_t currentPacketLossRate; - // Late loss rate; fraction between 0 and 1, scaled to Q14. - union { - RTC_DEPRECATED uint16_t currentDiscardRate; - }; // fraction (of original stream) of synthesized audio inserted through // expansion (in Q14) uint16_t currentExpandRate; @@ -123,14 +117,8 @@ struct NetworkStatistics { uint16_t currentSecondaryDiscardedRate; // average packet waiting time in the jitter buffer (ms) int meanWaitingTimeMs; - // median packet waiting time in the jitter buffer (ms) - int medianWaitingTimeMs; - // min packet waiting time in the jitter buffer (ms) - int minWaitingTimeMs; // max packet waiting time in the jitter buffer (ms) int maxWaitingTimeMs; - // added samples in off mode due to packet loss - size_t addedSamples; // count of the number of buffer flushes uint64_t packetBufferFlushes; // number of samples expanded due to delayed packets diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/buffer_level_filter.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/buffer_level_filter.cc index d238665ba..7ad006545 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/buffer_level_filter.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/buffer_level_filter.cc @@ -45,12 +45,12 @@ void BufferLevelFilter::Update(size_t buffer_size_samples, filtered_current_level - (int64_t{time_stretched_samples} * (1 << 8)))); } -void BufferLevelFilter::SetTargetBufferLevel(int target_buffer_level) { - if (target_buffer_level <= 1) { +void BufferLevelFilter::SetTargetBufferLevel(int target_buffer_level_ms) { + if (target_buffer_level_ms <= 20) { level_factor_ = 251; - } else if (target_buffer_level <= 3) { + } else if (target_buffer_level_ms <= 60) { level_factor_ = 252; - } else if (target_buffer_level <= 7) { + } else if (target_buffer_level_ms <= 140) { level_factor_ = 253; } else { level_factor_ = 254; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/buffer_level_filter.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/buffer_level_filter.h index 6dd424991..bb3185667 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/buffer_level_filter.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/buffer_level_filter.h @@ -23,15 +23,13 @@ class BufferLevelFilter { virtual ~BufferLevelFilter() {} virtual void Reset(); - // Updates the filter. Current buffer size is |buffer_size_packets| (Q0). + // Updates the filter. Current buffer size is |buffer_size_samples|. // |time_stretched_samples| is subtracted from the filtered value (thus // bypassing the filter operation). virtual void Update(size_t buffer_size_samples, int time_stretched_samples); - // Set the current target buffer level in number of packets (obtained from - // DelayManager::base_target_level()). Used to select the appropriate - // filter coefficient. - virtual void SetTargetBufferLevel(int target_buffer_level_packets); + // The target level is used to select the appropriate filter coefficient. + virtual void SetTargetBufferLevel(int target_buffer_level_ms); // Returns filtered current level in number of samples. virtual int filtered_current_level() const { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/decision_logic.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/decision_logic.cc index 8e1ffaf9f..9c0ee9682 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/decision_logic.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/decision_logic.cc @@ -27,16 +27,25 @@ namespace { constexpr int kPostponeDecodingLevel = 50; constexpr int kDefaultTargetLevelWindowMs = 100; +constexpr int kDecelerationTargetLevelOffsetMs = 85; } // namespace namespace webrtc { DecisionLogic::DecisionLogic(NetEqController::Config config) - : delay_manager_(DelayManager::Create(config.max_packets_in_buffer, - config.base_min_delay_ms, - config.enable_rtx_handling, - config.tick_timer)), + : DecisionLogic(config, + DelayManager::Create(config.max_packets_in_buffer, + config.base_min_delay_ms, + config.tick_timer), + std::make_unique()) {} + +DecisionLogic::DecisionLogic( + NetEqController::Config config, + std::unique_ptr delay_manager, + std::unique_ptr buffer_level_filter) + : delay_manager_(std::move(delay_manager)), + buffer_level_filter_(std::move(buffer_level_filter)), tick_timer_(config.tick_timer), disallow_time_stretching_(!config.allow_time_stretching), timescale_countdown_( @@ -67,6 +76,7 @@ void DecisionLogic::Reset() { packet_length_samples_ = 0; sample_memory_ = 0; prev_time_scale_ = false; + last_pack_cng_or_dtmf_ = true; timescale_countdown_.reset(); num_consecutive_expands_ = 0; time_stretched_cn_samples_ = 0; @@ -76,11 +86,12 @@ void DecisionLogic::SoftReset() { packet_length_samples_ = 0; sample_memory_ = 0; prev_time_scale_ = false; + last_pack_cng_or_dtmf_ = true; timescale_countdown_ = tick_timer_->GetNewCountdown(kMinTimescaleInterval + 1); time_stretched_cn_samples_ = 0; delay_manager_->Reset(); - buffer_level_filter_.Reset(); + buffer_level_filter_->Reset(); } void DecisionLogic::SetSampleRate(int fs_hz, size_t output_size_samples) { @@ -158,12 +169,13 @@ NetEq::Operation DecisionLogic::GetDecision(const NetEqStatus& status, const size_t current_span = estimate_dtx_delay_ ? status.packet_buffer_info.span_samples : status.packet_buffer_info.span_samples_no_dtx; + const int target_level_samples = + delay_manager_->TargetDelayMs() * sample_rate_ / 1000; if ((status.last_mode == NetEq::Mode::kExpand || status.last_mode == NetEq::Mode::kCodecPlc) && status.expand_mutefactor < 16384 / 2 && - current_span(delay_manager_->TargetLevel() * - packet_length_samples_ * - kPostponeDecodingLevel / 100)>> 8 && + current_span < static_cast(target_level_samples * + kPostponeDecodingLevel / 100) && !status.packet_buffer_info.dtx_or_cng) { return NetEq::Operation::kExpand; } @@ -195,41 +207,30 @@ void DecisionLogic::ExpandDecision(NetEq::Operation operation) { } } -absl::optional DecisionLogic::PacketArrived(bool last_cng_or_dtmf, - size_t packet_length_samples, - bool should_update_stats, - uint16_t main_sequence_number, - uint32_t main_timestamp, - int fs_hz) { - delay_manager_->LastDecodedWasCngOrDtmf(last_cng_or_dtmf); - absl::optional relative_delay; - if (delay_manager_->last_pack_cng_or_dtmf() == 0) { - // Calculate the total speech length carried in each packet. - if (packet_length_samples > 0 && - packet_length_samples != packet_length_samples_) { - packet_length_samples_ = packet_length_samples; - delay_manager_->SetPacketAudioLength( - rtc::dchecked_cast((1000 * packet_length_samples) / fs_hz)); - } - - // Update statistics. - if (should_update_stats) { - relative_delay = - delay_manager_->Update(main_sequence_number, main_timestamp, fs_hz); - } - } else if (delay_manager_->last_pack_cng_or_dtmf() == -1) { - // This is first "normal" packet after CNG or DTMF. - // Reset packet time counter and measure time until next packet, - // but don't update statistics. - delay_manager_->set_last_pack_cng_or_dtmf(0); - delay_manager_->ResetPacketIatCount(); +absl::optional DecisionLogic::PacketArrived( + int fs_hz, + bool should_update_stats, + const PacketArrivedInfo& info) { + if (info.is_cng_or_dtmf) { + last_pack_cng_or_dtmf_ = true; + return absl::nullopt; } + if (!should_update_stats) { + return absl::nullopt; + } + if (info.packet_length_samples > 0 && fs_hz > 0 && + info.packet_length_samples != packet_length_samples_) { + packet_length_samples_ = info.packet_length_samples; + delay_manager_->SetPacketAudioLength(packet_length_samples_ * 1000 / fs_hz); + } + auto relative_delay = delay_manager_->Update( + info.main_timestamp, fs_hz, /*reset=*/last_pack_cng_or_dtmf_); + last_pack_cng_or_dtmf_ = false; return relative_delay; } void DecisionLogic::FilterBufferLevel(size_t buffer_size_samples) { - buffer_level_filter_.SetTargetBufferLevel( - delay_manager_->base_target_level()); + buffer_level_filter_->SetTargetBufferLevel(delay_manager_->TargetDelayMs()); int time_stretched_samples = time_stretched_cn_samples_; if (prev_time_scale_) { @@ -237,7 +238,7 @@ void DecisionLogic::FilterBufferLevel(size_t buffer_size_samples) { timescale_countdown_ = tick_timer_->GetNewCountdown(kMinTimescaleInterval); } - buffer_level_filter_.Update(buffer_size_samples, time_stretched_samples); + buffer_level_filter_->Update(buffer_size_samples, time_stretched_samples); prev_time_scale_ = false; time_stretched_cn_samples_ = 0; } @@ -250,8 +251,8 @@ NetEq::Operation DecisionLogic::CngOperation(NetEq::Mode prev_mode, int32_t timestamp_diff = static_cast( static_cast(generated_noise_samples + target_timestamp) - available_timestamp); - int32_t optimal_level_samp = static_cast( - (delay_manager_->TargetLevel() * packet_length_samples_) >> 8); + int optimal_level_samp = + delay_manager_->TargetDelayMs() * sample_rate_ / 1000; const int64_t excess_waiting_time_samp = -static_cast(timestamp_diff) - optimal_level_samp; @@ -295,22 +296,26 @@ NetEq::Operation DecisionLogic::ExpectedPacketAvailable(NetEq::Mode prev_mode, bool play_dtmf) { if (!disallow_time_stretching_ && prev_mode != NetEq::Mode::kExpand && !play_dtmf) { - // Check criterion for time-stretching. The values are in number of packets - // in Q8. - int low_limit, high_limit; - delay_manager_->BufferLimits(&low_limit, &high_limit); - int buffer_level_packets = 0; - if (packet_length_samples_ > 0) { - buffer_level_packets = - ((1 << 8) * buffer_level_filter_.filtered_current_level()) / - packet_length_samples_; - } - if (buffer_level_packets >= high_limit << 2) + const int samples_per_ms = sample_rate_ / 1000; + const int target_level_samples = + delay_manager_->TargetDelayMs() * samples_per_ms; + const int low_limit = + std::max(target_level_samples * 3 / 4, + target_level_samples - + kDecelerationTargetLevelOffsetMs * samples_per_ms); + // |higher_limit| is equal to |target_level|, but should at + // least be 20 ms higher than |lower_limit|. + const int high_limit = + std::max(target_level_samples, low_limit + 20 * samples_per_ms); + + const int buffer_level_samples = + buffer_level_filter_->filtered_current_level(); + if (buffer_level_samples >= high_limit << 2) return NetEq::Operation::kFastAccelerate; if (TimescaleAllowed()) { - if (buffer_level_packets >= high_limit) + if (buffer_level_samples >= high_limit) return NetEq::Operation::kAccelerate; - if (buffer_level_packets < low_limit) + if (buffer_level_samples < low_limit) return NetEq::Operation::kPreemptiveExpand; } } @@ -352,11 +357,11 @@ NetEq::Operation DecisionLogic::FuturePacketAvailable( prev_mode == NetEq::Mode::kCodecInternalCng) { size_t cur_size_samples = estimate_dtx_delay_ - ? cur_size_samples = span_samples_in_packet_buffer + ? span_samples_in_packet_buffer : num_packets_in_packet_buffer * decoder_frame_length; // Target level is in number of packets in Q8. const size_t target_level_samples = - (delay_manager_->TargetLevel() * packet_length_samples_) >> 8; + delay_manager_->TargetDelayMs() * sample_rate_ / 1000; const bool generated_enough_noise = static_cast(generated_noise_samples + target_timestamp) >= available_timestamp; @@ -406,13 +411,8 @@ NetEq::Operation DecisionLogic::FuturePacketAvailable( } bool DecisionLogic::UnderTargetLevel() const { - int buffer_level_packets = 0; - if (packet_length_samples_ > 0) { - buffer_level_packets = - ((1 << 8) * buffer_level_filter_.filtered_current_level()) / - packet_length_samples_; - } - return buffer_level_packets <= delay_manager_->TargetLevel(); + return buffer_level_filter_->filtered_current_level() < + delay_manager_->TargetDelayMs() * sample_rate_ / 1000; } bool DecisionLogic::ReinitAfterExpands(uint32_t timestamp_leap) const { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/decision_logic.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/decision_logic.h index 5f1a41401..08feba64d 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/decision_logic.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/decision_logic.h @@ -11,6 +11,8 @@ #ifndef MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_ #define MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_ +#include + #include "api/neteq/neteq.h" #include "api/neteq/neteq_controller.h" #include "api/neteq/tick_timer.h" @@ -29,6 +31,9 @@ class DecisionLogic : public NetEqController { // Constructor. DecisionLogic(NetEqController::Config config); + DecisionLogic(NetEqController::Config config, + std::unique_ptr delay_manager, + std::unique_ptr buffer_level_filter); ~DecisionLogic() override; @@ -70,19 +75,15 @@ class DecisionLogic : public NetEqController { // Adds |value| to |sample_memory_|. void AddSampleMemory(int32_t value) override { sample_memory_ += value; } - int TargetLevelMs() override { - return ((delay_manager_->TargetLevel() * packet_length_samples_) >> 8) / - rtc::CheckedDivExact(sample_rate_, 1000); - } + int TargetLevelMs() const override { return delay_manager_->TargetDelayMs(); } - absl::optional PacketArrived(bool last_cng_or_dtmf, - size_t packet_length_samples, + absl::optional PacketArrived(int fs_hz, bool should_update_stats, - uint16_t main_sequence_number, - uint32_t main_timestamp, - int fs_hz) override; + const PacketArrivedInfo& info) override; - void RegisterEmptyPacket() override { delay_manager_->RegisterEmptyPacket(); } + void RegisterEmptyPacket() override {} + + void NotifyMutedState() override {} bool SetMaximumDelay(int delay_ms) override { return delay_manager_->SetMaximumDelay(delay_ms); @@ -99,7 +100,7 @@ class DecisionLogic : public NetEqController { bool PeakFound() const override { return false; } int GetFilteredBufferLevel() const override { - return buffer_level_filter_.filtered_current_level(); + return buffer_level_filter_->filtered_current_level(); } // Accessors and mutators. @@ -120,8 +121,8 @@ class DecisionLogic : public NetEqController { enum CngState { kCngOff, kCngRfc3389On, kCngInternalOn }; // Updates the |buffer_level_filter_| with the current buffer level - // |buffer_size_packets|. - void FilterBufferLevel(size_t buffer_size_packets); + // |buffer_size_samples|. + void FilterBufferLevel(size_t buffer_size_samples); // Returns the operation given that the next available packet is a comfort // noise payload (RFC 3389 only, not codec-internal). @@ -172,7 +173,7 @@ class DecisionLogic : public NetEqController { bool MaxWaitForPacket() const; std::unique_ptr delay_manager_; - BufferLevelFilter buffer_level_filter_; + std::unique_ptr buffer_level_filter_; const TickTimer* tick_timer_; int sample_rate_; size_t output_size_samples_; @@ -186,6 +187,7 @@ class DecisionLogic : public NetEqController { std::unique_ptr timescale_countdown_; int num_consecutive_expands_ = 0; int time_stretched_cn_samples_ = 0; + bool last_pack_cng_or_dtmf_ = true; FieldTrialParameter estimate_dtx_delay_; FieldTrialParameter time_stretch_cn_; FieldTrialConstrained target_level_window_ms_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/delay_manager.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/delay_manager.cc index 4ae6d108c..33eeb96f1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/delay_manager.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/delay_manager.cc @@ -22,38 +22,45 @@ #include "modules/audio_coding/neteq/histogram.h" #include "modules/include/module_common_types_public.h" #include "rtc_base/checks.h" +#include "rtc_base/experiments/struct_parameters_parser.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/numerics/safe_minmax.h" #include "system_wrappers/include/field_trial.h" +namespace webrtc { namespace { constexpr int kMinBaseMinimumDelayMs = 0; constexpr int kMaxBaseMinimumDelayMs = 10000; -constexpr int kMaxReorderedPackets = - 10; // Max number of consecutive reordered packets. -constexpr int kMaxHistoryMs = 2000; // Oldest packet to include in history to - // calculate relative packet arrival delay. constexpr int kDelayBuckets = 100; constexpr int kBucketSizeMs = 20; -constexpr int kDecelerationTargetLevelOffsetMs = 85 << 8; // In Q8. +constexpr int kStartDelayMs = 80; +constexpr int kMaxNumReorderedPackets = 5; -int PercentileToQuantile(double percentile) { - return static_cast((1 << 30) * percentile / 100.0 + 0.5); -} - -struct DelayHistogramConfig { - int quantile = 1041529569; // 0.97 in Q30. - int forget_factor = 32745; // 0.9993 in Q15. +struct DelayManagerConfig { + double quantile = 0.97; + double forget_factor = 0.9993; absl::optional start_forget_weight = 2; -}; + absl::optional resample_interval_ms; + int max_history_ms = 2000; -DelayHistogramConfig GetDelayHistogramConfig() { - constexpr char kDelayHistogramFieldTrial[] = - "WebRTC-Audio-NetEqDelayHistogram"; - DelayHistogramConfig config; - if (webrtc::field_trial::IsEnabled(kDelayHistogramFieldTrial)) { + std::unique_ptr Parser() { + return webrtc::StructParametersParser::Create( // + "quantile", &quantile, // + "forget_factor", &forget_factor, // + "start_forget_weight", &start_forget_weight, // + "resample_interval_ms", &resample_interval_ms, // + "max_history_ms", &max_history_ms); + } + + // TODO(jakobi): remove legacy field trial. + void MaybeUpdateFromLegacyFieldTrial() { + constexpr char kDelayHistogramFieldTrial[] = + "WebRTC-Audio-NetEqDelayHistogram"; + if (!webrtc::field_trial::IsEnabled(kDelayHistogramFieldTrial)) { + return; + } const auto field_trial_string = webrtc::field_trial::FindFullName(kDelayHistogramFieldTrial); double percentile = -1.0; @@ -63,30 +70,36 @@ DelayHistogramConfig GetDelayHistogramConfig() { &forget_factor, &start_forget_weight) >= 2 && percentile >= 0.0 && percentile <= 100.0 && forget_factor >= 0.0 && forget_factor <= 1.0) { - config.quantile = PercentileToQuantile(percentile); - config.forget_factor = (1 << 15) * forget_factor; - config.start_forget_weight = - start_forget_weight >= 1 ? absl::make_optional(start_forget_weight) - : absl::nullopt; + this->quantile = percentile / 100; + this->forget_factor = forget_factor; + this->start_forget_weight = start_forget_weight >= 1 + ? absl::make_optional(start_forget_weight) + : absl::nullopt; } } - RTC_LOG(LS_INFO) << "Delay histogram config:" - " quantile=" - << config.quantile - << " forget_factor=" << config.forget_factor - << " start_forget_weight=" - << config.start_forget_weight.value_or(0); - return config; -} + + explicit DelayManagerConfig() { + Parser()->Parse(webrtc::field_trial::FindFullName( + "WebRTC-Audio-NetEqDelayManagerConfig")); + MaybeUpdateFromLegacyFieldTrial(); + RTC_LOG(LS_INFO) << "Delay manager config:" + " quantile=" + << quantile << " forget_factor=" << forget_factor + << " start_forget_weight=" + << start_forget_weight.value_or(0) + << " resample_interval_ms=" + << resample_interval_ms.value_or(0) + << " max_history_ms=" << max_history_ms; + } +}; } // namespace -namespace webrtc { - -DelayManager::DelayManager(size_t max_packets_in_buffer, +DelayManager::DelayManager(int max_packets_in_buffer, int base_minimum_delay_ms, int histogram_quantile, - bool enable_rtx_handling, + absl::optional resample_interval_ms, + int max_history_ms, const TickTimer* tick_timer, std::unique_ptr histogram) : first_packet_received_(false), @@ -94,17 +107,14 @@ DelayManager::DelayManager(size_t max_packets_in_buffer, histogram_(std::move(histogram)), histogram_quantile_(histogram_quantile), tick_timer_(tick_timer), + resample_interval_ms_(resample_interval_ms), + max_history_ms_(max_history_ms), base_minimum_delay_ms_(base_minimum_delay_ms), effective_minimum_delay_ms_(base_minimum_delay_ms), - base_target_level_(4), // In Q0 domain. - target_level_(base_target_level_ << 8), // In Q8 domain. - packet_len_ms_(0), - last_seq_no_(0), - last_timestamp_(0), minimum_delay_ms_(0), maximum_delay_ms_(0), - last_pack_cng_or_dtmf_(1), - enable_rtx_handling_(enable_rtx_handling) { + target_level_ms_(kStartDelayMs), + last_timestamp_(0) { RTC_CHECK(histogram_); RTC_DCHECK_GE(base_minimum_delay_ms_, 0); @@ -112,102 +122,102 @@ DelayManager::DelayManager(size_t max_packets_in_buffer, } std::unique_ptr DelayManager::Create( - size_t max_packets_in_buffer, + int max_packets_in_buffer, int base_minimum_delay_ms, - bool enable_rtx_handling, const TickTimer* tick_timer) { - DelayHistogramConfig config = GetDelayHistogramConfig(); - const int quantile = config.quantile; + DelayManagerConfig config; + int forget_factor_q15 = (1 << 15) * config.forget_factor; + int quantile_q30 = (1 << 30) * config.quantile; std::unique_ptr histogram = std::make_unique( - kDelayBuckets, config.forget_factor, config.start_forget_weight); + kDelayBuckets, forget_factor_q15, config.start_forget_weight); return std::make_unique( - max_packets_in_buffer, base_minimum_delay_ms, quantile, - enable_rtx_handling, tick_timer, std::move(histogram)); + max_packets_in_buffer, base_minimum_delay_ms, quantile_q30, + config.resample_interval_ms, config.max_history_ms, tick_timer, + std::move(histogram)); } DelayManager::~DelayManager() {} -absl::optional DelayManager::Update(uint16_t sequence_number, - uint32_t timestamp, - int sample_rate_hz) { +absl::optional DelayManager::Update(uint32_t timestamp, + int sample_rate_hz, + bool reset) { if (sample_rate_hz <= 0) { return absl::nullopt; } - if (!first_packet_received_) { - // Prepare for next packet arrival. + if (!first_packet_received_ || reset) { + // Restart relative delay esimation from this packet. + delay_history_.clear(); packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); - last_seq_no_ = sequence_number; last_timestamp_ = timestamp; first_packet_received_ = true; + num_reordered_packets_ = 0; + resample_stopwatch_ = tick_timer_->GetNewStopwatch(); + max_delay_in_interval_ms_ = 0; return absl::nullopt; } - // Try calculating packet length from current and previous timestamps. - int packet_len_ms; - if (!IsNewerTimestamp(timestamp, last_timestamp_) || - !IsNewerSequenceNumber(sequence_number, last_seq_no_)) { - // Wrong timestamp or sequence order; use stored value. - packet_len_ms = packet_len_ms_; + const int expected_iat_ms = + 1000 * static_cast(timestamp - last_timestamp_) / sample_rate_hz; + const int iat_ms = packet_iat_stopwatch_->ElapsedMs(); + const int iat_delay_ms = iat_ms - expected_iat_ms; + int relative_delay; + bool reordered = !IsNewerTimestamp(timestamp, last_timestamp_); + if (reordered) { + relative_delay = std::max(iat_delay_ms, 0); } else { - // Calculate timestamps per packet and derive packet length in ms. - int64_t packet_len_samp = - static_cast(timestamp - last_timestamp_) / - static_cast(sequence_number - last_seq_no_); - packet_len_ms = - rtc::saturated_cast(1000 * packet_len_samp / sample_rate_hz); + UpdateDelayHistory(iat_delay_ms, timestamp, sample_rate_hz); + relative_delay = CalculateRelativePacketArrivalDelay(); } - bool reordered = false; - absl::optional relative_delay; - if (packet_len_ms > 0) { - // Cannot update statistics unless |packet_len_ms| is valid. - - // Inter-arrival time (IAT) in integer "packet times" (rounding down). This - // is the value added to the inter-arrival time histogram. - int iat_ms = packet_iat_stopwatch_->ElapsedMs(); - // Check for discontinuous packet sequence and re-ordering. - if (IsNewerSequenceNumber(sequence_number, last_seq_no_ + 1)) { - // Compensate for gap in the sequence numbers. Reduce IAT with the - // expected extra time due to lost packets. - int packet_offset = - static_cast(sequence_number - last_seq_no_ - 1); - iat_ms -= packet_offset * packet_len_ms; - } else if (!IsNewerSequenceNumber(sequence_number, last_seq_no_)) { - int packet_offset = - static_cast(last_seq_no_ + 1 - sequence_number); - iat_ms += packet_offset * packet_len_ms; - reordered = true; + absl::optional histogram_update; + if (resample_interval_ms_) { + if (static_cast(resample_stopwatch_->ElapsedMs()) > + *resample_interval_ms_) { + histogram_update = max_delay_in_interval_ms_; + resample_stopwatch_ = tick_timer_->GetNewStopwatch(); + max_delay_in_interval_ms_ = 0; } - - int iat_delay = iat_ms - packet_len_ms; - if (reordered) { - relative_delay = std::max(iat_delay, 0); - } else { - UpdateDelayHistory(iat_delay, timestamp, sample_rate_hz); - relative_delay = CalculateRelativePacketArrivalDelay(); - } - - const int index = relative_delay.value() / kBucketSizeMs; + max_delay_in_interval_ms_ = + std::max(max_delay_in_interval_ms_, relative_delay); + } else { + histogram_update = relative_delay; + } + if (histogram_update) { + const int index = *histogram_update / kBucketSizeMs; if (index < histogram_->NumBuckets()) { // Maximum delay to register is 2000 ms. histogram_->Add(index); } - // Calculate new |target_level_| based on updated statistics. - target_level_ = CalculateTargetLevel(); + } - LimitTargetLevel(); - } // End if (packet_len_ms > 0). + // Calculate new |target_level_ms_| based on updated statistics. + int bucket_index = histogram_->Quantile(histogram_quantile_); + target_level_ms_ = (1 + bucket_index) * kBucketSizeMs; + target_level_ms_ = std::max(target_level_ms_, effective_minimum_delay_ms_); + if (maximum_delay_ms_ > 0) { + target_level_ms_ = std::min(target_level_ms_, maximum_delay_ms_); + } + if (packet_len_ms_ > 0) { + // Target level should be at least one packet. + target_level_ms_ = std::max(target_level_ms_, packet_len_ms_); + // Limit to 75% of maximum buffer size. + target_level_ms_ = std::min( + target_level_ms_, 3 * max_packets_in_buffer_ * packet_len_ms_ / 4); + } - if (enable_rtx_handling_ && reordered && - num_reordered_packets_ < kMaxReorderedPackets) { - ++num_reordered_packets_; - return relative_delay; + // Prepare for next packet arrival. + if (reordered) { + // Allow a small number of reordered packets before resetting the delay + // estimation. + if (num_reordered_packets_ < kMaxNumReorderedPackets) { + ++num_reordered_packets_; + return relative_delay; + } + delay_history_.clear(); } num_reordered_packets_ = 0; - // Prepare for next packet arrival. packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); - last_seq_no_ = sequence_number; last_timestamp_ = timestamp; return relative_delay; } @@ -220,7 +230,7 @@ void DelayManager::UpdateDelayHistory(int iat_delay_ms, delay.timestamp = timestamp; delay_history_.push_back(delay); while (timestamp - delay_history_.front().timestamp > - static_cast(kMaxHistoryMs * sample_rate_hz / 1000)) { + static_cast(max_history_ms_ * sample_rate_hz / 1000)) { delay_history_.pop_front(); } } @@ -238,128 +248,29 @@ int DelayManager::CalculateRelativePacketArrivalDelay() const { return relative_delay; } -// Enforces upper and lower limits for |target_level_|. The upper limit is -// chosen to be minimum of i) 75% of |max_packets_in_buffer_|, to leave some -// headroom for natural fluctuations around the target, and ii) equivalent of -// |maximum_delay_ms_| in packets. Note that in practice, if no -// |maximum_delay_ms_| is specified, this does not have any impact, since the -// target level is far below the buffer capacity in all reasonable cases. -// The lower limit is equivalent of |effective_minimum_delay_ms_| in packets. -// We update |least_required_level_| while the above limits are applied. -// TODO(hlundin): Move this check to the buffer logistics class. -void DelayManager::LimitTargetLevel() { - if (packet_len_ms_ > 0 && effective_minimum_delay_ms_ > 0) { - int minimum_delay_packet_q8 = - (effective_minimum_delay_ms_ << 8) / packet_len_ms_; - target_level_ = std::max(target_level_, minimum_delay_packet_q8); - } - - if (maximum_delay_ms_ > 0 && packet_len_ms_ > 0) { - int maximum_delay_packet_q8 = (maximum_delay_ms_ << 8) / packet_len_ms_; - target_level_ = std::min(target_level_, maximum_delay_packet_q8); - } - - // Shift to Q8, then 75%.; - int max_buffer_packets_q8 = - static_cast((3 * (max_packets_in_buffer_ << 8)) / 4); - target_level_ = std::min(target_level_, max_buffer_packets_q8); - - // Sanity check, at least 1 packet (in Q8). - target_level_ = std::max(target_level_, 1 << 8); -} - -int DelayManager::CalculateTargetLevel() { - int limit_probability = histogram_quantile_; - - int bucket_index = histogram_->Quantile(limit_probability); - int target_level = 1; - if (packet_len_ms_ > 0) { - target_level += bucket_index * kBucketSizeMs / packet_len_ms_; - } - base_target_level_ = target_level; - - // Sanity check. |target_level| must be strictly positive. - target_level = std::max(target_level, 1); - // Scale to Q8 and assign to member variable. - target_level_ = target_level << 8; - return target_level_; -} - int DelayManager::SetPacketAudioLength(int length_ms) { if (length_ms <= 0) { RTC_LOG_F(LS_ERROR) << "length_ms = " << length_ms; return -1; } - packet_len_ms_ = length_ms; - packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); - last_pack_cng_or_dtmf_ = 1; // TODO(hlundin): Legacy. Remove? return 0; } void DelayManager::Reset() { - packet_len_ms_ = 0; // Packet size unknown. + packet_len_ms_ = 0; histogram_->Reset(); delay_history_.clear(); - base_target_level_ = 4; - target_level_ = base_target_level_ << 8; + target_level_ms_ = kStartDelayMs; packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); - last_pack_cng_or_dtmf_ = 1; + first_packet_received_ = false; + num_reordered_packets_ = 0; + resample_stopwatch_ = tick_timer_->GetNewStopwatch(); + max_delay_in_interval_ms_ = 0; } -void DelayManager::ResetPacketIatCount() { - packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); -} - -void DelayManager::BufferLimits(int* lower_limit, int* higher_limit) const { - BufferLimits(target_level_, lower_limit, higher_limit); -} - -// Note that |low_limit| and |higher_limit| are not assigned to -// |minimum_delay_ms_| and |maximum_delay_ms_| defined by the client of this -// class. They are computed from |target_level| in Q8 and used for decision -// making. -void DelayManager::BufferLimits(int target_level, - int* lower_limit, - int* higher_limit) const { - if (!lower_limit || !higher_limit) { - RTC_LOG_F(LS_ERROR) << "NULL pointers supplied as input"; - assert(false); - return; - } - - // |target_level| is in Q8 already. - *lower_limit = (target_level * 3) / 4; - - if (packet_len_ms_ > 0) { - *lower_limit = - std::max(*lower_limit, target_level - kDecelerationTargetLevelOffsetMs / - packet_len_ms_); - } - - int window_20ms = 0x7FFF; // Default large value for legacy bit-exactness. - if (packet_len_ms_ > 0) { - window_20ms = (20 << 8) / packet_len_ms_; - } - // |higher_limit| is equal to |target_level|, but should at - // least be 20 ms higher than |lower_limit|. - *higher_limit = std::max(target_level, *lower_limit + window_20ms); -} - -int DelayManager::TargetLevel() const { - return target_level_; -} - -void DelayManager::LastDecodedWasCngOrDtmf(bool it_was) { - if (it_was) { - last_pack_cng_or_dtmf_ = 1; - } else if (last_pack_cng_or_dtmf_ != 0) { - last_pack_cng_or_dtmf_ = -1; - } -} - -void DelayManager::RegisterEmptyPacket() { - ++last_seq_no_; +int DelayManager::TargetDelayMs() const { + return target_level_ms_; } bool DelayManager::IsValidMinimumDelay(int delay_ms) const { @@ -409,17 +320,6 @@ int DelayManager::GetBaseMinimumDelay() const { return base_minimum_delay_ms_; } -int DelayManager::base_target_level() const { - return base_target_level_; -} -int DelayManager::last_pack_cng_or_dtmf() const { - return last_pack_cng_or_dtmf_; -} - -void DelayManager::set_last_pack_cng_or_dtmf(int value) { - last_pack_cng_or_dtmf_ = value; -} - void DelayManager::UpdateEffectiveMinimumDelay() { // Clamp |base_minimum_delay_ms_| into the range which can be effectively // used. @@ -432,16 +332,11 @@ void DelayManager::UpdateEffectiveMinimumDelay() { int DelayManager::MinimumDelayUpperBound() const { // Choose the lowest possible bound discarding 0 cases which mean the value // is not set and unconstrained. - int q75 = MaxBufferTimeQ75(); + int q75 = max_packets_in_buffer_ * packet_len_ms_ * 3 / 4; q75 = q75 > 0 ? q75 : kMaxBaseMinimumDelayMs; const int maximum_delay_ms = maximum_delay_ms_ > 0 ? maximum_delay_ms_ : kMaxBaseMinimumDelayMs; return std::min(maximum_delay_ms, q75); } -int DelayManager::MaxBufferTimeQ75() const { - const int max_buffer_time = max_packets_in_buffer_ * packet_len_ms_; - return rtc::dchecked_cast(3 * max_buffer_time / 4); -} - } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/delay_manager.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/delay_manager.h index ab9ba3416..9832ceda2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/delay_manager.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/delay_manager.h @@ -25,10 +25,11 @@ namespace webrtc { class DelayManager { public: - DelayManager(size_t max_packets_in_buffer, + DelayManager(int max_packets_in_buffer, int base_minimum_delay_ms, int histogram_quantile, - bool enable_rtx_handling, + absl::optional resample_interval_ms, + int max_history_ms, const TickTimer* tick_timer, std::unique_ptr histogram); @@ -37,58 +38,29 @@ class DelayManager { // is the number of packet slots in the buffer) and that the target delay // should be greater than or equal to |base_minimum_delay_ms|. Supply a // PeakDetector object to the DelayManager. - static std::unique_ptr Create(size_t max_packets_in_buffer, + static std::unique_ptr Create(int max_packets_in_buffer, int base_minimum_delay_ms, - bool enable_rtx_handling, const TickTimer* tick_timer); virtual ~DelayManager(); - // Updates the delay manager with a new incoming packet, with - // |sequence_number| and |timestamp| from the RTP header. This updates the - // inter-arrival time histogram and other statistics, as well as the - // associated DelayPeakDetector. A new target buffer level is calculated. - // Returns the relative delay if it can be calculated. - virtual absl::optional Update(uint16_t sequence_number, - uint32_t timestamp, - int sample_rate_hz); + // Updates the delay manager with a new incoming packet, with |timestamp| from + // the RTP header. This updates the statistics and a new target buffer level + // is calculated. Returns the relative delay if it can be calculated. If + // |reset| is true, restarts the relative arrival delay calculation from this + // packet. + virtual absl::optional Update(uint32_t timestamp, + int sample_rate_hz, + bool reset = false); - // Calculates a new target buffer level. Called from the Update() method. - // Sets target_level_ (in Q8) and returns the same value. Also calculates - // and updates base_target_level_, which is the target buffer level before - // taking delay peaks into account. - virtual int CalculateTargetLevel(); - - // Notifies the DelayManager of how much audio data is carried in each packet. - // The method updates the DelayPeakDetector too, and resets the inter-arrival - // time counter. Returns 0 on success, -1 on failure. - virtual int SetPacketAudioLength(int length_ms); - - // Resets the DelayManager and the associated DelayPeakDetector. + // Resets all state. virtual void Reset(); - // Reset the inter-arrival time counter to 0. - virtual void ResetPacketIatCount(); + // Gets the target buffer level in milliseconds. + virtual int TargetDelayMs() const; - // Writes the lower and higher limits which the buffer level should stay - // within to the corresponding pointers. The values are in (fractions of) - // packets in Q8. - virtual void BufferLimits(int* lower_limit, int* higher_limit) const; - virtual void BufferLimits(int target_level, - int* lower_limit, - int* higher_limit) const; - - // Gets the target buffer level, in (fractions of) packets in Q8. - virtual int TargetLevel() const; - - // Informs the delay manager whether or not the last decoded packet contained - // speech. - virtual void LastDecodedWasCngOrDtmf(bool it_was); - - // Notify the delay manager that empty packets have been received. These are - // packets that are part of the sequence number series, so that an empty - // packet will shift the sequence numbers for the following packets. - virtual void RegisterEmptyPacket(); + // Notifies the DelayManager of how much audio data is carried in each packet. + virtual int SetPacketAudioLength(int length_ms); // Accessors and mutators. // Assuming |delay| is in valid range. @@ -96,16 +68,11 @@ class DelayManager { virtual bool SetMaximumDelay(int delay_ms); virtual bool SetBaseMinimumDelay(int delay_ms); virtual int GetBaseMinimumDelay() const; - virtual int base_target_level() const; - virtual int last_pack_cng_or_dtmf() const; - virtual void set_last_pack_cng_or_dtmf(int value); - // This accessor is only intended for testing purposes. + // These accessors are only intended for testing purposes. int effective_minimum_delay_ms_for_test() const { return effective_minimum_delay_ms_; } - - // These accessors are only intended for testing purposes. int histogram_quantile() const { return histogram_quantile_; } Histogram* histogram() const { return histogram_.get(); } @@ -114,9 +81,6 @@ class DelayManager { // size and given |maximum_delay_ms_|. Lower bound is a constant 0. int MinimumDelayUpperBound() const; - // Provides 75% of currently possible maximum buffer size in milliseconds. - int MaxBufferTimeQ75() const; - // Updates |delay_history_|. void UpdateDelayHistory(int iat_delay_ms, uint32_t timestamp, @@ -130,10 +94,6 @@ class DelayManager { // and buffer size. void UpdateEffectiveMinimumDelay(); - // Makes sure that |target_level_| is not too large, taking - // |max_packets_in_buffer_| into account. This method is called by Update(). - void LimitTargetLevel(); - // Makes sure that |delay_ms| is less than maximum delay, if any maximum // is set. Also, if possible check |delay_ms| to be less than 75% of // |max_packets_in_buffer_|. @@ -142,31 +102,27 @@ class DelayManager { bool IsValidBaseMinimumDelay(int delay_ms) const; bool first_packet_received_; - const size_t max_packets_in_buffer_; // Capacity of the packet buffer. + // TODO(jakobi): set maximum buffer delay instead of number of packets. + const int max_packets_in_buffer_; std::unique_ptr histogram_; const int histogram_quantile_; const TickTimer* tick_timer_; - int base_minimum_delay_ms_; - // Provides delay which is used by LimitTargetLevel as lower bound on target - // delay. - int effective_minimum_delay_ms_; + const absl::optional resample_interval_ms_; + const int max_history_ms_; - // Time elapsed since last packet. - std::unique_ptr packet_iat_stopwatch_; - int base_target_level_; // Currently preferred buffer level before peak - // detection and streaming mode (Q0). - // TODO(turajs) change the comment according to the implementation of - // minimum-delay. - int target_level_; // Currently preferred buffer level in (fractions) - // of packets (Q8), before adding any extra delay. - int packet_len_ms_; // Length of audio in each incoming packet [ms]. - uint16_t last_seq_no_; // Sequence number for last received packet. - uint32_t last_timestamp_; // Timestamp for the last received packet. - int minimum_delay_ms_; // Externally set minimum delay. - int maximum_delay_ms_; // Externally set maximum allowed delay. - int last_pack_cng_or_dtmf_; - const bool enable_rtx_handling_; - int num_reordered_packets_ = 0; // Number of consecutive reordered packets. + int base_minimum_delay_ms_; + int effective_minimum_delay_ms_; // Used as lower bound for target delay. + int minimum_delay_ms_; // Externally set minimum delay. + int maximum_delay_ms_; // Externally set maximum allowed delay. + + int packet_len_ms_ = 0; + std::unique_ptr + packet_iat_stopwatch_; // Time elapsed since last packet. + int target_level_ms_; // Currently preferred buffer level. + uint32_t last_timestamp_; // Timestamp for the last received packet. + int num_reordered_packets_ = 0; + int max_delay_in_interval_ms_ = 0; + std::unique_ptr resample_stopwatch_; struct PacketDelay { int iat_delay_ms; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_buffer_level_filter.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_buffer_level_filter.h new file mode 100644 index 000000000..503f6ac6b --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_buffer_level_filter.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_BUFFER_LEVEL_FILTER_H_ +#define MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_BUFFER_LEVEL_FILTER_H_ + +#include "modules/audio_coding/neteq/buffer_level_filter.h" +#include "test/gmock.h" + +namespace webrtc { + +class MockBufferLevelFilter : public BufferLevelFilter { + public: + MOCK_METHOD(void, + Update, + (size_t buffer_size_samples, int time_stretched_samples)); + MOCK_METHOD(int, filtered_current_level, (), (const)); +}; + +} // namespace webrtc +#endif // MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_BUFFER_LEVEL_FILTER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_delay_manager.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_delay_manager.h new file mode 100644 index 000000000..5b5133ece --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_delay_manager.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_DELAY_MANAGER_H_ +#define MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_DELAY_MANAGER_H_ + +#include +#include + +#include "api/neteq/tick_timer.h" +#include "modules/audio_coding/neteq/delay_manager.h" +#include "test/gmock.h" + +namespace webrtc { + +class MockDelayManager : public DelayManager { + public: + MockDelayManager(size_t max_packets_in_buffer, + int base_minimum_delay_ms, + int histogram_quantile, + absl::optional resample_interval_ms, + int max_history_ms, + const TickTimer* tick_timer, + std::unique_ptr histogram) + : DelayManager(max_packets_in_buffer, + base_minimum_delay_ms, + histogram_quantile, + resample_interval_ms, + max_history_ms, + tick_timer, + std::move(histogram)) {} + MOCK_METHOD(int, TargetDelayMs, (), (const)); +}; + +} // namespace webrtc +#endif // MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_DELAY_MANAGER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_neteq_controller.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_neteq_controller.h index b7df85fb2..fdfdbb4d1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_neteq_controller.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/mock/mock_neteq_controller.h @@ -41,15 +41,12 @@ class MockNetEqController : public NetEqController { MOCK_METHOD(void, SetCngOff, (), (override)); MOCK_METHOD(void, ExpandDecision, (NetEq::Operation operation), (override)); MOCK_METHOD(void, AddSampleMemory, (int32_t value), (override)); - MOCK_METHOD(int, TargetLevelMs, (), (override)); + MOCK_METHOD(int, TargetLevelMs, (), (const, override)); MOCK_METHOD(absl::optional, PacketArrived, - (bool last_cng_or_dtmf, - size_t packet_length_samples, + (int fs_hz, bool should_update_stats, - uint16_t main_sequence_number, - uint32_t main_timestamp, - int fs_hz), + const PacketArrivedInfo& info), (override)); MOCK_METHOD(bool, PeakFound, (), (const, override)); MOCK_METHOD(int, GetFilteredBufferLevel, (), (const, override)); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/neteq_impl.cc index 643fb1e2d..f8d5d9dc1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/neteq_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/neteq_impl.cc @@ -387,17 +387,9 @@ int NetEqImpl::FilteredCurrentDelayMs() const { int NetEqImpl::NetworkStatistics(NetEqNetworkStatistics* stats) { MutexLock lock(&mutex_); assert(decoder_database_.get()); - const size_t total_samples_in_buffers = - packet_buffer_->NumSamplesInBuffer(decoder_frame_length_) + - sync_buffer_->FutureLength(); - assert(controller_.get()); - stats->preferred_buffer_size_ms = controller_->TargetLevelMs(); - stats->jitter_peaks_found = controller_->PeakFound(); - stats_->GetNetworkStatistics(fs_hz_, total_samples_in_buffers, - decoder_frame_length_, stats); + *stats = CurrentNetworkStatisticsInternal(); + stats_->GetNetworkStatistics(decoder_frame_length_, stats); // Compensate for output delay chain. - stats->current_buffer_size_ms += output_delay_chain_ms_; - stats->preferred_buffer_size_ms += output_delay_chain_ms_; stats->mean_waiting_time_ms += output_delay_chain_ms_; stats->median_waiting_time_ms += output_delay_chain_ms_; stats->min_waiting_time_ms += output_delay_chain_ms_; @@ -405,6 +397,31 @@ int NetEqImpl::NetworkStatistics(NetEqNetworkStatistics* stats) { return 0; } +NetEqNetworkStatistics NetEqImpl::CurrentNetworkStatistics() const { + MutexLock lock(&mutex_); + return CurrentNetworkStatisticsInternal(); +} + +NetEqNetworkStatistics NetEqImpl::CurrentNetworkStatisticsInternal() const { + assert(decoder_database_.get()); + NetEqNetworkStatistics stats; + const size_t total_samples_in_buffers = + packet_buffer_->NumSamplesInBuffer(decoder_frame_length_) + + sync_buffer_->FutureLength(); + + assert(controller_.get()); + stats.preferred_buffer_size_ms = controller_->TargetLevelMs(); + stats.jitter_peaks_found = controller_->PeakFound(); + RTC_DCHECK_GT(fs_hz_, 0); + stats.current_buffer_size_ms = + static_cast(total_samples_in_buffers * 1000 / fs_hz_); + + // Compensate for output delay chain. + stats.current_buffer_size_ms += output_delay_chain_ms_; + stats.preferred_buffer_size_ms += output_delay_chain_ms_; + return stats; +} + NetEqLifetimeStatistics NetEqImpl::GetLifetimeStatistics() const { MutexLock lock(&mutex_); return stats_->GetLifetimeStatistics(); @@ -663,6 +680,7 @@ int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, } PacketList parsed_packet_list; + bool is_dtx = false; while (!packet_list.empty()) { Packet& packet = packet_list.front(); const DecoderDatabase::DecoderInfo* info = @@ -703,6 +721,7 @@ int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, for (auto& result : results) { RTC_DCHECK(result.frame); RTC_DCHECK_GE(result.priority, 0); + is_dtx = is_dtx || result.frame->IsDtxPacket(); if (first) { // Re-use the node and move it to parsed_packet_list. packet_list.front() = packet_from_result(result); @@ -784,10 +803,13 @@ int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, decoder_database_->GetDecoderInfo(main_payload_type); assert(dec_info); // Already checked that the payload type is known. - const bool last_cng_or_dtmf = - dec_info->IsComfortNoise() || dec_info->IsDtmf(); - const size_t packet_length_samples = + NetEqController::PacketArrivedInfo info; + info.is_cng_or_dtmf = dec_info->IsComfortNoise() || dec_info->IsDtmf(); + info.packet_length_samples = number_of_primary_packets * decoder_frame_length_; + info.main_timestamp = main_timestamp; + info.main_sequence_number = main_sequence_number; + info.is_dtx = is_dtx; // Only update statistics if incoming packet is not older than last played // out packet or RTX handling is enabled, and if new codec flag is not // set. @@ -796,9 +818,8 @@ int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, static_cast(main_timestamp - timestamp_) >= 0) && !new_codec_; - auto relative_delay = controller_->PacketArrived( - last_cng_or_dtmf, packet_length_samples, should_update_stats, - main_sequence_number, main_timestamp, fs_hz_); + auto relative_delay = + controller_->PacketArrived(fs_hz_, should_update_stats, info); if (relative_delay) { stats_->RelativePacketArrivalDelay(relative_delay.value()); } @@ -840,6 +861,7 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, static_cast(audio_frame->samples_per_channel_); audio_frame->num_channels_ = sync_buffer_->Channels(); stats_->ExpandedNoiseSamples(output_size_samples_, false); + controller_->NotifyMutedState(); *muted = true; return 0; } @@ -1309,13 +1331,6 @@ int NetEqImpl::GetDecision(Operation* operation, int extracted_samples = 0; if (packet) { sync_buffer_->IncreaseEndTimestamp(packet->timestamp - end_timestamp); - if (controller_->CngOff()) { - // Adjustment of timestamp only corresponds to an actual packet loss - // if comfort noise is not played. If comfort noise was just played, - // this adjustment of timestamp is only done to get back in sync with the - // stream timestamp; no loss to report. - stats_->LostSamples(packet->timestamp - end_timestamp); - } if (*operation != Operation::kRfc3389Cng) { // We are about to decode and use a non-CNG packet. @@ -1707,7 +1722,7 @@ int NetEqImpl::DoAccelerate(int16_t* decoded_buffer, decoded_length = required_samples * num_channels; } - size_t samples_removed; + size_t samples_removed = 0; Accelerate::ReturnCodes return_code = accelerate_->Process(decoded_buffer, decoded_length, fast_accelerate, algorithm_buffer_.get(), &samples_removed); @@ -1785,7 +1800,7 @@ int NetEqImpl::DoPreemptiveExpand(int16_t* decoded_buffer, decoded_length = required_samples * num_channels; } - size_t samples_added; + size_t samples_added = 0; PreemptiveExpand::ReturnCodes return_code = preemptive_expand_->Process( decoded_buffer, decoded_length, old_borrowed_samples_per_channel, algorithm_buffer_.get(), &samples_added); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/neteq_impl.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/neteq_impl.h index 0ade6b538..e130422a3 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/neteq_impl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/neteq_impl.h @@ -162,6 +162,8 @@ class NetEqImpl : public webrtc::NetEq { // after the call. int NetworkStatistics(NetEqNetworkStatistics* stats) override; + NetEqNetworkStatistics CurrentNetworkStatistics() const override; + NetEqLifetimeStatistics GetLifetimeStatistics() const override; NetEqOperationsAndState GetOperationsAndState() const override; @@ -330,6 +332,9 @@ class NetEqImpl : public webrtc::NetEq { virtual void UpdatePlcComponents(int fs_hz, size_t channels) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + NetEqNetworkStatistics CurrentNetworkStatisticsInternal() const + RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + Clock* const clock_; mutable Mutex mutex_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/red_payload_splitter.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/red_payload_splitter.cc index 134369099..5681464f4 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/red_payload_splitter.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/red_payload_splitter.cc @@ -29,10 +29,10 @@ namespace webrtc { // The method loops through a list of packets {A, B, C, ...}. Each packet is // split into its corresponding RED payloads, {A1, A2, ...}, which is // temporarily held in the list |new_packets|. -// When the first packet in |packet_list| has been processed, the orignal packet -// is replaced by the new ones in |new_packets|, so that |packet_list| becomes: -// {A1, A2, ..., B, C, ...}. The method then continues with B, and C, until all -// the original packets have been replaced by their split payloads. +// When the first packet in |packet_list| has been processed, the original +// packet is replaced by the new ones in |new_packets|, so that |packet_list| +// becomes: {A1, A2, ..., B, C, ...}. The method then continues with B, and C, +// until all the original packets have been replaced by their split payloads. bool RedPayloadSplitter::SplitRed(PacketList* packet_list) { // Too many RED blocks indicates that something is wrong. Clamp it at some // reasonable value. @@ -43,6 +43,7 @@ bool RedPayloadSplitter::SplitRed(PacketList* packet_list) { const Packet& red_packet = *it; assert(!red_packet.payload.empty()); const uint8_t* payload_ptr = red_packet.payload.data(); + size_t payload_length = red_packet.payload.size(); // Read RED headers (according to RFC 2198): // @@ -67,6 +68,10 @@ bool RedPayloadSplitter::SplitRed(PacketList* packet_list) { bool last_block = false; size_t sum_length = 0; while (!last_block) { + if (payload_length == 0) { + RTC_LOG(LS_WARNING) << "SplitRed header too short"; + return false; + } RedHeader new_header; // Check the F bit. If F == 0, this was the last block. last_block = ((*payload_ptr & 0x80) == 0); @@ -74,11 +79,16 @@ bool RedPayloadSplitter::SplitRed(PacketList* packet_list) { new_header.payload_type = payload_ptr[0] & 0x7F; if (last_block) { // No more header data to read. - ++sum_length; // Account for RED header size of 1 byte. + sum_length += kRedLastHeaderLength; // Account for RED header size. new_header.timestamp = red_packet.timestamp; new_header.payload_length = red_packet.payload.size() - sum_length; - payload_ptr += 1; // Advance to first payload byte. + payload_ptr += kRedLastHeaderLength; // Advance to first payload byte. + payload_length -= kRedLastHeaderLength; } else { + if (payload_length < kRedHeaderLength) { + RTC_LOG(LS_WARNING) << "SplitRed header too short"; + return false; + } // Bits 8 through 21 are timestamp offset. int timestamp_offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2); @@ -86,12 +96,17 @@ bool RedPayloadSplitter::SplitRed(PacketList* packet_list) { // Bits 22 through 31 are payload length. new_header.payload_length = ((payload_ptr[2] & 0x03) << 8) + payload_ptr[3]; - payload_ptr += 4; // Advance to next RED header. + + sum_length += new_header.payload_length; + sum_length += kRedHeaderLength; // Account for RED header size. + + payload_ptr += kRedHeaderLength; // Advance to next RED header. + payload_length -= kRedHeaderLength; } - sum_length += new_header.payload_length; - sum_length += 4; // Account for RED header size of 4 bytes. // Store in new list of packets. - new_headers.push_back(new_header); + if (new_header.payload_length > 0) { + new_headers.push_back(new_header); + } } if (new_headers.size() <= kMaxRedBlocks) { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/red_payload_splitter.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/red_payload_splitter.h index c2e0a445d..c54ffc0da 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/red_payload_splitter.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/red_payload_splitter.h @@ -18,6 +18,9 @@ namespace webrtc { class DecoderDatabase; +static const size_t kRedHeaderLength = 4; // 4 bytes RED header. +static const size_t kRedLastHeaderLength = + 1; // reduced size for last RED header. // This class handles splitting of RED payloads into smaller parts. // Codec-specific packet splitting can be performed by // AudioDecoder::ParsePayload. diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/statistics_calculator.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/statistics_calculator.cc index fa2925ce4..708780a8a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/statistics_calculator.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/statistics_calculator.cc @@ -115,11 +115,8 @@ void StatisticsCalculator::PeriodicUmaAverage::Reset() { StatisticsCalculator::StatisticsCalculator() : preemptive_samples_(0), accelerate_samples_(0), - added_zero_samples_(0), expanded_speech_samples_(0), expanded_noise_samples_(0), - discarded_packets_(0), - lost_timestamps_(0), timestamps_since_last_report_(0), secondary_decoded_samples_(0), discarded_secondary_packets_(0), @@ -139,7 +136,6 @@ StatisticsCalculator::~StatisticsCalculator() = default; void StatisticsCalculator::Reset() { preemptive_samples_ = 0; accelerate_samples_ = 0; - added_zero_samples_ = 0; expanded_speech_samples_ = 0; expanded_noise_samples_ = 0; secondary_decoded_samples_ = 0; @@ -148,8 +144,6 @@ void StatisticsCalculator::Reset() { } void StatisticsCalculator::ResetMcu() { - discarded_packets_ = 0; - lost_timestamps_ = 0; timestamps_since_last_report_ = 0; } @@ -237,10 +231,6 @@ void StatisticsCalculator::AcceleratedSamples(size_t num_samples) { lifetime_stats_.removed_samples_for_acceleration += num_samples; } -void StatisticsCalculator::AddZeros(size_t num_samples) { - added_zero_samples_ += num_samples; -} - void StatisticsCalculator::PacketsDiscarded(size_t num_packets) { operations_and_state_.discarded_primary_packets += num_packets; } @@ -254,10 +244,6 @@ void StatisticsCalculator::SecondaryPacketsReceived(size_t num_packets) { lifetime_stats_.fec_packets_received += num_packets; } -void StatisticsCalculator::LostSamples(size_t num_samples) { - lost_timestamps_ += num_samples; -} - void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) { const int time_step_ms = rtc::CheckedDivExact(static_cast(1000 * num_samples), fs_hz); @@ -267,9 +253,7 @@ void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) { timestamps_since_last_report_ += static_cast(num_samples); if (timestamps_since_last_report_ > static_cast(fs_hz * kMaxReportPeriod)) { - lost_timestamps_ = 0; timestamps_since_last_report_ = 0; - discarded_packets_ = 0; } lifetime_stats_.total_samples_received += num_samples; } @@ -321,20 +305,10 @@ void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) { operations_and_state_.last_waiting_time_ms = waiting_time_ms; } -void StatisticsCalculator::GetNetworkStatistics(int fs_hz, - size_t num_samples_in_buffers, - size_t samples_per_packet, +void StatisticsCalculator::GetNetworkStatistics(size_t samples_per_packet, NetEqNetworkStatistics* stats) { - RTC_DCHECK_GT(fs_hz, 0); RTC_DCHECK(stats); - stats->added_zero_samples = added_zero_samples_; - stats->current_buffer_size_ms = - static_cast(num_samples_in_buffers * 1000 / fs_hz); - - stats->packet_loss_rate = - CalculateQ14Ratio(lost_timestamps_, timestamps_since_last_report_); - stats->accelerate_rate = CalculateQ14Ratio(accelerate_samples_, timestamps_since_last_report_); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/statistics_calculator.h b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/statistics_calculator.h index 333f4a76a..f0c273442 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/statistics_calculator.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_coding/neteq/statistics_calculator.h @@ -62,9 +62,6 @@ class StatisticsCalculator { // Reports that |num_samples| samples were removed through accelerate. void AcceleratedSamples(size_t num_samples); - // Reports that |num_samples| zeros were inserted into the output. - void AddZeros(size_t num_samples); - // Reports that |num_packets| packets were discarded. virtual void PacketsDiscarded(size_t num_packets); @@ -74,9 +71,6 @@ class StatisticsCalculator { // Reports that |num_packets| secondary (FEC) packets were received. virtual void SecondaryPacketsReceived(size_t num_packets); - // Reports that |num_samples| were lost. - void LostSamples(size_t num_samples); - // Increases the report interval counter with |num_samples| at a sample rate // of |fs_hz|. This is how the StatisticsCalculator gets notified that current // time is increasing. @@ -107,15 +101,11 @@ class StatisticsCalculator { // period caused not by an actual packet loss, but by a delayed packet. virtual void LogDelayedPacketOutageEvent(int num_samples, int fs_hz); - // Returns the current network statistics in |stats|. The current sample rate - // is |fs_hz|, the total number of samples in packet buffer and sync buffer - // yet to play out is |num_samples_in_buffers|, and the number of samples per - // packet is |samples_per_packet|. The method does not populate + // Returns the current network statistics in |stats|. The number of samples + // per packet is |samples_per_packet|. The method does not populate // |preferred_buffer_size_ms|, |jitter_peaks_found| or |clockdrift_ppm|; use // the PopulateDelayManagerStats method for those. - void GetNetworkStatistics(int fs_hz, - size_t num_samples_in_buffers, - size_t samples_per_packet, + void GetNetworkStatistics(size_t samples_per_packet, NetEqNetworkStatistics* stats); // Returns a copy of this class's lifetime statistics. These statistics are @@ -196,12 +186,9 @@ class StatisticsCalculator { size_t silent_concealed_samples_correction_ = 0; size_t preemptive_samples_; size_t accelerate_samples_; - size_t added_zero_samples_; size_t expanded_speech_samples_; size_t expanded_noise_samples_; size_t concealed_samples_at_event_end_ = 0; - size_t discarded_packets_; - size_t lost_timestamps_; uint32_t timestamps_since_last_report_; std::deque waiting_times_; uint32_t secondary_decoded_samples_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/aaudio_recorder.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/aaudio_recorder.cc index 3a29bb80f..95f1a1a3c 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/aaudio_recorder.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/aaudio_recorder.cc @@ -18,7 +18,6 @@ #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/time_utils.h" -#include "system_wrappers/include/sleep.h" namespace webrtc { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/audio_device_template.h b/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/audio_device_template.h index a2185047e..fb5bf6fa5 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/audio_device_template.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/audio_device_template.h @@ -103,15 +103,13 @@ class AudioDeviceTemplate : public AudioDeviceGeneric { int32_t PlayoutDeviceName(uint16_t index, char name[kAdmMaxDeviceNameSize], char guid[kAdmMaxGuidSize]) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t RecordingDeviceName(uint16_t index, char name[kAdmMaxDeviceNameSize], char guid[kAdmMaxGuidSize]) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SetPlayoutDevice(uint16_t index) override { @@ -123,8 +121,7 @@ class AudioDeviceTemplate : public AudioDeviceGeneric { int32_t SetPlayoutDevice( AudioDeviceModule::WindowsDeviceType device) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SetRecordingDevice(uint16_t index) override { @@ -136,8 +133,7 @@ class AudioDeviceTemplate : public AudioDeviceGeneric { int32_t SetRecordingDevice( AudioDeviceModule::WindowsDeviceType device) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t PlayoutIsAvailable(bool& available) override { @@ -266,53 +262,38 @@ class AudioDeviceTemplate : public AudioDeviceGeneric { } int32_t SetMicrophoneVolume(uint32_t volume) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t MicrophoneVolume(uint32_t& volume) const override { - FATAL() << "Should never be called"; + RTC_CHECK_NOTREACHED(); return -1; } int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t MinMicrophoneVolume(uint32_t& minVolume) const override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SpeakerMuteIsAvailable(bool& available) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } - int32_t SetSpeakerMute(bool enable) override { - FATAL() << "Should never be called"; - return -1; - } + int32_t SetSpeakerMute(bool enable) override { RTC_CHECK_NOTREACHED(); } - int32_t SpeakerMute(bool& enabled) const override { - FATAL() << "Should never be called"; - return -1; - } + int32_t SpeakerMute(bool& enabled) const override { RTC_CHECK_NOTREACHED(); } int32_t MicrophoneMuteIsAvailable(bool& available) override { - FATAL() << "Not implemented"; - return -1; + RTC_CHECK_NOTREACHED(); } - int32_t SetMicrophoneMute(bool enable) override { - FATAL() << "Not implemented"; - return -1; - } + int32_t SetMicrophoneMute(bool enable) override { RTC_CHECK_NOTREACHED(); } int32_t MicrophoneMute(bool& enabled) const override { - FATAL() << "Not implemented"; - return -1; + RTC_CHECK_NOTREACHED(); } // Returns true if the audio manager has been configured to support stereo diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/audio_record_jni.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/audio_record_jni.cc index 12ac45876..a3aa85565 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/audio_record_jni.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/android/audio_record_jni.cc @@ -219,8 +219,7 @@ int32_t AudioRecordJni::EnableBuiltInAEC(bool enable) { int32_t AudioRecordJni::EnableBuiltInAGC(bool enable) { // TODO(henrika): possibly remove when no longer used by any client. - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t AudioRecordJni::EnableBuiltInNS(bool enable) { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/include/audio_device_factory.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_device/include/audio_device_factory.cc index 909506b9f..d5b381029 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/include/audio_device_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/include/audio_device_factory.cc @@ -38,7 +38,7 @@ CreateWindowsCoreAudioAudioDeviceModuleForTest( bool automatic_restart) { RTC_DLOG(INFO) << __FUNCTION__; // Returns NULL if Core Audio is not supported or if COM has not been - // initialized correctly using webrtc_win::ScopedCOMInitializer. + // initialized correctly using ScopedCOMInitializer. if (!webrtc_win::core_audio_utility::IsSupported()) { RTC_LOG(LS_ERROR) << "Unable to create ADM since Core Audio is not supported"; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/include/audio_device_factory.h b/TMessagesProj/jni/voip/webrtc/modules/audio_device/include/audio_device_factory.h index fb1ac41fa..9c19d6196 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/include/audio_device_factory.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/include/audio_device_factory.h @@ -30,8 +30,8 @@ namespace webrtc { // rtc::scoped_refptr CreateAudioDevice() { // task_queue_factory_ = CreateDefaultTaskQueueFactory(); // // Tell COM that this thread shall live in the MTA. -// com_initializer_ = std::make_unique( -// webrtc_win::ScopedCOMInitializer::kMTA); +// com_initializer_ = std::make_unique( +// ScopedCOMInitializer::kMTA); // if (!com_initializer_->Succeeded()) { // return nullptr; // } @@ -42,7 +42,7 @@ namespace webrtc { // } // // private: -// std::unique_ptr com_initializer_; +// std::unique_ptr com_initializer_; // std::unique_ptr task_queue_factory_; // rtc::scoped_refptr CreateWindowsCoreAudioAudioDeviceModule( diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_alsa_linux.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_alsa_linux.cc index 5fac1bcac..84d05e0f6 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_alsa_linux.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_alsa_linux.cc @@ -217,7 +217,10 @@ bool AudioDeviceLinuxALSA::Initialized() const { int32_t AudioDeviceLinuxALSA::InitSpeaker() { MutexLock lock(&mutex_); + return InitSpeakerLocked(); +} +int32_t AudioDeviceLinuxALSA::InitSpeakerLocked() { if (_playing) { return -1; } @@ -229,7 +232,10 @@ int32_t AudioDeviceLinuxALSA::InitSpeaker() { int32_t AudioDeviceLinuxALSA::InitMicrophone() { MutexLock lock(&mutex_); + return InitMicrophoneLocked(); +} +int32_t AudioDeviceLinuxALSA::InitMicrophoneLocked() { if (_recording) { return -1; } @@ -421,22 +427,22 @@ int32_t AudioDeviceLinuxALSA::StereoRecordingIsAvailable(bool& available) { // Stop/uninitialize recording if initialized (and possibly started) if (_recIsInitialized) { - StopRecording(); + StopRecordingLocked(); } // Try init in stereo; _recChannels = 2; - if (InitRecording() == 0) { + if (InitRecordingLocked() == 0) { available = true; } // Stop/uninitialize recording - StopRecording(); + StopRecordingLocked(); // Recover previous states _recChannels = recChannels; if (recIsInitialized) { - InitRecording(); + InitRecordingLocked(); } if (recording) { StartRecording(); @@ -481,22 +487,22 @@ int32_t AudioDeviceLinuxALSA::StereoPlayoutIsAvailable(bool& available) { // Stop/uninitialize recording if initialized (and possibly started) if (_playIsInitialized) { - StopPlayout(); + StopPlayoutLocked(); } // Try init in stereo; _playChannels = 2; - if (InitPlayout() == 0) { + if (InitPlayoutLocked() == 0) { available = true; } // Stop/uninitialize recording - StopPlayout(); + StopPlayoutLocked(); // Recover previous states _playChannels = playChannels; if (playIsInitialized) { - InitPlayout(); + InitPlayoutLocked(); } if (playing) { StartPlayout(); @@ -745,9 +751,13 @@ int32_t AudioDeviceLinuxALSA::RecordingIsAvailable(bool& available) { } int32_t AudioDeviceLinuxALSA::InitPlayout() { + MutexLock lock(&mutex_); + return InitPlayoutLocked(); +} + +int32_t AudioDeviceLinuxALSA::InitPlayoutLocked() { int errVal = 0; - MutexLock lock(&mutex_); if (_playing) { return -1; } @@ -760,7 +770,7 @@ int32_t AudioDeviceLinuxALSA::InitPlayout() { return 0; } // Initialize the speaker (devices might have been added or removed) - if (InitSpeaker() == -1) { + if (InitSpeakerLocked() == -1) { RTC_LOG(LS_WARNING) << "InitSpeaker() failed"; } @@ -864,9 +874,12 @@ int32_t AudioDeviceLinuxALSA::InitPlayout() { } int32_t AudioDeviceLinuxALSA::InitRecording() { - int errVal = 0; - MutexLock lock(&mutex_); + return InitRecordingLocked(); +} + +int32_t AudioDeviceLinuxALSA::InitRecordingLocked() { + int errVal = 0; if (_recording) { return -1; @@ -881,7 +894,7 @@ int32_t AudioDeviceLinuxALSA::InitRecording() { } // Initialize the microphone (devices might have been added or removed) - if (InitMicrophone() == -1) { + if (InitMicrophoneLocked() == -1) { RTC_LOG(LS_WARNING) << "InitMicrophone() failed"; } @@ -1058,28 +1071,28 @@ int32_t AudioDeviceLinuxALSA::StartRecording() { } int32_t AudioDeviceLinuxALSA::StopRecording() { - { MutexLock lock(&mutex_); + return StopRecordingLocked(); +} - if (!_recIsInitialized) { - return 0; - } - - if (_handleRecord == NULL) { - return -1; - } - - // Make sure we don't start recording (it's asynchronous). - _recIsInitialized = false; - _recording = false; +int32_t AudioDeviceLinuxALSA::StopRecordingLocked() { + if (!_recIsInitialized) { + return 0; } + if (_handleRecord == NULL) { + return -1; + } + + // Make sure we don't start recording (it's asynchronous). + _recIsInitialized = false; + _recording = false; + if (_ptrThreadRec) { _ptrThreadRec->Stop(); _ptrThreadRec.reset(); } - MutexLock lock(&mutex_); _recordingFramesLeft = 0; if (_recordingBuffer) { delete[] _recordingBuffer; @@ -1162,28 +1175,27 @@ int32_t AudioDeviceLinuxALSA::StartPlayout() { } int32_t AudioDeviceLinuxALSA::StopPlayout() { - { MutexLock lock(&mutex_); + return StopPlayoutLocked(); +} - if (!_playIsInitialized) { - return 0; - } - - if (_handlePlayout == NULL) { - return -1; - } - - _playing = false; +int32_t AudioDeviceLinuxALSA::StopPlayoutLocked() { + if (!_playIsInitialized) { + return 0; } + if (_handlePlayout == NULL) { + return -1; + } + + _playing = false; + // stop playout thread first if (_ptrThreadPlay) { _ptrThreadPlay->Stop(); _ptrThreadPlay.reset(); } - MutexLock lock(&mutex_); - _playoutFramesLeft = 0; delete[] _playoutBuffer; _playoutBuffer = NULL; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_alsa_linux.h b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_alsa_linux.h index 0e0b7919b..410afcf42 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_alsa_linux.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_alsa_linux.h @@ -40,8 +40,8 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric { AudioDeviceModule::AudioLayer& audioLayer) const override; // Main initializaton and termination - InitStatus Init() override; - int32_t Terminate() override; + InitStatus Init() RTC_LOCKS_EXCLUDED(mutex_) override; + int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_) override; bool Initialized() const override; // Device enumeration @@ -64,24 +64,24 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric { // Audio transport initialization int32_t PlayoutIsAvailable(bool& available) override; - int32_t InitPlayout() override; + int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; bool PlayoutIsInitialized() const override; int32_t RecordingIsAvailable(bool& available) override; - int32_t InitRecording() override; + int32_t InitRecording() RTC_LOCKS_EXCLUDED(mutex_) override; bool RecordingIsInitialized() const override; // Audio transport control int32_t StartPlayout() override; - int32_t StopPlayout() override; + int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; bool Playing() const override; int32_t StartRecording() override; - int32_t StopRecording() override; + int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_) override; bool Recording() const override; // Audio mixer initialization - int32_t InitSpeaker() override; + int32_t InitSpeaker() RTC_LOCKS_EXCLUDED(mutex_) override; bool SpeakerIsInitialized() const override; - int32_t InitMicrophone() override; + int32_t InitMicrophone() RTC_LOCKS_EXCLUDED(mutex_) override; bool MicrophoneIsInitialized() const override; // Speaker volume controls @@ -109,19 +109,28 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric { int32_t MicrophoneMute(bool& enabled) const override; // Stereo support - int32_t StereoPlayoutIsAvailable(bool& available) override; + int32_t StereoPlayoutIsAvailable(bool& available) + RTC_LOCKS_EXCLUDED(mutex_) override; int32_t SetStereoPlayout(bool enable) override; int32_t StereoPlayout(bool& enabled) const override; - int32_t StereoRecordingIsAvailable(bool& available) override; + int32_t StereoRecordingIsAvailable(bool& available) + RTC_LOCKS_EXCLUDED(mutex_) override; int32_t SetStereoRecording(bool enable) override; int32_t StereoRecording(bool& enabled) const override; // Delay information and control int32_t PlayoutDelay(uint16_t& delayMS) const override; - void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override; + void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) + RTC_LOCKS_EXCLUDED(mutex_) override; private: + int32_t InitRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t StopRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t StopPlayoutLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t InitPlayoutLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t InitSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t InitMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); int32_t GetDevicesInfo(const int32_t function, const bool playback, const int32_t enumDeviceNo = 0, diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_pulse_linux.h b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_pulse_linux.h index f05ba1ebf..03aa16bb8 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_pulse_linux.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_device_pulse_linux.h @@ -116,7 +116,7 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { // Main initializaton and termination InitStatus Init() override; - int32_t Terminate() override; + int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_) override; bool Initialized() const override; // Device enumeration @@ -139,18 +139,18 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { // Audio transport initialization int32_t PlayoutIsAvailable(bool& available) override; - int32_t InitPlayout() override; + int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; bool PlayoutIsInitialized() const override; int32_t RecordingIsAvailable(bool& available) override; int32_t InitRecording() override; bool RecordingIsInitialized() const override; // Audio transport control - int32_t StartPlayout() override; - int32_t StopPlayout() override; + int32_t StartPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; + int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; bool Playing() const override; - int32_t StartRecording() override; - int32_t StopRecording() override; + int32_t StartRecording() RTC_LOCKS_EXCLUDED(mutex_) override; + int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_) override; bool Recording() const override; // Audio mixer initialization @@ -192,7 +192,8 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { int32_t StereoRecording(bool& enabled) const override; // Delay information and control - int32_t PlayoutDelay(uint16_t& delayMS) const override; + int32_t PlayoutDelay(uint16_t& delayMS) const + RTC_LOCKS_EXCLUDED(mutex_) override; void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override; @@ -256,8 +257,8 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { static void RecThreadFunc(void*); static void PlayThreadFunc(void*); - bool RecThreadProcess(); - bool PlayThreadProcess(); + bool RecThreadProcess() RTC_LOCKS_EXCLUDED(mutex_); + bool PlayThreadProcess() RTC_LOCKS_EXCLUDED(mutex_); AudioDeviceBuffer* _ptrAudioBuffer; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.cc index 028be5db6..fb9d874ef 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.cc @@ -47,16 +47,19 @@ int32_t AudioMixerManagerLinuxALSA::Close() { MutexLock lock(&mutex_); - CloseSpeaker(); - CloseMicrophone(); + CloseSpeakerLocked(); + CloseMicrophoneLocked(); return 0; } int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() { - RTC_LOG(LS_VERBOSE) << __FUNCTION__; - MutexLock lock(&mutex_); + return CloseSpeakerLocked(); +} + +int32_t AudioMixerManagerLinuxALSA::CloseSpeakerLocked() { + RTC_LOG(LS_VERBOSE) << __FUNCTION__; int errVal = 0; @@ -86,9 +89,12 @@ int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() { } int32_t AudioMixerManagerLinuxALSA::CloseMicrophone() { - RTC_LOG(LS_VERBOSE) << __FUNCTION__; - MutexLock lock(&mutex_); + return CloseMicrophoneLocked(); +} + +int32_t AudioMixerManagerLinuxALSA::CloseMicrophoneLocked() { + RTC_LOG(LS_VERBOSE) << __FUNCTION__; int errVal = 0; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h index 61490b4a7..d98287822 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h @@ -21,27 +21,27 @@ namespace webrtc { class AudioMixerManagerLinuxALSA { public: - int32_t OpenSpeaker(char* deviceName); - int32_t OpenMicrophone(char* deviceName); - int32_t SetSpeakerVolume(uint32_t volume); + int32_t OpenSpeaker(char* deviceName) RTC_LOCKS_EXCLUDED(mutex_); + int32_t OpenMicrophone(char* deviceName) RTC_LOCKS_EXCLUDED(mutex_); + int32_t SetSpeakerVolume(uint32_t volume) RTC_LOCKS_EXCLUDED(mutex_); int32_t SpeakerVolume(uint32_t& volume) const; int32_t MaxSpeakerVolume(uint32_t& maxVolume) const; int32_t MinSpeakerVolume(uint32_t& minVolume) const; int32_t SpeakerVolumeIsAvailable(bool& available); int32_t SpeakerMuteIsAvailable(bool& available); - int32_t SetSpeakerMute(bool enable); + int32_t SetSpeakerMute(bool enable) RTC_LOCKS_EXCLUDED(mutex_); int32_t SpeakerMute(bool& enabled) const; int32_t MicrophoneMuteIsAvailable(bool& available); - int32_t SetMicrophoneMute(bool enable); + int32_t SetMicrophoneMute(bool enable) RTC_LOCKS_EXCLUDED(mutex_); int32_t MicrophoneMute(bool& enabled) const; int32_t MicrophoneVolumeIsAvailable(bool& available); - int32_t SetMicrophoneVolume(uint32_t volume); + int32_t SetMicrophoneVolume(uint32_t volume) RTC_LOCKS_EXCLUDED(mutex_); int32_t MicrophoneVolume(uint32_t& volume) const; int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const; int32_t MinMicrophoneVolume(uint32_t& minVolume) const; - int32_t Close(); - int32_t CloseSpeaker(); - int32_t CloseMicrophone(); + int32_t Close() RTC_LOCKS_EXCLUDED(mutex_); + int32_t CloseSpeaker() RTC_LOCKS_EXCLUDED(mutex_); + int32_t CloseMicrophone() RTC_LOCKS_EXCLUDED(mutex_); bool SpeakerIsInitialized() const; bool MicrophoneIsInitialized() const; @@ -50,6 +50,8 @@ class AudioMixerManagerLinuxALSA { ~AudioMixerManagerLinuxALSA(); private: + int32_t CloseSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t CloseMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); int32_t LoadMicMixerElement() const; int32_t LoadSpeakerMixerElement() const; void GetControlName(char* controlName, char* deviceName) const; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/audio_mixer_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/audio_mixer_impl.cc index 6552953de..04a8bcf72 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/audio_mixer_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/audio_mixer_impl.cc @@ -24,9 +24,23 @@ #include "rtc_base/ref_counted_object.h" namespace webrtc { + +struct AudioMixerImpl::SourceStatus { + SourceStatus(Source* audio_source, bool is_mixed, float gain) + : audio_source(audio_source), is_mixed(is_mixed), gain(gain) {} + Source* audio_source = nullptr; + bool is_mixed = false; + float gain = 0.0f; + + // A frame that will be passed to audio_source->GetAudioFrameWithInfo. + AudioFrame audio_frame; +}; + namespace { struct SourceFrame { + SourceFrame() = default; + SourceFrame(AudioMixerImpl::SourceStatus* source_status, AudioFrame* audio_frame, bool muted) @@ -57,6 +71,7 @@ struct SourceFrame { }; // ShouldMixBefore(a, b) is used to select mixer sources. +// Returns true if `a` is preferred over `b` as a source to be mixed. bool ShouldMixBefore(const SourceFrame& a, const SourceFrame& b) { if (a.muted != b.muted) { return b.muted; @@ -73,7 +88,7 @@ bool ShouldMixBefore(const SourceFrame& a, const SourceFrame& b) { } void RampAndUpdateGain( - const std::vector& mixed_sources_and_frames) { + rtc::ArrayView mixed_sources_and_frames) { for (const auto& source_frame : mixed_sources_and_frames) { float target_gain = source_frame.source_status->is_mixed ? 1.0f : 0.0f; Ramp(source_frame.source_status->gain, target_gain, @@ -82,9 +97,11 @@ void RampAndUpdateGain( } } -AudioMixerImpl::SourceStatusList::const_iterator FindSourceInList( +std::vector>::const_iterator +FindSourceInList( AudioMixerImpl::Source const* audio_source, - AudioMixerImpl::SourceStatusList const* audio_source_list) { + std::vector> const* + audio_source_list) { return std::find_if( audio_source_list->begin(), audio_source_list->end(), [audio_source](const std::unique_ptr& p) { @@ -93,14 +110,31 @@ AudioMixerImpl::SourceStatusList::const_iterator FindSourceInList( } } // namespace +struct AudioMixerImpl::HelperContainers { + void resize(size_t size) { + audio_to_mix.resize(size); + audio_source_mixing_data_list.resize(size); + ramp_list.resize(size); + preferred_rates.resize(size); + } + + std::vector audio_to_mix; + std::vector audio_source_mixing_data_list; + std::vector ramp_list; + std::vector preferred_rates; +}; + AudioMixerImpl::AudioMixerImpl( std::unique_ptr output_rate_calculator, bool use_limiter) : output_rate_calculator_(std::move(output_rate_calculator)), - output_frequency_(0), - sample_size_(0), audio_source_list_(), - frame_combiner_(use_limiter) {} + helper_containers_(std::make_unique()), + frame_combiner_(use_limiter) { + const int kTypicalMaxNumberOfMixedStreams = 3; + audio_source_list_.reserve(kTypicalMaxNumberOfMixedStreams); + helper_containers_->resize(kTypicalMaxNumberOfMixedStreams); +} AudioMixerImpl::~AudioMixerImpl() {} @@ -121,40 +155,23 @@ rtc::scoped_refptr AudioMixerImpl::Create( void AudioMixerImpl::Mix(size_t number_of_channels, AudioFrame* audio_frame_for_mixing) { RTC_DCHECK(number_of_channels >= 1); - RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); - - CalculateOutputFrequency(); - - { - MutexLock lock(&mutex_); - const size_t number_of_streams = audio_source_list_.size(); - frame_combiner_.Combine(GetAudioFromSources(), number_of_channels, - OutputFrequency(), number_of_streams, - audio_frame_for_mixing); - } - - return; -} - -void AudioMixerImpl::CalculateOutputFrequency() { - RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); MutexLock lock(&mutex_); - std::vector preferred_rates; + size_t number_of_streams = audio_source_list_.size(); + std::transform(audio_source_list_.begin(), audio_source_list_.end(), - std::back_inserter(preferred_rates), + helper_containers_->preferred_rates.begin(), [&](std::unique_ptr& a) { return a->audio_source->PreferredSampleRate(); }); - output_frequency_ = - output_rate_calculator_->CalculateOutputRate(preferred_rates); - sample_size_ = (output_frequency_ * kFrameDurationInMs) / 1000; -} + int output_frequency = output_rate_calculator_->CalculateOutputRateFromRange( + rtc::ArrayView(helper_containers_->preferred_rates.data(), + number_of_streams)); -int AudioMixerImpl::OutputFrequency() const { - RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); - return output_frequency_; + frame_combiner_.Combine(GetAudioFromSources(output_frequency), + number_of_channels, output_frequency, + number_of_streams, audio_frame_for_mixing); } bool AudioMixerImpl::AddSource(Source* audio_source) { @@ -164,6 +181,7 @@ bool AudioMixerImpl::AddSource(Source* audio_source) { audio_source_list_.end()) << "Source already added to mixer"; audio_source_list_.emplace_back(new SourceStatus(audio_source, false, 0)); + helper_containers_->resize(audio_source_list_.size()); return true; } @@ -175,35 +193,37 @@ void AudioMixerImpl::RemoveSource(Source* audio_source) { audio_source_list_.erase(iter); } -AudioFrameList AudioMixerImpl::GetAudioFromSources() { - RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); - AudioFrameList result; - std::vector audio_source_mixing_data_list; - std::vector ramp_list; - +rtc::ArrayView AudioMixerImpl::GetAudioFromSources( + int output_frequency) { // Get audio from the audio sources and put it in the SourceFrame vector. + int audio_source_mixing_data_count = 0; for (auto& source_and_status : audio_source_list_) { const auto audio_frame_info = source_and_status->audio_source->GetAudioFrameWithInfo( - OutputFrequency(), &source_and_status->audio_frame); + output_frequency, &source_and_status->audio_frame); if (audio_frame_info == Source::AudioFrameInfo::kError) { RTC_LOG_F(LS_WARNING) << "failed to GetAudioFrameWithInfo() from source"; continue; } - audio_source_mixing_data_list.emplace_back( - source_and_status.get(), &source_and_status->audio_frame, - audio_frame_info == Source::AudioFrameInfo::kMuted); + helper_containers_ + ->audio_source_mixing_data_list[audio_source_mixing_data_count++] = + SourceFrame(source_and_status.get(), &source_and_status->audio_frame, + audio_frame_info == Source::AudioFrameInfo::kMuted); } + rtc::ArrayView audio_source_mixing_data_view( + helper_containers_->audio_source_mixing_data_list.data(), + audio_source_mixing_data_count); // Sort frames by sorting function. - std::sort(audio_source_mixing_data_list.begin(), - audio_source_mixing_data_list.end(), ShouldMixBefore); + std::sort(audio_source_mixing_data_view.begin(), + audio_source_mixing_data_view.end(), ShouldMixBefore); int max_audio_frame_counter = kMaximumAmountOfMixedAudioSources; - + int ramp_list_lengh = 0; + int audio_to_mix_count = 0; // Go through list in order and put unmuted frames in result list. - for (const auto& p : audio_source_mixing_data_list) { + for (const auto& p : audio_source_mixing_data_view) { // Filter muted. if (p.muted) { p.source_status->is_mixed = false; @@ -214,19 +234,21 @@ AudioFrameList AudioMixerImpl::GetAudioFromSources() { bool is_mixed = false; if (max_audio_frame_counter > 0) { --max_audio_frame_counter; - result.push_back(p.audio_frame); - ramp_list.emplace_back(p.source_status, p.audio_frame, false, -1); + helper_containers_->audio_to_mix[audio_to_mix_count++] = p.audio_frame; + helper_containers_->ramp_list[ramp_list_lengh++] = + SourceFrame(p.source_status, p.audio_frame, false, -1); is_mixed = true; } p.source_status->is_mixed = is_mixed; } - RampAndUpdateGain(ramp_list); - return result; + RampAndUpdateGain(rtc::ArrayView( + helper_containers_->ramp_list.data(), ramp_list_lengh)); + return rtc::ArrayView( + helper_containers_->audio_to_mix.data(), audio_to_mix_count); } bool AudioMixerImpl::GetAudioSourceMixabilityStatusForTest( AudioMixerImpl::Source* audio_source) const { - RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); MutexLock lock(&mutex_); const auto iter = FindSourceInList(audio_source, &audio_source_list_); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/audio_mixer_impl.h b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/audio_mixer_impl.h index 57b1f5e4a..0a1308272 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/audio_mixer_impl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/audio_mixer_impl.h @@ -16,6 +16,7 @@ #include #include +#include "api/array_view.h" #include "api/audio/audio_frame.h" #include "api/audio/audio_mixer.h" #include "api/scoped_refptr.h" @@ -28,22 +29,9 @@ namespace webrtc { -typedef std::vector AudioFrameList; - class AudioMixerImpl : public AudioMixer { public: - struct SourceStatus { - SourceStatus(Source* audio_source, bool is_mixed, float gain) - : audio_source(audio_source), is_mixed(is_mixed), gain(gain) {} - Source* audio_source = nullptr; - bool is_mixed = false; - float gain = 0.0f; - - // A frame that will be passed to audio_source->GetAudioFrameWithInfo. - AudioFrame audio_frame; - }; - - using SourceStatusList = std::vector>; + struct SourceStatus; // AudioProcessing only accepts 10 ms frames. static const int kFrameDurationInMs = 10; @@ -75,32 +63,29 @@ class AudioMixerImpl : public AudioMixer { bool use_limiter); private: - // Set mixing frequency through OutputFrequencyCalculator. - void CalculateOutputFrequency(); - // Get mixing frequency. - int OutputFrequency() const; + struct HelperContainers; // Compute what audio sources to mix from audio_source_list_. Ramp // in and out. Update mixed status. Mixes up to // kMaximumAmountOfMixedAudioSources audio sources. - AudioFrameList GetAudioFromSources() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + rtc::ArrayView GetAudioFromSources(int output_frequency) + RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); // The critical section lock guards audio source insertion and // removal, which can be done from any thread. The race checker // checks that mixing is done sequentially. mutable Mutex mutex_; - rtc::RaceChecker race_checker_; std::unique_ptr output_rate_calculator_; - // The current sample frequency and sample size when mixing. - int output_frequency_ RTC_GUARDED_BY(race_checker_); - size_t sample_size_ RTC_GUARDED_BY(race_checker_); - // List of all audio sources. Note all lists are disjunct - SourceStatusList audio_source_list_ RTC_GUARDED_BY(mutex_); // May be mixed. + // List of all audio sources. + std::vector> audio_source_list_ + RTC_GUARDED_BY(mutex_); + const std::unique_ptr helper_containers_ + RTC_GUARDED_BY(mutex_); // Component that handles actual adding of audio frames. - FrameCombiner frame_combiner_ RTC_GUARDED_BY(race_checker_); + FrameCombiner frame_combiner_; RTC_DISALLOW_COPY_AND_ASSIGN(AudioMixerImpl); }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/default_output_rate_calculator.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/default_output_rate_calculator.cc index 57d88b638..5f24b653a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/default_output_rate_calculator.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/default_output_rate_calculator.cc @@ -18,14 +18,14 @@ namespace webrtc { -int DefaultOutputRateCalculator::CalculateOutputRate( - const std::vector& preferred_sample_rates) { +int DefaultOutputRateCalculator::CalculateOutputRateFromRange( + rtc::ArrayView preferred_sample_rates) { if (preferred_sample_rates.empty()) { return DefaultOutputRateCalculator::kDefaultFrequency; } using NativeRate = AudioProcessing::NativeRate; const int maximal_frequency = *std::max_element( - preferred_sample_rates.begin(), preferred_sample_rates.end()); + preferred_sample_rates.cbegin(), preferred_sample_rates.cend()); RTC_DCHECK_LE(NativeRate::kSampleRate8kHz, maximal_frequency); RTC_DCHECK_GE(NativeRate::kSampleRate48kHz, maximal_frequency); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/default_output_rate_calculator.h b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/default_output_rate_calculator.h index 2d34f3489..a7aaf681a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/default_output_rate_calculator.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/default_output_rate_calculator.h @@ -13,6 +13,7 @@ #include +#include "api/array_view.h" #include "modules/audio_mixer/output_rate_calculator.h" namespace webrtc { @@ -25,8 +26,8 @@ class DefaultOutputRateCalculator : public OutputRateCalculator { // sample rates. A native rate is one in // AudioProcessing::NativeRate. If |preferred_sample_rates| is // empty, returns |kDefaultFrequency|. - int CalculateOutputRate( - const std::vector& preferred_sample_rates) override; + int CalculateOutputRateFromRange( + rtc::ArrayView preferred_sample_rates) override; ~DefaultOutputRateCalculator() override {} }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/frame_combiner.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/frame_combiner.cc index f7c6a0c32..e184506b4 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/frame_combiner.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/frame_combiner.cc @@ -35,7 +35,7 @@ using MixingBuffer = std::array, FrameCombiner::kMaximumNumberOfChannels>; -void SetAudioFrameFields(const std::vector& mix_list, +void SetAudioFrameFields(rtc::ArrayView mix_list, size_t number_of_channels, int sample_rate, size_t number_of_streams, @@ -61,7 +61,7 @@ void SetAudioFrameFields(const std::vector& mix_list, } } -void MixFewFramesWithNoLimiter(const std::vector& mix_list, +void MixFewFramesWithNoLimiter(rtc::ArrayView mix_list, AudioFrame* audio_frame_for_mixing) { if (mix_list.empty()) { audio_frame_for_mixing->Mute(); @@ -74,7 +74,7 @@ void MixFewFramesWithNoLimiter(const std::vector& mix_list, audio_frame_for_mixing->mutable_data()); } -void MixToFloatFrame(const std::vector& mix_list, +void MixToFloatFrame(rtc::ArrayView mix_list, size_t samples_per_channel, size_t number_of_channels, MixingBuffer* mixing_buffer) { @@ -140,7 +140,7 @@ FrameCombiner::FrameCombiner(bool use_limiter) FrameCombiner::~FrameCombiner() = default; -void FrameCombiner::Combine(const std::vector& mix_list, +void FrameCombiner::Combine(rtc::ArrayView mix_list, size_t number_of_channels, int sample_rate, size_t number_of_streams, @@ -195,9 +195,10 @@ void FrameCombiner::Combine(const std::vector& mix_list, InterleaveToAudioFrame(mixing_buffer_view, audio_frame_for_mixing); } -void FrameCombiner::LogMixingStats(const std::vector& mix_list, - int sample_rate, - size_t number_of_streams) const { +void FrameCombiner::LogMixingStats( + rtc::ArrayView mix_list, + int sample_rate, + size_t number_of_streams) const { // Log every second. uma_logging_counter_++; if (uma_logging_counter_ > 1000 / AudioMixerImpl::kFrameDurationInMs) { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/frame_combiner.h b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/frame_combiner.h index d989d02c3..9ddf81e41 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/frame_combiner.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/frame_combiner.h @@ -14,6 +14,7 @@ #include #include +#include "api/array_view.h" #include "api/audio/audio_frame.h" #include "modules/audio_processing/agc2/limiter.h" @@ -32,7 +33,7 @@ class FrameCombiner { // because 'mix_list' can be empty. The parameter // 'number_of_streams' is used for determining whether to pass the // data through a limiter. - void Combine(const std::vector& mix_list, + void Combine(rtc::ArrayView mix_list, size_t number_of_channels, int sample_rate, size_t number_of_streams, @@ -46,7 +47,7 @@ class FrameCombiner { kMaximumNumberOfChannels>; private: - void LogMixingStats(const std::vector& mix_list, + void LogMixingStats(rtc::ArrayView mix_list, int sample_rate, size_t number_of_streams) const; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/output_rate_calculator.h b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/output_rate_calculator.h index cb3ca96b2..46b65a8b5 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/output_rate_calculator.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_mixer/output_rate_calculator.h @@ -13,14 +13,17 @@ #include +#include "api/array_view.h" + namespace webrtc { // Decides the sample rate of a mixing iteration given the preferred // sample rates of the sources. class OutputRateCalculator { public: - virtual int CalculateOutputRate( - const std::vector& preferred_sample_rates) = 0; + virtual int CalculateOutputRateFromRange( + rtc::ArrayView preferred_sample_rates) = 0; + virtual ~OutputRateCalculator() {} }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter.h index 2f6485340..759770946 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter.h @@ -42,6 +42,11 @@ void ComputeFrequencyResponse_Sse2( size_t num_partitions, const std::vector>& H, std::vector>* H2); + +void ComputeFrequencyResponse_Avx2( + size_t num_partitions, + const std::vector>& H, + std::vector>* H2); #endif // Adapts the filter partitions. @@ -60,6 +65,11 @@ void AdaptPartitions_Sse2(const RenderBuffer& render_buffer, const FftData& G, size_t num_partitions, std::vector>* H); + +void AdaptPartitions_Avx2(const RenderBuffer& render_buffer, + const FftData& G, + size_t num_partitions, + std::vector>* H); #endif // Produces the filter output. @@ -78,6 +88,11 @@ void ApplyFilter_Sse2(const RenderBuffer& render_buffer, size_t num_partitions, const std::vector>& H, FftData* S); + +void ApplyFilter_Avx2(const RenderBuffer& render_buffer, + size_t num_partitions, + const std::vector>& H, + FftData* S); #endif } // namespace aec3 diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc new file mode 100644 index 000000000..245b45ac3 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2020 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/audio_processing/aec3/adaptive_fir_filter.h" + +#include + +#include "rtc_base/checks.h" + +namespace webrtc { + +namespace aec3 { + +// Computes and stores the frequency response of the filter. +void ComputeFrequencyResponse_Avx2( + size_t num_partitions, + const std::vector>& H, + std::vector>* H2) { + for (auto& H2_ch : *H2) { + H2_ch.fill(0.f); + } + + const size_t num_render_channels = H[0].size(); + RTC_DCHECK_EQ(H.size(), H2->capacity()); + for (size_t p = 0; p < num_partitions; ++p) { + RTC_DCHECK_EQ(kFftLengthBy2Plus1, (*H2)[p].size()); + for (size_t ch = 0; ch < num_render_channels; ++ch) { + for (size_t j = 0; j < kFftLengthBy2; j += 8) { + __m256 re = _mm256_loadu_ps(&H[p][ch].re[j]); + __m256 re2 = _mm256_mul_ps(re, re); + __m256 im = _mm256_loadu_ps(&H[p][ch].im[j]); + re2 = _mm256_fmadd_ps(im, im, re2); + __m256 H2_k_j = _mm256_loadu_ps(&(*H2)[p][j]); + H2_k_j = _mm256_max_ps(H2_k_j, re2); + _mm256_storeu_ps(&(*H2)[p][j], H2_k_j); + } + float H2_new = H[p][ch].re[kFftLengthBy2] * H[p][ch].re[kFftLengthBy2] + + H[p][ch].im[kFftLengthBy2] * H[p][ch].im[kFftLengthBy2]; + (*H2)[p][kFftLengthBy2] = std::max((*H2)[p][kFftLengthBy2], H2_new); + } + } +} + +// Adapts the filter partitions. +void AdaptPartitions_Avx2(const RenderBuffer& render_buffer, + const FftData& G, + size_t num_partitions, + std::vector>* H) { + rtc::ArrayView> render_buffer_data = + render_buffer.GetFftBuffer(); + const size_t num_render_channels = render_buffer_data[0].size(); + const size_t lim1 = std::min( + render_buffer_data.size() - render_buffer.Position(), num_partitions); + const size_t lim2 = num_partitions; + constexpr size_t kNumEightBinBands = kFftLengthBy2 / 8; + + size_t X_partition = render_buffer.Position(); + size_t limit = lim1; + size_t p = 0; + do { + for (; p < limit; ++p, ++X_partition) { + for (size_t ch = 0; ch < num_render_channels; ++ch) { + FftData& H_p_ch = (*H)[p][ch]; + const FftData& X = render_buffer_data[X_partition][ch]; + + for (size_t k = 0, n = 0; n < kNumEightBinBands; ++n, k += 8) { + const __m256 G_re = _mm256_loadu_ps(&G.re[k]); + const __m256 G_im = _mm256_loadu_ps(&G.im[k]); + const __m256 X_re = _mm256_loadu_ps(&X.re[k]); + const __m256 X_im = _mm256_loadu_ps(&X.im[k]); + const __m256 H_re = _mm256_loadu_ps(&H_p_ch.re[k]); + const __m256 H_im = _mm256_loadu_ps(&H_p_ch.im[k]); + const __m256 a = _mm256_mul_ps(X_re, G_re); + const __m256 b = _mm256_mul_ps(X_im, G_im); + const __m256 c = _mm256_mul_ps(X_re, G_im); + const __m256 d = _mm256_mul_ps(X_im, G_re); + const __m256 e = _mm256_add_ps(a, b); + const __m256 f = _mm256_sub_ps(c, d); + const __m256 g = _mm256_add_ps(H_re, e); + const __m256 h = _mm256_add_ps(H_im, f); + _mm256_storeu_ps(&H_p_ch.re[k], g); + _mm256_storeu_ps(&H_p_ch.im[k], h); + } + } + } + X_partition = 0; + limit = lim2; + } while (p < lim2); + + X_partition = render_buffer.Position(); + limit = lim1; + p = 0; + do { + for (; p < limit; ++p, ++X_partition) { + for (size_t ch = 0; ch < num_render_channels; ++ch) { + FftData& H_p_ch = (*H)[p][ch]; + const FftData& X = render_buffer_data[X_partition][ch]; + + H_p_ch.re[kFftLengthBy2] += X.re[kFftLengthBy2] * G.re[kFftLengthBy2] + + X.im[kFftLengthBy2] * G.im[kFftLengthBy2]; + H_p_ch.im[kFftLengthBy2] += X.re[kFftLengthBy2] * G.im[kFftLengthBy2] - + X.im[kFftLengthBy2] * G.re[kFftLengthBy2]; + } + } + + X_partition = 0; + limit = lim2; + } while (p < lim2); +} + +// Produces the filter output (AVX2 variant). +void ApplyFilter_Avx2(const RenderBuffer& render_buffer, + size_t num_partitions, + const std::vector>& H, + FftData* S) { + RTC_DCHECK_GE(H.size(), H.size() - 1); + S->re.fill(0.f); + S->im.fill(0.f); + + rtc::ArrayView> render_buffer_data = + render_buffer.GetFftBuffer(); + const size_t num_render_channels = render_buffer_data[0].size(); + const size_t lim1 = std::min( + render_buffer_data.size() - render_buffer.Position(), num_partitions); + const size_t lim2 = num_partitions; + constexpr size_t kNumEightBinBands = kFftLengthBy2 / 8; + + size_t X_partition = render_buffer.Position(); + size_t p = 0; + size_t limit = lim1; + do { + for (; p < limit; ++p, ++X_partition) { + for (size_t ch = 0; ch < num_render_channels; ++ch) { + const FftData& H_p_ch = H[p][ch]; + const FftData& X = render_buffer_data[X_partition][ch]; + for (size_t k = 0, n = 0; n < kNumEightBinBands; ++n, k += 8) { + const __m256 X_re = _mm256_loadu_ps(&X.re[k]); + const __m256 X_im = _mm256_loadu_ps(&X.im[k]); + const __m256 H_re = _mm256_loadu_ps(&H_p_ch.re[k]); + const __m256 H_im = _mm256_loadu_ps(&H_p_ch.im[k]); + const __m256 S_re = _mm256_loadu_ps(&S->re[k]); + const __m256 S_im = _mm256_loadu_ps(&S->im[k]); + const __m256 a = _mm256_mul_ps(X_re, H_re); + const __m256 b = _mm256_mul_ps(X_im, H_im); + const __m256 c = _mm256_mul_ps(X_re, H_im); + const __m256 d = _mm256_mul_ps(X_im, H_re); + const __m256 e = _mm256_sub_ps(a, b); + const __m256 f = _mm256_add_ps(c, d); + const __m256 g = _mm256_add_ps(S_re, e); + const __m256 h = _mm256_add_ps(S_im, f); + _mm256_storeu_ps(&S->re[k], g); + _mm256_storeu_ps(&S->im[k], h); + } + } + } + limit = lim2; + X_partition = 0; + } while (p < lim2); + + X_partition = render_buffer.Position(); + p = 0; + limit = lim1; + do { + for (; p < limit; ++p, ++X_partition) { + for (size_t ch = 0; ch < num_render_channels; ++ch) { + const FftData& H_p_ch = H[p][ch]; + const FftData& X = render_buffer_data[X_partition][ch]; + S->re[kFftLengthBy2] += X.re[kFftLengthBy2] * H_p_ch.re[kFftLengthBy2] - + X.im[kFftLengthBy2] * H_p_ch.im[kFftLengthBy2]; + S->im[kFftLengthBy2] += X.re[kFftLengthBy2] * H_p_ch.im[kFftLengthBy2] + + X.im[kFftLengthBy2] * H_p_ch.re[kFftLengthBy2]; + } + } + limit = lim2; + X_partition = 0; + } while (p < lim2); +} + +} // namespace aec3 +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl.cc index 80378eb3c..dfe41091a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl.cc @@ -88,7 +88,6 @@ void ComputeErl(const Aec3Optimization& optimization, #endif #if defined(WEBRTC_HAS_NEON) case Aec3Optimization::kNeon: - aec3::ErlComputer_NEON(H2, erl); break; #endif diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl.h index 108d9f8e4..4ac13b1bc 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl.h @@ -36,6 +36,10 @@ void ErlComputer_NEON( void ErlComputer_SSE2( const std::vector>& H2, rtc::ArrayView erl); + +void ErlComputer_AVX2( + const std::vector>& H2, + rtc::ArrayView erl); #endif } // namespace aec3 diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl_avx2.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl_avx2.cc new file mode 100644 index 000000000..5fe7514db --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl_avx2.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 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/audio_processing/aec3/adaptive_fir_filter_erl.h" + +#include + +namespace webrtc { + +namespace aec3 { + +// Computes and stores the echo return loss estimate of the filter, which is the +// sum of the partition frequency responses. +void ErlComputer_AVX2( + const std::vector>& H2, + rtc::ArrayView erl) { + std::fill(erl.begin(), erl.end(), 0.f); + for (auto& H2_j : H2) { + for (size_t k = 0; k < kFftLengthBy2; k += 8) { + const __m256 H2_j_k = _mm256_loadu_ps(&H2_j[k]); + __m256 erl_k = _mm256_loadu_ps(&erl[k]); + erl_k = _mm256_add_ps(erl_k, H2_j_k); + _mm256_storeu_ps(&erl[k], erl_k); + } + erl[kFftLengthBy2] += H2_j[kFftLengthBy2]; + } +} + +} // namespace aec3 +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_common.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_common.cc index aeb848a57..7bd8d6267 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_common.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_common.cc @@ -20,7 +20,9 @@ namespace webrtc { Aec3Optimization DetectOptimization() { #if defined(WEBRTC_ARCH_X86_FAMILY) - if (WebRtc_GetCPUInfo(kSSE2) != 0) { + if (GetCPUInfo(kAVX2) != 0) { + return Aec3Optimization::kAvx2; + } else if (GetCPUInfo(kSSE2) != 0) { return Aec3Optimization::kSse2; } #endif diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_common.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_common.h index cdeefc704..3bfff967a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_common.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_common.h @@ -23,12 +23,12 @@ namespace webrtc { #define ALIGN16_END __attribute__((aligned(16))) #endif -enum class Aec3Optimization { kNone, kSse2, kNeon }; +enum class Aec3Optimization { kNone, kSse2, kAvx2, kNeon }; constexpr int kNumBlocksPerSecond = 250; constexpr int kMetricsReportingIntervalBlocks = 10 * kNumBlocksPerSecond; -constexpr int kMetricsComputationBlocks = 7; +constexpr int kMetricsComputationBlocks = 3; constexpr int kMetricsCollectionBlocks = kMetricsReportingIntervalBlocks - kMetricsComputationBlocks; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_fft.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_fft.cc index d1d4f7da0..8dfa18336 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_fft.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec3_fft.cc @@ -73,7 +73,7 @@ const float kSqrtHanning128[kFftLength] = { bool IsSse2Available() { #if defined(WEBRTC_ARCH_X86_FAMILY) - return WebRtc_GetCPUInfo(kSSE2) != 0; + return GetCPUInfo(kSSE2) != 0; #else return false; #endif diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec_state.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec_state.cc index e87f607a3..c7361093f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec_state.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec_state.cc @@ -27,13 +27,6 @@ namespace webrtc { namespace { -constexpr size_t kBlocksSinceConvergencedFilterInit = 10000; -constexpr size_t kBlocksSinceConsistentEstimateInit = 10000; - -bool DeactivateTransparentMode() { - return field_trial::IsEnabled("WebRTC-Aec3TransparentModeKillSwitch"); -} - bool DeactivateInitialStateResetAtEchoPathChange() { return field_trial::IsEnabled( "WebRTC-Aec3DeactivateInitialStateResetKillSwitch"); @@ -134,7 +127,6 @@ AecState::AecState(const EchoCanceller3Config& config, new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), config_(config), num_capture_channels_(num_capture_channels), - transparent_mode_activated_(!DeactivateTransparentMode()), deactivate_initial_state_reset_at_echo_path_change_( DeactivateInitialStateResetAtEchoPathChange()), full_reset_at_echo_path_change_(FullResetAtEchoPathChange()), @@ -142,7 +134,7 @@ AecState::AecState(const EchoCanceller3Config& config, SubtractorAnalyzerResetAtEchoPathChange()), initial_state_(config_), delay_state_(config_, num_capture_channels_), - transparent_state_(config_), + transparent_state_(TransparentMode::Create(config_)), filter_quality_state_(config_, num_capture_channels_), erl_estimator_(2 * kNumBlocksPerSecond), erle_estimator_(2 * kNumBlocksPerSecond, config_, num_capture_channels_), @@ -164,7 +156,9 @@ void AecState::HandleEchoPathChange( if (!deactivate_initial_state_reset_at_echo_path_change_) { initial_state_.Reset(); } - transparent_state_.Reset(); + if (transparent_state_) { + transparent_state_->Reset(); + } erle_estimator_.Reset(true); erl_estimator_.Reset(); filter_quality_state_.Reset(); @@ -203,8 +197,10 @@ void AecState::Update( // Analyze the filter outputs and filters. bool any_filter_converged; + bool any_coarse_filter_converged; bool all_filters_diverged; subtractor_output_analyzer_.Update(subtractor_output, &any_filter_converged, + &any_coarse_filter_converged, &all_filters_diverged); bool any_filter_consistent; @@ -277,13 +273,15 @@ void AecState::Update( initial_state_.Update(active_render, SaturatedCapture()); // Detect whether the transparent mode should be activated. - transparent_state_.Update(delay_state_.MinDirectPathFilterDelay(), - any_filter_consistent, any_filter_converged, - all_filters_diverged, active_render, - SaturatedCapture()); + if (transparent_state_) { + transparent_state_->Update( + delay_state_.MinDirectPathFilterDelay(), any_filter_consistent, + any_filter_converged, any_coarse_filter_converged, all_filters_diverged, + active_render, SaturatedCapture()); + } // Analyze the quality of the filter. - filter_quality_state_.Update(active_render, TransparentMode(), + filter_quality_state_.Update(active_render, TransparentModeActive(), SaturatedCapture(), external_delay, any_filter_converged); @@ -301,11 +299,12 @@ void AecState::Update( erle_estimator_.Dump(data_dumper_); reverb_model_estimator_.Dump(data_dumper_.get()); + data_dumper_->DumpRaw("aec3_active_render", active_render); data_dumper_->DumpRaw("aec3_erl", Erl()); data_dumper_->DumpRaw("aec3_erl_time_domain", ErlTimeDomain()); data_dumper_->DumpRaw("aec3_erle", Erle()[0]); data_dumper_->DumpRaw("aec3_usable_linear_estimate", UsableLinearEstimate()); - data_dumper_->DumpRaw("aec3_transparent_mode", TransparentMode()); + data_dumper_->DumpRaw("aec3_transparent_mode", TransparentModeActive()); data_dumper_->DumpRaw("aec3_filter_delay", filter_analyzer_.MinFilterDelayBlocks()); @@ -315,6 +314,8 @@ void AecState::Update( data_dumper_->DumpRaw("aec3_capture_saturation", SaturatedCapture()); data_dumper_->DumpRaw("aec3_echo_saturation", SaturatedEcho()); data_dumper_->DumpRaw("aec3_any_filter_converged", any_filter_converged); + data_dumper_->DumpRaw("aec3_any_coarse_filter_converged", + any_coarse_filter_converged); data_dumper_->DumpRaw("aec3_all_filters_diverged", all_filters_diverged); data_dumper_->DumpRaw("aec3_external_delay_avaliable", @@ -353,8 +354,9 @@ void AecState::InitialState::InitialState::Update(bool active_render, AecState::FilterDelay::FilterDelay(const EchoCanceller3Config& config, size_t num_capture_channels) - : delay_headroom_samples_(config.delay.delay_headroom_samples), - filter_delays_blocks_(num_capture_channels, 0) {} + : delay_headroom_blocks_(config.delay.delay_headroom_samples / kBlockSize), + filter_delays_blocks_(num_capture_channels, delay_headroom_blocks_), + min_filter_delay_(delay_headroom_blocks_) {} void AecState::FilterDelay::Update( rtc::ArrayView analyzer_filter_delay_estimates_blocks, @@ -372,7 +374,7 @@ void AecState::FilterDelay::Update( const bool delay_estimator_may_not_have_converged = blocks_with_proper_filter_adaptation < 2 * kNumBlocksPerSecond; if (delay_estimator_may_not_have_converged && external_delay_) { - int delay_guess = delay_headroom_samples_ / kBlockSize; + const int delay_guess = delay_headroom_blocks_; std::fill(filter_delays_blocks_.begin(), filter_delays_blocks_.end(), delay_guess); } else { @@ -387,92 +389,6 @@ void AecState::FilterDelay::Update( filter_delays_blocks_.end()); } -AecState::TransparentMode::TransparentMode(const EchoCanceller3Config& config) - : bounded_erl_(config.ep_strength.bounded_erl), - linear_and_stable_echo_path_( - config.echo_removal_control.linear_and_stable_echo_path), - active_blocks_since_sane_filter_(kBlocksSinceConsistentEstimateInit), - non_converged_sequence_size_(kBlocksSinceConvergencedFilterInit) {} - -void AecState::TransparentMode::Reset() { - non_converged_sequence_size_ = kBlocksSinceConvergencedFilterInit; - diverged_sequence_size_ = 0; - strong_not_saturated_render_blocks_ = 0; - if (linear_and_stable_echo_path_) { - recent_convergence_during_activity_ = false; - } -} - -void AecState::TransparentMode::Update(int filter_delay_blocks, - bool any_filter_consistent, - bool any_filter_converged, - bool all_filters_diverged, - bool active_render, - bool saturated_capture) { - ++capture_block_counter_; - strong_not_saturated_render_blocks_ += - active_render && !saturated_capture ? 1 : 0; - - if (any_filter_consistent && filter_delay_blocks < 5) { - sane_filter_observed_ = true; - active_blocks_since_sane_filter_ = 0; - } else if (active_render) { - ++active_blocks_since_sane_filter_; - } - - bool sane_filter_recently_seen; - if (!sane_filter_observed_) { - sane_filter_recently_seen = - capture_block_counter_ <= 5 * kNumBlocksPerSecond; - } else { - sane_filter_recently_seen = - active_blocks_since_sane_filter_ <= 30 * kNumBlocksPerSecond; - } - - if (any_filter_converged) { - recent_convergence_during_activity_ = true; - active_non_converged_sequence_size_ = 0; - non_converged_sequence_size_ = 0; - ++num_converged_blocks_; - } else { - if (++non_converged_sequence_size_ > 20 * kNumBlocksPerSecond) { - num_converged_blocks_ = 0; - } - - if (active_render && - ++active_non_converged_sequence_size_ > 60 * kNumBlocksPerSecond) { - recent_convergence_during_activity_ = false; - } - } - - if (!all_filters_diverged) { - diverged_sequence_size_ = 0; - } else if (++diverged_sequence_size_ >= 60) { - // TODO(peah): Change these lines to ensure proper triggering of usable - // filter. - non_converged_sequence_size_ = kBlocksSinceConvergencedFilterInit; - } - - if (active_non_converged_sequence_size_ > 60 * kNumBlocksPerSecond) { - finite_erl_recently_detected_ = false; - } - if (num_converged_blocks_ > 50) { - finite_erl_recently_detected_ = true; - } - - if (bounded_erl_) { - transparency_activated_ = false; - } else if (finite_erl_recently_detected_) { - transparency_activated_ = false; - } else if (sane_filter_recently_seen && recent_convergence_during_activity_) { - transparency_activated_ = false; - } else { - const bool filter_should_have_converged = - strong_not_saturated_render_blocks_ > 6 * kNumBlocksPerSecond; - transparency_activated_ = filter_should_have_converged; - } -} - AecState::FilteringQualityAnalyzer::FilteringQualityAnalyzer( const EchoCanceller3Config& config, size_t num_capture_channels) diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec_state.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec_state.h index e79e64bec..5b40e9513 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec_state.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/aec_state.h @@ -31,6 +31,7 @@ #include "modules/audio_processing/aec3/reverb_model_estimator.h" #include "modules/audio_processing/aec3/subtractor_output.h" #include "modules/audio_processing/aec3/subtractor_output_analyzer.h" +#include "modules/audio_processing/aec3/transparent_mode.h" namespace webrtc { @@ -107,8 +108,8 @@ class AecState { } // Returns whether the transparent mode is active - bool TransparentMode() const { - return transparent_mode_activated_ && transparent_state_.Active(); + bool TransparentModeActive() const { + return transparent_state_ && transparent_state_->Active(); } // Takes appropriate action at an echo path change. @@ -152,7 +153,6 @@ class AecState { std::unique_ptr data_dumper_; const EchoCanceller3Config config_; const size_t num_capture_channels_; - const bool transparent_mode_activated_; const bool deactivate_initial_state_reset_at_echo_path_change_; const bool full_reset_at_echo_path_change_; const bool subtractor_analyzer_reset_at_echo_path_change_; @@ -211,48 +211,15 @@ class AecState { size_t blocks_with_proper_filter_adaptation); private: - const int delay_headroom_samples_; + const int delay_headroom_blocks_; bool external_delay_reported_ = false; std::vector filter_delays_blocks_; - int min_filter_delay_ = 0; + int min_filter_delay_; absl::optional external_delay_; } delay_state_; - // Class for detecting and toggling the transparent mode which causes the - // suppressor to apply no suppression. - class TransparentMode { - public: - explicit TransparentMode(const EchoCanceller3Config& config); - - // Returns whether the transparent mode should be active. - bool Active() const { return transparency_activated_; } - - // Resets the state of the detector. - void Reset(); - - // Updates the detection deciscion based on new data. - void Update(int filter_delay_blocks, - bool any_filter_consistent, - bool any_filter_converged, - bool all_filters_diverged, - bool active_render, - bool saturated_capture); - - private: - const bool bounded_erl_; - const bool linear_and_stable_echo_path_; - size_t capture_block_counter_ = 0; - bool transparency_activated_ = false; - size_t active_blocks_since_sane_filter_; - bool sane_filter_observed_ = false; - bool finite_erl_recently_detected_ = false; - size_t non_converged_sequence_size_; - size_t diverged_sequence_size_ = 0; - size_t active_non_converged_sequence_size_ = 0; - size_t num_converged_blocks_ = 0; - bool recent_convergence_during_activity_ = false; - size_t strong_not_saturated_render_blocks_ = 0; - } transparent_state_; + // Classifier for toggling transparent mode when there is no echo. + std::unique_ptr transparent_state_; // Class for analyzing how well the linear filter is, and can be expected to, // perform on the current signals. The purpose of this is for using to @@ -316,7 +283,6 @@ class AecState { size_t blocks_with_active_render_ = 0; bool capture_signal_saturation_ = false; FilterAnalyzer filter_analyzer_; - absl::optional external_delay_; EchoAudibility echo_audibility_; ReverbModelEstimator reverb_model_estimator_; ReverbModel avg_render_reverb_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_canceller3.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_canceller3.cc index a0e1fc22a..98da232bb 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_canceller3.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_canceller3.cc @@ -213,6 +213,12 @@ void CopyBufferIntoFrame(const AudioBuffer& buffer, EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) { EchoCanceller3Config adjusted_cfg = config; + if (field_trial::IsEnabled("WebRTC-Aec3AntiHowlingMinimizationKillSwitch")) { + adjusted_cfg.suppressor.high_bands_suppression + .anti_howling_activation_threshold = 25.f; + adjusted_cfg.suppressor.high_bands_suppression.anti_howling_gain = 0.01f; + } + if (field_trial::IsEnabled("WebRTC-Aec3UseShortConfigChangeDuration")) { adjusted_cfg.filter.config_change_duration_blocks = 10; } @@ -362,6 +368,10 @@ EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) { adjusted_cfg.suppressor.nearend_tuning.max_dec_factor_lf = .2f; } + if (field_trial::IsEnabled("WebRTC-Aec3EnforceConservativeHfSuppression")) { + adjusted_cfg.suppressor.conservative_hf_suppression = true; + } + if (field_trial::IsEnabled("WebRTC-Aec3EnforceStationarityProperties")) { adjusted_cfg.echo_audibility.use_stationarity_properties = true; } @@ -378,6 +388,10 @@ EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) { adjusted_cfg.render_levels.active_render_limit = 30.f; } + if (field_trial::IsEnabled("WebRTC-Aec3NonlinearModeReverbKillSwitch")) { + adjusted_cfg.echo_model.model_reverb_in_nonlinear_mode = false; + } + // Field-trial based override for the whole suppressor tuning. const std::string suppressor_tuning_override_trial_name = field_trial::FindFullName("WebRTC-Aec3SuppressorTuningOverride"); @@ -564,6 +578,11 @@ class EchoCanceller3::RenderWriter { Aec3RenderQueueItemVerifier>* render_transfer_queue, size_t num_bands, size_t num_channels); + + RenderWriter() = delete; + RenderWriter(const RenderWriter&) = delete; + RenderWriter& operator=(const RenderWriter&) = delete; + ~RenderWriter(); void Insert(const AudioBuffer& input); @@ -575,7 +594,6 @@ class EchoCanceller3::RenderWriter { std::vector>> render_queue_input_frame_; SwapQueue>>, Aec3RenderQueueItemVerifier>* render_transfer_queue_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderWriter); }; EchoCanceller3::RenderWriter::RenderWriter( diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_path_variability.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_path_variability.h index adf0d7a4a..78e4f64b2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_path_variability.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_path_variability.h @@ -16,9 +16,7 @@ namespace webrtc { struct EchoPathVariability { enum class DelayAdjustment { kNone, - kBufferReadjustment, kBufferFlush, - kDelayReset, kNewDetectedDelay }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover.cc index a3cd22f21..df539bfad 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover.cc @@ -414,12 +414,16 @@ void EchoRemoverImpl::ProcessCapture( const auto& echo_spectrum = aec_state_.UsableLinearEstimate() ? S2_linear : R2; + // Determine if the suppressor should assume clock drift. + const bool clock_drift = config_.echo_removal_control.has_clock_drift || + echo_path_variability.clock_drift; + // Compute preferred gains. float high_bands_gain; std::array G; suppression_gain_.GetGain(nearend_spectrum, echo_spectrum, R2, cng_.NoiseSpectrum(), render_signal_analyzer_, - aec_state_, x, &high_bands_gain, &G); + aec_state_, x, clock_drift, &high_bands_gain, &G); suppression_filter_.ApplyGain(comfort_noise, high_band_comfort_noise, G, high_bands_gain, Y_fft, y); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover_metrics.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover_metrics.cc index 4502f31cc..1ceb329d3 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover_metrics.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover_metrics.cc @@ -23,12 +23,6 @@ namespace webrtc { -namespace { - -constexpr float kOneByMetricsCollectionBlocks = 1.f / kMetricsCollectionBlocks; - -} // namespace - EchoRemoverMetrics::DbMetric::DbMetric() : DbMetric(0.f, 0.f, 0.f) {} EchoRemoverMetrics::DbMetric::DbMetric(float sum_value, float floor_value, @@ -52,11 +46,8 @@ EchoRemoverMetrics::EchoRemoverMetrics() { } void EchoRemoverMetrics::ResetMetrics() { - erl_.fill(DbMetric(0.f, 10000.f, 0.000f)); erl_time_domain_ = DbMetric(0.f, 10000.f, 0.000f); - erle_.fill(DbMetric(0.f, 0.f, 1000.f)); erle_time_domain_ = DbMetric(0.f, 0.f, 1000.f); - active_render_count_ = 0; saturated_capture_ = false; } @@ -66,104 +57,24 @@ void EchoRemoverMetrics::Update( const std::array& suppressor_gain) { metrics_reported_ = false; if (++block_counter_ <= kMetricsCollectionBlocks) { - aec3::UpdateDbMetric(aec_state.Erl(), &erl_); erl_time_domain_.UpdateInstant(aec_state.ErlTimeDomain()); - aec3::UpdateDbMetric(aec_state.Erle()[0], &erle_); erle_time_domain_.UpdateInstant(aec_state.FullBandErleLog2()); - active_render_count_ += (aec_state.ActiveRender() ? 1 : 0); saturated_capture_ = saturated_capture_ || aec_state.SaturatedCapture(); } else { // Report the metrics over several frames in order to lower the impact of // the logarithms involved on the computational complexity. - constexpr int kMetricsCollectionBlocksBy2 = kMetricsCollectionBlocks / 2; switch (block_counter_) { case kMetricsCollectionBlocks + 1: - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErleBand0.Average", - aec3::TransformDbMetricForReporting(true, 0.f, 19.f, 0.f, - kOneByMetricsCollectionBlocks, - erle_[0].sum_value), - 0, 19, 20); - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErleBand0.Max", - aec3::TransformDbMetricForReporting(true, 0.f, 19.f, 0.f, 1.f, - erle_[0].ceil_value), - 0, 19, 20); - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErleBand0.Min", - aec3::TransformDbMetricForReporting(true, 0.f, 19.f, 0.f, 1.f, - erle_[0].floor_value), - 0, 19, 20); - break; - case kMetricsCollectionBlocks + 2: - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErleBand1.Average", - aec3::TransformDbMetricForReporting(true, 0.f, 19.f, 0.f, - kOneByMetricsCollectionBlocks, - erle_[1].sum_value), - 0, 19, 20); - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErleBand1.Max", - aec3::TransformDbMetricForReporting(true, 0.f, 19.f, 0.f, 1.f, - erle_[1].ceil_value), - 0, 19, 20); - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErleBand1.Min", - aec3::TransformDbMetricForReporting(true, 0.f, 19.f, 0.f, 1.f, - erle_[1].floor_value), - 0, 19, 20); - break; - case kMetricsCollectionBlocks + 3: - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErlBand0.Average", - aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, - kOneByMetricsCollectionBlocks, - erl_[0].sum_value), - 0, 59, 30); - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErlBand0.Max", - aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, 1.f, - erl_[0].ceil_value), - 0, 59, 30); - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErlBand0.Min", - aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, 1.f, - erl_[0].floor_value), - 0, 59, 30); - break; - case kMetricsCollectionBlocks + 4: - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErlBand1.Average", - aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, - kOneByMetricsCollectionBlocks, - erl_[1].sum_value), - 0, 59, 30); - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErlBand1.Max", - aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, 1.f, - erl_[1].ceil_value), - 0, 59, 30); - RTC_HISTOGRAM_COUNTS_LINEAR( - "WebRTC.Audio.EchoCanceller.ErlBand1.Min", - aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, 1.f, - erl_[1].floor_value), - 0, 59, 30); - break; - case kMetricsCollectionBlocks + 5: RTC_HISTOGRAM_BOOLEAN( "WebRTC.Audio.EchoCanceller.UsableLinearEstimate", static_cast(aec_state.UsableLinearEstimate() ? 1 : 0)); - RTC_HISTOGRAM_BOOLEAN( - "WebRTC.Audio.EchoCanceller.ActiveRender", - static_cast( - active_render_count_ > kMetricsCollectionBlocksBy2 ? 1 : 0)); RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.FilterDelay", aec_state.MinDirectPathFilterDelay(), 0, 30, 31); RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.EchoCanceller.CaptureSaturation", static_cast(saturated_capture_ ? 1 : 0)); break; - case kMetricsCollectionBlocks + 6: + case kMetricsCollectionBlocks + 2: RTC_HISTOGRAM_COUNTS_LINEAR( "WebRTC.Audio.EchoCanceller.Erl.Value", aec3::TransformDbMetricForReporting(true, 0.f, 59.f, 30.f, 1.f, @@ -180,7 +91,7 @@ void EchoRemoverMetrics::Update( erl_time_domain_.floor_value), 0, 59, 30); break; - case kMetricsCollectionBlocks + 7: + case kMetricsCollectionBlocks + 3: RTC_HISTOGRAM_COUNTS_LINEAR( "WebRTC.Audio.EchoCanceller.Erle.Value", aec3::TransformDbMetricForReporting(false, 0.f, 19.f, 0.f, 1.f, diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover_metrics.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover_metrics.h index 77fd8cd7d..c3d8e20da 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover_metrics.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/echo_remover_metrics.h @@ -48,11 +48,8 @@ class EchoRemoverMetrics { void ResetMetrics(); int block_counter_ = 0; - std::array erl_; DbMetric erl_time_domain_; - std::array erle_; DbMetric erle_time_domain_; - int active_render_count_ = 0; bool saturated_capture_ = false; bool metrics_reported_ = false; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/fft_data.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/fft_data.h index 5e5adb62d..abef1fbd1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/fft_data.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/fft_data.h @@ -40,6 +40,9 @@ struct FftData { im.fill(0.f); } + // Computes the power spectrum of the data. + void SpectrumAVX2(rtc::ArrayView power_spectrum) const; + // Computes the power spectrum of the data. void Spectrum(Aec3Optimization optimization, rtc::ArrayView power_spectrum) const { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/fft_data_avx2.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/fft_data_avx2.cc new file mode 100644 index 000000000..1fe4bd69c --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/fft_data_avx2.cc @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020 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/audio_processing/aec3/fft_data.h" + +#include + +#include "api/array_view.h" + +namespace webrtc { + +// Computes the power spectrum of the data. +void FftData::SpectrumAVX2(rtc::ArrayView power_spectrum) const { + RTC_DCHECK_EQ(kFftLengthBy2Plus1, power_spectrum.size()); + for (size_t k = 0; k < kFftLengthBy2; k += 8) { + __m256 r = _mm256_loadu_ps(&re[k]); + __m256 i = _mm256_loadu_ps(&im[k]); + __m256 ii = _mm256_mul_ps(i, i); + ii = _mm256_fmadd_ps(r, r, ii); + _mm256_storeu_ps(&power_spectrum[k], ii); + } + power_spectrum[kFftLengthBy2] = re[kFftLengthBy2] * re[kFftLengthBy2] + + im[kFftLengthBy2] * im[kFftLengthBy2]; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/filter_analyzer.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/filter_analyzer.cc index 696a57c18..be954d3a1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/filter_analyzer.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/filter_analyzer.cc @@ -69,9 +69,7 @@ void FilterAnalyzer::Reset() { blocks_since_reset_ = 0; ResetRegion(); for (auto& state : filter_analysis_states_) { - state.peak_index = 0; - state.gain = default_gain_; - state.consistent_filter_detector.Reset(); + state.Reset(default_gain_); } std::fill(filter_delays_blocks_.begin(), filter_delays_blocks_.end(), 0); } @@ -204,7 +202,9 @@ FilterAnalyzer::ConsistentFilterDetector::ConsistentFilterDetector( const EchoCanceller3Config& config) : active_render_threshold_(config.render_levels.active_render_limit * config.render_levels.active_render_limit * - kFftLengthBy2) {} + kFftLengthBy2) { + Reset(); +} void FilterAnalyzer::ConsistentFilterDetector::Reset() { significant_peak_ = false; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/filter_analyzer.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/filter_analyzer.h index 0be2a7bc3..b0b707011 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/filter_analyzer.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/filter_analyzer.h @@ -112,7 +112,16 @@ class FilterAnalyzer { struct FilterAnalysisState { explicit FilterAnalysisState(const EchoCanceller3Config& config) : filter_length_blocks(config.filter.refined_initial.length_blocks), - consistent_filter_detector(config) {} + consistent_filter_detector(config) { + Reset(config.ep_strength.default_gain); + } + + void Reset(float default_gain) { + peak_index = 0; + gain = default_gain; + consistent_filter_detector.Reset(); + } + float gain; size_t peak_index; int filter_length_blocks; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter.h index df9245322..fa44eb27f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter.h @@ -17,7 +17,6 @@ #include "api/array_view.h" #include "modules/audio_processing/aec3/aec3_common.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/system/arch.h" namespace webrtc { @@ -53,6 +52,16 @@ void MatchedFilterCore_SSE2(size_t x_start_index, bool* filters_updated, float* error_sum); +// Filter core for the matched filter that is optimized for AVX2. +void MatchedFilterCore_AVX2(size_t x_start_index, + float x2_sum_threshold, + float smoothing, + rtc::ArrayView x, + rtc::ArrayView y, + rtc::ArrayView h, + bool* filters_updated, + float* error_sum); + #endif // Filter core for the matched filter. @@ -94,6 +103,10 @@ class MatchedFilter { float smoothing, float matching_filter_threshold); + MatchedFilter() = delete; + MatchedFilter(const MatchedFilter&) = delete; + MatchedFilter& operator=(const MatchedFilter&) = delete; + ~MatchedFilter(); // Updates the correlation with the values in the capture buffer. @@ -129,8 +142,6 @@ class MatchedFilter { const float excitation_limit_; const float smoothing_; const float matching_filter_threshold_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MatchedFilter); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter_avx2.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter_avx2.cc new file mode 100644 index 000000000..ed32102aa --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter_avx2.cc @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2020 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/audio_processing/aec3/matched_filter.h" + +#include + +#include "rtc_base/checks.h" + +namespace webrtc { +namespace aec3 { + +void MatchedFilterCore_AVX2(size_t x_start_index, + float x2_sum_threshold, + float smoothing, + rtc::ArrayView x, + rtc::ArrayView y, + rtc::ArrayView h, + bool* filters_updated, + float* error_sum) { + const int h_size = static_cast(h.size()); + const int x_size = static_cast(x.size()); + RTC_DCHECK_EQ(0, h_size % 8); + + // Process for all samples in the sub-block. + for (size_t i = 0; i < y.size(); ++i) { + // Apply the matched filter as filter * x, and compute x * x. + + RTC_DCHECK_GT(x_size, x_start_index); + const float* x_p = &x[x_start_index]; + const float* h_p = &h[0]; + + // Initialize values for the accumulation. + __m256 s_256 = _mm256_set1_ps(0); + __m256 x2_sum_256 = _mm256_set1_ps(0); + float x2_sum = 0.f; + float s = 0; + + // Compute loop chunk sizes until, and after, the wraparound of the circular + // buffer for x. + const int chunk1 = + std::min(h_size, static_cast(x_size - x_start_index)); + + // Perform the loop in two chunks. + const int chunk2 = h_size - chunk1; + for (int limit : {chunk1, chunk2}) { + // Perform 256 bit vector operations. + const int limit_by_8 = limit >> 3; + for (int k = limit_by_8; k > 0; --k, h_p += 8, x_p += 8) { + // Load the data into 256 bit vectors. + __m256 x_k = _mm256_loadu_ps(x_p); + __m256 h_k = _mm256_loadu_ps(h_p); + // Compute and accumulate x * x and h * x. + x2_sum_256 = _mm256_fmadd_ps(x_k, x_k, x2_sum_256); + s_256 = _mm256_fmadd_ps(h_k, x_k, s_256); + } + + // Perform non-vector operations for any remaining items. + for (int k = limit - limit_by_8 * 8; k > 0; --k, ++h_p, ++x_p) { + const float x_k = *x_p; + x2_sum += x_k * x_k; + s += *h_p * x_k; + } + + x_p = &x[0]; + } + + // Sum components together. + __m128 x2_sum_128 = _mm_add_ps(_mm256_extractf128_ps(x2_sum_256, 0), + _mm256_extractf128_ps(x2_sum_256, 1)); + __m128 s_128 = _mm_add_ps(_mm256_extractf128_ps(s_256, 0), + _mm256_extractf128_ps(s_256, 1)); + // Combine the accumulated vector and scalar values. + float* v = reinterpret_cast(&x2_sum_128); + x2_sum += v[0] + v[1] + v[2] + v[3]; + v = reinterpret_cast(&s_128); + s += v[0] + v[1] + v[2] + v[3]; + + // Compute the matched filter error. + float e = y[i] - s; + const bool saturation = y[i] >= 32000.f || y[i] <= -32000.f; + (*error_sum) += e * e; + + // Update the matched filter estimate in an NLMS manner. + if (x2_sum > x2_sum_threshold && !saturation) { + RTC_DCHECK_LT(0.f, x2_sum); + const float alpha = smoothing * e / x2_sum; + const __m256 alpha_256 = _mm256_set1_ps(alpha); + + // filter = filter + smoothing * (y - filter * x) * x / x * x. + float* h_p = &h[0]; + x_p = &x[x_start_index]; + + // Perform the loop in two chunks. + for (int limit : {chunk1, chunk2}) { + // Perform 256 bit vector operations. + const int limit_by_8 = limit >> 3; + for (int k = limit_by_8; k > 0; --k, h_p += 8, x_p += 8) { + // Load the data into 256 bit vectors. + __m256 h_k = _mm256_loadu_ps(h_p); + __m256 x_k = _mm256_loadu_ps(x_p); + // Compute h = h + alpha * x. + h_k = _mm256_fmadd_ps(x_k, alpha_256, h_k); + + // Store the result. + _mm256_storeu_ps(h_p, h_k); + } + + // Perform non-vector operations for any remaining items. + for (int k = limit - limit_by_8 * 8; k > 0; --k, ++h_p, ++x_p) { + *h_p += alpha * *x_p; + } + + x_p = &x[0]; + } + + *filters_updated = true; + } + + x_start_index = x_start_index > 0 ? x_start_index - 1 : x_size - 1; + } +} + +} // namespace aec3 +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter_lag_aggregator.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter_lag_aggregator.h index 0cc7789d1..d48011e47 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter_lag_aggregator.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/matched_filter_lag_aggregator.h @@ -17,7 +17,6 @@ #include "api/audio/echo_canceller3_config.h" #include "modules/audio_processing/aec3/delay_estimate.h" #include "modules/audio_processing/aec3/matched_filter.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -31,6 +30,12 @@ class MatchedFilterLagAggregator { ApmDataDumper* data_dumper, size_t max_filter_lag, const EchoCanceller3Config::Delay::DelaySelectionThresholds& thresholds); + + MatchedFilterLagAggregator() = delete; + MatchedFilterLagAggregator(const MatchedFilterLagAggregator&) = delete; + MatchedFilterLagAggregator& operator=(const MatchedFilterLagAggregator&) = + delete; + ~MatchedFilterLagAggregator(); // Resets the aggregator. @@ -47,8 +52,6 @@ class MatchedFilterLagAggregator { int histogram_data_index_ = 0; bool significant_candidate_found_ = false; const EchoCanceller3Config::Delay::DelaySelectionThresholds thresholds_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MatchedFilterLagAggregator); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_buffer.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_buffer.h index 3422df35e..b8be6f517 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_buffer.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_buffer.h @@ -23,7 +23,6 @@ #include "modules/audio_processing/aec3/fft_data.h" #include "modules/audio_processing/aec3/spectrum_buffer.h" #include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -33,6 +32,11 @@ class RenderBuffer { RenderBuffer(BlockBuffer* block_buffer, SpectrumBuffer* spectrum_buffer, FftBuffer* fft_buffer); + + RenderBuffer() = delete; + RenderBuffer(const RenderBuffer&) = delete; + RenderBuffer& operator=(const RenderBuffer&) = delete; + ~RenderBuffer(); // Get a block. @@ -105,7 +109,6 @@ class RenderBuffer { const SpectrumBuffer* const spectrum_buffer_; const FftBuffer* const fft_buffer_; bool render_activity_ = false; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderBuffer); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc index f5030e17b..7bebc6fd4 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc @@ -385,9 +385,11 @@ void RenderDelayBufferImpl::ApplyTotalDelay(int delay) { void RenderDelayBufferImpl::AlignFromExternalDelay() { RTC_DCHECK(config_.delay.use_external_delay_estimator); if (external_audio_buffer_delay_) { - int64_t delay = render_call_counter_ - capture_call_counter_ + - *external_audio_buffer_delay_; - ApplyTotalDelay(delay); + const int64_t delay = render_call_counter_ - capture_call_counter_ + + *external_audio_buffer_delay_; + const int64_t delay_with_headroom = + delay - config_.delay.delay_headroom_samples / kBlockSize; + ApplyTotalDelay(delay_with_headroom); } } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_delay_controller.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_delay_controller.cc index c42d22bdc..3677085d8 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_delay_controller.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/render_delay_controller.cc @@ -25,7 +25,6 @@ #include "modules/audio_processing/logging/apm_data_dumper.h" #include "rtc_base/atomic_ops.h" #include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -36,6 +35,12 @@ class RenderDelayControllerImpl final : public RenderDelayController { RenderDelayControllerImpl(const EchoCanceller3Config& config, int sample_rate_hz, size_t num_capture_channels); + + RenderDelayControllerImpl() = delete; + RenderDelayControllerImpl(const RenderDelayControllerImpl&) = delete; + RenderDelayControllerImpl& operator=(const RenderDelayControllerImpl&) = + delete; + ~RenderDelayControllerImpl() override; void Reset(bool reset_delay_confidence) override; void LogRenderCall() override; @@ -57,7 +62,6 @@ class RenderDelayControllerImpl final : public RenderDelayController { size_t capture_call_counter_ = 0; int delay_change_counter_ = 0; DelayEstimate::Quality last_delay_estimate_quality_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderDelayControllerImpl); }; DelayEstimate ComputeBufferDelay( diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc index 5d31c6626..e352cf555 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/residual_echo_estimator.cc @@ -23,57 +23,23 @@ namespace webrtc { namespace { -bool UseLowEarlyReflectionsTransparentModeGain() { - return field_trial::IsEnabled( - "WebRTC-Aec3UseLowEarlyReflectionsTransparentModeGain"); -} - -bool UseLowLateReflectionsTransparentModeGain() { - return field_trial::IsEnabled( - "WebRTC-Aec3UseLowLateReflectionsTransparentModeGain"); -} - -bool UseLowEarlyReflectionsDefaultGain() { - return field_trial::IsEnabled("WebRTC-Aec3UseLowEarlyReflectionsDefaultGain"); -} - -bool UseLowLateReflectionsDefaultGain() { - return field_trial::IsEnabled("WebRTC-Aec3UseLowLateReflectionsDefaultGain"); -} - -bool ModelReverbInNonlinearMode() { - return !field_trial::IsEnabled("WebRTC-Aec3rNonlinearModeReverbKillSwitch"); -} - constexpr float kDefaultTransparentModeGain = 0.01f; -float GetEarlyReflectionsTransparentModeGain() { - if (UseLowEarlyReflectionsTransparentModeGain()) { - return 0.001f; - } - return kDefaultTransparentModeGain; -} - -float GetLateReflectionsTransparentModeGain() { - if (UseLowLateReflectionsTransparentModeGain()) { - return 0.001f; - } - +float GetTransparentModeGain() { return kDefaultTransparentModeGain; } float GetEarlyReflectionsDefaultModeGain( const EchoCanceller3Config::EpStrength& config) { - if (UseLowEarlyReflectionsDefaultGain()) { + if (field_trial::IsEnabled("WebRTC-Aec3UseLowEarlyReflectionsDefaultGain")) { return 0.1f; } - return config.default_gain; } float GetLateReflectionsDefaultModeGain( const EchoCanceller3Config::EpStrength& config) { - if (UseLowLateReflectionsDefaultGain()) { + if (field_trial::IsEnabled("WebRTC-Aec3UseLowLateReflectionsDefaultGain")) { return 0.1f; } return config.default_gain; @@ -201,15 +167,12 @@ ResidualEchoEstimator::ResidualEchoEstimator(const EchoCanceller3Config& config, size_t num_render_channels) : config_(config), num_render_channels_(num_render_channels), - early_reflections_transparent_mode_gain_( - GetEarlyReflectionsTransparentModeGain()), - late_reflections_transparent_mode_gain_( - GetLateReflectionsTransparentModeGain()), + early_reflections_transparent_mode_gain_(GetTransparentModeGain()), + late_reflections_transparent_mode_gain_(GetTransparentModeGain()), early_reflections_general_gain_( GetEarlyReflectionsDefaultModeGain(config_.ep_strength)), late_reflections_general_gain_( - GetLateReflectionsDefaultModeGain(config_.ep_strength)), - model_reverb_in_nonlinear_mode_(ModelReverbInNonlinearMode()) { + GetLateReflectionsDefaultModeGain(config_.ep_strength)) { Reset(); } @@ -277,7 +240,8 @@ void ResidualEchoEstimator::Estimate( NonLinearEstimate(echo_path_gain, X2, R2); } - if (model_reverb_in_nonlinear_mode_ && !aec_state.TransparentMode()) { + if (config_.echo_model.model_reverb_in_nonlinear_mode && + !aec_state.TransparentModeActive()) { AddReverb(ReverbType::kNonLinear, aec_state, render_buffer, R2); } } @@ -395,7 +359,7 @@ float ResidualEchoEstimator::GetEchoPathGain( const AecState& aec_state, bool gain_for_early_reflections) const { float gain_amplitude; - if (aec_state.TransparentMode()) { + if (aec_state.TransparentModeActive()) { gain_amplitude = gain_for_early_reflections ? early_reflections_transparent_mode_gain_ : late_reflections_transparent_mode_gain_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/residual_echo_estimator.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/residual_echo_estimator.h index 081cc063f..8fe7a84f0 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/residual_echo_estimator.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/residual_echo_estimator.h @@ -68,7 +68,6 @@ class ResidualEchoEstimator { const float late_reflections_transparent_mode_gain_; const float early_reflections_general_gain_; const float late_reflections_general_gain_; - const bool model_reverb_in_nonlinear_mode_; std::array X2_noise_floor_; std::array X2_noise_floor_counter_; ReverbModel echo_reverb_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.cc index 8b2218530..baf060016 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.cc @@ -22,12 +22,14 @@ SubtractorOutputAnalyzer::SubtractorOutputAnalyzer(size_t num_capture_channels) void SubtractorOutputAnalyzer::Update( rtc::ArrayView subtractor_output, bool* any_filter_converged, + bool* any_coarse_filter_converged, bool* all_filters_diverged) { RTC_DCHECK(any_filter_converged); RTC_DCHECK(all_filters_diverged); RTC_DCHECK_EQ(subtractor_output.size(), filters_converged_.size()); *any_filter_converged = false; + *any_coarse_filter_converged = false; *all_filters_diverged = true; for (size_t ch = 0; ch < subtractor_output.size(); ++ch) { @@ -36,16 +38,21 @@ void SubtractorOutputAnalyzer::Update( const float e2_coarse = subtractor_output[ch].e2_coarse; constexpr float kConvergenceThreshold = 50 * 50 * kBlockSize; + constexpr float kConvergenceThresholdLowLevel = 20 * 20 * kBlockSize; bool refined_filter_converged = e2_refined < 0.5f * y2 && y2 > kConvergenceThreshold; - bool coarse_filter_converged = + bool coarse_filter_converged_strict = e2_coarse < 0.05f * y2 && y2 > kConvergenceThreshold; + bool coarse_filter_converged_relaxed = + e2_coarse < 0.2f * y2 && y2 > kConvergenceThresholdLowLevel; float min_e2 = std::min(e2_refined, e2_coarse); bool filter_diverged = min_e2 > 1.5f * y2 && y2 > 30.f * 30.f * kBlockSize; filters_converged_[ch] = - refined_filter_converged || coarse_filter_converged; + refined_filter_converged || coarse_filter_converged_strict; *any_filter_converged = *any_filter_converged || filters_converged_[ch]; + *any_coarse_filter_converged = + *any_coarse_filter_converged || coarse_filter_converged_relaxed; *all_filters_diverged = *all_filters_diverged && filter_diverged; } } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.h index 5328ae7f1..32707dbb1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/subtractor_output_analyzer.h @@ -26,6 +26,7 @@ class SubtractorOutputAnalyzer { // Analyses the subtractor output. void Update(rtc::ArrayView subtractor_output, bool* any_filter_converged, + bool* any_coarse_filter_converged, bool* all_filters_diverged); const std::vector& ConvergedFilters() const { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/suppression_gain.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/suppression_gain.cc index c1f12b774..5b01c5290 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/suppression_gain.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/suppression_gain.cc @@ -27,39 +27,40 @@ namespace webrtc { namespace { -void PostprocessGains(std::array* gain) { - // TODO(gustaf): Investigate if this can be relaxed to achieve higher - // transparency above 2 kHz. - +void LimitLowFrequencyGains(std::array* gain) { // Limit the low frequency gains to avoid the impact of the high-pass filter // on the lower-frequency gain influencing the overall achieved gain. (*gain)[0] = (*gain)[1] = std::min((*gain)[1], (*gain)[2]); +} - // Limit the high frequency gains to avoid the impact of the anti-aliasing - // filter on the upper-frequency gains influencing the overall achieved - // gain. TODO(peah): Update this when new anti-aliasing filters are - // implemented. - constexpr size_t kAntiAliasingImpactLimit = (64 * 2000) / 8000; - const float min_upper_gain = (*gain)[kAntiAliasingImpactLimit]; +void LimitHighFrequencyGains(bool conservative_hf_suppression, + std::array* gain) { + // Limit the high frequency gains to avoid echo leakage due to an imperfect + // filter. + constexpr size_t kFirstBandToLimit = (64 * 2000) / 8000; + const float min_upper_gain = (*gain)[kFirstBandToLimit]; std::for_each( - gain->begin() + kAntiAliasingImpactLimit, gain->end() - 1, + gain->begin() + kFirstBandToLimit + 1, gain->end(), [min_upper_gain](float& a) { a = std::min(a, min_upper_gain); }); (*gain)[kFftLengthBy2] = (*gain)[kFftLengthBy2Minus1]; - // Limits the gain in the frequencies for which the adaptive filter has not - // converged. - // TODO(peah): Make adaptive to take the actual filter error into account. - constexpr size_t kUpperAccurateBandPlus1 = 29; + if (conservative_hf_suppression) { + // Limits the gain in the frequencies for which the adaptive filter has not + // converged. + // TODO(peah): Make adaptive to take the actual filter error into account. + constexpr size_t kUpperAccurateBandPlus1 = 29; - constexpr float oneByBandsInSum = - 1 / static_cast(kUpperAccurateBandPlus1 - 20); - const float hf_gain_bound = - std::accumulate(gain->begin() + 20, - gain->begin() + kUpperAccurateBandPlus1, 0.f) * - oneByBandsInSum; + constexpr float oneByBandsInSum = + 1 / static_cast(kUpperAccurateBandPlus1 - 20); + const float hf_gain_bound = + std::accumulate(gain->begin() + 20, + gain->begin() + kUpperAccurateBandPlus1, 0.f) * + oneByBandsInSum; - std::for_each(gain->begin() + kUpperAccurateBandPlus1, gain->end(), - [hf_gain_bound](float& a) { a = std::min(a, hf_gain_bound); }); + std::for_each( + gain->begin() + kUpperAccurateBandPlus1, gain->end(), + [hf_gain_bound](float& a) { a = std::min(a, hf_gain_bound); }); + } } // Scales the echo according to assessed audibility at the other end. @@ -265,6 +266,7 @@ void SuppressionGain::LowerBandGain( suppressor_input, rtc::ArrayView> residual_echo, rtc::ArrayView> comfort_noise, + bool clock_drift, std::array* gain) { gain->fill(1.f); const bool saturated_echo = aec_state.SaturatedEcho(); @@ -298,8 +300,14 @@ void SuppressionGain::LowerBandGain( last_echo_[ch].begin()); } - // Limit high-frequency gains. - PostprocessGains(gain); + LimitLowFrequencyGains(gain); + // Use conservative high-frequency gains during clock-drift or when not in + // dominant nearend. + if (!dominant_nearend_detector_->IsNearendState() || clock_drift || + config_.suppressor.conservative_hf_suppression) { + LimitHighFrequencyGains(config_.suppressor.conservative_hf_suppression, + gain); + } // Store computed gains. std::copy(gain->begin(), gain->end(), last_gain_.begin()); @@ -352,6 +360,7 @@ void SuppressionGain::GetGain( const RenderSignalAnalyzer& render_signal_analyzer, const AecState& aec_state, const std::vector>>& render, + bool clock_drift, float* high_bands_gain, std::array* low_band_gain) { RTC_DCHECK(high_bands_gain); @@ -364,7 +373,8 @@ void SuppressionGain::GetGain( // Compute gain for the lower band. bool low_noise_render = low_render_detector_.Detect(render); LowerBandGain(low_noise_render, aec_state, nearend_spectrum, - residual_echo_spectrum, comfort_noise_spectrum, low_band_gain); + residual_echo_spectrum, comfort_noise_spectrum, clock_drift, + low_band_gain); // Compute the gain for the upper bands. const absl::optional narrow_peak_band = diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/suppression_gain.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/suppression_gain.h index f46db0b7b..e7175c36d 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/suppression_gain.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/suppression_gain.h @@ -47,6 +47,7 @@ class SuppressionGain { const RenderSignalAnalyzer& render_signal_analyzer, const AecState& aec_state, const std::vector>>& render, + bool clock_drift, float* high_bands_gain, std::array* low_band_gain); @@ -76,6 +77,7 @@ class SuppressionGain { suppressor_input, rtc::ArrayView> residual_echo, rtc::ArrayView> comfort_noise, + bool clock_drift, std::array* gain); void GetMinGain(rtc::ArrayView weighted_residual_echo, diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/transparent_mode.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/transparent_mode.cc new file mode 100644 index 000000000..3ed0980bf --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/transparent_mode.cc @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2020 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/audio_processing/aec3/transparent_mode.h" + +#include "rtc_base/checks.h" +#include "system_wrappers/include/field_trial.h" + +namespace webrtc { +namespace { + +constexpr size_t kBlocksSinceConvergencedFilterInit = 10000; +constexpr size_t kBlocksSinceConsistentEstimateInit = 10000; + +bool DeactivateTransparentMode() { + return field_trial::IsEnabled("WebRTC-Aec3TransparentModeKillSwitch"); +} + +bool DeactivateTransparentModeHmm() { + return field_trial::IsEnabled("WebRTC-Aec3TransparentModeHmmKillSwitch"); +} + +} // namespace + +// Classifier that toggles transparent mode which reduces echo suppression when +// headsets are used. +class TransparentModeImpl : public TransparentMode { + public: + bool Active() const override { return transparency_activated_; } + + void Reset() override { + // Determines if transparent mode is used. + transparency_activated_ = false; + + // The estimated probability of being transparent mode. + prob_transparent_state_ = 0.f; + } + + void Update(int filter_delay_blocks, + bool any_filter_consistent, + bool any_filter_converged, + bool any_coarse_filter_converged, + bool all_filters_diverged, + bool active_render, + bool saturated_capture) override { + // The classifier is implemented as a Hidden Markov Model (HMM) with two + // hidden states: "normal" and "transparent". The estimated probabilities of + // the two states are updated by observing filter convergence during active + // render. The filters are less likely to be reported as converged when + // there is no echo present in the microphone signal. + + // The constants have been obtained by observing active_render and + // any_coarse_filter_converged under varying call scenarios. They + // have further been hand tuned to prefer normal state during uncertain + // regions (to avoid echo leaks). + + // The model is only updated during active render. + if (!active_render) + return; + + // Probability of switching from one state to the other. + constexpr float kSwitch = 0.000001f; + + // Probability of observing converged filters in states "normal" and + // "transparent" during active render. + constexpr float kConvergedNormal = 0.01f; + constexpr float kConvergedTransparent = 0.001f; + + // Probability of transitioning to transparent state from normal state and + // transparent state respectively. + constexpr float kA[2] = {kSwitch, 1.f - kSwitch}; + + // Probability of the two observations (converged filter or not converged + // filter) in normal state and transparent state respectively. + constexpr float kB[2][2] = { + {1.f - kConvergedNormal, kConvergedNormal}, + {1.f - kConvergedTransparent, kConvergedTransparent}}; + + // Probability of the two states before the update. + const float prob_transparent = prob_transparent_state_; + const float prob_normal = 1.f - prob_transparent; + + // Probability of transitioning to transparent state. + const float prob_transition_transparent = + prob_normal * kA[0] + prob_transparent * kA[1]; + const float prob_transition_normal = 1.f - prob_transition_transparent; + + // Observed output. + const int out = static_cast(any_coarse_filter_converged); + + // Joint probabilites of the observed output and respective states. + const float prob_joint_normal = prob_transition_normal * kB[0][out]; + const float prob_joint_transparent = + prob_transition_transparent * kB[1][out]; + + // Conditional probability of transparent state and the observed output. + RTC_DCHECK_GT(prob_joint_normal + prob_joint_transparent, 0.f); + prob_transparent_state_ = + prob_joint_transparent / (prob_joint_normal + prob_joint_transparent); + + // Transparent mode is only activated when its state probability is high. + // Dead zone between activation/deactivation thresholds to avoid switching + // back and forth. + if (prob_transparent_state_ > 0.95f) { + transparency_activated_ = true; + } else if (prob_transparent_state_ < 0.5f) { + transparency_activated_ = false; + } + } + + private: + bool transparency_activated_ = false; + float prob_transparent_state_ = 0.f; +}; + +// Legacy classifier for toggling transparent mode. +class LegacyTransparentModeImpl : public TransparentMode { + public: + explicit LegacyTransparentModeImpl(const EchoCanceller3Config& config) + : linear_and_stable_echo_path_( + config.echo_removal_control.linear_and_stable_echo_path), + active_blocks_since_sane_filter_(kBlocksSinceConsistentEstimateInit), + non_converged_sequence_size_(kBlocksSinceConvergencedFilterInit) {} + + bool Active() const override { return transparency_activated_; } + + void Reset() override { + non_converged_sequence_size_ = kBlocksSinceConvergencedFilterInit; + diverged_sequence_size_ = 0; + strong_not_saturated_render_blocks_ = 0; + if (linear_and_stable_echo_path_) { + recent_convergence_during_activity_ = false; + } + } + + void Update(int filter_delay_blocks, + bool any_filter_consistent, + bool any_filter_converged, + bool any_coarse_filter_converged, + bool all_filters_diverged, + bool active_render, + bool saturated_capture) override { + ++capture_block_counter_; + strong_not_saturated_render_blocks_ += + active_render && !saturated_capture ? 1 : 0; + + if (any_filter_consistent && filter_delay_blocks < 5) { + sane_filter_observed_ = true; + active_blocks_since_sane_filter_ = 0; + } else if (active_render) { + ++active_blocks_since_sane_filter_; + } + + bool sane_filter_recently_seen; + if (!sane_filter_observed_) { + sane_filter_recently_seen = + capture_block_counter_ <= 5 * kNumBlocksPerSecond; + } else { + sane_filter_recently_seen = + active_blocks_since_sane_filter_ <= 30 * kNumBlocksPerSecond; + } + + if (any_filter_converged) { + recent_convergence_during_activity_ = true; + active_non_converged_sequence_size_ = 0; + non_converged_sequence_size_ = 0; + ++num_converged_blocks_; + } else { + if (++non_converged_sequence_size_ > 20 * kNumBlocksPerSecond) { + num_converged_blocks_ = 0; + } + + if (active_render && + ++active_non_converged_sequence_size_ > 60 * kNumBlocksPerSecond) { + recent_convergence_during_activity_ = false; + } + } + + if (!all_filters_diverged) { + diverged_sequence_size_ = 0; + } else if (++diverged_sequence_size_ >= 60) { + // TODO(peah): Change these lines to ensure proper triggering of usable + // filter. + non_converged_sequence_size_ = kBlocksSinceConvergencedFilterInit; + } + + if (active_non_converged_sequence_size_ > 60 * kNumBlocksPerSecond) { + finite_erl_recently_detected_ = false; + } + if (num_converged_blocks_ > 50) { + finite_erl_recently_detected_ = true; + } + + if (finite_erl_recently_detected_) { + transparency_activated_ = false; + } else if (sane_filter_recently_seen && + recent_convergence_during_activity_) { + transparency_activated_ = false; + } else { + const bool filter_should_have_converged = + strong_not_saturated_render_blocks_ > 6 * kNumBlocksPerSecond; + transparency_activated_ = filter_should_have_converged; + } + } + + private: + const bool linear_and_stable_echo_path_; + size_t capture_block_counter_ = 0; + bool transparency_activated_ = false; + size_t active_blocks_since_sane_filter_; + bool sane_filter_observed_ = false; + bool finite_erl_recently_detected_ = false; + size_t non_converged_sequence_size_; + size_t diverged_sequence_size_ = 0; + size_t active_non_converged_sequence_size_ = 0; + size_t num_converged_blocks_ = 0; + bool recent_convergence_during_activity_ = false; + size_t strong_not_saturated_render_blocks_ = 0; +}; + +std::unique_ptr TransparentMode::Create( + const EchoCanceller3Config& config) { + if (config.ep_strength.bounded_erl || DeactivateTransparentMode()) { + return nullptr; + } + if (DeactivateTransparentModeHmm()) { + return std::make_unique(config); + } + return std::make_unique(); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/transparent_mode.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/transparent_mode.h new file mode 100644 index 000000000..bc5dd0391 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/transparent_mode.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef MODULES_AUDIO_PROCESSING_AEC3_TRANSPARENT_MODE_H_ +#define MODULES_AUDIO_PROCESSING_AEC3_TRANSPARENT_MODE_H_ + +#include + +#include "api/audio/echo_canceller3_config.h" +#include "modules/audio_processing/aec3/aec3_common.h" + +namespace webrtc { + +// Class for detecting and toggling the transparent mode which causes the +// suppressor to apply less suppression. +class TransparentMode { + public: + static std::unique_ptr Create( + const EchoCanceller3Config& config); + + virtual ~TransparentMode() {} + + // Returns whether the transparent mode should be active. + virtual bool Active() const = 0; + + // Resets the state of the detector. + virtual void Reset() = 0; + + // Updates the detection decision based on new data. + virtual void Update(int filter_delay_blocks, + bool any_filter_consistent, + bool any_filter_converged, + bool any_coarse_filter_converged, + bool all_filters_diverged, + bool active_render, + bool saturated_capture) = 0; +}; + +} // namespace webrtc +#endif // MODULES_AUDIO_PROCESSING_AEC3_TRANSPARENT_MODE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/vector_math.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/vector_math.h index 883cd95fd..8ef813341 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/vector_math.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/vector_math.h @@ -40,6 +40,7 @@ class VectorMath { : optimization_(optimization) {} // Elementwise square root. + void SqrtAVX2(rtc::ArrayView x); void Sqrt(rtc::ArrayView x) { switch (optimization_) { #if defined(WEBRTC_ARCH_X86_FAMILY) @@ -110,6 +111,9 @@ class VectorMath { } // Elementwise vector multiplication z = x * y. + void MultiplyAVX2(rtc::ArrayView x, + rtc::ArrayView y, + rtc::ArrayView z); void Multiply(rtc::ArrayView x, rtc::ArrayView y, rtc::ArrayView z) { @@ -133,6 +137,9 @@ class VectorMath { z[j] = x[j] * y[j]; } } break; + case Aec3Optimization::kAvx2: + MultiplyAVX2(x, y, z); + break; #endif #if defined(WEBRTC_HAS_NEON) case Aec3Optimization::kNeon: { @@ -159,6 +166,7 @@ class VectorMath { } // Elementwise vector accumulation z += x. + void AccumulateAVX2(rtc::ArrayView x, rtc::ArrayView z); void Accumulate(rtc::ArrayView x, rtc::ArrayView z) { RTC_DCHECK_EQ(z.size(), x.size()); switch (optimization_) { @@ -179,6 +187,9 @@ class VectorMath { z[j] += x[j]; } } break; + case Aec3Optimization::kAvx2: + AccumulateAVX2(x, z); + break; #endif #if defined(WEBRTC_HAS_NEON) case Aec3Optimization::kNeon: { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/vector_math_avx2.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/vector_math_avx2.cc new file mode 100644 index 000000000..0b5f3c142 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec3/vector_math_avx2.cc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 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/audio_processing/aec3/vector_math.h" + +#include +#include + +#include "api/array_view.h" +#include "rtc_base/checks.h" + +namespace webrtc { +namespace aec3 { + +// Elementwise square root. +void VectorMath::SqrtAVX2(rtc::ArrayView x) { + const int x_size = static_cast(x.size()); + const int vector_limit = x_size >> 3; + + int j = 0; + for (; j < vector_limit * 8; j += 8) { + __m256 g = _mm256_loadu_ps(&x[j]); + g = _mm256_sqrt_ps(g); + _mm256_storeu_ps(&x[j], g); + } + + for (; j < x_size; ++j) { + x[j] = sqrtf(x[j]); + } +} + +// Elementwise vector multiplication z = x * y. +void VectorMath::MultiplyAVX2(rtc::ArrayView x, + rtc::ArrayView y, + rtc::ArrayView z) { + RTC_DCHECK_EQ(z.size(), x.size()); + RTC_DCHECK_EQ(z.size(), y.size()); + const int x_size = static_cast(x.size()); + const int vector_limit = x_size >> 3; + + int j = 0; + for (; j < vector_limit * 8; j += 8) { + const __m256 x_j = _mm256_loadu_ps(&x[j]); + const __m256 y_j = _mm256_loadu_ps(&y[j]); + const __m256 z_j = _mm256_mul_ps(x_j, y_j); + _mm256_storeu_ps(&z[j], z_j); + } + + for (; j < x_size; ++j) { + z[j] = x[j] * y[j]; + } +} + +// Elementwise vector accumulation z += x. +void VectorMath::AccumulateAVX2(rtc::ArrayView x, + rtc::ArrayView z) { + RTC_DCHECK_EQ(z.size(), x.size()); + const int x_size = static_cast(x.size()); + const int vector_limit = x_size >> 3; + + int j = 0; + for (; j < vector_limit * 8; j += 8) { + const __m256 x_j = _mm256_loadu_ps(&x[j]); + __m256 z_j = _mm256_loadu_ps(&z[j]); + z_j = _mm256_add_ps(x_j, z_j); + _mm256_storeu_ps(&z[j], z_j); + } + + for (; j < x_size; ++j) { + z[j] += x[j]; + } +} + +} // namespace aec3 +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec_dump/aec_dump_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec_dump/aec_dump_impl.cc index 12997388f..18f85721b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec_dump/aec_dump_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/aec_dump/aec_dump_impl.cc @@ -203,6 +203,12 @@ void AecDumpImpl::WriteRuntimeSetting( setting->set_capture_fixed_post_gain(x); break; } + case AudioProcessing::RuntimeSetting::Type::kCaptureOutputUsed: { + bool x; + runtime_setting.GetBool(&x); + setting->set_capture_output_used(x); + break; + } case AudioProcessing::RuntimeSetting::Type::kPlayoutVolumeChange: { int x; runtime_setting.GetInt(&x); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_agc.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_agc.cc index a5d36089c..0372ccf38 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_agc.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_agc.cc @@ -14,12 +14,32 @@ #include "modules/audio_processing/agc2/vad_with_level.h" #include "modules/audio_processing/logging/apm_data_dumper.h" #include "rtc_base/checks.h" +#include "rtc_base/logging.h" namespace webrtc { +namespace { + +void DumpDebugData(const AdaptiveDigitalGainApplier::FrameInfo& info, + ApmDataDumper& dumper) { + dumper.DumpRaw("agc2_vad_probability", info.vad_result.speech_probability); + dumper.DumpRaw("agc2_vad_rms_dbfs", info.vad_result.rms_dbfs); + dumper.DumpRaw("agc2_vad_peak_dbfs", info.vad_result.peak_dbfs); + dumper.DumpRaw("agc2_noise_estimate_dbfs", info.input_noise_level_dbfs); + dumper.DumpRaw("agc2_last_limiter_audio_level", info.limiter_envelope_dbfs); +} + +constexpr int kGainApplierAdjacentSpeechFramesThreshold = 1; +constexpr float kMaxGainChangePerSecondDb = 3.f; +constexpr float kMaxOutputNoiseLevelDbfs = -50.f; + +} // namespace AdaptiveAgc::AdaptiveAgc(ApmDataDumper* apm_data_dumper) : speech_level_estimator_(apm_data_dumper), - gain_applier_(apm_data_dumper), + gain_applier_(apm_data_dumper, + kGainApplierAdjacentSpeechFramesThreshold, + kMaxGainChangePerSecondDb, + kMaxOutputNoiseLevelDbfs), apm_data_dumper_(apm_data_dumper), noise_level_estimator_(apm_data_dumper) { RTC_DCHECK(apm_data_dumper); @@ -30,48 +50,37 @@ AdaptiveAgc::AdaptiveAgc(ApmDataDumper* apm_data_dumper, : speech_level_estimator_( apm_data_dumper, config.adaptive_digital.level_estimator, - config.adaptive_digital.use_saturation_protector, + config.adaptive_digital + .level_estimator_adjacent_speech_frames_threshold, + config.adaptive_digital.initial_saturation_margin_db, config.adaptive_digital.extra_saturation_margin_db), - gain_applier_(apm_data_dumper), + vad_(config.adaptive_digital.vad_probability_attack), + gain_applier_( + apm_data_dumper, + config.adaptive_digital.gain_applier_adjacent_speech_frames_threshold, + config.adaptive_digital.max_gain_change_db_per_second, + config.adaptive_digital.max_output_noise_level_dbfs), apm_data_dumper_(apm_data_dumper), noise_level_estimator_(apm_data_dumper) { RTC_DCHECK(apm_data_dumper); + if (!config.adaptive_digital.use_saturation_protector) { + RTC_LOG(LS_WARNING) << "The saturation protector cannot be disabled."; + } } AdaptiveAgc::~AdaptiveAgc() = default; -void AdaptiveAgc::Process(AudioFrameView float_frame, - float last_audio_level) { - auto signal_with_levels = SignalWithLevels(float_frame); - signal_with_levels.vad_result = vad_.AnalyzeFrame(float_frame); - apm_data_dumper_->DumpRaw("agc2_vad_probability", - signal_with_levels.vad_result.speech_probability); - apm_data_dumper_->DumpRaw("agc2_vad_rms_dbfs", - signal_with_levels.vad_result.speech_rms_dbfs); - apm_data_dumper_->DumpRaw("agc2_vad_peak_dbfs", - signal_with_levels.vad_result.speech_peak_dbfs); - - speech_level_estimator_.UpdateEstimation(signal_with_levels.vad_result); - - signal_with_levels.input_level_dbfs = - speech_level_estimator_.LatestLevelEstimate(); - - signal_with_levels.input_noise_level_dbfs = - noise_level_estimator_.Analyze(float_frame); - - apm_data_dumper_->DumpRaw("agc2_noise_estimate_dbfs", - signal_with_levels.input_noise_level_dbfs); - - signal_with_levels.limiter_audio_level_dbfs = - last_audio_level > 0 ? FloatS16ToDbfs(last_audio_level) : -90.f; - apm_data_dumper_->DumpRaw("agc2_last_limiter_audio_level", - signal_with_levels.limiter_audio_level_dbfs); - - signal_with_levels.estimate_is_confident = - speech_level_estimator_.LevelEstimationIsConfident(); - - // The gain applier applies the gain. - gain_applier_.Process(signal_with_levels); +void AdaptiveAgc::Process(AudioFrameView frame, float limiter_envelope) { + AdaptiveDigitalGainApplier::FrameInfo info; + info.vad_result = vad_.AnalyzeFrame(frame); + speech_level_estimator_.Update(info.vad_result); + info.input_level_dbfs = speech_level_estimator_.level_dbfs(); + info.input_noise_level_dbfs = noise_level_estimator_.Analyze(frame); + info.limiter_envelope_dbfs = + limiter_envelope > 0 ? FloatS16ToDbfs(limiter_envelope) : -90.f; + info.estimate_is_confident = speech_level_estimator_.IsConfident(); + DumpDebugData(info, *apm_data_dumper_); + gain_applier_.Process(info, frame); } void AdaptiveAgc::Reset() { diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_agc.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_agc.h index 16c0082ed..f3c7854e1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_agc.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_agc.h @@ -21,19 +21,25 @@ namespace webrtc { class ApmDataDumper; +// Adaptive digital gain controller. +// TODO(crbug.com/webrtc/7494): Unify with `AdaptiveDigitalGainApplier`. class AdaptiveAgc { public: explicit AdaptiveAgc(ApmDataDumper* apm_data_dumper); + // TODO(crbug.com/webrtc/7494): Remove ctor above. AdaptiveAgc(ApmDataDumper* apm_data_dumper, const AudioProcessing::Config::GainController2& config); ~AdaptiveAgc(); - void Process(AudioFrameView float_frame, float last_audio_level); + // Analyzes `frame` and applies a digital adaptive gain to it. Takes into + // account the envelope measured by the limiter. + // TODO(crbug.com/webrtc/7494): Make the class depend on the limiter. + void Process(AudioFrameView frame, float limiter_envelope); void Reset(); private: AdaptiveModeLevelEstimator speech_level_estimator_; - VadWithLevel vad_; + VadLevelAnalyzer vad_; AdaptiveDigitalGainApplier gain_applier_; ApmDataDumper* const apm_data_dumper_; NoiseLevelEstimator noise_level_estimator_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc index 6ece83b23..36ef9be56 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc @@ -16,6 +16,7 @@ #include "modules/audio_processing/agc2/agc2_common.h" #include "modules/audio_processing/logging/apm_data_dumper.h" #include "rtc_base/checks.h" +#include "rtc_base/logging.h" #include "rtc_base/numerics/safe_minmax.h" #include "system_wrappers/include/metrics.h" @@ -44,12 +45,16 @@ float ComputeGainDb(float input_level_dbfs) { return 0.f; } -// We require 'gain + noise_level <= kMaxNoiseLevelDbfs'. +// Returns `target_gain` if the output noise level is below +// `max_output_noise_level_dbfs`; otherwise returns a capped gain so that the +// output noise level equals `max_output_noise_level_dbfs`. float LimitGainByNoise(float target_gain, float input_noise_level_dbfs, - ApmDataDumper* apm_data_dumper) { - const float noise_headroom_db = kMaxNoiseLevelDbfs - input_noise_level_dbfs; - apm_data_dumper->DumpRaw("agc2_noise_headroom_db", noise_headroom_db); + float max_output_noise_level_dbfs, + ApmDataDumper& apm_data_dumper) { + const float noise_headroom_db = + max_output_noise_level_dbfs - input_noise_level_dbfs; + apm_data_dumper.DumpRaw("agc2_noise_headroom_db", noise_headroom_db); return std::min(target_gain, std::max(noise_headroom_db, 0.f)); } @@ -74,57 +79,68 @@ float LimitGainByLowConfidence(float target_gain, // Return the gain difference in db to 'last_gain_db'. float ComputeGainChangeThisFrameDb(float target_gain_db, float last_gain_db, - bool gain_increase_allowed) { + bool gain_increase_allowed, + float max_gain_change_db) { float target_gain_difference_db = target_gain_db - last_gain_db; if (!gain_increase_allowed) { target_gain_difference_db = std::min(target_gain_difference_db, 0.f); } - - return rtc::SafeClamp(target_gain_difference_db, -kMaxGainChangePerFrameDb, - kMaxGainChangePerFrameDb); + return rtc::SafeClamp(target_gain_difference_db, -max_gain_change_db, + max_gain_change_db); } + } // namespace -SignalWithLevels::SignalWithLevels(AudioFrameView float_frame) - : float_frame(float_frame) {} -SignalWithLevels::SignalWithLevels(const SignalWithLevels&) = default; - AdaptiveDigitalGainApplier::AdaptiveDigitalGainApplier( - ApmDataDumper* apm_data_dumper) - : gain_applier_(false, DbToRatio(last_gain_db_)), - apm_data_dumper_(apm_data_dumper) {} + ApmDataDumper* apm_data_dumper, + int adjacent_speech_frames_threshold, + float max_gain_change_db_per_second, + float max_output_noise_level_dbfs) + : apm_data_dumper_(apm_data_dumper), + gain_applier_( + /*hard_clip_samples=*/false, + /*initial_gain_factor=*/DbToRatio(kInitialAdaptiveDigitalGainDb)), + adjacent_speech_frames_threshold_(adjacent_speech_frames_threshold), + max_gain_change_db_per_10ms_(max_gain_change_db_per_second * + kFrameDurationMs / 1000.f), + max_output_noise_level_dbfs_(max_output_noise_level_dbfs), + calls_since_last_gain_log_(0), + frames_to_gain_increase_allowed_(adjacent_speech_frames_threshold_), + last_gain_db_(kInitialAdaptiveDigitalGainDb) { + RTC_DCHECK_GT(max_gain_change_db_per_second, 0.f); + RTC_DCHECK_GE(frames_to_gain_increase_allowed_, 1); + RTC_DCHECK_GE(max_output_noise_level_dbfs_, -90.f); + RTC_DCHECK_LE(max_output_noise_level_dbfs_, 0.f); +} -void AdaptiveDigitalGainApplier::Process(SignalWithLevels signal_with_levels) { - calls_since_last_gain_log_++; - if (calls_since_last_gain_log_ == 100) { - calls_since_last_gain_log_ = 0; - RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.Agc2.DigitalGainApplied", - last_gain_db_, 0, kMaxGainDb, kMaxGainDb + 1); - RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.Agc2.EstimatedNoiseLevel", - -signal_with_levels.input_noise_level_dbfs, 0, - 100, 101); - } - - signal_with_levels.input_level_dbfs = - std::min(signal_with_levels.input_level_dbfs, 0.f); - - RTC_DCHECK_GE(signal_with_levels.input_level_dbfs, -150.f); - RTC_DCHECK_GE(signal_with_levels.float_frame.num_channels(), 1); - RTC_DCHECK_GE(signal_with_levels.float_frame.samples_per_channel(), 1); +void AdaptiveDigitalGainApplier::Process(const FrameInfo& info, + AudioFrameView frame) { + RTC_DCHECK_GE(info.input_level_dbfs, -150.f); + RTC_DCHECK_GE(frame.num_channels(), 1); + RTC_DCHECK( + frame.samples_per_channel() == 80 || frame.samples_per_channel() == 160 || + frame.samples_per_channel() == 320 || frame.samples_per_channel() == 480) + << "`frame` does not look like a 10 ms frame for an APM supported sample " + "rate"; const float target_gain_db = LimitGainByLowConfidence( - LimitGainByNoise(ComputeGainDb(signal_with_levels.input_level_dbfs), - signal_with_levels.input_noise_level_dbfs, - apm_data_dumper_), - last_gain_db_, signal_with_levels.limiter_audio_level_dbfs, - signal_with_levels.estimate_is_confident); + LimitGainByNoise(ComputeGainDb(std::min(info.input_level_dbfs, 0.f)), + info.input_noise_level_dbfs, + max_output_noise_level_dbfs_, *apm_data_dumper_), + last_gain_db_, info.limiter_envelope_dbfs, info.estimate_is_confident); - // Forbid increasing the gain when there is no speech. - gain_increase_allowed_ = signal_with_levels.vad_result.speech_probability > - kVadConfidenceThreshold; + // Forbid increasing the gain until enough adjacent speech frames are + // observed. + if (info.vad_result.speech_probability < kVadConfidenceThreshold) { + frames_to_gain_increase_allowed_ = adjacent_speech_frames_threshold_; + } else if (frames_to_gain_increase_allowed_ > 0) { + frames_to_gain_increase_allowed_--; + } const float gain_change_this_frame_db = ComputeGainChangeThisFrameDb( - target_gain_db, last_gain_db_, gain_increase_allowed_); + target_gain_db, last_gain_db_, + /*gain_increase_allowed=*/frames_to_gain_increase_allowed_ == 0, + max_gain_change_db_per_10ms_); apm_data_dumper_->DumpRaw("agc2_want_to_change_by_db", target_gain_db - last_gain_db_); @@ -137,10 +153,27 @@ void AdaptiveDigitalGainApplier::Process(SignalWithLevels signal_with_levels) { gain_applier_.SetGainFactor( DbToRatio(last_gain_db_ + gain_change_this_frame_db)); } - gain_applier_.ApplyGain(signal_with_levels.float_frame); + gain_applier_.ApplyGain(frame); // Remember that the gain has changed for the next iteration. last_gain_db_ = last_gain_db_ + gain_change_this_frame_db; apm_data_dumper_->DumpRaw("agc2_applied_gain_db", last_gain_db_); + + // Log every 10 seconds. + calls_since_last_gain_log_++; + if (calls_since_last_gain_log_ == 1000) { + calls_since_last_gain_log_ = 0; + RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.Agc2.DigitalGainApplied", + last_gain_db_, 0, kMaxGainDb, kMaxGainDb + 1); + RTC_HISTOGRAM_COUNTS_LINEAR( + "WebRTC.Audio.Agc2.EstimatedSpeechPlusNoiseLevel", + -info.input_level_dbfs, 0, 100, 101); + RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.Agc2.EstimatedNoiseLevel", + -info.input_noise_level_dbfs, 0, 100, 101); + RTC_LOG(LS_INFO) << "AGC2 adaptive digital" + << " | speech_plus_noise_dbfs: " << info.input_level_dbfs + << " | noise_dbfs: " << info.input_noise_level_dbfs + << " | gain_db: " << last_gain_db_; + } } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.h index e7f07fcf0..a65379f5b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_digital_gain_applier.h @@ -11,7 +11,6 @@ #ifndef MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_DIGITAL_GAIN_APPLIER_H_ #define MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_DIGITAL_GAIN_APPLIER_H_ -#include "modules/audio_processing/agc2/agc2_common.h" #include "modules/audio_processing/agc2/gain_applier.h" #include "modules/audio_processing/agc2/vad_with_level.h" #include "modules/audio_processing/include/audio_frame_view.h" @@ -20,36 +19,51 @@ namespace webrtc { class ApmDataDumper; -struct SignalWithLevels { - SignalWithLevels(AudioFrameView float_frame); - SignalWithLevels(const SignalWithLevels&); - - float input_level_dbfs = -1.f; - float input_noise_level_dbfs = -1.f; - VadWithLevel::LevelAndProbability vad_result; - float limiter_audio_level_dbfs = -1.f; - bool estimate_is_confident = false; - AudioFrameView float_frame; -}; - +// Part of the adaptive digital controller that applies a digital adaptive gain. +// The gain is updated towards a target. The logic decides when gain updates are +// allowed, it controls the adaptation speed and caps the target based on the +// estimated noise level and the speech level estimate confidence. class AdaptiveDigitalGainApplier { public: - explicit AdaptiveDigitalGainApplier(ApmDataDumper* apm_data_dumper); - // Decide what gain to apply. - void Process(SignalWithLevels signal_with_levels); + // Information about a frame to process. + struct FrameInfo { + float input_level_dbfs; // Estimated speech plus noise level. + float input_noise_level_dbfs; // Estimated noise level. + VadLevelAnalyzer::Result vad_result; + float limiter_envelope_dbfs; // Envelope level from the limiter. + bool estimate_is_confident; + }; + + // Ctor. + // `adjacent_speech_frames_threshold` indicates how many speech frames are + // required before a gain increase is allowed. `max_gain_change_db_per_second` + // limits the adaptation speed (uniformly operated across frames). + // `max_output_noise_level_dbfs` limits the output noise level. + AdaptiveDigitalGainApplier(ApmDataDumper* apm_data_dumper, + int adjacent_speech_frames_threshold, + float max_gain_change_db_per_second, + float max_output_noise_level_dbfs); + AdaptiveDigitalGainApplier(const AdaptiveDigitalGainApplier&) = delete; + AdaptiveDigitalGainApplier& operator=(const AdaptiveDigitalGainApplier&) = + delete; + + // Analyzes `info`, updates the digital gain and applies it to a 10 ms + // `frame`. Supports any sample rate supported by APM. + void Process(const FrameInfo& info, AudioFrameView frame); private: - float last_gain_db_ = kInitialAdaptiveDigitalGainDb; + ApmDataDumper* const apm_data_dumper_; GainApplier gain_applier_; - int calls_since_last_gain_log_ = 0; - // For some combinations of noise and speech probability, increasing - // the level is not allowed. Since we may get VAD results in bursts, - // we keep track of this variable until the next VAD results come - // in. - bool gain_increase_allowed_ = true; - ApmDataDumper* apm_data_dumper_ = nullptr; + const int adjacent_speech_frames_threshold_; + const float max_gain_change_db_per_10ms_; + const float max_output_noise_level_dbfs_; + + int calls_since_last_gain_log_; + int frames_to_gain_increase_allowed_; + float last_gain_db_; }; + } // namespace webrtc #endif // MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_DIGITAL_GAIN_APPLIER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc index dd27688ab..739997f5e 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc @@ -13,99 +13,187 @@ #include "modules/audio_processing/agc2/agc2_common.h" #include "modules/audio_processing/logging/apm_data_dumper.h" #include "rtc_base/checks.h" +#include "rtc_base/logging.h" #include "rtc_base/numerics/safe_minmax.h" namespace webrtc { +namespace { + +using LevelEstimatorType = + AudioProcessing::Config::GainController2::LevelEstimator; + +// Combines a level estimation with the saturation protector margins. +float ComputeLevelEstimateDbfs(float level_estimate_dbfs, + float saturation_margin_db, + float extra_saturation_margin_db) { + return rtc::SafeClamp( + level_estimate_dbfs + saturation_margin_db + extra_saturation_margin_db, + -90.f, 30.f); +} + +// Returns the level of given type from `vad_level`. +float GetLevel(const VadLevelAnalyzer::Result& vad_level, + LevelEstimatorType type) { + switch (type) { + case LevelEstimatorType::kRms: + return vad_level.rms_dbfs; + break; + case LevelEstimatorType::kPeak: + return vad_level.peak_dbfs; + break; + } + RTC_CHECK_NOTREACHED(); +} + +} // namespace + +bool AdaptiveModeLevelEstimator::LevelEstimatorState::operator==( + const AdaptiveModeLevelEstimator::LevelEstimatorState& b) const { + return time_to_full_buffer_ms == b.time_to_full_buffer_ms && + level_dbfs.numerator == b.level_dbfs.numerator && + level_dbfs.denominator == b.level_dbfs.denominator && + saturation_protector == b.saturation_protector; +} + +float AdaptiveModeLevelEstimator::LevelEstimatorState::Ratio::GetRatio() const { + RTC_DCHECK_NE(denominator, 0.f); + return numerator / denominator; +} AdaptiveModeLevelEstimator::AdaptiveModeLevelEstimator( ApmDataDumper* apm_data_dumper) - : level_estimator_( - AudioProcessing::Config::GainController2::LevelEstimator::kRms), - use_saturation_protector_(true), - saturation_protector_(apm_data_dumper), - apm_data_dumper_(apm_data_dumper) {} + : AdaptiveModeLevelEstimator( + apm_data_dumper, + AudioProcessing::Config::GainController2::LevelEstimator::kRms, + kDefaultLevelEstimatorAdjacentSpeechFramesThreshold, + kDefaultInitialSaturationMarginDb, + kDefaultExtraSaturationMarginDb) {} AdaptiveModeLevelEstimator::AdaptiveModeLevelEstimator( ApmDataDumper* apm_data_dumper, AudioProcessing::Config::GainController2::LevelEstimator level_estimator, - bool use_saturation_protector, + int adjacent_speech_frames_threshold, + float initial_saturation_margin_db, float extra_saturation_margin_db) - : level_estimator_(level_estimator), - use_saturation_protector_(use_saturation_protector), - saturation_protector_(apm_data_dumper, extra_saturation_margin_db), - apm_data_dumper_(apm_data_dumper) {} + : apm_data_dumper_(apm_data_dumper), + level_estimator_type_(level_estimator), + adjacent_speech_frames_threshold_(adjacent_speech_frames_threshold), + initial_saturation_margin_db_(initial_saturation_margin_db), + extra_saturation_margin_db_(extra_saturation_margin_db), + level_dbfs_(ComputeLevelEstimateDbfs(kInitialSpeechLevelEstimateDbfs, + initial_saturation_margin_db_, + extra_saturation_margin_db_)) { + RTC_DCHECK(apm_data_dumper_); + RTC_DCHECK_GE(adjacent_speech_frames_threshold_, 1); + Reset(); +} -void AdaptiveModeLevelEstimator::UpdateEstimation( - const VadWithLevel::LevelAndProbability& vad_data) { - RTC_DCHECK_GT(vad_data.speech_rms_dbfs, -150.f); - RTC_DCHECK_LT(vad_data.speech_rms_dbfs, 50.f); - RTC_DCHECK_GT(vad_data.speech_peak_dbfs, -150.f); - RTC_DCHECK_LT(vad_data.speech_peak_dbfs, 50.f); - RTC_DCHECK_GE(vad_data.speech_probability, 0.f); - RTC_DCHECK_LE(vad_data.speech_probability, 1.f); +void AdaptiveModeLevelEstimator::Update( + const VadLevelAnalyzer::Result& vad_level) { + RTC_DCHECK_GT(vad_level.rms_dbfs, -150.f); + RTC_DCHECK_LT(vad_level.rms_dbfs, 50.f); + RTC_DCHECK_GT(vad_level.peak_dbfs, -150.f); + RTC_DCHECK_LT(vad_level.peak_dbfs, 50.f); + RTC_DCHECK_GE(vad_level.speech_probability, 0.f); + RTC_DCHECK_LE(vad_level.speech_probability, 1.f); + DumpDebugData(); - if (vad_data.speech_probability < kVadConfidenceThreshold) { - DebugDumpEstimate(); + if (vad_level.speech_probability < kVadConfidenceThreshold) { + // Not a speech frame. + if (adjacent_speech_frames_threshold_ > 1) { + // When two or more adjacent speech frames are required in order to update + // the state, we need to decide whether to discard or confirm the updates + // based on the speech sequence length. + if (num_adjacent_speech_frames_ >= adjacent_speech_frames_threshold_) { + // First non-speech frame after a long enough sequence of speech frames. + // Update the reliable state. + reliable_state_ = preliminary_state_; + } else if (num_adjacent_speech_frames_ > 0) { + // First non-speech frame after a too short sequence of speech frames. + // Reset to the last reliable state. + preliminary_state_ = reliable_state_; + } + } + num_adjacent_speech_frames_ = 0; return; } - const bool buffer_is_full = buffer_size_ms_ >= kFullBufferSizeMs; + // Speech frame observed. + num_adjacent_speech_frames_++; + + // Update preliminary level estimate. + RTC_DCHECK_GE(preliminary_state_.time_to_full_buffer_ms, 0); + const bool buffer_is_full = preliminary_state_.time_to_full_buffer_ms == 0; if (!buffer_is_full) { - buffer_size_ms_ += kFrameDurationMs; + preliminary_state_.time_to_full_buffer_ms -= kFrameDurationMs; } - + // Weighted average of levels with speech probability as weight. + RTC_DCHECK_GT(vad_level.speech_probability, 0.f); const float leak_factor = buffer_is_full ? kFullBufferLeakFactor : 1.f; + preliminary_state_.level_dbfs.numerator = + preliminary_state_.level_dbfs.numerator * leak_factor + + GetLevel(vad_level, level_estimator_type_) * vad_level.speech_probability; + preliminary_state_.level_dbfs.denominator = + preliminary_state_.level_dbfs.denominator * leak_factor + + vad_level.speech_probability; - // Read speech level estimation. - float speech_level_dbfs = 0.f; - using LevelEstimatorType = - AudioProcessing::Config::GainController2::LevelEstimator; - switch (level_estimator_) { - case LevelEstimatorType::kRms: - speech_level_dbfs = vad_data.speech_rms_dbfs; - break; - case LevelEstimatorType::kPeak: - speech_level_dbfs = vad_data.speech_peak_dbfs; - break; - } + const float level_dbfs = preliminary_state_.level_dbfs.GetRatio(); - // Update speech level estimation. - estimate_numerator_ = estimate_numerator_ * leak_factor + - speech_level_dbfs * vad_data.speech_probability; - estimate_denominator_ = - estimate_denominator_ * leak_factor + vad_data.speech_probability; - last_estimate_with_offset_dbfs_ = estimate_numerator_ / estimate_denominator_; + UpdateSaturationProtectorState(vad_level.peak_dbfs, level_dbfs, + preliminary_state_.saturation_protector); - if (use_saturation_protector_) { - saturation_protector_.UpdateMargin(vad_data, - last_estimate_with_offset_dbfs_); - DebugDumpEstimate(); + if (num_adjacent_speech_frames_ >= adjacent_speech_frames_threshold_) { + // `preliminary_state_` is now reliable. Update the last level estimation. + level_dbfs_ = ComputeLevelEstimateDbfs( + level_dbfs, preliminary_state_.saturation_protector.margin_db, + extra_saturation_margin_db_); } } -float AdaptiveModeLevelEstimator::LatestLevelEstimate() const { - return rtc::SafeClamp( - last_estimate_with_offset_dbfs_ + - (use_saturation_protector_ ? saturation_protector_.LastMargin() - : 0.f), - -90.f, 30.f); +bool AdaptiveModeLevelEstimator::IsConfident() const { + if (adjacent_speech_frames_threshold_ == 1) { + // Ignore `reliable_state_` when a single frame is enough to update the + // level estimate (because it is not used). + return preliminary_state_.time_to_full_buffer_ms == 0; + } + // Once confident, it remains confident. + RTC_DCHECK(reliable_state_.time_to_full_buffer_ms != 0 || + preliminary_state_.time_to_full_buffer_ms == 0); + // During the first long enough speech sequence, `reliable_state_` must be + // ignored since `preliminary_state_` is used. + return reliable_state_.time_to_full_buffer_ms == 0 || + (num_adjacent_speech_frames_ >= adjacent_speech_frames_threshold_ && + preliminary_state_.time_to_full_buffer_ms == 0); } void AdaptiveModeLevelEstimator::Reset() { - buffer_size_ms_ = 0; - last_estimate_with_offset_dbfs_ = kInitialSpeechLevelEstimateDbfs; - estimate_numerator_ = 0.f; - estimate_denominator_ = 0.f; - saturation_protector_.Reset(); + ResetLevelEstimatorState(preliminary_state_); + ResetLevelEstimatorState(reliable_state_); + level_dbfs_ = ComputeLevelEstimateDbfs(kInitialSpeechLevelEstimateDbfs, + initial_saturation_margin_db_, + extra_saturation_margin_db_); + num_adjacent_speech_frames_ = 0; } -void AdaptiveModeLevelEstimator::DebugDumpEstimate() { - if (apm_data_dumper_) { - apm_data_dumper_->DumpRaw("agc2_adaptive_level_estimate_with_offset_dbfs", - last_estimate_with_offset_dbfs_); - apm_data_dumper_->DumpRaw("agc2_adaptive_level_estimate_dbfs", - LatestLevelEstimate()); - } - saturation_protector_.DebugDumpEstimate(); +void AdaptiveModeLevelEstimator::ResetLevelEstimatorState( + LevelEstimatorState& state) const { + state.time_to_full_buffer_ms = kFullBufferSizeMs; + state.level_dbfs.numerator = 0.f; + state.level_dbfs.denominator = 0.f; + ResetSaturationProtectorState(initial_saturation_margin_db_, + state.saturation_protector); } + +void AdaptiveModeLevelEstimator::DumpDebugData() const { + apm_data_dumper_->DumpRaw("agc2_adaptive_level_estimate_dbfs", level_dbfs_); + apm_data_dumper_->DumpRaw("agc2_adaptive_num_adjacent_speech_frames_", + num_adjacent_speech_frames_); + apm_data_dumper_->DumpRaw("agc2_adaptive_preliminary_level_estimate_num", + preliminary_state_.level_dbfs.numerator); + apm_data_dumper_->DumpRaw("agc2_adaptive_preliminary_level_estimate_den", + preliminary_state_.level_dbfs.denominator); + apm_data_dumper_->DumpRaw("agc2_adaptive_preliminary_saturation_margin_db", + preliminary_state_.saturation_protector.margin_db); +} + } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.h index 63b9de2ae..213fc0f0c 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator.h @@ -12,8 +12,9 @@ #define MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_MODE_LEVEL_ESTIMATOR_H_ #include +#include -#include "modules/audio_processing/agc2/agc2_common.h" // kFullBufferSizeMs... +#include "modules/audio_processing/agc2/agc2_common.h" #include "modules/audio_processing/agc2/saturation_protector.h" #include "modules/audio_processing/agc2/vad_with_level.h" #include "modules/audio_processing/include/audio_processing.h" @@ -21,33 +22,63 @@ namespace webrtc { class ApmDataDumper; +// Level estimator for the digital adaptive gain controller. class AdaptiveModeLevelEstimator { public: explicit AdaptiveModeLevelEstimator(ApmDataDumper* apm_data_dumper); + AdaptiveModeLevelEstimator(const AdaptiveModeLevelEstimator&) = delete; + AdaptiveModeLevelEstimator& operator=(const AdaptiveModeLevelEstimator&) = + delete; AdaptiveModeLevelEstimator( ApmDataDumper* apm_data_dumper, AudioProcessing::Config::GainController2::LevelEstimator level_estimator, - bool use_saturation_protector, + int adjacent_speech_frames_threshold, + float initial_saturation_margin_db, float extra_saturation_margin_db); - void UpdateEstimation(const VadWithLevel::LevelAndProbability& vad_data); - float LatestLevelEstimate() const; + + // Updates the level estimation. + void Update(const VadLevelAnalyzer::Result& vad_data); + // Returns the estimated speech plus noise level. + float level_dbfs() const { return level_dbfs_; } + // Returns true if the estimator is confident on its current estimate. + bool IsConfident() const; + void Reset(); - bool LevelEstimationIsConfident() const { - return buffer_size_ms_ >= kFullBufferSizeMs; - } private: - void DebugDumpEstimate(); + // Part of the level estimator state used for check-pointing and restore ops. + struct LevelEstimatorState { + bool operator==(const LevelEstimatorState& s) const; + inline bool operator!=(const LevelEstimatorState& s) const { + return !(*this == s); + } + struct Ratio { + float numerator; + float denominator; + float GetRatio() const; + }; + // TODO(crbug.com/webrtc/7494): Remove time_to_full_buffer_ms if redundant. + int time_to_full_buffer_ms; + Ratio level_dbfs; + SaturationProtectorState saturation_protector; + }; + static_assert(std::is_trivially_copyable::value, ""); + + void ResetLevelEstimatorState(LevelEstimatorState& state) const; + + void DumpDebugData() const; + + ApmDataDumper* const apm_data_dumper_; const AudioProcessing::Config::GainController2::LevelEstimator - level_estimator_; - const bool use_saturation_protector_; - size_t buffer_size_ms_ = 0; - float last_estimate_with_offset_dbfs_ = kInitialSpeechLevelEstimateDbfs; - float estimate_numerator_ = 0.f; - float estimate_denominator_ = 0.f; - SaturationProtector saturation_protector_; - ApmDataDumper* const apm_data_dumper_; + level_estimator_type_; + const int adjacent_speech_frames_threshold_; + const float initial_saturation_margin_db_; + const float extra_saturation_margin_db_; + LevelEstimatorState preliminary_state_; + LevelEstimatorState reliable_state_; + float level_dbfs_; + int num_adjacent_speech_frames_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc index b7c64373f..5ceeb7df7 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc @@ -38,7 +38,7 @@ void AdaptiveModeLevelEstimatorAgc::Process(const int16_t* audio, if (latest_voice_probability_ > kVadConfidenceThreshold) { time_in_ms_since_last_estimate_ += kFrameDurationMs; } - level_estimator_.UpdateEstimation(vad_prob); + level_estimator_.Update(vad_prob); } // Retrieves the difference between the target RMS level and the current @@ -48,8 +48,8 @@ bool AdaptiveModeLevelEstimatorAgc::GetRmsErrorDb(int* error) { if (time_in_ms_since_last_estimate_ <= kTimeUntilConfidentMs) { return false; } - *error = std::floor(target_level_dbfs() - - level_estimator_.LatestLevelEstimate() + 0.5f); + *error = + std::floor(target_level_dbfs() - level_estimator_.level_dbfs() + 0.5f); time_in_ms_since_last_estimate_ = 0; return true; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h index 6d1233988..bc6fa843b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h @@ -43,7 +43,7 @@ class AdaptiveModeLevelEstimatorAgc : public Agc { static constexpr int kDefaultAgc2LevelHeadroomDbfs = -1; int32_t time_in_ms_since_last_estimate_ = 0; AdaptiveModeLevelEstimator level_estimator_; - VadWithLevel agc2_vad_; + VadLevelAnalyzer agc2_vad_; float latest_voice_probability_ = 0.f; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/agc2_common.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/agc2_common.cc deleted file mode 100644 index 3f697d12a..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/agc2_common.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 "modules/audio_processing/agc2/agc2_common.h" - -#include - -#include - -#include "system_wrappers/include/field_trial.h" - -namespace webrtc { - -float GetInitialSaturationMarginDb() { - constexpr char kForceInitialSaturationMarginFieldTrial[] = - "WebRTC-Audio-Agc2ForceInitialSaturationMargin"; - - const bool use_forced_initial_saturation_margin = - webrtc::field_trial::IsEnabled(kForceInitialSaturationMarginFieldTrial); - if (use_forced_initial_saturation_margin) { - const std::string field_trial_string = webrtc::field_trial::FindFullName( - kForceInitialSaturationMarginFieldTrial); - float margin_db = -1; - if (sscanf(field_trial_string.c_str(), "Enabled-%f", &margin_db) == 1 && - margin_db >= 12.f && margin_db <= 25.f) { - return margin_db; - } - } - constexpr float kDefaultInitialSaturationMarginDb = 20.f; - return kDefaultInitialSaturationMarginDb; -} - -float GetExtraSaturationMarginOffsetDb() { - constexpr char kForceExtraSaturationMarginFieldTrial[] = - "WebRTC-Audio-Agc2ForceExtraSaturationMargin"; - - const bool use_forced_extra_saturation_margin = - webrtc::field_trial::IsEnabled(kForceExtraSaturationMarginFieldTrial); - if (use_forced_extra_saturation_margin) { - const std::string field_trial_string = webrtc::field_trial::FindFullName( - kForceExtraSaturationMarginFieldTrial); - float margin_db = -1; - if (sscanf(field_trial_string.c_str(), "Enabled-%f", &margin_db) == 1 && - margin_db >= 0.f && margin_db <= 10.f) { - return margin_db; - } - } - constexpr float kDefaultExtraSaturationMarginDb = 2.f; - return kDefaultExtraSaturationMarginDb; -} -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/agc2_common.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/agc2_common.h index a6389f4c2..5d01100eb 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/agc2_common.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/agc2_common.h @@ -26,18 +26,12 @@ constexpr size_t kMaximalNumberOfSamplesPerChannel = 480; constexpr float kAttackFilterConstant = 0.f; // Adaptive digital gain applier settings below. -constexpr float kMaxGainChangePerSecondDb = 3.f; -constexpr float kMaxGainChangePerFrameDb = - kMaxGainChangePerSecondDb * kFrameDurationMs / 1000.f; constexpr float kHeadroomDbfs = 1.f; constexpr float kMaxGainDb = 30.f; constexpr float kInitialAdaptiveDigitalGainDb = 8.f; // At what limiter levels should we start decreasing the adaptive digital gain. constexpr float kLimiterThresholdForAgcGainDbfs = -kHeadroomDbfs; -// This parameter must be tuned together with the noise estimator. -constexpr float kMaxNoiseLevelDbfs = -50.f; - // This is the threshold for speech. Speech frames are used for updating the // speech level, measuring the amount of speech, and decide when to allow target // gain reduction. @@ -49,9 +43,13 @@ constexpr float kFullBufferLeakFactor = 1.f - 1.f / kFullBufferSizeMs; constexpr float kInitialSpeechLevelEstimateDbfs = -30.f; +// Robust VAD probability and speech decisions. +constexpr float kDefaultSmoothedVadProbabilityAttack = 1.f; +constexpr int kDefaultLevelEstimatorAdjacentSpeechFramesThreshold = 1; + // Saturation Protector settings. -float GetInitialSaturationMarginDb(); -float GetExtraSaturationMarginOffsetDb(); +constexpr float kDefaultInitialSaturationMarginDb = 20.f; +constexpr float kDefaultExtraSaturationMarginDb = 2.f; constexpr size_t kPeakEnveloperSuperFrameLengthMs = 400; static_assert(kFullBufferSizeMs % kPeakEnveloperSuperFrameLengthMs == 0, diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/down_sampler.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/down_sampler.h index 61d1b005e..be7cbb3da 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/down_sampler.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/down_sampler.h @@ -13,7 +13,6 @@ #include "api/array_view.h" #include "modules/audio_processing/agc2/biquad_filter.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -22,6 +21,11 @@ class ApmDataDumper; class DownSampler { public: explicit DownSampler(ApmDataDumper* data_dumper); + + DownSampler() = delete; + DownSampler(const DownSampler&) = delete; + DownSampler& operator=(const DownSampler&) = delete; + void Initialize(int sample_rate_hz); void DownSample(rtc::ArrayView in, rtc::ArrayView out); @@ -31,8 +35,6 @@ class DownSampler { int sample_rate_hz_; int down_sampling_factor_; BiQuadFilter low_pass_filter_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DownSampler); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/noise_spectrum_estimator.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/noise_spectrum_estimator.h index b22f9bb39..e9895f0b1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/noise_spectrum_estimator.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/noise_spectrum_estimator.h @@ -12,7 +12,6 @@ #define MODULES_AUDIO_PROCESSING_AGC2_NOISE_SPECTRUM_ESTIMATOR_H_ #include "api/array_view.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -21,6 +20,11 @@ class ApmDataDumper; class NoiseSpectrumEstimator { public: explicit NoiseSpectrumEstimator(ApmDataDumper* data_dumper); + + NoiseSpectrumEstimator() = delete; + NoiseSpectrumEstimator(const NoiseSpectrumEstimator&) = delete; + NoiseSpectrumEstimator& operator=(const NoiseSpectrumEstimator&) = delete; + void Initialize(); void Update(rtc::ArrayView spectrum, bool first_update); @@ -31,8 +35,6 @@ class NoiseSpectrumEstimator { private: ApmDataDumper* data_dumper_; float noise_spectrum_[65]; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(NoiseSpectrumEstimator); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/auto_correlation.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/auto_correlation.cc index d932c7806..431c01fab 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/auto_correlation.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/auto_correlation.cc @@ -20,7 +20,7 @@ namespace { constexpr int kAutoCorrelationFftOrder = 9; // Length-512 FFT. static_assert(1 << kAutoCorrelationFftOrder > - kNumInvertedLags12kHz + kBufSize12kHz - kMaxPitch12kHz, + kNumLags12kHz + kBufSize12kHz - kMaxPitch12kHz, ""); } // namespace @@ -45,15 +45,15 @@ AutoCorrelationCalculator::~AutoCorrelationCalculator() = default; // pitch period. void AutoCorrelationCalculator::ComputeOnPitchBuffer( rtc::ArrayView pitch_buf, - rtc::ArrayView auto_corr) { + rtc::ArrayView auto_corr) { RTC_DCHECK_LT(auto_corr.size(), kMaxPitch12kHz); RTC_DCHECK_GT(pitch_buf.size(), kMaxPitch12kHz); - constexpr size_t kFftFrameSize = 1 << kAutoCorrelationFftOrder; - constexpr size_t kConvolutionLength = kBufSize12kHz - kMaxPitch12kHz; + constexpr int kFftFrameSize = 1 << kAutoCorrelationFftOrder; + constexpr int kConvolutionLength = kBufSize12kHz - kMaxPitch12kHz; static_assert(kConvolutionLength == kFrameSize20ms12kHz, "Mismatch between pitch buffer size, frame size and maximum " "pitch period."); - static_assert(kFftFrameSize > kNumInvertedLags12kHz + kConvolutionLength, + static_assert(kFftFrameSize > kNumLags12kHz + kConvolutionLength, "The FFT length is not sufficiently big to avoid cyclic " "convolution errors."); auto tmp = tmp_->GetView(); @@ -67,13 +67,12 @@ void AutoCorrelationCalculator::ComputeOnPitchBuffer( // Compute the FFT for the sliding frames chunk. The sliding frames are // defined as pitch_buf[i:i+kConvolutionLength] where i in - // [0, kNumInvertedLags12kHz). The chunk includes all of them, hence it is - // defined as pitch_buf[:kNumInvertedLags12kHz+kConvolutionLength]. + // [0, kNumLags12kHz). The chunk includes all of them, hence it is + // defined as pitch_buf[:kNumLags12kHz+kConvolutionLength]. std::copy(pitch_buf.begin(), - pitch_buf.begin() + kConvolutionLength + kNumInvertedLags12kHz, + pitch_buf.begin() + kConvolutionLength + kNumLags12kHz, tmp.begin()); - std::fill(tmp.begin() + kNumInvertedLags12kHz + kConvolutionLength, tmp.end(), - 0.f); + std::fill(tmp.begin() + kNumLags12kHz + kConvolutionLength, tmp.end(), 0.f); fft_.ForwardTransform(*tmp_, X_.get(), /*ordered=*/false); // Convolve in the frequency domain. @@ -84,7 +83,7 @@ void AutoCorrelationCalculator::ComputeOnPitchBuffer( // Extract the auto-correlation coefficients. std::copy(tmp.begin() + kConvolutionLength - 1, - tmp.begin() + kConvolutionLength + kNumInvertedLags12kHz - 1, + tmp.begin() + kConvolutionLength + kNumLags12kHz - 1, auto_corr.begin()); } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/auto_correlation.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/auto_correlation.h index de7f453bc..d58558ca2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/auto_correlation.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/auto_correlation.h @@ -34,7 +34,7 @@ class AutoCorrelationCalculator { // |auto_corr| indexes are inverted lags. void ComputeOnPitchBuffer( rtc::ArrayView pitch_buf, - rtc::ArrayView auto_corr); + rtc::ArrayView auto_corr); private: Pffft fft_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/common.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/common.cc index 744c87fea..5d76b52e5 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/common.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/common.cc @@ -18,7 +18,7 @@ namespace rnn_vad { Optimization DetectOptimization() { #if defined(WEBRTC_ARCH_X86_FAMILY) - if (WebRtc_GetCPUInfo(kSSE2) != 0) { + if (GetCPUInfo(kSSE2) != 0) { return Optimization::kSse2; } #endif diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/common.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/common.h index c2e8df690..36b366ad1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/common.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/common.h @@ -18,52 +18,58 @@ namespace rnn_vad { constexpr double kPi = 3.14159265358979323846; -constexpr size_t kSampleRate24kHz = 24000; -constexpr size_t kFrameSize10ms24kHz = kSampleRate24kHz / 100; -constexpr size_t kFrameSize20ms24kHz = kFrameSize10ms24kHz * 2; +constexpr int kSampleRate24kHz = 24000; +constexpr int kFrameSize10ms24kHz = kSampleRate24kHz / 100; +constexpr int kFrameSize20ms24kHz = kFrameSize10ms24kHz * 2; // Pitch buffer. -constexpr size_t kMinPitch24kHz = kSampleRate24kHz / 800; // 0.00125 s. -constexpr size_t kMaxPitch24kHz = kSampleRate24kHz / 62.5; // 0.016 s. -constexpr size_t kBufSize24kHz = kMaxPitch24kHz + kFrameSize20ms24kHz; +constexpr int kMinPitch24kHz = kSampleRate24kHz / 800; // 0.00125 s. +constexpr int kMaxPitch24kHz = kSampleRate24kHz / 62.5; // 0.016 s. +constexpr int kBufSize24kHz = kMaxPitch24kHz + kFrameSize20ms24kHz; static_assert((kBufSize24kHz & 1) == 0, "The buffer size must be even."); // 24 kHz analysis. // Define a higher minimum pitch period for the initial search. This is used to // avoid searching for very short periods, for which a refinement step is // responsible. -constexpr size_t kInitialMinPitch24kHz = 3 * kMinPitch24kHz; +constexpr int kInitialMinPitch24kHz = 3 * kMinPitch24kHz; static_assert(kMinPitch24kHz < kInitialMinPitch24kHz, ""); static_assert(kInitialMinPitch24kHz < kMaxPitch24kHz, ""); static_assert(kMaxPitch24kHz > kInitialMinPitch24kHz, ""); -constexpr size_t kNumInvertedLags24kHz = kMaxPitch24kHz - kInitialMinPitch24kHz; +// Number of (inverted) lags during the initial pitch search phase at 24 kHz. +constexpr int kInitialNumLags24kHz = kMaxPitch24kHz - kInitialMinPitch24kHz; +// Number of (inverted) lags during the pitch search refinement phase at 24 kHz. +constexpr int kRefineNumLags24kHz = kMaxPitch24kHz + 1; +static_assert( + kRefineNumLags24kHz > kInitialNumLags24kHz, + "The refinement step must search the pitch in an extended pitch range."); // 12 kHz analysis. -constexpr size_t kSampleRate12kHz = 12000; -constexpr size_t kFrameSize10ms12kHz = kSampleRate12kHz / 100; -constexpr size_t kFrameSize20ms12kHz = kFrameSize10ms12kHz * 2; -constexpr size_t kBufSize12kHz = kBufSize24kHz / 2; -constexpr size_t kInitialMinPitch12kHz = kInitialMinPitch24kHz / 2; -constexpr size_t kMaxPitch12kHz = kMaxPitch24kHz / 2; +constexpr int kSampleRate12kHz = 12000; +constexpr int kFrameSize10ms12kHz = kSampleRate12kHz / 100; +constexpr int kFrameSize20ms12kHz = kFrameSize10ms12kHz * 2; +constexpr int kBufSize12kHz = kBufSize24kHz / 2; +constexpr int kInitialMinPitch12kHz = kInitialMinPitch24kHz / 2; +constexpr int kMaxPitch12kHz = kMaxPitch24kHz / 2; static_assert(kMaxPitch12kHz > kInitialMinPitch12kHz, ""); // The inverted lags for the pitch interval [|kInitialMinPitch12kHz|, -// |kMaxPitch12kHz|] are in the range [0, |kNumInvertedLags12kHz|]. -constexpr size_t kNumInvertedLags12kHz = kMaxPitch12kHz - kInitialMinPitch12kHz; +// |kMaxPitch12kHz|] are in the range [0, |kNumLags12kHz|]. +constexpr int kNumLags12kHz = kMaxPitch12kHz - kInitialMinPitch12kHz; // 48 kHz constants. -constexpr size_t kMinPitch48kHz = kMinPitch24kHz * 2; -constexpr size_t kMaxPitch48kHz = kMaxPitch24kHz * 2; +constexpr int kMinPitch48kHz = kMinPitch24kHz * 2; +constexpr int kMaxPitch48kHz = kMaxPitch24kHz * 2; // Spectral features. -constexpr size_t kNumBands = 22; -constexpr size_t kNumLowerBands = 6; +constexpr int kNumBands = 22; +constexpr int kNumLowerBands = 6; static_assert((0 < kNumLowerBands) && (kNumLowerBands < kNumBands), ""); -constexpr size_t kCepstralCoeffsHistorySize = 8; +constexpr int kCepstralCoeffsHistorySize = 8; static_assert(kCepstralCoeffsHistorySize > 2, "The history size must at least be 3 to compute first and second " "derivatives."); -constexpr size_t kFeatureVectorSize = 42; +constexpr int kFeatureVectorSize = 42; enum class Optimization { kNone, kSse2, kNeon }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/features_extraction.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/features_extraction.cc index e9351797f..cdbbbc311 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/features_extraction.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/features_extraction.cc @@ -67,13 +67,12 @@ bool FeaturesExtractor::CheckSilenceComputeFeatures( ComputeLpResidual(lpc_coeffs, pitch_buf_24kHz_view_, lp_residual_view_); // Estimate pitch on the LP-residual and write the normalized pitch period // into the output vector (normalization based on training data stats). - pitch_info_48kHz_ = pitch_estimator_.Estimate(lp_residual_view_); - feature_vector[kFeatureVectorSize - 2] = - 0.01f * (static_cast(pitch_info_48kHz_.period) - 300); + pitch_period_48kHz_ = pitch_estimator_.Estimate(lp_residual_view_); + feature_vector[kFeatureVectorSize - 2] = 0.01f * (pitch_period_48kHz_ - 300); // Extract lagged frames (according to the estimated pitch period). - RTC_DCHECK_LE(pitch_info_48kHz_.period / 2, kMaxPitch24kHz); + RTC_DCHECK_LE(pitch_period_48kHz_ / 2, kMaxPitch24kHz); auto lagged_frame = pitch_buf_24kHz_view_.subview( - kMaxPitch24kHz - pitch_info_48kHz_.period / 2, kFrameSize20ms24kHz); + kMaxPitch24kHz - pitch_period_48kHz_ / 2, kFrameSize20ms24kHz); // Analyze reference and lagged frames checking if silence has been detected // and write the feature vector. return spectral_features_extractor_.CheckSilenceComputeFeatures( diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/features_extraction.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/features_extraction.h index ce5cce185..e2c77d2cf 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/features_extraction.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/features_extraction.h @@ -16,7 +16,6 @@ #include "api/array_view.h" #include "modules/audio_processing/agc2/biquad_filter.h" #include "modules/audio_processing/agc2/rnn_vad/common.h" -#include "modules/audio_processing/agc2/rnn_vad/pitch_info.h" #include "modules/audio_processing/agc2/rnn_vad/pitch_search.h" #include "modules/audio_processing/agc2/rnn_vad/sequence_buffer.h" #include "modules/audio_processing/agc2/rnn_vad/spectral_features.h" @@ -53,7 +52,7 @@ class FeaturesExtractor { PitchEstimator pitch_estimator_; rtc::ArrayView reference_frame_view_; SpectralFeaturesExtractor spectral_features_extractor_; - PitchInfo pitch_info_48kHz_; + int pitch_period_48kHz_; }; } // namespace rnn_vad diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/lp_residual.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/lp_residual.cc index 1a124a349..c553aa2ad 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/lp_residual.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/lp_residual.cc @@ -16,27 +16,23 @@ #include #include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_compare.h" namespace webrtc { namespace rnn_vad { namespace { -// Computes cross-correlation coefficients between |x| and |y| and writes them -// in |x_corr|. The lag values are in {0, ..., max_lag - 1}, where max_lag -// equals the size of |x_corr|. -// The |x| and |y| sub-arrays used to compute a cross-correlation coefficients -// for a lag l have both size "size of |x| - l" - i.e., the longest sub-array is -// used. |x| and |y| must have the same size. -void ComputeCrossCorrelation( +// Computes auto-correlation coefficients for |x| and writes them in +// |auto_corr|. The lag values are in {0, ..., max_lag - 1}, where max_lag +// equals the size of |auto_corr|. +void ComputeAutoCorrelation( rtc::ArrayView x, - rtc::ArrayView y, - rtc::ArrayView x_corr) { - constexpr size_t max_lag = x_corr.size(); - RTC_DCHECK_EQ(x.size(), y.size()); + rtc::ArrayView auto_corr) { + constexpr int max_lag = auto_corr.size(); RTC_DCHECK_LT(max_lag, x.size()); - for (size_t lag = 0; lag < max_lag; ++lag) { - x_corr[lag] = - std::inner_product(x.begin(), x.end() - lag, y.begin() + lag, 0.f); + for (int lag = 0; lag < max_lag; ++lag) { + auto_corr[lag] = + std::inner_product(x.begin(), x.end() - lag, x.begin() + lag, 0.f); } } @@ -45,9 +41,13 @@ void DenoiseAutoCorrelation( rtc::ArrayView auto_corr) { // Assume -40 dB white noise floor. auto_corr[0] *= 1.0001f; - for (size_t i = 1; i < kNumLpcCoefficients; ++i) { - auto_corr[i] -= auto_corr[i] * (0.008f * i) * (0.008f * i); - } + // Hard-coded values obtained as + // [np.float32((0.008*0.008*i*i)) for i in range(1,5)]. + auto_corr[1] -= auto_corr[1] * 0.000064f; + auto_corr[2] -= auto_corr[2] * 0.000256f; + auto_corr[3] -= auto_corr[3] * 0.000576f; + auto_corr[4] -= auto_corr[4] * 0.001024f; + static_assert(kNumLpcCoefficients == 5, "Update `auto_corr`."); } // Computes the initial inverse filter coefficients given the auto-correlation @@ -56,9 +56,9 @@ void ComputeInitialInverseFilterCoefficients( rtc::ArrayView auto_corr, rtc::ArrayView lpc_coeffs) { float error = auto_corr[0]; - for (size_t i = 0; i < kNumLpcCoefficients - 1; ++i) { + for (int i = 0; i < kNumLpcCoefficients - 1; ++i) { float reflection_coeff = 0.f; - for (size_t j = 0; j < i; ++j) { + for (int j = 0; j < i; ++j) { reflection_coeff += lpc_coeffs[j] * auto_corr[i - j]; } reflection_coeff += auto_corr[i + 1]; @@ -72,7 +72,7 @@ void ComputeInitialInverseFilterCoefficients( reflection_coeff /= -error; // Update LPC coefficients and total error. lpc_coeffs[i] = reflection_coeff; - for (size_t j = 0; j<(i + 1)>> 1; ++j) { + for (int j = 0; j < ((i + 1) >> 1); ++j) { const float tmp1 = lpc_coeffs[j]; const float tmp2 = lpc_coeffs[i - 1 - j]; lpc_coeffs[j] = tmp1 + reflection_coeff * tmp2; @@ -91,46 +91,49 @@ void ComputeAndPostProcessLpcCoefficients( rtc::ArrayView x, rtc::ArrayView lpc_coeffs) { std::array auto_corr; - ComputeCrossCorrelation(x, x, {auto_corr.data(), auto_corr.size()}); + ComputeAutoCorrelation(x, auto_corr); if (auto_corr[0] == 0.f) { // Empty frame. std::fill(lpc_coeffs.begin(), lpc_coeffs.end(), 0); return; } - DenoiseAutoCorrelation({auto_corr.data(), auto_corr.size()}); + DenoiseAutoCorrelation(auto_corr); std::array lpc_coeffs_pre{}; ComputeInitialInverseFilterCoefficients(auto_corr, lpc_coeffs_pre); // LPC coefficients post-processing. // TODO(bugs.webrtc.org/9076): Consider removing these steps. - float c1 = 1.f; - for (size_t i = 0; i < kNumLpcCoefficients - 1; ++i) { - c1 *= 0.9f; - lpc_coeffs_pre[i] *= c1; - } - const float c2 = 0.8f; - lpc_coeffs[0] = lpc_coeffs_pre[0] + c2; - lpc_coeffs[1] = lpc_coeffs_pre[1] + c2 * lpc_coeffs_pre[0]; - lpc_coeffs[2] = lpc_coeffs_pre[2] + c2 * lpc_coeffs_pre[1]; - lpc_coeffs[3] = lpc_coeffs_pre[3] + c2 * lpc_coeffs_pre[2]; - lpc_coeffs[4] = c2 * lpc_coeffs_pre[3]; + lpc_coeffs_pre[0] *= 0.9f; + lpc_coeffs_pre[1] *= 0.9f * 0.9f; + lpc_coeffs_pre[2] *= 0.9f * 0.9f * 0.9f; + lpc_coeffs_pre[3] *= 0.9f * 0.9f * 0.9f * 0.9f; + constexpr float kC = 0.8f; + lpc_coeffs[0] = lpc_coeffs_pre[0] + kC; + lpc_coeffs[1] = lpc_coeffs_pre[1] + kC * lpc_coeffs_pre[0]; + lpc_coeffs[2] = lpc_coeffs_pre[2] + kC * lpc_coeffs_pre[1]; + lpc_coeffs[3] = lpc_coeffs_pre[3] + kC * lpc_coeffs_pre[2]; + lpc_coeffs[4] = kC * lpc_coeffs_pre[3]; + static_assert(kNumLpcCoefficients == 5, "Update `lpc_coeffs(_pre)`."); } void ComputeLpResidual( rtc::ArrayView lpc_coeffs, rtc::ArrayView x, rtc::ArrayView y) { - RTC_DCHECK_LT(kNumLpcCoefficients, x.size()); + RTC_DCHECK_GT(x.size(), kNumLpcCoefficients); RTC_DCHECK_EQ(x.size(), y.size()); - std::array input_chunk; - input_chunk.fill(0.f); - for (size_t i = 0; i < y.size(); ++i) { - const float sum = std::inner_product(input_chunk.begin(), input_chunk.end(), - lpc_coeffs.begin(), x[i]); - // Circular shift and add a new sample. - for (size_t j = kNumLpcCoefficients - 1; j > 0; --j) - input_chunk[j] = input_chunk[j - 1]; - input_chunk[0] = x[i]; - // Copy result. - y[i] = sum; + // The code below implements the following operation: + // y[i] = x[i] + dot_product({x[i], ..., x[i - kNumLpcCoefficients + 1]}, + // lpc_coeffs) + // Edge case: i < kNumLpcCoefficients. + y[0] = x[0]; + for (int i = 1; i < kNumLpcCoefficients; ++i) { + y[i] = + std::inner_product(x.crend() - i, x.crend(), lpc_coeffs.cbegin(), x[i]); + } + // Regular case. + auto last = x.crend(); + for (int i = kNumLpcCoefficients; rtc::SafeLt(i, y.size()); ++i, --last) { + y[i] = std::inner_product(last - kNumLpcCoefficients, last, + lpc_coeffs.cbegin(), x[i]); } } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/lp_residual.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/lp_residual.h index cddedca5d..2e54dd93d 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/lp_residual.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/lp_residual.h @@ -19,7 +19,7 @@ namespace webrtc { namespace rnn_vad { // LPC inverse filter length. -constexpr size_t kNumLpcCoefficients = 5; +constexpr int kNumLpcCoefficients = 5; // Given a frame |x|, computes a post-processed version of LPC coefficients // tailored for pitch estimation. diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_info.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_info.h deleted file mode 100644 index c9fdd182b..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_info.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_PITCH_INFO_H_ -#define MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_PITCH_INFO_H_ - -namespace webrtc { -namespace rnn_vad { - -// Stores pitch period and gain information. The pitch gain measures the -// strength of the pitch (the higher, the stronger). -struct PitchInfo { - PitchInfo() : period(0), gain(0.f) {} - PitchInfo(int p, float g) : period(p), gain(g) {} - int period; - float gain; -}; - -} // namespace rnn_vad -} // namespace webrtc - -#endif // MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_PITCH_INFO_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search.cc index 1b3b459c5..c6c3e1b2b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search.cc @@ -19,37 +19,48 @@ namespace webrtc { namespace rnn_vad { PitchEstimator::PitchEstimator() - : pitch_buf_decimated_(kBufSize12kHz), - pitch_buf_decimated_view_(pitch_buf_decimated_.data(), kBufSize12kHz), - auto_corr_(kNumInvertedLags12kHz), - auto_corr_view_(auto_corr_.data(), kNumInvertedLags12kHz) { - RTC_DCHECK_EQ(kBufSize12kHz, pitch_buf_decimated_.size()); - RTC_DCHECK_EQ(kNumInvertedLags12kHz, auto_corr_view_.size()); -} + : y_energy_24kHz_(kRefineNumLags24kHz, 0.f), + pitch_buffer_12kHz_(kBufSize12kHz), + auto_correlation_12kHz_(kNumLags12kHz) {} PitchEstimator::~PitchEstimator() = default; -PitchInfo PitchEstimator::Estimate( - rtc::ArrayView pitch_buf) { +int PitchEstimator::Estimate( + rtc::ArrayView pitch_buffer) { + rtc::ArrayView pitch_buffer_12kHz_view( + pitch_buffer_12kHz_.data(), kBufSize12kHz); + RTC_DCHECK_EQ(pitch_buffer_12kHz_.size(), pitch_buffer_12kHz_view.size()); + rtc::ArrayView auto_correlation_12kHz_view( + auto_correlation_12kHz_.data(), kNumLags12kHz); + RTC_DCHECK_EQ(auto_correlation_12kHz_.size(), + auto_correlation_12kHz_view.size()); + // Perform the initial pitch search at 12 kHz. - Decimate2x(pitch_buf, pitch_buf_decimated_view_); - auto_corr_calculator_.ComputeOnPitchBuffer(pitch_buf_decimated_view_, - auto_corr_view_); - std::array pitch_candidates_inv_lags = FindBestPitchPeriods( - auto_corr_view_, pitch_buf_decimated_view_, kMaxPitch12kHz); - // Refine the pitch period estimation. + Decimate2x(pitch_buffer, pitch_buffer_12kHz_view); + auto_corr_calculator_.ComputeOnPitchBuffer(pitch_buffer_12kHz_view, + auto_correlation_12kHz_view); + CandidatePitchPeriods pitch_periods = ComputePitchPeriod12kHz( + pitch_buffer_12kHz_view, auto_correlation_12kHz_view); // The refinement is done using the pitch buffer that contains 24 kHz samples. // Therefore, adapt the inverted lags in |pitch_candidates_inv_lags| from 12 // to 24 kHz. - pitch_candidates_inv_lags[0] *= 2; - pitch_candidates_inv_lags[1] *= 2; - size_t pitch_inv_lag_48kHz = - RefinePitchPeriod48kHz(pitch_buf, pitch_candidates_inv_lags); - // Look for stronger harmonics to find the final pitch period and its gain. - RTC_DCHECK_LT(pitch_inv_lag_48kHz, kMaxPitch48kHz); - last_pitch_48kHz_ = CheckLowerPitchPeriodsAndComputePitchGain( - pitch_buf, kMaxPitch48kHz - pitch_inv_lag_48kHz, last_pitch_48kHz_); - return last_pitch_48kHz_; + pitch_periods.best *= 2; + pitch_periods.second_best *= 2; + + // Refine the initial pitch period estimation from 12 kHz to 48 kHz. + // Pre-compute frame energies at 24 kHz. + rtc::ArrayView y_energy_24kHz_view( + y_energy_24kHz_.data(), kRefineNumLags24kHz); + RTC_DCHECK_EQ(y_energy_24kHz_.size(), y_energy_24kHz_view.size()); + ComputeSlidingFrameSquareEnergies24kHz(pitch_buffer, y_energy_24kHz_view); + // Estimation at 48 kHz. + const int pitch_lag_48kHz = + ComputePitchPeriod48kHz(pitch_buffer, y_energy_24kHz_view, pitch_periods); + last_pitch_48kHz_ = ComputeExtendedPitchPeriod48kHz( + pitch_buffer, y_energy_24kHz_view, + /*initial_pitch_period_48kHz=*/kMaxPitch48kHz - pitch_lag_48kHz, + last_pitch_48kHz_); + return last_pitch_48kHz_.period; } } // namespace rnn_vad diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search.h index 74133d073..e96a2dcaf 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search.h @@ -17,8 +17,8 @@ #include "api/array_view.h" #include "modules/audio_processing/agc2/rnn_vad/auto_correlation.h" #include "modules/audio_processing/agc2/rnn_vad/common.h" -#include "modules/audio_processing/agc2/rnn_vad/pitch_info.h" #include "modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h" +#include "rtc_base/gtest_prod_util.h" namespace webrtc { namespace rnn_vad { @@ -30,17 +30,20 @@ class PitchEstimator { PitchEstimator(const PitchEstimator&) = delete; PitchEstimator& operator=(const PitchEstimator&) = delete; ~PitchEstimator(); - // Estimates the pitch period and gain. Returns the pitch estimation data for - // 48 kHz. - PitchInfo Estimate(rtc::ArrayView pitch_buf); + // Returns the estimated pitch period at 48 kHz. + int Estimate(rtc::ArrayView pitch_buffer); private: - PitchInfo last_pitch_48kHz_; + FRIEND_TEST_ALL_PREFIXES(RnnVadTest, PitchSearchWithinTolerance); + float GetLastPitchStrengthForTesting() const { + return last_pitch_48kHz_.strength; + } + + PitchInfo last_pitch_48kHz_{}; AutoCorrelationCalculator auto_corr_calculator_; - std::vector pitch_buf_decimated_; - rtc::ArrayView pitch_buf_decimated_view_; - std::vector auto_corr_; - rtc::ArrayView auto_corr_view_; + std::vector y_energy_24kHz_; + std::vector pitch_buffer_12kHz_; + std::vector auto_correlation_12kHz_; }; } // namespace rnn_vad diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.cc index f24a76f7b..262c38645 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.cc @@ -19,102 +19,77 @@ #include "modules/audio_processing/agc2/rnn_vad/common.h" #include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_compare.h" +#include "rtc_base/numerics/safe_conversions.h" namespace webrtc { namespace rnn_vad { namespace { -// Converts a lag to an inverted lag (only for 24kHz). -size_t GetInvertedLag(size_t lag) { - RTC_DCHECK_LE(lag, kMaxPitch24kHz); - return kMaxPitch24kHz - lag; -} - -float ComputeAutoCorrelationCoeff(rtc::ArrayView pitch_buf, - size_t inv_lag, - size_t max_pitch_period) { - RTC_DCHECK_LT(inv_lag, pitch_buf.size()); - RTC_DCHECK_LT(max_pitch_period, pitch_buf.size()); - RTC_DCHECK_LE(inv_lag, max_pitch_period); +float ComputeAutoCorrelation( + int inverted_lag, + rtc::ArrayView pitch_buffer) { + RTC_DCHECK_LT(inverted_lag, kBufSize24kHz); + RTC_DCHECK_LT(inverted_lag, kRefineNumLags24kHz); + static_assert(kMaxPitch24kHz < kBufSize24kHz, ""); // TODO(bugs.webrtc.org/9076): Maybe optimize using vectorization. - return std::inner_product(pitch_buf.begin() + max_pitch_period, - pitch_buf.end(), pitch_buf.begin() + inv_lag, 0.f); + return std::inner_product(pitch_buffer.begin() + kMaxPitch24kHz, + pitch_buffer.end(), + pitch_buffer.begin() + inverted_lag, 0.f); } -// Computes a pseudo-interpolation offset for an estimated pitch period |lag| by -// looking at the auto-correlation coefficients in the neighborhood of |lag|. -// (namely, |prev_auto_corr|, |lag_auto_corr| and |next_auto_corr|). The output -// is a lag in {-1, 0, +1}. -// TODO(bugs.webrtc.org/9076): Consider removing pseudo-i since it -// is relevant only if the spectral analysis works at a sample rate that is -// twice as that of the pitch buffer (not so important instead for the estimated -// pitch period feature fed into the RNN). -int GetPitchPseudoInterpolationOffset(size_t lag, - float prev_auto_corr, - float lag_auto_corr, - float next_auto_corr) { - const float& a = prev_auto_corr; - const float& b = lag_auto_corr; - const float& c = next_auto_corr; - - int offset = 0; - if ((c - a) > 0.7f * (b - a)) { - offset = 1; // |c| is the largest auto-correlation coefficient. - } else if ((a - c) > 0.7f * (b - c)) { - offset = -1; // |a| is the largest auto-correlation coefficient. +// Given an auto-correlation coefficient `curr_auto_correlation` and its +// neighboring values `prev_auto_correlation` and `next_auto_correlation` +// computes a pseudo-interpolation offset to be applied to the pitch period +// associated to `curr`. The output is a lag in {-1, 0, +1}. +// TODO(bugs.webrtc.org/9076): Consider removing this method. +// `GetPitchPseudoInterpolationOffset()` it is relevant only if the spectral +// analysis works at a sample rate that is twice as that of the pitch buffer; +// In particular, it is not relevant for the estimated pitch period feature fed +// into the RNN. +int GetPitchPseudoInterpolationOffset(float prev_auto_correlation, + float curr_auto_correlation, + float next_auto_correlation) { + if ((next_auto_correlation - prev_auto_correlation) > + 0.7f * (curr_auto_correlation - prev_auto_correlation)) { + return 1; // |next_auto_correlation| is the largest auto-correlation + // coefficient. + } else if ((prev_auto_correlation - next_auto_correlation) > + 0.7f * (curr_auto_correlation - next_auto_correlation)) { + return -1; // |prev_auto_correlation| is the largest auto-correlation + // coefficient. } - return offset; + return 0; } // Refines a pitch period |lag| encoded as lag with pseudo-interpolation. The // output sample rate is twice as that of |lag|. -size_t PitchPseudoInterpolationLagPitchBuf( - size_t lag, - rtc::ArrayView pitch_buf) { +int PitchPseudoInterpolationLagPitchBuf( + int lag, + rtc::ArrayView pitch_buffer) { int offset = 0; // Cannot apply pseudo-interpolation at the boundaries. if (lag > 0 && lag < kMaxPitch24kHz) { + const int inverted_lag = kMaxPitch24kHz - lag; offset = GetPitchPseudoInterpolationOffset( - lag, - ComputeAutoCorrelationCoeff(pitch_buf, GetInvertedLag(lag - 1), - kMaxPitch24kHz), - ComputeAutoCorrelationCoeff(pitch_buf, GetInvertedLag(lag), - kMaxPitch24kHz), - ComputeAutoCorrelationCoeff(pitch_buf, GetInvertedLag(lag + 1), - kMaxPitch24kHz)); + ComputeAutoCorrelation(inverted_lag + 1, pitch_buffer), + ComputeAutoCorrelation(inverted_lag, pitch_buffer), + ComputeAutoCorrelation(inverted_lag - 1, pitch_buffer)); } return 2 * lag + offset; } -// Refines a pitch period |inv_lag| encoded as inverted lag with -// pseudo-interpolation. The output sample rate is twice as that of -// |inv_lag|. -size_t PitchPseudoInterpolationInvLagAutoCorr( - size_t inv_lag, - rtc::ArrayView auto_corr) { - int offset = 0; - // Cannot apply pseudo-interpolation at the boundaries. - if (inv_lag > 0 && inv_lag < auto_corr.size() - 1) { - offset = GetPitchPseudoInterpolationOffset(inv_lag, auto_corr[inv_lag + 1], - auto_corr[inv_lag], - auto_corr[inv_lag - 1]); - } - // TODO(bugs.webrtc.org/9076): When retraining, check if |offset| below should - // be subtracted since |inv_lag| is an inverted lag but offset is a lag. - return 2 * inv_lag + offset; -} - -// Integer multipliers used in CheckLowerPitchPeriodsAndComputePitchGain() when +// Integer multipliers used in ComputeExtendedPitchPeriod48kHz() when // looking for sub-harmonics. // The values have been chosen to serve the following algorithm. Given the // initial pitch period T, we examine whether one of its harmonics is the true // fundamental frequency. We consider T/k with k in {2, ..., 15}. For each of -// these harmonics, in addition to the pitch gain of itself, we choose one +// these harmonics, in addition to the pitch strength of itself, we choose one // multiple of its pitch period, n*T/k, to validate it (by averaging their pitch -// gains). The multiplier n is chosen so that n*T/k is used only one time over -// all k. When for example k = 4, we should also expect a peak at 3*T/4. When -// k = 8 instead we don't want to look at 2*T/8, since we have already checked -// T/4 before. Instead, we look at T*3/8. +// strengths). The multiplier n is chosen so that n*T/k is used only one time +// over all k. When for example k = 4, we should also expect a peak at 3*T/4. +// When k = 8 instead we don't want to look at 2*T/8, since we have already +// checked T/4 before. Instead, we look at T*3/8. // The array can be generate in Python as follows: // from fractions import Fraction // # Smallest positive integer not in X. @@ -131,96 +106,215 @@ size_t PitchPseudoInterpolationInvLagAutoCorr( constexpr std::array kSubHarmonicMultipliers = { {3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}}; -// Initial pitch period candidate thresholds for ComputePitchGainThreshold() for -// a sample rate of 24 kHz. Computed as [5*k*k for k in range(16)]. -constexpr std::array kInitialPitchPeriodThresholds = { - {20, 45, 80, 125, 180, 245, 320, 405, 500, 605, 720, 845, 980, 1125}}; +struct Range { + int min; + int max; +}; + +// Number of analyzed pitches to the left(right) of a pitch candidate. +constexpr int kPitchNeighborhoodRadius = 2; + +// Creates a pitch period interval centered in `inverted_lag` with hard-coded +// radius. Clipping is applied so that the interval is always valid for a 24 kHz +// pitch buffer. +Range CreateInvertedLagRange(int inverted_lag) { + return {std::max(inverted_lag - kPitchNeighborhoodRadius, 0), + std::min(inverted_lag + kPitchNeighborhoodRadius, + kInitialNumLags24kHz - 1)}; +} + +constexpr int kNumPitchCandidates = 2; // Best and second best. +// Maximum number of analyzed pitch periods. +constexpr int kMaxPitchPeriods24kHz = + kNumPitchCandidates * (2 * kPitchNeighborhoodRadius + 1); + +// Collection of inverted lags. +class InvertedLagsIndex { + public: + InvertedLagsIndex() : num_entries_(0) {} + // Adds an inverted lag to the index. Cannot add more than + // `kMaxPitchPeriods24kHz` values. + void Append(int inverted_lag) { + RTC_DCHECK_LT(num_entries_, kMaxPitchPeriods24kHz); + inverted_lags_[num_entries_++] = inverted_lag; + } + const int* data() const { return inverted_lags_.data(); } + int size() const { return num_entries_; } + + private: + std::array inverted_lags_; + int num_entries_; +}; + +// Computes the auto correlation coefficients for the inverted lags in the +// closed interval `inverted_lags`. Updates `inverted_lags_index` by appending +// the inverted lags for the computed auto correlation values. +void ComputeAutoCorrelation( + Range inverted_lags, + rtc::ArrayView pitch_buffer, + rtc::ArrayView auto_correlation, + InvertedLagsIndex& inverted_lags_index) { + // Check valid range. + RTC_DCHECK_LE(inverted_lags.min, inverted_lags.max); + // Trick to avoid zero initialization of `auto_correlation`. + // Needed by the pseudo-interpolation. + if (inverted_lags.min > 0) { + auto_correlation[inverted_lags.min - 1] = 0.f; + } + if (inverted_lags.max < kInitialNumLags24kHz - 1) { + auto_correlation[inverted_lags.max + 1] = 0.f; + } + // Check valid `inverted_lag` indexes. + RTC_DCHECK_GE(inverted_lags.min, 0); + RTC_DCHECK_LT(inverted_lags.max, kInitialNumLags24kHz); + for (int inverted_lag = inverted_lags.min; inverted_lag <= inverted_lags.max; + ++inverted_lag) { + auto_correlation[inverted_lag] = + ComputeAutoCorrelation(inverted_lag, pitch_buffer); + inverted_lags_index.Append(inverted_lag); + } +} + +// Searches the strongest pitch period at 24 kHz and returns its inverted lag at +// 48 kHz. +int ComputePitchPeriod48kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView inverted_lags, + rtc::ArrayView auto_correlation, + rtc::ArrayView y_energy) { + static_assert(kMaxPitch24kHz > kInitialNumLags24kHz, ""); + static_assert(kMaxPitch24kHz < kBufSize24kHz, ""); + int best_inverted_lag = 0; // Pitch period. + float best_numerator = -1.f; // Pitch strength numerator. + float best_denominator = 0.f; // Pitch strength denominator. + for (int inverted_lag : inverted_lags) { + // A pitch candidate must have positive correlation. + if (auto_correlation[inverted_lag] > 0.f) { + // Auto-correlation energy normalized by frame energy. + const float numerator = + auto_correlation[inverted_lag] * auto_correlation[inverted_lag]; + const float denominator = y_energy[inverted_lag]; + // Compare numerator/denominator ratios without using divisions. + if (numerator * best_denominator > best_numerator * denominator) { + best_inverted_lag = inverted_lag; + best_numerator = numerator; + best_denominator = denominator; + } + } + } + // Pseudo-interpolation to transform `best_inverted_lag` (24 kHz pitch) to a + // 48 kHz pitch period. + if (best_inverted_lag == 0 || best_inverted_lag >= kInitialNumLags24kHz - 1) { + // Cannot apply pseudo-interpolation at the boundaries. + return best_inverted_lag * 2; + } + int offset = GetPitchPseudoInterpolationOffset( + auto_correlation[best_inverted_lag + 1], + auto_correlation[best_inverted_lag], + auto_correlation[best_inverted_lag - 1]); + // TODO(bugs.webrtc.org/9076): When retraining, check if |offset| below should + // be subtracted since |inverted_lag| is an inverted lag but offset is a lag. + return 2 * best_inverted_lag + offset; +} + +// Returns an alternative pitch period for `pitch_period` given a `multiplier` +// and a `divisor` of the period. +constexpr int GetAlternativePitchPeriod(int pitch_period, + int multiplier, + int divisor) { + RTC_DCHECK_GT(divisor, 0); + // Same as `round(multiplier * pitch_period / divisor)`. + return (2 * multiplier * pitch_period + divisor) / (2 * divisor); +} + +// Returns true if the alternative pitch period is stronger than the initial one +// given the last estimated pitch and the value of `period_divisor` used to +// compute the alternative pitch period via `GetAlternativePitchPeriod()`. +bool IsAlternativePitchStrongerThanInitial(PitchInfo last, + PitchInfo initial, + PitchInfo alternative, + int period_divisor) { + // Initial pitch period candidate thresholds for a sample rate of 24 kHz. + // Computed as [5*k*k for k in range(16)]. + constexpr std::array kInitialPitchPeriodThresholds = { + {20, 45, 80, 125, 180, 245, 320, 405, 500, 605, 720, 845, 980, 1125}}; + static_assert( + kInitialPitchPeriodThresholds.size() == kSubHarmonicMultipliers.size(), + ""); + RTC_DCHECK_GE(last.period, 0); + RTC_DCHECK_GE(initial.period, 0); + RTC_DCHECK_GE(alternative.period, 0); + RTC_DCHECK_GE(period_divisor, 2); + // Compute a term that lowers the threshold when |alternative.period| is close + // to the last estimated period |last.period| - i.e., pitch tracking. + float lower_threshold_term = 0.f; + if (std::abs(alternative.period - last.period) <= 1) { + // The candidate pitch period is within 1 sample from the last one. + // Make the candidate at |alternative.period| very easy to be accepted. + lower_threshold_term = last.strength; + } else if (std::abs(alternative.period - last.period) == 2 && + initial.period > + kInitialPitchPeriodThresholds[period_divisor - 2]) { + // The candidate pitch period is 2 samples far from the last one and the + // period |initial.period| (from which |alternative.period| has been + // derived) is greater than a threshold. Make |alternative.period| easy to + // be accepted. + lower_threshold_term = 0.5f * last.strength; + } + // Set the threshold based on the strength of the initial estimate + // |initial.period|. Also reduce the chance of false positives caused by a + // bias towards high frequencies (originating from short-term correlations). + float threshold = + std::max(0.3f, 0.7f * initial.strength - lower_threshold_term); + if (alternative.period < 3 * kMinPitch24kHz) { + // High frequency. + threshold = std::max(0.4f, 0.85f * initial.strength - lower_threshold_term); + } else if (alternative.period < 2 * kMinPitch24kHz) { + // Even higher frequency. + threshold = std::max(0.5f, 0.9f * initial.strength - lower_threshold_term); + } + return alternative.strength > threshold; +} } // namespace void Decimate2x(rtc::ArrayView src, rtc::ArrayView dst) { // TODO(bugs.webrtc.org/9076): Consider adding anti-aliasing filter. - static_assert(2 * dst.size() == src.size(), ""); - for (size_t i = 0; i < dst.size(); ++i) { + static_assert(2 * kBufSize12kHz == kBufSize24kHz, ""); + for (int i = 0; i < kBufSize12kHz; ++i) { dst[i] = src[2 * i]; } } -float ComputePitchGainThreshold(int candidate_pitch_period, - int pitch_period_ratio, - int initial_pitch_period, - float initial_pitch_gain, - int prev_pitch_period, - float prev_pitch_gain) { - // Map arguments to more compact aliases. - const int& t1 = candidate_pitch_period; - const int& k = pitch_period_ratio; - const int& t0 = initial_pitch_period; - const float& g0 = initial_pitch_gain; - const int& t_prev = prev_pitch_period; - const float& g_prev = prev_pitch_gain; - - // Validate input. - RTC_DCHECK_GE(t1, 0); - RTC_DCHECK_GE(k, 2); - RTC_DCHECK_GE(t0, 0); - RTC_DCHECK_GE(t_prev, 0); - - // Compute a term that lowers the threshold when |t1| is close to the last - // estimated period |t_prev| - i.e., pitch tracking. - float lower_threshold_term = 0; - if (abs(t1 - t_prev) <= 1) { - // The candidate pitch period is within 1 sample from the previous one. - // Make the candidate at |t1| very easy to be accepted. - lower_threshold_term = g_prev; - } else if (abs(t1 - t_prev) == 2 && - t0 > kInitialPitchPeriodThresholds[k - 2]) { - // The candidate pitch period is 2 samples far from the previous one and the - // period |t0| (from which |t1| has been derived) is greater than a - // threshold. Make |t1| easy to be accepted. - lower_threshold_term = 0.5f * g_prev; - } - // Set the threshold based on the gain of the initial estimate |t0|. Also - // reduce the chance of false positives caused by a bias towards high - // frequencies (originating from short-term correlations). - float threshold = std::max(0.3f, 0.7f * g0 - lower_threshold_term); - if (static_cast(t1) < 3 * kMinPitch24kHz) { - // High frequency. - threshold = std::max(0.4f, 0.85f * g0 - lower_threshold_term); - } else if (static_cast(t1) < 2 * kMinPitch24kHz) { - // Even higher frequency. - threshold = std::max(0.5f, 0.9f * g0 - lower_threshold_term); - } - return threshold; -} - -void ComputeSlidingFrameSquareEnergies( - rtc::ArrayView pitch_buf, - rtc::ArrayView yy_values) { - float yy = - ComputeAutoCorrelationCoeff(pitch_buf, kMaxPitch24kHz, kMaxPitch24kHz); - yy_values[0] = yy; - for (size_t i = 1; i < yy_values.size(); ++i) { - RTC_DCHECK_LE(i, kMaxPitch24kHz + kFrameSize20ms24kHz); - RTC_DCHECK_LE(i, kMaxPitch24kHz); - const float old_coeff = pitch_buf[kMaxPitch24kHz + kFrameSize20ms24kHz - i]; - const float new_coeff = pitch_buf[kMaxPitch24kHz - i]; - yy -= old_coeff * old_coeff; - yy += new_coeff * new_coeff; - yy = std::max(0.f, yy); - yy_values[i] = yy; +void ComputeSlidingFrameSquareEnergies24kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView y_energy) { + float yy = std::inner_product(pitch_buffer.begin(), + pitch_buffer.begin() + kFrameSize20ms24kHz, + pitch_buffer.begin(), 0.f); + y_energy[0] = yy; + static_assert(kMaxPitch24kHz - 1 + kFrameSize20ms24kHz < kBufSize24kHz, ""); + static_assert(kMaxPitch24kHz < kRefineNumLags24kHz, ""); + for (int inverted_lag = 0; inverted_lag < kMaxPitch24kHz; ++inverted_lag) { + yy -= pitch_buffer[inverted_lag] * pitch_buffer[inverted_lag]; + yy += pitch_buffer[inverted_lag + kFrameSize20ms24kHz] * + pitch_buffer[inverted_lag + kFrameSize20ms24kHz]; + yy = std::max(1.f, yy); + y_energy[inverted_lag + 1] = yy; } } -std::array FindBestPitchPeriods( - rtc::ArrayView auto_corr, - rtc::ArrayView pitch_buf, - size_t max_pitch_period) { +CandidatePitchPeriods ComputePitchPeriod12kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView auto_correlation) { + static_assert(kMaxPitch12kHz > kNumLags12kHz, ""); + static_assert(kMaxPitch12kHz < kBufSize12kHz, ""); + // Stores a pitch candidate period and strength information. struct PitchCandidate { // Pitch period encoded as inverted lag. - size_t period_inverted_lag = 0; + int period_inverted_lag = 0; // Pitch strength encoded as a ratio. float strength_numerator = -1.f; float strength_denominator = 0.f; @@ -232,25 +326,22 @@ std::array FindBestPitchPeriods( } }; - RTC_DCHECK_GT(max_pitch_period, auto_corr.size()); - RTC_DCHECK_LT(max_pitch_period, pitch_buf.size()); - const size_t frame_size = pitch_buf.size() - max_pitch_period; // TODO(bugs.webrtc.org/9076): Maybe optimize using vectorization. - float yy = - std::inner_product(pitch_buf.begin(), pitch_buf.begin() + frame_size + 1, - pitch_buf.begin(), 1.f); + float denominator = std::inner_product( + pitch_buffer.begin(), pitch_buffer.begin() + kFrameSize20ms12kHz + 1, + pitch_buffer.begin(), 1.f); // Search best and second best pitches by looking at the scaled // auto-correlation. - PitchCandidate candidate; PitchCandidate best; PitchCandidate second_best; second_best.period_inverted_lag = 1; - for (size_t inv_lag = 0; inv_lag < auto_corr.size(); ++inv_lag) { + for (int inverted_lag = 0; inverted_lag < kNumLags12kHz; ++inverted_lag) { // A pitch candidate must have positive correlation. - if (auto_corr[inv_lag] > 0) { - candidate.period_inverted_lag = inv_lag; - candidate.strength_numerator = auto_corr[inv_lag] * auto_corr[inv_lag]; - candidate.strength_denominator = yy; + if (auto_correlation[inverted_lag] > 0.f) { + PitchCandidate candidate{ + inverted_lag, + auto_correlation[inverted_lag] * auto_correlation[inverted_lag], + denominator}; if (candidate.HasStrongerPitchThan(second_best)) { if (candidate.HasStrongerPitchThan(best)) { second_best = best; @@ -261,142 +352,147 @@ std::array FindBestPitchPeriods( } } // Update |squared_energy_y| for the next inverted lag. - const float old_coeff = pitch_buf[inv_lag]; - const float new_coeff = pitch_buf[inv_lag + frame_size]; - yy -= old_coeff * old_coeff; - yy += new_coeff * new_coeff; - yy = std::max(0.f, yy); + const float y_old = pitch_buffer[inverted_lag]; + const float y_new = pitch_buffer[inverted_lag + kFrameSize20ms12kHz]; + denominator -= y_old * y_old; + denominator += y_new * y_new; + denominator = std::max(0.f, denominator); } - return {{best.period_inverted_lag, second_best.period_inverted_lag}}; + return {best.period_inverted_lag, second_best.period_inverted_lag}; } -size_t RefinePitchPeriod48kHz( - rtc::ArrayView pitch_buf, - rtc::ArrayView inv_lags) { - // Compute the auto-correlation terms only for neighbors of the given pitch - // candidates (similar to what is done in ComputePitchAutoCorrelation(), but - // for a few lag values). - std::array auto_corr; - auto_corr.fill(0.f); // Zeros become ignored lags in FindBestPitchPeriods(). - auto is_neighbor = [](size_t i, size_t j) { - return ((i > j) ? (i - j) : (j - i)) <= 2; - }; - for (size_t inv_lag = 0; inv_lag < auto_corr.size(); ++inv_lag) { - if (is_neighbor(inv_lag, inv_lags[0]) || is_neighbor(inv_lag, inv_lags[1])) - auto_corr[inv_lag] = - ComputeAutoCorrelationCoeff(pitch_buf, inv_lag, kMaxPitch24kHz); +int ComputePitchPeriod48kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView y_energy, + CandidatePitchPeriods pitch_candidates) { + // Compute the auto-correlation terms only for neighbors of the two pitch + // candidates (best and second best). + std::array auto_correlation; + InvertedLagsIndex inverted_lags_index; + // Create two inverted lag ranges so that `r1` precedes `r2`. + const bool swap_candidates = + pitch_candidates.best > pitch_candidates.second_best; + const Range r1 = CreateInvertedLagRange( + swap_candidates ? pitch_candidates.second_best : pitch_candidates.best); + const Range r2 = CreateInvertedLagRange( + swap_candidates ? pitch_candidates.best : pitch_candidates.second_best); + // Check valid ranges. + RTC_DCHECK_LE(r1.min, r1.max); + RTC_DCHECK_LE(r2.min, r2.max); + // Check `r1` precedes `r2`. + RTC_DCHECK_LE(r1.min, r2.min); + RTC_DCHECK_LE(r1.max, r2.max); + if (r1.max + 1 >= r2.min) { + // Overlapping or adjacent ranges. + ComputeAutoCorrelation({r1.min, r2.max}, pitch_buffer, auto_correlation, + inverted_lags_index); + } else { + // Disjoint ranges. + ComputeAutoCorrelation(r1, pitch_buffer, auto_correlation, + inverted_lags_index); + ComputeAutoCorrelation(r2, pitch_buffer, auto_correlation, + inverted_lags_index); } - // Find best pitch at 24 kHz. - const auto pitch_candidates_inv_lags = FindBestPitchPeriods( - {auto_corr.data(), auto_corr.size()}, - {pitch_buf.data(), pitch_buf.size()}, kMaxPitch24kHz); - const auto inv_lag = pitch_candidates_inv_lags[0]; // Refine the best. - // Pseudo-interpolation. - return PitchPseudoInterpolationInvLagAutoCorr(inv_lag, auto_corr); + return ComputePitchPeriod48kHz(pitch_buffer, inverted_lags_index, + auto_correlation, y_energy); } -PitchInfo CheckLowerPitchPeriodsAndComputePitchGain( - rtc::ArrayView pitch_buf, +PitchInfo ComputeExtendedPitchPeriod48kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView y_energy, int initial_pitch_period_48kHz, - PitchInfo prev_pitch_48kHz) { + PitchInfo last_pitch_48kHz) { RTC_DCHECK_LE(kMinPitch48kHz, initial_pitch_period_48kHz); RTC_DCHECK_LE(initial_pitch_period_48kHz, kMaxPitch48kHz); + // Stores information for a refined pitch candidate. struct RefinedPitchCandidate { - RefinedPitchCandidate() {} - RefinedPitchCandidate(int period_24kHz, float gain, float xy, float yy) - : period_24kHz(period_24kHz), gain(gain), xy(xy), yy(yy) {} - int period_24kHz; - // Pitch strength information. - float gain; - // Additional pitch strength information used for the final estimation of - // pitch gain. - float xy; // Cross-correlation. - float yy; // Auto-correlation. + int period; + float strength; + // Additional strength data used for the final pitch estimation. + float xy; // Auto-correlation. + float y_energy; // Energy of the sliding frame `y`. }; - // Initialize. - std::array yy_values; - ComputeSlidingFrameSquareEnergies(pitch_buf, - {yy_values.data(), yy_values.size()}); - const float xx = yy_values[0]; - // Helper lambdas. - const auto pitch_gain = [](float xy, float yy, float xx) { - RTC_DCHECK_LE(0.f, xx * yy); - return xy / std::sqrt(1.f + xx * yy); + const float x_energy = y_energy[kMaxPitch24kHz]; + const auto pitch_strength = [x_energy](float xy, float y_energy) { + RTC_DCHECK_GE(x_energy * y_energy, 0.f); + return xy / std::sqrt(1.f + x_energy * y_energy); }; - // Initial pitch candidate gain. + + // Initialize the best pitch candidate with `initial_pitch_period_48kHz`. RefinedPitchCandidate best_pitch; - best_pitch.period_24kHz = std::min(initial_pitch_period_48kHz / 2, - static_cast(kMaxPitch24kHz - 1)); - best_pitch.xy = ComputeAutoCorrelationCoeff( - pitch_buf, GetInvertedLag(best_pitch.period_24kHz), kMaxPitch24kHz); - best_pitch.yy = yy_values[best_pitch.period_24kHz]; - best_pitch.gain = pitch_gain(best_pitch.xy, best_pitch.yy, xx); + best_pitch.period = + std::min(initial_pitch_period_48kHz / 2, kMaxPitch24kHz - 1); + best_pitch.xy = + ComputeAutoCorrelation(kMaxPitch24kHz - best_pitch.period, pitch_buffer); + best_pitch.y_energy = y_energy[kMaxPitch24kHz - best_pitch.period]; + best_pitch.strength = pitch_strength(best_pitch.xy, best_pitch.y_energy); + // Keep a copy of the initial pitch candidate. + const PitchInfo initial_pitch{best_pitch.period, best_pitch.strength}; + // 24 kHz version of the last estimated pitch. + const PitchInfo last_pitch{last_pitch_48kHz.period / 2, + last_pitch_48kHz.strength}; - // Store the initial pitch period information. - const size_t initial_pitch_period = best_pitch.period_24kHz; - const float initial_pitch_gain = best_pitch.gain; - - // Given the initial pitch estimation, check lower periods (i.e., harmonics). - const auto alternative_period = [](int period, int k, int n) -> int { - RTC_DCHECK_GT(k, 0); - return (2 * n * period + k) / (2 * k); // Same as round(n*period/k). - }; - for (int k = 2; k < static_cast(kSubHarmonicMultipliers.size() + 2); - ++k) { - int candidate_pitch_period = alternative_period(initial_pitch_period, k, 1); - if (static_cast(candidate_pitch_period) < kMinPitch24kHz) { - break; - } - // When looking at |candidate_pitch_period|, we also look at one of its + // Find `max_period_divisor` such that the result of + // `GetAlternativePitchPeriod(initial_pitch_period, 1, max_period_divisor)` + // equals `kMinPitch24kHz`. + const int max_period_divisor = + (2 * initial_pitch.period) / (2 * kMinPitch24kHz - 1); + for (int period_divisor = 2; period_divisor <= max_period_divisor; + ++period_divisor) { + PitchInfo alternative_pitch; + alternative_pitch.period = GetAlternativePitchPeriod( + initial_pitch.period, /*multiplier=*/1, period_divisor); + RTC_DCHECK_GE(alternative_pitch.period, kMinPitch24kHz); + // When looking at |alternative_pitch.period|, we also look at one of its // sub-harmonics. |kSubHarmonicMultipliers| is used to know where to look. - // |k| == 2 is a special case since |candidate_pitch_secondary_period| might - // be greater than the maximum pitch period. - int candidate_pitch_secondary_period = alternative_period( - initial_pitch_period, k, kSubHarmonicMultipliers[k - 2]); - RTC_DCHECK_GT(candidate_pitch_secondary_period, 0); - if (k == 2 && - candidate_pitch_secondary_period > static_cast(kMaxPitch24kHz)) { - candidate_pitch_secondary_period = initial_pitch_period; + // |period_divisor| == 2 is a special case since |dual_alternative_period| + // might be greater than the maximum pitch period. + int dual_alternative_period = GetAlternativePitchPeriod( + initial_pitch.period, kSubHarmonicMultipliers[period_divisor - 2], + period_divisor); + RTC_DCHECK_GT(dual_alternative_period, 0); + if (period_divisor == 2 && dual_alternative_period > kMaxPitch24kHz) { + dual_alternative_period = initial_pitch.period; } - RTC_DCHECK_NE(candidate_pitch_period, candidate_pitch_secondary_period) + RTC_DCHECK_NE(alternative_pitch.period, dual_alternative_period) << "The lower pitch period and the additional sub-harmonic must not " "coincide."; // Compute an auto-correlation score for the primary pitch candidate - // |candidate_pitch_period| by also looking at its possible sub-harmonic - // |candidate_pitch_secondary_period|. - float xy_primary_period = ComputeAutoCorrelationCoeff( - pitch_buf, GetInvertedLag(candidate_pitch_period), kMaxPitch24kHz); - float xy_secondary_period = ComputeAutoCorrelationCoeff( - pitch_buf, GetInvertedLag(candidate_pitch_secondary_period), - kMaxPitch24kHz); - float xy = 0.5f * (xy_primary_period + xy_secondary_period); - float yy = 0.5f * (yy_values[candidate_pitch_period] + - yy_values[candidate_pitch_secondary_period]); - float candidate_pitch_gain = pitch_gain(xy, yy, xx); + // |alternative_pitch.period| by also looking at its possible sub-harmonic + // |dual_alternative_period|. + const float xy_primary_period = ComputeAutoCorrelation( + kMaxPitch24kHz - alternative_pitch.period, pitch_buffer); + const float xy_secondary_period = ComputeAutoCorrelation( + kMaxPitch24kHz - dual_alternative_period, pitch_buffer); + const float xy = 0.5f * (xy_primary_period + xy_secondary_period); + const float yy = + 0.5f * (y_energy[kMaxPitch24kHz - alternative_pitch.period] + + y_energy[kMaxPitch24kHz - dual_alternative_period]); + alternative_pitch.strength = pitch_strength(xy, yy); // Maybe update best period. - float threshold = ComputePitchGainThreshold( - candidate_pitch_period, k, initial_pitch_period, initial_pitch_gain, - prev_pitch_48kHz.period / 2, prev_pitch_48kHz.gain); - if (candidate_pitch_gain > threshold) { - best_pitch = {candidate_pitch_period, candidate_pitch_gain, xy, yy}; + if (IsAlternativePitchStrongerThanInitial( + last_pitch, initial_pitch, alternative_pitch, period_divisor)) { + best_pitch = {alternative_pitch.period, alternative_pitch.strength, xy, + yy}; } } - // Final pitch gain and period. + // Final pitch strength and period. best_pitch.xy = std::max(0.f, best_pitch.xy); - RTC_DCHECK_LE(0.f, best_pitch.yy); - float final_pitch_gain = (best_pitch.yy <= best_pitch.xy) - ? 1.f - : best_pitch.xy / (best_pitch.yy + 1.f); - final_pitch_gain = std::min(best_pitch.gain, final_pitch_gain); + RTC_DCHECK_LE(0.f, best_pitch.y_energy); + float final_pitch_strength = + (best_pitch.y_energy <= best_pitch.xy) + ? 1.f + : best_pitch.xy / (best_pitch.y_energy + 1.f); + final_pitch_strength = std::min(best_pitch.strength, final_pitch_strength); int final_pitch_period_48kHz = std::max( kMinPitch48kHz, - PitchPseudoInterpolationLagPitchBuf(best_pitch.period_24kHz, pitch_buf)); + PitchPseudoInterpolationLagPitchBuf(best_pitch.period, pitch_buffer)); - return {final_pitch_period_48kHz, final_pitch_gain}; + return {final_pitch_period_48kHz, final_pitch_strength}; } } // namespace rnn_vad diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h index 2cc5ce6af..0af55f8e6 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h @@ -14,10 +14,10 @@ #include #include +#include #include "api/array_view.h" #include "modules/audio_processing/agc2/rnn_vad/common.h" -#include "modules/audio_processing/agc2/rnn_vad/pitch_info.h" namespace webrtc { namespace rnn_vad { @@ -26,50 +26,82 @@ namespace rnn_vad { void Decimate2x(rtc::ArrayView src, rtc::ArrayView dst); -// Computes a gain threshold for a candidate pitch period given the initial and -// the previous pitch period and gain estimates and the pitch period ratio used -// to derive the candidate pitch period from the initial period. -float ComputePitchGainThreshold(int candidate_pitch_period, - int pitch_period_ratio, - int initial_pitch_period, - float initial_pitch_gain, - int prev_pitch_period, - float prev_pitch_gain); - -// Computes the sum of squared samples for every sliding frame in the pitch -// buffer. |yy_values| indexes are lags. +// Key concepts and keywords used below in this file. // -// The pitch buffer is structured as depicted below: -// |.........|...........| -// a b -// The part on the left, named "a" contains the oldest samples, whereas "b" the -// most recent ones. The size of "a" corresponds to the maximum pitch period, -// that of "b" to the frame size (e.g., 16 ms and 20 ms respectively). -void ComputeSlidingFrameSquareEnergies( - rtc::ArrayView pitch_buf, - rtc::ArrayView yy_values); +// The pitch estimation relies on a pitch buffer, which is an array-like data +// structured designed as follows: +// +// |....A....|.....B.....| +// +// The part on the left, named `A` contains the oldest samples, whereas `B` +// contains the most recent ones. The size of `A` corresponds to the maximum +// pitch period, that of `B` to the analysis frame size (e.g., 16 ms and 20 ms +// respectively). +// +// Pitch estimation is essentially based on the analysis of two 20 ms frames +// extracted from the pitch buffer. One frame, called `x`, is kept fixed and +// corresponds to `B` - i.e., the most recent 20 ms. The other frame, called +// `y`, is extracted from different parts of the buffer instead. +// +// The offset between `x` and `y` corresponds to a specific pitch period. +// For instance, if `y` is positioned at the beginning of the pitch buffer, then +// the cross-correlation between `x` and `y` can be used as an indication of the +// strength for the maximum pitch. +// +// Such an offset can be encoded in two ways: +// - As a lag, which is the index in the pitch buffer for the first item in `y` +// - As an inverted lag, which is the number of samples from the beginning of +// `x` and the end of `y` +// +// |---->| lag +// |....A....|.....B.....| +// |<--| inverted lag +// |.....y.....| `y` 20 ms frame +// +// The inverted lag has the advantage of being directly proportional to the +// corresponding pitch period. -// Given the auto-correlation coefficients stored according to -// ComputePitchAutoCorrelation() (i.e., using inverted lags), returns the best -// and the second best pitch periods. -std::array FindBestPitchPeriods( - rtc::ArrayView auto_corr, - rtc::ArrayView pitch_buf, - size_t max_pitch_period); +// Computes the sum of squared samples for every sliding frame `y` in the pitch +// buffer. The indexes of `y_energy` are inverted lags. +void ComputeSlidingFrameSquareEnergies24kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView y_energy); -// Refines the pitch period estimation given the pitch buffer |pitch_buf| and -// the initial pitch period estimation |inv_lags|. Returns an inverted lag at -// 48 kHz. -size_t RefinePitchPeriod48kHz( - rtc::ArrayView pitch_buf, - rtc::ArrayView inv_lags); +// Top-2 pitch period candidates. Unit: number of samples - i.e., inverted lags. +struct CandidatePitchPeriods { + int best; + int second_best; +}; -// Refines the pitch period estimation and compute the pitch gain. Returns the -// refined pitch estimation data at 48 kHz. -PitchInfo CheckLowerPitchPeriodsAndComputePitchGain( - rtc::ArrayView pitch_buf, +// Computes the candidate pitch periods at 12 kHz given a view on the 12 kHz +// pitch buffer and the auto-correlation values (having inverted lags as +// indexes). +CandidatePitchPeriods ComputePitchPeriod12kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView auto_correlation); + +// Computes the pitch period at 48 kHz given a view on the 24 kHz pitch buffer, +// the energies for the sliding frames `y` at 24 kHz and the pitch period +// candidates at 24 kHz (encoded as inverted lag). +int ComputePitchPeriod48kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView y_energy, + CandidatePitchPeriods pitch_candidates_24kHz); + +struct PitchInfo { + int period; + float strength; +}; + +// Computes the pitch period at 48 kHz searching in an extended pitch range +// given a view on the 24 kHz pitch buffer, the energies for the sliding frames +// `y` at 24 kHz, the initial 48 kHz estimation (computed by +// `ComputePitchPeriod48kHz()`) and the last estimated pitch. +PitchInfo ComputeExtendedPitchPeriod48kHz( + rtc::ArrayView pitch_buffer, + rtc::ArrayView y_energy, int initial_pitch_period_48kHz, - PitchInfo prev_pitch_48kHz); + PitchInfo last_pitch_48kHz); } // namespace rnn_vad } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/ring_buffer.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/ring_buffer.h index 294b0c0ba..f0270af91 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/ring_buffer.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/ring_buffer.h @@ -21,7 +21,7 @@ namespace webrtc { namespace rnn_vad { // Ring buffer for N arrays of type T each one with size S. -template +template class RingBuffer { static_assert(S > 0, ""); static_assert(N > 0, ""); @@ -45,11 +45,10 @@ class RingBuffer { // Return an array view onto the array with a given delay. A view on the last // and least recently push array is returned when |delay| is 0 and N - 1 // respectively. - rtc::ArrayView GetArrayView(size_t delay) const { - const int delay_int = static_cast(delay); - RTC_DCHECK_LE(0, delay_int); - RTC_DCHECK_LT(delay_int, N); - int offset = tail_ - 1 - delay_int; + rtc::ArrayView GetArrayView(int delay) const { + RTC_DCHECK_LE(0, delay); + RTC_DCHECK_LT(delay, N); + int offset = tail_ - 1 - delay; if (offset < 0) offset += N; return {buffer_.data() + S * offset, S}; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn.cc index 55a51ffa4..2072a6854 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn.cc @@ -26,6 +26,7 @@ #include "rtc_base/checks.h" #include "rtc_base/logging.h" +#include "rtc_base/numerics/safe_conversions.h" #include "third_party/rnnoise/src/rnn_activations.h" #include "third_party/rnnoise/src/rnn_vad_weights.h" @@ -77,15 +78,16 @@ std::vector GetScaledParams(rtc::ArrayView params) { // Casts and scales |weights| and re-arranges the layout. std::vector GetPreprocessedFcWeights( rtc::ArrayView weights, - size_t output_size) { + int output_size) { if (output_size == 1) { return GetScaledParams(weights); } // Transpose, scale and cast. - const size_t input_size = rtc::CheckedDivExact(weights.size(), output_size); + const int input_size = rtc::CheckedDivExact( + rtc::dchecked_cast(weights.size()), output_size); std::vector w(weights.size()); - for (size_t o = 0; o < output_size; ++o) { - for (size_t i = 0; i < input_size; ++i) { + for (int o = 0; o < output_size; ++o) { + for (int i = 0; i < input_size; ++i) { w[o * input_size + i] = rnnoise::kWeightsScale * static_cast(weights[i * output_size + o]); } @@ -93,7 +95,7 @@ std::vector GetPreprocessedFcWeights( return w; } -constexpr size_t kNumGruGates = 3; // Update, reset, output. +constexpr int kNumGruGates = 3; // Update, reset, output. // TODO(bugs.chromium.org/10480): Hard-coded optimized layout and remove this // function to improve setup time. @@ -101,17 +103,17 @@ constexpr size_t kNumGruGates = 3; // Update, reset, output. // It works both for weights, recurrent weights and bias. std::vector GetPreprocessedGruTensor( rtc::ArrayView tensor_src, - size_t output_size) { + int output_size) { // Transpose, cast and scale. // |n| is the size of the first dimension of the 3-dim tensor |weights|. - const size_t n = - rtc::CheckedDivExact(tensor_src.size(), output_size * kNumGruGates); - const size_t stride_src = kNumGruGates * output_size; - const size_t stride_dst = n * output_size; + const int n = rtc::CheckedDivExact(rtc::dchecked_cast(tensor_src.size()), + output_size * kNumGruGates); + const int stride_src = kNumGruGates * output_size; + const int stride_dst = n * output_size; std::vector tensor_dst(tensor_src.size()); - for (size_t g = 0; g < kNumGruGates; ++g) { - for (size_t o = 0; o < output_size; ++o) { - for (size_t i = 0; i < n; ++i) { + for (int g = 0; g < kNumGruGates; ++g) { + for (int o = 0; o < output_size; ++o) { + for (int i = 0; i < n; ++i) { tensor_dst[g * stride_dst + o * n + i] = rnnoise::kWeightsScale * static_cast( @@ -122,28 +124,28 @@ std::vector GetPreprocessedGruTensor( return tensor_dst; } -void ComputeGruUpdateResetGates(size_t input_size, - size_t output_size, +void ComputeGruUpdateResetGates(int input_size, + int output_size, rtc::ArrayView weights, rtc::ArrayView recurrent_weights, rtc::ArrayView bias, rtc::ArrayView input, rtc::ArrayView state, rtc::ArrayView gate) { - for (size_t o = 0; o < output_size; ++o) { + for (int o = 0; o < output_size; ++o) { gate[o] = bias[o]; - for (size_t i = 0; i < input_size; ++i) { + for (int i = 0; i < input_size; ++i) { gate[o] += input[i] * weights[o * input_size + i]; } - for (size_t s = 0; s < output_size; ++s) { + for (int s = 0; s < output_size; ++s) { gate[o] += state[s] * recurrent_weights[o * output_size + s]; } gate[o] = SigmoidApproximated(gate[o]); } } -void ComputeGruOutputGate(size_t input_size, - size_t output_size, +void ComputeGruOutputGate(int input_size, + int output_size, rtc::ArrayView weights, rtc::ArrayView recurrent_weights, rtc::ArrayView bias, @@ -151,12 +153,12 @@ void ComputeGruOutputGate(size_t input_size, rtc::ArrayView state, rtc::ArrayView reset, rtc::ArrayView gate) { - for (size_t o = 0; o < output_size; ++o) { + for (int o = 0; o < output_size; ++o) { gate[o] = bias[o]; - for (size_t i = 0; i < input_size; ++i) { + for (int i = 0; i < input_size; ++i) { gate[o] += input[i] * weights[o * input_size + i]; } - for (size_t s = 0; s < output_size; ++s) { + for (int s = 0; s < output_size; ++s) { gate[o] += state[s] * recurrent_weights[o * output_size + s] * reset[s]; } gate[o] = RectifiedLinearUnit(gate[o]); @@ -164,8 +166,8 @@ void ComputeGruOutputGate(size_t input_size, } // Gated recurrent unit (GRU) layer un-optimized implementation. -void ComputeGruLayerOutput(size_t input_size, - size_t output_size, +void ComputeGruLayerOutput(int input_size, + int output_size, rtc::ArrayView input, rtc::ArrayView weights, rtc::ArrayView recurrent_weights, @@ -173,8 +175,8 @@ void ComputeGruLayerOutput(size_t input_size, rtc::ArrayView state) { RTC_DCHECK_EQ(input_size, input.size()); // Stride and offset used to read parameter arrays. - const size_t stride_in = input_size * output_size; - const size_t stride_out = output_size * output_size; + const int stride_in = input_size * output_size; + const int stride_out = output_size * output_size; // Update gate. std::array update; @@ -198,7 +200,7 @@ void ComputeGruLayerOutput(size_t input_size, bias.subview(2 * output_size, output_size), input, state, reset, output); // Update output through the update gates and update the state. - for (size_t o = 0; o < output_size; ++o) { + for (int o = 0; o < output_size; ++o) { output[o] = update[o] * state[o] + (1.f - update[o]) * output[o]; state[o] = output[o]; } @@ -206,8 +208,8 @@ void ComputeGruLayerOutput(size_t input_size, // Fully connected layer un-optimized implementation. void ComputeFullyConnectedLayerOutput( - size_t input_size, - size_t output_size, + int input_size, + int output_size, rtc::ArrayView input, rtc::ArrayView bias, rtc::ArrayView weights, @@ -216,11 +218,11 @@ void ComputeFullyConnectedLayerOutput( RTC_DCHECK_EQ(input.size(), input_size); RTC_DCHECK_EQ(bias.size(), output_size); RTC_DCHECK_EQ(weights.size(), input_size * output_size); - for (size_t o = 0; o < output_size; ++o) { + for (int o = 0; o < output_size; ++o) { output[o] = bias[o]; // TODO(bugs.chromium.org/9076): Benchmark how different layouts for // |weights_| change the performance across different platforms. - for (size_t i = 0; i < input_size; ++i) { + for (int i = 0; i < input_size; ++i) { output[o] += input[i] * weights[o * input_size + i]; } output[o] = activation_function(output[o]); @@ -230,8 +232,8 @@ void ComputeFullyConnectedLayerOutput( #if defined(WEBRTC_ARCH_X86_FAMILY) // Fully connected layer SSE2 implementation. void ComputeFullyConnectedLayerOutputSse2( - size_t input_size, - size_t output_size, + int input_size, + int output_size, rtc::ArrayView input, rtc::ArrayView bias, rtc::ArrayView weights, @@ -240,16 +242,16 @@ void ComputeFullyConnectedLayerOutputSse2( RTC_DCHECK_EQ(input.size(), input_size); RTC_DCHECK_EQ(bias.size(), output_size); RTC_DCHECK_EQ(weights.size(), input_size * output_size); - const size_t input_size_by_4 = input_size >> 2; - const size_t offset = input_size & ~3; + const int input_size_by_4 = input_size >> 2; + const int offset = input_size & ~3; __m128 sum_wx_128; const float* v = reinterpret_cast(&sum_wx_128); - for (size_t o = 0; o < output_size; ++o) { + for (int o = 0; o < output_size; ++o) { // Perform 128 bit vector operations. sum_wx_128 = _mm_set1_ps(0); const float* x_p = input.data(); const float* w_p = weights.data() + o * input_size; - for (size_t i = 0; i < input_size_by_4; ++i, x_p += 4, w_p += 4) { + for (int i = 0; i < input_size_by_4; ++i, x_p += 4, w_p += 4) { sum_wx_128 = _mm_add_ps(sum_wx_128, _mm_mul_ps(_mm_loadu_ps(x_p), _mm_loadu_ps(w_p))); } @@ -266,8 +268,8 @@ void ComputeFullyConnectedLayerOutputSse2( } // namespace FullyConnectedLayer::FullyConnectedLayer( - const size_t input_size, - const size_t output_size, + const int input_size, + const int output_size, const rtc::ArrayView bias, const rtc::ArrayView weights, rtc::FunctionView activation_function, @@ -316,8 +318,8 @@ void FullyConnectedLayer::ComputeOutput(rtc::ArrayView input) { } GatedRecurrentLayer::GatedRecurrentLayer( - const size_t input_size, - const size_t output_size, + const int input_size, + const int output_size, const rtc::ArrayView bias, const rtc::ArrayView weights, const rtc::ArrayView recurrent_weights, diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn.h index 58274b2e1..5b44f5304 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn.h @@ -29,19 +29,19 @@ namespace rnn_vad { // over-allocate space for fully-connected layers output vectors (implemented as // std::array). The value should equal the number of units of the largest // fully-connected layer. -constexpr size_t kFullyConnectedLayersMaxUnits = 24; +constexpr int kFullyConnectedLayersMaxUnits = 24; // Maximum number of units for a recurrent layer. This value is used to // over-allocate space for recurrent layers state vectors (implemented as // std::array). The value should equal the number of units of the largest // recurrent layer. -constexpr size_t kRecurrentLayersMaxUnits = 24; +constexpr int kRecurrentLayersMaxUnits = 24; // Fully-connected layer. class FullyConnectedLayer { public: - FullyConnectedLayer(size_t input_size, - size_t output_size, + FullyConnectedLayer(int input_size, + int output_size, rtc::ArrayView bias, rtc::ArrayView weights, rtc::FunctionView activation_function, @@ -49,16 +49,16 @@ class FullyConnectedLayer { FullyConnectedLayer(const FullyConnectedLayer&) = delete; FullyConnectedLayer& operator=(const FullyConnectedLayer&) = delete; ~FullyConnectedLayer(); - size_t input_size() const { return input_size_; } - size_t output_size() const { return output_size_; } + int input_size() const { return input_size_; } + int output_size() const { return output_size_; } Optimization optimization() const { return optimization_; } rtc::ArrayView GetOutput() const; // Computes the fully-connected layer output. void ComputeOutput(rtc::ArrayView input); private: - const size_t input_size_; - const size_t output_size_; + const int input_size_; + const int output_size_; const std::vector bias_; const std::vector weights_; rtc::FunctionView activation_function_; @@ -72,8 +72,8 @@ class FullyConnectedLayer { // activation functions for the update/reset and output gates respectively. class GatedRecurrentLayer { public: - GatedRecurrentLayer(size_t input_size, - size_t output_size, + GatedRecurrentLayer(int input_size, + int output_size, rtc::ArrayView bias, rtc::ArrayView weights, rtc::ArrayView recurrent_weights, @@ -81,8 +81,8 @@ class GatedRecurrentLayer { GatedRecurrentLayer(const GatedRecurrentLayer&) = delete; GatedRecurrentLayer& operator=(const GatedRecurrentLayer&) = delete; ~GatedRecurrentLayer(); - size_t input_size() const { return input_size_; } - size_t output_size() const { return output_size_; } + int input_size() const { return input_size_; } + int output_size() const { return output_size_; } Optimization optimization() const { return optimization_; } rtc::ArrayView GetOutput() const; void Reset(); @@ -90,8 +90,8 @@ class GatedRecurrentLayer { void ComputeOutput(rtc::ArrayView input); private: - const size_t input_size_; - const size_t output_size_; + const int input_size_; + const int output_size_; const std::vector bias_; const std::vector weights_; const std::vector recurrent_weights_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn_vad_tool.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn_vad_tool.cc index c5293bedc..8b12b60c5 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn_vad_tool.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/rnn_vad_tool.cc @@ -20,6 +20,7 @@ #include "modules/audio_processing/agc2/rnn_vad/features_extraction.h" #include "modules/audio_processing/agc2/rnn_vad/rnn.h" #include "rtc_base/logging.h" +#include "rtc_base/numerics/safe_compare.h" ABSL_FLAG(std::string, i, "", "Path to the input wav file"); ABSL_FLAG(std::string, f, "", "Path to the output features file"); @@ -56,7 +57,7 @@ int main(int argc, char* argv[]) { } // Initialize. - const size_t frame_size_10ms = + const int frame_size_10ms = rtc::CheckedDivExact(wav_reader.sample_rate(), 100); std::vector samples_10ms; samples_10ms.resize(frame_size_10ms); @@ -69,9 +70,9 @@ int main(int argc, char* argv[]) { // Compute VAD probabilities. while (true) { // Read frame at the input sample rate. - const auto read_samples = + const size_t read_samples = wav_reader.ReadSamples(frame_size_10ms, samples_10ms.data()); - if (read_samples < frame_size_10ms) { + if (rtc::SafeLt(read_samples, frame_size_10ms)) { break; // EOF. } // Resample input. diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/sequence_buffer.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/sequence_buffer.h index 75d3d9bc0..a7402788c 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/sequence_buffer.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/sequence_buffer.h @@ -29,7 +29,7 @@ namespace rnn_vad { // values are written at the end of the buffer. // The class also provides a view on the most recent M values, where 0 < M <= S // and by default M = N. -template +template class SequenceBuffer { static_assert(N <= S, "The new chunk size cannot be larger than the sequence buffer " @@ -45,8 +45,8 @@ class SequenceBuffer { SequenceBuffer(const SequenceBuffer&) = delete; SequenceBuffer& operator=(const SequenceBuffer&) = delete; ~SequenceBuffer() = default; - size_t size() const { return S; } - size_t chunks_size() const { return N; } + int size() const { return S; } + int chunks_size() const { return N; } // Sets the sequence buffer values to zero. void Reset() { std::fill(buffer_.begin(), buffer_.end(), 0); } // Returns a view on the whole buffer. diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features.cc index 81e3339d7..96086babb 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features.cc @@ -16,6 +16,7 @@ #include #include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_compare.h" namespace webrtc { namespace rnn_vad { @@ -32,11 +33,11 @@ void UpdateCepstralDifferenceStats( RTC_DCHECK(sym_matrix_buf); // Compute the new cepstral distance stats. std::array distances; - for (size_t i = 0; i < kCepstralCoeffsHistorySize - 1; ++i) { - const size_t delay = i + 1; + for (int i = 0; i < kCepstralCoeffsHistorySize - 1; ++i) { + const int delay = i + 1; auto old_cepstral_coeffs = ring_buf.GetArrayView(delay); distances[i] = 0.f; - for (size_t k = 0; k < kNumBands; ++k) { + for (int k = 0; k < kNumBands; ++k) { const float c = new_cepstral_coeffs[k] - old_cepstral_coeffs[k]; distances[i] += c * c; } @@ -48,9 +49,9 @@ void UpdateCepstralDifferenceStats( // Computes the first half of the Vorbis window. std::array ComputeScaledHalfVorbisWindow( float scaling = 1.f) { - constexpr size_t kHalfSize = kFrameSize20ms24kHz / 2; + constexpr int kHalfSize = kFrameSize20ms24kHz / 2; std::array half_window{}; - for (size_t i = 0; i < kHalfSize; ++i) { + for (int i = 0; i < kHalfSize; ++i) { half_window[i] = scaling * std::sin(0.5 * kPi * std::sin(0.5 * kPi * (i + 0.5) / kHalfSize) * @@ -71,8 +72,8 @@ void ComputeWindowedForwardFft( RTC_DCHECK_EQ(frame.size(), 2 * half_window.size()); // Apply windowing. auto in = fft_input_buffer->GetView(); - for (size_t i = 0, j = kFrameSize20ms24kHz - 1; i < half_window.size(); - ++i, --j) { + for (int i = 0, j = kFrameSize20ms24kHz - 1; + rtc::SafeLt(i, half_window.size()); ++i, --j) { in[i] = frame[i] * half_window[i]; in[j] = frame[j] * half_window[i]; } @@ -162,7 +163,7 @@ void SpectralFeaturesExtractor::ComputeAvgAndDerivatives( RTC_DCHECK_EQ(average.size(), first_derivative.size()); RTC_DCHECK_EQ(first_derivative.size(), second_derivative.size()); RTC_DCHECK_LE(average.size(), curr.size()); - for (size_t i = 0; i < average.size(); ++i) { + for (int i = 0; rtc::SafeLt(i, average.size()); ++i) { // Average, kernel: [1, 1, 1]. average[i] = curr[i] + prev1[i] + prev2[i]; // First derivative, kernel: [1, 0, - 1]. @@ -178,7 +179,7 @@ void SpectralFeaturesExtractor::ComputeNormalizedCepstralCorrelation( reference_frame_fft_->GetConstView(), lagged_frame_fft_->GetConstView(), bands_cross_corr_); // Normalize. - for (size_t i = 0; i < bands_cross_corr_.size(); ++i) { + for (int i = 0; rtc::SafeLt(i, bands_cross_corr_.size()); ++i) { bands_cross_corr_[i] = bands_cross_corr_[i] / std::sqrt(0.001f + reference_frame_bands_energy_[i] * @@ -194,9 +195,9 @@ void SpectralFeaturesExtractor::ComputeNormalizedCepstralCorrelation( float SpectralFeaturesExtractor::ComputeVariability() const { // Compute cepstral variability score. float variability = 0.f; - for (size_t delay1 = 0; delay1 < kCepstralCoeffsHistorySize; ++delay1) { + for (int delay1 = 0; delay1 < kCepstralCoeffsHistorySize; ++delay1) { float min_dist = std::numeric_limits::max(); - for (size_t delay2 = 0; delay2 < kCepstralCoeffsHistorySize; ++delay2) { + for (int delay2 = 0; delay2 < kCepstralCoeffsHistorySize; ++delay2) { if (delay1 == delay2) // The distance would be 0. continue; min_dist = diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.cc index 29192a08f..91c0086fc 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.cc @@ -15,6 +15,7 @@ #include #include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_compare.h" namespace webrtc { namespace rnn_vad { @@ -105,9 +106,9 @@ void SpectralCorrelator::ComputeCrossCorrelation( RTC_DCHECK_EQ(x[1], 0.f) << "The Nyquist coefficient must be zeroed."; RTC_DCHECK_EQ(y[1], 0.f) << "The Nyquist coefficient must be zeroed."; constexpr auto kOpusScaleNumBins24kHz20ms = GetOpusScaleNumBins24kHz20ms(); - size_t k = 0; // Next Fourier coefficient index. + int k = 0; // Next Fourier coefficient index. cross_corr[0] = 0.f; - for (size_t i = 0; i < kOpusBands24kHz - 1; ++i) { + for (int i = 0; i < kOpusBands24kHz - 1; ++i) { cross_corr[i + 1] = 0.f; for (int j = 0; j < kOpusScaleNumBins24kHz20ms[i]; ++j) { // Band size. const float v = x[2 * k] * y[2 * k] + x[2 * k + 1] * y[2 * k + 1]; @@ -137,11 +138,11 @@ void ComputeSmoothedLogMagnitudeSpectrum( return x; }; // Smoothing over the bands for which the band energy is defined. - for (size_t i = 0; i < bands_energy.size(); ++i) { + for (int i = 0; rtc::SafeLt(i, bands_energy.size()); ++i) { log_bands_energy[i] = smooth(std::log10(kOneByHundred + bands_energy[i])); } // Smoothing over the remaining bands (zero energy). - for (size_t i = bands_energy.size(); i < kNumBands; ++i) { + for (int i = bands_energy.size(); i < kNumBands; ++i) { log_bands_energy[i] = smooth(kLogOneByHundred); } } @@ -149,8 +150,8 @@ void ComputeSmoothedLogMagnitudeSpectrum( std::array ComputeDctTable() { std::array dct_table; const double k = std::sqrt(0.5); - for (size_t i = 0; i < kNumBands; ++i) { - for (size_t j = 0; j < kNumBands; ++j) + for (int i = 0; i < kNumBands; ++i) { + for (int j = 0; j < kNumBands; ++j) dct_table[i * kNumBands + j] = std::cos((i + 0.5) * j * kPi / kNumBands); dct_table[i * kNumBands] *= k; } @@ -173,9 +174,9 @@ void ComputeDct(rtc::ArrayView in, RTC_DCHECK_LE(in.size(), kNumBands); RTC_DCHECK_LE(1, out.size()); RTC_DCHECK_LE(out.size(), in.size()); - for (size_t i = 0; i < out.size(); ++i) { + for (int i = 0; rtc::SafeLt(i, out.size()); ++i) { out[i] = 0.f; - for (size_t j = 0; j < in.size(); ++j) { + for (int j = 0; rtc::SafeLt(j, in.size()); ++j) { out[i] += in[j] * dct_table[j * kNumBands + i]; } // TODO(bugs.webrtc.org/10480): Scaling factor in the DCT table. diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.h index ed4caad02..aa7b1c6a4 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.h @@ -25,7 +25,7 @@ namespace rnn_vad { // At a sample rate of 24 kHz, the last 3 Opus bands are beyond the Nyquist // frequency. However, band #19 gets the contributions from band #18 because // of the symmetric triangular filter with peak response at 12 kHz. -constexpr size_t kOpusBands24kHz = 20; +constexpr int kOpusBands24kHz = 20; static_assert(kOpusBands24kHz < kNumBands, "The number of bands at 24 kHz must be less than those defined " "in the Opus scale at 48 kHz."); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/symmetric_matrix_buffer.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/symmetric_matrix_buffer.h index f0282aaed..dd3b62a1a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/symmetric_matrix_buffer.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/symmetric_matrix_buffer.h @@ -18,6 +18,7 @@ #include "api/array_view.h" #include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_compare.h" namespace webrtc { namespace rnn_vad { @@ -29,7 +30,7 @@ namespace rnn_vad { // removed when one of the two corresponding items that have been compared is // removed from the ring buffer. It is assumed that the comparison is symmetric // and that comparing an item with itself is not needed. -template +template class SymmetricMatrixBuffer { static_assert(S > 2, ""); @@ -55,9 +56,9 @@ class SymmetricMatrixBuffer { // column left. std::memmove(buf_.data(), buf_.data() + S, (buf_.size() - S) * sizeof(T)); // Copy new values in the last column in the right order. - for (size_t i = 0; i < values.size(); ++i) { - const size_t index = (S - 1 - i) * (S - 1) - 1; - RTC_DCHECK_LE(static_cast(0), index); + for (int i = 0; rtc::SafeLt(i, values.size()); ++i) { + const int index = (S - 1 - i) * (S - 1) - 1; + RTC_DCHECK_GE(index, 0); RTC_DCHECK_LT(index, buf_.size()); buf_[index] = values[i]; } @@ -65,9 +66,9 @@ class SymmetricMatrixBuffer { // Reads the value that corresponds to comparison of two items in the ring // buffer having delay |delay1| and |delay2|. The two arguments must not be // equal and both must be in {0, ..., S - 1}. - T GetValue(size_t delay1, size_t delay2) const { - int row = S - 1 - static_cast(delay1); - int col = S - 1 - static_cast(delay2); + T GetValue(int delay1, int delay2) const { + int row = S - 1 - delay1; + int col = S - 1 - delay2; RTC_DCHECK_NE(row, col) << "The diagonal cannot be accessed."; if (row > col) std::swap(row, col); // Swap to access the upper-right triangular part. diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/test_utils.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/test_utils.cc index 1a8e1a2ee..24bbf13e3 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/test_utils.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/test_utils.cc @@ -10,9 +10,11 @@ #include "modules/audio_processing/agc2/rnn_vad/test_utils.h" +#include #include #include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_compare.h" #include "rtc_base/system/arch.h" #include "system_wrappers/include/cpu_features_wrapper.h" #include "test/gtest.h" @@ -24,7 +26,7 @@ namespace test { namespace { using ReaderPairType = - std::pair>, const size_t>; + std::pair>, const int>; } // namespace @@ -33,7 +35,7 @@ using webrtc::test::ResourcePath; void ExpectEqualFloatArray(rtc::ArrayView expected, rtc::ArrayView computed) { ASSERT_EQ(expected.size(), computed.size()); - for (size_t i = 0; i < expected.size(); ++i) { + for (int i = 0; rtc::SafeLt(i, expected.size()); ++i) { SCOPED_TRACE(i); EXPECT_FLOAT_EQ(expected[i], computed[i]); } @@ -43,14 +45,14 @@ void ExpectNearAbsolute(rtc::ArrayView expected, rtc::ArrayView computed, float tolerance) { ASSERT_EQ(expected.size(), computed.size()); - for (size_t i = 0; i < expected.size(); ++i) { + for (int i = 0; rtc::SafeLt(i, expected.size()); ++i) { SCOPED_TRACE(i); EXPECT_NEAR(expected[i], computed[i], tolerance); } } -std::pair>, const size_t> -CreatePcmSamplesReader(const size_t frame_length) { +std::pair>, const int> +CreatePcmSamplesReader(const int frame_length) { auto ptr = std::make_unique>( test::ResourcePath("audio_processing/agc2/rnn_vad/samples", "pcm"), frame_length); @@ -59,14 +61,14 @@ CreatePcmSamplesReader(const size_t frame_length) { } ReaderPairType CreatePitchBuffer24kHzReader() { - constexpr size_t cols = 864; + constexpr int cols = 864; auto ptr = std::make_unique>( ResourcePath("audio_processing/agc2/rnn_vad/pitch_buf_24k", "dat"), cols); return {std::move(ptr), rtc::CheckedDivExact(ptr->data_length(), cols)}; } ReaderPairType CreateLpResidualAndPitchPeriodGainReader() { - constexpr size_t num_lp_residual_coeffs = 864; + constexpr int num_lp_residual_coeffs = 864; auto ptr = std::make_unique>( ResourcePath("audio_processing/agc2/rnn_vad/pitch_lp_res", "dat"), num_lp_residual_coeffs); @@ -83,8 +85,12 @@ ReaderPairType CreateVadProbsReader() { PitchTestData::PitchTestData() { BinaryFileReader test_data_reader( ResourcePath("audio_processing/agc2/rnn_vad/pitch_search_int", "dat"), - static_cast(1396)); + 1396); test_data_reader.ReadChunk(test_data_); + // Reverse the order of the squared energy values. + // Required after the WebRTC CL 191703 which switched to forward computation. + std::reverse(test_data_.begin() + kBufSize24kHz, + test_data_.begin() + kBufSize24kHz + kNumPitchBufSquareEnergies); } PitchTestData::~PitchTestData() = default; @@ -109,7 +115,7 @@ bool IsOptimizationAvailable(Optimization optimization) { switch (optimization) { case Optimization::kSse2: #if defined(WEBRTC_ARCH_X86_FAMILY) - return WebRtc_GetCPUInfo(kSSE2) != 0; + return GetCPUInfo(kSSE2) != 0; #else return false; #endif diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/test_utils.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/test_utils.h index db155e6a7..23e642be8 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/test_utils.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/rnn_vad/test_utils.h @@ -24,6 +24,7 @@ #include "api/array_view.h" #include "modules/audio_processing/agc2/rnn_vad/common.h" #include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_compare.h" namespace webrtc { namespace rnn_vad { @@ -47,7 +48,7 @@ void ExpectNearAbsolute(rtc::ArrayView expected, template class BinaryFileReader { public: - explicit BinaryFileReader(const std::string& file_path, size_t chunk_size = 0) + BinaryFileReader(const std::string& file_path, int chunk_size = 0) : is_(file_path, std::ios::binary | std::ios::ate), data_length_(is_.tellg() / sizeof(T)), chunk_size_(chunk_size) { @@ -58,7 +59,7 @@ class BinaryFileReader { BinaryFileReader(const BinaryFileReader&) = delete; BinaryFileReader& operator=(const BinaryFileReader&) = delete; ~BinaryFileReader() = default; - size_t data_length() const { return data_length_; } + int data_length() const { return data_length_; } bool ReadValue(D* dst) { if (std::is_same::value) { is_.read(reinterpret_cast(dst), sizeof(T)); @@ -72,7 +73,7 @@ class BinaryFileReader { // If |chunk_size| was specified in the ctor, it will check that the size of // |dst| equals |chunk_size|. bool ReadChunk(rtc::ArrayView dst) { - RTC_DCHECK((chunk_size_ == 0) || (chunk_size_ == dst.size())); + RTC_DCHECK((chunk_size_ == 0) || rtc::SafeEq(chunk_size_, dst.size())); const std::streamsize bytes_to_read = dst.size() * sizeof(T); if (std::is_same::value) { is_.read(reinterpret_cast(dst.data()), bytes_to_read); @@ -83,13 +84,13 @@ class BinaryFileReader { } return is_.gcount() == bytes_to_read; } - void SeekForward(size_t items) { is_.seekg(items * sizeof(T), is_.cur); } + void SeekForward(int items) { is_.seekg(items * sizeof(T), is_.cur); } void SeekBeginning() { is_.seekg(0, is_.beg); } private: std::ifstream is_; - const size_t data_length_; - const size_t chunk_size_; + const int data_length_; + const int chunk_size_; std::vector buf_; }; @@ -117,22 +118,22 @@ class BinaryFileWriter { // pointer and the second the number of chunks that can be read from the file. // Creates a reader for the PCM samples that casts from S16 to float and reads // chunks with length |frame_length|. -std::pair>, const size_t> -CreatePcmSamplesReader(const size_t frame_length); +std::pair>, const int> +CreatePcmSamplesReader(const int frame_length); // Creates a reader for the pitch buffer content at 24 kHz. -std::pair>, const size_t> +std::pair>, const int> CreatePitchBuffer24kHzReader(); // Creates a reader for the the LP residual coefficients and the pitch period // and gain values. -std::pair>, const size_t> +std::pair>, const int> CreateLpResidualAndPitchPeriodGainReader(); // Creates a reader for the VAD probabilities. -std::pair>, const size_t> +std::pair>, const int> CreateVadProbsReader(); -constexpr size_t kNumPitchBufAutoCorrCoeffs = 147; -constexpr size_t kNumPitchBufSquareEnergies = 385; -constexpr size_t kPitchTestDataSize = +constexpr int kNumPitchBufAutoCorrCoeffs = 147; +constexpr int kNumPitchBufSquareEnergies = 385; +constexpr int kPitchTestDataSize = kBufSize24kHz + kNumPitchBufSquareEnergies + kNumPitchBufAutoCorrCoeffs; // Class to retrieve a test pitch buffer content and the expected output for the diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/saturation_protector.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/saturation_protector.cc index 6d777ffdb..b64fcdb71 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/saturation_protector.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/saturation_protector.cc @@ -10,96 +10,112 @@ #include "modules/audio_processing/agc2/saturation_protector.h" -#include -#include - #include "modules/audio_processing/logging/apm_data_dumper.h" #include "rtc_base/numerics/safe_minmax.h" namespace webrtc { - namespace { -void ShiftBuffer(std::array* buffer_) { - // Move everything one element back. - std::copy(buffer_->begin() + 1, buffer_->end(), buffer_->begin()); -} + +constexpr float kMinLevelDbfs = -90.f; + +// Min/max margins are based on speech crest-factor. +constexpr float kMinMarginDb = 12.f; +constexpr float kMaxMarginDb = 25.f; + +using saturation_protector_impl::RingBuffer; + } // namespace -SaturationProtector::PeakEnveloper::PeakEnveloper() = default; - -void SaturationProtector::PeakEnveloper::Process(float frame_peak_dbfs) { - // Update the delayed buffer and the current superframe peak. - current_superframe_peak_dbfs_ = - std::max(current_superframe_peak_dbfs_, frame_peak_dbfs); - speech_time_in_estimate_ms_ += kFrameDurationMs; - if (speech_time_in_estimate_ms_ > kPeakEnveloperSuperFrameLengthMs) { - speech_time_in_estimate_ms_ = 0; - const bool buffer_full = elements_in_buffer_ == kPeakEnveloperBufferSize; - if (buffer_full) { - ShiftBuffer(&peak_delay_buffer_); - *peak_delay_buffer_.rbegin() = current_superframe_peak_dbfs_; - } else { - peak_delay_buffer_[elements_in_buffer_] = current_superframe_peak_dbfs_; - elements_in_buffer_++; +bool RingBuffer::operator==(const RingBuffer& b) const { + RTC_DCHECK_LE(size_, buffer_.size()); + RTC_DCHECK_LE(b.size_, b.buffer_.size()); + if (size_ != b.size_) { + return false; + } + for (int i = 0, i0 = FrontIndex(), i1 = b.FrontIndex(); i < size_; + ++i, ++i0, ++i1) { + if (buffer_[i0 % buffer_.size()] != b.buffer_[i1 % b.buffer_.size()]) { + return false; } - current_superframe_peak_dbfs_ = -90.f; + } + return true; +} + +void RingBuffer::Reset() { + next_ = 0; + size_ = 0; +} + +void RingBuffer::PushBack(float v) { + RTC_DCHECK_GE(next_, 0); + RTC_DCHECK_GE(size_, 0); + RTC_DCHECK_LT(next_, buffer_.size()); + RTC_DCHECK_LE(size_, buffer_.size()); + buffer_[next_++] = v; + if (rtc::SafeEq(next_, buffer_.size())) { + next_ = 0; + } + if (rtc::SafeLt(size_, buffer_.size())) { + size_++; } } -float SaturationProtector::PeakEnveloper::Query() const { - float result; - if (elements_in_buffer_ > 0) { - result = peak_delay_buffer_[0]; +absl::optional RingBuffer::Front() const { + if (size_ == 0) { + return absl::nullopt; + } + RTC_DCHECK_LT(FrontIndex(), buffer_.size()); + return buffer_[FrontIndex()]; +} + +bool SaturationProtectorState::operator==( + const SaturationProtectorState& b) const { + return margin_db == b.margin_db && peak_delay_buffer == b.peak_delay_buffer && + max_peaks_dbfs == b.max_peaks_dbfs && + time_since_push_ms == b.time_since_push_ms; +} + +void ResetSaturationProtectorState(float initial_margin_db, + SaturationProtectorState& state) { + state.margin_db = initial_margin_db; + state.peak_delay_buffer.Reset(); + state.max_peaks_dbfs = kMinLevelDbfs; + state.time_since_push_ms = 0; +} + +void UpdateSaturationProtectorState(float speech_peak_dbfs, + float speech_level_dbfs, + SaturationProtectorState& state) { + // Get the max peak over `kPeakEnveloperSuperFrameLengthMs` ms. + state.max_peaks_dbfs = std::max(state.max_peaks_dbfs, speech_peak_dbfs); + state.time_since_push_ms += kFrameDurationMs; + if (rtc::SafeGt(state.time_since_push_ms, kPeakEnveloperSuperFrameLengthMs)) { + // Push `max_peaks_dbfs` back into the ring buffer. + state.peak_delay_buffer.PushBack(state.max_peaks_dbfs); + // Reset. + state.max_peaks_dbfs = kMinLevelDbfs; + state.time_since_push_ms = 0; + } + + // Update margin by comparing the estimated speech level and the delayed max + // speech peak power. + // TODO(alessiob): Check with aleloi@ why we use a delay and how to tune it. + const float delayed_peak_dbfs = + state.peak_delay_buffer.Front().value_or(state.max_peaks_dbfs); + const float difference_db = delayed_peak_dbfs - speech_level_dbfs; + if (difference_db > state.margin_db) { + // Attack. + state.margin_db = + state.margin_db * kSaturationProtectorAttackConstant + + difference_db * (1.f - kSaturationProtectorAttackConstant); } else { - result = current_superframe_peak_dbfs_; - } - return result; -} - -SaturationProtector::SaturationProtector(ApmDataDumper* apm_data_dumper) - : SaturationProtector(apm_data_dumper, GetExtraSaturationMarginOffsetDb()) { -} - -SaturationProtector::SaturationProtector(ApmDataDumper* apm_data_dumper, - float extra_saturation_margin_db) - : apm_data_dumper_(apm_data_dumper), - last_margin_(GetInitialSaturationMarginDb()), - extra_saturation_margin_db_(extra_saturation_margin_db) {} - -void SaturationProtector::UpdateMargin( - const VadWithLevel::LevelAndProbability& vad_data, - float last_speech_level_estimate) { - peak_enveloper_.Process(vad_data.speech_peak_dbfs); - const float delayed_peak_dbfs = peak_enveloper_.Query(); - const float difference_db = delayed_peak_dbfs - last_speech_level_estimate; - - if (last_margin_ < difference_db) { - last_margin_ = last_margin_ * kSaturationProtectorAttackConstant + - difference_db * (1.f - kSaturationProtectorAttackConstant); - } else { - last_margin_ = last_margin_ * kSaturationProtectorDecayConstant + - difference_db * (1.f - kSaturationProtectorDecayConstant); + // Decay. + state.margin_db = state.margin_db * kSaturationProtectorDecayConstant + + difference_db * (1.f - kSaturationProtectorDecayConstant); } - last_margin_ = rtc::SafeClamp(last_margin_, 12.f, 25.f); -} - -float SaturationProtector::LastMargin() const { - return last_margin_ + extra_saturation_margin_db_; -} - -void SaturationProtector::Reset() { - peak_enveloper_ = PeakEnveloper(); -} - -void SaturationProtector::DebugDumpEstimate() const { - if (apm_data_dumper_) { - apm_data_dumper_->DumpRaw( - "agc2_adaptive_saturation_protector_delayed_peak_dbfs", - peak_enveloper_.Query()); - apm_data_dumper_->DumpRaw("agc2_adaptive_saturation_margin_db", - last_margin_); - } + state.margin_db = + rtc::SafeClamp(state.margin_db, kMinMarginDb, kMaxMarginDb); } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/saturation_protector.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/saturation_protector.h index e63746907..88be91a79 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/saturation_protector.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/saturation_protector.h @@ -13,59 +13,70 @@ #include +#include "absl/types/optional.h" #include "modules/audio_processing/agc2/agc2_common.h" -#include "modules/audio_processing/agc2/vad_with_level.h" +#include "rtc_base/numerics/safe_compare.h" namespace webrtc { +namespace saturation_protector_impl { -class ApmDataDumper; - -class SaturationProtector { +// Ring buffer which only supports (i) push back and (ii) read oldest item. +class RingBuffer { public: - explicit SaturationProtector(ApmDataDumper* apm_data_dumper); + bool operator==(const RingBuffer& b) const; + inline bool operator!=(const RingBuffer& b) const { return !(*this == b); } - SaturationProtector(ApmDataDumper* apm_data_dumper, - float extra_saturation_margin_db); + // Maximum number of values that the buffer can contain. + int Capacity() const { return buffer_.size(); } + // Number of values in the buffer. + int Size() const { return size_; } - // Update and return margin estimate. This method should be called - // whenever a frame is reliably classified as 'speech'. - // - // Returned value is in DB scale. - void UpdateMargin(const VadWithLevel::LevelAndProbability& vad_data, - float last_speech_level_estimate_dbfs); - - // Returns latest computed margin. Used in cases when speech is not - // detected. - float LastMargin() const; - - // Resets the internal memory. void Reset(); - - void DebugDumpEstimate() const; + // Pushes back `v`. If the buffer is full, the oldest value is replaced. + void PushBack(float v); + // Returns the oldest item in the buffer. Returns an empty value if the + // buffer is empty. + absl::optional Front() const; private: - // Computes a delayed envelope of peaks. - class PeakEnveloper { - public: - PeakEnveloper(); - void Process(float frame_peak_dbfs); - - float Query() const; - - private: - size_t speech_time_in_estimate_ms_ = 0; - float current_superframe_peak_dbfs_ = -90.f; - size_t elements_in_buffer_ = 0; - std::array peak_delay_buffer_ = {}; - }; - - ApmDataDumper* apm_data_dumper_; - - float last_margin_; - PeakEnveloper peak_enveloper_; - const float extra_saturation_margin_db_; + inline int FrontIndex() const { + return rtc::SafeEq(size_, buffer_.size()) ? next_ : 0; + } + // `buffer_` has `size_` elements (up to the size of `buffer_`) and `next_` is + // the position where the next new value is written in `buffer_`. + std::array buffer_; + int next_ = 0; + int size_ = 0; }; +} // namespace saturation_protector_impl + +// Saturation protector state. Exposed publicly for check-pointing and restore +// ops. +struct SaturationProtectorState { + bool operator==(const SaturationProtectorState& s) const; + inline bool operator!=(const SaturationProtectorState& s) const { + return !(*this == s); + } + + float margin_db; // Recommended margin. + saturation_protector_impl::RingBuffer peak_delay_buffer; + float max_peaks_dbfs; + int time_since_push_ms; // Time since the last ring buffer push operation. +}; + +// Resets the saturation protector state. +void ResetSaturationProtectorState(float initial_margin_db, + SaturationProtectorState& state); + +// Updates `state` by analyzing the estimated speech level `speech_level_dbfs` +// and the peak power `speech_peak_dbfs` for an observed frame which is +// reliably classified as "speech". `state` must not be modified without calling +// this function. +void UpdateSaturationProtectorState(float speech_peak_dbfs, + float speech_level_dbfs, + SaturationProtectorState& state); + } // namespace webrtc #endif // MODULES_AUDIO_PROCESSING_AGC2_SATURATION_PROTECTOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/signal_classifier.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/signal_classifier.cc index 38334f7ec..a06413d16 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/signal_classifier.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/signal_classifier.cc @@ -26,7 +26,7 @@ namespace { bool IsSse2Available() { #if defined(WEBRTC_ARCH_X86_FAMILY) - return WebRtc_GetCPUInfo(kSSE2) != 0; + return GetCPUInfo(kSSE2) != 0; #else return false; #endif diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/signal_classifier.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/signal_classifier.h index ae288ae77..20cce920f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/signal_classifier.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/signal_classifier.h @@ -18,7 +18,6 @@ #include "common_audio/third_party/ooura/fft_size_128/ooura_fft.h" #include "modules/audio_processing/agc2/down_sampler.h" #include "modules/audio_processing/agc2/noise_spectrum_estimator.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -30,6 +29,11 @@ class SignalClassifier { enum class SignalType { kNonStationary, kStationary }; explicit SignalClassifier(ApmDataDumper* data_dumper); + + SignalClassifier() = delete; + SignalClassifier(const SignalClassifier&) = delete; + SignalClassifier& operator=(const SignalClassifier&) = delete; + ~SignalClassifier(); void Initialize(int sample_rate_hz); @@ -39,6 +43,11 @@ class SignalClassifier { class FrameExtender { public: FrameExtender(size_t frame_size, size_t extended_frame_size); + + FrameExtender() = delete; + FrameExtender(const FrameExtender&) = delete; + FrameExtender& operator=(const FrameExtender&) = delete; + ~FrameExtender(); void ExtendFrame(rtc::ArrayView x, @@ -46,8 +55,6 @@ class SignalClassifier { private: std::vector x_old_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(FrameExtender); }; ApmDataDumper* const data_dumper_; @@ -59,7 +66,6 @@ class SignalClassifier { int consistent_classification_counter_; SignalType last_signal_type_; const OouraFft ooura_fft_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SignalClassifier); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/vad_with_level.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/vad_with_level.cc index d4ec2ced9..3dbb55732 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/vad_with_level.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/vad_with_level.cc @@ -16,55 +16,99 @@ #include "api/array_view.h" #include "common_audio/include/audio_util.h" +#include "common_audio/resampler/include/push_resampler.h" +#include "modules/audio_processing/agc2/agc2_common.h" #include "modules/audio_processing/agc2/rnn_vad/common.h" +#include "modules/audio_processing/agc2/rnn_vad/features_extraction.h" +#include "modules/audio_processing/agc2/rnn_vad/rnn.h" +#include "rtc_base/checks.h" namespace webrtc { - namespace { -float ProcessForPeak(AudioFrameView frame) { - float current_max = 0; - for (const auto& x : frame.channel(0)) { - current_max = std::max(std::fabs(x), current_max); + +using VoiceActivityDetector = VadLevelAnalyzer::VoiceActivityDetector; + +// Default VAD that combines a resampler and the RNN VAD. +// Computes the speech probability on the first channel. +class Vad : public VoiceActivityDetector { + public: + Vad() = default; + Vad(const Vad&) = delete; + Vad& operator=(const Vad&) = delete; + ~Vad() = default; + + float ComputeProbability(AudioFrameView frame) override { + // The source number of channels is 1, because we always use the 1st + // channel. + resampler_.InitializeIfNeeded( + /*sample_rate_hz=*/static_cast(frame.samples_per_channel() * 100), + rnn_vad::kSampleRate24kHz, + /*num_channels=*/1); + + std::array work_frame; + // Feed the 1st channel to the resampler. + resampler_.Resample(frame.channel(0).data(), frame.samples_per_channel(), + work_frame.data(), rnn_vad::kFrameSize10ms24kHz); + + std::array feature_vector; + const bool is_silence = features_extractor_.CheckSilenceComputeFeatures( + work_frame, feature_vector); + return rnn_vad_.ComputeVadProbability(feature_vector, is_silence); + } + + private: + PushResampler resampler_; + rnn_vad::FeaturesExtractor features_extractor_; + rnn_vad::RnnBasedVad rnn_vad_; +}; + +// Returns an updated version of `p_old` by using instant decay and the given +// `attack` on a new VAD probability value `p_new`. +float SmoothedVadProbability(float p_old, float p_new, float attack) { + RTC_DCHECK_GT(attack, 0.f); + RTC_DCHECK_LE(attack, 1.f); + if (p_new < p_old || attack == 1.f) { + // Instant decay (or no smoothing). + return p_new; + } else { + // Attack phase. + return attack * p_new + (1.f - attack) * p_old; } - return current_max; } -float ProcessForRms(AudioFrameView frame) { - float rms = 0; - for (const auto& x : frame.channel(0)) { - rms += x * x; - } - return std::sqrt(rms / frame.samples_per_channel()); -} } // namespace -VadWithLevel::VadWithLevel() = default; -VadWithLevel::~VadWithLevel() = default; +VadLevelAnalyzer::VadLevelAnalyzer() + : VadLevelAnalyzer(kDefaultSmoothedVadProbabilityAttack, + std::make_unique()) {} -VadWithLevel::LevelAndProbability VadWithLevel::AnalyzeFrame( - AudioFrameView frame) { - SetSampleRate(static_cast(frame.samples_per_channel() * 100)); - std::array work_frame; - // Feed the 1st channel to the resampler. - resampler_.Resample(frame.channel(0).data(), frame.samples_per_channel(), - work_frame.data(), rnn_vad::kFrameSize10ms24kHz); +VadLevelAnalyzer::VadLevelAnalyzer(float vad_probability_attack) + : VadLevelAnalyzer(vad_probability_attack, std::make_unique()) {} - std::array feature_vector; - - const bool is_silence = features_extractor_.CheckSilenceComputeFeatures( - work_frame, feature_vector); - const float vad_probability = - rnn_vad_.ComputeVadProbability(feature_vector, is_silence); - return LevelAndProbability(vad_probability, - FloatS16ToDbfs(ProcessForRms(frame)), - FloatS16ToDbfs(ProcessForPeak(frame))); +VadLevelAnalyzer::VadLevelAnalyzer(float vad_probability_attack, + std::unique_ptr vad) + : vad_(std::move(vad)), vad_probability_attack_(vad_probability_attack) { + RTC_DCHECK(vad_); } -void VadWithLevel::SetSampleRate(int sample_rate_hz) { - // The source number of channels in 1, because we always use the 1st - // channel. - resampler_.InitializeIfNeeded(sample_rate_hz, rnn_vad::kSampleRate24kHz, - 1 /* num_channels */); +VadLevelAnalyzer::~VadLevelAnalyzer() = default; + +VadLevelAnalyzer::Result VadLevelAnalyzer::AnalyzeFrame( + AudioFrameView frame) { + // Compute levels. + float peak = 0.f; + float rms = 0.f; + for (const auto& x : frame.channel(0)) { + peak = std::max(std::fabs(x), peak); + rms += x * x; + } + // Compute smoothed speech probability. + vad_probability_ = SmoothedVadProbability( + /*p_old=*/vad_probability_, /*p_new=*/vad_->ComputeProbability(frame), + vad_probability_attack_); + return {vad_probability_, + FloatS16ToDbfs(std::sqrt(rms / frame.samples_per_channel())), + FloatS16ToDbfs(peak)}; } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/vad_with_level.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/vad_with_level.h index b0ad868d4..ce72cdc75 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/vad_with_level.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/agc2/vad_with_level.h @@ -11,36 +11,46 @@ #ifndef MODULES_AUDIO_PROCESSING_AGC2_VAD_WITH_LEVEL_H_ #define MODULES_AUDIO_PROCESSING_AGC2_VAD_WITH_LEVEL_H_ -#include "common_audio/resampler/include/push_resampler.h" -#include "modules/audio_processing/agc2/rnn_vad/features_extraction.h" -#include "modules/audio_processing/agc2/rnn_vad/rnn.h" +#include + #include "modules/audio_processing/include/audio_frame_view.h" namespace webrtc { -class VadWithLevel { + +// Class to analyze voice activity and audio levels. +class VadLevelAnalyzer { public: - struct LevelAndProbability { - constexpr LevelAndProbability(float prob, float rms, float peak) - : speech_probability(prob), - speech_rms_dbfs(rms), - speech_peak_dbfs(peak) {} - LevelAndProbability() = default; - float speech_probability = 0; - float speech_rms_dbfs = 0; // Root mean square in decibels to full-scale. - float speech_peak_dbfs = 0; + struct Result { + float speech_probability; // Range: [0, 1]. + float rms_dbfs; // Root mean square power (dBFS). + float peak_dbfs; // Peak power (dBFS). }; - VadWithLevel(); - ~VadWithLevel(); + // Voice Activity Detector (VAD) interface. + class VoiceActivityDetector { + public: + virtual ~VoiceActivityDetector() = default; + // Analyzes an audio frame and returns the speech probability. + virtual float ComputeProbability(AudioFrameView frame) = 0; + }; - LevelAndProbability AnalyzeFrame(AudioFrameView frame); + // Ctor. Uses the default VAD. + VadLevelAnalyzer(); + explicit VadLevelAnalyzer(float vad_probability_attack); + // Ctor. Uses a custom `vad`. + VadLevelAnalyzer(float vad_probability_attack, + std::unique_ptr vad); + VadLevelAnalyzer(const VadLevelAnalyzer&) = delete; + VadLevelAnalyzer& operator=(const VadLevelAnalyzer&) = delete; + ~VadLevelAnalyzer(); + + // Computes the speech probability and the level for `frame`. + Result AnalyzeFrame(AudioFrameView frame); private: - void SetSampleRate(int sample_rate_hz); - - rnn_vad::RnnBasedVad rnn_vad_; - rnn_vad::FeaturesExtractor features_extractor_; - PushResampler resampler_; + std::unique_ptr vad_; + const float vad_probability_attack_; + float vad_probability_ = 0.f; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_builder_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_builder_impl.cc index e89bbecc6..f55c9158f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_builder_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_builder_impl.cc @@ -35,16 +35,10 @@ AudioProcessing* AudioProcessingBuilder::Create(const webrtc::Config& config) { #else // Standard implementation. - AudioProcessingImpl* apm = new rtc::RefCountedObject( + return new rtc::RefCountedObject( config, std::move(capture_post_processing_), std::move(render_pre_processing_), std::move(echo_control_factory_), std::move(echo_detector_), std::move(capture_analyzer_)); - if (apm->Initialize() != AudioProcessing::kNoError) { - delete apm; - apm = nullptr; - } - return apm; - #endif } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_impl.cc index b155bdbad..37112f088 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_impl.cc @@ -114,6 +114,7 @@ GainControl::Mode Agc1ConfigModeToInterfaceMode( case Agc1Config::kFixedDigital: return GainControl::kFixedDigital; } + RTC_CHECK_NOTREACHED(); } // Maximum lengths that frame of samples being passed from the render side to @@ -125,6 +126,7 @@ static const size_t kMaxAllowedValuesOfSamplesPerFrame = 480; // TODO(peah): Decrease this once we properly handle hugely unbalanced // reverse and forward call numbers. static const size_t kMaxNumFramesToBuffer = 100; + } // namespace // Throughout webrtc, it's assumed that success is represented by zero. @@ -307,6 +309,8 @@ AudioProcessingImpl::AudioProcessingImpl( config_.gain_controller1.analog_gain_controller.enable_digital_adaptive = !config.Get().digital_adaptive_disabled; #endif + + Initialize(); } AudioProcessingImpl::~AudioProcessingImpl() = default; @@ -315,7 +319,8 @@ int AudioProcessingImpl::Initialize() { // Run in a single-threaded manner during initialization. MutexLock lock_render(&mutex_render_); MutexLock lock_capture(&mutex_capture_); - return InitializeLocked(); + InitializeLocked(); + return kNoError; } int AudioProcessingImpl::Initialize(int capture_input_sample_rate_hz, @@ -356,7 +361,7 @@ int AudioProcessingImpl::MaybeInitializeRender( return InitializeLocked(processing_config); } -int AudioProcessingImpl::InitializeLocked() { +void AudioProcessingImpl::InitializeLocked() { UpdateActiveSubmoduleStates(); const int render_audiobuffer_sample_rate_hz = @@ -425,7 +430,6 @@ int AudioProcessingImpl::InitializeLocked() { if (aec_dump_) { aec_dump_->WriteInitMessage(formats_.api_format, rtc::TimeUTCMillis()); } - return kNoError; } int AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) { @@ -519,7 +523,8 @@ int AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) { capture_nonlocked_.capture_processing_format.sample_rate_hz(); } - return InitializeLocked(); + InitializeLocked(); + return kNoError; } void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) { @@ -542,34 +547,10 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) { config_.echo_canceller.mobile_mode != config.echo_canceller.mobile_mode; const bool agc1_config_changed = - config_.gain_controller1.enabled != config.gain_controller1.enabled || - config_.gain_controller1.mode != config.gain_controller1.mode || - config_.gain_controller1.target_level_dbfs != - config.gain_controller1.target_level_dbfs || - config_.gain_controller1.compression_gain_db != - config.gain_controller1.compression_gain_db || - config_.gain_controller1.enable_limiter != - config.gain_controller1.enable_limiter || - config_.gain_controller1.analog_level_minimum != - config.gain_controller1.analog_level_minimum || - config_.gain_controller1.analog_level_maximum != - config.gain_controller1.analog_level_maximum || - config_.gain_controller1.analog_gain_controller.enabled != - config.gain_controller1.analog_gain_controller.enabled || - config_.gain_controller1.analog_gain_controller.startup_min_volume != - config.gain_controller1.analog_gain_controller.startup_min_volume || - config_.gain_controller1.analog_gain_controller.clipped_level_min != - config.gain_controller1.analog_gain_controller.clipped_level_min || - config_.gain_controller1.analog_gain_controller - .enable_agc2_level_estimator != - config.gain_controller1.analog_gain_controller - .enable_agc2_level_estimator || - config_.gain_controller1.analog_gain_controller.enable_digital_adaptive != - config.gain_controller1.analog_gain_controller - .enable_digital_adaptive; + config_.gain_controller1 != config.gain_controller1; const bool agc2_config_changed = - config_.gain_controller2.enabled != config.gain_controller2.enabled; + config_.gain_controller2 != config.gain_controller2; const bool voice_detection_config_changed = config_.voice_detection.enabled != config.voice_detection.enabled; @@ -608,10 +589,8 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) { const bool config_ok = GainController2::Validate(config_.gain_controller2); if (!config_ok) { - RTC_LOG(LS_ERROR) << "AudioProcessing module config error\n" - "Gain Controller 2: " - << GainController2::ToString(config_.gain_controller2) - << "\nReverting to default parameter set"; + RTC_LOG(LS_ERROR) + << "Invalid Gain Controller 2 config; using the default config."; config_.gain_controller2 = AudioProcessing::Config::GainController2(); } @@ -638,9 +617,6 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) { } } -// TODO(webrtc:5298): Remove. -void AudioProcessingImpl::SetExtraOptions(const webrtc::Config& config) {} - void AudioProcessingImpl::OverrideSubmoduleCreationForTesting( const ApmSubmoduleCreationOverrides& overrides) { MutexLock lock(&mutex_capture_); @@ -705,6 +681,7 @@ void AudioProcessingImpl::SetRuntimeSetting(RuntimeSetting setting) { case RuntimeSetting::Type::kCapturePreGain: case RuntimeSetting::Type::kCaptureCompressionGain: case RuntimeSetting::Type::kCaptureFixedPostGain: + case RuntimeSetting::Type::kCaptureOutputUsed: capture_runtime_settings_enqueuer_.Enqueue(setting); return; case RuntimeSetting::Type::kPlayoutVolumeChange: @@ -731,15 +708,18 @@ AudioProcessingImpl::RuntimeSettingEnqueuer::~RuntimeSettingEnqueuer() = void AudioProcessingImpl::RuntimeSettingEnqueuer::Enqueue( RuntimeSetting setting) { - size_t remaining_attempts = 10; + int remaining_attempts = 10; while (!runtime_settings_.Insert(&setting) && remaining_attempts-- > 0) { RuntimeSetting setting_to_discard; - if (runtime_settings_.Remove(&setting_to_discard)) + if (runtime_settings_.Remove(&setting_to_discard)) { RTC_LOG(LS_ERROR) << "The runtime settings queue is full. Oldest setting discarded."; + } } - if (remaining_attempts == 0) + if (remaining_attempts == 0) { + RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.ApmRuntimeSettingCannotEnqueue", 1); RTC_LOG(LS_ERROR) << "Cannot enqueue a new runtime setting."; + } } int AudioProcessingImpl::MaybeInitializeCapture( @@ -865,6 +845,10 @@ void AudioProcessingImpl::HandleCaptureRuntimeSettings() { case RuntimeSetting::Type::kNotSpecified: RTC_NOTREACHED(); break; + case RuntimeSetting::Type::kCaptureOutputUsed: + // TODO(b/154437967): Add support for reducing complexity when it is + // known that the capture output will not be used. + break; } } } @@ -886,6 +870,7 @@ void AudioProcessingImpl::HandleRenderRuntimeSettings() { case RuntimeSetting::Type::kCapturePreGain: // fall-through case RuntimeSetting::Type::kCaptureCompressionGain: // fall-through case RuntimeSetting::Type::kCaptureFixedPostGain: // fall-through + case RuntimeSetting::Type::kCaptureOutputUsed: // fall-through case RuntimeSetting::Type::kNotSpecified: RTC_NOTREACHED(); break; @@ -1491,8 +1476,8 @@ bool AudioProcessingImpl::GetLinearAecOutput( rtc::ArrayView channel_view = rtc::ArrayView(linear_aec_buffer->channels_const()[ch], linear_aec_buffer->num_frames()); - std::copy(channel_view.begin(), channel_view.end(), - linear_output[ch].begin()); + FloatS16ToFloat(channel_view.data(), channel_view.size(), + linear_output[ch].data()); } return true; } @@ -1844,9 +1829,8 @@ void AudioProcessingImpl::InitializeNoiseSuppressor() { return NsConfig::SuppressionLevel::k18dB; case NoiseSuppresionConfig::kVeryHigh: return NsConfig::SuppressionLevel::k21dB; - default: - RTC_NOTREACHED(); } + RTC_CHECK_NOTREACHED(); }; NsConfig cfg; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_impl.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_impl.h index dfd5f63c5..d0eec0eec 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_impl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/audio_processing_impl.h @@ -72,7 +72,6 @@ class AudioProcessingImpl : public AudioProcessing { ChannelLayout render_input_layout) override; int Initialize(const ProcessingConfig& processing_config) override; void ApplyConfig(const AudioProcessing::Config& config) override; - void SetExtraOptions(const webrtc::Config& config) override; bool CreateAndAttachAecDump(const std::string& file_name, int64_t max_log_size_bytes, rtc::TaskQueue* worker_queue) override; @@ -140,7 +139,7 @@ class AudioProcessingImpl : public AudioProcessing { protected: // Overridden in a mock. - virtual int InitializeLocked() + virtual void InitializeLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_render_, mutex_capture_); private: diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/gain_controller2.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/gain_controller2.cc index b15a266cd..6561bebc6 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/gain_controller2.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/gain_controller2.cc @@ -65,8 +65,7 @@ void GainController2::NotifyAnalogLevel(int level) { void GainController2::ApplyConfig( const AudioProcessing::Config::GainController2& config) { - RTC_DCHECK(Validate(config)) - << " the invalid config was " << ToString(config); + RTC_DCHECK(Validate(config)); config_ = config; if (config.fixed_digital.gain_db != config_.fixed_digital.gain_db) { @@ -84,40 +83,19 @@ void GainController2::ApplyConfig( bool GainController2::Validate( const AudioProcessing::Config::GainController2& config) { - return config.fixed_digital.gain_db >= 0.f && - config.fixed_digital.gain_db < 50.f && - config.adaptive_digital.extra_saturation_margin_db >= 0.f && - config.adaptive_digital.extra_saturation_margin_db <= 100.f; -} - -std::string GainController2::ToString( - const AudioProcessing::Config::GainController2& config) { - rtc::StringBuilder ss; - std::string adaptive_digital_level_estimator; - using LevelEstimatorType = - AudioProcessing::Config::GainController2::LevelEstimator; - switch (config.adaptive_digital.level_estimator) { - case LevelEstimatorType::kRms: - adaptive_digital_level_estimator = "RMS"; - break; - case LevelEstimatorType::kPeak: - adaptive_digital_level_estimator = "peak"; - break; - } - // clang-format off - // clang formatting doesn't respect custom nested style. - ss << "{" - "enabled: " << (config.enabled ? "true" : "false") << ", " - "fixed_digital: {gain_db: " << config.fixed_digital.gain_db << "}, " - "adaptive_digital: {" - "enabled: " - << (config.adaptive_digital.enabled ? "true" : "false") << ", " - "level_estimator: " << adaptive_digital_level_estimator << ", " - "extra_saturation_margin_db:" - << config.adaptive_digital.extra_saturation_margin_db << "}" - "}"; - // clang-format on - return ss.Release(); + const auto& fixed = config.fixed_digital; + const auto& adaptive = config.adaptive_digital; + return fixed.gain_db >= 0.f && fixed.gain_db < 50.f && + adaptive.vad_probability_attack > 0.f && + adaptive.vad_probability_attack <= 1.f && + adaptive.level_estimator_adjacent_speech_frames_threshold >= 1 && + adaptive.initial_saturation_margin_db >= 0.f && + adaptive.initial_saturation_margin_db <= 100.f && + adaptive.extra_saturation_margin_db >= 0.f && + adaptive.extra_saturation_margin_db <= 100.f && + adaptive.gain_applier_adjacent_speech_frames_threshold >= 1 && + adaptive.max_gain_change_db_per_second > 0.f && + adaptive.max_output_noise_level_dbfs <= 0.f; } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/gain_controller2.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/gain_controller2.h index 7ed310ebf..da27fdcc6 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/gain_controller2.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/gain_controller2.h @@ -38,8 +38,6 @@ class GainController2 { void ApplyConfig(const AudioProcessing::Config::GainController2& config); static bool Validate(const AudioProcessing::Config::GainController2& config); - static std::string ToString( - const AudioProcessing::Config::GainController2& config); private: static int instance_count_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/audio_processing.cc b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/audio_processing.cc index 88544159a..04336b611 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/audio_processing.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/audio_processing.cc @@ -16,6 +16,9 @@ namespace webrtc { namespace { +using Agc1Config = AudioProcessing::Config::GainController1; +using Agc2Config = AudioProcessing::Config::GainController2; + std::string NoiseSuppressionLevelToString( const AudioProcessing::Config::NoiseSuppression::Level& level) { switch (level) { @@ -28,28 +31,30 @@ std::string NoiseSuppressionLevelToString( case AudioProcessing::Config::NoiseSuppression::Level::kVeryHigh: return "VeryHigh"; } + RTC_CHECK_NOTREACHED(); } -std::string GainController1ModeToString( - const AudioProcessing::Config::GainController1::Mode& mode) { +std::string GainController1ModeToString(const Agc1Config::Mode& mode) { switch (mode) { - case AudioProcessing::Config::GainController1::Mode::kAdaptiveAnalog: + case Agc1Config::Mode::kAdaptiveAnalog: return "AdaptiveAnalog"; - case AudioProcessing::Config::GainController1::Mode::kAdaptiveDigital: + case Agc1Config::Mode::kAdaptiveDigital: return "AdaptiveDigital"; - case AudioProcessing::Config::GainController1::Mode::kFixedDigital: + case Agc1Config::Mode::kFixedDigital: return "FixedDigital"; } + RTC_CHECK_NOTREACHED(); } std::string GainController2LevelEstimatorToString( - const AudioProcessing::Config::GainController2::LevelEstimator& level) { + const Agc2Config::LevelEstimator& level) { switch (level) { - case AudioProcessing::Config::GainController2::LevelEstimator::kRms: + case Agc2Config::LevelEstimator::kRms: return "Rms"; - case AudioProcessing::Config::GainController2::LevelEstimator::kPeak: + case Agc2Config::LevelEstimator::kPeak: return "Peak"; } + RTC_CHECK_NOTREACHED(); } int GetDefaultMaxInternalRate() { @@ -70,20 +75,60 @@ void CustomProcessing::SetRuntimeSetting( AudioProcessing::Config::Pipeline::Pipeline() : maximum_internal_processing_rate(GetDefaultMaxInternalRate()) {} +bool Agc1Config::operator==(const Agc1Config& rhs) const { + const auto& analog_lhs = analog_gain_controller; + const auto& analog_rhs = rhs.analog_gain_controller; + return enabled == rhs.enabled && mode == rhs.mode && + target_level_dbfs == rhs.target_level_dbfs && + compression_gain_db == rhs.compression_gain_db && + enable_limiter == rhs.enable_limiter && + analog_level_minimum == rhs.analog_level_minimum && + analog_level_maximum == rhs.analog_level_maximum && + analog_lhs.enabled == analog_rhs.enabled && + analog_lhs.startup_min_volume == analog_rhs.startup_min_volume && + analog_lhs.clipped_level_min == analog_rhs.clipped_level_min && + analog_lhs.enable_agc2_level_estimator == + analog_rhs.enable_agc2_level_estimator && + analog_lhs.enable_digital_adaptive == + analog_rhs.enable_digital_adaptive; +} + +bool Agc2Config::operator==(const Agc2Config& rhs) const { + const auto& adaptive_lhs = adaptive_digital; + const auto& adaptive_rhs = rhs.adaptive_digital; + + return enabled == rhs.enabled && + fixed_digital.gain_db == rhs.fixed_digital.gain_db && + adaptive_lhs.enabled == adaptive_rhs.enabled && + adaptive_lhs.vad_probability_attack == + adaptive_rhs.vad_probability_attack && + adaptive_lhs.level_estimator == adaptive_rhs.level_estimator && + adaptive_lhs.level_estimator_adjacent_speech_frames_threshold == + adaptive_rhs.level_estimator_adjacent_speech_frames_threshold && + adaptive_lhs.use_saturation_protector == + adaptive_rhs.use_saturation_protector && + adaptive_lhs.initial_saturation_margin_db == + adaptive_rhs.initial_saturation_margin_db && + adaptive_lhs.extra_saturation_margin_db == + adaptive_rhs.extra_saturation_margin_db && + adaptive_lhs.gain_applier_adjacent_speech_frames_threshold == + adaptive_rhs.gain_applier_adjacent_speech_frames_threshold && + adaptive_lhs.max_gain_change_db_per_second == + adaptive_rhs.max_gain_change_db_per_second && + adaptive_lhs.max_output_noise_level_dbfs == + adaptive_rhs.max_output_noise_level_dbfs; +} + std::string AudioProcessing::Config::ToString() const { - char buf[1024]; + char buf[2048]; rtc::SimpleStringBuilder builder(buf); builder << "AudioProcessing::Config{ " "pipeline: {" "maximum_internal_processing_rate: " << pipeline.maximum_internal_processing_rate << ", multi_channel_render: " << pipeline.multi_channel_render - << ", " - ", multi_channel_capture: " - << pipeline.multi_channel_capture - << "}, " - "pre_amplifier: { enabled: " - << pre_amplifier.enabled + << ", multi_channel_capture: " << pipeline.multi_channel_capture + << "}, pre_amplifier: { enabled: " << pre_amplifier.enabled << ", fixed_gain_factor: " << pre_amplifier.fixed_gain_factor << " }, high_pass_filter: { enabled: " << high_pass_filter.enabled << " }, echo_canceller: { enabled: " << echo_canceller.enabled @@ -106,18 +151,29 @@ std::string AudioProcessing::Config::ToString() const { << " }, gain_controller2: { enabled: " << gain_controller2.enabled << ", fixed_digital: { gain_db: " << gain_controller2.fixed_digital.gain_db - << " }, adaptive_digital: { enabled: " - << gain_controller2.adaptive_digital.enabled << ", level_estimator: " + << "}, adaptive_digital: { enabled: " + << gain_controller2.adaptive_digital.enabled + << ", level_estimator: { type: " << GainController2LevelEstimatorToString( gain_controller2.adaptive_digital.level_estimator) - << ", use_saturation_protector: " - << gain_controller2.adaptive_digital.use_saturation_protector + << ", adjacent_speech_frames_threshold: " + << gain_controller2.adaptive_digital + .level_estimator_adjacent_speech_frames_threshold + << ", initial_saturation_margin_db: " + << gain_controller2.adaptive_digital.initial_saturation_margin_db << ", extra_saturation_margin_db: " << gain_controller2.adaptive_digital.extra_saturation_margin_db + << "}, gain_applier: { adjacent_speech_frames_threshold: " + << gain_controller2.adaptive_digital + .gain_applier_adjacent_speech_frames_threshold + << ", max_gain_change_db_per_second: " + << gain_controller2.adaptive_digital.max_gain_change_db_per_second + << ", max_output_noise_level_dbfs: " + << gain_controller2.adaptive_digital.max_output_noise_level_dbfs << " } }, residual_echo_detector: { enabled: " << residual_echo_detector.enabled << " }, level_estimation: { enabled: " << level_estimation.enabled - << " } }"; + << " }}}"; return builder.str(); } diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/audio_processing.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/audio_processing.h index d84318f2a..e85ac0c63 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/audio_processing.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/audio_processing.h @@ -31,6 +31,7 @@ #include "modules/audio_processing/include/audio_processing_statistics.h" #include "modules/audio_processing/include/config.h" #include "rtc_base/arraysize.h" +#include "rtc_base/constructor_magic.h" #include "rtc_base/deprecation.h" #include "rtc_base/ref_count.h" #include "rtc_base/system/file_wrapper.h" @@ -104,7 +105,7 @@ struct ExperimentalAgc { // AudioProcessing::Config::TransientSuppression. // // Use to enable experimental noise suppression. It can be set in the -// constructor or using AudioProcessing::SetExtraOptions(). +// constructor. // TODO(webrtc:5298): Remove. struct ExperimentalNs { ExperimentalNs() : enabled(false) {} @@ -273,6 +274,11 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { // HAL. // Recommended to be enabled on the client-side. struct GainController1 { + bool operator==(const GainController1& rhs) const; + bool operator!=(const GainController1& rhs) const { + return !(*this == rhs); + } + bool enabled = false; enum Mode { // Adaptive mode intended for use if an analog volume control is @@ -337,6 +343,11 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { // first applies a fixed gain. The adaptive digital AGC can be turned off by // setting |adaptive_digital_mode=false|. struct GainController2 { + bool operator==(const GainController2& rhs) const; + bool operator!=(const GainController2& rhs) const { + return !(*this == rhs); + } + enum LevelEstimator { kRms, kPeak }; bool enabled = false; struct { @@ -344,9 +355,16 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { } fixed_digital; struct { bool enabled = false; + float vad_probability_attack = 1.f; LevelEstimator level_estimator = kRms; + int level_estimator_adjacent_speech_frames_threshold = 1; + // TODO(crbug.com/webrtc/7494): Remove `use_saturation_protector`. bool use_saturation_protector = true; + float initial_saturation_margin_db = 20.f; float extra_saturation_margin_db = 2.f; + int gain_applier_adjacent_speech_frames_threshold = 1; + float max_gain_change_db_per_second = 3.f; + float max_output_noise_level_dbfs = -50.f; } adaptive_digital; } gain_controller2; @@ -384,7 +402,8 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { kCaptureFixedPostGain, kPlayoutVolumeChange, kCustomRenderProcessingRuntimeSetting, - kPlayoutAudioDeviceChange + kPlayoutAudioDeviceChange, + kCaptureOutputUsed }; // Play-out audio device properties. @@ -434,6 +453,10 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { return {Type::kCustomRenderProcessingRuntimeSetting, payload}; } + static RuntimeSetting CreateCaptureOutputUsedSetting(bool payload) { + return {Type::kCaptureOutputUsed, payload}; + } + Type type() const { return type_; } // Getters do not return a value but instead modify the argument to protect // from implicit casting. @@ -445,6 +468,10 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { RTC_DCHECK(value); *value = value_.int_value; } + void GetBool(bool* value) const { + RTC_DCHECK(value); + *value = value_.bool_value; + } void GetPlayoutAudioDeviceInfo(PlayoutAudioDeviceInfo* value) const { RTC_DCHECK(value); *value = value_.playout_audio_device_info; @@ -463,6 +490,7 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { U(PlayoutAudioDeviceInfo value) : playout_audio_device_info(value) {} float float_value; int int_value; + bool bool_value; PlayoutAudioDeviceInfo playout_audio_device_info; } value_; }; @@ -478,6 +506,7 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { // rate and number of channels) have changed. Passing updated parameters // directly to |ProcessStream()| and |ProcessReverseStream()| is permissible. // If the parameters are known at init-time though, they may be provided. + // TODO(webrtc:5298): Change to return void. virtual int Initialize() = 0; // The int16 interfaces require: @@ -505,10 +534,6 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface { // over the parameters in the audio processing module and is likely to change. virtual void ApplyConfig(const Config& config) = 0; - // Pass down additional options which don't have explicit setters. This - // ensures the options are applied immediately. - virtual void SetExtraOptions(const webrtc::Config& config) = 0; - // TODO(ajm): Only intended for internal use. Make private and friend the // necessary classes? virtual int proc_sample_rate_hz() const = 0; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/config.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/config.h index 8a245864e..7fab17831 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/config.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/config.h @@ -13,7 +13,6 @@ #include -#include "rtc_base/constructor_magic.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { @@ -105,7 +104,6 @@ class RTC_EXPORT Config { typedef std::map OptionMap; OptionMap options_; - // RTC_DISALLOW_COPY_AND_ASSIGN Config(const Config&); void operator=(const Config&); }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/mock_audio_processing.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/mock_audio_processing.h index 562b23f7d..2055f7e51 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/mock_audio_processing.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/include/mock_audio_processing.h @@ -88,10 +88,6 @@ class MockAudioProcessing : public ::testing::NiceMock { (const ProcessingConfig& processing_config), (override)); MOCK_METHOD(void, ApplyConfig, (const Config& config), (override)); - MOCK_METHOD(void, - SetExtraOptions, - (const webrtc::Config& config), - (override)); MOCK_METHOD(int, proc_sample_rate_hz, (), (const, override)); MOCK_METHOD(int, proc_split_sample_rate_hz, (), (const, override)); MOCK_METHOD(size_t, num_input_channels, (), (const, override)); diff --git a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/logging/apm_data_dumper.h b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/logging/apm_data_dumper.h index 17a5c8771..1824fdd2a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/audio_processing/logging/apm_data_dumper.h +++ b/TMessagesProj/jni/voip/webrtc/modules/audio_processing/logging/apm_data_dumper.h @@ -26,7 +26,6 @@ #include "common_audio/wav_file.h" #include "rtc_base/checks.h" #endif -#include "rtc_base/constructor_magic.h" // Check to verify that the define is properly set. #if !defined(WEBRTC_APM_DEBUG_DUMP) || \ @@ -52,6 +51,10 @@ class ApmDataDumper { // instances of the code. explicit ApmDataDumper(int instance_index); + ApmDataDumper() = delete; + ApmDataDumper(const ApmDataDumper&) = delete; + ApmDataDumper& operator=(const ApmDataDumper&) = delete; + ~ApmDataDumper(); // Activates or deactivate the dumping functionality. @@ -277,7 +280,6 @@ class ApmDataDumper { int num_channels, WavFile::SampleFormat format); #endif - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ApmDataDumper); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/delay_based_bwe.h b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/delay_based_bwe.h index 25f5a3be7..74650dc82 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/delay_based_bwe.h +++ b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/delay_based_bwe.h @@ -26,7 +26,6 @@ #include "modules/remote_bitrate_estimator/aimd_rate_control.h" #include "modules/remote_bitrate_estimator/include/bwe_defines.h" #include "modules/remote_bitrate_estimator/inter_arrival.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/experiments/struct_parameters_parser.h" #include "rtc_base/race_checker.h" @@ -78,6 +77,11 @@ class DelayBasedBwe { explicit DelayBasedBwe(const WebRtcKeyValueConfig* key_value_config, RtcEventLog* event_log, NetworkStatePredictor* network_state_predictor); + + DelayBasedBwe() = delete; + DelayBasedBwe(const DelayBasedBwe&) = delete; + DelayBasedBwe& operator=(const DelayBasedBwe&) = delete; + virtual ~DelayBasedBwe(); Result IncomingPacketFeedbackVector( @@ -143,7 +147,6 @@ class DelayBasedBwe { bool has_once_detected_overuse_; BandwidthUsage prev_state_; bool alr_limited_backoff_enabled_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayBasedBwe); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc index b8be0982d..0a0b1801f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -96,7 +96,8 @@ GoogCcNetworkController::GoogCcNetworkController(NetworkControllerConfig config, key_value_config_) : nullptr), bandwidth_estimation_( - std::make_unique(event_log_)), + std::make_unique(key_value_config_, + event_log_)), alr_detector_( std::make_unique(key_value_config_, config.event_log)), probe_bitrate_estimator_(new ProbeBitrateEstimator(config.event_log)), diff --git a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.h b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.h index 1e4dcf62e..6dd70c896 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.h +++ b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.h @@ -33,7 +33,6 @@ #include "modules/congestion_controller/goog_cc/delay_based_bwe.h" #include "modules/congestion_controller/goog_cc/probe_controller.h" #include "modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/rate_control_settings.h" @@ -48,6 +47,11 @@ class GoogCcNetworkController : public NetworkControllerInterface { public: GoogCcNetworkController(NetworkControllerConfig config, GoogCcConfig goog_cc_config); + + GoogCcNetworkController() = delete; + GoogCcNetworkController(const GoogCcNetworkController&) = delete; + GoogCcNetworkController& operator=(const GoogCcNetworkController&) = delete; + ~GoogCcNetworkController() override; // NetworkControllerInterface @@ -137,8 +141,6 @@ class GoogCcNetworkController : public NetworkControllerInterface { bool previously_in_alr_ = false; absl::optional current_data_window_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(GoogCcNetworkController); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc index d2ae52840..4ca75bf26 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc @@ -19,6 +19,8 @@ #include "absl/strings/match.h" #include "api/rtc_event_log/rtc_event.h" #include "api/rtc_event_log/rtc_event_log.h" +#include "api/transport/webrtc_key_value_config.h" +#include "api/units/time_delta.h" #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h" #include "modules/remote_bitrate_estimator/include/bwe_defines.h" #include "rtc_base/checks.h" @@ -153,19 +155,24 @@ DataRate LinkCapacityTracker::estimate() const { return DataRate::BitsPerSec(capacity_estimate_bps_); } -RttBasedBackoff::RttBasedBackoff() - : rtt_limit_("limit", TimeDelta::Seconds(3)), +RttBasedBackoff::RttBasedBackoff(const WebRtcKeyValueConfig* key_value_config) + : disabled_("Disabled"), + configured_limit_("limit", TimeDelta::Seconds(3)), drop_fraction_("fraction", 0.8), drop_interval_("interval", TimeDelta::Seconds(1)), bandwidth_floor_("floor", DataRate::KilobitsPerSec(5)), + rtt_limit_(TimeDelta::PlusInfinity()), // By initializing this to plus infinity, we make sure that we never // trigger rtt backoff unless packet feedback is enabled. last_propagation_rtt_update_(Timestamp::PlusInfinity()), last_propagation_rtt_(TimeDelta::Zero()), last_packet_sent_(Timestamp::MinusInfinity()) { - ParseFieldTrial( - {&rtt_limit_, &drop_fraction_, &drop_interval_, &bandwidth_floor_}, - field_trial::FindFullName("WebRTC-Bwe-MaxRttLimit")); + ParseFieldTrial({&disabled_, &configured_limit_, &drop_fraction_, + &drop_interval_, &bandwidth_floor_}, + key_value_config->Lookup("WebRTC-Bwe-MaxRttLimit")); + if (!disabled_) { + rtt_limit_ = configured_limit_.Get(); + } } void RttBasedBackoff::UpdatePropagationRtt(Timestamp at_time, @@ -186,8 +193,11 @@ TimeDelta RttBasedBackoff::CorrectedRtt(Timestamp at_time) const { RttBasedBackoff::~RttBasedBackoff() = default; -SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log) - : lost_packets_since_last_loss_update_(0), +SendSideBandwidthEstimation::SendSideBandwidthEstimation( + const WebRtcKeyValueConfig* key_value_config, + RtcEventLog* event_log) + : rtt_backoff_(key_value_config), + lost_packets_since_last_loss_update_(0), expected_packets_since_last_loss_update_(0), current_target_(DataRate::Zero()), last_logged_target_(DataRate::Zero()), diff --git a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h index 241ec8c84..a13800b7f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h +++ b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h @@ -21,6 +21,7 @@ #include "absl/types/optional.h" #include "api/transport/network_types.h" +#include "api/transport/webrtc_key_value_config.h" #include "api/units/data_rate.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" @@ -54,17 +55,19 @@ class LinkCapacityTracker { class RttBasedBackoff { public: - RttBasedBackoff(); + explicit RttBasedBackoff(const WebRtcKeyValueConfig* key_value_config); ~RttBasedBackoff(); void UpdatePropagationRtt(Timestamp at_time, TimeDelta propagation_rtt); TimeDelta CorrectedRtt(Timestamp at_time) const; - FieldTrialParameter rtt_limit_; + FieldTrialFlag disabled_; + FieldTrialParameter configured_limit_; FieldTrialParameter drop_fraction_; FieldTrialParameter drop_interval_; FieldTrialParameter bandwidth_floor_; public: + TimeDelta rtt_limit_; Timestamp last_propagation_rtt_update_; TimeDelta last_propagation_rtt_; Timestamp last_packet_sent_; @@ -73,7 +76,8 @@ class RttBasedBackoff { class SendSideBandwidthEstimation { public: SendSideBandwidthEstimation() = delete; - explicit SendSideBandwidthEstimation(RtcEventLog* event_log); + SendSideBandwidthEstimation(const WebRtcKeyValueConfig* key_value_config, + RtcEventLog* event_log); ~SendSideBandwidthEstimation(); void OnRouteChange(); diff --git a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc deleted file mode 100644 index 52baab06c..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 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 "modules/congestion_controller/goog_cc/test/goog_cc_printer.h" - -#include - -#include - -#include "absl/types/optional.h" -#include "modules/congestion_controller/goog_cc/alr_detector.h" -#include "modules/congestion_controller/goog_cc/delay_based_bwe.h" -#include "modules/congestion_controller/goog_cc/trendline_estimator.h" -#include "modules/remote_bitrate_estimator/aimd_rate_control.h" -#include "rtc_base/checks.h" - -namespace webrtc { -namespace { -void WriteTypedValue(RtcEventLogOutput* out, int value) { - LogWriteFormat(out, "%i", value); -} -void WriteTypedValue(RtcEventLogOutput* out, double value) { - LogWriteFormat(out, "%.6f", value); -} -void WriteTypedValue(RtcEventLogOutput* out, absl::optional value) { - LogWriteFormat(out, "%.0f", value ? value->bytes_per_sec() : NAN); -} -void WriteTypedValue(RtcEventLogOutput* out, absl::optional value) { - LogWriteFormat(out, "%.0f", value ? value->bytes() : NAN); -} -void WriteTypedValue(RtcEventLogOutput* out, absl::optional value) { - LogWriteFormat(out, "%.3f", value ? value->seconds() : NAN); -} -void WriteTypedValue(RtcEventLogOutput* out, absl::optional value) { - LogWriteFormat(out, "%.3f", value ? value->seconds() : NAN); -} - -template -class TypedFieldLogger : public FieldLogger { - public: - TypedFieldLogger(std::string name, F&& getter) - : name_(std::move(name)), getter_(std::forward(getter)) {} - const std::string& name() const override { return name_; } - void WriteValue(RtcEventLogOutput* out) override { - WriteTypedValue(out, getter_()); - } - - private: - std::string name_; - F getter_; -}; - -template -FieldLogger* Log(std::string name, F&& getter) { - return new TypedFieldLogger(std::move(name), std::forward(getter)); -} - -} // namespace -GoogCcStatePrinter::GoogCcStatePrinter() { - for (auto* logger : CreateLoggers()) { - loggers_.emplace_back(logger); - } -} - -std::deque GoogCcStatePrinter::CreateLoggers() { - auto stable_estimate = [this] { - return DataRate::KilobitsPerSec( - controller_->delay_based_bwe_->rate_control_.link_capacity_ - .estimate_kbps_.value_or(-INFINITY)); - }; - auto rate_control_state = [this] { - return static_cast( - controller_->delay_based_bwe_->rate_control_.rate_control_state_); - }; - auto trend = [this] { - return reinterpret_cast( - controller_->delay_based_bwe_->active_delay_detector_); - }; - auto acknowledged_rate = [this] { - return controller_->acknowledged_bitrate_estimator_->bitrate(); - }; - auto loss_cont = [&] { - return &controller_->bandwidth_estimation_ - ->loss_based_bandwidth_estimation_; - }; - std::deque loggers({ - Log("time", [=] { return target_.at_time; }), - Log("rtt", [=] { return target_.network_estimate.round_trip_time; }), - Log("target", [=] { return target_.target_rate; }), - Log("stable_target", [=] { return target_.stable_target_rate; }), - Log("pacing", [=] { return pacing_.data_rate(); }), - Log("padding", [=] { return pacing_.pad_rate(); }), - Log("window", [=] { return congestion_window_; }), - Log("rate_control_state", [=] { return rate_control_state(); }), - Log("stable_estimate", [=] { return stable_estimate(); }), - Log("trendline", [=] { return trend()->prev_trend_; }), - Log("trendline_modified_offset", - [=] { return trend()->prev_modified_trend_; }), - Log("trendline_offset_threshold", [=] { return trend()->threshold_; }), - Log("acknowledged_rate", [=] { return acknowledged_rate(); }), - Log("est_capacity", [=] { return est_.link_capacity; }), - Log("est_capacity_dev", [=] { return est_.link_capacity_std_dev; }), - Log("est_capacity_min", [=] { return est_.link_capacity_min; }), - Log("est_cross_traffic", [=] { return est_.cross_traffic_ratio; }), - Log("est_cross_delay", [=] { return est_.cross_delay_rate; }), - Log("est_spike_delay", [=] { return est_.spike_delay_rate; }), - Log("est_pre_buffer", [=] { return est_.pre_link_buffer_delay; }), - Log("est_post_buffer", [=] { return est_.post_link_buffer_delay; }), - Log("est_propagation", [=] { return est_.propagation_delay; }), - Log("loss_ratio", [=] { return loss_cont()->last_loss_ratio_; }), - Log("loss_average", [=] { return loss_cont()->average_loss_; }), - Log("loss_average_max", [=] { return loss_cont()->average_loss_max_; }), - Log("loss_thres_inc", - [=] { return loss_cont()->loss_increase_threshold(); }), - Log("loss_thres_dec", - [=] { return loss_cont()->loss_decrease_threshold(); }), - Log("loss_dec_rate", [=] { return loss_cont()->decreased_bitrate(); }), - Log("loss_based_rate", [=] { return loss_cont()->loss_based_bitrate_; }), - Log("loss_ack_rate", - [=] { return loss_cont()->acknowledged_bitrate_max_; }), - Log("data_window", [=] { return controller_->current_data_window_; }), - Log("pushback_target", - [=] { return controller_->last_pushback_target_rate_; }), - }); - return loggers; -} -GoogCcStatePrinter::~GoogCcStatePrinter() = default; - -void GoogCcStatePrinter::PrintHeaders(RtcEventLogOutput* log) { - int ix = 0; - for (const auto& logger : loggers_) { - if (ix++) - log->Write(" "); - log->Write(logger->name()); - } - log->Write("\n"); - log->Flush(); -} - -void GoogCcStatePrinter::PrintState(RtcEventLogOutput* log, - GoogCcNetworkController* controller, - Timestamp at_time) { - controller_ = controller; - auto state_update = controller_->GetNetworkState(at_time); - target_ = state_update.target_rate.value(); - pacing_ = state_update.pacer_config.value(); - if (state_update.congestion_window) - congestion_window_ = *state_update.congestion_window; - if (controller_->network_estimator_) { - est_ = controller_->network_estimator_->GetCurrentEstimate().value_or( - NetworkStateEstimate()); - } - - int ix = 0; - for (const auto& logger : loggers_) { - if (ix++) - log->Write(" "); - logger->WriteValue(log); - } - - log->Write("\n"); - log->Flush(); -} - -GoogCcDebugFactory::GoogCcDebugFactory() - : GoogCcDebugFactory(GoogCcFactoryConfig()) {} - -GoogCcDebugFactory::GoogCcDebugFactory(GoogCcFactoryConfig config) - : GoogCcNetworkControllerFactory(std::move(config)) {} - -std::unique_ptr GoogCcDebugFactory::Create( - NetworkControllerConfig config) { - RTC_CHECK(controller_ == nullptr); - auto controller = GoogCcNetworkControllerFactory::Create(config); - controller_ = static_cast(controller.get()); - return controller; -} - -void GoogCcDebugFactory::PrintState(const Timestamp at_time) { - if (controller_ && log_writer_) { - printer_.PrintState(log_writer_.get(), controller_, at_time); - } -} - -void GoogCcDebugFactory::AttachWriter( - std::unique_ptr log_writer) { - if (log_writer) { - log_writer_ = std::move(log_writer); - printer_.PrintHeaders(log_writer_.get()); - } -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/test/goog_cc_printer.h b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/test/goog_cc_printer.h deleted file mode 100644 index 3eee7814c..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/goog_cc/test/goog_cc_printer.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 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. - */ -#ifndef MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_ -#define MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_ - -#include -#include -#include - -#include "api/rtc_event_log/rtc_event_log.h" -#include "api/transport/goog_cc_factory.h" -#include "api/transport/network_control.h" -#include "api/transport/network_types.h" -#include "api/units/timestamp.h" -#include "modules/congestion_controller/goog_cc/goog_cc_network_control.h" -#include "test/logging/log_writer.h" - -namespace webrtc { - -class FieldLogger { - public: - virtual ~FieldLogger() = default; - virtual const std::string& name() const = 0; - virtual void WriteValue(RtcEventLogOutput* out) = 0; -}; - -class GoogCcStatePrinter { - public: - GoogCcStatePrinter(); - GoogCcStatePrinter(const GoogCcStatePrinter&) = delete; - GoogCcStatePrinter& operator=(const GoogCcStatePrinter&) = delete; - ~GoogCcStatePrinter(); - - void PrintHeaders(RtcEventLogOutput* log); - void PrintState(RtcEventLogOutput* log, - GoogCcNetworkController* controller, - Timestamp at_time); - - private: - std::deque CreateLoggers(); - std::deque> loggers_; - - GoogCcNetworkController* controller_ = nullptr; - TargetTransferRate target_; - PacerConfig pacing_; - DataSize congestion_window_ = DataSize::PlusInfinity(); - NetworkStateEstimate est_; -}; - -class GoogCcDebugFactory : public GoogCcNetworkControllerFactory { - public: - GoogCcDebugFactory(); - explicit GoogCcDebugFactory(GoogCcFactoryConfig config); - std::unique_ptr Create( - NetworkControllerConfig config) override; - - void PrintState(const Timestamp at_time); - - void AttachWriter(std::unique_ptr log_writer); - - private: - GoogCcStatePrinter printer_; - GoogCcNetworkController* controller_ = nullptr; - std::unique_ptr log_writer_; -}; -} // namespace webrtc - -#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/include/receive_side_congestion_controller.h b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/include/receive_side_congestion_controller.h index 6cd8be39a..034f2e951 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/include/receive_side_congestion_controller.h +++ b/TMessagesProj/jni/voip/webrtc/modules/congestion_controller/include/receive_side_congestion_controller.h @@ -18,7 +18,6 @@ #include "api/transport/network_control.h" #include "modules/include/module.h" #include "modules/remote_bitrate_estimator/remote_estimator_proxy.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/synchronization/mutex.h" namespace webrtc { @@ -66,6 +65,11 @@ class ReceiveSideCongestionController : public CallStatsObserver, public: WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock); + WrappingBitrateEstimator() = delete; + WrappingBitrateEstimator(const WrappingBitrateEstimator&) = delete; + WrappingBitrateEstimator& operator=(const WrappingBitrateEstimator&) = + delete; + ~WrappingBitrateEstimator() override; void IncomingPacket(int64_t arrival_time_ms, @@ -96,8 +100,6 @@ class ReceiveSideCongestionController : public CallStatsObserver, bool using_absolute_send_time_; uint32_t packets_since_absolute_send_time_; int min_bitrate_bps_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator); }; const FieldTrialBasedConfig field_trial_config_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/OWNERS b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/OWNERS deleted file mode 100644 index eaa671cb7..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -jamiewalch@chromium.org -sergeyu@chromium.org diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc deleted file mode 100644 index ca3a89f49..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/blank_detector_desktop_capturer_wrapper.h" - -#include - -#include - -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/desktop_region.h" -#include "rtc_base/checks.h" -#include "system_wrappers/include/metrics.h" - -namespace webrtc { - -BlankDetectorDesktopCapturerWrapper::BlankDetectorDesktopCapturerWrapper( - std::unique_ptr capturer, - RgbaColor blank_pixel) - : capturer_(std::move(capturer)), blank_pixel_(blank_pixel) { - RTC_DCHECK(capturer_); -} - -BlankDetectorDesktopCapturerWrapper::~BlankDetectorDesktopCapturerWrapper() = - default; - -void BlankDetectorDesktopCapturerWrapper::Start( - DesktopCapturer::Callback* callback) { - callback_ = callback; - capturer_->Start(this); -} - -void BlankDetectorDesktopCapturerWrapper::SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) { - capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); -} - -void BlankDetectorDesktopCapturerWrapper::CaptureFrame() { - RTC_DCHECK(callback_); - capturer_->CaptureFrame(); -} - -void BlankDetectorDesktopCapturerWrapper::SetExcludedWindow(WindowId window) { - capturer_->SetExcludedWindow(window); -} - -bool BlankDetectorDesktopCapturerWrapper::GetSourceList(SourceList* sources) { - return capturer_->GetSourceList(sources); -} - -bool BlankDetectorDesktopCapturerWrapper::SelectSource(SourceId id) { - return capturer_->SelectSource(id); -} - -bool BlankDetectorDesktopCapturerWrapper::FocusOnSelectedSource() { - return capturer_->FocusOnSelectedSource(); -} - -bool BlankDetectorDesktopCapturerWrapper::IsOccluded(const DesktopVector& pos) { - return capturer_->IsOccluded(pos); -} - -void BlankDetectorDesktopCapturerWrapper::OnCaptureResult( - Result result, - std::unique_ptr frame) { - RTC_DCHECK(callback_); - if (result != Result::SUCCESS || non_blank_frame_received_) { - callback_->OnCaptureResult(result, std::move(frame)); - return; - } - - RTC_DCHECK(frame); - - // If nothing has been changed in current frame, we do not need to check it - // again. - if (!frame->updated_region().is_empty() || is_first_frame_) { - last_frame_is_blank_ = IsBlankFrame(*frame); - is_first_frame_ = false; - } - RTC_HISTOGRAM_BOOLEAN("WebRTC.DesktopCapture.BlankFrameDetected", - last_frame_is_blank_); - if (!last_frame_is_blank_) { - non_blank_frame_received_ = true; - callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); - return; - } - - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, - std::unique_ptr()); -} - -bool BlankDetectorDesktopCapturerWrapper::IsBlankFrame( - const DesktopFrame& frame) const { - // We will check 7489 pixels for a frame with 1024 x 768 resolution. - for (int i = 0; i < frame.size().width() * frame.size().height(); i += 105) { - const int x = i % frame.size().width(); - const int y = i / frame.size().width(); - if (!IsBlankPixel(frame, x, y)) { - return false; - } - } - - // We are verifying the pixel in the center as well. - return IsBlankPixel(frame, frame.size().width() / 2, - frame.size().height() / 2); -} - -bool BlankDetectorDesktopCapturerWrapper::IsBlankPixel( - const DesktopFrame& frame, - int x, - int y) const { - uint8_t* pixel_data = frame.GetFrameDataAtPos(DesktopVector(x, y)); - return RgbaColor(pixel_data) == blank_pixel_; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h deleted file mode 100644 index 46ba5257f..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_BLANK_DETECTOR_DESKTOP_CAPTURER_WRAPPER_H_ -#define MODULES_DESKTOP_CAPTURE_BLANK_DETECTOR_DESKTOP_CAPTURER_WRAPPER_H_ - -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/rgba_color.h" -#include "modules/desktop_capture/shared_memory.h" - -namespace webrtc { - -// A DesktopCapturer wrapper detects the return value of its owned -// DesktopCapturer implementation. If sampled pixels returned by the -// DesktopCapturer implementation all equal to the blank pixel, this wrapper -// returns ERROR_TEMPORARY. If the DesktopCapturer implementation fails for too -// many times, this wrapper returns ERROR_PERMANENT. -class BlankDetectorDesktopCapturerWrapper final - : public DesktopCapturer, - public DesktopCapturer::Callback { - public: - // Creates BlankDetectorDesktopCapturerWrapper. BlankDesktopCapturerWrapper - // takes ownership of |capturer|. The |blank_pixel| is the unmodified color - // returned by the |capturer|. - BlankDetectorDesktopCapturerWrapper(std::unique_ptr capturer, - RgbaColor blank_pixel); - ~BlankDetectorDesktopCapturerWrapper() override; - - // DesktopCapturer interface. - void Start(DesktopCapturer::Callback* callback) override; - void SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) override; - void CaptureFrame() override; - void SetExcludedWindow(WindowId window) override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - bool FocusOnSelectedSource() override; - bool IsOccluded(const DesktopVector& pos) override; - - private: - // DesktopCapturer::Callback interface. - void OnCaptureResult(Result result, - std::unique_ptr frame) override; - - bool IsBlankFrame(const DesktopFrame& frame) const; - - // Detects whether pixel at (x, y) equals to |blank_pixel_|. - bool IsBlankPixel(const DesktopFrame& frame, int x, int y) const; - - const std::unique_ptr capturer_; - const RgbaColor blank_pixel_; - - // Whether a non-blank frame has been received. - bool non_blank_frame_received_ = false; - - // Whether the last frame is blank. - bool last_frame_is_blank_ = false; - - // Whether current frame is the first frame. - bool is_first_frame_ = true; - - DesktopCapturer::Callback* callback_ = nullptr; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_BLANK_DETECTOR_DESKTOP_CAPTURER_WRAPPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.cc deleted file mode 100644 index e1d4b993e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/capture_result_desktop_capturer_wrapper.h" - -#include -#include - -#include "rtc_base/checks.h" - -namespace webrtc { - -CaptureResultDesktopCapturerWrapper::CaptureResultDesktopCapturerWrapper( - std::unique_ptr base_capturer, - ResultObserver* observer) - : DesktopCapturerWrapper(std::move(base_capturer)), observer_(observer) { - RTC_DCHECK(observer_); -} - -CaptureResultDesktopCapturerWrapper::~CaptureResultDesktopCapturerWrapper() = - default; - -void CaptureResultDesktopCapturerWrapper::Start(Callback* callback) { - if ((callback_ == nullptr) != (callback == nullptr)) { - if (callback) { - callback_ = callback; - base_capturer_->Start(this); - } else { - base_capturer_->Start(nullptr); - } - } - callback_ = callback; -} - -void CaptureResultDesktopCapturerWrapper::OnCaptureResult( - Result result, - std::unique_ptr frame) { - observer_->Observe(&result, &frame); - callback_->OnCaptureResult(result, std::move(frame)); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.h deleted file mode 100644 index 6d1d49a5e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_CAPTURE_RESULT_DESKTOP_CAPTURER_WRAPPER_H_ -#define MODULES_DESKTOP_CAPTURE_CAPTURE_RESULT_DESKTOP_CAPTURER_WRAPPER_H_ - -#include - -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_capturer_wrapper.h" -#include "modules/desktop_capture/desktop_frame.h" - -namespace webrtc { - -// A DesktopCapturerWrapper implementation to capture the result of -// |base_capturer|. Derived classes are expected to provide a ResultObserver -// implementation to observe the DesktopFrame returned by |base_capturer_|. -class CaptureResultDesktopCapturerWrapper : public DesktopCapturerWrapper, - public DesktopCapturer::Callback { - public: - using Callback = DesktopCapturer::Callback; - - // Provides a way to let derived classes or clients to modify the result - // returned by |base_capturer_|. - class ResultObserver { - public: - ResultObserver(); - virtual ~ResultObserver(); - - virtual void Observe(Result* result, - std::unique_ptr* frame) = 0; - }; - - // |observer| must outlive this instance and can be |this|. |observer| is - // guaranteed to be executed only after the constructor and before the - // destructor. - CaptureResultDesktopCapturerWrapper( - std::unique_ptr base_capturer, - ResultObserver* observer); - - ~CaptureResultDesktopCapturerWrapper() override; - - // DesktopCapturer implementations. - void Start(Callback* callback) final; - - private: - // DesktopCapturer::Callback implementation. - void OnCaptureResult(Result result, - std::unique_ptr frame) final; - - ResultObserver* const observer_; - Callback* callback_ = nullptr; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_CAPTURE_RESULT_DESKTOP_CAPTURER_WRAPPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropped_desktop_frame.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropped_desktop_frame.cc deleted file mode 100644 index 1ab035507..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropped_desktop_frame.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2014 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/desktop_capture/cropped_desktop_frame.h" - -#include -#include - -#include "modules/desktop_capture/desktop_region.h" -#include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -// A DesktopFrame that is a sub-rect of another DesktopFrame. -class CroppedDesktopFrame : public DesktopFrame { - public: - CroppedDesktopFrame(std::unique_ptr frame, - const DesktopRect& rect); - - private: - const std::unique_ptr frame_; - - RTC_DISALLOW_COPY_AND_ASSIGN(CroppedDesktopFrame); -}; - -std::unique_ptr CreateCroppedDesktopFrame( - std::unique_ptr frame, - const DesktopRect& rect) { - RTC_DCHECK(frame); - - if (!DesktopRect::MakeSize(frame->size()).ContainsRect(rect)) { - return nullptr; - } - - if (frame->size().equals(rect.size())) { - return frame; - } - - return std::unique_ptr( - new CroppedDesktopFrame(std::move(frame), rect)); -} - -CroppedDesktopFrame::CroppedDesktopFrame(std::unique_ptr frame, - const DesktopRect& rect) - : DesktopFrame(rect.size(), - frame->stride(), - frame->GetFrameDataAtPos(rect.top_left()), - frame->shared_memory()), - frame_(std::move(frame)) { - MoveFrameInfoFrom(frame_.get()); - set_top_left(frame_->top_left().add(rect.top_left())); - mutable_updated_region()->IntersectWith(rect); - mutable_updated_region()->Translate(-rect.left(), -rect.top()); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropped_desktop_frame.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropped_desktop_frame.h deleted file mode 100644 index bbc3c86ca..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropped_desktop_frame.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2014 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_ -#define MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_ - -#include - -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// Creates a DesktopFrame to contain only the area of |rect| in the original -// |frame|. -// |frame| should not be nullptr. |rect| is in |frame| coordinate, i.e. -// |frame|->top_left() does not impact the area of |rect|. -// Returns nullptr frame if |rect| is not contained by the bounds of |frame|. -std::unique_ptr RTC_EXPORT -CreateCroppedDesktopFrame(std::unique_ptr frame, - const DesktopRect& rect); - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer.cc deleted file mode 100644 index bd1ba4631..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2014 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/desktop_capture/cropping_window_capturer.h" - -#include - -#include - -#include "modules/desktop_capture/cropped_desktop_frame.h" -#include "rtc_base/logging.h" - -namespace webrtc { - -CroppingWindowCapturer::CroppingWindowCapturer( - const DesktopCaptureOptions& options) - : options_(options), - callback_(NULL), - window_capturer_(DesktopCapturer::CreateRawWindowCapturer(options)), - selected_window_(kNullWindowId), - excluded_window_(kNullWindowId) {} - -CroppingWindowCapturer::~CroppingWindowCapturer() {} - -void CroppingWindowCapturer::Start(DesktopCapturer::Callback* callback) { - callback_ = callback; - window_capturer_->Start(callback); -} - -void CroppingWindowCapturer::SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) { - window_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); -} - -void CroppingWindowCapturer::CaptureFrame() { - if (ShouldUseScreenCapturer()) { - if (!screen_capturer_.get()) { - screen_capturer_ = DesktopCapturer::CreateRawScreenCapturer(options_); - if (excluded_window_) { - screen_capturer_->SetExcludedWindow(excluded_window_); - } - screen_capturer_->Start(this); - } - screen_capturer_->CaptureFrame(); - } else { - window_capturer_->CaptureFrame(); - } -} - -void CroppingWindowCapturer::SetExcludedWindow(WindowId window) { - excluded_window_ = window; - if (screen_capturer_.get()) { - screen_capturer_->SetExcludedWindow(window); - } -} - -bool CroppingWindowCapturer::GetSourceList(SourceList* sources) { - return window_capturer_->GetSourceList(sources); -} - -bool CroppingWindowCapturer::SelectSource(SourceId id) { - if (window_capturer_->SelectSource(id)) { - selected_window_ = id; - return true; - } - return false; -} - -bool CroppingWindowCapturer::FocusOnSelectedSource() { - return window_capturer_->FocusOnSelectedSource(); -} - -void CroppingWindowCapturer::OnCaptureResult( - DesktopCapturer::Result result, - std::unique_ptr screen_frame) { - if (!ShouldUseScreenCapturer()) { - RTC_LOG(LS_INFO) << "Window no longer on top when ScreenCapturer finishes"; - window_capturer_->CaptureFrame(); - return; - } - - if (result != Result::SUCCESS) { - RTC_LOG(LS_WARNING) << "ScreenCapturer failed to capture a frame"; - callback_->OnCaptureResult(result, nullptr); - return; - } - - DesktopRect window_rect = GetWindowRectInVirtualScreen(); - if (window_rect.is_empty()) { - RTC_LOG(LS_WARNING) << "Window rect is empty"; - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); - return; - } - - callback_->OnCaptureResult( - Result::SUCCESS, - CreateCroppedDesktopFrame(std::move(screen_frame), window_rect)); -} - -bool CroppingWindowCapturer::IsOccluded(const DesktopVector& pos) { - // Returns true if either capturer returns true. - if (window_capturer_->IsOccluded(pos)) { - return true; - } - if (screen_capturer_ != nullptr && screen_capturer_->IsOccluded(pos)) { - return true; - } - return false; -} - -#if !defined(WEBRTC_WIN) -// CroppingWindowCapturer is implemented only for windows. On other platforms -// the regular window capturer is used. -// static -std::unique_ptr CroppingWindowCapturer::CreateCapturer( - const DesktopCaptureOptions& options) { - return DesktopCapturer::CreateWindowCapturer(options); -} -#endif - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer.h deleted file mode 100644 index 272a19697..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2014 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_ -#define MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_ - -#include - -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/shared_memory.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// WindowCapturer implementation that uses a screen capturer to capture the -// whole screen and crops the video frame to the window area when the captured -// window is on top. -class RTC_EXPORT CroppingWindowCapturer : public DesktopCapturer, - public DesktopCapturer::Callback { - public: - static std::unique_ptr CreateCapturer( - const DesktopCaptureOptions& options); - - ~CroppingWindowCapturer() override; - - // DesktopCapturer implementation. - void Start(DesktopCapturer::Callback* callback) override; - void SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) override; - void CaptureFrame() override; - void SetExcludedWindow(WindowId window) override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - bool FocusOnSelectedSource() override; - bool IsOccluded(const DesktopVector& pos) override; - - // DesktopCapturer::Callback implementation, passed to |screen_capturer_| to - // intercept the capture result. - void OnCaptureResult(DesktopCapturer::Result result, - std::unique_ptr frame) override; - - protected: - explicit CroppingWindowCapturer(const DesktopCaptureOptions& options); - - // The platform implementation should override these methods. - - // Returns true if it is OK to capture the whole screen and crop to the - // selected window, i.e. the selected window is opaque, rectangular, and not - // occluded. - virtual bool ShouldUseScreenCapturer() = 0; - - // Returns the window area relative to the top left of the virtual screen - // within the bounds of the virtual screen. This function should return the - // DesktopRect in full desktop coordinates, i.e. the top-left monitor starts - // from (0, 0). - virtual DesktopRect GetWindowRectInVirtualScreen() = 0; - - WindowId selected_window() const { return selected_window_; } - WindowId excluded_window() const { return excluded_window_; } - DesktopCapturer* window_capturer() const { return window_capturer_.get(); } - - private: - DesktopCaptureOptions options_; - DesktopCapturer::Callback* callback_; - std::unique_ptr window_capturer_; - std::unique_ptr screen_capturer_; - SourceId selected_window_; - WindowId excluded_window_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc deleted file mode 100644 index 6e53ca352..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2014 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/desktop_capture/cropping_window_capturer.h" -#include "modules/desktop_capture/desktop_capturer_differ_wrapper.h" -#include "modules/desktop_capture/win/screen_capture_utils.h" -#include "modules/desktop_capture/win/selected_window_context.h" -#include "modules/desktop_capture/win/window_capture_utils.h" -#include "rtc_base/logging.h" -#include "rtc_base/trace_event.h" -#include "rtc_base/win32.h" - -namespace webrtc { - -namespace { - -// Used to pass input data for verifying the selected window is on top. -struct TopWindowVerifierContext : public SelectedWindowContext { - TopWindowVerifierContext(HWND selected_window, - HWND excluded_window, - DesktopRect selected_window_rect, - WindowCaptureHelperWin* window_capture_helper) - : SelectedWindowContext(selected_window, - selected_window_rect, - window_capture_helper), - excluded_window(excluded_window) { - RTC_DCHECK_NE(selected_window, excluded_window); - } - - // Determines whether the selected window is on top (not occluded by any - // windows except for those it owns or any excluded window). - bool IsTopWindow() { - if (!IsSelectedWindowValid()) { - return false; - } - - // Enumerate all top-level windows above the selected window in Z-order, - // checking whether any overlaps it. This uses FindWindowEx rather than - // EnumWindows because the latter excludes certain system windows (e.g. the - // Start menu & other taskbar menus) that should be detected here to avoid - // inadvertent capture. - int num_retries = 0; - while (true) { - HWND hwnd = nullptr; - while ((hwnd = FindWindowEx(nullptr, hwnd, nullptr, nullptr))) { - if (hwnd == selected_window()) { - // Windows are enumerated in top-down Z-order, so we can stop - // enumerating upon reaching the selected window & report it's on top. - return true; - } - - // Ignore the excluded window. - if (hwnd == excluded_window) { - continue; - } - - // Ignore windows that aren't visible on the current desktop. - if (!window_capture_helper()->IsWindowVisibleOnCurrentDesktop(hwnd)) { - continue; - } - - // Ignore Chrome notification windows, especially the notification for - // the ongoing window sharing. Notes: - // - This only works with notifications from Chrome, not other Apps. - // - All notifications from Chrome will be ignored. - // - This may cause part or whole of notification window being cropped - // into the capturing of the target window if there is overlapping. - if (window_capture_helper()->IsWindowChromeNotification(hwnd)) { - continue; - } - - // Ignore windows owned by the selected window since we want to capture - // them. - if (IsWindowOwnedBySelectedWindow(hwnd)) { - continue; - } - - // Check whether this window intersects with the selected window. - if (IsWindowOverlappingSelectedWindow(hwnd)) { - // If intersection is not empty, the selected window is not on top. - return false; - } - } - - DWORD lastError = GetLastError(); - if (lastError == ERROR_SUCCESS) { - // The enumeration completed successfully without finding the selected - // window (which may have been closed). - RTC_LOG(LS_WARNING) << "Failed to find selected window (only expected " - "if it was closed)"; - RTC_DCHECK(!IsWindow(selected_window())); - return false; - } else if (lastError == ERROR_INVALID_WINDOW_HANDLE) { - // This error may occur if a window is closed around the time it's - // enumerated; retry the enumeration in this case up to 10 times - // (this should be a rare race & unlikely to recur). - if (++num_retries <= 10) { - RTC_LOG(LS_WARNING) << "Enumeration failed due to race with a window " - "closing; retrying - retry #" - << num_retries; - continue; - } else { - RTC_LOG(LS_ERROR) - << "Exhausted retry allowance around window enumeration failures " - "due to races with windows closing"; - } - } - - // The enumeration failed with an unexpected error (or more repeats of - // an infrequently-expected error than anticipated). After logging this & - // firing an assert when enabled, report that the selected window isn't - // topmost to avoid inadvertent capture of other windows. - RTC_LOG(LS_ERROR) << "Failed to enumerate windows: " << lastError; - RTC_DCHECK(false); - return false; - } - } - - const HWND excluded_window; -}; - -class CroppingWindowCapturerWin : public CroppingWindowCapturer { - public: - explicit CroppingWindowCapturerWin(const DesktopCaptureOptions& options) - : CroppingWindowCapturer(options), - full_screen_window_detector_(options.full_screen_window_detector()) {} - - void CaptureFrame() override; - - private: - bool ShouldUseScreenCapturer() override; - DesktopRect GetWindowRectInVirtualScreen() override; - - // Returns either selected by user sourceId or sourceId provided by - // FullScreenWindowDetector - WindowId GetWindowToCapture() const; - - // The region from GetWindowRgn in the desktop coordinate if the region is - // rectangular, or the rect from GetWindowRect if the region is not set. - DesktopRect window_region_rect_; - - WindowCaptureHelperWin window_capture_helper_; - - rtc::scoped_refptr full_screen_window_detector_; -}; - -void CroppingWindowCapturerWin::CaptureFrame() { - DesktopCapturer* win_capturer = window_capturer(); - if (win_capturer) { - // Update the list of available sources and override source to capture if - // FullScreenWindowDetector returns not zero - if (full_screen_window_detector_) { - full_screen_window_detector_->UpdateWindowListIfNeeded( - selected_window(), - [win_capturer](DesktopCapturer::SourceList* sources) { - return win_capturer->GetSourceList(sources); - }); - } - win_capturer->SelectSource(GetWindowToCapture()); - } - - CroppingWindowCapturer::CaptureFrame(); -} - -bool CroppingWindowCapturerWin::ShouldUseScreenCapturer() { - if (!rtc::IsWindows8OrLater() && window_capture_helper_.IsAeroEnabled()) { - return false; - } - - const HWND selected = reinterpret_cast(GetWindowToCapture()); - // Check if the window is visible on current desktop. - if (!window_capture_helper_.IsWindowVisibleOnCurrentDesktop(selected)) { - return false; - } - - // Check if the window is a translucent layered window. - const LONG window_ex_style = GetWindowLong(selected, GWL_EXSTYLE); - if (window_ex_style & WS_EX_LAYERED) { - COLORREF color_ref_key = 0; - BYTE alpha = 0; - DWORD flags = 0; - - // GetLayeredWindowAttributes fails if the window was setup with - // UpdateLayeredWindow. We have no way to know the opacity of the window in - // that case. This happens for Stiky Note (crbug/412726). - if (!GetLayeredWindowAttributes(selected, &color_ref_key, &alpha, &flags)) - return false; - - // UpdateLayeredWindow is the only way to set per-pixel alpha and will cause - // the previous GetLayeredWindowAttributes to fail. So we only need to check - // the window wide color key or alpha. - if ((flags & LWA_COLORKEY) || ((flags & LWA_ALPHA) && (alpha < 255))) { - return false; - } - } - - if (!GetWindowRect(selected, &window_region_rect_)) { - return false; - } - - DesktopRect content_rect; - if (!GetWindowContentRect(selected, &content_rect)) { - return false; - } - - DesktopRect region_rect; - // Get the window region and check if it is rectangular. - const int region_type = - GetWindowRegionTypeWithBoundary(selected, ®ion_rect); - - // Do not use the screen capturer if the region is empty or not rectangular. - if (region_type == COMPLEXREGION || region_type == NULLREGION) { - return false; - } - - if (region_type == SIMPLEREGION) { - // The |region_rect| returned from GetRgnBox() is always in window - // coordinate. - region_rect.Translate(window_region_rect_.left(), - window_region_rect_.top()); - // MSDN: The window region determines the area *within* the window where the - // system permits drawing. - // https://msdn.microsoft.com/en-us/library/windows/desktop/dd144950(v=vs.85).aspx. - // - // |region_rect| should always be inside of |window_region_rect_|. So after - // the intersection, |window_region_rect_| == |region_rect|. If so, what's - // the point of the intersecting operations? Why cannot we directly retrieve - // |window_region_rect_| from GetWindowRegionTypeWithBoundary() function? - // TODO(zijiehe): Figure out the purpose of these intersections. - window_region_rect_.IntersectWith(region_rect); - content_rect.IntersectWith(region_rect); - } - - // Check if the client area is out of the screen area. When the window is - // maximized, only its client area is visible in the screen, the border will - // be hidden. So we are using |content_rect| here. - if (!GetFullscreenRect().ContainsRect(content_rect)) { - return false; - } - - // Check if the window is occluded by any other window, excluding the child - // windows, context menus, and |excluded_window_|. - // |content_rect| is preferred, see the comments on - // IsWindowIntersectWithSelectedWindow(). - TopWindowVerifierContext context(selected, - reinterpret_cast(excluded_window()), - content_rect, &window_capture_helper_); - return context.IsTopWindow(); -} - -DesktopRect CroppingWindowCapturerWin::GetWindowRectInVirtualScreen() { - TRACE_EVENT0("webrtc", - "CroppingWindowCapturerWin::GetWindowRectInVirtualScreen"); - DesktopRect window_rect; - HWND hwnd = reinterpret_cast(GetWindowToCapture()); - if (!GetCroppedWindowRect(hwnd, /*avoid_cropping_border*/ false, &window_rect, - /*original_rect*/ nullptr)) { - RTC_LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); - return window_rect; - } - window_rect.IntersectWith(window_region_rect_); - - // Convert |window_rect| to be relative to the top-left of the virtual screen. - DesktopRect screen_rect(GetFullscreenRect()); - window_rect.IntersectWith(screen_rect); - window_rect.Translate(-screen_rect.left(), -screen_rect.top()); - return window_rect; -} - -WindowId CroppingWindowCapturerWin::GetWindowToCapture() const { - const auto selected_source = selected_window(); - const auto full_screen_source = - full_screen_window_detector_ - ? full_screen_window_detector_->FindFullScreenWindow(selected_source) - : 0; - return full_screen_source ? full_screen_source : selected_source; -} - -} // namespace - -// static -std::unique_ptr CroppingWindowCapturer::CreateCapturer( - const DesktopCaptureOptions& options) { - std::unique_ptr capturer( - new CroppingWindowCapturerWin(options)); - if (capturer && options.detect_updated_region()) { - capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); - } - - return capturer; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc deleted file mode 100644 index f282c1d50..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/desktop_and_cursor_composer.h" - -#include -#include - -#include -#include - -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/mouse_cursor.h" -#include "modules/desktop_capture/mouse_cursor_monitor.h" -#include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -namespace { - -// Helper function that blends one image into another. Source image must be -// pre-multiplied with the alpha channel. Destination is assumed to be opaque. -void AlphaBlend(uint8_t* dest, - int dest_stride, - const uint8_t* src, - int src_stride, - const DesktopSize& size) { - for (int y = 0; y < size.height(); ++y) { - for (int x = 0; x < size.width(); ++x) { - uint32_t base_alpha = 255 - src[x * DesktopFrame::kBytesPerPixel + 3]; - if (base_alpha == 255) { - continue; - } else if (base_alpha == 0) { - memcpy(dest + x * DesktopFrame::kBytesPerPixel, - src + x * DesktopFrame::kBytesPerPixel, - DesktopFrame::kBytesPerPixel); - } else { - dest[x * DesktopFrame::kBytesPerPixel] = - dest[x * DesktopFrame::kBytesPerPixel] * base_alpha / 255 + - src[x * DesktopFrame::kBytesPerPixel]; - dest[x * DesktopFrame::kBytesPerPixel + 1] = - dest[x * DesktopFrame::kBytesPerPixel + 1] * base_alpha / 255 + - src[x * DesktopFrame::kBytesPerPixel + 1]; - dest[x * DesktopFrame::kBytesPerPixel + 2] = - dest[x * DesktopFrame::kBytesPerPixel + 2] * base_alpha / 255 + - src[x * DesktopFrame::kBytesPerPixel + 2]; - } - } - src += src_stride; - dest += dest_stride; - } -} - -// DesktopFrame wrapper that draws mouse on a frame and restores original -// content before releasing the underlying frame. -class DesktopFrameWithCursor : public DesktopFrame { - public: - // Takes ownership of |frame|. - DesktopFrameWithCursor(std::unique_ptr frame, - const MouseCursor& cursor, - const DesktopVector& position, - const DesktopRect& previous_cursor_rect, - bool cursor_changed); - ~DesktopFrameWithCursor() override; - - DesktopRect cursor_rect() const { return cursor_rect_; } - - private: - const std::unique_ptr original_frame_; - - DesktopVector restore_position_; - std::unique_ptr restore_frame_; - DesktopRect cursor_rect_; - - RTC_DISALLOW_COPY_AND_ASSIGN(DesktopFrameWithCursor); -}; - -DesktopFrameWithCursor::DesktopFrameWithCursor( - std::unique_ptr frame, - const MouseCursor& cursor, - const DesktopVector& position, - const DesktopRect& previous_cursor_rect, - bool cursor_changed) - : DesktopFrame(frame->size(), - frame->stride(), - frame->data(), - frame->shared_memory()), - original_frame_(std::move(frame)) { - MoveFrameInfoFrom(original_frame_.get()); - - DesktopVector image_pos = position.subtract(cursor.hotspot()); - cursor_rect_ = DesktopRect::MakeSize(cursor.image()->size()); - cursor_rect_.Translate(image_pos); - DesktopVector cursor_origin = cursor_rect_.top_left(); - cursor_rect_.IntersectWith(DesktopRect::MakeSize(size())); - - if (!previous_cursor_rect.equals(cursor_rect_)) { - mutable_updated_region()->AddRect(cursor_rect_); - mutable_updated_region()->AddRect(previous_cursor_rect); - } else if (cursor_changed) { - mutable_updated_region()->AddRect(cursor_rect_); - } - - if (cursor_rect_.is_empty()) - return; - - // Copy original screen content under cursor to |restore_frame_|. - restore_position_ = cursor_rect_.top_left(); - restore_frame_.reset(new BasicDesktopFrame(cursor_rect_.size())); - restore_frame_->CopyPixelsFrom(*this, cursor_rect_.top_left(), - DesktopRect::MakeSize(restore_frame_->size())); - - // Blit the cursor. - uint8_t* cursor_rect_data = - reinterpret_cast(data()) + cursor_rect_.top() * stride() + - cursor_rect_.left() * DesktopFrame::kBytesPerPixel; - DesktopVector origin_shift = cursor_rect_.top_left().subtract(cursor_origin); - AlphaBlend(cursor_rect_data, stride(), - cursor.image()->data() + - origin_shift.y() * cursor.image()->stride() + - origin_shift.x() * DesktopFrame::kBytesPerPixel, - cursor.image()->stride(), cursor_rect_.size()); -} - -DesktopFrameWithCursor::~DesktopFrameWithCursor() { - // Restore original content of the frame. - if (restore_frame_) { - DesktopRect target_rect = DesktopRect::MakeSize(restore_frame_->size()); - target_rect.Translate(restore_position_); - CopyPixelsFrom(restore_frame_->data(), restore_frame_->stride(), - target_rect); - } -} - -} // namespace - -DesktopAndCursorComposer::DesktopAndCursorComposer( - std::unique_ptr desktop_capturer, - const DesktopCaptureOptions& options) - : DesktopAndCursorComposer(desktop_capturer.release(), - MouseCursorMonitor::Create(options).release()) {} - -DesktopAndCursorComposer::DesktopAndCursorComposer( - DesktopCapturer* desktop_capturer, - MouseCursorMonitor* mouse_monitor) - : desktop_capturer_(desktop_capturer), mouse_monitor_(mouse_monitor) { - RTC_DCHECK(desktop_capturer_); -} - -DesktopAndCursorComposer::~DesktopAndCursorComposer() = default; - -std::unique_ptr -DesktopAndCursorComposer::CreateWithoutMouseCursorMonitor( - std::unique_ptr desktop_capturer) { - return std::unique_ptr( - new DesktopAndCursorComposer(desktop_capturer.release(), nullptr)); -} - -void DesktopAndCursorComposer::Start(DesktopCapturer::Callback* callback) { - callback_ = callback; - if (mouse_monitor_) - mouse_monitor_->Init(this, MouseCursorMonitor::SHAPE_AND_POSITION); - desktop_capturer_->Start(this); -} - -void DesktopAndCursorComposer::SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) { - desktop_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); -} - -void DesktopAndCursorComposer::CaptureFrame() { - if (mouse_monitor_) - mouse_monitor_->Capture(); - desktop_capturer_->CaptureFrame(); -} - -void DesktopAndCursorComposer::SetExcludedWindow(WindowId window) { - desktop_capturer_->SetExcludedWindow(window); -} - -bool DesktopAndCursorComposer::GetSourceList(SourceList* sources) { - return desktop_capturer_->GetSourceList(sources); -} - -bool DesktopAndCursorComposer::SelectSource(SourceId id) { - return desktop_capturer_->SelectSource(id); -} - -bool DesktopAndCursorComposer::FocusOnSelectedSource() { - return desktop_capturer_->FocusOnSelectedSource(); -} - -bool DesktopAndCursorComposer::IsOccluded(const DesktopVector& pos) { - return desktop_capturer_->IsOccluded(pos); -} - -void DesktopAndCursorComposer::OnCaptureResult( - DesktopCapturer::Result result, - std::unique_ptr frame) { - if (frame && cursor_) { - if (frame->rect().Contains(cursor_position_) && - !desktop_capturer_->IsOccluded(cursor_position_)) { - DesktopVector relative_position = - cursor_position_.subtract(frame->top_left()); -#if defined(WEBRTC_MAC) - // On OSX, the logical(DIP) and physical coordinates are used mixingly. - // For example, the captured cursor has its size in physical pixels(2x) - // and location in logical(DIP) pixels on Retina monitor. This will cause - // problem when the desktop is mixed with Retina and non-Retina monitors. - // So we use DIP pixel for all location info and compensate with the scale - // factor of current frame to the |relative_position|. - const float scale = frame->scale_factor(); - relative_position.set(relative_position.x() * scale, - relative_position.y() * scale); -#endif - auto frame_with_cursor = std::make_unique( - std::move(frame), *cursor_, relative_position, previous_cursor_rect_, - cursor_changed_); - previous_cursor_rect_ = frame_with_cursor->cursor_rect(); - cursor_changed_ = false; - frame = std::move(frame_with_cursor); - } - } - - callback_->OnCaptureResult(result, std::move(frame)); -} - -void DesktopAndCursorComposer::OnMouseCursor(MouseCursor* cursor) { - cursor_changed_ = true; - cursor_.reset(cursor); -} - -void DesktopAndCursorComposer::OnMouseCursorPosition( - const DesktopVector& position) { - cursor_position_ = position; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h deleted file mode 100644 index 8f95721ec..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_AND_CURSOR_COMPOSER_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_AND_CURSOR_COMPOSER_H_ - -#include - -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/mouse_cursor.h" -#include "modules/desktop_capture/mouse_cursor_monitor.h" -#include "modules/desktop_capture/shared_memory.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// A wrapper for DesktopCapturer that also captures mouse using specified -// MouseCursorMonitor and renders it on the generated streams. -class RTC_EXPORT DesktopAndCursorComposer - : public DesktopCapturer, - public DesktopCapturer::Callback, - public MouseCursorMonitor::Callback { - public: - // Creates a new composer that captures mouse cursor using - // MouseCursorMonitor::Create(options) and renders it into the frames - // generated by |desktop_capturer|. - DesktopAndCursorComposer(std::unique_ptr desktop_capturer, - const DesktopCaptureOptions& options); - - ~DesktopAndCursorComposer() override; - - // Creates a new composer that relies on an external source for cursor shape - // and position information via the MouseCursorMonitor::Callback interface. - static std::unique_ptr - CreateWithoutMouseCursorMonitor( - std::unique_ptr desktop_capturer); - - // DesktopCapturer interface. - void Start(DesktopCapturer::Callback* callback) override; - void SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) override; - void CaptureFrame() override; - void SetExcludedWindow(WindowId window) override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - bool FocusOnSelectedSource() override; - bool IsOccluded(const DesktopVector& pos) override; - - // MouseCursorMonitor::Callback interface. - void OnMouseCursor(MouseCursor* cursor) override; - void OnMouseCursorPosition(const DesktopVector& position) override; - - private: - // Allows test cases to use a fake MouseCursorMonitor implementation. - friend class DesktopAndCursorComposerTest; - - // Constructor to delegate both deprecated and new constructors and allows - // test cases to use a fake MouseCursorMonitor implementation. - DesktopAndCursorComposer(DesktopCapturer* desktop_capturer, - MouseCursorMonitor* mouse_monitor); - - // DesktopCapturer::Callback interface. - void OnCaptureResult(DesktopCapturer::Result result, - std::unique_ptr frame) override; - - const std::unique_ptr desktop_capturer_; - const std::unique_ptr mouse_monitor_; - - DesktopCapturer::Callback* callback_; - - std::unique_ptr cursor_; - DesktopVector cursor_position_; - DesktopRect previous_cursor_rect_; - bool cursor_changed_ = false; - - RTC_DISALLOW_COPY_AND_ASSIGN(DesktopAndCursorComposer); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_AND_CURSOR_COMPOSER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_options.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_options.cc deleted file mode 100644 index c89896d5f..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_options.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/desktop_capture_options.h" -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include "modules/desktop_capture/mac/full_screen_mac_application_handler.h" -#elif defined(WEBRTC_WIN) -#include "modules/desktop_capture/win/full_screen_win_application_handler.h" -#endif - -namespace webrtc { - -DesktopCaptureOptions::DesktopCaptureOptions() {} -DesktopCaptureOptions::DesktopCaptureOptions( - const DesktopCaptureOptions& options) = default; -DesktopCaptureOptions::DesktopCaptureOptions(DesktopCaptureOptions&& options) = - default; -DesktopCaptureOptions::~DesktopCaptureOptions() {} - -DesktopCaptureOptions& DesktopCaptureOptions::operator=( - const DesktopCaptureOptions& options) = default; -DesktopCaptureOptions& DesktopCaptureOptions::operator=( - DesktopCaptureOptions&& options) = default; - -// static -DesktopCaptureOptions DesktopCaptureOptions::CreateDefault() { - DesktopCaptureOptions result; -#if defined(WEBRTC_USE_X11) - result.set_x_display(SharedXDisplay::CreateDefault()); -#endif -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - result.set_configuration_monitor(new DesktopConfigurationMonitor()); - result.set_full_screen_window_detector( - new FullScreenWindowDetector(CreateFullScreenMacApplicationHandler)); -#elif defined(WEBRTC_WIN) - result.set_full_screen_window_detector( - new FullScreenWindowDetector(CreateFullScreenWinApplicationHandler)); -#endif - return result; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_options.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_options.h deleted file mode 100644 index 521c80b5c..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_options.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_ - -#include "api/scoped_refptr.h" -#include "rtc_base/system/rtc_export.h" - -#if defined(WEBRTC_USE_X11) -#include "modules/desktop_capture/linux/shared_x_display.h" -#endif - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include "modules/desktop_capture/mac/desktop_configuration_monitor.h" -#endif - -#include "modules/desktop_capture/full_screen_window_detector.h" - -namespace webrtc { - -// An object that stores initialization parameters for screen and window -// capturers. -class RTC_EXPORT DesktopCaptureOptions { - public: - // Returns instance of DesktopCaptureOptions with default parameters. On Linux - // also initializes X window connection. x_display() will be set to null if - // X11 connection failed (e.g. DISPLAY isn't set). - static DesktopCaptureOptions CreateDefault(); - - DesktopCaptureOptions(); - DesktopCaptureOptions(const DesktopCaptureOptions& options); - DesktopCaptureOptions(DesktopCaptureOptions&& options); - ~DesktopCaptureOptions(); - - DesktopCaptureOptions& operator=(const DesktopCaptureOptions& options); - DesktopCaptureOptions& operator=(DesktopCaptureOptions&& options); - -#if defined(WEBRTC_USE_X11) - SharedXDisplay* x_display() const { return x_display_; } - void set_x_display(rtc::scoped_refptr x_display) { - x_display_ = x_display; - } -#endif - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - // TODO(zijiehe): Remove both DesktopConfigurationMonitor and - // FullScreenChromeWindowDetector out of DesktopCaptureOptions. It's not - // reasonable for external consumers to set these two parameters. - DesktopConfigurationMonitor* configuration_monitor() const { - return configuration_monitor_; - } - // If nullptr is set, ScreenCapturer won't work and WindowCapturer may return - // inaccurate result from IsOccluded() function. - void set_configuration_monitor( - rtc::scoped_refptr m) { - configuration_monitor_ = m; - } - - bool allow_iosurface() const { return allow_iosurface_; } - void set_allow_iosurface(bool allow) { allow_iosurface_ = allow; } -#endif - - FullScreenWindowDetector* full_screen_window_detector() const { - return full_screen_window_detector_; - } - void set_full_screen_window_detector( - rtc::scoped_refptr detector) { - full_screen_window_detector_ = detector; - } - - // Flag indicating that the capturer should use screen change notifications. - // Enables/disables use of XDAMAGE in the X11 capturer. - bool use_update_notifications() const { return use_update_notifications_; } - void set_use_update_notifications(bool use_update_notifications) { - use_update_notifications_ = use_update_notifications; - } - - // Flag indicating if desktop effects (e.g. Aero) should be disabled when the - // capturer is active. Currently used only on Windows. - bool disable_effects() const { return disable_effects_; } - void set_disable_effects(bool disable_effects) { - disable_effects_ = disable_effects; - } - - // Flag that should be set if the consumer uses updated_region() and the - // capturer should try to provide correct updated_region() for the frames it - // generates (e.g. by comparing each frame with the previous one). - bool detect_updated_region() const { return detect_updated_region_; } - void set_detect_updated_region(bool detect_updated_region) { - detect_updated_region_ = detect_updated_region; - } - -#if defined(WEBRTC_WIN) - bool allow_use_magnification_api() const { - return allow_use_magnification_api_; - } - void set_allow_use_magnification_api(bool allow) { - allow_use_magnification_api_ = allow; - } - // Allowing directx based capturer or not, this capturer works on windows 7 - // with platform update / windows 8 or upper. - bool allow_directx_capturer() const { return allow_directx_capturer_; } - void set_allow_directx_capturer(bool enabled) { - allow_directx_capturer_ = enabled; - } - - // Flag that may be set to allow use of the cropping window capturer (which - // captures the screen & crops that to the window region in some cases). An - // advantage of using this is significantly higher capture frame rates than - // capturing the window directly. A disadvantage of using this is the - // possibility of capturing unrelated content (e.g. overlapping windows that - // aren't detected properly, or neighboring regions when moving/resizing the - // captured window). Note: this flag influences the behavior of calls to - // DesktopCapturer::CreateWindowCapturer; calls to - // CroppingWindowCapturer::CreateCapturer ignore the flag (treat it as true). - bool allow_cropping_window_capturer() const { - return allow_cropping_window_capturer_; - } - void set_allow_cropping_window_capturer(bool allow) { - allow_cropping_window_capturer_ = allow; - } -#endif - -#if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire() const { return allow_pipewire_; } - void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; } -#endif - - private: -#if defined(WEBRTC_USE_X11) - rtc::scoped_refptr x_display_; -#endif - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - rtc::scoped_refptr configuration_monitor_; - bool allow_iosurface_ = false; -#endif - - rtc::scoped_refptr full_screen_window_detector_; - -#if defined(WEBRTC_WIN) - bool allow_use_magnification_api_ = false; - bool allow_directx_capturer_ = false; - bool allow_cropping_window_capturer_ = false; -#endif -#if defined(WEBRTC_USE_X11) - bool use_update_notifications_ = false; -#else - bool use_update_notifications_ = true; -#endif - bool disable_effects_ = true; - bool detect_updated_region_ = false; -#if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire_ = false; -#endif -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_types.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_types.h deleted file mode 100644 index 5031cbf3a..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capture_types.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_TYPES_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_TYPES_H_ - -#include - -namespace webrtc { - -// Type used to identify windows on the desktop. Values are platform-specific: -// - On Windows: HWND cast to intptr_t. -// - On Linux (with X11): X11 Window (unsigned long) type cast to intptr_t. -// - On OSX: integer window number. -typedef intptr_t WindowId; - -const WindowId kNullWindowId = 0; - -// Type used to identify screens on the desktop. Values are platform-specific: -// - On Windows: integer display device index. -// - On OSX: CGDirectDisplayID cast to intptr_t. -// - On Linux (with X11): TBD. -// On Windows, ScreenId is implementation dependent: sending a ScreenId from one -// implementation to another usually won't work correctly. -typedef intptr_t ScreenId; - -// The screen id corresponds to all screen combined together. -const ScreenId kFullDesktopScreenId = -1; - -const ScreenId kInvalidScreenId = -2; - -// An integer to attach to each DesktopFrame to differentiate the generator of -// the frame. -namespace DesktopCapturerId { -constexpr uint32_t CreateFourCC(char a, char b, char c, char d) { - return ((static_cast(a)) | (static_cast(b) << 8) | - (static_cast(c) << 16) | (static_cast(d) << 24)); -} - -constexpr uint32_t kUnknown = 0; -constexpr uint32_t kScreenCapturerWinGdi = CreateFourCC('G', 'D', 'I', ' '); -constexpr uint32_t kScreenCapturerWinDirectx = CreateFourCC('D', 'X', 'G', 'I'); -} // namespace DesktopCapturerId - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_TYPES_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer.cc deleted file mode 100644 index 61926a602..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016 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/desktop_capture/desktop_capturer.h" - -#include -#include - -#include -#include - -#include "modules/desktop_capture/cropping_window_capturer.h" -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer_differ_wrapper.h" - -namespace webrtc { - -DesktopCapturer::~DesktopCapturer() = default; - -void DesktopCapturer::SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) {} - -void DesktopCapturer::SetExcludedWindow(WindowId window) {} - -bool DesktopCapturer::GetSourceList(SourceList* sources) { - return true; -} - -bool DesktopCapturer::SelectSource(SourceId id) { - return false; -} - -bool DesktopCapturer::FocusOnSelectedSource() { - return false; -} - -bool DesktopCapturer::IsOccluded(const DesktopVector& pos) { - return false; -} - -// static -std::unique_ptr DesktopCapturer::CreateWindowCapturer( - const DesktopCaptureOptions& options) { -#if defined(WEBRTC_WIN) - if (options.allow_cropping_window_capturer()) { - return CroppingWindowCapturer::CreateCapturer(options); - } -#endif // defined(WEBRTC_WIN) - - std::unique_ptr capturer = CreateRawWindowCapturer(options); - if (capturer && options.detect_updated_region()) { - capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); - } - - return capturer; -} - -// static -std::unique_ptr DesktopCapturer::CreateScreenCapturer( - const DesktopCaptureOptions& options) { - std::unique_ptr capturer = CreateRawScreenCapturer(options); - if (capturer && options.detect_updated_region()) { - capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); - } - - return capturer; -} - -#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) -bool DesktopCapturer::IsRunningUnderWayland() { - const char* xdg_session_type = getenv("XDG_SESSION_TYPE"); - if (!xdg_session_type || strncmp(xdg_session_type, "wayland", 7) != 0) - return false; - - if (!(getenv("WAYLAND_DISPLAY"))) - return false; - - return true; -} -#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer.h deleted file mode 100644 index 64339c0ca..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ - -#include -#include - -#include -#include -#include -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/shared_memory.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -class DesktopCaptureOptions; -class DesktopFrame; - -// Abstract interface for screen and window capturers. -class RTC_EXPORT DesktopCapturer { - public: - enum class Result { - // The frame was captured successfully. - SUCCESS, - - // There was a temporary error. The caller should continue calling - // CaptureFrame(), in the expectation that it will eventually recover. - ERROR_TEMPORARY, - - // Capture has failed and will keep failing if the caller tries calling - // CaptureFrame() again. - ERROR_PERMANENT, - - MAX_VALUE = ERROR_PERMANENT - }; - - // Interface that must be implemented by the DesktopCapturer consumers. - class Callback { - public: - // Called after a frame has been captured. |frame| is not nullptr if and - // only if |result| is SUCCESS. - virtual void OnCaptureResult(Result result, - std::unique_ptr frame) = 0; - - protected: - virtual ~Callback() {} - }; - - typedef intptr_t SourceId; - - static_assert(std::is_same::value, - "SourceId should be a same type as ScreenId."); - - struct Source { - // The unique id to represent a Source of current DesktopCapturer. - SourceId id; - - // Title of the window or screen in UTF-8 encoding, maybe empty. This field - // should not be used to identify a source. - std::string title; - }; - - typedef std::vector SourceList; - - virtual ~DesktopCapturer(); - - // Called at the beginning of a capturing session. |callback| must remain - // valid until capturer is destroyed. - virtual void Start(Callback* callback) = 0; - - // Sets SharedMemoryFactory that will be used to create buffers for the - // captured frames. The factory can be invoked on a thread other than the one - // where CaptureFrame() is called. It will be destroyed on the same thread. - // Shared memory is currently supported only by some DesktopCapturer - // implementations. - virtual void SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory); - - // Captures next frame, and involve callback provided by Start() function. - // Pending capture requests are canceled when DesktopCapturer is deleted. - virtual void CaptureFrame() = 0; - - // Sets the window to be excluded from the captured image in the future - // Capture calls. Used to exclude the screenshare notification window for - // screen capturing. - virtual void SetExcludedWindow(WindowId window); - - // TODO(zijiehe): Following functions should be pure virtual. The default - // implementations are for backward compatibility only. Remove default - // implementations once all DesktopCapturer implementations in Chromium have - // implemented these functions. - - // Gets a list of sources current capturer supports. Returns false in case of - // a failure. - // For DesktopCapturer implementations to capture screens, this function - // should return monitors. - // For DesktopCapturer implementations to capture windows, this function - // should only return root windows owned by applications. - virtual bool GetSourceList(SourceList* sources); - - // Selects a source to be captured. Returns false in case of a failure (e.g. - // if there is no source with the specified type and id.) - virtual bool SelectSource(SourceId id); - - // Brings the selected source to the front and sets the input focus on it. - // Returns false in case of a failure or no source has been selected or the - // implementation does not support this functionality. - virtual bool FocusOnSelectedSource(); - - // Returns true if the |pos| on the selected source is covered by other - // elements on the display, and is not visible to the users. - // |pos| is in full desktop coordinates, i.e. the top-left monitor always - // starts from (0, 0). - // The return value if |pos| is out of the scope of the source is undefined. - virtual bool IsOccluded(const DesktopVector& pos); - - // Creates a DesktopCapturer instance which targets to capture windows. - static std::unique_ptr CreateWindowCapturer( - const DesktopCaptureOptions& options); - - // Creates a DesktopCapturer instance which targets to capture screens. - static std::unique_ptr CreateScreenCapturer( - const DesktopCaptureOptions& options); - -#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - static bool IsRunningUnderWayland(); -#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - - protected: - // CroppingWindowCapturer needs to create raw capturers without wrappers, so - // the following two functions are protected. - - // Creates a platform specific DesktopCapturer instance which targets to - // capture windows. - static std::unique_ptr CreateRawWindowCapturer( - const DesktopCaptureOptions& options); - - // Creates a platform specific DesktopCapturer instance which targets to - // capture screens. - static std::unique_ptr CreateRawScreenCapturer( - const DesktopCaptureOptions& options); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc deleted file mode 100644 index 4e80f3052..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2016 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/desktop_capture/desktop_capturer_differ_wrapper.h" - -#include -#include - -#include - -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/desktop_region.h" -#include "modules/desktop_capture/differ_block.h" -#include "rtc_base/checks.h" -#include "rtc_base/time_utils.h" - -namespace webrtc { - -namespace { - -// Returns true if (0, 0) - (|width|, |height|) vector in |old_buffer| and -// |new_buffer| are equal. |width| should be less than 32 -// (defined by kBlockSize), otherwise BlockDifference() should be used. -bool PartialBlockDifference(const uint8_t* old_buffer, - const uint8_t* new_buffer, - int width, - int height, - int stride) { - RTC_DCHECK_LT(width, kBlockSize); - const int width_bytes = width * DesktopFrame::kBytesPerPixel; - for (int i = 0; i < height; i++) { - if (memcmp(old_buffer, new_buffer, width_bytes) != 0) { - return true; - } - old_buffer += stride; - new_buffer += stride; - } - return false; -} - -// Compares columns in the range of [|left|, |right|), in a row in the -// range of [|top|, |top| + |height|), starts from |old_buffer| and -// |new_buffer|, and outputs updated regions into |output|. |stride| is the -// DesktopFrame::stride(). -void CompareRow(const uint8_t* old_buffer, - const uint8_t* new_buffer, - const int left, - const int right, - const int top, - const int bottom, - const int stride, - DesktopRegion* const output) { - const int block_x_offset = kBlockSize * DesktopFrame::kBytesPerPixel; - const int width = right - left; - const int height = bottom - top; - const int block_count = (width - 1) / kBlockSize; - const int last_block_width = width - block_count * kBlockSize; - RTC_DCHECK_GT(last_block_width, 0); - RTC_DCHECK_LE(last_block_width, kBlockSize); - - // The first block-column in a continuous dirty area in current block-row. - int first_dirty_x_block = -1; - - // We always need to add dirty area into |output| in the last block, so handle - // it separatedly. - for (int x = 0; x < block_count; x++) { - if (BlockDifference(old_buffer, new_buffer, height, stride)) { - if (first_dirty_x_block == -1) { - // This is the first dirty block in a continuous dirty area. - first_dirty_x_block = x; - } - } else if (first_dirty_x_block != -1) { - // The block on the left is the last dirty block in a continuous - // dirty area. - output->AddRect( - DesktopRect::MakeLTRB(first_dirty_x_block * kBlockSize + left, top, - x * kBlockSize + left, bottom)); - first_dirty_x_block = -1; - } - old_buffer += block_x_offset; - new_buffer += block_x_offset; - } - - bool last_block_diff; - if (last_block_width < kBlockSize) { - // The last one is a partial vector. - last_block_diff = PartialBlockDifference(old_buffer, new_buffer, - last_block_width, height, stride); - } else { - last_block_diff = BlockDifference(old_buffer, new_buffer, height, stride); - } - if (last_block_diff) { - if (first_dirty_x_block == -1) { - first_dirty_x_block = block_count; - } - output->AddRect(DesktopRect::MakeLTRB( - first_dirty_x_block * kBlockSize + left, top, right, bottom)); - } else if (first_dirty_x_block != -1) { - output->AddRect( - DesktopRect::MakeLTRB(first_dirty_x_block * kBlockSize + left, top, - block_count * kBlockSize + left, bottom)); - } -} - -// Compares |rect| area in |old_frame| and |new_frame|, and outputs dirty -// regions into |output|. -void CompareFrames(const DesktopFrame& old_frame, - const DesktopFrame& new_frame, - DesktopRect rect, - DesktopRegion* const output) { - RTC_DCHECK(old_frame.size().equals(new_frame.size())); - RTC_DCHECK_EQ(old_frame.stride(), new_frame.stride()); - rect.IntersectWith(DesktopRect::MakeSize(old_frame.size())); - - const int y_block_count = (rect.height() - 1) / kBlockSize; - const int last_y_block_height = rect.height() - y_block_count * kBlockSize; - // Offset from the start of one block-row to the next. - const int block_y_stride = old_frame.stride() * kBlockSize; - const uint8_t* prev_block_row_start = - old_frame.GetFrameDataAtPos(rect.top_left()); - const uint8_t* curr_block_row_start = - new_frame.GetFrameDataAtPos(rect.top_left()); - - int top = rect.top(); - // The last row may have a different height, so we handle it separately. - for (int y = 0; y < y_block_count; y++) { - CompareRow(prev_block_row_start, curr_block_row_start, rect.left(), - rect.right(), top, top + kBlockSize, old_frame.stride(), output); - top += kBlockSize; - prev_block_row_start += block_y_stride; - curr_block_row_start += block_y_stride; - } - CompareRow(prev_block_row_start, curr_block_row_start, rect.left(), - rect.right(), top, top + last_y_block_height, old_frame.stride(), - output); -} - -} // namespace - -DesktopCapturerDifferWrapper::DesktopCapturerDifferWrapper( - std::unique_ptr base_capturer) - : base_capturer_(std::move(base_capturer)) { - RTC_DCHECK(base_capturer_); -} - -DesktopCapturerDifferWrapper::~DesktopCapturerDifferWrapper() {} - -void DesktopCapturerDifferWrapper::Start(DesktopCapturer::Callback* callback) { - callback_ = callback; - base_capturer_->Start(this); -} - -void DesktopCapturerDifferWrapper::SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) { - base_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); -} - -void DesktopCapturerDifferWrapper::CaptureFrame() { - base_capturer_->CaptureFrame(); -} - -void DesktopCapturerDifferWrapper::SetExcludedWindow(WindowId window) { - base_capturer_->SetExcludedWindow(window); -} - -bool DesktopCapturerDifferWrapper::GetSourceList(SourceList* sources) { - return base_capturer_->GetSourceList(sources); -} - -bool DesktopCapturerDifferWrapper::SelectSource(SourceId id) { - return base_capturer_->SelectSource(id); -} - -bool DesktopCapturerDifferWrapper::FocusOnSelectedSource() { - return base_capturer_->FocusOnSelectedSource(); -} - -bool DesktopCapturerDifferWrapper::IsOccluded(const DesktopVector& pos) { - return base_capturer_->IsOccluded(pos); -} - -void DesktopCapturerDifferWrapper::OnCaptureResult( - Result result, - std::unique_ptr input_frame) { - int64_t start_time_nanos = rtc::TimeNanos(); - if (!input_frame) { - callback_->OnCaptureResult(result, nullptr); - return; - } - RTC_DCHECK(result == Result::SUCCESS); - - std::unique_ptr frame = - SharedDesktopFrame::Wrap(std::move(input_frame)); - if (last_frame_ && (last_frame_->size().width() != frame->size().width() || - last_frame_->size().height() != frame->size().height() || - last_frame_->stride() != frame->stride())) { - last_frame_.reset(); - } - - if (last_frame_) { - DesktopRegion hints; - hints.Swap(frame->mutable_updated_region()); - for (DesktopRegion::Iterator it(hints); !it.IsAtEnd(); it.Advance()) { - CompareFrames(*last_frame_, *frame, it.rect(), - frame->mutable_updated_region()); - } - } else { - frame->mutable_updated_region()->SetRect( - DesktopRect::MakeSize(frame->size())); - } - last_frame_ = frame->Share(); - - frame->set_capture_time_ms(frame->capture_time_ms() + - (rtc::TimeNanos() - start_time_nanos) / - rtc::kNumNanosecsPerMillisec); - callback_->OnCaptureResult(result, std::move(frame)); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.h deleted file mode 100644 index 1f70cef18..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_DIFFER_WRAPPER_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_DIFFER_WRAPPER_H_ - -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/shared_desktop_frame.h" -#include "modules/desktop_capture/shared_memory.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// DesktopCapturer wrapper that calculates updated_region() by comparing frames -// content. This class always expects the underlying DesktopCapturer -// implementation returns a superset of updated regions in DestkopFrame. If a -// DesktopCapturer implementation does not know the updated region, it should -// set updated_region() to full frame. -// -// This class marks entire frame as updated if the frame size or frame stride -// has been changed. -class RTC_EXPORT DesktopCapturerDifferWrapper - : public DesktopCapturer, - public DesktopCapturer::Callback { - public: - // Creates a DesktopCapturerDifferWrapper with a DesktopCapturer - // implementation, and takes its ownership. - explicit DesktopCapturerDifferWrapper( - std::unique_ptr base_capturer); - - ~DesktopCapturerDifferWrapper() override; - - // DesktopCapturer interface. - void Start(DesktopCapturer::Callback* callback) override; - void SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) override; - void CaptureFrame() override; - void SetExcludedWindow(WindowId window) override; - bool GetSourceList(SourceList* screens) override; - bool SelectSource(SourceId id) override; - bool FocusOnSelectedSource() override; - bool IsOccluded(const DesktopVector& pos) override; - - private: - // DesktopCapturer::Callback interface. - void OnCaptureResult(Result result, - std::unique_ptr frame) override; - - const std::unique_ptr base_capturer_; - DesktopCapturer::Callback* callback_; - std::unique_ptr last_frame_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_DIFFER_WRAPPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_wrapper.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_wrapper.cc deleted file mode 100644 index 4bbdd6c94..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_wrapper.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/desktop_capturer_wrapper.h" - -#include - -#include "rtc_base/checks.h" - -namespace webrtc { - -DesktopCapturerWrapper::DesktopCapturerWrapper( - std::unique_ptr base_capturer) - : base_capturer_(std::move(base_capturer)) { - RTC_DCHECK(base_capturer_); -} - -DesktopCapturerWrapper::~DesktopCapturerWrapper() = default; - -void DesktopCapturerWrapper::Start(Callback* callback) { - base_capturer_->Start(callback); -} - -void DesktopCapturerWrapper::SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) { - base_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); -} - -void DesktopCapturerWrapper::CaptureFrame() { - base_capturer_->CaptureFrame(); -} - -void DesktopCapturerWrapper::SetExcludedWindow(WindowId window) { - base_capturer_->SetExcludedWindow(window); -} - -bool DesktopCapturerWrapper::GetSourceList(SourceList* sources) { - return base_capturer_->GetSourceList(sources); -} - -bool DesktopCapturerWrapper::SelectSource(SourceId id) { - return base_capturer_->SelectSource(id); -} - -bool DesktopCapturerWrapper::FocusOnSelectedSource() { - return base_capturer_->FocusOnSelectedSource(); -} - -bool DesktopCapturerWrapper::IsOccluded(const DesktopVector& pos) { - return base_capturer_->IsOccluded(pos); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_wrapper.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_wrapper.h deleted file mode 100644 index e0f50d79e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_capturer_wrapper.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_WRAPPER_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_WRAPPER_H_ - -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/shared_memory.h" - -namespace webrtc { - -// Wraps a DesktopCapturer and forwards all the function calls to it. -class DesktopCapturerWrapper : public DesktopCapturer { - public: - explicit DesktopCapturerWrapper( - std::unique_ptr base_capturer); - ~DesktopCapturerWrapper() override; - - // DesktopCapturer implementations. - void Start(Callback* callback) override; - void SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) override; - void CaptureFrame() override; - void SetExcludedWindow(WindowId window) override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - bool FocusOnSelectedSource() override; - bool IsOccluded(const DesktopVector& pos) override; - - protected: - // Guaranteed to be valid. - const std::unique_ptr base_capturer_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_WRAPPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame.cc deleted file mode 100644 index fd10dd5d2..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame.cc +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/desktop_frame.h" - -#include - -#include -#include -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "rtc_base/checks.h" - -namespace webrtc { - -DesktopFrame::DesktopFrame(DesktopSize size, - int stride, - uint8_t* data, - SharedMemory* shared_memory) - : data_(data), - shared_memory_(shared_memory), - size_(size), - stride_(stride), - capture_time_ms_(0), - capturer_id_(DesktopCapturerId::kUnknown) { - RTC_DCHECK(size_.width() >= 0); - RTC_DCHECK(size_.height() >= 0); -} - -DesktopFrame::~DesktopFrame() = default; - -void DesktopFrame::CopyPixelsFrom(const uint8_t* src_buffer, - int src_stride, - const DesktopRect& dest_rect) { - RTC_CHECK(DesktopRect::MakeSize(size()).ContainsRect(dest_rect)); - - uint8_t* dest = GetFrameDataAtPos(dest_rect.top_left()); - for (int y = 0; y < dest_rect.height(); ++y) { - memcpy(dest, src_buffer, DesktopFrame::kBytesPerPixel * dest_rect.width()); - src_buffer += src_stride; - dest += stride(); - } -} - -void DesktopFrame::CopyPixelsFrom(const DesktopFrame& src_frame, - const DesktopVector& src_pos, - const DesktopRect& dest_rect) { - RTC_CHECK(DesktopRect::MakeSize(src_frame.size()) - .ContainsRect( - DesktopRect::MakeOriginSize(src_pos, dest_rect.size()))); - - CopyPixelsFrom(src_frame.GetFrameDataAtPos(src_pos), src_frame.stride(), - dest_rect); -} - -bool DesktopFrame::CopyIntersectingPixelsFrom(const DesktopFrame& src_frame, - double horizontal_scale, - double vertical_scale) { - const DesktopVector& origin = top_left(); - const DesktopVector& src_frame_origin = src_frame.top_left(); - - DesktopVector src_frame_offset = src_frame_origin.subtract(origin); - - // Determine the intersection, first adjusting its origin to account for any - // DPI scaling. - DesktopRect intersection_rect = src_frame.rect(); - if (horizontal_scale != 1.0 || vertical_scale != 1.0) { - DesktopVector origin_adjustment( - static_cast( - std::round((horizontal_scale - 1.0) * src_frame_offset.x())), - static_cast( - std::round((vertical_scale - 1.0) * src_frame_offset.y()))); - - intersection_rect.Translate(origin_adjustment); - - src_frame_offset = src_frame_offset.add(origin_adjustment); - } - - intersection_rect.IntersectWith(rect()); - if (intersection_rect.is_empty()) { - return false; - } - - // Translate the intersection rect to be relative to the outer rect. - intersection_rect.Translate(-origin.x(), -origin.y()); - - // Determine source position for the copy (offsets of outer frame from - // source origin, if positive). - int32_t src_pos_x = std::max(0, -src_frame_offset.x()); - int32_t src_pos_y = std::max(0, -src_frame_offset.y()); - - CopyPixelsFrom(src_frame, DesktopVector(src_pos_x, src_pos_y), - intersection_rect); - return true; -} - -DesktopRect DesktopFrame::rect() const { - const float scale = scale_factor(); - // Only scale the size. - return DesktopRect::MakeXYWH(top_left().x(), top_left().y(), - size().width() / scale, size().height() / scale); -} - -float DesktopFrame::scale_factor() const { - float scale = 1.0f; - -#if defined(WEBRTC_MAC) - // At least on Windows the logical and physical pixel are the same - // See http://crbug.com/948362. - if (!dpi().is_zero() && dpi().x() == dpi().y()) - scale = dpi().x() / kStandardDPI; -#endif - - return scale; -} - -uint8_t* DesktopFrame::GetFrameDataAtPos(const DesktopVector& pos) const { - return data() + stride() * pos.y() + DesktopFrame::kBytesPerPixel * pos.x(); -} - -void DesktopFrame::CopyFrameInfoFrom(const DesktopFrame& other) { - set_dpi(other.dpi()); - set_capture_time_ms(other.capture_time_ms()); - set_capturer_id(other.capturer_id()); - *mutable_updated_region() = other.updated_region(); - set_top_left(other.top_left()); - set_icc_profile(other.icc_profile()); -} - -void DesktopFrame::MoveFrameInfoFrom(DesktopFrame* other) { - set_dpi(other->dpi()); - set_capture_time_ms(other->capture_time_ms()); - set_capturer_id(other->capturer_id()); - mutable_updated_region()->Swap(other->mutable_updated_region()); - set_top_left(other->top_left()); - set_icc_profile(other->icc_profile()); -} - -BasicDesktopFrame::BasicDesktopFrame(DesktopSize size) - : DesktopFrame(size, - kBytesPerPixel * size.width(), - new uint8_t[kBytesPerPixel * size.width() * size.height()](), - nullptr) {} - -BasicDesktopFrame::~BasicDesktopFrame() { - delete[] data_; -} - -// static -DesktopFrame* BasicDesktopFrame::CopyOf(const DesktopFrame& frame) { - DesktopFrame* result = new BasicDesktopFrame(frame.size()); - for (int y = 0; y < frame.size().height(); ++y) { - memcpy(result->data() + y * result->stride(), - frame.data() + y * frame.stride(), - frame.size().width() * kBytesPerPixel); - } - result->CopyFrameInfoFrom(frame); - return result; -} - -// static -std::unique_ptr SharedMemoryDesktopFrame::Create( - DesktopSize size, - SharedMemoryFactory* shared_memory_factory) { - RTC_DCHECK(shared_memory_factory); - - size_t buffer_size = size.height() * size.width() * kBytesPerPixel; - std::unique_ptr shared_memory = - shared_memory_factory->CreateSharedMemory(buffer_size); - if (!shared_memory) - return nullptr; - - return std::make_unique( - size, size.width() * kBytesPerPixel, std::move(shared_memory)); -} - -SharedMemoryDesktopFrame::SharedMemoryDesktopFrame(DesktopSize size, - int stride, - SharedMemory* shared_memory) - : DesktopFrame(size, - stride, - reinterpret_cast(shared_memory->data()), - shared_memory) {} - -SharedMemoryDesktopFrame::SharedMemoryDesktopFrame( - DesktopSize size, - int stride, - std::unique_ptr shared_memory) - : SharedMemoryDesktopFrame(size, stride, shared_memory.release()) {} - -SharedMemoryDesktopFrame::~SharedMemoryDesktopFrame() { - delete shared_memory_; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame.h deleted file mode 100644 index 3a18b7852..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_ - -#include - -#include -#include - -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/desktop_region.h" -#include "modules/desktop_capture/shared_memory.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -const float kStandardDPI = 96.0f; - -// DesktopFrame represents a video frame captured from the screen. -class RTC_EXPORT DesktopFrame { - public: - // DesktopFrame objects always hold RGBA data. - static const int kBytesPerPixel = 4; - - virtual ~DesktopFrame(); - - // Returns the rectangle in full desktop coordinates to indicate it covers - // the area of top_left() to top_letf() + size() / scale_factor(). - DesktopRect rect() const; - - // Returns the scale factor from DIPs to physical pixels of the frame. - // Assumes same scale in both X and Y directions at present. - float scale_factor() const; - - // Size of the frame. In physical coordinates, mapping directly from the - // underlying buffer. - const DesktopSize& size() const { return size_; } - - // The top-left of the frame in full desktop coordinates. E.g. the top left - // monitor should start from (0, 0). The desktop coordinates may be scaled by - // OS, but this is always consistent with the MouseCursorMonitor. - const DesktopVector& top_left() const { return top_left_; } - void set_top_left(const DesktopVector& top_left) { top_left_ = top_left; } - - // Distance in the buffer between two neighboring rows in bytes. - int stride() const { return stride_; } - - // Data buffer used for the frame. - uint8_t* data() const { return data_; } - - // SharedMemory used for the buffer or NULL if memory is allocated on the - // heap. The result is guaranteed to be deleted only after the frame is - // deleted (classes that inherit from DesktopFrame must ensure it). - SharedMemory* shared_memory() const { return shared_memory_; } - - // Indicates region of the screen that has changed since the previous frame. - const DesktopRegion& updated_region() const { return updated_region_; } - DesktopRegion* mutable_updated_region() { return &updated_region_; } - - // DPI of the screen being captured. May be set to zero, e.g. if DPI is - // unknown. - const DesktopVector& dpi() const { return dpi_; } - void set_dpi(const DesktopVector& dpi) { dpi_ = dpi; } - - // Time taken to capture the frame in milliseconds. - int64_t capture_time_ms() const { return capture_time_ms_; } - void set_capture_time_ms(int64_t time_ms) { capture_time_ms_ = time_ms; } - - // Copies pixels from a buffer or another frame. |dest_rect| rect must lay - // within bounds of this frame. - void CopyPixelsFrom(const uint8_t* src_buffer, - int src_stride, - const DesktopRect& dest_rect); - void CopyPixelsFrom(const DesktopFrame& src_frame, - const DesktopVector& src_pos, - const DesktopRect& dest_rect); - - // Copies pixels from another frame, with the copied & overwritten regions - // representing the intersection between the two frames. Returns true if - // pixels were copied, or false if there's no intersection. The scale factors - // represent the ratios between pixel space & offset coordinate space (e.g. - // 2.0 would indicate the frames are scaled down by 50% for display, so any - // offset between their origins should be doubled). - bool CopyIntersectingPixelsFrom(const DesktopFrame& src_frame, - double horizontal_scale, - double vertical_scale); - - // A helper to return the data pointer of a frame at the specified position. - uint8_t* GetFrameDataAtPos(const DesktopVector& pos) const; - - // The DesktopCapturer implementation which generates current DesktopFrame. - // Not all DesktopCapturer implementations set this field; it's set to - // kUnknown by default. - uint32_t capturer_id() const { return capturer_id_; } - void set_capturer_id(uint32_t capturer_id) { capturer_id_ = capturer_id; } - - // Copies various information from |other|. Anything initialized in - // constructor are not copied. - // This function is usually used when sharing a source DesktopFrame with - // several clients: the original DesktopFrame should be kept unchanged. For - // example, BasicDesktopFrame::CopyOf() and SharedDesktopFrame::Share(). - void CopyFrameInfoFrom(const DesktopFrame& other); - - // Copies various information from |other|. Anything initialized in - // constructor are not copied. Not like CopyFrameInfoFrom() function, this - // function uses swap or move constructor to avoid data copy. It won't break - // the |other|, but some of its information may be missing after this - // operation. E.g. other->updated_region_; - // This function is usually used when wrapping a DesktopFrame: the wrapper - // instance takes the ownership of |other|, so other components cannot access - // |other| anymore. For example, CroppedDesktopFrame and - // DesktopFrameWithCursor. - void MoveFrameInfoFrom(DesktopFrame* other); - - // Set and get the ICC profile of the frame data pixels. Useful to build the - // a ColorSpace object from clients of webrtc library like chromium. The - // format of an ICC profile is defined in the following specification - // http://www.color.org/specification/ICC1v43_2010-12.pdf. - const std::vector& icc_profile() const { return icc_profile_; } - void set_icc_profile(const std::vector& icc_profile) { - icc_profile_ = icc_profile; - } - - protected: - DesktopFrame(DesktopSize size, - int stride, - uint8_t* data, - SharedMemory* shared_memory); - - // Ownership of the buffers is defined by the classes that inherit from this - // class. They must guarantee that the buffer is not deleted before the frame - // is deleted. - uint8_t* const data_; - SharedMemory* const shared_memory_; - - private: - const DesktopSize size_; - const int stride_; - - DesktopRegion updated_region_; - DesktopVector top_left_; - DesktopVector dpi_; - int64_t capture_time_ms_; - uint32_t capturer_id_; - std::vector icc_profile_; - - RTC_DISALLOW_COPY_AND_ASSIGN(DesktopFrame); -}; - -// A DesktopFrame that stores data in the heap. -class RTC_EXPORT BasicDesktopFrame : public DesktopFrame { - public: - // The entire data buffer used for the frame is initialized with zeros. - explicit BasicDesktopFrame(DesktopSize size); - - ~BasicDesktopFrame() override; - - // Creates a BasicDesktopFrame that contains copy of |frame|. - // TODO(zijiehe): Return std::unique_ptr - static DesktopFrame* CopyOf(const DesktopFrame& frame); - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(BasicDesktopFrame); -}; - -// A DesktopFrame that stores data in shared memory. -class RTC_EXPORT SharedMemoryDesktopFrame : public DesktopFrame { - public: - // May return nullptr if |shared_memory_factory| failed to create a - // SharedMemory instance. - // |shared_memory_factory| should not be nullptr. - static std::unique_ptr Create( - DesktopSize size, - SharedMemoryFactory* shared_memory_factory); - - // Takes ownership of |shared_memory|. - // Deprecated, use the next constructor. - SharedMemoryDesktopFrame(DesktopSize size, - int stride, - SharedMemory* shared_memory); - - // Preferred. - SharedMemoryDesktopFrame(DesktopSize size, - int stride, - std::unique_ptr shared_memory); - - ~SharedMemoryDesktopFrame() override; - - private: - // Avoid unexpected order of parameter evaluation. - // Executing both std::unique_ptr::operator->() and - // std::unique_ptr::release() in the member initializer list is not safe. - // Depends on the order of parameter evaluation, - // std::unique_ptr::operator->() may trigger assertion failure if it has - // been evaluated after std::unique_ptr::release(). By using this - // constructor, std::unique_ptr::operator->() won't be involved anymore. - SharedMemoryDesktopFrame(DesktopRect rect, - int stride, - SharedMemory* shared_memory); - - RTC_DISALLOW_COPY_AND_ASSIGN(SharedMemoryDesktopFrame); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_generator.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_generator.cc deleted file mode 100644 index 64ba86c67..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_generator.cc +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2016 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/desktop_capture/desktop_frame_generator.h" - -#include -#include - -#include - -#include "modules/desktop_capture/rgba_color.h" -#include "rtc_base/checks.h" -#include "rtc_base/random.h" -#include "rtc_base/time_utils.h" - -namespace webrtc { - -namespace { - -// Sets |updated_region| to |frame|. If |enlarge_updated_region| is -// true, this function will randomly enlarge each DesktopRect in -// |updated_region|. But the enlarged DesktopRegion won't excceed the -// frame->size(). If |add_random_updated_region| is true, several random -// rectangles will also be included in |frame|. -void SetUpdatedRegion(DesktopFrame* frame, - const DesktopRegion& updated_region, - bool enlarge_updated_region, - int enlarge_range, - bool add_random_updated_region) { - const DesktopRect screen_rect = DesktopRect::MakeSize(frame->size()); - Random random(rtc::TimeMicros()); - frame->mutable_updated_region()->Clear(); - for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd(); - it.Advance()) { - DesktopRect rect = it.rect(); - if (enlarge_updated_region && enlarge_range > 0) { - rect.Extend(random.Rand(enlarge_range), random.Rand(enlarge_range), - random.Rand(enlarge_range), random.Rand(enlarge_range)); - rect.IntersectWith(screen_rect); - } - frame->mutable_updated_region()->AddRect(rect); - } - - if (add_random_updated_region) { - for (int i = random.Rand(10); i >= 0; i--) { - // At least a 1 x 1 updated region. - const int left = random.Rand(0, frame->size().width() - 2); - const int top = random.Rand(0, frame->size().height() - 2); - const int right = random.Rand(left + 1, frame->size().width()); - const int bottom = random.Rand(top + 1, frame->size().height()); - frame->mutable_updated_region()->AddRect( - DesktopRect::MakeLTRB(left, top, right, bottom)); - } - } -} - -// Paints pixels in |rect| of |frame| to |color|. -void PaintRect(DesktopFrame* frame, DesktopRect rect, RgbaColor rgba_color) { - static_assert(DesktopFrame::kBytesPerPixel == sizeof(uint32_t), - "kBytesPerPixel should be 4."); - RTC_DCHECK_GE(frame->size().width(), rect.right()); - RTC_DCHECK_GE(frame->size().height(), rect.bottom()); - uint32_t color = rgba_color.ToUInt32(); - uint8_t* row = frame->GetFrameDataAtPos(rect.top_left()); - for (int i = 0; i < rect.height(); i++) { - uint32_t* column = reinterpret_cast(row); - for (int j = 0; j < rect.width(); j++) { - column[j] = color; - } - row += frame->stride(); - } -} - -// Paints pixels in |region| of |frame| to |color|. -void PaintRegion(DesktopFrame* frame, - DesktopRegion* region, - RgbaColor rgba_color) { - region->IntersectWith(DesktopRect::MakeSize(frame->size())); - for (DesktopRegion::Iterator it(*region); !it.IsAtEnd(); it.Advance()) { - PaintRect(frame, it.rect(), rgba_color); - } -} - -} // namespace - -DesktopFrameGenerator::DesktopFrameGenerator() {} -DesktopFrameGenerator::~DesktopFrameGenerator() {} - -DesktopFramePainter::DesktopFramePainter() {} -DesktopFramePainter::~DesktopFramePainter() {} - -PainterDesktopFrameGenerator::PainterDesktopFrameGenerator() - : size_(1024, 768), - return_frame_(true), - provide_updated_region_hints_(false), - enlarge_updated_region_(false), - enlarge_range_(20), - add_random_updated_region_(false), - painter_(nullptr) {} -PainterDesktopFrameGenerator::~PainterDesktopFrameGenerator() {} - -std::unique_ptr PainterDesktopFrameGenerator::GetNextFrame( - SharedMemoryFactory* factory) { - if (!return_frame_) { - return nullptr; - } - - std::unique_ptr frame = std::unique_ptr( - factory ? SharedMemoryDesktopFrame::Create(size_, factory).release() - : new BasicDesktopFrame(size_)); - if (painter_) { - DesktopRegion updated_region; - if (!painter_->Paint(frame.get(), &updated_region)) { - return nullptr; - } - - if (provide_updated_region_hints_) { - SetUpdatedRegion(frame.get(), updated_region, enlarge_updated_region_, - enlarge_range_, add_random_updated_region_); - } else { - frame->mutable_updated_region()->SetRect( - DesktopRect::MakeSize(frame->size())); - } - } - - return frame; -} - -DesktopSize* PainterDesktopFrameGenerator::size() { - return &size_; -} - -void PainterDesktopFrameGenerator::set_return_frame(bool return_frame) { - return_frame_ = return_frame; -} - -void PainterDesktopFrameGenerator::set_provide_updated_region_hints( - bool provide_updated_region_hints) { - provide_updated_region_hints_ = provide_updated_region_hints; -} - -void PainterDesktopFrameGenerator::set_enlarge_updated_region( - bool enlarge_updated_region) { - enlarge_updated_region_ = enlarge_updated_region; -} - -void PainterDesktopFrameGenerator::set_enlarge_range(int enlarge_range) { - enlarge_range_ = enlarge_range; -} - -void PainterDesktopFrameGenerator::set_add_random_updated_region( - bool add_random_updated_region) { - add_random_updated_region_ = add_random_updated_region; -} - -void PainterDesktopFrameGenerator::set_desktop_frame_painter( - DesktopFramePainter* painter) { - painter_ = painter; -} - -BlackWhiteDesktopFramePainter::BlackWhiteDesktopFramePainter() {} -BlackWhiteDesktopFramePainter::~BlackWhiteDesktopFramePainter() {} - -DesktopRegion* BlackWhiteDesktopFramePainter::updated_region() { - return &updated_region_; -} - -bool BlackWhiteDesktopFramePainter::Paint(DesktopFrame* frame, - DesktopRegion* updated_region) { - RTC_DCHECK(updated_region->is_empty()); - memset(frame->data(), 0, frame->stride() * frame->size().height()); - PaintRegion(frame, &updated_region_, RgbaColor(0xFFFFFFFF)); - updated_region_.Swap(updated_region); - return true; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_generator.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_generator.h deleted file mode 100644 index c8ac5a9ae..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_generator.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_GENERATOR_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_GENERATOR_H_ - -#include - -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/desktop_region.h" -#include "modules/desktop_capture/shared_memory.h" - -namespace webrtc { - -// An interface to generate a DesktopFrame. -class DesktopFrameGenerator { - public: - DesktopFrameGenerator(); - virtual ~DesktopFrameGenerator(); - - virtual std::unique_ptr GetNextFrame( - SharedMemoryFactory* factory) = 0; -}; - -// An interface to paint a DesktopFrame. This interface is used by -// PainterDesktopFrameGenerator. -class DesktopFramePainter { - public: - DesktopFramePainter(); - virtual ~DesktopFramePainter(); - - virtual bool Paint(DesktopFrame* frame, DesktopRegion* updated_region) = 0; -}; - -// An implementation of DesktopFrameGenerator to take care about the -// DesktopFrame size, filling updated_region(), etc, but leaves the real -// painting work to a DesktopFramePainter implementation. -class PainterDesktopFrameGenerator final : public DesktopFrameGenerator { - public: - PainterDesktopFrameGenerator(); - ~PainterDesktopFrameGenerator() override; - - std::unique_ptr GetNextFrame( - SharedMemoryFactory* factory) override; - - // Sets the size of the frame which will be returned in next GetNextFrame() - // call. - DesktopSize* size(); - - // Decides whether BaseDesktopFrameGenerator returns a frame in next Capture() - // callback. If return_frame_ is true, BaseDesktopFrameGenerator will create a - // frame according to both size_ and SharedMemoryFactory input, and uses - // Paint() function to paint it. - void set_return_frame(bool return_frame); - - // Decides whether MockScreenCapturer returns a frame with updated regions. - // MockScreenCapturer will keep DesktopFrame::updated_region() empty if this - // field is false. - void set_provide_updated_region_hints(bool provide_updated_region_hints); - - // Decides whether MockScreenCapturer randomly enlarges updated regions in the - // DesktopFrame. Set this field to true to simulate an inaccurate updated - // regions' return from OS APIs. - void set_enlarge_updated_region(bool enlarge_updated_region); - - // The range to enlarge a updated region if |enlarge_updated_region_| is true. - // If this field is less than zero, it will be treated as zero, and - // |enlarge_updated_region_| will be ignored. - void set_enlarge_range(int enlarge_range); - - // Decides whether BaseDesktopFrameGenerator randomly add some updated regions - // in the DesktopFrame. Set this field to true to simulate an inaccurate - // updated regions' return from OS APIs. - void set_add_random_updated_region(bool add_random_updated_region); - - // Sets the painter object to do the real painting work, if no |painter_| has - // been set to this instance, the DesktopFrame returned by GetNextFrame() - // function will keep in an undefined but valid state. - // PainterDesktopFrameGenerator does not take ownership of the |painter|. - void set_desktop_frame_painter(DesktopFramePainter* painter); - - private: - DesktopSize size_; - bool return_frame_; - bool provide_updated_region_hints_; - bool enlarge_updated_region_; - int enlarge_range_; - bool add_random_updated_region_; - DesktopFramePainter* painter_; -}; - -// An implementation of DesktopFramePainter to paint black on -// mutable_updated_region(), and white elsewhere. -class BlackWhiteDesktopFramePainter final : public DesktopFramePainter { - public: - BlackWhiteDesktopFramePainter(); - ~BlackWhiteDesktopFramePainter() override; - - // The black regions of the frame which will be returned in next Paint() - // call. BlackWhiteDesktopFramePainter will draw a white frame, with black - // in the updated_region_. Each Paint() call will consume updated_region_. - DesktopRegion* updated_region(); - - // DesktopFramePainter interface. - bool Paint(DesktopFrame* frame, DesktopRegion* updated_region) override; - - private: - DesktopRegion updated_region_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_GENERATOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_rotation.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_rotation.cc deleted file mode 100644 index 5e9928d1f..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_rotation.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2016 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/desktop_capture/desktop_frame_rotation.h" - -#include "rtc_base/checks.h" -#include "third_party/libyuv/include/libyuv/rotate_argb.h" - -namespace webrtc { - -namespace { - -libyuv::RotationMode ToLibyuvRotationMode(Rotation rotation) { - switch (rotation) { - case Rotation::CLOCK_WISE_0: - return libyuv::kRotate0; - case Rotation::CLOCK_WISE_90: - return libyuv::kRotate90; - case Rotation::CLOCK_WISE_180: - return libyuv::kRotate180; - case Rotation::CLOCK_WISE_270: - return libyuv::kRotate270; - } - RTC_NOTREACHED(); - return libyuv::kRotate0; -} - -DesktopRect RotateAndOffsetRect(DesktopRect rect, - DesktopSize size, - Rotation rotation, - DesktopVector offset) { - DesktopRect result = RotateRect(rect, size, rotation); - result.Translate(offset); - return result; -} - -} // namespace - -Rotation ReverseRotation(Rotation rotation) { - switch (rotation) { - case Rotation::CLOCK_WISE_0: - return rotation; - case Rotation::CLOCK_WISE_90: - return Rotation::CLOCK_WISE_270; - case Rotation::CLOCK_WISE_180: - return Rotation::CLOCK_WISE_180; - case Rotation::CLOCK_WISE_270: - return Rotation::CLOCK_WISE_90; - } - RTC_NOTREACHED(); - return Rotation::CLOCK_WISE_0; -} - -DesktopSize RotateSize(DesktopSize size, Rotation rotation) { - switch (rotation) { - case Rotation::CLOCK_WISE_0: - case Rotation::CLOCK_WISE_180: - return size; - case Rotation::CLOCK_WISE_90: - case Rotation::CLOCK_WISE_270: - return DesktopSize(size.height(), size.width()); - } - RTC_NOTREACHED(); - return DesktopSize(); -} - -DesktopRect RotateRect(DesktopRect rect, DesktopSize size, Rotation rotation) { - switch (rotation) { - case Rotation::CLOCK_WISE_0: - return rect; - case Rotation::CLOCK_WISE_90: - return DesktopRect::MakeXYWH(size.height() - rect.bottom(), rect.left(), - rect.height(), rect.width()); - case Rotation::CLOCK_WISE_180: - return DesktopRect::MakeXYWH(size.width() - rect.right(), - size.height() - rect.bottom(), rect.width(), - rect.height()); - case Rotation::CLOCK_WISE_270: - return DesktopRect::MakeXYWH(rect.top(), size.width() - rect.right(), - rect.height(), rect.width()); - } - RTC_NOTREACHED(); - return DesktopRect(); -} - -void RotateDesktopFrame(const DesktopFrame& source, - const DesktopRect& source_rect, - const Rotation& rotation, - const DesktopVector& target_offset, - DesktopFrame* target) { - RTC_DCHECK(target); - RTC_DCHECK(DesktopRect::MakeSize(source.size()).ContainsRect(source_rect)); - // The rectangle in |target|. - const DesktopRect target_rect = - RotateAndOffsetRect(source_rect, source.size(), rotation, target_offset); - RTC_DCHECK(DesktopRect::MakeSize(target->size()).ContainsRect(target_rect)); - - if (target_rect.is_empty()) { - return; - } - - int result = libyuv::ARGBRotate( - source.GetFrameDataAtPos(source_rect.top_left()), source.stride(), - target->GetFrameDataAtPos(target_rect.top_left()), target->stride(), - source_rect.width(), source_rect.height(), - ToLibyuvRotationMode(rotation)); - RTC_DCHECK_EQ(result, 0); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_rotation.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_rotation.h deleted file mode 100644 index 72bb1a651..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_rotation.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_ROTATION_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_ROTATION_H_ - -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" - -namespace webrtc { - -// Represents the rotation of a DesktopFrame. -enum class Rotation { - CLOCK_WISE_0, - CLOCK_WISE_90, - CLOCK_WISE_180, - CLOCK_WISE_270, -}; - -// Rotates input DesktopFrame |source|, copies pixel in an unrotated rectangle -// |source_rect| into the target rectangle of another DesktopFrame |target|. -// Target rectangle here is the rotated |source_rect| plus |target_offset|. -// |rotation| specifies |source| to |target| rotation. |source_rect| is in -// |source| coordinate. |target_offset| is in |target| coordinate. -// This function triggers check failure if |source| does not cover the -// |source_rect|, or |target| does not cover the rotated |rect|. -void RotateDesktopFrame(const DesktopFrame& source, - const DesktopRect& source_rect, - const Rotation& rotation, - const DesktopVector& target_offset, - DesktopFrame* target); - -// Returns a reverse rotation of |rotation|. -Rotation ReverseRotation(Rotation rotation); - -// Returns a rotated DesktopSize of |size|. -DesktopSize RotateSize(DesktopSize size, Rotation rotation); - -// Returns a rotated DesktopRect of |rect|. The |size| represents the size of -// the DesktopFrame which |rect| belongs in. -DesktopRect RotateRect(DesktopRect rect, DesktopSize size, Rotation rotation); - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_ROTATION_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_win.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_win.cc deleted file mode 100644 index 58ebac91d..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_win.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/desktop_frame_win.h" - -#include - -#include "rtc_base/logging.h" - -namespace webrtc { - -DesktopFrameWin::DesktopFrameWin(DesktopSize size, - int stride, - uint8_t* data, - std::unique_ptr shared_memory, - HBITMAP bitmap) - : DesktopFrame(size, stride, data, shared_memory.get()), - bitmap_(bitmap), - owned_shared_memory_(std::move(shared_memory)) {} - -DesktopFrameWin::~DesktopFrameWin() { - DeleteObject(bitmap_); -} - -// static -std::unique_ptr DesktopFrameWin::Create( - DesktopSize size, - SharedMemoryFactory* shared_memory_factory, - HDC hdc) { - int bytes_per_row = size.width() * kBytesPerPixel; - int buffer_size = bytes_per_row * size.height(); - - // Describe a device independent bitmap (DIB) that is the size of the desktop. - BITMAPINFO bmi = {}; - bmi.bmiHeader.biHeight = -size.height(); - bmi.bmiHeader.biWidth = size.width(); - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = DesktopFrameWin::kBytesPerPixel * 8; - bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); - bmi.bmiHeader.biSizeImage = bytes_per_row * size.height(); - - std::unique_ptr shared_memory; - HANDLE section_handle = nullptr; - if (shared_memory_factory) { - shared_memory = shared_memory_factory->CreateSharedMemory(buffer_size); - section_handle = shared_memory->handle(); - } - void* data = nullptr; - HBITMAP bitmap = - CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &data, section_handle, 0); - if (!bitmap) { - RTC_LOG(LS_WARNING) << "Failed to allocate new window frame " - << GetLastError(); - return nullptr; - } - - return std::unique_ptr( - new DesktopFrameWin(size, bytes_per_row, reinterpret_cast(data), - std::move(shared_memory), bitmap)); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_win.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_win.h deleted file mode 100644 index 73e864868..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_frame_win.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_WIN_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_WIN_H_ - -#include - -#include - -#include "modules/desktop_capture/desktop_frame.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -// DesktopFrame implementation used by screen and window captures on Windows. -// Frame data is stored in a GDI bitmap. -class DesktopFrameWin : public DesktopFrame { - public: - ~DesktopFrameWin() override; - - static std::unique_ptr - Create(DesktopSize size, SharedMemoryFactory* shared_memory_factory, HDC hdc); - - HBITMAP bitmap() { return bitmap_; } - - private: - DesktopFrameWin(DesktopSize size, - int stride, - uint8_t* data, - std::unique_ptr shared_memory, - HBITMAP bitmap); - - HBITMAP bitmap_; - std::unique_ptr owned_shared_memory_; - - RTC_DISALLOW_COPY_AND_ASSIGN(DesktopFrameWin); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_WIN_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_geometry.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_geometry.cc deleted file mode 100644 index e0a5d7af8..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_geometry.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/desktop_geometry.h" - -#include -#include - -namespace webrtc { - -bool DesktopRect::Contains(const DesktopVector& point) const { - return point.x() >= left() && point.x() < right() && point.y() >= top() && - point.y() < bottom(); -} - -bool DesktopRect::ContainsRect(const DesktopRect& rect) const { - return rect.left() >= left() && rect.right() <= right() && - rect.top() >= top() && rect.bottom() <= bottom(); -} - -void DesktopRect::IntersectWith(const DesktopRect& rect) { - left_ = std::max(left(), rect.left()); - top_ = std::max(top(), rect.top()); - right_ = std::min(right(), rect.right()); - bottom_ = std::min(bottom(), rect.bottom()); - if (is_empty()) { - left_ = 0; - top_ = 0; - right_ = 0; - bottom_ = 0; - } -} - -void DesktopRect::UnionWith(const DesktopRect& rect) { - if (is_empty()) { - *this = rect; - return; - } - - if (rect.is_empty()) { - return; - } - - left_ = std::min(left(), rect.left()); - top_ = std::min(top(), rect.top()); - right_ = std::max(right(), rect.right()); - bottom_ = std::max(bottom(), rect.bottom()); -} - -void DesktopRect::Translate(int32_t dx, int32_t dy) { - left_ += dx; - top_ += dy; - right_ += dx; - bottom_ += dy; -} - -void DesktopRect::Extend(int32_t left_offset, - int32_t top_offset, - int32_t right_offset, - int32_t bottom_offset) { - left_ -= left_offset; - top_ -= top_offset; - right_ += right_offset; - bottom_ += bottom_offset; -} - -void DesktopRect::Scale(double horizontal, double vertical) { - right_ += static_cast(std::round(width() * (horizontal - 1))); - bottom_ += static_cast(std::round(height() * (vertical - 1))); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_geometry.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_geometry.h deleted file mode 100644 index 09ebefda9..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_geometry.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_GEOMETRY_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_GEOMETRY_H_ - -#include - -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// A vector in the 2D integer space. E.g. can be used to represent screen DPI. -class DesktopVector { - public: - DesktopVector() : x_(0), y_(0) {} - DesktopVector(int32_t x, int32_t y) : x_(x), y_(y) {} - - int32_t x() const { return x_; } - int32_t y() const { return y_; } - bool is_zero() const { return x_ == 0 && y_ == 0; } - - bool equals(const DesktopVector& other) const { - return x_ == other.x_ && y_ == other.y_; - } - - void set(int32_t x, int32_t y) { - x_ = x; - y_ = y; - } - - DesktopVector add(const DesktopVector& other) const { - return DesktopVector(x() + other.x(), y() + other.y()); - } - DesktopVector subtract(const DesktopVector& other) const { - return DesktopVector(x() - other.x(), y() - other.y()); - } - - DesktopVector operator-() const { return DesktopVector(-x_, -y_); } - - private: - int32_t x_; - int32_t y_; -}; - -// Type used to represent screen/window size. -class DesktopSize { - public: - DesktopSize() : width_(0), height_(0) {} - DesktopSize(int32_t width, int32_t height) : width_(width), height_(height) {} - - int32_t width() const { return width_; } - int32_t height() const { return height_; } - - bool is_empty() const { return width_ <= 0 || height_ <= 0; } - - bool equals(const DesktopSize& other) const { - return width_ == other.width_ && height_ == other.height_; - } - - void set(int32_t width, int32_t height) { - width_ = width; - height_ = height; - } - - private: - int32_t width_; - int32_t height_; -}; - -// Represents a rectangle on the screen. -class RTC_EXPORT DesktopRect { - public: - static DesktopRect MakeSize(const DesktopSize& size) { - return DesktopRect(0, 0, size.width(), size.height()); - } - static DesktopRect MakeWH(int32_t width, int32_t height) { - return DesktopRect(0, 0, width, height); - } - static DesktopRect MakeXYWH(int32_t x, - int32_t y, - int32_t width, - int32_t height) { - return DesktopRect(x, y, x + width, y + height); - } - static DesktopRect MakeLTRB(int32_t left, - int32_t top, - int32_t right, - int32_t bottom) { - return DesktopRect(left, top, right, bottom); - } - static DesktopRect MakeOriginSize(const DesktopVector& origin, - const DesktopSize& size) { - return MakeXYWH(origin.x(), origin.y(), size.width(), size.height()); - } - - DesktopRect() : left_(0), top_(0), right_(0), bottom_(0) {} - - int32_t left() const { return left_; } - int32_t top() const { return top_; } - int32_t right() const { return right_; } - int32_t bottom() const { return bottom_; } - int32_t width() const { return right_ - left_; } - int32_t height() const { return bottom_ - top_; } - - void set_width(int32_t width) { right_ = left_ + width; } - void set_height(int32_t height) { bottom_ = top_ + height; } - - DesktopVector top_left() const { return DesktopVector(left_, top_); } - DesktopSize size() const { return DesktopSize(width(), height()); } - - bool is_empty() const { return left_ >= right_ || top_ >= bottom_; } - - bool equals(const DesktopRect& other) const { - return left_ == other.left_ && top_ == other.top_ && - right_ == other.right_ && bottom_ == other.bottom_; - } - - // Returns true if |point| lies within the rectangle boundaries. - bool Contains(const DesktopVector& point) const; - - // Returns true if |rect| lies within the boundaries of this rectangle. - bool ContainsRect(const DesktopRect& rect) const; - - // Finds intersection with |rect|. - void IntersectWith(const DesktopRect& rect); - - // Extends the rectangle to cover |rect|. If |this| is empty, replaces |this| - // with |rect|; if |rect| is empty, this function takes no effect. - void UnionWith(const DesktopRect& rect); - - // Adds (dx, dy) to the position of the rectangle. - void Translate(int32_t dx, int32_t dy); - void Translate(DesktopVector d) { Translate(d.x(), d.y()); } - - // Enlarges current DesktopRect by subtracting |left_offset| and |top_offset| - // from |left_| and |top_|, and adding |right_offset| and |bottom_offset| to - // |right_| and |bottom_|. This function does not normalize the result, so - // |left_| and |top_| may be less than zero or larger than |right_| and - // |bottom_|. - void Extend(int32_t left_offset, - int32_t top_offset, - int32_t right_offset, - int32_t bottom_offset); - - // Scales current DesktopRect. This function does not impact the |top_| and - // |left_|. - void Scale(double horizontal, double vertical); - - private: - DesktopRect(int32_t left, int32_t top, int32_t right, int32_t bottom) - : left_(left), top_(top), right_(right), bottom_(bottom) {} - - int32_t left_; - int32_t top_; - int32_t right_; - int32_t bottom_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_GEOMETRY_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_region.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_region.cc deleted file mode 100644 index befbcc6f4..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_region.cc +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/desktop_region.h" - -#include - -#include -#include - -namespace webrtc { - -DesktopRegion::RowSpan::RowSpan(int32_t left, int32_t right) - : left(left), right(right) {} - -DesktopRegion::Row::Row(const Row&) = default; -DesktopRegion::Row::Row(Row&&) = default; - -DesktopRegion::Row::Row(int32_t top, int32_t bottom) - : top(top), bottom(bottom) {} - -DesktopRegion::Row::~Row() {} - -DesktopRegion::DesktopRegion() {} - -DesktopRegion::DesktopRegion(const DesktopRect& rect) { - AddRect(rect); -} - -DesktopRegion::DesktopRegion(const DesktopRect* rects, int count) { - AddRects(rects, count); -} - -DesktopRegion::DesktopRegion(const DesktopRegion& other) { - *this = other; -} - -DesktopRegion::~DesktopRegion() { - Clear(); -} - -DesktopRegion& DesktopRegion::operator=(const DesktopRegion& other) { - Clear(); - rows_ = other.rows_; - for (Rows::iterator it = rows_.begin(); it != rows_.end(); ++it) { - // Copy each row. - Row* row = it->second; - it->second = new Row(*row); - } - return *this; -} - -bool DesktopRegion::Equals(const DesktopRegion& region) const { - // Iterate over rows of the tow regions and compare each row. - Rows::const_iterator it1 = rows_.begin(); - Rows::const_iterator it2 = region.rows_.begin(); - while (it1 != rows_.end()) { - if (it2 == region.rows_.end() || it1->first != it2->first || - it1->second->top != it2->second->top || - it1->second->bottom != it2->second->bottom || - it1->second->spans != it2->second->spans) { - return false; - } - ++it1; - ++it2; - } - return it2 == region.rows_.end(); -} - -void DesktopRegion::Clear() { - for (Rows::iterator row = rows_.begin(); row != rows_.end(); ++row) { - delete row->second; - } - rows_.clear(); -} - -void DesktopRegion::SetRect(const DesktopRect& rect) { - Clear(); - AddRect(rect); -} - -void DesktopRegion::AddRect(const DesktopRect& rect) { - if (rect.is_empty()) - return; - - // Top of the part of the |rect| that hasn't been inserted yet. Increased as - // we iterate over the rows until it reaches |rect.bottom()|. - int top = rect.top(); - - // Iterate over all rows that may intersect with |rect| and add new rows when - // necessary. - Rows::iterator row = rows_.upper_bound(top); - while (top < rect.bottom()) { - if (row == rows_.end() || top < row->second->top) { - // If |top| is above the top of the current |row| then add a new row above - // the current one. - int32_t bottom = rect.bottom(); - if (row != rows_.end() && row->second->top < bottom) - bottom = row->second->top; - row = rows_.insert(row, Rows::value_type(bottom, new Row(top, bottom))); - } else if (top > row->second->top) { - // If the |top| falls in the middle of the |row| then split |row| into - // two, at |top|, and leave |row| referring to the lower of the two, - // ready to insert a new span into. - assert(top <= row->second->bottom); - Rows::iterator new_row = rows_.insert( - row, Rows::value_type(top, new Row(row->second->top, top))); - row->second->top = top; - new_row->second->spans = row->second->spans; - } - - if (rect.bottom() < row->second->bottom) { - // If the bottom of the |rect| falls in the middle of the |row| split - // |row| into two, at |top|, and leave |row| referring to the upper of - // the two, ready to insert a new span into. - Rows::iterator new_row = rows_.insert( - row, Rows::value_type(rect.bottom(), new Row(top, rect.bottom()))); - row->second->top = rect.bottom(); - new_row->second->spans = row->second->spans; - row = new_row; - } - - // Add a new span to the current row. - AddSpanToRow(row->second, rect.left(), rect.right()); - top = row->second->bottom; - - MergeWithPrecedingRow(row); - - // Move to the next row. - ++row; - } - - if (row != rows_.end()) - MergeWithPrecedingRow(row); -} - -void DesktopRegion::AddRects(const DesktopRect* rects, int count) { - for (int i = 0; i < count; ++i) { - AddRect(rects[i]); - } -} - -void DesktopRegion::MergeWithPrecedingRow(Rows::iterator row) { - assert(row != rows_.end()); - - if (row != rows_.begin()) { - Rows::iterator previous_row = row; - previous_row--; - - // If |row| and |previous_row| are next to each other and contain the same - // set of spans then they can be merged. - if (previous_row->second->bottom == row->second->top && - previous_row->second->spans == row->second->spans) { - row->second->top = previous_row->second->top; - delete previous_row->second; - rows_.erase(previous_row); - } - } -} - -void DesktopRegion::AddRegion(const DesktopRegion& region) { - // TODO(sergeyu): This function is not optimized - potentially it can iterate - // over rows of the two regions similar to how it works in Intersect(). - for (Iterator it(region); !it.IsAtEnd(); it.Advance()) { - AddRect(it.rect()); - } -} - -void DesktopRegion::Intersect(const DesktopRegion& region1, - const DesktopRegion& region2) { - Clear(); - - Rows::const_iterator it1 = region1.rows_.begin(); - Rows::const_iterator end1 = region1.rows_.end(); - Rows::const_iterator it2 = region2.rows_.begin(); - Rows::const_iterator end2 = region2.rows_.end(); - if (it1 == end1 || it2 == end2) - return; - - while (it1 != end1 && it2 != end2) { - // Arrange for |it1| to always be the top-most of the rows. - if (it2->second->top < it1->second->top) { - std::swap(it1, it2); - std::swap(end1, end2); - } - - // Skip |it1| if it doesn't intersect |it2| at all. - if (it1->second->bottom <= it2->second->top) { - ++it1; - continue; - } - - // Top of the |it1| row is above the top of |it2|, so top of the - // intersection is always the top of |it2|. - int32_t top = it2->second->top; - int32_t bottom = std::min(it1->second->bottom, it2->second->bottom); - - Rows::iterator new_row = rows_.insert( - rows_.end(), Rows::value_type(bottom, new Row(top, bottom))); - IntersectRows(it1->second->spans, it2->second->spans, - &new_row->second->spans); - if (new_row->second->spans.empty()) { - delete new_row->second; - rows_.erase(new_row); - } else { - MergeWithPrecedingRow(new_row); - } - - // If |it1| was completely consumed, move to the next one. - if (it1->second->bottom == bottom) - ++it1; - // If |it2| was completely consumed, move to the next one. - if (it2->second->bottom == bottom) - ++it2; - } -} - -// static -void DesktopRegion::IntersectRows(const RowSpanSet& set1, - const RowSpanSet& set2, - RowSpanSet* output) { - RowSpanSet::const_iterator it1 = set1.begin(); - RowSpanSet::const_iterator end1 = set1.end(); - RowSpanSet::const_iterator it2 = set2.begin(); - RowSpanSet::const_iterator end2 = set2.end(); - assert(it1 != end1 && it2 != end2); - - do { - // Arrange for |it1| to always be the left-most of the spans. - if (it2->left < it1->left) { - std::swap(it1, it2); - std::swap(end1, end2); - } - - // Skip |it1| if it doesn't intersect |it2| at all. - if (it1->right <= it2->left) { - ++it1; - continue; - } - - int32_t left = it2->left; - int32_t right = std::min(it1->right, it2->right); - assert(left < right); - - output->push_back(RowSpan(left, right)); - - // If |it1| was completely consumed, move to the next one. - if (it1->right == right) - ++it1; - // If |it2| was completely consumed, move to the next one. - if (it2->right == right) - ++it2; - } while (it1 != end1 && it2 != end2); -} - -void DesktopRegion::IntersectWith(const DesktopRegion& region) { - DesktopRegion old_region; - Swap(&old_region); - Intersect(old_region, region); -} - -void DesktopRegion::IntersectWith(const DesktopRect& rect) { - DesktopRegion region; - region.AddRect(rect); - IntersectWith(region); -} - -void DesktopRegion::Subtract(const DesktopRegion& region) { - if (region.rows_.empty()) - return; - - // |row_b| refers to the current row being subtracted. - Rows::const_iterator row_b = region.rows_.begin(); - - // Current vertical position at which subtraction is happening. - int top = row_b->second->top; - - // |row_a| refers to the current row we are subtracting from. Skip all rows - // above |top|. - Rows::iterator row_a = rows_.upper_bound(top); - - // Step through rows of the both regions subtracting content of |row_b| from - // |row_a|. - while (row_a != rows_.end() && row_b != region.rows_.end()) { - // Skip |row_a| if it doesn't intersect with the |row_b|. - if (row_a->second->bottom <= top) { - // Each output row is merged with previously-processed rows before further - // rows are processed. - MergeWithPrecedingRow(row_a); - ++row_a; - continue; - } - - if (top > row_a->second->top) { - // If |top| falls in the middle of |row_a| then split |row_a| into two, at - // |top|, and leave |row_a| referring to the lower of the two, ready to - // subtract spans from. - assert(top <= row_a->second->bottom); - Rows::iterator new_row = rows_.insert( - row_a, Rows::value_type(top, new Row(row_a->second->top, top))); - row_a->second->top = top; - new_row->second->spans = row_a->second->spans; - } else if (top < row_a->second->top) { - // If the |top| is above |row_a| then skip the range between |top| and - // top of |row_a| because it's empty. - top = row_a->second->top; - if (top >= row_b->second->bottom) { - ++row_b; - if (row_b != region.rows_.end()) - top = row_b->second->top; - continue; - } - } - - if (row_b->second->bottom < row_a->second->bottom) { - // If the bottom of |row_b| falls in the middle of the |row_a| split - // |row_a| into two, at |top|, and leave |row_a| referring to the upper of - // the two, ready to subtract spans from. - int bottom = row_b->second->bottom; - Rows::iterator new_row = - rows_.insert(row_a, Rows::value_type(bottom, new Row(top, bottom))); - row_a->second->top = bottom; - new_row->second->spans = row_a->second->spans; - row_a = new_row; - } - - // At this point the vertical range covered by |row_a| lays within the - // range covered by |row_b|. Subtract |row_b| spans from |row_a|. - RowSpanSet new_spans; - SubtractRows(row_a->second->spans, row_b->second->spans, &new_spans); - new_spans.swap(row_a->second->spans); - top = row_a->second->bottom; - - if (top >= row_b->second->bottom) { - ++row_b; - if (row_b != region.rows_.end()) - top = row_b->second->top; - } - - // Check if the row is empty after subtraction and delete it. Otherwise move - // to the next one. - if (row_a->second->spans.empty()) { - Rows::iterator row_to_delete = row_a; - ++row_a; - delete row_to_delete->second; - rows_.erase(row_to_delete); - } else { - MergeWithPrecedingRow(row_a); - ++row_a; - } - } - - if (row_a != rows_.end()) - MergeWithPrecedingRow(row_a); -} - -void DesktopRegion::Subtract(const DesktopRect& rect) { - DesktopRegion region; - region.AddRect(rect); - Subtract(region); -} - -void DesktopRegion::Translate(int32_t dx, int32_t dy) { - Rows new_rows; - - for (Rows::iterator it = rows_.begin(); it != rows_.end(); ++it) { - Row* row = it->second; - - row->top += dy; - row->bottom += dy; - - if (dx != 0) { - // Translate each span. - for (RowSpanSet::iterator span = row->spans.begin(); - span != row->spans.end(); ++span) { - span->left += dx; - span->right += dx; - } - } - - if (dy != 0) - new_rows.insert(new_rows.end(), Rows::value_type(row->bottom, row)); - } - - if (dy != 0) - new_rows.swap(rows_); -} - -void DesktopRegion::Swap(DesktopRegion* region) { - rows_.swap(region->rows_); -} - -// static -bool DesktopRegion::CompareSpanRight(const RowSpan& r, int32_t value) { - return r.right < value; -} - -// static -bool DesktopRegion::CompareSpanLeft(const RowSpan& r, int32_t value) { - return r.left < value; -} - -// static -void DesktopRegion::AddSpanToRow(Row* row, int left, int right) { - // First check if the new span is located to the right of all existing spans. - // This is an optimization to avoid binary search in the case when rectangles - // are inserted sequentially from left to right. - if (row->spans.empty() || left > row->spans.back().right) { - row->spans.push_back(RowSpan(left, right)); - return; - } - - // Find the first span that ends at or after |left|. - RowSpanSet::iterator start = std::lower_bound( - row->spans.begin(), row->spans.end(), left, CompareSpanRight); - assert(start < row->spans.end()); - - // Find the first span that starts after |right|. - RowSpanSet::iterator end = - std::lower_bound(start, row->spans.end(), right + 1, CompareSpanLeft); - if (end == row->spans.begin()) { - // There are no overlaps. Just insert the new span at the beginning. - row->spans.insert(row->spans.begin(), RowSpan(left, right)); - return; - } - - // Move end to the left, so that it points the last span that ends at or - // before |right|. - end--; - - // At this point [start, end] is the range of spans that intersect with the - // new one. - if (end < start) { - // There are no overlaps. Just insert the new span at the correct position. - row->spans.insert(start, RowSpan(left, right)); - return; - } - - left = std::min(left, start->left); - right = std::max(right, end->right); - - // Replace range [start, end] with the new span. - *start = RowSpan(left, right); - ++start; - ++end; - if (start < end) - row->spans.erase(start, end); -} - -// static -bool DesktopRegion::IsSpanInRow(const Row& row, const RowSpan& span) { - // Find the first span that starts at or after |span.left| and then check if - // it's the same span. - RowSpanSet::const_iterator it = std::lower_bound( - row.spans.begin(), row.spans.end(), span.left, CompareSpanLeft); - return it != row.spans.end() && *it == span; -} - -// static -void DesktopRegion::SubtractRows(const RowSpanSet& set_a, - const RowSpanSet& set_b, - RowSpanSet* output) { - assert(!set_a.empty() && !set_b.empty()); - - RowSpanSet::const_iterator it_b = set_b.begin(); - - // Iterate over all spans in |set_a| adding parts of it that do not intersect - // with |set_b| to the |output|. - for (RowSpanSet::const_iterator it_a = set_a.begin(); it_a != set_a.end(); - ++it_a) { - // If there is no intersection then append the current span and continue. - if (it_b == set_b.end() || it_a->right < it_b->left) { - output->push_back(*it_a); - continue; - } - - // Iterate over |set_b| spans that may intersect with |it_a|. - int pos = it_a->left; - while (it_b != set_b.end() && it_b->left < it_a->right) { - if (it_b->left > pos) - output->push_back(RowSpan(pos, it_b->left)); - if (it_b->right > pos) { - pos = it_b->right; - if (pos >= it_a->right) - break; - } - ++it_b; - } - if (pos < it_a->right) - output->push_back(RowSpan(pos, it_a->right)); - } -} - -DesktopRegion::Iterator::Iterator(const DesktopRegion& region) - : region_(region), - row_(region.rows_.begin()), - previous_row_(region.rows_.end()) { - if (!IsAtEnd()) { - assert(row_->second->spans.size() > 0); - row_span_ = row_->second->spans.begin(); - UpdateCurrentRect(); - } -} - -DesktopRegion::Iterator::~Iterator() {} - -bool DesktopRegion::Iterator::IsAtEnd() const { - return row_ == region_.rows_.end(); -} - -void DesktopRegion::Iterator::Advance() { - assert(!IsAtEnd()); - - while (true) { - ++row_span_; - if (row_span_ == row_->second->spans.end()) { - previous_row_ = row_; - ++row_; - if (row_ != region_.rows_.end()) { - assert(row_->second->spans.size() > 0); - row_span_ = row_->second->spans.begin(); - } - } - - if (IsAtEnd()) - return; - - // If the same span exists on the previous row then skip it, as we've - // already returned this span merged into the previous one, via - // UpdateCurrentRect(). - if (previous_row_ != region_.rows_.end() && - previous_row_->second->bottom == row_->second->top && - IsSpanInRow(*previous_row_->second, *row_span_)) { - continue; - } - - break; - } - - assert(!IsAtEnd()); - UpdateCurrentRect(); -} - -void DesktopRegion::Iterator::UpdateCurrentRect() { - // Merge the current rectangle with the matching spans from later rows. - int bottom; - Rows::const_iterator bottom_row = row_; - Rows::const_iterator previous; - do { - bottom = bottom_row->second->bottom; - previous = bottom_row; - ++bottom_row; - } while (bottom_row != region_.rows_.end() && - previous->second->bottom == bottom_row->second->top && - IsSpanInRow(*bottom_row->second, *row_span_)); - rect_ = DesktopRect::MakeLTRB(row_span_->left, row_->second->top, - row_span_->right, bottom); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_region.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_region.h deleted file mode 100644 index 1aa95d097..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/desktop_region.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ -#define MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ - -#include - -#include -#include - -#include "modules/desktop_capture/desktop_geometry.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// DesktopRegion represents a region of the screen or window. -// -// Internally each region is stored as a set of rows where each row contains one -// or more rectangles aligned vertically. -class RTC_EXPORT DesktopRegion { - private: - // The following private types need to be declared first because they are used - // in the public Iterator. - - // RowSpan represents a horizontal span withing a single row. - struct RowSpan { - RowSpan(int32_t left, int32_t right); - - // Used by std::vector<>. - bool operator==(const RowSpan& that) const { - return left == that.left && right == that.right; - } - - int32_t left; - int32_t right; - }; - - typedef std::vector RowSpanSet; - - // Row represents a single row of a region. A row is set of rectangles that - // have the same vertical position. - struct Row { - Row(const Row&); - Row(Row&&); - Row(int32_t top, int32_t bottom); - ~Row(); - - int32_t top; - int32_t bottom; - - RowSpanSet spans; - }; - - // Type used to store list of rows in the region. The bottom position of row - // is used as the key so that rows are always ordered by their position. The - // map stores pointers to make Translate() more efficient. - typedef std::map Rows; - - public: - // Iterator that can be used to iterate over rectangles of a DesktopRegion. - // The region must not be mutated while the iterator is used. - class RTC_EXPORT Iterator { - public: - explicit Iterator(const DesktopRegion& target); - ~Iterator(); - - bool IsAtEnd() const; - void Advance(); - - const DesktopRect& rect() const { return rect_; } - - private: - const DesktopRegion& region_; - - // Updates |rect_| based on the current |row_| and |row_span_|. If - // |row_span_| matches spans on consecutive rows then they are also merged - // into |rect_|, to generate more efficient output. - void UpdateCurrentRect(); - - Rows::const_iterator row_; - Rows::const_iterator previous_row_; - RowSpanSet::const_iterator row_span_; - DesktopRect rect_; - }; - - DesktopRegion(); - explicit DesktopRegion(const DesktopRect& rect); - DesktopRegion(const DesktopRect* rects, int count); - DesktopRegion(const DesktopRegion& other); - ~DesktopRegion(); - - DesktopRegion& operator=(const DesktopRegion& other); - - bool is_empty() const { return rows_.empty(); } - - bool Equals(const DesktopRegion& region) const; - - // Reset the region to be empty. - void Clear(); - - // Reset region to contain just |rect|. - void SetRect(const DesktopRect& rect); - - // Adds specified rect(s) or region to the region. - void AddRect(const DesktopRect& rect); - void AddRects(const DesktopRect* rects, int count); - void AddRegion(const DesktopRegion& region); - - // Finds intersection of two regions and stores them in the current region. - void Intersect(const DesktopRegion& region1, const DesktopRegion& region2); - - // Same as above but intersects content of the current region with |region|. - void IntersectWith(const DesktopRegion& region); - - // Clips the region by the |rect|. - void IntersectWith(const DesktopRect& rect); - - // Subtracts |region| from the current content of the region. - void Subtract(const DesktopRegion& region); - - // Subtracts |rect| from the current content of the region. - void Subtract(const DesktopRect& rect); - - // Adds (dx, dy) to the position of the region. - void Translate(int32_t dx, int32_t dy); - - void Swap(DesktopRegion* region); - - private: - // Comparison functions used for std::lower_bound(). Compare left or right - // edges withs a given |value|. - static bool CompareSpanLeft(const RowSpan& r, int32_t value); - static bool CompareSpanRight(const RowSpan& r, int32_t value); - - // Adds a new span to the row, coalescing spans if necessary. - static void AddSpanToRow(Row* row, int32_t left, int32_t right); - - // Returns true if the |span| exists in the given |row|. - static bool IsSpanInRow(const Row& row, const RowSpan& rect); - - // Calculates the intersection of two sets of spans. - static void IntersectRows(const RowSpanSet& set1, - const RowSpanSet& set2, - RowSpanSet* output); - - static void SubtractRows(const RowSpanSet& set_a, - const RowSpanSet& set_b, - RowSpanSet* output); - - // Merges |row| with the row above it if they contain the same spans. Doesn't - // do anything if called with |row| set to rows_.begin() (i.e. first row of - // the region). If the rows were merged |row| remains a valid iterator to the - // merged row. - void MergeWithPrecedingRow(Rows::iterator row); - - Rows rows_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_block.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_block.cc deleted file mode 100644 index dd9ab457e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_block.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/differ_block.h" - -#include - -#include "modules/desktop_capture/differ_vector_sse2.h" -#include "rtc_base/system/arch.h" -#include "system_wrappers/include/cpu_features_wrapper.h" - -namespace webrtc { - -namespace { - -bool VectorDifference_C(const uint8_t* image1, const uint8_t* image2) { - return memcmp(image1, image2, kBlockSize * kBytesPerPixel) != 0; -} - -} // namespace - -bool VectorDifference(const uint8_t* image1, const uint8_t* image2) { - static bool (*diff_proc)(const uint8_t*, const uint8_t*) = nullptr; - - if (!diff_proc) { -#if defined(WEBRTC_ARCH_ARM_FAMILY) || defined(WEBRTC_ARCH_MIPS_FAMILY) - // For ARM and MIPS processors, always use C version. - // TODO(hclam): Implement a NEON version. - diff_proc = &VectorDifference_C; -#else - bool have_sse2 = WebRtc_GetCPUInfo(kSSE2) != 0; - // For x86 processors, check if SSE2 is supported. - if (have_sse2 && kBlockSize == 32) { - diff_proc = &VectorDifference_SSE2_W32; - } else if (have_sse2 && kBlockSize == 16) { - diff_proc = &VectorDifference_SSE2_W16; - } else { - diff_proc = &VectorDifference_C; - } -#endif - } - - return diff_proc(image1, image2); -} - -bool BlockDifference(const uint8_t* image1, - const uint8_t* image2, - int height, - int stride) { - for (int i = 0; i < height; i++) { - if (VectorDifference(image1, image2)) { - return true; - } - image1 += stride; - image2 += stride; - } - return false; -} - -bool BlockDifference(const uint8_t* image1, const uint8_t* image2, int stride) { - return BlockDifference(image1, image2, kBlockSize, stride); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_block.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_block.h deleted file mode 100644 index 2019ae03f..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_block.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_DIFFER_BLOCK_H_ -#define MODULES_DESKTOP_CAPTURE_DIFFER_BLOCK_H_ - -#include - -namespace webrtc { - -// Size (in pixels) of each square block used for diffing. This must be a -// multiple of sizeof(uint64)/8. -const int kBlockSize = 32; - -// Format: BGRA 32 bit. -const int kBytesPerPixel = 4; - -// Low level function to compare 2 vectors of pixels of size kBlockSize. Returns -// whether the blocks differ. -bool VectorDifference(const uint8_t* image1, const uint8_t* image2); - -// Low level function to compare 2 blocks of pixels of size -// (kBlockSize, |height|). Returns whether the blocks differ. -bool BlockDifference(const uint8_t* image1, - const uint8_t* image2, - int height, - int stride); - -// Low level function to compare 2 blocks of pixels of size -// (kBlockSize, kBlockSize). Returns whether the blocks differ. -bool BlockDifference(const uint8_t* image1, const uint8_t* image2, int stride); - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DIFFER_BLOCK_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_vector_sse2.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_vector_sse2.cc deleted file mode 100644 index 1c8b602d7..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_vector_sse2.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2016 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/desktop_capture/differ_vector_sse2.h" - -#if defined(_MSC_VER) -#include -#else -#include -#include -#endif - -namespace webrtc { - -extern bool VectorDifference_SSE2_W16(const uint8_t* image1, - const uint8_t* image2) { - __m128i acc = _mm_setzero_si128(); - __m128i v0; - __m128i v1; - __m128i sad; - const __m128i* i1 = reinterpret_cast(image1); - const __m128i* i2 = reinterpret_cast(image2); - v0 = _mm_loadu_si128(i1); - v1 = _mm_loadu_si128(i2); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 1); - v1 = _mm_loadu_si128(i2 + 1); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 2); - v1 = _mm_loadu_si128(i2 + 2); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 3); - v1 = _mm_loadu_si128(i2 + 3); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - - // This essential means sad = acc >> 64. We only care about the lower 16 - // bits. - sad = _mm_shuffle_epi32(acc, 0xEE); - sad = _mm_adds_epu16(sad, acc); - return _mm_cvtsi128_si32(sad) != 0; -} - -extern bool VectorDifference_SSE2_W32(const uint8_t* image1, - const uint8_t* image2) { - __m128i acc = _mm_setzero_si128(); - __m128i v0; - __m128i v1; - __m128i sad; - const __m128i* i1 = reinterpret_cast(image1); - const __m128i* i2 = reinterpret_cast(image2); - v0 = _mm_loadu_si128(i1); - v1 = _mm_loadu_si128(i2); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 1); - v1 = _mm_loadu_si128(i2 + 1); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 2); - v1 = _mm_loadu_si128(i2 + 2); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 3); - v1 = _mm_loadu_si128(i2 + 3); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 4); - v1 = _mm_loadu_si128(i2 + 4); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 5); - v1 = _mm_loadu_si128(i2 + 5); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 6); - v1 = _mm_loadu_si128(i2 + 6); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - v0 = _mm_loadu_si128(i1 + 7); - v1 = _mm_loadu_si128(i2 + 7); - sad = _mm_sad_epu8(v0, v1); - acc = _mm_adds_epu16(acc, sad); - - // This essential means sad = acc >> 64. We only care about the lower 16 - // bits. - sad = _mm_shuffle_epi32(acc, 0xEE); - sad = _mm_adds_epu16(sad, acc); - return _mm_cvtsi128_si32(sad) != 0; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_vector_sse2.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_vector_sse2.h deleted file mode 100644 index a3c297eb9..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/differ_vector_sse2.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -// This header file is used only differ_block.h. It defines the SSE2 rountines -// for finding vector difference. - -#ifndef MODULES_DESKTOP_CAPTURE_DIFFER_VECTOR_SSE2_H_ -#define MODULES_DESKTOP_CAPTURE_DIFFER_VECTOR_SSE2_H_ - -#include - -namespace webrtc { - -// Find vector difference of dimension 16. -extern bool VectorDifference_SSE2_W16(const uint8_t* image1, - const uint8_t* image2); - -// Find vector difference of dimension 32. -extern bool VectorDifference_SSE2_W32(const uint8_t* image1, - const uint8_t* image2); - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_DIFFER_VECTOR_SSE2_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fake_desktop_capturer.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fake_desktop_capturer.cc deleted file mode 100644 index 83e360b0d..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fake_desktop_capturer.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016 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/desktop_capture/fake_desktop_capturer.h" - -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_frame.h" - -namespace webrtc { - -FakeDesktopCapturer::FakeDesktopCapturer() = default; -FakeDesktopCapturer::~FakeDesktopCapturer() = default; - -void FakeDesktopCapturer::set_result(DesktopCapturer::Result result) { - result_ = result; -} - -int FakeDesktopCapturer::num_frames_captured() const { - return num_frames_captured_; -} - -int FakeDesktopCapturer::num_capture_attempts() const { - return num_capture_attempts_; -} - -// Uses the |generator| provided as DesktopFrameGenerator, FakeDesktopCapturer -// does -// not take the ownership of |generator|. -void FakeDesktopCapturer::set_frame_generator( - DesktopFrameGenerator* generator) { - generator_ = generator; -} - -void FakeDesktopCapturer::Start(DesktopCapturer::Callback* callback) { - callback_ = callback; -} - -void FakeDesktopCapturer::CaptureFrame() { - num_capture_attempts_++; - if (generator_) { - if (result_ != DesktopCapturer::Result::SUCCESS) { - callback_->OnCaptureResult(result_, nullptr); - return; - } - - std::unique_ptr frame( - generator_->GetNextFrame(shared_memory_factory_.get())); - if (frame) { - num_frames_captured_++; - callback_->OnCaptureResult(result_, std::move(frame)); - } else { - callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_TEMPORARY, - nullptr); - } - return; - } - callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT, nullptr); -} - -void FakeDesktopCapturer::SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) { - shared_memory_factory_ = std::move(shared_memory_factory); -} - -bool FakeDesktopCapturer::GetSourceList(DesktopCapturer::SourceList* sources) { - sources->push_back({kWindowId, "A-Fake-DesktopCapturer-Window"}); - sources->push_back({kScreenId}); - return true; -} - -bool FakeDesktopCapturer::SelectSource(DesktopCapturer::SourceId id) { - return id == kWindowId || id == kScreenId || id == kFullDesktopScreenId; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fake_desktop_capturer.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fake_desktop_capturer.h deleted file mode 100644 index 2aa000a17..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fake_desktop_capturer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_FAKE_DESKTOP_CAPTURER_H_ -#define MODULES_DESKTOP_CAPTURE_FAKE_DESKTOP_CAPTURER_H_ - -#include - -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame_generator.h" -#include "modules/desktop_capture/shared_memory.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// A fake implementation of DesktopCapturer or its derived interfaces to -// generate DesktopFrame for testing purpose. -// -// Consumers can provide a FrameGenerator instance to generate instances of -// DesktopFrame to return for each Capture() function call. -// If no FrameGenerator provided, FakeDesktopCapturer will always return a -// nullptr DesktopFrame. -// -// Double buffering is guaranteed by the FrameGenerator. FrameGenerator -// implements in desktop_frame_generator.h guarantee double buffering, they -// creates a new instance of DesktopFrame each time. -class RTC_EXPORT FakeDesktopCapturer : public DesktopCapturer { - public: - FakeDesktopCapturer(); - ~FakeDesktopCapturer() override; - - // Decides the result which will be returned in next Capture() callback. - void set_result(DesktopCapturer::Result result); - - // Uses the |generator| provided as DesktopFrameGenerator, FakeDesktopCapturer - // does not take the ownership of |generator|. - void set_frame_generator(DesktopFrameGenerator* generator); - - // Count of DesktopFrame(s) have been returned by this instance. This field - // would never be negative. - int num_frames_captured() const; - - // Count of CaptureFrame() calls have been made. This field would never be - // negative. - int num_capture_attempts() const; - - // DesktopCapturer interface - void Start(DesktopCapturer::Callback* callback) override; - void CaptureFrame() override; - void SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) override; - bool GetSourceList(DesktopCapturer::SourceList* sources) override; - bool SelectSource(DesktopCapturer::SourceId id) override; - - private: - static constexpr DesktopCapturer::SourceId kWindowId = 1378277495; - static constexpr DesktopCapturer::SourceId kScreenId = 1378277496; - - DesktopCapturer::Callback* callback_ = nullptr; - std::unique_ptr shared_memory_factory_; - DesktopCapturer::Result result_ = Result::SUCCESS; - DesktopFrameGenerator* generator_ = nullptr; - int num_frames_captured_ = 0; - int num_capture_attempts_ = 0; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_FAKE_DESKTOP_CAPTURER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.cc deleted file mode 100644 index 206791ca7..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.cc +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/fallback_desktop_capturer_wrapper.h" - -#include - -#include - -#include "rtc_base/checks.h" -#include "rtc_base/thread_checker.h" -#include "system_wrappers/include/metrics.h" - -namespace webrtc { - -namespace { - -// Implementation to share a SharedMemoryFactory between DesktopCapturer -// instances. This class is designed for synchronized DesktopCapturer -// implementations only. -class SharedMemoryFactoryProxy : public SharedMemoryFactory { - public: - // Users should maintain the lifetime of |factory| to ensure it overlives - // current instance. - static std::unique_ptr Create( - SharedMemoryFactory* factory); - ~SharedMemoryFactoryProxy() override; - - // Forwards CreateSharedMemory() calls to |factory_|. Users should always call - // this function in one thread. Users should not call this function after the - // SharedMemoryFactory which current instance created from has been destroyed. - std::unique_ptr CreateSharedMemory(size_t size) override; - - private: - explicit SharedMemoryFactoryProxy(SharedMemoryFactory* factory); - - SharedMemoryFactory* factory_ = nullptr; - rtc::ThreadChecker thread_checker_; -}; - -} // namespace - -SharedMemoryFactoryProxy::SharedMemoryFactoryProxy( - SharedMemoryFactory* factory) { - RTC_DCHECK(factory); - factory_ = factory; -} - -// static -std::unique_ptr SharedMemoryFactoryProxy::Create( - SharedMemoryFactory* factory) { - return std::unique_ptr( - new SharedMemoryFactoryProxy(factory)); -} - -SharedMemoryFactoryProxy::~SharedMemoryFactoryProxy() = default; - -std::unique_ptr SharedMemoryFactoryProxy::CreateSharedMemory( - size_t size) { - RTC_DCHECK(thread_checker_.IsCurrent()); - return factory_->CreateSharedMemory(size); -} - -FallbackDesktopCapturerWrapper::FallbackDesktopCapturerWrapper( - std::unique_ptr main_capturer, - std::unique_ptr secondary_capturer) - : main_capturer_(std::move(main_capturer)), - secondary_capturer_(std::move(secondary_capturer)) { - RTC_DCHECK(main_capturer_); - RTC_DCHECK(secondary_capturer_); -} - -FallbackDesktopCapturerWrapper::~FallbackDesktopCapturerWrapper() = default; - -void FallbackDesktopCapturerWrapper::Start( - DesktopCapturer::Callback* callback) { - callback_ = callback; - // FallbackDesktopCapturerWrapper catchs the callback of the main capturer, - // and checks its return value to decide whether the secondary capturer should - // be involved. - main_capturer_->Start(this); - // For the secondary capturer, we do not have a backup plan anymore, so - // FallbackDesktopCapturerWrapper won't check its return value any more. It - // will directly return to the input |callback|. - secondary_capturer_->Start(callback); -} - -void FallbackDesktopCapturerWrapper::SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) { - shared_memory_factory_ = std::move(shared_memory_factory); - if (shared_memory_factory_) { - main_capturer_->SetSharedMemoryFactory( - SharedMemoryFactoryProxy::Create(shared_memory_factory_.get())); - secondary_capturer_->SetSharedMemoryFactory( - SharedMemoryFactoryProxy::Create(shared_memory_factory_.get())); - } else { - main_capturer_->SetSharedMemoryFactory( - std::unique_ptr()); - secondary_capturer_->SetSharedMemoryFactory( - std::unique_ptr()); - } -} - -void FallbackDesktopCapturerWrapper::CaptureFrame() { - RTC_DCHECK(callback_); - if (main_capturer_permanent_error_) { - secondary_capturer_->CaptureFrame(); - } else { - main_capturer_->CaptureFrame(); - } -} - -void FallbackDesktopCapturerWrapper::SetExcludedWindow(WindowId window) { - main_capturer_->SetExcludedWindow(window); - secondary_capturer_->SetExcludedWindow(window); -} - -bool FallbackDesktopCapturerWrapper::GetSourceList(SourceList* sources) { - if (main_capturer_permanent_error_) { - return secondary_capturer_->GetSourceList(sources); - } - return main_capturer_->GetSourceList(sources); -} - -bool FallbackDesktopCapturerWrapper::SelectSource(SourceId id) { - if (main_capturer_permanent_error_) { - return secondary_capturer_->SelectSource(id); - } - const bool main_capturer_result = main_capturer_->SelectSource(id); - RTC_HISTOGRAM_BOOLEAN( - "WebRTC.DesktopCapture.PrimaryCapturerSelectSourceError", - main_capturer_result); - if (!main_capturer_result) { - main_capturer_permanent_error_ = true; - } - - return secondary_capturer_->SelectSource(id); -} - -bool FallbackDesktopCapturerWrapper::FocusOnSelectedSource() { - if (main_capturer_permanent_error_) { - return secondary_capturer_->FocusOnSelectedSource(); - } - return main_capturer_->FocusOnSelectedSource() || - secondary_capturer_->FocusOnSelectedSource(); -} - -bool FallbackDesktopCapturerWrapper::IsOccluded(const DesktopVector& pos) { - // Returns true if either capturer returns true. - if (main_capturer_permanent_error_) { - return secondary_capturer_->IsOccluded(pos); - } - return main_capturer_->IsOccluded(pos) || - secondary_capturer_->IsOccluded(pos); -} - -void FallbackDesktopCapturerWrapper::OnCaptureResult( - Result result, - std::unique_ptr frame) { - RTC_DCHECK(callback_); - RTC_HISTOGRAM_BOOLEAN("WebRTC.DesktopCapture.PrimaryCapturerError", - result != Result::SUCCESS); - RTC_HISTOGRAM_BOOLEAN("WebRTC.DesktopCapture.PrimaryCapturerPermanentError", - result == Result::ERROR_PERMANENT); - if (result == Result::SUCCESS) { - callback_->OnCaptureResult(result, std::move(frame)); - return; - } - - if (result == Result::ERROR_PERMANENT) { - main_capturer_permanent_error_ = true; - } - secondary_capturer_->CaptureFrame(); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.h deleted file mode 100644 index 2855eae7e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_FALLBACK_DESKTOP_CAPTURER_WRAPPER_H_ -#define MODULES_DESKTOP_CAPTURE_FALLBACK_DESKTOP_CAPTURER_WRAPPER_H_ - -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/shared_memory.h" - -namespace webrtc { - -// A DesktopCapturer wrapper owns two DesktopCapturer implementations. If the -// main DesktopCapturer fails, it uses the secondary one instead. Two capturers -// are expected to return same SourceList, and the meaning of each SourceId is -// identical, otherwise FallbackDesktopCapturerWrapper may return frames from -// different sources. Using asynchronized DesktopCapturer implementations with -// SharedMemoryFactory is not supported, and may result crash or assertion -// failure. -class FallbackDesktopCapturerWrapper final : public DesktopCapturer, - public DesktopCapturer::Callback { - public: - FallbackDesktopCapturerWrapper( - std::unique_ptr main_capturer, - std::unique_ptr secondary_capturer); - ~FallbackDesktopCapturerWrapper() override; - - // DesktopCapturer interface. - void Start(DesktopCapturer::Callback* callback) override; - void SetSharedMemoryFactory( - std::unique_ptr shared_memory_factory) override; - void CaptureFrame() override; - void SetExcludedWindow(WindowId window) override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - bool FocusOnSelectedSource() override; - bool IsOccluded(const DesktopVector& pos) override; - - private: - // DesktopCapturer::Callback interface. - void OnCaptureResult(Result result, - std::unique_ptr frame) override; - - const std::unique_ptr main_capturer_; - const std::unique_ptr secondary_capturer_; - std::unique_ptr shared_memory_factory_; - bool main_capturer_permanent_error_ = false; - DesktopCapturer::Callback* callback_ = nullptr; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_FALLBACK_DESKTOP_CAPTURER_WRAPPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_application_handler.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_application_handler.cc deleted file mode 100644 index e0975570b..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_application_handler.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2019 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/desktop_capture/full_screen_application_handler.h" -#include "rtc_base/logging.h" - -namespace webrtc { - -FullScreenApplicationHandler::FullScreenApplicationHandler( - DesktopCapturer::SourceId sourceId) - : source_id_(sourceId) {} - -DesktopCapturer::SourceId FullScreenApplicationHandler::FindFullScreenWindow( - const DesktopCapturer::SourceList&, - int64_t) const { - return 0; -} - -DesktopCapturer::SourceId FullScreenApplicationHandler::GetSourceId() const { - return source_id_; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_application_handler.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_application_handler.h deleted file mode 100644 index 849cb2c76..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_application_handler.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_FULL_SCREEN_APPLICATION_HANDLER_H_ -#define MODULES_DESKTOP_CAPTURE_FULL_SCREEN_APPLICATION_HANDLER_H_ - -#include -#include "modules/desktop_capture/desktop_capturer.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -// Base class for application specific handler to check criteria for switch to -// full-screen mode and find if possible the full-screen window to share. -// Supposed to be created and owned by platform specific -// FullScreenWindowDetector. -class FullScreenApplicationHandler { - public: - virtual ~FullScreenApplicationHandler() {} - - explicit FullScreenApplicationHandler(DesktopCapturer::SourceId sourceId); - - // Returns the full-screen window in place of the original window if all the - // criteria are met, or 0 if no such window found. - virtual DesktopCapturer::SourceId FindFullScreenWindow( - const DesktopCapturer::SourceList& window_list, - int64_t timestamp) const; - - // Returns source id of original window associated with - // FullScreenApplicationHandler - DesktopCapturer::SourceId GetSourceId() const; - - private: - const DesktopCapturer::SourceId source_id_; - - RTC_DISALLOW_COPY_AND_ASSIGN(FullScreenApplicationHandler); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_FULL_SCREEN_APPLICATION_HANDLER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_window_detector.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_window_detector.cc deleted file mode 100644 index d0bc9c7ca..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_window_detector.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2019 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/desktop_capture/full_screen_window_detector.h" -#include "modules/desktop_capture/full_screen_application_handler.h" -#include "rtc_base/time_utils.h" - -namespace webrtc { - -FullScreenWindowDetector::FullScreenWindowDetector( - ApplicationHandlerFactory application_handler_factory) - : application_handler_factory_(application_handler_factory), - last_update_time_ms_(0), - previous_source_id_(0), - no_handler_source_id_(0) {} - -DesktopCapturer::SourceId FullScreenWindowDetector::FindFullScreenWindow( - DesktopCapturer::SourceId original_source_id) { - if (app_handler_ == nullptr || - app_handler_->GetSourceId() != original_source_id) { - return 0; - } - return app_handler_->FindFullScreenWindow(window_list_, last_update_time_ms_); -} - -void FullScreenWindowDetector::UpdateWindowListIfNeeded( - DesktopCapturer::SourceId original_source_id, - rtc::FunctionView get_sources) { - const bool skip_update = previous_source_id_ != original_source_id; - previous_source_id_ = original_source_id; - - // Here is an attempt to avoid redundant creating application handler in case - // when an instance of WindowCapturer is used to generate a thumbnail to show - // in picker by calling SelectSource and CaptureFrame for every available - // source. - if (skip_update) { - return; - } - - CreateApplicationHandlerIfNeeded(original_source_id); - if (app_handler_ == nullptr) { - // There is no FullScreenApplicationHandler specific for - // current application - return; - } - - constexpr int64_t kUpdateIntervalMs = 500; - - if ((rtc::TimeMillis() - last_update_time_ms_) <= kUpdateIntervalMs) { - return; - } - - DesktopCapturer::SourceList window_list; - if (get_sources(&window_list)) { - last_update_time_ms_ = rtc::TimeMillis(); - window_list_.swap(window_list); - } -} - -void FullScreenWindowDetector::CreateApplicationHandlerIfNeeded( - DesktopCapturer::SourceId source_id) { - if (no_handler_source_id_ == source_id) { - return; - } - - if (app_handler_ == nullptr || app_handler_->GetSourceId() != source_id) { - app_handler_ = application_handler_factory_ - ? application_handler_factory_(source_id) - : nullptr; - } - - if (app_handler_ == nullptr) { - no_handler_source_id_ = source_id; - } -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_window_detector.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_window_detector.h deleted file mode 100644 index 46fb607b7..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/full_screen_window_detector.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2014 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_FULL_SCREEN_WINDOW_DETECTOR_H_ -#define MODULES_DESKTOP_CAPTURE_FULL_SCREEN_WINDOW_DETECTOR_H_ - -#include -#include "api/function_view.h" -#include "api/ref_counted_base.h" -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/full_screen_application_handler.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -// This is a way to handle switch to full-screen mode for application in some -// specific cases: -// - Chrome on MacOS creates a new window in full-screen mode to -// show a tab full-screen and minimizes the old window. -// - PowerPoint creates new windows in full-screen mode when user goes to -// presentation mode (Slide Show Window, Presentation Window). -// -// To continue capturing in these cases, we try to find the new full-screen -// window using criteria provided by application specific -// FullScreenApplicationHandler. - -class FullScreenWindowDetector : public rtc::RefCountedBase { - public: - using ApplicationHandlerFactory = - std::function( - DesktopCapturer::SourceId sourceId)>; - - FullScreenWindowDetector( - ApplicationHandlerFactory application_handler_factory); - - // Returns the full-screen window in place of the original window if all the - // criteria provided by FullScreenApplicationHandler are met, or 0 if no such - // window found. - DesktopCapturer::SourceId FindFullScreenWindow( - DesktopCapturer::SourceId original_source_id); - - // The caller should call this function periodically, implementation will - // update internal state no often than twice per second - void UpdateWindowListIfNeeded( - DesktopCapturer::SourceId original_source_id, - rtc::FunctionView get_sources); - - static rtc::scoped_refptr - CreateFullScreenWindowDetector(); - - protected: - std::unique_ptr app_handler_; - - private: - void CreateApplicationHandlerIfNeeded(DesktopCapturer::SourceId source_id); - - ApplicationHandlerFactory application_handler_factory_; - - int64_t last_update_time_ms_; - DesktopCapturer::SourceId previous_source_id_; - - // Save the source id when we fail to create an instance of - // CreateApplicationHandlerIfNeeded to avoid redundant attempt to do it again. - DesktopCapturer::SourceId no_handler_source_id_; - - DesktopCapturer::SourceList window_list_; - RTC_DISALLOW_COPY_AND_ASSIGN(FullScreenWindowDetector); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_FULL_SCREEN_WINDOW_DETECTOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc deleted file mode 100644 index 2640e93aa..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc +++ /dev/null @@ -1,890 +0,0 @@ -/* - * Copyright 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 "modules/desktop_capture/linux/base_capturer_pipewire.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "absl/memory/memory.h" -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -#if defined(WEBRTC_DLOPEN_PIPEWIRE) -#include "modules/desktop_capture/linux/pipewire_stubs.h" - -using modules_desktop_capture_linux::InitializeStubs; -using modules_desktop_capture_linux::kModulePipewire; -using modules_desktop_capture_linux::StubPathMap; -#endif // defined(WEBRTC_DLOPEN_PIPEWIRE) - -namespace webrtc { - -const char kDesktopBusName[] = "org.freedesktop.portal.Desktop"; -const char kDesktopObjectPath[] = "/org/freedesktop/portal/desktop"; -const char kDesktopRequestObjectPath[] = - "/org/freedesktop/portal/desktop/request"; -const char kSessionInterfaceName[] = "org.freedesktop.portal.Session"; -const char kRequestInterfaceName[] = "org.freedesktop.portal.Request"; -const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast"; - -const int kBytesPerPixel = 4; - -#if defined(WEBRTC_DLOPEN_PIPEWIRE) -const char kPipeWireLib[] = "libpipewire-0.2.so.1"; -#endif - -// static -void BaseCapturerPipeWire::OnStateChanged(void* data, - pw_remote_state old_state, - pw_remote_state state, - const char* error_message) { - BaseCapturerPipeWire* that = static_cast(data); - RTC_DCHECK(that); - - switch (state) { - case PW_REMOTE_STATE_ERROR: - RTC_LOG(LS_ERROR) << "PipeWire remote state error: " << error_message; - break; - case PW_REMOTE_STATE_CONNECTED: - RTC_LOG(LS_INFO) << "PipeWire remote state: connected."; - that->CreateReceivingStream(); - break; - case PW_REMOTE_STATE_CONNECTING: - RTC_LOG(LS_INFO) << "PipeWire remote state: connecting."; - break; - case PW_REMOTE_STATE_UNCONNECTED: - RTC_LOG(LS_INFO) << "PipeWire remote state: unconnected."; - break; - } -} - -// static -void BaseCapturerPipeWire::OnStreamStateChanged(void* data, - pw_stream_state old_state, - pw_stream_state state, - const char* error_message) { - BaseCapturerPipeWire* that = static_cast(data); - RTC_DCHECK(that); - - switch (state) { - case PW_STREAM_STATE_ERROR: - RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message; - break; - case PW_STREAM_STATE_CONFIGURE: - pw_stream_set_active(that->pw_stream_, true); - break; - case PW_STREAM_STATE_UNCONNECTED: - case PW_STREAM_STATE_CONNECTING: - case PW_STREAM_STATE_READY: - case PW_STREAM_STATE_PAUSED: - case PW_STREAM_STATE_STREAMING: - break; - } -} - -// static -void BaseCapturerPipeWire::OnStreamFormatChanged(void* data, - const struct spa_pod* format) { - BaseCapturerPipeWire* that = static_cast(data); - RTC_DCHECK(that); - - RTC_LOG(LS_INFO) << "PipeWire stream format changed."; - - if (!format) { - pw_stream_finish_format(that->pw_stream_, /*res=*/0, /*params=*/nullptr, - /*n_params=*/0); - return; - } - - that->spa_video_format_ = new spa_video_info_raw(); - spa_format_video_raw_parse(format, that->spa_video_format_, - &that->pw_type_->format_video); - - auto width = that->spa_video_format_->size.width; - auto height = that->spa_video_format_->size.height; - auto stride = SPA_ROUND_UP_N(width * kBytesPerPixel, 4); - auto size = height * stride; - - uint8_t buffer[1024] = {}; - auto builder = spa_pod_builder{buffer, sizeof(buffer)}; - - // Setup buffers and meta header for new format. - const struct spa_pod* params[2]; - params[0] = reinterpret_cast(spa_pod_builder_object( - &builder, - // id to enumerate buffer requirements - that->pw_core_type_->param.idBuffers, - that->pw_core_type_->param_buffers.Buffers, - // Size: specified as integer (i) and set to specified size - ":", that->pw_core_type_->param_buffers.size, "i", size, - // Stride: specified as integer (i) and set to specified stride - ":", that->pw_core_type_->param_buffers.stride, "i", stride, - // Buffers: specifies how many buffers we want to deal with, set as - // integer (i) where preferred number is 8, then allowed number is defined - // as range (r) from min and max values and it is undecided (u) to allow - // negotiation - ":", that->pw_core_type_->param_buffers.buffers, "iru", 8, - SPA_POD_PROP_MIN_MAX(1, 32), - // Align: memory alignment of the buffer, set as integer (i) to specified - // value - ":", that->pw_core_type_->param_buffers.align, "i", 16)); - params[1] = reinterpret_cast(spa_pod_builder_object( - &builder, - // id to enumerate supported metadata - that->pw_core_type_->param.idMeta, that->pw_core_type_->param_meta.Meta, - // Type: specified as id or enum (I) - ":", that->pw_core_type_->param_meta.type, "I", - that->pw_core_type_->meta.Header, - // Size: size of the metadata, specified as integer (i) - ":", that->pw_core_type_->param_meta.size, "i", - sizeof(struct spa_meta_header))); - - pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/2); -} - -// static -void BaseCapturerPipeWire::OnStreamProcess(void* data) { - BaseCapturerPipeWire* that = static_cast(data); - RTC_DCHECK(that); - - pw_buffer* buf = nullptr; - - if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) { - return; - } - - that->HandleBuffer(buf); - - pw_stream_queue_buffer(that->pw_stream_, buf); -} - -BaseCapturerPipeWire::BaseCapturerPipeWire(CaptureSourceType source_type) - : capture_source_type_(source_type) {} - -BaseCapturerPipeWire::~BaseCapturerPipeWire() { - if (pw_main_loop_) { - pw_thread_loop_stop(pw_main_loop_); - } - - if (pw_type_) { - delete pw_type_; - } - - if (spa_video_format_) { - delete spa_video_format_; - } - - if (pw_stream_) { - pw_stream_destroy(pw_stream_); - } - - if (pw_remote_) { - pw_remote_destroy(pw_remote_); - } - - if (pw_core_) { - pw_core_destroy(pw_core_); - } - - if (pw_main_loop_) { - pw_thread_loop_destroy(pw_main_loop_); - } - - if (pw_loop_) { - pw_loop_destroy(pw_loop_); - } - - if (current_frame_) { - free(current_frame_); - } - - if (start_request_signal_id_) { - g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_); - } - if (sources_request_signal_id_) { - g_dbus_connection_signal_unsubscribe(connection_, - sources_request_signal_id_); - } - if (session_request_signal_id_) { - g_dbus_connection_signal_unsubscribe(connection_, - session_request_signal_id_); - } - - if (session_handle_) { - GDBusMessage* message = g_dbus_message_new_method_call( - kDesktopBusName, session_handle_, kSessionInterfaceName, "Close"); - if (message) { - GError* error = nullptr; - g_dbus_connection_send_message(connection_, message, - G_DBUS_SEND_MESSAGE_FLAGS_NONE, - /*out_serial=*/nullptr, &error); - if (error) { - RTC_LOG(LS_ERROR) << "Failed to close the session: " << error->message; - g_error_free(error); - } - g_object_unref(message); - } - } - - g_free(start_handle_); - g_free(sources_handle_); - g_free(session_handle_); - g_free(portal_handle_); - - if (cancellable_) { - g_cancellable_cancel(cancellable_); - g_object_unref(cancellable_); - cancellable_ = nullptr; - } - - if (proxy_) { - g_object_unref(proxy_); - proxy_ = nullptr; - } -} - -void BaseCapturerPipeWire::InitPortal() { - cancellable_ = g_cancellable_new(); - g_dbus_proxy_new_for_bus( - G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, /*info=*/nullptr, - kDesktopBusName, kDesktopObjectPath, kScreenCastInterfaceName, - cancellable_, - reinterpret_cast(OnProxyRequested), this); -} - -void BaseCapturerPipeWire::InitPipeWire() { -#if defined(WEBRTC_DLOPEN_PIPEWIRE) - StubPathMap paths; - - // Check if the PipeWire library is available. - paths[kModulePipewire].push_back(kPipeWireLib); - if (!InitializeStubs(paths)) { - RTC_LOG(LS_ERROR) << "Failed to load the PipeWire library and symbols."; - portal_init_failed_ = true; - return; - } -#endif // defined(WEBRTC_DLOPEN_PIPEWIRE) - - pw_init(/*argc=*/nullptr, /*argc=*/nullptr); - - pw_loop_ = pw_loop_new(/*properties=*/nullptr); - pw_main_loop_ = pw_thread_loop_new(pw_loop_, "pipewire-main-loop"); - - pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr); - pw_core_type_ = pw_core_get_type(pw_core_); - pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0); - - InitPipeWireTypes(); - - // Initialize event handlers, remote end and stream-related. - pw_remote_events_.version = PW_VERSION_REMOTE_EVENTS; - pw_remote_events_.state_changed = &OnStateChanged; - - pw_stream_events_.version = PW_VERSION_STREAM_EVENTS; - pw_stream_events_.state_changed = &OnStreamStateChanged; - pw_stream_events_.format_changed = &OnStreamFormatChanged; - pw_stream_events_.process = &OnStreamProcess; - - pw_remote_add_listener(pw_remote_, &spa_remote_listener_, &pw_remote_events_, - this); - pw_remote_connect_fd(pw_remote_, pw_fd_); - - if (pw_thread_loop_start(pw_main_loop_) < 0) { - RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop"; - portal_init_failed_ = true; - } - - RTC_LOG(LS_INFO) << "PipeWire remote opened."; -} - -void BaseCapturerPipeWire::InitPipeWireTypes() { - spa_type_map* map = pw_core_type_->map; - pw_type_ = new PipeWireType(); - - spa_type_media_type_map(map, &pw_type_->media_type); - spa_type_media_subtype_map(map, &pw_type_->media_subtype); - spa_type_format_video_map(map, &pw_type_->format_video); - spa_type_video_format_map(map, &pw_type_->video_format); -} - -void BaseCapturerPipeWire::CreateReceivingStream() { - spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1}; - spa_rectangle pwScreenBounds = - spa_rectangle{static_cast(desktop_size_.width()), - static_cast(desktop_size_.height())}; - - spa_fraction pwFrameRateMin = spa_fraction{0, 1}; - spa_fraction pwFrameRateMax = spa_fraction{60, 1}; - - pw_properties* reuseProps = - pw_properties_new_string("pipewire.client.reuse=1"); - pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps); - - uint8_t buffer[1024] = {}; - const spa_pod* params[1]; - spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)}; - params[0] = reinterpret_cast(spa_pod_builder_object( - &builder, - // id to enumerate formats - pw_core_type_->param.idEnumFormat, pw_core_type_->spa_format, "I", - pw_type_->media_type.video, "I", pw_type_->media_subtype.raw, - // Video format: specified as id or enum (I), preferred format is BGRx, - // then allowed formats are enumerated (e) and the format is undecided (u) - // to allow negotiation - ":", pw_type_->format_video.format, "Ieu", pw_type_->video_format.BGRx, - SPA_POD_PROP_ENUM(2, pw_type_->video_format.RGBx, - pw_type_->video_format.BGRx), - // Video size: specified as rectangle (R), preferred size is specified as - // first parameter, then allowed size is defined as range (r) from min and - // max values and the format is undecided (u) to allow negotiation - ":", pw_type_->format_video.size, "Rru", &pwScreenBounds, 2, - &pwMinScreenBounds, &pwScreenBounds, - // Frame rate: specified as fraction (F) and set to minimum frame rate - // value - ":", pw_type_->format_video.framerate, "F", &pwFrameRateMin, - // Max frame rate: specified as fraction (F), preferred frame rate is set - // to maximum value, then allowed frame rate is defined as range (r) from - // min and max values and it is undecided (u) to allow negotiation - ":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2, - &pwFrameRateMin, &pwFrameRateMax)); - - pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_, - this); - pw_stream_flags flags = static_cast( - PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE | - PW_STREAM_FLAG_MAP_BUFFERS); - if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr, - flags, params, - /*n_params=*/1) != 0) { - RTC_LOG(LS_ERROR) << "Could not connect receiving stream."; - portal_init_failed_ = true; - return; - } -} - -void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) { - spa_buffer* spaBuffer = buffer->buffer; - void* src = nullptr; - - if (!(src = spaBuffer->datas[0].data)) { - return; - } - - uint32_t maxSize = spaBuffer->datas[0].maxsize; - int32_t srcStride = spaBuffer->datas[0].chunk->stride; - if (srcStride != (desktop_size_.width() * kBytesPerPixel)) { - RTC_LOG(LS_ERROR) << "Got buffer with stride different from screen stride: " - << srcStride - << " != " << (desktop_size_.width() * kBytesPerPixel); - portal_init_failed_ = true; - return; - } - - if (!current_frame_) { - current_frame_ = static_cast(malloc(maxSize)); - } - RTC_DCHECK(current_frame_ != nullptr); - - // If both sides decided to go with the RGBx format we need to convert it to - // BGRx to match color format expected by WebRTC. - if (spa_video_format_->format == pw_type_->video_format.RGBx) { - uint8_t* tempFrame = static_cast(malloc(maxSize)); - std::memcpy(tempFrame, src, maxSize); - ConvertRGBxToBGRx(tempFrame, maxSize); - std::memcpy(current_frame_, tempFrame, maxSize); - free(tempFrame); - } else { - std::memcpy(current_frame_, src, maxSize); - } -} - -void BaseCapturerPipeWire::ConvertRGBxToBGRx(uint8_t* frame, uint32_t size) { - // Change color format for KDE KWin which uses RGBx and not BGRx - for (uint32_t i = 0; i < size; i += 4) { - uint8_t tempR = frame[i]; - uint8_t tempB = frame[i + 2]; - frame[i] = tempB; - frame[i + 2] = tempR; - } -} - -guint BaseCapturerPipeWire::SetupRequestResponseSignal( - const gchar* object_path, - GDBusSignalCallback callback) { - return g_dbus_connection_signal_subscribe( - connection_, kDesktopBusName, kRequestInterfaceName, "Response", - object_path, /*arg0=*/nullptr, G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, - callback, this, /*user_data_free_func=*/nullptr); -} - -// static -void BaseCapturerPipeWire::OnProxyRequested(GObject* /*object*/, - GAsyncResult* result, - gpointer user_data) { - BaseCapturerPipeWire* that = static_cast(user_data); - RTC_DCHECK(that); - - GError* error = nullptr; - GDBusProxy *proxy = g_dbus_proxy_new_finish(result, &error); - if (!proxy) { - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - RTC_LOG(LS_ERROR) << "Failed to create a proxy for the screen cast portal: " - << error->message; - g_error_free(error); - that->portal_init_failed_ = true; - return; - } - that->proxy_ = proxy; - that->connection_ = g_dbus_proxy_get_connection(that->proxy_); - - RTC_LOG(LS_INFO) << "Created proxy for the screen cast portal."; - that->SessionRequest(); -} - -// static -gchar* BaseCapturerPipeWire::PrepareSignalHandle(GDBusConnection* connection, - const gchar* token) { - gchar* sender = g_strdup(g_dbus_connection_get_unique_name(connection) + 1); - for (int i = 0; sender[i]; i++) { - if (sender[i] == '.') { - sender[i] = '_'; - } - } - - gchar* handle = g_strconcat(kDesktopRequestObjectPath, "/", sender, "/", - token, /*end of varargs*/ nullptr); - g_free(sender); - - return handle; -} - -void BaseCapturerPipeWire::SessionRequest() { - GVariantBuilder builder; - gchar* variant_string; - - g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); - variant_string = - g_strdup_printf("webrtc_session%d", g_random_int_range(0, G_MAXINT)); - g_variant_builder_add(&builder, "{sv}", "session_handle_token", - g_variant_new_string(variant_string)); - g_free(variant_string); - variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); - g_variant_builder_add(&builder, "{sv}", "handle_token", - g_variant_new_string(variant_string)); - - portal_handle_ = PrepareSignalHandle(connection_, variant_string); - session_request_signal_id_ = SetupRequestResponseSignal( - portal_handle_, OnSessionRequestResponseSignal); - g_free(variant_string); - - RTC_LOG(LS_INFO) << "Screen cast session requested."; - g_dbus_proxy_call( - proxy_, "CreateSession", g_variant_new("(a{sv})", &builder), - G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, - reinterpret_cast(OnSessionRequested), this); -} - -// static -void BaseCapturerPipeWire::OnSessionRequested(GDBusProxy *proxy, - GAsyncResult* result, - gpointer user_data) { - BaseCapturerPipeWire* that = static_cast(user_data); - RTC_DCHECK(that); - - GError* error = nullptr; - GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error); - if (!variant) { - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - RTC_LOG(LS_ERROR) << "Failed to create a screen cast session: " - << error->message; - g_error_free(error); - that->portal_init_failed_ = true; - return; - } - RTC_LOG(LS_INFO) << "Initializing the screen cast session."; - - gchar* handle = nullptr; - g_variant_get_child(variant, 0, "o", &handle); - g_variant_unref(variant); - if (!handle) { - RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session."; - if (that->session_request_signal_id_) { - g_dbus_connection_signal_unsubscribe(that->connection_, - that->session_request_signal_id_); - that->session_request_signal_id_ = 0; - } - that->portal_init_failed_ = true; - return; - } - - g_free(handle); - - RTC_LOG(LS_INFO) << "Subscribing to the screen cast session."; -} - -// static -void BaseCapturerPipeWire::OnSessionRequestResponseSignal( - GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data) { - BaseCapturerPipeWire* that = static_cast(user_data); - RTC_DCHECK(that); - - RTC_LOG(LS_INFO) - << "Received response for the screen cast session subscription."; - - guint32 portal_response; - GVariant* response_data; - g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data); - g_variant_lookup(response_data, "session_handle", "s", - &that->session_handle_); - g_variant_unref(response_data); - - if (!that->session_handle_ || portal_response) { - RTC_LOG(LS_ERROR) - << "Failed to request the screen cast session subscription."; - that->portal_init_failed_ = true; - return; - } - - that->SourcesRequest(); -} - -void BaseCapturerPipeWire::SourcesRequest() { - GVariantBuilder builder; - gchar* variant_string; - - g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); - // We want to record monitor content. - g_variant_builder_add(&builder, "{sv}", "types", - g_variant_new_uint32(capture_source_type_)); - // We don't want to allow selection of multiple sources. - g_variant_builder_add(&builder, "{sv}", "multiple", - g_variant_new_boolean(false)); - variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); - g_variant_builder_add(&builder, "{sv}", "handle_token", - g_variant_new_string(variant_string)); - - sources_handle_ = PrepareSignalHandle(connection_, variant_string); - sources_request_signal_id_ = SetupRequestResponseSignal( - sources_handle_, OnSourcesRequestResponseSignal); - g_free(variant_string); - - RTC_LOG(LS_INFO) << "Requesting sources from the screen cast session."; - g_dbus_proxy_call( - proxy_, "SelectSources", - g_variant_new("(oa{sv})", session_handle_, &builder), - G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, - reinterpret_cast(OnSourcesRequested), this); -} - -// static -void BaseCapturerPipeWire::OnSourcesRequested(GDBusProxy *proxy, - GAsyncResult* result, - gpointer user_data) { - BaseCapturerPipeWire* that = static_cast(user_data); - RTC_DCHECK(that); - - GError* error = nullptr; - GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error); - if (!variant) { - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - RTC_LOG(LS_ERROR) << "Failed to request the sources: " << error->message; - g_error_free(error); - that->portal_init_failed_ = true; - return; - } - - RTC_LOG(LS_INFO) << "Sources requested from the screen cast session."; - - gchar* handle = nullptr; - g_variant_get_child(variant, 0, "o", &handle); - g_variant_unref(variant); - if (!handle) { - RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session."; - if (that->sources_request_signal_id_) { - g_dbus_connection_signal_unsubscribe(that->connection_, - that->sources_request_signal_id_); - that->sources_request_signal_id_ = 0; - } - that->portal_init_failed_ = true; - return; - } - - g_free(handle); - - RTC_LOG(LS_INFO) << "Subscribed to sources signal."; -} - -// static -void BaseCapturerPipeWire::OnSourcesRequestResponseSignal( - GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data) { - BaseCapturerPipeWire* that = static_cast(user_data); - RTC_DCHECK(that); - - RTC_LOG(LS_INFO) << "Received sources signal from session."; - - guint32 portal_response; - g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); - if (portal_response) { - RTC_LOG(LS_ERROR) - << "Failed to select sources for the screen cast session."; - that->portal_init_failed_ = true; - return; - } - - that->StartRequest(); -} - -void BaseCapturerPipeWire::StartRequest() { - GVariantBuilder builder; - gchar* variant_string; - - g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); - variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); - g_variant_builder_add(&builder, "{sv}", "handle_token", - g_variant_new_string(variant_string)); - - start_handle_ = PrepareSignalHandle(connection_, variant_string); - start_request_signal_id_ = - SetupRequestResponseSignal(start_handle_, OnStartRequestResponseSignal); - g_free(variant_string); - - // "Identifier for the application window", this is Wayland, so not "x11:...". - const gchar parent_window[] = ""; - - RTC_LOG(LS_INFO) << "Starting the screen cast session."; - g_dbus_proxy_call( - proxy_, "Start", - g_variant_new("(osa{sv})", session_handle_, parent_window, &builder), - G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, - reinterpret_cast(OnStartRequested), this); -} - -// static -void BaseCapturerPipeWire::OnStartRequested(GDBusProxy *proxy, - GAsyncResult* result, - gpointer user_data) { - BaseCapturerPipeWire* that = static_cast(user_data); - RTC_DCHECK(that); - - GError* error = nullptr; - GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error); - if (!variant) { - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - RTC_LOG(LS_ERROR) << "Failed to start the screen cast session: " - << error->message; - g_error_free(error); - that->portal_init_failed_ = true; - return; - } - - RTC_LOG(LS_INFO) << "Initializing the start of the screen cast session."; - - gchar* handle = nullptr; - g_variant_get_child(variant, 0, "o", &handle); - g_variant_unref(variant); - if (!handle) { - RTC_LOG(LS_ERROR) - << "Failed to initialize the start of the screen cast session."; - if (that->start_request_signal_id_) { - g_dbus_connection_signal_unsubscribe(that->connection_, - that->start_request_signal_id_); - that->start_request_signal_id_ = 0; - } - that->portal_init_failed_ = true; - return; - } - - g_free(handle); - - RTC_LOG(LS_INFO) << "Subscribed to the start signal."; -} - -// static -void BaseCapturerPipeWire::OnStartRequestResponseSignal( - GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data) { - BaseCapturerPipeWire* that = static_cast(user_data); - RTC_DCHECK(that); - - RTC_LOG(LS_INFO) << "Start signal received."; - guint32 portal_response; - GVariant* response_data; - GVariantIter* iter = nullptr; - g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data); - if (portal_response || !response_data) { - RTC_LOG(LS_ERROR) << "Failed to start the screen cast session."; - that->portal_init_failed_ = true; - return; - } - - // Array of PipeWire streams. See - // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml - // documentation for . - if (g_variant_lookup(response_data, "streams", "a(ua{sv})", &iter)) { - GVariant* variant; - - while (g_variant_iter_next(iter, "@(ua{sv})", &variant)) { - guint32 stream_id; - gint32 width; - gint32 height; - GVariant* options; - - g_variant_get(variant, "(u@a{sv})", &stream_id, &options); - RTC_DCHECK(options != nullptr); - - g_variant_lookup(options, "size", "(ii)", &width, &height); - - that->desktop_size_.set(width, height); - - g_variant_unref(options); - g_variant_unref(variant); - } - } - g_variant_iter_free(iter); - g_variant_unref(response_data); - - that->OpenPipeWireRemote(); -} - -void BaseCapturerPipeWire::OpenPipeWireRemote() { - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); - - RTC_LOG(LS_INFO) << "Opening the PipeWire remote."; - - g_dbus_proxy_call_with_unix_fd_list( - proxy_, "OpenPipeWireRemote", - g_variant_new("(oa{sv})", session_handle_, &builder), - G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, /*fd_list=*/nullptr, - cancellable_, - reinterpret_cast(OnOpenPipeWireRemoteRequested), - this); -} - -// static -void BaseCapturerPipeWire::OnOpenPipeWireRemoteRequested( - GDBusProxy *proxy, - GAsyncResult* result, - gpointer user_data) { - BaseCapturerPipeWire* that = static_cast(user_data); - RTC_DCHECK(that); - - GError* error = nullptr; - GUnixFDList* outlist = nullptr; - GVariant* variant = g_dbus_proxy_call_with_unix_fd_list_finish( - proxy, &outlist, result, &error); - if (!variant) { - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - RTC_LOG(LS_ERROR) << "Failed to open the PipeWire remote: " - << error->message; - g_error_free(error); - that->portal_init_failed_ = true; - return; - } - - gint32 index; - g_variant_get(variant, "(h)", &index); - - if ((that->pw_fd_ = g_unix_fd_list_get(outlist, index, &error)) == -1) { - RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " - << error->message; - g_error_free(error); - g_variant_unref(variant); - that->portal_init_failed_ = true; - return; - } - - g_variant_unref(variant); - g_object_unref(outlist); - - that->InitPipeWire(); -} - -void BaseCapturerPipeWire::Start(Callback* callback) { - RTC_DCHECK(!callback_); - RTC_DCHECK(callback); - - InitPortal(); - - callback_ = callback; -} - -void BaseCapturerPipeWire::CaptureFrame() { - if (portal_init_failed_) { - callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); - return; - } - - if (!current_frame_) { - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); - return; - } - - std::unique_ptr result(new BasicDesktopFrame(desktop_size_)); - result->CopyPixelsFrom( - current_frame_, (desktop_size_.width() * kBytesPerPixel), - DesktopRect::MakeWH(desktop_size_.width(), desktop_size_.height())); - if (!result) { - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); - return; - } - - // TODO(julien.isorce): http://crbug.com/945468. Set the icc profile on the - // frame, see ScreenCapturerX11::CaptureFrame. - - callback_->OnCaptureResult(Result::SUCCESS, std::move(result)); -} - -bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) { - RTC_DCHECK(sources->size() == 0); - // List of available screens is already presented by the xdg-desktop-portal. - // But we have to add an empty source as the code expects it. - sources->push_back({0}); - return true; -} - -bool BaseCapturerPipeWire::SelectSource(SourceId id) { - // Screen selection is handled by the xdg-desktop-portal. - return true; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h deleted file mode 100644 index f28d7a558..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_ - -#include -#define typeof __typeof__ -#include -#include - -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -class PipeWireType { - public: - spa_type_media_type media_type; - spa_type_media_subtype media_subtype; - spa_type_format_video format_video; - spa_type_video_format video_format; -}; - -class BaseCapturerPipeWire : public DesktopCapturer { - public: - enum CaptureSourceType { Screen = 1, Window }; - - explicit BaseCapturerPipeWire(CaptureSourceType source_type); - ~BaseCapturerPipeWire() override; - - // DesktopCapturer interface. - void Start(Callback* delegate) override; - void CaptureFrame() override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - - private: - // PipeWire types --> - pw_core* pw_core_ = nullptr; - pw_type* pw_core_type_ = nullptr; - pw_stream* pw_stream_ = nullptr; - pw_remote* pw_remote_ = nullptr; - pw_loop* pw_loop_ = nullptr; - pw_thread_loop* pw_main_loop_ = nullptr; - PipeWireType* pw_type_ = nullptr; - - spa_hook spa_stream_listener_ = {}; - spa_hook spa_remote_listener_ = {}; - - pw_stream_events pw_stream_events_ = {}; - pw_remote_events pw_remote_events_ = {}; - - spa_video_info_raw* spa_video_format_ = nullptr; - - gint32 pw_fd_ = -1; - - CaptureSourceType capture_source_type_ = - BaseCapturerPipeWire::CaptureSourceType::Screen; - - // <-- end of PipeWire types - - GDBusConnection* connection_ = nullptr; - GDBusProxy* proxy_ = nullptr; - GCancellable *cancellable_ = nullptr; - gchar* portal_handle_ = nullptr; - gchar* session_handle_ = nullptr; - gchar* sources_handle_ = nullptr; - gchar* start_handle_ = nullptr; - guint session_request_signal_id_ = 0; - guint sources_request_signal_id_ = 0; - guint start_request_signal_id_ = 0; - - DesktopSize desktop_size_ = {}; - DesktopCaptureOptions options_ = {}; - - uint8_t* current_frame_ = nullptr; - Callback* callback_ = nullptr; - - bool portal_init_failed_ = false; - - void InitPortal(); - void InitPipeWire(); - void InitPipeWireTypes(); - - void CreateReceivingStream(); - void HandleBuffer(pw_buffer* buffer); - - void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size); - - static void OnStateChanged(void* data, - pw_remote_state old_state, - pw_remote_state state, - const char* error); - static void OnStreamStateChanged(void* data, - pw_stream_state old_state, - pw_stream_state state, - const char* error_message); - - static void OnStreamFormatChanged(void* data, const struct spa_pod* format); - static void OnStreamProcess(void* data); - static void OnNewBuffer(void* data, uint32_t id); - - guint SetupRequestResponseSignal(const gchar* object_path, - GDBusSignalCallback callback); - - static void OnProxyRequested(GObject* object, - GAsyncResult* result, - gpointer user_data); - - static gchar* PrepareSignalHandle(GDBusConnection* connection, - const gchar* token); - - void SessionRequest(); - static void OnSessionRequested(GDBusProxy *proxy, - GAsyncResult* result, - gpointer user_data); - static void OnSessionRequestResponseSignal(GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data); - - void SourcesRequest(); - static void OnSourcesRequested(GDBusProxy *proxy, - GAsyncResult* result, - gpointer user_data); - static void OnSourcesRequestResponseSignal(GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data); - - void StartRequest(); - static void OnStartRequested(GDBusProxy *proxy, - GAsyncResult* result, - gpointer user_data); - static void OnStartRequestResponseSignal(GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data); - - void OpenPipeWireRemote(); - static void OnOpenPipeWireRemoteRequested(GDBusProxy *proxy, - GAsyncResult* result, - gpointer user_data); - - RTC_DISALLOW_COPY_AND_ASSIGN(BaseCapturerPipeWire); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.cc deleted file mode 100644 index e3668a507..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.cc +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/linux/mouse_cursor_monitor_x11.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/linux/x_error_trap.h" -#include "modules/desktop_capture/mouse_cursor.h" -#include "modules/desktop_capture/mouse_cursor_monitor.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace { - -// WindowCapturer returns window IDs of X11 windows with WM_STATE attribute. -// These windows may not be immediate children of the root window, because -// window managers may re-parent them to add decorations. However, -// XQueryPointer() expects to be passed children of the root. This function -// searches up the list of the windows to find the root child that corresponds -// to |window|. -Window GetTopLevelWindow(Display* display, Window window) { - while (true) { - // If the window is in WithdrawnState then look at all of its children. - ::Window root, parent; - ::Window* children; - unsigned int num_children; - if (!XQueryTree(display, window, &root, &parent, &children, - &num_children)) { - RTC_LOG(LS_ERROR) << "Failed to query for child windows although window" - "does not have a valid WM_STATE."; - return None; - } - if (children) - XFree(children); - - if (parent == root) - break; - - window = parent; - } - - return window; -} - -} // namespace - -namespace webrtc { - -MouseCursorMonitorX11::MouseCursorMonitorX11( - const DesktopCaptureOptions& options, - Window window) - : x_display_(options.x_display()), - callback_(NULL), - mode_(SHAPE_AND_POSITION), - window_(window), - have_xfixes_(false), - xfixes_event_base_(-1), - xfixes_error_base_(-1) { - // Set a default initial cursor shape in case XFixes is not present. - const int kSize = 5; - std::unique_ptr default_cursor( - new BasicDesktopFrame(DesktopSize(kSize, kSize))); - const uint8_t pixels[kSize * kSize] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - uint8_t* ptr = default_cursor->data(); - for (int y = 0; y < kSize; ++y) { - for (int x = 0; x < kSize; ++x) { - *ptr++ = pixels[kSize * y + x]; - *ptr++ = pixels[kSize * y + x]; - *ptr++ = pixels[kSize * y + x]; - *ptr++ = 0xff; - } - } - DesktopVector hotspot(2, 2); - cursor_shape_.reset(new MouseCursor(default_cursor.release(), hotspot)); -} - -MouseCursorMonitorX11::~MouseCursorMonitorX11() { - if (have_xfixes_) { - x_display_->RemoveEventHandler(xfixes_event_base_ + XFixesCursorNotify, - this); - } -} - -void MouseCursorMonitorX11::Init(Callback* callback, Mode mode) { - // Init can be called only once per instance of MouseCursorMonitor. - RTC_DCHECK(!callback_); - RTC_DCHECK(callback); - - callback_ = callback; - mode_ = mode; - - have_xfixes_ = - XFixesQueryExtension(display(), &xfixes_event_base_, &xfixes_error_base_); - - if (have_xfixes_) { - // Register for changes to the cursor shape. - XFixesSelectCursorInput(display(), window_, XFixesDisplayCursorNotifyMask); - x_display_->AddEventHandler(xfixes_event_base_ + XFixesCursorNotify, this); - - CaptureCursor(); - } else { - RTC_LOG(LS_INFO) << "X server does not support XFixes."; - } -} - -void MouseCursorMonitorX11::Capture() { - RTC_DCHECK(callback_); - - // Process X11 events in case XFixes has sent cursor notification. - x_display_->ProcessPendingXEvents(); - - // cursor_shape_| is set only if we were notified of a cursor shape change. - if (cursor_shape_.get()) - callback_->OnMouseCursor(cursor_shape_.release()); - - // Get cursor position if necessary. - if (mode_ == SHAPE_AND_POSITION) { - int root_x; - int root_y; - int win_x; - int win_y; - Window root_window; - Window child_window; - unsigned int mask; - - XErrorTrap error_trap(display()); - Bool result = XQueryPointer(display(), window_, &root_window, &child_window, - &root_x, &root_y, &win_x, &win_y, &mask); - CursorState state; - if (!result || error_trap.GetLastErrorAndDisable() != 0) { - state = OUTSIDE; - } else { - // In screen mode (window_ == root_window) the mouse is always inside. - // XQueryPointer() sets |child_window| to None if the cursor is outside - // |window_|. - state = - (window_ == root_window || child_window != None) ? INSIDE : OUTSIDE; - } - - // As the comments to GetTopLevelWindow() above indicate, in window capture, - // the cursor position capture happens in |window_|, while the frame catpure - // happens in |child_window|. These two windows are not alwyas same, as - // window manager may add some decorations to the |window_|. So translate - // the coordinate in |window_| to the coordinate space of |child_window|. - if (window_ != root_window && state == INSIDE) { - int translated_x, translated_y; - Window unused; - if (XTranslateCoordinates(display(), window_, child_window, win_x, win_y, - &translated_x, &translated_y, &unused)) { - win_x = translated_x; - win_y = translated_y; - } - } - - // X11 always starts the coordinate from (0, 0), so we do not need to - // translate here. - callback_->OnMouseCursorPosition(DesktopVector(root_x, root_y)); - } -} - -bool MouseCursorMonitorX11::HandleXEvent(const XEvent& event) { - if (have_xfixes_ && event.type == xfixes_event_base_ + XFixesCursorNotify) { - const XFixesCursorNotifyEvent* cursor_event = - reinterpret_cast(&event); - if (cursor_event->subtype == XFixesDisplayCursorNotify) { - CaptureCursor(); - } - // Return false, even if the event has been handled, because there might be - // other listeners for cursor notifications. - } - return false; -} - -void MouseCursorMonitorX11::CaptureCursor() { - RTC_DCHECK(have_xfixes_); - - XFixesCursorImage* img; - { - XErrorTrap error_trap(display()); - img = XFixesGetCursorImage(display()); - if (!img || error_trap.GetLastErrorAndDisable() != 0) - return; - } - - std::unique_ptr image( - new BasicDesktopFrame(DesktopSize(img->width, img->height))); - - // Xlib stores 32-bit data in longs, even if longs are 64-bits long. - unsigned long* src = img->pixels; - uint32_t* dst = reinterpret_cast(image->data()); - uint32_t* dst_end = dst + (img->width * img->height); - while (dst < dst_end) { - *dst++ = static_cast(*src++); - } - - DesktopVector hotspot(std::min(img->width, img->xhot), - std::min(img->height, img->yhot)); - - XFree(img); - - cursor_shape_.reset(new MouseCursor(image.release(), hotspot)); -} - -// static -MouseCursorMonitor* MouseCursorMonitorX11::CreateForWindow( - const DesktopCaptureOptions& options, - WindowId window) { - if (!options.x_display()) - return NULL; - window = GetTopLevelWindow(options.x_display()->display(), window); - if (window == None) - return NULL; - return new MouseCursorMonitorX11(options, window); -} - -MouseCursorMonitor* MouseCursorMonitorX11::CreateForScreen( - const DesktopCaptureOptions& options, - ScreenId screen) { - if (!options.x_display()) - return NULL; - return new MouseCursorMonitorX11( - options, DefaultRootWindow(options.x_display()->display())); -} - -std::unique_ptr MouseCursorMonitorX11::Create( - const DesktopCaptureOptions& options) { - return std::unique_ptr( - CreateForScreen(options, kFullDesktopScreenId)); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.h deleted file mode 100644 index 9603341a2..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_MOUSE_CURSOR_MONITOR_X11_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_MOUSE_CURSOR_MONITOR_X11_H_ - -#include - -#include - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/linux/shared_x_display.h" -#include "modules/desktop_capture/mouse_cursor.h" -#include "modules/desktop_capture/mouse_cursor_monitor.h" - -namespace webrtc { - -class MouseCursorMonitorX11 : public MouseCursorMonitor, - public SharedXDisplay::XEventHandler { - public: - MouseCursorMonitorX11(const DesktopCaptureOptions& options, Window window); - ~MouseCursorMonitorX11() override; - - static MouseCursorMonitor* CreateForWindow( - const DesktopCaptureOptions& options, - WindowId window); - static MouseCursorMonitor* CreateForScreen( - const DesktopCaptureOptions& options, - ScreenId screen); - static std::unique_ptr Create( - const DesktopCaptureOptions& options); - - void Init(Callback* callback, Mode mode) override; - void Capture() override; - - private: - // SharedXDisplay::XEventHandler interface. - bool HandleXEvent(const XEvent& event) override; - - Display* display() { return x_display_->display(); } - - // Captures current cursor shape and stores it in |cursor_shape_|. - void CaptureCursor(); - - rtc::scoped_refptr x_display_; - Callback* callback_; - Mode mode_; - Window window_; - - bool have_xfixes_; - int xfixes_event_base_; - int xfixes_error_base_; - - std::unique_ptr cursor_shape_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_MOUSE_CURSOR_MONITOR_X11_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc deleted file mode 100644 index fe672140c..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 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 "modules/desktop_capture/linux/screen_capturer_pipewire.h" - -#include - - -namespace webrtc { - -ScreenCapturerPipeWire::ScreenCapturerPipeWire() - : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {} -ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {} - -// static -std::unique_ptr -ScreenCapturerPipeWire::CreateRawScreenCapturer( - const DesktopCaptureOptions& options) { - return std::make_unique(); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h deleted file mode 100644 index 66dcd680e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_ - -#include - -#include "modules/desktop_capture/linux/base_capturer_pipewire.h" - -namespace webrtc { - -class ScreenCapturerPipeWire : public BaseCapturerPipeWire { - public: - ScreenCapturerPipeWire(); - ~ScreenCapturerPipeWire() override; - - static std::unique_ptr CreateRawScreenCapturer( - const DesktopCaptureOptions& options); - - RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerPipeWire); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_x11.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_x11.cc deleted file mode 100644 index 1b1707141..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_x11.cc +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/linux/screen_capturer_x11.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/linux/x_server_pixel_buffer.h" -#include "modules/desktop_capture/screen_capture_frame_queue.h" -#include "modules/desktop_capture/screen_capturer_helper.h" -#include "modules/desktop_capture/shared_desktop_frame.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" -#include "rtc_base/sanitizer.h" -#include "rtc_base/time_utils.h" -#include "rtc_base/trace_event.h" - -namespace webrtc { - -ScreenCapturerX11::ScreenCapturerX11() { - helper_.SetLogGridSize(4); -} - -ScreenCapturerX11::~ScreenCapturerX11() { - options_.x_display()->RemoveEventHandler(ConfigureNotify, this); - if (use_damage_) { - options_.x_display()->RemoveEventHandler(damage_event_base_ + XDamageNotify, - this); - } - if (use_randr_) { - options_.x_display()->RemoveEventHandler( - randr_event_base_ + RRScreenChangeNotify, this); - } - DeinitXlib(); -} - -bool ScreenCapturerX11::Init(const DesktopCaptureOptions& options) { - TRACE_EVENT0("webrtc", "ScreenCapturerX11::Init"); - options_ = options; - - atom_cache_ = std::make_unique(display()); - - root_window_ = RootWindow(display(), DefaultScreen(display())); - if (root_window_ == BadValue) { - RTC_LOG(LS_ERROR) << "Unable to get the root window"; - DeinitXlib(); - return false; - } - - gc_ = XCreateGC(display(), root_window_, 0, NULL); - if (gc_ == NULL) { - RTC_LOG(LS_ERROR) << "Unable to get graphics context"; - DeinitXlib(); - return false; - } - - options_.x_display()->AddEventHandler(ConfigureNotify, this); - - // Check for XFixes extension. This is required for cursor shape - // notifications, and for our use of XDamage. - if (XFixesQueryExtension(display(), &xfixes_event_base_, - &xfixes_error_base_)) { - has_xfixes_ = true; - } else { - RTC_LOG(LS_INFO) << "X server does not support XFixes."; - } - - // Register for changes to the dimensions of the root window. - XSelectInput(display(), root_window_, StructureNotifyMask); - - if (!x_server_pixel_buffer_.Init(atom_cache_.get(), - DefaultRootWindow(display()))) { - RTC_LOG(LS_ERROR) << "Failed to initialize pixel buffer."; - return false; - } - - if (options_.use_update_notifications()) { - InitXDamage(); - } - - InitXrandr(); - - // Default source set here so that selected_monitor_rect_ is sized correctly. - SelectSource(kFullDesktopScreenId); - - return true; -} - -void ScreenCapturerX11::InitXDamage() { - // Our use of XDamage requires XFixes. - if (!has_xfixes_) { - return; - } - - // Check for XDamage extension. - if (!XDamageQueryExtension(display(), &damage_event_base_, - &damage_error_base_)) { - RTC_LOG(LS_INFO) << "X server does not support XDamage."; - return; - } - - // TODO(lambroslambrou): Disable DAMAGE in situations where it is known - // to fail, such as when Desktop Effects are enabled, with graphics - // drivers (nVidia, ATI) that fail to report DAMAGE notifications - // properly. - - // Request notifications every time the screen becomes damaged. - damage_handle_ = - XDamageCreate(display(), root_window_, XDamageReportNonEmpty); - if (!damage_handle_) { - RTC_LOG(LS_ERROR) << "Unable to initialize XDamage."; - return; - } - - // Create an XFixes server-side region to collate damage into. - damage_region_ = XFixesCreateRegion(display(), 0, 0); - if (!damage_region_) { - XDamageDestroy(display(), damage_handle_); - RTC_LOG(LS_ERROR) << "Unable to create XFixes region."; - return; - } - - options_.x_display()->AddEventHandler(damage_event_base_ + XDamageNotify, - this); - - use_damage_ = true; - RTC_LOG(LS_INFO) << "Using XDamage extension."; -} - -RTC_NO_SANITIZE("cfi-icall") -void ScreenCapturerX11::InitXrandr() { - int major_version = 0; - int minor_version = 0; - int error_base_ignored = 0; - if (XRRQueryExtension(display(), &randr_event_base_, &error_base_ignored) && - XRRQueryVersion(display(), &major_version, &minor_version)) { - if (major_version > 1 || (major_version == 1 && minor_version >= 5)) { - // Dynamically link XRRGetMonitors and XRRFreeMonitors as a workaround - // to avoid a dependency issue with Debian 8. - get_monitors_ = reinterpret_cast( - dlsym(RTLD_DEFAULT, "XRRGetMonitors")); - free_monitors_ = reinterpret_cast( - dlsym(RTLD_DEFAULT, "XRRFreeMonitors")); - if (get_monitors_ && free_monitors_) { - use_randr_ = true; - RTC_LOG(LS_INFO) << "Using XRandR extension v" << major_version << '.' - << minor_version << '.'; - monitors_ = - get_monitors_(display(), root_window_, true, &num_monitors_); - - // Register for screen change notifications - XRRSelectInput(display(), root_window_, RRScreenChangeNotifyMask); - options_.x_display()->AddEventHandler( - randr_event_base_ + RRScreenChangeNotify, this); - } else { - RTC_LOG(LS_ERROR) << "Unable to link XRandR monitor functions."; - } - } else { - RTC_LOG(LS_ERROR) << "XRandR entension is older than v1.5."; - } - } else { - RTC_LOG(LS_ERROR) << "X server does not support XRandR."; - } -} - -RTC_NO_SANITIZE("cfi-icall") -void ScreenCapturerX11::UpdateMonitors() { - if (monitors_) { - free_monitors_(monitors_); - monitors_ = nullptr; - } - - monitors_ = get_monitors_(display(), root_window_, true, &num_monitors_); - - if (selected_monitor_name_) { - if (selected_monitor_name_ == static_cast(kFullDesktopScreenId)) { - selected_monitor_rect_ = - DesktopRect::MakeSize(x_server_pixel_buffer_.window_size()); - return; - } - - for (int i = 0; i < num_monitors_; ++i) { - XRRMonitorInfo& m = monitors_[i]; - if (selected_monitor_name_ == m.name) { - RTC_LOG(LS_INFO) << "XRandR monitor " << m.name << " rect updated."; - selected_monitor_rect_ = - DesktopRect::MakeXYWH(m.x, m.y, m.width, m.height); - return; - } - } - - // The selected monitor is not connected anymore - RTC_LOG(LS_INFO) << "XRandR selected monitor " << selected_monitor_name_ - << " lost."; - selected_monitor_rect_ = DesktopRect::MakeWH(0, 0); - } -} - -void ScreenCapturerX11::Start(Callback* callback) { - RTC_DCHECK(!callback_); - RTC_DCHECK(callback); - - callback_ = callback; -} - -void ScreenCapturerX11::CaptureFrame() { - TRACE_EVENT0("webrtc", "ScreenCapturerX11::CaptureFrame"); - int64_t capture_start_time_nanos = rtc::TimeNanos(); - - queue_.MoveToNextFrame(); - RTC_DCHECK(!queue_.current_frame() || !queue_.current_frame()->IsShared()); - - // Process XEvents for XDamage and cursor shape tracking. - options_.x_display()->ProcessPendingXEvents(); - - // ProcessPendingXEvents() may call ScreenConfigurationChanged() which - // reinitializes |x_server_pixel_buffer_|. Check if the pixel buffer is still - // in a good shape. - if (!x_server_pixel_buffer_.is_initialized()) { - // We failed to initialize pixel buffer. - RTC_LOG(LS_ERROR) << "Pixel buffer is not initialized."; - callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); - return; - } - - // Allocate the current frame buffer only if it is not already allocated. - // Note that we can't reallocate other buffers at this point, since the caller - // may still be reading from them. - if (!queue_.current_frame()) { - std::unique_ptr frame( - new BasicDesktopFrame(selected_monitor_rect_.size())); - - // We set the top-left of the frame so the mouse cursor will be composited - // properly, and our frame buffer will not be overrun while blitting. - frame->set_top_left(selected_monitor_rect_.top_left()); - queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame))); - } - - std::unique_ptr result = CaptureScreen(); - if (!result) { - RTC_LOG(LS_WARNING) << "Temporarily failed to capture screen."; - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); - return; - } - - last_invalid_region_ = result->updated_region(); - result->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) / - rtc::kNumNanosecsPerMillisec); - callback_->OnCaptureResult(Result::SUCCESS, std::move(result)); -} - -bool ScreenCapturerX11::GetSourceList(SourceList* sources) { - RTC_DCHECK(sources->size() == 0); - if (!use_randr_) { - sources->push_back({}); - return true; - } - - // Ensure that |monitors_| is updated with changes that may have happened - // between calls to GetSourceList(). - options_.x_display()->ProcessPendingXEvents(); - - for (int i = 0; i < num_monitors_; ++i) { - XRRMonitorInfo& m = monitors_[i]; - char* monitor_title = XGetAtomName(display(), m.name); - - // Note name is an X11 Atom used to id the monitor. - sources->push_back({static_cast(m.name), monitor_title}); - XFree(monitor_title); - } - - return true; -} - -bool ScreenCapturerX11::SelectSource(SourceId id) { - // Prevent the reuse of any frame buffers allocated for a previously selected - // source. This is required to stop crashes, or old data from appearing in - // a captured frame, when the new source is sized differently then the source - // that was selected at the time a reused frame buffer was created. - queue_.Reset(); - - if (!use_randr_ || id == kFullDesktopScreenId) { - selected_monitor_name_ = kFullDesktopScreenId; - selected_monitor_rect_ = - DesktopRect::MakeSize(x_server_pixel_buffer_.window_size()); - return true; - } - - for (int i = 0; i < num_monitors_; ++i) { - if (id == static_cast(monitors_[i].name)) { - RTC_LOG(LS_INFO) << "XRandR selected source: " << id; - XRRMonitorInfo& m = monitors_[i]; - selected_monitor_name_ = m.name; - selected_monitor_rect_ = - DesktopRect::MakeXYWH(m.x, m.y, m.width, m.height); - return true; - } - } - return false; -} - -bool ScreenCapturerX11::HandleXEvent(const XEvent& event) { - if (use_damage_ && (event.type == damage_event_base_ + XDamageNotify)) { - const XDamageNotifyEvent* damage_event = - reinterpret_cast(&event); - if (damage_event->damage != damage_handle_) - return false; - RTC_DCHECK(damage_event->level == XDamageReportNonEmpty); - return true; - } else if (use_randr_ && - event.type == randr_event_base_ + RRScreenChangeNotify) { - XRRUpdateConfiguration(const_cast(&event)); - UpdateMonitors(); - RTC_LOG(LS_INFO) << "XRandR screen change event received."; - return true; - } else if (event.type == ConfigureNotify) { - ScreenConfigurationChanged(); - return true; - } - return false; -} - -std::unique_ptr ScreenCapturerX11::CaptureScreen() { - std::unique_ptr frame = queue_.current_frame()->Share(); - RTC_DCHECK(selected_monitor_rect_.size().equals(frame->size())); - - // Pass the screen size to the helper, so it can clip the invalid region if it - // expands that region to a grid. - helper_.set_size_most_recent(x_server_pixel_buffer_.window_size()); - - // In the DAMAGE case, ensure the frame is up-to-date with the previous frame - // if any. If there isn't a previous frame, that means a screen-resolution - // change occurred, and |invalid_rects| will be updated to include the whole - // screen. - if (use_damage_ && queue_.previous_frame()) - SynchronizeFrame(); - - DesktopRegion* updated_region = frame->mutable_updated_region(); - - x_server_pixel_buffer_.Synchronize(); - if (use_damage_ && queue_.previous_frame()) { - // Atomically fetch and clear the damage region. - XDamageSubtract(display(), damage_handle_, None, damage_region_); - int rects_num = 0; - XRectangle bounds; - XRectangle* rects = XFixesFetchRegionAndBounds(display(), damage_region_, - &rects_num, &bounds); - for (int i = 0; i < rects_num; ++i) { - updated_region->AddRect(DesktopRect::MakeXYWH( - rects[i].x, rects[i].y, rects[i].width, rects[i].height)); - } - XFree(rects); - helper_.InvalidateRegion(*updated_region); - - // Capture the damaged portions of the desktop. - helper_.TakeInvalidRegion(updated_region); - updated_region->IntersectWith(selected_monitor_rect_); - - for (DesktopRegion::Iterator it(*updated_region); !it.IsAtEnd(); - it.Advance()) { - if (!x_server_pixel_buffer_.CaptureRect(it.rect(), frame.get())) - return nullptr; - } - } else { - // Doing full-screen polling, or this is the first capture after a - // screen-resolution change. In either case, need a full-screen capture. - if (!x_server_pixel_buffer_.CaptureRect(selected_monitor_rect_, - frame.get())) { - return nullptr; - } - updated_region->SetRect(selected_monitor_rect_); - } - - return std::move(frame); -} - -void ScreenCapturerX11::ScreenConfigurationChanged() { - TRACE_EVENT0("webrtc", "ScreenCapturerX11::ScreenConfigurationChanged"); - // Make sure the frame buffers will be reallocated. - queue_.Reset(); - - helper_.ClearInvalidRegion(); - if (!x_server_pixel_buffer_.Init(atom_cache_.get(), - DefaultRootWindow(display()))) { - RTC_LOG(LS_ERROR) << "Failed to initialize pixel buffer after screen " - "configuration change."; - } - - if (!use_randr_) { - selected_monitor_rect_ = - DesktopRect::MakeSize(x_server_pixel_buffer_.window_size()); - } -} - -void ScreenCapturerX11::SynchronizeFrame() { - // Synchronize the current buffer with the previous one since we do not - // capture the entire desktop. Note that encoder may be reading from the - // previous buffer at this time so thread access complaints are false - // positives. - - // TODO(hclam): We can reduce the amount of copying here by subtracting - // |capturer_helper_|s region from |last_invalid_region_|. - // http://crbug.com/92354 - RTC_DCHECK(queue_.previous_frame()); - - DesktopFrame* current = queue_.current_frame(); - DesktopFrame* last = queue_.previous_frame(); - RTC_DCHECK(current != last); - for (DesktopRegion::Iterator it(last_invalid_region_); !it.IsAtEnd(); - it.Advance()) { - if (selected_monitor_rect_.ContainsRect(it.rect())) { - DesktopRect r = it.rect(); - r.Translate(-selected_monitor_rect_.top_left()); - current->CopyPixelsFrom(*last, r.top_left(), r); - } - } -} - -RTC_NO_SANITIZE("cfi-icall") -void ScreenCapturerX11::DeinitXlib() { - if (monitors_) { - free_monitors_(monitors_); - monitors_ = nullptr; - } - - if (gc_) { - XFreeGC(display(), gc_); - gc_ = nullptr; - } - - x_server_pixel_buffer_.Release(); - - if (display()) { - if (damage_handle_) { - XDamageDestroy(display(), damage_handle_); - damage_handle_ = 0; - } - - if (damage_region_) { - XFixesDestroyRegion(display(), damage_region_); - damage_region_ = 0; - } - } -} - -// static -std::unique_ptr ScreenCapturerX11::CreateRawScreenCapturer( - const DesktopCaptureOptions& options) { - if (!options.x_display()) - return nullptr; - - std::unique_ptr capturer(new ScreenCapturerX11()); - if (!capturer.get()->Init(options)) { - return nullptr; - } - - return std::move(capturer); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_x11.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_x11.h deleted file mode 100644 index b19e2e46e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/screen_capturer_x11.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_X11_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_X11_H_ - -#include -#include -#include -#include -#include - -#include - -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_region.h" -#include "modules/desktop_capture/linux/shared_x_display.h" -#include "modules/desktop_capture/linux/x_atom_cache.h" -#include "modules/desktop_capture/linux/x_server_pixel_buffer.h" -#include "modules/desktop_capture/screen_capture_frame_queue.h" -#include "modules/desktop_capture/screen_capturer_helper.h" -#include "modules/desktop_capture/shared_desktop_frame.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -// A class to perform video frame capturing for Linux on X11. -// -// If XDamage is used, this class sets DesktopFrame::updated_region() according -// to the areas reported by XDamage. Otherwise this class does not detect -// DesktopFrame::updated_region(), the field is always set to the entire frame -// rectangle. ScreenCapturerDifferWrapper should be used if that functionality -// is necessary. -class ScreenCapturerX11 : public DesktopCapturer, - public SharedXDisplay::XEventHandler { - public: - ScreenCapturerX11(); - ~ScreenCapturerX11() override; - - static std::unique_ptr CreateRawScreenCapturer( - const DesktopCaptureOptions& options); - - // TODO(ajwong): Do we really want this to be synchronous? - bool Init(const DesktopCaptureOptions& options); - - // DesktopCapturer interface. - void Start(Callback* delegate) override; - void CaptureFrame() override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - - private: - Display* display() { return options_.x_display()->display(); } - - // SharedXDisplay::XEventHandler interface. - bool HandleXEvent(const XEvent& event) override; - - void InitXDamage(); - void InitXrandr(); - void UpdateMonitors(); - - // Capture screen pixels to the current buffer in the queue. In the DAMAGE - // case, the ScreenCapturerHelper already holds the list of invalid rectangles - // from HandleXEvent(). In the non-DAMAGE case, this captures the - // whole screen, then calculates some invalid rectangles that include any - // differences between this and the previous capture. - std::unique_ptr CaptureScreen(); - - // Called when the screen configuration is changed. - void ScreenConfigurationChanged(); - - // Synchronize the current buffer with |last_buffer_|, by copying pixels from - // the area of |last_invalid_rects|. - // Note this only works on the assumption that kNumBuffers == 2, as - // |last_invalid_rects| holds the differences from the previous buffer and - // the one prior to that (which will then be the current buffer). - void SynchronizeFrame(); - - void DeinitXlib(); - - DesktopCaptureOptions options_; - - Callback* callback_ = nullptr; - - // X11 graphics context. - GC gc_ = nullptr; - Window root_window_ = BadValue; - - // XRandR 1.5 monitors. - bool use_randr_ = false; - int randr_event_base_ = 0; - XRRMonitorInfo* monitors_ = nullptr; - int num_monitors_ = 0; - DesktopRect selected_monitor_rect_; - // selected_monitor_name_ will be changed to kFullDesktopScreenId - // by a call to SelectSource() at the end of Init() because - // selected_monitor_rect_ should be updated as well. - // Setting it to kFullDesktopScreenId here might be misleading. - Atom selected_monitor_name_ = 0; - typedef XRRMonitorInfo* (*get_monitors_func)(Display*, Window, Bool, int*); - typedef void (*free_monitors_func)(XRRMonitorInfo*); - get_monitors_func get_monitors_ = nullptr; - free_monitors_func free_monitors_ = nullptr; - - // XFixes. - bool has_xfixes_ = false; - int xfixes_event_base_ = -1; - int xfixes_error_base_ = -1; - - // XDamage information. - bool use_damage_ = false; - Damage damage_handle_ = 0; - int damage_event_base_ = -1; - int damage_error_base_ = -1; - XserverRegion damage_region_ = 0; - - // Access to the X Server's pixel buffer. - XServerPixelBuffer x_server_pixel_buffer_; - - // A thread-safe list of invalid rectangles, and the size of the most - // recently captured screen. - ScreenCapturerHelper helper_; - - // Queue of the frames buffers. - ScreenCaptureFrameQueue queue_; - - // Invalid region from the previous capture. This is used to synchronize the - // current with the last buffer used. - DesktopRegion last_invalid_region_; - - std::unique_ptr atom_cache_; - - RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerX11); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_X11_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/shared_x_display.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/shared_x_display.cc deleted file mode 100644 index f0b35f62d..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/shared_x_display.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/linux/shared_x_display.h" - -#include -#include - -#include - -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { - -SharedXDisplay::SharedXDisplay(Display* display) : display_(display) { - RTC_DCHECK(display_); -} - -SharedXDisplay::~SharedXDisplay() { - RTC_DCHECK(event_handlers_.empty()); - XCloseDisplay(display_); -} - -// static -rtc::scoped_refptr SharedXDisplay::Create( - const std::string& display_name) { - Display* display = - XOpenDisplay(display_name.empty() ? NULL : display_name.c_str()); - if (!display) { - RTC_LOG(LS_ERROR) << "Unable to open display"; - return NULL; - } - return new SharedXDisplay(display); -} - -// static -rtc::scoped_refptr SharedXDisplay::CreateDefault() { - return Create(std::string()); -} - -void SharedXDisplay::AddEventHandler(int type, XEventHandler* handler) { - event_handlers_[type].push_back(handler); -} - -void SharedXDisplay::RemoveEventHandler(int type, XEventHandler* handler) { - EventHandlersMap::iterator handlers = event_handlers_.find(type); - if (handlers == event_handlers_.end()) - return; - - std::vector::iterator new_end = - std::remove(handlers->second.begin(), handlers->second.end(), handler); - handlers->second.erase(new_end, handlers->second.end()); - - // Check if no handlers left for this event. - if (handlers->second.empty()) - event_handlers_.erase(handlers); -} - -void SharedXDisplay::ProcessPendingXEvents() { - // Hold reference to |this| to prevent it from being destroyed while - // processing events. - rtc::scoped_refptr self(this); - - // Find the number of events that are outstanding "now." We don't just loop - // on XPending because we want to guarantee this terminates. - int events_to_process = XPending(display()); - XEvent e; - - for (int i = 0; i < events_to_process; i++) { - XNextEvent(display(), &e); - EventHandlersMap::iterator handlers = event_handlers_.find(e.type); - if (handlers == event_handlers_.end()) - continue; - for (std::vector::iterator it = handlers->second.begin(); - it != handlers->second.end(); ++it) { - if ((*it)->HandleXEvent(e)) - break; - } - } -} - -void SharedXDisplay::IgnoreXServerGrabs() { - int test_event_base = 0; - int test_error_base = 0; - int major = 0; - int minor = 0; - if (XTestQueryExtension(display(), &test_event_base, &test_error_base, &major, - &minor)) { - XTestGrabControl(display(), true); - } -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/shared_x_display.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/shared_x_display.h deleted file mode 100644 index 64c498c13..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/shared_x_display.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SHARED_X_DISPLAY_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_SHARED_X_DISPLAY_H_ - -#include -#include -#include - -#include "api/ref_counted_base.h" -#include "api/scoped_refptr.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/system/rtc_export.h" - -// Including Xlib.h will involve evil defines (Bool, Status, True, False), which -// easily conflict with other headers. -typedef struct _XDisplay Display; -typedef union _XEvent XEvent; - -namespace webrtc { - -// A ref-counted object to store XDisplay connection. -class RTC_EXPORT SharedXDisplay : public rtc::RefCountedBase { - public: - class XEventHandler { - public: - virtual ~XEventHandler() {} - - // Processes XEvent. Returns true if the event has been handled. - virtual bool HandleXEvent(const XEvent& event) = 0; - }; - - // Takes ownership of |display|. - explicit SharedXDisplay(Display* display); - - // Creates a new X11 Display for the |display_name|. NULL is returned if X11 - // connection failed. Equivalent to CreateDefault() when |display_name| is - // empty. - static rtc::scoped_refptr Create( - const std::string& display_name); - - // Creates X11 Display connection for the default display (e.g. specified in - // DISPLAY). NULL is returned if X11 connection failed. - static rtc::scoped_refptr CreateDefault(); - - Display* display() { return display_; } - - // Adds a new event |handler| for XEvent's of |type|. - void AddEventHandler(int type, XEventHandler* handler); - - // Removes event |handler| added using |AddEventHandler|. Doesn't do anything - // if |handler| is not registered. - void RemoveEventHandler(int type, XEventHandler* handler); - - // Processes pending XEvents, calling corresponding event handlers. - void ProcessPendingXEvents(); - - void IgnoreXServerGrabs(); - - protected: - ~SharedXDisplay() override; - - private: - typedef std::map > EventHandlersMap; - - Display* display_; - - EventHandlersMap event_handlers_; - - RTC_DISALLOW_COPY_AND_ASSIGN(SharedXDisplay); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_SHARED_X_DISPLAY_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc deleted file mode 100644 index b4559156d..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 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 "modules/desktop_capture/linux/window_capturer_pipewire.h" - -#include - - -namespace webrtc { - -WindowCapturerPipeWire::WindowCapturerPipeWire() - : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Window) {} -WindowCapturerPipeWire::~WindowCapturerPipeWire() {} - -// static -std::unique_ptr -WindowCapturerPipeWire::CreateRawWindowCapturer( - const DesktopCaptureOptions& options) { - return std::make_unique(); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h deleted file mode 100644 index 7f184ef29..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_ - -#include - -#include "modules/desktop_capture/linux/base_capturer_pipewire.h" - -namespace webrtc { - -class WindowCapturerPipeWire : public BaseCapturerPipeWire { - public: - WindowCapturerPipeWire(); - ~WindowCapturerPipeWire() override; - - static std::unique_ptr CreateRawWindowCapturer( - const DesktopCaptureOptions& options); - - RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerPipeWire); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_x11.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_x11.cc deleted file mode 100644 index 94f9f92c8..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_x11.cc +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/linux/window_capturer_x11.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_region.h" -#include "modules/desktop_capture/linux/shared_x_display.h" -#include "modules/desktop_capture/linux/window_finder_x11.h" -#include "modules/desktop_capture/linux/window_list_utils.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" -#include "rtc_base/trace_event.h" - -namespace webrtc { - -WindowCapturerX11::WindowCapturerX11(const DesktopCaptureOptions& options) - : x_display_(options.x_display()), - atom_cache_(display()), - window_finder_(&atom_cache_) { - int event_base, error_base, major_version, minor_version; - if (XCompositeQueryExtension(display(), &event_base, &error_base) && - XCompositeQueryVersion(display(), &major_version, &minor_version) && - // XCompositeNameWindowPixmap() requires version 0.2 - (major_version > 0 || minor_version >= 2)) { - has_composite_extension_ = true; - } else { - RTC_LOG(LS_INFO) << "Xcomposite extension not available or too old."; - } - - x_display_->AddEventHandler(ConfigureNotify, this); -} - -WindowCapturerX11::~WindowCapturerX11() { - x_display_->RemoveEventHandler(ConfigureNotify, this); -} - -bool WindowCapturerX11::GetSourceList(SourceList* sources) { - return GetWindowList(&atom_cache_, [this, sources](::Window window) { - Source w; - w.id = window; - if (this->GetWindowTitle(window, &w.title)) { - sources->push_back(w); - } - return true; - }); -} - -bool WindowCapturerX11::SelectSource(SourceId id) { - if (!x_server_pixel_buffer_.Init(&atom_cache_, id)) - return false; - - // Tell the X server to send us window resizing events. - XSelectInput(display(), id, StructureNotifyMask); - - selected_window_ = id; - - // In addition to needing X11 server-side support for Xcomposite, it actually - // needs to be turned on for the window. If the user has modern - // hardware/drivers but isn't using a compositing window manager, that won't - // be the case. Here we automatically turn it on. - - // Redirect drawing to an offscreen buffer (ie, turn on compositing). X11 - // remembers who has requested this and will turn it off for us when we exit. - XCompositeRedirectWindow(display(), id, CompositeRedirectAutomatic); - - return true; -} - -bool WindowCapturerX11::FocusOnSelectedSource() { - if (!selected_window_) - return false; - - unsigned int num_children; - ::Window* children; - ::Window parent; - ::Window root; - // Find the root window to pass event to. - int status = XQueryTree(display(), selected_window_, &root, &parent, - &children, &num_children); - if (status == 0) { - RTC_LOG(LS_ERROR) << "Failed to query for the root window."; - return false; - } - - if (children) - XFree(children); - - XRaiseWindow(display(), selected_window_); - - // Some window managers (e.g., metacity in GNOME) consider it illegal to - // raise a window without also giving it input focus with - // _NET_ACTIVE_WINDOW, so XRaiseWindow() on its own isn't enough. - Atom atom = XInternAtom(display(), "_NET_ACTIVE_WINDOW", True); - if (atom != None) { - XEvent xev; - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.window = selected_window_; - xev.xclient.message_type = atom; - - // The format member is set to 8, 16, or 32 and specifies whether the - // data should be viewed as a list of bytes, shorts, or longs. - xev.xclient.format = 32; - - memset(xev.xclient.data.l, 0, sizeof(xev.xclient.data.l)); - - XSendEvent(display(), root, False, - SubstructureRedirectMask | SubstructureNotifyMask, &xev); - } - XFlush(display()); - return true; -} - -void WindowCapturerX11::Start(Callback* callback) { - RTC_DCHECK(!callback_); - RTC_DCHECK(callback); - - callback_ = callback; -} - -void WindowCapturerX11::CaptureFrame() { - TRACE_EVENT0("webrtc", "WindowCapturerX11::CaptureFrame"); - - if (!x_server_pixel_buffer_.IsWindowValid()) { - RTC_LOG(LS_ERROR) << "The window is no longer valid."; - callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); - return; - } - - x_display_->ProcessPendingXEvents(); - - if (!has_composite_extension_) { - // Without the Xcomposite extension we capture when the whole window is - // visible on screen and not covered by any other window. This is not - // something we want so instead, just bail out. - RTC_LOG(LS_ERROR) << "No Xcomposite extension detected."; - callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); - return; - } - - if (GetWindowState(&atom_cache_, selected_window_) == IconicState) { - // Window is in minimized. Return a 1x1 frame as same as OSX/Win does. - std::unique_ptr frame( - new BasicDesktopFrame(DesktopSize(1, 1))); - callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); - return; - } - - std::unique_ptr frame( - new BasicDesktopFrame(x_server_pixel_buffer_.window_size())); - - x_server_pixel_buffer_.Synchronize(); - if (!x_server_pixel_buffer_.CaptureRect(DesktopRect::MakeSize(frame->size()), - frame.get())) { - RTC_LOG(LS_WARNING) << "Temporarily failed to capture winodw."; - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); - return; - } - - frame->mutable_updated_region()->SetRect( - DesktopRect::MakeSize(frame->size())); - frame->set_top_left(x_server_pixel_buffer_.window_rect().top_left()); - - callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); -} - -bool WindowCapturerX11::IsOccluded(const DesktopVector& pos) { - return window_finder_.GetWindowUnderPoint(pos) != - static_cast(selected_window_); -} - -bool WindowCapturerX11::HandleXEvent(const XEvent& event) { - if (event.type == ConfigureNotify) { - XConfigureEvent xce = event.xconfigure; - if (xce.window == selected_window_) { - if (!DesktopRectFromXAttributes(xce).equals( - x_server_pixel_buffer_.window_rect())) { - if (!x_server_pixel_buffer_.Init(&atom_cache_, selected_window_)) { - RTC_LOG(LS_ERROR) - << "Failed to initialize pixel buffer after resizing."; - } - } - } - } - - // Always returns false, so other observers can still receive the events. - return false; -} - -bool WindowCapturerX11::GetWindowTitle(::Window window, std::string* title) { - int status; - bool result = false; - XTextProperty window_name; - window_name.value = nullptr; - if (window) { - status = XGetWMName(display(), window, &window_name); - if (status && window_name.value && window_name.nitems) { - int cnt; - char** list = nullptr; - status = - Xutf8TextPropertyToTextList(display(), &window_name, &list, &cnt); - if (status >= Success && cnt && *list) { - if (cnt > 1) { - RTC_LOG(LS_INFO) << "Window has " << cnt - << " text properties, only using the first one."; - } - *title = *list; - result = true; - } - if (list) - XFreeStringList(list); - } - if (window_name.value) - XFree(window_name.value); - } - return result; -} - -// static -std::unique_ptr WindowCapturerX11::CreateRawWindowCapturer( - const DesktopCaptureOptions& options) { - if (!options.x_display()) - return nullptr; - return std::unique_ptr(new WindowCapturerX11(options)); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_x11.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_x11.h deleted file mode 100644 index f689dd6f5..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_capturer_x11.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_X11_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_X11_H_ - -#include -#include - -#include -#include - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/linux/shared_x_display.h" -#include "modules/desktop_capture/linux/window_finder_x11.h" -#include "modules/desktop_capture/linux/x_atom_cache.h" -#include "modules/desktop_capture/linux/x_server_pixel_buffer.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -class WindowCapturerX11 : public DesktopCapturer, - public SharedXDisplay::XEventHandler { - public: - explicit WindowCapturerX11(const DesktopCaptureOptions& options); - ~WindowCapturerX11() override; - - static std::unique_ptr CreateRawWindowCapturer( - const DesktopCaptureOptions& options); - - // DesktopCapturer interface. - void Start(Callback* callback) override; - void CaptureFrame() override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - bool FocusOnSelectedSource() override; - bool IsOccluded(const DesktopVector& pos) override; - - // SharedXDisplay::XEventHandler interface. - bool HandleXEvent(const XEvent& event) override; - - private: - Display* display() { return x_display_->display(); } - - // Returns window title for the specified X |window|. - bool GetWindowTitle(::Window window, std::string* title); - - Callback* callback_ = nullptr; - - rtc::scoped_refptr x_display_; - - bool has_composite_extension_ = false; - - ::Window selected_window_ = 0; - XServerPixelBuffer x_server_pixel_buffer_; - XAtomCache atom_cache_; - WindowFinderX11 window_finder_; - - RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerX11); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_X11_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_finder_x11.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_finder_x11.cc deleted file mode 100644 index 16fb3252a..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_finder_x11.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/linux/window_finder_x11.h" - -#include - -#include - -#include "modules/desktop_capture/linux/window_list_utils.h" -#include "rtc_base/checks.h" - -namespace webrtc { - -WindowFinderX11::WindowFinderX11(XAtomCache* cache) : cache_(cache) { - RTC_DCHECK(cache_); -} - -WindowFinderX11::~WindowFinderX11() = default; - -WindowId WindowFinderX11::GetWindowUnderPoint(DesktopVector point) { - WindowId id = kNullWindowId; - GetWindowList(cache_, [&id, this, point](::Window window) { - DesktopRect rect; - if (GetWindowRect(this->cache_->display(), window, &rect) && - rect.Contains(point)) { - id = window; - return false; - } - return true; - }); - return id; -} - -// static -std::unique_ptr WindowFinder::Create( - const WindowFinder::Options& options) { - if (options.cache == nullptr) { - return nullptr; - } - - return std::make_unique(options.cache); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_finder_x11.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_finder_x11.h deleted file mode 100644 index d0bba8697..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_finder_x11.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_FINDER_X11_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_FINDER_X11_H_ - -#include "modules/desktop_capture/window_finder.h" - -namespace webrtc { - -class XAtomCache; - -// The implementation of WindowFinder for X11. -class WindowFinderX11 final : public WindowFinder { - public: - explicit WindowFinderX11(XAtomCache* cache); - ~WindowFinderX11() override; - - // WindowFinder implementation. - WindowId GetWindowUnderPoint(DesktopVector point) override; - - private: - XAtomCache* const cache_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_FINDER_X11_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_list_utils.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_list_utils.cc deleted file mode 100644 index 06660dde1..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_list_utils.cc +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/linux/window_list_utils.h" - -#include -#include -#include - -#include - -#include "modules/desktop_capture/linux/x_error_trap.h" -#include "modules/desktop_capture/linux/x_window_property.h" -#include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/logging.h" - -namespace webrtc { - -namespace { - -class DeferXFree { - public: - explicit DeferXFree(void* data) : data_(data) {} - ~DeferXFree(); - - private: - void* const data_; -}; - -DeferXFree::~DeferXFree() { - if (data_) - XFree(data_); -} - -// Iterates through |window| hierarchy to find first visible window, i.e. one -// that has WM_STATE property set to NormalState. -// See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 . -::Window GetApplicationWindow(XAtomCache* cache, ::Window window) { - int32_t state = GetWindowState(cache, window); - if (state == NormalState) { - // Window has WM_STATE==NormalState. Return it. - return window; - } else if (state == IconicState) { - // Window is in minimized. Skip it. - return 0; - } - - RTC_DCHECK_EQ(state, WithdrawnState); - // If the window is in WithdrawnState then look at all of its children. - ::Window root, parent; - ::Window* children; - unsigned int num_children; - if (!XQueryTree(cache->display(), window, &root, &parent, &children, - &num_children)) { - RTC_LOG(LS_ERROR) << "Failed to query for child windows although window" - "does not have a valid WM_STATE."; - return 0; - } - ::Window app_window = 0; - for (unsigned int i = 0; i < num_children; ++i) { - app_window = GetApplicationWindow(cache, children[i]); - if (app_window) - break; - } - - if (children) - XFree(children); - return app_window; -} - -// Returns true if the |window| is a desktop element. -bool IsDesktopElement(XAtomCache* cache, ::Window window) { - RTC_DCHECK(cache); - if (window == 0) - return false; - - // First look for _NET_WM_WINDOW_TYPE. The standard - // (http://standards.freedesktop.org/wm-spec/latest/ar01s05.html#id2760306) - // says this hint *should* be present on all windows, and we use the existence - // of _NET_WM_WINDOW_TYPE_NORMAL in the property to indicate a window is not - // a desktop element (that is, only "normal" windows should be shareable). - XWindowProperty window_type(cache->display(), window, - cache->WindowType()); - if (window_type.is_valid() && window_type.size() > 0) { - uint32_t* end = window_type.data() + window_type.size(); - bool is_normal = - (end != std::find(window_type.data(), end, cache->WindowTypeNormal())); - return !is_normal; - } - - // Fall back on using the hint. - XClassHint class_hint; - Status status = XGetClassHint(cache->display(), window, &class_hint); - if (status == 0) { - // No hints, assume this is a normal application window. - return false; - } - - DeferXFree free_res_name(class_hint.res_name); - DeferXFree free_res_class(class_hint.res_class); - return strcmp("gnome-panel", class_hint.res_name) == 0 || - strcmp("desktop_window", class_hint.res_name) == 0; -} - -} // namespace - -int32_t GetWindowState(XAtomCache* cache, ::Window window) { - // Get WM_STATE property of the window. - XWindowProperty window_state(cache->display(), window, - cache->WmState()); - - // WM_STATE is considered to be set to WithdrawnState when it missing. - return window_state.is_valid() ? *window_state.data() : WithdrawnState; -} - -bool GetWindowList(XAtomCache* cache, - rtc::FunctionView on_window) { - RTC_DCHECK(cache); - RTC_DCHECK(on_window); - ::Display* const display = cache->display(); - - int failed_screens = 0; - const int num_screens = XScreenCount(display); - for (int screen = 0; screen < num_screens; screen++) { - ::Window root_window = XRootWindow(display, screen); - ::Window parent; - ::Window* children; - unsigned int num_children; - { - XErrorTrap error_trap(display); - if (XQueryTree(display, root_window, &root_window, &parent, &children, - &num_children) == 0 || - error_trap.GetLastErrorAndDisable() != 0) { - failed_screens++; - RTC_LOG(LS_ERROR) << "Failed to query for child windows for screen " - << screen; - continue; - } - } - - DeferXFree free_children(children); - - for (unsigned int i = 0; i < num_children; i++) { - // Iterates in reverse order to return windows from front to back. - ::Window app_window = - GetApplicationWindow(cache, children[num_children - 1 - i]); - if (app_window && !IsDesktopElement(cache, app_window)) { - if (!on_window(app_window)) { - return true; - } - } - } - } - - return failed_screens < num_screens; -} - -bool GetWindowRect(::Display* display, - ::Window window, - DesktopRect* rect, - XWindowAttributes* attributes /* = nullptr */) { - XWindowAttributes local_attributes; - int offset_x; - int offset_y; - if (attributes == nullptr) { - attributes = &local_attributes; - } - - { - XErrorTrap error_trap(display); - if (!XGetWindowAttributes(display, window, attributes) || - error_trap.GetLastErrorAndDisable() != 0) { - return false; - } - } - *rect = DesktopRectFromXAttributes(*attributes); - - { - XErrorTrap error_trap(display); - ::Window child; - if (!XTranslateCoordinates(display, window, attributes->root, -rect->left(), - -rect->top(), &offset_x, &offset_y, &child) || - error_trap.GetLastErrorAndDisable() != 0) { - return false; - } - } - rect->Translate(offset_x, offset_y); - return true; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_list_utils.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_list_utils.h deleted file mode 100644 index 243680d34..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/window_list_utils.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_LIST_UTILS_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_LIST_UTILS_H_ - -#include -#include -#include - -#include "api/function_view.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/linux/x_atom_cache.h" - -namespace webrtc { - -// Synchronously iterates all on-screen windows in |cache|.display() in -// decreasing z-order and sends them one-by-one to |on_window| function before -// GetWindowList() returns. If |on_window| returns false, this function ignores -// other windows and returns immediately. GetWindowList() returns false if -// native APIs failed. If multiple screens are attached to the |display|, this -// function returns false only when native APIs failed on all screens. Menus, -// panels and minimized windows will be ignored. -bool GetWindowList(XAtomCache* cache, - rtc::FunctionView on_window); - -// Returns WM_STATE property of the |window|. This function returns -// WithdrawnState if the |window| is missing. -int32_t GetWindowState(XAtomCache* cache, ::Window window); - -// Returns the rectangle of the |window| in the coordinates of |display|. This -// function returns false if native APIs failed. If |attributes| is provided, it -// will be filled with the attributes of |window|. The |rect| is in system -// coordinate, i.e. the primary monitor always starts from (0, 0). -bool GetWindowRect(::Display* display, - ::Window window, - DesktopRect* rect, - XWindowAttributes* attributes = nullptr); - -// Creates a DesktopRect from |attributes|. -template -DesktopRect DesktopRectFromXAttributes(const T& attributes) { - return DesktopRect::MakeXYWH(attributes.x, attributes.y, attributes.width, - attributes.height); -} - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_LIST_UTILS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_atom_cache.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_atom_cache.cc deleted file mode 100644 index 4ea024938..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_atom_cache.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/linux/x_atom_cache.h" - -#include "rtc_base/checks.h" - -namespace webrtc { - -XAtomCache::XAtomCache(::Display* display) : display_(display) { - RTC_DCHECK(display_); -} - -XAtomCache::~XAtomCache() = default; - -::Display* XAtomCache::display() const { - return display_; -} - -Atom XAtomCache::WmState() { - return CreateIfNotExist(&wm_state_, "WM_STATE"); -} - -Atom XAtomCache::WindowType() { - return CreateIfNotExist(&window_type_, "_NET_WM_WINDOW_TYPE"); -} - -Atom XAtomCache::WindowTypeNormal() { - return CreateIfNotExist(&window_type_normal_, "_NET_WM_WINDOW_TYPE_NORMAL"); -} - -Atom XAtomCache::IccProfile() { - return CreateIfNotExist(&icc_profile_, "_ICC_PROFILE"); -} - -Atom XAtomCache::CreateIfNotExist(Atom* atom, const char* name) { - RTC_DCHECK(atom); - if (*atom == None) { - *atom = XInternAtom(display(), name, True); - } - return *atom; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_atom_cache.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_atom_cache.h deleted file mode 100644 index 0249c1597..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_atom_cache.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_X_ATOM_CACHE_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_X_ATOM_CACHE_H_ - -#include -#include - -namespace webrtc { - -// A cache of Atom. Each Atom object is created on demand. -class XAtomCache final { - public: - explicit XAtomCache(::Display* display); - ~XAtomCache(); - - ::Display* display() const; - - Atom WmState(); - Atom WindowType(); - Atom WindowTypeNormal(); - Atom IccProfile(); - - private: - // If |*atom| is None, this function uses XInternAtom() to retrieve an Atom. - Atom CreateIfNotExist(Atom* atom, const char* name); - - ::Display* const display_; - Atom wm_state_ = None; - Atom window_type_ = None; - Atom window_type_normal_ = None; - Atom icc_profile_ = None; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_X_ATOM_CACHE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_error_trap.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_error_trap.cc deleted file mode 100644 index 53c907fc4..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_error_trap.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/linux/x_error_trap.h" - -#include -#include - -#if defined(TOOLKIT_GTK) -#include -#endif // !defined(TOOLKIT_GTK) - -namespace webrtc { - -namespace { - -#if !defined(TOOLKIT_GTK) - -// TODO(sergeyu): This code is not thread safe. Fix it. Bug 2202. -static bool g_xserver_error_trap_enabled = false; -static int g_last_xserver_error_code = 0; - -int XServerErrorHandler(Display* display, XErrorEvent* error_event) { - assert(g_xserver_error_trap_enabled); - g_last_xserver_error_code = error_event->error_code; - return 0; -} - -#endif // !defined(TOOLKIT_GTK) - -} // namespace - -XErrorTrap::XErrorTrap(Display* display) - : original_error_handler_(NULL), enabled_(true) { -#if defined(TOOLKIT_GTK) - gdk_error_trap_push(); -#else // !defined(TOOLKIT_GTK) - assert(!g_xserver_error_trap_enabled); - original_error_handler_ = XSetErrorHandler(&XServerErrorHandler); - g_xserver_error_trap_enabled = true; - g_last_xserver_error_code = 0; -#endif // !defined(TOOLKIT_GTK) -} - -int XErrorTrap::GetLastErrorAndDisable() { - enabled_ = false; -#if defined(TOOLKIT_GTK) - return gdk_error_trap_push(); -#else // !defined(TOOLKIT_GTK) - assert(g_xserver_error_trap_enabled); - XSetErrorHandler(original_error_handler_); - g_xserver_error_trap_enabled = false; - return g_last_xserver_error_code; -#endif // !defined(TOOLKIT_GTK) -} - -XErrorTrap::~XErrorTrap() { - if (enabled_) - GetLastErrorAndDisable(); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_error_trap.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_error_trap.h deleted file mode 100644 index 1fb0fdcc9..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_error_trap.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_X_ERROR_TRAP_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_X_ERROR_TRAP_H_ - -#include - -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -// Helper class that registers X Window error handler. Caller can use -// GetLastErrorAndDisable() to get the last error that was caught, if any. -class XErrorTrap { - public: - explicit XErrorTrap(Display* display); - ~XErrorTrap(); - - // Returns last error and removes unregisters the error handler. - int GetLastErrorAndDisable(); - - private: - XErrorHandler original_error_handler_; - bool enabled_; - - RTC_DISALLOW_COPY_AND_ASSIGN(XErrorTrap); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_X_ERROR_TRAP_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.cc deleted file mode 100644 index d3b568d98..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.cc +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/linux/x_server_pixel_buffer.h" - -#include -#include -#include -#include -#include - -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/linux/window_list_utils.h" -#include "modules/desktop_capture/linux/x_error_trap.h" -#include "modules/desktop_capture/linux/x_window_property.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { - -namespace { - -// Returns the number of bits |mask| has to be shifted left so its last -// (most-significant) bit set becomes the most-significant bit of the word. -// When |mask| is 0 the function returns 31. -uint32_t MaskToShift(uint32_t mask) { - int shift = 0; - if ((mask & 0xffff0000u) == 0) { - mask <<= 16; - shift += 16; - } - if ((mask & 0xff000000u) == 0) { - mask <<= 8; - shift += 8; - } - if ((mask & 0xf0000000u) == 0) { - mask <<= 4; - shift += 4; - } - if ((mask & 0xc0000000u) == 0) { - mask <<= 2; - shift += 2; - } - if ((mask & 0x80000000u) == 0) - shift += 1; - - return shift; -} - -// Returns true if |image| is in RGB format. -bool IsXImageRGBFormat(XImage* image) { - return image->bits_per_pixel == 32 && image->red_mask == 0xff0000 && - image->green_mask == 0xff00 && image->blue_mask == 0xff; -} - -// We expose two forms of blitting to handle variations in the pixel format. -// In FastBlit(), the operation is effectively a memcpy. -void FastBlit(XImage* x_image, - uint8_t* src_pos, - const DesktopRect& rect, - DesktopFrame* frame) { - RTC_DCHECK_LE(frame->top_left().x(), rect.left()); - RTC_DCHECK_LE(frame->top_left().y(), rect.top()); - - int src_stride = x_image->bytes_per_line; - int dst_x = rect.left() - frame->top_left().x(); - int dst_y = rect.top() - frame->top_left().y(); - - uint8_t* dst_pos = frame->data() + frame->stride() * dst_y; - dst_pos += dst_x * DesktopFrame::kBytesPerPixel; - - int height = rect.height(); - int row_bytes = rect.width() * DesktopFrame::kBytesPerPixel; - for (int y = 0; y < height; ++y) { - memcpy(dst_pos, src_pos, row_bytes); - src_pos += src_stride; - dst_pos += frame->stride(); - } -} - -void SlowBlit(XImage* x_image, - uint8_t* src_pos, - const DesktopRect& rect, - DesktopFrame* frame) { - RTC_DCHECK_LE(frame->top_left().x(), rect.left()); - RTC_DCHECK_LE(frame->top_left().y(), rect.top()); - - int src_stride = x_image->bytes_per_line; - int dst_x = rect.left() - frame->top_left().x(); - int dst_y = rect.top() - frame->top_left().y(); - int width = rect.width(), height = rect.height(); - - uint32_t red_mask = x_image->red_mask; - uint32_t green_mask = x_image->red_mask; - uint32_t blue_mask = x_image->blue_mask; - - uint32_t red_shift = MaskToShift(red_mask); - uint32_t green_shift = MaskToShift(green_mask); - uint32_t blue_shift = MaskToShift(blue_mask); - - int bits_per_pixel = x_image->bits_per_pixel; - - uint8_t* dst_pos = frame->data() + frame->stride() * dst_y; - dst_pos += dst_x * DesktopFrame::kBytesPerPixel; - // TODO(hclam): Optimize, perhaps using MMX code or by converting to - // YUV directly. - // TODO(sergeyu): This code doesn't handle XImage byte order properly and - // won't work with 24bpp images. Fix it. - for (int y = 0; y < height; y++) { - uint32_t* dst_pos_32 = reinterpret_cast(dst_pos); - uint32_t* src_pos_32 = reinterpret_cast(src_pos); - uint16_t* src_pos_16 = reinterpret_cast(src_pos); - for (int x = 0; x < width; x++) { - // Dereference through an appropriately-aligned pointer. - uint32_t pixel; - if (bits_per_pixel == 32) { - pixel = src_pos_32[x]; - } else if (bits_per_pixel == 16) { - pixel = src_pos_16[x]; - } else { - pixel = src_pos[x]; - } - uint32_t r = (pixel & red_mask) << red_shift; - uint32_t g = (pixel & green_mask) << green_shift; - uint32_t b = (pixel & blue_mask) << blue_shift; - // Write as 32-bit RGB. - dst_pos_32[x] = - ((r >> 8) & 0xff0000) | ((g >> 16) & 0xff00) | ((b >> 24) & 0xff); - } - dst_pos += frame->stride(); - src_pos += src_stride; - } -} - -} // namespace - -XServerPixelBuffer::XServerPixelBuffer() {} - -XServerPixelBuffer::~XServerPixelBuffer() { - Release(); -} - -void XServerPixelBuffer::Release() { - if (x_image_) { - XDestroyImage(x_image_); - x_image_ = nullptr; - } - if (x_shm_image_) { - XDestroyImage(x_shm_image_); - x_shm_image_ = nullptr; - } - if (shm_pixmap_) { - XFreePixmap(display_, shm_pixmap_); - shm_pixmap_ = 0; - } - if (shm_gc_) { - XFreeGC(display_, shm_gc_); - shm_gc_ = nullptr; - } - - ReleaseSharedMemorySegment(); - - window_ = 0; -} - -void XServerPixelBuffer::ReleaseSharedMemorySegment() { - if (!shm_segment_info_) - return; - if (shm_segment_info_->shmaddr != nullptr) - shmdt(shm_segment_info_->shmaddr); - if (shm_segment_info_->shmid != -1) - shmctl(shm_segment_info_->shmid, IPC_RMID, 0); - delete shm_segment_info_; - shm_segment_info_ = nullptr; -} - -bool XServerPixelBuffer::Init(XAtomCache* cache, Window window) { - Release(); - display_ = cache->display(); - - XWindowAttributes attributes; - if (!GetWindowRect(display_, window, &window_rect_, &attributes)) { - return false; - } - - if (cache->IccProfile() != None) { - // |window| is the root window when doing screen capture. - XWindowProperty icc_profile_property(cache->display(), window, - cache->IccProfile()); - if (icc_profile_property.is_valid() && icc_profile_property.size() > 0) { - icc_profile_ = std::vector( - icc_profile_property.data(), - icc_profile_property.data() + icc_profile_property.size()); - } else { - RTC_LOG(LS_WARNING) << "Failed to get icc profile"; - } - } - - window_ = window; - InitShm(attributes); - - return true; -} - -void XServerPixelBuffer::InitShm(const XWindowAttributes& attributes) { - Visual* default_visual = attributes.visual; - int default_depth = attributes.depth; - - int major, minor; - Bool have_pixmaps; - if (!XShmQueryVersion(display_, &major, &minor, &have_pixmaps)) { - // Shared memory not supported. CaptureRect will use the XImage API instead. - return; - } - - bool using_shm = false; - shm_segment_info_ = new XShmSegmentInfo; - shm_segment_info_->shmid = -1; - shm_segment_info_->shmaddr = nullptr; - shm_segment_info_->readOnly = False; - x_shm_image_ = XShmCreateImage(display_, default_visual, default_depth, - ZPixmap, 0, shm_segment_info_, - window_rect_.width(), window_rect_.height()); - if (x_shm_image_) { - shm_segment_info_->shmid = - shmget(IPC_PRIVATE, x_shm_image_->bytes_per_line * x_shm_image_->height, - IPC_CREAT | 0600); - if (shm_segment_info_->shmid != -1) { - void* shmat_result = shmat(shm_segment_info_->shmid, 0, 0); - if (shmat_result != reinterpret_cast(-1)) { - shm_segment_info_->shmaddr = reinterpret_cast(shmat_result); - x_shm_image_->data = shm_segment_info_->shmaddr; - - XErrorTrap error_trap(display_); - using_shm = XShmAttach(display_, shm_segment_info_); - XSync(display_, False); - if (error_trap.GetLastErrorAndDisable() != 0) - using_shm = false; - if (using_shm) { - RTC_LOG(LS_VERBOSE) - << "Using X shared memory segment " << shm_segment_info_->shmid; - } - } - } else { - RTC_LOG(LS_WARNING) << "Failed to get shared memory segment. " - "Performance may be degraded."; - } - } - - if (!using_shm) { - RTC_LOG(LS_WARNING) - << "Not using shared memory. Performance may be degraded."; - ReleaseSharedMemorySegment(); - return; - } - - if (have_pixmaps) - have_pixmaps = InitPixmaps(default_depth); - - shmctl(shm_segment_info_->shmid, IPC_RMID, 0); - shm_segment_info_->shmid = -1; - - RTC_LOG(LS_VERBOSE) << "Using X shared memory extension v" << major << "." - << minor << " with" << (have_pixmaps ? "" : "out") - << " pixmaps."; -} - -bool XServerPixelBuffer::InitPixmaps(int depth) { - if (XShmPixmapFormat(display_) != ZPixmap) - return false; - - { - XErrorTrap error_trap(display_); - shm_pixmap_ = XShmCreatePixmap( - display_, window_, shm_segment_info_->shmaddr, shm_segment_info_, - window_rect_.width(), window_rect_.height(), depth); - XSync(display_, False); - if (error_trap.GetLastErrorAndDisable() != 0) { - // |shm_pixmap_| is not not valid because the request was not processed - // by the X Server, so zero it. - shm_pixmap_ = 0; - return false; - } - } - - { - XErrorTrap error_trap(display_); - XGCValues shm_gc_values; - shm_gc_values.subwindow_mode = IncludeInferiors; - shm_gc_values.graphics_exposures = False; - shm_gc_ = XCreateGC(display_, window_, - GCSubwindowMode | GCGraphicsExposures, &shm_gc_values); - XSync(display_, False); - if (error_trap.GetLastErrorAndDisable() != 0) { - XFreePixmap(display_, shm_pixmap_); - shm_pixmap_ = 0; - shm_gc_ = 0; // See shm_pixmap_ comment above. - return false; - } - } - - return true; -} - -bool XServerPixelBuffer::IsWindowValid() const { - XWindowAttributes attributes; - { - XErrorTrap error_trap(display_); - if (!XGetWindowAttributes(display_, window_, &attributes) || - error_trap.GetLastErrorAndDisable() != 0) { - return false; - } - } - return true; -} - -void XServerPixelBuffer::Synchronize() { - if (shm_segment_info_ && !shm_pixmap_) { - // XShmGetImage can fail if the display is being reconfigured. - XErrorTrap error_trap(display_); - // XShmGetImage fails if the window is partially out of screen. - xshm_get_image_succeeded_ = - XShmGetImage(display_, window_, x_shm_image_, 0, 0, AllPlanes); - } -} - -bool XServerPixelBuffer::CaptureRect(const DesktopRect& rect, - DesktopFrame* frame) { - RTC_DCHECK_LE(rect.right(), window_rect_.width()); - RTC_DCHECK_LE(rect.bottom(), window_rect_.height()); - - XImage* image; - uint8_t* data; - - if (shm_segment_info_ && (shm_pixmap_ || xshm_get_image_succeeded_)) { - if (shm_pixmap_) { - XCopyArea(display_, window_, shm_pixmap_, shm_gc_, rect.left(), - rect.top(), rect.width(), rect.height(), rect.left(), - rect.top()); - XSync(display_, False); - } - - image = x_shm_image_; - data = reinterpret_cast(image->data) + - rect.top() * image->bytes_per_line + - rect.left() * image->bits_per_pixel / 8; - - } else { - if (x_image_) - XDestroyImage(x_image_); - x_image_ = XGetImage(display_, window_, rect.left(), rect.top(), - rect.width(), rect.height(), AllPlanes, ZPixmap); - if (!x_image_) - return false; - - image = x_image_; - data = reinterpret_cast(image->data); - } - - if (IsXImageRGBFormat(image)) { - FastBlit(image, data, rect, frame); - } else { - SlowBlit(image, data, rect, frame); - } - - if (!icc_profile_.empty()) - frame->set_icc_profile(icc_profile_); - - return true; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.h deleted file mode 100644 index 06dd1a153..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -// Don't include this file in any .h files because it pulls in some X headers. - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_X_SERVER_PIXEL_BUFFER_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_X_SERVER_PIXEL_BUFFER_H_ - -#include -#include - -#include -#include - -#include "modules/desktop_capture/desktop_geometry.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -class DesktopFrame; -class XAtomCache; - -// A class to allow the X server's pixel buffer to be accessed as efficiently -// as possible. -class XServerPixelBuffer { - public: - XServerPixelBuffer(); - ~XServerPixelBuffer(); - - void Release(); - - // Allocate (or reallocate) the pixel buffer for |window|. Returns false in - // case of an error (e.g. window doesn't exist). - bool Init(XAtomCache* cache, Window window); - - bool is_initialized() { return window_ != 0; } - - // Returns the size of the window the buffer was initialized for. - DesktopSize window_size() { return window_rect_.size(); } - - // Returns the rectangle of the window the buffer was initialized for. - const DesktopRect& window_rect() { return window_rect_; } - - // Returns true if the window can be found. - bool IsWindowValid() const; - - // If shared memory is being used without pixmaps, synchronize this pixel - // buffer with the root window contents (otherwise, this is a no-op). - // This is to avoid doing a full-screen capture for each individual - // rectangle in the capture list, when it only needs to be done once at the - // beginning. - void Synchronize(); - - // Capture the specified rectangle and stores it in the |frame|. In the case - // where the full-screen data is captured by Synchronize(), this simply - // returns the pointer without doing any more work. The caller must ensure - // that |rect| is not larger than window_size(). - bool CaptureRect(const DesktopRect& rect, DesktopFrame* frame); - - private: - void ReleaseSharedMemorySegment(); - - void InitShm(const XWindowAttributes& attributes); - bool InitPixmaps(int depth); - - Display* display_ = nullptr; - Window window_ = 0; - DesktopRect window_rect_; - XImage* x_image_ = nullptr; - XShmSegmentInfo* shm_segment_info_ = nullptr; - XImage* x_shm_image_ = nullptr; - Pixmap shm_pixmap_ = 0; - GC shm_gc_ = nullptr; - bool xshm_get_image_succeeded_ = false; - std::vector icc_profile_; - - RTC_DISALLOW_COPY_AND_ASSIGN(XServerPixelBuffer); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_X_SERVER_PIXEL_BUFFER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_window_property.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_window_property.cc deleted file mode 100644 index ba25deec3..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_window_property.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2019 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/desktop_capture/linux/x_window_property.h" - -namespace webrtc { - -XWindowPropertyBase::XWindowPropertyBase(Display* display, - Window window, - Atom property, - int expected_size) { - const int kBitsPerByte = 8; - Atom actual_type; - int actual_format; - unsigned long bytes_after; // NOLINT: type required by XGetWindowProperty - int status = XGetWindowProperty(display, window, property, 0L, ~0L, False, - AnyPropertyType, &actual_type, &actual_format, - &size_, &bytes_after, &data_); - if (status != Success) { - data_ = nullptr; - return; - } - if ((expected_size * kBitsPerByte) != actual_format) { - size_ = 0; - return; - } - - is_valid_ = true; -} - -XWindowPropertyBase::~XWindowPropertyBase() { - if (data_) - XFree(data_); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_window_property.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_window_property.h deleted file mode 100644 index ef643b6a8..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/linux/x_window_property.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_X_WINDOW_PROPERTY_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_X_WINDOW_PROPERTY_H_ - -#include -#include - -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -class XWindowPropertyBase { - public: - XWindowPropertyBase(Display* display, - Window window, - Atom property, - int expected_size); - virtual ~XWindowPropertyBase(); - - // True if we got properly value successfully. - bool is_valid() const { return is_valid_; } - - // Size and value of the property. - size_t size() const { return size_; } - - protected: - unsigned char* data_ = nullptr; - - private: - bool is_valid_ = false; - unsigned long size_ = 0; // NOLINT: type required by XGetWindowProperty - - RTC_DISALLOW_COPY_AND_ASSIGN(XWindowPropertyBase); -}; - -// Convenience wrapper for XGetWindowProperty() results. -template -class XWindowProperty : public XWindowPropertyBase { - public: - XWindowProperty(Display* display, const Window window, const Atom property) - : XWindowPropertyBase(display, window, property, sizeof(PropertyType)) {} - ~XWindowProperty() override = default; - - const PropertyType* data() const { - return reinterpret_cast(data_); - } - PropertyType* data() { return reinterpret_cast(data_); } - - RTC_DISALLOW_COPY_AND_ASSIGN(XWindowProperty); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_LINUX_X_WINDOW_PROPERTY_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mock_desktop_capturer_callback.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mock_desktop_capturer_callback.cc deleted file mode 100644 index de77d99e1..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mock_desktop_capturer_callback.cc +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2016 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/desktop_capture/mock_desktop_capturer_callback.h" - -namespace webrtc { - -MockDesktopCapturerCallback::MockDesktopCapturerCallback() = default; -MockDesktopCapturerCallback::~MockDesktopCapturerCallback() = default; - -void MockDesktopCapturerCallback::OnCaptureResult( - DesktopCapturer::Result result, - std::unique_ptr frame) { - OnCaptureResultPtr(result, &frame); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mock_desktop_capturer_callback.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mock_desktop_capturer_callback.h deleted file mode 100644 index 6530dc554..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mock_desktop_capturer_callback.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2016 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_MOCK_DESKTOP_CAPTURER_CALLBACK_H_ -#define MODULES_DESKTOP_CAPTURE_MOCK_DESKTOP_CAPTURER_CALLBACK_H_ - -#include - -#include "modules/desktop_capture/desktop_capturer.h" -#include "test/gmock.h" - -namespace webrtc { - -class MockDesktopCapturerCallback : public DesktopCapturer::Callback { - public: - MockDesktopCapturerCallback(); - ~MockDesktopCapturerCallback() override; - - MOCK_METHOD(void, - OnCaptureResultPtr, - (DesktopCapturer::Result result, - std::unique_ptr* frame)); - void OnCaptureResult(DesktopCapturer::Result result, - std::unique_ptr frame) final; - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(MockDesktopCapturerCallback); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_MOCK_DESKTOP_CAPTURER_CALLBACK_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor.cc deleted file mode 100644 index 3b61e10a8..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/mouse_cursor.h" - -#include - -#include "modules/desktop_capture/desktop_frame.h" - -namespace webrtc { - -MouseCursor::MouseCursor() {} - -MouseCursor::MouseCursor(DesktopFrame* image, const DesktopVector& hotspot) - : image_(image), hotspot_(hotspot) { - assert(0 <= hotspot_.x() && hotspot_.x() <= image_->size().width()); - assert(0 <= hotspot_.y() && hotspot_.y() <= image_->size().height()); -} - -MouseCursor::~MouseCursor() {} - -// static -MouseCursor* MouseCursor::CopyOf(const MouseCursor& cursor) { - return cursor.image() - ? new MouseCursor(BasicDesktopFrame::CopyOf(*cursor.image()), - cursor.hotspot()) - : new MouseCursor(); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor.h deleted file mode 100644 index 2263610ed..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_H_ -#define MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_H_ - -#include - -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -class RTC_EXPORT MouseCursor { - public: - MouseCursor(); - - // Takes ownership of |image|. |hotspot| must be within |image| boundaries. - MouseCursor(DesktopFrame* image, const DesktopVector& hotspot); - - ~MouseCursor(); - - static MouseCursor* CopyOf(const MouseCursor& cursor); - - void set_image(DesktopFrame* image) { image_.reset(image); } - const DesktopFrame* image() const { return image_.get(); } - - void set_hotspot(const DesktopVector& hotspot) { hotspot_ = hotspot; } - const DesktopVector& hotspot() const { return hotspot_; } - - private: - std::unique_ptr image_; - DesktopVector hotspot_; - - RTC_DISALLOW_COPY_AND_ASSIGN(MouseCursor); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor.h deleted file mode 100644 index 43b75b3f7..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_MONITOR_H_ -#define MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_MONITOR_H_ - -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -class DesktopCaptureOptions; -class DesktopFrame; -class MouseCursor; - -// Captures mouse shape and position. -class MouseCursorMonitor { - public: - // Deprecated: CursorState will not be provided. - enum CursorState { - // Cursor on top of the window including window decorations. - INSIDE, - - // Cursor is outside of the window. - OUTSIDE, - }; - - enum Mode { - // Capture only shape of the mouse cursor, but not position. - SHAPE_ONLY, - - // Capture both, mouse cursor shape and position. - SHAPE_AND_POSITION, - }; - - // Callback interface used to pass current mouse cursor position and shape. - class Callback { - public: - // Called in response to Capture() when the cursor shape has changed. Must - // take ownership of |cursor|. - virtual void OnMouseCursor(MouseCursor* cursor) = 0; - - // Called in response to Capture(). |position| indicates cursor position - // relative to the |window| specified in the constructor. - // Deprecated: use the following overload instead. - virtual void OnMouseCursorPosition(CursorState state, - const DesktopVector& position) {} - - // Called in response to Capture(). |position| indicates cursor absolute - // position on the system in fullscreen coordinate, i.e. the top-left - // monitor always starts from (0, 0). - // The coordinates of the position is controlled by OS, but it's always - // consistent with DesktopFrame.rect().top_left(). - // TODO(zijiehe): Ensure all implementations return the absolute position. - // TODO(zijiehe): Current this overload works correctly only when capturing - // mouse cursor against fullscreen. - virtual void OnMouseCursorPosition(const DesktopVector& position) {} - - protected: - virtual ~Callback() {} - }; - - virtual ~MouseCursorMonitor() {} - - // Creates a capturer that notifies of mouse cursor events while the cursor is - // over the specified window. - // - // Deprecated: use Create() function. - static MouseCursorMonitor* CreateForWindow( - const DesktopCaptureOptions& options, - WindowId window); - - // Creates a capturer that monitors the mouse cursor shape and position over - // the specified screen. - // - // Deprecated: use Create() function. - static RTC_EXPORT MouseCursorMonitor* CreateForScreen( - const DesktopCaptureOptions& options, - ScreenId screen); - - // Creates a capturer that monitors the mouse cursor shape and position across - // the entire desktop. The capturer ensures that the top-left monitor starts - // from (0, 0). - static std::unique_ptr Create( - const DesktopCaptureOptions& options); - - // Initializes the monitor with the |callback|, which must remain valid until - // capturer is destroyed. - virtual void Init(Callback* callback, Mode mode) = 0; - - // Captures current cursor shape and position (depending on the |mode| passed - // to Init()). Calls Callback::OnMouseCursor() if cursor shape has - // changed since the last call (or when Capture() is called for the first - // time) and then Callback::OnMouseCursorPosition() if mode is set to - // SHAPE_AND_POSITION. - virtual void Capture() = 0; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_MONITOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc deleted file mode 100644 index e569f6ef3..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 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 - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/mouse_cursor_monitor.h" - -#if defined(WEBRTC_USE_X11) -#include "modules/desktop_capture/linux/mouse_cursor_monitor_x11.h" -#endif // defined(WEBRTC_USE_X11) - -namespace webrtc { - -// static -MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( - const DesktopCaptureOptions& options, - WindowId window) { -#if defined(WEBRTC_USE_X11) - return MouseCursorMonitorX11::CreateForWindow(options, window); -#else - return nullptr; -#endif // defined(WEBRTC_USE_X11) -} - -// static -MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( - const DesktopCaptureOptions& options, - ScreenId screen) { -#if defined(WEBRTC_USE_X11) - return MouseCursorMonitorX11::CreateForScreen(options, screen); -#else - return nullptr; -#endif // defined(WEBRTC_USE_X11) -} - -// static -std::unique_ptr MouseCursorMonitor::Create( - const DesktopCaptureOptions& options) { -#if defined(WEBRTC_USE_X11) - return MouseCursorMonitorX11::Create(options); -#else - return nullptr; -#endif // defined(WEBRTC_USE_X11) -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm deleted file mode 100644 index 31ad428e0..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/mouse_cursor_monitor.h" - -#include - -#include - -#include -#include -#include - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/mac/desktop_configuration.h" -#include "modules/desktop_capture/mac/desktop_configuration_monitor.h" -#include "modules/desktop_capture/mac/window_list_utils.h" -#include "modules/desktop_capture/mouse_cursor.h" - -namespace webrtc { - -namespace { -CGImageRef CreateScaledCGImage(CGImageRef image, int width, int height) { - // Create context, keeping original image properties. - CGColorSpaceRef colorspace = CGImageGetColorSpace(image); - CGContextRef context = CGBitmapContextCreate(nullptr, - width, - height, - CGImageGetBitsPerComponent(image), - width * DesktopFrame::kBytesPerPixel, - colorspace, - CGImageGetBitmapInfo(image)); - - if (!context) return nil; - - // Draw image to context, resizing it. - CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); - // Extract resulting image from context. - CGImageRef imgRef = CGBitmapContextCreateImage(context); - CGContextRelease(context); - - return imgRef; -} -} // namespace - -class MouseCursorMonitorMac : public MouseCursorMonitor { - public: - MouseCursorMonitorMac(const DesktopCaptureOptions& options, - CGWindowID window_id, - ScreenId screen_id); - ~MouseCursorMonitorMac() override; - - void Init(Callback* callback, Mode mode) override; - void Capture() override; - - private: - static void DisplaysReconfiguredCallback(CGDirectDisplayID display, - CGDisplayChangeSummaryFlags flags, - void *user_parameter); - void DisplaysReconfigured(CGDirectDisplayID display, - CGDisplayChangeSummaryFlags flags); - - void CaptureImage(float scale); - - rtc::scoped_refptr configuration_monitor_; - CGWindowID window_id_; - ScreenId screen_id_; - Callback* callback_; - Mode mode_; - __strong NSImage* last_cursor_; -}; - -MouseCursorMonitorMac::MouseCursorMonitorMac(const DesktopCaptureOptions& options, - CGWindowID window_id, - ScreenId screen_id) - : configuration_monitor_(options.configuration_monitor()), - window_id_(window_id), - screen_id_(screen_id), - callback_(NULL), - mode_(SHAPE_AND_POSITION) { - assert(window_id == kCGNullWindowID || screen_id == kInvalidScreenId); -} - -MouseCursorMonitorMac::~MouseCursorMonitorMac() {} - -void MouseCursorMonitorMac::Init(Callback* callback, Mode mode) { - assert(!callback_); - assert(callback); - - callback_ = callback; - mode_ = mode; -} - -void MouseCursorMonitorMac::Capture() { - assert(callback_); - - CGEventRef event = CGEventCreate(NULL); - CGPoint gc_position = CGEventGetLocation(event); - CFRelease(event); - - DesktopVector position(gc_position.x, gc_position.y); - - MacDesktopConfiguration configuration = - configuration_monitor_->desktop_configuration(); - float scale = GetScaleFactorAtPosition(configuration, position); - - CaptureImage(scale); - - if (mode_ != SHAPE_AND_POSITION) - return; - - // Always report cursor position in DIP pixel. - callback_->OnMouseCursorPosition( - position.subtract(configuration.bounds.top_left())); -} - -void MouseCursorMonitorMac::CaptureImage(float scale) { - NSCursor* nscursor = [NSCursor currentSystemCursor]; - - NSImage* nsimage = [nscursor image]; - if (nsimage == nil || !nsimage.isValid) { - return; - } - NSSize nssize = [nsimage size]; // DIP size - - // No need to caputre cursor image if it's unchanged since last capture. - if ([[nsimage TIFFRepresentation] isEqual:[last_cursor_ TIFFRepresentation]]) return; - last_cursor_ = nsimage; - - DesktopSize size(round(nssize.width * scale), - round(nssize.height * scale)); // Pixel size - NSPoint nshotspot = [nscursor hotSpot]; - DesktopVector hotspot( - std::max(0, - std::min(size.width(), static_cast(nshotspot.x * scale))), - std::max(0, - std::min(size.height(), static_cast(nshotspot.y * scale)))); - CGImageRef cg_image = - [nsimage CGImageForProposedRect:NULL context:nil hints:nil]; - if (!cg_image) - return; - - // Before 10.12, OSX may report 1X cursor on Retina screen. (See - // crbug.com/632995.) After 10.12, OSX may report 2X cursor on non-Retina - // screen. (See crbug.com/671436.) So scaling the cursor if needed. - CGImageRef scaled_cg_image = nil; - if (CGImageGetWidth(cg_image) != static_cast(size.width())) { - scaled_cg_image = CreateScaledCGImage(cg_image, size.width(), size.height()); - if (scaled_cg_image != nil) { - cg_image = scaled_cg_image; - } - } - if (CGImageGetBitsPerPixel(cg_image) != DesktopFrame::kBytesPerPixel * 8 || - CGImageGetWidth(cg_image) != static_cast(size.width()) || - CGImageGetBitsPerComponent(cg_image) != 8) { - if (scaled_cg_image != nil) CGImageRelease(scaled_cg_image); - return; - } - - CGDataProviderRef provider = CGImageGetDataProvider(cg_image); - CFDataRef image_data_ref = CGDataProviderCopyData(provider); - if (image_data_ref == NULL) { - if (scaled_cg_image != nil) CGImageRelease(scaled_cg_image); - return; - } - - const uint8_t* src_data = - reinterpret_cast(CFDataGetBytePtr(image_data_ref)); - - // Create a MouseCursor that describes the cursor and pass it to - // the client. - std::unique_ptr image( - new BasicDesktopFrame(DesktopSize(size.width(), size.height()))); - - int src_stride = CGImageGetBytesPerRow(cg_image); - image->CopyPixelsFrom(src_data, src_stride, DesktopRect::MakeSize(size)); - - CFRelease(image_data_ref); - if (scaled_cg_image != nil) CGImageRelease(scaled_cg_image); - - std::unique_ptr cursor( - new MouseCursor(image.release(), hotspot)); - - callback_->OnMouseCursor(cursor.release()); -} - -MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( - const DesktopCaptureOptions& options, WindowId window) { - return new MouseCursorMonitorMac(options, window, kInvalidScreenId); -} - -MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( - const DesktopCaptureOptions& options, - ScreenId screen) { - return new MouseCursorMonitorMac(options, kCGNullWindowID, screen); -} - -std::unique_ptr MouseCursorMonitor::Create( - const DesktopCaptureOptions& options) { - return std::unique_ptr( - CreateForScreen(options, kFullDesktopScreenId)); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc deleted file mode 100644 index ab1bc2fa3..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 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 - -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/mouse_cursor_monitor.h" - -namespace webrtc { - -MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( - const DesktopCaptureOptions& options, - WindowId window) { - return NULL; -} - -MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( - const DesktopCaptureOptions& options, - ScreenId screen) { - return NULL; -} - -std::unique_ptr MouseCursorMonitor::Create( - const DesktopCaptureOptions& options) { - return std::unique_ptr( - CreateForScreen(options, kFullDesktopScreenId)); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc deleted file mode 100644 index bf0d8534e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2013 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 -#include - -#include - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/mouse_cursor.h" -#include "modules/desktop_capture/mouse_cursor_monitor.h" -#include "modules/desktop_capture/win/cursor.h" -#include "modules/desktop_capture/win/screen_capture_utils.h" -#include "modules/desktop_capture/win/window_capture_utils.h" -#include "rtc_base/logging.h" - -namespace webrtc { - -namespace { - -bool IsSameCursorShape(const CURSORINFO& left, const CURSORINFO& right) { - // If the cursors are not showing, we do not care the hCursor handle. - return left.flags == right.flags && - (left.flags != CURSOR_SHOWING || left.hCursor == right.hCursor); -} - -} // namespace - -class MouseCursorMonitorWin : public MouseCursorMonitor { - public: - explicit MouseCursorMonitorWin(HWND window); - explicit MouseCursorMonitorWin(ScreenId screen); - ~MouseCursorMonitorWin() override; - - void Init(Callback* callback, Mode mode) override; - void Capture() override; - - private: - // Get the rect of the currently selected screen, relative to the primary - // display's top-left. If the screen is disabled or disconnected, or any error - // happens, an empty rect is returned. - DesktopRect GetScreenRect(); - - HWND window_; - ScreenId screen_; - - Callback* callback_; - Mode mode_; - - HDC desktop_dc_; - - // The last CURSORINFO (converted to MouseCursor) we have sent to the client. - CURSORINFO last_cursor_; -}; - -MouseCursorMonitorWin::MouseCursorMonitorWin(HWND window) - : window_(window), - screen_(kInvalidScreenId), - callback_(NULL), - mode_(SHAPE_AND_POSITION), - desktop_dc_(NULL) { - memset(&last_cursor_, 0, sizeof(CURSORINFO)); -} - -MouseCursorMonitorWin::MouseCursorMonitorWin(ScreenId screen) - : window_(NULL), - screen_(screen), - callback_(NULL), - mode_(SHAPE_AND_POSITION), - desktop_dc_(NULL) { - assert(screen >= kFullDesktopScreenId); - memset(&last_cursor_, 0, sizeof(CURSORINFO)); -} - -MouseCursorMonitorWin::~MouseCursorMonitorWin() { - if (desktop_dc_) - ReleaseDC(NULL, desktop_dc_); -} - -void MouseCursorMonitorWin::Init(Callback* callback, Mode mode) { - assert(!callback_); - assert(callback); - - callback_ = callback; - mode_ = mode; - - desktop_dc_ = GetDC(NULL); -} - -void MouseCursorMonitorWin::Capture() { - assert(callback_); - - CURSORINFO cursor_info; - cursor_info.cbSize = sizeof(CURSORINFO); - if (!GetCursorInfo(&cursor_info)) { - RTC_LOG_F(LS_ERROR) << "Unable to get cursor info. Error = " - << GetLastError(); - return; - } - - if (!IsSameCursorShape(cursor_info, last_cursor_)) { - if (cursor_info.flags == CURSOR_SUPPRESSED) { - // The cursor is intentionally hidden now, send an empty bitmap. - last_cursor_ = cursor_info; - callback_->OnMouseCursor(new MouseCursor( - new BasicDesktopFrame(DesktopSize()), DesktopVector())); - } else { - // According to MSDN https://goo.gl/u6gyuC, HCURSOR instances returned by - // functions other than CreateCursor do not need to be actively destroyed. - // And CloseHandle function (https://goo.gl/ja5ycW) does not close a - // cursor, so assume a HCURSOR does not need to be closed. - if (cursor_info.flags == 0) { - // Host machine does not have a hardware mouse attached, we will send a - // default one instead. - // Note, Windows automatically caches cursor resource, so we do not need - // to cache the result of LoadCursor. - cursor_info.hCursor = LoadCursor(nullptr, IDC_ARROW); - } - std::unique_ptr cursor( - CreateMouseCursorFromHCursor(desktop_dc_, cursor_info.hCursor)); - if (cursor) { - last_cursor_ = cursor_info; - callback_->OnMouseCursor(cursor.release()); - } - } - } - - if (mode_ != SHAPE_AND_POSITION) - return; - - // CURSORINFO::ptScreenPos is in full desktop coordinate. - DesktopVector position(cursor_info.ptScreenPos.x, cursor_info.ptScreenPos.y); - bool inside = cursor_info.flags == CURSOR_SHOWING; - - if (window_) { - DesktopRect original_rect; - DesktopRect cropped_rect; - if (!GetCroppedWindowRect(window_, /*avoid_cropping_border*/ false, - &cropped_rect, &original_rect)) { - position.set(0, 0); - inside = false; - } else { - if (inside) { - HWND windowUnderCursor = WindowFromPoint(cursor_info.ptScreenPos); - inside = windowUnderCursor - ? (window_ == GetAncestor(windowUnderCursor, GA_ROOT)) - : false; - } - position = position.subtract(cropped_rect.top_left()); - } - } else { - assert(screen_ != kInvalidScreenId); - DesktopRect rect = GetScreenRect(); - if (inside) - inside = rect.Contains(position); - position = position.subtract(rect.top_left()); - } - - callback_->OnMouseCursorPosition(position); -} - -DesktopRect MouseCursorMonitorWin::GetScreenRect() { - assert(screen_ != kInvalidScreenId); - if (screen_ == kFullDesktopScreenId) { - return DesktopRect::MakeXYWH(GetSystemMetrics(SM_XVIRTUALSCREEN), - GetSystemMetrics(SM_YVIRTUALSCREEN), - GetSystemMetrics(SM_CXVIRTUALSCREEN), - GetSystemMetrics(SM_CYVIRTUALSCREEN)); - } - DISPLAY_DEVICE device; - device.cb = sizeof(device); - BOOL result = EnumDisplayDevices(NULL, screen_, &device, 0); - if (!result) - return DesktopRect(); - - DEVMODE device_mode; - device_mode.dmSize = sizeof(device_mode); - device_mode.dmDriverExtra = 0; - result = EnumDisplaySettingsEx(device.DeviceName, ENUM_CURRENT_SETTINGS, - &device_mode, 0); - if (!result) - return DesktopRect(); - - return DesktopRect::MakeXYWH( - device_mode.dmPosition.x, device_mode.dmPosition.y, - device_mode.dmPelsWidth, device_mode.dmPelsHeight); -} - -MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( - const DesktopCaptureOptions& options, - WindowId window) { - return new MouseCursorMonitorWin(reinterpret_cast(window)); -} - -MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( - const DesktopCaptureOptions& options, - ScreenId screen) { - return new MouseCursorMonitorWin(screen); -} - -std::unique_ptr MouseCursorMonitor::Create( - const DesktopCaptureOptions& options) { - return std::unique_ptr( - CreateForScreen(options, kFullDesktopScreenId)); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/resolution_tracker.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/resolution_tracker.cc deleted file mode 100644 index 9639d627f..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/resolution_tracker.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/resolution_tracker.h" - -namespace webrtc { - -bool ResolutionTracker::SetResolution(DesktopSize size) { - if (!initialized_) { - initialized_ = true; - last_size_ = size; - return false; - } - - if (last_size_.equals(size)) { - return false; - } - - last_size_ = size; - return true; -} - -void ResolutionTracker::Reset() { - initialized_ = false; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/resolution_tracker.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/resolution_tracker.h deleted file mode 100644 index 55f25d133..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/resolution_tracker.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_RESOLUTION_TRACKER_H_ -#define MODULES_DESKTOP_CAPTURE_RESOLUTION_TRACKER_H_ - -#include "modules/desktop_capture/desktop_geometry.h" - -namespace webrtc { - -class ResolutionTracker final { - public: - // Sets the resolution to |size|. Returns true if a previous size was recorded - // and differs from |size|. - bool SetResolution(DesktopSize size); - - // Resets to the initial state. - void Reset(); - - private: - DesktopSize last_size_; - bool initialized_ = false; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_RESOLUTION_TRACKER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/rgba_color.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/rgba_color.cc deleted file mode 100644 index 362928a47..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/rgba_color.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016 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/desktop_capture/rgba_color.h" - -#include "rtc_base/system/arch.h" - -namespace webrtc { - -namespace { - -bool AlphaEquals(uint8_t i, uint8_t j) { - // On Linux and Windows 8 or early version, '0' was returned for alpha channel - // from capturer APIs, on Windows 10, '255' was returned. So a workaround is - // to treat 0 as 255. - return i == j || ((i == 0 || i == 255) && (j == 0 || j == 255)); -} - -} // namespace - -RgbaColor::RgbaColor(uint8_t blue, uint8_t green, uint8_t red, uint8_t alpha) { - this->blue = blue; - this->green = green; - this->red = red; - this->alpha = alpha; -} - -RgbaColor::RgbaColor(uint8_t blue, uint8_t green, uint8_t red) - : RgbaColor(blue, green, red, 0xff) {} - -RgbaColor::RgbaColor(const uint8_t* bgra) - : RgbaColor(bgra[0], bgra[1], bgra[2], bgra[3]) {} - -RgbaColor::RgbaColor(uint32_t bgra) - : RgbaColor(reinterpret_cast(&bgra)) {} - -bool RgbaColor::operator==(const RgbaColor& right) const { - return blue == right.blue && green == right.green && red == right.red && - AlphaEquals(alpha, right.alpha); -} - -bool RgbaColor::operator!=(const RgbaColor& right) const { - return !(*this == right); -} - -uint32_t RgbaColor::ToUInt32() const { -#if defined(WEBRTC_ARCH_LITTLE_ENDIAN) - return blue | (green << 8) | (red << 16) | (alpha << 24); -#else - return (blue << 24) | (green << 16) | (red << 8) | alpha; -#endif -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/rgba_color.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/rgba_color.h deleted file mode 100644 index c47c8bc65..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/rgba_color.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_RGBA_COLOR_H_ -#define MODULES_DESKTOP_CAPTURE_RGBA_COLOR_H_ - -#include - -#include "modules/desktop_capture/desktop_frame.h" - -namespace webrtc { - -// A four-byte structure to store a color in BGRA format. This structure also -// provides functions to be created from uint8_t array, say, -// DesktopFrame::data(). It always uses BGRA order for internal storage to match -// DesktopFrame::data(). -struct RgbaColor final { - // Creates a color with BGRA channels. - RgbaColor(uint8_t blue, uint8_t green, uint8_t red, uint8_t alpha); - - // Creates a color with BGR channels, and set alpha channel to 255 (opaque). - RgbaColor(uint8_t blue, uint8_t green, uint8_t red); - - // Creates a color from four-byte in BGRA order, i.e. DesktopFrame::data(). - explicit RgbaColor(const uint8_t* bgra); - - // Creates a color from BGRA channels in a uint format. Consumers should make - // sure the memory order of the uint32_t is always BGRA from left to right, no - // matter the system endian. This function creates an equivalent RgbaColor - // instance from the ToUInt32() result of another RgbaColor instance. - explicit RgbaColor(uint32_t bgra); - - // Returns true if |this| and |right| is the same color. - bool operator==(const RgbaColor& right) const; - - // Returns true if |this| and |right| are different colors. - bool operator!=(const RgbaColor& right) const; - - uint32_t ToUInt32() const; - - uint8_t blue; - uint8_t green; - uint8_t red; - uint8_t alpha; -}; -static_assert( - DesktopFrame::kBytesPerPixel == sizeof(RgbaColor), - "A pixel in DesktopFrame should be safe to be represented by a RgbaColor"); - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_RGBA_COLOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capture_frame_queue.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capture_frame_queue.h deleted file mode 100644 index 40dc6daa2..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capture_frame_queue.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURE_FRAME_QUEUE_H_ -#define MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURE_FRAME_QUEUE_H_ - -#include - -#include "rtc_base/constructor_magic.h" -// TODO(zijiehe): These headers are not used in this file, but to avoid build -// break in remoting/host. We should add headers in each individual files. -#include "modules/desktop_capture/desktop_frame.h" // Remove -#include "modules/desktop_capture/shared_desktop_frame.h" // Remove - -namespace webrtc { - -// Represents a queue of reusable video frames. Provides access to the 'current' -// frame - the frame that the caller is working with at the moment, and to the -// 'previous' frame - the predecessor of the current frame swapped by -// MoveToNextFrame() call, if any. -// -// The caller is expected to (re)allocate frames if current_frame() returns -// NULL. The caller can mark all frames in the queue for reallocation (when, -// say, frame dimensions change). The queue records which frames need updating -// which the caller can query. -// -// Frame consumer is expected to never hold more than kQueueLength frames -// created by this function and it should release the earliest one before trying -// to capture a new frame (i.e. before MoveToNextFrame() is called). -template -class ScreenCaptureFrameQueue { - public: - ScreenCaptureFrameQueue() : current_(0) {} - ~ScreenCaptureFrameQueue() = default; - - // Moves to the next frame in the queue, moving the 'current' frame to become - // the 'previous' one. - void MoveToNextFrame() { current_ = (current_ + 1) % kQueueLength; } - - // Replaces the current frame with a new one allocated by the caller. The - // existing frame (if any) is destroyed. Takes ownership of |frame|. - void ReplaceCurrentFrame(std::unique_ptr frame) { - frames_[current_] = std::move(frame); - } - - // Marks all frames obsolete and resets the previous frame pointer. No - // frames are freed though as the caller can still access them. - void Reset() { - for (int i = 0; i < kQueueLength; i++) { - frames_[i].reset(); - } - current_ = 0; - } - - FrameType* current_frame() const { return frames_[current_].get(); } - - FrameType* previous_frame() const { - return frames_[(current_ + kQueueLength - 1) % kQueueLength].get(); - } - - private: - // Index of the current frame. - int current_; - - static const int kQueueLength = 2; - std::unique_ptr frames_[kQueueLength]; - - RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCaptureFrameQueue); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURE_FRAME_QUEUE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_darwin.mm b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_darwin.mm deleted file mode 100644 index d5a7bb052..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_darwin.mm +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 - -#include "modules/desktop_capture/mac/screen_capturer_mac.h" - -namespace webrtc { - -// static -std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( - const DesktopCaptureOptions& options) { - if (!options.configuration_monitor()) { - return nullptr; - } - - std::unique_ptr capturer(new ScreenCapturerMac( - options.configuration_monitor(), options.detect_updated_region(), options.allow_iosurface())); - if (!capturer.get()->Init()) { - return nullptr; - } - - return capturer; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_helper.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_helper.cc deleted file mode 100644 index 8a23c88be..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_helper.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/screen_capturer_helper.h" - -#include - -namespace webrtc { - -ScreenCapturerHelper::ScreenCapturerHelper() - : invalid_region_lock_(RWLockWrapper::CreateRWLock()), log_grid_size_(0) {} - -ScreenCapturerHelper::~ScreenCapturerHelper() {} - -void ScreenCapturerHelper::ClearInvalidRegion() { - WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_); - invalid_region_.Clear(); -} - -void ScreenCapturerHelper::InvalidateRegion( - const DesktopRegion& invalid_region) { - WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_); - invalid_region_.AddRegion(invalid_region); -} - -void ScreenCapturerHelper::InvalidateScreen(const DesktopSize& size) { - WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_); - invalid_region_.AddRect(DesktopRect::MakeSize(size)); -} - -void ScreenCapturerHelper::TakeInvalidRegion(DesktopRegion* invalid_region) { - invalid_region->Clear(); - - { - WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_); - invalid_region->Swap(&invalid_region_); - } - - if (log_grid_size_ > 0) { - DesktopRegion expanded_region; - ExpandToGrid(*invalid_region, log_grid_size_, &expanded_region); - expanded_region.Swap(invalid_region); - - invalid_region->IntersectWith(DesktopRect::MakeSize(size_most_recent_)); - } -} - -void ScreenCapturerHelper::SetLogGridSize(int log_grid_size) { - log_grid_size_ = log_grid_size; -} - -const DesktopSize& ScreenCapturerHelper::size_most_recent() const { - return size_most_recent_; -} - -void ScreenCapturerHelper::set_size_most_recent(const DesktopSize& size) { - size_most_recent_ = size; -} - -// Returns the largest multiple of |n| that is <= |x|. -// |n| must be a power of 2. |nMask| is ~(|n| - 1). -static int DownToMultiple(int x, int nMask) { - return (x & nMask); -} - -// Returns the smallest multiple of |n| that is >= |x|. -// |n| must be a power of 2. |nMask| is ~(|n| - 1). -static int UpToMultiple(int x, int n, int nMask) { - return ((x + n - 1) & nMask); -} - -void ScreenCapturerHelper::ExpandToGrid(const DesktopRegion& region, - int log_grid_size, - DesktopRegion* result) { - assert(log_grid_size >= 1); - int grid_size = 1 << log_grid_size; - int grid_size_mask = ~(grid_size - 1); - - result->Clear(); - for (DesktopRegion::Iterator it(region); !it.IsAtEnd(); it.Advance()) { - int left = DownToMultiple(it.rect().left(), grid_size_mask); - int right = UpToMultiple(it.rect().right(), grid_size, grid_size_mask); - int top = DownToMultiple(it.rect().top(), grid_size_mask); - int bottom = UpToMultiple(it.rect().bottom(), grid_size, grid_size_mask); - result->AddRect(DesktopRect::MakeLTRB(left, top, right, bottom)); - } -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_helper.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_helper.h deleted file mode 100644 index fc4c85b70..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_helper.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURER_HELPER_H_ -#define MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURER_HELPER_H_ - -#include - -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/desktop_region.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/synchronization/rw_lock_wrapper.h" - -namespace webrtc { - -// ScreenCapturerHelper is intended to be used by an implementation of the -// ScreenCapturer interface. It maintains a thread-safe invalid region, and -// the size of the most recently captured screen, on behalf of the -// ScreenCapturer that owns it. -class ScreenCapturerHelper { - public: - ScreenCapturerHelper(); - ~ScreenCapturerHelper(); - - // Clear out the invalid region. - void ClearInvalidRegion(); - - // Invalidate the specified region. - void InvalidateRegion(const DesktopRegion& invalid_region); - - // Invalidate the entire screen, of a given size. - void InvalidateScreen(const DesktopSize& size); - - // Copies current invalid region to |invalid_region| clears invalid region - // storage for the next frame. - void TakeInvalidRegion(DesktopRegion* invalid_region); - - // Access the size of the most recently captured screen. - const DesktopSize& size_most_recent() const; - void set_size_most_recent(const DesktopSize& size); - - // Lossy compression can result in color values leaking between pixels in one - // block. If part of a block changes, then unchanged parts of that block can - // be changed in the compressed output. So we need to re-render an entire - // block whenever part of the block changes. - // - // If |log_grid_size| is >= 1, then this function makes TakeInvalidRegion() - // produce an invalid region expanded so that its vertices lie on a grid of - // size 2 ^ |log_grid_size|. The expanded region is then clipped to the size - // of the most recently captured screen, as previously set by - // set_size_most_recent(). - // If |log_grid_size| is <= 0, then the invalid region is not expanded. - void SetLogGridSize(int log_grid_size); - - // Expands a region so that its vertices all lie on a grid. - // The grid size must be >= 2, so |log_grid_size| must be >= 1. - static void ExpandToGrid(const DesktopRegion& region, - int log_grid_size, - DesktopRegion* result); - - private: - // A region that has been manually invalidated (through InvalidateRegion). - // These will be returned as dirty_region in the capture data during the next - // capture. - DesktopRegion invalid_region_; - - // A lock protecting |invalid_region_| across threads. - std::unique_ptr invalid_region_lock_; - - // The size of the most recently captured screen. - DesktopSize size_most_recent_; - - // The log (base 2) of the size of the grid to which the invalid region is - // expanded. - // If the value is <= 0, then the invalid region is not expanded to a grid. - int log_grid_size_; - - RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerHelper); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURER_HELPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_linux.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_linux.cc deleted file mode 100644 index 82dbae481..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_linux.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 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 - -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" - -#if defined(WEBRTC_USE_PIPEWIRE) -#include "modules/desktop_capture/linux/screen_capturer_pipewire.h" -#endif // defined(WEBRTC_USE_PIPEWIRE) - -#if defined(WEBRTC_USE_X11) -#include "modules/desktop_capture/linux/screen_capturer_x11.h" -#endif // defined(WEBRTC_USE_X11) - -namespace webrtc { - -// static -std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( - const DesktopCaptureOptions& options) { -#if defined(WEBRTC_USE_PIPEWIRE) - if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { - return ScreenCapturerPipeWire::CreateRawScreenCapturer(options); - } -#endif // defined(WEBRTC_USE_PIPEWIRE) - -#if defined(WEBRTC_USE_X11) - return ScreenCapturerX11::CreateRawScreenCapturer(options); -#endif // defined(WEBRTC_USE_X11) - - return nullptr; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_win.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_win.cc deleted file mode 100644 index be6d8a527..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_capturer_win.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013 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 -#include - -#include "modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h" -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/fallback_desktop_capturer_wrapper.h" -#include "modules/desktop_capture/rgba_color.h" -#include "modules/desktop_capture/win/screen_capturer_win_directx.h" -#include "modules/desktop_capture/win/screen_capturer_win_gdi.h" -#include "modules/desktop_capture/win/screen_capturer_win_magnifier.h" - -namespace webrtc { - -namespace { - -std::unique_ptr CreateScreenCapturerWinDirectx() { - std::unique_ptr capturer(new ScreenCapturerWinDirectx()); - capturer.reset(new BlankDetectorDesktopCapturerWrapper( - std::move(capturer), RgbaColor(0, 0, 0, 0))); - return capturer; -} - -} // namespace - -// static -std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( - const DesktopCaptureOptions& options) { - std::unique_ptr capturer(new ScreenCapturerWinGdi(options)); - if (options.allow_directx_capturer()) { - // |dxgi_duplicator_controller| should be alive in this scope to ensure it - // won't unload DxgiDuplicatorController. - auto dxgi_duplicator_controller = DxgiDuplicatorController::Instance(); - if (ScreenCapturerWinDirectx::IsSupported()) { - capturer.reset(new FallbackDesktopCapturerWrapper( - CreateScreenCapturerWinDirectx(), std::move(capturer))); - } - } - - if (options.allow_use_magnification_api()) { - // ScreenCapturerWinMagnifier cannot work on Windows XP or earlier, as well - // as 64-bit only Windows, and it may randomly crash on multi-screen - // systems. So we may need to fallback to use original capturer. - capturer.reset(new FallbackDesktopCapturerWrapper( - std::unique_ptr(new ScreenCapturerWinMagnifier()), - std::move(capturer))); - } - - return capturer; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer.cc deleted file mode 100644 index 6460f19f6..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2016 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/desktop_capture/screen_drawer.h" - -namespace webrtc { - -namespace { -std::unique_ptr g_screen_drawer_lock; -} // namespace - -ScreenDrawerLock::ScreenDrawerLock() = default; -ScreenDrawerLock::~ScreenDrawerLock() = default; - -ScreenDrawer::ScreenDrawer() { - g_screen_drawer_lock = ScreenDrawerLock::Create(); -} - -ScreenDrawer::~ScreenDrawer() { - g_screen_drawer_lock.reset(); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer.h deleted file mode 100644 index 061900023..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_SCREEN_DRAWER_H_ -#define MODULES_DESKTOP_CAPTURE_SCREEN_DRAWER_H_ - -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/rgba_color.h" - -namespace webrtc { - -// A cross-process lock to ensure only one ScreenDrawer can be used at a certain -// time. -class ScreenDrawerLock { - public: - virtual ~ScreenDrawerLock(); - - static std::unique_ptr Create(); - - protected: - ScreenDrawerLock(); -}; - -// A set of basic platform dependent functions to draw various shapes on the -// screen. -class ScreenDrawer { - public: - // Creates a ScreenDrawer for the current platform, returns nullptr if no - // ScreenDrawer implementation available. - // If the implementation cannot guarantee two ScreenDrawer instances won't - // impact each other, this function may block current thread until another - // ScreenDrawer has been destroyed. - static std::unique_ptr Create(); - - ScreenDrawer(); - virtual ~ScreenDrawer(); - - // Returns the region inside which DrawRectangle() function are expected to - // work, in capturer coordinates (assuming ScreenCapturer::SelectScreen has - // not been called). This region may exclude regions of the screen reserved by - // the OS for things like menu bars or app launchers. The DesktopRect is in - // system coordinate, i.e. the primary monitor always starts from (0, 0). - virtual DesktopRect DrawableRegion() = 0; - - // Draws a rectangle to cover |rect| with |color|. Note, rect.bottom() and - // rect.right() two lines are not included. The part of |rect| which is out of - // DrawableRegion() will be ignored. - virtual void DrawRectangle(DesktopRect rect, RgbaColor color) = 0; - - // Clears all content on the screen by filling the area with black. - virtual void Clear() = 0; - - // Blocks current thread until OS finishes previous DrawRectangle() actions. - // ScreenCapturer should be able to capture the changes after this function - // finish. - virtual void WaitForPendingDraws() = 0; - - // Returns true if incomplete shapes previous actions required may be drawn on - // the screen after a WaitForPendingDraws() call. i.e. Though the complete - // shapes will eventually be drawn on the screen, due to some OS limitations, - // these shapes may be partially appeared sometimes. - virtual bool MayDrawIncompleteShapes() = 0; - - // Returns the id of the drawer window. This function returns kNullWindowId if - // the implementation does not draw on a window of the system. - virtual WindowId window_id() const = 0; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_SCREEN_DRAWER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_linux.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_linux.cc deleted file mode 100644 index afd29ced0..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_linux.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2016 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 -#include -#include - -#include - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_geometry.h" -#include "modules/desktop_capture/linux/shared_x_display.h" -#include "modules/desktop_capture/rgba_color.h" -#include "modules/desktop_capture/screen_drawer.h" -#include "modules/desktop_capture/screen_drawer_lock_posix.h" -#include "rtc_base/checks.h" -#include "system_wrappers/include/sleep.h" - -namespace webrtc { - -namespace { - -// A ScreenDrawer implementation for X11. -class ScreenDrawerLinux : public ScreenDrawer { - public: - ScreenDrawerLinux(); - ~ScreenDrawerLinux() override; - - // ScreenDrawer interface. - DesktopRect DrawableRegion() override; - void DrawRectangle(DesktopRect rect, RgbaColor color) override; - void Clear() override; - void WaitForPendingDraws() override; - bool MayDrawIncompleteShapes() override; - WindowId window_id() const override; - - private: - // Bring the window to the front, this can help to avoid the impact from other - // windows or shadow effect. - void BringToFront(); - - rtc::scoped_refptr display_; - int screen_num_; - DesktopRect rect_; - Window window_; - GC context_; - Colormap colormap_; -}; - -ScreenDrawerLinux::ScreenDrawerLinux() { - display_ = SharedXDisplay::CreateDefault(); - RTC_CHECK(display_.get()); - screen_num_ = DefaultScreen(display_->display()); - XWindowAttributes root_attributes; - if (!XGetWindowAttributes(display_->display(), - RootWindow(display_->display(), screen_num_), - &root_attributes)) { - RTC_NOTREACHED() << "Failed to get root window size."; - } - window_ = XCreateSimpleWindow( - display_->display(), RootWindow(display_->display(), screen_num_), 0, 0, - root_attributes.width, root_attributes.height, 0, - BlackPixel(display_->display(), screen_num_), - BlackPixel(display_->display(), screen_num_)); - XSelectInput(display_->display(), window_, StructureNotifyMask); - XMapWindow(display_->display(), window_); - while (true) { - XEvent event; - XNextEvent(display_->display(), &event); - if (event.type == MapNotify) { - break; - } - } - XFlush(display_->display()); - Window child; - int x, y; - if (!XTranslateCoordinates(display_->display(), window_, - RootWindow(display_->display(), screen_num_), 0, 0, - &x, &y, &child)) { - RTC_NOTREACHED() << "Failed to get window position."; - } - // Some window manager does not allow a window to cover two or more monitors. - // So if the window is on the first monitor of a two-monitor system, the - // second half won't be able to show up without changing configurations of WM, - // and its DrawableRegion() is not accurate. - rect_ = DesktopRect::MakeLTRB(x, y, root_attributes.width, - root_attributes.height); - context_ = DefaultGC(display_->display(), screen_num_); - colormap_ = DefaultColormap(display_->display(), screen_num_); - BringToFront(); - // Wait for window animations. - SleepMs(200); -} - -ScreenDrawerLinux::~ScreenDrawerLinux() { - XUnmapWindow(display_->display(), window_); - XDestroyWindow(display_->display(), window_); -} - -DesktopRect ScreenDrawerLinux::DrawableRegion() { - return rect_; -} - -void ScreenDrawerLinux::DrawRectangle(DesktopRect rect, RgbaColor color) { - rect.Translate(-rect_.left(), -rect_.top()); - XColor xcolor; - // X11 does not support Alpha. - // X11 uses 16 bits for each primary color, so we need to slightly normalize - // a 8 bits channel to 16 bits channel, by setting the low 8 bits as its high - // 8 bits to avoid a mismatch of color returned by capturer. - xcolor.red = (color.red << 8) + color.red; - xcolor.green = (color.green << 8) + color.green; - xcolor.blue = (color.blue << 8) + color.blue; - xcolor.flags = DoRed | DoGreen | DoBlue; - XAllocColor(display_->display(), colormap_, &xcolor); - XSetForeground(display_->display(), context_, xcolor.pixel); - XFillRectangle(display_->display(), window_, context_, rect.left(), - rect.top(), rect.width(), rect.height()); - XFlush(display_->display()); -} - -void ScreenDrawerLinux::Clear() { - DrawRectangle(rect_, RgbaColor(0, 0, 0)); -} - -// TODO(zijiehe): Find the right signal from X11 to indicate the finish of all -// pending paintings. -void ScreenDrawerLinux::WaitForPendingDraws() { - SleepMs(50); -} - -bool ScreenDrawerLinux::MayDrawIncompleteShapes() { - return true; -} - -WindowId ScreenDrawerLinux::window_id() const { - return window_; -} - -void ScreenDrawerLinux::BringToFront() { - Atom state_above = XInternAtom(display_->display(), "_NET_WM_STATE_ABOVE", 1); - Atom window_state = XInternAtom(display_->display(), "_NET_WM_STATE", 1); - if (state_above == None || window_state == None) { - // Fallback to use XRaiseWindow, it's not reliable if two windows are both - // raise itself to the top. - XRaiseWindow(display_->display(), window_); - return; - } - - XEvent event; - memset(&event, 0, sizeof(event)); - event.type = ClientMessage; - event.xclient.window = window_; - event.xclient.message_type = window_state; - event.xclient.format = 32; - event.xclient.data.l[0] = 1; // _NET_WM_STATE_ADD - event.xclient.data.l[1] = state_above; - XSendEvent(display_->display(), RootWindow(display_->display(), screen_num_), - False, SubstructureRedirectMask | SubstructureNotifyMask, &event); -} - -} // namespace - -// static -std::unique_ptr ScreenDrawerLock::Create() { - return std::make_unique(); -} - -// static -std::unique_ptr ScreenDrawer::Create() { - if (SharedXDisplay::CreateDefault().get()) { - return std::make_unique(); - } - return nullptr; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_lock_posix.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_lock_posix.cc deleted file mode 100644 index 095189b05..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_lock_posix.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/screen_drawer_lock_posix.h" - -#include -#include - -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { - -namespace { - -// A uuid as the name of semaphore. -static constexpr char kSemaphoreName[] = "GSDL54fe5552804711e6a7253f429a"; - -} // namespace - -ScreenDrawerLockPosix::ScreenDrawerLockPosix() - : ScreenDrawerLockPosix(kSemaphoreName) {} - -ScreenDrawerLockPosix::ScreenDrawerLockPosix(const char* name) { - semaphore_ = sem_open(name, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 1); - if (semaphore_ == SEM_FAILED) { - RTC_LOG_ERRNO(LS_ERROR) << "Failed to create named semaphore with " << name; - RTC_NOTREACHED(); - } - - sem_wait(semaphore_); -} - -ScreenDrawerLockPosix::~ScreenDrawerLockPosix() { - if (semaphore_ == SEM_FAILED) { - return; - } - - sem_post(semaphore_); - sem_close(semaphore_); - // sem_unlink a named semaphore won't wait until other clients to release the - // sem_t. So if a new process starts, it will sem_open a different kernel - // object with the same name and eventually breaks the cross-process lock. -} - -// static -void ScreenDrawerLockPosix::Unlink(const char* name) { - sem_unlink(name); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_lock_posix.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_lock_posix.h deleted file mode 100644 index 1d5adf2c5..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_lock_posix.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_SCREEN_DRAWER_LOCK_POSIX_H_ -#define MODULES_DESKTOP_CAPTURE_SCREEN_DRAWER_LOCK_POSIX_H_ - -#include - -#include "modules/desktop_capture/screen_drawer.h" - -namespace webrtc { - -class ScreenDrawerLockPosix final : public ScreenDrawerLock { - public: - ScreenDrawerLockPosix(); - // Provides a name other than the default one for test only. - explicit ScreenDrawerLockPosix(const char* name); - ~ScreenDrawerLockPosix() override; - - // Unlinks the named semaphore actively. This will remove the sem_t object in - // the system and allow others to create a different sem_t object with the - // same/ name. - static void Unlink(const char* name); - - private: - sem_t* semaphore_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_SCREEN_DRAWER_LOCK_POSIX_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_mac.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_mac.cc deleted file mode 100644 index 17719e443..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_mac.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -// TODO(zijiehe): Implement ScreenDrawerMac - -#include - -#include "modules/desktop_capture/screen_drawer.h" -#include "modules/desktop_capture/screen_drawer_lock_posix.h" - -namespace webrtc { - -// static -std::unique_ptr ScreenDrawerLock::Create() { - return std::make_unique(); -} - -// static -std::unique_ptr ScreenDrawer::Create() { - return nullptr; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_win.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_win.cc deleted file mode 100644 index cacb88957..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/screen_drawer_win.cc +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2016 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 - -#include - -#include "modules/desktop_capture/screen_drawer.h" -#include "system_wrappers/include/sleep.h" - -namespace webrtc { - -namespace { - -static constexpr TCHAR kMutexName[] = - TEXT("Local\\ScreenDrawerWin-da834f82-8044-11e6-ac81-73dcdd1c1869"); - -class ScreenDrawerLockWin : public ScreenDrawerLock { - public: - ScreenDrawerLockWin(); - ~ScreenDrawerLockWin() override; - - private: - HANDLE mutex_; -}; - -ScreenDrawerLockWin::ScreenDrawerLockWin() { - while (true) { - mutex_ = CreateMutex(NULL, FALSE, kMutexName); - if (GetLastError() != ERROR_ALREADY_EXISTS && mutex_ != NULL) { - break; - } else { - if (mutex_) { - CloseHandle(mutex_); - } - SleepMs(1000); - } - } -} - -ScreenDrawerLockWin::~ScreenDrawerLockWin() { - CloseHandle(mutex_); -} - -DesktopRect GetScreenRect() { - HDC hdc = GetDC(NULL); - DesktopRect rect = DesktopRect::MakeWH(GetDeviceCaps(hdc, HORZRES), - GetDeviceCaps(hdc, VERTRES)); - ReleaseDC(NULL, hdc); - return rect; -} - -HWND CreateDrawerWindow(DesktopRect rect) { - HWND hwnd = CreateWindowA( - "STATIC", "DrawerWindow", WS_POPUPWINDOW | WS_VISIBLE, rect.left(), - rect.top(), rect.width(), rect.height(), NULL, NULL, NULL, NULL); - SetForegroundWindow(hwnd); - return hwnd; -} - -COLORREF ColorToRef(RgbaColor color) { - // Windows device context does not support alpha. - return RGB(color.red, color.green, color.blue); -} - -// A ScreenDrawer implementation for Windows. -class ScreenDrawerWin : public ScreenDrawer { - public: - ScreenDrawerWin(); - ~ScreenDrawerWin() override; - - // ScreenDrawer interface. - DesktopRect DrawableRegion() override; - void DrawRectangle(DesktopRect rect, RgbaColor color) override; - void Clear() override; - void WaitForPendingDraws() override; - bool MayDrawIncompleteShapes() override; - WindowId window_id() const override; - - private: - // Bring the window to the front, this can help to avoid the impact from other - // windows or shadow effects. - void BringToFront(); - - // Draw a line with |color|. - void DrawLine(DesktopVector start, DesktopVector end, RgbaColor color); - - // Draw a dot with |color|. - void DrawDot(DesktopVector vect, RgbaColor color); - - const DesktopRect rect_; - HWND window_; - HDC hdc_; -}; - -ScreenDrawerWin::ScreenDrawerWin() - : ScreenDrawer(), - rect_(GetScreenRect()), - window_(CreateDrawerWindow(rect_)), - hdc_(GetWindowDC(window_)) { - // We do not need to handle any messages for the |window_|, so disable Windows - // from processing windows ghosting feature. - DisableProcessWindowsGhosting(); - - // Always use stock pen (DC_PEN) and brush (DC_BRUSH). - SelectObject(hdc_, GetStockObject(DC_PEN)); - SelectObject(hdc_, GetStockObject(DC_BRUSH)); - BringToFront(); -} - -ScreenDrawerWin::~ScreenDrawerWin() { - ReleaseDC(NULL, hdc_); - DestroyWindow(window_); - // Unfortunately there is no EnableProcessWindowsGhosting() API. -} - -DesktopRect ScreenDrawerWin::DrawableRegion() { - return rect_; -} - -void ScreenDrawerWin::DrawRectangle(DesktopRect rect, RgbaColor color) { - if (rect.width() == 1 && rect.height() == 1) { - // Rectangle function cannot draw a 1 pixel rectangle. - DrawDot(rect.top_left(), color); - return; - } - - if (rect.width() == 1 || rect.height() == 1) { - // Rectangle function cannot draw a 1 pixel rectangle. - DrawLine(rect.top_left(), DesktopVector(rect.right(), rect.bottom()), - color); - return; - } - - SetDCBrushColor(hdc_, ColorToRef(color)); - SetDCPenColor(hdc_, ColorToRef(color)); - Rectangle(hdc_, rect.left(), rect.top(), rect.right(), rect.bottom()); -} - -void ScreenDrawerWin::Clear() { - DrawRectangle(rect_, RgbaColor(0, 0, 0)); -} - -// TODO(zijiehe): Find the right signal to indicate the finish of all pending -// paintings. -void ScreenDrawerWin::WaitForPendingDraws() { - BringToFront(); - SleepMs(50); -} - -bool ScreenDrawerWin::MayDrawIncompleteShapes() { - return true; -} - -WindowId ScreenDrawerWin::window_id() const { - return reinterpret_cast(window_); -} - -void ScreenDrawerWin::DrawLine(DesktopVector start, - DesktopVector end, - RgbaColor color) { - POINT points[2]; - points[0].x = start.x(); - points[0].y = start.y(); - points[1].x = end.x(); - points[1].y = end.y(); - SetDCPenColor(hdc_, ColorToRef(color)); - Polyline(hdc_, points, 2); -} - -void ScreenDrawerWin::DrawDot(DesktopVector vect, RgbaColor color) { - SetPixel(hdc_, vect.x(), vect.y(), ColorToRef(color)); -} - -void ScreenDrawerWin::BringToFront() { - if (SetWindowPos(window_, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE) != FALSE) { - return; - } - - long ex_style = GetWindowLong(window_, GWL_EXSTYLE); - ex_style |= WS_EX_TOPMOST; - if (SetWindowLong(window_, GWL_EXSTYLE, ex_style) != 0) { - return; - } - - BringWindowToTop(window_); -} - -} // namespace - -// static -std::unique_ptr ScreenDrawerLock::Create() { - return std::unique_ptr(new ScreenDrawerLockWin()); -} - -// static -std::unique_ptr ScreenDrawer::Create() { - return std::unique_ptr(new ScreenDrawerWin()); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_desktop_frame.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_desktop_frame.cc deleted file mode 100644 index 2ded14547..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_desktop_frame.cc +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/shared_desktop_frame.h" - -#include -#include -#include - -namespace webrtc { - -SharedDesktopFrame::~SharedDesktopFrame() {} - -// static -std::unique_ptr SharedDesktopFrame::Wrap( - std::unique_ptr desktop_frame) { - return std::unique_ptr( - new SharedDesktopFrame(new Core(std::move(desktop_frame)))); -} - -SharedDesktopFrame* SharedDesktopFrame::Wrap(DesktopFrame* desktop_frame) { - return Wrap(std::unique_ptr(desktop_frame)).release(); -} - -DesktopFrame* SharedDesktopFrame::GetUnderlyingFrame() { - return core_->get(); -} - -bool SharedDesktopFrame::ShareFrameWith(const SharedDesktopFrame& other) const { - return core_->get() == other.core_->get(); -} - -std::unique_ptr SharedDesktopFrame::Share() { - std::unique_ptr result(new SharedDesktopFrame(core_)); - result->CopyFrameInfoFrom(*this); - return result; -} - -bool SharedDesktopFrame::IsShared() { - return !core_->HasOneRef(); -} - -SharedDesktopFrame::SharedDesktopFrame(rtc::scoped_refptr core) - : DesktopFrame((*core)->size(), - (*core)->stride(), - (*core)->data(), - (*core)->shared_memory()), - core_(core) { - CopyFrameInfoFrom(*(core_->get())); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_desktop_frame.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_desktop_frame.h deleted file mode 100644 index fd862d7f2..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_desktop_frame.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_SHARED_DESKTOP_FRAME_H_ -#define MODULES_DESKTOP_CAPTURE_SHARED_DESKTOP_FRAME_H_ - -#include - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/ref_counted_object.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// SharedDesktopFrame is a DesktopFrame that may have multiple instances all -// sharing the same buffer. -class RTC_EXPORT SharedDesktopFrame : public DesktopFrame { - public: - ~SharedDesktopFrame() override; - - static std::unique_ptr Wrap( - std::unique_ptr desktop_frame); - - // Deprecated. - // TODO(sergeyu): remove this method. - static SharedDesktopFrame* Wrap(DesktopFrame* desktop_frame); - - // Deprecated. Clients do not need to know the underlying DesktopFrame - // instance. - // TODO(zijiehe): Remove this method. - // Returns the underlying instance of DesktopFrame. - DesktopFrame* GetUnderlyingFrame(); - - // Returns whether |this| and |other| share the underlying DesktopFrame. - bool ShareFrameWith(const SharedDesktopFrame& other) const; - - // Creates a clone of this object. - std::unique_ptr Share(); - - // Checks if the frame is currently shared. If it returns false it's - // guaranteed that there are no clones of the object. - bool IsShared(); - - private: - typedef rtc::RefCountedObject> Core; - - SharedDesktopFrame(rtc::scoped_refptr core); - - const rtc::scoped_refptr core_; - - RTC_DISALLOW_COPY_AND_ASSIGN(SharedDesktopFrame); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_SHARED_DESKTOP_FRAME_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_memory.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_memory.cc deleted file mode 100644 index b4ff78b2a..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_memory.cc +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/shared_memory.h" - -namespace webrtc { - -#if defined(WEBRTC_WIN) -const SharedMemory::Handle SharedMemory::kInvalidHandle = NULL; -#else -const SharedMemory::Handle SharedMemory::kInvalidHandle = -1; -#endif - -SharedMemory::SharedMemory(void* data, size_t size, Handle handle, int id) - : data_(data), size_(size), handle_(handle), id_(id) {} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_memory.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_memory.h deleted file mode 100644 index 2e2d2f338..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/shared_memory.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_SHARED_MEMORY_H_ -#define MODULES_DESKTOP_CAPTURE_SHARED_MEMORY_H_ - -#include - -#if defined(WEBRTC_WIN) -#include -#endif - -#include - -#include "rtc_base/constructor_magic.h" -#include "rtc_base/system/rtc_export.h" - -namespace webrtc { - -// SharedMemory is a base class for shared memory. It stores all required -// parameters of the buffer, but doesn't have any logic to allocate or destroy -// the actual buffer. DesktopCapturer consumers that need to use shared memory -// for video frames must extend this class with creation and destruction logic -// specific for the target platform and then call -// DesktopCapturer::SetSharedMemoryFactory(). -class RTC_EXPORT SharedMemory { - public: -#if defined(WEBRTC_WIN) - typedef HANDLE Handle; - static const Handle kInvalidHandle; -#else - typedef int Handle; - static const Handle kInvalidHandle; -#endif - - void* data() const { return data_; } - size_t size() const { return size_; } - - // Platform-specific handle of the buffer. - Handle handle() const { return handle_; } - - // Integer identifier that can be used used by consumers of DesktopCapturer - // interface to identify shared memory buffers it created. - int id() const { return id_; } - - virtual ~SharedMemory() {} - - protected: - SharedMemory(void* data, size_t size, Handle handle, int id); - - void* const data_; - const size_t size_; - const Handle handle_; - const int id_; - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(SharedMemory); -}; - -// Interface used to create SharedMemory instances. -class SharedMemoryFactory { - public: - SharedMemoryFactory() {} - virtual ~SharedMemoryFactory() {} - - virtual std::unique_ptr CreateSharedMemory(size_t size) = 0; - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(SharedMemoryFactory); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_SHARED_MEMORY_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_linux.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_linux.cc deleted file mode 100644 index 41dbf836b..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_linux.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 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 - -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" - -#if defined(WEBRTC_USE_PIPEWIRE) -#include "modules/desktop_capture/linux/window_capturer_pipewire.h" -#endif // defined(WEBRTC_USE_PIPEWIRE) - -#if defined(WEBRTC_USE_X11) -#include "modules/desktop_capture/linux/window_capturer_x11.h" -#endif // defined(WEBRTC_USE_X11) - -namespace webrtc { - -// static -std::unique_ptr DesktopCapturer::CreateRawWindowCapturer( - const DesktopCaptureOptions& options) { -#if defined(WEBRTC_USE_PIPEWIRE) - if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { - return WindowCapturerPipeWire::CreateRawWindowCapturer(options); - } -#endif // defined(WEBRTC_USE_PIPEWIRE) - -#if defined(WEBRTC_USE_X11) - return WindowCapturerX11::CreateRawWindowCapturer(options); -#endif // defined(WEBRTC_USE_X11) - - return nullptr; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_mac.mm b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_mac.mm deleted file mode 100644 index 96f89eb14..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_mac.mm +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2013 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 -#include -#include -#include - -#include - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "modules/desktop_capture/mac/desktop_configuration.h" -#include "modules/desktop_capture/mac/desktop_configuration_monitor.h" -#include "modules/desktop_capture/mac/desktop_frame_cgimage.h" -#include "modules/desktop_capture/mac/window_list_utils.h" -#include "modules/desktop_capture/window_finder_mac.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/logging.h" -#include "rtc_base/trace_event.h" - -namespace webrtc { - -namespace { - -// Returns true if the window exists. -bool IsWindowValid(CGWindowID id) { - CFArrayRef window_id_array = - CFArrayCreate(nullptr, reinterpret_cast(&id), 1, nullptr); - CFArrayRef window_array = - CGWindowListCreateDescriptionFromArray(window_id_array); - bool valid = window_array && CFArrayGetCount(window_array); - CFRelease(window_id_array); - CFRelease(window_array); - - return valid; -} - -class WindowCapturerMac : public DesktopCapturer { - public: - explicit WindowCapturerMac( - rtc::scoped_refptr full_screen_window_detector, - rtc::scoped_refptr configuration_monitor); - ~WindowCapturerMac() override; - - // DesktopCapturer interface. - void Start(Callback* callback) override; - void CaptureFrame() override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - bool FocusOnSelectedSource() override; - bool IsOccluded(const DesktopVector& pos) override; - - private: - Callback* callback_ = nullptr; - - // The window being captured. - CGWindowID window_id_ = 0; - - rtc::scoped_refptr full_screen_window_detector_; - - const rtc::scoped_refptr configuration_monitor_; - - WindowFinderMac window_finder_; - - RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerMac); -}; - -WindowCapturerMac::WindowCapturerMac( - rtc::scoped_refptr full_screen_window_detector, - rtc::scoped_refptr configuration_monitor) - : full_screen_window_detector_(std::move(full_screen_window_detector)), - configuration_monitor_(std::move(configuration_monitor)), - window_finder_(configuration_monitor_) {} - -WindowCapturerMac::~WindowCapturerMac() {} - -bool WindowCapturerMac::GetSourceList(SourceList* sources) { - return webrtc::GetWindowList(sources, true, true); -} - -bool WindowCapturerMac::SelectSource(SourceId id) { - if (!IsWindowValid(id)) - return false; - window_id_ = id; - return true; -} - -bool WindowCapturerMac::FocusOnSelectedSource() { - if (!window_id_) - return false; - - CGWindowID ids[1]; - ids[0] = window_id_; - CFArrayRef window_id_array = - CFArrayCreate(nullptr, reinterpret_cast(&ids), 1, nullptr); - - CFArrayRef window_array = - CGWindowListCreateDescriptionFromArray(window_id_array); - if (!window_array || 0 == CFArrayGetCount(window_array)) { - // Could not find the window. It might have been closed. - RTC_LOG(LS_INFO) << "Window not found"; - CFRelease(window_id_array); - return false; - } - - CFDictionaryRef window = reinterpret_cast( - CFArrayGetValueAtIndex(window_array, 0)); - CFNumberRef pid_ref = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowOwnerPID)); - - int pid; - CFNumberGetValue(pid_ref, kCFNumberIntType, &pid); - - // TODO(jiayl): this will bring the process main window to the front. We - // should find a way to bring only the window to the front. - bool result = - [[NSRunningApplication runningApplicationWithProcessIdentifier: pid] - activateWithOptions: NSApplicationActivateIgnoringOtherApps]; - - CFRelease(window_id_array); - CFRelease(window_array); - return result; -} - -bool WindowCapturerMac::IsOccluded(const DesktopVector& pos) { - DesktopVector sys_pos = pos; - if (configuration_monitor_) { - auto configuration = configuration_monitor_->desktop_configuration(); - sys_pos = pos.add(configuration.bounds.top_left()); - } - return window_finder_.GetWindowUnderPoint(sys_pos) != window_id_; -} - -void WindowCapturerMac::Start(Callback* callback) { - assert(!callback_); - assert(callback); - - callback_ = callback; -} - -void WindowCapturerMac::CaptureFrame() { - TRACE_EVENT0("webrtc", "WindowCapturerMac::CaptureFrame"); - - if (!IsWindowValid(window_id_)) { - RTC_LOG(LS_ERROR) << "The window is not valid any longer."; - callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); - return; - } - - CGWindowID on_screen_window = window_id_; - if (full_screen_window_detector_) { - full_screen_window_detector_->UpdateWindowListIfNeeded( - window_id_, [](DesktopCapturer::SourceList* sources) { - return webrtc::GetWindowList(sources, true, false); - }); - - CGWindowID full_screen_window = full_screen_window_detector_->FindFullScreenWindow(window_id_); - - if (full_screen_window != kCGNullWindowID) on_screen_window = full_screen_window; - } - - std::unique_ptr frame = DesktopFrameCGImage::CreateForWindow(on_screen_window); - if (!frame) { - RTC_LOG(LS_WARNING) << "Temporarily failed to capture window."; - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); - return; - } - - frame->mutable_updated_region()->SetRect( - DesktopRect::MakeSize(frame->size())); - frame->set_top_left(GetWindowBounds(on_screen_window).top_left()); - - float scale_factor = GetWindowScaleFactor(window_id_, frame->size()); - frame->set_dpi(DesktopVector(kStandardDPI * scale_factor, kStandardDPI * scale_factor)); - - callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); -} - -} // namespace - -// static -std::unique_ptr DesktopCapturer::CreateRawWindowCapturer( - const DesktopCaptureOptions& options) { - return std::unique_ptr(new WindowCapturerMac( - options.full_screen_window_detector(), options.configuration_monitor())); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_null.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_null.cc deleted file mode 100644 index 66e76a50f..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_null.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013 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 - -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/desktop_frame.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -namespace { - -class WindowCapturerNull : public DesktopCapturer { - public: - WindowCapturerNull(); - ~WindowCapturerNull() override; - - // DesktopCapturer interface. - void Start(Callback* callback) override; - void CaptureFrame() override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - - private: - Callback* callback_ = nullptr; - - RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerNull); -}; - -WindowCapturerNull::WindowCapturerNull() {} -WindowCapturerNull::~WindowCapturerNull() {} - -bool WindowCapturerNull::GetSourceList(SourceList* sources) { - // Not implemented yet. - return false; -} - -bool WindowCapturerNull::SelectSource(SourceId id) { - // Not implemented yet. - return false; -} - -void WindowCapturerNull::Start(Callback* callback) { - assert(!callback_); - assert(callback); - - callback_ = callback; -} - -void WindowCapturerNull::CaptureFrame() { - // Not implemented yet. - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); -} - -} // namespace - -// static -std::unique_ptr DesktopCapturer::CreateRawWindowCapturer( - const DesktopCaptureOptions& options) { - return std::unique_ptr(new WindowCapturerNull()); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_win.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_win.cc deleted file mode 100644 index a63a24df5..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_capturer_win.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013 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/desktop_capture/desktop_capture_options.h" -#include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/win/window_capturer_win_gdi.h" -#include "modules/desktop_capture/win/window_capturer_win_wgc.h" - -namespace webrtc { - -// static -std::unique_ptr DesktopCapturer::CreateRawWindowCapturer( - const DesktopCaptureOptions& options) { - // TODO(bugs.webrtc.org/11760): Add a WebRTC field trial (or similar - // mechanism) and Windows version check here that leads to use of the WGC - // capturer once it is fully implemented. - if (true) { - return WindowCapturerWinGdi::CreateRawWindowCapturer(options); - } else { - return WindowCapturerWinWgc::CreateRawWindowCapturer(options); - } -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder.cc deleted file mode 100644 index 86127d4c0..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/window_finder.h" - -namespace webrtc { - -WindowFinder::Options::Options() = default; -WindowFinder::Options::~Options() = default; -WindowFinder::Options::Options(const WindowFinder::Options& other) = default; -WindowFinder::Options::Options(WindowFinder::Options&& other) = default; - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder.h deleted file mode 100644 index 0d346640a..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_H_ -#define MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_H_ - -#include - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/desktop_capture_types.h" -#include "modules/desktop_capture/desktop_geometry.h" - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include "modules/desktop_capture/mac/desktop_configuration_monitor.h" -#endif - -namespace webrtc { - -#if defined(WEBRTC_USE_X11) -class XAtomCache; -#endif - -// An interface to return the id of the visible window under a certain point. -class WindowFinder { - public: - WindowFinder() = default; - virtual ~WindowFinder() = default; - - // Returns the id of the visible window under |point|. This function returns - // kNullWindowId if no window is under |point| and the platform does not have - // "root window" concept, i.e. the visible area under |point| is the desktop. - // |point| is always in system coordinate, i.e. the primary monitor always - // starts from (0, 0). - virtual WindowId GetWindowUnderPoint(DesktopVector point) = 0; - - struct Options final { - Options(); - ~Options(); - Options(const Options& other); - Options(Options&& other); - -#if defined(WEBRTC_USE_X11) - XAtomCache* cache = nullptr; -#endif -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - rtc::scoped_refptr configuration_monitor; -#endif - }; - - // Creates a platform-independent WindowFinder implementation. This function - // returns nullptr if |options| does not contain enough information or - // WindowFinder does not support current platform. - static std::unique_ptr Create(const Options& options); -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_mac.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_mac.h deleted file mode 100644 index 988dd497d..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_mac.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_MAC_H_ -#define MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_MAC_H_ - -#include "api/scoped_refptr.h" -#include "modules/desktop_capture/window_finder.h" - -namespace webrtc { - -class DesktopConfigurationMonitor; - -// The implementation of WindowFinder for Mac OSX. -class WindowFinderMac final : public WindowFinder { - public: - explicit WindowFinderMac( - rtc::scoped_refptr configuration_monitor); - ~WindowFinderMac() override; - - // WindowFinder implementation. - WindowId GetWindowUnderPoint(DesktopVector point) override; - - private: - const rtc::scoped_refptr configuration_monitor_; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_MAC_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_mac.mm b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_mac.mm deleted file mode 100644 index e1d0316c7..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_mac.mm +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/window_finder_mac.h" - -#include - -#include -#include - -#include "modules/desktop_capture/mac/desktop_configuration.h" -#include "modules/desktop_capture/mac/desktop_configuration_monitor.h" -#include "modules/desktop_capture/mac/window_list_utils.h" - -namespace webrtc { - -WindowFinderMac::WindowFinderMac( - rtc::scoped_refptr configuration_monitor) - : configuration_monitor_(std::move(configuration_monitor)) {} -WindowFinderMac::~WindowFinderMac() = default; - -WindowId WindowFinderMac::GetWindowUnderPoint(DesktopVector point) { - WindowId id = kNullWindowId; - GetWindowList( - [&id, point](CFDictionaryRef window) { - DesktopRect bounds; - bounds = GetWindowBounds(window); - if (bounds.Contains(point)) { - id = GetWindowId(window); - return false; - } - return true; - }, - true, - true); - return id; -} - -// static -std::unique_ptr WindowFinder::Create( - const WindowFinder::Options& options) { - return std::make_unique(options.configuration_monitor); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_win.cc b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_win.cc deleted file mode 100644 index a8c3d39e1..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_win.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017 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/desktop_capture/window_finder_win.h" - -#include - -#include - -namespace webrtc { - -WindowFinderWin::WindowFinderWin() = default; -WindowFinderWin::~WindowFinderWin() = default; - -WindowId WindowFinderWin::GetWindowUnderPoint(DesktopVector point) { - HWND window = WindowFromPoint(POINT{point.x(), point.y()}); - if (!window) { - return kNullWindowId; - } - - // The difference between GA_ROOTOWNER and GA_ROOT can be found at - // https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/Hirr_DkuZdw. - // In short, we should use GA_ROOT, since we only care about the root window - // but not the owner. - window = GetAncestor(window, GA_ROOT); - if (!window) { - return kNullWindowId; - } - - return reinterpret_cast(window); -} - -// static -std::unique_ptr WindowFinder::Create( - const WindowFinder::Options& options) { - return std::make_unique(); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_win.h b/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_win.h deleted file mode 100644 index a04e7e1aa..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/desktop_capture/window_finder_win.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#ifndef MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_WIN_H_ -#define MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_WIN_H_ - -#include "modules/desktop_capture/window_finder.h" - -namespace webrtc { - -// The implementation of WindowFinder for Windows. -class WindowFinderWin final : public WindowFinder { - public: - WindowFinderWin(); - ~WindowFinderWin() override; - - // WindowFinder implementation. - WindowId GetWindowUnderPoint(DesktopVector point) override; -}; - -} // namespace webrtc - -#endif // MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_WIN_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/include/module_common_types.cc b/TMessagesProj/jni/voip/webrtc/modules/include/module_common_types.cc deleted file mode 100644 index a589312ec..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/include/module_common_types.cc +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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 "modules/include/module_common_types.h" - -#include - -#include -#include - -#include "rtc_base/numerics/safe_conversions.h" - -namespace webrtc { - -RTPFragmentationHeader::RTPFragmentationHeader() - : fragmentationVectorSize(0), - fragmentationOffset(nullptr), - fragmentationLength(nullptr) {} - -RTPFragmentationHeader::RTPFragmentationHeader(RTPFragmentationHeader&& other) - : RTPFragmentationHeader() { - swap(*this, other); -} - -RTPFragmentationHeader& RTPFragmentationHeader::operator=( - RTPFragmentationHeader&& other) { - swap(*this, other); - return *this; -} - -RTPFragmentationHeader::~RTPFragmentationHeader() { - delete[] fragmentationOffset; - delete[] fragmentationLength; -} - -void swap(RTPFragmentationHeader& a, RTPFragmentationHeader& b) { - using std::swap; - swap(a.fragmentationVectorSize, b.fragmentationVectorSize); - swap(a.fragmentationOffset, b.fragmentationOffset); - swap(a.fragmentationLength, b.fragmentationLength); -} - -void RTPFragmentationHeader::CopyFrom(const RTPFragmentationHeader& src) { - if (this == &src) { - return; - } - - if (src.fragmentationVectorSize != fragmentationVectorSize) { - // new size of vectors - - // delete old - delete[] fragmentationOffset; - fragmentationOffset = nullptr; - delete[] fragmentationLength; - fragmentationLength = nullptr; - - if (src.fragmentationVectorSize > 0) { - // allocate new - if (src.fragmentationOffset) { - fragmentationOffset = new size_t[src.fragmentationVectorSize]; - } - if (src.fragmentationLength) { - fragmentationLength = new size_t[src.fragmentationVectorSize]; - } - } - // set new size - fragmentationVectorSize = src.fragmentationVectorSize; - } - - if (src.fragmentationVectorSize > 0) { - // copy values - if (src.fragmentationOffset) { - memcpy(fragmentationOffset, src.fragmentationOffset, - src.fragmentationVectorSize * sizeof(size_t)); - } - if (src.fragmentationLength) { - memcpy(fragmentationLength, src.fragmentationLength, - src.fragmentationVectorSize * sizeof(size_t)); - } - } -} - -void RTPFragmentationHeader::Resize(size_t size) { - const uint16_t size16 = rtc::dchecked_cast(size); - if (fragmentationVectorSize < size16) { - uint16_t old_vector_size = fragmentationVectorSize; - size_t* old_offsets = fragmentationOffset; - fragmentationOffset = new size_t[size16]; - memset(fragmentationOffset + old_vector_size, 0, - sizeof(size_t) * (size16 - old_vector_size)); - size_t* old_lengths = fragmentationLength; - fragmentationLength = new size_t[size16]; - memset(fragmentationLength + old_vector_size, 0, - sizeof(size_t) * (size16 - old_vector_size)); - - // copy old values - if (old_vector_size > 0) { - if (old_offsets != nullptr) { - memcpy(fragmentationOffset, old_offsets, - sizeof(size_t) * old_vector_size); - delete[] old_offsets; - } - if (old_lengths != nullptr) { - memcpy(fragmentationLength, old_lengths, - sizeof(size_t) * old_vector_size); - delete[] old_lengths; - } - } - fragmentationVectorSize = size16; - } -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/include/module_common_types.h b/TMessagesProj/jni/voip/webrtc/modules/include/module_common_types.h index 3afd7b7d7..7c9ef39cf 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/include/module_common_types.h +++ b/TMessagesProj/jni/voip/webrtc/modules/include/module_common_types.h @@ -11,44 +11,12 @@ #ifndef MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ #define MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ -#include #include #include -#include "rtc_base/system/rtc_export.h" - namespace webrtc { -class RTC_EXPORT RTPFragmentationHeader { - public: - RTPFragmentationHeader(); - RTPFragmentationHeader(const RTPFragmentationHeader&) = delete; - RTPFragmentationHeader(RTPFragmentationHeader&& other); - RTPFragmentationHeader& operator=(const RTPFragmentationHeader& other) = - delete; - RTPFragmentationHeader& operator=(RTPFragmentationHeader&& other); - ~RTPFragmentationHeader(); - - friend void swap(RTPFragmentationHeader& a, RTPFragmentationHeader& b); - - void CopyFrom(const RTPFragmentationHeader& src); - void VerifyAndAllocateFragmentationHeader(size_t size) { Resize(size); } - - void Resize(size_t size); - size_t Size() const { return fragmentationVectorSize; } - - size_t Offset(size_t index) const { return fragmentationOffset[index]; } - size_t Length(size_t index) const { return fragmentationLength[index]; } - - // TODO(danilchap): Move all members to private section, - // simplify by replacing raw arrays with single std::vector - uint16_t fragmentationVectorSize; // Number of fragmentations - size_t* fragmentationOffset; // Offset of pointer to data for each - // fragmentation - size_t* fragmentationLength; // Data size for each fragmentation -}; - // Interface used by the CallStats class to distribute call statistics. // Callbacks will be triggered as soon as the class has been registered to a // CallStats object using RegisterStatsObserver. diff --git a/TMessagesProj/jni/voip/webrtc/modules/pacing/bitrate_prober.cc b/TMessagesProj/jni/voip/webrtc/modules/pacing/bitrate_prober.cc index 1949570d8..381a54d50 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/pacing/bitrate_prober.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/pacing/bitrate_prober.cc @@ -37,9 +37,8 @@ BitrateProberConfig::BitrateProberConfig( : min_probe_packets_sent("min_probe_packets_sent", 5), min_probe_delta("min_probe_delta", TimeDelta::Millis(1)), min_probe_duration("min_probe_duration", TimeDelta::Millis(15)), - max_probe_delay("max_probe_delay", TimeDelta::Millis(3)), - // TODO(bugs.webrtc.org/11780): Change to default true. - abort_delayed_probes("abort_delayed_probes", false) { + max_probe_delay("max_probe_delay", TimeDelta::Millis(10)), + abort_delayed_probes("abort_delayed_probes", true) { ParseFieldTrial( {&min_probe_packets_sent, &min_probe_delta, &min_probe_duration, &max_probe_delay, &abort_delayed_probes}, diff --git a/TMessagesProj/jni/voip/webrtc/modules/pacing/pacing_controller.cc b/TMessagesProj/jni/voip/webrtc/modules/pacing/pacing_controller.cc index 107316d4e..5ffbc903b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/pacing/pacing_controller.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/pacing/pacing_controller.cc @@ -84,6 +84,7 @@ int GetPriorityForType(RtpPacketMediaType type) { // BWE high. return kFirstPriority + 4; } + RTC_CHECK_NOTREACHED(); } } // namespace @@ -112,7 +113,7 @@ PacingController::PacingController(Clock* clock, IsEnabled(*field_trials_, "WebRTC-Pacer-PadInSilence")), pace_audio_(IsEnabled(*field_trials_, "WebRTC-Pacer-BlockAudio")), small_first_probe_packet_( - IsEnabled(*field_trials_, "WebRTC-Pacer-SmallFirstProbePacket")), + !IsDisabled(*field_trials_, "WebRTC-Pacer-SmallFirstProbePacket")), ignore_transport_overhead_( IsEnabled(*field_trials_, "WebRTC-Pacer-IgnoreTransportOverhead")), padding_target_duration_(GetDynamicPaddingTarget(*field_trials_)), diff --git a/TMessagesProj/jni/voip/webrtc/modules/pacing/task_queue_paced_sender.cc b/TMessagesProj/jni/voip/webrtc/modules/pacing/task_queue_paced_sender.cc index eb8b11bb6..69ec5457a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/pacing/task_queue_paced_sender.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/pacing/task_queue_paced_sender.cc @@ -224,9 +224,13 @@ void TaskQueuePacedSender::MaybeProcessPackets( // If we're probing and there isn't already a wakeup scheduled for the next // process time, always post a task and just round sleep time down to // nearest millisecond. - time_to_next_process = - std::max(TimeDelta::Zero(), - (next_process_time - now).RoundDownTo(TimeDelta::Millis(1))); + if (next_process_time.IsMinusInfinity()) { + time_to_next_process = TimeDelta::Zero(); + } else { + time_to_next_process = + std::max(TimeDelta::Zero(), + (next_process_time - now).RoundDownTo(TimeDelta::Millis(1))); + } } else if (next_process_time_.IsMinusInfinity() || next_process_time <= next_process_time_ - hold_back_window_) { // Schedule a new task since there is none currently scheduled diff --git a/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/inter_arrival.h b/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/inter_arrival.h index 1d84970de..dbc630ff6 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/inter_arrival.h +++ b/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/inter_arrival.h @@ -14,8 +14,6 @@ #include #include -#include "rtc_base/constructor_magic.h" - namespace webrtc { // Helper class to compute the inter-arrival time delta and the size delta @@ -35,6 +33,10 @@ class InterArrival { double timestamp_to_ms_coeff, bool enable_burst_grouping); + InterArrival() = delete; + InterArrival(const InterArrival&) = delete; + InterArrival& operator=(const InterArrival&) = delete; + // This function returns true if a delta was computed, or false if the current // group is still incomplete or if only one group has been completed. // |timestamp| is the timestamp. @@ -87,8 +89,6 @@ class InterArrival { double timestamp_to_ms_coeff_; bool burst_grouping_; int num_consecutive_reordered_packets_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(InterArrival); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h b/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h index 242336334..f42a28f8c 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h +++ b/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h @@ -27,7 +27,6 @@ #include "modules/remote_bitrate_estimator/overuse_detector.h" #include "modules/remote_bitrate_estimator/overuse_estimator.h" #include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/race_checker.h" #include "rtc_base/rate_statistics.h" #include "rtc_base/synchronization/mutex.h" @@ -76,6 +75,13 @@ class RemoteBitrateEstimatorAbsSendTime : public RemoteBitrateEstimator { public: RemoteBitrateEstimatorAbsSendTime(RemoteBitrateObserver* observer, Clock* clock); + + RemoteBitrateEstimatorAbsSendTime() = delete; + RemoteBitrateEstimatorAbsSendTime(const RemoteBitrateEstimatorAbsSendTime&) = + delete; + RemoteBitrateEstimatorAbsSendTime& operator=( + const RemoteBitrateEstimatorAbsSendTime&) = delete; + ~RemoteBitrateEstimatorAbsSendTime() override; void IncomingPacket(int64_t arrival_time_ms, @@ -141,8 +147,6 @@ class RemoteBitrateEstimatorAbsSendTime : public RemoteBitrateEstimator { mutable Mutex mutex_; Ssrcs ssrcs_ RTC_GUARDED_BY(&mutex_); AimdRateControl remote_rate_ RTC_GUARDED_BY(&mutex_); - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorAbsSendTime); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h b/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h index 6da67e5a1..9fd2f9fc0 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h +++ b/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h @@ -21,7 +21,6 @@ #include "api/transport/field_trial_based_config.h" #include "modules/remote_bitrate_estimator/aimd_rate_control.h" #include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/rate_statistics.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -35,6 +34,13 @@ class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator { public: RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer, Clock* clock); + + RemoteBitrateEstimatorSingleStream() = delete; + RemoteBitrateEstimatorSingleStream( + const RemoteBitrateEstimatorSingleStream&) = delete; + RemoteBitrateEstimatorSingleStream& operator=( + const RemoteBitrateEstimatorSingleStream&) = delete; + ~RemoteBitrateEstimatorSingleStream() override; void IncomingPacket(int64_t arrival_time_ms, @@ -74,8 +80,6 @@ class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator { int64_t last_process_time_; int64_t process_interval_ms_ RTC_GUARDED_BY(mutex_); bool uma_recorded_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorSingleStream); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h b/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h index 5a30da828..079a7f888 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h +++ b/TMessagesProj/jni/voip/webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h @@ -263,10 +263,11 @@ class Logging { Context(uint32_t name, int64_t timestamp_ms, bool enabled); Context(const std::string& name, int64_t timestamp_ms, bool enabled); Context(const char* name, int64_t timestamp_ms, bool enabled); - ~Context(); - private: - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Context); + Context() = delete; + Context(const Context&) = delete; + Context& operator=(const Context&) = delete; + ~Context(); }; static Logging* GetInstance(); diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h index 46c310e27..cbc2d9211 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h @@ -65,6 +65,7 @@ enum RTPExtensionType : int { kRtpExtensionTransportSequenceNumber02, kRtpExtensionPlayoutDelay, kRtpExtensionVideoContentType, + kRtpExtensionVideoLayersAllocation, kRtpExtensionVideoTiming, kRtpExtensionRtpStreamId, kRtpExtensionRepairedRtpStreamId, diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index d597b1e28..70b073cd7 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -82,13 +82,6 @@ class MockRtpRtcpInterface : public RtpRtcpInterface { MOCK_METHOD(bool, SendingMedia, (), (const, override)); MOCK_METHOD(bool, IsAudioConfigured, (), (const, override)); MOCK_METHOD(void, SetAsPartOfAllocation, (bool), (override)); - MOCK_METHOD(void, - BitrateSent, - (uint32_t * total_rate, - uint32_t* video_rate, - uint32_t* fec_rate, - uint32_t* nack_rate), - (const, override)); MOCK_METHOD(RtpSendRates, GetSendRates, (), (const, override)); MOCK_METHOD(bool, OnSendingRtpFrame, diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc index 6a64d3e23..1da19e476 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc @@ -43,6 +43,7 @@ std::unique_ptr CreateVideoRtpDepacketizer( case kVideoCodecMultiplex: return std::make_unique(); } + RTC_CHECK_NOTREACHED(); } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc index ba091cefb..6cb9d9330 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc @@ -27,11 +27,11 @@ constexpr int kSendSideDelayWindowMs = 1000; constexpr int kBitrateStatisticsWindowMs = 1000; constexpr size_t kRtpSequenceNumberMapMaxEntries = 1 << 13; -bool IsEnabled(absl::string_view name, - const WebRtcKeyValueConfig* field_trials) { +bool IsDisabled(absl::string_view name, + const WebRtcKeyValueConfig* field_trials) { FieldTrialBasedConfig default_trials; auto& trials = field_trials ? *field_trials : default_trials; - return absl::StartsWith(trials.Lookup(name), "Enabled"); + return absl::StartsWith(trials.Lookup(name), "Disabled"); } } // namespace @@ -63,7 +63,7 @@ DEPRECATED_RtpSenderEgress::DEPRECATED_RtpSenderEgress( : absl::nullopt), populate_network2_timestamp_(config.populate_network2_timestamp), send_side_bwe_with_overhead_( - IsEnabled("WebRTC-SendSideBwe-WithOverhead", config.field_trials)), + !IsDisabled("WebRTC-SendSideBwe-WithOverhead", config.field_trials)), clock_(config.clock), packet_history_(packet_history), transport_(config.outgoing_transport), diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.cc index 5e762335e..54f3555fc 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.cc @@ -10,6 +10,9 @@ #include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h" +#include +#include + #include "rtc_base/checks.h" namespace webrtc { @@ -19,16 +22,16 @@ CompoundPacket::CompoundPacket() = default; CompoundPacket::~CompoundPacket() = default; -void CompoundPacket::Append(RtcpPacket* packet) { +void CompoundPacket::Append(std::unique_ptr packet) { RTC_CHECK(packet); - appended_packets_.push_back(packet); + appended_packets_.push_back(std::move(packet)); } bool CompoundPacket::Create(uint8_t* packet, size_t* index, size_t max_length, PacketReadyCallback callback) const { - for (RtcpPacket* appended : appended_packets_) { + for (const auto& appended : appended_packets_) { if (!appended->Create(packet, index, max_length, callback)) return false; } @@ -37,7 +40,7 @@ bool CompoundPacket::Create(uint8_t* packet, size_t CompoundPacket::BlockLength() const { size_t block_length = 0; - for (RtcpPacket* appended : appended_packets_) { + for (const auto& appended : appended_packets_) { block_length += appended->BlockLength(); } return block_length; diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h index f521c7f92..8bee60069 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h @@ -12,6 +12,7 @@ #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_COMPOUND_PACKET_H_ #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_COMPOUND_PACKET_H_ +#include #include #include "modules/rtp_rtcp/source/rtcp_packet.h" @@ -25,7 +26,7 @@ class CompoundPacket : public RtcpPacket { CompoundPacket(); ~CompoundPacket() override; - void Append(RtcpPacket* packet); + void Append(std::unique_ptr packet); // Size of this packet in bytes (i.e. total size of nested packets). size_t BlockLength() const override; @@ -36,7 +37,7 @@ class CompoundPacket : public RtcpPacket { PacketReadyCallback callback) const override; protected: - std::vector appended_packets_; + std::vector> appended_packets_; private: RTC_DISALLOW_COPY_AND_ASSIGN(CompoundPacket); diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc index fae635e1b..61e6085bb 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -37,7 +37,6 @@ #include "modules/rtp_rtcp/source/time_util.h" #include "modules/rtp_rtcp/source/tmmbr_help.h" #include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/trace_event.h" @@ -55,10 +54,10 @@ class PacketContainer : public rtcp::CompoundPacket { public: PacketContainer(Transport* transport, RtcEventLog* event_log) : transport_(transport), event_log_(event_log) {} - ~PacketContainer() override { - for (RtcpPacket* packet : appended_packets_) - delete packet; - } + + PacketContainer() = delete; + PacketContainer(const PacketContainer&) = delete; + PacketContainer& operator=(const PacketContainer&) = delete; size_t SendPackets(size_t max_payload_length) { size_t bytes_sent = 0; @@ -76,8 +75,6 @@ class PacketContainer : public rtcp::CompoundPacket { private: Transport* transport_; RtcEventLog* const event_log_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(PacketContainer); }; // Helper to put several RTCP packets into lower layer datagram RTCP packet. @@ -792,14 +789,14 @@ absl::optional RTCPSender::ComputeCompoundRTCPPacket( if (builder_it->first == kRtcpBye) { packet_bye = std::move(packet); } else { - out_packet->Append(packet.release()); + out_packet->Append(std::move(packet)); } } } // Append the BYE now at the end if (packet_bye) { - out_packet->Append(packet_bye.release()); + out_packet->Append(std::move(packet_bye)); } if (packet_type_counter_observer_ != nullptr) { diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_sender.h index bcdf15eda..22b2bb7b7 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_sender.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtcp_sender.h @@ -31,7 +31,6 @@ #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/random.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -65,6 +64,11 @@ class RTCPSender final { }; explicit RTCPSender(const RtpRtcpInterface::Configuration& config); + + RTCPSender() = delete; + RTCPSender(const RTCPSender&) = delete; + RTCPSender& operator=(const RTCPSender&) = delete; + virtual ~RTCPSender(); RtcpMode Status() const RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); @@ -308,8 +312,6 @@ class RTCPSender final { const RtcpContext&); // Map from RTCPPacketType to builder. std::map builders_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RTCPSender); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_format.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_format.cc index c7a35ee5a..27ce7a6fe 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_format.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_format.cc @@ -53,7 +53,7 @@ std::unique_ptr RtpPacketizer::Create( case kVideoCodecH265: { const auto& h265 = absl::get(rtp_video_header.video_type_header); - return absl::make_unique( + return std::make_unique( payload, limits, h265.packetization_mode); } #endif @@ -68,8 +68,9 @@ std::unique_ptr RtpPacketizer::Create( return std::make_unique(payload, limits, vp9); } case kVideoCodecAV1: - return std::make_unique(payload, limits, - rtp_video_header.frame_type); + return std::make_unique( + payload, limits, rtp_video_header.frame_type, + rtp_video_header.is_last_frame_in_picture); default: { return std::make_unique(payload, limits, rtp_video_header); diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_format_h265.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_format_h265.h index cc950be8d..a1c9665a1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_format_h265.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_format_h265.h @@ -107,7 +107,6 @@ class RtpPacketizerH265 : public RtpPacketizer { const PayloadSizeLimits limits_; size_t num_packets_left_; - RTPFragmentationHeader fragmentation_; RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerH265); }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extension_map.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extension_map.cc index 63562c5b8..c16dcaf6f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extension_map.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extension_map.cc @@ -13,6 +13,7 @@ #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" +#include "modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h" #include "rtc_base/arraysize.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" @@ -40,6 +41,7 @@ constexpr ExtensionInfo kExtensions[] = { CreateExtensionInfo(), CreateExtensionInfo(), CreateExtensionInfo(), + CreateExtensionInfo(), CreateExtensionInfo(), CreateExtensionInfo(), CreateExtensionInfo(), diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc index 527874d78..b540e4b22 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc @@ -371,7 +371,7 @@ constexpr uint8_t PlayoutDelayLimits::kValueSizeBytes; constexpr const char PlayoutDelayLimits::kUri[]; bool PlayoutDelayLimits::Parse(rtc::ArrayView data, - PlayoutDelay* playout_delay) { + VideoPlayoutDelay* playout_delay) { RTC_DCHECK(playout_delay); if (data.size() != 3) return false; @@ -386,7 +386,7 @@ bool PlayoutDelayLimits::Parse(rtc::ArrayView data, } bool PlayoutDelayLimits::Write(rtc::ArrayView data, - const PlayoutDelay& playout_delay) { + const VideoPlayoutDelay& playout_delay) { RTC_DCHECK_EQ(data.size(), 3); RTC_DCHECK_LE(0, playout_delay.min_ms); RTC_DCHECK_LE(playout_delay.min_ms, playout_delay.max_ms); diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h index 8a81280f7..1352611fb 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h @@ -148,7 +148,7 @@ class VideoOrientation { class PlayoutDelayLimits { public: - using value_type = PlayoutDelay; + using value_type = VideoPlayoutDelay; static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay; static constexpr uint8_t kValueSizeBytes = 3; static constexpr const char kUri[] = @@ -162,10 +162,10 @@ class PlayoutDelayLimits { static constexpr int kMaxMs = 0xfff * kGranularityMs; // 40950. static bool Parse(rtc::ArrayView data, - PlayoutDelay* playout_delay); - static size_t ValueSize(const PlayoutDelay&) { return kValueSizeBytes; } + VideoPlayoutDelay* playout_delay); + static size_t ValueSize(const VideoPlayoutDelay&) { return kValueSizeBytes; } static bool Write(rtc::ArrayView data, - const PlayoutDelay& playout_delay); + const VideoPlayoutDelay& playout_delay); }; class VideoContentTypeExtension { diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packet.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packet.cc index 767c9a068..38d29cc2b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packet.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packet.cc @@ -196,6 +196,7 @@ void RtpPacket::ZeroMutableExtensions() { case RTPExtensionType::kRtpExtensionRepairedRtpStreamId: case RTPExtensionType::kRtpExtensionRtpStreamId: case RTPExtensionType::kRtpExtensionVideoContentType: + case RTPExtensionType::kRtpExtensionVideoLayersAllocation: case RTPExtensionType::kRtpExtensionVideoRotation: case RTPExtensionType::kRtpExtensionInbandComfortNoise: { // Non-mutable extension. Don't change it. diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packet_history.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packet_history.h index f249116b7..4a2bf91bd 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packet_history.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packet_history.h @@ -19,7 +19,6 @@ #include "api/function_view.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -63,6 +62,11 @@ class RtpPacketHistory { static constexpr int kPacketCullingDelayFactor = 3; RtpPacketHistory(Clock* clock, bool enable_padding_prio); + + RtpPacketHistory() = delete; + RtpPacketHistory(const RtpPacketHistory&) = delete; + RtpPacketHistory& operator=(const RtpPacketHistory&) = delete; + ~RtpPacketHistory(); // Set/get storage mode. Note that setting the state will clear the history, @@ -211,8 +215,6 @@ class RtpPacketHistory { // Objects from |packet_history_| ordered by "most likely to be useful", used // in GetPayloadPaddingPacket(). PacketPrioritySet padding_priority_ RTC_GUARDED_BY(lock_); - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RtpPacketHistory); }; } // namespace webrtc #endif // MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packetizer_av1.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packetizer_av1.cc index 909b1289e..4408beed3 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packetizer_av1.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packetizer_av1.cc @@ -88,10 +88,12 @@ int MaxFragmentSize(int remaining_bytes) { RtpPacketizerAv1::RtpPacketizerAv1(rtc::ArrayView payload, RtpPacketizer::PayloadSizeLimits limits, - VideoFrameType frame_type) + VideoFrameType frame_type, + bool is_last_frame_in_picture) : frame_type_(frame_type), obus_(ParseObus(payload)), - packets_(Packetize(obus_, limits)) {} + packets_(Packetize(obus_, limits)), + is_last_frame_in_picture_(is_last_frame_in_picture) {} std::vector RtpPacketizerAv1::ParseObus( rtc::ArrayView payload) { @@ -414,11 +416,8 @@ bool RtpPacketizerAv1::NextPacket(RtpPacketToSend* packet) { kAggregationHeaderSize + next_packet.packet_size); ++packet_index_; - if (packet_index_ == packets_.size()) { - // TODO(danilchap): To support spatial scalability pass and use information - // if this frame is the last in the temporal unit. - packet->SetMarker(true); - } + bool is_last_packet_in_frame = packet_index_ == packets_.size(); + packet->SetMarker(is_last_packet_in_frame && is_last_frame_in_picture_); return true; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packetizer_av1.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packetizer_av1.h index 79fa6e02f..520e746ea 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packetizer_av1.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_packetizer_av1.h @@ -26,7 +26,8 @@ class RtpPacketizerAv1 : public RtpPacketizer { public: RtpPacketizerAv1(rtc::ArrayView payload, PayloadSizeLimits limits, - VideoFrameType frame_type); + VideoFrameType frame_type, + bool is_last_frame_in_picture); ~RtpPacketizerAv1() override = default; size_t NumPackets() const override { return packets_.size() - packet_index_; } @@ -63,6 +64,7 @@ class RtpPacketizerAv1 : public RtpPacketizer { const VideoFrameType frame_type_; const std::vector obus_; const std::vector packets_; + const bool is_last_frame_in_picture_; size_t packet_index_ = 0; }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 92abd9be6..b2268c7d1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -727,19 +727,6 @@ void ModuleRtpRtcpImpl::SetRemoteSSRC(const uint32_t ssrc) { rtcp_receiver_.SetRemoteSSRC(ssrc); } -void ModuleRtpRtcpImpl::BitrateSent(uint32_t* total_rate, - uint32_t* video_rate, - uint32_t* fec_rate, - uint32_t* nack_rate) const { - RtpSendRates send_rates = rtp_sender_->packet_sender.GetSendRates(); - *total_rate = send_rates.Sum().bps(); - if (video_rate) - *video_rate = 0; - if (fec_rate) - *fec_rate = 0; - *nack_rate = send_rates[RtpPacketMediaType::kRetransmission].bps(); -} - RtpSendRates ModuleRtpRtcpImpl::GetSendRates() const { return rtp_sender_->packet_sender.GetSendRates(); } diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h index c413efe13..7f7df174f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -264,11 +264,6 @@ class ModuleRtpRtcpImpl : public RtpRtcp, public RTCPReceiver::ModuleRtpRtcp { uint32_t* NTPfrac, uint32_t* remote_sr) const; - void BitrateSent(uint32_t* total_rate, - uint32_t* video_rate, - uint32_t* fec_rate, - uint32_t* nackRate) const override; - RtpSendRates GetSendRates() const override; void OnReceivedNack( diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc index 31e485483..88ede3d43 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc @@ -631,21 +631,6 @@ void ModuleRtpRtcpImpl2::SetRemoteSSRC(const uint32_t ssrc) { rtcp_receiver_.SetRemoteSSRC(ssrc); } -// TODO(nisse): Delete video_rate amd fec_rate arguments. -void ModuleRtpRtcpImpl2::BitrateSent(uint32_t* total_rate, - uint32_t* video_rate, - uint32_t* fec_rate, - uint32_t* nack_rate) const { - RTC_DCHECK_RUN_ON(worker_queue_); - RtpSendRates send_rates = rtp_sender_->packet_sender.GetSendRates(); - *total_rate = send_rates.Sum().bps(); - if (video_rate) - *video_rate = 0; - if (fec_rate) - *fec_rate = 0; - *nack_rate = send_rates[RtpPacketMediaType::kRetransmission].bps(); -} - RtpSendRates ModuleRtpRtcpImpl2::GetSendRates() const { RTC_DCHECK_RUN_ON(worker_queue_); return rtp_sender_->packet_sender.GetSendRates(); diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.h index 9611ace91..9eb7e3a6d 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.h @@ -250,11 +250,6 @@ class ModuleRtpRtcpImpl2 final : public RtpRtcpInterface, uint32_t* NTPfrac, uint32_t* remote_sr) const; - void BitrateSent(uint32_t* total_rate, - uint32_t* video_rate, - uint32_t* fec_rate, - uint32_t* nackRate) const override; - RtpSendRates GetSendRates() const override; void OnReceivedNack( diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_interface.h index f763da244..3bd5d4705 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_interface.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_rtcp_interface.h @@ -267,13 +267,6 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { // bitrate estimate since the stream participates in the bitrate allocation. virtual void SetAsPartOfAllocation(bool part_of_allocation) = 0; - // TODO(sprang): Remove when all call sites have been moved to - // GetSendRates(). Fetches the current send bitrates in bits/s. - virtual void BitrateSent(uint32_t* total_rate, - uint32_t* video_rate, - uint32_t* fec_rate, - uint32_t* nack_rate) const = 0; - // Returns bitrate sent (post-pacing) per packet type. virtual RtpSendRates GetSendRates() const = 0; diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index 119306805..584fced39 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -118,6 +118,7 @@ bool IsNonVolatile(RTPExtensionType type) { case kRtpExtensionVideoRotation: case kRtpExtensionPlayoutDelay: case kRtpExtensionVideoContentType: + case kRtpExtensionVideoLayersAllocation: case kRtpExtensionVideoTiming: case kRtpExtensionRepairedRtpStreamId: case kRtpExtensionColorSpace: @@ -127,6 +128,7 @@ bool IsNonVolatile(RTPExtensionType type) { RTC_NOTREACHED(); return false; } + RTC_CHECK_NOTREACHED(); } bool HasBweExtension(const RtpHeaderExtensionMap& extensions_map) { @@ -338,6 +340,7 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id) { return -1; } packet->set_packet_type(RtpPacketMediaType::kRetransmission); + packet->set_fec_protect_packet(false); std::vector> packets; packets.emplace_back(std::move(packet)); paced_sender_->EnqueuePackets(std::move(packets)); diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender.h index fd1a8da75..1580259b3 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender.h @@ -29,7 +29,6 @@ #include "modules/rtp_rtcp/source/rtp_packet_history.h" #include "modules/rtp_rtcp/source/rtp_rtcp_config.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/deprecation.h" #include "rtc_base/random.h" #include "rtc_base/rate_statistics.h" @@ -49,6 +48,10 @@ class RTPSender { RtpPacketHistory* packet_history, RtpPacketSender* packet_sender); + RTPSender() = delete; + RTPSender(const RTPSender&) = delete; + RTPSender& operator=(const RTPSender&) = delete; + ~RTPSender(); void SetSendingMediaStatus(bool enabled) RTC_LOCKS_EXCLUDED(send_mutex_); @@ -230,8 +233,6 @@ class RTPSender { bool supports_bwe_extension_ RTC_GUARDED_BY(send_mutex_); RateLimiter* const retransmission_rate_limiter_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RTPSender); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc index d15e7458a..8cf60aaec 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc @@ -46,15 +46,22 @@ const char* FrameTypeToString(AudioFrameType frame_type) { case AudioFrameType::kAudioFrameCN: return "audio_cn"; } + RTC_CHECK_NOTREACHED(); } #endif +constexpr char kIncludeCaptureClockOffset[] = + "WebRTC-IncludeCaptureClockOffset"; + } // namespace RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender) : clock_(clock), rtp_sender_(rtp_sender), - absolute_capture_time_sender_(clock) { + absolute_capture_time_sender_(clock), + include_capture_clock_offset_( + absl::StartsWith(field_trials_.Lookup(kIncludeCaptureClockOffset), + "Enabled")) { RTC_DCHECK(clock_); } @@ -280,7 +287,8 @@ bool RTPSenderAudio::SendAudio(AudioFrameType frame_type, // absolute capture time sending. encoder_rtp_timestamp_frequency.value_or(0), Int64MsToUQ32x32(absolute_capture_timestamp_ms + NtpOffsetMs()), - /*estimated_capture_clock_offset=*/absl::nullopt); + /*estimated_capture_clock_offset=*/ + include_capture_clock_offset_ ? absl::make_optional(0) : absl::nullopt); if (absolute_capture_time) { // It also checks that extension was registered during SDP negotiation. If // not then setter won't do anything. diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h index 3d3ca52c8..57b9dd7ce 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h @@ -17,11 +17,11 @@ #include #include "absl/strings/string_view.h" +#include "api/transport/field_trial_based_config.h" #include "modules/audio_coding/include/audio_coding_module_typedefs.h" #include "modules/rtp_rtcp/source/absolute_capture_time_sender.h" #include "modules/rtp_rtcp/source/dtmf_queue.h" #include "modules/rtp_rtcp/source/rtp_sender.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/one_time_event.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -32,6 +32,11 @@ namespace webrtc { class RTPSenderAudio { public: RTPSenderAudio(Clock* clock, RTPSender* rtp_sender); + + RTPSenderAudio() = delete; + RTPSenderAudio(const RTPSenderAudio&) = delete; + RTPSenderAudio& operator=(const RTPSenderAudio&) = delete; + ~RTPSenderAudio(); int32_t RegisterAudioPayload(absl::string_view payload_name, @@ -106,7 +111,8 @@ class RTPSenderAudio { AbsoluteCaptureTimeSender absolute_capture_time_sender_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RTPSenderAudio); + const FieldTrialBasedConfig field_trials_; + const bool include_capture_clock_offset_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_egress.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_egress.cc index c89b9e42c..aba23ddc4 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_egress.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_egress.cc @@ -30,11 +30,12 @@ constexpr size_t kRtpSequenceNumberMapMaxEntries = 1 << 13; constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(kBitrateStatisticsWindowMs); -bool IsEnabled(absl::string_view name, - const WebRtcKeyValueConfig* field_trials) { +bool IsTrialSetTo(const WebRtcKeyValueConfig* field_trials, + absl::string_view name, + absl::string_view value) { FieldTrialBasedConfig default_trials; auto& trials = field_trials ? *field_trials : default_trials; - return absl::StartsWith(trials.Lookup(name), "Enabled"); + return absl::StartsWith(trials.Lookup(name), value); } } // namespace @@ -89,7 +90,9 @@ RtpSenderEgress::RtpSenderEgress(const RtpRtcpInterface::Configuration& config, : absl::nullopt), populate_network2_timestamp_(config.populate_network2_timestamp), send_side_bwe_with_overhead_( - IsEnabled("WebRTC-SendSideBwe-WithOverhead", config.field_trials)), + !IsTrialSetTo(config.field_trials, + "WebRTC-SendSideBwe-WithOverhead", + "Disabled")), clock_(config.clock), packet_history_(packet_history), transport_(config.outgoing_transport), @@ -98,10 +101,7 @@ RtpSenderEgress::RtpSenderEgress(const RtpRtcpInterface::Configuration& config, is_audio_(config.audio), #endif need_rtp_packet_infos_(config.need_rtp_packet_infos), - fec_generator_( - IsEnabled("WebRTC-DeferredFecGeneration", config.field_trials) - ? config.fec_generator - : nullptr), + fec_generator_(config.fec_generator), transport_feedback_observer_(config.transport_feedback_callback), send_side_delay_observer_(config.send_side_delay_observer), send_packet_observer_(config.send_packet_observer), @@ -172,7 +172,7 @@ void RtpSenderEgress::SendPacket(RtpPacketToSend* packet, } if (fec_generator_ && packet->fec_protect_packet()) { - // Deferred fec generation is used, add packet to generator. + // This packet should be protected by FEC, add it to packet generator. RTC_DCHECK(fec_generator_); RTC_DCHECK(packet->packet_type() == RtpPacketMediaType::kVideo); absl::optional> diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc index 43b31ddff..55ba9b054 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -34,8 +34,10 @@ #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h" #include "modules/rtp_rtcp/source/time_util.h" #include "rtc_base/checks.h" +#include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/logging.h" #include "rtc_base/trace_event.h" @@ -44,6 +46,8 @@ namespace webrtc { namespace { constexpr size_t kRedForFecHeaderLength = 1; constexpr int64_t kMaxUnretransmittableFrameIntervalMs = 33 * 4; +constexpr char kIncludeCaptureClockOffset[] = + "WebRTC-IncludeCaptureClockOffset"; void BuildRedPayload(const RtpPacketToSend& media_packet, RtpPacketToSend* red_packet) { @@ -109,10 +113,35 @@ const char* FrameTypeToString(VideoFrameType frame_type) { } #endif -bool IsNoopDelay(const PlayoutDelay& delay) { +bool IsNoopDelay(const VideoPlayoutDelay& delay) { return delay.min_ms == -1 && delay.max_ms == -1; } +absl::optional LoadVideoPlayoutDelayOverride( + const WebRtcKeyValueConfig* key_value_config) { + RTC_DCHECK(key_value_config); + FieldTrialOptional playout_delay_min_ms("min_ms", absl::nullopt); + FieldTrialOptional playout_delay_max_ms("max_ms", absl::nullopt); + ParseFieldTrial({&playout_delay_max_ms, &playout_delay_min_ms}, + key_value_config->Lookup("WebRTC-ForceSendPlayoutDelay")); + return playout_delay_max_ms && playout_delay_min_ms + ? absl::make_optional(*playout_delay_min_ms, + *playout_delay_max_ms) + : absl::nullopt; +} + +// Some packets can be skipped and the stream can still be decoded. Those +// packets are less likely to be retransmitted if they are lost. +bool PacketWillLikelyBeRequestedForRestransmitionIfLost( + const RTPVideoHeader& video_header) { + return IsBaseLayer(video_header) && + !(video_header.generic.has_value() + ? absl::c_linear_search( + video_header.generic->decode_target_indications, + DecodeTargetIndication::kDiscardable) + : false); +} + } // namespace RTPSenderVideo::RTPSenderVideo(const Config& config) @@ -124,13 +153,13 @@ RTPSenderVideo::RTPSenderVideo(const Config& config) : (kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers)), last_rotation_(kVideoRotation_0), transmit_color_space_next_frame_(false), + send_allocation_(false), current_playout_delay_{-1, -1}, playout_delay_pending_(false), + forced_playout_delay_(LoadVideoPlayoutDelayOverride(config.field_trials)), red_payload_type_(config.red_payload_type), - fec_generator_(config.fec_generator), fec_type_(config.fec_type), fec_overhead_bytes_(config.fec_overhead_bytes), - video_bitrate_(1000, RateStatistics::kBpsScale), packetization_overhead_bitrate_(1000, RateStatistics::kBpsScale), frame_encryptor_(config.frame_encryptor), require_frame_encryption_(config.require_frame_encryption), @@ -146,7 +175,10 @@ RTPSenderVideo::RTPSenderVideo(const Config& config) config.frame_transformer, rtp_sender_->SSRC(), config.send_transport_queue) - : nullptr) { + : nullptr), + include_capture_clock_offset_(absl::StartsWith( + config.field_trials->Lookup(kIncludeCaptureClockOffset), + "Enabled")) { if (frame_transformer_delegate_) frame_transformer_delegate_->Init(); } @@ -159,27 +191,11 @@ RTPSenderVideo::~RTPSenderVideo() { void RTPSenderVideo::LogAndSendToNetwork( std::vector> packets, size_t unpacketized_payload_size) { - int64_t now_ms = clock_->TimeInMilliseconds(); -#if BWE_TEST_LOGGING_COMPILE_TIME_ENABLE - if (fec_generator_) { - uint32_t fec_rate_kbps = fec_generator_->CurrentFecRate().kbps(); - for (const auto& packet : packets) { - if (packet->packet_type() == - RtpPacketMediaType::kForwardErrorCorrection) { - const uint32_t ssrc = packet->Ssrc(); - BWE_TEST_LOGGING_PLOT_WITH_SSRC(1, "VideoFecBitrate_kbps", now_ms, - fec_rate_kbps, ssrc); - } - } - } -#endif - { MutexLock lock(&stats_mutex_); size_t packetized_payload_size = 0; for (const auto& packet : packets) { if (*packet->packet_type() == RtpPacketMediaType::kVideo) { - video_bitrate_.Update(packet->size(), now_ms); packetized_payload_size += packet->payload_size(); } } @@ -221,11 +237,15 @@ void RTPSenderVideo::SetVideoStructure( frame_transformer_delegate_->SetVideoStructureUnderLock(video_structure); return; } - // Lock is being held by SetVideoStructure() caller. - SetVideoStructureUnderLock(video_structure); + SetVideoStructureInternal(video_structure); } -void RTPSenderVideo::SetVideoStructureUnderLock( +void RTPSenderVideo::SetVideoStructureAfterTransformation( + const FrameDependencyStructure* video_structure) { + SetVideoStructureInternal(video_structure); +} + +void RTPSenderVideo::SetVideoStructureInternal( const FrameDependencyStructure* video_structure) { RTC_DCHECK_RUNS_SERIALIZED(&send_checker_); if (video_structure == nullptr) { @@ -255,6 +275,28 @@ void RTPSenderVideo::SetVideoStructureUnderLock( video_structure_->structure_id = structure_id; } +void RTPSenderVideo::SetVideoLayersAllocation( + VideoLayersAllocation allocation) { + if (frame_transformer_delegate_) { + frame_transformer_delegate_->SetVideoLayersAllocationUnderLock( + std::move(allocation)); + return; + } + SetVideoLayersAllocationInternal(std::move(allocation)); +} + +void RTPSenderVideo::SetVideoLayersAllocationAfterTransformation( + VideoLayersAllocation allocation) { + SetVideoLayersAllocationInternal(std::move(allocation)); +} + +void RTPSenderVideo::SetVideoLayersAllocationInternal( + VideoLayersAllocation allocation) { + RTC_DCHECK_RUNS_SERIALIZED(&send_checker_); + allocation_ = std::move(allocation); + send_allocation_ = true; +} + void RTPSenderVideo::AddRtpHeaderExtensions( const RTPVideoHeader& video_header, const absl::optional& absolute_capture_time, @@ -340,10 +382,15 @@ void RTPSenderVideo::AddRtpHeaderExtensions( descriptor.active_decode_targets_bitmask = active_decode_targets_tracker_.ActiveDecodeTargetsBitmask(); } - // To avoid extra structure copy, temporary share ownership of the - // video_structure with the dependency descriptor. + // VP9 mark all layer frames of the first picture as kVideoFrameKey, + // Structure should be attached to the descriptor to lowest spatial layer + // when inter layer dependency is used, i.e. L structures; or to all + // layers when inter layer dependency is not used, i.e. S structures. + // Distinguish these two cases by checking if there are any dependencies. if (video_header.frame_type == VideoFrameType::kVideoFrameKey && - first_packet) { + video_header.generic->dependencies.empty() && first_packet) { + // To avoid extra structure copy, temporary share ownership of the + // video_structure with the dependency descriptor. descriptor.attached_structure = absl::WrapUnique(video_structure_.get()); } @@ -385,6 +432,18 @@ void RTPSenderVideo::AddRtpHeaderExtensions( generic_descriptor); } } + + if (first_packet && send_allocation_) { + if (video_header.frame_type == VideoFrameType::kVideoFrameKey) { + packet->SetExtension( + allocation_.value()); + } else if (PacketWillLikelyBeRequestedForRestransmitionIfLost( + video_header)) { + VideoLayersAllocation allocation = allocation_.value(); + allocation.resolution_and_frame_rate_is_valid = false; + packet->SetExtension(allocation); + } + } } bool RTPSenderVideo::SendVideo( @@ -394,7 +453,8 @@ bool RTPSenderVideo::SendVideo( int64_t capture_time_ms, rtc::ArrayView payload, RTPVideoHeader video_header, - absl::optional expected_retransmission_time_ms) { + absl::optional expected_retransmission_time_ms, + absl::optional estimated_capture_clock_offset_ms) { #if RTC_TRACE_EVENTS_ENABLED TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms, "Send", "type", FrameTypeToString(video_header.frame_type)); @@ -414,10 +474,15 @@ bool RTPSenderVideo::SendVideo( } MaybeUpdateCurrentPlayoutDelay(video_header); - if (video_header.frame_type == VideoFrameType::kVideoFrameKey && - !IsNoopDelay(current_playout_delay_)) { - // Force playout delay on key-frames, if set. - playout_delay_pending_ = true; + if (video_header.frame_type == VideoFrameType::kVideoFrameKey) { + if (!IsNoopDelay(current_playout_delay_)) { + // Force playout delay on key-frames, if set. + playout_delay_pending_ = true; + } + if (allocation_) { + // Send the bitrate allocation on every key frame. + send_allocation_ = true; + } } if (video_structure_ != nullptr && video_header.generic) { @@ -428,9 +493,15 @@ bool RTPSenderVideo::SendVideo( video_header.generic->frame_id, video_header.generic->chain_diffs); } + const uint8_t temporal_id = GetTemporalId(video_header); + // No FEC protection for upper temporal layers, if used. + const bool use_fec = fec_type_.has_value() && + (temporal_id == 0 || temporal_id == kNoTemporalIdx); + // Maximum size of packet including rtp headers. // Extra space left in case packet will be resent using fec or rtx. - int packet_capacity = rtp_sender_->MaxRtpPacketSize() - FecPacketOverhead() - + int packet_capacity = rtp_sender_->MaxRtpPacketSize() - + (use_fec ? FecPacketOverhead() : 0) - (rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0); std::unique_ptr single_packet = @@ -446,7 +517,9 @@ bool RTPSenderVideo::SendVideo( single_packet->Csrcs()), single_packet->Timestamp(), kVideoPayloadTypeFrequency, Int64MsToUQ32x32(single_packet->capture_time_ms() + NtpOffsetMs()), - /*estimated_capture_clock_offset=*/absl::nullopt); + /*estimated_capture_clock_offset=*/ + include_capture_clock_offset_ ? estimated_capture_clock_offset_ms + : absl::nullopt); auto first_packet = std::make_unique(*single_packet); auto middle_packet = std::make_unique(*single_packet); @@ -488,8 +561,8 @@ bool RTPSenderVideo::SendVideo( first_packet->HasExtension() || first_packet->HasExtension(); - // Minimization of the vp8 descriptor may erase temporal_id, so save it. - const uint8_t temporal_id = GetTemporalId(video_header); + // Minimization of the vp8 descriptor may erase temporal_id, so use + // |temporal_id| rather than reference |video_header| beyond this point. if (has_generic_descriptor) { MinimizeDescriptor(&video_header); } @@ -582,18 +655,11 @@ bool RTPSenderVideo::SendVideo( packet->set_packetization_finish_time_ms(clock_->TimeInMilliseconds()); } - // No FEC protection for upper temporal layers, if used. - if (fec_type_.has_value() && - (temporal_id == 0 || temporal_id == kNoTemporalIdx)) { - if (fec_generator_) { - fec_generator_->AddPacketAndGenerateFec(*packet); - } else { - // Deferred FEC generation, just mark packet. - packet->set_fec_protect_packet(true); - } - } + packet->set_fec_protect_packet(use_fec); if (red_enabled()) { + // TODO(sprang): Consider packetizing directly into packets with the RED + // header already in place, to avoid this copy. std::unique_ptr red_packet(new RtpPacketToSend(*packet)); BuildRedPayload(*packet, red_packet.get()); red_packet->SetPayloadType(*red_payload_type_); @@ -620,19 +686,6 @@ bool RTPSenderVideo::SendVideo( } } - if (fec_generator_) { - // Fetch any FEC packets generated from the media frame and add them to - // the list of packets to send. - auto fec_packets = fec_generator_->GetFecPackets(); - const bool generate_sequence_numbers = !fec_generator_->FecSsrc(); - for (auto& fec_packet : fec_packets) { - if (generate_sequence_numbers) { - rtp_sender_->AssignSequenceNumber(fec_packet.get()); - } - rtp_packets.emplace_back(std::move(fec_packet)); - } - } - LogAndSendToNetwork(std::move(rtp_packets), payload.size()); // Update details about the last sent frame. @@ -647,15 +700,11 @@ bool RTPSenderVideo::SendVideo( } if (video_header.frame_type == VideoFrameType::kVideoFrameKey || - (IsBaseLayer(video_header) && - !(video_header.generic.has_value() - ? absl::c_linear_search( - video_header.generic->decode_target_indications, - DecodeTargetIndication::kDiscardable) - : false))) { - // This frame has guaranteed delivery, no need to populate playout + PacketWillLikelyBeRequestedForRestransmitionIfLost(video_header)) { + // This frame will likely be delivered, no need to populate playout // delay extensions until it changes again. playout_delay_pending_ = false; + send_allocation_ = false; } TRACE_EVENT_ASYNC_END1("webrtc", "Video", capture_time_ms, "timestamp", @@ -681,11 +730,6 @@ bool RTPSenderVideo::SendEncodedImage( expected_retransmission_time_ms); } -uint32_t RTPSenderVideo::VideoBitrateSent() const { - MutexLock lock(&stats_mutex_); - return video_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); -} - uint32_t RTPSenderVideo::PacketizationOverheadBps() const { MutexLock lock(&stats_mutex_); return packetization_overhead_bitrate_.Rate(clock_->TimeInMilliseconds()) @@ -785,12 +829,13 @@ bool RTPSenderVideo::UpdateConditionalRetransmit( void RTPSenderVideo::MaybeUpdateCurrentPlayoutDelay( const RTPVideoHeader& header) { - if (IsNoopDelay(header.playout_delay)) { + VideoPlayoutDelay requested_delay = + forced_playout_delay_.value_or(header.playout_delay); + + if (IsNoopDelay(requested_delay)) { return; } - PlayoutDelay requested_delay = header.playout_delay; - if (requested_delay.min_ms > PlayoutDelayLimits::kMaxMs || requested_delay.max_ms > PlayoutDelayLimits::kMaxMs) { RTC_DLOG(LS_ERROR) diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h index e8cba5073..3f431dfec 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h @@ -24,6 +24,7 @@ #include "api/transport/rtp/dependency_descriptor.h" #include "api/video/video_codec_type.h" #include "api/video/video_frame_type.h" +#include "api/video/video_layers_allocation.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/absolute_capture_time_sender.h" #include "modules/rtp_rtcp/source/active_decode_targets_helper.h" @@ -70,8 +71,6 @@ class RTPSenderVideo { // expected to outlive the RTPSenderVideo object they are passed to. Clock* clock = nullptr; RTPSender* rtp_sender = nullptr; - FlexfecSender* flexfec_sender = nullptr; - VideoFecGenerator* fec_generator = nullptr; // Some FEC data is duplicated here in preparation of moving FEC to // the egress stage. absl::optional fec_type; @@ -91,13 +90,19 @@ class RTPSenderVideo { // expected_retransmission_time_ms.has_value() -> retransmission allowed. // Calls to this method is assumed to be externally serialized. + // |estimated_capture_clock_offset_ms| is an estimated clock offset between + // this sender and the original capturer, for this video packet. See + // http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time for more + // details. If the sender and the capture has the same clock, it is supposed + // to be zero valued, which is given as the default. bool SendVideo(int payload_type, absl::optional codec_type, uint32_t rtp_timestamp, int64_t capture_time_ms, rtc::ArrayView payload, RTPVideoHeader video_header, - absl::optional expected_retransmission_time_ms); + absl::optional expected_retransmission_time_ms, + absl::optional estimated_capture_clock_offset_ms = 0); bool SendEncodedImage( int payload_type, @@ -113,14 +118,27 @@ class RTPSenderVideo { // All calls to SendVideo after this call must use video_header compatible // with the video_structure. void SetVideoStructure(const FrameDependencyStructure* video_structure); - void SetVideoStructureUnderLock( + // Should only be used by a RTPSenderVideoFrameTransformerDelegate and exists + // to ensure correct syncronization. + void SetVideoStructureAfterTransformation( const FrameDependencyStructure* video_structure); - uint32_t VideoBitrateSent() const; + // Sets current active VideoLayersAllocation. The allocation will be sent + // using the rtp video layers allocation extension. The allocation will be + // sent in full on every key frame. The allocation will be sent once on a + // none discardable delta frame per call to this method and will not contain + // resolution and frame rate. + void SetVideoLayersAllocation(VideoLayersAllocation allocation); + // Should only be used by a RTPSenderVideoFrameTransformerDelegate and exists + // to ensure correct syncronization. + void SetVideoLayersAllocationAfterTransformation( + VideoLayersAllocation allocation); // Returns the current packetization overhead rate, in bps. Note that this is // the payload overhead, eg the VP8 payload headers, not the RTP headers // or extension/ + // TODO(sprang): Consider moving this to RtpSenderEgress so it's in the same + // place as the other rate stats. uint32_t PacketizationOverheadBps() const; protected: @@ -141,6 +159,10 @@ class RTPSenderVideo { int64_t last_frame_time_ms; }; + void SetVideoStructureInternal( + const FrameDependencyStructure* video_structure); + void SetVideoLayersAllocationInternal(VideoLayersAllocation allocation); + void AddRtpHeaderExtensions( const RTPVideoHeader& video_header, const absl::optional& absolute_capture_time, @@ -177,24 +199,28 @@ class RTPSenderVideo { bool transmit_color_space_next_frame_ RTC_GUARDED_BY(send_checker_); std::unique_ptr video_structure_ RTC_GUARDED_BY(send_checker_); + absl::optional allocation_ + RTC_GUARDED_BY(send_checker_); + // Flag indicating if we should send |allocation_|. + bool send_allocation_ RTC_GUARDED_BY(send_checker_); // Current target playout delay. - PlayoutDelay current_playout_delay_ RTC_GUARDED_BY(send_checker_); - // Flag indicating if we need to propagate |current_playout_delay_| in order + VideoPlayoutDelay current_playout_delay_ RTC_GUARDED_BY(send_checker_); + // Flag indicating if we need to send |current_playout_delay_| in order // to guarantee it gets delivered. bool playout_delay_pending_; + // Set by the field trial WebRTC-ForceSendPlayoutDelay to override the playout + // delay of outgoing video frames. + const absl::optional forced_playout_delay_; // Should never be held when calling out of this class. Mutex mutex_; const absl::optional red_payload_type_; - VideoFecGenerator* const fec_generator_; absl::optional fec_type_; const size_t fec_overhead_bytes_; // Per packet max FEC overhead. mutable Mutex stats_mutex_; - // Bitrate used for video payload and RTP headers. - RateStatistics video_bitrate_ RTC_GUARDED_BY(stats_mutex_); RateStatistics packetization_overhead_bitrate_ RTC_GUARDED_BY(stats_mutex_); std::map frame_stats_by_temporal_layer_ @@ -218,6 +244,8 @@ class RTPSenderVideo { const rtc::scoped_refptr frame_transformer_delegate_; + + const bool include_capture_clock_offset_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc index 786e46777..074b64086 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc @@ -162,7 +162,14 @@ void RTPSenderVideoFrameTransformerDelegate::SetVideoStructureUnderLock( const FrameDependencyStructure* video_structure) { MutexLock lock(&sender_lock_); RTC_CHECK(sender_); - sender_->SetVideoStructureUnderLock(video_structure); + sender_->SetVideoStructureAfterTransformation(video_structure); +} + +void RTPSenderVideoFrameTransformerDelegate::SetVideoLayersAllocationUnderLock( + VideoLayersAllocation allocation) { + MutexLock lock(&sender_lock_); + RTC_CHECK(sender_); + sender_->SetVideoLayersAllocationAfterTransformation(std::move(allocation)); } void RTPSenderVideoFrameTransformerDelegate::Reset() { diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h index a14ce3a81..857386929 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h @@ -16,6 +16,7 @@ #include "api/frame_transformer_interface.h" #include "api/scoped_refptr.h" #include "api/task_queue/task_queue_base.h" +#include "api/video/video_layers_allocation.h" #include "rtc_base/synchronization/mutex.h" namespace webrtc { @@ -51,10 +52,16 @@ class RTPSenderVideoFrameTransformerDelegate : public TransformedFrameCallback { // Delegates the call to RTPSendVideo::SendVideo on the |encoder_queue_|. void SendVideo(std::unique_ptr frame) const; - // Delegates the call to RTPSendVideo::SendVideo under |sender_lock_|. + // Delegates the call to RTPSendVideo::SetVideoStructureAfterTransformation + // under |sender_lock_|. void SetVideoStructureUnderLock( const FrameDependencyStructure* video_structure); + // Delegates the call to + // RTPSendVideo::SetVideoLayersAllocationAfterTransformation under + // |sender_lock_|. + void SetVideoLayersAllocationUnderLock(VideoLayersAllocation allocation); + // Unregisters and releases the |frame_transformer_| reference, and resets // |sender_| under lock. Called from RTPSenderVideo destructor to prevent the // |sender_| to dangle. diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_utility.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_utility.cc index c25fd96fa..a3d6d6f7f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_utility.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_utility.cc @@ -492,6 +492,10 @@ void RtpHeaderParser::ParseOneByteExtensionHeader( &header->extension.video_timing); break; } + case kRtpExtensionVideoLayersAllocation: + RTC_LOG(WARNING) << "VideoLayersAllocation extension unsupported by " + "rtp header parser."; + break; case kRtpExtensionRtpStreamId: { std::string name(reinterpret_cast(ptr), len + 1); if (IsLegalRsidName(name)) { diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_header.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_header.h index 8789906dc..b5934ff8b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_header.h +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_header.h @@ -23,7 +23,6 @@ #include "api/video/video_frame_type.h" #include "api/video/video_rotation.h" #include "api/video/video_timing.h" -#include "common_types.h" // NOLINT(build/include_directory) #include "modules/video_coding/codecs/h264/include/h264_globals.h" #ifndef DISABLE_H265 #include "modules/video_coding/codecs/h265/include/h265_globals.h" @@ -83,10 +82,11 @@ struct RTPVideoHeader { VideoContentType content_type = VideoContentType::UNSPECIFIED; bool is_first_packet_in_frame = false; bool is_last_packet_in_frame = false; + bool is_last_frame_in_picture = true; uint8_t simulcastIdx = 0; VideoCodecType codec = VideoCodecType::kVideoCodecGeneric; - PlayoutDelay playout_delay = {-1, -1}; + VideoPlayoutDelay playout_delay; VideoSendTiming video_timing; absl::optional color_space; RTPVideoTypeHeader video_type_header; diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.cc b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.cc new file mode 100644 index 000000000..dbaa36b15 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.cc @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2020 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/rtp_rtcp/source/rtp_video_layers_allocation_extension.h" + +#include + +#include "api/video/video_layers_allocation.h" +#include "rtc_base/bit_buffer.h" + +namespace webrtc { + +constexpr RTPExtensionType RtpVideoLayersAllocationExtension::kId; +constexpr const char RtpVideoLayersAllocationExtension::kUri[]; + +namespace { + +// Counts the number of bits used in the binary representation of val. +size_t CountBits(uint64_t val) { + size_t bit_count = 0; + while (val != 0) { + bit_count++; + val >>= 1; + } + return bit_count; +} + +// Counts the number of bits used if `val`is encoded using unsigned exponential +// Golomb encoding. +// TODO(bugs.webrtc.org/12000): Move to bit_buffer.cc if Golomb encoding is used +// in the final version. +size_t SizeExponentialGolomb(uint32_t val) { + if (val == std::numeric_limits::max()) { + return 0; + } + uint64_t val_to_encode = static_cast(val) + 1; + return CountBits(val_to_encode) * 2 - 1; +} + +} // namespace + +// TODO(bugs.webrtc.org/12000): Review and revise the content and encoding of +// this extension. This is an experimental first version. + +// 0 1 2 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | NS|RSID|T|X|Res| Bit encoded data... +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// NS: Number of spatial layers/simulcast streams - 1. 2 bits, thus allowing +// passing number of layers/streams up-to 4. +// RSID: RTP stream id this allocation is sent on, numbered from 0. 2 bits. +// T: indicates if all spatial layers have the same amount of temporal layers. +// X: indicates if resolution and frame rate per spatial layer is present. +// Res: 2 bits reserved for future use. +// Bit encoded data: consists of following fields written in order: +// 1) T=1: Nt - 2-bit value of number of temporal layers - 1 +// T=0: NS 2-bit values of numbers of temporal layers - 1 for all spatial +// layers from lower to higher. +// 2) Bitrates: +// One value for each spatial x temporal layer. +// Format: RSID (2-bit) SID(2-bit),folowed by bitrate for all temporal +// layers for the RSID,SID tuple. All bitrates are in kbps. All bitrates are +// total required bitrate to receive the corresponding layer, i.e. in +// simulcast mode they include only corresponding spatial layer, in full-svc +// all lower spatial layers are included. All lower temporal layers are also +// included. All bitrates are written using unsigned Exponential Golomb +// encoding. +// 3) [only if X bit is set]. Encoded width, 16-bit, height, 16-bit, +// max frame rate 8-bit per spatial layer in order from lower to higher. + +bool RtpVideoLayersAllocationExtension::Write( + rtc::ArrayView data, + const VideoLayersAllocation& allocation) { + RTC_DCHECK_LT(allocation.rtp_stream_index, + VideoLayersAllocation::kMaxSpatialIds); + RTC_DCHECK_GE(data.size(), ValueSize(allocation)); + rtc::BitBufferWriter writer(data.data(), data.size()); + + // NS: + if (allocation.active_spatial_layers.empty()) + return false; + writer.WriteBits(allocation.active_spatial_layers.size() - 1, 2); + + // RSID: + writer.WriteBits(allocation.rtp_stream_index, 2); + + // T: + bool num_tls_is_the_same = true; + size_t first_layers_number_of_temporal_layers = + allocation.active_spatial_layers.front() + .target_bitrate_per_temporal_layer.size(); + for (const auto& spatial_layer : allocation.active_spatial_layers) { + if (first_layers_number_of_temporal_layers != + spatial_layer.target_bitrate_per_temporal_layer.size()) { + num_tls_is_the_same = false; + break; + } + } + writer.WriteBits(num_tls_is_the_same ? 1 : 0, 1); + + // X: + writer.WriteBits(allocation.resolution_and_frame_rate_is_valid ? 1 : 0, 1); + + // RESERVED: + writer.WriteBits(/*val=*/0, /*bit_count=*/2); + + if (num_tls_is_the_same) { + writer.WriteBits(first_layers_number_of_temporal_layers - 1, 2); + } else { + for (const auto& spatial_layer : allocation.active_spatial_layers) { + writer.WriteBits( + spatial_layer.target_bitrate_per_temporal_layer.size() - 1, 2); + } + } + + for (const auto& spatial_layer : allocation.active_spatial_layers) { + writer.WriteBits(spatial_layer.rtp_stream_index, 2); + writer.WriteBits(spatial_layer.spatial_id, 2); + for (const DataRate& bitrate : + spatial_layer.target_bitrate_per_temporal_layer) { + writer.WriteExponentialGolomb(bitrate.kbps()); + } + } + + if (allocation.resolution_and_frame_rate_is_valid) { + for (const auto& spatial_layer : allocation.active_spatial_layers) { + writer.WriteUInt16(spatial_layer.width); + writer.WriteUInt16(spatial_layer.height); + writer.WriteUInt8(spatial_layer.frame_rate_fps); + } + } + return true; +} + +bool RtpVideoLayersAllocationExtension::Parse( + rtc::ArrayView data, + VideoLayersAllocation* allocation) { + if (data.size() == 0) + return false; + rtc::BitBuffer reader(data.data(), data.size()); + if (!allocation) + return false; + allocation->active_spatial_layers.clear(); + + uint32_t val; + // NS: + if (!reader.ReadBits(&val, 2)) + return false; + int active_spatial_layers = val + 1; + + // RSID: + if (!reader.ReadBits(&val, 2)) + return false; + allocation->rtp_stream_index = val; + + // T: + if (!reader.ReadBits(&val, 1)) + return false; + bool num_tls_is_constant = (val == 1); + + // X: + if (!reader.ReadBits(&val, 1)) + return false; + allocation->resolution_and_frame_rate_is_valid = (val == 1); + + // RESERVED: + if (!reader.ReadBits(&val, 2)) + return false; + + int number_of_temporal_layers[VideoLayersAllocation::kMaxSpatialIds]; + if (num_tls_is_constant) { + if (!reader.ReadBits(&val, 2)) + return false; + for (int sl_idx = 0; sl_idx < active_spatial_layers; ++sl_idx) { + number_of_temporal_layers[sl_idx] = val + 1; + } + } else { + for (int sl_idx = 0; sl_idx < active_spatial_layers; ++sl_idx) { + if (!reader.ReadBits(&val, 2)) + return false; + number_of_temporal_layers[sl_idx] = val + 1; + if (number_of_temporal_layers[sl_idx] > + VideoLayersAllocation::kMaxTemporalIds) + return false; + } + } + + for (int sl_idx = 0; sl_idx < active_spatial_layers; ++sl_idx) { + allocation->active_spatial_layers.emplace_back(); + auto& spatial_layer = allocation->active_spatial_layers.back(); + auto& temporal_layers = spatial_layer.target_bitrate_per_temporal_layer; + if (!reader.ReadBits(&val, 2)) + return false; + spatial_layer.rtp_stream_index = val; + if (!reader.ReadBits(&val, 2)) + return false; + spatial_layer.spatial_id = val; + for (int tl_idx = 0; tl_idx < number_of_temporal_layers[sl_idx]; ++tl_idx) { + reader.ReadExponentialGolomb(&val); + temporal_layers.push_back(DataRate::KilobitsPerSec(val)); + } + } + + if (allocation->resolution_and_frame_rate_is_valid) { + for (auto& spatial_layer : allocation->active_spatial_layers) { + if (!reader.ReadUInt16(&spatial_layer.width)) + return false; + if (!reader.ReadUInt16(&spatial_layer.height)) + return false; + if (!reader.ReadUInt8(&spatial_layer.frame_rate_fps)) + return false; + } + } + return true; +} + +size_t RtpVideoLayersAllocationExtension::ValueSize( + const VideoLayersAllocation& allocation) { + if (allocation.active_spatial_layers.empty()) { + return 0; + } + size_t size_in_bits = 8; // Fixed first byte.¨ + bool num_tls_is_the_same = true; + size_t first_layers_number_of_temporal_layers = + allocation.active_spatial_layers.front() + .target_bitrate_per_temporal_layer.size(); + for (const auto& spatial_layer : allocation.active_spatial_layers) { + if (first_layers_number_of_temporal_layers != + spatial_layer.target_bitrate_per_temporal_layer.size()) { + num_tls_is_the_same = false; + } + size_in_bits += 4; // RSID, SID tuple. + for (const auto& bitrate : + spatial_layer.target_bitrate_per_temporal_layer) { + size_in_bits += SizeExponentialGolomb(bitrate.kbps()); + } + } + if (num_tls_is_the_same) { + size_in_bits += 2; + } else { + for (const auto& spatial_layer : allocation.active_spatial_layers) { + size_in_bits += + 2 * spatial_layer.target_bitrate_per_temporal_layer.size(); + } + } + if (allocation.resolution_and_frame_rate_is_valid) { + size_in_bits += allocation.active_spatial_layers.size() * 5 * 8; + } + return (size_in_bits + 7) / 8; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h new file mode 100644 index 000000000..ff8ea2a7a --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef MODULES_RTP_RTCP_SOURCE_RTP_VIDEO_LAYERS_ALLOCATION_EXTENSION_H_ +#define MODULES_RTP_RTCP_SOURCE_RTP_VIDEO_LAYERS_ALLOCATION_EXTENSION_H_ + +#include "api/video/video_layers_allocation.h" +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" + +namespace webrtc { + +// TODO(bugs.webrtc.org/12000): Note that this extensions is being developed and +// the wire format will likely change. +class RtpVideoLayersAllocationExtension { + public: + using value_type = VideoLayersAllocation; + static constexpr RTPExtensionType kId = kRtpExtensionVideoLayersAllocation; + static constexpr const char kUri[] = + "http://www.webrtc.org/experiments/rtp-hdrext/video-layers-allocation00"; + static bool Parse(rtc::ArrayView data, + VideoLayersAllocation* allocation); + static size_t ValueSize(const VideoLayersAllocation& allocation); + static bool Write(rtc::ArrayView data, + const VideoLayersAllocation& allocation); +}; + +} // namespace webrtc +#endif // MODULES_RTP_RTCP_SOURCE_RTP_VIDEO_LAYERS_ALLOCATION_EXTENSION_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_capture/device_info_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/video_capture/device_info_impl.cc index 91a72326c..846977e68 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_capture/device_info_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_capture/device_info_impl.cc @@ -25,34 +25,25 @@ namespace webrtc { namespace videocapturemodule { DeviceInfoImpl::DeviceInfoImpl() - : _apiLock(*RWLockWrapper::CreateRWLock()), - _lastUsedDeviceName(NULL), - _lastUsedDeviceNameLength(0) {} + : _lastUsedDeviceName(NULL), _lastUsedDeviceNameLength(0) {} DeviceInfoImpl::~DeviceInfoImpl(void) { - _apiLock.AcquireLockExclusive(); + MutexLock lock(&_apiLock); free(_lastUsedDeviceName); - _apiLock.ReleaseLockExclusive(); - - delete &_apiLock; } int32_t DeviceInfoImpl::NumberOfCapabilities(const char* deviceUniqueIdUTF8) { if (!deviceUniqueIdUTF8) return -1; - _apiLock.AcquireLockShared(); + MutexLock lock(&_apiLock); // Is it the same device that is asked for again. if (absl::EqualsIgnoreCase( deviceUniqueIdUTF8, absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) { - _apiLock.ReleaseLockShared(); return static_cast(_captureCapabilities.size()); } - // Need to get exclusive rights to create the new capability map. - _apiLock.ReleaseLockShared(); - WriteLockScoped cs2(_apiLock); int32_t ret = CreateCapabilityMap(deviceUniqueIdUTF8); return ret; @@ -63,20 +54,14 @@ int32_t DeviceInfoImpl::GetCapability(const char* deviceUniqueIdUTF8, VideoCaptureCapability& capability) { assert(deviceUniqueIdUTF8 != NULL); - ReadLockScoped cs(_apiLock); + MutexLock lock(&_apiLock); if (!absl::EqualsIgnoreCase( deviceUniqueIdUTF8, absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) { - _apiLock.ReleaseLockShared(); - _apiLock.AcquireLockExclusive(); if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8)) { - _apiLock.ReleaseLockExclusive(); - _apiLock.AcquireLockShared(); return -1; } - _apiLock.ReleaseLockExclusive(); - _apiLock.AcquireLockShared(); } // Make sure the number is valid @@ -98,17 +83,13 @@ int32_t DeviceInfoImpl::GetBestMatchedCapability( if (!deviceUniqueIdUTF8) return -1; - ReadLockScoped cs(_apiLock); + MutexLock lock(&_apiLock); if (!absl::EqualsIgnoreCase( deviceUniqueIdUTF8, absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) { - _apiLock.ReleaseLockShared(); - _apiLock.AcquireLockExclusive(); if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8)) { return -1; } - _apiLock.ReleaseLockExclusive(); - _apiLock.AcquireLockShared(); } int32_t bestformatIndex = -1; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_capture/device_info_impl.h b/TMessagesProj/jni/voip/webrtc/modules/video_capture/device_info_impl.h index 37a457ce8..4b4738960 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_capture/device_info_impl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_capture/device_info_impl.h @@ -18,7 +18,8 @@ #include "api/video/video_rotation.h" #include "modules/video_capture/video_capture.h" #include "modules/video_capture/video_capture_defines.h" -#include "rtc_base/synchronization/rw_lock_wrapper.h" +#include "rtc_base/synchronization/mutex.h" +#include "rtc_base/thread_annotations.h" namespace webrtc { namespace videocapturemodule { @@ -45,15 +46,16 @@ class DeviceInfoImpl : public VideoCaptureModule::DeviceInfo { * Fills the member variable _captureCapabilities with capabilities for the * given device name. */ - virtual int32_t CreateCapabilityMap(const char* deviceUniqueIdUTF8) = 0; + virtual int32_t CreateCapabilityMap(const char* deviceUniqueIdUTF8) + RTC_EXCLUSIVE_LOCKS_REQUIRED(_apiLock) = 0; protected: // Data members typedef std::vector VideoCaptureCapabilities; - VideoCaptureCapabilities _captureCapabilities; - RWLockWrapper& _apiLock; - char* _lastUsedDeviceName; - uint32_t _lastUsedDeviceNameLength; + VideoCaptureCapabilities _captureCapabilities RTC_GUARDED_BY(_apiLock); + Mutex _apiLock; + char* _lastUsedDeviceName RTC_GUARDED_BY(_apiLock); + uint32_t _lastUsedDeviceNameLength RTC_GUARDED_BY(_apiLock); }; } // namespace videocapturemodule } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_capture/linux/device_info_linux.h b/TMessagesProj/jni/voip/webrtc/modules/video_capture/linux/device_info_linux.h index a320c36fd..304ae7123 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_capture/linux/device_info_linux.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_capture/linux/device_info_linux.h @@ -33,13 +33,14 @@ class DeviceInfoLinux : public DeviceInfoImpl { * Fills the membervariable _captureCapabilities with capabilites for the * given device name. */ - int32_t CreateCapabilityMap(const char* deviceUniqueIdUTF8) override; + int32_t CreateCapabilityMap(const char* deviceUniqueIdUTF8) override + RTC_EXCLUSIVE_LOCKS_REQUIRED(_apiLock); int32_t DisplayCaptureSettingsDialogBox(const char* /*deviceUniqueIdUTF8*/, const char* /*dialogTitleUTF8*/, void* /*parentWindow*/, uint32_t /*positionX*/, uint32_t /*positionY*/) override; - int32_t FillCapabilities(int fd); + int32_t FillCapabilities(int fd) RTC_EXCLUSIVE_LOCKS_REQUIRED(_apiLock); int32_t Init() override; private: diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_decoder.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_decoder.cc index 1a8a0c477..bedb51937 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_decoder.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_decoder.cc @@ -19,7 +19,7 @@ #include "api/video/i420_buffer.h" #include "api/video_codecs/video_codec.h" #include "api/video_codecs/video_decoder.h" -#include "common_video/include/i420_buffer_pool.h" +#include "common_video/include/video_frame_buffer_pool.h" #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/logging.h" #include "third_party/libaom/source/libaom/aom/aom_decoder.h" @@ -59,7 +59,7 @@ class LibaomAv1Decoder final : public VideoDecoder { aom_codec_ctx_t context_; bool inited_; // Pool of memory buffers to store decoded image data for application access. - I420BufferPool buffer_pool_; + VideoFrameBufferPool buffer_pool_; DecodedImageCallback* decode_complete_callback_; }; @@ -138,7 +138,7 @@ int32_t LibaomAv1Decoder::Decode(const EncodedImage& encoded_image, // Allocate memory for decoded frame. rtc::scoped_refptr buffer = - buffer_pool_.CreateBuffer(decoded_image->d_w, decoded_image->d_h); + buffer_pool_.CreateI420Buffer(decoded_image->d_w, decoded_image->d_h); if (!buffer.get()) { // Pool has too many pending frames. RTC_LOG(LS_WARNING) << "LibaomAv1Decoder::Decode returned due to lack of" diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index cd9b37442..c1accad55 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -25,10 +25,11 @@ #include "api/video/video_frame.h" #include "api/video_codecs/video_codec.h" #include "api/video_codecs/video_encoder.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller_no_layering.h" #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_error_codes.h" +#include "modules/video_coding/svc/create_scalability_structure.h" +#include "modules/video_coding/svc/scalable_video_controller.h" +#include "modules/video_coding/svc/scalable_video_controller_no_layering.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "third_party/libaom/source/libaom/aom/aom_codec.h" @@ -93,7 +94,7 @@ class LibaomAv1Encoder final : public VideoEncoder { void SetSvcRefFrameConfig( const ScalableVideoController::LayerFrameConfig& layer_frame); - const std::unique_ptr svc_controller_; + std::unique_ptr svc_controller_; bool inited_; absl::optional svc_params_; VideoCodec encoder_settings_; @@ -164,6 +165,21 @@ int LibaomAv1Encoder::InitEncode(const VideoCodec* codec_settings, "LibaomAv1Encoder."; return result; } + if (encoder_settings_.numberOfSimulcastStreams > 1) { + RTC_LOG(LS_WARNING) << "Simulcast is not implemented by LibaomAv1Encoder."; + return result; + } + absl::string_view scalability_mode = encoder_settings_.ScalabilityMode(); + // When scalability_mode is not set, keep using svc_controller_ created + // at construction of the encoder. + if (!scalability_mode.empty()) { + svc_controller_ = CreateScalabilityStructure(scalability_mode); + } + if (svc_controller_ == nullptr) { + RTC_LOG(LS_WARNING) << "Failed to set scalability mode " + << scalability_mode; + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; + } if (!SetSvcParams(svc_controller_->StreamConfig())) { return WEBRTC_VIDEO_CODEC_ERROR; @@ -223,6 +239,12 @@ int LibaomAv1Encoder::InitEncode(const VideoCodec* codec_settings, << " on control AV1E_SET_CPUUSED."; return WEBRTC_VIDEO_CODEC_ERROR; } + ret = aom_codec_control(&ctx_, AV1E_SET_ENABLE_CDEF, 1); + if (ret != AOM_CODEC_OK) { + RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::EncodeInit returned " << ret + << " on control AV1E_SET_ENABLE_CDEF."; + return WEBRTC_VIDEO_CODEC_ERROR; + } ret = aom_codec_control(&ctx_, AV1E_SET_ENABLE_TPL_MODEL, 0); if (ret != AOM_CODEC_OK) { RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::EncodeInit returned " << ret @@ -440,7 +462,10 @@ int32_t LibaomAv1Encoder::Encode( const uint32_t duration = kRtpTicksPerSecond / static_cast(encoder_settings_.maxFramerate); - for (ScalableVideoController::LayerFrameConfig& layer_frame : layer_frames) { + for (size_t i = 0; i < layer_frames.size(); ++i) { + ScalableVideoController::LayerFrameConfig& layer_frame = layer_frames[i]; + const bool end_of_picture = i == layer_frames.size() - 1; + aom_enc_frame_flags_t flags = layer_frame.IsKeyframe() ? AOM_EFLAG_FORCE_KF : 0; @@ -460,7 +485,6 @@ int32_t LibaomAv1Encoder::Encode( // Get encoded image data. EncodedImage encoded_image; - encoded_image._completeFrame = true; aom_codec_iter_t iter = nullptr; int data_pkt_count = 0; while (const aom_codec_cx_pkt_t* pkt = @@ -507,6 +531,7 @@ int32_t LibaomAv1Encoder::Encode( if (encoded_image.size() > 0) { CodecSpecificInfo codec_specific_info; codec_specific_info.codecType = kVideoCodecAV1; + codec_specific_info.end_of_picture = end_of_picture; bool is_keyframe = layer_frame.IsKeyframe(); codec_specific_info.generic_frame_info = svc_controller_->OnEncodeDone(std::move(layer_frame)); @@ -527,7 +552,7 @@ int32_t LibaomAv1Encoder::Encode( } } encoded_image_callback_->OnEncodedImage(encoded_image, - &codec_specific_info, nullptr); + &codec_specific_info); } } @@ -597,6 +622,7 @@ VideoEncoder::EncoderInfo LibaomAv1Encoder::GetEncoderInfo() const { info.has_trusted_rate_controller = true; info.is_hardware_accelerated = false; info.scaling_settings = VideoEncoder::ScalingSettings(kMinQindex, kMaxQindex); + info.preferred_pixel_formats = {VideoFrameBuffer::Type::kI420}; return info; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.h index c2f04e669..04a2b65f5 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.h @@ -14,7 +14,7 @@ #include "absl/base/attributes.h" #include "api/video_codecs/video_encoder.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" +#include "modules/video_coding/svc/scalable_video_controller.h" namespace webrtc { diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t2.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t2.cc deleted file mode 100644 index ae4c87922..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t2.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l1t2.h" - -#include -#include - -#include "absl/base/macros.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; - -constexpr DecodeTargetIndication kDtis[3][2] = { - {kSwitch, kSwitch}, // KeyFrame - {kNotPresent, kDiscardable}, // DeltaFrame T1 - {kSwitch, kSwitch}, // DeltaFrame T0 -}; - -} // namespace - -ScalabilityStructureL1T2::~ScalabilityStructureL1T2() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL1T2::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 1; - result.num_temporal_layers = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureL1T2::DependencyStructure() const { - FrameDependencyStructure structure; - structure.num_decode_targets = 2; - structure.num_chains = 1; - structure.decode_target_protected_by_chain = {0, 0}; - structure.templates.resize(3); - structure.templates[0].T(0).Dtis("SS").ChainDiffs({0}); - structure.templates[1].T(0).Dtis("SS").ChainDiffs({2}).FrameDiffs({2}); - structure.templates[2].T(1).Dtis("-D").ChainDiffs({1}).FrameDiffs({1}); - return structure; -} - -std::vector -ScalabilityStructureL1T2::NextFrameConfig(bool restart) { - if (!active_decode_targets_[0]) { - RTC_LOG(LS_WARNING) << "No bitrate allocated for temporal layer 0, yet " - "frame is requested. No frame will be encoded."; - return {}; - } - if (restart) { - next_pattern_ = kKeyFrame; - } else if (!active_decode_targets_[1]) { - next_pattern_ = kDeltaFrameT0; - } - std::vector result(1); - - switch (next_pattern_) { - case kKeyFrame: - result[0].Id(0).T(0).Keyframe().Update(0); - next_pattern_ = kDeltaFrameT1; - break; - case kDeltaFrameT1: - result[0].Id(1).T(1).Reference(0); - next_pattern_ = kDeltaFrameT0; - break; - case kDeltaFrameT0: - result[0].Id(2).T(0).ReferenceAndUpdate(0); - next_pattern_ = kDeltaFrameT1; - break; - } - return result; -} - -absl::optional ScalabilityStructureL1T2::OnEncodeDone( - LayerFrameConfig config) { - // Encoder may have generated a keyframe even when not asked for it. Treat - // such frame same as requested keyframe, in particular restart the sequence. - if (config.IsKeyframe()) { - config = NextFrameConfig(/*restart=*/true).front(); - } - - absl::optional frame_info; - if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); - return frame_info; - } - frame_info.emplace(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = config.Buffers(); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), - std::end(kDtis[config.Id()])); - frame_info->part_of_chain = {config.TemporalId() == 0}; - frame_info->active_decode_targets = active_decode_targets_; - return frame_info; -} - -void ScalabilityStructureL1T2::OnRatesUpdated( - const VideoBitrateAllocation& bitrates) { - if (bitrates.GetBitrate(0, 0) == 0) { - // It is unclear what frame can be produced when base layer is disabled, - // so mark all decode targets as inactive to produce no frames. - active_decode_targets_.reset(); - return; - } - active_decode_targets_.set(0, true); - active_decode_targets_.set(1, bitrates.GetBitrate(0, 1) > 0); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t2.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t2.h deleted file mode 100644 index 55a9e8bbb..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t2.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L1T2_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L1T2_H_ - -#include -#include - -#include "api/transport/rtp/dependency_descriptor.h" -#include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" - -namespace webrtc { - -class ScalabilityStructureL1T2 : public ScalableVideoController { - public: - ~ScalabilityStructureL1T2() override; - - StreamLayersConfig StreamConfig() const override; - FrameDependencyStructure DependencyStructure() const override; - - std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; - - void OnRatesUpdated(const VideoBitrateAllocation& bitrates) override; - - private: - enum FramePattern { - kKeyFrame, - kDeltaFrameT1, - kDeltaFrameT0, - }; - - FramePattern next_pattern_ = kKeyFrame; - std::bitset<32> active_decode_targets_ = 0b11; -}; - -} // namespace webrtc - -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L1T2_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t3.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t3.cc deleted file mode 100644 index a04a4262e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t3.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l1t3.h" - -#include -#include - -#include "absl/base/macros.h" -#include "absl/types/optional.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; - -constexpr DecodeTargetIndication kDtis[3][3] = { - {kSwitch, kSwitch, kSwitch}, // T0 - {kNotPresent, kDiscardable, kSwitch}, // T1 - {kNotPresent, kNotPresent, kDiscardable}, // T2 -}; - -} // namespace - -ScalabilityStructureL1T3::~ScalabilityStructureL1T3() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL1T3::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 1; - result.num_temporal_layers = 3; - return result; -} - -FrameDependencyStructure ScalabilityStructureL1T3::DependencyStructure() const { - FrameDependencyStructure structure; - structure.num_decode_targets = 3; - structure.num_chains = 1; - structure.decode_target_protected_by_chain = {0, 0, 0}; - structure.templates.resize(5); - structure.templates[0].T(0).Dtis("SSS").ChainDiffs({0}); - structure.templates[1].T(0).Dtis("SSS").ChainDiffs({4}).FrameDiffs({4}); - structure.templates[2].T(1).Dtis("-DS").ChainDiffs({2}).FrameDiffs({2}); - structure.templates[3].T(2).Dtis("--D").ChainDiffs({1}).FrameDiffs({1}); - structure.templates[4].T(2).Dtis("--D").ChainDiffs({3}).FrameDiffs({1}); - return structure; -} - -std::vector -ScalabilityStructureL1T3::NextFrameConfig(bool restart) { - if (restart) { - next_pattern_ = kKeyFrame; - } - std::vector config(1); - - switch (next_pattern_) { - case kKeyFrame: - config[0].T(0).Keyframe().Update(0); - next_pattern_ = kDeltaFrameT2A; - break; - case kDeltaFrameT2A: - config[0].T(2).Reference(0); - next_pattern_ = kDeltaFrameT1; - break; - case kDeltaFrameT1: - config[0].T(1).Reference(0).Update(1); - next_pattern_ = kDeltaFrameT2B; - break; - case kDeltaFrameT2B: - config[0].T(2).Reference(1); - next_pattern_ = kDeltaFrameT0; - break; - case kDeltaFrameT0: - config[0].T(0).ReferenceAndUpdate(0); - next_pattern_ = kDeltaFrameT2A; - break; - } - return config; -} - -absl::optional ScalabilityStructureL1T3::OnEncodeDone( - LayerFrameConfig config) { - absl::optional frame_info; - if (config.TemporalId() < 0 || - config.TemporalId() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected temporal id " << config.TemporalId(); - return frame_info; - } - frame_info.emplace(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = config.Buffers(); - frame_info->decode_target_indications.assign( - std::begin(kDtis[config.TemporalId()]), - std::end(kDtis[config.TemporalId()])); - frame_info->part_of_chain = {config.TemporalId() == 0}; - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t3.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t3.h deleted file mode 100644 index 562d0f2a5..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l1t3.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L1T3_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L1T3_H_ - -#include - -#include "absl/types/optional.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" - -namespace webrtc { - -// T2 0 0 0 0 -// | / | / -// T1 / 0 / 0 ... -// |_/ |_/ -// T0 0-------0------ -// Time-> 0 1 2 3 4 5 6 7 -class ScalabilityStructureL1T3 : public ScalableVideoController { - public: - ~ScalabilityStructureL1T3() override; - - StreamLayersConfig StreamConfig() const override; - FrameDependencyStructure DependencyStructure() const override; - - std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; - - private: - enum FramePattern { - kKeyFrame, - kDeltaFrameT2A, - kDeltaFrameT1, - kDeltaFrameT2B, - kDeltaFrameT0, - }; - - FramePattern next_pattern_ = kKeyFrame; -}; - -} // namespace webrtc - -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L1T3_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1.cc deleted file mode 100644 index 2070a4c9b..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l2t1.h" - -#include -#include - -#include "absl/base/macros.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; -constexpr auto kRequired = DecodeTargetIndication::kRequired; - -constexpr DecodeTargetIndication kDtis[4][2] = { - {kSwitch, kSwitch}, // Key, S0 - {kNotPresent, kSwitch}, // Key, S1 - {kSwitch, kRequired}, // Delta, S0 - {kNotPresent, kRequired}, // Delta, S1 -}; - -} // namespace - -ScalabilityStructureL2T1::~ScalabilityStructureL2T1() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL2T1::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 2; - result.num_temporal_layers = 1; - result.scaling_factor_num[0] = 1; - result.scaling_factor_den[0] = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureL2T1::DependencyStructure() const { - FrameDependencyStructure structure; - structure.num_decode_targets = 2; - structure.num_chains = 2; - structure.decode_target_protected_by_chain = {0, 1}; - structure.templates.resize(4); - structure.templates[0].S(0).Dtis("SR").ChainDiffs({2, 1}).FrameDiffs({2}); - structure.templates[1].S(0).Dtis("SS").ChainDiffs({0, 0}); - structure.templates[2].S(1).Dtis("-R").ChainDiffs({1, 1}).FrameDiffs({2, 1}); - structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 1}).FrameDiffs({1}); - return structure; -} - -ScalableVideoController::LayerFrameConfig -ScalabilityStructureL2T1::KeyFrameConfig() const { - return LayerFrameConfig().Id(0).S(0).Keyframe().Update(0); -} - -std::vector -ScalabilityStructureL2T1::NextFrameConfig(bool restart) { - std::vector result(2); - // Buffer0 keeps latest S0 frame, Buffer1 keeps latest S1 frame. - if (restart || keyframe_) { - result[0] = KeyFrameConfig(); - result[1].Id(1).S(1).Reference(0).Update(1); - keyframe_ = false; - } else { - result[0].Id(2).S(0).ReferenceAndUpdate(0); - result[1].Id(3).S(1).Reference(0).ReferenceAndUpdate(1); - } - return result; -} - -absl::optional ScalabilityStructureL2T1::OnEncodeDone( - LayerFrameConfig config) { - absl::optional frame_info; - if (config.IsKeyframe()) { - config = KeyFrameConfig(); - } - - if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); - return frame_info; - } - frame_info.emplace(); - frame_info->spatial_id = config.SpatialId(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = std::move(config.Buffers()); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), - std::end(kDtis[config.Id()])); - frame_info->part_of_chain = {config.SpatialId() == 0, true}; - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1.h deleted file mode 100644 index 0f5360260..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1_H_ - -#include - -#include "api/transport/rtp/dependency_descriptor.h" -#include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" - -namespace webrtc { - -// S1 0--0--0- -// | | | ... -// S0 0--0--0- -class ScalabilityStructureL2T1 : public ScalableVideoController { - public: - ~ScalabilityStructureL2T1() override; - - StreamLayersConfig StreamConfig() const override; - FrameDependencyStructure DependencyStructure() const override; - - std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; - - private: - LayerFrameConfig KeyFrameConfig() const; - - bool keyframe_ = true; -}; - -} // namespace webrtc - -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.cc deleted file mode 100644 index ab76f1f7e..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.cc +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l2t1_key.h" - -#include -#include - -#include "absl/base/macros.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; - -constexpr DecodeTargetIndication kDtis[3][2] = { - {kSwitch, kSwitch}, // Key, S0 - {kSwitch, kNotPresent}, // Delta, S0 - {kNotPresent, kSwitch}, // Key and Delta, S1 -}; - -} // namespace - -ScalabilityStructureL2T1Key::~ScalabilityStructureL2T1Key() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL2T1Key::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 2; - result.num_temporal_layers = 1; - result.scaling_factor_num[0] = 1; - result.scaling_factor_den[0] = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureL2T1Key::DependencyStructure() - const { - FrameDependencyStructure structure; - structure.num_decode_targets = 2; - structure.num_chains = 2; - structure.decode_target_protected_by_chain = {0, 1}; - structure.templates.resize(4); - structure.templates[0].S(0).Dtis("S-").ChainDiffs({2, 1}).FrameDiffs({2}); - structure.templates[1].S(0).Dtis("SS").ChainDiffs({0, 0}); - structure.templates[2].S(1).Dtis("-S").ChainDiffs({1, 2}).FrameDiffs({2}); - structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 1}).FrameDiffs({1}); - return structure; -} - -ScalableVideoController::LayerFrameConfig -ScalabilityStructureL2T1Key::KeyFrameConfig() const { - return LayerFrameConfig().Id(0).S(0).Keyframe().Update(0); -} - -std::vector -ScalabilityStructureL2T1Key::NextFrameConfig(bool restart) { - std::vector result(2); - - // Buffer0 keeps latest S0T0 frame, Buffer1 keeps latest S1T0 frame. - if (restart || keyframe_) { - result[0] = KeyFrameConfig(); - result[1].Id(2).S(1).Reference(0).Update(1); - keyframe_ = false; - } else { - result[0].Id(1).S(0).ReferenceAndUpdate(0); - result[1].Id(2).S(1).ReferenceAndUpdate(1); - } - return result; -} - -absl::optional ScalabilityStructureL2T1Key::OnEncodeDone( - LayerFrameConfig config) { - absl::optional frame_info; - if (config.IsKeyframe()) { - config = KeyFrameConfig(); - } - - if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); - return frame_info; - } - frame_info.emplace(); - frame_info->spatial_id = config.SpatialId(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = std::move(config.Buffers()); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), - std::end(kDtis[config.Id()])); - if (config.IsKeyframe()) { - frame_info->part_of_chain = {true, true}; - } else { - frame_info->part_of_chain = {config.SpatialId() == 0, - config.SpatialId() == 1}; - } - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.h deleted file mode 100644 index c1d8c8947..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1_KEY_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1_KEY_H_ - -#include - -#include "api/transport/rtp/dependency_descriptor.h" -#include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" - -namespace webrtc { - -// S1 0--0--0- -// | ... -// S0 0--0--0- -class ScalabilityStructureL2T1Key : public ScalableVideoController { - public: - ~ScalabilityStructureL2T1Key() override; - - StreamLayersConfig StreamConfig() const override; - FrameDependencyStructure DependencyStructure() const override; - - std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; - - private: - LayerFrameConfig KeyFrameConfig() const; - - bool keyframe_ = true; -}; - -} // namespace webrtc - -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1_KEY_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2.cc deleted file mode 100644 index 3da41832a..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l2t2.h" - -#include -#include - -#include "absl/base/macros.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; -constexpr auto kRequired = DecodeTargetIndication::kRequired; - -// decode targets: S0T0, S0T1, S1T0, S1T1 -constexpr DecodeTargetIndication kDtis[6][4] = { - {kSwitch, kSwitch, kSwitch, kSwitch}, // kKey, S0 - {kNotPresent, kNotPresent, kSwitch, kSwitch}, // kKey, S1 - {kNotPresent, kDiscardable, kNotPresent, kRequired}, // kDeltaT1, S0 - {kNotPresent, kNotPresent, kNotPresent, kDiscardable}, // kDeltaT1, S1 - {kSwitch, kSwitch, kRequired, kRequired}, // kDeltaT0, S0 - {kNotPresent, kNotPresent, kSwitch, kSwitch}, // kDeltaT0, S1 -}; - -} // namespace - -ScalabilityStructureL2T2::~ScalabilityStructureL2T2() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL2T2::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 2; - result.num_temporal_layers = 2; - result.scaling_factor_num[0] = 1; - result.scaling_factor_den[0] = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureL2T2::DependencyStructure() const { - FrameDependencyStructure structure; - structure.num_decode_targets = 4; - structure.num_chains = 2; - structure.decode_target_protected_by_chain = {0, 0, 1, 1}; - structure.templates.resize(6); - auto& templates = structure.templates; - templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}); - templates[1].S(0).T(0).Dtis("SSRR").ChainDiffs({4, 3}).FrameDiffs({4}); - templates[2].S(0).T(1).Dtis("-D-R").ChainDiffs({2, 1}).FrameDiffs({2}); - templates[3].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1}); - templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({4, 1}); - templates[5].S(1).T(1).Dtis("---D").ChainDiffs({3, 2}).FrameDiffs({2, 1}); - return structure; -} - -ScalableVideoController::LayerFrameConfig -ScalabilityStructureL2T2::KeyFrameConfig() const { - return LayerFrameConfig().Id(0).Keyframe().S(0).T(0).Update(0); -} - -std::vector -ScalabilityStructureL2T2::NextFrameConfig(bool restart) { - if (restart) { - next_pattern_ = kKey; - } - std::vector result(2); - - // Buffer0 keeps latest S0T0 frame, - // Buffer1 keeps latest S1T0 frame. - // Buffer2 keeps latest S0T1 frame. - switch (next_pattern_) { - case kKey: - result[0] = KeyFrameConfig(); - result[1].Id(1).S(1).T(0).Reference(0).Update(1); - next_pattern_ = kDeltaT1; - break; - case kDeltaT1: - result[0].Id(2).S(0).T(1).Reference(0).Update(2); - result[1].Id(3).S(1).T(1).Reference(2).Reference(1); - next_pattern_ = kDeltaT0; - break; - case kDeltaT0: - result[0].Id(4).S(0).T(0).ReferenceAndUpdate(0); - result[1].Id(5).S(1).T(0).Reference(0).ReferenceAndUpdate(1); - next_pattern_ = kDeltaT1; - break; - } - return result; -} - -absl::optional ScalabilityStructureL2T2::OnEncodeDone( - LayerFrameConfig config) { - if (config.IsKeyframe()) { - config = KeyFrameConfig(); - } - - absl::optional frame_info; - if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); - return frame_info; - } - frame_info.emplace(); - frame_info->spatial_id = config.SpatialId(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = config.Buffers(); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), - std::end(kDtis[config.Id()])); - if (config.TemporalId() == 0) { - frame_info->part_of_chain = {config.SpatialId() == 0, true}; - } else { - frame_info->part_of_chain = {false, false}; - } - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2.h deleted file mode 100644 index dbf5036c1..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_H_ - -#include - -#include "api/transport/rtp/dependency_descriptor.h" -#include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" - -namespace webrtc { - -// S1T1 0 0 -// /| /| / -// S1T0 0-+-0-+-0 -// | | | | | ... -// S0T1 | 0 | 0 | -// |/ |/ |/ -// S0T0 0---0---0-- -// Time-> 0 1 2 3 4 -class ScalabilityStructureL2T2 : public ScalableVideoController { - public: - ~ScalabilityStructureL2T2() override; - - StreamLayersConfig StreamConfig() const override; - FrameDependencyStructure DependencyStructure() const override; - - std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; - - private: - enum FramePattern { - kKey, - kDeltaT1, - kDeltaT0, - }; - LayerFrameConfig KeyFrameConfig() const; - - FramePattern next_pattern_ = kKey; -}; - -} // namespace webrtc - -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.cc deleted file mode 100644 index a59ef1a97..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l2t2_key.h" - -#include -#include - -#include "absl/base/macros.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; - -// decode targets: S0T0, S0T1, S1T0, S1T1 -constexpr DecodeTargetIndication kDtis[6][4] = { - {kSwitch, kSwitch, kSwitch, kSwitch}, // kKey, S0 - {kNotPresent, kNotPresent, kSwitch, kSwitch}, // kKey, S1 - {kNotPresent, kDiscardable, kNotPresent, kNotPresent}, // kDeltaT1, S0 - {kNotPresent, kNotPresent, kNotPresent, kDiscardable}, // kDeltaT1, S1 - {kSwitch, kSwitch, kNotPresent, kNotPresent}, // kDeltaT0, S0 - {kNotPresent, kNotPresent, kSwitch, kSwitch}, // kDeltaT0, S1 -}; - -} // namespace - -ScalabilityStructureL2T2Key::~ScalabilityStructureL2T2Key() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL2T2Key::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 2; - result.num_temporal_layers = 2; - result.scaling_factor_num[0] = 1; - result.scaling_factor_den[0] = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureL2T2Key::DependencyStructure() - const { - FrameDependencyStructure structure; - structure.num_decode_targets = 4; - structure.num_chains = 2; - structure.decode_target_protected_by_chain = {0, 0, 1, 1}; - structure.templates.resize(6); - auto& templates = structure.templates; - templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}); - templates[1].S(0).T(0).Dtis("SS--").ChainDiffs({4, 3}).FrameDiffs({4}); - templates[2].S(0).T(1).Dtis("-D--").ChainDiffs({2, 1}).FrameDiffs({2}); - templates[3].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1}); - templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 4}).FrameDiffs({4}); - templates[5].S(1).T(1).Dtis("---D").ChainDiffs({3, 2}).FrameDiffs({2}); - return structure; -} - -ScalableVideoController::LayerFrameConfig -ScalabilityStructureL2T2Key::KeyFrameConfig() const { - return LayerFrameConfig().Id(0).Keyframe().S(0).T(0).Update(0); -} - -std::vector -ScalabilityStructureL2T2Key::NextFrameConfig(bool restart) { - if (restart) { - next_pattern_ = kKey; - } - std::vector result(2); - - // Buffer0 keeps latest S0T0 frame, - // Buffer1 keeps latest S1T0 frame. - switch (next_pattern_) { - case kKey: - result[0] = KeyFrameConfig(); - result[1].Id(1).S(1).T(0).Reference(0).Update(1); - next_pattern_ = kDeltaT1; - break; - case kDeltaT1: - result[0].Id(2).S(0).T(1).Reference(0); - result[1].Id(3).S(1).T(1).Reference(1); - next_pattern_ = kDeltaT0; - break; - case kDeltaT0: - result[0].Id(4).S(0).T(0).ReferenceAndUpdate(0); - result[1].Id(5).S(1).T(0).ReferenceAndUpdate(1); - next_pattern_ = kDeltaT1; - break; - } - return result; -} - -absl::optional ScalabilityStructureL2T2Key::OnEncodeDone( - LayerFrameConfig config) { - if (config.IsKeyframe()) { - config = KeyFrameConfig(); - } - - absl::optional frame_info; - if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); - return frame_info; - } - frame_info.emplace(); - frame_info->spatial_id = config.SpatialId(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = config.Buffers(); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), - std::end(kDtis[config.Id()])); - if (config.IsKeyframe()) { - frame_info->part_of_chain = {true, true}; - } else if (config.TemporalId() == 0) { - frame_info->part_of_chain = {config.SpatialId() == 0, - config.SpatialId() == 1}; - } else { - frame_info->part_of_chain = {false, false}; - } - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.h deleted file mode 100644 index 9adfcbcd5..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_KEY_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_KEY_H_ - -#include - -#include "api/transport/rtp/dependency_descriptor.h" -#include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" - -namespace webrtc { - -// S1T1 0 0 -// / / / -// S1T0 0---0---0 -// | ... -// S0T1 | 0 0 -// |/ / / -// S0T0 0---0---0 -// Time-> 0 1 2 3 4 -class ScalabilityStructureL2T2Key : public ScalableVideoController { - public: - ~ScalabilityStructureL2T2Key() override; - - StreamLayersConfig StreamConfig() const override; - FrameDependencyStructure DependencyStructure() const override; - - std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; - - private: - enum FramePattern { - kKey, - kDeltaT1, - kDeltaT0, - }; - LayerFrameConfig KeyFrameConfig() const; - - FramePattern next_pattern_ = kKey; -}; - -} // namespace webrtc - -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_KEY_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.cc deleted file mode 100644 index d205b4a1c..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l2t2_key_shift.h" - -#include -#include - -#include "absl/base/macros.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; - -constexpr DecodeTargetIndication kDtis[6][4] = { - {kSwitch, kSwitch, kSwitch, kSwitch}, // kKey, S0T0 - {kNotPresent, kNotPresent, kSwitch, kSwitch}, // kKey, S1T0 - {kSwitch, kSwitch, kNotPresent, kNotPresent}, // kDelta0, S0T0 - {kNotPresent, kNotPresent, kNotPresent, kDiscardable}, // kDelta0, S1T1 - {kNotPresent, kDiscardable, kNotPresent, kNotPresent}, // kDelta1, S0T1 - {kNotPresent, kNotPresent, kSwitch, kSwitch}, // kDelta1, S1T0 -}; - -} // namespace - -ScalabilityStructureL2T2KeyShift::~ScalabilityStructureL2T2KeyShift() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL2T2KeyShift::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 2; - result.num_temporal_layers = 2; - result.scaling_factor_num[0] = 1; - result.scaling_factor_den[0] = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureL2T2KeyShift::DependencyStructure() - const { - FrameDependencyStructure structure; - structure.num_decode_targets = 4; - structure.num_chains = 2; - structure.decode_target_protected_by_chain = {0, 0, 1, 1}; - structure.templates.resize(7); - auto& templates = structure.templates; - templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}); - templates[1].S(0).T(0).Dtis("SS--").ChainDiffs({2, 1}).FrameDiffs({2}); - templates[2].S(0).T(0).Dtis("SS--").ChainDiffs({4, 1}).FrameDiffs({4}); - templates[3].S(0).T(1).Dtis("-D--").ChainDiffs({2, 3}).FrameDiffs({2}); - templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1}); - templates[5].S(1).T(0).Dtis("--SS").ChainDiffs({3, 4}).FrameDiffs({4}); - templates[6].S(1).T(1).Dtis("---D").ChainDiffs({1, 2}).FrameDiffs({2}); - return structure; -} - -ScalableVideoController::LayerFrameConfig -ScalabilityStructureL2T2KeyShift::KeyFrameConfig() const { - return LayerFrameConfig().Id(0).Keyframe().S(0).T(0).Update(0); -} - -std::vector -ScalabilityStructureL2T2KeyShift::NextFrameConfig(bool restart) { - if (restart) { - next_pattern_ = kKey; - } - std::vector result(2); - - // Buffer0 keeps latest S0T0 frame, - // Buffer1 keeps latest S1T0 frame. - switch (next_pattern_) { - case kKey: - result[0] = KeyFrameConfig(); - result[1].Id(1).S(1).T(0).Reference(0).Update(1); - next_pattern_ = kDelta0; - break; - case kDelta0: - result[0].Id(2).S(0).T(0).ReferenceAndUpdate(0); - result[1].Id(3).S(1).T(1).Reference(1); - next_pattern_ = kDelta1; - break; - case kDelta1: - result[0].Id(4).S(0).T(1).Reference(0); - result[1].Id(5).S(1).T(0).ReferenceAndUpdate(1); - next_pattern_ = kDelta0; - break; - } - return result; -} - -absl::optional ScalabilityStructureL2T2KeyShift::OnEncodeDone( - LayerFrameConfig config) { - if (config.IsKeyframe()) { - config = KeyFrameConfig(); - } - - absl::optional frame_info; - if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); - return frame_info; - } - frame_info.emplace(); - frame_info->spatial_id = config.SpatialId(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = config.Buffers(); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), - std::end(kDtis[config.Id()])); - if (config.IsKeyframe()) { - frame_info->part_of_chain = {true, true}; - } else if (config.TemporalId() == 0) { - frame_info->part_of_chain = {config.SpatialId() == 0, - config.SpatialId() == 1}; - } else { - frame_info->part_of_chain = {false, false}; - } - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t1.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t1.cc deleted file mode 100644 index 51eb00352..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t1.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l3t1.h" - -#include -#include - -#include "absl/base/macros.h" -#include "absl/types/optional.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; -constexpr auto kRequired = DecodeTargetIndication::kRequired; - -constexpr DecodeTargetIndication kDtis[5][3] = { - {kSwitch, kSwitch, kSwitch}, // Key, S0 - {kNotPresent, kSwitch, kSwitch}, // Key, S1 - {kNotPresent, kNotPresent, kSwitch}, // Key and Delta, S2 - {kSwitch, kRequired, kRequired}, // Delta, S0 - {kNotPresent, kSwitch, kRequired}, // Delta, S1 -}; - -} // namespace - -ScalabilityStructureL3T1::~ScalabilityStructureL3T1() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL3T1::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 3; - result.num_temporal_layers = 1; - result.scaling_factor_num[0] = 1; - result.scaling_factor_den[0] = 4; - result.scaling_factor_num[1] = 1; - result.scaling_factor_den[1] = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureL3T1::DependencyStructure() const { - FrameDependencyStructure structure; - structure.num_decode_targets = 3; - structure.num_chains = 3; - structure.decode_target_protected_by_chain = {0, 1, 2}; - auto& templates = structure.templates; - templates.resize(6); - templates[0].S(0).Dtis("SRR").ChainDiffs({3, 2, 1}).FrameDiffs({3}); - templates[1].S(0).Dtis("SSS").ChainDiffs({0, 0, 0}); - templates[2].S(1).Dtis("-SR").ChainDiffs({1, 1, 1}).FrameDiffs({3, 1}); - templates[3].S(1).Dtis("-SS").ChainDiffs({1, 1, 1}).FrameDiffs({1}); - templates[4].S(2).Dtis("--S").ChainDiffs({2, 1, 1}).FrameDiffs({3, 1}); - templates[5].S(2).Dtis("--S").ChainDiffs({2, 1, 1}).FrameDiffs({1}); - return structure; -} - -std::vector -ScalabilityStructureL3T1::NextFrameConfig(bool restart) { - std::vector config(3); - - // Buffer i keeps latest frame for spatial layer i - if (restart || keyframe_) { - config[0].Id(0).S(0).Keyframe().Update(0); - config[1].Id(1).S(1).Update(1).Reference(0); - config[2].Id(2).S(2).Update(2).Reference(1); - keyframe_ = false; - } else { - config[0].Id(3).S(0).ReferenceAndUpdate(0); - config[1].Id(4).S(1).ReferenceAndUpdate(1).Reference(0); - config[2].Id(2).S(2).ReferenceAndUpdate(2).Reference(1); - } - return config; -} - -absl::optional ScalabilityStructureL3T1::OnEncodeDone( - LayerFrameConfig config) { - absl::optional frame_info; - if (config.IsKeyframe() && config.Id() != 0) { - // Encoder generated a key frame without asking to. - if (config.SpatialId() > 0) { - RTC_LOG(LS_WARNING) << "Unexpected spatial id " << config.SpatialId() - << " for key frame."; - } - config = LayerFrameConfig().Id(0).S(0).Keyframe().Update(0); - } - - if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); - return frame_info; - } - frame_info.emplace(); - frame_info->spatial_id = config.SpatialId(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = config.Buffers(); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), - std::end(kDtis[config.Id()])); - frame_info->part_of_chain = {config.SpatialId() == 0, config.SpatialId() <= 1, - true}; - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t3.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t3.cc deleted file mode 100644 index 14e261f74..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t3.cc +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_l3t3.h" - -#include -#include - -#include "absl/base/macros.h" -#include "absl/types/optional.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; -constexpr auto kRequired = DecodeTargetIndication::kRequired; - -constexpr DecodeTargetIndication kDtis[12][9] = { - // Key, S0 - {kSwitch, kSwitch, kSwitch, // S0 - kSwitch, kSwitch, kSwitch, // S1 - kSwitch, kSwitch, kSwitch}, // S2 - // Key, S1 - {kNotPresent, kNotPresent, kNotPresent, // S0 - kSwitch, kSwitch, kSwitch, // S1 - kSwitch, kSwitch, kSwitch}, // S2 - // Key, S2 - {kNotPresent, kNotPresent, kNotPresent, // S0 - kNotPresent, kNotPresent, kNotPresent, // S1 - kSwitch, kSwitch, kSwitch}, // S2 - // Delta, S0T2 - {kNotPresent, kNotPresent, kDiscardable, // S0 - kNotPresent, kNotPresent, kRequired, // S1 - kNotPresent, kNotPresent, kRequired}, // S2 - // Delta, S1T2 - {kNotPresent, kNotPresent, kNotPresent, // S0 - kNotPresent, kNotPresent, kDiscardable, // S1 - kNotPresent, kNotPresent, kRequired}, // S2 - // Delta, S2T2 - {kNotPresent, kNotPresent, kNotPresent, // S0 - kNotPresent, kNotPresent, kNotPresent, // S1 - kNotPresent, kNotPresent, kDiscardable}, // S2 - // Delta, S0T1 - {kNotPresent, kDiscardable, kSwitch, // S0 - kNotPresent, kRequired, kRequired, // S1 - kNotPresent, kRequired, kRequired}, // S2 - // Delta, S1T1 - {kNotPresent, kNotPresent, kNotPresent, // S0 - kNotPresent, kDiscardable, kSwitch, // S1 - kNotPresent, kRequired, kRequired}, // S2 - // Delta, S2T1 - {kNotPresent, kNotPresent, kNotPresent, // S0 - kNotPresent, kNotPresent, kNotPresent, // S1 - kNotPresent, kDiscardable, kSwitch}, // S2 - // Delta, S0T0 - {kSwitch, kSwitch, kSwitch, // S0 - kRequired, kRequired, kRequired, // S1 - kRequired, kRequired, kRequired}, // S2 - // Delta, S1T0 - {kNotPresent, kNotPresent, kNotPresent, // S0 - kSwitch, kSwitch, kSwitch, // S1 - kRequired, kRequired, kRequired}, // S2 - // Delta, S2T0 - {kNotPresent, kNotPresent, kNotPresent, // S0 - kNotPresent, kNotPresent, kNotPresent, // S1 - kSwitch, kSwitch, kSwitch}, // S2 -}; - -} // namespace - -ScalabilityStructureL3T3::~ScalabilityStructureL3T3() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureL3T3::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 3; - result.num_temporal_layers = 3; - result.scaling_factor_num[0] = 1; - result.scaling_factor_den[0] = 4; - result.scaling_factor_num[1] = 1; - result.scaling_factor_den[1] = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureL3T3::DependencyStructure() const { - FrameDependencyStructure structure; - structure.num_decode_targets = 9; - structure.num_chains = 3; - structure.decode_target_protected_by_chain = {0, 0, 0, 1, 1, 1, 2, 2, 2}; - auto& t = structure.templates; - t.resize(15); - // Templates are shown in the order frames following them appear in the - // stream, but in `structure.templates` array templates are sorted by - // (`spatial_id`, `temporal_id`) since that is a dependency descriptor - // requirement. Indexes are written in hex for nicer alignment. - t[0x1].S(0).T(0).Dtis("SSSSSSSSS").ChainDiffs({0, 0, 0}); - t[0x6].S(1).T(0).Dtis("---SSSSSS").ChainDiffs({1, 1, 1}).FrameDiffs({1}); - t[0xB].S(2).T(0).Dtis("------SSS").ChainDiffs({2, 1, 1}).FrameDiffs({1}); - t[0x3].S(0).T(2).Dtis("--D--R--R").ChainDiffs({3, 2, 1}).FrameDiffs({3}); - t[0x8].S(1).T(2).Dtis("-----D--R").ChainDiffs({4, 3, 2}).FrameDiffs({3, 1}); - t[0xD].S(2).T(2).Dtis("--------D").ChainDiffs({5, 4, 3}).FrameDiffs({3, 1}); - t[0x2].S(0).T(1).Dtis("-DS-RR-RR").ChainDiffs({6, 5, 4}).FrameDiffs({6}); - t[0x7].S(1).T(1).Dtis("----DS-RR").ChainDiffs({7, 6, 5}).FrameDiffs({6, 1}); - t[0xC].S(2).T(1).Dtis("-------DS").ChainDiffs({8, 7, 6}).FrameDiffs({6, 1}); - t[0x4].S(0).T(2).Dtis("--D--R--R").ChainDiffs({9, 8, 7}).FrameDiffs({3}); - t[0x9].S(1).T(2).Dtis("-----D--R").ChainDiffs({10, 9, 8}).FrameDiffs({3, 1}); - t[0xE].S(2).T(2).Dtis("--------D").ChainDiffs({11, 10, 9}).FrameDiffs({3, 1}); - t[0x0].S(0).T(0).Dtis("SSSRRRRRR").ChainDiffs({12, 11, 10}).FrameDiffs({12}); - t[0x5].S(1).T(0).Dtis("---SSSRRR").ChainDiffs({1, 1, 1}).FrameDiffs({12, 1}); - t[0xA].S(2).T(0).Dtis("------SSS").ChainDiffs({2, 1, 1}).FrameDiffs({12, 1}); - return structure; -} - -ScalableVideoController::LayerFrameConfig -ScalabilityStructureL3T3::KeyFrameConfig() const { - return LayerFrameConfig().Id(0).S(0).T(0).Keyframe().Update(0); -} - -std::vector -ScalabilityStructureL3T3::NextFrameConfig(bool restart) { - if (restart) { - next_pattern_ = kKeyFrame; - } - std::vector config(3); - - // For this structure name each of 8 buffers after the layer of the frame that - // buffer keeps. - static constexpr int kS0T0 = 0; - static constexpr int kS1T0 = 1; - static constexpr int kS2T0 = 2; - static constexpr int kS0T1 = 3; - static constexpr int kS1T1 = 4; - static constexpr int kS2T1 = 5; - static constexpr int kS0T2 = 6; - static constexpr int kS1T2 = 7; - switch (next_pattern_) { - case kKeyFrame: - config[0].Id(0).S(0).T(0).Keyframe().Update(kS0T0); - config[1].Id(1).S(1).T(0).Update(kS1T0).Reference(kS0T0); - config[2].Id(2).S(2).T(0).Update(kS2T0).Reference(kS1T0); - next_pattern_ = kDeltaFrameT2A; - break; - case kDeltaFrameT2A: - config[0].Id(3).S(0).T(2).Reference(kS0T0).Update(kS0T2); - config[1].Id(4).S(1).T(2).Reference(kS1T0).Reference(kS0T2).Update(kS1T2); - config[2].Id(5).S(2).T(2).Reference(kS2T0).Reference(kS1T2); - next_pattern_ = kDeltaFrameT1; - break; - case kDeltaFrameT1: - config[0].Id(6).S(0).T(1).Reference(kS0T0).Update(kS0T1); - config[1].Id(7).S(1).T(1).Reference(kS1T0).Reference(kS0T1).Update(kS1T1); - config[2].Id(8).S(2).T(1).Reference(kS2T0).Reference(kS1T1).Update(kS2T1); - next_pattern_ = kDeltaFrameT2B; - break; - case kDeltaFrameT2B: - config[0].Id(3).S(0).T(2).Reference(kS0T1).Update(kS0T2); - config[1].Id(4).S(1).T(2).Reference(kS1T1).Reference(kS0T2).Update(kS1T2); - config[2].Id(5).S(2).T(2).Reference(kS2T1).Reference(kS1T2); - next_pattern_ = kDeltaFrameT0; - break; - case kDeltaFrameT0: - config[0].Id(9).S(0).T(0).ReferenceAndUpdate(kS0T0); - config[1].Id(10).S(1).T(0).ReferenceAndUpdate(kS1T0).Reference(kS0T0); - config[2].Id(11).S(2).T(0).ReferenceAndUpdate(kS2T0).Reference(kS1T0); - next_pattern_ = kDeltaFrameT2A; - break; - } - return config; -} - -absl::optional ScalabilityStructureL3T3::OnEncodeDone( - LayerFrameConfig config) { - if (config.IsKeyframe() && config.Id() != 0) { - // Encoder generated a key frame without asking to. - if (config.SpatialId() > 0) { - RTC_LOG(LS_WARNING) << "Unexpected spatial id " << config.SpatialId() - << " for key frame."; - } - config = LayerFrameConfig() - .Keyframe() - .Id(0) - .S(0) - .T(0) - .Update(0) - .Update(1) - .Update(2) - .Update(3) - .Update(4) - .Update(5) - .Update(6) - .Update(7); - } - - absl::optional frame_info; - if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); - return frame_info; - } - frame_info.emplace(); - frame_info->spatial_id = config.SpatialId(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = config.Buffers(); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), - std::end(kDtis[config.Id()])); - if (config.TemporalId() == 0) { - frame_info->part_of_chain = {config.SpatialId() == 0, - config.SpatialId() <= 1, true}; - } else { - frame_info->part_of_chain = {false, false, false}; - } - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t3.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t3.h deleted file mode 100644 index 363f07e01..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t3.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L3T3_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L3T3_H_ - -#include - -#include "absl/types/optional.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" - -namespace webrtc { - -// https://aomediacodec.github.io/av1-rtp-spec/#a63-l3t3-full-svc -class ScalabilityStructureL3T3 : public ScalableVideoController { - public: - ~ScalabilityStructureL3T3() override; - - StreamLayersConfig StreamConfig() const override; - FrameDependencyStructure DependencyStructure() const override; - - std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; - - private: - enum FramePattern { - kKeyFrame, - kDeltaFrameT2A, - kDeltaFrameT1, - kDeltaFrameT2B, - kDeltaFrameT0, - }; - LayerFrameConfig KeyFrameConfig() const; - - FramePattern next_pattern_ = kKeyFrame; -}; - -} // namespace webrtc - -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L3T3_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_s2t1.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_s2t1.cc deleted file mode 100644 index 182891fa5..000000000 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_s2t1.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2020 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/codecs/av1/scalability_structure_s2t1.h" - -#include -#include - -#include "absl/base/macros.h" -#include "api/transport/rtp/dependency_descriptor.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace { - -constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; -constexpr auto kSwitch = DecodeTargetIndication::kSwitch; - -constexpr DecodeTargetIndication kDtis[2][2] = { - {kSwitch, kNotPresent}, // S0 - {kNotPresent, kSwitch}, // S1 -}; - -} // namespace - -ScalabilityStructureS2T1::~ScalabilityStructureS2T1() = default; - -ScalableVideoController::StreamLayersConfig -ScalabilityStructureS2T1::StreamConfig() const { - StreamLayersConfig result; - result.num_spatial_layers = 2; - result.num_temporal_layers = 1; - result.scaling_factor_num[0] = 1; - result.scaling_factor_den[0] = 2; - return result; -} - -FrameDependencyStructure ScalabilityStructureS2T1::DependencyStructure() const { - FrameDependencyStructure structure; - structure.num_decode_targets = 2; - structure.num_chains = 2; - structure.decode_target_protected_by_chain = {0, 1}; - structure.templates.resize(4); - structure.templates[0].S(0).Dtis("S-").ChainDiffs({2, 1}).FrameDiffs({2}); - structure.templates[1].S(0).Dtis("S-").ChainDiffs({0, 0}); - structure.templates[2].S(1).Dtis("-S").ChainDiffs({1, 2}).FrameDiffs({2}); - structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 0}); - return structure; -} - -std::vector -ScalabilityStructureS2T1::NextFrameConfig(bool restart) { - std::vector result(2); - // Buffer0 keeps latest S0T0 frame, Buffer1 keeps latest S1T0 frame. - if (restart || keyframe_) { - result[0].S(0).Keyframe().Update(0); - result[1].S(1).Keyframe().Update(1); - keyframe_ = false; - } else { - result[0].S(0).ReferenceAndUpdate(0); - result[1].S(1).ReferenceAndUpdate(1); - } - return result; -} - -absl::optional ScalabilityStructureS2T1::OnEncodeDone( - LayerFrameConfig config) { - absl::optional frame_info; - if (config.SpatialId() < 0 || - config.SpatialId() >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected spatial id " << config.SpatialId(); - return frame_info; - } - frame_info.emplace(); - frame_info->spatial_id = config.SpatialId(); - frame_info->temporal_id = config.TemporalId(); - frame_info->encoder_buffers = std::move(config.Buffers()); - frame_info->decode_target_indications.assign( - std::begin(kDtis[config.SpatialId()]), - std::end(kDtis[config.SpatialId()])); - frame_info->part_of_chain = {config.SpatialId() == 0, - config.SpatialId() == 1}; - return frame_info; -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc index 9e32c68f7..9002b8746 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc @@ -36,6 +36,7 @@ extern "C" { #include "rtc_base/logging.h" #include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/metrics.h" +#include "third_party/libyuv/include/libyuv/convert.h" namespace webrtc { @@ -103,7 +104,7 @@ int H264DecoderImpl::AVGetBuffer2(AVCodecContext* context, // TODO(nisse): Delete that feature from the video pool, instead add // an explicit call to InitializeData here. rtc::scoped_refptr frame_buffer = - decoder->pool_.CreateBuffer(width, height); + decoder->ffmpeg_buffer_pool_.CreateI420Buffer(width, height); int y_size = width * height; int uv_size = frame_buffer->ChromaWidth() * frame_buffer->ChromaHeight(); @@ -150,10 +151,13 @@ void H264DecoderImpl::AVFreeBuffer2(void* opaque, uint8_t* data) { } H264DecoderImpl::H264DecoderImpl() - : pool_(true), + : ffmpeg_buffer_pool_(true), decoded_image_callback_(nullptr), has_reported_init_(false), - has_reported_error_(false) {} + has_reported_error_(false), + preferred_output_format_(field_trial::IsEnabled("WebRTC-NV12Decode") + ? VideoFrameBuffer::Type::kNV12 + : VideoFrameBuffer::Type::kI420) {} H264DecoderImpl::~H264DecoderImpl() { Release(); @@ -219,7 +223,8 @@ int32_t H264DecoderImpl::InitDecode(const VideoCodec* codec_settings, av_frame_.reset(av_frame_alloc()); if (codec_settings && codec_settings->buffer_pool_size) { - if (!pool_.Resize(*codec_settings->buffer_pool_size)) { + if (!ffmpeg_buffer_pool_.Resize(*codec_settings->buffer_pool_size) || + !output_buffer_pool_.Resize(*codec_settings->buffer_pool_size)) { return WEBRTC_VIDEO_CODEC_UNINITIALIZED; } } @@ -325,12 +330,25 @@ int32_t H264DecoderImpl::Decode(const EncodedImage& input_image, i420_buffer->DataV() + i420_buffer->StrideV() * i420_buffer->height() / 2); - auto cropped_buffer = WrapI420Buffer( + rtc::scoped_refptr cropped_buffer = WrapI420Buffer( av_frame_->width, av_frame_->height, av_frame_->data[kYPlaneIndex], av_frame_->linesize[kYPlaneIndex], av_frame_->data[kUPlaneIndex], av_frame_->linesize[kUPlaneIndex], av_frame_->data[kVPlaneIndex], av_frame_->linesize[kVPlaneIndex], rtc::KeepRefUntilDone(i420_buffer)); + if (preferred_output_format_ == VideoFrameBuffer::Type::kNV12) { + const I420BufferInterface* cropped_i420 = cropped_buffer->GetI420(); + auto nv12_buffer = output_buffer_pool_.CreateNV12Buffer( + cropped_i420->width(), cropped_i420->height()); + libyuv::I420ToNV12(cropped_i420->DataY(), cropped_i420->StrideY(), + cropped_i420->DataU(), cropped_i420->StrideU(), + cropped_i420->DataV(), cropped_i420->StrideV(), + nv12_buffer->MutableDataY(), nv12_buffer->StrideY(), + nv12_buffer->MutableDataUV(), nv12_buffer->StrideUV(), + i420_buffer->width(), i420_buffer->height()); + cropped_buffer = nv12_buffer; + } + // Pass on color space from input frame if explicitly specified. const ColorSpace& color_space = input_image.ColorSpace() ? *input_image.ColorSpace() diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.h index 80892de63..47af12c8c 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.h @@ -40,7 +40,7 @@ extern "C" { } // extern "C" #include "common_video/h264/h264_bitstream_parser.h" -#include "common_video/include/i420_buffer_pool.h" +#include "common_video/include/video_frame_buffer_pool.h" namespace webrtc { @@ -88,7 +88,10 @@ class H264DecoderImpl : public H264Decoder { void ReportInit(); void ReportError(); - I420BufferPool pool_; + // Used by ffmpeg via |AVGetBuffer2()| to allocate I420 images. + VideoFrameBufferPool ffmpeg_buffer_pool_; + // Used to allocate NV12 images if NV12 output is preferred. + VideoFrameBufferPool output_buffer_pool_; std::unique_ptr av_context_; std::unique_ptr av_frame_; @@ -98,6 +101,9 @@ class H264DecoderImpl : public H264Decoder { bool has_reported_error_; webrtc::H264BitstreamParser h264_bitstream_parser_; + + // Decoder should produce this format if possible. + const VideoFrameBuffer::Type preferred_output_format_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc index af36dd986..ea784c19e 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc @@ -87,19 +87,15 @@ VideoFrameType ConvertToVideoFrameType(EVideoFrameType type) { } // namespace // Helper method used by H264EncoderImpl::Encode. -// Copies the encoded bytes from |info| to |encoded_image| and updates the -// fragmentation information of |frag_header|. The |encoded_image->_buffer| may -// be deleted and reallocated if a bigger buffer is required. +// Copies the encoded bytes from |info| to |encoded_image|. The +// |encoded_image->_buffer| may be deleted and reallocated if a bigger buffer is +// required. // // After OpenH264 encoding, the encoded bytes are stored in |info| spread out // over a number of layers and "NAL units". Each NAL unit is a fragment starting // with the four-byte start code {0,0,0,1}. All of this data (including the -// start codes) is copied to the |encoded_image->_buffer| and the |frag_header| -// is updated to point to each fragment, with offsets and lengths set as to -// exclude the start codes. -static void RtpFragmentize(EncodedImage* encoded_image, - SFrameBSInfo* info, - RTPFragmentationHeader* frag_header) { +// start codes) is copied to the |encoded_image->_buffer|. +static void RtpFragmentize(EncodedImage* encoded_image, SFrameBSInfo* info) { // Calculate minimum buffer size required to hold encoded data. size_t required_capacity = 0; size_t fragments_count = 0; @@ -114,12 +110,12 @@ static void RtpFragmentize(EncodedImage* encoded_image, } } // TODO(nisse): Use a cache or buffer pool to avoid allocation? - encoded_image->SetEncodedData(EncodedImageBuffer::Create(required_capacity)); + auto buffer = EncodedImageBuffer::Create(required_capacity); + encoded_image->SetEncodedData(buffer); // Iterate layers and NAL units, note each NAL unit as a fragment and copy // the data to |encoded_image->_buffer|. const uint8_t start_code[4] = {0, 0, 0, 1}; - frag_header->VerifyAndAllocateFragmentationHeader(fragments_count); size_t frag = 0; encoded_image->set_size(0); for (int layer = 0; layer < info->iLayerNum; ++layer) { @@ -134,15 +130,10 @@ static void RtpFragmentize(EncodedImage* encoded_image, RTC_DCHECK_EQ(layerInfo.pBsBuf[layer_len + 1], start_code[1]); RTC_DCHECK_EQ(layerInfo.pBsBuf[layer_len + 2], start_code[2]); RTC_DCHECK_EQ(layerInfo.pBsBuf[layer_len + 3], start_code[3]); - frag_header->fragmentationOffset[frag] = - encoded_image->size() + layer_len + sizeof(start_code); - frag_header->fragmentationLength[frag] = - layerInfo.pNalLengthInByte[nal] - sizeof(start_code); layer_len += layerInfo.pNalLengthInByte[nal]; } // Copy the entire layer's data (including start codes). - memcpy(encoded_image->data() + encoded_image->size(), layerInfo.pBsBuf, - layer_len); + memcpy(buffer->data() + encoded_image->size(), layerInfo.pBsBuf, layer_len); encoded_image->set_size(encoded_image->size() + layer_len); } } @@ -284,7 +275,6 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst, CalcBufferSize(VideoType::kI420, codec_.simulcastStream[idx].width, codec_.simulcastStream[idx].height); encoded_images_[i].SetEncodedData(EncodedImageBuffer::Create(new_capacity)); - encoded_images_[i]._completeFrame = true; encoded_images_[i]._encodedWidth = codec_.simulcastStream[idx].width; encoded_images_[i]._encodedHeight = codec_.simulcastStream[idx].height; encoded_images_[i].set_size(0); @@ -485,8 +475,7 @@ int32_t H264EncoderImpl::Encode( // Split encoded image up into fragments. This also updates // |encoded_image_|. - RTPFragmentationHeader frag_header; - RtpFragmentize(&encoded_images_[i], &info, &frag_header); + RtpFragmentize(&encoded_images_[i], &info); // Encoder can skip frames to save bandwidth in which case // |encoded_images_[i]._length| == 0. @@ -518,7 +507,7 @@ int32_t H264EncoderImpl::Encode( } } encoded_image_callback_->OnEncodedImage(encoded_images_[i], - &codec_specific, &frag_header); + &codec_specific); } } return WEBRTC_VIDEO_CODEC_OK; @@ -555,6 +544,12 @@ SEncParamExt H264EncoderImpl::CreateEncoderParams(size_t i) const { // |uiIntraPeriod| - multiple of GOP size // |keyFrameInterval| - number of frames encoder_params.uiIntraPeriod = configurations_[i].key_frame_interval; + // Reuse SPS id if possible. This helps to avoid reset of chromium HW decoder + // on each key-frame. + // Note that WebRTC resets encoder on resolution change which makes all + // EParameterSetStrategy modes except INCREASING_ID (default) essentially + // equivalent to CONSTANT_ID. + encoder_params.eSpsPpsIdStrategy = SPS_LISTING; encoder_params.uiMaxNalSize = 0; // Threading model: use auto. // 0: auto (dynamic imp. internal encoder) @@ -625,6 +620,7 @@ VideoEncoder::EncoderInfo H264EncoderImpl::GetEncoderInfo() const { info.is_hardware_accelerated = false; info.has_internal_source = false; info.supports_simulcast = true; + info.preferred_pixel_formats = {VideoFrameBuffer::Type::kI420}; return info; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h index 7fb87eae9..4eb4ad38c 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h @@ -68,7 +68,7 @@ class H264EncoderImpl : public H264Encoder { EncodedImageCallback* callback) override; void SetRates(const RateControlParameters& parameters) override; - // The result of encoding - an EncodedImage and RTPFragmentationHeader - are + // The result of encoding - an EncodedImage and CodecSpecificInfo - are // passed to the encode complete callback. int32_t Encode(const VideoFrame& frame, const std::vector* frame_types) override; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h index 92a4c88ce..c43109e46 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h @@ -57,8 +57,7 @@ class MultiplexEncoderAdapter : public VideoEncoder { EncodedImageCallback::Result OnEncodedImage( AlphaCodecStream stream_idx, const EncodedImage& encodedImage, - const CodecSpecificInfo* codecSpecificInfo, - const RTPFragmentationHeader* fragmentation); + const CodecSpecificInfo* codecSpecificInfo); private: // Wrapper class that redirects OnEncodedImage() calls. diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc index cd39e72c2..39c14e412 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc @@ -76,23 +76,26 @@ struct MultiplexDecoderAdapter::DecodedImageData { decoded_image_(decoded_image), decode_time_ms_(decode_time_ms), qp_(qp) {} + + DecodedImageData() = delete; + DecodedImageData(const DecodedImageData&) = delete; + DecodedImageData& operator=(const DecodedImageData&) = delete; + const AlphaCodecStream stream_idx_; VideoFrame decoded_image_; const absl::optional decode_time_ms_; const absl::optional qp_; - - private: - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DecodedImageData); }; struct MultiplexDecoderAdapter::AugmentingData { AugmentingData(std::unique_ptr augmenting_data, uint16_t data_size) : data_(std::move(augmenting_data)), size_(data_size) {} + AugmentingData() = delete; + AugmentingData(const AugmentingData&) = delete; + AugmentingData& operator=(const AugmentingData&) = delete; + std::unique_ptr data_; const uint16_t size_; - - private: - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AugmentingData); }; MultiplexDecoderAdapter::MultiplexDecoderAdapter( diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc index 69fe7b9a1..0fbbc4271 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc @@ -17,7 +17,6 @@ #include "common_video/include/video_frame_buffer.h" #include "common_video/libyuv/include/webrtc_libyuv.h" #include "media/base/video_common.h" -#include "modules/include/module_common_types.h" #include "modules/video_coding/codecs/multiplex/include/augmented_video_frame_buffer.h" #include "rtc_base/keep_ref_until_done.h" #include "rtc_base/logging.h" @@ -35,12 +34,11 @@ class MultiplexEncoderAdapter::AdapterEncodedImageCallback EncodedImageCallback::Result OnEncodedImage( const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* fragmentation) override { + const CodecSpecificInfo* codec_specific_info) override { if (!adapter_) return Result(Result::OK); return adapter_->OnEncodedImage(stream_idx_, encoded_image, - codec_specific_info, fragmentation); + codec_specific_info); } private: @@ -109,6 +107,7 @@ int MultiplexEncoderAdapter::InitEncode( encoder_info_ = EncoderInfo(); encoder_info_.implementation_name = "MultiplexEncoderAdapter ("; encoder_info_.requested_resolution_alignment = 1; + encoder_info_.apply_alignment_to_all_simulcast_layers = false; // This needs to be false so that we can do the split in Encode(). encoder_info_.supports_native_handle = false; @@ -145,6 +144,10 @@ int MultiplexEncoderAdapter::InitEncode( encoder_info_.requested_resolution_alignment, encoder_impl_info.requested_resolution_alignment); + if (encoder_impl_info.apply_alignment_to_all_simulcast_layers) { + encoder_info_.apply_alignment_to_all_simulcast_layers = true; + } + encoder_info_.has_internal_source = false; encoders_.emplace_back(std::move(encoder)); @@ -292,8 +295,7 @@ VideoEncoder::EncoderInfo MultiplexEncoderAdapter::GetEncoderInfo() const { EncodedImageCallback::Result MultiplexEncoderAdapter::OnEncodedImage( AlphaCodecStream stream_idx, const EncodedImage& encodedImage, - const CodecSpecificInfo* codecSpecificInfo, - const RTPFragmentationHeader* fragmentation) { + const CodecSpecificInfo* codecSpecificInfo) { // Save the image MultiplexImageComponent image_component; image_component.component_index = stream_idx; @@ -330,8 +332,7 @@ EncodedImageCallback::Result MultiplexEncoderAdapter::OnEncodedImage( CodecSpecificInfo codec_info = *codecSpecificInfo; codec_info.codecType = kVideoCodecMultiplex; - encoded_complete_callback_->OnEncodedImage(combined_image_, &codec_info, - fragmentation); + encoded_complete_callback_->OnEncodedImage(combined_image_, &codec_info); } stashed_images_.erase(stashed_images_.begin(), stashed_image_next_itr); diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.cc index 1a3df403a..7bf611715 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.cc @@ -195,6 +195,10 @@ class LibvpxVp8Facade : public LibvpxInterface { vpx_codec_iter_t* iter) const override { return ::vpx_codec_get_cx_data(ctx, iter); } + + const char* codec_error_detail(vpx_codec_ctx_t* ctx) const override { + return ::vpx_codec_error_detail(ctx); + } }; } // namespace diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.h index fe40dedec..3da38ea24 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.h @@ -93,6 +93,8 @@ class LibvpxInterface { vpx_codec_ctx_t* ctx, vpx_codec_iter_t* iter) const = 0; + virtual const char* codec_error_detail(vpx_codec_ctx_t* ctx) const = 0; + // Returns interface wrapping the actual libvpx functions. static std::unique_ptr CreateEncoder(); }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc index d86d8767c..af48c9253 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc @@ -132,7 +132,10 @@ LibvpxVp8Decoder::LibvpxVp8Decoder() key_frame_required_(true), deblock_params_(use_postproc_ ? GetPostProcParamsFromFieldTrialGroup() : absl::nullopt), - qp_smoother_(use_postproc_ ? new QpSmoother() : nullptr) {} + qp_smoother_(use_postproc_ ? new QpSmoother() : nullptr), + preferred_output_format_(field_trial::IsEnabled("WebRTC-NV12Decode") + ? VideoFrameBuffer::Type::kNV12 + : VideoFrameBuffer::Type::kI420) {} LibvpxVp8Decoder::~LibvpxVp8Decoder() { inited_ = true; // in order to do the actual release @@ -237,21 +240,14 @@ int LibvpxVp8Decoder::Decode(const EncodedImage& input_image, if (key_frame_required_) { if (input_image._frameType != VideoFrameType::kVideoFrameKey) return WEBRTC_VIDEO_CODEC_ERROR; - // We have a key frame - is it complete? - if (input_image._completeFrame) { - key_frame_required_ = false; - } else { - return WEBRTC_VIDEO_CODEC_ERROR; - } + key_frame_required_ = false; } // Restrict error propagation using key frame requests. // Reset on a key frame refresh. - if (input_image._frameType == VideoFrameType::kVideoFrameKey && - input_image._completeFrame) { + if (input_image._frameType == VideoFrameType::kVideoFrameKey) { propagation_cnt_ = -1; // Start count on first loss. - } else if ((!input_image._completeFrame || missing_frames) && - propagation_cnt_ == -1) { + } else if (missing_frames && propagation_cnt_ == -1) { propagation_cnt_ = 0; } if (propagation_cnt_ >= 0) { @@ -328,8 +324,39 @@ int LibvpxVp8Decoder::ReturnFrame( last_frame_width_ = img->d_w; last_frame_height_ = img->d_h; // Allocate memory for decoded image. - rtc::scoped_refptr buffer = - buffer_pool_.CreateBuffer(img->d_w, img->d_h); + rtc::scoped_refptr buffer; + + if (preferred_output_format_ == VideoFrameBuffer::Type::kNV12) { + // Convert instead of making a copy. + // Note: libvpx doesn't support creating NV12 image directly. + // Due to the bitstream structure such a change would just hide the + // conversion operation inside the decode call. + rtc::scoped_refptr nv12_buffer = + buffer_pool_.CreateNV12Buffer(img->d_w, img->d_h); + buffer = nv12_buffer; + if (nv12_buffer.get()) { + libyuv::I420ToNV12(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], + img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], + img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], + nv12_buffer->MutableDataY(), nv12_buffer->StrideY(), + nv12_buffer->MutableDataUV(), nv12_buffer->StrideUV(), + img->d_w, img->d_h); + } + } else { + rtc::scoped_refptr i420_buffer = + buffer_pool_.CreateI420Buffer(img->d_w, img->d_h); + buffer = i420_buffer; + if (i420_buffer.get()) { + libyuv::I420Copy(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], + img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], + img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], + i420_buffer->MutableDataY(), i420_buffer->StrideY(), + i420_buffer->MutableDataU(), i420_buffer->StrideU(), + i420_buffer->MutableDataV(), i420_buffer->StrideV(), + img->d_w, img->d_h); + } + } + if (!buffer.get()) { // Pool has too many pending frames. RTC_HISTOGRAM_BOOLEAN("WebRTC.Video.LibvpxVp8Decoder.TooManyPendingFrames", @@ -337,14 +364,6 @@ int LibvpxVp8Decoder::ReturnFrame( return WEBRTC_VIDEO_CODEC_NO_OUTPUT; } - libyuv::I420Copy(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], - img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], - img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], - buffer->MutableDataY(), buffer->StrideY(), - buffer->MutableDataU(), buffer->StrideU(), - buffer->MutableDataV(), buffer->StrideV(), img->d_w, - img->d_h); - VideoFrame decoded_image = VideoFrame::Builder() .set_video_frame_buffer(buffer) .set_timestamp_rtp(timestamp) diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h index 2a0c5f2c5..cf699f183 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h @@ -16,7 +16,7 @@ #include "absl/types/optional.h" #include "api/video/encoded_image.h" #include "api/video_codecs/video_decoder.h" -#include "common_video/include/i420_buffer_pool.h" +#include "common_video/include/video_frame_buffer_pool.h" #include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/include/video_codec_interface.h" #include "vpx/vp8dx.h" @@ -54,7 +54,7 @@ class LibvpxVp8Decoder : public VideoDecoder { const webrtc::ColorSpace* explicit_color_space); const bool use_postproc_; - I420BufferPool buffer_pool_; + VideoFrameBufferPool buffer_pool_; DecodedImageCallback* decode_complete_callback_; bool inited_; vpx_codec_ctx_t* decoder_; @@ -64,6 +64,9 @@ class LibvpxVp8Decoder : public VideoDecoder { bool key_frame_required_; const absl::optional deblock_params_; const std::unique_ptr qp_smoother_; + + // Decoder should produce this format if possible. + const VideoFrameBuffer::Type preferred_output_format_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index 2f901ad81..340817658 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -68,9 +68,6 @@ constexpr uint32_t kVp832ByteAlign = 32u; constexpr int kRtpTicksPerSecond = 90000; constexpr int kRtpTicksPerMs = kRtpTicksPerSecond / 1000; -constexpr double kLowRateFactor = 1.0; -constexpr double kHighRateFactor = 2.0; - // VP8 denoiser states. enum denoiserState : uint32_t { kDenoiserOff, @@ -82,15 +79,6 @@ enum denoiserState : uint32_t { kDenoiserOnAdaptive }; -// These settings correspond to the settings in vpx_codec_enc_cfg. -struct Vp8RateSettings { - uint32_t rc_undershoot_pct; - uint32_t rc_overshoot_pct; - uint32_t rc_buf_sz; - uint32_t rc_buf_optimal_sz; - uint32_t rc_dropframe_thresh; -}; - // Greatest common divisior int GCD(int a, int b) { int c = a % b; @@ -102,56 +90,6 @@ int GCD(int a, int b) { return b; } -uint32_t Interpolate(uint32_t low, - uint32_t high, - double bandwidth_headroom_factor) { - RTC_DCHECK_GE(bandwidth_headroom_factor, kLowRateFactor); - RTC_DCHECK_LE(bandwidth_headroom_factor, kHighRateFactor); - - // |factor| is between 0.0 and 1.0. - const double factor = bandwidth_headroom_factor - kLowRateFactor; - - return static_cast(((1.0 - factor) * low) + (factor * high) + 0.5); -} - -Vp8RateSettings GetRateSettings(double bandwidth_headroom_factor) { - static const Vp8RateSettings low_settings{1000u, 0u, 100u, 30u, 40u}; - static const Vp8RateSettings high_settings{100u, 15u, 1000u, 600u, 5u}; - - if (bandwidth_headroom_factor <= kLowRateFactor) { - return low_settings; - } else if (bandwidth_headroom_factor >= kHighRateFactor) { - return high_settings; - } - - Vp8RateSettings settings; - settings.rc_undershoot_pct = - Interpolate(low_settings.rc_undershoot_pct, - high_settings.rc_undershoot_pct, bandwidth_headroom_factor); - settings.rc_overshoot_pct = - Interpolate(low_settings.rc_overshoot_pct, high_settings.rc_overshoot_pct, - bandwidth_headroom_factor); - settings.rc_buf_sz = - Interpolate(low_settings.rc_buf_sz, high_settings.rc_buf_sz, - bandwidth_headroom_factor); - settings.rc_buf_optimal_sz = - Interpolate(low_settings.rc_buf_optimal_sz, - high_settings.rc_buf_optimal_sz, bandwidth_headroom_factor); - settings.rc_dropframe_thresh = - Interpolate(low_settings.rc_dropframe_thresh, - high_settings.rc_dropframe_thresh, bandwidth_headroom_factor); - return settings; -} - -void UpdateRateSettings(vpx_codec_enc_cfg_t* config, - const Vp8RateSettings& new_settings) { - config->rc_undershoot_pct = new_settings.rc_undershoot_pct; - config->rc_overshoot_pct = new_settings.rc_overshoot_pct; - config->rc_buf_sz = new_settings.rc_buf_sz; - config->rc_buf_optimal_sz = new_settings.rc_buf_optimal_sz; - config->rc_dropframe_thresh = new_settings.rc_dropframe_thresh; -} - static_assert(Vp8EncoderConfig::TemporalLayerConfig::kMaxPeriodicity == VPX_TS_MAX_PERIODICITY, "Vp8EncoderConfig::kMaxPeriodicity must be kept in sync with the " @@ -291,7 +229,6 @@ vpx_enc_frame_flags_t LibvpxVp8Encoder::EncodeFlags( LibvpxVp8Encoder::LibvpxVp8Encoder(std::unique_ptr interface, VP8Encoder::Settings settings) : libvpx_(std::move(interface)), - experimental_cpu_speed_config_arm_(CpuSpeedExperiment::GetConfigs()), rate_control_settings_(RateControlSettings::ParseFromFieldTrials()), requested_resolution_alignment_override_( GetRequestedResolutionAlignmentOverride()), @@ -408,18 +345,12 @@ void LibvpxVp8Encoder::SetRates(const RateControlParameters& parameters) { UpdateVpxConfiguration(stream_idx); - if (rate_control_settings_.Vp8DynamicRateSettings()) { - // Tweak rate control settings based on available network headroom. - UpdateRateSettings( - &vpx_configs_[i], - GetRateSettings(parameters.bandwidth_allocation.bps() / - parameters.bitrate.get_sum_bps())); - } - vpx_codec_err_t err = libvpx_->codec_enc_config_set(&encoders_[i], &vpx_configs_[i]); if (err != VPX_CODEC_OK) { - RTC_LOG(LS_WARNING) << "Error configuring codec, error code: " << err; + RTC_LOG(LS_WARNING) << "Error configuring codec, error code: " << err + << ", details: " + << libvpx_->codec_error_detail(&encoders_[i]); } } } @@ -496,6 +427,10 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } + // Use the previous pixel format to avoid extra image allocations. + vpx_img_fmt_t pixel_format = + raw_images_.empty() ? VPX_IMG_FMT_I420 : raw_images_[0].fmt; + int retVal = Release(); if (retVal < 0) { return retVal; @@ -553,9 +488,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, downsampling_factors_[number_of_streams - 1].num = 1; downsampling_factors_[number_of_streams - 1].den = 1; } - for (int i = 0; i < number_of_streams; ++i) { - encoded_images_[i]._completeFrame = true; - } + // populate encoder configuration with default values if (libvpx_->codec_enc_config_default(vpx_codec_vp8_cx(), &vpx_configs_[0], 0)) { @@ -649,8 +582,8 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, // Creating a wrapper to the image - setting image data to NULL. // Actual pointer will be set in encode. Setting align to 1, as it // is meaningless (no memory allocation is done here). - libvpx_->img_wrap(&raw_images_[0], VPX_IMG_FMT_I420, inst->width, - inst->height, 1, NULL); + libvpx_->img_wrap(&raw_images_[0], pixel_format, inst->width, inst->height, 1, + NULL); // Note the order we use is different from webm, we have lowest resolution // at position 0 and they have highest resolution at position 0. @@ -698,10 +631,9 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, // Setting alignment to 32 - as that ensures at least 16 for all // planes (32 for Y, 16 for U,V). Libvpx sets the requested stride for // the y plane, but only half of it to the u and v planes. - libvpx_->img_alloc(&raw_images_[i], VPX_IMG_FMT_I420, - inst->simulcastStream[stream_idx].width, - inst->simulcastStream[stream_idx].height, - kVp832ByteAlign); + libvpx_->img_alloc( + &raw_images_[i], pixel_format, inst->simulcastStream[stream_idx].width, + inst->simulcastStream[stream_idx].height, kVp832ByteAlign); SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); vpx_configs_[i].rc_target_bitrate = stream_bitrates[stream_idx]; if (stream_bitrates[stream_idx] > 0) { @@ -728,14 +660,17 @@ int LibvpxVp8Encoder::GetCpuSpeed(int width, int height) { // On mobile platform, use a lower speed setting for lower resolutions for // CPUs with 4 or more cores. RTC_DCHECK_GT(number_of_cores_, 0); + if (experimental_cpu_speed_config_arm_ + .GetValue(width * height, number_of_cores_) + .has_value()) { + return experimental_cpu_speed_config_arm_ + .GetValue(width * height, number_of_cores_) + .value(); + } + if (number_of_cores_ <= 3) return -12; - if (experimental_cpu_speed_config_arm_) { - return CpuSpeedExperiment::GetValue(width * height, - *experimental_cpu_speed_config_arm_); - } - if (width * height <= 352 * 288) return -8; else if (width * height <= 640 * 480) @@ -1010,26 +945,31 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame, flags[i] = send_key_frame ? VPX_EFLAG_FORCE_KF : EncodeFlags(tl_configs[i]); } - rtc::scoped_refptr input_image = - frame.video_frame_buffer()->ToI420(); + rtc::scoped_refptr input_image = frame.video_frame_buffer(); // Since we are extracting raw pointers from |input_image| to // |raw_images_[0]|, the resolution of these frames must match. RTC_DCHECK_EQ(input_image->width(), raw_images_[0].d_w); RTC_DCHECK_EQ(input_image->height(), raw_images_[0].d_h); - - // Image in vpx_image_t format. - // Input image is const. VP8's raw image is not defined as const. - raw_images_[0].planes[VPX_PLANE_Y] = - const_cast(input_image->DataY()); - raw_images_[0].planes[VPX_PLANE_U] = - const_cast(input_image->DataU()); - raw_images_[0].planes[VPX_PLANE_V] = - const_cast(input_image->DataV()); - - raw_images_[0].stride[VPX_PLANE_Y] = input_image->StrideY(); - raw_images_[0].stride[VPX_PLANE_U] = input_image->StrideU(); - raw_images_[0].stride[VPX_PLANE_V] = input_image->StrideV(); - + switch (input_image->type()) { + case VideoFrameBuffer::Type::kI420: + PrepareI420Image(input_image->GetI420()); + break; + case VideoFrameBuffer::Type::kNV12: + PrepareNV12Image(input_image->GetNV12()); + break; + default: { + rtc::scoped_refptr i420_image = + input_image->ToI420(); + if (!i420_image) { + RTC_LOG(LS_ERROR) << "Failed to convert " + << VideoFrameBufferTypeToString(input_image->type()) + << " image to I420. Can't encode frame."; + return WEBRTC_VIDEO_CODEC_ERROR; + } + input_image = i420_image; + PrepareI420Image(i420_image); + } + } struct CleanUpOnExit { explicit CleanUpOnExit(vpx_image_t& raw_image) : raw_image_(raw_image) {} ~CleanUpOnExit() { @@ -1040,22 +980,6 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame, vpx_image_t& raw_image_; } clean_up_on_exit(raw_images_[0]); - for (size_t i = 1; i < encoders_.size(); ++i) { - // Scale the image down a number of times by downsampling factor - libyuv::I420Scale( - raw_images_[i - 1].planes[VPX_PLANE_Y], - raw_images_[i - 1].stride[VPX_PLANE_Y], - raw_images_[i - 1].planes[VPX_PLANE_U], - raw_images_[i - 1].stride[VPX_PLANE_U], - raw_images_[i - 1].planes[VPX_PLANE_V], - raw_images_[i - 1].stride[VPX_PLANE_V], raw_images_[i - 1].d_w, - raw_images_[i - 1].d_h, raw_images_[i].planes[VPX_PLANE_Y], - raw_images_[i].stride[VPX_PLANE_Y], raw_images_[i].planes[VPX_PLANE_U], - raw_images_[i].stride[VPX_PLANE_U], raw_images_[i].planes[VPX_PLANE_V], - raw_images_[i].stride[VPX_PLANE_V], raw_images_[i].d_w, - raw_images_[i].d_h, libyuv::kFilterBilinear); - } - if (send_key_frame) { // Adapt the size of the key frame when in screenshare with 1 temporal // layer. @@ -1214,7 +1138,7 @@ int LibvpxVp8Encoder::GetEncodedPartitions(const VideoFrame& input_image, &qp_128); encoded_images_[encoder_idx].qp_ = qp_128; encoded_complete_callback_->OnEncodedImage(encoded_images_[encoder_idx], - &codec_specific, nullptr); + &codec_specific); const size_t steady_state_size = SteadyStateSize( stream_idx, codec_specific.codecSpecific.VP8.temporalIdx); if (qp_128 > variable_framerate_experiment_.steady_state_qp || @@ -1267,6 +1191,8 @@ VideoEncoder::EncoderInfo LibvpxVp8Encoder::GetEncoderInfo() const { info.scaling_settings.min_pixels_per_frame = rate_control_settings_.LibvpxVp8MinPixels().value(); } + info.preferred_pixel_formats = {VideoFrameBuffer::Type::kI420, + VideoFrameBuffer::Type::kNV12}; if (inited_) { // |encoder_idx| is libvpx index where 0 is highest resolution. @@ -1305,17 +1231,99 @@ int LibvpxVp8Encoder::RegisterEncodeCompleteCallback( return WEBRTC_VIDEO_CODEC_OK; } +void LibvpxVp8Encoder::MaybeUpdatePixelFormat(vpx_img_fmt fmt) { + RTC_DCHECK(!raw_images_.empty()); + if (raw_images_[0].fmt == fmt) { + RTC_DCHECK(std::all_of( + std::next(raw_images_.begin()), raw_images_.end(), + [fmt](const vpx_image_t& raw_img) { return raw_img.fmt == fmt; })) + << "Not all raw images had the right format!"; + return; + } + RTC_LOG(INFO) << "Updating vp8 encoder pixel format to " + << (fmt == VPX_IMG_FMT_NV12 ? "NV12" : "I420"); + for (size_t i = 0; i < raw_images_.size(); ++i) { + vpx_image_t& img = raw_images_[i]; + auto d_w = img.d_w; + auto d_h = img.d_h; + libvpx_->img_free(&img); + // First image is wrapping the input frame, the rest are allocated. + if (i == 0) { + libvpx_->img_wrap(&img, fmt, d_w, d_h, 1, NULL); + } else { + libvpx_->img_alloc(&img, fmt, d_w, d_h, kVp832ByteAlign); + } + } +} + +void LibvpxVp8Encoder::PrepareI420Image(const I420BufferInterface* frame) { + RTC_DCHECK(!raw_images_.empty()); + MaybeUpdatePixelFormat(VPX_IMG_FMT_I420); + // Image in vpx_image_t format. + // Input image is const. VP8's raw image is not defined as const. + raw_images_[0].planes[VPX_PLANE_Y] = const_cast(frame->DataY()); + raw_images_[0].planes[VPX_PLANE_U] = const_cast(frame->DataU()); + raw_images_[0].planes[VPX_PLANE_V] = const_cast(frame->DataV()); + + raw_images_[0].stride[VPX_PLANE_Y] = frame->StrideY(); + raw_images_[0].stride[VPX_PLANE_U] = frame->StrideU(); + raw_images_[0].stride[VPX_PLANE_V] = frame->StrideV(); + + for (size_t i = 1; i < encoders_.size(); ++i) { + // Scale the image down a number of times by downsampling factor + libyuv::I420Scale( + raw_images_[i - 1].planes[VPX_PLANE_Y], + raw_images_[i - 1].stride[VPX_PLANE_Y], + raw_images_[i - 1].planes[VPX_PLANE_U], + raw_images_[i - 1].stride[VPX_PLANE_U], + raw_images_[i - 1].planes[VPX_PLANE_V], + raw_images_[i - 1].stride[VPX_PLANE_V], raw_images_[i - 1].d_w, + raw_images_[i - 1].d_h, raw_images_[i].planes[VPX_PLANE_Y], + raw_images_[i].stride[VPX_PLANE_Y], raw_images_[i].planes[VPX_PLANE_U], + raw_images_[i].stride[VPX_PLANE_U], raw_images_[i].planes[VPX_PLANE_V], + raw_images_[i].stride[VPX_PLANE_V], raw_images_[i].d_w, + raw_images_[i].d_h, libyuv::kFilterBilinear); + } +} + +void LibvpxVp8Encoder::PrepareNV12Image(const NV12BufferInterface* frame) { + RTC_DCHECK(!raw_images_.empty()); + MaybeUpdatePixelFormat(VPX_IMG_FMT_NV12); + // Image in vpx_image_t format. + // Input image is const. VP8's raw image is not defined as const. + raw_images_[0].planes[VPX_PLANE_Y] = const_cast(frame->DataY()); + raw_images_[0].planes[VPX_PLANE_U] = const_cast(frame->DataUV()); + raw_images_[0].planes[VPX_PLANE_V] = raw_images_[0].planes[VPX_PLANE_U] + 1; + raw_images_[0].stride[VPX_PLANE_Y] = frame->StrideY(); + raw_images_[0].stride[VPX_PLANE_U] = frame->StrideUV(); + raw_images_[0].stride[VPX_PLANE_V] = frame->StrideUV(); + + for (size_t i = 1; i < encoders_.size(); ++i) { + // Scale the image down a number of times by downsampling factor + libyuv::NV12Scale( + raw_images_[i - 1].planes[VPX_PLANE_Y], + raw_images_[i - 1].stride[VPX_PLANE_Y], + raw_images_[i - 1].planes[VPX_PLANE_U], + raw_images_[i - 1].stride[VPX_PLANE_U], raw_images_[i - 1].d_w, + raw_images_[i - 1].d_h, raw_images_[i].planes[VPX_PLANE_Y], + raw_images_[i].stride[VPX_PLANE_Y], raw_images_[i].planes[VPX_PLANE_U], + raw_images_[i].stride[VPX_PLANE_U], raw_images_[i].d_w, + raw_images_[i].d_h, libyuv::kFilterBilinear); + raw_images_[i].planes[VPX_PLANE_V] = raw_images_[i].planes[VPX_PLANE_U] + 1; + } +} + // static LibvpxVp8Encoder::VariableFramerateExperiment LibvpxVp8Encoder::ParseVariableFramerateConfig(std::string group_name) { - FieldTrialFlag enabled = FieldTrialFlag("Enabled"); + FieldTrialFlag disabled = FieldTrialFlag("Disabled"); FieldTrialParameter framerate_limit("min_fps", 5.0); FieldTrialParameter qp("min_qp", 15); FieldTrialParameter undershoot_percentage("undershoot", 30); - ParseFieldTrial({&enabled, &framerate_limit, &qp, &undershoot_percentage}, + ParseFieldTrial({&disabled, &framerate_limit, &qp, &undershoot_percentage}, field_trial::FindFullName(group_name)); VariableFramerateExperiment config; - config.enabled = enabled.Get(); + config.enabled = !disabled.Get(); config.framerate_limit = framerate_limit.Get(); config.steady_state_qp = qp.Get(); config.steady_state_undershoot_percentage = undershoot_percentage.Get(); diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h index f6cfd0ffe..c08b9b088 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h @@ -93,10 +93,13 @@ class LibvpxVp8Encoder : public VideoEncoder { bool UpdateVpxConfiguration(size_t stream_index); + void MaybeUpdatePixelFormat(vpx_img_fmt fmt); + void PrepareI420Image(const I420BufferInterface* frame); + void PrepareNV12Image(const NV12BufferInterface* frame); + const std::unique_ptr libvpx_; - const absl::optional> - experimental_cpu_speed_config_arm_; + const CpuSpeedExperiment experimental_cpu_speed_config_arm_; const RateControlSettings rate_control_settings_; // EncoderInfo::requested_resolution_alignment override from field trial. diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/temporal_layers_checker.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/temporal_layers_checker.cc index 53a68bd5e..5aebd2c52 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/temporal_layers_checker.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp8/temporal_layers_checker.cc @@ -29,6 +29,7 @@ TemporalLayersChecker::CreateTemporalLayersChecker(Vp8TemporalLayersType type, // Conference mode temporal layering for screen content in base stream. return std::make_unique(num_temporal_layers); } + RTC_CHECK_NOTREACHED(); } TemporalLayersChecker::TemporalLayersChecker(int num_temporal_layers) diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_config.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_config.h index 9bd8b0e31..f6b562e18 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_config.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_config.h @@ -14,7 +14,7 @@ #include -#include "common_types.h" // NOLINT(build/include) +#include "api/video_codecs/spatial_layer.h" namespace webrtc { diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h index a4e0c28cc..fa53a155a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h @@ -11,52 +11,7 @@ #ifndef MODULES_VIDEO_CODING_CODECS_VP9_SVC_RATE_ALLOCATOR_H_ #define MODULES_VIDEO_CODING_CODECS_VP9_SVC_RATE_ALLOCATOR_H_ -#include -#include - -#include "absl/container/inlined_vector.h" -#include "api/video/video_bitrate_allocation.h" -#include "api/video/video_bitrate_allocator.h" -#include "api/video/video_codec_constants.h" -#include "api/video_codecs/video_codec.h" -#include "rtc_base/experiments/stable_target_rate_experiment.h" - -namespace webrtc { - -class SvcRateAllocator : public VideoBitrateAllocator { - public: - explicit SvcRateAllocator(const VideoCodec& codec); - - VideoBitrateAllocation Allocate( - VideoBitrateAllocationParameters parameters) override; - - static DataRate GetMaxBitrate(const VideoCodec& codec); - static DataRate GetPaddingBitrate(const VideoCodec& codec); - static absl::InlinedVector GetLayerStartBitrates( - const VideoCodec& codec); - - private: - VideoBitrateAllocation GetAllocationNormalVideo( - DataRate total_bitrate, - size_t first_active_layer, - size_t num_spatial_layers) const; - - VideoBitrateAllocation GetAllocationScreenSharing( - DataRate total_bitrate, - size_t first_active_layer, - size_t num_spatial_layers) const; - - // Returns the number of layers that are active and have enough bitrate to - // actually be enabled. - size_t FindNumEnabledLayers(DataRate target_rate) const; - - const VideoCodec codec_; - const StableTargetRateExperiment experiment_settings_; - const absl::InlinedVector - cumulative_layer_start_bitrates_; - size_t last_active_layer_count_; -}; - -} // namespace webrtc +// TODO(danilchap): Update dependent includes and remove this forwarding header. +#include "modules/video_coding/svc/svc_rate_allocator.h" #endif // MODULES_VIDEO_CODING_CODECS_VP9_SVC_RATE_ALLOCATOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc index d29c19dc8..c2b1f501f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -19,20 +19,27 @@ #include #include "absl/memory/memory.h" +#include "absl/strings/match.h" +#include "api/transport/field_trial_based_config.h" #include "api/video/color_space.h" #include "api/video/i010_buffer.h" #include "common_video/include/video_frame_buffer.h" #include "common_video/libyuv/include/webrtc_libyuv.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/video_coding/codecs/vp9/svc_rate_allocator.h" +#include "modules/video_coding/svc/create_scalability_structure.h" +#include "modules/video_coding/svc/scalable_video_controller.h" +#include "modules/video_coding/svc/scalable_video_controller_no_layering.h" #include "modules/video_coding/utility/vp9_uncompressed_header_parser.h" #include "rtc_base/checks.h" +#include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/rate_control_settings.h" #include "rtc_base/keep_ref_until_done.h" #include "rtc_base/logging.h" +#include "rtc_base/strings/string_builder.h" #include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" -#include "system_wrappers/include/field_trial.h" +#include "third_party/libyuv/include/libyuv/convert.h" #include "vpx/vp8cx.h" #include "vpx/vp8dx.h" #include "vpx/vpx_decoder.h" @@ -49,9 +56,6 @@ uint8_t kUpdBufIdx[4] = {0, 0, 1, 0}; // Maximum allowed PID difference for differnet per-layer frame-rate case. const int kMaxAllowedPidDiff = 30; -constexpr double kLowRateFactor = 1.0; -constexpr double kHighRateFactor = 2.0; - // TODO(ilink): Tune these thresholds further. // Selected using ConverenceMotion_1280_720_50.yuv clip. // No toggling observed on any link capacity from 100-2000kbps. @@ -61,15 +65,6 @@ constexpr double kHighRateFactor = 2.0; constexpr int kLowVp9QpThreshold = 149; constexpr int kHighVp9QpThreshold = 205; -// These settings correspond to the settings in vpx_codec_enc_cfg. -struct Vp9RateSettings { - uint32_t rc_undershoot_pct; - uint32_t rc_overshoot_pct; - uint32_t rc_buf_sz; - uint32_t rc_buf_optimal_sz; - uint32_t rc_dropframe_thresh; -}; - // Only positive speeds, range for real-time coding currently is: 5 - 8. // Lower means slower/better quality, higher means fastest/lower quality. int GetCpuSpeed(int width, int height) { @@ -161,54 +156,110 @@ std::pair GetActiveLayers( return {0, 0}; } -uint32_t Interpolate(uint32_t low, - uint32_t high, - double bandwidth_headroom_factor) { - RTC_DCHECK_GE(bandwidth_headroom_factor, kLowRateFactor); - RTC_DCHECK_LE(bandwidth_headroom_factor, kHighRateFactor); - - // |factor| is between 0.0 and 1.0. - const double factor = bandwidth_headroom_factor - kLowRateFactor; - - return static_cast(((1.0 - factor) * low) + (factor * high) + 0.5); -} - -Vp9RateSettings GetRateSettings(double bandwidth_headroom_factor) { - static const Vp9RateSettings low_settings{100u, 0u, 100u, 33u, 40u}; - static const Vp9RateSettings high_settings{50u, 50u, 1000u, 700u, 5u}; - - if (bandwidth_headroom_factor <= kLowRateFactor) { - return low_settings; - } else if (bandwidth_headroom_factor >= kHighRateFactor) { - return high_settings; +std::unique_ptr CreateVp9ScalabilityStructure( + const VideoCodec& codec) { + int num_spatial_layers = codec.VP9().numberOfSpatialLayers; + int num_temporal_layers = + std::max(1, int{codec.VP9().numberOfTemporalLayers}); + if (num_spatial_layers == 1 && num_temporal_layers == 1) { + return std::make_unique(); } - Vp9RateSettings settings; - settings.rc_undershoot_pct = - Interpolate(low_settings.rc_undershoot_pct, - high_settings.rc_undershoot_pct, bandwidth_headroom_factor); - settings.rc_overshoot_pct = - Interpolate(low_settings.rc_overshoot_pct, high_settings.rc_overshoot_pct, - bandwidth_headroom_factor); - settings.rc_buf_sz = - Interpolate(low_settings.rc_buf_sz, high_settings.rc_buf_sz, - bandwidth_headroom_factor); - settings.rc_buf_optimal_sz = - Interpolate(low_settings.rc_buf_optimal_sz, - high_settings.rc_buf_optimal_sz, bandwidth_headroom_factor); - settings.rc_dropframe_thresh = - Interpolate(low_settings.rc_dropframe_thresh, - high_settings.rc_dropframe_thresh, bandwidth_headroom_factor); - return settings; + char name[20]; + rtc::SimpleStringBuilder ss(name); + if (codec.mode == VideoCodecMode::kScreensharing) { + // TODO(bugs.webrtc.org/11999): Compose names of the structures when they + // are implemented. + return nullptr; + } else if (codec.VP9().interLayerPred == InterLayerPredMode::kOn || + num_spatial_layers == 1) { + ss << "L" << num_spatial_layers << "T" << num_temporal_layers; + } else if (codec.VP9().interLayerPred == InterLayerPredMode::kOnKeyPic) { + ss << "L" << num_spatial_layers << "T" << num_temporal_layers << "_KEY"; + } else { + RTC_DCHECK_EQ(codec.VP9().interLayerPred, InterLayerPredMode::kOff); + ss << "S" << num_spatial_layers << "T" << num_temporal_layers; + } + + // Check spatial ratio. + if (num_spatial_layers > 1 && codec.spatialLayers[0].targetBitrate > 0) { + if (codec.width != codec.spatialLayers[num_spatial_layers - 1].width || + codec.height != codec.spatialLayers[num_spatial_layers - 1].height) { + RTC_LOG(LS_WARNING) + << "Top layer resolution expected to match overall resolution"; + return nullptr; + } + // Check if the ratio is one of the supported. + int numerator; + int denominator; + if (codec.spatialLayers[1].width == 2 * codec.spatialLayers[0].width) { + numerator = 1; + denominator = 2; + // no suffix for 1:2 ratio. + } else if (2 * codec.spatialLayers[1].width == + 3 * codec.spatialLayers[0].width) { + numerator = 2; + denominator = 3; + ss << "h"; + } else { + RTC_LOG(LS_WARNING) << "Unsupported scalability ratio " + << codec.spatialLayers[0].width << ":" + << codec.spatialLayers[1].width; + return nullptr; + } + // Validate ratio is consistent for all spatial layer transitions. + for (int sid = 1; sid < num_spatial_layers; ++sid) { + if (codec.spatialLayers[sid].width * numerator != + codec.spatialLayers[sid - 1].width * denominator || + codec.spatialLayers[sid].height * numerator != + codec.spatialLayers[sid - 1].height * denominator) { + RTC_LOG(LS_WARNING) << "Inconsistent scalability ratio " << numerator + << ":" << denominator; + return nullptr; + } + } + } + + auto scalability_structure_controller = CreateScalabilityStructure(name); + if (scalability_structure_controller == nullptr) { + RTC_LOG(LS_WARNING) << "Unsupported scalability structure " << name; + } else { + RTC_LOG(LS_INFO) << "Created scalability structure " << name; + } + return scalability_structure_controller; } -void UpdateRateSettings(vpx_codec_enc_cfg_t* config, - const Vp9RateSettings& new_settings) { - config->rc_undershoot_pct = new_settings.rc_undershoot_pct; - config->rc_overshoot_pct = new_settings.rc_overshoot_pct; - config->rc_buf_sz = new_settings.rc_buf_sz; - config->rc_buf_optimal_sz = new_settings.rc_buf_optimal_sz; - config->rc_dropframe_thresh = new_settings.rc_dropframe_thresh; +vpx_svc_ref_frame_config_t Vp9References( + rtc::ArrayView layers) { + vpx_svc_ref_frame_config_t ref_config = {}; + for (const ScalableVideoController::LayerFrameConfig& layer_frame : layers) { + const auto& buffers = layer_frame.Buffers(); + RTC_DCHECK_LE(buffers.size(), 3); + int sid = layer_frame.SpatialId(); + if (!buffers.empty()) { + ref_config.lst_fb_idx[sid] = buffers[0].id; + ref_config.reference_last[sid] = buffers[0].referenced; + if (buffers[0].updated) { + ref_config.update_buffer_slot[sid] |= (1 << buffers[0].id); + } + } + if (buffers.size() > 1) { + ref_config.gld_fb_idx[sid] = buffers[1].id; + ref_config.reference_golden[sid] = buffers[1].referenced; + if (buffers[1].updated) { + ref_config.update_buffer_slot[sid] |= (1 << buffers[1].id); + } + } + if (buffers.size() > 2) { + ref_config.alt_fb_idx[sid] = buffers[2].id; + ref_config.reference_alt_ref[sid] = buffers[2].referenced; + if (buffers[2].updated) { + ref_config.update_buffer_slot[sid] |= (1 << buffers[2].id); + } + } + } + // TODO(bugs.webrtc.org/11999): Fill ref_config.duration + return ref_config; } } // namespace @@ -220,6 +271,10 @@ void VP9EncoderImpl::EncoderOutputCodedPacketCallback(vpx_codec_cx_pkt* pkt, } VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec) + : VP9EncoderImpl(codec, FieldTrialBasedConfig()) {} + +VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec, + const WebRtcKeyValueConfig& trials) : encoded_image_(), encoded_complete_callback_(nullptr), profile_( @@ -238,27 +293,32 @@ VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec) num_spatial_layers_(0), num_active_spatial_layers_(0), first_active_layer_(0), - layer_deactivation_requires_key_frame_( - field_trial::IsEnabled("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation")), + layer_deactivation_requires_key_frame_(absl::StartsWith( + trials.Lookup("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation"), + "Enabled")), is_svc_(false), inter_layer_pred_(InterLayerPredMode::kOn), external_ref_control_(false), // Set in InitEncode because of tests. - trusted_rate_controller_(RateControlSettings::ParseFromFieldTrials() - .LibvpxVp9TrustedRateController()), - dynamic_rate_settings_( - RateControlSettings::ParseFromFieldTrials().Vp9DynamicRateSettings()), + trusted_rate_controller_( + RateControlSettings::ParseFromKeyValueConfig(&trials) + .LibvpxVp9TrustedRateController()), layer_buffering_(false), full_superframe_drop_(true), first_frame_in_picture_(true), ss_info_needed_(false), force_all_active_layers_(false), + use_svc_controller_( + absl::StartsWith(trials.Lookup("WebRTC-Vp9DependencyDescriptor"), + "Enabled")), is_flexible_mode_(false), - variable_framerate_experiment_(ParseVariableFramerateConfig( - "WebRTC-VP9VariableFramerateScreenshare")), + variable_framerate_experiment_(ParseVariableFramerateConfig(trials)), variable_framerate_controller_( variable_framerate_experiment_.framerate_limit), - quality_scaler_experiment_( - ParseQualityScalerConfig("WebRTC-VP9QualityScaler")), + quality_scaler_experiment_(ParseQualityScalerConfig(trials)), + external_ref_ctrl_( + !absl::StartsWith(trials.Lookup("WebRTC-Vp9ExternalRefCtrl"), + "Disabled")), + per_layer_speed_(ParsePerLayerSpeed(trials)), num_steady_state_frames_(0), config_changed_(true) { codec_ = {}; @@ -269,8 +329,7 @@ VP9EncoderImpl::~VP9EncoderImpl() { Release(); } -void VP9EncoderImpl::SetFecControllerOverride( - FecControllerOverride* fec_controller_override) { +void VP9EncoderImpl::SetFecControllerOverride(FecControllerOverride*) { // Ignored. } @@ -396,6 +455,8 @@ bool VP9EncoderImpl::SetSvcRates( first_active_layer_ = 0; bool seen_active_layer = false; bool expect_no_more_active_layers = false; + int highest_active_width = 0; + int highest_active_height = 0; for (int i = 0; i < num_spatial_layers_; ++i) { if (config_->ss_target_bitrate[i] > 0) { RTC_DCHECK(!expect_no_more_active_layers) << "Only middle layer is " @@ -405,6 +466,12 @@ bool VP9EncoderImpl::SetSvcRates( } num_active_spatial_layers_ = i + 1; seen_active_layer = true; + highest_active_width = + (svc_params_.scaling_factor_num[i] * config_->g_w) / + svc_params_.scaling_factor_den[i]; + highest_active_height = + (svc_params_.scaling_factor_num[i] * config_->g_h) / + svc_params_.scaling_factor_den[i]; } else { expect_no_more_active_layers = seen_active_layer; } @@ -419,7 +486,20 @@ bool VP9EncoderImpl::SetSvcRates( force_all_active_layers_ = true; } + if (svc_controller_) { + VideoBitrateAllocation allocation; + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + for (int tid = 0; tid < num_temporal_layers_; ++tid) { + allocation.SetBitrate( + sid, tid, + config_->layer_target_bitrate[sid * num_temporal_layers_ + tid] * + 1000); + } + } + svc_controller_->OnRatesUpdated(allocation); + } current_bitrate_allocation_ = bitrate_allocation; + cpu_speed_ = GetCpuSpeed(highest_active_width, highest_active_height); config_changed_ = true; return true; } @@ -441,13 +521,6 @@ void VP9EncoderImpl::SetRates(const RateControlParameters& parameters) { codec_.maxFramerate = static_cast(parameters.framerate_fps + 0.5); - if (dynamic_rate_settings_) { - // Tweak rate control settings based on available network headroom. - UpdateRateSettings( - config_, GetRateSettings(parameters.bandwidth_allocation.bps() / - parameters.bitrate.get_sum_bps())); - } - bool res = SetSvcRates(parameters.bitrate); RTC_DCHECK(res) << "Failed to set new bitrate allocation"; config_changed_ = true; @@ -480,6 +553,9 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst, return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } + absl::optional previous_img_fmt = + raw_ ? absl::make_optional(raw_->fmt) : absl::nullopt; + int ret_val = Release(); if (ret_val < 0) { return ret_val; @@ -505,12 +581,14 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst, num_temporal_layers_ = 1; } + if (use_svc_controller_) { + svc_controller_ = CreateVp9ScalabilityStructure(*inst); + } framerate_controller_ = std::vector( num_spatial_layers_, FramerateController(codec_.maxFramerate)); is_svc_ = (num_spatial_layers_ > 1 || num_temporal_layers_ > 1); - encoded_image_._completeFrame = true; // Populate encoder configuration with default values. if (vpx_codec_enc_config_default(vpx_codec_vp9_cx(), config_, 0)) { return WEBRTC_VIDEO_CODEC_ERROR; @@ -520,7 +598,7 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst, unsigned int bits_for_storage = 8; switch (profile_) { case VP9Profile::kProfile0: - img_fmt = VPX_IMG_FMT_I420; + img_fmt = previous_img_fmt.value_or(VPX_IMG_FMT_I420); bits_for_storage = 8; config_->g_bit_depth = VPX_BITS_8; config_->g_profile = 0; @@ -602,11 +680,10 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst, // External reference control is required for different frame rate on spatial // layers because libvpx generates rtp incompatible references in this case. - external_ref_control_ = - !field_trial::IsDisabled("WebRTC-Vp9ExternalRefCtrl") || - (num_spatial_layers_ > 1 && - codec_.mode == VideoCodecMode::kScreensharing) || - inter_layer_pred_ == InterLayerPredMode::kOn; + external_ref_control_ = external_ref_ctrl_ || + (num_spatial_layers_ > 1 && + codec_.mode == VideoCodecMode::kScreensharing) || + inter_layer_pred_ == InterLayerPredMode::kOn; if (num_temporal_layers_ == 1) { gof_.SetGofInfoVP9(kTemporalStructureMode1); @@ -684,7 +761,13 @@ int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) { svc_params_.min_quantizers[i] = config_->rc_min_quantizer; } config_->ss_number_layers = num_spatial_layers_; - if (ExplicitlyConfiguredSpatialLayers()) { + if (svc_controller_) { + auto stream_config = svc_controller_->StreamConfig(); + for (int i = 0; i < stream_config.num_spatial_layers; ++i) { + svc_params_.scaling_factor_num[i] = stream_config.scaling_factor_num[i]; + svc_params_.scaling_factor_den[i] = stream_config.scaling_factor_den[i]; + } + } else if (ExplicitlyConfiguredSpatialLayers()) { for (int i = 0; i < num_spatial_layers_; ++i) { const auto& layer = codec_.spatialLayers[i]; RTC_CHECK_GT(layer.width, 0); @@ -743,6 +826,22 @@ int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) { RTC_LOG(LS_ERROR) << "Init error: " << vpx_codec_err_to_string(rv); return WEBRTC_VIDEO_CODEC_UNINITIALIZED; } + + if (per_layer_speed_.enabled) { + for (int i = 0; i < num_spatial_layers_; ++i) { + if (codec_.spatialLayers[i].active) { + continue; + } + + if (per_layer_speed_.layers[i] != -1) { + svc_params_.speed_per_layer[i] = per_layer_speed_.layers[i]; + } else { + svc_params_.speed_per_layer[i] = GetCpuSpeed( + codec_.spatialLayers[i].width, codec_.spatialLayers[i].height); + } + } + } + vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_); vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT, rc_max_intra_target_); @@ -882,6 +981,13 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image, force_key_frame_ = true; } + if (svc_controller_) { + layer_frames_ = svc_controller_->NextFrameConfig(force_key_frame_); + if (layer_frames_.empty()) { + return WEBRTC_VIDEO_CODEC_ERROR; + } + } + vpx_svc_layer_id_t layer_id = {0}; if (!force_key_frame_) { const size_t gof_idx = (pics_since_key_ + 1) % gof_.num_frames_in_gof; @@ -953,6 +1059,15 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image, layer_id.spatial_layer_id = first_active_layer_; } + if (svc_controller_) { + layer_id.spatial_layer_id = layer_frames_.front().SpatialId(); + layer_id.temporal_layer_id = layer_frames_.front().TemporalId(); + for (const auto& layer : layer_frames_) { + layer_id.temporal_layer_id_per_spatial[layer.SpatialId()] = + layer.TemporalId(); + } + } + vpx_codec_control(encoder_, VP9E_SET_SVC_LAYER_ID, &layer_id); if (num_spatial_layers_ > 1) { @@ -965,6 +1080,7 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image, if (vpx_codec_enc_config_set(encoder_, config_)) { return WEBRTC_VIDEO_CODEC_ERROR; } + vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_); config_changed_ = false; } @@ -978,20 +1094,37 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image, input_image_ = &input_image; // Keep reference to buffer until encode completes. - rtc::scoped_refptr i420_buffer; + rtc::scoped_refptr video_frame_buffer; const I010BufferInterface* i010_buffer; rtc::scoped_refptr i010_copy; switch (profile_) { case VP9Profile::kProfile0: { - i420_buffer = input_image.video_frame_buffer()->ToI420(); - // Image in vpx_image_t format. - // Input image is const. VPX's raw image is not defined as const. - raw_->planes[VPX_PLANE_Y] = const_cast(i420_buffer->DataY()); - raw_->planes[VPX_PLANE_U] = const_cast(i420_buffer->DataU()); - raw_->planes[VPX_PLANE_V] = const_cast(i420_buffer->DataV()); - raw_->stride[VPX_PLANE_Y] = i420_buffer->StrideY(); - raw_->stride[VPX_PLANE_U] = i420_buffer->StrideU(); - raw_->stride[VPX_PLANE_V] = i420_buffer->StrideV(); + if (input_image.video_frame_buffer()->type() == + VideoFrameBuffer::Type::kNV12) { + const NV12BufferInterface* nv12_buffer = + input_image.video_frame_buffer()->GetNV12(); + video_frame_buffer = nv12_buffer; + MaybeRewrapRawWithFormat(VPX_IMG_FMT_NV12); + raw_->planes[VPX_PLANE_Y] = const_cast(nv12_buffer->DataY()); + raw_->planes[VPX_PLANE_U] = const_cast(nv12_buffer->DataUV()); + raw_->planes[VPX_PLANE_V] = raw_->planes[VPX_PLANE_U] + 1; + raw_->stride[VPX_PLANE_Y] = nv12_buffer->StrideY(); + raw_->stride[VPX_PLANE_U] = nv12_buffer->StrideUV(); + raw_->stride[VPX_PLANE_V] = nv12_buffer->StrideUV(); + } else { + rtc::scoped_refptr i420_buffer = + input_image.video_frame_buffer()->ToI420(); + video_frame_buffer = i420_buffer; + MaybeRewrapRawWithFormat(VPX_IMG_FMT_I420); + // Image in vpx_image_t format. + // Input image is const. VPX's raw image is not defined as const. + raw_->planes[VPX_PLANE_Y] = const_cast(i420_buffer->DataY()); + raw_->planes[VPX_PLANE_U] = const_cast(i420_buffer->DataU()); + raw_->planes[VPX_PLANE_V] = const_cast(i420_buffer->DataV()); + raw_->stride[VPX_PLANE_Y] = i420_buffer->StrideY(); + raw_->stride[VPX_PLANE_U] = i420_buffer->StrideU(); + raw_->stride[VPX_PLANE_V] = i420_buffer->StrideV(); + } break; } case VP9Profile::kProfile1: { @@ -1030,7 +1163,10 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image, flags = VPX_EFLAG_FORCE_KF; } - if (external_ref_control_) { + if (svc_controller_) { + vpx_svc_ref_frame_config_t ref_config = Vp9References(layer_frames_); + vpx_codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_config); + } else if (external_ref_control_) { vpx_svc_ref_frame_config_t ref_config = SetReferences(force_key_frame_, layer_id.spatial_layer_id); @@ -1196,6 +1332,31 @@ void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific, } first_frame_in_picture_ = false; + + // Populate codec-agnostic section in the codec specific structure. + if (svc_controller_) { + auto it = absl::c_find_if( + layer_frames_, + [&](const ScalableVideoController::LayerFrameConfig& config) { + return config.SpatialId() == spatial_idx->value_or(0); + }); + RTC_CHECK(it != layer_frames_.end()) + << "Failed to find spatial id " << spatial_idx->value_or(0); + codec_specific->generic_frame_info = svc_controller_->OnEncodeDone(*it); + if (is_key_frame) { + codec_specific->template_structure = + svc_controller_->DependencyStructure(); + auto& resolutions = codec_specific->template_structure->resolutions; + resolutions.resize(num_spatial_layers_); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + resolutions[sid] = RenderResolution( + /*width=*/codec_.width * svc_params_.scaling_factor_num[sid] / + svc_params_.scaling_factor_den[sid], + /*height=*/codec_.height * svc_params_.scaling_factor_num[sid] / + svc_params_.scaling_factor_den[sid]); + } + } + } } void VP9EncoderImpl::FillReferenceIndices(const vpx_codec_cx_pkt& pkt, @@ -1484,7 +1645,6 @@ int VP9EncoderImpl::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) { encoded_image_._frameType = VideoFrameType::kVideoFrameKey; force_key_frame_ = false; } - RTC_DCHECK_LE(encoded_image_.size(), encoded_image_.capacity()); codec_specific_ = {}; absl::optional spatial_index; @@ -1523,17 +1683,10 @@ void VP9EncoderImpl::DeliverBufferedFrame(bool end_of_picture) { } } - codec_specific_.codecSpecific.VP9.end_of_picture = end_of_picture; + codec_specific_.end_of_picture = end_of_picture; - // No data partitioning in VP9, so 1 partition only. - int part_idx = 0; - RTPFragmentationHeader frag_info; - frag_info.VerifyAndAllocateFragmentationHeader(1); - frag_info.fragmentationOffset[part_idx] = 0; - frag_info.fragmentationLength[part_idx] = encoded_image_.size(); - - encoded_complete_callback_->OnEncodedImage(encoded_image_, &codec_specific_, - &frag_info); + encoded_complete_callback_->OnEncodedImage(encoded_image_, + &codec_specific_); if (codec_.mode == VideoCodecMode::kScreensharing) { const uint8_t spatial_idx = encoded_image_.SpatialIndex().value_or(0); @@ -1571,7 +1724,8 @@ VideoEncoder::EncoderInfo VP9EncoderImpl::GetEncoderInfo() const { EncoderInfo info; info.supports_native_handle = false; info.implementation_name = "libvpx"; - if (quality_scaler_experiment_.enabled) { + if (quality_scaler_experiment_.enabled && inited_ && + codec_.VP9().automaticResizeOn) { info.scaling_settings = VideoEncoder::ScalingSettings( quality_scaler_experiment_.low_qp, quality_scaler_experiment_.high_qp); } else { @@ -1608,6 +1762,10 @@ VideoEncoder::EncoderInfo VP9EncoderImpl::GetEncoderInfo() const { (sl_fps_fraction / decimator))); } } + if (profile_ == VP9Profile::kProfile0) { + info.preferred_pixel_formats = {VideoFrameBuffer::Type::kI420, + VideoFrameBuffer::Type::kNV12}; + } } return info; } @@ -1629,7 +1787,8 @@ size_t VP9EncoderImpl::SteadyStateSize(int sid, int tid) { // static VP9EncoderImpl::VariableFramerateExperiment -VP9EncoderImpl::ParseVariableFramerateConfig(std::string group_name) { +VP9EncoderImpl::ParseVariableFramerateConfig( + const WebRtcKeyValueConfig& trials) { FieldTrialFlag enabled = FieldTrialFlag("Enabled"); FieldTrialParameter framerate_limit("min_fps", 5.0); FieldTrialParameter qp("min_qp", 32); @@ -1638,7 +1797,7 @@ VP9EncoderImpl::ParseVariableFramerateConfig(std::string group_name) { "frames_before_steady_state", 5); ParseFieldTrial({&enabled, &framerate_limit, &qp, &undershoot_percentage, &frames_before_steady_state}, - field_trial::FindFullName(group_name)); + trials.Lookup("WebRTC-VP9VariableFramerateScreenshare")); VariableFramerateExperiment config; config.enabled = enabled.Get(); config.framerate_limit = framerate_limit.Get(); @@ -1651,12 +1810,12 @@ VP9EncoderImpl::ParseVariableFramerateConfig(std::string group_name) { // static VP9EncoderImpl::QualityScalerExperiment -VP9EncoderImpl::ParseQualityScalerConfig(std::string group_name) { +VP9EncoderImpl::ParseQualityScalerConfig(const WebRtcKeyValueConfig& trials) { FieldTrialFlag disabled = FieldTrialFlag("Disabled"); FieldTrialParameter low_qp("low_qp", kLowVp9QpThreshold); FieldTrialParameter high_qp("hihg_qp", kHighVp9QpThreshold); ParseFieldTrial({&disabled, &low_qp, &high_qp}, - field_trial::FindFullName(group_name)); + trials.Lookup("WebRTC-VP9QualityScaler")); QualityScalerExperiment config; config.enabled = !disabled.Get(); RTC_LOG(LS_INFO) << "Webrtc quality scaler for vp9 is " @@ -1667,16 +1826,47 @@ VP9EncoderImpl::ParseQualityScalerConfig(std::string group_name) { return config; } -VP9DecoderImpl::VP9DecoderImpl() +// static +VP9EncoderImpl::SpeedSettings VP9EncoderImpl::ParsePerLayerSpeed( + const WebRtcKeyValueConfig& trials) { + FieldTrialFlag enabled("enabled"); + FieldTrialParameter speeds[kMaxSpatialLayers]{ + {"s0", -1}, {"s1", -1}, {"s2", -1}, {"s3", -1}, {"s4", -1}}; + ParseFieldTrial( + {&enabled, &speeds[0], &speeds[1], &speeds[2], &speeds[3], &speeds[4]}, + trials.Lookup("WebRTC-VP9-PerLayerSpeed")); + return SpeedSettings{enabled.Get(), + {speeds[0].Get(), speeds[1].Get(), speeds[2].Get(), + speeds[3].Get(), speeds[4].Get()}}; +} + +void VP9EncoderImpl::MaybeRewrapRawWithFormat(const vpx_img_fmt fmt) { + if (!raw_) { + raw_ = vpx_img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, nullptr); + } else if (raw_->fmt != fmt) { + RTC_LOG(INFO) << "Switching VP9 encoder pixel format to " + << (fmt == VPX_IMG_FMT_NV12 ? "NV12" : "I420"); + vpx_img_free(raw_); + raw_ = vpx_img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, nullptr); + } + // else no-op since the image is already in the right format. +} + +VP9DecoderImpl::VP9DecoderImpl() : VP9DecoderImpl(FieldTrialBasedConfig()) {} +VP9DecoderImpl::VP9DecoderImpl(const WebRtcKeyValueConfig& trials) : decode_complete_callback_(nullptr), inited_(false), decoder_(nullptr), - key_frame_required_(true) {} + key_frame_required_(true), + preferred_output_format_( + absl::StartsWith(trials.Lookup("WebRTC-NV12Decode"), "Enabled") + ? VideoFrameBuffer::Type::kNV12 + : VideoFrameBuffer::Type::kI420) {} VP9DecoderImpl::~VP9DecoderImpl() { inited_ = true; // in order to do the actual release Release(); - int num_buffers_in_use = frame_buffer_pool_.GetNumBuffersInUse(); + int num_buffers_in_use = libvpx_buffer_pool_.GetNumBuffersInUse(); if (num_buffers_in_use > 0) { // The frame buffers are reference counted and frames are exposed after // decoding. There may be valid usage cases where previous frames are still @@ -1737,7 +1927,7 @@ int VP9DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) { return WEBRTC_VIDEO_CODEC_MEMORY; } - if (!frame_buffer_pool_.InitializeVpxUsePool(decoder_)) { + if (!libvpx_buffer_pool_.InitializeVpxUsePool(decoder_)) { return WEBRTC_VIDEO_CODEC_MEMORY; } @@ -1745,7 +1935,8 @@ int VP9DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) { // Always start with a complete key frame. key_frame_required_ = true; if (inst && inst->buffer_pool_size) { - if (!frame_buffer_pool_.Resize(*inst->buffer_pool_size)) { + if (!libvpx_buffer_pool_.Resize(*inst->buffer_pool_size) || + !output_buffer_pool_.Resize(*inst->buffer_pool_size)) { return WEBRTC_VIDEO_CODEC_UNINITIALIZED; } } @@ -1797,12 +1988,7 @@ int VP9DecoderImpl::Decode(const EncodedImage& input_image, if (key_frame_required_) { if (input_image._frameType != VideoFrameType::kVideoFrameKey) return WEBRTC_VIDEO_CODEC_ERROR; - // We have a key frame - is it complete? - if (input_image._completeFrame) { - key_frame_required_ = false; - } else { - return WEBRTC_VIDEO_CODEC_ERROR; - } + key_frame_required_ = false; } vpx_codec_iter_t iter = nullptr; vpx_image_t* img; @@ -1810,8 +1996,9 @@ int VP9DecoderImpl::Decode(const EncodedImage& input_image, if (input_image.size() == 0) { buffer = nullptr; // Triggers full frame concealment. } - // During decode libvpx may get and release buffers from |frame_buffer_pool_|. - // In practice libvpx keeps a few (~3-4) buffers alive at a time. + // During decode libvpx may get and release buffers from + // |libvpx_buffer_pool_|. In practice libvpx keeps a few (~3-4) buffers alive + // at a time. if (vpx_codec_decode(decoder_, buffer, static_cast(input_image.size()), 0, VPX_DL_REALTIME)) { @@ -1855,15 +2042,34 @@ int VP9DecoderImpl::ReturnFrame( switch (img->bit_depth) { case 8: if (img->fmt == VPX_IMG_FMT_I420) { - img_wrapped_buffer = WrapI420Buffer( - img->d_w, img->d_h, img->planes[VPX_PLANE_Y], - img->stride[VPX_PLANE_Y], img->planes[VPX_PLANE_U], - img->stride[VPX_PLANE_U], img->planes[VPX_PLANE_V], - img->stride[VPX_PLANE_V], - // WrappedI420Buffer's mechanism for allowing the release of its - // frame buffer is through a callback function. This is where we - // should release |img_buffer|. - rtc::KeepRefUntilDone(img_buffer)); + if (preferred_output_format_ == VideoFrameBuffer::Type::kNV12) { + rtc::scoped_refptr nv12_buffer = + output_buffer_pool_.CreateNV12Buffer(img->d_w, img->d_h); + if (!nv12_buffer.get()) { + // Buffer pool is full. + return WEBRTC_VIDEO_CODEC_NO_OUTPUT; + } + img_wrapped_buffer = nv12_buffer; + libyuv::I420ToNV12(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], + img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], + img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], + nv12_buffer->MutableDataY(), + nv12_buffer->StrideY(), + nv12_buffer->MutableDataUV(), + nv12_buffer->StrideUV(), img->d_w, img->d_h); + // No holding onto img_buffer as it's no longer needed and can be + // reused. + } else { + img_wrapped_buffer = WrapI420Buffer( + img->d_w, img->d_h, img->planes[VPX_PLANE_Y], + img->stride[VPX_PLANE_Y], img->planes[VPX_PLANE_U], + img->stride[VPX_PLANE_U], img->planes[VPX_PLANE_V], + img->stride[VPX_PLANE_V], + // WrappedI420Buffer's mechanism for allowing the release of its + // frame buffer is through a callback function. This is where we + // should release |img_buffer|. + rtc::KeepRefUntilDone(img_buffer)); + } } else if (img->fmt == VPX_IMG_FMT_I444) { img_wrapped_buffer = WrapI444Buffer( img->d_w, img->d_h, img->planes[VPX_PLANE_Y], @@ -1924,7 +2130,7 @@ int VP9DecoderImpl::Release() { if (decoder_ != nullptr) { if (inited_) { // When a codec is destroyed libvpx will release any buffers of - // |frame_buffer_pool_| it is currently using. + // |libvpx_buffer_pool_| it is currently using. if (vpx_codec_destroy(decoder_)) { ret_val = WEBRTC_VIDEO_CODEC_MEMORY; } @@ -1935,7 +2141,8 @@ int VP9DecoderImpl::Release() { // Releases buffers from the pool. Any buffers not in use are deleted. Buffers // still referenced externally are deleted once fully released, not returning // to the pool. - frame_buffer_pool_.ClearPool(); + libvpx_buffer_pool_.ClearPool(); + output_buffer_pool_.Release(); inited_ = false; return ret_val; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h index fae94c752..14c3ca8cc 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h @@ -20,10 +20,13 @@ #include #include "api/fec_controller_override.h" +#include "api/transport/webrtc_key_value_config.h" #include "api/video_codecs/video_encoder.h" +#include "common_video/include/video_frame_buffer_pool.h" #include "media/base/vp9_profile.h" #include "modules/video_coding/codecs/vp9/include/vp9.h" #include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h" +#include "modules/video_coding/svc/scalable_video_controller.h" #include "modules/video_coding/utility/framerate_controller.h" #include "vpx/vp8cx.h" #include "vpx/vpx_decoder.h" @@ -34,6 +37,8 @@ namespace webrtc { class VP9EncoderImpl : public VP9Encoder { public: explicit VP9EncoderImpl(const cricket::VideoCodec& codec); + VP9EncoderImpl(const cricket::VideoCodec& codec, + const WebRtcKeyValueConfig& trials); ~VP9EncoderImpl() override; @@ -98,6 +103,8 @@ class VP9EncoderImpl : public VP9Encoder { size_t SteadyStateSize(int sid, int tid); + void MaybeRewrapRawWithFormat(const vpx_img_fmt fmt); + EncodedImage encoded_image_; CodecSpecificInfo codec_specific_; EncodedImageCallback* encoded_complete_callback_; @@ -125,7 +132,6 @@ class VP9EncoderImpl : public VP9Encoder { InterLayerPredMode inter_layer_pred_; bool external_ref_control_; const bool trusted_rate_controller_; - const bool dynamic_rate_settings_; bool layer_buffering_; const bool full_superframe_drop_; vpx_svc_frame_drop_t svc_drop_frame_; @@ -133,7 +139,9 @@ class VP9EncoderImpl : public VP9Encoder { VideoBitrateAllocation current_bitrate_allocation_; bool ss_info_needed_; bool force_all_active_layers_; + const bool use_svc_controller_; + std::unique_ptr svc_controller_; std::vector framerate_controller_; // Used for flexible mode. @@ -157,6 +165,7 @@ class VP9EncoderImpl : public VP9Encoder { size_t temporal_layer_id = 0; }; std::map ref_buf_; + std::vector layer_frames_; // Variable frame-rate related fields and methods. const struct VariableFramerateExperiment { @@ -173,7 +182,7 @@ class VP9EncoderImpl : public VP9Encoder { int frames_before_steady_state; } variable_framerate_experiment_; static VariableFramerateExperiment ParseVariableFramerateConfig( - std::string group_name); + const WebRtcKeyValueConfig& trials); FramerateController variable_framerate_controller_; const struct QualityScalerExperiment { @@ -182,7 +191,14 @@ class VP9EncoderImpl : public VP9Encoder { bool enabled; } quality_scaler_experiment_; static QualityScalerExperiment ParseQualityScalerConfig( - std::string group_name); + const WebRtcKeyValueConfig& trials); + const bool external_ref_ctrl_; + + const struct SpeedSettings { + bool enabled; + int layers[kMaxSpatialLayers]; + } per_layer_speed_; + static SpeedSettings ParsePerLayerSpeed(const WebRtcKeyValueConfig& trials); int num_steady_state_frames_; // Only set config when this flag is set. @@ -192,6 +208,7 @@ class VP9EncoderImpl : public VP9Encoder { class VP9DecoderImpl : public VP9Decoder { public: VP9DecoderImpl(); + explicit VP9DecoderImpl(const WebRtcKeyValueConfig& trials); virtual ~VP9DecoderImpl(); @@ -214,13 +231,18 @@ class VP9DecoderImpl : public VP9Decoder { const webrtc::ColorSpace* explicit_color_space); // Memory pool used to share buffers between libvpx and webrtc. - Vp9FrameBufferPool frame_buffer_pool_; + Vp9FrameBufferPool libvpx_buffer_pool_; + // Buffer pool used to allocate additionally needed NV12 buffers. + VideoFrameBufferPool output_buffer_pool_; DecodedImageCallback* decode_complete_callback_; bool inited_; vpx_codec_ctx_t* decoder_; bool key_frame_required_; VideoCodec current_codec_; int num_cores_; + + // Decoder should produce this format if possible. + const VideoFrameBuffer::Type preferred_output_format_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/decoder_database.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/decoder_database.cc index 32be39bcb..a7a4b8f75 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/decoder_database.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/decoder_database.cc @@ -96,7 +96,7 @@ bool VCMDecoderDataBase::DeregisterReceiveCodec(uint8_t payload_type) { dec_map_.erase(it); if (payload_type == current_payload_type_) { // This codec is currently in use. - memset(&receive_codec_, 0, sizeof(VideoCodec)); + receive_codec_ = {}; current_payload_type_ = 0; } return true; @@ -113,7 +113,7 @@ VCMGenericDecoder* VCMDecoderDataBase::GetDecoder( // If decoder exists - delete. if (ptr_decoder_) { ptr_decoder_.reset(); - memset(&receive_codec_, 0, sizeof(VideoCodec)); + receive_codec_ = {}; current_payload_type_ = 0; } ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_); @@ -126,7 +126,7 @@ VCMGenericDecoder* VCMDecoderDataBase::GetDecoder( if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) < 0) { ptr_decoder_.reset(); - memset(&receive_codec_, 0, sizeof(VideoCodec)); + receive_codec_ = {}; current_payload_type_ = 0; return nullptr; } @@ -178,7 +178,7 @@ std::unique_ptr VCMDecoderDataBase::CreateAndInitDecoder( RTC_LOG(LS_ERROR) << "Failed to initialize decoder. Error code: " << err; return nullptr; } - memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec)); + *new_codec = *decoder_item->settings.get(); return ptr_decoder; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/encoded_frame.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/encoded_frame.cc index 3c26b8a72..4638771b2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/encoded_frame.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/encoded_frame.cc @@ -43,7 +43,6 @@ void VCMEncodedFrame::Reset() { _frameType = VideoFrameType::kVideoFrameDelta; _encodedWidth = 0; _encodedHeight = 0; - _completeFrame = false; _missingFrame = false; set_size(0); _codecSpecificInfo.codecType = kVideoCodecGeneric; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/encoded_frame.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/encoded_frame.h index 261aae77a..a77d42eec 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/encoded_frame.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/encoded_frame.h @@ -34,7 +34,9 @@ class RTC_EXPORT VCMEncodedFrame : protected EncodedImage { _renderTimeMs = renderTimeMs; } - void SetPlayoutDelay(PlayoutDelay playout_delay) { + VideoPlayoutDelay PlayoutDelay() const { return playout_delay_; } + + void SetPlayoutDelay(VideoPlayoutDelay playout_delay) { playout_delay_ = playout_delay; } @@ -90,10 +92,6 @@ class RTC_EXPORT VCMEncodedFrame : protected EncodedImage { */ EncodedImage::Timing video_timing() const { return timing_; } EncodedImage::Timing* video_timing_mutable() { return &timing_; } - /** - * True if this frame is complete, false otherwise - */ - bool Complete() const { return _completeFrame; } /** * True if there's a frame missing before this frame */ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer.cc index 755acb294..0f64ab144 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer.cc @@ -70,11 +70,6 @@ void VCMFrameBuffer::SetGofInfo(const GofInfoVP9& gof_info, size_t idx) { gof_info.temporal_up_switch[idx]; } -bool VCMFrameBuffer::IsSessionComplete() const { - TRACE_EVENT0("webrtc", "VCMFrameBuffer::IsSessionComplete"); - return _sessionInfo.complete(); -} - // Insert packet VCMFrameBufferEnum VCMFrameBuffer::InsertPacket(const VCMPacket& packet, int64_t timeInMs, @@ -98,15 +93,16 @@ VCMFrameBufferEnum VCMFrameBuffer::InsertPacket(const VCMPacket& packet, } } + size_t oldSize = encoded_image_buffer_ ? encoded_image_buffer_->size() : 0; uint32_t requiredSizeBytes = size() + packet.sizeBytes + (packet.insertStartCode ? kH264StartCodeLengthBytes : 0); - if (requiredSizeBytes > capacity()) { + if (requiredSizeBytes > oldSize) { const uint8_t* prevBuffer = data(); const uint32_t increments = requiredSizeBytes / kBufferIncStepSizeBytes + (requiredSizeBytes % kBufferIncStepSizeBytes > 0); - const uint32_t newSize = capacity() + increments * kBufferIncStepSizeBytes; + const uint32_t newSize = oldSize + increments * kBufferIncStepSizeBytes; if (newSize > kMaxJBFrameSizeBytes) { RTC_LOG(LS_ERROR) << "Failed to insert packet due to frame being too " "big."; @@ -133,7 +129,9 @@ VCMFrameBufferEnum VCMFrameBuffer::InsertPacket(const VCMPacket& packet, if (packet.sizeBytes > 0) CopyCodecSpecific(&packet.video_header); - int retVal = _sessionInfo.InsertPacket(packet, data(), frame_data); + int retVal = _sessionInfo.InsertPacket( + packet, encoded_image_buffer_ ? encoded_image_buffer_->data() : nullptr, + frame_data); if (retVal == -1) { return kSizeError; } else if (retVal == -2) { @@ -262,7 +260,6 @@ void VCMFrameBuffer::PrepareForDecode(bool continuous) { // Transfer frame information to EncodedFrame and create any codec // specific information. _frameType = _sessionInfo.FrameType(); - _completeFrame = _sessionInfo.complete(); _missingFrame = !continuous; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer2.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer2.cc index fd65d7e25..afce78766 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer2.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer2.cc @@ -348,6 +348,11 @@ void FrameBuffer::Clear() { ClearFramesAndHistory(); } +int FrameBuffer::Size() { + MutexLock lock(&mutex_); + return frames_.size(); +} + void FrameBuffer::UpdateRtt(int64_t rtt_ms) { MutexLock lock(&mutex_); jitter_estimator_.UpdateRtt(rtt_ms); diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer2.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer2.h index c88ae891c..2ed21c4f7 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer2.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_buffer2.h @@ -23,7 +23,6 @@ #include "modules/video_coding/inter_frame_delay.h" #include "modules/video_coding/jitter_estimator.h" #include "modules/video_coding/utility/decoded_frames_history.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/event.h" #include "rtc_base/experiments/rtt_mult_experiment.h" #include "rtc_base/numerics/sequence_number_util.h" @@ -50,6 +49,10 @@ class FrameBuffer { VCMTiming* timing, VCMReceiveStatisticsCallback* stats_callback); + FrameBuffer() = delete; + FrameBuffer(const FrameBuffer&) = delete; + FrameBuffer& operator=(const FrameBuffer&) = delete; + virtual ~FrameBuffer(); // Insert a frame into the frame buffer. Returns the picture id @@ -81,6 +84,8 @@ class FrameBuffer { // Clears the FrameBuffer, removing all the buffered frames. void Clear(); + int Size(); + private: struct FrameInfo { FrameInfo(); @@ -188,8 +193,6 @@ class FrameBuffer { // rtt_mult experiment settings. const absl::optional rtt_mult_settings_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(FrameBuffer); }; } // namespace video_coding diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_object.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_object.cc index bdb43f799..25fd23234 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_object.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_object.cc @@ -38,7 +38,8 @@ RtpFrameObject::RtpFrameObject( const absl::optional& color_space, RtpPacketInfos packet_infos, rtc::scoped_refptr image_buffer) - : first_seq_num_(first_seq_num), + : image_buffer_(image_buffer), + first_seq_num_(first_seq_num), last_seq_num_(last_seq_num), last_packet_received_time_(last_packet_received_time), times_nacked_(times_nacked) { @@ -50,7 +51,6 @@ RtpFrameObject::RtpFrameObject( // TODO(philipel): Remove when encoded image is replaced by EncodedFrame. // VCMEncodedFrame members CopyCodecSpecific(&rtp_video_header_); - _completeFrame = true; _payloadType = payload_type; SetTimestamp(rtp_timestamp); ntp_time_ms_ = ntp_time_ms; @@ -60,7 +60,7 @@ RtpFrameObject::RtpFrameObject( // as of the first packet's. SetPlayoutDelay(rtp_video_header_.playout_delay); - SetEncodedData(std::move(image_buffer)); + SetEncodedData(image_buffer_); _encodedWidth = rtp_video_header_.width; _encodedHeight = rtp_video_header_.height; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_object.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_object.h index 831b444df..d812b8fd2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_object.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/frame_object.h @@ -48,7 +48,11 @@ class RtpFrameObject : public EncodedFrame { bool delayed_by_retransmission() const override; const RTPVideoHeader& GetRtpVideoHeader() const; + uint8_t* mutable_data() { return image_buffer_->data(); } + private: + // Reference for mutable access. + rtc::scoped_refptr image_buffer_; RTPVideoHeader rtp_video_header_; VideoCodecType codec_type_; uint16_t first_seq_num_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/generic_decoder.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/generic_decoder.cc index 50ecd8da8..79057926f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/generic_decoder.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/generic_decoder.cc @@ -13,6 +13,7 @@ #include #include +#include #include "api/video/video_timing.h" #include "modules/video_coding/include/video_error_codes.h" @@ -31,12 +32,18 @@ VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming* timing, : _clock(clock), _timing(timing), _timestampMap(kDecoderFrameMemoryLength), - _extra_decode_time("t", absl::nullopt) { + _extra_decode_time("t", absl::nullopt), + low_latency_renderer_enabled_("enabled", true), + low_latency_renderer_include_predecode_buffer_("include_predecode_buffer", + true) { ntp_offset_ = _clock->CurrentNtpInMilliseconds() - _clock->TimeInMilliseconds(); ParseFieldTrial({&_extra_decode_time}, field_trial::FindFullName("WebRTC-SlowDownDecoder")); + ParseFieldTrial({&low_latency_renderer_enabled_, + &low_latency_renderer_include_predecode_buffer_}, + field_trial::FindFullName("WebRTC-LowLatencyRenderer")); } VCMDecodedFrameCallback::~VCMDecodedFrameCallback() {} @@ -85,9 +92,11 @@ void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, // TODO(holmer): We should improve this so that we can handle multiple // callbacks from one call to Decode(). VCMFrameInformation* frameInfo; + int timestamp_map_size = 0; { MutexLock lock(&lock_); frameInfo = _timestampMap.Pop(decodedImage.timestamp()); + timestamp_map_size = _timestampMap.Size(); } if (frameInfo == NULL) { @@ -101,13 +110,30 @@ void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, decodedImage.set_packet_infos(frameInfo->packet_infos); decodedImage.set_rotation(frameInfo->rotation); - const Timestamp now = _clock->CurrentTime(); - RTC_DCHECK(frameInfo->decodeStart); - if (!decode_time_ms) { - decode_time_ms = (now - *frameInfo->decodeStart).ms(); + if (low_latency_renderer_enabled_ && frameInfo->playout_delay.min_ms == 0 && + frameInfo->playout_delay.max_ms > 0) { + absl::optional max_composition_delay_in_frames = + _timing->MaxCompositionDelayInFrames(); + if (max_composition_delay_in_frames) { + // Subtract frames that are in flight. + if (low_latency_renderer_include_predecode_buffer_) { + *max_composition_delay_in_frames -= timestamp_map_size; + *max_composition_delay_in_frames = + std::max(0, *max_composition_delay_in_frames); + } + decodedImage.set_max_composition_delay_in_frames( + max_composition_delay_in_frames); + } } - _timing->StopDecodeTimer(*decode_time_ms, now.ms()); - decodedImage.set_processing_time({*frameInfo->decodeStart, now}); + + RTC_DCHECK(frameInfo->decodeStart); + const Timestamp now = _clock->CurrentTime(); + const TimeDelta decode_time = decode_time_ms + ? TimeDelta::Millis(*decode_time_ms) + : now - *frameInfo->decodeStart; + _timing->StopDecodeTimer(decode_time.ms(), now.ms()); + decodedImage.set_processing_time( + {*frameInfo->decodeStart, *frameInfo->decodeStart + decode_time}); // Report timing information. TimingFrameInfo timing_frame_info; @@ -161,7 +187,7 @@ void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, decodedImage.set_timestamp_us(frameInfo->renderTimeMs * rtc::kNumMicrosecsPerMillisec); - _receiveCallback->FrameToRender(decodedImage, qp, *decode_time_ms, + _receiveCallback->FrameToRender(decodedImage, qp, decode_time.ms(), frameInfo->content_type); } @@ -223,6 +249,7 @@ int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, Timestamp now) { _frameInfos[_nextFrameInfoIdx].decodeStart = now; _frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs(); _frameInfos[_nextFrameInfoIdx].rotation = frame.rotation(); + _frameInfos[_nextFrameInfoIdx].playout_delay = frame.PlayoutDelay(); _frameInfos[_nextFrameInfoIdx].timing = frame.video_timing(); _frameInfos[_nextFrameInfoIdx].ntp_time_ms = frame.EncodedImage().ntp_time_ms_; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/generic_decoder.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/generic_decoder.h index b89d3f436..8481fdc15 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/generic_decoder.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/generic_decoder.h @@ -35,6 +35,7 @@ struct VCMFrameInformation { void* userData; VideoRotation rotation; VideoContentType content_type; + PlayoutDelay playout_delay; EncodedImage::Timing timing; int64_t ntp_time_ms; RtpPacketInfos packet_infos; @@ -75,6 +76,16 @@ class VCMDecodedFrameCallback : public DecodedImageCallback { int64_t ntp_offset_; // Set by the field trial WebRTC-SlowDownDecoder to simulate a slow decoder. FieldTrialOptional _extra_decode_time; + + // Set by the field trial WebRTC-LowLatencyRenderer. The parameter |enabled| + // determines if the low-latency renderer algorithm should be used for the + // case min playout delay=0 and max playout delay>0. + FieldTrialParameter low_latency_renderer_enabled_; + // Set by the field trial WebRTC-LowLatencyRenderer. The parameter + // |include_predecode_buffer| determines if the predecode buffer should be + // taken into account when calculating maximum number of frames in composition + // queue. + FieldTrialParameter low_latency_renderer_include_predecode_buffer_; }; class VCMGenericDecoder { diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/include/video_codec_interface.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/include/video_codec_interface.h index fbf6cefbd..c7834a272 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/include/video_codec_interface.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/include/video_codec_interface.h @@ -25,6 +25,7 @@ #endif #include "modules/video_coding/codecs/vp9/include/vp9_globals.h" #include "modules/video_coding/include/video_error_codes.h" +#include "rtc_base/deprecation.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { @@ -82,7 +83,7 @@ struct CodecSpecificInfoVP9 { uint8_t num_ref_pics; uint8_t p_diff[kMaxVp9RefPics]; - bool end_of_picture; + RTC_DEPRECATED bool end_of_picture; }; static_assert(std::is_pod::value, ""); @@ -123,6 +124,7 @@ struct RTC_EXPORT CodecSpecificInfo { VideoCodecType codecType; CodecSpecificInfoUnion codecSpecific; + bool end_of_picture = true; absl::optional generic_frame_info; absl::optional template_structure; }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/include/video_coding_defines.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/include/video_coding_defines.h index ff9b7d6a6..641e7121e 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/include/video_coding_defines.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/include/video_coding_defines.h @@ -41,9 +41,7 @@ enum { }; enum VCMVideoProtection { - kProtectionNone, kProtectionNack, - kProtectionFEC, kProtectionNackFEC, }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/jitter_buffer.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/jitter_buffer.cc index 9d2d3a2d1..772098a73 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/jitter_buffer.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/jitter_buffer.cc @@ -298,8 +298,7 @@ VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { last_decoded_state_.SetState(frame); DropPacketsFromNackList(last_decoded_state_.sequence_num()); - if ((*frame).IsSessionComplete()) - UpdateAveragePacketsPerFrame(frame->NumPackets()); + UpdateAveragePacketsPerFrame(frame->NumPackets()); return frame; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/packet_buffer.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/packet_buffer.h index 160d8c7c3..e34f7040b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/packet_buffer.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/packet_buffer.h @@ -82,9 +82,9 @@ class PacketBuffer { PacketBuffer(Clock* clock, size_t start_buffer_size, size_t max_buffer_size); ~PacketBuffer(); - InsertResult InsertPacket(std::unique_ptr packet) ABSL_MUST_USE_RESULT + ABSL_MUST_USE_RESULT InsertResult InsertPacket(std::unique_ptr packet) RTC_LOCKS_EXCLUDED(mutex_); - InsertResult InsertPadding(uint16_t seq_num) ABSL_MUST_USE_RESULT + ABSL_MUST_USE_RESULT InsertResult InsertPadding(uint16_t seq_num) RTC_LOCKS_EXCLUDED(mutex_); void ClearTo(uint16_t seq_num) RTC_LOCKS_EXCLUDED(mutex_); void Clear() RTC_LOCKS_EXCLUDED(mutex_); diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/receiver.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/receiver.cc index 2db4e211b..6b942fbe5 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/receiver.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/receiver.cc @@ -161,18 +161,6 @@ VCMEncodedFrame* VCMReceiver::FrameForDecoding(uint16_t max_wait_time_ms, frame->SetRenderTime(render_time_ms); TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame->Timestamp(), "SetRenderTS", "render_time", frame->RenderTimeMs()); - if (!frame->Complete()) { - // Update stats for incomplete frames. - bool retransmitted = false; - const int64_t last_packet_time_ms = - jitter_buffer_.LastPacketTime(frame, &retransmitted); - if (last_packet_time_ms >= 0 && !retransmitted) { - // We don't want to include timestamps which have suffered from - // retransmission here, since we compensate with extra retransmission - // delay within the jitter estimate. - timing_->IncomingTimestamp(frame_timestamp, last_packet_time_ms); - } - } return frame; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/create_scalability_structure.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/create_scalability_structure.cc similarity index 64% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/create_scalability_structure.cc rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/create_scalability_structure.cc index 17375547c..4b4a23ed2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/create_scalability_structure.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/create_scalability_structure.cc @@ -7,24 +7,23 @@ * 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/codecs/av1/create_scalability_structure.h" +#include "modules/video_coding/svc/create_scalability_structure.h" #include #include "absl/strings/string_view.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l1t2.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l1t3.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l2t1.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l2t1_key.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l2t1h.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l2t2.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l2t2_key.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l3t1.h" -#include "modules/video_coding/codecs/av1/scalability_structure_l3t3.h" -#include "modules/video_coding/codecs/av1/scalability_structure_s2t1.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller_no_layering.h" +#include "modules/video_coding/svc/scalability_structure_key_svc.h" +#include "modules/video_coding/svc/scalability_structure_l1t2.h" +#include "modules/video_coding/svc/scalability_structure_l1t3.h" +#include "modules/video_coding/svc/scalability_structure_l2t1.h" +#include "modules/video_coding/svc/scalability_structure_l2t1h.h" +#include "modules/video_coding/svc/scalability_structure_l2t2.h" +#include "modules/video_coding/svc/scalability_structure_l2t2_key_shift.h" +#include "modules/video_coding/svc/scalability_structure_l3t1.h" +#include "modules/video_coding/svc/scalability_structure_l3t3.h" +#include "modules/video_coding/svc/scalability_structure_s2t1.h" +#include "modules/video_coding/svc/scalable_video_controller.h" +#include "modules/video_coding/svc/scalable_video_controller_no_layering.h" #include "rtc_base/checks.h" namespace webrtc { @@ -54,6 +53,7 @@ constexpr NamedStructureFactory kFactories[] = { {"L2T2_KEY_SHIFT", Create}, {"L3T1", Create}, {"L3T3", Create}, + {"L3T3_KEY", Create}, {"S2T1", Create}, }; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/create_scalability_structure.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/create_scalability_structure.h similarity index 72% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/create_scalability_structure.h rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/create_scalability_structure.h index fe4a283ae..9a14221fd 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/create_scalability_structure.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/create_scalability_structure.h @@ -7,14 +7,14 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_CREATE_SCALABILITY_STRUCTURE_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_CREATE_SCALABILITY_STRUCTURE_H_ +#ifndef MODULES_VIDEO_CODING_SVC_CREATE_SCALABILITY_STRUCTURE_H_ +#define MODULES_VIDEO_CODING_SVC_CREATE_SCALABILITY_STRUCTURE_H_ #include #include #include "absl/strings/string_view.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" +#include "modules/video_coding/svc/scalable_video_controller.h" namespace webrtc { @@ -26,4 +26,4 @@ std::unique_ptr CreateScalabilityStructure( } // namespace webrtc -#endif // MODULES_VIDEO_CODING_CODECS_AV1_CREATE_SCALABILITY_STRUCTURE_H_ +#endif // MODULES_VIDEO_CODING_SVC_CREATE_SCALABILITY_STRUCTURE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.cc new file mode 100644 index 000000000..c489b6050 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.cc @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_full_svc.h" + +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "api/transport/rtp/dependency_descriptor.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace { +enum : int { kKey, kDelta }; +} // namespace + +constexpr int ScalabilityStructureFullSvc::kMaxNumSpatialLayers; +constexpr int ScalabilityStructureFullSvc::kMaxNumTemporalLayers; +constexpr absl::string_view ScalabilityStructureFullSvc::kFramePatternNames[]; + +ScalabilityStructureFullSvc::ScalabilityStructureFullSvc( + int num_spatial_layers, + int num_temporal_layers) + : num_spatial_layers_(num_spatial_layers), + num_temporal_layers_(num_temporal_layers), + active_decode_targets_( + (uint32_t{1} << (num_spatial_layers * num_temporal_layers)) - 1) { + RTC_DCHECK_LE(num_spatial_layers, kMaxNumSpatialLayers); + RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); +} + +ScalabilityStructureFullSvc::~ScalabilityStructureFullSvc() = default; + +ScalabilityStructureFullSvc::StreamLayersConfig +ScalabilityStructureFullSvc::StreamConfig() const { + StreamLayersConfig result; + result.num_spatial_layers = num_spatial_layers_; + result.num_temporal_layers = num_temporal_layers_; + result.scaling_factor_num[num_spatial_layers_ - 1] = 1; + result.scaling_factor_den[num_spatial_layers_ - 1] = 1; + for (int sid = num_spatial_layers_ - 1; sid > 0; --sid) { + result.scaling_factor_num[sid - 1] = 1; + result.scaling_factor_den[sid - 1] = 2 * result.scaling_factor_den[sid]; + } + return result; +} + +bool ScalabilityStructureFullSvc::TemporalLayerIsActive(int tid) const { + if (tid >= num_temporal_layers_) { + return false; + } + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (DecodeTargetIsActive(sid, tid)) { + return true; + } + } + return false; +} + +DecodeTargetIndication ScalabilityStructureFullSvc::Dti( + int sid, + int tid, + const LayerFrameConfig& config) { + if (sid < config.SpatialId() || tid < config.TemporalId()) { + return DecodeTargetIndication::kNotPresent; + } + if (sid == config.SpatialId()) { + if (tid == 0) { + RTC_DCHECK_EQ(config.TemporalId(), 0); + return DecodeTargetIndication::kSwitch; + } + if (tid == config.TemporalId()) { + return DecodeTargetIndication::kDiscardable; + } + if (tid > config.TemporalId()) { + RTC_DCHECK_GT(tid, config.TemporalId()); + return DecodeTargetIndication::kSwitch; + } + } + RTC_DCHECK_GT(sid, config.SpatialId()); + RTC_DCHECK_GE(tid, config.TemporalId()); + if (config.IsKeyframe() || config.Id() == kKey) { + return DecodeTargetIndication::kSwitch; + } + return DecodeTargetIndication::kRequired; +} + +ScalabilityStructureFullSvc::FramePattern +ScalabilityStructureFullSvc::NextPattern() const { + switch (last_pattern_) { + case kNone: + case kDeltaT2B: + return kDeltaT0; + case kDeltaT2A: + if (TemporalLayerIsActive(1)) { + return kDeltaT1; + } + return kDeltaT0; + case kDeltaT1: + if (TemporalLayerIsActive(2)) { + return kDeltaT2B; + } + return kDeltaT0; + case kDeltaT0: + if (TemporalLayerIsActive(2)) { + return kDeltaT2A; + } + if (TemporalLayerIsActive(1)) { + return kDeltaT1; + } + return kDeltaT0; + } +} + +std::vector +ScalabilityStructureFullSvc::NextFrameConfig(bool restart) { + std::vector configs; + if (active_decode_targets_.none()) { + last_pattern_ = kNone; + return configs; + } + configs.reserve(num_spatial_layers_); + + if (last_pattern_ == kNone || restart) { + can_reference_t0_frame_for_spatial_id_.reset(); + last_pattern_ = kNone; + } + FramePattern current_pattern = NextPattern(); + + absl::optional spatial_dependency_buffer_id; + switch (current_pattern) { + case kDeltaT0: + // Disallow temporal references cross T0 on higher temporal layers. + can_reference_t1_frame_for_spatial_id_.reset(); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (!DecodeTargetIsActive(sid, /*tid=*/0)) { + // Next frame from the spatial layer `sid` shouldn't depend on + // potentially old previous frame from the spatial layer `sid`. + can_reference_t0_frame_for_spatial_id_.reset(sid); + continue; + } + configs.emplace_back(); + ScalableVideoController::LayerFrameConfig& config = configs.back(); + config.Id(last_pattern_ == kNone ? kKey : kDelta).S(sid).T(0); + + if (spatial_dependency_buffer_id) { + config.Reference(*spatial_dependency_buffer_id); + } else if (last_pattern_ == kNone) { + config.Keyframe(); + } + + if (can_reference_t0_frame_for_spatial_id_[sid]) { + config.ReferenceAndUpdate(BufferIndex(sid, /*tid=*/0)); + } else { + // TODO(bugs.webrtc.org/11999): Propagate chain restart on delta frame + // to ChainDiffCalculator + config.Update(BufferIndex(sid, /*tid=*/0)); + } + + can_reference_t0_frame_for_spatial_id_.set(sid); + spatial_dependency_buffer_id = BufferIndex(sid, /*tid=*/0); + } + break; + case kDeltaT1: + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (!DecodeTargetIsActive(sid, /*tid=*/1) || + !can_reference_t0_frame_for_spatial_id_[sid]) { + continue; + } + configs.emplace_back(); + ScalableVideoController::LayerFrameConfig& config = configs.back(); + config.Id(kDelta).S(sid).T(1); + // Temporal reference. + config.Reference(BufferIndex(sid, /*tid=*/0)); + // Spatial reference unless this is the lowest active spatial layer. + if (spatial_dependency_buffer_id) { + config.Reference(*spatial_dependency_buffer_id); + } + // No frame reference top layer frame, so no need save it into a buffer. + if (num_temporal_layers_ > 2 || sid < num_spatial_layers_ - 1) { + config.Update(BufferIndex(sid, /*tid=*/1)); + can_reference_t1_frame_for_spatial_id_.set(sid); + } + spatial_dependency_buffer_id = BufferIndex(sid, /*tid=*/1); + } + break; + case kDeltaT2A: + case kDeltaT2B: + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (!DecodeTargetIsActive(sid, /*tid=*/2) || + !can_reference_t0_frame_for_spatial_id_[sid]) { + continue; + } + configs.emplace_back(); + ScalableVideoController::LayerFrameConfig& config = configs.back(); + config.Id(kDelta).S(sid).T(2); + // Temporal reference. + if (current_pattern == kDeltaT2B && + can_reference_t1_frame_for_spatial_id_[sid]) { + config.Reference(BufferIndex(sid, /*tid=*/1)); + } else { + config.Reference(BufferIndex(sid, /*tid=*/0)); + } + // Spatial reference unless this is the lowest active spatial layer. + if (spatial_dependency_buffer_id) { + config.Reference(*spatial_dependency_buffer_id); + } + // No frame reference top layer frame, so no need save it into a buffer. + if (sid < num_spatial_layers_ - 1) { + config.Update(BufferIndex(sid, /*tid=*/2)); + } + spatial_dependency_buffer_id = BufferIndex(sid, /*tid=*/2); + } + break; + case kNone: + RTC_NOTREACHED(); + break; + } + + if (configs.empty() && !restart) { + RTC_LOG(LS_WARNING) << "Failed to generate configuration for L" + << num_spatial_layers_ << "T" << num_temporal_layers_ + << " with active decode targets " + << active_decode_targets_.to_string('-').substr( + active_decode_targets_.size() - + num_spatial_layers_ * num_temporal_layers_) + << " and transition from " + << kFramePatternNames[last_pattern_] << " to " + << kFramePatternNames[current_pattern] + << ". Resetting."; + return NextFrameConfig(/*restart=*/true); + } + + last_pattern_ = current_pattern; + return configs; +} + +GenericFrameInfo ScalabilityStructureFullSvc::OnEncodeDone( + const LayerFrameConfig& config) { + GenericFrameInfo frame_info; + frame_info.spatial_id = config.SpatialId(); + frame_info.temporal_id = config.TemporalId(); + frame_info.encoder_buffers = config.Buffers(); + frame_info.decode_target_indications.reserve(num_spatial_layers_ * + num_temporal_layers_); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + for (int tid = 0; tid < num_temporal_layers_; ++tid) { + frame_info.decode_target_indications.push_back(Dti(sid, tid, config)); + } + } + if (config.TemporalId() == 0) { + frame_info.part_of_chain.resize(num_spatial_layers_); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + frame_info.part_of_chain[sid] = config.SpatialId() <= sid; + } + } else { + frame_info.part_of_chain.assign(num_spatial_layers_, false); + } + frame_info.active_decode_targets = active_decode_targets_; + return frame_info; +} + +void ScalabilityStructureFullSvc::OnRatesUpdated( + const VideoBitrateAllocation& bitrates) { + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + // Enable/disable spatial layers independetely. + bool active = true; + for (int tid = 0; tid < num_temporal_layers_; ++tid) { + // To enable temporal layer, require bitrates for lower temporal layers. + active = active && bitrates.GetBitrate(sid, tid) > 0; + SetDecodeTargetIsActive(sid, tid, active); + } + } +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.h new file mode 100644 index 000000000..d490d6e4a --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_full_svc.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_FULL_SVC_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_FULL_SVC_H_ + +#include +#include + +#include "api/transport/rtp/dependency_descriptor.h" +#include "common_video/generic_frame_descriptor/generic_frame_info.h" +#include "modules/video_coding/svc/scalable_video_controller.h" + +namespace webrtc { + +class ScalabilityStructureFullSvc : public ScalableVideoController { + public: + ScalabilityStructureFullSvc(int num_spatial_layers, int num_temporal_layers); + ~ScalabilityStructureFullSvc() override; + + StreamLayersConfig StreamConfig() const override; + + std::vector NextFrameConfig(bool restart) override; + GenericFrameInfo OnEncodeDone(const LayerFrameConfig& config) override; + void OnRatesUpdated(const VideoBitrateAllocation& bitrates) override; + + private: + enum FramePattern { + kNone, + kDeltaT2A, + kDeltaT1, + kDeltaT2B, + kDeltaT0, + }; + static constexpr absl::string_view kFramePatternNames[] = { + "None", "DeltaT2A", "DeltaT1", "DeltaT2B", "DeltaT0"}; + static constexpr int kMaxNumSpatialLayers = 3; + static constexpr int kMaxNumTemporalLayers = 3; + + // Index of the buffer to store last frame for layer (`sid`, `tid`) + int BufferIndex(int sid, int tid) const { + return tid * num_spatial_layers_ + sid; + } + bool DecodeTargetIsActive(int sid, int tid) const { + return active_decode_targets_[sid * num_temporal_layers_ + tid]; + } + void SetDecodeTargetIsActive(int sid, int tid, bool value) { + active_decode_targets_.set(sid * num_temporal_layers_ + tid, value); + } + FramePattern NextPattern() const; + bool TemporalLayerIsActive(int tid) const; + static DecodeTargetIndication Dti(int sid, + int tid, + const LayerFrameConfig& frame); + + const int num_spatial_layers_; + const int num_temporal_layers_; + + FramePattern last_pattern_ = kNone; + std::bitset can_reference_t0_frame_for_spatial_id_ = 0; + std::bitset can_reference_t1_frame_for_spatial_id_ = 0; + std::bitset<32> active_decode_targets_; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_FULL_SVC_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.cc new file mode 100644 index 000000000..cfc89a379 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.cc @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_key_svc.h" + +#include +#include +#include + +#include "absl/types/optional.h" +#include "api/transport/rtp/dependency_descriptor.h" +#include "api/video/video_bitrate_allocation.h" +#include "common_video/generic_frame_descriptor/generic_frame_info.h" +#include "modules/video_coding/svc/scalable_video_controller.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace { +// Values to use as LayerFrameConfig::Id +enum : int { kKey, kDelta }; + +DecodeTargetIndication +Dti(int sid, int tid, const ScalableVideoController::LayerFrameConfig& config) { + if (config.IsKeyframe() || config.Id() == kKey) { + RTC_DCHECK_EQ(config.TemporalId(), 0); + return sid < config.SpatialId() ? DecodeTargetIndication::kNotPresent + : DecodeTargetIndication::kSwitch; + } + + if (sid != config.SpatialId() || tid < config.TemporalId()) { + return DecodeTargetIndication::kNotPresent; + } + if (tid == config.TemporalId() && tid > 0) { + return DecodeTargetIndication::kDiscardable; + } + return DecodeTargetIndication::kSwitch; +} + +} // namespace + +constexpr int ScalabilityStructureKeySvc::kMaxNumSpatialLayers; +constexpr int ScalabilityStructureKeySvc::kMaxNumTemporalLayers; + +ScalabilityStructureKeySvc::ScalabilityStructureKeySvc(int num_spatial_layers, + int num_temporal_layers) + : num_spatial_layers_(num_spatial_layers), + num_temporal_layers_(num_temporal_layers), + active_decode_targets_( + (uint32_t{1} << (num_spatial_layers * num_temporal_layers)) - 1) { + // There is no point to use this structure without spatial scalability. + RTC_DCHECK_GT(num_spatial_layers, 1); + RTC_DCHECK_LE(num_spatial_layers, kMaxNumSpatialLayers); + RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); +} + +ScalabilityStructureKeySvc::~ScalabilityStructureKeySvc() = default; + +ScalableVideoController::StreamLayersConfig +ScalabilityStructureKeySvc::StreamConfig() const { + StreamLayersConfig result; + result.num_spatial_layers = num_spatial_layers_; + result.num_temporal_layers = num_temporal_layers_; + result.scaling_factor_num[num_spatial_layers_ - 1] = 1; + result.scaling_factor_den[num_spatial_layers_ - 1] = 1; + for (int sid = num_spatial_layers_ - 1; sid > 0; --sid) { + result.scaling_factor_num[sid - 1] = 1; + result.scaling_factor_den[sid - 1] = 2 * result.scaling_factor_den[sid]; + } + return result; +} + +bool ScalabilityStructureKeySvc::TemporalLayerIsActive(int tid) const { + if (tid >= num_temporal_layers_) { + return false; + } + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (DecodeTargetIsActive(sid, tid)) { + return true; + } + } + return false; +} + +std::vector +ScalabilityStructureKeySvc::KeyframeConfig() { + std::vector configs; + configs.reserve(num_spatial_layers_); + absl::optional spatial_dependency_buffer_id; + spatial_id_is_enabled_.reset(); + // Disallow temporal references cross T0 on higher temporal layers. + can_reference_t1_frame_for_spatial_id_.reset(); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (!DecodeTargetIsActive(sid, /*tid=*/0)) { + continue; + } + configs.emplace_back(); + ScalableVideoController::LayerFrameConfig& config = configs.back(); + config.Id(kKey).S(sid).T(0); + + if (spatial_dependency_buffer_id) { + config.Reference(*spatial_dependency_buffer_id); + } else { + config.Keyframe(); + } + config.Update(BufferIndex(sid, /*tid=*/0)); + + spatial_id_is_enabled_.set(sid); + spatial_dependency_buffer_id = BufferIndex(sid, /*tid=*/0); + } + return configs; +} + +std::vector +ScalabilityStructureKeySvc::T0Config() { + std::vector configs; + configs.reserve(num_spatial_layers_); + // Disallow temporal references cross T0 on higher temporal layers. + can_reference_t1_frame_for_spatial_id_.reset(); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (!DecodeTargetIsActive(sid, /*tid=*/0)) { + spatial_id_is_enabled_.reset(sid); + continue; + } + configs.emplace_back(); + configs.back().Id(kDelta).S(sid).T(0).ReferenceAndUpdate( + BufferIndex(sid, /*tid=*/0)); + } + return configs; +} + +std::vector +ScalabilityStructureKeySvc::T1Config() { + std::vector configs; + configs.reserve(num_spatial_layers_); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (!DecodeTargetIsActive(sid, /*tid=*/1)) { + continue; + } + configs.emplace_back(); + ScalableVideoController::LayerFrameConfig& config = configs.back(); + config.Id(kDelta).S(sid).T(1).Reference(BufferIndex(sid, /*tid=*/0)); + if (num_temporal_layers_ > 2) { + config.Update(BufferIndex(sid, /*tid=*/1)); + can_reference_t1_frame_for_spatial_id_.set(sid); + } + } + return configs; +} + +std::vector +ScalabilityStructureKeySvc::T2Config() { + std::vector configs; + configs.reserve(num_spatial_layers_); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + if (!DecodeTargetIsActive(sid, /*tid=*/2)) { + continue; + } + configs.emplace_back(); + ScalableVideoController::LayerFrameConfig& config = configs.back(); + config.Id(kDelta).S(sid).T(2); + if (can_reference_t1_frame_for_spatial_id_[sid]) { + config.Reference(BufferIndex(sid, /*tid=*/1)); + } else { + config.Reference(BufferIndex(sid, /*tid=*/0)); + } + } + return configs; +} + +std::vector +ScalabilityStructureKeySvc::NextFrameConfig(bool restart) { + if (active_decode_targets_.none()) { + last_pattern_ = kNone; + return {}; + } + + if (restart) { + last_pattern_ = kNone; + } + + switch (last_pattern_) { + case kNone: + last_pattern_ = kDeltaT0; + return KeyframeConfig(); + case kDeltaT2B: + last_pattern_ = kDeltaT0; + return T0Config(); + case kDeltaT2A: + if (TemporalLayerIsActive(1)) { + last_pattern_ = kDeltaT1; + return T1Config(); + } + last_pattern_ = kDeltaT0; + return T0Config(); + case kDeltaT1: + if (TemporalLayerIsActive(2)) { + last_pattern_ = kDeltaT2B; + return T2Config(); + } + last_pattern_ = kDeltaT0; + return T0Config(); + case kDeltaT0: + if (TemporalLayerIsActive(2)) { + last_pattern_ = kDeltaT2A; + return T2Config(); + } else if (TemporalLayerIsActive(1)) { + last_pattern_ = kDeltaT1; + return T1Config(); + } + last_pattern_ = kDeltaT0; + return T0Config(); + } + RTC_NOTREACHED(); + return {}; +} + +GenericFrameInfo ScalabilityStructureKeySvc::OnEncodeDone( + const LayerFrameConfig& config) { + GenericFrameInfo frame_info; + frame_info.spatial_id = config.SpatialId(); + frame_info.temporal_id = config.TemporalId(); + frame_info.encoder_buffers = config.Buffers(); + frame_info.decode_target_indications.reserve(num_spatial_layers_ * + num_temporal_layers_); + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + for (int tid = 0; tid < num_temporal_layers_; ++tid) { + frame_info.decode_target_indications.push_back(Dti(sid, tid, config)); + } + } + frame_info.part_of_chain.assign(num_spatial_layers_, false); + if (config.IsKeyframe() || config.Id() == kKey) { + RTC_DCHECK_EQ(config.TemporalId(), 0); + for (int sid = config.SpatialId(); sid < num_spatial_layers_; ++sid) { + frame_info.part_of_chain[sid] = true; + } + } else if (config.TemporalId() == 0) { + frame_info.part_of_chain[config.SpatialId()] = true; + } + frame_info.active_decode_targets = active_decode_targets_; + return frame_info; +} + +void ScalabilityStructureKeySvc::OnRatesUpdated( + const VideoBitrateAllocation& bitrates) { + for (int sid = 0; sid < num_spatial_layers_; ++sid) { + // Enable/disable spatial layers independetely. + bool active = bitrates.GetBitrate(sid, /*tid=*/0) > 0; + SetDecodeTargetIsActive(sid, /*tid=*/0, active); + if (!spatial_id_is_enabled_[sid] && active) { + // Key frame is required to reenable any spatial layer. + last_pattern_ = kNone; + } + + for (int tid = 1; tid < num_temporal_layers_; ++tid) { + // To enable temporal layer, require bitrates for lower temporal layers. + active = active && bitrates.GetBitrate(sid, tid) > 0; + SetDecodeTargetIsActive(sid, tid, active); + } + } +} + +ScalabilityStructureL2T1Key::~ScalabilityStructureL2T1Key() = default; + +FrameDependencyStructure ScalabilityStructureL2T1Key::DependencyStructure() + const { + FrameDependencyStructure structure; + structure.num_decode_targets = 2; + structure.num_chains = 2; + structure.decode_target_protected_by_chain = {0, 1}; + structure.templates.resize(4); + structure.templates[0].S(0).Dtis("S-").ChainDiffs({2, 1}).FrameDiffs({2}); + structure.templates[1].S(0).Dtis("SS").ChainDiffs({0, 0}); + structure.templates[2].S(1).Dtis("-S").ChainDiffs({1, 2}).FrameDiffs({2}); + structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 1}).FrameDiffs({1}); + return structure; +} + +ScalabilityStructureL2T2Key::~ScalabilityStructureL2T2Key() = default; + +FrameDependencyStructure ScalabilityStructureL2T2Key::DependencyStructure() + const { + FrameDependencyStructure structure; + structure.num_decode_targets = 4; + structure.num_chains = 2; + structure.decode_target_protected_by_chain = {0, 0, 1, 1}; + structure.templates.resize(6); + auto& templates = structure.templates; + templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}); + templates[1].S(0).T(0).Dtis("SS--").ChainDiffs({4, 3}).FrameDiffs({4}); + templates[2].S(0).T(1).Dtis("-D--").ChainDiffs({2, 1}).FrameDiffs({2}); + templates[3].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1}); + templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 4}).FrameDiffs({4}); + templates[5].S(1).T(1).Dtis("---D").ChainDiffs({3, 2}).FrameDiffs({2}); + return structure; +} + +ScalabilityStructureL3T3Key::~ScalabilityStructureL3T3Key() = default; + +FrameDependencyStructure ScalabilityStructureL3T3Key::DependencyStructure() + const { + FrameDependencyStructure structure; + structure.num_decode_targets = 9; + structure.num_chains = 3; + structure.decode_target_protected_by_chain = {0, 0, 0, 1, 1, 1, 2, 2, 2}; + auto& t = structure.templates; + t.resize(15); + // Templates are shown in the order frames following them appear in the + // stream, but in `structure.templates` array templates are sorted by + // (`spatial_id`, `temporal_id`) since that is a dependency descriptor + // requirement. Indexes are written in hex for nicer alignment. + t[0x0].S(0).T(0).Dtis("SSSSSSSSS").ChainDiffs({0, 0, 0}); + t[0x5].S(1).T(0).Dtis("---SSSSSS").ChainDiffs({1, 1, 1}).FrameDiffs({1}); + t[0xA].S(2).T(0).Dtis("------SSS").ChainDiffs({2, 1, 1}).FrameDiffs({1}); + t[0x3].S(0).T(2).Dtis("--D------").ChainDiffs({3, 2, 1}).FrameDiffs({3}); + t[0x8].S(1).T(2).Dtis("-----D---").ChainDiffs({4, 3, 2}).FrameDiffs({3}); + t[0xD].S(2).T(2).Dtis("--------D").ChainDiffs({5, 4, 3}).FrameDiffs({3}); + t[0x2].S(0).T(1).Dtis("-DS------").ChainDiffs({6, 5, 4}).FrameDiffs({6}); + t[0x7].S(1).T(1).Dtis("----DS---").ChainDiffs({7, 6, 5}).FrameDiffs({6}); + t[0xC].S(2).T(1).Dtis("-------DS").ChainDiffs({8, 7, 6}).FrameDiffs({6}); + t[0x4].S(0).T(2).Dtis("--D------").ChainDiffs({9, 8, 7}).FrameDiffs({3}); + t[0x9].S(1).T(2).Dtis("-----D---").ChainDiffs({10, 9, 8}).FrameDiffs({3}); + t[0xE].S(2).T(2).Dtis("--------D").ChainDiffs({11, 10, 9}).FrameDiffs({3}); + t[0x1].S(0).T(0).Dtis("SSS------").ChainDiffs({12, 11, 10}).FrameDiffs({12}); + t[0x6].S(1).T(0).Dtis("---SSS---").ChainDiffs({1, 12, 11}).FrameDiffs({12}); + t[0xB].S(2).T(0).Dtis("------SSS").ChainDiffs({2, 1, 12}).FrameDiffs({12}); + return structure; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.h new file mode 100644 index 000000000..1d3277b5c --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_key_svc.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_KEY_SVC_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_KEY_SVC_H_ + +#include +#include + +#include "api/transport/rtp/dependency_descriptor.h" +#include "api/video/video_bitrate_allocation.h" +#include "common_video/generic_frame_descriptor/generic_frame_info.h" +#include "modules/video_coding/svc/scalable_video_controller.h" + +namespace webrtc { + +class ScalabilityStructureKeySvc : public ScalableVideoController { + public: + ScalabilityStructureKeySvc(int num_spatial_layers, int num_temporal_layers); + ~ScalabilityStructureKeySvc() override; + + StreamLayersConfig StreamConfig() const override; + + std::vector NextFrameConfig(bool restart) override; + GenericFrameInfo OnEncodeDone(const LayerFrameConfig& config) override; + void OnRatesUpdated(const VideoBitrateAllocation& bitrates) override; + + private: + enum FramePattern { + kNone, + kDeltaT0, + kDeltaT2A, + kDeltaT1, + kDeltaT2B, + }; + static constexpr int kMaxNumSpatialLayers = 3; + static constexpr int kMaxNumTemporalLayers = 3; + + // Index of the buffer to store last frame for layer (`sid`, `tid`) + int BufferIndex(int sid, int tid) const { + return tid * num_spatial_layers_ + sid; + } + bool DecodeTargetIsActive(int sid, int tid) const { + return active_decode_targets_[sid * num_temporal_layers_ + tid]; + } + void SetDecodeTargetIsActive(int sid, int tid, bool value) { + active_decode_targets_.set(sid * num_temporal_layers_ + tid, value); + } + bool TemporalLayerIsActive(int tid) const; + std::vector KeyframeConfig(); + std::vector T0Config(); + std::vector T1Config(); + std::vector T2Config(); + + const int num_spatial_layers_; + const int num_temporal_layers_; + + FramePattern last_pattern_ = kNone; + std::bitset spatial_id_is_enabled_; + std::bitset can_reference_t1_frame_for_spatial_id_; + std::bitset<32> active_decode_targets_; +}; + +// S1 0--0--0- +// | ... +// S0 0--0--0- +class ScalabilityStructureL2T1Key : public ScalabilityStructureKeySvc { + public: + ScalabilityStructureL2T1Key() : ScalabilityStructureKeySvc(2, 1) {} + ~ScalabilityStructureL2T1Key() override; + + FrameDependencyStructure DependencyStructure() const override; +}; + +// S1T1 0 0 +// / / / +// S1T0 0---0---0 +// | ... +// S0T1 | 0 0 +// |/ / / +// S0T0 0---0---0 +// Time-> 0 1 2 3 4 +class ScalabilityStructureL2T2Key : public ScalabilityStructureKeySvc { + public: + ScalabilityStructureL2T2Key() : ScalabilityStructureKeySvc(2, 2) {} + ~ScalabilityStructureL2T2Key() override; + + FrameDependencyStructure DependencyStructure() const override; +}; + +class ScalabilityStructureL3T3Key : public ScalabilityStructureKeySvc { + public: + ScalabilityStructureL3T3Key() : ScalabilityStructureKeySvc(3, 3) {} + ~ScalabilityStructureL3T3Key() override; + + FrameDependencyStructure DependencyStructure() const override; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_KEY_SVC_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.cc new file mode 100644 index 000000000..f639e2da6 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.cc @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_l1t2.h" + +#include + +#include "api/transport/rtp/dependency_descriptor.h" + +namespace webrtc { + +ScalabilityStructureL1T2::~ScalabilityStructureL1T2() = default; + +FrameDependencyStructure ScalabilityStructureL1T2::DependencyStructure() const { + FrameDependencyStructure structure; + structure.num_decode_targets = 2; + structure.num_chains = 1; + structure.decode_target_protected_by_chain = {0, 0}; + structure.templates.resize(3); + structure.templates[0].T(0).Dtis("SS").ChainDiffs({0}); + structure.templates[1].T(0).Dtis("SS").ChainDiffs({2}).FrameDiffs({2}); + structure.templates[2].T(1).Dtis("-D").ChainDiffs({1}).FrameDiffs({1}); + return structure; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.h new file mode 100644 index 000000000..d2f81aa11 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t2.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L1T2_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L1T2_H_ + +#include "api/transport/rtp/dependency_descriptor.h" +#include "modules/video_coding/svc/scalability_structure_full_svc.h" + +namespace webrtc { + +class ScalabilityStructureL1T2 : public ScalabilityStructureFullSvc { + public: + ScalabilityStructureL1T2() : ScalabilityStructureFullSvc(1, 2) {} + ~ScalabilityStructureL1T2() override; + + FrameDependencyStructure DependencyStructure() const override; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L1T2_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.cc new file mode 100644 index 000000000..17073344c --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.cc @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_l1t3.h" + +#include + +#include "api/transport/rtp/dependency_descriptor.h" + +namespace webrtc { + +ScalabilityStructureL1T3::~ScalabilityStructureL1T3() = default; + +FrameDependencyStructure ScalabilityStructureL1T3::DependencyStructure() const { + FrameDependencyStructure structure; + structure.num_decode_targets = 3; + structure.num_chains = 1; + structure.decode_target_protected_by_chain = {0, 0, 0}; + structure.templates.resize(5); + structure.templates[0].T(0).Dtis("SSS").ChainDiffs({0}); + structure.templates[1].T(0).Dtis("SSS").ChainDiffs({4}).FrameDiffs({4}); + structure.templates[2].T(1).Dtis("-DS").ChainDiffs({2}).FrameDiffs({2}); + structure.templates[3].T(2).Dtis("--D").ChainDiffs({1}).FrameDiffs({1}); + structure.templates[4].T(2).Dtis("--D").ChainDiffs({3}).FrameDiffs({1}); + return structure; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.h new file mode 100644 index 000000000..00e48ccc4 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l1t3.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L1T3_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L1T3_H_ + +#include "api/transport/rtp/dependency_descriptor.h" +#include "modules/video_coding/svc/scalability_structure_full_svc.h" + +namespace webrtc { + +// T2 0 0 0 0 +// | / | / +// T1 / 0 / 0 ... +// |_/ |_/ +// T0 0-------0------ +// Time-> 0 1 2 3 4 5 6 7 +class ScalabilityStructureL1T3 : public ScalabilityStructureFullSvc { + public: + ScalabilityStructureL1T3() : ScalabilityStructureFullSvc(1, 3) {} + ~ScalabilityStructureL1T3() override; + + FrameDependencyStructure DependencyStructure() const override; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L1T3_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.cc new file mode 100644 index 000000000..efd751665 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.cc @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_l2t1.h" + +#include + +#include "api/transport/rtp/dependency_descriptor.h" + +namespace webrtc { + +ScalabilityStructureL2T1::~ScalabilityStructureL2T1() = default; + +FrameDependencyStructure ScalabilityStructureL2T1::DependencyStructure() const { + FrameDependencyStructure structure; + structure.num_decode_targets = 2; + structure.num_chains = 2; + structure.decode_target_protected_by_chain = {0, 1}; + structure.templates.resize(4); + structure.templates[0].S(0).Dtis("SR").ChainDiffs({2, 1}).FrameDiffs({2}); + structure.templates[1].S(0).Dtis("SS").ChainDiffs({0, 0}); + structure.templates[2].S(1).Dtis("-S").ChainDiffs({1, 1}).FrameDiffs({2, 1}); + structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 1}).FrameDiffs({1}); + return structure; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.h new file mode 100644 index 000000000..96a0da56d --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T1_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T1_H_ + +#include "api/transport/rtp/dependency_descriptor.h" +#include "modules/video_coding/svc/scalability_structure_full_svc.h" + +namespace webrtc { + +// S1 0--0--0- +// | | | ... +// S0 0--0--0- +class ScalabilityStructureL2T1 : public ScalabilityStructureFullSvc { + public: + ScalabilityStructureL2T1() : ScalabilityStructureFullSvc(2, 1) {} + ~ScalabilityStructureL2T1() override; + + FrameDependencyStructure DependencyStructure() const override; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T1_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1h.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1h.cc similarity index 93% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1h.cc rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1h.cc index 7b05c92cf..c4682764a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1h.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1h.cc @@ -7,7 +7,7 @@ * 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/codecs/av1/scalability_structure_l2t1h.h" +#include "modules/video_coding/svc/scalability_structure_l2t1h.h" #include #include diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1h.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1h.h similarity index 63% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1h.h rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1h.h index ec419d9c3..7200a1084 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t1h.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t1h.h @@ -7,11 +7,11 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1H_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1H_H_ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T1H_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T1H_H_ -#include "modules/video_coding/codecs/av1/scalability_structure_l2t1.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" +#include "modules/video_coding/svc/scalability_structure_l2t1.h" +#include "modules/video_coding/svc/scalable_video_controller.h" namespace webrtc { @@ -24,4 +24,4 @@ class ScalabilityStructureL2T1h : public ScalabilityStructureL2T1 { } // namespace webrtc -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T1H_H_ +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T1H_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.cc new file mode 100644 index 000000000..a381ad080 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.cc @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_l2t2.h" + +#include + +#include "api/transport/rtp/dependency_descriptor.h" + +namespace webrtc { + +ScalabilityStructureL2T2::~ScalabilityStructureL2T2() = default; + +FrameDependencyStructure ScalabilityStructureL2T2::DependencyStructure() const { + FrameDependencyStructure structure; + structure.num_decode_targets = 4; + structure.num_chains = 2; + structure.decode_target_protected_by_chain = {0, 0, 1, 1}; + structure.templates.resize(6); + auto& templates = structure.templates; + templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}); + templates[1].S(0).T(0).Dtis("SSRR").ChainDiffs({4, 3}).FrameDiffs({4}); + templates[2].S(0).T(1).Dtis("-D-R").ChainDiffs({2, 1}).FrameDiffs({2}); + templates[3].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1}); + templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({4, 1}); + templates[5].S(1).T(1).Dtis("---D").ChainDiffs({3, 2}).FrameDiffs({2, 1}); + return structure; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.h new file mode 100644 index 000000000..781ea7e60 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T2_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T2_H_ + +#include "api/transport/rtp/dependency_descriptor.h" +#include "modules/video_coding/svc/scalability_structure_full_svc.h" + +namespace webrtc { + +// S1T1 0 0 +// /| /| / +// S1T0 0-+-0-+-0 +// | | | | | ... +// S0T1 | 0 | 0 | +// |/ |/ |/ +// S0T0 0---0---0-- +// Time-> 0 1 2 3 4 +class ScalabilityStructureL2T2 : public ScalabilityStructureFullSvc { + public: + ScalabilityStructureL2T2() : ScalabilityStructureFullSvc(2, 2) {} + ~ScalabilityStructureL2T2() override; + + FrameDependencyStructure DependencyStructure() const override; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T2_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2_key_shift.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2_key_shift.cc new file mode 100644 index 000000000..c53ff8f07 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2_key_shift.cc @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_l2t2_key_shift.h" + +#include +#include + +#include "absl/base/macros.h" +#include "api/transport/rtp/dependency_descriptor.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace { + +DecodeTargetIndication +Dti(int sid, int tid, const ScalableVideoController::LayerFrameConfig& config) { + if (config.IsKeyframe()) { + RTC_DCHECK_EQ(config.TemporalId(), 0); + return sid < config.SpatialId() ? DecodeTargetIndication::kNotPresent + : DecodeTargetIndication::kSwitch; + } + + if (sid != config.SpatialId() || tid < config.TemporalId()) { + return DecodeTargetIndication::kNotPresent; + } + if (tid == config.TemporalId() && tid > 0) { + return DecodeTargetIndication::kDiscardable; + } + return DecodeTargetIndication::kSwitch; +} + +} // namespace + +constexpr int ScalabilityStructureL2T2KeyShift::kNumSpatialLayers; +constexpr int ScalabilityStructureL2T2KeyShift::kNumTemporalLayers; + +ScalabilityStructureL2T2KeyShift::~ScalabilityStructureL2T2KeyShift() = default; + +ScalableVideoController::StreamLayersConfig +ScalabilityStructureL2T2KeyShift::StreamConfig() const { + StreamLayersConfig result; + result.num_spatial_layers = 2; + result.num_temporal_layers = 2; + result.scaling_factor_num[0] = 1; + result.scaling_factor_den[0] = 2; + return result; +} + +FrameDependencyStructure ScalabilityStructureL2T2KeyShift::DependencyStructure() + const { + FrameDependencyStructure structure; + structure.num_decode_targets = 4; + structure.num_chains = 2; + structure.decode_target_protected_by_chain = {0, 0, 1, 1}; + structure.templates.resize(7); + auto& templates = structure.templates; + templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}); + templates[1].S(0).T(0).Dtis("SS--").ChainDiffs({2, 1}).FrameDiffs({2}); + templates[2].S(0).T(0).Dtis("SS--").ChainDiffs({4, 1}).FrameDiffs({4}); + templates[3].S(0).T(1).Dtis("-D--").ChainDiffs({2, 3}).FrameDiffs({2}); + templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1}); + templates[5].S(1).T(0).Dtis("--SS").ChainDiffs({3, 4}).FrameDiffs({4}); + templates[6].S(1).T(1).Dtis("---D").ChainDiffs({1, 2}).FrameDiffs({2}); + return structure; +} + +std::vector +ScalabilityStructureL2T2KeyShift::NextFrameConfig(bool restart) { + std::vector configs; + configs.reserve(2); + if (restart) { + next_pattern_ = kKey; + } + + // Buffer0 keeps latest S0T0 frame, + // Buffer1 keeps latest S1T0 frame. + switch (next_pattern_) { + case kKey: + if (DecodeTargetIsActive(/*sid=*/0, /*tid=*/0)) { + configs.emplace_back(); + configs.back().S(0).T(0).Update(0).Keyframe(); + } + if (DecodeTargetIsActive(/*sid=*/1, /*tid=*/0)) { + configs.emplace_back(); + configs.back().S(1).T(0).Update(1); + if (DecodeTargetIsActive(/*sid=*/0, /*tid=*/0)) { + configs.back().Reference(0); + } else { + configs.back().Keyframe(); + } + } + next_pattern_ = kDelta0; + break; + case kDelta0: + if (DecodeTargetIsActive(/*sid=*/0, /*tid=*/0)) { + configs.emplace_back(); + configs.back().S(0).T(0).ReferenceAndUpdate(0); + } + if (DecodeTargetIsActive(/*sid=*/1, /*tid=*/1)) { + configs.emplace_back(); + configs.back().S(1).T(1).Reference(1); + } + if (configs.empty() && DecodeTargetIsActive(/*sid=*/1, /*tid=*/0)) { + configs.emplace_back(); + configs.back().S(1).T(0).ReferenceAndUpdate(1); + } + next_pattern_ = kDelta1; + break; + case kDelta1: + if (DecodeTargetIsActive(/*sid=*/0, /*tid=*/1)) { + configs.emplace_back(); + configs.back().S(0).T(1).Reference(0); + } + if (DecodeTargetIsActive(/*sid=*/1, /*tid=*/0)) { + configs.emplace_back(); + configs.back().S(1).T(0).ReferenceAndUpdate(1); + } + if (configs.empty() && DecodeTargetIsActive(/*sid=*/0, /*tid=*/0)) { + configs.emplace_back(); + configs.back().S(0).T(0).ReferenceAndUpdate(0); + } + next_pattern_ = kDelta0; + break; + } + + RTC_DCHECK(!configs.empty() || active_decode_targets_.none()); + return configs; +} + +GenericFrameInfo ScalabilityStructureL2T2KeyShift::OnEncodeDone( + const LayerFrameConfig& config) { + GenericFrameInfo frame_info; + frame_info.spatial_id = config.SpatialId(); + frame_info.temporal_id = config.TemporalId(); + frame_info.encoder_buffers = config.Buffers(); + for (int sid = 0; sid < kNumSpatialLayers; ++sid) { + for (int tid = 0; tid < kNumTemporalLayers; ++tid) { + frame_info.decode_target_indications.push_back(Dti(sid, tid, config)); + } + } + if (config.IsKeyframe()) { + frame_info.part_of_chain = {true, true}; + } else if (config.TemporalId() == 0) { + frame_info.part_of_chain = {config.SpatialId() == 0, + config.SpatialId() == 1}; + } else { + frame_info.part_of_chain = {false, false}; + } + return frame_info; +} + +void ScalabilityStructureL2T2KeyShift::OnRatesUpdated( + const VideoBitrateAllocation& bitrates) { + for (int sid = 0; sid < kNumSpatialLayers; ++sid) { + // Enable/disable spatial layers independetely. + bool active = bitrates.GetBitrate(sid, /*tid=*/0) > 0; + if (!DecodeTargetIsActive(sid, /*tid=*/0) && active) { + // Key frame is required to reenable any spatial layer. + next_pattern_ = kKey; + } + + SetDecodeTargetIsActive(sid, /*tid=*/0, active); + SetDecodeTargetIsActive(sid, /*tid=*/1, + active && bitrates.GetBitrate(sid, /*tid=*/1) > 0); + } +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2_key_shift.h similarity index 57% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.h rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2_key_shift.h index 1b18bd7c1..26d1afcb2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l2t2_key_shift.h @@ -7,14 +7,15 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_KEY_SHIFT_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_KEY_SHIFT_H_ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T2_KEY_SHIFT_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T2_KEY_SHIFT_H_ #include #include "api/transport/rtp/dependency_descriptor.h" +#include "api/video/video_bitrate_allocation.h" #include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" +#include "modules/video_coding/svc/scalable_video_controller.h" namespace webrtc { @@ -34,8 +35,8 @@ class ScalabilityStructureL2T2KeyShift : public ScalableVideoController { FrameDependencyStructure DependencyStructure() const override; std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; + GenericFrameInfo OnEncodeDone(const LayerFrameConfig& config) override; + void OnRatesUpdated(const VideoBitrateAllocation& bitrates) override; private: enum FramePattern { @@ -43,11 +44,21 @@ class ScalabilityStructureL2T2KeyShift : public ScalableVideoController { kDelta0, kDelta1, }; - LayerFrameConfig KeyFrameConfig() const; + + static constexpr int kNumSpatialLayers = 2; + static constexpr int kNumTemporalLayers = 2; + + bool DecodeTargetIsActive(int sid, int tid) const { + return active_decode_targets_[sid * kNumTemporalLayers + tid]; + } + void SetDecodeTargetIsActive(int sid, int tid, bool value) { + active_decode_targets_.set(sid * kNumTemporalLayers + tid, value); + } FramePattern next_pattern_ = kKey; + std::bitset<32> active_decode_targets_ = 0b1111; }; } // namespace webrtc -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L2T2_KEY_SHIFT_H_ +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L2T2_KEY_SHIFT_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t1.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t1.cc new file mode 100644 index 000000000..d7a532446 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t1.cc @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_l3t1.h" + +#include + +#include "api/transport/rtp/dependency_descriptor.h" + +namespace webrtc { + +ScalabilityStructureL3T1::~ScalabilityStructureL3T1() = default; + +FrameDependencyStructure ScalabilityStructureL3T1::DependencyStructure() const { + FrameDependencyStructure structure; + structure.num_decode_targets = 3; + structure.num_chains = 3; + structure.decode_target_protected_by_chain = {0, 1, 2}; + auto& templates = structure.templates; + templates.resize(6); + templates[0].S(0).Dtis("SRR").ChainDiffs({3, 2, 1}).FrameDiffs({3}); + templates[1].S(0).Dtis("SSS").ChainDiffs({0, 0, 0}); + templates[2].S(1).Dtis("-SR").ChainDiffs({1, 1, 1}).FrameDiffs({3, 1}); + templates[3].S(1).Dtis("-SS").ChainDiffs({1, 1, 1}).FrameDiffs({1}); + templates[4].S(2).Dtis("--S").ChainDiffs({2, 1, 1}).FrameDiffs({3, 1}); + templates[5].S(2).Dtis("--S").ChainDiffs({2, 1, 1}).FrameDiffs({1}); + return structure; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t1.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t1.h similarity index 50% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t1.h rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t1.h index 404860d08..dea40e96b 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_l3t1.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t1.h @@ -7,15 +7,11 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L3T1_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L3T1_H_ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L3T1_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L3T1_H_ -#include - -#include "absl/types/optional.h" #include "api/transport/rtp/dependency_descriptor.h" -#include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" +#include "modules/video_coding/svc/scalability_structure_full_svc.h" namespace webrtc { @@ -25,21 +21,14 @@ namespace webrtc { // | | | // S0 0-0-0- // Time-> 0 1 2 -class ScalabilityStructureL3T1 : public ScalableVideoController { +class ScalabilityStructureL3T1 : public ScalabilityStructureFullSvc { public: + ScalabilityStructureL3T1() : ScalabilityStructureFullSvc(3, 1) {} ~ScalabilityStructureL3T1() override; - StreamLayersConfig StreamConfig() const override; FrameDependencyStructure DependencyStructure() const override; - - std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; - - private: - bool keyframe_ = true; }; } // namespace webrtc -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_L3T1_H_ +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L3T1_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.cc new file mode 100644 index 000000000..932056b0d --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.cc @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_l3t3.h" + +#include + +#include "api/transport/rtp/dependency_descriptor.h" + +namespace webrtc { + +ScalabilityStructureL3T3::~ScalabilityStructureL3T3() = default; + +FrameDependencyStructure ScalabilityStructureL3T3::DependencyStructure() const { + FrameDependencyStructure structure; + structure.num_decode_targets = 9; + structure.num_chains = 3; + structure.decode_target_protected_by_chain = {0, 0, 0, 1, 1, 1, 2, 2, 2}; + auto& t = structure.templates; + t.resize(15); + // Templates are shown in the order frames following them appear in the + // stream, but in `structure.templates` array templates are sorted by + // (`spatial_id`, `temporal_id`) since that is a dependency descriptor + // requirement. Indexes are written in hex for nicer alignment. + t[0x1].S(0).T(0).Dtis("SSSSSSSSS").ChainDiffs({0, 0, 0}); + t[0x6].S(1).T(0).Dtis("---SSSSSS").ChainDiffs({1, 1, 1}).FrameDiffs({1}); + t[0xB].S(2).T(0).Dtis("------SSS").ChainDiffs({2, 1, 1}).FrameDiffs({1}); + t[0x3].S(0).T(2).Dtis("--D--R--R").ChainDiffs({3, 2, 1}).FrameDiffs({3}); + t[0x8].S(1).T(2).Dtis("-----D--R").ChainDiffs({4, 3, 2}).FrameDiffs({3, 1}); + t[0xD].S(2).T(2).Dtis("--------D").ChainDiffs({5, 4, 3}).FrameDiffs({3, 1}); + t[0x2].S(0).T(1).Dtis("-DS-RR-RR").ChainDiffs({6, 5, 4}).FrameDiffs({6}); + t[0x7].S(1).T(1).Dtis("----DS-RR").ChainDiffs({7, 6, 5}).FrameDiffs({6, 1}); + t[0xC].S(2).T(1).Dtis("-------DS").ChainDiffs({8, 7, 6}).FrameDiffs({6, 1}); + t[0x4].S(0).T(2).Dtis("--D--R--R").ChainDiffs({9, 8, 7}).FrameDiffs({3}); + t[0x9].S(1).T(2).Dtis("-----D--R").ChainDiffs({10, 9, 8}).FrameDiffs({3, 1}); + t[0xE].S(2).T(2).Dtis("--------D").ChainDiffs({11, 10, 9}).FrameDiffs({3, 1}); + t[0x0].S(0).T(0).Dtis("SSSRRRRRR").ChainDiffs({12, 11, 10}).FrameDiffs({12}); + t[0x5].S(1).T(0).Dtis("---SSSRRR").ChainDiffs({1, 1, 1}).FrameDiffs({12, 1}); + t[0xA].S(2).T(0).Dtis("------SSS").ChainDiffs({2, 1, 1}).FrameDiffs({12, 1}); + return structure; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.h new file mode 100644 index 000000000..3f42726cc --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_l3t3.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L3T3_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L3T3_H_ + +#include "api/transport/rtp/dependency_descriptor.h" +#include "modules/video_coding/svc/scalability_structure_full_svc.h" + +namespace webrtc { + +// https://aomediacodec.github.io/av1-rtp-spec/#a63-l3t3-full-svc +class ScalabilityStructureL3T3 : public ScalabilityStructureFullSvc { + public: + ScalabilityStructureL3T3() : ScalabilityStructureFullSvc(3, 3) {} + ~ScalabilityStructureL3T3() override; + + FrameDependencyStructure DependencyStructure() const override; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_L3T3_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_s2t1.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_s2t1.cc new file mode 100644 index 000000000..618deb4b3 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_s2t1.cc @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_s2t1.h" + +#include +#include + +#include "absl/base/macros.h" +#include "api/transport/rtp/dependency_descriptor.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { + +constexpr int ScalabilityStructureS2T1::kNumSpatialLayers; + +ScalabilityStructureS2T1::~ScalabilityStructureS2T1() = default; + +ScalableVideoController::StreamLayersConfig +ScalabilityStructureS2T1::StreamConfig() const { + StreamLayersConfig result; + result.num_spatial_layers = kNumSpatialLayers; + result.num_temporal_layers = 1; + result.scaling_factor_num[0] = 1; + result.scaling_factor_den[0] = 2; + return result; +} + +FrameDependencyStructure ScalabilityStructureS2T1::DependencyStructure() const { + FrameDependencyStructure structure; + structure.num_decode_targets = kNumSpatialLayers; + structure.num_chains = kNumSpatialLayers; + structure.decode_target_protected_by_chain = {0, 1}; + structure.templates.resize(4); + structure.templates[0].S(0).Dtis("S-").ChainDiffs({2, 1}).FrameDiffs({2}); + structure.templates[1].S(0).Dtis("S-").ChainDiffs({0, 0}); + structure.templates[2].S(1).Dtis("-S").ChainDiffs({1, 2}).FrameDiffs({2}); + structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 0}); + return structure; +} + +std::vector +ScalabilityStructureS2T1::NextFrameConfig(bool restart) { + if (restart) { + can_reference_frame_for_spatial_id_.reset(); + } + std::vector configs; + configs.reserve(kNumSpatialLayers); + for (int sid = 0; sid < kNumSpatialLayers; ++sid) { + if (!active_decode_targets_[sid]) { + can_reference_frame_for_spatial_id_.reset(sid); + continue; + } + configs.emplace_back(); + LayerFrameConfig& config = configs.back().S(sid); + if (can_reference_frame_for_spatial_id_[sid]) { + config.ReferenceAndUpdate(sid); + } else { + config.Keyframe().Update(sid); + can_reference_frame_for_spatial_id_.set(sid); + } + } + + return configs; +} + +GenericFrameInfo ScalabilityStructureS2T1::OnEncodeDone( + const LayerFrameConfig& config) { + GenericFrameInfo frame_info; + frame_info.spatial_id = config.SpatialId(); + frame_info.temporal_id = config.TemporalId(); + frame_info.encoder_buffers = config.Buffers(); + frame_info.decode_target_indications = { + config.SpatialId() == 0 ? DecodeTargetIndication::kSwitch + : DecodeTargetIndication::kNotPresent, + config.SpatialId() == 1 ? DecodeTargetIndication::kSwitch + : DecodeTargetIndication::kNotPresent, + }; + frame_info.part_of_chain = {config.SpatialId() == 0, config.SpatialId() == 1}; + frame_info.active_decode_targets = active_decode_targets_; + return frame_info; +} + +void ScalabilityStructureS2T1::OnRatesUpdated( + const VideoBitrateAllocation& bitrates) { + active_decode_targets_.set(0, bitrates.GetBitrate(/*sid=*/0, /*tid=*/0) > 0); + active_decode_targets_.set(1, bitrates.GetBitrate(/*sid=*/1, /*tid=*/0) > 0); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_s2t1.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_s2t1.h similarity index 61% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_s2t1.h rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_s2t1.h index 06a99775c..0f27e480f 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalability_structure_s2t1.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_s2t1.h @@ -7,14 +7,15 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_S2T1_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_S2T1_H_ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_S2T1_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_S2T1_H_ #include #include "api/transport/rtp/dependency_descriptor.h" +#include "api/video/video_bitrate_allocation.h" #include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" +#include "modules/video_coding/svc/scalable_video_controller.h" namespace webrtc { @@ -29,13 +30,16 @@ class ScalabilityStructureS2T1 : public ScalableVideoController { FrameDependencyStructure DependencyStructure() const override; std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; + GenericFrameInfo OnEncodeDone(const LayerFrameConfig& config) override; + void OnRatesUpdated(const VideoBitrateAllocation& bitrates) override; private: - bool keyframe_ = true; + static constexpr int kNumSpatialLayers = 2; + + std::bitset can_reference_frame_for_spatial_id_; + std::bitset<32> active_decode_targets_ = 0b11; }; } // namespace webrtc -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABILITY_STRUCTURE_S2T1_H_ +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_S2T1_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_test_helpers.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_test_helpers.cc new file mode 100644 index 000000000..2b0393f9c --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_test_helpers.cc @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2020 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/svc/scalability_structure_test_helpers.h" + +#include + +#include +#include + +#include "api/array_view.h" +#include "api/transport/rtp/dependency_descriptor.h" +#include "api/video/video_bitrate_allocation.h" +#include "api/video/video_frame_type.h" +#include "modules/video_coding/chain_diff_calculator.h" +#include "modules/video_coding/frame_dependencies_calculator.h" +#include "modules/video_coding/svc/scalable_video_controller.h" +#include "test/gtest.h" + +namespace webrtc { + +VideoBitrateAllocation EnableTemporalLayers(int s0, int s1, int s2) { + VideoBitrateAllocation bitrate; + for (int tid = 0; tid < s0; ++tid) { + bitrate.SetBitrate(0, tid, 1'000'000); + } + for (int tid = 0; tid < s1; ++tid) { + bitrate.SetBitrate(1, tid, 1'000'000); + } + for (int tid = 0; tid < s2; ++tid) { + bitrate.SetBitrate(2, tid, 1'000'000); + } + return bitrate; +} + +void ScalabilityStructureWrapper::GenerateFrames( + int num_temporal_units, + std::vector& frames) { + for (int i = 0; i < num_temporal_units; ++i) { + for (auto& layer_frame : + structure_controller_.NextFrameConfig(/*restart=*/false)) { + int64_t frame_id = ++frame_id_; + bool is_keyframe = layer_frame.IsKeyframe(); + + GenericFrameInfo frame_info = + structure_controller_.OnEncodeDone(layer_frame); + if (is_keyframe) { + chain_diff_calculator_.Reset(frame_info.part_of_chain); + } + frame_info.chain_diffs = + chain_diff_calculator_.From(frame_id, frame_info.part_of_chain); + for (int64_t base_frame_id : frame_deps_calculator_.FromBuffersUsage( + is_keyframe ? VideoFrameType::kVideoFrameKey + : VideoFrameType::kVideoFrameDelta, + frame_id, frame_info.encoder_buffers)) { + frame_info.frame_diffs.push_back(frame_id - base_frame_id); + } + + frames.push_back(std::move(frame_info)); + } + } +} + +bool ScalabilityStructureWrapper::FrameReferencesAreValid( + rtc::ArrayView frames) const { + bool valid = true; + // VP9 and AV1 supports up to 8 buffers. Expect no more buffers are not used. + std::bitset<8> buffer_contains_frame; + for (size_t i = 0; i < frames.size(); ++i) { + const GenericFrameInfo& frame = frames[i]; + for (const CodecBufferUsage& buffer_usage : frame.encoder_buffers) { + if (buffer_usage.id < 0 || buffer_usage.id >= 8) { + ADD_FAILURE() << "Invalid buffer id " << buffer_usage.id + << " for frame#" << i + << ". Up to 8 buffers are supported."; + valid = false; + continue; + } + if (buffer_usage.referenced && !buffer_contains_frame[buffer_usage.id]) { + ADD_FAILURE() << "buffer " << buffer_usage.id << " for frame#" << i + << " was reference before updated."; + valid = false; + } + if (buffer_usage.updated) { + buffer_contains_frame.set(buffer_usage.id); + } + } + for (int fdiff : frame.frame_diffs) { + if (fdiff <= 0 || static_cast(fdiff) > i) { + ADD_FAILURE() << "Invalid frame diff " << fdiff << " for frame#" << i; + valid = false; + } + } + } + return valid; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_test_helpers.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_test_helpers.h new file mode 100644 index 000000000..d183be476 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalability_structure_test_helpers.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 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. + */ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_TEST_HELPERS_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_TEST_HELPERS_H_ + +#include + +#include + +#include "api/array_view.h" +#include "api/transport/rtp/dependency_descriptor.h" +#include "api/video/video_bitrate_allocation.h" +#include "common_video/generic_frame_descriptor/generic_frame_info.h" +#include "modules/video_coding/chain_diff_calculator.h" +#include "modules/video_coding/frame_dependencies_calculator.h" +#include "modules/video_coding/svc/scalable_video_controller.h" + +namespace webrtc { + +// Creates bitrate allocation with non-zero bitrate for given number of temporal +// layers for each spatial layer. +VideoBitrateAllocation EnableTemporalLayers(int s0, int s1 = 0, int s2 = 0); + +class ScalabilityStructureWrapper { + public: + explicit ScalabilityStructureWrapper(ScalableVideoController& structure) + : structure_controller_(structure) {} + + std::vector GenerateFrames(int num_temporal_units) { + std::vector frames; + GenerateFrames(num_temporal_units, frames); + return frames; + } + void GenerateFrames(int num_temporal_units, + std::vector& frames); + + // Returns false and ADD_FAILUREs for frames with invalid references. + // In particular validates no frame frame reference to frame before frames[0]. + // In error messages frames are indexed starting with 0. + bool FrameReferencesAreValid( + rtc::ArrayView frames) const; + + private: + ScalableVideoController& structure_controller_; + FrameDependenciesCalculator frame_deps_calculator_; + ChainDiffCalculator chain_diff_calculator_; + int64_t frame_id_ = 0; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_STRUCTURE_TEST_HELPERS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller.h similarity index 91% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller.h rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller.h index 016782079..d2d848686 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller.h @@ -7,13 +7,12 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABLE_VIDEO_CONTROLLER_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABLE_VIDEO_CONTROLLER_H_ #include #include "absl/container/inlined_vector.h" -#include "absl/types/optional.h" #include "api/transport/rtp/dependency_descriptor.h" #include "api/video/video_bitrate_allocation.h" #include "common_video/generic_frame_descriptor/generic_frame_info.h" @@ -85,9 +84,7 @@ class ScalableVideoController { // Notifies Controller with updated bitrates per layer. In particular notifies // when certain layers should be disabled. // Controller shouldn't produce LayerFrameConfig for disabled layers. - // TODO(bugs.webrtc.org/11404): Make pure virtual when implemented by all - // structures. - virtual void OnRatesUpdated(const VideoBitrateAllocation& bitrates) {} + virtual void OnRatesUpdated(const VideoBitrateAllocation& bitrates) = 0; // When `restart` is true, first `LayerFrameConfig` should have `is_keyframe` // set to true. @@ -95,8 +92,7 @@ class ScalableVideoController { virtual std::vector NextFrameConfig(bool restart) = 0; // Returns configuration to pass to EncoderCallback. - virtual absl::optional OnEncodeDone( - LayerFrameConfig config) = 0; + virtual GenericFrameInfo OnEncodeDone(const LayerFrameConfig& config) = 0; }; // Below are implementation details. @@ -138,4 +134,4 @@ ScalableVideoController::LayerFrameConfig::ReferenceAndUpdate(int buffer_id) { } // namespace webrtc -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_ +#endif // MODULES_VIDEO_CODING_SVC_SCALABLE_VIDEO_CONTROLLER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller_no_layering.cc similarity index 79% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.cc rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller_no_layering.cc index 0d211fb91..6d8e6e8fc 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller_no_layering.cc @@ -7,7 +7,7 @@ * 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/codecs/av1/scalable_video_controller_no_layering.h" +#include "modules/video_coding/svc/scalable_video_controller_no_layering.h" #include #include @@ -50,17 +50,17 @@ ScalableVideoControllerNoLayering::NextFrameConfig(bool restart) { return result; } -absl::optional -ScalableVideoControllerNoLayering::OnEncodeDone(LayerFrameConfig config) { +GenericFrameInfo ScalableVideoControllerNoLayering::OnEncodeDone( + const LayerFrameConfig& config) { RTC_DCHECK_EQ(config.Id(), 0); - absl::optional frame_info(absl::in_place); - frame_info->encoder_buffers = config.Buffers(); + GenericFrameInfo frame_info; + frame_info.encoder_buffers = config.Buffers(); if (config.IsKeyframe()) { - for (auto& buffer : frame_info->encoder_buffers) { + for (auto& buffer : frame_info.encoder_buffers) { buffer.referenced = false; } } - frame_info->decode_target_indications = {DecodeTargetIndication::kSwitch}; + frame_info.decode_target_indications = {DecodeTargetIndication::kSwitch}; return frame_info; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller_no_layering.h similarity index 66% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.h rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller_no_layering.h index ad730989a..e253ffe84 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/scalable_video_controller_no_layering.h @@ -7,14 +7,15 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_NO_LAYERING_H_ -#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_NO_LAYERING_H_ +#ifndef MODULES_VIDEO_CODING_SVC_SCALABLE_VIDEO_CONTROLLER_NO_LAYERING_H_ +#define MODULES_VIDEO_CODING_SVC_SCALABLE_VIDEO_CONTROLLER_NO_LAYERING_H_ #include #include "api/transport/rtp/dependency_descriptor.h" +#include "api/video/video_bitrate_allocation.h" #include "common_video/generic_frame_descriptor/generic_frame_info.h" -#include "modules/video_coding/codecs/av1/scalable_video_controller.h" +#include "modules/video_coding/svc/scalable_video_controller.h" namespace webrtc { @@ -26,8 +27,8 @@ class ScalableVideoControllerNoLayering : public ScalableVideoController { FrameDependencyStructure DependencyStructure() const override; std::vector NextFrameConfig(bool restart) override; - absl::optional OnEncodeDone( - LayerFrameConfig config) override; + GenericFrameInfo OnEncodeDone(const LayerFrameConfig& config) override; + void OnRatesUpdated(const VideoBitrateAllocation& bitrates) override {} private: bool start_ = true; @@ -35,4 +36,4 @@ class ScalableVideoControllerNoLayering : public ScalableVideoController { } // namespace webrtc -#endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_NO_LAYERING_H_ +#endif // MODULES_VIDEO_CODING_SVC_SCALABLE_VIDEO_CONTROLLER_NO_LAYERING_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/svc_rate_allocator.cc similarity index 82% rename from TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc rename to TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/svc_rate_allocator.cc index 25bca63c0..a51bdb05d 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/svc_rate_allocator.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h" +#include "modules/video_coding/svc/svc_rate_allocator.h" #include #include @@ -17,40 +17,38 @@ #include #include "absl/container/inlined_vector.h" +#include "modules/video_coding/svc/create_scalability_structure.h" #include "rtc_base/checks.h" namespace webrtc { namespace { -const float kSpatialLayeringRateScalingFactor = 0.55f; -const float kTemporalLayeringRateScalingFactor = 0.55f; +constexpr float kSpatialLayeringRateScalingFactor = 0.55f; +constexpr float kTemporalLayeringRateScalingFactor = 0.55f; -// Returns numberOfSpatialLayers if no layers are active. -size_t GetFirstActiveLayer(const VideoCodec& codec) { - RTC_DCHECK_EQ(codec.codecType, kVideoCodecVP9); - RTC_DCHECK_GT(codec.VP9().numberOfSpatialLayers, 0u); - size_t layer = 0; - for (; layer < codec.VP9().numberOfSpatialLayers; ++layer) { - if (codec.spatialLayers[layer].active) { +struct ActiveSpatialLayers { + size_t first = 0; + size_t num = 0; +}; + +ActiveSpatialLayers GetActiveSpatialLayers(const VideoCodec& codec, + size_t num_spatial_layers) { + ActiveSpatialLayers active; + for (active.first = 0; active.first < num_spatial_layers; ++active.first) { + if (codec.spatialLayers[active.first].active) { break; } } - return layer; -} -static size_t GetNumActiveSpatialLayers(const VideoCodec& codec) { - RTC_DCHECK_EQ(codec.codecType, kVideoCodecVP9); - RTC_DCHECK_GT(codec.VP9().numberOfSpatialLayers, 0u); - - const size_t first_active_layer = GetFirstActiveLayer(codec); - size_t last_active_layer = first_active_layer; - for (; last_active_layer < codec.VP9().numberOfSpatialLayers; - ++last_active_layer) { + size_t last_active_layer = active.first; + for (; last_active_layer < num_spatial_layers; ++last_active_layer) { if (!codec.spatialLayers[last_active_layer].active) { break; } } - return last_active_layer - first_active_layer; + active.num = last_active_layer - active.first; + + return active; } std::vector AdjustAndVerify( @@ -173,16 +171,39 @@ DataRate FindLayerTogglingThreshold(const VideoCodec& codec, } // namespace +SvcRateAllocator::NumLayers SvcRateAllocator::GetNumLayers( + const VideoCodec& codec) { + NumLayers layers; + if (!codec.ScalabilityMode().empty()) { + if (auto structure = CreateScalabilityStructure(codec.ScalabilityMode())) { + ScalableVideoController::StreamLayersConfig config = + structure->StreamConfig(); + layers.spatial = config.num_spatial_layers; + layers.temporal = config.num_temporal_layers; + return layers; + } + } + if (codec.codecType == kVideoCodecVP9) { + layers.spatial = codec.VP9().numberOfSpatialLayers; + layers.temporal = codec.VP9().numberOfTemporalLayers; + return layers; + } + layers.spatial = 1; + layers.temporal = 1; + return layers; +} + SvcRateAllocator::SvcRateAllocator(const VideoCodec& codec) : codec_(codec), + num_layers_(GetNumLayers(codec)), experiment_settings_(StableTargetRateExperiment::ParseFromFieldTrials()), cumulative_layer_start_bitrates_(GetLayerStartBitrates(codec)), last_active_layer_count_(0) { - RTC_DCHECK_EQ(codec.codecType, kVideoCodecVP9); - RTC_DCHECK_GT(codec.VP9().numberOfSpatialLayers, 0u); - RTC_DCHECK_GT(codec.VP9().numberOfTemporalLayers, 0u); - for (size_t layer_idx = 0; layer_idx < codec.VP9().numberOfSpatialLayers; - ++layer_idx) { + RTC_DCHECK_GT(num_layers_.spatial, 0); + RTC_DCHECK_LE(num_layers_.spatial, kMaxSpatialLayers); + RTC_DCHECK_GT(num_layers_.temporal, 0); + RTC_DCHECK_LE(num_layers_.temporal, 3); + for (size_t layer_idx = 0; layer_idx < num_layers_.spatial; ++layer_idx) { // Verify min <= target <= max. if (codec.spatialLayers[layer_idx].active) { RTC_DCHECK_GT(codec.spatialLayers[layer_idx].maxBitrate, 0); @@ -205,16 +226,16 @@ VideoBitrateAllocation SvcRateAllocator::Allocate( } if (codec_.spatialLayers[0].targetBitrate == 0) { - // Delegate rate distribution to VP9 encoder wrapper if bitrate thresholds + // Delegate rate distribution to encoder wrapper if bitrate thresholds // are not set. VideoBitrateAllocation bitrate_allocation; bitrate_allocation.SetBitrate(0, 0, total_bitrate.bps()); return bitrate_allocation; } - const size_t first_active_layer = GetFirstActiveLayer(codec_); - const size_t num_active_layers = GetNumActiveSpatialLayers(codec_); - size_t num_spatial_layers = num_active_layers; + const ActiveSpatialLayers active_layers = + GetActiveSpatialLayers(codec_, num_layers_.spatial); + size_t num_spatial_layers = active_layers.num; if (num_spatial_layers == 0) { return VideoBitrateAllocation(); // All layers are deactivated. @@ -249,13 +270,13 @@ VideoBitrateAllocation SvcRateAllocator::Allocate( VideoBitrateAllocation allocation; if (codec_.mode == VideoCodecMode::kRealtimeVideo) { - allocation = GetAllocationNormalVideo(total_bitrate, first_active_layer, + allocation = GetAllocationNormalVideo(total_bitrate, active_layers.first, num_spatial_layers); } else { - allocation = GetAllocationScreenSharing(total_bitrate, first_active_layer, + allocation = GetAllocationScreenSharing(total_bitrate, active_layers.first, num_spatial_layers); } - allocation.set_bw_limited(num_spatial_layers < num_active_layers); + allocation.set_bw_limited(num_spatial_layers < active_layers.num); return allocation; } @@ -279,25 +300,24 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocationNormalVideo( VideoBitrateAllocation bitrate_allocation; - const size_t num_temporal_layers = codec_.VP9().numberOfTemporalLayers; for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { std::vector temporal_layer_rates = - SplitBitrate(num_temporal_layers, spatial_layer_rates[sl_idx], + SplitBitrate(num_layers_.temporal, spatial_layer_rates[sl_idx], kTemporalLayeringRateScalingFactor); // Distribute rate across temporal layers. Allocate more bits to lower // layers since they are used for prediction of higher layers and their // references are far apart. - if (num_temporal_layers == 1) { + if (num_layers_.temporal == 1) { bitrate_allocation.SetBitrate(sl_idx + first_active_layer, 0, temporal_layer_rates[0].bps()); - } else if (num_temporal_layers == 2) { + } else if (num_layers_.temporal == 2) { bitrate_allocation.SetBitrate(sl_idx + first_active_layer, 0, temporal_layer_rates[1].bps()); bitrate_allocation.SetBitrate(sl_idx + first_active_layer, 1, temporal_layer_rates[0].bps()); } else { - RTC_CHECK_EQ(num_temporal_layers, 3); + RTC_CHECK_EQ(num_layers_.temporal, 3); // In case of three temporal layers the high layer has two frames and the // middle layer has one frame within GOP (in between two consecutive low // layer frames). Thus high layer requires more bits (comparing pure @@ -383,13 +403,14 @@ size_t SvcRateAllocator::FindNumEnabledLayers(DataRate target_rate) const { } DataRate SvcRateAllocator::GetMaxBitrate(const VideoCodec& codec) { - const size_t first_active_layer = GetFirstActiveLayer(codec); - const size_t num_spatial_layers = GetNumActiveSpatialLayers(codec); + const NumLayers num_layers = GetNumLayers(codec); + const ActiveSpatialLayers active_layers = + GetActiveSpatialLayers(codec, num_layers.spatial); DataRate max_bitrate = DataRate::Zero(); - for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { + for (size_t sl_idx = 0; sl_idx < active_layers.num; ++sl_idx) { max_bitrate += DataRate::KilobitsPerSec( - codec.spatialLayers[first_active_layer + sl_idx].maxBitrate); + codec.spatialLayers[active_layers.first + sl_idx].maxBitrate); } if (codec.maxBitrate != 0) { @@ -412,12 +433,13 @@ DataRate SvcRateAllocator::GetPaddingBitrate(const VideoCodec& codec) { absl::InlinedVector SvcRateAllocator::GetLayerStartBitrates(const VideoCodec& codec) { absl::InlinedVector start_bitrates; - const size_t first_active_layer = GetFirstActiveLayer(codec); - const size_t num_layers = GetNumActiveSpatialLayers(codec); + const NumLayers num_layers = GetNumLayers(codec); + const ActiveSpatialLayers active_layers = + GetActiveSpatialLayers(codec, num_layers.spatial); DataRate last_rate = DataRate::Zero(); - for (size_t i = 1; i <= num_layers; ++i) { + for (size_t i = 1; i <= active_layers.num; ++i) { DataRate layer_toggling_rate = - FindLayerTogglingThreshold(codec, first_active_layer, i); + FindLayerTogglingThreshold(codec, active_layers.first, i); start_bitrates.push_back(layer_toggling_rate); RTC_DCHECK_LE(last_rate, layer_toggling_rate); last_rate = layer_toggling_rate; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/svc_rate_allocator.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/svc_rate_allocator.h new file mode 100644 index 000000000..bd75fca28 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/svc/svc_rate_allocator.h @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#ifndef MODULES_VIDEO_CODING_SVC_SVC_RATE_ALLOCATOR_H_ +#define MODULES_VIDEO_CODING_SVC_SVC_RATE_ALLOCATOR_H_ + +#include +#include + +#include "absl/container/inlined_vector.h" +#include "api/video/video_bitrate_allocation.h" +#include "api/video/video_bitrate_allocator.h" +#include "api/video/video_codec_constants.h" +#include "api/video_codecs/video_codec.h" +#include "rtc_base/experiments/stable_target_rate_experiment.h" + +namespace webrtc { + +class SvcRateAllocator : public VideoBitrateAllocator { + public: + explicit SvcRateAllocator(const VideoCodec& codec); + + VideoBitrateAllocation Allocate( + VideoBitrateAllocationParameters parameters) override; + + static DataRate GetMaxBitrate(const VideoCodec& codec); + static DataRate GetPaddingBitrate(const VideoCodec& codec); + static absl::InlinedVector GetLayerStartBitrates( + const VideoCodec& codec); + + private: + struct NumLayers { + size_t spatial = 1; + size_t temporal = 1; + }; + + static NumLayers GetNumLayers(const VideoCodec& codec); + VideoBitrateAllocation GetAllocationNormalVideo( + DataRate total_bitrate, + size_t first_active_layer, + size_t num_spatial_layers) const; + + VideoBitrateAllocation GetAllocationScreenSharing( + DataRate total_bitrate, + size_t first_active_layer, + size_t num_spatial_layers) const; + + // Returns the number of layers that are active and have enough bitrate to + // actually be enabled. + size_t FindNumEnabledLayers(DataRate target_rate) const; + + const VideoCodec codec_; + const NumLayers num_layers_; + const StableTargetRateExperiment experiment_settings_; + const absl::InlinedVector + cumulative_layer_start_bitrates_; + size_t last_active_layer_count_; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_SVC_SVC_RATE_ALLOCATOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/timestamp_map.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/timestamp_map.cc index d93293704..d79075ff2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/timestamp_map.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/timestamp_map.cc @@ -60,4 +60,13 @@ VCMFrameInformation* VCMTimestampMap::Pop(uint32_t timestamp) { bool VCMTimestampMap::IsEmpty() const { return (next_add_idx_ == next_pop_idx_); } + +size_t VCMTimestampMap::Size() const { + // The maximum number of elements in the list is |capacity_| - 1. The list is + // empty if the add and pop indices are equal. + return next_add_idx_ >= next_pop_idx_ + ? next_add_idx_ - next_pop_idx_ + : next_add_idx_ + capacity_ - next_pop_idx_; +} + } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/timestamp_map.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/timestamp_map.h index c85666c9a..cfa12573e 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/timestamp_map.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/timestamp_map.h @@ -24,6 +24,7 @@ class VCMTimestampMap { void Add(uint32_t timestamp, VCMFrameInformation* data); VCMFrameInformation* Pop(uint32_t timestamp); + size_t Size() const; private: struct TimestampDataTuple { diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/timing.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/timing.cc index f046edf49..eddac4f5d 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/timing.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/timing.cc @@ -14,16 +14,18 @@ #include +#include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/time/timestamp_extrapolator.h" #include "system_wrappers/include/clock.h" +#include "system_wrappers/include/field_trial.h" namespace webrtc { -VCMTiming::VCMTiming(Clock* clock, VCMTiming* master_timing) +VCMTiming::VCMTiming(Clock* clock) : clock_(clock), - master_(false), - ts_extrapolator_(), - codec_timer_(new VCMCodecTimer()), + ts_extrapolator_(std::make_unique( + clock_->TimeInMilliseconds())), + codec_timer_(std::make_unique()), render_delay_ms_(kDefaultRenderDelayMs), min_playout_delay_ms_(0), max_playout_delay_ms_(10000), @@ -31,25 +33,16 @@ VCMTiming::VCMTiming(Clock* clock, VCMTiming* master_timing) current_delay_ms_(0), prev_frame_timestamp_(0), timing_frame_info_(), - num_decoded_frames_(0) { - if (master_timing == NULL) { - master_ = true; - ts_extrapolator_ = new TimestampExtrapolator(clock_->TimeInMilliseconds()); - } else { - ts_extrapolator_ = master_timing->ts_extrapolator_; - } -} - -VCMTiming::~VCMTiming() { - if (master_) { - delete ts_extrapolator_; - } + num_decoded_frames_(0), + low_latency_renderer_enabled_("enabled", true) { + ParseFieldTrial({&low_latency_renderer_enabled_}, + field_trial::FindFullName("WebRTC-LowLatencyRenderer")); } void VCMTiming::Reset() { MutexLock lock(&mutex_); ts_extrapolator_->Reset(clock_->TimeInMilliseconds()); - codec_timer_.reset(new VCMCodecTimer()); + codec_timer_ = std::make_unique(); render_delay_ms_ = kDefaultRenderDelayMs; min_playout_delay_ms_ = 0; jitter_delay_ms_ = 0; @@ -177,10 +170,16 @@ int64_t VCMTiming::RenderTimeMs(uint32_t frame_timestamp, int64_t VCMTiming::RenderTimeMsInternal(uint32_t frame_timestamp, int64_t now_ms) const { - if (min_playout_delay_ms_ == 0 && max_playout_delay_ms_ == 0) { - // Render as soon as possible. + constexpr int kLowLatencyRendererMaxPlayoutDelayMs = 500; + if (min_playout_delay_ms_ == 0 && + (max_playout_delay_ms_ == 0 || + (low_latency_renderer_enabled_ && + max_playout_delay_ms_ <= kLowLatencyRendererMaxPlayoutDelayMs))) { + // Render as soon as possible or with low-latency renderer algorithm. return 0; } + // Note that TimestampExtrapolator::ExtrapolateLocalTime is not a const + // method; it mutates the object's wraparound state. int64_t estimated_complete_time_ms = ts_extrapolator_->ExtrapolateLocalTime(frame_timestamp); if (estimated_complete_time_ms == -1) { @@ -246,4 +245,15 @@ absl::optional VCMTiming::GetTimingFrameInfo() { return timing_frame_info_; } +void VCMTiming::SetMaxCompositionDelayInFrames( + absl::optional max_composition_delay_in_frames) { + MutexLock lock(&mutex_); + max_composition_delay_in_frames_ = max_composition_delay_in_frames; +} + +absl::optional VCMTiming::MaxCompositionDelayInFrames() const { + MutexLock lock(&mutex_); + return max_composition_delay_in_frames_; +} + } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/timing.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/timing.h index 75b8e7d99..736b5e9ae 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/timing.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/timing.h @@ -16,8 +16,10 @@ #include "absl/types/optional.h" #include "api/video/video_timing.h" #include "modules/video_coding/codec_timer.h" +#include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" +#include "rtc_base/time/timestamp_extrapolator.h" namespace webrtc { @@ -26,10 +28,8 @@ class TimestampExtrapolator; class VCMTiming { public: - // The primary timing component should be passed - // if this is the dual timing component. - explicit VCMTiming(Clock* clock, VCMTiming* master_timing = NULL); - virtual ~VCMTiming(); + explicit VCMTiming(Clock* clock); + virtual ~VCMTiming() = default; // Resets the timing to the initial state. void Reset(); @@ -100,6 +100,10 @@ class VCMTiming { void SetTimingFrameInfo(const TimingFrameInfo& info); absl::optional GetTimingFrameInfo(); + void SetMaxCompositionDelayInFrames( + absl::optional max_composition_delay_in_frames); + absl::optional MaxCompositionDelayInFrames() const; + enum { kDefaultRenderDelayMs = 10 }; enum { kDelayMaxChangeMsPerS = 100 }; @@ -112,9 +116,10 @@ class VCMTiming { private: mutable Mutex mutex_; Clock* const clock_; - bool master_ RTC_GUARDED_BY(mutex_); - TimestampExtrapolator* ts_extrapolator_ RTC_GUARDED_BY(mutex_); - std::unique_ptr codec_timer_ RTC_GUARDED_BY(mutex_); + const std::unique_ptr ts_extrapolator_ + RTC_PT_GUARDED_BY(mutex_); + std::unique_ptr codec_timer_ RTC_GUARDED_BY(mutex_) + RTC_PT_GUARDED_BY(mutex_); int render_delay_ms_ RTC_GUARDED_BY(mutex_); // Best-effort playout delay range for frames from capture to render. // The receiver tries to keep the delay between |min_playout_delay_ms_| @@ -128,6 +133,12 @@ class VCMTiming { uint32_t prev_frame_timestamp_ RTC_GUARDED_BY(mutex_); absl::optional timing_frame_info_ RTC_GUARDED_BY(mutex_); size_t num_decoded_frames_ RTC_GUARDED_BY(mutex_); + // Set by the field trial WebRTC-LowLatencyRenderer. The parameter enabled + // determines if the low-latency renderer algorithm should be used for the + // case min playout delay=0 and max playout delay>0. + FieldTrialParameter low_latency_renderer_enabled_ + RTC_GUARDED_BY(mutex_); + absl::optional max_composition_delay_in_frames_ RTC_GUARDED_BY(mutex_); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/ivf_file_reader.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/ivf_file_reader.cc index 9667bb7ce..e3c249947 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/ivf_file_reader.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/ivf_file_reader.cc @@ -27,6 +27,7 @@ constexpr int kCodecTypeBytesCount = 4; constexpr uint8_t kFileHeaderStart[kCodecTypeBytesCount] = {'D', 'K', 'I', 'F'}; constexpr uint8_t kVp8Header[kCodecTypeBytesCount] = {'V', 'P', '8', '0'}; constexpr uint8_t kVp9Header[kCodecTypeBytesCount] = {'V', 'P', '9', '0'}; +constexpr uint8_t kAv1Header[kCodecTypeBytesCount] = {'A', 'V', '0', '1'}; constexpr uint8_t kH264Header[kCodecTypeBytesCount] = {'H', '2', '6', '4'}; } // namespace @@ -170,7 +171,6 @@ absl::optional IvfFileReader::NextFrame() { if (is_first_frame) { image._frameType = VideoFrameType::kVideoFrameKey; } - image._completeFrame = true; return image; } @@ -191,6 +191,9 @@ absl::optional IvfFileReader::ParseCodecType(uint8_t* buffer, if (memcmp(&buffer[start_pos], kVp9Header, kCodecTypeBytesCount) == 0) { return VideoCodecType::kVideoCodecVP9; } + if (memcmp(&buffer[start_pos], kAv1Header, kCodecTypeBytesCount) == 0) { + return VideoCodecType::kVideoCodecAV1; + } if (memcmp(&buffer[start_pos], kH264Header, kCodecTypeBytesCount) == 0) { return VideoCodecType::kVideoCodecH264; } diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/ivf_file_writer.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/ivf_file_writer.cc index 46b8e87ba..496da894a 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/ivf_file_writer.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/ivf_file_writer.cc @@ -75,6 +75,12 @@ bool IvfFileWriter::WriteHeader() { ivf_header[10] = '9'; ivf_header[11] = '0'; break; + case kVideoCodecAV1: + ivf_header[8] = 'A'; + ivf_header[9] = 'V'; + ivf_header[10] = '0'; + ivf_header[11] = '1'; + break; case kVideoCodecH264: ivf_header[8] = 'H'; ivf_header[9] = '2'; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/quality_scaler.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/quality_scaler.cc index 71bf93429..2859ac2e2 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/quality_scaler.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/quality_scaler.cc @@ -189,13 +189,17 @@ QualityScaler::QualityScaler(QualityScalerQpUsageHandlerInterface* handler, // Protected ctor, should not be called directly. QualityScaler::QualityScaler(QualityScalerQpUsageHandlerInterface* handler, VideoEncoder::QpThresholds thresholds, - int64_t sampling_period_ms) + int64_t default_sampling_period_ms) : handler_(handler), thresholds_(thresholds), - sampling_period_ms_(sampling_period_ms), + sampling_period_ms_(QualityScalerSettings::ParseFromFieldTrials() + .SamplingPeriodMs() + .value_or(default_sampling_period_ms)), fast_rampup_(true), // Arbitrarily choose size based on 30 fps for 5 seconds. - average_qp_(5 * 30), + average_qp_(QualityScalerSettings::ParseFromFieldTrials() + .AverageQpWindow() + .value_or(5 * 30)), framedrop_percent_media_opt_(5 * 30), framedrop_percent_all_(5 * 30), experiment_enabled_(QualityScalingExperiment::Enabled()), diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_rate_allocator.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_rate_allocator.cc index 13de8755d..39e39abca 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_rate_allocator.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_rate_allocator.cc @@ -151,7 +151,7 @@ void SimulcastRateAllocator::DistributeAllocationToSimulcastLayers( size_t top_active_layer = active_layer; // Allocate up to the target bitrate for each active simulcast layer. for (; active_layer < codec_.numberOfSimulcastStreams; ++active_layer) { - const SimulcastStream& stream = + const SpatialLayer& stream = codec_.simulcastStream[layer_index[active_layer]]; if (!stream.active) { stream_enabled_[layer_index[active_layer]] = false; @@ -194,7 +194,7 @@ void SimulcastRateAllocator::DistributeAllocationToSimulcastLayers( // TODO(sprang): Allocate up to max bitrate for all layers once we have a // better idea of possible performance implications. if (left_in_total_allocation > DataRate::Zero()) { - const SimulcastStream& stream = codec_.simulcastStream[top_active_layer]; + const SpatialLayer& stream = codec_.simulcastStream[top_active_layer]; DataRate initial_layer_rate = DataRate::BitsPerSec( allocated_bitrates->GetSpatialLayerSum(top_active_layer)); DataRate additional_allocation = std::min( @@ -229,7 +229,8 @@ void SimulcastRateAllocator::DistributeAllocationToTemporalLayers( uint32_t max_bitrate_kbps; // Legacy temporal-layered only screenshare, or simulcast screenshare // with legacy mode for simulcast stream 0. - if (legacy_conference_mode_ && simulcast_id == 0) { + if (codec_.mode == VideoCodecMode::kScreensharing && + legacy_conference_mode_ && simulcast_id == 0) { // TODO(holmer): This is a "temporary" hack for screensharing, where we // interpret the startBitrate as the encoder target bitrate. This is // to allow for a different max bitrate, so if the codec can't meet @@ -249,7 +250,8 @@ void SimulcastRateAllocator::DistributeAllocationToTemporalLayers( if (num_temporal_streams == 1) { tl_allocation.push_back(target_bitrate_kbps); } else { - if (legacy_conference_mode_ && simulcast_id == 0) { + if (codec_.mode == VideoCodecMode::kScreensharing && + legacy_conference_mode_ && simulcast_id == 0) { tl_allocation = ScreenshareTemporalLayerAllocation( target_bitrate_kbps, max_bitrate_kbps, simulcast_id); } else { diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_test_fixture_impl.cc new file mode 100644 index 000000000..a9af64344 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_test_fixture_impl.cc @@ -0,0 +1,915 @@ +/* + * Copyright (c) 2014 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/utility/simulcast_test_fixture_impl.h" + +#include +#include +#include +#include + +#include "api/video/encoded_image.h" +#include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder.h" +#include "common_video/libyuv/include/webrtc_libyuv.h" +#include "modules/video_coding/include/video_codec_interface.h" +#include "modules/video_coding/include/video_coding_defines.h" +#include "rtc_base/checks.h" +#include "test/gtest.h" + +using ::testing::_; +using ::testing::AllOf; +using ::testing::Field; +using ::testing::Return; + +namespace webrtc { +namespace test { + +namespace { + +const int kDefaultWidth = 1280; +const int kDefaultHeight = 720; +const int kNumberOfSimulcastStreams = 3; +const int kColorY = 66; +const int kColorU = 22; +const int kColorV = 33; +const int kMaxBitrates[kNumberOfSimulcastStreams] = {150, 600, 1200}; +const int kMinBitrates[kNumberOfSimulcastStreams] = {50, 150, 600}; +const int kTargetBitrates[kNumberOfSimulcastStreams] = {100, 450, 1000}; +const float kMaxFramerates[kNumberOfSimulcastStreams] = {30, 30, 30}; +const int kDefaultTemporalLayerProfile[3] = {3, 3, 3}; +const int kNoTemporalLayerProfile[3] = {0, 0, 0}; + +const VideoEncoder::Capabilities kCapabilities(false); +const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200); + +template +void SetExpectedValues3(T value0, T value1, T value2, T* expected_values) { + expected_values[0] = value0; + expected_values[1] = value1; + expected_values[2] = value2; +} + +enum PlaneType { + kYPlane = 0, + kUPlane = 1, + kVPlane = 2, + kNumOfPlanes = 3, +}; + +} // namespace + +class SimulcastTestFixtureImpl::TestEncodedImageCallback + : public EncodedImageCallback { + public: + TestEncodedImageCallback() { + memset(temporal_layer_, -1, sizeof(temporal_layer_)); + memset(layer_sync_, false, sizeof(layer_sync_)); + } + + Result OnEncodedImage(const EncodedImage& encoded_image, + const CodecSpecificInfo* codec_specific_info) override { + bool is_vp8 = (codec_specific_info->codecType == kVideoCodecVP8); + bool is_h264 = (codec_specific_info->codecType == kVideoCodecH264); + // Only store the base layer. + if (encoded_image.SpatialIndex().value_or(0) == 0) { + if (encoded_image._frameType == VideoFrameType::kVideoFrameKey) { + encoded_key_frame_.SetEncodedData(EncodedImageBuffer::Create( + encoded_image.data(), encoded_image.size())); + encoded_key_frame_._frameType = VideoFrameType::kVideoFrameKey; + } else { + encoded_frame_.SetEncodedData(EncodedImageBuffer::Create( + encoded_image.data(), encoded_image.size())); + } + } + if (is_vp8) { + layer_sync_[encoded_image.SpatialIndex().value_or(0)] = + codec_specific_info->codecSpecific.VP8.layerSync; + temporal_layer_[encoded_image.SpatialIndex().value_or(0)] = + codec_specific_info->codecSpecific.VP8.temporalIdx; + } else if (is_h264) { + layer_sync_[encoded_image.SpatialIndex().value_or(0)] = + codec_specific_info->codecSpecific.H264.base_layer_sync; + temporal_layer_[encoded_image.SpatialIndex().value_or(0)] = + codec_specific_info->codecSpecific.H264.temporal_idx; + } + return Result(Result::OK, encoded_image.Timestamp()); + } + // This method only makes sense for VP8. + void GetLastEncodedFrameInfo(int* temporal_layer, + bool* layer_sync, + int stream) { + *temporal_layer = temporal_layer_[stream]; + *layer_sync = layer_sync_[stream]; + } + void GetLastEncodedKeyFrame(EncodedImage* encoded_key_frame) { + *encoded_key_frame = encoded_key_frame_; + } + void GetLastEncodedFrame(EncodedImage* encoded_frame) { + *encoded_frame = encoded_frame_; + } + + private: + EncodedImage encoded_key_frame_; + EncodedImage encoded_frame_; + int temporal_layer_[kNumberOfSimulcastStreams]; + bool layer_sync_[kNumberOfSimulcastStreams]; +}; + +class SimulcastTestFixtureImpl::TestDecodedImageCallback + : public DecodedImageCallback { + public: + TestDecodedImageCallback() : decoded_frames_(0) {} + int32_t Decoded(VideoFrame& decoded_image) override { + rtc::scoped_refptr i420_buffer = + decoded_image.video_frame_buffer()->ToI420(); + for (int i = 0; i < decoded_image.width(); ++i) { + EXPECT_NEAR(kColorY, i420_buffer->DataY()[i], 1); + } + + // TODO(mikhal): Verify the difference between U,V and the original. + for (int i = 0; i < i420_buffer->ChromaWidth(); ++i) { + EXPECT_NEAR(kColorU, i420_buffer->DataU()[i], 4); + EXPECT_NEAR(kColorV, i420_buffer->DataV()[i], 4); + } + decoded_frames_++; + return 0; + } + int32_t Decoded(VideoFrame& decoded_image, int64_t decode_time_ms) override { + RTC_NOTREACHED(); + return -1; + } + void Decoded(VideoFrame& decoded_image, + absl::optional decode_time_ms, + absl::optional qp) override { + Decoded(decoded_image); + } + int DecodedFrames() { return decoded_frames_; } + + private: + int decoded_frames_; +}; + +namespace { + +void SetPlane(uint8_t* data, uint8_t value, int width, int height, int stride) { + for (int i = 0; i < height; i++, data += stride) { + // Setting allocated area to zero - setting only image size to + // requested values - will make it easier to distinguish between image + // size and frame size (accounting for stride). + memset(data, value, width); + memset(data + width, 0, stride - width); + } +} + +// Fills in an I420Buffer from |plane_colors|. +void CreateImage(const rtc::scoped_refptr& buffer, + int plane_colors[kNumOfPlanes]) { + SetPlane(buffer->MutableDataY(), plane_colors[0], buffer->width(), + buffer->height(), buffer->StrideY()); + + SetPlane(buffer->MutableDataU(), plane_colors[1], buffer->ChromaWidth(), + buffer->ChromaHeight(), buffer->StrideU()); + + SetPlane(buffer->MutableDataV(), plane_colors[2], buffer->ChromaWidth(), + buffer->ChromaHeight(), buffer->StrideV()); +} + +void ConfigureStream(int width, + int height, + int max_bitrate, + int min_bitrate, + int target_bitrate, + float max_framerate, + SpatialLayer* stream, + int num_temporal_layers) { + assert(stream); + stream->width = width; + stream->height = height; + stream->maxBitrate = max_bitrate; + stream->minBitrate = min_bitrate; + stream->targetBitrate = target_bitrate; + stream->maxFramerate = max_framerate; + if (num_temporal_layers >= 0) { + stream->numberOfTemporalLayers = num_temporal_layers; + } + stream->qpMax = 45; + stream->active = true; +} + +} // namespace + +void SimulcastTestFixtureImpl::DefaultSettings( + VideoCodec* settings, + const int* temporal_layer_profile, + VideoCodecType codec_type, + bool reverse_layer_order) { + RTC_CHECK(settings); + *settings = {}; + settings->codecType = codec_type; + settings->startBitrate = 300; + settings->minBitrate = 30; + settings->maxBitrate = 0; + settings->maxFramerate = 30; + settings->width = kDefaultWidth; + settings->height = kDefaultHeight; + settings->numberOfSimulcastStreams = kNumberOfSimulcastStreams; + settings->active = true; + ASSERT_EQ(3, kNumberOfSimulcastStreams); + int layer_order[3] = {0, 1, 2}; + if (reverse_layer_order) { + layer_order[0] = 2; + layer_order[2] = 0; + } + settings->timing_frame_thresholds = {kDefaultTimingFramesDelayMs, + kDefaultOutlierFrameSizePercent}; + ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4, kMaxBitrates[0], + kMinBitrates[0], kTargetBitrates[0], kMaxFramerates[0], + &settings->simulcastStream[layer_order[0]], + temporal_layer_profile[0]); + ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2, kMaxBitrates[1], + kMinBitrates[1], kTargetBitrates[1], kMaxFramerates[1], + &settings->simulcastStream[layer_order[1]], + temporal_layer_profile[1]); + ConfigureStream(kDefaultWidth, kDefaultHeight, kMaxBitrates[2], + kMinBitrates[2], kTargetBitrates[2], kMaxFramerates[2], + &settings->simulcastStream[layer_order[2]], + temporal_layer_profile[2]); + if (codec_type == kVideoCodecVP8) { + settings->VP8()->denoisingOn = true; + settings->VP8()->automaticResizeOn = false; + settings->VP8()->frameDroppingOn = true; + settings->VP8()->keyFrameInterval = 3000; + } else { + settings->H264()->frameDroppingOn = true; + settings->H264()->keyFrameInterval = 3000; + } +} + +SimulcastTestFixtureImpl::SimulcastTestFixtureImpl( + std::unique_ptr encoder_factory, + std::unique_ptr decoder_factory, + SdpVideoFormat video_format) + : codec_type_(PayloadStringToCodecType(video_format.name)) { + encoder_ = encoder_factory->CreateVideoEncoder(video_format); + decoder_ = decoder_factory->CreateVideoDecoder(video_format); + SetUpCodec((codec_type_ == kVideoCodecVP8 || codec_type_ == kVideoCodecH264) + ? kDefaultTemporalLayerProfile + : kNoTemporalLayerProfile); +} + +SimulcastTestFixtureImpl::~SimulcastTestFixtureImpl() { + encoder_->Release(); + decoder_->Release(); +} + +void SimulcastTestFixtureImpl::SetUpCodec(const int* temporal_layer_profile) { + encoder_->RegisterEncodeCompleteCallback(&encoder_callback_); + decoder_->RegisterDecodeCompleteCallback(&decoder_callback_); + DefaultSettings(&settings_, temporal_layer_profile, codec_type_); + SetUpRateAllocator(); + EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings)); + EXPECT_EQ(0, decoder_->InitDecode(&settings_, 1)); + input_buffer_ = I420Buffer::Create(kDefaultWidth, kDefaultHeight); + input_buffer_->InitializeData(); + input_frame_ = std::make_unique( + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(input_buffer_) + .set_rotation(webrtc::kVideoRotation_0) + .set_timestamp_us(0) + .build()); +} + +void SimulcastTestFixtureImpl::SetUpRateAllocator() { + rate_allocator_.reset(new SimulcastRateAllocator(settings_)); +} + +void SimulcastTestFixtureImpl::SetRates(uint32_t bitrate_kbps, uint32_t fps) { + encoder_->SetRates(VideoEncoder::RateControlParameters( + rate_allocator_->Allocate( + VideoBitrateAllocationParameters(bitrate_kbps * 1000, fps)), + static_cast(fps))); +} + +void SimulcastTestFixtureImpl::RunActiveStreamsTest( + const std::vector active_streams) { + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + UpdateActiveStreams(active_streams); + // Set sufficient bitrate for all streams so we can test active without + // bitrate being an issue. + SetRates(kMaxBitrates[0] + kMaxBitrates[1] + kMaxBitrates[2], 30); + + ExpectStreams(VideoFrameType::kVideoFrameKey, active_streams); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, active_streams); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::UpdateActiveStreams( + const std::vector active_streams) { + ASSERT_EQ(static_cast(active_streams.size()), kNumberOfSimulcastStreams); + for (size_t i = 0; i < active_streams.size(); ++i) { + settings_.simulcastStream[i].active = active_streams[i]; + } + // Re initialize the allocator and encoder with the new settings. + // TODO(bugs.webrtc.org/8807): Currently, we do a full "hard" + // reconfiguration of the allocator and encoder. When the video bitrate + // allocator has support for updating active streams without a + // reinitialization, we can just call that here instead. + SetUpRateAllocator(); + EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings)); +} + +void SimulcastTestFixtureImpl::ExpectStreams( + VideoFrameType frame_type, + const std::vector expected_streams_active) { + ASSERT_EQ(static_cast(expected_streams_active.size()), + kNumberOfSimulcastStreams); + if (expected_streams_active[0]) { + EXPECT_CALL( + encoder_callback_, + OnEncodedImage( + AllOf(Field(&EncodedImage::_frameType, frame_type), + Field(&EncodedImage::_encodedWidth, kDefaultWidth / 4), + Field(&EncodedImage::_encodedHeight, kDefaultHeight / 4)), + _)) + .Times(1) + .WillRepeatedly(Return( + EncodedImageCallback::Result(EncodedImageCallback::Result::OK, 0))); + } + if (expected_streams_active[1]) { + EXPECT_CALL( + encoder_callback_, + OnEncodedImage( + AllOf(Field(&EncodedImage::_frameType, frame_type), + Field(&EncodedImage::_encodedWidth, kDefaultWidth / 2), + Field(&EncodedImage::_encodedHeight, kDefaultHeight / 2)), + _)) + .Times(1) + .WillRepeatedly(Return( + EncodedImageCallback::Result(EncodedImageCallback::Result::OK, 0))); + } + if (expected_streams_active[2]) { + EXPECT_CALL(encoder_callback_, + OnEncodedImage( + AllOf(Field(&EncodedImage::_frameType, frame_type), + Field(&EncodedImage::_encodedWidth, kDefaultWidth), + Field(&EncodedImage::_encodedHeight, kDefaultHeight)), + _)) + .Times(1) + .WillRepeatedly(Return( + EncodedImageCallback::Result(EncodedImageCallback::Result::OK, 0))); + } +} + +void SimulcastTestFixtureImpl::ExpectStreams(VideoFrameType frame_type, + int expected_video_streams) { + ASSERT_GE(expected_video_streams, 0); + ASSERT_LE(expected_video_streams, kNumberOfSimulcastStreams); + std::vector expected_streams_active(kNumberOfSimulcastStreams, false); + for (int i = 0; i < expected_video_streams; ++i) { + expected_streams_active[i] = true; + } + ExpectStreams(frame_type, expected_streams_active); +} + +void SimulcastTestFixtureImpl::VerifyTemporalIdxAndSyncForAllSpatialLayers( + TestEncodedImageCallback* encoder_callback, + const int* expected_temporal_idx, + const bool* expected_layer_sync, + int num_spatial_layers) { + int temporal_layer = -1; + bool layer_sync = false; + for (int i = 0; i < num_spatial_layers; i++) { + encoder_callback->GetLastEncodedFrameInfo(&temporal_layer, &layer_sync, i); + EXPECT_EQ(expected_temporal_idx[i], temporal_layer); + EXPECT_EQ(expected_layer_sync[i], layer_sync); + } +} + +// We currently expect all active streams to generate a key frame even though +// a key frame was only requested for some of them. +void SimulcastTestFixtureImpl::TestKeyFrameRequestsOnAllStreams() { + SetRates(kMaxBitrates[2], 30); // To get all three streams. + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameKey, kNumberOfSimulcastStreams); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, kNumberOfSimulcastStreams); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + frame_types[0] = VideoFrameType::kVideoFrameKey; + ExpectStreams(VideoFrameType::kVideoFrameKey, kNumberOfSimulcastStreams); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + std::fill(frame_types.begin(), frame_types.end(), + VideoFrameType::kVideoFrameDelta); + frame_types[1] = VideoFrameType::kVideoFrameKey; + ExpectStreams(VideoFrameType::kVideoFrameKey, kNumberOfSimulcastStreams); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + std::fill(frame_types.begin(), frame_types.end(), + VideoFrameType::kVideoFrameDelta); + frame_types[2] = VideoFrameType::kVideoFrameKey; + ExpectStreams(VideoFrameType::kVideoFrameKey, kNumberOfSimulcastStreams); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + std::fill(frame_types.begin(), frame_types.end(), + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameDelta, kNumberOfSimulcastStreams); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestPaddingAllStreams() { + // We should always encode the base layer. + SetRates(kMinBitrates[0] - 1, 30); + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameKey, 1); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, 1); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestPaddingTwoStreams() { + // We have just enough to get only the first stream and padding for two. + SetRates(kMinBitrates[0], 30); + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameKey, 1); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, 1); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestPaddingTwoStreamsOneMaxedOut() { + // We are just below limit of sending second stream, so we should get + // the first stream maxed out (at |maxBitrate|), and padding for two. + SetRates(kTargetBitrates[0] + kMinBitrates[1] - 1, 30); + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameKey, 1); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, 1); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestPaddingOneStream() { + // We have just enough to send two streams, so padding for one stream. + SetRates(kTargetBitrates[0] + kMinBitrates[1], 30); + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameKey, 2); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, 2); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestPaddingOneStreamTwoMaxedOut() { + // We are just below limit of sending third stream, so we should get + // first stream's rate maxed out at |targetBitrate|, second at |maxBitrate|. + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] - 1, 30); + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameKey, 2); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, 2); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestSendAllStreams() { + // We have just enough to send all streams. + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2], 30); + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameKey, 3); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, 3); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestDisablingStreams() { + // We should get three media streams. + SetRates(kMaxBitrates[0] + kMaxBitrates[1] + kMaxBitrates[2], 30); + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + ExpectStreams(VideoFrameType::kVideoFrameKey, 3); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + ExpectStreams(VideoFrameType::kVideoFrameDelta, 3); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + // We should only get two streams and padding for one. + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] / 2, 30); + ExpectStreams(VideoFrameType::kVideoFrameDelta, 2); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + // We should only get the first stream and padding for two. + SetRates(kTargetBitrates[0] + kMinBitrates[1] / 2, 30); + ExpectStreams(VideoFrameType::kVideoFrameDelta, 1); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + // We don't have enough bitrate for the thumbnail stream, but we should get + // it anyway with current configuration. + SetRates(kTargetBitrates[0] - 1, 30); + ExpectStreams(VideoFrameType::kVideoFrameDelta, 1); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + // We should only get two streams and padding for one. + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] / 2, 30); + // We get a key frame because a new stream is being enabled. + ExpectStreams(VideoFrameType::kVideoFrameKey, 2); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + // We should get all three streams. + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kTargetBitrates[2], 30); + // We get a key frame because a new stream is being enabled. + ExpectStreams(VideoFrameType::kVideoFrameKey, 3); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestActiveStreams() { + // All streams on. + RunActiveStreamsTest({true, true, true}); + // All streams off. + RunActiveStreamsTest({false, false, false}); + // Low stream off. + RunActiveStreamsTest({false, true, true}); + // Middle stream off. + RunActiveStreamsTest({true, false, true}); + // High stream off. + RunActiveStreamsTest({true, true, false}); + // Only low stream turned on. + RunActiveStreamsTest({true, false, false}); + // Only middle stream turned on. + RunActiveStreamsTest({false, true, false}); + // Only high stream turned on. + RunActiveStreamsTest({false, false, true}); +} + +void SimulcastTestFixtureImpl::SwitchingToOneStream(int width, int height) { + const int* temporal_layer_profile = nullptr; + // Disable all streams except the last and set the bitrate of the last to + // 100 kbps. This verifies the way GTP switches to screenshare mode. + if (codec_type_ == kVideoCodecVP8) { + settings_.VP8()->numberOfTemporalLayers = 1; + temporal_layer_profile = kDefaultTemporalLayerProfile; + } else { + temporal_layer_profile = kNoTemporalLayerProfile; + } + settings_.maxBitrate = 100; + settings_.startBitrate = 100; + settings_.width = width; + settings_.height = height; + for (int i = 0; i < settings_.numberOfSimulcastStreams - 1; ++i) { + settings_.simulcastStream[i].maxBitrate = 0; + settings_.simulcastStream[i].width = settings_.width; + settings_.simulcastStream[i].height = settings_.height; + settings_.simulcastStream[i].numberOfTemporalLayers = 1; + } + // Setting input image to new resolution. + input_buffer_ = I420Buffer::Create(settings_.width, settings_.height); + input_buffer_->InitializeData(); + + input_frame_ = std::make_unique( + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(input_buffer_) + .set_rotation(webrtc::kVideoRotation_0) + .set_timestamp_us(0) + .build()); + + // The for loop above did not set the bitrate of the highest layer. + settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].maxBitrate = + 0; + // The highest layer has to correspond to the non-simulcast resolution. + settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].width = + settings_.width; + settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].height = + settings_.height; + SetUpRateAllocator(); + EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings)); + + // Encode one frame and verify. + SetRates(kMaxBitrates[0] + kMaxBitrates[1], 30); + std::vector frame_types(kNumberOfSimulcastStreams, + VideoFrameType::kVideoFrameDelta); + EXPECT_CALL( + encoder_callback_, + OnEncodedImage(AllOf(Field(&EncodedImage::_frameType, + VideoFrameType::kVideoFrameKey), + Field(&EncodedImage::_encodedWidth, width), + Field(&EncodedImage::_encodedHeight, height)), + _)) + .Times(1) + .WillRepeatedly(Return( + EncodedImageCallback::Result(EncodedImageCallback::Result::OK, 0))); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); + + // Switch back. + DefaultSettings(&settings_, temporal_layer_profile, codec_type_); + // Start at the lowest bitrate for enabling base stream. + settings_.startBitrate = kMinBitrates[0]; + SetUpRateAllocator(); + EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings)); + SetRates(settings_.startBitrate, 30); + ExpectStreams(VideoFrameType::kVideoFrameKey, 1); + // Resize |input_frame_| to the new resolution. + input_buffer_ = I420Buffer::Create(settings_.width, settings_.height); + input_buffer_->InitializeData(); + input_frame_ = std::make_unique( + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(input_buffer_) + .set_rotation(webrtc::kVideoRotation_0) + .set_timestamp_us(0) + .build()); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, &frame_types)); +} + +void SimulcastTestFixtureImpl::TestSwitchingToOneStream() { + SwitchingToOneStream(1024, 768); +} + +void SimulcastTestFixtureImpl::TestSwitchingToOneOddStream() { + SwitchingToOneStream(1023, 769); +} + +void SimulcastTestFixtureImpl::TestSwitchingToOneSmallStream() { + SwitchingToOneStream(4, 4); +} + +// Test the layer pattern and sync flag for various spatial-temporal patterns. +// 3-3-3 pattern: 3 temporal layers for all spatial streams, so same +// temporal_layer id and layer_sync is expected for all streams. +void SimulcastTestFixtureImpl::TestSpatioTemporalLayers333PatternEncoder() { + bool is_h264 = codec_type_ == kVideoCodecH264; + TestEncodedImageCallback encoder_callback; + encoder_->RegisterEncodeCompleteCallback(&encoder_callback); + SetRates(kMaxBitrates[2], 30); // To get all three streams. + + int expected_temporal_idx[3] = {-1, -1, -1}; + bool expected_layer_sync[3] = {false, false, false}; + + // First frame: #0. + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(0, 0, 0, expected_temporal_idx); + SetExpectedValues3(!is_h264, !is_h264, !is_h264, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #1. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(2, 2, 2, expected_temporal_idx); + SetExpectedValues3(true, true, true, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #2. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(1, 1, 1, expected_temporal_idx); + SetExpectedValues3(true, true, true, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #3. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(2, 2, 2, expected_temporal_idx); + SetExpectedValues3(false, false, false, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #4. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(0, 0, 0, expected_temporal_idx); + SetExpectedValues3(false, false, false, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #5. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(2, 2, 2, expected_temporal_idx); + SetExpectedValues3(is_h264, is_h264, is_h264, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); +} + +// Test the layer pattern and sync flag for various spatial-temporal patterns. +// 3-2-1 pattern: 3 temporal layers for lowest resolution, 2 for middle, and +// 1 temporal layer for highest resolution. +// For this profile, we expect the temporal index pattern to be: +// 1st stream: 0, 2, 1, 2, .... +// 2nd stream: 0, 1, 0, 1, ... +// 3rd stream: -1, -1, -1, -1, .... +// Regarding the 3rd stream, note that a stream/encoder with 1 temporal layer +// should always have temporal layer idx set to kNoTemporalIdx = -1. +// Since CodecSpecificInfoVP8.temporalIdx is uint8_t, this will wrap to 255. +// TODO(marpan): Although this seems safe for now, we should fix this. +void SimulcastTestFixtureImpl::TestSpatioTemporalLayers321PatternEncoder() { + EXPECT_EQ(codec_type_, kVideoCodecVP8); + int temporal_layer_profile[3] = {3, 2, 1}; + SetUpCodec(temporal_layer_profile); + TestEncodedImageCallback encoder_callback; + encoder_->RegisterEncodeCompleteCallback(&encoder_callback); + SetRates(kMaxBitrates[2], 30); // To get all three streams. + + int expected_temporal_idx[3] = {-1, -1, -1}; + bool expected_layer_sync[3] = {false, false, false}; + + // First frame: #0. + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(0, 0, 255, expected_temporal_idx); + SetExpectedValues3(true, true, false, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #1. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(2, 1, 255, expected_temporal_idx); + SetExpectedValues3(true, true, false, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #2. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(1, 0, 255, expected_temporal_idx); + SetExpectedValues3(true, false, false, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #3. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(2, 1, 255, expected_temporal_idx); + SetExpectedValues3(false, false, false, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #4. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(0, 0, 255, expected_temporal_idx); + SetExpectedValues3(false, false, false, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); + + // Next frame: #5. + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + SetExpectedValues3(2, 1, 255, expected_temporal_idx); + SetExpectedValues3(false, true, false, expected_layer_sync); + VerifyTemporalIdxAndSyncForAllSpatialLayers( + &encoder_callback, expected_temporal_idx, expected_layer_sync, 3); +} + +void SimulcastTestFixtureImpl::TestStrideEncodeDecode() { + TestEncodedImageCallback encoder_callback; + TestDecodedImageCallback decoder_callback; + encoder_->RegisterEncodeCompleteCallback(&encoder_callback); + decoder_->RegisterDecodeCompleteCallback(&decoder_callback); + + SetRates(kMaxBitrates[2], 30); // To get all three streams. + // Setting two (possibly) problematic use cases for stride: + // 1. stride > width 2. stride_y != stride_uv/2 + int stride_y = kDefaultWidth + 20; + int stride_uv = ((kDefaultWidth + 1) / 2) + 5; + input_buffer_ = I420Buffer::Create(kDefaultWidth, kDefaultHeight, stride_y, + stride_uv, stride_uv); + input_frame_ = std::make_unique( + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(input_buffer_) + .set_rotation(webrtc::kVideoRotation_0) + .set_timestamp_us(0) + .build()); + + // Set color. + int plane_offset[kNumOfPlanes]; + plane_offset[kYPlane] = kColorY; + plane_offset[kUPlane] = kColorU; + plane_offset[kVPlane] = kColorV; + CreateImage(input_buffer_, plane_offset); + + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + + // Change color. + plane_offset[kYPlane] += 1; + plane_offset[kUPlane] += 1; + plane_offset[kVPlane] += 1; + CreateImage(input_buffer_, plane_offset); + input_frame_->set_timestamp(input_frame_->timestamp() + 3000); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + + EncodedImage encoded_frame; + // Only encoding one frame - so will be a key frame. + encoder_callback.GetLastEncodedKeyFrame(&encoded_frame); + EXPECT_EQ(0, decoder_->Decode(encoded_frame, false, 0)); + encoder_callback.GetLastEncodedFrame(&encoded_frame); + decoder_->Decode(encoded_frame, false, 0); + EXPECT_EQ(2, decoder_callback.DecodedFrames()); +} + +void SimulcastTestFixtureImpl::TestDecodeWidthHeightSet() { + MockEncodedImageCallback encoder_callback; + MockDecodedImageCallback decoder_callback; + + EncodedImage encoded_frame[3]; + SetRates(kMaxBitrates[2], 30); // To get all three streams. + encoder_->RegisterEncodeCompleteCallback(&encoder_callback); + decoder_->RegisterDecodeCompleteCallback(&decoder_callback); + + EXPECT_CALL(encoder_callback, OnEncodedImage(_, _)) + .Times(3) + .WillRepeatedly( + ::testing::Invoke([&](const EncodedImage& encoded_image, + const CodecSpecificInfo* codec_specific_info) { + EXPECT_EQ(encoded_image._frameType, VideoFrameType::kVideoFrameKey); + + size_t index = encoded_image.SpatialIndex().value_or(0); + encoded_frame[index].SetEncodedData(EncodedImageBuffer::Create( + encoded_image.data(), encoded_image.size())); + encoded_frame[index]._frameType = encoded_image._frameType; + return EncodedImageCallback::Result( + EncodedImageCallback::Result::OK, 0); + })); + EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL)); + + EXPECT_CALL(decoder_callback, Decoded(_, _, _)) + .WillOnce(::testing::Invoke([](VideoFrame& decodedImage, + absl::optional decode_time_ms, + absl::optional qp) { + EXPECT_EQ(decodedImage.width(), kDefaultWidth / 4); + EXPECT_EQ(decodedImage.height(), kDefaultHeight / 4); + })); + EXPECT_EQ(0, decoder_->Decode(encoded_frame[0], false, 0)); + + EXPECT_CALL(decoder_callback, Decoded(_, _, _)) + .WillOnce(::testing::Invoke([](VideoFrame& decodedImage, + absl::optional decode_time_ms, + absl::optional qp) { + EXPECT_EQ(decodedImage.width(), kDefaultWidth / 2); + EXPECT_EQ(decodedImage.height(), kDefaultHeight / 2); + })); + EXPECT_EQ(0, decoder_->Decode(encoded_frame[1], false, 0)); + + EXPECT_CALL(decoder_callback, Decoded(_, _, _)) + .WillOnce(::testing::Invoke([](VideoFrame& decodedImage, + absl::optional decode_time_ms, + absl::optional qp) { + EXPECT_EQ(decodedImage.width(), kDefaultWidth); + EXPECT_EQ(decodedImage.height(), kDefaultHeight); + })); + EXPECT_EQ(0, decoder_->Decode(encoded_frame[2], false, 0)); +} + +void SimulcastTestFixtureImpl:: + TestEncoderInfoForDefaultTemporalLayerProfileHasFpsAllocation() { + VideoEncoder::EncoderInfo encoder_info = encoder_->GetEncoderInfo(); + EXPECT_EQ(encoder_info.fps_allocation[0].size(), + static_cast(kDefaultTemporalLayerProfile[0])); + EXPECT_EQ(encoder_info.fps_allocation[1].size(), + static_cast(kDefaultTemporalLayerProfile[1])); + EXPECT_EQ(encoder_info.fps_allocation[2].size(), + static_cast(kDefaultTemporalLayerProfile[2])); +} +} // namespace test +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_test_fixture_impl.h b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_test_fixture_impl.h new file mode 100644 index 000000000..a3d3fc66a --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/utility/simulcast_test_fixture_impl.h @@ -0,0 +1,93 @@ +/* + * 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. + */ + +#ifndef MODULES_VIDEO_CODING_UTILITY_SIMULCAST_TEST_FIXTURE_IMPL_H_ +#define MODULES_VIDEO_CODING_UTILITY_SIMULCAST_TEST_FIXTURE_IMPL_H_ + +#include +#include + +#include "api/test/mock_video_decoder.h" +#include "api/test/mock_video_encoder.h" +#include "api/test/simulcast_test_fixture.h" +#include "api/video/i420_buffer.h" +#include "api/video/video_frame.h" +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_encoder_factory.h" +#include "modules/video_coding/utility/simulcast_rate_allocator.h" + +namespace webrtc { +namespace test { + +class SimulcastTestFixtureImpl final : public SimulcastTestFixture { + public: + SimulcastTestFixtureImpl(std::unique_ptr encoder_factory, + std::unique_ptr decoder_factory, + SdpVideoFormat video_format); + ~SimulcastTestFixtureImpl() final; + + // Implements SimulcastTestFixture. + void TestKeyFrameRequestsOnAllStreams() override; + void TestPaddingAllStreams() override; + void TestPaddingTwoStreams() override; + void TestPaddingTwoStreamsOneMaxedOut() override; + void TestPaddingOneStream() override; + void TestPaddingOneStreamTwoMaxedOut() override; + void TestSendAllStreams() override; + void TestDisablingStreams() override; + void TestActiveStreams() override; + void TestSwitchingToOneStream() override; + void TestSwitchingToOneOddStream() override; + void TestSwitchingToOneSmallStream() override; + void TestSpatioTemporalLayers333PatternEncoder() override; + void TestSpatioTemporalLayers321PatternEncoder() override; + void TestStrideEncodeDecode() override; + void TestDecodeWidthHeightSet() override; + void TestEncoderInfoForDefaultTemporalLayerProfileHasFpsAllocation() override; + + static void DefaultSettings(VideoCodec* settings, + const int* temporal_layer_profile, + VideoCodecType codec_type, + bool reverse_layer_order = false); + + private: + class TestEncodedImageCallback; + class TestDecodedImageCallback; + + void SetUpCodec(const int* temporal_layer_profile); + void SetUpRateAllocator(); + void SetRates(uint32_t bitrate_kbps, uint32_t fps); + void RunActiveStreamsTest(const std::vector active_streams); + void UpdateActiveStreams(const std::vector active_streams); + void ExpectStreams(VideoFrameType frame_type, + const std::vector expected_streams_active); + void ExpectStreams(VideoFrameType frame_type, int expected_video_streams); + void VerifyTemporalIdxAndSyncForAllSpatialLayers( + TestEncodedImageCallback* encoder_callback, + const int* expected_temporal_idx, + const bool* expected_layer_sync, + int num_spatial_layers); + void SwitchingToOneStream(int width, int height); + + std::unique_ptr encoder_; + MockEncodedImageCallback encoder_callback_; + std::unique_ptr decoder_; + MockDecodedImageCallback decoder_callback_; + VideoCodec settings_; + rtc::scoped_refptr input_buffer_; + std::unique_ptr input_frame_; + std::unique_ptr rate_allocator_; + VideoCodecType codec_type_; +}; + +} // namespace test +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_UTILITY_SIMULCAST_TEST_FIXTURE_IMPL_H_ diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/video_codec_initializer.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/video_codec_initializer.cc index 2859dd022..4777fe51c 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/video_codec_initializer.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/video_codec_initializer.cc @@ -94,8 +94,9 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( int max_framerate = 0; + absl::optional scalability_mode = streams[0].scalability_mode; for (size_t i = 0; i < streams.size(); ++i) { - SimulcastStream* sim_stream = &video_codec.simulcastStream[i]; + SpatialLayer* sim_stream = &video_codec.simulcastStream[i]; RTC_DCHECK_GT(streams[i].width, 0); RTC_DCHECK_GT(streams[i].height, 0); RTC_DCHECK_GT(streams[i].max_framerate, 0); @@ -126,6 +127,15 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( video_codec.qpMax = std::max(video_codec.qpMax, static_cast(streams[i].max_qp)); max_framerate = std::max(max_framerate, streams[i].max_framerate); + + if (streams[0].scalability_mode != streams[i].scalability_mode) { + RTC_LOG(LS_WARNING) << "Inconsistent scalability modes configured."; + scalability_mode.reset(); + } + } + + if (scalability_mode.has_value()) { + video_codec.SetScalabilityMode(*scalability_mode); } if (video_codec.maxBitrate == 0) { @@ -210,7 +220,7 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( for (size_t spatial_idx = first_active_layer; spatial_idx < config.simulcast_layers.size() && - spatial_idx < spatial_layers.size(); + spatial_idx < spatial_layers.size() + first_active_layer; ++spatial_idx) { spatial_layers[spatial_idx - first_active_layer].active = config.simulcast_layers[spatial_idx].active; diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_coding/video_receiver.cc b/TMessagesProj/jni/voip/webrtc/modules/video_coding/video_receiver.cc index 01fb378af..c2c8f8aa1 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_coding/video_receiver.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_coding/video_receiver.cc @@ -16,7 +16,6 @@ #include "api/rtp_headers.h" #include "api/video_codecs/video_codec.h" #include "api/video_codecs/video_decoder.h" -#include "modules/include/module_common_types.h" #include "modules/utility/include/process_thread.h" #include "modules/video_coding/decoder_database.h" #include "modules/video_coding/encoded_frame.h" @@ -209,9 +208,7 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { clock_->TimeInMilliseconds()); if (first_frame_received_()) { - RTC_LOG(LS_INFO) << "Received first " - << (frame->Complete() ? "complete" : "incomplete") - << " decodable video frame"; + RTC_LOG(LS_INFO) << "Received first complete decodable video frame"; } const int32_t ret = Decode(*frame); diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_processing/util/denoiser_filter.cc b/TMessagesProj/jni/voip/webrtc/modules/video_processing/util/denoiser_filter.cc index d6b5094a5..0e1570114 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_processing/util/denoiser_filter.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_processing/util/denoiser_filter.cc @@ -41,7 +41,7 @@ std::unique_ptr DenoiserFilter::Create( filter.reset(new DenoiserFilterSSE2()); #else // x86 CPU detection required. - if (WebRtc_GetCPUInfo(kSSE2)) { + if (GetCPUInfo(kSSE2)) { filter.reset(new DenoiserFilterSSE2()); } else { filter.reset(new DenoiserFilterC()); diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_processing/video_denoiser.cc b/TMessagesProj/jni/voip/webrtc/modules/video_processing/video_denoiser.cc index 40568a5ec..3a1812514 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_processing/video_denoiser.cc +++ b/TMessagesProj/jni/voip/webrtc/modules/video_processing/video_denoiser.cc @@ -235,7 +235,7 @@ rtc::scoped_refptr VideoDenoiser::DenoiseFrame( const uint8_t* y_src = frame->DataY(); int stride_y_src = frame->StrideY(); rtc::scoped_refptr dst = - buffer_pool_.CreateBuffer(width_, height_); + buffer_pool_.CreateI420Buffer(width_, height_); uint8_t* y_dst = dst->MutableDataY(); int stride_y_dst = dst->StrideY(); diff --git a/TMessagesProj/jni/voip/webrtc/modules/video_processing/video_denoiser.h b/TMessagesProj/jni/voip/webrtc/modules/video_processing/video_denoiser.h index 37d624bb2..eb98c5bc5 100644 --- a/TMessagesProj/jni/voip/webrtc/modules/video_processing/video_denoiser.h +++ b/TMessagesProj/jni/voip/webrtc/modules/video_processing/video_denoiser.h @@ -15,7 +15,7 @@ #include "api/scoped_refptr.h" #include "api/video/video_frame_buffer.h" -#include "common_video/include/i420_buffer_pool.h" +#include "common_video/include/video_frame_buffer_pool.h" #include "modules/video_processing/util/denoiser_filter.h" #include "modules/video_processing/util/noise_estimation.h" #include "modules/video_processing/util/skin_detection.h" @@ -77,7 +77,7 @@ class VideoDenoiser { std::unique_ptr y_density_; // Save the return values by MbDenoise for each block. std::unique_ptr mb_filter_decision_; - I420BufferPool buffer_pool_; + VideoFrameBufferPool buffer_pool_; rtc::scoped_refptr prev_buffer_; }; diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/connection.cc b/TMessagesProj/jni/voip/webrtc/p2p/base/connection.cc index 0863865a0..fe6042102 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/connection.cc +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/connection.cc @@ -187,13 +187,13 @@ void ConnectionRequest::Prepare(StunMessage* request) { uint32_t network_info = connection_->port()->Network()->id(); network_info = (network_info << 16) | connection_->port()->network_cost(); request->AddAttribute(std::make_unique( - STUN_ATTR_NETWORK_INFO, network_info)); + STUN_ATTR_GOOG_NETWORK_INFO, network_info)); if (webrtc::field_trial::IsEnabled( "WebRTC-PiggybackIceCheckAcknowledgement") && connection_->last_ping_id_received()) { request->AddAttribute(std::make_unique( - STUN_ATTR_LAST_ICE_CHECK_RECEIVED, + STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED, connection_->last_ping_id_received().value())); } @@ -616,7 +616,7 @@ void Connection::HandleStunBindingOrGoogPingRequest(IceMessage* msg) { // Note: If packets are re-ordered, we may get incorrect network cost // temporarily, but it should get the correct value shortly after that. const StunUInt32Attribute* network_attr = - msg->GetUInt32(STUN_ATTR_NETWORK_INFO); + msg->GetUInt32(STUN_ATTR_GOOG_NETWORK_INFO); if (network_attr) { uint32_t network_info = network_attr->value(); uint16_t network_cost = static_cast(network_info); @@ -868,7 +868,7 @@ void Connection::HandlePiggybackCheckAcknowledgementIfAny(StunMessage* msg) { RTC_DCHECK(msg->type() == STUN_BINDING_REQUEST || msg->type() == GOOG_PING_REQUEST); const StunByteStringAttribute* last_ice_check_received_attr = - msg->GetByteString(STUN_ATTR_LAST_ICE_CHECK_RECEIVED); + msg->GetByteString(STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED); if (last_ice_check_received_attr) { const std::string request_id = last_ice_check_received_attr->GetString(); auto iter = absl::c_find_if( diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/connection.h b/TMessagesProj/jni/voip/webrtc/p2p/base/connection.h index 4b71a7da5..88e930c21 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/connection.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/connection.h @@ -65,13 +65,13 @@ class ConnectionRequest : public StunRequest { int resend_delay() override; private: - Connection* connection_; + Connection* const connection_; }; // Represents a communication link between a port on the local client and a // port on the remote client. class Connection : public CandidatePairInterface, - public rtc::MessageHandler, + public rtc::MessageHandlerAutoCleanup, public sigslot::has_slots<> { public: struct SentPing { diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/dtls_transport.cc b/TMessagesProj/jni/voip/webrtc/p2p/base/dtls_transport.cc index 1b7a66000..52fe5c65a 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/dtls_transport.cc +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/dtls_transport.cc @@ -73,6 +73,8 @@ rtc::StreamResult StreamInterfaceChannel::Read(void* buffer, size_t buffer_len, size_t* read, int* error) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + if (state_ == rtc::SS_CLOSED) return rtc::SR_EOS; if (state_ == rtc::SS_OPENING) @@ -89,6 +91,7 @@ rtc::StreamResult StreamInterfaceChannel::Write(const void* data, size_t data_len, size_t* written, int* error) { + RTC_DCHECK_RUN_ON(&sequence_checker_); // Always succeeds, since this is an unreliable transport anyway. // TODO(zhihuang): Should this block if ice_transport_'s temporarily // unwritable? @@ -102,6 +105,7 @@ rtc::StreamResult StreamInterfaceChannel::Write(const void* data, } bool StreamInterfaceChannel::OnPacketReceived(const char* data, size_t size) { + RTC_DCHECK_RUN_ON(&sequence_checker_); if (packets_.size() > 0) { RTC_LOG(LS_WARNING) << "Packet already in queue."; } @@ -118,10 +122,12 @@ bool StreamInterfaceChannel::OnPacketReceived(const char* data, size_t size) { } rtc::StreamState StreamInterfaceChannel::GetState() const { + RTC_DCHECK_RUN_ON(&sequence_checker_); return state_; } void StreamInterfaceChannel::Close() { + RTC_DCHECK_RUN_ON(&sequence_checker_); packets_.Clear(); state_ = rtc::SS_CLOSED; } diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/dtls_transport.h b/TMessagesProj/jni/voip/webrtc/p2p/base/dtls_transport.h index 89156a15d..430c91233 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/dtls_transport.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/dtls_transport.h @@ -24,6 +24,7 @@ #include "rtc_base/ssl_stream_adapter.h" #include "rtc_base/stream.h" #include "rtc_base/strings/string_builder.h" +#include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/thread_checker.h" namespace rtc { @@ -54,9 +55,10 @@ class StreamInterfaceChannel : public rtc::StreamInterface { int* error) override; private: - IceTransportInternal* ice_transport_; // owned by DtlsTransport - rtc::StreamState state_; - rtc::BufferQueue packets_; + webrtc::SequenceChecker sequence_checker_; + IceTransportInternal* const ice_transport_; // owned by DtlsTransport + rtc::StreamState state_ RTC_GUARDED_BY(sequence_checker_); + rtc::BufferQueue packets_ RTC_GUARDED_BY(sequence_checker_); RTC_DISALLOW_COPY_AND_ASSIGN(StreamInterfaceChannel); }; diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel.cc b/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel.cc index 6f0df0415..9bf0b23db 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel.cc +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel.cc @@ -696,6 +696,9 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { // Make sure that nomination reaching ICE controlled asap. "send_ping_on_switch_ice_controlling", &field_trials_.send_ping_on_switch_ice_controlling, + // Make sure that nomination reaching ICE controlled asap. + "send_ping_on_selected_ice_controlling", + &field_trials_.send_ping_on_selected_ice_controlling, // Reply to nomination ASAP. "send_ping_on_nomination_ice_controlled", &field_trials_.send_ping_on_nomination_ice_controlled, @@ -1013,7 +1016,7 @@ void P2PTransportChannel::OnUnknownAddress(PortInterface* port, uint16_t network_id = 0; uint16_t network_cost = 0; const StunUInt32Attribute* network_attr = - stun_msg->GetUInt32(STUN_ATTR_NETWORK_INFO); + stun_msg->GetUInt32(STUN_ATTR_GOOG_NETWORK_INFO); if (network_attr) { uint32_t network_info = network_attr->value(); network_id = static_cast(network_info >> 16); @@ -1768,9 +1771,10 @@ void P2PTransportChannel::SwitchSelectedConnection(Connection* conn, RTC_LOG(LS_INFO) << ToString() << ": No selected connection"; } - if (field_trials_.send_ping_on_switch_ice_controlling && - ice_role_ == ICEROLE_CONTROLLING && old_selected_connection != nullptr && - conn != nullptr) { + if (conn != nullptr && ice_role_ == ICEROLE_CONTROLLING && + ((field_trials_.send_ping_on_switch_ice_controlling && + old_selected_connection != nullptr) || + field_trials_.send_ping_on_selected_ice_controlling)) { PingConnection(conn); MarkConnectionPinged(conn); } @@ -1784,6 +1788,15 @@ void P2PTransportChannel::SwitchSelectedConnection(Connection* conn, pair_change.selected_candidate_pair = *GetSelectedCandidatePair(); pair_change.last_data_received_ms = selected_connection_->last_data_received(); + + if (old_selected_connection) { + pair_change.estimated_disconnected_time_ms = + ComputeEstimatedDisconnectedTimeMs(rtc::TimeMillis(), + old_selected_connection); + } else { + pair_change.estimated_disconnected_time_ms = 0; + } + SignalCandidatePairChanged(pair_change); } @@ -1792,6 +1805,16 @@ void P2PTransportChannel::SwitchSelectedConnection(Connection* conn, ice_controller_->SetSelectedConnection(selected_connection_); } +int64_t P2PTransportChannel::ComputeEstimatedDisconnectedTimeMs( + int64_t now_ms, + Connection* old_connection) { + // TODO(jonaso): nicer keeps estimate of how frequently data _should_ be + // received, this could be used to give better estimate (if needed). + int64_t last_data_or_old_ping = + std::max(old_connection->last_received(), last_data_received_ms_); + return (now_ms - last_data_or_old_ping); +} + // Warning: UpdateState should eventually be called whenever a connection // is added, deleted, or the write state of any connection changes so that the // transport controller will get the up-to-date channel state. However it @@ -2110,6 +2133,9 @@ void P2PTransportChannel::OnReadPacket(Connection* connection, if (connection == selected_connection_) { // Let the client know of an incoming packet + RTC_DCHECK(connection->last_data_received() >= last_data_received_ms_); + last_data_received_ms_ = + std::max(last_data_received_ms_, connection->last_data_received()); SignalReadPacket(this, data, len, packet_time_us, 0); return; } @@ -2118,6 +2144,10 @@ void P2PTransportChannel::OnReadPacket(Connection* connection, if (!FindConnection(connection)) return; + RTC_DCHECK(connection->last_data_received() >= last_data_received_ms_); + last_data_received_ms_ = + std::max(last_data_received_ms_, connection->last_data_received()); + // Let the client know of an incoming packet SignalReadPacket(this, data, len, packet_time_us, 0); diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel.h b/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel.h index 4f891beb1..69a32e462 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel.h @@ -358,6 +358,9 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal { return const_cast(conn); } + int64_t ComputeEstimatedDisconnectedTimeMs(int64_t now, + Connection* old_connection); + std::string transport_name_ RTC_GUARDED_BY(network_thread_); int component_ RTC_GUARDED_BY(network_thread_); PortAllocator* allocator_ RTC_GUARDED_BY(network_thread_); @@ -440,6 +443,10 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal { // Number of times the selected_connection_ has been modified. uint32_t selected_candidate_pair_changes_ = 0; + // When was last data received on a existing connection, + // from connection->last_data_received() that uses rtc::TimeMillis(). + int64_t last_data_received_ms_ = 0; + IceFieldTrials field_trials_; RTC_DISALLOW_COPY_AND_ASSIGN(P2PTransportChannel); diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel_ice_field_trials.h b/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel_ice_field_trials.h index f30366fd1..00e1151ba 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel_ice_field_trials.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/p2p_transport_channel_ice_field_trials.h @@ -44,8 +44,14 @@ struct IceFieldTrials { int rtt_estimate_halftime_ms = 500; // Sending a PING directly after a switch on ICE_CONTROLLING-side. + // TODO(jonaso) : Deprecate this in favor of + // |send_ping_on_selected_ice_controlling|. bool send_ping_on_switch_ice_controlling = false; + // Sending a PING directly after selecting a connection + // (i.e either a switch or the inital selection). + bool send_ping_on_selected_ice_controlling = false; + // Sending a PING directly after a nomination on ICE_CONTROLLED-side. bool send_ping_on_nomination_ice_controlled = false; diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/port.h b/TMessagesProj/jni/voip/webrtc/p2p/base/port.h index 893e80b20..1e20d1346 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/port.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/port.h @@ -150,6 +150,8 @@ struct CandidatePairChangeEvent { CandidatePair selected_candidate_pair; int64_t last_data_received_ms; std::string reason; + // How long do we estimate that we've been disconnected. + int64_t estimated_disconnected_time_ms; }; typedef std::set ServerAddresses; @@ -158,7 +160,7 @@ typedef std::set ServerAddresses; // connections to similar mechanisms of the other client. Subclasses of this // one add support for specific mechanisms like local UDP ports. class Port : public PortInterface, - public rtc::MessageHandler, + public rtc::MessageHandlerAutoCleanup, public sigslot::has_slots<> { public: // INIT: The state when a port is just created. diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/pseudo_tcp.cc b/TMessagesProj/jni/voip/webrtc/p2p/base/pseudo_tcp.cc index 56e6b9b6a..13e7a2214 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/pseudo_tcp.cc +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/pseudo_tcp.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -402,9 +403,7 @@ uint32_t PseudoTcp::GetBytesInFlight() const { } uint32_t PseudoTcp::GetBytesBufferedNotSent() const { - size_t buffered_bytes = 0; - m_sbuf.GetBuffered(&buffered_bytes); - return static_cast(m_snd_una + buffered_bytes - m_snd_nxt); + return static_cast(m_snd_una + m_sbuf.GetBuffered() - m_snd_nxt); } uint32_t PseudoTcp::GetRoundTripTimeEstimateMs() const { @@ -422,15 +421,11 @@ int PseudoTcp::Recv(char* buffer, size_t len) { } size_t read = 0; - rtc::StreamResult result = m_rbuf.Read(buffer, len, &read, NULL); - - // If there's no data in |m_rbuf|. - if (result == rtc::SR_BLOCK) { + if (!m_rbuf.Read(buffer, len, &read)) { m_bReadEnable = true; m_error = EWOULDBLOCK; return SOCKET_ERROR; } - RTC_DCHECK(result == rtc::SR_SUCCESS); size_t available_space = 0; m_rbuf.GetWriteRemaining(&available_space); @@ -497,14 +492,13 @@ uint32_t PseudoTcp::queue(const char* data, uint32_t len, bool bCtrl) { (m_slist.back().xmit == 0)) { m_slist.back().len += len; } else { - size_t snd_buffered = 0; - m_sbuf.GetBuffered(&snd_buffered); - SSegment sseg(static_cast(m_snd_una + snd_buffered), len, bCtrl); + SSegment sseg(static_cast(m_snd_una + m_sbuf.GetBuffered()), len, + bCtrl); m_slist.push_back(sseg); } size_t written = 0; - m_sbuf.Write(data, len, &written, NULL); + m_sbuf.Write(data, len, &written); return static_cast(written); } @@ -532,9 +526,9 @@ IPseudoTcpNotify::WriteResult PseudoTcp::packet(uint32_t seq, if (len) { size_t bytes_read = 0; - rtc::StreamResult result = + bool result = m_sbuf.ReadOffset(buffer.get() + HEADER_SIZE, len, offset, &bytes_read); - RTC_DCHECK(result == rtc::SR_SUCCESS); + RTC_DCHECK(result); RTC_DCHECK(static_cast(bytes_read) == len); } @@ -601,11 +595,9 @@ bool PseudoTcp::clock_check(uint32_t now, long& nTimeout) { if (m_shutdown == SD_FORCEFUL) return false; - size_t snd_buffered = 0; - m_sbuf.GetBuffered(&snd_buffered); if ((m_shutdown == SD_GRACEFUL) && ((m_state != TCP_ESTABLISHED) || - ((snd_buffered == 0) && (m_t_ack == 0)))) { + ((m_sbuf.GetBuffered() == 0) && (m_t_ack == 0)))) { return false; } @@ -830,10 +822,8 @@ bool PseudoTcp::process(Segment& seg) { // The goal it to make sure we always have at least enough data to fill the // window. We'd like to notify the app when we are halfway to that point. const uint32_t kIdealRefillSize = (m_sbuf_len + m_rbuf_len) / 2; - size_t snd_buffered = 0; - m_sbuf.GetBuffered(&snd_buffered); if (m_bWriteEnable && - static_cast(snd_buffered) < kIdealRefillSize) { + static_cast(m_sbuf.GetBuffered()) < kIdealRefillSize) { m_bWriteEnable = false; if (m_notify) { m_notify->OnTcpWriteable(this); @@ -912,8 +902,7 @@ bool PseudoTcp::process(Segment& seg) { // there's not already data ready to read, but this should always be // true in the problematic scenario, since control frames are always // sent first in the stream. - size_t rcv_buffered; - if (m_rbuf.GetBuffered(&rcv_buffered) && rcv_buffered == 0) { + if (m_rbuf.GetBuffered() == 0) { m_rbuf.ConsumeWriteBuffer(seg.len); m_rbuf.ConsumeReadData(seg.len); // After shifting the position in the buffer, we may have @@ -924,15 +913,11 @@ bool PseudoTcp::process(Segment& seg) { } else { uint32_t nOffset = seg.seq - m_rcv_nxt; - rtc::StreamResult result = - m_rbuf.WriteOffset(seg.data, seg.len, nOffset, NULL); - if (result == rtc::SR_BLOCK) { + if (!m_rbuf.WriteOffset(seg.data, seg.len, nOffset, NULL)) { // Ignore incoming packets outside of the receive window. return false; } - RTC_DCHECK(result == rtc::SR_SUCCESS); - if (seg.seq == m_rcv_nxt) { m_rbuf.ConsumeWriteBuffer(seg.len); m_rcv_nxt += seg.len; @@ -1078,8 +1063,7 @@ void PseudoTcp::attemptSend(SendFlags sflags) { uint32_t nInFlight = m_snd_nxt - m_snd_una; uint32_t nUseable = (nInFlight < nWindow) ? (nWindow - nInFlight) : 0; - size_t snd_buffered = 0; - m_sbuf.GetBuffered(&snd_buffered); + size_t snd_buffered = m_sbuf.GetBuffered(); uint32_t nAvailable = std::min(static_cast(snd_buffered) - nInFlight, m_mss); @@ -1300,4 +1284,149 @@ void PseudoTcp::resizeReceiveBuffer(uint32_t new_size) { m_rcv_wnd = static_cast(available_space); } +PseudoTcp::LockedFifoBuffer::LockedFifoBuffer(size_t size) + : buffer_(new char[size]), + buffer_length_(size), + data_length_(0), + read_position_(0) {} + +PseudoTcp::LockedFifoBuffer::~LockedFifoBuffer() {} + +size_t PseudoTcp::LockedFifoBuffer::GetBuffered() const { + webrtc::MutexLock lock(&mutex_); + return data_length_; +} + +bool PseudoTcp::LockedFifoBuffer::SetCapacity(size_t size) { + webrtc::MutexLock lock(&mutex_); + if (data_length_ > size) + return false; + + if (size != buffer_length_) { + char* buffer = new char[size]; + const size_t copy = data_length_; + const size_t tail_copy = std::min(copy, buffer_length_ - read_position_); + memcpy(buffer, &buffer_[read_position_], tail_copy); + memcpy(buffer + tail_copy, &buffer_[0], copy - tail_copy); + buffer_.reset(buffer); + read_position_ = 0; + buffer_length_ = size; + } + + return true; +} + +bool PseudoTcp::LockedFifoBuffer::ReadOffset(void* buffer, + size_t bytes, + size_t offset, + size_t* bytes_read) { + webrtc::MutexLock lock(&mutex_); + return ReadOffsetLocked(buffer, bytes, offset, bytes_read); +} + +bool PseudoTcp::LockedFifoBuffer::WriteOffset(const void* buffer, + size_t bytes, + size_t offset, + size_t* bytes_written) { + webrtc::MutexLock lock(&mutex_); + return WriteOffsetLocked(buffer, bytes, offset, bytes_written); +} + +bool PseudoTcp::LockedFifoBuffer::Read(void* buffer, + size_t bytes, + size_t* bytes_read) { + webrtc::MutexLock lock(&mutex_); + size_t copy = 0; + if (!ReadOffsetLocked(buffer, bytes, 0, ©)) + return false; + + // If read was successful then adjust the read position and number of + // bytes buffered. + read_position_ = (read_position_ + copy) % buffer_length_; + data_length_ -= copy; + if (bytes_read) + *bytes_read = copy; + + return true; +} + +bool PseudoTcp::LockedFifoBuffer::Write(const void* buffer, + size_t bytes, + size_t* bytes_written) { + webrtc::MutexLock lock(&mutex_); + size_t copy = 0; + if (!WriteOffsetLocked(buffer, bytes, 0, ©)) + return false; + + // If write was successful then adjust the number of readable bytes. + data_length_ += copy; + if (bytes_written) { + *bytes_written = copy; + } + + return true; +} + +void PseudoTcp::LockedFifoBuffer::ConsumeReadData(size_t size) { + webrtc::MutexLock lock(&mutex_); + RTC_DCHECK(size <= data_length_); + read_position_ = (read_position_ + size) % buffer_length_; + data_length_ -= size; +} + +void PseudoTcp::LockedFifoBuffer::ConsumeWriteBuffer(size_t size) { + webrtc::MutexLock lock(&mutex_); + RTC_DCHECK(size <= buffer_length_ - data_length_); + data_length_ += size; +} + +bool PseudoTcp::LockedFifoBuffer::GetWriteRemaining(size_t* size) const { + webrtc::MutexLock lock(&mutex_); + *size = buffer_length_ - data_length_; + return true; +} + +bool PseudoTcp::LockedFifoBuffer::ReadOffsetLocked(void* buffer, + size_t bytes, + size_t offset, + size_t* bytes_read) { + if (offset >= data_length_) + return false; + + const size_t available = data_length_ - offset; + const size_t read_position = (read_position_ + offset) % buffer_length_; + const size_t copy = std::min(bytes, available); + const size_t tail_copy = std::min(copy, buffer_length_ - read_position); + char* const p = static_cast(buffer); + memcpy(p, &buffer_[read_position], tail_copy); + memcpy(p + tail_copy, &buffer_[0], copy - tail_copy); + + if (bytes_read) + *bytes_read = copy; + + return true; +} + +bool PseudoTcp::LockedFifoBuffer::WriteOffsetLocked(const void* buffer, + size_t bytes, + size_t offset, + size_t* bytes_written) { + if (data_length_ + offset >= buffer_length_) + return false; + + const size_t available = buffer_length_ - data_length_ - offset; + const size_t write_position = + (read_position_ + data_length_ + offset) % buffer_length_; + const size_t copy = std::min(bytes, available); + const size_t tail_copy = std::min(copy, buffer_length_ - write_position); + const char* const p = static_cast(buffer); + memcpy(&buffer_[write_position], p, tail_copy); + memcpy(&buffer_[0], p + tail_copy, copy - tail_copy); + + if (bytes_written) + *bytes_written = copy; + + return true; +} + } // namespace cricket diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/pseudo_tcp.h b/TMessagesProj/jni/voip/webrtc/p2p/base/pseudo_tcp.h index cb6d97449..74ffee631 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/pseudo_tcp.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/pseudo_tcp.h @@ -15,8 +15,9 @@ #include #include +#include -#include "rtc_base/memory/fifo_buffer.h" +#include "rtc_base/synchronization/mutex.h" #include "rtc_base/system/rtc_export.h" namespace cricket { @@ -196,6 +197,50 @@ class RTC_EXPORT PseudoTcp { // window scale factor |m_swnd_scale| accordingly. void resizeReceiveBuffer(uint32_t new_size); + class LockedFifoBuffer final { + public: + explicit LockedFifoBuffer(size_t size); + ~LockedFifoBuffer(); + + size_t GetBuffered() const; + bool SetCapacity(size_t size); + bool ReadOffset(void* buffer, + size_t bytes, + size_t offset, + size_t* bytes_read); + bool WriteOffset(const void* buffer, + size_t bytes, + size_t offset, + size_t* bytes_written); + bool Read(void* buffer, size_t bytes, size_t* bytes_read); + bool Write(const void* buffer, size_t bytes, size_t* bytes_written); + void ConsumeReadData(size_t size); + void ConsumeWriteBuffer(size_t size); + bool GetWriteRemaining(size_t* size) const; + + private: + bool ReadOffsetLocked(void* buffer, + size_t bytes, + size_t offset, + size_t* bytes_read) + RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + bool WriteOffsetLocked(const void* buffer, + size_t bytes, + size_t offset, + size_t* bytes_written) + RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // the allocated buffer + std::unique_ptr buffer_ RTC_GUARDED_BY(mutex_); + // size of the allocated buffer + size_t buffer_length_ RTC_GUARDED_BY(mutex_); + // amount of readable data in the buffer + size_t data_length_ RTC_GUARDED_BY(mutex_); + // offset to the readable data + size_t read_position_ RTC_GUARDED_BY(mutex_); + mutable webrtc::Mutex mutex_; + }; + IPseudoTcpNotify* m_notify; enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown; int m_error; @@ -211,13 +256,13 @@ class RTC_EXPORT PseudoTcp { RList m_rlist; uint32_t m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv; uint8_t m_rwnd_scale; // Window scale factor. - rtc::FifoBuffer m_rbuf; + LockedFifoBuffer m_rbuf; // Outgoing data SList m_slist; uint32_t m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una; uint8_t m_swnd_scale; // Window scale factor. - rtc::FifoBuffer m_sbuf; + LockedFifoBuffer m_sbuf; // Maximum segment size, estimated protocol level, largest segment sent uint32_t m_mss, m_msslevel, m_largest, m_mtu_advise; diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/stun_request.h b/TMessagesProj/jni/voip/webrtc/p2p/base/stun_request.h index d45376ea5..39f928eaf 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/stun_request.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/stun_request.h @@ -76,7 +76,7 @@ class StunRequestManager { private: typedef std::map RequestMap; - rtc::Thread* thread_; + rtc::Thread* const thread_; RequestMap requests_; std::string origin_; diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/turn_port.h b/TMessagesProj/jni/voip/webrtc/p2p/base/turn_port.h index 8247dbc77..a9ec43419 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/turn_port.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/turn_port.h @@ -33,6 +33,8 @@ class TurnCustomizer; namespace cricket { +const int kMaxTurnUsernameLength = 509; // RFC 8489 section 14.3 + extern const int STUN_ATTR_TURN_LOGGING_ID; extern const char TURN_PORT_TYPE[]; class TurnAllocateRequest; @@ -61,6 +63,10 @@ class TurnPort : public Port { int server_priority, const std::string& origin, webrtc::TurnCustomizer* customizer) { + // Do basic parameter validation. + if (credentials.username.size() > kMaxTurnUsernameLength) { + return nullptr; + } // Using `new` to access a non-public constructor. return absl::WrapUnique(new TurnPort( thread, factory, network, socket, username, password, server_address, @@ -102,6 +108,10 @@ class TurnPort : public Port { const std::vector& tls_elliptic_curves, webrtc::TurnCustomizer* customizer, rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr) { + // Do basic parameter validation. + if (credentials.username.size() > kMaxTurnUsernameLength) { + return nullptr; + } // Using `new` to access a non-public constructor. return absl::WrapUnique( new TurnPort(thread, factory, network, min_port, max_port, username, diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/turn_server.cc b/TMessagesProj/jni/voip/webrtc/p2p/base/turn_server.cc index 3a4784ac5..17a49e403 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/turn_server.cc +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/turn_server.cc @@ -59,7 +59,7 @@ enum { // Encapsulates a TURN permission. // The object is created when a create permission request is received by an // allocation, and self-deletes when its lifetime timer expires. -class TurnServerAllocation::Permission : public rtc::MessageHandler { +class TurnServerAllocation::Permission : public rtc::MessageHandlerAutoCleanup { public: Permission(rtc::Thread* thread, const rtc::IPAddress& peer); ~Permission() override; @@ -79,7 +79,7 @@ class TurnServerAllocation::Permission : public rtc::MessageHandler { // Encapsulates a TURN channel binding. // The object is created when a channel bind request is received by an // allocation, and self-deletes when its lifetime timer expires. -class TurnServerAllocation::Channel : public rtc::MessageHandler { +class TurnServerAllocation::Channel : public rtc::MessageHandlerAutoCleanup { public: Channel(rtc::Thread* thread, int id, const rtc::SocketAddress& peer); ~Channel() override; diff --git a/TMessagesProj/jni/voip/webrtc/p2p/base/turn_server.h b/TMessagesProj/jni/voip/webrtc/p2p/base/turn_server.h index 0f4fefea8..ca856448b 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/base/turn_server.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/base/turn_server.h @@ -66,7 +66,7 @@ class TurnServerConnection { // handles TURN messages (via HandleTurnMessage) and channel data messages // (via HandleChannelData) for this allocation when received by the server. // The object self-deletes and informs the server if its lifetime timer expires. -class TurnServerAllocation : public rtc::MessageHandler, +class TurnServerAllocation : public rtc::MessageHandlerAutoCleanup, public sigslot::has_slots<> { public: TurnServerAllocation(TurnServer* server_, diff --git a/TMessagesProj/jni/voip/webrtc/p2p/client/basic_port_allocator.h b/TMessagesProj/jni/voip/webrtc/p2p/client/basic_port_allocator.h index b27016a1d..26b181807 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/client/basic_port_allocator.h +++ b/TMessagesProj/jni/voip/webrtc/p2p/client/basic_port_allocator.h @@ -106,8 +106,9 @@ enum class SessionState { // process will be started. }; -class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession, - public rtc::MessageHandler { +class RTC_EXPORT BasicPortAllocatorSession + : public PortAllocatorSession, + public rtc::MessageHandlerAutoCleanup { public: BasicPortAllocatorSession(BasicPortAllocator* allocator, const std::string& content_name, @@ -323,7 +324,7 @@ class TurnPort; // Performs the allocation of ports, in a sequenced (timed) manner, for a given // network and IP address. -class AllocationSequence : public rtc::MessageHandler, +class AllocationSequence : public rtc::MessageHandlerAutoCleanup, public sigslot::has_slots<> { public: enum State { diff --git a/TMessagesProj/jni/voip/webrtc/p2p/client/turn_port_factory.cc b/TMessagesProj/jni/voip/webrtc/p2p/client/turn_port_factory.cc index de4b9e6a0..fd3420c01 100644 --- a/TMessagesProj/jni/voip/webrtc/p2p/client/turn_port_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/p2p/client/turn_port_factory.cc @@ -28,6 +28,8 @@ std::unique_ptr TurnPortFactory::Create( args.username, args.password, *args.server_address, args.config->credentials, args.config->priority, args.origin, args.turn_customizer); + if (!port) + return nullptr; port->SetTlsCertPolicy(args.config->tls_cert_policy); port->SetTurnLoggingId(args.config->turn_logging_id); return std::move(port); @@ -42,6 +44,8 @@ std::unique_ptr TurnPortFactory::Create(const CreateRelayPortArgs& args, args.config->credentials, args.config->priority, args.origin, args.config->tls_alpn_protocols, args.config->tls_elliptic_curves, args.turn_customizer, args.config->tls_cert_verifier); + if (!port) + return nullptr; port->SetTlsCertPolicy(args.config->tls_cert_policy); port->SetTurnLoggingId(args.config->turn_logging_id); return std::move(port); diff --git a/TMessagesProj/jni/voip/webrtc/pc/audio_rtp_receiver.cc b/TMessagesProj/jni/voip/webrtc/pc/audio_rtp_receiver.cc index 54912a5d7..8ff685d8e 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/audio_rtp_receiver.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/audio_rtp_receiver.cc @@ -42,8 +42,9 @@ AudioRtpReceiver::AudioRtpReceiver( : worker_thread_(worker_thread), id_(receiver_id), source_(new rtc::RefCountedObject(worker_thread)), - track_(AudioTrackProxy::Create(rtc::Thread::Current(), - AudioTrack::Create(receiver_id, source_))), + track_(AudioTrackProxyWithInternal::Create( + rtc::Thread::Current(), + AudioTrack::Create(receiver_id, source_))), cached_track_enabled_(track_->enabled()), attachment_id_(GenerateUniqueId()), delay_(JitterBufferDelayProxy::Create( @@ -146,6 +147,11 @@ void AudioRtpReceiver::Stop() { stopped_ = true; } +void AudioRtpReceiver::StopAndEndTrack() { + Stop(); + track_->internal()->set_ended(); +} + void AudioRtpReceiver::RestartMediaChannel(absl::optional ssrc) { RTC_DCHECK(media_channel_); if (!stopped_ && ssrc_ == ssrc) { diff --git a/TMessagesProj/jni/voip/webrtc/pc/audio_rtp_receiver.h b/TMessagesProj/jni/voip/webrtc/pc/audio_rtp_receiver.h index 88b16ee68..f4b821068 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/audio_rtp_receiver.h +++ b/TMessagesProj/jni/voip/webrtc/pc/audio_rtp_receiver.h @@ -19,10 +19,12 @@ #include "absl/types/optional.h" #include "api/crypto/frame_decryptor_interface.h" #include "api/media_stream_interface.h" +#include "api/media_stream_track_proxy.h" #include "api/media_types.h" #include "api/rtp_parameters.h" #include "api/scoped_refptr.h" #include "media/base/media_channel.h" +#include "pc/audio_track.h" #include "pc/jitter_buffer_delay_interface.h" #include "pc/remote_audio_source.h" #include "pc/rtp_receiver.h" @@ -84,6 +86,7 @@ class AudioRtpReceiver : public ObserverInterface, // RtpReceiverInternal implementation. void Stop() override; + void StopAndEndTrack() override; void SetupMediaChannel(uint32_t ssrc) override; void SetupUnsignaledMediaChannel() override; uint32_t ssrc() const override { return ssrc_.value_or(0); } @@ -116,7 +119,7 @@ class AudioRtpReceiver : public ObserverInterface, rtc::Thread* const worker_thread_; const std::string id_; const rtc::scoped_refptr source_; - const rtc::scoped_refptr track_; + const rtc::scoped_refptr> track_; cricket::VoiceMediaChannel* media_channel_ = nullptr; absl::optional ssrc_; std::vector> streams_; diff --git a/TMessagesProj/jni/voip/webrtc/pc/audio_track.cc b/TMessagesProj/jni/voip/webrtc/pc/audio_track.cc index ff680652c..4f4c6b475 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/audio_track.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/audio_track.cc @@ -39,7 +39,6 @@ AudioTrack::~AudioTrack() { } std::string AudioTrack::kind() const { - RTC_DCHECK(thread_checker_.IsCurrent()); return kAudioKind; } diff --git a/TMessagesProj/jni/voip/webrtc/pc/audio_track.h b/TMessagesProj/jni/voip/webrtc/pc/audio_track.h index f89bbcdd1..8cff79e8b 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/audio_track.h +++ b/TMessagesProj/jni/voip/webrtc/pc/audio_track.h @@ -14,9 +14,8 @@ #include #include "api/media_stream_interface.h" +#include "api/media_stream_track.h" #include "api/scoped_refptr.h" -#include "pc/media_stream_track.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/thread_checker.h" namespace webrtc { @@ -27,6 +26,11 @@ class AudioTrack : public MediaStreamTrack, // Protected ctor to force use of factory method. AudioTrack(const std::string& label, const rtc::scoped_refptr& source); + + AudioTrack() = delete; + AudioTrack(const AudioTrack&) = delete; + AudioTrack& operator=(const AudioTrack&) = delete; + ~AudioTrack() override; public: @@ -34,10 +38,10 @@ class AudioTrack : public MediaStreamTrack, const std::string& id, const rtc::scoped_refptr& source); - private: // MediaStreamTrack implementation. std::string kind() const override; + private: // AudioTrackInterface implementation. AudioSourceInterface* GetSource() const override; @@ -50,7 +54,6 @@ class AudioTrack : public MediaStreamTrack, private: const rtc::scoped_refptr audio_source_; rtc::ThreadChecker thread_checker_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioTrack); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/channel.cc b/TMessagesProj/jni/voip/webrtc/pc/channel.cc index eeba19b2c..02ee9d249 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/channel.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/channel.cc @@ -30,6 +30,7 @@ #include "rtc_base/logging.h" #include "rtc_base/network_route.h" #include "rtc_base/strings/string_builder.h" +#include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/trace_event.h" namespace cricket { @@ -206,7 +207,7 @@ void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) { } void BaseChannel::Deinit() { - RTC_DCHECK(worker_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(worker_thread()); media_channel_->SetInterface(/*iface=*/nullptr); // Packets arrive on the network thread, processing packets calls virtual // functions, so need to stop this process in Deinit that is called in @@ -289,6 +290,13 @@ bool BaseChannel::SetRemoteContent(const MediaContentDescription* content, Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc)); } +bool BaseChannel::SetPayloadTypeDemuxingEnabled(bool enabled) { + TRACE_EVENT0("webrtc", "BaseChannel::SetPayloadTypeDemuxingEnabled"); + return InvokeOnWorker( + RTC_FROM_HERE, + Bind(&BaseChannel::SetPayloadTypeDemuxingEnabled_w, this, enabled)); +} + bool BaseChannel::IsReadyToReceiveMedia_w() const { // Receive data if we are enabled and have local content, return enabled() && @@ -330,7 +338,7 @@ int BaseChannel::SetOption(SocketType type, int BaseChannel::SetOption_n(SocketType type, rtc::Socket::Option opt, int value) { - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); RTC_DCHECK(rtp_transport_); switch (type) { case ST_RTP: @@ -346,7 +354,7 @@ int BaseChannel::SetOption_n(SocketType type, } void BaseChannel::OnWritableState(bool writable) { - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); if (writable) { ChannelWritable_n(); } else { @@ -358,7 +366,7 @@ void BaseChannel::OnNetworkRouteChanged( absl::optional network_route) { RTC_LOG(LS_INFO) << "Network route for " << ToString() << " was changed."; - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); rtc::NetworkRoute new_route; if (network_route) { new_route = *(network_route); @@ -372,6 +380,18 @@ void BaseChannel::OnNetworkRouteChanged( }); } +sigslot::signal1& BaseChannel::SignalFirstPacketReceived() { + RTC_DCHECK_RUN_ON(signaling_thread_); + return SignalFirstPacketReceived_; +} + +sigslot::signal1& BaseChannel::SignalSentPacket() { + // TODO(bugs.webrtc.org/11994): Uncomment this check once callers have been + // fixed to access this variable from the correct thread. + // RTC_DCHECK_RUN_ON(worker_thread_); + return SignalSentPacket_; +} + void BaseChannel::OnTransportReadyToSend(bool ready) { invoker_.AsyncInvoke(RTC_FROM_HERE, worker_thread_, [=] { media_channel_->OnReadyToSend(ready); }); @@ -479,7 +499,7 @@ void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) { invoker_.AsyncInvoke( RTC_FROM_HERE, worker_thread_, [this, packet_buffer, packet_time_us] { - RTC_DCHECK(worker_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(worker_thread()); media_channel_->OnPacketReceived(packet_buffer, packet_time_us); }); } @@ -537,7 +557,7 @@ void BaseChannel::UpdateWritableState_n() { } void BaseChannel::ChannelWritable_n() { - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); if (writable_) { return; } @@ -551,7 +571,7 @@ void BaseChannel::ChannelWritable_n() { } void BaseChannel::ChannelNotWritable_n() { - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); if (!writable_) return; @@ -575,6 +595,37 @@ void BaseChannel::ResetUnsignaledRecvStream_w() { media_channel()->ResetUnsignaledRecvStream(); } +bool BaseChannel::SetPayloadTypeDemuxingEnabled_w(bool enabled) { + RTC_DCHECK_RUN_ON(worker_thread()); + if (enabled == payload_type_demuxing_enabled_) { + return true; + } + payload_type_demuxing_enabled_ = enabled; + if (!enabled) { + // TODO(crbug.com/11477): This will remove *all* unsignaled streams (those + // without an explicitly signaled SSRC), which may include streams that + // were matched to this channel by MID or RID. Ideally we'd remove only the + // streams that were matched based on payload type alone, but currently + // there is no straightforward way to identify those streams. + media_channel()->ResetUnsignaledRecvStream(); + demuxer_criteria_.payload_types.clear(); + if (!RegisterRtpDemuxerSink()) { + RTC_LOG(LS_ERROR) << "Failed to disable payload type demuxing for " + << ToString(); + return false; + } + } else if (!payload_types_.empty()) { + demuxer_criteria_.payload_types.insert(payload_types_.begin(), + payload_types_.end()); + if (!RegisterRtpDemuxerSink()) { + RTC_LOG(LS_ERROR) << "Failed to enable payload type demuxing for " + << ToString(); + return false; + } + } + return true; +} + bool BaseChannel::UpdateLocalStreams_w(const std::vector& streams, SdpType type, std::string* error_desc) { @@ -716,6 +767,7 @@ bool BaseChannel::UpdateRemoteStreams_w( // Re-register the sink to update the receiving ssrcs. if (!RegisterRtpDemuxerSink()) { RTC_LOG(LS_ERROR) << "Failed to set up demuxing for " << ToString(); + ret = false; } remote_streams_ = streams; return ret; @@ -741,7 +793,7 @@ void BaseChannel::OnMessage(rtc::Message* pmsg) { switch (pmsg->message_id) { case MSG_SEND_RTP_PACKET: case MSG_SEND_RTCP_PACKET: { - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); SendPacketMessageData* data = static_cast(pmsg->pdata); bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET; @@ -750,24 +802,31 @@ void BaseChannel::OnMessage(rtc::Message* pmsg) { break; } case MSG_FIRSTPACKETRECEIVED: { + RTC_DCHECK_RUN_ON(signaling_thread_); SignalFirstPacketReceived_(this); break; } } } -void BaseChannel::AddHandledPayloadType(int payload_type) { - demuxer_criteria_.payload_types.insert(static_cast(payload_type)); +void BaseChannel::MaybeAddHandledPayloadType(int payload_type) { + if (payload_type_demuxing_enabled_) { + demuxer_criteria_.payload_types.insert(static_cast(payload_type)); + } + // Even if payload type demuxing is currently disabled, we need to remember + // the payload types in case it's re-enabled later. + payload_types_.insert(static_cast(payload_type)); } void BaseChannel::ClearHandledPayloadTypes() { demuxer_criteria_.payload_types.clear(); + payload_types_.clear(); } void BaseChannel::FlushRtcpMessages_n() { // Flush all remaining RTCP messages. This should only be called in // destructor. - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); rtc::MessageList rtcp_messages; network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages); for (const auto& message : rtcp_messages) { @@ -777,11 +836,11 @@ void BaseChannel::FlushRtcpMessages_n() { } void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) { - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); invoker_.AsyncInvoke(RTC_FROM_HERE, worker_thread_, [this, sent_packet] { - RTC_DCHECK(worker_thread_->IsCurrent()); - SignalSentPacket(sent_packet); + RTC_DCHECK_RUN_ON(worker_thread()); + SignalSentPacket()(sent_packet); }); } @@ -810,7 +869,7 @@ VoiceChannel::~VoiceChannel() { } void BaseChannel::UpdateMediaSendRecvState() { - RTC_DCHECK(network_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread()); invoker_.AsyncInvoke(RTC_FROM_HERE, worker_thread_, [this] { UpdateMediaSendRecvState_w(); }); } @@ -869,7 +928,7 @@ bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content, if (webrtc::RtpTransceiverDirectionHasRecv(audio->direction())) { for (const AudioCodec& codec : audio->codecs()) { - AddHandledPayloadType(codec.id); + MaybeAddHandledPayloadType(codec.id); } // Need to re-register the sink to update the handled payload. if (!RegisterRtpDemuxerSink()) { @@ -1062,7 +1121,7 @@ bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content, if (webrtc::RtpTransceiverDirectionHasRecv(video->direction())) { for (const VideoCodec& codec : video->codecs()) { - AddHandledPayloadType(codec.id); + MaybeAddHandledPayloadType(codec.id); } // Need to re-register the sink to update the handled payload. if (!RegisterRtpDemuxerSink()) { @@ -1287,7 +1346,7 @@ bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content, return false; } for (const DataCodec& codec : data->codecs()) { - AddHandledPayloadType(codec.id); + MaybeAddHandledPayloadType(codec.id); } // Need to re-register the sink to update the handled payload. if (!RegisterRtpDemuxerSink()) { diff --git a/TMessagesProj/jni/voip/webrtc/pc/channel.h b/TMessagesProj/jni/voip/webrtc/pc/channel.h index 44374b176..51cc40fc5 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/channel.h +++ b/TMessagesProj/jni/voip/webrtc/pc/channel.h @@ -39,7 +39,9 @@ #include "rtc_base/async_invoker.h" #include "rtc_base/async_udp_socket.h" #include "rtc_base/network.h" +#include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/third_party/sigslot/sigslot.h" +#include "rtc_base/thread_annotations.h" #include "rtc_base/unique_id_generator.h" namespace webrtc { @@ -69,7 +71,7 @@ struct CryptoParams; // NetworkInterface. class BaseChannel : public ChannelInterface, - public rtc::MessageHandler, + public rtc::MessageHandlerAutoCleanup, public sigslot::has_slots<>, public MediaChannel::NetworkInterface, public webrtc::RtpPacketSinkInterface { @@ -124,6 +126,15 @@ class BaseChannel : public ChannelInterface, bool SetRemoteContent(const MediaContentDescription* content, webrtc::SdpType type, std::string* error_desc) override; + // Controls whether this channel will receive packets on the basis of + // matching payload type alone. This is needed for legacy endpoints that + // don't signal SSRCs or use MID/RID, but doesn't make sense if there is + // more than channel of specific media type, As that creates an ambiguity. + // + // This method will also remove any existing streams that were bound to this + // channel on the basis of payload type, since one of these streams might + // actually belong to a new channel. See: crbug.com/webrtc/11477 + bool SetPayloadTypeDemuxingEnabled(bool enabled) override; bool Enable(bool enable) override; @@ -134,22 +145,11 @@ class BaseChannel : public ChannelInterface, return remote_streams_; } - sigslot::signal2 SignalDtlsSrtpSetupFailure; - void SignalDtlsSrtpSetupFailure_n(bool rtcp); - void SignalDtlsSrtpSetupFailure_s(bool rtcp); - // Used for latency measurements. - sigslot::signal1& SignalFirstPacketReceived() override { - return SignalFirstPacketReceived_; - } + sigslot::signal1& SignalFirstPacketReceived() override; // Forward SignalSentPacket to worker thread. - sigslot::signal1 SignalSentPacket; - - // Emitted whenever rtcp-mux is fully negotiated and the rtcp-transport can - // be destroyed. - // Fired on the network thread. - sigslot::signal1 SignalRtcpMuxFullyActive; + sigslot::signal1& SignalSentPacket(); // From RtpTransport - public for testing only void OnTransportReadyToSend(bool ready); @@ -224,6 +224,7 @@ class BaseChannel : public ChannelInterface, bool AddRecvStream_w(const StreamParams& sp); bool RemoveRecvStream_w(uint32_t ssrc); void ResetUnsignaledRecvStream_w(); + bool SetPayloadTypeDemuxingEnabled_w(bool enabled); bool AddSendStream_w(const StreamParams& sp); bool RemoveSendStream_w(uint32_t ssrc); @@ -261,9 +262,11 @@ class BaseChannel : public ChannelInterface, return worker_thread_->Invoke(posted_from, functor); } - void AddHandledPayloadType(int payload_type); + // Add |payload_type| to |demuxer_criteria_| if payload type demuxing is + // enabled. + void MaybeAddHandledPayloadType(int payload_type) RTC_RUN_ON(worker_thread()); - void ClearHandledPayloadTypes(); + void ClearHandledPayloadTypes() RTC_RUN_ON(worker_thread()); void UpdateRtpHeaderExtensionMap( const RtpHeaderExtensions& header_extensions); @@ -285,7 +288,10 @@ class BaseChannel : public ChannelInterface, rtc::Thread* const network_thread_; rtc::Thread* const signaling_thread_; rtc::AsyncInvoker invoker_; - sigslot::signal1 SignalFirstPacketReceived_; + sigslot::signal1 SignalFirstPacketReceived_ + RTC_GUARDED_BY(signaling_thread_); + sigslot::signal1 SignalSentPacket_ + RTC_GUARDED_BY(worker_thread_); const std::string content_name_; @@ -308,6 +314,7 @@ class BaseChannel : public ChannelInterface, // well, but it can be changed only when signaling thread does a synchronous // call to the worker thread, so it should be safe. bool enabled_ = false; + bool payload_type_demuxing_enabled_ RTC_GUARDED_BY(worker_thread()) = true; std::vector local_streams_; std::vector remote_streams_; webrtc::RtpTransceiverDirection local_content_direction_ = @@ -315,6 +322,8 @@ class BaseChannel : public ChannelInterface, webrtc::RtpTransceiverDirection remote_content_direction_ = webrtc::RtpTransceiverDirection::kInactive; + // Cached list of payload types, used if payload type demuxing is re-enabled. + std::set payload_types_ RTC_GUARDED_BY(worker_thread()); webrtc::RtpDemuxerCriteria demuxer_criteria_; // This generator is used to generate SSRCs for local streams. // This is needed in cases where SSRCs are not negotiated or set explicitly diff --git a/TMessagesProj/jni/voip/webrtc/pc/channel_interface.h b/TMessagesProj/jni/voip/webrtc/pc/channel_interface.h index cd29ed4f8..68b648630 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/channel_interface.h +++ b/TMessagesProj/jni/voip/webrtc/pc/channel_interface.h @@ -52,6 +52,7 @@ class ChannelInterface { virtual bool SetRemoteContent(const MediaContentDescription* content, webrtc::SdpType type, std::string* error_desc) = 0; + virtual bool SetPayloadTypeDemuxingEnabled(bool enabled) = 0; // Access to the local and remote streams that were set on the channel. virtual const std::vector& local_streams() const = 0; diff --git a/TMessagesProj/jni/voip/webrtc/pc/channel_manager.cc b/TMessagesProj/jni/voip/webrtc/pc/channel_manager.cc index 84d74678b..9d5adcad4 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/channel_manager.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/channel_manager.cc @@ -193,6 +193,9 @@ VoiceChannel* ChannelManager::CreateVoiceChannel( const webrtc::CryptoOptions& crypto_options, rtc::UniqueRandomIdGenerator* ssrc_generator, const AudioOptions& options) { + // TODO(bugs.webrtc.org/11992): Remove this workaround after updates in + // PeerConnection and add the expectation that we're already on the right + // thread. if (!worker_thread_->IsCurrent()) { return worker_thread_->Invoke(RTC_FROM_HERE, [&] { return CreateVoiceChannel(call, media_config, rtp_transport, @@ -262,6 +265,9 @@ VideoChannel* ChannelManager::CreateVideoChannel( rtc::UniqueRandomIdGenerator* ssrc_generator, const VideoOptions& options, webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) { + // TODO(bugs.webrtc.org/11992): Remove this workaround after updates in + // PeerConnection and add the expectation that we're already on the right + // thread. if (!worker_thread_->IsCurrent()) { return worker_thread_->Invoke(RTC_FROM_HERE, [&] { return CreateVideoChannel(call, media_config, rtp_transport, diff --git a/TMessagesProj/jni/voip/webrtc/pc/channel_manager.h b/TMessagesProj/jni/voip/webrtc/pc/channel_manager.h index 8d5fc0aa5..ba2c26009 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/channel_manager.h +++ b/TMessagesProj/jni/voip/webrtc/pc/channel_manager.h @@ -96,16 +96,15 @@ class ChannelManager final { // call the appropriate Destroy*Channel method when done. // Creates a voice channel, to be associated with the specified session. - VoiceChannel* CreateVoiceChannel( - webrtc::Call* call, - const cricket::MediaConfig& media_config, - webrtc::RtpTransportInternal* rtp_transport, - rtc::Thread* signaling_thread, - const std::string& content_name, - bool srtp_required, - const webrtc::CryptoOptions& crypto_options, - rtc::UniqueRandomIdGenerator* ssrc_generator, - const AudioOptions& options); + VoiceChannel* CreateVoiceChannel(webrtc::Call* call, + const cricket::MediaConfig& media_config, + webrtc::RtpTransportInternal* rtp_transport, + rtc::Thread* signaling_thread, + const std::string& content_name, + bool srtp_required, + const webrtc::CryptoOptions& crypto_options, + rtc::UniqueRandomIdGenerator* ssrc_generator, + const AudioOptions& options); // Destroys a voice channel created by CreateVoiceChannel. void DestroyVoiceChannel(VoiceChannel* voice_channel); diff --git a/TMessagesProj/jni/voip/webrtc/pc/connection_context.cc b/TMessagesProj/jni/voip/webrtc/pc/connection_context.cc new file mode 100644 index 000000000..727fbd654 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/connection_context.cc @@ -0,0 +1,147 @@ +/* + * Copyright 2020 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 "pc/connection_context.h" + +#include +#include +#include + +#include "api/transport/field_trial_based_config.h" +#include "media/base/rtp_data_engine.h" +#include "rtc_base/helpers.h" +#include "rtc_base/ref_counted_object.h" +#include "rtc_base/time_utils.h" + +namespace webrtc { + +namespace { + +rtc::Thread* MaybeStartThread(rtc::Thread* old_thread, + const std::string& thread_name, + bool with_socket_server, + std::unique_ptr& thread_holder) { + if (old_thread) { + return old_thread; + } + if (with_socket_server) { + thread_holder = rtc::Thread::CreateWithSocketServer(); + } else { + thread_holder = rtc::Thread::Create(); + } + thread_holder->SetName(thread_name, nullptr); + thread_holder->Start(); + return thread_holder.get(); +} + +rtc::Thread* MaybeWrapThread(rtc::Thread* signaling_thread, + bool& wraps_current_thread) { + wraps_current_thread = false; + if (signaling_thread) { + return signaling_thread; + } + auto this_thread = rtc::Thread::Current(); + if (!this_thread) { + // If this thread isn't already wrapped by an rtc::Thread, create a + // wrapper and own it in this class. + this_thread = rtc::ThreadManager::Instance()->WrapCurrentThread(); + wraps_current_thread = true; + } + return this_thread; +} + +std::unique_ptr MaybeCreateSctpFactory( + std::unique_ptr factory, + rtc::Thread* network_thread) { + if (factory) { + return factory; + } +#ifdef HAVE_SCTP + return std::make_unique(network_thread); +#else + return nullptr; +#endif +} + +} // namespace + +// Static +rtc::scoped_refptr ConnectionContext::Create( + PeerConnectionFactoryDependencies* dependencies) { + auto context = new rtc::RefCountedObject(dependencies); + if (!context->channel_manager_->Init()) { + return nullptr; + } + return context; +} + +ConnectionContext::ConnectionContext( + PeerConnectionFactoryDependencies* dependencies) + : network_thread_(MaybeStartThread(dependencies->network_thread, + "pc_network_thread", + true, + owned_network_thread_)), + worker_thread_(MaybeStartThread(dependencies->worker_thread, + "pc_worker_thread", + false, + owned_worker_thread_)), + signaling_thread_(MaybeWrapThread(dependencies->signaling_thread, + wraps_current_thread_)), + network_monitor_factory_( + std::move(dependencies->network_monitor_factory)), + call_factory_(std::move(dependencies->call_factory)), + media_engine_(std::move(dependencies->media_engine)), + sctp_factory_( + MaybeCreateSctpFactory(std::move(dependencies->sctp_factory), + network_thread())), + trials_(dependencies->trials + ? std::move(dependencies->trials) + : std::make_unique()) { + signaling_thread_->AllowInvokesToThread(worker_thread_); + signaling_thread_->AllowInvokesToThread(network_thread_); + worker_thread_->AllowInvokesToThread(network_thread_); + network_thread_->DisallowAllInvokes(); + + RTC_DCHECK_RUN_ON(signaling_thread_); + rtc::InitRandom(rtc::Time32()); + + // If network_monitor_factory_ is non-null, it will be used to create a + // network monitor while on the network thread. + default_network_manager_ = std::make_unique( + network_monitor_factory_.get()); + + default_socket_factory_ = + std::make_unique(network_thread()); + + channel_manager_ = std::make_unique( + std::move(media_engine_), std::make_unique(), + worker_thread(), network_thread()); + + channel_manager_->SetVideoRtxEnabled(true); +} + +ConnectionContext::~ConnectionContext() { + RTC_DCHECK_RUN_ON(signaling_thread_); + channel_manager_.reset(nullptr); + + // Make sure |worker_thread()| and |signaling_thread()| outlive + // |default_socket_factory_| and |default_network_manager_|. + default_socket_factory_ = nullptr; + default_network_manager_ = nullptr; + + if (wraps_current_thread_) + rtc::ThreadManager::Instance()->UnwrapCurrentThread(); +} + +cricket::ChannelManager* ConnectionContext::channel_manager() const { + return channel_manager_.get(); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/connection_context.h b/TMessagesProj/jni/voip/webrtc/pc/connection_context.h new file mode 100644 index 000000000..02d08a191 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/connection_context.h @@ -0,0 +1,134 @@ +/* + * Copyright 2020 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. + */ + +#ifndef PC_CONNECTION_CONTEXT_H_ +#define PC_CONNECTION_CONTEXT_H_ + +#include +#include + +#include "api/call/call_factory_interface.h" +#include "api/media_stream_interface.h" +#include "api/peer_connection_interface.h" +#include "api/scoped_refptr.h" +#include "api/transport/sctp_transport_factory_interface.h" +#include "api/transport/webrtc_key_value_config.h" +#include "media/base/media_engine.h" +#include "media/sctp/sctp_transport_internal.h" +#include "p2p/base/basic_packet_socket_factory.h" +#include "pc/channel_manager.h" +#include "rtc_base/checks.h" +#include "rtc_base/network.h" +#include "rtc_base/network_monitor_factory.h" +#include "rtc_base/ref_count.h" +#include "rtc_base/rtc_certificate_generator.h" +#include "rtc_base/synchronization/sequence_checker.h" +#include "rtc_base/thread.h" +#include "rtc_base/thread_annotations.h" + +namespace rtc { +class BasicNetworkManager; +class BasicPacketSocketFactory; +} // namespace rtc + +namespace webrtc { + +class RtcEventLog; + +// This class contains resources needed by PeerConnection and associated +// objects. A reference to this object is passed to each PeerConnection. The +// methods on this object are assumed not to change the state in any way that +// interferes with the operation of other PeerConnections. +// +// This class must be created and destroyed on the signaling thread. +class ConnectionContext : public rtc::RefCountInterface { + public: + // Creates a ConnectionContext. May return null if initialization fails. + // The Dependencies class allows simple management of all new dependencies + // being added to the ConnectionContext. + static rtc::scoped_refptr Create( + PeerConnectionFactoryDependencies* dependencies); + + // This class is not copyable or movable. + ConnectionContext(const ConnectionContext&) = delete; + ConnectionContext& operator=(const ConnectionContext&) = delete; + + // Functions called from PeerConnection and friends + SctpTransportFactoryInterface* sctp_transport_factory() const { + RTC_DCHECK_RUN_ON(signaling_thread_); + return sctp_factory_.get(); + } + + cricket::ChannelManager* channel_manager() const; + + rtc::Thread* signaling_thread() { return signaling_thread_; } + const rtc::Thread* signaling_thread() const { return signaling_thread_; } + rtc::Thread* worker_thread() { return worker_thread_; } + const rtc::Thread* worker_thread() const { return worker_thread_; } + rtc::Thread* network_thread() { return network_thread_; } + const rtc::Thread* network_thread() const { return network_thread_; } + + const WebRtcKeyValueConfig& trials() const { return *trials_.get(); } + + // Accessors only used from the PeerConnectionFactory class + rtc::BasicNetworkManager* default_network_manager() { + RTC_DCHECK_RUN_ON(signaling_thread_); + return default_network_manager_.get(); + } + rtc::BasicPacketSocketFactory* default_socket_factory() { + RTC_DCHECK_RUN_ON(signaling_thread_); + return default_socket_factory_.get(); + } + CallFactoryInterface* call_factory() { + RTC_DCHECK_RUN_ON(worker_thread_); + return call_factory_.get(); + } + + protected: + explicit ConnectionContext(PeerConnectionFactoryDependencies* dependencies); + + virtual ~ConnectionContext(); + + private: + // The following three variables are used to communicate between the + // constructor and the destructor, and are never exposed externally. + bool wraps_current_thread_; + // Note: Since owned_network_thread_ and owned_worker_thread_ are used + // in the initialization of network_thread_ and worker_thread_, they + // must be declared before them, so that they are initialized first. + std::unique_ptr owned_network_thread_ + RTC_GUARDED_BY(signaling_thread_); + std::unique_ptr owned_worker_thread_ + RTC_GUARDED_BY(signaling_thread_); + rtc::Thread* const network_thread_; + rtc::Thread* const worker_thread_; + rtc::Thread* const signaling_thread_; + // channel_manager is accessed both on signaling thread and worker thread. + std::unique_ptr channel_manager_; + std::unique_ptr const network_monitor_factory_ + RTC_GUARDED_BY(signaling_thread_); + std::unique_ptr default_network_manager_ + RTC_GUARDED_BY(signaling_thread_); + std::unique_ptr const call_factory_ + RTC_GUARDED_BY(worker_thread_); + + std::unique_ptr default_socket_factory_ + RTC_GUARDED_BY(signaling_thread_); + std::unique_ptr media_engine_ + RTC_GUARDED_BY(signaling_thread_); + std::unique_ptr const sctp_factory_ + RTC_GUARDED_BY(signaling_thread_); + // Accessed both on signaling thread and worker thread. + std::unique_ptr const trials_; +}; + +} // namespace webrtc + +#endif // PC_CONNECTION_CONTEXT_H_ diff --git a/TMessagesProj/jni/voip/webrtc/pc/data_channel_controller.cc b/TMessagesProj/jni/voip/webrtc/pc/data_channel_controller.cc index 04a4bb624..9fabe13cc 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/data_channel_controller.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/data_channel_controller.cc @@ -129,7 +129,7 @@ void DataChannelController::OnDataReceived( cricket::ReceiveDataParams params; params.sid = channel_id; params.type = ToCricketDataMessageType(type); - data_channel_transport_invoker_->AsyncInvoke( + data_channel_transport_invoker_.AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this, params, buffer] { RTC_DCHECK_RUN_ON(signaling_thread()); // TODO(bugs.webrtc.org/11547): The data being received should be @@ -148,7 +148,7 @@ void DataChannelController::OnDataReceived( void DataChannelController::OnChannelClosing(int channel_id) { RTC_DCHECK_RUN_ON(network_thread()); - data_channel_transport_invoker_->AsyncInvoke( + data_channel_transport_invoker_.AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this, channel_id] { RTC_DCHECK_RUN_ON(signaling_thread()); SignalDataChannelTransportChannelClosing_s(channel_id); @@ -157,7 +157,7 @@ void DataChannelController::OnChannelClosing(int channel_id) { void DataChannelController::OnChannelClosed(int channel_id) { RTC_DCHECK_RUN_ON(network_thread()); - data_channel_transport_invoker_->AsyncInvoke( + data_channel_transport_invoker_.AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this, channel_id] { RTC_DCHECK_RUN_ON(signaling_thread()); SignalDataChannelTransportChannelClosed_s(channel_id); @@ -166,7 +166,7 @@ void DataChannelController::OnChannelClosed(int channel_id) { void DataChannelController::OnReadyToSend() { RTC_DCHECK_RUN_ON(network_thread()); - data_channel_transport_invoker_->AsyncInvoke( + data_channel_transport_invoker_.AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this] { RTC_DCHECK_RUN_ON(signaling_thread()); data_channel_transport_ready_to_send_ = true; @@ -177,7 +177,7 @@ void DataChannelController::OnReadyToSend() { void DataChannelController::OnTransportClosed() { RTC_DCHECK_RUN_ON(network_thread()); - data_channel_transport_invoker_->AsyncInvoke( + data_channel_transport_invoker_.AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this] { RTC_DCHECK_RUN_ON(signaling_thread()); OnTransportChannelClosed(); @@ -186,7 +186,6 @@ void DataChannelController::OnTransportClosed() { void DataChannelController::SetupDataChannelTransport_n() { RTC_DCHECK_RUN_ON(network_thread()); - data_channel_transport_invoker_ = std::make_unique(); // There's a new data channel transport. This needs to be signaled to the // |sctp_data_channels_| so that they can reopen and reconnect. This is @@ -196,7 +195,6 @@ void DataChannelController::SetupDataChannelTransport_n() { void DataChannelController::TeardownDataChannelTransport_n() { RTC_DCHECK_RUN_ON(network_thread()); - data_channel_transport_invoker_ = nullptr; if (data_channel_transport()) { data_channel_transport()->SetDataSink(nullptr); } @@ -592,7 +590,7 @@ bool DataChannelController::DataChannelSendData( void DataChannelController::NotifyDataChannelsOfTransportCreated() { RTC_DCHECK_RUN_ON(network_thread()); - data_channel_transport_invoker_->AsyncInvoke( + data_channel_transport_invoker_.AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this] { RTC_DCHECK_RUN_ON(signaling_thread()); for (const auto& channel : sctp_data_channels_) { diff --git a/TMessagesProj/jni/voip/webrtc/pc/data_channel_controller.h b/TMessagesProj/jni/voip/webrtc/pc/data_channel_controller.h index 3daee1138..675928882 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/data_channel_controller.h +++ b/TMessagesProj/jni/voip/webrtc/pc/data_channel_controller.h @@ -221,8 +221,9 @@ class DataChannelController : public RtpDataChannelProviderInterface, sigslot::signal1 SignalSctpDataChannelCreated_ RTC_GUARDED_BY(signaling_thread()); - // Used to invoke data channel transport signals on the signaling thread. - std::unique_ptr data_channel_transport_invoker_ + // Used from the network thread to invoke data channel transport signals on + // the signaling thread. + rtc::AsyncInvoker data_channel_transport_invoker_ RTC_GUARDED_BY(network_thread()); // Owning PeerConnection. diff --git a/TMessagesProj/jni/voip/webrtc/pc/dtls_srtp_transport.h b/TMessagesProj/jni/voip/webrtc/pc/dtls_srtp_transport.h index c63a3ca5d..f50928fc8 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/dtls_srtp_transport.h +++ b/TMessagesProj/jni/voip/webrtc/pc/dtls_srtp_transport.h @@ -63,6 +63,16 @@ class DtlsSrtpTransport : public SrtpTransport { active_reset_srtp_params_ = active_reset_srtp_params; } + virtual void OnErrorDemuxingPacket(uint32_t ssrc) override { + if (SignalOnErrorDemuxingPacket_) { + SignalOnErrorDemuxingPacket_(ssrc); + } + } + + void SetOnErrorDemuxingPacket(std::function f) { + SignalOnErrorDemuxingPacket_ = std::move(f); + } + private: bool IsDtlsActive(); bool IsDtlsConnected(); @@ -96,6 +106,8 @@ class DtlsSrtpTransport : public SrtpTransport { absl::optional> recv_extension_ids_; bool active_reset_srtp_params_ = false; + + std::function SignalOnErrorDemuxingPacket_ = nullptr; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/dtls_transport.cc b/TMessagesProj/jni/voip/webrtc/pc/dtls_transport.cc index f0882de3b..550ede790 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/dtls_transport.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/dtls_transport.cc @@ -31,6 +31,7 @@ DtlsTransportState TranslateState(cricket::DtlsTransportState internal_state) { case cricket::DTLS_TRANSPORT_FAILED: return DtlsTransportState::kFailed; } + RTC_CHECK_NOTREACHED(); } } // namespace diff --git a/TMessagesProj/jni/voip/webrtc/pc/ice_transport.h b/TMessagesProj/jni/voip/webrtc/pc/ice_transport.h index 69b69e41d..c1529de6b 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/ice_transport.h +++ b/TMessagesProj/jni/voip/webrtc/pc/ice_transport.h @@ -12,7 +12,6 @@ #define PC_ICE_TRANSPORT_H_ #include "api/ice_transport_interface.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/thread.h" #include "rtc_base/thread_checker.h" @@ -29,6 +28,10 @@ class IceTransportWithPointer : public IceTransportInterface { RTC_DCHECK(internal_); } + IceTransportWithPointer() = delete; + IceTransportWithPointer(const IceTransportWithPointer&) = delete; + IceTransportWithPointer& operator=(const IceTransportWithPointer&) = delete; + cricket::IceTransportInternal* internal() override; // This call will ensure that the pointer passed at construction is // no longer in use by this object. Later calls to internal() will return @@ -39,7 +42,6 @@ class IceTransportWithPointer : public IceTransportInterface { ~IceTransportWithPointer() override; private: - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(IceTransportWithPointer); const rtc::Thread* creator_thread_; cricket::IceTransportInternal* internal_ RTC_GUARDED_BY(creator_thread_); }; diff --git a/TMessagesProj/jni/voip/webrtc/pc/jsep_transport_controller.cc b/TMessagesProj/jni/voip/webrtc/pc/jsep_transport_controller.cc index 71dd8acc2..0b0532002 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/jsep_transport_controller.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/jsep_transport_controller.cc @@ -535,6 +535,9 @@ JsepTransportController::CreateDtlsSrtpTransport( config_.active_reset_srtp_params); dtls_srtp_transport->SignalDtlsStateChange.connect( this, &JsepTransportController::UpdateAggregateStates_n); + dtls_srtp_transport->SetOnErrorDemuxingPacket([this](uint32_t ssrc) { + this->JsepTransportController::ErrorDemuxingPacket_n(ssrc); + }); return dtls_srtp_transport; } @@ -1256,10 +1259,11 @@ void JsepTransportController::UpdateAggregateStates_n() { } if (ice_connection_state_ != new_connection_state) { ice_connection_state_ = new_connection_state; - invoker_.AsyncInvoke(RTC_FROM_HERE, signaling_thread_, - [this, new_connection_state] { - SignalIceConnectionState(new_connection_state); - }); + + invoker_.AsyncInvoke( + RTC_FROM_HERE, signaling_thread_, [this, new_connection_state] { + SignalIceConnectionState.Send(new_connection_state); + }); } // Compute the current RTCIceConnectionState as described in @@ -1381,7 +1385,10 @@ void JsepTransportController::UpdateAggregateStates_n() { }); } - if (all_done_gathering) { + // Compute the gathering state. + if (dtls_transports.empty()) { + new_gathering_state = cricket::kIceGatheringNew; + } else if (all_done_gathering) { new_gathering_state = cricket::kIceGatheringComplete; } else if (any_gathering) { new_gathering_state = cricket::kIceGatheringGathering; @@ -1395,6 +1402,10 @@ void JsepTransportController::UpdateAggregateStates_n() { } } +void JsepTransportController::ErrorDemuxingPacket_n(uint32_t ssrc) { + SignalErrorDemuxingPacket.emit(ssrc); +} + void JsepTransportController::OnRtcpPacketReceived_n( rtc::CopyOnWriteBuffer* packet, int64_t packet_time_us) { diff --git a/TMessagesProj/jni/voip/webrtc/pc/jsep_transport_controller.h b/TMessagesProj/jni/voip/webrtc/pc/jsep_transport_controller.h index d95b47596..025a7a1fc 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/jsep_transport_controller.h +++ b/TMessagesProj/jni/voip/webrtc/pc/jsep_transport_controller.h @@ -35,6 +35,7 @@ #include "rtc_base/async_invoker.h" #include "rtc_base/constructor_magic.h" #include "rtc_base/ref_counted_object.h" +#include "rtc_base/callback_list.h" #include "rtc_base/third_party/sigslot/sigslot.h" namespace rtc { @@ -101,7 +102,7 @@ class JsepTransportController : public sigslot::has_slots<> { RtcEventLog* event_log = nullptr; // Factory for SCTP transports. - cricket::SctpTransportInternalFactory* sctp_factory = nullptr; + SctpTransportFactoryInterface* sctp_factory = nullptr; }; // The ICE related events are signaled on the |signaling_thread|. @@ -197,10 +198,11 @@ class JsepTransportController : public sigslot::has_slots<> { // Else if all completed => completed, // Else if all connected => connected, // Else => connecting - sigslot::signal1 SignalIceConnectionState; + CallbackList SignalIceConnectionState; sigslot::signal1 SignalConnectionState; + sigslot::signal1 SignalStandardizedIceConnectionState; @@ -224,6 +226,8 @@ class JsepTransportController : public sigslot::has_slots<> { sigslot::signal1 SignalDtlsHandshakeError; + sigslot::signal1 SignalErrorDemuxingPacket; + private: RTCError ApplyDescription_n(bool local, SdpType type, @@ -347,6 +351,7 @@ class JsepTransportController : public sigslot::has_slots<> { void OnTransportCandidatePairChanged_n( const cricket::CandidatePairChangeEvent& event); void UpdateAggregateStates_n(); + void ErrorDemuxingPacket_n(uint32_t ssrc); void OnRtcpPacketReceived_n(rtc::CopyOnWriteBuffer* packet, int64_t packet_time_us); diff --git a/TMessagesProj/jni/voip/webrtc/pc/media_session.cc b/TMessagesProj/jni/voip/webrtc/pc/media_session.cc index 0cff84d79..6d8a9a489 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/media_session.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/media_session.cc @@ -36,6 +36,7 @@ #include "rtc_base/logging.h" #include "rtc_base/third_party/base64/base64.h" #include "rtc_base/unique_id_generator.h" +#include "system_wrappers/include/field_trial.h" namespace { @@ -336,6 +337,12 @@ static StreamParams CreateStreamParamsForNewSenderWithSsrcs( "a single media streams. This session has multiple " "media streams however, so no FlexFEC SSRC will be generated."; } + if (include_flexfec_stream && + !webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03")) { + include_flexfec_stream = false; + RTC_LOG(LS_WARNING) + << "WebRTC-FlexFEC trial is not enabled, not sending FlexFEC"; + } result.GenerateSsrcs(sender.num_sim_layers, include_rtx_streams, include_flexfec_stream, ssrc_generator); @@ -1559,6 +1566,13 @@ std::unique_ptr MediaSessionDescriptionFactory::CreateOffer( return nullptr; } break; + case MEDIA_TYPE_UNSUPPORTED: + if (!AddUnsupportedContentForOffer( + media_description_options, session_options, current_content, + current_description, offer.get(), &ice_credentials)) { + return nullptr; + } + break; default: RTC_NOTREACHED(); } @@ -1713,6 +1727,14 @@ MediaSessionDescriptionFactory::CreateAnswer( return nullptr; } break; + case MEDIA_TYPE_UNSUPPORTED: + if (!AddUnsupportedContentForAnswer( + media_description_options, session_options, offer_content, + offer, current_content, current_description, + bundle_transport.get(), answer.get(), &ice_credentials)) { + return nullptr; + } + break; default: RTC_NOTREACHED(); } @@ -1803,6 +1825,7 @@ const AudioCodecs& MediaSessionDescriptionFactory::GetAudioCodecsForOffer( case RtpTransceiverDirection::kRecvOnly: return audio_recv_codecs_; } + RTC_CHECK_NOTREACHED(); } const AudioCodecs& MediaSessionDescriptionFactory::GetAudioCodecsForAnswer( @@ -1821,6 +1844,7 @@ const AudioCodecs& MediaSessionDescriptionFactory::GetAudioCodecsForAnswer( case RtpTransceiverDirection::kRecvOnly: return audio_recv_codecs_; } + RTC_CHECK_NOTREACHED(); } const VideoCodecs& MediaSessionDescriptionFactory::GetVideoCodecsForOffer( @@ -1836,6 +1860,7 @@ const VideoCodecs& MediaSessionDescriptionFactory::GetVideoCodecsForOffer( case RtpTransceiverDirection::kRecvOnly: return video_recv_codecs_; } + RTC_CHECK_NOTREACHED(); } const VideoCodecs& MediaSessionDescriptionFactory::GetVideoCodecsForAnswer( @@ -1854,6 +1879,7 @@ const VideoCodecs& MediaSessionDescriptionFactory::GetVideoCodecsForAnswer( case RtpTransceiverDirection::kRecvOnly: return video_recv_codecs_; } + RTC_CHECK_NOTREACHED(); } void MergeCodecsFromDescription( @@ -2362,7 +2388,7 @@ bool MediaSessionDescriptionFactory::AddRtpDataContentForOffer( return false; } - data->set_bandwidth(kDataMaxBandwidth); + data->set_bandwidth(kRtpDataMaxBandwidth); SetMediaProtocol(secure_transport, data.get()); desc->AddContent(media_description_options.mid, MediaProtocolType::kRtp, media_description_options.stopped, std::move(data)); @@ -2403,6 +2429,31 @@ bool MediaSessionDescriptionFactory::AddDataContentForOffer( } } +bool MediaSessionDescriptionFactory::AddUnsupportedContentForOffer( + const MediaDescriptionOptions& media_description_options, + const MediaSessionOptions& session_options, + const ContentInfo* current_content, + const SessionDescription* current_description, + SessionDescription* desc, + IceCredentialsIterator* ice_credentials) const { + RTC_CHECK(IsMediaContentOfType(current_content, MEDIA_TYPE_UNSUPPORTED)); + + const UnsupportedContentDescription* current_unsupported_description = + current_content->media_description()->as_unsupported(); + auto unsupported = std::make_unique( + current_unsupported_description->media_type()); + unsupported->set_protocol(current_content->media_description()->protocol()); + desc->AddContent(media_description_options.mid, MediaProtocolType::kOther, + /*rejected=*/true, std::move(unsupported)); + + if (!AddTransportOffer(media_description_options.mid, + media_description_options.transport_options, + current_description, desc, ice_credentials)) { + return false; + } + return true; +} + // |audio_codecs| = set of all possible codecs that can be used, with correct // payload type mappings // @@ -2733,8 +2784,8 @@ bool MediaSessionDescriptionFactory::AddDataContentForAnswer( return false; } - if (!rejected) { - data_answer->set_bandwidth(kDataMaxBandwidth); + if (!rejected && session_options.data_channel_type == DCT_RTP) { + data_answer->set_bandwidth(kRtpDataMaxBandwidth); } else { // RFC 3264 // The answer MUST contain the same number of m-lines as the offer. @@ -2745,6 +2796,42 @@ bool MediaSessionDescriptionFactory::AddDataContentForAnswer( return true; } +bool MediaSessionDescriptionFactory::AddUnsupportedContentForAnswer( + const MediaDescriptionOptions& media_description_options, + const MediaSessionOptions& session_options, + const ContentInfo* offer_content, + const SessionDescription* offer_description, + const ContentInfo* current_content, + const SessionDescription* current_description, + const TransportInfo* bundle_transport, + SessionDescription* answer, + IceCredentialsIterator* ice_credentials) const { + std::unique_ptr unsupported_transport = + CreateTransportAnswer(media_description_options.mid, offer_description, + media_description_options.transport_options, + current_description, bundle_transport != nullptr, + ice_credentials); + if (!unsupported_transport) { + return false; + } + RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_UNSUPPORTED)); + + const UnsupportedContentDescription* offer_unsupported_description = + offer_content->media_description()->as_unsupported(); + std::unique_ptr unsupported_answer = + std::make_unique( + offer_unsupported_description->media_type()); + unsupported_answer->set_protocol(offer_unsupported_description->protocol()); + + if (!AddTransportAnswer(media_description_options.mid, + *(unsupported_transport.get()), answer)) { + return false; + } + answer->AddContent(media_description_options.mid, offer_content->type, + /*rejected=*/true, std::move(unsupported_answer)); + return true; +} + void MediaSessionDescriptionFactory::ComputeAudioCodecsIntersectionAndUnion() { audio_sendrecv_codecs_.clear(); all_audio_codecs_.clear(); @@ -2822,6 +2909,10 @@ bool IsDataContent(const ContentInfo* content) { return IsMediaContentOfType(content, MEDIA_TYPE_DATA); } +bool IsUnsupportedContent(const ContentInfo* content) { + return IsMediaContentOfType(content, MEDIA_TYPE_UNSUPPORTED); +} + const ContentInfo* GetFirstMediaContent(const ContentInfos& contents, MediaType media_type) { for (const ContentInfo& content : contents) { diff --git a/TMessagesProj/jni/voip/webrtc/pc/media_session.h b/TMessagesProj/jni/voip/webrtc/pc/media_session.h index f305a6214..58a31a2ab 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/media_session.h +++ b/TMessagesProj/jni/voip/webrtc/pc/media_session.h @@ -283,6 +283,14 @@ class MediaSessionDescriptionFactory { SessionDescription* desc, IceCredentialsIterator* ice_credentials) const; + bool AddUnsupportedContentForOffer( + const MediaDescriptionOptions& media_description_options, + const MediaSessionOptions& session_options, + const ContentInfo* current_content, + const SessionDescription* current_description, + SessionDescription* desc, + IceCredentialsIterator* ice_credentials) const; + bool AddAudioContentForAnswer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, @@ -324,6 +332,17 @@ class MediaSessionDescriptionFactory { SessionDescription* answer, IceCredentialsIterator* ice_credentials) const; + bool AddUnsupportedContentForAnswer( + const MediaDescriptionOptions& media_description_options, + const MediaSessionOptions& session_options, + const ContentInfo* offer_content, + const SessionDescription* offer_description, + const ContentInfo* current_content, + const SessionDescription* current_description, + const TransportInfo* bundle_transport, + SessionDescription* answer, + IceCredentialsIterator* ice_credentials) const; + void ComputeAudioCodecsIntersectionAndUnion(); void ComputeVideoCodecsIntersectionAndUnion(); @@ -356,6 +375,7 @@ bool IsMediaContent(const ContentInfo* content); bool IsAudioContent(const ContentInfo* content); bool IsVideoContent(const ContentInfo* content); bool IsDataContent(const ContentInfo* content); +bool IsUnsupportedContent(const ContentInfo* content); const ContentInfo* GetFirstMediaContent(const ContentInfos& contents, MediaType media_type); const ContentInfo* GetFirstAudioContent(const ContentInfos& contents); diff --git a/TMessagesProj/jni/voip/webrtc/pc/media_stream.h b/TMessagesProj/jni/voip/webrtc/pc/media_stream.h index 34299f46e..6f16bea1d 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/media_stream.h +++ b/TMessagesProj/jni/voip/webrtc/pc/media_stream.h @@ -48,7 +48,7 @@ class MediaStream : public Notifier { template bool RemoveTrack(TrackVector* Tracks, MediaStreamTrackInterface* track); - std::string id_; + const std::string id_; AudioTrackVector audio_tracks_; VideoTrackVector video_tracks_; }; diff --git a/TMessagesProj/jni/voip/webrtc/pc/peer_connection.cc b/TMessagesProj/jni/voip/webrtc/pc/peer_connection.cc index 7cee2c743..dd8f7d0ff 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/peer_connection.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/peer_connection.cc @@ -10,55 +10,54 @@ #include "pc/peer_connection.h" +#include +#include #include -#include #include -#include #include #include -#include #include "absl/algorithm/container.h" #include "absl/strings/match.h" #include "api/jsep_ice_candidate.h" -#include "api/jsep_session_description.h" -#include "api/media_stream_proxy.h" -#include "api/media_stream_track_proxy.h" -#include "api/rtc_error.h" -#include "api/rtc_event_log/rtc_event_log.h" -#include "api/rtc_event_log_output_file.h" #include "api/rtp_parameters.h" +#include "api/rtp_transceiver_direction.h" +#include "api/task_queue/queued_task.h" +#include "api/transport/webrtc_key_value_config.h" #include "api/uma_metrics.h" -#include "api/video/builtin_video_bitrate_allocator_factory.h" -#include "call/call.h" -#include "logging/rtc_event_log/ice_logger.h" +#include "api/video/video_codec_constants.h" +#include "call/audio_state.h" +#include "call/packet_receiver.h" +#include "media/base/media_channel.h" +#include "media/base/media_config.h" #include "media/base/rid_description.h" -#include "media/sctp/sctp_transport.h" -#include "pc/audio_rtp_receiver.h" -#include "pc/audio_track.h" -#include "pc/channel.h" -#include "pc/channel_manager.h" -#include "pc/dtmf_sender.h" -#include "pc/media_stream.h" -#include "pc/media_stream_observer.h" -#include "pc/remote_audio_source.h" -#include "pc/rtp_media_utils.h" +#include "media/base/stream_params.h" +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "p2p/base/connection.h" +#include "p2p/base/connection_info.h" +#include "p2p/base/dtls_transport_internal.h" +#include "p2p/base/p2p_constants.h" +#include "p2p/base/p2p_transport_channel.h" +#include "p2p/base/transport_info.h" +#include "pc/ice_server_parsing.h" #include "pc/rtp_receiver.h" #include "pc/rtp_sender.h" #include "pc/sctp_transport.h" -#include "pc/sctp_utils.h" -#include "pc/sdp_utils.h" -#include "pc/stream_collection.h" -#include "pc/video_rtp_receiver.h" -#include "pc/video_track.h" +#include "pc/simulcast_description.h" +#include "pc/webrtc_session_description_factory.h" #include "rtc_base/bind.h" -#include "rtc_base/checks.h" +#include "rtc_base/helpers.h" +#include "rtc_base/ip_address.h" +#include "rtc_base/location.h" #include "rtc_base/logging.h" +#include "rtc_base/net_helper.h" +#include "rtc_base/network_constants.h" +#include "rtc_base/callback_list.h" +#include "rtc_base/socket_address.h" #include "rtc_base/string_encode.h" -#include "rtc_base/strings/string_builder.h" +#include "rtc_base/task_utils/to_queued_task.h" #include "rtc_base/trace_event.h" -#include "system_wrappers/include/clock.h" -#include "system_wrappers/include/field_trial.h" +#include "rtc_base/unique_id_generator.h" #include "system_wrappers/include/metrics.h" using cricket::ContentInfo; @@ -81,158 +80,14 @@ using cricket::STUN_PORT_TYPE; namespace webrtc { -// Error messages -const char kBundleWithoutRtcpMux[] = - "rtcp-mux must be enabled when BUNDLE " - "is enabled."; -const char kInvalidCandidates[] = "Description contains invalid candidates."; -const char kInvalidSdp[] = "Invalid session description."; -const char kMlineMismatchInAnswer[] = - "The order of m-lines in answer doesn't match order in offer. Rejecting " - "answer."; -const char kMlineMismatchInSubsequentOffer[] = - "The order of m-lines in subsequent offer doesn't match order from " - "previous offer/answer."; -const char kSdpWithoutDtlsFingerprint[] = - "Called with SDP without DTLS fingerprint."; -const char kSdpWithoutSdesCrypto[] = "Called with SDP without SDES crypto."; -const char kSdpWithoutIceUfragPwd[] = - "Called with SDP without ice-ufrag and ice-pwd."; -const char kSessionError[] = "Session error code: "; -const char kSessionErrorDesc[] = "Session error description: "; -const char kDtlsSrtpSetupFailureRtp[] = - "Couldn't set up DTLS-SRTP on RTP channel."; -const char kDtlsSrtpSetupFailureRtcp[] = - "Couldn't set up DTLS-SRTP on RTCP channel."; - namespace { // UMA metric names. -const char kSimulcastVersionApplyLocalDescription[] = - "WebRTC.PeerConnection.Simulcast.ApplyLocalDescription"; -const char kSimulcastVersionApplyRemoteDescription[] = - "WebRTC.PeerConnection.Simulcast.ApplyRemoteDescription"; const char kSimulcastNumberOfEncodings[] = "WebRTC.PeerConnection.Simulcast.NumberOfSendEncodings"; -const char kSimulcastDisabled[] = "WebRTC.PeerConnection.Simulcast.Disabled"; - -static const char kDefaultStreamId[] = "default"; -static const char kDefaultAudioSenderId[] = "defaulta0"; -static const char kDefaultVideoSenderId[] = "defaultv0"; - -// The length of RTCP CNAMEs. -static const int kRtcpCnameLength = 16; - -enum { - MSG_SET_SESSIONDESCRIPTION_SUCCESS = 0, - MSG_SET_SESSIONDESCRIPTION_FAILED, - MSG_CREATE_SESSIONDESCRIPTION_FAILED, - MSG_GETSTATS, - MSG_REPORT_USAGE_PATTERN, -}; static const int REPORT_USAGE_PATTERN_DELAY_MS = 60000; -struct SetSessionDescriptionMsg : public rtc::MessageData { - explicit SetSessionDescriptionMsg( - webrtc::SetSessionDescriptionObserver* observer) - : observer(observer) {} - - rtc::scoped_refptr observer; - RTCError error; -}; - -struct CreateSessionDescriptionMsg : public rtc::MessageData { - explicit CreateSessionDescriptionMsg( - webrtc::CreateSessionDescriptionObserver* observer) - : observer(observer) {} - - rtc::scoped_refptr observer; - RTCError error; -}; - -struct GetStatsMsg : public rtc::MessageData { - GetStatsMsg(webrtc::StatsObserver* observer, - webrtc::MediaStreamTrackInterface* track) - : observer(observer), track(track) {} - rtc::scoped_refptr observer; - rtc::scoped_refptr track; -}; - -// Check if we can send |new_stream| on a PeerConnection. -bool CanAddLocalMediaStream(webrtc::StreamCollectionInterface* current_streams, - webrtc::MediaStreamInterface* new_stream) { - if (!new_stream || !current_streams) { - return false; - } - if (current_streams->find(new_stream->id()) != nullptr) { - RTC_LOG(LS_ERROR) << "MediaStream with ID " << new_stream->id() - << " is already added."; - return false; - } - return true; -} - -// If the direction is "recvonly" or "inactive", treat the description -// as containing no streams. -// See: https://code.google.com/p/webrtc/issues/detail?id=5054 -std::vector GetActiveStreams( - const cricket::MediaContentDescription* desc) { - return RtpTransceiverDirectionHasSend(desc->direction()) - ? desc->streams() - : std::vector(); -} - -bool IsValidOfferToReceiveMedia(int value) { - typedef PeerConnectionInterface::RTCOfferAnswerOptions Options; - return (value >= Options::kUndefined) && - (value <= Options::kMaxOfferToReceiveMedia); -} - -// Add options to |[audio/video]_media_description_options| from |senders|. -void AddPlanBRtpSenderOptions( - const std::vector>>& senders, - cricket::MediaDescriptionOptions* audio_media_description_options, - cricket::MediaDescriptionOptions* video_media_description_options, - int num_sim_layers) { - for (const auto& sender : senders) { - if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) { - if (audio_media_description_options) { - audio_media_description_options->AddAudioSender( - sender->id(), sender->internal()->stream_ids()); - } - } else { - RTC_DCHECK(sender->media_type() == cricket::MEDIA_TYPE_VIDEO); - if (video_media_description_options) { - video_media_description_options->AddVideoSender( - sender->id(), sender->internal()->stream_ids(), {}, - SimulcastLayerList(), num_sim_layers); - } - } - } -} - -// Add options to |session_options| from |rtp_data_channels|. -void AddRtpDataChannelOptions( - const std::map>& - rtp_data_channels, - cricket::MediaDescriptionOptions* data_media_description_options) { - if (!data_media_description_options) { - return; - } - // Check for data channels. - for (const auto& kv : rtp_data_channels) { - const RtpDataChannel* channel = kv.second; - if (channel->state() == RtpDataChannel::kConnecting || - channel->state() == RtpDataChannel::kOpen) { - // Legacy RTP data channels are signaled with the track/stream ID set to - // the data channel's label. - data_media_description_options->AddRtpDataChannel(channel->label(), - channel->label()); - } - } -} uint32_t ConvertIceTransportTypeToCandidateFilter( PeerConnectionInterface::IceTransportsType type) { @@ -251,28 +106,6 @@ uint32_t ConvertIceTransportTypeToCandidateFilter( return cricket::CF_NONE; } -// Map internal signaling state name to spec name: -// https://w3c.github.io/webrtc-pc/#rtcsignalingstate-enum -std::string GetSignalingStateString( - PeerConnectionInterface::SignalingState state) { - switch (state) { - case PeerConnectionInterface::kStable: - return "stable"; - case PeerConnectionInterface::kHaveLocalOffer: - return "have-local-offer"; - case PeerConnectionInterface::kHaveLocalPrAnswer: - return "have-local-pranswer"; - case PeerConnectionInterface::kHaveRemoteOffer: - return "have-remote-offer"; - case PeerConnectionInterface::kHaveRemotePrAnswer: - return "have-remote-pranswer"; - case PeerConnectionInterface::kClosed: - return "closed"; - } - RTC_NOTREACHED(); - return ""; -} - IceCandidatePairType GetIceCandidatePairCounter( const cricket::Candidate& local, const cricket::Candidate& remote) { @@ -346,253 +179,6 @@ IceCandidatePairType GetIceCandidatePairCounter( return kIceCandidatePairMax; } -// Logic to decide if an m= section can be recycled. This means that the new -// m= section is not rejected, but the old local or remote m= section is -// rejected. |old_content_one| and |old_content_two| refer to the m= section -// of the old remote and old local descriptions in no particular order. -// We need to check both the old local and remote because either -// could be the most current from the latest negotation. -bool IsMediaSectionBeingRecycled(SdpType type, - const ContentInfo& content, - const ContentInfo* old_content_one, - const ContentInfo* old_content_two) { - return type == SdpType::kOffer && !content.rejected && - ((old_content_one && old_content_one->rejected) || - (old_content_two && old_content_two->rejected)); -} - -// Verify that the order of media sections in |new_desc| matches -// |current_desc|. The number of m= sections in |new_desc| should be no -// less than |current_desc|. In the case of checking an answer's -// |new_desc|, the |current_desc| is the last offer that was set as the -// local or remote. In the case of checking an offer's |new_desc| we -// check against the local and remote descriptions stored from the last -// negotiation, because either of these could be the most up to date for -// possible rejected m sections. These are the |current_desc| and -// |secondary_current_desc|. -bool MediaSectionsInSameOrder(const SessionDescription& current_desc, - const SessionDescription* secondary_current_desc, - const SessionDescription& new_desc, - const SdpType type) { - if (current_desc.contents().size() > new_desc.contents().size()) { - return false; - } - - for (size_t i = 0; i < current_desc.contents().size(); ++i) { - const cricket::ContentInfo* secondary_content_info = nullptr; - if (secondary_current_desc && - i < secondary_current_desc->contents().size()) { - secondary_content_info = &secondary_current_desc->contents()[i]; - } - if (IsMediaSectionBeingRecycled(type, new_desc.contents()[i], - ¤t_desc.contents()[i], - secondary_content_info)) { - // For new offer descriptions, if the media section can be recycled, it's - // valid for the MID and media type to change. - continue; - } - if (new_desc.contents()[i].name != current_desc.contents()[i].name) { - return false; - } - const MediaContentDescription* new_desc_mdesc = - new_desc.contents()[i].media_description(); - const MediaContentDescription* current_desc_mdesc = - current_desc.contents()[i].media_description(); - if (new_desc_mdesc->type() != current_desc_mdesc->type()) { - return false; - } - } - return true; -} - -bool MediaSectionsHaveSameCount(const SessionDescription& desc1, - const SessionDescription& desc2) { - return desc1.contents().size() == desc2.contents().size(); -} - -void NoteKeyProtocolAndMedia(KeyExchangeProtocolType protocol_type, - cricket::MediaType media_type) { - // Array of structs needed to map {KeyExchangeProtocolType, - // cricket::MediaType} to KeyExchangeProtocolMedia without using std::map in - // order to avoid -Wglobal-constructors and -Wexit-time-destructors. - static constexpr struct { - KeyExchangeProtocolType protocol_type; - cricket::MediaType media_type; - KeyExchangeProtocolMedia protocol_media; - } kEnumCounterKeyProtocolMediaMap[] = { - {kEnumCounterKeyProtocolDtls, cricket::MEDIA_TYPE_AUDIO, - kEnumCounterKeyProtocolMediaTypeDtlsAudio}, - {kEnumCounterKeyProtocolDtls, cricket::MEDIA_TYPE_VIDEO, - kEnumCounterKeyProtocolMediaTypeDtlsVideo}, - {kEnumCounterKeyProtocolDtls, cricket::MEDIA_TYPE_DATA, - kEnumCounterKeyProtocolMediaTypeDtlsData}, - {kEnumCounterKeyProtocolSdes, cricket::MEDIA_TYPE_AUDIO, - kEnumCounterKeyProtocolMediaTypeSdesAudio}, - {kEnumCounterKeyProtocolSdes, cricket::MEDIA_TYPE_VIDEO, - kEnumCounterKeyProtocolMediaTypeSdesVideo}, - {kEnumCounterKeyProtocolSdes, cricket::MEDIA_TYPE_DATA, - kEnumCounterKeyProtocolMediaTypeSdesData}, - }; - - RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.KeyProtocol", protocol_type, - kEnumCounterKeyProtocolMax); - - for (const auto& i : kEnumCounterKeyProtocolMediaMap) { - if (i.protocol_type == protocol_type && i.media_type == media_type) { - RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.KeyProtocolByMedia", - i.protocol_media, - kEnumCounterKeyProtocolMediaTypeMax); - } - } -} - -void NoteAddIceCandidateResult(int result) { - RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.AddIceCandidate", result, - kAddIceCandidateMax); -} - -// Checks that each non-rejected content has SDES crypto keys or a DTLS -// fingerprint, unless it's in a BUNDLE group, in which case only the -// BUNDLE-tag section (first media section/description in the BUNDLE group) -// needs a ufrag and pwd. Mismatches, such as replying with a DTLS fingerprint -// to SDES keys, will be caught in JsepTransport negotiation, and backstopped -// by Channel's |srtp_required| check. -RTCError VerifyCrypto(const SessionDescription* desc, bool dtls_enabled) { - const cricket::ContentGroup* bundle = - desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); - for (const cricket::ContentInfo& content_info : desc->contents()) { - if (content_info.rejected) { - continue; - } - // Note what media is used with each crypto protocol, for all sections. - NoteKeyProtocolAndMedia(dtls_enabled ? webrtc::kEnumCounterKeyProtocolDtls - : webrtc::kEnumCounterKeyProtocolSdes, - content_info.media_description()->type()); - const std::string& mid = content_info.name; - if (bundle && bundle->HasContentName(mid) && - mid != *(bundle->FirstContentName())) { - // This isn't the first media section in the BUNDLE group, so it's not - // required to have crypto attributes, since only the crypto attributes - // from the first section actually get used. - continue; - } - - // If the content isn't rejected or bundled into another m= section, crypto - // must be present. - const MediaContentDescription* media = content_info.media_description(); - const TransportInfo* tinfo = desc->GetTransportInfoByName(mid); - if (!media || !tinfo) { - // Something is not right. - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, kInvalidSdp); - } - if (dtls_enabled) { - if (!tinfo->description.identity_fingerprint) { - RTC_LOG(LS_WARNING) - << "Session description must have DTLS fingerprint if " - "DTLS enabled."; - return RTCError(RTCErrorType::INVALID_PARAMETER, - kSdpWithoutDtlsFingerprint); - } - } else { - if (media->cryptos().empty()) { - RTC_LOG(LS_WARNING) - << "Session description must have SDES when DTLS disabled."; - return RTCError(RTCErrorType::INVALID_PARAMETER, kSdpWithoutSdesCrypto); - } - } - } - return RTCError::OK(); -} - -// Checks that each non-rejected content has ice-ufrag and ice-pwd set, unless -// it's in a BUNDLE group, in which case only the BUNDLE-tag section (first -// media section/description in the BUNDLE group) needs a ufrag and pwd. -bool VerifyIceUfragPwdPresent(const SessionDescription* desc) { - const cricket::ContentGroup* bundle = - desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); - for (const cricket::ContentInfo& content_info : desc->contents()) { - if (content_info.rejected) { - continue; - } - const std::string& mid = content_info.name; - if (bundle && bundle->HasContentName(mid) && - mid != *(bundle->FirstContentName())) { - // This isn't the first media section in the BUNDLE group, so it's not - // required to have ufrag/password, since only the ufrag/password from - // the first section actually get used. - continue; - } - - // If the content isn't rejected or bundled into another m= section, - // ice-ufrag and ice-pwd must be present. - const TransportInfo* tinfo = desc->GetTransportInfoByName(mid); - if (!tinfo) { - // Something is not right. - RTC_LOG(LS_ERROR) << kInvalidSdp; - return false; - } - if (tinfo->description.ice_ufrag.empty() || - tinfo->description.ice_pwd.empty()) { - RTC_LOG(LS_ERROR) << "Session description must have ice ufrag and pwd."; - return false; - } - } - return true; -} - -// Returns true if |new_desc| requests an ICE restart (i.e., new ufrag/pwd). -bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc, - const SessionDescriptionInterface* new_desc, - const std::string& content_name) { - if (!old_desc) { - return false; - } - const SessionDescription* new_sd = new_desc->description(); - const SessionDescription* old_sd = old_desc->description(); - const ContentInfo* cinfo = new_sd->GetContentByName(content_name); - if (!cinfo || cinfo->rejected) { - return false; - } - // If the content isn't rejected, check if ufrag and password has changed. - const cricket::TransportDescription* new_transport_desc = - new_sd->GetTransportDescriptionByName(content_name); - const cricket::TransportDescription* old_transport_desc = - old_sd->GetTransportDescriptionByName(content_name); - if (!new_transport_desc || !old_transport_desc) { - // No transport description exists. This is not an ICE restart. - return false; - } - if (cricket::IceCredentialsChanged( - old_transport_desc->ice_ufrag, old_transport_desc->ice_pwd, - new_transport_desc->ice_ufrag, new_transport_desc->ice_pwd)) { - RTC_LOG(LS_INFO) << "Remote peer requests ICE restart for " << content_name - << "."; - return true; - } - return false; -} - -// Generates a string error message for SetLocalDescription/SetRemoteDescription -// from an RTCError. -std::string GetSetDescriptionErrorMessage(cricket::ContentSource source, - SdpType type, - const RTCError& error) { - rtc::StringBuilder oss; - oss << "Failed to set " << (source == cricket::CS_LOCAL ? "local" : "remote") - << " " << SdpTypeToString(type) << " sdp: " << error.message(); - return oss.Release(); -} - -std::string GetStreamIdsString(rtc::ArrayView stream_ids) { - std::string output = "streams=["; - const char* separator = ""; - for (const auto& stream_id : stream_ids) { - output.append(separator).append(stream_id); - separator = ", "; - } - output.append("]"); - return output; -} absl::optional RTCConfigurationToIceConfigOptionalInt( int rtc_configuration_parameter) { @@ -603,88 +189,6 @@ absl::optional RTCConfigurationToIceConfigOptionalInt( return rtc_configuration_parameter; } -void ReportSimulcastApiVersion(const char* name, - const SessionDescription& session) { - bool has_legacy = false; - bool has_spec_compliant = false; - for (const ContentInfo& content : session.contents()) { - if (!content.media_description()) { - continue; - } - has_spec_compliant |= content.media_description()->HasSimulcast(); - for (const StreamParams& sp : content.media_description()->streams()) { - has_legacy |= sp.has_ssrc_group(cricket::kSimSsrcGroupSemantics); - } - } - - if (has_legacy) { - RTC_HISTOGRAM_ENUMERATION(name, kSimulcastApiVersionLegacy, - kSimulcastApiVersionMax); - } - if (has_spec_compliant) { - RTC_HISTOGRAM_ENUMERATION(name, kSimulcastApiVersionSpecCompliant, - kSimulcastApiVersionMax); - } - if (!has_legacy && !has_spec_compliant) { - RTC_HISTOGRAM_ENUMERATION(name, kSimulcastApiVersionNone, - kSimulcastApiVersionMax); - } -} - -const ContentInfo* FindTransceiverMSection( - RtpTransceiverProxyWithInternal* transceiver, - const SessionDescriptionInterface* session_description) { - return transceiver->mid() - ? session_description->description()->GetContentByName( - *transceiver->mid()) - : nullptr; -} - -// Wraps a CreateSessionDescriptionObserver and an OperationsChain operation -// complete callback. When the observer is invoked, the wrapped observer is -// invoked followed by invoking the completion callback. -class CreateSessionDescriptionObserverOperationWrapper - : public CreateSessionDescriptionObserver { - public: - CreateSessionDescriptionObserverOperationWrapper( - rtc::scoped_refptr observer, - std::function operation_complete_callback) - : observer_(std::move(observer)), - operation_complete_callback_(std::move(operation_complete_callback)) { - RTC_DCHECK(observer_); - } - ~CreateSessionDescriptionObserverOperationWrapper() override { - RTC_DCHECK(was_called_); - } - - void OnSuccess(SessionDescriptionInterface* desc) override { - RTC_DCHECK(!was_called_); -#ifdef RTC_DCHECK_IS_ON - was_called_ = true; -#endif // RTC_DCHECK_IS_ON - // Completing the operation before invoking the observer allows the observer - // to execute SetLocalDescription() without delay. - operation_complete_callback_(); - observer_->OnSuccess(desc); - } - - void OnFailure(RTCError error) override { - RTC_DCHECK(!was_called_); -#ifdef RTC_DCHECK_IS_ON - was_called_ = true; -#endif // RTC_DCHECK_IS_ON - operation_complete_callback_(); - observer_->OnFailure(std::move(error)); - } - - private: -#ifdef RTC_DCHECK_IS_ON - bool was_called_ = false; -#endif // RTC_DCHECK_IS_ON - rtc::scoped_refptr observer_; - std::function operation_complete_callback_; -}; - // Check if the changes of IceTransportsType motives an ice restart. bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed, PeerConnectionInterface::IceTransportsType current, @@ -705,156 +209,62 @@ bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed, return (current_filter & modified_filter) != current_filter; } -} // namespace - -// Used by parameterless SetLocalDescription() to create an offer or answer. -// Upon completion of creating the session description, SetLocalDescription() is -// invoked with the result. -class PeerConnection::ImplicitCreateSessionDescriptionObserver - : public CreateSessionDescriptionObserver { - public: - ImplicitCreateSessionDescriptionObserver( - rtc::WeakPtr pc, - rtc::scoped_refptr - set_local_description_observer) - : pc_(std::move(pc)), - set_local_description_observer_( - std::move(set_local_description_observer)) {} - ~ImplicitCreateSessionDescriptionObserver() override { - RTC_DCHECK(was_called_); +cricket::IceConfig ParseIceConfig( + const PeerConnectionInterface::RTCConfiguration& config) { + cricket::ContinualGatheringPolicy gathering_policy; + switch (config.continual_gathering_policy) { + case PeerConnectionInterface::GATHER_ONCE: + gathering_policy = cricket::GATHER_ONCE; + break; + case PeerConnectionInterface::GATHER_CONTINUALLY: + gathering_policy = cricket::GATHER_CONTINUALLY; + break; + default: + RTC_NOTREACHED(); + gathering_policy = cricket::GATHER_ONCE; } - void SetOperationCompleteCallback( - std::function operation_complete_callback) { - operation_complete_callback_ = std::move(operation_complete_callback); - } + cricket::IceConfig ice_config; + ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt( + config.ice_connection_receiving_timeout); + ice_config.prioritize_most_likely_candidate_pairs = + config.prioritize_most_likely_ice_candidate_pairs; + ice_config.backup_connection_ping_interval = + RTCConfigurationToIceConfigOptionalInt( + config.ice_backup_candidate_pair_ping_interval); + ice_config.continual_gathering_policy = gathering_policy; + ice_config.presume_writable_when_fully_relayed = + config.presume_writable_when_fully_relayed; + ice_config.surface_ice_candidates_on_ice_transport_type_changed = + config.surface_ice_candidates_on_ice_transport_type_changed; + ice_config.ice_check_interval_strong_connectivity = + config.ice_check_interval_strong_connectivity; + ice_config.ice_check_interval_weak_connectivity = + config.ice_check_interval_weak_connectivity; + ice_config.ice_check_min_interval = config.ice_check_min_interval; + ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout; + ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks; + ice_config.ice_inactive_timeout = config.ice_inactive_timeout; + ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval; + ice_config.network_preference = config.network_preference; + return ice_config; +} - bool was_called() const { return was_called_; } - - void OnSuccess(SessionDescriptionInterface* desc_ptr) override { - RTC_DCHECK(!was_called_); - std::unique_ptr desc(desc_ptr); - was_called_ = true; - - // Abort early if |pc_| is no longer valid. - if (!pc_) { - operation_complete_callback_(); - return; - } - // DoSetLocalDescription() is a synchronous operation that invokes - // |set_local_description_observer_| with the result. - pc_->DoSetLocalDescription(std::move(desc), - std::move(set_local_description_observer_)); - operation_complete_callback_(); - } - - void OnFailure(RTCError error) override { - RTC_DCHECK(!was_called_); - was_called_ = true; - set_local_description_observer_->OnSetLocalDescriptionComplete(RTCError( - error.type(), std::string("SetLocalDescription failed to create " - "session description - ") + - error.message())); - operation_complete_callback_(); - } - - private: - bool was_called_ = false; - rtc::WeakPtr pc_; - rtc::scoped_refptr - set_local_description_observer_; - std::function operation_complete_callback_; -}; - -class PeerConnection::LocalIceCredentialsToReplace { - public: - // Sets the ICE credentials that need restarting to the ICE credentials of - // the current and pending descriptions. - void SetIceCredentialsFromLocalDescriptions( - const SessionDescriptionInterface* current_local_description, - const SessionDescriptionInterface* pending_local_description) { - ice_credentials_.clear(); - if (current_local_description) { - AppendIceCredentialsFromSessionDescription(*current_local_description); - } - if (pending_local_description) { - AppendIceCredentialsFromSessionDescription(*pending_local_description); - } - } - - void ClearIceCredentials() { ice_credentials_.clear(); } - - // Returns true if we have ICE credentials that need restarting. - bool HasIceCredentials() const { return !ice_credentials_.empty(); } - - // Returns true if |local_description| shares no ICE credentials with the - // ICE credentials that need restarting. - bool SatisfiesIceRestart( - const SessionDescriptionInterface& local_description) const { - for (const auto& transport_info : - local_description.description()->transport_infos()) { - if (ice_credentials_.find(std::make_pair( - transport_info.description.ice_ufrag, - transport_info.description.ice_pwd)) != ice_credentials_.end()) { - return false; - } - } - return true; - } - - private: - void AppendIceCredentialsFromSessionDescription( - const SessionDescriptionInterface& desc) { - for (const auto& transport_info : desc.description()->transport_infos()) { - ice_credentials_.insert( - std::make_pair(transport_info.description.ice_ufrag, - transport_info.description.ice_pwd)); - } - } - - std::set> ice_credentials_; -}; - -// Wrapper for SetSessionDescriptionObserver that invokes the success or failure -// callback in a posted message handled by the peer connection. This introduces -// a delay that prevents recursive API calls by the observer, but this also -// means that the PeerConnection can be modified before the observer sees the -// result of the operation. This is ill-advised for synchronizing states. +// Ensures the configuration doesn't have any parameters with invalid values, +// or values that conflict with other parameters. // -// Implements both the SetLocalDescriptionObserverInterface and the -// SetRemoteDescriptionObserverInterface. -class PeerConnection::SetSessionDescriptionObserverAdapter - : public SetLocalDescriptionObserverInterface, - public SetRemoteDescriptionObserverInterface { - public: - SetSessionDescriptionObserverAdapter( - rtc::WeakPtr pc, - rtc::scoped_refptr inner_observer) - : pc_(std::move(pc)), inner_observer_(std::move(inner_observer)) {} +// Returns RTCError::OK() if there are no issues. +RTCError ValidateConfiguration( + const PeerConnectionInterface::RTCConfiguration& config) { + return cricket::P2PTransportChannel::ValidateIceConfig( + ParseIceConfig(config)); +} - // SetLocalDescriptionObserverInterface implementation. - void OnSetLocalDescriptionComplete(RTCError error) override { - OnSetDescriptionComplete(std::move(error)); - } - // SetRemoteDescriptionObserverInterface implementation. - void OnSetRemoteDescriptionComplete(RTCError error) override { - OnSetDescriptionComplete(std::move(error)); - } +bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) { + return content->media_description()->rtcp_mux(); +} - private: - void OnSetDescriptionComplete(RTCError error) { - if (!pc_) - return; - if (error.ok()) { - pc_->PostSetSessionDescriptionSuccess(inner_observer_); - } else { - pc_->PostSetSessionDescriptionFailure(inner_observer_, std::move(error)); - } - } - - rtc::WeakPtr pc_; - rtc::scoped_refptr inner_observer_; -}; +} // namespace bool PeerConnectionInterface::RTCConfiguration::operator==( const PeerConnectionInterface::RTCConfiguration& o) const { @@ -908,6 +318,7 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( std::string turn_logging_id; bool enable_implicit_rollback; absl::optional allow_codec_switching; + absl::optional report_usage_pattern_delay_ms; }; static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this), "Did you add something to RTCConfiguration and forget to " @@ -967,7 +378,8 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( offer_extmap_allow_mixed == o.offer_extmap_allow_mixed && turn_logging_id == o.turn_logging_id && enable_implicit_rollback == o.enable_implicit_rollback && - allow_codec_switching == o.allow_codec_switching; + allow_codec_switching == o.allow_codec_switching && + report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms; } bool PeerConnectionInterface::RTCConfiguration::operator!=( @@ -975,82 +387,84 @@ bool PeerConnectionInterface::RTCConfiguration::operator!=( return !(*this == o); } -void PeerConnection::TransceiverStableState::set_newly_created() { - RTC_DCHECK(!has_m_section_); - newly_created_ = true; -} - -void PeerConnection::TransceiverStableState::SetMSectionIfUnset( - absl::optional mid, - absl::optional mline_index) { - if (!has_m_section_) { - mid_ = mid; - mline_index_ = mline_index; - has_m_section_ = true; +rtc::scoped_refptr PeerConnection::Create( + rtc::scoped_refptr context, + const PeerConnectionFactoryInterface::Options& options, + std::unique_ptr event_log, + std::unique_ptr call, + const PeerConnectionInterface::RTCConfiguration& configuration, + PeerConnectionDependencies dependencies) { + RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig( + ParseIceConfig(configuration)); + if (!config_error.ok()) { + RTC_LOG(LS_ERROR) << "Invalid configuration: " << config_error.message(); + return nullptr; } -} -void PeerConnection::TransceiverStableState::SetRemoteStreamIdsIfUnset( - const std::vector& ids) { - if (!remote_stream_ids_.has_value()) { - remote_stream_ids_ = ids; + if (!dependencies.allocator) { + RTC_LOG(LS_ERROR) + << "PeerConnection initialized without a PortAllocator? " + "This shouldn't happen if using PeerConnectionFactory."; + return nullptr; } -} -// Generate a RTCP CNAME when a PeerConnection is created. -std::string GenerateRtcpCname() { - std::string cname; - if (!rtc::CreateRandomString(kRtcpCnameLength, &cname)) { - RTC_LOG(LS_ERROR) << "Failed to generate CNAME."; - RTC_NOTREACHED(); + if (!dependencies.observer) { + // TODO(deadbeef): Why do we do this? + RTC_LOG(LS_ERROR) << "PeerConnection initialized without a " + "PeerConnectionObserver"; + return nullptr; } - return cname; + + bool is_unified_plan = + configuration.sdp_semantics == SdpSemantics::kUnifiedPlan; + // The PeerConnection constructor consumes some, but not all, dependencies. + rtc::scoped_refptr pc( + new rtc::RefCountedObject( + context, options, is_unified_plan, std::move(event_log), + std::move(call), dependencies)); + if (!pc->Initialize(configuration, std::move(dependencies))) { + return nullptr; + } + return pc; } -bool ValidateOfferAnswerOptions( - const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options) { - return IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_audio) && - IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_video); -} - -// From |rtc_options|, fill parts of |session_options| shared by all generated -// m= sections (in other words, nothing that involves a map/array). -void ExtractSharedMediaSessionOptions( - const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, - cricket::MediaSessionOptions* session_options) { - session_options->vad_enabled = rtc_options.voice_activity_detection; - session_options->bundle_enabled = rtc_options.use_rtp_mux; - session_options->raw_packetization_for_video = - rtc_options.raw_packetization_for_video; -} - -PeerConnection::PeerConnection(PeerConnectionFactory* factory, - std::unique_ptr event_log, - std::unique_ptr call) - : factory_(factory), +PeerConnection::PeerConnection( + rtc::scoped_refptr context, + const PeerConnectionFactoryInterface::Options& options, + bool is_unified_plan, + std::unique_ptr event_log, + std::unique_ptr call, + PeerConnectionDependencies& dependencies) + : context_(context), + options_(options), + observer_(dependencies.observer), + is_unified_plan_(is_unified_plan), event_log_(std::move(event_log)), event_log_ptr_(event_log_.get()), - operations_chain_(rtc::OperationsChain::Create()), - rtcp_cname_(GenerateRtcpCname()), - local_streams_(StreamCollection::Create()), - remote_streams_(StreamCollection::Create()), + async_resolver_factory_(std::move(dependencies.async_resolver_factory)), + port_allocator_(std::move(dependencies.allocator)), + ice_transport_factory_(std::move(dependencies.ice_transport_factory)), + tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)), call_(std::move(call)), call_ptr_(call_.get()), - local_ice_credentials_to_replace_(new LocalIceCredentialsToReplace()), data_channel_controller_(this), - weak_ptr_factory_(this) {} + message_handler_(signaling_thread()) {} PeerConnection::~PeerConnection() { TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection"); RTC_DCHECK_RUN_ON(signaling_thread()); - weak_ptr_factory_.InvalidateWeakPtrs(); + if (sdp_handler_) { + sdp_handler_->PrepareForShutdown(); + } // Need to stop transceivers before destroying the stats collector because // AudioRtpSender has a reference to the StatsCollector it will update when // stopping. - for (const auto& transceiver : transceivers_) { - transceiver->StopInternal(); + if (rtp_manager()) { + for (const auto& transceiver : rtp_manager()->transceivers()->List()) { + transceiver->StopInternal(); + } } stats_.reset(nullptr); @@ -1059,14 +473,15 @@ PeerConnection::~PeerConnection() { stats_collector_ = nullptr; } - // Don't destroy BaseChannels until after stats has been cleaned up so that - // the last stats request can still read from the channels. - DestroyAllChannels(); + if (sdp_handler_) { + // Don't destroy BaseChannels until after stats has been cleaned up so that + // the last stats request can still read from the channels. + sdp_handler_->DestroyAllChannels(); - RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed."; + RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed."; - webrtc_session_desc_factory_.reset(); - sctp_factory_.reset(); + sdp_handler_->ResetSessionDescFactory(); + } transport_controller_.reset(); // port_allocator_ lives on the network thread and should be destroyed there. @@ -1077,43 +492,11 @@ PeerConnection::~PeerConnection() { // call_ and event_log_ must be destroyed on the worker thread. worker_thread()->Invoke(RTC_FROM_HERE, [this] { RTC_DCHECK_RUN_ON(worker_thread()); + call_safety_.reset(); call_.reset(); // The event log must outlive call (and any other object that uses it). event_log_.reset(); }); - - // Process all pending notifications in the message queue. If we don't do - // this, requests will linger and not know they succeeded or failed. - rtc::MessageList list; - signaling_thread()->Clear(this, rtc::MQID_ANY, &list); - for (auto& msg : list) { - if (msg.message_id == MSG_CREATE_SESSIONDESCRIPTION_FAILED) { - // Processing CreateOffer() and CreateAnswer() messages ensures their - // observers are invoked even if the PeerConnection is destroyed early. - OnMessage(&msg); - } else { - // TODO(hbos): Consider processing all pending messages. This would mean - // that SetLocalDescription() and SetRemoteDescription() observers are - // informed of successes and failures; this is currently NOT the case. - delete msg.pdata; - } - } -} - -void PeerConnection::DestroyAllChannels() { - // Destroy video channels first since they may have a pointer to a voice - // channel. - for (const auto& transceiver : transceivers_) { - if (transceiver->media_type() == cricket::MEDIA_TYPE_VIDEO) { - DestroyTransceiverChannel(transceiver); - } - } - for (const auto& transceiver : transceivers_) { - if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { - DestroyTransceiverChannel(transceiver); - } - } - DestroyDataChannelTransport(); } bool PeerConnection::Initialize( @@ -1122,33 +505,6 @@ bool PeerConnection::Initialize( RTC_DCHECK_RUN_ON(signaling_thread()); TRACE_EVENT0("webrtc", "PeerConnection::Initialize"); - RTCError config_error = ValidateConfiguration(configuration); - if (!config_error.ok()) { - RTC_LOG(LS_ERROR) << "Invalid configuration: " << config_error.message(); - return false; - } - - if (!dependencies.allocator) { - RTC_LOG(LS_ERROR) - << "PeerConnection initialized without a PortAllocator? " - "This shouldn't happen if using PeerConnectionFactory."; - return false; - } - - if (!dependencies.observer) { - // TODO(deadbeef): Why do we do this? - RTC_LOG(LS_ERROR) << "PeerConnection initialized without a " - "PeerConnectionObserver"; - return false; - } - - observer_ = dependencies.observer; - async_resolver_factory_ = std::move(dependencies.async_resolver_factory); - port_allocator_ = std::move(dependencies.allocator); - packet_socket_factory_ = std::move(dependencies.packet_socket_factory); - ice_transport_factory_ = std::move(dependencies.ice_transport_factory); - tls_cert_verifier_ = std::move(dependencies.tls_cert_verifier); - cricket::ServerAddresses stun_servers; std::vector turn_servers; @@ -1171,8 +527,7 @@ bool PeerConnection::Initialize( rtc::Bind(&PeerConnection::InitializePortAllocator_n, this, stun_servers, turn_servers, configuration)); - // If initialization was successful, note if STUN or TURN servers - // were supplied. + // Note if STUN or TURN servers were supplied. if (!stun_servers.empty()) { NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED); } @@ -1190,8 +545,6 @@ bool PeerConnection::Initialize( RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", address_family, kPeerConnectionAddressFamilyCounter_Max); - const PeerConnectionFactoryInterface::Options& options = factory_->options(); - // RFC 3264: The numeric value of the session id and version in the // o line MUST be representable with a "64 bit signed integer". // Due to this constraint session id |session_id_| is max limited to @@ -1200,63 +553,35 @@ bool PeerConnection::Initialize( JsepTransportController::Config config; config.redetermine_role_on_ice_restart = configuration.redetermine_role_on_ice_restart; - config.ssl_max_version = factory_->options().ssl_max_version; - config.disable_encryption = options.disable_encryption; + config.ssl_max_version = options_.ssl_max_version; + config.disable_encryption = options_.disable_encryption; config.bundle_policy = configuration.bundle_policy; config.rtcp_mux_policy = configuration.rtcp_mux_policy; - // TODO(bugs.webrtc.org/9891) - Remove options.crypto_options then remove this - // stub. + // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove + // this stub. config.crypto_options = configuration.crypto_options.has_value() ? *configuration.crypto_options - : options.crypto_options; + : options_.crypto_options; config.transport_observer = this; - // It's safe to pass |this| and using |rtcp_invoker_| and the |call_| pointer - // since the JsepTransportController instance is owned by this PeerConnection - // instance and is destroyed before both |rtcp_invoker_| and the |call_| - // pointer. - config.rtcp_handler = [this](const rtc::CopyOnWriteBuffer& packet, - int64_t packet_time_us) { - RTC_DCHECK_RUN_ON(network_thread()); - rtcp_invoker_.AsyncInvoke( - RTC_FROM_HERE, worker_thread(), [this, packet, packet_time_us] { - RTC_DCHECK_RUN_ON(worker_thread()); - // |call_| is reset on the worker thread in the PeerConnection - // destructor, so we check that it's still valid before propagating - // the packet. - if (call_) { - call_->Receiver()->DeliverPacket(MediaType::ANY, packet, - packet_time_us); - } - }); - }; + config.rtcp_handler = InitializeRtcpCallback(); config.event_log = event_log_ptr_; #if defined(ENABLE_EXTERNAL_AUTH) config.enable_external_auth = true; #endif config.active_reset_srtp_params = configuration.active_reset_srtp_params; - // Obtain a certificate from RTCConfiguration if any were provided (optional). - rtc::scoped_refptr certificate; - if (!configuration.certificates.empty()) { - // TODO(hbos,torbjorng): Decide on certificate-selection strategy instead of - // just picking the first one. The decision should be made based on the DTLS - // handshake. The DTLS negotiations need to know about all certificates. - certificate = configuration.certificates[0]; - } - - if (options.disable_encryption) { + if (options_.disable_encryption) { dtls_enabled_ = false; } else { // Enable DTLS by default if we have an identity store or a certificate. - dtls_enabled_ = (dependencies.cert_generator || certificate); + dtls_enabled_ = + (dependencies.cert_generator || !configuration.certificates.empty()); // |configuration| can override the default |dtls_enabled_| value. if (configuration.enable_dtls_srtp) { dtls_enabled_ = *(configuration.enable_dtls_srtp); } } - sctp_factory_ = factory_->CreateSctpTransportInternalFactory(); - if (configuration.enable_rtp_data_channel) { // Enable creation of RTP data channels if the kEnableRtpDataChannels is // set. It takes precendence over the disable_sctp_data_channels @@ -1264,9 +589,9 @@ bool PeerConnection::Initialize( data_channel_controller_.set_data_channel_type(cricket::DCT_RTP); } else { // DTLS has to be enabled to use SCTP. - if (!options.disable_sctp_data_channels && dtls_enabled_) { + if (!options_.disable_sctp_data_channels && dtls_enabled_) { data_channel_controller_.set_data_channel_type(cricket::DCT_SCTP); - config.sctp_factory = sctp_factory_.get(); + config.sctp_factory = context_->sctp_transport_factory(); } } @@ -1275,8 +600,6 @@ bool PeerConnection::Initialize( transport_controller_.reset(new JsepTransportController( signaling_thread(), network_thread(), port_allocator_.get(), async_resolver_factory_.get(), config)); - transport_controller_->SignalIceConnectionState.connect( - this, &PeerConnection::OnTransportControllerConnectionState); transport_controller_->SignalStandardizedIceConnectionState.connect( this, &PeerConnection::SetStandardizedIceConnectionState); transport_controller_->SignalConnectionState.connect( @@ -1293,92 +616,63 @@ bool PeerConnection::Initialize( this, &PeerConnection::OnTransportControllerDtlsHandshakeError); transport_controller_->SignalIceCandidatePairChanged.connect( this, &PeerConnection::OnTransportControllerCandidateChanged); + transport_controller_->SignalErrorDemuxingPacket.connect( + this, &PeerConnection::OnErrorDemuxingPacket); - stats_.reset(new StatsCollector(this)); - stats_collector_ = RTCStatsCollector::Create(this); + transport_controller_->SignalIceConnectionState.AddReceiver( + [this](cricket::IceConnectionState s) { + RTC_DCHECK_RUN_ON(signaling_thread()); + OnTransportControllerConnectionState(s); + }); configuration_ = configuration; transport_controller_->SetIceConfig(ParseIceConfig(configuration)); - video_options_.screencast_min_bitrate_kbps = - configuration.screencast_min_bitrate; - audio_options_.combined_audio_video_bwe = - configuration.combined_audio_video_bwe; + stats_ = std::make_unique(this); + stats_collector_ = RTCStatsCollector::Create(this); - audio_options_.audio_jitter_buffer_max_packets = - configuration.audio_jitter_buffer_max_packets; + demuxing_observer_ = new rtc::RefCountedObject(observer_); - audio_options_.audio_jitter_buffer_fast_accelerate = - configuration.audio_jitter_buffer_fast_accelerate; + sdp_handler_ = + SdpOfferAnswerHandler::Create(this, configuration, dependencies); - audio_options_.audio_jitter_buffer_min_delay_ms = - configuration.audio_jitter_buffer_min_delay_ms; - - audio_options_.audio_jitter_buffer_enable_rtx_handling = - configuration.audio_jitter_buffer_enable_rtx_handling; - - // Whether the certificate generator/certificate is null or not determines - // what PeerConnectionDescriptionFactory will do, so make sure that we give it - // the right instructions by clearing the variables if needed. - if (!dtls_enabled_) { - dependencies.cert_generator.reset(); - certificate = nullptr; - } else if (certificate) { - // Favor generated certificate over the certificate generator. - dependencies.cert_generator.reset(); - } - - webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( - signaling_thread(), channel_manager(), this, session_id(), - std::move(dependencies.cert_generator), certificate, &ssrc_generator_)); - webrtc_session_desc_factory_->SignalCertificateReady.connect( - this, &PeerConnection::OnCertificateReady); - - if (options.disable_encryption) { - webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); - } - - webrtc_session_desc_factory_->set_enable_encrypted_rtp_header_extensions( - GetCryptoOptions().srtp.enable_encrypted_rtp_header_extensions); - webrtc_session_desc_factory_->set_is_unified_plan(IsUnifiedPlan()); + rtp_manager_ = std::make_unique( + IsUnifiedPlan(), signaling_thread(), worker_thread(), channel_manager(), + &usage_pattern_, observer_, stats_.get(), [this]() { + RTC_DCHECK_RUN_ON(signaling_thread()); + sdp_handler_->UpdateNegotiationNeeded(); + }); // Add default audio/video transceivers for Plan B SDP. if (!IsUnifiedPlan()) { - transceivers_.push_back( + rtp_manager()->transceivers()->Add( RtpTransceiverProxyWithInternal::Create( signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_AUDIO))); - transceivers_.push_back( + rtp_manager()->transceivers()->Add( RtpTransceiverProxyWithInternal::Create( signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_VIDEO))); } - int delay_ms = - return_histogram_very_quickly_ ? 0 : REPORT_USAGE_PATTERN_DELAY_MS; - signaling_thread()->PostDelayed(RTC_FROM_HERE, delay_ms, this, - MSG_REPORT_USAGE_PATTERN, nullptr); - if (dependencies.video_bitrate_allocator_factory) { - video_bitrate_allocator_factory_ = - std::move(dependencies.video_bitrate_allocator_factory); - } else { - video_bitrate_allocator_factory_ = - CreateBuiltinVideoBitrateAllocatorFactory(); - } + int delay_ms = configuration.report_usage_pattern_delay_ms + ? *configuration.report_usage_pattern_delay_ms + : REPORT_USAGE_PATTERN_DELAY_MS; + message_handler_.RequestUsagePatternReport( + [this]() { + RTC_DCHECK_RUN_ON(signaling_thread()); + ReportUsagePattern(); + }, + delay_ms); + return true; } -RTCError PeerConnection::ValidateConfiguration( - const RTCConfiguration& config) const { - return cricket::P2PTransportChannel::ValidateIceConfig( - ParseIceConfig(config)); -} - rtc::scoped_refptr PeerConnection::local_streams() { RTC_DCHECK_RUN_ON(signaling_thread()); RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified " "Plan SdpSemantics. Please use GetSenders " "instead."; - return local_streams_; + return sdp_handler_->local_streams(); } rtc::scoped_refptr PeerConnection::remote_streams() { @@ -1386,7 +680,7 @@ rtc::scoped_refptr PeerConnection::remote_streams() { RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified " "Plan SdpSemantics. Please use GetReceivers " "instead."; - return remote_streams_; + return sdp_handler_->remote_streams(); } bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { @@ -1394,35 +688,7 @@ bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan " "SdpSemantics. Please use AddTrack instead."; TRACE_EVENT0("webrtc", "PeerConnection::AddStream"); - if (IsClosed()) { - return false; - } - if (!CanAddLocalMediaStream(local_streams_, local_stream)) { - return false; - } - - local_streams_->AddStream(local_stream); - MediaStreamObserver* observer = new MediaStreamObserver(local_stream); - observer->SignalAudioTrackAdded.connect(this, - &PeerConnection::OnAudioTrackAdded); - observer->SignalAudioTrackRemoved.connect( - this, &PeerConnection::OnAudioTrackRemoved); - observer->SignalVideoTrackAdded.connect(this, - &PeerConnection::OnVideoTrackAdded); - observer->SignalVideoTrackRemoved.connect( - this, &PeerConnection::OnVideoTrackRemoved); - stream_observers_.push_back(std::unique_ptr(observer)); - - for (const auto& track : local_stream->GetAudioTracks()) { - AddAudioTrack(track.get(), local_stream); - } - for (const auto& track : local_stream->GetVideoTracks()) { - AddVideoTrack(track.get(), local_stream); - } - - stats_->AddStream(local_stream); - UpdateNegotiationNeeded(); - return true; + return sdp_handler_->AddStream(local_stream); } void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { @@ -1431,27 +697,7 @@ void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { "Plan SdpSemantics. Please use RemoveTrack " "instead."; TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream"); - if (!IsClosed()) { - for (const auto& track : local_stream->GetAudioTracks()) { - RemoveAudioTrack(track.get(), local_stream); - } - for (const auto& track : local_stream->GetVideoTracks()) { - RemoveVideoTrack(track.get(), local_stream); - } - } - local_streams_->RemoveStream(local_stream); - stream_observers_.erase( - std::remove_if( - stream_observers_.begin(), stream_observers_.end(), - [local_stream](const std::unique_ptr& observer) { - return observer->stream()->id().compare(local_stream->id()) == 0; - }), - stream_observers_.end()); - - if (IsClosed()) { - return; - } - UpdateNegotiationNeeded(); + sdp_handler_->RemoveStream(local_stream); } RTCErrorOr> PeerConnection::AddTrack( @@ -1471,126 +717,19 @@ RTCErrorOr> PeerConnection::AddTrack( LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE, "PeerConnection is closed."); } - if (FindSenderForTrack(track)) { + if (rtp_manager()->FindSenderForTrack(track)) { LOG_AND_RETURN_ERROR( RTCErrorType::INVALID_PARAMETER, "Sender already exists for track " + track->id() + "."); } - auto sender_or_error = - (IsUnifiedPlan() ? AddTrackUnifiedPlan(track, stream_ids) - : AddTrackPlanB(track, stream_ids)); + auto sender_or_error = rtp_manager()->AddTrack(track, stream_ids); if (sender_or_error.ok()) { - UpdateNegotiationNeeded(); + sdp_handler_->UpdateNegotiationNeeded(); stats_->AddTrack(track); } return sender_or_error; } -RTCErrorOr> -PeerConnection::AddTrackPlanB( - rtc::scoped_refptr track, - const std::vector& stream_ids) { - if (stream_ids.size() > 1u) { - LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION, - "AddTrack with more than one stream is not " - "supported with Plan B semantics."); - } - std::vector adjusted_stream_ids = stream_ids; - if (adjusted_stream_ids.empty()) { - adjusted_stream_ids.push_back(rtc::CreateRandomUuid()); - } - cricket::MediaType media_type = - (track->kind() == MediaStreamTrackInterface::kAudioKind - ? cricket::MEDIA_TYPE_AUDIO - : cricket::MEDIA_TYPE_VIDEO); - auto new_sender = - CreateSender(media_type, track->id(), track, adjusted_stream_ids, {}); - if (track->kind() == MediaStreamTrackInterface::kAudioKind) { - new_sender->internal()->SetMediaChannel(voice_media_channel()); - GetAudioTransceiver()->internal()->AddSender(new_sender); - const RtpSenderInfo* sender_info = - FindSenderInfo(local_audio_sender_infos_, - new_sender->internal()->stream_ids()[0], track->id()); - if (sender_info) { - new_sender->internal()->SetSsrc(sender_info->first_ssrc); - } - } else { - RTC_DCHECK_EQ(MediaStreamTrackInterface::kVideoKind, track->kind()); - new_sender->internal()->SetMediaChannel(video_media_channel()); - GetVideoTransceiver()->internal()->AddSender(new_sender); - const RtpSenderInfo* sender_info = - FindSenderInfo(local_video_sender_infos_, - new_sender->internal()->stream_ids()[0], track->id()); - if (sender_info) { - new_sender->internal()->SetSsrc(sender_info->first_ssrc); - } - } - return rtc::scoped_refptr(new_sender); -} - -RTCErrorOr> -PeerConnection::AddTrackUnifiedPlan( - rtc::scoped_refptr track, - const std::vector& stream_ids) { - auto transceiver = FindFirstTransceiverForAddedTrack(track); - if (transceiver) { - RTC_LOG(LS_INFO) << "Reusing an existing " - << cricket::MediaTypeToString(transceiver->media_type()) - << " transceiver for AddTrack."; - if (transceiver->stopping()) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - "The existing transceiver is stopping."); - } - - if (transceiver->direction() == RtpTransceiverDirection::kRecvOnly) { - transceiver->internal()->set_direction( - RtpTransceiverDirection::kSendRecv); - } else if (transceiver->direction() == RtpTransceiverDirection::kInactive) { - transceiver->internal()->set_direction( - RtpTransceiverDirection::kSendOnly); - } - transceiver->sender()->SetTrack(track); - transceiver->internal()->sender_internal()->set_stream_ids(stream_ids); - transceiver->internal()->set_reused_for_addtrack(true); - } else { - cricket::MediaType media_type = - (track->kind() == MediaStreamTrackInterface::kAudioKind - ? cricket::MEDIA_TYPE_AUDIO - : cricket::MEDIA_TYPE_VIDEO); - RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type) - << " transceiver in response to a call to AddTrack."; - std::string sender_id = track->id(); - // Avoid creating a sender with an existing ID by generating a random ID. - // This can happen if this is the second time AddTrack has created a sender - // for this track. - if (FindSenderById(sender_id)) { - sender_id = rtc::CreateRandomUuid(); - } - auto sender = CreateSender(media_type, sender_id, track, stream_ids, {}); - auto receiver = CreateReceiver(media_type, rtc::CreateRandomUuid()); - transceiver = CreateAndAddTransceiver(sender, receiver); - transceiver->internal()->set_created_by_addtrack(true); - transceiver->internal()->set_direction(RtpTransceiverDirection::kSendRecv); - } - return transceiver->sender(); -} - -rtc::scoped_refptr> -PeerConnection::FindFirstTransceiverForAddedTrack( - rtc::scoped_refptr track) { - RTC_DCHECK(track); - for (auto transceiver : transceivers_) { - if (!transceiver->sender()->track() && - cricket::MediaTypeToString(transceiver->media_type()) == - track->kind() && - !transceiver->internal()->has_ever_been_used_to_send() && - !transceiver->stopped()) { - return transceiver; - } - } - return nullptr; -} - bool PeerConnection::RemoveTrack(RtpSenderInterface* sender) { TRACE_EVENT0("webrtc", "PeerConnection::RemoveTrack"); return RemoveTrackNew(sender).ok(); @@ -1622,10 +761,12 @@ RTCError PeerConnection::RemoveTrackNew( } else { bool removed; if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) { - removed = GetAudioTransceiver()->internal()->RemoveSender(sender); + removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender( + sender); } else { RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type()); - removed = GetVideoTransceiver()->internal()->RemoveSender(sender); + removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender( + sender); } if (!removed) { LOG_AND_RETURN_ERROR( @@ -1633,19 +774,14 @@ RTCError PeerConnection::RemoveTrackNew( "Couldn't find sender " + sender->id() + " to remove."); } } - UpdateNegotiationNeeded(); + sdp_handler_->UpdateNegotiationNeeded(); return RTCError::OK(); } rtc::scoped_refptr> PeerConnection::FindTransceiverBySender( rtc::scoped_refptr sender) { - for (auto transceiver : transceivers_) { - if (transceiver->sender() == sender) { - return transceiver; - } - } - return nullptr; + return rtp_manager()->transceivers()->FindBySender(sender); } RTCErrorOr> @@ -1701,6 +837,7 @@ PeerConnection::AddTransceiver( rtc::scoped_refptr track, const RtpTransceiverInit& init, bool update_negotiation_needed) { + RTC_DCHECK_RUN_ON(signaling_thread()); RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO || media_type == cricket::MEDIA_TYPE_VIDEO)); if (track) { @@ -1780,100 +917,27 @@ PeerConnection::AddTransceiver( << " transceiver in response to a call to AddTransceiver."; // Set the sender ID equal to the track ID if the track is specified unless // that sender ID is already in use. - std::string sender_id = - (track && !FindSenderById(track->id()) ? track->id() - : rtc::CreateRandomUuid()); - auto sender = CreateSender(media_type, sender_id, track, init.stream_ids, - parameters.encodings); - auto receiver = CreateReceiver(media_type, rtc::CreateRandomUuid()); - auto transceiver = CreateAndAddTransceiver(sender, receiver); + std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id()) + ? track->id() + : rtc::CreateRandomUuid()); + auto sender = rtp_manager()->CreateSender( + media_type, sender_id, track, init.stream_ids, parameters.encodings); + auto receiver = + rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid()); + auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver); transceiver->internal()->set_direction(init.direction); if (update_negotiation_needed) { - UpdateNegotiationNeeded(); + sdp_handler_->UpdateNegotiationNeeded(); } return rtc::scoped_refptr(transceiver); } -rtc::scoped_refptr> -PeerConnection::CreateSender( - cricket::MediaType media_type, - const std::string& id, - rtc::scoped_refptr track, - const std::vector& stream_ids, - const std::vector& send_encodings) { - RTC_DCHECK_RUN_ON(signaling_thread()); - rtc::scoped_refptr> sender; - if (media_type == cricket::MEDIA_TYPE_AUDIO) { - RTC_DCHECK(!track || - (track->kind() == MediaStreamTrackInterface::kAudioKind)); - sender = RtpSenderProxyWithInternal::Create( - signaling_thread(), - AudioRtpSender::Create(worker_thread(), id, stats_.get(), this)); - NoteUsageEvent(UsageEvent::AUDIO_ADDED); - } else { - RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO); - RTC_DCHECK(!track || - (track->kind() == MediaStreamTrackInterface::kVideoKind)); - sender = RtpSenderProxyWithInternal::Create( - signaling_thread(), VideoRtpSender::Create(worker_thread(), id, this)); - NoteUsageEvent(UsageEvent::VIDEO_ADDED); - } - bool set_track_succeeded = sender->SetTrack(track); - RTC_DCHECK(set_track_succeeded); - sender->internal()->set_stream_ids(stream_ids); - sender->internal()->set_init_send_encodings(send_encodings); - return sender; -} - -rtc::scoped_refptr> -PeerConnection::CreateReceiver(cricket::MediaType media_type, - const std::string& receiver_id) { - rtc::scoped_refptr> - receiver; - if (media_type == cricket::MEDIA_TYPE_AUDIO) { - receiver = RtpReceiverProxyWithInternal::Create( - signaling_thread(), new AudioRtpReceiver(worker_thread(), receiver_id, - std::vector({}))); - NoteUsageEvent(UsageEvent::AUDIO_ADDED); - } else { - RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO); - receiver = RtpReceiverProxyWithInternal::Create( - signaling_thread(), new VideoRtpReceiver(worker_thread(), receiver_id, - std::vector({}))); - NoteUsageEvent(UsageEvent::VIDEO_ADDED); - } - return receiver; -} - -rtc::scoped_refptr> -PeerConnection::CreateAndAddTransceiver( - rtc::scoped_refptr> sender, - rtc::scoped_refptr> - receiver) { - // Ensure that the new sender does not have an ID that is already in use by - // another sender. - // Allow receiver IDs to conflict since those come from remote SDP (which - // could be invalid, but should not cause a crash). - RTC_DCHECK(!FindSenderById(sender->id())); - auto transceiver = RtpTransceiverProxyWithInternal::Create( - signaling_thread(), - new RtpTransceiver( - sender, receiver, channel_manager(), - sender->media_type() == cricket::MEDIA_TYPE_AUDIO - ? channel_manager()->GetSupportedAudioRtpHeaderExtensions() - : channel_manager()->GetSupportedVideoRtpHeaderExtensions())); - transceivers_.push_back(transceiver); - transceiver->internal()->SignalNegotiationNeeded.connect( - this, &PeerConnection::OnNegotiationNeeded); - return transceiver; -} - void PeerConnection::OnNegotiationNeeded() { RTC_DCHECK_RUN_ON(signaling_thread()); RTC_DCHECK(!IsClosed()); - UpdateNegotiationNeeded(); + sdp_handler_->UpdateNegotiationNeeded(); } rtc::scoped_refptr PeerConnection::CreateSender( @@ -1904,18 +968,18 @@ rtc::scoped_refptr PeerConnection::CreateSender( rtc::scoped_refptr> new_sender; if (kind == MediaStreamTrackInterface::kAudioKind) { auto audio_sender = AudioRtpSender::Create( - worker_thread(), rtc::CreateRandomUuid(), stats_.get(), this); - audio_sender->SetMediaChannel(voice_media_channel()); + worker_thread(), rtc::CreateRandomUuid(), stats_.get(), rtp_manager()); + audio_sender->SetMediaChannel(rtp_manager()->voice_media_channel()); new_sender = RtpSenderProxyWithInternal::Create( signaling_thread(), audio_sender); - GetAudioTransceiver()->internal()->AddSender(new_sender); + rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender); } else if (kind == MediaStreamTrackInterface::kVideoKind) { - auto video_sender = - VideoRtpSender::Create(worker_thread(), rtc::CreateRandomUuid(), this); - video_sender->SetMediaChannel(video_media_channel()); + auto video_sender = VideoRtpSender::Create( + worker_thread(), rtc::CreateRandomUuid(), rtp_manager()); + video_sender->SetMediaChannel(rtp_manager()->video_media_channel()); new_sender = RtpSenderProxyWithInternal::Create( signaling_thread(), video_sender); - GetVideoTransceiver()->internal()->AddSender(new_sender); + rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender); } else { RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind; return nullptr; @@ -1929,67 +993,30 @@ std::vector> PeerConnection::GetSenders() const { RTC_DCHECK_RUN_ON(signaling_thread()); std::vector> ret; - for (const auto& sender : GetSendersInternal()) { + for (const auto& sender : rtp_manager()->GetSendersInternal()) { ret.push_back(sender); } return ret; } -std::vector>> -PeerConnection::GetSendersInternal() const { - std::vector>> - all_senders; - for (const auto& transceiver : transceivers_) { - if (IsUnifiedPlan() && transceiver->internal()->stopped()) - continue; - - auto senders = transceiver->internal()->senders(); - all_senders.insert(all_senders.end(), senders.begin(), senders.end()); - } - return all_senders; -} - std::vector> PeerConnection::GetReceivers() const { RTC_DCHECK_RUN_ON(signaling_thread()); std::vector> ret; - for (const auto& receiver : GetReceiversInternal()) { + for (const auto& receiver : rtp_manager()->GetReceiversInternal()) { ret.push_back(receiver); } return ret; } -std::vector< - rtc::scoped_refptr>> -PeerConnection::GetReceiversInternal() const { - std::vector< - rtc::scoped_refptr>> - all_receivers; - for (const auto& transceiver : transceivers_) { - if (IsUnifiedPlan() && transceiver->internal()->stopped()) - continue; - - auto receivers = transceiver->internal()->receivers(); - all_receivers.insert(all_receivers.end(), receivers.begin(), - receivers.end()); - } - return all_receivers; -} - std::vector> PeerConnection::GetTransceivers() const { RTC_DCHECK_RUN_ON(signaling_thread()); RTC_CHECK(IsUnifiedPlan()) << "GetTransceivers is only supported with Unified Plan SdpSemantics."; std::vector> all_transceivers; - for (const auto& transceiver : transceivers_) { - // Temporary fix: Do not show stopped transceivers. - // The long term fix is to remove them from transceivers_, but this - // turns out to cause issues with audio channel lifetimes. - // TODO(https://crbug.com/webrtc/11840): Fix issue. - if (!transceiver->stopped()) { - all_transceivers.push_back(transceiver); - } + for (const auto& transceiver : rtp_manager()->transceivers()->List()) { + all_transceivers.push_back(transceiver); } return all_transceivers; } @@ -2012,8 +1039,7 @@ bool PeerConnection::GetStats(StatsObserver* observer, << track->id(); return false; } - signaling_thread()->Post(RTC_FROM_HERE, this, MSG_GETSTATS, - new GetStatsMsg(observer, track)); + message_handler_.PostGetStats(observer, stats_.get(), track); return true; } @@ -2034,7 +1060,8 @@ void PeerConnection::GetStats( RTC_DCHECK(stats_collector_); rtc::scoped_refptr internal_sender; if (selector) { - for (const auto& proxy_transceiver : transceivers_) { + for (const auto& proxy_transceiver : + rtp_manager()->transceivers()->List()) { for (const auto& proxy_sender : proxy_transceiver->internal()->senders()) { if (proxy_sender == selector) { @@ -2063,7 +1090,8 @@ void PeerConnection::GetStats( RTC_DCHECK(stats_collector_); rtc::scoped_refptr internal_receiver; if (selector) { - for (const auto& proxy_transceiver : transceivers_) { + for (const auto& proxy_transceiver : + rtp_manager()->transceivers()->List()) { for (const auto& proxy_receiver : proxy_transceiver->internal()->receivers()) { if (proxy_receiver == selector) { @@ -2085,7 +1113,7 @@ void PeerConnection::GetStats( PeerConnectionInterface::SignalingState PeerConnection::signaling_state() { RTC_DCHECK_RUN_ON(signaling_thread()); - return signaling_state_; + return sdp_handler_->signaling_state(); } PeerConnectionInterface::IceConnectionState @@ -2114,9 +1142,9 @@ PeerConnection::ice_gathering_state() { absl::optional PeerConnection::can_trickle_ice_candidates() { RTC_DCHECK_RUN_ON(signaling_thread()); - SessionDescriptionInterface* description = current_remote_description_.get(); + const SessionDescriptionInterface* description = current_remote_description(); if (!description) { - description = pending_remote_description_.get(); + description = pending_remote_description(); } if (!description) { return absl::nullopt; @@ -2151,7 +1179,7 @@ rtc::scoped_refptr PeerConnection::CreateDataChannel( // Trigger the onRenegotiationNeeded event for every new RTP DataChannel, or // the first SCTP DataChannel. if (data_channel_type() == cricket::DCT_RTP || first_datachannel) { - UpdateNegotiationNeeded(); + sdp_handler_->UpdateNegotiationNeeded(); } NoteUsageEvent(UsageEvent::DATA_ADDED); return channel; @@ -2159,1768 +1187,59 @@ rtc::scoped_refptr PeerConnection::CreateDataChannel( void PeerConnection::RestartIce() { RTC_DCHECK_RUN_ON(signaling_thread()); - local_ice_credentials_to_replace_->SetIceCredentialsFromLocalDescriptions( - current_local_description_.get(), pending_local_description_.get()); - UpdateNegotiationNeeded(); + sdp_handler_->RestartIce(); } void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer, const RTCOfferAnswerOptions& options) { RTC_DCHECK_RUN_ON(signaling_thread()); - // Chain this operation. If asynchronous operations are pending on the chain, - // this operation will be queued to be invoked, otherwise the contents of the - // lambda will execute immediately. - operations_chain_->ChainOperation( - [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), - observer_refptr = - rtc::scoped_refptr(observer), - options](std::function operations_chain_callback) { - // Abort early if |this_weak_ptr| is no longer valid. - if (!this_weak_ptr) { - observer_refptr->OnFailure( - RTCError(RTCErrorType::INTERNAL_ERROR, - "CreateOffer failed because the session was shut down")); - operations_chain_callback(); - return; - } - // The operation completes asynchronously when the wrapper is invoked. - rtc::scoped_refptr - observer_wrapper(new rtc::RefCountedObject< - CreateSessionDescriptionObserverOperationWrapper>( - std::move(observer_refptr), - std::move(operations_chain_callback))); - this_weak_ptr->DoCreateOffer(options, observer_wrapper); - }); -} - -void PeerConnection::DoCreateOffer( - const RTCOfferAnswerOptions& options, - rtc::scoped_refptr observer) { - RTC_DCHECK_RUN_ON(signaling_thread()); - TRACE_EVENT0("webrtc", "PeerConnection::DoCreateOffer"); - - if (!observer) { - RTC_LOG(LS_ERROR) << "CreateOffer - observer is NULL."; - return; - } - - if (IsClosed()) { - std::string error = "CreateOffer called when PeerConnection is closed."; - RTC_LOG(LS_ERROR) << error; - PostCreateSessionDescriptionFailure( - observer, RTCError(RTCErrorType::INVALID_STATE, std::move(error))); - return; - } - - // If a session error has occurred the PeerConnection is in a possibly - // inconsistent state so fail right away. - if (session_error() != SessionError::kNone) { - std::string error_message = GetSessionErrorMsg(); - RTC_LOG(LS_ERROR) << "CreateOffer: " << error_message; - PostCreateSessionDescriptionFailure( - observer, - RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); - return; - } - - if (!ValidateOfferAnswerOptions(options)) { - std::string error = "CreateOffer called with invalid options."; - RTC_LOG(LS_ERROR) << error; - PostCreateSessionDescriptionFailure( - observer, RTCError(RTCErrorType::INVALID_PARAMETER, std::move(error))); - return; - } - - // Legacy handling for offer_to_receive_audio and offer_to_receive_video. - // Specified in WebRTC section 4.4.3.2 "Legacy configuration extensions". - if (IsUnifiedPlan()) { - RTCError error = HandleLegacyOfferOptions(options); - if (!error.ok()) { - PostCreateSessionDescriptionFailure(observer, std::move(error)); - return; - } - } - - cricket::MediaSessionOptions session_options; - GetOptionsForOffer(options, &session_options); - webrtc_session_desc_factory_->CreateOffer(observer, options, session_options); -} - -RTCError PeerConnection::HandleLegacyOfferOptions( - const RTCOfferAnswerOptions& options) { - RTC_DCHECK(IsUnifiedPlan()); - - if (options.offer_to_receive_audio == 0) { - RemoveRecvDirectionFromReceivingTransceiversOfType( - cricket::MEDIA_TYPE_AUDIO); - } else if (options.offer_to_receive_audio == 1) { - AddUpToOneReceivingTransceiverOfType(cricket::MEDIA_TYPE_AUDIO); - } else if (options.offer_to_receive_audio > 1) { - LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_PARAMETER, - "offer_to_receive_audio > 1 is not supported."); - } - - if (options.offer_to_receive_video == 0) { - RemoveRecvDirectionFromReceivingTransceiversOfType( - cricket::MEDIA_TYPE_VIDEO); - } else if (options.offer_to_receive_video == 1) { - AddUpToOneReceivingTransceiverOfType(cricket::MEDIA_TYPE_VIDEO); - } else if (options.offer_to_receive_video > 1) { - LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_PARAMETER, - "offer_to_receive_video > 1 is not supported."); - } - - return RTCError::OK(); -} - -void PeerConnection::RemoveRecvDirectionFromReceivingTransceiversOfType( - cricket::MediaType media_type) { - for (const auto& transceiver : GetReceivingTransceiversOfType(media_type)) { - RtpTransceiverDirection new_direction = - RtpTransceiverDirectionWithRecvSet(transceiver->direction(), false); - if (new_direction != transceiver->direction()) { - RTC_LOG(LS_INFO) << "Changing " << cricket::MediaTypeToString(media_type) - << " transceiver (MID=" - << transceiver->mid().value_or("") << ") from " - << RtpTransceiverDirectionToString( - transceiver->direction()) - << " to " - << RtpTransceiverDirectionToString(new_direction) - << " since CreateOffer specified offer_to_receive=0"; - transceiver->internal()->set_direction(new_direction); - } - } -} - -void PeerConnection::AddUpToOneReceivingTransceiverOfType( - cricket::MediaType media_type) { - RTC_DCHECK_RUN_ON(signaling_thread()); - if (GetReceivingTransceiversOfType(media_type).empty()) { - RTC_LOG(LS_INFO) - << "Adding one recvonly " << cricket::MediaTypeToString(media_type) - << " transceiver since CreateOffer specified offer_to_receive=1"; - RtpTransceiverInit init; - init.direction = RtpTransceiverDirection::kRecvOnly; - AddTransceiver(media_type, nullptr, init, - /*update_negotiation_needed=*/false); - } -} - -std::vector>> -PeerConnection::GetReceivingTransceiversOfType(cricket::MediaType media_type) { - std::vector< - rtc::scoped_refptr>> - receiving_transceivers; - for (const auto& transceiver : transceivers_) { - if (!transceiver->stopped() && transceiver->media_type() == media_type && - RtpTransceiverDirectionHasRecv(transceiver->direction())) { - receiving_transceivers.push_back(transceiver); - } - } - return receiving_transceivers; + sdp_handler_->CreateOffer(observer, options); } void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer, const RTCOfferAnswerOptions& options) { RTC_DCHECK_RUN_ON(signaling_thread()); - // Chain this operation. If asynchronous operations are pending on the chain, - // this operation will be queued to be invoked, otherwise the contents of the - // lambda will execute immediately. - operations_chain_->ChainOperation( - [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), - observer_refptr = - rtc::scoped_refptr(observer), - options](std::function operations_chain_callback) { - // Abort early if |this_weak_ptr| is no longer valid. - if (!this_weak_ptr) { - observer_refptr->OnFailure(RTCError( - RTCErrorType::INTERNAL_ERROR, - "CreateAnswer failed because the session was shut down")); - operations_chain_callback(); - return; - } - // The operation completes asynchronously when the wrapper is invoked. - rtc::scoped_refptr - observer_wrapper(new rtc::RefCountedObject< - CreateSessionDescriptionObserverOperationWrapper>( - std::move(observer_refptr), - std::move(operations_chain_callback))); - this_weak_ptr->DoCreateAnswer(options, observer_wrapper); - }); -} - -void PeerConnection::DoCreateAnswer( - const RTCOfferAnswerOptions& options, - rtc::scoped_refptr observer) { - RTC_DCHECK_RUN_ON(signaling_thread()); - TRACE_EVENT0("webrtc", "PeerConnection::DoCreateAnswer"); - if (!observer) { - RTC_LOG(LS_ERROR) << "CreateAnswer - observer is NULL."; - return; - } - - // If a session error has occurred the PeerConnection is in a possibly - // inconsistent state so fail right away. - if (session_error() != SessionError::kNone) { - std::string error_message = GetSessionErrorMsg(); - RTC_LOG(LS_ERROR) << "CreateAnswer: " << error_message; - PostCreateSessionDescriptionFailure( - observer, - RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); - return; - } - - if (!(signaling_state_ == kHaveRemoteOffer || - signaling_state_ == kHaveLocalPrAnswer)) { - std::string error = - "PeerConnection cannot create an answer in a state other than " - "have-remote-offer or have-local-pranswer."; - RTC_LOG(LS_ERROR) << error; - PostCreateSessionDescriptionFailure( - observer, RTCError(RTCErrorType::INVALID_STATE, std::move(error))); - return; - } - - // The remote description should be set if we're in the right state. - RTC_DCHECK(remote_description()); - - if (IsUnifiedPlan()) { - if (options.offer_to_receive_audio != RTCOfferAnswerOptions::kUndefined) { - RTC_LOG(LS_WARNING) << "CreateAnswer: offer_to_receive_audio is not " - "supported with Unified Plan semantics. Use the " - "RtpTransceiver API instead."; - } - if (options.offer_to_receive_video != RTCOfferAnswerOptions::kUndefined) { - RTC_LOG(LS_WARNING) << "CreateAnswer: offer_to_receive_video is not " - "supported with Unified Plan semantics. Use the " - "RtpTransceiver API instead."; - } - } - - cricket::MediaSessionOptions session_options; - GetOptionsForAnswer(options, &session_options); - - webrtc_session_desc_factory_->CreateAnswer(observer, session_options); + sdp_handler_->CreateAnswer(observer, options); } void PeerConnection::SetLocalDescription( SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc_ptr) { RTC_DCHECK_RUN_ON(signaling_thread()); - // Chain this operation. If asynchronous operations are pending on the chain, - // this operation will be queued to be invoked, otherwise the contents of the - // lambda will execute immediately. - operations_chain_->ChainOperation( - [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), - observer_refptr = - rtc::scoped_refptr(observer), - desc = std::unique_ptr(desc_ptr)]( - std::function operations_chain_callback) mutable { - // Abort early if |this_weak_ptr| is no longer valid. - if (!this_weak_ptr) { - // For consistency with SetSessionDescriptionObserverAdapter whose - // posted messages doesn't get processed when the PC is destroyed, we - // do not inform |observer_refptr| that the operation failed. - operations_chain_callback(); - return; - } - // SetSessionDescriptionObserverAdapter takes care of making sure the - // |observer_refptr| is invoked in a posted message. - this_weak_ptr->DoSetLocalDescription( - std::move(desc), - rtc::scoped_refptr( - new rtc::RefCountedObject( - this_weak_ptr, observer_refptr))); - // For backwards-compatability reasons, we declare the operation as - // completed here (rather than in a post), so that the operation chain - // is not blocked by this operation when the observer is invoked. This - // allows the observer to trigger subsequent offer/answer operations - // synchronously if the operation chain is now empty. - operations_chain_callback(); - }); + sdp_handler_->SetLocalDescription(observer, desc_ptr); } void PeerConnection::SetLocalDescription( std::unique_ptr desc, rtc::scoped_refptr observer) { RTC_DCHECK_RUN_ON(signaling_thread()); - // Chain this operation. If asynchronous operations are pending on the chain, - // this operation will be queued to be invoked, otherwise the contents of the - // lambda will execute immediately. - operations_chain_->ChainOperation( - [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), observer, - desc = std::move(desc)]( - std::function operations_chain_callback) mutable { - // Abort early if |this_weak_ptr| is no longer valid. - if (!this_weak_ptr) { - observer->OnSetLocalDescriptionComplete(RTCError( - RTCErrorType::INTERNAL_ERROR, - "SetLocalDescription failed because the session was shut down")); - operations_chain_callback(); - return; - } - this_weak_ptr->DoSetLocalDescription(std::move(desc), observer); - // DoSetLocalDescription() is implemented as a synchronous operation. - // The |observer| will already have been informed that it completed, and - // we can mark this operation as complete without any loose ends. - operations_chain_callback(); - }); + sdp_handler_->SetLocalDescription(std::move(desc), observer); } void PeerConnection::SetLocalDescription( SetSessionDescriptionObserver* observer) { RTC_DCHECK_RUN_ON(signaling_thread()); - SetLocalDescription( - new rtc::RefCountedObject( - weak_ptr_factory_.GetWeakPtr(), observer)); + sdp_handler_->SetLocalDescription(observer); } void PeerConnection::SetLocalDescription( rtc::scoped_refptr observer) { RTC_DCHECK_RUN_ON(signaling_thread()); - // The |create_sdp_observer| handles performing DoSetLocalDescription() with - // the resulting description as well as completing the operation. - rtc::scoped_refptr - create_sdp_observer( - new rtc::RefCountedObject( - weak_ptr_factory_.GetWeakPtr(), observer)); - // Chain this operation. If asynchronous operations are pending on the chain, - // this operation will be queued to be invoked, otherwise the contents of the - // lambda will execute immediately. - operations_chain_->ChainOperation( - [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), - create_sdp_observer](std::function operations_chain_callback) { - // The |create_sdp_observer| is responsible for completing the - // operation. - create_sdp_observer->SetOperationCompleteCallback( - std::move(operations_chain_callback)); - // Abort early if |this_weak_ptr| is no longer valid. This triggers the - // same code path as if DoCreateOffer() or DoCreateAnswer() failed. - if (!this_weak_ptr) { - create_sdp_observer->OnFailure(RTCError( - RTCErrorType::INTERNAL_ERROR, - "SetLocalDescription failed because the session was shut down")); - return; - } - switch (this_weak_ptr->signaling_state()) { - case PeerConnectionInterface::kStable: - case PeerConnectionInterface::kHaveLocalOffer: - case PeerConnectionInterface::kHaveRemotePrAnswer: - // TODO(hbos): If [LastCreatedOffer] exists and still represents the - // current state of the system, use that instead of creating another - // offer. - this_weak_ptr->DoCreateOffer(RTCOfferAnswerOptions(), - create_sdp_observer); - break; - case PeerConnectionInterface::kHaveLocalPrAnswer: - case PeerConnectionInterface::kHaveRemoteOffer: - // TODO(hbos): If [LastCreatedAnswer] exists and still represents - // the current state of the system, use that instead of creating - // another answer. - this_weak_ptr->DoCreateAnswer(RTCOfferAnswerOptions(), - create_sdp_observer); - break; - case PeerConnectionInterface::kClosed: - create_sdp_observer->OnFailure(RTCError( - RTCErrorType::INVALID_STATE, - "SetLocalDescription called when PeerConnection is closed.")); - break; - } - }); -} - -void PeerConnection::DoSetLocalDescription( - std::unique_ptr desc, - rtc::scoped_refptr observer) { - RTC_DCHECK_RUN_ON(signaling_thread()); - TRACE_EVENT0("webrtc", "PeerConnection::DoSetLocalDescription"); - - if (!observer) { - RTC_LOG(LS_ERROR) << "SetLocalDescription - observer is NULL."; - return; - } - - if (!desc) { - observer->OnSetLocalDescriptionComplete( - RTCError(RTCErrorType::INTERNAL_ERROR, "SessionDescription is NULL.")); - return; - } - - // If a session error has occurred the PeerConnection is in a possibly - // inconsistent state so fail right away. - if (session_error() != SessionError::kNone) { - std::string error_message = GetSessionErrorMsg(); - RTC_LOG(LS_ERROR) << "SetLocalDescription: " << error_message; - observer->OnSetLocalDescriptionComplete( - RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); - return; - } - - // For SLD we support only explicit rollback. - if (desc->GetType() == SdpType::kRollback) { - if (IsUnifiedPlan()) { - observer->OnSetLocalDescriptionComplete(Rollback(desc->GetType())); - } else { - observer->OnSetLocalDescriptionComplete( - RTCError(RTCErrorType::UNSUPPORTED_OPERATION, - "Rollback not supported in Plan B")); - } - return; - } - - RTCError error = ValidateSessionDescription(desc.get(), cricket::CS_LOCAL); - if (!error.ok()) { - std::string error_message = GetSetDescriptionErrorMessage( - cricket::CS_LOCAL, desc->GetType(), error); - RTC_LOG(LS_ERROR) << error_message; - observer->OnSetLocalDescriptionComplete( - RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); - return; - } - - // Grab the description type before moving ownership to ApplyLocalDescription, - // which may destroy it before returning. - const SdpType type = desc->GetType(); - - error = ApplyLocalDescription(std::move(desc)); - // |desc| may be destroyed at this point. - - if (!error.ok()) { - // If ApplyLocalDescription fails, the PeerConnection could be in an - // inconsistent state, so act conservatively here and set the session error - // so that future calls to SetLocalDescription/SetRemoteDescription fail. - SetSessionError(SessionError::kContent, error.message()); - std::string error_message = - GetSetDescriptionErrorMessage(cricket::CS_LOCAL, type, error); - RTC_LOG(LS_ERROR) << error_message; - observer->OnSetLocalDescriptionComplete( - RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); - return; - } - RTC_DCHECK(local_description()); - - if (local_description()->GetType() == SdpType::kAnswer) { - // 3.2.10.1: For each transceiver in the connection's set of transceivers - // run the following steps: - if (IsUnifiedPlan()) { - for (auto it = transceivers_.begin(); it != transceivers_.end();) { - const auto& transceiver = *it; - // 3.2.10.1.1: If transceiver is stopped, associated with an m= section - // and the associated m= section is rejected in - // connection.[[CurrentLocalDescription]] or - // connection.[[CurrentRemoteDescription]], remove the - // transceiver from the connection's set of transceivers. - if (transceiver->stopped()) { - const ContentInfo* content = - FindMediaSectionForTransceiver(transceiver, local_description()); - - if (content && content->rejected) { - RTC_LOG(LS_INFO) << "Dissociating transceiver" - << " since the media section is being recycled."; - (*it)->internal()->set_mid(absl::nullopt); - (*it)->internal()->set_mline_index(absl::nullopt); - it = transceivers_.erase(it); - } else { - ++it; - } - } else { - ++it; - } - } - } - - // TODO(deadbeef): We already had to hop to the network thread for - // MaybeStartGathering... - network_thread()->Invoke( - RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::DiscardCandidatePool, - port_allocator_.get())); - // Make UMA notes about what was agreed to. - ReportNegotiatedSdpSemantics(*local_description()); - } - - if (IsUnifiedPlan()) { - bool was_negotiation_needed = is_negotiation_needed_; - UpdateNegotiationNeeded(); - if (signaling_state() == kStable && was_negotiation_needed && - is_negotiation_needed_) { - Observer()->OnRenegotiationNeeded(); - } - } - - observer->OnSetLocalDescriptionComplete(RTCError::OK()); - NoteUsageEvent(UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED); - - // MaybeStartGathering needs to be called after informing the observer so that - // we don't signal any candidates before signaling that SetLocalDescription - // completed. - transport_controller_->MaybeStartGathering(); -} - -RTCError PeerConnection::ApplyLocalDescription( - std::unique_ptr desc) { - RTC_DCHECK_RUN_ON(signaling_thread()); - RTC_DCHECK(desc); - - // Update stats here so that we have the most recent stats for tracks and - // streams that might be removed by updating the session description. - stats_->UpdateStats(kStatsOutputLevelStandard); - - // Take a reference to the old local description since it's used below to - // compare against the new local description. When setting the new local - // description, grab ownership of the replaced session description in case it - // is the same as |old_local_description|, to keep it alive for the duration - // of the method. - const SessionDescriptionInterface* old_local_description = - local_description(); - std::unique_ptr replaced_local_description; - SdpType type = desc->GetType(); - if (type == SdpType::kAnswer) { - replaced_local_description = pending_local_description_ - ? std::move(pending_local_description_) - : std::move(current_local_description_); - current_local_description_ = std::move(desc); - pending_local_description_ = nullptr; - current_remote_description_ = std::move(pending_remote_description_); - } else { - replaced_local_description = std::move(pending_local_description_); - pending_local_description_ = std::move(desc); - } - // The session description to apply now must be accessed by - // |local_description()|. - RTC_DCHECK(local_description()); - - // Report statistics about any use of simulcast. - ReportSimulcastApiVersion(kSimulcastVersionApplyLocalDescription, - *local_description()->description()); - - if (!is_caller_) { - if (remote_description()) { - // Remote description was applied first, so this PC is the callee. - is_caller_ = false; - } else { - // Local description is applied first, so this PC is the caller. - is_caller_ = true; - } - } - - RTCError error = PushdownTransportDescription(cricket::CS_LOCAL, type); - if (!error.ok()) { - return error; - } - - if (IsUnifiedPlan()) { - RTCError error = UpdateTransceiversAndDataChannels( - cricket::CS_LOCAL, *local_description(), old_local_description, - remote_description()); - if (!error.ok()) { - return error; - } - std::vector> remove_list; - std::vector> removed_streams; - for (const auto& transceiver : transceivers_) { - if (transceiver->stopped()) { - continue; - } - - // 2.2.7.1.1.(6-9): Set sender and receiver's transport slots. - // Note that code paths that don't set MID won't be able to use - // information about DTLS transports. - if (transceiver->mid()) { - auto dtls_transport = - LookupDtlsTransportByMidInternal(*transceiver->mid()); - transceiver->internal()->sender_internal()->set_transport( - dtls_transport); - transceiver->internal()->receiver_internal()->set_transport( - dtls_transport); - } - - const ContentInfo* content = - FindMediaSectionForTransceiver(transceiver, local_description()); - if (!content) { - continue; - } - const MediaContentDescription* media_desc = content->media_description(); - // 2.2.7.1.6: If description is of type "answer" or "pranswer", then run - // the following steps: - if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) { - // 2.2.7.1.6.1: If direction is "sendonly" or "inactive", and - // transceiver's [[FiredDirection]] slot is either "sendrecv" or - // "recvonly", process the removal of a remote track for the media - // description, given transceiver, removeList, and muteTracks. - if (!RtpTransceiverDirectionHasRecv(media_desc->direction()) && - (transceiver->internal()->fired_direction() && - RtpTransceiverDirectionHasRecv( - *transceiver->internal()->fired_direction()))) { - ProcessRemovalOfRemoteTrack(transceiver, &remove_list, - &removed_streams); - } - // 2.2.7.1.6.2: Set transceiver's [[CurrentDirection]] and - // [[FiredDirection]] slots to direction. - transceiver->internal()->set_current_direction(media_desc->direction()); - transceiver->internal()->set_fired_direction(media_desc->direction()); - } - } - auto observer = Observer(); - for (const auto& transceiver : remove_list) { - observer->OnRemoveTrack(transceiver->receiver()); - } - for (const auto& stream : removed_streams) { - observer->OnRemoveStream(stream); - } - } else { - // Media channels will be created only when offer is set. These may use new - // transports just created by PushdownTransportDescription. - if (type == SdpType::kOffer) { - // TODO(bugs.webrtc.org/4676) - Handle CreateChannel failure, as new local - // description is applied. Restore back to old description. - RTCError error = CreateChannels(*local_description()->description()); - if (!error.ok()) { - return error; - } - } - // Remove unused channels if MediaContentDescription is rejected. - RemoveUnusedChannels(local_description()->description()); - } - - error = UpdateSessionState(type, cricket::CS_LOCAL, - local_description()->description()); - if (!error.ok()) { - return error; - } - - if (remote_description()) { - // Now that we have a local description, we can push down remote candidates. - UseCandidatesInSessionDescription(remote_description()); - } - - pending_ice_restarts_.clear(); - if (session_error() != SessionError::kNone) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, GetSessionErrorMsg()); - } - - // If setting the description decided our SSL role, allocate any necessary - // SCTP sids. - rtc::SSLRole role; - if (IsSctpLike(data_channel_type()) && GetSctpSslRole(&role)) { - data_channel_controller_.AllocateSctpSids(role); - } - - if (IsUnifiedPlan()) { - for (const auto& transceiver : transceivers_) { - if (transceiver->stopped()) { - continue; - } - const ContentInfo* content = - FindMediaSectionForTransceiver(transceiver, local_description()); - if (!content) { - continue; - } - cricket::ChannelInterface* channel = transceiver->internal()->channel(); - if (content->rejected || !channel || channel->local_streams().empty()) { - // 0 is a special value meaning "this sender has no associated send - // stream". Need to call this so the sender won't attempt to configure - // a no longer existing stream and run into DCHECKs in the lower - // layers. - transceiver->internal()->sender_internal()->SetSsrc(0); - } else { - // Get the StreamParams from the channel which could generate SSRCs. - const std::vector& streams = channel->local_streams(); - transceiver->internal()->sender_internal()->set_stream_ids( - streams[0].stream_ids()); - transceiver->internal()->sender_internal()->SetSsrc( - streams[0].first_ssrc()); - } - } - } else { - // Plan B semantics. - - // Update state and SSRC of local MediaStreams and DataChannels based on the - // local session description. - const cricket::ContentInfo* audio_content = - GetFirstAudioContent(local_description()->description()); - if (audio_content) { - if (audio_content->rejected) { - RemoveSenders(cricket::MEDIA_TYPE_AUDIO); - } else { - const cricket::AudioContentDescription* audio_desc = - audio_content->media_description()->as_audio(); - UpdateLocalSenders(audio_desc->streams(), audio_desc->type()); - } - } - - const cricket::ContentInfo* video_content = - GetFirstVideoContent(local_description()->description()); - if (video_content) { - if (video_content->rejected) { - RemoveSenders(cricket::MEDIA_TYPE_VIDEO); - } else { - const cricket::VideoContentDescription* video_desc = - video_content->media_description()->as_video(); - UpdateLocalSenders(video_desc->streams(), video_desc->type()); - } - } - } - - const cricket::ContentInfo* data_content = - GetFirstDataContent(local_description()->description()); - if (data_content) { - const cricket::RtpDataContentDescription* rtp_data_desc = - data_content->media_description()->as_rtp_data(); - // rtp_data_desc will be null if this is an SCTP description. - if (rtp_data_desc) { - data_channel_controller_.UpdateLocalRtpDataChannels( - rtp_data_desc->streams()); - } - } - - if (type == SdpType::kAnswer && - local_ice_credentials_to_replace_->SatisfiesIceRestart( - *current_local_description_)) { - local_ice_credentials_to_replace_->ClearIceCredentials(); - } - - return RTCError::OK(); -} - -// The SDP parser used to populate these values by default for the 'content -// name' if an a=mid line was absent. -static absl::string_view GetDefaultMidForPlanB(cricket::MediaType media_type) { - switch (media_type) { - case cricket::MEDIA_TYPE_AUDIO: - return cricket::CN_AUDIO; - case cricket::MEDIA_TYPE_VIDEO: - return cricket::CN_VIDEO; - case cricket::MEDIA_TYPE_DATA: - return cricket::CN_DATA; - } - RTC_NOTREACHED(); - return ""; -} - -void PeerConnection::FillInMissingRemoteMids( - cricket::SessionDescription* new_remote_description) { - RTC_DCHECK(new_remote_description); - const cricket::ContentInfos no_infos; - const cricket::ContentInfos& local_contents = - (local_description() ? local_description()->description()->contents() - : no_infos); - const cricket::ContentInfos& remote_contents = - (remote_description() ? remote_description()->description()->contents() - : no_infos); - for (size_t i = 0; i < new_remote_description->contents().size(); ++i) { - cricket::ContentInfo& content = new_remote_description->contents()[i]; - if (!content.name.empty()) { - continue; - } - std::string new_mid; - absl::string_view source_explanation; - if (IsUnifiedPlan()) { - if (i < local_contents.size()) { - new_mid = local_contents[i].name; - source_explanation = "from the matching local media section"; - } else if (i < remote_contents.size()) { - new_mid = remote_contents[i].name; - source_explanation = "from the matching previous remote media section"; - } else { - new_mid = mid_generator_(); - source_explanation = "generated just now"; - } - } else { - new_mid = std::string( - GetDefaultMidForPlanB(content.media_description()->type())); - source_explanation = "to match pre-existing behavior"; - } - RTC_DCHECK(!new_mid.empty()); - content.name = new_mid; - new_remote_description->transport_infos()[i].content_name = new_mid; - RTC_LOG(LS_INFO) << "SetRemoteDescription: Remote media section at i=" << i - << " is missing an a=mid line. Filling in the value '" - << new_mid << "' " << source_explanation << "."; - } + sdp_handler_->SetLocalDescription(observer); } void PeerConnection::SetRemoteDescription( SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc_ptr) { RTC_DCHECK_RUN_ON(signaling_thread()); - // Chain this operation. If asynchronous operations are pending on the chain, - // this operation will be queued to be invoked, otherwise the contents of the - // lambda will execute immediately. - operations_chain_->ChainOperation( - [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), - observer_refptr = - rtc::scoped_refptr(observer), - desc = std::unique_ptr(desc_ptr)]( - std::function operations_chain_callback) mutable { - // Abort early if |this_weak_ptr| is no longer valid. - if (!this_weak_ptr) { - // For consistency with SetSessionDescriptionObserverAdapter whose - // posted messages doesn't get processed when the PC is destroyed, we - // do not inform |observer_refptr| that the operation failed. - operations_chain_callback(); - return; - } - // SetSessionDescriptionObserverAdapter takes care of making sure the - // |observer_refptr| is invoked in a posted message. - this_weak_ptr->DoSetRemoteDescription( - std::move(desc), - rtc::scoped_refptr( - new rtc::RefCountedObject( - this_weak_ptr, observer_refptr))); - // For backwards-compatability reasons, we declare the operation as - // completed here (rather than in a post), so that the operation chain - // is not blocked by this operation when the observer is invoked. This - // allows the observer to trigger subsequent offer/answer operations - // synchronously if the operation chain is now empty. - operations_chain_callback(); - }); + sdp_handler_->SetRemoteDescription(observer, desc_ptr); } void PeerConnection::SetRemoteDescription( std::unique_ptr desc, rtc::scoped_refptr observer) { RTC_DCHECK_RUN_ON(signaling_thread()); - // Chain this operation. If asynchronous operations are pending on the chain, - // this operation will be queued to be invoked, otherwise the contents of the - // lambda will execute immediately. - operations_chain_->ChainOperation( - [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), observer, - desc = std::move(desc)]( - std::function operations_chain_callback) mutable { - // Abort early if |this_weak_ptr| is no longer valid. - if (!this_weak_ptr) { - observer->OnSetRemoteDescriptionComplete(RTCError( - RTCErrorType::INTERNAL_ERROR, - "SetRemoteDescription failed because the session was shut down")); - operations_chain_callback(); - return; - } - this_weak_ptr->DoSetRemoteDescription(std::move(desc), - std::move(observer)); - // DoSetRemoteDescription() is implemented as a synchronous operation. - // The |observer| will already have been informed that it completed, and - // we can mark this operation as complete without any loose ends. - operations_chain_callback(); - }); -} - -void PeerConnection::DoSetRemoteDescription( - std::unique_ptr desc, - rtc::scoped_refptr observer) { - RTC_DCHECK_RUN_ON(signaling_thread()); - TRACE_EVENT0("webrtc", "PeerConnection::DoSetRemoteDescription"); - - if (!observer) { - RTC_LOG(LS_ERROR) << "SetRemoteDescription - observer is NULL."; - return; - } - - if (!desc) { - observer->OnSetRemoteDescriptionComplete(RTCError( - RTCErrorType::INVALID_PARAMETER, "SessionDescription is NULL.")); - return; - } - - // If a session error has occurred the PeerConnection is in a possibly - // inconsistent state so fail right away. - if (session_error() != SessionError::kNone) { - std::string error_message = GetSessionErrorMsg(); - RTC_LOG(LS_ERROR) << "SetRemoteDescription: " << error_message; - observer->OnSetRemoteDescriptionComplete( - RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); - return; - } - if (IsUnifiedPlan()) { - if (configuration_.enable_implicit_rollback) { - if (desc->GetType() == SdpType::kOffer && - signaling_state() == kHaveLocalOffer) { - Rollback(desc->GetType()); - } - } - // Explicit rollback. - if (desc->GetType() == SdpType::kRollback) { - observer->OnSetRemoteDescriptionComplete(Rollback(desc->GetType())); - return; - } - } else if (desc->GetType() == SdpType::kRollback) { - observer->OnSetRemoteDescriptionComplete( - RTCError(RTCErrorType::UNSUPPORTED_OPERATION, - "Rollback not supported in Plan B")); - return; - } - if (desc->GetType() == SdpType::kOffer) { - // Report to UMA the format of the received offer. - ReportSdpFormatReceived(*desc); - } - - // Handle remote descriptions missing a=mid lines for interop with legacy end - // points. - FillInMissingRemoteMids(desc->description()); - - RTCError error = ValidateSessionDescription(desc.get(), cricket::CS_REMOTE); - if (!error.ok()) { - std::string error_message = GetSetDescriptionErrorMessage( - cricket::CS_REMOTE, desc->GetType(), error); - RTC_LOG(LS_ERROR) << error_message; - observer->OnSetRemoteDescriptionComplete( - RTCError(error.type(), std::move(error_message))); - return; - } - - // Grab the description type before moving ownership to - // ApplyRemoteDescription, which may destroy it before returning. - const SdpType type = desc->GetType(); - - error = ApplyRemoteDescription(std::move(desc)); - // |desc| may be destroyed at this point. - - if (!error.ok()) { - // If ApplyRemoteDescription fails, the PeerConnection could be in an - // inconsistent state, so act conservatively here and set the session error - // so that future calls to SetLocalDescription/SetRemoteDescription fail. - SetSessionError(SessionError::kContent, error.message()); - std::string error_message = - GetSetDescriptionErrorMessage(cricket::CS_REMOTE, type, error); - RTC_LOG(LS_ERROR) << error_message; - observer->OnSetRemoteDescriptionComplete( - RTCError(error.type(), std::move(error_message))); - return; - } - RTC_DCHECK(remote_description()); - - if (type == SdpType::kAnswer) { - // TODO(deadbeef): We already had to hop to the network thread for - // MaybeStartGathering... - network_thread()->Invoke( - RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::DiscardCandidatePool, - port_allocator_.get())); - // Make UMA notes about what was agreed to. - ReportNegotiatedSdpSemantics(*remote_description()); - } - - if (IsUnifiedPlan()) { - bool was_negotiation_needed = is_negotiation_needed_; - UpdateNegotiationNeeded(); - if (signaling_state() == kStable && was_negotiation_needed && - is_negotiation_needed_) { - Observer()->OnRenegotiationNeeded(); - } - } - - observer->OnSetRemoteDescriptionComplete(RTCError::OK()); - NoteUsageEvent(UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED); -} - -RTCError PeerConnection::ApplyRemoteDescription( - std::unique_ptr desc) { - RTC_DCHECK_RUN_ON(signaling_thread()); - RTC_DCHECK(desc); - - // Update stats here so that we have the most recent stats for tracks and - // streams that might be removed by updating the session description. - stats_->UpdateStats(kStatsOutputLevelStandard); - - // Take a reference to the old remote description since it's used below to - // compare against the new remote description. When setting the new remote - // description, grab ownership of the replaced session description in case it - // is the same as |old_remote_description|, to keep it alive for the duration - // of the method. - const SessionDescriptionInterface* old_remote_description = - remote_description(); - std::unique_ptr replaced_remote_description; - SdpType type = desc->GetType(); - if (type == SdpType::kAnswer) { - replaced_remote_description = pending_remote_description_ - ? std::move(pending_remote_description_) - : std::move(current_remote_description_); - current_remote_description_ = std::move(desc); - pending_remote_description_ = nullptr; - current_local_description_ = std::move(pending_local_description_); - } else { - replaced_remote_description = std::move(pending_remote_description_); - pending_remote_description_ = std::move(desc); - } - // The session description to apply now must be accessed by - // |remote_description()|. - RTC_DCHECK(remote_description()); - - // Report statistics about any use of simulcast. - ReportSimulcastApiVersion(kSimulcastVersionApplyRemoteDescription, - *remote_description()->description()); - - RTCError error = PushdownTransportDescription(cricket::CS_REMOTE, type); - if (!error.ok()) { - return error; - } - // Transport and Media channels will be created only when offer is set. - if (IsUnifiedPlan()) { - RTCError error = UpdateTransceiversAndDataChannels( - cricket::CS_REMOTE, *remote_description(), local_description(), - old_remote_description); - if (!error.ok()) { - return error; - } - } else { - // Media channels will be created only when offer is set. These may use new - // transports just created by PushdownTransportDescription. - if (type == SdpType::kOffer) { - // TODO(mallinath) - Handle CreateChannel failure, as new local - // description is applied. Restore back to old description. - RTCError error = CreateChannels(*remote_description()->description()); - if (!error.ok()) { - return error; - } - } - // Remove unused channels if MediaContentDescription is rejected. - RemoveUnusedChannels(remote_description()->description()); - } - - // NOTE: Candidates allocation will be initiated only when - // SetLocalDescription is called. - error = UpdateSessionState(type, cricket::CS_REMOTE, - remote_description()->description()); - if (!error.ok()) { - return error; - } - - if (local_description() && - !UseCandidatesInSessionDescription(remote_description())) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, kInvalidCandidates); - } - - if (old_remote_description) { - for (const cricket::ContentInfo& content : - old_remote_description->description()->contents()) { - // Check if this new SessionDescription contains new ICE ufrag and - // password that indicates the remote peer requests an ICE restart. - // TODO(deadbeef): When we start storing both the current and pending - // remote description, this should reset pending_ice_restarts and compare - // against the current description. - if (CheckForRemoteIceRestart(old_remote_description, remote_description(), - content.name)) { - if (type == SdpType::kOffer) { - pending_ice_restarts_.insert(content.name); - } - } else { - // We retain all received candidates only if ICE is not restarted. - // When ICE is restarted, all previous candidates belong to an old - // generation and should not be kept. - // TODO(deadbeef): This goes against the W3C spec which says the remote - // description should only contain candidates from the last set remote - // description plus any candidates added since then. We should remove - // this once we're sure it won't break anything. - WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( - old_remote_description, content.name, mutable_remote_description()); - } - } - } - - if (session_error() != SessionError::kNone) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, GetSessionErrorMsg()); - } - - // Set the the ICE connection state to connecting since the connection may - // become writable with peer reflexive candidates before any remote candidate - // is signaled. - // TODO(pthatcher): This is a short-term solution for crbug/446908. A real fix - // is to have a new signal the indicates a change in checking state from the - // transport and expose a new checking() member from transport that can be - // read to determine the current checking state. The existing SignalConnecting - // actually means "gathering candidates", so cannot be be used here. - if (remote_description()->GetType() != SdpType::kOffer && - remote_description()->number_of_mediasections() > 0u && - ice_connection_state() == PeerConnectionInterface::kIceConnectionNew) { - SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); - } - - // If setting the description decided our SSL role, allocate any necessary - // SCTP sids. - rtc::SSLRole role; - if (IsSctpLike(data_channel_type()) && GetSctpSslRole(&role)) { - data_channel_controller_.AllocateSctpSids(role); - } - - if (IsUnifiedPlan()) { - std::vector> - now_receiving_transceivers; - std::vector> remove_list; - std::vector> added_streams; - std::vector> removed_streams; - for (const auto& transceiver : transceivers_) { - const ContentInfo* content = - FindMediaSectionForTransceiver(transceiver, remote_description()); - if (!content) { - continue; - } - const MediaContentDescription* media_desc = content->media_description(); - RtpTransceiverDirection local_direction = - RtpTransceiverDirectionReversed(media_desc->direction()); - // Roughly the same as steps 2.2.8.6 of section 4.4.1.6 "Set the - // RTCSessionDescription: Set the associated remote streams given - // transceiver.[[Receiver]], msids, addList, and removeList". - // https://w3c.github.io/webrtc-pc/#set-the-rtcsessiondescription - if (RtpTransceiverDirectionHasRecv(local_direction)) { - std::vector stream_ids; - if (!media_desc->streams().empty()) { - // The remote description has signaled the stream IDs. - stream_ids = media_desc->streams()[0].stream_ids(); - } - transceiver_stable_states_by_transceivers_[transceiver] - .SetRemoteStreamIdsIfUnset(transceiver->receiver()->stream_ids()); - - RTC_LOG(LS_INFO) << "Processing the MSIDs for MID=" << content->name - << " (" << GetStreamIdsString(stream_ids) << ")."; - SetAssociatedRemoteStreams(transceiver->internal()->receiver_internal(), - stream_ids, &added_streams, - &removed_streams); - // From the WebRTC specification, steps 2.2.8.5/6 of section 4.4.1.6 - // "Set the RTCSessionDescription: If direction is sendrecv or recvonly, - // and transceiver's current direction is neither sendrecv nor recvonly, - // process the addition of a remote track for the media description. - if (!transceiver->fired_direction() || - !RtpTransceiverDirectionHasRecv(*transceiver->fired_direction())) { - RTC_LOG(LS_INFO) - << "Processing the addition of a remote track for MID=" - << content->name << "."; - now_receiving_transceivers.push_back(transceiver); - } - } - // 2.2.8.1.9: If direction is "sendonly" or "inactive", and transceiver's - // [[FiredDirection]] slot is either "sendrecv" or "recvonly", process the - // removal of a remote track for the media description, given transceiver, - // removeList, and muteTracks. - if (!RtpTransceiverDirectionHasRecv(local_direction) && - (transceiver->fired_direction() && - RtpTransceiverDirectionHasRecv(*transceiver->fired_direction()))) { - ProcessRemovalOfRemoteTrack(transceiver, &remove_list, - &removed_streams); - } - // 2.2.8.1.10: Set transceiver's [[FiredDirection]] slot to direction. - transceiver->internal()->set_fired_direction(local_direction); - // 2.2.8.1.11: If description is of type "answer" or "pranswer", then run - // the following steps: - if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) { - // 2.2.8.1.11.1: Set transceiver's [[CurrentDirection]] slot to - // direction. - transceiver->internal()->set_current_direction(local_direction); - // 2.2.8.1.11.[3-6]: Set the transport internal slots. - if (transceiver->mid()) { - auto dtls_transport = - LookupDtlsTransportByMidInternal(*transceiver->mid()); - transceiver->internal()->sender_internal()->set_transport( - dtls_transport); - transceiver->internal()->receiver_internal()->set_transport( - dtls_transport); - } - } - // 2.2.8.1.12: If the media description is rejected, and transceiver is - // not already stopped, stop the RTCRtpTransceiver transceiver. - if (content->rejected && !transceiver->stopped()) { - RTC_LOG(LS_INFO) << "Stopping transceiver for MID=" << content->name - << " since the media section was rejected."; - transceiver->StopInternal(); - } - if (!content->rejected && - RtpTransceiverDirectionHasRecv(local_direction)) { - if (!media_desc->streams().empty() && - media_desc->streams()[0].has_ssrcs()) { - uint32_t ssrc = media_desc->streams()[0].first_ssrc(); - transceiver->internal()->receiver_internal()->SetupMediaChannel(ssrc); - } else { - transceiver->internal() - ->receiver_internal() - ->SetupUnsignaledMediaChannel(); - } - } - } - // Once all processing has finished, fire off callbacks. - auto observer = Observer(); - for (const auto& transceiver : now_receiving_transceivers) { - stats_->AddTrack(transceiver->receiver()->track()); - observer->OnTrack(transceiver); - observer->OnAddTrack(transceiver->receiver(), - transceiver->receiver()->streams()); - } - for (const auto& stream : added_streams) { - observer->OnAddStream(stream); - } - for (const auto& transceiver : remove_list) { - observer->OnRemoveTrack(transceiver->receiver()); - } - for (const auto& stream : removed_streams) { - observer->OnRemoveStream(stream); - } - } - - const cricket::ContentInfo* audio_content = - GetFirstAudioContent(remote_description()->description()); - const cricket::ContentInfo* video_content = - GetFirstVideoContent(remote_description()->description()); - const cricket::AudioContentDescription* audio_desc = - GetFirstAudioContentDescription(remote_description()->description()); - const cricket::VideoContentDescription* video_desc = - GetFirstVideoContentDescription(remote_description()->description()); - const cricket::RtpDataContentDescription* rtp_data_desc = - GetFirstRtpDataContentDescription(remote_description()->description()); - - // Check if the descriptions include streams, just in case the peer supports - // MSID, but doesn't indicate so with "a=msid-semantic". - if (remote_description()->description()->msid_supported() || - (audio_desc && !audio_desc->streams().empty()) || - (video_desc && !video_desc->streams().empty())) { - remote_peer_supports_msid_ = true; - } - - // We wait to signal new streams until we finish processing the description, - // since only at that point will new streams have all their tracks. - rtc::scoped_refptr new_streams(StreamCollection::Create()); - - if (!IsUnifiedPlan()) { - // TODO(steveanton): When removing RTP senders/receivers in response to a - // rejected media section, there is some cleanup logic that expects the - // voice/ video channel to still be set. But in this method the voice/video - // channel would have been destroyed by the SetRemoteDescription caller - // above so the cleanup that relies on them fails to run. The RemoveSenders - // calls should be moved to right before the DestroyChannel calls to fix - // this. - - // Find all audio rtp streams and create corresponding remote AudioTracks - // and MediaStreams. - if (audio_content) { - if (audio_content->rejected) { - RemoveSenders(cricket::MEDIA_TYPE_AUDIO); - } else { - bool default_audio_track_needed = - !remote_peer_supports_msid_ && - RtpTransceiverDirectionHasSend(audio_desc->direction()); - UpdateRemoteSendersList(GetActiveStreams(audio_desc), - default_audio_track_needed, audio_desc->type(), - new_streams); - } - } - - // Find all video rtp streams and create corresponding remote VideoTracks - // and MediaStreams. - if (video_content) { - if (video_content->rejected) { - RemoveSenders(cricket::MEDIA_TYPE_VIDEO); - } else { - bool default_video_track_needed = - !remote_peer_supports_msid_ && - RtpTransceiverDirectionHasSend(video_desc->direction()); - UpdateRemoteSendersList(GetActiveStreams(video_desc), - default_video_track_needed, video_desc->type(), - new_streams); - } - } - - // If this is an RTP data transport, update the DataChannels with the - // information from the remote peer. - if (rtp_data_desc) { - data_channel_controller_.UpdateRemoteRtpDataChannels( - GetActiveStreams(rtp_data_desc)); - } - - // Iterate new_streams and notify the observer about new MediaStreams. - auto observer = Observer(); - for (size_t i = 0; i < new_streams->count(); ++i) { - MediaStreamInterface* new_stream = new_streams->at(i); - stats_->AddStream(new_stream); - observer->OnAddStream( - rtc::scoped_refptr(new_stream)); - } - - UpdateEndedRemoteMediaStreams(); - } - - if (type == SdpType::kAnswer && - local_ice_credentials_to_replace_->SatisfiesIceRestart( - *current_local_description_)) { - local_ice_credentials_to_replace_->ClearIceCredentials(); - } - - return RTCError::OK(); -} - -void PeerConnection::SetAssociatedRemoteStreams( - rtc::scoped_refptr receiver, - const std::vector& stream_ids, - std::vector>* added_streams, - std::vector>* removed_streams) { - std::vector> media_streams; - for (const std::string& stream_id : stream_ids) { - rtc::scoped_refptr stream = - remote_streams_->find(stream_id); - if (!stream) { - stream = MediaStreamProxy::Create(rtc::Thread::Current(), - MediaStream::Create(stream_id)); - remote_streams_->AddStream(stream); - added_streams->push_back(stream); - } - media_streams.push_back(stream); - } - // Special case: "a=msid" missing, use random stream ID. - if (media_streams.empty() && - !(remote_description()->description()->msid_signaling() & - cricket::kMsidSignalingMediaSection)) { - if (!missing_msid_default_stream_) { - missing_msid_default_stream_ = MediaStreamProxy::Create( - rtc::Thread::Current(), MediaStream::Create(rtc::CreateRandomUuid())); - added_streams->push_back(missing_msid_default_stream_); - } - media_streams.push_back(missing_msid_default_stream_); - } - std::vector> previous_streams = - receiver->streams(); - // SetStreams() will add/remove the receiver's track to/from the streams. This - // differs from the spec - the spec uses an "addList" and "removeList" to - // update the stream-track relationships in a later step. We do this earlier, - // changing the order of things, but the end-result is the same. - // TODO(hbos): When we remove remote_streams(), use set_stream_ids() - // instead. https://crbug.com/webrtc/9480 - receiver->SetStreams(media_streams); - RemoveRemoteStreamsIfEmpty(previous_streams, removed_streams); -} - -void PeerConnection::ProcessRemovalOfRemoteTrack( - rtc::scoped_refptr> - transceiver, - std::vector>* remove_list, - std::vector>* removed_streams) { - RTC_DCHECK(transceiver->mid()); - RTC_LOG(LS_INFO) << "Processing the removal of a track for MID=" - << *transceiver->mid(); - std::vector> previous_streams = - transceiver->internal()->receiver_internal()->streams(); - // This will remove the remote track from the streams. - transceiver->internal()->receiver_internal()->set_stream_ids({}); - remove_list->push_back(transceiver); - RemoveRemoteStreamsIfEmpty(previous_streams, removed_streams); -} - -void PeerConnection::RemoveRemoteStreamsIfEmpty( - const std::vector>& remote_streams, - std::vector>* removed_streams) { - // TODO(https://crbug.com/webrtc/9480): When we use stream IDs instead of - // streams, see if the stream was removed by checking if this was the last - // receiver with that stream ID. - for (const auto& remote_stream : remote_streams) { - if (remote_stream->GetAudioTracks().empty() && - remote_stream->GetVideoTracks().empty()) { - remote_streams_->RemoveStream(remote_stream); - removed_streams->push_back(remote_stream); - } - } -} - -RTCError PeerConnection::UpdateTransceiversAndDataChannels( - cricket::ContentSource source, - const SessionDescriptionInterface& new_session, - const SessionDescriptionInterface* old_local_description, - const SessionDescriptionInterface* old_remote_description) { - RTC_DCHECK(IsUnifiedPlan()); - - const cricket::ContentGroup* bundle_group = nullptr; - if (new_session.GetType() == SdpType::kOffer) { - auto bundle_group_or_error = - GetEarlyBundleGroup(*new_session.description()); - if (!bundle_group_or_error.ok()) { - return bundle_group_or_error.MoveError(); - } - bundle_group = bundle_group_or_error.MoveValue(); - } - - const ContentInfos& new_contents = new_session.description()->contents(); - for (size_t i = 0; i < new_contents.size(); ++i) { - const cricket::ContentInfo& new_content = new_contents[i]; - cricket::MediaType media_type = new_content.media_description()->type(); - mid_generator_.AddKnownId(new_content.name); - if (media_type == cricket::MEDIA_TYPE_AUDIO || - media_type == cricket::MEDIA_TYPE_VIDEO) { - const cricket::ContentInfo* old_local_content = nullptr; - if (old_local_description && - i < old_local_description->description()->contents().size()) { - old_local_content = - &old_local_description->description()->contents()[i]; - } - const cricket::ContentInfo* old_remote_content = nullptr; - if (old_remote_description && - i < old_remote_description->description()->contents().size()) { - old_remote_content = - &old_remote_description->description()->contents()[i]; - } - auto transceiver_or_error = - AssociateTransceiver(source, new_session.GetType(), i, new_content, - old_local_content, old_remote_content); - if (!transceiver_or_error.ok()) { - return transceiver_or_error.MoveError(); - } - auto transceiver = transceiver_or_error.MoveValue(); - RTCError error = - UpdateTransceiverChannel(transceiver, new_content, bundle_group); - if (!error.ok()) { - return error; - } - } else if (media_type == cricket::MEDIA_TYPE_DATA) { - if (GetDataMid() && new_content.name != *GetDataMid()) { - // Ignore all but the first data section. - RTC_LOG(LS_INFO) << "Ignoring data media section with MID=" - << new_content.name; - continue; - } - RTCError error = UpdateDataChannel(source, new_content, bundle_group); - if (!error.ok()) { - return error; - } - } else { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Unknown section type."); - } - } - - return RTCError::OK(); -} - -RTCError PeerConnection::UpdateTransceiverChannel( - rtc::scoped_refptr> - transceiver, - const cricket::ContentInfo& content, - const cricket::ContentGroup* bundle_group) { - RTC_DCHECK(IsUnifiedPlan()); - RTC_DCHECK(transceiver); - cricket::ChannelInterface* channel = transceiver->internal()->channel(); - if (content.rejected) { - if (channel) { - transceiver->internal()->SetChannel(nullptr); - DestroyChannelInterface(channel); - } - } else { - if (!channel) { - if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { - channel = CreateVoiceChannel(content.name); - } else { - RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->media_type()); - channel = CreateVideoChannel(content.name); - } - if (!channel) { - LOG_AND_RETURN_ERROR( - RTCErrorType::INTERNAL_ERROR, - "Failed to create channel for mid=" + content.name); - } - transceiver->internal()->SetChannel(channel); - } - } - return RTCError::OK(); -} - -RTCError PeerConnection::UpdateDataChannel( - cricket::ContentSource source, - const cricket::ContentInfo& content, - const cricket::ContentGroup* bundle_group) { - if (data_channel_type() == cricket::DCT_NONE) { - // If data channels are disabled, ignore this media section. CreateAnswer - // will take care of rejecting it. - return RTCError::OK(); - } - if (content.rejected) { - RTC_LOG(LS_INFO) << "Rejected data channel, mid=" << content.mid(); - DestroyDataChannelTransport(); - } else { - if (!data_channel_controller_.rtp_data_channel() && - !data_channel_controller_.data_channel_transport()) { - RTC_LOG(LS_INFO) << "Creating data channel, mid=" << content.mid(); - if (!CreateDataChannel(content.name)) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create data channel."); - } - } - if (source == cricket::CS_REMOTE) { - const MediaContentDescription* data_desc = content.media_description(); - if (data_desc && cricket::IsRtpProtocol(data_desc->protocol())) { - data_channel_controller_.UpdateRemoteRtpDataChannels( - GetActiveStreams(data_desc)); - } - } - } - return RTCError::OK(); -} - -// This method will extract any send encodings that were sent by the remote -// connection. This is currently only relevant for Simulcast scenario (where -// the number of layers may be communicated by the server). -static std::vector GetSendEncodingsFromRemoteDescription( - const MediaContentDescription& desc) { - if (!desc.HasSimulcast()) { - return {}; - } - std::vector result; - const SimulcastDescription& simulcast = desc.simulcast_description(); - - // This is a remote description, the parameters we are after should appear - // as receive streams. - for (const auto& alternatives : simulcast.receive_layers()) { - RTC_DCHECK(!alternatives.empty()); - // There is currently no way to specify or choose from alternatives. - // We will always use the first alternative, which is the most preferred. - const SimulcastLayer& layer = alternatives[0]; - RtpEncodingParameters parameters; - parameters.rid = layer.rid; - parameters.active = !layer.is_paused; - result.push_back(parameters); - } - - return result; -} - -static RTCError UpdateSimulcastLayerStatusInSender( - const std::vector& layers, - rtc::scoped_refptr sender) { - RTC_DCHECK(sender); - RtpParameters parameters = sender->GetParametersInternal(); - std::vector disabled_layers; - - // The simulcast envelope cannot be changed, only the status of the streams. - // So we will iterate over the send encodings rather than the layers. - for (RtpEncodingParameters& encoding : parameters.encodings) { - auto iter = std::find_if(layers.begin(), layers.end(), - [&encoding](const SimulcastLayer& layer) { - return layer.rid == encoding.rid; - }); - // A layer that cannot be found may have been removed by the remote party. - if (iter == layers.end()) { - disabled_layers.push_back(encoding.rid); - continue; - } - - encoding.active = !iter->is_paused; - } - - RTCError result = sender->SetParametersInternal(parameters); - if (result.ok()) { - result = sender->DisableEncodingLayers(disabled_layers); - } - - return result; -} - -static bool SimulcastIsRejected( - const ContentInfo* local_content, - const MediaContentDescription& answer_media_desc) { - bool simulcast_offered = local_content && - local_content->media_description() && - local_content->media_description()->HasSimulcast(); - bool simulcast_answered = answer_media_desc.HasSimulcast(); - bool rids_supported = RtpExtension::FindHeaderExtensionByUri( - answer_media_desc.rtp_header_extensions(), RtpExtension::kRidUri); - return simulcast_offered && (!simulcast_answered || !rids_supported); -} - -static RTCError DisableSimulcastInSender( - rtc::scoped_refptr sender) { - RTC_DCHECK(sender); - RtpParameters parameters = sender->GetParametersInternal(); - if (parameters.encodings.size() <= 1) { - return RTCError::OK(); - } - - std::vector disabled_layers; - std::transform( - parameters.encodings.begin() + 1, parameters.encodings.end(), - std::back_inserter(disabled_layers), - [](const RtpEncodingParameters& encoding) { return encoding.rid; }); - return sender->DisableEncodingLayers(disabled_layers); -} - -RTCErrorOr>> -PeerConnection::AssociateTransceiver(cricket::ContentSource source, - SdpType type, - size_t mline_index, - const ContentInfo& content, - const ContentInfo* old_local_content, - const ContentInfo* old_remote_content) { - RTC_DCHECK(IsUnifiedPlan()); - // If this is an offer then the m= section might be recycled. If the m= - // section is being recycled (defined as: rejected in the current local or - // remote description and not rejected in new description), dissociate the - // currently associated RtpTransceiver by setting its mid property to null, - // and discard the mapping between the transceiver and its m= section index. - if (IsMediaSectionBeingRecycled(type, content, old_local_content, - old_remote_content)) { - // We want to dissociate the transceiver that has the rejected mid. - const std::string& old_mid = - (old_local_content && old_local_content->rejected) - ? old_local_content->name - : old_remote_content->name; - auto old_transceiver = GetAssociatedTransceiver(old_mid); - if (old_transceiver) { - RTC_LOG(LS_INFO) << "Dissociating transceiver for MID=" << old_mid - << " since the media section is being recycled."; - old_transceiver->internal()->set_mid(absl::nullopt); - old_transceiver->internal()->set_mline_index(absl::nullopt); - } - } - const MediaContentDescription* media_desc = content.media_description(); - auto transceiver = GetAssociatedTransceiver(content.name); - if (source == cricket::CS_LOCAL) { - // Find the RtpTransceiver that corresponds to this m= section, using the - // mapping between transceivers and m= section indices established when - // creating the offer. - if (!transceiver) { - transceiver = GetTransceiverByMLineIndex(mline_index); - } - if (!transceiver) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - "Unknown transceiver"); - } - } else { - RTC_DCHECK_EQ(source, cricket::CS_REMOTE); - // If the m= section is sendrecv or recvonly, and there are RtpTransceivers - // of the same type... - // When simulcast is requested, a transceiver cannot be associated because - // AddTrack cannot be called to initialize it. - if (!transceiver && - RtpTransceiverDirectionHasRecv(media_desc->direction()) && - !media_desc->HasSimulcast()) { - transceiver = FindAvailableTransceiverToReceive(media_desc->type()); - } - // If no RtpTransceiver was found in the previous step, create one with a - // recvonly direction. - if (!transceiver) { - RTC_LOG(LS_INFO) << "Adding " - << cricket::MediaTypeToString(media_desc->type()) - << " transceiver for MID=" << content.name - << " at i=" << mline_index - << " in response to the remote description."; - std::string sender_id = rtc::CreateRandomUuid(); - std::vector send_encodings = - GetSendEncodingsFromRemoteDescription(*media_desc); - auto sender = CreateSender(media_desc->type(), sender_id, nullptr, {}, - send_encodings); - std::string receiver_id; - if (!media_desc->streams().empty()) { - receiver_id = media_desc->streams()[0].id; - } else { - receiver_id = rtc::CreateRandomUuid(); - } - auto receiver = CreateReceiver(media_desc->type(), receiver_id); - transceiver = CreateAndAddTransceiver(sender, receiver); - transceiver->internal()->set_direction( - RtpTransceiverDirection::kRecvOnly); - if (type == SdpType::kOffer) { - transceiver_stable_states_by_transceivers_[transceiver] - .set_newly_created(); - } - } - // Check if the offer indicated simulcast but the answer rejected it. - // This can happen when simulcast is not supported on the remote party. - if (SimulcastIsRejected(old_local_content, *media_desc)) { - RTC_HISTOGRAM_BOOLEAN(kSimulcastDisabled, true); - RTCError error = - DisableSimulcastInSender(transceiver->internal()->sender_internal()); - if (!error.ok()) { - RTC_LOG(LS_ERROR) << "Failed to remove rejected simulcast."; - return std::move(error); - } - } - } - RTC_DCHECK(transceiver); - if (transceiver->media_type() != media_desc->type()) { - LOG_AND_RETURN_ERROR( - RTCErrorType::INVALID_PARAMETER, - "Transceiver type does not match media description type."); - } - if (media_desc->HasSimulcast()) { - std::vector layers = - source == cricket::CS_LOCAL - ? media_desc->simulcast_description().send_layers().GetAllLayers() - : media_desc->simulcast_description() - .receive_layers() - .GetAllLayers(); - RTCError error = UpdateSimulcastLayerStatusInSender( - layers, transceiver->internal()->sender_internal()); - if (!error.ok()) { - RTC_LOG(LS_ERROR) << "Failed updating status for simulcast layers."; - return std::move(error); - } - } - if (type == SdpType::kOffer) { - bool state_changes = transceiver->internal()->mid() != content.name || - transceiver->internal()->mline_index() != mline_index; - if (state_changes) { - transceiver_stable_states_by_transceivers_[transceiver] - .SetMSectionIfUnset(transceiver->internal()->mid(), - transceiver->internal()->mline_index()); - } - } - // Associate the found or created RtpTransceiver with the m= section by - // setting the value of the RtpTransceiver's mid property to the MID of the m= - // section, and establish a mapping between the transceiver and the index of - // the m= section. - transceiver->internal()->set_mid(content.name); - transceiver->internal()->set_mline_index(mline_index); - return std::move(transceiver); -} - -rtc::scoped_refptr> -PeerConnection::GetAssociatedTransceiver(const std::string& mid) const { - RTC_DCHECK(IsUnifiedPlan()); - for (auto transceiver : transceivers_) { - if (transceiver->mid() == mid) { - return transceiver; - } - } - return nullptr; -} - -rtc::scoped_refptr> -PeerConnection::GetTransceiverByMLineIndex(size_t mline_index) const { - RTC_DCHECK(IsUnifiedPlan()); - for (auto transceiver : transceivers_) { - if (transceiver->internal()->mline_index() == mline_index) { - return transceiver; - } - } - return nullptr; -} - -rtc::scoped_refptr> -PeerConnection::FindAvailableTransceiverToReceive( - cricket::MediaType media_type) const { - RTC_DCHECK(IsUnifiedPlan()); - // From JSEP section 5.10 (Applying a Remote Description): - // If the m= section is sendrecv or recvonly, and there are RtpTransceivers of - // the same type that were added to the PeerConnection by addTrack and are not - // associated with any m= section and are not stopped, find the first such - // RtpTransceiver. - for (auto transceiver : transceivers_) { - if (transceiver->media_type() == media_type && - transceiver->internal()->created_by_addtrack() && !transceiver->mid() && - !transceiver->stopped()) { - return transceiver; - } - } - return nullptr; -} - -const cricket::ContentInfo* PeerConnection::FindMediaSectionForTransceiver( - rtc::scoped_refptr> - transceiver, - const SessionDescriptionInterface* sdesc) const { - RTC_DCHECK(transceiver); - RTC_DCHECK(sdesc); - if (IsUnifiedPlan()) { - if (!transceiver->internal()->mid()) { - // This transceiver is not associated with a media section yet. - return nullptr; - } - return sdesc->description()->GetContentByName( - *transceiver->internal()->mid()); - } else { - // Plan B only allows at most one audio and one video section, so use the - // first media section of that type. - return cricket::GetFirstMediaContent(sdesc->description()->contents(), - transceiver->media_type()); - } + sdp_handler_->SetRemoteDescription(std::move(desc), observer); } PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() { @@ -4058,11 +1377,24 @@ RTCError PeerConnection::SetConfiguration( } if (modified_config.allow_codec_switching.has_value()) { - cricket::VideoMediaChannel* video_channel = video_media_channel(); - if (video_channel) { - video_channel->SetVideoCodecSwitchingEnabled( - *modified_config.allow_codec_switching); + std::vector channels; + for (const auto& transceiver : rtp_manager()->transceivers()->List()) { + if (transceiver->media_type() != cricket::MEDIA_TYPE_VIDEO) + continue; + + auto* video_channel = static_cast( + transceiver->internal()->channel()); + if (video_channel) + channels.push_back(video_channel->media_channel()); } + + worker_thread()->Invoke( + RTC_FROM_HERE, + [channels = std::move(channels), + allow_codec_switching = *modified_config.allow_codec_switching]() { + for (auto* ch : channels) + ch->SetVideoCodecSwitchingEnabled(allow_codec_switching); + }); } configuration_ = modified_config; @@ -4072,124 +1404,21 @@ RTCError PeerConnection::SetConfiguration( bool PeerConnection::AddIceCandidate( const IceCandidateInterface* ice_candidate) { RTC_DCHECK_RUN_ON(signaling_thread()); - TRACE_EVENT0("webrtc", "PeerConnection::AddIceCandidate"); - if (IsClosed()) { - RTC_LOG(LS_ERROR) << "AddIceCandidate: PeerConnection is closed."; - NoteAddIceCandidateResult(kAddIceCandidateFailClosed); - return false; - } - - if (!remote_description()) { - RTC_LOG(LS_ERROR) << "AddIceCandidate: ICE candidates can't be added " - "without any remote session description."; - NoteAddIceCandidateResult(kAddIceCandidateFailNoRemoteDescription); - return false; - } - - if (!ice_candidate) { - RTC_LOG(LS_ERROR) << "AddIceCandidate: Candidate is null."; - NoteAddIceCandidateResult(kAddIceCandidateFailNullCandidate); - return false; - } - - bool valid = false; - bool ready = ReadyToUseRemoteCandidate(ice_candidate, nullptr, &valid); - if (!valid) { - NoteAddIceCandidateResult(kAddIceCandidateFailNotValid); - return false; - } - - // Add this candidate to the remote session description. - if (!mutable_remote_description()->AddCandidate(ice_candidate)) { - RTC_LOG(LS_ERROR) << "AddIceCandidate: Candidate cannot be used."; - NoteAddIceCandidateResult(kAddIceCandidateFailInAddition); - return false; - } - - if (ready) { - bool result = UseCandidate(ice_candidate); - if (result) { - NoteUsageEvent(UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED); - NoteAddIceCandidateResult(kAddIceCandidateSuccess); - } else { - NoteAddIceCandidateResult(kAddIceCandidateFailNotUsable); - } - return result; - } else { - RTC_LOG(LS_INFO) << "AddIceCandidate: Not ready to use candidate."; - NoteAddIceCandidateResult(kAddIceCandidateFailNotReady); - return true; - } + return sdp_handler_->AddIceCandidate(ice_candidate); } void PeerConnection::AddIceCandidate( std::unique_ptr candidate, std::function callback) { RTC_DCHECK_RUN_ON(signaling_thread()); - // Chain this operation. If asynchronous operations are pending on the chain, - // this operation will be queued to be invoked, otherwise the contents of the - // lambda will execute immediately. - operations_chain_->ChainOperation( - [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), - candidate = std::move(candidate), callback = std::move(callback)]( - std::function operations_chain_callback) { - if (!this_weak_ptr) { - operations_chain_callback(); - callback(RTCError( - RTCErrorType::INVALID_STATE, - "AddIceCandidate failed because the session was shut down")); - return; - } - if (!this_weak_ptr->AddIceCandidate(candidate.get())) { - operations_chain_callback(); - // Fail with an error type and message consistent with Chromium. - // TODO(hbos): Fail with error types according to spec. - callback(RTCError(RTCErrorType::UNSUPPORTED_OPERATION, - "Error processing ICE candidate")); - return; - } - operations_chain_callback(); - callback(RTCError::OK()); - }); + sdp_handler_->AddIceCandidate(std::move(candidate), callback); } bool PeerConnection::RemoveIceCandidates( const std::vector& candidates) { TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates"); RTC_DCHECK_RUN_ON(signaling_thread()); - if (IsClosed()) { - RTC_LOG(LS_ERROR) << "RemoveIceCandidates: PeerConnection is closed."; - return false; - } - - if (!remote_description()) { - RTC_LOG(LS_ERROR) << "RemoveIceCandidates: ICE candidates can't be removed " - "without any remote session description."; - return false; - } - - if (candidates.empty()) { - RTC_LOG(LS_ERROR) << "RemoveIceCandidates: candidates are empty."; - return false; - } - - size_t number_removed = - mutable_remote_description()->RemoveCandidates(candidates); - if (number_removed != candidates.size()) { - RTC_LOG(LS_ERROR) - << "RemoveIceCandidates: Failed to remove candidates. Requested " - << candidates.size() << " but only " << number_removed - << " are removed."; - } - - // Remove the candidates from the transport controller. - RTCError error = transport_controller_->RemoveRemoteCandidates(candidates); - if (!error.ok()) { - RTC_LOG(LS_ERROR) - << "RemoveIceCandidates: Error when removing remote candidates: " - << error.message(); - } - return true; + return sdp_handler_->RemoveIceCandidates(candidates); } RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) { @@ -4242,7 +1471,7 @@ void PeerConnection::SetAudioPlayout(bool playout) { return; } auto audio_state = - factory_->channel_manager()->media_engine()->voice().GetAudioState(); + context_->channel_manager()->media_engine()->voice().GetAudioState(); audio_state->SetPlayout(playout); } @@ -4254,40 +1483,10 @@ void PeerConnection::SetAudioRecording(bool recording) { return; } auto audio_state = - factory_->channel_manager()->media_engine()->voice().GetAudioState(); + context_->channel_manager()->media_engine()->voice().GetAudioState(); audio_state->SetRecording(recording); } -std::unique_ptr -PeerConnection::GetRemoteAudioSSLCertificate() { - std::unique_ptr chain = GetRemoteAudioSSLCertChain(); - if (!chain || !chain->GetSize()) { - return nullptr; - } - return chain->Get(0).Clone(); -} - -std::unique_ptr -PeerConnection::GetRemoteAudioSSLCertChain() { - RTC_DCHECK_RUN_ON(signaling_thread()); - auto audio_transceiver = GetFirstAudioTransceiver(); - if (!audio_transceiver || !audio_transceiver->internal()->channel()) { - return nullptr; - } - return transport_controller_->GetRemoteSSLCertChain( - audio_transceiver->internal()->channel()->transport_name()); -} - -rtc::scoped_refptr> -PeerConnection::GetFirstAudioTransceiver() const { - for (auto transceiver : transceivers_) { - if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { - return transceiver; - } - } - return nullptr; -} - void PeerConnection::AddAdaptationResource( rtc::scoped_refptr resource) { if (!worker_thread()->IsCurrent()) { @@ -4315,7 +1514,8 @@ bool PeerConnection::StartRtcEventLog(std::unique_ptr output, bool PeerConnection::StartRtcEventLog( std::unique_ptr output) { int64_t output_period_ms = webrtc::RtcEventLog::kImmediateOutput; - if (field_trial::IsEnabled("WebRTC-RtcEventLogNewFormat")) { + if (absl::StartsWith(context_->trials().Lookup("WebRTC-RtcEventLogNewFormat"), + "Enabled")) { output_period_ms = 5000; } return StartRtcEventLog(std::move(output), output_period_ms); @@ -4349,51 +1549,61 @@ rtc::scoped_refptr PeerConnection::GetSctpTransport() const SessionDescriptionInterface* PeerConnection::local_description() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return pending_local_description_ ? pending_local_description_.get() - : current_local_description_.get(); + return sdp_handler_->local_description(); } const SessionDescriptionInterface* PeerConnection::remote_description() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return pending_remote_description_ ? pending_remote_description_.get() - : current_remote_description_.get(); + return sdp_handler_->remote_description(); } const SessionDescriptionInterface* PeerConnection::current_local_description() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return current_local_description_.get(); + return sdp_handler_->current_local_description(); } const SessionDescriptionInterface* PeerConnection::current_remote_description() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return current_remote_description_.get(); + return sdp_handler_->current_remote_description(); } const SessionDescriptionInterface* PeerConnection::pending_local_description() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return pending_local_description_.get(); + return sdp_handler_->pending_local_description(); } const SessionDescriptionInterface* PeerConnection::pending_remote_description() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return pending_remote_description_.get(); + return sdp_handler_->pending_remote_description(); } void PeerConnection::Close() { RTC_DCHECK_RUN_ON(signaling_thread()); TRACE_EVENT0("webrtc", "PeerConnection::Close"); + + if (IsClosed()) { + return; + } // Update stats here so that we have the most recent stats for tracks and // streams before the channels are closed. stats_->UpdateStats(kStatsOutputLevelStandard); - ChangeSignalingState(PeerConnectionInterface::kClosed); + ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed; + Observer()->OnIceConnectionChange(ice_connection_state_); + standardized_ice_connection_state_ = + PeerConnectionInterface::IceConnectionState::kIceConnectionClosed; + connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed; + Observer()->OnConnectionChange(connection_state_); + + sdp_handler_->Close(); + NoteUsageEvent(UsageEvent::CLOSE_CALLED); - for (const auto& transceiver : transceivers_) { + for (const auto& transceiver : rtp_manager()->transceivers()->List()) { transceiver->internal()->SetPeerConnectionClosed(); if (!transceiver->stopped()) transceiver->StopInternal(); @@ -4407,15 +1617,16 @@ void PeerConnection::Close() { // Don't destroy BaseChannels until after stats has been cleaned up so that // the last stats request can still read from the channels. - DestroyAllChannels(); + sdp_handler_->DestroyAllChannels(); // The event log is used in the transport controller, which must be outlived // by the former. CreateOffer by the peer connection is implemented // asynchronously and if the peer connection is closed without resetting the // WebRTC session description factory, the session description factory would // call the transport controller. - webrtc_session_desc_factory_.reset(); + sdp_handler_->ResetSessionDescFactory(); transport_controller_.reset(); + rtp_manager_->Close(); network_thread()->Invoke( RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::DiscardCandidatePool, @@ -4423,6 +1634,7 @@ void PeerConnection::Close() { worker_thread()->Invoke(RTC_FROM_HERE, [this] { RTC_DCHECK_RUN_ON(worker_thread()); + call_safety_.reset(); call_.reset(); // The event log must outlive call (and any other object that uses it). event_log_.reset(); @@ -4433,215 +1645,8 @@ void PeerConnection::Close() { observer_ = nullptr; } -void PeerConnection::OnMessage(rtc::Message* msg) { - RTC_DCHECK_RUN_ON(signaling_thread()); - switch (msg->message_id) { - case MSG_SET_SESSIONDESCRIPTION_SUCCESS: { - SetSessionDescriptionMsg* param = - static_cast(msg->pdata); - param->observer->OnSuccess(); - delete param; - break; - } - case MSG_SET_SESSIONDESCRIPTION_FAILED: { - SetSessionDescriptionMsg* param = - static_cast(msg->pdata); - param->observer->OnFailure(std::move(param->error)); - delete param; - break; - } - case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { - CreateSessionDescriptionMsg* param = - static_cast(msg->pdata); - param->observer->OnFailure(std::move(param->error)); - delete param; - break; - } - case MSG_GETSTATS: { - GetStatsMsg* param = static_cast(msg->pdata); - StatsReports reports; - stats_->GetStats(param->track, &reports); - param->observer->OnComplete(reports); - delete param; - break; - } - case MSG_REPORT_USAGE_PATTERN: { - ReportUsagePattern(); - break; - } - default: - RTC_NOTREACHED() << "Not implemented"; - break; - } -} - -cricket::VoiceMediaChannel* PeerConnection::voice_media_channel() const { - RTC_DCHECK(!IsUnifiedPlan()); - auto* voice_channel = static_cast( - GetAudioTransceiver()->internal()->channel()); - if (voice_channel) { - return voice_channel->media_channel(); - } else { - return nullptr; - } -} - -cricket::VideoMediaChannel* PeerConnection::video_media_channel() const { - RTC_DCHECK(!IsUnifiedPlan()); - auto* video_channel = static_cast( - GetVideoTransceiver()->internal()->channel()); - if (video_channel) { - return video_channel->media_channel(); - } else { - return nullptr; - } -} - -void PeerConnection::CreateAudioReceiver( - MediaStreamInterface* stream, - const RtpSenderInfo& remote_sender_info) { - std::vector> streams; - streams.push_back(rtc::scoped_refptr(stream)); - // TODO(https://crbug.com/webrtc/9480): When we remove remote_streams(), use - // the constructor taking stream IDs instead. - auto* audio_receiver = new AudioRtpReceiver( - worker_thread(), remote_sender_info.sender_id, streams); - audio_receiver->SetMediaChannel(voice_media_channel()); - if (remote_sender_info.sender_id == kDefaultAudioSenderId) { - audio_receiver->SetupUnsignaledMediaChannel(); - } else { - audio_receiver->SetupMediaChannel(remote_sender_info.first_ssrc); - } - auto receiver = RtpReceiverProxyWithInternal::Create( - signaling_thread(), audio_receiver); - GetAudioTransceiver()->internal()->AddReceiver(receiver); - Observer()->OnAddTrack(receiver, streams); - NoteUsageEvent(UsageEvent::AUDIO_ADDED); -} - -void PeerConnection::CreateVideoReceiver( - MediaStreamInterface* stream, - const RtpSenderInfo& remote_sender_info) { - std::vector> streams; - streams.push_back(rtc::scoped_refptr(stream)); - // TODO(https://crbug.com/webrtc/9480): When we remove remote_streams(), use - // the constructor taking stream IDs instead. - auto* video_receiver = new VideoRtpReceiver( - worker_thread(), remote_sender_info.sender_id, streams); - video_receiver->SetMediaChannel(video_media_channel()); - if (remote_sender_info.sender_id == kDefaultVideoSenderId) { - video_receiver->SetupUnsignaledMediaChannel(); - } else { - video_receiver->SetupMediaChannel(remote_sender_info.first_ssrc); - } - auto receiver = RtpReceiverProxyWithInternal::Create( - signaling_thread(), video_receiver); - GetVideoTransceiver()->internal()->AddReceiver(receiver); - Observer()->OnAddTrack(receiver, streams); - NoteUsageEvent(UsageEvent::VIDEO_ADDED); -} - -// TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote -// description. -rtc::scoped_refptr PeerConnection::RemoveAndStopReceiver( - const RtpSenderInfo& remote_sender_info) { - auto receiver = FindReceiverById(remote_sender_info.sender_id); - if (!receiver) { - RTC_LOG(LS_WARNING) << "RtpReceiver for track with id " - << remote_sender_info.sender_id << " doesn't exist."; - return nullptr; - } - if (receiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { - GetAudioTransceiver()->internal()->RemoveReceiver(receiver); - } else { - GetVideoTransceiver()->internal()->RemoveReceiver(receiver); - } - return receiver; -} - -void PeerConnection::AddAudioTrack(AudioTrackInterface* track, - MediaStreamInterface* stream) { - RTC_DCHECK(!IsClosed()); - RTC_DCHECK(track); - RTC_DCHECK(stream); - auto sender = FindSenderForTrack(track); - if (sender) { - // We already have a sender for this track, so just change the stream_id - // so that it's correct in the next call to CreateOffer. - sender->internal()->set_stream_ids({stream->id()}); - return; - } - - // Normal case; we've never seen this track before. - auto new_sender = CreateSender(cricket::MEDIA_TYPE_AUDIO, track->id(), track, - {stream->id()}, {}); - new_sender->internal()->SetMediaChannel(voice_media_channel()); - GetAudioTransceiver()->internal()->AddSender(new_sender); - // If the sender has already been configured in SDP, we call SetSsrc, - // which will connect the sender to the underlying transport. This can - // occur if a local session description that contains the ID of the sender - // is set before AddStream is called. It can also occur if the local - // session description is not changed and RemoveStream is called, and - // later AddStream is called again with the same stream. - const RtpSenderInfo* sender_info = - FindSenderInfo(local_audio_sender_infos_, stream->id(), track->id()); - if (sender_info) { - new_sender->internal()->SetSsrc(sender_info->first_ssrc); - } -} - -// TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around -// indefinitely, when we have unified plan SDP. -void PeerConnection::RemoveAudioTrack(AudioTrackInterface* track, - MediaStreamInterface* stream) { - RTC_DCHECK(!IsClosed()); - auto sender = FindSenderForTrack(track); - if (!sender) { - RTC_LOG(LS_WARNING) << "RtpSender for track with id " << track->id() - << " doesn't exist."; - return; - } - GetAudioTransceiver()->internal()->RemoveSender(sender); -} - -void PeerConnection::AddVideoTrack(VideoTrackInterface* track, - MediaStreamInterface* stream) { - RTC_DCHECK(!IsClosed()); - RTC_DCHECK(track); - RTC_DCHECK(stream); - auto sender = FindSenderForTrack(track); - if (sender) { - // We already have a sender for this track, so just change the stream_id - // so that it's correct in the next call to CreateOffer. - sender->internal()->set_stream_ids({stream->id()}); - return; - } - - // Normal case; we've never seen this track before. - auto new_sender = CreateSender(cricket::MEDIA_TYPE_VIDEO, track->id(), track, - {stream->id()}, {}); - new_sender->internal()->SetMediaChannel(video_media_channel()); - GetVideoTransceiver()->internal()->AddSender(new_sender); - const RtpSenderInfo* sender_info = - FindSenderInfo(local_video_sender_infos_, stream->id(), track->id()); - if (sender_info) { - new_sender->internal()->SetSsrc(sender_info->first_ssrc); - } -} - -void PeerConnection::RemoveVideoTrack(VideoTrackInterface* track, - MediaStreamInterface* stream) { - RTC_DCHECK(!IsClosed()); - auto sender = FindSenderForTrack(track); - if (!sender) { - RTC_LOG(LS_WARNING) << "RtpSender for track with id " << track->id() - << " doesn't exist."; - return; - } - GetVideoTransceiver()->internal()->RemoveSender(sender); -} - void PeerConnection::SetIceConnectionState(IceConnectionState new_state) { + RTC_DCHECK_RUN_ON(signaling_thread()); if (ice_connection_state_ == new_state) { return; } @@ -4743,623 +1748,8 @@ void PeerConnection::OnSelectedCandidatePairChanged( Observer()->OnIceSelectedCandidatePairChanged(event); } -void PeerConnection::ChangeSignalingState( - PeerConnectionInterface::SignalingState signaling_state) { - if (signaling_state_ == signaling_state) { - return; - } - RTC_LOG(LS_INFO) << "Session: " << session_id() << " Old state: " - << GetSignalingStateString(signaling_state_) - << " New state: " - << GetSignalingStateString(signaling_state); - signaling_state_ = signaling_state; - if (signaling_state == kClosed) { - ice_connection_state_ = kIceConnectionClosed; - Observer()->OnIceConnectionChange(ice_connection_state_); - standardized_ice_connection_state_ = - PeerConnectionInterface::IceConnectionState::kIceConnectionClosed; - connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed; - Observer()->OnConnectionChange(connection_state_); - } - Observer()->OnSignalingChange(signaling_state_); -} - -void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track, - MediaStreamInterface* stream) { - if (IsClosed()) { - return; - } - AddAudioTrack(track, stream); - UpdateNegotiationNeeded(); -} - -void PeerConnection::OnAudioTrackRemoved(AudioTrackInterface* track, - MediaStreamInterface* stream) { - if (IsClosed()) { - return; - } - RemoveAudioTrack(track, stream); - UpdateNegotiationNeeded(); -} - -void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track, - MediaStreamInterface* stream) { - if (IsClosed()) { - return; - } - AddVideoTrack(track, stream); - UpdateNegotiationNeeded(); -} - -void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track, - MediaStreamInterface* stream) { - if (IsClosed()) { - return; - } - RemoveVideoTrack(track, stream); - UpdateNegotiationNeeded(); -} - -void PeerConnection::PostSetSessionDescriptionSuccess( - SetSessionDescriptionObserver* observer) { - SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); - signaling_thread()->Post(RTC_FROM_HERE, this, - MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); -} - -void PeerConnection::PostSetSessionDescriptionFailure( - SetSessionDescriptionObserver* observer, - RTCError&& error) { - RTC_DCHECK(!error.ok()); - SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); - msg->error = std::move(error); - signaling_thread()->Post(RTC_FROM_HERE, this, - MSG_SET_SESSIONDESCRIPTION_FAILED, msg); -} - -void PeerConnection::PostCreateSessionDescriptionFailure( - CreateSessionDescriptionObserver* observer, - RTCError error) { - RTC_DCHECK(!error.ok()); - CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); - msg->error = std::move(error); - signaling_thread()->Post(RTC_FROM_HERE, this, - MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg); -} - -void PeerConnection::GetOptionsForOffer( - const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options) { - ExtractSharedMediaSessionOptions(offer_answer_options, session_options); - - if (IsUnifiedPlan()) { - GetOptionsForUnifiedPlanOffer(offer_answer_options, session_options); - } else { - GetOptionsForPlanBOffer(offer_answer_options, session_options); - } - - // Intentionally unset the data channel type for RTP data channel with the - // second condition. Otherwise the RTP data channels would be successfully - // negotiated by default and the unit tests in WebRtcDataBrowserTest will fail - // when building with chromium. We want to leave RTP data channels broken, so - // people won't try to use them. - if (data_channel_controller_.HasRtpDataChannels() || - data_channel_type() != cricket::DCT_RTP) { - session_options->data_channel_type = data_channel_type(); - } - - // Apply ICE restart flag and renomination flag. - bool ice_restart = offer_answer_options.ice_restart || - local_ice_credentials_to_replace_->HasIceCredentials(); - for (auto& options : session_options->media_description_options) { - options.transport_options.ice_restart = ice_restart; - options.transport_options.enable_ice_renomination = - configuration_.enable_ice_renomination; - } - - session_options->rtcp_cname = rtcp_cname_; - session_options->crypto_options = GetCryptoOptions(); - session_options->pooled_ice_credentials = - network_thread()->Invoke>( - RTC_FROM_HERE, - rtc::Bind(&cricket::PortAllocator::GetPooledIceCredentials, - port_allocator_.get())); - session_options->offer_extmap_allow_mixed = - configuration_.offer_extmap_allow_mixed; - - // Allow fallback for using obsolete SCTP syntax. - // Note that the default in |session_options| is true, while - // the default in |options| is false. - session_options->use_obsolete_sctp_sdp = - offer_answer_options.use_obsolete_sctp_sdp; -} - -void PeerConnection::GetOptionsForPlanBOffer( - const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options) { - // Figure out transceiver directional preferences. - bool send_audio = !GetAudioTransceiver()->internal()->senders().empty(); - bool send_video = !GetVideoTransceiver()->internal()->senders().empty(); - - // By default, generate sendrecv/recvonly m= sections. - bool recv_audio = true; - bool recv_video = true; - - // By default, only offer a new m= section if we have media to send with it. - bool offer_new_audio_description = send_audio; - bool offer_new_video_description = send_video; - bool offer_new_data_description = data_channel_controller_.HasDataChannels(); - - // The "offer_to_receive_X" options allow those defaults to be overridden. - if (offer_answer_options.offer_to_receive_audio != - RTCOfferAnswerOptions::kUndefined) { - recv_audio = (offer_answer_options.offer_to_receive_audio > 0); - offer_new_audio_description = - offer_new_audio_description || - (offer_answer_options.offer_to_receive_audio > 0); - } - if (offer_answer_options.offer_to_receive_video != - RTCOfferAnswerOptions::kUndefined) { - recv_video = (offer_answer_options.offer_to_receive_video > 0); - offer_new_video_description = - offer_new_video_description || - (offer_answer_options.offer_to_receive_video > 0); - } - - absl::optional audio_index; - absl::optional video_index; - absl::optional data_index; - // If a current description exists, generate m= sections in the same order, - // using the first audio/video/data section that appears and rejecting - // extraneous ones. - if (local_description()) { - GenerateMediaDescriptionOptions( - local_description(), - RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), - RtpTransceiverDirectionFromSendRecv(send_video, recv_video), - &audio_index, &video_index, &data_index, session_options); - } - - // Add audio/video/data m= sections to the end if needed. - if (!audio_index && offer_new_audio_description) { - cricket::MediaDescriptionOptions options( - cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO, - RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), false); - options.header_extensions = - channel_manager()->GetSupportedAudioRtpHeaderExtensions(); - session_options->media_description_options.push_back(options); - audio_index = session_options->media_description_options.size() - 1; - } - if (!video_index && offer_new_video_description) { - cricket::MediaDescriptionOptions options( - cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO, - RtpTransceiverDirectionFromSendRecv(send_video, recv_video), false); - options.header_extensions = - channel_manager()->GetSupportedVideoRtpHeaderExtensions(); - session_options->media_description_options.push_back(options); - video_index = session_options->media_description_options.size() - 1; - } - if (!data_index && offer_new_data_description) { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForActiveData(cricket::CN_DATA)); - data_index = session_options->media_description_options.size() - 1; - } - - cricket::MediaDescriptionOptions* audio_media_description_options = - !audio_index ? nullptr - : &session_options->media_description_options[*audio_index]; - cricket::MediaDescriptionOptions* video_media_description_options = - !video_index ? nullptr - : &session_options->media_description_options[*video_index]; - - AddPlanBRtpSenderOptions(GetSendersInternal(), - audio_media_description_options, - video_media_description_options, - offer_answer_options.num_simulcast_layers); -} - -static cricket::MediaDescriptionOptions -GetMediaDescriptionOptionsForTransceiver( - rtc::scoped_refptr> - transceiver, - const std::string& mid, - bool is_create_offer) { - // NOTE: a stopping transceiver should be treated as a stopped one in - // createOffer as specified in - // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer. - bool stopped = - is_create_offer ? transceiver->stopping() : transceiver->stopped(); - cricket::MediaDescriptionOptions media_description_options( - transceiver->media_type(), mid, transceiver->direction(), stopped); - media_description_options.codec_preferences = - transceiver->codec_preferences(); - media_description_options.header_extensions = - transceiver->HeaderExtensionsToOffer(); - // This behavior is specified in JSEP. The gist is that: - // 1. The MSID is included if the RtpTransceiver's direction is sendonly or - // sendrecv. - // 2. If the MSID is included, then it must be included in any subsequent - // offer/answer exactly the same until the RtpTransceiver is stopped. - if (stopped || (!RtpTransceiverDirectionHasSend(transceiver->direction()) && - !transceiver->internal()->has_ever_been_used_to_send())) { - return media_description_options; - } - - cricket::SenderOptions sender_options; - sender_options.track_id = transceiver->sender()->id(); - sender_options.stream_ids = transceiver->sender()->stream_ids(); - - // The following sets up RIDs and Simulcast. - // RIDs are included if Simulcast is requested or if any RID was specified. - RtpParameters send_parameters = - transceiver->internal()->sender_internal()->GetParametersInternal(); - bool has_rids = std::any_of(send_parameters.encodings.begin(), - send_parameters.encodings.end(), - [](const RtpEncodingParameters& encoding) { - return !encoding.rid.empty(); - }); - - std::vector send_rids; - SimulcastLayerList send_layers; - for (const RtpEncodingParameters& encoding : send_parameters.encodings) { - if (encoding.rid.empty()) { - continue; - } - send_rids.push_back(RidDescription(encoding.rid, RidDirection::kSend)); - send_layers.AddLayer(SimulcastLayer(encoding.rid, !encoding.active)); - } - - if (has_rids) { - sender_options.rids = send_rids; - } - - sender_options.simulcast_layers = send_layers; - // When RIDs are configured, we must set num_sim_layers to 0 to. - // Otherwise, num_sim_layers must be 1 because either there is no - // simulcast, or simulcast is acheived by munging the SDP. - sender_options.num_sim_layers = has_rids ? 0 : 1; - media_description_options.sender_options.push_back(sender_options); - - return media_description_options; -} - -// Returns the ContentInfo at mline index |i|, or null if none exists. -static const ContentInfo* GetContentByIndex( - const SessionDescriptionInterface* sdesc, - size_t i) { - if (!sdesc) { - return nullptr; - } - const ContentInfos& contents = sdesc->description()->contents(); - return (i < contents.size() ? &contents[i] : nullptr); -} - -void PeerConnection::GetOptionsForUnifiedPlanOffer( - const RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options) { - // Rules for generating an offer are dictated by JSEP sections 5.2.1 (Initial - // Offers) and 5.2.2 (Subsequent Offers). - RTC_DCHECK_EQ(session_options->media_description_options.size(), 0); - const ContentInfos no_infos; - const ContentInfos& local_contents = - (local_description() ? local_description()->description()->contents() - : no_infos); - const ContentInfos& remote_contents = - (remote_description() ? remote_description()->description()->contents() - : no_infos); - // The mline indices that can be recycled. New transceivers should reuse these - // slots first. - std::queue recycleable_mline_indices; - // First, go through each media section that exists in either the local or - // remote description and generate a media section in this offer for the - // associated transceiver. If a media section can be recycled, generate a - // default, rejected media section here that can be later overwritten. - for (size_t i = 0; - i < std::max(local_contents.size(), remote_contents.size()); ++i) { - // Either |local_content| or |remote_content| is non-null. - const ContentInfo* local_content = - (i < local_contents.size() ? &local_contents[i] : nullptr); - const ContentInfo* current_local_content = - GetContentByIndex(current_local_description(), i); - const ContentInfo* remote_content = - (i < remote_contents.size() ? &remote_contents[i] : nullptr); - const ContentInfo* current_remote_content = - GetContentByIndex(current_remote_description(), i); - bool had_been_rejected = - (current_local_content && current_local_content->rejected) || - (current_remote_content && current_remote_content->rejected); - const std::string& mid = - (local_content ? local_content->name : remote_content->name); - cricket::MediaType media_type = - (local_content ? local_content->media_description()->type() - : remote_content->media_description()->type()); - if (media_type == cricket::MEDIA_TYPE_AUDIO || - media_type == cricket::MEDIA_TYPE_VIDEO) { - // A media section is considered eligible for recycling if it is marked as - // rejected in either the current local or current remote description. - auto transceiver = GetAssociatedTransceiver(mid); - if (!transceiver) { - // No associated transceiver. The media section has been stopped. - recycleable_mline_indices.push(i); - session_options->media_description_options.push_back( - cricket::MediaDescriptionOptions(media_type, mid, - RtpTransceiverDirection::kInactive, - /*stopped=*/true)); - } else { - // NOTE: a stopping transceiver should be treated as a stopped one in - // createOffer as specified in - // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer. - if (had_been_rejected && transceiver->stopping()) { - session_options->media_description_options.push_back( - cricket::MediaDescriptionOptions( - transceiver->media_type(), mid, - RtpTransceiverDirection::kInactive, - /*stopped=*/true)); - recycleable_mline_indices.push(i); - } else { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForTransceiver( - transceiver, mid, - /*is_create_offer=*/true)); - // CreateOffer shouldn't really cause any state changes in - // PeerConnection, but we need a way to match new transceivers to new - // media sections in SetLocalDescription and JSEP specifies this is - // done by recording the index of the media section generated for the - // transceiver in the offer. - transceiver->internal()->set_mline_index(i); - } - } - } else { - RTC_CHECK_EQ(cricket::MEDIA_TYPE_DATA, media_type); - if (had_been_rejected) { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForRejectedData(mid)); - } else { - RTC_CHECK(GetDataMid()); - if (mid == *GetDataMid()) { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForActiveData(mid)); - } else { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForRejectedData(mid)); - } - } - } - } - - // Next, look for transceivers that are newly added (that is, are not stopped - // and not associated). Reuse media sections marked as recyclable first, - // otherwise append to the end of the offer. New media sections should be - // added in the order they were added to the PeerConnection. - for (const auto& transceiver : transceivers_) { - if (transceiver->mid() || transceiver->stopping()) { - continue; - } - size_t mline_index; - if (!recycleable_mline_indices.empty()) { - mline_index = recycleable_mline_indices.front(); - recycleable_mline_indices.pop(); - session_options->media_description_options[mline_index] = - GetMediaDescriptionOptionsForTransceiver( - transceiver, mid_generator_(), /*is_create_offer=*/true); - } else { - mline_index = session_options->media_description_options.size(); - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForTransceiver( - transceiver, mid_generator_(), /*is_create_offer=*/true)); - } - // See comment above for why CreateOffer changes the transceiver's state. - transceiver->internal()->set_mline_index(mline_index); - } - // Lastly, add a m-section if we have local data channels and an m section - // does not already exist. - if (!GetDataMid() && data_channel_controller_.HasDataChannels()) { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForActiveData(mid_generator_())); - } -} - -void PeerConnection::GetOptionsForAnswer( - const RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options) { - ExtractSharedMediaSessionOptions(offer_answer_options, session_options); - - if (IsUnifiedPlan()) { - GetOptionsForUnifiedPlanAnswer(offer_answer_options, session_options); - } else { - GetOptionsForPlanBAnswer(offer_answer_options, session_options); - } - - // Intentionally unset the data channel type for RTP data channel. Otherwise - // the RTP data channels would be successfully negotiated by default and the - // unit tests in WebRtcDataBrowserTest will fail when building with chromium. - // We want to leave RTP data channels broken, so people won't try to use them. - if (data_channel_controller_.HasRtpDataChannels() || - data_channel_type() != cricket::DCT_RTP) { - session_options->data_channel_type = data_channel_type(); - } - - // Apply ICE renomination flag. - for (auto& options : session_options->media_description_options) { - options.transport_options.enable_ice_renomination = - configuration_.enable_ice_renomination; - } - - session_options->rtcp_cname = rtcp_cname_; - session_options->crypto_options = GetCryptoOptions(); - session_options->pooled_ice_credentials = - network_thread()->Invoke>( - RTC_FROM_HERE, - rtc::Bind(&cricket::PortAllocator::GetPooledIceCredentials, - port_allocator_.get())); -} - -void PeerConnection::GetOptionsForPlanBAnswer( - const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options) { - // Figure out transceiver directional preferences. - bool send_audio = !GetAudioTransceiver()->internal()->senders().empty(); - bool send_video = !GetVideoTransceiver()->internal()->senders().empty(); - - // By default, generate sendrecv/recvonly m= sections. The direction is also - // restricted by the direction in the offer. - bool recv_audio = true; - bool recv_video = true; - - // The "offer_to_receive_X" options allow those defaults to be overridden. - if (offer_answer_options.offer_to_receive_audio != - RTCOfferAnswerOptions::kUndefined) { - recv_audio = (offer_answer_options.offer_to_receive_audio > 0); - } - if (offer_answer_options.offer_to_receive_video != - RTCOfferAnswerOptions::kUndefined) { - recv_video = (offer_answer_options.offer_to_receive_video > 0); - } - - absl::optional audio_index; - absl::optional video_index; - absl::optional data_index; - - // Generate m= sections that match those in the offer. - // Note that mediasession.cc will handle intersection our preferred - // direction with the offered direction. - GenerateMediaDescriptionOptions( - remote_description(), - RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), - RtpTransceiverDirectionFromSendRecv(send_video, recv_video), &audio_index, - &video_index, &data_index, session_options); - - cricket::MediaDescriptionOptions* audio_media_description_options = - !audio_index ? nullptr - : &session_options->media_description_options[*audio_index]; - cricket::MediaDescriptionOptions* video_media_description_options = - !video_index ? nullptr - : &session_options->media_description_options[*video_index]; - - AddPlanBRtpSenderOptions(GetSendersInternal(), - audio_media_description_options, - video_media_description_options, - offer_answer_options.num_simulcast_layers); -} - -void PeerConnection::GetOptionsForUnifiedPlanAnswer( - const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options) { - // Rules for generating an answer are dictated by JSEP sections 5.3.1 (Initial - // Answers) and 5.3.2 (Subsequent Answers). - RTC_DCHECK(remote_description()); - RTC_DCHECK(remote_description()->GetType() == SdpType::kOffer); - for (const ContentInfo& content : - remote_description()->description()->contents()) { - cricket::MediaType media_type = content.media_description()->type(); - if (media_type == cricket::MEDIA_TYPE_AUDIO || - media_type == cricket::MEDIA_TYPE_VIDEO) { - auto transceiver = GetAssociatedTransceiver(content.name); - RTC_CHECK(transceiver); - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForTransceiver(transceiver, content.name, - /*is_create_offer=*/false)); - } else { - RTC_CHECK_EQ(cricket::MEDIA_TYPE_DATA, media_type); - // Reject all data sections if data channels are disabled. - // Reject a data section if it has already been rejected. - // Reject all data sections except for the first one. - if (data_channel_type() == cricket::DCT_NONE || content.rejected || - content.name != *GetDataMid()) { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForRejectedData(content.name)); - } else { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForActiveData(content.name)); - } - } - } -} - -void PeerConnection::GenerateMediaDescriptionOptions( - const SessionDescriptionInterface* session_desc, - RtpTransceiverDirection audio_direction, - RtpTransceiverDirection video_direction, - absl::optional* audio_index, - absl::optional* video_index, - absl::optional* data_index, - cricket::MediaSessionOptions* session_options) { - for (const cricket::ContentInfo& content : - session_desc->description()->contents()) { - if (IsAudioContent(&content)) { - // If we already have an audio m= section, reject this extra one. - if (*audio_index) { - session_options->media_description_options.push_back( - cricket::MediaDescriptionOptions( - cricket::MEDIA_TYPE_AUDIO, content.name, - RtpTransceiverDirection::kInactive, /*stopped=*/true)); - } else { - bool stopped = (audio_direction == RtpTransceiverDirection::kInactive); - session_options->media_description_options.push_back( - cricket::MediaDescriptionOptions(cricket::MEDIA_TYPE_AUDIO, - content.name, audio_direction, - stopped)); - *audio_index = session_options->media_description_options.size() - 1; - } - session_options->media_description_options.back().header_extensions = - channel_manager()->GetSupportedAudioRtpHeaderExtensions(); - } else if (IsVideoContent(&content)) { - // If we already have an video m= section, reject this extra one. - if (*video_index) { - session_options->media_description_options.push_back( - cricket::MediaDescriptionOptions( - cricket::MEDIA_TYPE_VIDEO, content.name, - RtpTransceiverDirection::kInactive, /*stopped=*/true)); - } else { - bool stopped = (video_direction == RtpTransceiverDirection::kInactive); - session_options->media_description_options.push_back( - cricket::MediaDescriptionOptions(cricket::MEDIA_TYPE_VIDEO, - content.name, video_direction, - stopped)); - *video_index = session_options->media_description_options.size() - 1; - } - session_options->media_description_options.back().header_extensions = - channel_manager()->GetSupportedVideoRtpHeaderExtensions(); - } else { - RTC_DCHECK(IsDataContent(&content)); - // If we already have an data m= section, reject this extra one. - if (*data_index) { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForRejectedData(content.name)); - } else { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForActiveData(content.name)); - *data_index = session_options->media_description_options.size() - 1; - } - } - } -} - -cricket::MediaDescriptionOptions -PeerConnection::GetMediaDescriptionOptionsForActiveData( - const std::string& mid) const { - // Direction for data sections is meaningless, but legacy endpoints might - // expect sendrecv. - cricket::MediaDescriptionOptions options(cricket::MEDIA_TYPE_DATA, mid, - RtpTransceiverDirection::kSendRecv, - /*stopped=*/false); - AddRtpDataChannelOptions(*data_channel_controller_.rtp_data_channels(), - &options); - return options; -} - -cricket::MediaDescriptionOptions -PeerConnection::GetMediaDescriptionOptionsForRejectedData( - const std::string& mid) const { - cricket::MediaDescriptionOptions options(cricket::MEDIA_TYPE_DATA, mid, - RtpTransceiverDirection::kInactive, - /*stopped=*/true); - AddRtpDataChannelOptions(*data_channel_controller_.rtp_data_channels(), - &options); - return options; -} - absl::optional PeerConnection::GetDataMid() const { + RTC_DCHECK_RUN_ON(signaling_thread()); switch (data_channel_type()) { case cricket::DCT_RTP: if (!data_channel_controller_.rtp_data_channel()) { @@ -5373,259 +1763,6 @@ absl::optional PeerConnection::GetDataMid() const { } } -void PeerConnection::RemoveSenders(cricket::MediaType media_type) { - UpdateLocalSenders(std::vector(), media_type); - UpdateRemoteSendersList(std::vector(), false, - media_type, nullptr); -} - -void PeerConnection::UpdateRemoteSendersList( - const cricket::StreamParamsVec& streams, - bool default_sender_needed, - cricket::MediaType media_type, - StreamCollection* new_streams) { - RTC_DCHECK(!IsUnifiedPlan()); - - std::vector* current_senders = - GetRemoteSenderInfos(media_type); - - // Find removed senders. I.e., senders where the sender id or ssrc don't match - // the new StreamParam. - for (auto sender_it = current_senders->begin(); - sender_it != current_senders->end(); - /* incremented manually */) { - const RtpSenderInfo& info = *sender_it; - const cricket::StreamParams* params = - cricket::GetStreamBySsrc(streams, info.first_ssrc); - std::string params_stream_id; - if (params) { - params_stream_id = - (!params->first_stream_id().empty() ? params->first_stream_id() - : kDefaultStreamId); - } - bool sender_exists = params && params->id == info.sender_id && - params_stream_id == info.stream_id; - // If this is a default track, and we still need it, don't remove it. - if ((info.stream_id == kDefaultStreamId && default_sender_needed) || - sender_exists) { - ++sender_it; - } else { - OnRemoteSenderRemoved(info, media_type); - sender_it = current_senders->erase(sender_it); - } - } - - // Find new and active senders. - for (const cricket::StreamParams& params : streams) { - if (!params.has_ssrcs()) { - // The remote endpoint has streams, but didn't signal ssrcs. For an active - // sender, this means it is coming from a Unified Plan endpoint,so we just - // create a default. - default_sender_needed = true; - break; - } - - // |params.id| is the sender id and the stream id uses the first of - // |params.stream_ids|. The remote description could come from a Unified - // Plan endpoint, with multiple or no stream_ids() signaled. Since this is - // not supported in Plan B, we just take the first here and create the - // default stream ID if none is specified. - const std::string& stream_id = - (!params.first_stream_id().empty() ? params.first_stream_id() - : kDefaultStreamId); - const std::string& sender_id = params.id; - uint32_t ssrc = params.first_ssrc(); - - rtc::scoped_refptr stream = - remote_streams_->find(stream_id); - if (!stream) { - // This is a new MediaStream. Create a new remote MediaStream. - stream = MediaStreamProxy::Create(rtc::Thread::Current(), - MediaStream::Create(stream_id)); - remote_streams_->AddStream(stream); - new_streams->AddStream(stream); - } - - const RtpSenderInfo* sender_info = - FindSenderInfo(*current_senders, stream_id, sender_id); - if (!sender_info) { - current_senders->push_back(RtpSenderInfo(stream_id, sender_id, ssrc)); - OnRemoteSenderAdded(current_senders->back(), media_type); - } - } - - // Add default sender if necessary. - if (default_sender_needed) { - rtc::scoped_refptr default_stream = - remote_streams_->find(kDefaultStreamId); - if (!default_stream) { - // Create the new default MediaStream. - default_stream = MediaStreamProxy::Create( - rtc::Thread::Current(), MediaStream::Create(kDefaultStreamId)); - remote_streams_->AddStream(default_stream); - new_streams->AddStream(default_stream); - } - std::string default_sender_id = (media_type == cricket::MEDIA_TYPE_AUDIO) - ? kDefaultAudioSenderId - : kDefaultVideoSenderId; - const RtpSenderInfo* default_sender_info = - FindSenderInfo(*current_senders, kDefaultStreamId, default_sender_id); - if (!default_sender_info) { - current_senders->push_back( - RtpSenderInfo(kDefaultStreamId, default_sender_id, /*ssrc=*/0)); - OnRemoteSenderAdded(current_senders->back(), media_type); - } - } -} - -void PeerConnection::OnRemoteSenderAdded(const RtpSenderInfo& sender_info, - cricket::MediaType media_type) { - RTC_LOG(LS_INFO) << "Creating " << cricket::MediaTypeToString(media_type) - << " receiver for track_id=" << sender_info.sender_id - << " and stream_id=" << sender_info.stream_id; - - MediaStreamInterface* stream = remote_streams_->find(sender_info.stream_id); - if (media_type == cricket::MEDIA_TYPE_AUDIO) { - CreateAudioReceiver(stream, sender_info); - } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { - CreateVideoReceiver(stream, sender_info); - } else { - RTC_NOTREACHED() << "Invalid media type"; - } -} - -void PeerConnection::OnRemoteSenderRemoved(const RtpSenderInfo& sender_info, - cricket::MediaType media_type) { - RTC_LOG(LS_INFO) << "Removing " << cricket::MediaTypeToString(media_type) - << " receiver for track_id=" << sender_info.sender_id - << " and stream_id=" << sender_info.stream_id; - - MediaStreamInterface* stream = remote_streams_->find(sender_info.stream_id); - - rtc::scoped_refptr receiver; - if (media_type == cricket::MEDIA_TYPE_AUDIO) { - // When the MediaEngine audio channel is destroyed, the RemoteAudioSource - // will be notified which will end the AudioRtpReceiver::track(). - receiver = RemoveAndStopReceiver(sender_info); - rtc::scoped_refptr audio_track = - stream->FindAudioTrack(sender_info.sender_id); - if (audio_track) { - stream->RemoveTrack(audio_track); - } - } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { - // Stopping or destroying a VideoRtpReceiver will end the - // VideoRtpReceiver::track(). - receiver = RemoveAndStopReceiver(sender_info); - rtc::scoped_refptr video_track = - stream->FindVideoTrack(sender_info.sender_id); - if (video_track) { - // There's no guarantee the track is still available, e.g. the track may - // have been removed from the stream by an application. - stream->RemoveTrack(video_track); - } - } else { - RTC_NOTREACHED() << "Invalid media type"; - } - if (receiver) { - Observer()->OnRemoveTrack(receiver); - } -} - -void PeerConnection::UpdateEndedRemoteMediaStreams() { - std::vector> streams_to_remove; - for (size_t i = 0; i < remote_streams_->count(); ++i) { - MediaStreamInterface* stream = remote_streams_->at(i); - if (stream->GetAudioTracks().empty() && stream->GetVideoTracks().empty()) { - streams_to_remove.push_back(stream); - } - } - - for (auto& stream : streams_to_remove) { - remote_streams_->RemoveStream(stream); - Observer()->OnRemoveStream(std::move(stream)); - } -} - -void PeerConnection::UpdateLocalSenders( - const std::vector& streams, - cricket::MediaType media_type) { - std::vector* current_senders = GetLocalSenderInfos(media_type); - - // Find removed tracks. I.e., tracks where the track id, stream id or ssrc - // don't match the new StreamParam. - for (auto sender_it = current_senders->begin(); - sender_it != current_senders->end(); - /* incremented manually */) { - const RtpSenderInfo& info = *sender_it; - const cricket::StreamParams* params = - cricket::GetStreamBySsrc(streams, info.first_ssrc); - if (!params || params->id != info.sender_id || - params->first_stream_id() != info.stream_id) { - OnLocalSenderRemoved(info, media_type); - sender_it = current_senders->erase(sender_it); - } else { - ++sender_it; - } - } - - // Find new and active senders. - for (const cricket::StreamParams& params : streams) { - // The sync_label is the MediaStream label and the |stream.id| is the - // sender id. - const std::string& stream_id = params.first_stream_id(); - const std::string& sender_id = params.id; - uint32_t ssrc = params.first_ssrc(); - const RtpSenderInfo* sender_info = - FindSenderInfo(*current_senders, stream_id, sender_id); - if (!sender_info) { - current_senders->push_back(RtpSenderInfo(stream_id, sender_id, ssrc)); - OnLocalSenderAdded(current_senders->back(), media_type); - } - } -} - -void PeerConnection::OnLocalSenderAdded(const RtpSenderInfo& sender_info, - cricket::MediaType media_type) { - RTC_DCHECK(!IsUnifiedPlan()); - auto sender = FindSenderById(sender_info.sender_id); - if (!sender) { - RTC_LOG(LS_WARNING) << "An unknown RtpSender with id " - << sender_info.sender_id - << " has been configured in the local description."; - return; - } - - if (sender->media_type() != media_type) { - RTC_LOG(LS_WARNING) << "An RtpSender has been configured in the local" - " description with an unexpected media type."; - return; - } - - sender->internal()->set_stream_ids({sender_info.stream_id}); - sender->internal()->SetSsrc(sender_info.first_ssrc); -} - -void PeerConnection::OnLocalSenderRemoved(const RtpSenderInfo& sender_info, - cricket::MediaType media_type) { - auto sender = FindSenderById(sender_info.sender_id); - if (!sender) { - // This is the normal case. I.e., RemoveStream has been called and the - // SessionDescriptions has been renegotiated. - return; - } - - // A sender has been removed from the SessionDescription but it's still - // associated with the PeerConnection. This only occurs if the SDP doesn't - // match with the calls to CreateSender, AddStream and RemoveStream. - if (sender->media_type() != media_type) { - RTC_LOG(LS_WARNING) << "An RtpSender has been configured in the local" - " description with an unexpected media type."; - return; - } - - sender->internal()->SetSsrc(0); -} - void PeerConnection::OnSctpDataChannelClosed(DataChannelInterface* channel) { // Since data_channel_controller doesn't do signals, this // signal is relayed here. @@ -5633,100 +1770,6 @@ void PeerConnection::OnSctpDataChannelClosed(DataChannelInterface* channel) { static_cast(channel)); } -rtc::scoped_refptr> -PeerConnection::GetAudioTransceiver() const { - // This method only works with Plan B SDP, where there is a single - // audio/video transceiver. - RTC_DCHECK(!IsUnifiedPlan()); - for (auto transceiver : transceivers_) { - if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { - return transceiver; - } - } - RTC_NOTREACHED(); - return nullptr; -} - -rtc::scoped_refptr> -PeerConnection::GetVideoTransceiver() const { - // This method only works with Plan B SDP, where there is a single - // audio/video transceiver. - RTC_DCHECK(!IsUnifiedPlan()); - for (auto transceiver : transceivers_) { - if (transceiver->media_type() == cricket::MEDIA_TYPE_VIDEO) { - return transceiver; - } - } - RTC_NOTREACHED(); - return nullptr; -} - -rtc::scoped_refptr> -PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) const { - for (const auto& transceiver : transceivers_) { - for (auto sender : transceiver->internal()->senders()) { - if (sender->track() == track) { - return sender; - } - } - } - return nullptr; -} - -rtc::scoped_refptr> -PeerConnection::FindSenderById(const std::string& sender_id) const { - for (const auto& transceiver : transceivers_) { - for (auto sender : transceiver->internal()->senders()) { - if (sender->id() == sender_id) { - return sender; - } - } - } - return nullptr; -} - -rtc::scoped_refptr> -PeerConnection::FindReceiverById(const std::string& receiver_id) const { - for (const auto& transceiver : transceivers_) { - for (auto receiver : transceiver->internal()->receivers()) { - if (receiver->id() == receiver_id) { - return receiver; - } - } - } - return nullptr; -} - -std::vector* -PeerConnection::GetRemoteSenderInfos(cricket::MediaType media_type) { - RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO || - media_type == cricket::MEDIA_TYPE_VIDEO); - return (media_type == cricket::MEDIA_TYPE_AUDIO) - ? &remote_audio_sender_infos_ - : &remote_video_sender_infos_; -} - -std::vector* PeerConnection::GetLocalSenderInfos( - cricket::MediaType media_type) { - RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO || - media_type == cricket::MEDIA_TYPE_VIDEO); - return (media_type == cricket::MEDIA_TYPE_AUDIO) ? &local_audio_sender_infos_ - : &local_video_sender_infos_; -} - -const PeerConnection::RtpSenderInfo* PeerConnection::FindSenderInfo( - const std::vector& infos, - const std::string& stream_id, - const std::string sender_id) const { - for (const RtpSenderInfo& sender_info : infos) { - if (sender_info.stream_id == stream_id && - sender_info.sender_id == sender_id) { - return &sender_info; - } - } - return nullptr; -} - SctpDataChannel* PeerConnection::FindDataChannelBySid(int sid) const { return data_channel_controller_.FindDataChannelBySid(sid); } @@ -5749,12 +1792,10 @@ PeerConnection::InitializePortAllocator_n( // by experiment. if (configuration.disable_ipv6) { port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); - } else if (absl::StartsWith( - webrtc::field_trial::FindFullName("WebRTC-IPv6Default"), - "Disabled")) { + } else if (absl::StartsWith(context_->trials().Lookup("WebRTC-IPv6Default"), + "Disabled")) { port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); } - if (configuration.disable_ipv6_on_wifi) { port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled."; @@ -5809,6 +1850,7 @@ bool PeerConnection::ReconfigurePortAllocator_n( webrtc::TurnCustomizer* turn_customizer, absl::optional stun_candidate_keepalive_interval, bool have_local_description) { + RTC_DCHECK_RUN_ON(network_thread()); port_allocator_->SetCandidateFilter( ConvertIceTransportTypeToCandidateFilter(type)); // According to JSEP, after setLocalDescription, changing the candidate pool @@ -5831,7 +1873,7 @@ bool PeerConnection::ReconfigurePortAllocator_n( } cricket::ChannelManager* PeerConnection::channel_manager() const { - return factory_->channel_manager(); + return context_->channel_manager(); } bool PeerConnection::StartRtcEventLog_w( @@ -5853,7 +1895,7 @@ void PeerConnection::StopRtcEventLog_w() { cricket::ChannelInterface* PeerConnection::GetChannel( const std::string& content_name) { - for (const auto& transceiver : transceivers_) { + for (const auto& transceiver : rtp_manager()->transceivers()->List()) { cricket::ChannelInterface* channel = transceiver->internal()->channel(); if (channel && channel->content_name() == content_name) { return channel; @@ -5883,8 +1925,9 @@ bool PeerConnection::GetSctpSslRole(rtc::SSLRole* role) { absl::optional dtls_role; if (sctp_mid_s_) { dtls_role = transport_controller_->GetDtlsRole(*sctp_mid_s_); - if (!dtls_role && is_caller_.has_value()) { - dtls_role = *is_caller_ ? rtc::SSL_SERVER : rtc::SSL_CLIENT; + if (!dtls_role && sdp_handler_->is_caller().has_value()) { + dtls_role = + *sdp_handler_->is_caller() ? rtc::SSL_SERVER : rtc::SSL_CLIENT; } *role = *dtls_role; return true; @@ -5910,155 +1953,6 @@ bool PeerConnection::GetSslRole(const std::string& content_name, return false; } -void PeerConnection::SetSessionError(SessionError error, - const std::string& error_desc) { - RTC_DCHECK_RUN_ON(signaling_thread()); - if (error != session_error_) { - session_error_ = error; - session_error_desc_ = error_desc; - } -} - -RTCError PeerConnection::UpdateSessionState( - SdpType type, - cricket::ContentSource source, - const cricket::SessionDescription* description) { - RTC_DCHECK_RUN_ON(signaling_thread()); - - // If there's already a pending error then no state transition should happen. - // But all call-sites should be verifying this before calling us! - RTC_DCHECK(session_error() == SessionError::kNone); - - // If this is answer-ish we're ready to let media flow. - if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) { - EnableSending(); - } - - // Update the signaling state according to the specified state machine (see - // https://w3c.github.io/webrtc-pc/#rtcsignalingstate-enum). - if (type == SdpType::kOffer) { - ChangeSignalingState(source == cricket::CS_LOCAL - ? PeerConnectionInterface::kHaveLocalOffer - : PeerConnectionInterface::kHaveRemoteOffer); - } else if (type == SdpType::kPrAnswer) { - ChangeSignalingState(source == cricket::CS_LOCAL - ? PeerConnectionInterface::kHaveLocalPrAnswer - : PeerConnectionInterface::kHaveRemotePrAnswer); - } else { - RTC_DCHECK(type == SdpType::kAnswer); - ChangeSignalingState(PeerConnectionInterface::kStable); - transceiver_stable_states_by_transceivers_.clear(); - have_pending_rtp_data_channel_ = false; - } - - // Update internal objects according to the session description's media - // descriptions. - RTCError error = PushdownMediaDescription(type, source); - if (!error.ok()) { - return error; - } - - return RTCError::OK(); -} - -RTCError PeerConnection::PushdownMediaDescription( - SdpType type, - cricket::ContentSource source) { - const SessionDescriptionInterface* sdesc = - (source == cricket::CS_LOCAL ? local_description() - : remote_description()); - RTC_DCHECK(sdesc); - - // Push down the new SDP media section for each audio/video transceiver. - for (const auto& transceiver : transceivers_) { - const ContentInfo* content_info = - FindMediaSectionForTransceiver(transceiver, sdesc); - cricket::ChannelInterface* channel = transceiver->internal()->channel(); - if (!channel || !content_info || content_info->rejected) { - continue; - } - const MediaContentDescription* content_desc = - content_info->media_description(); - if (!content_desc) { - continue; - } - std::string error; - bool success = (source == cricket::CS_LOCAL) - ? channel->SetLocalContent(content_desc, type, &error) - : channel->SetRemoteContent(content_desc, type, &error); - if (!success) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, error); - } - } - - // If using the RtpDataChannel, push down the new SDP section for it too. - if (data_channel_controller_.rtp_data_channel()) { - const ContentInfo* data_content = - cricket::GetFirstDataContent(sdesc->description()); - if (data_content && !data_content->rejected) { - const MediaContentDescription* data_desc = - data_content->media_description(); - if (data_desc) { - std::string error; - bool success = - (source == cricket::CS_LOCAL) - ? data_channel_controller_.rtp_data_channel()->SetLocalContent( - data_desc, type, &error) - : data_channel_controller_.rtp_data_channel()->SetRemoteContent( - data_desc, type, &error); - if (!success) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, error); - } - } - } - } - - // Need complete offer/answer with an SCTP m= section before starting SCTP, - // according to https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-19 - if (sctp_mid_s_ && local_description() && remote_description()) { - rtc::scoped_refptr sctp_transport = - transport_controller_->GetSctpTransport(*sctp_mid_s_); - auto local_sctp_description = cricket::GetFirstSctpDataContentDescription( - local_description()->description()); - auto remote_sctp_description = cricket::GetFirstSctpDataContentDescription( - remote_description()->description()); - if (sctp_transport && local_sctp_description && remote_sctp_description) { - int max_message_size; - // A remote max message size of zero means "any size supported". - // We configure the connection with our own max message size. - if (remote_sctp_description->max_message_size() == 0) { - max_message_size = local_sctp_description->max_message_size(); - } else { - max_message_size = - std::min(local_sctp_description->max_message_size(), - remote_sctp_description->max_message_size()); - } - sctp_transport->Start(local_sctp_description->port(), - remote_sctp_description->port(), max_message_size); - } - } - - return RTCError::OK(); -} - -RTCError PeerConnection::PushdownTransportDescription( - cricket::ContentSource source, - SdpType type) { - RTC_DCHECK_RUN_ON(signaling_thread()); - - if (source == cricket::CS_LOCAL) { - const SessionDescriptionInterface* sdesc = local_description(); - RTC_DCHECK(sdesc); - return transport_controller_->SetLocalDescription(type, - sdesc->description()); - } else { - const SessionDescriptionInterface* sdesc = remote_description(); - RTC_DCHECK(sdesc); - return transport_controller_->SetRemoteDescription(type, - sdesc->description()); - } -} - bool PeerConnection::GetTransportDescription( const SessionDescription* description, const std::string& content_name, @@ -6075,47 +1969,6 @@ bool PeerConnection::GetTransportDescription( return true; } -cricket::IceConfig PeerConnection::ParseIceConfig( - const PeerConnectionInterface::RTCConfiguration& config) const { - cricket::ContinualGatheringPolicy gathering_policy; - switch (config.continual_gathering_policy) { - case PeerConnectionInterface::GATHER_ONCE: - gathering_policy = cricket::GATHER_ONCE; - break; - case PeerConnectionInterface::GATHER_CONTINUALLY: - gathering_policy = cricket::GATHER_CONTINUALLY; - break; - default: - RTC_NOTREACHED(); - gathering_policy = cricket::GATHER_ONCE; - } - - cricket::IceConfig ice_config; - ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt( - config.ice_connection_receiving_timeout); - ice_config.prioritize_most_likely_candidate_pairs = - config.prioritize_most_likely_ice_candidate_pairs; - ice_config.backup_connection_ping_interval = - RTCConfigurationToIceConfigOptionalInt( - config.ice_backup_candidate_pair_ping_interval); - ice_config.continual_gathering_policy = gathering_policy; - ice_config.presume_writable_when_fully_relayed = - config.presume_writable_when_fully_relayed; - ice_config.surface_ice_candidates_on_ice_transport_type_changed = - config.surface_ice_candidates_on_ice_transport_type_changed; - ice_config.ice_check_interval_strong_connectivity = - config.ice_check_interval_strong_connectivity; - ice_config.ice_check_interval_weak_connectivity = - config.ice_check_interval_weak_connectivity; - ice_config.ice_check_min_interval = config.ice_check_min_interval; - ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout; - ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks; - ice_config.ice_inactive_timeout = config.ice_inactive_timeout; - ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval; - ice_config.network_preference = config.network_preference; - return ice_config; -} - std::vector PeerConnection::GetDataChannelStats() const { RTC_DCHECK_RUN_ON(signaling_thread()); return data_channel_controller_.GetDataChannelStats(); @@ -6146,7 +1999,7 @@ std::map PeerConnection::GetTransportNamesByMid() const { RTC_DCHECK_RUN_ON(signaling_thread()); std::map transport_names_by_mid; - for (const auto& transceiver : transceivers_) { + for (const auto& transceiver : rtp_manager()->transceivers()->List()) { cricket::ChannelInterface* channel = transceiver->internal()->channel(); if (channel) { transport_names_by_mid[channel->content_name()] = @@ -6212,24 +2065,13 @@ cricket::DataChannelType PeerConnection::data_channel_type() const { bool PeerConnection::IceRestartPending(const std::string& content_name) const { RTC_DCHECK_RUN_ON(signaling_thread()); - return pending_ice_restarts_.find(content_name) != - pending_ice_restarts_.end(); + return sdp_handler_->IceRestartPending(content_name); } bool PeerConnection::NeedsIceRestart(const std::string& content_name) const { return transport_controller_->NeedsIceRestart(content_name); } -void PeerConnection::OnCertificateReady( - const rtc::scoped_refptr& certificate) { - transport_controller_->SetLocalCertificate(certificate); -} - -void PeerConnection::OnDtlsSrtpSetupFailure(cricket::BaseChannel*, bool rtcp) { - SetSessionError(SessionError::kTransport, - rtcp ? kDtlsSrtpSetupFailureRtcp : kDtlsSrtpSetupFailureRtp); -} - void PeerConnection::OnTransportControllerConnectionState( cricket::IceConnectionState state) { switch (state) { @@ -6291,9 +2133,7 @@ void PeerConnection::OnTransportControllerCandidatesGathered( // Use transport_name as the candidate media id. std::unique_ptr candidate( new JsepIceCandidate(transport_name, sdp_mline_index, *citer)); - if (local_description()) { - mutable_local_description()->AddCandidate(candidate.get()); - } + sdp_handler_->AddLocalIceCandidate(candidate.get()); OnIceCandidate(std::move(candidate)); } } @@ -6315,10 +2155,7 @@ void PeerConnection::OnTransportControllerCandidatesRemoved( return; } } - - if (local_description()) { - mutable_local_description()->RemoveCandidates(candidates); - } + sdp_handler_->RemoveLocalIceCandidates(candidates); OnIceCandidatesRemoved(candidates); } @@ -6327,6 +2164,10 @@ void PeerConnection::OnTransportControllerCandidateChanged( OnSelectedCandidatePairChanged(event); } +void PeerConnection::OnErrorDemuxingPacket(uint32_t ssrc) { + message_handler_.PostErrorDemuxingPacket(demuxing_observer_, ssrc); +} + void PeerConnection::OnTransportControllerDtlsHandshakeError( rtc::SSLHandshakeError error) { RTC_HISTOGRAM_ENUMERATION( @@ -6334,20 +2175,6 @@ void PeerConnection::OnTransportControllerDtlsHandshakeError( static_cast(rtc::SSLHandshakeError::MAX_VALUE)); } -void PeerConnection::EnableSending() { - for (const auto& transceiver : transceivers_) { - cricket::ChannelInterface* channel = transceiver->internal()->channel(); - if (channel && !channel->enabled()) { - channel->Enable(true); - } - } - - if (data_channel_controller_.rtp_data_channel() && - !data_channel_controller_.rtp_data_channel()->enabled()) { - data_channel_controller_.rtp_data_channel()->Enable(true); - } -} - // Returns the media index for a local ice candidate given the content name. bool PeerConnection::GetLocalCandidateMediaIndex( const std::string& content_name, @@ -6368,258 +2195,6 @@ bool PeerConnection::GetLocalCandidateMediaIndex( return content_found; } -bool PeerConnection::UseCandidatesInSessionDescription( - const SessionDescriptionInterface* remote_desc) { - if (!remote_desc) { - return true; - } - bool ret = true; - - for (size_t m = 0; m < remote_desc->number_of_mediasections(); ++m) { - const IceCandidateCollection* candidates = remote_desc->candidates(m); - for (size_t n = 0; n < candidates->count(); ++n) { - const IceCandidateInterface* candidate = candidates->at(n); - bool valid = false; - if (!ReadyToUseRemoteCandidate(candidate, remote_desc, &valid)) { - if (valid) { - RTC_LOG(LS_INFO) - << "UseCandidatesInSessionDescription: Not ready to use " - "candidate."; - } - continue; - } - ret = UseCandidate(candidate); - if (!ret) { - break; - } - } - } - return ret; -} - -bool PeerConnection::UseCandidate(const IceCandidateInterface* candidate) { - RTCErrorOr result = - FindContentInfo(remote_description(), candidate); - if (!result.ok()) { - RTC_LOG(LS_ERROR) << "UseCandidate: Invalid candidate. " - << result.error().message(); - return false; - } - std::vector candidates; - candidates.push_back(candidate->candidate()); - // Invoking BaseSession method to handle remote candidates. - RTCError error = transport_controller_->AddRemoteCandidates( - result.value()->name, candidates); - if (error.ok()) { - ReportRemoteIceCandidateAdded(candidate->candidate()); - // Candidates successfully submitted for checking. - if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew || - ice_connection_state_ == - PeerConnectionInterface::kIceConnectionDisconnected) { - // If state is New, then the session has just gotten its first remote ICE - // candidates, so go to Checking. - // If state is Disconnected, the session is re-using old candidates or - // receiving additional ones, so go to Checking. - // If state is Connected, stay Connected. - // TODO(bemasc): If state is Connected, and the new candidates are for a - // newly added transport, then the state actually _should_ move to - // checking. Add a way to distinguish that case. - SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); - } - // TODO(bemasc): If state is Completed, go back to Connected. - } else { - RTC_LOG(LS_WARNING) << error.message(); - } - return true; -} - -RTCErrorOr PeerConnection::FindContentInfo( - const SessionDescriptionInterface* description, - const IceCandidateInterface* candidate) { - if (candidate->sdp_mline_index() >= 0) { - size_t mediacontent_index = - static_cast(candidate->sdp_mline_index()); - size_t content_size = description->description()->contents().size(); - if (mediacontent_index < content_size) { - return &description->description()->contents()[mediacontent_index]; - } else { - return RTCError(RTCErrorType::INVALID_RANGE, - "Media line index (" + - rtc::ToString(candidate->sdp_mline_index()) + - ") out of range (number of mlines: " + - rtc::ToString(content_size) + ")."); - } - } else if (!candidate->sdp_mid().empty()) { - auto& contents = description->description()->contents(); - auto it = absl::c_find_if( - contents, [candidate](const cricket::ContentInfo& content_info) { - return content_info.mid() == candidate->sdp_mid(); - }); - if (it == contents.end()) { - return RTCError( - RTCErrorType::INVALID_PARAMETER, - "Mid " + candidate->sdp_mid() + - " specified but no media section with that mid found."); - } else { - return &*it; - } - } - - return RTCError(RTCErrorType::INVALID_PARAMETER, - "Neither sdp_mline_index nor sdp_mid specified."); -} - -void PeerConnection::RemoveUnusedChannels(const SessionDescription* desc) { - // Destroy video channel first since it may have a pointer to the - // voice channel. - const cricket::ContentInfo* video_info = cricket::GetFirstVideoContent(desc); - if (!video_info || video_info->rejected) { - DestroyTransceiverChannel(GetVideoTransceiver()); - } - - const cricket::ContentInfo* audio_info = cricket::GetFirstAudioContent(desc); - if (!audio_info || audio_info->rejected) { - DestroyTransceiverChannel(GetAudioTransceiver()); - } - - const cricket::ContentInfo* data_info = cricket::GetFirstDataContent(desc); - if (!data_info || data_info->rejected) { - DestroyDataChannelTransport(); - } -} - -RTCErrorOr PeerConnection::GetEarlyBundleGroup( - const SessionDescription& desc) const { - const cricket::ContentGroup* bundle_group = nullptr; - if (configuration_.bundle_policy == - PeerConnectionInterface::kBundlePolicyMaxBundle) { - bundle_group = desc.GetGroupByName(cricket::GROUP_TYPE_BUNDLE); - if (!bundle_group) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - "max-bundle configured but session description " - "has no BUNDLE group"); - } - } - return bundle_group; -} - -RTCError PeerConnection::CreateChannels(const SessionDescription& desc) { - // Creating the media channels. Transports should already have been created - // at this point. - const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(&desc); - if (voice && !voice->rejected && - !GetAudioTransceiver()->internal()->channel()) { - cricket::VoiceChannel* voice_channel = CreateVoiceChannel(voice->name); - if (!voice_channel) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create voice channel."); - } - GetAudioTransceiver()->internal()->SetChannel(voice_channel); - } - - const cricket::ContentInfo* video = cricket::GetFirstVideoContent(&desc); - if (video && !video->rejected && - !GetVideoTransceiver()->internal()->channel()) { - cricket::VideoChannel* video_channel = CreateVideoChannel(video->name); - if (!video_channel) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create video channel."); - } - GetVideoTransceiver()->internal()->SetChannel(video_channel); - } - - const cricket::ContentInfo* data = cricket::GetFirstDataContent(&desc); - if (data_channel_type() != cricket::DCT_NONE && data && !data->rejected && - !data_channel_controller_.rtp_data_channel() && - !data_channel_controller_.data_channel_transport()) { - if (!CreateDataChannel(data->name)) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create data channel."); - } - } - - return RTCError::OK(); -} - -// TODO(steveanton): Perhaps this should be managed by the RtpTransceiver. -cricket::VoiceChannel* PeerConnection::CreateVoiceChannel( - const std::string& mid) { - RtpTransportInternal* rtp_transport = GetRtpTransport(mid); - - cricket::VoiceChannel* voice_channel = channel_manager()->CreateVoiceChannel( - call_ptr_, configuration_.media_config, rtp_transport, signaling_thread(), - mid, SrtpRequired(), GetCryptoOptions(), &ssrc_generator_, - audio_options_); - if (!voice_channel) { - return nullptr; - } - voice_channel->SignalDtlsSrtpSetupFailure.connect( - this, &PeerConnection::OnDtlsSrtpSetupFailure); - voice_channel->SignalSentPacket.connect(this, - &PeerConnection::OnSentPacket_w); - voice_channel->SetRtpTransport(rtp_transport); - - return voice_channel; -} - -// TODO(steveanton): Perhaps this should be managed by the RtpTransceiver. -cricket::VideoChannel* PeerConnection::CreateVideoChannel( - const std::string& mid) { - RtpTransportInternal* rtp_transport = GetRtpTransport(mid); - - cricket::VideoChannel* video_channel = channel_manager()->CreateVideoChannel( - call_ptr_, configuration_.media_config, rtp_transport, signaling_thread(), - mid, SrtpRequired(), GetCryptoOptions(), &ssrc_generator_, video_options_, - video_bitrate_allocator_factory_.get()); - if (!video_channel) { - return nullptr; - } - video_channel->SignalDtlsSrtpSetupFailure.connect( - this, &PeerConnection::OnDtlsSrtpSetupFailure); - video_channel->SignalSentPacket.connect(this, - &PeerConnection::OnSentPacket_w); - video_channel->SetRtpTransport(rtp_transport); - - return video_channel; -} - -bool PeerConnection::CreateDataChannel(const std::string& mid) { - switch (data_channel_type()) { - case cricket::DCT_SCTP: - if (network_thread()->Invoke( - RTC_FROM_HERE, - rtc::Bind(&PeerConnection::SetupDataChannelTransport_n, this, - mid))) { - sctp_mid_s_ = mid; - } else { - return false; - } - return true; - case cricket::DCT_RTP: - default: - RtpTransportInternal* rtp_transport = GetRtpTransport(mid); - // TODO(bugs.webrtc.org/9987): set_rtp_data_channel() should be called on - // the network thread like set_data_channel_transport is. - data_channel_controller_.set_rtp_data_channel( - channel_manager()->CreateRtpDataChannel( - configuration_.media_config, rtp_transport, signaling_thread(), - mid, SrtpRequired(), GetCryptoOptions(), &ssrc_generator_)); - if (!data_channel_controller_.rtp_data_channel()) { - return false; - } - data_channel_controller_.rtp_data_channel() - ->SignalDtlsSrtpSetupFailure.connect( - this, &PeerConnection::OnDtlsSrtpSetupFailure); - data_channel_controller_.rtp_data_channel()->SignalSentPacket.connect( - this, &PeerConnection::OnSentPacket_w); - data_channel_controller_.rtp_data_channel()->SetRtpTransport( - rtp_transport); - have_pending_rtp_data_channel_ = true; - return true; - } - return false; -} - Call::Stats PeerConnection::GetCallStats() { if (!worker_thread()->IsCurrent()) { return worker_thread()->Invoke( @@ -6695,178 +2270,6 @@ bool PeerConnection::ValidateBundleSettings(const SessionDescription* desc) { return true; } -bool PeerConnection::HasRtcpMuxEnabled(const cricket::ContentInfo* content) { - return content->media_description()->rtcp_mux(); -} - -static RTCError ValidateMids(const cricket::SessionDescription& description) { - std::set mids; - for (const cricket::ContentInfo& content : description.contents()) { - if (content.name.empty()) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - "A media section is missing a MID attribute."); - } - if (!mids.insert(content.name).second) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - "Duplicate a=mid value '" + content.name + "'."); - } - } - return RTCError::OK(); -} - -RTCError PeerConnection::ValidateSessionDescription( - const SessionDescriptionInterface* sdesc, - cricket::ContentSource source) { - if (session_error() != SessionError::kNone) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, GetSessionErrorMsg()); - } - - if (!sdesc || !sdesc->description()) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, kInvalidSdp); - } - - SdpType type = sdesc->GetType(); - if ((source == cricket::CS_LOCAL && !ExpectSetLocalDescription(type)) || - (source == cricket::CS_REMOTE && !ExpectSetRemoteDescription(type))) { - LOG_AND_RETURN_ERROR( - RTCErrorType::INVALID_STATE, - "Called in wrong state: " + GetSignalingStateString(signaling_state())); - } - - RTCError error = ValidateMids(*sdesc->description()); - if (!error.ok()) { - return error; - } - - // Verify crypto settings. - std::string crypto_error; - if (webrtc_session_desc_factory_->SdesPolicy() == cricket::SEC_REQUIRED || - dtls_enabled_) { - RTCError crypto_error = VerifyCrypto(sdesc->description(), dtls_enabled_); - if (!crypto_error.ok()) { - return crypto_error; - } - } - - // Verify ice-ufrag and ice-pwd. - if (!VerifyIceUfragPwdPresent(sdesc->description())) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - kSdpWithoutIceUfragPwd); - } - - if (!ValidateBundleSettings(sdesc->description())) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - kBundleWithoutRtcpMux); - } - - // TODO(skvlad): When the local rtcp-mux policy is Require, reject any - // m-lines that do not rtcp-mux enabled. - - // Verify m-lines in Answer when compared against Offer. - if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) { - // With an answer we want to compare the new answer session description with - // the offer's session description from the current negotiation. - const cricket::SessionDescription* offer_desc = - (source == cricket::CS_LOCAL) ? remote_description()->description() - : local_description()->description(); - if (!MediaSectionsHaveSameCount(*offer_desc, *sdesc->description()) || - !MediaSectionsInSameOrder(*offer_desc, nullptr, *sdesc->description(), - type)) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - kMlineMismatchInAnswer); - } - } else { - // The re-offers should respect the order of m= sections in current - // description. See RFC3264 Section 8 paragraph 4 for more details. - // With a re-offer, either the current local or current remote descriptions - // could be the most up to date, so we would like to check against both of - // them if they exist. It could be the case that one of them has a 0 port - // for a media section, but the other does not. This is important to check - // against in the case that we are recycling an m= section. - const cricket::SessionDescription* current_desc = nullptr; - const cricket::SessionDescription* secondary_current_desc = nullptr; - if (local_description()) { - current_desc = local_description()->description(); - if (remote_description()) { - secondary_current_desc = remote_description()->description(); - } - } else if (remote_description()) { - current_desc = remote_description()->description(); - } - if (current_desc && - !MediaSectionsInSameOrder(*current_desc, secondary_current_desc, - *sdesc->description(), type)) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - kMlineMismatchInSubsequentOffer); - } - } - - if (IsUnifiedPlan()) { - // Ensure that each audio and video media section has at most one - // "StreamParams". This will return an error if receiving a session - // description from a "Plan B" endpoint which adds multiple tracks of the - // same type. With Unified Plan, there can only be at most one track per - // media section. - for (const ContentInfo& content : sdesc->description()->contents()) { - const MediaContentDescription& desc = *content.media_description(); - if ((desc.type() == cricket::MEDIA_TYPE_AUDIO || - desc.type() == cricket::MEDIA_TYPE_VIDEO) && - desc.streams().size() > 1u) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - "Media section has more than one track specified " - "with a=ssrc lines which is not supported with " - "Unified Plan."); - } - } - } - - return RTCError::OK(); -} - -bool PeerConnection::ExpectSetLocalDescription(SdpType type) { - PeerConnectionInterface::SignalingState state = signaling_state(); - if (type == SdpType::kOffer) { - return (state == PeerConnectionInterface::kStable) || - (state == PeerConnectionInterface::kHaveLocalOffer); - } else { - RTC_DCHECK(type == SdpType::kPrAnswer || type == SdpType::kAnswer); - return (state == PeerConnectionInterface::kHaveRemoteOffer) || - (state == PeerConnectionInterface::kHaveLocalPrAnswer); - } -} - -bool PeerConnection::ExpectSetRemoteDescription(SdpType type) { - PeerConnectionInterface::SignalingState state = signaling_state(); - if (type == SdpType::kOffer) { - return (state == PeerConnectionInterface::kStable) || - (state == PeerConnectionInterface::kHaveRemoteOffer); - } else { - RTC_DCHECK(type == SdpType::kPrAnswer || type == SdpType::kAnswer); - return (state == PeerConnectionInterface::kHaveLocalOffer) || - (state == PeerConnectionInterface::kHaveRemotePrAnswer); - } -} - -const char* PeerConnection::SessionErrorToString(SessionError error) const { - switch (error) { - case SessionError::kNone: - return "ERROR_NONE"; - case SessionError::kContent: - return "ERROR_CONTENT"; - case SessionError::kTransport: - return "ERROR_TRANSPORT"; - } - RTC_NOTREACHED(); - return ""; -} - -std::string PeerConnection::GetSessionErrorMsg() { - rtc::StringBuilder desc; - desc << kSessionError << SessionErrorToString(session_error()) << ". "; - desc << kSessionErrorDesc << session_error_desc() << "."; - return desc.Release(); -} - void PeerConnection::ReportSdpFormatReceived( const SessionDescriptionInterface& remote_offer) { int num_audio_mlines = 0; @@ -6893,8 +2296,21 @@ void PeerConnection::ReportSdpFormatReceived( } else if (num_audio_tracks > 0 || num_video_tracks > 0) { format = kSdpFormatReceivedSimple; } - RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceived", format, - kSdpFormatReceivedMax); + switch (remote_offer.GetType()) { + case SdpType::kOffer: + // Historically only offers were counted. + RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceived", + format, kSdpFormatReceivedMax); + break; + case SdpType::kAnswer: + RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceivedAnswer", + format, kSdpFormatReceivedMax); + break; + default: + RTC_LOG(LS_ERROR) << "Can not report SdpFormatReceived for " + << SdpTypeToString(remote_offer.GetType()); + break; + } } void PeerConnection::ReportIceCandidateCollected( @@ -6911,110 +2327,19 @@ void PeerConnection::ReportIceCandidateCollected( } } -void PeerConnection::ReportRemoteIceCandidateAdded( - const cricket::Candidate& candidate) { - NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED); - if (candidate.address().IsPrivateIP()) { - NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED); - } - if (candidate.address().IsUnresolvedIP()) { - NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED); - } - if (candidate.address().family() == AF_INET6) { - NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED); - } -} - void PeerConnection::NoteUsageEvent(UsageEvent event) { RTC_DCHECK_RUN_ON(signaling_thread()); - usage_event_accumulator_ |= static_cast(event); + usage_pattern_.NoteUsageEvent(event); } void PeerConnection::ReportUsagePattern() const { - RTC_DLOG(LS_INFO) << "Usage signature is " << usage_event_accumulator_; - RTC_HISTOGRAM_ENUMERATION_SPARSE("WebRTC.PeerConnection.UsagePattern", - usage_event_accumulator_, - static_cast(UsageEvent::MAX_VALUE)); - const int bad_bits = - static_cast(UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED) | - static_cast(UsageEvent::CANDIDATE_COLLECTED); - const int good_bits = - static_cast(UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED) | - static_cast(UsageEvent::REMOTE_CANDIDATE_ADDED) | - static_cast(UsageEvent::ICE_STATE_CONNECTED); - if ((usage_event_accumulator_ & bad_bits) == bad_bits && - (usage_event_accumulator_ & good_bits) == 0) { - // If called after close(), we can't report, because observer may have - // been deallocated, and therefore pointer is null. Write to log instead. - if (observer_) { - Observer()->OnInterestingUsage(usage_event_accumulator_); - } else { - RTC_LOG(LS_INFO) << "Interesting usage signature " - << usage_event_accumulator_ - << " observed after observer shutdown"; - } - } -} - -void PeerConnection::ReportNegotiatedSdpSemantics( - const SessionDescriptionInterface& answer) { - SdpSemanticNegotiated semantics_negotiated; - switch (answer.description()->msid_signaling()) { - case 0: - semantics_negotiated = kSdpSemanticNegotiatedNone; - break; - case cricket::kMsidSignalingMediaSection: - semantics_negotiated = kSdpSemanticNegotiatedUnifiedPlan; - break; - case cricket::kMsidSignalingSsrcAttribute: - semantics_negotiated = kSdpSemanticNegotiatedPlanB; - break; - case cricket::kMsidSignalingMediaSection | - cricket::kMsidSignalingSsrcAttribute: - semantics_negotiated = kSdpSemanticNegotiatedMixed; - break; - default: - RTC_NOTREACHED(); - } - RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpSemanticNegotiated", - semantics_negotiated, kSdpSemanticNegotiatedMax); -} - -// We need to check the local/remote description for the Transport instead of -// the session, because a new Transport added during renegotiation may have -// them unset while the session has them set from the previous negotiation. -// Not doing so may trigger the auto generation of transport description and -// mess up DTLS identity information, ICE credential, etc. -bool PeerConnection::ReadyToUseRemoteCandidate( - const IceCandidateInterface* candidate, - const SessionDescriptionInterface* remote_desc, - bool* valid) { - *valid = true; - - const SessionDescriptionInterface* current_remote_desc = - remote_desc ? remote_desc : remote_description(); - - if (!current_remote_desc) { - return false; - } - - RTCErrorOr result = - FindContentInfo(current_remote_desc, candidate); - if (!result.ok()) { - RTC_LOG(LS_ERROR) << "ReadyToUseRemoteCandidate: Invalid candidate. " - << result.error().message(); - - *valid = false; - return false; - } - - std::string transport_name = GetTransportName(result.value()->name); - return !transport_name.empty(); + usage_pattern_.ReportUsagePattern(observer_); } bool PeerConnection::SrtpRequired() const { return (dtls_enabled_ || - webrtc_session_desc_factory_->SdesPolicy() == cricket::SEC_REQUIRED); + sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() == + cricket::SEC_REQUIRED); } void PeerConnection::OnTransportControllerGatheringState( @@ -7024,13 +2349,18 @@ void PeerConnection::OnTransportControllerGatheringState( OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering); } else if (state == cricket::kIceGatheringComplete) { OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete); + } else if (state == cricket::kIceGatheringNew) { + OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew); + } else { + RTC_LOG(LS_ERROR) << "Unknown state received: " << state; + RTC_NOTREACHED(); } } void PeerConnection::ReportTransportStats() { std::map> media_types_by_transport_name; - for (const auto& transceiver : transceivers_) { + for (const auto& transceiver : rtp_manager()->transceivers()->List()) { if (transceiver->internal()->channel()) { const std::string& transport_name = transceiver->internal()->channel()->transport_name(); @@ -7086,7 +2416,7 @@ void PeerConnection::ReportBestConnectionState( GetIceCandidatePairCounter(local, remote), kIceCandidatePairMax); } else { - RTC_CHECK(0); + RTC_CHECK_NOTREACHED(); } // Increment the counter for IP type. @@ -7179,79 +2509,6 @@ void PeerConnection::OnSentPacket_w(const rtc::SentPacket& sent_packet) { call_->OnSentPacket(sent_packet); } -const std::string PeerConnection::GetTransportName( - const std::string& content_name) { - cricket::ChannelInterface* channel = GetChannel(content_name); - if (channel) { - return channel->transport_name(); - } - if (data_channel_controller_.data_channel_transport()) { - RTC_DCHECK(sctp_mid_s_); - if (content_name == *sctp_mid_s_) { - return *sctp_transport_name(); - } - } - // Return an empty string if failed to retrieve the transport name. - return ""; -} - -void PeerConnection::DestroyTransceiverChannel( - rtc::scoped_refptr> - transceiver) { - RTC_DCHECK(transceiver); - - cricket::ChannelInterface* channel = transceiver->internal()->channel(); - if (channel) { - transceiver->internal()->SetChannel(nullptr); - DestroyChannelInterface(channel); - } -} - -void PeerConnection::DestroyDataChannelTransport() { - if (data_channel_controller_.rtp_data_channel()) { - data_channel_controller_.OnTransportChannelClosed(); - DestroyChannelInterface(data_channel_controller_.rtp_data_channel()); - data_channel_controller_.set_rtp_data_channel(nullptr); - } - - // Note: Cannot use rtc::Bind to create a functor to invoke because it will - // grab a reference to this PeerConnection. If this is called from the - // PeerConnection destructor, the RefCountedObject vtable will have already - // been destroyed (since it is a subclass of PeerConnection) and using - // rtc::Bind will cause "Pure virtual function called" error to appear. - - if (sctp_mid_s_) { - data_channel_controller_.OnTransportChannelClosed(); - network_thread()->Invoke(RTC_FROM_HERE, [this] { - RTC_DCHECK_RUN_ON(network_thread()); - TeardownDataChannelTransport_n(); - }); - sctp_mid_s_.reset(); - } -} - -void PeerConnection::DestroyChannelInterface( - cricket::ChannelInterface* channel) { - RTC_DCHECK(channel); - switch (channel->media_type()) { - case cricket::MEDIA_TYPE_AUDIO: - channel_manager()->DestroyVoiceChannel( - static_cast(channel)); - break; - case cricket::MEDIA_TYPE_VIDEO: - channel_manager()->DestroyVideoChannel( - static_cast(channel)); - break; - case cricket::MEDIA_TYPE_DATA: - channel_manager()->DestroyRtpDataChannel( - static_cast(channel)); - break; - default: - RTC_NOTREACHED() << "Unknown media type: " << channel->media_type(); - break; - } -} - bool PeerConnection::OnTransportChanged( const std::string& mid, RtpTransportInternal* rtp_transport, @@ -7269,12 +2526,6 @@ bool PeerConnection::OnTransportChanged( return ret; } -void PeerConnection::OnSetStreams() { - RTC_DCHECK_RUN_ON(signaling_thread()); - if (IsUnifiedPlan()) - UpdateNegotiationNeeded(); -} - PeerConnectionObserver* PeerConnection::Observer() const { RTC_DCHECK_RUN_ON(signaling_thread()); RTC_DCHECK(observer_); @@ -7282,11 +2533,12 @@ PeerConnectionObserver* PeerConnection::Observer() const { } CryptoOptions PeerConnection::GetCryptoOptions() { + RTC_DCHECK_RUN_ON(signaling_thread()); // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions // after it has been removed. return configuration_.crypto_options.has_value() ? *configuration_.crypto_options - : factory_->options().crypto_options; + : options_.crypto_options; } void PeerConnection::ClearStatsCache() { @@ -7296,283 +2548,52 @@ void PeerConnection::ClearStatsCache() { } } +bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) { + RTC_DCHECK_RUN_ON(signaling_thread()); + return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id); +} + void PeerConnection::RequestUsagePatternReportForTesting() { - signaling_thread()->Post(RTC_FROM_HERE, this, MSG_REPORT_USAGE_PATTERN, - nullptr); + message_handler_.RequestUsagePatternReport( + [this]() { + RTC_DCHECK_RUN_ON(signaling_thread()); + ReportUsagePattern(); + }, + /* delay_ms= */ 0); } -void PeerConnection::UpdateNegotiationNeeded() { +std::function +PeerConnection::InitializeRtcpCallback() { RTC_DCHECK_RUN_ON(signaling_thread()); - if (!IsUnifiedPlan()) { - Observer()->OnRenegotiationNeeded(); - return; - } - // If connection's [[IsClosed]] slot is true, abort these steps. - if (IsClosed()) - return; + auto flag = + worker_thread()->Invoke>( + RTC_FROM_HERE, [this] { + RTC_DCHECK_RUN_ON(worker_thread()); + if (!call_) + return rtc::scoped_refptr(); + if (!call_safety_) + call_safety_.reset(new ScopedTaskSafety()); + return call_safety_->flag(); + }); - // If connection's signaling state is not "stable", abort these steps. - if (signaling_state() != kStable) - return; + if (!flag) + return [](const rtc::CopyOnWriteBuffer&, int64_t) {}; - // NOTE - // The negotiation-needed flag will be updated once the state transitions to - // "stable", as part of the steps for setting an RTCSessionDescription. - - // If the result of checking if negotiation is needed is false, clear the - // negotiation-needed flag by setting connection's [[NegotiationNeeded]] slot - // to false, and abort these steps. - bool is_negotiation_needed = CheckIfNegotiationIsNeeded(); - if (!is_negotiation_needed) { - is_negotiation_needed_ = false; - return; - } - - // If connection's [[NegotiationNeeded]] slot is already true, abort these - // steps. - if (is_negotiation_needed_) - return; - - // Set connection's [[NegotiationNeeded]] slot to true. - is_negotiation_needed_ = true; - - // Queue a task that runs the following steps: - // If connection's [[IsClosed]] slot is true, abort these steps. - // If connection's [[NegotiationNeeded]] slot is false, abort these steps. - // Fire an event named negotiationneeded at connection. - Observer()->OnRenegotiationNeeded(); -} - -bool PeerConnection::CheckIfNegotiationIsNeeded() { - RTC_DCHECK_RUN_ON(signaling_thread()); - // 1. If any implementation-specific negotiation is required, as described at - // the start of this section, return true. - - // 2. If connection.[[LocalIceCredentialsToReplace]] is not empty, return - // true. - if (local_ice_credentials_to_replace_->HasIceCredentials()) { - return true; - } - - // 3. Let description be connection.[[CurrentLocalDescription]]. - const SessionDescriptionInterface* description = current_local_description(); - if (!description) - return true; - - // 4. If connection has created any RTCDataChannels, and no m= section in - // description has been negotiated yet for data, return true. - if (data_channel_controller_.HasSctpDataChannels()) { - if (!cricket::GetFirstDataContent(description->description()->contents())) - return true; - } - - // 5. For each transceiver in connection's set of transceivers, perform the - // following checks: - for (const auto& transceiver : transceivers_) { - const ContentInfo* current_local_msection = - FindTransceiverMSection(transceiver.get(), description); - - const ContentInfo* current_remote_msection = FindTransceiverMSection( - transceiver.get(), current_remote_description()); - - // 5.4 If transceiver is stopped and is associated with an m= section, - // but the associated m= section is not yet rejected in - // connection.[[CurrentLocalDescription]] or - // connection.[[CurrentRemoteDescription]], return true. - if (transceiver->stopped()) { - RTC_DCHECK(transceiver->stopping()); - if (current_local_msection && !current_local_msection->rejected && - ((current_remote_msection && !current_remote_msection->rejected) || - !current_remote_msection)) { - return true; - } - continue; - } - - // 5.1 If transceiver.[[Stopping]] is true and transceiver.[[Stopped]] is - // false, return true. - if (transceiver->stopping() && !transceiver->stopped()) - return true; - - // 5.2 If transceiver isn't stopped and isn't yet associated with an m= - // section in description, return true. - if (!current_local_msection) - return true; - - const MediaContentDescription* current_local_media_description = - current_local_msection->media_description(); - // 5.3 If transceiver isn't stopped and is associated with an m= section - // in description then perform the following checks: - - // 5.3.1 If transceiver.[[Direction]] is "sendrecv" or "sendonly", and the - // associated m= section in description either doesn't contain a single - // "a=msid" line, or the number of MSIDs from the "a=msid" lines in this - // m= section, or the MSID values themselves, differ from what is in - // transceiver.sender.[[AssociatedMediaStreamIds]], return true. - if (RtpTransceiverDirectionHasSend(transceiver->direction())) { - if (current_local_media_description->streams().size() == 0) - return true; - - std::vector msection_msids; - for (const auto& stream : current_local_media_description->streams()) { - for (const std::string& msid : stream.stream_ids()) - msection_msids.push_back(msid); - } - - std::vector transceiver_msids = - transceiver->sender()->stream_ids(); - if (msection_msids.size() != transceiver_msids.size()) - return true; - - absl::c_sort(transceiver_msids); - absl::c_sort(msection_msids); - if (transceiver_msids != msection_msids) - return true; - } - - // 5.3.2 If description is of type "offer", and the direction of the - // associated m= section in neither connection.[[CurrentLocalDescription]] - // nor connection.[[CurrentRemoteDescription]] matches - // transceiver.[[Direction]], return true. - if (description->GetType() == SdpType::kOffer) { - if (!current_remote_description()) - return true; - - if (!current_remote_msection) - return true; - - RtpTransceiverDirection current_local_direction = - current_local_media_description->direction(); - RtpTransceiverDirection current_remote_direction = - current_remote_msection->media_description()->direction(); - if (transceiver->direction() != current_local_direction && - transceiver->direction() != - RtpTransceiverDirectionReversed(current_remote_direction)) { - return true; - } - } - - // 5.3.3 If description is of type "answer", and the direction of the - // associated m= section in the description does not match - // transceiver.[[Direction]] intersected with the offered direction (as - // described in [JSEP] (section 5.3.1.)), return true. - if (description->GetType() == SdpType::kAnswer) { - if (!remote_description()) - return true; - - const ContentInfo* offered_remote_msection = - FindTransceiverMSection(transceiver.get(), remote_description()); - - RtpTransceiverDirection offered_direction = - offered_remote_msection - ? offered_remote_msection->media_description()->direction() - : RtpTransceiverDirection::kInactive; - - if (current_local_media_description->direction() != - (RtpTransceiverDirectionIntersection( - transceiver->direction(), - RtpTransceiverDirectionReversed(offered_direction)))) { - return true; - } - } - } - - // If all the preceding checks were performed and true was not returned, - // nothing remains to be negotiated; return false. - return false; -} - -RTCError PeerConnection::Rollback(SdpType sdp_type) { - auto state = signaling_state(); - if (state != PeerConnectionInterface::kHaveLocalOffer && - state != PeerConnectionInterface::kHaveRemoteOffer) { - return RTCError(RTCErrorType::INVALID_STATE, - "Called in wrong signalingState: " + - GetSignalingStateString(signaling_state())); - } - RTC_DCHECK_RUN_ON(signaling_thread()); - RTC_DCHECK(IsUnifiedPlan()); - std::vector> all_added_streams; - std::vector> all_removed_streams; - std::vector> removed_receivers; - - for (auto&& transceivers_stable_state_pair : - transceiver_stable_states_by_transceivers_) { - auto transceiver = transceivers_stable_state_pair.first; - auto state = transceivers_stable_state_pair.second; - - if (state.remote_stream_ids()) { - std::vector> added_streams; - std::vector> removed_streams; - SetAssociatedRemoteStreams(transceiver->internal()->receiver_internal(), - state.remote_stream_ids().value(), - &added_streams, &removed_streams); - all_added_streams.insert(all_added_streams.end(), added_streams.begin(), - added_streams.end()); - all_removed_streams.insert(all_removed_streams.end(), - removed_streams.begin(), - removed_streams.end()); - if (!state.has_m_section() && !state.newly_created()) { - continue; - } - } - - RTC_DCHECK(transceiver->internal()->mid().has_value()); - DestroyTransceiverChannel(transceiver); - - if (signaling_state() == PeerConnectionInterface::kHaveRemoteOffer && - transceiver->receiver()) { - removed_receivers.push_back(transceiver->receiver()); - } - if (state.newly_created()) { - if (transceiver->internal()->reused_for_addtrack()) { - transceiver->internal()->set_created_by_addtrack(true); - } else { - int remaining_transceiver_count = 0; - for (auto&& t : transceivers_) { - if (t != transceiver) { - transceivers_[remaining_transceiver_count++] = t; - } - } - transceivers_.resize(remaining_transceiver_count); - } - } - transceiver->internal()->sender_internal()->set_transport(nullptr); - transceiver->internal()->receiver_internal()->set_transport(nullptr); - transceiver->internal()->set_mid(state.mid()); - transceiver->internal()->set_mline_index(state.mline_index()); - } - transport_controller_->RollbackTransports(); - if (have_pending_rtp_data_channel_) { - DestroyDataChannelTransport(); - have_pending_rtp_data_channel_ = false; - } - transceiver_stable_states_by_transceivers_.clear(); - pending_local_description_.reset(); - pending_remote_description_.reset(); - ChangeSignalingState(PeerConnectionInterface::kStable); - - // Once all processing has finished, fire off callbacks. - for (const auto& receiver : removed_receivers) { - Observer()->OnRemoveTrack(receiver); - } - for (const auto& stream : all_added_streams) { - Observer()->OnAddStream(stream); - } - for (const auto& stream : all_removed_streams) { - Observer()->OnRemoveStream(stream); - } - - // The assumption is that in case of implicit rollback UpdateNegotiationNeeded - // gets called in SetRemoteDescription. - if (sdp_type == SdpType::kRollback) { - UpdateNegotiationNeeded(); - if (is_negotiation_needed_) { - Observer()->OnRenegotiationNeeded(); - } - } - return RTCError::OK(); + return [this, flag = std::move(flag)](const rtc::CopyOnWriteBuffer& packet, + int64_t packet_time_us) { + RTC_DCHECK_RUN_ON(network_thread()); + // TODO(bugs.webrtc.org/11993): We should actually be delivering this call + // directly to the Call class somehow directly on the network thread and not + // incur this hop here. The DeliverPacket() method will eventually just have + // to hop back over to the network thread. + worker_thread()->PostTask(ToQueuedTask(flag, [this, packet, + packet_time_us] { + RTC_DCHECK_RUN_ON(worker_thread()); + call_->Receiver()->DeliverPacket(MediaType::ANY, packet, packet_time_us); + })); + }; } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/peer_connection.h b/TMessagesProj/jni/voip/webrtc/pc/peer_connection.h index 41cb68c64..9c0541cc4 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/peer_connection.h +++ b/TMessagesProj/jni/voip/webrtc/pc/peer_connection.h @@ -11,6 +11,8 @@ #ifndef PC_PEER_CONNECTION_H_ #define PC_PEER_CONNECTION_H_ +#include +#include #include #include #include @@ -18,33 +20,86 @@ #include #include +#include "absl/types/optional.h" +#include "api/adaptation/resource.h" +#include "api/async_resolver_factory.h" +#include "api/audio_options.h" +#include "api/candidate.h" +#include "api/crypto/crypto_options.h" +#include "api/data_channel_interface.h" +#include "api/dtls_transport_interface.h" +#include "api/ice_transport_interface.h" +#include "api/jsep.h" +#include "api/media_stream_interface.h" +#include "api/media_types.h" +#include "api/packet_socket_factory.h" #include "api/peer_connection_interface.h" +#include "api/rtc_error.h" +#include "api/rtc_event_log/rtc_event_log.h" +#include "api/rtc_event_log_output.h" +#include "api/rtp_parameters.h" +#include "api/rtp_receiver_interface.h" +#include "api/rtp_sender_interface.h" +#include "api/rtp_transceiver_interface.h" +#include "api/scoped_refptr.h" +#include "api/sctp_transport_interface.h" +#include "api/set_local_description_observer_interface.h" +#include "api/set_remote_description_observer_interface.h" +#include "api/stats/rtc_stats_collector_callback.h" +#include "api/transport/bitrate_settings.h" #include "api/transport/data_channel_transport_interface.h" +#include "api/transport/enums.h" #include "api/turn_customizer.h" +#include "api/video/video_bitrate_allocator_factory.h" +#include "call/call.h" +#include "media/base/media_channel.h" +#include "media/base/media_engine.h" +#include "p2p/base/ice_transport_internal.h" +#include "p2p/base/port.h" +#include "p2p/base/port_allocator.h" +#include "p2p/base/transport_description.h" +#include "pc/channel.h" +#include "pc/channel_interface.h" +#include "pc/channel_manager.h" +#include "pc/connection_context.h" #include "pc/data_channel_controller.h" -#include "pc/ice_server_parsing.h" +#include "pc/data_channel_utils.h" +#include "pc/dtls_transport.h" #include "pc/jsep_transport_controller.h" -#include "pc/peer_connection_factory.h" #include "pc/peer_connection_internal.h" +#include "pc/peer_connection_message_handler.h" #include "pc/rtc_stats_collector.h" +#include "pc/rtp_data_channel.h" +#include "pc/rtp_receiver.h" #include "pc/rtp_sender.h" #include "pc/rtp_transceiver.h" +#include "pc/rtp_transmission_manager.h" +#include "pc/rtp_transport_internal.h" +#include "pc/sctp_data_channel.h" #include "pc/sctp_transport.h" +#include "pc/sdp_offer_answer.h" +#include "pc/session_description.h" #include "pc/stats_collector.h" #include "pc/stream_collection.h" -#include "pc/webrtc_session_description_factory.h" -#include "rtc_base/experiments/field_trial_parser.h" -#include "rtc_base/operations_chain.h" -#include "rtc_base/race_checker.h" +#include "pc/transceiver_list.h" +#include "pc/transport_stats.h" +#include "pc/usage_pattern.h" +#include "rtc_base/checks.h" +#include "rtc_base/copy_on_write_buffer.h" +#include "rtc_base/deprecation.h" +#include "rtc_base/network/sent_packet.h" +#include "rtc_base/rtc_certificate.h" +#include "rtc_base/ssl_certificate.h" +#include "rtc_base/ssl_stream_adapter.h" +#include "rtc_base/synchronization/sequence_checker.h" +#include "rtc_base/task_utils/pending_task_safety_flag.h" +#include "rtc_base/third_party/sigslot/sigslot.h" +#include "rtc_base/thread.h" +#include "rtc_base/thread_annotations.h" #include "rtc_base/unique_id_generator.h" -#include "rtc_base/weak_ptr.h" namespace webrtc { -class MediaStreamObserver; -class VideoRtpReceiver; -class RtcEventLog; - // PeerConnection is the implementation of the PeerConnection object as defined // by the PeerConnectionInterface API surface. // The class currently is solely responsible for the following: @@ -61,62 +116,19 @@ class RtcEventLog; // - Generating stats. class PeerConnection : public PeerConnectionInternal, public JsepTransportController::Observer, - public RtpSenderBase::SetStreamsObserver, - public rtc::MessageHandler, public sigslot::has_slots<> { public: - // A bit in the usage pattern is registered when its defining event occurs at - // least once. - enum class UsageEvent : int { - TURN_SERVER_ADDED = 0x01, - STUN_SERVER_ADDED = 0x02, - DATA_ADDED = 0x04, - AUDIO_ADDED = 0x08, - VIDEO_ADDED = 0x10, - // |SetLocalDescription| returns successfully. - SET_LOCAL_DESCRIPTION_SUCCEEDED = 0x20, - // |SetRemoteDescription| returns successfully. - SET_REMOTE_DESCRIPTION_SUCCEEDED = 0x40, - // A local candidate (with type host, server-reflexive, or relay) is - // collected. - CANDIDATE_COLLECTED = 0x80, - // A remote candidate is successfully added via |AddIceCandidate|. - ADD_ICE_CANDIDATE_SUCCEEDED = 0x100, - ICE_STATE_CONNECTED = 0x200, - CLOSE_CALLED = 0x400, - // A local candidate with private IP is collected. - PRIVATE_CANDIDATE_COLLECTED = 0x800, - // A remote candidate with private IP is added, either via AddiceCandidate - // or from the remote description. - REMOTE_PRIVATE_CANDIDATE_ADDED = 0x1000, - // A local mDNS candidate is collected. - MDNS_CANDIDATE_COLLECTED = 0x2000, - // A remote mDNS candidate is added, either via AddIceCandidate or from the - // remote description. - REMOTE_MDNS_CANDIDATE_ADDED = 0x4000, - // A local candidate with IPv6 address is collected. - IPV6_CANDIDATE_COLLECTED = 0x8000, - // A remote candidate with IPv6 address is added, either via AddIceCandidate - // or from the remote description. - REMOTE_IPV6_CANDIDATE_ADDED = 0x10000, - // A remote candidate (with type host, server-reflexive, or relay) is - // successfully added, either via AddIceCandidate or from the remote - // description. - REMOTE_CANDIDATE_ADDED = 0x20000, - // An explicit host-host candidate pair is selected, i.e. both the local and - // the remote candidates have the host type. This does not include candidate - // pairs formed with equivalent prflx remote candidates, e.g. a host-prflx - // pair where the prflx candidate has the same base as a host candidate of - // the remote peer. - DIRECT_CONNECTION_SELECTED = 0x40000, - MAX_VALUE = 0x80000, - }; - - explicit PeerConnection(PeerConnectionFactory* factory, - std::unique_ptr event_log, - std::unique_ptr call); - - bool Initialize( + // Creates a PeerConnection and initializes it with the given values. + // If the initialization fails, the function releases the PeerConnection + // and returns nullptr. + // + // Note that the function takes ownership of dependencies, and will + // either use them or release them, whether it succeeds or fails. + static rtc::scoped_refptr Create( + rtc::scoped_refptr context, + const PeerConnectionFactoryInterface::Options& options, + std::unique_ptr event_log, + std::unique_ptr call, const PeerConnectionInterface::RTCConfiguration& configuration, PeerConnectionDependencies dependencies); @@ -143,18 +155,6 @@ class PeerConnection : public PeerConnectionInternal, cricket::MediaType media_type, const RtpTransceiverInit& init) override; - // Gets the DTLS SSL certificate associated with the audio transport on the - // remote side. This will become populated once the DTLS connection with the - // peer has been completed, as indicated by the ICE connection state - // transitioning to kIceConnectionCompleted. - // Note that this will be removed once we implement RTCDtlsTransport which - // has standardized method for getting this information. - // See https://www.w3.org/TR/webrtc/#rtcdtlstransport-interface - std::unique_ptr GetRemoteAudioSSLCertificate(); - - // Version of the above method that returns the full certificate chain. - std::unique_ptr GetRemoteAudioSSLCertChain(); - rtc::scoped_refptr CreateSender( const std::string& kind, const std::string& stream_id) override; @@ -169,6 +169,7 @@ class PeerConnection : public PeerConnectionInternal, rtc::scoped_refptr CreateDataChannel( const std::string& label, const DataChannelInit* config) override; + // WARNING: LEGACY. See peerconnectioninterface.h bool GetStats(StatsObserver* observer, webrtc::MediaStreamTrackInterface* track, @@ -261,14 +262,14 @@ class PeerConnection : public PeerConnectionInternal, void Close() override; rtc::Thread* signaling_thread() const final { - return factory_->signaling_thread(); + return context_->signaling_thread(); } // PeerConnectionInternal implementation. rtc::Thread* network_thread() const final { - return factory_->network_thread(); + return context_->network_thread(); } - rtc::Thread* worker_thread() const final { return factory_->worker_thread(); } + rtc::Thread* worker_thread() const final { return context_->worker_thread(); } std::string session_id() const override { RTC_DCHECK_RUN_ON(signaling_thread()); @@ -284,7 +285,7 @@ class PeerConnection : public PeerConnectionInternal, rtc::scoped_refptr>> GetTransceiversInternal() const override { RTC_DCHECK_RUN_ON(signaling_thread()); - return transceivers_; + return rtp_manager()->transceivers()->List(); } sigslot::signal1& SignalRtpDataChannelCreated() override { @@ -324,174 +325,94 @@ class PeerConnection : public PeerConnectionInternal, PeerConnectionObserver* Observer() const; bool IsClosed() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return signaling_state_ == PeerConnectionInterface::kClosed; + return sdp_handler_->signaling_state() == PeerConnectionInterface::kClosed; } // Get current SSL role used by SCTP's underlying transport. bool GetSctpSslRole(rtc::SSLRole* role); // Handler for the "channel closed" signal void OnSctpDataChannelClosed(DataChannelInterface* channel); - // Functions made public for testing. - void ReturnHistogramVeryQuicklyForTesting() { + bool ShouldFireNegotiationNeededEvent(uint32_t event_id) override; + + // Functions needed by SdpOfferAnswerHandler + StatsCollector* stats() { RTC_DCHECK_RUN_ON(signaling_thread()); - return_histogram_very_quickly_ = true; + return stats_.get(); + } + DataChannelController* data_channel_controller() { + RTC_DCHECK_RUN_ON(signaling_thread()); + return &data_channel_controller_; + } + bool dtls_enabled() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return dtls_enabled_; + } + const PeerConnectionInterface::RTCConfiguration* configuration() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return &configuration_; } - void RequestUsagePatternReportForTesting(); absl::optional sctp_mid() { RTC_DCHECK_RUN_ON(signaling_thread()); return sctp_mid_s_; } + PeerConnectionMessageHandler* message_handler() { + RTC_DCHECK_RUN_ON(signaling_thread()); + return &message_handler_; + } - protected: - ~PeerConnection() override; + RtpTransmissionManager* rtp_manager() { return rtp_manager_.get(); } + const RtpTransmissionManager* rtp_manager() const { + return rtp_manager_.get(); + } + cricket::ChannelManager* channel_manager() const; - private: - class ImplicitCreateSessionDescriptionObserver; - friend class ImplicitCreateSessionDescriptionObserver; - class SetSessionDescriptionObserverAdapter; - friend class SetSessionDescriptionObserverAdapter; + JsepTransportController* transport_controller() { + return transport_controller_.get(); + } + cricket::PortAllocator* port_allocator() { return port_allocator_.get(); } + Call* call_ptr() { return call_ptr_; } - // Represents the [[LocalIceCredentialsToReplace]] internal slot in the spec. - // It makes the next CreateOffer() produce new ICE credentials even if - // RTCOfferAnswerOptions::ice_restart is false. - // https://w3c.github.io/webrtc-pc/#dfn-localufragstoreplace - // TODO(hbos): When JsepTransportController/JsepTransport supports rollback, - // move this type of logic to JsepTransportController/JsepTransport. - class LocalIceCredentialsToReplace; + ConnectionContext* context() { return context_.get(); } + const PeerConnectionFactoryInterface::Options* options() const { + return &options_; + } + cricket::DataChannelType data_channel_type() const; + void SetIceConnectionState(IceConnectionState new_state); + void NoteUsageEvent(UsageEvent event); - struct RtpSenderInfo { - RtpSenderInfo() : first_ssrc(0) {} - RtpSenderInfo(const std::string& stream_id, - const std::string sender_id, - uint32_t ssrc) - : stream_id(stream_id), sender_id(sender_id), first_ssrc(ssrc) {} - bool operator==(const RtpSenderInfo& other) { - return this->stream_id == other.stream_id && - this->sender_id == other.sender_id && - this->first_ssrc == other.first_ssrc; - } - std::string stream_id; - std::string sender_id; - // An RtpSender can have many SSRCs. The first one is used as a sort of ID - // for communicating with the lower layers. - uint32_t first_ssrc; - }; + // Report the UMA metric SdpFormatReceived for the given remote offer. + void ReportSdpFormatReceived(const SessionDescriptionInterface& remote_offer); - // Captures partial state to be used for rollback. Applicable only in - // Unified Plan. - class TransceiverStableState { - public: - TransceiverStableState() {} - void set_newly_created(); - void SetMSectionIfUnset(absl::optional mid, - absl::optional mline_index); - void SetRemoteStreamIdsIfUnset(const std::vector& ids); - absl::optional mid() const { return mid_; } - absl::optional mline_index() const { return mline_index_; } - absl::optional> remote_stream_ids() const { - return remote_stream_ids_; - } - bool has_m_section() const { return has_m_section_; } - bool newly_created() const { return newly_created_; } + // Returns true if the PeerConnection is configured to use Unified Plan + // semantics for creating offers/answers and setting local/remote + // descriptions. If this is true the RtpTransceiver API will also be available + // to the user. If this is false, Plan B semantics are assumed. + // TODO(bugs.webrtc.org/8530): Flip the default to be Unified Plan once + // sufficient time has passed. + bool IsUnifiedPlan() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return is_unified_plan_; + } + bool ValidateBundleSettings(const cricket::SessionDescription* desc); - private: - absl::optional mid_; - absl::optional mline_index_; - absl::optional> remote_stream_ids_; - // Indicates that mid value from stable state has been captured and - // that rollback has to restore the transceiver. Also protects against - // subsequent overwrites. - bool has_m_section_ = false; - // Indicates that the transceiver was created as part of applying a - // description to track potential need for removing transceiver during - // rollback. - bool newly_created_ = false; - }; + // Returns the MID for the data section associated with either the + // RtpDataChannel or SCTP data channel, if it has been set. If no data + // channels are configured this will return nullopt. + absl::optional GetDataMid() const; - // Implements MessageHandler. - void OnMessage(rtc::Message* msg) override; + void SetSctpDataMid(const std::string& mid) { + RTC_DCHECK_RUN_ON(signaling_thread()); + sctp_mid_s_ = mid; + } + void ResetSctpDataMid() { + RTC_DCHECK_RUN_ON(signaling_thread()); + sctp_mid_s_.reset(); + } - // Plan B helpers for getting the voice/video media channels for the single - // audio/video transceiver, if it exists. - cricket::VoiceMediaChannel* voice_media_channel() const - RTC_RUN_ON(signaling_thread()); - cricket::VideoMediaChannel* video_media_channel() const - RTC_RUN_ON(signaling_thread()); - - std::vector>> - GetSendersInternal() const RTC_RUN_ON(signaling_thread()); - std::vector< - rtc::scoped_refptr>> - GetReceiversInternal() const RTC_RUN_ON(signaling_thread()); - - rtc::scoped_refptr> - GetAudioTransceiver() const RTC_RUN_ON(signaling_thread()); - rtc::scoped_refptr> - GetVideoTransceiver() const RTC_RUN_ON(signaling_thread()); - - rtc::scoped_refptr> - GetFirstAudioTransceiver() const RTC_RUN_ON(signaling_thread()); - - // Implementation of the offer/answer exchange operations. These are chained - // onto the |operations_chain_| when the public CreateOffer(), CreateAnswer(), - // SetLocalDescription() and SetRemoteDescription() methods are invoked. - void DoCreateOffer( - const RTCOfferAnswerOptions& options, - rtc::scoped_refptr observer); - void DoCreateAnswer( - const RTCOfferAnswerOptions& options, - rtc::scoped_refptr observer); - void DoSetLocalDescription( - std::unique_ptr desc, - rtc::scoped_refptr observer); - void DoSetRemoteDescription( - std::unique_ptr desc, - rtc::scoped_refptr observer); - - void CreateAudioReceiver(MediaStreamInterface* stream, - const RtpSenderInfo& remote_sender_info) - RTC_RUN_ON(signaling_thread()); - - void CreateVideoReceiver(MediaStreamInterface* stream, - const RtpSenderInfo& remote_sender_info) - RTC_RUN_ON(signaling_thread()); - rtc::scoped_refptr RemoveAndStopReceiver( - const RtpSenderInfo& remote_sender_info) RTC_RUN_ON(signaling_thread()); - - // May be called either by AddStream/RemoveStream, or when a track is - // added/removed from a stream previously added via AddStream. - void AddAudioTrack(AudioTrackInterface* track, MediaStreamInterface* stream) - RTC_RUN_ON(signaling_thread()); - void RemoveAudioTrack(AudioTrackInterface* track, - MediaStreamInterface* stream) - RTC_RUN_ON(signaling_thread()); - void AddVideoTrack(VideoTrackInterface* track, MediaStreamInterface* stream) - RTC_RUN_ON(signaling_thread()); - void RemoveVideoTrack(VideoTrackInterface* track, - MediaStreamInterface* stream) - RTC_RUN_ON(signaling_thread()); - - // AddTrack implementation when Unified Plan is specified. - RTCErrorOr> AddTrackUnifiedPlan( - rtc::scoped_refptr track, - const std::vector& stream_ids) - RTC_RUN_ON(signaling_thread()); - // AddTrack implementation when Plan B is specified. - RTCErrorOr> AddTrackPlanB( - rtc::scoped_refptr track, - const std::vector& stream_ids) - RTC_RUN_ON(signaling_thread()); - - // Returns the first RtpTransceiver suitable for a newly added track, if such - // transceiver is available. - rtc::scoped_refptr> - FindFirstTransceiverForAddedTrack( - rtc::scoped_refptr track) - RTC_RUN_ON(signaling_thread()); - - rtc::scoped_refptr> - FindTransceiverBySender(rtc::scoped_refptr sender) - RTC_RUN_ON(signaling_thread()); + // Returns the CryptoOptions for this PeerConnection. This will always + // return the RTCConfiguration.crypto_options if set and will only default + // back to the PeerConnectionFactory settings if nothing was set. + CryptoOptions GetCryptoOptions(); // Internal implementation for AddTransceiver family of methods. If // |fire_callback| is set, fires OnRenegotiationNeeded callback if successful. @@ -499,28 +420,54 @@ class PeerConnection : public PeerConnectionInternal, cricket::MediaType media_type, rtc::scoped_refptr track, const RtpTransceiverInit& init, - bool fire_callback = true) RTC_RUN_ON(signaling_thread()); + bool fire_callback = true); - rtc::scoped_refptr> - CreateSender(cricket::MediaType media_type, - const std::string& id, - rtc::scoped_refptr track, - const std::vector& stream_ids, - const std::vector& send_encodings); + // Returns rtp transport, result can not be nullptr. + RtpTransportInternal* GetRtpTransport(const std::string& mid) { + RTC_DCHECK_RUN_ON(signaling_thread()); + auto rtp_transport = transport_controller_->GetRtpTransport(mid); + RTC_DCHECK(rtp_transport); + return rtp_transport; + } - rtc::scoped_refptr> - CreateReceiver(cricket::MediaType media_type, const std::string& receiver_id); + // Returns true if SRTP (either using DTLS-SRTP or SDES) is required by + // this session. + bool SrtpRequired() const RTC_RUN_ON(signaling_thread()); + + void OnSentPacket_w(const rtc::SentPacket& sent_packet); + + bool SetupDataChannelTransport_n(const std::string& mid) + RTC_RUN_ON(network_thread()); + void TeardownDataChannelTransport_n() RTC_RUN_ON(network_thread()); + cricket::ChannelInterface* GetChannel(const std::string& content_name); + + // Functions made public for testing. + void ReturnHistogramVeryQuicklyForTesting() { + RTC_DCHECK_RUN_ON(signaling_thread()); + return_histogram_very_quickly_ = true; + } + void RequestUsagePatternReportForTesting(); + + protected: + // Available for rtc::scoped_refptr creation + PeerConnection(rtc::scoped_refptr context, + const PeerConnectionFactoryInterface::Options& options, + bool is_unified_plan, + std::unique_ptr event_log, + std::unique_ptr call, + PeerConnectionDependencies& dependencies); + + ~PeerConnection() override; + + private: + bool Initialize( + const PeerConnectionInterface::RTCConfiguration& configuration, + PeerConnectionDependencies dependencies); - // Create a new RtpTransceiver of the given type and add it to the list of - // transceivers. rtc::scoped_refptr> - CreateAndAddTransceiver( - rtc::scoped_refptr> sender, - rtc::scoped_refptr> - receiver) RTC_RUN_ON(signaling_thread()); - - void SetIceConnectionState(IceConnectionState new_state) + FindTransceiverBySender(rtc::scoped_refptr sender) RTC_RUN_ON(signaling_thread()); + void SetStandardizedIceConnectionState( PeerConnectionInterface::IceConnectionState new_state) RTC_RUN_ON(signaling_thread()); @@ -549,304 +496,9 @@ class PeerConnection : public PeerConnectionInternal, const cricket::CandidatePairChangeEvent& event) RTC_RUN_ON(signaling_thread()); - // Update the state, signaling if necessary. - void ChangeSignalingState(SignalingState signaling_state) - RTC_RUN_ON(signaling_thread()); - - // Signals from MediaStreamObserver. - void OnAudioTrackAdded(AudioTrackInterface* track, - MediaStreamInterface* stream) - RTC_RUN_ON(signaling_thread()); - void OnAudioTrackRemoved(AudioTrackInterface* track, - MediaStreamInterface* stream) - RTC_RUN_ON(signaling_thread()); - void OnVideoTrackAdded(VideoTrackInterface* track, - MediaStreamInterface* stream) - RTC_RUN_ON(signaling_thread()); - void OnVideoTrackRemoved(VideoTrackInterface* track, - MediaStreamInterface* stream) - RTC_RUN_ON(signaling_thread()); - - void PostSetSessionDescriptionSuccess( - SetSessionDescriptionObserver* observer); - void PostSetSessionDescriptionFailure(SetSessionDescriptionObserver* observer, - RTCError&& error); - void PostCreateSessionDescriptionFailure( - CreateSessionDescriptionObserver* observer, - RTCError error); - - // Synchronous implementations of SetLocalDescription/SetRemoteDescription - // that return an RTCError instead of invoking a callback. - RTCError ApplyLocalDescription( - std::unique_ptr desc); - RTCError ApplyRemoteDescription( - std::unique_ptr desc); - - // Updates the local RtpTransceivers according to the JSEP rules. Called as - // part of setting the local/remote description. - RTCError UpdateTransceiversAndDataChannels( - cricket::ContentSource source, - const SessionDescriptionInterface& new_session, - const SessionDescriptionInterface* old_local_description, - const SessionDescriptionInterface* old_remote_description) - RTC_RUN_ON(signaling_thread()); - - // Either creates or destroys the transceiver's BaseChannel according to the - // given media section. - RTCError UpdateTransceiverChannel( - rtc::scoped_refptr> - transceiver, - const cricket::ContentInfo& content, - const cricket::ContentGroup* bundle_group) RTC_RUN_ON(signaling_thread()); - - // Either creates or destroys the local data channel according to the given - // media section. - RTCError UpdateDataChannel(cricket::ContentSource source, - const cricket::ContentInfo& content, - const cricket::ContentGroup* bundle_group) - RTC_RUN_ON(signaling_thread()); - - // Associate the given transceiver according to the JSEP rules. - RTCErrorOr< - rtc::scoped_refptr>> - AssociateTransceiver(cricket::ContentSource source, - SdpType type, - size_t mline_index, - const cricket::ContentInfo& content, - const cricket::ContentInfo* old_local_content, - const cricket::ContentInfo* old_remote_content) - RTC_RUN_ON(signaling_thread()); - - // Returns the RtpTransceiver, if found, that is associated to the given MID. - rtc::scoped_refptr> - GetAssociatedTransceiver(const std::string& mid) const - RTC_RUN_ON(signaling_thread()); - - // Returns the RtpTransceiver, if found, that was assigned to the given mline - // index in CreateOffer. - rtc::scoped_refptr> - GetTransceiverByMLineIndex(size_t mline_index) const - RTC_RUN_ON(signaling_thread()); - - // Returns an RtpTransciever, if available, that can be used to receive the - // given media type according to JSEP rules. - rtc::scoped_refptr> - FindAvailableTransceiverToReceive(cricket::MediaType media_type) const - RTC_RUN_ON(signaling_thread()); - - // Returns the media section in the given session description that is - // associated with the RtpTransceiver. Returns null if none found or this - // RtpTransceiver is not associated. Logic varies depending on the - // SdpSemantics specified in the configuration. - const cricket::ContentInfo* FindMediaSectionForTransceiver( - rtc::scoped_refptr> - transceiver, - const SessionDescriptionInterface* sdesc) const - RTC_RUN_ON(signaling_thread()); - - // Runs the algorithm **set the associated remote streams** specified in - // https://w3c.github.io/webrtc-pc/#set-associated-remote-streams. - void SetAssociatedRemoteStreams( - rtc::scoped_refptr receiver, - const std::vector& stream_ids, - std::vector>* added_streams, - std::vector>* removed_streams) - RTC_RUN_ON(signaling_thread()); - - // Runs the algorithm **process the removal of a remote track** specified in - // the WebRTC specification. - // This method will update the following lists: - // |remove_list| is the list of transceivers for which the receiving track is - // being removed. - // |removed_streams| is the list of streams which no longer have a receiving - // track so should be removed. - // https://w3c.github.io/webrtc-pc/#process-remote-track-removal - void ProcessRemovalOfRemoteTrack( - rtc::scoped_refptr> - transceiver, - std::vector>* remove_list, - std::vector>* removed_streams) - RTC_RUN_ON(signaling_thread()); - - void RemoveRemoteStreamsIfEmpty( - const std::vector>& - remote_streams, - std::vector>* removed_streams) - RTC_RUN_ON(signaling_thread()); void OnNegotiationNeeded(); - // Returns a MediaSessionOptions struct with options decided by |options|, - // the local MediaStreams and DataChannels. - void GetOptionsForOffer(const PeerConnectionInterface::RTCOfferAnswerOptions& - offer_answer_options, - cricket::MediaSessionOptions* session_options) - RTC_RUN_ON(signaling_thread()); - void GetOptionsForPlanBOffer( - const PeerConnectionInterface::RTCOfferAnswerOptions& - offer_answer_options, - cricket::MediaSessionOptions* session_options) - RTC_RUN_ON(signaling_thread()); - void GetOptionsForUnifiedPlanOffer( - const PeerConnectionInterface::RTCOfferAnswerOptions& - offer_answer_options, - cricket::MediaSessionOptions* session_options) - RTC_RUN_ON(signaling_thread()); - - RTCError HandleLegacyOfferOptions(const RTCOfferAnswerOptions& options) - RTC_RUN_ON(signaling_thread()); - void RemoveRecvDirectionFromReceivingTransceiversOfType( - cricket::MediaType media_type) RTC_RUN_ON(signaling_thread()); - void AddUpToOneReceivingTransceiverOfType(cricket::MediaType media_type); - std::vector< - rtc::scoped_refptr>> - GetReceivingTransceiversOfType(cricket::MediaType media_type) - RTC_RUN_ON(signaling_thread()); - - // Returns a MediaSessionOptions struct with options decided by - // |constraints|, the local MediaStreams and DataChannels. - void GetOptionsForAnswer(const RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options) - RTC_RUN_ON(signaling_thread()); - void GetOptionsForPlanBAnswer( - const PeerConnectionInterface::RTCOfferAnswerOptions& - offer_answer_options, - cricket::MediaSessionOptions* session_options) - RTC_RUN_ON(signaling_thread()); - void GetOptionsForUnifiedPlanAnswer( - const PeerConnectionInterface::RTCOfferAnswerOptions& - offer_answer_options, - cricket::MediaSessionOptions* session_options) - RTC_RUN_ON(signaling_thread()); - - // Generates MediaDescriptionOptions for the |session_opts| based on existing - // local description or remote description. - void GenerateMediaDescriptionOptions( - const SessionDescriptionInterface* session_desc, - RtpTransceiverDirection audio_direction, - RtpTransceiverDirection video_direction, - absl::optional* audio_index, - absl::optional* video_index, - absl::optional* data_index, - cricket::MediaSessionOptions* session_options) - RTC_RUN_ON(signaling_thread()); - - // Generates the active MediaDescriptionOptions for the local data channel - // given the specified MID. - cricket::MediaDescriptionOptions GetMediaDescriptionOptionsForActiveData( - const std::string& mid) const RTC_RUN_ON(signaling_thread()); - - // Generates the rejected MediaDescriptionOptions for the local data channel - // given the specified MID. - cricket::MediaDescriptionOptions GetMediaDescriptionOptionsForRejectedData( - const std::string& mid) const RTC_RUN_ON(signaling_thread()); - - // Returns the MID for the data section associated with either the - // RtpDataChannel or SCTP data channel, if it has been set. If no data - // channels are configured this will return nullopt. - absl::optional GetDataMid() const RTC_RUN_ON(signaling_thread()); - - // Remove all local and remote senders of type |media_type|. - // Called when a media type is rejected (m-line set to port 0). - void RemoveSenders(cricket::MediaType media_type) - RTC_RUN_ON(signaling_thread()); - - // Makes sure a MediaStreamTrack is created for each StreamParam in |streams|, - // and existing MediaStreamTracks are removed if there is no corresponding - // StreamParam. If |default_track_needed| is true, a default MediaStreamTrack - // is created if it doesn't exist; if false, it's removed if it exists. - // |media_type| is the type of the |streams| and can be either audio or video. - // If a new MediaStream is created it is added to |new_streams|. - void UpdateRemoteSendersList( - const std::vector& streams, - bool default_track_needed, - cricket::MediaType media_type, - StreamCollection* new_streams) RTC_RUN_ON(signaling_thread()); - - // Triggered when a remote sender has been seen for the first time in a remote - // session description. It creates a remote MediaStreamTrackInterface - // implementation and triggers CreateAudioReceiver or CreateVideoReceiver. - void OnRemoteSenderAdded(const RtpSenderInfo& sender_info, - cricket::MediaType media_type) - RTC_RUN_ON(signaling_thread()); - - // Triggered when a remote sender has been removed from a remote session - // description. It removes the remote sender with id |sender_id| from a remote - // MediaStream and triggers DestroyAudioReceiver or DestroyVideoReceiver. - void OnRemoteSenderRemoved(const RtpSenderInfo& sender_info, - cricket::MediaType media_type) - RTC_RUN_ON(signaling_thread()); - - // Finds remote MediaStreams without any tracks and removes them from - // |remote_streams_| and notifies the observer that the MediaStreams no longer - // exist. - void UpdateEndedRemoteMediaStreams() RTC_RUN_ON(signaling_thread()); - - // Loops through the vector of |streams| and finds added and removed - // StreamParams since last time this method was called. - // For each new or removed StreamParam, OnLocalSenderSeen or - // OnLocalSenderRemoved is invoked. - void UpdateLocalSenders(const std::vector& streams, - cricket::MediaType media_type) - RTC_RUN_ON(signaling_thread()); - - // Triggered when a local sender has been seen for the first time in a local - // session description. - // This method triggers CreateAudioSender or CreateVideoSender if the rtp - // streams in the local SessionDescription can be mapped to a MediaStreamTrack - // in a MediaStream in |local_streams_| - void OnLocalSenderAdded(const RtpSenderInfo& sender_info, - cricket::MediaType media_type) - RTC_RUN_ON(signaling_thread()); - - // Triggered when a local sender has been removed from a local session - // description. - // This method triggers DestroyAudioSender or DestroyVideoSender if a stream - // has been removed from the local SessionDescription and the stream can be - // mapped to a MediaStreamTrack in a MediaStream in |local_streams_|. - void OnLocalSenderRemoved(const RtpSenderInfo& sender_info, - cricket::MediaType media_type) - RTC_RUN_ON(signaling_thread()); - - // Returns true if the PeerConnection is configured to use Unified Plan - // semantics for creating offers/answers and setting local/remote - // descriptions. If this is true the RtpTransceiver API will also be available - // to the user. If this is false, Plan B semantics are assumed. - // TODO(bugs.webrtc.org/8530): Flip the default to be Unified Plan once - // sufficient time has passed. - bool IsUnifiedPlan() const RTC_RUN_ON(signaling_thread()) { - return configuration_.sdp_semantics == SdpSemantics::kUnifiedPlan; - } - - // The offer/answer machinery assumes the media section MID is present and - // unique. To support legacy end points that do not supply a=mid lines, this - // method will modify the session description to add MIDs generated according - // to the SDP semantics. - void FillInMissingRemoteMids(cricket::SessionDescription* remote_description) - RTC_RUN_ON(signaling_thread()); - - // Return the RtpSender with the given track attached. - rtc::scoped_refptr> - FindSenderForTrack(MediaStreamTrackInterface* track) const - RTC_RUN_ON(signaling_thread()); - - // Return the RtpSender with the given id, or null if none exists. - rtc::scoped_refptr> - FindSenderById(const std::string& sender_id) const - RTC_RUN_ON(signaling_thread()); - - // Return the RtpReceiver with the given id, or null if none exists. - rtc::scoped_refptr> - FindReceiverById(const std::string& receiver_id) const - RTC_RUN_ON(signaling_thread()); - - std::vector* GetRemoteSenderInfos( - cricket::MediaType media_type); - std::vector* GetLocalSenderInfos( - cricket::MediaType media_type); - const RtpSenderInfo* FindSenderInfo(const std::vector& infos, - const std::string& stream_id, - const std::string sender_id) const; // Returns the specified SCTP DataChannel in sctp_data_channels_, // or nullptr if not found. @@ -882,66 +534,6 @@ class PeerConnection : public PeerConnectionInternal, // This function should only be called from the worker thread. void StopRtcEventLog_w(); - // Ensures the configuration doesn't have any parameters with invalid values, - // or values that conflict with other parameters. - // - // Returns RTCError::OK() if there are no issues. - RTCError ValidateConfiguration(const RTCConfiguration& config) const; - - cricket::ChannelManager* channel_manager() const; - - enum class SessionError { - kNone, // No error. - kContent, // Error in BaseChannel SetLocalContent/SetRemoteContent. - kTransport, // Error from the underlying transport. - }; - - // Returns the last error in the session. See the enum above for details. - SessionError session_error() const RTC_RUN_ON(signaling_thread()) { - return session_error_; - } - const std::string& session_error_desc() const { return session_error_desc_; } - - cricket::ChannelInterface* GetChannel(const std::string& content_name); - - cricket::IceConfig ParseIceConfig( - const PeerConnectionInterface::RTCConfiguration& config) const; - - cricket::DataChannelType data_channel_type() const; - - // Called when an RTCCertificate is generated or retrieved by - // WebRTCSessionDescriptionFactory. Should happen before setLocalDescription. - void OnCertificateReady( - const rtc::scoped_refptr& certificate); - void OnDtlsSrtpSetupFailure(cricket::BaseChannel*, bool rtcp); - - // Non-const versions of local_description()/remote_description(), for use - // internally. - SessionDescriptionInterface* mutable_local_description() - RTC_RUN_ON(signaling_thread()) { - return pending_local_description_ ? pending_local_description_.get() - : current_local_description_.get(); - } - SessionDescriptionInterface* mutable_remote_description() - RTC_RUN_ON(signaling_thread()) { - return pending_remote_description_ ? pending_remote_description_.get() - : current_remote_description_.get(); - } - - // Updates the error state, signaling if necessary. - void SetSessionError(SessionError error, const std::string& error_desc); - - RTCError UpdateSessionState(SdpType type, - cricket::ContentSource source, - const cricket::SessionDescription* description); - // Push the media parts of the local or remote session description - // down to all of the channels. - RTCError PushdownMediaDescription(SdpType type, cricket::ContentSource source) - RTC_RUN_ON(signaling_thread()); - - RTCError PushdownTransportDescription(cricket::ContentSource source, - SdpType type); - // Returns true and the TransportInfo of the given |content_name| // from |description|. Returns false if it's not available. static bool GetTransportDescription( @@ -949,89 +541,12 @@ class PeerConnection : public PeerConnectionInternal, const std::string& content_name, cricket::TransportDescription* info); - // Enables media channels to allow sending of media. - // This enables media to flow on all configured audio/video channels and the - // RtpDataChannel. - void EnableSending() RTC_RUN_ON(signaling_thread()); - - // Destroys all BaseChannels and destroys the SCTP data channel, if present. - void DestroyAllChannels() RTC_RUN_ON(signaling_thread()); - // Returns the media index for a local ice candidate given the content name. // Returns false if the local session description does not have a media // content called |content_name|. bool GetLocalCandidateMediaIndex(const std::string& content_name, int* sdp_mline_index) RTC_RUN_ON(signaling_thread()); - // Uses all remote candidates in |remote_desc| in this session. - bool UseCandidatesInSessionDescription( - const SessionDescriptionInterface* remote_desc) - RTC_RUN_ON(signaling_thread()); - // Uses |candidate| in this session. - bool UseCandidate(const IceCandidateInterface* candidate) - RTC_RUN_ON(signaling_thread()); - RTCErrorOr FindContentInfo( - const SessionDescriptionInterface* description, - const IceCandidateInterface* candidate) RTC_RUN_ON(signaling_thread()); - // Deletes the corresponding channel of contents that don't exist in |desc|. - // |desc| can be null. This means that all channels are deleted. - void RemoveUnusedChannels(const cricket::SessionDescription* desc) - RTC_RUN_ON(signaling_thread()); - - // Allocates media channels based on the |desc|. If |desc| doesn't have - // the BUNDLE option, this method will disable BUNDLE in PortAllocator. - // This method will also delete any existing media channels before creating. - RTCError CreateChannels(const cricket::SessionDescription& desc) - RTC_RUN_ON(signaling_thread()); - - // If the BUNDLE policy is max-bundle, then we know for sure that all - // transports will be bundled from the start. This method returns the BUNDLE - // group if that's the case, or null if BUNDLE will be negotiated later. An - // error is returned if max-bundle is specified but the session description - // does not have a BUNDLE group. - RTCErrorOr GetEarlyBundleGroup( - const cricket::SessionDescription& desc) const - RTC_RUN_ON(signaling_thread()); - - // Helper methods to create media channels. - cricket::VoiceChannel* CreateVoiceChannel(const std::string& mid) - RTC_RUN_ON(signaling_thread()); - cricket::VideoChannel* CreateVideoChannel(const std::string& mid) - RTC_RUN_ON(signaling_thread()); - bool CreateDataChannel(const std::string& mid) RTC_RUN_ON(signaling_thread()); - - bool SetupDataChannelTransport_n(const std::string& mid) - RTC_RUN_ON(network_thread()); - void TeardownDataChannelTransport_n() RTC_RUN_ON(network_thread()); - - bool ValidateBundleSettings(const cricket::SessionDescription* desc); - bool HasRtcpMuxEnabled(const cricket::ContentInfo* content); - // Below methods are helper methods which verifies SDP. - RTCError ValidateSessionDescription(const SessionDescriptionInterface* sdesc, - cricket::ContentSource source) - RTC_RUN_ON(signaling_thread()); - - // Check if a call to SetLocalDescription is acceptable with a session - // description of the given type. - bool ExpectSetLocalDescription(SdpType type); - // Check if a call to SetRemoteDescription is acceptable with a session - // description of the given type. - bool ExpectSetRemoteDescription(SdpType type); - // Verifies a=setup attribute as per RFC 5763. - bool ValidateDtlsSetupAttribute(const cricket::SessionDescription* desc, - SdpType type); - - // Returns true if we are ready to push down the remote candidate. - // |remote_desc| is the new remote description, or NULL if the current remote - // description should be used. Output |valid| is true if the candidate media - // index is valid. - bool ReadyToUseRemoteCandidate(const IceCandidateInterface* candidate, - const SessionDescriptionInterface* remote_desc, - bool* valid) RTC_RUN_ON(signaling_thread()); - - // Returns true if SRTP (either using DTLS-SRTP or SDES) is required by - // this session. - bool SrtpRequired() const RTC_RUN_ON(signaling_thread()); // JsepTransportController signal handlers. void OnTransportControllerConnectionState(cricket::IceConnectionState state) @@ -1053,15 +568,7 @@ class PeerConnection : public PeerConnectionInternal, RTC_RUN_ON(signaling_thread()); void OnTransportControllerDtlsHandshakeError(rtc::SSLHandshakeError error); - const char* SessionErrorToString(SessionError error) const; - std::string GetSessionErrorMsg() RTC_RUN_ON(signaling_thread()); - - // Report the UMA metric SdpFormatReceived for the given remote offer. - void ReportSdpFormatReceived(const SessionDescriptionInterface& remote_offer); - - // Report inferred negotiated SDP semantics from a local/remote answer to the - // UMA observer. - void ReportNegotiatedSdpSemantics(const SessionDescriptionInterface& answer); + void OnErrorDemuxingPacket(uint32_t ssrc); // Invoked when TransportController connection completion is signaled. // Reports stats for all transports in use. @@ -1075,35 +582,9 @@ class PeerConnection : public PeerConnectionInternal, RTC_RUN_ON(signaling_thread()); void ReportIceCandidateCollected(const cricket::Candidate& candidate) RTC_RUN_ON(signaling_thread()); - void ReportRemoteIceCandidateAdded(const cricket::Candidate& candidate) - RTC_RUN_ON(signaling_thread()); - void NoteUsageEvent(UsageEvent event); void ReportUsagePattern() const RTC_RUN_ON(signaling_thread()); - void OnSentPacket_w(const rtc::SentPacket& sent_packet); - - const std::string GetTransportName(const std::string& content_name) - RTC_RUN_ON(signaling_thread()); - - // Functions for dealing with transports. - // Note that cricket code uses the term "channel" for what other code - // refers to as "transport". - - // Destroys and clears the BaseChannel associated with the given transceiver, - // if such channel is set. - void DestroyTransceiverChannel( - rtc::scoped_refptr> - transceiver); - - // Destroys the RTP data channel transport and/or the SCTP data channel - // transport and clears it. - void DestroyDataChannelTransport() RTC_RUN_ON(signaling_thread()); - - // Destroys the given ChannelInterface. - // The channel cannot be accessed after this method is called. - void DestroyChannelInterface(cricket::ChannelInterface* channel); - // JsepTransportController::Observer override. // // Called by |transport_controller_| when processing transport information @@ -1116,38 +597,17 @@ class PeerConnection : public PeerConnectionInternal, rtc::scoped_refptr dtls_transport, DataChannelTransportInterface* data_channel_transport) override; - // RtpSenderBase::SetStreamsObserver override. - void OnSetStreams() override; + std::function + InitializeRtcpCallback(); - // Returns the CryptoOptions for this PeerConnection. This will always - // return the RTCConfiguration.crypto_options if set and will only default - // back to the PeerConnectionFactory settings if nothing was set. - CryptoOptions GetCryptoOptions() RTC_RUN_ON(signaling_thread()); - - // Returns rtp transport, result can not be nullptr. - RtpTransportInternal* GetRtpTransport(const std::string& mid) - RTC_RUN_ON(signaling_thread()) { - auto rtp_transport = transport_controller_->GetRtpTransport(mid); - RTC_DCHECK(rtp_transport); - return rtp_transport; - } - - void UpdateNegotiationNeeded(); - bool CheckIfNegotiationIsNeeded(); - - // | sdp_type | is the type of the SDP that caused the rollback. - RTCError Rollback(SdpType sdp_type); - - // Storing the factory as a scoped reference pointer ensures that the memory - // in the PeerConnectionFactoryImpl remains available as long as the - // PeerConnection is running. It is passed to PeerConnection as a raw pointer. - // However, since the reference counting is done in the - // PeerConnectionFactoryInterface all instances created using the raw pointer - // will refer to the same reference count. - const rtc::scoped_refptr factory_; + const rtc::scoped_refptr context_; + const PeerConnectionFactoryInterface::Options options_; PeerConnectionObserver* observer_ RTC_GUARDED_BY(signaling_thread()) = nullptr; + const bool is_unified_plan_; + // The EventLog needs to outlive |call_| (and any other object that uses it). std::unique_ptr event_log_ RTC_GUARDED_BY(worker_thread()); @@ -1155,15 +615,6 @@ class PeerConnection : public PeerConnectionInternal, // pointer (but not touch the object) from any thread. RtcEventLog* const event_log_ptr_ RTC_PT_GUARDED_BY(worker_thread()); - // The operations chain is used by the offer/answer exchange methods to ensure - // they are executed in the right order. For example, if - // SetRemoteDescription() is invoked while CreateOffer() is still pending, the - // SRD operation will not start until CreateOffer() has completed. See - // https://w3c.github.io/webrtc-pc/#dfn-operations-chain. - rtc::scoped_refptr operations_chain_ - RTC_GUARDED_BY(signaling_thread()); - - SignalingState signaling_state_ RTC_GUARDED_BY(signaling_thread()) = kStable; IceConnectionState ice_connection_state_ RTC_GUARDED_BY(signaling_thread()) = kIceConnectionNew; PeerConnectionInterface::IceConnectionState standardized_ice_connection_state_ @@ -1178,101 +629,45 @@ class PeerConnection : public PeerConnectionInternal, // TODO(zstein): |async_resolver_factory_| can currently be nullptr if it // is not injected. It should be required once chromium supplies it. - std::unique_ptr async_resolver_factory_ + const std::unique_ptr async_resolver_factory_ RTC_GUARDED_BY(signaling_thread()); std::unique_ptr port_allocator_; // TODO(bugs.webrtc.org/9987): Accessed on both // signaling and network thread. - std::unique_ptr packet_socket_factory_; - std::unique_ptr + const std::unique_ptr ice_transport_factory_; // TODO(bugs.webrtc.org/9987): Accessed on the // signaling thread but the underlying raw // pointer is given to // |jsep_transport_controller_| and used on the // network thread. - std::unique_ptr - tls_cert_verifier_; // TODO(bugs.webrtc.org/9987): Accessed on both - // signaling and network thread. - - // One PeerConnection has only one RTCP CNAME. - // https://tools.ietf.org/html/draft-ietf-rtcweb-rtp-usage-26#section-4.9 - const std::string rtcp_cname_; - - // Streams added via AddStream. - const rtc::scoped_refptr local_streams_ - RTC_GUARDED_BY(signaling_thread()); - // Streams created as a result of SetRemoteDescription. - const rtc::scoped_refptr remote_streams_ - RTC_GUARDED_BY(signaling_thread()); - - std::vector> stream_observers_ - RTC_GUARDED_BY(signaling_thread()); - - // These lists store sender info seen in local/remote descriptions. - std::vector remote_audio_sender_infos_ - RTC_GUARDED_BY(signaling_thread()); - std::vector remote_video_sender_infos_ - RTC_GUARDED_BY(signaling_thread()); - std::vector local_audio_sender_infos_ - RTC_GUARDED_BY(signaling_thread()); - std::vector local_video_sender_infos_ - RTC_GUARDED_BY(signaling_thread()); - - bool remote_peer_supports_msid_ RTC_GUARDED_BY(signaling_thread()) = false; + const std::unique_ptr tls_cert_verifier_ + RTC_GUARDED_BY(network_thread()); // The unique_ptr belongs to the worker thread, but the Call object manages // its own thread safety. std::unique_ptr call_ RTC_GUARDED_BY(worker_thread()); - - rtc::AsyncInvoker rtcp_invoker_ RTC_GUARDED_BY(network_thread()); + std::unique_ptr call_safety_ + RTC_GUARDED_BY(worker_thread()); // Points to the same thing as `call_`. Since it's const, we may read the // pointer from any thread. + // TODO(bugs.webrtc.org/11992): Remove this workaround (and potential dangling + // pointer). Call* const call_ptr_; std::unique_ptr stats_ RTC_GUARDED_BY(signaling_thread()); // A pointer is passed to senders_ rtc::scoped_refptr stats_collector_ RTC_GUARDED_BY(signaling_thread()); - // Holds changes made to transceivers during applying descriptors for - // potential rollback. Gets cleared once signaling state goes to stable. - std::map>, - TransceiverStableState> - transceiver_stable_states_by_transceivers_; - // Used when rolling back RTP data channels. - bool have_pending_rtp_data_channel_ RTC_GUARDED_BY(signaling_thread()) = - false; - // Holds remote stream ids for transceivers from stable state. - std::map>, - std::vector> - remote_stream_ids_by_transceivers_; - std::vector< - rtc::scoped_refptr>> - transceivers_; // TODO(bugs.webrtc.org/9987): Accessed on both signaling - // and network thread. - // In Unified Plan, if we encounter remote SDP that does not contain an a=msid - // line we create and use a stream with a random ID for our receivers. This is - // to support legacy endpoints that do not support the a=msid attribute (as - // opposed to streamless tracks with "a=msid:-"). - rtc::scoped_refptr missing_msid_default_stream_ + rtc::scoped_refptr demuxing_observer_ RTC_GUARDED_BY(signaling_thread()); - // MIDs will be generated using this generator which will keep track of - // all the MIDs that have been seen over the life of the PeerConnection. - rtc::UniqueStringGenerator mid_generator_ RTC_GUARDED_BY(signaling_thread()); - - SessionError session_error_ RTC_GUARDED_BY(signaling_thread()) = - SessionError::kNone; - std::string session_error_desc_ RTC_GUARDED_BY(signaling_thread()); std::string session_id_ RTC_GUARDED_BY(signaling_thread()); std::unique_ptr transport_controller_; // TODO(bugs.webrtc.org/9987): Accessed on both // signaling and network thread. - std::unique_ptr - sctp_factory_; // TODO(bugs.webrtc.org/9987): Accessed on both - // signaling and network thread. // |sctp_mid_| is the content name (MID) in SDP. // Note: this is used as the data channel MID by both SCTP and data channel @@ -1284,58 +679,24 @@ class PeerConnection : public PeerConnectionInternal, absl::optional sctp_mid_s_ RTC_GUARDED_BY(signaling_thread()); absl::optional sctp_mid_n_ RTC_GUARDED_BY(network_thread()); - // Whether this peer is the caller. Set when the local description is applied. - absl::optional is_caller_ RTC_GUARDED_BY(signaling_thread()); + // The machinery for handling offers and answers. Const after initialization. + std::unique_ptr sdp_handler_ + RTC_GUARDED_BY(signaling_thread()); - - - std::unique_ptr current_local_description_ - RTC_GUARDED_BY(signaling_thread()); - std::unique_ptr pending_local_description_ - RTC_GUARDED_BY(signaling_thread()); - std::unique_ptr current_remote_description_ - RTC_GUARDED_BY(signaling_thread()); - std::unique_ptr pending_remote_description_ - RTC_GUARDED_BY(signaling_thread()); bool dtls_enabled_ RTC_GUARDED_BY(signaling_thread()) = false; - // List of content names for which the remote side triggered an ICE restart. - std::set pending_ice_restarts_ - RTC_GUARDED_BY(signaling_thread()); - - std::unique_ptr webrtc_session_desc_factory_ - RTC_GUARDED_BY(signaling_thread()); - - // Member variables for caching global options. - cricket::AudioOptions audio_options_ RTC_GUARDED_BY(signaling_thread()); - cricket::VideoOptions video_options_ RTC_GUARDED_BY(signaling_thread()); - - int usage_event_accumulator_ RTC_GUARDED_BY(signaling_thread()) = 0; + UsagePattern usage_pattern_ RTC_GUARDED_BY(signaling_thread()); bool return_histogram_very_quickly_ RTC_GUARDED_BY(signaling_thread()) = false; - // This object should be used to generate any SSRC that is not explicitly - // specified by the user (or by the remote party). - // The generator is not used directly, instead it is passed on to the - // channel manager and the session description factory. - rtc::UniqueRandomIdGenerator ssrc_generator_ - RTC_GUARDED_BY(signaling_thread()); - - // A video bitrate allocator factory. - // This can injected using the PeerConnectionDependencies, - // or else the CreateBuiltinVideoBitrateAllocatorFactory() will be called. - // Note that one can still choose to override this in a MediaEngine - // if one wants too. - std::unique_ptr - video_bitrate_allocator_factory_; - - std::unique_ptr - local_ice_credentials_to_replace_ RTC_GUARDED_BY(signaling_thread()); - bool is_negotiation_needed_ RTC_GUARDED_BY(signaling_thread()) = false; - DataChannelController data_channel_controller_; - rtc::WeakPtrFactory weak_ptr_factory_ - RTC_GUARDED_BY(signaling_thread()); + + // Machinery for handling messages posted to oneself + PeerConnectionMessageHandler message_handler_; + + // Administration of senders, receivers and transceivers + // Accessed on both signaling and network thread. Const after Initialize(). + std::unique_ptr rtp_manager_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_adaptation_integrationtest.cc b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_adaptation_integrationtest.cc new file mode 100644 index 000000000..71d054eb9 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_adaptation_integrationtest.cc @@ -0,0 +1,161 @@ +/* + * Copyright 2020 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 + +#include "api/audio_codecs/builtin_audio_decoder_factory.h" +#include "api/audio_codecs/builtin_audio_encoder_factory.h" +#include "api/rtp_parameters.h" +#include "api/scoped_refptr.h" +#include "call/adaptation/test/fake_resource.h" +#include "pc/test/fake_periodic_video_source.h" +#include "pc/test/fake_periodic_video_track_source.h" +#include "pc/test/peer_connection_test_wrapper.h" +#include "rtc_base/checks.h" +#include "rtc_base/gunit.h" +#include "rtc_base/ref_counted_object.h" +#include "rtc_base/thread.h" +#include "rtc_base/virtual_socket_server.h" +#include "test/gtest.h" + +namespace webrtc { + +const int64_t kDefaultTimeoutMs = 5000; + +struct TrackWithPeriodicSource { + rtc::scoped_refptr track; + rtc::scoped_refptr periodic_track_source; +}; + +// Performs an O/A exchange and waits until the signaling state is stable again. +void Negotiate(rtc::scoped_refptr caller, + rtc::scoped_refptr callee) { + // Wire up callbacks and listeners such that a full O/A is performed in + // response to CreateOffer(). + PeerConnectionTestWrapper::Connect(caller.get(), callee.get()); + caller->CreateOffer(PeerConnectionInterface::RTCOfferAnswerOptions()); + caller->WaitForNegotiation(); +} + +TrackWithPeriodicSource CreateTrackWithPeriodicSource( + rtc::scoped_refptr factory) { + FakePeriodicVideoSource::Config periodic_track_source_config; + periodic_track_source_config.frame_interval_ms = 100; + periodic_track_source_config.timestamp_offset_ms = rtc::TimeMillis(); + rtc::scoped_refptr periodic_track_source = + new rtc::RefCountedObject( + periodic_track_source_config, /* remote */ false); + TrackWithPeriodicSource track_with_source; + track_with_source.track = + factory->CreateVideoTrack("PeriodicTrack", periodic_track_source); + track_with_source.periodic_track_source = periodic_track_source; + return track_with_source; +} + +// Triggers overuse and obtains VideoSinkWants. Adaptation processing happens in +// parallel and this function makes no guarantee that the returnd VideoSinkWants +// have yet to reflect the overuse signal. Used together with EXPECT_TRUE_WAIT +// to "spam overuse until a change is observed". +rtc::VideoSinkWants TriggerOveruseAndGetSinkWants( + rtc::scoped_refptr fake_resource, + const FakePeriodicVideoSource& source) { + fake_resource->SetUsageState(ResourceUsageState::kOveruse); + return source.wants(); +} + +class PeerConnectionAdaptationIntegrationTest : public ::testing::Test { + public: + PeerConnectionAdaptationIntegrationTest() + : virtual_socket_server_(), + network_thread_(new rtc::Thread(&virtual_socket_server_)), + worker_thread_(rtc::Thread::Create()) { + RTC_CHECK(network_thread_->Start()); + RTC_CHECK(worker_thread_->Start()); + } + + rtc::scoped_refptr CreatePcWrapper( + const char* name) { + rtc::scoped_refptr pc_wrapper = + new rtc::RefCountedObject( + name, network_thread_.get(), worker_thread_.get()); + PeerConnectionInterface::RTCConfiguration config; + config.sdp_semantics = SdpSemantics::kUnifiedPlan; + EXPECT_TRUE(pc_wrapper->CreatePc(config, CreateBuiltinAudioEncoderFactory(), + CreateBuiltinAudioDecoderFactory())); + return pc_wrapper; + } + + protected: + rtc::VirtualSocketServer virtual_socket_server_; + std::unique_ptr network_thread_; + std::unique_ptr worker_thread_; +}; + +TEST_F(PeerConnectionAdaptationIntegrationTest, + ResouceInjectedAfterNegotiationCausesReductionInResolution) { + auto caller_wrapper = CreatePcWrapper("caller"); + auto caller = caller_wrapper->pc(); + auto callee_wrapper = CreatePcWrapper("callee"); + + // Adding a track and negotiating ensures that a VideoSendStream exists. + TrackWithPeriodicSource track_with_source = + CreateTrackWithPeriodicSource(caller_wrapper->pc_factory()); + auto sender = caller->AddTrack(track_with_source.track, {}).value(); + Negotiate(caller_wrapper, callee_wrapper); + // Prefer degrading resolution. + auto parameters = sender->GetParameters(); + parameters.degradation_preference = DegradationPreference::MAINTAIN_FRAMERATE; + sender->SetParameters(parameters); + + const auto& source = + track_with_source.periodic_track_source->fake_periodic_source(); + int pixel_count_before_overuse = source.wants().max_pixel_count; + + // Inject a fake resource and spam kOveruse until resolution becomes limited. + auto fake_resource = FakeResource::Create("FakeResource"); + caller->AddAdaptationResource(fake_resource); + EXPECT_TRUE_WAIT( + TriggerOveruseAndGetSinkWants(fake_resource, source).max_pixel_count < + pixel_count_before_overuse, + kDefaultTimeoutMs); +} + +TEST_F(PeerConnectionAdaptationIntegrationTest, + ResouceInjectedBeforeNegotiationCausesReductionInResolution) { + auto caller_wrapper = CreatePcWrapper("caller"); + auto caller = caller_wrapper->pc(); + auto callee_wrapper = CreatePcWrapper("callee"); + + // Inject a fake resource before adding any tracks or negotiating. + auto fake_resource = FakeResource::Create("FakeResource"); + caller->AddAdaptationResource(fake_resource); + + // Adding a track and negotiating ensures that a VideoSendStream exists. + TrackWithPeriodicSource track_with_source = + CreateTrackWithPeriodicSource(caller_wrapper->pc_factory()); + auto sender = caller->AddTrack(track_with_source.track, {}).value(); + Negotiate(caller_wrapper, callee_wrapper); + // Prefer degrading resolution. + auto parameters = sender->GetParameters(); + parameters.degradation_preference = DegradationPreference::MAINTAIN_FRAMERATE; + sender->SetParameters(parameters); + + const auto& source = + track_with_source.periodic_track_source->fake_periodic_source(); + int pixel_count_before_overuse = source.wants().max_pixel_count; + + // Spam kOveruse until resolution becomes limited. + EXPECT_TRUE_WAIT( + TriggerOveruseAndGetSinkWants(fake_resource, source).max_pixel_count < + pixel_count_before_overuse, + kDefaultTimeoutMs); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_factory.cc b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_factory.cc index d79e43815..da42e5a09 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_factory.cc @@ -12,23 +12,25 @@ #include #include +#include #include -#include #include "absl/strings/match.h" +#include "api/async_resolver_factory.h" +#include "api/call/call_factory_interface.h" #include "api/fec_controller.h" +#include "api/ice_transport_interface.h" #include "api/media_stream_proxy.h" #include "api/media_stream_track_proxy.h" #include "api/network_state_predictor.h" +#include "api/packet_socket_factory.h" #include "api/peer_connection_factory_proxy.h" #include "api/peer_connection_proxy.h" #include "api/rtc_event_log/rtc_event_log.h" -#include "api/transport/field_trial_based_config.h" -#include "api/turn_customizer.h" +#include "api/transport/bitrate_settings.h" #include "api/units/data_rate.h" -#include "api/video_track_source_proxy.h" -#include "media/base/rtp_data_engine.h" -#include "media/sctp/sctp_transport.h" +#include "call/audio_state.h" +#include "media/base/media_engine.h" #include "p2p/base/basic_async_resolver_factory.h" #include "p2p/base/basic_packet_socket_factory.h" #include "p2p/base/default_ice_transport_factory.h" @@ -38,12 +40,17 @@ #include "pc/media_stream.h" #include "pc/peer_connection.h" #include "pc/rtp_parameters_conversion.h" +#include "pc/session_description.h" #include "pc/video_track.h" #include "rtc_base/bind.h" #include "rtc_base/checks.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/field_trial_units.h" +#include "rtc_base/location.h" +#include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" +#include "rtc_base/ref_counted_object.h" +#include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/system/file_wrapper.h" namespace webrtc { @@ -51,183 +58,134 @@ namespace webrtc { rtc::scoped_refptr CreateModularPeerConnectionFactory( PeerConnectionFactoryDependencies dependencies) { - rtc::scoped_refptr pc_factory( - new rtc::RefCountedObject( - std::move(dependencies))); - // Call Initialize synchronously but make sure it is executed on - // |signaling_thread|. - MethodCall call( - pc_factory.get(), &PeerConnectionFactory::Initialize); - bool result = call.Marshal(RTC_FROM_HERE, pc_factory->signaling_thread()); + // The PeerConnectionFactory must be created on the signaling thread. + if (dependencies.signaling_thread && + !dependencies.signaling_thread->IsCurrent()) { + return dependencies.signaling_thread + ->Invoke>( + RTC_FROM_HERE, [&dependencies] { + return CreateModularPeerConnectionFactory( + std::move(dependencies)); + }); + } - if (!result) { + auto pc_factory = PeerConnectionFactory::Create(std::move(dependencies)); + if (!pc_factory) { return nullptr; } + // Verify that the invocation and the initialization ended up agreeing on the + // thread. + RTC_DCHECK_RUN_ON(pc_factory->signaling_thread()); return PeerConnectionFactoryProxy::Create(pc_factory->signaling_thread(), pc_factory); } +// Static +rtc::scoped_refptr PeerConnectionFactory::Create( + PeerConnectionFactoryDependencies dependencies) { + auto context = ConnectionContext::Create(&dependencies); + if (!context) { + return nullptr; + } + return new rtc::RefCountedObject(context, + &dependencies); +} + +PeerConnectionFactory::PeerConnectionFactory( + rtc::scoped_refptr context, + PeerConnectionFactoryDependencies* dependencies) + : context_(context), + task_queue_factory_(std::move(dependencies->task_queue_factory)), + event_log_factory_(std::move(dependencies->event_log_factory)), + fec_controller_factory_(std::move(dependencies->fec_controller_factory)), + network_state_predictor_factory_( + std::move(dependencies->network_state_predictor_factory)), + injected_network_controller_factory_( + std::move(dependencies->network_controller_factory)), + neteq_factory_(std::move(dependencies->neteq_factory)) {} + PeerConnectionFactory::PeerConnectionFactory( PeerConnectionFactoryDependencies dependencies) - : wraps_current_thread_(false), - network_thread_(dependencies.network_thread), - worker_thread_(dependencies.worker_thread), - signaling_thread_(dependencies.signaling_thread), - task_queue_factory_(std::move(dependencies.task_queue_factory)), - network_monitor_factory_(std::move(dependencies.network_monitor_factory)), - media_engine_(std::move(dependencies.media_engine)), - call_factory_(std::move(dependencies.call_factory)), - event_log_factory_(std::move(dependencies.event_log_factory)), - fec_controller_factory_(std::move(dependencies.fec_controller_factory)), - network_state_predictor_factory_( - std::move(dependencies.network_state_predictor_factory)), - injected_network_controller_factory_( - std::move(dependencies.network_controller_factory)), - neteq_factory_(std::move(dependencies.neteq_factory)), - trials_(dependencies.trials ? std::move(dependencies.trials) - : std::make_unique()) { - if (!network_thread_) { - owned_network_thread_ = rtc::Thread::CreateWithSocketServer(); - owned_network_thread_->SetName("pc_network_thread", nullptr); - owned_network_thread_->Start(); - network_thread_ = owned_network_thread_.get(); - } - - if (!worker_thread_) { - owned_worker_thread_ = rtc::Thread::Create(); - owned_worker_thread_->SetName("pc_worker_thread", nullptr); - owned_worker_thread_->Start(); - worker_thread_ = owned_worker_thread_.get(); - } - - if (!signaling_thread_) { - signaling_thread_ = rtc::Thread::Current(); - if (!signaling_thread_) { - // If this thread isn't already wrapped by an rtc::Thread, create a - // wrapper and own it in this class. - signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread(); - wraps_current_thread_ = true; - } - } - signaling_thread_->AllowInvokesToThread(worker_thread_); - signaling_thread_->AllowInvokesToThread(network_thread_); - worker_thread_->AllowInvokesToThread(network_thread_); - network_thread_->DisallowAllInvokes(); -} + : PeerConnectionFactory(ConnectionContext::Create(&dependencies), + &dependencies) {} PeerConnectionFactory::~PeerConnectionFactory() { - RTC_DCHECK(signaling_thread_->IsCurrent()); - channel_manager_.reset(nullptr); - - // Make sure |worker_thread_| and |signaling_thread_| outlive - // |default_socket_factory_| and |default_network_manager_|. - default_socket_factory_ = nullptr; - default_network_manager_ = nullptr; - - if (wraps_current_thread_) - rtc::ThreadManager::Instance()->UnwrapCurrentThread(); -} - -bool PeerConnectionFactory::Initialize() { - RTC_DCHECK(signaling_thread_->IsCurrent()); - rtc::InitRandom(rtc::Time32()); - - // If network_monitor_factory_ is non-null, it will be used to create a - // network monitor while on the network thread. - default_network_manager_.reset( - new rtc::BasicNetworkManager(network_monitor_factory_.get())); - if (!default_network_manager_) { - return false; - } - - default_socket_factory_.reset( - new rtc::BasicPacketSocketFactory(network_thread_)); - if (!default_socket_factory_) { - return false; - } - - channel_manager_ = std::make_unique( - std::move(media_engine_), std::make_unique(), - worker_thread_, network_thread_); - - channel_manager_->SetVideoRtxEnabled(true); - if (!channel_manager_->Init()) { - return false; - } - - return true; + RTC_DCHECK_RUN_ON(signaling_thread()); } void PeerConnectionFactory::SetOptions(const Options& options) { + RTC_DCHECK_RUN_ON(signaling_thread()); options_ = options; } RtpCapabilities PeerConnectionFactory::GetRtpSenderCapabilities( cricket::MediaType kind) const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(signaling_thread()); switch (kind) { case cricket::MEDIA_TYPE_AUDIO: { cricket::AudioCodecs cricket_codecs; - channel_manager_->GetSupportedAudioSendCodecs(&cricket_codecs); + channel_manager()->GetSupportedAudioSendCodecs(&cricket_codecs); return ToRtpCapabilities( cricket_codecs, - channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions()); + channel_manager()->GetDefaultEnabledAudioRtpHeaderExtensions()); } case cricket::MEDIA_TYPE_VIDEO: { cricket::VideoCodecs cricket_codecs; - channel_manager_->GetSupportedVideoSendCodecs(&cricket_codecs); + channel_manager()->GetSupportedVideoSendCodecs(&cricket_codecs); return ToRtpCapabilities( cricket_codecs, - channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions()); + channel_manager()->GetDefaultEnabledVideoRtpHeaderExtensions()); } case cricket::MEDIA_TYPE_DATA: return RtpCapabilities(); + case cricket::MEDIA_TYPE_UNSUPPORTED: + return RtpCapabilities(); } - // Not reached; avoids compile warning. - FATAL(); + RTC_CHECK_NOTREACHED(); } RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities( cricket::MediaType kind) const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(signaling_thread()); switch (kind) { case cricket::MEDIA_TYPE_AUDIO: { cricket::AudioCodecs cricket_codecs; - channel_manager_->GetSupportedAudioReceiveCodecs(&cricket_codecs); + channel_manager()->GetSupportedAudioReceiveCodecs(&cricket_codecs); return ToRtpCapabilities( cricket_codecs, - channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions()); + channel_manager()->GetDefaultEnabledAudioRtpHeaderExtensions()); } case cricket::MEDIA_TYPE_VIDEO: { cricket::VideoCodecs cricket_codecs; - channel_manager_->GetSupportedVideoReceiveCodecs(&cricket_codecs); + channel_manager()->GetSupportedVideoReceiveCodecs(&cricket_codecs); return ToRtpCapabilities( cricket_codecs, - channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions()); + channel_manager()->GetDefaultEnabledVideoRtpHeaderExtensions()); } case cricket::MEDIA_TYPE_DATA: return RtpCapabilities(); + case cricket::MEDIA_TYPE_UNSUPPORTED: + return RtpCapabilities(); } - // Not reached; avoids compile warning. - FATAL(); + RTC_CHECK_NOTREACHED(); } rtc::scoped_refptr PeerConnectionFactory::CreateAudioSource(const cricket::AudioOptions& options) { - RTC_DCHECK(signaling_thread_->IsCurrent()); + RTC_DCHECK(signaling_thread()->IsCurrent()); rtc::scoped_refptr source( LocalAudioSource::Create(&options)); return source; } bool PeerConnectionFactory::StartAecDump(FILE* file, int64_t max_size_bytes) { - RTC_DCHECK(signaling_thread_->IsCurrent()); - return channel_manager_->StartAecDump(FileWrapper(file), max_size_bytes); + RTC_DCHECK(signaling_thread()->IsCurrent()); + return channel_manager()->StartAecDump(FileWrapper(file), max_size_bytes); } void PeerConnectionFactory::StopAecDump() { - RTC_DCHECK(signaling_thread_->IsCurrent()); - channel_manager_->StopAecDump(); + RTC_DCHECK(signaling_thread()->IsCurrent()); + channel_manager()->StopAecDump(); } rtc::scoped_refptr @@ -248,7 +206,7 @@ rtc::scoped_refptr PeerConnectionFactory::CreatePeerConnection( const PeerConnectionInterface::RTCConfiguration& configuration, PeerConnectionDependencies dependencies) { - RTC_DCHECK(signaling_thread_->IsCurrent()); + RTC_DCHECK_RUN_ON(signaling_thread()); RTC_DCHECK(!(dependencies.allocator && dependencies.packet_socket_factory)) << "You can't set both allocator and packet_socket_factory; " "the former is going away (see bugs.webrtc.org/7447"; @@ -256,18 +214,18 @@ PeerConnectionFactory::CreatePeerConnection( // Set internal defaults if optional dependencies are not set. if (!dependencies.cert_generator) { dependencies.cert_generator = - std::make_unique(signaling_thread_, - network_thread_); + std::make_unique(signaling_thread(), + network_thread()); } if (!dependencies.allocator) { rtc::PacketSocketFactory* packet_socket_factory; if (dependencies.packet_socket_factory) packet_socket_factory = dependencies.packet_socket_factory.get(); else - packet_socket_factory = default_socket_factory_.get(); + packet_socket_factory = context_->default_socket_factory(); dependencies.allocator = std::make_unique( - default_network_manager_.get(), packet_socket_factory, + context_->default_network_manager(), packet_socket_factory, configuration.turn_customizer); } @@ -281,22 +239,21 @@ PeerConnectionFactory::CreatePeerConnection( std::make_unique(); } - dependencies.allocator->SetNetworkIgnoreMask(options_.network_ignore_mask); + dependencies.allocator->SetNetworkIgnoreMask(options().network_ignore_mask); std::unique_ptr event_log = - worker_thread_->Invoke>( + worker_thread()->Invoke>( RTC_FROM_HERE, rtc::Bind(&PeerConnectionFactory::CreateRtcEventLog_w, this)); - std::unique_ptr call = worker_thread_->Invoke>( + std::unique_ptr call = worker_thread()->Invoke>( RTC_FROM_HERE, rtc::Bind(&PeerConnectionFactory::CreateCall_w, this, event_log.get())); - rtc::scoped_refptr pc( - new rtc::RefCountedObject(this, std::move(event_log), - std::move(call))); - ActionsBeforeInitializeForTesting(pc); - if (!pc->Initialize(configuration, std::move(dependencies))) { + rtc::scoped_refptr pc = PeerConnection::Create( + context_, options_, std::move(event_log), std::move(call), configuration, + std::move(dependencies)); + if (!pc) { return nullptr; } return PeerConnectionProxy::Create(signaling_thread(), pc); @@ -304,43 +261,34 @@ PeerConnectionFactory::CreatePeerConnection( rtc::scoped_refptr PeerConnectionFactory::CreateLocalMediaStream(const std::string& stream_id) { - RTC_DCHECK(signaling_thread_->IsCurrent()); - return MediaStreamProxy::Create(signaling_thread_, + RTC_DCHECK(signaling_thread()->IsCurrent()); + return MediaStreamProxy::Create(signaling_thread(), MediaStream::Create(stream_id)); } rtc::scoped_refptr PeerConnectionFactory::CreateVideoTrack( const std::string& id, VideoTrackSourceInterface* source) { - RTC_DCHECK(signaling_thread_->IsCurrent()); + RTC_DCHECK(signaling_thread()->IsCurrent()); rtc::scoped_refptr track( - VideoTrack::Create(id, source, worker_thread_)); - return VideoTrackProxy::Create(signaling_thread_, worker_thread_, track); + VideoTrack::Create(id, source, worker_thread())); + return VideoTrackProxy::Create(signaling_thread(), worker_thread(), track); } rtc::scoped_refptr PeerConnectionFactory::CreateAudioTrack( const std::string& id, AudioSourceInterface* source) { - RTC_DCHECK(signaling_thread_->IsCurrent()); + RTC_DCHECK(signaling_thread()->IsCurrent()); rtc::scoped_refptr track(AudioTrack::Create(id, source)); - return AudioTrackProxy::Create(signaling_thread_, track); -} - -std::unique_ptr -PeerConnectionFactory::CreateSctpTransportInternalFactory() { -#ifdef HAVE_SCTP - return std::make_unique(network_thread()); -#else - return nullptr; -#endif + return AudioTrackProxy::Create(signaling_thread(), track); } cricket::ChannelManager* PeerConnectionFactory::channel_manager() { - return channel_manager_.get(); + return context_->channel_manager(); } std::unique_ptr PeerConnectionFactory::CreateRtcEventLog_w() { - RTC_DCHECK_RUN_ON(worker_thread_); + RTC_DCHECK_RUN_ON(worker_thread()); auto encoding_type = RtcEventLog::EncodingType::Legacy; if (IsTrialEnabled("WebRTC-RtcEventLogNewFormat")) @@ -352,14 +300,14 @@ std::unique_ptr PeerConnectionFactory::CreateRtcEventLog_w() { std::unique_ptr PeerConnectionFactory::CreateCall_w( RtcEventLog* event_log) { - RTC_DCHECK_RUN_ON(worker_thread_); + RTC_DCHECK_RUN_ON(worker_thread()); webrtc::Call::Config call_config(event_log); - if (!channel_manager_->media_engine() || !call_factory_) { + if (!channel_manager()->media_engine() || !context_->call_factory()) { return nullptr; } call_config.audio_state = - channel_manager_->media_engine()->voice().GetAudioState(); + channel_manager()->media_engine()->voice().GetAudioState(); FieldTrialParameter min_bandwidth("min", DataRate::KilobitsPerSec(30)); @@ -368,7 +316,7 @@ std::unique_ptr PeerConnectionFactory::CreateCall_w( FieldTrialParameter max_bandwidth("max", DataRate::KilobitsPerSec(2000)); ParseFieldTrial({&min_bandwidth, &start_bandwidth, &max_bandwidth}, - trials_->Lookup("WebRTC-PcFactoryDefaultBitrates")); + trials().Lookup("WebRTC-PcFactoryDefaultBitrates")); call_config.bitrate_config.min_bitrate_bps = rtc::saturated_cast(min_bandwidth->bps()); @@ -391,14 +339,14 @@ std::unique_ptr PeerConnectionFactory::CreateCall_w( RTC_LOG(LS_INFO) << "Using default network controller factory"; } - call_config.trials = trials_.get(); + call_config.trials = &trials(); - return std::unique_ptr(call_factory_->CreateCall(call_config)); + return std::unique_ptr( + context_->call_factory()->CreateCall(call_config)); } bool PeerConnectionFactory::IsTrialEnabled(absl::string_view key) const { - RTC_DCHECK(trials_); - return absl::StartsWith(trials_->Lookup(key), "Enabled"); + return absl::StartsWith(trials().Lookup(key), "Enabled"); } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_factory.h b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_factory.h index 3932562d2..427207f9c 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_factory.h +++ b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_factory.h @@ -12,14 +12,32 @@ #ifndef PC_PEER_CONNECTION_FACTORY_H_ #define PC_PEER_CONNECTION_FACTORY_H_ +#include +#include #include #include +#include "absl/strings/string_view.h" +#include "api/audio_options.h" +#include "api/fec_controller.h" #include "api/media_stream_interface.h" +#include "api/media_types.h" +#include "api/neteq/neteq_factory.h" +#include "api/network_state_predictor.h" #include "api/peer_connection_interface.h" +#include "api/rtc_event_log/rtc_event_log.h" +#include "api/rtc_event_log/rtc_event_log_factory_interface.h" +#include "api/rtp_parameters.h" #include "api/scoped_refptr.h" +#include "api/task_queue/task_queue_factory.h" +#include "api/transport/network_control.h" +#include "api/transport/sctp_transport_factory_interface.h" +#include "api/transport/webrtc_key_value_config.h" +#include "call/call.h" #include "media/sctp/sctp_transport_internal.h" +#include "p2p/base/port_allocator.h" #include "pc/channel_manager.h" +#include "pc/connection_context.h" #include "rtc_base/rtc_certificate_generator.h" #include "rtc_base/thread.h" @@ -34,6 +52,14 @@ class RtcEventLog; class PeerConnectionFactory : public PeerConnectionFactoryInterface { public: + // Creates a PeerConnectionFactory. It returns nullptr on initialization + // error. + // + // The Dependencies structure allows simple management of all new + // dependencies being added to the PeerConnectionFactory. + static rtc::scoped_refptr Create( + PeerConnectionFactoryDependencies dependencies); + void SetOptions(const Options& options) override; rtc::scoped_refptr CreatePeerConnection( @@ -46,8 +72,6 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface { const PeerConnectionInterface::RTCConfiguration& configuration, PeerConnectionDependencies dependencies) override; - bool Initialize(); - RtpCapabilities GetRtpSenderCapabilities( cricket::MediaType kind) const override; @@ -71,53 +95,53 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface { bool StartAecDump(FILE* file, int64_t max_size_bytes) override; void StopAecDump() override; - virtual std::unique_ptr - CreateSctpTransportInternalFactory(); + SctpTransportFactoryInterface* sctp_transport_factory() { + return context_->sctp_transport_factory(); + } virtual cricket::ChannelManager* channel_manager(); - rtc::Thread* signaling_thread() { + rtc::Thread* signaling_thread() const { // This method can be called on a different thread when the factory is // created in CreatePeerConnectionFactory(). - return signaling_thread_; + return context_->signaling_thread(); } - rtc::Thread* worker_thread() { return worker_thread_; } - rtc::Thread* network_thread() { return network_thread_; } - const Options& options() const { return options_; } + const Options& options() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return options_; + } + + const WebRtcKeyValueConfig& trials() const { return context_->trials(); } protected: - // This structure allows simple management of all new dependencies being added - // to the PeerConnectionFactory. + // Constructor used by the static Create() method. Modifies the dependencies. + PeerConnectionFactory(rtc::scoped_refptr context, + PeerConnectionFactoryDependencies* dependencies); + + // Constructor for use in testing. Ignores the possibility of initialization + // failure. The dependencies are passed in by std::move(). explicit PeerConnectionFactory( PeerConnectionFactoryDependencies dependencies); - // Hook to let testing framework insert actions between - // "new RTCPeerConnection" and "pc.Initialize" - virtual void ActionsBeforeInitializeForTesting(PeerConnectionInterface*) {} - virtual ~PeerConnectionFactory(); private: + rtc::Thread* worker_thread() const { return context_->worker_thread(); } + rtc::Thread* network_thread() const { return context_->network_thread(); } + bool IsTrialEnabled(absl::string_view key) const; + const cricket::ChannelManager* channel_manager() const { + return context_->channel_manager(); + } std::unique_ptr CreateRtcEventLog_w(); std::unique_ptr CreateCall_w(RtcEventLog* event_log); - bool wraps_current_thread_; - rtc::Thread* network_thread_; - rtc::Thread* worker_thread_; - rtc::Thread* signaling_thread_; - std::unique_ptr owned_network_thread_; - std::unique_ptr owned_worker_thread_; - const std::unique_ptr task_queue_factory_; - Options options_; - std::unique_ptr channel_manager_; - const std::unique_ptr network_monitor_factory_; - std::unique_ptr default_network_manager_; - std::unique_ptr default_socket_factory_; - std::unique_ptr media_engine_; - std::unique_ptr call_factory_; + rtc::scoped_refptr context_; + PeerConnectionFactoryInterface::Options options_ + RTC_GUARDED_BY(signaling_thread()); + std::unique_ptr task_queue_factory_; std::unique_ptr event_log_factory_; std::unique_ptr fec_controller_factory_; std::unique_ptr @@ -125,7 +149,6 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface { std::unique_ptr injected_network_controller_factory_; std::unique_ptr neteq_factory_; - const std::unique_ptr trials_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_integrationtest.cc b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_integrationtest.cc deleted file mode 100644 index dd24163f3..000000000 --- a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_integrationtest.cc +++ /dev/null @@ -1,5650 +0,0 @@ -/* - * Copyright 2012 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. - */ - -// Disable for TSan v2, see -// https://code.google.com/p/webrtc/issues/detail?id=1205 for details. -#if !defined(THREAD_SANITIZER) - -#include - -#include -#include -#include -#include -#include -#include - -#include "absl/algorithm/container.h" -#include "api/media_stream_interface.h" -#include "api/peer_connection_interface.h" -#include "api/peer_connection_proxy.h" -#include "api/rtc_event_log/rtc_event_log_factory.h" -#include "api/rtp_receiver_interface.h" -#include "api/task_queue/default_task_queue_factory.h" -#include "api/uma_metrics.h" -#include "api/video_codecs/sdp_video_format.h" -#include "call/call.h" -#include "logging/rtc_event_log/fake_rtc_event_log_factory.h" -#include "media/engine/fake_webrtc_video_engine.h" -#include "media/engine/webrtc_media_engine.h" -#include "media/engine/webrtc_media_engine_defaults.h" -#include "modules/audio_processing/test/audio_processing_builder_for_testing.h" -#include "p2p/base/fake_ice_transport.h" -#include "p2p/base/mock_async_resolver.h" -#include "p2p/base/p2p_constants.h" -#include "p2p/base/port_interface.h" -#include "p2p/base/test_stun_server.h" -#include "p2p/base/test_turn_customizer.h" -#include "p2p/base/test_turn_server.h" -#include "p2p/client/basic_port_allocator.h" -#include "pc/dtmf_sender.h" -#include "pc/local_audio_source.h" -#include "pc/media_session.h" -#include "pc/peer_connection.h" -#include "pc/peer_connection_factory.h" -#include "pc/rtp_media_utils.h" -#include "pc/session_description.h" -#include "pc/test/fake_audio_capture_module.h" -#include "pc/test/fake_periodic_video_track_source.h" -#include "pc/test/fake_rtc_certificate_generator.h" -#include "pc/test/fake_video_track_renderer.h" -#include "pc/test/mock_peer_connection_observers.h" -#include "rtc_base/fake_clock.h" -#include "rtc_base/fake_mdns_responder.h" -#include "rtc_base/fake_network.h" -#include "rtc_base/firewall_socket_server.h" -#include "rtc_base/gunit.h" -#include "rtc_base/numerics/safe_conversions.h" -#include "rtc_base/test_certificate_verifier.h" -#include "rtc_base/time_utils.h" -#include "rtc_base/virtual_socket_server.h" -#include "system_wrappers/include/metrics.h" -#include "test/field_trial.h" -#include "test/gmock.h" - -namespace webrtc { -namespace { - -using ::cricket::ContentInfo; -using ::cricket::StreamParams; -using ::rtc::SocketAddress; -using ::testing::_; -using ::testing::Combine; -using ::testing::Contains; -using ::testing::DoAll; -using ::testing::ElementsAre; -using ::testing::NiceMock; -using ::testing::Return; -using ::testing::SetArgPointee; -using ::testing::UnorderedElementsAreArray; -using ::testing::Values; -using RTCConfiguration = PeerConnectionInterface::RTCConfiguration; - -static const int kDefaultTimeout = 10000; -static const int kMaxWaitForStatsMs = 3000; -static const int kMaxWaitForActivationMs = 5000; -static const int kMaxWaitForFramesMs = 10000; -// Default number of audio/video frames to wait for before considering a test -// successful. -static const int kDefaultExpectedAudioFrameCount = 3; -static const int kDefaultExpectedVideoFrameCount = 3; - -static const char kDataChannelLabel[] = "data_channel"; - -// SRTP cipher name negotiated by the tests. This must be updated if the -// default changes. -static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_80; -static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM; - -static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0); - -// Helper function for constructing offer/answer options to initiate an ICE -// restart. -PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() { - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.ice_restart = true; - return options; -} - -// Remove all stream information (SSRCs, track IDs, etc.) and "msid-semantic" -// attribute from received SDP, simulating a legacy endpoint. -void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) { - for (ContentInfo& content : desc->contents()) { - content.media_description()->mutable_streams().clear(); - } - desc->set_msid_supported(false); - desc->set_msid_signaling(0); -} - -// Removes all stream information besides the stream ids, simulating an -// endpoint that only signals a=msid lines to convey stream_ids. -void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) { - for (ContentInfo& content : desc->contents()) { - std::string track_id; - std::vector stream_ids; - if (!content.media_description()->streams().empty()) { - const StreamParams& first_stream = - content.media_description()->streams()[0]; - track_id = first_stream.id; - stream_ids = first_stream.stream_ids(); - } - content.media_description()->mutable_streams().clear(); - StreamParams new_stream; - new_stream.id = track_id; - new_stream.set_stream_ids(stream_ids); - content.media_description()->AddStream(new_stream); - } -} - -int FindFirstMediaStatsIndexByKind( - const std::string& kind, - const std::vector& - media_stats_vec) { - for (size_t i = 0; i < media_stats_vec.size(); i++) { - if (media_stats_vec[i]->kind.ValueToString() == kind) { - return i; - } - } - return -1; -} - -class SignalingMessageReceiver { - public: - virtual void ReceiveSdpMessage(SdpType type, const std::string& msg) = 0; - virtual void ReceiveIceMessage(const std::string& sdp_mid, - int sdp_mline_index, - const std::string& msg) = 0; - - protected: - SignalingMessageReceiver() {} - virtual ~SignalingMessageReceiver() {} -}; - -class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface { - public: - explicit MockRtpReceiverObserver(cricket::MediaType media_type) - : expected_media_type_(media_type) {} - - void OnFirstPacketReceived(cricket::MediaType media_type) override { - ASSERT_EQ(expected_media_type_, media_type); - first_packet_received_ = true; - } - - bool first_packet_received() const { return first_packet_received_; } - - virtual ~MockRtpReceiverObserver() {} - - private: - bool first_packet_received_ = false; - cricket::MediaType expected_media_type_; -}; - -// Helper class that wraps a peer connection, observes it, and can accept -// signaling messages from another wrapper. -// -// Uses a fake network, fake A/V capture, and optionally fake -// encoders/decoders, though they aren't used by default since they don't -// advertise support of any codecs. -// TODO(steveanton): See how this could become a subclass of -// PeerConnectionWrapper defined in peerconnectionwrapper.h. -class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, - public SignalingMessageReceiver { - public: - // Different factory methods for convenience. - // TODO(deadbeef): Could use the pattern of: - // - // PeerConnectionWrapper = - // WrapperBuilder.WithConfig(...).WithOptions(...).build(); - // - // To reduce some code duplication. - static PeerConnectionWrapper* CreateWithDtlsIdentityStore( - const std::string& debug_name, - std::unique_ptr cert_generator, - rtc::Thread* network_thread, - rtc::Thread* worker_thread) { - PeerConnectionWrapper* client(new PeerConnectionWrapper(debug_name)); - webrtc::PeerConnectionDependencies dependencies(nullptr); - dependencies.cert_generator = std::move(cert_generator); - if (!client->Init(nullptr, nullptr, std::move(dependencies), network_thread, - worker_thread, nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false)) { - delete client; - return nullptr; - } - return client; - } - - webrtc::PeerConnectionFactoryInterface* pc_factory() const { - return peer_connection_factory_.get(); - } - - webrtc::PeerConnectionInterface* pc() const { return peer_connection_.get(); } - - // If a signaling message receiver is set (via ConnectFakeSignaling), this - // will set the whole offer/answer exchange in motion. Just need to wait for - // the signaling state to reach "stable". - void CreateAndSetAndSignalOffer() { - auto offer = CreateOfferAndWait(); - ASSERT_NE(nullptr, offer); - EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(offer))); - } - - // Sets the options to be used when CreateAndSetAndSignalOffer is called, or - // when a remote offer is received (via fake signaling) and an answer is - // generated. By default, uses default options. - void SetOfferAnswerOptions( - const PeerConnectionInterface::RTCOfferAnswerOptions& options) { - offer_answer_options_ = options; - } - - // Set a callback to be invoked when SDP is received via the fake signaling - // channel, which provides an opportunity to munge (modify) the SDP. This is - // used to test SDP being applied that a PeerConnection would normally not - // generate, but a non-JSEP endpoint might. - void SetReceivedSdpMunger( - std::function munger) { - received_sdp_munger_ = std::move(munger); - } - - // Similar to the above, but this is run on SDP immediately after it's - // generated. - void SetGeneratedSdpMunger( - std::function munger) { - generated_sdp_munger_ = std::move(munger); - } - - // Set a callback to be invoked when a remote offer is received via the fake - // signaling channel. This provides an opportunity to change the - // PeerConnection state before an answer is created and sent to the caller. - void SetRemoteOfferHandler(std::function handler) { - remote_offer_handler_ = std::move(handler); - } - - void SetRemoteAsyncResolver(rtc::MockAsyncResolver* resolver) { - remote_async_resolver_ = resolver; - } - - // Every ICE connection state in order that has been seen by the observer. - std::vector - ice_connection_state_history() const { - return ice_connection_state_history_; - } - void clear_ice_connection_state_history() { - ice_connection_state_history_.clear(); - } - - // Every standardized ICE connection state in order that has been seen by the - // observer. - std::vector - standardized_ice_connection_state_history() const { - return standardized_ice_connection_state_history_; - } - - // Every PeerConnection state in order that has been seen by the observer. - std::vector - peer_connection_state_history() const { - return peer_connection_state_history_; - } - - // Every ICE gathering state in order that has been seen by the observer. - std::vector - ice_gathering_state_history() const { - return ice_gathering_state_history_; - } - std::vector - ice_candidate_pair_change_history() const { - return ice_candidate_pair_change_history_; - } - - // Every PeerConnection signaling state in order that has been seen by the - // observer. - std::vector - peer_connection_signaling_state_history() const { - return peer_connection_signaling_state_history_; - } - - void AddAudioVideoTracks() { - AddAudioTrack(); - AddVideoTrack(); - } - - rtc::scoped_refptr AddAudioTrack() { - return AddTrack(CreateLocalAudioTrack()); - } - - rtc::scoped_refptr AddVideoTrack() { - return AddTrack(CreateLocalVideoTrack()); - } - - rtc::scoped_refptr CreateLocalAudioTrack() { - cricket::AudioOptions options; - // Disable highpass filter so that we can get all the test audio frames. - options.highpass_filter = false; - rtc::scoped_refptr source = - peer_connection_factory_->CreateAudioSource(options); - // TODO(perkj): Test audio source when it is implemented. Currently audio - // always use the default input. - return peer_connection_factory_->CreateAudioTrack(rtc::CreateRandomUuid(), - source); - } - - rtc::scoped_refptr CreateLocalVideoTrack() { - webrtc::FakePeriodicVideoSource::Config config; - config.timestamp_offset_ms = rtc::TimeMillis(); - return CreateLocalVideoTrackInternal(config); - } - - rtc::scoped_refptr - CreateLocalVideoTrackWithConfig( - webrtc::FakePeriodicVideoSource::Config config) { - return CreateLocalVideoTrackInternal(config); - } - - rtc::scoped_refptr - CreateLocalVideoTrackWithRotation(webrtc::VideoRotation rotation) { - webrtc::FakePeriodicVideoSource::Config config; - config.rotation = rotation; - config.timestamp_offset_ms = rtc::TimeMillis(); - return CreateLocalVideoTrackInternal(config); - } - - rtc::scoped_refptr AddTrack( - rtc::scoped_refptr track, - const std::vector& stream_ids = {}) { - auto result = pc()->AddTrack(track, stream_ids); - EXPECT_EQ(RTCErrorType::NONE, result.error().type()); - return result.MoveValue(); - } - - std::vector> GetReceiversOfType( - cricket::MediaType media_type) { - std::vector> receivers; - for (const auto& receiver : pc()->GetReceivers()) { - if (receiver->media_type() == media_type) { - receivers.push_back(receiver); - } - } - return receivers; - } - - rtc::scoped_refptr GetFirstTransceiverOfType( - cricket::MediaType media_type) { - for (auto transceiver : pc()->GetTransceivers()) { - if (transceiver->receiver()->media_type() == media_type) { - return transceiver; - } - } - return nullptr; - } - - bool SignalingStateStable() { - return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable; - } - - void CreateDataChannel() { CreateDataChannel(nullptr); } - - void CreateDataChannel(const webrtc::DataChannelInit* init) { - CreateDataChannel(kDataChannelLabel, init); - } - - void CreateDataChannel(const std::string& label, - const webrtc::DataChannelInit* init) { - data_channel_ = pc()->CreateDataChannel(label, init); - ASSERT_TRUE(data_channel_.get() != nullptr); - data_observer_.reset(new MockDataChannelObserver(data_channel_)); - } - - DataChannelInterface* data_channel() { return data_channel_; } - const MockDataChannelObserver* data_observer() const { - return data_observer_.get(); - } - - int audio_frames_received() const { - return fake_audio_capture_module_->frames_received(); - } - - // Takes minimum of video frames received for each track. - // - // Can be used like: - // EXPECT_GE(expected_frames, min_video_frames_received_per_track()); - // - // To ensure that all video tracks received at least a certain number of - // frames. - int min_video_frames_received_per_track() const { - int min_frames = INT_MAX; - if (fake_video_renderers_.empty()) { - return 0; - } - - for (const auto& pair : fake_video_renderers_) { - min_frames = std::min(min_frames, pair.second->num_rendered_frames()); - } - return min_frames; - } - - // Returns a MockStatsObserver in a state after stats gathering finished, - // which can be used to access the gathered stats. - rtc::scoped_refptr OldGetStatsForTrack( - webrtc::MediaStreamTrackInterface* track) { - rtc::scoped_refptr observer( - new rtc::RefCountedObject()); - EXPECT_TRUE(peer_connection_->GetStats( - observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); - EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout); - return observer; - } - - // Version that doesn't take a track "filter", and gathers all stats. - rtc::scoped_refptr OldGetStats() { - return OldGetStatsForTrack(nullptr); - } - - // Synchronously gets stats and returns them. If it times out, fails the test - // and returns null. - rtc::scoped_refptr NewGetStats() { - rtc::scoped_refptr callback( - new rtc::RefCountedObject()); - peer_connection_->GetStats(callback); - EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout); - return callback->report(); - } - - int rendered_width() { - EXPECT_FALSE(fake_video_renderers_.empty()); - return fake_video_renderers_.empty() - ? 0 - : fake_video_renderers_.begin()->second->width(); - } - - int rendered_height() { - EXPECT_FALSE(fake_video_renderers_.empty()); - return fake_video_renderers_.empty() - ? 0 - : fake_video_renderers_.begin()->second->height(); - } - - double rendered_aspect_ratio() { - if (rendered_height() == 0) { - return 0.0; - } - return static_cast(rendered_width()) / rendered_height(); - } - - webrtc::VideoRotation rendered_rotation() { - EXPECT_FALSE(fake_video_renderers_.empty()); - return fake_video_renderers_.empty() - ? webrtc::kVideoRotation_0 - : fake_video_renderers_.begin()->second->rotation(); - } - - int local_rendered_width() { - return local_video_renderer_ ? local_video_renderer_->width() : 0; - } - - int local_rendered_height() { - return local_video_renderer_ ? local_video_renderer_->height() : 0; - } - - double local_rendered_aspect_ratio() { - if (local_rendered_height() == 0) { - return 0.0; - } - return static_cast(local_rendered_width()) / - local_rendered_height(); - } - - size_t number_of_remote_streams() { - if (!pc()) { - return 0; - } - return pc()->remote_streams()->count(); - } - - StreamCollectionInterface* remote_streams() const { - if (!pc()) { - ADD_FAILURE(); - return nullptr; - } - return pc()->remote_streams(); - } - - StreamCollectionInterface* local_streams() { - if (!pc()) { - ADD_FAILURE(); - return nullptr; - } - return pc()->local_streams(); - } - - webrtc::PeerConnectionInterface::SignalingState signaling_state() { - return pc()->signaling_state(); - } - - webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() { - return pc()->ice_connection_state(); - } - - webrtc::PeerConnectionInterface::IceConnectionState - standardized_ice_connection_state() { - return pc()->standardized_ice_connection_state(); - } - - webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() { - return pc()->ice_gathering_state(); - } - - // Returns a MockRtpReceiverObserver for each RtpReceiver returned by - // GetReceivers. They're updated automatically when a remote offer/answer - // from the fake signaling channel is applied, or when - // ResetRtpReceiverObservers below is called. - const std::vector>& - rtp_receiver_observers() { - return rtp_receiver_observers_; - } - - void ResetRtpReceiverObservers() { - rtp_receiver_observers_.clear(); - for (const rtc::scoped_refptr& receiver : - pc()->GetReceivers()) { - std::unique_ptr observer( - new MockRtpReceiverObserver(receiver->media_type())); - receiver->SetObserver(observer.get()); - rtp_receiver_observers_.push_back(std::move(observer)); - } - } - - rtc::FakeNetworkManager* network_manager() const { - return fake_network_manager_.get(); - } - cricket::PortAllocator* port_allocator() const { return port_allocator_; } - - webrtc::FakeRtcEventLogFactory* event_log_factory() const { - return event_log_factory_; - } - - const cricket::Candidate& last_candidate_gathered() const { - return last_candidate_gathered_; - } - const cricket::IceCandidateErrorEvent& error_event() const { - return error_event_; - } - - // Sets the mDNS responder for the owned fake network manager and keeps a - // reference to the responder. - void SetMdnsResponder( - std::unique_ptr mdns_responder) { - RTC_DCHECK(mdns_responder != nullptr); - mdns_responder_ = mdns_responder.get(); - network_manager()->set_mdns_responder(std::move(mdns_responder)); - } - - // Returns null on failure. - std::unique_ptr CreateOfferAndWait() { - rtc::scoped_refptr observer( - new rtc::RefCountedObject()); - pc()->CreateOffer(observer, offer_answer_options_); - return WaitForDescriptionFromObserver(observer); - } - bool Rollback() { - return SetRemoteDescription( - webrtc::CreateSessionDescription(SdpType::kRollback, "")); - } - - private: - explicit PeerConnectionWrapper(const std::string& debug_name) - : debug_name_(debug_name) {} - - bool Init( - const PeerConnectionFactory::Options* options, - const PeerConnectionInterface::RTCConfiguration* config, - webrtc::PeerConnectionDependencies dependencies, - rtc::Thread* network_thread, - rtc::Thread* worker_thread, - std::unique_ptr event_log_factory, - bool reset_encoder_factory, - bool reset_decoder_factory) { - // There's an error in this test code if Init ends up being called twice. - RTC_DCHECK(!peer_connection_); - RTC_DCHECK(!peer_connection_factory_); - - fake_network_manager_.reset(new rtc::FakeNetworkManager()); - fake_network_manager_->AddInterface(kDefaultLocalAddress); - - std::unique_ptr port_allocator( - new cricket::BasicPortAllocator(fake_network_manager_.get())); - port_allocator_ = port_allocator.get(); - fake_audio_capture_module_ = FakeAudioCaptureModule::Create(); - if (!fake_audio_capture_module_) { - return false; - } - rtc::Thread* const signaling_thread = rtc::Thread::Current(); - - webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies; - pc_factory_dependencies.network_thread = network_thread; - pc_factory_dependencies.worker_thread = worker_thread; - pc_factory_dependencies.signaling_thread = signaling_thread; - pc_factory_dependencies.task_queue_factory = - webrtc::CreateDefaultTaskQueueFactory(); - cricket::MediaEngineDependencies media_deps; - media_deps.task_queue_factory = - pc_factory_dependencies.task_queue_factory.get(); - media_deps.adm = fake_audio_capture_module_; - webrtc::SetMediaEngineDefaults(&media_deps); - - if (reset_encoder_factory) { - media_deps.video_encoder_factory.reset(); - } - if (reset_decoder_factory) { - media_deps.video_decoder_factory.reset(); - } - - if (!media_deps.audio_processing) { - // If the standard Creation method for APM returns a null pointer, instead - // use the builder for testing to create an APM object. - media_deps.audio_processing = AudioProcessingBuilderForTesting().Create(); - } - - pc_factory_dependencies.media_engine = - cricket::CreateMediaEngine(std::move(media_deps)); - pc_factory_dependencies.call_factory = webrtc::CreateCallFactory(); - if (event_log_factory) { - event_log_factory_ = event_log_factory.get(); - pc_factory_dependencies.event_log_factory = std::move(event_log_factory); - } else { - pc_factory_dependencies.event_log_factory = - std::make_unique( - pc_factory_dependencies.task_queue_factory.get()); - } - peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory( - std::move(pc_factory_dependencies)); - - if (!peer_connection_factory_) { - return false; - } - if (options) { - peer_connection_factory_->SetOptions(*options); - } - if (config) { - sdp_semantics_ = config->sdp_semantics; - } - - dependencies.allocator = std::move(port_allocator); - peer_connection_ = CreatePeerConnection(config, std::move(dependencies)); - return peer_connection_.get() != nullptr; - } - - rtc::scoped_refptr CreatePeerConnection( - const PeerConnectionInterface::RTCConfiguration* config, - webrtc::PeerConnectionDependencies dependencies) { - PeerConnectionInterface::RTCConfiguration modified_config; - // If |config| is null, this will result in a default configuration being - // used. - if (config) { - modified_config = *config; - } - // Disable resolution adaptation; we don't want it interfering with the - // test results. - // TODO(deadbeef): Do something more robust. Since we're testing for aspect - // ratios and not specific resolutions, is this even necessary? - modified_config.set_cpu_adaptation(false); - - dependencies.observer = this; - return peer_connection_factory_->CreatePeerConnection( - modified_config, std::move(dependencies)); - } - - void set_signaling_message_receiver( - SignalingMessageReceiver* signaling_message_receiver) { - signaling_message_receiver_ = signaling_message_receiver; - } - - void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; } - - void set_signal_ice_candidates(bool signal) { - signal_ice_candidates_ = signal; - } - - rtc::scoped_refptr CreateLocalVideoTrackInternal( - webrtc::FakePeriodicVideoSource::Config config) { - // Set max frame rate to 10fps to reduce the risk of test flakiness. - // TODO(deadbeef): Do something more robust. - config.frame_interval_ms = 100; - - video_track_sources_.emplace_back( - new rtc::RefCountedObject( - config, false /* remote */)); - rtc::scoped_refptr track( - peer_connection_factory_->CreateVideoTrack( - rtc::CreateRandomUuid(), video_track_sources_.back())); - if (!local_video_renderer_) { - local_video_renderer_.reset(new webrtc::FakeVideoTrackRenderer(track)); - } - return track; - } - - void HandleIncomingOffer(const std::string& msg) { - RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingOffer"; - std::unique_ptr desc = - webrtc::CreateSessionDescription(SdpType::kOffer, msg); - if (received_sdp_munger_) { - received_sdp_munger_(desc->description()); - } - - EXPECT_TRUE(SetRemoteDescription(std::move(desc))); - // Setting a remote description may have changed the number of receivers, - // so reset the receiver observers. - ResetRtpReceiverObservers(); - if (remote_offer_handler_) { - remote_offer_handler_(); - } - auto answer = CreateAnswer(); - ASSERT_NE(nullptr, answer); - EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer))); - } - - void HandleIncomingAnswer(const std::string& msg) { - RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer"; - std::unique_ptr desc = - webrtc::CreateSessionDescription(SdpType::kAnswer, msg); - if (received_sdp_munger_) { - received_sdp_munger_(desc->description()); - } - - EXPECT_TRUE(SetRemoteDescription(std::move(desc))); - // Set the RtpReceiverObserver after receivers are created. - ResetRtpReceiverObservers(); - } - - // Returns null on failure. - std::unique_ptr CreateAnswer() { - rtc::scoped_refptr observer( - new rtc::RefCountedObject()); - pc()->CreateAnswer(observer, offer_answer_options_); - return WaitForDescriptionFromObserver(observer); - } - - std::unique_ptr WaitForDescriptionFromObserver( - MockCreateSessionDescriptionObserver* observer) { - EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout); - if (!observer->result()) { - return nullptr; - } - auto description = observer->MoveDescription(); - if (generated_sdp_munger_) { - generated_sdp_munger_(description->description()); - } - return description; - } - - // Setting the local description and sending the SDP message over the fake - // signaling channel are combined into the same method because the SDP - // message needs to be sent as soon as SetLocalDescription finishes, without - // waiting for the observer to be called. This ensures that ICE candidates - // don't outrace the description. - bool SetLocalDescriptionAndSendSdpMessage( - std::unique_ptr desc) { - rtc::scoped_refptr observer( - new rtc::RefCountedObject()); - RTC_LOG(LS_INFO) << debug_name_ << ": SetLocalDescriptionAndSendSdpMessage"; - SdpType type = desc->GetType(); - std::string sdp; - EXPECT_TRUE(desc->ToString(&sdp)); - RTC_LOG(LS_INFO) << debug_name_ << ": local SDP contents=\n" << sdp; - pc()->SetLocalDescription(observer, desc.release()); - RemoveUnusedVideoRenderers(); - // As mentioned above, we need to send the message immediately after - // SetLocalDescription. - SendSdpMessage(type, sdp); - EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout); - return true; - } - - bool SetRemoteDescription(std::unique_ptr desc) { - rtc::scoped_refptr observer( - new rtc::RefCountedObject()); - RTC_LOG(LS_INFO) << debug_name_ << ": SetRemoteDescription"; - pc()->SetRemoteDescription(observer, desc.release()); - RemoveUnusedVideoRenderers(); - EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout); - return observer->result(); - } - - // This is a work around to remove unused fake_video_renderers from - // transceivers that have either stopped or are no longer receiving. - void RemoveUnusedVideoRenderers() { - if (sdp_semantics_ != SdpSemantics::kUnifiedPlan) { - return; - } - auto transceivers = pc()->GetTransceivers(); - std::set active_renderers; - for (auto& transceiver : transceivers) { - // Note - we don't check for direction here. This function is called - // before direction is set, and in that case, we should not remove - // the renderer. - if (transceiver->receiver()->media_type() == cricket::MEDIA_TYPE_VIDEO) { - active_renderers.insert(transceiver->receiver()->track()->id()); - } - } - for (auto it = fake_video_renderers_.begin(); - it != fake_video_renderers_.end();) { - // Remove fake video renderers belonging to any non-active transceivers. - if (!active_renderers.count(it->first)) { - it = fake_video_renderers_.erase(it); - } else { - it++; - } - } - } - - // Simulate sending a blob of SDP with delay |signaling_delay_ms_| (0 by - // default). - void SendSdpMessage(SdpType type, const std::string& msg) { - if (signaling_delay_ms_ == 0) { - RelaySdpMessageIfReceiverExists(type, msg); - } else { - invoker_.AsyncInvokeDelayed( - RTC_FROM_HERE, rtc::Thread::Current(), - rtc::Bind(&PeerConnectionWrapper::RelaySdpMessageIfReceiverExists, - this, type, msg), - signaling_delay_ms_); - } - } - - void RelaySdpMessageIfReceiverExists(SdpType type, const std::string& msg) { - if (signaling_message_receiver_) { - signaling_message_receiver_->ReceiveSdpMessage(type, msg); - } - } - - // Simulate trickling an ICE candidate with delay |signaling_delay_ms_| (0 by - // default). - void SendIceMessage(const std::string& sdp_mid, - int sdp_mline_index, - const std::string& msg) { - if (signaling_delay_ms_ == 0) { - RelayIceMessageIfReceiverExists(sdp_mid, sdp_mline_index, msg); - } else { - invoker_.AsyncInvokeDelayed( - RTC_FROM_HERE, rtc::Thread::Current(), - rtc::Bind(&PeerConnectionWrapper::RelayIceMessageIfReceiverExists, - this, sdp_mid, sdp_mline_index, msg), - signaling_delay_ms_); - } - } - - void RelayIceMessageIfReceiverExists(const std::string& sdp_mid, - int sdp_mline_index, - const std::string& msg) { - if (signaling_message_receiver_) { - signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index, - msg); - } - } - - // SignalingMessageReceiver callbacks. - void ReceiveSdpMessage(SdpType type, const std::string& msg) override { - if (type == SdpType::kOffer) { - HandleIncomingOffer(msg); - } else { - HandleIncomingAnswer(msg); - } - } - - void ReceiveIceMessage(const std::string& sdp_mid, - int sdp_mline_index, - const std::string& msg) override { - RTC_LOG(LS_INFO) << debug_name_ << ": ReceiveIceMessage"; - std::unique_ptr candidate( - webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr)); - EXPECT_TRUE(pc()->AddIceCandidate(candidate.get())); - } - - // PeerConnectionObserver callbacks. - void OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState new_state) override { - EXPECT_EQ(pc()->signaling_state(), new_state); - peer_connection_signaling_state_history_.push_back(new_state); - } - void OnAddTrack(rtc::scoped_refptr receiver, - const std::vector>& - streams) override { - if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) { - rtc::scoped_refptr video_track( - static_cast(receiver->track().get())); - ASSERT_TRUE(fake_video_renderers_.find(video_track->id()) == - fake_video_renderers_.end()); - fake_video_renderers_[video_track->id()] = - std::make_unique(video_track); - } - } - void OnRemoveTrack( - rtc::scoped_refptr receiver) override { - if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) { - auto it = fake_video_renderers_.find(receiver->track()->id()); - if (it != fake_video_renderers_.end()) { - fake_video_renderers_.erase(it); - } else { - RTC_LOG(LS_ERROR) << "OnRemoveTrack called for non-active renderer"; - } - } - } - void OnRenegotiationNeeded() override {} - void OnIceConnectionChange( - webrtc::PeerConnectionInterface::IceConnectionState new_state) override { - EXPECT_EQ(pc()->ice_connection_state(), new_state); - ice_connection_state_history_.push_back(new_state); - } - void OnStandardizedIceConnectionChange( - webrtc::PeerConnectionInterface::IceConnectionState new_state) override { - standardized_ice_connection_state_history_.push_back(new_state); - } - void OnConnectionChange( - webrtc::PeerConnectionInterface::PeerConnectionState new_state) override { - peer_connection_state_history_.push_back(new_state); - } - - void OnIceGatheringChange( - webrtc::PeerConnectionInterface::IceGatheringState new_state) override { - EXPECT_EQ(pc()->ice_gathering_state(), new_state); - ice_gathering_state_history_.push_back(new_state); - } - - void OnIceSelectedCandidatePairChanged( - const cricket::CandidatePairChangeEvent& event) { - ice_candidate_pair_change_history_.push_back(event); - } - - void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override { - RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate"; - - if (remote_async_resolver_) { - const auto& local_candidate = candidate->candidate(); - if (local_candidate.address().IsUnresolvedIP()) { - RTC_DCHECK(local_candidate.type() == cricket::LOCAL_PORT_TYPE); - rtc::SocketAddress resolved_addr(local_candidate.address()); - const auto resolved_ip = mdns_responder_->GetMappedAddressForName( - local_candidate.address().hostname()); - RTC_DCHECK(!resolved_ip.IsNil()); - resolved_addr.SetResolvedIP(resolved_ip); - EXPECT_CALL(*remote_async_resolver_, GetResolvedAddress(_, _)) - .WillOnce(DoAll(SetArgPointee<1>(resolved_addr), Return(true))); - EXPECT_CALL(*remote_async_resolver_, Destroy(_)); - } - } - - std::string ice_sdp; - EXPECT_TRUE(candidate->ToString(&ice_sdp)); - if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) { - // Remote party may be deleted. - return; - } - SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp); - last_candidate_gathered_ = candidate->candidate(); - } - void OnIceCandidateError(const std::string& address, - int port, - const std::string& url, - int error_code, - const std::string& error_text) override { - error_event_ = cricket::IceCandidateErrorEvent(address, port, url, - error_code, error_text); - } - void OnDataChannel( - rtc::scoped_refptr data_channel) override { - RTC_LOG(LS_INFO) << debug_name_ << ": OnDataChannel"; - data_channel_ = data_channel; - data_observer_.reset(new MockDataChannelObserver(data_channel)); - } - - std::string debug_name_; - - std::unique_ptr fake_network_manager_; - // Reference to the mDNS responder owned by |fake_network_manager_| after set. - webrtc::FakeMdnsResponder* mdns_responder_ = nullptr; - - rtc::scoped_refptr peer_connection_; - rtc::scoped_refptr - peer_connection_factory_; - - cricket::PortAllocator* port_allocator_; - // Needed to keep track of number of frames sent. - rtc::scoped_refptr fake_audio_capture_module_; - // Needed to keep track of number of frames received. - std::map> - fake_video_renderers_; - // Needed to ensure frames aren't received for removed tracks. - std::vector> - removed_fake_video_renderers_; - - // For remote peer communication. - SignalingMessageReceiver* signaling_message_receiver_ = nullptr; - int signaling_delay_ms_ = 0; - bool signal_ice_candidates_ = true; - cricket::Candidate last_candidate_gathered_; - cricket::IceCandidateErrorEvent error_event_; - - // Store references to the video sources we've created, so that we can stop - // them, if required. - std::vector> - video_track_sources_; - // |local_video_renderer_| attached to the first created local video track. - std::unique_ptr local_video_renderer_; - - SdpSemantics sdp_semantics_; - PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options_; - std::function received_sdp_munger_; - std::function generated_sdp_munger_; - std::function remote_offer_handler_; - rtc::MockAsyncResolver* remote_async_resolver_ = nullptr; - rtc::scoped_refptr data_channel_; - std::unique_ptr data_observer_; - - std::vector> rtp_receiver_observers_; - - std::vector - ice_connection_state_history_; - std::vector - standardized_ice_connection_state_history_; - std::vector - peer_connection_state_history_; - std::vector - ice_gathering_state_history_; - std::vector - ice_candidate_pair_change_history_; - std::vector - peer_connection_signaling_state_history_; - webrtc::FakeRtcEventLogFactory* event_log_factory_; - - rtc::AsyncInvoker invoker_; - - friend class PeerConnectionIntegrationBaseTest; -}; - -class MockRtcEventLogOutput : public webrtc::RtcEventLogOutput { - public: - virtual ~MockRtcEventLogOutput() = default; - MOCK_METHOD(bool, IsActive, (), (const, override)); - MOCK_METHOD(bool, Write, (const std::string&), (override)); -}; - -// This helper object is used for both specifying how many audio/video frames -// are expected to be received for a caller/callee. It provides helper functions -// to specify these expectations. The object initially starts in a state of no -// expectations. -class MediaExpectations { - public: - enum ExpectFrames { - kExpectSomeFrames, - kExpectNoFrames, - kNoExpectation, - }; - - void ExpectBidirectionalAudioAndVideo() { - ExpectBidirectionalAudio(); - ExpectBidirectionalVideo(); - } - - void ExpectBidirectionalAudio() { - CallerExpectsSomeAudio(); - CalleeExpectsSomeAudio(); - } - - void ExpectNoAudio() { - CallerExpectsNoAudio(); - CalleeExpectsNoAudio(); - } - - void ExpectBidirectionalVideo() { - CallerExpectsSomeVideo(); - CalleeExpectsSomeVideo(); - } - - void ExpectNoVideo() { - CallerExpectsNoVideo(); - CalleeExpectsNoVideo(); - } - - void CallerExpectsSomeAudioAndVideo() { - CallerExpectsSomeAudio(); - CallerExpectsSomeVideo(); - } - - void CalleeExpectsSomeAudioAndVideo() { - CalleeExpectsSomeAudio(); - CalleeExpectsSomeVideo(); - } - - // Caller's audio functions. - void CallerExpectsSomeAudio( - int expected_audio_frames = kDefaultExpectedAudioFrameCount) { - caller_audio_expectation_ = kExpectSomeFrames; - caller_audio_frames_expected_ = expected_audio_frames; - } - - void CallerExpectsNoAudio() { - caller_audio_expectation_ = kExpectNoFrames; - caller_audio_frames_expected_ = 0; - } - - // Caller's video functions. - void CallerExpectsSomeVideo( - int expected_video_frames = kDefaultExpectedVideoFrameCount) { - caller_video_expectation_ = kExpectSomeFrames; - caller_video_frames_expected_ = expected_video_frames; - } - - void CallerExpectsNoVideo() { - caller_video_expectation_ = kExpectNoFrames; - caller_video_frames_expected_ = 0; - } - - // Callee's audio functions. - void CalleeExpectsSomeAudio( - int expected_audio_frames = kDefaultExpectedAudioFrameCount) { - callee_audio_expectation_ = kExpectSomeFrames; - callee_audio_frames_expected_ = expected_audio_frames; - } - - void CalleeExpectsNoAudio() { - callee_audio_expectation_ = kExpectNoFrames; - callee_audio_frames_expected_ = 0; - } - - // Callee's video functions. - void CalleeExpectsSomeVideo( - int expected_video_frames = kDefaultExpectedVideoFrameCount) { - callee_video_expectation_ = kExpectSomeFrames; - callee_video_frames_expected_ = expected_video_frames; - } - - void CalleeExpectsNoVideo() { - callee_video_expectation_ = kExpectNoFrames; - callee_video_frames_expected_ = 0; - } - - ExpectFrames caller_audio_expectation_ = kNoExpectation; - ExpectFrames caller_video_expectation_ = kNoExpectation; - ExpectFrames callee_audio_expectation_ = kNoExpectation; - ExpectFrames callee_video_expectation_ = kNoExpectation; - int caller_audio_frames_expected_ = 0; - int caller_video_frames_expected_ = 0; - int callee_audio_frames_expected_ = 0; - int callee_video_frames_expected_ = 0; -}; - -class MockIceTransport : public webrtc::IceTransportInterface { - public: - MockIceTransport(const std::string& name, int component) - : internal_(std::make_unique( - name, - component, - nullptr /* network_thread */)) {} - ~MockIceTransport() = default; - cricket::IceTransportInternal* internal() { return internal_.get(); } - - private: - std::unique_ptr internal_; -}; - -class MockIceTransportFactory : public IceTransportFactory { - public: - ~MockIceTransportFactory() override = default; - rtc::scoped_refptr CreateIceTransport( - const std::string& transport_name, - int component, - IceTransportInit init) { - RecordIceTransportCreated(); - return new rtc::RefCountedObject(transport_name, - component); - } - MOCK_METHOD(void, RecordIceTransportCreated, ()); -}; - -// Tests two PeerConnections connecting to each other end-to-end, using a -// virtual network, fake A/V capture and fake encoder/decoders. The -// PeerConnections share the threads/socket servers, but use separate versions -// of everything else (including "PeerConnectionFactory"s). -class PeerConnectionIntegrationBaseTest : public ::testing::Test { - public: - explicit PeerConnectionIntegrationBaseTest(SdpSemantics sdp_semantics) - : sdp_semantics_(sdp_semantics), - ss_(new rtc::VirtualSocketServer()), - fss_(new rtc::FirewallSocketServer(ss_.get())), - network_thread_(new rtc::Thread(fss_.get())), - worker_thread_(rtc::Thread::Create()) { - network_thread_->SetName("PCNetworkThread", this); - worker_thread_->SetName("PCWorkerThread", this); - RTC_CHECK(network_thread_->Start()); - RTC_CHECK(worker_thread_->Start()); - webrtc::metrics::Reset(); - } - - ~PeerConnectionIntegrationBaseTest() { - // The PeerConnections should deleted before the TurnCustomizers. - // A TurnPort is created with a raw pointer to a TurnCustomizer. The - // TurnPort has the same lifetime as the PeerConnection, so it's expected - // that the TurnCustomizer outlives the life of the PeerConnection or else - // when Send() is called it will hit a seg fault. - if (caller_) { - caller_->set_signaling_message_receiver(nullptr); - delete SetCallerPcWrapperAndReturnCurrent(nullptr); - } - if (callee_) { - callee_->set_signaling_message_receiver(nullptr); - delete SetCalleePcWrapperAndReturnCurrent(nullptr); - } - - // If turn servers were created for the test they need to be destroyed on - // the network thread. - network_thread()->Invoke(RTC_FROM_HERE, [this] { - turn_servers_.clear(); - turn_customizers_.clear(); - }); - } - - bool SignalingStateStable() { - return caller_->SignalingStateStable() && callee_->SignalingStateStable(); - } - - bool DtlsConnected() { - // TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS - // are connected. This is an important distinction. Once we have separate - // ICE and DTLS state, this check needs to use the DTLS state. - return (callee()->ice_connection_state() == - webrtc::PeerConnectionInterface::kIceConnectionConnected || - callee()->ice_connection_state() == - webrtc::PeerConnectionInterface::kIceConnectionCompleted) && - (caller()->ice_connection_state() == - webrtc::PeerConnectionInterface::kIceConnectionConnected || - caller()->ice_connection_state() == - webrtc::PeerConnectionInterface::kIceConnectionCompleted); - } - - // When |event_log_factory| is null, the default implementation of the event - // log factory will be used. - std::unique_ptr CreatePeerConnectionWrapper( - const std::string& debug_name, - const PeerConnectionFactory::Options* options, - const RTCConfiguration* config, - webrtc::PeerConnectionDependencies dependencies, - std::unique_ptr event_log_factory, - bool reset_encoder_factory, - bool reset_decoder_factory) { - RTCConfiguration modified_config; - if (config) { - modified_config = *config; - } - modified_config.sdp_semantics = sdp_semantics_; - if (!dependencies.cert_generator) { - dependencies.cert_generator = - std::make_unique(); - } - std::unique_ptr client( - new PeerConnectionWrapper(debug_name)); - - if (!client->Init(options, &modified_config, std::move(dependencies), - network_thread_.get(), worker_thread_.get(), - std::move(event_log_factory), reset_encoder_factory, - reset_decoder_factory)) { - return nullptr; - } - return client; - } - - std::unique_ptr - CreatePeerConnectionWrapperWithFakeRtcEventLog( - const std::string& debug_name, - const PeerConnectionFactory::Options* options, - const RTCConfiguration* config, - webrtc::PeerConnectionDependencies dependencies) { - std::unique_ptr event_log_factory( - new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current())); - return CreatePeerConnectionWrapper(debug_name, options, config, - std::move(dependencies), - std::move(event_log_factory), - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - } - - bool CreatePeerConnectionWrappers() { - return CreatePeerConnectionWrappersWithConfig( - PeerConnectionInterface::RTCConfiguration(), - PeerConnectionInterface::RTCConfiguration()); - } - - bool CreatePeerConnectionWrappersWithSdpSemantics( - SdpSemantics caller_semantics, - SdpSemantics callee_semantics) { - // Can't specify the sdp_semantics in the passed-in configuration since it - // will be overwritten by CreatePeerConnectionWrapper with whatever is - // stored in sdp_semantics_. So get around this by modifying the instance - // variable before calling CreatePeerConnectionWrapper for the caller and - // callee PeerConnections. - SdpSemantics original_semantics = sdp_semantics_; - sdp_semantics_ = caller_semantics; - caller_ = CreatePeerConnectionWrapper( - "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr), - nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - sdp_semantics_ = callee_semantics; - callee_ = CreatePeerConnectionWrapper( - "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr), - nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - sdp_semantics_ = original_semantics; - return caller_ && callee_; - } - - bool CreatePeerConnectionWrappersWithConfig( - const PeerConnectionInterface::RTCConfiguration& caller_config, - const PeerConnectionInterface::RTCConfiguration& callee_config) { - caller_ = CreatePeerConnectionWrapper( - "Caller", nullptr, &caller_config, - webrtc::PeerConnectionDependencies(nullptr), nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - callee_ = CreatePeerConnectionWrapper( - "Callee", nullptr, &callee_config, - webrtc::PeerConnectionDependencies(nullptr), nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - return caller_ && callee_; - } - - bool CreatePeerConnectionWrappersWithConfigAndDeps( - const PeerConnectionInterface::RTCConfiguration& caller_config, - webrtc::PeerConnectionDependencies caller_dependencies, - const PeerConnectionInterface::RTCConfiguration& callee_config, - webrtc::PeerConnectionDependencies callee_dependencies) { - caller_ = - CreatePeerConnectionWrapper("Caller", nullptr, &caller_config, - std::move(caller_dependencies), nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - callee_ = - CreatePeerConnectionWrapper("Callee", nullptr, &callee_config, - std::move(callee_dependencies), nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - return caller_ && callee_; - } - - bool CreatePeerConnectionWrappersWithOptions( - const PeerConnectionFactory::Options& caller_options, - const PeerConnectionFactory::Options& callee_options) { - caller_ = CreatePeerConnectionWrapper( - "Caller", &caller_options, nullptr, - webrtc::PeerConnectionDependencies(nullptr), nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - callee_ = CreatePeerConnectionWrapper( - "Callee", &callee_options, nullptr, - webrtc::PeerConnectionDependencies(nullptr), nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - return caller_ && callee_; - } - - bool CreatePeerConnectionWrappersWithFakeRtcEventLog() { - PeerConnectionInterface::RTCConfiguration default_config; - caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog( - "Caller", nullptr, &default_config, - webrtc::PeerConnectionDependencies(nullptr)); - callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog( - "Callee", nullptr, &default_config, - webrtc::PeerConnectionDependencies(nullptr)); - return caller_ && callee_; - } - - std::unique_ptr - CreatePeerConnectionWrapperWithAlternateKey() { - std::unique_ptr cert_generator( - new FakeRTCCertificateGenerator()); - cert_generator->use_alternate_key(); - - webrtc::PeerConnectionDependencies dependencies(nullptr); - dependencies.cert_generator = std::move(cert_generator); - return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr, - std::move(dependencies), nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - } - - bool CreateOneDirectionalPeerConnectionWrappers(bool caller_to_callee) { - caller_ = CreatePeerConnectionWrapper( - "Caller", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr), - nullptr, - /*reset_encoder_factory=*/!caller_to_callee, - /*reset_decoder_factory=*/caller_to_callee); - callee_ = CreatePeerConnectionWrapper( - "Callee", nullptr, nullptr, webrtc::PeerConnectionDependencies(nullptr), - nullptr, - /*reset_encoder_factory=*/caller_to_callee, - /*reset_decoder_factory=*/!caller_to_callee); - return caller_ && callee_; - } - - cricket::TestTurnServer* CreateTurnServer( - rtc::SocketAddress internal_address, - rtc::SocketAddress external_address, - cricket::ProtocolType type = cricket::ProtocolType::PROTO_UDP, - const std::string& common_name = "test turn server") { - rtc::Thread* thread = network_thread(); - std::unique_ptr turn_server = - network_thread()->Invoke>( - RTC_FROM_HERE, - [thread, internal_address, external_address, type, common_name] { - return std::make_unique( - thread, internal_address, external_address, type, - /*ignore_bad_certs=*/true, common_name); - }); - turn_servers_.push_back(std::move(turn_server)); - // Interactions with the turn server should be done on the network thread. - return turn_servers_.back().get(); - } - - cricket::TestTurnCustomizer* CreateTurnCustomizer() { - std::unique_ptr turn_customizer = - network_thread()->Invoke>( - RTC_FROM_HERE, - [] { return std::make_unique(); }); - turn_customizers_.push_back(std::move(turn_customizer)); - // Interactions with the turn customizer should be done on the network - // thread. - return turn_customizers_.back().get(); - } - - // Checks that the function counters for a TestTurnCustomizer are greater than - // 0. - void ExpectTurnCustomizerCountersIncremented( - cricket::TestTurnCustomizer* turn_customizer) { - unsigned int allow_channel_data_counter = - network_thread()->Invoke( - RTC_FROM_HERE, [turn_customizer] { - return turn_customizer->allow_channel_data_cnt_; - }); - EXPECT_GT(allow_channel_data_counter, 0u); - unsigned int modify_counter = network_thread()->Invoke( - RTC_FROM_HERE, - [turn_customizer] { return turn_customizer->modify_cnt_; }); - EXPECT_GT(modify_counter, 0u); - } - - // Once called, SDP blobs and ICE candidates will be automatically signaled - // between PeerConnections. - void ConnectFakeSignaling() { - caller_->set_signaling_message_receiver(callee_.get()); - callee_->set_signaling_message_receiver(caller_.get()); - } - - // Once called, SDP blobs will be automatically signaled between - // PeerConnections. Note that ICE candidates will not be signaled unless they - // are in the exchanged SDP blobs. - void ConnectFakeSignalingForSdpOnly() { - ConnectFakeSignaling(); - SetSignalIceCandidates(false); - } - - void SetSignalingDelayMs(int delay_ms) { - caller_->set_signaling_delay_ms(delay_ms); - callee_->set_signaling_delay_ms(delay_ms); - } - - void SetSignalIceCandidates(bool signal) { - caller_->set_signal_ice_candidates(signal); - callee_->set_signal_ice_candidates(signal); - } - - // Messages may get lost on the unreliable DataChannel, so we send multiple - // times to avoid test flakiness. - void SendRtpDataWithRetries(webrtc::DataChannelInterface* dc, - const std::string& data, - int retries) { - for (int i = 0; i < retries; ++i) { - dc->Send(DataBuffer(data)); - } - } - - rtc::Thread* network_thread() { return network_thread_.get(); } - - rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); } - - PeerConnectionWrapper* caller() { return caller_.get(); } - - // Set the |caller_| to the |wrapper| passed in and return the - // original |caller_|. - PeerConnectionWrapper* SetCallerPcWrapperAndReturnCurrent( - PeerConnectionWrapper* wrapper) { - PeerConnectionWrapper* old = caller_.release(); - caller_.reset(wrapper); - return old; - } - - PeerConnectionWrapper* callee() { return callee_.get(); } - - // Set the |callee_| to the |wrapper| passed in and return the - // original |callee_|. - PeerConnectionWrapper* SetCalleePcWrapperAndReturnCurrent( - PeerConnectionWrapper* wrapper) { - PeerConnectionWrapper* old = callee_.release(); - callee_.reset(wrapper); - return old; - } - - void SetPortAllocatorFlags(uint32_t caller_flags, uint32_t callee_flags) { - network_thread()->Invoke( - RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::set_flags, - caller()->port_allocator(), caller_flags)); - network_thread()->Invoke( - RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::set_flags, - callee()->port_allocator(), callee_flags)); - } - - rtc::FirewallSocketServer* firewall() const { return fss_.get(); } - - // Expects the provided number of new frames to be received within - // kMaxWaitForFramesMs. The new expected frames are specified in - // |media_expectations|. Returns false if any of the expectations were - // not met. - bool ExpectNewFrames(const MediaExpectations& media_expectations) { - // Make sure there are no bogus tracks confusing the issue. - caller()->RemoveUnusedVideoRenderers(); - callee()->RemoveUnusedVideoRenderers(); - // First initialize the expected frame counts based upon the current - // frame count. - int total_caller_audio_frames_expected = caller()->audio_frames_received(); - if (media_expectations.caller_audio_expectation_ == - MediaExpectations::kExpectSomeFrames) { - total_caller_audio_frames_expected += - media_expectations.caller_audio_frames_expected_; - } - int total_caller_video_frames_expected = - caller()->min_video_frames_received_per_track(); - if (media_expectations.caller_video_expectation_ == - MediaExpectations::kExpectSomeFrames) { - total_caller_video_frames_expected += - media_expectations.caller_video_frames_expected_; - } - int total_callee_audio_frames_expected = callee()->audio_frames_received(); - if (media_expectations.callee_audio_expectation_ == - MediaExpectations::kExpectSomeFrames) { - total_callee_audio_frames_expected += - media_expectations.callee_audio_frames_expected_; - } - int total_callee_video_frames_expected = - callee()->min_video_frames_received_per_track(); - if (media_expectations.callee_video_expectation_ == - MediaExpectations::kExpectSomeFrames) { - total_callee_video_frames_expected += - media_expectations.callee_video_frames_expected_; - } - - // Wait for the expected frames. - EXPECT_TRUE_WAIT(caller()->audio_frames_received() >= - total_caller_audio_frames_expected && - caller()->min_video_frames_received_per_track() >= - total_caller_video_frames_expected && - callee()->audio_frames_received() >= - total_callee_audio_frames_expected && - callee()->min_video_frames_received_per_track() >= - total_callee_video_frames_expected, - kMaxWaitForFramesMs); - bool expectations_correct = - caller()->audio_frames_received() >= - total_caller_audio_frames_expected && - caller()->min_video_frames_received_per_track() >= - total_caller_video_frames_expected && - callee()->audio_frames_received() >= - total_callee_audio_frames_expected && - callee()->min_video_frames_received_per_track() >= - total_callee_video_frames_expected; - - // After the combined wait, print out a more detailed message upon - // failure. - EXPECT_GE(caller()->audio_frames_received(), - total_caller_audio_frames_expected); - EXPECT_GE(caller()->min_video_frames_received_per_track(), - total_caller_video_frames_expected); - EXPECT_GE(callee()->audio_frames_received(), - total_callee_audio_frames_expected); - EXPECT_GE(callee()->min_video_frames_received_per_track(), - total_callee_video_frames_expected); - - // We want to make sure nothing unexpected was received. - if (media_expectations.caller_audio_expectation_ == - MediaExpectations::kExpectNoFrames) { - EXPECT_EQ(caller()->audio_frames_received(), - total_caller_audio_frames_expected); - if (caller()->audio_frames_received() != - total_caller_audio_frames_expected) { - expectations_correct = false; - } - } - if (media_expectations.caller_video_expectation_ == - MediaExpectations::kExpectNoFrames) { - EXPECT_EQ(caller()->min_video_frames_received_per_track(), - total_caller_video_frames_expected); - if (caller()->min_video_frames_received_per_track() != - total_caller_video_frames_expected) { - expectations_correct = false; - } - } - if (media_expectations.callee_audio_expectation_ == - MediaExpectations::kExpectNoFrames) { - EXPECT_EQ(callee()->audio_frames_received(), - total_callee_audio_frames_expected); - if (callee()->audio_frames_received() != - total_callee_audio_frames_expected) { - expectations_correct = false; - } - } - if (media_expectations.callee_video_expectation_ == - MediaExpectations::kExpectNoFrames) { - EXPECT_EQ(callee()->min_video_frames_received_per_track(), - total_callee_video_frames_expected); - if (callee()->min_video_frames_received_per_track() != - total_callee_video_frames_expected) { - expectations_correct = false; - } - } - return expectations_correct; - } - - void ClosePeerConnections() { - caller()->pc()->Close(); - callee()->pc()->Close(); - } - - void TestNegotiatedCipherSuite( - const PeerConnectionFactory::Options& caller_options, - const PeerConnectionFactory::Options& callee_options, - int expected_cipher_suite) { - ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options, - callee_options)); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); - EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(expected_cipher_suite), - caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout); - // TODO(bugs.webrtc.org/9456): Fix it. - EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents( - "WebRTC.PeerConnection.SrtpCryptoSuite.Audio", - expected_cipher_suite)); - } - - void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled, - bool remote_gcm_enabled, - bool aes_ctr_enabled, - int expected_cipher_suite) { - PeerConnectionFactory::Options caller_options; - caller_options.crypto_options.srtp.enable_gcm_crypto_suites = - local_gcm_enabled; - caller_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = - aes_ctr_enabled; - PeerConnectionFactory::Options callee_options; - callee_options.crypto_options.srtp.enable_gcm_crypto_suites = - remote_gcm_enabled; - callee_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = - aes_ctr_enabled; - TestNegotiatedCipherSuite(caller_options, callee_options, - expected_cipher_suite); - } - - protected: - SdpSemantics sdp_semantics_; - - private: - // |ss_| is used by |network_thread_| so it must be destroyed later. - std::unique_ptr ss_; - std::unique_ptr fss_; - // |network_thread_| and |worker_thread_| are used by both - // |caller_| and |callee_| so they must be destroyed - // later. - std::unique_ptr network_thread_; - std::unique_ptr worker_thread_; - // The turn servers and turn customizers should be accessed & deleted on the - // network thread to avoid a race with the socket read/write that occurs - // on the network thread. - std::vector> turn_servers_; - std::vector> turn_customizers_; - std::unique_ptr caller_; - std::unique_ptr callee_; -}; - -class PeerConnectionIntegrationTest - : public PeerConnectionIntegrationBaseTest, - public ::testing::WithParamInterface { - protected: - PeerConnectionIntegrationTest() - : PeerConnectionIntegrationBaseTest(GetParam()) {} -}; - -// Fake clock must be set before threads are started to prevent race on -// Set/GetClockForTesting(). -// To achieve that, multiple inheritance is used as a mixin pattern -// where order of construction is finely controlled. -// This also ensures peerconnection is closed before switching back to non-fake -// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc. -class FakeClockForTest : public rtc::ScopedFakeClock { - protected: - FakeClockForTest() { - // Some things use a time of "0" as a special value, so we need to start out - // the fake clock at a nonzero time. - // TODO(deadbeef): Fix this. - AdvanceTime(webrtc::TimeDelta::Seconds(1)); - } - - // Explicit handle. - ScopedFakeClock& FakeClock() { return *this; } -}; - -// Ensure FakeClockForTest is constructed first (see class for rationale). -class PeerConnectionIntegrationTestWithFakeClock - : public FakeClockForTest, - public PeerConnectionIntegrationTest {}; - -class PeerConnectionIntegrationTestPlanB - : public PeerConnectionIntegrationBaseTest { - protected: - PeerConnectionIntegrationTestPlanB() - : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {} -}; - -class PeerConnectionIntegrationTestUnifiedPlan - : public PeerConnectionIntegrationBaseTest { - protected: - PeerConnectionIntegrationTestUnifiedPlan() - : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {} -}; - -// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This -// includes testing that the callback is invoked if an observer is connected -// after the first packet has already been received. -TEST_P(PeerConnectionIntegrationTest, - RtpReceiverObserverOnFirstPacketReceived) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - // Start offer/answer exchange and wait for it to complete. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Should be one receiver each for audio/video. - EXPECT_EQ(2U, caller()->rtp_receiver_observers().size()); - EXPECT_EQ(2U, callee()->rtp_receiver_observers().size()); - // Wait for all "first packet received" callbacks to be fired. - EXPECT_TRUE_WAIT( - absl::c_all_of(caller()->rtp_receiver_observers(), - [](const std::unique_ptr& o) { - return o->first_packet_received(); - }), - kMaxWaitForFramesMs); - EXPECT_TRUE_WAIT( - absl::c_all_of(callee()->rtp_receiver_observers(), - [](const std::unique_ptr& o) { - return o->first_packet_received(); - }), - kMaxWaitForFramesMs); - // If new observers are set after the first packet was already received, the - // callback should still be invoked. - caller()->ResetRtpReceiverObservers(); - callee()->ResetRtpReceiverObservers(); - EXPECT_EQ(2U, caller()->rtp_receiver_observers().size()); - EXPECT_EQ(2U, callee()->rtp_receiver_observers().size()); - EXPECT_TRUE( - absl::c_all_of(caller()->rtp_receiver_observers(), - [](const std::unique_ptr& o) { - return o->first_packet_received(); - })); - EXPECT_TRUE( - absl::c_all_of(callee()->rtp_receiver_observers(), - [](const std::unique_ptr& o) { - return o->first_packet_received(); - })); -} - -class DummyDtmfObserver : public DtmfSenderObserverInterface { - public: - DummyDtmfObserver() : completed_(false) {} - - // Implements DtmfSenderObserverInterface. - void OnToneChange(const std::string& tone) override { - tones_.push_back(tone); - if (tone.empty()) { - completed_ = true; - } - } - - const std::vector& tones() const { return tones_; } - bool completed() const { return completed_; } - - private: - bool completed_; - std::vector tones_; -}; - -// Assumes |sender| already has an audio track added and the offer/answer -// exchange is done. -void TestDtmfFromSenderToReceiver(PeerConnectionWrapper* sender, - PeerConnectionWrapper* receiver) { - // We should be able to get a DTMF sender from the local sender. - rtc::scoped_refptr dtmf_sender = - sender->pc()->GetSenders().at(0)->GetDtmfSender(); - ASSERT_TRUE(dtmf_sender); - DummyDtmfObserver observer; - dtmf_sender->RegisterObserver(&observer); - - // Test the DtmfSender object just created. - EXPECT_TRUE(dtmf_sender->CanInsertDtmf()); - EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50)); - - EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout); - std::vector tones = {"1", "a", ""}; - EXPECT_EQ(tones, observer.tones()); - dtmf_sender->UnregisterObserver(); - // TODO(deadbeef): Verify the tones were actually received end-to-end. -} - -// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each -// direction). -TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Only need audio for DTMF. - caller()->AddAudioTrack(); - callee()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // DTLS must finish before the DTMF sender can be used reliably. - ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); - TestDtmfFromSenderToReceiver(caller(), callee()); - TestDtmfFromSenderToReceiver(callee(), caller()); -} - -// Basic end-to-end test, verifying media can be encoded/transmitted/decoded -// between two connections, using DTLS-SRTP. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - EXPECT_METRIC_LE( - 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol", - webrtc::kEnumCounterKeyProtocolDtls)); - EXPECT_METRIC_EQ( - 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol", - webrtc::kEnumCounterKeyProtocolSdes)); -} - -// Uses SDES instead of DTLS for key agreement. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) { - PeerConnectionInterface::RTCConfiguration sdes_config; - sdes_config.enable_dtls_srtp.emplace(false); - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config)); - ConnectFakeSignaling(); - - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - EXPECT_METRIC_LE( - 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol", - webrtc::kEnumCounterKeyProtocolSdes)); - EXPECT_METRIC_EQ( - 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol", - webrtc::kEnumCounterKeyProtocolDtls)); -} - -// Basic end-to-end test specifying the |enable_encrypted_rtp_header_extensions| -// option to offer encrypted versions of all header extensions alongside the -// unencrypted versions. -TEST_P(PeerConnectionIntegrationTest, - EndToEndCallWithEncryptedRtpHeaderExtensions) { - CryptoOptions crypto_options; - crypto_options.srtp.enable_encrypted_rtp_header_extensions = true; - PeerConnectionInterface::RTCConfiguration config; - config.crypto_options = crypto_options; - // Note: This allows offering >14 RTP header extensions. - config.offer_extmap_allow_mixed = true; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); - ConnectFakeSignaling(); - - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS -// certificate once the DTLS handshake has finished. -TEST_P(PeerConnectionIntegrationTest, - GetRemoteAudioSSLCertificateReturnsExchangedCertificate) { - auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) { - auto pci = reinterpret_cast(wrapper->pc()); - auto pc = reinterpret_cast(pci->internal()); - return pc->GetRemoteAudioSSLCertificate(); - }; - auto GetRemoteAudioSSLCertChain = [](PeerConnectionWrapper* wrapper) { - auto pci = reinterpret_cast(wrapper->pc()); - auto pc = reinterpret_cast(pci->internal()); - return pc->GetRemoteAudioSSLCertChain(); - }; - - auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]); - auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]); - - // Configure each side with a known certificate so they can be compared later. - PeerConnectionInterface::RTCConfiguration caller_config; - caller_config.enable_dtls_srtp.emplace(true); - caller_config.certificates.push_back(caller_cert); - PeerConnectionInterface::RTCConfiguration callee_config; - callee_config.enable_dtls_srtp.emplace(true); - callee_config.certificates.push_back(callee_cert); - ASSERT_TRUE( - CreatePeerConnectionWrappersWithConfig(caller_config, callee_config)); - ConnectFakeSignaling(); - - // When first initialized, there should not be a remote SSL certificate (and - // calling this method should not crash). - EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller())); - EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee())); - EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(caller())); - EXPECT_EQ(nullptr, GetRemoteAudioSSLCertChain(callee())); - - caller()->AddAudioTrack(); - callee()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); - - // Once DTLS has been connected, each side should return the other's SSL - // certificate when calling GetRemoteAudioSSLCertificate. - - auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller()); - ASSERT_TRUE(caller_remote_cert); - EXPECT_EQ(callee_cert->GetSSLCertificate().ToPEMString(), - caller_remote_cert->ToPEMString()); - - auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee()); - ASSERT_TRUE(callee_remote_cert); - EXPECT_EQ(caller_cert->GetSSLCertificate().ToPEMString(), - callee_remote_cert->ToPEMString()); - - auto caller_remote_cert_chain = GetRemoteAudioSSLCertChain(caller()); - ASSERT_TRUE(caller_remote_cert_chain); - ASSERT_EQ(1U, caller_remote_cert_chain->GetSize()); - auto remote_cert = &caller_remote_cert_chain->Get(0); - EXPECT_EQ(callee_cert->GetSSLCertificate().ToPEMString(), - remote_cert->ToPEMString()); - - auto callee_remote_cert_chain = GetRemoteAudioSSLCertChain(callee()); - ASSERT_TRUE(callee_remote_cert_chain); - ASSERT_EQ(1U, callee_remote_cert_chain->GetSize()); - remote_cert = &callee_remote_cert_chain->Get(0); - EXPECT_EQ(caller_cert->GetSSLCertificate().ToPEMString(), - remote_cert->ToPEMString()); -} - -// This test sets up a call between two parties with a source resolution of -// 1280x720 and verifies that a 16:9 aspect ratio is received. -TEST_P(PeerConnectionIntegrationTest, - Send1280By720ResolutionAndReceive16To9AspectRatio) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - // Add video tracks with 16:9 aspect ratio, size 1280 x 720. - webrtc::FakePeriodicVideoSource::Config config; - config.width = 1280; - config.height = 720; - config.timestamp_offset_ms = rtc::TimeMillis(); - caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config)); - callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config)); - - // Do normal offer/answer and wait for at least one frame to be received in - // each direction. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 && - callee()->min_video_frames_received_per_track() > 0, - kMaxWaitForFramesMs); - - // Check rendered aspect ratio. - EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio()); - EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio()); - EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio()); - EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio()); -} - -// This test sets up an one-way call, with media only from caller to -// callee. -TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudioAndVideo(); - media_expectations.CallerExpectsNoAudio(); - media_expectations.CallerExpectsNoVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Tests that send only works without the caller having a decoder factory and -// the callee having an encoder factory. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) { - ASSERT_TRUE( - CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true)); - ConnectFakeSignaling(); - // Add one-directional video, from caller to callee. - rtc::scoped_refptr caller_track = - caller()->CreateLocalVideoTrack(); - caller()->AddTrack(caller_track); - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_video = 0; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u); - - // Expect video to be received in one direction. - MediaExpectations media_expectations; - media_expectations.CallerExpectsNoVideo(); - media_expectations.CalleeExpectsSomeVideo(); - - EXPECT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Tests that receive only works without the caller having an encoder factory -// and the callee having a decoder factory. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) { - ASSERT_TRUE( - CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false)); - ConnectFakeSignaling(); - // Add one-directional video, from callee to caller. - rtc::scoped_refptr callee_track = - callee()->CreateLocalVideoTrack(); - callee()->AddTrack(callee_track); - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_video = 1; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u); - - // Expect video to be received in one direction. - MediaExpectations media_expectations; - media_expectations.CallerExpectsSomeVideo(); - media_expectations.CalleeExpectsNoVideo(); - - EXPECT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_P(PeerConnectionIntegrationTest, - EndToEndCallAddReceiveVideoToSendOnlyCall) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add one-directional video, from caller to callee. - rtc::scoped_refptr caller_track = - caller()->CreateLocalVideoTrack(); - caller()->AddTrack(caller_track); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Add receive video. - rtc::scoped_refptr callee_track = - callee()->CreateLocalVideoTrack(); - callee()->AddTrack(callee_track); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Ensure that video frames are received end-to-end. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_P(PeerConnectionIntegrationTest, - EndToEndCallAddSendVideoToReceiveOnlyCall) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add one-directional video, from callee to caller. - rtc::scoped_refptr callee_track = - callee()->CreateLocalVideoTrack(); - callee()->AddTrack(callee_track); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Add send video. - rtc::scoped_refptr caller_track = - caller()->CreateLocalVideoTrack(); - caller()->AddTrack(caller_track); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Expect video to be received in one direction. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_P(PeerConnectionIntegrationTest, - EndToEndCallRemoveReceiveVideoFromSendReceiveCall) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add send video, from caller to callee. - rtc::scoped_refptr caller_track = - caller()->CreateLocalVideoTrack(); - rtc::scoped_refptr caller_sender = - caller()->AddTrack(caller_track); - // Add receive video, from callee to caller. - rtc::scoped_refptr callee_track = - callee()->CreateLocalVideoTrack(); - - rtc::scoped_refptr callee_sender = - callee()->AddTrack(callee_track); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Remove receive video (i.e., callee sender track). - callee()->pc()->RemoveTrack(callee_sender); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Expect one-directional video. - MediaExpectations media_expectations; - media_expectations.CallerExpectsNoVideo(); - media_expectations.CalleeExpectsSomeVideo(); - - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_P(PeerConnectionIntegrationTest, - EndToEndCallRemoveSendVideoFromSendReceiveCall) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add send video, from caller to callee. - rtc::scoped_refptr caller_track = - caller()->CreateLocalVideoTrack(); - rtc::scoped_refptr caller_sender = - caller()->AddTrack(caller_track); - // Add receive video, from callee to caller. - rtc::scoped_refptr callee_track = - callee()->CreateLocalVideoTrack(); - - rtc::scoped_refptr callee_sender = - callee()->AddTrack(callee_track); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Remove send video (i.e., caller sender track). - caller()->pc()->RemoveTrack(caller_sender); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Expect one-directional video. - MediaExpectations media_expectations; - media_expectations.CalleeExpectsNoVideo(); - media_expectations.CallerExpectsSomeVideo(); - - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// This test sets up a audio call initially, with the callee rejecting video -// initially. Then later the callee decides to upgrade to audio/video, and -// initiates a new offer/answer exchange. -TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Initially, offer an audio/video stream from the caller, but refuse to - // send/receive video on the callee side. - caller()->AddAudioVideoTracks(); - callee()->AddAudioTrack(); - if (sdp_semantics_ == SdpSemantics::kPlanB) { - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_video = 0; - callee()->SetOfferAnswerOptions(options); - } else { - callee()->SetRemoteOfferHandler([this] { - callee() - ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO) - ->StopInternal(); - }); - } - // Do offer/answer and make sure audio is still received end-to-end. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - { - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudio(); - media_expectations.ExpectNoVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } - // Sanity check that the callee's description has a rejected video section. - ASSERT_NE(nullptr, callee()->pc()->local_description()); - const ContentInfo* callee_video_content = - GetFirstVideoContent(callee()->pc()->local_description()->description()); - ASSERT_NE(nullptr, callee_video_content); - EXPECT_TRUE(callee_video_content->rejected); - - // Now negotiate with video and ensure negotiation succeeds, with video - // frames and additional audio frames being received. - callee()->AddVideoTrack(); - if (sdp_semantics_ == SdpSemantics::kPlanB) { - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_video = 1; - callee()->SetOfferAnswerOptions(options); - } else { - callee()->SetRemoteOfferHandler(nullptr); - caller()->SetRemoteOfferHandler([this] { - // The caller creates a new transceiver to receive video on when receiving - // the offer, but by default it is send only. - auto transceivers = caller()->pc()->GetTransceivers(); - ASSERT_EQ(2U, transceivers.size()); - ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO, - transceivers[1]->receiver()->media_type()); - transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack()); - transceivers[1]->SetDirectionWithError( - RtpTransceiverDirection::kSendRecv); - }); - } - callee()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - { - // Expect additional audio frames to be received after the upgrade. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } -} - -// Simpler than the above test; just add an audio track to an established -// video-only connection. -TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Do initial offer/answer with just a video track. - caller()->AddVideoTrack(); - callee()->AddVideoTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Now add an audio track and do another offer/answer. - caller()->AddAudioTrack(); - callee()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Ensure both audio and video frames are received end-to-end. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// This test sets up a call that's transferred to a new caller with a different -// DTLS fingerprint. -TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Keep the original peer around which will still send packets to the - // receiving client. These SRTP packets will be dropped. - std::unique_ptr original_peer( - SetCallerPcWrapperAndReturnCurrent( - CreatePeerConnectionWrapperWithAlternateKey().release())); - // TODO(deadbeef): Why do we call Close here? That goes against the comment - // directly above. - original_peer->pc()->Close(); - - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Wait for some additional frames to be transmitted end-to-end. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// This test sets up a call that's transferred to a new callee with a different -// DTLS fingerprint. -TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Keep the original peer around which will still send packets to the - // receiving client. These SRTP packets will be dropped. - std::unique_ptr original_peer( - SetCalleePcWrapperAndReturnCurrent( - CreatePeerConnectionWrapperWithAlternateKey().release())); - // TODO(deadbeef): Why do we call Close here? That goes against the comment - // directly above. - original_peer->pc()->Close(); - - ConnectFakeSignaling(); - callee()->AddAudioVideoTracks(); - caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions()); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Wait for some additional frames to be transmitted end-to-end. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// This test sets up a non-bundled call and negotiates bundling at the same -// time as starting an ICE restart. When bundling is in effect in the restart, -// the DTLS-SRTP context should be successfully reset. -TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - // Remove the bundle group from the SDP received by the callee. - callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) { - desc->RemoveGroupByName("BUNDLE"); - }); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - { - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } - // Now stop removing the BUNDLE group, and trigger an ICE restart. - callee()->SetReceivedSdpMunger(nullptr); - caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions()); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Expect additional frames to be received after the ICE restart. - { - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } -} - -// Test CVO (Coordination of Video Orientation). If a video source is rotated -// and both peers support the CVO RTP header extension, the actual video frames -// don't need to be encoded in different resolutions, since the rotation is -// communicated through the RTP header extension. -TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add rotated video tracks. - caller()->AddTrack( - caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90)); - callee()->AddTrack( - callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270)); - - // Wait for video frames to be received by both sides. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 && - callee()->min_video_frames_received_per_track() > 0, - kMaxWaitForFramesMs); - - // Ensure that the aspect ratio is unmodified. - // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test, - // not just assumed. - EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio()); - EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio()); - EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio()); - EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio()); - // Ensure that the CVO bits were surfaced to the renderer. - EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation()); - EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation()); -} - -// Test that when the CVO extension isn't supported, video is rotated the -// old-fashioned way, by encoding rotated frames. -TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add rotated video tracks. - caller()->AddTrack( - caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90)); - callee()->AddTrack( - callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270)); - - // Remove the CVO extension from the offered SDP. - callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) { - cricket::VideoContentDescription* video = - GetFirstVideoContentDescription(desc); - video->ClearRtpHeaderExtensions(); - }); - // Wait for video frames to be received by both sides. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 && - callee()->min_video_frames_received_per_track() > 0, - kMaxWaitForFramesMs); - - // Expect that the aspect ratio is inversed to account for the 90/270 degree - // rotation. - // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test, - // not just assumed. - EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio()); - EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio()); - EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio()); - EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio()); - // Expect that each endpoint is unaware of the rotation of the other endpoint. - EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation()); - EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation()); -} - -// Test that if the answerer rejects the audio m= section, no audio is sent or -// received, but video still can be. -TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - if (sdp_semantics_ == SdpSemantics::kPlanB) { - // Only add video track for callee, and set offer_to_receive_audio to 0, so - // it will reject the audio m= section completely. - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_audio = 0; - callee()->SetOfferAnswerOptions(options); - } else { - // Stopping the audio RtpTransceiver will cause the media section to be - // rejected in the answer. - callee()->SetRemoteOfferHandler([this] { - callee() - ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO) - ->StopInternal(); - }); - } - callee()->AddTrack(callee()->CreateLocalVideoTrack()); - // Do offer/answer and wait for successful end-to-end video frames. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalVideo(); - media_expectations.ExpectNoAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - - // Sanity check that the callee's description has a rejected audio section. - ASSERT_NE(nullptr, callee()->pc()->local_description()); - const ContentInfo* callee_audio_content = - GetFirstAudioContent(callee()->pc()->local_description()->description()); - ASSERT_NE(nullptr, callee_audio_content); - EXPECT_TRUE(callee_audio_content->rejected); - if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) { - // The caller's transceiver should have stopped after receiving the answer, - // and thus no longer listed in transceivers. - EXPECT_EQ(nullptr, - caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)); - } -} - -// Test that if the answerer rejects the video m= section, no video is sent or -// received, but audio still can be. -TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - if (sdp_semantics_ == SdpSemantics::kPlanB) { - // Only add audio track for callee, and set offer_to_receive_video to 0, so - // it will reject the video m= section completely. - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_video = 0; - callee()->SetOfferAnswerOptions(options); - } else { - // Stopping the video RtpTransceiver will cause the media section to be - // rejected in the answer. - callee()->SetRemoteOfferHandler([this] { - callee() - ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO) - ->StopInternal(); - }); - } - callee()->AddTrack(callee()->CreateLocalAudioTrack()); - // Do offer/answer and wait for successful end-to-end audio frames. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudio(); - media_expectations.ExpectNoVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - - // Sanity check that the callee's description has a rejected video section. - ASSERT_NE(nullptr, callee()->pc()->local_description()); - const ContentInfo* callee_video_content = - GetFirstVideoContent(callee()->pc()->local_description()->description()); - ASSERT_NE(nullptr, callee_video_content); - EXPECT_TRUE(callee_video_content->rejected); - if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) { - // The caller's transceiver should have stopped after receiving the answer, - // and thus is no longer present. - EXPECT_EQ(nullptr, - caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)); - } -} - -// Test that if the answerer rejects both audio and video m= sections, nothing -// bad happens. -// TODO(deadbeef): Test that a data channel still works. Currently this doesn't -// test anything but the fact that negotiation succeeds, which doesn't mean -// much. -TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - if (sdp_semantics_ == SdpSemantics::kPlanB) { - // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it - // will reject both audio and video m= sections. - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_audio = 0; - options.offer_to_receive_video = 0; - callee()->SetOfferAnswerOptions(options); - } else { - callee()->SetRemoteOfferHandler([this] { - // Stopping all transceivers will cause all media sections to be rejected. - for (const auto& transceiver : callee()->pc()->GetTransceivers()) { - transceiver->StopInternal(); - } - }); - } - // Do offer/answer and wait for stable signaling state. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Sanity check that the callee's description has rejected m= sections. - ASSERT_NE(nullptr, callee()->pc()->local_description()); - const ContentInfo* callee_audio_content = - GetFirstAudioContent(callee()->pc()->local_description()->description()); - ASSERT_NE(nullptr, callee_audio_content); - EXPECT_TRUE(callee_audio_content->rejected); - const ContentInfo* callee_video_content = - GetFirstVideoContent(callee()->pc()->local_description()->description()); - ASSERT_NE(nullptr, callee_video_content); - EXPECT_TRUE(callee_video_content->rejected); -} - -// This test sets up an audio and video call between two parties. After the -// call runs for a while, the caller sends an updated offer with video being -// rejected. Once the re-negotiation is done, the video flow should stop and -// the audio flow should continue. -TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - { - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } - // Renegotiate, rejecting the video m= section. - if (sdp_semantics_ == SdpSemantics::kPlanB) { - caller()->SetGeneratedSdpMunger( - [](cricket::SessionDescription* description) { - for (cricket::ContentInfo& content : description->contents()) { - if (cricket::IsVideoContent(&content)) { - content.rejected = true; - } - } - }); - } else { - caller() - ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO) - ->StopInternal(); - } - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs); - - // Sanity check that the caller's description has a rejected video section. - ASSERT_NE(nullptr, caller()->pc()->local_description()); - const ContentInfo* caller_video_content = - GetFirstVideoContent(caller()->pc()->local_description()->description()); - ASSERT_NE(nullptr, caller_video_content); - EXPECT_TRUE(caller_video_content->rejected); - // Wait for some additional audio frames to be received. - { - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudio(); - media_expectations.ExpectNoVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } -} - -// Do one offer/answer with audio, another that disables it (rejecting the m= -// section), and another that re-enables it. Regression test for: -// bugs.webrtc.org/6023 -TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - // Add audio track, do normal offer/answer. - rtc::scoped_refptr track = - caller()->CreateLocalAudioTrack(); - rtc::scoped_refptr sender = - caller()->pc()->AddTrack(track, {"stream"}).MoveValue(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Remove audio track, and set offer_to_receive_audio to false to cause the - // m= section to be completely disabled, not just "recvonly". - caller()->pc()->RemoveTrack(sender); - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_audio = 0; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Add the audio track again, expecting negotiation to succeed and frames to - // flow. - sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue(); - options.offer_to_receive_audio = 1; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(); - EXPECT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Basic end-to-end test, but without SSRC/MSID signaling. This functionality -// is needed to support legacy endpoints. -// TODO(deadbeef): When we support the MID extension and demuxing on MID, also -// add a test for an end-to-end test without MID signaling either (basically, -// the minimum acceptable SDP). -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add audio and video, testing that packets can be demuxed on payload type. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - // Remove SSRCs and MSIDs from the received offer SDP. - callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Basic end-to-end test, without SSRC signaling. This means that the track -// was created properly and frames are delivered when the MSIDs are communicated -// with a=msid lines and no a=ssrc lines. -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - EndToEndCallWithoutSsrcSignaling) { - const char kStreamId[] = "streamId"; - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add just audio tracks. - caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId}); - callee()->AddAudioTrack(); - - // Remove SSRCs from the received offer SDP. - callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - EndToEndCallAddReceiveVideoToSendOnlyCall) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add one-directional video, from caller to callee. - rtc::scoped_refptr track = - caller()->CreateLocalVideoTrack(); - - RtpTransceiverInit video_transceiver_init; - video_transceiver_init.stream_ids = {"video1"}; - video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly; - auto video_sender = - caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Add receive direction. - video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv); - - rtc::scoped_refptr callee_track = - callee()->CreateLocalVideoTrack(); - - callee()->AddTrack(callee_track); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Ensure that video frames are received end-to-end. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Tests that video flows between multiple video tracks when SSRCs are not -// signaled. This exercises the MID RTP header extension which is needed to -// demux the incoming video tracks. -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddVideoTrack(); - caller()->AddVideoTrack(); - callee()->AddVideoTrack(); - callee()->AddVideoTrack(); - - caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids); - callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_EQ(2u, caller()->pc()->GetReceivers().size()); - ASSERT_EQ(2u, callee()->pc()->GetReceivers().size()); - - // Expect video to be received in both directions on both tracks. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalVideo(); - EXPECT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - caller()->AddVideoTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - auto callee_receivers = callee()->pc()->GetReceivers(); - ASSERT_EQ(2u, callee_receivers.size()); - EXPECT_TRUE(callee_receivers[0]->stream_ids().empty()); - EXPECT_TRUE(callee_receivers[1]->stream_ids().empty()); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - caller()->AddVideoTrack(); - callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - auto callee_receivers = callee()->pc()->GetReceivers(); - ASSERT_EQ(2u, callee_receivers.size()); - ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size()); - ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size()); - EXPECT_EQ(callee_receivers[0]->stream_ids()[0], - callee_receivers[1]->stream_ids()[0]); - EXPECT_EQ(callee_receivers[0]->streams()[0], - callee_receivers[1]->streams()[0]); -} - -// Test that if two video tracks are sent (from caller to callee, in this test), -// they're transmitted correctly end-to-end. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Add one audio/video stream, and one video-only stream. - caller()->AddAudioVideoTracks(); - caller()->AddVideoTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_EQ(3u, callee()->pc()->GetReceivers().size()); - - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) { - bool first = true; - for (cricket::ContentInfo& content : desc->contents()) { - if (first) { - first = false; - continue; - } - content.bundle_only = true; - } - first = true; - for (cricket::TransportInfo& transport : desc->transport_infos()) { - if (first) { - first = false; - continue; - } - transport.description.ice_ufrag.clear(); - transport.description.ice_pwd.clear(); - transport.description.connection_role = cricket::CONNECTIONROLE_NONE; - transport.description.identity_fingerprint.reset(nullptr); - } -} - -// Test that if applying a true "max bundle" offer, which uses ports of 0, -// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and -// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes -// successfully and media flows. -// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works. -// TODO(deadbeef): Won't need this test once we start generating actual -// standards-compliant SDP. -TEST_P(PeerConnectionIntegrationTest, - EndToEndCallWithSpecCompliantMaxBundleOffer) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - // Do the equivalent of setting the port to 0, adding a=bundle-only, and - // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all - // but the first m= section. - callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Test that we can receive the audio output level from a remote audio track. -// TODO(deadbeef): Use a fake audio source and verify that the output level is -// exactly what the source on the other side was configured with. -TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Just add an audio track. - caller()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Get the audio output level stats. Note that the level is not available - // until an RTCP packet has been received. - EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0, - kMaxWaitForFramesMs); -} - -// Test that an audio input level is reported. -// TODO(deadbeef): Use a fake audio source and verify that the input level is -// exactly what the source was configured with. -TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Just add an audio track. - caller()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Get the audio input level stats. The level should be available very - // soon after the test starts. - EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0, - kMaxWaitForStatsMs); -} - -// Test that we can get incoming byte counts from both audio and video tracks. -TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - // Do offer/answer, wait for the callee to receive some frames. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - - // Get a handle to the remote tracks created, so they can be used as GetStats - // filters. - for (const auto& receiver : callee()->pc()->GetReceivers()) { - // We received frames, so we definitely should have nonzero "received bytes" - // stats at this point. - EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(), - 0); - } -} - -// Test that we can get outgoing byte counts from both audio and video tracks. -TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - auto audio_track = caller()->CreateLocalAudioTrack(); - auto video_track = caller()->CreateLocalVideoTrack(); - caller()->AddTrack(audio_track); - caller()->AddTrack(video_track); - // Do offer/answer, wait for the callee to receive some frames. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - - // The callee received frames, so we definitely should have nonzero "sent - // bytes" stats at this point. - EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0); - EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0); -} - -// Test that we can get capture start ntp time. -TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - - callee()->AddAudioTrack(); - - // Do offer/answer, wait for the callee to receive some frames. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Get the remote audio track created on the receiver, so they can be used as - // GetStats filters. - auto receivers = callee()->pc()->GetReceivers(); - ASSERT_EQ(1u, receivers.size()); - auto remote_audio_track = receivers[0]->track(); - - // Get the audio output level stats. Note that the level is not available - // until an RTCP packet has been received. - EXPECT_TRUE_WAIT( - callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() > - 0, - 2 * kMaxWaitForFramesMs); -} - -// Test that the track ID is associated with all local and remote SSRC stats -// using the old GetStats() and more than 1 audio and more than 1 video track. -// This is a regression test for crbug.com/906988 -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - OldGetStatsAssociatesTrackIdForManyMediaSections) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - auto audio_sender_1 = caller()->AddAudioTrack(); - auto video_sender_1 = caller()->AddVideoTrack(); - auto audio_sender_2 = caller()->AddAudioTrack(); - auto video_sender_2 = caller()->AddVideoTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudioAndVideo(); - ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout); - - std::vector track_ids = { - audio_sender_1->track()->id(), video_sender_1->track()->id(), - audio_sender_2->track()->id(), video_sender_2->track()->id()}; - - auto caller_stats = caller()->OldGetStats(); - EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids)); - auto callee_stats = callee()->OldGetStats(); - EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids)); -} - -// Test that the new GetStats() returns stats for all outgoing/incoming streams -// with the correct track IDs if there are more than one audio and more than one -// video senders/receivers. -TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - auto audio_sender_1 = caller()->AddAudioTrack(); - auto video_sender_1 = caller()->AddVideoTrack(); - auto audio_sender_2 = caller()->AddAudioTrack(); - auto video_sender_2 = caller()->AddVideoTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudioAndVideo(); - ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout); - - std::vector track_ids = { - audio_sender_1->track()->id(), video_sender_1->track()->id(), - audio_sender_2->track()->id(), video_sender_2->track()->id()}; - - rtc::scoped_refptr caller_report = - caller()->NewGetStats(); - ASSERT_TRUE(caller_report); - auto outbound_stream_stats = - caller_report->GetStatsOfType(); - ASSERT_EQ(outbound_stream_stats.size(), 4u); - std::vector outbound_track_ids; - for (const auto& stat : outbound_stream_stats) { - ASSERT_TRUE(stat->bytes_sent.is_defined()); - EXPECT_LT(0u, *stat->bytes_sent); - if (*stat->kind == "video") { - ASSERT_TRUE(stat->key_frames_encoded.is_defined()); - EXPECT_GT(*stat->key_frames_encoded, 0u); - ASSERT_TRUE(stat->frames_encoded.is_defined()); - EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded); - } - ASSERT_TRUE(stat->track_id.is_defined()); - const auto* track_stat = - caller_report->GetAs(*stat->track_id); - ASSERT_TRUE(track_stat); - outbound_track_ids.push_back(*track_stat->track_identifier); - } - EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids)); - - rtc::scoped_refptr callee_report = - callee()->NewGetStats(); - ASSERT_TRUE(callee_report); - auto inbound_stream_stats = - callee_report->GetStatsOfType(); - ASSERT_EQ(4u, inbound_stream_stats.size()); - std::vector inbound_track_ids; - for (const auto& stat : inbound_stream_stats) { - ASSERT_TRUE(stat->bytes_received.is_defined()); - EXPECT_LT(0u, *stat->bytes_received); - if (*stat->kind == "video") { - ASSERT_TRUE(stat->key_frames_decoded.is_defined()); - EXPECT_GT(*stat->key_frames_decoded, 0u); - ASSERT_TRUE(stat->frames_decoded.is_defined()); - EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded); - } - ASSERT_TRUE(stat->track_id.is_defined()); - const auto* track_stat = - callee_report->GetAs(*stat->track_id); - ASSERT_TRUE(track_stat); - inbound_track_ids.push_back(*track_stat->track_identifier); - } - EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids)); -} - -// Test that we can get stats (using the new stats implementation) for -// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in -// SDP. -TEST_P(PeerConnectionIntegrationTest, - GetStatsForUnsignaledStreamWithNewStatsApi) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - // Remove SSRCs and MSIDs from the received offer SDP. - callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(1); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - - // We received a frame, so we should have nonzero "bytes received" stats for - // the unsignaled stream, if stats are working for it. - rtc::scoped_refptr report = - callee()->NewGetStats(); - ASSERT_NE(nullptr, report); - auto inbound_stream_stats = - report->GetStatsOfType(); - ASSERT_EQ(1U, inbound_stream_stats.size()); - ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined()); - ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U); - ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined()); -} - -// Same as above but for the legacy stats implementation. -TEST_P(PeerConnectionIntegrationTest, - GetStatsForUnsignaledStreamWithOldStatsApi) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - // Remove SSRCs and MSIDs from the received offer SDP. - callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Note that, since the old stats implementation associates SSRCs with tracks - // using SDP, when SSRCs aren't signaled in SDP these stats won't have an - // associated track ID. So we can't use the track "selector" argument. - // - // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to - // return cached stats if not enough time has passed since the last update. - EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0, - kDefaultTimeout); -} - -// Test that we can successfully get the media related stats (audio level -// etc.) for the unsignaled stream. -TEST_P(PeerConnectionIntegrationTest, - GetMediaStatsForUnsignaledStreamWithNewStatsApi) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - // Remove SSRCs and MSIDs from the received offer SDP. - callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(1); - media_expectations.CalleeExpectsSomeVideo(1); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - - rtc::scoped_refptr report = - callee()->NewGetStats(); - ASSERT_NE(nullptr, report); - - auto media_stats = report->GetStatsOfType(); - auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats); - ASSERT_GE(audio_index, 0); - EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined()); -} - -// Helper for test below. -void ModifySsrcs(cricket::SessionDescription* desc) { - for (ContentInfo& content : desc->contents()) { - for (StreamParams& stream : - content.media_description()->mutable_streams()) { - for (uint32_t& ssrc : stream.ssrcs) { - ssrc = rtc::CreateRandomId(); - } - } - } -} - -// Test that the "RTCMediaSteamTrackStats" object is updated correctly when -// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes. -// This should result in two "RTCInboundRTPStreamStats", but only one -// "RTCMediaStreamTrackStats", whose counters go up continuously rather than -// being reset to 0 once the SSRC change occurs. -// -// Regression test for this bug: -// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158 -// -// The bug causes the track stats to only represent one of the two streams: -// whichever one has the higher SSRC. So with this bug, there was a 50% chance -// that the track stat counters would reset to 0 when the new stream is -// received, and a 50% chance that they'll stop updating (while -// "concealed_samples" continues increasing, due to silence being generated for -// the inactive stream). -TEST_P(PeerConnectionIntegrationTest, - TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint - // that doesn't signal SSRCs (from the callee's perspective). - callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Wait for 50 audio frames (500ms of audio) to be received by the callee. - { - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(50); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } - // Some audio frames were received, so we should have nonzero "samples - // received" for the track. - rtc::scoped_refptr report = - callee()->NewGetStats(); - ASSERT_NE(nullptr, report); - auto track_stats = report->GetStatsOfType(); - ASSERT_EQ(1U, track_stats.size()); - ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined()); - ASSERT_GT(*track_stats[0]->total_samples_received, 0U); - // uint64_t prev_samples_received = *track_stats[0]->total_samples_received; - - // Create a new offer and munge it to cause the caller to use a new SSRC. - caller()->SetGeneratedSdpMunger(ModifySsrcs); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Wait for 25 more audio frames (250ms of audio) to be received, from the new - // SSRC. - { - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(25); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } - - report = callee()->NewGetStats(); - ASSERT_NE(nullptr, report); - track_stats = report->GetStatsOfType(); - ASSERT_EQ(1U, track_stats.size()); - ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined()); - // The "total samples received" stat should only be greater than it was - // before. - // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed. - // Right now, the new SSRC will cause the counters to reset to 0. - // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received); - - // Additionally, the percentage of concealed samples (samples generated to - // conceal packet loss) should be less than 50%. If it's greater, that's a - // good sign that we're seeing stats from the old stream that's no longer - // receiving packets, and is generating concealed samples of silence. - constexpr double kAcceptableConcealedSamplesPercentage = 0.50; - ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined()); - EXPECT_LT(*track_stats[0]->concealed_samples, - *track_stats[0]->total_samples_received * - kAcceptableConcealedSamplesPercentage); - - // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a - // sanity check that the SSRC really changed. - // TODO(deadbeef): This isn't working right now, because we're not returning - // *any* stats for the inactive stream. Uncomment when the bug is completely - // fixed. - // auto inbound_stream_stats = - // report->GetStatsOfType(); - // ASSERT_EQ(2U, inbound_stream_stats.size()); -} - -// Test that DTLS 1.0 is used if both sides only support DTLS 1.0. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) { - PeerConnectionFactory::Options dtls_10_options; - dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; - ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options, - dtls_10_options)); - ConnectFakeSignaling(); - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated. -TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) { - PeerConnectionFactory::Options dtls_10_options; - dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; - ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options, - dtls_10_options)); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); - EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher( - caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT), - kDefaultTimeout); - EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), - caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout); - // TODO(bugs.webrtc.org/9456): Fix it. - EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents( - "WebRTC.PeerConnection.SrtpCryptoSuite.Audio", - kDefaultSrtpCryptoSuite)); -} - -// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated. -TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) { - PeerConnectionFactory::Options dtls_12_options; - dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; - ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options, - dtls_12_options)); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); - EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher( - caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT), - kDefaultTimeout); - EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), - caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout); - // TODO(bugs.webrtc.org/9456): Fix it. - EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents( - "WebRTC.PeerConnection.SrtpCryptoSuite.Audio", - kDefaultSrtpCryptoSuite)); -} - -// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the -// callee only supports 1.0. -TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) { - PeerConnectionFactory::Options caller_options; - caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; - PeerConnectionFactory::Options callee_options; - callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; - ASSERT_TRUE( - CreatePeerConnectionWrappersWithOptions(caller_options, callee_options)); - ConnectFakeSignaling(); - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the -// callee supports 1.2. -TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) { - PeerConnectionFactory::Options caller_options; - caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; - PeerConnectionFactory::Options callee_options; - callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; - ASSERT_TRUE( - CreatePeerConnectionWrappersWithOptions(caller_options, callee_options)); - ConnectFakeSignaling(); - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher" -// works as expected; the cipher should only be used if enabled by both sides. -TEST_P(PeerConnectionIntegrationTest, - Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) { - PeerConnectionFactory::Options caller_options; - caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true; - PeerConnectionFactory::Options callee_options; - callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = - false; - int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80; - TestNegotiatedCipherSuite(caller_options, callee_options, - expected_cipher_suite); -} - -TEST_P(PeerConnectionIntegrationTest, - Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) { - PeerConnectionFactory::Options caller_options; - caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = - false; - PeerConnectionFactory::Options callee_options; - callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true; - int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80; - TestNegotiatedCipherSuite(caller_options, callee_options, - expected_cipher_suite); -} - -TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) { - PeerConnectionFactory::Options caller_options; - caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true; - PeerConnectionFactory::Options callee_options; - callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true; - int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32; - TestNegotiatedCipherSuite(caller_options, callee_options, - expected_cipher_suite); -} - -// Test that a non-GCM cipher is used if both sides only support non-GCM. -TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) { - bool local_gcm_enabled = false; - bool remote_gcm_enabled = false; - bool aes_ctr_enabled = true; - int expected_cipher_suite = kDefaultSrtpCryptoSuite; - TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled, - aes_ctr_enabled, expected_cipher_suite); -} - -// Test that a GCM cipher is used if both ends support it and non-GCM is -// disabled. -TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) { - bool local_gcm_enabled = true; - bool remote_gcm_enabled = true; - bool aes_ctr_enabled = false; - int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm; - TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled, - aes_ctr_enabled, expected_cipher_suite); -} - -// Verify that media can be transmitted end-to-end when GCM crypto suites are -// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported, -// only verify that a GCM cipher is negotiated, and not necessarily that SRTP -// works with it. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) { - PeerConnectionFactory::Options gcm_options; - gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true; - gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false; - ASSERT_TRUE( - CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options)); - ConnectFakeSignaling(); - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// This test sets up a call between two parties with audio, video and an RTP -// data channel. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithRtpDataChannel) { - PeerConnectionInterface::RTCConfiguration rtc_config; - rtc_config.enable_rtp_data_channel = true; - rtc_config.enable_dtls_srtp = false; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config)); - ConnectFakeSignaling(); - // Expect that data channel created on caller side will show up for callee as - // well. - caller()->CreateDataChannel(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Ensure the existence of the RTP data channel didn't impede audio/video. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - ASSERT_NE(nullptr, caller()->data_channel()); - ASSERT_NE(nullptr, callee()->data_channel()); - EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - - // Ensure data can be sent in both directions. - std::string data = "hello world"; - SendRtpDataWithRetries(caller()->data_channel(), data, 5); - EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(), - kDefaultTimeout); - SendRtpDataWithRetries(callee()->data_channel(), data, 5); - EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(), - kDefaultTimeout); -} - -TEST_P(PeerConnectionIntegrationTest, RtpDataChannelWorksAfterRollback) { - PeerConnectionInterface::RTCConfiguration rtc_config; - rtc_config.enable_rtp_data_channel = true; - rtc_config.enable_dtls_srtp = false; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config)); - ConnectFakeSignaling(); - auto data_channel = caller()->pc()->CreateDataChannel("label_1", nullptr); - ASSERT_TRUE(data_channel.get() != nullptr); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - caller()->CreateDataChannel("label_2", nullptr); - rtc::scoped_refptr observer( - new rtc::RefCountedObject()); - caller()->pc()->SetLocalDescription(observer, - caller()->CreateOfferAndWait().release()); - EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout); - caller()->Rollback(); - - std::string data = "hello world"; - SendRtpDataWithRetries(data_channel, data, 5); - EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(), - kDefaultTimeout); -} - -// Ensure that an RTP data channel is signaled as closed for the caller when -// the callee rejects it in a subsequent offer. -TEST_P(PeerConnectionIntegrationTest, - RtpDataChannelSignaledClosedInCalleeOffer) { - // Same procedure as above test. - PeerConnectionInterface::RTCConfiguration rtc_config; - rtc_config.enable_rtp_data_channel = true; - rtc_config.enable_dtls_srtp = false; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config)); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_NE(nullptr, caller()->data_channel()); - ASSERT_NE(nullptr, callee()->data_channel()); - ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - - // Close the data channel on the callee, and do an updated offer/answer. - callee()->data_channel()->Close(); - callee()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_FALSE(caller()->data_observer()->IsOpen()); - EXPECT_FALSE(callee()->data_observer()->IsOpen()); -} - -// Tests that data is buffered in an RTP data channel until an observer is -// registered for it. -// -// NOTE: RTP data channels can receive data before the underlying -// transport has detected that a channel is writable and thus data can be -// received before the data channel state changes to open. That is hard to test -// but the same buffering is expected to be used in that case. -// -// Use fake clock and simulated network delay so that we predictably can wait -// until an SCTP message has been delivered without "sleep()"ing. -TEST_P(PeerConnectionIntegrationTestWithFakeClock, - DataBufferedUntilRtpDataChannelObserverRegistered) { - virtual_socket_server()->set_delay_mean(5); // 5 ms per hop. - virtual_socket_server()->UpdateDelayDistribution(); - - PeerConnectionInterface::RTCConfiguration rtc_config; - rtc_config.enable_rtp_data_channel = true; - rtc_config.enable_dtls_srtp = false; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config)); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE(caller()->data_channel() != nullptr); - ASSERT_TRUE_SIMULATED_WAIT(callee()->data_channel() != nullptr, - kDefaultTimeout, FakeClock()); - ASSERT_TRUE_SIMULATED_WAIT(caller()->data_observer()->IsOpen(), - kDefaultTimeout, FakeClock()); - ASSERT_EQ_SIMULATED_WAIT(DataChannelInterface::kOpen, - callee()->data_channel()->state(), kDefaultTimeout, - FakeClock()); - - // Unregister the observer which is normally automatically registered. - callee()->data_channel()->UnregisterObserver(); - // Send data and advance fake clock until it should have been received. - std::string data = "hello world"; - caller()->data_channel()->Send(DataBuffer(data)); - SIMULATED_WAIT(false, 50, FakeClock()); - - // Attach data channel and expect data to be received immediately. Note that - // EXPECT_EQ_WAIT is used, such that the simulated clock is not advanced any - // further, but data can be received even if the callback is asynchronous. - MockDataChannelObserver new_observer(callee()->data_channel()); - EXPECT_EQ_SIMULATED_WAIT(data, new_observer.last_message(), kDefaultTimeout, - FakeClock()); -} - -// This test sets up a call between two parties with audio, video and but only -// the caller client supports RTP data channels. -TEST_P(PeerConnectionIntegrationTest, RtpDataChannelsRejectedByCallee) { - PeerConnectionInterface::RTCConfiguration rtc_config_1; - rtc_config_1.enable_rtp_data_channel = true; - // Must disable DTLS to make negotiation succeed. - rtc_config_1.enable_dtls_srtp = false; - PeerConnectionInterface::RTCConfiguration rtc_config_2; - rtc_config_2.enable_dtls_srtp = false; - rtc_config_2.enable_dtls_srtp = false; - ASSERT_TRUE( - CreatePeerConnectionWrappersWithConfig(rtc_config_1, rtc_config_2)); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - ASSERT_TRUE(caller()->data_channel() != nullptr); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // The caller should still have a data channel, but it should be closed, and - // one should ever have been created for the callee. - EXPECT_TRUE(caller()->data_channel() != nullptr); - EXPECT_FALSE(caller()->data_observer()->IsOpen()); - EXPECT_EQ(nullptr, callee()->data_channel()); -} - -// This test sets up a call between two parties with audio, and video. When -// audio and video is setup and flowing, an RTP data channel is negotiated. -TEST_P(PeerConnectionIntegrationTest, AddRtpDataChannelInSubsequentOffer) { - PeerConnectionInterface::RTCConfiguration rtc_config; - rtc_config.enable_rtp_data_channel = true; - rtc_config.enable_dtls_srtp = false; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(rtc_config, rtc_config)); - ConnectFakeSignaling(); - // Do initial offer/answer with audio/video. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Create data channel and do new offer and answer. - caller()->CreateDataChannel(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_NE(nullptr, caller()->data_channel()); - ASSERT_NE(nullptr, callee()->data_channel()); - EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - // Ensure data can be sent in both directions. - std::string data = "hello world"; - SendRtpDataWithRetries(caller()->data_channel(), data, 5); - EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(), - kDefaultTimeout); - SendRtpDataWithRetries(callee()->data_channel(), data, 5); - EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(), - kDefaultTimeout); -} - -#ifdef HAVE_SCTP - -// This test sets up a call between two parties with audio, video and an SCTP -// data channel. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSctpDataChannel) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Expect that data channel created on caller side will show up for callee as - // well. - caller()->CreateDataChannel(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Ensure the existence of the SCTP data channel didn't impede audio/video. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - // Caller data channel should already exist (it created one). Callee data - // channel may not exist yet, since negotiation happens in-band, not in SDP. - ASSERT_NE(nullptr, caller()->data_channel()); - ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout); - EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - - // Ensure data can be sent in both directions. - std::string data = "hello world"; - caller()->data_channel()->Send(DataBuffer(data)); - EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(), - kDefaultTimeout); - callee()->data_channel()->Send(DataBuffer(data)); - EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(), - kDefaultTimeout); -} - -// Ensure that when the callee closes an SCTP data channel, the closing -// procedure results in the data channel being closed for the caller as well. -TEST_P(PeerConnectionIntegrationTest, CalleeClosesSctpDataChannel) { - // Same procedure as above test. - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_NE(nullptr, caller()->data_channel()); - ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout); - ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - - // Close the data channel on the callee side, and wait for it to reach the - // "closed" state on both sides. - callee()->data_channel()->Close(); - EXPECT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout); - EXPECT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout); -} - -TEST_P(PeerConnectionIntegrationTest, SctpDataChannelConfigSentToOtherSide) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - webrtc::DataChannelInit init; - init.id = 53; - init.maxRetransmits = 52; - caller()->CreateDataChannel("data-channel", &init); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - // Since "negotiated" is false, the "id" parameter should be ignored. - EXPECT_NE(init.id, callee()->data_channel()->id()); - EXPECT_EQ("data-channel", callee()->data_channel()->label()); - EXPECT_EQ(init.maxRetransmits, callee()->data_channel()->maxRetransmits()); - EXPECT_FALSE(callee()->data_channel()->negotiated()); -} - -// Test usrsctp's ability to process unordered data stream, where data actually -// arrives out of order using simulated delays. Previously there have been some -// bugs in this area. -TEST_P(PeerConnectionIntegrationTest, StressTestUnorderedSctpDataChannel) { - // Introduce random network delays. - // Otherwise it's not a true "unordered" test. - virtual_socket_server()->set_delay_mean(20); - virtual_socket_server()->set_delay_stddev(5); - virtual_socket_server()->UpdateDelayDistribution(); - // Normal procedure, but with unordered data channel config. - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - webrtc::DataChannelInit init; - init.ordered = false; - caller()->CreateDataChannel(&init); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_NE(nullptr, caller()->data_channel()); - ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout); - ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - - static constexpr int kNumMessages = 100; - // Deliberately chosen to be larger than the MTU so messages get fragmented. - static constexpr size_t kMaxMessageSize = 4096; - // Create and send random messages. - std::vector sent_messages; - for (int i = 0; i < kNumMessages; ++i) { - size_t length = - (rand() % kMaxMessageSize) + 1; // NOLINT (rand_r instead of rand) - std::string message; - ASSERT_TRUE(rtc::CreateRandomString(length, &message)); - caller()->data_channel()->Send(DataBuffer(message)); - callee()->data_channel()->Send(DataBuffer(message)); - sent_messages.push_back(message); - } - - // Wait for all messages to be received. - EXPECT_EQ_WAIT(rtc::checked_cast(kNumMessages), - caller()->data_observer()->received_message_count(), - kDefaultTimeout); - EXPECT_EQ_WAIT(rtc::checked_cast(kNumMessages), - callee()->data_observer()->received_message_count(), - kDefaultTimeout); - - // Sort and compare to make sure none of the messages were corrupted. - std::vector caller_received_messages = - caller()->data_observer()->messages(); - std::vector callee_received_messages = - callee()->data_observer()->messages(); - absl::c_sort(sent_messages); - absl::c_sort(caller_received_messages); - absl::c_sort(callee_received_messages); - EXPECT_EQ(sent_messages, caller_received_messages); - EXPECT_EQ(sent_messages, callee_received_messages); -} - -// This test sets up a call between two parties with audio, and video. When -// audio and video are setup and flowing, an SCTP data channel is negotiated. -TEST_P(PeerConnectionIntegrationTest, AddSctpDataChannelInSubsequentOffer) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Do initial offer/answer with audio/video. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Create data channel and do new offer and answer. - caller()->CreateDataChannel(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Caller data channel should already exist (it created one). Callee data - // channel may not exist yet, since negotiation happens in-band, not in SDP. - ASSERT_NE(nullptr, caller()->data_channel()); - ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout); - EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - // Ensure data can be sent in both directions. - std::string data = "hello world"; - caller()->data_channel()->Send(DataBuffer(data)); - EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(), - kDefaultTimeout); - callee()->data_channel()->Send(DataBuffer(data)); - EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(), - kDefaultTimeout); -} - -// Set up a connection initially just using SCTP data channels, later upgrading -// to audio/video, ensuring frames are received end-to-end. Effectively the -// inverse of the test above. -// This was broken in M57; see https://crbug.com/711243 -TEST_P(PeerConnectionIntegrationTest, SctpDataChannelToAudioVideoUpgrade) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Do initial offer/answer with just data channel. - caller()->CreateDataChannel(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Wait until data can be sent over the data channel. - ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout); - ASSERT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - - // Do subsequent offer/answer with two-way audio and video. Audio and video - // should end up bundled on the DTLS/ICE transport already used for data. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) { - cricket::SctpDataContentDescription* dcd_offer = - GetFirstSctpDataContentDescription(desc); - // See https://crbug.com/webrtc/11211 - this function is a no-op - ASSERT_TRUE(dcd_offer); - dcd_offer->set_use_sctpmap(false); - dcd_offer->set_protocol("UDP/DTLS/SCTP"); -} - -// Test that the data channel works when a spec-compliant SCTP m= section is -// offered (using "a=sctp-port" instead of "a=sctpmap", and using -// "UDP/DTLS/SCTP" as the protocol). -TEST_P(PeerConnectionIntegrationTest, - DataChannelWorksWhenSpecCompliantSctpOfferReceived) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_channel() != nullptr, kDefaultTimeout); - EXPECT_TRUE_WAIT(caller()->data_observer()->IsOpen(), kDefaultTimeout); - EXPECT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - - // Ensure data can be sent in both directions. - std::string data = "hello world"; - caller()->data_channel()->Send(DataBuffer(data)); - EXPECT_EQ_WAIT(data, callee()->data_observer()->last_message(), - kDefaultTimeout); - callee()->data_channel()->Send(DataBuffer(data)); - EXPECT_EQ_WAIT(data, caller()->data_observer()->last_message(), - kDefaultTimeout); -} - -#endif // HAVE_SCTP - -// Test that the ICE connection and gathering states eventually reach -// "complete". -TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Do normal offer/answer. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete, - caller()->ice_gathering_state(), kMaxWaitForFramesMs); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete, - callee()->ice_gathering_state(), kMaxWaitForFramesMs); - // After the best candidate pair is selected and all candidates are signaled, - // the ICE connection state should reach "complete". - // TODO(deadbeef): Currently, the ICE "controlled" agent (the - // answerer/"callee" by default) only reaches "connected". When this is - // fixed, this test should be updated. - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kDefaultTimeout); -} - -constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN | - cricket::PORTALLOCATOR_DISABLE_RELAY | - cricket::PORTALLOCATOR_DISABLE_TCP; - -// Use a mock resolver to resolve the hostname back to the original IP on both -// sides and check that the ICE connection connects. -TEST_P(PeerConnectionIntegrationTest, - IceStatesReachCompletionWithRemoteHostname) { - auto caller_resolver_factory = - std::make_unique>(); - auto callee_resolver_factory = - std::make_unique>(); - NiceMock callee_async_resolver; - NiceMock caller_async_resolver; - - // This also verifies that the injected AsyncResolverFactory is used by - // P2PTransportChannel. - EXPECT_CALL(*caller_resolver_factory, Create()) - .WillOnce(Return(&caller_async_resolver)); - webrtc::PeerConnectionDependencies caller_deps(nullptr); - caller_deps.async_resolver_factory = std::move(caller_resolver_factory); - - EXPECT_CALL(*callee_resolver_factory, Create()) - .WillOnce(Return(&callee_async_resolver)); - webrtc::PeerConnectionDependencies callee_deps(nullptr); - callee_deps.async_resolver_factory = std::move(callee_resolver_factory); - - PeerConnectionInterface::RTCConfiguration config; - config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle; - config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire; - - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps( - config, std::move(caller_deps), config, std::move(callee_deps))); - - caller()->SetRemoteAsyncResolver(&callee_async_resolver); - callee()->SetRemoteAsyncResolver(&caller_async_resolver); - - // Enable hostname candidates with mDNS names. - caller()->SetMdnsResponder( - std::make_unique(network_thread())); - callee()->SetMdnsResponder( - std::make_unique(network_thread())); - - SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts); - - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kDefaultTimeout); - - EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents( - "WebRTC.PeerConnection.CandidatePairType_UDP", - webrtc::kIceCandidatePairHostNameHostName)); -} - -// Test that firewalling the ICE connection causes the clients to identify the -// disconnected state and then removing the firewall causes them to reconnect. -class PeerConnectionIntegrationIceStatesTest - : public PeerConnectionIntegrationBaseTest, - public ::testing::WithParamInterface< - std::tuple>> { - protected: - PeerConnectionIntegrationIceStatesTest() - : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) { - port_allocator_flags_ = std::get<1>(std::get<1>(GetParam())); - } - - void StartStunServer(const SocketAddress& server_address) { - stun_server_.reset( - cricket::TestStunServer::Create(network_thread(), server_address)); - } - - bool TestIPv6() { - return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6); - } - - void SetPortAllocatorFlags() { - PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags( - port_allocator_flags_, port_allocator_flags_); - } - - std::vector CallerAddresses() { - std::vector addresses; - addresses.push_back(SocketAddress("1.1.1.1", 0)); - if (TestIPv6()) { - addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0)); - } - return addresses; - } - - std::vector CalleeAddresses() { - std::vector addresses; - addresses.push_back(SocketAddress("2.2.2.2", 0)); - if (TestIPv6()) { - addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0)); - } - return addresses; - } - - void SetUpNetworkInterfaces() { - // Remove the default interfaces added by the test infrastructure. - caller()->network_manager()->RemoveInterface(kDefaultLocalAddress); - callee()->network_manager()->RemoveInterface(kDefaultLocalAddress); - - // Add network addresses for test. - for (const auto& caller_address : CallerAddresses()) { - caller()->network_manager()->AddInterface(caller_address); - } - for (const auto& callee_address : CalleeAddresses()) { - callee()->network_manager()->AddInterface(callee_address); - } - } - - private: - uint32_t port_allocator_flags_; - std::unique_ptr stun_server_; -}; - -// Ensure FakeClockForTest is constructed first (see class for rationale). -class PeerConnectionIntegrationIceStatesTestWithFakeClock - : public FakeClockForTest, - public PeerConnectionIntegrationIceStatesTest {}; - -// Tests that the PeerConnection goes through all the ICE gathering/connection -// states over the duration of the call. This includes Disconnected and Failed -// states, induced by putting a firewall between the peers and waiting for them -// to time out. -TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) { - const SocketAddress kStunServerAddress = - SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT); - StartStunServer(kStunServerAddress); - - PeerConnectionInterface::RTCConfiguration config; - PeerConnectionInterface::IceServer ice_stun_server; - ice_stun_server.urls.push_back( - "stun:" + kStunServerAddress.HostAsURIString() + ":" + - kStunServerAddress.PortAsString()); - config.servers.push_back(ice_stun_server); - - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); - ConnectFakeSignaling(); - SetPortAllocatorFlags(); - SetUpNetworkInterfaces(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - - // Initial state before anything happens. - ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew, - caller()->ice_gathering_state()); - ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew, - caller()->ice_connection_state()); - ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew, - caller()->standardized_ice_connection_state()); - - // Start the call by creating the offer, setting it as the local description, - // then sending it to the peer who will respond with an answer. This happens - // asynchronously so that we can watch the states as it runs in the - // background. - caller()->CreateAndSetAndSignalOffer(); - - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kDefaultTimeout, - FakeClock()); - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted, - caller()->standardized_ice_connection_state(), - kDefaultTimeout, FakeClock()); - - // Verify that the observer was notified of the intermediate transitions. - EXPECT_THAT(caller()->ice_connection_state_history(), - ElementsAre(PeerConnectionInterface::kIceConnectionChecking, - PeerConnectionInterface::kIceConnectionConnected, - PeerConnectionInterface::kIceConnectionCompleted)); - EXPECT_THAT(caller()->standardized_ice_connection_state_history(), - ElementsAre(PeerConnectionInterface::kIceConnectionChecking, - PeerConnectionInterface::kIceConnectionConnected, - PeerConnectionInterface::kIceConnectionCompleted)); - EXPECT_THAT( - caller()->peer_connection_state_history(), - ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting, - PeerConnectionInterface::PeerConnectionState::kConnected)); - EXPECT_THAT(caller()->ice_gathering_state_history(), - ElementsAre(PeerConnectionInterface::kIceGatheringGathering, - PeerConnectionInterface::kIceGatheringComplete)); - - // Block connections to/from the caller and wait for ICE to become - // disconnected. - for (const auto& caller_address : CallerAddresses()) { - firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address); - } - RTC_LOG(LS_INFO) << "Firewall rules applied"; - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected, - caller()->ice_connection_state(), kDefaultTimeout, - FakeClock()); - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected, - caller()->standardized_ice_connection_state(), - kDefaultTimeout, FakeClock()); - - // Let ICE re-establish by removing the firewall rules. - firewall()->ClearRules(); - RTC_LOG(LS_INFO) << "Firewall rules cleared"; - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kDefaultTimeout, - FakeClock()); - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted, - caller()->standardized_ice_connection_state(), - kDefaultTimeout, FakeClock()); - - // According to RFC7675, if there is no response within 30 seconds then the - // peer should consider the other side to have rejected the connection. This - // is signaled by the state transitioning to "failed". - constexpr int kConsentTimeout = 30000; - for (const auto& caller_address : CallerAddresses()) { - firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address); - } - RTC_LOG(LS_INFO) << "Firewall rules applied again"; - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed, - caller()->ice_connection_state(), kConsentTimeout, - FakeClock()); - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed, - caller()->standardized_ice_connection_state(), - kConsentTimeout, FakeClock()); -} - -// Tests that if the connection doesn't get set up properly we eventually reach -// the "failed" iceConnectionState. -TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, - IceStateSetupFailure) { - // Block connections to/from the caller and wait for ICE to become - // disconnected. - for (const auto& caller_address : CallerAddresses()) { - firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address); - } - - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - SetPortAllocatorFlags(); - SetUpNetworkInterfaces(); - caller()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - - // According to RFC7675, if there is no response within 30 seconds then the - // peer should consider the other side to have rejected the connection. This - // is signaled by the state transitioning to "failed". - constexpr int kConsentTimeout = 30000; - ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed, - caller()->standardized_ice_connection_state(), - kConsentTimeout, FakeClock()); -} - -// Tests that the best connection is set to the appropriate IPv4/IPv6 connection -// and that the statistics in the metric observers are updated correctly. -TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - SetPortAllocatorFlags(); - SetUpNetworkInterfaces(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kDefaultTimeout); - - // TODO(bugs.webrtc.org/9456): Fix it. - const int num_best_ipv4 = webrtc::metrics::NumEvents( - "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4); - const int num_best_ipv6 = webrtc::metrics::NumEvents( - "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6); - if (TestIPv6()) { - // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4 - // connection. - EXPECT_METRIC_EQ(0, num_best_ipv4); - EXPECT_METRIC_EQ(1, num_best_ipv6); - } else { - EXPECT_METRIC_EQ(1, num_best_ipv4); - EXPECT_METRIC_EQ(0, num_best_ipv6); - } - - EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents( - "WebRTC.PeerConnection.CandidatePairType_UDP", - webrtc::kIceCandidatePairHostHost)); - EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents( - "WebRTC.PeerConnection.CandidatePairType_UDP", - webrtc::kIceCandidatePairHostPublicHostPublic)); -} - -constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP | - cricket::PORTALLOCATOR_DISABLE_STUN | - cricket::PORTALLOCATOR_DISABLE_RELAY; -constexpr uint32_t kFlagsIPv6NoStun = - cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN | - cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY; -constexpr uint32_t kFlagsIPv4Stun = - cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY; - -INSTANTIATE_TEST_SUITE_P( - PeerConnectionIntegrationTest, - PeerConnectionIntegrationIceStatesTest, - Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan), - Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun), - std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun), - std::make_pair("IPv4 with STUN", kFlagsIPv4Stun)))); - -INSTANTIATE_TEST_SUITE_P( - PeerConnectionIntegrationTest, - PeerConnectionIntegrationIceStatesTestWithFakeClock, - Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan), - Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun), - std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun), - std::make_pair("IPv4 with STUN", kFlagsIPv4Stun)))); - -// This test sets up a call between two parties with audio and video. -// During the call, the caller restarts ICE and the test verifies that -// new ICE candidates are generated and audio and video still can flow, and the -// ICE state reaches completed again. -TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Do normal offer/answer and wait for ICE to complete. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kMaxWaitForFramesMs); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kMaxWaitForFramesMs); - - // To verify that the ICE restart actually occurs, get - // ufrag/password/candidates before and after restart. - // Create an SDP string of the first audio candidate for both clients. - const webrtc::IceCandidateCollection* audio_candidates_caller = - caller()->pc()->local_description()->candidates(0); - const webrtc::IceCandidateCollection* audio_candidates_callee = - callee()->pc()->local_description()->candidates(0); - ASSERT_GT(audio_candidates_caller->count(), 0u); - ASSERT_GT(audio_candidates_callee->count(), 0u); - std::string caller_candidate_pre_restart; - ASSERT_TRUE( - audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart)); - std::string callee_candidate_pre_restart; - ASSERT_TRUE( - audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart)); - const cricket::SessionDescription* desc = - caller()->pc()->local_description()->description(); - std::string caller_ufrag_pre_restart = - desc->transport_infos()[0].description.ice_ufrag; - desc = callee()->pc()->local_description()->description(); - std::string callee_ufrag_pre_restart = - desc->transport_infos()[0].description.ice_ufrag; - - EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u); - // Have the caller initiate an ICE restart. - caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions()); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kMaxWaitForFramesMs); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kMaxWaitForFramesMs); - - // Grab the ufrags/candidates again. - audio_candidates_caller = caller()->pc()->local_description()->candidates(0); - audio_candidates_callee = callee()->pc()->local_description()->candidates(0); - ASSERT_GT(audio_candidates_caller->count(), 0u); - ASSERT_GT(audio_candidates_callee->count(), 0u); - std::string caller_candidate_post_restart; - ASSERT_TRUE( - audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart)); - std::string callee_candidate_post_restart; - ASSERT_TRUE( - audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart)); - desc = caller()->pc()->local_description()->description(); - std::string caller_ufrag_post_restart = - desc->transport_infos()[0].description.ice_ufrag; - desc = callee()->pc()->local_description()->description(); - std::string callee_ufrag_post_restart = - desc->transport_infos()[0].description.ice_ufrag; - // Sanity check that an ICE restart was actually negotiated in SDP. - ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart); - ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart); - ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart); - ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart); - EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u); - - // Ensure that additional frames are received after the ICE restart. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Verify that audio/video can be received end-to-end when ICE renomination is -// enabled. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) { - PeerConnectionInterface::RTCConfiguration config; - config.enable_ice_renomination = true; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); - ConnectFakeSignaling(); - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Sanity check that ICE renomination was actually negotiated. - const cricket::SessionDescription* desc = - caller()->pc()->local_description()->description(); - for (const cricket::TransportInfo& info : desc->transport_infos()) { - ASSERT_THAT(info.description.transport_options, Contains("renomination")); - } - desc = callee()->pc()->local_description()->description(); - for (const cricket::TransportInfo& info : desc->transport_infos()) { - ASSERT_THAT(info.description.transport_options, Contains("renomination")); - } - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// With a max bundle policy and RTCP muxing, adding a new media description to -// the connection should not affect ICE at all because the new media will use -// the existing connection. -TEST_P(PeerConnectionIntegrationTest, - AddMediaToConnectedBundleDoesNotRestartIce) { - PeerConnectionInterface::RTCConfiguration config; - config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle; - config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig( - config, PeerConnectionInterface::RTCConfiguration())); - ConnectFakeSignaling(); - - caller()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kDefaultTimeout); - - caller()->clear_ice_connection_state_history(); - - caller()->AddVideoTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - EXPECT_EQ(0u, caller()->ice_connection_state_history().size()); -} - -// This test sets up a call between two parties with audio and video. It then -// renegotiates setting the video m-line to "port 0", then later renegotiates -// again, enabling video. -TEST_P(PeerConnectionIntegrationTest, - VideoFlowsAfterMediaSectionIsRejectedAndRecycled) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - // Do initial negotiation, only sending media from the caller. Will result in - // video and audio recvonly "m=" sections. - caller()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Negotiate again, disabling the video "m=" section (the callee will set the - // port to 0 due to offer_to_receive_video = 0). - if (sdp_semantics_ == SdpSemantics::kPlanB) { - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_video = 0; - callee()->SetOfferAnswerOptions(options); - } else { - callee()->SetRemoteOfferHandler([this] { - callee() - ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO) - ->StopInternal(); - }); - } - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Sanity check that video "m=" section was actually rejected. - const ContentInfo* answer_video_content = cricket::GetFirstVideoContent( - callee()->pc()->local_description()->description()); - ASSERT_NE(nullptr, answer_video_content); - ASSERT_TRUE(answer_video_content->rejected); - - // Enable video and do negotiation again, making sure video is received - // end-to-end, also adding media stream to callee. - if (sdp_semantics_ == SdpSemantics::kPlanB) { - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_video = 1; - callee()->SetOfferAnswerOptions(options); - } else { - // The caller's transceiver is stopped, so we need to add another track. - auto caller_transceiver = - caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO); - EXPECT_EQ(nullptr, caller_transceiver.get()); - caller()->AddVideoTrack(); - } - callee()->AddVideoTrack(); - callee()->SetRemoteOfferHandler(nullptr); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Verify the caller receives frames from the newly added stream, and the - // callee receives additional frames from the re-enabled video m= section. - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(); - media_expectations.ExpectBidirectionalVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// This tests that if we negotiate after calling CreateSender but before we -// have a track, then set a track later, frames from the newly-set track are -// received end-to-end. -TEST_F(PeerConnectionIntegrationTestPlanB, - MediaFlowsAfterEarlyWarmupWithCreateSender) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - auto caller_audio_sender = - caller()->pc()->CreateSender("audio", "caller_stream"); - auto caller_video_sender = - caller()->pc()->CreateSender("video", "caller_stream"); - auto callee_audio_sender = - callee()->pc()->CreateSender("audio", "callee_stream"); - auto callee_video_sender = - callee()->pc()->CreateSender("video", "callee_stream"); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs); - // Wait for ICE to complete, without any tracks being set. - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kMaxWaitForFramesMs); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kMaxWaitForFramesMs); - // Now set the tracks, and expect frames to immediately start flowing. - EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack())); - EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack())); - EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack())); - EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack())); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// This tests that if we negotiate after calling AddTransceiver but before we -// have a track, then set a track later, frames from the newly-set tracks are -// received end-to-end. -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - MediaFlowsAfterEarlyWarmupWithAddTransceiver) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO); - ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type()); - auto caller_audio_sender = audio_result.MoveValue()->sender(); - auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO); - ASSERT_EQ(RTCErrorType::NONE, video_result.error().type()); - auto caller_video_sender = video_result.MoveValue()->sender(); - callee()->SetRemoteOfferHandler([this] { - ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size()); - callee()->pc()->GetTransceivers()[0]->SetDirectionWithError( - RtpTransceiverDirection::kSendRecv); - callee()->pc()->GetTransceivers()[1]->SetDirectionWithError( - RtpTransceiverDirection::kSendRecv); - }); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs); - // Wait for ICE to complete, without any tracks being set. - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, - caller()->ice_connection_state(), kMaxWaitForFramesMs); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kMaxWaitForFramesMs); - // Now set the tracks, and expect frames to immediately start flowing. - auto callee_audio_sender = callee()->pc()->GetSenders()[0]; - auto callee_video_sender = callee()->pc()->GetSenders()[1]; - ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack())); - ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack())); - ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack())); - ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack())); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// This test verifies that a remote video track can be added via AddStream, -// and sent end-to-end. For this particular test, it's simply echoed back -// from the caller to the callee, rather than being forwarded to a third -// PeerConnection. -TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - // Just send a video track from the caller. - caller()->AddVideoTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs); - ASSERT_EQ(1U, callee()->remote_streams()->count()); - - // Echo the stream back, and do a new offer/anwer (initiated by callee this - // time). - callee()->pc()->AddStream(callee()->remote_streams()->at(0)); - callee()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs); - - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Test that we achieve the expected end-to-end connection time, using a -// fake clock and simulated latency on the media and signaling paths. -// We use a TURN<->TURN connection because this is usually the quickest to -// set up initially, especially when we're confident the connection will work -// and can start sending media before we get a STUN response. -// -// With various optimizations enabled, here are the network delays we expect to -// be on the critical path: -// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then -// signaling answer (with DTLS fingerprint). -// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when -// using TURN<->TURN pair, and DTLS exchange is 4 packets, -// the first of which should have arrived before the answer. -TEST_P(PeerConnectionIntegrationTestWithFakeClock, - EndToEndConnectionTimeWithTurnTurnPair) { - static constexpr int media_hop_delay_ms = 50; - static constexpr int signaling_trip_delay_ms = 500; - // For explanation of these values, see comment above. - static constexpr int required_media_hops = 9; - static constexpr int required_signaling_trips = 2; - // For internal delays (such as posting an event asychronously). - static constexpr int allowed_internal_delay_ms = 20; - static constexpr int total_connection_time_ms = - media_hop_delay_ms * required_media_hops + - signaling_trip_delay_ms * required_signaling_trips + - allowed_internal_delay_ms; - - static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0", - 3478}; - static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1", - 0}; - static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0", - 3478}; - static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1", - 0}; - cricket::TestTurnServer* turn_server_1 = CreateTurnServer( - turn_server_1_internal_address, turn_server_1_external_address); - - cricket::TestTurnServer* turn_server_2 = CreateTurnServer( - turn_server_2_internal_address, turn_server_2_external_address); - // Bypass permission check on received packets so media can be sent before - // the candidate is signaled. - network_thread()->Invoke(RTC_FROM_HERE, [turn_server_1] { - turn_server_1->set_enable_permission_checks(false); - }); - network_thread()->Invoke(RTC_FROM_HERE, [turn_server_2] { - turn_server_2->set_enable_permission_checks(false); - }); - - PeerConnectionInterface::RTCConfiguration client_1_config; - webrtc::PeerConnectionInterface::IceServer ice_server_1; - ice_server_1.urls.push_back("turn:88.88.88.0:3478"); - ice_server_1.username = "test"; - ice_server_1.password = "test"; - client_1_config.servers.push_back(ice_server_1); - client_1_config.type = webrtc::PeerConnectionInterface::kRelay; - client_1_config.presume_writable_when_fully_relayed = true; - - PeerConnectionInterface::RTCConfiguration client_2_config; - webrtc::PeerConnectionInterface::IceServer ice_server_2; - ice_server_2.urls.push_back("turn:99.99.99.0:3478"); - ice_server_2.username = "test"; - ice_server_2.password = "test"; - client_2_config.servers.push_back(ice_server_2); - client_2_config.type = webrtc::PeerConnectionInterface::kRelay; - client_2_config.presume_writable_when_fully_relayed = true; - - ASSERT_TRUE( - CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config)); - // Set up the simulated delays. - SetSignalingDelayMs(signaling_trip_delay_ms); - ConnectFakeSignaling(); - virtual_socket_server()->set_delay_mean(media_hop_delay_ms); - virtual_socket_server()->UpdateDelayDistribution(); - - // Set "offer to receive audio/video" without adding any tracks, so we just - // set up ICE/DTLS with no media. - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_audio = 1; - options.offer_to_receive_video = 1; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms, - FakeClock()); - // Closing the PeerConnections destroys the ports before the ScopedFakeClock. - // If this is not done a DCHECK can be hit in ports.cc, because a large - // negative number is calculated for the rtt due to the global clock changing. - ClosePeerConnections(); -} - -// Verify that a TurnCustomizer passed in through RTCConfiguration -// is actually used by the underlying TURN candidate pair. -// Note that turnport_unittest.cc contains more detailed, lower-level tests. -TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) { - static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0", - 3478}; - static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1", - 0}; - static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0", - 3478}; - static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1", - 0}; - CreateTurnServer(turn_server_1_internal_address, - turn_server_1_external_address); - CreateTurnServer(turn_server_2_internal_address, - turn_server_2_external_address); - - PeerConnectionInterface::RTCConfiguration client_1_config; - webrtc::PeerConnectionInterface::IceServer ice_server_1; - ice_server_1.urls.push_back("turn:88.88.88.0:3478"); - ice_server_1.username = "test"; - ice_server_1.password = "test"; - client_1_config.servers.push_back(ice_server_1); - client_1_config.type = webrtc::PeerConnectionInterface::kRelay; - auto* customizer1 = CreateTurnCustomizer(); - client_1_config.turn_customizer = customizer1; - - PeerConnectionInterface::RTCConfiguration client_2_config; - webrtc::PeerConnectionInterface::IceServer ice_server_2; - ice_server_2.urls.push_back("turn:99.99.99.0:3478"); - ice_server_2.username = "test"; - ice_server_2.password = "test"; - client_2_config.servers.push_back(ice_server_2); - client_2_config.type = webrtc::PeerConnectionInterface::kRelay; - auto* customizer2 = CreateTurnCustomizer(); - client_2_config.turn_customizer = customizer2; - - ASSERT_TRUE( - CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config)); - ConnectFakeSignaling(); - - // Set "offer to receive audio/video" without adding any tracks, so we just - // set up ICE/DTLS with no media. - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_audio = 1; - options.offer_to_receive_video = 1; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); - - ExpectTurnCustomizerCountersIncremented(customizer1); - ExpectTurnCustomizerCountersIncremented(customizer2); -} - -// Verifies that you can use TCP instead of UDP to connect to a TURN server and -// send media between the caller and the callee. -TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) { - static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0", - 3478}; - static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0}; - - // Enable TCP for the fake turn server. - CreateTurnServer(turn_server_internal_address, turn_server_external_address, - cricket::PROTO_TCP); - - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp"); - ice_server.username = "test"; - ice_server.password = "test"; - - PeerConnectionInterface::RTCConfiguration client_1_config; - client_1_config.servers.push_back(ice_server); - client_1_config.type = webrtc::PeerConnectionInterface::kRelay; - - PeerConnectionInterface::RTCConfiguration client_2_config; - client_2_config.servers.push_back(ice_server); - client_2_config.type = webrtc::PeerConnectionInterface::kRelay; - - ASSERT_TRUE( - CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config)); - - // Do normal offer/answer and wait for ICE to complete. - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kMaxWaitForFramesMs); - - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - EXPECT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Verify that a SSLCertificateVerifier passed in through -// PeerConnectionDependencies is actually used by the underlying SSL -// implementation to determine whether a certificate presented by the TURN -// server is accepted by the client. Note that openssladapter_unittest.cc -// contains more detailed, lower-level tests. -TEST_P(PeerConnectionIntegrationTest, - SSLCertificateVerifierUsedForTurnConnections) { - static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0", - 3478}; - static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0}; - - // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so - // that host name verification passes on the fake certificate. - CreateTurnServer(turn_server_internal_address, turn_server_external_address, - cricket::PROTO_TLS, "88.88.88.0"); - - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp"); - ice_server.username = "test"; - ice_server.password = "test"; - - PeerConnectionInterface::RTCConfiguration client_1_config; - client_1_config.servers.push_back(ice_server); - client_1_config.type = webrtc::PeerConnectionInterface::kRelay; - - PeerConnectionInterface::RTCConfiguration client_2_config; - client_2_config.servers.push_back(ice_server); - // Setting the type to kRelay forces the connection to go through a TURN - // server. - client_2_config.type = webrtc::PeerConnectionInterface::kRelay; - - // Get a copy to the pointer so we can verify calls later. - rtc::TestCertificateVerifier* client_1_cert_verifier = - new rtc::TestCertificateVerifier(); - client_1_cert_verifier->verify_certificate_ = true; - rtc::TestCertificateVerifier* client_2_cert_verifier = - new rtc::TestCertificateVerifier(); - client_2_cert_verifier->verify_certificate_ = true; - - // Create the dependencies with the test certificate verifier. - webrtc::PeerConnectionDependencies client_1_deps(nullptr); - client_1_deps.tls_cert_verifier = - std::unique_ptr(client_1_cert_verifier); - webrtc::PeerConnectionDependencies client_2_deps(nullptr); - client_2_deps.tls_cert_verifier = - std::unique_ptr(client_2_cert_verifier); - - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps( - client_1_config, std::move(client_1_deps), client_2_config, - std::move(client_2_deps))); - ConnectFakeSignaling(); - - // Set "offer to receive audio/video" without adding any tracks, so we just - // set up ICE/DTLS with no media. - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_audio = 1; - options.offer_to_receive_video = 1; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); - - EXPECT_GT(client_1_cert_verifier->call_count_, 0u); - EXPECT_GT(client_2_cert_verifier->call_count_, 0u); -} - -TEST_P(PeerConnectionIntegrationTest, - SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) { - static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0", - 3478}; - static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0}; - - // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so - // that host name verification passes on the fake certificate. - CreateTurnServer(turn_server_internal_address, turn_server_external_address, - cricket::PROTO_TLS, "88.88.88.0"); - - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp"); - ice_server.username = "test"; - ice_server.password = "test"; - - PeerConnectionInterface::RTCConfiguration client_1_config; - client_1_config.servers.push_back(ice_server); - client_1_config.type = webrtc::PeerConnectionInterface::kRelay; - - PeerConnectionInterface::RTCConfiguration client_2_config; - client_2_config.servers.push_back(ice_server); - // Setting the type to kRelay forces the connection to go through a TURN - // server. - client_2_config.type = webrtc::PeerConnectionInterface::kRelay; - - // Get a copy to the pointer so we can verify calls later. - rtc::TestCertificateVerifier* client_1_cert_verifier = - new rtc::TestCertificateVerifier(); - client_1_cert_verifier->verify_certificate_ = false; - rtc::TestCertificateVerifier* client_2_cert_verifier = - new rtc::TestCertificateVerifier(); - client_2_cert_verifier->verify_certificate_ = false; - - // Create the dependencies with the test certificate verifier. - webrtc::PeerConnectionDependencies client_1_deps(nullptr); - client_1_deps.tls_cert_verifier = - std::unique_ptr(client_1_cert_verifier); - webrtc::PeerConnectionDependencies client_2_deps(nullptr); - client_2_deps.tls_cert_verifier = - std::unique_ptr(client_2_cert_verifier); - - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps( - client_1_config, std::move(client_1_deps), client_2_config, - std::move(client_2_deps))); - ConnectFakeSignaling(); - - // Set "offer to receive audio/video" without adding any tracks, so we just - // set up ICE/DTLS with no media. - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_audio = 1; - options.offer_to_receive_video = 1; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - bool wait_res = true; - // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented - // properly, should be able to just wait for a state of "failed" instead of - // waiting a fixed 10 seconds. - WAIT_(DtlsConnected(), kDefaultTimeout, wait_res); - ASSERT_FALSE(wait_res); - - EXPECT_GT(client_1_cert_verifier->call_count_, 0u); - EXPECT_GT(client_2_cert_verifier->call_count_, 0u); -} - -// Test that the injected ICE transport factory is used to create ICE transports -// for WebRTC connections. -TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) { - PeerConnectionInterface::RTCConfiguration default_config; - PeerConnectionDependencies dependencies(nullptr); - auto ice_transport_factory = std::make_unique(); - EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1); - dependencies.ice_transport_factory = std::move(ice_transport_factory); - auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config, - std::move(dependencies), nullptr, - /*reset_encoder_factory=*/false, - /*reset_decoder_factory=*/false); - ASSERT_TRUE(wrapper); - wrapper->CreateDataChannel(); - rtc::scoped_refptr observer( - new rtc::RefCountedObject()); - wrapper->pc()->SetLocalDescription(observer, - wrapper->CreateOfferAndWait().release()); -} - -// Test that audio and video flow end-to-end when codec names don't use the -// expected casing, given that they're supposed to be case insensitive. To test -// this, all but one codec is removed from each media description, and its -// casing is changed. -// -// In the past, this has regressed and caused crashes/black video, due to the -// fact that code at some layers was doing case-insensitive comparisons and -// code at other layers was not. -TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - - // Remove all but one audio/video codec (opus and VP8), and change the - // casing of the caller's generated offer. - caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) { - cricket::AudioContentDescription* audio = - GetFirstAudioContentDescription(description); - ASSERT_NE(nullptr, audio); - auto audio_codecs = audio->codecs(); - audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(), - [](const cricket::AudioCodec& codec) { - return codec.name != "opus"; - }), - audio_codecs.end()); - ASSERT_EQ(1u, audio_codecs.size()); - audio_codecs[0].name = "OpUs"; - audio->set_codecs(audio_codecs); - - cricket::VideoContentDescription* video = - GetFirstVideoContentDescription(description); - ASSERT_NE(nullptr, video); - auto video_codecs = video->codecs(); - video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(), - [](const cricket::VideoCodec& codec) { - return codec.name != "VP8"; - }), - video_codecs.end()); - ASSERT_EQ(1u, video_codecs.size()); - video_codecs[0].name = "vP8"; - video->set_codecs(video_codecs); - }); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Verify frames are still received end-to-end. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Wait for one audio frame to be received by the callee. - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(1); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u); - auto receiver = callee()->pc()->GetReceivers()[0]; - ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO); - auto sources = receiver->GetSources(); - ASSERT_GT(receiver->GetParameters().encodings.size(), 0u); - EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc, - sources[0].source_id()); - EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type()); -} - -TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddVideoTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Wait for one video frame to be received by the callee. - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeVideo(1); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u); - auto receiver = callee()->pc()->GetReceivers()[0]; - ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO); - auto sources = receiver->GetSources(); - ASSERT_GT(receiver->GetParameters().encodings.size(), 0u); - ASSERT_GT(sources.size(), 0u); - EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc, - sources[0].source_id()); - EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type()); -} - -// Test that if a track is removed and added again with a different stream ID, -// the new stream ID is successfully communicated in SDP and media continues to -// flow end-to-end. -// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because -// it will not reuse a transceiver that has already been sending. After creating -// a new transceiver it tries to create an offer with two senders of the same -// track ids and it fails. -TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - // Add track using stream 1, do offer/answer. - rtc::scoped_refptr track = - caller()->CreateLocalAudioTrack(); - rtc::scoped_refptr sender = - caller()->AddTrack(track, {"stream_1"}); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - { - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(1); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } - // Remove the sender, and create a new one with the new stream. - caller()->pc()->RemoveTrack(sender); - sender = caller()->AddTrack(track, {"stream_2"}); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Wait for additional audio frames to be received by the callee. - { - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } -} - -TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - auto output = std::make_unique>(); - ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true)); - ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true)); - EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1)); - EXPECT_TRUE(caller()->pc()->StartRtcEventLog( - std::move(output), webrtc::RtcEventLog::kImmediateOutput)); - - caller()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); -} - -// Test that if candidates are only signaled by applying full session -// descriptions (instead of using AddIceCandidate), the peers can connect to -// each other and exchange media. -TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - // Each side will signal the session descriptions but not candidates. - ConnectFakeSignalingForSdpOnly(); - - // Add audio video track and exchange the initial offer/answer with media - // information only. This will start ICE gathering on each side. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - - // Wait for all candidates to be gathered on both the caller and callee. - ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete, - caller()->ice_gathering_state(), kDefaultTimeout); - ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete, - callee()->ice_gathering_state(), kDefaultTimeout); - - // The candidates will now be included in the session description, so - // signaling them will start the ICE connection. - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Ensure that media flows in both directions. - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Test that SetAudioPlayout can be used to disable audio playout from the -// start, then later enable it. This may be useful, for example, if the caller -// needs to play a local ringtone until some event occurs, after which it -// switches to playing the received audio. -TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - // Set up audio-only call where audio playout is disabled on caller's side. - caller()->pc()->SetAudioPlayout(false); - caller()->AddAudioTrack(); - callee()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Pump messages for a second. - WAIT(false, 1000); - // Since audio playout is disabled, the caller shouldn't have received - // anything (at the playout level, at least). - EXPECT_EQ(0, caller()->audio_frames_received()); - // As a sanity check, make sure the callee (for which playout isn't disabled) - // did still see frames on its audio level. - ASSERT_GT(callee()->audio_frames_received(), 0); - - // Enable playout again, and ensure audio starts flowing. - caller()->pc()->SetAudioPlayout(true); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -double GetAudioEnergyStat(PeerConnectionWrapper* pc) { - auto report = pc->NewGetStats(); - auto track_stats_list = - report->GetStatsOfType(); - const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr; - for (const auto* track_stats : track_stats_list) { - if (track_stats->remote_source.is_defined() && - *track_stats->remote_source) { - remote_track_stats = track_stats; - break; - } - } - - if (!remote_track_stats->total_audio_energy.is_defined()) { - return 0.0; - } - return *remote_track_stats->total_audio_energy; -} - -// Test that if audio playout is disabled via the SetAudioPlayout() method, then -// incoming audio is still processed and statistics are generated. -TEST_P(PeerConnectionIntegrationTest, - DisableAudioPlayoutStillGeneratesAudioStats) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - // Set up audio-only call where playout is disabled but audio-processing is - // still active. - caller()->AddAudioTrack(); - callee()->AddAudioTrack(); - caller()->pc()->SetAudioPlayout(false); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Wait for the callee to receive audio stats. - EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs); -} - -// Test that SetAudioRecording can be used to disable audio recording from the -// start, then later enable it. This may be useful, for example, if the caller -// wants to ensure that no audio resources are active before a certain state -// is reached. -TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - // Set up audio-only call where audio recording is disabled on caller's side. - caller()->pc()->SetAudioRecording(false); - caller()->AddAudioTrack(); - callee()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Pump messages for a second. - WAIT(false, 1000); - // Since caller has disabled audio recording, the callee shouldn't have - // received anything. - EXPECT_EQ(0, callee()->audio_frames_received()); - // As a sanity check, make sure the caller did still see frames on its - // audio level since audio recording is enabled on the calle side. - ASSERT_GT(caller()->audio_frames_received(), 0); - - // Enable audio recording again, and ensure audio starts flowing. - caller()->pc()->SetAudioRecording(true); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Test that after closing PeerConnections, they stop sending any packets (ICE, -// DTLS, RTP...). -TEST_P(PeerConnectionIntegrationTest, ClosingConnectionStopsPacketFlow) { - // Set up audio/video/data, wait for some frames to be received. - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); -#ifdef HAVE_SCTP - caller()->CreateDataChannel(); -#endif - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - // Close PeerConnections. - ClosePeerConnections(); - // Pump messages for a second, and ensure no new packets end up sent. - uint32_t sent_packets_a = virtual_socket_server()->sent_packets(); - WAIT(false, 1000); - uint32_t sent_packets_b = virtual_socket_server()->sent_packets(); - EXPECT_EQ(sent_packets_a, sent_packets_b); -} - -// Test that transport stats are generated by the RTCStatsCollector for a -// connection that only involves data channels. This is a regression test for -// crbug.com/826972. -#ifdef HAVE_SCTP -TEST_P(PeerConnectionIntegrationTest, - TransportStatsReportedForDataChannelOnlyConnection) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout); - - auto caller_report = caller()->NewGetStats(); - EXPECT_EQ(1u, caller_report->GetStatsOfType().size()); - auto callee_report = callee()->NewGetStats(); - EXPECT_EQ(1u, callee_report->GetStatsOfType().size()); -} -#endif // HAVE_SCTP - -TEST_P(PeerConnectionIntegrationTest, - IceEventsGeneratedAndLoggedInRtcEventLog) { - ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog()); - ConnectFakeSignaling(); - PeerConnectionInterface::RTCOfferAnswerOptions options; - options.offer_to_receive_audio = 1; - caller()->SetOfferAnswerOptions(options); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); - ASSERT_NE(nullptr, caller()->event_log_factory()); - ASSERT_NE(nullptr, callee()->event_log_factory()); - webrtc::FakeRtcEventLog* caller_event_log = - static_cast( - caller()->event_log_factory()->last_log_created()); - webrtc::FakeRtcEventLog* callee_event_log = - static_cast( - callee()->event_log_factory()->last_log_created()); - ASSERT_NE(nullptr, caller_event_log); - ASSERT_NE(nullptr, callee_event_log); - int caller_ice_config_count = caller_event_log->GetEventCount( - webrtc::RtcEvent::Type::IceCandidatePairConfig); - int caller_ice_event_count = caller_event_log->GetEventCount( - webrtc::RtcEvent::Type::IceCandidatePairEvent); - int callee_ice_config_count = callee_event_log->GetEventCount( - webrtc::RtcEvent::Type::IceCandidatePairConfig); - int callee_ice_event_count = callee_event_log->GetEventCount( - webrtc::RtcEvent::Type::IceCandidatePairEvent); - EXPECT_LT(0, caller_ice_config_count); - EXPECT_LT(0, caller_ice_event_count); - EXPECT_LT(0, callee_ice_config_count); - EXPECT_LT(0, callee_ice_event_count); -} - -TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) { - static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0", - 3478}; - static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0}; - - CreateTurnServer(turn_server_internal_address, turn_server_external_address); - - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.urls.push_back("turn:88.88.88.0:3478"); - ice_server.username = "test"; - ice_server.password = "test"; - - PeerConnectionInterface::RTCConfiguration caller_config; - caller_config.servers.push_back(ice_server); - caller_config.type = webrtc::PeerConnectionInterface::kRelay; - caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY; - caller_config.surface_ice_candidates_on_ice_transport_type_changed = true; - - PeerConnectionInterface::RTCConfiguration callee_config; - callee_config.servers.push_back(ice_server); - callee_config.type = webrtc::PeerConnectionInterface::kRelay; - callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY; - callee_config.surface_ice_candidates_on_ice_transport_type_changed = true; - - ASSERT_TRUE( - CreatePeerConnectionWrappersWithConfig(caller_config, callee_config)); - - // Do normal offer/answer and wait for ICE to complete. - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - // Since we are doing continual gathering, the ICE transport does not reach - // kIceGatheringComplete (see - // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not - // kIceConnectionComplete. - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - caller()->ice_connection_state(), kDefaultTimeout); - EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, - callee()->ice_connection_state(), kDefaultTimeout); - // Note that we cannot use the metric - // |WebRTC.PeerConnection.CandidatePairType_UDP| in this test since this - // metric is only populated when we reach kIceConnectionComplete in the - // current implementation. - EXPECT_EQ(cricket::RELAY_PORT_TYPE, - caller()->last_candidate_gathered().type()); - EXPECT_EQ(cricket::RELAY_PORT_TYPE, - callee()->last_candidate_gathered().type()); - - // Loosen the caller's candidate filter. - caller_config = caller()->pc()->GetConfiguration(); - caller_config.type = webrtc::PeerConnectionInterface::kAll; - caller()->pc()->SetConfiguration(caller_config); - // We should have gathered a new host candidate. - EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE, - caller()->last_candidate_gathered().type(), kDefaultTimeout); - - // Loosen the callee's candidate filter. - callee_config = callee()->pc()->GetConfiguration(); - callee_config.type = webrtc::PeerConnectionInterface::kAll; - callee()->pc()->SetConfiguration(callee_config); - EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE, - callee()->last_candidate_gathered().type(), kDefaultTimeout); - - // Create an offer and verify that it does not contain an ICE restart (i.e new - // ice credentials). - std::string caller_ufrag_pre_offer = caller() - ->pc() - ->local_description() - ->description() - ->transport_infos()[0] - .description.ice_ufrag; - caller()->CreateAndSetAndSignalOffer(); - std::string caller_ufrag_post_offer = caller() - ->pc() - ->local_description() - ->description() - ->transport_infos()[0] - .description.ice_ufrag; - EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer); -} - -TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) { - static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0", - 3478}; - static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0}; - - CreateTurnServer(turn_server_internal_address, turn_server_external_address); - - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.urls.push_back("turn:88.88.88.0:3478"); - ice_server.username = "test"; - ice_server.password = "123"; - - PeerConnectionInterface::RTCConfiguration caller_config; - caller_config.servers.push_back(ice_server); - caller_config.type = webrtc::PeerConnectionInterface::kRelay; - caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY; - - PeerConnectionInterface::RTCConfiguration callee_config; - callee_config.servers.push_back(ice_server); - callee_config.type = webrtc::PeerConnectionInterface::kRelay; - callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY; - - ASSERT_TRUE( - CreatePeerConnectionWrappersWithConfig(caller_config, callee_config)); - - // Do normal offer/answer and wait for ICE to complete. - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout); - EXPECT_EQ("Unauthorized", caller()->error_event().error_text); - EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url); - EXPECT_NE(caller()->error_event().address, ""); -} - -TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) { - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp"); - ice_server.username = "test"; - ice_server.password = "test"; - - PeerConnectionInterface::RTCConfiguration caller_config; - caller_config.servers.push_back(ice_server); - caller_config.type = webrtc::PeerConnectionInterface::kRelay; - caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY; - - PeerConnectionInterface::RTCConfiguration callee_config; - callee_config.servers.push_back(ice_server); - callee_config.type = webrtc::PeerConnectionInterface::kRelay; - callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY; - - ASSERT_TRUE( - CreatePeerConnectionWrappersWithConfig(caller_config, callee_config)); - - // Do normal offer/answer and wait for ICE to complete. - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout); - EXPECT_EQ(caller()->error_event().address, ""); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - AudioKeepsFlowingAfterImplicitRollback) { - PeerConnectionInterface::RTCConfiguration config; - config.sdp_semantics = SdpSemantics::kUnifiedPlan; - config.enable_implicit_rollback = true; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - callee()->AddAudioTrack(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - SetSignalIceCandidates(false); // Workaround candidate outrace sdp. - caller()->AddVideoTrack(); - callee()->AddVideoTrack(); - rtc::scoped_refptr observer( - new rtc::RefCountedObject()); - callee()->pc()->SetLocalDescription(observer, - callee()->CreateOfferAndWait().release()); - EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout); - caller()->CreateAndSetAndSignalOffer(); // Implicit rollback. - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - ImplicitRollbackVisitsStableState) { - RTCConfiguration config; - config.sdp_semantics = SdpSemantics::kUnifiedPlan; - config.enable_implicit_rollback = true; - - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); - - rtc::scoped_refptr sld_observer( - new rtc::RefCountedObject()); - callee()->pc()->SetLocalDescription(sld_observer, - callee()->CreateOfferAndWait().release()); - EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout); - EXPECT_EQ(sld_observer->error(), ""); - - rtc::scoped_refptr srd_observer( - new rtc::RefCountedObject()); - callee()->pc()->SetRemoteDescription( - srd_observer, caller()->CreateOfferAndWait().release()); - EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout); - EXPECT_EQ(srd_observer->error(), ""); - - EXPECT_THAT(callee()->peer_connection_signaling_state_history(), - ElementsAre(PeerConnectionInterface::kHaveLocalOffer, - PeerConnectionInterface::kStable, - PeerConnectionInterface::kHaveRemoteOffer)); -} - -INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest, - PeerConnectionIntegrationTest, - Values(SdpSemantics::kPlanB, - SdpSemantics::kUnifiedPlan)); - -INSTANTIATE_TEST_SUITE_P(PeerConnectionIntegrationTest, - PeerConnectionIntegrationTestWithFakeClock, - Values(SdpSemantics::kPlanB, - SdpSemantics::kUnifiedPlan)); - -// Tests that verify interoperability between Plan B and Unified Plan -// PeerConnections. -class PeerConnectionIntegrationInteropTest - : public PeerConnectionIntegrationBaseTest, - public ::testing::WithParamInterface< - std::tuple> { - protected: - // Setting the SdpSemantics for the base test to kDefault does not matter - // because we specify not to use the test semantics when creating - // PeerConnectionWrappers. - PeerConnectionIntegrationInteropTest() - : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB), - caller_semantics_(std::get<0>(GetParam())), - callee_semantics_(std::get<1>(GetParam())) {} - - bool CreatePeerConnectionWrappersWithSemantics() { - return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_, - callee_semantics_); - } - - const SdpSemantics caller_semantics_; - const SdpSemantics callee_semantics_; -}; - -TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) { - ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics()); - ConnectFakeSignaling(); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); -} - -TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) { - ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics()); - ConnectFakeSignaling(); - auto audio_sender = caller()->AddAudioTrack(); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Verify that one audio receiver has been created on the remote and that it - // has the same track ID as the sending track. - auto receivers = callee()->pc()->GetReceivers(); - ASSERT_EQ(1u, receivers.size()); - EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type()); - EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id()); - - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) { - ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics()); - ConnectFakeSignaling(); - auto video_sender = caller()->AddVideoTrack(); - auto audio_sender = caller()->AddAudioTrack(); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Verify that one audio and one video receiver have been created on the - // remote and that they have the same track IDs as the sending tracks. - auto audio_receivers = - callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO); - ASSERT_EQ(1u, audio_receivers.size()); - EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id()); - auto video_receivers = - callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO); - ASSERT_EQ(1u, video_receivers.size()); - EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id()); - - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_P(PeerConnectionIntegrationInteropTest, - OneAudioOneVideoLocalToOneAudioOneVideoRemote) { - ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics()); - ConnectFakeSignaling(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -TEST_P(PeerConnectionIntegrationInteropTest, - ReverseRolesOneAudioLocalToOneVideoRemote) { - ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics()); - ConnectFakeSignaling(); - caller()->AddAudioTrack(); - callee()->AddVideoTrack(); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Verify that only the audio track has been negotiated. - EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size()); - // Might also check that the callee's NegotiationNeeded flag is set. - - // Reverse roles. - callee()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - MediaExpectations media_expectations; - media_expectations.CallerExpectsSomeVideo(); - media_expectations.CalleeExpectsSomeAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -INSTANTIATE_TEST_SUITE_P( - PeerConnectionIntegrationTest, - PeerConnectionIntegrationInteropTest, - Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan), - std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB))); - -// Test that if the Unified Plan side offers two video tracks then the Plan B -// side will only see the first one and ignore the second. -TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) { - ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics( - SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)); - ConnectFakeSignaling(); - auto first_sender = caller()->AddVideoTrack(); - caller()->AddVideoTrack(); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - - // Verify that there is only one receiver and it corresponds to the first - // added track. - auto receivers = callee()->pc()->GetReceivers(); - ASSERT_EQ(1u, receivers.size()); - EXPECT_TRUE(receivers[0]->track()->enabled()); - EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id()); - - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} - -// Test that if the initial offer tagged BUNDLE section is rejected due to its -// associated RtpTransceiver being stopped and another transceiver is added, -// then renegotiation causes the callee to receive the new video track without -// error. -// This is a regression test for bugs.webrtc.org/9954 -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - ReOfferWithStoppedBundleTaggedTransceiver) { - RTCConfiguration config; - config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle; - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); - ConnectFakeSignaling(); - auto audio_transceiver_or_error = - caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack()); - ASSERT_TRUE(audio_transceiver_or_error.ok()); - auto audio_transceiver = audio_transceiver_or_error.MoveValue(); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - { - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeAudio(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } - - audio_transceiver->StopInternal(); - caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack()); - - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - { - MediaExpectations media_expectations; - media_expectations.CalleeExpectsSomeVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); - } -} - -#ifdef HAVE_SCTP - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - EndToEndCallWithBundledSctpDataChannel) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_EQ_WAIT(SctpTransportState::kConnected, - caller()->pc()->GetSctpTransport()->Information().state(), - kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - EndToEndCallWithDataChannelOnlyConnects) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - ASSERT_TRUE(caller()->data_observer()->IsOpen()); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, DataChannelClosesWhenClosed) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - caller()->data_channel()->Close(); - ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - DataChannelClosesWhenClosedReverse) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - callee()->data_channel()->Close(); - ASSERT_TRUE_WAIT(!caller()->data_observer()->IsOpen(), kDefaultTimeout); -} - -TEST_F(PeerConnectionIntegrationTestUnifiedPlan, - DataChannelClosesWhenPeerConnectionClosed) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - caller()->CreateDataChannel(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer(), kDefaultTimeout); - ASSERT_TRUE_WAIT(callee()->data_observer()->IsOpen(), kDefaultTimeout); - caller()->pc()->Close(); - ASSERT_TRUE_WAIT(!callee()->data_observer()->IsOpen(), kDefaultTimeout); -} - -#endif // HAVE_SCTP - -} // namespace -} // namespace webrtc - -#endif // if !defined(THREAD_SANITIZER) diff --git a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_message_handler.cc b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_message_handler.cc new file mode 100644 index 000000000..7988339c5 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_message_handler.cc @@ -0,0 +1,200 @@ +/* + * Copyright 2020 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 "pc/peer_connection_message_handler.h" + +#include + +#include "api/jsep.h" +#include "api/media_stream_interface.h" +#include "api/peer_connection_interface.h" +#include "pc/stats_collector_interface.h" +#include "rtc_base/synchronization/sequence_checker.h" + +namespace webrtc { + +namespace { + +enum { + MSG_SET_SESSIONDESCRIPTION_SUCCESS = 0, + MSG_SET_SESSIONDESCRIPTION_FAILED, + MSG_CREATE_SESSIONDESCRIPTION_FAILED, + MSG_GETSTATS, + MSG_REPORT_USAGE_PATTERN, + MSG_ON_ERROR_DEMUXING_PACKET, +}; + +struct SetSessionDescriptionMsg : public rtc::MessageData { + explicit SetSessionDescriptionMsg( + webrtc::SetSessionDescriptionObserver* observer) + : observer(observer) {} + + rtc::scoped_refptr observer; + RTCError error; +}; + +struct CreateSessionDescriptionMsg : public rtc::MessageData { + explicit CreateSessionDescriptionMsg( + webrtc::CreateSessionDescriptionObserver* observer) + : observer(observer) {} + + rtc::scoped_refptr observer; + RTCError error; +}; + +struct GetStatsMsg : public rtc::MessageData { + GetStatsMsg(webrtc::StatsObserver* observer, + StatsCollectorInterface* stats, + webrtc::MediaStreamTrackInterface* track) + : observer(observer), stats(stats), track(track) {} + rtc::scoped_refptr observer; + StatsCollectorInterface* stats; + rtc::scoped_refptr track; +}; + +struct RequestUsagePatternMsg : public rtc::MessageData { + explicit RequestUsagePatternMsg(std::function func) + : function(func) {} + std::function function; +}; + +struct OnErrorDemuxingPacketMsg : public rtc::MessageData { + explicit OnErrorDemuxingPacketMsg(webrtc::ErrorDemuxingPacketObserver* observer, + uint32_t ssrc) + : observer(observer), ssrc(ssrc) {} + + rtc::scoped_refptr observer; + uint32_t ssrc; +}; + +} // namespace + +PeerConnectionMessageHandler::~PeerConnectionMessageHandler() { + // Process all pending notifications in the message queue. If we don't do + // this, requests will linger and not know they succeeded or failed. + rtc::MessageList list; + signaling_thread()->Clear(this, rtc::MQID_ANY, &list); + for (auto& msg : list) { + if (msg.message_id == MSG_CREATE_SESSIONDESCRIPTION_FAILED) { + // Processing CreateOffer() and CreateAnswer() messages ensures their + // observers are invoked even if the PeerConnection is destroyed early. + OnMessage(&msg); + } else { + // TODO(hbos): Consider processing all pending messages. This would mean + // that SetLocalDescription() and SetRemoteDescription() observers are + // informed of successes and failures; this is currently NOT the case. + delete msg.pdata; + } + } +} + +void PeerConnectionMessageHandler::OnMessage(rtc::Message* msg) { + RTC_DCHECK_RUN_ON(signaling_thread()); + switch (msg->message_id) { + case MSG_SET_SESSIONDESCRIPTION_SUCCESS: { + SetSessionDescriptionMsg* param = + static_cast(msg->pdata); + param->observer->OnSuccess(); + delete param; + break; + } + case MSG_SET_SESSIONDESCRIPTION_FAILED: { + SetSessionDescriptionMsg* param = + static_cast(msg->pdata); + param->observer->OnFailure(std::move(param->error)); + delete param; + break; + } + case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { + CreateSessionDescriptionMsg* param = + static_cast(msg->pdata); + param->observer->OnFailure(std::move(param->error)); + delete param; + break; + } + case MSG_GETSTATS: { + GetStatsMsg* param = static_cast(msg->pdata); + StatsReports reports; + param->stats->GetStats(param->track, &reports); + param->observer->OnComplete(reports); + delete param; + break; + } + case MSG_REPORT_USAGE_PATTERN: { + RequestUsagePatternMsg* param = + static_cast(msg->pdata); + param->function(); + delete param; + break; + } + case MSG_ON_ERROR_DEMUXING_PACKET: { + OnErrorDemuxingPacketMsg* param = static_cast(msg->pdata); + param->observer->OnErrorDemuxingPacket(param->ssrc); + delete param; + break; + } + default: + RTC_NOTREACHED() << "Not implemented"; + break; + } +} + +void PeerConnectionMessageHandler::PostSetSessionDescriptionSuccess( + SetSessionDescriptionObserver* observer) { + SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); + signaling_thread()->Post(RTC_FROM_HERE, this, + MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); +} + +void PeerConnectionMessageHandler::PostSetSessionDescriptionFailure( + SetSessionDescriptionObserver* observer, + RTCError&& error) { + RTC_DCHECK(!error.ok()); + SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); + msg->error = std::move(error); + signaling_thread()->Post(RTC_FROM_HERE, this, + MSG_SET_SESSIONDESCRIPTION_FAILED, msg); +} + +void PeerConnectionMessageHandler::PostCreateSessionDescriptionFailure( + CreateSessionDescriptionObserver* observer, + RTCError error) { + RTC_DCHECK(!error.ok()); + CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); + msg->error = std::move(error); + signaling_thread()->Post(RTC_FROM_HERE, this, + MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg); +} + +void PeerConnectionMessageHandler::PostGetStats( + StatsObserver* observer, + StatsCollectorInterface* stats, + MediaStreamTrackInterface* track) { + signaling_thread()->Post(RTC_FROM_HERE, this, MSG_GETSTATS, + new GetStatsMsg(observer, stats, track)); +} + +void PeerConnectionMessageHandler::RequestUsagePatternReport( + std::function func, + int delay_ms) { + signaling_thread()->PostDelayed(RTC_FROM_HERE, delay_ms, this, + MSG_REPORT_USAGE_PATTERN, + new RequestUsagePatternMsg(func)); +} + +void PeerConnectionMessageHandler::PostErrorDemuxingPacket( + ErrorDemuxingPacketObserver* observer, + uint32_t ssrc) { + signaling_thread()->Post(RTC_FROM_HERE, this, + MSG_ON_ERROR_DEMUXING_PACKET, + new OnErrorDemuxingPacketMsg(observer, ssrc)); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/peer_connection_message_handler.h b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_message_handler.h new file mode 100644 index 000000000..858426d6f --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/peer_connection_message_handler.h @@ -0,0 +1,59 @@ +/* + * Copyright 2020 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. + */ + +#ifndef PC_PEER_CONNECTION_MESSAGE_HANDLER_H_ +#define PC_PEER_CONNECTION_MESSAGE_HANDLER_H_ + +#include +#include "api/rtc_error.h" +#include "api/stats_types.h" +#include "rtc_base/message_handler.h" +#include "rtc_base/thread.h" + +namespace webrtc { + +class CreateSessionDescriptionObserver; +class SetSessionDescriptionObserver; +class StatsCollectorInterface; +class StatsObserver; +class MediaStreamTrackInterface; +class ErrorDemuxingPacketObserver; + +class PeerConnectionMessageHandler : public rtc::MessageHandler { + public: + explicit PeerConnectionMessageHandler(rtc::Thread* signaling_thread) + : signaling_thread_(signaling_thread) {} + ~PeerConnectionMessageHandler(); + + // Implements MessageHandler. + void OnMessage(rtc::Message* msg) override; + void PostSetSessionDescriptionSuccess( + SetSessionDescriptionObserver* observer); + void PostSetSessionDescriptionFailure(SetSessionDescriptionObserver* observer, + RTCError&& error); + void PostCreateSessionDescriptionFailure( + CreateSessionDescriptionObserver* observer, + RTCError error); + void PostGetStats(StatsObserver* observer, + StatsCollectorInterface* stats, + MediaStreamTrackInterface* track); + void RequestUsagePatternReport(std::function, int delay_ms); + void PostErrorDemuxingPacket(ErrorDemuxingPacketObserver* observer, + uint32_t ssrc); + + private: + rtc::Thread* signaling_thread() const { return signaling_thread_; } + + rtc::Thread* const signaling_thread_; +}; + +} // namespace webrtc + +#endif // PC_PEER_CONNECTION_MESSAGE_HANDLER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/pc/remote_audio_source.cc b/TMessagesProj/jni/voip/webrtc/pc/remote_audio_source.cc index 18a4ed25c..8ae061254 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/remote_audio_source.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/remote_audio_source.cc @@ -18,7 +18,6 @@ #include "absl/algorithm/container.h" #include "api/scoped_refptr.h" #include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" #include "rtc_base/location.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" @@ -36,6 +35,11 @@ class RemoteAudioSource::AudioDataProxy : public AudioSinkInterface { explicit AudioDataProxy(RemoteAudioSource* source) : source_(source) { RTC_DCHECK(source); } + + AudioDataProxy() = delete; + AudioDataProxy(const AudioDataProxy&) = delete; + AudioDataProxy& operator=(const AudioDataProxy&) = delete; + ~AudioDataProxy() override { source_->OnAudioChannelGone(); } // AudioSinkInterface implementation. @@ -45,8 +49,6 @@ class RemoteAudioSource::AudioDataProxy : public AudioSinkInterface { private: const rtc::scoped_refptr source_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioDataProxy); }; RemoteAudioSource::RemoteAudioSource(rtc::Thread* worker_thread) diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_collector.cc b/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_collector.cc index 5851b0680..529200894 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_collector.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_collector.cc @@ -216,6 +216,7 @@ const char* QualityLimitationReasonToRTCQualityLimitationReason( case QualityLimitationReason::kOther: return RTCQualityLimitationReason::kOther; } + RTC_CHECK_NOTREACHED(); } double DoubleAudioLevelFromIntAudioLevel(int audio_level) { @@ -227,6 +228,7 @@ double DoubleAudioLevelFromIntAudioLevel(int audio_level) { std::unique_ptr CodecStatsFromRtpCodecParameters( uint64_t timestamp_us, const std::string& mid, + const std::string& transport_id, bool inbound, const RtpCodecParameters& codec_params) { RTC_DCHECK_GE(codec_params.payload_type, 0); @@ -249,6 +251,7 @@ std::unique_ptr CodecStatsFromRtpCodecParameters( if (WriteFmtpParameters(codec_params.parameters, &fmtp)) { codec_stats->sdp_fmtp_line = fmtp.Release(); } + codec_stats->transport_id = transport_id; return codec_stats; } @@ -305,7 +308,10 @@ void SetInboundRTPStreamStatsFromVoiceReceiverInfo( voice_receiver_info.inserted_samples_for_deceleration; inbound_audio->removed_samples_for_acceleration = voice_receiver_info.removed_samples_for_acceleration; - inbound_audio->audio_level = voice_receiver_info.audio_level; + if (voice_receiver_info.audio_level >= 0) { + inbound_audio->audio_level = + DoubleAudioLevelFromIntAudioLevel(voice_receiver_info.audio_level); + } inbound_audio->total_audio_energy = voice_receiver_info.total_output_energy; inbound_audio->total_samples_duration = voice_receiver_info.total_output_duration; @@ -1070,24 +1076,14 @@ void RTCStatsCollector::GetStatsReportInternal( num_pending_partial_reports_ = 2; partial_report_timestamp_us_ = cache_now_us; - // Prepare |transceiver_stats_infos_| for use in + // Prepare |transceiver_stats_infos_| and |call_stats_| for use in // |ProducePartialResultsOnNetworkThread| and // |ProducePartialResultsOnSignalingThread|. - transceiver_stats_infos_ = PrepareTransceiverStatsInfos_s_w(); + PrepareTransceiverStatsInfosAndCallStats_s_w(); // Prepare |transport_names_| for use in // |ProducePartialResultsOnNetworkThread|. transport_names_ = PrepareTransportNames_s(); - // Prepare |call_stats_| here since GetCallStats() will hop to the worker - // thread. - // TODO(holmer): To avoid the hop we could move BWE and BWE stats to the - // network thread, where it more naturally belongs. - // TODO(https://crbug.com/webrtc/11767): In the meantime we can piggyback on - // the blocking-invoke that is already performed in - // PrepareTransceiverStatsInfos_s_w() so that we can call GetCallStats() - // without additional blocking-invokes. - call_stats_ = pc_->GetCallStats(); - // Don't touch |network_report_| on the signaling thread until // ProducePartialResultsOnNetworkThread() has signaled the // |network_report_event_|. @@ -1288,6 +1284,9 @@ void RTCStatsCollector::ProduceCodecStats_n( if (!stats.mid) { continue; } + std::string transport_id = RTCTransportStatsIDFromTransportChannel( + *stats.transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); + const cricket::VoiceMediaInfo* voice_media_info = stats.track_media_info_map->voice_media_info(); const cricket::VideoMediaInfo* video_media_info = @@ -1297,12 +1296,12 @@ void RTCStatsCollector::ProduceCodecStats_n( // Inbound for (const auto& pair : voice_media_info->receive_codecs) { report->AddStats(CodecStatsFromRtpCodecParameters( - timestamp_us, *stats.mid, true, pair.second)); + timestamp_us, *stats.mid, transport_id, true, pair.second)); } // Outbound for (const auto& pair : voice_media_info->send_codecs) { report->AddStats(CodecStatsFromRtpCodecParameters( - timestamp_us, *stats.mid, false, pair.second)); + timestamp_us, *stats.mid, transport_id, false, pair.second)); } } // Video @@ -1310,12 +1309,12 @@ void RTCStatsCollector::ProduceCodecStats_n( // Inbound for (const auto& pair : video_media_info->receive_codecs) { report->AddStats(CodecStatsFromRtpCodecParameters( - timestamp_us, *stats.mid, true, pair.second)); + timestamp_us, *stats.mid, transport_id, true, pair.second)); } // Outbound for (const auto& pair : video_media_info->send_codecs) { report->AddStats(CodecStatsFromRtpCodecParameters( - timestamp_us, *stats.mid, false, pair.second)); + timestamp_us, *stats.mid, transport_id, false, pair.second)); } } } @@ -1894,11 +1893,10 @@ RTCStatsCollector::PrepareTransportCertificateStats_n( return transport_cert_stats; } -std::vector -RTCStatsCollector::PrepareTransceiverStatsInfos_s_w() const { +void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w() { RTC_DCHECK(signaling_thread_->IsCurrent()); - std::vector transceiver_stats_infos; + transceiver_stats_infos_.clear(); // These are used to invoke GetStats for all the media channels together in // one worker thread hop. std::mapinternal(); stats.media_type = media_type; @@ -1948,14 +1946,16 @@ RTCStatsCollector::PrepareTransceiverStatsInfos_s_w() const { } } - // We jump to the worker thread and call GetStats() on each media channel. At - // the same time we construct the TrackMediaInfoMaps, which also needs info - // from the worker thread. This minimizes the number of thread jumps. + // We jump to the worker thread and call GetStats() on each media channel as + // well as GetCallStats(). At the same time we construct the + // TrackMediaInfoMaps, which also needs info from the worker thread. This + // minimizes the number of thread jumps. worker_thread_->Invoke(RTC_FROM_HERE, [&] { rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; for (const auto& entry : voice_stats) { - if (!entry.first->GetStats(entry.second.get())) { + if (!entry.first->GetStats(entry.second.get(), + /*get_and_clear_legacy_stats=*/false)) { RTC_LOG(LS_WARNING) << "Failed to get voice stats."; } } @@ -1966,7 +1966,7 @@ RTCStatsCollector::PrepareTransceiverStatsInfos_s_w() const { } // Create the TrackMediaInfoMap for each transceiver stats object. - for (auto& stats : transceiver_stats_infos) { + for (auto& stats : transceiver_stats_infos_) { auto transceiver = stats.transceiver; std::unique_ptr voice_media_info; std::unique_ptr video_media_info; @@ -1998,9 +1998,9 @@ RTCStatsCollector::PrepareTransceiverStatsInfos_s_w() const { std::move(voice_media_info), std::move(video_media_info), senders, receivers); } - }); - return transceiver_stats_infos; + call_stats_ = pc_->GetCallStats(); + }); } std::set RTCStatsCollector::PrepareTransportNames_s() const { diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_collector.h b/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_collector.h index e1bc27d9e..35576e91d 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_collector.h +++ b/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_collector.h @@ -215,7 +215,8 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface, PrepareTransportCertificateStats_n( const std::map& transport_stats_by_name) const; - std::vector PrepareTransceiverStatsInfos_s_w() const; + // The results are stored in |transceiver_stats_infos_| and |call_stats_|. + void PrepareTransceiverStatsInfosAndCallStats_s_w(); std::set PrepareTransportNames_s() const; // Stats gathering on a particular thread. diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_integrationtest.cc b/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_integrationtest.cc index e627d45e2..ee68ec9a0 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_integrationtest.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_integrationtest.cc @@ -442,6 +442,8 @@ class RTCStatsReportVerifier { bool VerifyRTCCodecStats(const RTCCodecStats& codec) { RTCStatsVerifier verifier(report_, &codec); + verifier.TestMemberIsIDReference(codec.transport_id, + RTCTransportStats::kType); verifier.TestMemberIsDefined(codec.payload_type); verifier.TestMemberIsDefined(codec.mime_type); verifier.TestMemberIsPositive(codec.clock_rate); diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_traversal.cc b/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_traversal.cc index c08643eba..aa53dde18 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_traversal.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/rtc_stats_traversal.cc @@ -76,7 +76,8 @@ std::vector GetStatsReferencedIds(const RTCStats& stats) { const auto& certificate = static_cast(stats); AddIdIfDefined(certificate.issuer_certificate_id, &neighbor_ids); } else if (type == RTCCodecStats::kType) { - // RTCCodecStats does not have any neighbor references. + const auto& codec = static_cast(stats); + AddIdIfDefined(codec.transport_id, &neighbor_ids); } else if (type == RTCDataChannelStats::kType) { // RTCDataChannelStats does not have any neighbor references. } else if (type == RTCIceCandidatePairStats::kType) { diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_data_channel.h b/TMessagesProj/jni/voip/webrtc/pc/rtp_data_channel.h index adc724d64..ea2de49b5 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_data_channel.h +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_data_channel.h @@ -191,7 +191,6 @@ class RtpDataChannel : public DataChannelInterface, uint32_t send_ssrc_ RTC_GUARDED_BY(signaling_thread_) = 0; uint32_t receive_ssrc_ RTC_GUARDED_BY(signaling_thread_) = 0; PacketQueue queued_received_data_ RTC_GUARDED_BY(signaling_thread_); - rtc::AsyncInvoker invoker_ RTC_GUARDED_BY(signaling_thread_); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_parameters_conversion.cc b/TMessagesProj/jni/voip/webrtc/pc/rtp_parameters_conversion.cc index 9c7a337ab..68a948ea8 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_parameters_conversion.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_parameters_conversion.cc @@ -76,8 +76,7 @@ RTCErrorOr ToCricketFeedbackParam( } return cricket::FeedbackParam(cricket::kRtcpFbParamTransportCc); } - // Not reached; avoids compile warning. - FATAL(); + RTC_CHECK_NOTREACHED(); } template diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_receiver.h b/TMessagesProj/jni/voip/webrtc/pc/rtp_receiver.h index 84c2ff723..2cfccd4e6 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_receiver.h +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_receiver.h @@ -41,7 +41,11 @@ namespace webrtc { // Internal class used by PeerConnection. class RtpReceiverInternal : public RtpReceiverInterface { public: + // Stops receiving. The track may be reactivated. virtual void Stop() = 0; + // Stops the receiver permanently. + // Causes the associated track to enter kEnded state. Cannot be reversed. + virtual void StopAndEndTrack() = 0; // Sets the underlying MediaEngine channel associated with this RtpSender. // A VoiceMediaChannel should be used for audio RtpSenders and diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_sender.cc b/TMessagesProj/jni/voip/webrtc/pc/rtp_sender.cc index 1430e299c..0da6dfca8 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_sender.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_sender.cc @@ -17,8 +17,7 @@ #include "api/audio_options.h" #include "api/media_stream_interface.h" #include "media/base/media_engine.h" -#include "pc/peer_connection.h" -#include "pc/stats_collector.h" +#include "pc/stats_collector_interface.h" #include "rtc_base/checks.h" #include "rtc_base/helpers.h" #include "rtc_base/location.h" @@ -418,7 +417,7 @@ void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) { rtc::scoped_refptr AudioRtpSender::Create( rtc::Thread* worker_thread, const std::string& id, - StatsCollector* stats, + StatsCollectorInterface* stats, SetStreamsObserver* set_streams_observer) { return rtc::scoped_refptr( new rtc::RefCountedObject(worker_thread, id, stats, @@ -427,7 +426,7 @@ rtc::scoped_refptr AudioRtpSender::Create( AudioRtpSender::AudioRtpSender(rtc::Thread* worker_thread, const std::string& id, - StatsCollector* stats, + StatsCollectorInterface* stats, SetStreamsObserver* set_streams_observer) : RtpSenderBase(worker_thread, id, set_streams_observer), stats_(stats), diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_sender.h b/TMessagesProj/jni/voip/webrtc/pc/rtp_sender.h index c343ff085..c2fe91f01 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_sender.h +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_sender.h @@ -28,7 +28,7 @@ namespace webrtc { -class StatsCollector; +class StatsCollectorInterface; bool UnimplementedRtpParameterHasValue(const RtpParameters& parameters); @@ -257,7 +257,7 @@ class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase { static rtc::scoped_refptr Create( rtc::Thread* worker_thread, const std::string& id, - StatsCollector* stats, + StatsCollectorInterface* stats, SetStreamsObserver* set_streams_observer); virtual ~AudioRtpSender(); @@ -281,7 +281,7 @@ class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase { protected: AudioRtpSender(rtc::Thread* worker_thread, const std::string& id, - StatsCollector* stats, + StatsCollectorInterface* stats, SetStreamsObserver* set_streams_observer); void SetSend() override; @@ -303,7 +303,7 @@ class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase { } sigslot::signal0<> SignalDestroyed; - StatsCollector* stats_ = nullptr; + StatsCollectorInterface* stats_ = nullptr; rtc::scoped_refptr dtmf_sender_proxy_; bool cached_track_enabled_ = false; diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_transceiver.cc b/TMessagesProj/jni/voip/webrtc/pc/rtp_transceiver.cc index 701b83ffc..6b3032e27 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_transceiver.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_transceiver.cc @@ -119,12 +119,14 @@ RtpTransceiver::RtpTransceiver( rtc::scoped_refptr> receiver, cricket::ChannelManager* channel_manager, - std::vector header_extensions_offered) + std::vector header_extensions_offered, + std::function on_negotiation_needed) : thread_(GetCurrentTaskQueueOrThread()), unified_plan_(true), media_type_(sender->media_type()), channel_manager_(channel_manager), - header_extensions_to_offer_(std::move(header_extensions_offered)) { + header_extensions_to_offer_(std::move(header_extensions_offered)), + on_negotiation_needed_(std::move(on_negotiation_needed)) { RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO || media_type_ == cricket::MEDIA_TYPE_VIDEO); RTC_DCHECK_EQ(sender->media_type(), receiver->media_type()); @@ -299,10 +301,6 @@ RtpTransceiverDirection RtpTransceiver::direction() const { return direction_; } -void RtpTransceiver::SetDirection(RtpTransceiverDirection new_direction) { - SetDirectionWithError(new_direction); -} - RTCError RtpTransceiver::SetDirectionWithError( RtpTransceiverDirection new_direction) { if (unified_plan_ && stopping()) { @@ -318,14 +316,14 @@ RTCError RtpTransceiver::SetDirectionWithError( } direction_ = new_direction; - SignalNegotiationNeeded(); + on_negotiation_needed_(); return RTCError::OK(); } absl::optional RtpTransceiver::current_direction() const { - if (unified_plan_ && stopping()) + if (unified_plan_ && stopped()) return webrtc::RtpTransceiverDirection::kStopped; return current_direction_; @@ -350,7 +348,7 @@ void RtpTransceiver::StopSendingAndReceiving() { // 5. Stop receiving media with receiver. for (const auto& receiver : receivers_) - receiver->internal()->Stop(); + receiver->internal()->StopAndEndTrack(); stopping_ = true; direction_ = webrtc::RtpTransceiverDirection::kInactive; @@ -358,7 +356,11 @@ void RtpTransceiver::StopSendingAndReceiving() { RTCError RtpTransceiver::StopStandard() { RTC_DCHECK_RUN_ON(thread_); - RTC_DCHECK(unified_plan_); + // If we're on Plan B, do what Stop() used to do there. + if (!unified_plan_) { + StopInternal(); + return RTCError::OK(); + } // 1. Let transceiver be the RTCRtpTransceiver object on which the method is // invoked. // @@ -378,13 +380,18 @@ RTCError RtpTransceiver::StopStandard() { // 5. Stop sending and receiving given transceiver, and update the // negotiation-needed flag for connection. StopSendingAndReceiving(); - SignalNegotiationNeeded(); + on_negotiation_needed_(); return RTCError::OK(); } void RtpTransceiver::StopInternal() { + StopTransceiverProcedure(); +} + +void RtpTransceiver::StopTransceiverProcedure() { RTC_DCHECK_RUN_ON(thread_); + // As specified in the "Stop the RTCRtpTransceiver" procedure // 1. If transceiver.[[Stopping]] is false, stop sending and receiving given // transceiver. if (!stopping_) diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_transceiver.h b/TMessagesProj/jni/voip/webrtc/pc/rtp_transceiver.h index 980d64ca7..4d9716c89 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_transceiver.h +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_transceiver.h @@ -71,7 +71,8 @@ class RtpTransceiver final rtc::scoped_refptr> receiver, cricket::ChannelManager* channel_manager, - std::vector HeaderExtensionsToOffer); + std::vector HeaderExtensionsToOffer, + std::function on_negotiation_needed); ~RtpTransceiver() override; // Returns the Voice/VideoChannel set for this transceiver. May be null if @@ -177,9 +178,13 @@ class RtpTransceiver final // PeerConnection is closed. void SetPeerConnectionClosed(); + // Executes the "stop the RTCRtpTransceiver" procedure from + // the webrtc-pc specification, described under the stop() method. + void StopTransceiverProcedure(); + // Fired when the RtpTransceiver state changes such that negotiation is now // needed (e.g., in response to a direction change). - sigslot::signal0<> SignalNegotiationNeeded; + // sigslot::signal0<> SignalNegotiationNeeded; // RtpTransceiverInterface implementation. cricket::MediaType media_type() const override; @@ -189,7 +194,6 @@ class RtpTransceiver final bool stopped() const override; bool stopping() const override; RtpTransceiverDirection direction() const override; - void SetDirection(RtpTransceiverDirection new_direction) override; RTCError SetDirectionWithError( RtpTransceiverDirection new_direction) override; absl::optional current_direction() const override; @@ -237,18 +241,18 @@ class RtpTransceiver final cricket::ChannelManager* channel_manager_ = nullptr; std::vector codec_preferences_; std::vector header_extensions_to_offer_; + const std::function on_negotiation_needed_; }; BEGIN_SIGNALING_PROXY_MAP(RtpTransceiver) PROXY_SIGNALING_THREAD_DESTRUCTOR() -PROXY_CONSTMETHOD0(cricket::MediaType, media_type) +BYPASS_PROXY_CONSTMETHOD0(cricket::MediaType, media_type) PROXY_CONSTMETHOD0(absl::optional, mid) PROXY_CONSTMETHOD0(rtc::scoped_refptr, sender) PROXY_CONSTMETHOD0(rtc::scoped_refptr, receiver) PROXY_CONSTMETHOD0(bool, stopped) PROXY_CONSTMETHOD0(bool, stopping) PROXY_CONSTMETHOD0(RtpTransceiverDirection, direction) -PROXY_METHOD1(void, SetDirection, RtpTransceiverDirection) PROXY_METHOD1(webrtc::RTCError, SetDirectionWithError, RtpTransceiverDirection) PROXY_CONSTMETHOD0(absl::optional, current_direction) PROXY_CONSTMETHOD0(absl::optional, fired_direction) diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_transmission_manager.cc b/TMessagesProj/jni/voip/webrtc/pc/rtp_transmission_manager.cc new file mode 100644 index 000000000..e796f9b1b --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_transmission_manager.cc @@ -0,0 +1,685 @@ +/* + * Copyright 2020 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 "pc/rtp_transmission_manager.h" + +#include + +#include "absl/types/optional.h" +#include "api/peer_connection_interface.h" +#include "api/rtp_transceiver_direction.h" +#include "pc/audio_rtp_receiver.h" +#include "pc/channel.h" +#include "pc/stats_collector_interface.h" +#include "pc/video_rtp_receiver.h" +#include "rtc_base/checks.h" +#include "rtc_base/helpers.h" +#include "rtc_base/logging.h" + +namespace webrtc { + +namespace { + +static const char kDefaultAudioSenderId[] = "defaulta0"; +static const char kDefaultVideoSenderId[] = "defaultv0"; + +} // namespace + +RtpTransmissionManager::RtpTransmissionManager( + bool is_unified_plan, + rtc::Thread* signaling_thread, + rtc::Thread* worker_thread, + cricket::ChannelManager* channel_manager, + UsagePattern* usage_pattern, + PeerConnectionObserver* observer, + StatsCollectorInterface* stats, + std::function on_negotiation_needed) + : is_unified_plan_(is_unified_plan), + signaling_thread_(signaling_thread), + worker_thread_(worker_thread), + channel_manager_(channel_manager), + usage_pattern_(usage_pattern), + observer_(observer), + stats_(stats), + on_negotiation_needed_(on_negotiation_needed), + weak_ptr_factory_(this) {} + +void RtpTransmissionManager::Close() { + closed_ = true; + observer_ = nullptr; +} + +// Implementation of SetStreamsObserver +void RtpTransmissionManager::OnSetStreams() { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (IsUnifiedPlan()) + OnNegotiationNeeded(); +} + +// Function to call back to the PeerConnection when negotiation is needed +void RtpTransmissionManager::OnNegotiationNeeded() { + on_negotiation_needed_(); +} + +// Function that returns the currently valid observer +PeerConnectionObserver* RtpTransmissionManager::Observer() const { + RTC_DCHECK(!closed_); + RTC_DCHECK(observer_); + return observer_; +} + +cricket::VoiceMediaChannel* RtpTransmissionManager::voice_media_channel() + const { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(!IsUnifiedPlan()); + auto* voice_channel = static_cast( + GetAudioTransceiver()->internal()->channel()); + if (voice_channel) { + return voice_channel->media_channel(); + } else { + return nullptr; + } +} + +cricket::VideoMediaChannel* RtpTransmissionManager::video_media_channel() + const { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(!IsUnifiedPlan()); + auto* video_channel = static_cast( + GetVideoTransceiver()->internal()->channel()); + if (video_channel) { + return video_channel->media_channel(); + } else { + return nullptr; + } +} + +RTCErrorOr> +RtpTransmissionManager::AddTrack( + rtc::scoped_refptr track, + const std::vector& stream_ids) { + RTC_DCHECK_RUN_ON(signaling_thread()); + + return (IsUnifiedPlan() ? AddTrackUnifiedPlan(track, stream_ids) + : AddTrackPlanB(track, stream_ids)); +} + +RTCErrorOr> +RtpTransmissionManager::AddTrackPlanB( + rtc::scoped_refptr track, + const std::vector& stream_ids) { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (stream_ids.size() > 1u) { + LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION, + "AddTrack with more than one stream is not " + "supported with Plan B semantics."); + } + std::vector adjusted_stream_ids = stream_ids; + if (adjusted_stream_ids.empty()) { + adjusted_stream_ids.push_back(rtc::CreateRandomUuid()); + } + cricket::MediaType media_type = + (track->kind() == MediaStreamTrackInterface::kAudioKind + ? cricket::MEDIA_TYPE_AUDIO + : cricket::MEDIA_TYPE_VIDEO); + auto new_sender = + CreateSender(media_type, track->id(), track, adjusted_stream_ids, {}); + if (track->kind() == MediaStreamTrackInterface::kAudioKind) { + new_sender->internal()->SetMediaChannel(voice_media_channel()); + GetAudioTransceiver()->internal()->AddSender(new_sender); + const RtpSenderInfo* sender_info = + FindSenderInfo(local_audio_sender_infos_, + new_sender->internal()->stream_ids()[0], track->id()); + if (sender_info) { + new_sender->internal()->SetSsrc(sender_info->first_ssrc); + } + } else { + RTC_DCHECK_EQ(MediaStreamTrackInterface::kVideoKind, track->kind()); + new_sender->internal()->SetMediaChannel(video_media_channel()); + GetVideoTransceiver()->internal()->AddSender(new_sender); + const RtpSenderInfo* sender_info = + FindSenderInfo(local_video_sender_infos_, + new_sender->internal()->stream_ids()[0], track->id()); + if (sender_info) { + new_sender->internal()->SetSsrc(sender_info->first_ssrc); + } + } + return rtc::scoped_refptr(new_sender); +} + +RTCErrorOr> +RtpTransmissionManager::AddTrackUnifiedPlan( + rtc::scoped_refptr track, + const std::vector& stream_ids) { + auto transceiver = FindFirstTransceiverForAddedTrack(track); + if (transceiver) { + RTC_LOG(LS_INFO) << "Reusing an existing " + << cricket::MediaTypeToString(transceiver->media_type()) + << " transceiver for AddTrack."; + if (transceiver->stopping()) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + "The existing transceiver is stopping."); + } + + if (transceiver->direction() == RtpTransceiverDirection::kRecvOnly) { + transceiver->internal()->set_direction( + RtpTransceiverDirection::kSendRecv); + } else if (transceiver->direction() == RtpTransceiverDirection::kInactive) { + transceiver->internal()->set_direction( + RtpTransceiverDirection::kSendOnly); + } + transceiver->sender()->SetTrack(track); + transceiver->internal()->sender_internal()->set_stream_ids(stream_ids); + transceiver->internal()->set_reused_for_addtrack(true); + } else { + cricket::MediaType media_type = + (track->kind() == MediaStreamTrackInterface::kAudioKind + ? cricket::MEDIA_TYPE_AUDIO + : cricket::MEDIA_TYPE_VIDEO); + RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type) + << " transceiver in response to a call to AddTrack."; + std::string sender_id = track->id(); + // Avoid creating a sender with an existing ID by generating a random ID. + // This can happen if this is the second time AddTrack has created a sender + // for this track. + if (FindSenderById(sender_id)) { + sender_id = rtc::CreateRandomUuid(); + } + auto sender = CreateSender(media_type, sender_id, track, stream_ids, {}); + auto receiver = CreateReceiver(media_type, rtc::CreateRandomUuid()); + transceiver = CreateAndAddTransceiver(sender, receiver); + transceiver->internal()->set_created_by_addtrack(true); + transceiver->internal()->set_direction(RtpTransceiverDirection::kSendRecv); + } + return transceiver->sender(); +} + +rtc::scoped_refptr> +RtpTransmissionManager::CreateSender( + cricket::MediaType media_type, + const std::string& id, + rtc::scoped_refptr track, + const std::vector& stream_ids, + const std::vector& send_encodings) { + RTC_DCHECK_RUN_ON(signaling_thread()); + rtc::scoped_refptr> sender; + if (media_type == cricket::MEDIA_TYPE_AUDIO) { + RTC_DCHECK(!track || + (track->kind() == MediaStreamTrackInterface::kAudioKind)); + sender = RtpSenderProxyWithInternal::Create( + signaling_thread(), + AudioRtpSender::Create(worker_thread(), id, stats_, this)); + NoteUsageEvent(UsageEvent::AUDIO_ADDED); + } else { + RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO); + RTC_DCHECK(!track || + (track->kind() == MediaStreamTrackInterface::kVideoKind)); + sender = RtpSenderProxyWithInternal::Create( + signaling_thread(), VideoRtpSender::Create(worker_thread(), id, this)); + NoteUsageEvent(UsageEvent::VIDEO_ADDED); + } + bool set_track_succeeded = sender->SetTrack(track); + RTC_DCHECK(set_track_succeeded); + sender->internal()->set_stream_ids(stream_ids); + sender->internal()->set_init_send_encodings(send_encodings); + return sender; +} + +rtc::scoped_refptr> +RtpTransmissionManager::CreateReceiver(cricket::MediaType media_type, + const std::string& receiver_id) { + RTC_DCHECK_RUN_ON(signaling_thread()); + rtc::scoped_refptr> + receiver; + if (media_type == cricket::MEDIA_TYPE_AUDIO) { + receiver = RtpReceiverProxyWithInternal::Create( + signaling_thread(), new AudioRtpReceiver(worker_thread(), receiver_id, + std::vector({}))); + NoteUsageEvent(UsageEvent::AUDIO_ADDED); + } else { + RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO); + receiver = RtpReceiverProxyWithInternal::Create( + signaling_thread(), new VideoRtpReceiver(worker_thread(), receiver_id, + std::vector({}))); + NoteUsageEvent(UsageEvent::VIDEO_ADDED); + } + return receiver; +} + +rtc::scoped_refptr> +RtpTransmissionManager::CreateAndAddTransceiver( + rtc::scoped_refptr> sender, + rtc::scoped_refptr> + receiver) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Ensure that the new sender does not have an ID that is already in use by + // another sender. + // Allow receiver IDs to conflict since those come from remote SDP (which + // could be invalid, but should not cause a crash). + RTC_DCHECK(!FindSenderById(sender->id())); + auto transceiver = RtpTransceiverProxyWithInternal::Create( + signaling_thread(), + new RtpTransceiver( + sender, receiver, channel_manager(), + sender->media_type() == cricket::MEDIA_TYPE_AUDIO + ? channel_manager()->GetSupportedAudioRtpHeaderExtensions() + : channel_manager()->GetSupportedVideoRtpHeaderExtensions(), + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr()]() { + if (this_weak_ptr) { + this_weak_ptr->OnNegotiationNeeded(); + } + })); + transceivers()->Add(transceiver); + return transceiver; +} + +rtc::scoped_refptr> +RtpTransmissionManager::FindFirstTransceiverForAddedTrack( + rtc::scoped_refptr track) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(track); + for (auto transceiver : transceivers()->List()) { + if (!transceiver->sender()->track() && + cricket::MediaTypeToString(transceiver->media_type()) == + track->kind() && + !transceiver->internal()->has_ever_been_used_to_send() && + !transceiver->stopped()) { + return transceiver; + } + } + return nullptr; +} + +std::vector>> +RtpTransmissionManager::GetSendersInternal() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + std::vector>> + all_senders; + for (const auto& transceiver : transceivers_.List()) { + if (IsUnifiedPlan() && transceiver->internal()->stopped()) + continue; + + auto senders = transceiver->internal()->senders(); + all_senders.insert(all_senders.end(), senders.begin(), senders.end()); + } + return all_senders; +} + +std::vector< + rtc::scoped_refptr>> +RtpTransmissionManager::GetReceiversInternal() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + std::vector< + rtc::scoped_refptr>> + all_receivers; + for (const auto& transceiver : transceivers_.List()) { + if (IsUnifiedPlan() && transceiver->internal()->stopped()) + continue; + + auto receivers = transceiver->internal()->receivers(); + all_receivers.insert(all_receivers.end(), receivers.begin(), + receivers.end()); + } + return all_receivers; +} + +rtc::scoped_refptr> +RtpTransmissionManager::GetAudioTransceiver() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + // This method only works with Plan B SDP, where there is a single + // audio/video transceiver. + RTC_DCHECK(!IsUnifiedPlan()); + for (auto transceiver : transceivers_.List()) { + if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { + return transceiver; + } + } + RTC_NOTREACHED(); + return nullptr; +} + +rtc::scoped_refptr> +RtpTransmissionManager::GetVideoTransceiver() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + // This method only works with Plan B SDP, where there is a single + // audio/video transceiver. + RTC_DCHECK(!IsUnifiedPlan()); + for (auto transceiver : transceivers_.List()) { + if (transceiver->media_type() == cricket::MEDIA_TYPE_VIDEO) { + return transceiver; + } + } + RTC_NOTREACHED(); + return nullptr; +} + +void RtpTransmissionManager::AddAudioTrack(AudioTrackInterface* track, + MediaStreamInterface* stream) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(track); + RTC_DCHECK(stream); + auto sender = FindSenderForTrack(track); + if (sender) { + // We already have a sender for this track, so just change the stream_id + // so that it's correct in the next call to CreateOffer. + sender->internal()->set_stream_ids({stream->id()}); + return; + } + + // Normal case; we've never seen this track before. + auto new_sender = CreateSender(cricket::MEDIA_TYPE_AUDIO, track->id(), track, + {stream->id()}, {}); + new_sender->internal()->SetMediaChannel(voice_media_channel()); + GetAudioTransceiver()->internal()->AddSender(new_sender); + // If the sender has already been configured in SDP, we call SetSsrc, + // which will connect the sender to the underlying transport. This can + // occur if a local session description that contains the ID of the sender + // is set before AddStream is called. It can also occur if the local + // session description is not changed and RemoveStream is called, and + // later AddStream is called again with the same stream. + const RtpSenderInfo* sender_info = + FindSenderInfo(local_audio_sender_infos_, stream->id(), track->id()); + if (sender_info) { + new_sender->internal()->SetSsrc(sender_info->first_ssrc); + } +} + +// TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around +// indefinitely, when we have unified plan SDP. +void RtpTransmissionManager::RemoveAudioTrack(AudioTrackInterface* track, + MediaStreamInterface* stream) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(!IsUnifiedPlan()); + auto sender = FindSenderForTrack(track); + if (!sender) { + RTC_LOG(LS_WARNING) << "RtpSender for track with id " << track->id() + << " doesn't exist."; + return; + } + GetAudioTransceiver()->internal()->RemoveSender(sender); +} + +void RtpTransmissionManager::AddVideoTrack(VideoTrackInterface* track, + MediaStreamInterface* stream) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(track); + RTC_DCHECK(stream); + auto sender = FindSenderForTrack(track); + if (sender) { + // We already have a sender for this track, so just change the stream_id + // so that it's correct in the next call to CreateOffer. + sender->internal()->set_stream_ids({stream->id()}); + return; + } + + // Normal case; we've never seen this track before. + auto new_sender = CreateSender(cricket::MEDIA_TYPE_VIDEO, track->id(), track, + {stream->id()}, {}); + new_sender->internal()->SetMediaChannel(video_media_channel()); + GetVideoTransceiver()->internal()->AddSender(new_sender); + const RtpSenderInfo* sender_info = + FindSenderInfo(local_video_sender_infos_, stream->id(), track->id()); + if (sender_info) { + new_sender->internal()->SetSsrc(sender_info->first_ssrc); + } +} + +void RtpTransmissionManager::RemoveVideoTrack(VideoTrackInterface* track, + MediaStreamInterface* stream) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(!IsUnifiedPlan()); + auto sender = FindSenderForTrack(track); + if (!sender) { + RTC_LOG(LS_WARNING) << "RtpSender for track with id " << track->id() + << " doesn't exist."; + return; + } + GetVideoTransceiver()->internal()->RemoveSender(sender); +} + +void RtpTransmissionManager::CreateAudioReceiver( + MediaStreamInterface* stream, + const RtpSenderInfo& remote_sender_info) { + RTC_DCHECK(!closed_); + std::vector> streams; + streams.push_back(rtc::scoped_refptr(stream)); + // TODO(https://crbug.com/webrtc/9480): When we remove remote_streams(), use + // the constructor taking stream IDs instead. + auto* audio_receiver = new AudioRtpReceiver( + worker_thread(), remote_sender_info.sender_id, streams); + audio_receiver->SetMediaChannel(voice_media_channel()); + if (remote_sender_info.sender_id == kDefaultAudioSenderId) { + audio_receiver->SetupUnsignaledMediaChannel(); + } else { + audio_receiver->SetupMediaChannel(remote_sender_info.first_ssrc); + } + auto receiver = RtpReceiverProxyWithInternal::Create( + signaling_thread(), audio_receiver); + GetAudioTransceiver()->internal()->AddReceiver(receiver); + Observer()->OnAddTrack(receiver, streams); + NoteUsageEvent(UsageEvent::AUDIO_ADDED); +} + +void RtpTransmissionManager::CreateVideoReceiver( + MediaStreamInterface* stream, + const RtpSenderInfo& remote_sender_info) { + RTC_DCHECK(!closed_); + std::vector> streams; + streams.push_back(rtc::scoped_refptr(stream)); + // TODO(https://crbug.com/webrtc/9480): When we remove remote_streams(), use + // the constructor taking stream IDs instead. + auto* video_receiver = new VideoRtpReceiver( + worker_thread(), remote_sender_info.sender_id, streams); + video_receiver->SetMediaChannel(video_media_channel()); + if (remote_sender_info.sender_id == kDefaultVideoSenderId) { + video_receiver->SetupUnsignaledMediaChannel(); + } else { + video_receiver->SetupMediaChannel(remote_sender_info.first_ssrc); + } + auto receiver = RtpReceiverProxyWithInternal::Create( + signaling_thread(), video_receiver); + GetVideoTransceiver()->internal()->AddReceiver(receiver); + Observer()->OnAddTrack(receiver, streams); + NoteUsageEvent(UsageEvent::VIDEO_ADDED); +} + +// TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote +// description. +rtc::scoped_refptr +RtpTransmissionManager::RemoveAndStopReceiver( + const RtpSenderInfo& remote_sender_info) { + auto receiver = FindReceiverById(remote_sender_info.sender_id); + if (!receiver) { + RTC_LOG(LS_WARNING) << "RtpReceiver for track with id " + << remote_sender_info.sender_id << " doesn't exist."; + return nullptr; + } + if (receiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { + GetAudioTransceiver()->internal()->RemoveReceiver(receiver); + } else { + GetVideoTransceiver()->internal()->RemoveReceiver(receiver); + } + return receiver; +} + +void RtpTransmissionManager::OnRemoteSenderAdded( + const RtpSenderInfo& sender_info, + MediaStreamInterface* stream, + cricket::MediaType media_type) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_LOG(LS_INFO) << "Creating " << cricket::MediaTypeToString(media_type) + << " receiver for track_id=" << sender_info.sender_id + << " and stream_id=" << sender_info.stream_id; + + if (media_type == cricket::MEDIA_TYPE_AUDIO) { + CreateAudioReceiver(stream, sender_info); + } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { + CreateVideoReceiver(stream, sender_info); + } else { + RTC_NOTREACHED() << "Invalid media type"; + } +} + +void RtpTransmissionManager::OnRemoteSenderRemoved( + const RtpSenderInfo& sender_info, + MediaStreamInterface* stream, + cricket::MediaType media_type) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_LOG(LS_INFO) << "Removing " << cricket::MediaTypeToString(media_type) + << " receiver for track_id=" << sender_info.sender_id + << " and stream_id=" << sender_info.stream_id; + + rtc::scoped_refptr receiver; + if (media_type == cricket::MEDIA_TYPE_AUDIO) { + // When the MediaEngine audio channel is destroyed, the RemoteAudioSource + // will be notified which will end the AudioRtpReceiver::track(). + receiver = RemoveAndStopReceiver(sender_info); + rtc::scoped_refptr audio_track = + stream->FindAudioTrack(sender_info.sender_id); + if (audio_track) { + stream->RemoveTrack(audio_track); + } + } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { + // Stopping or destroying a VideoRtpReceiver will end the + // VideoRtpReceiver::track(). + receiver = RemoveAndStopReceiver(sender_info); + rtc::scoped_refptr video_track = + stream->FindVideoTrack(sender_info.sender_id); + if (video_track) { + // There's no guarantee the track is still available, e.g. the track may + // have been removed from the stream by an application. + stream->RemoveTrack(video_track); + } + } else { + RTC_NOTREACHED() << "Invalid media type"; + } + if (receiver) { + RTC_DCHECK(!closed_); + Observer()->OnRemoveTrack(receiver); + } +} + +void RtpTransmissionManager::OnLocalSenderAdded( + const RtpSenderInfo& sender_info, + cricket::MediaType media_type) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(!IsUnifiedPlan()); + auto sender = FindSenderById(sender_info.sender_id); + if (!sender) { + RTC_LOG(LS_WARNING) << "An unknown RtpSender with id " + << sender_info.sender_id + << " has been configured in the local description."; + return; + } + + if (sender->media_type() != media_type) { + RTC_LOG(LS_WARNING) << "An RtpSender has been configured in the local" + " description with an unexpected media type."; + return; + } + + sender->internal()->set_stream_ids({sender_info.stream_id}); + sender->internal()->SetSsrc(sender_info.first_ssrc); +} + +void RtpTransmissionManager::OnLocalSenderRemoved( + const RtpSenderInfo& sender_info, + cricket::MediaType media_type) { + RTC_DCHECK_RUN_ON(signaling_thread()); + auto sender = FindSenderById(sender_info.sender_id); + if (!sender) { + // This is the normal case. I.e., RemoveStream has been called and the + // SessionDescriptions has been renegotiated. + return; + } + + // A sender has been removed from the SessionDescription but it's still + // associated with the PeerConnection. This only occurs if the SDP doesn't + // match with the calls to CreateSender, AddStream and RemoveStream. + if (sender->media_type() != media_type) { + RTC_LOG(LS_WARNING) << "An RtpSender has been configured in the local" + " description with an unexpected media type."; + return; + } + + sender->internal()->SetSsrc(0); +} + +std::vector* RtpTransmissionManager::GetRemoteSenderInfos( + cricket::MediaType media_type) { + RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO || + media_type == cricket::MEDIA_TYPE_VIDEO); + return (media_type == cricket::MEDIA_TYPE_AUDIO) + ? &remote_audio_sender_infos_ + : &remote_video_sender_infos_; +} + +std::vector* RtpTransmissionManager::GetLocalSenderInfos( + cricket::MediaType media_type) { + RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO || + media_type == cricket::MEDIA_TYPE_VIDEO); + return (media_type == cricket::MEDIA_TYPE_AUDIO) ? &local_audio_sender_infos_ + : &local_video_sender_infos_; +} + +const RtpSenderInfo* RtpTransmissionManager::FindSenderInfo( + const std::vector& infos, + const std::string& stream_id, + const std::string sender_id) const { + for (const RtpSenderInfo& sender_info : infos) { + if (sender_info.stream_id == stream_id && + sender_info.sender_id == sender_id) { + return &sender_info; + } + } + return nullptr; +} + +rtc::scoped_refptr> +RtpTransmissionManager::FindSenderForTrack( + MediaStreamTrackInterface* track) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + for (const auto& transceiver : transceivers_.List()) { + for (auto sender : transceiver->internal()->senders()) { + if (sender->track() == track) { + return sender; + } + } + } + return nullptr; +} + +rtc::scoped_refptr> +RtpTransmissionManager::FindSenderById(const std::string& sender_id) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + for (const auto& transceiver : transceivers_.List()) { + for (auto sender : transceiver->internal()->senders()) { + if (sender->id() == sender_id) { + return sender; + } + } + } + return nullptr; +} + +rtc::scoped_refptr> +RtpTransmissionManager::FindReceiverById(const std::string& receiver_id) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + for (const auto& transceiver : transceivers_.List()) { + for (auto receiver : transceiver->internal()->receivers()) { + if (receiver->id() == receiver_id) { + return receiver; + } + } + } + return nullptr; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_transmission_manager.h b/TMessagesProj/jni/voip/webrtc/pc/rtp_transmission_manager.h new file mode 100644 index 000000000..731c3b74d --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_transmission_manager.h @@ -0,0 +1,267 @@ +/* + * Copyright 2020 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. + */ + +#ifndef PC_RTP_TRANSMISSION_MANAGER_H_ +#define PC_RTP_TRANSMISSION_MANAGER_H_ + +#include +#include +#include +#include + +#include "api/media_stream_interface.h" +#include "api/media_types.h" +#include "api/peer_connection_interface.h" +#include "api/rtc_error.h" +#include "api/rtp_parameters.h" +#include "api/rtp_receiver_interface.h" +#include "api/rtp_sender_interface.h" +#include "api/scoped_refptr.h" +#include "media/base/media_channel.h" +#include "pc/channel_manager.h" +#include "pc/rtp_receiver.h" +#include "pc/rtp_sender.h" +#include "pc/rtp_transceiver.h" +#include "pc/stats_collector_interface.h" +#include "pc/transceiver_list.h" +#include "pc/usage_pattern.h" +#include "rtc_base/synchronization/sequence_checker.h" +#include "rtc_base/third_party/sigslot/sigslot.h" +#include "rtc_base/thread.h" +#include "rtc_base/thread_annotations.h" + +namespace rtc { +class Thread; +} + +namespace webrtc { + +// This class contains information about +// an RTPSender, used for things like looking it up by SSRC. +struct RtpSenderInfo { + RtpSenderInfo() : first_ssrc(0) {} + RtpSenderInfo(const std::string& stream_id, + const std::string sender_id, + uint32_t ssrc) + : stream_id(stream_id), sender_id(sender_id), first_ssrc(ssrc) {} + bool operator==(const RtpSenderInfo& other) { + return this->stream_id == other.stream_id && + this->sender_id == other.sender_id && + this->first_ssrc == other.first_ssrc; + } + std::string stream_id; + std::string sender_id; + // An RtpSender can have many SSRCs. The first one is used as a sort of ID + // for communicating with the lower layers. + uint32_t first_ssrc; +}; + +// The RtpTransmissionManager class is responsible for managing the lifetime +// and relationships between objects of type RtpSender, RtpReceiver and +// RtpTransceiver. +class RtpTransmissionManager : public RtpSenderBase::SetStreamsObserver { + public: + RtpTransmissionManager(bool is_unified_plan, + rtc::Thread* signaling_thread, + rtc::Thread* worker_thread, + cricket::ChannelManager* channel_manager, + UsagePattern* usage_pattern, + PeerConnectionObserver* observer, + StatsCollectorInterface* stats_, + std::function on_negotiation_needed); + + // No move or copy permitted. + RtpTransmissionManager(const RtpTransmissionManager&) = delete; + RtpTransmissionManager& operator=(const RtpTransmissionManager&) = delete; + + // Stop activity. In particular, don't call observer_ any more. + void Close(); + + // RtpSenderBase::SetStreamsObserver override. + void OnSetStreams() override; + + // Add a new track, creating transceiver if required. + RTCErrorOr> AddTrack( + rtc::scoped_refptr track, + const std::vector& stream_ids); + + // Create a new RTP sender. Does not associate with a transceiver. + rtc::scoped_refptr> + CreateSender(cricket::MediaType media_type, + const std::string& id, + rtc::scoped_refptr track, + const std::vector& stream_ids, + const std::vector& send_encodings); + + // Create a new RTP receiver. Does not associate with a transceiver. + rtc::scoped_refptr> + CreateReceiver(cricket::MediaType media_type, const std::string& receiver_id); + + // Create a new RtpTransceiver of the given type and add it to the list of + // registered transceivers. + rtc::scoped_refptr> + CreateAndAddTransceiver( + rtc::scoped_refptr> sender, + rtc::scoped_refptr> + receiver); + + // Returns the first RtpTransceiver suitable for a newly added track, if such + // transceiver is available. + rtc::scoped_refptr> + FindFirstTransceiverForAddedTrack( + rtc::scoped_refptr track); + + // Returns the list of senders currently associated with some + // registered transceiver + std::vector>> + GetSendersInternal() const; + + // Returns the list of receivers currently associated with a transceiver + std::vector< + rtc::scoped_refptr>> + GetReceiversInternal() const; + + // Plan B: Get the transceiver containing all audio senders and receivers + rtc::scoped_refptr> + GetAudioTransceiver() const; + // Plan B: Get the transceiver containing all video senders and receivers + rtc::scoped_refptr> + GetVideoTransceiver() const; + + // Add an audio track, reusing or creating the sender. + void AddAudioTrack(AudioTrackInterface* track, MediaStreamInterface* stream); + // Plan B: Remove an audio track, removing the sender. + void RemoveAudioTrack(AudioTrackInterface* track, + MediaStreamInterface* stream); + // Add a video track, reusing or creating the sender. + void AddVideoTrack(VideoTrackInterface* track, MediaStreamInterface* stream); + // Plan B: Remove a video track, removing the sender. + void RemoveVideoTrack(VideoTrackInterface* track, + MediaStreamInterface* stream); + + // Triggered when a remote sender has been seen for the first time in a remote + // session description. It creates a remote MediaStreamTrackInterface + // implementation and triggers CreateAudioReceiver or CreateVideoReceiver. + void OnRemoteSenderAdded(const RtpSenderInfo& sender_info, + MediaStreamInterface* stream, + cricket::MediaType media_type); + + // Triggered when a remote sender has been removed from a remote session + // description. It removes the remote sender with id |sender_id| from a remote + // MediaStream and triggers DestroyAudioReceiver or DestroyVideoReceiver. + void OnRemoteSenderRemoved(const RtpSenderInfo& sender_info, + MediaStreamInterface* stream, + cricket::MediaType media_type); + + // Triggered when a local sender has been seen for the first time in a local + // session description. + // This method triggers CreateAudioSender or CreateVideoSender if the rtp + // streams in the local SessionDescription can be mapped to a MediaStreamTrack + // in a MediaStream in |local_streams_| + void OnLocalSenderAdded(const RtpSenderInfo& sender_info, + cricket::MediaType media_type); + + // Triggered when a local sender has been removed from a local session + // description. + // This method triggers DestroyAudioSender or DestroyVideoSender if a stream + // has been removed from the local SessionDescription and the stream can be + // mapped to a MediaStreamTrack in a MediaStream in |local_streams_|. + void OnLocalSenderRemoved(const RtpSenderInfo& sender_info, + cricket::MediaType media_type); + + std::vector* GetRemoteSenderInfos( + cricket::MediaType media_type); + std::vector* GetLocalSenderInfos( + cricket::MediaType media_type); + const RtpSenderInfo* FindSenderInfo(const std::vector& infos, + const std::string& stream_id, + const std::string sender_id) const; + + // Return the RtpSender with the given track attached. + rtc::scoped_refptr> + FindSenderForTrack(MediaStreamTrackInterface* track) const; + + // Return the RtpSender with the given id, or null if none exists. + rtc::scoped_refptr> + FindSenderById(const std::string& sender_id) const; + + // Return the RtpReceiver with the given id, or null if none exists. + rtc::scoped_refptr> + FindReceiverById(const std::string& receiver_id) const; + + TransceiverList* transceivers() { return &transceivers_; } + const TransceiverList* transceivers() const { return &transceivers_; } + + // Plan B helpers for getting the voice/video media channels for the single + // audio/video transceiver, if it exists. + cricket::VoiceMediaChannel* voice_media_channel() const; + cricket::VideoMediaChannel* video_media_channel() const; + + private: + rtc::Thread* signaling_thread() const { return signaling_thread_; } + rtc::Thread* worker_thread() const { return worker_thread_; } + cricket::ChannelManager* channel_manager() const { return channel_manager_; } + bool IsUnifiedPlan() const { return is_unified_plan_; } + void NoteUsageEvent(UsageEvent event) { + usage_pattern_->NoteUsageEvent(event); + } + + // AddTrack implementation when Unified Plan is specified. + RTCErrorOr> AddTrackUnifiedPlan( + rtc::scoped_refptr track, + const std::vector& stream_ids); + // AddTrack implementation when Plan B is specified. + RTCErrorOr> AddTrackPlanB( + rtc::scoped_refptr track, + const std::vector& stream_ids); + + // Create an RtpReceiver that sources an audio track. + void CreateAudioReceiver(MediaStreamInterface* stream, + const RtpSenderInfo& remote_sender_info) + RTC_RUN_ON(signaling_thread()); + + // Create an RtpReceiver that sources a video track. + void CreateVideoReceiver(MediaStreamInterface* stream, + const RtpSenderInfo& remote_sender_info) + RTC_RUN_ON(signaling_thread()); + rtc::scoped_refptr RemoveAndStopReceiver( + const RtpSenderInfo& remote_sender_info) RTC_RUN_ON(signaling_thread()); + + PeerConnectionObserver* Observer() const; + void OnNegotiationNeeded(); + + TransceiverList transceivers_; + + // These lists store sender info seen in local/remote descriptions. + std::vector remote_audio_sender_infos_ + RTC_GUARDED_BY(signaling_thread()); + std::vector remote_video_sender_infos_ + RTC_GUARDED_BY(signaling_thread()); + std::vector local_audio_sender_infos_ + RTC_GUARDED_BY(signaling_thread()); + std::vector local_video_sender_infos_ + RTC_GUARDED_BY(signaling_thread()); + + bool closed_ = false; + bool const is_unified_plan_; + rtc::Thread* signaling_thread_; + rtc::Thread* worker_thread_; + cricket::ChannelManager* channel_manager_; + UsagePattern* usage_pattern_; + PeerConnectionObserver* observer_; + StatsCollectorInterface* const stats_; + std::function on_negotiation_needed_; + rtc::WeakPtrFactory weak_ptr_factory_ + RTC_GUARDED_BY(signaling_thread()); +}; + +} // namespace webrtc + +#endif // PC_RTP_TRANSMISSION_MANAGER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_transport.cc b/TMessagesProj/jni/voip/webrtc/pc/rtp_transport.cc index fe7357fc9..0f4a820d8 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_transport.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_transport.cc @@ -195,9 +195,14 @@ void RtpTransport::DemuxPacket(rtc::CopyOnWriteBuffer packet, if (!rtp_demuxer_.OnRtpPacket(parsed_packet)) { RTC_LOG(LS_WARNING) << "Failed to demux RTP packet: " << RtpDemuxer::DescribePacket(parsed_packet); + uint32_t ssrc = parsed_packet.Ssrc(); + OnErrorDemuxingPacket(ssrc); } } +void RtpTransport::OnErrorDemuxingPacket(uint32_t ssrc) { +} + bool RtpTransport::IsTransportWritable() { auto rtcp_packet_transport = rtcp_mux_enabled_ ? nullptr : rtcp_packet_transport_; diff --git a/TMessagesProj/jni/voip/webrtc/pc/rtp_transport.h b/TMessagesProj/jni/voip/webrtc/pc/rtp_transport.h index 57ad9e5fd..3191e852b 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/rtp_transport.h +++ b/TMessagesProj/jni/voip/webrtc/pc/rtp_transport.h @@ -76,6 +76,8 @@ class RtpTransport : public RtpTransportInternal { bool UnregisterRtpDemuxerSink(RtpPacketSinkInterface* sink) override; + virtual void OnErrorDemuxingPacket(uint32_t ssrc); + protected: // These methods will be used in the subclasses. void DemuxPacket(rtc::CopyOnWriteBuffer packet, int64_t packet_time_us); diff --git a/TMessagesProj/jni/voip/webrtc/pc/sctp_data_channel.cc b/TMessagesProj/jni/voip/webrtc/pc/sctp_data_channel.cc index e603dddd0..c4357a8da 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/sctp_data_channel.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/sctp_data_channel.cc @@ -21,6 +21,7 @@ #include "rtc_base/location.h" #include "rtc_base/logging.h" #include "rtc_base/ref_counted_object.h" +#include "rtc_base/task_utils/to_queued_task.h" #include "rtc_base/thread.h" namespace webrtc { @@ -206,8 +207,14 @@ bool SctpDataChannel::Init() { // Chrome glue and WebKit) are not wired up properly until after this // function returns. if (provider_->ReadyToSendData()) { - invoker_.AsyncInvoke(RTC_FROM_HERE, rtc::Thread::Current(), - [this] { OnTransportReady(true); }); + AddRef(); + rtc::Thread::Current()->PostTask(ToQueuedTask( + [this] { + RTC_DCHECK_RUN_ON(signaling_thread_); + if (state_ != kClosed) + OnTransportReady(true); + }, + [this] { Release(); })); } return true; diff --git a/TMessagesProj/jni/voip/webrtc/pc/sctp_data_channel.h b/TMessagesProj/jni/voip/webrtc/pc/sctp_data_channel.h index 871f18af5..6d121e6f8 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/sctp_data_channel.h +++ b/TMessagesProj/jni/voip/webrtc/pc/sctp_data_channel.h @@ -21,7 +21,6 @@ #include "api/transport/data_channel_transport_interface.h" #include "media/base/media_channel.h" #include "pc/data_channel_utils.h" -#include "rtc_base/async_invoker.h" #include "rtc_base/ssl_stream_adapter.h" // For SSLRole #include "rtc_base/third_party/sigslot/sigslot.h" @@ -277,7 +276,6 @@ class SctpDataChannel : public DataChannelInterface, PacketQueue queued_control_data_ RTC_GUARDED_BY(signaling_thread_); PacketQueue queued_received_data_ RTC_GUARDED_BY(signaling_thread_); PacketQueue queued_send_data_ RTC_GUARDED_BY(signaling_thread_); - rtc::AsyncInvoker invoker_ RTC_GUARDED_BY(signaling_thread_); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/sdp_offer_answer.cc b/TMessagesProj/jni/voip/webrtc/pc/sdp_offer_answer.cc new file mode 100644 index 000000000..fd697ce8b --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/sdp_offer_answer.cc @@ -0,0 +1,5027 @@ +/* + * Copyright 2020 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 "pc/sdp_offer_answer.h" + +#include +#include +#include +#include +#include +#include + +#include "absl/algorithm/container.h" +#include "absl/memory/memory.h" +#include "absl/strings/string_view.h" +#include "api/array_view.h" +#include "api/crypto/crypto_options.h" +#include "api/data_channel_interface.h" +#include "api/dtls_transport_interface.h" +#include "api/media_stream_proxy.h" +#include "api/rtp_parameters.h" +#include "api/rtp_receiver_interface.h" +#include "api/rtp_sender_interface.h" +#include "api/uma_metrics.h" +#include "api/video/builtin_video_bitrate_allocator_factory.h" +#include "media/base/codec.h" +#include "media/base/media_engine.h" +#include "media/base/rid_description.h" +#include "p2p/base/p2p_constants.h" +#include "p2p/base/p2p_transport_channel.h" +#include "p2p/base/port.h" +#include "p2p/base/transport_description.h" +#include "p2p/base/transport_description_factory.h" +#include "p2p/base/transport_info.h" +#include "pc/connection_context.h" +#include "pc/data_channel_utils.h" +#include "pc/media_protocol_names.h" +#include "pc/media_stream.h" +#include "pc/peer_connection.h" +#include "pc/peer_connection_message_handler.h" +#include "pc/rtp_data_channel.h" +#include "pc/rtp_media_utils.h" +#include "pc/rtp_sender.h" +#include "pc/rtp_transport_internal.h" +#include "pc/sctp_transport.h" +#include "pc/simulcast_description.h" +#include "pc/stats_collector.h" +#include "pc/usage_pattern.h" +#include "pc/webrtc_session_description_factory.h" +#include "rtc_base/bind.h" +#include "rtc_base/helpers.h" +#include "rtc_base/location.h" +#include "rtc_base/logging.h" +#include "rtc_base/ref_counted_object.h" +#include "rtc_base/rtc_certificate.h" +#include "rtc_base/socket_address.h" +#include "rtc_base/ssl_stream_adapter.h" +#include "rtc_base/string_encode.h" +#include "rtc_base/strings/string_builder.h" +#include "rtc_base/third_party/sigslot/sigslot.h" +#include "rtc_base/trace_event.h" +#include "system_wrappers/include/metrics.h" + +using cricket::ContentInfo; +using cricket::ContentInfos; +using cricket::MediaContentDescription; +using cricket::MediaProtocolType; +using cricket::RidDescription; +using cricket::RidDirection; +using cricket::SessionDescription; +using cricket::SimulcastDescription; +using cricket::SimulcastLayer; +using cricket::SimulcastLayerList; +using cricket::StreamParams; +using cricket::TransportInfo; + +using cricket::LOCAL_PORT_TYPE; +using cricket::PRFLX_PORT_TYPE; +using cricket::RELAY_PORT_TYPE; +using cricket::STUN_PORT_TYPE; + +namespace webrtc { + +namespace { + +typedef webrtc::PeerConnectionInterface::RTCOfferAnswerOptions + RTCOfferAnswerOptions; + +// Error messages +const char kInvalidSdp[] = "Invalid session description."; +const char kInvalidCandidates[] = "Description contains invalid candidates."; +const char kBundleWithoutRtcpMux[] = + "rtcp-mux must be enabled when BUNDLE " + "is enabled."; +const char kMlineMismatchInAnswer[] = + "The order of m-lines in answer doesn't match order in offer. Rejecting " + "answer."; +const char kMlineMismatchInSubsequentOffer[] = + "The order of m-lines in subsequent offer doesn't match order from " + "previous offer/answer."; +const char kSdpWithoutIceUfragPwd[] = + "Called with SDP without ice-ufrag and ice-pwd."; +const char kSdpWithoutDtlsFingerprint[] = + "Called with SDP without DTLS fingerprint."; +const char kSdpWithoutSdesCrypto[] = "Called with SDP without SDES crypto."; + +const char kSessionError[] = "Session error code: "; +const char kSessionErrorDesc[] = "Session error description: "; + +// UMA metric names. +const char kSimulcastVersionApplyLocalDescription[] = + "WebRTC.PeerConnection.Simulcast.ApplyLocalDescription"; +const char kSimulcastVersionApplyRemoteDescription[] = + "WebRTC.PeerConnection.Simulcast.ApplyRemoteDescription"; +const char kSimulcastDisabled[] = "WebRTC.PeerConnection.Simulcast.Disabled"; + +// The length of RTCP CNAMEs. +static const int kRtcpCnameLength = 16; + +const char kDefaultStreamId[] = "default"; +// NOTE: Duplicated in peer_connection.cc: +static const char kDefaultAudioSenderId[] = "defaulta0"; +static const char kDefaultVideoSenderId[] = "defaultv0"; + +void NoteAddIceCandidateResult(int result) { + RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.AddIceCandidate", result, + kAddIceCandidateMax); +} + +void NoteKeyProtocolAndMedia(KeyExchangeProtocolType protocol_type, + cricket::MediaType media_type) { + // Array of structs needed to map {KeyExchangeProtocolType, + // cricket::MediaType} to KeyExchangeProtocolMedia without using std::map in + // order to avoid -Wglobal-constructors and -Wexit-time-destructors. + static constexpr struct { + KeyExchangeProtocolType protocol_type; + cricket::MediaType media_type; + KeyExchangeProtocolMedia protocol_media; + } kEnumCounterKeyProtocolMediaMap[] = { + {kEnumCounterKeyProtocolDtls, cricket::MEDIA_TYPE_AUDIO, + kEnumCounterKeyProtocolMediaTypeDtlsAudio}, + {kEnumCounterKeyProtocolDtls, cricket::MEDIA_TYPE_VIDEO, + kEnumCounterKeyProtocolMediaTypeDtlsVideo}, + {kEnumCounterKeyProtocolDtls, cricket::MEDIA_TYPE_DATA, + kEnumCounterKeyProtocolMediaTypeDtlsData}, + {kEnumCounterKeyProtocolSdes, cricket::MEDIA_TYPE_AUDIO, + kEnumCounterKeyProtocolMediaTypeSdesAudio}, + {kEnumCounterKeyProtocolSdes, cricket::MEDIA_TYPE_VIDEO, + kEnumCounterKeyProtocolMediaTypeSdesVideo}, + {kEnumCounterKeyProtocolSdes, cricket::MEDIA_TYPE_DATA, + kEnumCounterKeyProtocolMediaTypeSdesData}, + }; + + RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.KeyProtocol", protocol_type, + kEnumCounterKeyProtocolMax); + + for (const auto& i : kEnumCounterKeyProtocolMediaMap) { + if (i.protocol_type == protocol_type && i.media_type == media_type) { + RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.KeyProtocolByMedia", + i.protocol_media, + kEnumCounterKeyProtocolMediaTypeMax); + } + } +} + +// Returns true if |new_desc| requests an ICE restart (i.e., new ufrag/pwd). +bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc, + const SessionDescriptionInterface* new_desc, + const std::string& content_name) { + if (!old_desc) { + return false; + } + const SessionDescription* new_sd = new_desc->description(); + const SessionDescription* old_sd = old_desc->description(); + const ContentInfo* cinfo = new_sd->GetContentByName(content_name); + if (!cinfo || cinfo->rejected) { + return false; + } + // If the content isn't rejected, check if ufrag and password has changed. + const cricket::TransportDescription* new_transport_desc = + new_sd->GetTransportDescriptionByName(content_name); + const cricket::TransportDescription* old_transport_desc = + old_sd->GetTransportDescriptionByName(content_name); + if (!new_transport_desc || !old_transport_desc) { + // No transport description exists. This is not an ICE restart. + return false; + } + if (cricket::IceCredentialsChanged( + old_transport_desc->ice_ufrag, old_transport_desc->ice_pwd, + new_transport_desc->ice_ufrag, new_transport_desc->ice_pwd)) { + RTC_LOG(LS_INFO) << "Remote peer requests ICE restart for " << content_name + << "."; + return true; + } + return false; +} + +// Generates a string error message for SetLocalDescription/SetRemoteDescription +// from an RTCError. +std::string GetSetDescriptionErrorMessage(cricket::ContentSource source, + SdpType type, + const RTCError& error) { + rtc::StringBuilder oss; + oss << "Failed to set " << (source == cricket::CS_LOCAL ? "local" : "remote") + << " " << SdpTypeToString(type) << " sdp: " << error.message(); + return oss.Release(); +} + +std::string GetStreamIdsString(rtc::ArrayView stream_ids) { + std::string output = "streams=["; + const char* separator = ""; + for (const auto& stream_id : stream_ids) { + output.append(separator).append(stream_id); + separator = ", "; + } + output.append("]"); + return output; +} + +void ReportSimulcastApiVersion(const char* name, + const SessionDescription& session) { + bool has_legacy = false; + bool has_spec_compliant = false; + for (const ContentInfo& content : session.contents()) { + if (!content.media_description()) { + continue; + } + has_spec_compliant |= content.media_description()->HasSimulcast(); + for (const StreamParams& sp : content.media_description()->streams()) { + has_legacy |= sp.has_ssrc_group(cricket::kSimSsrcGroupSemantics); + } + } + + if (has_legacy) { + RTC_HISTOGRAM_ENUMERATION(name, kSimulcastApiVersionLegacy, + kSimulcastApiVersionMax); + } + if (has_spec_compliant) { + RTC_HISTOGRAM_ENUMERATION(name, kSimulcastApiVersionSpecCompliant, + kSimulcastApiVersionMax); + } + if (!has_legacy && !has_spec_compliant) { + RTC_HISTOGRAM_ENUMERATION(name, kSimulcastApiVersionNone, + kSimulcastApiVersionMax); + } +} + +const ContentInfo* FindTransceiverMSection( + RtpTransceiverProxyWithInternal* transceiver, + const SessionDescriptionInterface* session_description) { + return transceiver->mid() + ? session_description->description()->GetContentByName( + *transceiver->mid()) + : nullptr; +} + +// If the direction is "recvonly" or "inactive", treat the description +// as containing no streams. +// See: https://code.google.com/p/webrtc/issues/detail?id=5054 +std::vector GetActiveStreams( + const cricket::MediaContentDescription* desc) { + return RtpTransceiverDirectionHasSend(desc->direction()) + ? desc->streams() + : std::vector(); +} + +// Logic to decide if an m= section can be recycled. This means that the new +// m= section is not rejected, but the old local or remote m= section is +// rejected. |old_content_one| and |old_content_two| refer to the m= section +// of the old remote and old local descriptions in no particular order. +// We need to check both the old local and remote because either +// could be the most current from the latest negotation. +bool IsMediaSectionBeingRecycled(SdpType type, + const ContentInfo& content, + const ContentInfo* old_content_one, + const ContentInfo* old_content_two) { + return type == SdpType::kOffer && !content.rejected && + ((old_content_one && old_content_one->rejected) || + (old_content_two && old_content_two->rejected)); +} + +// Verify that the order of media sections in |new_desc| matches +// |current_desc|. The number of m= sections in |new_desc| should be no +// less than |current_desc|. In the case of checking an answer's +// |new_desc|, the |current_desc| is the last offer that was set as the +// local or remote. In the case of checking an offer's |new_desc| we +// check against the local and remote descriptions stored from the last +// negotiation, because either of these could be the most up to date for +// possible rejected m sections. These are the |current_desc| and +// |secondary_current_desc|. +bool MediaSectionsInSameOrder(const SessionDescription& current_desc, + const SessionDescription* secondary_current_desc, + const SessionDescription& new_desc, + const SdpType type) { + if (current_desc.contents().size() > new_desc.contents().size()) { + return false; + } + + for (size_t i = 0; i < current_desc.contents().size(); ++i) { + const cricket::ContentInfo* secondary_content_info = nullptr; + if (secondary_current_desc && + i < secondary_current_desc->contents().size()) { + secondary_content_info = &secondary_current_desc->contents()[i]; + } + if (IsMediaSectionBeingRecycled(type, new_desc.contents()[i], + ¤t_desc.contents()[i], + secondary_content_info)) { + // For new offer descriptions, if the media section can be recycled, it's + // valid for the MID and media type to change. + continue; + } + if (new_desc.contents()[i].name != current_desc.contents()[i].name) { + return false; + } + const MediaContentDescription* new_desc_mdesc = + new_desc.contents()[i].media_description(); + const MediaContentDescription* current_desc_mdesc = + current_desc.contents()[i].media_description(); + if (new_desc_mdesc->type() != current_desc_mdesc->type()) { + return false; + } + } + return true; +} + +bool MediaSectionsHaveSameCount(const SessionDescription& desc1, + const SessionDescription& desc2) { + return desc1.contents().size() == desc2.contents().size(); +} +// Checks that each non-rejected content has SDES crypto keys or a DTLS +// fingerprint, unless it's in a BUNDLE group, in which case only the +// BUNDLE-tag section (first media section/description in the BUNDLE group) +// needs a ufrag and pwd. Mismatches, such as replying with a DTLS fingerprint +// to SDES keys, will be caught in JsepTransport negotiation, and backstopped +// by Channel's |srtp_required| check. +RTCError VerifyCrypto(const SessionDescription* desc, bool dtls_enabled) { + const cricket::ContentGroup* bundle = + desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); + for (const cricket::ContentInfo& content_info : desc->contents()) { + if (content_info.rejected) { + continue; + } + // Note what media is used with each crypto protocol, for all sections. + NoteKeyProtocolAndMedia(dtls_enabled ? webrtc::kEnumCounterKeyProtocolDtls + : webrtc::kEnumCounterKeyProtocolSdes, + content_info.media_description()->type()); + const std::string& mid = content_info.name; + if (bundle && bundle->HasContentName(mid) && + mid != *(bundle->FirstContentName())) { + // This isn't the first media section in the BUNDLE group, so it's not + // required to have crypto attributes, since only the crypto attributes + // from the first section actually get used. + continue; + } + + // If the content isn't rejected or bundled into another m= section, crypto + // must be present. + const MediaContentDescription* media = content_info.media_description(); + const TransportInfo* tinfo = desc->GetTransportInfoByName(mid); + if (!media || !tinfo) { + // Something is not right. + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, kInvalidSdp); + } + if (dtls_enabled) { + if (!tinfo->description.identity_fingerprint) { + RTC_LOG(LS_WARNING) + << "Session description must have DTLS fingerprint if " + "DTLS enabled."; + return RTCError(RTCErrorType::INVALID_PARAMETER, + kSdpWithoutDtlsFingerprint); + } + } else { + if (media->cryptos().empty()) { + RTC_LOG(LS_WARNING) + << "Session description must have SDES when DTLS disabled."; + return RTCError(RTCErrorType::INVALID_PARAMETER, kSdpWithoutSdesCrypto); + } + } + } + return RTCError::OK(); +} + +// Checks that each non-rejected content has ice-ufrag and ice-pwd set, unless +// it's in a BUNDLE group, in which case only the BUNDLE-tag section (first +// media section/description in the BUNDLE group) needs a ufrag and pwd. +bool VerifyIceUfragPwdPresent(const SessionDescription* desc) { + const cricket::ContentGroup* bundle = + desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); + for (const cricket::ContentInfo& content_info : desc->contents()) { + if (content_info.rejected) { + continue; + } + const std::string& mid = content_info.name; + if (bundle && bundle->HasContentName(mid) && + mid != *(bundle->FirstContentName())) { + // This isn't the first media section in the BUNDLE group, so it's not + // required to have ufrag/password, since only the ufrag/password from + // the first section actually get used. + continue; + } + + // If the content isn't rejected or bundled into another m= section, + // ice-ufrag and ice-pwd must be present. + const TransportInfo* tinfo = desc->GetTransportInfoByName(mid); + if (!tinfo) { + // Something is not right. + RTC_LOG(LS_ERROR) << kInvalidSdp; + return false; + } + if (tinfo->description.ice_ufrag.empty() || + tinfo->description.ice_pwd.empty()) { + RTC_LOG(LS_ERROR) << "Session description must have ice ufrag and pwd."; + return false; + } + } + return true; +} + +static RTCError ValidateMids(const cricket::SessionDescription& description) { + std::set mids; + for (const cricket::ContentInfo& content : description.contents()) { + if (content.name.empty()) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + "A media section is missing a MID attribute."); + } + if (!mids.insert(content.name).second) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + "Duplicate a=mid value '" + content.name + "'."); + } + } + return RTCError::OK(); +} + +bool IsValidOfferToReceiveMedia(int value) { + typedef PeerConnectionInterface::RTCOfferAnswerOptions Options; + return (value >= Options::kUndefined) && + (value <= Options::kMaxOfferToReceiveMedia); +} + +bool ValidateOfferAnswerOptions( + const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options) { + return IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_audio) && + IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_video); +} + +// Map internal signaling state name to spec name: +// https://w3c.github.io/webrtc-pc/#rtcsignalingstate-enum +std::string GetSignalingStateString( + PeerConnectionInterface::SignalingState state) { + switch (state) { + case PeerConnectionInterface::kStable: + return "stable"; + case PeerConnectionInterface::kHaveLocalOffer: + return "have-local-offer"; + case PeerConnectionInterface::kHaveLocalPrAnswer: + return "have-local-pranswer"; + case PeerConnectionInterface::kHaveRemoteOffer: + return "have-remote-offer"; + case PeerConnectionInterface::kHaveRemotePrAnswer: + return "have-remote-pranswer"; + case PeerConnectionInterface::kClosed: + return "closed"; + } + RTC_NOTREACHED(); + return ""; +} + +// This method will extract any send encodings that were sent by the remote +// connection. This is currently only relevant for Simulcast scenario (where +// the number of layers may be communicated by the server). +static std::vector GetSendEncodingsFromRemoteDescription( + const MediaContentDescription& desc) { + if (!desc.HasSimulcast()) { + return {}; + } + std::vector result; + const SimulcastDescription& simulcast = desc.simulcast_description(); + + // This is a remote description, the parameters we are after should appear + // as receive streams. + for (const auto& alternatives : simulcast.receive_layers()) { + RTC_DCHECK(!alternatives.empty()); + // There is currently no way to specify or choose from alternatives. + // We will always use the first alternative, which is the most preferred. + const SimulcastLayer& layer = alternatives[0]; + RtpEncodingParameters parameters; + parameters.rid = layer.rid; + parameters.active = !layer.is_paused; + result.push_back(parameters); + } + + return result; +} + +static RTCError UpdateSimulcastLayerStatusInSender( + const std::vector& layers, + rtc::scoped_refptr sender) { + RTC_DCHECK(sender); + RtpParameters parameters = sender->GetParametersInternal(); + std::vector disabled_layers; + + // The simulcast envelope cannot be changed, only the status of the streams. + // So we will iterate over the send encodings rather than the layers. + for (RtpEncodingParameters& encoding : parameters.encodings) { + auto iter = std::find_if(layers.begin(), layers.end(), + [&encoding](const SimulcastLayer& layer) { + return layer.rid == encoding.rid; + }); + // A layer that cannot be found may have been removed by the remote party. + if (iter == layers.end()) { + disabled_layers.push_back(encoding.rid); + continue; + } + + encoding.active = !iter->is_paused; + } + + RTCError result = sender->SetParametersInternal(parameters); + if (result.ok()) { + result = sender->DisableEncodingLayers(disabled_layers); + } + + return result; +} + +static bool SimulcastIsRejected( + const ContentInfo* local_content, + const MediaContentDescription& answer_media_desc) { + bool simulcast_offered = local_content && + local_content->media_description() && + local_content->media_description()->HasSimulcast(); + bool simulcast_answered = answer_media_desc.HasSimulcast(); + bool rids_supported = RtpExtension::FindHeaderExtensionByUri( + answer_media_desc.rtp_header_extensions(), RtpExtension::kRidUri); + return simulcast_offered && (!simulcast_answered || !rids_supported); +} + +static RTCError DisableSimulcastInSender( + rtc::scoped_refptr sender) { + RTC_DCHECK(sender); + RtpParameters parameters = sender->GetParametersInternal(); + if (parameters.encodings.size() <= 1) { + return RTCError::OK(); + } + + std::vector disabled_layers; + std::transform( + parameters.encodings.begin() + 1, parameters.encodings.end(), + std::back_inserter(disabled_layers), + [](const RtpEncodingParameters& encoding) { return encoding.rid; }); + return sender->DisableEncodingLayers(disabled_layers); +} + +// The SDP parser used to populate these values by default for the 'content +// name' if an a=mid line was absent. +static absl::string_view GetDefaultMidForPlanB(cricket::MediaType media_type) { + switch (media_type) { + case cricket::MEDIA_TYPE_AUDIO: + return cricket::CN_AUDIO; + case cricket::MEDIA_TYPE_VIDEO: + return cricket::CN_VIDEO; + case cricket::MEDIA_TYPE_DATA: + return cricket::CN_DATA; + case cricket::MEDIA_TYPE_UNSUPPORTED: + return "not supported"; + } + RTC_NOTREACHED(); + return ""; +} + +// Add options to |[audio/video]_media_description_options| from |senders|. +void AddPlanBRtpSenderOptions( + const std::vector>>& senders, + cricket::MediaDescriptionOptions* audio_media_description_options, + cricket::MediaDescriptionOptions* video_media_description_options, + int num_sim_layers) { + for (const auto& sender : senders) { + if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) { + if (audio_media_description_options) { + audio_media_description_options->AddAudioSender( + sender->id(), sender->internal()->stream_ids()); + } + } else { + RTC_DCHECK(sender->media_type() == cricket::MEDIA_TYPE_VIDEO); + if (video_media_description_options) { + video_media_description_options->AddVideoSender( + sender->id(), sender->internal()->stream_ids(), {}, + SimulcastLayerList(), num_sim_layers); + } + } + } +} + +static cricket::MediaDescriptionOptions +GetMediaDescriptionOptionsForTransceiver( + rtc::scoped_refptr> + transceiver, + const std::string& mid, + bool is_create_offer) { + // NOTE: a stopping transceiver should be treated as a stopped one in + // createOffer as specified in + // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer. + bool stopped = + is_create_offer ? transceiver->stopping() : transceiver->stopped(); + cricket::MediaDescriptionOptions media_description_options( + transceiver->media_type(), mid, transceiver->direction(), stopped); + media_description_options.codec_preferences = + transceiver->codec_preferences(); + media_description_options.header_extensions = + transceiver->HeaderExtensionsToOffer(); + // This behavior is specified in JSEP. The gist is that: + // 1. The MSID is included if the RtpTransceiver's direction is sendonly or + // sendrecv. + // 2. If the MSID is included, then it must be included in any subsequent + // offer/answer exactly the same until the RtpTransceiver is stopped. + if (stopped || (!RtpTransceiverDirectionHasSend(transceiver->direction()) && + !transceiver->internal()->has_ever_been_used_to_send())) { + return media_description_options; + } + + cricket::SenderOptions sender_options; + sender_options.track_id = transceiver->sender()->id(); + sender_options.stream_ids = transceiver->sender()->stream_ids(); + + // The following sets up RIDs and Simulcast. + // RIDs are included if Simulcast is requested or if any RID was specified. + RtpParameters send_parameters = + transceiver->internal()->sender_internal()->GetParametersInternal(); + bool has_rids = std::any_of(send_parameters.encodings.begin(), + send_parameters.encodings.end(), + [](const RtpEncodingParameters& encoding) { + return !encoding.rid.empty(); + }); + + std::vector send_rids; + SimulcastLayerList send_layers; + for (const RtpEncodingParameters& encoding : send_parameters.encodings) { + if (encoding.rid.empty()) { + continue; + } + send_rids.push_back(RidDescription(encoding.rid, RidDirection::kSend)); + send_layers.AddLayer(SimulcastLayer(encoding.rid, !encoding.active)); + } + + if (has_rids) { + sender_options.rids = send_rids; + } + + sender_options.simulcast_layers = send_layers; + // When RIDs are configured, we must set num_sim_layers to 0 to. + // Otherwise, num_sim_layers must be 1 because either there is no + // simulcast, or simulcast is acheived by munging the SDP. + sender_options.num_sim_layers = has_rids ? 0 : 1; + media_description_options.sender_options.push_back(sender_options); + + return media_description_options; +} + +// Returns the ContentInfo at mline index |i|, or null if none exists. +static const ContentInfo* GetContentByIndex( + const SessionDescriptionInterface* sdesc, + size_t i) { + if (!sdesc) { + return nullptr; + } + const ContentInfos& contents = sdesc->description()->contents(); + return (i < contents.size() ? &contents[i] : nullptr); +} + +// From |rtc_options|, fill parts of |session_options| shared by all generated +// m= sectionss (in other words, nothing that involves a map/array). +void ExtractSharedMediaSessionOptions( + const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, + cricket::MediaSessionOptions* session_options) { + session_options->vad_enabled = rtc_options.voice_activity_detection; + session_options->bundle_enabled = rtc_options.use_rtp_mux; + session_options->raw_packetization_for_video = + rtc_options.raw_packetization_for_video; +} + +// Generate a RTCP CNAME when a PeerConnection is created. +std::string GenerateRtcpCname() { + std::string cname; + if (!rtc::CreateRandomString(kRtcpCnameLength, &cname)) { + RTC_LOG(LS_ERROR) << "Failed to generate CNAME."; + RTC_NOTREACHED(); + } + return cname; +} + +// Add options to |session_options| from |rtp_data_channels|. +void AddRtpDataChannelOptions( + const std::map>& + rtp_data_channels, + cricket::MediaDescriptionOptions* data_media_description_options) { + if (!data_media_description_options) { + return; + } + // Check for data channels. + for (const auto& kv : rtp_data_channels) { + const RtpDataChannel* channel = kv.second; + if (channel->state() == RtpDataChannel::kConnecting || + channel->state() == RtpDataChannel::kOpen) { + // Legacy RTP data channels are signaled with the track/stream ID set to + // the data channel's label. + data_media_description_options->AddRtpDataChannel(channel->label(), + channel->label()); + } + } +} + +// Check if we can send |new_stream| on a PeerConnection. +bool CanAddLocalMediaStream(webrtc::StreamCollectionInterface* current_streams, + webrtc::MediaStreamInterface* new_stream) { + if (!new_stream || !current_streams) { + return false; + } + if (current_streams->find(new_stream->id()) != nullptr) { + RTC_LOG(LS_ERROR) << "MediaStream with ID " << new_stream->id() + << " is already added."; + return false; + } + return true; +} + +} // namespace + +// Used by parameterless SetLocalDescription() to create an offer or answer. +// Upon completion of creating the session description, SetLocalDescription() is +// invoked with the result. +class SdpOfferAnswerHandler::ImplicitCreateSessionDescriptionObserver + : public CreateSessionDescriptionObserver { + public: + ImplicitCreateSessionDescriptionObserver( + rtc::WeakPtr sdp_handler, + rtc::scoped_refptr + set_local_description_observer) + : sdp_handler_(std::move(sdp_handler)), + set_local_description_observer_( + std::move(set_local_description_observer)) {} + ~ImplicitCreateSessionDescriptionObserver() override { + RTC_DCHECK(was_called_); + } + + void SetOperationCompleteCallback( + std::function operation_complete_callback) { + operation_complete_callback_ = std::move(operation_complete_callback); + } + + bool was_called() const { return was_called_; } + + void OnSuccess(SessionDescriptionInterface* desc_ptr) override { + RTC_DCHECK(!was_called_); + std::unique_ptr desc(desc_ptr); + was_called_ = true; + + // Abort early if |pc_| is no longer valid. + if (!sdp_handler_) { + operation_complete_callback_(); + return; + } + // DoSetLocalDescription() is a synchronous operation that invokes + // |set_local_description_observer_| with the result. + sdp_handler_->DoSetLocalDescription( + std::move(desc), std::move(set_local_description_observer_)); + operation_complete_callback_(); + } + + void OnFailure(RTCError error) override { + RTC_DCHECK(!was_called_); + was_called_ = true; + set_local_description_observer_->OnSetLocalDescriptionComplete(RTCError( + error.type(), std::string("SetLocalDescription failed to create " + "session description - ") + + error.message())); + operation_complete_callback_(); + } + + private: + bool was_called_ = false; + rtc::WeakPtr sdp_handler_; + rtc::scoped_refptr + set_local_description_observer_; + std::function operation_complete_callback_; +}; + +// Wraps a CreateSessionDescriptionObserver and an OperationsChain operation +// complete callback. When the observer is invoked, the wrapped observer is +// invoked followed by invoking the completion callback. +class CreateSessionDescriptionObserverOperationWrapper + : public CreateSessionDescriptionObserver { + public: + CreateSessionDescriptionObserverOperationWrapper( + rtc::scoped_refptr observer, + std::function operation_complete_callback) + : observer_(std::move(observer)), + operation_complete_callback_(std::move(operation_complete_callback)) { + RTC_DCHECK(observer_); + } + ~CreateSessionDescriptionObserverOperationWrapper() override { +#if RTC_DCHECK_IS_ON + RTC_DCHECK(was_called_); +#endif + } + + void OnSuccess(SessionDescriptionInterface* desc) override { +#if RTC_DCHECK_IS_ON + RTC_DCHECK(!was_called_); + was_called_ = true; +#endif // RTC_DCHECK_IS_ON + // Completing the operation before invoking the observer allows the observer + // to execute SetLocalDescription() without delay. + operation_complete_callback_(); + observer_->OnSuccess(desc); + } + + void OnFailure(RTCError error) override { +#if RTC_DCHECK_IS_ON + RTC_DCHECK(!was_called_); + was_called_ = true; +#endif // RTC_DCHECK_IS_ON + operation_complete_callback_(); + observer_->OnFailure(std::move(error)); + } + + private: +#if RTC_DCHECK_IS_ON + bool was_called_ = false; +#endif // RTC_DCHECK_IS_ON + rtc::scoped_refptr observer_; + std::function operation_complete_callback_; +}; + +// Wrapper for SetSessionDescriptionObserver that invokes the success or failure +// callback in a posted message handled by the peer connection. This introduces +// a delay that prevents recursive API calls by the observer, but this also +// means that the PeerConnection can be modified before the observer sees the +// result of the operation. This is ill-advised for synchronizing states. +// +// Implements both the SetLocalDescriptionObserverInterface and the +// SetRemoteDescriptionObserverInterface. +class SdpOfferAnswerHandler::SetSessionDescriptionObserverAdapter + : public SetLocalDescriptionObserverInterface, + public SetRemoteDescriptionObserverInterface { + public: + SetSessionDescriptionObserverAdapter( + rtc::WeakPtr handler, + rtc::scoped_refptr inner_observer) + : handler_(std::move(handler)), + inner_observer_(std::move(inner_observer)) {} + + // SetLocalDescriptionObserverInterface implementation. + void OnSetLocalDescriptionComplete(RTCError error) override { + OnSetDescriptionComplete(std::move(error)); + } + // SetRemoteDescriptionObserverInterface implementation. + void OnSetRemoteDescriptionComplete(RTCError error) override { + OnSetDescriptionComplete(std::move(error)); + } + + private: + void OnSetDescriptionComplete(RTCError error) { + if (!handler_) + return; + if (error.ok()) { + handler_->pc_->message_handler()->PostSetSessionDescriptionSuccess( + inner_observer_); + } else { + handler_->pc_->message_handler()->PostSetSessionDescriptionFailure( + inner_observer_, std::move(error)); + } + } + + rtc::WeakPtr handler_; + rtc::scoped_refptr inner_observer_; +}; + +class SdpOfferAnswerHandler::LocalIceCredentialsToReplace { + public: + // Sets the ICE credentials that need restarting to the ICE credentials of + // the current and pending descriptions. + void SetIceCredentialsFromLocalDescriptions( + const SessionDescriptionInterface* current_local_description, + const SessionDescriptionInterface* pending_local_description) { + ice_credentials_.clear(); + if (current_local_description) { + AppendIceCredentialsFromSessionDescription(*current_local_description); + } + if (pending_local_description) { + AppendIceCredentialsFromSessionDescription(*pending_local_description); + } + } + + void ClearIceCredentials() { ice_credentials_.clear(); } + + // Returns true if we have ICE credentials that need restarting. + bool HasIceCredentials() const { return !ice_credentials_.empty(); } + + // Returns true if |local_description| shares no ICE credentials with the + // ICE credentials that need restarting. + bool SatisfiesIceRestart( + const SessionDescriptionInterface& local_description) const { + for (const auto& transport_info : + local_description.description()->transport_infos()) { + if (ice_credentials_.find(std::make_pair( + transport_info.description.ice_ufrag, + transport_info.description.ice_pwd)) != ice_credentials_.end()) { + return false; + } + } + return true; + } + + private: + void AppendIceCredentialsFromSessionDescription( + const SessionDescriptionInterface& desc) { + for (const auto& transport_info : desc.description()->transport_infos()) { + ice_credentials_.insert( + std::make_pair(transport_info.description.ice_ufrag, + transport_info.description.ice_pwd)); + } + } + + std::set> ice_credentials_; +}; + +SdpOfferAnswerHandler::SdpOfferAnswerHandler(PeerConnection* pc) + : pc_(pc), + local_streams_(StreamCollection::Create()), + remote_streams_(StreamCollection::Create()), + operations_chain_(rtc::OperationsChain::Create()), + rtcp_cname_(GenerateRtcpCname()), + local_ice_credentials_to_replace_(new LocalIceCredentialsToReplace()), + weak_ptr_factory_(this) { + operations_chain_->SetOnChainEmptyCallback( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr()]() { + if (!this_weak_ptr) + return; + this_weak_ptr->OnOperationsChainEmpty(); + }); +} + +SdpOfferAnswerHandler::~SdpOfferAnswerHandler() {} + +// Static +std::unique_ptr SdpOfferAnswerHandler::Create( + PeerConnection* pc, + const PeerConnectionInterface::RTCConfiguration& configuration, + PeerConnectionDependencies& dependencies) { + auto handler = absl::WrapUnique(new SdpOfferAnswerHandler(pc)); + handler->Initialize(configuration, dependencies); + return handler; +} + +void SdpOfferAnswerHandler::Initialize( + const PeerConnectionInterface::RTCConfiguration& configuration, + PeerConnectionDependencies& dependencies) { + RTC_DCHECK_RUN_ON(signaling_thread()); + video_options_.screencast_min_bitrate_kbps = + configuration.screencast_min_bitrate; + audio_options_.combined_audio_video_bwe = + configuration.combined_audio_video_bwe; + + audio_options_.audio_jitter_buffer_max_packets = + configuration.audio_jitter_buffer_max_packets; + + audio_options_.audio_jitter_buffer_fast_accelerate = + configuration.audio_jitter_buffer_fast_accelerate; + + audio_options_.audio_jitter_buffer_min_delay_ms = + configuration.audio_jitter_buffer_min_delay_ms; + + audio_options_.audio_jitter_buffer_enable_rtx_handling = + configuration.audio_jitter_buffer_enable_rtx_handling; + + // Obtain a certificate from RTCConfiguration if any were provided (optional). + rtc::scoped_refptr certificate; + if (!configuration.certificates.empty()) { + // TODO(hbos,torbjorng): Decide on certificate-selection strategy instead of + // just picking the first one. The decision should be made based on the DTLS + // handshake. The DTLS negotiations need to know about all certificates. + certificate = configuration.certificates[0]; + } + + webrtc_session_desc_factory_ = + std::make_unique( + signaling_thread(), channel_manager(), this, pc_->session_id(), + pc_->dtls_enabled(), std::move(dependencies.cert_generator), + certificate, &ssrc_generator_, + [this](const rtc::scoped_refptr& certificate) { + transport_controller()->SetLocalCertificate(certificate); + }); + + if (pc_->options()->disable_encryption) { + webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); + } + + webrtc_session_desc_factory_->set_enable_encrypted_rtp_header_extensions( + pc_->GetCryptoOptions().srtp.enable_encrypted_rtp_header_extensions); + webrtc_session_desc_factory_->set_is_unified_plan(IsUnifiedPlan()); + + if (dependencies.video_bitrate_allocator_factory) { + video_bitrate_allocator_factory_ = + std::move(dependencies.video_bitrate_allocator_factory); + } else { + video_bitrate_allocator_factory_ = + CreateBuiltinVideoBitrateAllocatorFactory(); + } +} + +// ================================================================== +// Access to pc_ variables +cricket::ChannelManager* SdpOfferAnswerHandler::channel_manager() const { + return pc_->channel_manager(); +} +TransceiverList* SdpOfferAnswerHandler::transceivers() { + if (!pc_->rtp_manager()) { + return nullptr; + } + return pc_->rtp_manager()->transceivers(); +} +const TransceiverList* SdpOfferAnswerHandler::transceivers() const { + if (!pc_->rtp_manager()) { + return nullptr; + } + return pc_->rtp_manager()->transceivers(); +} +JsepTransportController* SdpOfferAnswerHandler::transport_controller() { + return pc_->transport_controller(); +} +const JsepTransportController* SdpOfferAnswerHandler::transport_controller() + const { + return pc_->transport_controller(); +} +DataChannelController* SdpOfferAnswerHandler::data_channel_controller() { + return pc_->data_channel_controller(); +} +const DataChannelController* SdpOfferAnswerHandler::data_channel_controller() + const { + return pc_->data_channel_controller(); +} +cricket::PortAllocator* SdpOfferAnswerHandler::port_allocator() { + return pc_->port_allocator(); +} +const cricket::PortAllocator* SdpOfferAnswerHandler::port_allocator() const { + return pc_->port_allocator(); +} +RtpTransmissionManager* SdpOfferAnswerHandler::rtp_manager() { + return pc_->rtp_manager(); +} +const RtpTransmissionManager* SdpOfferAnswerHandler::rtp_manager() const { + return pc_->rtp_manager(); +} + +// =================================================================== + +void SdpOfferAnswerHandler::PrepareForShutdown() { + RTC_DCHECK_RUN_ON(signaling_thread()); + weak_ptr_factory_.InvalidateWeakPtrs(); +} + +void SdpOfferAnswerHandler::Close() { + ChangeSignalingState(PeerConnectionInterface::kClosed); +} + +void SdpOfferAnswerHandler::RestartIce() { + RTC_DCHECK_RUN_ON(signaling_thread()); + local_ice_credentials_to_replace_->SetIceCredentialsFromLocalDescriptions( + current_local_description(), pending_local_description()); + UpdateNegotiationNeeded(); +} + +rtc::Thread* SdpOfferAnswerHandler::signaling_thread() const { + return pc_->signaling_thread(); +} + +void SdpOfferAnswerHandler::CreateOffer( + CreateSessionDescriptionObserver* observer, + const PeerConnectionInterface::RTCOfferAnswerOptions& options) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Chain this operation. If asynchronous operations are pending on the chain, + // this operation will be queued to be invoked, otherwise the contents of the + // lambda will execute immediately. + operations_chain_->ChainOperation( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), + observer_refptr = + rtc::scoped_refptr(observer), + options](std::function operations_chain_callback) { + // Abort early if |this_weak_ptr| is no longer valid. + if (!this_weak_ptr) { + observer_refptr->OnFailure( + RTCError(RTCErrorType::INTERNAL_ERROR, + "CreateOffer failed because the session was shut down")); + operations_chain_callback(); + return; + } + // The operation completes asynchronously when the wrapper is invoked. + rtc::scoped_refptr + observer_wrapper(new rtc::RefCountedObject< + CreateSessionDescriptionObserverOperationWrapper>( + std::move(observer_refptr), + std::move(operations_chain_callback))); + this_weak_ptr->DoCreateOffer(options, observer_wrapper); + }); +} + +void SdpOfferAnswerHandler::SetLocalDescription( + SetSessionDescriptionObserver* observer, + SessionDescriptionInterface* desc_ptr) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Chain this operation. If asynchronous operations are pending on the chain, + // this operation will be queued to be invoked, otherwise the contents of the + // lambda will execute immediately. + operations_chain_->ChainOperation( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), + observer_refptr = + rtc::scoped_refptr(observer), + desc = std::unique_ptr(desc_ptr)]( + std::function operations_chain_callback) mutable { + // Abort early if |this_weak_ptr| is no longer valid. + if (!this_weak_ptr) { + // For consistency with SetSessionDescriptionObserverAdapter whose + // posted messages doesn't get processed when the PC is destroyed, we + // do not inform |observer_refptr| that the operation failed. + operations_chain_callback(); + return; + } + // SetSessionDescriptionObserverAdapter takes care of making sure the + // |observer_refptr| is invoked in a posted message. + this_weak_ptr->DoSetLocalDescription( + std::move(desc), + rtc::scoped_refptr( + new rtc::RefCountedObject( + this_weak_ptr, observer_refptr))); + // For backwards-compatability reasons, we declare the operation as + // completed here (rather than in a post), so that the operation chain + // is not blocked by this operation when the observer is invoked. This + // allows the observer to trigger subsequent offer/answer operations + // synchronously if the operation chain is now empty. + operations_chain_callback(); + }); +} + +void SdpOfferAnswerHandler::SetLocalDescription( + std::unique_ptr desc, + rtc::scoped_refptr observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Chain this operation. If asynchronous operations are pending on the chain, + // this operation will be queued to be invoked, otherwise the contents of the + // lambda will execute immediately. + operations_chain_->ChainOperation( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), observer, + desc = std::move(desc)]( + std::function operations_chain_callback) mutable { + // Abort early if |this_weak_ptr| is no longer valid. + if (!this_weak_ptr) { + observer->OnSetLocalDescriptionComplete(RTCError( + RTCErrorType::INTERNAL_ERROR, + "SetLocalDescription failed because the session was shut down")); + operations_chain_callback(); + return; + } + this_weak_ptr->DoSetLocalDescription(std::move(desc), observer); + // DoSetLocalDescription() is implemented as a synchronous operation. + // The |observer| will already have been informed that it completed, and + // we can mark this operation as complete without any loose ends. + operations_chain_callback(); + }); +} + +void SdpOfferAnswerHandler::SetLocalDescription( + SetSessionDescriptionObserver* observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); + SetLocalDescription( + new rtc::RefCountedObject( + weak_ptr_factory_.GetWeakPtr(), observer)); +} + +void SdpOfferAnswerHandler::SetLocalDescription( + rtc::scoped_refptr observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // The |create_sdp_observer| handles performing DoSetLocalDescription() with + // the resulting description as well as completing the operation. + rtc::scoped_refptr + create_sdp_observer( + new rtc::RefCountedObject( + weak_ptr_factory_.GetWeakPtr(), observer)); + // Chain this operation. If asynchronous operations are pending on the chain, + // this operation will be queued to be invoked, otherwise the contents of the + // lambda will execute immediately. + operations_chain_->ChainOperation( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), + create_sdp_observer](std::function operations_chain_callback) { + // The |create_sdp_observer| is responsible for completing the + // operation. + create_sdp_observer->SetOperationCompleteCallback( + std::move(operations_chain_callback)); + // Abort early if |this_weak_ptr| is no longer valid. This triggers the + // same code path as if DoCreateOffer() or DoCreateAnswer() failed. + if (!this_weak_ptr) { + create_sdp_observer->OnFailure(RTCError( + RTCErrorType::INTERNAL_ERROR, + "SetLocalDescription failed because the session was shut down")); + return; + } + switch (this_weak_ptr->signaling_state()) { + case PeerConnectionInterface::kStable: + case PeerConnectionInterface::kHaveLocalOffer: + case PeerConnectionInterface::kHaveRemotePrAnswer: + // TODO(hbos): If [LastCreatedOffer] exists and still represents the + // current state of the system, use that instead of creating another + // offer. + this_weak_ptr->DoCreateOffer( + PeerConnectionInterface::RTCOfferAnswerOptions(), + create_sdp_observer); + break; + case PeerConnectionInterface::kHaveLocalPrAnswer: + case PeerConnectionInterface::kHaveRemoteOffer: + // TODO(hbos): If [LastCreatedAnswer] exists and still represents + // the current state of the system, use that instead of creating + // another answer. + this_weak_ptr->DoCreateAnswer( + PeerConnectionInterface::RTCOfferAnswerOptions(), + create_sdp_observer); + break; + case PeerConnectionInterface::kClosed: + create_sdp_observer->OnFailure(RTCError( + RTCErrorType::INVALID_STATE, + "SetLocalDescription called when PeerConnection is closed.")); + break; + } + }); +} + +RTCError SdpOfferAnswerHandler::ApplyLocalDescription( + std::unique_ptr desc) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(desc); + + // Update stats here so that we have the most recent stats for tracks and + // streams that might be removed by updating the session description. + pc_->stats()->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard); + + // Take a reference to the old local description since it's used below to + // compare against the new local description. When setting the new local + // description, grab ownership of the replaced session description in case it + // is the same as |old_local_description|, to keep it alive for the duration + // of the method. + const SessionDescriptionInterface* old_local_description = + local_description(); + std::unique_ptr replaced_local_description; + SdpType type = desc->GetType(); + if (type == SdpType::kAnswer) { + replaced_local_description = pending_local_description_ + ? std::move(pending_local_description_) + : std::move(current_local_description_); + current_local_description_ = std::move(desc); + pending_local_description_ = nullptr; + current_remote_description_ = std::move(pending_remote_description_); + } else { + replaced_local_description = std::move(pending_local_description_); + pending_local_description_ = std::move(desc); + } + // The session description to apply now must be accessed by + // |local_description()|. + RTC_DCHECK(local_description()); + + // Report statistics about any use of simulcast. + ReportSimulcastApiVersion(kSimulcastVersionApplyLocalDescription, + *local_description()->description()); + + if (!is_caller_) { + if (remote_description()) { + // Remote description was applied first, so this PC is the callee. + is_caller_ = false; + } else { + // Local description is applied first, so this PC is the caller. + is_caller_ = true; + } + } + + RTCError error = PushdownTransportDescription(cricket::CS_LOCAL, type); + if (!error.ok()) { + return error; + } + + if (IsUnifiedPlan()) { + RTCError error = UpdateTransceiversAndDataChannels( + cricket::CS_LOCAL, *local_description(), old_local_description, + remote_description()); + if (!error.ok()) { + return error; + } + std::vector> remove_list; + std::vector> removed_streams; + for (const auto& transceiver : transceivers()->List()) { + if (transceiver->stopped()) { + continue; + } + + // 2.2.7.1.1.(6-9): Set sender and receiver's transport slots. + // Note that code paths that don't set MID won't be able to use + // information about DTLS transports. + if (transceiver->mid()) { + auto dtls_transport = transport_controller()->LookupDtlsTransportByMid( + *transceiver->mid()); + transceiver->internal()->sender_internal()->set_transport( + dtls_transport); + transceiver->internal()->receiver_internal()->set_transport( + dtls_transport); + } + + const ContentInfo* content = + FindMediaSectionForTransceiver(transceiver, local_description()); + if (!content) { + continue; + } + const MediaContentDescription* media_desc = content->media_description(); + // 2.2.7.1.6: If description is of type "answer" or "pranswer", then run + // the following steps: + if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) { + // 2.2.7.1.6.1: If direction is "sendonly" or "inactive", and + // transceiver's [[FiredDirection]] slot is either "sendrecv" or + // "recvonly", process the removal of a remote track for the media + // description, given transceiver, removeList, and muteTracks. + if (!RtpTransceiverDirectionHasRecv(media_desc->direction()) && + (transceiver->internal()->fired_direction() && + RtpTransceiverDirectionHasRecv( + *transceiver->internal()->fired_direction()))) { + ProcessRemovalOfRemoteTrack(transceiver, &remove_list, + &removed_streams); + } + // 2.2.7.1.6.2: Set transceiver's [[CurrentDirection]] and + // [[FiredDirection]] slots to direction. + transceiver->internal()->set_current_direction(media_desc->direction()); + transceiver->internal()->set_fired_direction(media_desc->direction()); + } + } + auto observer = pc_->Observer(); + for (const auto& transceiver : remove_list) { + observer->OnRemoveTrack(transceiver->receiver()); + } + for (const auto& stream : removed_streams) { + observer->OnRemoveStream(stream); + } + } else { + // Media channels will be created only when offer is set. These may use new + // transports just created by PushdownTransportDescription. + if (type == SdpType::kOffer) { + // TODO(bugs.webrtc.org/4676) - Handle CreateChannel failure, as new local + // description is applied. Restore back to old description. + RTCError error = CreateChannels(*local_description()->description()); + if (!error.ok()) { + return error; + } + } + // Remove unused channels if MediaContentDescription is rejected. + RemoveUnusedChannels(local_description()->description()); + } + + error = UpdateSessionState(type, cricket::CS_LOCAL, + local_description()->description()); + if (!error.ok()) { + return error; + } + + if (remote_description()) { + // Now that we have a local description, we can push down remote candidates. + UseCandidatesInSessionDescription(remote_description()); + } + + pending_ice_restarts_.clear(); + if (session_error() != SessionError::kNone) { + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, GetSessionErrorMsg()); + } + + // If setting the description decided our SSL role, allocate any necessary + // SCTP sids. + rtc::SSLRole role; + if (IsSctpLike(pc_->data_channel_type()) && pc_->GetSctpSslRole(&role)) { + data_channel_controller()->AllocateSctpSids(role); + } + + if (IsUnifiedPlan()) { + for (const auto& transceiver : transceivers()->List()) { + if (transceiver->stopped()) { + continue; + } + const ContentInfo* content = + FindMediaSectionForTransceiver(transceiver, local_description()); + if (!content) { + continue; + } + cricket::ChannelInterface* channel = transceiver->internal()->channel(); + if (content->rejected || !channel || channel->local_streams().empty()) { + // 0 is a special value meaning "this sender has no associated send + // stream". Need to call this so the sender won't attempt to configure + // a no longer existing stream and run into DCHECKs in the lower + // layers. + transceiver->internal()->sender_internal()->SetSsrc(0); + } else { + // Get the StreamParams from the channel which could generate SSRCs. + const std::vector& streams = channel->local_streams(); + transceiver->internal()->sender_internal()->set_stream_ids( + streams[0].stream_ids()); + transceiver->internal()->sender_internal()->SetSsrc( + streams[0].first_ssrc()); + } + } + } else { + // Plan B semantics. + + // Update state and SSRC of local MediaStreams and DataChannels based on the + // local session description. + const cricket::ContentInfo* audio_content = + GetFirstAudioContent(local_description()->description()); + if (audio_content) { + if (audio_content->rejected) { + RemoveSenders(cricket::MEDIA_TYPE_AUDIO); + } else { + const cricket::AudioContentDescription* audio_desc = + audio_content->media_description()->as_audio(); + UpdateLocalSenders(audio_desc->streams(), audio_desc->type()); + } + } + + const cricket::ContentInfo* video_content = + GetFirstVideoContent(local_description()->description()); + if (video_content) { + if (video_content->rejected) { + RemoveSenders(cricket::MEDIA_TYPE_VIDEO); + } else { + const cricket::VideoContentDescription* video_desc = + video_content->media_description()->as_video(); + UpdateLocalSenders(video_desc->streams(), video_desc->type()); + } + } + } + + const cricket::ContentInfo* data_content = + GetFirstDataContent(local_description()->description()); + if (data_content) { + const cricket::RtpDataContentDescription* rtp_data_desc = + data_content->media_description()->as_rtp_data(); + // rtp_data_desc will be null if this is an SCTP description. + if (rtp_data_desc) { + data_channel_controller()->UpdateLocalRtpDataChannels( + rtp_data_desc->streams()); + } + } + + if (type == SdpType::kAnswer && + local_ice_credentials_to_replace_->SatisfiesIceRestart( + *current_local_description_)) { + local_ice_credentials_to_replace_->ClearIceCredentials(); + } + + return RTCError::OK(); +} + +void SdpOfferAnswerHandler::SetRemoteDescription( + SetSessionDescriptionObserver* observer, + SessionDescriptionInterface* desc_ptr) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Chain this operation. If asynchronous operations are pending on the chain, + // this operation will be queued to be invoked, otherwise the contents of the + // lambda will execute immediately. + operations_chain_->ChainOperation( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), + observer_refptr = + rtc::scoped_refptr(observer), + desc = std::unique_ptr(desc_ptr)]( + std::function operations_chain_callback) mutable { + // Abort early if |this_weak_ptr| is no longer valid. + if (!this_weak_ptr) { + // For consistency with SetSessionDescriptionObserverAdapter whose + // posted messages doesn't get processed when the PC is destroyed, we + // do not inform |observer_refptr| that the operation failed. + operations_chain_callback(); + return; + } + // SetSessionDescriptionObserverAdapter takes care of making sure the + // |observer_refptr| is invoked in a posted message. + this_weak_ptr->DoSetRemoteDescription( + std::move(desc), + rtc::scoped_refptr( + new rtc::RefCountedObject( + this_weak_ptr, observer_refptr))); + // For backwards-compatability reasons, we declare the operation as + // completed here (rather than in a post), so that the operation chain + // is not blocked by this operation when the observer is invoked. This + // allows the observer to trigger subsequent offer/answer operations + // synchronously if the operation chain is now empty. + operations_chain_callback(); + }); +} + +void SdpOfferAnswerHandler::SetRemoteDescription( + std::unique_ptr desc, + rtc::scoped_refptr observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Chain this operation. If asynchronous operations are pending on the chain, + // this operation will be queued to be invoked, otherwise the contents of the + // lambda will execute immediately. + operations_chain_->ChainOperation( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), observer, + desc = std::move(desc)]( + std::function operations_chain_callback) mutable { + // Abort early if |this_weak_ptr| is no longer valid. + if (!this_weak_ptr) { + observer->OnSetRemoteDescriptionComplete(RTCError( + RTCErrorType::INTERNAL_ERROR, + "SetRemoteDescription failed because the session was shut down")); + operations_chain_callback(); + return; + } + this_weak_ptr->DoSetRemoteDescription(std::move(desc), + std::move(observer)); + // DoSetRemoteDescription() is implemented as a synchronous operation. + // The |observer| will already have been informed that it completed, and + // we can mark this operation as complete without any loose ends. + operations_chain_callback(); + }); +} + +RTCError SdpOfferAnswerHandler::ApplyRemoteDescription( + std::unique_ptr desc) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(desc); + + // Update stats here so that we have the most recent stats for tracks and + // streams that might be removed by updating the session description. + pc_->stats()->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard); + + // Take a reference to the old remote description since it's used below to + // compare against the new remote description. When setting the new remote + // description, grab ownership of the replaced session description in case it + // is the same as |old_remote_description|, to keep it alive for the duration + // of the method. + const SessionDescriptionInterface* old_remote_description = + remote_description(); + std::unique_ptr replaced_remote_description; + SdpType type = desc->GetType(); + if (type == SdpType::kAnswer) { + replaced_remote_description = pending_remote_description_ + ? std::move(pending_remote_description_) + : std::move(current_remote_description_); + current_remote_description_ = std::move(desc); + pending_remote_description_ = nullptr; + current_local_description_ = std::move(pending_local_description_); + } else { + replaced_remote_description = std::move(pending_remote_description_); + pending_remote_description_ = std::move(desc); + } + // The session description to apply now must be accessed by + // |remote_description()|. + RTC_DCHECK(remote_description()); + + // Report statistics about any use of simulcast. + ReportSimulcastApiVersion(kSimulcastVersionApplyRemoteDescription, + *remote_description()->description()); + + RTCError error = PushdownTransportDescription(cricket::CS_REMOTE, type); + if (!error.ok()) { + return error; + } + // Transport and Media channels will be created only when offer is set. + if (IsUnifiedPlan()) { + RTCError error = UpdateTransceiversAndDataChannels( + cricket::CS_REMOTE, *remote_description(), local_description(), + old_remote_description); + if (!error.ok()) { + return error; + } + } else { + // Media channels will be created only when offer is set. These may use new + // transports just created by PushdownTransportDescription. + if (type == SdpType::kOffer) { + // TODO(mallinath) - Handle CreateChannel failure, as new local + // description is applied. Restore back to old description. + RTCError error = CreateChannels(*remote_description()->description()); + if (!error.ok()) { + return error; + } + } + // Remove unused channels if MediaContentDescription is rejected. + RemoveUnusedChannels(remote_description()->description()); + } + + // NOTE: Candidates allocation will be initiated only when + // SetLocalDescription is called. + error = UpdateSessionState(type, cricket::CS_REMOTE, + remote_description()->description()); + if (!error.ok()) { + return error; + } + + if (local_description() && + !UseCandidatesInSessionDescription(remote_description())) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, kInvalidCandidates); + } + + if (old_remote_description) { + for (const cricket::ContentInfo& content : + old_remote_description->description()->contents()) { + // Check if this new SessionDescription contains new ICE ufrag and + // password that indicates the remote peer requests an ICE restart. + // TODO(deadbeef): When we start storing both the current and pending + // remote description, this should reset pending_ice_restarts and compare + // against the current description. + if (CheckForRemoteIceRestart(old_remote_description, remote_description(), + content.name)) { + if (type == SdpType::kOffer) { + pending_ice_restarts_.insert(content.name); + } + } else { + // We retain all received candidates only if ICE is not restarted. + // When ICE is restarted, all previous candidates belong to an old + // generation and should not be kept. + // TODO(deadbeef): This goes against the W3C spec which says the remote + // description should only contain candidates from the last set remote + // description plus any candidates added since then. We should remove + // this once we're sure it won't break anything. + WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( + old_remote_description, content.name, mutable_remote_description()); + } + } + } + + if (session_error() != SessionError::kNone) { + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, GetSessionErrorMsg()); + } + + // Set the the ICE connection state to connecting since the connection may + // become writable with peer reflexive candidates before any remote candidate + // is signaled. + // TODO(pthatcher): This is a short-term solution for crbug/446908. A real fix + // is to have a new signal the indicates a change in checking state from the + // transport and expose a new checking() member from transport that can be + // read to determine the current checking state. The existing SignalConnecting + // actually means "gathering candidates", so cannot be be used here. + if (remote_description()->GetType() != SdpType::kOffer && + remote_description()->number_of_mediasections() > 0u && + pc_->ice_connection_state() == + PeerConnectionInterface::kIceConnectionNew) { + pc_->SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); + } + + // If setting the description decided our SSL role, allocate any necessary + // SCTP sids. + rtc::SSLRole role; + if (IsSctpLike(pc_->data_channel_type()) && pc_->GetSctpSslRole(&role)) { + data_channel_controller()->AllocateSctpSids(role); + } + + if (IsUnifiedPlan()) { + std::vector> + now_receiving_transceivers; + std::vector> remove_list; + std::vector> added_streams; + std::vector> removed_streams; + for (const auto& transceiver : transceivers()->List()) { + const ContentInfo* content = + FindMediaSectionForTransceiver(transceiver, remote_description()); + if (!content) { + continue; + } + const MediaContentDescription* media_desc = content->media_description(); + RtpTransceiverDirection local_direction = + RtpTransceiverDirectionReversed(media_desc->direction()); + // Roughly the same as steps 2.2.8.6 of section 4.4.1.6 "Set the + // RTCSessionDescription: Set the associated remote streams given + // transceiver.[[Receiver]], msids, addList, and removeList". + // https://w3c.github.io/webrtc-pc/#set-the-rtcsessiondescription + if (RtpTransceiverDirectionHasRecv(local_direction)) { + std::vector stream_ids; + if (!media_desc->streams().empty()) { + // The remote description has signaled the stream IDs. + stream_ids = media_desc->streams()[0].stream_ids(); + } + transceivers() + ->StableState(transceiver) + ->SetRemoteStreamIdsIfUnset(transceiver->receiver()->stream_ids()); + + RTC_LOG(LS_INFO) << "Processing the MSIDs for MID=" << content->name + << " (" << GetStreamIdsString(stream_ids) << ")."; + SetAssociatedRemoteStreams(transceiver->internal()->receiver_internal(), + stream_ids, &added_streams, + &removed_streams); + // From the WebRTC specification, steps 2.2.8.5/6 of section 4.4.1.6 + // "Set the RTCSessionDescription: If direction is sendrecv or recvonly, + // and transceiver's current direction is neither sendrecv nor recvonly, + // process the addition of a remote track for the media description. + if (!transceiver->fired_direction() || + !RtpTransceiverDirectionHasRecv(*transceiver->fired_direction())) { + RTC_LOG(LS_INFO) + << "Processing the addition of a remote track for MID=" + << content->name << "."; + now_receiving_transceivers.push_back(transceiver); + } + } + // 2.2.8.1.9: If direction is "sendonly" or "inactive", and transceiver's + // [[FiredDirection]] slot is either "sendrecv" or "recvonly", process the + // removal of a remote track for the media description, given transceiver, + // removeList, and muteTracks. + if (!RtpTransceiverDirectionHasRecv(local_direction) && + (transceiver->fired_direction() && + RtpTransceiverDirectionHasRecv(*transceiver->fired_direction()))) { + ProcessRemovalOfRemoteTrack(transceiver, &remove_list, + &removed_streams); + } + // 2.2.8.1.10: Set transceiver's [[FiredDirection]] slot to direction. + transceiver->internal()->set_fired_direction(local_direction); + // 2.2.8.1.11: If description is of type "answer" or "pranswer", then run + // the following steps: + if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) { + // 2.2.8.1.11.1: Set transceiver's [[CurrentDirection]] slot to + // direction. + transceiver->internal()->set_current_direction(local_direction); + // 2.2.8.1.11.[3-6]: Set the transport internal slots. + if (transceiver->mid()) { + auto dtls_transport = + transport_controller()->LookupDtlsTransportByMid( + *transceiver->mid()); + transceiver->internal()->sender_internal()->set_transport( + dtls_transport); + transceiver->internal()->receiver_internal()->set_transport( + dtls_transport); + } + } + // 2.2.8.1.12: If the media description is rejected, and transceiver is + // not already stopped, stop the RTCRtpTransceiver transceiver. + if (content->rejected && !transceiver->stopped()) { + RTC_LOG(LS_INFO) << "Stopping transceiver for MID=" << content->name + << " since the media section was rejected."; + transceiver->internal()->StopTransceiverProcedure(); + } + if (!content->rejected && + RtpTransceiverDirectionHasRecv(local_direction)) { + if (!media_desc->streams().empty() && + media_desc->streams()[0].has_ssrcs()) { + uint32_t ssrc = media_desc->streams()[0].first_ssrc(); + transceiver->internal()->receiver_internal()->SetupMediaChannel(ssrc); + } else { + transceiver->internal() + ->receiver_internal() + ->SetupUnsignaledMediaChannel(); + } + } + } + // Once all processing has finished, fire off callbacks. + auto observer = pc_->Observer(); + for (const auto& transceiver : now_receiving_transceivers) { + pc_->stats()->AddTrack(transceiver->receiver()->track()); + observer->OnTrack(transceiver); + observer->OnAddTrack(transceiver->receiver(), + transceiver->receiver()->streams()); + } + for (const auto& stream : added_streams) { + observer->OnAddStream(stream); + } + for (const auto& transceiver : remove_list) { + observer->OnRemoveTrack(transceiver->receiver()); + } + for (const auto& stream : removed_streams) { + observer->OnRemoveStream(stream); + } + } + + const cricket::ContentInfo* audio_content = + GetFirstAudioContent(remote_description()->description()); + const cricket::ContentInfo* video_content = + GetFirstVideoContent(remote_description()->description()); + const cricket::AudioContentDescription* audio_desc = + GetFirstAudioContentDescription(remote_description()->description()); + const cricket::VideoContentDescription* video_desc = + GetFirstVideoContentDescription(remote_description()->description()); + const cricket::RtpDataContentDescription* rtp_data_desc = + GetFirstRtpDataContentDescription(remote_description()->description()); + + // Check if the descriptions include streams, just in case the peer supports + // MSID, but doesn't indicate so with "a=msid-semantic". + if (remote_description()->description()->msid_supported() || + (audio_desc && !audio_desc->streams().empty()) || + (video_desc && !video_desc->streams().empty())) { + remote_peer_supports_msid_ = true; + } + + // We wait to signal new streams until we finish processing the description, + // since only at that point will new streams have all their tracks. + rtc::scoped_refptr new_streams(StreamCollection::Create()); + + if (!IsUnifiedPlan()) { + // TODO(steveanton): When removing RTP senders/receivers in response to a + // rejected media section, there is some cleanup logic that expects the + // voice/ video channel to still be set. But in this method the voice/video + // channel would have been destroyed by the SetRemoteDescription caller + // above so the cleanup that relies on them fails to run. The RemoveSenders + // calls should be moved to right before the DestroyChannel calls to fix + // this. + + // Find all audio rtp streams and create corresponding remote AudioTracks + // and MediaStreams. + if (audio_content) { + if (audio_content->rejected) { + RemoveSenders(cricket::MEDIA_TYPE_AUDIO); + } else { + bool default_audio_track_needed = + !remote_peer_supports_msid_ && + RtpTransceiverDirectionHasSend(audio_desc->direction()); + UpdateRemoteSendersList(GetActiveStreams(audio_desc), + default_audio_track_needed, audio_desc->type(), + new_streams); + } + } + + // Find all video rtp streams and create corresponding remote VideoTracks + // and MediaStreams. + if (video_content) { + if (video_content->rejected) { + RemoveSenders(cricket::MEDIA_TYPE_VIDEO); + } else { + bool default_video_track_needed = + !remote_peer_supports_msid_ && + RtpTransceiverDirectionHasSend(video_desc->direction()); + UpdateRemoteSendersList(GetActiveStreams(video_desc), + default_video_track_needed, video_desc->type(), + new_streams); + } + } + + // If this is an RTP data transport, update the DataChannels with the + // information from the remote peer. + if (rtp_data_desc) { + data_channel_controller()->UpdateRemoteRtpDataChannels( + GetActiveStreams(rtp_data_desc)); + } + + // Iterate new_streams and notify the observer about new MediaStreams. + auto observer = pc_->Observer(); + for (size_t i = 0; i < new_streams->count(); ++i) { + MediaStreamInterface* new_stream = new_streams->at(i); + pc_->stats()->AddStream(new_stream); + observer->OnAddStream( + rtc::scoped_refptr(new_stream)); + } + + UpdateEndedRemoteMediaStreams(); + } + + if (type == SdpType::kAnswer && + local_ice_credentials_to_replace_->SatisfiesIceRestart( + *current_local_description_)) { + local_ice_credentials_to_replace_->ClearIceCredentials(); + } + + return RTCError::OK(); +} + +void SdpOfferAnswerHandler::DoSetLocalDescription( + std::unique_ptr desc, + rtc::scoped_refptr observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); + TRACE_EVENT0("webrtc", "SdpOfferAnswerHandler::DoSetLocalDescription"); + + if (!observer) { + RTC_LOG(LS_ERROR) << "SetLocalDescription - observer is NULL."; + return; + } + + if (!desc) { + observer->OnSetLocalDescriptionComplete( + RTCError(RTCErrorType::INTERNAL_ERROR, "SessionDescription is NULL.")); + return; + } + + // If a session error has occurred the PeerConnection is in a possibly + // inconsistent state so fail right away. + if (session_error() != SessionError::kNone) { + std::string error_message = GetSessionErrorMsg(); + RTC_LOG(LS_ERROR) << "SetLocalDescription: " << error_message; + observer->OnSetLocalDescriptionComplete( + RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); + return; + } + + // For SLD we support only explicit rollback. + if (desc->GetType() == SdpType::kRollback) { + if (IsUnifiedPlan()) { + observer->OnSetLocalDescriptionComplete(Rollback(desc->GetType())); + } else { + observer->OnSetLocalDescriptionComplete( + RTCError(RTCErrorType::UNSUPPORTED_OPERATION, + "Rollback not supported in Plan B")); + } + return; + } + + RTCError error = ValidateSessionDescription(desc.get(), cricket::CS_LOCAL); + if (!error.ok()) { + std::string error_message = GetSetDescriptionErrorMessage( + cricket::CS_LOCAL, desc->GetType(), error); + RTC_LOG(LS_ERROR) << error_message; + observer->OnSetLocalDescriptionComplete( + RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); + return; + } + + // Grab the description type before moving ownership to ApplyLocalDescription, + // which may destroy it before returning. + const SdpType type = desc->GetType(); + + error = ApplyLocalDescription(std::move(desc)); + // |desc| may be destroyed at this point. + + if (!error.ok()) { + // If ApplyLocalDescription fails, the PeerConnection could be in an + // inconsistent state, so act conservatively here and set the session error + // so that future calls to SetLocalDescription/SetRemoteDescription fail. + SetSessionError(SessionError::kContent, error.message()); + std::string error_message = + GetSetDescriptionErrorMessage(cricket::CS_LOCAL, type, error); + RTC_LOG(LS_ERROR) << error_message; + observer->OnSetLocalDescriptionComplete( + RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); + return; + } + RTC_DCHECK(local_description()); + + if (local_description()->GetType() == SdpType::kAnswer) { + RemoveStoppedTransceivers(); + + // TODO(deadbeef): We already had to hop to the network thread for + // MaybeStartGathering... + pc_->network_thread()->Invoke( + RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::DiscardCandidatePool, + port_allocator())); + // Make UMA notes about what was agreed to. + ReportNegotiatedSdpSemantics(*local_description()); + } + + observer->OnSetLocalDescriptionComplete(RTCError::OK()); + pc_->NoteUsageEvent(UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED); + + // Check if negotiation is needed. We must do this after informing the + // observer that SetLocalDescription() has completed to ensure negotiation is + // not needed prior to the promise resolving. + if (IsUnifiedPlan()) { + bool was_negotiation_needed = is_negotiation_needed_; + UpdateNegotiationNeeded(); + if (signaling_state() == PeerConnectionInterface::kStable && + was_negotiation_needed && is_negotiation_needed_) { + // Legacy version. + pc_->Observer()->OnRenegotiationNeeded(); + // Spec-compliant version; the event may get invalidated before firing. + GenerateNegotiationNeededEvent(); + } + } + + // MaybeStartGathering needs to be called after informing the observer so that + // we don't signal any candidates before signaling that SetLocalDescription + // completed. + transport_controller()->MaybeStartGathering(); +} + +void SdpOfferAnswerHandler::DoCreateOffer( + const PeerConnectionInterface::RTCOfferAnswerOptions& options, + rtc::scoped_refptr observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); + TRACE_EVENT0("webrtc", "SdpOfferAnswerHandler::DoCreateOffer"); + + if (!observer) { + RTC_LOG(LS_ERROR) << "CreateOffer - observer is NULL."; + return; + } + + if (pc_->IsClosed()) { + std::string error = "CreateOffer called when PeerConnection is closed."; + RTC_LOG(LS_ERROR) << error; + pc_->message_handler()->PostCreateSessionDescriptionFailure( + observer, RTCError(RTCErrorType::INVALID_STATE, std::move(error))); + return; + } + + // If a session error has occurred the PeerConnection is in a possibly + // inconsistent state so fail right away. + if (session_error() != SessionError::kNone) { + std::string error_message = GetSessionErrorMsg(); + RTC_LOG(LS_ERROR) << "CreateOffer: " << error_message; + pc_->message_handler()->PostCreateSessionDescriptionFailure( + observer, + RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); + return; + } + + if (!ValidateOfferAnswerOptions(options)) { + std::string error = "CreateOffer called with invalid options."; + RTC_LOG(LS_ERROR) << error; + pc_->message_handler()->PostCreateSessionDescriptionFailure( + observer, RTCError(RTCErrorType::INVALID_PARAMETER, std::move(error))); + return; + } + + // Legacy handling for offer_to_receive_audio and offer_to_receive_video. + // Specified in WebRTC section 4.4.3.2 "Legacy configuration extensions". + if (IsUnifiedPlan()) { + RTCError error = HandleLegacyOfferOptions(options); + if (!error.ok()) { + pc_->message_handler()->PostCreateSessionDescriptionFailure( + observer, std::move(error)); + return; + } + } + + cricket::MediaSessionOptions session_options; + GetOptionsForOffer(options, &session_options); + webrtc_session_desc_factory_->CreateOffer(observer, options, session_options); +} + +void SdpOfferAnswerHandler::CreateAnswer( + CreateSessionDescriptionObserver* observer, + const PeerConnectionInterface::RTCOfferAnswerOptions& options) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Chain this operation. If asynchronous operations are pending on the chain, + // this operation will be queued to be invoked, otherwise the contents of the + // lambda will execute immediately. + operations_chain_->ChainOperation( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), + observer_refptr = + rtc::scoped_refptr(observer), + options](std::function operations_chain_callback) { + // Abort early if |this_weak_ptr| is no longer valid. + if (!this_weak_ptr) { + observer_refptr->OnFailure(RTCError( + RTCErrorType::INTERNAL_ERROR, + "CreateAnswer failed because the session was shut down")); + operations_chain_callback(); + return; + } + // The operation completes asynchronously when the wrapper is invoked. + rtc::scoped_refptr + observer_wrapper(new rtc::RefCountedObject< + CreateSessionDescriptionObserverOperationWrapper>( + std::move(observer_refptr), + std::move(operations_chain_callback))); + this_weak_ptr->DoCreateAnswer(options, observer_wrapper); + }); +} + +void SdpOfferAnswerHandler::DoCreateAnswer( + const PeerConnectionInterface::RTCOfferAnswerOptions& options, + rtc::scoped_refptr observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); + TRACE_EVENT0("webrtc", "SdpOfferAnswerHandler::DoCreateAnswer"); + if (!observer) { + RTC_LOG(LS_ERROR) << "CreateAnswer - observer is NULL."; + return; + } + + // If a session error has occurred the PeerConnection is in a possibly + // inconsistent state so fail right away. + if (session_error() != SessionError::kNone) { + std::string error_message = GetSessionErrorMsg(); + RTC_LOG(LS_ERROR) << "CreateAnswer: " << error_message; + pc_->message_handler()->PostCreateSessionDescriptionFailure( + observer, + RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); + return; + } + + if (!(signaling_state_ == PeerConnectionInterface::kHaveRemoteOffer || + signaling_state_ == PeerConnectionInterface::kHaveLocalPrAnswer)) { + std::string error = + "PeerConnection cannot create an answer in a state other than " + "have-remote-offer or have-local-pranswer."; + RTC_LOG(LS_ERROR) << error; + pc_->message_handler()->PostCreateSessionDescriptionFailure( + observer, RTCError(RTCErrorType::INVALID_STATE, std::move(error))); + return; + } + + // The remote description should be set if we're in the right state. + RTC_DCHECK(remote_description()); + + if (IsUnifiedPlan()) { + if (options.offer_to_receive_audio != + PeerConnectionInterface::RTCOfferAnswerOptions::kUndefined) { + RTC_LOG(LS_WARNING) << "CreateAnswer: offer_to_receive_audio is not " + "supported with Unified Plan semantics. Use the " + "RtpTransceiver API instead."; + } + if (options.offer_to_receive_video != + PeerConnectionInterface::RTCOfferAnswerOptions::kUndefined) { + RTC_LOG(LS_WARNING) << "CreateAnswer: offer_to_receive_video is not " + "supported with Unified Plan semantics. Use the " + "RtpTransceiver API instead."; + } + } + + cricket::MediaSessionOptions session_options; + GetOptionsForAnswer(options, &session_options); + webrtc_session_desc_factory_->CreateAnswer(observer, session_options); +} + +void SdpOfferAnswerHandler::DoSetRemoteDescription( + std::unique_ptr desc, + rtc::scoped_refptr observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); + TRACE_EVENT0("webrtc", "SdpOfferAnswerHandler::DoSetRemoteDescription"); + + if (!observer) { + RTC_LOG(LS_ERROR) << "SetRemoteDescription - observer is NULL."; + return; + } + + if (!desc) { + observer->OnSetRemoteDescriptionComplete(RTCError( + RTCErrorType::INVALID_PARAMETER, "SessionDescription is NULL.")); + return; + } + + // If a session error has occurred the PeerConnection is in a possibly + // inconsistent state so fail right away. + if (session_error() != SessionError::kNone) { + std::string error_message = GetSessionErrorMsg(); + RTC_LOG(LS_ERROR) << "SetRemoteDescription: " << error_message; + observer->OnSetRemoteDescriptionComplete( + RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error_message))); + return; + } + if (IsUnifiedPlan()) { + if (pc_->configuration()->enable_implicit_rollback) { + if (desc->GetType() == SdpType::kOffer && + signaling_state() == PeerConnectionInterface::kHaveLocalOffer) { + Rollback(desc->GetType()); + } + } + // Explicit rollback. + if (desc->GetType() == SdpType::kRollback) { + observer->OnSetRemoteDescriptionComplete(Rollback(desc->GetType())); + return; + } + } else if (desc->GetType() == SdpType::kRollback) { + observer->OnSetRemoteDescriptionComplete( + RTCError(RTCErrorType::UNSUPPORTED_OPERATION, + "Rollback not supported in Plan B")); + return; + } + if (desc->GetType() == SdpType::kOffer || + desc->GetType() == SdpType::kAnswer) { + // Report to UMA the format of the received offer or answer. + pc_->ReportSdpFormatReceived(*desc); + } + + // Handle remote descriptions missing a=mid lines for interop with legacy end + // points. + FillInMissingRemoteMids(desc->description()); + + RTCError error = ValidateSessionDescription(desc.get(), cricket::CS_REMOTE); + if (!error.ok()) { + std::string error_message = GetSetDescriptionErrorMessage( + cricket::CS_REMOTE, desc->GetType(), error); + RTC_LOG(LS_ERROR) << error_message; + observer->OnSetRemoteDescriptionComplete( + RTCError(error.type(), std::move(error_message))); + return; + } + + // Grab the description type before moving ownership to + // ApplyRemoteDescription, which may destroy it before returning. + const SdpType type = desc->GetType(); + + error = ApplyRemoteDescription(std::move(desc)); + // |desc| may be destroyed at this point. + + if (!error.ok()) { + // If ApplyRemoteDescription fails, the PeerConnection could be in an + // inconsistent state, so act conservatively here and set the session error + // so that future calls to SetLocalDescription/SetRemoteDescription fail. + SetSessionError(SessionError::kContent, error.message()); + std::string error_message = + GetSetDescriptionErrorMessage(cricket::CS_REMOTE, type, error); + RTC_LOG(LS_ERROR) << error_message; + observer->OnSetRemoteDescriptionComplete( + RTCError(error.type(), std::move(error_message))); + return; + } + RTC_DCHECK(remote_description()); + + if (type == SdpType::kAnswer) { + RemoveStoppedTransceivers(); + // TODO(deadbeef): We already had to hop to the network thread for + // MaybeStartGathering... + pc_->network_thread()->Invoke( + RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::DiscardCandidatePool, + port_allocator())); + // Make UMA notes about what was agreed to. + ReportNegotiatedSdpSemantics(*remote_description()); + } + + observer->OnSetRemoteDescriptionComplete(RTCError::OK()); + pc_->NoteUsageEvent(UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED); + + // Check if negotiation is needed. We must do this after informing the + // observer that SetRemoteDescription() has completed to ensure negotiation is + // not needed prior to the promise resolving. + if (IsUnifiedPlan()) { + bool was_negotiation_needed = is_negotiation_needed_; + UpdateNegotiationNeeded(); + if (signaling_state() == PeerConnectionInterface::kStable && + was_negotiation_needed && is_negotiation_needed_) { + // Legacy version. + pc_->Observer()->OnRenegotiationNeeded(); + // Spec-compliant version; the event may get invalidated before firing. + GenerateNegotiationNeededEvent(); + } + } +} + +void SdpOfferAnswerHandler::SetAssociatedRemoteStreams( + rtc::scoped_refptr receiver, + const std::vector& stream_ids, + std::vector>* added_streams, + std::vector>* removed_streams) { + RTC_DCHECK_RUN_ON(signaling_thread()); + std::vector> media_streams; + for (const std::string& stream_id : stream_ids) { + rtc::scoped_refptr stream = + remote_streams_->find(stream_id); + if (!stream) { + stream = MediaStreamProxy::Create(rtc::Thread::Current(), + MediaStream::Create(stream_id)); + remote_streams_->AddStream(stream); + added_streams->push_back(stream); + } + media_streams.push_back(stream); + } + // Special case: "a=msid" missing, use random stream ID. + if (media_streams.empty() && + !(remote_description()->description()->msid_signaling() & + cricket::kMsidSignalingMediaSection)) { + if (!missing_msid_default_stream_) { + missing_msid_default_stream_ = MediaStreamProxy::Create( + rtc::Thread::Current(), MediaStream::Create(rtc::CreateRandomUuid())); + added_streams->push_back(missing_msid_default_stream_); + } + media_streams.push_back(missing_msid_default_stream_); + } + std::vector> previous_streams = + receiver->streams(); + // SetStreams() will add/remove the receiver's track to/from the streams. This + // differs from the spec - the spec uses an "addList" and "removeList" to + // update the stream-track relationships in a later step. We do this earlier, + // changing the order of things, but the end-result is the same. + // TODO(hbos): When we remove remote_streams(), use set_stream_ids() + // instead. https://crbug.com/webrtc/9480 + receiver->SetStreams(media_streams); + RemoveRemoteStreamsIfEmpty(previous_streams, removed_streams); +} + +bool SdpOfferAnswerHandler::AddIceCandidate( + const IceCandidateInterface* ice_candidate) { + RTC_DCHECK_RUN_ON(signaling_thread()); + TRACE_EVENT0("webrtc", "SdpOfferAnswerHandler::AddIceCandidate"); + if (pc_->IsClosed()) { + RTC_LOG(LS_ERROR) << "AddIceCandidate: PeerConnection is closed."; + NoteAddIceCandidateResult(kAddIceCandidateFailClosed); + return false; + } + + if (!remote_description()) { + RTC_LOG(LS_ERROR) << "AddIceCandidate: ICE candidates can't be added " + "without any remote session description."; + NoteAddIceCandidateResult(kAddIceCandidateFailNoRemoteDescription); + return false; + } + + if (!ice_candidate) { + RTC_LOG(LS_ERROR) << "AddIceCandidate: Candidate is null."; + NoteAddIceCandidateResult(kAddIceCandidateFailNullCandidate); + return false; + } + + bool valid = false; + bool ready = ReadyToUseRemoteCandidate(ice_candidate, nullptr, &valid); + if (!valid) { + NoteAddIceCandidateResult(kAddIceCandidateFailNotValid); + return false; + } + + // Add this candidate to the remote session description. + if (!mutable_remote_description()->AddCandidate(ice_candidate)) { + RTC_LOG(LS_ERROR) << "AddIceCandidate: Candidate cannot be used."; + NoteAddIceCandidateResult(kAddIceCandidateFailInAddition); + return false; + } + + if (ready) { + bool result = UseCandidate(ice_candidate); + if (result) { + pc_->NoteUsageEvent(UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED); + NoteAddIceCandidateResult(kAddIceCandidateSuccess); + } else { + NoteAddIceCandidateResult(kAddIceCandidateFailNotUsable); + } + return result; + } else { + RTC_LOG(LS_INFO) << "AddIceCandidate: Not ready to use candidate."; + NoteAddIceCandidateResult(kAddIceCandidateFailNotReady); + return true; + } +} + +void SdpOfferAnswerHandler::AddIceCandidate( + std::unique_ptr candidate, + std::function callback) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Chain this operation. If asynchronous operations are pending on the chain, + // this operation will be queued to be invoked, otherwise the contents of the + // lambda will execute immediately. + operations_chain_->ChainOperation( + [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), + candidate = std::move(candidate), callback = std::move(callback)]( + std::function operations_chain_callback) { + if (!this_weak_ptr) { + operations_chain_callback(); + callback(RTCError( + RTCErrorType::INVALID_STATE, + "AddIceCandidate failed because the session was shut down")); + return; + } + if (!this_weak_ptr->AddIceCandidate(candidate.get())) { + operations_chain_callback(); + // Fail with an error type and message consistent with Chromium. + // TODO(hbos): Fail with error types according to spec. + callback(RTCError(RTCErrorType::UNSUPPORTED_OPERATION, + "Error processing ICE candidate")); + return; + } + operations_chain_callback(); + callback(RTCError::OK()); + }); +} + +bool SdpOfferAnswerHandler::RemoveIceCandidates( + const std::vector& candidates) { + TRACE_EVENT0("webrtc", "SdpOfferAnswerHandler::RemoveIceCandidates"); + RTC_DCHECK_RUN_ON(signaling_thread()); + if (pc_->IsClosed()) { + RTC_LOG(LS_ERROR) << "RemoveIceCandidates: PeerConnection is closed."; + return false; + } + + if (!remote_description()) { + RTC_LOG(LS_ERROR) << "RemoveIceCandidates: ICE candidates can't be removed " + "without any remote session description."; + return false; + } + + if (candidates.empty()) { + RTC_LOG(LS_ERROR) << "RemoveIceCandidates: candidates are empty."; + return false; + } + + size_t number_removed = + mutable_remote_description()->RemoveCandidates(candidates); + if (number_removed != candidates.size()) { + RTC_LOG(LS_ERROR) + << "RemoveIceCandidates: Failed to remove candidates. Requested " + << candidates.size() << " but only " << number_removed + << " are removed."; + } + + // Remove the candidates from the transport controller. + RTCError error = transport_controller()->RemoveRemoteCandidates(candidates); + if (!error.ok()) { + RTC_LOG(LS_ERROR) + << "RemoveIceCandidates: Error when removing remote candidates: " + << error.message(); + } + return true; +} + +void SdpOfferAnswerHandler::AddLocalIceCandidate( + const JsepIceCandidate* candidate) { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (local_description()) { + mutable_local_description()->AddCandidate(candidate); + } +} + +void SdpOfferAnswerHandler::RemoveLocalIceCandidates( + const std::vector& candidates) { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (local_description()) { + mutable_local_description()->RemoveCandidates(candidates); + } +} + +const SessionDescriptionInterface* SdpOfferAnswerHandler::local_description() + const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return pending_local_description_ ? pending_local_description_.get() + : current_local_description_.get(); +} + +const SessionDescriptionInterface* SdpOfferAnswerHandler::remote_description() + const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return pending_remote_description_ ? pending_remote_description_.get() + : current_remote_description_.get(); +} + +const SessionDescriptionInterface* +SdpOfferAnswerHandler::current_local_description() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return current_local_description_.get(); +} + +const SessionDescriptionInterface* +SdpOfferAnswerHandler::current_remote_description() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return current_remote_description_.get(); +} + +const SessionDescriptionInterface* +SdpOfferAnswerHandler::pending_local_description() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return pending_local_description_.get(); +} + +const SessionDescriptionInterface* +SdpOfferAnswerHandler::pending_remote_description() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return pending_remote_description_.get(); +} + +PeerConnectionInterface::SignalingState SdpOfferAnswerHandler::signaling_state() + const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return signaling_state_; +} + +void SdpOfferAnswerHandler::ChangeSignalingState( + PeerConnectionInterface::SignalingState signaling_state) { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (signaling_state_ == signaling_state) { + return; + } + RTC_LOG(LS_INFO) << "Session: " << pc_->session_id() << " Old state: " + << GetSignalingStateString(signaling_state_) + << " New state: " + << GetSignalingStateString(signaling_state); + signaling_state_ = signaling_state; + pc_->Observer()->OnSignalingChange(signaling_state_); +} + +RTCError SdpOfferAnswerHandler::UpdateSessionState( + SdpType type, + cricket::ContentSource source, + const cricket::SessionDescription* description) { + RTC_DCHECK_RUN_ON(signaling_thread()); + + // If there's already a pending error then no state transition should happen. + // But all call-sites should be verifying this before calling us! + RTC_DCHECK(session_error() == SessionError::kNone); + + // If this is answer-ish we're ready to let media flow. + if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) { + EnableSending(); + } + + // Update the signaling state according to the specified state machine (see + // https://w3c.github.io/webrtc-pc/#rtcsignalingstate-enum). + if (type == SdpType::kOffer) { + ChangeSignalingState(source == cricket::CS_LOCAL + ? PeerConnectionInterface::kHaveLocalOffer + : PeerConnectionInterface::kHaveRemoteOffer); + } else if (type == SdpType::kPrAnswer) { + ChangeSignalingState(source == cricket::CS_LOCAL + ? PeerConnectionInterface::kHaveLocalPrAnswer + : PeerConnectionInterface::kHaveRemotePrAnswer); + } else { + RTC_DCHECK(type == SdpType::kAnswer); + ChangeSignalingState(PeerConnectionInterface::kStable); + transceivers()->DiscardStableStates(); + have_pending_rtp_data_channel_ = false; + } + + // Update internal objects according to the session description's media + // descriptions. + RTCError error = PushdownMediaDescription(type, source); + if (!error.ok()) { + return error; + } + + return RTCError::OK(); +} + +bool SdpOfferAnswerHandler::ShouldFireNegotiationNeededEvent( + uint32_t event_id) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Plan B? Always fire to conform with useless legacy behavior. + if (!IsUnifiedPlan()) { + return true; + } + // The event ID has been invalidated. Either negotiation is no longer needed + // or a newer negotiation needed event has been generated. + if (event_id != negotiation_needed_event_id_) { + return false; + } + // The chain is no longer empty, update negotiation needed when it becomes + // empty. This should generate a newer negotiation needed event, making this + // one obsolete. + if (!operations_chain_->IsEmpty()) { + // Since we just suppressed an event that would have been fired, if + // negotiation is still needed by the time the chain becomes empty again, we + // must make sure to generate another event if negotiation is needed then. + // This happens when |is_negotiation_needed_| goes from false to true, so we + // set it to false until UpdateNegotiationNeeded() is called. + is_negotiation_needed_ = false; + update_negotiation_needed_on_empty_chain_ = true; + return false; + } + // We must not fire if the signaling state is no longer "stable". If + // negotiation is still needed when we return to "stable", a new negotiation + // needed event will be generated, so this one can safely be suppressed. + if (signaling_state_ != PeerConnectionInterface::kStable) { + return false; + } + // All checks have passed - please fire "negotiationneeded" now! + return true; +} + +rtc::scoped_refptr +SdpOfferAnswerHandler::local_streams() { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified " + "Plan SdpSemantics. Please use GetSenders " + "instead."; + return local_streams_; +} + +rtc::scoped_refptr +SdpOfferAnswerHandler::remote_streams() { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified " + "Plan SdpSemantics. Please use GetReceivers " + "instead."; + return remote_streams_; +} + +bool SdpOfferAnswerHandler::AddStream(MediaStreamInterface* local_stream) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan " + "SdpSemantics. Please use AddTrack instead."; + if (pc_->IsClosed()) { + return false; + } + if (!CanAddLocalMediaStream(local_streams_, local_stream)) { + return false; + } + + local_streams_->AddStream(local_stream); + MediaStreamObserver* observer = new MediaStreamObserver(local_stream); + observer->SignalAudioTrackAdded.connect( + this, &SdpOfferAnswerHandler::OnAudioTrackAdded); + observer->SignalAudioTrackRemoved.connect( + this, &SdpOfferAnswerHandler::OnAudioTrackRemoved); + observer->SignalVideoTrackAdded.connect( + this, &SdpOfferAnswerHandler::OnVideoTrackAdded); + observer->SignalVideoTrackRemoved.connect( + this, &SdpOfferAnswerHandler::OnVideoTrackRemoved); + stream_observers_.push_back(std::unique_ptr(observer)); + + for (const auto& track : local_stream->GetAudioTracks()) { + rtp_manager()->AddAudioTrack(track.get(), local_stream); + } + for (const auto& track : local_stream->GetVideoTracks()) { + rtp_manager()->AddVideoTrack(track.get(), local_stream); + } + + pc_->stats()->AddStream(local_stream); + UpdateNegotiationNeeded(); + return true; +} + +void SdpOfferAnswerHandler::RemoveStream(MediaStreamInterface* local_stream) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified " + "Plan SdpSemantics. Please use RemoveTrack " + "instead."; + TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream"); + if (!pc_->IsClosed()) { + for (const auto& track : local_stream->GetAudioTracks()) { + rtp_manager()->RemoveAudioTrack(track.get(), local_stream); + } + for (const auto& track : local_stream->GetVideoTracks()) { + rtp_manager()->RemoveVideoTrack(track.get(), local_stream); + } + } + local_streams_->RemoveStream(local_stream); + stream_observers_.erase( + std::remove_if( + stream_observers_.begin(), stream_observers_.end(), + [local_stream](const std::unique_ptr& observer) { + return observer->stream()->id().compare(local_stream->id()) == 0; + }), + stream_observers_.end()); + + if (pc_->IsClosed()) { + return; + } + UpdateNegotiationNeeded(); +} + +void SdpOfferAnswerHandler::OnAudioTrackAdded(AudioTrackInterface* track, + MediaStreamInterface* stream) { + if (pc_->IsClosed()) { + return; + } + rtp_manager()->AddAudioTrack(track, stream); + UpdateNegotiationNeeded(); +} + +void SdpOfferAnswerHandler::OnAudioTrackRemoved(AudioTrackInterface* track, + MediaStreamInterface* stream) { + if (pc_->IsClosed()) { + return; + } + rtp_manager()->RemoveAudioTrack(track, stream); + UpdateNegotiationNeeded(); +} + +void SdpOfferAnswerHandler::OnVideoTrackAdded(VideoTrackInterface* track, + MediaStreamInterface* stream) { + if (pc_->IsClosed()) { + return; + } + rtp_manager()->AddVideoTrack(track, stream); + UpdateNegotiationNeeded(); +} + +void SdpOfferAnswerHandler::OnVideoTrackRemoved(VideoTrackInterface* track, + MediaStreamInterface* stream) { + if (pc_->IsClosed()) { + return; + } + rtp_manager()->RemoveVideoTrack(track, stream); + UpdateNegotiationNeeded(); +} + +RTCError SdpOfferAnswerHandler::Rollback(SdpType desc_type) { + auto state = signaling_state(); + if (state != PeerConnectionInterface::kHaveLocalOffer && + state != PeerConnectionInterface::kHaveRemoteOffer) { + return RTCError(RTCErrorType::INVALID_STATE, + "Called in wrong signalingState: " + + GetSignalingStateString(signaling_state())); + } + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(IsUnifiedPlan()); + std::vector> all_added_streams; + std::vector> all_removed_streams; + std::vector> removed_receivers; + + for (auto&& transceivers_stable_state_pair : transceivers()->StableStates()) { + auto transceiver = transceivers_stable_state_pair.first; + auto state = transceivers_stable_state_pair.second; + + if (state.remote_stream_ids()) { + std::vector> added_streams; + std::vector> removed_streams; + SetAssociatedRemoteStreams(transceiver->internal()->receiver_internal(), + state.remote_stream_ids().value(), + &added_streams, &removed_streams); + all_added_streams.insert(all_added_streams.end(), added_streams.begin(), + added_streams.end()); + all_removed_streams.insert(all_removed_streams.end(), + removed_streams.begin(), + removed_streams.end()); + if (!state.has_m_section() && !state.newly_created()) { + continue; + } + } + + RTC_DCHECK(transceiver->internal()->mid().has_value()); + DestroyTransceiverChannel(transceiver); + + if (signaling_state() == PeerConnectionInterface::kHaveRemoteOffer && + transceiver->receiver()) { + removed_receivers.push_back(transceiver->receiver()); + } + if (state.newly_created()) { + if (transceiver->internal()->reused_for_addtrack()) { + transceiver->internal()->set_created_by_addtrack(true); + } else { + transceivers()->Remove(transceiver); + } + } + transceiver->internal()->sender_internal()->set_transport(nullptr); + transceiver->internal()->receiver_internal()->set_transport(nullptr); + transceiver->internal()->set_mid(state.mid()); + transceiver->internal()->set_mline_index(state.mline_index()); + } + transport_controller()->RollbackTransports(); + if (have_pending_rtp_data_channel_) { + DestroyDataChannelTransport(); + have_pending_rtp_data_channel_ = false; + } + transceivers()->DiscardStableStates(); + pending_local_description_.reset(); + pending_remote_description_.reset(); + ChangeSignalingState(PeerConnectionInterface::kStable); + + // Once all processing has finished, fire off callbacks. + for (const auto& receiver : removed_receivers) { + pc_->Observer()->OnRemoveTrack(receiver); + } + for (const auto& stream : all_added_streams) { + pc_->Observer()->OnAddStream(stream); + } + for (const auto& stream : all_removed_streams) { + pc_->Observer()->OnRemoveStream(stream); + } + + // The assumption is that in case of implicit rollback UpdateNegotiationNeeded + // gets called in SetRemoteDescription. + if (desc_type == SdpType::kRollback) { + UpdateNegotiationNeeded(); + if (is_negotiation_needed_) { + // Legacy version. + pc_->Observer()->OnRenegotiationNeeded(); + // Spec-compliant version; the event may get invalidated before firing. + GenerateNegotiationNeededEvent(); + } + } + return RTCError::OK(); +} + +bool SdpOfferAnswerHandler::IsUnifiedPlan() const { + return pc_->IsUnifiedPlan(); +} + +void SdpOfferAnswerHandler::OnOperationsChainEmpty() { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (pc_->IsClosed() || !update_negotiation_needed_on_empty_chain_) + return; + update_negotiation_needed_on_empty_chain_ = false; + // Firing when chain is empty is only supported in Unified Plan to avoid Plan + // B regressions. (In Plan B, onnegotiationneeded is already broken anyway, so + // firing it even more might just be confusing.) + if (IsUnifiedPlan()) { + UpdateNegotiationNeeded(); + } +} + +absl::optional SdpOfferAnswerHandler::is_caller() { + RTC_DCHECK_RUN_ON(signaling_thread()); + return is_caller_; +} + +bool SdpOfferAnswerHandler::HasNewIceCredentials() { + RTC_DCHECK_RUN_ON(signaling_thread()); + return local_ice_credentials_to_replace_->HasIceCredentials(); +} + +bool SdpOfferAnswerHandler::IceRestartPending( + const std::string& content_name) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return pending_ice_restarts_.find(content_name) != + pending_ice_restarts_.end(); +} + +bool SdpOfferAnswerHandler::NeedsIceRestart( + const std::string& content_name) const { + return transport_controller()->NeedsIceRestart(content_name); +} + +absl::optional SdpOfferAnswerHandler::GetDtlsRole( + const std::string& mid) const { + return transport_controller()->GetDtlsRole(mid); +} + +void SdpOfferAnswerHandler::UpdateNegotiationNeeded() { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (!IsUnifiedPlan()) { + pc_->Observer()->OnRenegotiationNeeded(); + GenerateNegotiationNeededEvent(); + return; + } + + // In the spec, a task is queued here to run the following steps - this is + // meant to ensure we do not fire onnegotiationneeded prematurely if multiple + // changes are being made at once. In order to support Chromium's + // implementation where the JavaScript representation of the PeerConnection + // lives on a separate thread though, the queuing of a task is instead + // performed by the PeerConnectionObserver posting from the signaling thread + // to the JavaScript main thread that negotiation is needed. And because the + // Operations Chain lives on the WebRTC signaling thread, + // ShouldFireNegotiationNeededEvent() must be called before firing the event + // to ensure the Operations Chain is still empty and the event has not been + // invalidated. + + // If connection's [[IsClosed]] slot is true, abort these steps. + if (pc_->IsClosed()) + return; + + // If connection's signaling state is not "stable", abort these steps. + if (signaling_state() != PeerConnectionInterface::kStable) + return; + + // NOTE + // The negotiation-needed flag will be updated once the state transitions to + // "stable", as part of the steps for setting an RTCSessionDescription. + + // If the result of checking if negotiation is needed is false, clear the + // negotiation-needed flag by setting connection's [[NegotiationNeeded]] slot + // to false, and abort these steps. + bool is_negotiation_needed = CheckIfNegotiationIsNeeded(); + if (!is_negotiation_needed) { + is_negotiation_needed_ = false; + // Invalidate any negotiation needed event that may previosuly have been + // generated. + ++negotiation_needed_event_id_; + return; + } + + // If connection's [[NegotiationNeeded]] slot is already true, abort these + // steps. + if (is_negotiation_needed_) + return; + + // Set connection's [[NegotiationNeeded]] slot to true. + is_negotiation_needed_ = true; + + // Queue a task that runs the following steps: + // If connection's [[IsClosed]] slot is true, abort these steps. + // If connection's [[NegotiationNeeded]] slot is false, abort these steps. + // Fire an event named negotiationneeded at connection. + pc_->Observer()->OnRenegotiationNeeded(); + // Fire the spec-compliant version; when ShouldFireNegotiationNeededEvent() is + // used in the task queued by the observer, this event will only fire when the + // chain is empty. + GenerateNegotiationNeededEvent(); +} + +bool SdpOfferAnswerHandler::CheckIfNegotiationIsNeeded() { + RTC_DCHECK_RUN_ON(signaling_thread()); + // 1. If any implementation-specific negotiation is required, as described at + // the start of this section, return true. + + // 2. If connection.[[LocalIceCredentialsToReplace]] is not empty, return + // true. + if (local_ice_credentials_to_replace_->HasIceCredentials()) { + return true; + } + + // 3. Let description be connection.[[CurrentLocalDescription]]. + const SessionDescriptionInterface* description = current_local_description(); + if (!description) + return true; + + // 4. If connection has created any RTCDataChannels, and no m= section in + // description has been negotiated yet for data, return true. + if (data_channel_controller()->HasSctpDataChannels()) { + if (!cricket::GetFirstDataContent(description->description()->contents())) + return true; + } + + // 5. For each transceiver in connection's set of transceivers, perform the + // following checks: + for (const auto& transceiver : transceivers()->List()) { + const ContentInfo* current_local_msection = + FindTransceiverMSection(transceiver.get(), description); + + const ContentInfo* current_remote_msection = FindTransceiverMSection( + transceiver.get(), current_remote_description()); + + // 5.4 If transceiver is stopped and is associated with an m= section, + // but the associated m= section is not yet rejected in + // connection.[[CurrentLocalDescription]] or + // connection.[[CurrentRemoteDescription]], return true. + if (transceiver->stopped()) { + RTC_DCHECK(transceiver->stopping()); + if (current_local_msection && !current_local_msection->rejected && + ((current_remote_msection && !current_remote_msection->rejected) || + !current_remote_msection)) { + return true; + } + continue; + } + + // 5.1 If transceiver.[[Stopping]] is true and transceiver.[[Stopped]] is + // false, return true. + if (transceiver->stopping() && !transceiver->stopped()) + return true; + + // 5.2 If transceiver isn't stopped and isn't yet associated with an m= + // section in description, return true. + if (!current_local_msection) + return true; + + const MediaContentDescription* current_local_media_description = + current_local_msection->media_description(); + // 5.3 If transceiver isn't stopped and is associated with an m= section + // in description then perform the following checks: + + // 5.3.1 If transceiver.[[Direction]] is "sendrecv" or "sendonly", and the + // associated m= section in description either doesn't contain a single + // "a=msid" line, or the number of MSIDs from the "a=msid" lines in this + // m= section, or the MSID values themselves, differ from what is in + // transceiver.sender.[[AssociatedMediaStreamIds]], return true. + if (RtpTransceiverDirectionHasSend(transceiver->direction())) { + if (current_local_media_description->streams().size() == 0) + return true; + + std::vector msection_msids; + for (const auto& stream : current_local_media_description->streams()) { + for (const std::string& msid : stream.stream_ids()) + msection_msids.push_back(msid); + } + + std::vector transceiver_msids = + transceiver->sender()->stream_ids(); + if (msection_msids.size() != transceiver_msids.size()) + return true; + + absl::c_sort(transceiver_msids); + absl::c_sort(msection_msids); + if (transceiver_msids != msection_msids) + return true; + } + + // 5.3.2 If description is of type "offer", and the direction of the + // associated m= section in neither connection.[[CurrentLocalDescription]] + // nor connection.[[CurrentRemoteDescription]] matches + // transceiver.[[Direction]], return true. + if (description->GetType() == SdpType::kOffer) { + if (!current_remote_description()) + return true; + + if (!current_remote_msection) + return true; + + RtpTransceiverDirection current_local_direction = + current_local_media_description->direction(); + RtpTransceiverDirection current_remote_direction = + current_remote_msection->media_description()->direction(); + if (transceiver->direction() != current_local_direction && + transceiver->direction() != + RtpTransceiverDirectionReversed(current_remote_direction)) { + return true; + } + } + + // 5.3.3 If description is of type "answer", and the direction of the + // associated m= section in the description does not match + // transceiver.[[Direction]] intersected with the offered direction (as + // described in [JSEP] (section 5.3.1.)), return true. + if (description->GetType() == SdpType::kAnswer) { + if (!remote_description()) + return true; + + const ContentInfo* offered_remote_msection = + FindTransceiverMSection(transceiver.get(), remote_description()); + + RtpTransceiverDirection offered_direction = + offered_remote_msection + ? offered_remote_msection->media_description()->direction() + : RtpTransceiverDirection::kInactive; + + if (current_local_media_description->direction() != + (RtpTransceiverDirectionIntersection( + transceiver->direction(), + RtpTransceiverDirectionReversed(offered_direction)))) { + return true; + } + } + } + + // If all the preceding checks were performed and true was not returned, + // nothing remains to be negotiated; return false. + return false; +} + +void SdpOfferAnswerHandler::GenerateNegotiationNeededEvent() { + RTC_DCHECK_RUN_ON(signaling_thread()); + ++negotiation_needed_event_id_; + pc_->Observer()->OnNegotiationNeededEvent(negotiation_needed_event_id_); +} + +RTCError SdpOfferAnswerHandler::ValidateSessionDescription( + const SessionDescriptionInterface* sdesc, + cricket::ContentSource source) { + if (session_error() != SessionError::kNone) { + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, GetSessionErrorMsg()); + } + + if (!sdesc || !sdesc->description()) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, kInvalidSdp); + } + + SdpType type = sdesc->GetType(); + if ((source == cricket::CS_LOCAL && !ExpectSetLocalDescription(type)) || + (source == cricket::CS_REMOTE && !ExpectSetRemoteDescription(type))) { + LOG_AND_RETURN_ERROR( + RTCErrorType::INVALID_STATE, + "Called in wrong state: " + GetSignalingStateString(signaling_state())); + } + + RTCError error = ValidateMids(*sdesc->description()); + if (!error.ok()) { + return error; + } + + // Verify crypto settings. + std::string crypto_error; + if (webrtc_session_desc_factory_->SdesPolicy() == cricket::SEC_REQUIRED || + pc_->dtls_enabled()) { + RTCError crypto_error = + VerifyCrypto(sdesc->description(), pc_->dtls_enabled()); + if (!crypto_error.ok()) { + return crypto_error; + } + } + + // Verify ice-ufrag and ice-pwd. + if (!VerifyIceUfragPwdPresent(sdesc->description())) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + kSdpWithoutIceUfragPwd); + } + + if (!pc_->ValidateBundleSettings(sdesc->description())) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + kBundleWithoutRtcpMux); + } + + // TODO(skvlad): When the local rtcp-mux policy is Require, reject any + // m-lines that do not rtcp-mux enabled. + + // Verify m-lines in Answer when compared against Offer. + if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) { + // With an answer we want to compare the new answer session description with + // the offer's session description from the current negotiation. + const cricket::SessionDescription* offer_desc = + (source == cricket::CS_LOCAL) ? remote_description()->description() + : local_description()->description(); + if (!MediaSectionsHaveSameCount(*offer_desc, *sdesc->description()) || + !MediaSectionsInSameOrder(*offer_desc, nullptr, *sdesc->description(), + type)) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + kMlineMismatchInAnswer); + } + } else { + // The re-offers should respect the order of m= sections in current + // description. See RFC3264 Section 8 paragraph 4 for more details. + // With a re-offer, either the current local or current remote descriptions + // could be the most up to date, so we would like to check against both of + // them if they exist. It could be the case that one of them has a 0 port + // for a media section, but the other does not. This is important to check + // against in the case that we are recycling an m= section. + const cricket::SessionDescription* current_desc = nullptr; + const cricket::SessionDescription* secondary_current_desc = nullptr; + if (local_description()) { + current_desc = local_description()->description(); + if (remote_description()) { + secondary_current_desc = remote_description()->description(); + } + } else if (remote_description()) { + current_desc = remote_description()->description(); + } + if (current_desc && + !MediaSectionsInSameOrder(*current_desc, secondary_current_desc, + *sdesc->description(), type)) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + kMlineMismatchInSubsequentOffer); + } + } + + if (IsUnifiedPlan()) { + // Ensure that each audio and video media section has at most one + // "StreamParams". This will return an error if receiving a session + // description from a "Plan B" endpoint which adds multiple tracks of the + // same type. With Unified Plan, there can only be at most one track per + // media section. + for (const ContentInfo& content : sdesc->description()->contents()) { + const MediaContentDescription& desc = *content.media_description(); + if ((desc.type() == cricket::MEDIA_TYPE_AUDIO || + desc.type() == cricket::MEDIA_TYPE_VIDEO) && + desc.streams().size() > 1u) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + "Media section has more than one track specified " + "with a=ssrc lines which is not supported with " + "Unified Plan."); + } + } + } + + return RTCError::OK(); +} + +RTCError SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels( + cricket::ContentSource source, + const SessionDescriptionInterface& new_session, + const SessionDescriptionInterface* old_local_description, + const SessionDescriptionInterface* old_remote_description) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(IsUnifiedPlan()); + + const cricket::ContentGroup* bundle_group = nullptr; + if (new_session.GetType() == SdpType::kOffer) { + auto bundle_group_or_error = + GetEarlyBundleGroup(*new_session.description()); + if (!bundle_group_or_error.ok()) { + return bundle_group_or_error.MoveError(); + } + bundle_group = bundle_group_or_error.MoveValue(); + } + + const ContentInfos& new_contents = new_session.description()->contents(); + for (size_t i = 0; i < new_contents.size(); ++i) { + const cricket::ContentInfo& new_content = new_contents[i]; + cricket::MediaType media_type = new_content.media_description()->type(); + mid_generator_.AddKnownId(new_content.name); + if (media_type == cricket::MEDIA_TYPE_AUDIO || + media_type == cricket::MEDIA_TYPE_VIDEO) { + const cricket::ContentInfo* old_local_content = nullptr; + if (old_local_description && + i < old_local_description->description()->contents().size()) { + old_local_content = + &old_local_description->description()->contents()[i]; + } + const cricket::ContentInfo* old_remote_content = nullptr; + if (old_remote_description && + i < old_remote_description->description()->contents().size()) { + old_remote_content = + &old_remote_description->description()->contents()[i]; + } + auto transceiver_or_error = + AssociateTransceiver(source, new_session.GetType(), i, new_content, + old_local_content, old_remote_content); + if (!transceiver_or_error.ok()) { + // In the case where a transceiver is rejected locally, we don't + // expect to find a transceiver, but might find it in the case + // where state is still "stopping", not "stopped". + if (new_content.rejected) { + continue; + } + return transceiver_or_error.MoveError(); + } + auto transceiver = transceiver_or_error.MoveValue(); + RTCError error = + UpdateTransceiverChannel(transceiver, new_content, bundle_group); + if (!error.ok()) { + return error; + } + } else if (media_type == cricket::MEDIA_TYPE_DATA) { + if (pc_->GetDataMid() && new_content.name != *(pc_->GetDataMid())) { + // Ignore all but the first data section. + RTC_LOG(LS_INFO) << "Ignoring data media section with MID=" + << new_content.name; + continue; + } + RTCError error = UpdateDataChannel(source, new_content, bundle_group); + if (!error.ok()) { + return error; + } + } else if (media_type == cricket::MEDIA_TYPE_UNSUPPORTED) { + RTC_LOG(LS_INFO) << "Ignoring unsupported media type"; + } else { + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, + "Unknown section type."); + } + } + + return RTCError::OK(); +} + +RTCErrorOr>> +SdpOfferAnswerHandler::AssociateTransceiver( + cricket::ContentSource source, + SdpType type, + size_t mline_index, + const ContentInfo& content, + const ContentInfo* old_local_content, + const ContentInfo* old_remote_content) { + RTC_DCHECK(IsUnifiedPlan()); +#if RTC_DCHECK_IS_ON + // If this is an offer then the m= section might be recycled. If the m= + // section is being recycled (defined as: rejected in the current local or + // remote description and not rejected in new description), the transceiver + // should have been removed by RemoveStoppedtransceivers()-> + if (IsMediaSectionBeingRecycled(type, content, old_local_content, + old_remote_content)) { + const std::string& old_mid = + (old_local_content && old_local_content->rejected) + ? old_local_content->name + : old_remote_content->name; + auto old_transceiver = transceivers()->FindByMid(old_mid); + // The transceiver should be disassociated in RemoveStoppedTransceivers() + RTC_DCHECK(!old_transceiver); + } +#endif + + const MediaContentDescription* media_desc = content.media_description(); + auto transceiver = transceivers()->FindByMid(content.name); + if (source == cricket::CS_LOCAL) { + // Find the RtpTransceiver that corresponds to this m= section, using the + // mapping between transceivers and m= section indices established when + // creating the offer. + if (!transceiver) { + transceiver = transceivers()->FindByMLineIndex(mline_index); + } + if (!transceiver) { + // This may happen normally when media sections are rejected. + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + "Transceiver not found based on m-line index"); + } + } else { + RTC_DCHECK_EQ(source, cricket::CS_REMOTE); + // If the m= section is sendrecv or recvonly, and there are RtpTransceivers + // of the same type... + // When simulcast is requested, a transceiver cannot be associated because + // AddTrack cannot be called to initialize it. + if (!transceiver && + RtpTransceiverDirectionHasRecv(media_desc->direction()) && + !media_desc->HasSimulcast()) { + transceiver = FindAvailableTransceiverToReceive(media_desc->type()); + } + // If no RtpTransceiver was found in the previous step, create one with a + // recvonly direction. + if (!transceiver) { + RTC_LOG(LS_INFO) << "Adding " + << cricket::MediaTypeToString(media_desc->type()) + << " transceiver for MID=" << content.name + << " at i=" << mline_index + << " in response to the remote description."; + std::string sender_id = rtc::CreateRandomUuid(); + std::vector send_encodings = + GetSendEncodingsFromRemoteDescription(*media_desc); + auto sender = rtp_manager()->CreateSender(media_desc->type(), sender_id, + nullptr, {}, send_encodings); + std::string receiver_id; + if (!media_desc->streams().empty()) { + receiver_id = media_desc->streams()[0].id; + } else { + receiver_id = rtc::CreateRandomUuid(); + } + auto receiver = + rtp_manager()->CreateReceiver(media_desc->type(), receiver_id); + transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver); + transceiver->internal()->set_direction( + RtpTransceiverDirection::kRecvOnly); + if (type == SdpType::kOffer) { + transceivers()->StableState(transceiver)->set_newly_created(); + } + } + + RTC_DCHECK(transceiver); + + // Check if the offer indicated simulcast but the answer rejected it. + // This can happen when simulcast is not supported on the remote party. + if (SimulcastIsRejected(old_local_content, *media_desc)) { + RTC_HISTOGRAM_BOOLEAN(kSimulcastDisabled, true); + RTCError error = + DisableSimulcastInSender(transceiver->internal()->sender_internal()); + if (!error.ok()) { + RTC_LOG(LS_ERROR) << "Failed to remove rejected simulcast."; + return std::move(error); + } + } + } + + if (transceiver->media_type() != media_desc->type()) { + LOG_AND_RETURN_ERROR( + RTCErrorType::INVALID_PARAMETER, + "Transceiver type does not match media description type."); + } + + if (media_desc->HasSimulcast()) { + std::vector layers = + source == cricket::CS_LOCAL + ? media_desc->simulcast_description().send_layers().GetAllLayers() + : media_desc->simulcast_description() + .receive_layers() + .GetAllLayers(); + RTCError error = UpdateSimulcastLayerStatusInSender( + layers, transceiver->internal()->sender_internal()); + if (!error.ok()) { + RTC_LOG(LS_ERROR) << "Failed updating status for simulcast layers."; + return std::move(error); + } + } + if (type == SdpType::kOffer) { + bool state_changes = transceiver->internal()->mid() != content.name || + transceiver->internal()->mline_index() != mline_index; + if (state_changes) { + transceivers() + ->StableState(transceiver) + ->SetMSectionIfUnset(transceiver->internal()->mid(), + transceiver->internal()->mline_index()); + } + } + // Associate the found or created RtpTransceiver with the m= section by + // setting the value of the RtpTransceiver's mid property to the MID of the m= + // section, and establish a mapping between the transceiver and the index of + // the m= section. + transceiver->internal()->set_mid(content.name); + transceiver->internal()->set_mline_index(mline_index); + return std::move(transceiver); +} + +RTCErrorOr +SdpOfferAnswerHandler::GetEarlyBundleGroup( + const SessionDescription& desc) const { + const cricket::ContentGroup* bundle_group = nullptr; + if (pc_->configuration()->bundle_policy == + PeerConnectionInterface::kBundlePolicyMaxBundle) { + bundle_group = desc.GetGroupByName(cricket::GROUP_TYPE_BUNDLE); + if (!bundle_group) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + "max-bundle configured but session description " + "has no BUNDLE group"); + } + } + return bundle_group; +} + +RTCError SdpOfferAnswerHandler::UpdateTransceiverChannel( + rtc::scoped_refptr> + transceiver, + const cricket::ContentInfo& content, + const cricket::ContentGroup* bundle_group) { + RTC_DCHECK(IsUnifiedPlan()); + RTC_DCHECK(transceiver); + cricket::ChannelInterface* channel = transceiver->internal()->channel(); + if (content.rejected) { + if (channel) { + transceiver->internal()->SetChannel(nullptr); + DestroyChannelInterface(channel); + } + } else { + if (!channel) { + if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { + channel = CreateVoiceChannel(content.name); + } else { + RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->media_type()); + channel = CreateVideoChannel(content.name); + } + if (!channel) { + LOG_AND_RETURN_ERROR( + RTCErrorType::INTERNAL_ERROR, + "Failed to create channel for mid=" + content.name); + } + transceiver->internal()->SetChannel(channel); + } + } + return RTCError::OK(); +} + +RTCError SdpOfferAnswerHandler::UpdateDataChannel( + cricket::ContentSource source, + const cricket::ContentInfo& content, + const cricket::ContentGroup* bundle_group) { + if (pc_->data_channel_type() == cricket::DCT_NONE) { + // If data channels are disabled, ignore this media section. CreateAnswer + // will take care of rejecting it. + return RTCError::OK(); + } + if (content.rejected) { + RTC_LOG(LS_INFO) << "Rejected data channel, mid=" << content.mid(); + DestroyDataChannelTransport(); + } else { + if (!data_channel_controller()->rtp_data_channel() && + !data_channel_controller()->data_channel_transport()) { + RTC_LOG(LS_INFO) << "Creating data channel, mid=" << content.mid(); + if (!CreateDataChannel(content.name)) { + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, + "Failed to create data channel."); + } + } + if (source == cricket::CS_REMOTE) { + const MediaContentDescription* data_desc = content.media_description(); + if (data_desc && cricket::IsRtpProtocol(data_desc->protocol())) { + data_channel_controller()->UpdateRemoteRtpDataChannels( + GetActiveStreams(data_desc)); + } + } + } + return RTCError::OK(); +} + +bool SdpOfferAnswerHandler::ExpectSetLocalDescription(SdpType type) { + PeerConnectionInterface::SignalingState state = signaling_state(); + if (type == SdpType::kOffer) { + return (state == PeerConnectionInterface::kStable) || + (state == PeerConnectionInterface::kHaveLocalOffer); + } else { + RTC_DCHECK(type == SdpType::kPrAnswer || type == SdpType::kAnswer); + return (state == PeerConnectionInterface::kHaveRemoteOffer) || + (state == PeerConnectionInterface::kHaveLocalPrAnswer); + } +} + +bool SdpOfferAnswerHandler::ExpectSetRemoteDescription(SdpType type) { + PeerConnectionInterface::SignalingState state = signaling_state(); + if (type == SdpType::kOffer) { + return (state == PeerConnectionInterface::kStable) || + (state == PeerConnectionInterface::kHaveRemoteOffer); + } else { + RTC_DCHECK(type == SdpType::kPrAnswer || type == SdpType::kAnswer); + return (state == PeerConnectionInterface::kHaveLocalOffer) || + (state == PeerConnectionInterface::kHaveRemotePrAnswer); + } +} + +void SdpOfferAnswerHandler::FillInMissingRemoteMids( + cricket::SessionDescription* new_remote_description) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(new_remote_description); + const cricket::ContentInfos no_infos; + const cricket::ContentInfos& local_contents = + (local_description() ? local_description()->description()->contents() + : no_infos); + const cricket::ContentInfos& remote_contents = + (remote_description() ? remote_description()->description()->contents() + : no_infos); + for (size_t i = 0; i < new_remote_description->contents().size(); ++i) { + cricket::ContentInfo& content = new_remote_description->contents()[i]; + if (!content.name.empty()) { + continue; + } + std::string new_mid; + absl::string_view source_explanation; + if (IsUnifiedPlan()) { + if (i < local_contents.size()) { + new_mid = local_contents[i].name; + source_explanation = "from the matching local media section"; + } else if (i < remote_contents.size()) { + new_mid = remote_contents[i].name; + source_explanation = "from the matching previous remote media section"; + } else { + new_mid = mid_generator_.GenerateString(); + source_explanation = "generated just now"; + } + } else { + new_mid = std::string( + GetDefaultMidForPlanB(content.media_description()->type())); + source_explanation = "to match pre-existing behavior"; + } + RTC_DCHECK(!new_mid.empty()); + content.name = new_mid; + new_remote_description->transport_infos()[i].content_name = new_mid; + RTC_LOG(LS_INFO) << "SetRemoteDescription: Remote media section at i=" << i + << " is missing an a=mid line. Filling in the value '" + << new_mid << "' " << source_explanation << "."; + } +} + +rtc::scoped_refptr> +SdpOfferAnswerHandler::FindAvailableTransceiverToReceive( + cricket::MediaType media_type) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(IsUnifiedPlan()); + // From JSEP section 5.10 (Applying a Remote Description): + // If the m= section is sendrecv or recvonly, and there are RtpTransceivers of + // the same type that were added to the PeerConnection by addTrack and are not + // associated with any m= section and are not stopped, find the first such + // RtpTransceiver. + for (auto transceiver : transceivers()->List()) { + if (transceiver->media_type() == media_type && + transceiver->internal()->created_by_addtrack() && !transceiver->mid() && + !transceiver->stopped()) { + return transceiver; + } + } + return nullptr; +} + +const cricket::ContentInfo* +SdpOfferAnswerHandler::FindMediaSectionForTransceiver( + rtc::scoped_refptr> + transceiver, + const SessionDescriptionInterface* sdesc) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(transceiver); + RTC_DCHECK(sdesc); + if (IsUnifiedPlan()) { + if (!transceiver->internal()->mid()) { + // This transceiver is not associated with a media section yet. + return nullptr; + } + return sdesc->description()->GetContentByName( + *transceiver->internal()->mid()); + } else { + // Plan B only allows at most one audio and one video section, so use the + // first media section of that type. + return cricket::GetFirstMediaContent(sdesc->description()->contents(), + transceiver->media_type()); + } +} + +void SdpOfferAnswerHandler::GetOptionsForOffer( + const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, + cricket::MediaSessionOptions* session_options) { + RTC_DCHECK_RUN_ON(signaling_thread()); + ExtractSharedMediaSessionOptions(offer_answer_options, session_options); + + if (IsUnifiedPlan()) { + GetOptionsForUnifiedPlanOffer(offer_answer_options, session_options); + } else { + GetOptionsForPlanBOffer(offer_answer_options, session_options); + } + + // Intentionally unset the data channel type for RTP data channel with the + // second condition. Otherwise the RTP data channels would be successfully + // negotiated by default and the unit tests in WebRtcDataBrowserTest will fail + // when building with chromium. We want to leave RTP data channels broken, so + // people won't try to use them. + if (data_channel_controller()->HasRtpDataChannels() || + pc_->data_channel_type() != cricket::DCT_RTP) { + session_options->data_channel_type = pc_->data_channel_type(); + } + + // Apply ICE restart flag and renomination flag. + bool ice_restart = offer_answer_options.ice_restart || HasNewIceCredentials(); + for (auto& options : session_options->media_description_options) { + options.transport_options.ice_restart = ice_restart; + options.transport_options.enable_ice_renomination = + pc_->configuration()->enable_ice_renomination; + } + + session_options->rtcp_cname = rtcp_cname_; + session_options->crypto_options = pc_->GetCryptoOptions(); + session_options->pooled_ice_credentials = + pc_->network_thread()->Invoke>( + RTC_FROM_HERE, + rtc::Bind(&cricket::PortAllocator::GetPooledIceCredentials, + port_allocator())); + session_options->offer_extmap_allow_mixed = + pc_->configuration()->offer_extmap_allow_mixed; + + // Allow fallback for using obsolete SCTP syntax. + // Note that the default in |session_options| is true, while + // the default in |options| is false. + session_options->use_obsolete_sctp_sdp = + offer_answer_options.use_obsolete_sctp_sdp; +} + +void SdpOfferAnswerHandler::GetOptionsForPlanBOffer( + const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, + cricket::MediaSessionOptions* session_options) { + // Figure out transceiver directional preferences. + bool send_audio = + !rtp_manager()->GetAudioTransceiver()->internal()->senders().empty(); + bool send_video = + !rtp_manager()->GetVideoTransceiver()->internal()->senders().empty(); + + // By default, generate sendrecv/recvonly m= sections. + bool recv_audio = true; + bool recv_video = true; + + // By default, only offer a new m= section if we have media to send with it. + bool offer_new_audio_description = send_audio; + bool offer_new_video_description = send_video; + bool offer_new_data_description = + data_channel_controller()->HasDataChannels(); + + // The "offer_to_receive_X" options allow those defaults to be overridden. + if (offer_answer_options.offer_to_receive_audio != + PeerConnectionInterface::RTCOfferAnswerOptions::kUndefined) { + recv_audio = (offer_answer_options.offer_to_receive_audio > 0); + offer_new_audio_description = + offer_new_audio_description || + (offer_answer_options.offer_to_receive_audio > 0); + } + if (offer_answer_options.offer_to_receive_video != + RTCOfferAnswerOptions::kUndefined) { + recv_video = (offer_answer_options.offer_to_receive_video > 0); + offer_new_video_description = + offer_new_video_description || + (offer_answer_options.offer_to_receive_video > 0); + } + + absl::optional audio_index; + absl::optional video_index; + absl::optional data_index; + // If a current description exists, generate m= sections in the same order, + // using the first audio/video/data section that appears and rejecting + // extraneous ones. + if (local_description()) { + GenerateMediaDescriptionOptions( + local_description(), + RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), + RtpTransceiverDirectionFromSendRecv(send_video, recv_video), + &audio_index, &video_index, &data_index, session_options); + } + + // Add audio/video/data m= sections to the end if needed. + if (!audio_index && offer_new_audio_description) { + cricket::MediaDescriptionOptions options( + cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO, + RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), false); + options.header_extensions = + channel_manager()->GetSupportedAudioRtpHeaderExtensions(); + session_options->media_description_options.push_back(options); + audio_index = session_options->media_description_options.size() - 1; + } + if (!video_index && offer_new_video_description) { + cricket::MediaDescriptionOptions options( + cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO, + RtpTransceiverDirectionFromSendRecv(send_video, recv_video), false); + options.header_extensions = + channel_manager()->GetSupportedVideoRtpHeaderExtensions(); + session_options->media_description_options.push_back(options); + video_index = session_options->media_description_options.size() - 1; + } + if (!data_index && offer_new_data_description) { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForActiveData(cricket::CN_DATA)); + data_index = session_options->media_description_options.size() - 1; + } + + cricket::MediaDescriptionOptions* audio_media_description_options = + !audio_index ? nullptr + : &session_options->media_description_options[*audio_index]; + cricket::MediaDescriptionOptions* video_media_description_options = + !video_index ? nullptr + : &session_options->media_description_options[*video_index]; + + AddPlanBRtpSenderOptions(rtp_manager()->GetSendersInternal(), + audio_media_description_options, + video_media_description_options, + offer_answer_options.num_simulcast_layers); +} + +void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanOffer( + const RTCOfferAnswerOptions& offer_answer_options, + cricket::MediaSessionOptions* session_options) { + // Rules for generating an offer are dictated by JSEP sections 5.2.1 (Initial + // Offers) and 5.2.2 (Subsequent Offers). + RTC_DCHECK_EQ(session_options->media_description_options.size(), 0); + const ContentInfos no_infos; + const ContentInfos& local_contents = + (local_description() ? local_description()->description()->contents() + : no_infos); + const ContentInfos& remote_contents = + (remote_description() ? remote_description()->description()->contents() + : no_infos); + // The mline indices that can be recycled. New transceivers should reuse these + // slots first. + std::queue recycleable_mline_indices; + // First, go through each media section that exists in either the local or + // remote description and generate a media section in this offer for the + // associated transceiver. If a media section can be recycled, generate a + // default, rejected media section here that can be later overwritten. + for (size_t i = 0; + i < std::max(local_contents.size(), remote_contents.size()); ++i) { + // Either |local_content| or |remote_content| is non-null. + const ContentInfo* local_content = + (i < local_contents.size() ? &local_contents[i] : nullptr); + const ContentInfo* current_local_content = + GetContentByIndex(current_local_description(), i); + const ContentInfo* remote_content = + (i < remote_contents.size() ? &remote_contents[i] : nullptr); + const ContentInfo* current_remote_content = + GetContentByIndex(current_remote_description(), i); + bool had_been_rejected = + (current_local_content && current_local_content->rejected) || + (current_remote_content && current_remote_content->rejected); + const std::string& mid = + (local_content ? local_content->name : remote_content->name); + cricket::MediaType media_type = + (local_content ? local_content->media_description()->type() + : remote_content->media_description()->type()); + if (media_type == cricket::MEDIA_TYPE_AUDIO || + media_type == cricket::MEDIA_TYPE_VIDEO) { + // A media section is considered eligible for recycling if it is marked as + // rejected in either the current local or current remote description. + auto transceiver = transceivers()->FindByMid(mid); + if (!transceiver) { + // No associated transceiver. The media section has been stopped. + recycleable_mline_indices.push(i); + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions(media_type, mid, + RtpTransceiverDirection::kInactive, + /*stopped=*/true)); + } else { + // NOTE: a stopping transceiver should be treated as a stopped one in + // createOffer as specified in + // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer. + if (had_been_rejected && transceiver->stopping()) { + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions( + transceiver->media_type(), mid, + RtpTransceiverDirection::kInactive, + /*stopped=*/true)); + recycleable_mline_indices.push(i); + } else { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForTransceiver( + transceiver, mid, + /*is_create_offer=*/true)); + // CreateOffer shouldn't really cause any state changes in + // PeerConnection, but we need a way to match new transceivers to new + // media sections in SetLocalDescription and JSEP specifies this is + // done by recording the index of the media section generated for the + // transceiver in the offer. + transceiver->internal()->set_mline_index(i); + } + } + } else if (media_type == cricket::MEDIA_TYPE_UNSUPPORTED) { + RTC_DCHECK(local_content->rejected); + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions(media_type, mid, + RtpTransceiverDirection::kInactive, + /*stopped=*/true)); + } else { + RTC_CHECK_EQ(cricket::MEDIA_TYPE_DATA, media_type); + if (had_been_rejected) { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForRejectedData(mid)); + } else { + RTC_CHECK(pc_->GetDataMid()); + if (mid == *(pc_->GetDataMid())) { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForActiveData(mid)); + } else { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForRejectedData(mid)); + } + } + } + } + + // Next, look for transceivers that are newly added (that is, are not stopped + // and not associated). Reuse media sections marked as recyclable first, + // otherwise append to the end of the offer. New media sections should be + // added in the order they were added to the PeerConnection. + for (const auto& transceiver : transceivers()->List()) { + if (transceiver->mid() || transceiver->stopping()) { + continue; + } + size_t mline_index; + if (!recycleable_mline_indices.empty()) { + mline_index = recycleable_mline_indices.front(); + recycleable_mline_indices.pop(); + session_options->media_description_options[mline_index] = + GetMediaDescriptionOptionsForTransceiver( + transceiver, mid_generator_.GenerateString(), + /*is_create_offer=*/true); + } else { + mline_index = session_options->media_description_options.size(); + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForTransceiver( + transceiver, mid_generator_.GenerateString(), + /*is_create_offer=*/true)); + } + // See comment above for why CreateOffer changes the transceiver's state. + transceiver->internal()->set_mline_index(mline_index); + } + // Lastly, add a m-section if we have local data channels and an m section + // does not already exist. + if (!pc_->GetDataMid() && data_channel_controller()->HasDataChannels()) { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForActiveData( + mid_generator_.GenerateString())); + } +} + +void SdpOfferAnswerHandler::GetOptionsForAnswer( + const RTCOfferAnswerOptions& offer_answer_options, + cricket::MediaSessionOptions* session_options) { + RTC_DCHECK_RUN_ON(signaling_thread()); + ExtractSharedMediaSessionOptions(offer_answer_options, session_options); + + if (IsUnifiedPlan()) { + GetOptionsForUnifiedPlanAnswer(offer_answer_options, session_options); + } else { + GetOptionsForPlanBAnswer(offer_answer_options, session_options); + } + + // Intentionally unset the data channel type for RTP data channel. Otherwise + // the RTP data channels would be successfully negotiated by default and the + // unit tests in WebRtcDataBrowserTest will fail when building with chromium. + // We want to leave RTP data channels broken, so people won't try to use them. + if (data_channel_controller()->HasRtpDataChannels() || + pc_->data_channel_type() != cricket::DCT_RTP) { + session_options->data_channel_type = pc_->data_channel_type(); + } + + // Apply ICE renomination flag. + for (auto& options : session_options->media_description_options) { + options.transport_options.enable_ice_renomination = + pc_->configuration()->enable_ice_renomination; + } + + session_options->rtcp_cname = rtcp_cname_; + session_options->crypto_options = pc_->GetCryptoOptions(); + session_options->pooled_ice_credentials = + pc_->network_thread()->Invoke>( + RTC_FROM_HERE, + rtc::Bind(&cricket::PortAllocator::GetPooledIceCredentials, + port_allocator())); +} + +void SdpOfferAnswerHandler::GetOptionsForPlanBAnswer( + const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, + cricket::MediaSessionOptions* session_options) { + // Figure out transceiver directional preferences. + bool send_audio = + !rtp_manager()->GetAudioTransceiver()->internal()->senders().empty(); + bool send_video = + !rtp_manager()->GetVideoTransceiver()->internal()->senders().empty(); + + // By default, generate sendrecv/recvonly m= sections. The direction is also + // restricted by the direction in the offer. + bool recv_audio = true; + bool recv_video = true; + + // The "offer_to_receive_X" options allow those defaults to be overridden. + if (offer_answer_options.offer_to_receive_audio != + RTCOfferAnswerOptions::kUndefined) { + recv_audio = (offer_answer_options.offer_to_receive_audio > 0); + } + if (offer_answer_options.offer_to_receive_video != + RTCOfferAnswerOptions::kUndefined) { + recv_video = (offer_answer_options.offer_to_receive_video > 0); + } + + absl::optional audio_index; + absl::optional video_index; + absl::optional data_index; + + // Generate m= sections that match those in the offer. + // Note that mediasession.cc will handle intersection our preferred + // direction with the offered direction. + GenerateMediaDescriptionOptions( + remote_description(), + RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), + RtpTransceiverDirectionFromSendRecv(send_video, recv_video), &audio_index, + &video_index, &data_index, session_options); + + cricket::MediaDescriptionOptions* audio_media_description_options = + !audio_index ? nullptr + : &session_options->media_description_options[*audio_index]; + cricket::MediaDescriptionOptions* video_media_description_options = + !video_index ? nullptr + : &session_options->media_description_options[*video_index]; + + AddPlanBRtpSenderOptions(rtp_manager()->GetSendersInternal(), + audio_media_description_options, + video_media_description_options, + offer_answer_options.num_simulcast_layers); +} + +void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanAnswer( + const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, + cricket::MediaSessionOptions* session_options) { + // Rules for generating an answer are dictated by JSEP sections 5.3.1 (Initial + // Answers) and 5.3.2 (Subsequent Answers). + RTC_DCHECK(remote_description()); + RTC_DCHECK(remote_description()->GetType() == SdpType::kOffer); + for (const ContentInfo& content : + remote_description()->description()->contents()) { + cricket::MediaType media_type = content.media_description()->type(); + if (media_type == cricket::MEDIA_TYPE_AUDIO || + media_type == cricket::MEDIA_TYPE_VIDEO) { + auto transceiver = transceivers()->FindByMid(content.name); + if (transceiver) { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForTransceiver( + transceiver, content.name, + /*is_create_offer=*/false)); + } else { + // This should only happen with rejected transceivers. + RTC_DCHECK(content.rejected); + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions(media_type, content.name, + RtpTransceiverDirection::kInactive, + /*stopped=*/true)); + } + } else if (media_type == cricket::MEDIA_TYPE_UNSUPPORTED) { + RTC_DCHECK(content.rejected); + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions(media_type, content.name, + RtpTransceiverDirection::kInactive, + /*stopped=*/true)); + } else { + RTC_CHECK_EQ(cricket::MEDIA_TYPE_DATA, media_type); + // Reject all data sections if data channels are disabled. + // Reject a data section if it has already been rejected. + // Reject all data sections except for the first one. + if (pc_->data_channel_type() == cricket::DCT_NONE || content.rejected || + content.name != *(pc_->GetDataMid())) { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForRejectedData(content.name)); + } else { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForActiveData(content.name)); + } + } + } +} + +const char* SdpOfferAnswerHandler::SessionErrorToString( + SessionError error) const { + switch (error) { + case SessionError::kNone: + return "ERROR_NONE"; + case SessionError::kContent: + return "ERROR_CONTENT"; + case SessionError::kTransport: + return "ERROR_TRANSPORT"; + } + RTC_NOTREACHED(); + return ""; +} + +std::string SdpOfferAnswerHandler::GetSessionErrorMsg() { + RTC_DCHECK_RUN_ON(signaling_thread()); + rtc::StringBuilder desc; + desc << kSessionError << SessionErrorToString(session_error()) << ". "; + desc << kSessionErrorDesc << session_error_desc() << "."; + return desc.Release(); +} + +void SdpOfferAnswerHandler::SetSessionError(SessionError error, + const std::string& error_desc) { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (error != session_error_) { + session_error_ = error; + session_error_desc_ = error_desc; + } +} + +RTCError SdpOfferAnswerHandler::HandleLegacyOfferOptions( + const PeerConnectionInterface::RTCOfferAnswerOptions& options) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(IsUnifiedPlan()); + + if (options.offer_to_receive_audio == 0) { + RemoveRecvDirectionFromReceivingTransceiversOfType( + cricket::MEDIA_TYPE_AUDIO); + } else if (options.offer_to_receive_audio == 1) { + AddUpToOneReceivingTransceiverOfType(cricket::MEDIA_TYPE_AUDIO); + } else if (options.offer_to_receive_audio > 1) { + LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_PARAMETER, + "offer_to_receive_audio > 1 is not supported."); + } + + if (options.offer_to_receive_video == 0) { + RemoveRecvDirectionFromReceivingTransceiversOfType( + cricket::MEDIA_TYPE_VIDEO); + } else if (options.offer_to_receive_video == 1) { + AddUpToOneReceivingTransceiverOfType(cricket::MEDIA_TYPE_VIDEO); + } else if (options.offer_to_receive_video > 1) { + LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_PARAMETER, + "offer_to_receive_video > 1 is not supported."); + } + + return RTCError::OK(); +} + +void SdpOfferAnswerHandler::RemoveRecvDirectionFromReceivingTransceiversOfType( + cricket::MediaType media_type) { + for (const auto& transceiver : GetReceivingTransceiversOfType(media_type)) { + RtpTransceiverDirection new_direction = + RtpTransceiverDirectionWithRecvSet(transceiver->direction(), false); + if (new_direction != transceiver->direction()) { + RTC_LOG(LS_INFO) << "Changing " << cricket::MediaTypeToString(media_type) + << " transceiver (MID=" + << transceiver->mid().value_or("") << ") from " + << RtpTransceiverDirectionToString( + transceiver->direction()) + << " to " + << RtpTransceiverDirectionToString(new_direction) + << " since CreateOffer specified offer_to_receive=0"; + transceiver->internal()->set_direction(new_direction); + } + } +} + +void SdpOfferAnswerHandler::AddUpToOneReceivingTransceiverOfType( + cricket::MediaType media_type) { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (GetReceivingTransceiversOfType(media_type).empty()) { + RTC_LOG(LS_INFO) + << "Adding one recvonly " << cricket::MediaTypeToString(media_type) + << " transceiver since CreateOffer specified offer_to_receive=1"; + RtpTransceiverInit init; + init.direction = RtpTransceiverDirection::kRecvOnly; + pc_->AddTransceiver(media_type, nullptr, init, + /*update_negotiation_needed=*/false); + } +} + +std::vector>> +SdpOfferAnswerHandler::GetReceivingTransceiversOfType( + cricket::MediaType media_type) { + std::vector< + rtc::scoped_refptr>> + receiving_transceivers; + for (const auto& transceiver : transceivers()->List()) { + if (!transceiver->stopped() && transceiver->media_type() == media_type && + RtpTransceiverDirectionHasRecv(transceiver->direction())) { + receiving_transceivers.push_back(transceiver); + } + } + return receiving_transceivers; +} + +void SdpOfferAnswerHandler::ProcessRemovalOfRemoteTrack( + rtc::scoped_refptr> + transceiver, + std::vector>* remove_list, + std::vector>* removed_streams) { + RTC_DCHECK(transceiver->mid()); + RTC_LOG(LS_INFO) << "Processing the removal of a track for MID=" + << *transceiver->mid(); + std::vector> previous_streams = + transceiver->internal()->receiver_internal()->streams(); + // This will remove the remote track from the streams. + transceiver->internal()->receiver_internal()->set_stream_ids({}); + remove_list->push_back(transceiver); + RemoveRemoteStreamsIfEmpty(previous_streams, removed_streams); +} + +void SdpOfferAnswerHandler::RemoveRemoteStreamsIfEmpty( + const std::vector>& remote_streams, + std::vector>* removed_streams) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // TODO(https://crbug.com/webrtc/9480): When we use stream IDs instead of + // streams, see if the stream was removed by checking if this was the last + // receiver with that stream ID. + for (const auto& remote_stream : remote_streams) { + if (remote_stream->GetAudioTracks().empty() && + remote_stream->GetVideoTracks().empty()) { + remote_streams_->RemoveStream(remote_stream); + removed_streams->push_back(remote_stream); + } + } +} + +void SdpOfferAnswerHandler::RemoveSenders(cricket::MediaType media_type) { + RTC_DCHECK_RUN_ON(signaling_thread()); + UpdateLocalSenders(std::vector(), media_type); + UpdateRemoteSendersList(std::vector(), false, + media_type, nullptr); +} + +void SdpOfferAnswerHandler::UpdateLocalSenders( + const std::vector& streams, + cricket::MediaType media_type) { + RTC_DCHECK_RUN_ON(signaling_thread()); + std::vector* current_senders = + rtp_manager()->GetLocalSenderInfos(media_type); + + // Find removed tracks. I.e., tracks where the track id, stream id or ssrc + // don't match the new StreamParam. + for (auto sender_it = current_senders->begin(); + sender_it != current_senders->end(); + /* incremented manually */) { + const RtpSenderInfo& info = *sender_it; + const cricket::StreamParams* params = + cricket::GetStreamBySsrc(streams, info.first_ssrc); + if (!params || params->id != info.sender_id || + params->first_stream_id() != info.stream_id) { + rtp_manager()->OnLocalSenderRemoved(info, media_type); + sender_it = current_senders->erase(sender_it); + } else { + ++sender_it; + } + } + + // Find new and active senders. + for (const cricket::StreamParams& params : streams) { + // The sync_label is the MediaStream label and the |stream.id| is the + // sender id. + const std::string& stream_id = params.first_stream_id(); + const std::string& sender_id = params.id; + uint32_t ssrc = params.first_ssrc(); + const RtpSenderInfo* sender_info = + rtp_manager()->FindSenderInfo(*current_senders, stream_id, sender_id); + if (!sender_info) { + current_senders->push_back(RtpSenderInfo(stream_id, sender_id, ssrc)); + rtp_manager()->OnLocalSenderAdded(current_senders->back(), media_type); + } + } +} + +void SdpOfferAnswerHandler::UpdateRemoteSendersList( + const cricket::StreamParamsVec& streams, + bool default_sender_needed, + cricket::MediaType media_type, + StreamCollection* new_streams) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(!IsUnifiedPlan()); + + std::vector* current_senders = + rtp_manager()->GetRemoteSenderInfos(media_type); + + // Find removed senders. I.e., senders where the sender id or ssrc don't match + // the new StreamParam. + for (auto sender_it = current_senders->begin(); + sender_it != current_senders->end(); + /* incremented manually */) { + const RtpSenderInfo& info = *sender_it; + const cricket::StreamParams* params = + cricket::GetStreamBySsrc(streams, info.first_ssrc); + std::string params_stream_id; + if (params) { + params_stream_id = + (!params->first_stream_id().empty() ? params->first_stream_id() + : kDefaultStreamId); + } + bool sender_exists = params && params->id == info.sender_id && + params_stream_id == info.stream_id; + // If this is a default track, and we still need it, don't remove it. + if ((info.stream_id == kDefaultStreamId && default_sender_needed) || + sender_exists) { + ++sender_it; + } else { + rtp_manager()->OnRemoteSenderRemoved( + info, remote_streams_->find(info.stream_id), media_type); + sender_it = current_senders->erase(sender_it); + } + } + + // Find new and active senders. + for (const cricket::StreamParams& params : streams) { + if (!params.has_ssrcs()) { + // The remote endpoint has streams, but didn't signal ssrcs. For an active + // sender, this means it is coming from a Unified Plan endpoint,so we just + // create a default. + default_sender_needed = true; + break; + } + + // |params.id| is the sender id and the stream id uses the first of + // |params.stream_ids|. The remote description could come from a Unified + // Plan endpoint, with multiple or no stream_ids() signaled. Since this is + // not supported in Plan B, we just take the first here and create the + // default stream ID if none is specified. + const std::string& stream_id = + (!params.first_stream_id().empty() ? params.first_stream_id() + : kDefaultStreamId); + const std::string& sender_id = params.id; + uint32_t ssrc = params.first_ssrc(); + + rtc::scoped_refptr stream = + remote_streams_->find(stream_id); + if (!stream) { + // This is a new MediaStream. Create a new remote MediaStream. + stream = MediaStreamProxy::Create(rtc::Thread::Current(), + MediaStream::Create(stream_id)); + remote_streams_->AddStream(stream); + new_streams->AddStream(stream); + } + + const RtpSenderInfo* sender_info = + rtp_manager()->FindSenderInfo(*current_senders, stream_id, sender_id); + if (!sender_info) { + current_senders->push_back(RtpSenderInfo(stream_id, sender_id, ssrc)); + rtp_manager()->OnRemoteSenderAdded(current_senders->back(), stream, + media_type); + } + } + + // Add default sender if necessary. + if (default_sender_needed) { + rtc::scoped_refptr default_stream = + remote_streams_->find(kDefaultStreamId); + if (!default_stream) { + // Create the new default MediaStream. + default_stream = MediaStreamProxy::Create( + rtc::Thread::Current(), MediaStream::Create(kDefaultStreamId)); + remote_streams_->AddStream(default_stream); + new_streams->AddStream(default_stream); + } + std::string default_sender_id = (media_type == cricket::MEDIA_TYPE_AUDIO) + ? kDefaultAudioSenderId + : kDefaultVideoSenderId; + const RtpSenderInfo* default_sender_info = rtp_manager()->FindSenderInfo( + *current_senders, kDefaultStreamId, default_sender_id); + if (!default_sender_info) { + current_senders->push_back( + RtpSenderInfo(kDefaultStreamId, default_sender_id, /*ssrc=*/0)); + rtp_manager()->OnRemoteSenderAdded(current_senders->back(), + default_stream, media_type); + } + } +} + +void SdpOfferAnswerHandler::EnableSending() { + RTC_DCHECK_RUN_ON(signaling_thread()); + for (const auto& transceiver : transceivers()->List()) { + cricket::ChannelInterface* channel = transceiver->internal()->channel(); + if (channel && !channel->enabled()) { + channel->Enable(true); + } + } + + if (data_channel_controller()->rtp_data_channel() && + !data_channel_controller()->rtp_data_channel()->enabled()) { + data_channel_controller()->rtp_data_channel()->Enable(true); + } +} + +RTCError SdpOfferAnswerHandler::PushdownMediaDescription( + SdpType type, + cricket::ContentSource source) { + const SessionDescriptionInterface* sdesc = + (source == cricket::CS_LOCAL ? local_description() + : remote_description()); + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(sdesc); + + if (!UpdatePayloadTypeDemuxingState(source)) { + // Note that this is never expected to fail, since RtpDemuxer doesn't return + // an error when changing payload type demux criteria, which is all this + // does. + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, + "Failed to update payload type demuxing state."); + } + + // Push down the new SDP media section for each audio/video transceiver. + for (const auto& transceiver : transceivers()->List()) { + const ContentInfo* content_info = + FindMediaSectionForTransceiver(transceiver, sdesc); + cricket::ChannelInterface* channel = transceiver->internal()->channel(); + if (!channel || !content_info || content_info->rejected) { + continue; + } + const MediaContentDescription* content_desc = + content_info->media_description(); + if (!content_desc) { + continue; + } + std::string error; + bool success = (source == cricket::CS_LOCAL) + ? channel->SetLocalContent(content_desc, type, &error) + : channel->SetRemoteContent(content_desc, type, &error); + if (!success) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, error); + } + } + + // If using the RtpDataChannel, push down the new SDP section for it too. + if (data_channel_controller()->rtp_data_channel()) { + const ContentInfo* data_content = + cricket::GetFirstDataContent(sdesc->description()); + if (data_content && !data_content->rejected) { + const MediaContentDescription* data_desc = + data_content->media_description(); + if (data_desc) { + std::string error; + bool success = (source == cricket::CS_LOCAL) + ? data_channel_controller() + ->rtp_data_channel() + ->SetLocalContent(data_desc, type, &error) + : data_channel_controller() + ->rtp_data_channel() + ->SetRemoteContent(data_desc, type, &error); + if (!success) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, error); + } + } + } + } + + // Need complete offer/answer with an SCTP m= section before starting SCTP, + // according to https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-19 + if (pc_->sctp_mid() && local_description() && remote_description()) { + rtc::scoped_refptr sctp_transport = + transport_controller()->GetSctpTransport(*(pc_->sctp_mid())); + auto local_sctp_description = cricket::GetFirstSctpDataContentDescription( + local_description()->description()); + auto remote_sctp_description = cricket::GetFirstSctpDataContentDescription( + remote_description()->description()); + if (sctp_transport && local_sctp_description && remote_sctp_description) { + int max_message_size; + // A remote max message size of zero means "any size supported". + // We configure the connection with our own max message size. + if (remote_sctp_description->max_message_size() == 0) { + max_message_size = local_sctp_description->max_message_size(); + } else { + max_message_size = + std::min(local_sctp_description->max_message_size(), + remote_sctp_description->max_message_size()); + } + sctp_transport->Start(local_sctp_description->port(), + remote_sctp_description->port(), max_message_size); + } + } + + return RTCError::OK(); +} + +RTCError SdpOfferAnswerHandler::PushdownTransportDescription( + cricket::ContentSource source, + SdpType type) { + RTC_DCHECK_RUN_ON(signaling_thread()); + + if (source == cricket::CS_LOCAL) { + const SessionDescriptionInterface* sdesc = local_description(); + RTC_DCHECK(sdesc); + return transport_controller()->SetLocalDescription(type, + sdesc->description()); + } else { + const SessionDescriptionInterface* sdesc = remote_description(); + RTC_DCHECK(sdesc); + return transport_controller()->SetRemoteDescription(type, + sdesc->description()); + } +} + +void SdpOfferAnswerHandler::RemoveStoppedTransceivers() { + RTC_DCHECK_RUN_ON(signaling_thread()); + // 3.2.10.1: For each transceiver in the connection's set of transceivers + // run the following steps: + if (!IsUnifiedPlan()) + return; + // Traverse a copy of the transceiver list. + auto transceiver_list = transceivers()->List(); + for (auto transceiver : transceiver_list) { + // 3.2.10.1.1: If transceiver is stopped, associated with an m= section + // and the associated m= section is rejected in + // connection.[[CurrentLocalDescription]] or + // connection.[[CurrentRemoteDescription]], remove the + // transceiver from the connection's set of transceivers. + if (!transceiver->stopped()) { + continue; + } + const ContentInfo* local_content = + FindMediaSectionForTransceiver(transceiver, local_description()); + const ContentInfo* remote_content = + FindMediaSectionForTransceiver(transceiver, remote_description()); + if ((local_content && local_content->rejected) || + (remote_content && remote_content->rejected)) { + RTC_LOG(LS_INFO) << "Dissociating transceiver" + << " since the media section is being recycled."; + transceiver->internal()->set_mid(absl::nullopt); + transceiver->internal()->set_mline_index(absl::nullopt); + transceivers()->Remove(transceiver); + continue; + } + if (!local_content && !remote_content) { + // TODO(bugs.webrtc.org/11973): Consider if this should be removed already + // See https://github.com/w3c/webrtc-pc/issues/2576 + RTC_LOG(LS_INFO) + << "Dropping stopped transceiver that was never associated"; + transceivers()->Remove(transceiver); + continue; + } + } +} + +void SdpOfferAnswerHandler::RemoveUnusedChannels( + const SessionDescription* desc) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Destroy video channel first since it may have a pointer to the + // voice channel. + const cricket::ContentInfo* video_info = cricket::GetFirstVideoContent(desc); + if (!video_info || video_info->rejected) { + DestroyTransceiverChannel(rtp_manager()->GetVideoTransceiver()); + } + + const cricket::ContentInfo* audio_info = cricket::GetFirstAudioContent(desc); + if (!audio_info || audio_info->rejected) { + DestroyTransceiverChannel(rtp_manager()->GetAudioTransceiver()); + } + + const cricket::ContentInfo* data_info = cricket::GetFirstDataContent(desc); + if (!data_info || data_info->rejected) { + DestroyDataChannelTransport(); + } +} + +void SdpOfferAnswerHandler::ReportNegotiatedSdpSemantics( + const SessionDescriptionInterface& answer) { + SdpSemanticNegotiated semantics_negotiated; + switch (answer.description()->msid_signaling()) { + case 0: + semantics_negotiated = kSdpSemanticNegotiatedNone; + break; + case cricket::kMsidSignalingMediaSection: + semantics_negotiated = kSdpSemanticNegotiatedUnifiedPlan; + break; + case cricket::kMsidSignalingSsrcAttribute: + semantics_negotiated = kSdpSemanticNegotiatedPlanB; + break; + case cricket::kMsidSignalingMediaSection | + cricket::kMsidSignalingSsrcAttribute: + semantics_negotiated = kSdpSemanticNegotiatedMixed; + break; + default: + RTC_NOTREACHED(); + } + RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpSemanticNegotiated", + semantics_negotiated, kSdpSemanticNegotiatedMax); +} + +void SdpOfferAnswerHandler::UpdateEndedRemoteMediaStreams() { + RTC_DCHECK_RUN_ON(signaling_thread()); + std::vector> streams_to_remove; + for (size_t i = 0; i < remote_streams_->count(); ++i) { + MediaStreamInterface* stream = remote_streams_->at(i); + if (stream->GetAudioTracks().empty() && stream->GetVideoTracks().empty()) { + streams_to_remove.push_back(stream); + } + } + + for (auto& stream : streams_to_remove) { + remote_streams_->RemoveStream(stream); + pc_->Observer()->OnRemoveStream(std::move(stream)); + } +} + +bool SdpOfferAnswerHandler::UseCandidatesInSessionDescription( + const SessionDescriptionInterface* remote_desc) { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (!remote_desc) { + return true; + } + bool ret = true; + + for (size_t m = 0; m < remote_desc->number_of_mediasections(); ++m) { + const IceCandidateCollection* candidates = remote_desc->candidates(m); + for (size_t n = 0; n < candidates->count(); ++n) { + const IceCandidateInterface* candidate = candidates->at(n); + bool valid = false; + if (!ReadyToUseRemoteCandidate(candidate, remote_desc, &valid)) { + if (valid) { + RTC_LOG(LS_INFO) + << "UseCandidatesInSessionDescription: Not ready to use " + "candidate."; + } + continue; + } + ret = UseCandidate(candidate); + if (!ret) { + break; + } + } + } + return ret; +} + +bool SdpOfferAnswerHandler::UseCandidate( + const IceCandidateInterface* candidate) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTCErrorOr result = + FindContentInfo(remote_description(), candidate); + if (!result.ok()) { + RTC_LOG(LS_ERROR) << "UseCandidate: Invalid candidate. " + << result.error().message(); + return false; + } + std::vector candidates; + candidates.push_back(candidate->candidate()); + // Invoking BaseSession method to handle remote candidates. + RTCError error = transport_controller()->AddRemoteCandidates( + result.value()->name, candidates); + if (error.ok()) { + ReportRemoteIceCandidateAdded(candidate->candidate()); + // Candidates successfully submitted for checking. + if (pc_->ice_connection_state() == + PeerConnectionInterface::kIceConnectionNew || + pc_->ice_connection_state() == + PeerConnectionInterface::kIceConnectionDisconnected) { + // If state is New, then the session has just gotten its first remote ICE + // candidates, so go to Checking. + // If state is Disconnected, the session is re-using old candidates or + // receiving additional ones, so go to Checking. + // If state is Connected, stay Connected. + // TODO(bemasc): If state is Connected, and the new candidates are for a + // newly added transport, then the state actually _should_ move to + // checking. Add a way to distinguish that case. + pc_->SetIceConnectionState( + PeerConnectionInterface::kIceConnectionChecking); + } + // TODO(bemasc): If state is Completed, go back to Connected. + } else { + RTC_LOG(LS_WARNING) << error.message(); + } + return true; +} + +// We need to check the local/remote description for the Transport instead of +// the session, because a new Transport added during renegotiation may have +// them unset while the session has them set from the previous negotiation. +// Not doing so may trigger the auto generation of transport description and +// mess up DTLS identity information, ICE credential, etc. +bool SdpOfferAnswerHandler::ReadyToUseRemoteCandidate( + const IceCandidateInterface* candidate, + const SessionDescriptionInterface* remote_desc, + bool* valid) { + RTC_DCHECK_RUN_ON(signaling_thread()); + *valid = true; + + const SessionDescriptionInterface* current_remote_desc = + remote_desc ? remote_desc : remote_description(); + + if (!current_remote_desc) { + return false; + } + + RTCErrorOr result = + FindContentInfo(current_remote_desc, candidate); + if (!result.ok()) { + RTC_LOG(LS_ERROR) << "ReadyToUseRemoteCandidate: Invalid candidate. " + << result.error().message(); + + *valid = false; + return false; + } + + std::string transport_name = GetTransportName(result.value()->name); + return !transport_name.empty(); +} + +void SdpOfferAnswerHandler::ReportRemoteIceCandidateAdded( + const cricket::Candidate& candidate) { + pc_->NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED); + if (candidate.address().IsPrivateIP()) { + pc_->NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED); + } + if (candidate.address().IsUnresolvedIP()) { + pc_->NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED); + } + if (candidate.address().family() == AF_INET6) { + pc_->NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED); + } +} + +RTCErrorOr SdpOfferAnswerHandler::FindContentInfo( + const SessionDescriptionInterface* description, + const IceCandidateInterface* candidate) { + if (candidate->sdp_mline_index() >= 0) { + size_t mediacontent_index = + static_cast(candidate->sdp_mline_index()); + size_t content_size = description->description()->contents().size(); + if (mediacontent_index < content_size) { + return &description->description()->contents()[mediacontent_index]; + } else { + return RTCError(RTCErrorType::INVALID_RANGE, + "Media line index (" + + rtc::ToString(candidate->sdp_mline_index()) + + ") out of range (number of mlines: " + + rtc::ToString(content_size) + ")."); + } + } else if (!candidate->sdp_mid().empty()) { + auto& contents = description->description()->contents(); + auto it = absl::c_find_if( + contents, [candidate](const cricket::ContentInfo& content_info) { + return content_info.mid() == candidate->sdp_mid(); + }); + if (it == contents.end()) { + return RTCError( + RTCErrorType::INVALID_PARAMETER, + "Mid " + candidate->sdp_mid() + + " specified but no media section with that mid found."); + } else { + return &*it; + } + } + + return RTCError(RTCErrorType::INVALID_PARAMETER, + "Neither sdp_mline_index nor sdp_mid specified."); +} + +RTCError SdpOfferAnswerHandler::CreateChannels(const SessionDescription& desc) { + // Creating the media channels. Transports should already have been created + // at this point. + RTC_DCHECK_RUN_ON(signaling_thread()); + const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(&desc); + if (voice && !voice->rejected && + !rtp_manager()->GetAudioTransceiver()->internal()->channel()) { + cricket::VoiceChannel* voice_channel = CreateVoiceChannel(voice->name); + if (!voice_channel) { + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, + "Failed to create voice channel."); + } + rtp_manager()->GetAudioTransceiver()->internal()->SetChannel(voice_channel); + } + + const cricket::ContentInfo* video = cricket::GetFirstVideoContent(&desc); + if (video && !video->rejected && + !rtp_manager()->GetVideoTransceiver()->internal()->channel()) { + cricket::VideoChannel* video_channel = CreateVideoChannel(video->name); + if (!video_channel) { + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, + "Failed to create video channel."); + } + rtp_manager()->GetVideoTransceiver()->internal()->SetChannel(video_channel); + } + + const cricket::ContentInfo* data = cricket::GetFirstDataContent(&desc); + if (pc_->data_channel_type() != cricket::DCT_NONE && data && + !data->rejected && !data_channel_controller()->rtp_data_channel() && + !data_channel_controller()->data_channel_transport()) { + if (!CreateDataChannel(data->name)) { + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, + "Failed to create data channel."); + } + } + + return RTCError::OK(); +} + +// TODO(steveanton): Perhaps this should be managed by the RtpTransceiver. +cricket::VoiceChannel* SdpOfferAnswerHandler::CreateVoiceChannel( + const std::string& mid) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RtpTransportInternal* rtp_transport = pc_->GetRtpTransport(mid); + + // TODO(bugs.webrtc.org/11992): CreateVoiceChannel internally switches to the + // worker thread. We shouldn't be using the |call_ptr_| hack here but simply + // be on the worker thread and use |call_| (update upstream code). + cricket::VoiceChannel* voice_channel; + { + RTC_DCHECK_RUN_ON(pc_->signaling_thread()); + voice_channel = channel_manager()->CreateVoiceChannel( + pc_->call_ptr(), pc_->configuration()->media_config, rtp_transport, + signaling_thread(), mid, pc_->SrtpRequired(), pc_->GetCryptoOptions(), + &ssrc_generator_, audio_options()); + } + if (!voice_channel) { + return nullptr; + } + voice_channel->SignalSentPacket().connect(pc_, + &PeerConnection::OnSentPacket_w); + voice_channel->SetRtpTransport(rtp_transport); + + return voice_channel; +} + +// TODO(steveanton): Perhaps this should be managed by the RtpTransceiver. +cricket::VideoChannel* SdpOfferAnswerHandler::CreateVideoChannel( + const std::string& mid) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RtpTransportInternal* rtp_transport = pc_->GetRtpTransport(mid); + + // TODO(bugs.webrtc.org/11992): CreateVideoChannel internally switches to the + // worker thread. We shouldn't be using the |call_ptr_| hack here but simply + // be on the worker thread and use |call_| (update upstream code). + cricket::VideoChannel* video_channel; + { + RTC_DCHECK_RUN_ON(pc_->signaling_thread()); + video_channel = channel_manager()->CreateVideoChannel( + pc_->call_ptr(), pc_->configuration()->media_config, rtp_transport, + signaling_thread(), mid, pc_->SrtpRequired(), pc_->GetCryptoOptions(), + &ssrc_generator_, video_options(), + video_bitrate_allocator_factory_.get()); + } + if (!video_channel) { + return nullptr; + } + video_channel->SignalSentPacket().connect(pc_, + &PeerConnection::OnSentPacket_w); + video_channel->SetRtpTransport(rtp_transport); + + return video_channel; +} + +bool SdpOfferAnswerHandler::CreateDataChannel(const std::string& mid) { + RTC_DCHECK_RUN_ON(signaling_thread()); + switch (pc_->data_channel_type()) { + case cricket::DCT_SCTP: + if (pc_->network_thread()->Invoke( + RTC_FROM_HERE, + rtc::Bind(&PeerConnection::SetupDataChannelTransport_n, pc_, + mid))) { + pc_->SetSctpDataMid(mid); + } else { + return false; + } + return true; + case cricket::DCT_RTP: + default: + RtpTransportInternal* rtp_transport = pc_->GetRtpTransport(mid); + // TODO(bugs.webrtc.org/9987): set_rtp_data_channel() should be called on + // the network thread like set_data_channel_transport is. + { + RTC_DCHECK_RUN_ON(pc_->signaling_thread()); + data_channel_controller()->set_rtp_data_channel( + channel_manager()->CreateRtpDataChannel( + pc_->configuration()->media_config, rtp_transport, + signaling_thread(), mid, pc_->SrtpRequired(), + pc_->GetCryptoOptions(), &ssrc_generator_)); + } + if (!data_channel_controller()->rtp_data_channel()) { + return false; + } + data_channel_controller()->rtp_data_channel()->SignalSentPacket().connect( + pc_, &PeerConnection::OnSentPacket_w); + data_channel_controller()->rtp_data_channel()->SetRtpTransport( + rtp_transport); + SetHavePendingRtpDataChannel(); + return true; + } + return false; +} + +void SdpOfferAnswerHandler::DestroyTransceiverChannel( + rtc::scoped_refptr> + transceiver) { + RTC_DCHECK(transceiver); + + cricket::ChannelInterface* channel = transceiver->internal()->channel(); + if (channel) { + transceiver->internal()->SetChannel(nullptr); + DestroyChannelInterface(channel); + } +} + +void SdpOfferAnswerHandler::DestroyDataChannelTransport() { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (data_channel_controller()->rtp_data_channel()) { + data_channel_controller()->OnTransportChannelClosed(); + DestroyChannelInterface(data_channel_controller()->rtp_data_channel()); + data_channel_controller()->set_rtp_data_channel(nullptr); + } + + // Note: Cannot use rtc::Bind to create a functor to invoke because it will + // grab a reference to this PeerConnection. If this is called from the + // PeerConnection destructor, the RefCountedObject vtable will have already + // been destroyed (since it is a subclass of PeerConnection) and using + // rtc::Bind will cause "Pure virtual function called" error to appear. + + if (pc_->sctp_mid()) { + RTC_DCHECK_RUN_ON(pc_->signaling_thread()); + data_channel_controller()->OnTransportChannelClosed(); + pc_->network_thread()->Invoke(RTC_FROM_HERE, [this] { + RTC_DCHECK_RUN_ON(pc_->network_thread()); + pc_->TeardownDataChannelTransport_n(); + }); + pc_->ResetSctpDataMid(); + } +} + +void SdpOfferAnswerHandler::DestroyChannelInterface( + cricket::ChannelInterface* channel) { + // TODO(bugs.webrtc.org/11992): All the below methods should be called on the + // worker thread. (they switch internally anyway). Change + // DestroyChannelInterface to either be called on the worker thread, or do + // this asynchronously on the worker. + RTC_DCHECK(channel); + switch (channel->media_type()) { + case cricket::MEDIA_TYPE_AUDIO: + channel_manager()->DestroyVoiceChannel( + static_cast(channel)); + break; + case cricket::MEDIA_TYPE_VIDEO: + channel_manager()->DestroyVideoChannel( + static_cast(channel)); + break; + case cricket::MEDIA_TYPE_DATA: + channel_manager()->DestroyRtpDataChannel( + static_cast(channel)); + break; + default: + RTC_NOTREACHED() << "Unknown media type: " << channel->media_type(); + break; + } +} + +void SdpOfferAnswerHandler::DestroyAllChannels() { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (!transceivers()) { + return; + } + // Destroy video channels first since they may have a pointer to a voice + // channel. + for (const auto& transceiver : transceivers()->List()) { + if (transceiver->media_type() == cricket::MEDIA_TYPE_VIDEO) { + DestroyTransceiverChannel(transceiver); + } + } + for (const auto& transceiver : transceivers()->List()) { + if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { + DestroyTransceiverChannel(transceiver); + } + } + DestroyDataChannelTransport(); +} + +void SdpOfferAnswerHandler::GenerateMediaDescriptionOptions( + const SessionDescriptionInterface* session_desc, + RtpTransceiverDirection audio_direction, + RtpTransceiverDirection video_direction, + absl::optional* audio_index, + absl::optional* video_index, + absl::optional* data_index, + cricket::MediaSessionOptions* session_options) { + RTC_DCHECK_RUN_ON(signaling_thread()); + for (const cricket::ContentInfo& content : + session_desc->description()->contents()) { + if (IsAudioContent(&content)) { + // If we already have an audio m= section, reject this extra one. + if (*audio_index) { + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions( + cricket::MEDIA_TYPE_AUDIO, content.name, + RtpTransceiverDirection::kInactive, /*stopped=*/true)); + } else { + bool stopped = (audio_direction == RtpTransceiverDirection::kInactive); + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions(cricket::MEDIA_TYPE_AUDIO, + content.name, audio_direction, + stopped)); + *audio_index = session_options->media_description_options.size() - 1; + } + session_options->media_description_options.back().header_extensions = + channel_manager()->GetSupportedAudioRtpHeaderExtensions(); + } else if (IsVideoContent(&content)) { + // If we already have an video m= section, reject this extra one. + if (*video_index) { + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions( + cricket::MEDIA_TYPE_VIDEO, content.name, + RtpTransceiverDirection::kInactive, /*stopped=*/true)); + } else { + bool stopped = (video_direction == RtpTransceiverDirection::kInactive); + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions(cricket::MEDIA_TYPE_VIDEO, + content.name, video_direction, + stopped)); + *video_index = session_options->media_description_options.size() - 1; + } + session_options->media_description_options.back().header_extensions = + channel_manager()->GetSupportedVideoRtpHeaderExtensions(); + } else if (IsUnsupportedContent(&content)) { + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions(cricket::MEDIA_TYPE_UNSUPPORTED, + content.name, + RtpTransceiverDirection::kInactive, + /*stopped=*/true)); + } else { + RTC_DCHECK(IsDataContent(&content)); + // If we already have an data m= section, reject this extra one. + if (*data_index) { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForRejectedData(content.name)); + } else { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForActiveData(content.name)); + *data_index = session_options->media_description_options.size() - 1; + } + } + } +} + +cricket::MediaDescriptionOptions +SdpOfferAnswerHandler::GetMediaDescriptionOptionsForActiveData( + const std::string& mid) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Direction for data sections is meaningless, but legacy endpoints might + // expect sendrecv. + cricket::MediaDescriptionOptions options(cricket::MEDIA_TYPE_DATA, mid, + RtpTransceiverDirection::kSendRecv, + /*stopped=*/false); + AddRtpDataChannelOptions(*(data_channel_controller()->rtp_data_channels()), + &options); + return options; +} + +cricket::MediaDescriptionOptions +SdpOfferAnswerHandler::GetMediaDescriptionOptionsForRejectedData( + const std::string& mid) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + cricket::MediaDescriptionOptions options(cricket::MEDIA_TYPE_DATA, mid, + RtpTransceiverDirection::kInactive, + /*stopped=*/true); + AddRtpDataChannelOptions(*(data_channel_controller()->rtp_data_channels()), + &options); + return options; +} + +const std::string SdpOfferAnswerHandler::GetTransportName( + const std::string& content_name) { + RTC_DCHECK_RUN_ON(signaling_thread()); + cricket::ChannelInterface* channel = pc_->GetChannel(content_name); + if (channel) { + return channel->transport_name(); + } + if (data_channel_controller()->data_channel_transport()) { + RTC_DCHECK(pc_->sctp_mid()); + if (content_name == *(pc_->sctp_mid())) { + return *(pc_->sctp_transport_name()); + } + } + // Return an empty string if failed to retrieve the transport name. + return ""; +} + +bool SdpOfferAnswerHandler::UpdatePayloadTypeDemuxingState( + cricket::ContentSource source) { + RTC_DCHECK_RUN_ON(signaling_thread()); + // We may need to delete any created default streams and disable creation of + // new ones on the basis of payload type. This is needed to avoid SSRC + // collisions in Call's RtpDemuxer, in the case that a transceiver has + // created a default stream, and then some other channel gets the SSRC + // signaled in the corresponding Unified Plan "m=" section. Specifically, we + // need to disable payload type based demuxing when two bundled "m=" sections + // are using the same payload type(s). For more context + // see https://bugs.chromium.org/p/webrtc/issues/detail?id=11477 + const SessionDescriptionInterface* sdesc = + (source == cricket::CS_LOCAL ? local_description() + : remote_description()); + const cricket::ContentGroup* bundle_group = + sdesc->description()->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); + std::set audio_payload_types; + std::set video_payload_types; + bool pt_demuxing_enabled_audio = true; + bool pt_demuxing_enabled_video = true; + for (auto& content_info : sdesc->description()->contents()) { + // If this m= section isn't bundled, it's safe to demux by payload type + // since other m= sections using the same payload type will also be using + // different transports. + if (!bundle_group || !bundle_group->HasContentName(content_info.name)) { + continue; + } + if (content_info.rejected || + (source == cricket::ContentSource::CS_LOCAL && + !RtpTransceiverDirectionHasRecv( + content_info.media_description()->direction())) || + (source == cricket::ContentSource::CS_REMOTE && + !RtpTransceiverDirectionHasSend( + content_info.media_description()->direction()))) { + // Ignore transceivers that are not receiving. + continue; + } + switch (content_info.media_description()->type()) { + case cricket::MediaType::MEDIA_TYPE_AUDIO: { + const cricket::AudioContentDescription* audio_desc = + content_info.media_description()->as_audio(); + for (const cricket::AudioCodec& audio : audio_desc->codecs()) { + if (audio_payload_types.count(audio.id)) { + // Two m= sections are using the same payload type, thus demuxing + // by payload type is not possible. + pt_demuxing_enabled_audio = false; + } + audio_payload_types.insert(audio.id); + } + break; + } + case cricket::MediaType::MEDIA_TYPE_VIDEO: { + const cricket::VideoContentDescription* video_desc = + content_info.media_description()->as_video(); + for (const cricket::VideoCodec& video : video_desc->codecs()) { + if (video_payload_types.count(video.id)) { + // Two m= sections are using the same payload type, thus demuxing + // by payload type is not possible. + pt_demuxing_enabled_video = false; + } + video_payload_types.insert(video.id); + } + break; + } + default: + // Ignore data channels. + continue; + } + } + + // Gather all updates ahead of time so that all channels can be updated in a + // single Invoke; necessary due to thread guards. + std::vector> + channels_to_update; + for (const auto& transceiver : transceivers()->List()) { + cricket::ChannelInterface* channel = transceiver->internal()->channel(); + const ContentInfo* content = + FindMediaSectionForTransceiver(transceiver, sdesc); + if (!channel || !content) { + continue; + } + RtpTransceiverDirection local_direction = + content->media_description()->direction(); + if (source == cricket::CS_REMOTE) { + local_direction = RtpTransceiverDirectionReversed(local_direction); + } + channels_to_update.emplace_back(local_direction, + transceiver->internal()->channel()); + } + + if (channels_to_update.empty()) { + return true; + } + return pc_->worker_thread()->Invoke( + RTC_FROM_HERE, [&channels_to_update, bundle_group, + pt_demuxing_enabled_audio, pt_demuxing_enabled_video]() { + for (const auto& it : channels_to_update) { + RtpTransceiverDirection local_direction = it.first; + cricket::ChannelInterface* channel = it.second; + cricket::MediaType media_type = channel->media_type(); + bool in_bundle_group = (bundle_group && bundle_group->HasContentName( + channel->content_name())); + if (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO) { + if (!channel->SetPayloadTypeDemuxingEnabled( + (!in_bundle_group || pt_demuxing_enabled_audio) && + RtpTransceiverDirectionHasRecv(local_direction))) { + return false; + } + } else if (media_type == cricket::MediaType::MEDIA_TYPE_VIDEO) { + if (!channel->SetPayloadTypeDemuxingEnabled( + (!in_bundle_group || pt_demuxing_enabled_video) && + RtpTransceiverDirectionHasRecv(local_direction))) { + return false; + } + } + } + return true; + }); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/sdp_offer_answer.h b/TMessagesProj/jni/voip/webrtc/pc/sdp_offer_answer.h new file mode 100644 index 000000000..43a3dbb5a --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/sdp_offer_answer.h @@ -0,0 +1,676 @@ +/* + * Copyright 2020 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. + */ + +#ifndef PC_SDP_OFFER_ANSWER_H_ +#define PC_SDP_OFFER_ANSWER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/types/optional.h" +#include "api/audio_options.h" +#include "api/candidate.h" +#include "api/jsep.h" +#include "api/jsep_ice_candidate.h" +#include "api/media_stream_interface.h" +#include "api/media_types.h" +#include "api/peer_connection_interface.h" +#include "api/rtc_error.h" +#include "api/rtp_transceiver_direction.h" +#include "api/rtp_transceiver_interface.h" +#include "api/scoped_refptr.h" +#include "api/set_local_description_observer_interface.h" +#include "api/set_remote_description_observer_interface.h" +#include "api/transport/data_channel_transport_interface.h" +#include "api/turn_customizer.h" +#include "api/video/video_bitrate_allocator_factory.h" +#include "media/base/media_channel.h" +#include "media/base/stream_params.h" +#include "p2p/base/port_allocator.h" +#include "pc/channel.h" +#include "pc/channel_interface.h" +#include "pc/channel_manager.h" +#include "pc/data_channel_controller.h" +#include "pc/ice_server_parsing.h" +#include "pc/jsep_transport_controller.h" +#include "pc/media_session.h" +#include "pc/media_stream_observer.h" +#include "pc/peer_connection_factory.h" +#include "pc/peer_connection_internal.h" +#include "pc/rtc_stats_collector.h" +#include "pc/rtp_receiver.h" +#include "pc/rtp_sender.h" +#include "pc/rtp_transceiver.h" +#include "pc/rtp_transmission_manager.h" +#include "pc/sctp_transport.h" +#include "pc/sdp_state_provider.h" +#include "pc/session_description.h" +#include "pc/stats_collector.h" +#include "pc/stream_collection.h" +#include "pc/transceiver_list.h" +#include "pc/webrtc_session_description_factory.h" +#include "rtc_base/checks.h" +#include "rtc_base/experiments/field_trial_parser.h" +#include "rtc_base/operations_chain.h" +#include "rtc_base/race_checker.h" +#include "rtc_base/rtc_certificate.h" +#include "rtc_base/ssl_stream_adapter.h" +#include "rtc_base/synchronization/sequence_checker.h" +#include "rtc_base/third_party/sigslot/sigslot.h" +#include "rtc_base/thread.h" +#include "rtc_base/thread_annotations.h" +#include "rtc_base/unique_id_generator.h" +#include "rtc_base/weak_ptr.h" + +namespace webrtc { + +// SdpOfferAnswerHandler is a component +// of the PeerConnection object as defined +// by the PeerConnectionInterface API surface. +// The class is responsible for the following: +// - Parsing and interpreting SDP. +// - Generating offers and answers based on the current state. +// This class lives on the signaling thread. +class SdpOfferAnswerHandler : public SdpStateProvider, + public sigslot::has_slots<> { + public: + ~SdpOfferAnswerHandler(); + + // Creates an SdpOfferAnswerHandler. Modifies dependencies. + static std::unique_ptr Create( + PeerConnection* pc, + const PeerConnectionInterface::RTCConfiguration& configuration, + PeerConnectionDependencies& dependencies); + + void ResetSessionDescFactory() { + RTC_DCHECK_RUN_ON(signaling_thread()); + webrtc_session_desc_factory_.reset(); + } + const WebRtcSessionDescriptionFactory* webrtc_session_desc_factory() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return webrtc_session_desc_factory_.get(); + } + + // Change signaling state to Closed, and perform appropriate actions. + void Close(); + + // Called as part of destroying the owning PeerConnection. + void PrepareForShutdown(); + + // Implementation of SdpStateProvider + PeerConnectionInterface::SignalingState signaling_state() const override; + + const SessionDescriptionInterface* local_description() const override; + const SessionDescriptionInterface* remote_description() const override; + const SessionDescriptionInterface* current_local_description() const override; + const SessionDescriptionInterface* current_remote_description() + const override; + const SessionDescriptionInterface* pending_local_description() const override; + const SessionDescriptionInterface* pending_remote_description() + const override; + + bool NeedsIceRestart(const std::string& content_name) const override; + bool IceRestartPending(const std::string& content_name) const override; + absl::optional GetDtlsRole( + const std::string& mid) const override; + + void RestartIce(); + + // JSEP01 + void CreateOffer( + CreateSessionDescriptionObserver* observer, + const PeerConnectionInterface::RTCOfferAnswerOptions& options); + void CreateAnswer( + CreateSessionDescriptionObserver* observer, + const PeerConnectionInterface::RTCOfferAnswerOptions& options); + + void SetLocalDescription( + std::unique_ptr desc, + rtc::scoped_refptr observer); + void SetLocalDescription( + rtc::scoped_refptr observer); + void SetLocalDescription(SetSessionDescriptionObserver* observer, + SessionDescriptionInterface* desc); + void SetLocalDescription(SetSessionDescriptionObserver* observer); + + void SetRemoteDescription( + std::unique_ptr desc, + rtc::scoped_refptr observer); + void SetRemoteDescription(SetSessionDescriptionObserver* observer, + SessionDescriptionInterface* desc); + + PeerConnectionInterface::RTCConfiguration GetConfiguration(); + RTCError SetConfiguration( + const PeerConnectionInterface::RTCConfiguration& configuration); + bool AddIceCandidate(const IceCandidateInterface* candidate); + void AddIceCandidate(std::unique_ptr candidate, + std::function callback); + bool RemoveIceCandidates(const std::vector& candidates); + // Adds a locally generated candidate to the local description. + void AddLocalIceCandidate(const JsepIceCandidate* candidate); + void RemoveLocalIceCandidates( + const std::vector& candidates); + bool ShouldFireNegotiationNeededEvent(uint32_t event_id); + + bool AddStream(MediaStreamInterface* local_stream); + void RemoveStream(MediaStreamInterface* local_stream); + + absl::optional is_caller(); + bool HasNewIceCredentials(); + void UpdateNegotiationNeeded(); + void SetHavePendingRtpDataChannel() { + RTC_DCHECK_RUN_ON(signaling_thread()); + have_pending_rtp_data_channel_ = true; + } + + // Returns the media section in the given session description that is + // associated with the RtpTransceiver. Returns null if none found or this + // RtpTransceiver is not associated. Logic varies depending on the + // SdpSemantics specified in the configuration. + const cricket::ContentInfo* FindMediaSectionForTransceiver( + rtc::scoped_refptr> + transceiver, + const SessionDescriptionInterface* sdesc) const; + + // Destroys all BaseChannels and destroys the SCTP data channel, if present. + void DestroyAllChannels(); + + rtc::scoped_refptr local_streams(); + rtc::scoped_refptr remote_streams(); + + private: + class ImplicitCreateSessionDescriptionObserver; + + friend class ImplicitCreateSessionDescriptionObserver; + class SetSessionDescriptionObserverAdapter; + + friend class SetSessionDescriptionObserverAdapter; + + enum class SessionError { + kNone, // No error. + kContent, // Error in BaseChannel SetLocalContent/SetRemoteContent. + kTransport, // Error from the underlying transport. + }; + + // Represents the [[LocalIceCredentialsToReplace]] internal slot in the spec. + // It makes the next CreateOffer() produce new ICE credentials even if + // RTCOfferAnswerOptions::ice_restart is false. + // https://w3c.github.io/webrtc-pc/#dfn-localufragstoreplace + // TODO(hbos): When JsepTransportController/JsepTransport supports rollback, + // move this type of logic to JsepTransportController/JsepTransport. + class LocalIceCredentialsToReplace; + + // Only called by the Create() function. + explicit SdpOfferAnswerHandler(PeerConnection* pc); + // Called from the `Create()` function. Can only be called + // once. Modifies dependencies. + void Initialize( + const PeerConnectionInterface::RTCConfiguration& configuration, + PeerConnectionDependencies& dependencies); + + rtc::Thread* signaling_thread() const; + // Non-const versions of local_description()/remote_description(), for use + // internally. + SessionDescriptionInterface* mutable_local_description() + RTC_RUN_ON(signaling_thread()) { + return pending_local_description_ ? pending_local_description_.get() + : current_local_description_.get(); + } + SessionDescriptionInterface* mutable_remote_description() + RTC_RUN_ON(signaling_thread()) { + return pending_remote_description_ ? pending_remote_description_.get() + : current_remote_description_.get(); + } + + // Synchronous implementations of SetLocalDescription/SetRemoteDescription + // that return an RTCError instead of invoking a callback. + RTCError ApplyLocalDescription( + std::unique_ptr desc); + RTCError ApplyRemoteDescription( + std::unique_ptr desc); + + // Implementation of the offer/answer exchange operations. These are chained + // onto the |operations_chain_| when the public CreateOffer(), CreateAnswer(), + // SetLocalDescription() and SetRemoteDescription() methods are invoked. + void DoCreateOffer( + const PeerConnectionInterface::RTCOfferAnswerOptions& options, + rtc::scoped_refptr observer); + void DoCreateAnswer( + const PeerConnectionInterface::RTCOfferAnswerOptions& options, + rtc::scoped_refptr observer); + void DoSetLocalDescription( + std::unique_ptr desc, + rtc::scoped_refptr observer); + void DoSetRemoteDescription( + std::unique_ptr desc, + rtc::scoped_refptr observer); + + // Update the state, signaling if necessary. + void ChangeSignalingState( + PeerConnectionInterface::SignalingState signaling_state); + + RTCError UpdateSessionState(SdpType type, + cricket::ContentSource source, + const cricket::SessionDescription* description); + + bool IsUnifiedPlan() const RTC_RUN_ON(signaling_thread()); + + // Signals from MediaStreamObserver. + void OnAudioTrackAdded(AudioTrackInterface* track, + MediaStreamInterface* stream) + RTC_RUN_ON(signaling_thread()); + void OnAudioTrackRemoved(AudioTrackInterface* track, + MediaStreamInterface* stream) + RTC_RUN_ON(signaling_thread()); + void OnVideoTrackAdded(VideoTrackInterface* track, + MediaStreamInterface* stream) + RTC_RUN_ON(signaling_thread()); + void OnVideoTrackRemoved(VideoTrackInterface* track, + MediaStreamInterface* stream) + RTC_RUN_ON(signaling_thread()); + + // | desc_type | is the type of the description that caused the rollback. + RTCError Rollback(SdpType desc_type); + void OnOperationsChainEmpty(); + + // Runs the algorithm **set the associated remote streams** specified in + // https://w3c.github.io/webrtc-pc/#set-associated-remote-streams. + void SetAssociatedRemoteStreams( + rtc::scoped_refptr receiver, + const std::vector& stream_ids, + std::vector>* added_streams, + std::vector>* removed_streams); + + bool CheckIfNegotiationIsNeeded(); + void GenerateNegotiationNeededEvent(); + // Helper method which verifies SDP. + RTCError ValidateSessionDescription(const SessionDescriptionInterface* sdesc, + cricket::ContentSource source) + RTC_RUN_ON(signaling_thread()); + + // Updates the local RtpTransceivers according to the JSEP rules. Called as + // part of setting the local/remote description. + RTCError UpdateTransceiversAndDataChannels( + cricket::ContentSource source, + const SessionDescriptionInterface& new_session, + const SessionDescriptionInterface* old_local_description, + const SessionDescriptionInterface* old_remote_description); + + // Associate the given transceiver according to the JSEP rules. + RTCErrorOr< + rtc::scoped_refptr>> + AssociateTransceiver(cricket::ContentSource source, + SdpType type, + size_t mline_index, + const cricket::ContentInfo& content, + const cricket::ContentInfo* old_local_content, + const cricket::ContentInfo* old_remote_content) + RTC_RUN_ON(signaling_thread()); + + // If the BUNDLE policy is max-bundle, then we know for sure that all + // transports will be bundled from the start. This method returns the BUNDLE + // group if that's the case, or null if BUNDLE will be negotiated later. An + // error is returned if max-bundle is specified but the session description + // does not have a BUNDLE group. + RTCErrorOr GetEarlyBundleGroup( + const cricket::SessionDescription& desc) const + RTC_RUN_ON(signaling_thread()); + + // Either creates or destroys the transceiver's BaseChannel according to the + // given media section. + RTCError UpdateTransceiverChannel( + rtc::scoped_refptr> + transceiver, + const cricket::ContentInfo& content, + const cricket::ContentGroup* bundle_group) RTC_RUN_ON(signaling_thread()); + + // Either creates or destroys the local data channel according to the given + // media section. + RTCError UpdateDataChannel(cricket::ContentSource source, + const cricket::ContentInfo& content, + const cricket::ContentGroup* bundle_group) + RTC_RUN_ON(signaling_thread()); + // Check if a call to SetLocalDescription is acceptable with a session + // description of the given type. + bool ExpectSetLocalDescription(SdpType type); + // Check if a call to SetRemoteDescription is acceptable with a session + // description of the given type. + bool ExpectSetRemoteDescription(SdpType type); + + // The offer/answer machinery assumes the media section MID is present and + // unique. To support legacy end points that do not supply a=mid lines, this + // method will modify the session description to add MIDs generated according + // to the SDP semantics. + void FillInMissingRemoteMids(cricket::SessionDescription* remote_description); + + // Returns an RtpTransciever, if available, that can be used to receive the + // given media type according to JSEP rules. + rtc::scoped_refptr> + FindAvailableTransceiverToReceive(cricket::MediaType media_type) const; + + // Returns a MediaSessionOptions struct with options decided by |options|, + // the local MediaStreams and DataChannels. + void GetOptionsForOffer(const PeerConnectionInterface::RTCOfferAnswerOptions& + offer_answer_options, + cricket::MediaSessionOptions* session_options); + void GetOptionsForPlanBOffer( + const PeerConnectionInterface::RTCOfferAnswerOptions& + offer_answer_options, + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); + void GetOptionsForUnifiedPlanOffer( + const PeerConnectionInterface::RTCOfferAnswerOptions& + offer_answer_options, + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); + + // Returns a MediaSessionOptions struct with options decided by + // |constraints|, the local MediaStreams and DataChannels. + void GetOptionsForAnswer(const PeerConnectionInterface::RTCOfferAnswerOptions& + offer_answer_options, + cricket::MediaSessionOptions* session_options); + void GetOptionsForPlanBAnswer( + const PeerConnectionInterface::RTCOfferAnswerOptions& + offer_answer_options, + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); + void GetOptionsForUnifiedPlanAnswer( + const PeerConnectionInterface::RTCOfferAnswerOptions& + offer_answer_options, + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); + + const char* SessionErrorToString(SessionError error) const; + std::string GetSessionErrorMsg(); + // Returns the last error in the session. See the enum above for details. + SessionError session_error() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return session_error_; + } + const std::string& session_error_desc() const { return session_error_desc_; } + + RTCError HandleLegacyOfferOptions( + const PeerConnectionInterface::RTCOfferAnswerOptions& options); + void RemoveRecvDirectionFromReceivingTransceiversOfType( + cricket::MediaType media_type) RTC_RUN_ON(signaling_thread()); + void AddUpToOneReceivingTransceiverOfType(cricket::MediaType media_type); + + std::vector< + rtc::scoped_refptr>> + GetReceivingTransceiversOfType(cricket::MediaType media_type) + RTC_RUN_ON(signaling_thread()); + + // Runs the algorithm specified in + // https://w3c.github.io/webrtc-pc/#process-remote-track-removal + // This method will update the following lists: + // |remove_list| is the list of transceivers for which the receiving track is + // being removed. + // |removed_streams| is the list of streams which no longer have a receiving + // track so should be removed. + void ProcessRemovalOfRemoteTrack( + rtc::scoped_refptr> + transceiver, + std::vector>* remove_list, + std::vector>* removed_streams); + + void RemoveRemoteStreamsIfEmpty( + const std::vector>& + remote_streams, + std::vector>* removed_streams); + + // Remove all local and remote senders of type |media_type|. + // Called when a media type is rejected (m-line set to port 0). + void RemoveSenders(cricket::MediaType media_type); + + // Loops through the vector of |streams| and finds added and removed + // StreamParams since last time this method was called. + // For each new or removed StreamParam, OnLocalSenderSeen or + // OnLocalSenderRemoved is invoked. + void UpdateLocalSenders(const std::vector& streams, + cricket::MediaType media_type); + + // Makes sure a MediaStreamTrack is created for each StreamParam in |streams|, + // and existing MediaStreamTracks are removed if there is no corresponding + // StreamParam. If |default_track_needed| is true, a default MediaStreamTrack + // is created if it doesn't exist; if false, it's removed if it exists. + // |media_type| is the type of the |streams| and can be either audio or video. + // If a new MediaStream is created it is added to |new_streams|. + void UpdateRemoteSendersList( + const std::vector& streams, + bool default_track_needed, + cricket::MediaType media_type, + StreamCollection* new_streams); + + // Enables media channels to allow sending of media. + // This enables media to flow on all configured audio/video channels and the + // RtpDataChannel. + void EnableSending(); + // Push the media parts of the local or remote session description + // down to all of the channels. + RTCError PushdownMediaDescription(SdpType type, + cricket::ContentSource source); + + RTCError PushdownTransportDescription(cricket::ContentSource source, + SdpType type); + // Helper function to remove stopped transceivers. + void RemoveStoppedTransceivers(); + // Deletes the corresponding channel of contents that don't exist in |desc|. + // |desc| can be null. This means that all channels are deleted. + void RemoveUnusedChannels(const cricket::SessionDescription* desc); + + // Report inferred negotiated SDP semantics from a local/remote answer to the + // UMA observer. + void ReportNegotiatedSdpSemantics(const SessionDescriptionInterface& answer); + + // Finds remote MediaStreams without any tracks and removes them from + // |remote_streams_| and notifies the observer that the MediaStreams no longer + // exist. + void UpdateEndedRemoteMediaStreams(); + + // Uses all remote candidates in |remote_desc| in this session. + bool UseCandidatesInSessionDescription( + const SessionDescriptionInterface* remote_desc); + // Uses |candidate| in this session. + bool UseCandidate(const IceCandidateInterface* candidate); + // Returns true if we are ready to push down the remote candidate. + // |remote_desc| is the new remote description, or NULL if the current remote + // description should be used. Output |valid| is true if the candidate media + // index is valid. + bool ReadyToUseRemoteCandidate(const IceCandidateInterface* candidate, + const SessionDescriptionInterface* remote_desc, + bool* valid); + void ReportRemoteIceCandidateAdded(const cricket::Candidate& candidate) + RTC_RUN_ON(signaling_thread()); + + RTCErrorOr FindContentInfo( + const SessionDescriptionInterface* description, + const IceCandidateInterface* candidate) RTC_RUN_ON(signaling_thread()); + + // Functions for dealing with transports. + // Note that cricket code uses the term "channel" for what other code + // refers to as "transport". + + // Allocates media channels based on the |desc|. If |desc| doesn't have + // the BUNDLE option, this method will disable BUNDLE in PortAllocator. + // This method will also delete any existing media channels before creating. + RTCError CreateChannels(const cricket::SessionDescription& desc); + + // Helper methods to create media channels. + cricket::VoiceChannel* CreateVoiceChannel(const std::string& mid); + cricket::VideoChannel* CreateVideoChannel(const std::string& mid); + bool CreateDataChannel(const std::string& mid); + + // Destroys and clears the BaseChannel associated with the given transceiver, + // if such channel is set. + void DestroyTransceiverChannel( + rtc::scoped_refptr> + transceiver); + + // Destroys the RTP data channel transport and/or the SCTP data channel + // transport and clears it. + void DestroyDataChannelTransport(); + + // Destroys the given ChannelInterface. + // The channel cannot be accessed after this method is called. + void DestroyChannelInterface(cricket::ChannelInterface* channel); + // Generates MediaDescriptionOptions for the |session_opts| based on existing + // local description or remote description. + + void GenerateMediaDescriptionOptions( + const SessionDescriptionInterface* session_desc, + RtpTransceiverDirection audio_direction, + RtpTransceiverDirection video_direction, + absl::optional* audio_index, + absl::optional* video_index, + absl::optional* data_index, + cricket::MediaSessionOptions* session_options); + + // Generates the active MediaDescriptionOptions for the local data channel + // given the specified MID. + cricket::MediaDescriptionOptions GetMediaDescriptionOptionsForActiveData( + const std::string& mid) const; + + // Generates the rejected MediaDescriptionOptions for the local data channel + // given the specified MID. + cricket::MediaDescriptionOptions GetMediaDescriptionOptionsForRejectedData( + const std::string& mid) const; + + const std::string GetTransportName(const std::string& content_name); + // Based on number of transceivers per media type, enabled or disable + // payload type based demuxing in the affected channels. + bool UpdatePayloadTypeDemuxingState(cricket::ContentSource source); + + // ================================================================== + // Access to pc_ variables + cricket::ChannelManager* channel_manager() const; + TransceiverList* transceivers(); + const TransceiverList* transceivers() const; + DataChannelController* data_channel_controller(); + const DataChannelController* data_channel_controller() const; + cricket::PortAllocator* port_allocator(); + const cricket::PortAllocator* port_allocator() const; + RtpTransmissionManager* rtp_manager(); + const RtpTransmissionManager* rtp_manager() const; + JsepTransportController* transport_controller(); + const JsepTransportController* transport_controller() const; + // =================================================================== + const cricket::AudioOptions& audio_options() { return audio_options_; } + const cricket::VideoOptions& video_options() { return video_options_; } + + PeerConnection* const pc_; + + std::unique_ptr webrtc_session_desc_factory_ + RTC_GUARDED_BY(signaling_thread()); + + std::unique_ptr current_local_description_ + RTC_GUARDED_BY(signaling_thread()); + std::unique_ptr pending_local_description_ + RTC_GUARDED_BY(signaling_thread()); + std::unique_ptr current_remote_description_ + RTC_GUARDED_BY(signaling_thread()); + std::unique_ptr pending_remote_description_ + RTC_GUARDED_BY(signaling_thread()); + + PeerConnectionInterface::SignalingState signaling_state_ + RTC_GUARDED_BY(signaling_thread()) = PeerConnectionInterface::kStable; + + // Whether this peer is the caller. Set when the local description is applied. + absl::optional is_caller_ RTC_GUARDED_BY(signaling_thread()); + + // Streams added via AddStream. + const rtc::scoped_refptr local_streams_ + RTC_GUARDED_BY(signaling_thread()); + // Streams created as a result of SetRemoteDescription. + const rtc::scoped_refptr remote_streams_ + RTC_GUARDED_BY(signaling_thread()); + + std::vector> stream_observers_ + RTC_GUARDED_BY(signaling_thread()); + + // The operations chain is used by the offer/answer exchange methods to ensure + // they are executed in the right order. For example, if + // SetRemoteDescription() is invoked while CreateOffer() is still pending, the + // SRD operation will not start until CreateOffer() has completed. See + // https://w3c.github.io/webrtc-pc/#dfn-operations-chain. + rtc::scoped_refptr operations_chain_ + RTC_GUARDED_BY(signaling_thread()); + + // One PeerConnection has only one RTCP CNAME. + // https://tools.ietf.org/html/draft-ietf-rtcweb-rtp-usage-26#section-4.9 + const std::string rtcp_cname_; + + // MIDs will be generated using this generator which will keep track of + // all the MIDs that have been seen over the life of the PeerConnection. + rtc::UniqueStringGenerator mid_generator_ RTC_GUARDED_BY(signaling_thread()); + + // List of content names for which the remote side triggered an ICE restart. + std::set pending_ice_restarts_ + RTC_GUARDED_BY(signaling_thread()); + + std::unique_ptr + local_ice_credentials_to_replace_ RTC_GUARDED_BY(signaling_thread()); + + bool remote_peer_supports_msid_ RTC_GUARDED_BY(signaling_thread()) = false; + bool is_negotiation_needed_ RTC_GUARDED_BY(signaling_thread()) = false; + uint32_t negotiation_needed_event_id_ = 0; + bool update_negotiation_needed_on_empty_chain_ + RTC_GUARDED_BY(signaling_thread()) = false; + + // In Unified Plan, if we encounter remote SDP that does not contain an a=msid + // line we create and use a stream with a random ID for our receivers. This is + // to support legacy endpoints that do not support the a=msid attribute (as + // opposed to streamless tracks with "a=msid:-"). + rtc::scoped_refptr missing_msid_default_stream_ + RTC_GUARDED_BY(signaling_thread()); + + // Used when rolling back RTP data channels. + bool have_pending_rtp_data_channel_ RTC_GUARDED_BY(signaling_thread()) = + false; + + // Updates the error state, signaling if necessary. + void SetSessionError(SessionError error, const std::string& error_desc); + + SessionError session_error_ RTC_GUARDED_BY(signaling_thread()) = + SessionError::kNone; + std::string session_error_desc_ RTC_GUARDED_BY(signaling_thread()); + + // Member variables for caching global options. + cricket::AudioOptions audio_options_ RTC_GUARDED_BY(signaling_thread()); + cricket::VideoOptions video_options_ RTC_GUARDED_BY(signaling_thread()); + + // This object should be used to generate any SSRC that is not explicitly + // specified by the user (or by the remote party). + // The generator is not used directly, instead it is passed on to the + // channel manager and the session description factory. + rtc::UniqueRandomIdGenerator ssrc_generator_ + RTC_GUARDED_BY(signaling_thread()); + + // A video bitrate allocator factory. + // This can be injected using the PeerConnectionDependencies, + // or else the CreateBuiltinVideoBitrateAllocatorFactory() will be called. + // Note that one can still choose to override this in a MediaEngine + // if one wants too. + std::unique_ptr + video_bitrate_allocator_factory_; + + rtc::WeakPtrFactory weak_ptr_factory_ + RTC_GUARDED_BY(signaling_thread()); +}; + +} // namespace webrtc + +#endif // PC_SDP_OFFER_ANSWER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/pc/sdp_state_provider.h b/TMessagesProj/jni/voip/webrtc/pc/sdp_state_provider.h new file mode 100644 index 000000000..23ffc91bd --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/sdp_state_provider.h @@ -0,0 +1,54 @@ +/* + * Copyright 2020 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. + */ + +#ifndef PC_SDP_STATE_PROVIDER_H_ +#define PC_SDP_STATE_PROVIDER_H_ + +#include + +#include "api/jsep.h" +#include "api/peer_connection_interface.h" + +namespace webrtc { + +// This interface provides access to the state of an SDP offer/answer +// negotiation. +// +// All the functions are const, so using this interface serves as +// assurance that the user is not modifying the state. +class SdpStateProvider { + public: + virtual ~SdpStateProvider() {} + + virtual PeerConnectionInterface::SignalingState signaling_state() const = 0; + + virtual const SessionDescriptionInterface* local_description() const = 0; + virtual const SessionDescriptionInterface* remote_description() const = 0; + virtual const SessionDescriptionInterface* current_local_description() + const = 0; + virtual const SessionDescriptionInterface* current_remote_description() + const = 0; + virtual const SessionDescriptionInterface* pending_local_description() + const = 0; + virtual const SessionDescriptionInterface* pending_remote_description() + const = 0; + + // Whether an ICE restart has been asked for. Used in CreateOffer. + virtual bool NeedsIceRestart(const std::string& content_name) const = 0; + // Whether an ICE restart was indicated in the remote offer. + // Used in CreateAnswer. + virtual bool IceRestartPending(const std::string& content_name) const = 0; + virtual absl::optional GetDtlsRole( + const std::string& mid) const = 0; +}; + +} // namespace webrtc + +#endif // PC_SDP_STATE_PROVIDER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/pc/session_description.h b/TMessagesProj/jni/voip/webrtc/pc/session_description.h index 53c981a34..52a3a1fe0 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/session_description.h +++ b/TMessagesProj/jni/voip/webrtc/pc/session_description.h @@ -58,6 +58,7 @@ class AudioContentDescription; class VideoContentDescription; class RtpDataContentDescription; class SctpDataContentDescription; +class UnsupportedContentDescription; // Describes a session description media section. There are subclasses for each // media type (audio, video, data) that will have additional information. @@ -86,6 +87,11 @@ class MediaContentDescription { virtual SctpDataContentDescription* as_sctp() { return nullptr; } virtual const SctpDataContentDescription* as_sctp() const { return nullptr; } + virtual UnsupportedContentDescription* as_unsupported() { return nullptr; } + virtual const UnsupportedContentDescription* as_unsupported() const { + return nullptr; + } + virtual bool has_codecs() const = 0; // Copy operator that returns an unique_ptr. @@ -406,13 +412,37 @@ class SctpDataContentDescription : public MediaContentDescription { int max_message_size_ = 64 * 1024; }; +class UnsupportedContentDescription : public MediaContentDescription { + public: + explicit UnsupportedContentDescription(const std::string& media_type) + : media_type_(media_type) {} + MediaType type() const override { return MEDIA_TYPE_UNSUPPORTED; } + + UnsupportedContentDescription* as_unsupported() override { return this; } + const UnsupportedContentDescription* as_unsupported() const override { + return this; + } + + bool has_codecs() const override { return false; } + const std::string& media_type() const { return media_type_; } + + private: + UnsupportedContentDescription* CloneInternal() const override { + return new UnsupportedContentDescription(*this); + } + + std::string media_type_; +}; + // Protocol used for encoding media. This is the "top level" protocol that may // be wrapped by zero or many transport protocols (UDP, ICE, etc.). enum class MediaProtocolType { - kRtp, // Section will use the RTP protocol (e.g., for audio or video). - // https://tools.ietf.org/html/rfc3550 - kSctp // Section will use the SCTP protocol (e.g., for a data channel). - // https://tools.ietf.org/html/rfc4960 + kRtp, // Section will use the RTP protocol (e.g., for audio or video). + // https://tools.ietf.org/html/rfc3550 + kSctp, // Section will use the SCTP protocol (e.g., for a data channel). + // https://tools.ietf.org/html/rfc4960 + kOther // Section will use another top protocol which is not + // explicitly supported. }; // Represents a session description section. Most information about the section diff --git a/TMessagesProj/jni/voip/webrtc/pc/stats_collector.cc b/TMessagesProj/jni/voip/webrtc/pc/stats_collector.cc index 73d4510fa..991cc4eb2 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/stats_collector.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/stats_collector.cc @@ -16,7 +16,6 @@ #include #include "pc/channel.h" -#include "pc/peer_connection.h" #include "rtc_base/checks.h" #include "rtc_base/third_party/base64/base64.h" #include "system_wrappers/include/field_trial.h" @@ -991,7 +990,8 @@ class VoiceMediaChannelStatsGatherer final : public MediaChannelStatsGatherer { } bool GetStatsOnWorkerThread() override { - return voice_media_channel_->GetStats(&voice_media_info); + return voice_media_channel_->GetStats(&voice_media_info, + /*get_and_clear_legacy_stats=*/true); } void ExtractStats(StatsCollector* collector) const override { diff --git a/TMessagesProj/jni/voip/webrtc/pc/stats_collector.h b/TMessagesProj/jni/voip/webrtc/pc/stats_collector.h index 041fe2f8f..befbcabbf 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/stats_collector.h +++ b/TMessagesProj/jni/voip/webrtc/pc/stats_collector.h @@ -27,6 +27,7 @@ #include "api/stats_types.h" #include "p2p/base/port.h" #include "pc/peer_connection_internal.h" +#include "pc/stats_collector_interface.h" #include "rtc_base/network_constants.h" #include "rtc_base/ssl_certificate.h" @@ -44,7 +45,7 @@ const char* AdapterTypeToStatsType(rtc::AdapterType type); // A mapping between track ids and their StatsReport. typedef std::map TrackIdMap; -class StatsCollector { +class StatsCollector : public StatsCollectorInterface { public: // The caller is responsible for ensuring that the pc outlives the // StatsCollector instance. @@ -57,11 +58,13 @@ class StatsCollector { void AddTrack(MediaStreamTrackInterface* track); // Adds a local audio track that is used for getting some voice statistics. - void AddLocalAudioTrack(AudioTrackInterface* audio_track, uint32_t ssrc); + void AddLocalAudioTrack(AudioTrackInterface* audio_track, + uint32_t ssrc) override; // Removes a local audio tracks that is used for getting some voice // statistics. - void RemoveLocalAudioTrack(AudioTrackInterface* audio_track, uint32_t ssrc); + void RemoveLocalAudioTrack(AudioTrackInterface* audio_track, + uint32_t ssrc) override; // Gather statistics from the session and store them for future use. void UpdateStats(PeerConnectionInterface::StatsOutputLevel level); @@ -74,7 +77,8 @@ class StatsCollector { // of filling in |reports|. As is, there's a requirement that the caller // uses |reports| immediately without allowing any async activity on // the thread (message handling etc) and then discard the results. - void GetStats(MediaStreamTrackInterface* track, StatsReports* reports); + void GetStats(MediaStreamTrackInterface* track, + StatsReports* reports) override; // Prepare a local or remote SSRC report for the given ssrc. Used internally // in the ExtractStatsFromList template. diff --git a/TMessagesProj/jni/voip/webrtc/pc/stats_collector_interface.h b/TMessagesProj/jni/voip/webrtc/pc/stats_collector_interface.h new file mode 100644 index 000000000..4d5c98a4a --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/stats_collector_interface.h @@ -0,0 +1,43 @@ +/* + * Copyright 2020 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. + */ + +// This file contains an interface for the (obsolete) StatsCollector class that +// is used by compilation units that do not wish to depend on the StatsCollector +// implementation. + +#ifndef PC_STATS_COLLECTOR_INTERFACE_H_ +#define PC_STATS_COLLECTOR_INTERFACE_H_ + +#include + +#include "api/media_stream_interface.h" +#include "api/stats_types.h" + +namespace webrtc { + +class StatsCollectorInterface { + public: + virtual ~StatsCollectorInterface() {} + + // Adds a local audio track that is used for getting some voice statistics. + virtual void AddLocalAudioTrack(AudioTrackInterface* audio_track, + uint32_t ssrc) = 0; + + // Removes a local audio tracks that is used for getting some voice + // statistics. + virtual void RemoveLocalAudioTrack(AudioTrackInterface* audio_track, + uint32_t ssrc) = 0; + virtual void GetStats(MediaStreamTrackInterface* track, + StatsReports* reports) = 0; +}; + +} // namespace webrtc + +#endif // PC_STATS_COLLECTOR_INTERFACE_H_ diff --git a/TMessagesProj/jni/voip/webrtc/pc/transceiver_list.cc b/TMessagesProj/jni/voip/webrtc/pc/transceiver_list.cc new file mode 100644 index 000000000..5fe148a22 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/transceiver_list.cc @@ -0,0 +1,67 @@ +/* + * Copyright 2020 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 "pc/transceiver_list.h" + +namespace webrtc { + +void TransceiverStableState::set_newly_created() { + RTC_DCHECK(!has_m_section_); + newly_created_ = true; +} + +void TransceiverStableState::SetMSectionIfUnset( + absl::optional mid, + absl::optional mline_index) { + if (!has_m_section_) { + mid_ = mid; + mline_index_ = mline_index; + has_m_section_ = true; + } +} + +void TransceiverStableState::SetRemoteStreamIdsIfUnset( + const std::vector& ids) { + if (!remote_stream_ids_.has_value()) { + remote_stream_ids_ = ids; + } +} + +RtpTransceiverProxyRefPtr TransceiverList::FindBySender( + rtc::scoped_refptr sender) const { + for (auto transceiver : transceivers_) { + if (transceiver->sender() == sender) { + return transceiver; + } + } + return nullptr; +} + +RtpTransceiverProxyRefPtr TransceiverList::FindByMid( + const std::string& mid) const { + for (auto transceiver : transceivers_) { + if (transceiver->mid() == mid) { + return transceiver; + } + } + return nullptr; +} + +RtpTransceiverProxyRefPtr TransceiverList::FindByMLineIndex( + size_t mline_index) const { + for (auto transceiver : transceivers_) { + if (transceiver->internal()->mline_index() == mline_index) { + return transceiver; + } + } + return nullptr; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/transceiver_list.h b/TMessagesProj/jni/voip/webrtc/pc/transceiver_list.h new file mode 100644 index 000000000..cd77d67f4 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/transceiver_list.h @@ -0,0 +1,100 @@ +/* + * Copyright 2020 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. + */ + +#ifndef PC_TRANSCEIVER_LIST_H_ +#define PC_TRANSCEIVER_LIST_H_ + +#include +#include +#include +#include + +#include "pc/rtp_transceiver.h" + +namespace webrtc { + +typedef rtc::scoped_refptr> + RtpTransceiverProxyRefPtr; + +// Captures partial state to be used for rollback. Applicable only in +// Unified Plan. +class TransceiverStableState { + public: + TransceiverStableState() {} + void set_newly_created(); + void SetMSectionIfUnset(absl::optional mid, + absl::optional mline_index); + void SetRemoteStreamIdsIfUnset(const std::vector& ids); + absl::optional mid() const { return mid_; } + absl::optional mline_index() const { return mline_index_; } + absl::optional> remote_stream_ids() const { + return remote_stream_ids_; + } + bool has_m_section() const { return has_m_section_; } + bool newly_created() const { return newly_created_; } + + private: + absl::optional mid_; + absl::optional mline_index_; + absl::optional> remote_stream_ids_; + // Indicates that mid value from stable state has been captured and + // that rollback has to restore the transceiver. Also protects against + // subsequent overwrites. + bool has_m_section_ = false; + // Indicates that the transceiver was created as part of applying a + // description to track potential need for removing transceiver during + // rollback. + bool newly_created_ = false; +}; + +class TransceiverList { + public: + std::vector List() const { return transceivers_; } + + void Add(RtpTransceiverProxyRefPtr transceiver) { + transceivers_.push_back(transceiver); + } + void Remove(RtpTransceiverProxyRefPtr transceiver) { + transceivers_.erase( + std::remove(transceivers_.begin(), transceivers_.end(), transceiver), + transceivers_.end()); + } + RtpTransceiverProxyRefPtr FindBySender( + rtc::scoped_refptr sender) const; + RtpTransceiverProxyRefPtr FindByMid(const std::string& mid) const; + RtpTransceiverProxyRefPtr FindByMLineIndex(size_t mline_index) const; + + // Find or create the stable state for a transceiver. + TransceiverStableState* StableState(RtpTransceiverProxyRefPtr transceiver) { + return &(transceiver_stable_states_by_transceivers_[transceiver]); + } + + void DiscardStableStates() { + transceiver_stable_states_by_transceivers_.clear(); + } + + std::map& StableStates() { + return transceiver_stable_states_by_transceivers_; + } + + private: + std::vector transceivers_; + // Holds changes made to transceivers during applying descriptors for + // potential rollback. Gets cleared once signaling state goes to stable. + std::map + transceiver_stable_states_by_transceivers_; + // Holds remote stream ids for transceivers from stable state. + std::map> + remote_stream_ids_by_transceivers_; +}; + +} // namespace webrtc + +#endif // PC_TRANSCEIVER_LIST_H_ diff --git a/TMessagesProj/jni/voip/webrtc/pc/usage_pattern.cc b/TMessagesProj/jni/voip/webrtc/pc/usage_pattern.cc new file mode 100644 index 000000000..848472148 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/usage_pattern.cc @@ -0,0 +1,49 @@ +/* + * Copyright 2020 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 "pc/usage_pattern.h" + +#include "api/peer_connection_interface.h" +#include "rtc_base/logging.h" +#include "system_wrappers/include/metrics.h" + +namespace webrtc { + +void UsagePattern::NoteUsageEvent(UsageEvent event) { + usage_event_accumulator_ |= static_cast(event); +} + +void UsagePattern::ReportUsagePattern(PeerConnectionObserver* observer) const { + RTC_DLOG(LS_INFO) << "Usage signature is " << usage_event_accumulator_; + RTC_HISTOGRAM_ENUMERATION_SPARSE("WebRTC.PeerConnection.UsagePattern", + usage_event_accumulator_, + static_cast(UsageEvent::MAX_VALUE)); + const int bad_bits = + static_cast(UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED) | + static_cast(UsageEvent::CANDIDATE_COLLECTED); + const int good_bits = + static_cast(UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED) | + static_cast(UsageEvent::REMOTE_CANDIDATE_ADDED) | + static_cast(UsageEvent::ICE_STATE_CONNECTED); + if ((usage_event_accumulator_ & bad_bits) == bad_bits && + (usage_event_accumulator_ & good_bits) == 0) { + // If called after close(), we can't report, because observer may have + // been deallocated, and therefore pointer is null. Write to log instead. + if (observer) { + observer->OnInterestingUsage(usage_event_accumulator_); + } else { + RTC_LOG(LS_INFO) << "Interesting usage signature " + << usage_event_accumulator_ + << " observed after observer shutdown"; + } + } +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/pc/usage_pattern.h b/TMessagesProj/jni/voip/webrtc/pc/usage_pattern.h new file mode 100644 index 000000000..c4a8918ac --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/pc/usage_pattern.h @@ -0,0 +1,75 @@ +/* + * Copyright 2020 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. + */ + +#ifndef PC_USAGE_PATTERN_H_ +#define PC_USAGE_PATTERN_H_ + +namespace webrtc { + +class PeerConnectionObserver; + +// A bit in the usage pattern is registered when its defining event occurs +// at least once. +enum class UsageEvent : int { + TURN_SERVER_ADDED = 0x01, + STUN_SERVER_ADDED = 0x02, + DATA_ADDED = 0x04, + AUDIO_ADDED = 0x08, + VIDEO_ADDED = 0x10, + // |SetLocalDescription| returns successfully. + SET_LOCAL_DESCRIPTION_SUCCEEDED = 0x20, + // |SetRemoteDescription| returns successfully. + SET_REMOTE_DESCRIPTION_SUCCEEDED = 0x40, + // A local candidate (with type host, server-reflexive, or relay) is + // collected. + CANDIDATE_COLLECTED = 0x80, + // A remote candidate is successfully added via |AddIceCandidate|. + ADD_ICE_CANDIDATE_SUCCEEDED = 0x100, + ICE_STATE_CONNECTED = 0x200, + CLOSE_CALLED = 0x400, + // A local candidate with private IP is collected. + PRIVATE_CANDIDATE_COLLECTED = 0x800, + // A remote candidate with private IP is added, either via AddiceCandidate + // or from the remote description. + REMOTE_PRIVATE_CANDIDATE_ADDED = 0x1000, + // A local mDNS candidate is collected. + MDNS_CANDIDATE_COLLECTED = 0x2000, + // A remote mDNS candidate is added, either via AddIceCandidate or from the + // remote description. + REMOTE_MDNS_CANDIDATE_ADDED = 0x4000, + // A local candidate with IPv6 address is collected. + IPV6_CANDIDATE_COLLECTED = 0x8000, + // A remote candidate with IPv6 address is added, either via AddIceCandidate + // or from the remote description. + REMOTE_IPV6_CANDIDATE_ADDED = 0x10000, + // A remote candidate (with type host, server-reflexive, or relay) is + // successfully added, either via AddIceCandidate or from the remote + // description. + REMOTE_CANDIDATE_ADDED = 0x20000, + // An explicit host-host candidate pair is selected, i.e. both the local and + // the remote candidates have the host type. This does not include candidate + // pairs formed with equivalent prflx remote candidates, e.g. a host-prflx + // pair where the prflx candidate has the same base as a host candidate of + // the remote peer. + DIRECT_CONNECTION_SELECTED = 0x40000, + MAX_VALUE = 0x80000, +}; + +class UsagePattern { + public: + void NoteUsageEvent(UsageEvent event); + void ReportUsagePattern(PeerConnectionObserver* observer) const; + + private: + int usage_event_accumulator_ = 0; +}; + +} // namespace webrtc +#endif // PC_USAGE_PATTERN_H_ diff --git a/TMessagesProj/jni/voip/webrtc/pc/video_rtp_receiver.cc b/TMessagesProj/jni/voip/webrtc/pc/video_rtp_receiver.cc index f093bf4b3..dd601259e 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/video_rtp_receiver.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/video_rtp_receiver.cc @@ -16,7 +16,6 @@ #include #include "api/media_stream_proxy.h" -#include "api/media_stream_track_proxy.h" #include "api/video_track_source_proxy.h" #include "pc/jitter_buffer_delay.h" #include "pc/jitter_buffer_delay_proxy.h" @@ -43,7 +42,7 @@ VideoRtpReceiver::VideoRtpReceiver( : worker_thread_(worker_thread), id_(receiver_id), source_(new RefCountedObject(this)), - track_(VideoTrackProxy::Create( + track_(VideoTrackProxyWithInternal::Create( rtc::Thread::Current(), worker_thread, VideoTrack::Create( @@ -136,6 +135,11 @@ void VideoRtpReceiver::Stop() { stopped_ = true; } +void VideoRtpReceiver::StopAndEndTrack() { + Stop(); + track_->internal()->set_ended(); +} + void VideoRtpReceiver::RestartMediaChannel(absl::optional ssrc) { RTC_DCHECK(media_channel_); if (!stopped_ && ssrc_ == ssrc) { diff --git a/TMessagesProj/jni/voip/webrtc/pc/video_rtp_receiver.h b/TMessagesProj/jni/voip/webrtc/pc/video_rtp_receiver.h index f66a8a789..74ae44431 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/video_rtp_receiver.h +++ b/TMessagesProj/jni/voip/webrtc/pc/video_rtp_receiver.h @@ -20,6 +20,7 @@ #include "api/crypto/frame_decryptor_interface.h" #include "api/frame_transformer_interface.h" #include "api/media_stream_interface.h" +#include "api/media_stream_track_proxy.h" #include "api/media_types.h" #include "api/rtp_parameters.h" #include "api/rtp_receiver_interface.h" @@ -31,6 +32,7 @@ #include "pc/jitter_buffer_delay_interface.h" #include "pc/rtp_receiver.h" #include "pc/video_rtp_track_source.h" +#include "pc/video_track.h" #include "rtc_base/ref_counted_object.h" #include "rtc_base/thread.h" @@ -89,6 +91,7 @@ class VideoRtpReceiver : public rtc::RefCountedObject, // RtpReceiverInternal implementation. void Stop() override; + void StopAndEndTrack() override; void SetupMediaChannel(uint32_t ssrc) override; void SetupUnsignaledMediaChannel() override; uint32_t ssrc() const override { return ssrc_.value_or(0); } @@ -130,7 +133,7 @@ class VideoRtpReceiver : public rtc::RefCountedObject, // |source_| is held here to be able to change the state of the source when // the VideoRtpReceiver is stopped. rtc::scoped_refptr source_; - rtc::scoped_refptr track_; + rtc::scoped_refptr> track_; std::vector> streams_; bool stopped_ = true; RtpReceiverObserverInterface* observer_ = nullptr; diff --git a/TMessagesProj/jni/voip/webrtc/pc/video_track.h b/TMessagesProj/jni/voip/webrtc/pc/video_track.h index 90e0758a6..b7835dee2 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/video_track.h +++ b/TMessagesProj/jni/voip/webrtc/pc/video_track.h @@ -14,12 +14,12 @@ #include #include "api/media_stream_interface.h" +#include "api/media_stream_track.h" #include "api/scoped_refptr.h" #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" #include "api/video/video_source_interface.h" #include "media/base/video_source_base.h" -#include "pc/media_stream_track.h" #include "rtc_base/thread.h" #include "rtc_base/thread_annotations.h" #include "rtc_base/thread_checker.h" diff --git a/TMessagesProj/jni/voip/webrtc/pc/webrtc_sdp.cc b/TMessagesProj/jni/voip/webrtc/pc/webrtc_sdp.cc index 4af121ddc..9643dcc16 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/webrtc_sdp.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/webrtc_sdp.cc @@ -75,6 +75,7 @@ using cricket::StreamParams; using cricket::StreamParamsVec; using cricket::TransportDescription; using cricket::TransportInfo; +using cricket::UnsupportedContentDescription; using cricket::VideoContentDescription; using rtc::SocketAddress; @@ -276,9 +277,6 @@ static bool ParseSessionDescription(const std::string& message, rtc::SocketAddress* connection_addr, cricket::SessionDescription* desc, SdpParseError* error); -static bool ParseGroupAttribute(const std::string& line, - cricket::SessionDescription* desc, - SdpParseError* error); static bool ParseMediaDescription( const std::string& message, const TransportDescription& session_td, @@ -302,6 +300,9 @@ static bool ParseContent( TransportDescription* transport, std::vector>* candidates, SdpParseError* error); +static bool ParseGroupAttribute(const std::string& line, + cricket::SessionDescription* desc, + SdpParseError* error); static bool ParseSsrcAttribute(const std::string& line, SsrcInfoVec* ssrc_infos, int* msid_signaling, @@ -1346,30 +1347,24 @@ void BuildMediaDescription(const ContentInfo* content_info, // RFC 4566 // m= // fmt is a list of payload type numbers that MAY be used in the session. - const char* type = NULL; - if (media_type == cricket::MEDIA_TYPE_AUDIO) - type = kMediaTypeAudio; - else if (media_type == cricket::MEDIA_TYPE_VIDEO) - type = kMediaTypeVideo; - else if (media_type == cricket::MEDIA_TYPE_DATA) - type = kMediaTypeData; - else - RTC_NOTREACHED(); - + std::string type; std::string fmt; if (media_type == cricket::MEDIA_TYPE_VIDEO) { + type = kMediaTypeVideo; const VideoContentDescription* video_desc = media_desc->as_video(); for (const cricket::VideoCodec& codec : video_desc->codecs()) { fmt.append(" "); fmt.append(rtc::ToString(codec.id)); } } else if (media_type == cricket::MEDIA_TYPE_AUDIO) { + type = kMediaTypeAudio; const AudioContentDescription* audio_desc = media_desc->as_audio(); for (const cricket::AudioCodec& codec : audio_desc->codecs()) { fmt.append(" "); fmt.append(rtc::ToString(codec.id)); } } else if (media_type == cricket::MEDIA_TYPE_DATA) { + type = kMediaTypeData; const cricket::SctpDataContentDescription* sctp_data_desc = media_desc->as_sctp(); if (sctp_data_desc) { @@ -1388,6 +1383,12 @@ void BuildMediaDescription(const ContentInfo* content_info, fmt.append(rtc::ToString(codec.id)); } } + } else if (media_type == cricket::MEDIA_TYPE_UNSUPPORTED) { + const UnsupportedContentDescription* unsupported_desc = + media_desc->as_unsupported(); + type = unsupported_desc->media_type(); + } else { + RTC_NOTREACHED(); } // The fmt must never be empty. If no codecs are found, set the fmt attribute // to 0. @@ -2711,7 +2712,17 @@ bool ParseMediaDescription( } } else { RTC_LOG(LS_WARNING) << "Unsupported media type: " << line; - continue; + auto unsupported_desc = + std::make_unique(media_type); + if (!ParseContent(message, cricket::MEDIA_TYPE_UNSUPPORTED, mline_index, + protocol, payload_types, pos, &content_name, + &bundle_only, §ion_msid_signaling, + unsupported_desc.get(), &transport, candidates, + error)) { + return false; + } + unsupported_desc->set_protocol(protocol); + content = std::move(unsupported_desc); } if (!content.get()) { // ParseContentDescription returns NULL if failed. @@ -2739,7 +2750,9 @@ bool ParseMediaDescription( content_rejected = port_rejected; } - if (cricket::IsRtpProtocol(protocol) && !content->as_sctp()) { + if (content->as_unsupported()) { + content_rejected = true; + } else if (cricket::IsRtpProtocol(protocol) && !content->as_sctp()) { content->set_protocol(protocol); // Set the extmap. if (!session_extmaps.empty() && @@ -3031,11 +3044,11 @@ bool ParseContent(const std::string& message, // the first place and provides another way to get around the limitation. if (media_type == cricket::MEDIA_TYPE_DATA && cricket::IsRtpProtocol(protocol) && - (b > cricket::kDataMaxBandwidth / 1000 || + (b > cricket::kRtpDataMaxBandwidth / 1000 || bandwidth_type == kTransportSpecificBandwidth)) { rtc::StringBuilder description; description << "RTP-based data channels may not send more than " - << cricket::kDataMaxBandwidth / 1000 << "kbps."; + << cricket::kRtpDataMaxBandwidth / 1000 << "kbps."; return ParseFailed(line, description.str(), error); } // Convert values. Prevent integer overflow. diff --git a/TMessagesProj/jni/voip/webrtc/pc/webrtc_session_description_factory.cc b/TMessagesProj/jni/voip/webrtc/pc/webrtc_session_description_factory.cc index aaef7fdeb..2a9dc3fbd 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/webrtc_session_description_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/pc/webrtc_session_description_factory.cc @@ -11,9 +11,10 @@ #include "pc/webrtc_session_description_factory.h" #include - +#include #include #include +#include #include #include @@ -22,6 +23,7 @@ #include "api/jsep.h" #include "api/jsep_session_description.h" #include "api/rtc_error.h" +#include "pc/sdp_state_provider.h" #include "pc/session_description.h" #include "rtc_base/checks.h" #include "rtc_base/location.h" @@ -125,11 +127,14 @@ void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( rtc::Thread* signaling_thread, cricket::ChannelManager* channel_manager, - PeerConnectionInternal* pc, + const SdpStateProvider* sdp_info, const std::string& session_id, + bool dtls_enabled, std::unique_ptr cert_generator, const rtc::scoped_refptr& certificate, - UniqueRandomIdGenerator* ssrc_generator) + UniqueRandomIdGenerator* ssrc_generator, + std::function&)> + on_certificate_ready) : signaling_thread_(signaling_thread), session_desc_factory_(channel_manager, &transport_desc_factory_, @@ -139,20 +144,21 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( // to just use a random number as session id and start version from // |kInitSessionVersion|. session_version_(kInitSessionVersion), - cert_generator_(std::move(cert_generator)), - pc_(pc), + cert_generator_(dtls_enabled ? std::move(cert_generator) : nullptr), + sdp_info_(sdp_info), session_id_(session_id), - certificate_request_state_(CERTIFICATE_NOT_NEEDED) { + certificate_request_state_(CERTIFICATE_NOT_NEEDED), + on_certificate_ready_(on_certificate_ready) { RTC_DCHECK(signaling_thread_); - RTC_DCHECK(!(cert_generator_ && certificate)); - bool dtls_enabled = cert_generator_ || certificate; - // SRTP-SDES is disabled if DTLS is on. - SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); + if (!dtls_enabled) { + SetSdesPolicy(cricket::SEC_REQUIRED); RTC_LOG(LS_VERBOSE) << "DTLS-SRTP disabled."; return; } + // SRTP-SDES is disabled if DTLS is on. + SetSdesPolicy(cricket::SEC_DISABLED); if (certificate) { // Use |certificate|. certificate_request_state_ = CERTIFICATE_WAITING; @@ -252,13 +258,13 @@ void WebRtcSessionDescriptionFactory::CreateAnswer( PostCreateSessionDescriptionFailed(observer, error); return; } - if (!pc_->remote_description()) { + if (!sdp_info_->remote_description()) { error += " can't be called before SetRemoteDescription."; RTC_LOG(LS_ERROR) << error; PostCreateSessionDescriptionFailed(observer, error); return; } - if (pc_->remote_description()->GetType() != SdpType::kOffer) { + if (sdp_info_->remote_description()->GetType() != SdpType::kOffer) { error += " failed because remote_description is not an offer."; RTC_LOG(LS_ERROR) << error; PostCreateSessionDescriptionFailed(observer, error); @@ -325,12 +331,12 @@ void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { void WebRtcSessionDescriptionFactory::InternalCreateOffer( CreateSessionDescriptionRequest request) { - if (pc_->local_description()) { + if (sdp_info_->local_description()) { // If the needs-ice-restart flag is set as described by JSEP, we should // generate an offer with a new ufrag/password to trigger an ICE restart. for (cricket::MediaDescriptionOptions& options : request.options.media_description_options) { - if (pc_->NeedsIceRestart(options.mid)) { + if (sdp_info_->NeedsIceRestart(options.mid)) { options.transport_options.ice_restart = true; } } @@ -338,8 +344,8 @@ void WebRtcSessionDescriptionFactory::InternalCreateOffer( std::unique_ptr desc = session_desc_factory_.CreateOffer( - request.options, pc_->local_description() - ? pc_->local_description()->description() + request.options, sdp_info_->local_description() + ? sdp_info_->local_description()->description() : nullptr); if (!desc) { PostCreateSessionDescriptionFailed(request.observer, @@ -360,11 +366,11 @@ void WebRtcSessionDescriptionFactory::InternalCreateOffer( auto offer = std::make_unique( SdpType::kOffer, std::move(desc), session_id_, rtc::ToString(session_version_++)); - if (pc_->local_description()) { + if (sdp_info_->local_description()) { for (const cricket::MediaDescriptionOptions& options : request.options.media_description_options) { if (!options.transport_options.ice_restart) { - CopyCandidatesFromSessionDescription(pc_->local_description(), + CopyCandidatesFromSessionDescription(sdp_info_->local_description(), options.mid, offer.get()); } } @@ -374,31 +380,34 @@ void WebRtcSessionDescriptionFactory::InternalCreateOffer( void WebRtcSessionDescriptionFactory::InternalCreateAnswer( CreateSessionDescriptionRequest request) { - if (pc_->remote_description()) { + if (sdp_info_->remote_description()) { for (cricket::MediaDescriptionOptions& options : request.options.media_description_options) { // According to http://tools.ietf.org/html/rfc5245#section-9.2.1.1 // an answer should also contain new ICE ufrag and password if an offer // has been received with new ufrag and password. options.transport_options.ice_restart = - pc_->IceRestartPending(options.mid); - // We should pass the current SSL role to the transport description + sdp_info_->IceRestartPending(options.mid); + // We should pass the current DTLS role to the transport description // factory, if there is already an existing ongoing session. - rtc::SSLRole ssl_role; - if (pc_->GetSslRole(options.mid, &ssl_role)) { + absl::optional dtls_role = + sdp_info_->GetDtlsRole(options.mid); + if (dtls_role) { options.transport_options.prefer_passive_role = - (rtc::SSL_SERVER == ssl_role); + (rtc::SSL_SERVER == *dtls_role); } } } std::unique_ptr desc = session_desc_factory_.CreateAnswer( - pc_->remote_description() ? pc_->remote_description()->description() - : nullptr, + sdp_info_->remote_description() + ? sdp_info_->remote_description()->description() + : nullptr, request.options, - pc_->local_description() ? pc_->local_description()->description() - : nullptr); + sdp_info_->local_description() + ? sdp_info_->local_description()->description() + : nullptr); if (!desc) { PostCreateSessionDescriptionFailed(request.observer, "Failed to initialize the answer."); @@ -416,13 +425,13 @@ void WebRtcSessionDescriptionFactory::InternalCreateAnswer( auto answer = std::make_unique( SdpType::kAnswer, std::move(desc), session_id_, rtc::ToString(session_version_++)); - if (pc_->local_description()) { + if (sdp_info_->local_description()) { // Include all local ICE candidates in the SessionDescription unless // the remote peer has requested an ICE restart. for (const cricket::MediaDescriptionOptions& options : request.options.media_description_options) { if (!options.transport_options.ice_restart) { - CopyCandidatesFromSessionDescription(pc_->local_description(), + CopyCandidatesFromSessionDescription(sdp_info_->local_description(), options.mid, answer.get()); } } @@ -481,7 +490,8 @@ void WebRtcSessionDescriptionFactory::SetCertificate( RTC_LOG(LS_VERBOSE) << "Setting new certificate."; certificate_request_state_ = CERTIFICATE_SUCCEEDED; - SignalCertificateReady(certificate); + + on_certificate_ready_(certificate); transport_desc_factory_.set_certificate(certificate); transport_desc_factory_.set_secure(cricket::SEC_ENABLED); diff --git a/TMessagesProj/jni/voip/webrtc/pc/webrtc_session_description_factory.h b/TMessagesProj/jni/voip/webrtc/pc/webrtc_session_description_factory.h index f70b847b4..9256045d6 100644 --- a/TMessagesProj/jni/voip/webrtc/pc/webrtc_session_description_factory.h +++ b/TMessagesProj/jni/voip/webrtc/pc/webrtc_session_description_factory.h @@ -12,7 +12,6 @@ #define PC_WEBRTC_SESSION_DESCRIPTION_FACTORY_H_ #include - #include #include #include @@ -22,22 +21,23 @@ #include "api/scoped_refptr.h" #include "p2p/base/transport_description.h" #include "p2p/base/transport_description_factory.h" +#include "pc/channel_manager.h" #include "pc/media_session.h" -#include "pc/peer_connection_internal.h" +#include "pc/sdp_state_provider.h" #include "rtc_base/constructor_magic.h" #include "rtc_base/message_handler.h" #include "rtc_base/rtc_certificate.h" #include "rtc_base/rtc_certificate_generator.h" #include "rtc_base/third_party/sigslot/sigslot.h" #include "rtc_base/thread.h" +#include "rtc_base/thread_message.h" #include "rtc_base/unique_id_generator.h" namespace webrtc { // DTLS certificate request callback class. class WebRtcCertificateGeneratorCallback - : public rtc::RTCCertificateGeneratorCallback, - public sigslot::has_slots<> { + : public rtc::RTCCertificateGeneratorCallback { public: // |rtc::RTCCertificateGeneratorCallback| overrides. void OnSuccess( @@ -80,11 +80,14 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler, WebRtcSessionDescriptionFactory( rtc::Thread* signaling_thread, cricket::ChannelManager* channel_manager, - PeerConnectionInternal* pc, + const SdpStateProvider* sdp_info, const std::string& session_id, + bool dtls_enabled, std::unique_ptr cert_generator, const rtc::scoped_refptr& certificate, - rtc::UniqueRandomIdGenerator* ssrc_generator); + rtc::UniqueRandomIdGenerator* ssrc_generator, + std::function&)> + on_certificate_ready); virtual ~WebRtcSessionDescriptionFactory(); static void CopyCandidatesFromSessionDescription( @@ -110,9 +113,6 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler, session_desc_factory_.set_is_unified_plan(is_unified_plan); } - sigslot::signal1&> - SignalCertificateReady; - // For testing. bool waiting_for_certificate_for_testing() const { return certificate_request_state_ == CERTIFICATE_WAITING; @@ -151,12 +151,13 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler, cricket::MediaSessionDescriptionFactory session_desc_factory_; uint64_t session_version_; const std::unique_ptr cert_generator_; - // TODO(jiayl): remove the dependency on peer connection once bug 2264 is - // fixed. - PeerConnectionInternal* const pc_; + const SdpStateProvider* sdp_info_; const std::string session_id_; CertificateRequestState certificate_request_state_; + std::function&)> + on_certificate_ready_; + RTC_DISALLOW_COPY_AND_ASSIGN(WebRtcSessionDescriptionFactory); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/async_invoker.h b/TMessagesProj/jni/voip/webrtc/rtc_base/async_invoker.h index ed2df1cdc..983e710bc 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/async_invoker.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/async_invoker.h @@ -87,7 +87,7 @@ namespace rtc { // destruction. This can be done by starting each chain of invocations on the // same thread on which it will be destroyed, or by using some other // synchronization method. -class AsyncInvoker : public MessageHandler { +class AsyncInvoker : public MessageHandlerAutoCleanup { public: AsyncInvoker(); ~AsyncInvoker() override; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/buffer_queue.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/buffer_queue.cc index adad9dda1..7879e933c 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/buffer_queue.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/buffer_queue.cc @@ -21,23 +21,20 @@ BufferQueue::BufferQueue(size_t capacity, size_t default_size) : capacity_(capacity), default_size_(default_size) {} BufferQueue::~BufferQueue() { - webrtc::MutexLock lock(&mutex_); - - for (Buffer* buffer : queue_) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + for (Buffer* buffer : queue_) delete buffer; - } - for (Buffer* buffer : free_list_) { + for (Buffer* buffer : free_list_) delete buffer; - } } size_t BufferQueue::size() const { - webrtc::MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); return queue_.size(); } void BufferQueue::Clear() { - webrtc::MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); while (!queue_.empty()) { free_list_.push_back(queue_.front()); queue_.pop_front(); @@ -45,36 +42,30 @@ void BufferQueue::Clear() { } bool BufferQueue::ReadFront(void* buffer, size_t bytes, size_t* bytes_read) { - webrtc::MutexLock lock(&mutex_); - if (queue_.empty()) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + if (queue_.empty()) return false; - } - bool was_writable = queue_.size() < capacity_; Buffer* packet = queue_.front(); queue_.pop_front(); bytes = std::min(bytes, packet->size()); memcpy(buffer, packet->data(), bytes); - if (bytes_read) { + + if (bytes_read) *bytes_read = bytes; - } + free_list_.push_back(packet); - if (!was_writable) { - NotifyWritableForTest(); - } return true; } bool BufferQueue::WriteBack(const void* buffer, size_t bytes, size_t* bytes_written) { - webrtc::MutexLock lock(&mutex_); - if (queue_.size() == capacity_) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + if (queue_.size() == capacity_) return false; - } - bool was_readable = !queue_.empty(); Buffer* packet; if (!free_list_.empty()) { packet = free_list_.back(); @@ -84,13 +75,10 @@ bool BufferQueue::WriteBack(const void* buffer, } packet->SetData(static_cast(buffer), bytes); - if (bytes_written) { + if (bytes_written) *bytes_written = bytes; - } + queue_.push_back(packet); - if (!was_readable) { - NotifyReadableForTest(); - } return true; } diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/buffer_queue.h b/TMessagesProj/jni/voip/webrtc/rtc_base/buffer_queue.h index 29d1a5b13..24a9b04dc 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/buffer_queue.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/buffer_queue.h @@ -18,16 +18,16 @@ #include "rtc_base/buffer.h" #include "rtc_base/constructor_magic.h" -#include "rtc_base/synchronization/mutex.h" +#include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/thread_annotations.h" namespace rtc { -class BufferQueue { +class BufferQueue final { public: // Creates a buffer queue with a given capacity and default buffer size. BufferQueue(size_t capacity, size_t default_size); - virtual ~BufferQueue(); + ~BufferQueue(); // Return number of queued buffers. size_t size() const; @@ -44,17 +44,22 @@ class BufferQueue { // Returns true unless no data could be written. bool WriteBack(const void* data, size_t bytes, size_t* bytes_written); - protected: - // These methods are called when the state of the queue changes. - virtual void NotifyReadableForTest() {} - virtual void NotifyWritableForTest() {} + bool is_writable() const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + return queue_.size() < capacity_; + } + + bool is_readable() const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + return !queue_.empty(); + } private: - size_t capacity_; - size_t default_size_; - mutable webrtc::Mutex mutex_; - std::deque queue_ RTC_GUARDED_BY(mutex_); - std::vector free_list_ RTC_GUARDED_BY(mutex_); + webrtc::SequenceChecker sequence_checker_; + const size_t capacity_; + const size_t default_size_; + std::deque queue_ RTC_GUARDED_BY(sequence_checker_); + std::vector free_list_ RTC_GUARDED_BY(sequence_checker_); RTC_DISALLOW_COPY_AND_ASSIGN(BufferQueue); }; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/callback.h.pump b/TMessagesProj/jni/voip/webrtc/rtc_base/callback.h.pump new file mode 100644 index 000000000..dc5fb3ae1 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/callback.h.pump @@ -0,0 +1,104 @@ +/* + * Copyright 2012 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. + */ + +// To generate callback.h from callback.h.pump, execute: +// ../third_party/googletest/src/googletest/scripts/pump.py callback.h.pump + +// Callbacks are callable object containers. They can hold a function pointer +// or a function object and behave like a value type. Internally, data is +// reference-counted, making copies and pass-by-value inexpensive. +// +// Callbacks are typed using template arguments. The format is: +// CallbackN +// where N is the number of arguments supplied to the callable object. +// Callbacks are invoked using operator(), just like a function or a function +// object. Default-constructed callbacks are "empty," and executing an empty +// callback does nothing. A callback can be made empty by assigning it from +// a default-constructed callback. +// +// Callbacks are similar in purpose to std::function (which isn't available on +// all platforms we support) and a lightweight alternative to sigslots. Since +// they effectively hide the type of the object they call, they're useful in +// breaking dependencies between objects that need to interact with one another. +// Notably, they can hold the results of Bind(), std::bind*, etc, without needing +// to know the resulting object type of those calls. +// +// Sigslots, on the other hand, provide a fuller feature set, such as multiple +// subscriptions to a signal, optional thread-safety, and lifetime tracking of +// slots. When these features are needed, choose sigslots. +// +// Example: +// int sqr(int x) { return x * x; } +// struct AddK { +// int k; +// int operator()(int x) const { return x + k; } +// } add_k = {5}; +// +// Callback1 my_callback; +// cout << my_callback.empty() << endl; // true +// +// my_callback = Callback1(&sqr); +// cout << my_callback.empty() << endl; // false +// cout << my_callback(3) << endl; // 9 +// +// my_callback = Callback1(add_k); +// cout << my_callback(10) << endl; // 15 +// +// my_callback = Callback1(); +// cout << my_callback.empty() << endl; // true + +#ifndef RTC_BASE_CALLBACK_H_ +#define RTC_BASE_CALLBACK_H_ + +#include "rtc_base/ref_count.h" +#include "rtc_base/ref_counted_object.h" +#include "api/scoped_refptr.h" + +namespace rtc { + +$var n = 5 +$range i 0..n +$for i [[ +$range j 1..i + +template +class Callback$i { + public: + // Default copy operations are appropriate for this class. + Callback$i() {} + template Callback$i(const T& functor) + : helper_(new RefCountedObject< HelperImpl >(functor)) {} + R operator()($for j , [[P$j p$j]]) { + if (empty()) + return R(); + return helper_->Run($for j , [[p$j]]); + } + bool empty() const { return !helper_; } + + private: + struct Helper : RefCountInterface { + virtual ~Helper() {} + virtual R Run($for j , [[P$j p$j]]) = 0; + }; + template struct HelperImpl : Helper { + explicit HelperImpl(const T& functor) : functor_(functor) {} + virtual R Run($for j , [[P$j p$j]]) { + return functor_($for j , [[p$j]]); + } + T functor_; + }; + scoped_refptr helper_; +}; + +]] +} // namespace rtc + +#endif // RTC_BASE_CALLBACK_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/callback_list.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/callback_list.cc new file mode 100644 index 000000000..ac947e225 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/callback_list.cc @@ -0,0 +1,48 @@ +/* + * Copyright 2020 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 "rtc_base/callback_list.h" + +#include "rtc_base/checks.h" + +namespace webrtc { +namespace callback_list_impl { + +CallbackListReceivers::CallbackListReceivers() = default; + +CallbackListReceivers::~CallbackListReceivers() { + RTC_CHECK(!send_in_progress_); +} + +void CallbackListReceivers::Foreach( + rtc::FunctionView fv) { + RTC_CHECK(!send_in_progress_); + send_in_progress_ = true; + for (auto& r : receivers_) { + fv(r); + } + send_in_progress_ = false; +} + +template void CallbackListReceivers::AddReceiver( + UntypedFunction::TrivialUntypedFunctionArgs<1>); +template void CallbackListReceivers::AddReceiver( + UntypedFunction::TrivialUntypedFunctionArgs<2>); +template void CallbackListReceivers::AddReceiver( + UntypedFunction::TrivialUntypedFunctionArgs<3>); +template void CallbackListReceivers::AddReceiver( + UntypedFunction::TrivialUntypedFunctionArgs<4>); +template void CallbackListReceivers::AddReceiver( + UntypedFunction::NontrivialUntypedFunctionArgs); +template void CallbackListReceivers::AddReceiver( + UntypedFunction::FunctionPointerUntypedFunctionArgs); + +} // namespace callback_list_impl +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/callback_list.h b/TMessagesProj/jni/voip/webrtc/rtc_base/callback_list.h new file mode 100644 index 000000000..659b838d0 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/callback_list.h @@ -0,0 +1,167 @@ +/* + * Copyright 2020 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. + */ + +#ifndef RTC_BASE_CALLBACK_LIST_H_ +#define RTC_BASE_CALLBACK_LIST_H_ + +#include +#include + +#include "api/function_view.h" +#include "rtc_base/checks.h" +#include "rtc_base/system/assume.h" +#include "rtc_base/system/inline.h" +#include "rtc_base/untyped_function.h" + +namespace webrtc { +namespace callback_list_impl { + +class CallbackListReceivers { + public: + CallbackListReceivers(); + CallbackListReceivers(const CallbackListReceivers&) = delete; + CallbackListReceivers& operator=(const CallbackListReceivers&) = delete; + CallbackListReceivers(CallbackListReceivers&&) = delete; + CallbackListReceivers& operator=(CallbackListReceivers&&) = delete; + ~CallbackListReceivers(); + + template + RTC_NO_INLINE void AddReceiver(UntypedFunctionArgsT args) { + RTC_CHECK(!send_in_progress_); + receivers_.push_back(UntypedFunction::Create(args)); + } + + void Foreach(rtc::FunctionView fv); + + private: + std::vector receivers_; + bool send_in_progress_ = false; +}; + +extern template void CallbackListReceivers::AddReceiver( + UntypedFunction::TrivialUntypedFunctionArgs<1>); +extern template void CallbackListReceivers::AddReceiver( + UntypedFunction::TrivialUntypedFunctionArgs<2>); +extern template void CallbackListReceivers::AddReceiver( + UntypedFunction::TrivialUntypedFunctionArgs<3>); +extern template void CallbackListReceivers::AddReceiver( + UntypedFunction::TrivialUntypedFunctionArgs<4>); +extern template void CallbackListReceivers::AddReceiver( + UntypedFunction::NontrivialUntypedFunctionArgs); +extern template void CallbackListReceivers::AddReceiver( + UntypedFunction::FunctionPointerUntypedFunctionArgs); + +} // namespace callback_list_impl + +// A collection of receivers (callable objects) that can be called all at once. +// Optimized for minimal binary size. The template arguments dictate what +// signature the callbacks must have; for example, a CallbackList +// will require callbacks with signature void(int, float). +// +// CallbackList is neither copyable nor movable (could easily be made movable if +// necessary). Callbacks must be movable, but need not be copyable. +// +// Usage example: +// +// // Declaration (usually a member variable). +// CallbackList foo_; +// +// // Register callbacks. This can be done zero or more times. The +// // callbacks must accept the arguments types listed in the CallbackList's +// // template argument list, and must return void. +// foo_.AddReceiver([...](int a, float b) {...}); // Lambda. +// foo_.AddReceiver(SomeFunction); // Function pointer. +// +// // Call the zero or more receivers, one after the other. +// foo_.Send(17, 3.14); +// +// Callback lifetime considerations +// -------------------------------- +// +// CallbackList::AddReceiver() takes ownership of the given callback by moving +// it in place. The callback can be any callable object; in particular, it may +// have a nontrivial destructor, which will be run when the CallbackList is +// destroyed. The callback may thus access data via any type of smart pointer, +// expressing e.g. unique, shared, or weak ownership. Of course, if the data is +// guaranteed to outlive the callback, a plain raw pointer can be used. +// +// Take care when trying to have the callback own reference-counted data. The +// CallbackList will keep the callback alive, and the callback will keep its +// data alive, so as usual with reference-counted ownership, keep an eye out for +// cycles! +// +// Thread safety +// ------------- +// +// Like most C++ types, CallbackList is thread compatible: it's not safe to +// access it concurrently from multiple threads, but it can be made safe if it +// is protected by a mutex, for example. +// +// Excercise some care when deciding what mutexes to hold when you call +// CallbackList::Send(). In particular, do not hold mutexes that callbacks may +// need to grab. If a larger object has a CallbackList member and a single mutex +// that protects all of its data members, this may e.g. make it necessary to +// protect its CallbackList with a separate mutex; otherwise, there will be a +// deadlock if the callbacks try to access the object. +// +// CallbackList as a class data member +// ----------------------------------- +// +// CallbackList is a normal C++ data type, and should be private when it is a +// data member of a class. For thread safety reasons (see above), it is likely +// best to not have an accessor for the entire CallbackList, and instead only +// allow callers to add callbacks: +// +// template +// void AddFooCallback(F&& callback) { +// // Maybe grab a mutex here? +// foo_callbacks_.AddReceiver(std::forward(callback)); +// } +// +// Removing callbacks +// ------------------ +// +// TODO(kwiberg): The current design doesn’t support removing callbacks, only +// adding them, but removal support can easily be added. +template +class CallbackList { + public: + CallbackList() = default; + CallbackList(const CallbackList&) = delete; + CallbackList& operator=(const CallbackList&) = delete; + CallbackList(CallbackList&&) = delete; + CallbackList& operator=(CallbackList&&) = delete; + + // Adds a new receiver. The receiver (a callable object or a function pointer) + // must be movable, but need not be copyable. Its call signature should be + // `void(ArgT...)`. + template + void AddReceiver(F&& f) { + receivers_.AddReceiver( + UntypedFunction::PrepareArgs(std::forward(f))); + } + + // Calls all receivers with the given arguments. While the Send is in + // progress, no method calls are allowed; specifically, this means that the + // callbacks may not do anything with this CallbackList instance. + template + void Send(ArgU&&... args) { + receivers_.Foreach([&](UntypedFunction& f) { + f.Call(std::forward(args)...); + }); + } + + private: + callback_list_impl::CallbackListReceivers receivers_; +}; + +} // namespace webrtc + +#endif // RTC_BASE_CALLBACK_LIST_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/checks.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/checks.cc index e5fc2ed41..239ea9f0d 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/checks.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/checks.cc @@ -36,6 +36,21 @@ #include "rtc_base/checks.h" namespace { + +RTC_NORETURN void WriteFatalLogAndAbort(const std::string& output) { + const char* output_c = output.c_str(); +#if defined(WEBRTC_ANDROID) + __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", output_c); +#endif + fflush(stdout); + fprintf(stderr, "%s", output_c); + fflush(stderr); +#if defined(WEBRTC_WIN) + DebugBreak(); +#endif + abort(); +} + #if defined(__GNUC__) __attribute__((__format__(__printf__, 2, 3))) #endif @@ -149,19 +164,7 @@ RTC_NORETURN void FatalLog(const char* file, va_end(args); - const char* output = s.c_str(); - -#if defined(WEBRTC_ANDROID) - __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", output); -#endif - - fflush(stdout); - fprintf(stderr, "%s", output); - fflush(stderr); -#if defined(WEBRTC_WIN) - DebugBreak(); -#endif - abort(); + WriteFatalLogAndAbort(s); } #else // RTC_CHECK_MSG_ENABLED RTC_NORETURN void FatalLog(const char* file, int line) { @@ -174,22 +177,40 @@ RTC_NORETURN void FatalLog(const char* file, int line) { "# Check failed.\n" "# ", file, line, LAST_SYSTEM_ERROR); - const char* output = s.c_str(); - -#if defined(WEBRTC_ANDROID) - __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", output); -#endif - - fflush(stdout); - fprintf(stderr, "%s", output); - fflush(stderr); -#if defined(WEBRTC_WIN) - DebugBreak(); -#endif - abort(); + WriteFatalLogAndAbort(s); } #endif // RTC_CHECK_MSG_ENABLED +#if RTC_DCHECK_IS_ON + +RTC_NORETURN void UnreachableCodeReached(const char* file, int line) { + std::string s; + AppendFormat(&s, + "\n\n" + "#\n" + "# Unreachable code reached: %s, line %d\n" + "# last system error: %u\n" + "# ", + file, line, LAST_SYSTEM_ERROR); + WriteFatalLogAndAbort(s); +} + +#else // !RTC_DCHECK_IS_ON + +RTC_NORETURN void UnreachableCodeReached() { + std::string s; + AppendFormat(&s, + "\n\n" + "#\n" + "# Unreachable code reached (file and line unknown)\n" + "# last system error: %u\n" + "# ", + LAST_SYSTEM_ERROR); + WriteFatalLogAndAbort(s); +} + +#endif // !RTC_DCHECK_IS_ON + } // namespace webrtc_checks_impl } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/checks.h b/TMessagesProj/jni/voip/webrtc/rtc_base/checks.h index 61c074ac8..508de2a57 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/checks.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/checks.h @@ -338,6 +338,22 @@ class FatalLogCall final { const char* message_; }; +#if RTC_DCHECK_IS_ON + +// Be helpful, and include file and line in the RTC_CHECK_NOTREACHED error +// message. +#define RTC_UNREACHABLE_FILE_AND_LINE_CALL_ARGS __FILE__, __LINE__ +RTC_NORETURN RTC_EXPORT void UnreachableCodeReached(const char* file, int line); + +#else + +// Be mindful of binary size, and don't include file and line in the +// RTC_CHECK_NOTREACHED error message. +#define RTC_UNREACHABLE_FILE_AND_LINE_CALL_ARGS +RTC_NORETURN RTC_EXPORT void UnreachableCodeReached(); + +#endif + } // namespace webrtc_checks_impl // The actual stream used isn't important. We reference |ignored| in the code @@ -430,6 +446,14 @@ class FatalLogCall final { #define RTC_UNREACHABLE_CODE_HIT false #define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT) +// Kills the process with an error message. Never returns. Use when you wish to +// assert that a point in the code is never reached. +#define RTC_CHECK_NOTREACHED() \ + do { \ + ::rtc::webrtc_checks_impl::UnreachableCodeReached( \ + RTC_UNREACHABLE_FILE_AND_LINE_CALL_ARGS); \ + } while (0) + // TODO(bugs.webrtc.org/8454): Add an RTC_ prefix or rename differently. #define FATAL() \ ::rtc::webrtc_checks_impl::FatalLogCall(__FILE__, __LINE__, \ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/constructor_magic.h b/TMessagesProj/jni/voip/webrtc/rtc_base/constructor_magic.h index e63c2ff62..8d12a7b13 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/constructor_magic.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/constructor_magic.h @@ -11,24 +11,10 @@ #ifndef RTC_BASE_CONSTRUCTOR_MAGIC_H_ #define RTC_BASE_CONSTRUCTOR_MAGIC_H_ -// Put this in the declarations for a class to be unassignable. -#define RTC_DISALLOW_ASSIGN(TypeName) \ - TypeName& operator=(const TypeName&) = delete - // A macro to disallow the copy constructor and operator= functions. This should // be used in the declarations for a class. #define RTC_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&) = delete; \ - RTC_DISALLOW_ASSIGN(TypeName) - -// A macro to disallow all the implicit constructors, namely the default -// constructor, copy constructor and operator= functions. -// -// This should be used in the declarations for a class that wants to prevent -// anyone from instantiating it. This is especially useful for classes -// containing only static methods. -#define RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName() = delete; \ - RTC_DISALLOW_COPY_AND_ASSIGN(TypeName) + TypeName& operator=(const TypeName&) = delete #endif // RTC_BASE_CONSTRUCTOR_MAGIC_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/deprecated/signal_thread.h b/TMessagesProj/jni/voip/webrtc/rtc_base/deprecated/signal_thread.h index 3612f5a1c..10805ad45 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/deprecated/signal_thread.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/deprecated/signal_thread.h @@ -45,7 +45,7 @@ namespace rtc { /////////////////////////////////////////////////////////////////////////////// class DEPRECATED_SignalThread : public sigslot::has_slots<>, - protected MessageHandler { + protected MessageHandlerAutoCleanup { public: DEPRECATED_SignalThread(); @@ -110,14 +110,17 @@ class DEPRECATED_SignalThread : public sigslot::has_slots<>, class Worker : public Thread { public: explicit Worker(DEPRECATED_SignalThread* parent); + + Worker() = delete; + Worker(const Worker&) = delete; + Worker& operator=(const Worker&) = delete; + ~Worker() override; void Run() override; bool IsProcessingMessagesForTesting() override; private: DEPRECATED_SignalThread* parent_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Worker); }; class RTC_SCOPED_LOCKABLE EnterExit { @@ -131,6 +134,11 @@ class DEPRECATED_SignalThread : public sigslot::has_slots<>, RTC_DCHECK_NE(0, t_->refcount_); ++t_->refcount_; } + + EnterExit() = delete; + EnterExit(const EnterExit&) = delete; + EnterExit& operator=(const EnterExit&) = delete; + ~EnterExit() RTC_UNLOCK_FUNCTION() { bool d = (0 == --t_->refcount_); t_->cs_.Leave(); @@ -140,8 +148,6 @@ class DEPRECATED_SignalThread : public sigslot::has_slots<>, private: DEPRECATED_SignalThread* t_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EnterExit); }; void Run(); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/cpu_speed_experiment.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/cpu_speed_experiment.cc index 6d5650acc..0f5332009 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/cpu_speed_experiment.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/cpu_speed_experiment.cc @@ -12,8 +12,7 @@ #include -#include - +#include "rtc_base/experiments/field_trial_list.h" #include "rtc_base/logging.h" #include "system_wrappers/include/field_trial.h" @@ -22,30 +21,18 @@ namespace { constexpr char kFieldTrial[] = "WebRTC-VP8-CpuSpeed-Arm"; constexpr int kMinSetting = -16; constexpr int kMaxSetting = -1; -} // namespace -absl::optional> -CpuSpeedExperiment::GetConfigs() { - if (!webrtc::field_trial::IsEnabled(kFieldTrial)) - return absl::nullopt; - - const std::string group = webrtc::field_trial::FindFullName(kFieldTrial); - if (group.empty()) - return absl::nullopt; - - std::vector configs(3); - if (sscanf(group.c_str(), "Enabled-%d,%d,%d,%d,%d,%d", &(configs[0].pixels), - &(configs[0].cpu_speed), &(configs[1].pixels), - &(configs[1].cpu_speed), &(configs[2].pixels), - &(configs[2].cpu_speed)) != 6) { - RTC_LOG(LS_WARNING) << "Too few parameters provided."; - return absl::nullopt; +std::vector GetValidOrEmpty( + const std::vector& configs) { + if (configs.empty()) { + RTC_LOG(LS_WARNING) << "Unsupported size, value ignored."; + return {}; } for (const auto& config : configs) { if (config.cpu_speed < kMinSetting || config.cpu_speed > kMaxSetting) { RTC_LOG(LS_WARNING) << "Unsupported cpu speed setting, value ignored."; - return absl::nullopt; + return {}; } } @@ -53,20 +40,51 @@ CpuSpeedExperiment::GetConfigs() { if (configs[i].pixels < configs[i - 1].pixels || configs[i].cpu_speed > configs[i - 1].cpu_speed) { RTC_LOG(LS_WARNING) << "Invalid parameter value provided."; - return absl::nullopt; + return {}; } } - return absl::optional>(configs); + return configs; } -int CpuSpeedExperiment::GetValue(int pixels, - const std::vector& configs) { +bool HasLeCores(const std::vector& configs) { for (const auto& config : configs) { - if (pixels <= config.pixels) - return config.cpu_speed; + if (config.cpu_speed_le_cores == 0) + return false; } - return kMinSetting; + return true; +} +} // namespace + +CpuSpeedExperiment::CpuSpeedExperiment() : cores_("cores") { + FieldTrialStructList configs( + {FieldTrialStructMember("pixels", [](Config* c) { return &c->pixels; }), + FieldTrialStructMember("cpu_speed", + [](Config* c) { return &c->cpu_speed; }), + FieldTrialStructMember( + "cpu_speed_le_cores", + [](Config* c) { return &c->cpu_speed_le_cores; })}, + {}); + ParseFieldTrial({&configs, &cores_}, field_trial::FindFullName(kFieldTrial)); + + configs_ = GetValidOrEmpty(configs.Get()); +} + +CpuSpeedExperiment::~CpuSpeedExperiment() {} + +absl::optional CpuSpeedExperiment::GetValue(int pixels, + int num_cores) const { + if (configs_.empty()) + return absl::nullopt; + + bool use_le = HasLeCores(configs_) && cores_ && num_cores <= cores_.Value(); + + for (const auto& config : configs_) { + if (pixels <= config.pixels) + return use_le ? absl::optional(config.cpu_speed_le_cores) + : absl::optional(config.cpu_speed); + } + return absl::optional(kMinSetting); } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/cpu_speed_experiment.h b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/cpu_speed_experiment.h index e6c834094..7c7268c55 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/cpu_speed_experiment.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/cpu_speed_experiment.h @@ -15,25 +15,49 @@ #include "absl/types/optional.h" +#include "rtc_base/experiments/field_trial_parser.h" + namespace webrtc { class CpuSpeedExperiment { public: - struct Config { - bool operator==(const Config& o) const { - return pixels == o.pixels && cpu_speed == o.cpu_speed; - } + CpuSpeedExperiment(); + ~CpuSpeedExperiment(); - int pixels; // The video frame size. - int cpu_speed; // The |cpu_speed| to be used if the frame size is less - // than or equal to |pixels|. + // Example: + // WebRTC-VP8-CpuSpeed-Arm/pixels:100|200|300,cpu_speed:-1|-2|-3/ + // pixels <= 100 -> cpu speed: -1 + // pixels <= 200 -> cpu speed: -2 + // pixels <= 300 -> cpu speed: -3 + + // WebRTC-VP8-CpuSpeed-Arm/pixels:100|200|300,cpu_speed:-1|-2|-3/, + // cpu_speed_le_cores:-4|-5|-6,cores:3/ + // If |num_cores| > 3 + // pixels <= 100 -> cpu speed: -1 + // pixels <= 200 -> cpu speed: -2 + // pixels <= 300 -> cpu speed: -3 + // else + // pixels <= 100 -> cpu speed: -4 + // pixels <= 200 -> cpu speed: -5 + // pixels <= 300 -> cpu speed: -6 + + struct Config { + int pixels = 0; // The video frame size. + int cpu_speed = 0; // The |cpu_speed| to be used if the frame size is less + // than or equal to |pixels|. + // Optional. + int cpu_speed_le_cores = 0; // Same as |cpu_speed| above but only used if + // |num_cores| <= |cores_|. }; - // Returns the configurations from field trial on success. - static absl::optional> GetConfigs(); + // Gets the cpu speed based on |pixels| and |num_cores|. + absl::optional GetValue(int pixels, int num_cores) const; - // Gets the cpu speed from the |configs| based on |pixels|. - static int GetValue(int pixels, const std::vector& configs); + private: + std::vector configs_; + + // Threshold for when to use |cpu_speed_le_cores|. + FieldTrialOptional cores_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/quality_scaler_settings.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/quality_scaler_settings.cc index c8d83ebe4..d2443b05c 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/quality_scaler_settings.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/quality_scaler_settings.cc @@ -21,14 +21,17 @@ const double kMinScaleFactor = 0.01; QualityScalerSettings::QualityScalerSettings( const WebRtcKeyValueConfig* const key_value_config) - : min_frames_("min_frames"), + : sampling_period_ms_("sampling_period_ms"), + average_qp_window_("average_qp_window"), + min_frames_("min_frames"), initial_scale_factor_("initial_scale_factor"), scale_factor_("scale_factor"), initial_bitrate_interval_ms_("initial_bitrate_interval_ms"), initial_bitrate_factor_("initial_bitrate_factor") { ParseFieldTrial( - {&min_frames_, &initial_scale_factor_, &scale_factor_, - &initial_bitrate_interval_ms_, &initial_bitrate_factor_}, + {&sampling_period_ms_, &average_qp_window_, &min_frames_, + &initial_scale_factor_, &scale_factor_, &initial_bitrate_interval_ms_, + &initial_bitrate_factor_}, key_value_config->Lookup("WebRTC-Video-QualityScalerSettings")); } @@ -37,6 +40,22 @@ QualityScalerSettings QualityScalerSettings::ParseFromFieldTrials() { return QualityScalerSettings(&field_trial_config); } +absl::optional QualityScalerSettings::SamplingPeriodMs() const { + if (sampling_period_ms_ && sampling_period_ms_.Value() <= 0) { + RTC_LOG(LS_WARNING) << "Unsupported sampling_period_ms value, ignored."; + return absl::nullopt; + } + return sampling_period_ms_.GetOptional(); +} + +absl::optional QualityScalerSettings::AverageQpWindow() const { + if (average_qp_window_ && average_qp_window_.Value() <= 0) { + RTC_LOG(LS_WARNING) << "Unsupported average_qp_window value, ignored."; + return absl::nullopt; + } + return average_qp_window_.GetOptional(); +} + absl::optional QualityScalerSettings::MinFrames() const { if (min_frames_ && min_frames_.Value() < kMinFrames) { RTC_LOG(LS_WARNING) << "Unsupported min_frames value, ignored."; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/quality_scaler_settings.h b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/quality_scaler_settings.h index e3b12c54e..b4b6a427a 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/quality_scaler_settings.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/quality_scaler_settings.h @@ -21,6 +21,8 @@ class QualityScalerSettings final { public: static QualityScalerSettings ParseFromFieldTrials(); + absl::optional SamplingPeriodMs() const; + absl::optional AverageQpWindow() const; absl::optional MinFrames() const; absl::optional InitialScaleFactor() const; absl::optional ScaleFactor() const; @@ -31,6 +33,8 @@ class QualityScalerSettings final { explicit QualityScalerSettings( const WebRtcKeyValueConfig* const key_value_config); + FieldTrialOptional sampling_period_ms_; + FieldTrialOptional average_qp_window_; FieldTrialOptional min_frames_; FieldTrialOptional initial_scale_factor_; FieldTrialOptional scale_factor_; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/rate_control_settings.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/rate_control_settings.cc index 71c2eb198..6766db62c 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/rate_control_settings.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/rate_control_settings.cc @@ -75,21 +75,19 @@ constexpr char VideoRateControlConfig::kKey[]; std::unique_ptr VideoRateControlConfig::Parser() { // The empty comments ensures that each pair is on a separate line. return StructParametersParser::Create( - "pacing_factor", &pacing_factor, // - "alr_probing", &alr_probing, // - "vp8_qp_max", &vp8_qp_max, // - "vp8_min_pixels", &vp8_min_pixels, // - "trust_vp8", &trust_vp8, // - "trust_vp9", &trust_vp9, // - "video_hysteresis", &video_hysteresis, // - "screenshare_hysteresis", &screenshare_hysteresis, // - "probe_max_allocation", &probe_max_allocation, // - "bitrate_adjuster", &bitrate_adjuster, // - "adjuster_use_headroom", &adjuster_use_headroom, // - "vp8_s0_boost", &vp8_s0_boost, // - "vp8_base_heavy_tl3_alloc", &vp8_base_heavy_tl3_alloc, // - "vp8_dynamic_rate", &vp8_dynamic_rate, // - "vp9_dynamic_rate", &vp9_dynamic_rate); + "pacing_factor", &pacing_factor, // + "alr_probing", &alr_probing, // + "vp8_qp_max", &vp8_qp_max, // + "vp8_min_pixels", &vp8_min_pixels, // + "trust_vp8", &trust_vp8, // + "trust_vp9", &trust_vp9, // + "video_hysteresis", &video_hysteresis, // + "screenshare_hysteresis", &screenshare_hysteresis, // + "probe_max_allocation", &probe_max_allocation, // + "bitrate_adjuster", &bitrate_adjuster, // + "adjuster_use_headroom", &adjuster_use_headroom, // + "vp8_s0_boost", &vp8_s0_boost, // + "vp8_base_heavy_tl3_alloc", &vp8_base_heavy_tl3_alloc); } RateControlSettings::RateControlSettings( @@ -182,18 +180,10 @@ bool RateControlSettings::Vp8BoostBaseLayerQuality() const { return video_config_.vp8_s0_boost; } -bool RateControlSettings::Vp8DynamicRateSettings() const { - return video_config_.vp8_dynamic_rate; -} - bool RateControlSettings::LibvpxVp9TrustedRateController() const { return video_config_.trust_vp9; } -bool RateControlSettings::Vp9DynamicRateSettings() const { - return video_config_.vp9_dynamic_rate; -} - double RateControlSettings::GetSimulcastHysteresisFactor( VideoCodecMode mode) const { if (mode == VideoCodecMode::kScreensharing) { diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/rate_control_settings.h b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/rate_control_settings.h index 6898bf6dd..db7f1cd13 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/rate_control_settings.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/experiments/rate_control_settings.h @@ -36,18 +36,16 @@ struct VideoRateControlConfig { bool alr_probing = false; absl::optional vp8_qp_max; absl::optional vp8_min_pixels; - bool trust_vp8 = false; - bool trust_vp9 = false; - double video_hysteresis = 1.0; + bool trust_vp8 = true; + bool trust_vp9 = true; + double video_hysteresis = 1.2; // Default to 35% hysteresis for simulcast screenshare. double screenshare_hysteresis = 1.35; bool probe_max_allocation = true; - bool bitrate_adjuster = false; - bool adjuster_use_headroom = false; - bool vp8_s0_boost = true; + bool bitrate_adjuster = true; + bool adjuster_use_headroom = true; + bool vp8_s0_boost = false; bool vp8_base_heavy_tl3_alloc = false; - bool vp8_dynamic_rate = false; - bool vp9_dynamic_rate = false; std::unique_ptr Parser(); }; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/fake_network.h b/TMessagesProj/jni/voip/webrtc/rtc_base/fake_network.h index 040b24205..8bd50b69f 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/fake_network.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/fake_network.h @@ -31,7 +31,8 @@ const int kFakeIPv4NetworkPrefixLength = 24; const int kFakeIPv6NetworkPrefixLength = 64; // Fake network manager that allows us to manually specify the IPs to use. -class FakeNetworkManager : public NetworkManagerBase, public MessageHandler { +class FakeNetworkManager : public NetworkManagerBase, + public MessageHandlerAutoCleanup { public: FakeNetworkManager() {} diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/gunit.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/gunit.cc new file mode 100644 index 000000000..83ee8075f --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/gunit.cc @@ -0,0 +1,42 @@ +/* + * Copyright 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 "rtc_base/gunit.h" + +#include + +#include "absl/strings/match.h" + +::testing::AssertionResult AssertStartsWith(const char* text_expr, + const char* prefix_expr, + absl::string_view text, + absl::string_view prefix) { + if (absl::StartsWith(text, prefix)) { + return ::testing::AssertionSuccess(); + } else { + return ::testing::AssertionFailure() + << text_expr << "\nwhich is\n\"" << text + << "\"\ndoes not start with\n" + << prefix_expr << "\nwhich is\n\"" << prefix << "\""; + } +} + +::testing::AssertionResult AssertStringContains(const char* str_expr, + const char* substr_expr, + const std::string& str, + const std::string& substr) { + if (str.find(substr) != std::string::npos) { + return ::testing::AssertionSuccess(); + } else { + return ::testing::AssertionFailure() + << str_expr << "\nwhich is\n\"" << str << "\"\ndoes not contain\n" + << substr_expr << "\nwhich is\n\"" << substr << "\""; + } +} diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/gunit.h b/TMessagesProj/jni/voip/webrtc/rtc_base/gunit.h new file mode 100644 index 000000000..dedf3ee06 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/gunit.h @@ -0,0 +1,168 @@ +/* + * Copyright 2004 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. + */ + +#ifndef RTC_BASE_GUNIT_H_ +#define RTC_BASE_GUNIT_H_ + +#include "rtc_base/fake_clock.h" +#include "rtc_base/logging.h" +#include "rtc_base/thread.h" +#include "test/gtest.h" + +// Wait until "ex" is true, or "timeout" expires. +#define WAIT(ex, timeout) \ + for (int64_t start = rtc::SystemTimeMillis(); \ + !(ex) && rtc::SystemTimeMillis() < start + (timeout);) { \ + rtc::Thread::Current()->ProcessMessages(0); \ + rtc::Thread::Current()->SleepMs(1); \ + } + +// This returns the result of the test in res, so that we don't re-evaluate +// the expression in the XXXX_WAIT macros below, since that causes problems +// when the expression is only true the first time you check it. +#define WAIT_(ex, timeout, res) \ + do { \ + int64_t start = rtc::SystemTimeMillis(); \ + res = (ex); \ + while (!res && rtc::SystemTimeMillis() < start + (timeout)) { \ + rtc::Thread::Current()->ProcessMessages(0); \ + rtc::Thread::Current()->SleepMs(1); \ + res = (ex); \ + } \ + } while (0) + +// The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout. +// One can add failure message by appending "<< msg". +#define EXPECT_TRUE_WAIT(ex, timeout) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (bool res = true) { \ + WAIT_(ex, timeout, res); \ + if (!res) \ + goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \ + } else \ + GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_TRUE(ex) + +#define EXPECT_EQ_WAIT(v1, v2, timeout) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (bool res = true) { \ + WAIT_(v1 == v2, timeout, res); \ + if (!res) \ + goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \ + } else \ + GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_EQ(v1, v2) + +#define ASSERT_TRUE_WAIT(ex, timeout) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (bool res = true) { \ + WAIT_(ex, timeout, res); \ + if (!res) \ + goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \ + } else \ + GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_TRUE(ex) + +#define ASSERT_EQ_WAIT(v1, v2, timeout) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (bool res = true) { \ + WAIT_(v1 == v2, timeout, res); \ + if (!res) \ + goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \ + } else \ + GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_EQ(v1, v2) + +// Version with a "soft" timeout and a margin. This logs if the timeout is +// exceeded, but it only fails if the expression still isn't true after the +// margin time passes. +#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (bool res = true) { \ + WAIT_(ex, timeout, res); \ + if (res) \ + break; \ + RTC_LOG(LS_WARNING) << "Expression " << #ex << " still not true after " \ + << (timeout) << "ms; waiting an additional " << margin \ + << "ms"; \ + WAIT_(ex, margin, res); \ + if (!res) \ + goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \ + } else \ + GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_TRUE(ex) + +// Wait until "ex" is true, or "timeout" expires, using fake clock where +// messages are processed every millisecond. +// TODO(pthatcher): Allow tests to control how many milliseconds to advance. +#define SIMULATED_WAIT(ex, timeout, clock) \ + for (int64_t start = rtc::TimeMillis(); \ + !(ex) && rtc::TimeMillis() < start + (timeout);) { \ + (clock).AdvanceTime(webrtc::TimeDelta::Millis(1)); \ + } + +// This returns the result of the test in res, so that we don't re-evaluate +// the expression in the XXXX_WAIT macros below, since that causes problems +// when the expression is only true the first time you check it. +#define SIMULATED_WAIT_(ex, timeout, res, clock) \ + do { \ + int64_t start = rtc::TimeMillis(); \ + res = (ex); \ + while (!res && rtc::TimeMillis() < start + (timeout)) { \ + (clock).AdvanceTime(webrtc::TimeDelta::Millis(1)); \ + res = (ex); \ + } \ + } while (0) + +// The typical EXPECT_XXXX, but done until true or a timeout with a fake clock. +#define EXPECT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \ + do { \ + bool res; \ + SIMULATED_WAIT_(ex, timeout, res, clock); \ + if (!res) { \ + EXPECT_TRUE(ex); \ + } \ + } while (0) + +#define EXPECT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (bool res = true) { \ + SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \ + if (!res) \ + goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \ + } else \ + GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_EQ(v1, v2) + +#define ASSERT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (bool res = true) { \ + SIMULATED_WAIT_(ex, timeout, res, clock); \ + if (!res) \ + goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \ + } else \ + GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_TRUE(ex) + +#define ASSERT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (bool res = true) { \ + SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \ + if (!res) \ + goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \ + } else \ + GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_EQ(v1, v2) + +// Usage: EXPECT_PRED_FORMAT2(AssertStartsWith, text, "prefix"); +testing::AssertionResult AssertStartsWith(const char* text_expr, + const char* prefix_expr, + absl::string_view text, + absl::string_view prefix); + +// Usage: EXPECT_PRED_FORMAT2(AssertStringContains, str, "substring"); +testing::AssertionResult AssertStringContains(const char* str_expr, + const char* substr_expr, + const std::string& str, + const std::string& substr); + +#endif // RTC_BASE_GUNIT_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/location.h b/TMessagesProj/jni/voip/webrtc/rtc_base/location.h index ad8f47913..ff1eea95a 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/location.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/location.h @@ -13,7 +13,6 @@ #include -#include "rtc_base/stringize_macros.h" #include "rtc_base/system/rtc_export.h" namespace rtc { diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/logging.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/logging.cc index d07a7e75e..13a5f0259 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/logging.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/logging.cc @@ -33,6 +33,7 @@ static const int kMaxLogLineSize = 1024 - 60; #endif // WEBRTC_MAC && !defined(WEBRTC_IOS) || WEBRTC_ANDROID +#include #include #include @@ -110,9 +111,13 @@ LogMessage::LogMessage(const char* file, // Also ensure WallClockStartTime is initialized, so that it matches // LogStartTime. WallClockStartTime(); - print_stream_ << "[" << rtc::LeftPad('0', 3, rtc::ToString(time / 1000)) - << ":" << rtc::LeftPad('0', 3, rtc::ToString(time % 1000)) - << "] "; + // TODO(kwiberg): Switch to absl::StrFormat, if binary size is ok. + char timestamp[50]; // Maximum string length of an int64_t is 20. + int len = + snprintf(timestamp, sizeof(timestamp), "[%03" PRId64 ":%03" PRId64 "]", + time / 1000, time % 1000); + RTC_DCHECK_LT(len, sizeof(timestamp)); + print_stream_ << timestamp; } if (thread_) { @@ -481,11 +486,6 @@ void Log(const LogArgType* fmt, ...) { } } - if (LogMessage::IsNoop(meta.meta.Severity())) { - va_end(args); - return; - } - LogMessage log_message(meta.meta.File(), meta.meta.Line(), meta.meta.Severity(), meta.err_ctx, meta.err); if (tag) { diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/logging.h b/TMessagesProj/jni/voip/webrtc/rtc_base/logging.h index 0852c0618..d2607c28b 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/logging.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/logging.h @@ -487,6 +487,12 @@ class LogMessage { // |streams_| collection is empty, the LogMessage will be considered a noop // LogMessage. static bool IsNoop(LoggingSeverity severity); + // Version of IsNoop that uses fewer instructions at the call site, since the + // caller doesn't have to pass an argument. + template + RTC_NO_INLINE static bool IsNoop() { + return IsNoop(S); + } #else // Next methods do nothing; no one will call these functions. LogMessage(const char* file, int line, LoggingSeverity sev) {} @@ -525,7 +531,11 @@ class LogMessage { inline static int GetLogToStream(LogSink* stream = nullptr) { return 0; } inline static int GetMinLogSeverity() { return 0; } inline static void ConfigureLogging(const char* params) {} - inline static bool IsNoop(LoggingSeverity severity) { return true; } + static constexpr bool IsNoop(LoggingSeverity severity) { return true; } + template + static constexpr bool IsNoop() { + return IsNoop(S); + } #endif // RTC_LOG_ENABLED() private: @@ -598,16 +608,18 @@ class LogMessage { // Logging Helpers ////////////////////////////////////////////////////////////////////// -#define RTC_LOG_FILE_LINE(sev, file, line) \ - RTC_LOG_ENABLED() && \ - ::rtc::webrtc_logging_impl::LogCall() & \ - ::rtc::webrtc_logging_impl::LogStreamer<>() \ - << ::rtc::webrtc_logging_impl::LogMetadata(file, line, sev) +#define RTC_LOG_FILE_LINE(sev, file, line) \ + ::rtc::webrtc_logging_impl::LogCall() & \ + ::rtc::webrtc_logging_impl::LogStreamer<>() \ + << ::rtc::webrtc_logging_impl::LogMetadata(file, line, sev) -#define RTC_LOG(sev) RTC_LOG_FILE_LINE(::rtc::sev, __FILE__, __LINE__) +#define RTC_LOG(sev) \ + !rtc::LogMessage::IsNoop<::rtc::sev>() && \ + RTC_LOG_FILE_LINE(::rtc::sev, __FILE__, __LINE__) // The _V version is for when a variable is passed in. -#define RTC_LOG_V(sev) RTC_LOG_FILE_LINE(sev, __FILE__, __LINE__) +#define RTC_LOG_V(sev) \ + !rtc::LogMessage::IsNoop(sev) && RTC_LOG_FILE_LINE(sev, __FILE__, __LINE__) // The _F version prefixes the message with the current function name. #if (defined(__GNUC__) && !defined(NDEBUG)) || defined(WANT_PRETTY_LOG_F) @@ -626,11 +638,12 @@ inline bool LogCheckLevel(LoggingSeverity sev) { return (LogMessage::GetMinLogSeverity() <= sev); } -#define RTC_LOG_E(sev, ctx, err) \ - RTC_LOG_ENABLED() && ::rtc::webrtc_logging_impl::LogCall() & \ - ::rtc::webrtc_logging_impl::LogStreamer<>() \ - << ::rtc::webrtc_logging_impl::LogMetadataErr { \ - {__FILE__, __LINE__, ::rtc::sev}, ::rtc::ERRCTX_##ctx, (err) \ +#define RTC_LOG_E(sev, ctx, err) \ + !rtc::LogMessage::IsNoop<::rtc::sev>() && \ + ::rtc::webrtc_logging_impl::LogCall() & \ + ::rtc::webrtc_logging_impl::LogStreamer<>() \ + << ::rtc::webrtc_logging_impl::LogMetadataErr { \ + {__FILE__, __LINE__, ::rtc::sev}, ::rtc::ERRCTX_##ctx, (err) \ } #define RTC_LOG_T(sev) RTC_LOG(sev) << this << ": " @@ -663,11 +676,12 @@ inline const char* AdaptString(const std::string& str) { } } // namespace webrtc_logging_impl -#define RTC_LOG_TAG(sev, tag) \ - RTC_LOG_ENABLED() && ::rtc::webrtc_logging_impl::LogCall() & \ - ::rtc::webrtc_logging_impl::LogStreamer<>() \ - << ::rtc::webrtc_logging_impl::LogMetadataTag { \ - sev, ::rtc::webrtc_logging_impl::AdaptString(tag) \ +#define RTC_LOG_TAG(sev, tag) \ + !rtc::LogMessage::IsNoop(sev) && \ + ::rtc::webrtc_logging_impl::LogCall() & \ + ::rtc::webrtc_logging_impl::LogStreamer<>() \ + << ::rtc::webrtc_logging_impl::LogMetadataTag { \ + sev, ::rtc::webrtc_logging_impl::AdaptString(tag) \ } #else diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/memory/fifo_buffer.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/memory/fifo_buffer.cc index 49e926719..3fbea8dc2 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/memory/fifo_buffer.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/memory/fifo_buffer.cc @@ -104,7 +104,7 @@ StreamResult FifoBuffer::Read(void* buffer, // if we were full before, and now we're not, post an event if (!was_writable && copy > 0) { - PostEvent(owner_, SE_WRITE, 0); + PostEvent(SE_WRITE, 0); } } return result; @@ -129,7 +129,7 @@ StreamResult FifoBuffer::Write(const void* buffer, // if we didn't have any data to read before, and now we do, post an event if (!was_readable && copy > 0) { - PostEvent(owner_, SE_READ, 0); + PostEvent(SE_READ, 0); } } return result; @@ -155,7 +155,7 @@ void FifoBuffer::ConsumeReadData(size_t size) { read_position_ = (read_position_ + size) % buffer_length_; data_length_ -= size; if (!was_writable && size > 0) { - PostEvent(owner_, SE_WRITE, 0); + PostEvent(SE_WRITE, 0); } } @@ -185,7 +185,7 @@ void FifoBuffer::ConsumeWriteBuffer(size_t size) { const bool was_readable = (data_length_ > 0); data_length_ += size; if (!was_readable && size > 0) { - PostEvent(owner_, SE_READ, 0); + PostEvent(SE_READ, 0); } } diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/memory/fifo_buffer.h b/TMessagesProj/jni/voip/webrtc/rtc_base/memory/fifo_buffer.h index 04c4cbf33..bf2edf6e2 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/memory/fifo_buffer.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/memory/fifo_buffer.h @@ -15,6 +15,8 @@ #include "rtc_base/stream.h" #include "rtc_base/synchronization/mutex.h" +#include "rtc_base/task_utils/pending_task_safety_flag.h" +#include "rtc_base/task_utils/to_queued_task.h" namespace rtc { @@ -98,6 +100,12 @@ class FifoBuffer final : public StreamInterface { bool GetWriteRemaining(size_t* size) const; private: + void PostEvent(int events, int err) { + owner_->PostTask(webrtc::ToQueuedTask(task_safety_, [this, events, err]() { + SignalEvent(this, events, err); + })); + } + // Helper method that implements ReadOffset. Caller must acquire a lock // when calling this method. StreamResult ReadOffsetLocked(void* buffer, @@ -114,6 +122,8 @@ class FifoBuffer final : public StreamInterface { size_t* bytes_written) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + webrtc::ScopedTaskSafety task_safety_; + // keeps the opened/closed state of the stream StreamState state_ RTC_GUARDED_BY(mutex_); // the allocated buffer @@ -125,7 +135,7 @@ class FifoBuffer final : public StreamInterface { // offset to the readable data size_t read_position_ RTC_GUARDED_BY(mutex_); // stream callbacks are dispatched on this thread - Thread* owner_; + Thread* const owner_; // object lock mutable webrtc::Mutex mutex_; RTC_DISALLOW_COPY_AND_ASSIGN(FifoBuffer); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/message_handler.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/message_handler.cc index 18a06e241..e6e973dbd 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/message_handler.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/message_handler.cc @@ -14,7 +14,16 @@ namespace rtc { -MessageHandler::~MessageHandler() { +MessageHandlerAutoCleanup::MessageHandlerAutoCleanup() {} + +MessageHandlerAutoCleanup::~MessageHandlerAutoCleanup() { + // Note that even though this clears currently pending messages for the + // message handler, it's still racy since it doesn't prevent threads that + // might be in the process of posting new messages with would-be dangling + // pointers. + // This is related to the design of Message having a raw pointer. + // We could consider whether it would be safer to require message handlers + // to be reference counted (as some are). ThreadManager::Clear(this); } diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/message_handler.h b/TMessagesProj/jni/voip/webrtc/rtc_base/message_handler.h index 85cb78548..62c8344e1 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/message_handler.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/message_handler.h @@ -21,17 +21,27 @@ namespace rtc { struct Message; -// Messages get dispatched to a MessageHandler +// MessageQueue/Thread Messages get dispatched via the MessageHandler interface. class RTC_EXPORT MessageHandler { public: - virtual ~MessageHandler(); + virtual ~MessageHandler() {} virtual void OnMessage(Message* msg) = 0; +}; + +// Warning: Provided for backwards compatibility. +// +// This class performs expensive cleanup in the dtor that will affect all +// instances of Thread (and their pending message queues) and will block the +// current thread as well as all other threads. +class RTC_EXPORT MessageHandlerAutoCleanup : public MessageHandler { + public: + ~MessageHandlerAutoCleanup() override; protected: - MessageHandler() {} + MessageHandlerAutoCleanup(); private: - RTC_DISALLOW_COPY_AND_ASSIGN(MessageHandler); + RTC_DISALLOW_COPY_AND_ASSIGN(MessageHandlerAutoCleanup); }; } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/network.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/network.cc index 0d518c0b4..8aabdcb7e 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/network.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/network.cc @@ -806,6 +806,11 @@ bool BasicNetworkManager::IsIgnoredNetwork(const Network& network) const { } #endif + if (network_monitor_ && + !network_monitor_->IsAdapterAvailable(network.name())) { + return true; + } + // Ignore any networks with a 0.x.y.z IP if (network.prefix().family() == AF_INET) { return (network.prefix().v4AddressAsHostOrderInteger() < 0x01000000); @@ -845,15 +850,11 @@ void BasicNetworkManager::StopUpdating() { } void BasicNetworkManager::StartNetworkMonitor() { - NetworkMonitorFactory* factory = network_monitor_factory_; - if (factory == nullptr) { - factory = NetworkMonitorFactory::GetFactory(); - if (factory == nullptr) { - return; - } + if (network_monitor_factory_ == nullptr) { + return; } if (!network_monitor_) { - network_monitor_.reset(factory->CreateNetworkMonitor()); + network_monitor_.reset(network_monitor_factory_->CreateNetworkMonitor()); if (!network_monitor_) { return; } diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/network.h b/TMessagesProj/jni/voip/webrtc/rtc_base/network.h index 3dad521a7..7103f0fa2 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/network.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/network.h @@ -224,7 +224,7 @@ class RTC_EXPORT NetworkManagerBase : public NetworkManager { // Basic implementation of the NetworkManager interface that gets list // of networks using OS APIs. class RTC_EXPORT BasicNetworkManager : public NetworkManagerBase, - public MessageHandler, + public MessageHandlerAutoCleanup, public sigslot::has_slots<> { public: BasicNetworkManager(); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor.cc index 8fd5f786d..70c2ad502 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor.cc @@ -10,37 +10,21 @@ #include "rtc_base/network_monitor.h" -#include - #include "rtc_base/checks.h" -#include "rtc_base/location.h" -#include "rtc_base/logging.h" - -namespace { -const uint32_t UPDATE_NETWORKS_MESSAGE = 1; -} // namespace namespace rtc { -NetworkMonitorInterface::NetworkMonitorInterface() {} +const char* NetworkPreferenceToString(NetworkPreference preference) { + switch (preference) { + case NetworkPreference::NEUTRAL: + return "NEUTRAL"; + case NetworkPreference::NOT_PREFERRED: + return "NOT_PREFERRED"; + } + RTC_CHECK_NOTREACHED(); +} + +NetworkMonitorInterface::NetworkMonitorInterface() {} NetworkMonitorInterface::~NetworkMonitorInterface() {} -NetworkMonitorBase::NetworkMonitorBase() : worker_thread_(Thread::Current()) {} -NetworkMonitorBase::~NetworkMonitorBase() {} - -void NetworkMonitorBase::OnNetworksChanged() { - RTC_LOG(LS_VERBOSE) << "Network change is received at the network monitor"; - worker_thread_->Post(RTC_FROM_HERE, this, UPDATE_NETWORKS_MESSAGE); -} - -void NetworkMonitorBase::OnMessage(Message* msg) { - RTC_DCHECK(msg->message_id == UPDATE_NETWORKS_MESSAGE); - SignalNetworksChanged(); -} - -AdapterType NetworkMonitorBase::GetVpnUnderlyingAdapterType( - const std::string& interface_name) { - return ADAPTER_TYPE_UNKNOWN; -} - } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor.h b/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor.h index eb3c3d65f..4a3002f42 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor.h @@ -12,11 +12,7 @@ #define RTC_BASE_NETWORK_MONITOR_H_ #include "rtc_base/network_constants.h" -// TODO(deadbeef): Remove this include when downstream code stops using -// NetworkMonitorFactory::SetFactory. -#include "rtc_base/network_monitor_factory.h" #include "rtc_base/third_party/sigslot/sigslot.h" -#include "rtc_base/thread.h" namespace rtc { @@ -38,6 +34,8 @@ enum class NetworkPreference { NOT_PREFERRED = -1, }; +const char* NetworkPreferenceToString(NetworkPreference preference); + class NetworkBinderInterface { public: // Binds a socket to the network that is attached to |address| so that all @@ -64,8 +62,7 @@ class NetworkBinderInterface { * * Memory consideration: * NetworkMonitor is owned by the caller (NetworkManager). The global network - * monitor factory is owned by the factory itself but needs to be released from - * the factory creator. + * monitor factory is owned by the PeerConnectionFactory. */ // Generic network monitor interface. It starts and stops monitoring network // changes, and fires the SignalNetworksChanged event when networks change. @@ -79,36 +76,25 @@ class NetworkMonitorInterface { virtual void Start() = 0; virtual void Stop() = 0; - // Implementations should call this method on the base when networks change, - // and the base will fire SignalNetworksChanged on the right thread. - virtual void OnNetworksChanged() = 0; - virtual AdapterType GetAdapterType(const std::string& interface_name) = 0; virtual AdapterType GetVpnUnderlyingAdapterType( const std::string& interface_name) = 0; + virtual NetworkPreference GetNetworkPreference( const std::string& interface_name) = 0; -}; -class NetworkMonitorBase : public NetworkMonitorInterface, - public MessageHandler, - public sigslot::has_slots<> { - public: - NetworkMonitorBase(); - ~NetworkMonitorBase() override; - - void OnNetworksChanged() override; - - void OnMessage(Message* msg) override; - - AdapterType GetVpnUnderlyingAdapterType( - const std::string& interface_name) override; - - protected: - Thread* worker_thread() { return worker_thread_; } - - private: - Thread* worker_thread_; + // Is this interface available to use? WebRTC shouldn't attempt to use it if + // this returns false. + // + // It's possible for this status to change, in which case + // SignalNetworksChanged will be fired. + // + // These specific use case this was added for was a phone with two SIM cards, + // where attempting to use all interfaces returned from getifaddrs caused the + // connection to be dropped. + virtual bool IsAdapterAvailable(const std::string& interface_name) { + return true; + } }; } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor_factory.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor_factory.cc index 915f2e3c4..9fac4d95a 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor_factory.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor_factory.cc @@ -10,33 +10,9 @@ #include "rtc_base/network_monitor_factory.h" -namespace { -// This is set by NetworkMonitorFactory::SetFactory and the caller of -// NetworkMonitorFactory::SetFactory must be responsible for calling -// ReleaseFactory to destroy the factory. -rtc::NetworkMonitorFactory* network_monitor_factory = nullptr; -} // namespace - namespace rtc { NetworkMonitorFactory::NetworkMonitorFactory() {} NetworkMonitorFactory::~NetworkMonitorFactory() {} -void NetworkMonitorFactory::SetFactory(NetworkMonitorFactory* factory) { - if (network_monitor_factory != nullptr) { - delete network_monitor_factory; - } - network_monitor_factory = factory; -} - -void NetworkMonitorFactory::ReleaseFactory(NetworkMonitorFactory* factory) { - if (factory == network_monitor_factory) { - SetFactory(nullptr); - } -} - -NetworkMonitorFactory* NetworkMonitorFactory::GetFactory() { - return network_monitor_factory; -} - } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor_factory.h b/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor_factory.h index ac463d82c..dadcd4aa8 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor_factory.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/network_monitor_factory.h @@ -24,15 +24,6 @@ class NetworkMonitorInterface; */ class NetworkMonitorFactory { public: - // This is not thread-safe; it should be called once (or once per audio/video - // call) during the call initialization. - // DEPRECATED: Should pass NetworkMonitorFactory through - // PeerConnectionFactoryDependencies instead. - static void SetFactory(NetworkMonitorFactory* factory); - - static void ReleaseFactory(NetworkMonitorFactory* factory); - static NetworkMonitorFactory* GetFactory(); - virtual NetworkMonitorInterface* CreateNetworkMonitor() = 0; virtual ~NetworkMonitorFactory(); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/math_utils.h b/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/math_utils.h index 4bf48e22b..0f1d51b09 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/math_utils.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/math_utils.h @@ -8,14 +8,16 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef RTC_BASE_NUMERICS_MATH_UTILS_H_ -#define RTC_BASE_NUMERICS_MATH_UTILS_H_ +#ifndef API_NUMERICS_MATH_UTILS_H_ +#define API_NUMERICS_MATH_UTILS_H_ #include #include #include "rtc_base/checks.h" +namespace webrtc { +namespace webrtc_impl { // Given two numbers |x| and |y| such that x >= y, computes the difference // x - y without causing undefined behavior due to signed overflow. template @@ -67,4 +69,7 @@ constexpr T minus_infinity_or_min() { return std::numeric_limits::min(); } -#endif // RTC_BASE_NUMERICS_MATH_UTILS_H_ +} // namespace webrtc_impl +} // namespace webrtc + +#endif // API_NUMERICS_MATH_UTILS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/running_statistics.h b/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/running_statistics.h index 4a3516d3f..bbcc7e2a7 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/running_statistics.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/running_statistics.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef RTC_BASE_NUMERICS_RUNNING_STATISTICS_H_ -#define RTC_BASE_NUMERICS_RUNNING_STATISTICS_H_ +#ifndef API_NUMERICS_RUNNING_STATISTICS_H_ +#define API_NUMERICS_RUNNING_STATISTICS_H_ #include #include @@ -20,6 +20,7 @@ #include "rtc_base/numerics/math_utils.h" namespace webrtc { +namespace webrtc_impl { // tl;dr: Robust and efficient online computation of statistics, // using Welford's method for variance. [1] @@ -154,6 +155,7 @@ class RunningStatistics { double cumul_ = 0; // Variance * size_, sometimes noted m2. }; +} // namespace webrtc_impl } // namespace webrtc -#endif // RTC_BASE_NUMERICS_RUNNING_STATISTICS_H_ +#endif // API_NUMERICS_RUNNING_STATISTICS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/safe_conversions.h b/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/safe_conversions.h index 5d5867251..e00219cbd 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/safe_conversions.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/safe_conversions.h @@ -63,12 +63,10 @@ inline constexpr Dst saturated_cast(Src value) { // Should fail only on attempting to assign NaN to a saturated integer. case internal::TYPE_INVALID: - FATAL(); - return std::numeric_limits::max(); + RTC_CHECK_NOTREACHED(); } - FATAL(); - return static_cast(value); + RTC_CHECK_NOTREACHED(); } } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/sample_stats.h b/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/sample_stats.h index f6347414b..39af1c6a3 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/sample_stats.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/numerics/sample_stats.h @@ -10,10 +10,10 @@ #ifndef RTC_BASE_NUMERICS_SAMPLE_STATS_H_ #define RTC_BASE_NUMERICS_SAMPLE_STATS_H_ +#include "api/numerics/samples_stats_counter.h" #include "api/units/data_rate.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" -#include "rtc_base/numerics/samples_stats_counter.h" namespace webrtc { template diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_adapter.h b/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_adapter.h index 0e76836ba..6f1f7dcca 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_adapter.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_adapter.h @@ -32,7 +32,8 @@ namespace rtc { -class OpenSSLAdapter final : public SSLAdapter, public MessageHandler { +class OpenSSLAdapter final : public SSLAdapter, + public MessageHandlerAutoCleanup { public: static bool InitializeSSL(); static bool CleanupSSL(); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_certificate.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_certificate.cc index 9459f76df..bd9bb04fd 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_certificate.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_certificate.cc @@ -244,13 +244,8 @@ std::unique_ptr OpenSSLCertificate::Clone() const { std::string OpenSSLCertificate::ToPEMString() const { BIO* bio = BIO_new(BIO_s_mem()); - if (!bio) { - FATAL() << "Unreachable code."; - } - if (!PEM_write_bio_X509(bio, x509_)) { - BIO_free(bio); - FATAL() << "Unreachable code."; - } + RTC_CHECK(bio); + RTC_CHECK(PEM_write_bio_X509(bio, x509_)); BIO_write(bio, "\0", 1); char* buffer; BIO_get_mem_data(bio, &buffer); @@ -264,13 +259,8 @@ void OpenSSLCertificate::ToDER(Buffer* der_buffer) const { der_buffer->SetSize(0); // Calculates the DER representation of the certificate, from scratch. BIO* bio = BIO_new(BIO_s_mem()); - if (!bio) { - FATAL() << "Unreachable code."; - } - if (!i2d_X509_bio(bio, x509_)) { - BIO_free(bio); - FATAL() << "Unreachable code."; - } + RTC_CHECK(bio); + RTC_CHECK(i2d_X509_bio(bio, x509_)); char* data = nullptr; size_t length = BIO_get_mem_data(bio, &data); der_buffer->SetData(data, length); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_stream_adapter.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_stream_adapter.cc index cd7f8025c..f59b4edf1 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_stream_adapter.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_stream_adapter.cc @@ -21,6 +21,7 @@ #include #endif +#include #include #include #include @@ -34,6 +35,7 @@ #include "rtc_base/openssl_identity.h" #include "rtc_base/ssl_certificate.h" #include "rtc_base/stream.h" +#include "rtc_base/task_utils/to_queued_task.h" #include "rtc_base/thread.h" #include "rtc_base/time_utils.h" #include "system_wrappers/include/field_trial.h" @@ -50,7 +52,6 @@ namespace rtc { namespace { - // SRTP cipher suite table. |internal_name| is used to construct a // colon-separated profile strings which is needed by // SSL_CTX_set_tlsext_use_srtp(). @@ -265,9 +266,25 @@ static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) { // OpenSSLStreamAdapter ///////////////////////////////////////////////////////////////////////////// +static std::atomic g_use_legacy_tls_protocols_override(false); +static std::atomic g_allow_legacy_tls_protocols(false); + +void SetAllowLegacyTLSProtocols(const absl::optional& allow) { + g_use_legacy_tls_protocols_override.store(allow.has_value()); + if (allow.has_value()) + g_allow_legacy_tls_protocols.store(allow.value()); +} + +bool ShouldAllowLegacyTLSProtocols() { + return g_use_legacy_tls_protocols_override.load() + ? g_allow_legacy_tls_protocols.load() + : webrtc::field_trial::IsEnabled("WebRTC-LegacyTlsProtocols"); +} + OpenSSLStreamAdapter::OpenSSLStreamAdapter( std::unique_ptr stream) : SSLStreamAdapter(std::move(stream)), + owner_(rtc::Thread::Current()), state_(SSL_NONE), role_(SSL_CLIENT), ssl_read_needs_write_(false), @@ -278,10 +295,10 @@ OpenSSLStreamAdapter::OpenSSLStreamAdapter( ssl_max_version_(SSL_PROTOCOL_TLS_12), // Default is to support legacy TLS protocols. // This will be changed to default non-support in M82 or M83. - support_legacy_tls_protocols_flag_( - !webrtc::field_trial::IsDisabled("WebRTC-LegacyTlsProtocols")) {} + support_legacy_tls_protocols_flag_(ShouldAllowLegacyTLSProtocols()) {} OpenSSLStreamAdapter::~OpenSSLStreamAdapter() { + timeout_task_.Stop(); Cleanup(0); } @@ -530,7 +547,7 @@ StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len, size_t* written, int* error) { - RTC_LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")"; + RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")"; switch (state_) { case SSL_NONE: @@ -570,18 +587,18 @@ StreamResult OpenSSLStreamAdapter::Write(const void* data, int ssl_error = SSL_get_error(ssl_, code); switch (ssl_error) { case SSL_ERROR_NONE: - RTC_LOG(LS_VERBOSE) << " -- success"; + RTC_DLOG(LS_VERBOSE) << " -- success"; RTC_DCHECK_GT(code, 0); RTC_DCHECK_LE(code, data_len); if (written) *written = code; return SR_SUCCESS; case SSL_ERROR_WANT_READ: - RTC_LOG(LS_VERBOSE) << " -- error want read"; + RTC_DLOG(LS_VERBOSE) << " -- error want read"; ssl_write_needs_read_ = true; return SR_BLOCK; case SSL_ERROR_WANT_WRITE: - RTC_LOG(LS_VERBOSE) << " -- error want write"; + RTC_DLOG(LS_VERBOSE) << " -- error want write"; return SR_BLOCK; case SSL_ERROR_ZERO_RETURN: @@ -599,7 +616,7 @@ StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len, size_t* read, int* error) { - RTC_LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")"; + RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")"; switch (state_) { case SSL_NONE: // pass-through in clear text @@ -637,7 +654,7 @@ StreamResult OpenSSLStreamAdapter::Read(void* data, switch (ssl_error) { case SSL_ERROR_NONE: - RTC_LOG(LS_VERBOSE) << " -- success"; + RTC_DLOG(LS_VERBOSE) << " -- success"; RTC_DCHECK_GT(code, 0); RTC_DCHECK_LE(code, data_len); if (read) { @@ -649,7 +666,7 @@ StreamResult OpenSSLStreamAdapter::Read(void* data, unsigned int pending = SSL_pending(ssl_); if (pending) { - RTC_LOG(LS_INFO) << " -- short DTLS read. flushing"; + RTC_DLOG(LS_INFO) << " -- short DTLS read. flushing"; FlushInput(pending); if (error) { *error = SSE_MSG_TRUNC; @@ -659,14 +676,14 @@ StreamResult OpenSSLStreamAdapter::Read(void* data, } return SR_SUCCESS; case SSL_ERROR_WANT_READ: - RTC_LOG(LS_VERBOSE) << " -- error want read"; + RTC_DLOG(LS_VERBOSE) << " -- error want read"; return SR_BLOCK; case SSL_ERROR_WANT_WRITE: - RTC_LOG(LS_VERBOSE) << " -- error want write"; + RTC_DLOG(LS_VERBOSE) << " -- error want write"; ssl_read_needs_write_ = true; return SR_BLOCK; case SSL_ERROR_ZERO_RETURN: - RTC_LOG(LS_VERBOSE) << " -- remote side closed"; + RTC_DLOG(LS_VERBOSE) << " -- remote side closed"; Close(); return SR_EOS; default: @@ -696,7 +713,7 @@ void OpenSSLStreamAdapter::FlushInput(unsigned int left) { return; } - RTC_LOG(LS_VERBOSE) << " -- flushed " << code << " bytes"; + RTC_DLOG(LS_VERBOSE) << " -- flushed " << code << " bytes"; left -= code; } } @@ -734,7 +751,7 @@ void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, RTC_DCHECK(stream == this->stream()); if ((events & SE_OPEN)) { - RTC_LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN"; + RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN"; if (state_ != SSL_WAIT) { RTC_DCHECK(state_ == SSL_NONE); events_to_signal |= SE_OPEN; @@ -748,9 +765,9 @@ void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, } if ((events & (SE_READ | SE_WRITE))) { - RTC_LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent" - << ((events & SE_READ) ? " SE_READ" : "") - << ((events & SE_WRITE) ? " SE_WRITE" : ""); + RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent" + << ((events & SE_READ) ? " SE_READ" : "") + << ((events & SE_WRITE) ? " SE_WRITE" : ""); if (state_ == SSL_NONE) { events_to_signal |= events & (SE_READ | SE_WRITE); } else if (state_ == SSL_CONNECTING) { @@ -761,20 +778,20 @@ void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, } else if (state_ == SSL_CONNECTED) { if (((events & SE_READ) && ssl_write_needs_read_) || (events & SE_WRITE)) { - RTC_LOG(LS_VERBOSE) << " -- onStreamWriteable"; + RTC_DLOG(LS_VERBOSE) << " -- onStreamWriteable"; events_to_signal |= SE_WRITE; } if (((events & SE_WRITE) && ssl_read_needs_write_) || (events & SE_READ)) { - RTC_LOG(LS_VERBOSE) << " -- onStreamReadable"; + RTC_DLOG(LS_VERBOSE) << " -- onStreamReadable"; events_to_signal |= SE_READ; } } } if ((events & SE_CLOSE)) { - RTC_LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err - << ")"; + RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err + << ")"; Cleanup(0); events_to_signal |= SE_CLOSE; // SE_CLOSE is the only event that uses the final parameter to OnEvent(). @@ -787,10 +804,37 @@ void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, } } +void OpenSSLStreamAdapter::PostEvent(int events, int err) { + owner_->PostTask(webrtc::ToQueuedTask( + task_safety_, [this, events, err]() { SignalEvent(this, events, err); })); +} + +void OpenSSLStreamAdapter::SetTimeout(int delay_ms) { + // We need to accept 0 delay here as well as >0 delay, because + // DTLSv1_get_timeout seems to frequently return 0 ms. + RTC_DCHECK_GE(delay_ms, 0); + RTC_DCHECK(!timeout_task_.Running()); + + timeout_task_ = webrtc::RepeatingTaskHandle::DelayedStart( + owner_, webrtc::TimeDelta::Millis(delay_ms), + [flag = task_safety_.flag(), this]() { + if (flag->alive()) { + RTC_DLOG(LS_INFO) << "DTLS timeout expired"; + timeout_task_.Stop(); + DTLSv1_handle_timeout(ssl_); + ContinueSSL(); + } else { + RTC_NOTREACHED(); + } + // This callback will never run again (stopped above). + return webrtc::TimeDelta::PlusInfinity(); + }); +} + int OpenSSLStreamAdapter::BeginSSL() { RTC_DCHECK(state_ == SSL_CONNECTING); // The underlying stream has opened. - RTC_LOG(LS_INFO) << "BeginSSL with peer."; + RTC_DLOG(LS_INFO) << "BeginSSL with peer."; BIO* bio = nullptr; @@ -833,18 +877,18 @@ int OpenSSLStreamAdapter::BeginSSL() { } int OpenSSLStreamAdapter::ContinueSSL() { - RTC_LOG(LS_VERBOSE) << "ContinueSSL"; + RTC_DLOG(LS_VERBOSE) << "ContinueSSL"; RTC_DCHECK(state_ == SSL_CONNECTING); // Clear the DTLS timer - Thread::Current()->Clear(this, MSG_TIMEOUT); + timeout_task_.Stop(); const int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_); const int ssl_error = SSL_get_error(ssl_, code); switch (ssl_error) { case SSL_ERROR_NONE: - RTC_LOG(LS_VERBOSE) << " -- success"; + RTC_DLOG(LS_VERBOSE) << " -- success"; // By this point, OpenSSL should have given us a certificate, or errored // out if one was missing. RTC_DCHECK(peer_cert_chain_ || !GetClientAuthEnabled()); @@ -865,18 +909,16 @@ int OpenSSLStreamAdapter::ContinueSSL() { break; case SSL_ERROR_WANT_READ: { - RTC_LOG(LS_VERBOSE) << " -- error want read"; + RTC_DLOG(LS_VERBOSE) << " -- error want read"; struct timeval timeout; if (DTLSv1_get_timeout(ssl_, &timeout)) { int delay = timeout.tv_sec * 1000 + timeout.tv_usec / 1000; - - Thread::Current()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_TIMEOUT, - 0); + SetTimeout(delay); } } break; case SSL_ERROR_WANT_WRITE: - RTC_LOG(LS_VERBOSE) << " -- error want write"; + RTC_DLOG(LS_VERBOSE) << " -- error want write"; break; case SSL_ERROR_ZERO_RETURN: @@ -886,8 +928,8 @@ int OpenSSLStreamAdapter::ContinueSSL() { if (err_code != 0 && ERR_GET_REASON(err_code) == SSL_R_NO_SHARED_CIPHER) { ssl_handshake_err = SSLHandshakeError::INCOMPATIBLE_CIPHERSUITE; } - RTC_LOG(LS_VERBOSE) << " -- error " << code << ", " << err_code << ", " - << ERR_GET_REASON(err_code); + RTC_DLOG(LS_VERBOSE) << " -- error " << code << ", " << err_code << ", " + << ERR_GET_REASON(err_code); SignalSSLHandshakeError(ssl_handshake_err); return (ssl_error != 0) ? ssl_error : -1; } @@ -910,7 +952,7 @@ void OpenSSLStreamAdapter::Error(const char* context, } void OpenSSLStreamAdapter::Cleanup(uint8_t alert) { - RTC_LOG(LS_INFO) << "Cleanup"; + RTC_DLOG(LS_INFO) << "Cleanup"; if (state_ != SSL_ERROR) { state_ = SSL_CLOSED; @@ -948,18 +990,7 @@ void OpenSSLStreamAdapter::Cleanup(uint8_t alert) { peer_cert_chain_.reset(); // Clear the DTLS timer - Thread::Current()->Clear(this, MSG_TIMEOUT); -} - -void OpenSSLStreamAdapter::OnMessage(Message* msg) { - // Process our own messages and then pass others to the superclass - if (MSG_TIMEOUT == msg->message_id) { - RTC_LOG(LS_INFO) << "DTLS timeout expired"; - DTLSv1_handle_timeout(ssl_); - ContinueSSL(); - } else { - StreamInterface::OnMessage(msg); - } + timeout_task_.Stop(); } SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() { @@ -1072,7 +1103,7 @@ bool OpenSSLStreamAdapter::VerifyPeerCertificate() { // Ignore any verification error if the digest matches, since there is no // value in checking the validity of a self-signed cert issued by untrusted // sources. - RTC_LOG(LS_INFO) << "Accepted peer certificate."; + RTC_DLOG(LS_INFO) << "Accepted peer certificate."; peer_certificate_verified_ = true; return true; } @@ -1107,7 +1138,7 @@ int OpenSSLStreamAdapter::SSLVerifyCallback(X509_STORE_CTX* store, void* arg) { // If the peer certificate digest isn't known yet, we'll wait to verify // until it's known, and for now just return a success status. if (stream->peer_certificate_digest_algorithm_.empty()) { - RTC_LOG(LS_INFO) << "Waiting to verify certificate until digest is known."; + RTC_DLOG(LS_INFO) << "Waiting to verify certificate until digest is known."; return 1; } diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_stream_adapter.h b/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_stream_adapter.h index 7ea324321..fbfccd684 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_stream_adapter.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/openssl_stream_adapter.h @@ -19,11 +19,15 @@ #include #include +#include "absl/types/optional.h" #include "rtc_base/buffer.h" #include "rtc_base/openssl_identity.h" #include "rtc_base/ssl_identity.h" #include "rtc_base/ssl_stream_adapter.h" #include "rtc_base/stream.h" +#include "rtc_base/system/rtc_export.h" +#include "rtc_base/task_utils/pending_task_safety_flag.h" +#include "rtc_base/task_utils/repeating_task.h" namespace rtc { @@ -55,6 +59,12 @@ class SSLCertChain; /////////////////////////////////////////////////////////////////////////////// +// If |allow| has a value, its value determines if legacy TLS protocols are +// allowed, overriding the default configuration. +// If |allow| has no value, any previous override is removed and the default +// configuration is restored. +RTC_EXPORT void SetAllowLegacyTLSProtocols(const absl::optional& allow); + class OpenSSLStreamAdapter final : public SSLStreamAdapter { public: explicit OpenSSLStreamAdapter(std::unique_ptr stream); @@ -137,7 +147,8 @@ class OpenSSLStreamAdapter final : public SSLStreamAdapter { SSL_CLOSED // Clean close }; - enum { MSG_TIMEOUT = MSG_MAX + 1 }; + void PostEvent(int events, int err); + void SetTimeout(int delay_ms); // The following three methods return 0 on success and a negative // error code on failure. The error code may be from OpenSSL or -1 @@ -161,9 +172,6 @@ class OpenSSLStreamAdapter final : public SSLStreamAdapter { void Error(const char* context, int err, uint8_t alert, bool signal); void Cleanup(uint8_t alert); - // Override MessageHandler - void OnMessage(Message* msg) override; - // Flush the input buffers by reading left bytes (for DTLS) void FlushInput(unsigned int left); @@ -184,6 +192,10 @@ class OpenSSLStreamAdapter final : public SSLStreamAdapter { !peer_certificate_digest_value_.empty(); } + rtc::Thread* const owner_; + webrtc::ScopedTaskSafety task_safety_; + webrtc::RepeatingTaskHandle timeout_task_; + SSLState state_; SSLRole role_; int ssl_error_code_; // valid when state_ == SSL_ERROR or SSL_CLOSED diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/operations_chain.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/operations_chain.cc index 68ee20bab..f707d339b 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/operations_chain.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/operations_chain.cc @@ -19,12 +19,14 @@ OperationsChain::CallbackHandle::CallbackHandle( : operations_chain_(std::move(operations_chain)) {} OperationsChain::CallbackHandle::~CallbackHandle() { +#if RTC_DCHECK_IS_ON RTC_DCHECK(has_run_); +#endif } void OperationsChain::CallbackHandle::OnOperationComplete() { +#if RTC_DCHECK_IS_ON RTC_DCHECK(!has_run_); -#ifdef RTC_DCHECK_IS_ON has_run_ = true; #endif // RTC_DCHECK_IS_ON operations_chain_->OnOperationComplete(); @@ -49,6 +51,17 @@ OperationsChain::~OperationsChain() { RTC_DCHECK(chained_operations_.empty()); } +void OperationsChain::SetOnChainEmptyCallback( + std::function on_chain_empty_callback) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + on_chain_empty_callback_ = std::move(on_chain_empty_callback); +} + +bool OperationsChain::IsEmpty() const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + return chained_operations_.empty(); +} + std::function OperationsChain::CreateOperationsChainCallback() { return [handle = rtc::scoped_refptr( new CallbackHandle(this))]() { handle->OnOperationComplete(); }; @@ -59,9 +72,12 @@ void OperationsChain::OnOperationComplete() { // The front element is the operation that just completed, remove it. RTC_DCHECK(!chained_operations_.empty()); chained_operations_.pop(); - // If there are any other operations chained, execute the next one. + // If there are any other operations chained, execute the next one. Otherwise, + // invoke the "on chain empty" callback if it has been set. if (!chained_operations_.empty()) { chained_operations_.front()->Run(); + } else if (on_chain_empty_callback_.has_value()) { + on_chain_empty_callback_.value()(); } } diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/operations_chain.h b/TMessagesProj/jni/voip/webrtc/rtc_base/operations_chain.h index b6ec46e04..44a3d9acb 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/operations_chain.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/operations_chain.h @@ -18,6 +18,7 @@ #include #include +#include "absl/types/optional.h" #include "api/scoped_refptr.h" #include "rtc_base/checks.h" #include "rtc_base/constructor_magic.h" @@ -49,11 +50,15 @@ class OperationWithFunctor final : public Operation { : functor_(std::forward(functor)), callback_(std::move(callback)) {} - ~OperationWithFunctor() override { RTC_DCHECK(has_run_); } + ~OperationWithFunctor() override { +#if RTC_DCHECK_IS_ON + RTC_DCHECK(has_run_); +#endif // RTC_DCHECK_IS_ON + } void Run() override { +#if RTC_DCHECK_IS_ON RTC_DCHECK(!has_run_); -#ifdef RTC_DCHECK_IS_ON has_run_ = true; #endif // RTC_DCHECK_IS_ON // The functor being executed may invoke the callback synchronously, @@ -69,7 +74,7 @@ class OperationWithFunctor final : public Operation { private: typename std::remove_reference::type functor_; std::function callback_; -#ifdef RTC_DCHECK_IS_ON +#if RTC_DCHECK_IS_ON bool has_run_ = false; #endif // RTC_DCHECK_IS_ON }; @@ -112,6 +117,9 @@ class OperationsChain final : public RefCountedObject { static scoped_refptr Create(); ~OperationsChain(); + void SetOnChainEmptyCallback(std::function on_chain_empty_callback); + bool IsEmpty() const; + // Chains an operation. Chained operations are executed in FIFO order. The // operation starts when |functor| is executed by the OperationsChain and is // contractually obligated to invoke the callback passed to it when the @@ -163,7 +171,7 @@ class OperationsChain final : public RefCountedObject { private: scoped_refptr operations_chain_; -#ifdef RTC_DCHECK_IS_ON +#if RTC_DCHECK_IS_ON bool has_run_ = false; #endif // RTC_DCHECK_IS_ON @@ -181,6 +189,8 @@ class OperationsChain final : public RefCountedObject { // to it. std::queue> chained_operations_ RTC_GUARDED_BY(sequence_checker_); + absl::optional> on_chain_empty_callback_ + RTC_GUARDED_BY(sequence_checker_); RTC_DISALLOW_COPY_AND_ASSIGN(OperationsChain); }; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/physical_socket_server.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/physical_socket_server.cc index 05b32557b..cf6e79279 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/physical_socket_server.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/physical_socket_server.cc @@ -103,6 +103,20 @@ typedef char* SockOptArg; #endif #endif +namespace { +class ScopedSetTrue { + public: + ScopedSetTrue(bool* value) : value_(value) { + RTC_DCHECK(!*value_); + *value_ = true; + } + ~ScopedSetTrue() { *value_ = false; } + + private: + bool* value_; +}; +} // namespace + namespace rtc { std::unique_ptr SocketServer::CreateDefault() { @@ -835,7 +849,7 @@ void SocketDispatcher::OnEvent(uint32_t ff, int err) { #if defined(WEBRTC_USE_EPOLL) -static int GetEpollEvents(uint32_t ff) { +inline static int GetEpollEvents(uint32_t ff) { int events = 0; if (ff & (DE_READ | DE_ACCEPT)) { events |= EPOLLIN; @@ -1061,7 +1075,8 @@ PhysicalSocketServer::~PhysicalSocketServer() { close(epoll_fd_); } #endif - RTC_DCHECK(dispatchers_.empty()); + RTC_DCHECK(dispatcher_by_key_.empty()); + RTC_DCHECK(key_by_dispatcher_.empty()); } void PhysicalSocketServer::WakeUp() { @@ -1100,45 +1115,32 @@ AsyncSocket* PhysicalSocketServer::WrapSocket(SOCKET s) { void PhysicalSocketServer::Add(Dispatcher* pdispatcher) { CritScope cs(&crit_); - if (processing_dispatchers_) { - // A dispatcher is being added while a "Wait" call is processing the - // list of socket events. - // Defer adding to "dispatchers_" set until processing is done to avoid - // invalidating the iterator in "Wait". - pending_remove_dispatchers_.erase(pdispatcher); - pending_add_dispatchers_.insert(pdispatcher); - } else { - dispatchers_.insert(pdispatcher); + if (key_by_dispatcher_.count(pdispatcher)) { + RTC_LOG(LS_WARNING) + << "PhysicalSocketServer asked to add a duplicate dispatcher."; + return; } + uint64_t key = next_dispatcher_key_++; + dispatcher_by_key_.emplace(key, pdispatcher); + key_by_dispatcher_.emplace(pdispatcher, key); #if defined(WEBRTC_USE_EPOLL) if (epoll_fd_ != INVALID_SOCKET) { - AddEpoll(pdispatcher); + AddEpoll(pdispatcher, key); } #endif // WEBRTC_USE_EPOLL } void PhysicalSocketServer::Remove(Dispatcher* pdispatcher) { CritScope cs(&crit_); - if (processing_dispatchers_) { - // A dispatcher is being removed while a "Wait" call is processing the - // list of socket events. - // Defer removal from "dispatchers_" set until processing is done to avoid - // invalidating the iterator in "Wait". - if (!pending_add_dispatchers_.erase(pdispatcher) && - dispatchers_.find(pdispatcher) == dispatchers_.end()) { - RTC_LOG(LS_WARNING) << "PhysicalSocketServer asked to remove a unknown " - "dispatcher, potentially from a duplicate call to " - "Add."; - return; - } - - pending_remove_dispatchers_.insert(pdispatcher); - } else if (!dispatchers_.erase(pdispatcher)) { + if (!key_by_dispatcher_.count(pdispatcher)) { RTC_LOG(LS_WARNING) << "PhysicalSocketServer asked to remove a unknown " "dispatcher, potentially from a duplicate call to Add."; return; } + uint64_t key = key_by_dispatcher_.at(pdispatcher); + key_by_dispatcher_.erase(pdispatcher); + dispatcher_by_key_.erase(key); #if defined(WEBRTC_USE_EPOLL) if (epoll_fd_ != INVALID_SOCKET) { RemoveEpoll(pdispatcher); @@ -1152,34 +1154,22 @@ void PhysicalSocketServer::Update(Dispatcher* pdispatcher) { return; } + // Don't update dispatchers that haven't yet been added. CritScope cs(&crit_); - if (dispatchers_.find(pdispatcher) == dispatchers_.end()) { + if (!key_by_dispatcher_.count(pdispatcher)) { return; } - UpdateEpoll(pdispatcher); + UpdateEpoll(pdispatcher, key_by_dispatcher_.at(pdispatcher)); #endif } -void PhysicalSocketServer::AddRemovePendingDispatchers() { - if (!pending_add_dispatchers_.empty()) { - for (Dispatcher* pdispatcher : pending_add_dispatchers_) { - dispatchers_.insert(pdispatcher); - } - pending_add_dispatchers_.clear(); - } - - if (!pending_remove_dispatchers_.empty()) { - for (Dispatcher* pdispatcher : pending_remove_dispatchers_) { - dispatchers_.erase(pdispatcher); - } - pending_remove_dispatchers_.clear(); - } -} - #if defined(WEBRTC_POSIX) bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { + // We don't support reentrant waiting. + RTC_DCHECK(!waiting_); + ScopedSetTrue s(&waiting_); #if defined(WEBRTC_USE_EPOLL) // We don't keep a dedicated "epoll" descriptor containing only the non-IO // (i.e. signaling) dispatcher, so "poll" will be used instead of the default @@ -1205,6 +1195,9 @@ static void ProcessEvents(Dispatcher* dispatcher, &len); } + // Most often the socket is writable or readable or both, so make a single + // virtual call to get requested events + const uint32_t requested_events = dispatcher->GetRequestedEvents(); uint32_t ff = 0; // Check readable descriptors. If we're waiting on an accept, signal @@ -1212,7 +1205,7 @@ static void ProcessEvents(Dispatcher* dispatcher, // readable or really closed. // TODO(pthatcher): Only peek at TCP descriptors. if (readable) { - if (dispatcher->GetRequestedEvents() & DE_ACCEPT) { + if (requested_events & DE_ACCEPT) { ff |= DE_ACCEPT; } else if (errcode || dispatcher->IsDescriptorClosed()) { ff |= DE_CLOSE; @@ -1224,7 +1217,7 @@ static void ProcessEvents(Dispatcher* dispatcher, // Check writable descriptors. If we're waiting on a connect, detect // success versus failure by the reaped error code. if (writable) { - if (dispatcher->GetRequestedEvents() & DE_CONNECT) { + if (requested_events & DE_CONNECT) { if (!errcode) { ff |= DE_CONNECT; } else { @@ -1258,13 +1251,9 @@ bool PhysicalSocketServer::WaitSelect(int cmsWait, bool process_io) { stop_us = rtc::TimeMicros() + cmsWait * 1000; } - // Zero all fd_sets. Don't need to do this inside the loop since - // select() zeros the descriptors not signaled fd_set fdsRead; - FD_ZERO(&fdsRead); fd_set fdsWrite; - FD_ZERO(&fdsWrite); // Explicitly unpoison these FDs on MemorySanitizer which doesn't handle the // inline assembly in FD_ZERO. // http://crbug.com/344505 @@ -1276,16 +1265,22 @@ bool PhysicalSocketServer::WaitSelect(int cmsWait, bool process_io) { fWait_ = true; while (fWait_) { + // Zero all fd_sets. Although select() zeros the descriptors not signaled, + // we may need to do this for dispatchers that were deleted while + // iterating. + FD_ZERO(&fdsRead); + FD_ZERO(&fdsWrite); int fdmax = -1; { CritScope cr(&crit_); - // TODO(jbauch): Support re-entrant waiting. - RTC_DCHECK(!processing_dispatchers_); - for (Dispatcher* pdispatcher : dispatchers_) { + current_dispatcher_keys_.clear(); + for (auto const& kv : dispatcher_by_key_) { + uint64_t key = kv.first; + Dispatcher* pdispatcher = kv.second; // Query dispatchers for read and write wait state - RTC_DCHECK(pdispatcher); if (!process_io && (pdispatcher != signal_wakeup_)) continue; + current_dispatcher_keys_.push_back(key); int fd = pdispatcher->GetDescriptor(); // "select"ing a file descriptor that is equal to or larger than // FD_SETSIZE will result in undefined behavior. @@ -1323,8 +1318,14 @@ bool PhysicalSocketServer::WaitSelect(int cmsWait, bool process_io) { } else { // We have signaled descriptors CritScope cr(&crit_); - processing_dispatchers_ = true; - for (Dispatcher* pdispatcher : dispatchers_) { + // Iterate only on the dispatchers whose sockets were passed into + // WSAEventSelect; this avoids the ABA problem (a socket being + // destroyed and a new one created with the same file descriptor). + for (uint64_t key : current_dispatcher_keys_) { + if (!dispatcher_by_key_.count(key)) + continue; + Dispatcher* pdispatcher = dispatcher_by_key_.at(key); + int fd = pdispatcher->GetDescriptor(); bool readable = FD_ISSET(fd, &fdsRead); @@ -1340,11 +1341,6 @@ bool PhysicalSocketServer::WaitSelect(int cmsWait, bool process_io) { // The error code can be signaled through reads or writes. ProcessEvents(pdispatcher, readable, writable, readable || writable); } - - processing_dispatchers_ = false; - // Process deferred dispatchers that have been added/removed while the - // events were handled above. - AddRemovePendingDispatchers(); } // Recalc the time remaining to wait. Doing it here means it doesn't get @@ -1365,7 +1361,7 @@ bool PhysicalSocketServer::WaitSelect(int cmsWait, bool process_io) { #if defined(WEBRTC_USE_EPOLL) -void PhysicalSocketServer::AddEpoll(Dispatcher* pdispatcher) { +void PhysicalSocketServer::AddEpoll(Dispatcher* pdispatcher, uint64_t key) { RTC_DCHECK(epoll_fd_ != INVALID_SOCKET); int fd = pdispatcher->GetDescriptor(); RTC_DCHECK(fd != INVALID_SOCKET); @@ -1375,7 +1371,7 @@ void PhysicalSocketServer::AddEpoll(Dispatcher* pdispatcher) { struct epoll_event event = {0}; event.events = GetEpollEvents(pdispatcher->GetRequestedEvents()); - event.data.ptr = pdispatcher; + event.data.u64 = key; int err = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &event); RTC_DCHECK_EQ(err, 0); if (err == -1) { @@ -1404,7 +1400,7 @@ void PhysicalSocketServer::RemoveEpoll(Dispatcher* pdispatcher) { } } -void PhysicalSocketServer::UpdateEpoll(Dispatcher* pdispatcher) { +void PhysicalSocketServer::UpdateEpoll(Dispatcher* pdispatcher, uint64_t key) { RTC_DCHECK(epoll_fd_ != INVALID_SOCKET); int fd = pdispatcher->GetDescriptor(); RTC_DCHECK(fd != INVALID_SOCKET); @@ -1414,7 +1410,7 @@ void PhysicalSocketServer::UpdateEpoll(Dispatcher* pdispatcher) { struct epoll_event event = {0}; event.events = GetEpollEvents(pdispatcher->GetRequestedEvents()); - event.data.ptr = pdispatcher; + event.data.u64 = key; int err = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &event); RTC_DCHECK_EQ(err, 0); if (err == -1) { @@ -1456,11 +1452,12 @@ bool PhysicalSocketServer::WaitEpoll(int cmsWait) { CritScope cr(&crit_); for (int i = 0; i < n; ++i) { const epoll_event& event = epoll_events_[i]; - Dispatcher* pdispatcher = static_cast(event.data.ptr); - if (dispatchers_.find(pdispatcher) == dispatchers_.end()) { + uint64_t key = event.data.u64; + if (!dispatcher_by_key_.count(key)) { // The dispatcher for this socket no longer exists. continue; } + Dispatcher* pdispatcher = dispatcher_by_key_.at(key); bool readable = (event.events & (EPOLLIN | EPOLLPRI)); bool writable = (event.events & EPOLLOUT); @@ -1472,7 +1469,7 @@ bool PhysicalSocketServer::WaitEpoll(int cmsWait) { if (cmsWait != kForever) { tvWait = TimeDiff(tvStop, TimeMillis()); - if (tvWait < 0) { + if (tvWait <= 0) { // Return success on timeout. return true; } @@ -1555,6 +1552,10 @@ bool PhysicalSocketServer::WaitPoll(int cmsWait, Dispatcher* dispatcher) { #if defined(WEBRTC_WIN) bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { + // We don't support reentrant waiting. + RTC_DCHECK(!waiting_); + ScopedSetTrue s(&waiting_); + int64_t cmsTotal = cmsWait; int64_t cmsElapsed = 0; int64_t msStart = Time(); @@ -1562,37 +1563,40 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { fWait_ = true; while (fWait_) { std::vector events; - std::vector event_owners; + std::vector event_owners; events.push_back(socket_ev_); { CritScope cr(&crit_); - // TODO(jbauch): Support re-entrant waiting. - RTC_DCHECK(!processing_dispatchers_); - - // Calling "CheckSignalClose" might remove a closed dispatcher from the - // set. This must be deferred to prevent invalidating the iterator. - processing_dispatchers_ = true; - for (Dispatcher* disp : dispatchers_) { + // Get a snapshot of all current dispatchers; this is used to avoid the + // ABA problem (see later comment) and avoids the dispatcher_by_key_ + // iterator being invalidated by calling CheckSignalClose, which may + // remove the dispatcher from the list. + current_dispatcher_keys_.clear(); + for (auto const& kv : dispatcher_by_key_) { + current_dispatcher_keys_.push_back(kv.first); + } + for (uint64_t key : current_dispatcher_keys_) { + if (!dispatcher_by_key_.count(key)) { + continue; + } + Dispatcher* disp = dispatcher_by_key_.at(key); + if (!disp) + continue; if (!process_io && (disp != signal_wakeup_)) continue; SOCKET s = disp->GetSocket(); if (disp->CheckSignalClose()) { - // We just signalled close, don't poll this socket + // We just signalled close, don't poll this socket. } else if (s != INVALID_SOCKET) { WSAEventSelect(s, events[0], FlagsToEvents(disp->GetRequestedEvents())); } else { events.push_back(disp->GetWSAEvent()); - event_owners.push_back(disp); + event_owners.push_back(key); } } - - processing_dispatchers_ = false; - // Process deferred dispatchers that have been added/removed while the - // events were handled above. - AddRemovePendingDispatchers(); } // Which is shorter, the delay wait or the asked wait? @@ -1624,15 +1628,23 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { int index = dw - WSA_WAIT_EVENT_0; if (index > 0) { --index; // The first event is the socket event - Dispatcher* disp = event_owners[index]; - // The dispatcher could have been removed while waiting for events. - if (dispatchers_.find(disp) != dispatchers_.end()) { - disp->OnPreEvent(0); - disp->OnEvent(0, 0); + uint64_t key = event_owners[index]; + if (!dispatcher_by_key_.count(key)) { + // The dispatcher could have been removed while waiting for events. + continue; } + Dispatcher* disp = dispatcher_by_key_.at(key); + disp->OnPreEvent(0); + disp->OnEvent(0, 0); } else if (process_io) { - processing_dispatchers_ = true; - for (Dispatcher* disp : dispatchers_) { + // Iterate only on the dispatchers whose sockets were passed into + // WSAEventSelect; this avoids the ABA problem (a socket being + // destroyed and a new one created with the same SOCKET handle). + for (uint64_t key : current_dispatcher_keys_) { + if (!dispatcher_by_key_.count(key)) { + continue; + } + Dispatcher* disp = dispatcher_by_key_.at(key); SOCKET s = disp->GetSocket(); if (s == INVALID_SOCKET) continue; @@ -1698,11 +1710,6 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { } } } - - processing_dispatchers_ = false; - // Process deferred dispatchers that have been added/removed while the - // events were handled above. - AddRemovePendingDispatchers(); } // Reset the network event until new activity occurs diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/physical_socket_server.h b/TMessagesProj/jni/voip/webrtc/rtc_base/physical_socket_server.h index 7eaf590e3..cc21a67b1 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/physical_socket_server.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/physical_socket_server.h @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include "rtc_base/deprecated/recursive_critical_section.h" @@ -85,17 +85,13 @@ class RTC_EXPORT PhysicalSocketServer : public SocketServer { // The number of events to process with one call to "epoll_wait". static constexpr size_t kNumEpollEvents = 128; - typedef std::set DispatcherSet; - - void AddRemovePendingDispatchers() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_); - #if defined(WEBRTC_POSIX) bool WaitSelect(int cms, bool process_io); #endif // WEBRTC_POSIX #if defined(WEBRTC_USE_EPOLL) - void AddEpoll(Dispatcher* dispatcher); + void AddEpoll(Dispatcher* dispatcher, uint64_t key); void RemoveEpoll(Dispatcher* dispatcher); - void UpdateEpoll(Dispatcher* dispatcher); + void UpdateEpoll(Dispatcher* dispatcher, uint64_t key); bool WaitEpoll(int cms); bool WaitPoll(int cms, Dispatcher* dispatcher); @@ -106,16 +102,31 @@ class RTC_EXPORT PhysicalSocketServer : public SocketServer { std::array epoll_events_; const int epoll_fd_ = INVALID_SOCKET; #endif // WEBRTC_USE_EPOLL - DispatcherSet dispatchers_ RTC_GUARDED_BY(crit_); - DispatcherSet pending_add_dispatchers_ RTC_GUARDED_BY(crit_); - DispatcherSet pending_remove_dispatchers_ RTC_GUARDED_BY(crit_); - bool processing_dispatchers_ RTC_GUARDED_BY(crit_) = false; + // uint64_t keys are used to uniquely identify a dispatcher in order to avoid + // the ABA problem during the epoll loop (a dispatcher being destroyed and + // replaced by one with the same address). + uint64_t next_dispatcher_key_ RTC_GUARDED_BY(crit_) = 0; + std::unordered_map dispatcher_by_key_ + RTC_GUARDED_BY(crit_); + // Reverse lookup necessary for removals/updates. + std::unordered_map key_by_dispatcher_ + RTC_GUARDED_BY(crit_); + // A list of dispatcher keys that we're interested in for the current + // select() or WSAWaitForMultipleEvents() loop. Again, used to avoid the ABA + // problem (a socket being destroyed and a new one created with the same + // handle, erroneously receiving the events from the destroyed socket). + // + // Kept as a member variable just for efficiency. + std::vector current_dispatcher_keys_; Signaler* signal_wakeup_; // Assigned in constructor only RecursiveCriticalSection crit_; #if defined(WEBRTC_WIN) const WSAEVENT socket_ev_; #endif bool fWait_; + // Are we currently in a select()/epoll()/WSAWaitForMultipleEvents loop? + // Used for a DCHECK, because we don't support reentrant waiting. + bool waiting_ = false; }; class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> { diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/random.h b/TMessagesProj/jni/voip/webrtc/rtc_base/random.h index 93241a3e9..0e2d103cb 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/random.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/random.h @@ -16,7 +16,6 @@ #include #include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -35,6 +34,10 @@ class Random { // See also discussion here: https://codereview.webrtc.org/1623543002/ explicit Random(uint64_t seed); + Random() = delete; + Random(const Random&) = delete; + Random& operator=(const Random&) = delete; + // Return pseudo-random integer of the specified type. // We need to limit the size to 32 bits to keep the output close to uniform. template @@ -73,8 +76,6 @@ class Random { } uint64_t state_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Random); }; // Return pseudo-random number in the interval [0.0, 1.0). diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/rate_limiter.h b/TMessagesProj/jni/voip/webrtc/rtc_base/rate_limiter.h index 051ccf6aa..9bbe21f9c 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/rate_limiter.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/rate_limiter.h @@ -14,7 +14,6 @@ #include #include -#include "rtc_base/constructor_magic.h" #include "rtc_base/rate_statistics.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -29,6 +28,11 @@ class Clock; class RateLimiter { public: RateLimiter(Clock* clock, int64_t max_window_ms); + + RateLimiter() = delete; + RateLimiter(const RateLimiter&) = delete; + RateLimiter& operator=(const RateLimiter&) = delete; + ~RateLimiter(); // Try to use rate to send bytes. Returns true on success and if so updates @@ -49,8 +53,6 @@ class RateLimiter { RateStatistics current_rate_ RTC_GUARDED_BY(lock_); int64_t window_size_ms_ RTC_GUARDED_BY(lock_); uint32_t max_rate_bps_ RTC_GUARDED_BY(lock_); - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RateLimiter); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/rolling_accumulator.h b/TMessagesProj/jni/voip/webrtc/rtc_base/rolling_accumulator.h index 015229b04..241bd72a1 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/rolling_accumulator.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/rolling_accumulator.h @@ -40,7 +40,7 @@ class RollingAccumulator { size_t count() const { return static_cast(stats_.Size()); } void Reset() { - stats_ = webrtc::RunningStatistics(); + stats_ = webrtc::webrtc_impl::RunningStatistics(); next_index_ = 0U; max_ = T(); max_stale_ = false; @@ -129,7 +129,7 @@ class RollingAccumulator { double ComputeVariance() const { return stats_.GetVariance().value_or(0); } private: - webrtc::RunningStatistics stats_; + webrtc::webrtc_impl::RunningStatistics stats_; size_t next_index_; mutable T max_; mutable bool max_stale_; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/rtc_certificate_generator.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/rtc_certificate_generator.cc index 4c9d378dd..d95b64539 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/rtc_certificate_generator.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/rtc_certificate_generator.cc @@ -30,75 +30,6 @@ namespace { const char kIdentityName[] = "WebRTC"; const uint64_t kYearInSeconds = 365 * 24 * 60 * 60; -enum { - MSG_GENERATE, - MSG_GENERATE_DONE, -}; - -// Helper class for generating certificates asynchronously; a single task -// instance is responsible for a single asynchronous certificate generation -// request. We are using a separate helper class so that a generation request -// can outlive the |RTCCertificateGenerator| that spawned it. -class RTCCertificateGenerationTask : public RefCountInterface, - public MessageHandler { - public: - RTCCertificateGenerationTask( - Thread* signaling_thread, - Thread* worker_thread, - const KeyParams& key_params, - const absl::optional& expires_ms, - const scoped_refptr& callback) - : signaling_thread_(signaling_thread), - worker_thread_(worker_thread), - key_params_(key_params), - expires_ms_(expires_ms), - callback_(callback) { - RTC_DCHECK(signaling_thread_); - RTC_DCHECK(worker_thread_); - RTC_DCHECK(callback_); - } - ~RTCCertificateGenerationTask() override {} - - // Handles |MSG_GENERATE| and its follow-up |MSG_GENERATE_DONE|. - void OnMessage(Message* msg) override { - switch (msg->message_id) { - case MSG_GENERATE: - RTC_DCHECK(worker_thread_->IsCurrent()); - // Perform the certificate generation work here on the worker thread. - certificate_ = RTCCertificateGenerator::GenerateCertificate( - key_params_, expires_ms_); - // Handle callbacks on signaling thread. Pass on the |msg->pdata| - // (which references |this| with ref counting) to that thread. - signaling_thread_->Post(RTC_FROM_HERE, this, MSG_GENERATE_DONE, - msg->pdata); - break; - case MSG_GENERATE_DONE: - RTC_DCHECK(signaling_thread_->IsCurrent()); - // Perform callback with result here on the signaling thread. - if (certificate_) { - callback_->OnSuccess(certificate_); - } else { - callback_->OnFailure(); - } - // Destroy |msg->pdata| which references |this| with ref counting. This - // may result in |this| being deleted - do not touch member variables - // after this line. - delete msg->pdata; - return; - default: - RTC_NOTREACHED(); - } - } - - private: - Thread* const signaling_thread_; - Thread* const worker_thread_; - const KeyParams key_params_; - const absl::optional expires_ms_; - const scoped_refptr callback_; - scoped_refptr certificate_; -}; - } // namespace // static @@ -148,13 +79,16 @@ void RTCCertificateGenerator::GenerateCertificateAsync( // Create a new |RTCCertificateGenerationTask| for this generation request. It // is reference counted and referenced by the message data, ensuring it lives // until the task has completed (independent of |RTCCertificateGenerator|). - ScopedRefMessageData* msg_data = - new ScopedRefMessageData( - new RefCountedObject( - signaling_thread_, worker_thread_, key_params, expires_ms, - callback)); - worker_thread_->Post(RTC_FROM_HERE, msg_data->data().get(), MSG_GENERATE, - msg_data); + worker_thread_->PostTask(RTC_FROM_HERE, [key_params, expires_ms, + signaling_thread = signaling_thread_, + cb = callback]() { + scoped_refptr certificate = + RTCCertificateGenerator::GenerateCertificate(key_params, expires_ms); + signaling_thread->PostTask( + RTC_FROM_HERE, [cert = std::move(certificate), cb = std::move(cb)]() { + cert ? cb->OnSuccess(cert) : cb->OnFailure(); + }); + }); } } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/ssl_roots.h b/TMessagesProj/jni/voip/webrtc/rtc_base/ssl_roots.h index 23a3836e6..8f869f4a9 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/ssl_roots.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/ssl_roots.h @@ -15,8 +15,8 @@ // Google. // It was generated with the following command line: -// > python tools/sslroots/generate_sslroots.py -// https://pki.google.com/roots.pem +// > python tools_webrtc/sslroots/generate_sslroots.py +// https://pki.goog/roots.pem // clang-format off // Don't bother formatting generated code, @@ -1699,82 +1699,6 @@ const unsigned char GlobalSign_ECC_Root_CA___R5_certificate[546]={ }; -/* subject:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root */ -/* issuer :/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root */ - - -const unsigned char AddTrust_External_Root_certificate[1082]={ -0x30,0x82,0x04,0x36,0x30,0x82,0x03,0x1E,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, -0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31,0x14, -0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75,0x73, -0x74,0x20,0x41,0x42,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41, -0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x45,0x78,0x74,0x65,0x72,0x6E,0x61,0x6C, -0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x22,0x30,0x20, -0x06,0x03,0x55,0x04,0x03,0x13,0x19,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20, -0x45,0x78,0x74,0x65,0x72,0x6E,0x61,0x6C,0x20,0x43,0x41,0x20,0x52,0x6F,0x6F,0x74, -0x30,0x1E,0x17,0x0D,0x30,0x30,0x30,0x35,0x33,0x30,0x31,0x30,0x34,0x38,0x33,0x38, -0x5A,0x17,0x0D,0x32,0x30,0x30,0x35,0x33,0x30,0x31,0x30,0x34,0x38,0x33,0x38,0x5A, -0x30,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53,0x45,0x31, -0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54,0x72,0x75, -0x73,0x74,0x20,0x41,0x42,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D, -0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x45,0x78,0x74,0x65,0x72,0x6E,0x61, -0x6C,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x22,0x30, -0x20,0x06,0x03,0x55,0x04,0x03,0x13,0x19,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74, -0x20,0x45,0x78,0x74,0x65,0x72,0x6E,0x61,0x6C,0x20,0x43,0x41,0x20,0x52,0x6F,0x6F, -0x74,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, -0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01, -0x01,0x00,0xB7,0xF7,0x1A,0x33,0xE6,0xF2,0x00,0x04,0x2D,0x39,0xE0,0x4E,0x5B,0xED, -0x1F,0xBC,0x6C,0x0F,0xCD,0xB5,0xFA,0x23,0xB6,0xCE,0xDE,0x9B,0x11,0x33,0x97,0xA4, -0x29,0x4C,0x7D,0x93,0x9F,0xBD,0x4A,0xBC,0x93,0xED,0x03,0x1A,0xE3,0x8F,0xCF,0xE5, -0x6D,0x50,0x5A,0xD6,0x97,0x29,0x94,0x5A,0x80,0xB0,0x49,0x7A,0xDB,0x2E,0x95,0xFD, -0xB8,0xCA,0xBF,0x37,0x38,0x2D,0x1E,0x3E,0x91,0x41,0xAD,0x70,0x56,0xC7,0xF0,0x4F, -0x3F,0xE8,0x32,0x9E,0x74,0xCA,0xC8,0x90,0x54,0xE9,0xC6,0x5F,0x0F,0x78,0x9D,0x9A, -0x40,0x3C,0x0E,0xAC,0x61,0xAA,0x5E,0x14,0x8F,0x9E,0x87,0xA1,0x6A,0x50,0xDC,0xD7, -0x9A,0x4E,0xAF,0x05,0xB3,0xA6,0x71,0x94,0x9C,0x71,0xB3,0x50,0x60,0x0A,0xC7,0x13, -0x9D,0x38,0x07,0x86,0x02,0xA8,0xE9,0xA8,0x69,0x26,0x18,0x90,0xAB,0x4C,0xB0,0x4F, -0x23,0xAB,0x3A,0x4F,0x84,0xD8,0xDF,0xCE,0x9F,0xE1,0x69,0x6F,0xBB,0xD7,0x42,0xD7, -0x6B,0x44,0xE4,0xC7,0xAD,0xEE,0x6D,0x41,0x5F,0x72,0x5A,0x71,0x08,0x37,0xB3,0x79, -0x65,0xA4,0x59,0xA0,0x94,0x37,0xF7,0x00,0x2F,0x0D,0xC2,0x92,0x72,0xDA,0xD0,0x38, -0x72,0xDB,0x14,0xA8,0x45,0xC4,0x5D,0x2A,0x7D,0xB7,0xB4,0xD6,0xC4,0xEE,0xAC,0xCD, -0x13,0x44,0xB7,0xC9,0x2B,0xDD,0x43,0x00,0x25,0xFA,0x61,0xB9,0x69,0x6A,0x58,0x23, -0x11,0xB7,0xA7,0x33,0x8F,0x56,0x75,0x59,0xF5,0xCD,0x29,0xD7,0x46,0xB7,0x0A,0x2B, -0x65,0xB6,0xD3,0x42,0x6F,0x15,0xB2,0xB8,0x7B,0xFB,0xEF,0xE9,0x5D,0x53,0xD5,0x34, -0x5A,0x27,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xDC,0x30,0x81,0xD9,0x30,0x1D,0x06, -0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xAD,0xBD,0x98,0x7A,0x34,0xB4,0x26,0xF7, -0xFA,0xC4,0x26,0x54,0xEF,0x03,0xBD,0xE0,0x24,0xCB,0x54,0x1A,0x30,0x0B,0x06,0x03, -0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13, -0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x81,0x99,0x06,0x03,0x55, -0x1D,0x23,0x04,0x81,0x91,0x30,0x81,0x8E,0x80,0x14,0xAD,0xBD,0x98,0x7A,0x34,0xB4, -0x26,0xF7,0xFA,0xC4,0x26,0x54,0xEF,0x03,0xBD,0xE0,0x24,0xCB,0x54,0x1A,0xA1,0x73, -0xA4,0x71,0x30,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x53, -0x45,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x13,0x0B,0x41,0x64,0x64,0x54, -0x72,0x75,0x73,0x74,0x20,0x41,0x42,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B, -0x13,0x1D,0x41,0x64,0x64,0x54,0x72,0x75,0x73,0x74,0x20,0x45,0x78,0x74,0x65,0x72, -0x6E,0x61,0x6C,0x20,0x54,0x54,0x50,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31, -0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x13,0x19,0x41,0x64,0x64,0x54,0x72,0x75, -0x73,0x74,0x20,0x45,0x78,0x74,0x65,0x72,0x6E,0x61,0x6C,0x20,0x43,0x41,0x20,0x52, -0x6F,0x6F,0x74,0x82,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, -0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xB0,0x9B,0xE0,0x85,0x25,0xC2, -0xD6,0x23,0xE2,0x0F,0x96,0x06,0x92,0x9D,0x41,0x98,0x9C,0xD9,0x84,0x79,0x81,0xD9, -0x1E,0x5B,0x14,0x07,0x23,0x36,0x65,0x8F,0xB0,0xD8,0x77,0xBB,0xAC,0x41,0x6C,0x47, -0x60,0x83,0x51,0xB0,0xF9,0x32,0x3D,0xE7,0xFC,0xF6,0x26,0x13,0xC7,0x80,0x16,0xA5, -0xBF,0x5A,0xFC,0x87,0xCF,0x78,0x79,0x89,0x21,0x9A,0xE2,0x4C,0x07,0x0A,0x86,0x35, -0xBC,0xF2,0xDE,0x51,0xC4,0xD2,0x96,0xB7,0xDC,0x7E,0x4E,0xEE,0x70,0xFD,0x1C,0x39, -0xEB,0x0C,0x02,0x51,0x14,0x2D,0x8E,0xBD,0x16,0xE0,0xC1,0xDF,0x46,0x75,0xE7,0x24, -0xAD,0xEC,0xF4,0x42,0xB4,0x85,0x93,0x70,0x10,0x67,0xBA,0x9D,0x06,0x35,0x4A,0x18, -0xD3,0x2B,0x7A,0xCC,0x51,0x42,0xA1,0x7A,0x63,0xD1,0xE6,0xBB,0xA1,0xC5,0x2B,0xC2, -0x36,0xBE,0x13,0x0D,0xE6,0xBD,0x63,0x7E,0x79,0x7B,0xA7,0x09,0x0D,0x40,0xAB,0x6A, -0xDD,0x8F,0x8A,0xC3,0xF6,0xF6,0x8C,0x1A,0x42,0x05,0x51,0xD4,0x45,0xF5,0x9F,0xA7, -0x62,0x21,0x68,0x15,0x20,0x43,0x3C,0x99,0xE7,0x7C,0xBD,0x24,0xD8,0xA9,0x91,0x17, -0x73,0x88,0x3F,0x56,0x1B,0x31,0x38,0x18,0xB4,0x71,0x0F,0x9A,0xCD,0xC8,0x0E,0x9E, -0x8E,0x2E,0x1B,0xE1,0x8C,0x98,0x83,0xCB,0x1F,0x31,0xF1,0x44,0x4C,0xC6,0x04,0x73, -0x49,0x76,0x60,0x0F,0xC7,0xF8,0xBD,0x17,0x80,0x6B,0x2E,0xE9,0xCC,0x4C,0x0E,0x5A, -0x9A,0x79,0x0F,0x20,0x0A,0x2E,0xD5,0x9E,0x63,0x26,0x1E,0x55,0x92,0x94,0xD8,0x82, -0x17,0x5A,0x7B,0xD0,0xBC,0xC7,0x8F,0x4E,0x86,0x04, -}; - - /* subject:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust ECC Certification Authority */ /* issuer :/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust ECC Certification Authority */ @@ -2572,50 +2496,6 @@ const unsigned char Entrust_Root_Certification_Authority___EC1_certificate[765]= }; -/* subject:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA - R8 */ -/* issuer :/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA - R8 */ - - -const unsigned char GlobalSign_Root_CA___R8_certificate[567]={ -0x30,0x82,0x02,0x33,0x30,0x82,0x01,0xB9,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x48, -0x1B,0x6A,0x09,0xF4,0xF9,0x60,0x71,0x3A,0xFE,0x81,0xCC,0x86,0xDD,0x30,0x0A,0x06, -0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x30,0x5C,0x31,0x0B,0x30,0x09,0x06, -0x03,0x55,0x04,0x06,0x13,0x02,0x42,0x45,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04, -0x0A,0x13,0x10,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x6E,0x76, -0x2D,0x73,0x61,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0B,0x13,0x07,0x52,0x6F, -0x6F,0x74,0x20,0x43,0x41,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, -0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20, -0x43,0x41,0x20,0x2D,0x20,0x52,0x38,0x30,0x1E,0x17,0x0D,0x31,0x36,0x30,0x36,0x31, -0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36,0x30,0x36,0x31,0x35, -0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x5C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, -0x04,0x06,0x13,0x02,0x42,0x45,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0A,0x13, -0x10,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x6E,0x76,0x2D,0x73, -0x61,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0B,0x13,0x07,0x52,0x6F,0x6F,0x74, -0x20,0x43,0x41,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x47,0x6C, -0x6F,0x62,0x61,0x6C,0x53,0x69,0x67,0x6E,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41, -0x20,0x2D,0x20,0x52,0x38,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, -0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xB8,0xEE,0x7C, -0x30,0x87,0xD8,0x94,0x1F,0x54,0x6B,0x6D,0x98,0x9D,0xFC,0x75,0xFB,0x5B,0x88,0xAB, -0x42,0xBA,0x8D,0x7D,0x39,0x7E,0xDD,0x44,0x3D,0x39,0x3C,0xE1,0x05,0xA1,0x4A,0x64, -0x60,0xAC,0x37,0xA6,0x73,0xB0,0xF9,0xC9,0x45,0x4B,0x0B,0x06,0xD0,0x3A,0xE0,0xF1, -0x6D,0x5F,0xFA,0x5E,0x5B,0x5A,0x52,0xB5,0x76,0xE3,0x46,0xDB,0xD5,0x1E,0x8C,0x74, -0x7A,0x42,0xC9,0x41,0x35,0x4F,0xC6,0xD4,0xE2,0x28,0x60,0xAB,0x34,0x8A,0xCE,0xB1, -0x40,0x23,0x46,0xA5,0xAE,0x19,0x24,0x52,0x7C,0x90,0x55,0x44,0xCE,0xA3,0x42,0x30, -0x40,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01, -0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01, -0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x2F,0x3A,0x12, -0x26,0x80,0xE8,0x8A,0xC2,0x50,0x78,0x6D,0x06,0xC4,0x34,0x7E,0xE2,0x49,0x39,0x57, -0x76,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x03,0x68,0x00, -0x30,0x65,0x02,0x31,0x00,0xC7,0xA1,0x3D,0xB2,0x92,0x90,0xFA,0xCA,0x5D,0xE0,0x27, -0x84,0x82,0x3B,0x21,0xCC,0xF4,0x8D,0xF8,0x94,0x56,0xF2,0x20,0x5F,0x11,0xC0,0xAC, -0xBC,0x5F,0x15,0xA5,0x0B,0xC8,0x16,0x43,0xA7,0xF8,0xC5,0x7F,0x8D,0x20,0xA0,0x7F, -0x5E,0xFC,0x16,0x1C,0x27,0x02,0x30,0x1E,0x8C,0xF5,0x56,0xBF,0x38,0xDB,0x9C,0xE6, -0xA6,0xD7,0x84,0x29,0xE6,0xDF,0x0D,0x53,0x2E,0xE8,0x2B,0x01,0xB7,0x7D,0x09,0x3C, -0xB1,0x32,0x6A,0x1A,0x9A,0xB8,0x0A,0xEA,0xE8,0xAD,0x08,0xF2,0x74,0x39,0xD5,0x2B, -0x22,0x36,0xDC,0xEF,0x46,0x66,0xD8, -}; - - /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */ /* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */ @@ -2817,7 +2697,6 @@ const unsigned char* const kSSLCertCertificateList[] = { COMODO_Certification_Authority_certificate, GlobalSign_ECC_Root_CA___R4_certificate, GlobalSign_ECC_Root_CA___R5_certificate, - AddTrust_External_Root_certificate, USERTrust_ECC_Certification_Authority_certificate, Entrust_net_Premium_2048_Secure_Server_CA_certificate, AffirmTrust_Premium_ECC_certificate, @@ -2830,7 +2709,6 @@ const unsigned char* const kSSLCertCertificateList[] = { DigiCert_Trusted_Root_G4_certificate, COMODO_ECC_Certification_Authority_certificate, Entrust_Root_Certification_Authority___EC1_certificate, - GlobalSign_Root_CA___R8_certificate, GeoTrust_Global_CA_certificate, DigiCert_Assured_ID_Root_G3_certificate, Go_Daddy_Root_Certificate_Authority___G2_certificate, @@ -2861,7 +2739,6 @@ const size_t kSSLCertCertificateSizeList[] = { 1057, 485, 546, - 1082, 659, 1070, 514, @@ -2874,7 +2751,6 @@ const size_t kSSLCertCertificateSizeList[] = { 1428, 653, 765, - 567, 856, 586, 969, diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/ssl_stream_adapter.h b/TMessagesProj/jni/voip/webrtc/rtc_base/ssl_stream_adapter.h index 3da0b0946..7bff72651 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/ssl_stream_adapter.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/ssl_stream_adapter.h @@ -93,11 +93,11 @@ bool IsGcmCryptoSuiteName(const std::string& crypto_suite); enum SSLRole { SSL_CLIENT, SSL_SERVER }; enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS }; -// Note: TLS_10, TLS_11, and DTLS_10 will all be ignored, and only -// DTLS1_2 will be accepted, if the trial flag -// WebRTC-LegacyTlsProtocols/Disabled/ is passed in. Support for these -// protocol versions will be completely removed in M84 or later. -// TODO(https://bugs.webrtc.org/10261). +// Note: TLS_10, TLS_11, and DTLS_10 will all be ignored, and only DTLS1_2 will +// be accepted unless the trial flag WebRTC-LegacyTlsProtocols/Enabled/ is +// passed in or an explicit override is used. Support for the legacy protocol +// versions will be completely removed in the future. +// See https://bugs.webrtc.org/10261. enum SSLProtocolVersion { SSL_PROTOCOL_NOT_GIVEN = -1, SSL_PROTOCOL_TLS_10 = 0, diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/stream.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/stream.cc index 1b0a4d759..ee72f8d2b 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/stream.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/stream.cc @@ -24,7 +24,6 @@ namespace rtc { /////////////////////////////////////////////////////////////////////////////// // StreamInterface /////////////////////////////////////////////////////////////////////////////// -StreamInterface::~StreamInterface() {} StreamResult StreamInterface::WriteAll(const void* data, size_t data_len, @@ -44,29 +43,12 @@ StreamResult StreamInterface::WriteAll(const void* data, return result; } -void StreamInterface::PostEvent(Thread* t, int events, int err) { - t->Post(RTC_FROM_HERE, this, MSG_POST_EVENT, - new StreamEventData(events, err)); -} - -void StreamInterface::PostEvent(int events, int err) { - PostEvent(Thread::Current(), events, err); -} - bool StreamInterface::Flush() { return false; } StreamInterface::StreamInterface() {} -void StreamInterface::OnMessage(Message* msg) { - if (MSG_POST_EVENT == msg->message_id) { - StreamEventData* pe = static_cast(msg->pdata); - SignalEvent(this, pe->events, pe->error); - delete msg->pdata; - } -} - /////////////////////////////////////////////////////////////////////////////// // StreamAdapterInterface /////////////////////////////////////////////////////////////////////////////// diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/stream.h b/TMessagesProj/jni/voip/webrtc/rtc_base/stream.h index dc77a7111..9bf11a240 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/stream.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/stream.h @@ -48,16 +48,9 @@ enum StreamResult { SR_ERROR, SR_SUCCESS, SR_BLOCK, SR_EOS }; // SE_WRITE: Data can be written, so Write is likely to not return SR_BLOCK enum StreamEvent { SE_OPEN = 1, SE_READ = 2, SE_WRITE = 4, SE_CLOSE = 8 }; -struct StreamEventData : public MessageData { - int events, error; - StreamEventData(int ev, int er) : events(ev), error(er) {} -}; - -class RTC_EXPORT StreamInterface : public MessageHandler { +class RTC_EXPORT StreamInterface { public: - enum { MSG_POST_EVENT = 0xF1F1, MSG_MAX = MSG_POST_EVENT }; - - ~StreamInterface() override; + virtual ~StreamInterface() {} virtual StreamState GetState() const = 0; @@ -96,13 +89,6 @@ class RTC_EXPORT StreamInterface : public MessageHandler { // certain events will be raised in the future. sigslot::signal3 SignalEvent; - // Like calling SignalEvent, but posts a message to the specified thread, - // which will call SignalEvent. This helps unroll the stack and prevent - // re-entrancy. - void PostEvent(Thread* t, int events, int err); - // Like the aforementioned method, but posts to the current thread. - void PostEvent(int events, int err); - // Return true if flush is successful. virtual bool Flush(); @@ -125,9 +111,6 @@ class RTC_EXPORT StreamInterface : public MessageHandler { protected: StreamInterface(); - // MessageHandler Interface - void OnMessage(Message* msg) override; - private: RTC_DISALLOW_COPY_AND_ASSIGN(StreamInterface); }; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/string_utils.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/string_utils.cc index dfbb54805..1720c62d5 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/string_utils.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/string_utils.cc @@ -50,10 +50,4 @@ std::string ToHex(const int i) { return std::string(buffer); } -std::string LeftPad(char padding, unsigned length, std::string s) { - if (s.length() >= length) - return s; - return std::string(length - s.length(), padding) + s; -} - } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/string_utils.h b/TMessagesProj/jni/voip/webrtc/rtc_base/string_utils.h index 3518702ec..23c55cb89 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/string_utils.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/string_utils.h @@ -88,8 +88,6 @@ std::string string_trim(const std::string& s); // TODO(jonasolsson): replace with absl::Hex when that becomes available. std::string ToHex(const int i); -std::string LeftPad(char padding, unsigned length, std::string s); - } // namespace rtc #endif // RTC_BASE_STRING_UTILS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/stringize_macros.h b/TMessagesProj/jni/voip/webrtc/rtc_base/stringize_macros.h deleted file mode 100644 index aee8d1455..000000000 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/stringize_macros.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -// Modified from the Chromium original: -// src/base/strings/stringize_macros.h - -// This file defines preprocessor macros for stringizing preprocessor -// symbols (or their output) and manipulating preprocessor symbols -// that define strings. - -#ifndef RTC_BASE_STRINGIZE_MACROS_H_ -#define RTC_BASE_STRINGIZE_MACROS_H_ - -// This is not very useful as it does not expand defined symbols if -// called directly. Use its counterpart without the _NO_EXPANSION -// suffix, below. -#define STRINGIZE_NO_EXPANSION(x) #x - -// Use this to quote the provided parameter, first expanding it if it -// is a preprocessor symbol. -// -// For example, if: -// #define A FOO -// #define B(x) myobj->FunctionCall(x) -// -// Then: -// STRINGIZE(A) produces "FOO" -// STRINGIZE(B(y)) produces "myobj->FunctionCall(y)" -#define STRINGIZE(x) STRINGIZE_NO_EXPANSION(x) - -#endif // RTC_BASE_STRINGIZE_MACROS_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/swap_queue.h b/TMessagesProj/jni/voip/webrtc/rtc_base/swap_queue.h index eb0b1fff0..9eac49a93 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/swap_queue.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/swap_queue.h @@ -141,7 +141,8 @@ class SwapQueue { return false; } - std::swap(*input, queue_[next_write_index_]); + using std::swap; + swap(*input, queue_[next_write_index_]); // Increment the value of num_elements_ to account for the inserted element. // Release memory ordering prevents the reads and writes to @@ -181,7 +182,8 @@ class SwapQueue { return false; } - std::swap(*output, queue_[next_read_index_]); + using std::swap; + swap(*output, queue_[next_read_index_]); // Decrement the value of num_elements_ to account for the removed element. // Release memory ordering prevents the reads and writes to diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/mutex.h b/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/mutex.h index 1ccbbdcbd..620fe74e4 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/mutex.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/mutex.h @@ -15,7 +15,6 @@ #include "absl/base/const_init.h" #include "rtc_base/checks.h" -#include "rtc_base/platform_thread_types.h" #include "rtc_base/system/unused.h" #include "rtc_base/thread_annotations.h" @@ -40,54 +39,17 @@ class RTC_LOCKABLE Mutex final { Mutex& operator=(const Mutex&) = delete; void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() { - rtc::PlatformThreadRef current = CurrentThreadRefAssertingNotBeingHolder(); impl_.Lock(); - // |holder_| changes from 0 to CurrentThreadRef(). - holder_.store(current, std::memory_order_relaxed); } RTC_WARN_UNUSED_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) { - rtc::PlatformThreadRef current = CurrentThreadRefAssertingNotBeingHolder(); - if (impl_.TryLock()) { - // |holder_| changes from 0 to CurrentThreadRef(). - holder_.store(current, std::memory_order_relaxed); - return true; - } - return false; + return impl_.TryLock(); } void Unlock() RTC_UNLOCK_FUNCTION() { - // |holder_| changes from CurrentThreadRef() to 0. If something else than - // CurrentThreadRef() is stored in |holder_|, the Unlock results in - // undefined behavior as mutexes can't be unlocked from another thread than - // the one that locked it, or called while not being locked. - holder_.store(0, std::memory_order_relaxed); impl_.Unlock(); } private: - rtc::PlatformThreadRef CurrentThreadRefAssertingNotBeingHolder() { - rtc::PlatformThreadRef holder = holder_.load(std::memory_order_relaxed); - rtc::PlatformThreadRef current = rtc::CurrentThreadRef(); - // TODO(bugs.webrtc.org/11567): remove this temporary check after migrating - // fully to Mutex. - RTC_CHECK_NE(holder, current); - return current; - } - MutexImpl impl_; - // TODO(bugs.webrtc.org/11567): remove |holder_| after migrating fully to - // Mutex. - // |holder_| contains the PlatformThreadRef of the thread currently holding - // the lock, or 0. - // Remarks on the used memory orders: the atomic load in - // CurrentThreadRefAssertingNotBeingHolder() observes either of two things: - // 1. our own previous write to holder_ with our thread ID. - // 2. another thread (with ID y) writing y and then 0 from an initial value of - // 0. If we're observing case 1, our own stores are obviously ordered before - // the load, and hit the CHECK. If we're observing case 2, the value observed - // w.r.t |impl_| being locked depends on the memory order. Since we only care - // that it's different from CurrentThreadRef()), we use the more performant - // option, memory_order_relaxed. - std::atomic holder_ = {0}; }; // MutexLock, for serializing execution through a scope. diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_posix.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_posix.cc deleted file mode 100644 index 15ef3d706..000000000 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_posix.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2011 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 "rtc_base/synchronization/rw_lock_posix.h" - -#include - -namespace webrtc { - -RWLockPosix::RWLockPosix() : lock_() {} - -RWLockPosix::~RWLockPosix() { - pthread_rwlock_destroy(&lock_); -} - -RWLockPosix* RWLockPosix::Create() { - RWLockPosix* ret_val = new RWLockPosix(); - if (!ret_val->Init()) { - delete ret_val; - return NULL; - } - return ret_val; -} - -bool RWLockPosix::Init() { - return pthread_rwlock_init(&lock_, 0) == 0; -} - -void RWLockPosix::AcquireLockExclusive() { - pthread_rwlock_wrlock(&lock_); -} - -void RWLockPosix::ReleaseLockExclusive() { - pthread_rwlock_unlock(&lock_); -} - -void RWLockPosix::AcquireLockShared() { - pthread_rwlock_rdlock(&lock_); -} - -void RWLockPosix::ReleaseLockShared() { - pthread_rwlock_unlock(&lock_); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_posix.h b/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_posix.h deleted file mode 100644 index a103fe771..000000000 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_posix.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2011 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. - */ - -#ifndef RTC_BASE_SYNCHRONIZATION_RW_LOCK_POSIX_H_ -#define RTC_BASE_SYNCHRONIZATION_RW_LOCK_POSIX_H_ - -#include - -#include "rtc_base/synchronization/rw_lock_wrapper.h" - -namespace webrtc { - -class RWLockPosix : public RWLockWrapper { - public: - static RWLockPosix* Create(); - ~RWLockPosix() override; - - void AcquireLockExclusive() override; - void ReleaseLockExclusive() override; - - void AcquireLockShared() override; - void ReleaseLockShared() override; - - private: - RWLockPosix(); - bool Init(); - - pthread_rwlock_t lock_; -}; - -} // namespace webrtc - -#endif // RTC_BASE_SYNCHRONIZATION_RW_LOCK_POSIX_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_win.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_win.cc deleted file mode 100644 index 3274c78a9..000000000 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_win.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012 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 "rtc_base/synchronization/rw_lock_win.h" - -#include "rtc_base/logging.h" - -namespace webrtc { - -RWLockWin::RWLockWin() { - InitializeSRWLock(&lock_); -} - -RWLockWin* RWLockWin::Create() { - return new RWLockWin(); -} - -void RWLockWin::AcquireLockExclusive() { - AcquireSRWLockExclusive(&lock_); -} - -void RWLockWin::ReleaseLockExclusive() { - ReleaseSRWLockExclusive(&lock_); -} - -void RWLockWin::AcquireLockShared() { - AcquireSRWLockShared(&lock_); -} - -void RWLockWin::ReleaseLockShared() { - ReleaseSRWLockShared(&lock_); -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_win.h b/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_win.h deleted file mode 100644 index 43bde1da9..000000000 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_win.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -#ifndef RTC_BASE_SYNCHRONIZATION_RW_LOCK_WIN_H_ -#define RTC_BASE_SYNCHRONIZATION_RW_LOCK_WIN_H_ - -#include - -#include "rtc_base/synchronization/rw_lock_wrapper.h" - -namespace webrtc { - -class RWLockWin : public RWLockWrapper { - public: - static RWLockWin* Create(); - - void AcquireLockExclusive() override; - void ReleaseLockExclusive() override; - - void AcquireLockShared() override; - void ReleaseLockShared() override; - - private: - RWLockWin(); - - SRWLOCK lock_; -}; - -} // namespace webrtc - -#endif // RTC_BASE_SYNCHRONIZATION_RW_LOCK_WIN_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.cc deleted file mode 100644 index fb464192a..000000000 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2012 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 "rtc_base/synchronization/rw_lock_wrapper.h" - -#if defined(_WIN32) -#include "rtc_base/synchronization/rw_lock_win.h" -#else -#include "rtc_base/synchronization/rw_lock_posix.h" -#endif - -namespace webrtc { - -RWLockWrapper* RWLockWrapper::CreateRWLock() { -#ifdef _WIN32 - return RWLockWin::Create(); -#else - return RWLockPosix::Create(); -#endif -} - -} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.h b/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.h deleted file mode 100644 index 39f52fca3..000000000 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/synchronization/rw_lock_wrapper.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2011 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. - */ - -#ifndef RTC_BASE_SYNCHRONIZATION_RW_LOCK_WRAPPER_H_ -#define RTC_BASE_SYNCHRONIZATION_RW_LOCK_WRAPPER_H_ - -#include "rtc_base/thread_annotations.h" - -// Note, Windows pre-Vista version of RW locks are not supported natively. For -// these OSs regular critical sections have been used to approximate RW lock -// functionality and will therefore have worse performance. - -namespace webrtc { - -class RTC_LOCKABLE RWLockWrapper { - public: - static RWLockWrapper* CreateRWLock(); - virtual ~RWLockWrapper() {} - - virtual void AcquireLockExclusive() RTC_EXCLUSIVE_LOCK_FUNCTION() = 0; - virtual void ReleaseLockExclusive() RTC_UNLOCK_FUNCTION() = 0; - - virtual void AcquireLockShared() RTC_SHARED_LOCK_FUNCTION() = 0; - virtual void ReleaseLockShared() RTC_UNLOCK_FUNCTION() = 0; -}; - -// RAII extensions of the RW lock. Prevents Acquire/Release missmatches and -// provides more compact locking syntax. -class RTC_SCOPED_LOCKABLE ReadLockScoped { - public: - explicit ReadLockScoped(RWLockWrapper& rw_lock) - RTC_SHARED_LOCK_FUNCTION(rw_lock) - : rw_lock_(rw_lock) { - rw_lock_.AcquireLockShared(); - } - - ~ReadLockScoped() RTC_UNLOCK_FUNCTION() { rw_lock_.ReleaseLockShared(); } - - private: - RWLockWrapper& rw_lock_; -}; - -class RTC_SCOPED_LOCKABLE WriteLockScoped { - public: - explicit WriteLockScoped(RWLockWrapper& rw_lock) - RTC_EXCLUSIVE_LOCK_FUNCTION(rw_lock) - : rw_lock_(rw_lock) { - rw_lock_.AcquireLockExclusive(); - } - - ~WriteLockScoped() RTC_UNLOCK_FUNCTION() { rw_lock_.ReleaseLockExclusive(); } - - private: - RWLockWrapper& rw_lock_; -}; - -} // namespace webrtc - -#endif // RTC_BASE_SYNCHRONIZATION_RW_LOCK_WRAPPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/system/assume.h b/TMessagesProj/jni/voip/webrtc/rtc_base/system/assume.h new file mode 100644 index 000000000..231c9e18a --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/system/assume.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef RTC_BASE_SYSTEM_ASSUME_H_ +#define RTC_BASE_SYSTEM_ASSUME_H_ + +// Possibly evaluate `p`, promising the compiler that the result is true; the +// compiler is allowed (but not required) to use this information when +// optimizing the code. USE WITH CAUTION! If you promise the compiler things +// that aren't true, it will build a broken binary for you. +// +// As a simple example, the compiler is allowed to transform this +// +// RTC_ASSUME(x == 4); +// return x; +// +// into this +// +// return 4; +// +// It is even allowed to propagate the assumption "backwards in time", if it can +// prove that it must have held at some earlier time. For example, the compiler +// is allowed to transform this +// +// int Add(int x, int y) { +// if (x == 17) +// y += 1; +// RTC_ASSUME(x != 17); +// return x + y; +// } +// +// into this +// +// int Add(int x, int y) { +// return x + y; +// } +// +// since if `x` isn't 17 on the third line of the function body, the test of `x +// == 17` on the first line must fail since nothing can modify the local +// variable `x` in between. +// +// The intended use is to allow the compiler to optimize better. For example, +// here we allow the compiler to omit an instruction that ensures correct +// rounding of negative arguments: +// +// int DivBy2(int x) { +// RTC_ASSUME(x >= 0); +// return x / 2; +// } +// +// and here we allow the compiler to possibly omit a null check: +// +// void Delete(int* p) { +// RTC_ASSUME(p != nullptr); +// delete p; +// } +// +// clang-format off +#if defined(__GNUC__) +#define RTC_ASSUME(p) do { if (!(p)) __builtin_unreachable(); } while (0) +#else +#define RTC_ASSUME(p) do {} while (0) +#endif +// clang-format on + +#endif // RTC_BASE_SYSTEM_ASSUME_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/thread.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/thread.cc index 2882f50da..32449020c 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/thread.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/thread.cc @@ -32,6 +32,7 @@ #include "rtc_base/atomic_ops.h" #include "rtc_base/checks.h" #include "rtc_base/deprecated/recursive_critical_section.h" +#include "rtc_base/event.h" #include "rtc_base/logging.h" #include "rtc_base/null_socket_server.h" #include "rtc_base/synchronization/sequence_checker.h" @@ -73,7 +74,7 @@ const int kSlowDispatchLoggingThreshold = 50; // 50 ms class MessageHandlerWithTask final : public MessageHandler { public: - MessageHandlerWithTask() = default; + MessageHandlerWithTask() {} void OnMessage(Message* msg) override { static_cast(msg->pdata)->Run(); @@ -164,6 +165,9 @@ void ThreadManager::RemoveFromSendGraph(Thread* thread) { void ThreadManager::RegisterSendAndCheckForCycles(Thread* source, Thread* target) { + RTC_DCHECK(source); + RTC_DCHECK(target); + CritScope cs(&crit_); std::deque all_targets({target}); // We check the pre-existing who-sends-to-who graph for any path from target @@ -890,46 +894,62 @@ void Thread::Send(const Location& posted_from, AssertBlockingIsAllowedOnCurrentThread(); - AutoThread thread; Thread* current_thread = Thread::Current(); - RTC_DCHECK(current_thread != nullptr); // AutoThread ensures this - RTC_DCHECK(current_thread->IsInvokeToThreadAllowed(this)); + #if RTC_DCHECK_IS_ON - ThreadManager::Instance()->RegisterSendAndCheckForCycles(current_thread, - this); -#endif - bool ready = false; - PostTask( - webrtc::ToQueuedTask([msg]() mutable { msg.phandler->OnMessage(&msg); }, - [this, &ready, current_thread] { - CritScope cs(&crit_); - ready = true; - current_thread->socketserver()->WakeUp(); - })); - - bool waited = false; - crit_.Enter(); - while (!ready) { - crit_.Leave(); - current_thread->socketserver()->Wait(kForever, false); - waited = true; - crit_.Enter(); + if (current_thread) { + RTC_DCHECK(current_thread->IsInvokeToThreadAllowed(this)); + ThreadManager::Instance()->RegisterSendAndCheckForCycles(current_thread, + this); } - crit_.Leave(); +#endif - // Our Wait loop above may have consumed some WakeUp events for this - // Thread, that weren't relevant to this Send. Losing these WakeUps can - // cause problems for some SocketServers. - // - // Concrete example: - // Win32SocketServer on thread A calls Send on thread B. While processing the - // message, thread B Posts a message to A. We consume the wakeup for that - // Post while waiting for the Send to complete, which means that when we exit - // this loop, we need to issue another WakeUp, or else the Posted message - // won't be processed in a timely manner. + // Perhaps down the line we can get rid of this workaround and always require + // current_thread to be valid when Send() is called. + std::unique_ptr done_event; + if (!current_thread) + done_event.reset(new rtc::Event()); - if (waited) { - current_thread->socketserver()->WakeUp(); + bool ready = false; + PostTask(webrtc::ToQueuedTask( + [&msg]() mutable { msg.phandler->OnMessage(&msg); }, + [this, &ready, current_thread, done = done_event.get()] { + if (current_thread) { + CritScope cs(&crit_); + ready = true; + current_thread->socketserver()->WakeUp(); + } else { + done->Set(); + } + })); + + if (current_thread) { + bool waited = false; + crit_.Enter(); + while (!ready) { + crit_.Leave(); + current_thread->socketserver()->Wait(kForever, false); + waited = true; + crit_.Enter(); + } + crit_.Leave(); + + // Our Wait loop above may have consumed some WakeUp events for this + // Thread, that weren't relevant to this Send. Losing these WakeUps can + // cause problems for some SocketServers. + // + // Concrete example: + // Win32SocketServer on thread A calls Send on thread B. While processing + // the message, thread B Posts a message to A. We consume the wakeup for + // that Post while waiting for the Send to complete, which means that when + // we exit this loop, we need to issue another WakeUp, or else the Posted + // message won't be processed in a timely manner. + + if (waited) { + current_thread->socketserver()->WakeUp(); + } + } else { + done_event->Wait(rtc::Event::kForever); } } diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/thread.h b/TMessagesProj/jni/voip/webrtc/rtc_base/thread.h index 353d63032..ed19e9892 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/thread.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/thread.h @@ -339,6 +339,7 @@ class RTC_LOCKABLE RTC_EXPORT Thread : public webrtc::TaskQueueBase { // will be used only for reference-based comparison, so instance can be safely // deleted. If NDEBUG is defined and DCHECK_ALWAYS_ON is undefined do nothing. void AllowInvokesToThread(Thread* thread); + // If NDEBUG is defined and DCHECK_ALWAYS_ON is undefined do nothing. void DisallowAllInvokes(); // Returns true if |target| was allowed by AllowInvokesToThread() or if no @@ -437,13 +438,6 @@ class RTC_LOCKABLE RTC_EXPORT Thread : public webrtc::TaskQueueBase { // irrevocable. Must be called on this thread. void DisallowBlockingCalls() { SetAllowBlockingCalls(false); } -#ifdef WEBRTC_ANDROID - // Sets the per-thread allow-blocking-calls flag to true, sidestepping the - // invariants upheld by DisallowBlockingCalls() and - // ScopedDisallowBlockingCalls. Must be called on this thread. - void DEPRECATED_AllowBlockingCalls() { SetAllowBlockingCalls(true); } -#endif - protected: class CurrentThreadSetter : CurrentTaskQueueSetter { public: @@ -533,6 +527,7 @@ class RTC_LOCKABLE RTC_EXPORT Thread : public webrtc::TaskQueueBase { private: class QueuedTaskHandler final : public MessageHandler { public: + QueuedTaskHandler() {} void OnMessage(Message* msg) override; }; @@ -625,7 +620,9 @@ class RTC_LOCKABLE RTC_EXPORT Thread : public webrtc::TaskQueueBase { // AutoThread automatically installs itself at construction // uninstalls at destruction, if a Thread object is // _not already_ associated with the current OS thread. - +// +// NOTE: *** This class should only be used by tests *** +// class AutoThread : public Thread { public: AutoThread(); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/time/timestamp_extrapolator.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/time/timestamp_extrapolator.cc index bf9f726c4..99445284d 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/time/timestamp_extrapolator.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/time/timestamp_extrapolator.cc @@ -15,8 +15,7 @@ namespace webrtc { TimestampExtrapolator::TimestampExtrapolator(int64_t start_ms) - : _rwLock(RWLockWrapper::CreateRWLock()), - _startMs(0), + : _startMs(0), _firstTimestamp(0), _wrapArounds(0), _prevUnwrappedTimestamp(-1), @@ -34,12 +33,7 @@ TimestampExtrapolator::TimestampExtrapolator(int64_t start_ms) Reset(start_ms); } -TimestampExtrapolator::~TimestampExtrapolator() { - delete _rwLock; -} - void TimestampExtrapolator::Reset(int64_t start_ms) { - WriteLockScoped wl(*_rwLock); _startMs = start_ms; _prevMs = _startMs; _firstTimestamp = 0; @@ -58,13 +52,10 @@ void TimestampExtrapolator::Reset(int64_t start_ms) { } void TimestampExtrapolator::Update(int64_t tMs, uint32_t ts90khz) { - _rwLock->AcquireLockExclusive(); if (tMs - _prevMs > 10e3) { // Ten seconds without a complete frame. // Reset the extrapolator - _rwLock->ReleaseLockExclusive(); Reset(tMs); - _rwLock->AcquireLockExclusive(); } else { _prevMs = tMs; } @@ -100,7 +91,6 @@ void TimestampExtrapolator::Update(int64_t tMs, uint32_t ts90khz) { if (_prevUnwrappedTimestamp >= 0 && unwrapped_ts90khz < _prevUnwrappedTimestamp) { // Drop reordered frames. - _rwLock->ReleaseLockExclusive(); return; } @@ -131,11 +121,9 @@ void TimestampExtrapolator::Update(int64_t tMs, uint32_t ts90khz) { if (_packetCount < _startUpFilterDelayInPackets) { _packetCount++; } - _rwLock->ReleaseLockExclusive(); } int64_t TimestampExtrapolator::ExtrapolateLocalTime(uint32_t timestamp90khz) { - ReadLockScoped rl(*_rwLock); int64_t localTimeMs = 0; CheckForWrapArounds(timestamp90khz); double unwrapped_ts90khz = diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/time/timestamp_extrapolator.h b/TMessagesProj/jni/voip/webrtc/rtc_base/time/timestamp_extrapolator.h index 63af57b22..b325d2cba 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/time/timestamp_extrapolator.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/time/timestamp_extrapolator.h @@ -13,14 +13,12 @@ #include -#include "rtc_base/synchronization/rw_lock_wrapper.h" - namespace webrtc { +// Not thread safe. class TimestampExtrapolator { public: explicit TimestampExtrapolator(int64_t start_ms); - ~TimestampExtrapolator(); void Update(int64_t tMs, uint32_t ts90khz); int64_t ExtrapolateLocalTime(uint32_t timestamp90khz); void Reset(int64_t start_ms); @@ -28,7 +26,6 @@ class TimestampExtrapolator { private: void CheckForWrapArounds(uint32_t ts90khz); bool DelayChangeDetection(double error); - RWLockWrapper* _rwLock; double _w[2]; double _pP[2][2]; int64_t _startMs; diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/untyped_function.h b/TMessagesProj/jni/voip/webrtc/rtc_base/untyped_function.h new file mode 100644 index 000000000..c1f59458b --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/untyped_function.h @@ -0,0 +1,324 @@ +/* + * Copyright 2020 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. + */ + +#ifndef RTC_BASE_UNTYPED_FUNCTION_H_ +#define RTC_BASE_UNTYPED_FUNCTION_H_ + +#include +#include +#include +#include +#include + +#include "rtc_base/system/assume.h" + +namespace webrtc { +namespace webrtc_function_impl { + +using FunVoid = void(); + +// Inline storage size is this many machine words. +enum : size_t { kInlineStorageWords = 4 }; + +union VoidUnion { + void* void_ptr; + FunVoid* fun_ptr; + typename std::aligned_storage::type + inline_storage; +}; + +// Returns the number of elements of the `inline_storage` array required to +// store an object of type T. +template +constexpr size_t InlineStorageSize() { + // sizeof(T) / sizeof(uintptr_t), but rounded up. + return (sizeof(T) + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); +} + +template +struct CallHelpers; +template +struct CallHelpers { + // Return type of the three helpers below. + using return_type = RetT; + // Complete function type of the three helpers below. + using function_type = RetT(VoidUnion*, ArgT...); + // Helper for calling the `void_ptr` case of VoidUnion. + template + static RetT CallVoidPtr(VoidUnion* vu, ArgT... args) { + return (*static_cast(vu->void_ptr))(std::forward(args)...); + } + // Helper for calling the `fun_ptr` case of VoidUnion. + static RetT CallFunPtr(VoidUnion* vu, ArgT... args) { + return (reinterpret_cast(vu->fun_ptr))( + std::forward(args)...); + } + // Helper for calling the `inline_storage` case of VoidUnion. + template + static RetT CallInlineStorage(VoidUnion* vu, ArgT... args) { + return (*reinterpret_cast(&vu->inline_storage))( + std::forward(args)...); + } +}; + +} // namespace webrtc_function_impl + +// A class that holds (and owns) any callable. The same function call signature +// must be provided when constructing and calling the object. +// +// The point of not having the call signature as a class template parameter is +// to have one single concrete type for all signatures; this reduces binary +// size. +class UntypedFunction final { + public: + // Callables of at most this size can be stored inline, if they are trivial. + // (Useful in tests and benchmarks; avoid using this in production code.) + enum : size_t { + kInlineStorageSize = sizeof(webrtc_function_impl::VoidUnion::inline_storage) + }; + static_assert(kInlineStorageSize == + webrtc_function_impl::kInlineStorageWords * + sizeof(uintptr_t), + ""); + + // The *UntypedFunctionArgs structs are used to transfer arguments from + // PrepareArgs() to Create(). They are trivial, but may own heap allocations, + // so make sure to pass them to Create() exactly once! + // + // The point of doing Create(PrepareArgs(foo)) instead of just Create(foo) is + // to separate the code that has to be inlined (PrepareArgs) from the code + // that can be noninlined (Create); the *UntypedFunctionArgs types are + // designed to efficiently carry the required information from one to the + // other. + template + struct TrivialUntypedFunctionArgs { + static_assert(N >= 1, ""); + static_assert(N <= webrtc_function_impl::kInlineStorageWords, ""); + // We use an uintptr_t array here instead of std::aligned_storage, because + // the former can be efficiently passed in registers when using + // TrivialUntypedFunctionArgs as a function argument. (We can't do the same + // in VoidUnion, because std::aligned_storage but not uintptr_t can be + // legally reinterpret_casted to arbitrary types. + // TrivialUntypedFunctionArgs, on the other hand, only needs to handle + // placement new and memcpy.) + alignas(std::max_align_t) uintptr_t inline_storage[N]; + webrtc_function_impl::FunVoid* call; + }; + struct NontrivialUntypedFunctionArgs { + void* void_ptr; + webrtc_function_impl::FunVoid* call; + void (*del)(webrtc_function_impl::VoidUnion*); + }; + struct FunctionPointerUntypedFunctionArgs { + webrtc_function_impl::FunVoid* fun_ptr; + webrtc_function_impl::FunVoid* call; + }; + + // Create function for lambdas and other callables that are trivial and small; + // it accepts every type of argument except those noted in its enable_if call. + template < + typename Signature, + typename F, + typename F_deref = typename std::remove_reference::type, + typename std::enable_if< + // Not for function pointers; we have another overload for that below. + !std::is_function< + typename std::remove_pointer::type>::value && + + // Not for nullptr; we have a constructor for that below. + !std::is_same::type>::value && + + // Not for UntypedFunction objects; use move construction or + // assignment. + !std::is_same::type>::value && + + // Only for trivial callables that will fit in inline storage. + std::is_trivially_move_constructible::value && + std::is_trivially_destructible::value && + sizeof(F_deref) <= kInlineStorageSize>::type* = nullptr, + size_t InlineSize = webrtc_function_impl::InlineStorageSize()> + static TrivialUntypedFunctionArgs PrepareArgs(F&& f) { + // The callable is trivial and small enough, so we just store its bytes + // in the inline storage. + TrivialUntypedFunctionArgs args; + new (&args.inline_storage) F_deref(std::forward(f)); + args.call = reinterpret_cast( + webrtc_function_impl::CallHelpers< + Signature>::template CallInlineStorage); + return args; + } + template + static UntypedFunction Create(TrivialUntypedFunctionArgs args) { + webrtc_function_impl::VoidUnion vu; + std::memcpy(&vu.inline_storage, args.inline_storage, + sizeof(args.inline_storage)); + return UntypedFunction(vu, args.call, nullptr); + } + + // Create function for lambdas and other callables that are nontrivial or + // large; it accepts every type of argument except those noted in its + // enable_if call. + template ::type, + typename std::enable_if< + // Not for function pointers; we have another overload for that + // below. + !std::is_function< + typename std::remove_pointer::type>::value && + + // Not for nullptr; we have a constructor for that below. + !std::is_same::type>::value && + + // Not for UntypedFunction objects; use move construction or + // assignment. + !std::is_same::type>::value && + + // Only for nontrivial callables, or callables that won't fit in + // inline storage. + !(std::is_trivially_move_constructible::value && + std::is_trivially_destructible::value && + sizeof(F_deref) <= kInlineStorageSize)>::type* = nullptr> + static NontrivialUntypedFunctionArgs PrepareArgs(F&& f) { + // The callable is either nontrivial or too large, so we can't keep it + // in the inline storage; use the heap instead. + NontrivialUntypedFunctionArgs args; + args.void_ptr = new F_deref(std::forward(f)); + args.call = reinterpret_cast( + webrtc_function_impl::CallHelpers::template CallVoidPtr< + F_deref>); + args.del = static_cast( + [](webrtc_function_impl::VoidUnion* vu) { + // Assuming that this pointer isn't null allows the + // compiler to eliminate a null check in the (inlined) + // delete operation. + RTC_ASSUME(vu->void_ptr != nullptr); + delete reinterpret_cast(vu->void_ptr); + }); + return args; + } + static UntypedFunction Create(NontrivialUntypedFunctionArgs args) { + webrtc_function_impl::VoidUnion vu; + vu.void_ptr = args.void_ptr; + return UntypedFunction(vu, args.call, args.del); + } + + // Create function that accepts function pointers. If the argument is null, + // the result is an empty UntypedFunction. + template + static FunctionPointerUntypedFunctionArgs PrepareArgs(Signature* f) { + FunctionPointerUntypedFunctionArgs args; + args.fun_ptr = reinterpret_cast(f); + args.call = reinterpret_cast( + webrtc_function_impl::CallHelpers::CallFunPtr); + return args; + } + static UntypedFunction Create(FunctionPointerUntypedFunctionArgs args) { + webrtc_function_impl::VoidUnion vu; + vu.fun_ptr = args.fun_ptr; + return UntypedFunction(vu, args.fun_ptr == nullptr ? nullptr : args.call, + nullptr); + } + + // Prepares arguments and creates an UntypedFunction in one go. + template + static UntypedFunction Create(F&& f) { + return Create(PrepareArgs(std::forward(f))); + } + + // Default constructor. Creates an empty UntypedFunction. + UntypedFunction() : call_(nullptr), delete_(nullptr) {} + + // Nullptr constructor and assignment. Creates an empty UntypedFunction. + UntypedFunction(std::nullptr_t) // NOLINT(runtime/explicit) + : call_(nullptr), delete_(nullptr) {} + UntypedFunction& operator=(std::nullptr_t) { + call_ = nullptr; + if (delete_) { + delete_(&f_); + delete_ = nullptr; + } + return *this; + } + + // Not copyable. + UntypedFunction(const UntypedFunction&) = delete; + UntypedFunction& operator=(const UntypedFunction&) = delete; + + // Move construction and assignment. + UntypedFunction(UntypedFunction&& other) + : f_(other.f_), call_(other.call_), delete_(other.delete_) { + other.delete_ = nullptr; + } + UntypedFunction& operator=(UntypedFunction&& other) { + if (delete_) { + delete_(&f_); + } + f_ = other.f_; + call_ = other.call_; + delete_ = other.delete_; + other.delete_ = nullptr; + return *this; + } + + ~UntypedFunction() { + if (delete_) { + delete_(&f_); + } + } + + friend void swap(UntypedFunction& a, UntypedFunction& b) { + using std::swap; + swap(a.f_, b.f_); + swap(a.call_, b.call_); + swap(a.delete_, b.delete_); + } + + // Returns true if we have a function, false if we don't (i.e., we're null). + explicit operator bool() const { return call_ != nullptr; } + + template + typename webrtc_function_impl::CallHelpers::return_type Call( + ArgT&&... args) { + return reinterpret_cast< + typename webrtc_function_impl::CallHelpers::function_type*>( + call_)(&f_, std::forward(args)...); + } + + // Returns true iff we don't need to call a destructor. This is guaranteed + // to hold for a moved-from object. + bool IsTriviallyDestructible() { return delete_ == nullptr; } + + private: + UntypedFunction(webrtc_function_impl::VoidUnion f, + webrtc_function_impl::FunVoid* call, + void (*del)(webrtc_function_impl::VoidUnion*)) + : f_(f), call_(call), delete_(del) {} + + // The callable thing, or a pointer to it. + webrtc_function_impl::VoidUnion f_; + + // Pointer to a dispatch function that knows the type of the callable thing + // that's stored in f_, and how to call it. An UntypedFunction object is empty + // (null) iff call_ is null. + webrtc_function_impl::FunVoid* call_; + + // Pointer to a function that knows how to delete the callable thing that's + // stored in f_. Null if `f_` is trivially deletable. + void (*delete_)(webrtc_function_impl::VoidUnion*); +}; + +} // namespace webrtc + +#endif // RTC_BASE_UNTYPED_FUNCTION_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/virtual_socket_server.h b/TMessagesProj/jni/voip/webrtc/rtc_base/virtual_socket_server.h index 84f8fb1bd..f33ebccd3 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/virtual_socket_server.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/virtual_socket_server.h @@ -305,7 +305,7 @@ class VirtualSocketServer : public SocketServer, public sigslot::has_slots<> { // Implements the socket interface using the virtual network. Packets are // passed as messages using the message queue of the socket server. class VirtualSocket : public AsyncSocket, - public MessageHandler, + public MessageHandlerAutoCleanup, public sigslot::has_slots<> { public: VirtualSocket(VirtualSocketServer* server, int family, int type, bool async); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/weak_ptr.h b/TMessagesProj/jni/voip/webrtc/rtc_base/weak_ptr.h index 3e63a7587..8b2ba099c 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/weak_ptr.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/weak_ptr.h @@ -241,6 +241,10 @@ class WeakPtrFactory { public: explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {} + WeakPtrFactory() = delete; + WeakPtrFactory(const WeakPtrFactory&) = delete; + WeakPtrFactory& operator=(const WeakPtrFactory&) = delete; + ~WeakPtrFactory() { ptr_ = nullptr; } WeakPtr GetWeakPtr() { @@ -263,7 +267,6 @@ class WeakPtrFactory { private: internal::WeakReferenceOwner weak_reference_owner_; T* ptr_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); }; } // namespace rtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/win/get_activation_factory.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/win/get_activation_factory.cc new file mode 100644 index 000000000..b3be9abfa --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/win/get_activation_factory.cc @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 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 "rtc_base/win/get_activation_factory.h" + +#include +#include + +namespace { + +FARPROC LoadComBaseFunction(const char* function_name) { + static HMODULE const handle = + ::LoadLibraryExW(L"combase.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + return handle ? ::GetProcAddress(handle, function_name) : nullptr; +} + +decltype(&::RoGetActivationFactory) GetRoGetActivationFactoryFunction() { + static decltype(&::RoGetActivationFactory) const function = + reinterpret_cast( + LoadComBaseFunction("RoGetActivationFactory")); + return function; +} + +} // namespace + +namespace webrtc { + +bool ResolveCoreWinRTDelayload() { + return GetRoGetActivationFactoryFunction() && + ResolveCoreWinRTStringDelayload(); +} + +HRESULT RoGetActivationFactoryProxy(HSTRING class_id, + const IID& iid, + void** out_factory) { + auto get_factory_func = GetRoGetActivationFactoryFunction(); + if (!get_factory_func) + return E_FAIL; + return get_factory_func(class_id, iid, out_factory); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/win/get_activation_factory.h b/TMessagesProj/jni/voip/webrtc/rtc_base/win/get_activation_factory.h new file mode 100644 index 000000000..801f39d31 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/win/get_activation_factory.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef RTC_BASE_WIN_GET_ACTIVATION_FACTORY_H_ +#define RTC_BASE_WIN_GET_ACTIVATION_FACTORY_H_ + +#include + +#include "rtc_base/win/hstring.h" + +namespace webrtc { + +// Provides access to Core WinRT functions which may not be available on +// Windows 7. Loads functions dynamically at runtime to prevent library +// dependencies. + +// Callers must check the return value of ResolveCoreWinRTDelayLoad() before +// using these functions. + +bool ResolveCoreWinRTDelayload(); + +HRESULT RoGetActivationFactoryProxy(HSTRING class_id, + const IID& iid, + void** out_factory); + +// Retrieves an activation factory for the type specified. +template +HRESULT GetActivationFactory(InterfaceType** factory) { + HSTRING class_id_hstring; + HRESULT hr = CreateHstring(runtime_class_id, wcslen(runtime_class_id), + &class_id_hstring); + if (FAILED(hr)) + return hr; + + hr = RoGetActivationFactoryProxy(class_id_hstring, IID_PPV_ARGS(factory)); + if (FAILED(hr)) + return hr; + + return DeleteHstring(class_id_hstring); +} + +} // namespace webrtc + +#endif // RTC_BASE_WIN_GET_ACTIVATION_FACTORY_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/win/hstring.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/win/hstring.cc new file mode 100644 index 000000000..5a362a97c --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/win/hstring.cc @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 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 "rtc_base/win/hstring.h" + +#include +#include + +namespace { + +FARPROC LoadComBaseFunction(const char* function_name) { + static HMODULE const handle = + ::LoadLibraryExW(L"combase.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + return handle ? ::GetProcAddress(handle, function_name) : nullptr; +} + +decltype(&::WindowsCreateString) GetWindowsCreateString() { + static decltype(&::WindowsCreateString) const function = + reinterpret_cast( + LoadComBaseFunction("WindowsCreateString")); + return function; +} + +decltype(&::WindowsDeleteString) GetWindowsDeleteString() { + static decltype(&::WindowsDeleteString) const function = + reinterpret_cast( + LoadComBaseFunction("WindowsDeleteString")); + return function; +} + +} // namespace + +namespace webrtc { + +bool ResolveCoreWinRTStringDelayload() { + return GetWindowsDeleteString() && GetWindowsCreateString(); +} + +HRESULT CreateHstring(const wchar_t* src, uint32_t len, HSTRING* out_hstr) { + decltype(&::WindowsCreateString) create_string_func = + GetWindowsCreateString(); + if (!create_string_func) + return E_FAIL; + return create_string_func(src, len, out_hstr); +} + +HRESULT DeleteHstring(HSTRING hstr) { + decltype(&::WindowsDeleteString) delete_string_func = + GetWindowsDeleteString(); + if (!delete_string_func) + return E_FAIL; + return delete_string_func(hstr); +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/win/hstring.h b/TMessagesProj/jni/voip/webrtc/rtc_base/win/hstring.h new file mode 100644 index 000000000..8fb119a9e --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/win/hstring.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef RTC_BASE_WIN_HSTRING_H_ +#define RTC_BASE_WIN_HSTRING_H_ + +#include +#include +#include + +namespace webrtc { + +// Callers must check the return value of ResolveCoreWinRTStringDelayLoad() +// before using these functions. +bool ResolveCoreWinRTStringDelayload(); + +HRESULT CreateHstring(const wchar_t* src, uint32_t len, HSTRING* out_hstr); + +HRESULT DeleteHstring(HSTRING hstr); + +} // namespace webrtc + +#endif // RTC_BASE_WIN_HSTRING_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/win/scoped_com_initializer.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/win/scoped_com_initializer.cc new file mode 100644 index 000000000..b83ad32a6 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/win/scoped_com_initializer.cc @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 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 "rtc_base/win/scoped_com_initializer.h" + +namespace webrtc { + +ScopedCOMInitializer::ScopedCOMInitializer() { + RTC_DLOG(INFO) << "Single-Threaded Apartment (STA) COM thread"; + Initialize(COINIT_APARTMENTTHREADED); +} + +// Constructor for MTA initialization. +ScopedCOMInitializer::ScopedCOMInitializer(SelectMTA mta) { + RTC_DLOG(INFO) << "Multi-Threaded Apartment (MTA) COM thread"; + Initialize(COINIT_MULTITHREADED); +} + +ScopedCOMInitializer::~ScopedCOMInitializer() { + if (Succeeded()) { + CoUninitialize(); + } +} + +void ScopedCOMInitializer::Initialize(COINIT init) { + // Initializes the COM library for use by the calling thread, sets the + // thread's concurrency model, and creates a new apartment for the thread + // if one is required. CoInitializeEx must be called at least once, and is + // usually called only once, for each thread that uses the COM library. + hr_ = CoInitializeEx(NULL, init); + RTC_CHECK_NE(RPC_E_CHANGED_MODE, hr_) + << "Invalid COM thread model change (MTA->STA)"; + // Multiple calls to CoInitializeEx by the same thread are allowed as long + // as they pass the same concurrency flag, but subsequent valid calls + // return S_FALSE. To close the COM library gracefully on a thread, each + // successful call to CoInitializeEx, including any call that returns + // S_FALSE, must be balanced by a corresponding call to CoUninitialize. + if (hr_ == S_OK) { + RTC_DLOG(INFO) + << "The COM library was initialized successfully on this thread"; + } else if (hr_ == S_FALSE) { + RTC_DLOG(WARNING) + << "The COM library is already initialized on this thread"; + } +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/win/scoped_com_initializer.h b/TMessagesProj/jni/voip/webrtc/rtc_base/win/scoped_com_initializer.h new file mode 100644 index 000000000..918812fc7 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/win/scoped_com_initializer.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef RTC_BASE_WIN_SCOPED_COM_INITIALIZER_H_ +#define RTC_BASE_WIN_SCOPED_COM_INITIALIZER_H_ + +#include + +#include "rtc_base/logging.h" + +namespace webrtc { + +// Initializes COM in the constructor (STA or MTA), and uninitializes COM in the +// destructor. Taken from base::win::ScopedCOMInitializer. +// +// WARNING: This should only be used once per thread, ideally scoped to a +// similar lifetime as the thread itself. You should not be using this in +// random utility functions that make COM calls; instead ensure that these +// functions are running on a COM-supporting thread! +// See https://msdn.microsoft.com/en-us/library/ms809971.aspx for details. +class ScopedCOMInitializer { + public: + // Enum value provided to initialize the thread as an MTA instead of STA. + // There are two types of apartments, Single Threaded Apartments (STAs) + // and Multi Threaded Apartments (MTAs). Within a given process there can + // be multiple STA’s but there is only one MTA. STA is typically used by + // "GUI applications" and MTA by "worker threads" with no UI message loop. + enum SelectMTA { kMTA }; + + // Constructor for STA initialization. + ScopedCOMInitializer(); + + // Constructor for MTA initialization. + explicit ScopedCOMInitializer(SelectMTA mta); + + ~ScopedCOMInitializer(); + + ScopedCOMInitializer(const ScopedCOMInitializer&) = delete; + ScopedCOMInitializer& operator=(const ScopedCOMInitializer&) = delete; + + bool Succeeded() { return SUCCEEDED(hr_); } + + private: + void Initialize(COINIT init); + + HRESULT hr_; +}; + +} // namespace webrtc + +#endif // RTC_BASE_WIN_SCOPED_COM_INITIALIZER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/win/windows_version.cc b/TMessagesProj/jni/voip/webrtc/rtc_base/win/windows_version.cc index 2e6c1577c..42148adee 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/win/windows_version.cc +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/win/windows_version.cc @@ -203,8 +203,12 @@ Version MajorMinorBuildToVersion(int major, int minor, int build) { return VERSION_WIN10_RS2; } else if (build < 17134) { return VERSION_WIN10_RS3; - } else { + } else if (build < 17763) { return VERSION_WIN10_RS4; + } else if (build < 18362) { + return VERSION_WIN10_RS5; + } else { + return VERSION_WIN10_19H1; } } else if (major > 6) { RTC_NOTREACHED(); diff --git a/TMessagesProj/jni/voip/webrtc/rtc_base/win/windows_version.h b/TMessagesProj/jni/voip/webrtc/rtc_base/win/windows_version.h index 1ad319e4c..33449e2b3 100644 --- a/TMessagesProj/jni/voip/webrtc/rtc_base/win/windows_version.h +++ b/TMessagesProj/jni/voip/webrtc/rtc_base/win/windows_version.h @@ -43,6 +43,8 @@ enum Version { VERSION_WIN10_RS2 = 10, // Redstone 2: Version 1703, Build 15063. VERSION_WIN10_RS3 = 11, // Redstone 3: Version 1709, Build 16299. VERSION_WIN10_RS4 = 12, // Redstone 4: Version 1803, Build 17134. + VERSION_WIN10_RS5 = 13, // Redstone 5: Version 1809, Build 17763. + VERSION_WIN10_19H1 = 14, // 19H1: Version 1903, Build 18362. // On edit, update tools\metrics\histograms\enums.xml "WindowsVersion" and // "GpuBlacklistFeatureTestResultsWindows2". VERSION_WIN_LAST, // Indicates error condition. diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/generated_peerconnection_jni/CandidatePairChangeEvent_jni.h b/TMessagesProj/jni/voip/webrtc/sdk/android/generated_peerconnection_jni/CandidatePairChangeEvent_jni.h index 63599ca54..e9bc7b40b 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/generated_peerconnection_jni/CandidatePairChangeEvent_jni.h +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/generated_peerconnection_jni/CandidatePairChangeEvent_jni.h @@ -44,7 +44,8 @@ static base::android::ScopedJavaLocalRef Java_CandidatePairChangeEvent_ env, const base::android::JavaRef& local, const base::android::JavaRef& remote, JniIntWrapper lastDataReceivedMs, - const base::android::JavaRef& reason) { + const base::android::JavaRef& reason, + JniIntWrapper estimatedDisconnectedTimeMs) { jclass clazz = org_webrtc_CandidatePairChangeEvent_clazz(env); CHECK_CLAZZ(env, clazz, org_webrtc_CandidatePairChangeEvent_clazz(env), NULL); @@ -55,13 +56,13 @@ static base::android::ScopedJavaLocalRef Java_CandidatePairChangeEvent_ env, clazz, "", - "(Lorg/webrtc/IceCandidate;Lorg/webrtc/IceCandidate;ILjava/lang/String;)V", + "(Lorg/webrtc/IceCandidate;Lorg/webrtc/IceCandidate;ILjava/lang/String;I)V", &g_org_webrtc_CandidatePairChangeEvent_Constructor); jobject ret = env->NewObject(clazz, call_context.base.method_id, local.obj(), remote.obj(), as_jint(lastDataReceivedMs), - reason.obj()); + reason.obj(), as_jint(estimatedDisconnectedTimeMs)); return base::android::ScopedJavaLocalRef(env, ret); } diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/generated_peerconnection_jni/RtpTransceiver_jni.h b/TMessagesProj/jni/voip/webrtc/sdk/android/generated_peerconnection_jni/RtpTransceiver_jni.h index bd1b2e604..ca874d549 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/generated_peerconnection_jni/RtpTransceiver_jni.h +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/generated_peerconnection_jni/RtpTransceiver_jni.h @@ -157,10 +157,10 @@ JNI_GENERATOR_EXPORT void Java_org_webrtc_RtpTransceiver_nativeStopStandard( return JNI_RtpTransceiver_StopStandard(env, rtpTransceiver); } -static void JNI_RtpTransceiver_SetDirection(JNIEnv* env, jlong rtpTransceiver, +static jboolean JNI_RtpTransceiver_SetDirection(JNIEnv* env, jlong rtpTransceiver, const base::android::JavaParamRef& rtpTransceiverDirection); -JNI_GENERATOR_EXPORT void Java_org_webrtc_RtpTransceiver_nativeSetDirection( +JNI_GENERATOR_EXPORT jboolean Java_org_webrtc_RtpTransceiver_nativeSetDirection( JNIEnv* env, jclass jcaller, jlong rtpTransceiver, diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/generated_video_jni/EncodedImage_jni.h b/TMessagesProj/jni/voip/webrtc/sdk/android/generated_video_jni/EncodedImage_jni.h index da8a56926..738313039 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/generated_video_jni/EncodedImage_jni.h +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/generated_video_jni/EncodedImage_jni.h @@ -83,7 +83,6 @@ static base::android::ScopedJavaLocalRef Java_EncodedImage_Constructor( jlong captureTimeNs, const base::android::JavaRef& frameType, JniIntWrapper rotation, - jboolean completeFrame, const base::android::JavaRef& qp) { jclass clazz = org_webrtc_EncodedImage_clazz(env); CHECK_CLAZZ(env, clazz, @@ -95,14 +94,13 @@ static base::android::ScopedJavaLocalRef Java_EncodedImage_Constructor( env, clazz, "", -"(Ljava/nio/ByteBuffer;Ljava/lang/Runnable;IIJLorg/webrtc/EncodedImage$FrameType;IZLjava/lang/Integer;)V", +"(Ljava/nio/ByteBuffer;Ljava/lang/Runnable;IIJLorg/webrtc/EncodedImage$FrameType;ILjava/lang/Integer;)V", &g_org_webrtc_EncodedImage_Constructor); jobject ret = env->NewObject(clazz, call_context.base.method_id, buffer.obj(), releaseCallback.obj(), as_jint(encodedWidth), - as_jint(encodedHeight), captureTimeNs, frameType.obj(), as_jint(rotation), - completeFrame, qp.obj()); + as_jint(encodedHeight), captureTimeNs, frameType.obj(), as_jint(rotation), qp.obj()); return base::android::ScopedJavaLocalRef(env, ret); } @@ -237,28 +235,6 @@ static jint Java_EncodedImage_getRotation(JNIEnv* env, const base::android::Java return ret; } -static std::atomic g_org_webrtc_EncodedImage_getCompleteFrame(nullptr); -static jboolean Java_EncodedImage_getCompleteFrame(JNIEnv* env, const - base::android::JavaRef& obj) { - jclass clazz = org_webrtc_EncodedImage_clazz(env); - CHECK_CLAZZ(env, obj.obj(), - org_webrtc_EncodedImage_clazz(env), false); - - jni_generator::JniJavaCallContextChecked call_context; - call_context.Init< - base::android::MethodID::TYPE_INSTANCE>( - env, - clazz, - "getCompleteFrame", - "()Z", - &g_org_webrtc_EncodedImage_getCompleteFrame); - - jboolean ret = - env->CallBooleanMethod(obj.obj(), - call_context.base.method_id); - return ret; -} - static std::atomic g_org_webrtc_EncodedImage_getQp(nullptr); static base::android::ScopedJavaLocalRef Java_EncodedImage_getQp(JNIEnv* env, const base::android::JavaRef& obj) { diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/native_api/base/network_monitor.h b/TMessagesProj/jni/voip/webrtc/sdk/android/native_api/base/network_monitor.h deleted file mode 100644 index fc7d3e54c..000000000 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/native_api/base/network_monitor.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 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. - */ - -#ifndef SDK_ANDROID_NATIVE_API_BASE_NETWORK_MONITOR_H_ -#define SDK_ANDROID_NATIVE_API_BASE_NETWORK_MONITOR_H_ - -// TODO(deadbeef): Remove this forwarding header once clients switch to the -// new one. -#include "sdk/android/native_api/network_monitor/network_monitor.h" - -#endif // SDK_ANDROID_NATIVE_API_BASE_NETWORK_MONITOR_H_ diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/DEPS b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/DEPS deleted file mode 100644 index ae33fa683..000000000 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/DEPS +++ /dev/null @@ -1,15 +0,0 @@ -include_rules = [ - "+third_party/libyuv", - "+call/callfactoryinterface.h", - "+common_video", - "+logging/rtc_event_log/rtc_event_log_factory.h", - "+media/base", - "+media/engine", - "+modules/audio_device/include/audio_device.h", - "+modules/audio_processing/include/audio_processing.h", - "+modules/include", - "+modules/utility/include/jvm_android.h", - "+modules/video_coding", - "+pc", - "+system_wrappers/include", -] diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_network_monitor.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_network_monitor.cc index e41fd035d..434e6d3af 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_network_monitor.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_network_monitor.cc @@ -21,6 +21,7 @@ #include "rtc_base/ip_address.h" #include "rtc_base/logging.h" #include "rtc_base/strings/string_builder.h" +#include "rtc_base/synchronization/sequence_checker.h" #include "sdk/android/generated_base_jni/NetworkChangeDetector_jni.h" #include "sdk/android/generated_base_jni/NetworkMonitor_jni.h" #include "sdk/android/native_api/jni/java_types.h" @@ -30,6 +31,37 @@ namespace webrtc { namespace jni { +namespace { + +const char* NetworkTypeToString(NetworkType type) { + switch (type) { + case NETWORK_UNKNOWN: + return "UNKNOWN"; + case NETWORK_ETHERNET: + return "ETHERNET"; + case NETWORK_WIFI: + return "WIFI"; + case NETWORK_5G: + return "5G"; + case NETWORK_4G: + return "4G"; + case NETWORK_3G: + return "3G"; + case NETWORK_2G: + return "2G"; + case NETWORK_UNKNOWN_CELLULAR: + return "UNKNOWN_CELLULAR"; + case NETWORK_BLUETOOTH: + return "BLUETOOTH"; + case NETWORK_VPN: + return "VPN"; + case NETWORK_NONE: + return "NONE"; + } +} + +} // namespace + enum AndroidSdkVersion { SDK_VERSION_LOLLIPOP = 21, SDK_VERSION_MARSHMALLOW = 23 @@ -196,12 +228,13 @@ AndroidNetworkMonitor::AndroidNetworkMonitor( const JavaRef& j_application_context) : android_sdk_int_(Java_NetworkMonitor_androidSdkInt(env)), j_application_context_(env, j_application_context), - j_network_monitor_(env, Java_NetworkMonitor_getInstance(env)) {} + j_network_monitor_(env, Java_NetworkMonitor_getInstance(env)), + network_thread_(rtc::Thread::Current()) {} AndroidNetworkMonitor::~AndroidNetworkMonitor() = default; void AndroidNetworkMonitor::Start() { - RTC_CHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread_); if (started_) { return; } @@ -215,7 +248,7 @@ void AndroidNetworkMonitor::Start() { // This is kind of magic behavior, but doing this allows the SocketServer to // use this as a NetworkBinder to bind sockets on a particular network when // it creates sockets. - worker_thread()->socketserver()->set_network_binder(this); + network_thread_->socketserver()->set_network_binder(this); JNIEnv* env = AttachCurrentThreadIfNeeded(); Java_NetworkMonitor_startMonitoring( @@ -223,7 +256,7 @@ void AndroidNetworkMonitor::Start() { } void AndroidNetworkMonitor::Stop() { - RTC_CHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread_); if (!started_) { return; } @@ -232,8 +265,8 @@ void AndroidNetworkMonitor::Stop() { // Once the network monitor stops, it will clear all network information and // it won't find the network handle to bind anyway. - if (worker_thread()->socketserver()->network_binder() == this) { - worker_thread()->socketserver()->set_network_binder(nullptr); + if (network_thread_->socketserver()->network_binder() == this) { + network_thread_->socketserver()->set_network_binder(nullptr); } JNIEnv* env = AttachCurrentThreadIfNeeded(); @@ -249,7 +282,7 @@ void AndroidNetworkMonitor::Stop() { rtc::NetworkBindingResult AndroidNetworkMonitor::BindSocketToNetwork( int socket_fd, const rtc::IPAddress& address) { - RTC_CHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread_); // Android prior to Lollipop didn't have support for binding sockets to // networks. This may also occur if there is no connectivity manager @@ -346,17 +379,9 @@ rtc::NetworkBindingResult AndroidNetworkMonitor::BindSocketToNetwork( return rtc::NetworkBindingResult::FAILURE; } -void AndroidNetworkMonitor::OnNetworkConnected( - const NetworkInformation& network_info) { - worker_thread()->Invoke( - RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkConnected_w, - this, network_info)); - // Fire SignalNetworksChanged to update the list of networks. - OnNetworksChanged(); -} - -void AndroidNetworkMonitor::OnNetworkConnected_w( +void AndroidNetworkMonitor::OnNetworkConnected_n( const NetworkInformation& network_info) { + RTC_DCHECK_RUN_ON(network_thread_); RTC_LOG(LS_INFO) << "Network connected: " << network_info.ToString(); adapter_type_by_name_[network_info.interface_name] = AdapterTypeFromNetworkType(network_info.type, surface_cellular_types_); @@ -369,11 +394,13 @@ void AndroidNetworkMonitor::OnNetworkConnected_w( for (const rtc::IPAddress& address : network_info.ip_addresses) { network_handle_by_address_[address] = network_info.handle; } + SignalNetworksChanged(); } absl::optional AndroidNetworkMonitor::FindNetworkHandleFromAddress( const rtc::IPAddress& ip_address) const { + RTC_DCHECK_RUN_ON(network_thread_); RTC_LOG(LS_INFO) << "Find network handle."; if (find_network_handle_without_ipv6_temporary_part_) { for (auto const& iter : network_info_by_handle_) { @@ -396,14 +423,9 @@ AndroidNetworkMonitor::FindNetworkHandleFromAddress( } } -void AndroidNetworkMonitor::OnNetworkDisconnected(NetworkHandle handle) { +void AndroidNetworkMonitor::OnNetworkDisconnected_n(NetworkHandle handle) { + RTC_DCHECK_RUN_ON(network_thread_); RTC_LOG(LS_INFO) << "Network disconnected for handle " << handle; - worker_thread()->Invoke( - RTC_FROM_HERE, - rtc::Bind(&AndroidNetworkMonitor::OnNetworkDisconnected_w, this, handle)); -} - -void AndroidNetworkMonitor::OnNetworkDisconnected_w(NetworkHandle handle) { auto iter = network_info_by_handle_.find(handle); if (iter != network_info_by_handle_.end()) { for (const rtc::IPAddress& address : iter->second.ip_addresses) { @@ -413,31 +435,33 @@ void AndroidNetworkMonitor::OnNetworkDisconnected_w(NetworkHandle handle) { } } -void AndroidNetworkMonitor::OnNetworkPreference( +void AndroidNetworkMonitor::OnNetworkPreference_n( NetworkType type, rtc::NetworkPreference preference) { - worker_thread()->Invoke(RTC_FROM_HERE, [&] { - auto adapter_type = - AdapterTypeFromNetworkType(type, surface_cellular_types_); - network_preference_by_adapter_type_[adapter_type] = preference; - }); - OnNetworksChanged(); + RTC_DCHECK_RUN_ON(network_thread_); + RTC_LOG(LS_INFO) << "Android network monitor preference for " + << NetworkTypeToString(type) << " changed to " + << rtc::NetworkPreferenceToString(preference); + auto adapter_type = AdapterTypeFromNetworkType(type, surface_cellular_types_); + network_preference_by_adapter_type_[adapter_type] = preference; + SignalNetworksChanged(); } void AndroidNetworkMonitor::SetNetworkInfos( const std::vector& network_infos) { - RTC_CHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(network_thread_); network_handle_by_address_.clear(); network_info_by_handle_.clear(); RTC_LOG(LS_INFO) << "Android network monitor found " << network_infos.size() << " networks"; for (const NetworkInformation& network : network_infos) { - OnNetworkConnected_w(network); + OnNetworkConnected_n(network); } } rtc::AdapterType AndroidNetworkMonitor::GetAdapterType( const std::string& if_name) { + RTC_DCHECK_RUN_ON(network_thread_); auto iter = adapter_type_by_name_.find(if_name); rtc::AdapterType type = (iter == adapter_type_by_name_.end()) ? rtc::ADAPTER_TYPE_UNKNOWN @@ -450,6 +474,7 @@ rtc::AdapterType AndroidNetworkMonitor::GetAdapterType( rtc::AdapterType AndroidNetworkMonitor::GetVpnUnderlyingAdapterType( const std::string& if_name) { + RTC_DCHECK_RUN_ON(network_thread_); auto iter = vpn_underlying_adapter_type_by_name_.find(if_name); rtc::AdapterType type = (iter == vpn_underlying_adapter_type_by_name_.end()) ? rtc::ADAPTER_TYPE_UNKNOWN @@ -459,6 +484,7 @@ rtc::AdapterType AndroidNetworkMonitor::GetVpnUnderlyingAdapterType( rtc::NetworkPreference AndroidNetworkMonitor::GetNetworkPreference( const std::string& if_name) { + RTC_DCHECK_RUN_ON(network_thread_); auto iter = adapter_type_by_name_.find(if_name); if (iter == adapter_type_by_name_.end()) { return rtc::NetworkPreference::NEUTRAL; @@ -499,7 +525,11 @@ AndroidNetworkMonitorFactory::CreateNetworkMonitor() { void AndroidNetworkMonitor::NotifyConnectionTypeChanged( JNIEnv* env, const JavaRef& j_caller) { - OnNetworksChanged(); + invoker_.AsyncInvoke(RTC_FROM_HERE, network_thread_, [this] { + RTC_LOG(LS_INFO) + << "Android network monitor detected connection type change."; + SignalNetworksChanged(); + }); } void AndroidNetworkMonitor::NotifyOfActiveNetworkList( @@ -518,14 +548,19 @@ void AndroidNetworkMonitor::NotifyOfNetworkConnect( const JavaRef& j_network_info) { NetworkInformation network_info = GetNetworkInformationFromJava(env, j_network_info); - OnNetworkConnected(network_info); + network_thread_->Invoke( + RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkConnected_n, + this, network_info)); } void AndroidNetworkMonitor::NotifyOfNetworkDisconnect( JNIEnv* env, const JavaRef& j_caller, jlong network_handle) { - OnNetworkDisconnected(static_cast(network_handle)); + network_thread_->Invoke( + RTC_FROM_HERE, + rtc::Bind(&AndroidNetworkMonitor::OnNetworkDisconnected_n, this, + static_cast(network_handle))); } void AndroidNetworkMonitor::NotifyOfNetworkPreference( @@ -536,7 +571,10 @@ void AndroidNetworkMonitor::NotifyOfNetworkPreference( NetworkType type = GetNetworkTypeFromJava(env, j_connection_type); rtc::NetworkPreference preference = static_cast(jpreference); - OnNetworkPreference(type, preference); + + network_thread_->Invoke( + RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkPreference_n, + this, type, preference)); } } // namespace jni diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_network_monitor.h b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_network_monitor.h index d1008f266..eff212254 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_network_monitor.h +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_network_monitor.h @@ -17,9 +17,11 @@ #include #include "absl/types/optional.h" +#include "rtc_base/async_invoker.h" #include "rtc_base/network_monitor.h" #include "rtc_base/network_monitor_factory.h" -#include "rtc_base/thread_checker.h" +#include "rtc_base/thread.h" +#include "rtc_base/thread_annotations.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { @@ -61,7 +63,7 @@ struct NetworkInformation { std::string ToString() const; }; -class AndroidNetworkMonitor : public rtc::NetworkMonitorBase, +class AndroidNetworkMonitor : public rtc::NetworkMonitorInterface, public rtc::NetworkBinderInterface { public: AndroidNetworkMonitor(JNIEnv* env, @@ -83,10 +85,6 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase, rtc::NetworkPreference GetNetworkPreference( const std::string& if_name) override; - void OnNetworkConnected(const NetworkInformation& network_info); - void OnNetworkDisconnected(NetworkHandle network_handle); - void OnNetworkPreference(NetworkType type, rtc::NetworkPreference preference); - // Always expected to be called on the network thread. void SetNetworkInfos(const std::vector& network_infos); @@ -111,22 +109,30 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase, const rtc::IPAddress& address) const; private: - void OnNetworkConnected_w(const NetworkInformation& network_info); - void OnNetworkDisconnected_w(NetworkHandle network_handle); + void OnNetworkConnected_n(const NetworkInformation& network_info); + void OnNetworkDisconnected_n(NetworkHandle network_handle); + void OnNetworkPreference_n(NetworkType type, + rtc::NetworkPreference preference); const int android_sdk_int_; ScopedJavaGlobalRef j_application_context_; ScopedJavaGlobalRef j_network_monitor_; - rtc::ThreadChecker thread_checker_; - bool started_ = false; - std::map adapter_type_by_name_; - std::map vpn_underlying_adapter_type_by_name_; - std::map network_handle_by_address_; - std::map network_info_by_handle_; + rtc::Thread* network_thread_; + bool started_ RTC_GUARDED_BY(network_thread_) = false; + std::map adapter_type_by_name_ + RTC_GUARDED_BY(network_thread_); + std::map vpn_underlying_adapter_type_by_name_ + RTC_GUARDED_BY(network_thread_); + std::map network_handle_by_address_ + RTC_GUARDED_BY(network_thread_); + std::map network_info_by_handle_ + RTC_GUARDED_BY(network_thread_); std::map - network_preference_by_adapter_type_; - bool find_network_handle_without_ipv6_temporary_part_; - bool surface_cellular_types_; + network_preference_by_adapter_type_ RTC_GUARDED_BY(network_thread_); + bool find_network_handle_without_ipv6_temporary_part_ + RTC_GUARDED_BY(network_thread_) = false; + bool surface_cellular_types_ RTC_GUARDED_BY(network_thread_) = false; + rtc::AsyncInvoker invoker_; }; class AndroidNetworkMonitorFactory : public rtc::NetworkMonitorFactory { diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_video_track_source.h b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_video_track_source.h index 378d380a1..eeac48f1e 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_video_track_source.h +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/android_video_track_source.h @@ -13,10 +13,8 @@ #include -#include "common_video/include/i420_buffer_pool.h" #include "common_video/libyuv/include/webrtc_libyuv.h" #include "media/base/adapted_video_track_source.h" -#include "rtc_base/async_invoker.h" #include "rtc_base/checks.h" #include "rtc_base/thread.h" #include "rtc_base/timestamp_aligner.h" diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/DEPS b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/DEPS deleted file mode 100644 index 9a3adee68..000000000 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/DEPS +++ /dev/null @@ -1,4 +0,0 @@ -include_rules = [ - "+base/android/jni_android.h", - "+modules/audio_device", -] diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/aaudio_recorder.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/aaudio_recorder.cc index 65bef4b1b..34b14f450 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/aaudio_recorder.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/aaudio_recorder.cc @@ -18,8 +18,6 @@ #include "rtc_base/logging.h" #include "rtc_base/time_utils.h" -#include "system_wrappers/include/sleep.h" - namespace webrtc { namespace jni { diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/audio_device_module.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/audio_device_module.cc index d77488ff4..eb5d93fa2 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/audio_device_module.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/audio_device/audio_device_module.cc @@ -151,15 +151,13 @@ class AndroidAudioDeviceModule : public AudioDeviceModule { int32_t PlayoutDeviceName(uint16_t index, char name[kAdmMaxDeviceNameSize], char guid[kAdmMaxGuidSize]) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t RecordingDeviceName(uint16_t index, char name[kAdmMaxDeviceNameSize], char guid[kAdmMaxGuidSize]) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SetPlayoutDevice(uint16_t index) override { @@ -171,8 +169,7 @@ class AndroidAudioDeviceModule : public AudioDeviceModule { int32_t SetPlayoutDevice( AudioDeviceModule::WindowsDeviceType device) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SetRecordingDevice(uint16_t index) override { @@ -184,8 +181,7 @@ class AndroidAudioDeviceModule : public AudioDeviceModule { int32_t SetRecordingDevice( AudioDeviceModule::WindowsDeviceType device) override { - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t PlayoutIsAvailable(bool* available) override { @@ -396,62 +392,52 @@ class AndroidAudioDeviceModule : public AudioDeviceModule { int32_t SetMicrophoneVolume(uint32_t volume) override { RTC_LOG(INFO) << __FUNCTION__ << "(" << volume << ")"; - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t MicrophoneVolume(uint32_t* volume) const override { RTC_LOG(INFO) << __FUNCTION__; - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override { RTC_LOG(INFO) << __FUNCTION__; - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t MinMicrophoneVolume(uint32_t* minVolume) const override { RTC_LOG(INFO) << __FUNCTION__; - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SpeakerMuteIsAvailable(bool* available) override { RTC_LOG(INFO) << __FUNCTION__; - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SetSpeakerMute(bool enable) override { RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")"; - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SpeakerMute(bool* enabled) const override { RTC_LOG(INFO) << __FUNCTION__; - FATAL() << "Should never be called"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t MicrophoneMuteIsAvailable(bool* available) override { RTC_LOG(INFO) << __FUNCTION__; - FATAL() << "Not implemented"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t SetMicrophoneMute(bool enable) override { RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")"; - FATAL() << "Not implemented"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t MicrophoneMute(bool* enabled) const override { RTC_LOG(INFO) << __FUNCTION__; - FATAL() << "Not implemented"; - return -1; + RTC_CHECK_NOTREACHED(); } int32_t StereoPlayoutIsAvailable(bool* available) const override { @@ -569,8 +555,7 @@ class AndroidAudioDeviceModule : public AudioDeviceModule { int32_t EnableBuiltInAGC(bool enable) override { RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")"; - FATAL() << "HW AGC is not available"; - return -1; + RTC_CHECK_NOTREACHED(); } // TODO(henrika): add implementation for OpenSL ES based audio as well. diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/encoded_image.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/encoded_image.cc index e13653ca3..839f6a8f6 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/encoded_image.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/encoded_image.cc @@ -70,7 +70,7 @@ ScopedJavaLocalRef NativeToJavaEncodedImage( static_cast(image._encodedWidth), static_cast(image._encodedHeight), image.capture_time_ms_ * rtc::kNumNanosecsPerMillisec, frame_type, - static_cast(image.rotation_), image._completeFrame, qp); + static_cast(image.rotation_), qp); } ScopedJavaLocalRef NativeToJavaFrameTypeArray( @@ -98,8 +98,6 @@ EncodedImage JavaToNativeEncodedImage(JNIEnv* env, Java_EncodedImage_getEncodedHeight(env, j_encoded_image); frame.rotation_ = (VideoRotation)Java_EncodedImage_getRotation(env, j_encoded_image); - frame._completeFrame = - Java_EncodedImage_getCompleteFrame(env, j_encoded_image); frame.qp_ = JavaToNativeOptionalInt( env, Java_EncodedImage_getQp(env, j_encoded_image)) diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/pc/peer_connection.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/pc/peer_connection.cc index 116533364..6706782e3 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/pc/peer_connection.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/pc/peer_connection.cc @@ -128,7 +128,8 @@ ScopedJavaLocalRef NativeToJavaCandidatePairChange( env, NativeToJavaCandidate(env, selected_pair.local_candidate()), NativeToJavaCandidate(env, selected_pair.remote_candidate()), static_cast(event.last_data_received_ms), - NativeToJavaString(env, event.reason)); + NativeToJavaString(env, event.reason), + static_cast(event.estimated_disconnected_time_ms)); } } // namespace diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/pc/rtp_transceiver.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/pc/rtp_transceiver.cc index a0b3c20fd..1d468461f 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/pc/rtp_transceiver.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/pc/rtp_transceiver.cc @@ -151,18 +151,25 @@ void JNI_RtpTransceiver_StopStandard(JNIEnv* jni, ->StopStandard(); } -void JNI_RtpTransceiver_SetDirection( +jboolean JNI_RtpTransceiver_SetDirection( JNIEnv* jni, jlong j_rtp_transceiver_pointer, const base::android::JavaParamRef& j_rtp_transceiver_direction) { if (IsNull(jni, j_rtp_transceiver_direction)) { - return; + return false; } RtpTransceiverDirection direction = static_cast( Java_RtpTransceiverDirection_getNativeIndex(jni, j_rtp_transceiver_direction)); - reinterpret_cast(j_rtp_transceiver_pointer) - ->SetDirection(direction); + webrtc::RTCError error = + reinterpret_cast(j_rtp_transceiver_pointer) + ->SetDirectionWithError(direction); + if (!error.ok()) { + RTC_LOG(LS_WARNING) << "SetDirection failed, code " + << ToString(error.type()) << ", message " + << error.message(); + } + return error.ok(); } } // namespace jni diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_decoder_wrapper.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_decoder_wrapper.cc index d45c6f1d8..3aa18abbd 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_decoder_wrapper.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_decoder_wrapper.cc @@ -257,17 +257,6 @@ absl::optional VideoDecoderWrapper::ParseQP( } break; } -#ifndef DISABLE_H265 - case kVideoCodecH265: { - h265_bitstream_parser_.ParseBitstream(input_image.data(), - input_image.size()); - int qp_int; - if (h265_bitstream_parser_.GetLastSliceQp(&qp_int)) { - qp = qp_int; - } - break; - } -#endif default: break; // Default is to not provide QP. } diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_decoder_wrapper.h b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_decoder_wrapper.h index 1e02ba60a..f5c4787a6 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_decoder_wrapper.h +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_decoder_wrapper.h @@ -18,7 +18,6 @@ #include "api/video_codecs/video_decoder.h" #include "common_video/h264/h264_bitstream_parser.h" -#include "common_video/h265/h265_bitstream_parser.h" #include "rtc_base/race_checker.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_checker.h" @@ -102,9 +101,6 @@ class VideoDecoderWrapper : public VideoDecoder { H264BitstreamParser h264_bitstream_parser_ RTC_GUARDED_BY(decoder_thread_checker_); - H265BitstreamParser h265_bitstream_parser_ - RTC_GUARDED_BY(decoder_thread_checker_); - DecodedImageCallback* callback_ RTC_GUARDED_BY(callback_race_checker_); // Accessed both on the decoder thread and the callback thread. diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_encoder_wrapper.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_encoder_wrapper.cc index ada2a5bbd..f64f1b466 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_encoder_wrapper.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_encoder_wrapper.cc @@ -116,7 +116,10 @@ int32_t VideoEncoderWrapper::Release() { int32_t status = JavaToNativeVideoCodecStatus( jni, Java_VideoEncoder_release(jni, encoder_)); RTC_LOG(LS_INFO) << "release: " << status; - frame_extra_infos_.clear(); + { + MutexLock lock(&frame_extra_infos_lock_); + frame_extra_infos_.clear(); + } initialized_ = false; return status; @@ -141,7 +144,10 @@ int32_t VideoEncoderWrapper::Encode( FrameExtraInfo info; info.capture_time_ns = frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec; info.timestamp_rtp = frame.timestamp(); - frame_extra_infos_.push_back(info); + { + MutexLock lock(&frame_extra_infos_lock_); + frame_extra_infos_.push_back(info); + } ScopedJavaLocalRef j_frame = NativeToJavaVideoFrame(jni, frame); ScopedJavaLocalRef ret = @@ -232,19 +238,23 @@ void VideoEncoderWrapper::OnEncodedFrame( // entries that don't belong to us, and we need to be careful not to // remove them. Removing only those entries older than the current frame // provides this guarantee. - while (!frame_extra_infos_.empty() && - frame_extra_infos_.front().capture_time_ns < capture_time_ns) { + FrameExtraInfo frame_extra_info; + { + MutexLock lock(&frame_extra_infos_lock_); + while (!frame_extra_infos_.empty() && + frame_extra_infos_.front().capture_time_ns < capture_time_ns) { + frame_extra_infos_.pop_front(); + } + if (frame_extra_infos_.empty() || + frame_extra_infos_.front().capture_time_ns != capture_time_ns) { + RTC_LOG(LS_WARNING) + << "Java encoder produced an unexpected frame with timestamp: " + << capture_time_ns; + return; + } + frame_extra_info = frame_extra_infos_.front(); frame_extra_infos_.pop_front(); } - if (frame_extra_infos_.empty() || - frame_extra_infos_.front().capture_time_ns != capture_time_ns) { - RTC_LOG(LS_WARNING) - << "Java encoder produced an unexpected frame with timestamp: " - << capture_time_ns; - return; - } - FrameExtraInfo frame_extra_info = std::move(frame_extra_infos_.front()); - frame_extra_infos_.pop_front(); // This is a bit subtle. The |frame| variable from the lambda capture is // const. Which implies that (i) we need to make a copy to be able to @@ -346,7 +356,6 @@ CodecSpecificInfo VideoEncoderWrapper::ParseCodecSpecificInfo( static_cast(gof_idx_++ % gof_.num_frames_in_gof); info.codecSpecific.VP9.num_spatial_layers = 1; info.codecSpecific.VP9.first_frame_in_picture = true; - info.codecSpecific.VP9.end_of_picture = true; info.codecSpecific.VP9.spatial_layer_resolution_present = false; if (info.codecSpecific.VP9.ss_data_available) { info.codecSpecific.VP9.spatial_layer_resolution_present = true; diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_encoder_wrapper.h b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_encoder_wrapper.h index dfde795e3..16eb1c2b8 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_encoder_wrapper.h +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_encoder_wrapper.h @@ -24,6 +24,7 @@ #include "common_video/h265/h265_bitstream_parser.h" #endif #include "modules/video_coding/codecs/vp9/include/vp9_globals.h" +#include "rtc_base/synchronization/mutex.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/video_frame.h" @@ -85,7 +86,10 @@ class VideoEncoderWrapper : public VideoEncoder { const ScopedJavaGlobalRef encoder_; const ScopedJavaGlobalRef int_array_class_; - std::deque frame_extra_infos_; + // Modified both on the encoder thread and the callback thread. + Mutex frame_extra_infos_lock_; + std::deque frame_extra_infos_ + RTC_GUARDED_BY(frame_extra_infos_lock_); EncodedImageCallback* callback_; bool initialized_; int num_resets_; diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_frame.cc b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_frame.cc index d57fe8f9b..860eebe5e 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_frame.cc +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_frame.cc @@ -152,14 +152,14 @@ const ScopedJavaGlobalRef& AndroidVideoBuffer::video_frame_buffer() return j_video_frame_buffer_; } -rtc::scoped_refptr AndroidVideoBuffer::CropAndScale( - JNIEnv* jni, +rtc::scoped_refptr AndroidVideoBuffer::CropAndScale( int crop_x, int crop_y, int crop_width, int crop_height, int scale_width, int scale_height) { + JNIEnv* jni = AttachCurrentThreadIfNeeded(); return Adopt(jni, Java_Buffer_cropAndScale(jni, j_video_frame_buffer_, crop_x, crop_y, crop_width, crop_height, scale_width, scale_height)); diff --git a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_frame.h b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_frame.h index f6b569a3e..5e39b8a77 100644 --- a/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_frame.h +++ b/TMessagesProj/jni/voip/webrtc/sdk/android/src/jni/video_frame.h @@ -42,13 +42,12 @@ class AndroidVideoBuffer : public VideoFrameBuffer { // Crops a region defined by |crop_x|, |crop_y|, |crop_width| and // |crop_height|. Scales it to size |scale_width| x |scale_height|. - rtc::scoped_refptr CropAndScale(JNIEnv* jni, - int crop_x, - int crop_y, - int crop_width, - int crop_height, - int scale_width, - int scale_height); + rtc::scoped_refptr CropAndScale(int crop_x, + int crop_y, + int crop_width, + int crop_height, + int scale_width, + int scale_height) override; protected: // Should not be called directly. Adopts the Java VideoFrame.Buffer. Use diff --git a/TMessagesProj/jni/voip/webrtc/stats/rtc_stats.cc b/TMessagesProj/jni/voip/webrtc/stats/rtc_stats.cc index b8e9633f4..59de664c0 100644 --- a/TMessagesProj/jni/voip/webrtc/stats/rtc_stats.cc +++ b/TMessagesProj/jni/voip/webrtc/stats/rtc_stats.cc @@ -35,6 +35,20 @@ std::string VectorToString(const std::vector& vector) { return sb.Release(); } +// This overload is required because std::vector range loops don't +// return references but objects, causing -Wrange-loop-analysis diagnostics. +std::string VectorToString(const std::vector& vector) { + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + for (bool element : vector) { + sb << separator << rtc::ToString(element); + separator = ","; + } + sb << "]"; + return sb.Release(); +} + // Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and // std::string element types. template diff --git a/TMessagesProj/jni/voip/webrtc/stats/rtc_stats_report.cc b/TMessagesProj/jni/voip/webrtc/stats/rtc_stats_report.cc index a56d30d3c..d29d819fc 100644 --- a/TMessagesProj/jni/voip/webrtc/stats/rtc_stats_report.cc +++ b/TMessagesProj/jni/voip/webrtc/stats/rtc_stats_report.cc @@ -98,13 +98,12 @@ std::unique_ptr RTCStatsReport::Take(const std::string& id) { return stats; } -void RTCStatsReport::TakeMembersFrom( - rtc::scoped_refptr victim) { - for (StatsMap::iterator it = victim->stats_.begin(); - it != victim->stats_.end(); ++it) { +void RTCStatsReport::TakeMembersFrom(rtc::scoped_refptr other) { + for (StatsMap::iterator it = other->stats_.begin(); it != other->stats_.end(); + ++it) { AddStats(std::unique_ptr(it->second.release())); } - victim->stats_.clear(); + other->stats_.clear(); } RTCStatsReport::ConstIterator RTCStatsReport::begin() const { diff --git a/TMessagesProj/jni/voip/webrtc/stats/rtcstats_objects.cc b/TMessagesProj/jni/voip/webrtc/stats/rtcstats_objects.cc index 2fe85468c..5a803de07 100644 --- a/TMessagesProj/jni/voip/webrtc/stats/rtcstats_objects.cc +++ b/TMessagesProj/jni/voip/webrtc/stats/rtcstats_objects.cc @@ -92,6 +92,7 @@ RTCCertificateStats::~RTCCertificateStats() {} // clang-format off WEBRTC_RTCSTATS_IMPL(RTCCodecStats, RTCStats, "codec", + &transport_id, &payload_type, &mime_type, &clock_rate, @@ -104,6 +105,7 @@ RTCCodecStats::RTCCodecStats(const std::string& id, int64_t timestamp_us) RTCCodecStats::RTCCodecStats(std::string&& id, int64_t timestamp_us) : RTCStats(std::move(id), timestamp_us), + transport_id("transportId"), payload_type("payloadType"), mime_type("mimeType"), clock_rate("clockRate"), @@ -112,6 +114,7 @@ RTCCodecStats::RTCCodecStats(std::string&& id, int64_t timestamp_us) RTCCodecStats::RTCCodecStats(const RTCCodecStats& other) : RTCStats(other.id(), other.timestamp_us()), + transport_id(other.transport_id), payload_type(other.payload_type), mime_type(other.mime_type), clock_rate(other.clock_rate), diff --git a/TMessagesProj/jni/voip/webrtc/system_wrappers/include/clock.h b/TMessagesProj/jni/voip/webrtc/system_wrappers/include/clock.h index 8eac3d18b..3c60f63da 100644 --- a/TMessagesProj/jni/voip/webrtc/system_wrappers/include/clock.h +++ b/TMessagesProj/jni/voip/webrtc/system_wrappers/include/clock.h @@ -13,10 +13,10 @@ #include +#include #include #include "api/units/timestamp.h" -#include "rtc_base/synchronization/rw_lock_wrapper.h" #include "rtc_base/system/rtc_export.h" #include "system_wrappers/include/ntp_time.h" @@ -78,8 +78,12 @@ class SimulatedClock : public Clock { void AdvanceTime(TimeDelta delta); private: - Timestamp time_; - std::unique_ptr lock_; + // The time is read and incremented with relaxed order. Each thread will see + // monotonically increasing time, and when threads post tasks or messages to + // one another, the synchronization done as part of the message passing should + // ensure that any causual chain of events on multiple threads also + // corresponds to monotonically increasing time. + std::atomic time_us_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/system_wrappers/include/cpu_features_wrapper.h b/TMessagesProj/jni/voip/webrtc/system_wrappers/include/cpu_features_wrapper.h index 739161afc..612b4a5d6 100644 --- a/TMessagesProj/jni/voip/webrtc/system_wrappers/include/cpu_features_wrapper.h +++ b/TMessagesProj/jni/voip/webrtc/system_wrappers/include/cpu_features_wrapper.h @@ -13,12 +13,10 @@ #include -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif +namespace webrtc { // List of features in x86. -typedef enum { kSSE2, kSSE3 } CPUFeature; +typedef enum { kSSE2, kSSE3, kAVX2 } CPUFeature; // List of features in ARM. enum { @@ -28,21 +26,17 @@ enum { kCPUFeatureLDREXSTREX = (1 << 3) }; -typedef int (*WebRtc_CPUInfo)(CPUFeature feature); - // Returns true if the CPU supports the feature. -extern WebRtc_CPUInfo WebRtc_GetCPUInfo; +int GetCPUInfo(CPUFeature feature); // No CPU feature is available => straight C path. -extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM; +int GetCPUInfoNoASM(CPUFeature feature); // Return the features in an ARM device. // It detects the features in the hardware platform, and returns supported // values in the above enum definition as a bitmask. -extern uint64_t WebRtc_GetCPUFeaturesARM(void); +uint64_t GetCPUFeaturesARM(void); -#if defined(__cplusplus) || defined(c_plusplus) -} // extern "C" -#endif +} // namespace webrtc #endif // SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/system_wrappers/source/clock.cc b/TMessagesProj/jni/voip/webrtc/system_wrappers/source/clock.cc index e0f4b401e..0ae624d84 100644 --- a/TMessagesProj/jni/voip/webrtc/system_wrappers/source/clock.cc +++ b/TMessagesProj/jni/voip/webrtc/system_wrappers/source/clock.cc @@ -26,7 +26,6 @@ #endif // defined(WEBRTC_POSIX) #include "rtc_base/synchronization/mutex.h" -#include "rtc_base/synchronization/rw_lock_wrapper.h" #include "rtc_base/time_utils.h" namespace webrtc { @@ -239,16 +238,15 @@ Clock* Clock::GetRealTimeClock() { } SimulatedClock::SimulatedClock(int64_t initial_time_us) - : SimulatedClock(Timestamp::Micros(initial_time_us)) {} + : time_us_(initial_time_us) {} SimulatedClock::SimulatedClock(Timestamp initial_time) - : time_(initial_time), lock_(RWLockWrapper::CreateRWLock()) {} + : SimulatedClock(initial_time.us()) {} SimulatedClock::~SimulatedClock() {} Timestamp SimulatedClock::CurrentTime() { - ReadLockScoped synchronize(*lock_); - return time_; + return Timestamp::Micros(time_us_.load(std::memory_order_relaxed)); } NtpTime SimulatedClock::CurrentNtpTime() { @@ -271,9 +269,13 @@ void SimulatedClock::AdvanceTimeMicroseconds(int64_t microseconds) { AdvanceTime(TimeDelta::Micros(microseconds)); } +// TODO(bugs.webrtc.org(12102): It's desirable to let a single thread own +// advancement of the clock. We could then replace this read-modify-write +// operation with just a thread checker. But currently, that breaks a couple of +// tests, in particular, RepeatingTaskTest.ClockIntegration and +// CallStatsTest.LastProcessedRtt. void SimulatedClock::AdvanceTime(TimeDelta delta) { - WriteLockScoped synchronize(*lock_); - time_ += delta; + time_us_.fetch_add(delta.us(), std::memory_order_relaxed); } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features.cc b/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features.cc index ebcb48c15..0f8121289 100644 --- a/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features.cc +++ b/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features.cc @@ -12,11 +12,14 @@ #include "rtc_base/system/arch.h" #include "system_wrappers/include/cpu_features_wrapper.h" +#include "system_wrappers/include/field_trial.h" #if defined(WEBRTC_ARCH_X86_FAMILY) && defined(_MSC_VER) #include #endif +namespace webrtc { + // No CPU feature is available => straight C path. int GetCPUInfoNoASM(CPUFeature feature) { (void)feature; @@ -24,6 +27,22 @@ int GetCPUInfoNoASM(CPUFeature feature) { } #if defined(WEBRTC_ARCH_X86_FAMILY) + +#if defined(WEBRTC_ENABLE_AVX2) +// xgetbv returns the value of an Intel Extended Control Register (XCR). +// Currently only XCR0 is defined by Intel so |xcr| should always be zero. +static uint64_t xgetbv(uint32_t xcr) { +#if defined(_MSC_VER) + return _xgetbv(xcr); +#else + uint32_t eax, edx; + + __asm__ volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr)); + return (static_cast(edx) << 32) | eax; +#endif // _MSC_VER +} +#endif // WEBRTC_ENABLE_AVX2 + #ifndef _MSC_VER // Intrinsic for "cpuid". #if defined(__pic__) && defined(__i386__) @@ -41,7 +60,7 @@ static inline void __cpuid(int cpu_info[4], int info_type) { __asm__ volatile("cpuid\n" : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) - : "a"(info_type)); + : "a"(info_type), "c"(0)); } #endif #endif // _MSC_VER @@ -49,7 +68,7 @@ static inline void __cpuid(int cpu_info[4], int info_type) { #if defined(WEBRTC_ARCH_X86_FAMILY) // Actual feature detection for x86. -static int GetCPUInfo(CPUFeature feature) { +int GetCPUInfo(CPUFeature feature) { int cpu_info[4]; __cpuid(cpu_info, 1); if (feature == kSSE2) { @@ -58,15 +77,39 @@ static int GetCPUInfo(CPUFeature feature) { if (feature == kSSE3) { return 0 != (cpu_info[2] & 0x00000001); } +#if defined(WEBRTC_ENABLE_AVX2) + if (feature == kAVX2 && + !webrtc::field_trial::IsEnabled("WebRTC-Avx2SupportKillSwitch")) { + int cpu_info7[4]; + __cpuid(cpu_info7, 0); + int num_ids = cpu_info7[0]; + if (num_ids < 7) { + return 0; + } + // Interpret CPU feature information. + __cpuid(cpu_info7, 7); + + // AVX instructions can be used when + // a) AVX are supported by the CPU, + // b) XSAVE is supported by the CPU, + // c) XSAVE is enabled by the kernel. + // See http://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled + // AVX2 support needs (avx_support && (cpu_info7[1] & 0x00000020) != 0;). + return (cpu_info[2] & 0x10000000) != 0 && + (cpu_info[2] & 0x04000000) != 0 /* XSAVE */ && + (cpu_info[2] & 0x08000000) != 0 /* OSXSAVE */ && + (xgetbv(0) & 0x00000006) == 6 /* XSAVE enabled by kernel */ && + (cpu_info7[1] & 0x00000020) != 0; + } +#endif // WEBRTC_ENABLE_AVX2 return 0; } #else // Default to straight C for other platforms. -static int GetCPUInfo(CPUFeature feature) { +int GetCPUInfo(CPUFeature feature) { (void)feature; return 0; } #endif -WebRtc_CPUInfo WebRtc_GetCPUInfo = GetCPUInfo; -WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM = GetCPUInfoNoASM; +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_android.c b/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_android.cc similarity index 85% rename from TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_android.c rename to TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_android.cc index 0cb3a6c5e..95cc609b0 100644 --- a/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_android.c +++ b/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_android.cc @@ -10,6 +10,10 @@ #include -uint64_t WebRtc_GetCPUFeaturesARM(void) { +namespace webrtc { + +uint64_t GetCPUFeaturesARM(void) { return android_getCpuFeatures(); } + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_linux.c b/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_linux.cc similarity index 87% rename from TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_linux.c rename to TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_linux.cc index 004de5a6a..335bed4da 100644 --- a/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_linux.c +++ b/TMessagesProj/jni/voip/webrtc/system_wrappers/source/cpu_features_linux.cc @@ -8,32 +8,39 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include #include #include -#include -#ifndef __GLIBC_PREREQ -#define __GLIBC_PREREQ(a, b) 0 + +#ifdef __GLIBC_PREREQ +#define WEBRTC_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) +#else +#define WEBRTC_GLIBC_PREREQ(a, b) 0 #endif -#if __GLIBC_PREREQ(2, 16) + +#if WEBRTC_GLIBC_PREREQ(2, 16) #include #else -#include -#include #include +#include #include +#include #endif + #include "rtc_base/system/arch.h" #include "system_wrappers/include/cpu_features_wrapper.h" #if defined(WEBRTC_ARCH_ARM_FAMILY) #include -uint64_t WebRtc_GetCPUFeaturesARM(void) { +namespace webrtc { + +uint64_t GetCPUFeaturesARM(void) { uint64_t result = 0; int architecture = 0; - unsigned long hwcap = 0; + uint64_t hwcap = 0; const char* platform = NULL; -#if __GLIBC_PREREQ(2, 16) +#if WEBRTC_GLIBC_PREREQ(2, 16) hwcap = getauxval(AT_HWCAP); platform = (const char*)getauxval(AT_PLATFORM); #else @@ -57,7 +64,7 @@ uint64_t WebRtc_GetCPUFeaturesARM(void) { } close(fd); } -#endif // __GLIBC_PREREQ(2,16) +#endif // WEBRTC_GLIBC_PREREQ(2, 16) #if defined(__aarch64__) architecture = 8; if ((hwcap & HWCAP_FP) != 0) @@ -84,4 +91,6 @@ uint64_t WebRtc_GetCPUFeaturesARM(void) { result |= kCPUFeatureLDREXSTREX; return result; } + +} // namespace webrtc #endif // WEBRTC_ARCH_ARM_FAMILY diff --git a/TMessagesProj/jni/voip/webrtc/video/adaptation/balanced_constraint.cc b/TMessagesProj/jni/voip/webrtc/video/adaptation/balanced_constraint.cc new file mode 100644 index 000000000..fb455193f --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/video/adaptation/balanced_constraint.cc @@ -0,0 +1,58 @@ +/* + * Copyright 2020 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 +#include + +#include "rtc_base/synchronization/sequence_checker.h" +#include "rtc_base/task_utils/to_queued_task.h" +#include "video/adaptation/balanced_constraint.h" + +namespace webrtc { + +BalancedConstraint::BalancedConstraint( + DegradationPreferenceProvider* degradation_preference_provider) + : encoder_target_bitrate_bps_(absl::nullopt), + degradation_preference_provider_(degradation_preference_provider) { + RTC_DCHECK(degradation_preference_provider_); + sequence_checker_.Detach(); +} + +void BalancedConstraint::OnEncoderTargetBitrateUpdated( + absl::optional encoder_target_bitrate_bps) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps); +} + +bool BalancedConstraint::IsAdaptationUpAllowed( + const VideoStreamInputState& input_state, + const VideoSourceRestrictions& restrictions_before, + const VideoSourceRestrictions& restrictions_after) const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + // Don't adapt if BalancedDegradationSettings applies and determines this will + // exceed bitrate constraints. + if (degradation_preference_provider_->degradation_preference() == + DegradationPreference::BALANCED && + !balanced_settings_.CanAdaptUp(input_state.video_codec_type(), + input_state.frame_size_pixels().value(), + encoder_target_bitrate_bps_.value_or(0))) { + return false; + } + if (DidIncreaseResolution(restrictions_before, restrictions_after) && + !balanced_settings_.CanAdaptUpResolution( + input_state.video_codec_type(), + input_state.frame_size_pixels().value(), + encoder_target_bitrate_bps_.value_or(0))) { + return false; + } + return true; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/video/adaptation/balanced_constraint.h b/TMessagesProj/jni/voip/webrtc/video/adaptation/balanced_constraint.h new file mode 100644 index 000000000..5e0240802 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/video/adaptation/balanced_constraint.h @@ -0,0 +1,50 @@ +/* + * Copyright 2020 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. + */ + +#ifndef VIDEO_ADAPTATION_BALANCED_CONSTRAINT_H_ +#define VIDEO_ADAPTATION_BALANCED_CONSTRAINT_H_ + +#include + +#include "absl/types/optional.h" +#include "call/adaptation/adaptation_constraint.h" +#include "call/adaptation/degradation_preference_provider.h" +#include "rtc_base/experiments/balanced_degradation_settings.h" +#include "rtc_base/synchronization/sequence_checker.h" + +namespace webrtc { + +class BalancedConstraint : public AdaptationConstraint { + public: + explicit BalancedConstraint( + DegradationPreferenceProvider* degradation_preference_provider); + ~BalancedConstraint() override = default; + + void OnEncoderTargetBitrateUpdated( + absl::optional encoder_target_bitrate_bps); + + // AdaptationConstraint implementation. + std::string Name() const override { return "BalancedConstraint"; } + bool IsAdaptationUpAllowed( + const VideoStreamInputState& input_state, + const VideoSourceRestrictions& restrictions_before, + const VideoSourceRestrictions& restrictions_after) const override; + + private: + SequenceChecker sequence_checker_; + absl::optional encoder_target_bitrate_bps_ + RTC_GUARDED_BY(&sequence_checker_); + const BalancedDegradationSettings balanced_settings_; + const DegradationPreferenceProvider* degradation_preference_provider_; +}; + +} // namespace webrtc + +#endif // VIDEO_ADAPTATION_BALANCED_CONSTRAINT_H_ diff --git a/TMessagesProj/jni/voip/webrtc/video/adaptation/bitrate_constraint.cc b/TMessagesProj/jni/voip/webrtc/video/adaptation/bitrate_constraint.cc new file mode 100644 index 000000000..1061c4557 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/video/adaptation/bitrate_constraint.cc @@ -0,0 +1,65 @@ +/* + * Copyright 2020 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 +#include + +#include "call/adaptation/video_stream_adapter.h" +#include "rtc_base/synchronization/sequence_checker.h" +#include "video/adaptation/bitrate_constraint.h" + +namespace webrtc { + +BitrateConstraint::BitrateConstraint() + : encoder_settings_(absl::nullopt), + encoder_target_bitrate_bps_(absl::nullopt) { + sequence_checker_.Detach(); +} + +void BitrateConstraint::OnEncoderSettingsUpdated( + absl::optional encoder_settings) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + encoder_settings_ = std::move(encoder_settings); +} + +void BitrateConstraint::OnEncoderTargetBitrateUpdated( + absl::optional encoder_target_bitrate_bps) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps); +} + +bool BitrateConstraint::IsAdaptationUpAllowed( + const VideoStreamInputState& input_state, + const VideoSourceRestrictions& restrictions_before, + const VideoSourceRestrictions& restrictions_after) const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + // Make sure bitrate limits are not violated. + if (DidIncreaseResolution(restrictions_before, restrictions_after)) { + uint32_t bitrate_bps = encoder_target_bitrate_bps_.value_or(0); + absl::optional bitrate_limits = + encoder_settings_.has_value() + ? encoder_settings_->encoder_info() + .GetEncoderBitrateLimitsForResolution( + // Need some sort of expected resulting pixels to be used + // instead of unrestricted. + GetHigherResolutionThan( + input_state.frame_size_pixels().value())) + : absl::nullopt; + if (bitrate_limits.has_value() && bitrate_bps != 0) { + RTC_DCHECK_GE(bitrate_limits->frame_size_pixels, + input_state.frame_size_pixels().value()); + return bitrate_bps >= + static_cast(bitrate_limits->min_start_bitrate_bps); + } + } + return true; +} + +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/video/adaptation/bitrate_constraint.h b/TMessagesProj/jni/voip/webrtc/video/adaptation/bitrate_constraint.h new file mode 100644 index 000000000..015edcc13 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/video/adaptation/bitrate_constraint.h @@ -0,0 +1,52 @@ +/* + * Copyright 2020 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. + */ + +#ifndef VIDEO_ADAPTATION_BITRATE_CONSTRAINT_H_ +#define VIDEO_ADAPTATION_BITRATE_CONSTRAINT_H_ + +#include + +#include "absl/types/optional.h" +#include "call/adaptation/adaptation_constraint.h" +#include "call/adaptation/encoder_settings.h" +#include "call/adaptation/video_source_restrictions.h" +#include "call/adaptation/video_stream_input_state.h" +#include "rtc_base/synchronization/sequence_checker.h" + +namespace webrtc { + +class BitrateConstraint : public AdaptationConstraint { + public: + BitrateConstraint(); + ~BitrateConstraint() override = default; + + void OnEncoderSettingsUpdated( + absl::optional encoder_settings); + void OnEncoderTargetBitrateUpdated( + absl::optional encoder_target_bitrate_bps); + + // AdaptationConstraint implementation. + std::string Name() const override { return "BitrateConstraint"; } + bool IsAdaptationUpAllowed( + const VideoStreamInputState& input_state, + const VideoSourceRestrictions& restrictions_before, + const VideoSourceRestrictions& restrictions_after) const override; + + private: + SequenceChecker sequence_checker_; + absl::optional encoder_settings_ + RTC_GUARDED_BY(&sequence_checker_); + absl::optional encoder_target_bitrate_bps_ + RTC_GUARDED_BY(&sequence_checker_); +}; + +} // namespace webrtc + +#endif // VIDEO_ADAPTATION_BITRATE_CONSTRAINT_H_ diff --git a/TMessagesProj/jni/voip/webrtc/video/adaptation/quality_scaler_resource.cc b/TMessagesProj/jni/voip/webrtc/video/adaptation/quality_scaler_resource.cc index ff8f1712d..c43848818 100644 --- a/TMessagesProj/jni/voip/webrtc/video/adaptation/quality_scaler_resource.cc +++ b/TMessagesProj/jni/voip/webrtc/video/adaptation/quality_scaler_resource.cc @@ -12,6 +12,7 @@ #include +#include "rtc_base/checks.h" #include "rtc_base/experiments/balanced_degradation_settings.h" #include "rtc_base/ref_counted_object.h" #include "rtc_base/task_utils/to_queued_task.h" @@ -19,27 +20,14 @@ namespace webrtc { -namespace { - -const int64_t kUnderuseDueToDisabledCooldownMs = 1000; - -} // namespace - // static -rtc::scoped_refptr QualityScalerResource::Create( - DegradationPreferenceProvider* degradation_preference_provider) { - return new rtc::RefCountedObject( - degradation_preference_provider); +rtc::scoped_refptr QualityScalerResource::Create() { + return new rtc::RefCountedObject(); } -QualityScalerResource::QualityScalerResource( - DegradationPreferenceProvider* degradation_preference_provider) +QualityScalerResource::QualityScalerResource() : VideoStreamEncoderResource("QualityScalerResource"), - quality_scaler_(nullptr), - last_underuse_due_to_disabled_timestamp_ms_(absl::nullopt), - degradation_preference_provider_(degradation_preference_provider) { - RTC_CHECK(degradation_preference_provider_); -} + quality_scaler_(nullptr) {} QualityScalerResource::~QualityScalerResource() { RTC_DCHECK(!quality_scaler_); @@ -60,6 +48,7 @@ void QualityScalerResource::StartCheckForOveruse( void QualityScalerResource::StopCheckForOveruse() { RTC_DCHECK_RUN_ON(encoder_queue()); + RTC_DCHECK(is_started()); // Ensure we have no pending callbacks. This makes it safe to destroy the // QualityScaler and even task queues with tasks in-flight. quality_scaler_.reset(); @@ -83,21 +72,6 @@ void QualityScalerResource::OnEncodeCompleted(const EncodedImage& encoded_image, RTC_DCHECK_RUN_ON(encoder_queue()); if (quality_scaler_ && encoded_image.qp_ >= 0) { quality_scaler_->ReportQp(encoded_image.qp_, time_sent_in_us); - } else if (!quality_scaler_) { - // Reference counting guarantees that this object is still alive by the time - // the task is executed. - // TODO(webrtc:11553): this is a workaround to ensure that all quality - // scaler imposed limitations are removed once qualty scaler is disabled - // mid call. - // Instead it should be done at a higher layer in the same way for all - // resources. - int64_t timestamp_ms = rtc::TimeMillis(); - if (!last_underuse_due_to_disabled_timestamp_ms_.has_value() || - timestamp_ms - last_underuse_due_to_disabled_timestamp_ms_.value() >= - kUnderuseDueToDisabledCooldownMs) { - last_underuse_due_to_disabled_timestamp_ms_ = timestamp_ms; - OnResourceUsageStateMeasured(ResourceUsageState::kUnderuse); - } } } diff --git a/TMessagesProj/jni/voip/webrtc/video/adaptation/quality_scaler_resource.h b/TMessagesProj/jni/voip/webrtc/video/adaptation/quality_scaler_resource.h index 27c255567..06c22ca3c 100644 --- a/TMessagesProj/jni/voip/webrtc/video/adaptation/quality_scaler_resource.h +++ b/TMessagesProj/jni/voip/webrtc/video/adaptation/quality_scaler_resource.h @@ -32,18 +32,15 @@ namespace webrtc { class QualityScalerResource : public VideoStreamEncoderResource, public QualityScalerQpUsageHandlerInterface { public: - static rtc::scoped_refptr Create( - DegradationPreferenceProvider* degradation_preference_provider); + static rtc::scoped_refptr Create(); - explicit QualityScalerResource( - DegradationPreferenceProvider* degradation_preference_provider); + QualityScalerResource(); ~QualityScalerResource() override; bool is_started() const; void StartCheckForOveruse(VideoEncoder::QpThresholds qp_thresholds); void StopCheckForOveruse(); - void SetQpThresholds(VideoEncoder::QpThresholds qp_thresholds); bool QpFastFilterLow(); void OnEncodeCompleted(const EncodedImage& encoded_image, @@ -55,15 +52,8 @@ class QualityScalerResource : public VideoStreamEncoderResource, void OnReportQpUsageLow() override; private: - // Members accessed on the encoder queue. std::unique_ptr quality_scaler_ RTC_GUARDED_BY(encoder_queue()); - // The timestamp of the last time we reported underuse because this resource - // was disabled in order to prevent getting stuck with QP adaptations. Used to - // make sure underuse reporting is not too spammy. - absl::optional last_underuse_due_to_disabled_timestamp_ms_ - RTC_GUARDED_BY(encoder_queue()); - DegradationPreferenceProvider* const degradation_preference_provider_; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.cc b/TMessagesProj/jni/voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.cc index 16c8b3d5b..c7ca4bccf 100644 --- a/TMessagesProj/jni/voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.cc +++ b/TMessagesProj/jni/voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.cc @@ -22,11 +22,14 @@ #include "api/video/video_adaptation_reason.h" #include "api/video/video_source_interface.h" #include "call/adaptation/video_source_restrictions.h" +#include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/ref_counted_object.h" #include "rtc_base/strings/string_builder.h" +#include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/time_utils.h" +#include "video/adaptation/quality_scaler_resource.h" namespace webrtc { @@ -52,6 +55,7 @@ std::string ToString(VideoAdaptationReason reason) { case VideoAdaptationReason::kCpu: return "cpu"; } + RTC_CHECK_NOTREACHED(); } } // namespace @@ -128,137 +132,6 @@ class VideoStreamEncoderResourceManager::InitialFrameDropper { int initial_framedrop_; }; -VideoStreamEncoderResourceManager::BitrateConstraint::BitrateConstraint( - VideoStreamEncoderResourceManager* manager) - : manager_(manager), - resource_adaptation_queue_(nullptr), - encoder_settings_(absl::nullopt), - encoder_target_bitrate_bps_(absl::nullopt) {} - -void VideoStreamEncoderResourceManager::BitrateConstraint::SetAdaptationQueue( - TaskQueueBase* resource_adaptation_queue) { - resource_adaptation_queue_ = resource_adaptation_queue; -} - -void VideoStreamEncoderResourceManager::BitrateConstraint:: - OnEncoderSettingsUpdated(absl::optional encoder_settings) { - RTC_DCHECK_RUN_ON(manager_->encoder_queue_); - resource_adaptation_queue_->PostTask( - ToQueuedTask([this_ref = rtc::scoped_refptr(this), - encoder_settings] { - RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_); - this_ref->encoder_settings_ = std::move(encoder_settings); - })); -} - -void VideoStreamEncoderResourceManager::BitrateConstraint:: - OnEncoderTargetBitrateUpdated( - absl::optional encoder_target_bitrate_bps) { - RTC_DCHECK_RUN_ON(manager_->encoder_queue_); - resource_adaptation_queue_->PostTask( - ToQueuedTask([this_ref = rtc::scoped_refptr(this), - encoder_target_bitrate_bps] { - RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_); - this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps; - })); -} - -bool VideoStreamEncoderResourceManager::BitrateConstraint:: - IsAdaptationUpAllowed(const VideoStreamInputState& input_state, - const VideoSourceRestrictions& restrictions_before, - const VideoSourceRestrictions& restrictions_after, - rtc::scoped_refptr reason_resource) const { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); - VideoAdaptationReason reason = - manager_->GetReasonFromResource(reason_resource); - // If increasing resolution due to kQuality, make sure bitrate limits are not - // violated. - // TODO(https://crbug.com/webrtc/11771): Why are we allowing violating bitrate - // constraints if adapting due to CPU? Shouldn't this condition be checked - // regardless of reason? - if (reason == VideoAdaptationReason::kQuality && - DidIncreaseResolution(restrictions_before, restrictions_after)) { - uint32_t bitrate_bps = encoder_target_bitrate_bps_.value_or(0); - absl::optional bitrate_limits = - encoder_settings_.has_value() - ? encoder_settings_->encoder_info() - .GetEncoderBitrateLimitsForResolution( - // Need some sort of expected resulting pixels to be used - // instead of unrestricted. - GetHigherResolutionThan( - input_state.frame_size_pixels().value())) - : absl::nullopt; - if (bitrate_limits.has_value() && bitrate_bps != 0) { - RTC_DCHECK_GE(bitrate_limits->frame_size_pixels, - input_state.frame_size_pixels().value()); - return bitrate_bps >= - static_cast(bitrate_limits->min_start_bitrate_bps); - } - } - return true; -} - -VideoStreamEncoderResourceManager::BalancedConstraint::BalancedConstraint( - VideoStreamEncoderResourceManager* manager, - DegradationPreferenceProvider* degradation_preference_provider) - : manager_(manager), - resource_adaptation_queue_(nullptr), - encoder_target_bitrate_bps_(absl::nullopt), - degradation_preference_provider_(degradation_preference_provider) { - RTC_DCHECK(manager_); - RTC_DCHECK(degradation_preference_provider_); -} - -void VideoStreamEncoderResourceManager::BalancedConstraint::SetAdaptationQueue( - TaskQueueBase* resource_adaptation_queue) { - resource_adaptation_queue_ = resource_adaptation_queue; -} - -void VideoStreamEncoderResourceManager::BalancedConstraint:: - OnEncoderTargetBitrateUpdated( - absl::optional encoder_target_bitrate_bps) { - RTC_DCHECK_RUN_ON(manager_->encoder_queue_); - resource_adaptation_queue_->PostTask( - ToQueuedTask([this_ref = rtc::scoped_refptr(this), - encoder_target_bitrate_bps] { - RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_); - this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps; - })); -} - -bool VideoStreamEncoderResourceManager::BalancedConstraint:: - IsAdaptationUpAllowed(const VideoStreamInputState& input_state, - const VideoSourceRestrictions& restrictions_before, - const VideoSourceRestrictions& restrictions_after, - rtc::scoped_refptr reason_resource) const { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); - VideoAdaptationReason reason = - manager_->GetReasonFromResource(reason_resource); - // Don't adapt if BalancedDegradationSettings applies and determines this will - // exceed bitrate constraints. - // TODO(https://crbug.com/webrtc/11771): Why are we allowing violating - // balanced settings if adapting due CPU? Shouldn't this condition be checked - // regardless of reason? - if (reason == VideoAdaptationReason::kQuality && - degradation_preference_provider_->degradation_preference() == - DegradationPreference::BALANCED && - !manager_->balanced_settings_.CanAdaptUp( - input_state.video_codec_type(), - input_state.frame_size_pixels().value(), - encoder_target_bitrate_bps_.value_or(0))) { - return false; - } - if (reason == VideoAdaptationReason::kQuality && - DidIncreaseResolution(restrictions_before, restrictions_after) && - !manager_->balanced_settings_.CanAdaptUpResolution( - input_state.video_codec_type(), - input_state.frame_size_pixels().value(), - encoder_target_bitrate_bps_.value_or(0))) { - return false; - } - return true; -} - VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager( VideoStreamInputStateProvider* input_state_provider, VideoStreamEncoderObserver* encoder_stats_observer, @@ -267,16 +140,13 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager( std::unique_ptr overuse_detector, DegradationPreferenceProvider* degradation_preference_provider) : degradation_preference_provider_(degradation_preference_provider), - bitrate_constraint_(new rtc::RefCountedObject(this)), - balanced_constraint_(new rtc::RefCountedObject( - this, + bitrate_constraint_(std::make_unique()), + balanced_constraint_(std::make_unique( degradation_preference_provider_)), encode_usage_resource_( EncodeUsageResource::Create(std::move(overuse_detector))), - quality_scaler_resource_( - QualityScalerResource::Create(degradation_preference_provider_)), + quality_scaler_resource_(QualityScalerResource::Create()), encoder_queue_(nullptr), - resource_adaptation_queue_(nullptr), input_state_provider_(input_state_provider), adaptation_processor_(nullptr), encoder_stats_observer_(encoder_stats_observer), @@ -293,24 +163,16 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager( encoder_settings_(absl::nullopt) { RTC_CHECK(degradation_preference_provider_); RTC_CHECK(encoder_stats_observer_); - MapResourceToReason(encode_usage_resource_, VideoAdaptationReason::kCpu); - MapResourceToReason(quality_scaler_resource_, - VideoAdaptationReason::kQuality); } -VideoStreamEncoderResourceManager::~VideoStreamEncoderResourceManager() {} +VideoStreamEncoderResourceManager::~VideoStreamEncoderResourceManager() = + default; void VideoStreamEncoderResourceManager::Initialize( - rtc::TaskQueue* encoder_queue, - rtc::TaskQueue* resource_adaptation_queue) { + rtc::TaskQueue* encoder_queue) { RTC_DCHECK(!encoder_queue_); RTC_DCHECK(encoder_queue); - RTC_DCHECK(!resource_adaptation_queue_); - RTC_DCHECK(resource_adaptation_queue); encoder_queue_ = encoder_queue; - resource_adaptation_queue_ = resource_adaptation_queue; - bitrate_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get()); - balanced_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get()); encode_usage_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get()); quality_scaler_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get()); } @@ -318,7 +180,7 @@ void VideoStreamEncoderResourceManager::Initialize( void VideoStreamEncoderResourceManager::SetAdaptationProcessor( ResourceAdaptationProcessorInterface* adaptation_processor, VideoStreamAdapter* stream_adapter) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_); adaptation_processor_ = adaptation_processor; stream_adapter_ = stream_adapter; } @@ -341,48 +203,55 @@ void VideoStreamEncoderResourceManager::EnsureEncodeUsageResourceStarted() { RTC_DCHECK(encoder_settings_.has_value()); if (encode_usage_resource_->is_started()) { encode_usage_resource_->StopCheckForOveruse(); + } else { + // If the resource has not yet started then it needs to be added. + AddResource(encode_usage_resource_, VideoAdaptationReason::kCpu); } encode_usage_resource_->StartCheckForOveruse(GetCpuOveruseOptions()); } void VideoStreamEncoderResourceManager::StopManagedResources() { RTC_DCHECK_RUN_ON(encoder_queue_); - encode_usage_resource_->StopCheckForOveruse(); - quality_scaler_resource_->StopCheckForOveruse(); + RTC_DCHECK(adaptation_processor_); + if (encode_usage_resource_->is_started()) { + encode_usage_resource_->StopCheckForOveruse(); + RemoveResource(encode_usage_resource_); + } + if (quality_scaler_resource_->is_started()) { + quality_scaler_resource_->StopCheckForOveruse(); + RemoveResource(quality_scaler_resource_); + } } -void VideoStreamEncoderResourceManager::MapResourceToReason( +void VideoStreamEncoderResourceManager::AddResource( rtc::scoped_refptr resource, VideoAdaptationReason reason) { - MutexLock lock(&resource_lock_); + RTC_DCHECK_RUN_ON(encoder_queue_); RTC_DCHECK(resource); - RTC_DCHECK(absl::c_find_if(resources_, - [resource](const ResourceAndReason& r) { - return r.resource == resource; - }) == resources_.end()) - << "Resource " << resource->Name() << " already was inserted"; - resources_.emplace_back(resource, reason); + bool inserted; + std::tie(std::ignore, inserted) = resources_.emplace(resource, reason); + RTC_DCHECK(inserted) << "Resurce " << resource->Name() + << " already was inserted"; + adaptation_processor_->AddResource(resource); } -std::vector> -VideoStreamEncoderResourceManager::MappedResources() const { - MutexLock lock(&resource_lock_); - std::vector> resources; - for (auto const& resource_and_reason : resources_) { - resources.push_back(resource_and_reason.resource); +void VideoStreamEncoderResourceManager::RemoveResource( + rtc::scoped_refptr resource) { + { + RTC_DCHECK_RUN_ON(encoder_queue_); + RTC_DCHECK(resource); + const auto& it = resources_.find(resource); + RTC_DCHECK(it != resources_.end()) + << "Resource \"" << resource->Name() << "\" not found."; + resources_.erase(it); } - return resources; + adaptation_processor_->RemoveResource(resource); } std::vector VideoStreamEncoderResourceManager::AdaptationConstraints() const { - return {bitrate_constraint_, balanced_constraint_}; -} - -rtc::scoped_refptr -VideoStreamEncoderResourceManager::quality_scaler_resource_for_testing() { - MutexLock lock(&resource_lock_); - return quality_scaler_resource_; + RTC_DCHECK_RUN_ON(encoder_queue_); + return {bitrate_constraint_.get(), balanced_constraint_.get()}; } void VideoStreamEncoderResourceManager::SetEncoderSettings( @@ -429,24 +298,12 @@ void VideoStreamEncoderResourceManager::SetEncoderRates( void VideoStreamEncoderResourceManager::OnFrameDroppedDueToSize() { RTC_DCHECK_RUN_ON(encoder_queue_); - // The VideoStreamEncoder makes the manager outlive the adaptation queue. This - // means that if the task gets executed, |this| has not been freed yet. - // TODO(https://crbug.com/webrtc/11565): When the manager no longer outlives - // the adaptation queue, add logic to prevent use-after-free on |this|. - resource_adaptation_queue_->PostTask([this] { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); - if (!adaptation_processor_) { - // The processor nulled before this task had a chance to execute. This - // happens if the processor is destroyed. No action needed. - return; - } - Adaptation reduce_resolution = stream_adapter_->GetAdaptDownResolution(); - if (reduce_resolution.status() == Adaptation::Status::kValid) { - stream_adapter_->ApplyAdaptation(reduce_resolution, - quality_scaler_resource_); - } - }); initial_frame_dropper_->OnFrameDroppedDueToSize(); + Adaptation reduce_resolution = stream_adapter_->GetAdaptDownResolution(); + if (reduce_resolution.status() == Adaptation::Status::kValid) { + stream_adapter_->ApplyAdaptation(reduce_resolution, + quality_scaler_resource_); + } } void VideoStreamEncoderResourceManager::OnEncodeStarted( @@ -468,7 +325,6 @@ void VideoStreamEncoderResourceManager::OnEncodeCompleted( encoded_image.capture_time_ms_ * rtc::kNumMicrosecsPerMillisec; encode_usage_resource_->OnEncodeCompleted( timestamp, time_sent_in_us, capture_time_us, encode_duration_us); - // Inform |quality_scaler_resource_| of the encode completed event. quality_scaler_resource_->OnEncodeCompleted(encoded_image, time_sent_in_us); } @@ -486,7 +342,7 @@ bool VideoStreamEncoderResourceManager::DropInitialFrames() const { void VideoStreamEncoderResourceManager::OnMaybeEncodeFrame() { RTC_DCHECK_RUN_ON(encoder_queue_); initial_frame_dropper_->OnMaybeEncodeFrame(); - if (quality_rampup_experiment_) { + if (quality_rampup_experiment_ && quality_scaler_resource_->is_started()) { DataRate bandwidth = encoder_rates_.has_value() ? encoder_rates_->bandwidth_allocation : DataRate::Zero(); @@ -502,10 +358,15 @@ void VideoStreamEncoderResourceManager::UpdateQualityScalerSettings( absl::optional qp_thresholds) { RTC_DCHECK_RUN_ON(encoder_queue_); if (qp_thresholds.has_value()) { + if (quality_scaler_resource_->is_started()) { + quality_scaler_resource_->SetQpThresholds(qp_thresholds.value()); + } else { + quality_scaler_resource_->StartCheckForOveruse(qp_thresholds.value()); + AddResource(quality_scaler_resource_, VideoAdaptationReason::kQuality); + } + } else if (quality_scaler_resource_->is_started()) { quality_scaler_resource_->StopCheckForOveruse(); - quality_scaler_resource_->StartCheckForOveruse(qp_thresholds.value()); - } else { - quality_scaler_resource_->StopCheckForOveruse(); + RemoveResource(quality_scaler_resource_); } initial_frame_dropper_->OnQualityScalerSettingsUpdated(); } @@ -554,14 +415,11 @@ void VideoStreamEncoderResourceManager::ConfigureQualityScaler( VideoAdaptationReason VideoStreamEncoderResourceManager::GetReasonFromResource( rtc::scoped_refptr resource) const { - MutexLock lock(&resource_lock_); - const auto& registered_resource = - absl::c_find_if(resources_, [&resource](const ResourceAndReason& r) { - return r.resource == resource; - }); + RTC_DCHECK_RUN_ON(encoder_queue_); + const auto& registered_resource = resources_.find(resource); RTC_DCHECK(registered_resource != resources_.end()) << resource->Name() << " not found."; - return registered_resource->reason; + return registered_resource->second; } // TODO(pbos): Lower these thresholds (to closer to 100%) when we handle @@ -598,28 +456,23 @@ void VideoStreamEncoderResourceManager::OnVideoSourceRestrictionsUpdated( const VideoAdaptationCounters& adaptation_counters, rtc::scoped_refptr reason, const VideoSourceRestrictions& unfiltered_restrictions) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_); // TODO(bugs.webrtc.org/11553) Remove reason parameter and add reset callback. if (!reason && adaptation_counters.Total() == 0) { // Adaptation was manually reset - clear the per-reason counters too. encoder_stats_observer_->ClearAdaptationStats(); } - // The VideoStreamEncoder makes the manager outlive the encoder queue. This - // means that if the task gets executed, |this| has not been freed yet. - encoder_queue_->PostTask([this, restrictions] { - RTC_DCHECK_RUN_ON(encoder_queue_); - video_source_restrictions_ = FilterRestrictionsByDegradationPreference( - restrictions, degradation_preference_); - MaybeUpdateTargetFrameRate(); - }); + video_source_restrictions_ = FilterRestrictionsByDegradationPreference( + restrictions, degradation_preference_); + MaybeUpdateTargetFrameRate(); } void VideoStreamEncoderResourceManager::OnResourceLimitationChanged( rtc::scoped_refptr resource, const std::map, VideoAdaptationCounters>& resource_limitations) { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_); if (!resource) { encoder_stats_observer_->ClearAdaptationStats(); return; @@ -641,19 +494,14 @@ void VideoStreamEncoderResourceManager::OnResourceLimitationChanged( adaptation_reason, limitations[VideoAdaptationReason::kCpu], limitations[VideoAdaptationReason::kQuality]); - encoder_queue_->PostTask(ToQueuedTask( - [cpu_limited = limitations.at(VideoAdaptationReason::kCpu).Total() > 0, - qp_resolution_adaptations = - limitations.at(VideoAdaptationReason::kQuality) - .resolution_adaptations, - this]() { - RTC_DCHECK_RUN_ON(encoder_queue_); - if (quality_rampup_experiment_) { - quality_rampup_experiment_->cpu_adapted(cpu_limited); - quality_rampup_experiment_->qp_resolution_adaptations( - qp_resolution_adaptations); - } - })); + if (quality_rampup_experiment_) { + bool cpu_limited = limitations.at(VideoAdaptationReason::kCpu).Total() > 0; + auto qp_resolution_adaptations = + limitations.at(VideoAdaptationReason::kQuality).resolution_adaptations; + quality_rampup_experiment_->cpu_adapted(cpu_limited); + quality_rampup_experiment_->qp_resolution_adaptations( + qp_resolution_adaptations); + } RTC_LOG(LS_INFO) << ActiveCountsToString(limitations); } @@ -716,19 +564,7 @@ std::string VideoStreamEncoderResourceManager::ActiveCountsToString( void VideoStreamEncoderResourceManager::OnQualityRampUp() { RTC_DCHECK_RUN_ON(encoder_queue_); - // The VideoStreamEncoder makes the manager outlive the adaptation queue. - // This means that if the task gets executed, |this| has not been freed yet. - // TODO(https://crbug.com/webrtc/11565): When the manager no longer outlives - // the adaptation queue, add logic to prevent use-after-free on |this|. - resource_adaptation_queue_->PostTask([this] { - RTC_DCHECK_RUN_ON(resource_adaptation_queue_); - if (!stream_adapter_) { - // The processor nulled before this task had a chance to execute. This - // happens if the processor is destroyed. No action needed. - return; - } - stream_adapter_->ClearRestrictions(); - }); + stream_adapter_->ClearRestrictions(); quality_rampup_experiment_.reset(); } } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.h b/TMessagesProj/jni/voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.h index 10d0e66c1..932d90c20 100644 --- a/TMessagesProj/jni/voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.h +++ b/TMessagesProj/jni/voip/webrtc/video/adaptation/video_stream_encoder_resource_manager.h @@ -40,7 +40,10 @@ #include "rtc_base/strings/string_builder.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/task_queue.h" +#include "rtc_base/thread_annotations.h" #include "system_wrappers/include/clock.h" +#include "video/adaptation/balanced_constraint.h" +#include "video/adaptation/bitrate_constraint.h" #include "video/adaptation/encode_usage_resource.h" #include "video/adaptation/overuse_frame_detector.h" #include "video/adaptation/quality_rampup_experiment_helper.h" @@ -77,8 +80,7 @@ class VideoStreamEncoderResourceManager DegradationPreferenceProvider* degradation_preference_provider); ~VideoStreamEncoderResourceManager() override; - void Initialize(rtc::TaskQueue* encoder_queue, - rtc::TaskQueue* resource_adaptation_queue); + void Initialize(rtc::TaskQueue* encoder_queue); void SetAdaptationProcessor( ResourceAdaptationProcessorInterface* adaptation_processor, VideoStreamAdapter* stream_adapter); @@ -115,12 +117,10 @@ class VideoStreamEncoderResourceManager // Resources need to be mapped to an AdaptReason (kCpu or kQuality) in order // to update legacy getStats(). - void MapResourceToReason(rtc::scoped_refptr resource, - VideoAdaptationReason reason); - std::vector> MappedResources() const; + void AddResource(rtc::scoped_refptr resource, + VideoAdaptationReason reason); + void RemoveResource(rtc::scoped_refptr resource); std::vector AdaptationConstraints() const; - rtc::scoped_refptr - quality_scaler_resource_for_testing(); // If true, the VideoStreamEncoder should eexecute its logic to maybe drop // frames baseed on size and bitrate. bool DropInitialFrames() const; @@ -163,84 +163,19 @@ class VideoStreamEncoderResourceManager const std::map& active_counts); - // TODO(hbos): Add tests for manager's constraints. - // Does not trigger adaptations, only prevents adapting up resolution. - class BitrateConstraint : public rtc::RefCountInterface, - public AdaptationConstraint { - public: - explicit BitrateConstraint(VideoStreamEncoderResourceManager* manager); - ~BitrateConstraint() override = default; - - void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue); - void OnEncoderSettingsUpdated( - absl::optional encoder_settings); - void OnEncoderTargetBitrateUpdated( - absl::optional encoder_target_bitrate_bps); - - // AdaptationConstraint implementation. - std::string Name() const override { return "BitrateConstraint"; } - bool IsAdaptationUpAllowed( - const VideoStreamInputState& input_state, - const VideoSourceRestrictions& restrictions_before, - const VideoSourceRestrictions& restrictions_after, - rtc::scoped_refptr reason_resource) const override; - - private: - // The |manager_| must be alive as long as this resource is added to the - // ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called. - VideoStreamEncoderResourceManager* const manager_; - TaskQueueBase* resource_adaptation_queue_; - absl::optional encoder_settings_ - RTC_GUARDED_BY(resource_adaptation_queue_); - absl::optional encoder_target_bitrate_bps_ - RTC_GUARDED_BY(resource_adaptation_queue_); - }; - - // Does not trigger adaptations, only prevents adapting up in BALANCED. - class BalancedConstraint : public rtc::RefCountInterface, - public AdaptationConstraint { - public: - BalancedConstraint( - VideoStreamEncoderResourceManager* manager, - DegradationPreferenceProvider* degradation_preference_provider); - ~BalancedConstraint() override = default; - - void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue); - void OnEncoderTargetBitrateUpdated( - absl::optional encoder_target_bitrate_bps); - - // AdaptationConstraint implementation. - std::string Name() const override { return "BalancedConstraint"; } - bool IsAdaptationUpAllowed( - const VideoStreamInputState& input_state, - const VideoSourceRestrictions& restrictions_before, - const VideoSourceRestrictions& restrictions_after, - rtc::scoped_refptr reason_resource) const override; - - private: - // The |manager_| must be alive as long as this resource is added to the - // ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called. - VideoStreamEncoderResourceManager* const manager_; - TaskQueueBase* resource_adaptation_queue_; - absl::optional encoder_target_bitrate_bps_ - RTC_GUARDED_BY(resource_adaptation_queue_); - DegradationPreferenceProvider* degradation_preference_provider_; - }; - DegradationPreferenceProvider* const degradation_preference_provider_; - const rtc::scoped_refptr bitrate_constraint_; - const rtc::scoped_refptr balanced_constraint_; + std::unique_ptr bitrate_constraint_ + RTC_GUARDED_BY(encoder_queue_); + const std::unique_ptr balanced_constraint_ + RTC_GUARDED_BY(encoder_queue_); const rtc::scoped_refptr encode_usage_resource_; const rtc::scoped_refptr quality_scaler_resource_; rtc::TaskQueue* encoder_queue_; - rtc::TaskQueue* resource_adaptation_queue_; VideoStreamInputStateProvider* const input_state_provider_ RTC_GUARDED_BY(encoder_queue_); - ResourceAdaptationProcessorInterface* adaptation_processor_ - RTC_GUARDED_BY(resource_adaptation_queue_); - VideoStreamAdapter* stream_adapter_ - RTC_GUARDED_BY(resource_adaptation_queue_); + ResourceAdaptationProcessorInterface* adaptation_processor_; + VideoStreamAdapter* stream_adapter_ RTC_GUARDED_BY(encoder_queue_); // Thread-safe. VideoStreamEncoderObserver* const encoder_stats_observer_; @@ -265,17 +200,8 @@ class VideoStreamEncoderResourceManager // Ties a resource to a reason for statistical reporting. This AdaptReason is // also used by this module to make decisions about how to adapt up/down. - struct ResourceAndReason { - ResourceAndReason(rtc::scoped_refptr resource, - VideoAdaptationReason reason) - : resource(resource), reason(reason) {} - virtual ~ResourceAndReason() = default; - - const rtc::scoped_refptr resource; - const VideoAdaptationReason reason; - }; - mutable Mutex resource_lock_; - std::vector resources_ RTC_GUARDED_BY(&resource_lock_); + std::map, VideoAdaptationReason> resources_ + RTC_GUARDED_BY(encoder_queue_); }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/video/alignment_adjuster.cc b/TMessagesProj/jni/voip/webrtc/video/alignment_adjuster.cc new file mode 100644 index 000000000..b08f2f184 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/video/alignment_adjuster.cc @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2020 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 "video/alignment_adjuster.h" + +#include +#include + +#include "absl/algorithm/container.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace { +// Round each scale factor to the closest rational in form alignment/i where i +// is a multiple of |requested_alignment|. Each resolution divisible by +// |alignment| will be divisible by |requested_alignment| after the scale factor +// is applied. +double RoundToMultiple(int alignment, + int requested_alignment, + VideoEncoderConfig* config, + bool update_config) { + double diff = 0.0; + for (auto& layer : config->simulcast_layers) { + double min_dist = std::numeric_limits::max(); + double new_scale = 1.0; + for (int i = requested_alignment; i <= alignment; + i += requested_alignment) { + double dist = std::abs(layer.scale_resolution_down_by - + alignment / static_cast(i)); + if (dist <= min_dist) { + min_dist = dist; + new_scale = alignment / static_cast(i); + } + } + diff += std::abs(layer.scale_resolution_down_by - new_scale); + if (update_config) { + RTC_LOG(LS_INFO) << "scale_resolution_down_by " + << layer.scale_resolution_down_by << " -> " << new_scale; + layer.scale_resolution_down_by = new_scale; + } + } + return diff; +} +} // namespace + +// Input: encoder_info.requested_resolution_alignment (K) +// Input: encoder_info.apply_alignment_to_all_simulcast_layers (B) +// Input: vector config->simulcast_layers.scale_resolution_down_by (S[i]) +// Output: +// If B is false, returns K and does not adjust scaling factors. +// Otherwise, returns adjusted alignment (A), adjusted scaling factors (S'[i]) +// are written in |config| such that: +// +// A / S'[i] are integers divisible by K +// sum abs(S'[i] - S[i]) -> min +// A integer <= 16 +// +// Solution chooses closest S'[i] in a form A / j where j is a multiple of K. + +int AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors( + const VideoEncoder::EncoderInfo& encoder_info, + VideoEncoderConfig* config) { + const int requested_alignment = encoder_info.requested_resolution_alignment; + if (!encoder_info.apply_alignment_to_all_simulcast_layers) { + return requested_alignment; + } + + if (requested_alignment < 1 || config->number_of_streams <= 1 || + config->simulcast_layers.size() <= 1) { + return requested_alignment; + } + + // Update alignment to also apply to simulcast layers. + const bool has_scale_resolution_down_by = absl::c_any_of( + config->simulcast_layers, [](const webrtc::VideoStream& layer) { + return layer.scale_resolution_down_by >= 1.0; + }); + + if (!has_scale_resolution_down_by) { + // Default resolution downscaling used (scale factors: 1, 2, 4, ...). + return requested_alignment * (1 << (config->simulcast_layers.size() - 1)); + } + + // Get alignment for downscaled layers. + // Adjust |scale_resolution_down_by| to a common multiple to limit the + // alignment value (to avoid largely cropped frames and possibly with an + // aspect ratio far from the original). + const int kMaxAlignment = 16; + + for (auto& layer : config->simulcast_layers) { + layer.scale_resolution_down_by = + std::max(layer.scale_resolution_down_by, 1.0); + layer.scale_resolution_down_by = + std::min(layer.scale_resolution_down_by, 10000.0); + } + + // Decide on common multiple to use. + double min_diff = std::numeric_limits::max(); + int best_alignment = 1; + for (int alignment = requested_alignment; alignment <= kMaxAlignment; + ++alignment) { + double diff = RoundToMultiple(alignment, requested_alignment, config, + /*update_config=*/false); + if (diff < min_diff) { + min_diff = diff; + best_alignment = alignment; + } + } + RoundToMultiple(best_alignment, requested_alignment, config, + /*update_config=*/true); + + return std::max(best_alignment, requested_alignment); +} +} // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/video/alignment_adjuster.h b/TMessagesProj/jni/voip/webrtc/video/alignment_adjuster.h new file mode 100644 index 000000000..53d792788 --- /dev/null +++ b/TMessagesProj/jni/voip/webrtc/video/alignment_adjuster.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef VIDEO_ALIGNMENT_ADJUSTER_H_ +#define VIDEO_ALIGNMENT_ADJUSTER_H_ + +#include "api/video_codecs/video_encoder.h" +#include "api/video_codecs/video_encoder_config.h" + +namespace webrtc { + +class AlignmentAdjuster { + public: + // Returns the resolution alignment requested by the encoder (i.e + // |EncoderInfo::requested_resolution_alignment| which ensures that delivered + // frames to the encoder are divisible by this alignment). + // + // If |EncoderInfo::apply_alignment_to_all_simulcast_layers| is enabled, the + // alignment will be adjusted to ensure that each simulcast layer also is + // divisible by |requested_resolution_alignment|. The configured scale factors + // |scale_resolution_down_by| may be adjusted to a common multiple to limit + // the alignment value to avoid largely cropped frames and possibly with an + // aspect ratio far from the original. + static int GetAlignmentAndMaybeAdjustScaleFactors( + const VideoEncoder::EncoderInfo& info, + VideoEncoderConfig* config); +}; + +} // namespace webrtc + +#endif // VIDEO_ALIGNMENT_ADJUSTER_H_ diff --git a/TMessagesProj/jni/voip/webrtc/video/buffered_frame_decryptor.cc b/TMessagesProj/jni/voip/webrtc/video/buffered_frame_decryptor.cc index fc9dff5b0..187bac6ee 100644 --- a/TMessagesProj/jni/voip/webrtc/video/buffered_frame_decryptor.cc +++ b/TMessagesProj/jni/voip/webrtc/video/buffered_frame_decryptor.cc @@ -73,7 +73,7 @@ BufferedFrameDecryptor::FrameDecision BufferedFrameDecryptor::DecryptFrame( frame->size()); RTC_CHECK_LE(max_plaintext_byte_size, frame->size()); // Place the decrypted frame inline into the existing frame. - rtc::ArrayView inline_decrypted_bitstream(frame->data(), + rtc::ArrayView inline_decrypted_bitstream(frame->mutable_data(), max_plaintext_byte_size); // Enable authenticating the header if the field trial isn't disabled. diff --git a/TMessagesProj/jni/voip/webrtc/video/frame_encode_metadata_writer.cc b/TMessagesProj/jni/voip/webrtc/video/frame_encode_metadata_writer.cc index b30eeeace..0e604cd76 100644 --- a/TMessagesProj/jni/voip/webrtc/video/frame_encode_metadata_writer.cc +++ b/TMessagesProj/jni/voip/webrtc/video/frame_encode_metadata_writer.cc @@ -213,7 +213,7 @@ void FrameEncodeMetadataWriter::UpdateBitstream( // Make sure that the data is not copied if owned by EncodedImage. const EncodedImage& buffer = *encoded_image; rtc::Buffer modified_buffer = - SpsVuiRewriter::ParseOutgoingBitstreamAndRewriteSps( + SpsVuiRewriter::ParseOutgoingBitstreamAndRewrite( buffer, encoded_image->ColorSpace()); encoded_image->SetEncodedData( diff --git a/TMessagesProj/jni/voip/webrtc/video/full_stack_tests.cc b/TMessagesProj/jni/voip/webrtc/video/full_stack_tests.cc index a12b33423..ece756b2d 100644 --- a/TMessagesProj/jni/voip/webrtc/video/full_stack_tests.cc +++ b/TMessagesProj/jni/voip/webrtc/video/full_stack_tests.cc @@ -48,8 +48,6 @@ namespace webrtc { namespace { static const int kFullStackTestDurationSecs = 45; -const char kVp8TrustedRateControllerFieldTrial[] = - "WebRTC-LibvpxVp8TrustedRateController/Enabled/"; struct ParamsWithLogging : public VideoQualityTest::Params { public: @@ -91,7 +89,7 @@ std::string ClipNameToClipPath(const char* clip_name) { // }; #if defined(RTC_ENABLE_VP9) -TEST(FullStackTest, ForemanCifWithoutPacketLossVp9) { +TEST(FullStackTest, Foreman_Cif_Net_Delay_0_0_Plr_0_VP9) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -105,7 +103,8 @@ TEST(FullStackTest, ForemanCifWithoutPacketLossVp9) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(GenericDescriptorTest, ForemanCifPlr5Vp9) { +TEST(GenericDescriptorTest, + Foreman_Cif_Delay_50_0_Plr_5_VP9_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -122,7 +121,7 @@ TEST(GenericDescriptorTest, ForemanCifPlr5Vp9) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, GeneratorWithoutPacketLossVp9Profile2) { +TEST(FullStackTest, Generator_Net_Delay_0_0_Plr_0_VP9Profile2) { // Profile 2 might not be available on some platforms until // https://bugs.chromium.org/p/webm/issues/detail?id=1544 is solved. bool profile_2_is_supported = false; @@ -148,7 +147,7 @@ TEST(FullStackTest, GeneratorWithoutPacketLossVp9Profile2) { fixture->RunWithAnalyzer(generator); } -TEST(FullStackTest, ForemanCifWithoutPacketLossMultiplexI420Frame) { +TEST(FullStackTest, Foreman_Cif_Net_Delay_0_0_Plr_0_Multiplex) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -162,7 +161,7 @@ TEST(FullStackTest, ForemanCifWithoutPacketLossMultiplexI420Frame) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, GeneratorWithoutPacketLossMultiplexI420AFrame) { +TEST(FullStackTest, Generator_Net_Delay_0_0_Plr_0_Multiplex) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging generator; @@ -179,11 +178,11 @@ TEST(FullStackTest, GeneratorWithoutPacketLossMultiplexI420AFrame) { #if defined(WEBRTC_LINUX) // Crashes on the linux trusty perf bot: bugs.webrtc.org/9129. -#define MAYBE_ParisQcifWithoutPacketLoss DISABLED_ParisQcifWithoutPacketLoss +#define MAYBE_Net_Delay_0_0_Plr_0 DISABLED_Net_Delay_0_0_Plr_0 #else -#define MAYBE_ParisQcifWithoutPacketLoss ParisQcifWithoutPacketLoss +#define MAYBE_Net_Delay_0_0_Plr_0 Net_Delay_0_0_Plr_0 #endif -TEST(FullStackTest, MAYBE_ParisQcifWithoutPacketLoss) { +TEST(FullStackTest, MAYBE_Net_Delay_0_0_Plr_0) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging paris_qcif; paris_qcif.call.send_side_bwe = true; @@ -197,7 +196,8 @@ TEST(FullStackTest, MAYBE_ParisQcifWithoutPacketLoss) { fixture->RunWithAnalyzer(paris_qcif); } -TEST(GenericDescriptorTest, ForemanCifWithoutPacketLoss) { +TEST(GenericDescriptorTest, + Foreman_Cif_Net_Delay_0_0_Plr_0_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); // TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif. ParamsWithLogging foreman_cif; @@ -213,7 +213,8 @@ TEST(GenericDescriptorTest, ForemanCifWithoutPacketLoss) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(GenericDescriptorTest, ForemanCif30kbpsWithoutPacketLoss) { +TEST(GenericDescriptorTest, + Foreman_Cif_30kbps_Net_Delay_0_0_Plr_0_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -229,30 +230,8 @@ TEST(GenericDescriptorTest, ForemanCif30kbpsWithoutPacketLoss) { fixture->RunWithAnalyzer(foreman_cif); } -// TODO(webrtc:9722): Remove when experiment is cleaned up. -TEST(GenericDescriptorTest, - ForemanCif30kbpsWithoutPacketLossTrustedRateControl) { - test::ScopedFieldTrials override_field_trials( - AppendFieldTrials(kVp8TrustedRateControllerFieldTrial)); - auto fixture = CreateVideoQualityTestFixture(); - - ParamsWithLogging foreman_cif; - foreman_cif.call.send_side_bwe = true; - foreman_cif.video[0] = { - true, 352, 288, 10, - 30000, 30000, 30000, false, - "VP8", 1, 0, 0, - false, false, true, ClipNameToClipPath("foreman_cif")}; - foreman_cif.analyzer = { - "foreman_cif_30kbps_net_delay_0_0_plr_0_trusted_rate_ctrl_generic_" - "descriptor", - 0.0, 0.0, kFullStackTestDurationSecs}; - foreman_cif.call.generic_descriptor = true; - fixture->RunWithAnalyzer(foreman_cif); -} - // Link capacity below default start rate. -TEST(FullStackTest, ForemanCifLink150kbpsWithoutPacketLoss) { +TEST(FullStackTest, Foreman_Cif_Link_150kbps_Net_Delay_0_0_Plr_0) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -268,7 +247,8 @@ TEST(FullStackTest, ForemanCifLink150kbpsWithoutPacketLoss) { } // Restricted network and encoder overproducing by 30%. -TEST(FullStackTest, ForemanCifLink150kbpsBadRateController) { +TEST(FullStackTest, + Foreman_Cif_Link_150kbps_Delay100ms_30pkts_Queue_Overshoot30) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -291,7 +271,7 @@ TEST(FullStackTest, ForemanCifLink150kbpsBadRateController) { // Packet rate and loss are low enough that loss will happen with ~3s interval. // This triggers protection overhead to toggle between zero and non-zero. // Link queue is restrictive enough to trigger loss on probes. -TEST(FullStackTest, ForemanCifMediaCapacitySmallLossAndQueue) { +TEST(FullStackTest, Foreman_Cif_Link_250kbps_Delay100ms_10pkts_Loss1) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -310,7 +290,7 @@ TEST(FullStackTest, ForemanCifMediaCapacitySmallLossAndQueue) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(GenericDescriptorTest, ForemanCifPlr5) { +TEST(GenericDescriptorTest, Foreman_Cif_Delay_50_0_Plr_5_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -327,7 +307,8 @@ TEST(GenericDescriptorTest, ForemanCifPlr5) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(GenericDescriptorTest, ForemanCifPlr5Ulpfec) { +TEST(GenericDescriptorTest, + Foreman_Cif_Delay_50_0_Plr_5_Ulpfec_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -345,7 +326,7 @@ TEST(GenericDescriptorTest, ForemanCifPlr5Ulpfec) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCifPlr5Flexfec) { +TEST(FullStackTest, Foreman_Cif_Delay_50_0_Plr_5_Flexfec) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -361,7 +342,7 @@ TEST(FullStackTest, ForemanCifPlr5Flexfec) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCif500kbpsPlr3Flexfec) { +TEST(FullStackTest, Foreman_Cif_500kbps_Delay_50_0_Plr_3_Flexfec) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -378,7 +359,7 @@ TEST(FullStackTest, ForemanCif500kbpsPlr3Flexfec) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCif500kbpsPlr3Ulpfec) { +TEST(FullStackTest, Foreman_Cif_500kbps_Delay_50_0_Plr_3_Ulpfec) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -396,7 +377,7 @@ TEST(FullStackTest, ForemanCif500kbpsPlr3Ulpfec) { } #if defined(WEBRTC_USE_H264) -TEST(FullStackTest, ForemanCifWithoutPacketlossH264) { +TEST(FullStackTest, Foreman_Cif_Net_Delay_0_0_Plr_0_H264) { auto fixture = CreateVideoQualityTestFixture(); // TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif. ParamsWithLogging foreman_cif; @@ -411,7 +392,7 @@ TEST(FullStackTest, ForemanCifWithoutPacketlossH264) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCif30kbpsWithoutPacketlossH264) { +TEST(FullStackTest, Foreman_Cif_30kbps_Net_Delay_0_0_Plr_0_H264) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -425,7 +406,8 @@ TEST(FullStackTest, ForemanCif30kbpsWithoutPacketlossH264) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(GenericDescriptorTest, ForemanCifPlr5H264) { +TEST(GenericDescriptorTest, + Foreman_Cif_Delay_50_0_Plr_5_H264_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -443,7 +425,7 @@ TEST(GenericDescriptorTest, ForemanCifPlr5H264) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCifPlr5H264SpsPpsIdrIsKeyframe) { +TEST(FullStackTest, Foreman_Cif_Delay_50_0_Plr_5_H264_Sps_Pps_Idr) { test::ScopedFieldTrials override_field_trials( AppendFieldTrials("WebRTC-SpsPpsIdrIsH264Keyframe/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); @@ -463,7 +445,7 @@ TEST(FullStackTest, ForemanCifPlr5H264SpsPpsIdrIsKeyframe) { } // Verify that this is worth the bot time, before enabling. -TEST(FullStackTest, ForemanCifPlr5H264Flexfec) { +TEST(FullStackTest, Foreman_Cif_Delay_50_0_Plr_5_H264_Flexfec) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -481,7 +463,7 @@ TEST(FullStackTest, ForemanCifPlr5H264Flexfec) { // Ulpfec with H264 is an unsupported combination, so this test is only useful // for debugging. It is therefore disabled by default. -TEST(FullStackTest, DISABLED_ForemanCifPlr5H264Ulpfec) { +TEST(FullStackTest, DISABLED_Foreman_Cif_Delay_50_0_Plr_5_H264_Ulpfec) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -498,7 +480,7 @@ TEST(FullStackTest, DISABLED_ForemanCifPlr5H264Ulpfec) { } #endif // defined(WEBRTC_USE_H264) -TEST(FullStackTest, ForemanCif500kbps) { +TEST(FullStackTest, Foreman_Cif_500kbps) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -515,7 +497,7 @@ TEST(FullStackTest, ForemanCif500kbps) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCif500kbpsLimitedQueue) { +TEST(FullStackTest, Foreman_Cif_500kbps_32pkts_Queue) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -532,7 +514,7 @@ TEST(FullStackTest, ForemanCif500kbpsLimitedQueue) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCif500kbps100ms) { +TEST(FullStackTest, Foreman_Cif_500kbps_100ms) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -549,7 +531,8 @@ TEST(FullStackTest, ForemanCif500kbps100ms) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(GenericDescriptorTest, ForemanCif500kbps100msLimitedQueue) { +TEST(GenericDescriptorTest, + Foreman_Cif_500kbps_100ms_32pkts_Queue_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -568,7 +551,7 @@ TEST(GenericDescriptorTest, ForemanCif500kbps100msLimitedQueue) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCif500kbps100msLimitedQueueRecvBwe) { +TEST(FullStackTest, Foreman_Cif_500kbps_100ms_32pkts_Queue_Recv_Bwe) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = false; @@ -585,7 +568,7 @@ TEST(FullStackTest, ForemanCif500kbps100msLimitedQueueRecvBwe) { fixture->RunWithAnalyzer(foreman_cif); } -TEST(FullStackTest, ForemanCif1000kbps100msLimitedQueue) { +TEST(FullStackTest, Foreman_Cif_1000kbps_100ms_32pkts_Queue) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging foreman_cif; foreman_cif.call.send_side_bwe = true; @@ -603,7 +586,7 @@ TEST(FullStackTest, ForemanCif1000kbps100msLimitedQueue) { } // TODO(sprang): Remove this if we have the similar ModerateLimits below? -TEST(FullStackTest, ConferenceMotionHd2000kbps100msLimitedQueue) { +TEST(FullStackTest, Conference_Motion_Hd_2000kbps_100ms_32pkts_Queue) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging conf_motion_hd; conf_motion_hd.call.send_side_bwe = true; @@ -624,34 +607,8 @@ TEST(FullStackTest, ConferenceMotionHd2000kbps100msLimitedQueue) { fixture->RunWithAnalyzer(conf_motion_hd); } -// TODO(webrtc:9722): Remove when experiment is cleaned up. -TEST(FullStackTest, ConferenceMotionHd1TLModerateLimitsWhitelistVp8) { - test::ScopedFieldTrials override_field_trials( - AppendFieldTrials(kVp8TrustedRateControllerFieldTrial)); - auto fixture = CreateVideoQualityTestFixture(); - - ParamsWithLogging conf_motion_hd; - conf_motion_hd.call.send_side_bwe = true; - conf_motion_hd.video[0] = { - true, 1280, - 720, 50, - 30000, 3000000, - 3000000, false, - "VP8", 1, - -1, 0, - false, false, - false, ClipNameToClipPath("ConferenceMotion_1280_720_50")}; - conf_motion_hd.analyzer = { - "conference_motion_hd_1tl_moderate_limits_trusted_rate_ctrl", 0.0, 0.0, - kFullStackTestDurationSecs}; - conf_motion_hd.config->queue_length_packets = 50; - conf_motion_hd.config->loss_percent = 3; - conf_motion_hd.config->queue_delay_ms = 100; - conf_motion_hd.config->link_capacity_kbps = 2000; - fixture->RunWithAnalyzer(conf_motion_hd); -} - -TEST(GenericDescriptorTest, ConferenceMotionHd2TLModerateLimits) { +TEST(GenericDescriptorTest, + Conference_Motion_Hd_2tl_Moderate_Limits_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging conf_motion_hd; conf_motion_hd.call.send_side_bwe = true; @@ -675,7 +632,7 @@ TEST(GenericDescriptorTest, ConferenceMotionHd2TLModerateLimits) { fixture->RunWithAnalyzer(conf_motion_hd); } -TEST(FullStackTest, ConferenceMotionHd3TLModerateLimits) { +TEST(FullStackTest, Conference_Motion_Hd_3tl_Moderate_Limits) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging conf_motion_hd; conf_motion_hd.call.send_side_bwe = true; @@ -697,7 +654,7 @@ TEST(FullStackTest, ConferenceMotionHd3TLModerateLimits) { fixture->RunWithAnalyzer(conf_motion_hd); } -TEST(FullStackTest, ConferenceMotionHd4TLModerateLimits) { +TEST(FullStackTest, Conference_Motion_Hd_4tl_Moderate_Limits) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging conf_motion_hd; conf_motion_hd.call.send_side_bwe = true; @@ -719,7 +676,7 @@ TEST(FullStackTest, ConferenceMotionHd4TLModerateLimits) { fixture->RunWithAnalyzer(conf_motion_hd); } -TEST(FullStackTest, ConferenceMotionHd3TLModerateLimitsAltTLPattern) { +TEST(FullStackTest, Conference_Motion_Hd_3tl_Alt_Moderate_Limits) { test::ScopedFieldTrials field_trial( AppendFieldTrials("WebRTC-UseShortVP8TL3Pattern/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); @@ -743,8 +700,7 @@ TEST(FullStackTest, ConferenceMotionHd3TLModerateLimitsAltTLPattern) { fixture->RunWithAnalyzer(conf_motion_hd); } -TEST(FullStackTest, - ConferenceMotionHd3TLModerateLimitsAltTLPatternAndBaseHeavyTLAllocation) { +TEST(FullStackTest, Conference_Motion_Hd_3tl_Alt_Heavy_Moderate_Limits) { auto fixture = CreateVideoQualityTestFixture(); test::ScopedFieldTrials field_trial( AppendFieldTrials("WebRTC-UseShortVP8TL3Pattern/Enabled/" @@ -771,7 +727,7 @@ TEST(FullStackTest, } #if defined(RTC_ENABLE_VP9) -TEST(FullStackTest, ConferenceMotionHd2000kbps100msLimitedQueueVP9) { +TEST(FullStackTest, Conference_Motion_Hd_2000kbps_100ms_32pkts_Queue_Vp9) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging conf_motion_hd; conf_motion_hd.call.send_side_bwe = true; @@ -794,7 +750,7 @@ TEST(FullStackTest, ConferenceMotionHd2000kbps100msLimitedQueueVP9) { } #endif -TEST(FullStackTest, ScreenshareSlidesVP8_2TL) { +TEST(FullStackTest, Screenshare_Slides) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging screenshare; screenshare.call.send_side_bwe = true; @@ -809,7 +765,7 @@ TEST(FullStackTest, ScreenshareSlidesVP8_2TL) { #if !defined(WEBRTC_MAC) && !defined(WEBRTC_WIN) // TODO(bugs.webrtc.org/9840): Investigate why is this test flaky on Win/Mac. -TEST(FullStackTest, ScreenshareSlidesVP8_2TL_Simulcast) { +TEST(FullStackTest, Screenshare_Slides_Simulcast) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging screenshare; screenshare.call.send_side_bwe = true; @@ -839,7 +795,7 @@ TEST(FullStackTest, ScreenshareSlidesVP8_2TL_Simulcast) { #endif // !defined(WEBRTC_MAC) && !defined(WEBRTC_WIN) -TEST(FullStackTest, ScreenshareSlidesVP8_2TL_Scroll) { +TEST(FullStackTest, Screenshare_Slides_Scrolling) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging config; config.call.send_side_bwe = true; @@ -852,7 +808,7 @@ TEST(FullStackTest, ScreenshareSlidesVP8_2TL_Scroll) { fixture->RunWithAnalyzer(config); } -TEST(GenericDescriptorTest, ScreenshareSlidesVP8_2TL_LossyNet) { +TEST(GenericDescriptorTest, Screenshare_Slides_Lossy_Net_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging screenshare; screenshare.call.send_side_bwe = true; @@ -869,7 +825,7 @@ TEST(GenericDescriptorTest, ScreenshareSlidesVP8_2TL_LossyNet) { fixture->RunWithAnalyzer(screenshare); } -TEST(FullStackTest, ScreenshareSlidesVP8_2TL_VeryLossyNet) { +TEST(FullStackTest, Screenshare_Slides_Very_Lossy) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging screenshare; screenshare.call.send_side_bwe = true; @@ -885,7 +841,7 @@ TEST(FullStackTest, ScreenshareSlidesVP8_2TL_VeryLossyNet) { fixture->RunWithAnalyzer(screenshare); } -TEST(FullStackTest, ScreenshareSlidesVP8_2TL_LossyNetRestrictedQueue) { +TEST(FullStackTest, Screenshare_Slides_Lossy_Limited) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging screenshare; screenshare.call.send_side_bwe = true; @@ -902,7 +858,7 @@ TEST(FullStackTest, ScreenshareSlidesVP8_2TL_LossyNetRestrictedQueue) { fixture->RunWithAnalyzer(screenshare); } -TEST(FullStackTest, ScreenshareSlidesVP8_2TL_ModeratelyRestricted) { +TEST(FullStackTest, Screenshare_Slides_Moderately_Restricted) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging screenshare; screenshare.call.send_side_bwe = true; @@ -971,7 +927,7 @@ ParamsWithLogging::Video SimulcastVp8VideoLow() { #if defined(RTC_ENABLE_VP9) -TEST(FullStackTest, ScreenshareSlidesVP9_3SL_High_Fps) { +TEST(FullStackTest, Screenshare_Slides_Vp9_3sl_High_Fps) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging screenshare; screenshare.call.send_side_bwe = true; @@ -990,7 +946,7 @@ TEST(FullStackTest, ScreenshareSlidesVP9_3SL_High_Fps) { // TODO(http://bugs.webrtc.org/9506): investigate. #if !defined(WEBRTC_MAC) -TEST(FullStackTest, VP9KSVC_3SL_High) { +TEST(FullStackTest, Vp9ksvc_3sl_High) { webrtc::test::ScopedFieldTrials override_trials( AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); @@ -1005,7 +961,7 @@ TEST(FullStackTest, VP9KSVC_3SL_High) { fixture->RunWithAnalyzer(simulcast); } -TEST(FullStackTest, VP9KSVC_3SL_Low) { +TEST(FullStackTest, Vp9ksvc_3sl_Low) { webrtc::test::ScopedFieldTrials override_trials( AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); @@ -1020,7 +976,7 @@ TEST(FullStackTest, VP9KSVC_3SL_Low) { fixture->RunWithAnalyzer(simulcast); } -TEST(FullStackTest, VP9KSVC_3SL_Low_Bw_Limited) { +TEST(FullStackTest, Vp9ksvc_3sl_Low_Bw_Limited) { webrtc::test::ScopedFieldTrials override_trials( AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/" "WebRTC-Vp9ExternalRefCtrl/Enabled/")); @@ -1037,7 +993,7 @@ TEST(FullStackTest, VP9KSVC_3SL_Low_Bw_Limited) { fixture->RunWithAnalyzer(simulcast); } -TEST(FullStackTest, VP9KSVC_3SL_Medium_Network_Restricted) { +TEST(FullStackTest, Vp9ksvc_3sl_Medium_Network_Restricted) { webrtc::test::ScopedFieldTrials override_trials( AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); @@ -1055,10 +1011,9 @@ TEST(FullStackTest, VP9KSVC_3SL_Medium_Network_Restricted) { } // TODO(webrtc:9722): Remove when experiment is cleaned up. -TEST(FullStackTest, VP9KSVC_3SL_Medium_Network_Restricted_Trusted_Rate) { +TEST(FullStackTest, Vp9ksvc_3sl_Medium_Network_Restricted_Trusted_Rate) { webrtc::test::ScopedFieldTrials override_trials( - AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/" - "WebRTC-LibvpxVp9TrustedRateController/Enabled/")); + AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -1079,12 +1034,12 @@ TEST(FullStackTest, VP9KSVC_3SL_Medium_Network_Restricted_Trusted_Rate) { // Android bots can't handle FullHD, so disable the test. // TODO(bugs.webrtc.org/9220): Investigate source of flakiness on Mac. #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) -#define MAYBE_SimulcastFullHdOveruse DISABLED_SimulcastFullHdOveruse +#define MAYBE_Simulcast_HD_High DISABLED_Simulcast_HD_High #else -#define MAYBE_SimulcastFullHdOveruse SimulcastFullHdOveruse +#define MAYBE_Simulcast_HD_High Simulcast_HD_High #endif -TEST(FullStackTest, MAYBE_SimulcastFullHdOveruse) { +TEST(FullStackTest, MAYBE_Simulcast_HD_High) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -1107,7 +1062,7 @@ TEST(FullStackTest, MAYBE_SimulcastFullHdOveruse) { fixture->RunWithAnalyzer(simulcast); } -TEST(FullStackTest, SimulcastVP8_3SL_High) { +TEST(FullStackTest, Simulcast_Vp8_3sl_High) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -1133,7 +1088,7 @@ TEST(FullStackTest, SimulcastVP8_3SL_High) { fixture->RunWithAnalyzer(simulcast); } -TEST(FullStackTest, SimulcastVP8_3SL_Low) { +TEST(FullStackTest, Simulcast_Vp8_3sl_Low) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -1163,11 +1118,11 @@ TEST(FullStackTest, SimulcastVP8_3SL_Low) { // available and exercises WebRTC calls with a high target bitrate(100 Mbps). // Android32 bots can't handle this high bitrate, so disable test for those. #if defined(WEBRTC_ANDROID) -#define MAYBE_HighBitrateWithFakeCodec DISABLED_HighBitrateWithFakeCodec +#define MAYBE_High_Bitrate_With_Fake_Codec DISABLED_High_Bitrate_With_Fake_Codec #else -#define MAYBE_HighBitrateWithFakeCodec HighBitrateWithFakeCodec +#define MAYBE_High_Bitrate_With_Fake_Codec High_Bitrate_With_Fake_Codec #endif // defined(WEBRTC_ANDROID) -TEST(FullStackTest, MAYBE_HighBitrateWithFakeCodec) { +TEST(FullStackTest, MAYBE_High_Bitrate_With_Fake_Codec) { auto fixture = CreateVideoQualityTestFixture(); const int target_bitrate = 100000000; ParamsWithLogging generator; @@ -1199,12 +1154,12 @@ TEST(FullStackTest, MAYBE_HighBitrateWithFakeCodec) { #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) // Fails on mobile devices: // https://bugs.chromium.org/p/webrtc/issues/detail?id=7301 -#define MAYBE_LargeRoomVP8_50thumb DISABLED_LargeRoomVP8_50thumb +#define MAYBE_Largeroom_50thumb DISABLED_Largeroom_50thumb #else -#define MAYBE_LargeRoomVP8_50thumb LargeRoomVP8_50thumb +#define MAYBE_Largeroom_50thumb Largeroom_50thumb #endif -TEST(FullStackTest, MAYBE_LargeRoomVP8_50thumb) { +TEST(FullStackTest, MAYBE_Largeroom_50thumb) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging large_room; large_room.call.send_side_bwe = true; diff --git a/TMessagesProj/jni/voip/webrtc/video/full_stack_tests_plot.py b/TMessagesProj/jni/voip/webrtc/video/full_stack_tests_plot.py index f50c297b1..c195b72a5 100755 --- a/TMessagesProj/jni/voip/webrtc/video/full_stack_tests_plot.py +++ b/TMessagesProj/jni/voip/webrtc/video/full_stack_tests_plot.py @@ -6,7 +6,6 @@ # 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. - """Generate graphs for data generated by loopback tests. Usage examples: @@ -34,14 +33,14 @@ import numpy # Fields DROPPED = 0 -INPUT_TIME = 1 # ms (timestamp) -SEND_TIME = 2 # ms (timestamp) -RECV_TIME = 3 # ms (timestamp) -RENDER_TIME = 4 # ms (timestamp) -ENCODED_FRAME_SIZE = 5 # bytes +INPUT_TIME = 1 # ms (timestamp) +SEND_TIME = 2 # ms (timestamp) +RECV_TIME = 3 # ms (timestamp) +RENDER_TIME = 4 # ms (timestamp) +ENCODED_FRAME_SIZE = 5 # bytes PSNR = 6 SSIM = 7 -ENCODE_TIME = 8 # ms (time interval) +ENCODE_TIME = 8 # ms (time interval) TOTAL_RAW_FIELDS = 9 @@ -78,111 +77,116 @@ _FIELDS = [ NAME_TO_ID = {field[1]: field[0] for field in _FIELDS} ID_TO_TITLE = {field[0]: field[2] for field in _FIELDS} + def FieldArgToId(arg): - if arg == "none": - return None - if arg in NAME_TO_ID: - return NAME_TO_ID[arg] - if arg + "_ms" in NAME_TO_ID: - return NAME_TO_ID[arg + "_ms"] - raise Exception("Unrecognized field name \"{}\"".format(arg)) + if arg == "none": + return None + if arg in NAME_TO_ID: + return NAME_TO_ID[arg] + if arg + "_ms" in NAME_TO_ID: + return NAME_TO_ID[arg + "_ms"] + raise Exception("Unrecognized field name \"{}\"".format(arg)) class PlotLine(object): - """Data for a single graph line.""" + """Data for a single graph line.""" - def __init__(self, label, values, flags): - self.label = label - self.values = values - self.flags = flags + def __init__(self, label, values, flags): + self.label = label + self.values = values + self.flags = flags class Data(object): - """Object representing one full stack test.""" + """Object representing one full stack test.""" - def __init__(self, filename): - self.title = "" - self.length = 0 - self.samples = defaultdict(list) + def __init__(self, filename): + self.title = "" + self.length = 0 + self.samples = defaultdict(list) - self._ReadSamples(filename) + self._ReadSamples(filename) - def _ReadSamples(self, filename): - """Reads graph data from the given file.""" - f = open(filename) - it = iter(f) + def _ReadSamples(self, filename): + """Reads graph data from the given file.""" + f = open(filename) + it = iter(f) - self.title = it.next().strip() - self.length = int(it.next()) - field_names = [name.strip() for name in it.next().split()] - field_ids = [NAME_TO_ID[name] for name in field_names] + self.title = it.next().strip() + self.length = int(it.next()) + field_names = [name.strip() for name in it.next().split()] + field_ids = [NAME_TO_ID[name] for name in field_names] - for field_id in field_ids: - self.samples[field_id] = [0.0] * self.length + for field_id in field_ids: + self.samples[field_id] = [0.0] * self.length - for sample_id in xrange(self.length): - for col, value in enumerate(it.next().split()): - self.samples[field_ids[col]][sample_id] = float(value) + for sample_id in xrange(self.length): + for col, value in enumerate(it.next().split()): + self.samples[field_ids[col]][sample_id] = float(value) - self._SubtractFirstInputTime() - self._GenerateAdditionalData() + self._SubtractFirstInputTime() + self._GenerateAdditionalData() - f.close() + f.close() - def _SubtractFirstInputTime(self): - offset = self.samples[INPUT_TIME][0] - for field in [INPUT_TIME, SEND_TIME, RECV_TIME, RENDER_TIME]: - if field in self.samples: - self.samples[field] = [x - offset for x in self.samples[field]] + def _SubtractFirstInputTime(self): + offset = self.samples[INPUT_TIME][0] + for field in [INPUT_TIME, SEND_TIME, RECV_TIME, RENDER_TIME]: + if field in self.samples: + self.samples[field] = [x - offset for x in self.samples[field]] - def _GenerateAdditionalData(self): - """Calculates sender time, receiver time etc. from the raw data.""" - s = self.samples - last_render_time = 0 - for field_id in [SENDER_TIME, RECEIVER_TIME, END_TO_END, RENDERED_DELTA]: - s[field_id] = [0] * self.length + def _GenerateAdditionalData(self): + """Calculates sender time, receiver time etc. from the raw data.""" + s = self.samples + last_render_time = 0 + for field_id in [ + SENDER_TIME, RECEIVER_TIME, END_TO_END, RENDERED_DELTA + ]: + s[field_id] = [0] * self.length - for k in range(self.length): - s[SENDER_TIME][k] = s[SEND_TIME][k] - s[INPUT_TIME][k] + for k in range(self.length): + s[SENDER_TIME][k] = s[SEND_TIME][k] - s[INPUT_TIME][k] - decoded_time = s[RENDER_TIME][k] - s[RECEIVER_TIME][k] = decoded_time - s[RECV_TIME][k] - s[END_TO_END][k] = decoded_time - s[INPUT_TIME][k] - if not s[DROPPED][k]: - if k > 0: - s[RENDERED_DELTA][k] = decoded_time - last_render_time - last_render_time = decoded_time + decoded_time = s[RENDER_TIME][k] + s[RECEIVER_TIME][k] = decoded_time - s[RECV_TIME][k] + s[END_TO_END][k] = decoded_time - s[INPUT_TIME][k] + if not s[DROPPED][k]: + if k > 0: + s[RENDERED_DELTA][k] = decoded_time - last_render_time + last_render_time = decoded_time - def _Hide(self, values): - """ + def _Hide(self, values): + """ Replaces values for dropped frames with None. These values are then skipped by the Plot() method. """ - return [None if self.samples[DROPPED][k] else values[k] - for k in range(len(values))] + return [ + None if self.samples[DROPPED][k] else values[k] + for k in range(len(values)) + ] - def AddSamples(self, config, target_lines_list): - """Creates graph lines from the current data set with given config.""" - for field in config.fields: - # field is None means the user wants just to skip the color. - if field is None: - target_lines_list.append(None) - continue + def AddSamples(self, config, target_lines_list): + """Creates graph lines from the current data set with given config.""" + for field in config.fields: + # field is None means the user wants just to skip the color. + if field is None: + target_lines_list.append(None) + continue - field_id = field & FIELD_MASK - values = self.samples[field_id] + field_id = field & FIELD_MASK + values = self.samples[field_id] - if field & HIDE_DROPPED: - values = self._Hide(values) + if field & HIDE_DROPPED: + values = self._Hide(values) - target_lines_list.append(PlotLine( - self.title + " " + ID_TO_TITLE[field_id], - values, field & ~FIELD_MASK)) + target_lines_list.append( + PlotLine(self.title + " " + ID_TO_TITLE[field_id], values, + field & ~FIELD_MASK)) def AverageOverCycle(values, length): - """ + """ Returns the list: [ avg(values[0], values[length], ...), @@ -194,221 +198,272 @@ def AverageOverCycle(values, length): Skips None values when calculating the average value. """ - total = [0.0] * length - count = [0] * length - for k, val in enumerate(values): - if val is not None: - total[k % length] += val - count[k % length] += 1 + total = [0.0] * length + count = [0] * length + for k, val in enumerate(values): + if val is not None: + total[k % length] += val + count[k % length] += 1 - result = [0.0] * length - for k in range(length): - result[k] = total[k] / count[k] if count[k] else None - return result + result = [0.0] * length + for k in range(length): + result[k] = total[k] / count[k] if count[k] else None + return result class PlotConfig(object): - """Object representing a single graph.""" + """Object representing a single graph.""" - def __init__(self, fields, data_list, cycle_length=None, frames=None, - offset=0, output_filename=None, title="Graph"): - self.fields = fields - self.data_list = data_list - self.cycle_length = cycle_length - self.frames = frames - self.offset = offset - self.output_filename = output_filename - self.title = title + def __init__(self, + fields, + data_list, + cycle_length=None, + frames=None, + offset=0, + output_filename=None, + title="Graph"): + self.fields = fields + self.data_list = data_list + self.cycle_length = cycle_length + self.frames = frames + self.offset = offset + self.output_filename = output_filename + self.title = title - def Plot(self, ax1): - lines = [] - for data in self.data_list: - if not data: - # Add None lines to skip the colors. - lines.extend([None] * len(self.fields)) - else: - data.AddSamples(self, lines) + def Plot(self, ax1): + lines = [] + for data in self.data_list: + if not data: + # Add None lines to skip the colors. + lines.extend([None] * len(self.fields)) + else: + data.AddSamples(self, lines) - def _SliceValues(values): - if self.offset: - values = values[self.offset:] - if self.frames: - values = values[:self.frames] - return values + def _SliceValues(values): + if self.offset: + values = values[self.offset:] + if self.frames: + values = values[:self.frames] + return values - length = None - for line in lines: - if line is None: - continue + length = None + for line in lines: + if line is None: + continue - line.values = _SliceValues(line.values) - if self.cycle_length: - line.values = AverageOverCycle(line.values, self.cycle_length) + line.values = _SliceValues(line.values) + if self.cycle_length: + line.values = AverageOverCycle(line.values, self.cycle_length) - if length is None: - length = len(line.values) - elif length != len(line.values): - raise Exception("All arrays should have the same length!") + if length is None: + length = len(line.values) + elif length != len(line.values): + raise Exception("All arrays should have the same length!") - ax1.set_xlabel("Frame", fontsize="large") - if any(line.flags & RIGHT_Y_AXIS for line in lines if line): - ax2 = ax1.twinx() - ax2.set_xlabel("Frame", fontsize="large") - else: - ax2 = None + ax1.set_xlabel("Frame", fontsize="large") + if any(line.flags & RIGHT_Y_AXIS for line in lines if line): + ax2 = ax1.twinx() + ax2.set_xlabel("Frame", fontsize="large") + else: + ax2 = None - # Have to implement color_cycle manually, due to two scales in a graph. - color_cycle = ["b", "r", "g", "c", "m", "y", "k"] - color_iter = itertools.cycle(color_cycle) + # Have to implement color_cycle manually, due to two scales in a graph. + color_cycle = ["b", "r", "g", "c", "m", "y", "k"] + color_iter = itertools.cycle(color_cycle) - for line in lines: - if not line: - color_iter.next() - continue + for line in lines: + if not line: + color_iter.next() + continue - if self.cycle_length: - x = numpy.array(range(self.cycle_length)) - else: - x = numpy.array(range(self.offset, self.offset + len(line.values))) - y = numpy.array(line.values) - ax = ax2 if line.flags & RIGHT_Y_AXIS else ax1 - ax.Plot(x, y, "o-", label=line.label, markersize=3.0, linewidth=1.0, - color=color_iter.next()) + if self.cycle_length: + x = numpy.array(range(self.cycle_length)) + else: + x = numpy.array( + range(self.offset, self.offset + len(line.values))) + y = numpy.array(line.values) + ax = ax2 if line.flags & RIGHT_Y_AXIS else ax1 + ax.Plot(x, + y, + "o-", + label=line.label, + markersize=3.0, + linewidth=1.0, + color=color_iter.next()) - ax1.grid(True) - if ax2: - ax1.legend(loc="upper left", shadow=True, fontsize="large") - ax2.legend(loc="upper right", shadow=True, fontsize="large") - else: - ax1.legend(loc="best", shadow=True, fontsize="large") + ax1.grid(True) + if ax2: + ax1.legend(loc="upper left", shadow=True, fontsize="large") + ax2.legend(loc="upper right", shadow=True, fontsize="large") + else: + ax1.legend(loc="best", shadow=True, fontsize="large") def LoadFiles(filenames): - result = [] - for filename in filenames: - if filename in LoadFiles.cache: - result.append(LoadFiles.cache[filename]) - else: - data = Data(filename) - LoadFiles.cache[filename] = data - result.append(data) - return result + result = [] + for filename in filenames: + if filename in LoadFiles.cache: + result.append(LoadFiles.cache[filename]) + else: + data = Data(filename) + LoadFiles.cache[filename] = data + result.append(data) + return result + + LoadFiles.cache = {} def GetParser(): - class CustomAction(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - if "ordered_args" not in namespace: - namespace.ordered_args = [] - namespace.ordered_args.append((self.dest, values)) + class CustomAction(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + if "ordered_args" not in namespace: + namespace.ordered_args = [] + namespace.ordered_args.append((self.dest, values)) - parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument( - "-c", "--cycle_length", nargs=1, action=CustomAction, - type=int, help="Cycle length over which to average the values.") - parser.add_argument( - "-f", "--field", nargs=1, action=CustomAction, - help="Name of the field to show. Use 'none' to skip a color.") - parser.add_argument("-r", "--right", nargs=0, action=CustomAction, - help="Use right Y axis for given field.") - parser.add_argument("-d", "--drop", nargs=0, action=CustomAction, - help="Hide values for dropped frames.") - parser.add_argument("-o", "--offset", nargs=1, action=CustomAction, type=int, - help="Frame offset.") - parser.add_argument("-n", "--next", nargs=0, action=CustomAction, - help="Separator for multiple graphs.") - parser.add_argument( - "--frames", nargs=1, action=CustomAction, type=int, - help="Frame count to show or take into account while averaging.") - parser.add_argument("-t", "--title", nargs=1, action=CustomAction, - help="Title of the graph.") - parser.add_argument( - "-O", "--output_filename", nargs=1, action=CustomAction, - help="Use to save the graph into a file. " - "Otherwise, a window will be shown.") - parser.add_argument( - "files", nargs="+", action=CustomAction, - help="List of text-based files generated by loopback tests.") - return parser + parser.add_argument("-c", + "--cycle_length", + nargs=1, + action=CustomAction, + type=int, + help="Cycle length over which to average the values.") + parser.add_argument( + "-f", + "--field", + nargs=1, + action=CustomAction, + help="Name of the field to show. Use 'none' to skip a color.") + parser.add_argument("-r", + "--right", + nargs=0, + action=CustomAction, + help="Use right Y axis for given field.") + parser.add_argument("-d", + "--drop", + nargs=0, + action=CustomAction, + help="Hide values for dropped frames.") + parser.add_argument("-o", + "--offset", + nargs=1, + action=CustomAction, + type=int, + help="Frame offset.") + parser.add_argument("-n", + "--next", + nargs=0, + action=CustomAction, + help="Separator for multiple graphs.") + parser.add_argument( + "--frames", + nargs=1, + action=CustomAction, + type=int, + help="Frame count to show or take into account while averaging.") + parser.add_argument("-t", + "--title", + nargs=1, + action=CustomAction, + help="Title of the graph.") + parser.add_argument("-O", + "--output_filename", + nargs=1, + action=CustomAction, + help="Use to save the graph into a file. " + "Otherwise, a window will be shown.") + parser.add_argument( + "files", + nargs="+", + action=CustomAction, + help="List of text-based files generated by loopback tests.") + return parser def _PlotConfigFromArgs(args, graph_num): - # Pylint complains about using kwargs, so have to do it this way. - cycle_length = None - frames = None - offset = 0 - output_filename = None - title = "Graph" + # Pylint complains about using kwargs, so have to do it this way. + cycle_length = None + frames = None + offset = 0 + output_filename = None + title = "Graph" - fields = [] - files = [] - mask = 0 - for key, values in args: - if key == "cycle_length": - cycle_length = values[0] - elif key == "frames": - frames = values[0] - elif key == "offset": - offset = values[0] - elif key == "output_filename": - output_filename = values[0] - elif key == "title": - title = values[0] - elif key == "drop": - mask |= HIDE_DROPPED - elif key == "right": - mask |= RIGHT_Y_AXIS - elif key == "field": - field_id = FieldArgToId(values[0]) - fields.append(field_id | mask if field_id is not None else None) - mask = 0 # Reset mask after the field argument. - elif key == "files": - files.extend(values) + fields = [] + files = [] + mask = 0 + for key, values in args: + if key == "cycle_length": + cycle_length = values[0] + elif key == "frames": + frames = values[0] + elif key == "offset": + offset = values[0] + elif key == "output_filename": + output_filename = values[0] + elif key == "title": + title = values[0] + elif key == "drop": + mask |= HIDE_DROPPED + elif key == "right": + mask |= RIGHT_Y_AXIS + elif key == "field": + field_id = FieldArgToId(values[0]) + fields.append(field_id | mask if field_id is not None else None) + mask = 0 # Reset mask after the field argument. + elif key == "files": + files.extend(values) - if not files: - raise Exception("Missing file argument(s) for graph #{}".format(graph_num)) - if not fields: - raise Exception("Missing field argument(s) for graph #{}".format(graph_num)) + if not files: + raise Exception( + "Missing file argument(s) for graph #{}".format(graph_num)) + if not fields: + raise Exception( + "Missing field argument(s) for graph #{}".format(graph_num)) - return PlotConfig(fields, LoadFiles(files), cycle_length=cycle_length, - frames=frames, offset=offset, output_filename=output_filename, - title=title) + return PlotConfig(fields, + LoadFiles(files), + cycle_length=cycle_length, + frames=frames, + offset=offset, + output_filename=output_filename, + title=title) def PlotConfigsFromArgs(args): - """Generates plot configs for given command line arguments.""" - # The way it works: - # First we detect separators -n/--next and split arguments into groups, one - # for each plot. For each group, we partially parse it with - # argparse.ArgumentParser, modified to remember the order of arguments. - # Then we traverse the argument list and fill the PlotConfig. - args = itertools.groupby(args, lambda x: x in ["-n", "--next"]) - prep_args = list(list(group) for match, group in args if not match) + """Generates plot configs for given command line arguments.""" + # The way it works: + # First we detect separators -n/--next and split arguments into groups, one + # for each plot. For each group, we partially parse it with + # argparse.ArgumentParser, modified to remember the order of arguments. + # Then we traverse the argument list and fill the PlotConfig. + args = itertools.groupby(args, lambda x: x in ["-n", "--next"]) + prep_args = list(list(group) for match, group in args if not match) - parser = GetParser() - plot_configs = [] - for index, raw_args in enumerate(prep_args): - graph_args = parser.parse_args(raw_args).ordered_args - plot_configs.append(_PlotConfigFromArgs(graph_args, index)) - return plot_configs + parser = GetParser() + plot_configs = [] + for index, raw_args in enumerate(prep_args): + graph_args = parser.parse_args(raw_args).ordered_args + plot_configs.append(_PlotConfigFromArgs(graph_args, index)) + return plot_configs def ShowOrSavePlots(plot_configs): - for config in plot_configs: - fig = plt.figure(figsize=(14.0, 10.0)) - ax = fig.add_subPlot(1, 1, 1) + for config in plot_configs: + fig = plt.figure(figsize=(14.0, 10.0)) + ax = fig.add_subPlot(1, 1, 1) - plt.title(config.title) - config.Plot(ax) - if config.output_filename: - print "Saving to", config.output_filename - fig.savefig(config.output_filename) - plt.close(fig) + plt.title(config.title) + config.Plot(ax) + if config.output_filename: + print "Saving to", config.output_filename + fig.savefig(config.output_filename) + plt.close(fig) + + plt.show() - plt.show() if __name__ == "__main__": - ShowOrSavePlots(PlotConfigsFromArgs(sys.argv[1:])) + ShowOrSavePlots(PlotConfigsFromArgs(sys.argv[1:])) diff --git a/TMessagesProj/jni/voip/webrtc/video/pc_full_stack_tests.cc b/TMessagesProj/jni/voip/webrtc/video/pc_full_stack_tests.cc index 7a4b44909..d515a5271 100644 --- a/TMessagesProj/jni/voip/webrtc/video/pc_full_stack_tests.cc +++ b/TMessagesProj/jni/voip/webrtc/video/pc_full_stack_tests.cc @@ -49,8 +49,6 @@ using VideoCodecConfig = namespace { constexpr int kTestDurationSec = 45; -constexpr char kVp8TrustedRateControllerFieldTrial[] = - "WebRTC-LibvpxVp8TrustedRateController/Enabled/"; EmulatedNetworkNode* CreateEmulatedNodeWithConfig( NetworkEmulationManager* emulation, @@ -109,7 +107,7 @@ std::string ClipNameToClipPath(const char* clip_name) { } // namespace #if defined(RTC_ENABLE_VP9) -TEST(PCFullStackTest, ForemanCifWithoutPacketLossVp9) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Net_Delay_0_0_Plr_0_VP9) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -134,7 +132,8 @@ TEST(PCFullStackTest, ForemanCifWithoutPacketLossVp9) { fixture->Run(std::move(run_params)); } -TEST(PCGenericDescriptorTest, ForemanCifPlr5Vp9) { +TEST(PCGenericDescriptorTest, + Pc_Foreman_Cif_Delay_50_0_Plr_5_VP9_Generic_Descriptor) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -165,13 +164,13 @@ TEST(PCGenericDescriptorTest, ForemanCifPlr5Vp9) { #if (defined(WEBRTC_ANDROID) && \ (defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM))) || \ (defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM64)) -#define MAYBE_GeneratorWithoutPacketLossVp9Profile2 \ - DISABLED_GeneratorWithoutPacketLossVp9Profile2 +#define MAYBE_Pc_Generator_Net_Delay_0_0_Plr_0_VP9Profile2 \ + DISABLED_Pc_Generator_Net_Delay_0_0_Plr_0_VP9Profile2 #else -#define MAYBE_GeneratorWithoutPacketLossVp9Profile2 \ - GeneratorWithoutPacketLossVp9Profile2 +#define MAYBE_Pc_Generator_Net_Delay_0_0_Plr_0_VP9Profile2 \ + Pc_Generator_Net_Delay_0_0_Plr_0_VP9Profile2 #endif -TEST(PCFullStackTest, MAYBE_GeneratorWithoutPacketLossVp9Profile2) { +TEST(PCFullStackTest, MAYBE_Pc_Generator_Net_Delay_0_0_Plr_0_VP9Profile2) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -228,7 +227,7 @@ TEST(PCFullStackTest, GeneratorWithoutPacketLossMultiplexI420AFrame) { */ #endif // defined(RTC_ENABLE_VP9) -TEST(PCFullStackTest, ParisQcifWithoutPacketLoss) { +TEST(PCFullStackTest, Pc_Net_Delay_0_0_Plr_0) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -250,7 +249,8 @@ TEST(PCFullStackTest, ParisQcifWithoutPacketLoss) { fixture->Run(std::move(run_params)); } -TEST(PCGenericDescriptorTest, ForemanCifWithoutPacketLoss) { +TEST(PCGenericDescriptorTest, + Pc_Foreman_Cif_Net_Delay_0_0_Plr_0_Generic_Descriptor) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -273,7 +273,8 @@ TEST(PCGenericDescriptorTest, ForemanCifWithoutPacketLoss) { fixture->Run(std::move(run_params)); } -TEST(PCGenericDescriptorTest, ForemanCif30kbpsWithoutPacketLoss) { +TEST(PCGenericDescriptorTest, + Pc_Foreman_Cif_30kbps_Net_Delay_0_0_Plr_0_Generic_Descriptor) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -302,42 +303,8 @@ TEST(PCGenericDescriptorTest, ForemanCif30kbpsWithoutPacketLoss) { fixture->Run(std::move(run_params)); } -// TODO(webrtc:9722): Remove when experiment is cleaned up. -TEST(PCGenericDescriptorTest, - ForemanCif30kbpsWithoutPacketLossTrustedRateControl) { - test::ScopedFieldTrials override_field_trials( - AppendFieldTrials(kVp8TrustedRateControllerFieldTrial)); - std::unique_ptr network_emulation_manager = - CreateNetworkEmulationManager(); - BuiltInNetworkBehaviorConfig config; - auto fixture = CreateTestFixture( - "pc_foreman_cif_30kbps_net_delay_0_0_plr_0_trusted_rate_ctrl_generic_" - "descriptor", - *network_emulation_manager->time_controller(), - CreateTwoNetworkLinks(network_emulation_manager.get(), config), - [](PeerConfigurer* alice) { - VideoConfig video(352, 288, 10); - video.stream_label = "alice-video"; - auto frame_generator = CreateFromYuvFileFrameGenerator( - video, ClipNameToClipPath("foreman_cif")); - alice->AddVideoConfig(std::move(video), std::move(frame_generator)); - - BitrateSettings bitrate_settings; - bitrate_settings.min_bitrate_bps = 30000; - bitrate_settings.start_bitrate_bps = 30000; - bitrate_settings.max_bitrate_bps = 30000; - alice->SetBitrateSettings(bitrate_settings); - }, - [](PeerConfigurer* bob) {}); - RunParams run_params(TimeDelta::Seconds(kTestDurationSec)); - run_params.video_codecs = {VideoCodecConfig(cricket::kVp8CodecName)}; - run_params.use_flex_fec = false; - run_params.use_ulp_fec = false; - fixture->Run(std::move(run_params)); -} - // Link capacity below default start rate. -TEST(PCFullStackTest, ForemanCifLink150kbpsWithoutPacketLoss) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Link_150kbps_Net_Delay_0_0_Plr_0) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -361,7 +328,7 @@ TEST(PCFullStackTest, ForemanCifLink150kbpsWithoutPacketLoss) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCifLink130kbps100msDelay1PercentPacketLossUlpfec) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Link_130kbps_Delay100ms_Loss1_Ulpfec) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -387,7 +354,7 @@ TEST(PCFullStackTest, ForemanCifLink130kbps100msDelay1PercentPacketLossUlpfec) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCifLink50kbps100msDelay1PercentPacketLossUlpfec) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Link_50kbps_Delay100ms_Loss1_Ulpfec) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -414,7 +381,8 @@ TEST(PCFullStackTest, ForemanCifLink50kbps100msDelay1PercentPacketLossUlpfec) { } // Restricted network and encoder overproducing by 30%. -TEST(PCFullStackTest, ForemanCifLink150kbpsBadRateController) { +TEST(PCFullStackTest, + Pc_Foreman_Cif_Link_150kbps_Delay100ms_30pkts_Queue_Overshoot30) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -445,7 +413,7 @@ TEST(PCFullStackTest, ForemanCifLink150kbpsBadRateController) { // Packet rate and loss are low enough that loss will happen with ~3s interval. // This triggers protection overhead to toggle between zero and non-zero. // Link queue is restrictive enough to trigger loss on probes. -TEST(PCFullStackTest, ForemanCifMediaCapacitySmallLossAndQueue) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Link_250kbps_Delay100ms_10pkts_Loss1) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -473,7 +441,8 @@ TEST(PCFullStackTest, ForemanCifMediaCapacitySmallLossAndQueue) { fixture->Run(std::move(run_params)); } -TEST(PCGenericDescriptorTest, ForemanCifPlr5) { +TEST(PCGenericDescriptorTest, + Pc_Foreman_Cif_Delay_50_0_Plr_5_Generic_Descriptor) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -498,7 +467,8 @@ TEST(PCGenericDescriptorTest, ForemanCifPlr5) { fixture->Run(std::move(run_params)); } -TEST(PCGenericDescriptorTest, ForemanCifPlr5Ulpfec) { +TEST(PCGenericDescriptorTest, + Pc_Foreman_Cif_Delay_50_0_Plr_5_Ulpfec_Generic_Descriptor) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -523,7 +493,7 @@ TEST(PCGenericDescriptorTest, ForemanCifPlr5Ulpfec) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCifPlr5Flexfec) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Delay_50_0_Plr_5_Flexfec) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -548,7 +518,7 @@ TEST(PCFullStackTest, ForemanCifPlr5Flexfec) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCif500kbpsPlr3Flexfec) { +TEST(PCFullStackTest, Pc_Foreman_Cif_500kbps_Delay_50_0_Plr_3_Flexfec) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -574,7 +544,7 @@ TEST(PCFullStackTest, ForemanCif500kbpsPlr3Flexfec) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCif500kbpsPlr3Ulpfec) { +TEST(PCFullStackTest, Pc_Foreman_Cif_500kbps_Delay_50_0_Plr_3_Ulpfec) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -601,7 +571,7 @@ TEST(PCFullStackTest, ForemanCif500kbpsPlr3Ulpfec) { } #if defined(WEBRTC_USE_H264) -TEST(PCFullStackTest, ForemanCifWithoutPacketlossH264) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Net_Delay_0_0_Plr_0_H264) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -624,7 +594,7 @@ TEST(PCFullStackTest, ForemanCifWithoutPacketlossH264) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCif30kbpsWithoutPacketlossH264) { +TEST(PCFullStackTest, Pc_Foreman_Cif_30kbps_Net_Delay_0_0_Plr_0_H264) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -653,7 +623,8 @@ TEST(PCFullStackTest, ForemanCif30kbpsWithoutPacketlossH264) { fixture->Run(std::move(run_params)); } -TEST(PCGenericDescriptorTest, ForemanCifPlr5H264) { +TEST(PCGenericDescriptorTest, + Pc_Foreman_Cif_Delay_50_0_Plr_5_H264_Generic_Descriptor) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -678,7 +649,7 @@ TEST(PCGenericDescriptorTest, ForemanCifPlr5H264) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCifPlr5H264SpsPpsIdrIsKeyframe) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Delay_50_0_Plr_5_H264_Sps_Pps_Idr) { test::ScopedFieldTrials override_field_trials( AppendFieldTrials("WebRTC-SpsPpsIdrIsH264Keyframe/Enabled/")); @@ -706,7 +677,7 @@ TEST(PCFullStackTest, ForemanCifPlr5H264SpsPpsIdrIsKeyframe) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCifPlr5H264Flexfec) { +TEST(PCFullStackTest, Pc_Foreman_Cif_Delay_50_0_Plr_5_H264_Flexfec) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -733,7 +704,7 @@ TEST(PCFullStackTest, ForemanCifPlr5H264Flexfec) { // Ulpfec with H264 is an unsupported combination, so this test is only useful // for debugging. It is therefore disabled by default. -TEST(PCFullStackTest, DISABLED_ForemanCifPlr5H264Ulpfec) { +TEST(PCFullStackTest, DISABLED_Pc_Foreman_Cif_Delay_50_0_Plr_5_H264_Ulpfec) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -759,7 +730,7 @@ TEST(PCFullStackTest, DISABLED_ForemanCifPlr5H264Ulpfec) { } #endif // defined(WEBRTC_USE_H264) -TEST(PCFullStackTest, ForemanCif500kbps) { +TEST(PCFullStackTest, Pc_Foreman_Cif_500kbps) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -784,7 +755,7 @@ TEST(PCFullStackTest, ForemanCif500kbps) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCif500kbpsLimitedQueue) { +TEST(PCFullStackTest, Pc_Foreman_Cif_500kbps_32pkts_Queue) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -810,7 +781,7 @@ TEST(PCFullStackTest, ForemanCif500kbpsLimitedQueue) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ForemanCif500kbps100ms) { +TEST(PCFullStackTest, Pc_Foreman_Cif_500kbps_100ms) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -836,7 +807,8 @@ TEST(PCFullStackTest, ForemanCif500kbps100ms) { fixture->Run(std::move(run_params)); } -TEST(PCGenericDescriptorTest, ForemanCif500kbps100msLimitedQueue) { +TEST(PCGenericDescriptorTest, + Pc_Foreman_Cif_500kbps_100ms_32pkts_Queue_Generic_Descriptor) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -883,7 +855,7 @@ TEST(PCFullStackTest, ForemanCif500kbps100msLimitedQueueRecvBwe) { } */ -TEST(PCFullStackTest, ForemanCif1000kbps100msLimitedQueue) { +TEST(PCFullStackTest, Pc_Foreman_Cif_1000kbps_100ms_32pkts_Queue) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -910,7 +882,7 @@ TEST(PCFullStackTest, ForemanCif1000kbps100msLimitedQueue) { } // TODO(sprang): Remove this if we have the similar ModerateLimits below? -TEST(PCFullStackTest, ConferenceMotionHd2000kbps100msLimitedQueue) { +TEST(PCFullStackTest, Pc_Conference_Motion_Hd_2000kbps_100ms_32pkts_Queue) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -936,36 +908,6 @@ TEST(PCFullStackTest, ConferenceMotionHd2000kbps100msLimitedQueue) { fixture->Run(std::move(run_params)); } -// TODO(webrtc:9722): Remove when experiment is cleaned up. -TEST(PCFullStackTest, ConferenceMotionHd1TLModerateLimitsWhitelistVp8) { - test::ScopedFieldTrials override_field_trials( - AppendFieldTrials(kVp8TrustedRateControllerFieldTrial)); - std::unique_ptr network_emulation_manager = - CreateNetworkEmulationManager(); - BuiltInNetworkBehaviorConfig config; - config.queue_length_packets = 50; - config.loss_percent = 3; - config.queue_delay_ms = 100; - config.link_capacity_kbps = 2000; - auto fixture = CreateTestFixture( - "pc_conference_motion_hd_1tl_moderate_limits_trusted_rate_ctrl", - *network_emulation_manager->time_controller(), - CreateTwoNetworkLinks(network_emulation_manager.get(), config), - [](PeerConfigurer* alice) { - VideoConfig video(1280, 720, 50); - video.stream_label = "alice-video"; - auto frame_generator = CreateFromYuvFileFrameGenerator( - video, ClipNameToClipPath("ConferenceMotion_1280_720_50")); - alice->AddVideoConfig(std::move(video), std::move(frame_generator)); - }, - [](PeerConfigurer* bob) {}); - RunParams run_params(TimeDelta::Seconds(kTestDurationSec)); - run_params.video_codecs = {VideoCodecConfig(cricket::kVp8CodecName)}; - run_params.use_flex_fec = false; - run_params.use_ulp_fec = false; - fixture->Run(std::move(run_params)); -} - /* // TODO(bugs.webrtc.org/10639) requires simulcast/SVC support in PC framework TEST(PCGenericDescriptorTest, ConferenceMotionHd2TLModerateLimits) { @@ -1093,7 +1035,7 @@ TEST(PCFullStackTest, */ #if defined(RTC_ENABLE_VP9) -TEST(PCFullStackTest, ConferenceMotionHd2000kbps100msLimitedQueueVP9) { +TEST(PCFullStackTest, Pc_Conference_Motion_Hd_2000kbps_100ms_32pkts_Queue_Vp9) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -1122,7 +1064,7 @@ TEST(PCFullStackTest, ConferenceMotionHd2000kbps100msLimitedQueueVP9) { } #endif -TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_NoConferenceMode) { +TEST(PCFullStackTest, Pc_Screenshare_Slides_No_Conference_Mode) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -1146,7 +1088,7 @@ TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_NoConferenceMode) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL) { +TEST(PCFullStackTest, Pc_Screenshare_Slides) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -1172,7 +1114,7 @@ TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL) { // TODO(bugs.webrtc.org/9840): Investigate why is this test flaky on Win/Mac. #if !defined(WEBRTC_MAC) && !defined(WEBRTC_WIN) -TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_Simulcast_NoConferenceMode) { +TEST(PCFullStackTest, Pc_Screenshare_Slides_Simulcast_No_Conference_Mode) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -1198,7 +1140,7 @@ TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_Simulcast_NoConferenceMode) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_Simulcast) { +TEST(PCFullStackTest, Pc_Screenshare_Slides_Simulcast) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); auto fixture = CreateTestFixture( @@ -1230,40 +1172,6 @@ TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_Simulcast) { #if !defined(WEBRTC_MAC) // TODO(bugs.webrtc.org/9840): Investigate why is this test flaky on Win/Mac. #if !defined(WEBRTC_WIN) -const char kScreenshareSimulcastVariableFramerateExperiment[] = - "WebRTC-VP8VariableFramerateScreenshare/" - "Enabled,min_fps:5.0,min_qp:15,undershoot:30/"; -// TODO(bugs.webrtc.org/10639) requires simulcast/SVC support in PC framework -TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_Simulcast_Variable_Framerate) { - test::ScopedFieldTrials field_trial( - AppendFieldTrials(kScreenshareSimulcastVariableFramerateExperiment)); - auto fixture = CreateVideoQualityTestFixture(); - ParamsWithLogging screenshare; - screenshare.call.send_side_bwe = true; - screenshare.screenshare[0] = {true, false, 10}; - screenshare.video[0] = {true, 1850, 1110, 30, 800000, 2500000, - 2500000, false, "VP8", 2, 1, 400000, - false, false, false, ""}; - screenshare.analyzer = {"screenshare_slides_simulcast_variable_framerate", - 0.0, 0.0, kTestDurationSec}; - ParamsWithLogging screenshare_params_high; - screenshare_params_high.video[0] = { - true, 1850, 1110, 60, 600000, 1250000, 1250000, false, - "VP8", 2, 0, 400000, false, false, false, ""}; - VideoQualityTest::Params screenshare_params_low; - screenshare_params_low.video[0] = {true, 1850, 1110, 5, 30000, 200000, - 1000000, false, "VP8", 2, 0, 400000, - false, false, false, ""}; - - std::vector streams = { - VideoQualityTest::DefaultVideoStream(screenshare_params_low, 0), - VideoQualityTest::DefaultVideoStream(screenshare_params_high, 0)}; - screenshare.ss[0] = { - streams, 1, 1, 0, InterLayerPredMode::kOn, std::vector(), - false}; - fixture->RunWithAnalyzer(screenshare); -} - // TODO(bugs.webrtc.org/10639) requires simulcast/SVC support in PC framework TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_Simulcast_low) { auto fixture = CreateVideoQualityTestFixture(); @@ -1311,7 +1219,7 @@ TEST(PCFullStackTest, ScreenshareSlidesVP8_2TL_Scroll) { } // TODO(bugs.webrtc.org/10639) requires simulcast/SVC support in PC framework -TEST(PCGenericDescriptorTest, ScreenshareSlidesVP8_2TL_LossyNet) { +TEST(PCGenericDescriptorTest, Screenshare_Slides_Lossy_Net_Generic_Descriptor) { auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging screenshare; screenshare.call.send_side_bwe = true; @@ -1437,7 +1345,7 @@ ParamsWithLogging::Video SimulcastVp8VideoLow() { #if defined(RTC_ENABLE_VP9) -TEST(PCFullStackTest, ScreenshareSlidesVP9_3SL_High_Fps) { +TEST(PCFullStackTest, Pc_Screenshare_Slides_Vp9_3sl_High_Fps) { webrtc::test::ScopedFieldTrials override_trials( AppendFieldTrials("WebRTC-Vp9InterLayerPred/" "Enabled,inter_layer_pred_mode:on/")); @@ -1467,7 +1375,7 @@ TEST(PCFullStackTest, ScreenshareSlidesVP9_3SL_High_Fps) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, VP9SVC_3SL_High) { +TEST(PCFullStackTest, Pc_Vp9svc_3sl_High) { webrtc::test::ScopedFieldTrials override_trials( AppendFieldTrials("WebRTC-Vp9InterLayerPred/" "Enabled,inter_layer_pred_mode:on/")); @@ -1496,7 +1404,7 @@ TEST(PCFullStackTest, VP9SVC_3SL_High) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, VP9SVC_3SL_Low) { +TEST(PCFullStackTest, Pc_Vp9svc_3sl_Low) { webrtc::test::ScopedFieldTrials override_trials( AppendFieldTrials("WebRTC-Vp9InterLayerPred/" "Enabled,inter_layer_pred_mode:on/")); @@ -1598,8 +1506,7 @@ TEST(PCFullStackTest, VP9KSVC_3SL_Medium_Network_Restricted) { // TODO(webrtc:9722): Remove when experiment is cleaned up. TEST(PCFullStackTest, VP9KSVC_3SL_Medium_Network_Restricted_Trusted_Rate) { webrtc::test::ScopedFieldTrials override_trials( - AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/" - "WebRTC-LibvpxVp9TrustedRateController/Enabled/")); + AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -1621,11 +1528,11 @@ TEST(PCFullStackTest, VP9KSVC_3SL_Medium_Network_Restricted_Trusted_Rate) { // Android bots can't handle FullHD, so disable the test. // TODO(bugs.webrtc.org/9220): Investigate source of flakiness on Mac. #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) -#define MAYBE_SimulcastFullHdOveruse DISABLED_SimulcastFullHdOveruse +#define MAYBE_Pc_Simulcast_HD_High DISABLED_Pc_Simulcast_HD_High #else -#define MAYBE_SimulcastFullHdOveruse SimulcastFullHdOveruse +#define MAYBE_Pc_Simulcast_HD_High Pc_Simulcast_HD_High #endif -TEST(PCFullStackTest, MAYBE_SimulcastFullHdOveruse) { +TEST(PCFullStackTest, MAYBE_Pc_Simulcast_HD_High) { webrtc::test::ScopedFieldTrials override_trials(AppendFieldTrials( "WebRTC-ForceSimulatedOveruseIntervalMs/1000-50000-300/")); std::unique_ptr network_emulation_manager = @@ -1651,7 +1558,7 @@ TEST(PCFullStackTest, MAYBE_SimulcastFullHdOveruse) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, SimulcastVP8_3SL_High) { +TEST(PCFullStackTest, Pc_Simulcast_Vp8_3sl_High) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; @@ -1677,7 +1584,7 @@ TEST(PCFullStackTest, SimulcastVP8_3SL_High) { fixture->Run(std::move(run_params)); } -TEST(PCFullStackTest, SimulcastVP8_3SL_Low) { +TEST(PCFullStackTest, Pc_Simulcast_Vp8_3sl_Low) { std::unique_ptr network_emulation_manager = CreateNetworkEmulationManager(); BuiltInNetworkBehaviorConfig config; diff --git a/TMessagesProj/jni/voip/webrtc/video/rtp_streams_synchronizer.cc b/TMessagesProj/jni/voip/webrtc/video/rtp_streams_synchronizer.cc index 28e9a0ba9..29ace9043 100644 --- a/TMessagesProj/jni/voip/webrtc/video/rtp_streams_synchronizer.cc +++ b/TMessagesProj/jni/voip/webrtc/video/rtp_streams_synchronizer.cc @@ -89,11 +89,18 @@ void RtpStreamsSynchronizer::Process() { log_stats = true; } + int64_t last_audio_receive_time_ms = + audio_measurement_.latest_receive_time_ms; absl::optional audio_info = syncable_audio_->GetInfo(); if (!audio_info || !UpdateMeasurements(&audio_measurement_, *audio_info)) { return; } + if (last_audio_receive_time_ms == audio_measurement_.latest_receive_time_ms) { + // No new audio packet has been received since last update. + return; + } + int64_t last_video_receive_ms = video_measurement_.latest_receive_time_ms; absl::optional video_info = syncable_video_->GetInfo(); if (!video_info || !UpdateMeasurements(&video_measurement_, *video_info)) { diff --git a/TMessagesProj/jni/voip/webrtc/video/rtp_streams_synchronizer2.cc b/TMessagesProj/jni/voip/webrtc/video/rtp_streams_synchronizer2.cc index 49be355a3..4096fceb9 100644 --- a/TMessagesProj/jni/voip/webrtc/video/rtp_streams_synchronizer2.cc +++ b/TMessagesProj/jni/voip/webrtc/video/rtp_streams_synchronizer2.cc @@ -92,11 +92,18 @@ void RtpStreamsSynchronizer::UpdateDelay() { log_stats = true; } + int64_t last_audio_receive_time_ms = + audio_measurement_.latest_receive_time_ms; absl::optional audio_info = syncable_audio_->GetInfo(); if (!audio_info || !UpdateMeasurements(&audio_measurement_, *audio_info)) { return; } + if (last_audio_receive_time_ms == audio_measurement_.latest_receive_time_ms) { + // No new audio packet has been received since last update. + return; + } + int64_t last_video_receive_ms = video_measurement_.latest_receive_time_ms; absl::optional video_info = syncable_video_->GetInfo(); if (!video_info || !UpdateMeasurements(&video_measurement_, *video_info)) { @@ -147,8 +154,12 @@ void RtpStreamsSynchronizer::UpdateDelay() { << "target_delay_ms: " << target_video_delay_ms << "} "; } - syncable_audio_->SetMinimumPlayoutDelay(target_audio_delay_ms); - syncable_video_->SetMinimumPlayoutDelay(target_video_delay_ms); + if (!syncable_audio_->SetMinimumPlayoutDelay(target_audio_delay_ms)) { + sync_->ReduceAudioDelay(); + } + if (!syncable_video_->SetMinimumPlayoutDelay(target_video_delay_ms)) { + sync_->ReduceVideoDelay(); + } } // TODO(https://bugs.webrtc.org/7065): Move RtpToNtpEstimator out of diff --git a/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver.h b/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver.h index 0cdc26d40..2746295fc 100644 --- a/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver.h +++ b/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver.h @@ -146,8 +146,7 @@ class RtpVideoStreamReceiver : public LossNotificationSender, // Implements RtpPacketSinkInterface. void OnRtpPacket(const RtpPacketReceived& packet) override; - // TODO(philipel): Stop using VCMPacket in the new jitter buffer and then - // remove this function. Public only for tests. + // Public only for tests. void OnReceivedPayloadData(rtc::CopyOnWriteBuffer codec_payload, const RtpPacketReceived& rtp_packet, const RTPVideoHeader& video); diff --git a/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver2.cc b/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver2.cc index db68706bc..d623e7a87 100644 --- a/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver2.cc +++ b/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver2.cc @@ -331,6 +331,10 @@ void RtpVideoStreamReceiver2::AddReceiveCodec( const std::map& codec_params, bool raw_payload) { RTC_DCHECK_RUN_ON(&worker_task_checker_); + if (codec_params.count(cricket::kH264FmtpSpsPpsIdrInKeyframe) || + field_trial::IsEnabled("WebRTC-SpsPpsIdrIsH264Keyframe")) { + packet_buffer_.ForceSpsPpsIdrIsH264Keyframe(); + } payload_type_map_.emplace( payload_type, raw_payload ? std::make_unique() diff --git a/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver2.h b/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver2.h index 69bfb532f..79e95b688 100644 --- a/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver2.h +++ b/TMessagesProj/jni/voip/webrtc/video/rtp_video_stream_receiver2.h @@ -121,8 +121,7 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, // Implements RtpPacketSinkInterface. void OnRtpPacket(const RtpPacketReceived& packet) override; - // TODO(philipel): Stop using VCMPacket in the new jitter buffer and then - // remove this function. Public only for tests. + // Public only for tests. void OnReceivedPayloadData(rtc::CopyOnWriteBuffer codec_payload, const RtpPacketReceived& rtp_packet, const RTPVideoHeader& video); diff --git a/TMessagesProj/jni/voip/webrtc/video/send_statistics_proxy.cc b/TMessagesProj/jni/voip/webrtc/video/send_statistics_proxy.cc index b0ff9b517..92545ecf9 100644 --- a/TMessagesProj/jni/voip/webrtc/video/send_statistics_proxy.cc +++ b/TMessagesProj/jni/voip/webrtc/video/send_statistics_proxy.cc @@ -976,13 +976,11 @@ void SendStatisticsProxy::OnSendEncodedImage( stats->frames_encoded++; stats->total_encode_time_ms += encoded_image.timing_.encode_finish_ms - encoded_image.timing_.encode_start_ms; - // Report resolution of top spatial layer in case of VP9 SVC. - bool is_svc_low_spatial_layer = - (codec_info && codec_info->codecType == kVideoCodecVP9) - ? !codec_info->codecSpecific.VP9.end_of_picture - : false; + // Report resolution of the top spatial layer. + bool is_top_spatial_layer = + codec_info == nullptr || codec_info->end_of_picture; - if (!stats->width || !stats->height || !is_svc_low_spatial_layer) { + if (!stats->width || !stats->height || is_top_spatial_layer) { stats->width = encoded_image._encodedWidth; stats->height = encoded_image._encodedHeight; update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds(); diff --git a/TMessagesProj/jni/voip/webrtc/video/stream_synchronization.cc b/TMessagesProj/jni/voip/webrtc/video/stream_synchronization.cc index 8c808f13c..d5c77c1ec 100644 --- a/TMessagesProj/jni/voip/webrtc/video/stream_synchronization.cc +++ b/TMessagesProj/jni/voip/webrtc/video/stream_synchronization.cc @@ -184,4 +184,12 @@ void StreamSynchronization::SetTargetBufferingDelay(int target_delay_ms) { base_target_delay_ms_ = target_delay_ms; } +void StreamSynchronization::ReduceAudioDelay() { + audio_delay_.extra_ms *= 0.9f; +} + +void StreamSynchronization::ReduceVideoDelay() { + video_delay_.extra_ms *= 0.9f; +} + } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/video/stream_synchronization.h b/TMessagesProj/jni/voip/webrtc/video/stream_synchronization.h index 1aba62d1e..2da6a49a1 100644 --- a/TMessagesProj/jni/voip/webrtc/video/stream_synchronization.h +++ b/TMessagesProj/jni/voip/webrtc/video/stream_synchronization.h @@ -44,6 +44,12 @@ class StreamSynchronization { // |target_delay_ms|. void SetTargetBufferingDelay(int target_delay_ms); + // Lowers the audio delay by 10%. Can be used to recover from errors. + void ReduceAudioDelay(); + + // Lowers the video delay by 10%. Can be used to recover from errors. + void ReduceVideoDelay(); + uint32_t audio_stream_id() const { return audio_stream_id_; } uint32_t video_stream_id() const { return video_stream_id_; } diff --git a/TMessagesProj/jni/voip/webrtc/video/video_analyzer.cc b/TMessagesProj/jni/voip/webrtc/video/video_analyzer.cc index a1174b519..c16c3b383 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_analyzer.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_analyzer.cc @@ -522,7 +522,8 @@ void VideoAnalyzer::PollStats() { } if (audio_receive_stream_ != nullptr) { - AudioReceiveStream::Stats receive_stats = audio_receive_stream_->GetStats(); + AudioReceiveStream::Stats receive_stats = + audio_receive_stream_->GetStats(/*get_and_clear_legacy_stats=*/true); audio_expand_rate_.AddSample(receive_stats.expand_rate); audio_accelerate_rate_.AddSample(receive_stats.accelerate_rate); audio_jitter_buffer_ms_.AddSample(receive_stats.jitter_buffer_ms); diff --git a/TMessagesProj/jni/voip/webrtc/video/video_analyzer.h b/TMessagesProj/jni/voip/webrtc/video/video_analyzer.h index c2401d282..18bacc16f 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_analyzer.h +++ b/TMessagesProj/jni/voip/webrtc/video/video_analyzer.h @@ -35,7 +35,7 @@ class VideoAnalyzer : public PacketReceiver, public Transport, public rtc::VideoSinkInterface { public: - using Statistics = RunningStatistics; + using Statistics = webrtc_impl::RunningStatistics; VideoAnalyzer(test::LayerFilteringTransport* transport, const std::string& test_label, diff --git a/TMessagesProj/jni/voip/webrtc/video/video_quality_test.cc b/TMessagesProj/jni/voip/webrtc/video/video_quality_test.cc index d2f3f9b5b..a58aa1f33 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_quality_test.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_quality_test.cc @@ -238,8 +238,7 @@ class QualityTestVideoEncoder : public VideoEncoder, private: // Implement EncodedImageCallback Result OnEncodedImage(const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* fragmentation) override { + const CodecSpecificInfo* codec_specific_info) override { if (codec_specific_info) { int simulcast_index; if (codec_specific_info->codecType == kVideoCodecVP9) { @@ -258,8 +257,7 @@ class QualityTestVideoEncoder : public VideoEncoder, } } - return callback_->OnEncodedImage(encoded_image, codec_specific_info, - fragmentation); + return callback_->OnEncodedImage(encoded_image, codec_specific_info); } void OnDroppedFrame(DropReason reason) override { @@ -864,6 +862,10 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, video_encoder_configs_[video_idx].encoder_specific_settings = new rtc::RefCountedObject< VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings); + RTC_DCHECK_EQ(video_encoder_configs_[video_idx].simulcast_layers.size(), + 1); + // Min bitrate will be enforced by spatial layer config instead. + video_encoder_configs_[video_idx].simulcast_layers[0].min_bitrate_bps = 0; } else if (params_.video[video_idx].automatic_scaling) { if (params_.video[video_idx].codec == "VP8") { VideoCodecVP8 vp8_settings = VideoEncoder::GetDefaultVp8Settings(); @@ -1106,6 +1108,11 @@ void VideoQualityTest::CreateCapturers() { static_cast(params_.video[video_idx].width), static_cast(params_.video[video_idx].height), test::FrameGeneratorInterface::OutputType::kI010, absl::nullopt); + } else if (params_.video[video_idx].clip_path == "GeneratorNV12") { + frame_generator = test::CreateSquareFrameGenerator( + static_cast(params_.video[video_idx].width), + static_cast(params_.video[video_idx].height), + test::FrameGeneratorInterface::OutputType::kNV12, absl::nullopt); } else if (params_.video[video_idx].clip_path.empty()) { video_sources_[video_idx] = test::CreateVideoCapturer( params_.video[video_idx].width, params_.video[video_idx].height, @@ -1341,8 +1348,8 @@ rtc::scoped_refptr VideoQualityTest::CreateAudioDevice() { // CO_E_NOTINITIALIZED otherwise. The legacy ADM for Windows used internal // COM initialization but the new ADM requires COM to be initialized // externally. - com_initializer_ = std::make_unique( - webrtc_win::ScopedCOMInitializer::kMTA); + com_initializer_ = + std::make_unique(ScopedCOMInitializer::kMTA); RTC_CHECK(com_initializer_->Succeeded()); RTC_CHECK(webrtc_win::core_audio_utility::IsSupported()); RTC_CHECK(webrtc_win::core_audio_utility::IsMMCSSSupported()); diff --git a/TMessagesProj/jni/voip/webrtc/video/video_quality_test.h b/TMessagesProj/jni/voip/webrtc/video/video_quality_test.h index 217783079..f49ce385b 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_quality_test.h +++ b/TMessagesProj/jni/voip/webrtc/video/video_quality_test.h @@ -30,6 +30,7 @@ #include "video/video_analyzer.h" #ifdef WEBRTC_WIN #include "modules/audio_device/win/core_audio_utility_win.h" +#include "rtc_base/win/scoped_com_initializer.h" #endif namespace webrtc { @@ -137,7 +138,7 @@ class VideoQualityTest : public test::CallTest, #ifdef WEBRTC_WIN // Windows Core Audio based ADM needs to run on a COM initialized thread. // Only referenced in combination with --audio --use_real_adm flags. - std::unique_ptr com_initializer_; + std::unique_ptr com_initializer_; #endif }; diff --git a/TMessagesProj/jni/voip/webrtc/video/video_receive_stream.cc b/TMessagesProj/jni/voip/webrtc/video/video_receive_stream.cc index c2769cc93..418901131 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_receive_stream.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_receive_stream.cc @@ -115,8 +115,6 @@ class WebRtcRecordableEncodedFrame : public RecordableEncodedFrame { VideoCodec CreateDecoderVideoCodec(const VideoReceiveStream::Decoder& decoder) { VideoCodec codec; - memset(&codec, 0, sizeof(codec)); - codec.codecType = PayloadStringToCodecType(decoder.video_format.name); if (codec.codecType == kVideoCodecVP8) { @@ -567,7 +565,7 @@ void VideoReceiveStream::OnCompleteFrame( } last_complete_frame_time_ms_ = time_now_ms; - const PlayoutDelay& playout_delay = frame->EncodedImage().playout_delay_; + const VideoPlayoutDelay& playout_delay = frame->EncodedImage().playout_delay_; if (playout_delay.min_ms >= 0) { MutexLock lock(&playout_delay_lock_); frame_minimum_playout_delay_ms_ = playout_delay.min_ms; @@ -620,11 +618,12 @@ void VideoReceiveStream::SetEstimatedPlayoutNtpTimestampMs( RTC_NOTREACHED(); } -void VideoReceiveStream::SetMinimumPlayoutDelay(int delay_ms) { +bool VideoReceiveStream::SetMinimumPlayoutDelay(int delay_ms) { RTC_DCHECK_RUN_ON(&module_process_sequence_checker_); MutexLock lock(&playout_delay_lock_); syncable_minimum_playout_delay_ms_ = delay_ms; UpdatePlayoutDelays(); + return true; } int64_t VideoReceiveStream::GetWaitMs() const { diff --git a/TMessagesProj/jni/voip/webrtc/video/video_receive_stream.h b/TMessagesProj/jni/voip/webrtc/video/video_receive_stream.h index 57329f492..5fb9cf72d 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_receive_stream.h +++ b/TMessagesProj/jni/voip/webrtc/video/video_receive_stream.h @@ -37,7 +37,6 @@ namespace webrtc { class CallStats; class ProcessThread; -class RTPFragmentationHeader; class RtpStreamReceiverInterface; class RtpStreamReceiverControllerInterface; class RtxReceiveStream; @@ -127,7 +126,7 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream, int64_t time_ms) override; // SetMinimumPlayoutDelay is only called by A/V sync. - void SetMinimumPlayoutDelay(int delay_ms) override; + bool SetMinimumPlayoutDelay(int delay_ms) override; std::vector GetSources() const override; diff --git a/TMessagesProj/jni/voip/webrtc/video/video_receive_stream2.cc b/TMessagesProj/jni/voip/webrtc/video/video_receive_stream2.cc index 9e4c2ad76..8cc14e57c 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_receive_stream2.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_receive_stream2.cc @@ -113,8 +113,6 @@ class WebRtcRecordableEncodedFrame : public RecordableEncodedFrame { VideoCodec CreateDecoderVideoCodec(const VideoReceiveStream::Decoder& decoder) { VideoCodec codec; - memset(&codec, 0, sizeof(codec)); - codec.codecType = PayloadStringToCodecType(decoder.video_format.name); if (codec.codecType == kVideoCodecVP8) { @@ -132,8 +130,19 @@ VideoCodec CreateDecoderVideoCodec(const VideoReceiveStream::Decoder& decoder) { return associated_codec; } - codec.width = 320; - codec.height = 180; + FieldTrialOptional width("w"); + FieldTrialOptional height("h"); + ParseFieldTrial( + {&width, &height}, + field_trial::FindFullName("WebRTC-Video-InitialDecoderResolution")); + if (width && height) { + codec.width = width.Value(); + codec.height = height.Value(); + } else { + codec.width = 320; + codec.height = 180; + } + const int kDefaultStartBitrate = 300; codec.startBitrate = codec.minBitrate = codec.maxBitrate = kDefaultStartBitrate; @@ -222,6 +231,9 @@ VideoReceiveStream2::VideoReceiveStream2( max_wait_for_frame_ms_(KeyframeIntervalSettings::ParseFromFieldTrials() .MaxWaitForFrameMs() .value_or(kMaxWaitForFrameMs)), + low_latency_renderer_enabled_("enabled", true), + low_latency_renderer_include_predecode_buffer_("include_predecode_buffer", + true), decode_queue_(task_queue_factory_->CreateTaskQueue( "DecodingQueue", TaskQueueFactory::Priority::HIGH)) { @@ -262,6 +274,10 @@ VideoReceiveStream2::VideoReceiveStream2( rtp_receive_statistics_->EnableRetransmitDetection(config.rtp.remote_ssrc, true); } + + ParseFieldTrial({&low_latency_renderer_enabled_, + &low_latency_renderer_include_predecode_buffer_}, + field_trial::FindFullName("WebRTC-LowLatencyRenderer")); } VideoReceiveStream2::~VideoReceiveStream2() { @@ -544,7 +560,7 @@ void VideoReceiveStream2::OnCompleteFrame( } last_complete_frame_time_ms_ = time_now_ms; - const PlayoutDelay& playout_delay = frame->EncodedImage().playout_delay_; + const VideoPlayoutDelay& playout_delay = frame->EncodedImage().playout_delay_; if (playout_delay.min_ms >= 0) { frame_minimum_playout_delay_ms_ = playout_delay.min_ms; UpdatePlayoutDelays(); @@ -596,10 +612,11 @@ void VideoReceiveStream2::SetEstimatedPlayoutNtpTimestampMs( RTC_NOTREACHED(); } -void VideoReceiveStream2::SetMinimumPlayoutDelay(int delay_ms) { +bool VideoReceiveStream2::SetMinimumPlayoutDelay(int delay_ms) { RTC_DCHECK_RUN_ON(&worker_sequence_checker_); syncable_minimum_playout_delay_ms_ = delay_ms; UpdatePlayoutDelays(); + return true; } int64_t VideoReceiveStream2::GetMaxWaitMs() const { @@ -768,6 +785,22 @@ void VideoReceiveStream2::UpdatePlayoutDelays() const { syncable_minimum_playout_delay_ms_}); if (minimum_delay_ms >= 0) { timing_->set_min_playout_delay(minimum_delay_ms); + if (frame_minimum_playout_delay_ms_ == 0 && + frame_maximum_playout_delay_ms_ > 0 && low_latency_renderer_enabled_) { + // TODO(kron): Estimate frame rate from video stream. + constexpr double kFrameRate = 60.0; + // Convert playout delay in ms to number of frames. + int max_composition_delay_in_frames = std::lrint( + static_cast(frame_maximum_playout_delay_ms_ * kFrameRate) / + rtc::kNumMillisecsPerSec); + if (low_latency_renderer_include_predecode_buffer_) { + // Subtract frames in buffer. + max_composition_delay_in_frames = std::max( + max_composition_delay_in_frames - frame_buffer_->Size(), 0); + } + timing_->SetMaxCompositionDelayInFrames( + absl::make_optional(max_composition_delay_in_frames)); + } } const int maximum_delay_ms = frame_maximum_playout_delay_ms_; diff --git a/TMessagesProj/jni/voip/webrtc/video/video_receive_stream2.h b/TMessagesProj/jni/voip/webrtc/video/video_receive_stream2.h index 71b336e58..e8e3edc3d 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_receive_stream2.h +++ b/TMessagesProj/jni/voip/webrtc/video/video_receive_stream2.h @@ -37,7 +37,6 @@ namespace webrtc { class ProcessThread; -class RTPFragmentationHeader; class RtpStreamReceiverInterface; class RtpStreamReceiverControllerInterface; class RtxReceiveStream; @@ -149,7 +148,7 @@ class VideoReceiveStream2 : public webrtc::VideoReceiveStream, int64_t time_ms) override; // SetMinimumPlayoutDelay is only called by A/V sync. - void SetMinimumPlayoutDelay(int delay_ms) override; + bool SetMinimumPlayoutDelay(int delay_ms) override; std::vector GetSources() const override; @@ -258,6 +257,16 @@ class VideoReceiveStream2 : public webrtc::VideoReceiveStream, bool keyframe_generation_requested_ RTC_GUARDED_BY(worker_sequence_checker_) = false; + // Set by the field trial WebRTC-LowLatencyRenderer. The parameter |enabled| + // determines if the low-latency renderer algorithm should be used for the + // case min playout delay=0 and max playout delay>0. + FieldTrialParameter low_latency_renderer_enabled_; + // Set by the field trial WebRTC-LowLatencyRenderer. The parameter + // |include_predecode_buffer| determines if the predecode buffer should be + // taken into account when calculating maximum number of frames in composition + // queue. + FieldTrialParameter low_latency_renderer_include_predecode_buffer_; + // Defined last so they are destroyed before all other members. rtc::TaskQueue decode_queue_; diff --git a/TMessagesProj/jni/voip/webrtc/video/video_send_stream.cc b/TMessagesProj/jni/voip/webrtc/video/video_send_stream.cc index 30ed86dbd..d6e1b6bbf 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_send_stream.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_send_stream.cc @@ -29,8 +29,6 @@ namespace webrtc { namespace { -constexpr char kTargetBitrateRtcpFieldTrial[] = "WebRTC-Target-Bitrate-Rtcp"; - size_t CalculateMaxHeaderSize(const RtpConfig& config) { size_t header_size = kRtpHeaderSize; size_t extensions_size = 0; @@ -113,13 +111,6 @@ VideoSendStream::VideoSendStream( // it was created on. thread_sync_event_.Wait(rtc::Event::kForever); send_stream_->RegisterProcessThread(module_process_thread); - // TODO(sprang): Enable this also for regular video calls by default, if it - // works well. - if (encoder_config.content_type == VideoEncoderConfig::ContentType::kScreen || - field_trial::IsEnabled(kTargetBitrateRtcpFieldTrial)) { - video_stream_encoder_->SetBitrateAllocationObserver(send_stream_.get()); - } - ReconfigureVideoEncoder(std::move(encoder_config)); } diff --git a/TMessagesProj/jni/voip/webrtc/video/video_send_stream_impl.cc b/TMessagesProj/jni/voip/webrtc/video/video_send_stream_impl.cc index 712af87a0..ee4301862 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_send_stream_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_send_stream_impl.cc @@ -49,6 +49,13 @@ static constexpr int64_t kMaxVbaThrottleTimeMs = 500; constexpr TimeDelta kEncoderTimeOut = TimeDelta::Seconds(2); +// When send-side BWE is used a stricter 1.1x pacing factor is used, rather than +// the 2.5x which is used with receive-side BWE. Provides a more careful +// bandwidth rampup with less risk of overshoots causing adverse effects like +// packet loss. Not used for receive side BWE, since there we lack the probing +// feature and so may result in too slow initial rampup. +static constexpr double kStrictPacingMultiplier = 1.1; + bool TransportSeqNumExtensionConfigured(const VideoSendStream::Config& config) { const std::vector& extensions = config.rtp.extensions; return absl::c_any_of(extensions, [](const RtpExtension& ext) { @@ -175,7 +182,7 @@ bool SameStreamsEnabled(const VideoBitrateAllocation& lhs, } // namespace PacingConfig::PacingConfig() - : pacing_factor("factor", PacedSender::kDefaultPaceMultiplier), + : pacing_factor("factor", kStrictPacingMultiplier), max_pacing_delay("max_delay", TimeDelta::Millis(PacedSender::kMaxQueueLengthMs)) { ParseFieldTrial({&pacing_factor, &max_pacing_delay}, @@ -300,17 +307,6 @@ VideoSendStreamImpl::VideoSendStreamImpl( video_stream_encoder_->SetStartBitrate( bitrate_allocator_->GetStartBitrate(this)); - - // Only request rotation at the source when we positively know that the remote - // side doesn't support the rotation extension. This allows us to prepare the - // encoder in the expectation that rotation is supported - which is the common - // case. - bool rotation_applied = absl::c_none_of( - config_->rtp.extensions, [](const RtpExtension& extension) { - return extension.uri == RtpExtension::kVideoRotationUri; - }); - - video_stream_encoder_->SetSink(this, rotation_applied); } VideoSendStreamImpl::~VideoSendStreamImpl() { @@ -323,6 +319,21 @@ VideoSendStreamImpl::~VideoSendStreamImpl() { void VideoSendStreamImpl::RegisterProcessThread( ProcessThread* module_process_thread) { + // Called on libjingle's worker thread (not worker_queue_), as part of the + // initialization steps. That's also the correct thread/queue for setting the + // state for |video_stream_encoder_|. + + // Only request rotation at the source when we positively know that the remote + // side doesn't support the rotation extension. This allows us to prepare the + // encoder in the expectation that rotation is supported - which is the common + // case. + bool rotation_applied = absl::c_none_of( + config_->rtp.extensions, [](const RtpExtension& extension) { + return extension.uri == RtpExtension::kVideoRotationUri; + }); + + video_stream_encoder_->SetSink(this, rotation_applied); + rtp_video_sender_->RegisterProcessThread(module_process_thread); } @@ -468,6 +479,20 @@ void VideoSendStreamImpl::OnBitrateAllocationUpdated( } } +void VideoSendStreamImpl::OnVideoLayersAllocationUpdated( + VideoLayersAllocation allocation) { + if (!worker_queue_->IsCurrent()) { + auto ptr = weak_ptr_; + worker_queue_->PostTask([allocation = std::move(allocation), ptr] { + if (!ptr.get()) + return; + ptr->OnVideoLayersAllocationUpdated(allocation); + }); + return; + } + rtp_video_sender_->OnVideoLayersAllocationUpdated(allocation); +} + void VideoSendStreamImpl::SignalEncoderActive() { RTC_DCHECK_RUN_ON(worker_queue_); if (rtp_video_sender_->IsActive()) { @@ -558,8 +583,7 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged( EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage( const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* fragmentation) { + const CodecSpecificInfo* codec_specific_info) { // Encoded is called on whatever thread the real encoder implementation run // on. In the case of hardware encoders, there might be several encoders // running in parallel on different threads. @@ -582,8 +606,8 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage( } EncodedImageCallback::Result result(EncodedImageCallback::Result::OK); - result = rtp_video_sender_->OnEncodedImage(encoded_image, codec_specific_info, - fragmentation); + result = + rtp_video_sender_->OnEncodedImage(encoded_image, codec_specific_info); // Check if there's a throttled VideoBitrateAllocation that we should try // sending. rtc::WeakPtr send_stream = weak_ptr_; diff --git a/TMessagesProj/jni/voip/webrtc/video/video_send_stream_impl.h b/TMessagesProj/jni/voip/webrtc/video/video_send_stream_impl.h index 834fed469..41a7859a7 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_send_stream_impl.h +++ b/TMessagesProj/jni/voip/webrtc/video/video_send_stream_impl.h @@ -67,8 +67,7 @@ struct PacingConfig { // An encoder may deliver frames through the EncodedImageCallback on an // arbitrary thread. class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver, - public VideoStreamEncoderInterface::EncoderSink, - public VideoBitrateAllocationObserver { + public VideoStreamEncoderInterface::EncoderSink { public: VideoSendStreamImpl( Clock* clock, @@ -113,27 +112,28 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver, // Implements BitrateAllocatorObserver. uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) override; + // Implements VideoStreamEncoderInterface::EncoderSink void OnEncoderConfigurationChanged( std::vector streams, bool is_svc, VideoEncoderConfig::ContentType content_type, int min_transmit_bitrate_bps) override; + void OnBitrateAllocationUpdated( + const VideoBitrateAllocation& allocation) override; + void OnVideoLayersAllocationUpdated( + VideoLayersAllocation allocation) override; + // Implements EncodedImageCallback. The implementation routes encoded frames // to the |payload_router_| and |config.pre_encode_callback| if set. // Called on an arbitrary encoder callback thread. EncodedImageCallback::Result OnEncodedImage( const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* fragmentation) override; + const CodecSpecificInfo* codec_specific_info) override; // Implements EncodedImageCallback. void OnDroppedFrame(EncodedImageCallback::DropReason reason) override; - // Implements VideoBitrateAllocationObserver. - void OnBitrateAllocationUpdated( - const VideoBitrateAllocation& allocation) override; - // Starts monitoring and sends a keyframe. void StartupVideoSendStream(); // Removes the bitrate observer, stops monitoring and notifies the video diff --git a/TMessagesProj/jni/voip/webrtc/video/video_send_stream_tests.cc b/TMessagesProj/jni/voip/webrtc/video/video_send_stream_tests.cc index 64a1a5571..52e4ddbc4 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_send_stream_tests.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_send_stream_tests.cc @@ -1276,180 +1276,6 @@ TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) { TestPacketFragmentationSize(kVP8, true); } -// The test will go through a number of phases. -// 1. Start sending packets. -// 2. As soon as the RTP stream has been detected, signal a low REMB value to -// suspend the stream. -// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP -// packets. -// 4. Signal a high REMB and then wait for the RTP stream to start again. -// When the stream is detected again, and the stats show that the stream -// is no longer suspended, the test ends. -TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { - static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps. - - class RembObserver : public test::SendTest { - public: - class CaptureObserver : public rtc::VideoSinkInterface { - public: - explicit CaptureObserver(RembObserver* remb_observer) - : remb_observer_(remb_observer) {} - - void OnFrame(const VideoFrame&) { - MutexLock lock(&remb_observer_->mutex_); - if (remb_observer_->test_state_ == kDuringSuspend && - ++remb_observer_->suspended_frame_count_ > kSuspendTimeFrames) { - VideoSendStream::Stats stats = remb_observer_->stream_->GetStats(); - EXPECT_TRUE(stats.suspended); - remb_observer_->SendRtcpFeedback(remb_observer_->high_remb_bps_); - remb_observer_->test_state_ = kWaitingForPacket; - } - } - - private: - RembObserver* const remb_observer_; - }; - - RembObserver() - : SendTest(kDefaultTimeoutMs), - clock_(Clock::GetRealTimeClock()), - capture_observer_(this), - stream_(nullptr), - test_state_(kBeforeSuspend), - rtp_count_(0), - last_sequence_number_(0), - suspended_frame_count_(0), - low_remb_bps_(0), - high_remb_bps_(0) {} - - private: - Action OnSendRtp(const uint8_t* packet, size_t length) override { - MutexLock lock(&mutex_); - ++rtp_count_; - RtpPacket rtp_packet; - EXPECT_TRUE(rtp_packet.Parse(packet, length)); - last_sequence_number_ = rtp_packet.SequenceNumber(); - - if (test_state_ == kBeforeSuspend) { - // The stream has started. Try to suspend it. - SendRtcpFeedback(low_remb_bps_); - test_state_ = kDuringSuspend; - } else if (test_state_ == kDuringSuspend) { - if (rtp_packet.padding_size() == 0) { - // Received non-padding packet during suspension period. Reset the - // counter. - suspended_frame_count_ = 0; - } - SendRtcpFeedback(0); // REMB is only sent if value is > 0. - } else if (test_state_ == kWaitingForPacket) { - if (rtp_packet.padding_size() == 0) { - // Non-padding packet observed. Test is almost complete. Will just - // have to wait for the stats to change. - test_state_ = kWaitingForStats; - } - SendRtcpFeedback(0); // REMB is only sent if value is > 0. - } else if (test_state_ == kWaitingForStats) { - VideoSendStream::Stats stats = stream_->GetStats(); - if (stats.suspended == false) { - // Stats flipped to false. Test is complete. - observation_complete_.Set(); - } - SendRtcpFeedback(0); // REMB is only sent if value is > 0. - } - - return SEND_PACKET; - } - - void set_low_remb_bps(int value) { - MutexLock lock(&mutex_); - low_remb_bps_ = value; - } - - void set_high_remb_bps(int value) { - MutexLock lock(&mutex_); - high_remb_bps_ = value; - } - - void OnVideoStreamsCreated( - VideoSendStream* send_stream, - const std::vector& receive_streams) override { - stream_ = send_stream; - } - - void OnFrameGeneratorCapturerCreated( - test::FrameGeneratorCapturer* frame_generator_capturer) override { - frame_generator_capturer->AddOrUpdateSink(&capture_observer_, - rtc::VideoSinkWants()); - } - - void ModifyVideoConfigs( - VideoSendStream::Config* send_config, - std::vector* receive_configs, - VideoEncoderConfig* encoder_config) override { - RTC_DCHECK_EQ(1, encoder_config->number_of_streams); - transport_adapter_.reset( - new internal::TransportAdapter(send_config->send_transport)); - transport_adapter_->Enable(); - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - send_config->suspend_below_min_bitrate = true; - int min_bitrate_bps = - test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0]; - set_low_remb_bps(min_bitrate_bps - 10000); - int threshold_window = std::max(min_bitrate_bps / 10, 20000); - ASSERT_GT(encoder_config->max_bitrate_bps, - min_bitrate_bps + threshold_window + 5000); - set_high_remb_bps(min_bitrate_bps + threshold_window + 5000); - } - - void PerformTest() override { - EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test."; - } - - enum TestState { - kBeforeSuspend, - kDuringSuspend, - kWaitingForPacket, - kWaitingForStats - }; - - virtual void SendRtcpFeedback(int remb_value) - RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_) { - FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0], - last_sequence_number_, rtp_count_, 0); - RtpRtcpInterface::Configuration config; - config.clock = clock_; - config.receive_statistics = &receive_stats; - config.outgoing_transport = transport_adapter_.get(); - config.rtcp_report_interval_ms = kRtcpIntervalMs; - config.local_media_ssrc = kVideoSendSsrcs[0]; - RTCPSender rtcp_sender(config); - - rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize); - rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]); - if (remb_value > 0) { - rtcp_sender.SetRemb(remb_value, std::vector()); - } - RTCPSender::FeedbackState feedback_state; - EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); - } - - std::unique_ptr transport_adapter_; - Clock* const clock_; - CaptureObserver capture_observer_; - VideoSendStream* stream_; - - Mutex mutex_; - TestState test_state_ RTC_GUARDED_BY(mutex_); - int rtp_count_ RTC_GUARDED_BY(mutex_); - int last_sequence_number_ RTC_GUARDED_BY(mutex_); - int suspended_frame_count_ RTC_GUARDED_BY(mutex_); - int low_remb_bps_ RTC_GUARDED_BY(mutex_); - int high_remb_bps_ RTC_GUARDED_BY(mutex_); - } test; - - RunBaseTest(&test); -} - // This test that padding stops being send after a while if the Camera stops // producing video frames and that padding resumes if the camera restarts. TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) { @@ -2935,12 +2761,13 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { static const int kMaxBitrateKbps = 413; static const int kIncreasedStartBitrateKbps = 451; static const int kIncreasedMaxBitrateKbps = 597; - // If these fields trial are on, we get lower bitrates than expected by this - // test, due to the packetization overhead and encoder pushback. + // TODO(bugs.webrtc.org/12058): If these fields trial are on, we get lower + // bitrates than expected by this test, due to encoder pushback and subtracted + // overhead. webrtc::test::ScopedFieldTrials field_trials( std::string(field_trial::GetFieldTrialString()) + - "WebRTC-SubtractPacketizationOverhead/Disabled/" - "WebRTC-VideoRateControl/bitrate_adjuster:false/"); + "WebRTC-VideoRateControl/bitrate_adjuster:false/" + "WebRTC-SendSideBwe-WithOverhead/Disabled/"); class EncoderBitrateThresholdObserver : public test::SendTest, public VideoBitrateAllocatorFactory, @@ -3150,8 +2977,10 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) { CodecSpecificInfo specifics; specifics.codecType = kVideoCodecGeneric; - uint8_t buffer[16] = {0}; - EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer)); + EncodedImage encoded; + auto buffer = EncodedImageBuffer::Create(16); + memset(buffer->data(), 0, 16); + encoded.SetEncodedData(buffer); encoded.SetTimestamp(input_image.timestamp()); encoded.capture_time_ms_ = input_image.render_time_ms(); @@ -3166,7 +2995,7 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) { callback = callback_; } RTC_DCHECK(callback); - if (callback->OnEncodedImage(encoded, &specifics, nullptr).error != + if (callback->OnEncodedImage(encoded, &specifics).error != EncodedImageCallback::Result::OK) { return -1; } @@ -4020,7 +3849,7 @@ class ContentSwitchTest : public test::SendTest { auto internal_send_peer = test::VideoSendStreamPeer(send_stream_); float pacing_factor = internal_send_peer.GetPacingFactorOverride().value_or(0.0f); - float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier; + float expected_pacing_factor = 1.1; // Strict pacing factor. if (send_stream_->GetStats().content_type == webrtc::VideoContentType::SCREENSHARE) { expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR. diff --git a/TMessagesProj/jni/voip/webrtc/video/video_source_sink_controller.cc b/TMessagesProj/jni/voip/webrtc/video/video_source_sink_controller.cc index a5c0941e0..376eb85ea 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_source_sink_controller.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_source_sink_controller.cc @@ -43,25 +43,33 @@ VideoSourceSinkController::VideoSourceSinkController( RTC_DCHECK(sink_); } +VideoSourceSinkController::~VideoSourceSinkController() { + RTC_DCHECK_RUN_ON(&sequence_checker_); +} + void VideoSourceSinkController::SetSource( rtc::VideoSourceInterface* source) { - rtc::VideoSourceInterface* old_source; - rtc::VideoSinkWants wants; - { - MutexLock lock(&mutex_); - old_source = source_; - source_ = source; - wants = CurrentSettingsToSinkWants(); - } + RTC_DCHECK_RUN_ON(&sequence_checker_); + + rtc::VideoSourceInterface* old_source = source_; + source_ = source; + if (old_source != source && old_source) old_source->RemoveSink(sink_); + if (!source) return; - source->AddOrUpdateSink(sink_, wants); + + source->AddOrUpdateSink(sink_, CurrentSettingsToSinkWants()); +} + +bool VideoSourceSinkController::HasSource() const { + RTC_DCHECK_RUN_ON(&sequence_checker_); + return source_ != nullptr; } void VideoSourceSinkController::PushSourceSinkSettings() { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); if (!source_) return; rtc::VideoSinkWants wants = CurrentSettingsToSinkWants(); @@ -70,62 +78,62 @@ void VideoSourceSinkController::PushSourceSinkSettings() { } VideoSourceRestrictions VideoSourceSinkController::restrictions() const { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); return restrictions_; } absl::optional VideoSourceSinkController::pixels_per_frame_upper_limit() const { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); return pixels_per_frame_upper_limit_; } absl::optional VideoSourceSinkController::frame_rate_upper_limit() const { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); return frame_rate_upper_limit_; } bool VideoSourceSinkController::rotation_applied() const { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); return rotation_applied_; } int VideoSourceSinkController::resolution_alignment() const { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); return resolution_alignment_; } void VideoSourceSinkController::SetRestrictions( VideoSourceRestrictions restrictions) { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); restrictions_ = std::move(restrictions); } void VideoSourceSinkController::SetPixelsPerFrameUpperLimit( absl::optional pixels_per_frame_upper_limit) { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); pixels_per_frame_upper_limit_ = std::move(pixels_per_frame_upper_limit); } void VideoSourceSinkController::SetFrameRateUpperLimit( absl::optional frame_rate_upper_limit) { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); frame_rate_upper_limit_ = std::move(frame_rate_upper_limit); } void VideoSourceSinkController::SetRotationApplied(bool rotation_applied) { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); rotation_applied_ = rotation_applied; } void VideoSourceSinkController::SetResolutionAlignment( int resolution_alignment) { - MutexLock lock(&mutex_); + RTC_DCHECK_RUN_ON(&sequence_checker_); resolution_alignment_ = resolution_alignment; } -// RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_) +// RTC_EXCLUSIVE_LOCKS_REQUIRED(sequence_checker_) rtc::VideoSinkWants VideoSourceSinkController::CurrentSettingsToSinkWants() const { rtc::VideoSinkWants wants; diff --git a/TMessagesProj/jni/voip/webrtc/video/video_source_sink_controller.h b/TMessagesProj/jni/voip/webrtc/video/video_source_sink_controller.h index 877cf8590..ed8f99097 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_source_sink_controller.h +++ b/TMessagesProj/jni/voip/webrtc/video/video_source_sink_controller.h @@ -18,7 +18,7 @@ #include "api/video/video_sink_interface.h" #include "api/video/video_source_interface.h" #include "call/adaptation/video_source_restrictions.h" -#include "rtc_base/synchronization/mutex.h" +#include "rtc_base/synchronization/sequence_checker.h" namespace webrtc { @@ -31,7 +31,11 @@ class VideoSourceSinkController { VideoSourceSinkController(rtc::VideoSinkInterface* sink, rtc::VideoSourceInterface* source); + ~VideoSourceSinkController(); + void SetSource(rtc::VideoSourceInterface* source); + bool HasSource() const; + // Must be called in order for changes to settings to have an effect. This // allows you to modify multiple properties in a single push to the sink. void PushSourceSinkSettings(); @@ -53,20 +57,27 @@ class VideoSourceSinkController { private: rtc::VideoSinkWants CurrentSettingsToSinkWants() const - RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + RTC_EXCLUSIVE_LOCKS_REQUIRED(sequence_checker_); + + // Used to ensure that this class is called on threads/sequences that it and + // downstream implementations were designed for. + // In practice, this represent's libjingle's worker thread. + SequenceChecker sequence_checker_; - mutable Mutex mutex_; rtc::VideoSinkInterface* const sink_; - rtc::VideoSourceInterface* source_ RTC_GUARDED_BY(&mutex_); + rtc::VideoSourceInterface* source_ + RTC_GUARDED_BY(&sequence_checker_); // Pixel and frame rate restrictions. - VideoSourceRestrictions restrictions_ RTC_GUARDED_BY(&mutex_); + VideoSourceRestrictions restrictions_ RTC_GUARDED_BY(&sequence_checker_); // Ensures that even if we are not restricted, the sink is never configured // above this limit. Example: We are not CPU limited (no |restrictions_|) but // our encoder is capped at 30 fps (= |frame_rate_upper_limit_|). - absl::optional pixels_per_frame_upper_limit_ RTC_GUARDED_BY(&mutex_); - absl::optional frame_rate_upper_limit_ RTC_GUARDED_BY(&mutex_); - bool rotation_applied_ RTC_GUARDED_BY(&mutex_) = false; - int resolution_alignment_ RTC_GUARDED_BY(&mutex_) = 1; + absl::optional pixels_per_frame_upper_limit_ + RTC_GUARDED_BY(&sequence_checker_); + absl::optional frame_rate_upper_limit_ + RTC_GUARDED_BY(&sequence_checker_); + bool rotation_applied_ RTC_GUARDED_BY(&sequence_checker_) = false; + int resolution_alignment_ RTC_GUARDED_BY(&sequence_checker_) = 1; }; } // namespace webrtc diff --git a/TMessagesProj/jni/voip/webrtc/video/video_stream_decoder_impl.cc b/TMessagesProj/jni/voip/webrtc/video/video_stream_decoder_impl.cc index 02ba45e25..f5b0f5f78 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_stream_decoder_impl.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_stream_decoder_impl.cc @@ -26,7 +26,7 @@ VideoStreamDecoderImpl::VideoStreamDecoderImpl( std::map> decoder_settings) : timing_(Clock::GetRealTimeClock()), decode_callbacks_(this), - next_frame_timestamps_index_(0), + next_frame_info_index_(0), callbacks_(callbacks), keyframe_required_(true), decoder_factory_(decoder_factory), @@ -39,7 +39,6 @@ VideoStreamDecoderImpl::VideoStreamDecoderImpl( decode_queue_(task_queue_factory->CreateTaskQueue( "video_stream_decoder_decode_queue", TaskQueueFactory::Priority::NORMAL)) { - frame_timestamps_.fill({-1, -1, -1}); bookkeeping_queue_.PostTask([this]() { RTC_DCHECK_RUN_ON(&bookkeeping_queue_); StartNextDecode(); @@ -125,16 +124,15 @@ VideoDecoder* VideoStreamDecoderImpl::GetDecoder(int payload_type) { return decoder_.get(); } -void VideoStreamDecoderImpl::SaveFrameTimestamps( +void VideoStreamDecoderImpl::SaveFrameInfo( const video_coding::EncodedFrame& frame) { - FrameTimestamps* frame_timestamps = - &frame_timestamps_[next_frame_timestamps_index_]; - frame_timestamps->timestamp = frame.Timestamp(); - frame_timestamps->decode_start_time_ms = rtc::TimeMillis(); - frame_timestamps->render_time_us = frame.RenderTimeMs() * 1000; + FrameInfo* frame_info = &frame_info_[next_frame_info_index_]; + frame_info->timestamp = frame.Timestamp(); + frame_info->decode_start_time_ms = rtc::TimeMillis(); + frame_info->render_time_us = frame.RenderTimeMs() * 1000; + frame_info->content_type = frame.EncodedImage().content_type_; - next_frame_timestamps_index_ = - Add(next_frame_timestamps_index_, 1); + next_frame_info_index_ = Add(next_frame_info_index_, 1); } void VideoStreamDecoderImpl::StartNextDecode() { @@ -155,7 +153,7 @@ void VideoStreamDecoderImpl::OnNextFrameCallback( switch (result) { case video_coding::FrameBuffer::kFrameFound: { RTC_DCHECK(frame); - SaveFrameTimestamps(*frame); + SaveFrameInfo(*frame); MutexLock lock(&shut_down_mutex_); if (shut_down_) { @@ -230,14 +228,14 @@ VideoStreamDecoderImpl::DecodeResult VideoStreamDecoderImpl::DecodeFrame( } } -VideoStreamDecoderImpl::FrameTimestamps* -VideoStreamDecoderImpl::GetFrameTimestamps(int64_t timestamp) { - int start_time_index = next_frame_timestamps_index_; - for (int i = 0; i < kFrameTimestampsMemory; ++i) { - start_time_index = Subtract(start_time_index, 1); +VideoStreamDecoderImpl::FrameInfo* VideoStreamDecoderImpl::GetFrameInfo( + int64_t timestamp) { + int start_time_index = next_frame_info_index_; + for (int i = 0; i < kFrameInfoMemory; ++i) { + start_time_index = Subtract(start_time_index, 1); - if (frame_timestamps_[start_time_index].timestamp == timestamp) - return &frame_timestamps_[start_time_index]; + if (frame_info_[start_time_index].timestamp == timestamp) + return &frame_info_[start_time_index]; } return nullptr; @@ -250,29 +248,33 @@ void VideoStreamDecoderImpl::OnDecodedFrameCallback( int64_t decode_stop_time_ms = rtc::TimeMillis(); bookkeeping_queue_.PostTask([this, decode_stop_time_ms, decoded_image, - decode_time_ms, qp]() { + decode_time_ms, qp]() mutable { RTC_DCHECK_RUN_ON(&bookkeeping_queue_); - FrameTimestamps* frame_timestamps = - GetFrameTimestamps(decoded_image.timestamp()); - if (!frame_timestamps) { + FrameInfo* frame_info = GetFrameInfo(decoded_image.timestamp()); + if (!frame_info) { RTC_LOG(LS_ERROR) << "No frame information found for frame with timestamp" << decoded_image.timestamp(); return; } - absl::optional casted_qp; + Callbacks::FrameInfo callback_info; + callback_info.content_type = frame_info->content_type; + if (qp) - casted_qp.emplace(*qp); + callback_info.qp.emplace(*qp); - absl::optional casted_decode_time_ms(decode_time_ms.value_or( - decode_stop_time_ms - frame_timestamps->decode_start_time_ms)); + if (!decode_time_ms) { + decode_time_ms = decode_stop_time_ms - frame_info->decode_start_time_ms; + } + decoded_image.set_processing_time( + {Timestamp::Millis(frame_info->decode_start_time_ms), + Timestamp::Millis(frame_info->decode_start_time_ms + + *decode_time_ms)}); + decoded_image.set_timestamp_us(frame_info->render_time_us); + timing_.StopDecodeTimer(*decode_time_ms, decode_stop_time_ms); - timing_.StopDecodeTimer(*casted_decode_time_ms, decode_stop_time_ms); - - VideoFrame copy = decoded_image; - copy.set_timestamp_us(frame_timestamps->render_time_us); - callbacks_->OnDecodedFrame(copy, casted_decode_time_ms, casted_qp); + callbacks_->OnDecodedFrame(decoded_image, callback_info); }); } diff --git a/TMessagesProj/jni/voip/webrtc/video/video_stream_decoder_impl.h b/TMessagesProj/jni/voip/webrtc/video/video_stream_decoder_impl.h index 2f33e9d34..69a819505 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_stream_decoder_impl.h +++ b/TMessagesProj/jni/voip/webrtc/video/video_stream_decoder_impl.h @@ -62,16 +62,16 @@ class VideoStreamDecoderImpl : public VideoStreamDecoderInterface { kDecodeFailure, }; - struct FrameTimestamps { - int64_t timestamp; + struct FrameInfo { + int64_t timestamp = -1; int64_t decode_start_time_ms; int64_t render_time_us; + VideoContentType content_type; }; - void SaveFrameTimestamps(const video_coding::EncodedFrame& frame) - RTC_RUN_ON(bookkeeping_queue_); - FrameTimestamps* GetFrameTimestamps(int64_t timestamp) + void SaveFrameInfo(const video_coding::EncodedFrame& frame) RTC_RUN_ON(bookkeeping_queue_); + FrameInfo* GetFrameInfo(int64_t timestamp) RTC_RUN_ON(bookkeeping_queue_); void StartNextDecode() RTC_RUN_ON(bookkeeping_queue_); void OnNextFrameCallback(std::unique_ptr frame, video_coding::FrameBuffer::ReturnReason res) @@ -90,10 +90,10 @@ class VideoStreamDecoderImpl : public VideoStreamDecoderInterface { // Some decoders are pipelined so it is not sufficient to save frame info // for the last frame only. - static constexpr int kFrameTimestampsMemory = 8; - std::array frame_timestamps_ + static constexpr int kFrameInfoMemory = 8; + std::array frame_info_ RTC_GUARDED_BY(bookkeeping_queue_); - int next_frame_timestamps_index_ RTC_GUARDED_BY(bookkeeping_queue_); + int next_frame_info_index_ RTC_GUARDED_BY(bookkeeping_queue_); VideoStreamDecoderInterface::Callbacks* const callbacks_ RTC_PT_GUARDED_BY(bookkeeping_queue_); video_coding::VideoLayerFrameId last_continuous_id_ diff --git a/TMessagesProj/jni/voip/webrtc/video/video_stream_encoder.cc b/TMessagesProj/jni/voip/webrtc/video/video_stream_encoder.cc index dfd7bf49a..b3bef4901 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_stream_encoder.cc +++ b/TMessagesProj/jni/voip/webrtc/video/video_stream_encoder.cc @@ -26,6 +26,7 @@ #include "api/video/video_adaptation_reason.h" #include "api/video/video_bitrate_allocator_factory.h" #include "api/video/video_codec_constants.h" +#include "api/video/video_layers_allocation.h" #include "api/video_codecs/video_encoder.h" #include "call/adaptation/resource_adaptation_processor.h" #include "call/adaptation/video_stream_adapter.h" @@ -34,18 +35,18 @@ #include "rtc_base/arraysize.h" #include "rtc_base/checks.h" #include "rtc_base/constructor_magic.h" +#include "rtc_base/event.h" #include "rtc_base/experiments/alr_experiment.h" #include "rtc_base/experiments/rate_control_settings.h" #include "rtc_base/location.h" #include "rtc_base/logging.h" #include "rtc_base/strings/string_builder.h" -#include "rtc_base/synchronization/mutex.h" #include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/thread_annotations.h" -#include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" #include "system_wrappers/include/field_trial.h" #include "video/adaptation/video_stream_encoder_resource_manager.h" +#include "video/alignment_adjuster.h" namespace webrtc { @@ -122,21 +123,44 @@ bool RequiresEncoderReset(const VideoCodec& prev_send_codec, } for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams; ++i) { - if (new_send_codec.simulcastStream[i].width != + if (!new_send_codec.simulcastStream[i].active) { + // No need to reset when stream is inactive. + continue; + } + + if (!prev_send_codec.simulcastStream[i].active || + new_send_codec.simulcastStream[i].width != prev_send_codec.simulcastStream[i].width || new_send_codec.simulcastStream[i].height != prev_send_codec.simulcastStream[i].height || - new_send_codec.simulcastStream[i].maxFramerate != - prev_send_codec.simulcastStream[i].maxFramerate || new_send_codec.simulcastStream[i].numberOfTemporalLayers != prev_send_codec.simulcastStream[i].numberOfTemporalLayers || new_send_codec.simulcastStream[i].qpMax != - prev_send_codec.simulcastStream[i].qpMax || - new_send_codec.simulcastStream[i].active != - prev_send_codec.simulcastStream[i].active) { + prev_send_codec.simulcastStream[i].qpMax) { return true; } } + + if (new_send_codec.codecType == kVideoCodecVP9) { + size_t num_spatial_layers = new_send_codec.VP9().numberOfSpatialLayers; + for (unsigned char i = 0; i < num_spatial_layers; ++i) { + if (new_send_codec.spatialLayers[i].width != + prev_send_codec.spatialLayers[i].width || + new_send_codec.spatialLayers[i].height != + prev_send_codec.spatialLayers[i].height || + new_send_codec.spatialLayers[i].numberOfTemporalLayers != + prev_send_codec.spatialLayers[i].numberOfTemporalLayers || + new_send_codec.spatialLayers[i].qpMax != + prev_send_codec.spatialLayers[i].qpMax) { + return true; + } + } + } + + if (new_send_codec.ScalabilityMode() != prev_send_codec.ScalabilityMode()) { + return true; + } + return false; } @@ -186,6 +210,73 @@ VideoBitrateAllocation UpdateAllocationFromEncoderInfo( return new_allocation; } +// Converts a VideoBitrateAllocation that contains allocated bitrate per layer, +// and an EncoderInfo that contains information about the actual encoder +// structure used by a codec. Stream structures can be Ksvc, Full SVC, Simulcast +// etc. +VideoLayersAllocation CreateVideoLayersAllocation( + const VideoCodec& encoder_config, + const VideoEncoder::RateControlParameters& current_rate, + const VideoEncoder::EncoderInfo& encoder_info) { + const VideoBitrateAllocation& target_bitrate = current_rate.target_bitrate; + VideoLayersAllocation layers_allocation; + if (target_bitrate.get_sum_bps() == 0) { + return layers_allocation; + } + + if (encoder_config.numberOfSimulcastStreams > 0) { + layers_allocation.resolution_and_frame_rate_is_valid = true; + for (int si = 0; si < encoder_config.numberOfSimulcastStreams; ++si) { + if (!target_bitrate.IsSpatialLayerUsed(si) || + target_bitrate.GetSpatialLayerSum(si) == 0) { + break; + } + layers_allocation.active_spatial_layers.emplace_back(); + VideoLayersAllocation::SpatialLayer& spatial_layer = + layers_allocation.active_spatial_layers.back(); + spatial_layer.width = encoder_config.simulcastStream[si].width; + spatial_layer.height = encoder_config.simulcastStream[si].height; + spatial_layer.rtp_stream_index = si; + spatial_layer.spatial_id = 0; + auto frame_rate_fraction = + VideoEncoder::EncoderInfo::kMaxFramerateFraction; + if (encoder_info.fps_allocation[si].size() == 1) { + // One TL is signalled to be used by the encoder. Do not distribute + // bitrate allocation across TLs (use sum at tl:0). + spatial_layer.target_bitrate_per_temporal_layer.push_back( + DataRate::BitsPerSec(target_bitrate.GetSpatialLayerSum(si))); + frame_rate_fraction = encoder_info.fps_allocation[si][0]; + } else { // Temporal layers are supported. + uint32_t temporal_layer_bitrate_bps = 0; + for (size_t ti = 0; + ti < encoder_config.simulcastStream[si].numberOfTemporalLayers; + ++ti) { + if (!target_bitrate.HasBitrate(si, ti)) { + break; + } + if (ti < encoder_info.fps_allocation[si].size()) { + // Use frame rate of the top used temporal layer. + frame_rate_fraction = encoder_info.fps_allocation[si][ti]; + } + temporal_layer_bitrate_bps += target_bitrate.GetBitrate(si, ti); + spatial_layer.target_bitrate_per_temporal_layer.push_back( + DataRate::BitsPerSec(temporal_layer_bitrate_bps)); + } + } + // Encoder may drop frames internally if `maxFramerate` is set. + spatial_layer.frame_rate_fps = std::min( + static_cast(encoder_config.simulcastStream[si].maxFramerate), + static_cast( + (current_rate.framerate_fps * frame_rate_fraction) / + VideoEncoder::EncoderInfo::kMaxFramerateFraction)); + } + } else { + // TODO(bugs.webrtc.org/12000): Implement support for kSVC and full SVC. + } + + return layers_allocation; +} + } // namespace VideoStreamEncoder::EncoderRateSettings::EncoderRateSettings() @@ -218,48 +309,38 @@ bool VideoStreamEncoder::EncoderRateSettings::operator!=( class VideoStreamEncoder::DegradationPreferenceManager : public DegradationPreferenceProvider { public: - DegradationPreferenceManager() + explicit DegradationPreferenceManager( + VideoStreamAdapter* video_stream_adapter) : degradation_preference_(DegradationPreference::DISABLED), is_screenshare_(false), - effective_degradation_preference_(DegradationPreference::DISABLED) {} - - ~DegradationPreferenceManager() override { - RTC_DCHECK(!video_stream_adapter_); + effective_degradation_preference_(DegradationPreference::DISABLED), + video_stream_adapter_(video_stream_adapter) { + RTC_DCHECK(video_stream_adapter_); + sequence_checker_.Detach(); } + ~DegradationPreferenceManager() override = default; + DegradationPreference degradation_preference() const override { - MutexLock lock(&lock_); + RTC_DCHECK_RUN_ON(&sequence_checker_); return effective_degradation_preference_; } void SetDegradationPreference(DegradationPreference degradation_preference) { - MutexLock lock(&lock_); + RTC_DCHECK_RUN_ON(&sequence_checker_); degradation_preference_ = degradation_preference; MaybeUpdateEffectiveDegradationPreference(); } void SetIsScreenshare(bool is_screenshare) { - MutexLock lock(&lock_); + RTC_DCHECK_RUN_ON(&sequence_checker_); is_screenshare_ = is_screenshare; MaybeUpdateEffectiveDegradationPreference(); } - void SetVideoStreamAdapterQueue( - TaskQueueBase* video_stream_adapter_task_queue) { - RTC_DCHECK(!video_stream_adapter_task_queue_); - RTC_DCHECK(video_stream_adapter_task_queue); - RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue); - video_stream_adapter_task_queue_ = video_stream_adapter_task_queue; - } - - void SetVideoStreamAdapter(VideoStreamAdapter* video_stream_adapter) { - RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue_); - video_stream_adapter_ = video_stream_adapter; - } - private: void MaybeUpdateEffectiveDegradationPreference() - RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_) { + RTC_RUN_ON(&sequence_checker_) { DegradationPreference effective_degradation_preference = (is_screenshare_ && degradation_preference_ == DegradationPreference::BALANCED) @@ -268,27 +349,18 @@ class VideoStreamEncoder::DegradationPreferenceManager if (effective_degradation_preference != effective_degradation_preference_) { effective_degradation_preference_ = effective_degradation_preference; - if (video_stream_adapter_task_queue_) { - video_stream_adapter_task_queue_->PostTask( - ToQueuedTask([this, effective_degradation_preference]() { - RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue_); - if (video_stream_adapter_) { - video_stream_adapter_->SetDegradationPreference( - effective_degradation_preference); - } - })); - } + video_stream_adapter_->SetDegradationPreference( + effective_degradation_preference); } } - mutable Mutex lock_; - DegradationPreference degradation_preference_ RTC_GUARDED_BY(&lock_); - bool is_screenshare_ RTC_GUARDED_BY(&lock_); + SequenceChecker sequence_checker_; + DegradationPreference degradation_preference_ + RTC_GUARDED_BY(&sequence_checker_); + bool is_screenshare_ RTC_GUARDED_BY(&sequence_checker_); DegradationPreference effective_degradation_preference_ - RTC_GUARDED_BY(&lock_); - TaskQueueBase* video_stream_adapter_task_queue_ = nullptr; - VideoStreamAdapter* video_stream_adapter_ - RTC_GUARDED_BY(&video_stream_adapter_task_queue_); + RTC_GUARDED_BY(&sequence_checker_); + VideoStreamAdapter* video_stream_adapter_ RTC_GUARDED_BY(&sequence_checker_); }; VideoStreamEncoder::VideoStreamEncoder( @@ -298,7 +370,7 @@ VideoStreamEncoder::VideoStreamEncoder( const VideoStreamEncoderSettings& settings, std::unique_ptr overuse_detector, TaskQueueFactory* task_queue_factory) - : shutdown_event_(true /* manual_reset */, false), + : main_queue_(TaskQueueBase::Current()), number_of_cores_(number_of_cores), quality_scaling_experiment_enabled_(QualityScalingExperiment::Enabled()), sink_(nullptr), @@ -332,7 +404,6 @@ VideoStreamEncoder::VideoStreamEncoder( animation_start_time_(Timestamp::PlusInfinity()), cap_resolution_due_to_video_content_(false), expect_resize_state_(ExpectResizeState::kNoResize), - bitrate_observer_(nullptr), fec_controller_override_(nullptr), force_disable_frame_dropper_(false), input_framerate_(kFrameRateAvergingWindowSizeMs, 1000), @@ -347,13 +418,14 @@ VideoStreamEncoder::VideoStreamEncoder( encoder_switch_requested_(false), input_state_provider_(encoder_stats_observer), video_stream_adapter_( - std::make_unique(&input_state_provider_)), + std::make_unique(&input_state_provider_, + encoder_stats_observer)), resource_adaptation_processor_( std::make_unique( - encoder_stats_observer, video_stream_adapter_.get())), degradation_preference_manager_( - std::make_unique()), + std::make_unique( + video_stream_adapter_.get())), adaptation_constraints_(), stream_resource_manager_(&input_state_provider_, encoder_stats_observer, @@ -363,39 +435,28 @@ VideoStreamEncoder::VideoStreamEncoder( degradation_preference_manager_.get()), video_source_sink_controller_(/*sink=*/this, /*source=*/nullptr), - resource_adaptation_queue_(task_queue_factory->CreateTaskQueue( - "ResourceAdaptationQueue", - TaskQueueFactory::Priority::NORMAL)), encoder_queue_(task_queue_factory->CreateTaskQueue( "EncoderQueue", TaskQueueFactory::Priority::NORMAL)) { + RTC_DCHECK(main_queue_); RTC_DCHECK(encoder_stats_observer); RTC_DCHECK_GE(number_of_cores, 1); - stream_resource_manager_.Initialize(&encoder_queue_, - &resource_adaptation_queue_); + stream_resource_manager_.Initialize(&encoder_queue_); rtc::Event initialize_processor_event; - resource_adaptation_queue_.PostTask([this, &initialize_processor_event] { - RTC_DCHECK_RUN_ON(&resource_adaptation_queue_); - resource_adaptation_processor_->SetResourceAdaptationQueue( - resource_adaptation_queue_.Get()); + encoder_queue_.PostTask([this, &initialize_processor_event] { + RTC_DCHECK_RUN_ON(&encoder_queue_); + resource_adaptation_processor_->SetTaskQueue(encoder_queue_.Get()); stream_resource_manager_.SetAdaptationProcessor( resource_adaptation_processor_.get(), video_stream_adapter_.get()); resource_adaptation_processor_->AddResourceLimitationsListener( &stream_resource_manager_); video_stream_adapter_->AddRestrictionsListener(&stream_resource_manager_); video_stream_adapter_->AddRestrictionsListener(this); - degradation_preference_manager_->SetVideoStreamAdapterQueue( - resource_adaptation_queue_.Get()); - degradation_preference_manager_->SetVideoStreamAdapter( - video_stream_adapter_.get()); // Add the stream resource manager's resources to the processor. adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints(); - for (auto& resource : stream_resource_manager_.MappedResources()) { - resource_adaptation_processor_->AddResource(resource); - } for (auto* constraint : adaptation_constraints_) { video_stream_adapter_->AddAdaptationConstraint(constraint); } @@ -405,62 +466,42 @@ VideoStreamEncoder::VideoStreamEncoder( } VideoStreamEncoder::~VideoStreamEncoder() { - RTC_DCHECK_RUN_ON(&thread_checker_); - RTC_DCHECK(shutdown_event_.Wait(0)) + RTC_DCHECK_RUN_ON(main_queue_); + RTC_DCHECK(!video_source_sink_controller_.HasSource()) << "Must call ::Stop() before destruction."; } void VideoStreamEncoder::Stop() { - RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_DCHECK_RUN_ON(main_queue_); video_source_sink_controller_.SetSource(nullptr); - if (resource_adaptation_processor_) { - for (auto& resource : stream_resource_manager_.MappedResources()) { - resource_adaptation_processor_->RemoveResource(resource); - } - } - rtc::Event shutdown_adaptation_processor_event; - resource_adaptation_queue_.PostTask([this, - &shutdown_adaptation_processor_event] { - RTC_DCHECK_RUN_ON(&resource_adaptation_queue_); + rtc::Event shutdown_event; + + encoder_queue_.PostTask([this, &shutdown_event] { + RTC_DCHECK_RUN_ON(&encoder_queue_); if (resource_adaptation_processor_) { - // Removed on the resource_adaptaiton_processor_ queue because the - // adaptation_constraints_ and adaptation_listeners_ fields are guarded by - // this queue. + stream_resource_manager_.StopManagedResources(); for (auto* constraint : adaptation_constraints_) { video_stream_adapter_->RemoveAdaptationConstraint(constraint); } + for (auto& resource : additional_resources_) { + stream_resource_manager_.RemoveResource(resource); + } + additional_resources_.clear(); video_stream_adapter_->RemoveRestrictionsListener(this); video_stream_adapter_->RemoveRestrictionsListener( &stream_resource_manager_); resource_adaptation_processor_->RemoveResourceLimitationsListener( &stream_resource_manager_); stream_resource_manager_.SetAdaptationProcessor(nullptr, nullptr); - degradation_preference_manager_->SetVideoStreamAdapter(nullptr); resource_adaptation_processor_.reset(); } - shutdown_adaptation_processor_event.Set(); - }); - shutdown_adaptation_processor_event.Wait(rtc::Event::kForever); - encoder_queue_.PostTask([this] { - RTC_DCHECK_RUN_ON(&encoder_queue_); - stream_resource_manager_.StopManagedResources(); rate_allocator_ = nullptr; - bitrate_observer_ = nullptr; ReleaseEncoder(); - shutdown_event_.Set(); - }); - shutdown_event_.Wait(rtc::Event::kForever); -} - -void VideoStreamEncoder::SetBitrateAllocationObserver( - VideoBitrateAllocationObserver* bitrate_observer) { - RTC_DCHECK_RUN_ON(&thread_checker_); - encoder_queue_.PostTask([this, bitrate_observer] { - RTC_DCHECK_RUN_ON(&encoder_queue_); - RTC_DCHECK(!bitrate_observer_); - bitrate_observer_ = bitrate_observer; + encoder_ = nullptr; + shutdown_event.Set(); }); + shutdown_event.Wait(rtc::Event::kForever); } void VideoStreamEncoder::SetFecControllerOverride( @@ -477,15 +518,15 @@ void VideoStreamEncoder::SetFecControllerOverride( void VideoStreamEncoder::AddAdaptationResource( rtc::scoped_refptr resource) { + RTC_DCHECK_RUN_ON(main_queue_); // Map any externally added resources as kCpu for the sake of stats reporting. // TODO(hbos): Make the manager map any unknown resources to kCpu and get rid // of this MapResourceToReason() call. rtc::Event map_resource_event; encoder_queue_.PostTask([this, resource, &map_resource_event] { RTC_DCHECK_RUN_ON(&encoder_queue_); - stream_resource_manager_.MapResourceToReason(resource, - VideoAdaptationReason::kCpu); - resource_adaptation_processor_->AddResource(resource); + additional_resources_.push_back(resource); + stream_resource_manager_.AddResource(resource, VideoAdaptationReason::kCpu); map_resource_event.Set(); }); map_resource_event.Wait(rtc::Event::kForever); @@ -493,21 +534,22 @@ void VideoStreamEncoder::AddAdaptationResource( std::vector> VideoStreamEncoder::GetAdaptationResources() { + RTC_DCHECK_RUN_ON(main_queue_); return resource_adaptation_processor_->GetResources(); } void VideoStreamEncoder::SetSource( rtc::VideoSourceInterface* source, const DegradationPreference& degradation_preference) { - RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_DCHECK_RUN_ON(main_queue_); video_source_sink_controller_.SetSource(source); input_state_provider_.OnHasInputChanged(source); - degradation_preference_manager_->SetDegradationPreference( - degradation_preference); // This may trigger reconfiguring the QualityScaler on the encoder queue. encoder_queue_.PostTask([this, degradation_preference] { RTC_DCHECK_RUN_ON(&encoder_queue_); + degradation_preference_manager_->SetDegradationPreference( + degradation_preference); stream_resource_manager_.SetDegradationPreferences(degradation_preference); if (encoder_) { stream_resource_manager_.ConfigureQualityScaler( @@ -517,8 +559,10 @@ void VideoStreamEncoder::SetSource( } void VideoStreamEncoder::SetSink(EncoderSink* sink, bool rotation_applied) { + RTC_DCHECK_RUN_ON(main_queue_); video_source_sink_controller_.SetRotationApplied(rotation_applied); video_source_sink_controller_.PushSourceSinkSettings(); + encoder_queue_.PostTask([this, sink] { RTC_DCHECK_RUN_ON(&encoder_queue_); sink_ = sink; @@ -575,6 +619,7 @@ void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config, // the VideoBitrateAllocator and call OnEncoderConfigurationChanged with a // "soft" reconfiguration. void VideoStreamEncoder::ReconfigureEncoder() { + // Running on the encoder queue. RTC_DCHECK(pending_encoder_reconfiguration_); if (!encoder_selector_ && @@ -585,11 +630,41 @@ void VideoStreamEncoder::ReconfigureEncoder() { conf.codec_name = encoder_switch_experiment_.to_codec; conf.param = encoder_switch_experiment_.to_param; conf.value = encoder_switch_experiment_.to_value; - settings_.encoder_switch_request_callback->RequestEncoderSwitch(conf); + QueueRequestEncoderSwitch(conf); encoder_switch_requested_ = true; } + bool encoder_reset_required = false; + if (pending_encoder_creation_) { + // Destroy existing encoder instance before creating a new one. Otherwise + // attempt to create another instance will fail if encoder factory + // supports only single instance of encoder of given type. + encoder_.reset(); + + encoder_ = settings_.encoder_factory->CreateVideoEncoder( + encoder_config_.video_format); + // TODO(nisse): What to do if creating the encoder fails? Crash, + // or just discard incoming frames? + RTC_CHECK(encoder_); + + if (encoder_selector_) { + encoder_selector_->OnCurrentEncoder(encoder_config_.video_format); + } + + encoder_->SetFecControllerOverride(fec_controller_override_); + + codec_info_ = settings_.encoder_factory->QueryVideoEncoder( + encoder_config_.video_format); + + encoder_reset_required = true; + } + + // Possibly adjusts scale_resolution_down_by in |encoder_config_| to limit the + // alignment value. + int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors( + encoder_->GetEncoderInfo(), &encoder_config_); + std::vector streams = encoder_config_.video_stream_factory->CreateEncoderStreams( last_frame_info_->width, last_frame_info_->height, encoder_config_); @@ -622,31 +697,6 @@ void VideoStreamEncoder::ReconfigureEncoder() { crop_width_ = last_frame_info_->width - highest_stream_width; crop_height_ = last_frame_info_->height - highest_stream_height; - bool encoder_reset_required = false; - if (pending_encoder_creation_) { - // Destroy existing encoder instance before creating a new one. Otherwise - // attempt to create another instance will fail if encoder factory - // supports only single instance of encoder of given type. - encoder_.reset(); - - encoder_ = settings_.encoder_factory->CreateVideoEncoder( - encoder_config_.video_format); - // TODO(nisse): What to do if creating the encoder fails? Crash, - // or just discard incoming frames? - RTC_CHECK(encoder_); - - if (encoder_selector_) { - encoder_selector_->OnCurrentEncoder(encoder_config_.video_format); - } - - encoder_->SetFecControllerOverride(fec_controller_override_); - - codec_info_ = settings_.encoder_factory->QueryVideoEncoder( - encoder_config_.video_format); - - encoder_reset_required = true; - } - encoder_bitrate_limits_ = encoder_->GetEncoderInfo().GetEncoderBitrateLimitsForResolution( last_frame_info_->width * last_frame_info_->height); @@ -754,13 +804,18 @@ void VideoStreamEncoder::ReconfigureEncoder() { for (const auto& stream : streams) { max_framerate = std::max(stream.max_framerate, max_framerate); } - int alignment = encoder_->GetEncoderInfo().requested_resolution_alignment; - if (max_framerate != video_source_sink_controller_.frame_rate_upper_limit() || - alignment != video_source_sink_controller_.resolution_alignment()) { - video_source_sink_controller_.SetFrameRateUpperLimit(max_framerate); - video_source_sink_controller_.SetResolutionAlignment(alignment); - video_source_sink_controller_.PushSourceSinkSettings(); - } + + main_queue_->PostTask( + ToQueuedTask(task_safety_, [this, max_framerate, alignment]() { + RTC_DCHECK_RUN_ON(main_queue_); + if (max_framerate != + video_source_sink_controller_.frame_rate_upper_limit() || + alignment != video_source_sink_controller_.resolution_alignment()) { + video_source_sink_controller_.SetFrameRateUpperLimit(max_framerate); + video_source_sink_controller_.SetResolutionAlignment(alignment); + video_source_sink_controller_.PushSourceSinkSettings(); + } + })); if (codec.maxBitrate == 0) { // max is one bit per pixel @@ -788,7 +843,7 @@ void VideoStreamEncoder::ReconfigureEncoder() { // start bitrate or max framerate has changed. if (!encoder_reset_required) { encoder_reset_required = RequiresEncoderReset( - codec, send_codec_, was_encode_called_since_last_initialization_); + send_codec_, codec, was_encode_called_since_last_initialization_); } send_codec_ = codec; @@ -819,6 +874,10 @@ void VideoStreamEncoder::ReconfigureEncoder() { encoder_->RegisterEncodeCompleteCallback(this); frame_encode_metadata_writer_.OnEncoderInit(send_codec_, HasInternalSource()); + next_frame_types_.clear(); + next_frame_types_.resize( + std::max(static_cast(codec.numberOfSimulcastStreams), 1), + VideoFrameType::kVideoFrameKey); } frame_encode_metadata_writer_.Reset(); @@ -830,10 +889,6 @@ void VideoStreamEncoder::ReconfigureEncoder() { OnEncoderSettingsChanged(); if (success) { - next_frame_types_.clear(); - next_frame_types_.resize( - std::max(static_cast(codec.numberOfSimulcastStreams), 1), - VideoFrameType::kVideoFrameKey); RTC_LOG(LS_VERBOSE) << " max bitrate " << codec.maxBitrate << " start bitrate " << codec.startBitrate << " max frame rate " << codec.maxFramerate @@ -844,10 +899,6 @@ void VideoStreamEncoder::ReconfigureEncoder() { } if (pending_encoder_creation_) { - // TODO(hbos): Stopping and restarting for backwards compatibility reasons. - // We may be able to change this to "EnsureStarted()" if it took care of - // reconfiguring the QualityScaler as well. (ConfigureQualityScaler() is - // invoked later in this method.) stream_resource_manager_.EnsureEncodeUsageResourceStarted(); pending_encoder_creation_ = false; } @@ -892,7 +943,7 @@ void VideoStreamEncoder::ReconfigureEncoder() { last_encoder_rate_settings_.reset(); rate_settings.rate_control.framerate_fps = GetInputFramerateFps(); - SetEncoderRates(UpdateBitrateAllocationAndNotifyObserver(rate_settings)); + SetEncoderRates(UpdateBitrateAllocation(rate_settings)); } encoder_stats_observer_->OnEncoderReconfigured(encoder_config_, streams); @@ -939,14 +990,14 @@ void VideoStreamEncoder::OnFrame(const VideoFrame& video_frame) { VideoFrame incoming_frame = video_frame; // Local time in webrtc time base. - int64_t current_time_us = clock_->TimeInMicroseconds(); - int64_t current_time_ms = current_time_us / rtc::kNumMicrosecsPerMillisec; + Timestamp now = clock_->CurrentTime(); + // In some cases, e.g., when the frame from decoder is fed to encoder, // the timestamp may be set to the future. As the encoding pipeline assumes // capture time to be less than present time, we should reset the capture // timestamps here. Otherwise there may be issues with RTP send stream. - if (incoming_frame.timestamp_us() > current_time_us) - incoming_frame.set_timestamp_us(current_time_us); + if (incoming_frame.timestamp_us() > now.us()) + incoming_frame.set_timestamp_us(now.us()); // Capture time may come from clock with an offset and drift from clock_. int64_t capture_ntp_time_ms; @@ -955,7 +1006,7 @@ void VideoStreamEncoder::OnFrame(const VideoFrame& video_frame) { } else if (video_frame.render_time_ms() != 0) { capture_ntp_time_ms = video_frame.render_time_ms() + delta_ntp_internal_ms_; } else { - capture_ntp_time_ms = current_time_ms + delta_ntp_internal_ms_; + capture_ntp_time_ms = now.ms() + delta_ntp_internal_ms_; } incoming_frame.set_ntp_time_ms(capture_ntp_time_ms); @@ -979,14 +1030,14 @@ void VideoStreamEncoder::OnFrame(const VideoFrame& video_frame) { } bool log_stats = false; - if (current_time_ms - last_frame_log_ms_ > kFrameLogIntervalMs) { - last_frame_log_ms_ = current_time_ms; + if (now.ms() - last_frame_log_ms_ > kFrameLogIntervalMs) { + last_frame_log_ms_ = now.ms(); log_stats = true; } last_captured_timestamp_ = incoming_frame.ntp_time_ms(); - int64_t post_time_us = rtc::TimeMicros(); + int64_t post_time_us = clock_->CurrentTime().us(); ++posted_frames_waiting_for_encode_; encoder_queue_.PostTask( @@ -1071,7 +1122,7 @@ void VideoStreamEncoder::TraceFrameDropEnd() { } VideoStreamEncoder::EncoderRateSettings -VideoStreamEncoder::UpdateBitrateAllocationAndNotifyObserver( +VideoStreamEncoder::UpdateBitrateAllocation( const EncoderRateSettings& rate_settings) { VideoBitrateAllocation new_allocation; // Only call allocators if bitrate > 0 (ie, not suspended), otherwise they @@ -1082,24 +1133,8 @@ VideoStreamEncoder::UpdateBitrateAllocationAndNotifyObserver( rate_settings.rate_control.framerate_fps)); } - if (bitrate_observer_ && new_allocation.get_sum_bps() > 0) { - if (encoder_ && encoder_initialized_) { - // Avoid too old encoder_info_. - const int64_t kMaxDiffMs = 100; - const bool updated_recently = - (last_encode_info_ms_ && ((clock_->TimeInMilliseconds() - - *last_encode_info_ms_) < kMaxDiffMs)); - // Update allocation according to info from encoder. - bitrate_observer_->OnBitrateAllocationUpdated( - UpdateAllocationFromEncoderInfo( - new_allocation, - updated_recently ? encoder_info_ : encoder_->GetEncoderInfo())); - } else { - bitrate_observer_->OnBitrateAllocationUpdated(new_allocation); - } - } - EncoderRateSettings new_rate_settings = rate_settings; + new_rate_settings.rate_control.target_bitrate = new_allocation; new_rate_settings.rate_control.bitrate = new_allocation; // VideoBitrateAllocator subclasses may allocate a bitrate higher than the // target in order to sustain the min bitrate of the video codec. In this @@ -1120,9 +1155,6 @@ VideoStreamEncoder::UpdateBitrateAllocationAndNotifyObserver( new_rate_settings.rate_control.bitrate = adjusted_allocation; } - encoder_stats_observer_->OnBitrateAllocationUpdated( - send_codec_, new_rate_settings.rate_control.bitrate); - return new_rate_settings; } @@ -1142,6 +1174,15 @@ void VideoStreamEncoder::SetEncoderRates( bool rate_control_changed = (!last_encoder_rate_settings_.has_value() || last_encoder_rate_settings_->rate_control != rate_settings.rate_control); + // For layer allocation signal we care only about the target bitrate (not the + // adjusted one) and the target fps. + bool layer_allocation_changed = + !last_encoder_rate_settings_.has_value() || + last_encoder_rate_settings_->rate_control.target_bitrate != + rate_settings.rate_control.target_bitrate || + last_encoder_rate_settings_->rate_control.framerate_fps != + rate_settings.rate_control.framerate_fps; + if (last_encoder_rate_settings_ != rate_settings) { last_encoder_rate_settings_ = rate_settings; } @@ -1165,10 +1206,35 @@ void VideoStreamEncoder::SetEncoderRates( if (rate_control_changed) { encoder_->SetRates(rate_settings.rate_control); + + encoder_stats_observer_->OnBitrateAllocationUpdated( + send_codec_, rate_settings.rate_control.bitrate); frame_encode_metadata_writer_.OnSetRates( rate_settings.rate_control.bitrate, static_cast(rate_settings.rate_control.framerate_fps + 0.5)); stream_resource_manager_.SetEncoderRates(rate_settings.rate_control); + if (layer_allocation_changed && + settings_.allocation_cb_type == + VideoStreamEncoderSettings::BitrateAllocationCallbackType:: + kVideoLayersAllocation) { + sink_->OnVideoLayersAllocationUpdated(CreateVideoLayersAllocation( + send_codec_, rate_settings.rate_control, encoder_->GetEncoderInfo())); + } + } + if ((settings_.allocation_cb_type == + VideoStreamEncoderSettings::BitrateAllocationCallbackType:: + kVideoBitrateAllocation) || + (encoder_config_.content_type == + VideoEncoderConfig::ContentType::kScreen && + settings_.allocation_cb_type == + VideoStreamEncoderSettings::BitrateAllocationCallbackType:: + kVideoBitrateAllocationWhenScreenSharing)) { + sink_->OnBitrateAllocationUpdated( + // Update allocation according to info from encoder. An encoder may + // choose to not use all layers due to for example HW. + UpdateAllocationFromEncoderInfo( + rate_settings.rate_control.target_bitrate, + encoder_->GetEncoderInfo())); } } @@ -1220,8 +1286,7 @@ void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame, EncoderRateSettings new_rate_settings = *last_encoder_rate_settings_; new_rate_settings.rate_control.framerate_fps = static_cast(framerate_fps); - SetEncoderRates( - UpdateBitrateAllocationAndNotifyObserver(new_rate_settings)); + SetEncoderRates(UpdateBitrateAllocation(new_rate_settings)); } last_parameters_update_ms_.emplace(now_ms); } @@ -1277,8 +1342,8 @@ void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame, // Frame dropping is enabled iff frame dropping is not force-disabled, and // rate controller is not trusted. const bool frame_dropping_enabled = false; - /*!force_disable_frame_dropper_ && - !encoder_info_.has_trusted_rate_controller;*/ + //!force_disable_frame_dropper_ && + //!encoder_info_.has_trusted_rate_controller; frame_dropper_.Enable(frame_dropping_enabled); if (frame_dropping_enabled && frame_dropper_.DropFrame()) { RTC_LOG(LS_VERBOSE) @@ -1339,20 +1404,23 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, last_encode_info_ms_ = clock_->TimeInMilliseconds(); VideoFrame out_frame(video_frame); - - const VideoFrameBuffer::Type buffer_type = - out_frame.video_frame_buffer()->type(); - const bool is_buffer_type_supported = - buffer_type == VideoFrameBuffer::Type::kI420 || - (buffer_type == VideoFrameBuffer::Type::kNative && - info.supports_native_handle); - - if (!is_buffer_type_supported) { + if (out_frame.video_frame_buffer()->type() == + VideoFrameBuffer::Type::kNative && + !info.supports_native_handle) { // This module only supports software encoding. - rtc::scoped_refptr converted_buffer( - out_frame.video_frame_buffer()->ToI420()); - - if (!converted_buffer) { + rtc::scoped_refptr buffer = + out_frame.video_frame_buffer()->GetMappedFrameBuffer( + info.preferred_pixel_formats); + bool buffer_was_converted = false; + if (!buffer) { + buffer = out_frame.video_frame_buffer()->ToI420(); + // TODO(https://crbug.com/webrtc/12021): Once GetI420 is pure virtual, + // this just true as an I420 buffer would return from + // GetMappedFrameBuffer. + buffer_was_converted = + (out_frame.video_frame_buffer()->GetI420() == nullptr); + } + if (!buffer) { RTC_LOG(LS_ERROR) << "Frame conversion failed, dropping frame."; return; } @@ -1366,8 +1434,7 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, update_rect = VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()}; } - - out_frame.set_video_frame_buffer(converted_buffer); + out_frame.set_video_frame_buffer(buffer); out_frame.set_update_rect(update_rect); } @@ -1376,29 +1443,24 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, out_frame.video_frame_buffer()->type() != VideoFrameBuffer::Type::kNative) { // If the frame can't be converted to I420, drop it. - auto i420_buffer = video_frame.video_frame_buffer()->ToI420(); - if (!i420_buffer) { - RTC_LOG(LS_ERROR) << "Frame conversion for crop failed, dropping frame."; - return; - } int cropped_width = video_frame.width() - crop_width_; int cropped_height = video_frame.height() - crop_height_; - rtc::scoped_refptr cropped_buffer = - I420Buffer::Create(cropped_width, cropped_height); + rtc::scoped_refptr cropped_buffer; // TODO(ilnik): Remove scaling if cropping is too big, as it should never // happen after SinkWants signaled correctly from ReconfigureEncoder. VideoFrame::UpdateRect update_rect = video_frame.update_rect(); if (crop_width_ < 4 && crop_height_ < 4) { - cropped_buffer->CropAndScaleFrom(*i420_buffer, crop_width_ / 2, - crop_height_ / 2, cropped_width, - cropped_height); + cropped_buffer = video_frame.video_frame_buffer()->CropAndScale( + crop_width_ / 2, crop_height_ / 2, cropped_width, cropped_height, + cropped_width, cropped_height); update_rect.offset_x -= crop_width_ / 2; update_rect.offset_y -= crop_height_ / 2; update_rect.Intersect( VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height}); } else { - cropped_buffer->ScaleFrom(*i420_buffer); + cropped_buffer = video_frame.video_frame_buffer()->Scale(cropped_width, + cropped_height); if (!update_rect.IsEmpty()) { // Since we can't reason about pixels after scaling, we invalidate whole // picture, if anything changed. @@ -1406,6 +1468,11 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height}; } } + if (!cropped_buffer) { + RTC_LOG(LS_ERROR) << "Cropping and scaling frame failed, dropping frame."; + return; + } + out_frame.set_video_frame_buffer(cropped_buffer); out_frame.set_update_rect(update_rect); out_frame.set_ntp_time_ms(video_frame.ntp_time_ms()); @@ -1461,12 +1528,14 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, if (settings_.encoder_switch_request_callback) { if (encoder_selector_) { if (auto encoder = encoder_selector_->OnEncoderBroken()) { - settings_.encoder_switch_request_callback->RequestEncoderSwitch( - *encoder); + QueueRequestEncoderSwitch(*encoder); } } else { encoder_failed_ = true; - settings_.encoder_switch_request_callback->RequestEncoderFallback(); + main_queue_->PostTask(ToQueuedTask(task_safety_, [this]() { + RTC_DCHECK_RUN_ON(main_queue_); + settings_.encoder_switch_request_callback->RequestEncoderFallback(); + })); } } else { RTC_LOG(LS_ERROR) @@ -1538,8 +1607,7 @@ void VideoStreamEncoder::OnLossNotification( EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage( const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* /*fragmentation*/) { + const CodecSpecificInfo* codec_specific_info) { TRACE_EVENT_INSTANT1("webrtc", "VCMEncodedFrameCallback::Encoded", "timestamp", encoded_image.Timestamp()); const size_t spatial_idx = encoded_image.SpatialIndex().value_or(0); @@ -1615,7 +1683,7 @@ EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage( } EncodedImageCallback::Result result = - sink_->OnEncodedImage(image_copy, codec_specific_info, nullptr); + sink_->OnEncodedImage(image_copy, codec_specific_info); // We are only interested in propagating the meta-data about the image, not // encoded data itself, to the post encode function. Since we cannot be sure @@ -1635,7 +1703,8 @@ EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage( temporal_index = 0; } - RunPostEncode(image_copy, rtc::TimeMicros(), temporal_index, frame_size); + RunPostEncode(image_copy, clock_->CurrentTime().us(), temporal_index, + frame_size); if (result.error == Result::OK) { // In case of an internal encoder running on a separate thread, the @@ -1726,8 +1795,7 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, if (encoder_selector_) { if (auto encoder = encoder_selector_->OnAvailableBitrate(link_allocation)) { - settings_.encoder_switch_request_callback->RequestEncoderSwitch( - *encoder); + QueueRequestEncoderSwitch(*encoder); } } else if (encoder_switch_experiment_.IsBitrateBelowThreshold( target_bitrate) && @@ -1736,7 +1804,7 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, conf.codec_name = encoder_switch_experiment_.to_codec; conf.param = encoder_switch_experiment_.to_param; conf.value = encoder_switch_experiment_.to_value; - settings_.encoder_switch_request_callback->RequestEncoderSwitch(conf); + QueueRequestEncoderSwitch(conf); encoder_switch_requested_ = true; } @@ -1761,7 +1829,7 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, EncoderRateSettings new_rate_settings{ VideoBitrateAllocation(), static_cast(framerate_fps), link_allocation, target_bitrate, stable_target_bitrate}; - SetEncoderRates(UpdateBitrateAllocationAndNotifyObserver(new_rate_settings)); + SetEncoderRates(UpdateBitrateAllocation(new_rate_settings)); if (target_bitrate.bps() != 0) encoder_target_bitrate_bps_ = target_bitrate.bps(); @@ -1775,7 +1843,8 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, } if (video_suspension_changed && !video_is_suspended && pending_frame_ && !DropDueToSize(pending_frame_->size())) { - int64_t pending_time_us = rtc::TimeMicros() - pending_frame_post_time_us_; + int64_t pending_time_us = + clock_->CurrentTime().us() - pending_frame_post_time_us_; if (pending_time_us < kPendingFrameTimeoutMs * 1000) EncodeVideoFrame(*pending_frame_, pending_frame_post_time_us_); pending_frame_.reset(); @@ -1817,12 +1886,16 @@ void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated( const VideoAdaptationCounters& adaptation_counters, rtc::scoped_refptr reason, const VideoSourceRestrictions& unfiltered_restrictions) { - RTC_DCHECK_RUN_ON(&resource_adaptation_queue_); - std::string resource_name = reason ? reason->Name() : ""; - RTC_LOG(INFO) << "Updating sink restrictions from " << resource_name << " to " + RTC_DCHECK_RUN_ON(&encoder_queue_); + RTC_LOG(INFO) << "Updating sink restrictions from " + << (reason ? reason->Name() : std::string("")) << " to " << restrictions.ToString(); - video_source_sink_controller_.SetRestrictions(std::move(restrictions)); - video_source_sink_controller_.PushSourceSinkSettings(); + main_queue_->PostTask(ToQueuedTask( + task_safety_, [this, restrictions = std::move(restrictions)]() { + RTC_DCHECK_RUN_ON(main_queue_); + video_source_sink_controller_.SetRestrictions(std::move(restrictions)); + video_source_sink_controller_.PushSourceSinkSettings(); + })); } void VideoStreamEncoder::RunPostEncode(const EncodedImage& encoded_image, @@ -1843,9 +1916,9 @@ void VideoStreamEncoder::RunPostEncode(const EncodedImage& encoded_image, if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) { encode_duration_us = // TODO(nisse): Maybe use capture_time_ms_ rather than encode_start_ms_? - rtc::kNumMicrosecsPerMillisec * - (encoded_image.timing_.encode_finish_ms - - encoded_image.timing_.encode_start_ms); + TimeDelta::Millis(encoded_image.timing_.encode_finish_ms - + encoded_image.timing_.encode_start_ms) + .us(); } // Run post encode tasks, such as overuse detection and frame rate/drop @@ -2081,20 +2154,43 @@ void VideoStreamEncoder::CheckForAnimatedContent( RTC_LOG(LS_INFO) << "Removing resolution cap due to no consistent " "animation detection."; } - video_source_sink_controller_.SetPixelsPerFrameUpperLimit( - should_cap_resolution ? absl::optional(kMaxAnimationPixels) - : absl::nullopt); - video_source_sink_controller_.PushSourceSinkSettings(); + main_queue_->PostTask(ToQueuedTask(task_safety_, [this, + should_cap_resolution]() { + RTC_DCHECK_RUN_ON(main_queue_); + video_source_sink_controller_.SetPixelsPerFrameUpperLimit( + should_cap_resolution ? absl::optional(kMaxAnimationPixels) + : absl::nullopt); + video_source_sink_controller_.PushSourceSinkSettings(); + })); } } + +// RTC_RUN_ON(&encoder_queue_) +void VideoStreamEncoder::QueueRequestEncoderSwitch( + const EncoderSwitchRequestCallback::Config& conf) { + main_queue_->PostTask(ToQueuedTask(task_safety_, [this, conf]() { + RTC_DCHECK_RUN_ON(main_queue_); + settings_.encoder_switch_request_callback->RequestEncoderSwitch(conf); + })); +} + +// RTC_RUN_ON(&encoder_queue_) +void VideoStreamEncoder::QueueRequestEncoderSwitch( + const webrtc::SdpVideoFormat& format) { + main_queue_->PostTask(ToQueuedTask(task_safety_, [this, format]() { + RTC_DCHECK_RUN_ON(main_queue_); + settings_.encoder_switch_request_callback->RequestEncoderSwitch(format); + })); +} + void VideoStreamEncoder::InjectAdaptationResource( rtc::scoped_refptr resource, VideoAdaptationReason reason) { rtc::Event map_resource_event; encoder_queue_.PostTask([this, resource, reason, &map_resource_event] { RTC_DCHECK_RUN_ON(&encoder_queue_); - stream_resource_manager_.MapResourceToReason(resource, reason); - resource_adaptation_processor_->AddResource(resource); + additional_resources_.push_back(resource); + stream_resource_manager_.AddResource(resource, reason); map_resource_event.Set(); }); map_resource_event.Wait(rtc::Event::kForever); @@ -2103,8 +2199,8 @@ void VideoStreamEncoder::InjectAdaptationResource( void VideoStreamEncoder::InjectAdaptationConstraint( AdaptationConstraint* adaptation_constraint) { rtc::Event event; - resource_adaptation_queue_.PostTask([this, adaptation_constraint, &event] { - RTC_DCHECK_RUN_ON(&resource_adaptation_queue_); + encoder_queue_.PostTask([this, adaptation_constraint, &event] { + RTC_DCHECK_RUN_ON(&encoder_queue_); if (!resource_adaptation_processor_) { // The VideoStreamEncoder was stopped and the processor destroyed before // this task had a chance to execute. No action needed. @@ -2117,17 +2213,11 @@ void VideoStreamEncoder::InjectAdaptationConstraint( event.Wait(rtc::Event::kForever); } -rtc::scoped_refptr -VideoStreamEncoder::quality_scaler_resource_for_testing() { - RTC_DCHECK_RUN_ON(&encoder_queue_); - return stream_resource_manager_.quality_scaler_resource_for_testing(); -} - void VideoStreamEncoder::AddRestrictionsListenerForTesting( VideoSourceRestrictionsListener* restrictions_listener) { rtc::Event event; - resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] { - RTC_DCHECK_RUN_ON(&resource_adaptation_queue_); + encoder_queue_.PostTask([this, restrictions_listener, &event] { + RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK(resource_adaptation_processor_); video_stream_adapter_->AddRestrictionsListener(restrictions_listener); event.Set(); @@ -2138,8 +2228,8 @@ void VideoStreamEncoder::AddRestrictionsListenerForTesting( void VideoStreamEncoder::RemoveRestrictionsListenerForTesting( VideoSourceRestrictionsListener* restrictions_listener) { rtc::Event event; - resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] { - RTC_DCHECK_RUN_ON(&resource_adaptation_queue_); + encoder_queue_.PostTask([this, restrictions_listener, &event] { + RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK(resource_adaptation_processor_); video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener); event.Set(); diff --git a/TMessagesProj/jni/voip/webrtc/video/video_stream_encoder.h b/TMessagesProj/jni/voip/webrtc/video/video_stream_encoder.h index 5761896e1..7dfc99084 100644 --- a/TMessagesProj/jni/voip/webrtc/video/video_stream_encoder.h +++ b/TMessagesProj/jni/voip/webrtc/video/video_stream_encoder.h @@ -33,13 +33,13 @@ #include "call/adaptation/video_source_restrictions.h" #include "call/adaptation/video_stream_input_state_provider.h" #include "modules/video_coding/utility/frame_dropper.h" -#include "rtc_base/event.h" #include "rtc_base/experiments/rate_control_settings.h" #include "rtc_base/numerics/exp_filter.h" #include "rtc_base/race_checker.h" #include "rtc_base/rate_statistics.h" -#include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/task_queue.h" +#include "rtc_base/task_utils/pending_task_safety_flag.h" +#include "rtc_base/thread_annotations.h" #include "rtc_base/thread_checker.h" #include "system_wrappers/include/clock.h" #include "video/adaptation/video_stream_encoder_resource_manager.h" @@ -80,9 +80,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // TODO(perkj): Can we remove VideoCodec.startBitrate ? void SetStartBitrate(int start_bitrate_bps) override; - void SetBitrateAllocationObserver( - VideoBitrateAllocationObserver* bitrate_observer) override; - void SetFecControllerOverride( FecControllerOverride* fec_controller_override) override; @@ -112,9 +109,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // Used for testing. For example the |ScalingObserverInterface| methods must // be called on |encoder_queue_|. rtc::TaskQueue* encoder_queue() { return &encoder_queue_; } - rtc::TaskQueue* resource_adaptation_queue() { - return &resource_adaptation_queue_; - } void OnVideoSourceRestrictionsUpdated( VideoSourceRestrictions restrictions, @@ -128,9 +122,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, VideoAdaptationReason reason); void InjectAdaptationConstraint(AdaptationConstraint* adaptation_constraint); - rtc::scoped_refptr - quality_scaler_resource_for_testing(); - void AddRestrictionsListenerForTesting( VideoSourceRestrictionsListener* restrictions_listener); void RemoveRestrictionsListenerForTesting( @@ -189,8 +180,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // Implements EncodedImageCallback. EncodedImageCallback::Result OnEncodedImage( const EncodedImage& encoded_image, - const CodecSpecificInfo* codec_specific_info, - const RTPFragmentationHeader* fragmentation) override; + const CodecSpecificInfo* codec_specific_info) override; void OnDroppedFrame(EncodedImageCallback::DropReason reason) override; @@ -199,9 +189,8 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, void TraceFrameDropEnd(); // Returns a copy of |rate_settings| with the |bitrate| field updated using - // the current VideoBitrateAllocator, and notifies any listeners of the new - // allocation. - EncoderRateSettings UpdateBitrateAllocationAndNotifyObserver( + // the current VideoBitrateAllocator. + EncoderRateSettings UpdateBitrateAllocation( const EncoderRateSettings& rate_settings) RTC_RUN_ON(&encoder_queue_); uint32_t GetInputFramerateFps() RTC_RUN_ON(&encoder_queue_); @@ -214,12 +203,21 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, DataSize frame_size); bool HasInternalSource() const RTC_RUN_ON(&encoder_queue_); void ReleaseEncoder() RTC_RUN_ON(&encoder_queue_); + // After calling this function |resource_adaptation_processor_| will be null. + void ShutdownResourceAdaptationQueue(); void CheckForAnimatedContent(const VideoFrame& frame, int64_t time_when_posted_in_ms) RTC_RUN_ON(&encoder_queue_); - rtc::Event shutdown_event_; + // TODO(bugs.webrtc.org/11341) : Remove this version of RequestEncoderSwitch. + void QueueRequestEncoderSwitch( + const EncoderSwitchRequestCallback::Config& conf) + RTC_RUN_ON(&encoder_queue_); + void QueueRequestEncoderSwitch(const webrtc::SdpVideoFormat& format) + RTC_RUN_ON(&encoder_queue_); + + TaskQueueBase* const main_queue_; const uint32_t number_of_cores_; @@ -232,9 +230,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, std::unique_ptr const encoder_selector_; VideoStreamEncoderObserver* const encoder_stats_observer_; - // |thread_checker_| checks that public methods that are related to lifetime - // of VideoStreamEncoder are called on the same thread. - rtc::ThreadChecker thread_checker_; VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(&encoder_queue_); std::unique_ptr encoder_ RTC_GUARDED_BY(&encoder_queue_) @@ -303,8 +298,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, kFirstFrameAfterResize // Resize observed. } expect_resize_state_ RTC_GUARDED_BY(&encoder_queue_); - VideoBitrateAllocationObserver* bitrate_observer_ - RTC_GUARDED_BY(&encoder_queue_); FecControllerOverride* fec_controller_override_ RTC_GUARDED_BY(&encoder_queue_); absl::optional last_parameters_update_ms_ @@ -407,20 +400,19 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, bool encoder_switch_requested_ RTC_GUARDED_BY(&encoder_queue_); // Provies video stream input states: current resolution and frame rate. - // This class is thread-safe. VideoStreamInputStateProvider input_state_provider_; std::unique_ptr video_stream_adapter_ - RTC_GUARDED_BY(&resource_adaptation_queue_); + RTC_GUARDED_BY(&encoder_queue_); // Responsible for adapting input resolution or frame rate to ensure resources - // (e.g. CPU or bandwidth) are not overused. - // Adding resources can occur on any thread, but all other methods need to be - // called on the adaptation thread. + // (e.g. CPU or bandwidth) are not overused. Adding resources can occur on any + // thread. std::unique_ptr resource_adaptation_processor_; - std::unique_ptr degradation_preference_manager_; + std::unique_ptr degradation_preference_manager_ + RTC_GUARDED_BY(&encoder_queue_); std::vector adaptation_constraints_ - RTC_GUARDED_BY(&resource_adaptation_queue_); + RTC_GUARDED_BY(&encoder_queue_); // Handles input, output and stats reporting related to VideoStreamEncoder // specific resources, such as "encode usage percent" measurements and "QP // scaling". Also involved with various mitigations such as inital frame @@ -428,21 +420,24 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // The manager primarily operates on the |encoder_queue_| but its lifetime is // tied to the VideoStreamEncoder (which is destroyed off the encoder queue) // and its resource list is accessible from any thread. - VideoStreamEncoderResourceManager stream_resource_manager_; + VideoStreamEncoderResourceManager stream_resource_manager_ + RTC_GUARDED_BY(&encoder_queue_); + std::vector> additional_resources_ + RTC_GUARDED_BY(&encoder_queue_); // Carries out the VideoSourceRestrictions provided by the // ResourceAdaptationProcessor, i.e. reconfigures the source of video frames // to provide us with different resolution or frame rate. // This class is thread-safe. - VideoSourceSinkController video_source_sink_controller_; + VideoSourceSinkController video_source_sink_controller_ + RTC_GUARDED_BY(main_queue_); // Public methods are proxied to the task queues. The queues must be destroyed // first to make sure no tasks run that use other members. - // TODO(https://crbug.com/webrtc/11172): Move ownership of the - // ResourceAdaptationProcessor and its task queue to Call when processors are - // multi-stream aware. - rtc::TaskQueue resource_adaptation_queue_; rtc::TaskQueue encoder_queue_; + // Used to cancel any potentially pending tasks to the main thread. + ScopedTaskSafety task_safety_; + RTC_DISALLOW_COPY_AND_ASSIGN(VideoStreamEncoder); }; diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index bb9aace5c..6ce638f81 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -80,6 +80,7 @@ android:theme="@style/Theme.TMessages.Start" android:manageSpaceActivity="org.telegram.ui.ExternalActionActivity" android:supportsRtl="false" + android:requestLegacyExternalStorage="true" tools:replace="android:supportsRtl"> + + + + + + diff --git a/TMessagesProj/src/main/assets/darkblue.attheme b/TMessagesProj/src/main/assets/darkblue.attheme index 0a3bf5b13..d7d8af39e 100644 --- a/TMessagesProj/src/main/assets/darkblue.attheme +++ b/TMessagesProj/src/main/assets/darkblue.attheme @@ -462,3 +462,4 @@ chat_outSentClock=-8213557 dialogBackgroundGray=-14932431 chat_searchPanelText=-8796932 chat_inContactIcon=-1 +voipgroup_topPanelGray=-10521727 diff --git a/TMessagesProj/src/main/assets/emoji/0_0.png b/TMessagesProj/src/main/assets/emoji/0_0.png index 425de9ac326b795f5ceef5f341c9ab2d355d11d1..c2ce490de53c0c8be4567ab7aeafa4c8288eba1a 100644 GIT binary patch delta 1573 zcmV+=2HN@04b2UZpMRkR{jU-K_h$d?a{t>`|MFJt46;3T+wg@H}si>|vG zW;bC2@KnlnHe6jWEDB<7SXq~@2cyQnxTxG2QlRKf1H#1Ybm;(3J;%i=n7JVsMHdWt zT3O0!^uX{y(81q!EDC2xoy2Pfl62eoU~4VAm+lFgd|)ZRy?rx zz)MW2up?5OX21WJx$)ResX**jy8EYUt1SL?W}L2S~%|8-y;wcJzB zU?07aCB95UA3KT5&2qWiq^m5`F9*s7zb`Xbu3wN)Q-mLW?f%>9ho%!IRzQ5yS#CCI zx>_Ze)hbOl8~g_lHX`2@K=?t3)3n2|Wsq!XjK$)AubV6uC@j-*ZHfpY9EI%!%Q!(N zDH@1eGYbgFXk-)wEW-BTwiU}@R3y+Y0C)2Z=TyeF2)m_jPmCdB!G*{YJ+|v+?CK;F zkUg^k?nf6d(vKGy7fvVzM(_;AXpLhhY%hC$ z7ofcEglKU0PhVrq=91-{-U0To7f$eoch3NxGfr|%9MS@|Lt=B+gJUs5&xkD|LleT@>c)ymH)pA`jZ6z`HTPedH?#H z|I$SNd4E-N>NCpdi5fCV=jT|2g{UZ0k5@tky5?r{=x!@bA zQ=O)HnxB|%&tW#zQWspz(bTY53T~*BGCgtD44XaD(r~ey9!CIeFi9zuS(aw$2t9tu zVA`%KZ(S?XHkz`eK<1c;tk**=WocW9CbuCtD*@^)m#MOfRv-Xu8Thv%m~*J=L}rJ_ zJv(SsRv=)EP0I+Nh=Kusq*O3Kqu@8jXJ86~IiQT$U}J3Jm$~uSj;V^eTj}nfRl7==Up?bU)YSX^5eOlGkZnZ?Vb$rov^j9N z!}+Uxd=!sAgdtoflRyz*2mwa(C<{&qp}dvyySbRU!}zmogvyWO9*E07!NiT?g2WLJ z(Fl3c#7Xu!Fh#I`S1lZmhUkYedRbg*XLQXor&u6m1DE=D!bYyLxe*jGveN{j1Okn& z6CG4A#(v5MqQA&1r;I%}9pu;(ix)dj4+-50BAxtM6wvogqmFAU03a~tI{?B0 zacrjP2X<3OVX#o0?30QW+jtLzK;>OjeL^Z0@9Ppq;fF&*JVb$yM0>8Do;WQM<-9fU zw{Kg*;1y4QRg8Tsg3vzTlR@CalTp@fm1SvOozG94k)lnKWQ$3Xwk=fk`CR3jEah=s zVjqKvA->E*A3I5^-Fm&=Wt%)#F9*s5|6k=$u3nH*y$C=2+P{|!L)}TtH$Z$-S?_jP zw%MeZ%_hrsJNy9%J6`NdAp9W2X_{e}WsrQWjn(RZuXkCkP*`WxRxcuma1^E!T*d`D z$kPJ;hd_(EW&K5-4kup31^(=sT$jDGp0Jt zIph!fDjV>C(A9E%yFgtDZ*;CA3J-z{Satx$rYAh}R`o3K_1 zZV@hjqevU|mQnIS*wqdq(vxucG7arG82w0y%Owio{N35$0a|g!F9g+wdnTL#t(aa8 z>@GlA+Y8a??w`KeSS;(fVDt`ffW5GSH@x0!mBUUlxdIiy7_&evsiKh`@TmlVvlixgHPlodd zlrTUDtD!#nI-Gp!sO!xKkxB>`WH9&iQFr{w1GhJuLS`NwxIb0y`W@^1SDzvLkDp)` Z{0sMM`(@*S!3F>T002ovPDHLkV1g=&{_Ow& diff --git a/TMessagesProj/src/main/assets/emoji/0_1.png b/TMessagesProj/src/main/assets/emoji/0_1.png index 146ede33d7f3ae096fd3b0ac560f342fea145c5b..08c79072ab3cdc2b676e02f47552974ce40eb2b2 100644 GIT binary patch delta 1574 zcmV+>2HE+$4Z01GcNqQKJ$*w5)0!Rq=5f4$7XRU0|Ijc0`lgYO7-9e6FxGbi|JX6l zZ3AU30{_!V-GK)F?unImT>tr(seK@)jC5@|4Y-pl)44Z;S~aesmcqQZ(9_l6j0^0U z4&UPC|ME)zzY72T&;S12^P&*n$zJdA^ZEPv|Irdj(H&ir2mv5}eMv+?RCr#sm*!fp64auxtZ#L_Q)W~|eQSs1` zzhdwz%}SG~pVH*O?fAd@Aj7OeNKNykTtJSClf)F08B*bYB7Ej)HQk-eM&QU?*ygRK zRVToV2tOv36DA*_5WsInns$4(+x$Jm2*J=mW+5BSC%hrfWInXQ8Qz;9RjqUXc^oPj z;xG&+ZE~!J%i*dq6Tm;#aADpc+VC?Rhx$22N2`WFJ8ZYxjnMTi-wGQC+6*rEaRY9K zAv#7{=l1k}eaUt-J&v)B8amd##Vr4$(WV3V@LjmD1_KJ>Fpdq_%2^XJQj2S~T6^U) zlVOEqO&3-*0DgjeZbR*K^wDT^aLiqkSG3`jPSc$q8Ae8@qn@tAK*gxlil5_Ji=hH5 zBwWE-wYY_hfYYTE9mp|4TF5gg=%LSWz)5YHmIb$eP#_gf=4hCp0Eaj7gu)`l^MMnE zM~152>12;`bo6Sqnv6Wa1_>(Ixq^8u+e7+bs2cB-MDF8VH$ahineCt{BUm6vw1MN7CrR3;l!)Iw<5YROb;ChEVjoo*j^4 zZ68>FlVW9e`#^#U!_c)yN0rl*3UUBcVKI!<#S>r_Iu8a?ygxc}o+VId!ag7CSYdqLk+gDLD=*j{4}XU7vZ!iZ1hc6A6!jIY4nI6nEo;A|Wu!%Cn&xN#FKX zYg-DW!uh1YBr*y(aB^Kd=!CJMHqR45EQNY7^aL|bY zk{C*0E-jsMJU)z7p(qY;7?30yE{8)OHQ=EPLV$)UR7a+}9KxYM4je^KzU_sS7)IoO zZ@1G8XqLWZMp5vSD2kZt58=*cx}Ca;$dQt-S-wn3G(GTlPy782G@B)e5PT?Sx!gec zZol7885k%>Id>z-_IMkLzkpvnJ$-w6+V6JT?P4({7K`n6x7$AfVA%PQXrhPHl*15h zu+1JFAo=$FjBjWLwtgU*7-SBLTv@b#5iGZ)KnZeG4gvskZkSF@JoI=DxmNtI0S@L* z7dwn{ktdoHHt`Nk$Q*JfvJKaD{mpa%V>=GRs~1r2yDrl;J_)%GIndq%IZVrBmIWdh z|8yak!iroU$}Ps28(<7GmSrLgM4+<7pIFPUTah7R$R;G}KsW+_i0}5QnDMgIpaEE1HhJisBhE(z9j0{HMS(wEx8zNoyFi>yK z$!EFa5oQ`)Xau~0LA#(qT>MnZm83&60uz?-Nf1E@X(-Vk&dGC!gN^9Hobg@q^_n2S z7Mv>vB!^ij486BOG>868a~=hMfldM(1EwIuW%8L+Pc%ZWjIJw+q61hD88AdIrC$GJ zEZ*@(9I&8=03mfiEtFxK*U70Vl8{B>I8aZ5l*&U~r;r5+SWqLOdJtp_U;M%@sO14z zKm(pJ(u4Xz`KtmVm&uk>1Mq+es|TraHuLKr%!Q1aE!_d7tePo6{qK<-=iK~l{`?95 Y0t2|JU|Gk32mk;807*qoM6N<$f*cm}cK`qY delta 1575 zcmV+?2H5$!4Z97HcNqWSUH#iVeM1M+njQV-alC*Q|KTwI(@Bw!7-80T1OM1D-GK(r zZ3AU30{_r2|M{2x?unImT>tu}seK@)jC5@|4Y-pl)44aUqL#wEx6sqogIYD;;^p(A z5bT)_|Nh;CZx@2mv5}en~_@RCr#s*9UXj zN)QL|Py`5Uc&FM6z4zYSoxJb=iQewsNf=CcPBQt6aWWG7WA`?h!QcKk`EP$edCYGY z7m9NFA4*y-7IMD|7#3N%7{^7iy8Z!L$$Dc%+`*n$hd z8|75aGlx!;yG;JZ5b3V+@^8?1Ycv|%04pwUP^RM-rJK&(6vmTAqtyZ+4 z!3lz3+96{-T8-Ati3t2<12+~;N(bJC$01*i(N$^zq!V;Hon~NrhGzuLBpn7fJg3>| z0DwkS>E0E8&WLPRQ5^@{sH3s*3}$%m%?@3Vch80!8xRn10>{yCE0;|;n7UK1*E?&E z>5M8wHgscMhrnAfmu<-1u3D{D6JufPyrKhMZ0h#ngHYAFUHN<+8WPoZ+j(~CZH5F@ zh;V|n>rNX}g`6*?Xu%v+OdIn|1byf;T=1f{bi;suM+n4(mHBX(K!D*^T|pQ`JSRCL zToP((x10SiM^~-YYU8R4F#$n>eI}UOHeE~~gqrq%lO+3iP&FXNE*Yk&(;({;v8Ef$ z5lxMX%K>2RJ z-_IBbG)E=*zLM?nHY9He?>HX6ACLRpZo6GBXO!h~yWQ>fM+gWzFBDDm=rqM)h&I?^ zj|L#$e|*Y!lp$Ns7flQ^36ZOaHvH9pmIy>JAIcG+E_Mf|QWLK|nj={&{?h=1d9&pX zN4c6Kof9_k08NNFlAXkD*tYE*X3H%&XH8)B63RW>W~#zZLhK_s(B3NR%2hK^wX0cD7vSj+Dlp+;j+6K9c!!tf1$rr(I6 zt3nuxjV8(6!zecmAxJ1#K)^aKQp8a#ZWuoS7znBmQdhnNXJ8c32Q%1pAynfYhVr$q zomp-?!kLCw8UfeWXcu%4SHHaGO0l76z79*c074u>2&JEVh0b%s!bVho!T2uudUXJ> z1?z@@$>A*22>rkH!v*xO>xmy&P) z%2>STjaZotmo!Y2U!3B002ovPDHLkV1iP-?6v>^ diff --git a/TMessagesProj/src/main/assets/emoji/0_10.png b/TMessagesProj/src/main/assets/emoji/0_10.png index 5f974a9716cf105c5e2aa9b1897ce3057dd68316..9589ec712f1692f5e3f3c5b7ff13eee3eeada51d 100644 GIT binary patch delta 1605 zcmV-L2DhPg4b^%S*@Ps`d?Vh17VMc2?1Tl|f-A~w z2-R~6$Y}-foEzSF3IEnI|FR(e%{l&{5&z&Y|GFptt`mn$1$RCJn8x+kb%v|Lbm)SqT5-PygOs z|NE`~`J4a!)BleR!;K?nF9HAjz|L(0|MzpDV+Y@f3jfa$|NrOfv7;pb000kkQchC< zRik$nGLruN3e2?b#Mr>$EieE81xHClK~#8Nz1WFz;zkq&&=E)iv1#AMzVDmunf(8c z<=*ZVl8MK$lYdICYLKhxck1=SFol2o>sUYj^H?JP6wnQ=Y4%0Tre^5huGh@|G#vg? z3BqaL)V`w_W`8ym^}dK;hO@qDd>LqktY0nX$NT+!zTc1Y?aBudPQQfcO#%3?$MYYx zobU5Jk(R0dZ3}%5N7$cGf5ue;yw1nNui?<^Yo7v^#(x(4(;4lbKge;F>6wSX1M%x>X=gjHhpz5g_PcoySS7^_I)%U{T zRuIolRe!Croo~mXH+UXL^WqH;TW0=RgVa^!6#zCJh91W8e2mbQ!uFL>P!+6*Y+tv` zDD>LKJHliW2hj#L)iWnoMFQ9wc$dceCf4B?1dt`J*WYEi#j^(yH(axg`Xs`UAod3s z$bP>>1p(f1aYf{?6vPN^)TW^iE?zJ~_RMm>9Dhxs=sH@~!j;Jgz@FjWvA3?hC>qb< zjuZl6cSCkbB_wi%Pb?>7 zgg_wTOpCUu2ouE2VaV8N6uqG~c|!pN-v{wnNm=g%+&lxJ=4o|tkQw4QA(U|%vy_D~ z?i)$7Ejp8gB%lA2jpE;YT(#SW`2t&LcZn}#iR3R}UZhu&qxZ-sU zL9|*wRTK3#coZ5AjpPbMI0!h9Sy~EHc?>pDPxA$aY6Hj^NQTeK9mCrsbzK33p*qHk z37{Umlgn`^gtJW2YnEki8Ag)G4jw(=7? z4y#o?fS&o4?}R&phVSW8;ygsfqI=vSpXK?Rz z8k$bt`sNqzMz@1>8~nokz4B_eB~vbaKi2>C7mPmviw0TBBDY$j00000NkvXXu0mjf DJBI#& delta 2405 zcmV-r37YoR4DS+Jcoq%Wx0JY6(12r7mjqfq{%OXY1jLAvSH{ z#cK=dj~7FF?#F8j#cK@be+VIA@Y0n;^Pw8Ki&;@|!fAP@8h<#!yp&I1b-2`!HuH)E z|IRu8(KY|F8void=8_Em%`(7@2LHe@@0<_+#WLZH3jfb7|G_Gl zT?(RQ32rt6c|ZgI*)Gm)1BFQi|MEuv>^kOw0=R=5Unv6r)iUkcK0t^5`{GOCLRI5H8)OXRu1YRExFffg?ILh;)AmsA<9)I~GK@dcqrzYx&aO}2#2_4`xUM&jI zc#=sUCo*lzTww(>v2>P6#=+wS+6_el8-nmtZZXbqEc-5&nVIJ88q{PGX%@1^1@D*n z4%U)D9KsI)SxiEa%_hEDDEQfN3uC0%5c`Sk_{>R3BxkaopGblSTxosiURLzrRkiV1vBX#MkI8C$SDpL zaR{Mlb##dP{|3#!##akK0j{4>lphL|7JvQa5Sv~|uat2C z6hDEhx=;}X*UlYG?8T=n+)nHICU00~<4DH?;xK?>C!sSRd|BRa+GJ((8?2 z+4Fg`-|u6a6P%u8Hx$_u!&=sAo`2+t<}=Tw0Sche`8G9TFJrI?WA@PjY8#qu3WEYR zI7rblHe$RxG1?bJNpd8|eWE~tDG%2}awSPB7KR1#9@Bx2U;EWp6@v~*T}rm$78;!C>PI%b524_!^QJm{vs6bo}bN-j5p-vH`96CgN|*!0cM6QhXygjv&$e%=piU_CH7yJ=$zO%b97I@}rV;V|?O?mM zI48K)Iw{wOn)aSRPUdgrUj!xeM}-(IEd|TCkc_B#4-1vX_g6MTDm-$ zAa$Om$8mrrD8gSqPB`ks7wcHp=Z%J85s@yV+`T_GcSEZKW3KDEiu*KQ7*P!%n9&n9udK?Tg^)5PvxWM2t-6WG_!P z=lOhKbUH&x)Dt3`5HJRVfwva!{&5mNuJA4ioCJKr#9+{2q6s2Xltg9PIxaB@8BB=7 z+4Ihm{b(Pbk=VmY?0McK7;QWyynlP`P4Dv81h+wkzTL+j60b!Rp9zV#`w5+#S7OD) zkch?Wk7+I?ddqJYVt;-(@b|s=3H2O&&~-ANbO;C&$7`bBd%X}a5YN*+{ft5Y{2~Io z9;i96%_|~H1okNnBSG~4gkS&$Zii*kDwfCARIM}H?*E{D?o87HVGJ5`nX7sdAR8=L zrpeoEO{)n}YCm9~m;{7n!7v&|qUgjVAU%|b6n4$UYp*}86@MgA&ONkv873PB84VaJ z3Xp`AG=Ww0rxo?03H;H>jlvxXi{+7;kaMVef;QNAM<3zd2jben$L8jQ+-yDqn@;?_>|ud1 z&;;&BngZIuD90uGAR`h!6fmwY1bI~N+o}gSMw_1QG=KR_8>3(yFwls$3WQG#90iGB zr2$BU)sZHSfDY~?MPG3BnBEGgq1K{Az_%*QwvhS7?nZ_q@$40LnDkp;a?%E%wp8`Bgt}PKLDqPRNxLV>beyJ47wH$Q<1zwI!pX&i+vc)ffbedXbj8?#?bg4d9 z&E^^SwE!fag))ZI?&4~X$EdHA(7|s6N~uz-W@PHO*>Vx|?}ZDB#eBY;&;Ozt_W#Vk XvE|xZ{%+yF00000NkvXXu0mjfc{rhl diff --git a/TMessagesProj/src/main/assets/emoji/0_100.png b/TMessagesProj/src/main/assets/emoji/0_100.png index 318e3f0ab40799a9b19e620fa2185d7707b526de..56c8d25454de297305f041d74a6456e0df31ce94 100644 GIT binary patch delta 1566 zcmV+(2I2Ya2d@l}B!68{OjJcja7?45rJS9gn3|iRqNA;@u$!Eme}I3Hk&(T=zow_C zqNAmSg@v@Ww!FQ)tgWuY#Kfefrpe38(bLq~+uYydnIR}2apg*ZZ>V+a^L?kr@Dol#8-B5=FgO^oJ4|;YBvoy|NKw#P1E>;+p0IZ`4yot zk>b$)Md%|@wA%lIFi=W?^fN-okV>GeeYQPzL<1T7Q?(6fI-l_;2PI4MzH6!?%r6y6=0fn$~{~mP08eC0HJmuUw@E3KYOV zh}P7+DKl7Wv)z6eUB@&)BmgFOE}{2A7>GiFfsg>F>{_N8bc7<_xH3}))dKBorhwsQ z2;pdP7I9;m=c#}mfM~oL&_9B_iztd6-L@N|%=5C$Q-7ktOFEgb;7&nfH0}G$05(;| zO{FlLooHvlP8bq|F(5C32#lD;2W1hAarbFrcMvEH0blHiYYfD#atd99hH!3PO6oYMD=W<5-Q+3M6wWw5n8oJ#ni_wj0fQvA~rS#a(N&XV>Ka!BLo-~fnt1P z0topSpS9Z%M1K@UJ22w43m}#UA`a~lB7Y)YMt?HTl9L?s5u({=wjhqr6a&wFz zAVwe%$ze()5Jd6@5h)4cAd<)Anzl&nA;NNvk3c*k`9`U83k_Z(TAPUxlOSfGK;Yyu zZ4L-?6c-aCtUE*)L4dF<)UB7xWwo`|7I!;eujk91z^I6$jQAa~locIB_lBmU+uV(k`;u#$GKa8 zpfd;}Mg*=A#PK2$BDerz?{Urx=4!bCv42BuA=Em35ebE{t7ER*UN(&R4#Xsi?p%n-KSnv>{({B*%$s#8rL6pmxOM@o%P!%mU<2Ta0 zITKL`0!jC^bL$#Q0)dEP-OgXjYYRDC%mGEbSN{}q=7%}IMzoCqU>m4&nL=gMU!uU- zVpazkkz*zXzz~(txdZT*FiBO4VkD1>)@tUQ{MBuy}x2{^0^15i=q7_w@OlcU&{a^Ba5 zrj~fB=St$N%PG#Em|=631u^54+Bh3S5y>PTldK%xgi;aU?-NG@(K+ixl7Ax0ts6#g z<5UZQlq?b(0_g)Nx=!NjbF>s(OxXo;k?giq`95z4*TRgcp5t3f!UX};ToF1`EK``4 zG0ijFQC%gJrF!URBXF%H5O`xk!2*Lp9T4I;rZG)3t|{?(z^Zy52-$RDdtbmBCpk^9 zCkS7UqJ|QcDbYAmprNlv<$r-cjO~j9&sV**R-C{9HptfXkBZs8S1G)eYW>$G1vU_h zRZaWl@aqVOsgQkIT0LLS+a@!nk@WYLDi@?VWZtshNj^HsXvpg6$&ip1%0GWkZ7nlO zh{iv|DJ9Ck`NrMYOmwuFD5>)vgdZjAiu>EHSH>9SfBnyg_V9rR;1@sWUu;^qqtgx% Q!~g&Q07*qoM6N<$f~|epzyJUM delta 982 zcmV;{11bEk4D1JxB!5d#OjJcja7;upGY|_4NIE-2H8l+s zI59&=KUR%wyn|w~eOs)Nalm+2rUC;3m376NdCOQ$X_|Y-qk+_jXSaS!6@CB!00?wa zPE!Ct=U{^VBm9#$l9K=c14v0kK~#8N?UdP$;~)@4+Y3&ycz<7#|NqjdOR-oM_C%U_ z?Bf<4$mLLl?Y$I($%Unu!YI8-Fz3jX?26pvnMJqUajXiej23Ysk4BIhWWEKV@A%O;Dgm zAfh%DYaII>g)UZ9bnwIQKR@+_ke#3iO}0T{1iP(=)qloln$|1RiZ%IG6o!)~E6AZp zJN3PE!5d11UOxTgv}{QVP3!h{8nxl(4iTg=!`+0K<_kVplokE7IuvQNrkL+#%+nrM zX_4WaWjB8=D7ZWy?(>*|WVepAfub)faFG(uBRtuJOD!rsJu4VGohV!vK78d!;_fes z$)Q6EIe($gPhRl~!-~&IVWL9Ag`m79apPr0s(9Thz{>54Gw?YG z$+n;vE(#qLNZKABE{eEqI4K5sauvgn6hld&;2JoE5PLJSLh>ysj*?gCtl-dY8J9Pp zimO6&j*w*AS)mQzwkIi6u?jFs(ix+Zg5zq58-GR&cHt$BNq9cANJi#JA(IqT*XVo% z7>6M=HKw(+lHe{>UDvDtU02myH?UCxAV?aId}%eJTGdULe?VCQmPN}Bh{`}}7PTO* ztDj6)*CNs57Z3#KA}gd9f2k$KEQ5@5ROl*pktInXSv+Uvw17q!2#SgsAPvVE@9@Z7 z=zo%8VUz~s)1%V~>wTluKrL_-6#ffA`!h$oBn%X2AyQP-k)W8Nh$|+xfE59Xt0PdU ztWXVB8kH5Qin*VAI#G;XQ6a!mBdrhu!O9+eb%MNqej zdbtu6k?$3CL=I$kX#B>Z{vwt9xY4s>9tT!5_X>H<9u@OU zPgNlBq~Ke?>v~&7qa^U4pgM3@#nTHSbb+q}|DRv}097(~sUg`LDF6Tf07*qoM6N<$ Ef(i?|H2?qr diff --git a/TMessagesProj/src/main/assets/emoji/0_1000.png b/TMessagesProj/src/main/assets/emoji/0_1000.png index 49e6653b1ff7101312b531cb855d379774c5adf9..620c9c5ff8f5cd1fa4cc39061ea3781991abcb53 100644 GIT binary patch delta 1996 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 M07*qoM6N<$g2H>tYXATM diff --git a/TMessagesProj/src/main/assets/emoji/0_1001.png b/TMessagesProj/src/main/assets/emoji/0_1001.png index d817337ddacdd36be58c026654f1707c905d223e..b62966b89e72e4614d5723427eea39865290d8a8 100644 GIT binary patch delta 1832 zcmV+@2iN$@5VsDHB!B-Mn<`^vWq-CTVhX=zzmSXWn8)?{Sv?d-NrPJl2l=;q|!+ke^Y>*yvK5>Y)gOgJzt zAQ@LeH}LQ5MKLMj;NA1`?>#LhH7Fu#TUA<6Ovt>uOh!c3)Y5fzdWwjMtf{BV$HTs@ zqGMxYY;A5D4hs19_4f7hJvcUob#CI+%jLwvpIltQn2@7~e|BkLYZ)0^M?2rBrU6*lD+jHX00000dbW%=J0R8^`{{H?C{u$kURf9?XU(7oFeYpPK zC^ojos^682k<_Bnsn^Ef!?Oke00qEFL_t(|UhS6WQX5GWh0$n6NFcy~!I#tvtr8eO984w?U}`tD z^Y(8XY4IoFGEPQDkAA@i=vI!w39p5z`nxSpml-lFz zq<(XAQ-6Q`BBA}I(E#Ia9NWZ%2&L1;9U(GA>^N-JnUU+(3xor>KK^z$rnYQ4PT#@C zyQwY9PQUM%vQ5M0grzzECFAJy;Gi)b!!zLo>~qZV2(;=~7#WSiCLrhAzv$%G`av@s z!!@Z893m6B-|zK$904>5i%IR~dOhNG{d7_=1AiuxgTQz8O{D07!K3hJ_Vo0ow)Sva zSM|v>r^M`I8(hG84{}UK0>uH^WVUENtKWQG7o}Z4ZHBQeqZ$k#Am)N2crQ#4us~=y zsjanfemV_VBOTaAd4*u^nHdlqV0#P!M$xRT>BiaB)Fw6%d@pYW-zh&XKpe~4N@rKk zlYbn|2u{A5heZbdZkzHIw*Lu%R@u$xgT5Q00hnnfRP!^yPZA2Y=|EUy6bNLf-7Jd2e3m46(F zA@e6fGUzJaAX*rBG!g`nt0;qxU~?CaY}5S}1cd{{h%-s)dQpHKw@bo`6nR}G5@VFX z1YK>$J8Cm~G%NM48yT>^Mp5K;6-lJqqTf}D z&^0uDAb|mbux#T*2y+lRlILl& zVatUd`1n`IBOeEX6=!G#@Y?C5f^fJz7e|L#mVn?6k|fPWqkr!2e~g^MPm`pRq<&$J z`AVK)VcYHVUZVwkPUDBK*NLtzA?;-X;IAPeh}$hAj(8M zL5^j{{z-=+bV&34`5e^&2xzE*zoT0uf^bbx5TF|;`;4&SqXa_NU6);KR7*j`?mD8}5lZ3VnOYyDGEj8S(ll4+wXmSM8YUYQ%$o{kK>FNcXI8QKEzaciwU0>Nz<6+?Zx zXNv`90y&h3nOLv4uP%Uiw4r*MW^th(U>J`kc3!>o{qq$|VpRxN={`wu0a!Fu+1q+a zt(__fGht~z5jYBtV1Fib=3#@4ih)lYZQ(<)ZVg1KIsp?Kw5RZPz_U>u2>xJ=)U>J* z%4KU4q6G#w0>tC#8j$L83!4c%%gzF#G64i3gU$duixiuUaEPk`qNx?hssOB$zX`#B zR7SY?#ZWHxRx@ml!|s{|xh|ilwSdiWbS?lc*GJeKXYcZ2XCdd}at{;z-_?RPB={GN Wjl05^Fmjv#0000g#+F24rMp+1T5R6$Ua5 z3wKCIwzj#<%FBfiQ>k%@`uqEz2vfnp!o&(`k}qhdl2OqMbEI5aI0Yru$WOnWrPiox z+zeje4R)R!D}U^D@Sgwx03CEvPE!D;{z@A(U<~Ht{(=7embSa*Z{FSMSDIk$2S#2aV){tx4QT57d)3ozq< zUK9#Y{ngs1h*I-{eRxPTI*ijG@H$vtI~Dl{D1EQ)%I0W`JUq#j^p_@zv))~ zCeUpv&zb62`o%CjTa^9|QfpG*v8+r0BSRd|ZnocCmE(W5F}IDxGNwfgLysd%Zy43f z>Or{1oLi~kIYu50fM6@sJph$_i~Reoe;}$2N{yal`=00I0l>GFQj}aD2>)aCL{PWq z`9xQU`+qBoD%4w00L#=ge+7pg9g3GwAaeTQQzte!#y5hf|6LQoxq z;hiH%Dc-Nfhg)$>{F95Q|3`+j38!g-2qui7Lw_V<2rxw8_bTh~xf7idR78V8|I_F5 z`jwz|>R`s0X%Ywq41!IpAq+KOlKSUQ^Fbu|?*wGh`J+Lpm)e?eOU!1D?a^Zu47|94N1e~Gk<9`bT10smy3DX28g4+O0twXX)4wX0~T7eE_ zq*f3$X7Zq8EaM@gR9Tczy8sGA2}}f~WDzWlWr$2%DToSoWzcaPe}RFR3IbCYrv?n; z*b-wP&?xeZWe1!3j4Q4(F6qRcr!dikBq~Xud|^zdiIt=t$_UAj?{xaiZPp8--hXsi zKQ8-xM-Y;x2~~+z7-?b4IESqlW>?kGIEXN(2GEEq4x*|Q>ZLJO^9y}*? zM@fRQ6q-;`5V`L4F;R0}9>>05LSFCm^g2^ zs1x^PPV^R|Q7e2HC;JlP2>vkt)_>zn3LzQeL7%u+r+0*sUW^z9fubHx#?#g$_;$A^ ztl3?!H3;K%O7=uQh)lPAc9M$eMnOC@iIl=)yf^D@e~!oLem#@f-FmxSKllu1#3Bf3 zK1VT0(-oa~U=k#ykExOLR;x5Q+9SPHFEJDlQb@eW<~aK;ZI_kfmWhE-jDJtFSVg8; zY^F~@ghwIFQ5@aH(WL?)2tpi)V&fz^I0ez?ZhlWXsX_V+rU{C5bWoKW!TF0G7riaenyZM z$BpXQODUOAxWFJV-zf~w$$uLeyB3J_d2vkqJ__j%m?oqL=k{)^CH!bFd(hbttulr& zUQVSUItvVh%d;B(a@n6imdnV}f=^6MlqKwq*HUBUkZ59*jbbFT<#00WuX~;rJn900 z`n>Vhb6cBr0>W5pIM9Y+&7v0E;nu06g=pAfnDoo6_J*Ku2SJG0aDSK?hSB4KQ<)|X z2<72$GGdbsZlArG^AeB4#c%>hp++W4Pbny2D?jPKS11gP%zM3b>NpOZ_z&ME6D>sTvv;N5 zF2_(L?7*fEtKMupUVpE?%>f9a>-Rr{Ya{5a*0b@tH@+LsR?85CR^`1wwbpI4;y4ad zDDco*-`$PVeh>$XMyXbP&lHvJ4W*Q{g81Ld70j@HxVu|heGrJ0s9CDi|67AgN;#!M z;^nVjo9%iw8^h0Pv;DQiyGIpKdb>%DbFMfDh$KILe0zGB>3@}&ZJ&Ppct!;2K$F@V zLWL`(1x@(R&znsO1Q<`7=jRBcU8HPQUZ3Jd*&yf=2x0tvbN@8EgRC~2%}8IF^Spkt zclllbf)I0Ye{ug)6Wh)GDM8w=2wYc*=Z76eI% z78nqJKHhJk#DD$8~ncQ6=@7Wdb%`ApU&3n9V@=dhy*oOk$b{mtL8J zbF^;@C3eKui|zK}>({?Dv9Cci@$w`UL@6>E*$Wu~#-kQAk=G!uiO9?Mk!wT+F`=#| zKyXb>{Ph)tjL2(Xm%%VEE=CCnnGw4&Tz9n5#4e9O=r$T;Pq6NbSKj7Lv)O1gn((^I nKmK*d#Z5z}siWT-#d`h+%4noQ|I^VZ00000NkvXXu0mjfq3yqz diff --git a/TMessagesProj/src/main/assets/emoji/0_1002.png b/TMessagesProj/src/main/assets/emoji/0_1002.png index ea5c3d4ee9cfcd0cb93aa76303ebb512e20cb65a..781fb81dddc7b7865ab1aadf1a72146691ea135e 100644 GIT binary patch delta 2666 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 YFDrgpPsw$_r2qf`07*qoM6N<$g2-br{Qv*} delta 2031 zcmVu+suUk?V9l$P7t+&2yvj}!$<6AjJE%crEJcq1U1 zDjmGLz=I{2v1Kq7IyH z7AG(&_a{iHB4VeX0DXKU1|r4Uo3nEG#~KLJZFIAwM2v;JVH}?wXEjKn`$H#i(%|Ur zgc!~0dmx{V$d2P+Pvk2~ICIC~Tqa780h0V$bjTqu@U$P8e@aeBVbx3EdAQycAAPB)B`FlS5GTqkVE5n!fM( z-UNt*q{^C}}Hy z0oKX$D?*MY<7sRsgzWdagSPkB>3?l!W7e5ZUH@q|gtQ8K;f1zUBOpsY>BO~xF%?KQ z9L*oT_ePCWFwU$qdw7^_v<(RndA^`No~8Q1Qp=QJu>|cja8Ux2ttlQln#&zQeH{Ii znkAbzQyVyAT5=N`O1w{UWYmuEv5)-E#PNlty_66{?BfI(v?tcW!fVp6Wqoz0 z7@xKPm*b`6?9h*p0IBre&_bJ?pi=@Ct?V=L^TNVS+C(%NuEuLAT{L|TNJK3%bYpaj!eTaW84|cf#G-Za z)_q$|E`2WL)E$tayS>nDx0|z}CSmGMrR3|TEWLTtmg7%8NY^Dp>tG|8P;B1UiQu*) zxn4r;=*?7fttWr%wh?J1H#QW5T5I4UF`js=UOxJbaT4O?q)o;^DSx3ULaC`s!o>Gl zzZIyC=8fl1&}er9!6?e~Z{ICs1|sYEYTm$m-^P5kqLm?`cJ!{4Yt0)fWVu<*MzhtZ z*PE^GCleH|O7Fi1ze2-XZf2w2Y~JhiMyp%8j9%s63sg(>;uJ5i{tydT&1aoXZ@9o~ z_PCNO9lxiGeEnPq1%GHP3mfcVw(4|d{RJ*HFvW_w{O{)T_)H0mVsQK8N1-trje4We zXj6FnaSM#1RPOCcN=2bH3P?2m`RBfXbJ;=T;r`$MdE}f3d?~&)srjPb3XI2(kA=bm z5@_5P9v?$MBTX^?dKc%~Bm_eOV0?XjKk8sMh3i6OX9R!!%YR-M27$B)4t8{Xdi|Y< z`@(5L?2T8yX;o}PVMs`cyVFx_WK=*avSeBY@voLqQbxh)q*Sgu>nF*s^6xaNFiG_sZ@o1WR}ML*o7cg>OWpop2)H z$khpyKmo!uxucMgJpC6@^z%dg~B3XCs=k$-0g{UHWI>qaWZmD zQJ-?#1`-7#Fe$M!z`|2x{l%TPh^bU6^qOYzuYFFh(znuc@R`l$e*wT(g)t1WXrTZA N002ovPDHLkV1kI5xEKHc diff --git a/TMessagesProj/src/main/assets/emoji/0_1003.png b/TMessagesProj/src/main/assets/emoji/0_1003.png index 18cfdb7acf19ac5c87fb695a15aac42e80eea5ec..2341d7ccc35374c3cedb72049b22d94e846d5bf5 100644 GIT binary patch delta 2459 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 Z4HT|I%98c~y5;}?002ovPDHLkV1k~Ox+4Gp delta 2322 zcmV+t3GMc!6P*%}B!59rOjJcja7-^RFA5D06ciL392_DfBrO;fMJNb1CL{+32PY>d zDJm)$7#I{576bQ*DH{$D5DN?pr>CbsCL=;TIs^m+rZ^|LO*}(GLjVK?!AUqo zL_||7B?1Bi78n^HARrqZ9U~+p`NAd&2?;4FDC4IX_Pihw5`PmjGc($q74EVd^0yt* zkrG!gD=scB=&TrgO$)Xj3CbS|IypH&K|ub-Cr3v||H>2_6jvixmcF4g`4; z1zS1^m>CEz69(b3DX}LJii(NY+1$pC6RaHm|1%ITZrMiL<$v+SO%`*G+!ujBbO-)U)vbW*TtdV69(z9xmaa;f0W!AV$ z!LN$TWe#Z`5T9TSs*p)}PCC75RlJjOTTDRz)-2@q8t?!B03LKwPE!Eo{#xcP8~zOE zr@cdjrT+erYUcjm(au-Ax`9`*ogNv<000MVNkli=3x`JZFLtDem9_M?t-o={}@Po7`)B8oHrnUe9We+UVGfARCWMF6iM zX^;0A@PD^^2I+fpVOI(pIO77ij3|+nCq!;**-gkOTmI)Fd@`lHML0grDeI4n<(%ST ztb9)^TaWmaP&$nfee9kKv!Q`da~Ui0h}g2yk!M6mvA#bNRx{hjEaI(PE_b|8jy%u+ zAe~7IP9FX(OIdwJY$?Llw}lO_0&^^cWF4W8sGBDkFVuQ znzceMgdmue9)WBr&1HUmW8^( zvy5uGuBqL-L@iL_dBjsPLm^<<47mq`i+?6|A(lckHjBk%GI>k0#4?pg)S8kc>6)l^ zhi3^JMDe^#5d@}s#bU8#Vmjj5n2c;DL8)6(xLhhFB%RA-c8g*BLJnyB@$Z<^FhDsj0qwfOYQIPCuL04L{4x1hX??9ct~sao05K4 zqF}{aFmgnpFRs&a{ll52o^^?dx`5>6mk9qC z#KuxLz&BJ)${rp5`uX$p@PG2ak<*_^u=P}^HaWtu9UWJ;PU9`@*w+& zkY-2F&t?H(fYtpX)Zuji?zc;6rJxkUh)b}=viUsx0bn+RhJ#ln3zFglag&T$=!<{p zwbl_cN~QJ<2t(&MKrA!^Gmt3=2%Jt3H_4(YyIu;{y7Fcc7mQ*K{!4*C`&Xn2f;~NJVEx@2nWMUZ)wf8(ct$qUE-WL z#Nlw*l^g=6Yes{wCyR>fop`md7}6-AMBJ{#W^kG+O4%n9S^@#Wl%b5b6%MkkB#%nA z4I(E}$AhG6Y6GEijDLaEcuyOY*@8heumKE-(_xE?;@mj`0da;9y4{2z-d98(rFy(= z1H^S7#sSdyBEB%OS3;%gCbjY5rEQIAC969%BW^SF^Ug!9_RzVO?2}xrHFhc^3{if} z*lZQ6I|&sS@Lctqa1Qm)2`(<)?No{}8m>wo%m0_zs#geu6o1pa7GYOiUrD-6=#^ue zetTDh-|t^v_dA`Fhhn*bX_oe_hX0gjI3x&`C9o|1eSRHn zcP5jQ{$w&KT>QGA7h+dGcH$-1#Km1{e04RL_9vZ_lgXqrzP>uoVF%*#enjvo3j#|s znfv?kwB6~Sob)?|==IgTz|fD3@cTLXl(b@(0pqZo8-I_dB#r(_wB6p8WrA=R?{4;W z%OL=Q!F;aWjz;?(VxlnEMlQs=JI(J)D=g~}7?~j2)7?&|6CD!-g`XJjo;e$AT7ZRf zOvs2J#$e-QIw%aL&j>6t@;iyH2?|TxE(kn29t_%p=%6zm7Yc4)083oM(f>g|4D1*2F#;&asKsXErljW7y-#j&a spkOdaT3g%yaw!@l@)6l1p7Z=Kt$YExdHwch01E&B07*qoM6N<$f;M9|y8r+H diff --git a/TMessagesProj/src/main/assets/emoji/0_1004.png b/TMessagesProj/src/main/assets/emoji/0_1004.png index 161c13d44c4ce7fac27fa89f6761c7ad3a10394d..b5b8e9e5dcd3b0cc19ef4d833417aa1e4a96bf52 100644 GIT binary patch delta 2432 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1005.png b/TMessagesProj/src/main/assets/emoji/0_1005.png index 758abb25644c29b7221e3439fc21d5524a34939e..b61898ace8101dd8980c96bbb88337e1f683f8ab 100644 GIT binary patch delta 2298 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 UcS8?g01E&B07*qoM6N<$g5WhjkpKVy delta 1950 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 delta 1939 zcmV;E2WCblH8c|x6e}nv1_lN`J33Mu6uwP6Ks`N~FCeNrDy}{*933440|PcTI4>_S z78n>OCnyUF3J(zxAR!@5O;0~RKv-E@Mn*_fR8_4Y4r&nwn|~Y&Zf$FahliDwmAfDc zRxm5!-rR;PA2SUI%gfApcXd__1I{E3gcJpyo}FG^V5q04KPDq?KRUd&wfFb;$(wzz zgIv(QN!7+@b*>6B0000ObW%=J0EwtjW+H{?XiDdP000Jb zNklf*sk3hnAe{up$=6~8f1H8~2pAV-mi~NV#Zv^&z zc1nV1#oo9;1Te0rFERX#F}-2@;TL{(&0Il^a~=vuNAOQRX5Tp*oDdJ3-@KH;4ID!i zhviNu9}m3rU6(;Udc*@~^K*oJ_}0h?kaXZ*IS+PCkL-JB42To%>e z2$|hs2!B_U3eFgFnLSzYUUEK#kiY*bB!7iiMAeUPvoZJaUP=h6B}a9!@=Rnh{q|!O zy+TM?M2khV`s}@KK9dR{0^;ESX@6lkz!M8t8W-d@gy|6rgT{%_%5@xo z2%spypp=G_5TZlGh&bESYeR|{6+x=#SyPF&I}7wXq1i-%gY9 z34bvVdKc!)%zy_}s8vr8)C zWgaebEfjGA$YAqUn34-NR2{}uUTJziJ%1sl_f%KQeGpW&RtylqCfOv32j^b)8fuI- zXpJiiMTZw>8d6m(_nS??6*QISwCmOvNoKtuCrMjJv|HF4rj&s?2i1yMIAKf($Q7voyhn#l;P)Lde5*_p5@ka2YzD&wN|* zzCDxH+VHw>Xha0TKCC$Q)ms~+f)4jxEQSs55$$<*`mXEm@j=I?cxyuy@UVtE*pkiy zQXFi`;1>gj1YU)C%y38FYD^8-Sk@Xcu?*aQxG5CSTJmfjM#VW4^Kx?Wo_~gDBd=*U zn{3dCeahX=g=bAD8s{;Go_JTYdr>WOMTy(l01A3{ETJEE45h2Q(2&Oanq0~}RFv|b zfj;oZ5_%JWh{^rOgV$IWVNI#PYJj>8fM2Kg;DQMn?JhqXm&(5Ntmw|nty{2fH-aGfR841EP;u-jw%7A{G721!)Q@+hDQ9P!QteP z0uTthMHE-$bAp|diZJdOzVEFa_>(125F{*C@y-r?fAUd;E0`2GLkODi@yTFcC7c-1 zVuujsf*6R`9pQ_^^WYH~(Id_{ojAt5m)@m{Qmkbf}xDquFA-_~)w zijuV5U}J64bPoeXefzcl2d1O>o#c|#ak%%kP19uSrYyJna8(Oq%+-AIr+QB2QsR7P z#Qy0iNz3whXpYBn-99CT7_0f@^CDbvZV5)TKYwPM=2&hI<*{s^e*V`Nrqk7DB^h1W zfe#VHeSS{CMsqkcV1Hu$^H~z}XT}T&7GY;Z?WgHx-GB~BntDQ$6XV0G&N=JTK!gHB z+css>tdlGY=ovx`J~qLn=?NVoO}1s(v}u-kIPYOa2_E;;4{9ly#F9x%&=e6V*f@ZR zY(tgkZ9qyNy)uT98BKZ*T2Uv%udu94+bmlHqR)gVMfC84w|_6^2Hd_Nf;BSQtj*SI zi?B8bBENVxF4xCJ=!D6e4;C5mXbS2k*XVu0WTUw{X6_M0x)?Q*sHq?LLI_?Wvys Z1ARkmgGWI2j|>0+002ovPDHLkV1f%pZIb{1 diff --git a/TMessagesProj/src/main/assets/emoji/0_1008.png b/TMessagesProj/src/main/assets/emoji/0_1008.png index 16de2c3a1524a584bf47fbe1ef3c14f61acc23a6..83481d6b1edd4a994b4fe5f6dca115ef0f8dd744 100644 GIT binary patch delta 2527 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 delta 1883 zcmV-h2c-Du6X_0+BYyz5P)t-sM{rCW92_GeA`uZ02L}fk78WTL5;!Cwr>Cb64-ao| zaSja)G%_*|4h}3SDL_3uzDqhz8Wg8GDxWhWA0QwE1Oyrz926B6H#a&aCMPm7Gb}7E z4Gj%DJU&4|Lq0!2R#jD+nwm&RNn8#Dnja3UAP#g91dA00GJgyRO))Lu-`rs>Cx9y< z%_0l9APP`WPtDEFytucDi;H7pV}5>q_V)G2poh`GPlk46$ck#CluD+aiMC=;*E^L4 z0000KbW%=J0Om7`=1v+6^{W15wa4GxZ1uwDQ=l)u000I}Nklsn<0$Grwm8Hu75ac~_|{#J8{I|GBfKi#F4{{|T@b zv+aZKGTF{H)Bn1_W~-c?cg@aGlhxucUH+_Ut#si1nVl=Qi_e7V{dDZDbl+f{K*-rp zWHBCr#}C1D02V9mdjHOD=jfI7P6Ur*W8tbt>%Gv5aDSt`n?|7Cjj5wX#@)S8k9SvL zD{M~54hF!F=fT5!f&hBl^~9qRvw?V2`o0&et-ISvYE%HhQTTO@YumQ$$61eB+>Z(Q z_`TCN3Pxy3xpG~{aRT`21LK8KLQT5*-yfwK5f57C)jx<>4>$%0%C%?%10gU}DUDGQ zr(%8ok$?Y-2tz=ujdoy&HeeX3wSshGrIcE>(PVn}{YM(!ARy_F2Ze2=F&qqn10WJY zAn=F=yZ5_*D6ud}(`iNqEN?j<2-_{1!%090M^Mh?#{hnB7GvE%6lyN<9%na!!!wGh;kQ zp$>7r9J<@Mv0RAlB80QzxWN2MG)Qbl1UESVb)7JXAxh!9D{wG~z>yHdpaDbzg=1;> zh=14^qfw|+4uVm(=A1(n2ZDy9ID}};C{D$sND#vp12N^4#7IO?loD4lEno`Hd$5U+ zTqsTvkAR3com(SfPFYkpaouo^C0rPT-$U@&hDd6-$>Jz#Dnqw-17U5csp{O$tBe~W zY*z$$sjvsZ@pdOqKozJ#v)mR{N$Kj_D1R$T%Q}a;(oiW}b^3J<*y${K!QP!;ckFd( zi?#;Tw5y!b&6wCws_M!Hg8-pUg>zoh?725w_u!n)G&>xW(CwAP%`32`W5SwK630Ne z%1CAJi_B1({Vp6A331+c$CsnlhTuDu6~m<%XN8MVf+3jH-lcfTXqLWR)@=>@P=A!& z@j+=LT_DoZ&=~?l7L?|7B!G}o2>PGnSn68dO_Xg5SibYg#SQ@ot_arWwI_rP zgm6XGsWHB(C9`9Fl@UQkYJ>Yn@Ek%=y-b(s8MHTRKvwfxD-8s zpZWGPR`L1mJC;>jBcoUYh!#Md?Acm$`Vurx2sqm_93^fFZ-f)EygMT12r$Ce( zrg1xqxol!euQkwc#}^DJL4k+}Tqr)u#*}eJDXxaFAwo;3@y7-MPX`Ag%;%roFwIO= zhrI!ccGnC_tpn9|z-gEyH=9py+Ey%X($H|C6&Pw=2*&jO+#X0~vMj7PEam5hZsH`& z&`?5odmEk)YuyT2m_!kQTYt9CW36(i0S1$RIKI$Y`zNh53Sk;)6#iSEuEEe}6do`=U5hahfqA z$zT5;z}tD*-JkLD?RkAHipybtxfK5E+bd}!_7e5~OYP@*SVgBip4>VtV`O$>i8 zK|Q}S)_zM|YcLAL_U23$L`!^!PG||t5vQ?Sb_5z62zLAL$W(?%$=VsSjyNs-HcJc= zU|fmY*UuG^q$PTRddn+tSRU3CYoLz=F|(Uj%?V^apW|a2Z#l|(j+tQaX+Esye*lH( VCh+?HMvMRe002ovPDHLkV1gXTSBL-r diff --git a/TMessagesProj/src/main/assets/emoji/0_1009.png b/TMessagesProj/src/main/assets/emoji/0_1009.png index 2375d8a39a012df722d01437883c2e189b32a384..6d6aa56d96e567304cfacfbd6466f8c4ca7afa41 100644 GIT binary patch delta 2483 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 delta 2380 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 delta 2195 zcmV;E2yFL(3Z4;=BYy$%P)t-sM{rDCGO2-xx zvdP0gb$_hIz`zX)t;N4IP+EBr5#S^wNnL2K$H07FcdfRv`hSND{D=|!jvR$;p}1u` z|9%MliVyvb29$4nxEvlNevKo1ivTx705m}-gOW~*mUE)0WS5^;kC|tgp~oGX5eM2C}Dm7iP!0&Sh79dw9%sI6FgfEQ9-BYKoPgpfovH6v++M{svSYjK*u z!x~>~rmCY134aPme2jm1a#;L(*?eX)Cs;Cyr&S+46 zvDMcA)c7Ho$~>IKY^})_yTLoPy8pE|SE$1Pz3fjoU!2Cw*51~?Q&EO$q*7B>Qf+XM zxVz%#;dNS!WM5xi!pD1vbV8Q(}9IEU6=wne(~|*_HdRI0R^{NkJwnK#g3T93P)tF*<~-i4cug2wcaicWk)kv>{F-8VsX!?S{;eR7gL*NiF&SY0S0y}{rKv)tgn;c&8jEaLr zWIlm?IN8S^g1{-np3YHlfbh5R$px0WXy6|X$Rt9ma2z+IAoE2y5L!ky104Upp(u(G zwgiC}Ar63INP#^Cas}E#RlBT$&|?ikirH1wh2As}@)Q`aQh1R9hkeVkYJ-L0^?wEe zq+AbbUNF@aUy%$ch^H|0{!EhUlGLjWo9GdWTI&x>Senw z)l@?cFcvk52ChRlL`tL!hAdr8eLV!+%hkV`-+E&_`Za()i2^_=AyTbp?o-(|7Ushv4`6 z;3`@zMuc8x)9~Q0>%9RKec-THS9uy-)@LddN$clfJpO(?P~6-cUbR}BrqP}7;#pZ3e8H*qV9&YIQ3eVm@VjeD()Oa$PbR$s4oWk3i;NIjFVLW-VETi8#RD6y&mNm82Yx(wZ zJ1HxfiEW$f^^U+Fa*WUYHwwdXELEMJ^Rjz?54U98Mw8R2(P|mf z=@i_ujRRGdQ>v<3j$`x>6dxkJk>fa~sk$)Aj+YNA7|vnxDb(tRy3nwS+%_MU53VdL zu4)ilj7#=6y7KYsyvT9M^84u3ck<}A?}8lyj6 z6@LE^D+Ix1s|wHa%5@qEg}ZgH*9%!_5qG@_@@UF+L~-c%A1JQsb#WmIg21w@z*Vc& zGz&W6Yb_K3LdI8!T;Uvoa~5VGau(vSUO!Y^)k_PJ1@ie!o<*QKxZ5c1ID7(=$)iRP z7p3CW)jLI51OXT_8Gnw00_~u4`iwd44DtXZC_*hOmc5E{xs*Y02;5`_EB}_^0KOiE zdC^z)D15#$$Nh~#65OW6E$Qvq{Y0kZ^Ldl6wNxsV0bEN62vE9-eUcW7$N&1_fPasYq~&s{9o1&Bs5gp$ zuA|z3FU?X44dn1klcXRld#fO%TrOA0VG7MvZKXGAKtu1;I<=xcudSNZ+#ZeaDhNU< z?6}qDl}cAHR)A)s3w5s7DwUOVyPE(7;Z=~*S>bF$Tbs{jKkF~Eo12?r1InzUcW1MX z)IQr%kVuar5Pv0!O?rWlYRiB0m&fIDS!~Rf%g2shS$3OAoZ%mlDAKE-hzqcq3>i%}HeQGXnRk!ULH*#iGcdM@KAa1ovx z0{r-i21kPVu7zQkEJ@Ly@I`q4P@2dlneULy5;R3ezqx}BAO}qmlBQ*kplK38!VDF~ zchpNDOoC(&h2LH%xEq0^Pg22fl)})|5x_}?ga7%Q6$r+{;gh3;!?ED;N38$(7XT7_ VG8l|M!VCZa002ovPDHLkV1n~+K7IfI diff --git a/TMessagesProj/src/main/assets/emoji/0_1010.png b/TMessagesProj/src/main/assets/emoji/0_1010.png index 64fa233cb62604d2013a75509ccb8202689d2905..27de035833c17be59f72aacc29cc5fb124d4e485 100644 GIT binary patch delta 2389 zcmV-b399zo5#SP#B!5a!OjJcja7@U@#>B?QqfJ0+LOsjK!>*o^(#5pEy0x~QjLON# zsD^iHIWnA^ny;#+pPQGms-$W$DWjd2otT!uzrDi2zi~l2u&%A5pPaLBQH@bYf;cgK zNIs5NNQQN8xV5yOJ~6X-Vy=vNWE=^-y}a1h)$s7{=H}$=?SJjk)6(JK;Oy$>!otDy z^YY5c$M*L1&(6%;vW%dfow&HSudlAGsi&o-qtL;&w6n6prj^^ShTYuT;JlaDrhfbT z`^JS?%8X(7`1seUgVUdPo1C4Qmz2(xYu~q!yn0ZRjft>vN3olY=hD6J+|R?dtH76g z`SI(bUqifvVSmDoYLRMO7ykeMl`S9R!JLCqMKKTq z?Vgh9duWYNFxfpHt2HCgT}`<#8ST2XzNBiHYzXI2GRZR+zLO5^SK!6~001O(QchC< zbNl@nRQ^V2&sM~^2G zuEbLO!}c@O_V$N(ESZS>N3HC>dG`M1{g*(`p1s+9`*!8&pyZpKp`Fbv8)0ltyC)IONu1%ti&;1YJa*& zQweX!zRrj&FDWI6=6Mz%0MJ0lgT+H~dS|-0_(*G)_MD8!NfIYv0CfP;sNk$n1jl9i z`+pZFZxUfX63c{PGMvP797e;MhvK185`rZzog1`l%Gr1+Om?OI87cI7Wb~X9QiAt&N5I#aOT`NJM}zLi(hG>VJb$ zok7a;2IGNj5mog(T~;k(k*Erit#`}G2b;=mh_GF=R;!w|Q5ylC$bYjMJ4-iEX(Me&nj&Sqa8M#ORx&(nVoB*5*|{3$n#QBD^?IS%zB#O+s%uM$dx(YCwH7cAZ`y@o zJ?C|^@bqjWdp;L1W^jVrl?pIMbHwV}gWVZ>jV@Y;qjsT=B}fCHkb_xJWMPn_ADfrQz9Yw_}eF|a#@rsJBey%-W6*oehGv|H{$p`Obb z(#fHJd3nNQ1H`O<*+0Cz+<#Zfh!|U)gNqjcc&J1qv0eCRj|-JtrKew_PN00Zsq|X( z&W+Tq0AfNqh0%+!AAs#*hfDxbRv1e7E7J?AF?1-i%}QlNL_77-^Ke8eIsk;hp6;KV z{Pn-oX)hZfwCN|f(?69AKn$XtVkjcAU3ByTHsriJ^nU#4=A~JH=zk8C)WMIg)NQ28 zmEu5k3OAvM4+UGGh;+I!>vp@dED(ae&U$deNT(@6cnlG5TEYYoMgx?+1q2Y-Tt>q% zU}F>~f?YTcMXZd8KBfp@%mKHUEG`P6h_P;sk6wiS5`C1_W`LlO1|$GFZ!{<&Ks06f zARH0-L-r6+HmD6a(tp_08Enop5)hH52roK)6roZC+CUlgIskDe)EiX5F8>RH=uO<< zX|!R01!LSsjSdVjV$eLwIe6RE=>B5}i*9Sd(N0lBBpeZC+L%hE(mM@Nw|`Q>G}=NG5U;`!HetNB z(JhvHr+GN2SQbur3D>wiOi^4h&Ffyqp@HfZ8dUFXi(km=I1&oFGIk|KgF3thl}`s4`C{B0fVp<9ZGn z*~rx=9a-dgoPU0J5*1|2-Z?r>hE8j%kcsMBsvrm|AznFW^xy^U^rVUclPII8gy5Td?YeHjx(NrEdm z7LtkSAcOk251IE_WMEIYW;MPb!c!zsm)8=%_M{px=%jcjg{G026Sk7eBDmlf)mjUw zM)i&X5Pzi519VGp%xX0rSzt2I9G&=UVND4bA{~S0!iieCBm9|&EJYaxyX(Y5_XaRr zpQua*hv`5Z?S+qom*{;Vs;jWiUx)7UBrvM3ZON*DZaI{QgKU)8ZWRdgsMzK^{~e4u zp-Mn5V8r%uzSMO(%c?T5Y_Nb?1a_BV6cDcXdQO#6T*t9*<+vsS*5i>UDj8p2t^T6b z^>{M!bR|~eYwKI9X4OR1R=3vI;wwQ8Pp2e7OLM`e$K(GGdLWiL_`~T(00000NkvXX Hu0mjfl}M(P delta 2256 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 Ef<)()DF6Tf delta 2197 zcmV;G2x|A;5}^^0B!2}^OjJcja7-W{9}Nx;I2B$~g*!Vt2MGzMIx0*X6~0hFzeqPaIyw^+6eJ}jEGsH- zad8A0M8co-;8qW@crVmw%aGUtp-HsJ6DYydDaE zfq_s@Pm+?6dU<(7Lqmm#iQL`Xi;az0Sy;WjzRMyEh!X`mIXcM6%BC6!b`b?lF)f)E z27f9f@9^*0AqinFD3&T4hgwxR3<-)yLa1X~TOyuL7LsEO18-SYbV56ses^Xpt9DwN zhiP)Tl#im5Nq^CuXxGPE*2h7_vrYIr)s_GN02y>rPE!D-s{ZFlVGt_l{d$Y$-qhXw zx4y&jTY;F0i6-0t00%NjL_t(|UY(bPcH_trhQ}V;N$lLf&~Ag6nazyB!QK1*k8-O8 zu_q@q_ct81toqJhRo!jr-77k7owkmTp8x&z_}ZC1(0|YB|0m_BSv!k-%Q7s>A2dF8 zj{h7`CsAfp$|BM@{WC}fu!5anlnp$J}n zMCxy39DPJs9}J?s2Dx+{bDbBG|8V?3s38e)7!yMDN^p!-l|xeF=uyO;a27SIK?flT z7-}xe#DAih*!kK6BD!FV{ZM}xHxVF^PRckCf)5ahPQV^&JrM)?Fwie5hc$*67%-m> zC@R)rnq?ReCuQ96g+BOuU%v~Te5fXM0}!g=d0uE_jDkUWWYI9BMg#~{tAfbj!yy7+ zd?{=+!M8N8_A(AL26AF@>hHEJA&ZJ&CTr7U&rri7;~IqI}hsa55>TjpgbJ_eCppkfdGx$ zpU#NR5l;jI>|LoG$`q+st$q2l8sCg3nACnpjNvRmFws#I2!gN=tYCs*dl+HvGXsqK z6MywL1jfs8uA7PPlS~sHRC&k;b`T+gH(lDxs;}w|8O~i-Ih7nVeEWKC(5aCk^b`HqherNR?1?k7y!ZReI~xG=IZe zuqs0F1B;q=;Q<6iu)v%k%9Mt;o*9Jg700thTj}_O=T?h0`^h&fQ?%hyU-D(Ua$$Q^ zN1-DNc4$~xn8t=OlX$k^Djl8k(rnSADIhFE6XnFWJYKr5rnu;k)aN&liya%8AI9O< zT}piY-GS;nzw9lxUK(Z@mF;fAI)Ad+CS@8!O_F&2=035-!0@xsGgiuk=R1dp7SHSM z!lhmaHf1}RPd3t~znhnNB+drLqaSm@HVxmP^v+#j{-mmARSb2tSZpb^Xe!&oxqWjp z>Lv4XeI@hVO~1FBCxWecmO-tRJLC9|RVk`Wq*-sVSW_zuWKrxU!uR`OGJh1xY9z^z z-H+i=6m2s$3~TEu6RFChQj_N=Zg0`MwP>KRRmNt;eu;<s8+hr9d@1lO10&{V+3W!K|dbplt)WIEZlW$7Kl6!QW`oX5N4LG1>p(^ zBgmtg-G>F$l^&=av+cI<;eTkR0~OFJ1|ZV40$Pz`UOl$K%@{%np%}JZAcDy7!iwLmerLOW=|j#4CIheZAV3~oo8_Sw9eu1;UeF#CqeO_T9$Fg6 z!h;Dd4M(h)2&UCjsuwoeUZ9l>TQh?oFg2SIiageZiPLB95zo0xov;mn{V&(Q+0)=>99R%BkvZAr60YQ_8X-LDkD`*A5+m77cQfj?;r&d>$g*%;v z1w%GN3QBWN(9qky(tn#FSY9tPNUt~Q--T(;FoW3hAT0pE;cb8Fw$;kuG?06=Gq@R@md z3*(eAT(@mdFOJhR_Cg9}m@3NW&f9O}KfAzad(^Tl!>}?dTz`*7KxqEK!%$-bE@pAp zF{xouvpd`=?r3vTYaPGwVTcgIZAQJ>WjBFM+ezm0?pB#@I2EgnTJyDfHfw|lWA5(P zuS*l6o#A{wm)F16DhR{7_Og>!gXlUVsNDTO|9-y&7osztC*OYj`%i?_LN7iYH5>Y% zLPS4*US6B9`G0nYiGBV3zds3AB5tEuilC|py}!P`6o;Vhx9h9-2vrF6g~eVY z0|1cn0YrL#b#?u1m?T5t^6Kh6e}LdR&zsP3E_M~l5zv$*F|WS@Ldp?1N1Q*?mKGjh zXdH+U5Dy5j0WL1DzJ3KnWdl+|&s4Ndbc~A5abN-vOn(BH_#GihDyly{sm=*encE@_ zKzz+@biV-s5KxSq!2#l#Oqwb~ATB3>i30KU3J5u(vcd6yIC-)s9hG2C0!C>95THE1 zLLjb0s88>obrlzgk^qPUUGljNU?3jB*XffxO#^gta#DPQ-v8%7m-(p%Q+~z1p8o@` X60T0=RSspb00000NkvXXu0mjf2G;0W diff --git a/TMessagesProj/src/main/assets/emoji/0_1012.png b/TMessagesProj/src/main/assets/emoji/0_1012.png index 50abb1ff9f70820fb361919dc60582873261cb4e..76e55a1e852359944f55fa710351a43921e6d1e1 100644 GIT binary patch delta 2481 zcmV;i2~PH*5xWzRB!6O1OjJcja7>huj>yW&pqiGiuC0k|UAV8QwWyt(oSa=iG|0oi zosEOc$;gUgRcSUYo|22l#>SeMmcPBc%gD#Atg3G@Cxm)+!N0z~yt|`KKXE}ed~Rxa zLp-QbNTOLxX+$}hkBVtPJbpJYkVZP9Juqk|AfR++S1clyJby5OR7OM~5WBj$=jP?} z^YZQL=ilk*w@w0&CJr$(Vw56$Hv5}sHbWMJ(D{n$9gh?a4v#Y_Wnv{rw zd|^^-OhKcGd4IQ?j*)C$KOhk6+0lzwL~{=XE)N5cFe9=r8l-VZm|!`ldt0-KY?WzE z)4#F*|NpZ*D}GQr?Vgg(xTV|9!k=hAqAncML@V2DT+8>-U;O&``NB_87XDR3 z!Z`j95FD;QUIX#%+oRoupYVVLwBX0TL&iIbp@^erJO2~1Q};difPYi{@eUwBK?Xpc z|2UhiE|@?9X7K*@Jrbzifv%6=J~=w7)pkNZOn;+J)A)!EZn@Ei+b>_f+}?ipaQhzg z?tLE+H?`WMANbhwO)Nt{`$&Z@=ce+?ra6m{V!BE;(*ADgppw`6AB)CYb{(f+z}{X0>{Q z?tipYB9FQiT`NEWd=jEXK?Ddm0WU>B;wMZ_?+?1MDO0<&%}NDM5IBK{08s=7)I$;9 zc*>&1d@PN#50K2}=z#BnQOHVs z(!>TJBs75%Kpcl#0mZ>NdV_G92O=!uZOli$M{FvL0R#|4Nd-yLG+npAm|-!7p?^b} zfP^%ZBuV-tf|?+T0kINXt}{xLG!;c5{a(JQ>rGa%h+^rwrZJX*(j-H-Ad&g+=XIVC zNW{Q6h|jm%m3Fh)bbEtNuhqY)uQTvttJyRZoe+;$mTm#U+YC=EDi3Z%Sl2ZnywbU; zJ2!(tuT!tbI=!2EY0#^%&EBBjw}0)n>)I?)0OhSLeec3!S=I(Xw;Stp>(2hg*@fJY zRawqt_V?vX{Q|fp=LU$ejv0-*p2ynk1Y(o5&3ry@=Brf)474OMnG?>{Qs>n+h*PbyXHhK!Ygcac6K)3?heb2BTG3EW+mHF)9E+(PMsC6V1G&Eiap?$ zhr{(e)!I_zzol53U&|w6eON6!8M)s&OP{_u0l-+NXXj_<=P;bf)SW6K;9_%a;z5hA z!7NaOQ_sk9qmcstU;zQRKUGx~Mq!t!m#b|T5Ye^G3B=Nx3EbIswF)NG#zm!m(>qHc zz*p+5Q}6WlWk6&~<-7}(TYuYxJSJA>n(0RK`Es?MQ5(HxrFU3ndw(<3e!JH_>==WF z3W%6(yY2OO_`#P>I6l8u-ezOvjNBM-<@M&_VO_gOe=9|E*jzt6tcd%v3<#wii@k>U z2>~$jdv%+1OMuYt4?)9Em;JGg)McBF$YQGjh%Qs9R$mAG0{FdDVShTMOk+Q*4FU1# zPw8%qI32YR@#%ywpo@;)cB+p85RuoVwt}t9=_GdWOC)GYeq*dMMIZwOMovITO8W$gC@V@A5dnI|kV%9J#X!WVnw~%q zW`7D|kx>vKr+mh#>fk3_2~O$(VlV|Ur|4xUr(aK1eRFmZD}PhPF3!@bii8w>%q*rd z4MC)CwN5ih$tQP0?n=}c%hDzOD#zWO$i9hswQDF-5uVf@I>=BPE&l3(vVHn>k#U9< ziBt|A%>*NKqgpLFa;9-d0Xf*dJGpB#Wc>2f^{I$OPm!9{O4HfDzsi9qfaiS%e!jmc zwJJkfB4jWP!G98qGm2V2iv$`^wqvn%t2l;S2|a_iIEHvIBY}tnAPkMei&05lsgw^v z<%-4Afnx3|$r+kOylLwqVS9>UDFW?hM5vkLG*nQ-aVkndL}f*|i{i1FgO`CFaLDwC z&Ul0|41*y`^FqG3yMrF`4o;eiKkV6-PCUDI@Nyv#v44!2=!`;$Vrki2Qpk?yQ%L4S zgWxYsVlj|M^x)ti5D}TPSw)vP5gM8t3X13pj>#O44U(kkkVpIA;AUkt9yBGc4R$4t zPoi@8`X)NUi(Elti0wXo*4LqrS^Z~86H${@u>GZ78pcxwWdR_I1YKd>Xkr68p+XQN zv~0SbWqr1p)siAaeoLFr#CJKq2&n?=gYcCYYF+*Ps-VPP_m_ zWX=T!)}z3QB6RXpwDlf)h`JCK#!eYlshtQ~UVn4o!}VZZB&?W-!gx9tNHD4Qc}CY2 z;;q4X5W|ITj3o+Vpj(bMz}U!QKNtlM{<9HZ*&ys(cqUMx#V8tKv5SOzVK0ko-eb{1 zbn#pAk#HOU)09|-wh$<;ZL?$9t_c8hIUx6GMwS6VUr`K20d;v1lK5#w77}w$pF;aZ vH7Yy%^yyq;>VFNUQ$nF|D2xiBrpNyWxg)$#RtbYc00000NkvXXu0mjfq{+IR delta 2197 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 QfdBvi07*qoM6N<$f}ll29smFU delta 2202 zcmV;L2xa$y5~UH4BYyz%P)t-sM{rCL5fUIFAs84KDi{?Q7#No+8$Br{6%`c;2?-An z5DE(mDk>^#F|QC15G*SyQ6Cux1_n1bHzFb;Ks`JI1O-+vg*_K+s5&aXP(ZgsGbJV_ zGBPqOD=RlSIY>xIARr(V6cloDavdEVcXxMfZEXz=4Hy|2XMbmB0|W#>K|x$xTw-Bi zP*6~>9ST-fR=XVufPjQZE-Qa1AYCJ&%OVVm6$W~GdS(s;pBV>v69vo6&0I4r-r(M{ zv9s^+@VvaeV<;h~q^3|9lbVy8kd2L#acemY3EUzIXfdjWL`Ai8Z8a2GV@pQPqhZ&_ zPNI`ZwJP&+0Dk}g8+1}mQviZ4O&sO^44&q*X+Y*&-ulqD>fP@B{K{L3MSij4000L@ zNklfZw`!u-Gq;M;KmpOL!q zcgR@@2tfuATtEE_;k=GRzdTeXj$=RekW%|o;kZdy7{(zS7|O7aK|+tTerKE<{Q6Es zn0hh{z97`25RCN7Z<>E!{V6D_rRp3Jg7+bWAjEZBwd%DOjwpl+cD5%fDiF3V!Z}9} z&UM{}sDGBFDnGkrm(@eT!g)zhbA4vdrc6kqO#p$I}pGNl4t z0RX5Ce6uXKdWmV}iMYh%eJRxHDg=q)5mbhhV?i80@I&9A}6e5(rI)GGk7#tuswC_K3tv$f2r@^fmy)aevC66MQm3N7|n z>}Xm*siRG$5M?T_JQ0enPNSsPOOnyeJb$IJ##9%gYH+k5QtFCe$MM*9{m=&>0YX36 z#wxazB~kv+NTQqhzza;S60uc4H^u7kJ&$750^8fIA4ZLbX(J+*ef~t8s}@Nj%;K+& zo4MvWnrRv-WIv99eB!|CArN^UhIAEiOFerc&aPY@^)fGH`0FkfqZk-rU}yt~oPVn} za6&VM*JIB}Gs+mw8@Ai5JrUKWYd7w4%tA~}7Mf1FHexH>X(gehsX^_*+A#w!2oPo- ziE_(*_iVRxt^6**9>dsSv8l~MKXt9$Rx61)*~RYdat-tJeU3fcPF9xNIy#8ry3^j> z3jRiX<~!?|4kzIDVNwvygEwFtQ_@c|*F8NX&RsW4?jk}lVn9q5*{yZk zf1IU;B$mrtcs^P$(f}rjFli?Z2?Q-p~;wz52I+q>V`gAN57=vs?#1A$4ua_8{8yrS<>IIZ zY0yw~qRIWn4~^~4iN%wGh=09l1ZfcWUG3<Cx|^d z0wPyoS-ljcD5F7{ECV9$vSL4Qz$k_pQW!-7MO0oC;KbT_(Mc!{bAL=P-Vw{P>~z4S z5X8_&k|Zk?+ITs~S11A_mt{c0!3?>sYc1!o0|}srEJ~7w4rk-FoL;Sfh%%Ulyi-dj z7^=|c^8iRO3EYPw$kp-D>#4xD(M!e{T7kscoKfm|>uoFrMqz39R@QHC9#0fKx=ThY zX#_A4d7tH*K6C*>)_;$BxecTItk0LCDH;t7rhM2NY-18QJYT81`-WKFMz<@=(f)2tW0A#Cie-yRl9Ns2Q zDquizM5w$0rWg_VZ?ygAH}a?LB#DxS!;sDq;yQ^R0EpVhe}4*8&z1UZ1XZNVc^YEE z(&gj^u8iBJa$5bv4?~0y`*zgJua~pMY(1YX7Rv_^Y>s$GIeu%NX9^+^#O<%&zFlv{ z(UZkuv3~e=!;7FdJ{_HR2*w})ar6DVaXneg=AxAQ?f37@E|JdpZ-nCxh6sV{-j5&G zo9%2eUruK0&410eA7oGP`s-t@b|?j*AZ+!^W^+BCK$ga)`$biCeQ&&eu`7fEAO#>S zAU3HW=GWcs7gx1^60crqwK~NJQV6Q`rQ6-WNtw;In{M}mYdsOK?m4H3BGIpCLsu>L zOLx=Vq_f%Nx_d8(eJ9Y8`pQIG1alRN6@o2^E+BJR#D6^yWhc62>8kQdAB6CtS|I>& zFO2);JqSREPK05*mTte?$+1p|ZV5xzg&+w?3VLfi#a*-0>C~IeX1xwSMLzsP-V+h7`bl2mhyVZp07*qoM6N<$f@jJ0qyPW_ diff --git a/TMessagesProj/src/main/assets/emoji/0_1014.png b/TMessagesProj/src/main/assets/emoji/0_1014.png index 8e91f62a675e947e8cadf3b3ed5c81313486b151..ea87733d12682966b4651a842d65dc8d67987fd8 100644 GIT binary patch delta 2971 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 R2@e1O002ovPDHLkV1jDqY>NN@ delta 2140 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 delta 2238 zcmV;v2toJ27s(NjBYyziP)t-sM{rClDJXD)aV{+@K1Dt-FfJ=9DO6ojI6gP9r-#6? zi!L%PCnhB*CMIHZWg;OVfR%=piEKhnLP}Ihk)x4gc4mg0j6X&_eUXD)Z(TJsGDufS zUTj@!erBm-2OS#g(91;j=I;ejt#b>+7ml)iY{*rnc4i1GU=?+cfPzfwWAc zKWMdDf50#pW1Y_N$;pY)vhDwaV_lw)xj#;lu@7Bcb$`tEzXUXg^4=ehb^KU!#yswr z_P=p*cpD~+vzY7n$>e@AnIt^!8~auS!`u zOvPMhkU;PQt{|6l!)|?6jomXlev+^l@^u9yRN->~@os)@qt!e2VS&#S9|Q0KK_Z-t z{hVQ5@qd`{u^%g*Bov#FAH?8e=o5xzTrmd1m?;&bqm;u$Cy)T*;~g6O&W-kfAqD1R z2$b#z8xuoE<5wgC2;&{Y{taPZaIVWh5}e1F3t~_v{DU#D?O*q^)iB|NPh~`I#27LG zgfIyjl#n4K<2T)CwEO6WE`xEm2pwPlf=~zyoqtB+|F#gw#J)bqOmJQXc`BkfW(+ov z5;`kBj&JKXgVoo;j3Le~g1pKkiUE*(_+Z3w|CbDFfW(2&oT94oJP)Mnp)B~bopT6= zs<>nQstjz%Ku|oEFE1}kKr(V9RthE)00^It;$NiE>KlEA#35(-vRrN%0UY6xPKEm< z&VR24ox%Px%$6AwL3yw;tAW;#%<2*qcV%wmLB>s`Io6!y*GhE2u*u z99O485XOx5FD`>UN+FJlst%=;A`J3(6{2)pf>4`z%kJ$(3;+Nj%#GqfjR>pEiywXU7(1fg zB_TZZ`1ttDMJ*%kYTR${L$v$EXJJ)7E#iCs@!Ol1ZVe5cClJ2?@htIS^{hnxDW?n9V9A(SVwm!cF>hBcK@Rd}X)E=2H9J4|WEcyI5; zyWvr04G+zF0-^=K7ZuWRT`nVv2U=ng6XL!cSl_E^DARt0mmStLzBUvFu$p{gT_Es|R{g@D3`%nO~Jzqj* z8j+tJt-o^+)!{BY7Sa^j))IBArue60OIM9ual?sWX;PwEsE4p4!D(2 zNTb&}_!-f>5%Jaw=&GpGG%Ft!TBOg-B+b$^6-vo0%W8>F)X8an_#@%qw5m$Q{Wu=G zBc;5euItjDfB5F52Z~)z>SfA~3?Y_0#=i{d}JW zK#-NZ6rzlnaK_r!8m%v|qo{)_bNeG-r0Lr;gob2Q03Z6uF6MLvWmpviUw%3# z7uc!rSm#EMgftALT+Mj9$5C14g{L|_g=R6&^I%1Z;k)>$t=373*?+k*;Hs4J+%&Oi zndu{j(XMWN6pqnoI$n8p*=v~{+lX=A9-yUU zqm!)44hM=mj(dA?eeAkU?>j=4qbkcj_Pq0UxPIheEZu&^LbfbaUyTrg}Fx3TvUM?Hf z;c1YcTGR`SOWJGxH%#aXEL{@NrnZi`T8Gv8%e&40tw)25EQb|E039>o%4 zD_Nv92wK+VSqUEqK#L@5M3p*=YmL0N^{VEz>)`Rh@LUnz5`i2Q?*v+a4516$Hiso? z*tVLdUFp#RjoBj34#B3P4-RGd4j=?Z4~PA1I6M=O6jI)teeEvR(eC>lLtqoF_VDXh zBJ4JxZ?UlmWq+tu=tohc-R}G-@&G`-AB;m{T!v{ac7zYNT+cb0rA4|`jh{_-vzfYJ zc;6w)+Y1e8iZBiT0ef3QIh{?XX`R6o((7z9o6Xjk5zqVB&n+2$U!eL!d-tuNA00)aGcsQJzg0e?kLvndcqVB`SgfewdevnL>E z2}Oib3@z%n-9visSwN9@GzUUsW&nTy#JoG#x{m;X^upsafwQ&~F|-h`39t?XXfu7y zgV_}OccJ;bJM|(hydL+g_T@hp9jkXvv7TOVf3%s;rl7#U%^cAXlISjovECwXdhP$d zDW69qZ#O;1LWFMcHs5r+nt?yM3#f~?k`PA+d;j^}>fjUEr0)p-0c~u!HEAzX)Bpeg M07*qoM6N<$f&e5mKmY&$ diff --git a/TMessagesProj/src/main/assets/emoji/0_1016.png b/TMessagesProj/src/main/assets/emoji/0_1016.png index 87c2b4943e0931afc6026819383a3f61bf2c86f8..8056dcb1f69a18eac5adca86e0c11d1d2192e853 100644 GIT binary patch delta 3004 zcmV;t3q$mj5y2ObBYy(=P)t-sM{rEnsBlI(DM>gaNjD)lEgd~BCW41eJ2xjmPA_!Z z`$jh;QB*RedQM16KSMPjK{6o9z-+U;a1#UqKRF`Bhg>2W5Jfm7I447ek8o5*C^sk+ zil|vsreCF>KT1nXTUI)fbw5_IPP2+sU`i{)omNsf9f)W&Xn$BjUQ01mt4Wr~fxXpt z3kwTjUdl~dKca#A`XPQYBIfk~H^M=BFZYgj&RT0Z~)09r;bWK=>n zBoVZiMp&ODTb^3Z;e1q)H)^pquZ>1roMlwQR8Yxnw!mJ9gGEq*Z7UxTu9`=j)tO?| zf?Q}UWjs?-r+?c-K^YwlPFhJaQ9&$6I3!L#DQHzWJ1!YtOf@qm6+AE>Rz@&XL@i1? zDdM@2b6rDYP&js9MQc_)Wl}oLm1=HTKT9$i(3^5tJRz!rOIK1W+_8#{Ye>wGVx5I_ zNlHr9p?Kl8k5N%kH7Oi_U^daCX+t$3*Qb42TU#q15PwE15$C>^WJ@kga~QXYRobqF zeq~6PfjwMCDr7|^J}g3NP$u2BkY`Uca9csFlSoWSDb=fk3)e*|6-Z}jX~LCB%9&v{ z9bSP zGs{X+t3*zXULlfA2#QFi^Sy(cMCZ(;fmTw2f`nl~W7NpAu(GwRrJ-JbFR`>lwerS} zS|Kb)3}DhWF{oWblRgK7MT*jWubOUAaf&o`!*ROph|clLq++1qsV;OpamSU$!c?H9 ztA8R;oK&UdvuM&$00010bW%=J0RDZ^=RsHn7Yyh2BmU^Bkq{jIF8*b}=>53zXZ!xT zZ5KlOTGdjo#j`HnqU5rf^|IrO=R@-0sguw2=bKB)^~3&r<*@$S*>$VLR?0rT_p4AxT6*RCr$1mt|C3cN)eaGk**aAb1EQAx0q5t)xlQcDE{No35u7 zcXxMp_qe;eyQl8!d(OW1LVC7g*ptb(eLf6#fcJNv|10;s*X930K?@fyd+oL7Jv^V8 zKzm6n5C~p>eRh2YzR5jAZJa4;9P_Q42GQ}0|s5l@pZB;Zd8e5Rwd1&Xm;M4a0b9HIohu7!Hg~<^)=4hV&ctuh(h?F9 z(nuv_gXq~zE@WfwvZqBX@qZyyQ&U^p)MT|E}QD>DgVB*p(JO+;BMvlB?ArIS*U zN>8t>T=X;m51OwR4>G|)5GK@9D3L%>nFyH<`P0}4nnA%K8WIU3CJ=~3qohQF9JqCI zPz>{R^Zeg!?MKClLO?jgrjXhUA}&S+P#S14uaMc(HmRqZuNOFAN`J%<50U%+TfhN` z7@XidJH;`?lNRE|!%-m6e->mxA`=KmLz^cdLWB!VMxjkzj@}_^^)^ylww0^%KrmPg zWqLv+yN?ILQ8GgyvhVF|-=HZb!nP$QCT`iX<%=(N?>=rY81`EZ#eE*EFzT8H%x1&! z{rk5P>g(&XL$l*xgnv5Q{Yl2c7l1)fT6XUqh%xU!q-;`{_$HG^x~HM2D8_664xz0Z zHwNyCWmy=Esdsaa6)(PU>0#o-hb^rQ?J+ED^HBW(Lh&ZWQ1zWV?SLU6yEc*n(ClB7 z)1CbEo(GgmWo4la9Bp!Zd^`Y1h(2*3W-?0;W$$h_YNJifYF78+Wn z?c`VK^;Mb!ld8}U>AUpR;KXp8I0?i*(PEx|xUq7wbJyM^2sTZ3clCJtxe12p-2Lvc zh6no2t|Ec~;Zs-Aieoqax{~za{_)<>GHX(@zPY-+kN4mnpFm_a-)R`=d(hkyy@$xF z!_~az*k_+jFn|1?+gsMEb?v#|%nJ-WG}N3G4?1!m3k;0icj0`r0*Yf^;DE6BBS75v z78oSrRM+{c=6{NyFYYy;uj)8oasEQbp+hIXyWd>Z(O@o$S>Rx)eb{^K2H5!a9l$-e zxAl|?(*NK>RnNT(741VKBVAqRE}Z-B+`aCL)gx_&n13P%h=7lJiG%$8%6ou+84$%b zX{Wya$dMz8w(j^_w=`XC@TH=&x>ITl9x%kbF?GZjuUoh7t83T4`T9M`^SgUn`-^SS zis})aPTE;r#lLln-=SAXb-_b=W3(|?Vu)GjU`Ri?di9&@*ROy5wl|TCvi{<~xF*-@ zM|ygyJAe2JsZ^2G(b3bR*XL`Z6~SV|EJqJI?_9ll?Zk-_SKeO?z;{E}7az3cn=};e70!!M7oik^1)6>M}D%#6tAhT*TnNR`O$=jRRPm&uNM;&=bt!n z4SxuglaCMqOW!Iku^E#!8V#foWRyZ@ECqsN1#Q?6mv`-NIa+N>vcq*H ziswSr;*@h9^VCz;Rx%?aeqFR z$3a3?uYDyoHT+R{e>v&szhG&b%lKC4S=RNV$Z;r25%bxH8-lT_mBy42s{^OYPB*2B4=!>Osc zxv66r+fO$Zi;{fK7B>Q5%qK}z3xDx8SDVe%^<_^-Hi%YEP-kXZ`%?)4Nsv*f4ZZk% zm#Q%1c3WMN3gT@gNh(!RU5U+6UA!Xzk;brCEU?R=I+fO1)nRMQ4?q3*FVQ9yIM71t z$(Z9PnqJvdqjHo}&*e}tB!kfQNoAbL{{G)T{rH19`wa2B!pGV^UTL+y;Wfa;aw?S? yG3&AB5PEgaCo^Zx{PV0=pVUhc5n(@f>3;wSPz%l2^L=0d0000+>q zHiVgqS!7aOa9}ShDxQyUe35{xoO*qef-5N~Yk+YjBqTOAGmfN`L`**?B_%XAF==sJ zhMbH`R6~xWlxlx)Pg+V$P)NV9ie7MGWqN8fF)t`4CN3;1I)64aM_5UMmxzs`l0;KQ zhn$UUfN?!bK0-V?K~F+`k%CZQQFe=aafNm{MLK6)N0O(QNkc$SNJXEJai*4bmaCj0 zA|W$CHJOTRi-2Xg&%JkXS*@OYrM#=SsDcs@3i|iO-pP)tvX{QOl4nE_M<)taPD;X( zMYDJw4Y8ey0Dk}gBXm+uQvglgtuHi484UgCR*r4R<<{n$=(qQFA000LqNkl z0T+%mlz(DA*G6CfLh1NmK%UY3B#P5xP58PxpU-t&5JOUAN_+unA`SZc{AiqM8q%oE zAw)wA3CS5c5E?u=+ru~oLHNjo{L|(#rFl3xLnX$ZPA$uCXmgmS3m{aXkC0P>_#>*W zpgnZGzdI9c6-F9*Le&Bz@B~nrKZbIKuY&+Ydw*xI7g0}LsNiU-tuUsf8ZCU;o?y_a z16}Ct;?6jbLlETEVBB>%TTo7P3W5MY==ebNcX@G2O-1`s@f0_S<1pkN3M`x5-x6fc zobIY<|5(!`0nr2;_NL>QN#rdwK&UrKpsVx#&XOW|6b1-3k4?uSIZo(uL&l>Ck_Mga z@_(YOk`J`ug2i!?#LjT|PO;&M+<^$9y`#4W);DPur>>MLdZ)V;l?;kxW{w6XIt79B)RN;kvI+Z!r1x^Er{3u;QnOZ{Oa2K0m#>T-QtWy@-keMELS<@_%AU z#LLsu^N%0TPguLU*ZX96mPUqaCf3vQ&mYfg%h{IH89tGo!{Iv7qwao0aGk}Rb7#H2=So=l1aTO<9BvFP z$D;0@S+2qyFrYOECQmw_KF=;nE`Lv8Ka>PViIm92LQ-ZS=hugYPj%*k0Y9Wdw5h`7 z0_Qd6u2TG*P(5OC!d(mtlI56Y?h?%&H}TFsC$zO74&ww2vXs^kj(hC7amdASzf$=G zQ5G5tO*2kH%aWU$7^2o}7$%seap1FXc(OAcTY6bjM;M$=7&8YrvSw zXbAPFD2z%XNTn56S86Pt0C`ALY65?@m=QIn*6JnZ{hD+i_G%Z1^8~hrVKejEu!BKeHiG1Ihn8fVrRktnXc;y@QjJiodY5nEP3&t4Gn^P!}Ho!i4zmtwTc$z)>~60uoMr+=%J5=cuM7(#en>HOmt zd8NaM{ILg<$1I*qmYYlgVl%nBn=bD*p1non45gC;4!hlJ#drtEm!WXZT@WUB(^aIv z1u*U&Rw?-J2q-F5wxx4TlSMfo--OD(nnIJwbQ!HC(B1UzVM6r@;7ZPjlxx}7E#{j1 zgJ7U$l19-_?|+u?gaI+#DqDDZ;_^d zAZ%_Xye8dXN?s^32E+EEfYq^XxKG8nI52Y*S#3Xq3~2U(THB88BXv|MeS zgYdxsn*{sCVuPp=34|MYhsy&oplkuiA`Qw#B(m}6vDY7@BoJ;_a2SZ({V5Q1^YAJe z4|m=I3cl3;?%(_ashclfzkL0QOa6`<2=D)czT&NPK*C&m*Z%?PP1|9Dhp3nU0000< LMNUMnLIPldC4Cqy diff --git a/TMessagesProj/src/main/assets/emoji/0_1017.png b/TMessagesProj/src/main/assets/emoji/0_1017.png index bfed2547f908b01816a957fbc64d10c93696fc5f..c4a09a9ea5f2bea7bbd88a0738c33509a2a2b0e6 100644 GIT binary patch delta 2866 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 Q)&Kwi07*qoM6N<$f@E_)DgXcg delta 2214 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 a2>$}~#4UP&FzPNJcj#5(oupaYIZyB{wV_ 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 U?q3y>mjD0&07*qoM6N<$f&}IeX#fBK diff --git a/TMessagesProj/src/main/assets/emoji/0_1020.png b/TMessagesProj/src/main/assets/emoji/0_1020.png index 2826605e38bdfddcf9243e545242cf0981c734dd..c121d9a7570d52898b6377f02a487ded27262fa4 100644 GIT binary patch delta 2991 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 delta 2520 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 delta 3277 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 LNkvXXu0mjf2=Zx9 diff --git a/TMessagesProj/src/main/assets/emoji/0_1023.png b/TMessagesProj/src/main/assets/emoji/0_1023.png index 33b80c962acd3fe0cd521c3323ac5914d38327f3..ce6c575e875ea4617cfc6147b3ecb32c3fb9c665 100644 GIT binary patch delta 2751 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 FV1nm%1e*W= delta 3308 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 Eg3d~xlK=n! delta 3276 zcmV;-3^Vii6VMruB!Bl%OjJcja7=qgI&iAbYdR`?JWp&tCWo=io}P$%VPt$tSZ6an zrHN;S&g^$YBSdVQhS2Yb*7AfXaEwkcUo;_#UqWDdn|nzsY(FP*LnwAaDU@F^do5^+ zC1h@Ut6@WCWp|`jG-rKEF1UduadD^DrXF!tik4q1h|%$lX@6^|XA8D@5yFipYf(#$ zCShedBV`;e zX@#Jnz1iz`V@#fGN!od1hLdN&vYCKwOyuwKH$#3iId^m3U~3{Nw$( z{y=uQPyGJ;>HggP&u*+{xBC8jHvazo{@#|>>V%v6(&@iehaXS!{@n4|`_V*QmrVG+ z{PC;(l5+2m)5!ko`<}@A?7CNq)z>?$tbeZg>hSZ?$CCZc!~3U}}TvY28#`nO?>ddtfT8yky?Zk@Ps z!|AuFUygt<@ZK^MVQXhs-P>DM-hbGbmv`&N74;v#|2EZr1k>+$#>cWl6byc|z?UWz zHWn2ELCquEfpK6YM33uEl(E0#Jpc$yY!~?UcGuPvHRhG)-MXU2lu}&%?eE{}jS!^A z%N1%tM^?P!U>jox7HVp0Yx4>V!GfAnDiu8SAE&<>0TCME>B@A&#M*VmHh;Tn-|Fs~ zn!>WOvJ<9i^%qYoq*C4kO=?Qx_(#3n-8Bq>K|H*(=%KViEY^%&hU!GjWp4y( ztC*qY8o4B%YVwM!Nk}r*VKemF0YU(DAPc$ZWHeRV8`eY5$|zmX;)WQ zp4X$=+U~;gY5-(qWzo}6N-tu&&hrn`4Ra#k=9fMF^p z)z{RNpFZ*m%?MhFns9_%x9?p3dpJ2cd4aFzov^lKCnpBLG6>9+=YJ=91pwtNf0$q! z8TtJWhYkm=Xv+ddaKxSSAg8SGaHnASm<$Yx#I1!wj=sK*e)6ZAYETVRJhZB_?OG}NT<7ZodSba*aij$`gqzn z1V%aqN7|ZfZEbB03$(N_>*y2%fkt4KI_{-_>z@!Ra&Qm{{at@Xgzp{njD;47+?MbE zXID+@H@4P`m2!oGluM;jxq=}5bdJ`;Whb9`u3kHTUiqIMcYmg5)4%?vt*z}V2W#3t z2q+YWkpyL>d$8UsV^MzWkDlHxoxYx{FZ?x zv)dZArUfBxKi-WWfR)0Xy_{{%wq~5Dxxr(% z2z|r~lYb5%X6btQMtaEj54O-D+~2Q|lj|0`G1fNV6iHGPMDgPy2AGmX7|TWt_n8{ei#*h(qC%?i3DIN7mOLDz7y@rIiiq~UK#buJMZl!_h;aRiSg@c}_{=wFyGj!< z5=7y=WpL&9D&-8qNG3BLh8Q;)K_JONWradBKYx@>>bP(nybn^Lz;P1iSpmXXsW4y; zoGqI@l!1<+si9);3Z;(+3lN5UUeNypqY*ruz@eK6XPT5?HnH9;nQS)r)|OG!C@7lW z;ay?2aG<|a40G;Ze`bbL1Pp}4>2<@MCf}>io+y(@WMho9JF#jNAm_sP6c1*wZJ1Ku ze1H4;v;Iy<0t^!0AfOS%CJvh$5c#s%6GshBV_cMsZiT*&8LrtA%A^3ov+K9}8vcZd zkOZ`oe&!r!%9+ca83hQ5Og76Hg%8FPS4m_N#*@RIn>QU8>^xP@?d$iOiw&FB0fQb0 zy?U)MY+!GpyJV95eA1WS2-Q?jo-hOi) zJrE4DMhBV)^;JNTtr{cCryWTKC&cx)p&LG_zMmzWI+fIP6ZB`aBO=KDj~DXND1{W--9At@>IcwI{696dyY(%zw#A z1Xk3`>CAn9E;7$Bqq#q)Km`OqWS&eto^m+=F1z0b4A#YfP@^bGeokURMoCG-)HQ3y zX>E)B&Qd^3r(7VJYHSpa}YsA**W0XllwXp1S5k?U(CrGeworkW)~f zernJ}YRcu0%n_j#SKw!%wY$+#yMOX?N&u0O^C2J65@%t$s-OV~XOA8|n#AU)ycEFf zGm+^uf%b9yaft=lP1z-@^$=~DPf}$R6x18i1jfWkFabG027a6UOolx0fQ; zjEs6ParP)p000n91HqmFjDHvATh9{)cKTS0K(2`w`K0000< KMNUMnLSTYK^G#&{ diff --git a/TMessagesProj/src/main/assets/emoji/0_1026.png b/TMessagesProj/src/main/assets/emoji/0_1026.png index 573a744d710b08e3c6c7e341678b107062f27e6d..9c8a62576cb6bf03fe8ad8e890dda89f01c7c224 100644 GIT binary patch delta 2939 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 A2><{9 delta 3155 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1028.png b/TMessagesProj/src/main/assets/emoji/0_1028.png index 0a5e9fe45d01411e47e4e12b29904008a7fa3317..c4ab53b3a202a3fbd1ad18bb7e8fc5358b2ee8df 100644 GIT binary patch delta 2933 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

~`e90~UbbcDH71%HG`gG=n-z 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 P00000NkvXXu0mjfb()LU delta 3106 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_103.png b/TMessagesProj/src/main/assets/emoji/0_103.png index 7f8234782630d95658811d48622a048e680af3fc..6b379a8ee1249843f32c4afd454b5455e600c125 100644 GIT binary patch delta 2197 zcmV;G2x|AZ5TOx}B!BWyOjJcja7>!3t_Vj|{Spl{U}pq8N|m;_1UN*Yx3h*PCZfBw zWEB-MTWSA+0sWT;v&zG!!oG=cupd`rX9NV_JURJ|F5ZSl3qDI?1_jGyWC}b=#}*T^ z$-_T&f2_s8zzqwn#lJLAT6qx>;3OnTU1+bzzly7{v93CWojU#-E05?PcG(jhWl1_`3bE2qZm!DUUnP-`yV3wX5Yk4z( zj$D(RD}Ibbhm%;9pIib0ZJneYbclSYtyp`27gAj#dXzkbkVG{#BWZ+3aCbs$ahkxx z8eeRts-p}E3V%p^jDL7?Ss)-GA|k0@Unn*?`g(XVf|hY>X)FWuZ&5f$4Je}XJaA(+b6-qycUQHE-yQd3q^ZE%pd zyW;2Jby|#G!pCcgihG!ssm##!QBMExYX8$B|Jxa4Utj;U0{`C@b+o#Mu(QxzQz-9jaF)sf6?>YWp!TmEFs_Xse@YO|8y`znoN4mLz zc;=E^%lWLn*(y=Qhc8%cQOIIPe97?|(Q;oi%xy?;U`ozASig-q!nkvJ%&-(c7u-qq{% z;X!yuX;_~z++Ppd#OFJoMA$aciTj7|E)VxlJE0X%K8c;sgTxav;_=Y?EX94kgk9(Q z*S%je_O`+)GF!XvT#k>A-D7ua0jqk(SHhZ`D~H^3VF0A z7k`w=#6DphdW}goAA51GXg&!rCO&|9w5yXDRo4KB55@o&qc0eW029FJ8b#N*tKYU= zt=hJIHFAA=a&mgj=n%3dLNsC_a2>1q*meVm*admD{~0T0&9VWg1Lx3{OEwK*10o%Lq=(QsYv+Y_z1d zYRGepT3e!l>(C83pja;yVhjTW0rkdGA2fOXeAIGFks#AghTU>&aLDsKH;~FBR+b%x z*)9|^bH%qvz+Snf@-(OCgFX=sW?~#(%&NLV{0V zurUO4NH_#C7nR7>dvgfEL+1th85RrwYkyc+0-JwXF3*15 zDH`3NWlij%A#?2GGv?`1jt@tpQ9B4_n2Z;F9F5Cqe49D@Z1bKiu)ieVUE^<|^6eEACUq%28I9DgJXn6m`4uMhrw zQ+U07tl)Wvt;ih5$+t-)@CrNPndg2`JF^T4yhqvsNz$K!PIFvO>wND3yvSL;``ERBz?o(C@+9 z{V*qZN-l-RQ%WR0V~_;5Nnt~Bvv)UW>_5RoF?3W~VI%VPjI zJhNJT4%Bgdt-X3gj=>Sufa3h{pFKpA94z0$a9lLT0kP<|GSO`a9)fl&PADo3GdrS) z?F($tcOgg8A>V=G11MA`dPr=$;eH2`rl=FwHD8#b2!EI27>r0$0oNt)Z=~xmjsgea zIw8P^Pc%59%nvOL!=y=y{)7+0{e{v*I>!8fSel?II`rKuXdiOW6d|f=`Ut8j5+uw} zA$&&N_yQzIc2M}~hJv%TTO&tN8WWfKQ_gOxFI1o5FN+1ySAHT)=pML?s Xr+UCJ-3|%O00000NkvXXu0mjfdXp%n delta 2091 zcmV+`2-NqX5x5YLB!5#-OjJcja7^UBTi2Q=?aP_gl_~z=YSElJdtyA@t!LP#R@|RC z+np~V92eK2Huc$)^3#*XlNra87~-f{y^AB`wu;J^8_Jg)FbSEhOEmC&rEw@ycK4yGrDby7Gm>K=mUtdl>-?BH-t4FYlDUWwtx05kMJu*Zz7`2&C zUP&I)wN}ldH-C3xIE!&Ccv~Bui*TZP8gOG)|KE0>gE;@@fA!2lw|Of5*KLq#7w^PN z;i+lcoJarMRmrxY{M1Rbbt(Vtg3`vk|Lb@E=xqP-iLIcL7BVw47#V_3`~9(ZW~EwIHi`SL=k%^$ zd1rpU|2Zr0(*Igkc3kdfFZEgyp9K4+*Yga(_35RsZMD$7&G8(!z4Hge?cL-#p66Xw z6y7sF>~XB6@N@(d2_99ecB=65UzFCV_YCkQWa2P;;9 zXU8t^5Xds|z=C)U0(WT<;iW}S*S26*AcnYULHq>*IWvn0n+wP4o>o98v28(onzjH! zPh`!zys`0uW@BU7wP{wsegwozi$gz{wIEI^%6}#j&P?X38K={kVS_z$0WLyVJQ$lG zAV3Lg>`ey2-Y+yjGMSsq4XXh`eoIgwa)V^B{o&g`X}&!`$=o23DH66M4kSwSSPIMw z)c8V*+}+)=y!#`iT7v0h$(=00P!fyY9OaD!qT?Y zqkkpk!g&ZV5@v~SPYrq;gg6a`!;;mb_1-TABd0{TNjOacz~8ta&>GH6f*7YTMCmUJ zVkH-i;I1hgVGa;~o0(1GoD#`PO|p8Wde*3LSHd%O^pz3-%+MA`AQCqb(jv+B-dhmv zx2H)E5lTQHE#`<5+M)!4)JWP^EQsZN5`RR55?{MrYCH-c(%nENQHn(FAQUb)EQq~i zA$iJ1N~MI;*_Y)3F@OM|!b7(uw`_!nphcnZ*7I|TU|~v}e{IXEA!omxz(B|pCnwGp zGm$%lUU?llle5X7)4Sgt5G>@@)d zEeN5P9tr!?NmhK6xMTx?bQ*tAQGe7{`g|_VV_8uYxgD7i*zk0cSMj(HM4k=6IBzp( zaeOox}5KKlvJUtBeDu@C- zivW@i)O8y+o(I|^qzx50?zc;9p3S3#*<#HzM|g0WLNAp{WwTuy*?|3sO@E)%^}0UM zZE3)zQksqt)T+H+&$n=%EB4%BjR;7)J!Jyt?Q(ro$4|Kp0%7x7Hr1f1)y6q-{sr%{ z7r935n53P`R=Zswn5SLV>xfPXj8M&Ht63m5MC4+Q`L7Z0562hdMyl7#nyK0d5wP{k zeO=efeOn-pXj(O!qJc8LxPLf%B;4yC4`W zs2Sko)>IILV%+Xp-`{tebKub`#yDb(FAja7$}CY_iwXJoaSeh{ERsiyPC}c!DaK+P zC-^$D+8T~|v_YP3CGiQhVM~#RK7r$k<^%2qLF00OfKgLrL}_(~7vpixFL445C;4;Z zi(#jws4}h^gjlh-@PD3zNhBDghKhI2QGGHgm&+Y9EyTbpZ!&6<+d~K-FvpX4QA3iT zv}6#UKmYjgFEgL#bK8Q@0wBd=izVo3NW^F`vTEFZpXj5}_uJbaG@oy8zmGQG+p>ps=DahS8!I!zhZP;@7G=6YMUFPk(kh48PycH4M3FU_Zkc zFw6h}Q*Nn7gY)|#I4r+pyQYTJznjTc0)pwI0_kA? z^%wnB2aH_K&mA{m81sW*wB|AA&p~jkQNcQ%H`k6Bj9e_$H_+n|K&5_9%K81g<9c;v z>38wIyLOmGQh$1rnFdx|R}6BUe|uA2ulP-y_R=TO_;4*50zk89ZM>u>b!e{|2of VkaZULGrj--002ovPDHLkV1gw)`r!Zo diff --git a/TMessagesProj/src/main/assets/emoji/0_1030.png b/TMessagesProj/src/main/assets/emoji/0_1030.png index ef139ca55e71277e4c60d0506973dc5a1231b6b5..24a4dc464dda73314352729aac3ea16e1aa885fd 100644 GIT binary patch delta 2937 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 QdjJ3c07*qoM6N<$g4wH5Q~&?~ delta 3085 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1032.png b/TMessagesProj/src/main/assets/emoji/0_1032.png index 7347397745ee0ac83854c2b7b871f71144d9bffc..868d0b3b0dc6f2757461a329e625015ebd75e8e3 100644 GIT binary patch delta 2677 zcmV-*3X1iN82uEGBYy$BP)t-sM{rC$q-oH_fZNWG(#C(krCQ_Gm+j)F!m4G^!FA}x zPWHz=Pt}W8?skM|h)X0Rww{vW%1wV66hzIpJpB>C~g*q9>9zIxr!kE59H^v3_lCF9qa^y;$T)ROS#s@ctv(#MPZ!Xxyz9rwK<=G&Y3 z@xi;Wb^rIs?ynr!%!SLqgXgFk+|Y~v&@allcdDIk-kcfT#d_wmDn4p7|IkA;rEH;T z57Lz!n9S9&|cs9TYT zaj&P2|H~|%fS{_x&6MDsQ%MG_>|+%<>c>M zi?Hk3{(t^9a`e&w00==zL_t(|UbWT-Qyke52XG$?3@k_s!UQ1+1xu$p+b}tY%{k|s zmz;CX%2{_`*!_l8SwahzT=u_;V&~EGn|}S6g1`K~({)o%*MEEah+%MO;BSzDp}TD( zKhJb@4i4a!^))^77Ghwq^CywcAy&VCeSLm@9e<$pd1_#AucxU{18qMn z+#JO92cyhFz993&-L4-LhAaR;0I*mVEEXME2V`9Xwlhn zao9}2u`aMIfn!(iWRPW9o}eg=B2wXS-4jWct0yPbax&tnhbQ+b6qaXM%y8u>26+e$ zf`toDPKJvmM5jelVU`RtF+j=jQ6_YItKUNZ0&JH9EL%hU?D}C($Ile+Qr?5%)TD z0^^GZ2VpC}woBI_^zK^h^nc)B*%)OtoZ9d@yzwiDTmM*zc)gg0Yve23moV~cc<_P< z5^J%Xe?wDwAYOUBk(JwBR}kh@(#r!8eI4B8S#}o*y5ZVoiQV0xF@}gpBxSyecw#pX zM_3#Y65LGFNN6JZH6k<;1pDpQx)vmAb&6r#3wgf5^Z+T zZnonje{l_rn5y8_eloYzz`u0TV*)brEqxrU>g!% zo}wj5ailmL2vrm~hP>0_JQz|1gU1P+uon|(D^uam&1?gqSW`s-2%H2#C57(GLf0LP zBpHTdb;9F82JJF!A8c+OY%fnqiegQ8JR(jIIFAI9?Eik4K!2zV0|3t2&7PG6>_w{4 zj!49$)L;(QoX2by^&c}T5ZL|8uSqvULR6I?2#vS9&E`VRAuG@c1OVAzHk-|EkwpXu zK>T{^@+e51Ac4R!(T)(*2q+2w*2D?`c2PhC0R)7*JdA$m01;@jq#yudHhZ!OzXRe= z#619jfTm3l7k`yZTMGh$H3?+6J%RK@HXNSZOQ#Fa0tfSLJT8c6l_9|3b%MK0 z7%m7F5uCm7{y6Y*8Zr^cWCIiE~JXut$3f~b73W*3Y@azv1WCYS<>2wK%=2A)3kAz`b5C+&M$6*A- zom|dLluFN$5y+ezX9Ck8JTH|dGTCJt2rLP;%y%2<2LKT)!IvG9BwIghfdRye7wHlb zw)PxWNq;iAStub~Af(Z`Eo5Xq zjlCTm`;LT*`;u-aAnhYxHDQA!;ut)^Jvll2aVG?Wm>V?)gFQV|f_iZTs|DJ??9nbL?MwTZteZ3%rc6x90Ee3la!NrHYeLLeY;hpi!q#LTRL_#Of zp)`*J2`~!qnN)bZuXkssudnyU4P@v7d~WQ8^zDR>!etW5U>JG~&3!y+M{z&pFcNFe zPJ|vle24@@j2e4-jH5`?k%!~Y$A(dv?`gZ9=KmR8Bi(u)bV9lx`~vywm;CYo*1x)h jJm^Msu#N)r{9oi>8vqU=-hRv100000NkvXXu0mjfAq^*W delta 3080 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1033.png b/TMessagesProj/src/main/assets/emoji/0_1033.png index 8f6648dcc2b3069669ecdff37dc52fe55a8ddc99..dc4f339ed36f41ceb2c62c374387c90dae91218e 100644 GIT binary patch delta 2757 zcmV;$3Oe=A7t9rqBYy$KP)t-sM{rEex_jErkfolyxqrg8dC;SG%)ENUtZLK2 zg2kF(=+~P)v~o(vgU`Qz(#L~Dy?MyEcFVqe@#e4U*rP$KZd&D*Q`wE!&5Yi|j_1{# zQP_-Jt$gj;sOsRR`SHZ=a^ky|v7ltCo?t+MRf>graDRhY`S8B!-k#r^5b`rW+Zt%vU9rnszd%D#WZwwI`!gXPzwZh0&8)Udvv zagKmiEz=9X{w}@Zje>7rHPo3eBHyN>d~z;nPJGS zZ|KdP-qVg2Su`YULDivO|M}JD!ILhCRR8$RAY?mMbu)pMY&E24zmH6(l2Z~21bwlK z&Be4~gk0azw#2K5!N;QI-M{$k+i>2eiEc}zuYZDyHGfB!TD^r~X2*@|P}`0eUpW8&|M2F?En6r!DiTgSA`eR{8=ohd@20000fbW%=J02luB{wn?cK?z;{LqYzUas0xB=zaeALA}?e_5GN< z zFfubkkfFGrckk2GJ&iN=CVO`OhBJD4`suza<>mMv|L=5l>AUp$uHOF==(hTe)7y7{h_cN7OUtZ<92&jxnaGX%o`3fBv$Jhx!8bIj|C|zrhcsXoWdZ#{ zm~W`>)0;So&t6=wMWX}ymvN{e1s${QHFV?RoZq^~`&CNYn#kffngUXyLs7lZjp)HoZ&D~19R4)x) z+lnE+1V*J6+w{ps!3vS2Kp-HgM$EDqtAEAnrBaFirt2DF8281aJF$8?8cRnT$;P&1 zx7%&b?QN+MP1mC7SZpU6e@5T9W*zsRu|A4q`Fc8DjO{d{mF;wTBfVFNZtui0&2*h- zN!-Wc_pT;x46!&#L*wGHO05!&rYo`KgM;N-B^`}cqLob53@C6DwYxapxu6JEwXbtOZ#x_gA<5z_ z#lLy;X8mDdKj7b9UT*pW`|0(!Z`OaoSlE6hL`87GIy$B6dpIX>K+y5G>+9>k{QS~p zvo)Je`>U5}IDYd-oJ2%WQGeC%0O&{o#jHoCyOR>b>lfrutp4bpzciNu3d^Pj_=O=p{oNS6gG5lR`XCfR< zi3*M5EHUAK0@=6O{D^?%>}$tyL?lHq6~281VTgoNL5iaAcpUERgnu7@y9$udiu`dM zOW__6B3BSS-LfHE00DPTpgRL#1IDHq=-8I@3cake!o2+Sp`LOYd4TFj4}6h+AatN46Rf-6%?$JJ$ZWi zRLiMRLP9WQ)|$=3wnE(L&`gGaGB6G&DKfHVRAA2uoc{K(oqwlEw2agmhEuTl@@B?O zU_Br2n;`-WGfj~c9m!;j3e@3Lp8f`TYLqk~li?{KI3y6n&5xRS7ZD7D2u~y&Mg|lj zsiLS@16EB4hj|j6X52u8?p%IBd&~sH?IuaMjchQ4!{b3!a9AZtN?IMz$#6JqFz{ND zNN|TR{pD5=8h=3`A_T7(LX1IGRRuv+m7o!TNJQp6e-aS$qv9 znVBF&oLS9)fZiw$hceqUnahv$CgFxKIz+fJ3`0idbt17^E}M=M2~B`u9U@>Vq$2_C z9k%x^6p$qWsIhe1<6 zdbe(&VU56v>h$8`^z`&15KH;QaXv9M^#TT9Fu&}E(G);u!ukE>gc^GKNA+S)3mQeK**X~GPI_cC!4 z0P|#srpeH_n#(!VqZSx1^2Zw+iKQ1Hw3byNms27hL`5X`vhu;zA0 zTF6*BK07;3EP~KlN$0FqWt;#a?nSe2U;0zd1%HB9;XE|$H3DHBYeD9x6N!U^M~UfQ zTR@C7a#nSmA!$#%fQWAW2gGe~y#>VsiIf#bZg)i^mJ+Ye4qh)UK@nga<*b6q1ye$z z3#NMqKm0EQM!bbNj`M`Z5wX$Ih{xGS)v-s}H6S2kO{-9ja2}2e7QEg`@88Sly6uIy z#D57cOMb7-eL1_k2)<%O#2-NaVC!I~!P8 zY0aN(G;-*2!I5ihjLgqNL(ih3$pr)<7Jpn|xc(}muiNW_7?qGNM2wd+{m-G9D+B${ z&!Pap-WBcd?;jXhfw7TdIRZi`XmmmT>PGKP5D+l|MKGq*5tu*F-~ar}FTd;u0|fZ| z9D%+XPtOluK)!0{i!WfX2OV7;|M0`bJT0)0|3&@{#r@}l3&jK~00000 LNkvXXu0mjfju?Wx delta 3018 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 RU>yJe002ovPDHLkV1jCE1JnQj delta 3048 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 delta 3047 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1036.png b/TMessagesProj/src/main/assets/emoji/0_1036.png index 961ae4a7697e73214efe9b8a8b282225e0f668b8..9a6ca2f1126aee9ce5ae611087f0368dc96317ed 100644 GIT binary patch delta 2580 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 Ef-}&)1poj5 diff --git a/TMessagesProj/src/main/assets/emoji/0_1037.png b/TMessagesProj/src/main/assets/emoji/0_1037.png index df0fba6996e04521a135b8441ed18060e8f3a3b0..1c95ebb8cf3f982fe2d09a28503c5df2360c83d6 100644 GIT binary patch delta 2548 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 KMNUMnLSTXdRpPn; delta 2924 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 IM6N<$f-~mx>Hq)$ delta 2960 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 GLSTYLPmeSJ diff --git a/TMessagesProj/src/main/assets/emoji/0_1039.png b/TMessagesProj/src/main/assets/emoji/0_1039.png index ccffef60bb8b72982292a396fb4026419372499a..1a4c9b82eeb7a04e26d498a8d55e5a5b1b3a50fb 100644 GIT binary patch delta 2393 zcmV-f38wbt6XX(*B!3D}OjJcja7;|6cQt`kAyzU~hF9g*r{&3=ytj$ayOcYTVByW9 z;LW4e#FzH&zDT@!;Le~naY@j~m`I#%@8Y!Qxs^kdVeaL%@7k}zm1!hTEj*1}gK$s9 zx{zI*WAo~{*P3)-m0KiHGeMYV$iI>D>bmK`oI;ag*qe2dp?_o8tA%KpZPCb^B2+O( znP%t0orSJq>A95T+pAuDKPX)|qM3m7>%6wEgTt_gwT)CooNq{=ay52LHiK6V<=xc8c{GWZbm_UOlFieNv5C zRhD3jrdoKjW`8hUEThDKRBtYd>C2q5XYj|Q`r*R$&#cnNm&vMwxubaX?Y#Tlz22yS z?ZTh=*|_Dij_0_P@yw~}y_wd}pW&{FzOsk+)3M&wq`Rn&uB3~Zi)yEqZvE}h=-;o< zpnLrC;Qsc;>*BGuv7g7ijpfCo)wPe!!KJf`Wc%dC$$!F=zLISG=ga;3`0nMk-qN(l z!LZ7+mh$Pj{Pe@Xwv@1%cch+-s$ME=b@t~JDVHJp1A=_YftJ& z*SCt&J8R2xd3mt$@cR1b=qNh*xO%v`JO^Tp27rT@9Imd9o^0ILh<77Y2f){i358zs z+y_GViUw&P^&1KR+(7;}1h((3G2xqJc;kEa!N(QhcE zsN>~eun-Jp`+b18DmZaj(p5?^jP1pRJDO{Kb8UIs$c2&4^iRwHb=n6LaDRXbpQ?do zRbq6M&l$w_>dGCD(G^{P^@7k?N#{+|J{)w?SayQ=WF8+5Y_rPaVNJ+luFfBuO$U;K^=eFdB?ThaW!O zxHxMM1`uBq(~^9ZLU7vp9e?#$M@Ztr0+Nc6-O*^Ydl5NvZwB_^Y~aL~#Se%B1VT@j z?kee1m=y%1M~cne-M{}x6@yqG5dBE;*on)#;XGf6fS@^Hc>!|4f)EB7-a&|*yni~aJ73CzAVXCd z40;lS)+z*n(TAXqF+8s$Q4rypmu=1U483APmQj#{%vm z921;MK3Lhg?mypbAIls?) zub0j3?*(8;5}vd>`}>_?Qpa(Lli6phKJaiqJ^EgiITwP%7k?Z`h!fc#-JY6*Ap!(( zvJ8VW3NB$j2J1j3l0_iQ{r*GrD&XPk$0W-k;mi?sPo=y2Sak_hf) z9u|HSMOHb!yzb*Twwb?p7|lL0k>36ECNyEPwgJfQdUxZJF;*5t zI3#zOm9s1aV;!lVY2<{mhAUD?gt3S3t`XlnAizM9D4jC}M#7)oG5{0z>(81rjo z3_T2lHBhBR#&Rg6Z5lYTnuVDL;6e8;jUa}GH?SivJi z%4O$DrKDuLbq3nBRaF&5Q8w@Iby=3x#t~N7Zc-@_oogLB;={mcMWrM{h_ZRM2bHvd z9-Xk2K#aTAx(tHg<}1W%G8jxIHnXvs*aNZwTn|?ELjdXc?>v742oyh%ALPn900000 LNkvXXu0mjf(%`dC delta 2523 zcmV<12_*L966F(+B!5FtOjJcja7>}+(V^zi)1M}! zoaN4%##j7=- z=Fgz!(AJE6p5@M_A1kRtH=|V`nnhN>s#naSJi3f9oNE(pyMLv`m^R0gBD4!L@DW9z z3^cD` zW4a78wS*yy&al%L;0!?QD_5_Vm*lS{ z$(%cM87YoY41cmBJh6yB|IaY`#VwSy5q6vfiYPvWn}MY2)T8OsqUqA7>C~X+(4*+l zrta9K>(-s)&4tmqsO#3H?bfI8*?h{f?YAhJ;K`5L!}Gr{s`A`&!K&M)BdhP(*Ct2O z3p>jwN6w=+d$yj@lp3~p6Tk{IuOdI6*1LYWkKHIsrGIx8q3+(6+{Jput-V}GyVH`p ziyiL5OsAe)`^Yc<(lFyFO^|F4!y!YUFEF){MEAZT?%v>_3MQPj>;wG? z5qE|n*c)6Zk#jgj%=2loRU)QP{=qLG{{8*YiGSey`}ubL@^1F~>C~E8%UGgq#QXVP z?y|`4=GWp)xW}{L%e#5V+sH7h>XSp}z1~^gxanQsSI7VW2KGrrK~#8Nt(E0>8%Y+$ z#bC>lt(at{#1to)NgSL^V3?M<5yZ@FW@cszGYrH2Y5S^WNOs*xj&SpCiNeCL7~|6B9+6O*Z^3xsF71(gC^HKz1dgR- zk?a9v^4u)-yAgB}%#0J*u9$pTikqFUP-qRA?_x?`&ax~`;k*r;U=?yiP=hlw%UD>k zCg;BZ73V54UXMY`z-Ee|DVnCC9CHehjeoJJa9BpH(Y*r5sL(g+^%bwgP*`A@Twb1} zU<1w@VZ>;IPMgXXJ+&~}LfIamQGe~~)u{jL5B4TVt)VP*=h9Lq&F*JmP$F*!4`>== z*!*lYPtfbHMg4yN?UN@z*v-5I!`R8WhYvd^_YrI%Uk41yJ_E;C3vECH)7W?o0e@}- zgR3f3>KE+D3+W)P40WJ zNR)iYIEL?LK@&8=Vie6-@-OQ3QUA`){GIvv=YbY3f_*Q07G@_Vq9;#2aX9R#6z(3uQWVajnK(G7nb4C1!E3^9YKL^K$hH zWCZOV{Sov$-2GGQ&zHmXH|3%?DkoD*xEMA?=(O2v-@@*1LEn{)OK0a6!wu7Q8rj>v zGKJ*|GsEKe3=llQ?|)$T^Rnk<53a0^hr{899=F^23HW%k)bdP&mYYO`XNf0eWe+-# zwiBz7@vfeb+iG;EvPExI#`({?M^>c6iM3Ei$NYT9eAS&RYl$rsB+kw3f}@K z{^|>xZN*dH6RLBEIwCC-Fr&kdLTh!~A*&GxZFah;^ocbe-rb33D^91g*ST=ojbsG?nBZvI zn=jCp^Jl+U@vK}vJ!5yMfROm**B@R00T4HDw1dC}PasK?S93Vx_b0ALY8yU><6(s= z+`kOmx^?S^7k_<#_$<>11c(9<6lnq}QqtDmp85LAgFwOs49japi8<>fPoOm zgb5(7lEV)QdiwDVBa+n^iVY49whUDbwfs8pk7C{XM$}Q>1PKT)*bq`72SQ9FtH}L|I}l6v{l_xS#A#0>RgRHyH?gs0O;cnc_$j5K<}-nvJ{yaPjy-z}MgJ zOA+q+0!cuCa>`AqAoxJ(Y@sN;q&XfKi$N6t0l?krIy}|V1!v4QHL$t) z$B#bx7yt*wcun4>JduF1kw=nb=0c& z0X`v!&~-t5*s46pS5O+%c30D7xVaFawo>Rc2}@Rjn@sr^r8bY$Gu2XCAv%I&nsSY< zNa|^5X&D%}AUc|$`eRaQLv8KAnPZ|O3lLowip~t5N)K_WXn43N9YpYY<%!|H6sLg* z22{UP9=il4(m|XMsb!+{5WItQU8JWI!TK~^DE}~fyf{5X#_`$X8R;R4-|PNAATFhe lP@jG8tWuOFqxhXo{0DAO=?a@DV734N002ovPDHLkV1hiV6yyK^ diff --git a/TMessagesProj/src/main/assets/emoji/0_104.png b/TMessagesProj/src/main/assets/emoji/0_104.png index 554a2ee476815253fc21629cfc8c60b8eb589f05..66ba2733987459a731445ce23899f4ade639938a 100644 GIT binary patch delta 1571 zcmV+;2Hg4d5VH)BBYyyRP)t-sM{rDDHwCtS%eE(g$rq!3rK1TP<9JMWea*J z3Z6L%c2^6MG74@X3Z6I%u|*4`JPW>13(8pwe<%voU<>DL3-ERe@rMiWe+%)B3-Xi; z@|g?UYzy(73-Rm=^70Gt#S8J;3-GQB@uUlHAPRmc3St`yT7UDCeEaj)Z%K3yqN4|YQz9jUVT|N&N+g{ILfz-D z9g&P0vpc8GoH?WZ%D1Sks_6`Lj8kn}{_?4n`-HR4h12L+F-VSw_H~P|s@KOVEVZ9> zT4gL1t+KqEfA%f%(ZijTX{67`|9+LRE$Nnaa(*o`e1A#37)wSasY+!XZP_kks2NGM zk?%ct{w?y+Q87dtnKE@Js>|8Yah#*}ck{Wo$eSLi%1FzQR*@7XnG#A{?(*b=`qD>? zsw9nw(o)q5DX7}gGnbF?^|z?|yOa#o$`Yi3h?FLJnVs~@D}efPp+=W-Zf7MFD3R)O zW6}#UKY#vOBKK=bswFTR?1vyQr4MpyLH%U5H)pFCshKo%i+?0#mP$ZDJyf|}8m0zps*~@KDe|pMYfBC^lsPJqs#SZ1+&8E#-Ep z1PUa&T&h8XZL6ZxQ7AkWv|!SK@w9;rS}KSE zY=5JO^@1YD|9l4u85Krt0CX6UbX@_tfEC64>H-v{AC6H~TEmXOSd#T|26pvGsUs9G zz++&d_lKuJ1P@PFfSix-XBsx!Ky3FEPXz-MnAIBlew{D82lN(NnY(=lyrAR&8Yn>6 z=h64)rLI7_2|$DX0R;sxnF!eRd6_*g^MAn(L4%!4fD*WYSyTWx@4EH8KX*IrgE^r< zQMeG8Cd{y#7U;Ph(=MR2IW;Z<<%2dUfK9)e4H-8k8o!RIKXr0-)Kj&nIIp5wW{_U94^5snWAbOMlN}1z<=@ zRg+rYZOe(LEf0UYZe}CG3_I~<$f)~qM{Yzai$GE$}#UtFkQ_<%6Bj%6$**o}0 z`lpKqt4YlQo+wj3iTRVsGYRS+OaGL`u_QeUh;AK@AAL1I;LC5azisf-AsTQl2j2c{ z`_1IfBv3#6K|%lW0C@Y;w|@57Z-3LxUy?xXU;N4D=9?BYy#FP)t-sM{rEuv`o#HC)u4Y;;drJl{3zoBHgcR+on?4mMi18 zj_kvS*_$gOA{Qzn8_Sm;=(%d(sAwD>8{@Kp@zIgSk{AE!e%_xs&6**|l^WoqNx+N} zz=b*G~77f9hIK`0?|KV%w!d1$qNG2W@&5|JIwla%yRN$&2=e$bOu~Xr^ zSG}D~Q${uN$$w#-fHc*uM0jIQa91B_R6ot7H~-*v%I zDcqh*|K3>t@r?iNc+-;-_|HRFLK!nFBmd`qm2evW?SrU(9DZOMxu=w#j(z^uO#kNxf#hQWRD z!kF1bG5+=IUR-3DWn4Co^ED%g@jcvEm^LBC3Lq#VFt43vfMa?>C=dXI_}+w=20??< z2ookn?8^c}D^Oy|l%PH>QV@itdqr&1n4$<^5PxymWMZ!eLr#bQKUS;Qm5MJ;0sDwcrQ38fPLWt#u!rT}q#UX$| ziHtD_L)iUsi5eL%ImwCNzp)qRo|%0{(jpZ=Kp?~+fKT)&hXz566Jki*A0{oFtC4^o z1O!szoDiP|**!d@L}o}-B5AXa;-nPlhIL1|`&31p7Z^Gds2rXDk@+`~pZ1sGd zDg=OFEGKJ}NQBD|2I`KK!-+sZ)4U1!4n!hREXQJZPcjn&L0jZlR?mbowLIS%5uQwoPge2X zY_WVDM1>M7cSk{qN;V5Z33)u8b)8p+1YTzpzU9?4EqIL<5J21?#v+J>pMTEcwCSPg z>Y-4x{vD||Jt6(n!(twdahb)dVtW>I-L^IDb+m9CIo6^ zEA4i_-}hmj&Y!0_AxSEPT&|Afs#(f}>b(+aQR?X+w5FzIExEdmq*PVCl2+|M5%!5F zC#o$(*C8OaCVprqZC<>a?tFjWnwliU+>@!d z$`w~Gm&1`rWMgBavQZgD*N3mjI<6KY;cyr?3)02^KTJNEBt0fyzMQhgqJrS_`NG8_ zWkyM0+aQsR2n__EPY|N`rA~c#Nd*ujM@7EmPt(9RmpClNvqdI8IQLERvT`G2JUE zjTIV>OG}vGshp>mRV*AwUH86^ErLLNT{f9ydpEbG4&DxpQzJ4-qu05W$z{cdJEKvn z?Ji+=4GckML45i0`SYKHeE$69r^pawfio$AtVEBGIW!kH*?;8O%}uBD{r2Vt5(4Dr z=JtE3^yM}WK_tR)Y|(a~a9Cla(`iA4aoa)Re17xnOeQ(o+|1|mNh~MXGnGrHQ34;+ z2XRge3{I8VhK&825QYH)rXeR~B5dIpcGGX@Ft&&xp0cO_;ZBH=Y>0+{L72s9g+UNT z$tO1-68TL90DloCNC$Ic(FH`3Fc6&NK9O(W5YpDxvCB#Y^VnAQUBr+$MmfvhorSD0 zoFr`(T>C4S-e#<4Iy zzwd%#gv?-m1Uw#@g;Ed;$o}m7_=^$nXk_O3JQQSh-lW0fVspP3AIJ9b7bZh|d=;nL e?L>k9ME(Nr{LSneS4#r`00008 zJdRvUnPxR}Oxv%AH-}mD?7NwhSwf3gJ&<4@PceaML+<6Z=6~I--m{G&R53=GX2!UR zaEe{n#h8VzV!e1yK9FEven8sNp(tHA*v_BR%A3&0q~E)gx_C~ccsva#8p5xJ#-DP% zwTVZba73GLDq}u0e^fPiPBC;#N}_ZcQ80FzR#AylEp0_Tm18)ES~!hiYoTIbj!WE!B_we7DkZ_NMa4sVklIFlfR5U&s0L7V3anGrM*aQ+7YhFT{^;i)6EW;Eo^R%fZfWL$#@)!YR^#W>SZ*hX zdAR7Q*O9TFjpvz1*r~ns$hGUL&N=AN$7$q*LjV8Hmv~U*97<3$G5rL)b}gl+V-Rs5c>&8Y%Ai@Pyu)7zYqx0*dY>I9$HR7jwCsU;LF` zVr3sMip9y~Z{E#DN@Y)U-8P}f6UT@Ma)11&U3{@>D7&GX5YtXGF2gX@Qh{z4sMFJQ zI|r6rv6w3|X)ztTp`t4k->2A6D3oRjX*N|zRZ~>?k5})m**4>~3#nA0z)+#d+ZHGQ8(#k7AmM}m3no`)Y-ym!Sk5(HTj73Rw)7xL|0_5^K7GC_F-r)-ED}NV^eINN_A5qs?kk>HJ>ka#X5{>G#c%% zNU=WxMBP>-Ez4zvM%GEOY)a!ei{oU$;HvZpaKBxVB1mqiTPRz)1n^W- zIXluIA;jHPL;Y#w(wy16EN8KX)PLD*3NKYvB@N?j`LZedF_L#G!r?$H>4(s?N~Th& z%%;TPQz2-YrZ-&I{e3GCUT)YsJPAH^MNUAHgtOhOGbJH>%}mAJY{!(4(uJ8l-G6cz zT&j4YsxOnGXA8*5dilXw*?~@c#Z2v#2WNRtc1+z9>6emRYbLu#2q761ts(p7&0p`) zFsDud^=eoq=gcsNWnFO)dVdnWYpM_f36`Qct&2|SZRMgxMglo1t*d(JZRR4QVc9Yf zI=Xu?Vu#2i3WO>xprZN<0RvGpaLh>v6tbzAdn*=v_Yf2^Mvf!FN`hfl$z;fi!9gMq zTaXoO?ydYO**z3wOVAJ~0J4^D1`K4$!GSbI78Ee7Bzma$ojATiGJn-f#z87U0tNJ; z?1uwuIO$lj`6AQDA43|sRR(1xj4b!K~=BKDka z=rSg)kRT3L1Wo$(2@qt9uvZpg%;A>34C zMX}^2A_h~iIgb$&Yk!|b>?E1wbmA~kc5v%6XgV4gEZw7%iS7IR*$h67*s_4JsWr=k z*RKa<3=yy*8^0y?A;Y~0e;d(d1ti!s;SFFxvGgBe@P&789z=8tB!VK##06Jd|JmQl zO&o>|l26E%Z9s+%d02`Vx^4N`x)J&1o4}@g_u(=UF$^6r41c5a;m6Gt|5QQ;y=lWx z9Ke?Y>87Bade|XERe=krLYsQq0b@JZj$?-;gaUzHci{u{)GtD{681&+Ub0C$gsOXo zNY9Rb^8Y`aZK~6!W)7!n<9z==;L063^SSdhiZe%C~)81=O7r~kDS?ThD!D0 z=VlH7Y|iL@7=OGYj(dA|%{W&I2t-~UpAf)NigWhu?)GivbKpxM#5$vt)yUj=tQvtc zslQ(i(C zA-NEoX`P+{K!R)y^*gOZKjzkuKg1%AW2#Ca3!5ZL={N=g5)$MY^#*Oil^;=V&_H61 z1XpbTaeptA;(rOO=|QtNYE3fmB28BhkQj;c!ko`ZB6i1De1|cxgO0*V(G|jS1?vBSorgFVr*8~X5Weh~Gt&Dy{GzJENl~TDcC=3M2Od~Xe@3s(Q&%3$# x0yF92c(7i>OuG2J@x1zU(uE&9*#04Y12*S7G!QD%%-;Y2002ovPDHLkV1mA5ie>-+ delta 2420 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 RZU6uP002ovPDHLkV1nCoYDNG6 delta 2337 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 Hu0mjfJ>X4X delta 2292 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 Z0C!EgzYy**RIdO4002ovPDHLkV1nfwIRO9w delta 2261 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1044.png b/TMessagesProj/src/main/assets/emoji/0_1044.png index 89ebc459d5e08e2456b50c43be1185f7050b5bb8..2ec6461c022456a01e077998c76173e2c2732b97 100644 GIT binary patch delta 2828 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⋘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 Ef?5ANB>(^b delta 2017 zcmV<72Ojv674Hv_B!6pAOjJcja7>QYzMSRGYqc<;;>e-s(wgANmcE#s<;|n%)0bXF zqUqD1=+d9((4FSbf`UDv=+dI;(t&C-oaN2Cb55h$z^!pnp61P<=Fn%6Dxl}ktFMcX zSU{$0PKs4Mk6JpecU5bnEu&~ie~Kida#gT>Szeqfs#Xqbm47XX(z|G`E~Rl%fw@#x ziz0lwLyW_kRC^bXzGRDCF^{r~likItZ&8GqIbe?(*h~Pcqk@^<$brzfd$ysV=Fp^P zOQPt~r0dnE@Y=b7U8CvKrta9OZBev%Se@g{l36~7(z}OLH+jdesOr_G=+bb&sHE)I zlG?+o@!fKHEPt5a$brqZvT#tFUqyqI3ayT3e3@{Ro_VFps-=WnYH%lqn*gis*?Nlx zcU&fiV+e+kIE$eIb+?s>uY|jpai-fU=v+n>Kz5@zk3;AG90eeu!p z8FZg{?|;3LW^g=KgRY@LM?V^gcm%-{c|2q=!b_^CsFHu=k%S??Br+BJkMhBVc~wwE zg)*ebEx_&d4syRoa7RQ{5lA?}sD3vixRN~Y84Lf8DQ_|-iUJZ83K4R=mpKz8HK$5B zPw)pwXmn*X6uN6~$fH6q5&!}M7YyMN0Zf=V^?yEObarWJap}cus7r|P($UGu5hAk{ zVnp?j0JmRadBIgx^~c;@!iQ%AL`$coo-j&5R%Ggk^$0}j4J8?Jyj&%D zTwGqBoxN~_hXQYit}Ku69TNx{4FyKFCjQ;0;Z9E&g?I5L`b1OXLNgNm`*RtEHM9Ut#w|6{J$AxmsP=5@k zwSO*~SEhXa;cbp!4N{9t-K-yvL(_yXbo&185fvh4267b)E0t}WV=Qaaqi+scNHGk+ zOUD>jv~fw|sfQmK0^NVqhk%TdGnLKmH)l+HYI=QJ9*-kJmkzOQ*HtO`lM~Min~en{ z3Ni8)AeuK(6Km1+s4kBq1^DV=)qloE;#>DmPosdqRvkddp8+oFmFT*u;p_EntjjHg zpqQFjZTW|KoN!#sqtc2926Rn9C97G{>|zw#>&0sm>xXekinmSkQ_%gu*&g)d$kOlh zwxw69+r{GcbrA*|7_DQyY9_qDctC{xg2eKX;`ItP0kK{ry0SH0)~cqq_J0?cco-5J z<8x|G%mG2GR-@}oyU{BX0|6hT%7227hsAlr0Z;sx5ODK`5sJG9jVs$UtIbr($~#?- zU+T$1U9V_ZJ4iJcp}3pPHf+1vESD{3zEq0+5-?M#R4{JuLmUAR1pL3>Xr?H^5cr{o z0K=0rdZp5?*AHN6Wp9WDAb$V?AgQv`Nf0RQ=~)kMcs`-)+ITBoqN}q31co@sf>O>r z2wY?~lRf$}zmR|mXrClhDmlxk)P8h(`x+<&ks=7oNeSt6x)AJ91>Y2Gs+oAnvMeAp zKYxCTv1!BNntNlVQYk1V)DmR?vC02D70x#?F`sy2mCFFg0)Yxv*nd^@)mw`pmg$o6{l3jz;@%vxi-?C1wE74qTgL|=&4j>&hE+~X0G8ur0s1pxgZNDloWG+&?BE2*U|EG29;_H1mHza0~K+qfc?6-!}0NIZ^Tsstv5P00000NkvXXu0mjfBnjF7 diff --git a/TMessagesProj/src/main/assets/emoji/0_1049.png b/TMessagesProj/src/main/assets/emoji/0_1049.png index 4562ee82fef950f98999f400e15f88185fa9a65d..f1485300f774a635b4a469257a7b0b869a1c646b 100644 GIT binary patch delta 2449 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 P015yANkvXXu0mjfwd|XA delta 1949 zcmV;O2V(e}6RQu9B!5s)OjJcja7>=&&}_6YbwD4Y=+dI&$DZZQhn{t#>C>Fz%An`b zqUq9|<;{U!DQ-C(py<(^<<6bv&u>>Co#oA;=+a`ME1>4kZ#o`mj4fX<7l)BCflnrQ zLLit$7_U$VVWKNyG8u@`x?YJNm708YX)0rwD0#R*fqF1ii+>`JzGiiWL3cbHbGtc^ zw{M1-TZOKBiMfr3z>|@QXO-B$adZ->@7bZ}(4*(!*_(se%}p5x4^^4()F z7lueAZa5l!KO2o!FMUQPpVzyKP%DeozNqTei=Y5=!>okQxRcw&gqHw)$+2;HELbWM za#b6e-^hQPc7KIwLv?@$hHMO%Z$yDw6rjVQdWU3eW+H2GDV&2_!d3@=j|F2%8GD5- zf3t^gx}Un+oSd+WgPtRkPbHh1Y>2_0eV0t-(0QU>29CLBomL}x$2n$%I^I`uLI3~& zHFQ!=Qvg}~%-<0u2<0ad;a~^%BTE7_WO~J z+i}F{=@u%Q>85otdBSyKnTy%wrYu`9jPr3MW_@vx&z;Vp$#`NkSSMek36o zh5dpg2!DbWeVmU7j|4%Y(h^fZFdU9?KL-eAB~ict5Xc{j1}VW8<#{%j`59B;oG3{c zQyYRH@@^VjL`I^BkjO^9g3RUL@4?Y=8M(J-PM4B`}iDK7T&L5|tpKl`lv|6d@#|0NAF1$)%b1VO_j%D8o)X}qLJ@FwSy1d-kX0!6%`1P#j= z6BqK-gvf@bh^b`4z=+R6uK5>J6Z6lZxL6KJ7*Z%-P0G^L1xnD4l24S11s5TUDC%RL z5r4$R=GdP10|Gn%94Zid1w>cVmJ)?{QE-JZEyX=Jd;}23ecN)1$Mes*U={&E1p@9B zM2XO_EQr&ynMJoyS_*LkK<(p;j&WHW_4h}+0WKneRMNF>uPaLQ>rigmy)X~Ys5ci+ zI2eog?@_;hxxYWMtrb`TWECh_?U6NZ5P$dH(+Ha8Gwq5S+%?&5|7jbYXJFLbr~-Na z+yw|C_T77PAZ+S_hDsUT`i@Zq*~ag0d8iW*s;Wv8%SM`8b>=@ah(*K&rO?g_YN>SH zF_gAa>}+R6vPC6Xlt-3*zJb9*Z*}%e#oBFkOylw#Ix0>a-JC>|9utns zu%bv3!K!;i>!qHh9Kr5RtF^0}#($`wX$4!?Kfz4#R4Bp%<8G*37cKp$)#~iFTCJnD zVvHu|j;;s76yObsVvWu)tJhcV$WnB3bB}6i zv#l$NshhoKZT-RfhYLqiY~dU{m`d+v*Cn);PIlUDT{m}{&0768AM>En+kbrn2u`oL zLlMU}r`4UKHV|sHQoY;FJOqd@Tb5-i{gZ072M7oQ5T|fTfKUR0iuoVul8t~ODCrQ0Rlyoz3*dgZgs_QoQ+ALTQ60?1noy_Y3Za2jAp400)&jB9(`F| z3A|R6*Pk@pbzhN_&7-4TQhx^^;3IKC2y(exMhUMJ7WKu&<=?ucQmt8SZX6sKifIDo zc&=Tsr7;*B9ySgKgY8uY7!U;A4wB1WO<_VTA`80RKN^)vqj3oTD~-cE z9ZML300I^Esw62BL|G_Y5Co_KTAHKy9N_N|vd=3DRCX&RCMqrfNZWTmw8{kX03xBe zE7Xh1T^*H+_jgG}cz-nYfjtmhN&^6x7>o}qmBH8;4l9j!vHP=LyY<0`e~dV{9HlcH z!)@ja58rb4^G-oAAe7>~3ZaOCT`ZbP(Y9^FJbuaCR}hLpaI}()hkW$-P7J%~0HJ6o z`m4~_mrj;dSvq#S&xN)D2)LCA;b<%PO}U{YU_BL~2&-r~hJWFhdf-`}`9%d&f+$9} zUmJ?zz|3Au|000Kl}p6pWaR65yB%j9CFm9)VEVN6z#Q{9QN&7mQ3-G}A)c<9$_g_J zVlf>z&8Lq?EGTAxSqLm}vmlfOhJ!3;LXa9}M8s!A#AkQ0;=rMrNpk^XRz!Na_&-2! j@nW1~W@My)+7`q=$`!qJu~bC~00000NkvXXu0mjfuMnO~ diff --git a/TMessagesProj/src/main/assets/emoji/0_105.png b/TMessagesProj/src/main/assets/emoji/0_105.png index 971707caa1cad208100e9b404022343ed3c821a0..bfc26e726bde8177a8e20792f78acf15f649cbc3 100644 GIT binary patch delta 2091 zcmV+`2-NqI6}J$OBYy!?P)t-sM{rE!zFXItC+*9b)|Dy#;cC&GI(uR~-K}TXrdHga zIoq8tAsiRip*Ho|lk(G(#*-PxlNjQtSiOrQRV~Dk7QBcMQa&RsCLZ(3QqPFdt(p5w~GBqtE=etVevoF1ZDEQE0;Y|Lua~(!SEhyse;;|MryW-q!#3jct|H z-2eapC3I3wQvm+%L;n3h3>YrH+9*_qYp&vIXWz|x{C}9JNud14-$=@Tl#ZT~>wi}O z00wSJL_t(|UftJaf7?nL1@PE01>B@<5Q=xjY-VO=hdJfmyWb!8%*b9luG-|~{`M%Z zBF#VN8B4aa^uLys9hdvrmwGLUkAi*E>v;y?`uI}Vwz|;0&G8(!z4HX(_HObV&+{&; zaxcYjSbyZX?bq%6y6T=r57ZmaSb`K8i9J%aMnBTD=ynOi6CxY+-cer8& zcy{ap4}n}J9$FBuLEtPcBD}Qd>Dm^|3d9gMEr`EBAQxs4VRK8PrZtco7-4DK z>VMXfvf&&A7;&@2=f?)!4no`n!(nOD>KUnvLEjA#?&D6A0Pr^s2(*SX9Vf;O3{m>a zf>_B$eK>0hrd}&WpIGPQOwDfEn826h!>qM_MG<&N~aj z{pKbC!bb@Rw8f0Lr7emeNR5Qe>RDdSC4WHpDDk!3rp8PF5or(7@uJUn4k3TJVL|LC z@`)SPS1iVz&aN!?hyeru6~46_a>GUlA6n$|Z#=)22<9im$=9Z=2IS1=TNntL;`Y|r zV8(Kb5G)}=!C!0a=R^4fONgSgC6|86t=qYre#yxGsw%hRq(uTm{*8M<@VpI8iGP!U zqB4xi3}(RT>6f0$D2#j+_pvN{2_mE~Zm2hpM4v{8Ql!y;`{^e zvKP2o<%*=4%#_=0Aeg6FGOCC{35-zAWXc&J6-4A>j`^<hloPXxE?=&au#RZyc$LJ693t5oWiFN0>v|Lsue_4|FaST_y#()x$q zD5fE)R4N*c24~3yYqj81z!{uPr9vSM5wd6hI#^#aiGzccwc~;y2!EOu3Z+~e>jwvJa}L~Eg&0SS(b{=>i5N9TRs#<|$Hs8@^Wot;&5wtNpTnV1eHda8 zrpDpASYg%k>qqLusK6MGQCLy%&eNa=!zhZP;@7G=73?mHPk(khjC#G!)dI3Vfb|R$ zfMEs*m{LOx)VO*bg2VDlwrgTYHSC8;Aae$a_-hgoVh(JCrLi_KxURB5ARw47Dv%EL z-+$3xb->7G>)e$eMqqvrjOM@M>RAYmH7Z!gvv=o+!N|sv-2i&b095LBq-?#;JMLCj zmi`p)+dGF@B!6l6nMq*zjigYgz}r_({RijSzrN#Ph`i8g8l{pScV*XTmIYp{*By7) z`>60_mfueh(V?Yuy{+ph&B2SJ$lqOWp~7?G-q@lDl({$nyzneNHy(mGpiIM4fX?uI znwZCk!2hUd!bN&B+{sTIF VljsLk^*;ar002ovPDHLkV1j;*2Fm~d delta 2699 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 delta 2073 zcmV+!2d6s8c6B!7KSOjJcja7=Z>texb|py$w>-@TpP!C6rwe4&1Z(7BoA&!g(p zhLkU%=+d3#&z|Pbpy|<_<<6t&(=sC(qv_J4>C&X?)M>0QYiJmt<g{W|>V1WvMM(nkibCC?ysRX|gYVvSYh( zCwjv|T4Yvx#I4Io0Hy5Kr|;OJ=g~7C7^LddpXJV~@!O;6(?>BWC>9VwD(-{}(|>SxEPu?ijn}^*4+(h3uYi*ScYiK&y`(}m6m)?HPD2)SqkdmiLT!q4 zWN0d^_TPt_0F0pkYHuipu7_>4F<)33t>nCv!>D9!SaM`Za=$cKFARu#Sjtuhd(1nP z!iIvSXmOKPo1AaRzi4xQXusBtb~+Bp(}AOB2lLf}c7Mk;bAcNnw&Ixp002XDQchC< z{$6+*Gam^45cB=dg;K(m>Nq9fxcvUCLu3B@o`2!~um0=(a{g*rS;+qUzuKCa_qcoD zx!wMfr`zz|kVD_MvuLTXE+zl~1{Fy}K~#8NrI+Pnl#x&#FUCc4}J#>z;1 z^=pVAd>O+SLL!j}_)rvuASJ>HaT)P!P-xZj0DrLdYWvmNn)hK0BqI_i1}O@(#9f4O z*OiFHkW098u>LxcSV{c6z1Ev$R77XL{c$FVpM^%)+87-{pF1N+CUJ)4THpRLadLHa zlK8pn!!wQ$`R%X2{rtj zbbd{^36N(DD_k%oUav@y4vzn_wbf3kx__E#uRQbk$ALg3BqDKc3X6yhRpBPM+*s@h z>e)p^vOl#|RaN!!=B8QQ@kW6l0va%YU>)&s_`3*C=spANu}mZpzrVb>RGT+VmF`Xi z5H|sEWzIqzAmXv!^Ma4HCqxK0Bax|#%ccs_>rbaKhbxwZ@Xe)#5#Jt>d&_oO7Ju(a z;tb0)8wS(^BKgY*q=$%PNfJ80)-6oHtFroF{|8GJ8r5y#)yQTrX(H!xIi0O$-yB2msg` zvdor2tL3&)&t{LPW~7ey_s>&>!V5Q8u#?|443Tv+Rd7W$v}(DWOlGs?(|-chQ*(2= zR(SHr`Qwko1Gv-A{?rqL7OLg!Q5ICL0z;<|#OA*qVZg&Y8X_1W83=}Ew6jO;BT%rc z6)2?|ZRK(~m+AS z-yxKP4L}sZLY^ZOvT7TqcXC5F7U!lc3HAt>VD-#I@ECX%CwRy+6B#^WGndKT9fKP5 z#Xhmje9l?iY*(wNkOV`3Cub2{KoTUANy~A;rioc?c6MjV^7(u~_?a#@ z`arqj`G@kt!ouys(w|GWOG{q=55WCQ;65U@2p7xT%=_}kwOVaqp$4Cq3orle@cfYX z`JfF(fHX4lxb0BJ;eRKJWSY6)!QnxvRw}`*w)d+54AV3TFHf_}ZYXdv$!UOC(!0_j zAWCot(pu+aClcXZaAjOJh@k-gUNON0LmV7}f?h|5!40H4pLEzR3a|i@-!j5MhfvxU zdT%*$&xS1`EHgry1P?i)#1T*L!iGM17=UowAg1LsNPb(Z*MANVYjyoJd3X>Uy8p(< z8Gw)?k07els3+^Xsv4)I=feHGqZ!PNggmy5q`{?ZrBqd;DoCgQS$jD4)iErmvE;IS zzh+%#dxT2t()~gKD#T z>;LcTzJFXyLNgAxcM*$7!A00000NkvXXu0mjf Dg9Pn) diff --git a/TMessagesProj/src/main/assets/emoji/0_1051.png b/TMessagesProj/src/main/assets/emoji/0_1051.png index 504192bbfdd22093d77885a610cad886253e3d0b..0b290daaa998cb2c6435b2e0d72f66da1c1e9561 100644 GIT binary patch delta 2240 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 Hu0mjfK%+5U diff --git a/TMessagesProj/src/main/assets/emoji/0_1052.png b/TMessagesProj/src/main/assets/emoji/0_1052.png index b67c531ead4d9beb1e8685a3ebe32ef1e9a08cba..ed1565e61d1413971d9e546c37554b845a3a5e98 100644 GIT binary patch delta 2258 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 delta 2111 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 M07*qoM6N<$g6wm~AOHXW delta 2108 zcmV-C2*dZT5XcaaBYy#yP)t-sM{rD{>C?fTZlCASrQ^z^>eS%0jhD%|oa4-#X~)gi@N8wQ@+$m1~4yFQ4SiLVt;hmX0?`l#r9Xq`<(H@7bv8)uZXtqUh40=Fptu%&YL*)t`6dy_dav zQH|8S&5~)P>wnbRs)BUGtdZKnc}WC=l>(;d(wN=F<;tRXi3NbmvxLyO=+Ucu#;?zq zZ<1UjZNI0;hFr6AORH)=wbr)8v5(Wfnr}h^a#q*U4^^o^oS|faK0< z`rMaPtDcX%YlOOarGhlO9I%D}002dFQchC<*d|yL@BIiPG?M=14uVCdX}-&Z{r+^j z{@<%%L6dPKOv;Grq5JWp!s`3-)b3H|%Fo!x&p&$YnCI%U=)uy+lf2mb3H3Sq000IW zNkl6V+ zPk+ex_@Xn&Ay~5e;rHKP=dK7eO!tAUYeN87oJr6@JemT55=&H=QD6kp>kl8U2^0-} zK}f{G0rJgVoFc@@`T6+xV-AE7#gb$R@gI-*>wSb7N(h$V0D=f1^TycYV}1bQ?DXi! z{xtR254%v{9mzuI%)pncQPeroU=#@?0Dk}_0Z0}G;!9IgZ+ex;QQ`d4Q;rK`rz4Wy z==rSWN_kox7(`}Div+hJA+9HQGbvn zEPp(N3PcF_t^^qN=Y~KHQO>7NwThnhhiH;7A1%p+euX6<^WZnn2FnU={`cK7x=s;+Ou{fujZaSs?|9Dj5xM%QlE zGZ}cnpH>aVai})+>09o7Ktu&uBzwC(wx$CC9jKvd1-q%6>q~y-7G!v26=5V00iIdk zqRDKpwDlTvXdb6Zf4cSehYL;2cy>EPFfX>ZoNOPQx7)hj?53*a^sheV)_CW88mpSM z^#&m_AZ#BrE?Vtow^S+{X@7Zj_*Q^rSzE0|)*B~4kZEjhziBj1&QGf)!${|4arF;- zaP!lwZAT*AWB6*FkrEI>oHSCYvOx)nkGjr-^FREXW=A$U`Fy&ZN~I3!^{u)?q#BJz z)kvq)c_4DisLQ!LoWHBqRCQxd&gYF%Ds`f(?{u|Q2jZ-hYQQKBB7cZH&nt14DI}L$ z%fC#orVXQ9N>x)oj@4{Uv(;96(VqyrBLe0?jiVyn$(-XSnbWkQHNi892vX6|PY$|ZQ@%WQUkpE6_L#e(0L>4`!KhkzPx88%>K zX`^iXJDV*Q-xiDD?0=7Wnb7wJ5#$`7qk(C-gnNN3rV z{S)_8bCOxuOvVNxk__i(21rshXPLpWpw^ND5=pf-Xf=y__NI3*A$C{08yk%9P7hA7 mg+U2!UYlnI4Cnpk68{B@YA#1{2eKjn0000gwxo4FY6jWZBr;j1>kl z4GVWjN4B=P%*xA!5L2mfiTeBdp9oXY3vUxf!ed? z8GgGe000K!NklDm*WOuv|>Yl+g|L26Cv*;$qgVC0DHTFv&mt8)C$Hs+QYXXd1cY3gxQ=^dkb zUOfnxnDZ<#UE4ea01zyRx(A>FTO6ly?H!0}gHp3+Tb}FM`vBlsQc6lL4}|x*`a+P` zr~8R65P$cU8I_jjfda|5he*n~XrAtSd-A$4>gSgHwx6=bC{319P%fpnk0s%o#lax$ zJ#o#gZb5vO{JbbZz2yWcA&`)V2*n|aa?#k;IQ>TD`7t5BeX4J9Ohwj{h#>gX2-^nhPnc)|l>rzJW+9@#5raH)!s#RYr!i{Reibez(9=Tgcf|x(0}Fe1%d(LN6~<3f)l|l04CWX`6Y)coD(fy zhcZ$th#E7v-!T`_m{BS-N~l!;1tJ9|f>JW~7v>^B2CfuD1v|>`*tR#vKuiRIDa@A! z3}aggV<6Blbj?Kv8~ThZt}+hkM6N3_(S#y0j-h;EOeS#_Coakf#gJ!rQsy-41%FX* zIxLOK9^Vp#BuPwVoE1hAn}G47|txp;X;DCxzBU=S$k;&?P^4gBYu z9g$6MdaZsCtrD^$Qa?1D_Q{J>3@7xXu|bp)F5|svZ}W3BN_OiRPj6P6&FbD`I49@B4cK#-dDR*0`??GnZRgf>V{m zHVEbMcravx4sM^ko6{1Hg86s=Na)(GYgv|O=_lB*5AI+-^HCR;@_pkXjQkl8P{i^) zP;A@tET{m&Ebw_Dywjr``GH0T3s*`gVM#AeKPnW4MrOTUGO=wNPW=1l!9WXP`{YBZ zx62U}2|BRp{jxV5jel0l=NSNgc=_>XaBcXV2eW((5ieCsMflTRun}+ z0tN1StDBoqlKPQ9ZBT5nd<=?H$7>&>qP-ae{`()&$noO8)RKqUV0+q2uBn%JywUlOGKhH%=nq)!SR8DNiaGc><6Wcrhp*Cxf9l^SW3yXrk!Sp5@J>>C>0s$$iMNjIXAm>C>BO zMw{f#N|%#{SV5rZ(U;)LpWe)&<;|n&)Su_ipytn<=+K|((xd9rm*L8w=h2|&(T`h1 zLWqlyTt%bl)2nn>gjPRtWl^7ZUqy$Cd~al5KPj+)Uu8lmuz!_VUqvE)V>q{fVK{Vr znP^Z#iHdcIB#MtUvzTX9o0*iPjESX+s;7^P)V)%gmzUtlmEOmipHwkuc4AHvVm>RI zaaV%SxTcmupWMYeUt*)2gs1P>qUh16>(;CB+o0vop5n@&X;6}1M{~ogwtZi|h-Gg^ zGNb9!r0dmrNPhvR>C}qUy_ep`k=eq9&$n+u0(*=Gu69|gJZ^=l}o)L`g(JRCwB@ zmWNkbS$`155u^%;SP<+z8jUe(l18(&E0>ir>p=9$$xI{M<(tfnbw19x`DQ8=0yL1vuL zYeocs-y+)F-*roPVYOPnSgp@)d^lWAM4f&9dhDd`%Z46mppD5p>SDF$Z|Ft9~sm`o!9}#`YOq3wB^NK`|s=> zGitgZ3{rD2B2LRf(k8E1hPG<(isSHTT1i){EJahpcenPS4j5Rf8K{-wf=2OVnor66 z!qi6jf`cMpXsenN;;9RS^w`5)27maVh=>o06~cvrMj#x&Q-o9@nwPKlYk1*orEMi!!1=oO-XqmcHCG+p3KSPMX43J3 zznBvI(YzoXR%$E@btuJ($8BnLCh8E4JAwfK3I*4tRKZ^m3VweyX_NLVTYpV4pLahZt;b#7}BDQ?UA{dqsAl+4Ndl`3CUR{9>fqK3^Bqt>&Y>C=22h%LLlgWqxfHGhKGoBXnvNk`F6H=+oty(A)##_Y33x76V$phj9K8k81 zI4TgJ8Q1-YsmZzIobAJ(pz@Kk5C{m+*Vy*%?kUl8OYh4Fae++)0K({7 zudp86v2ZXF{ItCt+ke~J!<^kev>L<9ph^e?U>gMjjH~6O48XO5PtM5h4j|6YW7|7B z+t0NcV1&XUiVAqa18``MqtzzSF%Us!eJb(xTD6J7gOaP19 zg;XdcMo3Qxg8Zn`GlT)6+%39kXJ8ae#Ey4&VtYqNr>9^-yJopP>w!TadP8djh`A6X zzFt4dCKA$d?2YNilg&<(89{bat3n9ESCJC3kOM+ODz2{GiEuzM3@oj|mMaT;44|rf zn3aH#mHFgq_kYiq&TAd_z|qyM!?mJKxRRx8R+e(gyH&@3qXq%nQZ77UOj^oHk}Smq zWnppYzMg3wki+h!k!K|?@wpUlQ|6{L|6g6h14F%Ike*bOWNESu0&!^>J zJ}D>L+T4MDe`G8s`uqEj6b0()>u+suUk?V9l$LxD1vd^CWn^Sa6AjJE%crEJcq1U1 zDjmGLz=IRMv)LzyH&?2LK6bSCV&q=br_#z`}gh zJwpy~^8b)ptwE{%&%>*g*6BsLT)sFhREmv12dd4}vVSsyz;T=)Fid{YD*hqRDyzVm z<#7U27XAdO)Vbjd6JSWM#2}>Hti9X$kljYB+WRCk>6x zCd5>%bpVR#i2U3L4n(moxwCXkn#)AVX4Ej1QXDJ!kgMtoL0vWW9i0LJBX@EgYl4Q6^UvX&ei7RFPGbgSTKR*<~xUrcr zCM8I9h-5@+SJtyK8dqGM9~1KGV=cumxg0JP0HB~@TuQFPP=7MU53}*{N*)szT!z~( z3DN}4#~naKVFLqTpbrLu5e6VRJ56f%{8#u3F@G9uKYec0P9-xPUU6HM-Fkh&i7*8s5nL%{W>K6090&qDFBVWa z-XKKm5pg?72rdvLU27VLkj5Di`g@#v9)B5J;1N*~cI>Uq@Y&4>kSZIW$5adj5&=_x zWp;gLV=*U+mlpHZO2tzoVkQMJZoWj6Ve*V%(Uhz18m)RGC#rP|*Ivv)fF_s#y=Mlw zVH(3(r=vtl5Tv$SVST9OMD2qmR<~W55s2e)hpUcrFoJQ%!QqnID5WMC_q(=LIDa`x z!Lqxz>x7WX5wi_0O)K8*>o7NgGq$2mM+l|~0kIcbR^^zeSXS)a#(Ktyz;VZ-%)c*F z!W_1N&ZE0ACqfc|D_>fd)nlSjx7hl2l@L6D@iL0+xxW~sWth7`7)4S4VVMw8*wSC2 zb^7v-P|%a{Jhc--3M!s#x z^%RM)ASom4-mNB-ySq>mihm1R6J18D@m4CAT_2E$DAtDRwC_k*EtavV1+X-+iZ9=L zZflCQ4?@h{kv7z95W15|cQIC4n7eZ!VA~aycOTjc@a&^-U2P~8>^S3+Er%)*+({(1 zYiyppn?@mi_NVTIkT`v?p_rt_BbSJ2-(xMB%J+@akZvavZH%NOg@3}OoV!}+`(B(0 z@7K}2_53~=lUcx-jx>jNzb)hjA=~9<*`a6O&T_M%l}Uu=$#13B?B41^*1OH3z1Xw| zgT>~d-zVX^^83%=*JOC>-J(5MEC;_Q>pYw z1Q`#dr>79fNK-Dp-Nl766M_+eIK8=fX!j_)(oHF{a{}J}vwyd^sd!cdpdH1FwQP|RVA~)HZ|uIDvvij~CLSJ1_@;@p6VL>{ z-boQS2U`H7LT5^R{dRwL|LvP5EE}}}XxRX--$yFIB^8N#!Ln20{y?O&kr4K)lTlz& z_bIYAh$v}-k`bAKmH-f~S9jhrrCzV=_cW`29CCJ@ewAKBM?Rnb0SkhEW=B3bvj6}9 M07*qoM6N<$f;~u^#Q*>R delta 2142 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1056.png b/TMessagesProj/src/main/assets/emoji/0_1056.png index 19374ea0a1966a3c6e0530851ebe60c9dbccbaf0..fed2a7291d618f7fb337b10d7f2a704880d4f43b 100644 GIT binary patch delta 2321 zcmV+s3GVj%51bN^B!59rOjJcja7-^RFA5D06ciL392_DfBrO;fMJNb1CL{+32PY>d zDJm)$7#I{576bQ*DH{$D5DN?pr>CbsCL=;TIs^m+rZ^|LO*}(GLjVK?!AUqo zL_||7B?1Bi78n^HARrqZ9U~+p`NAd&2?;4FDC4IX_Pii2E`Kf&5)(5sGuoXM?y?*5 zw;j@v5?3!Pd`%0s9tp}H3OYGC{>CRjK|p8@1V=|l=&Tr;nwzB>2_6jvixmd{$}4#i z1zS1^m>CEz69(b3DX}LJii(NY+1$pC61%Lm|GF4SoXJ=>9qbmFK!uronO-)U)vbW*TtdV69(z9xmaa;f0W!AV$ z!LN$TWe#Z`5UP+#c}_Z?U<|!!RlJjOTTDRz)-2viS6~1D03LKwPE!Eo{#xcP8~zOE zr@cdjrT+erYUcjm(au-Ax`9`*ogNv<000MUNklGTTe@gp|G=m^HDeG5TAC)6fn?|qMFHMPN&L{7YqPM zq!N;sM_^mkS7(TAUE2OKwc*#HMny=|Q$(chS$~Oyt|#=xsr@h8(mcYaO3vUjK)_H6 zYE%&+tS0896RA`Zu^;#rP4KS~o%G=Iw}4+wL4hjP3P_WnK=*1TPdp5ZOUvIr7t;w| zU7JHll9TQb$hJ=YATI_h1tfCMg*?x)96y!B{p)kIoGv@B5WJI4m(%IAL=Y0oRQhfW z0)OGA#Vm-!EDInqY{ANM(P5=|1kXEVqBIY#C7xq~#@G!)A`IpLKoJ^-flhI!TrO4} z?j?eCibQE%1=}oU3T@NqyU-0#G{AsF1_q2V4C!LAns+#UF3vTcbE?&RHGj`T-{4t8 z70WV>_II}uEQlf!8I5BQuqZ?8z~a1vDSyJ#8jGELJ{F7JvpliPxNfDcD2ipuM!SFE zQV=7G8bc76>E!eIhJ)Gg+`;5DCkBe&lg70|!Bs3FnG`^jBO7+#4OSoPK|}AQU4g^&>;hy0sdjh%!M)44ymteodSriqI)jGk=7( z8w}Pe_5ISmPy$Bjs1giTF4|*PWB?%+V~tpz6}8X|5z-J#5mgLHUL@PWi*~(UFYQky z>Xd z16B?g^l5p9SpI~VLEM&&yBbp%Lw}Mb>*(kPDnZ^@KRT)_Nx`Tf*l^pBcO4O}FU)Bj ziB8Nl90i;IA*DijmFAjV**W=MjE{wqkd(45=5| zicmlQ)f}SQ?TMF$F!>c}!u--y>{`&s%2_+gBPKMD2&^DBx@!Q!uGoq>Ie)J~thK9S zftpC3oEJ1q<~Np6yU4<_y8%XjK@{_y&@kXbqiLOrI(1nC&WkN zcfhv|Q%O#afByJ!etf;}$$y)lC~)))=r%UMuph4!Mw%0ceU&L9xqm><<5J5X#8} z=E)==Y_PhUhd%tT5pZ?sjX1Po+gSyUSh7@tHvmpfU=ZL^NrIFtLEOcnD*6;yc&!b@ z4dU@#8^W-l0uWRuU5zptVb1IG8UY%0JYfPej@wSRpL$Ltv) zxBI*KSXK9S^p!SApz-)#kRUuC0<^Al?zF4Uo`& z90ozdtL)UoxPS`fEoSq>hqiUD5i9Ri>?~zim#xQ2<*{|E&^x(NsqLi)7^3``vDL_z z_gn)Q@Ve>N;Xc&8B)F{neJ`Dlvhb+%u>yZNjcS@ONHg_Y8GlaI?TunlLZ=wr`Yiz% z>rSKSF)XWYnx<8+TP7uxtCaAEjLx7fXQAAr%4Ths62gD@@V;@MFTx|lcN>}j(RepqCO??ESGwC z7#=oT-Ltc9D;K%Fd5}2vi4l4~$3;D%(>7oo)-uE4A%97udlqRn4>XM+JjT0+eM9vK zfZ(v0X*MH~Zi|@6^$yS+;@y)LSWM_V?-4kSAex6etyU{CBnSpSGv2-DZ1M>SHqJAl zA%Yl!jkCjEu6H;?V2#t>NpxM(dE$0T5YcI`*X%`lt>G}2%N-(7<0yj@MNV6Prw>(S z8BAAk8h<0AgB&25kzAzbA@DN-zuifQQzcFW8=eVtu#@Zca?QiuPHt!C5Ir$45;<;V z>CGrOi3gLIqXZF&fS>}vO9aDlqW{e(SRN3hV-7??)xkgJ6rsObB%&*3dHx41I|A*XqfdhX015yANkvXXu0mjf&x$z6 delta 2030 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 delta 2163 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 IM6N<$f(H@C@c;k- delta 2133 zcmV-b2&(t05aAGzBYy!wP)t-sM{rD=&XW?Nf`hlp2AO+P9ZQ9(5S(NMRQY2~$#%73Ve>%yP#$ffSXppI`* z^v)p)UuW7!l3QOqos^@_sXW|z@GBUsf2@q>Asrz*|)QuiTBpE>%E!j zy_xyiy87L```^F&;lbF-w)*SUbXhki76w`_75)47>D+K%gf8u)PK~@&d=iE;o{=rudlGz*Vm+^q^YT?mzbEs!orS@jh&sHp?O@iw6w^` z$iBY5p`oFrrKOaUlBc7fy1KfIjEshchL)C=gN212OH@Yy003)rQchC<1r8V{G(k;X zhOfKb_5PCo|NHLFuZM3)Zqj(k{vrSWNz(uSto;A~_<#TZ|NsC0|NnH(|Noc&|HA+O z|NrOz|NsC0|NsC0|NsC0|NsC0fTYI$-~Rvq|NsC0{Qm#u|Nnm8|G59Ek-uatg4Db;tKk(~ZMhc#UfpIYmj^G^it9bhfY>br*iIDi_Zt@9zqlyfPy zLI74LWhAE-7Sd zZ(f`x@5{F%YVcDd-b&0?zGQ%Wu>v6KghIThHcM8|R>&QbJw&+QuOIIb z88Z1(MdpPiFQ5yTl?W-5GmeVc6GB1`0{hfW`ub6+CI}_-N5ZVgRPaEkk*y+AvW4-m z$7Gus2pF%CGSuIAV|$-iXU3s|&L5&bkAFtCzI%w)7=nOTN5B9f=h}Pc$cGXv8Rok& zP+&-n{I;-YgF}e{=p_e42-a187I#W0aS(b0j5qGrm=z|#9wK1=&k&EO0V0{++M@}K zI|u*}7^p!e2$na9IPiPu76AV0yGL{vPnh@yu~kAZQ38;0A4q*SZW7#hye6$DYJYh- zwp^+)ya`c;TCN<4c5;=N3L)1Np_b2L^oJ6?9Udwcn+IZc^Qmwm$Qt7Y_d zREXnEql6x!D?2}ah+L-*yOC(}IG&ynxuxdI6I}1pUA6Ckpg{eT?$RH&WeDQOQGR-l z+0Q?=>T5g|2%{*J9cOHdHDNTCWG@o>HujtBs;G9B8kM?Mk#Vt*=9;V(gm zcd-}$KRiP6++-vM6m{Kpoj^yRE9y&=k=zg;|1To;)iV~Ts=F_TTR$$B<0wLGk-!#x+94rOj38AZb-Jzw|?h^C1PjLpSsI{HFX_|<5m&2 zk03xH0MpG)>|=vC-`n)TxWENbYm<{SS=*Xc>-YZv_asp%%zFS(a`NN)i_fCme))wKDKc;-+WRic$3GY!Eo^W<=R8h9X*tKoWvw7%`TeUE&r5IP1&cnHpdgL8qinjJFvIP6!GPsylB$vI za_8l9^4uc4ERf)PVt=kMF~9`iWEt94lJK}wNw&IC|{R=kes=k(#r1HK;Km;YV} zBSk?l&Ql>J?90$qvl4ZTQc#I3*!;@C5k48cet*A?CQB>96C%S3i3;qFT2wtp*kUaa zAZpHQ#weE5d9f7Rmy6}%eLB4mhKe#~GX+Ah7F%Ql>%=MmU4LLjnKlxh@m< zbC51fhi#`6M{BSiKq-tN4Va0?#D$t7DLJ*}v9kpOpSWaSk@5U!~r@LqRKpN18;1(h{ zXlTemvpuF_`mN{=1|$fYW`N5#8H1(?0y4P0-pV84Uza)|`Kj*@>U=%qGJ&6d00000 LNkvXXu0mjf;tE(( diff --git a/TMessagesProj/src/main/assets/emoji/0_1059.png b/TMessagesProj/src/main/assets/emoji/0_1059.png index 3d9bb776548fa368c5a6a6c149c3e8441c32f079..01284ecbd5d4dc60710b6ce5f8e6f22b2def58b4 100644 GIT binary patch delta 1953 zcmV;S2VVG-5v~uABYyzQP)t-sM{rCG3JMPo4;&mEE+8Ha3=9qr4=NiO9vvMA2nZ7q z5i&9|NFWAL_?dKnw%aD zrlzJ~4+U2-EQ=Ke=j7tm)z-@&36PMHbP)td4F@U=2Yo3X$jHaBw6=z3T!=?M`}_OF zJtNJdf6>5C!ijUEluFOEsKvEC0ssI27j#liQvgk*I3s0=4(8^zv-{fS%=_!fSNnli zwNaUe000JhNqb! zH(qV^TGXdq2Q}2EkL90SjYk8M@zwvgelVF&U5Mwp)7zmn{+|Ks*2@ALlG>Qeo6fC2 zbossNc<#dbe$pW1^TB(<=z84u=C1uRfJ`n${@q`J_kW+WQEv)E7TT{FnL9+IBeI*( zZ-V!EeA$Fz%zKpx0&jk9JIcJ9UXN?fyE*ftTQ8(U1(${Rg#ZxQrN{WQ7fvqCZ#?(< z?=ggSzzOlPAPX*mI|RZI=J8D2xZZW2;5T18-SS|8O9=DAFndneeL+0Pv>UV~5LLDR@_lT%Sk@(!62{^Cy~|pT|2SOL z=<55Irm9~d0J)o*H{^tej4%aD%wmXAia$rqzZ9ElQ**aZa9(d9RmDwVMcg!`1QA@^ zg#w~bQab=PO|5<>lpz`liZxMWShnqNaUf&S_m>fWYRI5l=%TK3vQ&j54r{L0JXgngB7m5Z4Nb1X7vpGRA{Y z#9+i)h$s!R(1j8PGQ<`HAQTYiOcbjDSgk5$DpMt#*l}Wv?j#v_AtGIi1mZDe^$5xq z$$tv6!Kx&XQp+fcKrs#wQ6z;96eWh(AmK9FBP>Q-Lo`^E3Z3GoBhY9V9wN1oTu&t!+YF89VxJL5S5SEJD21 zy#^y>sn$-LX-RfZrT*rJ3mggVJ z!Q3y`LP#4%Arsig9D#l&gw-q9ihoXR3H$NO;}HN5@*E6jeLNo5v5rNQO4vpM`xu;o z-ax%%l|&-7BN(fLF+y1a;h&!t2_?mSQn)zGmo?~qwYrOt&|vsoknl067$UmI2mPA` zz{?snJSRz=rLYq;K#7H)=dp(ModBcA_DNEBSmI@@Zyai@w$zrUhJysWDSuQ)4Fn(} zZ&xHR%-QJEYZ;mvJCa3GYb2nEw1XgueaLeOMj9+JLEyEmz%&v@cxr0I#?V5<*Z~DB zK}fTz+5D{o&tS%rgb=KO1|lXv;4VxFAPO~m``~4OkQrP|}%(|?iZgp3fjSupF}L)%a#NweLBDeMKZZqp!0m!;4GgkZPZ zR(tyTDEkMsB-w1YnT>|@mqJQ;$nkX=EUHaWC=mW+)JapJ0Y#)P@sC02OBsQ%t(wAx zL*GY@FaQJ;hycLOK-hdpzvMk(I zu#1KD>7%h01sMAv3n6$3;P?T;;G@9Uny772H2cVjBRdFE>96mbqS?)c*61U<7+gCQnU3EgCT{4RPpT9NUkI4xGMD+G5okW$bSS;IPw9fN0VSjY>)~}4A>v7z0R{{t; z8OZfAj&mgbHW*QC_{Kh5SDCh*K=KN!%h3>EoQcV+zpbW_*=&Ya nlk{J`$Qfpe!5aT&mwEmN{mWgPJB-J~00000NkvXXu0mjfKLCmK delta 2184 zcmV;32zU3c50ep)BYy!eqhr)oSq8 zZ0^@`^4M$c*n9ldQ~b*{_q!JGx+L(k6YaDhByMS~qh|%Xi4gDZ z?Z%5@#>B$mSFi;IPYg}b}El$4aErKS3*JxKrn z0C03tPE!B`4IC{&TY<8_-0}XB|NsB?-N>ztd1gvCCVv^g{r~^`{r|E>Q>?7ynpxZTeXCE_Xo00x3dL_t(|0qm01VZ<;H1*~S{eECM1pM?dQ9k}?>> z2+sC?6819;Oo))@WCTp~u()hw`#%sF0DlQX00OuuNp2Z^GQJ;-ZLNc35J3 zAwvuyzK*d!Ryw>Rsuv;`0yT_BU-gj?VT8!3SPl@>zaeC6iGK)6 zf3>d}6E7+J>lEIL!Gu=X7b*TxLKqAIf_as~+dyTWiSg$Xy8n;TArcq>$cQPV4*<|w z2iX!e+5dbsp9xEuX()zHq>tE%c_KcWjL~$O&Y$)a(N%@@UgjbWsC9(_B!LJ}Njjar z-`Lcdxex}b>fitVuZp~g1{2O99e>ITcp?&X>D%?#C<7)!=z6jIb+x)$G&T|}cz?l% z+B!TFq1<@)bZ8;0Zo1{NU#_k%dh|mh9&0(&wO}!5CZODXPXsljfUdq?-CVD(Z`;JjeRsN)B~x;AbQOQ04yH$s8*UbBaef+ir1tcXxW)c0J8GKOUxj zK2#ToyqfTFLZ>R=XZQ8~o zTI+ls2h!1jrm^v?R`WzFwSV(|Iy2D8Kn(96=lI9uP34dWHrjE(gHDLh+33ToxYWsG zqT+; z**jwJPiN2b=Bkdac-pvod8EfdXuK>!Yi!=Tb5uj6yp?G z&1OoHiiP`!7k^0dKG&9%GZ=?qA={u?&{!fV~!_I^MMUva(Lo0eDPD3Em43KL4rQKUgl;TKt!?Hp^+ zLP%?s-Iuj?>--CF-fFYqV2^^8LTJ|Ec4#UZBOYFFk$-WAJqf9DrEI4zRPSE(xnmWI zQqcb3O!QW^eL%2&-)6xUHujp7E>1o{p%v*ptZaj9`@Rm2|6%(lK8ek)*pS+J#{>|w zQ?w~|8$mdVO>u<*Z diff --git a/TMessagesProj/src/main/assets/emoji/0_106.png b/TMessagesProj/src/main/assets/emoji/0_106.png index eb7cc0ee356e0695593992b2acea005ae310caec..f9e183e56a87281d18187b522dd7b83a84589461 100644 GIT binary patch delta 2151 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 Y343cV%(m8I01E&B07*qoM6N<$f^?yUr2qf` delta 2010 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

W(@^277(g#4Krbp+O-e>IFF-IXKQAax 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1064.png b/TMessagesProj/src/main/assets/emoji/0_1064.png index ff72aa4f474aa6ec9bc037bafa6e09f00928c283..4c482ee8988ddfbd76c7f795430a9b8b94b44179 100644 GIT binary patch delta 2197 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 delta 1900 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 delta 1758 zcmV<41|j*S5$z3-BYy!GP)t-sM{rDfN>qAIG>~XYid|DzEL&eJX03aJh*n;hV0fit zqi#2InQ%^qT|%H;qHmWM-;m`YA_8cFCndWQ+W&)$i`!wA|{;C<91n=PI$YVG$3^$Sy7e4l+MF}tWW-!7akVlP`@76e)BztyN`vnwx< zv(*(*-eFX}E@r8x^wlU!S6A4P@3W`0jW>3)XbF_-k=bx z=M_4l3WOY3W*UZRnk2SrSt>yw4k+g#%Y7wRaet2CC`^*nRz0h)nwUn1ZZp+>pxk=p z`sHXK>e?$>)>=Y90GFs@)E5T#j^V6RAb%mgOIB) zKc=_J&2xA&9IjryTzOvKDwe0#X||$c0pXQb&#!j)<9T>NlCUkz&Y~G=U54fC zdqJFqqhW?8o58zL8iQa39wmW@6~K)Q!+-b|LJmiX2>=w>Z&4Cx1TfcdII`uq1R;V? zLwJAF5baMJBF@3Uc0d(Li2}-WH`1yfRMkh36B~JKr%8zCo?8H5bZ8%2M+`3r4&&#! z7sH9?%f@mk%O=DDozUtUj_bM(&q&ufiH7et8t2t&=b%MLoH-x}4u;-XdfsyB`+xpq za!CIZ;iKyiK)^&e2|tb@es0qW%`*r4!0~Rc=L$S4YDCaP_9Jx?4z`lhSfO_h2pSq8 zm|a@p3tNE;fm5fOq4u8Y2oG7wXX|x?u2P^q350#9^V<4awo)`?xP<9yu z32`!Ec^E4QI2J;PqR!D&a>k+nt(dS3W4OJIKyuJ^jb^)=T}BYdPD(&9Jglg&0YH$X z6PmsH%z(h^lZM2x5WujQ0EG7VXz$l4TEQ_;2B-NOg2Ny?!7>ka657f3AAg@m90P(b zU4D@8V`xAsyih<#R_Qbg)7rLH9Ep&(uI(Lf2+|Ih%y#ZRMv1Ma+kPsw4s{L$?Xvwr z(vjc|0S5c++rQt&b0&+HY1Y}cSf7D_=2cpIKwt{RJp%tCG2o=NJ?%8N5F%VgQFM0* z!SZ+}V-O(5^IpM=lCSMFCcxJ=7t4RCpaL!Hu||k0IupXAifP z*r|{nAR;hum}o#p=W`GWXa!3_>>PjaC5>YMDF8vkaf=>Au{k$=JAbj$+913z7!*7U z2K3Y|T)bbb1J0G=nbA4{1bR{c!u{M)gD1}|PKOq?0iZ)f#uyll2E2KAc-UO6h~EZ> zP0FtVKs3(q;VV788if$44xwqd7PL{pM3&dfX%Z%x9YquA;X#rl$|Qcz#=pM4R?9LA zll9|z6=p!}RS=*z8duBf>sVDyJ4w>aE+0W4Wza|Eve8&BV_7xL5?=O1Iz-`($jM)z z#BpqzX0&&C{I36FwCX39e|`D#rFwGQ{+~wv2TqJ-jN9v-7XSbN07*qoM6N<$f_v&N A=>Px# diff --git a/TMessagesProj/src/main/assets/emoji/0_1067.png b/TMessagesProj/src/main/assets/emoji/0_1067.png index 5ba3b85a02ddcbfb9d1cd8a72343ee033b06dad0..1b3d5ba4e177c47a70799e6a31d84f9658bc401c 100644 GIT binary patch delta 2138 zcmV-g2&MOe4d)P$B!BHtOjJcja7-m6Bn}S`4G#|{A08|#D=HZl3=9kn3=KCZCJPG- z4h{|w5fKv;6PPI*Ks-E0Ass(IKWHwk2M7qgO+0BYuB$sMsy!?|8ftAavK<{A7#SHQ zB_$FQ6EH3=AR!?>K0Y)wG%6}81Ox;`L_|3`IY>xIPft#~9)Ag3TwJQEs!uU3V`F2V z83#;EOp6r;%pweW770`wmuC$FR#a568wlUv-)1l=ySltV85DwkeQ|GYtRxeIC?Q)N z7Vz=#k&27lA`6(3pv%n8FAxr$Y-U(7hlfT<)V@(*=z;@yeU(Bi?QeN=!!D!E9K=4Ug7A%4$3Hde_HryhA3YM z|NIx?LW@eC%POZFQz0=BhO&7;WsK79#tWk>dkA4Ju8(&G#Tz9Q1S(+iTo?f*@);l~ z-DULpg6$&;f~AWu7IIDr;6i5?Yua7KYp3;9I z2B1c(KAkb+1)eXAQ9mJpHb$!;@TH#3Mo1XUQ!Zha#W7tICVU;5|NNu$ANw10>OcYshHbqEteH^W^N3g@`v_@2@0@f##7f>Prb}Vn22@Xos8E? znSM+OBa>+4y2btWS#;e|d$S~l$QT;!c1WNAw-4jMCc>L0SfSo}7y_b6iKMN;rR$zQ z+c;cTM4LI0gnC-5@hZJ_Zd-T5et%#Q$#`<>P8vT}u`fJL37teW<~o?o{bb16X0wEE znef$ml`MOM_HbCw5Zl#Vuhsr%H4c?F*b8gXg1T22$9^OnB56-3CC2wuJ=xCglJTsW zslOes?_kD2u{8t2G8&`~#<8z6*G;4LCL$aWo>E~Phn|;r9xuQRQNb62QGdQ1L=EFQ zwxrK$!fNgIW-h7GxXJ=tt7xDe+YQmf3!di-NtdvgFpdu|RDwtVv5793#8)VT2HJI@g zGSG#f(ikEU2*Nnn5)mWr=6}1|^SY)HAO;hNByU?va*)Xh3Q~b_H1x}g=F>}B8%u}; z7=eX&xQ$?DGK4m)fhOp)X|>n8G8+qN(1sNrERgrh1g2sxT-&b>g+kFrG-1NG2otWM z{0^PYM8?xbcA`Nv;#aSoc1}6NqIAFpFq9Irp@HS)+$3mAp^3>LihpXPT7LbQ=A<^E zQlNcb&u$pF;7NiXm2XW%k$^)tc-W!Z46Q9(Z7#1~h3nZN0;|O4|`I zBoi73YCQG<00_687Jt<9T>|uzP`r2IQkoK_0P7&>XR7x&}gYM3O$)oT1OXxvgMWq+Y^`d&6pE6fNCpN<}X z+;4I8&1$vUKKyehiIn)NyzS)7U-`P5Kr3H=JU#~K0wL_|EkZ$SZB0m` zzJI^(ZihGH@y#&lP9MJ;L|C!Y*YjA=z9k@n@^9VleR2aDf9-a^aZVr#`y|z)SLcK9 zMMgk`1BmWdi+{L(div&aN^%?Y{8baaW++SG76C;W4!2!IIDmN1#tHKo#B0LdN36A^i2^nKFVG+AXh~pAoJiNTBLdeXmB>>{7`_%mk z$+QSe1~RDY5PCS0Q(_FUKSgpx#sB~!tc@JO%Ln@=o>Rgw;>-jha#=)f0};eIn2e%i zjAF!=@Dg$FW;Vc~%ZcQrgPqqD3RM)oqyGN*>Ep*w|I76E?jqiUZ@=>Se{lGf6l@^S QYybcN07*qoM6N<$g6`DbnE(I) delta 1649 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 JPDHLkV1f_CH!lDH delta 1646 zcmV-!29f#45&sO3B!B-#< zK8k5HZy+8WFfA>kSF1ZGAS)ghN;WN5LNzoY8B#klL@y|(RI)uSCJG4&Tt+-@ZEUPv zvq3&TgGGrrHa4k7YPqhs(f`#sJuMAqze}Upxj;JY#@U~xT7S7Om&6c9k{jWmt2L?AQ^(Zrc*LSGA_G=&fa zS$_d4jRK9fV_9e06&VM?j(U$yj4FIVy3SC9vpMNljqguBJZ8FTZuLMrTwn4Cki<0g+yR-y5LF%&~L{L#qw zC3B*3&d%Yu$@L9;2?-^1&h$q!AksAqM4ep!#Y#Mo5hT^omCrjpNS(8-WZU7wi#6WcQB9E6a3)Tq_SEPDf^ zG??Zvd=RGP$Py;05#onovmMHlLFOYW^5M%bUpgy)3R?(H| zbHzE9ETad#E3^Rs%j&SK;?Y2B*?)F;&Xi>nO@4e{<@mwiqRp@h-9T$yb$ClRWz*CV z8_`W;7e#RtAAfP|=!PWgDtAi>S%zSedGgUrA-@N4S~|9hD;poPIj(eW*~FkbrDwZR z(kzXFw0ERN>q^xjsCUhCOSMgNf3VNbpFcm>R&ttUQFecHn<_oLb`^yFlYc;r#l%Xp z;O zLJ>n*EON=*KV5$ALpYSMuue9_B-7+N8UZ1pcNPTK0>FmYva*o)rDJis-A>0B_~A?A zit+!6<{cgkU2>MoC4K9Q<5(qt`paX%uvdGzUXpjVD2r0w+VPfUac8$E!I~29IP3K~ z2(k!8w%b9P65<8`yK#;e6Y_!)WaP~?3kDF_$2cs62NJ-b$$0CweRgWvl^(xLDUxOU sZ3&n3^i+>q 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 delta 2024 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 delta 1974 zcmV;n2TAy`5yKCVBYy!?P)t-sM{rDIGie|oAZ|Kt9334)ElVIEAWt_-KrlN_GfpHY zC?+N<9v&X5WI=2-ab+=SE?Qz$D_wRzdQU4F-uycSTvegKv`Z_ zZZ>o+EG+omzYh)$C?_XrGjH+Jvm+lKVlZhL7#Qoxsa!2%SAQy7=DwZZvycM=1M=9q zGcq#MpnY>XdU`&8Qc+PkI5f^OzpQ*uH;>Jwsp;KWSXf1N zQLXahU|(W8Y=3Zs#hijcB}|1}LVbdGxwe3OnTc0J&$5@G;MRS5Yf4E zU;qFB9CT7nQvin5U+GA)9x)AeSCje1rS|OE!q=aM>VNuQzt9L;h?f8W1_Mb%K~#8N zy_W@Z+gK2QYsc)kq2`kIgbZe8W`~)Xq459lcAuPFX6i<6XYM}RvOLlIW=T(z5C1W4 zkKgZidfb01@c3K~nhu9)hu!7({)u4HK_^b)t3W)N;Qm13bI>QN8!xQJE41tP(s56U zmDP>aw|~ULcIWRHTp|}=jmP7!0{oS5_{TPQT{I^r<0pjp3+Na-4j-KivvhLE$qUJ3 z*zOs#7xqd#%!&zr8wiht=oUmL5r^GC;OgTk0+y94vK- z!)09xk;ABE(O?9{01MJLSdK(u;{u0fUBJibV}Q@=&&q? zoqs4~Hm@_n;bDjg0fG>MfO_YpQYR>jeyfI{f)j(?O!2B-zfzbG!+_`Ts=n0i~x@6f#V9sehEuw65xB-Kz&?s8IA`Rz`)(T7lP{gQC`} zw{+7W2&gc6Xkf=suy|c5pDikkSx>`&(-0^~DaNTq5D`21l%c>tKtuGRE*OTO+<+WL z+*-i~32e6(Ar6LtvAXF+1pN#Qc%O}@K;&8x93j0{Yu((m6{W=zgXkYqfv^XVi+`fD zYqeTi5sDlMf^)eor;`OJdd(KmafgNK4}(44Y+VKT%PN zj{=m`5<>6-h@m;S-T;MV7~UxgSCh9CQy5|hp$o-ggT@3{VChEz)VT*(7;fmm9gQ^gzJHenc9bUqVle6F(z#rkI2w&|IsNp@(U_tT>9h}mw}!ht zqDYs^xE^dzAAgkwj|P7KhzO33&|q@$n9IRCjlkLC#=_`gcotAV?XSNYn$4l>Vkh?q zV8!jF4O{JnE zhRZz*J3)-vCxSw=IT&2u6m>-ahcLMPy1V!dmJX@H?eoz)B8?bwy4Noh3InpyD2A>p zfS}*s-!CSUrl69nYJUs31|*gO_eA~!+$BNn#xlWHA3Ox zDR4kJVz+z1H9S9xMK~BpOH)+||4boRvr!7aMDA@>rM_NV53VmRkL#^gJC#aBfL>M8 zpn@@Yy+Hk}n83SRt7@&tAx3|(cUfy^hGexWIC$y}JpXe?JbyE)iaU0(7-`p!pKfn& zpN@}@>x8o^pi2BJ5-?&eY?`K>Wm4^SrnbBL)ns>fb8~ZgdU|nw4is-tRdv*K+Gez~ zd_D`*cV7X+;`F@dgVzR8zGZIYZRWO3eF@}|S{;(uG$WYzn-_a*b2A!Y=F{A-pUz&d z=ks4*0s$iG{VzQ~?{mJn)a&**0guP~?*2`#1P|~TR{u}@14;zOVGuAxFaQ7m07*qo IM6N<$g2G0S3;+NC diff --git a/TMessagesProj/src/main/assets/emoji/0_1071.png b/TMessagesProj/src/main/assets/emoji/0_1071.png index 6f766a77cd450000cf4b6abc6e11b74aa67950ce..2106b438e70906ebd662d3fce7d5e9c5e52a3fb2 100644 GIT binary patch delta 2611 zcmV-33e5Gp61xI% zm_q=NRFIKWk;HGn#a_h7a>#sSL|y<$eh6A}3RAl+ajPY2l7D29xE!;+Dz}eLkCH!- zj!TNgZ^Er6n1Tyemm6NaT?3I2V!Ub(v?g9q- zmVygc|I7k_2~^~Z7T}E!cx;uykWaf_0c&hexl}Uzv=ujjm$xFYjY*B4C`rkE4wZ{- z_MZ&chzw>Azy?I zPvev%2I3ihYq+Z?H03v4X6h zBa+=`ZL4Ps=Dr<7krv5_x zjMb^AX-)Lr++T*|D~%*W=>AZ~cl~(cy6%l)#YWG>$^Mh7kh1%1)bcIl{H=cVI>77x zx69#)bm0B&n31`YJb6iHZjZ&x=-sTM^ndovo%eC0rMCY58X3xu000JgNklcCOJf23wV}G*{ zh&nX3hQq;e7$+?p*d3#;U@>_(YzF7$Xkd5hIp*QG1jacUjhx59IdaVeayYPY^7G=R zCb?M7VQP3Vi>d+%0~vT4ag#>gl%rvS_wb)bxg!3cBJw64Q=F5-;czrOCYwevg*$i% za2VF);5i%|X7U>0Fsc;+T>+nI6n~4AdRzlbBpe>jHuot?_obtDC?ar)M6XcRhy-e) zp2=bROE^q_hDnhWo)qDWB#&!h!Dsq}k3PRG;MQLK{A1jmC4rfi6uwE&wpV-^$hbwF zFBKiT^7zYRwa4}j{U7(I`AJ|uvwd3qzo*Ds@d=M+d=8hail_mPl~9cv-4Al>yleU7)VHcBY+(G<}uE3S&#; zVsSW?Mo&(?Dpae43s6fe%zuI9=SOXYA@ikm3grUw@NfaBjXai~Dh14sS`hi~4`20w zsN$9Wa@LEYy1F`rj4S;5N^8qbgxZ)QjCXShf)L1L0gkXoQ_f| z<^qB2MoCEt5P)Cf(a_6Z=dPauQNe9J_l6M|T5jGfA{BS~pENXhQZb;BgzhL%eD>+X zHti=ytzJEhv#So>N+#l+k2MJ zbQ_XL(3U`ORUvIZ*RGe=DG7orh#K?UGrjZkz4HM+E>?%@If4KJk+l9=qf{y55~N{$ z@+gB#Y`*tX67T%uvs|nyxB?|9ICHJ9TnT1`3nm3DonfZL0)N2(pr_~Q@#8*@)|P~* zPu~bXzI*pS_w=H2fTH|Gw^1dZ>D@apaO%{B3kMI94p%D*`id1RZVh!dH#c_%&vl$5seiB6zr7YgMj~Qw@dr*#jYkm(O#lk*5$g&-R5?H-7KSl znmWm(bBr@7W<%CleW|9V=F%URKdr9bkhy#$glo*O0YY|Zf#SXIi^CpUm`G>n^Oc{9>U|2E-vc*f;`@cy`OI!2BMSd{=oCgA6FeD6zKo{>hy<|3K z%YY<2_pE}|NX#5Q&}A^h zkBsZA;KVtIZ3D6sD1c*-beOn!pexT{ScpE0>EaVSHw5}SqILWB?K^35nCR*n1cu?3 zKwM`9Z?>_qMhaE{9HoVMgJ$yb3Jr#7@fLyOqJQxs0MNinQc+r1SU6ZnQd(-57GS`EEH5aCy)lGpshiqz+Ok7v#zqhM5Qh+noJ&&m>2>fh}{YV&DiAZ?5xu{ zJAcO|m{x@2+{9-QJWx9=j?ozb0Rb7&mK}r6O?=i1?|EAGpdFEr(Tme5D9DNYi+H}V zid<#OJ-08lCk`_DZXvF(u0^rc8>*|{@Z7Qbr5#?cr9jlcFm&m<%*^-CW@kU?erH{Z zSISZkh&m3FH}3ukuyHa8FiZq&@|ynsbu3&je*%#c Vwo`+3diMYT002ovPDHLkV1no&*!lnf delta 2353 zcmV-13C{Mr6uT0TBYy$HP)t-sM{rDXI(62?a@WUo+suAnJYHcvWXiddlw3DJI(AelSy?Py*~xgdnNea!X=gKR zdqH|KR$J7=a<`mR!>e72P%Mm6FWJm@LRwhArCNPRI*xE)l7Ce&u$NSHI(Tq6blkO$ z-nx_6uZYl{bJeGR&bexNK74C8Z+}67ukhn$Gil@4iE2$E-@TXS+>qPNeOoME?&rJW z!JFvbn(X4QU@&CIjbn*YE`ebzwslOrd{W=if{kl4c2_3Km29Bh(!qsX=Ek3Uzmj-G zCZK;ns*FfrMt>g2uw$)lMW$ps)WUI=bT`hRd7o}fYp#L4j%ucQSHh-Qtb}98q=ay{ zhorlqbgHGs$*EqRZ&sFN@#@B9r+ATdQMsK{KyPu8(533lrcj7oP9;%dI3A|v+kQ|g zt?S-NLs3Y9gonwTj>f>7(a7oGqkOrvh>D%@(W-1OaDRMpUX7)Xd|QXb+rWNLRep4m zpl)zMXh}+WQcfd1UY3<#GfVUD(6adGd|5zSQEhL5c+a+zprMA<#Gz4;lAPGEJ5@et zXK;#%a~c$-?EnA(Ds)m#Qvl9WXe~v>g=BMgO+uV z%hbZX%zwfDPuZx(000L5Nklr6PO0spOMK?y{#pJ?QSyo&PVgo{?^#r(Xu+|7!lALh{(;^O+XK#&}TO#eD*y7`*-&CjFO&P zrXjIejESsGV9&PK28K4BqVHCUyE==-rcCIJ0yd+dGPdvy-l`jtJ?LR7pwwLfvi88| zlYjKzLeXu43htTQ`h*G1@#)|tU=p}R7_z%MD4orh)9c+zkX+5bawx>tXy337)lL_8 zWnAn2L<(7qs4gHwipSy$Y=rYc?TxxP=J9ya7?z7CluG4XZf-6fSI$?stav5^oXH3V zpTEq6y#NxWu~nDLwH^y3=I2x5nLOdLD1UU$%~(k`=nM-KykV~gM0#baGA!DYdt4T! zAII_rYs5;@ESt|W3=<4{JXkCiOK>T%V#t04g-@3XWLN`Ps~N0TgTX*i6v;TTRmep@ z&vlD7gyT#;&L2w$tL1W)vI-dT)k16)%eZ1me@djDvVKrxv+?A5x*Vh_tD&u^ReuWw zuQ%;V>H~>Ek%P47CoaX!2a*s4Ns{28BFGVmP&5U zY7vChK+^f3cU>QF`=83h6^Ufh70Yv;>h*G#m7Q!JWHzvqIMMQ>Efg zCf8k z-meFT-jxY6Bt;nvRs$Pk$$Xwu?UlYfjK43(@& zA-2sx0pw61U|CN)8J1?5JWVrD%bappF(|rG`-kC7NPwd)aizn~Aj3F4m4KNu?^_Xl1hs``d+KE_ly)!r}9y2V(>MVh#nD@!%zS2Fq@GB^Q1i< zZy1({uA^mZWwe7shxB~A}^*FvGS zjkC$f=X$hQ-(GBUaDP)l<%E!j%4}9$>}wVAsCK`gAfw54I3KG&TMfO6yQLDdi`STx_*uk z0Dg431A?|;1HA;rR1q9#KG;5WT~mzvDi9Dy7i%EUY^=3oKz}r+W~ZiRXNz?Zz-ao9 zhrQP=YyvpYv)q0sKm{=)L~@~h<*uU>5uxV(d5 z0OsRbKBQSg?0@`Obu#4F$A?BXPW|Lz58?+X?6uJ3WTWw=6l6(& zGBlcRwtjvIQ(OGLa)k38wuu}J!0G<(ZYb0!p@W9b=i!YesoKYnA2&CDN3(&=6|$DiIbo1Z=%A0N*l z&Q}1l>VGf5$8}g2ax*+Syy%N}VQcH#8{pfwt*wQHg`a`Z@f8&1cc3&woerA`^V>`s z9zCA9t?vkiM^agze8TZ>jCb5-z4Fn&VOS=UNf(ZR1tEf89u2i_mdeK`%mNeRA$ zj>u$v(r3^Afq@73@XMn|_ocnEe=VI}sdQ*aDk|;m6Z?(;cMd#z{`}d%bvMeu`oHC$ XPxN~0Kn``Y00000NkvXXu0mjf+qaDQ diff --git a/TMessagesProj/src/main/assets/emoji/0_1072.png b/TMessagesProj/src/main/assets/emoji/0_1072.png index 9a1ea23552c30752e8702b1e0751aaaaea65dbcf..908a678464d019f864fe98ceceee1d3734eb1039 100644 GIT binary patch delta 2330 zcmV+#3FY?24x|#0BYy(8P)t-sM{rE!hy_tsbUa6*Wmtl4O}9iphnISMR7Y@DMRikJ zc5`=)aCMG9D1S2yKX`nOK1P*jZGpUF2tFNJVP}ItD27Q+ZCPJ}6M|Q___iGLr4xld z56^xJ{htV{R(}F#ZIV4gXgfuwo1Uxbjbxum06a&eQd*QoPH)3r04fDFFbX;}9&^#C8tI+_Iuk^-jVJuJ8%7>g zF&<`)a>t&J!jL`ypGN?cZJjQXka||VhFsBWORseM?&Tw;AHGjU=>s6iM`EjD?9Tgy%}kV#H#G&^O2UB)mvhF4v9Wk{WX zRn09oequkFTRxaPN2fVNp(rtHM=g#wL6kQ_n>0L%I6q)AJ(5W-hxeWXKP7l1ELN>< z2PH0J)qj}|dS0GWGk^ZxJ)LSLIXiGdNRm@Hm3CCbYL|RWkbRnhf-{kdPgjEf>{w@8 zVqQ6sQz&n(mezAonS6?1BrRJ>9#=g_n>$90KrCN9C2~SdiHKUULqT-rkO4V1Pf#_N z)rAH-Kz{zrH2?Whvz0|nLsx}hh5ynbl6t%0s(%)mch{kmdrES#5{ZvzW44)Sw9lzd zC{=|LY=tj)oAKI2lWve8lA$>uY(`FYKuCWvKdN_LK&yReb5o3pb*+F~U~3`+UjP6A zd2~`vQvekG{2Km60|*jgSp5F}BQBjIDEa1J>bKE8<4rJIc39M} zvVVx_{gD3XsXp0o>i+$#?R4dNz-6GxHlM4X{4|aHfKJc2*8SI=p22={^{>^9%U$Es zxx@a-`P7%T;_ckix4B%6jML_uj;5kE1g3_LxY1SLkVr>XX0kQ5>@gMvm}0ym?BRM^M5r4 zl+WjDf;+w>q*$Xx^i54>1ksN)Iirafk{4=_;engOeB{ohMc)LH2oSS3-hS`Songd& z?~mcHXA$bn{R+Ds;oJH5?0oxMgj$RIc`OY<5I&+u^t4nGA(FPt??ez=bF)pqkVzs2 zBeYqGD9)U*#nXxZ*S|8LdOp7(jekTOIy=}P?MNd*5V64%Hj5J%%x1HLkEEx6zi(p< zZb9nYjh}p5CtW zG!#W?J-xjzI|TyeTex<1);#_B#j^X4&jY}lt|l0SflraDl#F!0>RRlkTYok>0u=CC z2v-nFMf2!aFx1JEdr~)=CX@445YefBk%Q+}9!?di|MxTG?dkIu(LPpxOy98}C!vZsm zN-rBqZ?^tvb2U2!N{MFnlqWKx6N-wcR4RDc$(&9xPbrWnq?b#BYikXfco;*X=qQ|G z$fTYchng{s16rujxCK9+t(Iyu3Y11eHLm$n@`x@gJME#pz5P_?G=E`aTrRB!0zhrG zp+kz%Q9Wfp=vh}We#SU=u6_A5!#ypSJ^$drvuyTR%)+iV7!1`@f?&+P+Sb-~;U_o1 zaeSIV!l2UwnVB|)3;eVeXg-dMi;IFL)3|U!BwD&8q%aY4^z|J-e z7I-;_jy6d~e!unGlNZsx;{0)fW>VsMnmmrgbko##Cb05kFCrAw7+ zM^$<880EmAmVcWd_Cu_+FvHI=;2Cp#EMZyzq zM@3Z`psE5GO5`HeR71|cPE&|$1d0Z=+TpNREEN`uL#J+#Pu7yTO10l-hI3`5QCN2Z z%SElzIdnQT2tjUoe>@F(Vo(le#)F+#Syy)glK_jlq<;i6ETxZiWe9IY%*;m{ln%mh zOFRhWl@yjI2UcPvmcz^>#{vf?0SJXclZeOi2qGg{Z+L@*e0au6p|DPfVX8DH&UJsd zBDN6671SrzY7|vsh>R322Q%dOa&cXQAr3cIWwlZ$R^AFv@;<)Yu_A<#p*NNIEaP&y z%VNSvZhu9LZ_b!LU>n)9B5Y;}^m=`Et#o%JdGn^tz!8?Td3O?!JNYlCjkexZrysNv9a+=?)n1(0r@FJF14%kw;#*S&OY|-mMtkMtAT+C z%h($07*qoM6N<$f<0?C A+W-In delta 1848 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 YpA%C%$!6jBDF6Tf07*qoM6N<$f`anQApigX diff --git a/TMessagesProj/src/main/assets/emoji/0_1076.png b/TMessagesProj/src/main/assets/emoji/0_1076.png index b171416779867b3fbd8e66b7d99819ed5288699a..573fd03752d9e69349ad17488369f6746aa0fd22 100644 GIT binary patch delta 3310 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 delta 2209 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1077.png b/TMessagesProj/src/main/assets/emoji/0_1077.png index 4f6b11c59d7773a36d8d3a7055bbbb2508bc37aa..52cd3a020c569b4f21dde3e908102ca2589522b8 100644 GIT binary patch delta 3264 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1078.png b/TMessagesProj/src/main/assets/emoji/0_1078.png index 5f60229153c551da36c964400344d3767fbccf22..461ebca6b4cdf81d40bcef0e2f6ff8c0a9ccc9eb 100644 GIT binary patch delta 3274 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 IM6N<$g7>pZmjD0& delta 2244 zcmV;#2s`)98P5@rBYy!SP)t-sM{rDvPH>^2o|>7KhfrgNS2>)LiJ*#wnR$DTWoVz1 ziJF?0y@_R~rlON%M2=uReKU@TS~!6+l7LY!b18y?I+cP{IG2}{kYPcanwPeMV6%K( zrf*ehD|CG{kDs5MZ9*U=1TT0hiE$@^elCzI2Qt5pX@)YGW`7}ds7SoYX5EuIrduCo zoK!{p7YC$BajBTHHRhx29b4MqIRx_rC zXL?O5vazkCfq!AOwX>moTe!HktgNW6cUq`%RA#_qsQvgNqnKQXG2^1w#x7GS#?2&rf*y?DNd(>#3+UU^0)!t<_LjwQ+ z2RcbaK~#8Nl$7a?;xG_|hlG#-${>Wq@hk7*JNLysvwz3?KgCuX0%ElUwj@Lxxxelz z8$O;Y7;UDmPYZwJt|p@Z&;KKT;zmvwPA>@8*@sT#2LFec?%THAyO-4_#G;teTS!^su!!qI5zTz9VayIofmMD4Dgc9rgQ)I-=rH9B`?tuyLubM9!Dg2tXYbpOrpH%`54 z_nR)4XnKQ(WbYnr9c}!lY1Zw18!y%@qss4zk+Okp#Gk@A8tg_M;PvtbXxUmKa{c|{10`(#hDVmh(80#QLm z&wCJqSy9C?5SCy8-$~45QW8Unf*MHS`G0*rWDbNhu#tj5S9Hr*UJ`@GkQET7?_8IJ zpgtOxi3pHkjAh?o*fD^Blb$d<10OLGQ)I&uN*H4mZYm<>+9C?^`L7&@gTeU2w+QUH zCP9RXNggwm*fGdSB?~dfzX=K+5T7$WTYJlEng%{BA<1$k&u0_I+@_%f5SYSSu777U zy&gOqrqT*6ghj{;Vw(vBW6sCpSy!>37uaK`D9}Y~(w3kab&*9f*U>U=z$ zPN&0JRgyO;ory(Y&)*0QnJO3fP!{B;`o(Si@2{_~->1V-NdvHuQW`=SAlAVhF|DaFf$-5MyEt%Hl3h!#?}@Q(^@9rxNqwO%w^k_?pC>OjJAd=OV*<8- z<&=gYjZ~pb{fXK_nzJ~#5AW~ty$9RTxV7${u1;i4rr0RPqQK6@HB+dW_)?1?z_jNy zV8KK9xYtPc1cy?8d*5BPE(sy~r*H>E9Hp6f`|Q;(R1?LF<=appGHJK2J{{eejUFMg zEPGoU2BAfnr!H^2S0{##AOY5ci%H$S#3AB6=l2%x@@Ne_JIf*Jgb~-R)+H6!`=U`MnrDQX$NV#~9lzf30uUPk;V`w?pAC!}ZPf z>tg9M=1t6TSxKkxJHa*wfyz;)n6_$bXejqS9g!!R?AJyYzK&UWAsRg0AVun z_;_pC_yJAAc#3lR9}s-Xpf{3 zNBsLx+GU0kAxYOcLw^vQ3lOUBgONmd&4S#Kq*sjYON<6W2!IFymy2nLK!AV%fioD} zxe_Ew0pv}L8Zv;v0h}NhF$4xlNgphox!ikhf3PUbTD6N1=y0E{ePVyK#)^M5GK~_OR4$H z(w-|hy|jQh{6ROR(Fk_Ob*Y_meYdF#0ADrrS!JEWXE$QN(iFb)-W*j!XGR6Z?ZIx5!I0YV5N#U7S(*S+nzLw diff --git a/TMessagesProj/src/main/assets/emoji/0_1079.png b/TMessagesProj/src/main/assets/emoji/0_1079.png index 6cfe38744bb5f5609ac5096275bb79dbf0968448..c7887ec078a3c0575c1f4b41d882bdf30b98a89b 100644 GIT binary patch delta 3286 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 Ub>A1e&;S4c07*qoM6N<$f`E)KQvd(} delta 1946 zcmV;L2W9x#8K)1BBYyzlP)t-sM{rC}J2aP&mz$fHkd2R|q@bCZm56Y7YeHLfMqO$@ zOHe#CmXVcU{+&KMN&UDT}ePMAQwh6ElfEwHYg)# zRZDJKP(Cgvt*xqcMJjh?TYYL^eM&60wzGy&Fjq7rX+J51b7l$I#@+w`0338uPE!Da zbG$G2n-M2MVSmL|-;A&2+|KRa=I+Yblgq6O@tcGI00vn}L_t(|UX+sSj;cTqgbyH$ zhzT(gFqXLpf09We#cc7|~`&sp#L8FC9k5 z#R8|prP`s(AGe7<7R%Lg&hBzl=xMEvj@|b2cD#%f!%*y>tYufOezUS$s(c)Vaz0oi zw!Reiu7BBfmo?|}xyfq$ZL@kC5ql)Orft@qq!L~T>vS)bQgFx!@-m=3f#(<06qM6O z1dbA?jJ*h883LwD6c4J`R)oN(Y2vD>U$f9i!4m+d2qA@!hzX7CULhQ$pJwskm5GSJ zNkPcn3k0D1Ng;TztOntU5#rzDvr-wR@KGU7cz+?JR$lldp%k=F5Sdg-0+mppMMMdj zmjJR}k8zYBQ2+#qRyZQi4+3ynS}UK}$ncUe)*?iu4yVa#!2@LgdS|R$Z{r|s-}l4- zMT7}uG|-nx2z)6aTOrgZ+dGE{G7$;58&2CPF(RV3vSn*I5+cRmw4q-?>z-dYF+dW+ ztbZnHrTIqO2wzfbCoZ#%h=6((frQ?o2}(hP;GEHBN(_i)SlIpALS3V~h7ismVm85z z`xu>8-v}8I)aRB4erk7A$3v4HzT3Rz@V&F+_~D$OMuj392K&sK!x0Yk-C8S9AkD2! z;i*5sLZ<7e-H4(N_Cv^x?2RC~9S0DnL)Fe@RH5I|4%bG%;P-`}s}M{h(*V$h`R zEizQ|6M+QEDP=@hYY_Cm5_9Wq+yx@e)x)~TDq@FuZDijusNZCxBEh$_hog9S@+ z|Njr_%$QDMJ1;$Xkp%MdnKPpcVk{WYn)8Tr4o-#+z&M~CAO=Es=Ll?AM~#O>4}Tr* zSF}F@0YpoSKRpg3A@KMTfz22JL4ec#4?-v1FcJbycIPgWH3!#Fqv53dcT5FK{(w^a^MB{vxA2Y$mJWNDBWwjBfEaWPkxFU$L&6xl4ZmI7 z^PcwwuE%lJ8`sM7EI3`#3K1ELnV9Osx#SxJ%sgm8#{`hUM)`(2II z@aXB#{}^oDYDoxSuxlH?GiM^LI>_v)-SvI1p4%-4HLdM?6V+`aWtF8VBGATV62h6N zuo7LjI~_f@HH~)D)?7c=?Gx0otf-P}8@EVc4lzn#Jk_X%`oMQ|vcoVJRhCgDppRcG zzfJ|iI*?E;7FL2djDl;fR)2ciY_+t~EEbE;ZIB6vSS}VzVkqiu)NFAmlme=?OF%3! zjU=I_oF#!l03ibt#2^A_+cZEpGVA~ZWMstnXd_@4L<|7*;24S+Qf|3bjxZ9z)q*?j z-alx?Dldv6&r6n_7)C0jNMnpu1UL~gw#xHj1M39~-l8ar&H6iOlYg`72pNpUNUSlG zf;C5YR&Kr@wceEPmE64}*6U54IV1Z6I3O7_ICojT!KH3xdH0rPnImHjSBp}_>Ea}6 zfIA>nkRdImwRwK(i9f~SiVa*VvAH64iCk%!V(=?~fG|4|I2UtKmN^IsY*nm_xcVHC zKp7CCTV9r{I5@@0#D8j4!WAME@qo2o8(A*LF)i1{N{AIn2t>F_m;hlBtSmEwb0Dob z5XFUYpf{7WLkwQsa>nLwgAu}BB0!x1nny#N3J07*qoM6N<$f_s*QO8@`> diff --git a/TMessagesProj/src/main/assets/emoji/0_108.png b/TMessagesProj/src/main/assets/emoji/0_108.png index 932c1a5e08cc5e29184bec3ad64102ac66a312fd..78e5012ed5151030a2807d829d0d78f9a746a72f 100644 GIT binary patch delta 2403 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 delta 1811 zcmV+u2kiLO7@-c3BYyzHP)t-sM{rD+mz6RsDwUO!M>adArJ$IYlzeM@ifxflJx!sZ zoq;)&e=?CgF*2T>nmaKqIx#dxH!?aiF+DRed^3)1CVnm|DN8psZZCZ(2QYXliC057 za3_F%E|AA#+f*K4m_4evRm`VIyN5HGWgv7g8Y)5-Ox)AE^?&p0f^l7wXAp8>Q=yT2 zz@tz-I5=8RPewmK8Wj{xMMXCS!)(0_Cm0000PbW%=J0C?Y3Kl!8(G9%<*(aptPzTkSRk=Tuv`fLStQ2+o1 z^hrcPRCr#LlYfhjvM>;Zms^V@vaBXP#`In;>hAykPxa3XRWw<_JtR<|d_8kIe7uyb zGm*{1LS#iPKmMpfv`yv349hBCHLds?L<)bsUJ=2{D!OUkM96HOST~5MQXw@Vs^W%U zN7ZeUW@di*N)nG8u|!+1CD3@ER+cRyZgbN(`SVTjI)4B%d@H%AuFWnXgy&cmdzpOU zp~APza$*TE^9?^uj*uZsVUU_|d6{CZ0!-R_@ZmYBp zSO{kVfPlV_E-%-Uh<(6mj35B2H!vu&fruXE;IP(}fP@hGxDcixm^jP~azXr~T&sf+ zw2-DM25QmKm|o2t0<%ZAwy#GQ1By)~!sLuGc47u0kl~%>~Uz9(v^+v@BgW8X5yrTYyY@MN?S+cU!R#g4z2vypXa%Qz&=P9 zA;`u(A|MkGL(Ih)0JPtNas<%TL*70RQx`!3c-VXWn`S`(5CWVm8Zyw$70)2pynj9( z*(I1bx1vK6WI>)$dLU?8Vt15X(OoW&$1R3gK5gp^27&|$91R+6SXd|px8b_HiJEVp zz{Vt7-qS3OIOpQ6H=(JCsc0IQvn%5nU&XV(9^MpQ$a$7!9U-vs=`2itPa{G=9gqCr z@yL5ojR@9WTpF}B(m||MD%U1AgnvLn#`)^oqrw_pFxGUGh~q(izsbW1V*!`cyMw*G z;y^^h7%_tXm~ezfV8e&~;r!<$fBv?p{JWO##_smHQbsfl`_x9r2SoP^5Xb#dO8N40 zpW_5x_qmk%Ww(EoszU@rMC5-u3D$@%1%$ork1s&jIm8YYyZsRirrj4dLVw;P8bq|f zFvlI}_G%11n!^oO2OzY75Y7g_w-MBQFad~Eq3oYiZnQh6CVxK}1xi!2!Dylr8!I;n z>;n+3><_wj(EuM9P9JO$d{pa%`m!c$<<0K_=7iIUq9vAb}VT z0hzKAP>$f#xo||@N34pfEPuWq%JR7v+#iid z#K;SM1vx;0rLMLfJBbJ}LIx*o3m7F)@S`JC_mxF7P80hW?$%k8PSoBlI>u{POr1x8 zOU1gVs5=5MRx^=)p$75;5LaDQweMW4>jEJa5O`LX&n4?VCotGr)qmWT7vMM?#tC2& z{)(#Hwih@3NB!zV@mwN&1nFS}fMEFIgBVHGfK>HzZ4uG17YV@aprzb%Tee5v@jsQs5)8$tK<`69X%&q`^0N zD*&)vuR;PmK>WGy`(e0Q%uJGiV`CSaWC@=!W@c=%Oe_HOY!N|~`vCY_-aPQ;8~Y<( z%!7dbh)RA0v0cV-Jomi+^RJQjZ7c^+0PD~7FL`vWyeIrx$_xMi002ovPDHLkV1fhY BMfU&z diff --git a/TMessagesProj/src/main/assets/emoji/0_1081.png b/TMessagesProj/src/main/assets/emoji/0_1081.png index 2fcfdd51833a88e84f4f61a30f4be9f5c27455ea..4f47a91017fb34d1d2b4b2a11497617c7e449dce 100644 GIT binary patch delta 3083 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 M07*qoM6N<$g3}x0B>(^b diff --git a/TMessagesProj/src/main/assets/emoji/0_1082.png b/TMessagesProj/src/main/assets/emoji/0_1082.png index 18aa902bdfdc01a47976b5b1659f52e18a0faf3c..d877b916f67ac6e3f067dfef04c7ab639e715d9c 100644 GIT binary patch delta 3108 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 delta 1993 zcmV;)2R8Vq7}gJvBYy!AP)t-sM{rD>oSB=OnV_JZq?e6tVo{u&nVXM-rKF>wkAQ@O zfvuX0j*W|NZ*NOFAd!%dkdKWoD=RiIEc5`s;#G&G@iQlM$%Er5KadFI;c8Q6JgMWjAj*gD%yqA-clls%J znwpt>e0=7xh;wmq&6{@k*te^GUHtUr)v}M3d}H?E#F=9jyO(%KK|v-WA2~EMO-4qs zu&zTrJw7-%Qc6o;S68;Sw5qD9T2WE*$)+J06F4RppP!%Qw2%`I4V-UHNHQVVp>>90 zM7xGo0RaKJx_`Q0LoDpJkKm|*_0X>F!k)vAYHv_EXlG~hCxm+d001X+QchC<&{ygx z9rNEI+dUL)>JO*5(%P27%` zj)ZZKTz_RghB~ren*!6?3nyl}w~C{Y;|XGqw;h^^=SGfV(^hvnUOe6=|Ik}(6nD;S zSf(l~x>)D}ar1aEot&>6UOVf{$GY~8y8Ds7yoH%){9J~dK@_c4QS@oYVjfQH%%qAAPrk9s#nvWaf|k$bk0%Jw4H0ss4^qnQMD^p-B0f4m>A7M;n*JO#7LMfyWU|=1<00iCG z4M9@m7*i@0q6dUQO1!cvwovATP~{j9`s$%cU>zbaS*M`#jP6?+*_wc+f%`rE-=Vhl zNPlY^E2R+k_joV}X(DKeHOUt8g0>3NgQ}85>}NlGi=e zf^!MA9cw0-q(mhV8UWBMt&nyFP)ZK(d)jU{7{?WgjT9>I;rla@pg4EfyVz1mB_XHX z!-2wQu2i^=Qeg6Y`muX?#DXyZrUhW4e1CB-7}BqmN_%+x^>eq|J^dyan8H}v{TNGL zug7OVUr&I^!_%o%?7qD`65OAzPC*F4I|1u5yF~f`4;P zcl&G|9+f0fQAF!?fw%EZue(XF;&?%e^^Ou$b2H$kY4VyiJ1s#q=^ zlS`SwvMBahwWwJ&WLVL4v*A=K5A@JaYWmyheU`QJm?`lGXF>n7$ zU>6km3E{3*{6GK`EGvbc1;Z8@J$K3%Lludbi(H1KP$sHeFi`DsfdUVdRi)JM^_bFg z!`@m}JOEj`{XLPp!W4rM5X*D83PK}2BtKfs8ohn` zQ%Z5p$l+3iG74?;x71I7{B}az3?u>sqf7i4~*0DnSH?fFq1Bv;<4ESy8qCdp;7Gy z_aosAjg&F$x byzkaO6<{GiR|2*g00000NkvXXu0mjfOM}C0 diff --git a/TMessagesProj/src/main/assets/emoji/0_1083.png b/TMessagesProj/src/main/assets/emoji/0_1083.png index b32117970ab9b3bc221d1e3d561582467de1dd9e..392532a5318719c71e63c3eb4b4236dc913ae056 100644 GIT binary patch delta 3123 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 N002ovPDHLkV1mOf`EmdN delta 1976 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 delta 1725 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 delta 1655 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1087.png b/TMessagesProj/src/main/assets/emoji/0_1087.png index b9de8cfa4b492682b603629ffb74d381e656f2ef..2a3aaad75290000a1dc4dd0fab0e9a0d92d37f6a 100644 GIT binary patch delta 3049 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 delta 2234 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 mQ(QL(2M0F@z!^jTTm1*{Z`O~1Cxjg6Cmij_!Q ze4d_~7f^{sP-vi_oJT-F4nTi1T8Sl1gX_<+>b;ro#iBelHKU`TA3OyuZg6io(eK-3V$qP2sv~C0Tu!QBLrQY z9%`fvWuyotSqBn11{zAxnR48wfW3}w{rBZNBM-2CTOt(?jb=u3PdpYcSetKFS2`Zw z$Ef$}&Wv6VuZ0!Vw^B7QFGfE;NkT$SMMNtoDN;#EJ2f;TARj!?tPdaaJby>{Lr;Om&NS9-r$?i29k?5Jm$A z0kMN;k!;CwWDSb)BGv1{;(g10x0&~Ufm;n1lBLR!lS3qS=6=uw5PS8DYjUmU zpBTn<@U(edkYIpKTU<*7XoQU9b4K7d8CHo--r;_|ETc{16B>BlM~`>qW))4s-{wfr zsV$C1Ka3i`_fQSy0H_r9XqifwgD<>zklW0lS$MD_@961^=x@wBObcmRrm6S z)0vi7dNi93uhIUp3VO3UAj0gkEZgsmpmH?yE+TkS1tR-chRMqa#Vm2B5w*e zjDJyr1SvKB$LlbLQj$>0n6Sm{&ngfEfRsc`J4he`jR|Fx)n%u!2#}hc*SO(|gOrwG zA(aJdEV`sI1Em10hb4%r7%MdZ4+xu{odY3MLkMw2K_|15#P9zF?mwBdx9D=*Lxm zl5~YvpVt&&{PZ-><2ihuR?q9r^L!rXIcyKVJp9S|_cTo}lw+a}_swU-zkhvUNX!Bw zl$VL&2jN)UTR&{rs%fSv)Ht3c2zt|H-iAXB>Wm>gE)BSvgq&i!x%b#wH^I0#KB6F) zy0K=i%P3;_CHUp9AjFbzqr3S!nlp-4EACBoVVqZwCLxLG3+Iec?5{_Ee+$A4!!F`@ ze)s816g~NzGS}PNhOF_^5`Vg3Pd76#GXEtAf*bC~BDo(0L3Eq>IpdST5C~mP<9HGv z*u%lVqYV4LcXRuPUl2I==QlUE$X_5D_J%+hKpfVnzm^yRanBe-3xBcj{S1Q;^l)zxxBwLY$ zkjmRBPptk&nJt-?MSr5u6$*D;1^{=)qizp~L38`DjAbSDSK>11OF|+;ARxcN>q%;}Wx(NldvM zBKIK;LkfnT?tk4l7r_)$mwS`ta^krhVN~3XV`pDHZou-E6w1_EhK#;<ecCqqIIrOes!t=fJ{5rzqcyyD%Jn^zg-cZM!V5a zHLR*yqtQ4yX}24i+Gxk8s;agX1(y8JC~f8B*Af=LG~oK@`3HC|a6-TX%t!zL002ov JPDHLkV1oO>@9zKr diff --git a/TMessagesProj/src/main/assets/emoji/0_1089.png b/TMessagesProj/src/main/assets/emoji/0_1089.png index 61f90db55c0b23864609e56fba8db2f7d1938360..59a856f0d371aaa0bdf8e3d866bae918ba080b2b 100644 GIT binary patch delta 2956 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 C)~){l delta 2145 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 P00000NkvXXu0mjfajeF4 diff --git a/TMessagesProj/src/main/assets/emoji/0_1090.png b/TMessagesProj/src/main/assets/emoji/0_1090.png index d0e877272635b42062497bacde6acaf9368d4e6c..f41392bff6aec26a4b997f9499fd643d4a0308cd 100644 GIT binary patch delta 2921 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 R-If3V002ovPDHLkV1gJ2*Hi!i diff --git a/TMessagesProj/src/main/assets/emoji/0_1091.png b/TMessagesProj/src/main/assets/emoji/0_1091.png index 14c62fb9d5730459de8d5cd032ed220da785cd14..acf8f978fdc00d2f07b364452e2d87ffcd5ec782 100644 GIT binary patch delta 2961 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 M07*qoM6N<$f-oghNB{r; diff --git a/TMessagesProj/src/main/assets/emoji/0_1093.png b/TMessagesProj/src/main/assets/emoji/0_1093.png index 6032ba10e15752eb46b0f39d8e5d527e9fcd66b3..6a90a9297a8cd57c561976d03aa900bb122b97fd 100644 GIT binary patch delta 2420 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1094.png b/TMessagesProj/src/main/assets/emoji/0_1094.png index 4851f8f4eaad5e22eb852ca884785ef4121dc391..968164193d587ca228fbc5e19bbf13cf356cd34a 100644 GIT binary patch delta 2334 zcmV+(3E}qk52+H6B!Bo&OjJcja7>@!$)V@b%aCWH>C&U=(wyecqUh3{z^bU<#h~cX znBd8r;>n-o&&iHtsnx!n<C>F$&7bDan&Qi( zC^5u_ScNn)vJEr6gJq{3GS{hsz=Bx5x0=e4X{Tj8-nNj4(to^fA}8FplD2Mo&!&Hg zhk=zVFx|kMwPt3v2rsRQZIn_zw{%PC4??;OG`qv4pjk$=3^KCNv)T_okk-G`m~Xla zGnmM@skxft4?um38IVF#ua}paSu=t|CW|aPx_MCPLTIkJQIxb1){}{(>C>g`)}ZCj zr|;R%m28{h%YTN^xuomV*`|MO!mHb?hTgP|$&O`v#jT;~(~;W4sOr_yop!78+``%P2>8%CW*FKj_AviPgP{w49t&F0^b#vL`^J z@7d!hOx-9;)eJlB($VeS-J&No&Agezo_6LAK)ORl%YO?vn5m0$x1W>@C#dAe>cqX{ z&9J)%G2F{-y5Fm=d{?Q5XSk?_#IKCJUQxl#uewt@o~RA7Qel6Zc+nj})PZt{P%fsL zg{cxRk#BUMNLaqskF2q(qq~)wa~X%5jecQMw7xdyuA}R>uln4VeWV7|xNdj7NOr)8 z&`K@F(SJH@-&YO*002#NQchC<9OVw$?qCR{zWAIfwFbWX;H!(SNxOy zGSG=)`{Vrk`&+`jgGu4(Uhed&Z}_O|v(mBB+UWVn%agae-oIJ?Ebu+!000J) zNkl$8phEKkPt$I5O-^m`fYFJ`hWU%+;Ml0yL;XB`rZ9E_dUZx(tb+Q z4g2sLob%;*bw+ho)wH+QsH#z&Nrz!N)7c?vlb)hDj`Hg2&PZstQ=B5)t2>hqL#v*` z@DjsR0vK!S)P~O^7|k4kV_Z=Dv(h?xP>r@Cf zFNTxk?#|9GUM6U2K13+h!YI9|#?W))+RO@k5C_>%+q_T-jBu~Mc9+jnred#Q99{x| zkQIuu4_>;oJ(El>gI1PqX|;Xdc%c#`M-UIAROvLKsV$D2hQJkJC=3$kaFXK+mVYmM zwv%CxG_mMOt^{s1nO_A-AaDfsFbD-ih9LW;-ZTTXR3vmC7&zv7{zJZZB9)50+do?N zFa7<_xQhvbMJEFY1VCYQl&V*&0c=@HC`>T@_QmqSyT#Pj(?i~Ww6fIv)a44IP?(2K zf+Urm&>YWcE5)4<>E!Sr>qt!I?|&RDq(GtGXWKL5KGsFz3`sFh@4^X0&^MfzoQ{(W z6b2yHtS^>Ru}~-$ljhgApC=MghGZDhX~``T1ss*G^}X5Az0bgybmHw~{#kEo@5z3u zcYXc2kca{R*+0x3-UJ^6)@pcvdNdS=BmI}bxY*2#?e+EW-o8j@|2p|P<9}mNJ-EVM zTK3S_3zQzU<%bgpg+@{+7!&nnCg1(g{bI;JoEuscQ#YeP0K@{F%N9YC>hs4?+ka})F&jXj<<+N; zA3r`iI=Xl7Z6=(9;$#E|>$=^bI#t@i3n9@11Yr$sBmHY%$n1sbOv1;eVPxA*0W^*D zpW^|rm=T1vTyFT@yG9g~>t3Yf1FJA72D29xo$Oxk?#{1|?aBV-WPEyRe1GtG*Lx#HA5hiG2yi>u{p3k^ zcW)>p$=Uh&{DVKK%lWp!&!C9SP%)5V^Bws8**!^;c>j~Jv9azemyeCM=p!I~qpE@$ z+{LONilWR*l1LB#<^1`+&d!s6S!dRe8nkvQ_XW}ddV~NW{H5Vzry4)?p4);Dlx0HX zc`%aubAPAmf0ogV6NG(m2(~ZnAHLG3I)jWY9VT@bx}VKv2UKShL|-q{;o&RUaJ}lx zs;425U4FSr#Q82-?y3rLwR3 z7*$EzAL`duhiE#N`ad8pREaQ*#6}FN>ZEP@>=(BB4?=Qgz+BTc%m4rY07*qoM6N<$ Eg392<4gdfE delta 2024 zcmV!sB9vCuT!}i z7#Ix-3KJ0#DJCTa1_vS^9?*VZgk#(6W(`g??gUVyvH(ZfQh!P5*f-P#H;1xPf&RIDp;`;p`!}s>gVt>4rU~!dC@na-LpHBB}Nq_uL zIXkU4F!huF1e`Q#?QW+znKYZ1oldvbIQy#5=r$)0>yHso zK?jlA7uHj|lym^X`vB7K)_+@QPKe->G2|Dc^P7t~?~j3?gUQ1K?8ZCjw~fZ-cs!9p zkU<~j@qbV`U+Hn$g_kse5OUD(H$i!Ga8LW4)6X|z0=M?1phD+^0V)-PL8JZI0jYQJ zJ|NOeP!|kTkZB?_0iu8Y3DIr>Fc=V#X}PX?R7_c?2}Gy<$zJvW7(_%*G%aUnL=dGY z2mf9BxP*Giz-4lwX#9Y;c_Hg#-|{}hGE2r zB&m$lCS%Zux@Six3Ivp3q%h6)5?jYvw)848>AZnxgpPKAWid^%mFgmAY^_vF|-q?C*#n(4)XZ##}N zasaUrQQJ~vQYZK}?y;j$dvHH%L>D@=@M357xLht@cC%3#XEw{1%k;&W?Vtq^I^hQoSAU!6 z5RrJXH5$!derU7V$oWZF$;%IKnwCWQ_)tdu zP?4yWl!OCRb%{dYnYo}4odMChx_`TaO%OJK(4Yy({1!Y*b zeRbFK{p%J0x4mJn*Sk^#VT3S-HITprCd9KUA_$>G+10)GZ9l%gZGkkz__s(96{gE6 z)+pPDnr0e`Q}b95s)T-Q`+i{bdP5Zh{_aXbN~u1qs)l1(RuFm~3>mIq8GleB)fseU zd}l)m%&>~zYat=aK#x@jL$Qi%GhMIm*X#8rTUd4wd%4b3(Yaq{_$CZ*U}H~#;GCmD z**u1Xw_xZQ3apR&Y&WrTCaR8zJ_ziD#CSL?joYbA~G{Jf--S9O~sqwx~mYT7~WsC z&LHnUWG5#(llra<#a9>}WoB4dxJpcC>_?rQJpMU>+UTHsLYSHuS zGd_*NUxn67i`y_11>jEeAPl6qU{VM~FUxw)qEP6fo6<#RTe>wu|Nm$7_}-+NxHvsv z@9xLB(neFzS=3T$zg-ZUr%xYvnQxQG&IuUv3jx2M-=|t?ncyQud+SH-q`15R4u4<% z$LBrfqYhf<^7 zvAYv?J%nM7;xvPih#HTHQw&KBZwyep3lIc7W}-eIE_$>y&dNXp3?Qt;{}G3?Hdfh` ztOY`$8f*Xoaot3&5nb@sdJLo+q1f<*%!Iom@{-u}A)$7lYZ+c%SZPMvWR=+UBM9Ky zBntuv6Sma=F<~2Pi=3jt9>Gb8g%laBh6llS@{rI*fylLR4a$w+7S|f9#3dwUjh3}U zW2|C<2r`IpR70$tMHkYbOq8|8kq8PC-uu==%&!Xtkpy<(?(z~SU)12eWoaN4<L4!-=ttN{zt+c)V?oK}DmaEAP?JwYw*}#HFmm5_-fimT2(T0000@bW%=J z09)nW2Y>HtBNQ@okNyiwq9l2d{ybUy)4a<56jJ?#uQD3_%#G!acKhhYX|?|G)Z*`6 z{@m=K&$8+6zwqb#$2j(}(%tX0Z^6HV^47ct$*ceX27O6HK~#9!t(S#&8d(^{NeBc2 zGz1dj*2Ze7Y~8(U?~M=c?izPbn!3yCf4bir2!Gl1gtQy>GKa&NdG9y(yH9429ai-< zN9twOs97U-Gjh%0A@v#s#x#w&*5*SJjfh4I!GLiZ;v)QmBj07>p3csJ7>8NMB2zZf^{744o+k zAb%h;T|(5*h?bZL?}c>s8HNppKH0963e0bB^Au@qCPuKFbWoM@C1){eRjPIX!-o6U zuC0$>IA0F3hr;gdr%$)t^iB`lD|ut+9We}zQG1OPY`?*9e{OtyeDdhg^W`9Ent%H4 z-G?%QMoOs;OqWGc!b~rjFvG)-<^V7WjDHLL5}}ua2&g?S5Y+KCf+Am7p{dsyhOdE# zxk)%A8>%*rrg#dmvs$*?9&3srn`v{YG6qEQ#<=yQ!7w*&+1e-+3UiZ>be(S4zdOJ4gU6E24-s+m& zuq2Hgz9rL|E%RmW=uwl^Dw0z8m>E&v6$rJv>$C~)5{jjWj(B>+a@rK~`QXURuTS0$ zI;@nLr!b$?f(1fQ)RYMj_AaAX27e%?r#CFn9T>Lx`Sn}rxJ#r&n3t>B6^zZqt8&lU zk?&`uzMx zBw~wZuaC^mI7FT&?zK4~6*Xb3ARfM6fe@rLQc|X(D>yT9>q}u{Fp@R?8h`bMv{p(A zz?91_Coyi{XU9{wbH(`rX_px3v@^DHBN2$ELOxq)l_C=dtqIxJZn{ym@0Qxg6axW> zbU>sruixhN`u)$JuX#gOilR_=I1yNFKT=m=PgKe=B8f13an#VN-xhlQ!nd^a?Ah}U z?+1i%cSl6fYE%d8?LBf}kbgKN0y6n+r1!JmL8mjeKk;fRkh!e>#si|MmElln3)6c2 z-nY>EEodo}5NvDVKp^S-8B81uQMQdDgkV?H`n}=k67+uY;>G4>hcOYzL?SCQ>EMs* zZ$2l~O}%oe+vNA=gqUe_b8}*1VPRo5X3QEB(V28SXgyvd`=)d!AAk7#DM5%iXC@XF z7Zw%^3mxfLWLcO^2OTb}II8>xKtFKeqBoVxtjtb3r*nzy;zGihOTzEiOi&_-%;=E= z9SoecrBdOQl~~+4?VJ??0w~up4I&m?fZ!>%R$VcN&aP8F+eOprs@3XnI-Q?aa$Y~k zyXGVcx~w3Pce}av3V-9$HE=8yPI*m8w7P;$=k(v7{`zS1+iZUSgX3{$JRXNK2!Uno zT+jZ9zM-putAiJhJD@dG@%h!0Cr|$P==0fZrAsQ1sIp`qo@mCJD_ z`8d-_%c2D!zkz=0yhpeW2QeWbxW>AQadaJb5XFNtTON<+Rexb|@ztk?5B2qD98w{~ z1j_;fY*dnx2Z=71V`6;D1DcxJS}gq1B~zbqNhVm<4PsfYsiKQE&d$1l0R+(47#yCh z6M7jiAWPC6Jg{J-(xAxdYdO0eW9>pH!ka127=IuLzRfNLLB63?O{FO8Eb87`w@5`005LIkLRES{U^&779e~hq;Iw;o z*+O!(SUh7A;;y>sgU6%cie92s=?xtH0jIqzO_9R{_xu3{mQOKv0($$uNk`UvEI_~G2S!7jMATMTFC zMk~HN*AS0zk7OiywuXt*Wdr|TQ)b=@^WS6&9hd@i(T{j$vO{5F6s7bb>KgV z9y07)cL&5k2-o$p|14Fn*^b&z4tk@3s9?N#M|KFQnr>_AyKaOd`D{KvBs-iSx&}c= z+`O4jG;YWaErPhz5)i6EKn{<)1fiuW#8v%}a6?}OA}m~&H5>yI)gT_r>Qu7o5X3=s zi0Dw2h@n)pS{GORgZ_;>M7vca7h@m)*jNdnt?F&yV2Dk6jjR z=h(B~&XD2LncmBh?6rX7zJ$D>SZX1B&$@BgxO-?JdF0NJUl(!M#(?6UdCQM;cO`~b z5o*znbIX)%!h~&#TWrjXbHssfxtDdROSFM4lZrH)qeicCB!7mMKc;9Pe3CezUmSFu zL8(v`Wv^4XbTwB+E> zNrqJ}x0p`WrG3tnYOQNT$ctjNbxXgbS-PH7z=2rR!gl4vpLj|tyn9jZwSUB_U**}6 z;M0WT!JEmkWq;+UdhFx2bx};XjBiRN5`u1H$H2FzoRMEXJoNPQ@w$zubw-tKTlMkR zDhvdae|V~USNQhgrGsHe6J0nJMp_we(f2^W0000abW%=J04F3$2^2T}{-5gn$K-t9 zjN@J1yOCnR?D(a;)9%Gh^?tp#I!9{F000JRNklbsT&ki;=ZYlRmUv-A z2r+;tM2PL5mY{dlVi1J^g;FS@IBdN>+Hwu+YkxJ>Va9hug_5@+s5Y#>UINQOq!#mi z!|qD_WRxR$YQ(Fx*J@NR(iCqQPWam}41Kw4vq&8ha)^qIUaQeog%pD7@P4nCBt0KR zoODQtdH`^eR|b31OhM!&k|6McAOXT+6-W^x($UL9DN~8jkanUMcpTydJ;S!y08=Rh zB7fB8$%_+BCn%vh5R$-i6-99g@nx9}&;+3tWRzbJDop`|8Z(2Y(Uljvo+C+UbY)8* zr669KYx!a@5Clh({oAJn$1OhVng)fC(7=!x9|;5qg8I^3{vnN`h?i_5;dE_09&5+} z@v<(sA}bzDg!H0%oTyJ6i%DJE_Y|$8b$>dYF_I(21^KvR8P7YD(TC$(aUNMrw!3nV zQx>cFe5JrRlv&)(=XXybjfb~*Cq2FyrS}e#K^VbewOMT*mXDjl7;BHK&Ev!Nu?s_% zm=jNqkF_fBG6*|N=Ih7h>fzz@T8BZ|the*|!*ac`L)n&KOfD)%cXPsskdxcZ4u8PI zlHaX!L0j*Z^ap*n@(mCYA06M%vsjWPndZ^iZLmZZcIG(GZa0U(8ao&FnS{h?`RG6_ z`mZb}oYHAL;Y{XpBLg}e^LZ^vj$n2;421|@I69JZUOEsuhN@*l&5d!V(b4cyJR&HQ z_7UOahDn(bdM<9u@ek=_(Lfk-Mt?+SM~KQh#u(3Vdk3g-Fgp1Ug5m0l*DDCCew5%5 z7)B2@^qkP>2rUyd-3>wrIF-bMsC+m-%Vt|Dmnzj09N$@%I7smdyM8tp+MUKU8X()=(y<0369A0Kf6*S`VN>E+eO{JwZEP^d?2k-@?6dcNWJys6^m0sw02VqK9-?)v8A34nqqjL6Bx z!nq2TayZbZ-Yr810tDf6(8p4ayS~2p^XgL-z=5C-XQa3k={E5=mwy5#=rP7yxC#J5 zdN=3LpIdw^RSwG!1R10ZXtMIw_LIQNztTc`DHQ_V^v9R&>h5m7{rz7bIcchrLWX0^ z|N6Q$5I_I5{Q70i<1$EC{9RbR^EeGeVHm~`GE#~Z1`~w0SP7rGUXlU{A#Jy!phXG| z1rieD`TxIwbLOIn@qe0qUHkDjc3}W*eF*W;-2gk9aeVvceKLOhx=1N48jmDAe*HYp z!FzxGLw~z3zd;GbL25fJ2|`}(_pd(OU$kTZz@(qAwBd?C^i;Uqe>}b$z$76y;+E=9 zQUUx!UgpH>)(48a$Zj3U_m7d?X;ArIksNbU)u zTM}aurfF?Zzk!EZWJu^ZmF0JOuO)Dd>NX9k+3JK6Ylo?bbs)0n@B8EzMW|UhI?VH%B rH(uw+-6RyVji3ra22{ds5Ptz3W~5}W;o9{80000=Fgtu$(`WGn&8Q7JS3LguyH{rqv_J2=+ap+ z9hu?EazQ7IPcD=?FQ4Ymp5@J=>eHUw$DZcUfJZK!<;|by(V0g&qUqCPIU<&#in0we zq36(_<<6HJE1>1jcSR}DqnKMWA80!x@DW9Nh;g$GFKsL(iht6(uxNDA4m+`9Wwr@0 zzX~*VB`}LtH-=L*eoQcrJW7jjBb~97iPXK9o>ICDGv*>rmTXs@+rzUKHg;b;p_Pa3 z6-a`RcchAkmsbp>yt0UeBD)MUcb^J!!>Xd_(WdR!r0dnE@Y<;A)t}|ho8iiUNiBOs zD2`Y)WjZ5=(SN#;*}|si(uYwntM1v1)xM+Y)72(Na=@v7%CcoM98f74b~q)=Cq;kJ zxN*s_mfgm5N-wS>I-Vjkz$HUC)XOOWh4U z<0wtQSVfvd=FxZI(xP+_u;g@2^ezo||xj7TY;1}LWG$bzYs ze`rjbG(PbuQI3-p?$gktrVjGq2FCU3dR41L-Cb~Z9hd8} zyZ`K->dpXnm%uD}lV5-7s;A#0eJashS1lbKEq|J3bfepZkg5Cn5Z$1W!8DB-(~WBq zI_wM$3ehxUzm|_yi;+Pg04R*^PXMi6uWS80f_9L`Aw+`+2HUkNp{w6$G`TFFV@mIW z&4>$y6bQmbz3ME)V2l~s)c4kyIEiV_d!i>xUn<(CI@N zo8k?absn1HWhL+4_k5{PC$*4X+p zPurpc9Mq`@L^znScTP{wEaq}+`L(t3;y2FrFaI(dqJco;s+Xy+R!a(MG2)OSgyx}M z0OSC_d%JgLA|d#*S;IuR{Ec<+C!XUtAfRdnE3E;J@u%J#1gcsj5Q1g%TnJ@0AAjVj ztR$@zizoTS;1dGWc%Gwc=3|DLCtfXocy~<9nG0YbJ{aBD zEF1`u9H*qjL4Fem0D!yfYW&?VZiFxb!g+NN29aupaRGWEOx|TwMAy#q9}Y1yT2z|k5T^BY%F&C4~zDy zbFR~6B=OLUTM!N6Fzg;)A6{QC$uaUN&ZSe2^;ez~dW*}1c0U5aFut?CzP`M@yu9q* zkj-)|yOEBjypvs;E9HFhToMhGp_-msUfzT6{&Fe3kp)63>Ir)JFMm3(09e}`_Y;Oh zqPP)>%&jEM`+KrkD9uIY#*b1dAY^!C?6?fj-gZwA#cc7oT1iLX(Xs&~9s?ng20)M? zIM$?Z7(x4xLlW-0Yc;ReQ;9@=E5hIc?XN~am1xlGB?ROP^f#!>&|QZh3gXuc=MAPR zk>CFP;lo2{P|5FqK7UyOMM)SL&d0KWK;OlPfl*5C>A5!DL@gkgD00hCi@EL;jbu~&w zfW^E2oX9~G0Dl3%i=||8>9%TGJIDr38K@DWI{+(o-FI@yaJZ1qB_WPNcwtI^`g8A; zfjSyw(-wfcv%WiP@wd6PxY;0{B$EqEQ=Ml&I$?prFzPQuV0QCuJbouG`~8BP$met0 zU+YfuZDRv!Z?!fGWR@kG9goRzv!5X1Z{OZ|@cd6_=YJ;z18P_hO&6;oVD?fX5Dey# zn>PonR_FPu*-V@XLc63dSYP1xcY=@=fFO@JFIsi!KZ!m}Onh-)5CuV?%sp1k|1GU8 zgt7gJfecUC+%urLhP0OcZrz_@e;hQTxt^d}ZN!2(F1Kl}tu_NBa!96{MBE&rsG+71 zJ=RgG$57f7VnoyC029q1M&Ve|G>5oJP|dn%PNQPeE=B|>MpJ5c_#N%dA*}bL<`FB+ lBAj=nyP78Dw0^dU{{XiYJAfo1`PKjc002ovPDHLkV1f+bSmOWy delta 1905 zcmV-%2afpS5&sU5BYyzxP)t-sM{rDfO)z;rWrI{Ve^WDB6KjWBJ9|h@h*v+SfM;qR zdx%*$yozVQk8N2q7i>Wzb0UM7ZBS($cA{=dX)#KEE0Byeo|HVJTN!V2C5NI#uA4xp zr%JMhFqUZ`ePJGUt4_7ARJm0%9b-Q%NGA|rIUS&FQkZ8=P=75HKOqY=91L_vD8Y|v zvwU2CQaEi!GQEmrt8`RrKp}TbHp7%~k6=eYC>VTBE4YMVgj+<3S~{V3UC5etaZx_K zp^vtggt3fv#*}Qzp@Dl@L?H+Rgl=NTy|eQ3@@q^vI~78afOhBF&7*V}O%!3kn>eEC zk#_(902OpnPJdGXz+9+|<>DYf{=adR-{#uw?UBO!yiRxS000IoNkl!8%f(``gsjG*xO2Y_DMpAYt&t&u3?vJ~F#E8EdmlpDHf4%ZN}vei+59IG+3zU&u*RgSDj;AE5`h%~ zqKUUXAqW5+eN^Md^C~RCXb4-7MP?D6HCsf`0DmOAz7)5z1fE3J$Rr68fe7Q_8KEFV z(arUZdTCYJF;vtPBB<*C5ngJR0s;eNk!?XU_v+pDQfR?-Nl96jRKztXfP|Fn3`w(a z8)kSI(Y3w08RwoybV=yE5S=VyKaLTR8KG1$#Z%8ik8`fHDI*d4>-E})#E4j> z$bV?5HB*FhO2aFYj8dhTHioo;zxMOK2Lv2IP6OeR8G|<2?Uj{s#f&i}m4Sc-Y{&h2 z=mG;J>~;;*J$e!s8DWS_lq5S?M_A>@Au2s-SaC&gAtNmUaOlbV?&Gi z;kDfF%=l2Rhl~$&KHurXl2RbRNH1T|34hl{!yH+=Jnnb9olcI+L8uQ$2EX8o<2EB2 z!g%FgJWZ}4rVPd6xB#o#91lJc`P*@;je37Ou3BDNgL@Z=JEaX0NxeCU_xIo5-Zq2K zAKnh_`|thRCMc-3QQqX@LfFtE6LlT;xxd-uISTOA!w>ytT?Z{UXrvcc@`!{sk$(*0 z7}j8)ipep3p2KcKG7x-pai`2i8`31THP+|!YXm^3MOF?3xw}MsV@%oW36lhMJP1Io zebjOvgrLAn&fo!rb32_P;JA+CAfYf?)8b6{feh+E;PtQ<9p=zOS9ar0ANqCe05E-s zA08gu6F~^nP@#ZHutg9>Srj5+OMl3y1OTcsKHhBlU^aC?igE0zB?uv$TZ77TjaX6= zCH}cYLo5J9ly6{1@Z$Jp1|pA<;6oG}YWVhDF50#bK>%yU5`&<4ys_zfJR#iQgM&nx zrW|{a0+v$Ka=zd1U*R!V9(W=oAV5_m`vJ&p2^9P%+(tOvi9MriI_b--AxcU z6BslU)0#AZV3I_JN;72z4}U_V+8XWcKmRR$^r{Mtp@ud*YoxF*R)iTfP~s$1-(Ozl zO_Py-eFl$!Km?8NKVHhr-c6e@G%r8MFhy1UQE1)dHV6Yz0B&faRBVb+#=o)MG|NiK zf<>j=fQ9dWoj%WmxT22wKw{-jGmixvLWn8nY=*ZLvEOdqFRWY-CVyI+=1+X&r)j#~ zuJfFc!x;bw(oQR~F^$bX|L*mWqNNasY@W~41xpBESlMj5G3X*BW0+W{>j%R5pj3bo zO`gkn!x3aRR-$iw2YO3EX$~7?ZHy@;Bgq^iL~Ie=Pz29`p@b;LqO6JidWIrs?>Io% zKx>?Y8_YjMUxjLrMStSmVPmeuZbfue;P5iihXiBD6zUn#LvTlq!v$n9pim*=gYZpa zKNR5uVFOtVM!4C3rszm{2uvW=U}PZ-6TVH1q@0|thV%i1m1UEsM2|hn8F$|XcQt_2 zO_K7>F7}0R;I(%U7y-eCZ1bByMex?d5IlrHQtC+*F=QDbjA~5LCKL$FM|eVb7+#E8 zh7k0Z=tw&dHl?8PW=@C@k4mKs7^z*S5IRJYNtZDe1B4htlvSP)WAI0(DdkKGZJanv rxI4jy5bZAd--NHk@j=kCNo*58pX1yZc^F1$00000NkvXXu0mjfjh1Or diff --git a/TMessagesProj/src/main/assets/emoji/0_1097.png b/TMessagesProj/src/main/assets/emoji/0_1097.png index f47a5e6eab64d4def79075828780e462670a64fb..ea5b6753e75a11cec99191f79f754b67a8754be9 100644 GIT binary patch delta 2272 zcmV<62p{+L4eJq*BYy$TP)t-sM{rD<6nh~qO*t~1>C&O- z(xU0pf0uKk>eQOz%Ae-Xo#oD->C>L%&ch8hpy$w?VMUs=FqG0+dwTRF(Mly77sTlAf4mQn&8QK$giX6(~Q-=bHS>q?boL0 z(udKxk=nxIC`=j;3C<)%!zM(5%CoBW-%&(4ff_4-(YQe(A6!d5o*OV?V^>{zYnI){ z(+xV=Cra@tQLs~8Z@8YsS3<1`ERnmVSSTo$fO)vwp?|QXp4f(XfRKe^R!V@gpM{=x zrQyd}9Uttqtbl!OjFk_WTqxzo!}QzQq(m@bl!0uYjHGgAi@y+pUtgrF4RVAS&c3_g z%WKQfdiva#rFb28yKSbU58?Waxc~qFPIOXEQvfpl68;ng{v+^?4PHtNz`rGUi@!wO3O1;+Ox6f=)uU#ecrUf zwBWz6;k^Zb000JlNklY`DQq3eO1rW&EsZ?!rHhCWA>eiR|Za5Wi0 z23hr*G8cmp0)OnTKSHLzoHqQ?2AIq-0D%b7b%dKnw8li({!y6>)84yY@AL%%*l@VD zb$`f_(Lo{vkB|wbhQDwZN1Q{Z2H=_Z@ng^M!naQv0Edmk(XF3<-eTxRpaC<{#-PRx zhM^1`$ulMor0z^;GlXD|!`tX-ufBhxeM7T9CF*=8m>@YJx7RlxF&f$RwU)D^APE4FdI69F{P=&o!)qHB zi!94)3&Y-fUE3L5$1%arf9U9VAiLp~MUO%WG@p4Ng&NK@jEJ$H&LFcW&?Oypbdd{wynj!k@0t0iNhx19oQoM36YKnTIVry?WMZMXs(-q#0QCN~+fo!k z^s8`q|LjPbcqt|~Hdn$c)z^gr5aw0JdZ`Y>7gGYP1xv0PhPCxtphQuI#kI1s63zf1 z1PFy=M_T$}HcZYM1P{#V2!uhy+3EZLp5}~3L6{wi z0U?u#0fLJHB4Yh?Du%wk$p_tY&|m}+*esuU-oHOR{qW(#zwdn?A}V5WB7y|p)%qy# z;7*K0rm*ixr_;Zc&tCra_VkB)9S>s}t)d(afYvfdxD^OB9)F50r&6hOntYwT{NWqj z*AGLQ2%3$OV0l-|q73jX%P2}{IklKtB#~H5r~h#ewv>nSah1`gLqsF3ilXZniLfY( z*Oya?M2)bNNT0 zLm*;2z2+eqB!38CDUnJg{$i@157@{#gK5<%Ha^Nm4t*1zbZXI4_M{U_i|NJ0%-83~ zJ-)%RwXJaSqLI|l%JUR>YL_n;(xO8kx1);=sH;~c-VU>0SKZr zcI(!3ufcq=YF#7Bh`aUXY3IqhiS7xO8ll_qiF7;qFFWVDNT&R_QGg(X-WH}^ddLo< zi2ulB5@Jkuy@2e$00cFdl=^hnjy@4eF-eIx+d@z`Cq;3x zEyQ5&7+HMUK*(aZuCKcd5xSeQ*r#(C+8~$#p*h)}im~hHW|I2E#iN;6Ig^^lm`I-0000i>getZ6biIPqwd9xUpBdLNhHL6%!^J6lt~j_Qx<25QL1wQ000woQchCKB%#r zp)i$D20&SsjHuk{cO*gF_d&ew>-OLI&U5Okol1F6c+S|B`6mKos)VShr*FV2zYLa@+djI!f*cMJ$Z5!Tv$b7l+0AslVH0Iaze%~j7XEa$%P}$ zArMifgVs)`8xD_yv1)(D=%LJoWdv6SLZ(ncKR?~=`X?A3u}%E)ywguT44Fw|lJmzJ z3V)R$C{Z7t`*>Gv@9ao4hq@?sJzj1rMMg3`yU$4?nP}_h{rzqSVt?N;k>2flyimXH zHHZxR%A>RUoSTe^x_sH+RaIqQ_b*Iz-Qzy4cJ1+Te_!`RWX6SO4@8Z`V7ITGJ#HT# zw;;%Pc|2IW@VXsFLW#3SGGjke?O?6NM}Kd(-B<$GEwpWCL0}d5P3C6_NdZx&wnG?T zgF{rx1l7pT5z8x2Wb|a&6W|dao8sw$fEs3Tj<}WzkvNhewIjfg$2@^m_^u$9lhumP zHVA`dK-X&k28Qf;5++g%l@8V$mR12kDIkk*wLWfc0syOZw_dM9PZ&henZWQw+ke(= z&4i!BKp-Q(IUYCmW)(p4Jy%2+A75i^U-o@Fbib8Q6xnZ%2tJ%`p4JmN#VBdG28v^d zx-QYlT3>=1plIG5eSAH%IIaUC@&sX{D(T<7uQYwB<4;#La}@wec>+$`zFmU2N_=4O zD0ZmC)7{~4xO);+%43i~MbnW0;(vps{P2Vjf(@x!Zz!K?K!*|n0BV||z*`5z-iG6& zB?KE>0|r)*))l2rPXhN8DVE!DFy9RWBf%L*kv$A#;LCtLNb0~%L2Phuio0(Ya{wp8 zImd`M@OUudomRaIPDB<)T26u`J)M6NUhy?#)dN9F`bv|23;@pk{Pj~8rGFNaGvCS4 z$w(glc~Jd($y!sw^RO&Ev*cv0B}ya$B*2OAp$Nh_^dRq83)b58jCf1$n^ zEV@A=`=XrC{CG2TLCrF)YijEQ(Ujlc-hd#ToQFZ)-#=~y+-@YKw07L#cc-+|Mh#Y$ zpT{?(s_NpE=A%+74tOyUe}CTraMrbZEeoOgO^^b>F-;-bs6q$^e}%s5{f>E=lFUYW zDW4Lx!23y$|G!PgOhDBs%*pPdRmm^WL;3*EsZp@Y$ zZo@=4BN`D|aFovm5Dtt?=o6xd3WD21h6#!hgp5p>ov0oOLBhy!^nc?bhKg{2So@r) zS`sFN3h2u` z4v1_J!UT+Sq7gxF1Kv#w7NW3`i|{5)*qxA%L>n|#5Bymc4jVoj|2H{pQMJZ9!WGxJ zT-e}qz~CB8$aA8OJzt10Sc^6z2tx8IOi+uhhCLw)Toc5cR@G}aU9N0oLUW6J&{Lue zdUU>C&L* z(wpSXoZ!f#>eQU$%-@z4r0LV6>C?=L6kwq$oaN1+=h4xZ8=dCSq36+{=+leSylRsw z;HDvFn=j9k7}%W~y?zj5ohrq58DN?vvTqEavvR)2gTj#=cz?A)iPF2feGuueAApe? z?6Mx8Rtemt9KF41n&HZWl`W0DW|w^)RC^bIbSZX}GS`_D)So0)j3R`=Mv{3Z?zSM+ zk`KOw6p6WxjK`Lc+QWagkb%&+uApGOfD_oeM1_wxrR>(D>C>n0*{A8$pytq>Nj+4H(0q3z$O7#_fx4W4B91Fu&000JeNklVIgtBB9H{s8vNBSMos_Xhy)t4E-^{ zY-?#YeI3E9R}mJ}nvla>MvWAp_T%nmWeDW`@qjkk04Rqz<9;b3`uw?cia-Xf4hEe-Np+09w^IvZtfQ%hn4vU6RKOgU2N(E+0Ci{x^+Z^!lA+1u zKKk|;(eXbM5PG9X;044!+hI=#jGoeF4S%cn7yu$x7{<}1`$j|TeJBIMOgyNF;}Alt zIi|K+YbjB48^S~YApHU$ry^vx0OI`zXStkw4=zl42G|@@k?=f+NXeW4>DOkHf~O}< z()MExfYG16-7PzvFaF$L*&A%NAlS!agmCD22q6HFcHBMgo{dK8slXmEz%u{W_J5z- z&KLVf&f?=1x@Lmo_*DT4!Uza$r{~nboMmW_Avj^@=xF8e@X(puePkp?!8*?|{COe7|?``CjmLQkod}arF;D z;CaBON|IQXrcw-T)tyIBo!|r4PM_8?sKdJ$c|G|gTp0bqomna6I7ASy#Da3fFnygD z+^2of>b!6OK?w7?en9NMdl(j_b@zJwu*5?EIJF`crqg!4`NAvJC@{4s1b>0!1m5qB zY|HCzMcQ0*XT;=Tp69q!J{ZpC`?~7f{w6~YgGeF*58+`U6quBY>#mHr?slyyqWmJA zN~J%9!*?v^OYU|{4=`$RVE&JCF`IF@GHVM9u8b0lzsQ%$+3=u^uz0894fy-5x-Y8x|0_vZ5`#OH=U@V~FdvDm zt{1X*ys>~k7YbRw1h{@vmWz_K{U%aHKos+@Bazq7CaVNqpt~*uw11A=l#AsL+ebUz zNF?$O!UW9|M5Iy)`27UIv2AtpFtrYUmn`0%%7fX!;-Y2(S_+8O3NXC>90*+CL|>i0 z3|}9-9h9UyDLxeP#}+HEAFi#fK_LVIhBMD7c0-U zw!)j6yX!Dq^FIc>pnq6D*yC6qh`z8C$}~4OKK}h=AQp=e!ok7T!B$ojMdjAh`#%FC z77LIvG(^-$UC1Du@!3EOAl^6oYa1IITN?+Nt*wKJ*5=uO)(;*`umDNG3!siDE2%f< z5BOJ?mXM30cq5csn-W9_ zf{<=JI=$LxjekMJ)j24XF-m+!-+tO9gw5M~doP#ona|wyjwmn)gtpa3fKoe~a&Y%k z(CKu_yGt|FxqI4|AdrNSs#}QWGF^5iMM7{Ul^gfZ&#;9~Bw(~Ub#-JV9@$hr>5R*9 zLXZmgn*aIIF}CqN5auOw!Lq3-KqTYwxGaVVE`mU0Fz+sVO-w7n5>P3{QMB za6x1gbqT_3#6G6)H%XR)QZTEGcI*DT%$B=)^Bi3HN?1{pb~wLRkV&U&4~pT@iGuP& ztL~~IhzH%%;`gS85X0k};$x~2#AtWBm>t$Ng7}>p85}WP9WfFV=X54BrE3TQH2|Rj zgcNMoH9n?xDLC91fqGng(%KlJbuc;DAfo$bym5r{y9N=a>&fesu0clkSDW}7NS|Bu Tw_Zik00000NkvXXu0mjfDJgr6 delta 1601 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 z zm4h%rx!eIDB9TNOKoDHe(l!s9{l{@A;qmTTJf4h1zyx*i91sK;34g>vYcdnlyltA} z$FXriP=v=7DISL{5;^eu{ly}Q;@$y#g(w4*5DW&j!8R!jjf$hAH%#$B5_U-FczZh& z4(Cq`{@lG^$R8jIC_|0~LFTWQVw}Bsb8%@dnMfqS!}0b!yk5duW?nw{b0!(02xY|2=wSYt4HgNYm10Z0!o62=zras`Gplr04G~ ze%ix>W=#ufCV#h~jhwVjw404a;SCqz^ugy3q+K%>*#co+)fXx%>rowy=viKT|HS^~ zC^ul+YLHZl%c*Eq$z~N^T)8vx)zGd$*k@RTyh}<};1xKtM~4mnU-m&yU+=5{(_x#7 zvxaL4o)L!xUL0M?h@+E+>k1Iz+2Nn~C0i#5@#Z2gj9eKyL5vO$@!^{tA(jlc#%~#~ zkGLi9vj!tUyFjN$J# Z@gIQfKBDW&N+|#U002ovPDHLkV1lVgNQM9a delta 2040 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 V)J_E1IX?gZ002ovPDHLkV1f#mp?d%T delta 1507 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 XgX=x(9X+M&00000NkvXXu0mjfeEO`P delta 2388 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 N002ovPDHLkV1hKG{d@ob delta 1862 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 delta 2016 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 N002ovPDHLkV1gobiBJFl diff --git a/TMessagesProj/src/main/assets/emoji/0_1103.png b/TMessagesProj/src/main/assets/emoji/0_1103.png index 61f0a161a74bbb24a587285d42387cb7002e114c..800659ed52050ee24bde470f11ea87d7d41bb6d6 100644 GIT binary patch delta 2071 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 Hu0mjfKzJS6 delta 1586 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 delta 1705 zcmV;a23Gma5V#GHBYyz-P)t-sM{rEkp(yLJAa7VN_QXEovMM=Rk&J+1JXwzBwJtYc znl)C5l5{xYt04BnH0rl7_{S^!&L8QtEz*@2(3c!CSB}w-5YB`RELD;F&rQsaCN*WD z96f6D!a$Bx5yEx|GF_HmjmlAj#y)epScu3&dB8Pephm|zW)R0Mxc3ABbLC>;&{%M+}TS6wj$&a-!Pac=+h z*CR4VkdvKBMt?iXW|h_e001C#QchCj`pQo~^WrL=mJ;riT)q42Uo-))Wl z&bZk}YC$6a00mA-L_t(|Ud)x*a^gl5h6f}SQ5mxc0>L%5pP<)8`^LW7ljQv$CZ}5> z!p>yG3NM`~5D<4w?jlZTDM&QQN*cU5SX`jOona5h_XIBuSJ~kRXmJMvtuu zSgNR$K@dpE2tfe7A~JlB0zt*hC<={H)i9Lt`+pQdhbTS}8Jm=eYFG5S2t$Z~2xtMn z3Z#l-#UTeyFl|>r2o_+y7rRWt>*0y;ZnxWCwoI}_(P^9F5i3y8gj0e@am6E0p8^F> zcEx71Y4$YGeTZs}IV%Wr+JAb9KT?j3BB+b-Ylj&N#5s1`6fWktnJp>9 zbSX_DK;K&&TG2Y;GftVT9b6EJ1gU2e6k>AE2hE*PVjQp#@APRSMP*=~f5^!j6oGDai&~;3kibsngpkQ=H!Wcckr(_#*rXiGH-!v+;px9JEh7J3?*H1z_7$K~J z5O`>_9fP6?VH|w!{PXSthmjbVF@H4o)gaI<-khpNFg)*kXTYYA1Kp%RU~rp*BoU=Z zgSnW^^&j7NP(*4FqWtE<`(+{ttQG3@b^h}7?-ya`m4l>$VsTsSgT)!cYWv{yeso}Z z4=-^dz(O(RD#>1cYZCtY^>@qaTYo-$`2l|wN(ZZx!Y~-X7X%&ZSrEoUZGW0J?f3)^ z9^JFd`#;R4*^Dcq|NT6Ohy3^we6(h(mUUg``906ex~$vK^^KMQ%F{3mQ~kIt(06sB zVOx3jH;18h+on93R%V{yyhBRCw#TW%{L=&?05+=S%^lwFrP_um=RD=QYa1q_i@<{I zE-zpb0RSQ(606vLi~)4%mdEQ}h@j~WG0Lt5l}q9t_Wi!<)o4Sx`(5LO6xO*{d$ zg!T|Z3{haOVey)1y0V9N-tUkaitNO6OBje!JUTzV_&FGY0MUP1JZf|-Ah0ASIU4}q zV}v_`gn(4uV!V_PW8XxHctP}3_CN{&qGLj$#+T3! zgunzIYxr*s05N_b3?dU_Bq8LWry8h22zSIESmC$~E$?8{00000NkvXXu0mjfDwa4E diff --git a/TMessagesProj/src/main/assets/emoji/0_1106.png b/TMessagesProj/src/main/assets/emoji/0_1106.png index 0d4efd62a4fe51ed031df39cbf9a7d7357aac58c..54c90b715b4811cc46ffafbc49cca6265a6f7390 100644 GIT binary patch delta 2104 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 KMNUMnLSTZxb~+^h diff --git a/TMessagesProj/src/main/assets/emoji/0_1107.png b/TMessagesProj/src/main/assets/emoji/0_1107.png index 0e4b108d2cefbbc01586e2646dffc5581c919ebb..8638f305ad38d56fe2c29de3c21f19a6400ef3a6 100644 GIT binary patch delta 2140 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 Qn*aa+07*qoM6N<$f*leUP5=M^ diff --git a/TMessagesProj/src/main/assets/emoji/0_1109.png b/TMessagesProj/src/main/assets/emoji/0_1109.png index a71f01442f1dfbaf20907756a823486f506fa3a5..4f486fa9cd9a02ad0b55a3432d07874e967ee229 100644 GIT binary patch delta 2032 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 O0000<+8^@I!#*-Je zhA98%aOu8CdkM*rYjZCx>xe>>u=ak!Hzvxpq1h%(&4UvO0s z<5bV;(5P{5&!6d|MHCg>Tmztaq7G{z??ZiFb&a>6V9YJ z+nq=M?|A?6gOGJror*#K+)tc`Xz|Be)~6%gp;m=t6rp_^tCvs0wO;@CleTv%|M!fM z05~uJ001I%QchC6FSOCAUP$Il&3us4hJS7K^G|D)T5Gqv--Tiz;VS?D z24hJ?K~#8N<<@0$8(A6!V1q2M6FG)}Au!D?W@ctKGqaQV|Fq}5>glzdu1RJ-ZPlJ~ zrEK+kpFa1hrOMR*T5QW^>u-;~GbA=R)0<7pZvf_v8E(mF(6Yn}CezaTuaI~1CQdL3 zW&>h+QGf7ylfo|$^SsFuu;<$&@#&}$&o zkbk$F6pY@~b>5$hJk{%0!=e)hv3+r|N5FT@*kwi}J-oVlDtePyqesge6XMQ_R47Q2 zQhDCL06{0g4r6Z*HO@O%H3`=X12yE&ZWs}Z?p!Vx7*-TXk)&D&>mZCn#P*d$snyf* zoYNg!Hz2GFxlt~Mt>R`1kmo=52w;KMtA9y~qEuAp^>uDEO5B-^h%dPjj6|lI@2P}5 zf8W!Ey=@Ze9UN#PM{|*B1Hu*FvLpTET1+j~t-G7Ux z!j)7QL~BGii3lJ5Tw?{VjzUCa4wUHNCaUy$yLx&(6|ae6u}Vaoh%c`N%R)GO7-vMu z6%>O7G1%MP-e$lya=s-7gF*4CnsAPZu-o>Ec;}HB;R4aYG{%eDdJYZ_YK+*@2|4_F zCo6JlOt=_PC=hXg#aK=$DI#72;eT{GL-9BWdHxl#kkSYkw?P^Yb`JEEO8FWQ(Ru~~ zBT}iE$w$LBmtq^aB?EUvXUU}llsempnjnF-NTuFQ5N}f;;_*=EmWU_XNS!U!Qw$=K z3xZCpOdbUh0V2q7RSE^=mH@2;c9*H+GpZ&+2n0q<9>zR~L$q)@U1anwD}NmT8jnC#8Z(<-JKpC9i`L72pR0orB0=CiBu{b5GdjT5Q+rcr^p@7 z)AoXxp7FPuO%l{2RaJ`-D0C)+%bT0ao6Esd=9VQ?Odky?&1S2$lQh2|%rg$Y*>2bC z?eiht=ejH6+@-EKB{hiTLLg7EhHkIkdg(=-ceMA(`dj7nut z8~+t362Q`IJ@)(M{}R^OwWPz*>Tj{&`!`JlAw{WBsYp^f6k#C(U1{pE#XE#Q)@H4m zU^OrHyAS;qYPgGT)P=zkO4pP@jR}EBAW;0PL$lp~=suvuEDR#1W`Fkvk#p6CNzkdKY-Z6f_tycY$>Nw%a7%TGQarCDIA2^woBN%l!=3ag0%u@>= zuQA=IVUA-OzzFPPB4*UcW_@Es6N1uKeTcNTlw)yh_^_Vkvg4yx48x zt&q|CPL{)-qpctrT@XHBHhY4Tu>AZLPDTt0_W(hP$uvzU!GAoCp-VN`O9BY}V>k=2$u=_s@ikkR^u11&_doJk3<&HX3}ag$ z!w-aQ2nvI=-zWt5(P0K1j59qy=YX-Z1BI9ufy&~CFt@-2<5*VC=EwkIlpO%V+}Xlptp@*jx2fule{t9bwb002ov JPDHLkV1ftX{Br;R diff --git a/TMessagesProj/src/main/assets/emoji/0_1110.png b/TMessagesProj/src/main/assets/emoji/0_1110.png index 6b10e77b5bfdb33fefce36ffba448e615f8de908..2b204583e0ef39c89633fc05c6ae0d7aca9515b4 100644 GIT binary patch delta 2163 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1111.png b/TMessagesProj/src/main/assets/emoji/0_1111.png index e116b129014d21d8b9e79d8fe44be056b09d47c2..6ea4f945a48a2855600b46ab82ac9c736d82b171 100644 GIT binary patch delta 2132 zcmV-a2&?z$65$Y#B!59rOjJcja7>z)p0cW(%DkH5!+qDegy_qY=gpet&z|PVjOW6Z z?bmkh)pPIGZS~n^@7Z_%(nR{lEA+Y??6Mc{vmD>AE90;s+O9p;s5+FCl={<9URGFV zU0!WrV2g)>SWZo5TU&^Sh*wQbKPnedK{Wr-P`8z7<+YE>sDFyjx3isz_tv%Ry_xB~ znfcnf`rW+y-@p6e!Pv^S`s>wnSvMyZ23jr^{rmUn+{uei3;yQFu67E}o-gn1?8>KN z%E`ye%gfZ%)PK&-&*I_X;^N}3udvtG*QBJRsi~=#n3%%C!j6uOot>Sbd0e!#w8+TF zzP`Spp`oRvrIeGBr=y^{y1I;vjE07WmX?--g@qnVR7U^+0BdwoPE!B{4j3jhK}}wU zue;s#{*wRy`|i%Khi^!3(s;@KA^-nL(*OUg{Qv*>|9}7g|NsC0|8&m(|Cj&&!vFvO z|L6bz|NsC0|NsC0|NsC0|NsAhq{jZ={{R2~|NsB|{{QCx|9;;8xc{o;-^5LG@a+Hq z24qP@K~#7F?2^?%#Xt~6S>MRIK6g+5^)bO63gG<2=gQ>nH~v8w6Uw-d4+zdE#Tfnh zYszKQc7J`Zlzu@e)pwndoc=zCHC+#%TI-ziPXzBBU@gq*yN3QafEuN(^C8BRb1Ah# z09GeuB&QgIgE7kdFoaC44=Gnh&`Ye@d_G^yXUp-Nu$mK$iR9Z6#ryPL0nbLw!7VK|6pXx7?;pB zbQQ{vedg#Ns#iTM@sRfW)oQ=n!-)0qaZf&G`paKIY8k8dZk%*FU#{2NdA))*2Jb^m zr9#zz0oT%>ZugAR1(MuA3^X z7=OKLel6ZG{TvY|B*P?c@|if*ize&o^TH~z0wC&yLcFIoOIFWT$Q_eCM7ZCtAMX(v zGWkVEMcSV z2mlZms6i$OmN$qv@O$VM0RHN`M|2lYnD_>fsc<658si4|df2A?Pb{uf zh~rJ8gdUd^M(jT^E2;#?4etM7D z&p)>6aPwT6+z=oCFCzBkSt5!#id8o##D+~b3{dGJflx-4 z@V;Iz^6}(3LPxy;{c&c5rZEKN4JZJeGe=wn{_gNa#=E71I$m)T&XNPLYZHVrS5wy32qybsdW1RuQ(3 zAV47i)6GrnV}m%~+w{S>zy(ojlan-A+nQGE_x}L*BvC2MdjL>!^5g$MJvmLsLyU0? z;YAFi*^jx^?XNf6I6?+?hP85@ITK9(?`7ctEfGZsHAmUny5liCLD%oxBd}{>j-3tFF9E5zeGVo2}rf1ZOQS|9-co9?z;7Nkp zcIyBwY;Zs4JWfGrImgFktsrCh{i_wvOK;-^i$0g2AdR`BY`UE=!|i#&faPhDs*&w- z=jC(q+#C}|6T|q zML{smQz0en%g|M`5_ODHP>C$q{K~))J{i4!f4`0BEt%a3ha(rR6R%7Vl5FM zYR+rMD3;WDu@u{vi{;{dI=v8viZW(11wybETVw?5#3}$?V1GrKHWIv!>uqW3_Fo8d zkVZ4CWud_;N$`;bq{_0rf}H0mV`(iUrK924Lc9_Te>Jgnpj3+5=3zRheU?=uaIG0u zC?T%_2~2}g-ptckihm2?fQaT)8PE(FQ0FM53a<^i=GKH1NRYs+4qDCdFg{s~i?{LP ztfE!}1BnbFt$!K5zBYKq^8%D3NG3oTLrKuTpM5+&z1bLl%Oge^wBIjA} za>htm4i46ZQ9=k~v^j?7&&_`@&Yzay5f=;yp^Wu%7?dSx&x~M$ebJnNfu>rUQ|CsU zjK)PwIW^c9n;(~?YG0LM#e_a8(2Cqb5T!vKwP00PVoiGQ#wT{CyJz}98qkN}79u!k zXvjgcJ*Hy%t>_L0BnX;jfXg=-gQf`rGPu3o$|K=lmpUQ&sqYW!d_CkcfuDW=0000< KMNUMnLSTaY(O8oJ delta 2398 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 QVgLXD07*qoM6N<$g66Q01^@s6 diff --git a/TMessagesProj/src/main/assets/emoji/0_1112.png b/TMessagesProj/src/main/assets/emoji/0_1112.png index 4d1677f3fdc3375891a1537715dcafb2a6ba8fb7..3d9bb776548fa368c5a6a6c149c3e8441c32f079 100644 GIT binary patch delta 2182 zcmV;12zmGU5R(y*B!5s)OjJcja7>_zhpL)?=FW)Y)|l$piRRat>f4U$*M9TWYVg)< z?$>hi*lX_Cd;HZ?{L3}>yB6@eB=EBn?X)1{vMl4TAmOho*r!_ArcTtLPQsjHqmy{? z=AqcVc;e8E^XsYX;hxx|A-#lqE>UcUgE_i#}b=3o;Zx#6pOrp0}lz-dpcD&3Ev;{?y!8Px`C0fvm5sapB zn5Wp?AC21_r&q?k}(<4=Pcs08^yWdTRlfIwgr1ZJ(0^ZWjH9?w zTYo#Rmik+2cWZnJXsokTJ~<>}vc0=ET7SMr(-~T8hC&RS;%v742g1(GIR+>JLy+)G1Wfd>xNKzmKM)xJ34cQX0=OtiZW({sL1edV(4=B>k#T4!2%T_ zLkuCljSWpxk{=1U009uD)K~T(7Qg+t#r` z3(+jDuWwd#sO}IA6Y9gmwpXfwFwihTb#vGDHjf))j~8;N?iz@M4yxRHJAV_U0v(Ca zcHQ!tLfoG|^p1%<$NJ$)4s~tdXCwho<^J2r94ifTibpxyZgG2ecY4}(JwF#u($RsYvGJ@{^F%AP^M8IiGtkLE4DTQ3_{Zc;<&Xz9+Ht^xPKeOi=)`>vwhw1FTPTTyPz(x@s# zPWnbALNNI7-kr}mhciIP|G#zCwyad79VCRcx1*Wae1H1c zJ7VxpXV3HK@d@*;IT#2M$$cHNh?)bjK<#5Rf1aIwa1xv?mhp5N#bU)W`ZYy${a;;S zMSp&$mW6-PPSGA2K_U#}P_M9F6~|q_JE=(~ zlZT4|i|Cg&G!BMnFj165X&XsoFQlvtlSD|$U!NL|!S(6^-Qf8>x*kA7J&o6#q)3ub zT178enMSad2C7(zHLl@6c!U1ssM{S~4)Hxfm|#EHqI?DB^e~-k7U#ZlwvG07pc6lcwv!E3E`umS8Xx;}luV zW=fKZh5LsWNPqG^*Orts7>8jY+n`y{SyGx{21^b)@^Pn!L>R*oxG8&`aSjcREOV4* zl3BChDTkqDXoR&+l7^1LYu()Ten1OfalPA{mRIB`kaX4x6H3idq(M#L7g?6=9Ba@* zNNbhdm$i25{0ng2YO~>BkAjs#Xx8C&Xet^b9$s&eaes$B38`|WY^N?%?_Tw}V-<>0 z(Ei{|^j5ZgK(Kz_X2BLV_L`I~PCh}Q73n>!Y=dn3z7CH6Vf!aOiOsIqklK021Q4@R zv?+EQK{$%zpTUPa&p#Y8ls~T@4!&1psQ(vU(f)U_T^#HC1DRkc8tR%i?EnA(07*qo IM6N<$g7kWD5&!@I delta 2156 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1115.png b/TMessagesProj/src/main/assets/emoji/0_1115.png index 0ddafd83f381debb0833ace4c65037e5f768a267..a9c58f95077324734f4662dc4fa38327f4e9512c 100644 GIT binary patch delta 1926 zcmV;12YLA24wMg&BYy!JP)t-sM{rDfcz3ZBOXRGEdSF~wvb305DP*uDY%zl#DA1AgJ?iWH7`szFgq$E zWKKL#J2Or?GF?qC&CSix(9hxE;nUO8uCA`Jv9YD4 zrJS6cwY9aFn17h0q@;M1$$p8PZ!vFvH|NsC0|NsC0 z8}$FQ-T(jp{{R2~|NsC0{{R2~|NsC0ZlTEE|NsC0|9|Fo(*L%iNbA$I+vlDO*4{z@ z00qlQL_t(|0ql`gLPb#sMZKKvdfnagAD>{i4#4#fyY7DFpALXAE}r0wG3fq&jh9ks zW9&PO(Msa4Kio@=x6XO*0}`L{h;z;wE!ocxl*Qu^Q_7{();J~LNNcs^l%mHkR{ih< zdOq}XX@75X4~C=BXgqoBhqaQ?P=aq?v=H(Kh3RZQpD*UK>8sNmLi_$jKlGG%D=}Fj zbK>a-2-ORH{(X|#58h#8*gQaoX;y1wLr+GuF?Eeu>yLew6sY=#5%qSr-V=v8a(vh+ zgj9YT7I>xVX~lRtA1>GH<+dgp=MZDcmBT$HWq-WeC=A14RktUYv?A7tW7ajd+9WO+ zKwHXKx9#rz-{=xTZZsNn^Pg7v^x65jU(Dv!^{({hYrZXFQ-@;pKjU^F9<1I$SHQ6Qhzh{UXfp9El1V_SHHo-BhPfXRnl zX2QLPo<|^vsbh(SL8yxeHi&pCRt7PaD1Y^+%JDM9M7$P$6*kjEG?uX)X4`RyV)6Ml zbB|Ee*BC*j5V_YtfMPq5iXPzuU7pWTYUL*(_%s=dIF7Obp-{_25|0^*N-3F?LkJPY zaX3pvBnAYls;;VPm(YJkNwTW;rp>G!LLf%r9&kWtE)UJ7KDP2{j~+ouUDe0+v41&~ zY!P4)`8K=`91v7@Qa*3i?dBwvw`k<%#kRVdyoK4v1OhkR>9u`r*ROBQ4&5kJHEk(nKva6l|45KtS$dToCH-W+JyMBTJ&Q>N9`z!m|{BFF?d#IEb4k!T+tUQRxe&C79U zbu~H!K(LEN>JhB#u6cWZzqx6;KYv5C>0nxKed{S928T$4SB=3U?2Rz(pPJtff1Bq+ z!p?%_;kj>}b|txO0ze!dy0sXN9VyxG_lYEOvD77#Oe)hV(H=Y4tqE9$=}bQm_NM&B znoRb|W+LwI%p<}%tVS-fdm+#wJ_D9g7(z^jf znaRih&jcszp{#Z~Pr8{5m*ED4=f6d)(svJI8re(D+wp&x!^-#uZj2|F&Uj`zQ z@2)W0ZLzP){?%0OxAj3l+{QWsD?Fe(}f3 zYw~Rn$w0)yqf{ED6ety&Jk&;MEiG9s3(eDX-7(^52aKfu+l+(_*M-zLAhlMe#uGAY z-pB`%N?9VFe=u++y%W;Ah9|T)=R{U1Nx{=wlXcxZkkGIKB|(bVj(_`3d&NK!+yVRr z0&t&(kb!LUp#>eL9bp%H0V~27VJ-j7c5|*75;kHlc3`k$p$vFl7%iO- z-h#2|=F)HI9uRjaTv(Jisg3Z^Zd7r^?P!m6ed44+uucjJe2JDtA;Xtnw@K6Wk_Qsf zSuiy5Q(YfhARr_=OMeViz@c!SLdX|s8X>(Dd^|-!y2wKy?}W7A;KVumxS*x#OhiH; z2OT{BxdH?M4q^?!YL#=|r6VJnQKtO3;5E7#Z;P-YI7=LimdzelFPlDIR*y5*@(?&# z7lIYB9E^I}BUsxs&Ba9xXg7@baLr;Oo6YC*FZ22AYxnDlM1LS_dDP)9ID|$FqJow4 zl`MJgeYi|U;u1WPD7l_tqxzhl9^MX3c5vjcH&EI!M2qvct0#BJ8kA2z=NV%YcC!A` z0`bnq5bPa@_Tue{b>*Wqa5rJ+TZ8m?{&r@Qwn6^?(Psb7Wg`xM0k%Nq>~6$Eh5!Hn M07*qoM6N<$g6KuYp8x;= delta 1871 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 TDmPLp00000NkvXXu0mjf<``?h delta 2119 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 JPDHLkV1m^xhhYE! diff --git a/TMessagesProj/src/main/assets/emoji/0_1127.png b/TMessagesProj/src/main/assets/emoji/0_1127.png index f2f29d3c418dca35f87b3d4cf775084542368dd8..4668a82bcbc9cffcb63176a439dd40c934baef75 100644 GIT binary patch delta 1651 zcmV-(28{Xs4}%SmBYyzfP)t-sM{rCe9~~zqC1*NnB_Sa_D?x5IbVoHxO*K$BEIKA4 zB4RUW9~&AZAs}cpZe}xUPbyVZDqAp0S1wFeI4L6<6%%SSaZx=rH83zPDk@1fFc1w5 zBOo9zA{#+4Dq=8bBp4D|EMRdscVAXiJ~=r>KS5F{Qb;91SARn}frgZ3TU(&t)ptC7 zPDV#rn{HT7PHnV?1Ox-F^5tZwdX~+{dc2ZbNIh(Tazl4}gul6}>E3OfnS!dOcv*&J zYG{VXoKuXCJY`5VPDDj^Q8!~~l+db6Q(;YsUwm|SKJrSs0000KbW%=J0EuQ_uSw7! z4Kn42?a%F}#eeFb-LmIu;s5{zLrFwIRCr#!n1@p1NEAiKM#hqjfthLLoaLNzAT#s- zU$pnBg^Q^*$V}Dlv2dvh`tbU`*A~UM|CqW|t5$1L{cinzm`G8ic!FOhEc2b6@PBCM4I(ShLMBF&vAqtu< z_rqaMcx3nmM^*1@vexGe`$G=yqlR>5FB)+enN}2Y3RT?4y(Wm~HABO`Wm$_NTtpnb zq3PALvTViZp*5B@PJ|1uf>!;kBoJX=ACF~SBl34$$CXn(Yahri*39vnME?V%QN9oA z1r)L;n}4QkX$41Fc~hh-9leM&)3bpm%d!Pz!lZk>QXYk+=h2(YV1&)cL^Yu(k_hEd zSa|@JX)H3;a2$u>vKfO1J3|?b(w+zwIS_@BEf%n-szEs9pi-=>(lA=N!W!E~hV=^~ zBMiqgVHnF+SzAR?=+@Y@seA{O5ShVj7(5THE`L?j8x|bqShks==7QX!GMn;{X;{iy zB9Q_=DSJ)^$WVZ6ZJIZ;RB;6bihzOyhNTt;Y7ZmDSU5w04I_LM&OF&!92KfzlfgVg zK^sPNHehP8KEuTo<{1h(uNDf2;v_H?Tp^P|K0`qU%99xxpdcNZuS|8I#)wzWRnTM< z4u1r>Kq0C}2Fof}Aj|?duor_F;qTwLW87fX%0}zTG>;OG!J#rob(oqNCIw;XLcMf4 zP2$~V@^hy0EG;~sVJK6`;3%O%ck+YkVcOE`rU*glF+*TShv~uR0TMu#1lKng=X_pp z2eM;n3I{OZv8lC*qVz5=NyJrhtv~~X`_8bun~&yq^Y*?pjV26O%zyVn zWneF)n7+)XcP~V{cPV}zL|%leK!LA)yS)rEI8Xx&oGr@uEC_|~04V$2Y}4&-x-ZMc za5SHe?(Vqcu6^_AHn_s~-TitqA;V@ene3LM(G*D(%s=Vt#dQFvi1utU*=%Mo5M3Cc zC>-SO6%$F@WFIR7;MnSx}t{m4mNV_ehmh=NQ0YSzdFImFvLr= z0yXdw5W{5CF~W8i_p{w|zH)#U8J?8j6&GRSBA>f}k4Q-i+!-ey)CA9-5L36m4G9A1@R-T262+OrxYTJ;AN~yvdsV7 zgNNh0z8knc{Z$($E+$8T;(tU#dz{@G9GH`1a7fVuXgdEOIaS34-1+%b?zhNcd;c0o z8Y@Jp4}uV!TrAd(0UXYljKZQ{G{Kx{UrrnC9oPd%H6 zbH|DVt6U&`6YdhPBik^O+9ijctMFGWwSZdxDmhZQ>%@3c>qFAd6tp+?m x|M}ww9&PWwTbF7;l0>ome-70OsABd1#6Lx?LH7@yj~@U4002ovPDHLkV1h#1_JaTb delta 2033 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 delta 1902 zcmV-!2a)*v68#R4B!2=>OjJcja7;ZiFBCavG;g{o3 zh0G`)9*=ZEOD-8slg~7Bx)e8K7estWjmuDu(IF^2OExf0I)5@bC?QBQD=i=yQavw^)J;W3S58jg*vo-$ zVfpy`Yr{B)g>BY@d^uWOY00s(4L_t(|UYylwZ|YbK2H-|YL;?sZQK_xa?R>P)ezLM} z-Fvs$|NmbZJAt9?WiE8ypeRWAk&h#pv!5nT>cnUNFMmnY35J6frQHoW(Z`u6Xpd&| ze={4kgO4dm(Bk^pKCE=3546yparvkLM$JV|D~L}OM%4Jbw3>VOG$R?zSZM7sX-%5& zL+=!$->xPMOkUMilWLdF2|WyFm9I#6od!thss_nXqB9y*-n)w0evhP_DmW&@!xsJ4 z6Oyu0=YNe+wc}%x7;(SOF+vJ4`*s?nijJM5#e`CfG_BOHlY3!+*!0**f=Nn*l|rSi z>4mE}j^dfrfT)cz8O3mz zLjdbiceIOu2t@)_hhb*2MhW>@g9JqbK83J=+J7pdG}kjCRjLGP3Bnzm#rb*shENhP z^&Ayub&RiLwUnuQ^G4$H=J?^w9_dt05TTTn04Cc85v5R8gH+xHd!T=H)l>~&e8U%sz9pAM562oa3YmyMTntu}~+ z#8FrgA(jg#m3vy`z=F)z4xJmXN`cgciO!Pi&;S}7bmINKB@s<{bD3GMq$n23dG~FR z%bFXu5Y@i?`6S5%?S`*C%Nbw)5tD|68%4*;+93 z+vmS0sF4I3#Nl+wK-BZ+hv(aQMut|7l4=sdKfY}4{`&RL32($t{lfr{LkS7<`-g|k z-RA2p&C*z*tf7hCe)+taPN(00|9?$brDza8GxWp#{q%0Sx%>QeCKPW=CGelZ%dW+3 z9Sp*4LW7r{P!iZ&ggp>h*52$zd!1f+R{{|UeXOMa|5rM%{K2-^n=yf4oX0cs%1ZKn z6PGHVo?rf7C)CH~*Ns1E9;6r4}hZRr56!)m^R-Ab&UZ3`CoS zF>5@RW%Q#0bT?S)-nCxt}72tK@=ZE`< zW*3T9E_V|{Smp*mEIjP?%{{{Yspl;i%z`l)Vcu&15)Va~r^Dxv!wrK7ArWIPq!+BD zlsFO4Y<}8*N)SST(Wbu&!GEb3h+sf4*>2Yv`z%B+jIg}rl`(}8{Tl(aa7EjOVas!U1s+U1pNSHXsb66*3z!4D-!~*2tQTT_zWo>=>lMn8VET ztq^P7c6oU;k3ir_z!e1XVGc8o_nIqX74fjm1_WBnkYfrA3Nuay0)Im|M+muJu7YKH znmQ8Ytv<#uGvwN%3q(Dxw3!V7E;zalcamU)Da_2c3XFASBnPCd`@*<2NFP&6421dE zst`1i<$(|afGZ)WiH3$kuMn;NSqE=(<3c{oG+Ct%+YABir zB(HTL293r`<{a8y41&^WpC3cOb|pwDm7<+9Oh!DN^Gk?t31=UQu}p+AUd)EwJH|0g ziBZGVadCC>ssKVrWkfJYN+56|jYjD0xmo!JscJz;urwh?8wDDSK%136dCl>>A@M>c oPN$RKk{n+C1mRrT4Ehk`53}VGaNgtW-~a#s07*qoM6N<$f-dfHQUCw| diff --git a/TMessagesProj/src/main/assets/emoji/0_1129.png b/TMessagesProj/src/main/assets/emoji/0_1129.png index eb1b88cc54e533b66f38e6b6dc46ca79c7f17ee4..b2552eb76a50540cd6c702b76740588cb81c758d 100644 GIT binary patch delta 2261 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 delta 2306 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_113.png b/TMessagesProj/src/main/assets/emoji/0_113.png index 6606291ab15f91dbb4889e2f8bb335805853a519..02da31950e23acca4a9c9527f486b1620e486104 100644 GIT binary patch delta 2080 zcmV+*2;cYK2&@p0BYy!_P)t-sM{rEjp-yY{zI>8^)6t zwuUJG=Wyx1NaM1B-lbz$LnYLr9M7B=%aI`%6bws0BH*hcSbs|?_0Ch-mlnLDQuoec z;Ilp4t}ncQD9oD>#ETc^yGSV`81ctY<+Cp6zf%JO1I3XL?!-p=(^bNVCE=hO$)-mA z)L-|_M*rq!H#95p#yr)qPyW|xvU4YYX-5CxTWwu2lz%(otZ}%LDzk_jsE9J$!C!Dy z5#`fvm2nzjP=7(Qlsw6n5S@xa|M!#r;(5P{5x|@|Krjve@`HtKE%C=&|L=I}yg1gU zBhI8Z+nq=M+)uW5Dv)(n|MHCg+;RWtf}DqF|LSkikrUmaR)u5~p?w>xmrugAUjO%u z^JvZJ0000YbW%=J03hTk{QN)?3@^0Nsa{CtOwD|d(|?9-_47|_m0D}JyWfRkAmJ+j z00v`8L_t(|Ugg$ha~sJT1z>|LuoF3kfaA~(ina$r&Q8fESmm?C?#CB zN`+lVp^Y|*FCOy1tDN>?|f+#x*m-slmp^Q^AuM>OES&qDe5UPm$M#XnN!6#1*>pP2h2#%dwJ(Z_lB?l3E&(9VID}nMYFAVOqu)$AC5~Q*V%8B6b7D%cWpEL4by5%KM{U|I-;j$(`` zIs;-LCkDFLTU!j+LJs%EKp-G)RN^+32)Qh;h<9$85l#?oOk=#TrRD1Cs>+CcjgUjH zcd{ZURl>=LT#kq`Lh^-xaS)*KK>JEdv6!tA5vipi zFd~_pnS3-Xb4j+512S+&be5bNK&i2fIN~I*7Rlth3F2)ML@X8z9uVwOGSPB6| zazfCEmC2(Z!cPPl&T=lN91!qQ0=rAs@E&!o_FMrByEG%{% zH;Cf^hVx*f>PQCa$_ zah{ejVtU5cY&1x4>^K~bLKq62N&n*J=Hlj}|CByp2^La214^UOY;GrvV}xNwHEcpCQ5kW{n%9YEKlnRDfh(K4GdTjD`;jgt> zAWSeD7kizDUK2H31sCeVUNTFk13d4Fp5ul*)3%Wk*Z zh4@*p1PS^F1Aol_5*K~BLLs+XmSrx{LyIYuSX-N2NZPsM<6}1|YG@u$5Y6Lb;0Q}8 zZkL;aQO=HE>g?K@S=|RcT6UfrAyDXET(j5d>>^U<0VP9NJz5U|1U*``6Sc{*-EQX@ zqB1h~*a?UcEuy&F8XbC@qWHk!X81?{jlw+!A{`z=^bXt5{Uh7R48+@LV$%CML*Dnu4>2IHgV2p- zfearIwjn4CQomy%z=sYq=%AnJ`8hj`?d|A@(E^pl2Vri33HmXuoX(K}L@(O_gt^m| z>8Zbq^~XJsZGS?>nQdJ1K>+Y$;u!Rc{5TcvP(%$h20~!K{dddM?_>R5KNWmHCIUb> zt$(*p{aN0w0+~=)gZk;q^$hOopFXf-{6|RrbWWg9f%@uu0RJ%4 zAHIL8*YEF7@9XtXt7!1AVtv2*30Zw_HBJ5Nm@HPS1sUuAFY+H5P=9gDcLwqR0000< KMNUMnLSTY}&HUK_ delta 1098 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1131.png b/TMessagesProj/src/main/assets/emoji/0_1131.png index 6fcf34e262d744308b92ce974b0baace001da2be..849704974b4f219957a3c71cecaefbe9288a19f7 100644 GIT binary patch delta 2038 zcmVl$aYiLwHfU=>AWtn7O+{o>EL~PAT~aR*URNw$7!3xs zfM8@XYl&P(cszYiG9ijvI9@jzv3gtt0s(rO-+bi zPJVxJs;Z^u+kaV(jd8n-c(%1fc2PZONHkeKh|Hk4mVchz(_W=^hr_+Ng=2l4lc|De ze1MERR#j|VQ-^tOg`%v$w5QqT<5ZYvt?%QL*sN)UdVf!Ad_h_G(jLFj)Idl^h{v?W zc_r)LapRj6nUkQ`z%JP-?2`Zh03UQxPE!CXLY4jq7JvT!{$P1~smSNCpSM}($d8c7 z)w|u}#oj&Ju%m4a6QTQ1D64vP1>@aBw8D(Lj{M(Tf8KNT&oEMs>XBGmMv?U3t-zBm;{}} zUb39zdf3*W2eb9e3(-_!U?XZk7qb|a z1)qyz0gAK*MF5ec8q@-rU974^VJ**~NPlCv`J|d@L7>Nx2?2!_0vu8N+fA{YPM5P; zo)dL6Qx|n);cTa<1$Y=-6+S4)3sE~vm8#Kj^p>UOQgav2+@4!v5mX)%jc&6WjZ!NE{YFSskvdrDFj;D813@mtl-1c*VB+<%)Y zT9zXb141!l7ghcC?k--mWf7^RB}}KQg6AJ4oC-%KuHMGuvRzbY62XYa_2wj31Wz5P zzY-^sBKcNv#@@VL3c=vQS{ZQ2gdb1-;2 z8V=u$6;VtoeKX-G5{VZ-cK9Qb6pgI?vVI|#TE+GC_2KZL-|w4+ieso$5|yyahjPg4 z@%evg$;L%-{2-4}k-wNcTS*X*14A6{RrS9#?4n(~I>}s3hVS0J`!-@LfPbXGV#QPz z-6qsG_c?>fmg^aL{4kloaq^{78C^EI*ViLR7>04X#>1?Z$xun@!dU+XzW&Z$e?0Cs zK7Raod|iQK(WNPDLY8HWByMhP{BYjs{PD-1j)Bk^u`X%&UooG_KPHf9@$vY6fB*jL z*T0XC_qxZ&jstnT_>tlT!+*r9RRN^Fu%pE2e%tu-_sio(ckh@2&n3&e`oWN{Fl;_f z3Fxs{J{Ds}pT97T#$I=?(QqW#$`5wpdBqe=H2`$IkY`5M_xs!1+m|q$K|vg_HLh7E zJhh*T&thh?uY-Pbbbq=-IsL8M?VceG!XEPZ#7^%?_}Q~qv)SC}_kTAAm!}^-eAwCf z0De0IaDZ+Xt4}ODtr%V$0;ah^7;NuA00ULLKRd(I1z5a)U&DNPrVKXDVWL0{?G6m5 zFc8i+H{SzTVA$N;9I!0A@^n98s4#2+TdD0kh8;p@^I+4lKyYv{h{f0^>**l|7M;u& z%-s$#5Kcj7_wayPsDI$#CI-dalSz;isGvF6KHce@BAg03=k3G8g9AMHad>!S#=w(` zm()-wm}Yb99D$GV=jZ$F+R>rI(NRA?UGZPTppC!|pz#>4_Ezu6;aAf%^WaIvVvHKV z*7o^6f)S2*2->@~-p#KRGge8&%tGO5ML6#mYHh?J`Z0cYtAEz(4HyQk#I*hFB6~J&aNT6SjFs2E`Q~1M+tIr3ut=%?}v_Hv3S-ZRYRO=0pIh&|B zFifm4O#yu28WdZ*l-pZ1fSV(J3xip}HW-!=gJG%ycwWO%+oIHJJ%t?nT)zp>N($x% z6v9&#zLj3DS8t2H8Sp5O?~Ih@q#j@OVN`UY)OKoSrI;vRXvxZ?7mxH7l+ z8qrC@o3{(|q4~MF`MK5Sgw@r>xfKrtu6WiKmftR~&3pg%YQG2g{fM3w->k3x51V<~ Uckg_z?f?J)07*qoM6N<$g6ZnsVE_OC delta 2196 zcmV;F2y6F*5TFr|B!3G~OjJcja7 z6KPQpU-t9dLKaGF8+`BPz;YggeI$>NQ!j%jmgd@?pkO$%a7TAfN1by}zocBDfIMd> zXL>}|5#RAK0+LL>{K zXd5{I(|^_G=FVRJ7sBP`B{MF`NKU>jio<$czJZVI{9_Ygb#nuRloc8SNEqla1;CB` zKL|Uk8yHZK>A~OHrt8(qP5eMlG~N4D$RDj%FjhDC?P_%#37pDj+BX#5bL%sL2`f5( zb=z(41ITXg9BkUn0i9MX=LPJ%4)M`D;^Vio+D51l9+|LxXa7!DdB1ef)1P)*d z2(y!yho0{_ll5Ki8cYb)*itVPtRt$C*ys@mCUjdWO5l6!O&rIXukY@9P$CBFm?cKJ ziT|%`t=@$KD}lw`O)SSU$7>)^xPyc>Zhzl<>_sIaft6@p_j>Dz*$E9OF@wxxwZ#pD z*APMgS9Oa@ob`HlcaIaZ-|;MezFt2j7~mIjg&W9wjiXxtBw!3xS=`Zqv2VI=$8-Go z!eBMFx_alaV(63Fn^*fqXrp;Hu_^3X;p17fP_k}Tz)M3RtG!qo;^H| zLPYGmdj1?UGGbPh^e1N)XlQ3ah!~_P0Mp!TQ`Tp;Rwb(3?SMFpF4xT=b4kq5Cj>7RFth$2B6H&OA-jvalDQ`@-7yy z&kGm`kmBga;`QmmbNlEqrxu7z3L^-Va2}~BL(6iUf%|-tyBPjCJhxeovwQt~xX9u2 zGkwG6Q%G=SEA>T+B8NmrcYiM4{zP8i&I8t?7=C_!`{B6`2#E-8YzV0|D*%@fPbLxi zTkREu_3%=n8uz8QH~Q?qy^Y+CWkmoT0kOXUfWnBWX@bzsmlv5QHq3Kk&J{ zJhwqORT`U}0)c0*aKMT1da+EaBO1l?mvilGxjcbD#>sMduARS}Xn#aJNlD^M3fC6Q zm>7Z>*u`RiXJM0uU_XQVCZ0usrs>#4y&@-$q(P)3LIOdPxVnbRsdPqD@Zb`|pA-!p zw~%UuT7-fu?}OL}@op-p;ah!7QVQsNsDx4g#K2wX2_<4;LjaNAhzY7OGBJrp1X41J zL7Gkcqee)GqOFTX)`HDpp+u7S!icn#T!yNSe3R8+ zJ22e7YX?z@{!sau*k^>0P>Gn1e3#cC!!`oi2`k~6Q`{6d0Z87+Ga{dy1cW-9_^5%6 z(mS}V8Q@9*D`C!5MTrQ0RZ!A$l0dKy(a?&4_WbWZ}h7c0_oDepM zu*2Y;fDh=ac6Od*qnejs7NkA|| z`aaZcMAt|4y2525-b3cQ&QzG~_WqxJGIfx0B5ux#v zTP$+*?{#{!K?V9RQ(7 z)Pe-Q%#RC|I6<#Ygs>DKBnix$TxNWQMg-oZKoCMo8=E0AB3Ox!bMX70M1;Z#7(D#b zPsBm$V=@vYB0eT2s05$m<9CAmf?$`H%m`Wdgb?JYMT>@KxuQ3+D^9dIK_wE`)n8op WWelvI=M9qp0000 z9vhK+d=Cr@0s#S6D_vbJWJ)!K;aNl973~wS7Q?MRros%DSH2)Y;(M zPmWd+)u` zdnfh2|2MezRwB8%!I8+!{Sgy0%>HKeRzUpf|1K6uBqA~TPXRiT-dx)jgzfEj$;6*1 zbYhcnO4VwmQmK|Q!e;8l2mobVjuA!JjJ!}-b9}%jD%H$d>Lo&&F-w)|e=0LCFj5TT zW~wF9pMM##wM<54N~JPXDwn+Q%glBnB#{)VW!KF3mHqIw^DY)jh%lvU$y5c$aWc*m z{9ehY=Vi)HV`k21e(|EX&G_<14?6 zwGh)tn>fLYt7dIgbxpx}%2PrdEdACbGn7?P6o0d}EX%HInyxF$s){d}-4LTN1rQw7 z))Y}x(8qZ_k4BU_?!yUmuk@&Lmq5JC-0u#gN-ljYA74pb*Z z7N@C(AXL^f6wQAubj>n!ybzaNIFTTN^?$R`Km-<-%bKApD41sOp{h@WN{qarIHl9m zvTooeRM#}qVF^q|!?3h+87w^uf^0Iuzk!n~^O zzc<-C6>Kb%+ql;& z2ge5o2Vciju}C36NfHIE2NKZ-cz?1D{nq#~nH*q~2Z|bhY1gNx<03&K0m2IPL)Q%m z#*yFq3VnW*PS1Pw_WAjF?-X_tw2cTQS(b%JUe_nrxmD{c=YIWM}`ghz0 zsogx4sFkIISf4jIt|mg4-1u()jI^Jt*O6!g0$9C1m87L-vN9(`?eePDnC@R(T%4U< zK)LS_8VJCvz9ele8AfDlK7W^Lq?6Ve0w^Hi84v)6heJuCVoS~we~fq{bh;qyd%{`n z@DLVy&LMOnNz(Jfh@wDAJXhm}GhaBvx`&IyUo94mM&o%RwlxO;zRmO8po;>w4|NAe z3s~s`i%|oLK0iwocmTMQ*8W*{AC^PiZa3FCI$B^yizA3zN^JZTxPN{QR+9Ay>92nCyMgcXe1m_M*l7>}>bG(;K)m$;bOyut>gZ-P zy1C&RRIvfZ^TZ0y5gT@3-3;>A5BeaSP?UtfZi@3F7)yxQjz`1?oem2&G=DB#kk zB#r~(x#*Skoi``({(qo@NT+Ym!e?1&j#x&QzG07*qoM6N<$f_8>oZ~y=R delta 2168 zcmV-;2#5F04uuhrB!2=>OjJcja7LSA3{Uy_`s{ zRvBVe7Gz~NNMj*sSQ})zh-9Wrx{5fPf>}O#OG{-yE{rpuT{Jy~Sv`_wP;VxBx`$+% zKCWgZb5#;!U>0v#6J|ak4qOy!F&YYG7<9XdWPMXPb4xR}f`4FVK`BTo8K-ephgm6>J{Cq!A32(D zQ>BJ;T0AVRcvu_?1y~?VMH5fzjucR)7BN?2GAyrfGhG@}Gb&rBXQd zZOeC1U(ST=zXGxZ;Lkgb8G9qk4}G&_o(caVz|qMq03zZ~nM~%&jmM!wNd6xN5RQ7i z*`)&@6bsBOT-mXY6Q$eJqr%?`x%2bmhvux;dv(I@RVK-GWd|6^%M|!w{?9}CaLnqd z1tWlvlz-5$MgJAR{nPRB`G@=;golT3-^lm|<7)fDLc_l9^&|jP=YKg_;pu@4Ql4hB z!yUZeF$=0s)&AJ%>=7aTysZzV@JCqla@4s>4f+zLbq7&4U}et>iyb8y(g~vn^jf4s_kc zB!7?uwJ`>-no)I;iDoYnp2d==73 zaDj!02eBB~s_G>Mia9*arL-~97#FopjSEe~kY58T7YShKslgr8RFd1wNT-qiTtk&f zXv>DiVq1~wxeb@k)N1V1btN%qs4PaVOhT0eLzbsRP#+^Z2rNQW*V<0vj#?GPXn!&T z^_gv}a+xAdMVQgbLiu)&HyH8Qx}b(jmULvF?1X!^t;x`!&vFOZBvR72n|NF zS}xbB7{=j!n-ZW2O;NOK5Vop&k$}I0eW6 zO+oc>g^HydiDAhcIHl4WvDo^kU^pQu8bg}KUH;%m!T|sXlA?^Fi2Z~4c&V4Ze=ng- zC}9|O`T9VK`jr+8LJtimV>B8CFrb)F#uknvZm5iq2!BENVh#ih z21pe}VS;K~-uuuS4J`y=QJlu`#k+p@M$8}r216JDkczn)q9TN)uU?iflg4rYfIji^ zW%x1?mnscJXGDeHA%QrpYzj-&rx2Dmoa>XxB$_YH?<6>nb6uz7p*lj0o|N9A6orFB zX_vr?2I73~f%r9Flvpd~e1EP^Ci<`Wyn$(}vu)yI{-E#?K&#c_L`x+iTrS?D=vQg6 zKm>}hSp2~8&&8_if@mo)=q4ggvIoKmnF*oMQ^NAY<$U#XxmYYAknwY|Sp8hhmt#gq z+r%jzoTn+F$Z{V`Vt1Xew3^RX-%SEoj@5j%DviU~)%Bhx@mq+{=zlxJp~474KuG9h zB#uopbW98)DcYr|ae$qVJ`w^;k^zyCQbJ=fJj+k+|3AgIJiV_e$sIIJ0Yv^|8Vdw= zm)hutChx)YVfiK}oRCJ*O8cN`9#9?a5XMy1qkv*C!fJ???W_quh}1p=DG4D-r;Iq< znlA{Wuc~%8ba)HhNPqR>QWC;eJq>+uqQXZ(C2#@;e+(2oH4=FYlpp&{Scgz#8pVeA zn0$*$$3sMW>ZxuwgyCQn13!+(CW=jB${tPWD0m;VtZ648V5rz$XvN1a$BxIZLCFcR z9Md)PK$|=<7y-o4 zW_{PD!V9eb+R< zz>L}Rt3O5!5Q5Go1o9GrN8V1INZUl28CvhTe<_NWz2})mCwB?#%-t&R7;K&(%Itc1 z_RI=xuydS1;PgLiZ=jrDuWT~vZLKw%wXn_*s5XSOJ#oz49hwrgGDEPEsLcrw%9_A1 z_dDT6LI8onivT*Trv&ZHy-wDIA~)+GxWNk?BdeU?eE`_+Bqi`?_p6)|X&-x?aH5?O u9ej3(wyY%Uv0uVI!3F&6q+r6d diff --git a/TMessagesProj/src/main/assets/emoji/0_1133.png b/TMessagesProj/src/main/assets/emoji/0_1133.png index bff484e151f0a6a9428b4be95e6905ba01a732b0..922a85147ac3433874356c08f6b5bf52d5445e4c 100644 GIT binary patch delta 1866 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 UT#|(-ivR!s07*qoM6N<$f{q=P_y7O^ diff --git a/TMessagesProj/src/main/assets/emoji/0_1134.png b/TMessagesProj/src/main/assets/emoji/0_1134.png index 331fd8c0520f30dcd37e33db8f2ac41e658f3166..f814725a323fec7cab374f85a46173bfb96a936d 100644 GIT binary patch delta 2396 zcmV-i38VJy4(1Y&BYy%PP)t-sM{rC~ELx#x4stnog;_{qHfP|qTJyzGsBkS}G;LZu zT;8P~O*mI#Fl=!-cvLK1YBY1$oe`~b4pTEEGMnrh|R;%wx~b%-`SG`~Ux$T?^#Um2o(DYc_K0vn1fA9_XzdwtEoN zogc-I9OADkTrFeox-4KXXUdHecszaFo*DhfE%?JL^}QqVy)#oLS!}b0YcO>1zCpc) z7i68A!-*ASF@I~)mlyE2B|~m+lg`Ta%U!#F6tQ;^p=J!JZVlF>D`Kj9f4`P(rl|Sb zk)$tHXM?`E zK4VC(@Z_K0)%@tU_|}4Sy^n~^p#Rh@b+xyCK!aSObAMNxY+I0#|I9E^kYtI-zLVXo zNp^Xxe_wl z<=Xn-qx@`NrPCqv!B7Kf!5a3+Qogim|jLZ zPBd9um49wHi&QcH;$^3gNRF$4ijuCq(%x5DKF-9oGgv*B)URNRdv|_Oz|O@wy~Bh6 z00202QchCDF<{3400zEEL_t(|UY(X@cYhmM5{3Q{vzznZWGO&MYX6 zAZBJ}HZwCbg_#)!e&AMjlzg(B);vc?#~)me-l}{1-mW+taSb4@_}etro%{DcfU{Q` z|CU8uclO8Vzzvpx=#OXX1Z5lQ&gQNU4BX%x0|VCwMdxbDG+Yr4Mx)n3!Vw+Jc|_lr z<$n-d5#@5MgM$-@HaEW)morDR#{&+KLDvy;X%oaP0<#Mk4})z@A#&m7_%Islxj6a;e=DGnF_AXTWB3F zRpM>@6m4{nVX#<0jcK)7jb=(SrPYp%OldS~KXHklqUxXUq=K`q@R{a=;|0c}9of$1BRBO&ajpVrrbg7 z;{R%@ehPRkHk-{7NThBbYiX#Kh|4i#GMS6NUbvY~#N+8yDz$7-jR6hSLcWS$FAi)z z9f&@8wtSN%l`bg8KGRw)=6@IBzt^?Fr`nB7=EkG@sdV~&A*(7XRH|xTGx^W8&EUpn z@MH8^CiAgSC}d?w(SRT-q?(68^4li9x5+#nB%Wq6Pu{J`P(;N78Bhd4S|#5!2wV2F zK|S*tW-a z-IX;5p z;P-p8;WZO-~kS!^^-TVA0n+bi!PZ`9tm!(rpl!U9Nu*>x0c5gyitY0C>( zEaWS@U17Jct!!_tg%^yWp>TL%7+6?X*ft%~iKG>gW$%(cpD*xArdV59fAAogjI4); zj3FZ^IEEH>O{KS&xM9qmH58Hh27lBK8I8s}CbXgCdXA0R z4F<#Q!g3+M-rv{PwcphT%!ERr@sM!{U}d2{P_$K8s*SNR)Nq?6AKCBgVhyaLXJUMO zVmuTw8bLKNG3_e3til#}4plPFVC{qm{ZQWp%uG*Dzz0OEVESPmc4+OvZGZtmP#Lr` z*VEMp237#WaDPufoQ4l80>Q)fyxoo-G*5w~l@-8BDrDKo&aVB=eYU*6zrWM{M|=Cj zBJJ(%x9q@?14D2Ig-n(;omo*tljITRoOMSVp{>btwUT^#Vo2YhCoh~o57li|;;&{2AcXf60q?gQu~5wGpZ^a}uD`PJ=Nl{l O0000Y delta 1887 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 Ef;DS{5dZ)H delta 2633 zcmV-P3bysA644ZpBYy#RP)t-sM{rERjVObIgM^5YdU|<#e0+n0guk$#!o0DlsHk~* ze2R&M!^6YqtR0w{oq%<2g@uNPhJ>%Luyb^Dl6On>z%b5_46CcFopUY4#l@C|VUkx3 zh)xgkvKY$B%JjZ0t!)S4sU`WxH?V~`l$4bH%s8A~1I*0K-hZDHsdXHGbX@w&HTJ|r z#fuu@q!*c96355KzrVk-va-y~%$u8=@xf8Z$jH!_8>N|jbXq`ncXxbze0h3$?6Do_ zs~YmR9dvYb;iVbdo)^uK6`^Aby?_$bnHj{06k=m#vw0EsydeM0F#gFZot~a{c6N%3 zi-CcGhK7celz)}(wIz^{kg>6``@$rdnVI?1YTmOvu5k^NSPRRbMDe;Q|I$AA!YQYx zr}4o-{pq`+qN0aR2I9$!z`(%A$H%U&ul?=H`Pzj0;h^xlILyqxhLiF zoCz7`%wjP-MLOYpkL&w?gZ}1%DIS8V2yRO)?>Ao2t-KDzr$kyU6Y`?h|#Fy1N_j;qPd(Q8z7ZZYiQBcaJ~5cpCUchl`yZitMP7FH`NE zpPS}sB$C~^zbAkF;%|-KM;GT8%qT`8=+JIVMIz~A0vzui-~Z12op63m2sGI}&idKN z9DnDI9*T&&IK4}A{Pf{Pd^j(HxVWIukjE3486BN}^XARs{OHUy=NU}ykf0`r|MWgY z3>6U^$FF;PYyExmpAQZtz?tgdW^5$7#t%%Tl?fx_hH&omMKxf#@Wk;;- zjZR|Y^7f=Kjv-kMjM6#A9tb9s(@QmHyA6OwHgdUrJ6R_Gjv2c@juQBQ5(L;Ahaj9d z*0-~bpR#>(GFe_5-z$PZejEkMhK@yIlLcY&wqfa&L*xuOY~|pl@hqE!ff~r}?|)qT zO+^G$SX)cxGW^MH)v~IUgCDb9sel+smp8|Y=j;x7+*Set0%5b96-OF3-;BCb{Z?t^ zo11FagiwItj`CZeRRVhkK!rkP=~?4u-M-s$=GL1h*VosNj>s?7hBcDSVHS*n78g(3 zON_fhmM0~S?E2kS)Xw7^IlYYJmw%6tIn+p(lWSxh7Z*Ff^)@##&Hy3^C{bO{>osfZ z&UAE%o~8u8Jj&16(UA;BX&P>gp*5TbkR*aQ($zRx&dZi&n_F9^Wor_Ie12Kh^T?cS zO^8`y;O;=!HUf_bkW7}#g>*(-I_;_+d{>hf}l$L9zoN@InxXz!Rd+vK*x( z-JYCWU!ANcTw#4=^6L7wp~M_Ze;Wu7t7-}>%|OX80_RCmlrS7aiQQaYOJ3MF`6+MQ{5{G}1mv?8El3vs1 zJ^elqI3|z~!iV!J3-9fjp3`k*b>s3HM{4_Lgh<5qFR#8{-F59BDq2(<^@LI?NeT)j z0^T;l7vf&Zx)fX4*uLB9+TKSCl7s!*yL#jDEUsvdHskT5Fn(3A@UoI9NxDAQ#|1&SAtyXsH{T@CE69yfqLhfQ#1jxGLBC3r zN-+>G0~j5Edm=N4?-75Cz=iUK`!rosKp<48R0u&+ipje6jvEyIA_O5s-t|*3nuCx@ z3{4_6Xkv*U-%ZplishGgM8G?qXMwu-IUK(`<^2ge-U9uhxp6W%3I+tVF%`OhEY7>bf}q^s=^3l1;xFGc+ZJD5uv~$aOSE z1j(MAed`ki5rkU;cLhs`Z%qOslMRMv-eMFIt?Tr(OG625hVo&vqE% z@E6lOMNGUof5GDt0wYqCXkR8theB}Ft(M1#e@;#!8*)-B5P(loO+SBV} z+aLr4yv=7tHS+zWN;3ihbOG&L0(I#!+rt)$dLVLmqjQa=lSboYi3)&o1=^zhI}B;R zu74yVB{tcIrc~rRO$1vgl*=x`yUXnDAOb-uU>WT52l>R1#wAoE5jBGma>>nPlW5(U z9r05FS2arseDc9CEICZJi6j}pE*u`3o#_Wn!ajXa0|*NM_A&=Tq?^cidjND!!VIxR z0CCfN#Rys=(+%L^Nm8vAEX-;n1fG;&PeO{$gcyN)kP;mkCq}uz2$b;kJV5jWhrM1e rehw@wEIfKJ3kw4SUK(F_pauLF8fUpmHEa7&00000NkvXXu0mjfz(WoN diff --git a/TMessagesProj/src/main/assets/emoji/0_1136.png b/TMessagesProj/src/main/assets/emoji/0_1136.png index b49cce840653cf2a4aa8af632e387d1be3969ea5..0bdafa0bcd9dae9f4b145d548b2c0b43e5d966fb 100644 GIT binary patch delta 2431 zcmV-_34r#m6NwX$BYy%_ns7O8*v5HfJ6X!BVycX6c1v5oeNmcQ zGvwi`-pztlEM9dxdSWqaYBh4GhC@h5W5JhKZ#Z_+zHrH!WZlt_l2bHUEMHAFRbnt{ zayfbE-k0Fgio1_fEn&caf{ERG+tu)^u0_YQQxzRo7&M~sCjs_u%O`9 z=-ia5>)$$PYBW+mg~^?BypC|Hs7`-?L2yl!)5~9%m4CdAQ@e_0kjluTa6!tEWmt@h zfxfq>c~zw4+E9yR%CcnOw~(4}ShIjjH(o(gLuY0+RC{}W+QO*DvY5oIVt++ihoq5k zRzJqo+S26b<D8PEu!-;H*R*OGtQmgt(si_sVfgcRXfBQk7-p*p7CK zh**VynSWbRg`KTQTvqPw-qXjvSaEfNN)dn6PT3z(79dLb%VZRk{^RQl7rrhz zb${e9SwsaT7wotGiMZ8hDk(_baHPc4c~?!&<9k7)-DFaiWF=`Z znM~l|u-i>)b(&gTDoUo0e^;xK0|8HUS_elm{W#m9222QeqVzqW<8Qpn5S3;NI?~e8 z)Z7QfRq$1*?q%okRTOlXyx{0SfB?u=fqw-YrF@I{%w*3F3htpe2snioiU7-JVxGOc zm}XK3$JPZR2mUAV3}(+8rg-5r+BvWbFUy<;3a5nnIf(L;GrZn!LvLk^(ZKU3v@UT zh}3Wb&QW6|DdMPzXESEKf?;ATFrrk#NaBL#Ipv5}L46_OJreJ*EliVI5-E(Rgx6s( zDyX9=JUKBttFckE0u-E~CNdQWlz$mX1yR9wqh(bDHN-dt3Zs!k3Z+7!tWkm@=Lp|2 z@`i^sHWt=IWGd2(9L+GNoPuvZMH!W#Ag1O6fiN^}%iC0XBo|817=v_wPLY&Jqt zmDzOoO#Z?2BrKwDVzJow-+vu@m01O3zRG-Vk;{NHYf3T}d$KwPg*;q_BI3y9{2T?VO7?XP`*e3V7JK@`56c!kBa1s6 zjKgt|he7y7GZj(NYpc|1EVlhKCdC{MIRG`_4u&aC|MV_9`BF)fihszOHnRKV$-r3oSY%q9q^QQ0qO7ylH2R>ECar`As zE5O43LefwFx4r$}fB%ZF)YkjWwbyEU?lW!-|3n$-hh;2x7itwWvG&_Pz5TB93Mv!ub zp+PXTL%tJm&VS565NVKL=F(L+hL!I<3@|uwOloPeJe!2~g8}l;jM16U%*>^`01|{k zOKvN+XFtYQw=_AD;m ziL=;!#gMRylOGLNt4E#AK`!o`oP@PC)c>#U?#0D!;EG3ZB78< zXmM5#P2A{e=)MB^D|#y<*XgBFL+YOA#0P_CsIRXN(h!F{2>QXW#NZf)-C`63-R&7!UI=5{X;`YQhgszjFF#yTJbb2 z!CNso!#EfOj$5UP6o9D6GGn~)S}b_aSBt5a)ly3 xSK{eoi1Kuy=%ZPfE))vI$^3;O7W4a`^8Y&<#gN;m2jTz#002ovPDHLkV1nta(P#hw delta 2470 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_114.png b/TMessagesProj/src/main/assets/emoji/0_114.png index bda566507fea96dde99208c8382c6e6b6f0f6707..02e72808a6b7978d656d262fad7dfb1e898ece95 100644 GIT binary patch delta 1275 zcmVv9#=&BRMeFD&m1^&%9 z_rN9bwjBG&F8|R#-<%5n(@D~b1OL`kXdlI60000AbW%=J0IR>^ewW?;DOz|c_(A{x z1bazDK~#8N?U(DeoHh)FXTTt=iw*Ps4_j%=z)6_4|Jx`l$$tsje3G{Wti1jY@h7%2 zP0RK*vmo>Dgh|bK`lg(WP1b*8Y#y(o#;sX>rmHkh=;FHiH=H`Du5}XL_r~85`_2*) z*M03_6>d!3T-a=JN6MWn)4D9ON2YgUHu}a`)EcvP-aVwNu`E|kn5Ap;3=#S6Xhu&vDg}ZA(Ojq8ykH%O;5H#{iHMw*2coFo%S_~e#sur` zE&^du1P!ulWO)u<0%4>r)q%KnV6qkn34|oVrmyp8EM4|b$Z)DlwFF|AVI9inj%|d5 zc7vM=Z?9fUZj~}dq8uZ6jJ0A^rj)8glq;(|tiDI`@PBg=Ac)e6yrp83{f|nCz}jh6 zd-yp?jNW>>*`sBqc@?QujAp_Rx&Q$)?6F*{7&AjOw2garEUlbBB{{Rq&u4b)VsI0~ zRDu8>Acv20GH%&!jT^+|Wr`*Qpi-BHd)T*~AfM zy_?~Hw|}3MP3lsobuHVg9x9?U8KcE}AaS3Wth1O!BF~wA0zn6f>QP=LghuJ|jbPls zqSIT2xeusaZnJbU6X|atm<1Xch;vh!O_xQTPLvyYB9KLLrU=!s! zk?cU|I8`9ZtM-s^B2d1W>zz6fRV5Le2$!jZsDJbC2##zN*`;SmZ7f*|C*owF znPvn@#o}TXNFd*U&=xg(B2fegkJdtzAT~<`ys|43R)p3L8Hjfv@HWfv0zl+xOiB%B zJb&^8agmMlsooQ@&X)k$oo+chm&>$>L=nVY zMkrq`oQV9fA6-&lCnFkNSH-a4!I>8qt0iK&5TpFF0k{bkN)==5(1i$w z%Uv%60s9;guWgbc`6NS!;O^pAgbFkK zMIN7mW!SX`qqzp&41~FN!VSDM9lHu~PHe%~^eThpv8XYEP3IXyz54I~0MPL<*?(4O zZbrKhVenE2t93HkFfyIc{G=`8w5RRRgUF`6;M&<@x`W`P7B{IF6s1Iv>c6@Z=Ks2c*m{95K&j`!)Igk$hjtC#9A* lqHGV%b|yFa;|6H&$}^(j%GGpB9{zu)6YIe*^ox5UgD)#6o%P08&c zEi)knx?k&)j5bYJJRlknkl5jwFz+P=;a$pzvSw8%G83#ikMzX2YbX;z2{s)_65Un+fyE*Ko;xWhBM@vSa~@rs2)@oz z@N%(g2K7B1K!12nbScMK3M9N{;)u-;2v%8$`i+?O*buv#_7ghdn~ZyHXEi4S4cVub zr)n1iE~K2*q<;(quXzSK726TD`X8y$3Z-fi z`<|Iq?O-3byX{Fz8~8KUx(HKW2#uWwLdF2dw-3ZR;U*z1uQG*i!ZLS5e9Tz*x`3dB z5F82qu7$uga`#v;DcoXW*7ifgaFGxk5#k7%!qSBIL{dPIF019$BEltTk0V+mcflJ$ zzY!Lz6@T6yBak7)5DF>~9w!1x4}o6gMu_*3gGdDk?+C6_90)t)d`39(OG8sas}^|9 zPsDq5gf@b+hOyVyu&r;tMTZNzUKi%l$1f`b!hZ7opVsn?KnGW3Ek=tY7J-g9qKFUe z^x+X0f&ouZD1>~HWh0ohpAbA|0kHulCcY6LF@N<=8G(u`Wr7hWK)lQD!Wl3EO+pCA zG6)L@%r3C$+zJ*UW5_cC3?~o>H-ds*NEHM=5C}Zow*`N7*O3}P3$f!wP$2l1gpr#l zQEtz3vw>yh(hDXqT#$6p?Q Y07HaRAS`&K+5i9m07*qoM6N<$g0DlV_5c6? diff --git a/TMessagesProj/src/main/assets/emoji/0_1140.png b/TMessagesProj/src/main/assets/emoji/0_1140.png index c0417f596764808f96d5a8c4fe660a8dfdbfea6c..5cd620d4f140ff5695ecd55e9bc93536fd8dfb34 100644 GIT binary patch delta 2461 zcmV;O31aq_5T+B5BYy%c@1b;;Z zen5lU*4ORq;WlAoOC~+Jd=So&5yFTb>9H%AZzcQx{k?(+*P9sVtsvp09Dzs&rG>y(jnAXimAW@Od$^GiJ zaH^ihst!{`lNO9!dW1#IEqU^#X8ZsE2E<83K~#8NotM>P8&?*GJ+@?7wqppG(j*&f zn${_8+eOGQiJ2MA%*@Qp5M+jOclQt5Gjg2mgJqBM$q#e?RKvBVtQbuKLqpRuX^hqVO-cgi@XgFnjOn52 z>6z)7P^e7lCJ6UQ@rsiJX)!`+A%SpNxPOu0I3D?n*wM;U|I7>kOxYe#1Idkyl#mE= zN^}wP7KC9KC8N}6!lAVJ;gS)~Y?pEbBD#~0W-Kx%MF1pe9xZt^E2Dy86(eK$^I{wM z<3O3I#9vY}J2LX<(Jbe*YgADUI9U3xDPk3NhGNb1vQ)ZETkK3&rCH7k`E<4{u`^^?aWEp2Eo?;0^8C9vGF_EFo~VXxsM48 zOWKvhs6QBe4=50p5V_=%uP8H168^QoC=>m?!%b6S$9mRGn@Bn^{Cj~)1$B{xNQFG5 zkTp>x0jm`bzcXm;qoYbC|Fzitlz$hntcA2&gW!k?62|HG4=elK{6|S5N&SkInJL0< zWi(-ppa?TTO@Du*cm-5p;%F#?Q3jnP2%-QO1O=>?*s*d_i+On2KRXP^5ek6-6iV?` z00k`Pw9uo=q_VLQ6lGSS2qp5vS@8;CCT3Dta%CgW+nto#YPGr%>OzuuE`JnCX^Y@c zHj=E#g1D^&%_Co@B%qL|6quY8$y=>8GDbH^N)sFcWpiXba78(qX3{AgDhjemAF{D>OMR6v6X6G-UoZ zTOviE43< z>o>~gUxem&nr>`v?nELHHHua5IWTMjOBZ3t_rI0W?=G@*AHFufkjIjR+T@{htbH2*@gx_x71 z3V88UuOHtqKAD>v#|!{|R2k`pUBn(_7?2Fi@9a!X?WmlFx#lXHv9GVMd=7IN3`dl4 z?8H-&Bndmi*zK#^zkmLEyX)mNG1mu%=Dub@^3Y{C{4^xF`X4Eag#rn=yS=^f_HD%* zRj{hcYpZIG5pyITrbyP~!)B)$_S(6Qk3SsWc)R-p{k+O(^Ol!aH4Cr4C%7T^kR{DN zVR%XdPTI7tP-qn{Z2aL<+*t1Qc#X#LDxkcoeB5 z?mUZ&6*^t#672NWM%(@S?e*>Vfl80ZQ|qyL0YT<@?ZV?7#xeL1;7dzOop(DId+P7E z3kJbaSzB9svwzm(vDrX%^JeK|7anJ&b=54?Ic>B1%yY7|8eR20Po zV0b*((|^-b5lcfJ1Px$V)EjWzpvQzifLe7Ng(M#of}y3gwN*$zfBppWAn-XHTh+kC zI}Bwz?%xoAO6eO)rc!XTt-TlSq*qTI9d;)ui-k?C^DFFEwnZAaWh8B2u zOT#bUj+)FAHM|}{A%pLuPze2kA`TgunLeMdL4UvpC$P@4CX*?m1GI`gVDSL7C@C&q zI5PKfIDX?~9Oo|ybONXrjiHW_eAwNZebpiG?Af#5{#^pVe@B740OTMZBYyzWP)t-sM{rDNW@UPMdQwhHD;^iOxVRu39FUNZm6esv&CG^| zhIn{*rlzJT9~($PK#`D2 zFp47gc0BwifV*+SG|Z)*;xBh|JO00b9s{l$MPWD^$$vaeBYe9Z{(a!b0P7L7F&*}L zV?sh8o9W-0$>rtjG1jyl0qJP0%xkIVAs6!F$Ny4{`!nPz)3j}v>LadP8Ip{Zrdjv1 zOXI%_PiK_ArWNvr1!dfzj!4sj=QHGAmtPaJr{^bSWZLScUGfm~(6l}P&g{!MygY+o zEO4hGx9KCzA_gGP%aZ zwI8WX{6Ri%#khMxu%5F1W{)QqyVWVX?ZssJ@EtaMWqi`gjD;5v>-Dmn-&Cvj*;XTM z38U`ylUD5S5IF1QqU?@}cfbzWRyqs>1Px^NX@47><)R-<fwxv?qGGZV8E&R)z1I)dhYrr8=c33bV?}#To?X{#_A3 z)_)}Q69+995=POi#cIy$tEpLy@qF1T0v{I2ELi0rOyBqAYXR((R|JHt5(~Z5#=X%l zLJ3yl6d+zrDS?<+g-<)Csb&3zGQeD(ia-b;fr=;!5UCDBnytl(kX672_IfjoI|h{C ziAsk6A`F2brdcym5hx=egEl%CF2ndn6@LKeTbbvr)B@?JQ52>*`avWyzEp(23ldB9 zg4}T*3sg{+Bm_bfk{j0bFp6B4nOv6=ibO%&Ng*2J80dh6AOO*|Z%k9_ZYWdg zq#ZZZ^GK&MMt0Y6ghxiXC?AbZF986-^F-`)jcX98OK;Tofa)nk8Rm^KARp@RssW9sev{7~1iI^@~b|9yN5Q)%Ax zK#;+RA{^mx@N*Ek%)`y`r;q&pxsFJPUY^v~qnk=O>DXN&U@&rpS@3GGkbk>&Z=~nx z{&?K@^7miIGgZaeG3BqvO{(kHohtzX2rGfzF}h4}gt+S5&{0A=`}ynFUq6p;ig-I7 z=7#LF`u%+GohIiMVjeiIZeo8kTE(nO`m*PHa6T-8HIy!M(-c2lkP;o)z`KWj0 zIc)-W>Xn1k1b0GbA{d+qhQhd(koq`hq87X>5O%jsc=p)mPLz@6xY5H?5fQe<(C)U0 zt_=d)^<;nu&ZmB>j3}o=R#Sv8hv%MX2%08x9=8ZDnfP1=g^VzaPJc!4)AV7$1PeS0 z$`ujLsgp$WRT&#LnptuYzOMyBi1sKbMmKH|L9+Gfu@!OeIVW{lpvP9_cudq=yvu#? zWo>s7++LexAh~*g=Mf9KIV!p&I3N1p%Zi+cAer0a5e!TL>(ZRH5W@9%h(UNY;WT~l zHKF|JB$*pS+--z_fPV!5JK`EUnV&5Uq54qQwtbkXLbQk39;hPvWeFqJwjl+VWV?cp@vEB&HB7rL@DAlL zQ7#s2thN^s_SFRhfwN87Zxg&T+qr5HeGtmf_}sbE=tNPLiV&hMq8Vm;pgc~h0%wke zl?8#&5P|s;+kYn1FhA=gc4~r*61`hkj`f5t7X3aE4hz)B7oF6^dQC>11pqeN1p4@@ z6A*nYSp$KBsP#-Tp*CRCN4t|YvF1-52FU>73AF*y$5)-y$2k&OQAL$RP#^p@{?FKh puF4?mfBQU-R@SXEZ}!!{0Uz%U$3RaM#Q*>R07*qoL1kby#9WDNS)Z zYiu@dRaI3jJ3KBdFjXvGKT1j*92{~vcxp6q=(CLR*uh~iXkRa7bUtECGE&;1d*is4 zNJvPhYhK}}fVFH*YBh1+tA;KwF5szyIZjXL&A7gGOm;kcdw)NH78e)KnRU2qL^fPp zx^GDJ_2&Ek^wykryohlL2@0cwjo;nP_y6>5Hgst-Z}Q5g<*|(I#iHrDmfo+6LqtV7 zJ3Cx0V{$ooVlZj>)3A3td>tSn#(!Agr+}vC+-9Ad*`Rsuz?*!*l~^lZD<~#}$DELUt;;rsZoJ}Rw!Cxs(bgxq5j&oqjXv%9T;-EjZY<4tb=TKTSo>5 z2ky6!lX_Td(rvRX1Qpa&w#7(UZ~2 zF;qQGN@vcpmS$2yTSGJS&#i~0sJNbnhizFmUO@2Z*VvS5YCBpCD^WlDf-jsK>d^ z)#lB#t$(qk;+qvvVOw@>Xp~e&*1<0S-4FcIGt|&}>d6=X?r1$}HA4UZ05)_|PE!Du zDE|Kb3;qNaJ$L?7c;d*JwDGMJi^5c>>PGt|VZzs%*Da2Ce2mt=+oI*~tjw$H)X&h6 zJQ9yp000JiNklW)d9@XwvtQBBMdkO^x#!+K4F#7V5Q#*Bg5QjwwBl}KRaI5v-3rlf5)@TdmCyF| z{jIOBucy4KQkZXED5@;(f%qvs;_7^tQ&BaW&9cnSmP@MhszX@Ol8K%Pip3H~WnMLi z%YVzuXS2X9YjE5t%A=8Y#4Rnw-vNQdVOHf+Mx{g|&d`DogF(fQsT_AioHyfEE0!mI+~9AA~BVj>q>;x5><@PS7ivA*8}>vOQCQ@W2$Pd z$NG^(!jGobr-Aiopr4#_`4z+la@?uoSbxPMvx6U)A~lHk6oh%()4}OgKNXy=6>waL z%E3?hD2gJ84TL`xTu&u<3jem5*UGJoYQCAjHf13Ee!qfs@ObE!P}qa^W{zi*uR;o! zJ+-#VIuu|+P}7kc+!Ufe@?)tfdW|29^0Hx8M7UCkdj(uq5)1eu!35?1Zt(lJR)1X# z!&Onlk454P<07D+S*We(HboeiX3mEz7Kqb^?3Mt$#M)Yf*q{uzxz3Eb$HDbD2@W_D zRCZ4Y#RfqcYPl+ewW*+nq^DdiUSjKXPY8m$0%&du2IBTeBD$U+Hcnv`1)Ql(t&>bT z5n)^#;83_+3bd&deVeIYc(0@}t)KP=am)`CvF5c!*EfrdTJhwDumhBVk6d{jYf+V1nw8Ym(! zZs;|PAsRDJ2l>G@#z)a)wwZbLLqnzmX}#Uf_zW~1udU11AgpVCtRdqxZGSL;fF%FW zAQI+hsQcZMzck-((m+Q5ji%po^uO1$b?1zW43Z?P^r=B#wA(+(- z=FPiz$>f_CFZMkq+0YOxk$=gQvNA4n>rWe`ouF6W(QlKC?yb3mJB} zX?*?i=sNpN{Q2|0|NBeE06cwad4^*bcSCdwi)i%dRMKR6>*vicU&jCQuYZh;glr=t zoe0)Ze^C+jm@KV_GpW(*U*R9#A8vjL{PO&@#b^szEF&zPuQBYF=zK-PRs4NF%U(bZ z;Li@0^Ps5Dy$oc4jg(4F9ZOx>MJtM1t&59G9lhP7$D@ejTa_)KoagCQt^ z6?j(KtlGszEq{uGU};R(+uNO`w|8eADGGBbYEBI%k9*9zv~-#un;4&5*xBjLu(K?d zpR2fbW?0cdZV4De`EfW~Zs+py&dxF*o;R7KP-||*sbSvTHZeW{=?Rnvfv#g=#QWZO8TA&&AL?t>ZUiVVYGQh&(M{F6f=g}LWlriPggolb|+ zo12p;?><;?I#(d6JO#_GK#sD;Ygblg+#Nb3(Y=nxN&D8;%LV7kyi|%SWm(YCL5kc6 zg?DEb+#T)?ggX(5?7{F!C-zN{fmLAah0CSqR)Hw`ac1G*zzrN6Ko0|ZFgW&Jg*{;p zyOnSu0e>j!FZdtTIg`cdboQXfUafxB4o{v`DwiTmEQO-;6~c-tC*rTbwi@yL`QO_C zHklDzX>7Q7go`TfR{fY#v;6ea%^&VJlrD66q6=BYy#9P)t-sM{rE~#6Fx~5-eJfOl+YxR*4``j(d`~MQfv~Y7He< zlkB%JB2$k`ez*DBcPLtzBUg~lk`?*QM^uo}C|i?Pl-TvVBk#2z_scrxzC8ZTI`+OL z{K_{hO>#PW#wT8%A5e>0ncYT$!_Si)BT0dUMgrN$m|Adh(tnW+mt`YLiqbuO#%_Li zj#3Fsb(-&^!Os zMmc%I|I;o0>3^&`eaTFW(;iQZAVO-&p(lZNTOU!2GH$g%gUm*U&@O1LP>Rsa0* zJ0b~oJqBK#;66c9UrafK+@c2n00202QchC<9sYM6S%2jXF8;GP%SZl@^3&RC+^+1KLX(zBVvp_;Y+=EPkU000O3NklXG0rF z5(Z#NC<}=!vM~mOS=;LkcSldmK{-cq&e`GjUsX>JNWkvi`TYP$&<|BLJw5XMUHpke zdS)i=_kaCl5|cBdQwquD3ez*`$j<_22y?_7jQ`^+#TzP8de;i6AIM8aXUH~8yV~vvUKgVoG$(7DW zL(8Fm1dhF5(^Lk4J zo*9231V3(VZS4Soh`9W$+E8nL2LSf#vDb--t<9~i#!dsE#^F2I-s#D?*-^;s++@NZ zS$|$Q1Rpv@V=?-g@NRPx2*@VnO)@<@dR;p?*~gsJu19Ak-_lw{gFIN^J ztCD9l9?KZ>02H_z-PB_iFUvg7D}TCa*@h8=7=~?IR!kxKZ^Id8K(Gwl69{<1uug~> z(0LHF0z}hz;1oBq;Sl}HxRBXq#@1HS9cBfF003MJj{8F<#5PbUU~-T`u7ClGw``s0 ze+UvY;Fg-8edKYBkSqw}37MFN$@A4JtgqsFOchh$W!->DtqFn%#zqD2h<}gJNn{Ae zn9XK0qRl)%VtgMkMN^zr)!2$@Vql(?oE z@_!+?9gK&wQzK?Gq7VzjPS4JC4a%^He_2wgk*~lA;F=`IX$7Jv2~9N|jm(;s!WW1o zpPyGzpsAjppDT{c%Ze2n@qdRnRTU(x12W|E4J<$f07wD{M9?>BItq+}pKec2@g7k) zZeNsT4G3Z{`J!R9%LyVDlFj}e@eK@%6c9MIsSf)5GY$|MxxDN=bPhCE&@OIn_c|*? z;}v4g`h!5IoCF4BFbITz>!CJE%xSiz6qH)$$L-$U%7J@T%eOx+_kZ>-Yr3YGjy&TM zf+UHM@hA`+u1A3pwk%KI|Jd8xd$_F8GPGI;UtQc!%d%t1v%zo|{+8oVktjj`zuE<& zIp~|z3`0>4?r%XbYK%C!#8;{N16j5WWiA>n0-*vT2$TrJ@+J+AGa=hCMb@rQZemVq z-)%%o?cW62sr_r1g@0k_>CjssAgBm1i_o~*?G_m^9QEtO(&6fr;M_}k@QJmQPSktk9`6^0_S#36W(!A+)N4dpTpRAV6G99`W0zf<(2w z$6{1j5eZ*h;#8IOf#at{aJ;XK%m6C`jRyoC+EkErYsnX)cjQwa>_IZ5cA0^MxRCUZ zm|*Zc32_7a)#V1N39sepk9L<5ZqiO8UPE-*p} zM;Q^pYeH`ngyA5GN5G(Uc#&NpE-(TG?|QInLJdZUB5p7+6xmZ`1%+UobBQJr?0T?7 z-!{9{V4a|m7;%UK2m}EA!;(Kbh-VBKj|A>3FL71vB{GsU6!A~m4$&2ePMnc+G!*7I zi5}DLD1W?R_6?K~8HgYZ4uk?R!?qx{5&Lr>TvRy`A_?9o1hy%>fpV%xh#7pa2%OaV z0S|OYED#8MKPomk5o{#zn)VM9Gti{1Fan;h8BRUA3z+STHpKpZ*D7*ggFy*8iEgrw z2!?wJe9ntpv31v(o|>MXx>&z!9dRPcNVt7)+<#!i*Owu8ph&=jE>Df4*4=vNrqiJ{ z;Mq=UE*zE&Aq0A0dQ;2)r05=q^#IfC00EN?Jz(Ob1yYvLX__ zJF|bF9+5?&LYH8+VLd~)k#PS^2)!VpUMK96Lmk(!EEQVa7~UD|PG zSjUNAe8H8=j(=p^u885$g};4L(3ftVV>r!|YI;3@;I@#4!@Gsco>C@Q*T;KmpPQ|6 zMQgEzSB#3McUCrDVYzrsVyb(piB5H}twnTnvVUN>hf+^eVN^O|#g%WEXiE3-x0%?_ za=VOQn3mVSs6A&$t?%Rb^u9_bP;aTG`S!}8;@3-uTz`|*tbRd+K5K1nF?VY?Qjp8Y z?BSYCe}7w`ajIuM@8_aYl4W^2f6uyizpj+{_vlA{Rg~bY#jItG&!s;~O7rZjd%3f5O?P4^XfahgL>^1e-QfHE z^ILaymw#YgYd$5wpkvOpXXotUg;RKvyrRvuY=4QKQ9meYsK@HcD9fX5cxO_ej&v>~ z6?vJh#d;;;n-%%@)BgS3z0lFwyMJp{GR3oRk*#|F-4FlnXx4imtN;K2Ky*@0QvfJ> zJqZ?;{R0yHd|Ak}=au#;hay4B{{E(ZM*CrxZ-1_^*X`y^{Cw8wT)K>+-qgaX<;}RR z(=orb>f^-U)I;e2!C-t&^P3ao;H0#?pf!`gbN>P&fg`I)M% z1%F>9*tn&9U&}8keomBEbH75sX+gouvT|8 z0gk3Rs~k9qM4~ZGqA`)UcCCk_(Hz^DMIVk00M|Y<00!HzW(#x07EVu^ffVSQ&F{Bq zzGK=^Zoz2{C(W{_XWp;Z>z`>fTbU+NZGXGG>_CDZ+e3%mq2PJ_%q!uZ?0M#|7`6fP z^OyZ`z20lU1t#2IXscp+tiR!K3i}-nhaS=IRnUY(01>`Ck zhhX>A)YP0wSorKDi&-H@hc&}tS}4SELM;GH?g!i4Zd^djUKTP;W5Xlca9AgV`hQJ= z6mz)AgleG+g`1cuHdPEi3hQ`8EWT|nEkU245QblGXLv4-Ke`;&(eVcl;zEHM{@_6n z`0T?CISebQs0iyq58QY<2V{Vv#%aQ!W2z`CER?GZGy$m9kOs2E;%*%0?S@`3<7i=6 zW#FNaqy=;C_%=7L#(77X?u>%tg@0j%K?e>(K&X)e7ZL(Bf%A4URj@YC`sFGe4=047 zahODU9t3j*uxYp7t5Sqe`spmxDT9z^uHbGCI~1yr+Z{t46_^MiC~#1~K$udtM=MuA zLs3U*npV8lXl%dXJj3=J=4=NC%oQAjZgv*-hsO4h=It)aLcuNDELW&>;D4C6*+B4z z-=XE{Hgj{ba_oUpbo3*eMl@ccY{f(W@9*Bd7>8b}pqbe^ymFP? z;q`_>F`P&1R6DbNH**X2o`rtEDdmB{pgLR3=4Sa`K7ZlIP5YrC3KgKxI;;l|l;*8r zF*g*Pzq`12q57QO;nixruz!kYtm1Z{G%uI&%jEGsb=|(v(Q*A$B`n`ceV4R7&4D}? zvm|~PC1Q01e)sOwJVre^R7b?-1hLW4(Z#!UU0q#P31u{klvr#;h)If~4z5|%z%CglXq-205`V@<7a!kwd}pGQ zqBX;30zS;HiyR+>h|3M=4PnQiAkk%XlR1!>?FzctEG{Lg?Q+a zA_+bEEAZEc&Y_DIr}E;Zi%*9rj3i6H*ir79^-l~21Kd(v$WtslHFtO0{{EOY0GBR3 zy@9Qg276cMeHENZkbf9L3k#DkUrxSy^~z#NIxSbOT)YAj%hBCOFg4=dBG5GMTIaF#CMIKA$rQAerwT zhGlBTnuG1_7$|Pvz8z^shE^~jMPFavV4u$i@jm!A2#O5NU>|6QTflDuMWnXolR?%X zGY<~-!2=*cTYp;w!?5C&=hTCMl4%hCoJYDf3rQrlqLV4Ak2ktim@idLM4 z5e%3}B$e_du9^l}O)G>WYPwzZBW+7dZNSpf$jDU@ux`a(8X<+0z#46CmDSY9P&m+S zw%6B>EK^@U9nGZRmZl7RzC(fl%YLaHmV%H~wHDZTA zh=xyyzaD6=?e*NcH9dU`xEhs6q(J^kiXEcm9HPAebHI$aj^dl`wXWcp=PIHpDx$<9 z37@~RqDYDiK(IE@96-?l6c2)4FhocagH1u91t4u{u*k9Ou#cd}%o-vQd6NyCL^aFZ*<wdWm#jsUl}zeP&-kfyqREz%xi@ zI(x-GX`|kuc=_11_|&j2VVlvCZ1>WwS(x0_m~zU7URjmcB!49;S(n_{opkomu0K3K zSeV-?GC^`?Ut&{C!IpMMKs@28gYL+oIr9gwsGjO*$eaSFvvN?If6%!I48yeZ2 zcKqGD`ryAOUVon*PKq5;lIXaTNI*aP>(1t`hn|LXAw_YxnS4PnCEC88er#hlb-nxJ z#7~aZSx`?5d&70+RU?z_xbnx^5N&)%3nx4 zeqT#DGc-qbx3_*uST`u<(6ZdkwY;#Vlwl8Eo#24+7JrZc00202QchC<{ZYOC@EHsK zF64#QZTuQRE|+T6-bbuh%Zm5z{aTl)+sb0Oj>x0o)pXqJ=+u|GqouIo%C-Jg@xlNA z00=BeL_t(|UY*y6R~yF`25|KP0)Z&T#$XI_Tw^;<-eY@T_1-(ZcifYI{(UpEl7)|) zyySy(gnte@KizwG*j-$IkzjOoW@Bw_W7hRAGrO_&QqpY8QeQsWi2fVkkyO+*!zj27 z4SD%!Ciss59UrerYHd2?Hf+Pv)wP*_08G94y=XyDrP^<+vopVjnuaY|MRo1}Y$q6) zY`6P8-BKmn{eqG+3x%eksaEmj(&W_N0*gOAe}BI7p?$jFv+UZ!p!DcE8Hr`LmQRls z|7Iq0=YNtM9-Z#Ho9naRW)p&Ov47fLIsfzd)49J;7I$`bD6(^O+Fu{-e6>*MET5k2 zz(;=ip%K2nbGUPUPLL1n<)u6N>H-AtEKh$R1nwUmQi4=+68o;&srC`6;T(Z9H=ekE zn12MZvvY`?Kfv~0T6*(#9(ns_X(<|vt-wAGW30|Ei8v zceB6uni!-M(h*u2(*{d+E5pBHz#e)S27f)xD`^}+<~633#pJgdGV=01?SGI>C-r(H z!wibtZ6$a==>%OQPJLKET=<^k;Qax~vq&n7W&ptWB``|N4S;kur3ibu{AL|X2cgS- z2R`I=!ZDEZ(G3=OI25)NdAXi9bG}i58UXTnUnG&*f`KxS#qVdCCPJnhe}CXJO@A|& z_Z{3Vgb?{>euWsUjBgVSqlmO4B*Zoj?cV0UQw|2maza5bXoX~MSj13BDP`_BpU>TD zh1+h9DhvUDEvc$zG=JTp>5nAS)1gqI(Cp^&x!3*?<9?9s2?kK1>VFTR zu4k(B$cCBCqJm6DNytKVaxo^;F>2v1-Ysq>L+n+lfUAI8onD2t&iE5k|-Q^1M*tBChDK z=8Y<;_Se?!S^rw!-Y$`^FRlJr|4R?QxH11bO9%mmTt*%TK=4=(K!1o=IIru`b?!!0 z?d$%hmU;H|8U;XUw06ImXPs+91#z(!nBd|941&my!yxE-grmf^udAuO%Nx_gqAOCv zcJZoD-hI66scJpf1A$KyundSu39?$?@J$-oD1y*FU$)N9&i?pv2>`_9SMu)S@-sF@ zUV9YwS1KHbWk7gJaDQB!1TPrpjC$KOG^ugb`s3rpXN=|sFHDWYixM9N(F}_ zK)eB$CjtS5RpMyS@0qPNr<*u?dgJ=~YTG#<#m3e3bpspDZWfyE*~w}JMw~c;h%*xQ zf`CD56DNcJafjTtB&n)ScLaiQV2|sns)E2%LeyKuu@%Z-1%EbpY?Sc2p5Q10gryTh zFJXVtAIM*=WW)b0JVDnpLI&ZQtP+6{ygxism>v+tl4TRZR!c=j82II?M?~Ka!Sfyv zo;b&dI0$s|V!cq)B$bvS6>5@H3mGMy5?ZaW{vzn*+il~L2pa>p>b37dd;vob@K!~z8 zILijAmO5unS|xTq&CNxVCzt3n82oAVs~`>Gbp>1ad}yj)o^dpb@7Caquwg5u8q7fWReS2CWc7vdCrE zQbA}CW&&OaBLoJ=5{y)t5$7mT_PSQ53#<mZ&fIY0;7H0aqjBP{&5=u zZkmi>MZ`UKh=89NAm}X@4+=u%^tffKh|xbjtq3w?7-%HUhUxw8*)>)jAyO$AGBNgB zola{X0xv5WdheATg6+)Fc;c)Ro+rc>?)HkzSK7xkZFVP5DGIFu!ftS6bx>=wg@08s7s8KeVyb&jb#@>V3;6i!zo?H;fq*$qK2J<%Q7J}+z`1j-s*}&k zjL@VyV?CLgs_WmJ+tOR0aiitgZl$C< zR8x3?hf6HQGP(?rh001s@QchC<9sW`N zG7$a+{+6fWbbfP|!G4gbv*pdD)xpc-@mcaqkb`OR}Kkjy-Ur0C6JQ4f5Z zbFR|z0D45rFQeCKyV?c@2HLu`nqLy=+6Vm0v$L~Bc>7@ zn=KS-ri?CIpo*goJcgY4P;5xAdNR6gh(Jw*6r$ji^66Mit5(q-O2=$fkU^0pryydS zoLAq8VK9((3h7W4NpLzP8TXkol-(KXQmcSI1Oa99`8?z?-jgv=9us93hBRswF17p?{SYM4q+houa=Uu8Js1WI9{a z@m>&QR&g@E%&h^MT1Zeh{+rsv=9QDdaetnoD9;VhmF%Nf7z>pQIz=PSa=yC5HiOzTb4ZYkI1keb15lq6%H*M%P#D@or(%RT@o)@wJ110A3Y`L-U<_lIp!^zj zg-Qb|!!BS(MP_hFq7r;2k7B^u`0)hQx89DVn3ap77CZ; zvez4=tyUzl(zKiIRCBlgp5gr-ws^`H3x(^$-D#3`yR8T}LDTez?%_6`B!4KD;+Bh? z{|FS<*C!+mfPg09iJO3z|MTh#qWjf7vAo;Gr$sN#M21 zEHUfxfBFl!`ay2bOs1kUGc$|ZG)V3*!=NMFJivm4!;6=diHV;-|GqIG2`WT)|3J_e z3r4iCIUFlq9)9~ae|2@WIDfg6TAZAmnXEe=-=}y?5EuZf+Hp*t?4BHc^Z)bXU@@9n zS_B7T=71!g=e2_jIBgA%bBhz$lD- z9GoUj4#(%m$2TLTh z)DkHA8qTN7W%hc#pUdU4`EcXxY;|Mx3|Pr#v+LQ^5`bjcQIZ(ZH)!Lv%SD0#7~9-9 zTSW%+s;sZC@2qFDkk7)?PL6Ce7@FrUSj54qA+lCAKp{Y7X9t4o01}*^kC7zVdG~y} zU>6W%5L(I2Lvn2u34dTLCU%mL+(95i(rmGi9e1|@2GU|SPY1*M6RR6*8xRN9)+Y9o z$@AoSm1HuxWww|tt#=k-g%Thi4134MQ4+l&KQXZq`977bGc`4}XE8TW^xYW3;oJ%& z*AS3jsmyQYrfwVgs=yo0MaDPB=Yes^Z$|d_M|1J`7__{ zUqLXo7Yvea`hNz(5^SIV42F(5P>k*)M!z#m0B%)`2?rrV67WJ;%)y3LAaw8M=5o1F z0P3HMiwv9{wqq{IgJU&+^9^aB-+lzMlXCOF@fO@L5>RTG~>|GqO z1(fUvNs^Ev{2z~cwfEm7`e&`Z@2csvB)#e$?9ul0wmSB-KB_U?+oA5ChOTF@ySw{+ ryH=;aHR}M49@47+1MBthbrt*z``#iKuv!$U00000NkvXXu0mjfOjPdi delta 2561 zcmV+c3jX!Z5Q`L$B!6yDOjJcja7;#WtT|qh;;wqakYgZJkA0WAwQoj9ZKEYqjV4)? zB2kSbSClPSjz3(7Bvp}8j?lJoN4R=YRgKKow}O?Ggne;nI%SvLvx-WF$vtY(py^HBju` z%BzKE+sU){_Vc}yaG7sRns;H%sD<~~X+loN<}_2=(3zy%+bAd;fj*93ci1Y$tw!;e%$Mv%Au0 z>%GJYqJLZ{RN`Bo3{fdiPfb&jBk>vo4QUN5}yFtlB74E=$oWt zo3_-J3gv$Qc7IYc38hJ2W(eXk$=LdnG?NN{xs*ign;_)w+W?qM29uezL)*I4o>7^d z-46k>dQy|GZ-tk8$+Xi%G}n>CfT8DJgj@21&3~r+F^UBS!yFMynMgZ~NdvIg@@v)9 zI|?bwa?AJqu?)ud)yXrCzFd7nh@D#& z5D;K`J8LKH3b(BgK!>C@6X(_x2wAouts;87D+i^0Na>(L#1lJvE%0R-pHSQ0xXLL6 zm4CyZ!IR|@#kmh*Tvww?m7+1Vz(P#L7rx;K5DE+kHa3h>i~xi0_VZ^@`6`^tajtu|$72E+e~dyJD?JRd2;i2{ zmdVal!&n$=qa@C!*f5arSf5}(Th@xAIDf%m>vP^PfIvtswstp+P~bwT)B=gu-(ch>oqpn^!k!#sMcvGMQ9Z&%63MKt{OIa2tsW zRsG#&z3{YcMR5SnJI;G_gLbslV1JV;jTLR0oY*F5UOd87YOxtFQADi};vm&*II=Hs zzy1E_Ry}roc=H_-D_|fyX7~K^KVTfZpbdb*~Y{d9#Jl-#hV0KIW zpx~h>)Av-v?d>e^^=R({S~hSj2LO)X$tvjQFm#*&3c1=7J{eOoF23hFrhgD-v)Mdw z^{AA2i^mS=LmP;=3*ySbs}`h=hnDUDwsR zR!jWojmLIqx3^lG&1SbtgYeAm=Kbep^K*L0XO%Au8$8S8L4w48RYb9w$(PiDbSAA0T387>cp zuTpBGj!;R7(2Gpb`9DWBPf4ZM8>I~pZm~8(xQBEc@=qIHC#2oQ)6#_81 z6&o3RURT$3M1LhdwlETDXu3ce=?yf)p-Mc%8x96T{KE$r>cH)(D6}t#VuGSj|DT9x z!TyFcxRT=qPS4S3uvkopu!i|vBoTpFx1!2Ksv!*`gj>v|U#iINmK=INJ$7REPoDK8EmMWMvzKxV6JR(JI(V$wmuUp0WCm+Pz6WTVLEv6yayT|=Q$MT&kt?mzpe0U~1jXDl zHV6U4Rm4I}sOx#inUKM|L%Gq>Y7kc2^lfV6^c}!Kt9fhpcRUMFO&+ zF(HU>g{W1kcqiva2>kt~Qffe;qn?O|&6Ew*xf?|D;qD^mv*jrTBlmZWIs^m=RT8q9 zGAcL=B>`bJgQ4BMJ46)}gXO!khVBOlNzkHDQ-2SLWR|H(ZD&kJzV?EZuQjUtd4p-u~w+vAzBL`dWVGi*@xM XB2($W_Z5~Z00000NkvXXu0mjfDcZ#i diff --git a/TMessagesProj/src/main/assets/emoji/0_1144.png b/TMessagesProj/src/main/assets/emoji/0_1144.png index 81d394b44cea09e0681cf85f2910af208c4cfbd4..ee0e7a615ab429c23b11f860e1dd3a170d1a474e 100644 GIT binary patch delta 2066 zcmV+t2<`Wa5}y!|B!8PwOjJcja7+;UPmhls}UO7E! zYhEs8IxHqxE?`zeIW!y)XEAMj!Ig%?yM)J_dA7Ahcv3tg6j_dqPk(@y)y-$1oo%&- zNOX2-O+#p{f`9t??Q^ZJZCOpG=iFGFZLRO)U`jx5siu?EtdPpcNg_=@OG`a!NuS@< zU#ECtnU+tCVRO8WQ7Bh;Usa0FqfsY3Z$oxgNNT^Vm${*YcaV{hY)^Ane1Cj}h?}W- zTZ`1qzonCNN=sz#&m!jI)YIbPNF^&cU_zAOtirpmF@IG%a$8VZW@KiDdwonneL!Hm zel@<*-r}1Td}CSa-*LLh#>9PHNdN!O{xs^5mJR;wF4O%Vw2s3?U(LyDWwNZr3uOpI1uu!gLDYER0&9ZeHSNWOlBVQ6qXL(>^iv{Rt?1xea@rRT&9#WX9j{}=fE0!<3Sq|!5j zi@bo=0^)2!(snyV(U65grbN4-rJG9v5PxhY%2Fgn!=frfJuOOJfre!z9SsRZz+EQ_ zU2jJ830g1^tk8@C85Ao3{UA)@WqH(oGYfzs=-w{H^k#4$D0qPc;Dk_)hGJ5=!Z^sY zUO7;TgiKi8ZMFIcLg?i2*+0noz=0C=W}@)4327vO7&LaE&>4GKNR*}sKBSQaQGb@u z%4v2oiw};vAW2Yhez4TvQ9$ubVqtQ$>8nrKboPP}_26PI?cp`}_>ZDq|J#$Z#$M^nh_3H(_{r zjIl2iK@uld#K~>-_U`Wc1;zoWg&4ze7&rRT7SVNoMQ4;aA-)_P-QEF5Uw=95;yhkC zK0DoKFyN)FK7f582w8IFColi~{{8ai8+Nw1TZ}J0E+)^AWc2w&^%$eoYH8U)A3i0P zmj3zY2N){xMd0x|Khy%?Z>yPWPiM}l}zr+JRURHnEJUfFq=DT>uvRK)Q z$7M+}nLK5lnZz)G1#K*XzYhkPi{tZDt+r5zZxz>zpg_dq@v|5<(DrnVIz2YqG7s$8 zPS5i*Gc#*&C5pw$IF$Gt5MrF!U2nCj$oHU}2_dK#JMfb+{@O5WvmmCx*ccZPpXcp(~6G*Bf~-tjUI% zxy0t?EL^jw9&V6=8E!oW7&wdx!ziWHOv5mPSlUc)0<-cfolYObVzHKa8jykUcs#*y zIGYE99OfFZlwD0jDSr~Bffe{pth;3ss0B|D1h#{PwV8aQJfF`mB?_yn=`>vMUR`|% z$J!}Ie;I7K#9Dr-S-+G>qza{n2dG_z_rr(npa*EF7{g*s!$AQGQMFv3sx55f`aXPs zYG4IE4+1R}<3A1ITrH7GAX2D)p|FuH1^QNG!ZFU}v9(hSK!1+1p|nw3s6lnJej}R$ z!vT!RU>JG=f+O5gp;M1H41sK+P*?ztk2jzm1Yo#!IbFZN;ESMW>fl@A;%OY|s5tj9Nh53jrh#WtG$ZV*K zb{GPIQmK?fKz{-OD~s5(!G`rTfyiwz?nqZ#hWi2lR3lb+1pJr*;h+qP3pMfFZ|l&z zzP>v+iRLcy$HJgS^=8=(+R}IF;M}`&sM=+Yq w)6>)D{vo64r&?_=7>sIFC;u=2MPL69X;I&Xb^}bg01E&B07*qoM6N<$f(47g8UO$Q delta 2303 zcmVF6u`gJQ zGg*#9SA-^6l_OV_Vm~ZrMKDZ(yh2T1f>=9LkkX)ROeR*3q;yqRmD#_FW;IiJbWb@> zFdj;Y&@^P8x`kq9TU$MU$%$J&x`$&{HzY-c%UPM-hgds8b$_u;E*-juV<1zIw}N3K zRg)%MoFP}2A5o3Qlx)6?W_nFA!jNf-TRp0DSh9Otop4Y!8w^x17g#wcDPg07R5Kn= ziZyh+LnabBeaR$Aco+!|L@gUrsGa$un2 zTAAD|W~*g89e+PNLA;%P`}+8(nvacpaXxOa=-}1v>Ep|>c%_DGz_qPdG*CPM001g< zQchC=Ga?E6GiM%93@6 z{V+4T2UO6S{~U@amIjkk7i;kN14=dy1Il=mL`KM6j-+2Cx3Pq*VI^`^cjY@(>l1=+}yl4J811> z#r@-}WuS~t#rK3iuCI|;Tw^Yqt+UM$=PxrFZJxD0!~5V<=;_0cucBeYUg>FZ_nF@Z0G)HQw%uc(f+O8^Q>eVc25JvIH7yV|)qCusVKi zWh(*tm*ab78isgl%VJ+k-~m(5Q-kg8?k~qO6}tE8Mmr3857v4ekR`GaGlQo2c9wnI z&2g+xg@+&r!UthZVFV_BzcP-*^&Q)mroG{CIK8o1qTw)zI8&B+D1W0>W5)Or4pSF8Db~hRP*qLRrLx!#Lr*qvO)rQT zVVF43;SdZj>R;P#3Iy(58vh0Bhz;;`^V$FlhgHo_TUK z^!6%+4iLIT5p1M@iy?><#FiWdQ1ATv&k>nD&naQgpI;pB$M-qGP4!R8I=!4JwPL2c zjRbp1`AXJxA`T{hGoQ`oxT!a2;BPYncFM0?{7zK@p@V^qfgLHx}l9vETh;91V+FlWG z@~fHb7uE^E9rYcDvu~17IEUFxRnyZ2ST$yUHD5_l;k12>I97(|^HWQ(9M`o`klp%6 zv65G$^m-fxrU`_e%u`cqnVqohp<(dDWu^ulCjX_8scBL|(0}n$LR{+vk9~=ifrcL- z5bz)nT12J{LQ3Ev$goZ%G#CM8#Les%!9@c$Q|5WkHi(RZb(k#{G$kRh=2C{G3_{`} zv0ZG07Bld0;3U~B8)6Ng3+(E2OIasr89ESZToajr!Q~jYod{4xdYCgw_H|5B1q2S* z7s2=BG}uL>Sbu{)*9b)_r$jLiz>>h{stVh^a~L^p3h=p)*~&Hu_=IG4W9KSOO-jn3 z^NcmEDrOHN!Qos8$6L8ZrCgAJPl?qq*9WR6vw$+RTB#(|qq<;O_#;;;z@p?ypBxH0 z%r^tommd)KDwI5U#6K;j?I|dagH8wE0V5^YFw>ND41drP_HmDfG?+|XjPLS~lK}`Z zgc7U>z5EMNEKma*q@Pmw=T2ubnR*1`K29bb35&xPkw}NRo~lHLu_U_PrSUlB`6&vD z3NRQckq$FWC9l&c3M0@^I)e$#KtVSlmVFe82)rFA*2f6^n}c3Im<$FAv@iyCMd-4?d9vciE*FVHMP|! Z{s)ZQwRf-uNX-BM002ovPDHLkV1io|EH3~6 diff --git a/TMessagesProj/src/main/assets/emoji/0_1145.png b/TMessagesProj/src/main/assets/emoji/0_1145.png index 2706bb6f3f291cda89b5fc7c7273b775b03ab12c..71b190b3b6ac64fb90a247ea99a46dca789dd811 100644 GIT binary patch delta 1904 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 YpA%C%$!6jBDF6Tf07*qoM6N<$f@vPx# delta 1942 zcmV;H2Wj}D6Qd81BYyzKP)t-sM{rCjR*x)Mk2fnSMqY*?RFEWAkRufiUUQi$Cn+;q zktbS}Ogl49iq1MKBp?_RN`1OBDl9N1Aud2ySC!dEht5enI5jORAQTNMO?WqGqFkHb zAykn?F)B+pFd|o%Qav;$U7cA(IXWpL7ZMO2QH>xS94;OfB7a41GHtRobi6)+%TSQk zEoQ48Pl+jEq&a%UUP(R<2?$6*L7R(!uAh@WI5|d#&~RT>HZd_BHBZ92wfXt@gmi4J ze<2AK*20NgaKn`V0010xQchCd^iZ{#UY^b5q_#YNYzI)8Wj>_3!=^ zl(Yu`00wYLM1Mh4cwU{>hho}F5Cu>PBqRi;+PGv_z0te7lf3``sdr~qiy-9Hi=6;Q zhnd-x!1%jZ&1SFL?ODeEOmopaMJC${{yhPlQ@=A7DXa`=})@N{|v-&9EQH{ zCyoOoK`s9Y@lZiX@ss;rvpI4KDg7{xyZ>@1uG=Wfaes&r_%azX+3TYcGA2FK`$u4K zdwaK-vLTaxPfzxNjc`9M9|!+1*_&^i#bY^6iif)SW`Sn>aaleszTMs4{EaerSuB)M zmTwQ|oeyD*OM$;qZvWD-?iSkElqGjj8~yh(Vt|dm8sy!}3kU>;FkR!)C?BEg-29%n zeVHqQB!9fd!v4IcjJm_7<(f|m9T?VcM>&T;nIoG)Z#3EeJY_!_4IB77cp?_R9min) zq6`9Nt$TfZt=!uiAagF1Te%*@oNok7Z36Z`_j~^30GT{(h@g?fu&&!c0I(3?c%5hb z(Cry_V4%ioAGy=o%uMO_FG%!akgQC z5%;PM?qV}rihY{Cf%sL(k+zs^Hrlwo*p_EPR6eJ>UCzL@Fr7Y&CF(^Ptbn1^2$iv{%eXlep_YP#WhCBlU|u+Bg`g4+ z2!GIN+Rn~exvR>sHaMP2AR#E*X`Uy(Oi1CRD%Jgb94*;6FXLvz6(}JXD*}q6r+oUPnO| znC^3)77!8|U$U)$oEAsIC_pq@l|kpr44qgVlz$@J_D+sud>C`lghJUSq zfC<+aDk9waudhB;KuiegRT7c!Muug>pgPu=V8;bf0U}#vEyEq{cu9}P*W&Ocxe929 zL-BQ#im)s@TL~D1L@go$1}dVv-K8>2KEC3^uK0Kjw@CPUd_C@*<3~b-?7AQ_7=#2* z76`$~vYL?b=N4;F{P96$#PZ`nkAJ>@ZY5^nkCtqaOz>>Ml)s zUIu~#1hep3M1Up69#~01TT5;ahvNaGpatb|9=^5-2&X74Q>fRI6JSNG4u1>milAZK z^Y?(z=QC}~!J^^;KZ#Sf?{>sWA0qykOd}Er{@I_G$A|?UiFyQIx>yn1Bj{&-{JnHBIxcz7ky-P zAGQSobyWrkda74-f`krVv44C`6h)J__evi?3xc#XN(9Pq`??Hl%%muivpybNqZ4F$ zdOSRedFn*K;FC3x>bmDA1p-j_!RMGB9=+aUVgTY)SP*p#3!QKolCIf1B&mw%H&Fx; zSv?Ahd)^6*2A81>hmcgVz(sfvbQQV}#1t20tOt4;A?lYhjJ5FKT7R}CNZ?(;@v=*z z<@Ow9D1`tBXv1wmxaxyDp=X&;SEG)>1|{?>K{^mR>e8YF?nB4SI3NTF1RD&7Btb=@ z3kU*2P0)JiSiB|`K?Y8qWHpiKz{-gWV9N?0%sg2bsicv_z2NNJTxb%h@fm2DyXJiVlPIT zxEdyC;>1GCa#9b8K5wVCbYpRMFauiDlUe3Jy1>XSARED4W(QK>m>kEmrPs^ z^Ln5{5io$@m}PbRjGthFg}}QaEYQ$3K?V>G05)}DOxUh*mDYI`Fy=tOAo!nC6DY#e zz*Q&kX>uSgGd~g4i@e_u1A)}zoFkjl4Pk?4As}Equ46r}R^_TxI~gOq%5uqFl*npz cc9Q-HLr~a4Q4jydQvd(}07*qoM6N<$g0Yot?*IS* diff --git a/TMessagesProj/src/main/assets/emoji/0_1147.png b/TMessagesProj/src/main/assets/emoji/0_1147.png index 97e86b62a8aa25dced412d648f59ab65309d2949..879475f57770d1300a2e16a63e92c9827eceb188 100644 GIT binary patch delta 2210 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 delta 2244 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 delta 2096 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 USbqHs01E&B07*qoM6N<$f;Zta_5c6? diff --git a/TMessagesProj/src/main/assets/emoji/0_115.png b/TMessagesProj/src/main/assets/emoji/0_115.png index 6a7ef2c2f1f1b04d3d6aadab1b861a085fe23ed7..6606291ab15f91dbb4889e2f8bb335805853a519 100644 GIT binary patch delta 1097 zcmV-P1h)IN2i^#fB!4YXOjJcja7^K?iOq~=&W~u%k7?7EanqD-;H`+yk7)MOvGmWa z@yVy{!Jg;0lH8+yY~RX500009bW%=J0R1YWfm{8|-I}P2Bme*d*GWV{RCwC$mFte| zC=7&$07<}x_kY}Vm1zj4Gt&OvJ=Umu6c?YbX@36N|G|!QU4QBL%@dD*LAbQma=j_9 zTB^|V`)RYE)Wi^yU))-16^*9Lzi{%^^vae*DW&EYzrZ1onC`s-vBRMY5GA1_%ZV-| zM}$xeB-d9rfxuFh87_2ee6VBu z&jWBx5sm%ayXgoHWTe`IFG?+~;{h89QuC4I$N9aRehkqX9})dFl4M7Z@e*D+HEKdz z17X4Ax`&oHNTTef!tB7?@S>@V4 zW{*%&g?~^-%xKZ?XZ3hZu<92$sLe zgoy%yoSt-=PDE^|kn1-fb%o+YRCYLcEK~|AC4yH*g9|q0)JaM}?9V9jH^mWjV_n(u z38CH>To!@n1-stWyJ`rI0?T%y7%Em!(d$-ONb?B*CT4?)NJMZv=NV+=u@D^-+l!EJ z_J82HErc_e$li}P1XIAnJ&VBzgHh*Hh*+a^LI7c$(&X1M%@gS$nC*zwO$~hl3U`m! z*pwg<6@Rc0Yf*>*;jzO9@8d0s3EmN`#r+QiuI{Ki;}67nZiv-un%`+T?EAkFL~rcH zi<>qslY^QSXP2~?+6LX;XVLB#3GTUN8-GE2&RmRXn^XhpKpO2)?o%V8=K;6WH$l~Q zk9#$DV{Em2-gHKZVNHR6MdAi{nf~4DoZU7v=I`7@NQ*w$i-Z7@*cy+>3K7Rh%f8727W{zc5)OPyW P00000NkvXXu0mjf;!hHp delta 927 zcmV;Q17Q5#2(<^0B!4GROjJcja7>L{Mu}NMsB%}HX;8R@W4nrFvwdEhW=^YgSf6Q7 zc1$;jSVF2=s7U|-01b3fPE!CVc+Z;u|NmJ3{i5t|)ebHI00S^dL_t(|+U=GBcHfOCP})q70?Gkghw>%RWSzYs^txg3vD*?*L0LdN_3&QH$#UX^_{ zF3S56Odd~=L{wUz%`6^Y8AfkKzy$mP>R5A zqzaKji!j8+^2;QFcn?HMifGfBOVr|3Xc}!Y0zs;_y$axd72M_-(9+n5A*c@ow0KAj zgb5x*7=I|)Mzj|ZVtz-os3Hh{-2g>IJ0l3)5L3j>JM~ZvIfwUx2;Jg_fFUp;cF1LM z1UAVLLWCg3dn%;5Oq&l}0!I`g{OQ03;jk1ev$$eBbB^%$99+d@Rz%ELs9y|Gh%ilh zCj<+`AG2tIsWf+iO%Y*z1f&tNAvh~r5tmaC2!9!>To7?aAet;ihysR(8%gdMg~;5! z1rdaAj`XU5;8=QFdJzbQ?LzJ|QthoB4$%w|TyY-{148Ft&uqi!$UN?S9>aAHWFiU{ z&uk$AFp{7J}rwq+OoHO2iSKJs{;=<+(_Gk(37faxhEnyBtMuAHU1+YkwRc z0e^nWFO52#^n5($%ic84gm|r%wkHBELZ^pi2pA895-(;l48k9b5RsNHIdx$m!YWik zM7dn|#WYCkr>SReO%x-;0jf%fNa~7cjgQ=UxO#plw?$4a-Zt~;>f?{D@1L6|eM}9p zD1L>|N23P6oyTwSOd+n6nof;Wk6pZJ{}|&hk3Wx!La#gMTUP)8002ovPDHLkV1gpa Bo!S5Z diff --git a/TMessagesProj/src/main/assets/emoji/0_1150.png b/TMessagesProj/src/main/assets/emoji/0_1150.png index ff80199a4ecac9424aa608726c11fc71d9a4948f..cb8ea3a6bb7921cfc825512de17550c9bed4820e 100644 GIT binary patch delta 1947 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 delta 1757 zcmV<31|s>M4($z)B!AmbOjJcja7<1actsNj1z8kiP8mw3e_*zu zkJHS)00pK=L_t(|UZvNEauZ7s1yCfd!pb@F%*^JT zlyh_h{{M?!chAThkWH1jlnWQ7J>2dY8S$;0=2iXMKcwBLe`_qy|AlB~S8XJkUoFyZ zH`Tl5Ef80C&94#X=gsdK5-5GG#C_KMFRR~Xjk-cki1{>vI) zBpMn1{a4xfy;}b&pa61l2XF!J#JlpfIU>z0AZGds}4ZNFj&%Op~c{v_xyYfjn(C&>LQ?g&_lj2acm*9E4<_Bspy#5gzpMWKDUZS6Lyq z8Dn8642j4-PIBaATO)lm9FBBzY|g245Hi~agp*N?^Jk5Yshen!@&tmzIS4TzFpQRz z5PwUvtUqfgrU?Yb9FL!1V2d+5j?ACRobYbL(;d*gQ216qZv~Kx8B%zyvh@#$N*Jnw=@Ou3niys}?1Aj&- zEu*CqLA#hdhj1mPzwF2U%HH)4hWps>?LxNwWrGo-VHGcETM#c`m_TqlP4|1YS^=?_ zgwcQN!5=W=_0f(QN29dQ_6-n2*@B4v+Z)~k|JUoIFpS-6AJFvo>pqHYBtq-5QzR;b zMDBL~m`3XI?QQ!`?4!tE?)O^{Zhsjja0*1HN~Eqo*lyM3Znr(GbFkh0R|gh#&XMKM*dD1lWZl*t4QLUcsX2x3?P z-Xz8ui@mB~X+V^g0fg+KW5!@`GysX@IwLU!J}m-7o-Wi72oWP;gf>15As}U8m+GcqfiYLATPT7Q6N?Lrd6y^ITg%%4G{9c zqbSO6_15tw9Xb^<1Xe*tj{MBY;pjm*YADj6QDlwdfga{@qkC4ZaU8*gm=B%fMxlmW zXem+z0d{=x!AjpxMV@PQ8Gu3um}5S^5y$dB^^4MMlh}Fl00000NkvXXu0mjfbYmed diff --git a/TMessagesProj/src/main/assets/emoji/0_1152.png b/TMessagesProj/src/main/assets/emoji/0_1152.png index 63dff09ad1224883f6a779c0bf19411e3c04dbb3..e0259af890ec1bcae69c7cca9548d5fe98c5f6c2 100644 GIT binary patch delta 2081 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 KMNUMnLSTZ9EXq&- delta 2306 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 delta 2007 zcmV;|2PpX43*--wBYy!MP)t-sM{rDyjg6;gIZH7lwzjsThFX1neui>4jeB5>c1nzm zje>)NLoOpwJTk+HHLh_mJ}M!Ih={s%_M_WlhiHV7- zs;Z@>rJ!j)r>Cb&Ix>QTgRQNtY+F%$e0-mupLJtckC2d}qN0^nCZu#s-pjDau8;Zl z@UonMu&}VSbbm&%gFRX1C%8(tI*zOwu z001a-QchC<>HMeXHR}i?5u|%nJ6VQ`RjKLw4T8{H}PZaPU8rE*1`oH>b(}fhg#w>EcZ(8GoyhbUGd_r``eLv>bmEAz3P= zF3NF0q@r&`q|4FxrCxZa7YotT^xIrqMhl3zDHiq88*A~7T7Y$_7vG2|>iGSadg&rs zcq<}$T7S~ZWxb5me47f)4V8ZLvYM$}?)(r{%cYY44S_-g^jGR2or`^_*N4O5WH_uh zKE!JI*D3KGA_>6qO)+;;pL~CzN&VAF?lnm2LibfpB?~wD#mOfM*b%-@CiT0M{A-9P z1>ER*sf2{%-z}gppHI2{y>-FpQQgl)XFh%HO@9IaK-3$(^Zo5PkN!eL=Q1y{!vFvX z$f)gYPj#+DF^?!S*M<#IY)t-@A5963{fu*MJ_m@x%vHHQsoMtI82a*KsqR3>duke& z=bmJ%4pFRO@Qu1J48_Y=?<9Pd^T$L}=W~rX4Xhe(7$T2xG~A2q!J^_rwxYMn|-v-vmzm`VHma-$KnNiUu-RyMr6zZW4qn9+FTusvw%=7G-8N0>xsAF z&I7TB0mPBS0RlDVq#;;mZP8R!Rd!sFQhz**M?+35fXGVRtljE%+igyo)~RRPRRxeH z6VtVA5oEKXNaI0QfsxGsqT6b9+cR$3Y=C9aCbGaVuoyv5HQ6E#fNaC|ja>cN8R;`_ z+-`x|SkOCg?AlgG>2wqZMLCS1Sr!(U4Rw)>0ESZa=7Loo@=K<+3Y3b9OwXn&gN z8fYU}i=!##F&KagKtLK6LtsB$*8(FzK@r!5JS^Ep8+KqvvQw@NgaLI?K@*Hgn2xS@ zK#GUKTfrfWWr%>N1vg~;0s$rjrqf{<1p;@%j9{rI*!Y?Y^d`*%)E!UzL($d*MG&5u zAB)9~p*;Qg@${rJf@RqD=X5v%T7R?4P5X7j)dWFVKCM{e`Suq>**tATakWte%@%{D zNS=)WvHgV*5%IVYH|&GC^nEa^XL}<)ko87YU6BNaJ$*KAdoJ4CbX0duO#j2ez3tIPEU2lH;Pi^uhXK5tZwkPoRa1l?4c$Om*GD68dawOrD2F0eCJkNCWR z!6Vj5I*8zQh(yeEEET4rb9;NMFi2P+gIV0(E@19dnOMP5kN=B+zDRuh0>dCMbTrU| z4xs?@o*6`tS`g8cpcp=4lz)wxIOrG;1h@bJZAzDd^9rR1Lr@znMD(+H+k|3Ze`A=Y zb{33=IK@K{JLIhz?@RQ^0mMvdzR!!Ur6GbcG=~t!@?1cLRM|Ab5Q(Y8jRDc^&bVgc zqbNE%8;lGD!A}G85RJniA_WMv;T?SaifvFEDC%8cJc4h+h=n1VXn$kYZUX|&oIArt z8$JUm^bACTX4!^#k_;e{@0-W~2z<~6Z@UB-C}NtX1DE9!TtoaE3qfT1%_-&rlrbE@ z%}VVvY^8&V{-pW)l!Jcb|i?GG2ybeh>y(gal`5s6f* p)$8l)ze05V*L5`#iJW;h{sC%`HqP|HgAM=y002ovPDHLkV1im(x9$J{ diff --git a/TMessagesProj/src/main/assets/emoji/0_1158.png b/TMessagesProj/src/main/assets/emoji/0_1158.png index c36aeab74d0855b9bbb3dc6b506378886524cf0f..c49a38f42d1725b4953a497691950b87266c7357 100644 GIT binary patch delta 2236 zcmV;t2t)Um4aX6XBYy!$P)t-sM{rD;nU|TFmg%%H`q*`XiIh-lke;Kgp`VZHvn`gE zl+v6nkdTh2rlKfNgDz8q>$NcxO^242lcAxWo}Qbapq$^SFcwaU{p6F`oE!{3d_-S} z>9HiCp`GirDEGrL?Y1r)Icz^(jSw$m3@c^--+04@8U4~t|9{t7NKIBze52;99{=c? zgo=RLoE7G&7uA*({?I}D%Q)bo7V)+n`NAaiydUha8vMyF&5jnleiaExgac5J#)lU3 zzAk}Q8t=S21wVZS0|WorU#oG-{? z?oa33nJYhj_pHK8fq0OiSIlBCus9!v>$eE1;)&(u*ccI9Z!ITwg5kFzVy%2W-wKX_ zfo1w3_J2x5I51wgl*pf*wE|R={^0`vZrYlh)ET34gFLT}yFr=@$lqeqAj5C`SxDz0{7K zuzx;%e|`xQZ?)o!FK_E&!f(d(ekEp~()n26g>4VUz}igt{+V!Sjw%#l{Gf{v>D3Bt zM7MX@6liaIKRO5Q-zH{mKRGHj4lk(=uTQJ&ZZz~JLMW<@8kc|Tx@7OZXWn4pYvd8& zkbkOCWuvcUFdNqB`cd^YsL^OtC1AXcppC8%JzYcjxc;(`8_YKap#e+JHP3TZ zuIvgRsw9hwqKFdzg_)6KPZ21>wt)bEtSf*3Llh}O{T7~)gIBOHP()i&T|lREQO;g; zvcPa{h_X7X8SgnjAW@Vgo-1cN7xjAGwlC_GF^(cj)ftE{oFXU$%aY1d0w4}csDE0g zK6q7DD1v(h0t?y%Q3qWRp#zLE=OOG_K~zN$L=Aa4DC3aT*$&u%B#HquY?(F`a)@%|`%ACSA8Ypt#>B!{ zvxuGTPzGdB)q##U*jEwDvK;BI{eO6tu(Wm`!5CQx3=>_$JRm58Q#n@GY>t-&Sr)bX z?%KjLgz%<$Cjo(AIE0d**DP$8-6Se>NY@3p2}w}o-rSttQf9^IMnr)S0T4*nYyEx= z4Dsbo$JT39I>Jc7NVqqR)v1V&X~T#pf`|nyD!OiImaY>G{-S|EKWchS!+!`Ng6@s< zhlQyz(ni`+2*%U}OeCFg=%4^7!qZQ5&Y;m6xlgClD^uomH4S>e8o`M6!cMU%pwLO@ zZI$C;`fXXnSg|xc2Z$*)!fWYtu{hL-g%BheSpA0wXTXCI5FhD3+}=e75EAL+SFTtD z8&gdbbA<;4*^x4cIPK+s+kZ8d=T*Q&dcCuU-UxP_Xxd%DMSOUAz?e-S0HSgSS&=X} zy>0*c)xIm)ysGl4NW1;3cRRX30#pKQwfnrET_Cay9L0tgFV zCAK0dBHU5Y~lY6QW&T3!l|a9$`HT`JQ^|L~{WY~K7Ht7`zo zWwiS`fjC-Cr_-s`ZZkl*IzBIUe|u^+%@zM-Hg5poLn@R(A%DGFr$*IxZhHWwCMsaS zBi!6Ho0BB-o6QO1rfH^gg)3N_c`Tq(!g&swXu@IuP{i8&_-Qd0+Kz_i_Vzb6Hs%=SEk8<_cVQ1oFGBEny8aK#GE9k*o@wd;0000< KMNUMnLSTZq@-u4y delta 1672 zcmV;326y?#5tj{+BYyzNP)t-sM{rDxdR>!*XpD-6Z&fusGAe+8fQWQPiFH%9wzelC zAtD?bkdTmdSTS>LXdxULDv4GUyVK8}u#F@GZ*B_bj%DJYedlzn}D zKsq@n92H$tQig?vNAS1%F{lL_t(|UZvKFR^mt)1z<>m$*{?$qSlgqUs)HmyJz12q2~XKgy0F_ zIrODljfeWYRYe6_-=it*)?Y*&v|9sfs{REb!EnV@R7twGgQ{6G4T`p?RS<<`JR;&Te=RRU;wWop@SW4@@C}KPiQ)_T1F@F$$e`+Z+t8*`5OciT3b7!zG zcM@&WEpxt_TBkdC#7w$B!=3Mh)Ye*Rcl25m+wC^nZj0h|H0j*lD#r(uX_v8UagXtX=;0Jz4j6T)C3~SQRfzMs-Y-z*X%8`Z^I!tpJd#7&A^eXTG0c z>CkaVuuQ7p*gBV|qAANTgeSm%Q5y&_;Hn-QR)1NBy$gc$Y{$c_fSypefX)FSL?B^3 zGzco>(rUcu`eL)zBQN)2>>UQg_t8KE16F_u1rs!9qV;VXjLq-OdSP#&bN~cpsUxOy z3V5aS*dW>w5{va>q1zDQV|#=Mh!xaY#jiI9eG>PnGkB4xW|5q%R-Q; z8-F#o^~FX)l<>SF2mxT+#2AKf04k*`gxW^|f<&HR1;Q8aGAYn)ODsUJaS$_+c(mkROBZR~H8N<0d z&&-;byY8PAHAIcEdV}!ttpkLa?G8Jd9)^`+91c6?e?`>fgpkHksNaafNjWt>B7dDY zzjm1+1k*e4b?8|8oYR!}-3HOu7bhYvNXogspF5CWANH|ER$cEc{xgxJKBu4iFMkyN z-G7J{X1qV3@MphYF`uwb^PK8>O)Qaccl*PyfB*Z~M}ja`ANxPzI;PzB$J#YwEr{3D zXVf&j-PhM{Hxzl(2Ugz^S6ffH&~uPir1qkOFylz;jDq(MktRL*3fdvUvmL^U3X`h^bVfEa5{B9H20 z7Rwz1GdUTQ!bp1bz=frN19Fi-LlF5>2k$q6K!m5h?=zzk@P>Mcc<`e7uJxc0r>ud5 zxKWs=d2r@9k4-{D0u4drL*fuvjiUh%{OP=eGinm*gNHTr1rkvnCr-5*IDZx${3ZnM zI}YhxAf9qh^uS<^kU$M;V(`9;|9E*HhKA#j+BBYWGynm{j=<=S(V(D|Z$~LT3h7&K zeDQ;yoC^a|8gl0mU*;m5Gx3H%Q5bbq6q=FZ7!6d)B691I_>6NDFoN>a$9i~UG2#*t zJ#^dlWEBiRFy&W2g+;g;Ie!*LUKyas>I4o8W2i6$nnJTiRRj&#-Dj!OOJOe{I6fVB zTQ}1NphD1CU}ULB2uU&Ub=3MHqDDO#UEB)wRR|rh34`-FXlv>%LVIZRSi>ilIANSZ zSW33T;qXb8v>&EY8^;^S?@xPGgh3hvNgN&1e`%|?ry>lTN=bZvZhs;`Z8$!liVs5e zv#j0P6-+f1Akf%-BD4k(t|6O+{`_(oksiL)u*(`%&VJl1?7nnsIqDi~QKLpq&|0_q z?HfkD8kJEab&aThc`kBolp9+U=gw002ovPDHLkU;%{ diff --git a/TMessagesProj/src/main/assets/emoji/0_1159.png b/TMessagesProj/src/main/assets/emoji/0_1159.png index b855fd0919b53190f3392fe1ec45191239ad6891..3659b0496aba361aba2370bd37ab1fca653f2003 100644 GIT binary patch delta 2130 zcmV-Y2(9;*58n`wB!50oOjJcja7?A8pqG}EL{DQ}Uv8S2m+Zr!s-~Wejgx_jl}KEC zo}QW)P>DrQXrQ2+M?gRhKz}n@i6u>g>(8<3y_xUDqC7P%g2t zJUlH`g66c2Ksq|^!=PA9O_`aN+@yXV9314YiKL^R3Nma8EPrDNIdlO576Jhy1YMmT zYNQNhqzENh2NF338cNWaa@?kXy^d}D_vJey53qh)A{7sfW=3;QJQgoln{QTEIv(H0 zsQ2p5j9w70g%#AdQZ+CyMn67DLPAbOL@OvMQb|cWH8dk2A3!=eT2N3{O-x}{RvQ@_ zuCA)+Y7IaQ!e$re0L~qPwW$irXeOcaxEpc95Wy{i)&OISuoo+Y zWdQWJlRJx0c4mqM`-T-n_HCz1?Y`E0`OiuzmNTY7YpGv{H|HIOFMnIY z6>RtWr~@)2ZAo7W>5#%FW~BW2t}$Q|#2^2Dcm7o;a))FVD|Ee;&kN zh}f@SiHNo2QZUfV6R1-0oJm%kSbx4;Y`NV2iHM&*8|B}|>xMOPB#Z-ik4keZU8pqy zJ*o64OA^f*&8u(G_Ik8*m)pH*s}8Ff%$S*MzW*1vXEL$3=yKd21rwh6`OFhWP&v;? zw#3WND~d3FeVyg;4BoHH=hgaoHjDEdwufIH|77fYmSva9F;Rp2<}+g7zJG8eW`PmP z%f#?PI2QL-k88ecm{|sG9M2L2z2S0i&7ckHj36v74Y(SIjAFWe@c2qM!MHp=q9B;M zvEr`FDdPAg_~q{)#FB8M``Id*af+5p=1p{ATvU!GA&JQgW1Lg$uZDkp3&Iq`F5-B0 z|LIE=8{g)sJZkZp8h!??;;@a%g=nHAx|=BlL`)K6AOOL|W95ubI~_1&8$`D8)_(+%O$eg18G4*k zN)Zxk(-b6x5ao%UD)Y+Y?twPZAOt00CJ9<5B22 z5HFmL0|0;+kgZh;y`E)VDf?+!R%!ICB-8CKbi9#S3`G_j33U1f3=zIi0D?HLNTPC{ zSb&Hm#54?;h$PCu{PwYRcoHPB3ILK+%Py|qW)Tqd%<63$kAFV^`{mG^4cpj4Nh0f$ zBr6G}2F;0(ObFI)6o%tycu0J`ACJa6(zC!IM3j^4V*g0qHOveGfT1VJ&Z8J1?o1!P z7KWU{=cywekTYsn32de)H_fKT3jcqqwcl<&w6Cvo%uuYU*Jme+*1kdc^_d0$ZcE?%-aLJGTKSLv?TUEUTlKoC zVO7=Y_4>(4t5w(3dMiFtRkfukQ1U;cw3L%yOIUoU!}ZVe56CTWx}(JZ;{X5v07*qo IM6N<$f@pI6{r~^~ delta 1929 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 Y07HaRAS`&K+5i9m07*qoM6N<$g2`U0LI3~& delta 840 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 Z&3`FBfD(CMuR8z$002ovPDHLkV1fkR4~YN( delta 1906 zcmV-&2aWjf5P=VnB!3`KOjJcja7-&wi7;1?s)T7jQgkg({-FE9Jy!qSgpL^CP)zLcADSw&Qvi5X{2nn<4gM{+E~Uqess8TV{947V(s=8N@cioa?wDi9yz1oJ{`khU z-c*r5DcJx31>;FXK~#8NrPpUy+ej1!U^grYj7>FQV1H=|B-x!&@5Q}WdQblUzu0>v z+3U3>b`N>&7CV!SVqr1ODWXUd*Z|x?y>}NYL-0?97 z1am>S&k?yC_mu#V^wzj|R!*1lsMvLw}L^5^FG*GM0eQR*RR@A#jhcFwNkD z7Hgb$1tf5$M6yA+$IPB?Hk%rx39m14TT|%DzCi@JYmF8E!TD%@R8`fqRVLT*vd|)GakExUatd; zy1Fc6PHMIC^)uwUTzdi{Ey%JgNxoxwVSg-$>BJBz5eZCL6oJr888(%q0|JZy0f+|)KY;;+ZCm?G=lhRELJtWr zh=Bhn3P`|q+qRdDBFZ!3hi9{<5)hI+BMi%CFPUXRoZXRnC0RJMO@A0j5X;gH z-O_=;Vc;kZ&-WA2#C3SUlYfcqp`}l25UUNb4d?&_uEQ%Zi6~!o zw$17U0Tc|2g$@x!J*WW$3?r2&u+tj23ve$8PpMDfI=Cp}pdQvh0%~xFSVI=br1$>d zXY`WRaT12fMy(@}IjBPoFv{gJ45N|^YJg$%TxT27bKMsKw?p^r?0+(V*Q^m35Ug>q z;@1E}7Dl~+>$-!XPGlH_Zs9PaQf#0Bi@}Jnl*~SBfq}s%@jr}i;v^!IY=njw8mCNQ zY8ZZ|0_!g$a-J11AhRM#=A89R9gtZJ5P}Vj83q`Qe;Hh01c(6u%)tgBF3AccTum@n zF_|gYo@L^%Q3(Ee_J1yM74bD@25t=+we{5gIm?2Au`G`*aEXtSLSj|~3Ait(fBk90 z=>~_j?e>qv$6<;Q#`DS5xXrfP8<@eDQtIPBDKZBO1`HfZ{Jw8^%AX~+Fr8pxRVGR%<&mzniL~BHY+kA4m60?-``5Jh0 z(U|5r2$G2NIEiUs+qJ=y4n@)QC6AwUcNgxljX*xEkWt%11_H&WLFN sGd^7c7)WM)!H6JmviLRK*a}AaH<{O4;hfcBTL1t607*qoM6N<$f=~#8_W%F@ diff --git a/TMessagesProj/src/main/assets/emoji/0_1161.png b/TMessagesProj/src/main/assets/emoji/0_1161.png index 7191452a9dc6d70d201d6c419749dad5969fb903..0623051f44e4fcd62e0f6ffb2df5c727fa767aaf 100644 GIT binary patch delta 2083 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1162.png b/TMessagesProj/src/main/assets/emoji/0_1162.png index e6505776c7ad4c18ad96095cb0f476d6ae3b1afd..9a494611527ffb61f70f18bcedb4d8e3ba9d79d3 100644 GIT binary patch delta 1877 zcmV-b2den|591DyBYyz%P)t-sM{rDAR9l&tm6({7cx-80S7E27qM@0TbbpVCfrAxL zi6~Kpo12%GmXi-IV{lD5OFA^8qo55yesV%5h*vpIK|LNlZHQAcNIpWKpqzP4HF-uW zi&Zm+Q8AENH3>L!3o&W}0vQ1T0tqT%0t6-q1`Hi(qzPlAV1GI!1Y4U2B31?$LrpIp z5;9uu;Ks9+bfI-t9V)+0-(z}+Qatz3)J5M|_KQJj&K{sJdLtRNfSw%Z* zS4~MbFJ)3ka9vY0CL(oFJBCp(c4S!xNrf~`XpUGlY(Xf0ODqdhk0%=!m0vovw6O+1 ze0WAGVAhq#0Dk}gA9PYqQvhV1b|ORk2{9Dbi@sIeeBSQv+o8P4xR>3;>)`bF3Ff7( z000I6NklyDc+5QR5D3}iteRa1pN$&BwN_w1#8|EKBL5Xe?ZV9yU^3(v=y zGv?)?@+^+x)UVPqipwmg^>l@*V#Qd|A|l4vs*dvSA%BWbuc+OX%x{W`h&*l&W;GF5 z-14%O-;^C-q@$!*btmJSs@(IUYh_eq&k~@s@ldw9o-JHkZ3W$

  • 5CDjjXP*w4HYq?)#!OswL zM4q0-QGe(C{p|fEHy4H#<@2$YHOrp8W~+Ggie*LoWb6_3Fs{LWp3J?H;XdYN@-kh? zY_qO_ldAP*IVbnu)SSwtcKaZwC9jsrw*bioLGN$n1h3}bAj~SX`~Rh-T23b*xUUwR z({7c8;)!Q1eaqjBzPOxAp!#$a6S&Hf{Q92 ziBlO;(-h|WJpzu88TsPP?K;Bgv_(opS?8y5 z+HD2WPAcHQ{}SVVr0MJ7u-yT|g%ApxcM>8{TV_W4nMMcCjRwZKFol$;5La>@hW*QX!oqo-&P)5_8z~!zD>iQLs>-q=BC)61hWMt$8A9Tlpi(FL z?M=|$vMkuRYQnOodr}Gry;#J*{(rMZa!n}Zm+g14U1+V8Iz%=j9*qBV0t6tU11Ta} zY`z!of2|k0x`=Woi?2tq+mu8~tfteN(Y>?}YKCS4R4$p&FjV2N8pcN(<^#%Tt8lytR0!QLh{{aq z4+IZB!p6tldCIXxb5?3aA%7wqU_42hMM6r|lp#Q1g^`7DR$AShcX=N8FOBjva)DqY zl4ndSA&4D_FP`Hvz{+1*`9a=2PiEi)(JDwor>&+~OHoU%3wU!~*9p@+I3xVvRLLzP z{1dpcr~GM?THZ-@K3?czn%BWT2>zYXPQ@JxX@quQ@*;F~auMw-pEx9ORe?gtO33^DP{ixb4T5Q;cnRen&} zO?;YG4=2RUy;ZTeh&)(H&10Zs?6oeqH}x09t5J|!b{lUE&x6rHF7oXu3bkaCK|GL3 z!V9;wkb;tCnIu9Gjel??v55JuenYwc91btgevWgx`a3k$I2& z2#2*2Sre?4)}zrA4D|aNH0%{XfIu?qzH9vO^V=EDW-~BmQZs^7mOVW_k9%fsFnU&$ zWu$<}lH-g4!#_I4wTB_|=H|xi{@(9DjmKp|&wmbjWBgMcJx)C)<#;g4$|RxwZ$pIf zbJG9n)-;UH;JMR#G;U$mG>uWuFvo*VuV;SxY3?;spMJSLLovhV&m#W?zwGXLs4@c; P00000NkvXXu0mjf%5QMk delta 2031 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 KMNUMnLSTY!#a;mb diff --git a/TMessagesProj/src/main/assets/emoji/0_1164.png b/TMessagesProj/src/main/assets/emoji/0_1164.png index 3de6583d0313e410c0f20463e58c764aabc707bc..bde137fb516abb39e3b40dc96f3a8bce5dec50b7 100644 GIT binary patch delta 2184 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 FV1m(jm)QUS delta 2259 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 delta 2096 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1169.png b/TMessagesProj/src/main/assets/emoji/0_1169.png index c3004c0f3973de780c214a8de56197488b1f6156..5a53d6ef179cc3614d8e9ba47e53d2768527f8e6 100644 GIT binary patch delta 1599 zcmV-F2Eh5e4bTjbB!9P1OjJcja7IJ^lR2TJMz4!Co}WUih%uL| zPPMO8xe^c$8W;PoEIBtfWMpJj zK{jGrSafi1WllbpiF`B?KT9D6!MwGtqMP>j_1f3co^>Zk6k2O*YtFfjQ59vqU980b z000qmQchC<=Ah_PHiI4h{CU306t9gp-N%Sdw-2uS$oy2`@*^*<#^;s}Z3@Nc)mLkY zD@q5Vt~Vn@A2kEYyi&7@$xSRXZmw?X~qeJljWS5xT0RqO&jq0)(4@!Bi{(c*>vdLrN)l z5T(Y^4YDE#9N~yT*O&OoC@cVUs7*NpVO4l60e>Oo*-mna34le`X<_{!KxPncr4UC-z9+wYsNF*Ntv zcz;$P@1s#fIN3%I3BiQGMyKl=a=(NY!*aji{c;^kqx{)ECbB?aAzIJPJdVS#ZloE< zW}dYM;W+l;N?ttS_`*UM2nIq=AnMNv3J+twHn(_F7b*~P_drNq1qUlB%2i+~Xk3DK z3PONLq8)d^izJCxLW1Bk2}X&RWuci^OMm#TS+qOO^PB)U9Gm0u7!d(LO35`o2t^5m z=6wi`Y;gRrKg1D$hTfo1{3vsR0gK3E^XB&hd!NHU5vzj0j5x@70e_7e-;a z{EkZ?=!y<&*l3_7L|6_CzZ7lMKzC$324f&_2}vn8fI?74#Eabwo@lAM>3X?bu76Xh zN-6}wH`Vi&hI{NF5V09T@wYGCjrhTWBEeEtq6x{cQcuvgA{ji=0!V2X;LQesGtB?K z<}&Ov5D+XFKMsd6mUJjn5b9NE+g8v1>u{fE{EKuWD4QXSM-ZyuHsMra01$9d{&_d# z_)`ftMT#*XYEQJt`}@1bq)ySJdw=rULl&pMPZCEOg@6*L_mc@i_fMg9u-i5ag8_Kn zoR(N;7@|bU5*-X%(aU!8&4Awjxkj3C)TVRt!#?uEPhMk#(__E7C++7&rd^*Z*thf(Jwdzb|F*?>um#A|XMTl~5ym zFkEZ#eA~f;2;~xL#-5Ae_>dS(n6|t(G(n}EpbOF65Ivv>(=}>jyNBgUm^K3|r&3}+=$fFiLFbSZEs_1LG?8w6wBj&OVx7a;WHU+%ZxJM)z zkxbEw%*{~bG4VVw*?<|wh)IUI3flvaZ2EX$VrG+e5Ib>sDT1i55b8uxmCT(9_dMAlcMng0uA}JXY zRY^liC>t{)A%RaYFbPMDF`IsVeuYmkWF2%(5@3FQeqUc-plCmIbaY!=TXJ%8dwY9V zG9H9dF?~!fVmTs8Dj1AdG;2R6KqD1&Mk*~K8ygc3H76k>8GjWt8V!_QIQshd=Hb{9 z4GW)WKtK*uBL_SL0s!#r$X7Z)cdC;wvbTF)NhJPzYHOrp_j zG#VwTR#uuU8)sHiz>Ie}K!hYvqR?p-2$L-!S+Cw!tAABHhNDF9H1-0vh>!p)MP}0Y zZMaz{;rea4*2jqM8I|A)$;cDNr0d~uy;-hjvsr82h9kt^aVcm>hzKNh80PDEp1;j- zKC8SXj}ttIRD+8WB#cUy`7(-LhAkvgH6Pl=L82eVSb_Nq?M@Iv&pR_N<7uFZnP#K=3_{Dk6=DXy@~Mg?ES(h-IF?W=Dt-Cq%-fS_Q$& ze4Z~;$A;c!!#rOujuTiUA;KXc$G9kOJHU48_x2V4m_IEJ5T|iM0ui7!6Y>d-p;2bL z{k`2F@F61Nb5XPqY|J+%+iqXxIp%f$M)-V3B!8e$wGc)uXz6gdWMGcMK_ZNNMh<`o zD}^vdj9-^ST0S4XJZ0mL5HwFk1XzhRIOC_yX7e=8u)_yiM4)u)zy_YkdN6G^Y^Mae zSG^iR*%_h8gtBD~jwf8|1_)eVA#u~ben(&pHmHTlj6_1#c7idGrf1mtuHD54ZtJf1 zzC~eh2_r!fQ5lS6f#w$d)_1(#wy)|0_kZv;u!OK$1#A#e6)_fw=zgOb-4Wr2nHIm2KZ{Kj4n_i8mc4CbYfg5R68B7$139u$<7q82>ME^p|nXmK9@VFX-)�}8%%;wzlrsc)mNzW1Q4x$JV5meg!hbmB z4MZ~GqBO#kM9&xKmqtNQhgebxjURq*Xsmz=6TZN;@A17?5sWAygj8Yl-ar`2jns{A z?VIkOEwsca?H^&KK?ucaCd%}^(YNJ#vx!$4(x?-twg4S$5h1Xc(mY*-ly*rEu1phnOj?yh@G5MTs%1>lol zlaiQ4TG`!hF6xh(+g6KvbUPjph6?bBQbaJqMQ9?7Fi|VgXX}f>2;K+H9h6cK@<>NT z5eK$FDxwb2SAZ0r7dWRiK$x)MYeZ@4e3PJ&=v^2Vh>;ewa}F#LC~yxZD1TJXb{b2F zY(ck@ccU~BiV5F?hmn?XgC^n&l?XJ@xsoKL+9JUMXF8pxRn8iO?gdUlU_~T^GM1+0`r#9U#*xyLsl56{og z+`^z?&;S(p-$iMaCV`iiA%sd@HWL^_C)+_#JQf@a9{6?t%V#n{V;{j=2|z3VR8ac4 z1b)5C{Xcu|NLCQGEP+CO{o^CP>F4XdFWJHn0iFQ;yaOKVX(j|2hJThqK!Vb4!aybb zeEeCZiRfMwgas9N;hBVLeLbI=2@I_TE9t5$VF&zIWe*`(;Ae{BL6ksk`H%gC@V7zL zg#sv7|Dd4KNSv2~vQ~k^6LIe=)PO3V8*a$dB0+*eK~GVrbztBi(Y?g4pb9J-pkq($ zI?(#VMDO(ek}~K}1|@^D%gcW-UooFJpFe$mm;V6@7ubxo7nn}~0000L{Mu}NMsB%}HX;8R@W4nrFvwdEhW=^YgSf6Q7 zc1$;jSVF2=s7U|-01b3fPE!CVc+Z;u|NmJ3{i5t|)ebHI00S^dL_t(|+U=GBcHfOCP})q70?Gkghw>%RWSzYs^txg3vD*?*L0LdN_3&QH$#UX^_{ zF3S56Odd~=L{wUz%`6^Y8AfkKzy$mP>R5A zqzaKji!j8+^2;QFcn?HMifGfBOVr|3Xc}!Y0zs;_y$axd72M_-(9+n5A*c@ow0KAj zgb5x*7=I|)Mzj|ZVtz-os3Hh{-2g>IJ0l3)5L3j>JM~ZvIfwUx2;Jg_fFUp;cF1LM z1UAVLLWCg3dn%;5Oq&l}0!I`g{OQ03;jk1ev$$eBbB^%$99+d@Rz%ELs9y|Gh%ilh zCj<+`AG2tIsWf+iO%Y*z1f&tNAvh~r5tmaC2!9!>To7?aAet;ihysR(8%gdMg~;5! z1rdaAj`XU5;8=QFdJzbQ?LzJ|QthoB4$%w|TyY-{148Ft&uqi!$UN?S9>aAHWFiU{ z&uk$AFp{7J}rwq+OoHO2iSKJs{;=<+(_Gk(37faxhEnyBtMuAHU1+YkwRc z0e^nWFO52#^n5($%ic84gm|r%wkHBELZ^pi2pA895-(;l48k9b5RsNHIdx$m!YWik zM7dn|#WYCkr>SReO%x-;0jf%fNa~7cjgQ=UxO#plw?$4a-Zt~;>f?{D@1L6|eM}9p zD1L>|N23P6oyTwSOd+n6nof;Wk6pZJ{}|&hk3Wx!La#gMTUP)8002ovPDHLkV1nf? Boyh4p+Fkxa2D#t>00LV{L_t(|+U=KN7ULiYgaeM?{ZG7xmN%wo4zRoY z(A1fH5=fuz^*{cJ5LIbAq3xCGQ}o_-=hP{{UKwr1CFpnfMt=?gGJSsFxS^}t5#b@g zT<>9Hdhnr5n}{t#}I@xzDC?RQzQH{L3c^?1p&m^Rt=zo+7kXXaALL% zMcO@yFwI>Sp*^yY+Vn&$Zfhwfmxykgek6j)>QxYFA)g4=isq#wwN9lNzC$?Gng!%o zO-}H5ljqPt{(rHaxZRzf2$8MACf!+l7sl2H z)lvt1{2(Hsu~_V81(D{0z?e}Oxf?S;4`+fQiAV_MgcE|cFeSo44Wu6sps66r2FC~a zalrG)C4c0Q1sCvSw)lDWlj$pB)$?c-l&-Ilh^q2Tb9y!bvy;rjq`i6|f|Jf8O5(zzj1KY{tBdzfLd!oQ@ey>)Pxc_t7RHRl<1sdVLIPhPtIz1EqEajr7gaS?@pceZ eZtZ{kVV3-iA^j*gCvjE%65Qs$@=yOBTQrWE$g zXPKFq@3kVhxVWgOsP3~K(UTJT#v%B`AnLFm=dvw@g@%rfj^wN#%ZwAtjuF(75YUtp z^t~-xSya!@&xePHo12@OnwrUo5&g?5{nHt2WL|@VgNST1!GFQQ$H&M0&Oq6m6t#2= zn3$NmZ3owb29IAGjg5`M!otVL$CQ+lxw*NhsHmi*q?($VzP`S-wY9Oav4)0*tgNh` zpPzq!fX&U#WoT}-c@FHdAlI80z=RRsq88?;7woPX`oSaiyC3kkCGxc!$%_*5yDiX^ z7Wcv`t8Wbd%6}`CTnPQfC;!hm{p!E`<*oSBb^6(f^~qZE!$|z#lY~nJ5)B9c%`pDe zPX5{r=M(2p|zR`{#7$=YPFbQ<;+fN{#$b<+B?fV0JhLUY9k~NdP+K-|zgl0beoH-mF{BJ23W~HR4n1%l&FiTg( zZf`i84}W{z;#I9;{I0;L73b}{XKp&()7tMzjB*dg?V%*+rTp(?=->Q6d)TiQepztJ zepIyEozARm9Q;ZW^Rzo4^$v__!?{OiK39%xjMI6$>-+tAN6}8d=WxJxuh*Sce<4M+ z2Yof96??tjP|8@sb3fqPgt9IS< zg42veIm|)soQHXI*0Qhy6R1CuAB30wu5B(aOdNk&~5nn1)#B73vh z1d|u)n@wFN77Dp&X1pYYCP7>#jrDSIzZ^t6LGZ9#tkxSxl8}&$1v$t!eaa<%TrSq* z@p`&-M8(B&Ilg~&f{to``_EGNGWD_>(xr%-1MYy-E!uZ zQ{s$UvNe2MKg@?`=Ex*zO{c8{GPIN7hs<3 z6qfMgqrIM$t7>7}Fbp%lHyOIl9ZLqO!=eZw_7uVqX!NAWSE}cegc~5JUdZ$Fi^@xR znke?u7^%Y{K9^gCv@na~U3r^VtyV%#j?GH-;%iE6?{!BpN@K`CIh1IU8h;=J9qDJO zp>hr@71S>-E^fDi$lh0c2t!|3Qh^(qram4Bq~$O@Mosn11{i?PpKpOwal8N5P%xVx zDRV49($&3Ur6tP1sZNj6X{%0l289ybTK_Csqj22hsl)d5#bWVA1A*m;le5F)?Y+vA z$%_Jz?9BLKWv^3*BZT0>*?%@q4xgvI9I3kbdJ6|&@lQXiH}e{XDhFp=fMDMMJ3<0- z2N3+*x06qY`JY!k5Wv-draZjCI`)A3vTQnfZUOQo@D67^{b2?*4Xn`FOBM|9JW7-P^az<(KzwFArYf&E>nl-hZPIAxd3JRb%mY zA$8BIHVnmaxK{#%6p=02(j-HldFtfz}F* z+sE(N$L-z(N45KEjemrdqXNNL{SN3?C#^7#A2&6hH|(=%CdM2?B81S^9T9p!V*e^s z-JrD}V~A)LCMqz&s7M6IzKGT4S?CJ@Jz7awG%yXrFbENij4&^ki0U+e8l{OzONd57 zAdw;?6Dkthr+esN7P#SrWP?gjnz2mu8U@3#Cj&^KX2N~l#edU_vFUUYa@jzH7(ha# z6-&grK;azANHPeCTmDP*;3Wc=XpnNA4X=^{`6Nuq_e8DyJR%{HAOn%80A#|yCpI13 zguyt^PBsvsA?YN`#J2M`Js=~I4JmCz(pyG^TO!tlm&RDHl{IuDmq)|GE#Jubaj?Q&6Os delta 1560 zcmV+z2Iu*S5U320BYyy^P)t-sM{rD0O-(y0BqJOl84(bOFP1|+J~RqUSwlEL4pen= zaAsm-MnXh=eSKhHU`$6wU>k5VCng^n9BOK5aBy&Qb8}r8X6r6D<%g( zZ(vctx~ipc6-^Rfe=Ck{KL^U1CuSaXSQlt>C4!4EnY*cbsVv*_0000NbW%=J01)WX z=;tB+=KTIcT7mR>=a91gwBXH8^E#*i00k9EL_t(|UX9gh)cwDk~$!P zbFj*GP0{WOP`AyKxj@{Ok?=xzuYhn&@vh#=rru>)Re!Zj!7me3q7p(8!Hn9~U8Q!- z7Gzeikk9!n&ABr2h$Y=P*EAw%x>OHIhL>o}VUGt3aTTCSgYcP-h4VAsHG%I(}S(3@e?zNW>b(S}BjWfrb-8j}O4| z+vqb<;-3phG`!21)W;hoLRD%4_Xtmqo)_Pa2ry6}gGvyA1_{xyrmBFLzATpT3-{?| zdVfSf(kMK)PU|n*z->x_#D8~B&(P&Zs*#8|3YOr;$lk~ghLr}1>36KL#Lq-fBB7kM zP71mkUwbeP>!cbZ{CqiVbadQ8LkVZRF!IYCr7L@e1@5XBY)2{$}Jj+h|jfTR04=hkwJ)M6#?{6`%z#W z2ZM-MgHwrcOGW5GhEv(67I6sb@r>8wq3mmDsO_X6A{vB%A+SVjL5HL9^s?*;5K8=Z zX_P-UXc(tO)wf7PEPs4Y#H!RBx9?04(mud|aH)+TA{irmWzY)*cNXIqFGG!kL4ODt zQqn_B#`7|cg@AS}{3!YpvWf&f+aBTkh@eG45hMtJ&>}bxmaAyQh4j-PkurV${zN^d zW6t_WdN<_CCnFW%EE1{6U6{#2r~`E22B+7nw9>;yNC9FXOMHz20&TSr1{C2_jnqV* zARb5n2N14}5Xwj(R5Cmv3S>P#S$~3YdLfxKKnM+8R5JV;fGjYRlO-H<=hiwcFj8t2 ziOj3@W?dbU4H2W890;i;5RBs(fr!R>Gn;MJ!BCYNY%vAGI*nt*61X@+f&u_ShN3Tt zA>x)n3n!&xSb`S8rPhyEbUp@VK>#we&O3{PIB7JO1}kugo;*%AB+O@X$bW3J*{sc} zC-Oi91B04MdK2`DfcYV>^9@FyBf!u&M0~5wIts6Spb51)MbND>!UTb9u?axRuV1h8 zIT6FVAcJe8onus@1mJKs1(?_S!6(vB0t90qKnW7k`IP(N``x#YL}*hU13!QL>@!46 zZ!8HwXdrM5F-riPPWk=w_kTIUNv*k~G0Gk|9K^ig#~?Afu@G8;SK72XmMGeF#KICS8r z1v-9?SYE;Vgj>WK+K3GhNg&_?F}=czKcA0dCLr9$T;E?0<$u^6co7<~>Ryom0000< KMNUMnLSTaby{QNQ diff --git a/TMessagesProj/src/main/assets/emoji/0_1171.png b/TMessagesProj/src/main/assets/emoji/0_1171.png index c6b9674635c6a32ac6d1bbae844c0e3ffa779c28..576020056f53f891d60af803bed1d619344875af 100644 GIT binary patch delta 1863 zcmV-N2e|n65Y`TmB!3-HOjJcja7>MjjVB``DJCV^u8)vCd6xqrEnlas~8#iF93ot>Sn zt*wTJhQYzXy}iAdn3#WmfN^qjA|4&|&#mvtrx_L&vO+oXPEK`Fnfi=>Qm{nD+}x}Hoi8$>-ka#lbmBO}M0bo=DS zGc7IClxj{!MSu3koBsRslWtRXWK@rSXZ`Qi?&jCWiC|@AX3x&cm|+6R$;d#j@WcQB z03~!%PE!EbmK!Mx7)|`=zy9avIcR+6-n-P7SVzT|wRrBK=jzdRp6Tq5%ouwB00qNI zL_t(|Ud+|mP9sMY24G}&gC!)(@-_}Q0s@avd-c9A-hX#sChz|kIaO^!kCLGwSNWy3 zeN$hZQ>ScS{BL8n#}B{jbj|++bbEuxaN|4$BptJ3kemQ*0GdGFN4MNiqK3`Cu4nN zbGl+~)G4H-6wRwt?@H=^O!QW^sv6NnMgWNeM1LU&97^AehMBa~sm-Z9OEZkI@Y%Yv zpT$LRhID#OgsPd+L||Se6I-7xI&l$$qWftz5Fo%f4*4>)LJOi4oLLz-ai9+d^*%v# zES?;k(&Ni81czJruf#^Qb(#O`4Bx%Cmi7;OzIh@P_A=GrW%psi#Y~@KhD~`Ed zt)65b7imJQZ7fmK*WH}NGr{ve(?cRD97YvBJ04~6Jtx_ocD^+c_xpn&`3`oIwDVjU z;WLa=qU1Tx(qMXZ(U3{BaLMy-CZ&uQyMM3}PU_nd=Q}PIv#HTU+%o3l zu{3epB$(zM5Eu-&mS;j4)lDZpW9l@UJ8^-q00@_=8hELqiHX@vv>#u5!Z{FtV1L&N zv8z6*Dlm!Shj-xe_GY9(}Br_xEl3^P!l#reZSxD zU)2bNB3G56dI_=5TwWEyG4Tu8ssQ7LWWt}`8X#>|L~T+JNbYqRmTpEtFcM1%+f<&3 ztA2(Bar=6?j$0?5Xt3}J<`6=NOMhIK00)B03Q6_9h|$jk7AhL>p@_aw8*6tkm@zOg z=E+9=g9J`)DZ$@M)YCr}qne;2wl|kQ&7|F%FyB>3e)Jsgm~*UzyVkhZ*1OyY2+=~7 z>B#uU9n}UQLSP~?0HBLIedcFkD{6p$^DpGP*T>d0&m|bp(n|6s`ZL`QK7s2;aYhOZm}tHy=9JFKbXB z>-F_@?f1_7&3iqjY5Mx%PvBpL(#vk!Fc1aM3a}lAu^?z=XrqMz@gY7$Qv1LkkWB+P zi^}N#e@15}lgfys_Ig9Z;D5oLp%0aKzr8?yVes&FZO+`d@-~dqG>ye>^ZvOhlAB)X zKIiQ{hb*cc5lZ*k+hk<5e*dWv$y%k{bUps$9AB?FgphOFR0kkB-6?0JY}PhV!F>hs z@X6E1?FhMjTt_K`BqSG&0D?+Lu@ue-_zvR%u`-V^^q8fQ7$S0zN`GrlEyUtMs?vd= zDS#-5btxrdz?c!~H;HrU9CVBnt+9x;4h)kF1{o&eCsBMO_QF{b226}-U=2hlXoNrn zud_IO8v_Nt|7alM5;|Xm>eh+9AffO3frG=KK|#itzl66d#Lj`x|Ar8PP~@dD@?WB| zUW0(4CJ2#%2r-T)p?^oUX-Qm^k8pd=Y>+Y&{HP0Je^DK@j}g{^MF^vvB0>gk<6p!< z06`b@K+~|H(cq`~B*G?9dObwg9xs*miiRd*o@DEPu`7KX@E7Z`#+?x|xW?C;m<{5| zc0hP%4Ar>b3E@%n!z2=jxJp#E8wRaX2o|?-#}L6am_TETxIie~17U#hP=kqi5`L2h zA}xse^!$9P%eJlS6CCH9C^e;ov}KLo;n0dl;t%CQ86Sy+T&e&7002ovPDHLkV1n=c BnQH(5 delta 2154 zcmV-w2$lEN4)+j{B!5{@OjJcja7=DnM>iV@L_|cDFpR8dfJa&cl}Vj?6b?XenKT3YzOBY=Q_;Gq^zPf)dd6tS_f(32DN zxf|rC8IzNf&5jc6uo>~T9LtUqa6AZRSV3Jo7W%>tl2-<> za}QlzU7?|&j#>23! zt*wZMK2HDu05)_|PE!Cc{rmp@80ZT9=;$g*>00jU{(q*6=3D3e=jFPI)&7=kzUJrW zgVcGg_r%QQT+`>$j-BVLx9@7R#Q*>Xmq|oHRCr#M*XLIoR~iOzNgl!AfDFihZD7H; z1RUG3lifSL_paXQ)iuff|7G7hGb$vbCh* z!Q#We<$v{$h=pAiAye~Qf?>qKDUU`Jj!x+~_^*dQBFJq71QB_Nkwglw*Y70kq zq?0K!h8Zti*#L5*Ii(H~jz6V);N2Y*z(B6e%?Pc7A(Z zy1qR>FXt!7ZO3pTAb627hgVl8e}2Ebyu1b@H-Ays_JhDTOpd3Si@UqhS+92t#^CN; z%u6in3V{=1LJqFF-!6~;`U8Yg>AYJWN_1)$z1|U>lh{G58eoE2>UOV6eJl(D_o~-h%1i7E zNPkl?!COn+-nV{ZFc{v1=e=I9P30t3G$g2oz%qPdbX+^Q0HF&)PGWh>!~}jLBHdo< z-d&wv-SxUhRxDUn4q{;!TBriz@H3OCW_xLA>8Nc{Amk+qRZ}ovGk^etqGegekA6%v z^AP)5Ot6d?8)@`pj(o(jrWr)M88FJ&(0@~-**?lakX1p&1Sj#(V^RYEiq@M)ONAU+ z*;0w*X7KlBp+ttZphceSMZT&DNa7*01gmkh{xBa=YY+yDgxH`Vi9#cX5ZH}eMAff{ zEX6r22=OFo5hn0M`(O%?n;*$}@7-?rw9a_~FC|7=ghxRbRT5zHXSju{XPfixr+?>a zx^9M=loDwZT0$C;v>=t$VxjQ(^cQl@EAegGlGR9Kq~u@$0RbBvyO=C^to#Nw-YY+6 zA1dLSx-QwS#xX#QgB?-iH$KZw(9{1cqnr;V^Pt zH$9PfFBf2xwXE$}cslI~y`wB8D}h5P`v0$;8+rz%UUD0GB}& ziif9bxW@tjvIK`O%QEA6gun_<$Md~AFtiwfWDqdSBP=|ZVH0^cHr~S1C>= zgd%_lril;&A~QRb)wJ-pJg2FK>ed^bS_H%-uOdJ|fy^P6H>_rpqJMPD(q-21JN14& za%KqfO}}3A2-PqQZEH>mx!JZ@fu|{*=KNZtQSUgx4DqT|@Av!lj_Z5QL8h?q+G;mP zLCv?3E*rH@qu#Ft&fAnAA04ijKyB3HyvQV0L|npmoUp7*b_35*3v3|p`d4orJUPDX z*T#99N$ii>Z7K-xe}5cg&BbH5k?nmT$s(+O@C35HK5%{C4@1v>nn_fxc3anMd?{HE z`qms(wWAN|dYlLA>(|gSAP99U`&SPTmMnO#W7r)$gr*sRJ2*a$h1Qc+s|7udZ*3LM zb#d-)S`?4`22|*TstGUBu3ZDrN^%OHV-Qb<7tkV;(3|ZhTz^i@1;G|L4rxT#xyHaL zjskxarS;$#qc7(Z@vZ7Ke1Ty&({S8DDk$TeDJ?u#CP6-@fM{AWqq?1dkr+-O!rIAr z{n;d6&(0KOE&D`(fEqNTMy@JJ41yAk)(r4sPz znC92)HzHB^3kMOQA83MVyN#1{gfElze8F1R#Y1>Mw-+km*q#?gwLuGrRG0vtCdnYk!`9jp_+EJV6sJ;o@p5f-^>>_K gah~D)G@EDt11-~UDgSz!AOHXW07*qoM6N<$f(P&xEC2ui diff --git a/TMessagesProj/src/main/assets/emoji/0_1172.png b/TMessagesProj/src/main/assets/emoji/0_1172.png index f4bbb326dd2669e8cfee18cea633478b070a149e..601615b36b642df7f100e0d3abfef50c14887f7a 100644 GIT binary patch delta 2018 zcmV<82Oapr67Ua@B!5{@OjJcja7>Plj=P*xkBErRvV6UKQ`5C}vzU0`(u~=*cd3VH z*S~nQd|A4>x}Tq)!)kF2b$*~o#VfL7VVe$LL$#Kgq2 zbWH8Hf`Ea6(2s9yXK3xTg5AY}(!X}Qds)PTW8blb<4AB-=KG! zo15U$i`d71!lzuw$jGRusJgnk#KgpmjEum*z_hfqrKP2YhK8J+oS~titgNiDv9Xkt zl#h>(xVX4~e}9;mn9a@2l9H0$w2jlCc+|mm+{=X4rhm+mY2(40v35+{uZh2gSlF$E z(V23`ieJU6Uw`Aqprd#{v5QCHyOqtiY~Qz$5)B8xn|0~cy70G!^XS*-&8Otolh?(3 z?zevJv3>63qF7EtFe4V4Vl7=c6@FYek$Pg7ZA|_9^~I}+@#&_%k7(Vig7LeL>E4=d zY-@c)2xtHR05Nn@PE!Eb{uwU&91HzX{)|TF=y?AAPk+DYj_B9@Z|CRE=CbT;*q^?l z#+Kr->bIxnX~MR|6d2e*000IRNkl#A!&w-u?-a zs=XKYUefOWmmAWKV_bq&a!>ckkRZVGab`G@j{dh4#65-oB;cFBiv3qczxbQav<7bZ7zrN<+>#veS#*c7p ze*l~r{VzGhI`qzQisKKk%{l*q;++23@k6$uV>tHoDN-rFj3NZ}L(eD0J_8~d#eR`d z7ju(fs}XO(g%SinBn_4J6s2ZvC#a!F{Mo{Hh<~(WAPs<>CtL&zz*X;F#KIbldWjx*RgNY0*A zn1O_vqU%VPEkn~h&j$~2e3l2uYB>s8yTgSTBOr<*WXhIe2%68$IL`Ts;+`se%|L1Z zM1KHyK=y25!}B~=NM07Oj$`O%(parlkxE5W(^xgi*w$u{#vsh;MGac%TWGatBuS#W zuB%dlBzbBqRA_c zuo(r&@Co^yGo6Lsj)qZyH|52&v3ICuV}CMFHfDtV(5dCU_*gOQmC{=* zm+>^+n6lwKRr3^Awt-D|J&C7r+~}%XLw6d(vFXaP!JXzRE~%osUc_-cx7IEr?at$P zIuF*aY#XP!?~6;@#(Hm^&gV0~yJnTB>3RdV&bk}PwtZE|Q`8LG(vjOu6SLcO)ql4% zdI{>LkuEFBiFSFII8t?4-5Q`3ws%m6*u1GQp;+QY z{y@!ho+9fz1+oppz%(B(djuYdWr`=#?vmObzgQ0a_1o%X@=TXH-D(tuK^M7I<< zVo5}FKRmCpTj=KHCBvsRzI5FljYh*^cKxnsI=-f0NCN;#04A4KL6a~%|9-np`vnxw z?RI-O98t29L&Yt}39J-^Oc}sfM$|w%;XCXr!gpR6SvK4%hFM2E7;*mMf`2nCS=aTb zJfBh~NkDaq;X4&p^7Y;TFvI8$)bEI5rDa>PY3h3N_hd3zZji2nLAWnfwrkxS7?|bZ zTKurH;J_ex-eQ_ER)qaffnt>H1S8<&?z4HTwrm9?&L^#m<3Eji;cVq; zU=a*Kfa|LDo<-s3j~~l&dHLh)kI(Db&&f(VVxKC-jgTRq1|S$zECj6+h;l{j)0$U87MNfNG7upL zcJgmx$GDNj4T1(d0Fm(*`7d!*+L1s8W$r;YgG?JHDd|#&XMZB&THOrF9g-FU1(ufM4CsZ zQ^by!3(KSE^nK0=5@GT@XE|f+h{^FczJ4M80Dm8n)KV}omjD0&07*qoM6N<$f|BU} AYXATM delta 2359 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 delta 2026 zcmVK|mQ87EePuUS3{^etF=hct9OosBu?ED;KbNT%>JObW1jcRzYPzET3voidsXIVM>5g zJ;jr0j$TLq|NFa&WxkDO%b9M+mTbY1X>Dz7SuzzjH8az?mFeBh2LuATy1CAqaaB`N zXFeSD@8sRfu79|wl8kv#drJ#>d3ddwddit2qkJc(rlymVl9yiu$*^plot?C_w26s{ zfPjFlt*yU-52@&9#Q*>RD|Av$Qvm+w=KB2?{O1Y&Df|9CdSLd*=UA2L=Ym1q=jZj7 zrGw|IWY^K>ztZQxEp0Ou000J1NklKznjGerU-9F4>A1!j~4|NfLHyhcGM1`@-`coa&4 zK*K}+upWdwgvw@m!vta?-7T->ck%TO7+1?%*h|h9#B+2c)XTs%u6&woC~H^ZE>=vuZvQ-PqubsSqMasM&K z8hK_>?^}VQT0lrpBEDM@_g{u_ya;mn$AShc7pAybMRVZfE_C z75ScP2$Wuc@qTuHb^r0h$FDK880RAJNNgZPfez@!5{&yV|9$xI^*X*@0FbXmmjscg zAb&9&Ocu*{xmesR$8)5dHQD*nL&sG|wwpm8ckqoB#uY#!ym-+FPyOg)4MW+ud}zu5^V;nx#>? zB7lJ+lYwNINsH>V)+`jBO;4*E-uujwsHCWx#0fx>g9#@CDy?R5Jbi^V;G6wQW`8b~ z4BIh<)IbIT)L=!l%UGjZuJyBs?iG{}Ox1CXl>v`-?I4lX!0%~2i%_vd#2mckXn+6^ zZe&OYDbXzBESuR|>A#gE!L;;-=Ym1efF~z;c3`PadLrp8+bI2z>hD;h*I>jqxgk+- zsMn~%4liJ}>FINL?T z)r6*?&%f-M;{! z6#nB;e{B#CiU5KNd>^;?VGzxuLu{(~3QX|usG1s<9VxD;`);UmpzRjD8 zu1ZAgeN<13l4B9uM?@1LDX~ubxO`CM!0)^!-!UPueQj$sp?0UC0uq7ZnkIkjPm4Um z?~z0$960n91j1BelO89Ke}7$a013Rv_Z1~2GA`tR;<<^Y;wp};vxdWov{RA0 zY>*_o#d8WoEJdT)h3;Kvc7UzskB=2hN@a{EE~pogu`@g-+)&h;4VBxv7HXA z2LOo6%SvlLw>-QW8TW!eZ)_o$#PQsK;U-MejU0WB4S0&h${dUcZjG^>Jxw6+I4vDF zK@?3hUAqASu7;G0<$rQyq{eO@RgoFgl!dER*Ff^DY zTQyiM|NQsoG}%O7ka!8xRs#)$prIG}4sbnR{OutxGRN6JNP+WpGKl(d@t^|lr?-Xal}eR^gWBnzkQbPjFJ3;)|7}7SOb@@{DF6Tf07*qo IM6N<$f}Li?7XSbN diff --git a/TMessagesProj/src/main/assets/emoji/0_1175.png b/TMessagesProj/src/main/assets/emoji/0_1175.png index f618ab43970bc8e520014cf37669abd38f223dad..0d79218e1ba00d89f0118f497780c3f8a4542f8d 100644 GIT binary patch delta 1589 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1176.png b/TMessagesProj/src/main/assets/emoji/0_1176.png index df2d75606fc7c2aa6c07f3f35343fac4298fec6a..3ecdcd172339165b30ae74bb18ef715499156052 100644 GIT binary patch delta 1708 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1177.png b/TMessagesProj/src/main/assets/emoji/0_1177.png index c8bfa8bf952dd0bf1a5c18ffca7f7a4c866f0247..afdbe09e524fecd7b9b5527e7f16760abb7bfd74 100644 GIT binary patch delta 1768 zcmV*|B!3rBOjJcja7;N^j?a>9!I62_n|0&4lsGdojB#8-PG@OjdoU|2 zH(Zr6QiAlzo-)n;AA+^TnWf zWK%OPE#0S%RJ8rT$YO60-jbe|>Ghmu4QiW-g%^*Z^>bjQq)wATZkn+o@@W-R=!JQ~1 zBSk$t`OT>d3JW(fF+4Xp_{yT-tA!mK8r-CP_0X=ckaxeIh5FjL%!y$8;=}sizn*ql z*~PI-L`76eNPn<`WF-azf?7k&vzqbg;6NP_cuNHK$C|2~l(ml?4V$H90000ebW%=J z0OR{W{vyr(9S;7z~~khA`@`hULhgzIeBmA?CZm!)Rr000GONkl&`&ZtnMF`+xq=(HUcwkf>|6RX+!TMdtHA zXP7Vl8}%Ac{}1KuW~&Oc9@}^SMpJ9Hde&;STEn%ntm@Zx?H2`)z18{}tNQpWl6KWv zuU8)cN&99)vxng!{xvJhYu=i{T4T9~SB~qsIi6?S=4kg^s0W~?C^mlJ-qOom&k92q z1!oLYn14uUeyiRv-j?Nsj$<0`wF3o!c|$9;o@ao<2}87az`2#e(JG&Y2XVvB#Zq9L zgSfTQK3s@v1G$LMt=_PScK_?)Q5vpUvho3ZIi}S=2vAXxO$bWCO~55Xd)Q z4z33q1rl1}iJp81lA+GxJcL?=(0{-H__mJ%#Q(54S~p_g;4w)SyPduXK*zP$H)Dhs4z?caE>o70Lg-Gtx!CG01TH5mEq3)vE!ja0mc~g0Z=MUa5~;vsi1Hpt7na!U$3S6-ow7&k5qEg`2$hmJ?+3pzlPH z?*(;YK}(DP06I5No(qOGNuoSCM;lv75F(HXQOH>hPelKc$ZLlpY=4GX4H+VNA#9RR zEUZ8$$hPC&MnIn+Y8E<)kuDmX7?ChSWXIi0u<%6*!jKpd`Ik^=Gznrz!C*v~a1#sL zTRamLn07rKh-e715#H#REApD}(Q>?HBghbi3HJ|CKrh34-LAL!+8NtTQpE9OGzkXe zQKe@C;F0KG6FdSO8eyI>?~HhpG*Keo!=N9ar!O;8YzQGnyvdLtln~(Ti2NEeCq$fq zGQ-;hAwNZ(hG87h&}+=Q8BE+~_!Ln?O9c8r>}RY35pjioCVl~fFAHGA4`X)#0000< KMNUMnLSTa2MLUoH delta 2163 zcmV-(2#ojm4S*4lB!6^JOjJcja7=S^a`(L;fPjFphBl&jFMdM;|IILzdP=o=4q#$s zR8US}U|^hO4fnhoJ{$pje0+dN2Fs2Ri%3+%BPfk*?_of^)P5wmv;c6N4jbabCEjv>UW{454KR)tVLSuNlyj61jX0-lP}js~G>#FoQ}3%8nALYzlcn1igX} z!i5j6aty_a5P$#vw&p@aoB?lyTV6w#dGpxu=2p>8Rz+gtLtriZff0#hySeR*Fn~x<+)dQG&xiYNa@0nZ7c<;C}!B06BD0PE!E(=VTHd=;#RJ zHHhctgZ+~)3_npPO#k3NinzQxQfQt_2<;vp5l=J z00x3dL_t(|UX9e}chkrk2JjR+D4isP6vz@_AuJ)l()OzN-iv!p?~StU{`2=8OSXJY z?2Dd&PJh14FV8!g(a2AepZqd8xwJSo_7ZXr@+-={UViyGflaEe%UTpclVqV#G-yq- zER8nsB)^XQJRf~mWtEt~X?J(`zR()3L5C*?{d3mzlUO%}w6Trww zJY2K|o2?+C$n2h9w$3lskB-*QFN3Va+d%SdF@Gi+{>5o~Gz?ouNA0!KTi(b!t2-8G^5Z}V^bgecIW9%xor{NV{%tWlJ zKz}$Lf-YT!;YHnHMN7Lm55ucMHX^^M3Zi31K#+9d;3_=7-TiWNc^aO6D}j)Oz&?1Y zFM2uy1W9vb>EPS-_4U=agHofA^>n_lT)|d=Kn7XhNUmw%1&%91hhoM9t^}$bL_8G} za9PoR2;NCC1MyC=Jm2dOG!V$>CgUJjZhuj-1XV*suSSmmCd*}iQBhQ(BBulh2?AUu zVpXbmKI|uj2xO$Q&~zaafql>v--?*DMt2rcrs%@UkqpUySe*6HX7n26R+VOiZLkK^AS-S{%uix31u_y%bD|FzzkiPn zH(rniqv|w~8Ym>Cbq5(AhfVuDIzCj$y)tlF&|xP>|6ng0|CWYQ9-p>k@ew1w+zZ z1DoRvQvb3r@?KQIKuG)rqsgYxB+@$qL%?Ee`mV7`HJgm`9vjK;fT8I!&ws}TO`xGt z0u@M%`?-Drd&LoqCOidfVF`>%uLw;L6vIDCiKGCwIWzics{e(;Uyal{!9tNBK?Z#IrhYq~K|OK+aL|*3FsdNwygr%qTX=5*0!`v^9^JhU)0;@x zXy7-ReVs{aRDpv38_ z7-+6pt5>Zk(kyXpzY83~&+_uhi3|5le>8MAO9f8$9jIUml7B2m6|dSt!eKA_%lj*> z-5crm!33O>tCG5d=?X7&%e|b0r4$;{3UHxQ}YBycta3Ky*$O>-aiFF>)mk*ATGR z1v)uIwVn^&i)I-a93@p*ivmJd1hxf0viN%}eE$x=>^&R&Mj9nVG^mPQm4M(iPjvc# z@BMi^?2;ude1EY*5KN@lY^w{P{I@Uvk0@}wV*3$6$&$dX#p9>z|LtZlu}Z^!;vA*9 zwyVQls#Rwt0nlQ!{BQUN56B;b38I1H93d-$Z$)~=t(vVAK>52bLkNoFK&ZIBDru4{ zrb2K1UrB}%1V>Q16bM2fDM;u7>H0Je1_`fsID!E|Rct*41ZQQhC#1kXo&5FBKmvQ- z`av+7;;F71KnD>1OoS9j^W?5DwGC(glL7*-4by pi8s$6k0F0R9zdQvc+#K${13D^y>Wpg5yAif002ovPDHLkV1hek3>yFd diff --git a/TMessagesProj/src/main/assets/emoji/0_1178.png b/TMessagesProj/src/main/assets/emoji/0_1178.png index 3c671f2bd5620b3e5f385ad7e2414a7d00a7a12e..80fa98c09d5a3c5b8a03ba5ec738c8900bf1f204 100644 GIT binary patch delta 1856 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 DfC#;U diff --git a/TMessagesProj/src/main/assets/emoji/0_1179.png b/TMessagesProj/src/main/assets/emoji/0_1179.png index 8368bf0e863b7fb172f7a19f4623df25a1b2b99b..9c5e80ee850d9093106ec96136dce755adea383b 100644 GIT binary patch delta 1721 zcmV;q21faS5y%aYBYyz)P)t-sM{rDJK`cU1hI&slnrlyGQ&pgEP;XdV$)0{YRgHO2 zIfGR;cTP4mSdzewY=l)fGFz3lh-Wuci#cegid;NpK`a|OVqrlry^3WwW~IiLbE0fd zvUyUse_2m~#YcR?HDjP(jmkcAx-(suRfWevcfVSR$T3-wEq_#qIBBUoaJ4#Yu49nP zX_L((M|Fx?KCgIMw0>WkX-&6+U%7^3az`wZV?%pSI%+>2TsI$mPcFumZBH!~yo+T# z9t*yUUBHfLsd7{&3j>5zGsBWbyrq|ie||zX zH6$@czM3fnqJNc+0000UbW%=J0R1GNBSQWW{_11Xf0o|7VNu1w@!K~#8Nw3dmIqc#wRqcsSZ&DwFw&bVe~pF#J~XriFj{{}cs56#a+jFrF;u^W`L-1^)&U%zu_^t$8cGp2y)2Qi6D{aU+g7 z9B`rM@sB`e0Pqjz`kOc>^KdjF*4PJ=9zeRG_p_0NaE&zq?fvMLwC8b*aGnqiu~#J^ z)oV;H!CE_)K%gJJl(NctB@ZJCGttBqnN0xDj1J)m&RMHwBTVd-Es7#@D!EIgWjMPW zt_A_eS%2msnX@WMZk#kel23zq>@Cc!3rV1FdpFmJD5qdOu($6SQ~|0<^^*Y z&QBU=@lZYH3L>-+g4UR8VvM@V7z89c8H2F35HioDWE4Oc^Il{u!tDi7iE&vq}n)j6g(yP)x{r4|$WS1AhqMD$S(eZVbXYxL5CXzNRv55gI1D zUB(1c8B}CIOY1n391%=w>cdmOn zmZe}X7UzIzR7tE7;CjSn2(hZ214MN^U3P`6(gt#vnvc`YTuKQD^)%4#GblZl;{3KN zc7FxFRIQ7PUrl@d02jsnDHuT1Hp3!+J?`HNA;&8-`$%ps;uF2qmX@8>|4}SAYJn zz0ZVr8##SDel$A1y?_Zuxta79rl1ra?o*VWAfN9GYq(zx`EvSt1bsar?8{MKO$3W+ ztMuUg0U}-8ch0Ac!IVKR5agUQTu32qO>D1#CPmm~tLMMedZq|4K!RP*l#_@4Nsm`V zr!UWcYu~tMP!Q_~8%U!=_MMNGZ$aqgOwzzOw-$ zqj61Xb{|WGCVRW$TDhLJv_+As!bYWs@V$u!ZFNi?vzJE#ILEryr z&ip9qX*Flo@;MAyd7H-9F8`;xNJwdd9frE@ulZ?#ytunCOaR8$dwjo9XPSE3-^z@M zfXT;%I@&c_K0h*?Jl|0EV`;7D!ZX zOn4@4-*e_w@ZQK6AYSzYr+;tp`HI-qh*P4(1SpAUA%GD15S(%fLd;??L5D;>3tD$t zFNXKQIhC>)?J04o!Ysh(z-$Jh++zG{am_xi5j;uVrErni2v9gHkzT}p5>*r$Bq40f z2s>uF-&C824Liw7e>BqI_q45cyJlZ*TSg-)*nEv;`4 P00000NkvXXu0mjf5Nj0| delta 2164 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 delta 1718 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 QVgLXD07*qoM6N<$g1%vq3IG5A delta 1500 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1184.png b/TMessagesProj/src/main/assets/emoji/0_1184.png index 7291aaa001af26090b8fb7b7736b33f13af1201a..e2c49325b5799c92f7eb3c33b95dae6e86132e2b 100644 GIT binary patch delta 2177 zcmV-{2!8kT4UG|yBYy!kP)t-sM{rEx!Cx+Ryg=ZgkS{rGX3_?B+NKF=5 zgG6l3lWE3mT;JA{_wrbE4?l2`z>!oa4lzcTORNZCa;z zU+US!lZ}JEkbiCN<)U0fHjp%ipOO3WtX?`Jt*N2Gy|`{&OF0@l^XjOBESGy7 zob2R_LlI9{8)kPXiESi*e=3uF)$4@-001L&QchCL;(tmU1#obXumxNNgd*`Jt9^l) zaqqp*dwSV&+xtJlJ%5wCn~hjDdq4==Ge3@JEE*@%KC9D~aUkR4H*?k;cBNh&N$Pf5 za=ZO*K&HX1Zf}40D$`!K`CbI$TJ2VM;N5-tA$R-U5Le{)339WiC)%gC+3QlP-3IcG z4$a=39)C}!uO|PFA(MbrFyqAAe-Ds@G5F+iT5F3bgE-2T^Yp5wUqW#-Bh$Z z9>)_9ilTUmhY&+fsdP}|WQnQnDWzuQ>3Ez@On+S|k%L3Q2~7fVvIH7vhG8UW5RB7A z#}tH^I)F5#(}3~w5@w0{j$y=OPDZTgicuR{S$`;~D78)z=bqsp+9VD*uMx-eGy^Z> zrH@f|QDm&l)+G^rL9Smh6+ER&M zfe-}o&Jxku6-ce@QcjP_1OOh{vh3DCdw-}7NRUT;VN1~DR!`HEGF=9o37;Ykp)zE# zAWdT|6`qZHW@n&U9}m_*6}ElRY&6l(N$k_*w%WrT1R}GWl0h{rGnAt zwh&hHa6f&a+QJqWSc)XO&jRkQuO3##cDo~+E~&fiws_iJVUM$A;v|mNy|8W9R)5_Q z05UEkRTVTk&$49}uwC)^v?!{Fhe&-99=F?VwR$M9Im>0D83HbTxc}kXV>;@)C;}%2 z!L8!)vAQa%tMC>s;y#82j;jrN1Q`sKYOB`eS>t>D=;M@%cf3p)--ZuWRTWvdace?^ z8vxaE5w1ATma(l8Y@x!d$Y(HYGJmp+MT;;jsv#7^X&QNR`qG7 z1;#=P-@dt?&;Oat*1kn+>I{#za3%p~mcN_L{`@?jU*7;xEykFo`u@%5FLRuO!Cf9C z35a7Y495uq7NNuZ8sooQ-+!Wr#Vp%bufO~Y6~My2o04pnt}IU(IHJUt>HW zD1w{uZ~yD7UR&A-qA&pWLcFy^!A46oAf4-8LN7~b5kFW;gBZ|HtMr5HZFc|vPw08i zWSUf_eGw65o}6>$tXtK?P*Ldn)AHB18xYYdF7e8`Uf$-y;Q$wMe}DDy>b|ZAF$_XD zCuO(1Y{TVr}jM;KYnzt3wrOkc9^d)2jf)1O}`NAW5aWE9s=wlhjP z0Rs`zQDm=_No@PHKjjx}jCcWJv6wdVG`ETBH-_se%9y0nSvvo;XbO7G|Dy`}Q}bA^ zvQ)#^6f&qTNjjUiS$}HFx_l^_qKH-jqIsxSrAT3zU?57jnt)V8tXE%~;v`1A*)Jfh zDj044*Feg_rWDOnuIl=8L#q|Z$@CE`NQYbo1I@qyQkE*c)m#`Ub%nP^w2nzlKs5;0 zw`m)i*%U&kbWV^WMla$y7Jda?Z)}!k+IGS4h~&b!l8fD_uzz>TfN;`StzlpwxZTiA zWvu^2H5o^V@njev&<z0jhyFe(?QZxS{b_fu%SBAEL)_{yQ4+Gg0VkCwUCypfx zy;4}kjls1O0)rR_Vi?5g}%W^8aXGJhaYs%r8&LhMcg5uR)fBISW}h6@4Wo-qjuA;jhfSk6dxM+clk&U<9%Sq=|;w%Yg&oy3$y^Vpud00000NkvXXu0mjf DyYm(P delta 1764 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 A#{d8T diff --git a/TMessagesProj/src/main/assets/emoji/0_1186.png b/TMessagesProj/src/main/assets/emoji/0_1186.png index 0ae1d8e4ada0fa51b28b59f29b34b7468a0779ef..a752e4dfc90b84272ccb935d31bd4206352558c7 100644 GIT binary patch delta 1866 zcmV-Q2etU44%rTnB!A&hOjJcja7@Xcx zSlZCW#JQ`9gno@faMH1VH4-|3E0#eKOjR0Vcqoc&BYkZ*Uq#CrGynhq7<5ujQvfCO zd9Qyq3m0C^vw!v2^5svQ@uA4;=i-XS$ru0t1`kO@K~#8NoYdz|BS{nmV2|23NtQ4I z{#LHeIXEX^HogA??YY$kp&2mj9ve%5`|ES7${t+Jc+zJ)_+OcfrZ>Y`pM`h(V?6#3 z5WRWq&G-9VpZ$Kn4CdbVkumban~mz-HcH{KXgx+_Ov*uDK>7rIe|YT%Yg`qg*X zrB4VYL5*v~A`BUVIb@y_f(3!mBaq0tQp24~M!_81P;yz-by6l_uk;dXT$=*`cO`No zC=TJNEAloFHsy0-#+|@aWrTGBk~;(y*qd?l`G2Xn>&H+vb+G;gF+kWWLR-w{zpTY% zI_Zgl7ZQ*tO?R$&?jsjOtC}U3L*n+e&t&9?VRk?5TMXTrX(e-M(82gI9!@b5RkVhJ z6NVaI4|osvj+j3B(LHI{k0cEhj)d@IB*H7=6i9Gtr8x^h%t*MskL<9w?xQ$*SWE_! zJAali2r~DrESE;O>-!gxm!%YFqH2yZ*ptyBf*i4F*FKZ}AY*Wz&JnXegqHZYQ`>s+Put$K5eeT_@0wCK9Kv>(uU48(AqB zOi;5Ze!Q6sE}2r1ILhK0L@w&%Nd;U7O@HLWh$7oHI2o!wb}&$sMH&8sg}@kZ8NooZ zs8+Sf&+Q2ValbuT0I1P47*U&3TSyQb0%}{T@ZNa57+M>1Xq&JOv*)()U5P{6?lcpJ zripW@YP6-nfBU3NMNETd5to+Ud^kL}?Xw?cSr*5qw(SnjO_K>zG3tfq936hi(0`H* zAE&~`&&OkPJdi-8{qEQ_$IiDl&mkbbnEobUIjj!>hOn`3-MPeM7sL16->m2XUwrsU zn@RzL6blK7G9nHjC@~^TFIXc-9}!-i_eSOi*a-sO6X^HPW&?wSicLQvZg>U5k2CSI zd3m}J7R!$xcu(8)`tQv~U>GAc|9^xa!^UE>`2%m?K4n0xF$P5Tv|6pUD`$vY^3Mpy zSd|+HFRL}KSZ^aBR#>XA`uTHkd7!{?IVy%1J;W@F}{U;Lq>^wXiovwC9#`8{(SgdGy ztvZK^A0_u9@%2E&^Zk@Fj9w(#g3x;Hg7N4|xkBJI0E$T=I~X%^Dz)0G0c4YWetPEo zgE*gFlQ+3<28hzmxtv4t$A64zpYfg`6RTe!&KRfi-h^hTW}K=?1{Eg5cgG2@AmT(8 z|L-Btib6(yXMoLaMmzx>2KN?2q8~gprV|B3sfvc!e zVVK-EgS^JvPMNAHln}F`E3%-2hY^}F7kRZXs%3S3g;+;KsbY1e!+%SBAhk`Gk*G6J z3u3brh2;hS3p7C(9>!&n(eh?MEUp{{19TTUMlOwpM6HQXR|v~Otr{UCb))<-#$pMS zhq@{dEDSKzgpG8$87@LYlFxIX5$OA#yMt}5uc)me;5g?o*o#)CbO5ve&!SG<3QM*wFff#Blae0=M^l>w) zNF!O}cTot&kO4&NW+<6hf2levG}Mq$RO{S&H^3p{5KCx&_gYb5?F56xm`-ca!cju zmP`!HLVZ&JnTZh;MG4Uu?rtdI_ATzq-?_cv+zlQ04TEgljiS0v6ccxA(%XVki6l zFSaxHinb})iGOpV00u;UIy0nc{rEcje>U6o@pxRXwwwL_$6x2LTOWn6Cx{h@#OUa#mJH-FJ!^`x(u*Ext#K~~=_vLmhHCupz;HX+a7E3y^Vh1M=> zV9+4nF?Qla{h%a0oeJ`iIZ;A(e-t+2bfw)8Iw>qDz<*%g4EtweFHWyl+YUo$xhA$K z)%or$`!$8~whcp2i31`8FcgQXeNJGA!|xY?hlvS@;8V`1AcGFJLBf*b{x>C#Cpd_b zNrezpm(k!FLI6VNcC)U&Cbkv;D|D+=7|=i@1A@-nM-ct>I`;JlA`5{A&lq8ONo5Gp z`pZ$aSbrF5_nq>^Xe|MRGo}H0W3=S@iyHf9iSKJU0^uAWIWozS5P43u@)tFBvWI_= z$t#yqa>~U>CZ3tGABmK5mYdJ-iM~gH;2eodB9mhcb=|}aiQy_T4&rn`@ zm-^iuv6}!00SMRu5U>bpncp*aYcb8<_A)&&MY-HRyeBg+t6q*TUq;tvALVsYU zr-ZdqMN6g@>_Zb2E8 z@WIdN4|hb1>Ac4pEEa-E$*O^bu%(1AGb53g1OQWcL5++x>Lf0KQCk=*D3nlsp4pF^ z1u@lN59Kw*tI|+>zGU-0iPcUafOR3$?w%M6f=1bB6J`1PE7a-;uZ2{`ha4^{q!T_w%tQxvt+vx}E$Hpv&-NVL% zY0CWnKjzF(#3H_MBI%QN3I{3#S}>Fl#_N&ubhjg+&ch>}$8P2Qr+@Rigp}*&`OJc6 zK#1Tk&%68WliI#*Ixg!m4JZD6Kb=S+Ue3xt17>gj^0%f)-^y3Y<~%= z^R_Gp4T9L5NRbRV6Ms?Fh;~&(O@Q2UoCA+(O3rl+F$8JmDLN`y$7tgu8X!iWaa{x0 zSY~NF5wJ3tDCr|^)PTuQ%NWaIzWClCAe0`fQCeFFBS3N7kJ0yW+}I5$hT@%I0jd^` zFEb-dVE(tpewt$zLJ)*!?p^PkDFkLB)-@&q)i)E(xAK_1NDVRo0000d z4>gM}qIhRmk}s==e|fmGt7al~Z6touqE6w(h_Zq~f-9DGCy6=^L{u4JL=sP39c+D+ z6%YUb02XvoPE!CkeDwWc$p;b{gsZXi)mb;C;o$x5049zk000H8Nkl2l&m z6a`>VNn%lzz<-o~-QKk>?0B2W^8T-tbGspA2-r>zE(*-mS4Z8AJ^DN|pXp>W`ahYC zlX;egWYGf5e{d$qG|KC1x~|Qm<+l-B4j?V-o9KKoold`lOfa@gn+n8D+9m@&`BsNz z-nNzM{$+G!`n3T8W%IVy73uDpy8FJtLZ<6ZQ>Ao^bbtH^3C34D17Q+17zaU(*1Cnm zxiGEDV0>{KOH8-Ap$avANpQ4^P~)rHXti!iBJxJ#^ADzMa6UfY4b4DVQe`a+U=RWm zpoVxkJ}prKK!_|1(rtL#T%l4eMvn=U0H8{x%8DEeq9zz2!BSk~@nS|0kWy9FIUu|s z!GOeA!++xA8hkDlhwsBVV?07!{u&UJJ!~WMGR^YwhNN`44FHmJ zL3BVo(5U%CV%d0s*OG!HBZBz=tv!`HY_o8!#b&K!ssHNID&j2#7hY*XwG3B4@o( zK7V5x@(SJ0Nmi04;{pabL&K?xOA>u81;-rw^7)zUu!h0wA!4TG(`92WH-p52K-gn{ zVrt)?P=gEhLqkO3z3+Sr;UjMj*cjX5gF}I9duh$bTR%uYi}!o$;a`#lyCPtsejo5SIi4Jn3;9_~u0*(iz9Z%Wk*ZY`kHdC3-+8rK~j&w!6b-w>$i(*)S~p+--hrHoMK?cb*|6 zx=Zk1HEY#&iwh7aui*&Pf7MxcEsDcX7=XuF+*w^+5iuVHWuTy5v_(iRlAh%M|E)c5 zQez$BTkx(A=Ob-(os^Elzhi@!V}H}Et3>+JeD^0IHQxZ_?k>%DBL*iC?Y&o#AF>nY zZ6^iL0pJ`6w-NXl{ElF80nh7&o$y}*Fv~;Ll~2xJPaVxL=J$SuH?d{BvAaF*AA{$;qK@qj=93rK+hQ=QQK_Myvh2b`D zh)oi-SB6A@A=tonABZ!Lb$=gLRbh3IP9`A|2_Qkt3UNRbnqlJjhB!(Vl+CAr=El4b z141wA)AUKO#u_NaD9ucV6~vo)?lcQZSp-NiN;6X-SW<-wjP3i6#}l8W)dQGZJrw@beRJ|z@1`dJeuM7Dq&{(q_j^6Ij@`H zydjK5N)1UMgpDLl1{SZXL`1WEP1`I$%uF#X6jLJ>Xm)n61%#MlBA972FszByhh&fS zQ$7wEfMAd;(W4NM)i=|*+M`qeYyl_&5^;r$kl3P#O1{?rwg_&|z^|VX+myNRAFQUH UcTY&pIRF3v07*qoM6N<$g744^Z~y=R delta 1636 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 j%;nuo(AT|W+9 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 AU;qFB delta 1783 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 D1XV4* diff --git a/TMessagesProj/src/main/assets/emoji/0_1190.png b/TMessagesProj/src/main/assets/emoji/0_1190.png index 59f541a02eeb208b232924d715d85ed1c3d3fa99..6766de6fe517f8a153561837e21aa5a5afc4a7cc 100644 GIT binary patch delta 1975 zcmV;o2T1tN4#W?TBYy!JP)t-sM{rEtzk#=QLVvz zan{0u;K6~;xNg3GRg8>`-NSu*dwaaRyq1=hot>Sks;akfLEOxR$&+N3mX_eSing}4 zZEbCKc6MK3VZxhSVq#*EXi&tfU%!4*&d$!k!NIq;x4gW(YJX~KdU|?eV`H+ivUGHH zUtV2sZ*QrosjjZB-?osAr;-z!NtYJq@<*YiHU%LfuEnB99vJ%0000b zbW%=J0Ks2kE9W`>4$=~c=gEtWzRk4a#4^$@MgRZ?G)Y83 zRCr#Tl-X|LNEn4NvM?rqxC)4yNS!CB-TQ9#oowAb^MC%YG5=pSizZ2v^sz6>Lg%Yf zhpKA)L2cWtWw#rDp?0S`w5GF}4Cwa!*#`v2u?Alw46LaiTVTNlUeI}9eJRJC_3VU^KXcw`1}ZwY3FZ(ITTxU@ z(c!>z(tlLTux~E|O;!}d1sZ1fR>*BP#oHhbwFAwdq9`nQVAQj3Hi3bQ zIM@b}j}A1V!UBb$Ta6C%tYPeV+iep2XbjOFhB(x^wGsnk7oqP-3PBK3sqoJuIAC zNf1{-dgh-IJ?PF)65+Z^DWYl)VUmg<38Js0=;10TldDy5Sd|rss5A&xsqlgTV|>ts zc@?Y;h&W;C_OMD*S%O>?Pt#SfO@)r}<2rSPGf4LW`2p2aB4xP%m9<>_Dy3u|#PA<3 zfPcZbIx>Ah#)DJ12M8gFo|n1hS*}PWQ$!|l=r_+hdCX*A8(aAQoo>cX9C@5D2)@~* zXNF1-yTdvq%!~YydAgVw$lBuv)n9BjP+){Ssrr9XyW&4z?gAH zM9phH!n~XiqXTR&qFm;0%h%WCu5QE4kAKV8<#Lz3Ns$Odm|aFVm`3-f0_;A;Ac}Nt z`_ZG)&ECNBy3MmHMz&r8A;>Z=68g|+55`JI=(idd-2(%p3=?(qp<^BJUXkY456@T|U zpb>YGFG|dy>%gxCOpS;!VJO~zw@F(g&JaR4r5xh8Aav_W@k1%aB>tuWe01*Nx(*2t zWC)2dTr?^~xHW<>fdmc!NnwM1&R`r7%0-Bfu995iAOue(05qX4;$0n7)QmM_)l#JA zd6a1aP}ff{z~Imb6!D>2kH7%P@qgv%s8C>(fYmT}KbcQ{{eF^o2R(jzWi&l1BtO2q z{Q5bc?3E6Jpwdf#Tlf7^=DW_@CaLDKQfRgz>rN@bPYnp;U7Z`oRT&xBx8s-d7LM?}I5x&>n3IUL z0>H?U5@Y;$F3b^Xrc(qTCAOw^BUxEc!RZPv&M>}$dtk6At$J;08x1c~7EZI}TuZ+U1_dcqp)j2R%Ef6R7{mGQmtM^~&d>$pFhCFn{_Rb-rhv|@J1Q(6_!+b+893)KwZvl$Sb$~FTuRDlV zO=wQdm`Ch1HjAOi>_m(bX;l$IN`esUg>DKWq|_hFScmsvXydV;^H19WEFu8cix8pM zaj+03z72yT({49E5Pv`*fe=tA79)r8H4N)v(8j_@E;HvCy4UFhkZfU^5jqvz&5q>4 zaj1mq9uyK}k;rI9Is_46Za;Tar>B@gB@Z^lU@?s95P)s4##AsJf#6)ma7rmTc1W%2cK&6!lBfaNU=5id z0%(ejK}PV<-Y|fPS;qZ}bOYLMx0}s=e@)u&H=8Y~pRe9@;vbd%RU8);L9GA)002ov JPDHLkV1l{&$OZra delta 1856 zcmV-G2fz5l56%vdBYyzrP)t-sM{rE4s;Vg@BPS#zLOeQUTvw}%aFvvkwzjr7HaBr> zXeA;du#R>qB_(olb9{V!EGQ`*8yj+Qab{*^*_?IUqI-&piYzE778Mp}Wn|)}e&Vc# z*qnEWWJ&wnyYbDdB_bmD*R}lM!1mLzKsh){LP07fCR$QZ6@L>H9~&C&zng%6e$%y< zx}AaNwU5cGi{h<^*`|QuxtCx+EO%H!&zW=Y#-rrMrFM392nY&_iHN18r7$ZhaBgg5 zWM!S5ovNy;QcFw3j%GG7Fk)C&k!MJhd1JPB+mhyT`w_+mau|0000U zbW%=J0OyRZ9)Ax0{^vDsR6cZ_<=o)y#N}z(tXf= z9j*otQ_$jk?w^`y= zXVzQGwtv7lr5@$ko?B(G<%L;kI<^c9X~zfid4ofmHM(ssZCKd`42jJc7&Z>RX3Px9 zK=2)$yH4XCTpNf8jInKN!cGDuQTDcBND?@&l%`F3+iGt^vN9*g_r`dw%{<~u zAXFOsz3G1SXVuz3=ni$FO=jz|B3QQMkz{Kdwto$X#7XU@HfNk5*;c610+4-4s5Z7j zLUjvdFnElw4Slw%{y@l5K`u&_IvbCWe4lzm&d`i)Np+g~Y#9jF7_S{iEj<~pkjT`@ z6IqV;sg%yFTI8;G1|b>ybXyW4dz1j70u&~oMM0iFTQ+AHjTVe=rHV*fNsHI;L zxqm`X-z!u{*r(&lqN$64#F`Xj)n7~4T&IMFsDXxws>+#d9Au?<<{C{W(g$LkI^zL_#Th_j20;qUmaN z?r<*)suD#hy{ZUB#Y<+xa^iVlcuB!D?0=>U-u-G>hwAqg>QjOS6+&U5vY-~cqZR?j zf&*ztOS7IiLJ32KguX&p)GB@`gHx)JVW-U>!T)S*0SK8WOhZx2iXd~10_-xR)Jg69 zb2B2+fPjPYQfX9Cun7+e8 z*aL0gN)QD(EdqpE0P)X<=KLp)gQ7YSFsed90Yc^$g-_KYi2}5FrVJn`V*pYL*o3^b z@O-oxL@}y(rwo-dh~Oz4L0&CFUw@@eaIOmEDvO;02w6cwfxOkAxbdiBlR@H42IFU^ zs5Qzx(;&x95`nduj(cYjt#KM0H<5+I5BJj-ut#iL{d0tF+p_Xk4d{FOP?75+0m6sG ze*6yN!5U`)W5_IykR=2#jzF7`Fviy49HMh;S@s62zym4b{hkuJMtFWDVSl&ITJ&0m zl}16q7*wV4K21FUIHC}O+#VZkSe%6n`VR*%0HLy%rs*t$M_tCo{CbD~E#6J<>hB1B zfZ>F3{+#)W%%gh$9dtUE{TF>*F_=k^Z}tZjg;LKKC+@ea50~aM`;!I4N#e~jE?6nL zb7ZktT+Dz+90iHP5rVi_%zsA+7@xYAGlV>jq96d`dAHsH!5J58bcf##ITFV?EX*2l zxyJR?r$ZcJ9D&5Mxi%N`%Qd=~|7Omk0EwcQA@r>p5y{BqR@>0o~3y6(i)C$wO3lB!OWu{KBI<9D9_iTA_a?|%U|n4XB@ayeb- zenB}SVj9@Qojx%Hk2ty?UjIV4y21Do_ zs4!&n)ieP3Z5QUg$2=m27)`|Ks@8zbY68g3+q1d;BJz0-V2r7Y0v2;5)3vob5utI~ z84bH9!Vyqo@PEjsrHdmp&E4D`joiudqydlBkBrWjB{n@8a0{;e`1thr`2EoZ z0-HeNm?aplJ9^z^h%M^*69IWdzJu`O&PT4u3#~PtfMBIwS8GgAtd5ga`F5T&R&O985YXUl)DUI?4P3G=ngC+@tHcShoH@^Vp>J1NRTj_yLj3r< u{Ppp#*Dt)?f4jN45vw1c^6`e{Q}_S+Bh_c;+BMAp0000S;?1eYCj-%N-Cy-V$HIax`<$2 zLoDjv&4pDmIw1|tn{gHq44QOPO*J9hsd=f2YpaiP;mWPNn|=B9?#s)|mzS8Got=}C zlCpLc&CSiHr+=r##l?+{jmXHz!N9<1S4Dq+eujpHqN1WDVP5qB001F$QchCCIC>UQ|MD)B+h>F!J@wM4(ZM?0L-sKQFb)f26xk1&)I9mnD@KTIH zpmQf`Ro6@<$=U0=ZhJGhR7VBL16Ku}hQ#ix;`TmqFI6(C{3=Ld6;R>UI?2fzD+7Wx z`j}viD zJbwa4BlsJIAx02Gjn07EyQ#7E1i8CCL3%MuC~=&ehuBz~I*Qp8=bL@FDz<0D##{Z~r#beRQf)W8*M!hnzi~-|DQzL0g84MxmPPh^ zQDmk7xUwQ!EtX|UBy%TL1GpiSVBYl68h^|cv7G zesQUS$q7I)oxPsweP{;=Ltp!28}a?21WR3&Wn^^7H1O$gAky`F(8U|GrJOWnv_XJ@ zLDTNYL!9gm8>XJthh2jx4<3u3c882g9}TQ)J#Rqh{dYiml4#-S%tt&YS(!yy34esS z(XL!ayE4nEM5uF(i57qR(pwYWFsSECg7avdt>+F9)@$gfGtaU)&ap<^H3SN6eWUJ- zo*05+3?msiP{SG!ry0eB3q%cp(pmSNBM)%{!MWrFc z_v7*S{PW@OzohiW9WZ>rNbetBoj6##z78iWhFd4Hz|->Vec36hjl^l^Rl0fZ;ic}ce`TS9dy&PLkggcE%S zK*`puZ!QwHpG5;k=j17oF)F$q0Buc3YQO!rg?((F{n3_T4g}3mmpdP=>^+tpy>0AeG#o4`eGNw#Vp=`HRuYVoXs9qH@+}+ke<3Lf}5Z7)_zd z1O`Leu@<2uGnCt0ok6VCgit6@8=EFRIT?W9Me#D`P~ht}Y+Z11thSrEsQQDE9bv z7-rz?(c)qyHxGmW00IIgiZ%@xJPf5e*Bc`&9+nGHL?EkdVj@6>hUvt-$djmkv65{M z#4DlB1XBz`)ocXI(>f60YAH>jXbT@t(S?a%gAWLVjLeCQWPcKfg*RQ?yb~iA{8no> zY?m6zxCVPq1ZkMy-4$Fo%NoP5kupGesnqK`Yqcf-Rbd$cLJw O0000*M zzkO7}!osMisH>~1x3{;lva+tOuA-u%R8ml9W@Yrvs9{}NJ%2tu+_a9yp?kZVQ{lUn z%e89bz?#{tg}Ih<<;tVv$Drogmeiqn&6RD&ieTK#gtCup*TsCVj!UC_S_0P%-f&D#I^|cV7mYS z1;9x}K~#8Nl$QB!+c*%13kw3|7+x5T8>DGpV0csKefT_*?D76jvomzupbJau{shSX za6WyUAq;*QjyIXFW-hDwWIC{Dw0^eON70*06lIIm#DDuOz;wQdUjLIlQhq~Wwtu~m zC|h~=I($dMt-M8x`$W9QF1k&4eS6F1_iSPzB_eJHTf6^X#$*xgrJvnWpw}G?Z-KUw z%gZ!h-Q#lojc~w|@kUZfQSt&AHxg0yi?O-P_f(Ma*3Y7kVA(Z$dMLBeZ8%f^RLTOE zeimPo?SHduzb__Z5|Kk}cBS9p^3TFwGpsSYe6aAh#E`|cqJS_X^#M1N=RhtxkLg=h~}_1bq%?(ikcw|A##=*lAdv6c#fC z85Wa<|1gAj>39$WF#yY*Lx`TIh`@pnD!{FT4iP$p1|_u7kOVSW4kJ=R=vrB8jj>dY9#;+Im^J7) z@JA5Kv`0j}-kh3zeXOk`TrDU~B@n@r$uOc%(^w0^stq2k##va$5Do&SMhjfz4SymY z90El6Zs|xUd{cgEKu(A>d7cg;yyrAcG!2#P=}6dLEOc{0;6MiRqyInFa{N-tO$93FWKBtZWtZJ&$p|RI)Bwv?P@4gH0Lx2n?68F{lEG+#6n?L{l>+2t1 z?#(ht5rRq5;B;jFR$4E+ZNoqmKud&RBta07g^_MTi4U0yP^4W{MHX2&by06bj{pB_ zIzy_UYNV}m<;TWzaEFEs?SEfz9K*)(dV_u}^PGs|kJm6V63E!q?=Y$ZHX-7>bABb_ z^)+g_d;L~b2TUg3TjQqN`5BLLK2+5aZ~lH0aNTLtO(&UipVMC@DTti5n_!Lq&X0^u z&&$)YED6DVa1)0$AXsIL;`iNOk-FPqT>t@R*e{ePG^hs>KJwvV4S#QC^ES{%5Fv2R ztv^5SGxF&XYaD+%4?PKMLVOG9S{k<$)hmByFMA9cba!;}!5UqRK>%DLH&W2NqV)JM zahlkdN7{vIoFH&zbg9t`Lb{F6+$W%<*OpDw|{jV}-(T-2~cKwNi`frva@1Vhu5ObGsG z4V_kjwn=M^~!I4d6- zXgwo~RWdgu8--9WeM&4nE+?O7K2SY0Ml~&2MmwTxL`y0cb3-V(qKLDPYa$j9;?==v zR!o_9S<<+bU`;~|2m|->>aKrRieN%=U{t22rjnA9d1qXHY+;|DpUln8$;ruugoMGt z!I+qsi;Iia)qm2mcNKJWbhx;;yu7@|#>NDSf0+OP03vi!PE!EqPAU8rYYHbk>5k@% zvBp&9#LwpC*;Emv(d=bauTdp000IyNklrnV>`5Em|4sIsE_zta+6M2}7Os-`KmBz;#eb)F=na0+|MWlTcf8N*b&ago zpGWS;EuB$)|8U~Ijz{jtB<}U$UwPzEhoiwq4slgu6dw4)JW$v1wR`y?uKXIqKvMu| zh7w-raO2qL@qLTUqW}QMMTYxBRQmOy1=E%|j>FD*!{8cHVacO)ZNVspF%L|7XBFNW z2gkt?V}J8D3~@{3o-cv5Ltd8Lhn#(o2nZvraqgq-gjhV{N|jt;BEkppqa)|0;e}8= z^m!^27V$BPVIMeZyfcbX2!;q0I!p01%5P~`(Ww8fp*O+qzR#7GAi*a5sNt<*(mONF z(6&~F5CRsFrb;y$j>kgB)!==_6&g5?jARz@n14(-ASyv}nF1Q9)S&@IjvB_KF)5tt zA_bm0V^XAwi&jGoScMU3sZjCXS#-Onb$iaU~#WxfpK0$QLVp-Hif4*8xC!BsoW;fxXarE61$FhZ!6 z3{y~$Wwp-Nn|MWSizJU%(PmlgWybwc-wGB)f@5e$=*~53B(U!|N=Wjf+VFCdRs}@` zTjjVF+ds8Y(G(Qj*@8*JlB}K7ggn!9Q z%;69O3>s$g8^bv|5Rpkn8?eM~hu;e*j_q}3hen8;4_~?bGflt`7?438VW_Z6P!fX% zdkegF3->*trIl#O7!4pvjSi@mumA&;-|vYvh}Unw{uCVu-Giw)h;bZ8kN^N_vb_7g zmyKcCf9uK;1|1J~cQ4BXi$H}elYjW1CHY^^Pq%k3Qfecv-@GzhM;NUi9>3i_KYh)Y zgf$~*UW%_z!1LqxKkyFgK;Ughw*U5c`}6|>f9Fg~t+mlI`KPdQ>rEquf^cb|6a-R0 zYNR~mqV@GBL{*il50$O%`d0b!|NlwPIV>TqcIgOS0DqpDW4yw(=HOkuet%tlA;LUk z>0|GZ;D$l|_(pmyE`-)vs4}wdiN-mv&6D?{HFE8S=9e!o%U_`dP_0t*HZO>9)raD} zD4{um{4U>rer*+101y+`nBuxtk2yv2#u$RE1tg{EqfI!Bt5%j;rY^Bp~QTm7x!n zAq*W=gpfkL(&xTZBw!eT;J*qOe}|z;Fls-2M2}z*0nVK|?X73TpksDnv@kc4)iWTF zK!_qt^jUS?TbMA0aev4clZef>6be1=6TMa)io#qj5k$<4E(JifzpaDSyNFitEK(w%aKg@t)}c{m~xtbeSmPfbgbl9FOyUYwkp zx3{;kv9Y9pU#W|1si~=>qob01YQe$5TnNM|0000JbW%=J0G!RkH2zi>=XU6%=hNuW z=;ZkfBSsGZ00nkQL_t(|UX_-Ia@$H4M3)Izh^yc?IU$3YitqowZTk*^5@{PS-74Bu zEZkG)_KZaSXMa3tlFb(L`C`79Wl1{n(B%AVA*A*(TA0NwS^ga%S;)8dn|SeKmi&dn z%m8qcxA!+M>e<~UAp8PAyfjbQU4UiAWNiAdPKs1)s=5{ux)Hx6n8Z$%QKr{^?ET=J= z6`JN*{+-cVx`^_1Zmqb8L=~ z#}I3PD7X`$Ee#6x{zBdf>YYJ1(i{FSXA0e$S7?|!_G(V1tfA+IW&n$ zrOQ@{qAi^SB5+>e-vB-kv(ej0mkN&-g>!ACB#Mx#Eh|+N;5s0DP;|UD8~rsy6HakJ zlz&7KGN6d6EejCfIeNl0(c(4|2jv{KCJ5^DX zsBorbOAs*V9ga4!relr39%Bf>YR8qU%Chu6Do_Z4K*bv%YOBW)i802}Gr5qp~9O8jJ@q~a=QzeuM((uH>MZuN!US~w9Adg>!Fsf~0OjiOYdywZqO2+p0C zGMhl8i&_K)4f3eyZ`Kupb1i|;5_?Q(Fardw0){pqTqC6C$_WOEDMZ7x8yG5gH-DEa z#47S8nMT+~^cwgPb$N}D0us7urY$noUSVs(; zFd?*rgxxl?DMGri4K%PyjPi_eFv_S=c;Q0bG zz#@~$k{L5#08#}@pUu1_1{UGcfxfcPCTIhffLVT@On+xOkoc;xa z)k115g~|8(BQc`J@m`H|{rr!}S#AV<>DeETf2*;~p7%kiATiFYZT7?%5Pz%ej`{U! zzjs_AE=WO`ev{Qb8Z?jWb;UU#mm?7d2x1&gAFsQQ(_=CUNwa6t?YeIJPr)hVp(PN< z{c&?T|J&#EuwMQi@PO&V;cz;A9=Bgb)iXR0D74#wFyyfL9VC0`;xy&sQjXrMHRtcNXrChQO}&i|gz zXR6?}1LE{?!}yGdO~1<;TU?Fz1k8dG1H>;HXJ`QN5IbFVeGfD_5Mm;PFj1t#eYw>* z4;pcm>{8_}Qobz+F;EVxUgPyfqZ>3Hi4f-pk%6!qJWfDBV|TO4Dl n^YVZ^#wY&wotH;?d!7CtN;Ev%f~-T^00000NkvXXu0mjf?PL9% diff --git a/TMessagesProj/src/main/assets/emoji/0_1193.png b/TMessagesProj/src/main/assets/emoji/0_1193.png index b4b6e4bc421aa4c246e0c1cebb0d6e4341027e88..2be5d54592807f01344d49a13911cafbb96d0daa 100644 GIT binary patch delta 1733 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 XR(cb_-K!+U00000NkvXXu0mjf#VlPW delta 1312 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 KMNUMnLSTY*(m@3P delta 1925 zcmV;02YUF(5tI**B!3i8OjJcja7;dBmE^ZQ)vHNdW`ag+v&pGlqok!gaJRIje?mr5 zJ!+sgQ*`XOFYv!MOksTEvoz|pD*4V-&Yv?tUWCr3L*%X|K}TJ_haU9BM?Gec)t(}v zlXInxV~lJ?%B4%$o*1ub$R6akeY4K%iid*vTUyT`0w?=)N<@oIr;(s00s$3L_t(|UX<49 zavDbz1z;Drpl}5up+vUIi{v#OPTvqj?jYGb6 zS^qcl{D17IaK1?650lFuGq2R(h%jHMWg1Tdo2M)m^IfW{%Fhp;?(k~8&gHzDUcg`% z-=#`Go}-IH#1yWk3S&}rle<|4sn{-@=eZE#y#Hv&lPl<4;Se&(OXe5Vj`CHma>mLs zMvjD1N*vhHLFF0a*oE!ZVJT3Na}Ob+CcK2iSby(~%ia>trX}ZGWI7@3HaJ&CzSwLE z)sXpS;aS-TYP6xfE18UEkqbmJDh(*xwr$H2tyb6HXe0$GR@qK=nvy|ZiOFSy6fzph zQYo#$Tf$-hiA1%9gy6ERQ<9S2%Y1SU!zhyi)iug^FL7pcBAVDRPl}>iu&@Gx^D>qe6CO)t z1jYE(xR)5-B%*=y;GP*w7Cz6thk0m$oaQlFgDB1}4*Y!F;6&6wFwZlaZZ_%Lm4Aqc zG5j+?WOz2{Euo~-KtN*deXjfh@<1RFV}m844x?!wF;X&UifRxd0fPYnVPHfEI4Dzy z23+?NLqY?l2uabDoWL4@*mO1GE~N?zNgyr`T%9h17SaXhLY_LLyYLecDXxLgsFxVO zRt8g1H;7^v3ZF_Wzau2A1=UpbAAiYINt1{sExf2alz;%SHyVp-Ax-Zs2XZE*ma6Uy zAUXr~^MNp^R#MYq)Ju$R9tk*BvM0RX6HToVQdZ0BNiQ+Jl-g3%)o2RV8H-0k06~qB zZx8*Xt};W#z6K%eJEEznMuM8`{pbKOe)C#WwXY!x))}6GkqD!alB>5M9Dm9PTOc~a zl0D%&LST!id4KG&ZSqP}k!pZ}Rve6{l~|_))o+hJ=3HnAH9EuU5{yT}WCGUl=J*3= zW~ta4&B`Xj?+I!IH6KoR{M>CQ7zsfc1>=DbR!Iycj%J7r6`fHFyd_{T#u8E6(@J!^ z(HXMcwp#%}M>N!aJ6@tYlz(I-L`bCDP<8|$B7@^NDI+-8)FU;q+m>`S@}el-Js+QL zNGe29RA?PzzPf(*>F)N+?Teo?R6<17w%lL;bNi*s%OMb_86U8vN`a!=ws?Q{WuM#I zUni#-liyyv%e1ASm~GqMeZGAppvG}y{QS?CpMrB)hPAOaw4Xi$aesOZnE&IiU+$cS z;LL>(wmafKHJ%?L#{U*tM=j06P#Ay>ROU#bHv^#;--XaLCrOj7IAQbK#!zpBfh{yc z{Qv*MlVo*isra&9jq~uHv=>RTheB)J)VnQa_x}Zf_vOl>(F@kzXUT7Xp9cU1w%+2E z>1n<9#&Y>X7z5g9U4JZ+X@G!Iic%>=YQOgG^5?FrMh5ro=D6&~35Gk+o zE?k&%)3#k#*DFk_q?9Z&aAg3!m|X>NnY<#Lb86D?3Tz9CqJ9zAP#)=xIgydTxPN#Q zlWI_|=fI#yKo*EaER^Ai34z394J3-huR;5BD8tWpU_(L!5(0^_k-Js0P$CE(2?)#;*%%ev|>kXDL6}j00000 LNkvXXu0mjf{>7z9 diff --git a/TMessagesProj/src/main/assets/emoji/0_1196.png b/TMessagesProj/src/main/assets/emoji/0_1196.png index 3daaaa8a0e9bcc1a690f81f804a3ce5e247b2a90..d36d6fda2ce38e8a0e0a3f6d3e7a74f30cfa9e1a 100644 GIT binary patch delta 2177 zcmV-{2!8kE42=Y%NS6S z6**@`jLH^0Zx~C76E$BLM0^)Ob{9s1Op4EWjH=C;YuvDk+N_1vq8-qM?4IkJ>X-?x$6%!R3MN0@RlQzs0{jb<1H z0>y`2=fzm{IMjBK=;g*_M#%Dk+_t(2R6V&>YFDrvJ-mDNd) z+*g;}C}XT@mdluvl8DYZ(nWHwk)E+qkJC?+&pds>F>tq0Sa%~{rX5+L zK!e2_RGIc^3lIPR04Q`)PE!E=^tU{c{{9aiHCVQ){(s!;^@LpO&iUD>{9ZAlXLia+ z$KTU{=i-VPxvDq-00y{8L_t(|UYwNYZsRx*fGtF21tazk+enN60Rn9H71*g-+4zJNWe_~RWeb629Bgnwuzkg3JAns=b#&Nf^fCxk zMn-GW0^AJq=rDulK5ii|!%ed-h39#ue||tG%U`XI35&b0Nb^n8^nL%!{?k3*ZmrI^ z;km76o*k({?l0q0ZDLuC@wgNEmfOmEp)|Qe%6~8WI;yuU-}BqaxYG$6z6Y8VSD_@b zA@zOxa82p?gF!p#0HO5UNp`Li*Y!*ph7D=#Q5cplJt?RdXqg3)Qo^v)Nyadd`_A>) zlD;>ij1VSzplP?09T5BeVG0v5P+-h4W>lbFZvgaq2#J9_MBzza($s)CZ)R}LF+hlD z$bZ8WGbkc(oZ--UcBt6lgt6HHy)Zmq3NVOGl5B{R8$>&4&lzV7y|1u~_G^WlQNqW| zWp~uw3^Ri>g2{3@4;Y<=Zxptk21h}y_@Xcyh!K(`b4CPyu7Wa5=gFKaMZb6SCTj>T8t@ z0~Cw;XtSc2FcdcO)%0V|G1W8032AZy5}4XG*a#sauCMC-dQ6-YzN)X5{Y6YuMa@nH zRZe)5Rq`#JBHqMlCHl|{5uvNNKU(&?t0{*n92`INNB#adS~G$=GhQs%$JKz~CV#*D zyt}p)RS0edHKQuVGe+Zh*@v8IgdK3;=m}=sFq$$l7|*DFUUgIn^z^Lo!r2M@#hXs4 zBt{ye(`eJ}c4QQD2OK<#;8a6LDcW6hc?|C>K=TrIj!VK7B{tS5A=79r-8hC4R6mDN zJoksukPxaRh;apGa2Ri?2%I^PCVvQFcsQLp7z~PLIwOn_p=pd`36g zOQvoLIP#086jT`?M3r~m^Ann7mOKUl2mlU>Ax~qK$Aqdu1?clm@TR4LDF-fL zssd3bS1eFwpy;&lE|q~G7~te#k?zBxZ4Duup0*=8H#*=pl3t~%|g04OT+juX9k2`E`4dQwzQ_Z z{cByw&*kS2ZAu8prT_So^3V783olDso}(+e>NdAn&Gru^bXi`B7+x>$-$8t^o^yUC zz#Fl-&%kCpASDq4wvDL%Sw&L zM=WF>#0#ZV*R%>=&z>KDEDXaNYb%uumO7UKn`GOxq9=i|Z@cvtY(V-UHdUAAh2;Cb zy*E-s&T(HB-NR~^hkw2w>`<~;sH&M3a-Qcvzu+B=i6{;$!ky#8U`rkg?NimNaVm4o z2nJz=i;PXg+88&HTU(aQ;fQ{$B$aWwOhyJbA((Q%yp8Pxz{q9hL6E^YBK!(bfH>#mHzlzUx=bWv4rdHi?|)XdiB+9Tde)HWRiKOP za+%MAaJF`m14iTkuGV5BG{x9em23o+VY7j?_8=Zs4nl;rR~RVb^{Cp4j9lhyGjbhz zj*~21b-Ry|E=U3$HVbuKS8XTetrB91&`bN=f#6v(aHBHxb(+HJ<00II9RbVGo7f<7XCBA_-f zfHds}FLlwlf7(zQ0pWN&2DAT`vp3<0h@;x%e5&yu6OO_j*0Q>X00000NkvXXu0mjf DVmBIZ delta 1620 zcmV-a2CMmv5#$VzBYyy{P)t-sM{rDKWNbcUmP=W{N;MG(SdMv4d#jwUO}0rSr_H z^v|v7yqNdXvhBj3->irE*|^xCdn_j=``*4mIyp>4LN_rn9)BAf3=0d;lWlBQO1F}B zqkUz6V^AkNQ8iY8J#w`xL|w*%T|jTDK4p$NY`Z;Znn8EECPig9qw?VZ000?uQchC< zZrs`-J^R@H4lsP{kyp2m>z~8?yY9}Fh~<1`000F{Nkl&KGrp&cZwCG0)qkho8TXR-JH7jx z!T%|v``08%{DUOPYwxCid4q8r@7FdDQsUQ3kwGuUHNOOr-rxdYcyj>6^o+MNp`YUP z=7J6hRsNCGJuqqK>>zuwf4FL&uz7~@;M^S2EX5M(aeuSZ zry6`LQ8Heq2R*`GYlo|GLS4hU#@$dRN>#KEEvjZZTjX`rMhx#`B4Puknvzl~B@-m1 zF!+s@H-GigP8-q36UCHVO9>{Zr&DcJndd18nP9s(Da#Orto;%l`HrYLPib1Q~||Iu}Kz=+lam&(y@CC*9)$g)<_6!gap2V1Su!fGi@bCL}VojNHAP147Y*_ zkb-L_uo`0?e&k$>tm2F-WreU>g0zZpkcw*&S${=JOf60mDR8cs=T%@80KRaIgur(^ zErj58ev;@RF=b5GDV|=!tu{tkg#<30;5!;?n2=876pVf&w*ahR1zD8*HzrBsm$0H??~ z5`Plts5LMTiBT)j39~5@Sesi5z@msVYn7mA1I$4t%zIa@c}R04giwO1NEjJKk&U(l zHwGba#N@6`7-`=T7{+YGw2d%3gE4X>gE03V+KDL)r&XCO79ijGwMB?$pJ%Wb>(5WJ!rP>)gLIaj73iEu`o`<3+Ky%>?pc?ymQhzaE z+Tcg-P7uRC&o~Umw+qy^#f|`A(iG2UZVyH{49#gPOoO)ekkF_@usV0M)PD>>?`jx< z#%`XR%Rp-^arVydPhhA95!!%qhPAE*7$yT8#JSuRt_E*@twh7_<|(Cy;BjKZ6h*tcN`6K%{dZ z47zIv93boY*NpyCE&U|T!nxbu=RQ~&k*DE-u=pqMnDu;4CxBUQsN_+NW1~;PPh%fC zhhu^aA~rV-@#Lm>u$qJ)L}R@FQ{&dnbnrdM&*s%3?|bC~iPjoVL``%^Xn;?8Pze(D z*%OBb3fmgPmmTqmf^*(U*dy!B*Y7nDb`$NtT%Sw#meTEZue;aRi~ZX!FN42F&uL2T S_z#N!0000W=TR6IcFM6 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1198.png b/TMessagesProj/src/main/assets/emoji/0_1198.png index a65f34a5ac4d91f3058f6235e28ff8b07f53afb7..c13e8ab53907f39c045b78df756e7a98d43b16b3 100644 GIT binary patch delta 2035 zcmVMLel-LPRDQB^wx} zdR)r5sheXvQ$RO(X<~6*Q(#R)PdqbcQ%d#q@{?U8-`2{(qil(0P-sXxppu6N0s|>( zwN;hXNs!!KiGROVmfcd2(!Do1sLWRd1R-KK` zsgD2v03mczPE!E%(PAN6IS>B+Ke@W7^mOg{nS?Kj=b~ZK$K~kXzvIkFtr6e=00wSJ zL_t(|UYykDZsJN52k;d#FqW{eqJR*Jk~f%I+zY*zB!Am)d;hn%XJ)c&qMNL<_m7P5 zhx233v=6^Zx9iz-Km5OV?S9Y-(=-iRy+OP4+f26|gv;6VM`p{gH|YG9(CMY7es&2k z%W&YmU+9N3SANOTeueFK3v&RLKQlLQ7Ra$-)PqD2U%Qp}hqG zLTiEYCk3h?g^771Nz-Jsd_rl2HO88YD9>%RV}J5IFDM~N!`A4w5<-apf-xo;14jsC zBOsIj(QhUQ^nrnpwTrB!1dU;gQPD&|41us_wNhDT0A-Xc%Tx^pCq*;Sqh=6{iHOh$ z>Yak}JQC0rj*3_3;(FA5P81PlIzF24%+#w)*tZxu5k>K0MY`9PxK-oPg$PI?fFP03 zT7TEd1QZQDM7hSA)0lccfzfbmiS`XvW6*5+hQLfpRhH6JE9Ycoy=Fi}$GgjzN8_3Y z&bpOM4zC>2Aq9s_MIDG0m)<$X^pGRc7I!K zs;5=mZmKOjN@GECF_a7dhJ*jyHJn*H!x6_=v$BL`R4!7&n>43a1im?O=YwfNxG>;DD}lPm+G zHU#G|3?>*@H3)dWmrfAD8&@xKhJRF3ZEp(&tqYOoK$uQ;)6akGu@&CDg9F4hW^(uG z^m)3gA=q4eIWoZRuZQ#F-=DzHT%b4aPp^f9#=Fz$%g4u$57Sy@k_(|#rt0a#{r%Uk z=Rg1XE;vFkmA^E;oKEM*^ZD`qVHV{k5z_w_RyRFv+dvqAyYRLy?81Oy6n}gVxa}?l*@66EBx9gP-!$5~%{{Bcnj%UQUGeJ%6QAbHie~X{KcJ zJZmWn!4LQLnSsDd$U8nU0nPACZi2`L_KTM!H`_Zgwy*^#nK_haVrk|b=`$jD&CbvD zg`NsQbk0q~xns=SHiN5qk-Pyz=W~6a&pRXto-%4s0%LJ$29cS`d4x`Eo!IaZ|4am{ zTxloJSejXiAi-DlX@7z*387eo=*D(lFtIfA1EDz2`brMD2m@4kHCQ(p#>Cu=d^ce2 z5>`@Q2y6_5h2UW_g0*OrW&nRDU?sJ!uFpXHUtn$9vWU(62vUepo9AYyM>3R}1%(20 z>Zc&XLe%EDvRW>KfH|a+LAcOOZ7U$iJP}$#0#TdifooC(segI!vk*gYuJb@4;@^Vw za7K5mO%v}Bog+*t3K)ZO&H)l!gl2>(s{w=}v8@qZBMF%!6oDn@T|mP*gGN*k1Q028 zl~`}_2#pbvK|v%BLMi8c0&<>6$D5paHN|mqmfPU52@qnMJhox24e)SEVh#dN@tLd5 zVgpC`DJcU&%WOEn@O!AVS5KvGh41P`Mv|`d RD2)IB002ovPDHLkV1j1K!bboA delta 1540 zcmV+f2K)Jd5S0v&BYyyyP)t-sM{rDZN;82}H$Xc;d{8w%VvTo9FF$X#hiY1JTw8un zGl^L`HB)p#V}?*8FegP~Dn3$bQ%)>^OXC0l026dlPE!DnPyT7=wAd3e z0m{?;^uzIVsDC*fhyLmN>5qr*9MUD>+#OEC_kiJWP8vT)=W}=3-=#mDGa_26t^SBb zwBfuL8D5e_t@FnvX%7KIw`-hJ1#-%Aw@dDiWS!RIjt&WJPG1sIXi4>s4~@P{wgI7L z4XfN=63@e|TL#D5Dhn|Yp1JZ&yz&cThNGhh3M zv_=z!Xffxl8ZT*$^D>T$GjWwJ*ChcEBi@Xy6+NaPWfw8VWpT4fOiAh_V!eJcOn0C7 zouc$~(Th@%ScwMkgZ1{N?}EW zK`BPmP{eD&^$`(gnWG7XR6)-2q@uAfRF#Qw520BIrMOIh87IY@tt!BiQWY^f2o!Mu<|{T4I@0$U-nz zLf3DACGFg6f0sDk2v*8!niP{#s?<=jR0>vN>7F(S7m?ZvW#YP{a$Sj%a~p@O5W_v8 zhktc3SAx_;peD(+29wyrvJm+D9x-58yd^HGFcc;EQbR(SNG}WACvqOWWzbLxKqDkq zg5@d{f%E9@6a9-Goh3@f#2C3%xDic(Oq53hhx@-5*1NiQq(h8YfzOK}HvkKf@IGMKd%o1fMnzwBa0lKrYQd`r3kpwZs^O z=r_)h)kjOM2K}8xeHdVgtnuNnb($GxbS0D+mi|X*qU?PfHc!OPXSmd0v|kB9EkW{! zY<1$P8-}xaFLQFrGs9je@)T*it)I+_cSpR(wttF!e;)Op zg3)mv?3d$nX#Kdg3S+3CtUh0WLOL^(sScLB7e}3hvJcEWFOld(!UBYW_i+5M;)Q2< zeJctUATN&i*hJfiyyrMbi8hwtv#i$GO=Ptw<{TL{wg$)f8lP}jGO=X8fG@_BC$u#H z*{c{-$s;PHlrkBEKLRfTJAGQ(8cQri?vAU2p(8;dkfHccW6p3;JZ7=S79{S2Zxxd$ zx*C9#u4Cky5BHP$7MT?U#p1gf1q;O}s|>hLMu9?Vh(l_~CLlk4koIkhjcSc)4*e)p qHmcq5AI_-CpoV3T%PHravicY7HAks~u_|l;0000{0Ha0XX zCqOMDFefBBZ?Qr#DQ!_O#-=?oY_k|hf;ufIcwaj&Y_lL)o}+{~Xi_|JS~wLvZbv&c zONGoRA0Cf%K}#+fPLt0xbGj5aV;4kxNR7)-j?p0~JWDn(PJcQw77hzJC?QBQD=i=y zRzWu&8X7<@CsI8$1_cEwCMR1)I+~1u#l5(2URQ8bGDJN+HZd_xMMhUnPT<(ffp1~? z`1G}>oK%w4znDQ;DFRiN)GlnbDQ2)BTcb={bXJz#)y0xah|5Wk+(3cEj9&pdd%q=N zsun$O995i9Y=4s&N{B>;$Qe+Q8DZ%B0000WbW%=J0F?Cc{z$I=4TGq5C-71nysT;#Np_MyU<8vl@1eD57*WP@oCS}&Qj zCNbfme~5A1$tMArys6D6`AfP7^e~*}J}2RAB4B9cgKRI+9glPGc}{JAL`+DY>=W9< z7JZ#3#D4^($vY$OwD(P79Qx%vAfynpZ6_jmx`*ht0-;nuVk^ydhF$_dtV#9|$;1$0 zrBH@%df}!Cr}#kh4fatW= z1x1Gh4goATd~X*C5sCz=W~|UfR9JX+AVJZ94}T#nptFi7N97G7l~Dqn1i^RC;^d_L zj!+WN_z=a4CfYZ#PD;by?MVA1PLN%0k#5cf5lUGJpo>iqQ3_=pNacC51&+_pW7Pmg zm!vgG4Hp2;$%56cc#UQ?lMX=&?$g&ZeXeakT0@Qc^eiG-P6Ps$3s;v;ZveeGb&Jvh zN`K)^7J-wC0--pGLj=qg4XUVdRfmp zjYvp4WjPUIG3Qe8>v;)5kmZUa=c8pUkh;+6QFg&JpvFPBy}fTqM9nVG3hR{=)m(AU zzt2nA5Y>u%e|@!FSx{aLj%f%EwU+(2*MCn&M#$-DAna;cUSEH|TD}m=5q)}EmR2e+ z1{Z~T~Dn=utt&KoObxjkGEG(A`zMl5szuyQpV!8#)B)AB!L3*c*oVO&+Es(fBS0!(uyyeLF^ib5)x*& zcX#W@^|uF_rM5y@O%r{1{<^-oxqtcfkKct=iU#pB!`mi`W4bP9>!dG>-QE8u3$CQYH7lbRZ@)fFCRxX%(j|d#mvM+*x(vnuG1=K{E5Pf* z50Cc|>s2UPx!heD!ZJ4iV&P%6S>GdUo_l@*gIQuUBg}gZK;oeY^Su2Wvb~^)5E3!k zKp??NN{JHzlg-bYPYFT@Fn>m~5Bxj7=7z7e-iq;+1g?Bl>p+f(3vO z_GvcDlM$r4g7|G9&4^}pV4$AuoCycSQFNI}7Eb|T7*@#5h+*hA8(JfCHddKj9J6DP z24f5}_FEy=y5;opSU&-QI{{}9#D_7=SnoMk#w_A-nGFcEm?6g$7=IL|H3NYmoFjys z?qtI<-Ax^d@>U-$%m_L6m<6KlW~P}90giZe9j+w72rbNwaTcg`rjjjE)_tLE4bsPS zB1R2!o2n30$#fxv0N_jrnng?@fH8y_jR0X#$$GL7Yjf8K83auP5+B0k2B`=&HP6k` zWgA=WEeLe0WJC|-l0V5Bip)DmMg#?Bx-zO7Rz zoKu-a6M^KlF2tZ}ykyRyugM^2pZ56{0=6qbN~sj>oZ)K3(`+$6g?LE#QH5b9jNj?F6uatp^O^tv002ovPDHLkV1jn=V!!|Z delta 1341 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_120.png b/TMessagesProj/src/main/assets/emoji/0_120.png index b844743547235e8f834e98799ee1b9682ea60d0d..2ab289436029b2551ef3012b1de8f3cc7ab80c92 100644 GIT binary patch delta 1154 zcmV-|1bzF+2bT$uB!6R2OjJcja7@sH3*ed*#B~q9ZVI$v1=NWZ^0Xr0mJr8!4db2} z)rk(ma0SJ73FDp_){PVLwk`9xGVH7%(trfUb_wmUC;!bs|IbSQ$vOYjTKvN?_q;3Z zs~!8rKIWkm|ItzZ*JbWtf7Ac~02XvoPE!EMY#1#HL;n3)qkrmpzlhuG{M7uTw{)8U z`~Uz0%}GQ-RCr$PlxdIiC=i5wU<{7$8FzEq`TxIi3rIA_zN4Mp{hE?21=BoKms_d+ ztzLTRrI+L&|7W>eX`Q>@0=gOHpBXKl*)aLxmyB-k#AeP%3voYWrO!yF|Hcq9m$XuR zBlL#isVjNx*?+l?OsnpuV2u01XooGX8U<_IhV~1=855>Xuf$OU(ZCe-O*;h##{5Az z%*Ao2sv+`ajt|D%XoxF$E&`WOQ}p=$96D7LT8G_ar!?Fo`*J<8Qd4Fn_QlHw*YMg;5Z`e^0dc-WNn6 z7v4RYEn zBae(Q&Y#(*JiRkOt=|c?{75Gi{B&ZG7D=2!GIZzh5N`L{V0mVec1jH{EQ+jBXx7 z+l|WQ52BaN0+DNhuqJ=iIe24%$Ydbww&)=rP-9mJWk4feW*C(%r9>78@(2ro`?8{f zwrU*A#W9a&kvNVz0y$lHn3Y+ms6GpY@{U}QaAoKl`o7g?odQ)9C`9Ncpn zT6t&8Hjhh>MlFgG=8;9vO?YI%Wyd0}ei`S@80VFKhKbDC?BfzGY(QMfT^~-Z&j1^b zcMwYAGVVCw!$+X9K0U%-*T@!11cFd=Dt{@}i5m#YT|gYym5lLcEeoJb7cwKJ6jkz3 zX59DZc@yGxp1m*A4G%eTlp<-&)o1A?AQ1G7R`FOiiJ;U}Rg+SQVc3>EWP}*PqN{Hb z$%x^55fC0hs5cGzn?f8Oh{q=Iupp|xYfPzL1#ywfg!0Fi8IGQNDMyU8Z|E!l@dg-OV0Ns#v UxVjM-#sB~S07*qoM6N<$f*?IIi2wiq delta 946 zcmV;j15Nyw3CIVKB!5CsOjJcja7@OCUcY}<)S`L3dQ!W0O3#{b&zNt*gj&FXSHgr@ z$&O{(tc1{=bk?SQz=2oey_nsyi{QAC*Q9&ftc2ynpf#|qr2qf`5Oh*bQvmdPt}7B} z{lry0-tUgnquR~-kpKV#B}qgas+GD1C{+w{a9=9bUdxeNk^D}@snW!i^I*Hd2w@^zd z?Ux)eXjwFtcS3`?hAkdff2svB+s%W)Zw!4j&K8Eu`7Phs7zB?35!;R^RI)X`@>>pb zV80yOb`%(n#ea|tT)nXwhK|sQC6+K`RWGM%)YJAJsjYpn2|-p)y~nV(J_kJ*c3OQQ z=422jF;np~hONB|-MeW!9x)jVe`hdHhVe3+Tk1E;6R`-O@{16yma~L@qpT$l1`w^P z5xoI12wb8<3XL9E7{NC} z5qB6J8ga4b1cF=~?*la-gutU4D%W<5=j$83=edGsF!;I?R<0uj@Wko97zFm=dLGbk zJ+d6Q(s_89wJ+}j6_#67 zmB*(t5iNyNEbLHy31?9(hjKJSOaz97fqx-b806GZU;}A=BM%!r!V=|1tB*O1If^xm zr)B&r%}0A2V-yz=AMvhI1%`%kBAnK4AZCe%tAErx9zb8FBLsd~HK#T;5jBLm5YQkr zr|dXq=KITq@~Kj#<(#vq*48(8WmYr8%c+IYzDm0qbNoJtT*V?RMs2<1)>VEN zB)JO79Ly@1J`c#H72#WH<@bG0KD-x#Pb=8=N^d`ri6Q*PsY8fn`+I%#(MKQs2X=2( U#w|duVgLXD07*qoM6N<$g6*NZP5=M^ diff --git a/TMessagesProj/src/main/assets/emoji/0_1200.png b/TMessagesProj/src/main/assets/emoji/0_1200.png index 382e18b05654e44bd01a5a6743c023dd1594cff6..9dde1f708e95a688b17e16ffb94d65cbf37f9e4d 100644 GIT binary patch delta 2305 zcmV+c3I6u935*huBYy!hP)t-sM{rDSGEH|nVxUs8mRX1Ex;Io8Vfe;As7$__XNY1W zZk=u*{m(*H7GzZ!VOSqmo=d8qc2!^>ZR*K}{?0w3NVlC!ug0ES_|j{-h&rG}v-`?A zfRhA5g*AAdUk_S2g_u>I((Wg%OOET1g^JdIH{b2c{l%vJx?EPpynzMzEY*Ro$b zB>&q|0|5h~MYb##2N4SfoNZ1n0000fbW%=J05@1ZApWoX{tk})Hs{ZClKuPno8oQy zzWd5({>Zej=KbCI{`&H~@`Dege*gdnU`a$lRCr#U)_;dm8`%;DU?da}A_gzUfY;!( zXL3%;IR|o%_I>|XxZQn5!xVUZ@9tkk6;eqbfA<_|nEOp~simdek6XJ-bN@2%?rc#~ zip64jYd7_8fURt;CNpMxOw;62c55m3&jE;3DmkX%F@+UtwU7T`o>XRKr-mtN!G1E4 z*jHU94}SpJ`u~tzYChBLcGt7D;z03M$xQCsF4Mr+Ud*iiPvMUb?-ow0U`$F%kWYke zVjovhT0aJSG4=bUtSwNcYFGcU06hO2Yrhmy zAEvWZDwXe{ki*a~ndT|942v%Oa+E(SmGJ!+N1bL8%%$C}_Z0e^|N>? ztE>=F;lg2V>HTK!tkpU>Icc@ddiCtbrA4vYJgQW%2aWP}5g=5!&}>)NcE91fDO>^M z(0}hYFOVQ({_PkPF7(&Gu`~j4rB@#w_|+E!MtL(v)Ir?q^=!A-g2W6cvb`ZzJE8G< zl+>q}4ps4B^Q331>0a*)f>30v3u3#21ofDY6Kf%WLf^kX0m5*zH#hZq4C13lQ3U5lgh{j%nI~R00JU za;Q#k4@Nnf8MM);#03ek2yyQL&cThVnx+~^5-7l+!`o~_jpotCl&^FxDnSis5m*8a z(oM-#ZNmaX21Sc8Hj?n)(RIJt#!HI}p^K6{f^?cB`2GajmY8igOp%qqQ!Ud;r-!6aO2hMpAc6t2 zKEIFu!sAZ^mnLj$hlCs=6edlLcx2!e1h zM1iSBFic||O;Z>l&;&xrPNQ7#(dgg?V3Oov8yocdC=@2}w3k3MK&qk*au@n#R9I z^$_92O9cO`X^m9JH6JGTljp}xIV9M_WPS2Hc`zN%Fb!yd1Xm&g*fJ8=(86Z+cI)TQ zpZ_si^#R{S{Q)1Vt$Wo`P2*TE)9b+jA~Co483ha{%#p3Iv)1VO`G03{b`lb;2Yk$0 zEyuA<6A20$%c;5KG6;=EgA?aOXiwvNQw_4?aS@F{Z9LwF$Mtbt0m5n&^cP|!H)HNWiN4-G38+dJn4Bl=FAyEbbmtinvFet*e zT)l=u4UHN;gwu`(?0;B@6RUXF=R|`DoWybzsW_k%IROTb#2j-}7WAlip^yY3`FTc^ z3%rI0lN4vE)$7skn#?>Z!3o-C0*KTyq7iYRnlOnLy{q_C(>RE81gaI4;M<(TWH`~_ zgm|Y~t`gNyn5-y3&@eJ{O(;=_&9O+t>WhkmcxA+DXn`9@QGW?$KML_VbXWx@@i`*s zYv8~(y|BjZ?d?Dt+}@HoD_sKv3iRBy-xlBapNc8V)(~%`Gq@nD1f$PYn0pEmu zC;EPj;B(9_YneZXME^=P6dC^da0DL>`WZqSnR$2ph@cXmlOd5<*2$nrfIvf4B&~QW z8w6MmeTRB?RevOWI!LqA9VQba{62n@UKy&Q;T9Cn_84wNLxBi^h-eO;WbCW}L58U^ z4Ui(P5&(^<=j|C0&5?+RT=Y>R0$=K1<3AX(1d1jpjCtmH`!!L>AP_Aywu~yjvt3)J zVY^NcIBs4wt#gpuAyI}zha$F6Kq3MVQRp5UD#b7!kAKTBA3ZJlg8uSV5le<2TG}TN z%_bQ7<)i07Tvt8r;(YwpEpQ^f%;bV{#nx_;#CN2asm>~@%EbFy_wceH7>#cfI>vzD&lj*Pgk6XBjCLv bV(03=ZW9M`zt_Rr00000NkvXXu0mjfOfV^P delta 1185 zcmV;S1YY}$60`}BBYyy0P)t-sM{rCrC?q#CG$a}nH7qMXV~sH@DL-zuO-)fkKuJMl ziBn&IJ4s|oH7++OAtD+UDkLI7FDW-NG8PXFP&+hOL^(q|JU?!#D?d^=TZ24sw4RlgYQvi?L-(umo*%dXYchdhorhn`J00a3+L_t(|UX_-M za-u*KL>GfBXzraCFEz>kf97^`r-Cd2OzRL$Ij2tFp)CJwr*6u!V9K(o|NK66SyZRk zTVh`oW%Elwaq7R8=}%Qz|H6QPb>it&NK<9NI~WRtFAWeM)|1;Q3%2FXjFy``#r$e%5e|_ouz1 zt@`L)VjxTx^O0Z_gY0TFJ#~`>pN(xB86m^ZjLm7(=n)~B=wXz$6?hneF$S7!B8uJv z;Z$9ww4Jbww7H4FT`afHBNE{y1l8&Dp=${XZ6I@QxPOf}#YsX$T09}6T^C@Ew_sa9 zK1Ku(kWPa5t^-MdfR|zcc!01T6GFN+wAywpbOI2-(v6HG1baZC6KZI{3jqQ+2!SHU zh}=UYU^nEkF%TiSp7?!4#Udc6%O|QFhD->@+k~higlCVCl0r9hU`f{*!V^lF?Qt>% zEI582pnuOM0uEoIfre?KDjtaD2+?+U231VZE2oIPHW6G!Q+lg65se`j&Qf52)e#9b z{YLD3>6G6Vf`vMkc8Ypl4AE>#v_54EfdLm|8Y0su0uiCuL?|T9g16F~)dW0j^&uaLu9_IaCBJibHgC>3B06fwiXb*9hr4q#Cm>XE6J4GOsToo2{V*WHG(>c% zVTeFPv-|s|;xN`4xrcI^)xl4UhD{{zkma!kucEty$hX&16W`7ZYPk>;gE&gTCZ-X* zE`Mgh9?r4Gag*<9xbVyf8jgD~7^qT%Q72CbQ4F&%z_CVVz+2{Vikif6ip&ra5*V|^ zJc+|Y@n8@Vf=~XbiK|}y`8zR!kfJGx6=9^Tf6ow?loDV4h&)aW5U(U}VIOGCcYm3}u$soWqYV@%EpImDQ zPdHnwHEukW=JNL_=lA#Xl)nSseHzaHXD-b@7qG-Hsgepq00000NkvXXu0mjfr#lx< diff --git a/TMessagesProj/src/main/assets/emoji/0_1201.png b/TMessagesProj/src/main/assets/emoji/0_1201.png index 4d96d4539bf825900a1019e84c81955d8414db11..cdbb0f680678e76eb843f920812869b04a39d23a 100644 GIT binary patch delta 2264 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1202.png b/TMessagesProj/src/main/assets/emoji/0_1202.png index 155f3963a735ffb9b35236c80471f1a9ee555065..cc2a256f372879440275b9d3303e1c05fd6394a1 100644 GIT binary patch delta 2196 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≫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 A5C8xG diff --git a/TMessagesProj/src/main/assets/emoji/0_1204.png b/TMessagesProj/src/main/assets/emoji/0_1204.png index 3c1eb3b714f53e2ba05720ddc2dc988670b5a92a..01c44a9d426892c5f9e7b33351881fa6273d3a82 100644 GIT binary patch delta 2041 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 Ef+d>Je5bNRV!9vBW_g~VM<6!fJTaRKX;o$ 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1206.png b/TMessagesProj/src/main/assets/emoji/0_1206.png index dc1fa3ed4838d4b2f726978e7e678221a78b0ff3..b6bd328ba4275d2b57a6518cacc565364b949a9e 100644 GIT binary patch delta 2630 zcmV-M3c2-^56={kB!72MOjJcja7@9CD1(E8gou%PdU<<%e1n68zp$Ueys@aLsCjyP ziiw58!^7yT9hjM&fOT$#g@%WQgs-o#b98i)cT4raFwTz*tE;P>b1lWi#g>I(l2;9g zP7m_37|P1Z^u8>uZ3p40CHcoUu!T63l$8C8s3_QXWR ziyGmi7nxoX$H&LNzrV7wvdqlPo12^Q!BNP_$k3M?rI~$nT0nPqcYJ(&d3t*6u^s5E z8gz7Y;iVbdo)^uK6}^BG)R`Hxc@e~j6rp1aVq;~er>B{jnfJUP|IIM|$tsnBs?aKS%pzymm`Pzic%*>~79sA|0$H&LE zwzliqs4*Q4PBj-&F${{C6~;ZG@gR^s}m{O7rO!QQj}<-ysj!0gw)-@f9lyZHWo zERl8q00>P3q zMr3_&_kV~;#QXDn-wa7SKM6B8KR>auGBL<_{#BU4iIvyYqL@e|U$0Ee{TpCuV`D>* zWy?_Fd13AK()>TH0)S*~t!m!28?vY*H#S!O2@(#xra~gFzJLDY$@``z3zY7 zI51+{Gur?vqVb%ze==*CN*>1R@JQr;3XflW{C~K$DcMpzDXI%kTsJan88Ei@Y}@}h z$o#az)AN&)lh2=bS$oxN%ytCyXj+=QxN1wO^OKJ+o(6x?VRvhbB3qLEX|}iXbIUrl z?cCPq&*a-L{?-_Hw0p7Z7-ic=hhAgWwlgOLI5|K0{5$h^!o>w4(B%9i7jQ;q7Q;<6Z3P7XC$>nf|?-yGw={GT1Idj zpLcemLxW4d9UrbE2kYx+$F(;TbE7-u3;4UVwjL?0Z|1b(OTHXObXV@&{#(f&e>H5V$>4`*ODa zL-ud>W@6E)oiYgI`%$oL=vX8+S>k4HTbfckM9z@IZjNtS&vGdksDYgS&h*|?M1Meq zXf##GvU|66O{>?Azt4WH24XxD+ng$2ICse7o)Qoc2%E7SKi<0eqBhO?ms&Sp+|<3( zTnUCd$}hog3G5jF6-wFFXRVuU{jO~;Zg);@Z*LzRkx%uOHl8bB7L0-xyH9&dOu0gi zB_)pZ=3U#+i#SJ4uOY>?BV-XZGJmmDl&oWSck7pd&L*ZDfCwB))VGUDLu=nzrXtYO zl)#rq#YNp1&tjC0;no<9;yi#95%_U$>u9YgYO-#%+m@!w0)%35O;n1=qOMKzIbz`M zK%8v^9}ysxip5HqEWdi{tsfNyRg;T?ZZw-s%P@6CEUpQv3_?)M)75Oo>3=~&FUrs+ zgcw2ue%jC%i$dPC6jEN)wT4B~P(@7>fyk;c&i`eUKQLsDO$dcTp_IvStaPgB#iC)z zaHH;K+v6 z)&x;jXU8}WJqj?&J5fv${C_nTBMox7EHAMm3#u$O)VPZNO*4^9CW(+#EVNL~W>XPl z^?e`D!pOkD6T>KoD&J4MUA5(ZX3pdm-4z@twgjN1ulzfZK$13DkINS!9xGB}tULC_+FW zwHd5b5q5NYF=!v^xo&NkYur zOHs(j^M82}!B>vp=?~#N5S9w8J4ff5ATB|kM*_?sF%SU)`NI)78eVb<9&@-EV$;qj zX_vrFI`@Z65COjch%YBS5g*HCy95z%Uv4gn)pT z`5Z6VU-#-X;}AfX(9R`LmoBq6&O%WSL;){!uCcn;YVEC30dS#2TlD^fA-&g?gr~%& z^M9r(ZGWY)v4v7B<`S&C%z=AEFhm6`!+HNf-Z5lw2_@T>vKXO|+Dvtb?wxrr0ZQPi z<|q-3;z-F!0h6H@P)ax#4o{l*GX$E%dG|pLAWi@{4+|i8x{0i>AHe-d++}nLAZ|L3 z9D^~5=2PttcQ^bgs90Dc${SOfRp)sG&hu_1? o%gc`*%<}T^u#d*y7wiK61r}Gci2bxIKmY&$07*qoM6N<$f;DO&5dZ)H delta 1925 zcmV;02YUF=6qFB;B!37{OjJcja7J2*ISWP2mO5-fSBNp2 zJTECrL_w7}t65P?cQ=DpM>IPlDqGbp{bpsLA81*j8_(C1_cFB5`SM&JTw~;4n;95J}V|Q zB^_)deM>elDjgImBqmi;R2>%_F$g?mA9hC%R!vDsjx?gHNWKmX4L}S{l{%<%CWM+j ztye-go_vQvh4BfDS52{sk9t)XrU- zKw-MLef^c&s{M;g`1E%lor3s(gny!Viu-$jXOd(Zlg-nA_x$`x zwK%|Y=`(tEm(gUU&g`fi1h>)oTVLOhcH7LhM{zFT|>15#w9zcUPd^5pq` zzv>l>Q%p!rJ#zn9xa{=ab2Ya=noO#m=M}w3^0IpqO!0nNbsL&H>Gwy#OsWtMQf2ln zLBazku79RA-0G+g8DS=v6MjE|_KMXB5Dpk#wZEQGa=#YY>ICZhn&UVPzv@lajmgea zp&06S1NiVKqyBs{(Hs*3MPg(W89O(co{`iVK`f=(gdAM&1MCHPtA4wwmr{Mu#6;3+<*>dwL1kS z6o0xe@9N7`GaIt(j`H#Ile0XZG7Q}%;aa+O{4hM4EC{lrJMWA8?n_k-iN)K!_O={3 zjx5Wc$4aLz8FCJbx@6FcjJK`<1_^>}YVQl9t9>kW5cKz@Av+(-g@%Mra^Vir#_h=* zc72)W!l`bJ=y3)^q<#3FX1^}9hVkq534d_?<@M$5WBGcI%a9v*Pw3={twLY(Za@nMezy4d^}2jR+J0Xymy0*k1fn5d(gbs&!h|5W*dY#;PZ=;5NpYzL z7@BEL7mLLUY!ai}Fr=Xa0X2MvBj*6Cw&4~S5LTgY;q>#wC!rgLt;2Y6u(aVoKY!?v z=L*rwUw{hhN&Hlr%~K8t4JR>R*67DwbZ~6bkwfAXUS+t&x6I~sDLpn|5T}0mZh%7# z(SZICyzCJWu)a*@Bp^ibklG-|A(0_Y*;=i37aJxb0HA;bM$YCG5C-i-ZhwoY*T=04 zkrX?f78>nx85ZJT3&&ppEbIQ0kRsx%z-5GodR-6>i1SuYhz+YOH3J{=ye2fSsG~9n zqP0N~2V>YK5Y(9f>3te-c)=&YBG7DJ(Iq4XR%w%{V~b8A(-XcL@D2qb070RmBuZ8r z7k<5i7z?$7^G>hV`)Vka=6~;0DoUw@CB$-KH*r>Lb$XqSFcx~9l_4pLQmIrviHnQ& z0EnNtEuxNub=T=Y0bx8I_h6~95hEd?NK!c>=&f}|M6J_m)x^#?GU6UsL<$i$Bt#(E z7u;@Q06CRt6oQAwNpfpV1uS24Sy}%rggMM^x~h~ z-HD2HQ-|$hjdep&n$3VkqP=|}NVIzKAq>iu>mLsgXcZbjSP=m&V3HxOv%R%VA_1of zf+&iQ$^{=1V<6UQgu4iWCK94(UGN(Mm%FRsA%Y+&IRc4#eT!(aKvX0k+ER(wOisM3 zVduwT1%^Byqp?oFI)5u6!8U=ghDu_K;0_0Ok#IyHf$Ll+;u6Ql0Sl8z$`wy+CD9f^ zkSa%9cyIB=SgjKX6o4ok1-MZ~IU=^hU6;Apz37%$s~Zml1tS*SoQ-w05mvo=RW1VHQ={tOAc_k%C12-xov*aGKR5%j(UwL!of(ICOz1d%xt#=i*( zTCCQ&clgZtS^T$Vl_TP+aKxane>gsuIXFN6afm5hCvrSR{Fn1D3|-I%s@h1q00000 LNkvXXu0mjf>X~5W diff --git a/TMessagesProj/src/main/assets/emoji/0_1207.png b/TMessagesProj/src/main/assets/emoji/0_1207.png index 9de6243e1b1678d99527736a683cd25533462797..46cf47c2549bf2fc960cae2c6dc00413b152fc78 100644 GIT binary patch delta 2467 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 delta 2210 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1208.png b/TMessagesProj/src/main/assets/emoji/0_1208.png index 6b957fda1161224d9f13220617127bf16c3be6d0..7906f603e1daa2a9eca8767d508276f396997bc0 100644 GIT binary patch delta 2585 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 delta 2127 zcmV-V2(b5}6xQ&Tf8E{uVCprD}h#+Cc$$il+H#h-xu?9=n-)B5AX{`~g+=EHn^ zd{|gmj*gD@(XDZDaTO5{!otG++O6uqoJvSYlarIAq@-V8UznJf)6>(rxw*>9%BiWT zot>Ti>doxRsDCFUBly_1#>U3`$j0|Sw^Oib;`1ps(@ovKr=-_LF(4JhK7dC&CO(5SlQXx!;oo$ zZe3hbQBW=t*RF~G`|yQVCEMHE)rUU^0000!bW%=J0Du1eD*pZc{{9OdCOjGZK-z_L zz36UgD{`KpoohZLZe3+M{eG}zOFFg6lVXi<8<1! zVWg|yPt&n)17mEvOvv5Nc`O#wjq^^k8!vUrPj>5@(_}i~r1>czpp01cH_9o15Xvju zN~QB|vvZDsSh~|Jx5M#P|1^YbSZn#NQq1^{G-(uYxQO7U*9EqJst zzPHQ5{rB&3^DFfz>`N#6C5e-!O!`CzbyQ2M`tR*q?%YxqgkBX9zdgeJO*JMr-aP={ zepXSNk~C#pf_;rE#ZYu&$>VWWt9{{5{I}Lgwfid_{P>B^tEQ#-6Vv04e}CAK z;JkgkD(Y)XPFBx7G8CbWv>Hn%9|`IdH4QaPy?e6P)DD-FR*j8q$Xqf859$P@1Vqne z{3%>>34o=c*K;#R(_7SF-5RYp>=X#eQjAN20K~6^u@gdMF zX+*ryXeANFaXrCUPS@8?r?*HA6Mr)_?`KG3cP9HS4h%pzXEKJ`;N-q=I3T8Zv){(J zhKb{7fX$h8!nNoXdQLDPTwLzTAUHij!aJ=WvB>ikhFlmD>|cV{|GXAw^n&m+foOoi z#hZPCxa%h2y>BNnXUfEaM$ovKvAKqckHLC9D7sM%Y(T|HqTP_=aZdJhJb!Vhq}3z} zXNsasIH1T)Rt*H$nIXcY5f&h*&yh$Zn&X*fqb0|koYU!)Q8QH9e09}sxBD3)1A`zDU}F}sBR1-b z_(o%gXk z@%wq#=Ku&ktLs_9a=c;@Q>oNr9qa`StLSGK2EI`d72f?B`iK;*V}H*Qp^c4@m=Z~U_BcS1!|(jk}rm`!C)2!Vi*X)d8ory;c;5^MZjLfh6zz4BKc50U$o}4!8$Sq zy;wB_y`H3>$8#DHn13E6(7Bd8Y-Wwc^RTMO5Dfzm8V5r0^YjHGitO?TVY$?Z8XQ35 z8#r;xeU|5mj01fUs4dks|c5 z=NKj&aGPQX1X$}m$BIE1E2bI*3(f5kzlPkD1spsD1&ALY7QU6M&d>@8VJ~WI9S(b0Rx8S z;9WtV&NgylLb35VXle@^jeRo;e@RzB07A^xjdALu(6+)xZcQtS%@3=(fIXA(P3r}| zxBPI$L0EF*Qh!-(5ucfr~wxW1917c;%E{Yfl&vfLc$06e~Rf# z7=XcM1yoeTfPga=4h~-NpS1mb7)nSXLfh{g^npf!2raKB9$t4E9}p9-CaCwR@PL4I zMTEJ+XoTbSL^ynDRH33i-b`S-Mk6(Y@V}KX?S2er!$<=Ht`reqOdP;0UXQHrzW)*m z)oMkw-MHDjw>7=sz}^_jKEA#_<954emX}=)2ZjAt=U=@;C}60nW!C@z002ovPDHLk FV1i(UDbfG{ diff --git a/TMessagesProj/src/main/assets/emoji/0_1209.png b/TMessagesProj/src/main/assets/emoji/0_1209.png index cabb27264e6f4aaa96df1015aac829a293ec01c8..e63359fc546c3a9c6ca6dd6e04e08e48b9a754f8 100644 GIT binary patch delta 2357 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 B6m$Rp delta 996 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 TWTH}K00000NkvXXu0mjfhB_HU diff --git a/TMessagesProj/src/main/assets/emoji/0_1211.png b/TMessagesProj/src/main/assets/emoji/0_1211.png index 72616246497692269651d384984dadb239c3ed1d..2b90fba174392cc2dca4ead2e90a530f1850302f 100644 GIT binary patch delta 2056 zcmV+j2>17h5R?#*BYyzWP)t-sM{rDNW@UPMdQwhHD;^iOxVRu39FUNZm6esv&CG^| zhIn{*rlzJT9~($PK#`De_AY5kYl|`~E)%zV)ykK^xP4r!yub z0J53>qnQkcv*$=rb_67&u{3Xmngv|Qw{L%^XpdLOOR6Z_AW=uCyfy?GD@8FLXG86; zg_kQzS5b0t2cb6ZP)DdJ{_7R;zv1tR*~{yTG*V@C*DSe@c_>O30B82wIeff=VB^JB z%rm`zw|}dIzp7*S^;H_gbf36^K8Nb*^jyMGBh-;>DznM`hRbIoUJ z6MvA)t!NJ)2-Z{9U(E4juv^vHZ3mO-(^uH=rE#H^84DjE*6U?4zbjYg*_I<^38U)u zLM!H12%PnDQM5<-8L&gPr3wQ9K?9jxY=g60bbtMc82l=rmokgi(qQD5R%YwEhV`PG z?mVyjWj!(|^D$;4`vm$`3N$AEl zT7S+3jJ&LaFJ#`{bjA2IUWbh$@L{1y{Z$4+_dHL$<-qE^As|E<8^y9V9<^o>QZQmW z2l1v00Yt|te45d9CG9Sx0cKbife=6f6_Mv45*3Ef8;d0&N}mnv_0MTMFdzljDpd#| zf&d7j>lGs;fihw;XrqJSGPEyL0f4TNx_|CUE)ZUV<2%XF4i~jw&jvhEQ)8X)rkQ>a9u01+uALN#GxnZIUsuqP=-{{w2Z_+{Iv~hk zL=v`TbMQTgOk~04_}xQ(eqVR^5`T&Oj>4}2pEjqU>3X@EabM?8Gor+vOgX- zp7{C4@k&;4bxi0I-zKVh+q$tp0Aa;9TUwh5j%D4n?&wuQx%&R&#~K}@Ot4Ua{*;mntk>%b<{fgQ6~iPk+;=-ifez6qFkx z?7EX!@njhrHaIMB5uT^`*iX$-P_%Z`ApCgi(XkbB?-?g?SfFF8v|T2uE#Brn__j7X z@$YYSGLTFj;91Cms*mzE3HEs(d|N3s;m31xJc5BKU|o{27C^Wi_b~{!BJ5Ki@}5vm zoy2pkKT9L*tO<3eZ(mv^Qj$Kbm00R&WCwEP`e@w7*;PA0);ShERBq4I zFuF!;*~&IkGmgl2N@T-EYQky`vpG;nbc+H;q-+BUZpn59A>~Im6LOelQ{WxSVWL

    PQe(AqL74TRYf$0*&HYcpQ^w+$HGW` z-%=0@^Ch-P$bVs8>Ljvj0!D$}4J^lcLKll}mk65$>f>@JHL+fkQDp&u%_hNpTZvej5KdX0I*N mOS@k#=h;ZxRp#ai_&=nP51k&w1S$Xk002ovPDHLkU;%z-oBWyk#m|;41MIeV$CzxR`V}CXmmtZi7R4AWlK50E4 zr*T86azCwpRH>12Y+_B)yQjX6TgR)5^zGk!a%{)P$JW->n3RxdCU z!^6XIdLZxs0047zQchC<6Ff^^C<%3!+Wr5$=l}oz{eS=e|Nq+m|CcEK{{H{}{%rrP z|Nq+m+{U*5#Q);||NsB||Nl_`|8xKU%K!hYasU7S|NcP!g#VQP|NsB$o&O!@|Nr#= z|No5g|Ig$!!2kdM|55+{rvLxL#r5v#W#!u0MV6od00rwwL_t(|0qoE<0s}z^1<-Nf zPYA5t|9_@&>sG4RtI=;h$)9yTco&n|DCSZL08uMGZ8;$Ccz?r?=FD2D;NH&+kZ4$a zgT4+R64AUahSv3bYCi#yoT%!s<__Cf#{p+_Yd@Q!SuBHP90$3tzsoC*07-YGn>@4| zg@GsI#7iI+wDtPYqOQ;1~QDC%6VM)+4L} zr=Uz8gV#G0gsi000=d|RvCcVb+h8>LI%c4ZJ2I^6>3XAd(!JVwwyMLHORYOHG+uM# zwkWe48D|uC+4pPOyJ3von$mK=(d-o>YkzdzR8q=19EY!Q6t{JiUL3BUlU(k;QA+!b zLd5qSW!rsUh;9P>crsOGD((p=a;|w*fs`X6%uBi1KO{eY4G7~lyY0>a7fT=hyxm%B zO(n%d!11G{#;&?-Ty`xAwcBiWJ8LjjDTmusg*f-Y?QpjOU7nLS26tNH9HY+50)N0d zOg6Y?WALb;$ipcV%jx>uUr*!x{`2?hpLZ?F1y?9zz&OAILO>+Pl+&_g?D~JL^}VGi z7K8!(Zenvzwvnf3^c=Y(Q4uh8#5N3wV%FLB|6{)b>4ckis&o4B-J*)qnVoAWs-_$G zc5+(_%Ai>E|CmZ{$w|F4w<&B@C{vZ*Fd+8bj4?)n+b7 z9i^$x<$f(f5P$gL?!NhX{C7PSDU5uE@UE{tX-F9!MkBR<|6{3GrU)WFlz+?OuXp$N z&1Qc*z%NYP(P;Egdqqqi3E{0D_>N*}-{ZDW74Zt;j)cC^K+2ixguXq@5Z6Ss8Jh=- z1&onv^$R7jNF|mM0Ytwpu;FZEhrV;3h}uk8N|Ll%1fk<9+INLQsf1_Wk0cOa7~Et% z3gM432U&xtuG?(Biq=tV*ngvr%A52I{DB1edqdZGFCjwr9N|@wVzaJR*K0C-do)vI z!O#(bbGiP(c4YfO=w6;DhSS}eDmoc%2Q%Bp-y1p=*ED%=Zk-Us!+An#x1}hG z5F|Z|J5y9k)~GlNggV?heh`F{{8?gkIILhubeJg4;kdJoqN(lFtx_Xib72hORnXV)Lmtrx9}~N0LI9=^(yu*FSho3=S(? zG6)e{sSnyIK{3*HsImq^17Tyldn`*Va4YD7%HCvc?}<3Y=qMHu2Ddt{9gdVnh7jJ; zj+0Mha1bTs1aJ`R{D6TW=?DH&Bwa}*phk%heVpdZE?SHY85L`FLpZ5_1ed)1m z4Ysxop&JLBM;-(s(hv$d0pd*y8!KCub;-_@xpil^_2fr$y2T*q9DbN~f(YRa&cZc3 zyUvwh)=c4PN~+alO?(K{37OMDn9#zrXZ+Xy2T$L{51w^&3PD4m#RRVLVXO7m0vr5B z1T{0=cS}x*zjRqdkO1Q8vBUL$L~Kq3ZO9AagTG4%AgW0U5XqMEe@3w76Ol~jDaF@+ zpO`MM*2%8>PXy=V7JBjbk>hgnZby4cgQf1f^RbQ- diff --git a/TMessagesProj/src/main/assets/emoji/0_1212.png b/TMessagesProj/src/main/assets/emoji/0_1212.png index 7f3ed65fb70257049bfa532148711b86758cfffc..d81310eb30876b1af57919a3589ba5983454bf76 100644 GIT binary patch delta 2528 zcmV<62_N>o4(bz-B!6X4OjJcja7_BdKAc|?ELxCEY@s$*i6Bspdy=Wib-A01L&yyV^Nr8n%0@=uzT5xjGk$(-BWg|+8(mj2~Zhm-< zQVC3Tn(?+8xSl~bY^7Lue~?odQ)6m`LjkI72|-U_=&TwcRFeI~B_dXpCtRB%Seg33 zAoaQ*AX1P2$RqEw8n$>3?Dr2bs$|@aCi8*=09#4$_&^!OsMml}T z|I;o1%rO4xtbZt9p-ha^P>WfBSn zGH$i}(^NKdy&p+}=DI8X_1P|Htzanw|K2mwsztr2go8!}K!eP)lvO(-3IF`^7&KLv zjB;L`;C4L*K0#AoOgRn^YI^_x0626~PE!CK{&yW&<$nz>{uTyXP z{inB+{_gGg-iVWxJn;ALW7N&r*W%&Qvzf!8nzjDs#9b8t00;a@L_t(|UY*wGTN_Cd z25{ww1PCldGR9!A*Y}?qmWuHH#?UO{|vB@DVKE9@fnVy=t^oX{u4mCTsl@{`^%MKnoh1% znoIv5K=5Cw^Ae<{SpRwV=FPwRwyDdta%S#-Y)UxbZ@1Sk0Fa6Cj*@RaMr}u_mCjSa z)!;t@i5JVut^LLJ#)U?#=o`icK4MF1v)#q^Vt?WvIy<%X8Pf#AHa;=|>+nSlv$N4& zJl*=d{9@{Flti=D+G57nKLbPdJ73hd*zPqy)4cdgBl1ggv$?f}NTJ;xo%Oqq8*LGI zX8eT^c)z*1*#ZI)arK94gYCr@0PNRO&l4{;uQxZFttLRtt=F)<(=!Y6Daic7Oxzn@ zU4PmFzty6~a^yMT_4PFnkZZ`xM0!58Q{Ub`!ED!eQgbt}E7wi%n}|Hyj>JnOC{QWv zf0$2hpWK}cXD9V*0m{5)#?z^U-)~X^fXdB zq=)2% z&&kknrE+N`8RbJ34JZSX__3E2Dm284%yGYOSUOxY_`gxAVc;vTOipC?51Fy`y?>(- zD563IXoR$Wd`x`4tE+z0CVch0jKN~6rD`pwkPnU1!$JkxfteaAVj!G~+zrt!pKe93 z&d#pjnwZ_iwjPu-AUn2U(=rOQrOnna;Xx;0I07Ivq;*1c+u#+2SVsTL8O@hLt}H^< zrGe3WEMsZ_pupYerXIC;S>}0O(SJ?LHjF65Fl^hhq6*P}n`kftf@R>Ipa2slbV5v@ z&V!)kAezPlr?`;~hv=WCg~ll}Ha8P)GYilJ0AMjV?hly|+dv_QsX=nJ90n-fvUQ^W zAxO-CBlUvL;}F{j$$~H)mx*bZJYTKC_$rRaR53YT)(z;?J3$b^*e~FTcz+Kw36EnN zv)ODz6pF&CS0J8Js^r> zo*B(B6y@OV0R*GYi0w;!O5PpFvTY~}kx(886%aw7L_u0T|R%CD<3? z)geNPg%@W%J5DS#VrFa30c==_~sG{ne=*M0^I~` z9x)GQyf{oOMSnaijxN(Gjys)>WxP zj4CT4?ukio9N0Xt{genykCf5yvog@QMc}qW1zERNJVAOQzt4lcNXAvRD3lPF5?)vo zdz~ghY=DNccT&g0IwJqA?vvzkf9qFc5)gpiv^6p>)-!4i2@ z>`{Zw1daHlLli(D0O)U5ypb`yW59SM=)Pi!sp>G%kfiajcgA*zu0V9+Or|5j5XVXM znx?H7YJVnc=n&C>2*Q{@=!+V*1+k6jpZ-u@>Nu&-e8xU*trvk-#+_Z6?NFq*Gx8yk8rfdUWqII~N^@{q??`=fDPo60{S�U`x z4HNjD7rA` zDS_Q&J99LNSFV9o0C9N8>Y!=6p9V${Y zqYWJpStJT{2<8;VGxQV*_s@jj6CyI03H#(w!7(g{NTTsba8KufGkGMi>O!T0gD?m% z5?Pud;5_IB`80k;NKge5)L_9U)*eQP!Dons%Bc|6&dM_>96}X%?|}eU?9&87uw{;p q@_=9&KZJd>g@r!Czo9oC%YOm?xtzY(bR+!$0000mXSwwtu#+uC9K4ePu~H$;rva z#>Uan(L^&UA{!UW%gZ}0CRbHeU|?WjSy*syZ+(4zOgJ$W5fCpS8dE+ruCA_;}2Jy$|F zYieobPE!CByK(*}Hvawz{&$%+JRVYC zOWS|@&63fV>RR&a$K|2s?ziBayUDeK&f>_v{+kPy!T z)_^XT2Y+d0U)|cx7s^+K`BVhM5?70pf6iX%ge#RcUa3I~1JRak3l&jpG#XZ8(16D) z11%D>^fJl;b}x#=B(iObNnxT_i338e%1owIOpzi84be6iP>$o6Kw+ZB>%@SVO)hig zlv4tm7fpvCf{YDCL~9q3DHk&gcSuYyO6K({Mt=!-+yUa-*ESl@Lf!+W0c8eAQJAw}d8b zz&srQW`LLuMc|;UmK>bHfrrE|D_<21JviZ3QAOe`Fs=y)6Gn=Si`FV+?nD_DF1K#} z9ta8&>9&Fah)HmwIDE@0Jri}q&{Z|JNwg**+dog9&K);lThYL^gqZl(w$7UMTz^8u z@Nr6YL#TZ0+~0SkJsL<53KlgS)5dE~P-qOMh2aTZcWlH<^(41NM4e7ViG9}h4P`#C zWs}}>nV2Bh(>eaM9aSLY1?z_)ySG8?Q)2uDM)}$0-LM}o=b{Zg5G?swP!y#ODf?{L zb0^1JLdqA7*3DRwfEeLCsNwaESYOhD3`<=%j_*R3=X)2q-2~5%B`DfU zY6yk_j7||fHZIr+5R;3_ZerpBFz!lGgh6no)L0>u5ZE3M#BF|)kP?E&4tnDVYRy0d zjX>26qwfQO$6`0Z1JLbx-G3}Bhdblh>+-lzd<477(VL(f`qCp4FQQA zd&lc?Zsj`<$M7QR+mzldZU{tIH__Pni8FnPBN?{+63z*ko*T7M@n1~#HERYeQp zK3oxBsBRN?c*h~K5X1HP5_Pr+BVGoo0x|k*==aY#W~=t_+@ny3BXc@}ai+6?Mj!-i zsj3~Fz(8?#E}8AB+)dyF2znj8Qz=S!BncrTAuj8fBaY)Lv!imio+o@rUOI&>hN6TE z*=UF*rpRA{fj6GnRezQ0UM|0ON=EC~#Gr(F#N_KIiguJ^epmaS5NNMLu=HF7GzG(y z>vfL#ZB>9kK^mv`9YVk?kidE?A+4@R+Q)l{@9mVJeWXO@twjFEI^q2Z!Q3E$XA=na z7onZJo!GzmIHF${aBb2QL2!ge_wC5(&G%3Ao>Joc{KI8EmnUJ~S^3KT>FFL;wVJEs cnSXcv4SwXdhI!7>LI3~&07*qoM6N<$f(XoNO#lD@ diff --git a/TMessagesProj/src/main/assets/emoji/0_1213.png b/TMessagesProj/src/main/assets/emoji/0_1213.png index 9538dff4fe9ba4855f47cbd35ceda92bc80f2abd..4d2171600e327e63d375ee6c8ec146a785473c50 100644 GIT binary patch delta 2591 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 X{$nj9JmnWh00000NkvXXu0mjfvQffB diff --git a/TMessagesProj/src/main/assets/emoji/0_1214.png b/TMessagesProj/src/main/assets/emoji/0_1214.png index 56025bf33b2becd50f076cdc1f40ccbe2e34b574..f2fccffd109e7b39bbd3de47523eac3f25f2296e 100644 GIT binary patch delta 2561 zcmV+c3jX!v4~rC#B!6yDOjJcja7;#WtT|qh;;wqakYgZJkA0WAwQoj9ZKEYqjV4)? zB2kSbSClPSjz3(7Bvp}8j?lJoN4R=YRgKKow}O?Ggne;nI%SvLvx-WF$vtY(py^HBju` z%BzKE+sU){_Vc}yaG7sRns;H%sD<~&Wx9{^??rw*R%TiWz= zkDGDX!ao4J-`N(2GO#a`6m>~Ep8CYKxa?mZB^LQ22Q@DVcFcn;>62r#dRlheF^y%vA}RD_xhyz8b_VizzB zK|-&d`8F>AkAS=YVZnf4W5X)B1)zz&e&!4&UxW{MJ_yeCL`)##k5w3Lr9(G`0Dc*N znN(fTw7IdiO6{fqO<@Okq#VMACl^G&~)HqpQbo&?+iUPv$X9XI|x7BL3CR;8rKGY!!M$+B>M1O=; zaN^G;2mnI==D$=MR<=!y)GRmTdHnVGApmkszUn;Gdkf*{kC8RVqo8nFvS z`Q2u{_@-?|VE_lr!@QSnNxQVwl7CIAw5-vl$zVGWUU^ulGRFflrlwR*3`Ro8TO4ED z|9;;&T(c(ar#=9MU(Pw#_u8mnJ|E9~FM9qKOLt2`5a8GjT-39Ug$!;7gTqqjPscP5 z3NMO0c}G2r$5Y?aqJ#Gs+0Zpz01E?uIrKURTz7~@ZVy6_j0qW6-*X=m2!GS*bmlu+ zR7}6c%2}ps+lz&5$AoU<&B8P-A}V1N8y~NJMJL$KUdv1d*7{M>B2E;{*e zC{-d=gF(&A#|Jo8OFjc(gd&Q`#A_k~!w%X@-G~W$(eCL+K*Z%0gn z@c@vZ*3@D`dO?JH*4bV)b~=I0F&5i9cz5QyAYMwzlB%E;&v7uoYJU<$6oyfxX_`_~ ztBD`&!N3Zv)=qP~(dcw&A#9_w{qU*L_|#ekXvBO0qJ~yNLcEd;LgT2aATB>x=2^Gd zXf%$NEdzpWw07v-pnK+8A8uR_N{tLcLMBvvoBq^lwPND6adKl>i|#3en@-oTQHIg| z1mfnGu5DVYmANNp>VF_q6dr{Uhze!{l%tlCY4clr$RVaA}!#tJ7)e5O^3m-gOrEc!&olDX$U1iWXr-OKL1Anpeg)D-(fmSsD3NAJ1n@05MEm@936Gh9LT{QlY{E6Hy98N5piyL$KZc&~-;S%jPQZvj1j3TZn3c;NJ-Xm+OYm!csDk#yqJEAV!~$s{nw( zqu5I0=QU;1M}Ji0V+%_n3{?wJhO~uYxYUWQ+oR!dg#Y*eLmzm0Dun81L?J=R*ZwCW zx?q1p8QjU)5~pXsKU^*sM3|%8K8lDyY(`OGB2^a#5usDaN@7jy-jPV#UJny}6hiC; zQ3Q{Ik}SpqRP5n$Vt+l2!0t5(X!dLX>mn*4Z%9Fe*njFATp0+tT!x>Lwy>^j*k-S1 z+7Ng-ev;%86KesZ<34y<)z8cDi^(*u4RIf!Z3cm7na<+aq)q*}41#w>*F!%;tz;W zxO#{v^#vh|PQ=p(KSN?9lsSOd1VKgc35h)EL=1z82^m1vd4~{5RWQNl^p`2egd+$T zaR6=zbxowcLZmd6!jEDQp5_Y3oEuTa5&LD5#e2@(-QDxu-G9H5-QDMRcj9M0yRQBN X6_4fo03x*y00000NkvXXu0mjfH>koj delta 2006 zcmV;{2PycA6yy((B!5{@OjJcja7@#gbl$a*B0_QOvxW4=k~lkBJU3;NTws!DbyQ=h z;HG~qGF4(|tRp;aF;$e{C;JgcUPf4K-geM1JJ3g6+73PJ6f_ zOMVnSYcElS^~RClt%2pQfAq+g_RpYFXsk3dK=#q3Ix{mTSAUH^I5<>twZ@WgOmD96 zzm7U@t<9Hhc4%keu7BaIfcMUx`{l$hD=JP=XC+#XoOfS}c55YFl3a|yKY6$L;KKLN zt?Qt z``)}(iN7INihojtz4g_!O+!KHyO;jx$xDH{Gb<^ui*JHxSJ=Iwa9BquB_$6%X9zP~ z0wPUAIyX;APY?|a5kYKZlEnJ$+t9Fy7b;7>ql=1kXjCr|ubG3Hc1s^JQaLj-C_Z96 zU5B_krquud06KJ1PE!E=CZYZQEgA(6ZT?|bfWwhNy??*{kHqI#O6b_r;%Yo!qN3A* zc#G`n*`l(zXV*^0h23%8&-(gcd)GKJcmMzf07*naRCr$P*JpF$MjQrki6&ui0fW!R zy(GDs>z72m(0lLhz205Ef622efi8eEwr7%8d4?Ik(f;ON77b?pv-}^P^Z7WAe>%X0 z=E5&tgnz?xLEn=UJ~a2D(Kse)G=2#O{g1C;jvQ|ca}@SHQt*YXgN-BP8*=pR^WzME z_!x(Aj-=D+?2&{Y(+fY>0f0DyrfGXWJ%R`}_D=RX0EP-RK0l(2@X_80q79i21e6ha z_%>ebX`SAY1_kFxI%o`H@ZQ<+qwDxZ({|M++kfrtlJxGnY{0|rooM$B}_nU!OOB<_DdGwXS(}6uIcrD#|Unua*_%O8bfb@$efL<9aji^=>kLbW(18 z+BO|yj*J40^ktg*ZLf1BD;HX1iE;8#-ylc5-uDc%-id8l66Eq<+&m zxjP5Z-Eaigc5G>j2(h!PHryFW#oKUySV_-V3!t``m2JdyQ*O0n-MbC}tu=NPS-!cslPyB-UdVN$$p%~l;O9?e6Vdh9ps@8Vude92 zP4JuDJJpbl3j=+W%Q7yATvrSa`@tsGKb?~+gCah>b;i3f?}f0%TU7QzGnlfK?o(lvaA6?!6@D`yxmC5liUzNuQmir4SLK$z-Aw@xV};*GJzPT?2yW`tac3;Mtl@pp4)oLX;Lk ztO=QnP)&AW08v#{AwuL51Ps){tq6D|6XnN=G$puS%r%B@pTwfmA#45*3SBa1tC8oqP5bY@x(QX%rkrNVM zB5VL*Bgco9kj-ZI*O)az#B;O!2vIpprz^E7W~W`N)Y`U@|9*^oJw)hv2&Zm7DnLkO z+@pkuA}X~t|8fPf4K#ClaDPZM08aC(Tr@+8C^LyDtWCEeIEGM7kt?>zLTaKYItE2bK=L3;iR5p&crl)P?)$sIPgOwFq<@SAp_pomX%U4u z21N#hK#7&np9(e+FBBvxCltgqHSBrV2xgK!B}9r4Ze}8Z^HQ-`O@hFJ(2HZxvF;y$ zz{M&Sv5+yMCQ_n^StpVOeCN(Y(b{c}8aA;H0*#C>1Vn*cO4OZ735n=yLZk@+GzDWw zWb>35nAn=8+I7JKy zj^Tp~3$)gMj;~#TV6Aj;DTt7LM#|(zfXT!%A?PrjB5dM;;g)MQ5g#FZ4F6u`gJQ zGg*#9SA-^6l_OV_Vm~ZrMKDZ(yh2T1f>=9LkkX)ROeR*3q;yqRmD#_FW;IiJbWb@> zFdj;Y&@^P8x`kq9TU$MU$%$J&x`$&{HzY-c%UPM-hgds8b$_u;E*-juV<1zIw}N3K zRg)%MoFP}2A5o3Qlx)6?W_nFA!jNgIbXc-`Tb*!FH5&|6Fc(-kD2iJ>9#4undBZ7T zqdI-bgH$s^CK6hi+%aynBuRJ}2?dpBKs9u{9y?ofR720SnMa7wEM}`^I~~rOa$un2 zP>|L@gUs8;uzx>0LA;%P`}+8(nvacpaXxOa=-}1v>Ep|>c%_DGz_qPXZ%kG68{r$X`8O&2z}0#W%=@K?_UE1?oMQx za6xE!u0u?6@Nbav;iUn9No4M#Ua5bqMUE>In;iVZp@?E>JU@4^2A4mgWc^s+9GRH* zW&N=Hw|_um|Kzv(FXMUBAuhLFkNe6A5g77$b3ShT&183mcbF9ze3Yvsa;0YRjsw7# z;oWchJAa`xR`>V!!{HE(r`%@eb-`LR=gR%v9o}UBPmSV-`xOdsRcAb>U8F|tX|4?K zhBSBke2&*|^$FewpBnFuqd}Kaq1T!1UPazdiMCIB z@IEkz-2K{$_yHEf`vCN2qx?4KaZ_%(8P7ulufll^(^k?p;&f&sg@@83_DVCIqJaeF zmw#3oi2yaI=N?aibeqBymtojq%d!L-t2ydGGpvq3wz3lg zz0T-bSp)&z+OpW!8o0sK@@Oz(xc`S^nFzCMwb>8+!Hu<92V{*jyUd_z{5;DZ?&heg zFN7Q4_k$Z@Ltz9af1Mg9;${&&ECB_r34hlG13(7B24hi$mT^7n^wwqUBtQe+T7LlFiL0qG#jcSo~MQbt?^EJpwZZ7c*gH#~7YD;xj=P8=Tsg*Dad)Yw@U z5d$b_=Qlt&vP?|b;UXanaPa`4APfiaW-cEatGEpD1OX~^H7VZ*LXaVZn6_!ku7Bfr z9>;l}<2bGr1c6Y{y3D}PO=-+ z(8&Z0Hy8-nElmOg&j&OBds05707TLCLPgvjKp&xh<1F01pUYGVP_G6?7k?(WC1y%_ z3ZT%|cQe_G0d6Vz{dM8LEr~%xmalLA`J)W!`&WC#g4C82FaS|^i$Ex_UQr}Q91tG} z=j(axZQ?&JX(#sbHGG{+etd-!XZhSgv7omlFc48sk)Z3L3q}}z=(^9}V4jn~^H&oI z^XnV_G<|t?WozP4LWgl6qJN!MfWY-2FyhSg2d=w(dGle-Q#J1gt-a;8*^ner|Y z>?P$ZStklPnEdVIa`}jxdW#1Bv@~F+yqd-DZAl=sF|aYPBgHBRG=G3P$TEC!p~YvbQafG)1RU@!s3IY%;zd8iGsFPfMgk?1A}$|VR~4A%I(Sq3 z$d*z<$roEfU^zgbVG|b*rYqZ61`<(FYn3%@nh}ap2BMr)1q9S}loLEgn1(EHgm^W_ zFd5+p$46pS0U};dsDA)a#4SmPLNQYhc}id`d|ZVx5CjRXR?k%O5&$u=OCMXiDFG*c zE0g`qIw82DUKDZmZ9IzTIGfqh^ke~6jX6x`D=8|RwvQpl%5Xh?VF^~`I5rBhQ~M}Z z@`{vPkE6gefY9T4YHBsJ7xY~;41TiC!l1+CKi4x=O^OLRet$}c8=c^>FR?Pv@O%V( z9t1**$do}y2s{KC)`^4$BcP0KBl}r!(16X9dET`RBBNj(XNv_*i3zN^lwm3BX&FfD z7VCk<3_Kh-NjA&6SjFc8y*k}e)=5%^4usmRip;>^a*WfD1*jr9%$YccIwr0H0tf7~ z;JI=V?4n+*LVuqdgd&v_qL>F@P2h7?h3(!u4kIT4_}s^AWfuf|LbAKDbCskj#bwZW zb~SBF%pQe8#5oX-w{rDLxgY_b5a}>C2dc-jfHJgdsU+0GnqXP@SFTimMe&n9J{0jV zHwUV(KOnAED0%#ZzgjH%3s9cM?KZvxMoh3_rYY$dpnoOo;~EWVJYP5%&*7iuV-UI! zO0XjIatg5jt{7~PeoEo5JMH;=;Sz}RG@rL6EDi|PNIJ|kTM`|{nwZVj#?yl57bqwy zz+faqJj^teyiTJij6g$akLNUF1>Klf_faUOKsr#Yj}iDg2fcngACDDiVFYYS=<$={ z-GRmgMRzcCJwvG~;hor%;@3`4NQfR9>&yT^lM$?lLORT}le7w4)9c|P3|rsZBqY|y z`<>_#og5HgBmpobbULx}J48dm#N+I}6EM16O@e6ZFZ;nx*O-R(^5xxhai7^W)pQj9 Y2W@4tM6H=BjQ{`u delta 2106 zcmV-A2*vk`62}mbB!6*GOjJcja7@&&c0NjlEK-U$Fla_Vd$)K^p;}nDhH&iSpJi>a zQ)8t>U7zLIl-j(5%8*_sHe}JJaWX`HAw6lvjbAQHge6LT6gXnJdQ8x!Zw)nHA~|E& zy?(}xT`4wYP;j!}&59&TcD{mE%9UgmHeuq`kmApe#gJaqxqo@)%$UG_P(Ny^ynj#H z$%5Fle$bn5NqM&=Q-@Q1yF_}nxpPL^$$?BpSYlFB*QC*xQGy^;hE9XKW0AxfO?^{_zSpOAFlwc!d`GvJPkLHQ z>(8<1$D_lZdCrPk2sB;HwQJhRfhj&=8ZJ&|Kq%9|cs(Z@m~S+bYEmH&4C>#~w2f#4 zD^vj?Oq_pbK0Hfjlf~cAiSz2Gys4Y2l7r66&OrbG0Dn4kQchC<8#~D#75)Sc{#|)# z`zJbKmsODbY(>iWIp(|XV05dZ)N zOG!jQRCr$P)Mry0$r=UVQ5=zkKuF|hg26dl+dDBR=A3gNXPmvi{+^y0WF$e^a@Fpq zJ-7;N(|?anPrp6XznA}FKy37%1Geq8rDxB!w$|qDf27d%wcU}C?<6B56Ih)W|G;1hMu2A+lBIw5^xmSbm+V7Ph&ar_>HtWrd~5N5T}Xqx4cv6gtftGy$L@ zQd*G2#twaV@w|aD%s=A94a$a{@af&>!cXHdS_r)KxuXkzU!MPHvtoUD@(%I1`jjjs z1T{BP<=gF6yUpuILqBeaEdS&4={Zj}(tmEBpI?2xmc)yhJA+|(J~KDPRyl5Y4l8zM zSiapt^d5#64MlGKxVk!*T7^vVPCgQ=EQ^hSK&F(sEVcO#*?)&R z7;Qc!f!MR@gR|Qr|1MO;J#^4R(>%vB!VlSFGrjE91OX6etvq1@7#X#)5n8@1%C%2R#d{# zM~r$BrIMGK1~Hxq1~b|9%YE{y5oDPaSO}LVA3+=}poiHMCcomM2Z@AASe_)4@mi1= zA_stFWmP~4B<9BN7Q(?=yk@f9ON^sLh+#r7!s|^d5E4;o5`h@8Su==?|31Q70^u8{ zEN^^89}`N}{NeI()2blW=6{z@dWTpnGER+UgZ_BjZ|dC$J?beX5}peF-&d*VMkXIP z{(_u*(u5dEz)8EpC=n03>A@CWPjTG#+JjVx5%&kP<-oy501#9l5{U%X%`TKk#)B@Z zH)CGx!{ZwtEdoGvBU~s4V%ioWnh=OiyMr|lnU#A9W^C101mN*#dw+qE#f$_3WHA6j zl-+KB4TlzX3=oNgx57MOd_~0L_27YMJ+g&-xl9-hik4rQu#aRdY`mZFhXDAPidQ#k zszHz_K~y3i_9xNsmARkr5F!)|6@9)?+~-XI=^7}aAv#e5;Wt_CC77ho$1t@ph`R=g zkR~8vAPN}}ale!5%YV2^_{d}?vjq?(7?q+n9~l(Uh=Yhm;7k_>h@#g^h!7rBxxge! z7!z;zTvVfnsD&K^1XJ-qzy*tk%dRIS-28-kEDVmt|C5LXK;T6DuZ;b~bO@)(Bx_`> zO_tRz(XG)-#DgZw0Fh*H6yyU7>qe@FKr;{+u>c_=(E_eWFn{Z&`eUpm877Hc7oynY zs<+fn6!PRi4p1W>4&w4S1_;_jCXNV;w0gv)o{gv_B9Yj_0?s6hn}gTJK&FE=yk;~3 z1g^|25y!D&5h)SdTqIk;z%NpRpg)$^%fwt9vTtEQKTL_pY_MqpvGC(mn#lCR+S%ETgNhi`sZ=&mtO_-CV@n3^NnjVjLY?U43FgobDBe(QKps kAhgY5Cb8H+QvYE75AC&A=4Bb^m;e9(07*qoM6N<$f-=Ja+yDRo diff --git a/TMessagesProj/src/main/assets/emoji/0_1216.png b/TMessagesProj/src/main/assets/emoji/0_1216.png index ff126c57cc29e59603df6029fefe3c933c59c521..53b76e448babf0fe6db08814ef33a80768f022db 100644 GIT binary patch delta 2210 zcmV;T2wnHy4z3Z9B!3G~OjJcja7;uc79>=TDqNW$Q;uRhCvrzGZFZDpIwMnSmp5LN zCtH?Ee!47Ij3iZ%QjX9?CKpC07+FOGv{wh|m zM0><*&E(#GpttB}`u(HZyOEdR)xGHB{&#~+(f|MlElET{RCr#U*M~wP$rc7+8fcnE zz=Vp9qqBRh&Y7H}IXh|J|4HtDs!Cc$H~!8j3iWx;sehuu%wI(-6x3Qx)ieJwh27ez z&3wLJFOM|C7{>5uIG7-*|DM|kssNf_pgwHBUFIcc6_WB z3P(yYVm8d$KWs%CCcrQ5a#Gz6cfUERKIx!*{jyZ8QVke{xuKp`i6_c9k3J4b2`_rvGN%}3)XlhEV9crwi%5AM?lW@mp)_w!!S%149fAzYZA=Xd0? z^aBVtdeV5`%4Y!x!M&i`(+tFy`<=6Kj|l4JX77C)h!i??4h-I;-EI%sgF*dV8dS%6 zD}UPFN|>DY4@Ym-w<#n1qqGmF<1rCb$nV^p;?No&*4>c*&njGXC&8??Kh z*N){I!95%_he6{FAPuD1sCT46&6L+>DFqC|Xpb7fa2PZjBQD5R5D?9V(LaYFTG`Xq ziWm!_ZynNan+3xlkctc$KX75uOn-|YKnSigYBm~5tfa_*LIjEkf`-#SpHAdR zzi6u>#srYiv922+ip-A^DDTp2He2o+Lzb~A0WMf|5KW&k+h%@T3>9T2qae7e`9G(V z8gd$+1VDmo)nijX)$d_P1L+j&bG6uv3t>6j`wC&95!+UPj8N$9RZH-Aa9 zV|3CuvD}r>`^@{8OeR?0=R&s7#)EujV~y9nl!Un9p*Hx9U2A3ZdY`D1oamw7=~$+f z(?AqaM1rF+OkNFz&PfELh&@uPD}yd9*pCg~1L8WSSt7z`e9bISE@cg~UEeSBgcTWx#;~E49MgdT1oh`|S>5jl zz;X;Tt7VQjVS5kJ^MgmrN%0=o#j{65GTh4OdD9REvY}-vc^4tUoSWHiM?Dt&+dQNFp}YMfe6#Vq7G8kL0GgN0a4BT<_$skFZYAz;q2$qBY(qN{%GF? z!Scl?BKl3^gk=%p?i1ngn5H1QL6iB{p`SgrU@LpbUHb6Z6z<2EX)1A+nL%*iy=ODOY5pj?=O@o3jW?oa- zEQlEU`Lyi*@$>1yhD{}5jvvlJl=Y~n#Ekh5 zcL=tG$9wpGw_INOjKyJ6EaaRyf;BV|?1)|k!40TZMcYXf8~}Pk&1v zAjA_DgY=2;ZGPJZktoV;$-;&R0xL=&N(KypVwZB6-K{WYvJ4wHS)}-~2o{A~yV{0h ztctMmItV&z!hlJ8q+%E_x`-Ff5XBY(MzO8p@eZmsC4r{|l1)3IGU$z!>;&aU#bWG< zdD1gvOV4arn7aW$Y=20GlAFs;3?fj*u_8NRew>8ZM&FlxC`VKTh_|Ca${-NgNoONd zcpYdwlu5e0h$8yfumq8g0?|Y#h9KNdC3A!_VAz*YKtK?8ZCe&`K+i}?$UZ1J5Qyjm zMp@eqBN#MN7RSsJf*)?-dA=eHA`T=`GSW_n$ZD!04bKysA%AA6YPf8YV6OEcIuVA! z_oRbyNMjYY5(QOL?$-D|f46~Y9Pi~E%7iyOb zdYja~6#`%)91!wkuBU9gA*Kj7u5Wp+9qw`heNYkn%73yRtttlUq_5e1H11rtTGtk) zbIw&kq{CcKMRp|1V kru;Jwg&QFsQ%y(lf3|phg&|oG<^TWy07*qoM6N<$g4nAI!vFvP delta 1871 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 delta 1873 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 TB}tM+00000NkvXXu0mjf4|YA) delta 1586 zcmV-22F>}<5yA|RBYyzWP)t-sM{rC|Mn*I^SW{l0DlI}cE-OxAq(nGfRUkt=GD$5e zHa0IXYEMBZLwGAcVJ#*kM>;epAs$9QKPF3lFeoNSceF57jSV$lBTRr7H(yY2vLG{B z7DI4Ec()lbQYBZ6I4UG68xtKG8dE+sLNO^SW12>Oxhy6nN`E&m3pryYU6ChaAi3&GXo_~A}~x3 zAU2wNL}QV|-`LH=zrfMGkGrg(I$DHcGDf2S001C#QchC<{W4fzp>Y%jAVz!sh5o?G z?f#zO*2Cn~xqqph=Jn0--tioP000F4Nkl2l&Y6a`=p*vLy9LpuwQr6up| z`fIfC<4?#Dj>K@g<+8HD{M zU8fvC&M3n>qYUFIU9Z|m&f$S6@1agHbYulSh2>(EX1p5R$HD-$9-2#gO1FN&@#&Gz(njYQa#WeSMU z5UTo^Fn@TK)tMd5EYuo{B6>*Urh0qOLhS%0i>!g~jxlb@UP8kvDUJ zWEo#O=Kf~g(k#8sxuG$1f>re}ELJ#F#cX?Vu@g31zS%~6-LUrvo$Iufr)bYkGrSM2 z-(8JK#B8&fMH@+MW_-Q*fhzV#oYfn)kws4&E`N43U{I(Rb(|vF{3+Jr=ayRez7?~d zKSI9dWfhhYUDZR}dPB0Neiem4W*OF~;|%!b`z(6W^wIY(FE3vnS$^qx8Iedc5~yq|C#=Vp^wndB#2ti^&^!^rpwP|9B8+mXE@`oQ zAh4Uikd`FOs_(bdf$}v)K;WX~-?^2XK!4ZH0a0CiLmsL`xKrd6Wgr4VioaY0&&%cV zRxhj2PZ6sj5w&g{ce{f?a6*bNoM$3Bx2VHvcCjS(&5sCnJ)if+abXa^l|Y7%wWDr4 z?)7fi0kO)7+7OY(s}S;QkCUK?&hp+O0>b#lJV7jy8j46J$#6LD#og&L2m~c~g?}J{ zPN!4TYNPlRQ9~oE#RRV>i-j`A@o2Dor92}5DE)rRbh~j6Z{ceP#7YtDdO=ANbs*D0 zXZcLYf&Sp$a!~{b_au?jsuKWZ9o-QjvVy)622mD5B#qz-z? zYTp1N6-i8UqR9@4g(T(xhT|@XZ^s6R&W-@>YsUokBtr=E?kGV`?+n!qh<;AQ?h!FT z>9hl{PDc*~0dXu1MJ&+?h*K9LhjKx6_j=u_d;N`4UJDF$xyz0udPk>;RDXxKO$d0) zX_K`}LK+3p*%7_C$&QHm5UWWT-B+}nD5f+ni2i_xc;st`sr2SpEGHUGwpT}0C;_7m z0wPu&#=N14Bf&N0{gh`>%z3}xxxHQXrz3bxOFK$69@EMJ1R_wz-gFT?Afn|g(F(@Q z)sADjUr}CDFRmCw*@wJQ5Py&Cu0sgU>r^VPTV=bFlEuM@t0FqL%)DFTOkM3)sXpMd ziV#s=2Xf0aQ*X6&^Or>BK?3MwS42^TMLh%fWvpweVp8@&N0AfA?-58rj6OlIJ)%4c zA}XIEsE?fJ{5GLgaTs|cL{KA?$1{GQv1G?_(VruOgVZ~Svn#OfPH{Qv*}07*qoM6N<$f;Ax8wg3PC diff --git a/TMessagesProj/src/main/assets/emoji/0_1219.png b/TMessagesProj/src/main/assets/emoji/0_1219.png index d186695f1786eda2907d9c133a89e9f928e1f742..af0d1dba9b47f7c5c2d434df1ecba54ada6f1066 100644 GIT binary patch delta 2098 zcmV-22+jBM4!;nPB!4?lOjJcja7^d0Q*s`Fpn6|lIAT{bTt`Di_tdfR$D)y6Rqnic z^T&R3AA)!zhxX8=b|i*EK0R|HfIK)jgF;vBw|nQVQ8h3yJvll^Mn*k3IzKx+ML|LH z#EE$#iTBZ)f-I9TEG+1saQM`u`PZy8F){D9hi)8v=Am!<;eWvs5)uju3oa=s_}I54 zAt3tPyYtPe92pt|1qJB0kk*xL;I4?%W_aE0h@T4rWuB?bYQVnH(yIFvJ{n>ntlp_tIi!{W}c znwOG87zK$>G2PwSZEbCFKn0*Yvy){2x81pO0000ebW%=J04DYQCO>2T{tty)%dpa4 zt%AP&qdnr`@0Nhsyyd0n^Zb;w(A43*n@xi-000JyNqBYI%3`q=P3$PW_8-Ee(ran< z+kYY6Q(H`G@NMn=YYSnR7)`~1V2-HR>xe(T#kQ!}JN7t6i?1V?E#>_WIsK0P1NHMd z;)qHgVSgeeAHQ-I$MC$I0^*2Gy^=_=sg!(lBp+{y>DLm});m$5MOsn9(_|8fBqWhY z{5z4RWlEG~S(KO4WReFvdx!hgYI%Qu|8Vah`ELh{M$d!5V&Z)|wtiTx)=qyyP9Zgb zc3wu{IFMi>MX~WOHFy#USowKctCfp8iI<2h0)HqG8i}o?DcN+?Dgfa?CB?%R3SoXw zSb!WKQ*x`X@x{}hPmyZ*%Cn7~#r$F$P zaa^-n7=?HH|A2%UD@DWHY~;M@nzev_dHgt$XoPOlWGMQ!JLN zkbi(dM74bQo4v%owrD`;mS=!aE%3a?Ogk^)XuqGw||ZwQTe_B#w5?H6=V>GNC19ZDI?+La=CWt z^768s%QY*7PKA?(hGiJ`_(9?Xcq)`irBW!YOk>-1-CP?b*X;sPkodl3S*B$fP>8A) zik+xYIefa5-KF5x>rGsQ4T7%gCLrf|Rq8B}3MN*{*o+b|iE|`mAp~($0Zow@n19%b z3d{x)N~Lz&?bb8Rf~5JDH5!=;geJ%&F9~QNpj2=^LbjLWTmPRW*)7 zJtZRx2@}n{Z5z5dU-TFA+W`w9mGtKQetd`wj#mMxgonXIhzlUR;dF7mILl9OSsa<7 z=F{o*y)#9}{(*;PRN+%(r@4QK%!O}T!}5)Dw>Z1Mz7|=M-u2YKK0Axw`G0We9Ssa& zkBJcN5YabG|K{fY?Ck7*^w=YUcs=vcAI@jfxMAlts6z_BYRu;d;ag_!@zDX|uios2 z5Vw!B1rWc6vzt*ssNutvh!S~Ar^VU)*RQ|Ev)Mo<#%y+j{%|``Ov847;MFh5RiZ=) z$1t;sEN9KEIA8-oW(R{?Q-4=Pg@(f+A%YXa#2Ys}PRRy>lG#WI1>2=fW5OeX7uKUh zs0wZ3=`=-&@)JTv2Smx5Mjs2j6e5yux@fCQ0_F)PQ(OWAqL34owG4+4>Oq8X1ETHL zo0^I{A%v_bq9`iF1A^AA2?v7!f{PG!FiIstG&rqq=}-nCV5-@ysec5MKz+bUISw(Q zAxPvU z*{x@g(Onu%7ze)kTH}Yj<2d<;aSIC$5+srck<4VkAP8;-8F?!U2<_S9@!0U-7pWlt z1Tew`vq20@;B=e3=8RfdRK4e!2*~PjDX2jpiF})PGhqXNT7RJqDGs+VjRU~Q=c9t~ z9f)ulQ3DV-Vw&%nx{kk!qlttLK`%TCI0)Lhooa1?hVT|nIa6ASA7eN3Z z$o(7MYX&7SfI#<0xA9hQd0#>K`gJI%TtHM%zI^zE`v{*7F-Q zTr@I`MzbjhUw^*u?R`2}Pm(Sotz<}u5fFd=={B0a-)vqqGo(Yed$POo^hzuBpo}XZ zAeZpkbaOBp=1P1c`115+Rnkx+Em|+1^Y(Yb4)<4Dvq#2q_`2bh7=du^kxr z0wQHZg^Hj{RsaA1 delta 1891 zcmV-p2b}o75b_R?B!3rBOjJcja7@*oA?BzV){!ymuN&^N9qFzepF^wdwJrF_O7FBB zaU^_nCVF)#c}5pgf-jMhJD~BmA@{#2btHpvCU?=26!^q8_{c(WA%66_BKX5J_RwnJ zpcCGm6|r{~iB=h%LaCuetd~8bk2afyFOhmDh@?rcZz6uDO@Fdo8FH|34VYUC*_jid zWDUuR65yZ~^Sdhh!zc5C_Zq;)rZ;OpyvvY3s! zUl)2KH9r5SvEXM48xFe&vfWg1q2u{AnfgQgM& z(|@>-@#vYZ0kT`F86XugYCI3YkTiqBIDk+SYxdGLk(wbD8DOw&Y8tPhMx-1&RGcUk zu!dySOECh=bQ~NI35@8jX)C1MH)D*Fhz&M;zL2eF@Kr@2o@K@{MJU&lVZ$ZW2newi zOv!GyqI4C8Di>zE-EzNM?L1^*$3cOYM}LpEhkT%k*o_^OPmE<1feEwOY`I$P_Dexa zM1&pFBSaH=w|5gx(~Vs}$ye`xonF$F0LvkuWWsKLI={TFpcmIf#Aw*hp+p%WCiL?D z@_ydFT#i>GJ6>K+r|tIrJ@l}PabPGnXT0?&Vn*coTXEW+x7)*|%ql`HFX!`ldw)K? zo;=Gnu_ZjY0_Lq5*QwIp7-8|I+L6pLgSa}lJ^V9CFEbV$f?XrAZ?dSF+5iuhy z@_6gA-Vr!=YC5KvOqBJ^w(a#*V1L79L)OZa1f~;G%Mu?uHwiKD5q2G)OqF`R8O6sd z(;-okd#($8prC!5$aB%RLWe>pdUeB~g~b8@cG&=dK42>-@_n)0yG2NZVNR5>##Do z0lT0m>nov5lfZE>@Lkk2}#D_$}Td_hnHUn4; zdjJ6^2ve5{HPLt?bs4^e-82pZs01=e07zZTYXG5<=(eX=(2Z>^iR{d>DzBchLJNGT4l0j%ChNc;O!!(Y`_uiG8m-9J5jhkrb;kO)^7;&~nl z|9pP_#`APP7<51V-=Nj{^_Sm&{wh+js$~8evMgr z6_wJZL$(aL|Lf>?I7Y52;^vK%#fL{=tb~!%I1IzvD@{h|Qi@XdkL&e|`n;>0Qr5yu zF93rSOUbBYAdhd{;(zU-N{R@|BIJMjkRm54r^*zC3IidqBBpa;Nh#KCJ z92t7-6B2@3*Od|E2|5HaRz!yE6Cy&`whaiiD@RPwV;@9U7+iI*5XflA-zovahW<(9 z3<8nRK>)gz^>g=5O!PcUirWcy0K3EANB3onBJw48w;o5~-{J5C{!RBv=L?$W%lk<* dKy$y|=MT8a?55H%K!iX5Oh*bQvmdPt}7B} z{lry0-tUgnquR~-kpKV#CrLy>RCwC$lmk=OYQPdh4yX-uhcb6aOE0mfY)mvVZ^`% zLCi3D6yj6&2}JQ}oQJ|83V}v7r5(zQ_uCVBkH--MfkDTau~Ho_DiD;~9T z!RP`ZZhu&$nm)d>QjtN#1*y+mxnQ5972NtZ^=&~fQASg!p6fiy+V?8=nE9FefbbSA zGo^9YCW3R^C51eqm+<&1heyiHTtOM)-*!VHB@TLmEi;7inAyFpGw8x$BtCn60>* z@!$>r8i(YJ8Lc=_lu2imC@`fbUI=fk?}#f@Mt@eTXENA7){bb<;q>g<)I`)6>y3a0 zfxUL)xpkgj%y8RvuI0|0y{OLB*^4_+YS#N!`WJ9Dvx3nMoe5$26Acs9#VR&l(3JJj zK&W>^Qvd@-w)S+~L{zJf(N{!86O6uYTajo;>Z$egEJlEsE|5Vm;TLNc4;uoR1R%r$ zdw-m(TfLZmpe{)c2tFtkJQz&CUuta@@hUrvd_;h-M9>#7KF9oN)$h{1tFMId!#5c> z0TWSQ$_CGqQHX>PdbMj9j4}!AgH_*X)eDpKYI?XbtuXi*TJ-4S_eNwCH{oVf?je7T z@_QrMR|tfUGh2HF|F#Yx88c|-}MX4 W6Ie>(?jE540000lvhJ|=odD`q+)!>okI0000JbW%=J08p+m|NoMF6xaX#|Ey-l z=KlPsD(eOS00QqxL_t(|0qvCMo+Kd%#0}6Y829}j_L_40cYn_1@O5faH{jnAoON%# z_10T|Drnnh~H4SE>nQuFjh-tuv0m%q4shOUi z)qV=*VGN>AMjphZ%^sTo@j}2%WO@W+&)C0G*gkYK8Zqr-B|{htjRPUz@FV6P?;vyO zd#y3F+F9U&iI#`UMa*!~Z7T%32B5XyB%mlKl12is2? zPQ%4D3v-BV5!YJ!Aj_AlP-T*hkUM1|q((3GPObKNn&#pJqr_{`ohk*dWIQIhaFt}g zu}Mq0Uua#i;MJxYai?nW2|nx|nXpK$1Gy*?#(>O2@E5r8?b}K@y6nqnYDTGKRMmZ1=o~8LfwT5g6w6^rL z^wlq1i1$F88T2`I47H%2eGxuoY0BQ9+FTz*?|(qNBv@v`=Zsc&P@h5uOq2F*sNRIt z``Qdf7^0bAU8WHrKQ=>7$EcCz{SsuiHbV5cS6jI)rM(Nj?UBe#%owNHAfwbLhncRH z-6=l>MUR+4Sk1Yyz&Mk~zneo5M)*J&;ltnb4=`SHt3~&{k{Nl*J_-Ai3dWH`AAhJg zmTo>bg2)I1r_I9{^e|W#`uIa-7%^?aQyCuyQZf_BKNgJGDD)wm3`OeI!jFwC5i!C! zv)qhfaaj0`;x*^T#~l7O><6M(bbq4ky^lX&-_h*;U2nbh)>~fygbXpqKDH2l00000 LNkvXXu0mjf&EuY` diff --git a/TMessagesProj/src/main/assets/emoji/0_1220.png b/TMessagesProj/src/main/assets/emoji/0_1220.png index ee8de8cd9c8509969df111d62391b5939bd22b76..d8f92458dfeada9e33ce3750c5aeef63821d0b4e 100644 GIT binary patch delta 2191 zcmV;A2ypkk4Vn>dB*cBZu0WXnjLY;?$Yv&5Lp#fp;Q@ZyLf>_CmVYzuv znsqs`a7TYoE2(He-?x#8ESc8BcjDEH^30=xCz5p_gmE8#dn1ahj6~Y8jM2Msj4qwp z$$j(g)Y`0tT^^*%}4lKszloZXqOdPPw+byDRP*o0Mj@=${??l`Ok@s%o zOJrj+;&Ma|Tn?*oK#P^eV)+MzEiy^xz&U$-amBr{{gGsMd)saQf9)3M1YOADigjW8 zFghm$D>@K`b?6@MHiPGsrY>t$somP)>2pD8qq&o7y zeQkDZu2~P4tv%i?YD{QU9Usk^Sr7l4JvQ4@!{uuGJV(2XR!nBkMo_>2n(pRz#( z8-Ea&&DQn>a^qb^)0lE8e0DafR>2S_N0*B;ePb_HA2A3Z1&)rYrADz>RE|qwAn5Y! zfEc~;E-x+1Y#V?m7I2M5S&nJ7n8tCb1cfp)2a}9eUKQ3JA8#+0mzTfw@oW74G^aFM z8pEMS$;2Rj|F-27!5d7(Zy%A{fq!>59DlBG4V@aN)SwD={AYfDDQtg9cr(Gw$weku zKa2*25{Of-p{jaID{|#5F{TWWO1s(8rx!KWqrrMGb8&KVk_ko!=pCwYsw~TDQ`3}k z2#-A{o6Ux@;TNZ|6|I9HsUIc==zN@PsIrI<1P5|vKtP1D+rKX5KT{$YjK*SvaDO;U zN{ABA^OC4ynp*m7j${cDD*bxD)}myNX96cd1Qr3JW4-0<9GMVqv#{>1*E5+5dYrNN zAbgCo6hR32d|m*8ae#!*5F85xO!CQUUg;``3xpE=3diW`wWev;Y#=p7WSyKzHVgzr zI{oV;TQM>Rk|9KoW14!ShcSA+Kz|^RN==Y!UDXw?TtNj8>8yE@&xy%ODRHS3TdE`k z0uD#Pfy@w|$9{CYILY#HrBVrfGVSD#XdS|gC~8fS4Ykcin!$<0upgFwjZp-QD$iGHxu>s3p16tnqd^*Xqwi{C`qw$!xEC z_qF?U(+v~|Q3wPI{cg8^e%`%SiJ{cW<+R&Kc#Xs|=IC{Y=OE7e{lYXtzx$*A^wjNZ zbQA`Y>^Y4@&`7jY@oqSLLeBfc)I@Of|NQZUF!x`JY7+!gs~BIkbpw%zFBfI0pBtWo zXr=Cl#IbN5`4ap8$3KPwZHDG(?N3g!-t1ra+q`Q zgg}jQdeK0vPOrt3Pelwtwu4)qy;v@G(|oS1IUXwQmmx5CdBcIfruTF8grs3lN#vpQhx~KSy6|ez$hDu z)daoa$*54Qh8p~iI9X*vpWqNiA`!? z5)hY3MVZy`6au`g;(x_`E};ORscl-!1YTBzezvZX3aNqG16~k#Ns@T-y-1M~asxsQ z0kLN_yd$v$sX+oG9><`xhM?Va2SO^95(d{dO(B&>2@XIR!OuOz^<0a=h(__3pdPG8 z4>1bY5b^O%@!HLguSoaDO^YRh4555V0%hNDw?4<>q{kr;YJbG8Y7-;i({Ij6ZuB+; zej*%C1H!P?I1Gxwz$^(I2MnyGEy;RQm!)=Icor&?d@>O0Ueurlde8$&TyfM8@_E+h z^RWbw)M*gkcg=gCLU{*v#Qo1FMyQ(6B5oHn2`Aq$dfH<23FB$kYIV)DN%m zUBNzi7SH2GF@Ly~H8KT#JVXeq`HzvQ2feBFt82#R6J=1U(;8GjPUN+LvATYA-4TAdoG0Rjdg42r?KsBgV$Y^}~mG1o8))X2PH ze2yDxfG`D%PDHLkV1mrZF53VA delta 1710 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 W9ps{E%OmIj0000%%)^Z? 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 DqbdT- diff --git a/TMessagesProj/src/main/assets/emoji/0_1223.png b/TMessagesProj/src/main/assets/emoji/0_1223.png index 482d0b5d0e41e46aed72446337424c83e809066c..de24db257a55641fbbc8a493cf562a9a6ddb68b6 100644 GIT binary patch delta 1644 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1224.png b/TMessagesProj/src/main/assets/emoji/0_1224.png index 872f3b14e577d2ab60caddfe248df354c945690d..d040b0e2243683331251536607169e267890e5b4 100644 GIT binary patch delta 2154 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 b8wUIr)PviS^f&qX00000NkvXXu0mjf6>D_< delta 1761 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 delta 1503 zcmV<51t9w75AX|+BYyzWP)t-sM{rDPK_zECC2&P4V>=(r%*=L6FmqHylVeAknwpuJ znQlZWnwpwoIUIdbGl+QaPlgq;W+h!NI|@va(@7E0&g)s;a79SXEm!9f@jO zjbB20PB5BkPJ&lJPb(6ib5vP08N7;ShgdaiK_aPgSh0Itw||6UWIG+dj%Ya`3~5F% zqkmq)!otj&Z*xW_ySux_m21t-&CREV=GDR1x|m8Z8~60?r-o+L)z#6_(F_O$r>Cdi zsdz*=Ex3Lh$H&KXZ*8fJZL+emypLft5aB!k0010xQchCE)=I`hU)g0wRqs000EBNklE6Y;xpw~LO3+(}aD}Mk3pcJ9Q_K`*O1}XiQKmnW+ z%G_g8Z~_`?RzfUXfQjb_p_H;C@^I)~$z)1ZX|W$q2t|S*7&i8!B_Jx0a!NU1!!Z_z zf%Q%s%DBL=K<9EAP>R9(Shx&sLlO+L4$?f=Aqy%@@Dzq&=+$>3z`R+y$#a?75R8Va z0$lCdI)8cr_H3#{0S+Bb_k`iEC#O!~4Y6_->M$l6B`E}k_77iLPi;e6L#%rmrfHnS z0wrj%pw3deu5BzIa@LY3i64_fZ@?lodhli$wCfd9%wfv74-VgtBO+LlY7LrPr&f~I zD}YeSH1;hS3_pn@E{brIYk7nMJEjXtlWd1y5r4-~A#>ea2&O3&hGuii-jhWn%~Mp= zwX-z<1H3Rj~dNmyBKHfmB4 zhkrjys4dQXF4LY@uMnCi$#RvyygWXV_1qffYx7*L<0R7T;Lff){PpTCczs^2 zA>6Q9so-_Jnj}d?c!R<_qp0vF>*aDenSZ0<85d-U&$wM8PFhW0zk)=GZ&q}UhUe#J ztOdax6Dv-de&k&tK(X5)lbxd4EwE=fxoA8T^ceKBa%4U@=Ghws5zRl%jwW&POTi;3 zKdB7xx){NdHZ?=qN&s*uAp}X@)FB66qoOBMvnE#I$5E7Il_7~(-mLJ3Qi}*2Hh&Gf z-K+tV(7A3kDn?qSu&xQV)D}Wx>?;}~CS}-eEW~pLBgSKJzz~cmMHx-3K}b1tp^zp# zuiZljfQJ%uHc);720C&a_t?Xh%XowmKN3YDU}4cf91q?)`oQKe62&Hy>aJ+D$&Ypv zlt*B(L=hJk?>+##BSyK342o0ce1G61?tO(e2yCYiY}Eer5u9RA??Z-G&#WjS#QU>2 z?e@QoUbr&7P>R!++nav(_-=Upn{(v0;ISd%w?8^hPn}E993$x7oOdkeKW+skqWF*V zr@sKObZ)xMg3gm=X93PTD3}3gX_EAD_6$GKSYQA)evHg!Ai3<<wSkSUkWVIxY{c%@;H*fXZUA8GrzRH^FhJl+#Nz;H=7G zu_XWx26P-sqYs9M`+J;KSxj^#Kn1*ikBy9>-ch@j@jaV$1deJ zps-RrEXIGXq=UUjD={6ymF@qz70|pf+>GPF zIIQ3eFkuE$4m9J-)z!(>_4W1D$>;xY^7+JaWo7_-#XqBlQ%e<6(SZN}002ovPDHLk FV1gT(#}EJj diff --git a/TMessagesProj/src/main/assets/emoji/0_1229.png b/TMessagesProj/src/main/assets/emoji/0_1229.png index c64609eeadf24ccde085c9f027d5010ca11b7a3f..70873eba1e618a8c6d27879b308675506b5bae24 100644 GIT binary patch delta 1670 zcmV;126_3Z3zrR$B!9_JOjJcja7>JPU6X`pjEaVDRW&>^Du951h;&AYbyK#swkIMX zA{-l#kdSp)F>`HbAsiYjBq1pxA1WdqYELv|OE`IXd7Yh|j*gCWVMRtZEgcsWNHr%M z78FA;DM~gjJ1QevMmttPH&Hw@B_bl5o0}003uH|`j*gBoBYzxyeSIw{D3z6zp`oEb zIyopD6-q)vT~ktqg@t5USf-|?uCA^&FfgmDs#8l#%E7eu^X#08XyDVnxVX5*u7|X< zvt&02oOeT)Tm{XM9SJD0n*aa+9CT7nQvhB*f2Ka^4<+YYz21lXiKpas!|1u;t^48b z$R%WS`~Uz2VShE6@7^F+(*px_Dm2%U1{AHMXU#6rVsBVhJWJc&va$3ckU&OnWE3o-ENofc3Ji^o_5rmgk*dr|Cj1Q=PBL}Y_6OkcfBOgLqfa^Fv| zbm%z5+9XwQZJo=bXv!uG@ozU9Q5y&_;Hq95R)5)q{R@KhWCx=>gPu@0gU%KqL?B_k z)Uqn%(r!G*@oK$|Bd_oR>>XOf_t8KE1D1se1!FZQ(FV2+#`@QKyRvss+5&>{)Dh#H z177JoG>CSD#A>@*#dZWl2t>*lUF3IX8M#2AKf04k*`ggQV0f<%#E1wwUJ7pxb`B6`zCZ3+dK^`TaXjw1{~0lp5<(hVp?)JWC#B4IkNj=o z{NCrMSxoOpx1pmS3d&OA_Zq|?UY&^`BPpfvVc|f2zuTu8d3Alz>CZ%x`jmYfK7Ud8 z_wX)Sn8D$Q!k@!o$$i2*&2t*ZHL*d$-5-v>|NZa%5DCIqz90UG>wr<;pJ>;Jtsq`f zpEJ|&_Me~o{YVI|Zn*I~T>n}!6Nu&^(>%K-y5ltE49``oAme4t(;x?WU2wYmy%${I+B z2Zec_gL21tXc8I{Xb7Sh5r@EToD6uuci&1l<0heYJ**M0kcf&PajMB2#nqY4F*d2-%-j=Li*aD zT>RiC7s7y)hTM6;x48(VoKq736vjOjg=VB6Km(Psh}?Q0KBp7~jG+AVp+PqDDPTEFOjNGK3D;gv0q9wl(z@p>-QQw(yB1NH}E> zo|4^YGU38GU5&u#VgD8j%|O5)>V9e)98!|}o4@F?0( zvUcmPV5(7oKx6-b&=y3vhOAfd)AMCS>VB(Xmo=(<`F6ds2hy$WsB3IRjT$*a+t?no zZy5D%R7Q=|HKM`gS>)O%Z)`<;ht~M9?)l1=cB>4YFspwqX7x0Hf1wKCf27QXMzqfs QdjJ3c07*qoM6N<$f~tuaX#fBK delta 1431 zcmV;I1!(%04XF!|B!9h7OjJcja7;QWB1knWKP)3aEF+zrok%tn!HnZ)6>&_etvvvV5g_2&(6-efE{j3 zId>9L-v9sr7<5ujQvhNoM&|X?5a#}yeYxlOB}U+1m#lK3pIqlmvj6}DgGod|RCr$1 zmgkbus*P&;*c8dw0iY7RG_!N8&cU@n-e52b^ z3E0*MF5Eg;#i#B`oyI&&vh9k3@e)Sdv(mI?3>!~|L4;HkUQz%e(hIp7(^$}+;X^8GvAie*q)CwI zv?5T)NIFU(J{1TY)oD^AB2^ypB$MGuj+Trfj~ML;5V)td4@co>G`hf`z$K;9SWX~# zE}anJXDJ#4Qmkx<#_{YL+5{_D?8QzEad5?oTz|?8qaqsTVqm14MNSw+2`FbPA>tD+ za-68(sj!;Qh~NoUVt<{>xb^`aiXs^o=xLMeLLp=rkH_#0Muo|?pMsBFv+OLaY;ZzC^Htd_eL%aDk(pKs;w{nu`EO5|&d>-`v`p2W@7#9(BJ zhpLTtyX}@HYOIn8alPB3Q&F5GZMX1YmH~mGK6P~q1Q-zhONed@!dAs_917P6VpJIE zCCRY$p}=H>s7{#!ggzr7O_rCj_Mc{pqkkC000d_P(-i5W1_XL)4B7~TAPbQ^+~u#g$A_B%56{1T zLhmbIA*dh0qW}5X@4vp?M0rGfAAcgqAM){M`TjYBi1OG9c*S;F3iJN{vG{oZ3BY7B zolJ=G+U(>R0IXI!LYhYLAWS!#=~Pkr&rKfs0H~#!QWItbSSxKNU|dh;0fZ@5ZU7+) zq%9EOOGz`X=JEmpR?=>oLg8?r3CE*itigD@X5tA1TBjipMH7HL00ImcPk&czJkKWU zBP}9n4!xB%1pq=Zkjs^dzD_pBIYg8iQUkOLEKrP>D|t-UgdoP*4aJ`kcpcZ9r@^-! zolVJT#enTgRhi%e8?$eV@iyBi?^t-@qgK__YC66x#tTLQEkHIE)M diff --git a/TMessagesProj/src/main/assets/emoji/0_123.png b/TMessagesProj/src/main/assets/emoji/0_123.png index bf0969f4835534fe4cd76cf566227b8a2b579862..9ebc627b77cb84ce5d8496b7eb5af39273ce26ec 100644 GIT binary patch delta 997 zcmV?QP=HcBj9NsRWlf`PQ+rQ3x`t!5e_w4uGHgUJ zZ$>hOS3#$7R&`1?qij>Ldt8H5KX*(xjax;cZBoRQZoiFZ!I5gNcUs1oa=Q&O#Q*>R z6?9TgQvhZ&<^KK0{`(CgSx2FIg~IxvyV){$WSRf~14l_jL4QV` z1+`lf@c(~wZvabYs%vU?_qFo^B=Y)Z+0W9Tr-F$VpO;L&WShhEpBT=79(4O?dB9B+Uzdgm1y zaK!Oeh+bN^L4SEVSP8-sQ|HR}8$&e_8xy;3zzucct;tZ0AX-qzCn^I^a*GCo!8j4g z<(FJv*(D%O0)wCzN6fwvv>N5NL>zGzUmAj4p5;1c$A1kW^9vy|m2*^D++?qWfgxh( z{Xx)iB5V*uuni#^=--Vo5 zc&T}@WPf=vGYI7Oo$xTTE?RsCGvEVDNr6FhP$~#UAFzli#)V81UbJC!|q*qwE~g%C}S;x zTB9ywtZ0p4%S`C32%-~VwYC*;FA;IxLPUNY1hGRN?@A1*48(;9p(5@T5*t+g-Ox6N zIk{!-GF_d`i>y>`UR(vr-MqNOjNLoUgy+QT-0|0svCCE|n;jF~<#9K!3@Q0C6lOZv z{(sC>ar0CNCIlml=47pN_9WFlR6yM>%-5CdB$%8&$${0{vMTbjRCo655&00000NkvXXu0mjfB0SAz delta 746 zcmVOPr zk@p+b(3F&v(wz|`%*RfExCo{(awLH$FC#+S+bZ(molu-$S0xlV#gtq4!Z24H zsPLz)yk-)@S?HHlPmzIC(WQ(~LeapEi>;86z_QBrTIW9s23e~KDtO0gqn$k{i~6aS z%6o1MbLlZ>w|^UfJysd6wGe9I+??fN7-*%jtYjic7*o)nQUi*SjH%KG#37cWGbTdV zB@q`PW|JeGj@A^Lk346H7en2Fh3KesSM)|u7aP~aXTZQXw+04k?EwG13-o%JOEVEV8}R5VilytVa(@O~LIxvw@Q+LfaLJY)1duq* zSY$GCYkk+AlSrBAI1pHe#u7|(EnKG|+G@Td6sH5R^0_wU5M5t0P|L;8zBim<77V{N z*OhAl()vXnO{_4RT^gyp%m~Kp1tFM=Wzvpw5JU117_x+XQd~l~<{*8F3QB;sfpEAr zjy$y!A%9YM>wW^08tUfW7p{zIE&EkOv_`~!QmWEW9A9Q~{Y)zrDu4U@1jc*OLt(JI7+K7{S9pXuSk?-8{2-mA$CZJss-_mhw&;Tty6uP2^( c;)y@RKk2w3sF{wa(f|Me07*qoM6N<$f)E2;y8r+H diff --git a/TMessagesProj/src/main/assets/emoji/0_1230.png b/TMessagesProj/src/main/assets/emoji/0_1230.png index 1907ee90662967576add218c37916b75ebe0da2d..a578409e573ef51b13c6c6811a95c2d81c377edc 100644 GIT binary patch delta 1931 zcmV;62Xy$<3YZU&BYy!GP)t-sM{rExt}*z=KkBzJE>(^#Q;X!WDx->5*`+nnl^5!? zDEiJ-HCBr-Sd%DCh3vE^He#Uo$v)GU80@qrGcP&$$UOGLHYiMk=B^^rn<1NnLioiq zG+vt_KyEBgh}xVM?Xn-skQ$L{9MqN+A39@%c1oRQ4fDAn<$tLe*_##n!6g68FaOUw z@Up8sMW9_q`y>jT5hQ5WRsB|H&#rZ?i{ty)#>wDo%zzYOF6-k}Oh;{m@YV z)J8X8pN>=qJ7uQ)*l(g`2t;$Z|KW%J<(Uu+2i~qYw~a67z*kyNHF#k*Gaw56>8?+G z#B4zb5++8>wSR?9fye&VTmSIGzM)(B+KN|PVy2U3|Mk;#c6wfMhSz7jAOHXWCv;Ly zQvg!_X(D|#4JG}J@K&ccz}3#X+WNKa$fkMtoa+1L*Y2kH=(f=}g{K-h000IFNklUZ$CjXNvn-p8aAbk@^*J)D#g!Dj}yb`@PZA zk9D3_U$e!;o9mXZG#07FcbdpbhuP7OS9uy`GxA%6%A;v8i$qhxU)RSrGdzqQcKVaS z011i|&n4CRDo(GSR+||eC87!2_f;{CmXBv}oPVF-8IFd-;a8C!iZl*P>Pu`Vl1ecd zJ;7;qus7^&C-2fFKc9`OCw)t|Q%Yyh*RAcm$~$036XoR893M2vIe5KP;vSAx__& zG=E!?%~Z=eE;#oylazGMNy^bNhXd=$Q~AU#peMgIc>%um3Z#ZLHV` znb-mb%82w?T({$5Y!*VU@eznY88Rq!pMR0<5K0Y$+PZE+Z_6U^gZ;!7c3m@+$hEsb zu++Nkscw2Y2!;XcyHK%LuLScA6)Gz6Q0fAV~apvKAeG%H;YIMJ?Gr;Z6FTnFn&x78p>hb=pbPi@5` znUHC+63hVNn@3DOOo;jtO-vOwZFx@oO``G5Q5a!QrX6=eUs@=iJ5vNp0YXWIEd&Ti zi4%?v7wIjY7vuRXFecB7`|PW4&~Pi$-^jk3qg1$wR`vD`EtCxmxN&S=F9nb zyjUT_CN9wvTRVjk>lT&j!f}CEJ&z%`_d_ucX#~J{*;zeOoAikuk0J()I0M2qhNIi% z^449g3GM0oa=Gk3ubQxtzI7$PO%O&Ht=V)sne{YPtI3lugb{`y6oRNuOeTnX zVC7RHwoSB|A&5pY7FXCXgn!{X9Z25{1lz<1a%`KZa{^K-wd=?55sh^_FsRe-xR`UG zQe;}Eu~0%7Ky>TX9DKf-NEon8YQx|C^+s*DM=FHaxrCd*L^)Au9H&!?sNp+{@Ao3# z7Z_&AN*tua30?!j-*b|&173p~`sew#zaih|^C<;^l?eTslRmC_1?eF0g@zBKQRN072}ihLLV*B?7DSTO>bgiU)^1Y1 zCYGt|NJQ7M^(6s7bbpO%fQY-4YPG%G=_dp8YPx|?z2LO#X=P4 zI`)g?t32W|!Wfim7xO8G(=4AqBy&6Iw}_p~4Wm|L#7((+x0p@vdP&J>00UcS1@VDLh~S@9?Lpvi9ZW`nB)H2~QTeBgY{MZHLc z5fGaOXlt-s>b5`bL>QYjphsv6AS#u7#Pb%6BQT%^M{ZsMV`bll>X)L%zZvfobu%p$ Rs{jB107*qoLk(sDG%a&CSii!okte(Mv-^ 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 delta 1614 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 delta 1561 zcmV+!2Il#L5vdH2BYyz)P)t-sM{rCyXQnYQHF$)PIYn7MI5%60$YEh@&5vhAdcVw? zcR4aHIA)~EvXeDqp3RbN$De>bH#RyoGdypz*PnWfVnxc5ZZ|P7$eMk}l5jp-hdOSu zDkdi1u#51cnoGB$G_0g{L&8y_Gj7&sC41Wg*-K2dmD=Ofsh3B}G z)0l7Az@~s^Q`((&`PsN39v=GMzDs_=H!(3kaI!L8mA-&kQ-sCKpnz~&Ohi6DVoEwq zJ29bvXFNAJ^Y7}MbyM!((zTU#S&7H|;=*5z%1|W*IcTORPk}ZO1s5_@R7*-AKxvz6 z3Ac|JM0mU1K~#8N<(KDD8%Y#K6^$$;fkZOcOwKtd=R|gV|CiaXyT_WP3TB4=yQfE@ zRK-1f_jb2cF8wb!svR?GNB>DsyXw`ub4It`s~mq+bAR0H&VT$HeO|BBK9Zof)=3#2 z9S;STZgI(R_iy1G&tc(X_qdqhYL3{iSrf?5!BwFyy1LG)5(eu*%C`bJj_cN7&I;2~ ziy&iJ*0)-2hPp0`G7R9g07OwFTfIC*Wj>b;LzD-vV2X&67vreDwq(&D5^FGEqo5=X z5jiS3lYf|7kt|vfk%$pAV4Vhu2=$}vKGw1ri7WTQG5{nnFo*;Sh^@>{s=Yykx~Zg@ ztJyNi5+#!q0SPBxWskx_(xoJDlH}Oa{nlSB7R%)l?=ye99gk(wUL{9?K73VBRh4QS zM>}BSSt3cEf+U_oq40bd@(M&S9pGk#6rwJ`Kz|f5B_!|wK4o7_u~GyDRdK@o!Neoe zGJh7bh+(Q+yRF9e_xEwK0PnRuG`Px3QH5fq3c}JbWZnNUO9Xq}pAAGqoGOB2Wo|0y z$>JW{v6}rD;8f@_3$ns-u=JVlDFU}JqU`%#!G2(vA@JI59s)|c?eUlg*&yG@xo0<# zOn($g$cL<$N*FQE6xny=v@J(Ahrv%B@8V+0Cz_C3dF|ES5fq~EZ>t%KCbt$%%wmT# zZMT9)G4@u_0t zKfXNvYH!#i;>~73K6@LqxDd7TtVT|?>3;wUezV*D`t5Fr0#Cf#co)BZw>PmWNEg0y zn|ZX(HP@7|C2{C^I~;91$;%UBUR60KFtuhWi(A_@9eT?`fZC8gM1p&(sGQ~o_I0MB zX}f{L5d{xP94b70!4uM}D&bF@pJpmfP1n^pRfU2$R7t@bM;%OIy5?mmo90QwCV#_V z4#{*RNwYB;mI9+_oFGItM<=Gk!NC(aw*hSANkV8rvs%jKGSCnsaUi&B3&cP}NOt2( zDW7ZCcDO?;ysD)C?s1NJLPO+t!eT(8Xj6A;bBO^Vf@Y}*&49*GRbImOING$KDa@dm z=eX!aV-N>t0}U@zq6Vj62=E0b6n_rD+1L^s6afa#(byykwn7|`pbR;n<2c&JX{jjH z%K*JVl0szX*wBwT93r6s=$Ev~48=-xP zATU7?xQ)w?|2N{MQXhi`VGJ%RH|3+^^*61~^XU1zK2F)Le?C2RS~s;KbAK$iI-}9^ zXavXFM+(B&hvCm~IE1B~ce-k=QOeKn^VxQ_+RpUv&%-}}NS<0bU#XoZLZWyYJ^v&; zkEo#E?^8{uoM9-#K;kk+?8gug0hmlC{cK0A0|DYDmQ(;p{T&pL42Ng$?oA7VK7a(! z>NEl|+yUzN`rc-q!GNfw<$oa-1b9CP4xpL$Vw4e={TX6O7G(mM;NkA!fjG+V^Z~;I zb1)|CEvbLNlQ8MG-suAd00$t238~@WxI3%9-N%F)Kw68Hc93%S`OWk76$(~NBv=Wr z6^XC^)-bAPebkXTrp0MJ7Gsj^@7Fg+@%huI&y-IYB)>38=lKu#4ibkAUb(dN00000 LNkvXXu0mjf$T#Sf diff --git a/TMessagesProj/src/main/assets/emoji/0_1233.png b/TMessagesProj/src/main/assets/emoji/0_1233.png index bb45663fa49499e421618c12915a1215fc665880..445642b25328cb1ae39290c87a176553f94fc992 100644 GIT binary patch delta 2035 zcmVQiym>GA&Yx*`qdMR9h=bds9I{HD8>3N-K0oE8wa~fmAo%sBkJnY~H9*D^G`G zJ}Na|ozIj=$8&rgz7UT7S`)XUMjw!J>sD2?2yvGfsiWN_)T&AUvvlBN8l9<=xaobGXv9m5hFO z?(67LeZ|9=J6QpMHvj+tE_6~(Qvm)eE&de#{{9J7pHp^uCi=ww<)p(!+wJ^m?5WL^ zsJ+?yin#vl=bYQK&&{v)0A!N@00ve`L_t(|UZvJ|cYoSS8U}C+goJ1|xPVJsk~rn& zu6pnE-ivEVvfuwZ>^mb+SR=f9e4k?s{4u}t%sU{lvlfQg*}Xj3`3GS>9qpWmm&`vP zj>dm8=Rh1Cy|)9iTPp3Iixbo5y~Iu}2o{k(4E&S15pcTmtb) z6u;y3?#NvQ6uWp3dy4=8MJ(+yC*pX5*4nS)x_`-HYAccWjsfIcT!|_bCE`jHjlHSKK6%6#TovQG%!1R^zV;DuDsm1zH|Pxlt6Q7UoNAD>0n{0nBt_ z)*QSv3>Nx*t8ZCWzkkR?6Il+7>3BMw@S~*T5BiF-X4Di!fZ#ZmwQVc0(F8J`OiVjj zvwwWw*Q}ZnZUy(i1Q^?DqzaS?hMr7<&>#4afo4IMrL)`%Hln8y&)?tQUl$73*Toyl zu{454%3$CGT|xy6&FQD2gb$VG@#7;fk9#%LwP%;Hf~(XNWwm?&(X4|_fl0G$wNYie za;GB`K-_Sg*|WVeNzj_64YXxwnugbrM1OprWn0gU#$BV@VhfJt*gVfmoNo4duI+gq z6~;pwu?{zhOt-?es?X2Q)mEhogk^#t34$s}Jg4jCpXik4Xja6LoFh7!4v#0Oj=Ab*+# zr^a!TP7yFZx4n$2z)(q7;`tsB2T{{(1q54>hXu#xB-39k;7F}{Ak;Y@vRDu><9^hM zWMq6E4IsLmA?@^lph3hz ztAaOM`15)|{Po&kK49Vw%|dSOXXET5AdNG(o2NYpe_V*UP{UiY4_s!G>0nUVfX|kAzAfU#I$Q@h}uD&7!&o*__ zGm!u$&zTf`mEGAOI$cx)6WwNRCq;NBu7MB_T`&nCR{JQQL5C=UZ3WkhZYR$quF5@~ z=P@Dh9swH@R)TI5&|#A}mBCnEwK~Jh&KYS#4IVnQVU(QC!;7|n34fC!Vq1w;6<<5$ zW}ZnAR1Z&sD*v3%Q06~9UKOB(OGe%e6Q?pZKxmy*5ro6AruJ>m})L|MwFpQun!X|l)oTh zdyOGRmSe?7^C6SHBFmKR_VDe!OrE{{BRta#4LLa8YL!iAu7COjL6#vTL7(ls9VQJ1 zWN83_zIW{L$9~PCX$>;?n9jtRw~Y8{K;Wrj17DDb_gcT!w=B)Se>^@u&gU}mH@1Qa zjNl%KXx!aaj_*H0?jMI;luCC$ok_g86$qXwGB9y_+o%A^R$F*J&k%M$9p8Q`IBPZT ze%~(BfZRcD?`-hxCLP&?!Q;SNS+5ah?Pa41M;<+nm4PQ3+-IRj1kz|#_M?qlSOXF4 zhOt%y<{E#~=!6FBel0Kx`~-w7r#EMjNHFpI>mH5Ye{vW6L-%jExOJ8_{sSY2Qx?J9 R_#prQ002ovPDHLkV1lYqv=;yX delta 1632 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 N002ovPDHLkV1jLIS&9Gv delta 1481 zcmV;)1vdKO4%!QlBYyzWP)t-sM{rDsSvN&`zov9pb6r(VI4*ipHg{`jTZ+hkQ#5Ep zE;whVaY-*YW~7W>KPWCeH)f+eZ?iRHp=w1gid;N&NGdN^jTJ9Zmt#y^HXF8rVQN7o zvwdE3M=FO{Ihklnu6J6FT}F9NJ6}5|xrSq(a8W{axV(#IJbxSsJZ-JUm2AV3YDjy& zkYYbgfW%dX#=nnfOeqjHWT1diFfUk+&908VntAT+>spG)S%<_@g25XA0L{Iy;nvKo zjd);=$|65z*~zz@6{(~CrSL0Efr?C9# z*LKR%_1vQCEPtp)u>b%Bo=HSORCr$HmuXYm$`Xb#V~YqINDQ20_D!4DePPdb?*IQw zw`az}t_nyZU(X|3B~$9B-X8Z9^2vXKvvwS4pZ%4f9bMkECV^J#CW=3*i7&+@O;K7R z<)jt0Ka${5NLP0ZSVXU}ByPEai6fi?E=k$HcvEqefk{Ac5Gkg2SBx zaB&+q>4LAEVRZ~&@sjg)gA9B@h4@oI1H4zKh$a(W6qv96NC5(jF{QUPG0s|o^F>iC zFm)Dj=%{pH9@Tvt5Ez4_SU8IhBVL;cIj*bc^iohvG3TWP93tR@gc#MG+^nEoD^qPC zivvD#Ab%tXf8lZEQrvJ*P)3+ar51)$i%YDv)PfSzsCqS>Vnql^63`&GP4qFCf}&Ta zuvj`np3n2#iI_Tq<0cBs86!y!3Scz%fX(}eY^KlGE84ZUA z!*G-{q#%Z_Rsc5?3q}Zr@#JD9=Ak}?YYLN+CVvEhBCZ}SiZvsN;M~mx9}T@ihWRim zVTvwl6j4yP&J(5bVPM1%$-$K;MDfLW^?=6|OXk1Q+^@jiF(2jg;XFyaqI!?C5e7xV zm_{!ar^()syqFin1!7*Yx~y`%X6n=9t-re?_~Q_n9k#3`^1Q%g+}cvg}Z~X zr+?kz@$qqyK8Hp|o2LRk~*{L(dOKsSB0Y3S}gKcg`^R* zQAdwUMaou?pLn34jXa2nI&LMp|MP{F<;EBRZ+}XAAO9KA|9XY7-GedieC>D7n%DO){#mcrS63Ey z@Se`qkHPZuMZeK{bfG@*Xh3i30@dL6(iPECb6$yV~%1 zuq;`_3oO9e3j$#I+^sY~SRc4#;K;mS8W>kP+F-~W180E)&PRrs$2q>dJAWe=U>J`d zLeGKBJNJS+ID(`9-Y|U0vgrc=9UmC`1P>qp!fBkn7o(evr?dNeF9FRf(-0xld&e~E zzSGBedUyBz&Pm2_JWRt05&)t2y9XQ>@ANVCx7>r{h?(O)2tW~-z1>MSn}PsB1jp=t zRubynQF3?s=6v-t*Y6B!Jwl*3w14Qr-2$>{_w7Dr&?KzhLvS2dA1?ziyPNjkRGfbL jbn5w3!TyHXVLks3%D6E)5oeXu00000NkvXXu0mjfDqO=H diff --git a/TMessagesProj/src/main/assets/emoji/0_1235.png b/TMessagesProj/src/main/assets/emoji/0_1235.png index f2189b05288b448fd254cbb155634907123f72c8..a747c00ca0773aba9da108daded707fba3b557d0 100644 GIT binary patch delta 1763 zcmV<91|0d{3-b+-B!BQwOjJcja7=VpGBqzRqj)APH%==e9(Y+VdvQ-JLuxTulrk+U zFjkLjQ8a2%IxHn2FeV;0GdLj^5-n4Xpm{GfUz{mSgD6acGb9`|UYnC}G%8MmQ#&X; zYN{eST~IqSRzWvgMLJ40Fhw#fJ7uLL77#!!Cn_Bk8yFcbRDX_UO+FV74LK+xVoEzQ zBOE6qBPvdXL2t7n9v?L@Fg|LlGg_7m2?Y*$N~j)qo5 zJWnJ8M02=Je8UqbMnO6{qI@SgG&O{Kb*rG59v?JLfyYrvN#^C@!nm-4R}V-*LCm;{ z(THkd0000UbbnG#Qvj>cCNi~-4I!mZRL1LoX6@c~M%3%cpzCRd)#l{6&q6mB%|J&doT1(^8RnLcV;9EvE|+4y(o@3L|^XwGvYY& zB|;{X&$cuFBSNX2xp1<84o=&z2_+EiLyHJP-mm8=QGcuF4I@!E)Ad#;* z?JK{XbxLiycGx%s5H#6vGAuWdJF%G^9u7Wmp*LaN(RAO%Golegh;YXriQ0>hi=$=z<*bKA<Kgp;G)L_t-j(KI(M-3w|R5W&nh)b2;cLYYa+uJz}@z?F`GfVCPT`e65Q^HLb ziiD_Pg}YW#IMM8Ac1zQo;NNt;z|>tgu7WPf{jN*d^BqLF-|vjB`{RKC~gbl4-nTQX;WiSf&u{u)3q8qrWq4B8Fmy>LZXqkB7q28tFlF0YF~(1ml0&;PbHZt zJ_S~?G<8-)qC{BOwILu7Mpz&u^0;`P>(2bM$zuMlua|Q|RC8z*#lHlhtYMgZ7JndI z*CS;9ZY~UW{j`u+4e4>=EnNNn&1Zyhw6&*wN+2MjnL7mW{*GtW{rIz#03h!RY{~lm z?NI??8kIBxEe4EG$kUs%UVq%bfuM2Tp4RL2{hzlvB?7OopU{V%N>=m7kB|H1(qY0% znm^4y?(dfiiBO^?Y@e)7=aYCa^?yJm2yP_OW;dl3z9&R6@bhA3FVO^HU{{l)vHDaH zO6a=TNF%Nj!lVSkpDg|dVT9^|*g9H;fwpO3|1xzQ!+^mMRiQ703+!;}dQ03v@Ogq5 zN0;X<3`0qXATU%TFem|pjiS}aY!hP`F=1b3Dkg3tagV^&5fvSH3D3mQ+=iH!J4z4`6gd`)x*5Po6a#a>D}UAXKreSu{KS1!n(J5(8^t z#OUTlo83NJmi2rajcK&;Nx7QZrTl5|ec{B*%Sb~lh^!b*|L0{&74d9iP=XpaFnC5R z`2OYwznOlPcO!+(I9%cyFkX^uG~CX3+$4!Vhu9~)#y@v1!zlwPTPgqm002ovPDHLk FV1l>`5RCu; delta 1485 zcmV;;1v2{c4c`lpB!AdYOjJcja7eTUOMbzaVLCJ&5gZW@O*$})Rx^fCF={;}LnIS*wRQoPXWb&-C{9wTl)sUzuQz%F41^Ut0RT0000ObW%=J043pCH-Y}`RTZ7? z<)^jh<hE-utsRVYZA zq9hONhg~i@b*k_mW)!-E@B3N7MP*YP%1!2FUkv`%FwV)eDup_0XP&2LKE+By;ebHL zs!F4wtbHgT8IuK_*eL}H9rx9WPPBbI=n*Pqj6Y)j4;ig$i0r$dbW; zd*zk%AAhLcG-ZOjxdxvy3582->0G;tuR~#mp_xWZ2p+qxUK}yd!B{QtW(I=@g1|6> z&`gpv0xV*55;`?Qt5oPI861K{$mkPJy{J^^<4`IlTbwNhl1uffEV>H1#$YG}BU(5J zhf+cznOdRH$0puphQ?$hAq8*{k33kV;w;kz>VI%)k2Bxjh9|hD4VM^UQmz1f)DZ>- z;~W`#840k`e3l&Y(8Rv!lq%G*9zo$y4;YLK8AXkWfnL{?hA9*kTT5_}hCyL)3}~>V z1qw6b0^Ka5#W;^lQV+f!Ow!264Gz^IPR^?ToSle7 zDnQ6%&SPfm)S-3{D$xWgDI6wx69tgTBofAvLnR%~kVa7o>c=pof$A7^YbY86G=BgJ zau^9?EDefpVv}+8pbn}`1Co%j#55z38q$DfHfkxl0}){;Ac`2H#Z0QgOzI{<-4H1` z!T_1aF^}LQLnP$4P0do^AW1@bpsX;&r8vPj>Y~AsK=O&XmjQG&E~3OFNstS2L+4;0 zx+)h)1QsGmQYHq-VLv(pNTMhuB7Y`MG<0%r2WG*A5DbgQ+W!AWG_}86*Nr8(`mHrv z_48;nd#8)V;_lAf;qLbG^0e1%)OkO}zc1*#z0(VU4#V~1V{WN3w0iH71&&)tbXV6Q zSX^F%N3!(FGijb)0vHO>EwOmd1-5PHn$u>5f!>sR@&n*TE&!Hg+2xMLDSreq-A^8+ z0`XH|O)VRaA7|5pzy^@Ok{_P}G7uIye*KsP40*2hBP_J8Wew6WpJU;`1Lr@a(Zs{@ zHMT9Ykv|Fn!olD3IULO&>bSP%01{hb(P@Dx8S;3^)b4%1sm|^E5psNCS{R@x9H`{m zIxG^vARXv_!Pj^&Kl*lm{YIiXD0upX`9}saM`^U1-`6okqkx5=Joqc}^_G0V`fjX^ n^P|JV!z1FbgzW>?XFvZ1xM@F`J=;XT00000NkvXXu0mjf`{SP# diff --git a/TMessagesProj/src/main/assets/emoji/0_1236.png b/TMessagesProj/src/main/assets/emoji/0_1236.png index 7eb8917ebef8e0711f09e34b779f397d15b00576..b80c357b3e0157b32e0dfe4e1c166f69ff249a1c 100644 GIT binary patch delta 2263 zcmV;|2q^c43gQuvBYy!hP)t-sM{rDMWNBbuVD7RXaBy&8VPSD^ZrGU+p z_PieAq!wFSTlKpi*q9Ui#3jm!4cC|w;Gz~g5<1nE655;;sefz=!-NmWi4f|p8~em2 z@U|c3sTu#wF8IJBg+~J7r5FClDOxH4WH15ku^rx_7WBIzi%$ikWC(UX1G91plvD(L zK?A*i4$qJgn_LFAdJkAMC~r0Z|NPufB?14@K1Lq^`0>X3?Wa2&0-%v)_QEzE138hm!8h2$umuf87(5pfYS1=U-Sr}~GLB0000cbW%=J06b(I{`H0E6X(|G=I7_<=jG?-=iD;+ zyKhvoh|Ia8td492RTVZK~#8Nebsk++<(Lx1#sIT_L|rUCXnEe5a7Zz z_1?R-7uS*s-1hyy!hL5XE#k7fXY=^UAD*AjyqeMOZO-|T$k{WVle4qaqo+@gkB^@` zc_M!H^V1gMXN(ZaNj;iRoHQhH?n#O-YYHs_2$3{Rv*5$?WDD^lMmZNI6T1$|xJ0I_ z$TG3-E`N9y6%nhg9mL=bMl4Q86NqEbGQ+B?D^YbZTU58V)y2bIA%Gpkqa&1Oi9MN& zjMPqPNj=q9oN6|!77x|c)z#f}L3Xzoy!Z!V#DNMCLq=T!A^A}?o8DayhZk3n#qb_$ zJ6pU0BAtvzqagO;I*ys?m-Ell&sVn>)5jpptAFXVlzES>#5qQ>4TPP9IZMNsspe=g zn=WAW?G-2N&%+CI=Q!b+CeVQsG!GJzyQKOw8v@Z}6kQCbCI~wSk3|63Kx8;f339{5 ztVcw_=i%_>PU1(CIv@Z+GE5DEO!XxY5A%6bBDZue=xzhtsjOW1PRJAqb9R8HGJRKm*dOJ%dsX~d>h-x`RENZ zjKDC`+A&};BNUqrq5C=y0Ijf<_>u-mk_1NN)Vb@%NrnUg2463O07QdqCkjZyYs9`= z7$x%5zZy#m{t0Fq!9qepVWb!tDaqHv@Rz#0l-m|d&Du`H5K;tSM3HTWj1NN?qJM_y zAsBi2ato1XlxA@VM&#I|i9!22>3RU7>*H+%VtLMlk%BR?W68yB4M1dF7KrA1?sD5k zFhUp!gO7AHVVcf77mTh3>;%r16jS`P1NILGeZs?@*BA+GWfbX}o*_=OJsrfPa9r(gtWZGSUOQ%WRBU5)N^_%sPl_W0`ky}g6S-wt|&q)MuZ zb4D|g7FxPvbyr<@=8KP7o#rgT_?WEUBy~5yPG;diZTzkA@-Nh?r%wmBWtkUB#8m zriKJ1Pyz=m5L;;usb2E8^9b^+Spx+IAgzstfSq8(5R`CBgCDR0fzj?oir&xP^9Z6X z&@e`;n1<^O4PD6kp2vgU6H46+Qg5U29F%XwT zkrBYr5)q3J8iSAJH5ZzlsIH>YB7tk)H^f9-6h?IoM4Q8=$NmqGIU!m|(Ak&ax#1+? zM(uzRazhk>s3;?FI{OA}VgSP4xgu)#I)A^)ih{EufNReU{#?Aa2!H$y(_G)wb`b3W zeWi%F5DDi#Tx>54jK-Kp6bykt)E?0e;$YAaE^<1$moqwe&5-ozYF^@9rwMawsi!|rrH6NnxyQ%~h3rI=Juze~HH{RO? z>kuF|Db?V1Kj-LvAE#b$xTQT2)06 z5<=oQKHWG>UV`$2Y4NM%7$M2ZB92LzMAZ#M7^KW7V|l)57O(j}B#M0gk~bVadQ8KU zpU*@Ak#{R@CMtvLRk!}*yN^78aP+t58(WM; z4L?t!&=W6eMxwUC$8|n%1&mF^TOh!&bT2eAMfZIPXG!%}-~<0afcj?B6R|oXE||~n zJ1?;YKJ@d)hd(wE=YJ9*f-5hfIH+1+y>Ok4#4EjhB!4I-7;ZdlBl-=5rhB*g-(9}i zbij4EqfkPnq%>icv@oi*uwK2JIJWo;$3-P!riy78GyP)t-sM{rCrEGs)PDk2&dIx{UcFDySeH(80uN>*qCMHvPJbf=cw<#riN~m+pI?p2 zM0mVTMn;2lY$85n#jkm#flr@r3z3C@du(UDl^m68F|L(?$^ZZW5_D2dQvjxG=242{ z?Hn~xs>$T$cGl|TFEq{o00a9;L_t(|UgekPa_UGBMiC&42*#eMEOK!64ZH9EX8ZND z1lMaA#Qxngc7GvJ^wHNnLzUh6UoedNOf>vYf~Xrz1{-EDn1uaXHT_`o_V!lc$Gw2f zAdGHF0KpkHL2F5O@UK!@oTT5srW0|Jga$(T4cy< zHs4$@fZ&=U+-$P4%(HVTaw3~wi7^~(=9w+a(q?3#X@7ikgjXg30~CbK$#NnCPBHPH z(_o(E2rL^5M`@-@4w(I&Oy)ThN-1eAOOPdN+OVwc`bXgu#uyEYl=d5xBJ?XVdaN-5 z7_AkMav7l$1%jOoh(bc|JlDTNcK0{k{}NDG z6?jkQgR)W!BdYhq;k|0MBu;wU# z5Yj-6fW%NBt)wP{p{pK3w2lFXQA#TO;(yi|G#$)#^d&nCB?pSGU5H7iEunP|L)`AN`Xev@Ap2OYrsG+wd5l~=DLyjW2rLY*i^T$#(SLQp zdc_8o z;S_>8F2e?nkR(qDv4rE|-i#qw0+uWoj=+W|;2g6{A?{&7RBqXM@NyI!K{NLkVvGaG$9Rc4njk5@)i)uMdVgo%W{i4ozQBLryLh&yZ?nqXjHbaZrl zb95>uChESMTU%RRUS4`_aO}UF>Ajg~XlTxwc$HQ;>AjiizJHq8o_W!eZRWC#)|qk> z5fSOUndi5Y@XDy}#iQY@hux)r?7*GPjAh7#T=&eUP&_b?e{k~8t{oW}?daY0)U&K; zK>`B zZ6SPSW@Td?b9g6)j4_(rs3(Ffkc`IKtpET3DRfd!QvlUS=;!|a=M5p~b${pn=k~wn z=Odoy=3_VZ$*O_FwA|&Wa_#TuT8V2*<`a z!LehLxZF6&lOEf{ya1vmU zt6FVvcXlR?@~6+WL8mib*W#%rN`%uOq~e=Z>vRS; zAb;#SmQkBtfByUlLPrrWiix%&Mx1cf!nTLPn1T4TkV0)NCi%aFG50tXgm0&*=rO3> z-PHz}P~74H2$hLTKzNq#z(|KzP!xbE*0tEx1op|iB~ef7_2KyH>gsqr9IF(!Ff=jp zT-pr?GX((whKQ~(E^d(#?K$JEt|aUwk$;s~OX!qL-e_@GPJ(DdMbs!J@RBvElr$O? zL_v*W0?|f%Rt`Kli8fY{;cy)RL`2-H3DGrD2r#4ord~``jcQdRP|DP@nDdWOfYdD~ zEhI$rEC`K!V%fSz_F!#F*p>!1A06B$M$*u?%}IT(YUmykv4d`~gA1|wsIpOcwSV_$ zl^7u_qs;2IN!^SX>K-ZSww`Zn9Q?Sqxv}xp?{5!QiOl#?!eN2yXWM|HV$l!;P9LJn zYt&dJ`XID1i)`NuJX0Hb9cW{b_u_!8vH238*&XR4l0Z-*a;%``Sun6t5KE-)W1XVL ztBU+Q(8NpeM2W+*}$?Hf^o#7%5v z!i1sr;WVzxXCh?)dK6_;1o5n|YZ!eivQ2m2P=868rFy`yL)3usP!SkH8-IrfO9F;5 zk9?DPaZ}ye%m8B3Mx)hed>JGgV)M=3D?Hopbqk|p;ewH{3SwzU1Ytp=(b(4nR;rBG zFEgS#iW3W^9X4%(P{w3wIF8QdGP{G3v*O@0%FI^-SN6W`F(6h&c?2ApQ!W7V%a+kGB$ftY?Saj+HP3V(^K0K}tVx77;B zJ)#*m8W$IhIrUt&RanAgrsII%VYl1r5|5Twc45T$T1sWV^*l$Y{2)rWAtlUqSkMhy zjgWZ3au>$=`AJKpD?avfi0`)Q_0;FYw(zLfFr!Hk12H-vmWPdGZlny@vazxdbsUqF;x|gvh*<1 z=wQJ7)YHr;@A)@k5j^!5GGo{d3753uXrN`gag4v3D3PR08q!5$tO(g z5CTeg9--kB&q5Ay5BN*IksP9O=r~f~TnODuJPchS10ekMC13xWc+s2rKJ!2jf)1BG z5PFCVK#GaY?epGcLR?{R8cd`BLUqvR*AcrMvj W71NZqKOjJcja7^>LB8W7Y_P!|j%v0>MAosu~=dm@OL#g-1Lv|{8 za3Fs6y(DlWe)hj8_r4|g!!h{LXh#`Mb0~A|vLA6KcKXLU`o=f(yCrregMBKB=BORl znG>*b4e+%eXC+ggL#vuUrlm@-lslk|HJOAika;JFYao187k_HwrW=Ar1L>?9s%r|@ znHIHm4Bnp?onHuwP6htQC+@Nw^Sdnj!6W=ln>h zdce@%UDUwK*2TW)Zx22I00quTL_t(|UgXx-ZX?GM2H-<540s@rTzf4FQ1ErfFfj+l z92C~?|0=E;Qp6gVkygI-PeBkhjc=-}nj`)1zY(k3?SDbK*1rR~!}jR*+d1RWP4CN$ z)&92hr?c5#klA$VZ#uWbFCpFb)5~;*0H#v>W#_i{>q2i_q(~re4OG&<`DNjo|Dq$@ z#y^x980}x&#n_*{g#5+#rx0|$YFM}aZ2F?Zq`z7ESLRE5X>VpgaKlB>?`)RHT+2b@ z^PcuPQ-4@lNNTup0qJajc`pa%vKexS`mhuIPQPCih2T6!!$e>} zD&_3J<>5!fpe!(pM8{E-LPKc0D9#8dkYWMS?SBVlbnglmZ$_k!2q7xP&5+`PxK+UV zsEixCD%gc02;4VdB;tnd7JWqU7mEP0ut!#NGu;3Qp}Cr%l?M)iO3dyB5NIqw0leH+ zx3QTmSmqW)hY^E4m*w08L?t{#q*5?J;58oewmV@HccN)bu!hN`oZE;H0SI5ie%uMH zaDM{tsc9c0m#B%-6t=P6?RLom>X_T8>|URrsnI(UIE=AL-s&~YgDH}ljHhb1hNE3V z=3pSgM6%N+TbVdgj5Y40*HS{#m6n18^AdvuB9)S}DAB8x<}zaTsGb-GDyFLyk4a$T z>3A0q!N%rrU1wA#GRntReK(yn%vP`uCx0jF!{M-=U*nSXdYvdo$dH;?2&ZAJBgQFR zWl{yn;dIz;Piy-kEDopbkL~FYIe1D!shC&WPwP%-Lsv9m;xOHAe;l{d;zF!v+wB(K zABc)W8tRzYwf*e2k`Rf=aW?+`$NsoKO`!=8+dsYS-;OJPNmzmeS6;hzAWQ<0QGelh zrN2KOkIyF`0Bk7`$K%`UvdqtfPV+(SKnM>*lVy?P+2!m0?K#<$NPtl;U-x^xE^Q!8 z2848Kr+Oo}#%9DUx9z#>+SM*DlZDgn!Rg3JOp)MfTsu=CIoJ4r2)xTEuEaUE7buxw zFLZQg)eK}H;y9L?LO=7Lh~?%g*ngfQbY?W?JgFtVt0+yASZ9(2_QkOAq`!kUwt~`- z!=0K4A@G4|jJTFzGerpTDxlg22SLV3oVL1k1W^i?I~wk%BkZBA^d4Nzyc` zCm121h*ba74Ob}TUIZ*cLkVdVMWUW?7=$Phhv%VyGI?IXYmEXH5pxNEfPd5zgTR4+ z5yhc&z_90wL_ld`rz*jTc$^A#P9t$KWSBTP7&(-J!*TGD;|Li?LXj%0k+>TAY~Ua; z?*ag4Nhdyv-M_lCbkRmmXMV#)M>lhGl~GbompQ9eIkPBif)ltos;d$VNJgL*BblK{;0VRxq|@3!Z|PdY~@ltQ6!R4SGJwj(=;(|Q9Lc>ZJ(v3L)tLvg2g>zq{w7iRuF+^-wIQIzu*sNfm@Uf-7S*rQ!^7frb^iP& z@l&JO?0=Hr2SK~ZIOec}S+!dHx+vb>-X4sv=Wh^~C@~1A0^?ro3WRCZf@<$zI_^E( zBG@!~L|xORd`LRbOp!{CE}k0YZd`7>HICHD>!|?4tbV z%XM$u8{c$ZCHeq7{Np?$%p26G2IcVO<e zXiE@6xef@+vTO?{@9%F2c!OvT+rweIRtr3(SR8TJF|^T2)9Jv#=T)MM45dCNbbnF9Q!GjJGB#`I^Q7!t=M^&OYa^H>5s1wi zOQy4%Xf~TmBk(6N$0Xm>003_{(SVW}{={dln;S@0!*Wb(7g28@y2nu0;HJS{BJ7Px zOvc^P64-lR*(B=q%%B>cVH-@EYooMMLd4<-z&V}%eD;2WpkNdjUDQyv?J#NNHGi@m z7LUUdv_3oAd-v||2mh$75s&pp5HNI&wqu)aqzo9#NixJ`Q2_`3dG;CKzfg^wcqD=h zs-bMtQL%DzV>ycDavEgs6V=!|!1sEKyhb0Ja7Cye$~T6g*ZBoCs0>C~5$iQvlS)j4 zgaIVK95+aMwJM)5MEad&gSf&mmwyElkIU64TCr?rKAX`XdY3c`j13|)T+=pGgnJ&V ztOk(IbD6S_F93R%pS83!jvq6F2*XB+8eP&TGpL9;+222;>=UpmKt@i~(;5zKBGPZg z*Xu}&w9L4ilu5~&pC2rZ&$QE12ngjN|FRbmM^KX_shXK{wzOc#?SO?!c zL5YmOc>uUpuDl{czggPp5-|)+S;`5$i0p!1rh-e6ii*3r;c;DLiR47K2oxa#fPpxU zD}~S-lpr#L7P3Oj4FZeE9)C&&GdPH5I8!*n^+vTpMV82l$cOo&tyAI+8UzfF1>;Qg z(@|1`Zfb^r*pf>F&%oA*l2Rmo97mcUBOoIwCo!!A*-BJOcB`eI0uUwQBuOGJx`Y05 z9sUFtvz&wxjkuNgU|227arKpOSR95)$Q2RUI=o;y4HF$dj0@X{V}F#e6*l1Ffss%S zIgk1Sj6$<`lj&#_u5z+<4wNt$S0D@(#*-w8H36gFtre$tccal1>xm*EB2n17Oq7ru zQ<$bJXpBg37SUhGu2;N6$S6jPF^(K-n)qQWVIVlmn35_Lav(jtmTkl(2<#97SD65Ugbm=|`0OHn-4Md*-EX;&1IzsW zh#biCEpdJ^8a>T00ctQ2O-3N{4*B`rMCIb?BXV(4I6?}A lB7VNO_+IA+oge?2{{i%ij)mawk^KMw002ovPDHLkV1ja~yo3M% delta 1677 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 b=BE7vt)<8>VFf*}00000NkvXXu0mjfUcOvM diff --git a/TMessagesProj/src/main/assets/emoji/0_124.png b/TMessagesProj/src/main/assets/emoji/0_124.png index dbad8f10e12b3112f00761abb1d452742bef3f6a..c20c97e4288db97f72a90abe4c8b45615a7f17cf 100644 GIT binary patch delta 885 zcmV-*1B(2~42%bmB!4+jOjJcja7<=8BZ*WpT{R$lvhJ|=odD`q+)!>okI0000JbW%=J08p+m|NoMF6xaX#|Ey-l z=KlPsD(eOS00QqxL_t(|0qvCMo+Kd%#0}6Y829}j_L_40cYn_1@O5faH{jnAoON%# z_10T|Drnnh~H4SE>nQuFjh-tuv0m%q4shOUi z)qV=*VGN>AMjphZ%^sTo@j}2%WO@W+&)C0G*gkYK8Zqr-B|{htjRPUz@FV6P?;vyO zd#y3F+F9U&iI#`UMa*!~Z7T%32B5XyB%mlKl12is2? zPQ%4D3v-BV5!YJ!Aj_AlP-T*hkUM1|q((3GPObKNn&#pJqr_{`ohk*dWIQIhaFt}g zu}Mq0Uua#i;MJxYai?nW2|nx|nXpK$1Gy*?#(>O2@E5r8?b}K@y6nqnYDTGKRMmZ1=o~8LfwT5g6w6^rL z^wlq1i1$F88T2`I47H%2eGxuoY0BQ9+FTz*?|(qNBv@v`=Zsc&P@h5uOq2F*sNRIt z``Qdf7^0bAU8WHrKQ=>7$EcCz{SsuiHbV5cS6jI)rM(Nj?UBe#%owNHAfwbLhncRH z-6=l>MUR+4Sk1Yyz&Mk~zneo5M)*J&;ltnb4=`SHt3~&{k{Nl*J_-Ai3dWH`AAhJg zmTo>bg2)I1r_I9{^e|W#`uIa-7%^?aQyCuyQZf_BKNgJGDD)wm3`OeI!jFwC5i!C! zv)qhfaaj0`;x*^T#~l7O><6M(bbq4ky^lX&-_h*;U2nbh)>~fygbXpqKDH2l00000 LNkvXXu0mjf+p?an delta 1592 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 B`jG$t delta 1701 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 LNkvXXu0mjf9vPq+ delta 1466 zcmV;r1x5O*49p9VB!8k%OjJcja7;llA8}ScaW-h4L#bUxI%iHhHYg*EU{-TZNmN2N zUP(N3BY{6KC~qQth%}f<8BuB>cOMrNJuW6F92ZA7Fik5NKPng%5Dk4wEI1((ic~UU zI3i9xHdsbIZ$c<8A|66BEn-hcS1}!TVOW(sp@C>!j5L^SSAR~GUO3Ol!J3JD@bdGn zrI~dlgq~+Uf-R3?9dfXEIipCfr(Um~LaC1fy6^x101|XkPE!EJVovS0kNy=f>fqn+ zs_*@GVo|E@000EXNkl z6v%Nq?&qwaG|kNagC-MS3&{=otfwlaT#P<2#p85?f)FQ$aXhMi7 zItFK3cwY$9Ijt*dAri#~Bg|L_ocl$If>%ipi4tVgbxn@GI(hC*?v|Kg84`#j40{6# z9NP$(bGL*oohuO8^8Eh=N$)=&{u=Xu>DQp);X4JWUO$Sag+ zGo&RXKz}XWD}mJBIN{YGXfqQCWf{jMBT5ot=aH0rI=-1TS{GU<2msPFy+v{`-6;MT z;cE$k_Oi|5biYs2y+yFGD&P?{gh1A#8|u-VwZa%#9A_ppdxVfO#Pcpx1;!e=J8~Yg zpb7#ZlCVX6OtOD@d0~V>jH7VK0V4ItBvV~sQGb*qrp(HhKCGZin}9(Xp@MqkOdP2c z3MU~p;$@%iuL2`z0>t2qVTfR4GyH%Aff8w2HoK-|#4=^kGM zoC+0)z=0gk?_r`37{unV36uE!yibWBqZ%Z91p!9L5BED4=tDo)ryyt*l-XpE5R@os z%XE)?Cc1|sGa{lz;%SKRKtSP11_T%&+JDdz(GW3tP#n~tNxJ&>7xshT-K5+hDj3Sp zB$mk9ENkPB5?Kg9sZpX*6-9`f8nH?6wDu(w3qXQl0ttc&t3KEGT*6MPh6#Ej2-r}3 zt|YWc7=~=v6NOMAN(Iv)LUPzhtdV9V{gP*;9iy#;;-bhP;Q^>|Nit0N@#YB&UVn-) z5>yDfu1`JD$CEX}L}%D1Y>&_s5U7H*87AtEko0k?@SHQ!zwN0c2|_gGPo)t;Yc@hM za6?-H!9_r3NC?9#p$7>cgsvqC2#~~NKoI^oVgNb_jSLd5X2L+A8n}!xEj^w1%0y=v zCI;Vso!Kncb`YBu00hLCYll#yM1MYeaK`>}cOA#~y$8xuXtJ#2z%lZni|6}}dppIb zwe+54S;ibF!SiD2;-88M_x~DLE*{_B-kzUp5Gfn_`GPzymecRt@8bRoE=IDFh3B`+ zD}@yIE5Th{ZUO~)BVbEmWpTgB^1`cMkt>7SEwEm1*Q8t??-g+&Y}ZJq0Drs+YvdnX z>+M}*`UnBbC|sMN?G>uO+7Hl;2djSGSY+v zHi-B+9U_(>D0dOwAlgxPXfuw*wmX6w;9m$9*k#MXt@!!l$4}(Pz3>WJ*zf260jIt) U{pMd&N&o-=07*qoM6N<$f>~Usc>n+a diff --git a/TMessagesProj/src/main/assets/emoji/0_1242.png b/TMessagesProj/src/main/assets/emoji/0_1242.png index 2cf0c6110bbbb7a5a024d6c6e9146fe1c976e61b..b894a19e9fedaff3dd51a85df8a09cc809312378 100644 GIT binary patch delta 2154 zcmV-w2$lE!3HA_>BYy!|P)t-sM{rDTTSqq=2}DFh(UcPHx+=YsHtet*lW#!(=#~G? zF}b<9=BgU-wHu^q3RF>0a&mEEVqzjBC+)EsT3TB8zaxNvfZ(APPft*_d=!#b2GEle z^tl`4rx}xzlg*A2?64W}wj9fj6L35TW>`U8I~MxFAb)>fxd9s0o{=c*X{ z!zTE?AOFW9Z*On^%`oGp7uT8;-k%lft{MN(IKP4q#fT7{VhOo?4Xtns%a0SYcMYX# z3z1U<|JYP|LVpDR(?(rfTWK=^g-r+k^~3-B+gB+9Y)2KPdnW(RD?2+nXjVIRc6JB_ z1JJW-x{ozxW@g&Skx@V)*`_XrZ#wSduYP`hxw*NAhljMZw62VN*Gi{@MB{paPniPip=ZNBE` z=Y!OFt@p&tLS;H`ke7IC2#9b4la+W7MB)U{ z0e@*aCU|S9+xyyY3-%2!*opi)8-HqQH0#GX2(l{ZnBXKHdQ55nK+$URc&U&h zD_c5|+>F?mAe6|^7PQEd{m9of0ZBY$mS8oGRv+dgY7N3*kq{d+BvEMO5CXfAi>UhT zkfk_>1tFd!Ey4tTXdg}ia`OW@@4ed%pH?|f;HAV!i|{B2qe=p7{tUNp^=xzA{eSda zO;ycMlTspWLQ6;^k`|=0S}YVEU;RSPc_qG0Te2Q$jFcQKARu6aV;7SJkCoq`#yjQb z>_a7dQ&lC~)i?%-aj+wb{6^BEc!g^`f}fd$!v3X@8trFvX-?S3$I416jUNNey@Nq@ej9@WK59nl;6mBJN|jHyRtt&!-b71z;lO!+*lx@1`tq zTKE7p*}>2R#Bw+o5il`pw3L5O zH)6TUF)WKrU6*88tS%=#W`7M9vN$WG8?i|y!0v_&mxy7FC`4fJRWdR52{25=0>EVu zh2qiG8t$7QEzfDXp}XxyrxpP*$;${3P#|-Ny zj+_~SeBE!?JVG}NL))5DLT=VAR^Vw$r8&RWXtX;{Fhjg7wfp^kyW{$vbC@YCyt3-e zQBd=3q{>FE(`ff=fwP?w8`<7_k}Sgd2TvgD>jT&K{V??GrzJ3EO1A@@EvVZjeVabB$I)>fBLui^2xPz0ESZFo=rbY3{Z$O1ksGIO2?b;0htt40QIRWu>cnK{s3AI^o!hhw|To7!5VHoBCMT` z*Pl)D@$5`d*0N6o2&h3bdgSVo#2_fqXw3j0r}_NryhjEEZsA7;FL6Q;bxz0YVb#aa zkZ38~DB^F{U2Y22deh56kh&e@&B3@M^QE%93VBw!k3Wt2J66BtX3U zk7<6-ej^fvziv3VfL+i(?>PpWaHGLD-&cJ2o8Wl`<8k zz^6E0KK=Ahp?C!E=k8J`9NY84s5WQ;kqQ&w(h($ delta 1258 zcmVgUR#r<&O789Kf-R3)MmjMf8jd!aR2pM#Y;1*obilp4o`02&u&JG-Nw0ibGP8w8 zo*KS`EFQIuu>^>mcP`Fc*A zMDGj1dK`xCjDP96VHndqcn?Tcvg^(y%nBg!8v|vrY(-}Pi>#wx3;EEr?WheKY~;7Y z%5saNCm~7G!6zkwV#@GAE)*uW>w4!MM0mV2(th1M6 zj93VSF(9LMFnG5wo1iiYb7%t<>p&N2`eKwg#iEo0!GD-G3`4<(`HLo?7$RC$GRSOL zh#m(|H_^z(5G5jbFE;Q{O4&SZBbO2l&OpGR!R>JXFwfeE8cu{j;sBvegiLKCM8tj~ zmPGKD1O-8)Wui$zF>P=eX8vVzj{Pz%R2V{-MlgDk#Jfz1gk&uWRaI0)0fs>&DbNHI z<^DMYmw%km7dji~*Cl_n9+8jMJ5=dw(~biNIhmB-r26RbdwxHxcm%p}O0TQpNRR z7J9v?!}rfkm4*X783SGAb&tNE8T<%meI}XPRyq#0j9=7NV!DltAv7p zSOAhsKVc1xD5dC2;80os%OrRHcSb;?KL>^KFsDRrg=JntlcYAAqPFzpCbuIFSyM@58bpMq0nyYW8j`cUu8WH>;|X;h>er@{P_5Ud^`(PV4)@c1sM_e Uct_nOw*UYD07*qoM6N<$g3}-;;Q#;t diff --git a/TMessagesProj/src/main/assets/emoji/0_1243.png b/TMessagesProj/src/main/assets/emoji/0_1243.png index 8c7d5a9c915f2a01ea84b39058fba0a6a05aaedf..791cb717e15ca9fac3a7300959a2d0141d278c2b 100644 GIT binary patch delta 2359 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 delta 1832 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 Z{|8d`yC9j>4)Xv2002ovPDHLkV1lX9Hpc(} delta 1675 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 JPDHLkV1kP+#3%p& delta 1725 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1247.png b/TMessagesProj/src/main/assets/emoji/0_1247.png index 68ef2bb7d8a91245b6ba6fc62d9ffe28019bf9e0..aa550346c8afaf8623c1309b3669a7eec16a0854 100644 GIT binary patch delta 1685 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 delta 1268 zcmV~a8Xg-P zN;WQHSXU<`BvwHk=H>tZ02FjmPE!Enk~YRWTmBp8=yZ+nsnh=BU$GPFu{Qt!1Qkg{K~#8N z&6eqMqdE{qV~lMkculk}?08?^|M6~jBMQ%*81Vd>BdQ3FbojajaX$WiqK>~?KMTTe z;R)CC+1rMBSbye8M_w+%`CD0{wM;ynM27P>6#qBmNV$-~*dVjOmcJXk1A;{3iddyq zJ`0EvS&VW-VOgd+&3~_p|!A@kWvPNn<*jqLRVInEwmI5N$}ZV z896Mnl}_aXp`{%hMi>o*pr+ZX(w56-I8Sj%82yh&Ab&A8w^~<~O*!4xF9sx8_`1Ii zik@0+6b4CuK&G3hPqD+wIVc!c`juqW*U;HY0x2lCbB#n>uc0&1+l+aN85#w^jM9V! zkL@DGy$TZ8)Ns+@7&k^Kv~+=jUIhYkUDiS#5Gkc9U6I2MDy-sMWQT*uo;(?Npf`HB z5b6WNMSo0b&;X>+mWj-9MKSEWcSoQMB?NZSxI>398q0IK0z>bnMmq?B_j3*-JVT!e z4l(Sm_a)gt2nS8T>CYAcUiw_=)Q0`!Q;8i+>|Sb~tXgmrCvLH3P+_UlAK+Sbo1V znds_qPbh}C-pwMZ;QGv%QbT`olz~F7M^;spdfaP4isESC+B{B)W6G=tzCu>UFzDt1 z(mWn@yC>V`I>9&31pSI=qd<}QtpG#!!{dT-~P{6afdOoPwX{|VQ!%L_W-eB|?#l}9z5Zo9p8iQ~g zLZtDaA_`VJg${rOBtZd&(5rYh=D)?+27evS3C7Tq;h7Apbr5`vBZ`&bC~*vc6AHKq zAwcvomH-_DX&mbw%QqY(Y2ij~Aj5maJB7XEj047~HDq{~*-illQEC-`{0*T&hlZil zh6L}Y;Do`$yq{wFwG30v+KuHVUw%!;3!<;(_ZCPbC>S|paxIF<RKR;Ruifh8K090489L?-zBP(cm4Z`4bFDj-M-; zUO+*2K?U)rfdIv2`g1FM%}+U=C3rzQLc6kj(F)p2a(IIux6ZYvEq>9A<>%+GPvln* eGy^AgivIxj7WI#^r>B$v0000qQ$Aeqx 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 delta 1390 zcmV-!1(EuK27wEZB!7EQOjJcja7Ce-aaM+!9|LHR%U*Wr#|NsB2|NeOY|NsC0@8L+K$coVa;Q0T$B3J%V000DxNklVMw|$!e5;=lkzA!QxA_s9@_1L z^Yvl^+c%6|tL35Opss`A%rKo$BqL*E0jZGpf5I!t*?$S!$lh}fTOQme%>l0IG z6QCf7(|=AStz!}dz$Df1FmDm;1feb%QvW;R6o3VRieUJJ06~mIf&kn@*zU%WSV6`O zqVfoWi0=_6Lm)*#0B$B*i3@zXAP##j9Frl=9lQ`_TUCh&b)N4L$WahX=Z=YeIah_9 z*HfPn42pn#7a%Siupy@2hqgFelI-@(>Vkqy&fz<_{8)mLs*1=vA2m%ywyJ7Pu z7aVVjfVyMwy&w=f&jejY+{o=AkZ#kNZnx~B1N5iET@W(QNP>v(5Jd-35#r)3TVyOw z5dpZJV&rCug!LHNU3Oi>sb(4K`F4}ZG8%$O5u^x0Aa?EVE_9ygND(o{riqX~ToBQS zH-7;WF?LyBR()0E|K_rIAt;J&97WnRWQYXZi8X;f5zyqaN9X*t6hJqPFB`9HLomHXvfWQTREsAS$$TTXW^uTQCBw^(9*<4%$Fd}6G40?q2Sc+o| z$q!38uY*qxgi#c&69fpvtZ;Cg5y-@Ji+?W!hG}HN;D>d26!ZPbaOZPE6EGWsn5>Yi zw+=lCnIWExusmkHiY@{XhFXUwg4uRRt^RU&2tul`0JBo8;}HCM&36=qEW%KkN!VQ2 z!EWdeCvS}~hEc5F?9zHEHaF<|5LA~TM1~NhAgV(@pl!+svtVTmpU=_b)oUpRp?@br zg>Ib>^NRFZiCHBjUd_YC$D*Zd88<^L$HQ^SE7?Ufk(NR zd_|OE)Xhzuox?RVK?PsYJSd*e&H67zSI>@N)TupxG9INa2O3k%Nc3RfeTxcDCLb#0RUkCwcmvV>p5apAAru>BP8n#BK;b&UxAqFD| zLX_(_1OTYReS|6jG+Foo!OZva!2kdN07*qoM6N<$f;kqYRR910 diff --git a/TMessagesProj/src/main/assets/emoji/0_1250.png b/TMessagesProj/src/main/assets/emoji/0_1250.png index 55406b642ce923da3f2c5190045efe5bc852b25c..bf1a7d41ddd2c94429655bdea9ea46666f75f56d 100644 GIT binary patch delta 2165 zcmV-*2#WXg41y7mB!7KSOjJcja7@dRX&)C488~2LWMy%1Zz@fF+O3D3bX$;jXU>;y z%#&%Zg=b%2Vn%hcs%AdXn{!Z6Rkd_XbaHX1f@PRkGk}1A!j)g1VLQ{GcMmRAP*PTz zSu{d#s>Y6E)1P;Le}9=+G@xWTn_fFeNmF`ydSYT?UteERgnz_#c6K{vpEF&Qf=(>N zhFn}+Ts%Tm898DTFjl#dR84)n8#-e(D<{d9bKtp?ST!b4fx^LoSKYLZ+pme*tcBI2 zeA1nDzI;;Is)N*_dET{;*r$NdnsT~$PS2KY%#moda!JL8T*{4P+_Hbc%zO0;1 zf4@q3xJGobZ)jRFT96$+X;LWw&zl`BRf$rB#6fPVJ%4DSH({8qf3-&d00264QchC< zr2hW?{^;iv2!lrko7e5=%;)Fl=d9V_9gf;-+yx?5N0Bt(Q6)k;{JH=xkxzlw@JKTSy_3VnwgpThkyQ_h`v8KI5i#~{(IcCDZUp`7KBAn8oi zBfejCs~2>@jc}ZDcH|Pf)oM2qafqv{i|TGb;t>#~8WI)-M63QC&LeX6qj_CzQJG*T zLVs}FYNdjQY86}6>P4k?b@k&%6FE{0L?qr2oL;H3I8IAEZ&i0wXUzkqRlVLVikVCh zBKF<@gAjNiNQ)wiyRGw!-B#Ar81wc^Zk=7%WEGr=a zhA3u4ym$#f#5L1U3|69DVz@jw5nWJCj(?CDAV!Vg8wrJFjo?&|7%{|PL|j!3MeEOV z)UYfu6NHF`SqkLnK3$=otV4Aki&CWpF2>TM=}{$gYHf zC9asP%mU%n!0?KlOD_c^qDz`26TC}!2FdESy?LkY@{`zjBh1jU!dMg&>(<@;j28#2QcGI<5rGXzf**=RHF#FqcmHvxs30yuwy|OYjm)*sB^N zp@9l17CXlg%*XzMQjjac(oaq{X;5>`P&Po0Fqt_J*#8A4o{BsEjCZXRCZRv!@3T_dcs71m=t>HbA zbPB{4C-42WNBptG%f@yr6x{|x217!_A}tE~42gaLG^TzTnQ3f6U}aN(0Du1dd7Ut2 z)Vrh7sC0MIlmtKs;-NGn7Z5qGTgDB%tw;gN~3%&L%H zk7bz0;Y8nPV-ai4_9Z3Ds?ri&mkn&`#`3So)n89`Q|vB2s!EK%m~58kr135d=S zJyh00{+X31lHz%Zk+q(g%~kRxJM9rzq-3L_5Mv*|i8V?jC4B7jjDO0dOSMX^%>m)% zpOsp^uPlu#L5j4j2{0{5*6n=0QX+^u#Ky;brBVZ>Was9`Jftj<<#NcDoH%{}!{f zDDngWyWkluhudhUIe)lKqRGXbiHUEJ)6=@HC>+NT#2a5COaWmk_@z{pe6414S%XV& zF7CWT05frV+R(FE)6~>I{Djy75EP^7InGo{xCv9s61n>N04SHs-%i&jzFexTAguXL za}5beP<5DBrKI;%Rm*a@Is#?L9=!I-6YJ{}jj2@U4}St?L4VQ=Yqmk)G+94&Y%iTNSe8{yE_YPk8>}DZfAD(cOU&|=(?ag)=`5BY z(ssiI+?99p(tn?jV4fBn36a)KC;{6zasY4re~0lW;sS3uC!(YkO;&qKF5egexb8og z&(8IsKk*nJIIK$OI-zMGlo|uTTkd5X!7w276#S3Q0HF>YJOGz}8szimIe$VB1XeRR zDA6O7biV@%!}YhAPq&{w{q83`-IfFy1VvE@5b}*fPj2V~w@&^If48@OMC@H7CCDZL z1jk{AJt*M{BS1gD{wyRvz;}Q0q-Sto=xMuNJ{%Fe^<#ckkZr+*`uTZ|+P_ rPrrKg>gCIa59j9Qe#iWJH~;!Sac#LHhc&b000000NkvXXu0mjfiUJuG delta 1635 zcmV-p2AuhV5%dg@B!37{OjJcja7;yczk_I3Ix{bQaA!U^HbP5V<*%fz2U{>+Ur}x#gDJ3QI&a3s&uNIP9zgZd%qquQzJ%mQ9m-yrGZ|I$uV4% z!Iy8=!mZoU$bZGNqF9E*VUNq|#(Ruj1AZN@7XSbNA#_qsQvmG!Rw3Rm{_PQa;zLEP zNM*OLf_8u5wf=>?kNzE;^&pXilGqPVOkbOM*&gw1JB+TQ_uYu}Q#_ly)$5Mx8%t$KN*x zTXg}$KdakB0|&U-B1b9LXrnG6ss?gHmgPnxcbJ(WH#pbRs#k!QneyWqG?1DuBa5!`)H$I+YhGb zCeA_&8YdxzUCrpE(x#}7rs(7!^s(b1T$nWp<7k3VYFKP zzClQm(Kl2T!PKQ)-A1ugm}D4zb+t135v}*-D|C{=wDvYBFid6T`$F52rB!4N54=T!@=ROZSy7B!8ETzz3oT?zj3-Qb26j()54y7Gl3 zLw_d^mRw5Toz?0iR+MHzrTmhZ3|gSMb(8+O|Gz3jfm>C>P$kqM08aeemlTB*Q!D)) zIX;(Vm-f|c_WHIkA_r2a_I@3*U>dd<(@7R9oWQx-OXuo3aJ58XI;N(HqDlrR7)CKZLx^+^ zuN`y}JM>^21Y=j?3JM{5-wJz~oH?S#VuxyaLEtjTxIxD#Fw0CXJ=dgZ00{?Hhoh3h zbgn5xb|*;;FVjlLO%sB?q4We9K_ zxF*#qs0O5gK{rL`j3%*dD{w%fYdCar;40F-+?K)_IUs=s=l~hqb1djC4o9RQF`9-h zb~3B;||pYQKRLzG60{q}vmSv)z-Z}a>z>H#_K1mqxw!rfi7SFe+$ zoHdj3$#e5LhJs9eFdg09*L#3lPSTT{HaU@|3CaEa9nNP6ZX;kRo~C7JHtPf|5p_CI zPlhn;hTU!mNwNH)Az!51aeq%D;YKdFMR^TJ`o=mSCsxM4u`gTd3&pd0o+nCQuEICvTi z;NWEmT?nX}*Z%}hwQzGMg<@F4pP#q`NpQu{B@zJ)+|k|N*h#t9eO&rUDI&VjQRBn{ z{5{gt_VXLp1ByWx#D-eJATi((WJD+BO?{l)V#P2>ED9x|(u8CT7$t7Njh{Cz>Heor h`JG& diff --git a/TMessagesProj/src/main/assets/emoji/0_1251.png b/TMessagesProj/src/main/assets/emoji/0_1251.png index a7522bdb5c574518c9599a6f53956c67717e91b3..d4ccc8b790d9bb8daa180a586da2a05f10954614 100644 GIT binary patch delta 1947 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 g+4Ugxwjs(woW&i*H07*qoM6N<$f-Ym`VE_OC delta 1863 zcmV-N2e|md5Y`TmB!2`@OjJcja7-c~P3Y(4Gb$)EBr7l_DLXbXiFTb&HCYuBK`keH7vHSy(}s!4GlX;SeUi4ua}pXHau|> z5jbFHc($~#>B!c4d3J#yDi;?*F)1cMKzmVQjtU3~qoJMB&40x}PmD!Yo(2Lhj*E-K zB}d2?NIFG$*fvEjF*YnIMtyyHb#!%2W021tI+hnKdU$w|kB&w*F)}!Byi;AWEI!&N zMyVP#tRgp7P)@(Ry-hPO0|q6ytE|x>IoH+Ho*+7ce}2QjyN!y7H7+DoR$N3>h7%D& zH9m?oG-WtMfqzXqF;GxY6B81~mzco}L81jOAQ={o4J)V$FA)q1J3Bf!H(`#Cj)*i+ zNoSl+Lp&`pU0zB*;e(83ok>2~ujDL>Lvps3X&GE>VF#hLMYFYpQ1dmBX zK~#8NrPt+G8(9TZ;&4uWbLHKa2~uF7d_Et6j$%GfB2|sO2KD!I+jpz zA%BT*IFSHEI!XmlhUiWrLWOl~sKf}IaVw7b65()~fvW@+sjzq;=<@}DB7w|8^)5~a zS^`uek>J7+;#>d389EYS625ypIASUurx^^xsFvUz$iu}Qp=pM}0=||9A_Owj7|leY zQK}JIK)4JR4FoVoT@1fx>U$4-6iqLkXMb0DJc){as~zt`&J*h0Z42@8oAVH_2n*r& zk7?iq@ij{3lZCj5i3_wSfcJ4;g1;%vF$07~GiS6E_~#<0OIIAL`=L#!%bHjVevl1h3=|&N)_4f6~AN&EfZN)D1InRm>7wMmxuoz zAOI2D-esuNW`P9%Su~)VpVT~=+kcL2`L&=G+Re>^mPDYYs7SoN2z~0n|J~aI0+USL zFKDPe5sINH5mMgoaFFKL6oz3YVM!r5+&CD5Lb=c> zKGoWrq|=ETU7j@IGFsceB7d;6{5%9zq?5GTybaSIiEqz7Ta%SwmZzfW5=r82+gi`{ z4j~5+&SuRSZTR_@i7(j_mN0X8Xc_2*&FUm;asjBaqL-HizG202w{g7;MdV;2HY@4O zS&FQ(UXV?0$8oFC=Dm&}APukCjXUlAS*N0ztjwNY`Q>yHW{w&-f*YuSTAFX6iK}{H%{6^&FHCezaO2-`E`BM zY6W$8t68r&orW8?JG)QK@~6=!NUkWaVhK(UOQ3SlP$OQ(BbmI!9c->k*3V}=ZA(`+kkLl zpl4oSO4)2%+d@U_aG&OQ7iBUfQfO$3G=l6;`X8Q}gejz}*=Ya(002ovPDHLkV1hF1 BI^X~R diff --git a/TMessagesProj/src/main/assets/emoji/0_1414.png b/TMessagesProj/src/main/assets/emoji/0_1414.png index cffa2450f7ec4c7786d7e0b16f1d2388c48d7dc7..8cd01f31cd21beee4b4e8feb8685ffd4b80c315e 100644 GIT binary patch delta 1924 zcmV-~2YdLc3X>0zB!Bo&OjJcja7-p9C?g{$7#JEfGBFJd4jm#*Sx{X*IY>D(I3y$` zH#j#I6cZyNA~G^FOG`{KF*JI5dw(W>P)tfyRaG}PHZU(QCnzUgUS3vGQY|ele}8~) zZ*aLeymD}GHZ(LOBrQiqMl&=tNJvOPOME3ICqO_zMMXqyZGUfBRaHVlK}$+WDk?1L z(7T(PnoM1cmQ$f9CnpLC2|7DGAR{zqWMoxpm``MtxHrAqu!(GJZB^lT&p##c7G#x*O_!%Sz7kZs!m>uM^%Ik z4KFr6ZRxs|J4JO87bui1mt-DhRcV$?5K^RfU5P4-yqWTx=h0I6YvOU2D6BaJ#I{_VC^ z*w^U(w(H5v)Oc?9A^pl6d4Zt(@2qLv-`tfDHs@S_d77>?n3La8efj?WlcF(_!E3Yl z;DON7u=v}!POHpIx5U)R;Qsz?;{SgD00iPmM1Mh4cwX(6)pHwH6viWISJH~vVz4aR zvSo%OhS-TAV27ED$s&ju%*+_(^xy22l+=Fcbhq1?P9OTs=w(Oex8H$#?wN`-`JmAj4BCux!353y9)^j$#ELed45J&%u$!BkFLxM=FaqSusPN5~k)nxV&m)2m z$bXs4`X0k1GBll0c!l*s{d{W&R!}ejt5hArGHE$o`b-f7e5fK|wJ^lM-Sw??6|oxI zCE!k>EliVUBNDHl(tH-QYi+U5H-ROS5JfZ*j!;3)Wg#(tgRyekt#&@se2DH z)}SE94FI?mjg`isP8es5LIz`Cd}QPnNPp#*Q3*k1nuMP9$EUwcrcd?51Z5GtFV3dJ z;c#x7fW<-)?Wf9!aC)0KBS9cRh_mTjxUAd*LUm6fgfMz4y_R-`!;@d`c6LgHY##ZK z;dI`Rb4?cJ9$pnziBXp;y_U_t_!>=>9<~TV{NQrs7T;u-Huh64G2|=K#X6l-*u=7mda)3+(BOGGb-pd9)DyyDnr^7de1wh?)yNlcviJJ+-rkdg?PUaFSX%=ow%@0s@6Ae{h?C3Ds%jhairUW^ z40&MUT`Ic2Q;YC4(YsvMGw_?5zkmI6-e3SGHlC;U_fQYdQpnqur>2&tfTpMGW~CFq zEoC>}rRJi0alGaPUqm^&ZXRfM_Tcrz0&e;M_SW1E9^#JxuLp0JR@BYv$>fLBT%wMC08lp%CQQf8*7BBsY&WFXGZ+pr90x~STT2) zp|OMc+1JwUll^X7&E{Xa*E2m`*GJbr&5X@Bk7?>P@~t=l5;XoaE?; z>>6v*WAP%{N=7a@jDOW2)~`7V=+|@2MN6>9ZKV@V_miQnYF81z|JZ9aJyy=?98}ub zBI+3g|E?!5R$A12Z2WC{vxf7Gc-+^XIC{!eS4SL1Q4?!9wse~uCho6bul3r1$Me(& zN(tGM&U(g=9O0Yv7>|8naXudIX&z?E`Ri(v4%5-$*4P{vpM9&OgS|R5+%k+;0(EvP ziP_474I#>YH(9g;9;YL2qXs zXt_AQD-T5w6g&Ujb-FmbfPj3nIJj08(^PPE!C^9#oA74FeB1{^e};fyya3>q7o@&FW6{e@@Hn@HD8-fXE=i%BM4} z{d(6+@_(gZao%L@t~K}gv;30f>hrOZ@ri!j$b|00@zq=GRp@o4{#sW?*Z=?m%Sl8* zRCwC$(?xq4Q51k-0vRAci2+H|xVto-)ZJS~85rE%-Q#Zk!@ZL>Or4}~iQklN(z4jw3SF^=Q#O$=rXWk_Ej z5M$Yx@5QJ9)RHPsdRRQj7P;bYDQFu5Kgz+N2ai=Mg~-;J8iI&|Boesu^NQwA_$I0b zEq}uoOyPlmj}^7aWjCvkJ39H9#0wP;_bA1hVhVJ>FeNAdCdYB#`m!c~!>*{fvr{i&@EHex;^xEOJP9aQ?ykUfVFgl^gLncpMw(b8NHrCMA|S66o14YLt1?(6xv7|1|`t<(C5-6r!#zL04_r^ zr_~xvVV%x-m3}S+PSKw;m`aE+A3zCg*pN0wbSXsi3!(cQF&sp6nXvibX$xQx6873@4<@zLc|c#S0)}K!3T~ zN@maqNB|MoQXfgCSk;N^;*bwOEXtfJmFm>ux6tkjGcsP)Nnq_m;S-DB@3-vJl-pQ6 zIy!oT)g`n~bRhtpPtta`(OTVg#NT$;C3JWB?*?$$Z9K5+aKxuS^o-Uq120(a2S5N{ zJaO9ltY%_@2Pn7AXtY|Z_c;h+dVju0TALsqw^;TmJ4Ms9i?X}jZX3dkRe~Vmr@d=6 z5!iS#nWU3^G)>vY;A5OBqb&$Cf?b@ z)Tx+EU5&$=aYj{$<=?Tys(wL1L2XAJsftx2BsEWDm9{p%w>G`t*{BE!4s~i|xO`Pn zQBprYKuStV5fdv!QGbJift{V5Jv~9OaY$G@Zq=%SXKHF|RaI4pLyAK~ zLNG8e+R>dWD}OB%6+S>fLAR%NH#j+2T3LL2d|zK)fq{a^$jGxbxT`a*-`AbgpmxKC zSmfQS&&7n!zPENmOkblF&!+<|ZN=iyZL_|D2J~cHr z-LHr?K5b)SV$G0c(wS`4p?B%yxO8=N#D!c{R8z7xwQOu{aBy*}G_9L`Ksq-$jf{-r z+osy7flFG5FEwEuB2K_N!A}!YTpC@nm{L1MbwEpeWgcb?4lcs4XwJWWbR%_XFI5&B zEQ%_N%!}tII0Dp8+PE!CXAix#= z{s9FF{z3l!{{A%ZfbjfC_>=zl{vq6p@BRM%+JAhrw#g1%#$s0_7RunGTug3%{rhP- z-O~L({H*Thr2Sm{wXPeQH=mH*o+bHnd(r-zf1+*Z?tqJQm8M;fu9V|x*Ur=1^#1+R z*YDTFva5Bs#Dk{Rj*#%l;QooB<{$t71q?|2kTEm)J6jm9C{_7mzY~jUAz&dTD*hrBp_h z(dhLQR)~~?>l-uC=)eoH7cHny^|GJS?+GH$Lf zZiGUs&ap9oVCiDXV%gZ}x3EWCUR<>F1Fe>it+3981t6TB_wPfYN2l}IG$+;u5Dt%h z_3pjzmt56s7|`bcP-pMA9OajVmX*bE+XGXSL+u+rEsdZ-4KU z&#*;6*jE|D!^6R+cc-thMHE!|hGUHFvFjx%*{n=l^aW#xjJ2ns@|(465QnOK3qBA^ z-@AKdWwmTpApeVDpI98s=<_&lAA>MfCNeU73!}4Z@9YlC?G#oe1&HA57o(GNbq?p^ zQ8sa4C#rnGm$Q?jBXiFk{T5cM3xE667kncIh>>lFz5nP(ACEmQ`qo~?5Ob?`kNxsT z4{F>+aP77D#puX$FtJw{=OPIR`{Vt~H!l~&lOuBuyM0r|6i|5}rpnqQF~kY+!orRT zd!0ipg+)2sBVUWf;@QbqEHPr41aHJZEhJzT7Dc2@VHExx^m#vt5<^>GeU>mZW0L-6~Io7 zkd$$gN^v(2X3*6gUXr4S##@xch9fjd5R^n{s0mX%J_MOiojh?)b57EOR%>#Fj3QA= zA`wbx0#IlYk;j^*KGGmfn9VHNVNlP(WL2hLS0f=w8X-v#6C#NZh<{XJOG^|7N7hp~ zVYLE87H(3d@nj@0K^ufZ5C;%;98FD>4S}q*D2`~-DmW0vm!9IuylO<)&fSd@R|^sp zHHQ|&5knQCTzDrmm0lE}HM<8m3Y$5>iZQ91I|j#N2zTx-8GiWTLyNwrRKS7xaGEWU zx6h0M1ojDWPCeBX=CG^HDBMA`uyWn&QDT<~@fz&g(v8_JV2A%&gL935#Q|@O%v)(JgH{gh3w4C$3_^!U|t}QN;Go*!kcgr zgME>vC^;|cJ%8hk#n0(-qu$g%5z>0p-vxk)Bq#El&*z^HOXFk9v!SAT0cZ)BE9g)} zv^)j`Nc!MWasCCx?pFs+YY^e?&fMJGP8=1<7;f-W`j#KjJ?=HBYMVdcx2aP#Qik6V zOwiLR-@B)|DtUW*yIjSEm@A3@H~$u(|G0h!gwd6Kfe-SJH~;_u07*qoM6N<$f}SYP A%>V!Z delta 1294 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 FV1j%kQH=lq delta 1145 zcmV-<1cv+C4vqC<=xV-G_k&mVudM$gC>VhF@GMmRFH`&i%njPRcV&F zH@&tvxe*#ZdRm4G4k_j3+qQ*Xn`CIRt*BW(DVda#f?jMq7dM?Spm0kxhA4+>F-bfk z4s1&@F&qguL2rF#PRqu=xQSyk8V+0}L>?6Yx`tx4eqO#hzC}`iJVkV;b5?>Vg98d7 zTRbLAFB`9VTYrypTy#z~Nm+(KOnPx4bTd0@E;V9lAZuYCU{7I=o@`H5X_PlWZzwES zRX8JHMlr#SX%7)EA0abpQ9CjjO(7&rT5z3ZYlcB55`RZeG9CzXY;c<~nVe%{!$_S{th?;{*MR!W%f8f{(t>nf`0wGdmpM$mqd5Shl?Y00NvzL_t(|UhUP# zQ`jZriql?uY;#;UGu{2|)MzVc-lAJ4@T{e!tyre}dgd zz}+_7?ta^7wG1NwBEp7YW!pq>ihzjZd9713Z%ngBn=Rlb$pzd|4Ks^tW^0vofl3Fh z4pOZSA`I;&zF8z9yp5P9yD!50PewYG40V(ePwN(hY`Cc4_f&VA+@4?W`R@0Vp`ef5Cte9E^Auh z7NJ_DFaso9{Q8i1Bn0$Tg_W45BJ8Ua-oc4K7-9AHHN+7@xOQ79!->oivWNgD_~;T+ zeP={~5uWIeeP;;=01*Ni0AV$FEtiKvxqmP=k+D?Uw(sj#^_=oN$C!lZSx~R9NJNm8 zVskJU9E;;!!{*#I5$g47F0T|z%}a0B%Zw%L&Rvnnc{$%G5#ZA6?OrD4Ka4ShBfJbi z0H<#6{^R?RiA@KPl}3?F@RC>8Lx=OJ(FA^@PK3Oi%jIM_uP92RQ7jglx~_NczjBYZ zjJQ#)R&!M+g5>ilxJ^ek01Gm{vTd+z198#i+QusX~59e00000 LNkvXXu0mjfmpu&4 diff --git a/TMessagesProj/src/main/assets/emoji/0_1418.png b/TMessagesProj/src/main/assets/emoji/0_1418.png index e14bf54456f8c4232035cedbcc06a3abfea05fa6..976b290701377c0e2dd946783509ee48e6d56763 100644 GIT binary patch delta 1693 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 Vc$a*#g#iEn002ovPDHLkV1h=6p~3(F delta 667 zcmV;M0%ZM`2eSo`B!3}LOjJcja7;xrD?>0TNjEM?G%ZLrE=DseT17fgJTyfyD>Nk@ z7W?b+00007bW%=J0Ibv&JBwhCM!>!R00KHmL_t(|+NGC)Zo?o9L}S2U^Zy^bfrE~O zDzwgJ)fBIJy4nY$$FmX_k&xrzRw`XW$xDb*Od{Ed$WjJFoqr4lLL~ZHAq6(b*Nadl zhOearf++i%F}tAG&5#g%(Rz)D!Ha++ZX* z)a%=fam@v6pr5x1j$PP7fNbeKSs|hsRx_#240EDY4Q<6SCz=nrA^>QeeA{d64^y?7 zNI>MXCVyi~ni%~$i;DW0EQneWTiReih}OAv)%!Ui()@e~M3x@Y$8^$ix??^6!nvOt zQaB-&!`4r`HC03tN))I)jr&`sM=VBn^08N@3Q8R#9qHL2;B54;nvoHoACC1gbHI=; zBR#%Xj45YkrrzK&ee!)VNK6#|)uwj16}v8_KNJ@}MAY5#{s#a6002ovPDHLkV1jdt BCGY?M diff --git a/TMessagesProj/src/main/assets/emoji/0_1420.png b/TMessagesProj/src/main/assets/emoji/0_1420.png index d557834d6a572337670c76dcf2d669be46315ca8..e3732d5ea3fe4d394938cbcead789af000aae3d9 100644 GIT binary patch delta 1655 zcmV--28j8@2#5`kB!7TVOjJcja7-&JEio}ODk>{3G(1d9OlfIpX=7h6FE1q_A3Hld zE-o-(VPY2+7bYerMn*8&CSg*F)|Jf4=^w?Z*Ok} z1Oq83C_FnmDJd>eWtCK5eaFYgGBGjc*T^g@E>2p5)3>2)ZGUc%hJBZfh)i9L>AHu% zy0^f=!OfL$Qc_YpJwBbCoN{q-p`V>zUR~9#iO$T*P*73C!^3}nfP;d8(4cWrNJSbP zNDT}M@yVs`!JJ`hgzw3u%8g#JeNv^RrL>TE^vtEWkaF+9oFE`iLQHrdARvBzf|8Pw z`1tr16+TsImw!h`N8_x9Zf|fwKtFkUdV_<6b#!z!H8=6Xoh&OY4i7Agi;R|*mL(-E z*4Eavw6uYKecPXS<+zl=n||}kry3k5TUuLbOg;F}tuihyG&o@%Ax=(Sj6X?vH$QGE zEm5qjtfHc#{Mfd@h-PqMRi=AirjdVHZ=FX~gjHH_-hbZS^whKH&$(Kkd^G?708?~Q zPE!CME58c+{sa~N{zU%%gy_*zH~pMpcmCJ@wDJCR@Rqh`n(QO=l@P`ye9BOONBygy z`Q4@9_|=yF_FUPy?aG;sJ?@yz#kDgFXR3W|HxIJ|7SJT@$duNcv>P=MIsn3?4M;(g#mb=7W#0%Ub?$L$NGn zS{%$>CeuImTU0uoPC$xFL}9;qb(cu9J&L7VCVx_RzuCX)C2oygn&sUg=HGs4_cw2i zelPu!bXU#SS6}*Vs8%BF(gZTQ-|n}K<~5am>2-;i-fy=Ju>lcb#I0T%;?lL)Y(3{) zuj%yMyZ1|m@nvffd5Y#Y|A@t&$XJNQs-I&EKKF#_tsRJX5@T^^i1@rS=end5)f!|} zV}H%>T$_khFUqypPNVsD-fc0f)tXYOwHnR-_XT%|iE6B-D)su3Xk5MWxki-gilnqe zqdo7knmZR|h>-3?(Rk&~MXYvFRy9J~Y&68b>tdAn`cCcALbSw&_|E4z7V0m~huQ^1 zNOefK<(&e?$DpRh-;l$rvwC@1E-6w=6n~epeus$h!~2n*O-0bz_0@8@q*}FX+{96b zCdLk-?(gBx$>~qQl7&#}(8CQ#IxL0v+2P5_;R)2okEdtH2SMYl%&xC8<(?BOTVlO5gyhSS(hEl79r~ z>+42CHUXhBn8y)g>fNR3bxo58 zG+u#r(iF&}zUZ!okq!`3f=tUG5R@y7GSC6QWvas_Xd3e(NL1}QXv;Xzk6tMiH{N+;CwjACd{WI+6(SHknl3)@P0J;feQ>RUHINhNXle0s3vMbN5fq20O z>rp?4WdROwon&HM>PR_!AXVvJiMc9UO9k+N=Mf)O2nY9qOD)b3<8wl2I3!wKctnJjRVi+N`Ft6?uy8k5n4^b*9*j|m z<>6qX{_Rw$>*#id^1uCFm`Ei@t4(rQLebV{W@gqDmB>20;2C^%OMUbk%EfU;k|YL? z=R$}>`EyC`+dGZ&TsR!&cocCipZ9-!Eg=7L{RvPD1vCqqn1}!X002ovPDHLkV1ldt BD5C%X delta 1071 zcmV+~1kn444a5kLB!5#-OjJcja7^OKjIXS%+}YXZu_-VyG1SVknURQ5QBq)FU{_aH zPf$`;S6K7HFy*v4-PzOr-*=mpkLkBBw6U_ae-^>Kx7N?gdU<+eP%(sqg#6Ay<*FOW zmME;Lss6|;xU{jrzQMx3y>xVRi&6#l#WBc_7~9(1y0^E;o_|GERaMs4-fC)bBPceV znV6(&4*uM23Jxj$+;95FEb7T`pk)fPh(OHB%6)x(goK2rbrjv)-0Rn&_1AlMJps?V zgwoK^Z*On^(KK6ITYGzZ{l_V~x3~1bF1>*gb#--zh>BNNSL5O1{?$fgWMoK4Nu!{k zYHDhOgM+E2sec0sAv`-i`Mw{{mL1upHzg%5+odL!S_s&j7prp<@473<#Kf(KNER6^ zje>Q^}5`X7Y{>S#}(Veo$HnCpW;{JnZ zd#&-R+znGe;R}e*mjD0)U`a$lRCr$P(pPiZKoo{y$p{u%q8HPG z4VVPSy`~oRM(@43mel`Wvn!8t4JS954DStB=b4WkQU6b?R;^m)@+J~q7aTy|kB7&8 z|M8)R27e0lssEbfzbS3Q3>3U6-T3i+NfgBdj7XKl61gXNU_?IL>1$(#VfqS?py<@- z;kGl>b-fQJwi%5Hk94dsK?;`V(l3q&y3%_cz4nlEU0h1J%Y0D3M5O{oA{%Dwv>y>2c>ga0Mm2p6wHnArpuIAW$$Z zDq4R!H}N}EK`Zi1_k242Q8#5nHpz_rB?+{Vx}4YRrdgK_fwkP0B(0;RgpIfHIk~UP zLXDN&m6o&TLG=3w~HUx3g}y!*LwX^C%n_ p!#2Hkw09JvmJL0#&p-cazX2zAk`FdE2}%F}002ovPDHLkV1kB88|MH3 diff --git a/TMessagesProj/src/main/assets/emoji/0_1421.png b/TMessagesProj/src/main/assets/emoji/0_1421.png index 633cce2f0c01b3f908dac43d09c9e4532e54a4a1..d3abacbc83140829b2c097184573c1ca0cddd22c 100644 GIT binary patch delta 1806 zcmV+p2l4pp2b~U(B!AIROjJcja7;5aHZ(FZI5;|CVPVV5%P=uDc5!PyK0;_|X&oX> zGc+_SD=cqtakYO{L_|a?DlA1tMmIJ#kZCh8Ffk@4Cn6&zB_$;xAty{sOueFbGcz+p zL`6hKOe-rZa&d9cvW_MuCfCWLL_|tWPEHvbCnzQ;B_}%#4u2356d6`)nOJR_Y;A5( zP*6xnN!Z7K#iejeU5(4j%TG^FZf$OeeRg?$gg7}m)WUk%xpu~oXU?Brxw^YkVu`)L z!A)3wwY0L=r+e0|imZfIjAblFRfeW-J(OTHrl+VdFff>xm1JXMe}932fr8e=d(*LZ z%g4jpu7MgGNPi9vH^s)rrKP2xpP#^_U#osp)S`SxL0Umfc#@Km`1trMD=tV#NJB$J z&X8qvbahu(SWHb#Jv}~wfr1|(BHgizmX?-zd3tSaZP=uIeSLk|s)NjzaM7Q4g@uN} zzrLTJo{f%Y+zSqPCn(uo8q{X)wZ4LZ3`0s003TeQchC>S} zaC55d?SR6Y$=%@i;l=Rt;?dXi(oxJ8;yVBU1f5AlK~#8N?Uv_v+GZ5S0ZD*BAi#jZ zEE@whiS2rhc*HBqBTeFrZq32o({t~UJ=*@YeSg8E_J^KImCxzvhd!Tme|qkHpZ7|N ze^viW)9Uy8TWEqsa2isp6qcUeXx3hD4 zdQj(ltC2-$`5~Rz0XjX9i%_(VWq->a9v&KZ4z{1jYsCM3IvO<|R<1_0gMkWF|DyHIww`X*6_KwVH=0C*%!mvTp$r)KLrjh({OkfgkGh0=9{GS@QMC4D7 zV>u?VM{m&&G?Ht9{^YzoIxfTn1292fgrou{Z`CyEQP;Q5t3n~R5jULCw9#Uhh<_Nq z-B92Cc2ny@Ar>nN%pOfwKU+=G2-;h>KQVm9K2~6qdF$>EPk)Wy3XDVP98wKQly~o`+beCj@pZ(DQ2*%t7|YWpcaW6d>()GLb&p)cUS{(!jOOiR)=08QT7p+ w?fRZJg=~(X!xl0rq)Vgyi@ycMe_Ve6tqV8KL>(XU00000Ne4wvM6N<$f^Cmz_W%F@ delta 981 zcmV;`11kKT4(kVyB!3i8OjJcja7e9IBx{bKDw)M=XT3T9H zS63Go8r#^|x3jRznRSAKf^>9ri+^>>$H%s_uJhKq-m!`0%73jhG&M6XDD%v#nUs>z z&dvl08V3gqfq{Ya;Lh8xjlOkF1pxr`%&9UmGW*o91PUSSyq0TgYvA7Ay0^F2rhpz7 z61jZEuo*EopDpnwV!EBGqoA13jhEBHFQ!=Qvm){ zI{W??1^)dE{r-slH=cc|{U2>mfm!bBZj(UU)&1khs?dKm%&6L6%ksOZ&QaYHt z*HQog0#QjsK~#8N?b20q+dveCVM~d$0yD&pA$1TODu1n*&5WV;|NoDkji;BLkxy?r z9l!Vc%(p8g{-5^k+qbXS;Q2-o4=9c7tqk4f6s(YyH{0Ya(#UNES=KbIg%Ze<48d_h z(6k(GMXONoJkRh71wqT=2=RLHUXUcOx$p!eL9R_2zDqyNz>{(bTwnc_u0KEPt|v8+ zD=PkqQh(DmpQR`4-&N9eN@=+8q(`JcuI>N`-9^FsP7=r}CIumwyXQ&*Te<3fYf`Fz zDJ9TlGMP%1u56VV_-E$w=W`LC(bN!7b2>edM=hMmL<9uh3 zAZMcyd`T843}FWMYC!#%m#JBuZI)#X*iLcQOP}k5BHYI@h*F2~0~Wgjw=K)_sWX@& zT*kXfk*}pv^?C}b)p%B`2)KBVd(0{E2=YfAfPb`Kohy8dUXB6W00000NkvXXu0mjf DC3fe_ diff --git a/TMessagesProj/src/main/assets/emoji/0_1422.png b/TMessagesProj/src/main/assets/emoji/0_1422.png index e61469530b5c830898e1b3cd6fcfa528c8f6a088..0ea9c411455b36112981fff09b7af7353eb96875 100644 GIT binary patch delta 1778 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 delta 984 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 delta 849 zcmV-X1FrnD59bDuBYyzNP)t-sM{rE1rKK<<96U5MQd3kP7!^)TOq`gQqoAK@X=pGm zE>>1nO+q~-Bq`0x%B!iV%gM+^Jv%!$H{RLOu&t|ne0)kjJ3TNf!oIyCAt!->fk`=AIWe!Ss1i( zLog{wNK1)`h}P57PfJT<_YiepZHaD}dusSLu-P_w>QcHMub^{6_Jv~5i zaBy2%T9J>Bzr4H_87!D$6@UN$04sD-PE!Cl{uloKSpNJ7{*7w>{reZ5M@ri~gg0@l z-pP0Dow$?P*nipG#IlFA>e2m;t|R~e0wPI7K~#8N?a{|_+b|G-VH&KUStQDlWJ_|3 zTY|>k)%^Ys6+rY%uGIRH$>_iEgb&Mw_WyM0(xprK!m=VA4&Z3|k|YU#nL`nMnj}V| z%BL7c%#%|*msubIuhjit%{5SK*DbfDD$l3DT|6P=x_`cpPzfdQiV=c*RM&pF)?iIr zL5W$@+VmqJ;iZC7#%k02twRY)DIv@>&07uFVxr6iGO1dAFC>?9>B!&F-!@ghw1@?iOOjiBLcop{7^XsAykB5LX*Uf5qb!3z)x~t zg`L`k19??E5J#t_P-1ZI?UoRf*p34x-de&?F1|rn8&cQp!3Gn$w;_mhwhbf}^XZB* zHG&cV1eOC3R@0q0*p5QZCp^X|&G(tex-L_@uz$}bemu$hg*ZrIml}q#H?Hw{z?+a) z3w6Fo_Xgj(z8jqb;2(EFmYo12;rX_7{q5cTWIQ2-zXRl33Ak?g>327?(L+2cL7v|m zYJ{9~o^W3F{nmb;j3n-|EGvqgswmP_T2jmVzW*#fX5)z0tW#z3Baw7KjL%-iNB)dg z>`I0THN<|1bAwC8x5pS5U;o;tLuw&Iw~_VuDo62`BVX0>uD|lEQ=TsI$<_LHjkRxv bwSTog6J%YLCee!u00000NkvXXu0mjfKX#Ht diff --git a/TMessagesProj/src/main/assets/emoji/0_1426.png b/TMessagesProj/src/main/assets/emoji/0_1426.png index 53571305baff5751e7336dd749cf04966e8e16ca..2e052f8b0f6e26c3eb4f0eb79c784a6940bc6f7f 100644 GIT binary patch delta 1888 zcmV-m2cP)p2=5M%B!Bf#OjJcja7;QmI)Q%f~=S6a}RbU8UgL_j@oae7r$ zRD*(npPif8Ej`mCH^Uz>xEwL;!k(NJBMuD>FfcH2adJLAJz7pj8XQPpUtWQMg6F%3 z!XY!kl51gWgnzs%j1uA0ke4 zbaX#FJn_k`I6Yu#Nd zwzQ%vefHSKU2P9$SouhH@+d!YKtbJ^|E?e2hDz27~Kw4e8S z+35L()pqEX&eBofy*cyD000EVNklI}>ZwnVtQx=llEV-g}PjlYoC)|EonNlMYbnbh=Q$ z=W+!kLeQWqN=MUzq7Icbh8Y1_oB;Dto)kbOA%a)*$TOTxM|n+4EJOBXWv_@MgqxR6 zqJI}d@rtFWw^$H@@JK_ne$FiXR4iJeIF4gd5tW7b2mO2ISy8W%hUj^?un^BYEM<6v zO4Ui_qrA)lUY;KX)ZGcqWE|Ht>$WnX&kgS$R z_wJ8mGL>)70n&w{Jws&I`~`s_UH8`K*MFC~E-F5une+2J;*%KXF02TMrIoKFBfePA z@r?DQAMZ<^=bfb&v6cC*&C=IBl1H(WOKjxckxYE3RT|>6^Xs|A#NzG%w`WPfI6yKM(7>}4_~rT`K;R4ig{bv2S~OV-s7tIMf9 zrc(Mn3stQirN~(b4Ycu^ot-7JB6BEh7xtA|rz8*EZSumB#6Cm8rms7+!gADCcryMOJ7=Od2d^$~c zUe6mHrt>W4)(C^@El&rV z8san5?Yv?0W+^?+(JaAn1Pc;K{Z6zyDNnODRMUYoM+l!fWYahdbd82t9LK$KKu|B_ zYUZrbpgX-Bnc2SKH91uPDu1_M^%_hy0>K(qj6q>z6H_NxW4C}v_G>$ihA$tpYO8Ln zaUkfV%qI{8M5s2|yi$%w`Sdy<$OX1=!7RAGtyjf zo}xu*vzj`+*q@oyrNT|t-xO_9YuQ5i@KDP^6LoAK+-W}+e|585v_8J+ED-tZlc~wT zk*l&!YvZvZ(+P}^Ie*{+=O0G_`!v+Yw>AnNb3op!HrSgkEx&VM3cAT3Lp9VBvoZva z9$R-I$khBp+Dr{7{QjwSzG0;!RkhYSRe#|_>a3&r?(;Z%ZfPeT)r9_ot`ualeni-N zp{z^9pN$4?oxIh03k(7R!$Fm`z4c(rjKj`yLDVmr-SFM_tyu%k#;v3DOl#FCXGcfJ zH8rF)h}_^;txtb|T)~e>%oV1x)hrcudF)~@c4NS=IliZ5HVuYh8k-CdFS-2hUkfPk aAJ-p2Mn|a}h9R&30000~ zsTMT;&pG_fL6;IJrfCT;IcJ3tBmduz=&&P9UyQ>QG?Ei1$rv`86e!i37glPR|I$H< zARZYED*DGU^1CGE-O~5GBeQl4e?$Y_ksZX0A603XB_~OF4}Ty3*jHO(dJ!5v{Lw5t*EdUFicNcnUs>z%fscbCjZ)E-pG&bx+wX@EC1eYH$iWJfP92S z1Km+C|Nrx~S1P1r2f?9E`@$mz3?u)`EH^-JloTiY&^7eA9^s`L_Qf^0c?`mY5AeM% zcMcvqMs?8}G=C;3Rc#I()15F=W|S^9VohI+TcW`f>SscwUHPDd~|I*VELB9r~UP`#H~}JdWSC8)A;h5V^D3+)xPT8Rq`yg+WZqU2p9kW z0&7V`K~#8N?bSzf8bJ_%QC0?quq!YMRzk9}m1SjF&fXl!IcJoU?Z59HaOn)qMF+mx zYrpE5nt!Uby_SXz8#XM!ZF7SGryC5z&W>RL!kt|(3{!NuHUc=|^upz$0L09qgfX^Q zRMZEiSY#d)mO~Mr6w7S#Vz+q=L8e!IY3u$9Qh9!X;Er;xJTwi{Fiq_WNs!g1qG*P3 zubJA44cAJ+C5pVtH+{wuk~sP00ztiBUjB)FTz`v-0)*!C`CtiL)8`f}VH&E++0cf@ ztLCl7^NVPLEM6JQK3?R%O`r|W($~3ZR{RrjfPs$KR{lmJgBjj;kyfkaIPl_$2@rrN z@8XG_NN0=ZDG&NacOni-$dhmISK;Uq@-Chzm+$WG%CbC4(8RM`iN`CyW%Olu4&+cl z(SPHi%PB9G7?nd6U604`1Oeh!w}6W+gJ!sY_od0(1_uQz&vZgvjPD}aI*{WV=Xj79RWd*c~%rHt$zLV7@}Q%=$kl6 z$Lsa_jXRf1Jw3+2=$9bltA*1j; z4)i8?W)g`+wc4gttKo21k}{c0RDf=dzxPCt%~ZEUD%C~6kdgwe*5hIP?QSpgv`lR6 zuvQX;{829k@r-J@su6;7=LG-&002ovPDHLkV1kmr5qSUr diff --git a/TMessagesProj/src/main/assets/emoji/0_1427.png b/TMessagesProj/src/main/assets/emoji/0_1427.png index 14a1ccfbfc943f450982f42838c2e2eaad05b71f..c98d2b249edc5a701b0484afdc07ad5127436646 100644 GIT binary patch delta 1931 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 JPDHLkV1h;V4PpQQ diff --git a/TMessagesProj/src/main/assets/emoji/0_1428.png b/TMessagesProj/src/main/assets/emoji/0_1428.png index 07266ec9c23b08639949c8c481f42142664a9595..e9e8367eebcb26cd5b55161d1994eda061d7c118 100644 GIT binary patch delta 1863 zcmV-N2e|nD2-XgeB!B5pOjJcja7-m8CO0rFQBhHgcYQT8G-+vRYgR}wFf=+eHGzSG zE-f#5dweY}FGNK}GBPqLCMYj3G(%5*E+QR2K}JVMM-LAXa8W}jC@MlA3bkceGcz+3 z6+SE~ELd%s9U@O=PC7-rU<(Y?^jTF|ipdYey{DDLk|(F`Pp+!z?vRTZ@KTKu;qbXQPhlS^5Np>kCpCRCXd9T^!J`1trrN=igTL_Iw{VPRr7I5{OHEpSmaZcH$4 zZf_3~Ew_PTTUuIlb#$^CDt!XUg%We@$%K#&Vn9`=spp z-p20qX-fN-mD2a}qVD)(B&)@BeB{ZD{<7r9$yWKI)rX0}ncczGkA~g2`K!#2FYm9{ z!QsA*A;D1Q6C0jDa9LFcN<1oVs<6&mTa=&j2 z%*+lmABMKSv`abZX=XYTtNWtUi@q1W(2O3f<+Y*apU!{Lk|aLh@Or)H+Rt=!v^($s z#?cW9g~Fk5I21aAX?WMe;o>?7kah-(P+y&&pD%tPIxx#1JIdMl;<}u$7fWDN4`YRm z`G1X~thD1*QFkS~oOQY8i=bc=%gf6-*Lr?qW8)ki(e&+a%dx`FP7J!SUmkBY3;mh;OFAn+UiQ@SrxvZy&w}Soqrecjnkc5GO=>$EH?3IH3`P*>aS;T1?IuZ z(A?JArCj-b6DCpjU?sVbO8&B+F5IufB+joUQwyn2x%5uq9)m@EbG{RZg~fx{=~$r& zcOc0*AQnGmv$1$wJ@q{eke(YzS4!+>%RBoKHew(& z%81KLwY8h|kZ3d-q(4Lu7ykVA?JFaqOQKV)Xr{wJR2ptRMM5T+&>_SJ-@Plk?7Wd^ zWFvi~qGhr4{{8!Hli4Uqi3HCHCJ#kH55DgxmE?^=0{Ll%Kpcv>wP9xh=ZL(Is`SKxgbG%<& z!)W!*&Tfk0GF?Zb@UWDn%6|c2maN0IGI4`$)yU5nt;Ik`jDM7`9uUnZ2r?0%riZsH zo4Y;1MC*~PxivNQ(J;|wRco}G5i!zSg&0AT((5r3 zUC#g6gH#+DJ@*Vi@KmY}RB5~@2WuA`-R z>Ej1_jP-tb3E7S<$VOeYbun{mvOmrV1HI3uC%#OTv>A?lRzF#NbvmqlD9*bbOpV^a zw!woDbgXx6qt0J_kAJxPUp{9i&7ct?YbFC|uyLZAz<9(vD!2QE4SLY@B?b)0 zrv8%;=x7D!1u@WcoA%zJD=jRIJeKr_>~XQm|}z~~c8bmQT|Car<~ zQe4s5srSG5|IEvQqgzKqjM2Kplh)SOUL8w!D?7oNX2Y{7wm{{mUYLuig%Tr?h)A`V z^h$4K%Y>UCkD;W8Fm;&-4?I&GM*9~QcHqA}zXMV#QOCj>^p*es002ovPDHLkV1oS5 BZUF!Q delta 1129 zcmV-v1eW{O4*m#`B!6^JOjJcja7>^qGRnS_(5rR1ds8twXo?dhoNsJ9MRa*xU&^|V zF*je+v46t2bcPWlFF9wW6)cq!CQV<8xDqX^ctyz=HQ%<1%d(BBh(%d$n@U%8nlCTa zR#KA`C&asX<=xV`wXVaBVNG6*!xS*Z88pTiHp97ic@G~E8h<_t4k+WR72dfjkTp<)y#>qhi%-jh~c)4+Npug95X*mdX^O@0tq11p?AoVYR{W< z!ii&d5FJEQfPYC@hkp(rZ44XOAu=yEWE2-cC@WV_VUEEcE;m4LRco0mGG8-0YSSY# zp;$p&aGebiC?6p+qlR;~r(vXnJ*pNi%D{fEnNPj4Zj2BkHWD&WL}5ckQh+2Tg<>FJ z9yf1th;VLkc}^RzYEaQRJKn;k9wJVrI5%``e=5oxWq$ww07i6DPE!CJ6;u9=I|Tj- zGgpTG_H4_iH4$0c>TIp*PA&WI=T6I-%4qdcwDqle{d&-b^4|W_zMji?uafKWjJSl_ zV)3iB&D;L|Dvkp-0007WNkllsGwjYny67@44U4Xp0mBs zdoT9hl7Ia9%x+AsVYu;v?|$BAX3w*(`_iC6g9h>AiTA=4ec!> z4Q305Z2%H*H$=C$58Afi_a8)kDB_2|9qYij(<>LIP$Xs;oqed?ZZB{s!@WrY}w}gnIQM>x&MiK(0Kxiz>hFr*) zmmr9yDT?^tgwcqovl<}+n&1S{e9IC-W*?&sJ`|c^Ch4rSh&DLqZD*ylw7BHL=blJI z(x@9xEJ@XLx+?8H#S`zV5^Pb}9Svdy{)1Gg0-?+eV~OBI;V+?JFX7x1yM^k_P2o@( zl>oy>JE9KnJZ1&xBPr~$69dZ^ZW&i*oySDz!)58w7@P7dS>>AC>`G?&K z+zT6sdyAD!xtzPJoK@Aejcym=AC*9m>tC8`Gu+)N v<0FBgy8?j`yMP;Pk8gElm3Q?S0Qa;%uEDPFV@h4200000NkvXXu0mjf8-WU0 diff --git a/TMessagesProj/src/main/assets/emoji/0_1429.png b/TMessagesProj/src/main/assets/emoji/0_1429.png index 1f5018bd1524e84848665664eacab3c099afa409..dbb4c71ca31bf031fe2ea9ba302fe5c0dff13bd8 100644 GIT binary patch delta 1749 zcmV;`1}gdD2;~isB!9M0OjJcja7->PE@^3LGcqweGcr9fHC#zdQA|yHdwd)rO*%3! zD<~>LLPAAFMJy~WLP0 zE-gSnK$t@;pcf`=ZEkRHZ%kc`Bp)H1o0^G;hM!9?iBvDcA2V?-Ayr>_wY9WeTw95W ziBw{Nuv#}Fn>oZZA2zaUXV;vZe(kIe}94J=jV`LH_s$Dw;L;3TVSuNs76Lg zmXwpu&d!!#HGh6fE!{9em@q0ICRCUc9T^!JudAezl9HmLqP)Dk`1tr(ZJ9hgJ!(88 zM@L3VOG|S@C^a@Wf`WrB921LCGK5etVq#(z7(9_#HINe@OIn9VHY~FoD{XFW-!ejV zb#)LFBQzu+i;Ig-D;s=CD=95eHa>00BQe_`GGZDSU4J(ra1IxM5F0HtV>?E5nqfO` zE+B4AH&t42I6Yut3KL2>FycN=QDcxmFD1epEI}G2gD@n)opGswSz1+4Y0`8%0001A zbW%=J0RH|kCKLn<{`;LB{_Mhc{`>x4`u*BwMw{CHef`O{{yOpR{Jv!$-O`3mO|4VN+tA7XRoP^V73OF1lol1h%@eZg`sl2NM zR5HdsRw^y<8-Pp(b$P@jNooxdag|}{964V4D68UBhd>?{i;}g~Y5_(<9pcub?g?+R zNfKa~)FS>kIbp0F9zcBR5Nl6=KPeV-xvXTBT&f6$I{;A3X0wdV7DH4f@^C=lJCe=n z(toIv;Y*MP(_xqxAgI)B0O&B;+&ztIA@@x4fROw8f#wD>q#k9fyX&_#H_^SF-FkiU zu0cIP|9p41{{H<<7!M|Q28j1N>OH+%ugaNZAF3|Ov-(Wwm)#wv`*cmM6<^h>2Zz<) z_PfO|ZmDeY^?LR2;9!s8bHzLA99>(V9Dg9*?w#`4;%&7Bsg?lZ?J3Xa?x-usbP$#{0iFYwA*Dq(lnt_jF6uO>i3U&g#sNt%Ynu9Ck>4$MgRbKyV2M)8jTc(wi{=B zw|iC-z4)|Vp%>+;seU0;D1<^G3U1dpsMFcsmjn(L^A=_IeFGqljqYuZCaDI>vMkkV zbtEe$_%=naGR9K*{QUf4dJGbTMt=i?XpRbnnl=&(n+;CXYf+NRizr6ZtjB|qc@z>@ z4n#v*Z8U8GCy@~SJ_Vh{3K#v09u=lpktTrzj$>(og%Sg!lI^&5WI+O9V8!u~(KQeI zLHMiyVHhOP5GCJ4Z6rTE3Zadg<^~O6Oa)NFm9T_aj^zX^NzM;Xds1|aa(^Qoc1}zU z5cAOpa32}>S>jPUM7l5MBZb;W4VzOK-;fa$JUcWWap7?PH_vb?;2Zxd;q9?>WAwNVHY=eLIny1zIeH^5&<66GOrd*!>a0VJUs*`?M_|V!uhe_mVZVwj*G~kGpGp16UsI?fiEnJj!(9an;iCh&0EXc9n<3)g-V-(zN^R6 r?DDzYZlBAnQ7!}W4_^zK|G54F)u1H9%Y44T00000NkvXXu0mjfjN%m8 delta 1101 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 delta 1072 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 B?H~XE delta 1008 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 JPDHLkV1llfj3EF3 delta 1922 zcmV-|2YvX-6Oj*)B!4teOjJcja7@{&gzxCY-L#F=!i7%5;m??Fx2cry=cLPgL_8&7W@Buz}vQi{j0Z%#vx^wuRo&ngUO6x1_?RUtlYO{@$TfI3JgQFu&~OqdJhsp7ammZ<=J|C zmTzo(kB*t}=%wo6pX=bALATV3Z)v8WgUOC&aKzt4y4HzMO^sZsj)j&@Pj_!^j-j2Y z^6lrath4Lj(SLQs;4)uDOdu!m#M?gIlo(V1?|lW5(}hvBn}RDZ|isD(ia4NJ6@Ol#5b2q9X) zrCPh3Q*+hxoq0Lz;-2*CsA}5y&9-c?j!63Ptje8U#;svUzT4&5m0Z;KU|oaOtaiPV zb-Ki*GB#z})zSCx>B6steb(@6Y>C2&TC0DBDk@Xv$ETEUG{9l{ciZ}3-2W6aV^}JE zK?i7rVt;Rby19D6$)>ZJTTy(eds&#lt63>tzrnL|KTu`2)p|&##ftW>b=Q!Mp`Omg zd`_iALuP9?nyG@sm|@nYjMMi3003@uQchC<{tf;D{uu`T4I{6={SEys{xvp5?Pt-I z7gcH_#@X|a>YMe#-YzG5M_8qK&x9N1BC%eB^?&>2O|P@VtaSYSroGOmP=kj1th(?w z+U(c$yw5`T_4uOPnTCSe#_Yb0&Gc#FSohoDf#I?$eak3H3r_$51fEGmK~#8N)t1#; z8(A2}GZ~T)BOyj01Of?8DX#Ty+pT-o-ECCjZn(QscVGYK_M7yg4_hcR!_Dq{H8=A+ z?|*qed5-KqD^;nHl1e30 zL&;#4kF-BHT4^(hypQ8y03fkQYET~x>VH#_NNm(&7KhM$g%MLD$z(DWiwzCMl7oZE zk1XO4>aq}u(j)LUZvdPG^@Dn|I7B5&V2D33w7#B+#FC?fgL=K*F3v`QF2t1waB?KV zLn1?f(f7*4Nm=P?bGZ>nB$CNwfRh?+5{bx_u#!RuZsyU{)JSGM604Spm%5ijLw_>^ zPZ)-o8p<3K+!%7Z)AGuP(lf;YA&v23ngyFsX&I(Wlk=b@9?kqVaAOfA2oxC35|ywB zG**J;a=|rG3lleP3|wDapjnneF$U8bg;k;%50uvdp#&lC1K|4gf%|yiM3I{VBUYQB zJY0C7NGX$9tReg^k4R74^ZRv5vwzEt0z;4wWtE@xm@O3{#Q$s}o{oFNin|NPfn8UD z5u8O(8f|WhsIa04I~^_rg~!Ii@eg>o6Qe3L!V-msq6ma8I<5eXffVs~Ap?yS<+ORi z5XvHwBynA}YR_0sig5gL4djawbcx{k(7DSS)iPNPFaQuP^e%!8J41O?!hbuv&I}}; zp@2NRUT@s{rP|4mU_!LsQ51UPaWAN_7Y%vT5)i7BUT->`j!#V7Ls7~B04X+j#6bEA ziiMgrQV4mfli@ft`3#4lRCA3?l789~F1-9~I)oDB^oP=1oc`r+&@@HS?8DXqDU3^< z8yg#)oh!?@fBDY2y;2bJ4u1f2zI^`p>8Ym=B)L#GUF~@BqT}WBTZY>P!>1AuMlD8Q zYuMF}KLK(3_T({@Sc0XD!CPtJ64MY`29`fbv;GshHp|C`Q_Fz>P9wD<9x6880)IHDYB0me#Wflo zAXpNy8`Z)e7z7Es+@X2Bhx|Cpl3ayTTMN{kWkkROzq(#a+2F@lz!1PJo-W z`EOhIwYO~BY$XU(!+*6k9u6=!>fCd4b2k&wv)8s`*f|>4so&RZ~sIiG!r#CsQgt>+F*PCmI}6!1Xq z^F@Eye2>xtiNsA%A`y-56EM>)-}w&yJIwlvOS1_c5cRbSd8W6Y{r-)UitBsMFU>-= zecdu44C7W_<)!;S|MkIYUx92llGnfAb9z?<7$bEt82o?gAN03%q^O=HV*mgE07*qo IM6N<$g0qk2mjD0& diff --git a/TMessagesProj/src/main/assets/emoji/0_1435.png b/TMessagesProj/src/main/assets/emoji/0_1435.png index d45e98989fd485855e508d4501e86fc3cb3f3957..af07b5150550b359b1ed31927a863f3d2a9c59c5 100644 GIT binary patch delta 2469 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 delta 1849 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 KMNUMnLSTYTxz^?Y delta 1873 zcmV-X2d?NeUrRxhTsKO--AEl~d`l~D#Ni4ILzIer-`di4 zZISBV(t3QBud1P7*lx1uf7)kZ+=SD3UfUBXFk#(YUM{sR_SYLz2p@V!&r-zu8a$i+I2WAvA zV_Q;unSWu{Xljj?n}S&@H&!iC$HKs7F_Wx&&BlxNyJz)TGj?uASZ-WuTfNjV-Umwn z003rmQchC0_pi_WM$7!Dw$K0o1c^yRK~#8N)t2R38(A2|iIIsAVn7H43((@;mW2X!-L|Xla_?B& z-Enufy086#dneszpIw$TGsBnN^L>7t_k9oNrrE0FM(N2kS7}^L|SI!jFVC3dw1M*xsqcpYJVUE$cX(7z=5o|-{)on(@_B8Hvi_t#Dsm+ z6?Ze@cwI~m$abfV_ODDZlq{x~<56TfoualMCyCh=v<^gZ#d&2+hl@zCe26w{M+`py zEfNh0z;@&*42S7Wdn5br3>xj9v(#rmcsml*-cxK7X(S z07R7fDwg>an}LNiF$fc$nVX+qhz2r*#exF_(Xca8q_p|lm>?F5@a6f1g=jRgZ1ekt z{Ul=46|-X0Qhp(7nW}0)tj;4sU~ZLgmP!P=eq^MYl@FQFX=xQ`l>n!IpNj;nszhRI z`BTKMR6UCVc<1Tq!hC(3mhd1w+KI+^!a>~NIolr zkktXamE}=nr8G@ba)GpbGAm!gdbkC<})`&_KQGIR(rIG?3Dpy$pfk0$#ZhticM92g$ z8>&Dcx?nxbK%kWILP*OKk!Uo!4Ispo6}%8=qlwV%)foUudgdxW7eD;;7-!b07NuFIf=C?51W=d!)kAWpjUs4LS)(y&*~}vrArH;!zkjca(5T`KdBfg{2!!q^S*DN++if<)q4B!mvOLcsx@NQBxN5Fc zHwpd7&HhGrM^|G@&ahR9aKcubYsw;lT5j&{e(`WIb@N6phJhq(^0!1$Djoc?bJv?n z?R}I3Ayd+nQ2h3VOMeExTKC3A&gU?p#w~4E@*T~1D;e{4HXKhVyGyhy^0(19$=Lb@ zzcyHKLSe>&|EvB0xVe3LP^G&|00000 LNkvXXu0mjfWLtkS diff --git a/TMessagesProj/src/main/assets/emoji/0_1437.png b/TMessagesProj/src/main/assets/emoji/0_1437.png index 520dd6cb073be6f5fb8ae0a28ced59396deb1581..a5f08d30ee8f4341e5df40a22c08078d89c628be 100644 GIT binary patch delta 2528 zcmV<62_N?14e1k*BYy(TP)t-sM{rCrF)tw?AcBH|B_uOOHb5C2Abw+1KR`iWMn9#C zf<{z=BO)UtBqVTsk}ox4(72bGiHRj9EH5oBk%)*K93&$qCVDR~ut7oNO-5k0m8WL_(XJo1#EKvJnyNxIF5zC!}x{=cy&0o}N@!S28d#yc87cwkxkd zK+BsZ<2gBvOn)JtpP$~}N~VM}KoaKg&c!U06agJadkYj+~c} zMMhKOa~z#5p@V(b3SoOG}=fp2)9p*xTf>cM*EZf)pz_Z&l(DOL^Bw$^mx7Q@F?rCfNG`XJ{$A%po1W3`#X7}@+y3)7!u-YSf1+~Dk?y|3gzDVr z-s1j>(Cqrf&%I;X^!3)YB}&u)00uirM1Mh4c-qyL^;a8N6o4m_5FrWf#i6vNc!5Go zU7_x>)$P{3TU~dT@wj_%cXy{Pl)A3l->@&C-NT**&M?32calja$$Yu*zI)#r=zjyx zBPeL02gID9^t~q|BO~8VU&z!Daq`a3V?>@}W)SSX`%-b|P9(E9c$*L0by5yUhkqF1 zvew*NDk;qehUf2x&t(>d*<4gq)N9Jm|M4cwVw8-{&m{Hr_3dU;uTGKX#Ypi^YiY09 z++JT~*5P6%1L0*KxLYcTtMBMA|BlMx7!CtRwj{r_!(=kmw||y$NyJ*tV^ExHN+lhp z`q1|FwHy}5i%C8`)<{f6aqXd@?SI$68H-UqH^znj7Ftvkw{|PU<1LS8G$j|dUXAPM zSQ7+=ad#!SFl=_gr>lScd^eN?6EO@G(7YW@ZEZ^uQwS`I!_07MyDC>zRrR5mz+wc< zVpyVbDwH^Zc{4J2Y_DokRjR6*x)j*Mcjs~##IYM(om-i!D%5EQ-`fiuJMr38@wlYy{&&{o@+#xCL9W0UcotO5%+--UdYFcxkyga`gJb&}^O(rmolKwOFdov7lLiXCL-+#OMyJyb<^+l^60!3#Q zeTBDQILpO1>RQB=Xp8`K4=ORB7~KNVCrl)c+AmI+_YL3Jh~g;5w%{c)*@*~DW=9XHYc_Q+0ow+wdsKmEJx+r=miyueep= z1UM?(jZIAyrIht=*h4Ry@kjJ}y)aLx7Yg+bDk`cUWT=Omie&?$J?GE3&`IW7LZMLO z{=nV+{wr?Q-pnxarGIkKstxD2(8;DyBh=*Gdr*tY~e1<_JeYc$pOxGB={ASi+$qO1^F>)oPihr-=A6B!3iU+;W3RC}2#dP+&StD-NGKJ;ic@;6lDyE#8P> zLk2aeHVk3=!?_N;r`p|l@gIyS;vtq8=W-4`@_(VVTZbDcl4=-Mci|5o6`*KZ{G``& z60hvc1Icv1_kWd3#7h63fXjhTnu%ztL2XnHDcRNrs#wt+*xcivbs=KH3h_!h`|@!geN#N3#jBp{(udfF@ zhEXkQY^bqgNLjxW!R##!HWV)y^bfp#!*c?K$4%3iXyR)x=Uq>ks zaponAeKB>0=YJKfOa*`dz=Vxzu~{i)rXQ}P4A|q&(Sq9r;DFgEwj$hX9aU&EkV{ug zu!ZgN<$sF&Qp94|NOlo8W@*?N#%EJDSo@- zW>Mh~jL1>KcG1<_Le}A0U2{*jf54y?ZXqoqL8?^;dLOo{XF!vZXl=w%6vm5VJ-ybc z$u1lVXl`x}!0>2Nox$>0%2vQAiW9cf$(v@r6@Pkb|~xUSehT0!i*IDL4%`K=?lZAza zq*=Odo1615=EqtM2K8beXe!)hBnNNv5sU>TNDR)YtEtNgp8sk?^jQ!bya2>7H9VK` qGd26Rx^?&f;f^AbxI57waCvRN&X1g;dW=H!w*x zEl)Z!Mlvf^KsHl7Ge0dRXw&fn13e)g9u*T3Q%OoaDgoj|$*SP8>%H8|UzRhR000DFNklk7vL!Q9 z?8L!_+AwTwSBAA6Gk#*38N$pAg>Aofuf1F>YkxdT%EfkWWj#JG+t~kB6z!#r*CNoa zTPrJ(;58uLj-|RHUabUUWa&a3S{b^;($Y#@iGV{B!O~rwPh4o;r3uklt*)+C=WD9Y zuj(*NPpfv}7t5<<&~mw&NZbl~!>SQfdpebhrQ)&jJfveOu^RK~Xi8-|1s)*rcq+48 zE`MiY@tJtcZc*7-lYK0gj>W(UC>6_OVrHw#zUbz8o=XFuW+1b?yqwASE$R?HQQ%QB zotl}MiN|B$0_0PdPote>MIy;00RogdrX5o!z0Vg6`4P*cNTwwUQoRpWc#ed?# z{t#A!@+@*Hn^F$3I4&Tut)&1e&dn92&oNMdN8mz{d<;S?BF&$*faXBOo{xZVqeDQg z%8EkiyEuju?H1~Txw=}4Jw0v=a~fDCsCYi?q(1~l$PEkt6bjiq*l_VEKq>ERtEJ9z ze^M+KvLGq@jc1ex6YBM0OCc+PvVYROZ+TYJN%4GKkn;Jwl*|2oEFicBnrvkApzP5x z&*C>UAtDWoJ4wKu8X(u(+$~ z`e|hmL;BuZsye%wNY*$En!MTj?+duQRt(EkPpqBoW`anHJKIy=Kkt0nuwShRG7)Oj za}G;qSKHat*}AP1{nXUx=MA*Ay|#bOjkeqd3$HHdH+!_-^uTO{Aazaw9#XF z^>TZA>L%7)10{Lz^5=|CY!%yg_aC3Wjh_AFRxn0Sk diff --git a/TMessagesProj/src/main/assets/emoji/0_1438.png b/TMessagesProj/src/main/assets/emoji/0_1438.png index e9e980bf4318d09aff319ce463ede7a36b45ea24..ddff5ab9e65524e184b070483bdbe02dcd4be2fa 100644 GIT binary patch delta 2360 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 Hu0mjfG>^lK delta 1689 zcmV;K24?yC6Q~W4BYy$2P)t-sM{rEcu#)7pk>#|HuCA`wzpLcHpyI`^+rh2Cz`#X9 zK@1^Ua&mO*$gIi5!^gO+;l!)qwv_P8s_w+0?7^Pd+1c&Jq`$nl)XKv3(XhO`y1Ti% zgM))dLP74tq2Q{8-p;&nT1-VjKsq)?BOf2)uZkulGx5o$5PuLe<+P9V(XZjKjGUE_ zCLclOy_}nxpY_qN=ed-)wzf=2N#n7M^UbSua&Ya#pz_P8>f_seZeWy?ln4wuS6OW5 z=jYD=$><85njP*Hc~*TvPJdHC_@d3%<*x3#mT zo{orvp`ED#3x75V4N5*lW@l=T$jHcgacf&!TMH9f3JE^Z!nHCdAokC!-QC^v%ct(Hr*Y;1?{+QN-^YV+#fSYCq^Gh?clhN+5hQ9UlCg>3nhZDs%f09|xa zPE!B`D*XNv4hb6m5dQu>N&Yd4m#A@*K_iBDF{Jmgm_It&-(DkC+)#=9P$3D|G000C> zNkl;NxQmt0& z6PcqYSE=MmwP-Y2iw=rY*lV>YpjriwzFtuZkKOH#)~oJHwOV~8awV=|+4p)iby~02 z#VX{6M&$HIqftLR>=WA@yWcJ&jj>ap7!i2}Nz?a$*t zEPiqXh%dB|1ociBuMN629LM7)C-L|RU_)>axi=D-ZTp#FEfbGtz?UZzKWTrX5Vi_! zCq`oqKFtPi-~mq@{KPP?R#+7~!m=SJ1b-pxz`(zZXTT@$OFMo{MLGv0LSi^**{~FX zEU^p#za}=N>#~l4e)S2;AstH5CaqDg36=Jw=&NF(YpaCK7>w5>CU%6fppap)0|og!RW1)*%&Rkf1hR;RmY#O`(It#ZV@c z%5;OGSfVkGh*BWqaJroRhOs1h@qgP3F$TG1DqSvSFHXtuY4Y`m7{fX!WxCkS<=q$V z(42@AuD1!LA1Jb1u9V}lA{2;K$s5YuA&%pc*=+LHR_iG-Z~I|BLnsN*WRs!n`xfiq z@SO*XYTvM_)qvDt;a-hapc7Qt@FwD-8B&i}j0EOD-y1z3wkIoHaRTN!og>WfIH+L z%-Nk{O15lgP4xi}vn1rUu(V_OSH)ag)(>aR0>dzZE+MLs`)aP(Ti7V>G+%k3=YVcm j-;O}f1W`c$RsI2>BN8!#RcfjQ00000NkvXXu0mjfto>%| diff --git a/TMessagesProj/src/main/assets/emoji/0_144.png b/TMessagesProj/src/main/assets/emoji/0_144.png index 227fd09459551edad124fe203ac997f83f44b45c..03ad5c8cd4399b85b79eb1ceda20d81bbd27136f 100644 GIT binary patch delta 667 zcmV;M0%ZNi2(tx{B!3}LOjJcja7;xrD?>0TNjEM?G%ZLrE=DseT17fgJTyfyD>Nk@ z7W?b+00007bW%=J0Ibv&JBwhCM!>!R00KHmL_t(|+NGC)Zo?o9L}S2U^Zy^bfrE~O zDzwgJ)fBIJy4nY$$FmX_k&xrzRw`XW$xDb*Od{Ed$WjJFoqr4lLL~ZHAq6(b*Nadl zhOearf++i%F}tAG&5#g%(Rz)D!Ha++ZX* z)a%=fam@v6pr5x1j$PP7fNbeKSs|hsRx_#240EDY4Q<6SCz=nrA^>QeeA{d64^y?7 zNI>MXCVyi~ni%~$i;DW0EQneWTiReih}OAv)%!Ui()@e~M3x@Y$8^$ix??^6!nvOt zQaB-&!`4r`HC03tN))I)jr&`sM=VBn^08N@3Q8R#9qHL2;B54;nvoHoACC1gbHI=; zBR#%Xj45YkrrzK&ee!)VNK6#|)uwj16}v8_KNJ@}MAY5#{s#a6002ovPDHLkV1o6~ BCL#a; delta 1074 zcmV-21kL-i1;+@GB!5LvOjJcja7@yaZSl;i?#HCpo_WxbYwyRT+^B=dgImv$YQ}+D z@5ZF;z@7QnxAM%Y=ed>Rv5eQ9cipCe(UNQX-M#hFu>0V_ulC@o0000BbW%=J0N`Sl zM5oRl{eH*ZB0YTo00X8;L_t(|UY(cedLkhZMb%!gtzun#|9?jvZb2i-OvcDD$**v% z<Dn6lQ-6I#^o1h?I2opd3SBV%%E zhNR8$uLIu&i%ErNIhK;Pj*CM#L(+NwtBiHG`*K^=D0p^~c8<{yq^K*K@LjQJopUy{ zFUt)YwQCp#MSrl&Z17LU5LtIs-wY@&X<&%ckmdCK-FIl49k0Mpqwn0;H+h~)=9r(8}GnUeL0P60949jH1=O8uvDU) zUUg~n+Uu&{8B!)OP}Zjbz46h9`PQH_SB253qYd?~EPw9}#sw(2&q7kfr$XuX1`3ia zCX)q;7}>6PV@OD?kIn)n0RbiJ*I$hyNf8|G(FgB+z~4~uznrERilSyx;?;9dJ zPd~N6*7=Bcx43A!UrBW;(u<#pu(+ti*hqUjG)TMpTcOhvo|j5P!9~%cm3p*#FuFpQ zSJKbg(SO*75k-K)pa`6RpP)Hia$u30i?2yiE0K02b?79QDC~70AR$*PZ-|K^qfdz~;o#9&KWY=ds z#-u6anI*B3T*@=h$E^ngWo6Uaqde?h<_U!tL4R;86CsB6v0hGACSU+rEBO;g>qHL7 zEhCeq-ImUmLOHHLbT-!eNc7c_dsa*cr((c# z1%EgocoeqdIN-42$SuqiJT?MHU;mg+L9MFLYHALVh{L#eItCc&{DE4>P&U~ReF&~% zE6#*W&;+-~kS zCwP?oAxHGR4lauA@;O^^Sf-|k>x4o*e1CA3s5VkUG{M@-;3);zP6bUXRD=Rcotp*N zf@7qM*!g2lv9@b(isCV;xH?-E^TQ|#Zi=|hHe&hA)-kK-!I+%q5vqdN&aPw=1sR&I zLS02sm>#E!P%sQ`_MWwGFg*9X0GlW*TkHH}EUxt{9SoC2sH^t@lHlWY@}fSXhbzR- s8}P{}OdH^M+~fUzJ=A3$1>Ok$07*HUyMb%k{r~^~07*qoM6N<$g3P}jCIA2c diff --git a/TMessagesProj/src/main/assets/emoji/0_1440.png b/TMessagesProj/src/main/assets/emoji/0_1440.png index e3139454a3cc4e460dd6a10c9bf65525d0b529f9..0d5bb8d23a2c2f1cdf426e61f3aa29302757db5a 100644 GIT binary patch delta 2294 zcmVQ*7Z`SPchwmgQdVZ3K0c;!Q@@UHL{Wgmr=zfY zUR_>ZP*hZsT7OMPS%yeghHFSHX+2M#QO?&kYTWi-|uyJ(ZJ^eK9eKU_F03JAWM=9WOC4D=I1x5D+3GBOf3j zx3{<@CMHfyOr)cu8X6kDzP>__;^N}9eqV5JZWR?2N?M4ktE=hi>$`?yv9Yl@ zIXRS+lZ%UtHzp;-!^4DwgVxp6c_bu1N_v`_ooOQ@KQ1d+FBAm`30G^F5fv(KNi4OJ zd2UWJFn=~;Y(^-GD=Sc8k6=3`RT&wes&5?%V(#46~;OfVP-O_-a`tPg$#b&>6000HyNkl%@&Qj1D!_K*32GEYk~FMlmy)nK4}czj|dmnRLc>*E{{vXQb7v zq5}Pkfn2CUZyMRaR4y>Y<&ig-WWp46Gh;(T zBSUG%T7<=rnI*PGNYxg(5^UrMr0J5&3`hH zFqEf;?}Yb@3^-aVRI%&(sK>Uir~yTKg-txP>sy=0X0v@#jUqQ8VHx(>))Wp3MKpp8 zs*i0^+jEaCDn*gif(*HU6>z`J7WDuH>8DcP9J+U}w^Cz8hdbK_avq+2SW;4Q=jF?nzuN8ILJYIy9^To6oV7m!>(vH!`$#`#nYzJ$s*GR~ zO8#GWO7ZBl{V719@U8+y@;ZNoMyD~#w7nO~FZ7~mLMaCV6yrPTrm<43Q-4=y?m8$5 z`UxCHB2`pBhVk#FQl(Pmm@9QUZGIs7+<~EpbR|snTd>0_eu8(eeDOZuy)+5Z=5bRv z0i$zBfB)hkh@YW&;KdsTTz`aZRWwZ_$#JZI@jHGYt`rv+52Sgqc5qn}w&)7S{NB+q zW#Ctb>hp<-3D?9x@kAPsXn$ff7>$O*4s7bv<2k$(@{2B)tH;{oS_f$2KmX=iiAu5M z%HyBjknw57MORNxeDvqh(PyuDGWcXZC~>leJsr3A@=^2vtTn$3!mQKj#4rpTStrJ_ ztg{n3{sWIvpo*S&yeD4s(NXL#IDw;6xqFX@2Oq@O6ygTw+rR`1vwxk}cPn`+05w`Q z471>|4vwNQyIjdHgy=-tV0|Y;+r$C~`v#psd~!Fx)#7SAD=W+Tj$9-@+N9H|;SH!x z^Io1IpsR7KHER?oAVY&(sigoog&=+ed3+e+H>95dg*C0nP*-b3S{%m-#E(+Ifvfr5 zbjsc+GEr0v6a)?e%zr0*q%Sd#sQ)8QquF+MmuJPZHWbyASYFUKzKYZCl`uzg;T0cE ztxkntSiPkJk{A7W%$gOqj@ER_8c)U+n(uaZH={Hcc1IlZj)*(VNvY=9>4pF8DKFo& zFM7jA^s^_w00w^&iym~(&Vp}`hx{a$p#4Y+@zVj0l%y7>XMekAZ{Iz$nZhtQ_|pdc zVo_ts{e@QqOu@l0LnACU5K%|6sFWQ5}P!j_SFlB8Ljcr{)i+LWSCf|05@2VidgL{WWfmEYM^4NEyjl3GkAL&?};NWyRq zwpxuLRk!N1H-E{Isix3%2=u>PBH-p6Y8~a^0?4aaER+m^0~+KaXs!M{M+O39d)X$p zmu9WlpleV!5kXRlQpjBRScW9R1qfntJTxAPC2=^dFrMLpeu|PX?KxZh9@HC8kn;q~ z!f4=@N;5|?6rP%XoO-;F!tn$-SE;Ob`@#GXv@ct$e`7Y&Sx{1Ps%qjUsaw$w=sHngY!=T9P2U3LsVc96^B3 ziR~0+rBc?3Iq_ht4EPu_Aw7TY+`0480OnbY&CtIS-_el}dUqxoGow!MG zfjb-#@Nb%*-i#_rgAx>_nbz&r;>J8*BEXa$QKp5eBMg{RA9ymr0D!Vf-GP9wwQT!6 zEjuqSzha|Qs3@cpD;y}EEv%X QZ2$lO07*qoM6N<$f*|!PB>(^b delta 1669 zcmV;02738{5|s^*BYy$HP)t-sM{rEoxP{1)Wxc(<<+qCI=h)S!g3Yg)&8&vDg=7dK zThOF{y|}d8v5K&zRm+oV$ckU*-qqEyfz+aV z!mXITySdJlY|Wc@+^>km!^O{-ZtUaK+_a8UReSK}*vQ7kNqgnfbXJy*9haDX`+pmbxpLoNPZH{hK=;GPaqkhrCe+dXJe}R$7$;!L6vCFomy12Op z4omCj;m4!LYG=H)ut7jgkB*VbtZ|Hn zfq8dz5fL=0rGKrHlAN8In^R0j>Few9@asWDMc&Vf=Gm0p+Sm&dSkTJJt*EpB6IaNK zU<(sk-m;6>r-0k7hSs8a)0}ey13u!oki^8qxVX4jSXpUmYR=Bh=H}+z-QKIKtI(8c zM@L7Kla<-o+2GQOV`F1@czemn$k3#F<=B$d)YRfFtT z^694H;^Ls7q2I=@8Z~Ceqiw>GWYM&nDk)dGs+@IPOJiw^J33)HIy%IyoyeT1`_?6Asc zyRO~N;qAlL*R0Ofs{`Ss000CaNklawm? z?WnuNT}J=ktq#mXc0y=sp7xym&Y|D>*Wa!C-G5sUcj%2Qo9LBMMA}t{nhC zWq*#3pF0~c5o(!>0+7yR+8Xd9J^>&@Lkcch-EIgTuqagVy>Qs`*OM zFPW*%^ZUWzKKhll^Q%l^PIX>D zQ=OulUXdUQJwxc31_qtPOfivG8$l>L5Pv~@IfNkb03Q#X0?sQbXNpcbVnJD0&4~s= zW#!iOo<$enxb`MVHY^c(T4!711A$zH5DzS=35`v~QIttiPbXazrD~_b0?)@QN(-nR znsJU&HA>7Sg#^!yo`nh_#|x_j(X;`mX^q4wZG#XpZ3BdRK9svwT3FW;CNJeONq?Sn zJJZ@PrqPr8iV!*!qZ~D@mOiJGAi&Q1J5`4c-EL6h4Th zKB279Uqt>Fcui1>0sM^2Jh2!C}4FGq-iFM4rt;eXj&Kf(PZ%?qLnUo;x^6<*fw zLOCes1!Fi?@cVqeWGa<>T<^`MFtrFqBl6%+BAHW3f9ge@=P>Fz%*A2_vtN`s8TFY9 zb4_)H%D@5Ga^SDX_x^pSAa+I1iku7FfO6j6CyDE)#jhH_5bC{wWN=kI+B{}eBdpoy4)YdG^rhcYwp3iSut@iKD z&AH2NVO_#rXnw_Ry}nsT&m2M=9UW=4rP5Og8*XfiHUH}{HC=yPqOc%9iJc`RxR~u; z{U#JWT^+A4&sd~oLJC8FORN-1>(uYD?z2~8#P^8o8hoN7zEc_{@n6+HSnWis1{Wm} P00000NkvXXu0mjfxin%g diff --git a/TMessagesProj/src/main/assets/emoji/0_1441.png b/TMessagesProj/src/main/assets/emoji/0_1441.png index 42cef1b56e9e5c53f829bea3e1c3a6b00be2d97c..21266df5e5f0f4cbc5d1ed3b62177a7fac22b9ca 100644 GIT binary patch delta 2272 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 T8FnsC00000NkvXXu0mjfIByLt diff --git a/TMessagesProj/src/main/assets/emoji/0_1442.png b/TMessagesProj/src/main/assets/emoji/0_1442.png index eef5cae0c31d6b7dfaa7f311f03d403fd3214bed..a66e4cfb277d35745c6fe16b76ca864c6d0249ab 100644 GIT binary patch delta 2180 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 A(f|Me diff --git a/TMessagesProj/src/main/assets/emoji/0_1443.png b/TMessagesProj/src/main/assets/emoji/0_1443.png index d492db687980fb72d803bc10ef614b80019717ff..73020b5f54cbd857030654753343bfa62e245a01 100644 GIT binary patch delta 2571 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 Eg3p3%N&o-= delta 1928 zcmV;32Y2|96P6Esj$|O%{o)I5G6CXm>ks8N@7W>99^|~(aup_U@TwX7(n-uNZ^$8J4;D$|-hbEGj~e8g8~^v|%*MgV zh#m9n;5t#E8zw};A!O|5-QkxT{K`7&qa6ChHRGBY)s7g>A8Xf>9c5>I=b|1gDnGS} zMinAY6CXgmeI8k4qvV+z{?ScFVy61KApg@+etwJn)o81#ukPvJuoPMh5rRghsh_O~DZ-)B%(mGH7F&Q(j#IdpncM(Ca!_O%}E zrW*098~nvG^{g4-l^gxaI`pv{`M)OGEN|N}a{ty@;D0i9Coxq2$0Z3EI{wj3*ePxQ z(LLTOa~LH@)h27pD`5Q1MgQ7o93F(+HFZ^dy#C!_9xF`^3VPO#82+*s$%7j!GLHS- zcmKW@RB)~`JdoNSaN{<4IY^d^oWXNdSWzn}eC?_yqj)PsFL_r)U?eDtDKA4^d$-cq-T&ig&vixT>gsZBkY`F8 z_vyd2kxuZZOvPU-ZGW`$v{-;vERERE#sB~SaCA~mQvftIQx6IU{saE~D<2m96&gq0 z{(b(|SwR+{U@qvDO}+2N?Wit6)?;*Hh5P}u+g1e-}j zK~#8N<&{-)8wV7HS77f-GRTswnAtJL>=+@YI8GX5hBgHk7eUO-GBb0yO#iLBax)!I ztbcg5ed$c^qelD9Id{*w3;cISED)sptLL){iXQ@cUvqJhQfu}e2oZ-aJL&lX^E0|J|SVJ zQUih-i+;2$nJ+|z3_i+3^b-@FC*_T~{NAf5BU@BTy&Zi#3|k~kYutK|UXjHyR4qz!uNwg5VV5FwD-{XSVM=X$!+BjnJHQ$P2@8 ztExzYVBxS#DA%!gBXoS5DbpqaXMMVtX=CXXU`#n?dF!tHUgt* z4D3AB$RKnq!aiFL0V;~3K@rD_wW25p7iIvtC!JPZ%!%*Y+~m_14N=T7Ur>fRud_sK4n4Dmq37OK-}ojZR7@KS!){9~t+K{$780gI%V*#s{cRxN{ArQ8~# znHK?qKH7GgW_WS)S^KVwX#uqP^uJMp? z%kO{vdTRcM-{+=ZzFgk@s((IFLj5oUU2YspV`Fz| z;Cf==O1bBsTA5mZGce6a$Sf(z9A8=+xRwY*JO(Z>g!Q#?MgmLNonD$-yPbd)D1Q=* zF0L<*GkXkOzF4vm@{W&BcU?^&p(k(+N^bt>^)81pE0Tb|Peb0_7k~RC*j+6UbF`tL z5SYyS;vYFYU z=1*Xhmf)7a{hL=B`hR5caw1nS2R~1Ebp7Q*QB`p(V%mHaG&-b}$#IrRQ3x9UQbGXK zTiy1P+2Kg*x)2AEZ;Ofe;3PG?GN+jr>*BOSfz$A@H>&r6*_?K%_Gm;IF2UN5O|tl* z!)&~9qz|Y^VTu&WkI&9^qgh&c7$EEGk)=1)p1--j-_PZ{RezCYK6iK(>1T{aR{fL4B*13g^t>CQ_Y1-3(^X1hb`Xk$u*VdQ-S~Q`~{MFiC+$nI_CfY O002ovPDHLkU;%=UII;i$ diff --git a/TMessagesProj/src/main/assets/emoji/0_1445.png b/TMessagesProj/src/main/assets/emoji/0_1445.png index 7e67077b7e3bfbab51bab9bd06b5541be640d8b0..5ad7d9e4164cbde841aadb8274884a7eef1af06d 100644 GIT binary patch delta 2454 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 Uv=1My<^TWy07*qoM6N<$g6pV{r~m)} delta 1809 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 IM6N<$f)^|SYXATM delta 1694 zcmV;P24VTd5v>i7BYy#{P)t-sM{rDSLMU%QCV)*YJ~v7fB0^6(GkH!^j!-pfPAq;( zEp|mIeM>86Iw^okDtt&Q79LM`L?&Q8EOA07k6AT#LnxG8Ht+A@k7hiJQ#6E3FCrp^ zG&Nt6TQrYZG;?-`5Dsby2}W;2E50FOPdP9&D?9)C?VDda&VMj(6e3YxV|YC@R!~-! zOE)l)TsDhTGA}Mb!z5#WODsh)G)^`*<>1(7JR=byLjLyZz`VL=UThE(OvoW*3lBe& zT{fpqN4p?jph-mj_UTJsq1@KZ$H%=!Tb@K>r>QJSC?hP%#J%t8;fZcoyDwR%rKSi7 zVog(Kotl_TW`C(lac{QjS+MkykWG%naCY@1^{(KqIYyL~WH~4_QyUwD zDlm*&J19(2Yuhn$;x~CmW2#hhv08n)SV1^FD<;Fk#(yz7kib1zom4-xI8az;r3eUH zHYs=BJ!1GF^*qg7n>;BrAl^Xy61Xf8zK~#8N)tBdU zB1aI#cY$SDg2+gK5Yj29Q_iP+r;{%S2hGMn&RIFTn5((AjrNmPJivMUtQ?|;J@MwQUD9}4YPYl1=)p${EE5qhN@ zh$LZMMa1oaFDc!}Xk=m^sJ?zc!J0-y@iNHF`mLs^b+ zrGp=kr>n^$%QDS~c$WovwtRq=IbHy5y%@3#BLF-PZ)awL*_-#6BY zM1P?)nkJ2r&gD+y?DDeLfVwL_`s6syp5$^7S5renVYnCaW9ljzk00kEusjV2F$9+G zQZS#!<18CH=4e@gxU_0}5TNOiRR!fWrov&i61x&%xC+E$SBKEHfrL0tVl6HpR1w>; z(}ct`9Dryuscs+=)6*Kv;*tS#hlr29jjO{)H=9OuI*QgA|DDu2yvSXbuAfhUx@=GVR1RHEsJAYqx zliTgIKs|j?MMl-hSc?aWFsok9zjzz07s?F$a0|FG$XhA11lUS_6vXx~T80`qV zx}wOa#46!%>V)RTVWKE9Afm!XPfv2RQHwwz$@f(m>?xg-IUm})v-*Nn5Su^-VgN&{ zmDJVMRce#x7|Dr7c)f9Rb8&GU41XnXe7+Thu>N&#Z+GYRa;Nb7;NZhq^$lKAlQ5g*V-{Yh?~CzAQOS2g44hNsWegn!jXM17PV-rsp2!@iLfC=kxh3m^Lw^ z;`G^wWN__o-e%{5<$M|zK`dhRt954J%|8sUM65xHdPP&%jQ}^^~}Eg5G*f{ o*i))`ZR$-6_S7P={}*fh3Cq(qHv&PBXaE2J07*qoM6N<$f?*mU%K!iX diff --git a/TMessagesProj/src/main/assets/emoji/0_1449.png b/TMessagesProj/src/main/assets/emoji/0_1449.png index fbc6c89f6d3ae146f09e33a517a7faaa7a4ce2ef..251999353572e21d54b90aa4894ec41c6b8ec08b 100644 GIT binary patch delta 1792 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_145.png b/TMessagesProj/src/main/assets/emoji/0_145.png index 1021051f6999cf496137acbf41187b4c0593ecc9..210d5876bc96691410fada6ad080be50323d94a7 100644 GIT binary patch delta 1253 zcmV%58IR(+mIB)ZVcLy81l0t z?5Y^JWDWPbDgV`E|IkPL#53};9qz0b^|&O{f(hxQ5apf?*NO?vdJ5r~3fzzh`MxXv z$~^zmQUBFj|JGzbJwOTo000kkQchC<-l~#?64Fg4+VGGU?{#XB%*xxZn5Ko8-hRiljN|+J zFbwb4+dVVJGQVHPpFcjrV@jozloW~QZU6ZA*!PX8>(7!b@As5519BD?M46ES99a#2 zs`FWJy)(8ISbsJ_KpM6a+m_SqTa580Z`ZLkYPu$PeuvJ!j6L z;yZdU!Ywl@oPgjVN{Q_NQc^T5P!hf+xzkqqCtV4fOd-Df-!>A zjHz*gR-=V@&BnN~LI}m#ez396b6s8wD1@?70aZb}!o|?)cm;KW%Rq{h89hyH=i)Jy z>%R>tL@5+jk{|H&P)z@9MCK|wBSqP*3?C#ZTNTUxG6Ncta6T9Wf)Gh5VO%}(BP`Y5 z4Lcf?aDTIR&S`fLV+>KZZth6aJcmGo46u-}TkxGdinP}A+7@dg_Kj4S{kaUt95g-| zt;A*^AiiIhrfBR3pQgbfgt5^GA*G_zPB6yRZ8;RIfs#t=1SkUSMQYm#lFY@ipCbd~ zMuN{0I=b7Tu&!<=Rt&JRTdpV;*7)i;6c|EVDSyg#(!IhmlB!~=g3R(Esiiy=(PJ+@ zZ71zll2wt(Th*ByTdkNB*3CMYdh;O(P@>*`(>;Hs)Uq{&32vTswAO+K2P2PrC)VY< zX5R88jxms;U>OzB(^7e@9ir(D)c!Qp#ei7+NSLJHxk*sLm9$ZN6vWb01xal5YkMn> zQhy-{QPwDO)aj7|Vgv(-l!A8dM&;ECO?wgCYyd1^ za03K7YB7w)YOO3IB}E;UGDB4i+G)Z8voqkJAOxMLKnjuC5uq5ez0y`cSKu#P<`M+K z!d0{q5UTWo(FfDHhhn_U7yK5QgCIqeNPmf!dHHZ9H7SVUf~@O$8iwKGT|h^b@T{V? zro_Pc*ZnNpSy_PTP>$#@;vwN&S*?RLMhc-G2-&vt8^hrM1*h1`IImsAu^|R*^oED+ z{HtU3I+VfCSDE0nKhOt$9>DOzQTsuZ75DQQTXiZ7!vcbr4jpkWi5iC~ygz??=zk{; zp%NktgrL}+4o-^G+wVDfs-;{{&MzH`Y1K4Z+Mx(b)WPCiC^3XVMGvP(CEbc;Mg{JL ziO`EKPNcxAFX*99G3r2yB&}Qf6iYcNsOWCSnH02Je(X=7cp}Bn+Y8z)B~9$?=iq{o zs1T-iB&Uc91&ZDj(-{?luF1}JE?zoXPyjNxzM+m9Qh)Szw7fV7+~3n$s_K62=Miz4D*by!R&*w11<+bBE{|qfM4!n=t&#^@cHVE;}V|B znN*_pJP!as^nWo;_G(}PX~<8W;c8e?PDCW=S1CDnSHls~gyl+HGqW=DI?tCP?4{~J zhAWuonJgtmA-#HcF5;Hp6TgiR$R8N+gFO~;3-D4s!qEz^Z-)!_MWF2TqVVJAeFTVA z5l)KNrWkGw0aEcEB^OJm+dn95xGw^WB#RwDLIE*t*?({!7_emBrpIr5ET$^V2L@l( zTuRABeh8`LeVX?Q@6$RHl*^SUfwD=7T(u%DiB~- zXkzvGX@3FaVXo>x+`@_6V4AAp$p-C$xo$)iv{SkGJP`#pZ{ZpOgblJ^9UzK%OO=q7 z&Thfr7Zq-t+dU~Trj$icxEn<8#X6bChVfVdM7iAF3?oH?^opi)SGX@9>0!{PqGLbD zGs-Zpv53Q_u&<=V6eR%&$DyjCuJq)aZ9pO+$5`}-8PGwqm=9R+? zuq9R2R74@_J)Lk=nEA-&sA&uJ-izwkko9F&C?gA|Y3jOe9N7^$hlJ+2-g~S7gpEC& zf+K8I8gWP=3Si1PRSD+;8Sf>X?-?%+z*sn!``(z83Z?TOj=VX5z?kH=%qP}S4euG( ztbg-hRKXFSXi{URjH4sLox>v@71O(yZtD< zAS)PUW1GU{B;SdoC{vrl@mc}uJlhqh zifsO>XdQ<6yJD1V5$%fM&k8%$f1>T~v8ei*UAJlZh&d6ic(v|^^2EYoNo?N~?L2>t^vgrY%O6c{xC0000< KMNUMnLSTYamEsuy diff --git a/TMessagesProj/src/main/assets/emoji/0_1450.png b/TMessagesProj/src/main/assets/emoji/0_1450.png index 437029ef2d5a4036f7904cad9957dfc120a1de45..f5e5a1532aaf3f64ad17280ad6677b30f31638e7 100644 GIT binary patch delta 1686 zcmV;H25I^K4WRa)xi|4GTCXC0FU@#>P#_N-?(Z#-bt}B~d%J z3=Ag~5D`W{KPx6M=*_VZ6e&_un1q9d3k)L3GSIL$xUQX-^y}SKOGzm&cLxS4=D?Zg zw~)6;sH8`$txv2wM1U_gjxaNM6A(HuD=S7pMG6ZQ?8BxB41XyH2PFXm3k3xQDj6!% zMAa}dj{yK8Qf{Y6VwONkcr-h5`tjQ5(zPBLj-;Ta3=0dlE4{jaSriizJuNavK}o4r zsHmi&+SABDPme@Zg;Y&PND{r{0{rhd98PE-+(KXqLov zmlzgHT5p=)rKm_}nYoyOs6mrtPFBaEfEyt>J}@Jvj&ZkQq{)nb)Q+avrI*u`lA4EzKB4jDK8{vkL1M)N8yfhU=KWq{)S{{7&ySeN^e z?N4*Kkj(S3`!i%_#`xkNS0`TMOKt9SxBKauiGT4zPUTSO-P@x0JZjjR>GNv$@wUzM z@RWh2-s`TqwM+V^x9E=Z{+jWymeFT{XsYc100X{BL_t(|Ugg$TR~uIl2XKKFc2$uO zU;z>aWH8+}m|k5H$4=bh)ZTm9TGV^*^xiw}sb4R5m2ya)R+GofyME_CcV^B?@xQ3D zYk%hJ`u_sx&EqXCEjP_7D4;gq3x#xfRAw9~jOTs6d|s#1C3M$d#8^n{LqAW1P@RJj z?ZW1!FA?%d^#<%UG&eb7L+cX+t)LwOPGw|`UlSTbx4f!VM{ulB4W1`t(4#!1D)x}J0l-ixWzjkYdQrj+ECzR>vw3j`?F3;01_z4 z9hMDrN41pD1tng5nGHM&I1edmv{etfl&W%;b|T^{3hh@%D?ljyfTi~lL1(%;hJQLP zs9DekE(QidWbcN>$D1qPlu|RNe;&Q!2JY3;oPbYvxzs1TT!W!dt8-`)T z-P99_*y4#jAW>GojrO8EI>(3S8h>5|5fzp>)`^InSaJ(Ue37&kh(+RHqM;fT;`2Sa zJMf6Ma^dZX42ZZJU;g=7#`$EC5AS6%)i@vovAwWlcQMCtE`0p_8zbZskosw9VZq~C zUL(RsxtG)s;sFxuqIh&1POUN}IDi2` z03a?d&Cc4zX(s3WI#D z1!chyJ@ywa78RuDHPP*I6|PIuWl$=~o2BuxKx zLC65?heC+}UBJJs6L1TqT9d?ZqNMt}ZD3Iu)%RhY&N z5yNDKY+|4f5&t^!!9*nSDK7uqmFr$Z>puijn;~+)UnZb8es_P}@AtQ#7F2DK$m)mk z=Ao)no}8czet(DRG|`o>oRT>XjltlT%CO#|K26u$u8_MEHQ!fC^oVxy{~yjs gH8pix-bwrpD)c`N5f3{l?f?J)07*qoM6N<$g7^{}761SM delta 1775 zcmV82oOzwZ-&$MLix&zDrwfEnJDBlp5E z@3JHL!Y=f%A@8m#^Smb2iXq&UBIu+c=%^(1zAojcCKY|Z@U=sw79I+vl_}8hyO?z$yB_BO5Vb^RpR{sDFsjtv%R}A?2YWdz`@$yw!yuJd2oEh|my2Wj(O(*d!qSByhse~zfehG> z8&XV97BXdtk7@eOSp4X$DSWv+fzU`=d*PZQep@+CLP9#O{VzFHGdWYIX(%6ev2}`g z{NIUjhky%txPJ}H_{~^lx#0QEU3zRp#%&d?hBjcq`&hmBz_VeKt&SNlUjN>A zvzkzWnT7l1r2NJy^|>Yg$|w53CjZeW|I94yts(NX9{0T_{=_5Onisfv4H`RdE|Sjw z${)>*6Z*IysAvlK$3P&5#*I+~(3m0r(LAnl4Y`CI^MAlFeL(@@q!yuK2svh_6ES5d zN`U{s7&l&=TeRc;)?hlC(mAKa$Zb%R1(CH95PgmBtLI0RFHJX@c;SQCVIFsVWb>JhquU! z#&;jIn}0@+aX46&okdGkHYyzd@2J4Df+`~);CWjap#l$ z@bZ(@F%%6(g1l(YGNF8UqM(;dDsnoWi6$vK zWfv>q%g7VSGsPVu(@G-hPEvx|22D8mL`HUpVziW2&Jt0a%7YaMLonsvdfOD^IC?7) zPi182o7l!uk*$G0-os4Sx-z zL4P#*roX$Pp|{QnKkr0AZR0ma(a!T7-!|435Ew$Pf2|og^3guuYmMfs>pBFXv09_i zj2s^wy?zGrX(PO#uh?9!UeG)n$pV^%WBC7t&eoUw*$WH}IKQyG$@Z$?e>tRYBfM0- zkWIC>iA|P46Hd;zq4h3RgDiQ&O@Azx2i=M`P8!gzd6%;BYTweF6PB=<$-tyGyyo>T zdA)1eNr|f?U|T_vhTGb3crBZ-_D&yXhHZwGB%SK;-_fcoND{IcDg(oq0P*77P**Xe zOAkeq*%@=~?GLIjiA+N|6j8*`6`d2?t1og{-L7}^k#>k?fQc$)Sm#a8lYiOA^V8Gw z^N(je;}vY65W^sb%_7lN6CNPEoCe0zS)Wq9GoQQcaC4R?S*~3@X+Qh~ z6hUWYNQNKAR4rh|%TNfSO@9XC@X9$)vREOF1x7HD5aBJPND10`8P-Q;uMLlG`d&dvRhtD%VDJ|#mdD?=s!>@Hylskwi@=6v_yLCJpue*uqndwD@{ RzN7#E002ovPDHLkV1g3xelh?6 diff --git a/TMessagesProj/src/main/assets/emoji/0_1451.png b/TMessagesProj/src/main/assets/emoji/0_1451.png index dbd723f69e415d903ad1ac197f93aee6281680f0..19beffa8c633eefb9da971e21661291a16655bb0 100644 GIT binary patch delta 1714 zcmV;j22J_r48aYMBYy%eP)t-sM{rCS6+Yarh$tH#NLYtNPJ4!J>40ydBqUkj(44?Q z$4)T892$BC1~1{$tieCR=)jT^7%}wfs3jf{0`(gj^}8q@mi=$cKiB0RS)z4nh|eF;8TaE-rB1%auAlPNy%ht~9d^5G27! z%Bn`P*tC+et$(SviD$fLill>9gkCDkwQFN!caBv~qK%16V3@*+U=0RJQ*4~#)sgV! zqTbup1`aJMD`>{3hR8$Djb$^%zqiP+Y4-1}uaQuAb#^v2QQNP5QY&xW%!Z4Ll9Q2< z`0n4Db9djkj6FqlKT3KkjF*r|UZAWsMnCx16QY!nbU^XjKMKyl7b(ae@= ztunL$1RB$wbto*u;9jKEJe-P%AA^7#B*QeLmf_f(;8k$4$vn zXO-;Ypuai9E-+)DIF3qanptj|*QtrNIlD7AXQ)fB`S7jAjD9*YK*WG>xL}!FKt#-o zT)=vb&wr7Qk632Ge^yXVV8p6nxnqMJB09HpNRMGPgIXy$peChPCU9vH+He2>0CaRxPE!E<{tW*93j_WQ{uw7OBTD@K>tW@3D%MXzI{f}2 z{g9ZnvyxrnLUV)ST4;SQ6)xpz{_(uVW|880^?#t~)BE{G?CF~JVnwdyphESCYPzq~ zm7)H{_R941v-pX&l%>tT-oU)`+-JIsxXk>m(DAR9(VYGi|2x6}00YiRL_t(|Ue(uU zQyXUx2XJ(fI8~4UAwZ&pW;#aL*cj7siJiFN?)2W9udDao>Am;nn&jK%IWdzld39P| zWq&`wZ~nXctTdPNe<=L4fV`xmB=0mpyY90BR602nXsav;2JLqH;-U@*3g0gp!uCuR z+<+0fV00G&_xX<%G#}e=r&b6Y~44$?2RsN`!xf68Q=f>vSr%Ui+MDaPZ+bIHV1hW!-a;)xEwJak&^Yi58Z1DyEi*3T!ib0> zt(d|z#LGLm(0#Zk*z{jZ8e;Q~5=azZ;)y+im_1tzB$|wfaKAkTf%p8$6H^$R$ZO<@ zxv5#g+m{dQ!)weCL~`j8kmzw4*?)9;Zk6DG1TO!1C4va|DiPXP_z)E0M#Y|qCpMC< zRUmQKWy}zp+)Cd<3q)wutVB%cN{zFjm4$^5AfvdedHUjoJ000Xqd)}U(#x<{Gt-Pi zwxyX3J^%ZcddOeE`s3-D8Hx4PC>MH@x~PN@&ym1TJ8!l^>ucusaRAXZhJOUwAv2Gz zA1uoX0YdKi>6tMJIhk5pKUgzgR6#-@fuZKjDcjm|JoaTSB*fSlYQvlg1Ohg*tOhWO zQiefo$V7UP%_cH~M$si<7ZORV)+yDQ6xQnc z?B}VhqiKqi)+_Y^nVFG7LYh4{KhG05 z3%t;AOq@XC9?wXX@RekU6Bnxf$>OmLwF@Rxb%^-S?_JZfXZap3c&nvF`&!G@6N37d z*7IYD&IuiEEnDt#J4=2op0L&0pbRIET+{WLN9)oxVFqbZF?F9Qw81QT0bvRn_othp?0Q2UX5WUX`gU@&Et;07*qo IM6N<$f&^VxfdBvi delta 1623 zcmV-d2B`VL4d)DyBYy$8P)t-sM{rE)y_(#rgypxB;;Dnjn0V*4kHUvxBq1Rf78XXM z*xIFb^u?YuG&LfM#!Eal=)0IuMMCPpp6R`s;jM~(ZCp1qGZlWo?!K8VCno2)mgBLG zSZ0Xoxs>g|oY9|rCw;X+J3K`{KjE&5_|2vyd$34DMKm!m_kYW!@yDbjAt5(BO^?Xo z^2MJKEL zZv5oM_uaiOk<46LSzEHjx%ASGhCW1OMqr*eI{z9-O#w5w!bHNw$7!~Q)V{W9*@ZU}SzmFD4m{mgs*cV9)6>sN)j*7uIC z{_fH#16bJBi-Cfs$!8Sf)zy$~p0-=PS-mh+N?!6a!uj%dXFTUA@oQ_|j%zP!} zLDqcq=FRBI*bieG9_s5Ga^o0kdWUA`YqeT#K7Z~+6&8t7S4(ZyjYh<4giy)lYPD`R zH;Yuq@O+MFllDrbk^>pO5cC(mH%M_PMXQVv=g&>6^DU+6)b>K9rfPj2l_$`7U$y1pN@9ka4QcEC7vJbWj zB0-Sta4~#&c~LweNrE6?iFhKBAOx~S(|@dMS0D-SFDx-U@+c4>?p5pcdboWr5C}XP zaYDavr_&u3nP9wF5<1wiF75iLaD$z6G+d3@=!1 z-z@ojVQWGK3i~z+WFQ~~|j*Fv4XkvhpHj<(xuf~!+C@N-XLI((6R)4gB zh}rT%ksE+-1trb+%2`pgh+@{aA#pnBR(Pn+sxMj2sww+cC2rINNq8A*^qDW2EUQWS z)}quHTr+T7N3s4pZ<8Qp@aG$}Q7mLLj6E!C)(958TTL zvYgF5wg2UBEnoJRo<d1waD?n%x=AeAWT+~vA-QMjn%KD_UPOyf1U@;&zqnaNZGVjM!wnoy zsJ5AUxBripeLy_6@dJ=!Pv?H}`13DU`P_Xn^fW}njXt9xg84fQzTSNPpzdmPLME$0 zXN4SmCd^M!6f>ufFcii07%>yVk5@mdDD*?4msS+2--w|^rxFHS?_w3!qel^N1FO({ z1T*#n%4J3oOd*X`0uDwt+=_7nqr$u672s2aXcGN7i=Y`Z3vN z!qBcn4wi2+16I@aoiWh`;PCc-@yt#vGu=R;wpj1*4KX^{0mFw VKy2j1Ueo{p002ovPDHLkV1nNwB9H(8 diff --git a/TMessagesProj/src/main/assets/emoji/0_1452.png b/TMessagesProj/src/main/assets/emoji/0_1452.png index 1f83809fe99f914be30d95e2a54d27e660c4e3cc..3351fc935ac0ca47757fe5204bf03728b1ff4cba 100644 GIT binary patch delta 1574 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 Q<^TWy07*qoM6N<$f}y(R5dZ)H delta 1393 zcmV-%1&;dT41^1iB!5RxOjJcja7>|TOR#%ft%PNlZCO+@8me_zqHa>1Y*n#&Ta#!^ zq;6EKcUrJ{T1+bwU9{k9KOne*U!rbQAAPv5iE(yHEjpOZN2b}EZC15@UATT*c~m_W zfx&oCIfZ$0t#?^MReKgPV{1h!pKDPXG+{YCQ#YK{7=F7Oet)>Bb60A2d!1@gfmuPF zdubYmzzce|T256mJ6B+Ulu?hcYHxUC$o6W?`G&R05iejNGFMJ;j9PSwYlDVuh?ahR zf4PNYxPoE4hh(*YV8D!LvwU5_gj+`@4`o3sHysLpRXkrgAB$f`B8S5(kI8RMIK+}^ zm2FaXN+-9Mf`4eg=|LwM#iNTFJ8mywq&a1!Jgnt1oYl#ga3NQfn}2N8xRp{-Wul*z zamMa?k(+v8QsU0GahR+bh{-ZsnkPztBR_C1RE~bU*(Q3o)D@)Ad2C000B6NklRh!~S6b9e`2_Z^wX=G=ig_fC?@s+Z8P-%A? z-T!~R6`Gx$zSw=9s_z0S7kN47q!J?hZ!&5=ot6^ryK?#HDVVvR? zXCdjL=YL09kru*h$UDW*H-|wq9_vM|lj0yc<0za{gC+=~AkQu&N8Ju5W6GS6Aof=kaIY`;yE`nC?74 zqY(mtjEL>|uE|VDk{jBia}q@7BQiE!(_CRCLMwCw0wQlXCfGA2Nn$3fi6xm4j681) z12eQNiX$27no4DG=>VCTP-0?GuF#av`j?2LnMYBhL}M^0#~CzQ z4pP`h0i4&3eryZ|gT`wI)iSK3z$p2#(SPq#WYF(7e#@bp%=%}DfKvF>U#3y01Hd>8 zF$tjjFY&362FOS;5i$n3#Lt8bK{CNaqyeg{-HYSD7CFA?$~j=O4MPD$Sv~st<=f|z zlatTiz8tOA5zI3ZsMg(cB72;)2rl-qv)^(W$e6(J@fWsutHiJSRTXiNSW05v98%PM(NvohVF1k0ke=6MH!}LNKts_q>s7 zjM*-#((dj4ATBN_v0JyFp9utL22k&$B@u#z_V&l?r{^03kqx|@Iu&84F;O?=!!9f(xPEXGY zi`D63#h&$-XJ;?hf2_D(!Z%*M+W4_r|8L-L$57=oo3Y7S00000NkvXXu0mjfh7_AJ diff --git a/TMessagesProj/src/main/assets/emoji/0_1454.png b/TMessagesProj/src/main/assets/emoji/0_1454.png index fcb34c73a03b77ed88e58ecb650c016ce3d6e38f..60f188e7b761822f2ea3b08a5a33b6feda901b77 100644 GIT binary patch delta 1536 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1455.png b/TMessagesProj/src/main/assets/emoji/0_1455.png index 8a11b2571c5b8f05d631287ffbadd709535cd4c0..20ae5df7ce7d9bab3f61a6f0b3878d6f90ac8729 100644 GIT binary patch delta 1656 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 LNkvXXu0mjfgcQ4y delta 1456 zcmV;h1yB0J3&IPKB!6g7OjJcja7;ToIdfP|b98p^v?6nJbKILIgKuDDV`9n1$JUuE zadURW!ougFA3Hia=HukTbRjV?FgrRr@wX>(adEtV5K2f#a&vTUadqdRALOw?_|IPF zs3zK!Amg7OI5#&uIy!cCcF>U+=B6Ovrykzg-Ft9m)TBaoc7J!mn@{n#DagUM*3;L! ze-GE5ANkjL`rMJ}t0kt8d60&Q^VE&aw|?=xJhzx+-IW>n#60HZ<;#r`+no{n+KS`1 zLuF}l;NITc*x0_kz1h~*h>3~hgVUMt*wHBg1@`Ep`f7Ws~o4Kq@0|b z?(FT2jg69$l81+f-=i4lzfe?AOW2+q`OHlI?#cV#oHjKzZEbC!p{S8}Hs{l$p=Akz zRuvi(6QpVi|N7MP-JSpT&oC`VFaQ7mN_0|AQvm)Eynp@ZM+7AO8m;}cwEYW9LH*DE%SBv?YW!xB<;DB_dG)ZKztZs3_sijZtGwT>!~Tl) zz{epd000BONkl3&%1}gz^fk-Ut}M;M;_Qf_$)O{PSX}lo*5p)$MnH!t zSrpl2P1eNOQ-GmK<#0n3oll>Z8vEvu_IEpo`q7e>$inU^+Z`xHW)*8h=zM?pTJ!*|wk~x2rq!Hw2^3(h(Nv&2ZW=gP* zMo|7jDg?u}X~$a7z3K<(H$-|4!#2WF>p2o{+C1q={<0-rH)Amuh)G7SoVC~|*%NwR?8hm%4?1^|INH_{CUfks?)M194i!;w2Fg5r4G; z5YHJ5hNlHhjF1RI5hntnj?(K5;2HELQ(qu~$%qZSFJ$iS?i!G01BwsAJ`iNr;+P3F z?x5Lqpx8yPsR-DBnegM7v%sE5sVa=711mw zzY|=fDi9G!@FHJFf!?G`Oqzbq3j$$~Z>kJ|*lq&R@pAys5sf7GVq%-~D?@r>=n~#t zWvIM_@N>dTi1BbZfmR<7Q!0W90Wk(5^a5f6yIA)!8Cb`#k_TFQ!||?{DSrduuH->w zmk1#y=^n_37>bmYUT>0NnC&sFAsWH`ccqhL818qtVi_u;luoBTYjC1ydXe6w5zwZ` zc&AQ4ni!RaM%&uI0xmXnqDl_HS$e(RQ2{YidLmtN685Q zZawZ45f}GBNlth-=&4zt!RZ0000< KMNUMnLSTaOFz?|2 diff --git a/TMessagesProj/src/main/assets/emoji/0_1457.png b/TMessagesProj/src/main/assets/emoji/0_1457.png index 42b76d1bfbaf1fa295b2664c5ee3befd59249d09..82823b9fe9e8e105280274e1a93bae8a10f78cac 100644 GIT binary patch delta 1467 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 IM6N<$f(eVUvH$=8 diff --git a/TMessagesProj/src/main/assets/emoji/0_1458.png b/TMessagesProj/src/main/assets/emoji/0_1458.png index c49a2f7ab07a3ad7034bbfd323c467d5aea1185f..8826f52affcc86e0e561b6addb768ea11e7d505b 100644 GIT binary patch delta 1463 zcmV;o1xWgc3&{(RB!9M0OjJcja7;;Biuds3p>0tp5Ea0|!dgm#l8(K*wX-iWb$(Sb zrlFuME4C~$d|x^r6%slN3Of!9M}>oi5*RTB1TKhfR}Bj|4-zZ&{QL?FGvMFcmvv&I zoSbY+E^Tp~v*Y66y}Gpl05CvL zk02gZ5EDvCW}F=xTb*oAU^W-JifG{8+b}R)+}__hK2CaNX1ax52MaQ`wX(OWq?(wY zbyG8GNGm{5h<{04j$%6?Ha%}sY@ENYpi^p^Iu`%6dlw(LfNO(I#bT~h7PhpU4OD;A$YYYc72oEQ` zh+`fcJ=E0IE-+whMkz8iX2OqXx1EbfF+H}Bd1E^rMSmX!f>by$GDJW`Zq3fmXFw!a zZJO!n>0B}tO=pO-?h<$m2qGo7%5y-L|00018 zbW%=J0RAHW4gLcR{jU45+57spODDIT@mrrH7Fyh@({B4;$MXvm` zS?*-uc7H?PU7FDBg{fkR?o-8`sO(PCweR)*>wc2nj(69x$j|tt(&E?r>C@S>wX^^L z17%4>K~#8N<<{4C(?}Esa0^+Af?FKN364`q59usPAZ%cP4ZUq|>fOEfn%;r`cxTMA z=a?t?=8^ARKYyC5d&ahJA@=Ji{wo02-4nyZCx655-*rJ7xQ9>v%Lol4+_4rAi^X!e z6Lv{&ZcS^5Aam8~rVSYSv7XY+Q?vGD(+)M( zbbs<>*W~%fGz}&ED{l9M%9r2Vv4Mkr-9LSi;hxRdu8^+ZS&rLZ_g{gSd4`1j%m!Sz zvBNeI!QQ9A#2q%nu!x`r!NeBFQq9c8C9?%47CA1n6y)`bMescCvK+gl7x>~L4JI-y z>(C2Y@$L;EF|>{d=0i#=uU`WaKQf4*K7VMb@;x9y&tu|fNlVS%15VXHjR>yk(0DMh zrZOxhQhJ#IZtFZreJ0d01zT48bP&AMiJ_CiG)X1#%RDuiD;AvE1rNyl28j5NaS}j0d#rUWogn!~w&d)@AdA#%UbWR~6G&<=FB&4*GZ;bx5(D6{0 zMMQ`$+p9$4Sjk63VRgIHBHN-E3X5YldtXA5v+v?%FZr-d@DBKlzpP%a-i5b+r<2KKU)vo!U>N6%*5+Y<6{y#J zK12lUZNz!+eT(DhK~LlO(lF2cZCB*npw(3y`llCX$?@hj^p75W?Mtlv=)c3{11Twk RCshCd002ovPDHLkV1gE5voQbw delta 1397 zcmV-*1&aE~3y2GlB!5s)OjJcja7@djZ_%`J;na@R!G`DDnDOYQ`SGpm;-1a7Y|*}R zl6Yj=$%4wUY1hSj<=B(Io?WPXL*UYj*tdYRepKA8gxRNlzlmJUoomXIXvLm=(5;H% zz?$EEv0E;o;@v<>}_;?(6Kt!^7R%+t$<5;NIT6yuHcB z#@W`^&&|!kzrVJ#v%R>usHLT&p`z2Ecbb`*(3x?TmX^1jij$I)rjv-#n{tzhhjMdt zgM)*eot<=bb$@JYYjbmRczAexe0*+ja&K{Ra&mHtii(boj&*f)c6N4hadB{PZ*XvM zczAe-iHSHjH%drHJ32WtGBG?nI#EzhHZ?UfF)=$jIYB`{J32ZuGc!6lII}Rv(EtDd zaCA~mQve!NX+hNg|NemY1(^T;_5c6>+yDRn`E>vP|9}7g{r^b++yDRn|NFx;{GtzJ zk^UzCW5NIZt^fZ=|Nr5e{Jj7F|NsC0@c*^{_5bC{#jF4S!vFvO{@1tZ|NoSLVI@N0 z-!T6EL7M;nP`Cf(AB0W z02QarSa6V5hFW?90QIFVY*kd=c2taR1;&}Xd0~7 z$$ZQ%XE$YGt2q{(^$ToQPz$?0n;Sc`%sew^AlrgX)kun>b7CZg5(NBrfu!IBasS_0 zgfKgn7Oej7e^F$0M=VC_}XO7?HyeZkLdDb_Iwh z#ebM&&-8j@G7`mpnLV8^cw;*@?;{qB;u1@ z_vdC@I+k@1f^vjc&eIfINCU8`+@gyB6No@FDL=>zmJKlbz67y+4j8{j)@T@u zECe9#MF3%M(HmmA#IW9B;w1*x6KF;G`?D6r z7|2F^GCJoP1-kcQnCJL<6IaM@d;V9E&&8j*00000NkvXXu0mjf D9N*OV diff --git a/TMessagesProj/src/main/assets/emoji/0_1459.png b/TMessagesProj/src/main/assets/emoji/0_1459.png index 86a323260ca2074ddaa0a453bd6b2d85e327314b..0714318451398ee9f5750816eb6773fb599059e6 100644 GIT binary patch delta 1423 zcmV;A1#tTG384#+B!87qOjJcja7+^qD?cnG6c9T2@a1(yDSm>`G9pfqSu-ja8%I}% z4GKB8udM6Qt1K~q2?i}ABUu(4G)XBKyu7_FE4Dl)8%kG}+1J&XbXncp+KGmTJ1j0j zF((oaG*f1rBOi_l3@L?BD*62U!NI~?G$*a7r8`7`QaL1sf`55`Oeus;EiN&0lUz62 z+}*&tyvxbS-QM16X?A{qk2E)YG&^#SR4uBitcPw`d4Zvso~{QAAEud)pq`?fm6AOz zCOATND=>RWUXCg%UQ1`4ARksdJ7(YB+YAT?Ffd)n#JycrT}4JxwzIJZ3o>9$HA!8L zOkkLrYD#E8CVxdqbyIAddqyWyYMPc@Gs45f-QC?hLvs!aH{jvn(bCgCM|ee3fgc}D zLQZ^&Q!$raHcn)cen}}zU5g75D3fPN0R$Q}IB7UOZ^OmL>FMb&F=2&GEGQZiYd<7H zFeqCz9eP+tDJWGkGe$Ne88aa;6%GoagmIjVf>>>u8h;r<78FZGGc5uLC#j^RPHdlD zIx>%bbv!E~NH;F^s!n$R003EZQchCI}h6->a&v_WZk%#_ieX}_V}6Nc3t~DD%IAK`_%D_?&HPc{nDVSmHzdues{=; zR;~A?qkrP&^mtvms{jB4Vo5|nRCr$H*VkJUX%q(VN#gKLLP#yfBnT^^3Ic*4g08yu zvb}xN`=s|CYSF)YzYKbjyUDrT_ddUQbIvo*NvQurysmUQy+Xm`in}wJubF2*&p;c* zGhc7gSVk}+es%+#H5y;iuoBNkA3tl@Sq2d(o`3oBEscg7fe30j66w}zwJt&2z=5vP zYMl^Gy4zi*VEJJ`r`2l_qgw0FLWyLOQJaQl^q+Wv#3M#yR8^(B{kI6(VvQjL9qISq zQqcUaGSzys-i!pjP-3-8HzRem`WHe_!n+!eyNzn{@HPbwd3bhhAe1+V0ngMS=K1o% z3V#L9?F}N7g*~`%?+q3Rfj=R52`of$xy=822TW}7I4TGi*ZwUqvB~orsTNZmf{B?; z%;TY|F@wz+=t>s^j4xUmlU%q5BvwX5bYEj~3%7v8Z+=3Qt{E-22qe(DO{5qmw+P&7 zcFn(mdEu$1=KMfnwd%(h6QY`n0*Q4xihoIqp=Knbu$R@l))Fw!mxhcnEIoi-0s5N9 zJT47X`T|I-8-ANe8m%ad$o`WP%H=Zl=ji=X=?GLpYdyRuVPT*d1EKUDG708NzckrO zOH+;3_V#1QF{?|L$H%_P6|EW#?o|vzd?13Zygs`!>b>?m1R(C}M39OhnVhpuC4T@A zrhd9S)_rW{v{!HT+ArsTB}}Ctb6l?{x9?9uO6a4nA#)@ix&0h4ipMW>-4sKfX%FW) zkwXE(^b00>D%PDHLkV1mp7k){9u delta 1248 zcmV<61RwjM3-k$)B!3G~OjJcja7;unB#~Z3dvtK0ZBTtuG;dBonrl$5jc%cOU~WSs zZ9^uVZ%~h4Lv3DHlVM0_KO==zH%K@xR52KMPA`5?H9;~cY(XNofMBqATF#tu!H{Zc zJ|u^0PQb04A{-Cazpi>qG+|Ce)Ub}Ja#n+RbKct8;@#cl+8hB!`#`~*3{I?$;ov zc6N4pdU{PuN`E;xH$FT(J3Bc#Iypf>Ks!1*i6a}c00014bW%=J03AtTbYKwD|NeCB z|NI4*|NcDx|JzZR|NsC0g#G*f|HCf-_d+FNxc>fE|Nlq-{gfj8ivRy%|NsC0wc+fU zs>;W%|Nq0C|NsBH)aL(>fbIYOtd6?><&=~6#sB~VKYvL?K~#7FVxTnua86$d48kB7 zfVvulpadjvMf6^2V2ae>`8W_v2$1-rwI5_kA0IPZXbkbAVA|5t0;$9RMIQ zvS}U}LY^1QTpTIy1|njnBG2hcTp5VEAo3pfo(?Cn5JU(;R09{ejc5n}yohK3AhIl^ zBCl;Ldw=$xW5aeP57w?P29>U-0Y=Nkn9$F^c@~*}GB2s=a*m6NT)zj~6>m`Y1iyDa zo=ikdelG^M6Od;nVrojSEs@h@Y^?7+8^MPVzzpnJTSnyXX01=QKj(CDAUP020d#km z&u(VWZ`o2?X39UTF+`yGMYmUcxl;et-*CO1e}DcW+^)2`f`5)a4OdqD~?pp@3{v*Ux4c$x+8MQH*+tjv01_T+q-O)wh>6%n0?pz&Qv z+2#3mEC>W}d=eYn=~lKz zFF;b`2R5pJ?*C%6=X#6%(%e2~o>jaZz0 zy^K}C?_=KFh#&aGwsZFVK98eaIPD)1LkYh`b`fG28IWSE*o?y2EE3inf)zk55`Pkj z)?WlbGEslNAVMTs@li6BSc8lN+m%$ww?N{k+4>z}j~dbm&^8hRG!h|=ct&Cu=Na~7 zBCHJFC&7T;HL459;!f5giBNrSUjQvqRzpfzP|9QgVpcLde>$ZDObucfh~o+iD2g1Q zN9r`0-2WtR0uT6*4)}q;*zHqdomq3R^mnh|PYH)+N(6!2FGnOvm=x4*|9gI+^O-|* z7Oj5-NFb(YDBpI%2+fN-i~YpsndzfAEiz+C&CRjLe{b*K5Bv`_#J+~%ZJlHQ0000< KMNUMnLSTXrePLq& diff --git a/TMessagesProj/src/main/assets/emoji/0_146.png b/TMessagesProj/src/main/assets/emoji/0_146.png index 93ebac3d0b4f7b1fa17a0c4fdf9c357386116e3f..8be5811f0f619e6ab1d7367b111c6377c9aad986 100644 GIT binary patch delta 1077 zcmV-51j_re2g(SLB!5LvOjJcja7@yaZSl;i?#HCpo_WxbYwyRT+^B=dgImv$YQ}+D z@5ZG0*thb`s{7r&?7*Gpxs~IwjMtra-KK%jl56$Su>0V_o)L|K0000BbW%=J0N`Sl zM5oRl{eH*ZB0YTo00XH>L_t(|UY(bVZreH#L?i1#%ggt}|9}6fcXvopO4?qviWU(Eb1zFcdQPqAdJFFu42+p#mret zF|^I|Lo{mBFn^qiNjC0h~)agL*4zt?TtA%_}yH5Cmcsk>HV`-MUd zm8jS=7nig<7JX;1g<#+i=hU=udmrYlK^IpQM%#`yw14(d+#5_tqHui{XpuVH8G3yy#klzd!%H42LmEu*k@}P| z3nCe2(FI%-1q(IkLF{FmE~FfTZ|wv|aA9hSO&>rH1v0P*3Lnz*Ss#2(@Pf=Z9p##_ zvg_gKHE9YwvrsGa63@Vx*Io>XRZQC+mD6D{Pk&KF2vTsE2#S(l=UZ`cBp89bNB`hx zJHZ0nGUA9#Y3)1}irqj|A+-)$p&v;brncAG`n5ZzQ1S972Ra={QHXqK^*)*_szUy} ztFe<(j@}taT8kue2*`+0cZzX1RPf6A**-jaDKi|Xn>Z-dy^5pL+XlI6a(5s=kZ_L3DlyPmZ>=)fy0D+I4(G}^Y7Fgm)PV} zjwywTuY{2JP;VT_fy`3IMvOUvoOktg=V*H|gA8GDXBhhxS1^*Jj$yrZVb%YT4Ey*P#^svF@F4Y2eW4vG=hLqWp|m7yqx zFpDA96!3+YT!{OaVrkdju;MkSn1Zj0@nNvSK`}gx1^2aeYadngVhql6Pf*}RGN@Rg zAVb3`)C2`HJWiEG;lvO|?^*i|#tl6$zzT(T-iJ6?i>ZFI5yM~zHO2b!NHI@?7cTXc vqe$Yg0dGbC!>Hr+%+Ke9$NwlwxDosZ-fEbnUf`QM00000NkvXXu0mjfMwSej delta 924 zcmV;N17rNk2(kx|B!4+jOjJcja7?s+UUp13w0~cgWlVTYICe}om}gF5J}RqqShs>< zidsXldR?b*R=bI1zm8~`WK4NZImMN1L(`Lb0000AbW%=J0Cm^VNqwmy{Gw>kfbjqT z10G34K~#8Noz;s@>>v;Z;N3z?I~Okd{ttT?rUPr!94o&jCV$3${)0n({VBon`s;Jv zzgrF$WBPnjbccTq_`^8>h!F^4N*@ax&zgj{i|GupKxU)_@4LcR;Be{Fez6eD1Tcsg zUAO|?k$d|PMgvHn9wo%k#0Y#P-YLZza7T4Sa5{J=a;6%HHBdvmgo_~MG!d$EI4fWT zBiB@gnRCuqwtveMy|6$r^_d4j1#60C-}h??clr4)3<7Z9OTo-cELDzoxQy{jQUsQ# z^*m$CkJWGw2>Xi|Dw69)cvOPG2s41*kLRe(sS;}R$S6h}zX|OmD$(|$0}-eb4@!V; zR%K!j02>h=2#}G9^hkRcz3tTlf%1;I2IbR&>$B5LN`G+KB}LXtqbqJi`n3cx7OBDg zJlmBFMx--$R5BuSh0fbW@}j$_>WOg3`IbR<>sMB22=qkTkUCsGj6ZHXH!E2A^Zdp79rH&T$gAf zzJKIuh%imOwmu2X62UGlketO-woWjvbA-oEVlXsuzQN8wEG40wogy1~xwp4BJ8bCT z)+Q!aK0}*HI4vw59TX8W4-GgbCptAecrP)BBq)zoL^?-9LPtbQKrko=2rB96;ew2x zNkc?UI4Zonywuas5*0Pq*3z-Bu?PzwsidGsWvD(gFXQFq5PuIKkd28H5FJxOH`CC~ zM_Y>o05B*hbk5JwF*k2XIyJAXs&R9SPHCRb%gqoEI~^iLT3BT$DN|Bwqc}f|H#~kt zFem2Y-WU``Wp$l;dVNS+jY?gVTuDEblbTUHGT-0dK1OyrL2*uEkU>m)MN@(W3?)oB zFw)V{J1QkfT7QWvBqT;ME9&a%DIFFO4LlneOD!*74GS|H7Zx)&Xh%at*xA|Q;^I$A zOEx7P$;!$b8Zcr~Ns)|;#Kgn_0TwbXF@t}8ARkjzY@23gZW$IoJUTi?PIgW}KNpqz z?EnA(M|4t7Qvm+`$qD`a2>$*i{t`nPH0=JgMJoQpU4O%v6fiGo*GX1klDE)Fl{wrS zfs23dXmGOO-1Sqkm(%|J=x2MH=fSP<-OG^jZ3477%K!iaK1oDDRCr$H*H>Q}OBe=l zc4Z49AWcysf)Zm*j2cBvKV`P|Lhs#{^Zo0YA$q~NT3#>DbI?9LR`dCX*);Lae|#+45|AV%xU) z)LaX~h)5bawq5rad$I>z2~F#aXFE>4o(B?uknHJr7M|JNKa4_&$X8r~={T7HJh6P_kbiOL^W)&F&U17@mTOOQ9`H9i5?1p?eLU zwgiFI(>k5ogc3P}qWBI%gWNKZILH|-YV?3m`urV`h_J1e(3@g{1rppIA&enHh~0(} z(SI|xMF|F*cF;MHSZ7%3H<9Ln#F5Dh0%?R9j0(Vmt{c>h=+eDo*ghD#O|=DM>U7!O z4y+G{B}9)l9UewR&jyC;x@~^Y9gIdG;s|wquzbs)5kniJOTamM^VPKOWwF{sI`hxN z^#$ZI>;AgGzqcB;sWW!@CIulnSdi65e1F1t{qPb8ATDGgNY#qzdGYE8fDrsd+7PRi ze%G_Z)g*wpB}FKWyK=4GFNHs@K#Gt_8(657A4}l`U=-OCS;lRYuO2Z`2}4Hl){dBvrF81?`_!8g_YvoEcBr2Bm$AX0B zs(f<0&_q%n6;YCwNb#{hAym N002ovPDHLkV1mrzUAzDQ delta 1200 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 Z{tX|pa@f-vnGFB{002ovPDHLkV1kgmKSTfk delta 1108 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 B4?6$= delta 1523 zcmVWQ)cz#qqE=MaRep5SrNGa;E zH-=q8cuqG}IxgRu9(6=Ac1AMtyeRIkBa=5IBFljy zeLyZmF(`ppKuj(r`^rE5*=^mID(9vldQdy!t~7a1I(tz%_J6=E<)|6lFfU6rDnTzN zO*k#zs3-Z;X#L!Kjynxs3kR7Q7e_NGLNF+rAR@|I9p9i6|JZ5&*k%~iy?S3sgJNL;0R7{Zq<&od(nspTQ_V^tscsDa@3{Z+%zvOI4*%z%erY_khcDX4hITb2 z>vb!|n_>q5002vLQchCgg&i>*M^q&9#1KdeOK~#8N z#no4L+J8tG24G=JfWQV*jjsl zVXKHZxL!#OlDE33Rg25FMO8JgRV_sFT^v*uPDRC{q9UbwK+?t7c3eR!Vi=R4w~0=g zBY&(&G_7egBPn4AMU-u(*XXob9lBTDrpUrZs|W=G2vz+KiZBirEh&n`xIiF{<(<~h z8t*1a0oLMsbw@Xt#&3H*3(*Vly;?snHUHvzcfrBn{hk|Na0g5E^Ydn~u^(&>27~4^ z8#b{g2w>D}^-^=NzTRvG=WqqvGeHznM7#*SY^N$;FS^TAec}U76-Y#=J7Z%}{xbQ9z zX3}XOeh+h!ACFLwYd4$zmTdNN*M$@;f(;|j>_RpRn@4H4cV|6l28XbEIWN1K>Hqnd zem^tLdhv*emy1%XnQk`&87(L58h;+)@NzCHmgzddfGaE~)-}$LNqE^$?DlQ} zmXp~xC`#dEhVjhCoM%QMv$|SNCJWt_kO%X-h%SexW94M-tUEVX$Xy%G6<4^5cT_`4 zG%^l*O`<#^W@mbMXCyM?qD;c*PEEm*EU#GnQOv(ZtCbxuTwj<(*(B^1D}PJj<~!jl z=Pq(U0Dw=NU6_R1`9s91(e?c>k#SEruP?3(_6Z`w_)eS>64r6!^fZ~7usCz47ok`bF0NVTDv}yE@B3}iI|mLHQ+0KLed2_vDMP~ zO|UlfmcBqDjLq{9*lPP#=WO{GHUh%ErRzFB55x-{vcTfExzXyk^wE#c>#crY-^3=S zc$i`Me9|O%xF2p^3%kfhjgd)7uudc>ei3K^ZoiZSs+0N4Ni$ ZzX3h}C!puZw>tm;002ovPDHLkV1jej(dqyI diff --git a/TMessagesProj/src/main/assets/emoji/0_1463.png b/TMessagesProj/src/main/assets/emoji/0_1463.png index 7344d4a7b98610a165d1ffc96ac6078935794ad8..57899d9731ef202572e815480baf75f5778f0e45 100644 GIT binary patch delta 1696 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 delta 1451 zcmV;c1yuU)4804GB!72MOjJcja7=hkH(EX~)S`GkDZI zdPOpNPdKY0AHkwtdQdpensME;i{;poyqi|hpL2dxJk_Fm&oC~5S3q1oE_O^dm?9lS zF(|@RKzmU*x`bTDlW)b5WPDOO*{g(<92`h9D&o_IgDV}?qknryGbyKaS4%Z2O*k#* z+LqO&d)&cD`&QA0UxO zF}Hn5*QbGF2LXC2Dnc$M*TsF~)sU}jPp@!K%$057wT^#PJcV09+^vR6G%KKaShy1s zk7rA+5D(a#(AtAJXQFTc&s(DD| zH8krcCEB)=+suXFyNtP#Zqu)UVgdm0=c9HtCEjdRJbwkRNB{r;Npw<9Qvf;_v?l)V z2M;KBNaOzfzn1*_{u#3tl76U!jgK4&S~#yx5{Fgju{; z_%h4Fug8SK;giM7F#~0Ej*gUW2vo#NM_*Nbj;v5UFSF>Mq3DD zjengRx?&_iAdc(zR;!ix%}NSTuGM!@1zLDFR$W9JviffMwm$kxRhGRsH_ICye8J zmCs`}c!Wu~xd$LL5h81Oli=KV0%b$$6bM-sz(~XuE{gO~}urI`i zkK7R!v1kie{Ih3QR%$@h=3TZW%xjURDIm%-LMRD9(D)bH3lXUaWs?8^pKz3OKzP{F zHxiKUQYdp_4;Zgg~ z8J>S_Cm=irnM{UX1LAcCvPt1jbALD)W@ay6%a}|2d9Lu#p}A`{2_DwXeHxe81fa=3 z6SL(3_B0~9&|-hq-oAOj^CY`#1jDe~?bc_GdRhK!{sx4HAjpcE#xvSAuIy)2* zKs7;&KQAyqO@=l-gULlyoDVDt2sF$fHxdyp<>1z4N1Wy}GlYo0futf`5UKhJ=EmqLYnRGm>04K1q2-Q-YUb zIx#e64G|~Q8Z?7WF4-V9+b26oT8SqnSt~7H*)Tx@2OUjdj|l}Z+$}&hJ8U^Wa1abR z+8HxnOF>s`njalW85cl8O?^&im`5=wP&_m}MRYePA%CG3C|o)!-ySuFQ8S-vKzT&Jipf98+mRE|MN9o-!`7H#U?+GC)2{C>|O- zJ!Xq3ExDbBsDo*PJ}^o(L6;^<#DA>100017bW%=J01i3+{QfWm1`p|E9I1#Sz)Svq zipOtS{eOulI1@h7`FA&(Qv5#tuk6C0?5_KR%lYS?qM2;#%k1{!=3j)j*JPsAVPzdY)Bpeju}MThRCr#^*VlIwM-&EdS$%C8At|!l z1vWPB6x)Cc2{k}~^q%c~)qC&Ny;73=wVAce!GDjt_bK;HFF$?r-O-#Q!~cJ54xi5f z1~A9elyAkG9P~~>g@u`!ndDY7ncSKI8ooj@Sttx9x6pVo5Mf=+mrfUvgMtkDU@=@T zE49*MzM#&64Q9;I^@^!fD&_O}`xuOPGffjE(`ltrT7(jFA3xGWCC~4lmhM9j^5Fwc z5PvwaZ#wnB1m`a_0&u)mGQG5d1RFL)(1_rt^QKh;aEuR73ckVfD>f)$n=1RL z`_u^}t|LNh;&lRl3hi^!jrP$zuG9DpAYuPW5F&xy0~!&)%VoUHsYIEki5tMJ4k03- z5(Ew;u-T);C*u8&uyedPCk|;GKUlUw${Zrv2{908BBHyq+yl9qvt2hL#O5)oVt)tn zTeTZs9CLyg5Sm@Q_8vrFv-P8DH4@+s>00doL_Dw8U;o>7i)|WJQ7!`r`|PXNxm>Zc z)(pgh&VrML%KalR_wj9G}m`KP@icfT12V($8;gst$!>c7_$|d z2!}H=6C)`}Mf4aK#504VVpO;|na8z-$yi)DkC3CBb*7~I~}BDm(+78_)PXe^hB)nKr-tu2HH zeY-j=+v+S_4!5!X+tR3}A~yZo>b&*){eS*`*&Z3uy3f(gFV1J_FBom_%zw_zH_gf! RVT=F(002ovPDHLkV1jZ*wYUHP delta 1256 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 P00000NkvXXu0mjf?|o2I delta 2979 zcmV;U3taTg5vdoDB!8MvOjJcja7+aT2j8J{L^e26KRe#4hBz-Yf^cc{&a2p@h2E-! zDIy|f2?OlEo8qsF*rkFlDJkc(jpD6`X~68{vW@G$n(e}$->-{#PdI*4J2507d}vsC zQ9XW2HtD^YTeRa?JTC6Pn)At}?Zly9Lo<6&Iebw#)}nr1U4LHXw2;!Ee0xkdJe$%q zHa``A!sWA$V;UAiFDQIbIU6)$yn|+TL^4A(FCQKr-l>Ea78c&EixPRaa>(%@9UpNV z7=24Pcpny?8yPA&T1Orl>bjNAm~}8HCNV87S5{U!FDe`~U=@73Vg&$xQ#*Z8Izuxn z7InE1e87eo7k^{~0v$43L@+2yGb!P$hAJc?95-WcpuZJ#yE=ZRH;%+3At5L~WS^g% zS!RZdZ)8bALW*KY?6!`5lcKsPC_Fegk|rjxB_FYiZpN>i5q`T2dbzicbZgA{OnZ${ zwe4Sro_v6O6@R;Sji8On?bBAg1;_QkE|#qBt&>MXR7erzI+A(xGE^U zARjMaqb7K^Q&UrTnylnMImdru+qs%dVTmA6kAK85F1MkHWU0@!iD`hZ#VJdHFk73Z z$kMTHOs`r;sk^_bd0TEUHr)UK0C;p#PE!E>6({cb&hy8d`Fpn&7;9$)^ybA$Z+NLEA9Y~A3qx1sRa z$bZI5E1=!d>fCwj>Qfn-bJ%Cz{MX^}{4& zL_t(|UWL{5LmSx^2k;4zNs!>AKyeBbtpH1*DwNW8tJ{`(x3((JcO>raxVyX7-CbAS zd;iNjGq6OK;eGQ%ZZgSd&OPS_5dWaOFnlacHw~VkO%OHK8H8nMLYwEeL!T#D%S6>IQ8VrWB zVT=NM_mshGuCJ|qo|QHAe3v(oXO&8&1}jaN&7Uy|XkKl-SvF*@gJNORUk7;v&VK=E z{P2Kd4h)CgAl<~&(y)qpt7Cjz=CDG|@W}HJybAM}&B=f5$`)w|iF6Z(sh8F|gWg3D z!`1dWYU33=&!o@RYsV%BbvoVPOMhBaQiG>!g37DTK}kOl{a44F6O{snQ?-HBJ$%a% z|4?Te9I#Kmn)B+~&iILucVI??IU{7~ z=4VpYoJ$NJ5sPg)r|G{e)&|eX2rVaZC*S1~J+$G9@}C$9GfU=n>M)l^XA=`Dmeh+t z3JLy1ZN0s|b`rmwi7*icgVdbu#9gn3HBNVnRBASRriyY)V5+LQAVQ;Sjlp zfB${PEis$nB@mu6L~e|5DSt4xC=_8NtX8XmWw=U`94k+3<7$l zH!?Ev=l=fw-!?*$PI`#L%{On~Zcx9nyt_C3^5yis%}hmn|Dmrp2?_xqGBW8u(TioQ z+1A|9aP#()Coi8g+@79(_wJiDOA~>qgLm4%fFvdLy})C*i$$o_>Si#gOgB8f_xRpn z&XPnT?tUT9?M;I8_J7I;G5q)+MJUzE8udJJv*F3Mt=k@NU9t>8h}iuizcaTNlG}D? z5EF+4ED+ze1_!r78IXo%bxm;1y`{UcGgaIJL|a>KZf;v={(HALHGHAZDX&I@m9P~^ zv%0k-_}}BiQU?qbit)>T&zE-s($?9Tehv{6C#)AA50NrF@f}z5KL?tt!Y(*p{9tfB8={}f5Q2=B6F|&4m==0gqy^8 zA_!=r7#EAS*0eUMAx*8yj(z1A&QJ6QV83EKsuYL?B)=>mgl;Iz8pp*YM}PpMsYzMW zailO6hf7N|(|>dv-78;A8B)L(Ys0Bo<2b+YNR6_!3DOG0zBO<^xa5~;9AC}deq#2) zvuAhiJbU)^?H(SKfu*2m3Wnp+MHE3rNfB{7p|TW#e>24C(6{Kjt5?vq3!?oGIS|m!x3jZPXJ=>M-lvJhtgO~IHg;#^eBRR4C<;E|Fz~tplQ^o0$lRA{7eFaU@WrAQh{*K14S~e9l{^mn=(gS1T;UOeRuV zqOe#*flCk^AS5l_s~CyE)fS6J6bjW4K!1h$OoS%(b5<=+pn#AZ#1q#nGBjJfi?=4BCbkg>yQ<)lg_^l*K{_ zsd7XXi|<5M%78GgqKPg>0wRQ&X42DD_??TK1tP~t6C6gOfF$Q{E+pZA`x5Q25r2vR zO240(2vwM(=x>HA@Mw?*r`Ei-Y2>^XmkB2K^V89V7sthK9D zs-r=$P$g3fCgITeo`ovT4EAWQcz^9AE`2CHSyc@01RYC;btO|X&h&ozlzWIKK79I+ zd(hK~N>zIDeEqy*s^oN)V+RAVx390SjsD_kSap^y5=F^&hr^+wh_GYyvY3G=lee|~ z^U(aNukD9ZUd@C~*bh)0;H*6g>tk_D%_#ff$Ab&2ANPXgF?JOf@8HoKCmd*P@mjVQ Z@IMj=u}Hf;wtD~o002ovPDHLkV1haOtkM7g diff --git a/TMessagesProj/src/main/assets/emoji/0_147.png b/TMessagesProj/src/main/assets/emoji/0_147.png index b622def5fb1e19b8a2a5142d0efabb86f459c981..e2fb675c2ed8510d53902a713c13714e9ffe52e7 100644 GIT binary patch delta 987 zcmV<110?*32k{4xB!5LvOjJcja7?*(P1~`F*QtTKdQr-gYq@w%$&hEsk!i4OL*2BE z(42JCpn2c7kleA0*{g)&y_eObe9)V6#DrVQk7m1hP~^g#+HDNFT(HUm>MpDyT-&LZw zg4LS(0RV{Fx_?Dp4TMRWqP(F)HWhcfp?AkXxo(DV2EFkp+q zoD|Qhm~IUQT+kXh7rQCbKPaTRF9HK6iyV-I45F*qP=8+-F!(%8jX!7`L{W$@3_3&~ zLhylqF)sMl&3lE`F0P5V#z-lpfcrRn8!VGgmFF^?h7v6Rd`;>rh2bKs%k4yS`~+X> zD+Odli&g{lQ=Z#t{=E+yJ}3<6kQJ&4%)6)T!#k}HH!!EGDdfq#e^gK`v@Yq)fPto< z#MbBC0)I%&jM;%$!-=#(w-m+32L2(g6UmC`17CbPVHq;la7_kG1rV+dV8vQf#rVu1 zYcObG0kx*>o)l=E^DGFo8$_+yx`;dawu8!Gre}4i!AqJZr=1_)Xh5npQW{Hh8QkVg1 zQh7|FDvW9Agrh>NN2;Tw&6Io3W=Dm`=UKtbBv_VZ7>0Q!hvgjB@11h*kpd7ZEuD-? z$f6YN;6gHh&U;rRlnW%Z=5&5$zBmAFpj@`O5zd90&d&~C9bB??d|Ubxac+ip=IC=j z7=Kn!#Fx~mdC1JOBEgMABOVpYr$x7Qu!Ph3KV{$V1xXS7@c2DLZYgF(R2>Sr~hD=~Ry{20pWf4wRq!6v8`xPfUui^eGgL6`=I9Ux8WS z#a|V@%@BWA%$%)6zhe5cLN4V?w7;FolT?DRu5+k@6zp(xU-U4r!fI<>h<&kG%A1Yt zE+Ig-FHy$3bF7?D9d`Vjf`%11JEB9=8-mRUafkt%T`_z#2WrEA|@7x4f9002ov JPDHLkV1gMZ)3E>m delta 882 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1471.png b/TMessagesProj/src/main/assets/emoji/0_1471.png index 63b066cef776e32b2ae227011a7194081d750eb3..0a78ff14ca4b7cb43b2f46e806321199750c6f05 100644 GIT binary patch delta 2046 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 @SrlpQ^30_1yW+&c@EhTaAs4F(3F1O?b}h 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 QD*ylh07*qoM6N<$f^XH5`v3p{ diff --git a/TMessagesProj/src/main/assets/emoji/0_1473.png b/TMessagesProj/src/main/assets/emoji/0_1473.png index 6b4a6b702a65abaaabf23ac76cd11874ff74a2cf..5ca664bad50811c58eab62116745f402bc54ebc9 100644 GIT binary patch delta 2042 zcmV zV33oMkJZuC_ror~zr;L1QNV!{YHD+^uC9K5ezrVF+<$a_|JGUk*HsV|Fj#V=`prUj zIRM?kjQ{-i$E{@6z=YVNB;~b7dwF(|jEN;DET*5U=)_i^UlAf68^N!Zpp16>zbdV- zv_wczKuml@P=Gx~b+&sI6AwAy;o&$xa0Lt{-QC^)&@>zxMl&~P*4No5C|UW(GV!$> z<>chLyMMkC5JXE{i~GVQt8o)nX_yijGwJE-9vxHv+FJh9LjTMy=AaVft||ZCV$qfw z!ig8`s}ukN7gtkT?8Q~Sz{O2HG6@GX|JqQ^#JSU+B*DbYUqLJ~HC`_yFWQ(B+1%sp zzcuQ=OxwbM#JsUYL{ihQS!-1=zMp2Up@Zbdbbq6xtjDl}&8%y)g(%6DM#j3Lrk8zl zStrn_J^$Tlgi|Jef|Zs;M?(Mr0G4!8PE!E>4I2F!{SE^NCprAs7yd-Z@+dL>Ne28E z{5jeZDgB%L@5^M5w5DoYPIdaw{a-iyYBp<5q22T2eA05#QJj$N!&f|v7?s@8s(WGO zqksNo{qepa1p~}~Zl*{Om+o*!h&$`b0;2~P}N%uIoe362~+tK~l{G7V5vuela zn6R9#WccT;gwXAeZtqyRM~t|4?n95ussI24heBXGu9vbCuxA|gVlg(Z-4{Y@?XEhHJyq}>TgY=5d4 zGq*;OBaN+5n_!8rIvdi+G;^AzAPkb&sZf}8ZMqiHvKxWTLZ~(CbWs@=5|&`H3WQo+ z6xnLYIL<_1E76TuGFo(P=fa?g>fL8QFKE+^f8l|+6W7xwxTEI-+#!O$9+l{8Zn4}T zvej})O$|34v=>tFI4@W0YxL?O_O1K7)#b}N%G*PZs8`SE)7lx~_g5aJ+&wV-F zIrgFyc0uV^nQFFsYBy1Mp(Q3K+@pxUs{4Kg$#B{Hs^Ih0}1_DBEn5}n%_;%7x z%!w4^IgsaM!;L;b49tnlH*x~tgndnbkPJMj*G)%55t%}d2`F8VWZ2_{JnqXQHl3GJ7MT-d)@^IR~y;d z{U&`1augSv)04_d+PDs{0B6|Y{u{*8{@p`j@$ zv-Rf2s(*6RT@jd-Gu=W()PGH6*B+}C8+z8SYaBFg_i{n-I?Z|YFydh)3)x|{(y)%f zibk?q6UTI3pr7FUPC7hO2C+VvxF99Mx&Efm`cbiGmnE|#p7WfFnmI0Nj1 zXKF2jz)X90ITV6?POLexI1B^rWCJYGsF4z=>1_vqAe%Z%YB%?TRuG|f-7CJ9A;nC4 z)=tCYy#pZ>U{yC07C82)TF?#JnrWmTC~>g4Og|}xVXDPj0)LcZPa}Nw$MW-%9ggZS z0f?nrf>o$wfHXd3t~{6ddG8<&BLN7Dbs!5+b zTk0ES7au*o-suYoC8R3qZI>**ER#(|Qhp@=sN*6$*=2Vx*le~>D0wsQ4!5^=T={ZY zDC6bbbSNaH`g1>cz_H0>m;IKPBr%>NYoE%YJl(hE#yS)P2{zecBrbPCCTo{<#8CgG zgoS`%I^NgZM;%ifKA)4kR7LoA*RFkE?!vzihNKxd{8-jQ90(dkl>8Gvv637zT~<|9>A93LC?y?#x$VQBVGs&u1ps6Q0fZSBNI4RdMF*PtT^w+n-A0JOoPj6dN$Bb!xXweROq@ zd2BIZq+h7d_UP7`ARVkJC?#{S>Nqw%8xMf5#eXDPpW`7QbR`)uRgi-f6R~bgadC0K zn|!o%kAxRlZ;K|`{Q=}QQYWzFd^2Wk| zpMUtyobmU5o!45M#k!pA-sjGP?v&}Ux&HqC+AmGE000OBNklDAdo~6#Pnhe7))Dih;57=$0fGcPFxf3X47`FeZe!M-n*#1_uhMP@4ck%pR;!c z85J0^-@`fcj^51Y+;`_nKY#=V4F)?9E{g0NnY6q-yS)6Qc*~8PlV$x> z%1%ml6fWfSKlv|}Po-FZUDn^|Nr;#kK*iZc!)$hT_Etk!rdwWKo|>A{>5RrmAtNCv z2ZGhuKRf$rcJ^$PFCo?O4J_RhC^{pHwTH0?>1-oQ+rwIhV*C4N%Q)U0EQw{*8-ENe zqYeavAq!(5xRJ|K>cvH^O}E^*43YY7vD74q+pJcr&8BB%@feE8omw{bv7OHO7JQ0A zBDp?<5y#bJWo4yFZNeD|q)=z<=^h(*X`J)J!_c=WZ|AWrE3UWVK&Y)o+*pV*or7P! zxHLBIa1oj%WrN9J^qz#5WvyHo9)AX6Zg`H=GZC^Je*4lB+k(U47@xz(=B02T7Z}vYabidM>6yx z%E0d#nqC3H@xn3fTGaD%B;H==ak7$xzsgDyXFSLr1K-Lf9FFPfX_vz_T7Sdm=XfVW zoKF!ps|^Tsqzqvq41DdV%Q4M1I~;`51mh_4*|nMQ#$}io++>Yn5YRnFnC>MP!JeNt zyGC!qEV9I2f|IYdTJZ_J<(YDMC$>v7D_$ zxQ1|tf1~gO2>5`Y8!9D9QVm3_{UHdUK!lK_Nwh^kO9`SN@th)PlSnKe=!VK-fyh7J z)zR8&x3{)-bk!dh!ABw7ZJMb`K+k!rIEo}_=!S|wz~w-Mwn9QFA`^~g%H5`!(Iv99 zA6~!y5c2xj{eSa3=nheeVMTCzA?J8kT}LRSqpqty>|-%BG$~-ZN}!nsvGaHCr2Txa zt*!0e&uMoqKpC!MC6W**TEYnff=XRo6A*|TDk~0{Obv8Gwwo3_#1%|X>KX};BFPFd zk{Q<2RY#`_h>s9X2x;~_9xB*v7ldo*#Lrim?qji1S(I84dHE8aU?k-0!4%Y#1#xl zJR^$zJO+s1)fS7TWi@rRT?>~F5Qr$M$UC7Z03a3b-ks)49Hwu`1e_u)eSPq3YTwO< z_6>r^lLrnt5KzVaALw`q1Oy;j`UVCpsd=9?)PD?UTY#V0pWX z1|Z;BAA&J)Lryb$@yunm**O#^0Kku^v7`p?gG=8I1RAH(sGNVzh;yqnnn2=aO^r77 zv;T{5Ults6t5m8(frJtW4n;KVKwzctsPiBa?gXMB(VrMlDz%>o;~SJU4eiWCVu4EK zHh-T%VxobF&hR7JX@UoYvY~w!Basp9cDvc(NXbRGM#lsY-Ae5~nz*?G5d(yi9f1fg zI^Aw_gg;T!t+edJc5M*o4g|c^7-*~0=`@G?5f&h{K=dh<1D4+)E<^iB*pR@L;{RM32muhz_$?ET}U1f%D#O(Mk2zk*_i8a_s9{pJgbPfukM7s2u>VNuK|pl97f-~XN>{^=e)1b+)} zxJf1)hhJm)zv-KMNG}O`uyFyztB}2eg5t_tlo!LWU8*l)l~i55LlYjxeUZN4<0;d z-U|YH)wA-1L*i<++O$E?OF09vS4mM@`{Dlgt8cyi19kAC~z uUeD^gb6{;o7$ukIa%m2eiR2=Q5AZ+UFsvE_K8er(0000(?2;mIy5xIS7IF;T{%5rL|mi` z2{bn|G&nRi+@gZPzr7INqZteupN_|B>l4?c{8giK|e zvp7Va9xLpGjV>}|KTUk;y_s=wamvii!hBRHDqI*AB~VXKU|?nh1rx}GUA<2`|LD`H zrm#mwO4*@$;e(8}xV9Y{N!)aPOka(wdsNh!bc9$m*nh~fdwF)+)y*t4W08!BHX;&o zafTfmO+ie2Jx6y=V2?ylfZW{NNLPgp3N`uEvE=0BE;3^T0|emU;O@qu)YaCyyS(hY zmNz|a78Ng&v}1`Z}18b$uww?RNs zB_>+QzJIpYy{GBHpwE(P)~}H-D_70Nz#A47v5RY4MKoqnM|@vOrKPU<#-FaBmW*ju zNJVAi&AKNfBq}dKR#jd{JwL&+rL(G{byHQ^$FeakE|_9Xp=wEZV^J6pU5@|&0EKi? zPE!E>{{9&n{s9gI3MSVE4sHIb$T|KO{^HM0H-8xFt^7yVvNXaqO!^`*VnBPET-#qK z3e!gMsLwN${!U~0{{CX9=|z0!qQ}IN*q?RC^5?pO_Dd#>as2#-lVQ$<-@n9rolIqB z<&czpp7vjn&&TgLaB}z9jFjKA@XC>|=g{ft?eOXTy(*1d000DsNklo-~B)v5;=909#CF1Op)HLPXT1q2dtyhvl$XjuQKwh<@{ zBL4@Lc&5rV>-?h&`kLIZvu0Zs7t>fzz;QfLIqE1|WDVTGv?oFRRrs%<(@h3QBntPNqA!lcvEwgqzq zG@?zd=-!wfu`k?$?neo&wr$AA#m~#2hwH4C)~<~JM4Jc}aYjp<)}{dhI!`G;(7HEr z@dz}ceaek^>qhY42*-;S0K)uMY=56Q8w^LdIJ01))#f*H%`_aMqNse%W>TxoQ*!TQIbHKjWiAOMxtvR2Z<@=DwY-H3k9 z3=n|^=~{joURp>i6bkK>m{o4pJqe7!yXbPRggg=Ut?5h(+jEd+xA}a4Ie#o|&dm*o zkY1A6+A1H{=r=0=EDeMpsQGt!X1wYV5_{C)Ahu>%8vQ$2Yfu0L>|WIBGuE@3d?eT5 zAc-_*wchoPlOqVg#m$7Sn#7uO;MnUR88&C$<$5@A=WqZ?7Ke9wwl&t^ASsD;vuf7K zX^QomP}m=ad5&nz_as9ot$(loUKyKgM*W?rV<9I$dd?+D%D|DyWX7TSY=2|;CcMt; zlH`yKuCxNe*bpbn&n*`omgfbGZ6GOP(ke3o#J60(Or(a~!@P+x3_}@)I*g!-u}hdg zCT@jfe##tVfRCZ14!4n3fnUAM*fpa$423HTvf^Z89Oa4J&k~YT!hd$V#ZFTcE;)rJ z$;Rd-?Ca+O=%q(!`UwiB4B1FToOND8P!0J9#?W}bZZ9{BO;MC&5J9@ElK{cw9&93g zAMhZ7Q*F0lUwHH*pM<*w9TO8T`J7k$JK*(lG-+Nprorho3kpHL(pT(#xs$d^VrG>B9?(4K8qJ%2CNpLQ5~x#`56(wJ;% z!0pVCWxFaVxSCGw;=sP6S!N3bd{H@Z92k61Im?u9#foEmQ8_O(PU66l^6bpWnrGt9 znc}sL@X4jttb21H6&y2Od{H{s#CshzVAiC3R-nl3!k&FgI7Bim(YtSaP&pldzZ@DI zWCQ|X1OP-ZD1RF=TzpYDNHr`%GAwC@lf{Qx)W3SGC?&a)S~56HvzUJ#hsY^2Q4M;^ z;H-rXe7b-a6`mUzepEYsQ99SJeu`p9RIcFOvyUevBxr}7H;cgP;=Uz)w}^|1qHIa% zyO)U|AAe#}eNsA=3ki8%QG~g>-K>Q=EhnyuaC(4+9)E(t4tcun#-y1Y8(~E@J*DFw zG+kW1@teD@fvBV&cCO~ws}z8}X?~Ahj;e{j)+0c2Mp%B>rhenTm)4?qg9!%Qtb_a4 zwdJ{yi(*I9oO0l|kTjUm<;9=bu8P7L7~!*u{ouZ*gJMiKEceo{?7*9^bV-6(KaC3r zwGtAKW`9ecdRw0j45fcvnsZbhh{&vnX#eNPm2OWfkIOfo#8%dI(Or++hCn?yW2>?S4885pY&4~ASqP)JAP z*ohlBXns{ZCsL1|W<55e-#@MBNT%AQlYx0WDd;#g=G&fiVpVQkUgVd1m0L2#oqBhq zxhQ(*EYC&wr-jzNxLXl$wdI&uQ4PuIHP#{{H@X{36W& z00=%wL_t(|UWL_lcof$f2Jl(SY_d^V;_e|HAdmzp5J+%}d!dvT3behqg*w-@y)*0X zad&rD+}*8iSN^--nGIP9lfHSL%w+d@e*2yGoXKML!8t4zi^IjH2WPvYuyJhWynngq zcxr0u@xS@u_5yQt)K!$I-OL$<*}J~`Hyc7u3EUA-`wsLUAzzwC;pGuheM(+$_C zy6>sfLEd(y6(Wykr*)jtv#p8Ub&ZXUb%?2hJ6~F2(V2&7PrK5tL4JDp z&^gi~IBabk?e43g41HbWdb&zkIe!xq0VdPafQf4pD2prv`|ZXNt(GTO5h{sM*SOw+ zhFIKsZOqgm^BEovp11}|4$F$T!0WvCU8S}Xev{wR5<6OhhfN*N6T2XOjRnCXU{50Aa+e{E56c$C)R4k zT5)BixWOZirp<+Xep81=sehEq<)o4%OifMvDFVxgX)tIFu%}|Jp&`hLjz~%2n+Q@V z@9+V~XPD0q$g-Nz$m_j&L4V=uJ%fgU(GkJHY5WfPk#5t_Gm;nzNJ&Yt5P0BzThtMd791SxXI+(tL2Ohtheps7PZ z5Hb@#Z4CajCUBSik_KLbWIqF=P1cT_oHc3u;laVdp{A7JH90vuY_~sJMi3$b1p07T zk$?VhPl7-uOX&E^hklVP>)mHM&fVE;lr%iq8SUswZ#euRBJm52he#y)F){H^d#wQW z?~?25)dM{3ljP)qfq$K=a2f$Wb|*10@rzDX=P%ztB92;!*VXkGFP<(OG$!{CJa{nB zKbMB!?#aDIl*Gh{ALFJz%k!Z6QhohJwfaH-=?4P?r;~r{N%P;^W8^Ev-H1e# z!?*t{32~YlqOh<#M4qtCyB!(T)#cuwhLDn#=0g1p zTCzu20(F3JxqqOgho=?iy+oKFN@}+MwYS-JNM zBAydNQiVn?F&M<58-yoHE<;LA2-`Nez)N8qdm=+57k@3pKcAeUyxcn;b1@e>8;0O5 zL9*M3E1{N@TaClm_h;-|z0LmqR3umB7Y3WO~i!~M`0 zTw5YAR3b{kS6u({Ki{4|ckcZ8Z@<324~-EL$a046Sj>$;pcE9ewWNpRc?QFhEW4Ab zkpyu(mw!xtm%??YVQc=Wl*}eOV^PT}c`x#*er_qyy1L zg_?qD*?M2yLP(VxHd#e21QAdMJb4;{2o22Ke1HFb&r(QF&;9#rqk({qtd18RrwN6F z$hISP17TFEWQ!>xKmP_5bU_3+Ol&z`FmI>}d^xZ;*%E)mFc*o@C}IHd-kcj|BmW8* zt1w7jm~$A{GDWD98;&uTO?F`>U`w$1F0VLK4~pa3e5o{l?VPpJB5A&vn7#Ovv*m;W z0Dn^EGTSLOv5}wQh9TmHw5saLoLQTz%BrL{W>K?q^Xw0~nYcMVURygpZXwKZ%&#gg zlg^2LqpY;JC?5zE)|;4J95PQn{^4Kd{P6hwa97-hC@q%GahxJ(f_pW~dvTn%*@!5+LQl+(Aw)!i3-(?DT-}|f6K}8=ROx0U z0^JEh;KQJ#x9G?e7v2-3j;}q^tW0H)9z-ATcDvG5GXo)~Xc){B)KqOc%1b39`C}I^N zis%VW5Ok1)R+K>4??@34(ghSzN=rbJ2!fiQ1G{T`E}{_uHAYJjvD|@{a3MtQfs`fE zcyXo?MP@=*b%>sDBPP!^gV4m;K7VF!RaEHSS_RiqM9~vYAs${_$`WXjY$|j3eP3VS zRyKx*`}g(vd(sN{QNrVs*AVd!fyW-UHNoDh*Xv(pVwkTU;!96_+T8puMZELOqx+~e z;j5n_VkwIz>)w4q92;qt{nKhCnJ|8=el@(pjEeQ|^WQ>O##sB~S diff --git a/TMessagesProj/src/main/assets/emoji/0_1475.png b/TMessagesProj/src/main/assets/emoji/0_1475.png index b9af05f3fbaef294f14452789b871a5ad5ad3dfd..12a124dbe1de9bf002fd609795343b9ee6978da0 100644 GIT binary patch delta 1963 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 AuK)l5 diff --git a/TMessagesProj/src/main/assets/emoji/0_1476.png b/TMessagesProj/src/main/assets/emoji/0_1476.png index 214f7dc1b4d6b1fb712083b42c1be191cc266ffa..0f2addbe7bd8f90bb90164476cd21b22e3864cde 100644 GIT binary patch delta 1812 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 kq2D zQzaQ2HDX~nCC#5~(wc6*qgl|EYECsRc1kf_LNP@yB;Co1M=>W>Hz)J&%*>Ey+NpnL z2m->1Vc^f0BQsjRj%XY;VAQdC8h^sqs(fSx0CX!MMKC6u9U46^DA~t>7<{_buX~=7 zgJA{&YA+o`Sbu>lH zsfb9)jA4Po-{;z=TD$Osxx3G`Wyi2+Ih@xbG+Zr=!GCE60H`Y}ym(51sH9eSj~qd9 z=Gd!Vj;iIpmfNj_*{6M!TsKWOE!LuU;<=HLSu~$#KHs&D!WkKLMk|wQO_p9btBOTd zG$F{ZWa6)cic>Mehg^Y8EiPfCMKUUl3kalsT!aY)dIkfZ4Ge%+KAw13H)Eu&hGnOL zV1!yhwSN*4m~m1ZgvFs^-lY7id&Ul?w^&CnjA;J}jBl z;~^kYKsG5$f^I=3yr728u#h-rs&yzEd@>@?CMD`PHc(e{nL;XgPBOTccUq#!aUBw{ zCM9lMT%n$qt9?gLEgI#~wRfbsg%uMcLwIz@@QZnJv>qKOe7VZEo@J1w$u%#Ty2FV} zD}Vg@=a0Y9u2MCgV6sC1004z_QchC<{ZS_V84m^m4E`G~EN1PShU!7BV*Q;TyE8rB z(}Vv0$L9QCGjjdN+_?V!c>ZRC*!@vbJNu+iyUzY~^Y~bjN&UUDGsNg~?ES~#tbEy0 ziT(ANrN8|A?ceDf@yP1k;n(5ph4=1Z`hQxo*qL#x+MDpt{&Cx=>)T_O>eBwx*z@kL zx0OjoHUIz!u1Q2eRCr#EmjzH9X&Q!mV218tfC)CZClDk81PBBoBq46M@m#XW#$~g+ zw<>pg+T-qnySuwf+}+)EUGA>#>s~U8WaDv@jcYcXyTz@_)8a zhBYAuhK#KVvkz?Ey!pUCr@!?<`_87fGlM0_b%82K-a~FpdI&BQZ zo*8v}!)MHxK{8M?4+&{kNTsD!RD@bnS8-rQlp*S9Z*Mqo!ap@ltrpbQwvrST_bI%lv`bL1#cmbx2LjL-_5K`xd^Bsp?FLn|d>-eFB= zTmF!U%jtfuISiUUQpl2ezZd=w03lbab?SJGqK+?B{ewdfZ&cwTUUFMQmw!q#djt_* z-;kT507Pz~LaB~JDdrK>ugm{Ft+=nM>c&$+ow8pw&-lrhMK7*@Ut8DKkPpA}Uuy7G+($4E`4Q&s*9xBucHkMr^c6LeVeO2M$ z;^oV}DnM*9junls*C{0pN`Hw`BH{bh$5HfRs!G+Rm-bajrBb{P=M8ps{>g~IoHzRM z8yc?F%OwqbLxLwlfd~px4f60lsh(3+CFOLgRDdvQl3d(z@k-j2ix0%trXW-ZjV4N^ zmr9e{x`#x(ZdFiF&~%fBWVb=BZmq3Q*BcTTREXsojV9%<1RL9E+N`JiIUVVN{Roq8dUM}H0kv)zLHq}_5qSkaABFoa6eQiYV6Xau#~-6!n%d<9)dr_+=F_W7O(?k3Ym?X4DW|4lA`aDRKS zl|40sx%0DipGdV_t$+5{nsuLjWs+fh6w=%*`$Z}KZwLh29Z{-o>^xIbv+h4X-T3L( z??ATuMm&5ZJAL889oci8*kCTu9EhMCQ!tslIyt0 zn>CDhH~VCHHc`vv)2C%Wye@zJWbrCXh-j{;XIDvMdjzPxaedtY&UF~>X2AW&<>{w@ zar&&RC_AhC_J4hyrS-tvL?Zg%ODY@NL5+>;_b1`_@ORGmca(` z5@3J`go73r5e-Ehm3*aqCV>DEhy`2ue6izO1T;k?jeleZ5nU$GNDl_Y3`9j2=trU+lBiMP1lA@7=lZ^;)vB4gu zgl}T&mOWqDTSumCZM+!eO9>2A-Hirg^lYkxDu#^twf-Fp1^)~(yOmjUo0Men;e`4kMTdE76gi z>;(ubT475|4vkGKtA>L_I4*PvWEgGOMWb-cnQT%BAl_pj7=p#j!U#l8i$YOI8yBd^ zEiTI;$H`>6m@GMlA?Ao<&_vI247{2sDh# z{@pwXx!|x~E%M4LQAbgk}#igai zWiA*M!pnmn)EtdE64A$^uPA_EWsOcy}pQX?=gC%BU1g`jH*go9~{K$KPope~Bi z{M;57l-dO#oS=31D_(}(!G>mCB5k)?@a73&EVKNFAY8PHf+KFU#mVa=-&8%ML z>W+?!2@C|C65G)c>r6?&_VKhU{zydog#!?nh_OTUzD0{x6eCrh$Eb0r5)a8R{R~5gSj{jGd2O zz4|lh;;Tom9!1PIdAswE^>$B7^CjO{1^%&uv}qJBmYq3s=8`K}2t@4=4a*a*uc#0Z z2-^&k%V00000NkvXXu0mjf3!?ce diff --git a/TMessagesProj/src/main/assets/emoji/0_1478.png b/TMessagesProj/src/main/assets/emoji/0_1478.png index e869b3334219f0d0c3617cf76da782e6e2c61235..e73e78da44d554c10eceb205976d59cb2f0bbd65 100644 GIT binary patch delta 1667 zcmV-}27LLQ7?TZPJ?Du%o0lL0TUe6f-6;JVbLQBSO8q zyG~({8yQSIC^8flHSOl#C?zOCFD2mK+wbe%!o$NMAY5)zMm8`ojgX!b4VvUN5Cx0tu5Dh#^Mn)137oD7( z3=A|YGhs|aK3G6C2?;OC%gi+kU}j8VkXb`FjEI0jQ;D`b zNUk(L+;o1ZCo@=bq;zqHOE)h*Eha!qdqYou;Naj;J2Ol-E;lG3+}zwoGb=418Q0g> z7ZgGd3pOYyS>)v81`H)PJ#I5MXkk)IAs|mSF)>S9ihn{rK6Ptm>+9=QX_#wXTClFH zS4KSn0~r()6HZD>iGX^~&(Kv=VJ0a*dvtOzGDk*3LzkGOOxbGq0001IbW%=J0R0*L z0|)*N{u%xL{v-ZA{z?-G{!}q)Dylm>{bHmh#{SzwW~R@{gV3#u*X%cseQf?(`jKzm zbU??G&wt(Q71#IHzF4Tw{@sOgp;wCBvd-yYy7%|rcI33&&yn(qw6KY@Rha3f!NU^@ z000CoNkl~p4E=9|9jyEm&<}z02tgoYkxB{Ydx)~h}OM!`S+S>LnPdn`StM5 zg?1P3eq1lFAtZu$JD*NJq~RB?9t_bCZOJ73B-0N)Xo2EGK;UdPod}ZYK@5$s`{S%= z69LfK?1+`v{eDIe1qNK~5{Seg!!WEM0Nq6|hPZs+2~Kx`PG}ccM&LwIr|ZR0jcpc) zI)6?8+XgKvVd?dF766F9S7VhdJGi?JuQXOd7(VdfaCT8!0Z}i}bT&Lvhhd13;_4M% z3TMO8n+k@YuZ?szOSd?XiP5lRBDDq)m({`8DtPZk}O5XKXRiGR1K5wjRNg@iLB6Nr1<{#l-4_bhfRjBW!sow=J9(NO$uJ<}tV1}nhCX}a8RnbdgU3x6ZY?o0VmvNSFhC(acU-;y%_wEBGk*+s zB{}QM%i&KBu<W2Akx7}xf*ry!4kx+mWb+@Wlr3>oiPG5eUsa%SRnQfx3 zIW%o3S*U7iAoALP$&?~hfrzd-5r1kg6~LGJ*0lw0+?1lCiC{1oNQAmd6dZ3lTZ_C+ zlLihE3|a$;#6)RAB&JQeU)BuP;!NEo`! zDm|5&npKXWZ~fWEx+oIHIRLfcKqyLTQsYWp!Wfs{S$858D(4yvG{(v4#stL?Up8rsB60!lhLv#`+GAZdUJa zZ*SdsqUOWVk$1URz;GOY>G-Lt8XH}1YH6w~{;3Kt_g$~rp>`--^cRI{8M1{i^V$Fa N002ovPDHLkV1fpV4}Aat delta 3097 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 delta 2973 zcmV;O3u5%T5u+E7B!84pOjJcja7;WpMyhsCq;N{Idro{zH_D)Zh<<3ef?jJ?N~Ua1 zP&_)Sb4}T(g+U__u6a+Oa80v(Sf*=Dq-{rhP&uJ*N$ta+J}oD^DJPr{4t-EHOf@S; zHZXfqJLb5RJTy6cQ8lo6R2_l9-?EQo2m=>?!F)_LBtmm!8h;k(yqN63oP1F^muX6< zb5g5yQW|@=o`7j}9~Cb(OR8>6f=e`gQ90(gltMEs9W-CMd{uGC^0a+cQ5OT48zm}6t0*O0dy`s)oDP7_ z4tu$ZT|?@;n8K8EIF-%asDo-66&)KKsDo^K85fBlADUr9!HH~P#P&yNg4v{iUTJnB zHCsHE$%_>enH?LaXhda+k$PfLl?w^eG%~`EX1$4G_kYr_w0&HSWJ$4iSbkJHPB<-u zT0og`QiKTxODYqqa8vu&wToXxZcaNm9SLVeGLmXeTs|#YG#dQizO@n(Xg?(G#Gv%d zsm7IV>b#gBhsLFTUBVa`L@_Ci3ka)+WdG;LbxA3q4GgD(Vr~ZltPl@$LMA+&)lNo8 zERf3>5q}cg!K7QX<0m5|;yE?Lg;~t8lz3%Vdo3SKsNAY2CDbP-nrBY4ka>-IZkBXk z=cIv$ZCNl}n;SJ_I%A{kCMHBYJ9-8K%@`NNrI2jD>L^Kl*c}}mJZ(5;s^cLbFkz)J zD=MvtYd0}4r<8%8dRaM1Y|Nc^D^Q8MpNKxJ=zlJm)QGXcaFeJ~nZv)4% ziEdhZkKfR}&lhlF0001cbW%=J02w(S7ETQW{t4$OXZ`*wSK|D2l}P7({{HLhoMIv_ z-Mn7@{QZCZJ%Yo^iqNL4{{2(JGrMEX!v6k*Q?qaV^ySpw)O7Z!-=*>Wo6NUrIdtpY zE`Nfn)9ys!>O9_Ht0BtkoJot~bi3B5@VtlK`mw^B@tTyn+3f!Q7p=a6000O>Nkl@_)D>I5IOhM*zb?k-1Zxdw%cUz31~|X9(#j zo7-VFr=-s*2#-o{!@Mrc4Qb@q=Jp$tsVbU7h}>%ttD45fUf+K0%bnJ+prq$1lgB+h zJyil$L2`b~VYJHiW|i;B6O}NSNO|1Z+1c}$Av$~F*#tCKCAEr;R)fJHS4yR)C4T_{ zFX_DOHq<-@#?zXf&hObq%FB?;ttOLL0}K;LZh+uab>6nwTv;MfR+gu*^Lw0yNNtci zta|OJNn>G<4Bk|KoT?kH{%2kF_4VMh>uD7maiGv~)Lvw;EEWwwRzj%bV))kG6P5P!7Upb=}Vft7^se4^_w>;gnrVZUx-XZY+y*jA%) zV7%t?OSgOMlVV(B)GVKx+Ts5e)(>>TF2*|x>o2cQo1Nf;AB{Z|_jeKQzdtqnZ7_3x96V6H= z8eSLu*4rLu?R% z?-F^OE~n?*E`&8(L`g8LPQSaAIDHK!gZ;&~UEg#L4y1GOadR z|DThQ5^nJB7xOEQU-EdIe;%*k3)qqHvp<);Bm1z@(syNLKhHx00DtFS2_qxby)N6O zgoNIU$Fos3;_RC{cgo&9douQ}45a%+puvAu-@AT&#QxElFx=bQdvW+XwkGmEycy~) z156qC=zgC$)yAU4>Rb07UawB*O&9^f#e{z>Vwq=O;hMKY-FINR+y3gqrcTxmcDubA z7%(Fv3Bw7)Kj5fza^5s49{zj!-3+CVxw77X+en9xt4 zIe!k$uWbRwy<64x#GB3AE_qhWM&y%Z^eDN1*4 zpZY>$3rOPyb$|1|Rp8b^UMLZZkytKX;GN0_B!+|oWtwpP1c=1Omd3_JKpa|>18#*5 z6wL=sNRBPM@@Nf{N3T|Lz;uYra5P6pQJaeQscV4&gjzt99|mpYguH_#V3^zSmG>9E z`h4ZuwQE;i-MzmDwh<*si_=jD(*%bA0aIIhvw40w`hP7&tvwuiGRZvNv32+F0^z}f zYgazsy}uIYG#`ti!w^mg@jDUp8>HFMPfwGELsTqEZ!(rGKLafvJsF? zIdOq~MKhzqB2gs$3-Mr*z!7fD;y4mMDEy5|y?p0LqBSaw~*PG4CjbA01RVuywD`pSEHyxaQx&j19fS3$lX@34(zp)}i<$ErL z1WekDrxh>S-2URlU6>ay+BX*o(7?d?N|g@~sgN)$ApwITp+T2vqqpfB_Gjp~X|?~J z)_){JNR#+WCJB}R0>d!b>Ea({7>O<8g%Un#QZXQWa}oG58W1~p+hrI==Y*9h)(;(1+@G=sYwNOKX~2%4s&bCK9+aE%C?h2R0ANu}JvN=N`9 z8;t>187+&Bok=XgS3^S2PJ~6sWZG?!2!C&f3>1;m2z`Kfu0Oygps@@Qi{L+MK_LwO zim&%U0^MS6ssjW%XBTjc+d~P2FZDfXk}gNSf`oK6Dkt$bSJ( zHP=DHPnnmn6OlCLKi5K<%*3bd2qaEtBmC1oKpbEv!erR8aK@6sH+oR;6obK3!a?v< zlfjU@h*dyO$V%6L1FMtTz8#!kf>WYU)FcZKB)$d|@$AHJrISR#MBl`TU}C=lBsm=r z3JX)PWcT`yAN|CJ@sHY*K?~+5n}19eMG9D3da}i2u< zr*Kw^T0^mVUB8ZKnPg0PPC2`YWyO_jYZvT<0000AbW%=J0Cm^VNqwmy{Gw>kfbjqT z10P95K~#8No!AXegfI*S;5#-LwB6VJ{~v3+((NQ9;@&ecF@N&-c305&`d5PG_228f zf43a2*7W(L>JI-L@P~5%P%A{JDSa$(JZlo(uBI~)1u`Qgc;6Mi0*6bV_Jf5$i~xhE z)rBkIU370B!e{{L)1!nKnpy#`#5<+R0e7$?g44k}k#pogGyh&g8}+ka(>URa>Yug{f;g*ZjC@B6icyL^8a1_8A1rBFtUC{>PkxQy{fQU#Q& z^*n3Kuhno52zy5i70GoYJSq{v2s0qQAJ4(fBNJ-$$S6h}e+lg*m}q;^feNt`4@!V; z7BjU60F4L_1jy9hN;XE2yzSKkA?BSjhvdUT>$B5LN`GM4B}LXtqbqJi`m;ntDpCXc zdA3_J7?IB0QOSsm3;{I2RtsDh#K?V#h`(1WH3V!iyaM-KdI=-MkiwD*S!;xJ$=w`; z(F{qISFLdn}J$2LRdkxpV`1;(lKqMhFYXg>L*|v4T+ZwA~N?baMai$R57Uny(2 z1#V`6zT#zDIa|v*fcvb4#83p3SZ*$QWB>~gv(=t9Fw^$>e>OEl5W-IoVG%+N%)CSs z@qZ<=!NNT8+WI7MmI!v!LX@+Z%GL>_b&l}ViM-7d07}drhTX7Cke_Z5wS^qUJONC^ zSz^`o1Saw%aTo!!gM`J1>EjF}1S4_!P4!IRDbO~3o7uy<_$gv(1V)@L5tzt=MOw+>4m%<2@BEqb(?5xP|kNG_LhZe^Vd76V0SkfQr00000NkvXXu0mjfeEq2r delta 727 zcmV;|0x12n2k!-tB!47OOjJcja7;ceCNm@*Loq2qFDO1OCPXqSIw~VZG%Q<2J5)b5 zOE)k{vG#KS000SeQchC<{{A7jjY-;Xhatf30007UNkl2{6BPG>f)rx${oogS}bTF+LI_Bc&K;fdft9p*Y_arB>FO5lf0{z&ax!ElA~t$WXY!{WT-ydILZl z00?xeqJBj}0R8IRL*RD>2c>5L!7@3@f`J9B7m78G;=2$ceKH*M`&ZW#%6yGpG?N8b zWJd{T(Th--@ZkgzTmSXV#*;f8H)m+M8r zzWz}tCK*UR6?jg)$v-GUAMv(+Y30#4W*(6FAu)vk7k>f-9D^~^RexyR+iCk-Dg8<= zMj(<<*6Y_qH6gF5hfS(NR@Wj#vx&gXCUsF83JM7GuLU$u6s8Dgi2M6?8##zme zzq;m7OksjOht+|{d+_RjkTw)CUllnX8zfMND|Wz(0`?S9hr@fZ8AGIxR@qaOkwO6X z6v8Yo{w@Q$bz`Kv3E1=BbeFc1D2yd0=fF^MB2nSY&New~hNGxCIX68kQzj%V zLp?s`;MkA|BI~@KPEdQsQcVsGG8z{)5)m*B3JUejsGFOcRZ2tJGDc@flY>P{P)$cel#`IczPRA3owsX4QE8W;EkTWni1yO0 zq@I`Nwvt3thJPFyN-#BU?1YV~9yNx4e?K@lL@qhhH9?jTDY6(YznEn-GBWPKn#qb} z;oaQq%&M`mu`)3#o2;o=SYgn!Q?9 zQDu~NTYpB@g>s;7Pi$&wz8x|p9~(0@UBal1SwT0#G&)8{QPF8$JSrW!2poQPb*P1L z+LnJcFfdSSo$}A0C#j!PE!CQ5+42v8UqFn zRsJ{pF-IJvLuUTr*Ep4B#dYNw6?BlZ`+Zi%HAj+-YcQ z;IJSG=?y(SZ5mKq?i~zH!xPQ8#{Npf9UmX(a^MgxtDx*51Xt4lXQi%XW8If&x4!~) zzZNcx)GWt(W~STiw%hF-IK-89o5M#@tA7ittL_X)6`$Emgl~1pxvC@@G(216pilz;Iso~zI(19KYKBhOf7rg@? z!6I@&63@I2lX33M|3LVsw;e{pdkc0=LI}eqX(C>J58KmDwbWnw%xNN==P}s93L_RB zgzFL;ijefcA4Yf`q!Vs1=tHj3Fn{8ui3~ywM(X3g7Y(8@zu}qFNG_(7Cr(JtTKCPV zLx>d{NzSDtK3k`=)}KE)1tx23dXuoZ22v8-Rg8Z2ns2%3*n7mB(K?!vawbs;?Hg?+ zBjqAdI8DMemneds6#QC&%V@N)EVSgie z^Ru%ux#i8$(zr^T&y15$mVaH(+UHdP5lY;wpPA6B&^QrEpVu77oz*cvFVpHI`YFA~ zgWh1r6+=nWLBq^OfRGDOy~mVB7DUlpIe!&Ke0=nHmSyL$ zBBNn`tkOHwXH{(Xo@zxt++yt z3nhFENv{-JCULDYrj_LE`e;*wRm*{hN%UJVV|*2A#uZ9gqabQ8%WCqXulx;#0vDRm zbbtdg%sM&faaGh9Zhz-QC4ea8a-C3eJ?xPmY6*}bVnuVN8)Z+6~|d2?0cAk0b2S79D2Bm-B-l--e^$DOfXP|R~Ut^-l*UPBy}#jH~Z z-G!V(BmLd^BkmO5MI4Bbpmn?9{wTJXJrp%llziau>bk{_d4DC3^!^HbfGC>xqDpVh zcT?2FU>|+|UpKpAz9Km-&0lP7p=)bv5)Xe5OS{`cQSQOM{hOe-rYq*Fo>n+9F)gh045(|3Ev2R!@pf&+^t$YI4^y5hd!!J=j0 zWsBQJ+eP%=E;lL~E@ng=8nKH(PkvNZT=4tJl6vglpOWc`UsVi&Ao_#;0X-<9;=^|o Qd;kCd07*qoM6N<$g7XBF)c^nh delta 3043 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­Q!3_;eA3%)fuNnxX<9Fj0uR)VHz z8M$y#Sl_OMT|tw{=`=Z8Sa4CY9{*`y34dBF7L&;YnIvn(?sbMjK_^hSkX4LWz1T*` z>9Yib<&Z?@UtUaRcN4*tZ{C9=zVv!AjKGYpQ0P0jiO{>cfj}5H9)|9-5XjSO#4xwZ zgYG6y$}rC@NP$ig+8IoS`37Nw+ysPl z!ETk=zk*$?uk|G1v10B~Cfrv1w0{E#5g-VAStgV)Vbn&d*t8NpsKv;-`o|_oXcycv z!qeXdC9E&%rTbta1V$|Or@vcW-H&nAcq_aSFtnyl9BHqth&AXrFUC<^ ztq~U%l7vQpHZqa}v{RoX_=k#$aU53*ulLZKKraA+o_JFTY6AF#00^q(S~_yBTC5Wa z(CqBGWCGd$LL2RWHv_cJXXqIauA$zKI8nTSJ%Zx)IuAMGS z`sO+#5P%%Il88r-mZ3y%9Gd0i>EstweIFn+LPKE`tN;yF;VS>w`FJ7!(~sZqPU$HI zMQAwJd!huh3CwlP;V|Ex&8q5Q9GdAyvhJRMS!{LARLw*e4UrQdM zqUqW5?L7lWC|q7EiLuneX@^7cYWzq{D6RY~=~YjC1d`=2u=b{3m1b}P2I050Gq$j@xI)0%%C_m%U#Vd~X@#6)}jDz`QWE?ayb%@62Cw_$d1L~8&6rGUa(f|Me07*qoM6N<$ Ef*j0)UH||9 delta 2767 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 V5yN7IP$K{U002ovPDHLkV1oY${YwA< diff --git a/TMessagesProj/src/main/assets/emoji/0_1483.png b/TMessagesProj/src/main/assets/emoji/0_1483.png index ce0bb47560a2fb99c76364180f843bd6e9333118..837d1e24ffbe463246e7ec34383b099ebaf7408a 100644 GIT binary patch delta 1835 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1484.png b/TMessagesProj/src/main/assets/emoji/0_1484.png index 79d24f94375b315ea28ff962f6a8cef1a59de8e6..4eafbb22260fa1ce1aa231d66317a449e568d856 100644 GIT binary patch delta 1864 zcmV-O2ekeH7vHSy(}s!4GlX;SeUi4ua}pXHau|> z5jbFHc($~#>B!c4d3J#yDi;?*F)1cMKzmVQjtU3~qoJMB&40x}PmD!Yo(2Lhj*E-K zB}d2?NIFG$*fvEjF*YnIMtyyHb#!%2W021tI+hnKdU$w|kB&w*F)}!Byi;AWEI!&N zMyVP#tRgp7P)@(Ry-hPO0|q6ytE|x>IoH+Ho*+7ce}2QjyN!y7H7+DoR$N3>h7%D& zH9m?oG-WtMfqzXqF;GxY6B81~mzco}L81jOAQ={o4J)V$FA)q1J3Bf!H(`#Cj)*i+ zNoSl+Lp&`pU0zB*;e(8AsjMkEiFtSDSCKzM@dp_X>6zo9$hyw zU{XggD}OsbKuM^Wen%@&YhPHKm~$Qg0044yQchC<{0&nh1{MPh{WdaQ{WnGVLLl(1 z3Bb4*!qw26VxAV4{@maqulm<{gfsrkS1IipkZZ7g**4eoz~-&ew~?lcNNs%RJK9n5 z3ok>2~ujDL>Lvps3X&GE>VF#hLMYFYpQ1dvHY zK~#8NrPk$F8(91M}O&wppOU0YraXoY5Tv!EqGl@t|<))pZz?D)TXdq5!K ziAMzuwJSssG$mk__1f)P(;9_gn2}#nNDlX&Q1yxh5z4Bz+XGswZU>{nJFf~LifW&9 ziZ~oDz#0L8n^r%DeID`C%lRLcHSL^ZtfQA9#6U2zziY@7KqTe0y!7XifPXz;!<{=o z;O9*s)6G4ZW1$r!;fR=)^+vv!U0If28*19eGM=h25U^=2&gHgcF(A-<1o>b$HzRuQQ{JM$olS}Ll)BwHOeP=|@%28eaT*LxwK zYZsns?H#Sdfg3<80O2%5T7SPHoXj#4XrLovLy^*VsjBS=!G@n&{pRH5P3P6<=MC$!EuXWU5&7$U?SFt z){(OmNkuK1O>V{Uh{5W<1wN|zZj%Lf*m|>0MKxZLJ-@PRsU%EnDSzNV8Vq53k$o?P z*^|3`6^~e~&N`;Xs?@J2tq@bY&++b`HeX*Cnj$~$;<*fjM z)yWndiKu$jZ4&$a#(!B!M)>WIQ8Wio+%Wa5(SoOlI^OYD(z>TcAk3G`(*XMWpE<8c zj=FB~;1m0m$+Rx6O0(Rqmwvx~e(qAbkIyQGb6)k_Nh1ioQ4hkOE?qQf)cf^^HAN?> z_6$_#?84OHM<6iaZ;~EAvkHhi`=1F2DnxVN0xjju^8<&A2SEo1pN1OJOjJcja7^;arG`%}j#Ms$SV3`HP<&E5dxMdZb7W#jJAhI( zKQ}&!Sv!DFGjhrEcStgMLLuU{l9FjnYzPAzHDh~DG=NVwfK)nsK_!AuF@aGuiBBq9 zwB$W5C*`x2dQm#-zMDQQBtkMS7=glmP&9^4F_a4ld{8-TMSnPF8Wl)0DSS~lTtzxh zK|41tGS{br;i`mqLLutEn{gr z8;a6|Q8E#O$qszFbx=J`Ixt=Y0)Q74LNhLDHX4CZH9|Z*HCJ}PD=Al7Ur}p4ufw^GZ&h1jDTlo+j?FoCotYgQSAT+$XUO+r!}ObJMN(dGr*d4d zeOj7dG>J?l_Ry{^Bq4(d27yN-`_{7{7#5FGDMvLej%7)CKpvJ^EreP?7Y`0kI4qub zR{r9`ieX0Sy_mHU62cf5bw(;O9TPt>ESwGuVl^F>a8YPaLDsXBqkv%{h{h_9%Rw(E zLpnOGh<|6FXFW2Q(tlMvH83zyL_k?SFFGtHcm@K4YF?}m4@jrn`rNwK9v!HIVsBbd zQ7syIWLLwKa4kl2-ynl)+IA*H<>CNmWC4c8PH85eNCw;o7C?zIHelc8|)x@wR zbFfxxcA|rCE>)3%ouxKDTuFD4uUbc_nUc$ITh~iJYeC^@0001lbW%=J0R8^{6bn)U z1{^sjD7OADz9#)W_HBi{(%vzr0drGT7v%hOFeq)`rk78{p*8t%|N2V{rtx8 z(to$1qiOQ|SM}&zjoahk>_`07?QLnlOHiBi(&pEJOTpgif!rCRCr#6)&*A_Sr!NIYNM;6@dOP) z6Czjy2m#{m9^#oyl9{;7j_l0(mbAMo?tkv?8h4*r`yzX*n$X>ZV*Z>%y>puSaqoTa zaX@B=&lNyW{SJM#`6JeU`|?28{vyO~-`CH1D?yh3<GefpMaCK?0?D$~Tl*Xqi~~rS&3{&JTjp-$$nci-&QZNyKi1hvG#+6%8{7n`w6DKf zU0I2-`|GSyDYe}lXts3donPFre zEPmFh8GELGHmoUr=FAJ8o7f@MScm`9S2TuIzH7IIDEr&BVMi@6COhkP> zDRp3&rNhClWcNu)GB?cqX@79Kv9VKYt?L|S9pEw%E6Qy3q}9T4^mSM`9a6I1<6uBG zWe^f$kx@cqWFm}&98RQE+QDYCEl`6Eu8JqY+mvo(u~^1aoA```Z+2=ye6G~$a5(xj zx$*G@saFMvXHHLLWMriOgAt(rV1Z5&FJf55k_`#`g{u%&T zbjD45Ywmgeyw&ty41=Ajou zgD(aL2XFsjIm0|<>VH>N&5I_fENcFjYIERB5hjz#3uyA19nO!c7z3`kB@Vj+e_bEk=O_Rvtem!8&E zvq`jHG&J`#d^i|>tE99vCnu+>sx&c0g>k|^-_x#v{k=_Kw0}M_o9qpt|DKxjp73v| zFy*ZhFaRhmO}w)i!~9(xA0za}0nr1K`4I>YdP4_TEt0wJyC52qt=&)p0idKLacdBU zZKkj4;`I`OBAQHQv#AM)bwv_lZ}68yxC#?TY$$nE;!5I~2$^f3{M8adQnXHFZ!$re z?7a=!4@d}N^?w%v8ilEL2{x1@x)7*>8|@ls@D_rQ9QaOTf6xT6FBLUxKg}W}>le=^ z!Z?_02}(EOA`T;w9D1Ou3CQX1L`&@tAT+TYT4NoWJ^Kak3e+7B}@<~3I zDkBO-VG=}K;C4~3-EIe=R}{Mc=rI;SoJG9}VKjy>M1S)qx}SV{`|#nzw@=uD=Ow5V_(akYg;#ZqI$? z`KweLQGeti^d;5Ef_(@t3d=AW&n})O8e9nt1p-;^y{|rOjN^l#`7Q!N6Zfc_ zSIOz33JzRp85mdx85mGnl3|~yR^WKKw?h^UH=BEM!Nd~};yw^vT{wFaO;oF^XA%hn z>=esg1}`c){1O)toLtcTnfL@mK1{ibNXH{!Sbx6B)oR*MQxE#k#;xCbYUX&M{?UOx zDB^d1ns_=*@DM@dp}l{jE=pLk+F+jGn4q#w5knGr#gAz$`GB?P`!}8eY`lR!aG2`@oWSL2mmw@qSG0Y!}mDHbqXNp z1b=6O?iJp?g!13IyWiaE?(Y7rJmH!j-(%0z&T$};C?Z4+1Vi{iN~O}#vEsS|o$ntIQTovd^ECZrVv4;ypn^S#* zu?pcTF)mg{Aj0eL+!p3Ni}8v!#U&m^=nSz4Q+!v6#o`l52zM1R}zlD26Jc(AW?+!BmCvI*jo+6T!a`(pI5UFcU%`=pz-WoPX5_ zKS@Cm{>T+YTgAA-A7v2e87LP{ceKsdQ%{0dixsiR5}=CbA^01`xN-+&?ZUm!1)nBh zCn60%g!uCirbOcSDj|h!#AV(GJRD}w233R`;29FdOeEnl*SU_sIo`j?C#0gH%@B$B z>?sB!mYMKn<3T+74Y6#aSHHaDg@1+p*<1wOky2QgvJ7F&T{fQj71jEEu`CZ3?g+Bw za(TQT^*^#!E{|ap(7)sOPhV5SFBVzi*5BO`zOnkGg@Msj|3Pa<1eS0^u{>Tnk%z*1Yb zgMrxa`0?YatyCiyU{wmM=>)?2Wo25LD4>^F48+!wsw${rdUg3Lk72?j_4xCVs%WvgO^< zxwWqT%`=B7itV!>f+UE{mL-fUi-#zT;J8-(?Y1Pwa&!ObgY2>&H$iV_ z9%#8Zzbg+#5EMKA-F3P+ynujwvpBeJZhOp=7;I~7PES~TKLDs|2)?9T|LupPNnE{m zLx?#=p@B^9vws`|3L*c_FGEp(Nm++iYnZDvuDUqC_s2EiryhhShu)$VGdpQ*AaP{aM>rT$u1M%VxV0?bK7 zK~#8N?bk(H8&MR1VMv%vNYWrlfKuGGh2nL0%echd-4%E5AMPC}`*7H>$hVl?ywAC3 z?q(Y9OZDp2tA{C-$~yr{!|2T7i~$1!_|MUp4}TSVheJnr?yLH8IbZB(V-83>&sD3r z90Dk+1-6gn#r0y$ceD}mdcA}kw1_!ZC7Tr}uOCHdK~uD<#SJ1@G{?QfOQlNm*{A`6$U_to%*V&2jz5u$ zn12DZ41Xw11cQE2-l|qzEa3oS;xk25N@l{VRdf{7p!ZVz)3Vd|TO67PAA;}MZD4SxXz#mBIo3x~t28Pfm`JqMT16kM*zwh6cl zd{(bFStEkrI?Ftj0jKE8o2&&y*mj`=He||Jqe2=HeKP1ihfTXtAseynK5Pao0+${G z`O|elRR9uK&cNw9rE*1WRz$$Uo(Pnxcy8OaK7bPPUO^R!+Tesz+naV3&Ljau^nYuY zTBs}<0SO=ioA0Hlv}io=oNP-0h&h$ZXfz(OZk9=%*pTt+mIT%|7&&0wZa2Hb&?(E- z-rn9D>{deCc&7xgI|0U-ve>sS%ZayLw-UNK-PZ$noDK=NESD2gAG$|wF@q$qHv=F* zDv>;YdkI z@7u4N>}ve<oz;3nA{>IkT|h8=PBShd9+V3Sd{H@jP&j)~H+DcMd`&V!H9kQvC()yJ zNHs1#EF@t}Kz2YOi%=;gc&=|+QP-$|>EN6_EG>jhGI(KEGk;EWeNsBRDkvQ_V2MvE zQLNry6Az7BJl3OobwD6>9~4s-5@`(vbUq(sOg?cN7<5TByNPGkrF}^?E7YfY!Hs7d zHDln%jfPGt7k<6QuVmDsdQCYmd{8*os(5-sA}2LleNsAdT2QcfPcc4Th*2!Shg=wl z&K!QZkXANc0)GI785h%_d3;eh#f4iPGF(kJEJZFNK`kb_fLbatPTQ@895-V*k;<)e zQ8|^*8;a5ne7bi+Bxyb<(3)}U;hf{xl8a(UuqY(k%7svdq0YN-a#ltyLS$hE0BZ;Y zP(L+^ARu|U)kZQVSw%Z!#`a$>6IfbZxrv-1_8Gd z6LdNr+^vROH6hHkZEj06!KGWef>>QiKvF?EJ0cfm1p(4CF=|jkkxe1RpnZ5M9DPhL zw2EoNnPR?u^%4R z#CfE8Kh3h0(}ZJ8l)Q>W7k{FxwvNq3Q$F%7Q(004$`QchC<{xtp-Q6B{Y3lJ-4{=feGsQLc6nptId7K16; z>rCnNSN_5)Foyp8&;7UI{Xavc&HhyT^^JEvKkLVOXZ{?wp}yd;?@`-F<>cIC)aNT{ zdFi8!_x;l5c%jQB^6E%=ff>M*ozUT!@_*vhq}s@l_uG8&{$=0S-omHmmd~Esf#lM( z>700x>dXKD2&YLzK~#8No!13$6YCZS@J$-oG?gTUdTD8aLRBbGTA;XGxVSqHc<6<9 z-&J`o8+VtwySuyM?(S|^W#0E~ph-%%%)I|}vO7uhn{&>dO(w|TpdK_32J(LB@qc4r z;!$MykS8Dd2!uTf9ZZkeyXOa(J$t=|15gK_rmJ}TC(~_-F?)VE4|DPS`2+KZ5vYM2 zQlr0rVBpoOZMMdk1GTp=-oE|j;ltY6+E3yM3ED@2StaUAO^uCh{{D>)*2Lb2j~>+n z<>Kv!we|JW2#c89*vL`$b1s22HGegI$+QUe2kLto9zA+dUt3$>^Ww#9I#ChcO-*XO zUaba1Cdg#VNaH`LPrxvhs2HZVezrXU;ihcLY_91l(>G^9B+Hv(O{hA$Uzv=?j_wW> zF)=qYORcZzDwIJaGczl5l% znQTQA^Y7n#Y%-c2-@DK6`Idknb4vPI_mqL9I$fT>@M?1jY3{%ycRc@?kC?h8Sg&+)o5(kL@!W#FMqO(Jo~mRGlns$X4vQ~T!PtLozE2oaH$ z#Ua%c7M9i2bm?Szl3LBNTve30G@++ge$3F@ldy?GMEn`7f?8dssDIJx!GoHU1sB7r zjJ2xj;%-s3YHc_|NGO$=SzsJpGFe$OiIb^RDy<20`%;lgl^|L=9U)9iocDSkACmgk zty}sMj*riJ@3}O@Ix8C1f;b?<#Gb|+eej!9Zfa^3>#qk#F|9xTP%?GO{wJd1geQM@ zqcVvN#*VM-K9{sB+JD=h+u41!4Ydd!tAcWJG_BRfCqY3MTKA7*5D4gw{3}=No@W;t zp4)+hZnM0yN|ST_dQRofs-OoKE?j86IfbZ*Lr?QV`|RvK2f&ppec#Uw$E_vQaC@goluQCXRx0e=QePHWK3pqs0PZe^TA z@_o8vXdg(ZW0Ai=GVWawE*UP;jFY%=CP$3c zR=RVMInJYdH}}fN03)a3$)rKt=6UBM#Y~d&R6mI0d!jd3{$p?9(?xP zsiP+@Uw=Mv;?%jbOJEs(%=lQ0KgVlq^o;@+m;xyz=nJU^h6wzq$dVb>#MaH=DoGY^sTP5* zC$?OZ;<<4HC(!v@usPP(l`&HyVbhVrIC1*&<$u$605M}BcwSH}O8BEaAfm58$7O>|HXSEYQc{kAq`)I27y+1SwWSZI5C^bC9_wtY2u1;+ z>VM_In=O1zN@5};65#<~+K7Ny(Bi;mhA^pgWb@V;@R|-(5zIhnEB+B%NQSK*OO(q~ zj?FtJ&jklaAk(G=SZyd700^>h1|UEcAULtk12#F;6~zg;!H~FSLCLe0{4bHPwl3&ErJwJSt8k5)*VMnL?KOHQ9+P zQ}CQ9wnS-idG5RzK$K^HfKYHFDZ9A}1ut?4ViEHL1j=yYfhu+*ZmFP(1vFbCPk)@8 zyNEU-J2`o{DrgIMGG3KC5;F-LeaS-*ln)V1UoMYZE8&YeJK8^q!~`3O1@LG}fN zFBs#l!35%p6C==(2Jw-+Tw;O=34gd!?(a3?nwty>WMuB}1SJv>yMPq~I+{ebCB!)4 z4yf{B2!ze$;q_A%@CNOL10>{Z#9fXP3_`-4C-Y_E7EfWj;0^{@1sibygxD~Fm~iFE z%zN#|Q_QsfH`I0Ck#6xmcZ9mH91v_`g6t=A!e6Cw6>OV+8N1us8sj_=hJPEYt&KGb zAjcjU%&p(GN>(o z`ueHkHp?X9ge;aa(-U^&EpQaFgqafwh*|mh`Dw6zbcgxuUB(KP;HR$;614UB>0AP0 zbdh7)KbO5b+i966Ee;Go83!l8@bm%a-b7WP%XjWH50Son=PY0i#ACz8jbC_}n+o&X d=(*Vn_#d`aM6{s9O9KD^002ovPDHLkV1hzC-Ut8y diff --git a/TMessagesProj/src/main/assets/emoji/0_1486.png b/TMessagesProj/src/main/assets/emoji/0_1486.png index bfc1272311a96a1db62492eec38b9735e99b6195..afa96f537b0b53c85903d62609ff532489535277 100644 GIT binary patch delta 1290 zcmV+l1@-#z7Mu!@BYy$2P)t-sM{rDDS63k%AZA@#c_n)k6+bgOXjDg4T}*ANG^{Hz zUzm@L-l@d1H?}q|Dv~Xg@x+{$FPf%clNS{pgD8c5Cx6kBZZRH9UQtfw)y2-PmQ+MZ zB_ktMQdt-pD2OSFqBNk=tco>2Z8SMvQ)!aLf?E&~BcLv+9)BS@3JVMH$e?s1c7rE{ z&u^);lYa8fsrSW_f+U3Z(W(gv320(x3IcH5?i&bfsTv1V2ZJM+-xo2Twv8|`F zQK3ywTF=VD_2J6AsFwB5uh61;0s;Z|&#O2=Z&YcST5p>x4@I~*yncRsySK2^g`&Q8 zPvo_d(35Q|DSs+O6+=lQIk}>Yp@?nu&8Y_rBM%J?>%pJ8H@$-&C?6m*J2*Q@K|b81es3#ZsA_J;qJq$%hJW0!k~TeU?7NXZN_SCYkV8aL zv3Om=ih;dKt-m|K|K7V;DQa+ZicUj%c1coMc{K~#8N z?b20u8f_GYVWf111OkBoY4E5tLR=fKdp{W$+}$ni)t}sVSS#nSbCQGH=X0%R&y4J$ z^w?vMJ%(c#b}s;1v&xm5YdCy?-CCB1!(nAV)PKMh<%K)~F&^ z4AkEL%`4tbr|XnJ^}}Wi{Kpdn!EYGsp z?b9^FFlvP$j@u?+f? zw(kj)c+aTS3?fYI6j0D?XmzfOiwl>DoqvPgp;qfm=N#9_vQ7;6JzP3A(?}CX)vVJ1 zT%kk6IYDsMY#)rk@hR4nsS$h=5xp{4n3I)=MgUI8=GY%iLVq5}nxH=hKKGkW(?_*H z_Boi?;?p#DR=o$|nJ11awLl;PB{Y*rFn>n^jM#lOJG;+UYE>k_h{^dh`YY?dZhx;c zl91_~@aUT}Gc(=`=PupSD9?gm7Y5}-Xf1%Lg1e=wMf$K#2^L$5bVqQX17Z4vm2&*$^|q!5xj zmJEcDQm1VmGZ?%phk(`w?_un8`?N@s#qPEY?CI-7A|5|(-GE+5t8x3#;^uadEPib7 z6i3(K^3zt!gF{_XLq=q421dt6G1)!CWe>H#YTDQ%i12g<00000NkvXXt^-0~f^_3q AQvd(} delta 2923 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 Vd{7-VL?8eF002ovPDHLkV1oFjN(uk~ diff --git a/TMessagesProj/src/main/assets/emoji/0_1487.png b/TMessagesProj/src/main/assets/emoji/0_1487.png index 5b5bc38c39707451b56ae2d45af5fff2748404a8..028c0ae2715a56cf94c56c72267987629a63ee01 100644 GIT binary patch delta 1291 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 LNkvXXu0mjfbX5r= delta 2608 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_149.png b/TMessagesProj/src/main/assets/emoji/0_149.png index 33f1404cf648061a8ab1689bade0dfe9a6f7c996..b622def5fb1e19b8a2a5142d0efabb86f459c981 100644 GIT binary patch delta 882 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1491.png b/TMessagesProj/src/main/assets/emoji/0_1491.png index a2a1704586240777f9ef5bd726aa748204de219b..c141e3cdb66725cef4fb1fc1e34ea4f439edce51 100644 GIT binary patch delta 1072 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1492.png b/TMessagesProj/src/main/assets/emoji/0_1492.png index 5ca430c105ee02e9fd270fb01cc1599054af6d2c..f0f33ac2fe995d649435ae710dba104fb5406e57 100644 GIT binary patch delta 983 zcmV;|11S9F6zm6(BYy!DP)t-sM{rDFU|>p0OtG-At*fk3QdHK^$*G@~CMPR6IXhfh zSlQUv1p@+FT3dyNhopjSDJm-;A0@rJx;rc(EG{nJ&%xi?)auf>>AH=$wzl=mr&?NC zS65dT7aH5x*tfH=%b9h8f`W8(bc=s=%E!mHv##^jy56yg<$ubpGc+|bFDUcOtC^IN z(az2U2^t3n41s}x^x)3huZ_NSO$7k}^vtPRT3RwPGW*o91PUSSyq0TgYvA7Ay0^F2 zrhpz767R&JyqbUHvWsP9Wps3Of`Wo?Z*S$|jZEuC>w&b6OuOfxPLjKlx{05x<{PE!E> zR66_q7X|+P4E_Fy{x_a|sr?^qP=Q(Q>u!@k+tvN!$g0qPHO#2mV9WBmsLoaEmg=wm zo!3$T00L4;L_t(|UhULZbDKaEhGBtCN2pt}iY?o5Z+~e^@2L0Un*9I&k+at1E*I$J zCX>;7zt4ON44MC@UAuPeDz{j+RmKByD}OCP*993XI}hszG}Zh)6=Xv`P4`{a;UZ8Ukb-b=3qa^EO2Ky_gREu~5aPLiCTFl!>;AVk zA?BA#23;d-sFz z4)^enLQ#NlJ?|VlfAKz&wi0q@+H$FB6mS@w8?FseWVaGNpG+p&$AE<4UWaSRFhuF(oZn)@ z$p&x|IsgDjdJ{Xx2dRm(2>@_j=U~F`49k-4sws!ar(G)aI-Oq6NfL%(bZBT<)|*qj zNJR*z<1xHR8YmQ@2KQz`!<3h4IK54d<4`1wzUg(y4M7p_(ino=gz*WD-htbcXW8s2 zOcBr1U8T%6ve{-c3pE-n?WPPkzgKuD$m#!Ae-40uv|ldYdulff-@yO?002ovPDHLk FV1hJS;~D?} delta 2654 zcmV-k3ZeDv2j&!zBYy$`P)t-sM{rC?GAT|tFnvupXGJ$!LOWbKEOTaIYfU>=J~Bu# zBuOzRieW}1At5{|AYnKo95rEGJ1iR*7)~oAd`>k`J26HsBY8|Tc}g*UP&a)}G+wsl zMKC8VAsjU#8j@*EL@_5wFCx1rCO9b~K`tkUQ7~OGBU@WrfPYUia7i>8fx=NYD~(z< zGcPiHP&a-|HzGS>ABDs>A{t6UKYUU-g;FtHLNQP>BxDE!GD&7UDk2zuy&QhHWCj6c z9u!|vOlLVFKaRX2hQ?+E0EHPBSx7$}GF(YMJ6~O0Av$3{e4aX$&klULrXwMVCLl6h zc_n+eQ7|8^Eq^O0pzS?kek49(BQ{_okkp(F3^kh5X295@-tq77`GCO)e`bETer~ zFCrYp7#NCCFheseERoHofnbCQ1zSfvB8bO?T0nBg@qeEU462E0A3kk=RXmLg365n- z*B%`>Ha4GVKbCG!CPsOwgkyLH1J^GtnsZd3c~`O$5^760LqbGDu%^GF+T3RF64jrNqwkWs`7lZ~#Qdq5uE@V02PWQvm)qQxhgG1PUBw-TwZ>{{BSyR;^B- znuom1{_W}3{&~Irfwb;%{@-N%gZ$j>aJN$Kj{5%l&q7P4p=a`a-{Jc);G>_?%kAo- zfxz?j`uy_Y5?zsLANBs%e#+X<{&h;AJ^%m*w0}uNK~#8Nh1Ugp+gKI`U`eqhbI5Vf zVQ$0FCS`64Q<%218Q2QJ%oJwkGV{={+;bIgEyq#%wNIs|j$fT~bg$)L2Se$M5CfJQ z%BV*%QrOWU`hLHD{rb5pB{@GxUOD#;<=hqWNTJQS{jZXiKEna~+`Cjd<`QjyD!Fd; zKYwj$*~>M^YcWsCBO6mZv5)(MNl|;g|;@F^;R%ETZq} zc9Gv@U4U$FZ+ED!Ww^#klI#sLu^7XJ!;M-aHFhj4_`P0#5fCVSs+Y`RwLc=k*7X5bV&Y2qqeEAAet5T%2(a3~)As1~DA8`ccC)Al4uxGkJq8 ze?SrfK)3}dDrq&MtMJhu*X444zpYeVepFl(;qT%i8_joUOtZo7 zcZKPcNARF9Kon(m!%6c1D~fPW7ezL3g3u%&I1Dq)!9N^;MXDb?=4Q8G&Yo0&b(=6P z!fGw@htc(+7TgP7QDKH4&j%!l3xD%ce&B>rn}BuU=U`QM85-88)oN95$>#hh8*m3; z651QJHW&oM<%NB~K@(_ksR={#J@)`C(eoxuGlZ?f>2!kO^@8AZR&_LHSA15I^7HeX zu_L0>lMinEE_0kLbN{_DM5;gjC^GN2`>@Rd&+d2S>9viYZ~i**nC2Ot`F}hy@oNvI z(l6Jqt<~3y$Dh^1$^G99TExwr%F2n)EvcuUCm@wWnHnxf=KuV2KJttO;qSlKZfkX8 zxOQRZdF8~!;|WE$li4CC{}Vw*q<#&AHK^yO!b1g$xVL?G6bwjZ<@0}}D)M^~o12?p zC_xR?-@bf!E5~T*P8AhWpMT7*`UXVSeh6VS z3%Kpn7$gpV#@c)8XipWPyix%h9Ec~oyC6&g5n$OSGM6wxAEr}d?PDm2FyS6$pj4U2 zvVk)|Z0_!EBI3+>mOWmU+eaNuSL=aLkai$+=KX<^O)Sfvzm$AE`2;fgI=Oo3Ec{n% z&XzC41*U<5M$&0NjephR%0SCN7$`*q7?X%NbF!Reqiwmvq5~}Yj#Hij0uRs z{+V&b7)J-?t@es0XfYkC(M%Ron0_Qpq-W7>z>KwJP4@^O^7_XumYM#}e#@L?e4i+5 zwyRbs0RV;#6=YX&Rk=oCF@}g4%hJ+#e`#mU`jTa)RDY>mXK&4Z!XsjO`Q?lBEZzc< zxdsq58ylAXuGaO?#vBkz^aOQ)Fbs7BL0NvgJUv|y>?qb#Dq?&o1VkGmYQ}-k2xXIH z+3Rnp_QDZ;B~ugYq0n4sUd4JMbR<#7;Ee1fY%)VLHr)Xt0R&O8ln5;yP0%=3t#fcV zeh876>whGFL>O#5R56U1I0omdjoHM;3J}Kfr9@)=2*Oy+GrU}j6>@OwC3A^Z-H!;; z$@83S!t_p#=eWWw!V;QF%vBi5msVEREp|Ii1hOQ`j>xfQ6w{zC$D0AW%r9@a$;0b}d}B2iOr&?IVk#z`V;m_M*OyJ}XT z5g;sxsL&>gne;nNJl>eS%@AQJQ|`=4ja{1{aAtplmhiYEt6#&Ft*sP%I2zgpx3&gL zFn`TFVEB$-K%gFS%(b7@gwaORcohk~;xrv=&=ja{p8rE3ZY=N%53;|9(X@bw23nx$ zDng66I3mk`C>KAyEps>24;m<6piyt6Ss2_JY}6XY%?sbYUAU+a7rtE>y{P)_P8byM z*fG?RnHC0VrdWeGwX?G`+JhRo31{)snO7|g?`IggVV_{&)S*H2jE#=oy_i0W-})sp z%sQ9=ZX-}Z4OK7}vsM+<>07sY{(p7~tc+1R>@XSkn<5$<4SE&uKcST5I0AL2wg3PC M07*qoM6N<$f)e1*4*&oF diff --git a/TMessagesProj/src/main/assets/emoji/0_1493.png b/TMessagesProj/src/main/assets/emoji/0_1493.png index d3e5dc3ef97faa373c6da1f5839f2356dfa075b8..9f9177ba8d6525bb4c8de10ab603f24b6a979fb4 100644 GIT binary patch delta 1011 zcmVrTzZ?{%k@}>!&s6hB*3Z z@OsSK$a~6_{=sOcUKshyjC!i|`q$pB+TgKutk7FPC4Z&>00K`*L_t(|UhUD>a@tT3 zfME#Yd)Jd*1&YvIpe>V11Lx@Xtth`)SV+_5XC}(4j-VOe~i1 z;Q=}m{}zV6mKdbK#KXTy&(GmFjUyT`4TZZ<40nt=2wksm2}N)hcTZ3AIeEI>Q{-LL zh2&i-m46b1IhLU7nyw4elxe2sKPX(MXB9ka2r=-*A0%lK$x`@y z#}W{erVmeKClWDMH9YZAB1UA@Vz2_&oNNi>$bXL|nBz!<9K=+wy@~3T>ALP&f6y6s22rByNpOX_z3%r1gMMc$^DHZhVu0IAD4ZA9Fb}{? z=0(*-fBN`b3at#9r#;19U`SK0cZR- hKW}L2odNKV_6IyIina*T^-cf)002ovPDHLkV1j)D`xF2G delta 2409 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 delta 2967 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 delta 3190 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1497.png b/TMessagesProj/src/main/assets/emoji/0_1497.png index 4ce65d9f2983d4801e8b39dd0c466034d571bdc4..6a20c381f5ce7f81d9af12fc9f5162448932da32 100644 GIT binary patch delta 1108 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1498.png b/TMessagesProj/src/main/assets/emoji/0_1498.png index bf78eb23d677bd06f1be2e4f755651fb10b85935..a74c9901fd2d7dd10159999c8dada1996486a5a8 100644 GIT binary patch delta 1144 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 D-ow{^ diff --git a/TMessagesProj/src/main/assets/emoji/0_1499.png b/TMessagesProj/src/main/assets/emoji/0_1499.png index 9b13f83a5d48779bb94201145e46caeca45bbbc5..610e5ad16f3dcc897795c1be19c25113c6373a76 100644 GIT binary patch delta 1130 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 UH~pGk;{X5v07*qoM6N<$f&fPA-2eap delta 3167 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 FV1mpKGvNRL diff --git a/TMessagesProj/src/main/assets/emoji/0_1501.png b/TMessagesProj/src/main/assets/emoji/0_1501.png index 45f4b3ad5c83b76baa3bb8be41f1f9994b908492..bc37bcdb24b7d26c68ff0fa7f3a0942d9ad1f944 100644 GIT binary patch delta 1073 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1502.png b/TMessagesProj/src/main/assets/emoji/0_1502.png index 6c715dac1cf6a671631598328957e6c86b4f86e1..635d68c132ee6a130e2d2dcbadb5500fa9fe315e 100644 GIT binary patch delta 1010 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 Wg)3ToNW1_500{s|MNUMnLSTY_n&j~S delta 3233 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 TQQ+V@00000NkvXXu0mjfFt#!x diff --git a/TMessagesProj/src/main/assets/emoji/0_1505.png b/TMessagesProj/src/main/assets/emoji/0_1505.png index 5450a2374b371eb8e1bcba6de10c51ee4b99806c..6c4b0c7f78298b68858129ae21d750195e7c89f3 100644 GIT binary patch delta 1922 zcmV-|2YvX38ITW*uc}Le$SX~ z@aVzZvWncVhR&93&6RA}s)Ny@b=07D(x`gPl4-(|S7NWm)qkvg%a3L5=iAGVXUUCZ zKDpG>s(Nu%deNkJ7#&((TZ74rVFn2~)vVmNW%2Ihp$ZH`wXm?tvU(2^LKhxX?&aBf ze3ox)dykHp@aU!L;h*c^ok6$Mif?JApo7VdW^lycM7q|AP)&_osg8w~O;2}kZH}Rx zsq*dTu&lG|;D6C|#NxBQv*^Kz@bBv0&WPOC&}_ouR)4C=uw{sFnbN6YRV{S#>)_DI z$p{!*RmADKmS>BIf3mHl_3`Wn2R_5Sxvi+I($2>iw!F2svxQX8-?xy|o^;!=iP@-t z+^mGxrF`VNlGUMk;IM}S13hEU?$McU&68-|&WGW%i+@zd<*0>03JpuNl}u~V@CYGV zz@=KdoKthv^PPD)NWRZoek_|3L#u#QOj@vO?7UdF9q?Bbr~*_B+>_h4Ov)~t5D zlXYL*|GLDbGB#z})zSCx>B6steb(@6Y>6r=Q|8B~z+w792WY~HTC0DBSSo!KGh=t# z`jl@pgnwdhe!97O!O5nxnOjkOse4(N!K+y*UcbS!az9XIx7B(`rp1c(u65UtjiH{- z#e7bsL_=n4H=3z}#F$~$aR2Mg0001PbW%=J0R9dB0{$5W{tY9qzx@sUE&eq&MeS$N zl^0cNBgWbDkLsKC!rm??dq-HMdC!C!<|46PgMan=n}t{ieOnr%;22`>eX~ zH`?si^}NqQ`1Sar+?j@g+Q#g@jm`9F;#l|F;DOd z?ti-vtgHIZN>gO9sCPvuI-E0{bI`F1h^1?MczAex{GdfCL461aIU=M>DZ?=gN<+pE z6(}N@-oO-#7KwzljRPJ%=@?=`T!CMB}R>Yzke|i3PmO>t@04MuW)j1A|8(?B9XDNNPKiO z{*g@{LR%6*QDy@E77c(Czj4%Pm4_(jNF4F{#%|wEg(C6E(NUw(=#*z8*AU=KeFQZT z5+R{6z!-Z~@`RPU+uRihBoa!cQou<}HpxV!OIS`LB)|A*Zf+uVI~1u_$(Od5M}Gs0 zBTrbCof}IXk=z(+XR+;-53F*I2SO4T#WqVeq0zH!i7xFyPd-}wZDe5$B}o(*#f2Ja z5$NnB$ESm9qE}}Y7DjHZtuh=(qd1G}r41X_O!!LcfKZ4~_W^M0*2sOrH<(|+gAuz! zQXX!?myfAbHhX}$D0P#MXi6*0-VD{bBqrk2! z!%5yIDUG%Ynk=)U2sa7*qJ4Mmd(lYcZDGz7|yz6%-X>?p6# zl7_(YDT*Qt)tWs+X=Mka7iu71lw=Ae&xfI+v{9>4)c^wk!933z*l@CRrGG|xXV+PQ zBr>ug50A$a^?a!0@F zK7ai5_|pf9Txgpvb-Z}d@$&f%(^Zq{Qw0dK z9w+fl{8GoCfVg^f_J~FLw{<}#;+_+vWufs9D zXaS)Z!t1>bgvWR038q{lry=w#EPsmOyn}`|+sCHk*L*&LL26|@RDT?z1#nQ+V1<(l zYIFuba1`P+Yo$LhND6kjOZR#Yc?piA__AVsEl@MdjDQDmb-fnW;3Wu-q4@ww>LqM) z7vwf0BfV6VtIM_W-NT_@=gpV&kzRf+k6)Ge6wE&3$tf; zKwxDQQI%m+=6=0DEC~BP+o9KLX$~F;8HAnO5QH=J+Y>By#@Cj48y#2@HqI4no0t0R z%4TKeS;zv!A3tsd?CtJu$=e^zBydstW>*qTp&EPM7vU+d|8v$Ibwnllq} z`-JchTklb{FBZEAip9d=ehD+(@}02%%`ofFtuMtyKv-y(@=R|(_5Ht2DyZ){v%Un? z7P?hZ80PJ~s*46b|MkH}U#@C5QrExVb7EHn7$a=~82o?gAMO}+OsO23P5=M^07*qo IM6N<$f>uS>A^-pY delta 3201 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1506.png b/TMessagesProj/src/main/assets/emoji/0_1506.png index 3672d1b7fe3b8314382bfb89d71e70cdc0d6f74b..303ca2924613e8da09b247c2a0e96c13a432daa4 100644 GIT binary patch delta 1851 zcmV-B2gLY@8OjcjB!3D}OjJcja7?9cQJ7>(3L;zL-OI0yd8BMoqL+cFb7H4)RF`E; zO*2NCW=EA{N4bY%xPxG_e_o7SIb6-{l4V1jYE8F@VzYu_sBuJ1W@lG{3JgOa7dLiG zF9rriihY!KywvRB)p2Ncud1=czrEMX)|_Tfeorruigjmjp1rua=i%6J#NWJ&VQ_7Z zdU%teovHHe=YOtvTb-Ppy}7iFi3yYla`d zIk?W@x8{XZ&xMGex`tz{b6C8JWx$SSxPoG~fMBtCT(o^&lw?C*HW_Ww@P$@0zK3E? zED=z{;jVdCo@Y;1$>*nWRe0O_MkNfLb5LvA`2__)Wq&*!UfKM2)$wXTA-|Mr0RcHy zFcot~CItsdWY6wE2WFvqSv?;Kdrd5uY)UUOUjr6Z%Aa<+XY_inudb1CY;1=Z7)hC* ziI%vj*0Ppm!{5!L(n!ACq<>&{MWPflV})H_pLu&&Dt-3y?ms_d_UquQY}&w7`oVVo zk!0DJTz}6>5OH5KN~nRtuyb*nVtmV(?fud6d;kCdWpq+bQvejc{tztv1q&Qx4J0}4 zwB`N&E$>b}nlaPSK6$tP>rTl8489>e^AsrSK`i1Wai_RDr^y|!8S{!M+h9n<=B z{nhzA+T@0Vr<1Id*ZlRog}Q&9>-Evv;fA>2>3=!g*USD<;zGdy00fFjL_t(|Ud@(e zQyf_sg@>^o#)mOf5+DIWa7%yyaohMt)+M)H#@!8fC+@5Nac@)9*0MmRyZNwtYCcR= z*F1I3+h^W;W&c|tdV^JSB!a%mHW?Yv9sy#l+2%DVH%KMudU*iPsFBL(k4)|=Qc)r; z#(!02CK8FvL}s9>B_XOA#$sU@9ss}f!{J&*yRf)i@WTt*v1uK0z35I>b1C+#T5$-? zaU8>F3+u^31F30VxvS;k5Ka_eWROXPr+>oGL@Eb0T`jVn=iET;57G=fH5CrSENm)w zP9{#JPN%k`k$@9nJ)SV+uyIKpa}oq_uP*w6F3*%FTP}f6VgkTj8Lh+D?L)ol?38!%UxPFIaT3V}Ii$;@a05A+s*VzU3Q)L7wxX&Y6$$zCp zA`uNGmne!NAOt_95|-Z_^xOC%HW2h`A{q^aqN}K%sb~a{VQdh@=s^7yr81e_2&lyb zBqYlged>V{gR>DDF$(fgTBD|#9S$=_`Zf|A#}xwJ#ieVIU2DbwunV%Gg@x)g0ur6{ z2Fl6;-mR?w_YDuP!-!5{(?FaANq+#6s<^i0^?J9UyxbSOJtIb#5P{w9rD+35Q#s23-6QV^FPzkk25u<*wW zs%9?SmNX3IPahT*9>06`E7XuA7n=KzHb4Bi`R>`PU!bHQR3;3h*XQRqdBnuT&~-#C z!OkCx1nryuZHI7nXiO=x5`V32I0gVoQ}fSw!o;hWbsBMp$f;cbszzV(9$o}}bi0@& z@Gt;?ASpCxlWQGgXTN6rev~F!#avRL2OdyUWq>nOs`PS*plGsPr4f9=fCRY9wfevJ zkUWS&1~Au|S{*|2s0cvN>OS2+hf}5I86-q1OzdvcA%Cmt5vA4^-$oB+Gb=UE;R= pek(U`K>U$}Xq2)e3z7XN`U^$)bI8NK)N%j-002ovPDHLkV1hs$jdcJ3 delta 3203 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1507.png b/TMessagesProj/src/main/assets/emoji/0_1507.png index a1491815fd0202d275517c7f639c03938f52d89f..87eee5f75d76a5d0d3da59edc0d68ee9b725def9 100644 GIT binary patch delta 1870 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 LNkvXXu0mjf%0t+D diff --git a/TMessagesProj/src/main/assets/emoji/0_1509.png b/TMessagesProj/src/main/assets/emoji/0_1509.png index bb12e615597dcae367642502fd1738a1a1892707..99a52b8d29e9f3e93ad7f907484034b7a86a555e 100644 GIT binary patch delta 1961 zcmV;a2Uhs{7`G3QB!5y+OjJcja7+jwTDY#O+nyxi-`%)_Bjx7jxsYSDk3#9LBf^6h zw5g-Oeipm7qqw)W>7*ODxxM(mExNq9?W`ijf*1Df+?I@i(TE%5q8{(DA?>p+`^rDS zdlUZ5Ho(BZZEbS)&tcNg&G^MN%!V2I$UR(AXf-oNr=^_pw|^`S5=ZpSVEM>I__-X) z%FGA|E&0MR>D|lOmmZFfn$XS8!?1+xsUYm99q_Ln_sC7(p(DV+z_hlwSXyk#gBt7U zbnN0V)CG6zch{u0lja-<%nuo~^B?wg3}X_wL;E@aqQ$Kl|T)-rUtT zHc!%-AI!a&uB)Sih?V`pCH1Zv{Kzr`13bsa$N9Vb{U z;Mv*P(4R{G&@}4m>Xek0fq{W=aB_Hgdhfd|(UBfSMo6x9656CB|KWCPY=_8?8tKiF z_{BWVhJPCo5k@#TIPL83QB6rMGh`_#Qet3SprNDau_xQ3Gi_8fSYCtv*kj_sX~(K| z6fl2m%o*6jn#+ER*zkIgcA@>wm<5TFY~{{`9N6PJtvP7dS)Aa+Cf{ znf?2kvNHZ^@c!=C*JMqJNRCr$9mE~6(SsaEZ$s`$w5Tr-<3_c!gCc=mc~dwgoj zd4uWWi23s`*Q4z!pb$a~c~EWknimw#DQ6PX6w*lC>y`VQ&WAU`87jCH(?zI4QMFYQ z!FW-)@u^&*uY{mA3%iS$_e2 z11B{xJ*X0$@%#Nei)F|%G&HnwQ$+hwop*UpM^K9FGbSF-Wa3!>JRWc5hdi1~o71#l zD=Gm7cACjzG5JjtAdQLlN7MNndQ+_QEyjTt310yQov4?ULQ@pu$oQXmp5%&Yd zn?;+$xsk#|A-F=yK#CFj>VMA8j{0sEgJE`)G6QuH`{d-LedKQFDd05Ou3p|C9J`PK3Ic|M z?SY8e91foXQ=%wdl$d^Wlmrwlz;=5M`Jm-y#5t^1n*zfM(4zLtqgwnDD#sKh`${#V zK5o(HqcmvsH$8mh5PwBP7ud`T(fi%paA8dSxkZQ1Hvjh9zOS3>jvb_s%9RRh%mIgR zIl`Db13DG?lI6MH03UFVcDce@e^}#lWAF8k5+2Xf7WklhU{>(od?;D5DN6)#s{uLS zT`6sG!XumD_Bugqc0eDcry6r49bHHF)`)fS$H#fBBc zESOzb`u=@DLSv0iED^J3_Xf*lu~@l%eNUb~HHc~SLRK!ZBre;dD7(dCy`*4ymVTtM zjji7iv;P_<-0{`y8VKU?c!(3w(Qr>(m%#hx*wOvv?3#xlh-QceS=svx2!g;pXKxPw vzMh)}F$STcq#}JLf<6&=Pd>(B{tNyAsymra6_JSb00000NkvXXu0mjfa|{Bw delta 3189 zcmV-*42tu&5BeC8B!B2oOjJcja7->JDmN}JNjES_E-1ceNUdf;onu&oWl%^b5Go-c zH!35JUPUV)7^-$nEFv34Gb=DABAaGRsd7k4MoK&_C)r3YGb0?SZA{);I4U6=o@_=s zDI`#RF5Wct;&#K-_X6lx2_{ceX*dMxR1*=0001ubW%=J z0Dlu6{tFTs0tfy%&iyPpM$K9NF8-?in8f{cM)UnxBWZzX{$#nl?fxUC{QZI9fAHEi zhwj|0;znR*v;6&z(tUB%zx2ZS@taUf!%_KP{=Vvj+2HDV*}PgIHFfQ;{><;O= zXw9aNp?~1k$mP8L;NG6(sBE1R&YRefOMl(P@x9kA$X(9afYAO4-r}eL00^{6L_t(| zUWL_VbQ@O|2k?N2brNslQhh2QrvcnyX|(dGb3g;Gc!|= znVF#s`*rV(q*zuo-v0;BJ3eQAy6@g=8F3B9@kmPYz!5j$a3LJz{{#!jJh*xD=6{39 z5tu8$&0G8@$l|<_5iEAc!%8M&GhGV#*0biu7CO`CemfEoz1bot9(%37|1~3N@u05y z`t%z&Zh(=*F2o$Xrp-6?iXH-UtvJ@XypL~G>kI{hfq~brPrp8w$9j#-Vv$L&H`UeE z^>&LyYhs23VPIg5!C)w;uC5*&41XNVVyg(-t+bPXMM!O`{m{R&y;;;yON5`@-y5Ty3zDMMc&D=qO?6_+WgJdqS%<3AzroS)x@260z(bQE~HC!(TYw*Pk z+wjGO3+*VR=w5T!emb=*T64tnmjo|Nn zapdT+uCDh1=;}K5bo5ZcxzC%Mn=jC54r^?D{C6G;;oaFcu74E_I>)X&GR}FmoIKys z$BikVKncNxk1eQ>g@}`OF6{vWa`Z||->=3v2jMmG_REUKu#^I>|BAaPs!@!r;cRFc1oXAXB++iD;QrwX~-Nj4Q28O*was3R$e< z9!2Q#!iwO=#(&0Onm|c3!RawnIh&E$ycl^EUbVO7FM17bBK~e-EDZRQ7VZC z!k(P3Vr2>`(@-CI5gI=AWFa6R03n1jg0R;Fe6-Y{(HYbj}ha?>tSMwiCN|!ITu~z9^N3 zWK6hPQeSrY%$dt&^-#u4gzHNZ!^+@~HcFFmy+jL?VuSRD1PQec2fsaj|w5AK^|U zi3I0y$R@!ea^4tDe2yV;#l_O@1O#7y^`bK|AqnC5`l5+EhXD0v$4vs*g_w;YvAxz_ zNq;=Tp9MsNjcA~W41^ct=bOrN+RSY4XdKzK+lAmEF`45hio6jIAPzf-!xw977a^FC z8{|1eAOL{0@ceOxfH1@xOuI7nU@(wc8*#=?%tRnUui;~52&m!~L)^MW6I`ZIz$}_z z9|+Tol8ZJ1c}>803qJ_FdGiOz&6_s^|9|GU3v=Lj#wR;o!fwHGo+_zb{?Q^2ge6$0 zy4_zCHGYQ3zg-=QJNq0@u~=*kd8^H8ZQJPurLhDLmC0lhQO0``nNb$XcP6}2=vNA9jKdghsspi&w)leb{~d2!ExL z^5k$+Q4|&Xu@fHYDvhc=6N#7y&oKecL^y#G;zW$&2~R4God_7CQc3*dk)(GeD#^SE z=SJrOVGTimAP8{?JK;S>B2oKCBOY5N5=ncsvmQhclrDls zsWi+wV96Sn1?L4RiEx_mA(XJ-?1@&{-;7lm;h)g3#gJ3XUUO5Gsa_)x-hUEVD9%_C zWAgCHrP)86^G1XFF*^klIX9V>bpOx6SrBlUJfon{ED(

    g$zgDs z#=7BCT3TDjZM2`7{`2M#k@3!@OYdYbRlq42FqUAO4jr<6G`{Ij7Fa`>JZ;)!%yF7J bY~KF^r(ZAG(kc{_00000NkvXXu0mjf<&Muw diff --git a/TMessagesProj/src/main/assets/emoji/0_151.png b/TMessagesProj/src/main/assets/emoji/0_151.png index a613bdb664cc80f2546af609467e52829979028a..33f1404cf648061a8ab1689bade0dfe9a6f7c996 100644 GIT binary patch delta 956 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 delta 3235 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 QSpWb407*qoM6N<$f_|59yZ`_I delta 3176 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 T3^;j}00000NkvXXu0mjfrpO`N delta 3239 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1513.png b/TMessagesProj/src/main/assets/emoji/0_1513.png index 6a60c4e5e135e409669281aec476b8aa1eb12cb6..383bfca10a6b418e59b2d16a4966c12aaa10a28e 100644 GIT binary patch delta 1602 zcmV-I2EF-!7SarmBYy#sP)t-sM{rDiS3|hAwO&3oeMu_F#lc}YDU5DP*3-&)Mk$C> zGDI;ed`T?7zP@pAbp;++y0ot}C@_jvHny{|b3i0XIWo%0$#z62iBd6bJ|&)vfxNrB zk6Ss6V@kELtB_eWLN6(6Y->+1A#*|}dr2$Y+0^Uj;*wi7j(=D)lUz55QZnP-)uw=E z@#WZQJ0qZ#jyWntrC4v7nWQhm5GCr=OLRQ9U#0>FI=L zR;Z+{3lmxh2Y){F@#~FePgH`F5%(g$jHdr+SFEzGVUduOJUcoF2}a-F-hWqIfoM`jg=$x%q@=u_iP_A; zM>8!|K{h@;W5TVmo&W#R`jwy-5%sjBeJiD_n-7N$&GlXH_ ze{ai4ZB=FivgT>4_B=>W{q?DHZeQXq{V)4i;N!=D*Qgs{9((dlRch3(mk{`NN%)!? z)#=0AJD>Wh%Bv3%Na6E60=8k+mu29E3Q#GjUw?EaYO%6HyDY$VxvdvLOz;wHL#ACW zk6Lsh2F|`n2q28`>Yl9F0x$7Gx!fMp>%ul9^1LXdQZIB5m(d4-h#&%1%A$M3Cm6&+ zM&ehUBx%yepn}0MD+?B~$)`_$opkm$6aS3k@P~!B*>1Or)m;!Y9A6>{3*o_lL=RzDqh};w)xN<< z$Bx<_wvkV$${3WKXPU<*`j;nhiBOc>Tb{9!IuLXuk-;h|%6Uu#1B4!ViYg+fgnuPo z#Et5aDU!jEVp!yP6mt^#Y~TsYDQ6Gv{T&-4fRcc)2VSfbU41c=F*6S@7r^;0;lw7TM%l#0@s3d|f=UklYsdRW) zaJ3Hn{dgFWcpftOdWqxW@#h6hD3mJ7s#!b2$MXz;LTtBLi|=ib-Y2*dt{G;76seIy zPWK3*vE`|aE%l5&;HrmX0t7?TBQrKF6dS_;q^>T4rmy;OMg@U|2r!~3j(^zht=HmH z5h3ICcm}pv7D9+HW;ROQhZqq7g25lb)PQwcU{wwR)9Z`oyR1-i41(jf8y+s@Segh4 zm~&D6^YQDKTc+C(4geqbtKE5CvPz^0Ds{4&b^!9T|<_e^EV?F7oc$e!Z&?r$c>2UX8ct3;;;MX zkKXt$f1kV_#mY%aFmKXWxNZwq(p3iIdzWevR2cJ()a)x0IZ~2XU^l9-L zVt8}ky|2oB)OoC7!`c6kT|b8DdB53kyWO2mM}DMbqda=$r~lQ&{5#sG%?55;_G;Qn z!}LulFRl+BoHX9piJy^ae)8Ee@spxy;=iiD0R&|z20DQAjsO4v07*qoM6N<$f_e-W AmjD0& delta 2809 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 LNkvXXu0mjfb2K(d diff --git a/TMessagesProj/src/main/assets/emoji/0_1514.png b/TMessagesProj/src/main/assets/emoji/0_1514.png index c862b3511f744acdd853abedad28ea246b6cf42a..26bc7559cb7751c97f0b8734bde63c8fbc963bca 100644 GIT binary patch delta 1464 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 Q00000NkvXXt^-0~f`TZv82|tP delta 2980 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 P00000NkvXXu0mjf2s4s% delta 3039 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1518.png b/TMessagesProj/src/main/assets/emoji/0_1518.png index 28b5cfe7be684f2288beef66e3c936b57820c4c0..7cb789f32419ca96384a1160b6a3b7d683be2e3c 100644 GIT binary patch delta 1753 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 C#yPnF diff --git a/TMessagesProj/src/main/assets/emoji/0_1519.png b/TMessagesProj/src/main/assets/emoji/0_1519.png index 9e77d96b2c2d5ea1cc70cdb0c8b6a80fb5f155a6..dc55c49da0f49b51b91d9f5d747e6e7f7341c589 100644 GIT binary patch delta 1692 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 delta 825 zcmV-91IGNK2hawPB!4YXOjJcja7=SbHIH3Jqij=?U`di+NTY01drvyOjAp=)X}E-9 zrEOHPd0dxcOomoLUjD)100008bW%=J0Q@Yif?VOliyma90008YNkl^^Ym!oPWdL08&8!DDlrB5$h!^ zK_aD;ek)WW!a=GKa|k2Tz#)|UcnyUBs$nJK#c1&%AqwF<&npQ@8R_1d6DdlDlL)5( z7&Q<*-}Ocsm@cPpB5(>Wjj`X%k7RbosSN(B#|WP@(1qOA30`v^#MaYi0)-cb6Q-JD zw7!3Nl2cj7KYtf#DU)pZi!CB;keoL%#9NF&{bgYvo&3uXFAI$X5Pcx%AdXlj$?U() zU^_BITtbNb4xoE>L|HcR9>8#ZHeV4CCIo7L#kLX%v91&HvI)I~YN*5@Gr52`a-l9~vZ z&^*MAcI^tXSzsaj>gm%%bnfc1qV3@kqI2-}2H?lnM+jz^z<&0p58_)VNS7~qrDuc2 zcrv8KXF=6f+e3o?8c2?<2VA!JHCJ6S|Q z78XPlA4v`rTh23Z6&yKCRG7fLy1E!$z$9c^MmbJNT_GQMO>3;&*3Cv*o^d)rL}RF5 zUSql)T~0+&w7ImePDMpbUZkO< zuBD=)QdXFqFn>_n)y-gNeno4mMlvi&H7-IgDNHyqR6#aUJvBWnB-=7_;VE+8Gj=s5 z9$7*;9w|!KDs0mxYDq#u+AMDh89ERRdmbNzH9e3jE{siOskkd$KR7u;H!#H`U^_>X zo-9yXeY)BtY!41>T2N2pHhEKav@|U#yTQwhiHw4Wuzx*3Xi_aMWOS`WFL{xp#@^%R zBN`=KT#c{uOfUcd09JHTPE!E>V*Mcl7zh3k{(49{^}~|rEN={vKK@h0)BdyC;_n|M z-emnw)|dYN@v@qie!11O`_@1&_ty2RLeTm_^^x1Qll-dmN^Ot0!q}E*g0Jp;&w%S+ z{8lwy0Dk}kJ4r-ARCr$1mQ{D-1`vfM83dLwF~pAJFf<4o+-#af=r-kw$;=q$h5qo4 zw8`n&)LBc~mv)XH{PgMGJ2M&~|Jic6y%WxF0k|jT_8gAAeV1K8Xl^f`cN{}a*tM{6 z+-MvdHH+J0cpdq(hU3_wm)B+x{xhwacjWcozJJXuoN=+)$Tyq$eBNUdf%_$vZL&8I~vd5ZjCt&vP6v zq}TgMyF>0_eLf#6q|?H0Z{MuhqL3Ko#Zsambd>DNojJRaxQB?Hx{}?2{tj3gbliRS z=YLtNo>i1O5Yp+O$Gi}CVDh#Lo{pjv3MZW=Ap*m^5OP)|QWFM>uODUsQD-=o7X=U! zGl!r>USbAaNN9k+))BI*cBC^-9}$A^;ARlsl%#1G;vNwB>sHo4D4lCf;()@k0W%Cd z%xOLv2@nL!=ql8c6XmcqJsFn_hN;DMCVw?E zIBnWMfQ*9t)`ieKUc;RaGuz<(CA{#H<4DWXOOxtfvVU+F`wnKxMg*n@$TNL)$tiFTjZ`E1jkwuzEXe z$uJPpyufn-dp8Mr(Q4&dt!WA7-5vsY^0@N;{rk)4Cr#5fhV6*>^WEveY3;+uT6sKk z)&A8wVR-BG;Nal&!^fL;rCKd*u75nSY~tMk6ll0?1EMs3wDQ=Z6?{vV@R?98m&V7- z?b?>L;R^s6r0Dr& z6>=;s&d-dO%GFBcYS6-j?!#hg>wlHYAYtB(EC6B?ZAg;8k9L~0F)6Z~Sugv=oNU@^HQjYk$2?;eVKdvMF(`IQdi0fAt+aJP)G!4&sd34x9-E=2kt3NtA1Ov>AJ z`|(iB6ON}?g2`miOk!%}fqyVX@#}|+^m_cCid2S*KJAXcAxy?c_egv;Q>2O)Q?3U- zTtya==uxkBi$&^}?d})RL-1VhtJD7jRYX_2#))G=o=Jv~-UzgqxaT9XfJK}muYN`) zPBU@A@nwi&>V>e~-!0{lv8T_YSM!jw{Q^HzKMo_` fSS}axf33d(2Zkap4k^R@00000NkvXXu0mjfI|}w@ delta 2649 zcmV-f3a0h(4B-@zBYy%_P)t-sM{rEvjvxQoX#e7e{@r~3;f?*+Z|b!`=dL9F>9POv z%7b50>8msU-huzaQi^qaysmBHx}Lxtv*eWk1EEKGLs5-=86eg>NPt6OMahx1V?7 zr5db>XyT+Acv3axq$1&?CgGkW?S75E-dY) zBC{ta<25r zQaOH8J9t1Wb~7S(VoiBsOn_-pgl}1TV@-)*MT&M`dQ&`pQ#*}iNs?+!d{8-fUPza4 zQG8K4oPTy!lYnQMhj68UUZIb7rHq%y|Nlhs|No$I|Jnck|NsC0#{d7b^8dX5|J(nA{Qlp_|FW+A{QqSC zkk{jW0ssI8^+`lQRCob=(FL08Di{Xfy1UZ`N?NFe3&}*s-Dm&nxuJ7}{?Fum@w_-W zkbI$7DwisSDug4I%jF^@m|Cgc(5aUTO@BbG3<4>%8}&|Cr_<|$7Bp!C1Tq+odgJlr zJJZ?;%`(YMvybKr3!}+|5VWKf(~e|M)B2iLSyNfhDC6_RVzb>^^Escbjn;R6h*>7V zCia{k4oe3Mj42oYtUi%~5zJi9ZC>Jflm?c7G6( zn6afeGbg;_F4Kh4mV6OpPQ;@qjADXF9EFH_=0sK;B}Yn52xf53#}}93L`|+PugBu1 zWfJ>Cw_|=Y$Qs3+K*MBA5J~Sy+! zGM5Qt5V%T87rRm_KNy%)4Sc1LCV!>eJ7bD4k5o}?GaIMRr&Fp?B^_&SVX5dds0RAN z_TuH$#y*^G{?3>9}{eR=0cSxz` z-=g#6mv@x;NHi8teDHxU5syV9^H186sdOfrOC%EcLb?b|?n#ztW`!SH$7RdXI^!|JfFS9XUG2v1 zh}EoWvRrE#(AG?GJ>o)a%vC0qE_dkhc-)ajhV||T9|h*`PQ;Hk^M4}GIRb00ZT;X| zav_!} zCWI^Ngn;m@Xy!l1l^ki;g6upf4_w>wbLd9gjIp~2TDHPcz)P?1Ye#^30WSE zG~2L-@Ew9KpF(|=e+a>n6`_i2hy5UhL(dPM1-R2feb3gl5k%905a$0t&=W5d<3CFt zm?{`7DPrxgcwWKOAFrPMkinhK`-C9Tr-bLok3L$2!3>380e>N?B!pNidQL;w_w-DG z{(f}o83N(N2I9gqA4X_liK2cy_tXy^LKICPQg9C9XY;y1;c$`=5V#%$LV%2pk3+e? zVfh2$#34NA$LRR{@sT-4J_BKpi%A^9`zi8QDm&g8VUjomthdm@Lm6b|$@tbUudc6e zNUpE1uA*eM;D3)QxifMc-EOU~=cid;--=9^0jm7{FcLoW)@w%VBFk+Uj03p#zC&qK z<}Ur-@PzDH_yVPal)Mac%*=K;xn4gh%=w$?XO@I7s#I^JQVmE7PZ&agQNVgf5CuV! zBmpAjNPFS&hsu&De|Y)wA0bjHnGo`vxPATP@ncMsI)9=fVnTuuA<(l=#V17oO$ddi$yH#;LYObS__!io{;MKF$hIvv7{_p3oe*%n zg$mIH&-WGSH%MSGWD9luY4t1$6q*qR&+84#u>;;nVPY9p45Ltyn2zVuguuDl{61%d z4TP47_kR#d(oJZ|YI~tC3ct~z00GBpYHS3&y-DPNh-isDhX{b^89}h0P}^SOE60ew zJpiI)?jh(1h|bU9jGzt^?qDz{+#O;RDIE@oP!WbFi296>dz(ZTh&J_`PD1)PaWOEQ zpNugWY!e!-2^F+_}V7JtF*C%Txh2+=-Bu>F7#4|;GB=@$gIiUk4fF zR(}k_K$Ja4`YR654Ohq-iQ@%Az&0f3>R44nq|({sMI+B(n?0p`pdn^Jd^^6J=UJVx z4PW~DFTnc3%!1J_nWfp6*T?5GiZlKgAhp)IGQ=9e3Vk{oCI?~CH6kFarDD48%oPo; zsRd9pIcClde{=5L-&H}79NDP))vC%6s+-J|FZnAW&T*-X`glF(r9@X00000NkvXX Hu0mjfx&|Xa diff --git a/TMessagesProj/src/main/assets/emoji/0_1521.png b/TMessagesProj/src/main/assets/emoji/0_1521.png index 89af54b5c7f5df8e85aeb0dba2e68d166fd415c2..a43c873797bda576def66a1fea2c5f9246ee2075 100644 GIT binary patch delta 1776 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 VKzzFd`HBDl002ovPDHLkV1ktDD delta 2961 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1524.png b/TMessagesProj/src/main/assets/emoji/0_1524.png index e420c0adee5b8737af589f5d0a5130b136093e82..101bab49e52cc674d44ebfea61d71ef8085c44ea 100644 GIT binary patch delta 1394 zcmV-&1&#Xr6od8G8(FNSfXxHoorRHd0Ufc zOr&m9tan>6J506Yd;{kf?uL;R3Ck~uZeMXN-a8=%}1u$n{8ILeqFeJTX|GH z6@kHcP&tKpa;`QGr=O zoqK5-hQJGYwpvbAGCNmbfRs^>uxf93WXSev%=w13$q_GLAu?A^aEw}XiED#~ZHShB zeSf)yW4MB0yoY4KjAylgV6%K(!Gv2!CJ$vnD>oeqe^oqRIUkE(Mk0s9E04)XQDvf^ zm2t-IdXbxYU{d1FwsDxO8HmX;T$(3JfFnO}E>wV7sMid5M8Dv>#nIVR5Z6|SP1IvXWv5XLA zTI~P7?kINC%|-h>Gv9?hy3ngRN5`^+|4mxSrBYH%;7($tSC~$xh3!g`SC9jLdKjg! z$+?kK!GHBawLmw*Ye?ILz%zz^I38;SwVmJ~+T$>oQ-j9$LqEqZ#EQNz4u^*0Mu_V+ z*tfAY@dGi`w4oS08AF9tNHok~J`6RCR6lT|Y_ZqjcrI<^XoTT-D0+_AU?n8co8LF* zp2E9A&O35jn1(jo{#X@a13LGl?cqh@i7S9;TRLw5Ji!hFej#HgfMj7 zG4zeVG)-n=GMSi$Gqea%T_-TiM@28+}b4!!iU>DN0yK*^mJNxm20<+AG&Q2&< zcrYkuX7v17rhI2t*_)9=cC%k9XK2dh!KDo(W!trGJUf`4m8Uf{Bm_$i{vqBnaX$CW2nHrgScj|9Z;tMMug4i>(L|PQ;oDEdhYCVWL_){a?yHD6{)gyhQGbPL zyyIA35;PICu(b&EIWs&Ra;)+y*Yy+OuD}oFyOAWUgszzWhoz`W> zXHGgT$Os^)Dis0%iYJ96$IB}v0Dss_=HPcD1B@{u(X}m`G}3I zy}cR{`^4rf)(U94Z)_8&Zztd|}i51w|hc5wGtTIV40XQ!uU z`KQ(CV#S=bowKu@wdWPrOZfWh*Xz%#wf_eG2A=cfKD`9sWB>pF07*qoM6N<$f@>$M A5C8xG delta 2676 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 delta 2555 zcmV${m6GEy-pC4yN%=C+f3Qhz!MJ#%?kK}J0}?Zclz zG%!6kHZLL_k|7}P!k@W}an+!F5k-F!L3?>(Oz*~`cV9}(q>zS4H-}(HeN#ILJ91!J zSrb8cXAKBy4heWQFnmxsLozB%K|b!lo$th<+`OO?HejA4BkR7KUH||SU7ceN2pn3N z#*J=>Xi`8kFMlo|7hDVt96@26YggN*fP5n%wm~wpA|O&cGE_e{``5HXFe&)buShg4 zO*t?-H8TZ5eST+A15uKwf?<<>W}|*xkPHemFE3n0IR##!i(*D~2n39HVVw>QKsq=k z9~~GK6;3uPeg_1Gaa;4ws{G%+JS-)|8X30|694DOntz6GX;4Jut%xfZ4+Uncl4(t< zhi0RZcmzp@h6x5`1_1(BnomYVsF!}8cvU?7f%t z_Wsd5chCsRkp1C@8M*MCbFT;RVi!WlI|c>@I_eeJrQpipj$b>5l>}Bc@`1H{RQ31; zLD}(07!05zlgV$N*CT7igrDPLyu;z(V;tuf zC9ob##FLUnqe*GXqp`H(g%go*ehC8v7k~3}648l_4OpU5qcj;!K52X(wGK=dRMF$7 zKBv<_)WN+t(e&Dr{FFTcVm)g~ZoKX~CuD7bPhYYNb>!@qto2j2RwhjbTlMuCV* zBlJY;bm1~()1O?6X)682l}eXci&q&98;#OYI+>(3nOBAUNR}fV6#P&Q64nA2BY&D+ z?XvWfqoboIG^=TCDr($zhNK)ZNemFCt<1Y*JQE4)?J>Llb7Z%-nAb|6;bQ(6N%4~3 z#07l1b@%9aCzw7y-u-L3m{7DaB$o|j8Ioy}VP!Ht5uqcy5t^MCzv$OX7@lJ|o{`i8 zP|j%0K!0cc0^yR;CSf=x)~3a=@_(tA$V_B1f0p8h{aL?1+ff!E9?XpX_bW`~>$B0B z2So8&+o*JV^YL`FMD+xp{CndR~VT1R(a-)|^ftoHt6Zhuj-S#&#Sk*?&AZ`1tYJ zgEIlY@opa__wJo@Zy)ZK?v)bo(ZtqP0t^TUhtCcV|30gCay6IB?d=K7Ue0MUnQoL? z4y7$&b9!AleY@ALa1 z?^YrKg4gDro1j_xu`op)MRDCgfZ=qSmJEMzBv~WBL_B9%y7dJRV1H~O;{Gc(!nQQQ zN~kG{)ID7?tvVsAK=k#H6nUx9r(0+?()(iB1_lV;W%t~JDfAHZOAQbzM64pgWH9vA z!$UgR1)?{?vMu8;LN>403xaLgy&~_0!Ul2dAxTn<_QsM4j8!NC2&I~&_@N8LW13|L z7576nFhD>={n!)@Gk+me6vdAyo*KY_8i2UlHwl%I&59ynY>H(yU9$V3Wt))YkbC8K ztXIRby~-MjZ&na}h(H1mcPFvmc#11-jV^fdb4)%LT1Lk5G9vzsjSbTD<6)lEDKP~Q z`51t>2dzSpYP@J3EIl=yCqi%o0SF}1(nlNvms6e*27wS3xqn7kSVRkr{(SQL?oh~m znmHiwLE6YM?YKaIVSosP&~HU$46^LcAjz&*eK<>1)eLG`S}JvnpdPDJLu4lh;QGbM_Q!cY;0^a8tdweMwiiu2tq~jBj=qNX%X5` z*12;^xPbTx5r3&zDl#q*;cyrPAi$}{AnG2S>Uhrbe#W8{S*ZjtYtE&3?iFIRs2Z-}jgcsKrJ%4rmS1l=v(ReFAKos|9o;a~u z=c_92z~Lg{5s2!mmc>*U2(jde&dNLUR_n=SV%<|$ktZ6;5oSa*h!U08@&sOvFwb|& zuFPA_mx%TE>z-h7d$wg`lx!Lqnmp4j+KY?LCd5_#epQJ%P-CtM9B z2>h03{eS-<6#aPuzeHTa`hP^+ww@6SR@a@&L<2Sx2BNV%u>i!3I8j}mz)uOH+GQ0Z zpwSmCjaNmhsJLxDHqYN7Du6)8OT;a#qER3eKOk^1B76(0{1M?YA1?q=2}iUhMa28} zi{bt}5f&#ZU&9*Qp21{yHq2(%6{2tm5slUG8GpLCo(hZi1vW%ENSy+G!ovHplIf}Ao^GyW_XS(`lhKzJ69EfDRg?+B=+E9#6zCsg?}9CgCt4v z!{>sm88)vzcqP%}^TFw`h#+^Q(`4{h9F)~`wrz|PpYPdGT zbabFo6&EBqX6Sr|dUSF0yRya(8+!dvNkUc=WEdv+P#}UFoT|SQI-edUf^?YdJmWDw%CbT}>SABFhP{{W@HS%OYk$f2bIuKW;2kj%>Z>SW-_l zB_48LPA)l6Es)7`#_%P3w=!Is8Z~4yW2A3xZH;|yppk<@Yk^OEmRqvn$-uBANPl?F z`qaXjCaRSm0Dk}gEOb&%QvhCa{s<qx%J{^Ry?GLuT~UiHn#y{7E! z>VU=h>zd>4gxcf+&Hw-dTS-JgRCr#U*Vl5}I1~n8kzf&6OGsOmT$4C$0k9W!xwj;{ z@BcJ=NNZ>8y~xbLxgdDMZ-5_11U33&jU7c*6@4UKntyWQc@Lg<;*Mp7Ns&Jc<()`Q zMD?t+U3=bONX^6Xydur=wr$sIZ%t)_plw@ZU_kXwfG6}g&$F`3GAnQM+{z6NpM;ec zS!tSOR^(7tj8D`kK-iF)0a6y0WvN(U9H(g}YF5{^U<5KL3@qVH(^Nc??Y6ETw#{Ri zrZ#q8m47Tvw@=MKPptm+xcz0Osf7(gP1DreK0U7My1&9KrVf&Dvn(w|&0mZ3M1Urs z2!vT~;9^3a8JZ~iP37DyOHzxn2Ng776EHKiN5Yn%r?=38$8+IH| zr`g8bliYWc;{Y#c;d9shyj~pxuv-1}3_PLx?78ZGz5?BI6XC;9SkunIfaheQ~!-1a3!Y66SY{<=a_= z$ktMr5rp|}0S)?LvDocmC9nmq!N-O%qWxjGal?&CNT`iNs$mba5#^i<)1d-Jcz=&U zz?KUHi*>apY`G74$~Y6@C?GKUx)fnB#t0qhF%XF(BWMw0g1GPw6fg!d1UxE)seeMJ z!blWZf|&3qC19x11c3}xAczz(EFgx>REX?CMg|bZa5l=uIZ_1^?l2uD+ZRE?lVE=$ zL~`A!``p&|Rwze|qy10A@wuT%5zde1$6-%=W=!sXDm>X-48&h;!)8+JxNP>stZkZ0 znUx%Ud3pJA^m_OFQXNSU2UXWq2QkB4H{9Xt@M~3leVql|ok@L!ADx};L!6!cN%$Ar W?WRyChWB{@0000Ct9?Q>FF`suJ~lMs!;ZwOUedpI z*T;g%vu!&qFFP?TCL$p>FfJ}CDzAr1rfWjKnpxDRdl?oMEPp5`(7bZVqGipFXL@5! z&ZK@#H!B($8dO6;)17tUwvXh$nBKFE*QtTfrgPb>hO3!={^i8{-M#wOwB4_W@WYdL9rr+uV;U8{#?!=7S$;N5m~@S0Npngw ziC{(9se#(9hlM{deOEwtU`%>lNqQOxEhW=ynV>;mfEG%I z5Ib~?ARomV8r~rx>?S79EiAJqCgU|UyErf+b+-(0w+L#lWrv>vRF)WTvlCyUx)T$W z6cf=K8(P&uc9VuxQx zLNzd5LNir7E=4gYKr}DOe}?%0007=}QchC<4^)@769p@5mJM6utNO*f7kv0 z-v9sq_#nmq|NZ~}|C|4-$p8QT{{GGt|NsC0|I;7;|NsB~|NsC0|NsC0{<8o7xBdVB z|9}7g|Nq3P|NsBz{r~^}|10GG@Yc|u|Nj5~Cc)T3VOsui|NsBt^I4K?gngIf|NL&& z|L>+jumAu5|NsC0|NsC0|NsC0_y1%6|NLA3|I`1m|NsC0|NsB?|NsA}wEtGU-2ZF; ztn2aq@5kn_$>NS+G{?zFj@tg({q6rm|9_zW{;=@>$-l?7|MP|Z{{QOimw__?00*o| zL_t(|0gTrJbff7S!14d{=2N~*)3LEu7Grz8V-~|j+x2d-wr$(CZQB~2d&lY&w@vyb z{odPC=`pbs$bUtL36vQluq9A~cf!86GKYWeI>*QrB2fq;_^68VOo>2mM|8BYqIF1CkmU3= zfw%_o?KjNBfm*r zElej7F~zABxAPVtQ=+rsiXVV_rGINZzNJ-y%Dy7nr@pJ!fh~hbLXl(+0LR%`RaLdq zabjjSlU81EsOttpfE&zWGAlA9;sNUI^>IintX)H;NE7{2Hl<(!NnS zxrgTEk6twF(8c+)7v<(Gq1BS5M=i_CKVsR~WsCD?Et|c3NroxDjk9yx`hTpABz*&`t=_%B62b* zPAQsJc<2F>4mfn&v{O$bGkTNdfyGk`3ra`Pfs=BM z8$V*mi1Ekeo_*sB&sS~UZ#QWw>8guS(YD+ zYS03>)P<3gYTHgBoqsXS>CaEB_`hU?^hY^B;Ni+eH3ynCtOic(Nk>bqWD4pcz@x(KkA>>F$qEtx;t*C zjs29>CNXL$x<-Kz4u`R#blY945BmWu@hc*I_aO|yAQA&B8w@i&VXgTDdK=g{IF10u zu?jU~6j(XeMVK}Y5D>x&>(>Y`zLuUCved`j3$P?8V%d;*_dK6(t_Jg#2*zkgATngd{g1uj(&batt|%Hp+ML3aj=7{tOBaBl+cJ1;F!R13c?6{0ql zW!q8U@~IvikYfe@U_)Nx-Bx(b-7rgTEOdn^FJ*Gwh|&HQl6)^9<# zE`m6~!ISyO`>W(`uQ{LrVvYyYc##)lmInxcHMyMsY=h&MJkQkTm9gN}tD(mr1_yGc z!r;4vEq_>mM=v(c1@pP1mqej}Pfz0CMlCSBl2M>eYM$c-1ot0<;^ZJZWU1Ub^NMpZ=&NVih-w} z;buynUPD`d{;Oq^ph<)_!rqgB!Zb1_?DRcMI)_He?_i2#<7)-QHtmQ*4E)TAq{ji@ zC)G9p4X6$h>u9t>b9&ov3474U2jc9Nd4GzV;qfrOf}7Dm(p9T^z>|#POrVO)34%ak z48UUcYG*qKB#*Y6`08#bUJL`cnPRF)(F01=xxYAvO*`#Sl=fjk9%KO94#M)DvvQHHerLz%J30 zVx>;k`+a8xed&k}Y^#XB8IR-HO#KKSSF3H?hYPy5^*e<26)Jc;hjLUHhKP~@2phu? znszbFYg*sz2$dnMGlx=y#28bm2xys27%}<3hDPhI^MpKiMjOIXk;}&;mFT};`w6E0 zc~LJ4cNEO3c&Rg+C;E3JIxkbT0 Z^$9%9cRruy#GwEH002ovPDHLkV1gu=a1@3bOwb93CACWCKaWMg8<#>du~ zD{*sn=Huk&p&vUsI>f@l!gL`qFfcnhI`OwBa&d9Ie-KJYM{;v?ZgF+zp&#V2LHN&J z=cp#ylpy1uA2>HRJUTjdc6QK_80MxR;HMtm+TD9_X4IrYc7Jwv!kbU=w<*ZMx7O3w zyMGVYo*((wdHURu>8mBCka>`XiSyKr&9{E>y*#&=WZjh+`NTZt<>kwb5!;;+``U`* zw?k!Va^T+H+}PN@y}jAi)`*FTgVTzf`W&Khu@1LprNRdcQ)tKqoHL9 zf>sq86BDFr3jg}l^WB~Q_Rr0NJ5>Mx07`UHPE!E>5r4e>=tl%3{Ti+PwY2>UOXcoi z{r;BNd0YP5l*%xUfH0x{B|-hq{>w#NiE8|2lI6ww{CV}Tp1;!Y)c4EbeXG3Rt;7C` z_Q1y>C;$Khzez+vRCr#s(`R!cM-T?!1r}z>E201aA}F3DEXfMzOHSu7n=?5l#c;`g z-@Tl^`hUZW$}d~Y6jlAu(>2Td-wEY^fCNJHLjK+DKVQGz{{1db+rs(#+vnVzBN_p{ zzFE$1zNb;3>Lbu-IA7+4Lg8u-pM9EnoENT^Pft#hm1TI60Se;SVx4+DolZMTr_QoR z6huvMoF$887ML$H8Up2J%X(e5EDN)BCtasGNPpg8-#Qy~Jzai3d7`73Y#?O(0rX3_b$zQe<)Xhl51tOBsHYDSKkjVe| zs1Jg6#EoQjd)>z~(mNhtwVgrSlvYAe7k_s&mXyc|E@9X(M;J;Q2q8x%peWY%?z@I* z+qP+R+v1*vqlkzIZD8%wJfw(8&jS%4|uyAp&$AgAp1mpTZybv(qFmf`M zPww?@JRXe4yFi@44`jnA$~fr~tLW{Xc#_0&k%+hyaOrf=)^)wB>un%TOIWxhB7dTS zRs`ZXgF)xCs0mRLfiK}?AUqL!y#YLf-e~FzBrzGWf%p0B_4Ty^=_|1L!0!V=b}f#X zuyPH>t^=E0^qPu*2Hf;vS@#kW(Dgp=Q~Hy>;`jF_u&h^;xJLGhu*qt;KOIh#aCkBt zPL&TwN%@!|NiA8*L+xm)WV4fzIDhP~7fWo8@LjKkd{8@8DwXfVc1aEp5us?2SrPq8 z>N~+jYdjHwcrWrzM5s-<#HjD*ydV$;`KDqAi0wWQ6F&z49igPS7Zcl@U+mBm9hdO# ziXHJKgrDPILJT{d5tRCXm{Ji;7>FSd;TI4i=wjW=WMLh`N**Zfb%wiMrhfv2yOIZ0 zTq2B^lzSi_VklA(d%aPXVYY{`hG_)%-^EFaVYuJnie;&Yawe1Utig$5nMG!kMnIb$ zkLPYhs2)$EOhK$AR8@7mU}7pHMm|q(Y_Z6w2@Z%&HM3Z#YvfIMRQ2vIhE`j5A0sCK zxbwJEL|noHTXMp?nMfoyIVx8}Yq3NkMlnysmAU5~<1Lr}`-1-qHlqRE^0)Ri00000 LNkvXXu0mjf4*cpD delta 2607 zcmV+~3efe!3%3-IBYy%eP)t-sM{rE!(wNVscH-2I#CyxNYtW*3t%OLFYfR0oap>Hbx|vkd!FR!rXSsq^ z#jat)g<8~~b>X&;;=PyHrhdzrYR{5s+^&Y9dRfAnbmhdKtbd4S#-oJJx^1O^Ua5p* z)24j8omiT4Q+s1hu$_aUk9fR}Yu>Yri)>rcw3Lf>U!{|Kz=c`s&aaMoWhWOBshE9~ zfM>FMQHO3)x_?)@fnKzBP>EedfmuPScv;x2g^6KBZAmg&L_t+MEsHfRoI5miU`=*n zPgFrYq9`h_G=D7CdR!AhcpF!h5?Y*Mdy5`Wgb+M;iyj@wDk3aI(}3;d{H@gVoZEdI)qw4dtyv~X;OJ&On6*Hd{8-!WlDl< zR(M%Mfqz&(cV9||IPpZ|NsB}-2MOmu)q9M<^TW2 z&Hw-ZZh-y%vGkPR@3`vB=GBf%-TsKw?*Hij_+p^{{dn=4$*=SF?uh;6{l@>Z{#Vq@ z?|%!-000L7Nkl>yO)_W5vdXyt<>%Rni+s~+ zmki3fD6%BkHqQHW5nXD@$tJ^Jf!kfR0)MDlAAZ*uc&aK&vB^%n-h9)AZtE}<2H;#4 zULHA%F%8qo%*@=r|C7w^DEvzneMjblFd~pb2-*GPzYrlAQbr*IsZ$V;QB+k`GJpi? zzH?GEUB#-dDdczJ6yFU+CM4#9cTP>E08s)4ePPPR=*`Eq~4H zh0E;4QW;TB@%dK~tF?NgimT;%vnsZJgvsKRt+%UE>tE7AIua@>RTcB?Vk~t&`ANh@ zOTCa)^id>Ti6D$*Bx4m3sT-v{&R?mQ*eCybFpn^lpo;UP*Y{JOQ~pAH9?}^Ii5W84 z=HKtnFI#5A2<1mW1S909XmUMB!GCx%1^{-ZA?m=qGMP;P-^4#5B|j=eCXkOxWUoU` zwqnZ!429GTdH_Pm;!ZoPFh~fkq|d-J7bTuW94)W364J7sFE-m9fur4avzV^~Hr*eN zC&m~(AD-zXtAo&CC=5?>FS-DX(HGp}Qg`=uc1~~!e>L_Uy?cTsyBvfGWq4s%UC%##2$TvV=MMy8gisP+p8x^G(WkKl2!?TXo`%XW?7fxcj1`0yjA8-= zjPvrNzav)}!8_F24a3Jkuv(YUk??V>hxm@~Z(Gi<`lF;`{S7Bi2~%=ANZZcj*X#Pl`YTS_GR^;l{o z9ggbnfk22@b|xgU{;vI(`<^d2Sd0`#-I?O4@1;IOSq$=urBA#^CVzC(t_%&bJ3)m~ z66|}?9Uc3Mj7>Rib%+U1?K26%YL#e&j0q4{_$U*sEyoLf451Kg`lw_^ZAHt2OS9 zj!q$?*oyhvO`y;_5`W+r@}?0rVUQ5D!_xsw3`?#<7`i>~IzHimnDhkcojHQZdY{@L zWQh3j--2MNgDOp?et!;x3=yw_n8t$EA!rLioC{8ZFbOcDL?{6)A#kwCcvkyOI1UKZ zRh^5W|2qh*7yC2awqTefSax_((LBcLC5$(qe42M1KQ4%;ihq{vI#;zWSXNV(!dBFe zPbmN2Va*h;VYo?2_yPzF+GNdve~5u5OW`$UVMQ%Jw!J9NlZQerRT3~<8A&LZ-4XTg zB(T9{JluLl(*{5O*bU7sf8lmJf066UAcDCvbbL zAfDIA{vo_Z$x|hlqZ*+o=W#5GFe6OZb{_n+bwYmy)7RIp!j7=hN_NAtW!+1W_u26=g@n ziv+xQdw+c&%hSdHYrr9Y^1@b(A* RMT7tV002ovPDHLkV1h;A`*HvP diff --git a/TMessagesProj/src/main/assets/emoji/0_1528.png b/TMessagesProj/src/main/assets/emoji/0_1528.png index aaab9679bd0d7501349d9bcd2bbe7bcaf5f1c276..42b76d1bfbaf1fa295b2664c5ee3befd59249d09 100644 GIT binary patch delta 1351 zcmV-N1-Sax71;`qBYy!eP)t-sM{rCmEGtGoKPf0EPEAZEA|O#nNMl%7Q%y}gIyomJ zBPt{#KR!KVT~|LmIU^t-GAt@cMMO9@Haa;t!lH&^NjDl77BDU@OFAs?#i9Jxvw~|@ zqlRnHzNP!)#o4)=dxl2k@U-__u07FsfMwxuIt;(mVbtR(3EoH%DUaCgypl2 z*r9v)(XKKvF>_^Hi+O9}vWnQaq2jZV*0Pn?)70hV=HcGn-{0cw>FMq3>*(d>>E`Cy z*4D+t#Lmpj+1A$2%+1Hd!@<72sivm6wzi_7p_-YQmX?<2x|WiXlIy>lx}}z#ot^H) zprezA?!ljIZ+~%wgM)Q-bzo&?Y-?+DbaZ=rd+x%Xbai!YZ*g*Ra*d6Rc6N4jbaZlW zZ*p;Qa&mHjfPi>-cm}j4`2YX_Wpq+bQve=XLK0Zp|Np#s=Klnc|Ns5|;||NZ~||NmG2|HBI^`IgQ9FT^`~M$j8v!T+o3|9}6k{*mUq|NsC0|NsC0vj5ug z|Lfn!u>ZiE|NsA=sn_oRlY1p!=HRk-Vwlwc00VSML_t(|0b-yv0B}xM2?)bL6h(o$ zTax-ThP%W57l!U&?*BX0j3?g=6E9e{^Ud`vBw+f%UvS;fk1#?MyGi<)XJMG5<#ri3VshF$N=?bglM^~wGi+%#7<5} zm}1gs(6s{4O}j@CB~@DUVbHo+CkBex`&+dmZGSs7^})xU_v2Qox>oXJj-nB=^Lj1U z>&q3pU#@QVxs*~pp0^e1E^hZXC3RulKnw$5c!)BCTi=yb2#qLcVtO>~Gv4jFrasMG#>qZu-bag0bHuicJ8;1H1n zA%6)Y^Gv&vjxk!MJ`6Ts7;B&UW0P{^Uf@z=^EgoM#o!7aa$-b6CW`(NTe7(v+WaN z-hRS?boyA25QL%td{eeQz_?5&ecBtOfaJqZF@odJGQR&a%2EEm*ZCj_U$ zGz8q#=|r7DFe8zr5RN@Ra|w!9&ySl0*@{2Hj6i<>2@#Ud zVwVE#>nA#rScfgk`28R&GgmvD-820m&-ovtJ|o;beSO>s8~`(g+Z^G&oV5S|002ov JPDHLkV1jlqvBv-a delta 2768 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 W7HwUNud`zS0000*Aixw`|eA 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 Z2^4_+Uq=>-KU4q!002ovPDHLkV1nwkaG3xA delta 691 zcmV;k0!;m~2FnGIB!3}LOjJcja7<-6BXB_{d`T>FLMU=VD4k|Lm0mf3OfHL6G<8EL ziZ(QH00006bW%=J0RAtZY0h6?mQerz0#ivuK~#9!?Uvz^+b{@(YXL^+{U5jn6tFBO zR@z_f+d0_;Uydt3;^0EPnywH#{`L&il>+r4$fh zky;6tW00f1i?vo1>5xSNsD%)R4n%{8GXQ;n?g(zEwuYa2i_0rgxz|w|y(iEsfF!t* z;5Oc#OA_|?`ZP%aCwzwRyGaV7C-^82bi=z8ZQNx9O}9w=A}%3B5tl&0`|HoLi!o3X zj{0>3j3!pFUb&d@rby*V~I!?kO+82Xk+f{ zaPfrbO|x&6+$|wkB-i_h_~3#^1mC;hK+p|>=MzX5O>*N1DS@CnM6II>nOz8`i`{i@ z%n}Ih0ao@+B48S1IQool=RgcDM5J6?@Q7&g)ZGsjJ>4+c@Ehz-qs*Evl4fPNQbi8|`Z+G>I%!RQn%lcs1v) zUbD68YJa{HwVE$0P;Ep6B*L#MYnwHWXr}GuiH3ixhis(d8QXe|FuU#WA*GAh9J2~E69K9z0P2-SOMnw#1{lN?yC_mMmu@War7yzNL#QENTHv@sD4t=x zQ==sl=mdRSv9@npi-=LqFu@AI(`>iebc{tCvn=#%m9VOUrlLXwI-~$d!uRrP^P~S; ZzX3kAJ(9>M!ASrB002ovPDHLkV1lC#FdhH^ diff --git a/TMessagesProj/src/main/assets/emoji/0_1530.png b/TMessagesProj/src/main/assets/emoji/0_1530.png index 1cde415d24dead9003a2363f6b6deb091327a0b6..86a323260ca2074ddaa0a453bd6b2d85e327314b 100644 GIT binary patch delta 1249 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 M07*qoM6N<$f-u->FaQ7m diff --git a/TMessagesProj/src/main/assets/emoji/0_1532.png b/TMessagesProj/src/main/assets/emoji/0_1532.png index 7bdaf02c745f1a1a2f2225954f22b5b16d4b92b2..2482208855323c50346aeff78ea2c00da534a1bc 100644 GIT binary patch delta 1108 zcmV-a1grbt73c_%BYyzBP)t-sM{rD0JTyKqD>*DDDj^<0Jv%ovG)XlsTUlB-FD)}D zBxG1tbaQjg%*>OLk~A+XH7_hYEhj!LCpRxEc6N4ncXmleMRs;}KR7mYbaX>DGIert zb8~ah&dzviUOqiNkBNxn;^NK9%64{k>F4Jm7!zh=VsdhF#ec%Wo0^*F=H`x#jd^)_ zl$4Z&gM&XlJ)obSSw=h9)z#tN-yRtksHLU5xVJ$sCsj^OXjMkCudeRw>~L^!k$h*Y zl5R;vvK|q{{00{{ru?tBOZ&J$TGav{jKVd+F&+J{ISZlg?HK5 zNyq*JnuH|)0Dl89NklAl0gZ|Oes{*N_Pr!z-$ zGZ%JieknGJfZDlv<$Z=znN3gx*^dZ5l##Fr)|%1=2t$ zoqC&`+|zOWM6scIAVqBY=}r)<=Tb!Ay-_mhIt;!i`@9El)&$W3kj{z1(eCZFEWp;! zuj6D{OMm$7FuguKNC@p``k8i)J*3?y76PH_?vuP?zt5 z1gEsAfxxuaThUCE3lbWk&2V+lfTrA%nG#J*V1Fv1GZGkQyd^dzDib2y1EKaXq5(yW z0}=;UuoZ-!fw(%3b4B7ziC{A{AXZ3V#@mprfDmiOhLU(U+(tmg5s6()=thW8De)hN z8yEoGhB|rl301`iLOdWKI1EGbxFJM{U_K!{DvNp;YWx-DmJ1Tbf%wM$3zB1C{xEzX z#D9*(Mv1=ul@GQNuEJBIdjY?vogqs2u#s(^m-*Lfm6s(D0Tw0@rqVcw@-i#)C@M3U zb{e6c;L-9qtS!oXzb}g-1HuxCAd)OU z9)T$G)!JZ+X#OEiIS}P)4S)oZ+==98#DDvG^#dY9;$-Z8NUTomn>a}lH4w_SND{d! zlqjo{43nH#u&JU1}@ a6ZjhiV}$F5V}Eo20000D delta 2777 zcmV;~3MTdF2;dcvBYy%(P)t-sM{rDcR6jK>IC*1CZBj^0H!MFmHE>Qlj%ikJQAEp| zaknZcdsI73CLVrPK6_9&cw$U;UrKyZIe}|b$c0bW1lBLU_`kbFzM4et%Lr+qHstT1I$dQ9Cg$ zuX$TrK{KdwSG0UtYC$J_Q93CjA=}J@LNzeansBmwUf8IBuX|m}vTBzZ7k^7PRwEl| z3kC){au7Us7e{}0U`s7XYO8ZqvVB&4Q8@@XaExF+X&f2Xq(~ZN8XKXefu6SD6p>}LpQK@rRr!Ohaoom5_Si`GcV+8?X0RXCW zSrc2FsXxpLGFOnt=!f24}2`c3+f$XQO^x!=qlL4-N!Dewl1bnsZYKJaq&{grbmlRXZ-Q z5fN=eC?RyWer8bKAt6OED57~%U^pI(3J2!HotO*@sdQM2SURbfe!ziOyAu;;2LjO> z8_pMB!Jmlk#e(kQcNoqQAa@NH#O`g zCa<1@Jy2$AfQ~B;1j1uW3vjl0H6-!qrO>=_c5fB*mhY;;miQvgjV z{0IL14Fnet{y;*Lq04W^{{A4yVXz|cGw?fETz~x%F+^bss3!j_uRT;v!=)3uJFD3ubZ^ge$@TA{ruq0^~Z+Rb>(-LrTFfM z=-U<+{v-eZ2ii$QK~#8NmDhz=8`&NQ@CixCBq1s81a~jRX$vh-N?mqeZM(bm-8U0= zcYnd%-JQCw|7GuYLxBM@bl;bgGnaF@pZmLa=1vaSp>P<&mX;Qwh>INwp7iL}ty_54m(isl_f4ckA`~F|j0NkV>$wx2sk)tCMS!s~WwkotD5$XY69x7$Rh1`+rO+ zPT`;3S9Oo+CnqOY+qzZv=@(Ku)5mpMIv4TE(+=a?`L1#HRO^d8vtxi2K#D zY5M$16{%8wmTp>pO`vo=nAsUI94bdahCamOC^96Mp3hEF`>FkgI4WmDF8G-BV##b&WsCKCqY!{$)(js-ZPCr|lbs;8^J+uSZ z4Zr;SX(@6^|NNJRdJdhyy=fhJZ(W&t^@Y!W_l|!viXzniJT&y1=abF$$+bSD%jD7! zPpu;(??>kEz2@^*-o0Dl-+$bj3=aYU86T7`-O$jwE|V2_Cu^9Y0|LM4-6c?uCWZ80W4+QJ4kuRbo*W zI(yX+5P)dFcz;maCH%lT2t^YY6Fk(qzecMC0?F5|*zOm@<9`+ry}d~2>1jZlY_6)L z2$k0q*$Eg_0fcrZFJA(|x=J{ms@p6epb9h|1rg|Zqn3eRg=K)0kz=v^z7vZ@oacXJ z340`Z0=VgSZhZWB9`fQgRz zBl2-tB7T>UN&^wzbZ)*++4l`XBbDT22x$q{Ig_7Y(Fk}*{Ma7RCaa?oVLn8JVnQHH z5uqIVe@EJYIJrX@>+nN_5{NwS?7tznc@n86Ad!!S{a-{l>j-fU3p4zyg>b@*ZGnhc zAb(=MNl1YR=ZJtn*CT`wV*ueZgmUQ!(GJ04$c_*(Xd#G*=sT8(F-l))B;hziCe>&p zIot!phYw0a9u^YOr#y}bNryd%&%-i8;VCtq;844O=rhD%+|a(+WkWu6(WJbns6P#6 z5U`7i*aE7a8vXX|+gJ{U$HFyOL@RKk*?(;Ir~tzYM&TMuy(0x>Wo6sZ94s|$d%LU* zx@dBm-Ouh%6Tkp=e}6x_U|)!Wk=wzsIL3+%4u)m{jUXr*9PDSq-(j5S{vu0JTGXz9 zmj^@n!N?Q@L-TD~P#^#%fVoFUPork^C=@hWzQ4k4G&%Y`C=Hsy&4{{tiMD7+Sq8p-a-nZVQT2wZ9-ST;88(AQJkG-DzsB6 fK6kGRJKXg@4fJ23#T%wZ00000NkvXXu0mjfw#ptU diff --git a/TMessagesProj/src/main/assets/emoji/0_1533.png b/TMessagesProj/src/main/assets/emoji/0_1533.png index d1b877b1c73c737a30b8bf3dd2bda3beb3f0c980..575fe5f5ae0e2d9be02992481dab202366752917 100644 GIT binary patch delta 1522 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 Ef>JxO-v9sr delta 2513 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1537.png b/TMessagesProj/src/main/assets/emoji/0_1537.png index dcc4c0153daebdfb63e84e36ae3d143707c8fec0..b847498a46cd80cec61c26ed37665ccc5b76d2f8 100644 GIT binary patch delta 1142 zcmV-+1d0386^aRvBYyzcP)t-sM{rC#DIt7LG=5V%fKfM6JTY80A!|h}V?Qf(OE!N- zG<{1kfKoO?E+~CLD_21_Q8OllQZsNX8HZ6Zf>Sq$R5EB%NOwUgRW&C@GAXSd9!D=E z&MquPH7sFIMUNa8V+#hCAt9C_7k3;Jx*{T!T{lHACU!w6qknx{OgAm7hGu_NJhu`O zgl>Go55SSVA{{O)isdQp6k_Y)3Dx5D=IQ3#1MWnsio;3<-J(1&(D&(jFZy zAR65uAh9?rbO!@w1OenVH0mZL#Hy5`aZH~q9fNx^N&o-=C3I3wQvm+3?ZEy03Ku{t zchM(Lbf=g3{(s-`{F%_-{(<;bzF@?#@8H8e9ma7000TTpL_t(|+O5~wlA_wG?!{I<$#TO2O%6~zO1)-Kbs;P`2#pk88A1^s<+WD`JXJVC_)hBgEPK!8 z_fT-Ss-VF~5M){4c|jp-9E2g$6dD16bD^@)KB(-1G20*C-l|!8n%%yF@iby49-;`0V+EA}a9hnZ=EHc5nx=v} zAjf?*YoZ6l+KE-PT0$M2uxX-4)}1&_v`m_6e}6oJ5G}VL-mzBk_?f`EYQG0zmAq^| z9}U(6u`%5)o2aU)s97d26x*!Fs->8om#e7F>O!O%>sJ}ZS3oo%G^@?_s=^{yY;$^ zbiEHSAs2~e&X{mGl=2N9SCkwFLJa3oG z9#7`J?-N)$@*y`P4#AKlUm|lLZX}qRh~uwBUFTmPK9};k_7}{=*q3rbZj`SbNj`Cz z%P@UHh~E+IRATPN!i6Tfm+D964fJ!&(Tve(q;yy0GW}bA1LV!Z07*qo IM6N<$f?xCUzW@LL delta 2764 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 R)eHat002ovPDHLkV1hRcbA$i@ diff --git a/TMessagesProj/src/main/assets/emoji/0_1539.png b/TMessagesProj/src/main/assets/emoji/0_1539.png index 566cf316800c41fa287105001f1b84dd52d9cadc..184cf83c295ae39ba07967e9f581391a85819c07 100644 GIT binary patch delta 3133 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 IM6N<$f<~qeP5=M^ diff --git a/TMessagesProj/src/main/assets/emoji/0_1540.png b/TMessagesProj/src/main/assets/emoji/0_1540.png index 46b34e63933cd74576cd2e90e07e8b35babd910a..c65ca4bd1443446b06ca76e95cb506144123bc07 100644 GIT binary patch delta 2982 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 Ef@Piof&c&j delta 2724 zcmV;V3S0HB7_1eLB!3)GOjJcja7<7@J$h3-F)b`sLpU@hA&PHhU`j?!JU2EhGe0gY zcVJ9_YE<&Zp?y?5I4UzfE+iId@`BvMDD< zH7<&EUh2l9LpnA?C?t1bOFS?vI4mefFe=NQenBuS?ZBLPVt-75PdnYNiYp}}^2eiw zUPgCeOg}O$cve7tQ#Q_tu#6}oAbnXu>bsU<3k3)| zac2qy2RLthQ910sntV|@;<1lQLqVAr7JE=RL_Iue92gNkbviUM8&HZtG%ssfP{@^Y z5kq?-L~M*8AAe&Q656bf-ll$3S!HVk02n@Sd>|j2A|rwy8X{bg5nG<1gLjCAi497Q zlXF;8J~sE!u1hy9PdYL9)w4b?CNu3kaSL3<6l1jAls~5fHNy68+-ATYo+9&xjYU`2gV zIr7Y@;;e$@c2bZFwDO87Yjswa7003fi zQchC<5k&qB{sRUVC?9D4{p~tW^Nv>j{xrA3pw#{1{rZ+dzinTuS(&WzcM_@K^R3J& z#mU*e{jb=BJIvpY`t|AJ_G{58{`s@&V@&dDe1HDaul=uu9^?AQ$xfHo=F^9?lW1K$ z7{UMm2i-|TK~#8Njo0T}+gKI`a2a=l!KOMCn}F#gKe5t#>~5bP#p%>LAI1~;?c@5>^p~*<`NeLo6T;=@<>hhX zE+%QngA#-;Ww8<}ZXghVL(ze5cO{c}$aMz-ZY~#ix7%IECI}VoJU%)yFV6+Ls~iSV z5HN3;DXrG&G*MbqN*+#wTZ=nzQmfUPw10eevxKP!hC?CER_l7}mUP?QEMg&eS6!r* zPcAu@NWPYgJ5Jc*RDK!yavVB782Ym2U?l`~d~~kE;Q-0xYGF=moqf%29|?s*U+fvm zp%xxn7cDNw=cR!qhr_&NUUIcCx~Nr^OdsSP9EU<{LnG6Nidq&z(j55w>91`wHGg3I zYx`3mk1=(!L|kn&9-uS zw-=7UczyI{4+(pFAMc$Jk8R7# zySvL)ID2N@A4srS2X(ste$Gio6ot?!fF`QJ!#bt%Fbj>;06C$oShFs=Di-vbv68@SOQa3 zr6Gv=pAZ4@0db>^Ab*JN^Ma%u$Eh+Pyz>z6tjBUqra*tfuudhMQ1y7w;PY91J_8~u zq#C0B+>#f_&?WN`0fyH*yJ*=dEk}(Bv2JKWS^)$YK)`(55LbbEen2as3AN<EX5 z*DQ;%#0X3#r!wn_R=Aw_l+X?8z<2! z)u|QO(ZqJ^fJugkYP&sVASfM!R8`eqIU@>+%L;fvq<>{j`TbL?nLR5J|J2C^ASBss z8@LSV)zRE&hPm2IH&a6|zKSXa(Js!%XkukzVx=d$D>66X2LeU#9~B3-X&IA4Lw57! z>XKZ$*_@3Cp`g3!jF6QJu^17VoAdY7+?p7jivYn$j@>wHj8VNM^Z-QN9DxN5ziJHPm<0LeLv4tigJ!wsm(b0)SVmMlz1H_O$UPY--xlfb3`s8xLyZA=b_{R=M{Y}DzE-qu~c0?3%*od4M!Kv|&A|j!SC?br;+?2%F;h6sx zFMS0le-kfZMzXOSMA*MaGzoK7V%;RnNH&(1VKh#rB47*-BTa&|71&R7iQ>j$WW;FC z#((m^L!@=V7+k8s8k^uL^sgX_n~^-gqRX}`X2yzj0!sUTFt zwN0i<^iyFX!=&lq*&Vh!(T6DySS;o+Cmrjb e5(i2m2Jk=Jk_bvLFUNKO0000* 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Π=I(`;{0hyQ(j$ln&r;G3^DVDZF z9fa^wcjVI%w{sD5o+A>7HmC#A(9ky0fkk>u5f{em`)i4_Jb3w1SMsUkl2rajWZSps`rfk_0N@ zu>>O<$~%hV_#)R_W>|P96**gkqr&8;<#!%5Vhlw z+G1(_p@=YeDA=``*rJ48r+&KgZ!&jYqxm z%pGXX$AA6vmq+*SKYH}bvya!H3}`4jT8kfN^A1Uii+{Z!#nR^b{=*0#%9u4>Q1lXy z&{L!UA&4B*Bi7Nhd=GS=i$sJsg8`8e#9o9QjaygE5CS5xTuaB`Dt~gANWzaHK8ZoZo%XySKfmC4((`;J zEaa<)?Bz#0Clml!)^7Yr5)hL3T0r)Rg^)ykSy@-os%TSVS^gv;VDeK02qh%3@#C{s zKan8`%3Z)MFjZCMCk3x=R8%Porh33mMrRS|+CRMg>htH%UlDoxJ=Y(l5@m{M!UP0u z7=MLh3S~6Mr>vr)aUQ~BiCQgc zS&jsytJUg70j|VqflpaE5UXg3fJGvasDFipBqYL`9yE)nt5Bvefhcdxrze7dkfeJe z9t6?iIfKYokOUuys(k)@ghT?bjxrJaV5CrT zhH{dHP=1X#6&?xAs!8ifJ5Se))9-)%_4k`e;{AW$!_N8bPMii`ll{oAo8p=@v0)(% z@z)nGUKA|_0X;prn+^}IHyFeO;h#lrQ)!5$!iI*6o2PeYzi~EmJ#<30COMQS$Zsd? zY5#eE9yoh;>GW>jW(w|qEH!mEhvb;M{8Ihc6yW~{4Emf&b;H#F0000H)Z9T;{zEGI8UtaezrDkyzXIYcigfPZ01gIGWaI&rReT6SPc zg-JDfPd18SMoLj(JvKFWVN82aH>Ph?CmtHJeO(+taePrZuzFjnb60>>JAqR>WIP~5 zJ33|u0dx=y4?J%YN`@OyiYg-@d{H`#ARlI0RUc}qsVF6A4F_cq2@_nMn<682Og3sn zEt?Gsj$=j`P=AD?ZdGj;5E?ybO-fU|iDgqhHI-^jLN6zYTtJ;~QBF85jCf$Cfnb4F zJfV77fM`+$LVg2Lkp^e1KRGv!WJz`i0|s8ATtzrFE-W!7B9eY)BOe|DSDAiNHJ%O( z#FA>X5)vyO7`%jGZ9*m-6A`q3UpX@}VhRMp7Z-sE1%IoFXQGjKA9S|_Nr;OJ2&a~O z-XS3iaJHxq4wMWEdP^>sgKSeqJzX>!$|@QYerszBuoGR09SNUPE!CB z{%$Bm{eK1x{$n&gA6gep{r;o=&+sMC!nv4~jI?{=$yYV3{qw4;@Z!gie8Tbl%ed*yx~FQV)UW;i{r7j)m)h;`+w}J9_K-~MxJ&>52TVysK~#8Njn@Tx z+gKI`U|Y5$ImS5XAj34wO_QdKGi?WUS7>Ht2!AtknP-0Lo-2D2liYss^GNZvUY&a+ zOO~i0gtlp6VWCMY78M0oNSdpgB?>}RHp+#!ndmF=0zuI{LUSBVkMzsR3EHu@PL#z( z=VDud@CVJJm|3=0A}n-`1$~PUpU)o*PAPMR`nhBnWq&`JOuiDXqsf;_rFaDyO}WI- z{(sl6N6CGJB#(}&g#=t5^!ww0prleAxqX{B+Gkj_c~wl9$?sOvNi_Q18i)!Ls;ShQ zv#;O3P*2XjuAZf)x^j-`&Hc+asnyHqyB@U#JAA;`qTSj0pi8-_V)Yjx zkBM9Xvg0^-6Y>DzxsR6=l)o=8zutcT`WPyKB941LU7Z^EeaAYAy)dQjn*DAKS&_q`2!2#gR1oUZ4DSt%-$|fRyMWt0$)=!g(0gdLJJ>m5h;Pl zWQ8XP=tk2mn6^Ts0wNO|PiUaFZoFU~4Pue@xqBrWw|l9DmtRdM{({{}vxE%^H4mW4 z)A`3$Sx2>Z!QwwaxU+fwD;&>0isp2UI8T6Ka>bE-!AxK(boR#a42 zAr*+g2jD#v!c^;QE ziIHwSI6IJ6G>#hsU<~pj_+|jN)Se#kklTm9muWyS9CGKnShWDmn1%H8GkF(KSP-4UfBd~GI4AHv4sd( zZD8%}CkREg5HVig2!zqv_ygjmqPdum1b9Nz7}#0^0v9GMtN#*~f+~2T7VrNlV!l2@ zOypPb0TH4>BTo?JiI>7eW0t5DCPonPNHav6RxPdxys#HQNaR0BxDYX1O!WVdP>+}p zK}diwm47DGKm@F{nzDpzj_Aw~L=iCv#M)Xw{v%=-SF@;^xqRXSPsn~mz}{EsVO++d z<-8`BH~>OE2-l6Zt%EXz>h{@k+*kVSjyi-Y?o<(5ELv;;}`)Kll(AB3cZT z!BD3J0y{Opy)gI2?_2aaVN1N#>Gb)0l>&m&dvS4U=;I$ZPrVo3cGWfRd<&1_$W%IE z_3fCnq=5GsP7MsxgjV&K;S^)qu4lN29^}#g(z@(wanK+DjG=`m_|?{{d5k&XLEhPt zT}OpE^_3)umOAJ}A77$YUuVGd%Bun^8=TI%R(_~b4^_ZW$>1ufR7GSF)BYTCf=xnC?F$AG%O+<87GU! z-KvH)A|7eL>|3$D({tICMQPd{8-J5)A9YpM6p~CL$o!pL!E_xq?D8d{H^% zvW@G$nrtK-W(NXY8x(y@IDJw&XaxWqG+-Hhzg1+1fkHJXKV);4sdUKj>bQ~}f4Szk zlvh?(M?pc8BYzg)-l>D%se`mFDq%-CZ~ z8#H1~H!emqD?u(NE+r!Q)wAoomm!D7m~m2sSwJNqAAgSv3GKj~Qav@1XiUZ#87&LGtB3v3s#iKJ@yMhulg?K`H$gl+g$f4z<;bXmV}DgVO-V_g zdRa9xGHwR}r49}I-Mo4S130GP*f1|SHaBKYLi)y=OR3zz*h-f25eIGq{r;Q3>;6^8cHLaN z+}-~D{MP>c^z$&SeCE%uXj62%*3v)oNr>j)w=expXZ-%HX`JBV_jS5wC&_&qRh(9tK_8q{^FkOOaK4}$w@>(RCr#6*9BV}*%}A%iB5zPB!nbb z(SM*)pi7~&-5S01ZSU51E9-Kt9gDjQ?(QyiU*CH_*L}~FHWR`u|A&VeX2Os6yyu*m z2P`Qvi9{m9vE<-zCw`AV+Kf+7G?__)G~-e)%B2kHUkZ8p-iK`VW#HTFOT8T^V;vop z;Pa-Wn3nez7Z)cRl1k6m*jRsmzlWyjN`DEjApNA+Di(M2_U_wPT)Z!jOJsONa;v8w z6b~)7DtL*E-VU*IPTUXmqCs=UtSYtAZn<1+^?0mSxwwU|rLxK~4>dF63_#5&8Qfc9 z%HbfX038Sf+~QIJUoSoVR%g&?T(rFEM?|HJLs$uta-^oF5)?u56D=O=+;aUC<9|0U zPLKC{JpCo{HBm~FR+Uul= ze13)!#Xl)ExQm~8*T-Yi>)!ftH-BF*^5mkqiJ|!}l()>#j9a9a#Czc;9jOlZilsV8 zH(xLQE*H^3rVCoZ40R3p7epd`d}U-BNJlIdpsCcDgEDA&39-l-8tP(#LST$xkzB0h z+zk+~I>tO>9j^#F591@yx|HnQ^C;8 zn>WEww^(eo>Ny0aph<$FNP^UtV7!C}Hh{>z9En7P({ectKV~M}*9Sfk--ei_m z8uWU3YA_gFmdo{eLuE_irdGI7K;Vx+B0Y2SZqP0i3hV!QGgB(z%s$?9y6wBLClHwZ zy6tomzoEL5f9}5DABp(ypMN{|k8520E9K~>OBs9hQmGsr{q8u5uLlPPQe2y0Y;L-IooP1Z<&SnE zavPY5vo$%B0Ad0HE--9EGaL>FmDZUu=tDw^ZQy8?!$ByL1RVb8;q)7( z8WRd4(vL7~L$z5z7)}B)=<^K@rgRRRRKTSw*$&N&lwtn@V1J9afR*{#hAKcHH77f5 zV1Quj95{MR2W8~#(99yW_WIL5{)_U*lSl0WR7Rl+zY0~iXc57NB{HF*Iy_NOH#3nd zc>C(g&ySz{^2?LQzpkvFL1i?nrByLUrL^g2r_Bb4&DJ?QkXC|ept8&a0g8rBXs@sS z{3{4x0MU*^8Grt=@1gr8*s-I-$N&Kmd6*Qsq1j$ULoRma0hhQg!O8*F5fn7PWMH_H z4NH6k7l_1pRh?&;i!gg1h{umsRv%Ms zo+9E5+Ic_L=}^H(E9y-DB~3dwLpsyiTv>9idQM&5EzkYyjXb@ZiA;w~9|?Y@gU2zo*A* zHd`9^o_}zf&EB59h!6-gNsAna)s;t2Q8)yIC7gYI-o~~Q=7l~d5NxE{q@9*|`{Cc- z=i%)=5{yGw%nLw#b^s9;Aox-^VH5^uTI+&BBS1%LdSed3-B5kJ^N_Y#Vg=?IcUPizHA5TpX* z&E1KKFHRxi=G4U0H7=nb2qMf9M3^AJ;>oEmfMBb*Fg0QPfz$S5sdIB-LW85%NBH^N z^Q(OQyz~0cKWk61#OwdPhO_q(=)%v#BwN3%iU>a^s1hFHKO-X}(Sz(jKAf>>a#WBc zMG;#B1*aMw;$Ti~^xvo6osC3q$+*pgChD|6;EF6bui~o$zi{i;!S`o3z=|7r8ciNc h;<#3!QAjwz{{c+|QV343;pYGV002ovPDHLkV1jEZDWd=Y delta 2189 zcmV;82y*x06_^o_BYy#0P)t-sM{rDeVoi8oNN`CsPdYO@DJ^+XJW@V4L^3Z}K{!G) zEj%eCM>jA-Gc1L0TRkfzdrUKRP&$85HDU?`wJ9h$C?bPVGkIA;gj+&+VoZHeH$E*V zJ1iwZFe!geGULYRhhXHrR&Y)y=K zVH_3|rGQ_h4-Ol1w+BCYr@00yf`L_t(|UX9lWSKC+` z24ES>mgI`TWn3U&6HG~HnapNq*q~nAd++p4lK+3sexF4^HkO(91f!tbN3ZU^B1gnj z7^f>9kAJ(IB=IJc)#q}#d{%~-8(aKXk2^q33AF25uXohzeT&=X3C`o=!tbn13f6DE z{O`of1*=0Sl?o+@AP5H&7bD%AnpYvR%yAp$JzS;Xa43|Z0vJQDk?`?whU3BDIYsfB z36xt96ht6kZ5!t;uJBDoP&f`s2!h*eN}07Gwttm5j56FNjk+RLtE?ztnu3EgB?OsM zWSB2m;do(^;6zbsRjbvOB(fanCW$IA76~3CVa>R#-lo{pBp^hM7n^I0d5ip@hijMW zS$e{nv4ywEj#?EU8kS1coS+Yep04tE#2?)$>fDIu{t=P3y&JnT)}_fIVQD|2?1`$U=$`|Te$S2yhw&F{aty1MZvUV2b82!BA_ zw~jKoGc>5#GkMZR<460d4bqL@f0BG5KHZ;Ta=EkIJ$&Y}JF^68zg9b~fq}XC;fMT9 z{?;@1xqDFbD!EK1J+p@Oq*lK?#U3cMPaaPECtqJmx_Bj3b>E-gz z+K+MCwfb`1f8u>6;=j`888lGHrGL+}=U<$&2uE{y`TDfh9t%G&mz$dU{A-q3V)I|p zVCW^XpO0JY!VF?XRSQVe+U<7jw0^lPtLm0s*T=H#aW<37VTVlm{EJv+6V!|ns=Bdv z{Syob5}c~4E)?h>%Zgusz##EC!m<(TtP*PUFCgMiXgL;x>o`|G+61`5{? z%QpO3lp;bPh)EIvVx*_2t9zS0V;A0)IG}OC$pX7-8i*{6M*#`K9%O^Yb+v85 zToTw~oCo}R0D|(Wk|-u9B+j!s@JtXsV-5V5>Iz8ox+vZ1k;Im7ynkCXS;8GahL4_} zevR|=bcC}&t{Z2=DeGI=8f>*XEew8!kkB-lPof@9c~YsA#gf8Ld_Z8OM8x&Dc!z`5 ziOw_8(TSKOYJ30*i^tdi@H5k>~=ktO_1P*LP${5V&Zi! z0{Yb2|G=>k-+F)4=mTMh-E((wH?V}l#cok2APh-N1&Pt95?NS+Z&Sp=U`+VJ#XG36 z`9hlzb`#=aU|9g7JD+I4*obu%iOv*p@d$+d!#jl4Ks06&G=CC<`9v9s#WAruK@^b) zlbgkhJ0K|Y8$lvSn-i2ye0YagpG`ah@qq{p{uM!n`lE8AlbAy==EUfQ7*!I~n;Y3A ze4h7-G7!EB5=%zH_e?B!{#6TR2C-luimC8i0*5Z>1oMUn;j;oeJWQGhl>PbY_71k0 zA|Br*FnINHAAbpbPNoS@h_I&aF6I%|Ftqr?N6<^(;c;7KjHiIO^DGc#`0k?X*)*LC z{8g#qdzXDn(|D&*XWVK&A7=A+D>~g? diff --git a/TMessagesProj/src/main/assets/emoji/0_1545.png b/TMessagesProj/src/main/assets/emoji/0_1545.png index bf530a61edd47d24e18c551dcc380dbbaebc112c..fd5e1cf3c730b1eab8653ef2fbd3db465f75eb18 100644 GIT binary patch delta 3154 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 delta 2189 zcmV;82y*w<7?=@|BYy#6P)t-sM{rCvBppvWGCLp|Ml>x^KQ|~NB0xGcMJ^>oH8M3R zC3#dmLo_anWl4EsO*kkcJT){lGC_J(K2AnOcwR_%R6#EyA2%lH*gS3e0nbV4&O zJ}f48VN5tDAwe=Md16d2Dk(uYHz*+4J3BWy z4?=rq2?MVvCci8z2|IFpQ92njRTM#ZYaAGiAs-n_gMc6$n-LHUM}V9nBx(czfgKtS zTb&tOnG!TwYX$%wVV+DjEkiIVR6aI5EG8`;7$O`ST1GsJcVd5NQj=>Iou^BhF(IKg>+UsE@n_jZ(daiZnUov z5u<)w9CNsBn{`#64h?!aDRu}1V+jK*OlpG(1!zSy zNm5@JXQ`AUA!HvGp>5Y40000(bW%=J0RH|x{to^ICVv=fMdSYZss1ve{%~4cOz`pk z)4IHv#@GF}z|M+|-+tr$&X=?8{{7^-{7YuDXMXkco5tDNip|i^q5t-Z000J}Nkl7z4%)m&ED0?Y$$3-g|fNJ<0dKyMlx&l9{{qAlZNM z^B&HEM}O2rp8sGXo{lHu?=xphe%}OATnbVJ?*HSX7soj zqBTI2jT!F}CrvcF9fzFI(s;zED(EmB^d@CoVo=lQ zXeP1D-vzdyX?j0ExhS^etl z;I4LeaBy{X@P2q#-~RvP-DSp<+tbk{rc5aegFNS4}bZu z6C}EeFXa*trwZwcPE(!{@hCn|Ob8bbAQ~ zR{d;$|6u=5@y9aC-BPLB)tPRooXh2=wjqBy%HQAOT2Q$BbpH+8=r>U+Wy;-tm2$;m z?z23FF#mab|B%PE)Im7PKjinn*?;;(;4!nDEA@qPX1Q2AbWS5It?v&{M_`gD?X0b1F^Oc@PaMsfMDMy3termC_JPq#;xShxB62UbXVPxpJyRZwBcE(Z18Ob!ifV)?bxjrthj#6M~J z9}rkbJecrz0Rj6{6=}Dq8#$ejv9ZlD!Us**%zICH-N+;Hj`QG31Zal%L?o~>I$?q~ zJmSPUSQ8Tcx(9-ih{`z4Zhw^tirhcNOr|FkmzUpCVMb+L!ve0C2~(!M`=0Ui1jI** z^TM7;@LI~0_!%d8*T%4eiLVCYx@rBJ3efmuj?brD1RDGfaveMygcgl z^3rkO#U6O|22HTo6cXn@s&U>Yz>qNVCo9Qha(+IEk4SJ{h786lOf34K%)L5qG|so- z3l9s}EnykP36VTssZ>Ci*PSKo-R8Bd{v-kx$;;_P!)iU>-r8=Ytc`Od%sv}STo}zK z3W*95l^=xU3=9ab$A2tSI$=%SG`82bQa3kNAg~0iT-Ti^9dl zMZzxvk^Tj7dY#%b_lP$mT>z0z__>AuOi&96o#2d#Vpv<1h)jo2?95DK_B$OOyc_V+PcFbg~!n@21La#{(=x34eVwLu};nX z2639&5#}0r+?@YiT*UaNsM=d3ajy!MZ^#P zc${$!C)}zUj|VtP2rR}`x5H2nJ%kVio+>GXup|FzoIKBGgB&GV@J?Vq$kZ_N{Q}0j00zlRt!K*B|kXm3W z!G+y~xNUm(E@*?SntnDYdElPkE2HjQg)TfUqkA(buHQPG4$qHh9Q_O2i}$U-LsGE- P0000EONX<;2>^ zi{8tS%b08B*q8C>sOjFN=h~;SkyGQxqW$~o?clu1lW6DLm*m)s*u;IrjbqEjnegh$ ztchx)e?a&2+0wjm-_eNN%YoLycFeVG&9-dIk!Zh`XpCJhzkj1ynshhDtzyrnbH9mS zw|Y~eb3V73POOVYy`gfic1x^nMAD~v;I@v~rhU+uZp)ErzlK`Fs$$fga@whZ%bt0* ziDl5PkLAOi+pdMBZce?AW{6Qh#))5vU`2LVHj!yerD;djtbfC!Qh!l7 zgt@z_m4Akkkb6ZkeNH-b9~`bE9@B(lm?|iHNjOwQN`E(!%U`$VX~FG|ztZHcf}60j zT)pvMkg`QOMwT8NxG5*yAtAyU7}7H_;59R{E-pN(=5@#KR z|Nrm*|Ng4~|NsC0|FKE`|Mma>|Nj5)|GE7B|NsC0|NY_r{Z04(WdHx6zW@KITE6uE z+30ZXKmPy!`~UyFT9p6)|Nn0_|LybpCYS$E&-MTR*Z=>Ysp$Xz)BpWk!TqMc#@f`=l@DBz>eAQ5RFfQl6$ zPGLh+s|11WPh;non?mzN4Ux5^Jl#)1+UVmSWF#tV#Y03iMViVb{D!~ELs~IyFGaR9 zP2S|yRjyxJtI{d_S;JEr+|mg(YI+ex5@vhSMBqQEzCVrh1*PZOl3c2zk$+waeX0YV zs``yeb-+OEBvh&tFbuPc=GRP$6dsi^D-6XHQ&cfWBoWPs(_>QAz>J}38Cbr7mJOTV zXG>0@464j%2~)`q$OMAQ_z59n4F$r6(FxQT5`YXP6XqJ5iV0@;H#?{f4F2xf`d&hh z*dLbZGmNN2BZl#{71l~8!hb|vpKYjXy&G*`FyNx&Ac=zpg z-(=RF6OPcxt2tzoy>{Gj(_^>Xe#gB|IPt(Tw~hN{}BQ0ShslN)A#(!K3|&3x#TO?X%pRmqA?8mLU>ZXm9jp}?H8GFdO{{I*eM z8I;*Y#fi@m-0P*vnSbz;tEa6L9jT(oc^?LWjsHd21d1rpL*?68i_45)_SscgamkYl zCFe^gv$IG#eowgsb&~Vr#!Cky8GKSluj@qw5&PTeA$*>)O1rL1Vs@khWWnO0V?uyf zy$!iD<(Y`c%R7gXy5m(Wy1Dd?ee#=TDB^iD_njG{yf*1X`ugE_Fc$E=5AZH}sGg$@LwvvHRXzq2TrWpSD0fr|da)U%F!}{lX z{qXz{)o6MR0N4SqYE-DBa|k68lXn8hN_fPGa3rX=61sYF{)TGnx@`y6<^=4Tur?6q z?^20tx2F<}tbgQW<1{(?`!@iuSj`-O&~Zc!C{Fsl}qUtmM{tJRE0zyHH)|u6}NA`cf z=N3(&M1PqPSl~B3!^oOrOv9g6_jKM?JNFr>?8BM*9Y?lKgiub9iNO9xoLS%c0!4{q zZsyQUKMN3$WCf5UK&tNh(bR8#WOenBBj$etR_b1r*d)|L~uCwkJ+GgwjqP;J~6BC*E#jqt*hSl|zMgYMX@@boqX!qR~-(XpxkzwLYCX^ z5QTFAul~u`*Url)yo=7VmU*a3@hKZMaUR}y{!s}4ZksoctY23ao^%@k$oD%{jq5!+ zkqZD|;(!8>q{n{Cy0gk7kKD$cwA}N^MSltajg5C4(ggVE^TbgDF1s56@HqY7>Y6$V zw1@`*fZNZf+k99jaou$voLMWepSDlBE$TH*ySo&Vi_&QogklN>gy*iFs&4)85_RhA z=cdIdV(Neg&{94D@G=e7h-({onKss?7kn<4P-&)FJGgO<2F*+6QRHp`BjE>qeSZlh z*KpjIc;|-ZW=AbP^fmy7bbl{p6T?-Xvaih==Qp73161Gm|70Bc z5did?t}4IIm-Oj31c64Iy39BV-QFDt0FZjMY~mef{~A9)hS>{RD3AuY^;*(^VAN7h z@WZQD`T%N9c=RoyK;5Fl4m-T{dg`udJM6Hwdnre*+u`a9+5tLFc=UqnDSvQ%YdjuL z{03Hh|9IRgzl)j9bOGR-B?}up3Y_aZ=9psuIOgGFj`4mgm#{v*C8Dw@1R2;JE~{m{Z#nhx0PiQ@_!mbrUPufN@IVEJnf-l6drRI08d{g3Ov(F zY4WM-zTZ9hr|x@6`ZQZk=dagy|LJq9(<)r&e*vQ*|GzV%%R~SG002ovPDHLkV1f>2 BZKVJJ delta 2976 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1548.png b/TMessagesProj/src/main/assets/emoji/0_1548.png index b4aba9c7f09fd7efbfc2cd354a8fea069a1cef70..48dbd9eb4683a933610e8d0fbf5db7f20768ccf7 100644 GIT binary patch delta 3129 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 T3`j4J00000NkvXXu0mjfi1Ool delta 2625 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1549.png b/TMessagesProj/src/main/assets/emoji/0_1549.png index fb9a69e683674f8abd743e177d47dce09f9454c4..d37561c90ca519e717fe39f731fe8f3396d3d92a 100644 GIT binary patch delta 3083 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_155.png b/TMessagesProj/src/main/assets/emoji/0_155.png index 92e56ffb189a1a1fbf066bdebd472a2916ae60de..edef6d59d81155a349d5d275f98e72344c5fc774 100644 GIT binary patch delta 691 zcmV;k0!;ne3d;qMB!3}LOjJcja7<-6BXB_{d`T>FLMU=VD4k|Lm0mf3OfHL6G<8EL ziZ(QH00006bW%=J0RAtZY0h6?mQerz0#ivuK~#9!?Uvz^+b{@(YXL^+{U5jn6tFBO zR@z_f+d0_;Uydt3;^0EPnywH#{`L&il>+r4$fh zky;6tW00f1i?vo1>5xSNsD%)R4n%{8GXQ;n?g(zEwuYa2i_0rgxz|w|y(iEsfF!t* z;5Oc#OA_|?`ZP%aCwzwRyGaV7C-^82bi=z8ZQNx9O}9w=A}%3B5tl&0`|HoLi!o3X zj{0>3j3!pFUb&d@rby*V~I!?kO+82Xk+f{ zaPfrbO|x&6+$|wkB-i_h_~3#^1mC;hK+p|>=MzX5O>*N1DS@CnM6II>nOz8`i`{i@ z%n}Ih0ao@+B48S1IQool=RgcDM5J6?@Q7&g)ZGsjJ>4+c@Ehz-qs*Evl4fPNQbi8|`Z+G>I%!RQn%lcs1v) zUbD68YJa{HwVE$0P;Ep6B*L#MYnwHWXr}GuiH3ixhis(d8QXe|FuU#WA*GAh9J2~E69K9z0P2-SOMnw#1{lN?yC_mMmu@War7yzNL#QENTHv@sD4t=x zQ==sl=mdRSv9@npi-=LqFu@AI(`>iebc{tCvn=#%m9VOUrlLXwI-~$d!uRrP^P~S; ZzX3kAJ(9>M!ASrB002ovPDHLkV1gWwFiQXc delta 1352 zcmV-O1-JUk1=|XcB!5~^OjJcja7?US3+JR3(S#7!kQ2IQ4YgzpyJropUk$5T4)wSt z(e$8!wOe+vK8P?t*%|I}9h z)mv~i3#~$RumAu64s=pZQviIeUp&vH{v7=4gxt*KDL*a%0DlCcNkld7K z5Qc+UWMR<0*(C4(nx{7uuu_$oyHhovZ$e>z{M~BF`S^F3kIOVI$GLx=|JJbFoVC`u z+YtrF>3+LS%O6-y%XFWnBO0Q$2C;tmm?w`u>#m32qEA=2&saCjr|hf=>l%Ww>3EBd zeAdR%Ayv*~xPQ@&!5BAPyaNLgOs?NPcbiASyxai{fAMlBgjdO#^+A{Mpb($2`8Za8 zwIP5X!q@)GHr4_Pc7)h{Yq0t7lY!&9v-URdV?9;dYsQ46xX%(I#g|WV+=&Z$=cCj^@xd#s2P{@1@{kLpW&*^m0 z*OtAH(SLiNld3UBM?^m;ZVn#2+(7x)LIf#idM-3=<|70M1btxSB_Y6TOuQ2}=GC;gRjOD=rw!9j68HC1a>!)U!E zESs*WCTpO-BiQ4jHmwImYPBS4T+uqIs){q=M}NlyleBG{2Srh;wNgsmboNzm)mv@> z?@Ze9-;$WlqartrY@5oEblY@^&N{#n&i2A+FS&wAV%9ayz{%>=RL>QuX!)ZB>9)^%;X4bfD$;8K1AXpBbry9NX8Et$3)@ ztaLn*!oOEC-whxZjKM1ej&DoyP83qeZZ<%{$Zqmni^53}&*rHaQi&N96A5@0aT`Q- zv{n^@C2h%>z#;H#i+jb=rx_1M3?dCd*ngyxybq`l8*>>I1~-B@K;pO~40`hOMFEOn zecCCGR?6U7@qm>i=*bDL91Sf;Z$;V7*1G~aPC;aocp%0;6&N$-{lPU~-xT7oPKdZ; zLl41q)MFR)Rb@qYkVL?c&xBG(Q@bN$LdClSC4e=EB%~O)9;q~GMQ8b5k-i<#!hft% zB2A_=vkj-GwY?H{h-4+NsCi8}ggWgM^WAa`k#tM9vW7$W)S!+%(@Turdd?vVym+i| zMeAWu9Gzpw8*7lUM>xew%TakWcauSm^)-hqip1y!oCydqvN+DsB_u$)mkd-!4>2CW z*7A-;0vhtvuG%sF8h7ZHq1IiUqL0tn>;ZG18GUXILDDv2ya^a9B|2?oR9xRg>7S;UjQ z0OG`kx@*MXsI8$yG#wFuK^;GS;h<1b(w>q~K!#sAomH(3D6dEYGW^bb&_N3Bt(^u} zrRUY9_u*H`S!*R!)j4y7Kee0=m&^GKD&~B?93a8pGr#ch|K>j`KiGz?P0eNi0000< KMNUMnLSTY>eTpUk diff --git a/TMessagesProj/src/main/assets/emoji/0_1550.png b/TMessagesProj/src/main/assets/emoji/0_1550.png index 1627e40d645eadcb5a6b0c672c77a34197083eba..a379cdfddcb7685a41b53e159c326c1383b0386d 100644 GIT binary patch delta 3063 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 FV1m32&Mg1{ delta 2429 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 delta 1948 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 N002ovPDHLkV1mH;44eP} delta 2745 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1553.png b/TMessagesProj/src/main/assets/emoji/0_1553.png index 83a4bcbca63e710219e300c1426dbfebb838bc8c..7e973f51f59adffa89464e0d28a9c3852b3494e5 100644 GIT binary patch delta 2885 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 delta 3122 zcmV-249)Y*7PlCXB!34`OjJcja7_NrH_sX!`p7>sDW&(rGpRG8w;(6kDK6%(J1iuZ z^VEX!xg-9~H~Y&vA{u?vnHcuXUHRRR1OpBG%R~$bI6V_k^}Q$Lrz7-w@Bhz0^tvJZ z%su|oS+NZc5)MMuog>MWE#J6R7ZYFDTGZ@x=)+3BOb7!H41Y@-6+`{YKkBa?_`xg= z3_PMB5b}EM{o8rdmJ^C!5aem!oFrwNAQW8y1QQTUsu&xc5)_L74%3($h$)H?3_L6( zn=mJ#DI%0JDW@PCge4w~&lVTeA0pEl9M>Z!$P*OWCo9@3FdrIxzYr49C@i)Q56c-H z%_1emBPZit-+$0Z&F*gLmMD;V8+^1hvDZr@z(Tv(V9m?`40EdAt_c{~IE%P#-XLjTV?6n_l`|Jq>w?!8(r0%A%u|IRG` z&och<%=^}H|JG3b=%x3_NkA+wt9cjhzC+NYF20I2cm)TE2ncys7XSCw*t~rI;D9y} z1k9;Xx{V%^Y9VAr6VAY!mO`@cim2Qts6-aVExPJ$>fjABMD_humzux<)_vYSHe`IFK zJ4;rammf%QcAuGdhTI!hlv!M326%g4U1`D z4SxofRlNUIqSVTkILYWEh}BD9W2AfC!Jt??x>TEeKK!0g~F#xmc_ONDABRy9_onlq=qSjirBtzlG>s4?Vw zy(8dQ4Xaq6xKhM$i}Pd&(_9tO1Ed2&G=CT`$*c^DJwx(BiE4&19P&KFOi%KcR_8V9 zI9LcnLEPTrd46bU1qD0y{3t%b_lAZZMM6o?HP8sd55HK=JfyB@tCTpA7lJ&HEDOY4 z$|UjoL&Gq*$Z?{Q#~B(0iV1Jv?c%uI4_#XdRD^t_2Ci-sV(YH!=hoUxun3|SLj}c2Q#t60B?Q$%5@Dbv;F(R!(PDQ|)VN%_Z<@}bRF#!oyj1am* zk*RQYE+&{9rz7M#BO|FPa9@zcLcyq()j)RyVP|Uy6iTT%>Ud^}5JbZ;lC%yWI#`fP zn@HvGgJhzbuGzAHPj~W0rOdqI(0|*^7fgm2cYL0>$mGn9&j4`wZAy^pI_t^EDZ!qH z?OdfYtaN;67}Z^vpX?|$9e+Cu3Pot^ zLr);{$Zsrscum4u4Se%N@Ue@b}Jbs~0$- zCyPs|QNwH%`Rz8Or~<|>w|xW%J1%m;k-d_vtA72cSce4=ufTCqK~yYxax@yr8nFZ9 zGn;C;-a&EKQ9#IAf`}q7!%mPOdVm4hxCx6tB*HCUPwwcC` zBb6iyaUiJGdd`n?n2Hw)lEjS<>U9cEzyMOPqP7`9b=Q+nns6KzJfg+}H3`vU1o!}g z<0vrrk(B@eV>{1boZkil_*feubV3yDMFD~ooi^1`rwvwAA_$^`v7H?uQctJ~jI-Jd zTxV@o#FNYjL0wlTj(>*()YeWJ(f0_1Q-$-#=k*s}$?u=<=NTbTejP>9 z0j0nY1+bFyjzP`SHVUwW7277Z3y6`{bzq=2C??noH!cy3p-7PqNw6Sq>b@Fakt4e9 z>N>qd+(|Nc9TTH|7c*`>ivh6lYXRq%#Oxymc%A4U zxMGbUcfm{M8Pt&M|MdLRNUz|=AU`w4Y7F@2QVE3-{(SRxJ)8PL{^O6o01$6{bwx4c zC$MoB2>-TOcfD!bVHChoRFSA$lyuUh-E>m(ay2a%?SJm3ywCsvN==qQUPxiC32zP< zTw|DFRKp5QNFr6qmZXc8u(C;|F1EPO<@{o4M zH;-%B9Ip5ay8Hzlb{O*QmyWL?0Puu79{h2JjLRA}042Z2-}gT8i=Wd$0Yb)ijwup6 z$TJTMH-Gvk*g7;?YNz5PUNHt>(50h+ff|k}COoskkwO14W)7b$jbygnZqgX29j-87 z#SRb{j~r8$u*eNg{N9}0-{(`MnsT#utbz6xt`~$`#v{jr0SSvNw$ZI0<|~GY+0$-I zS}Kp#VjB2y7ljq!xgg*b$1)+f7Z4#204o-8lz-1=$`IPkW>U*Z5^ktrCS+0GT48_y zfI2Ogn(fIF$RJOHbO*C6*FcdThyeSf!&6|A*HHyYztA`0N`8p;k+@% z9DnyASb$9&s~9X8B1ze_f-ftnVxruJ5D_9ifeZ^Ff`oGX!?P#h>M8xa!;^YiM!~!P>v2R4d zU388rrpXBtJtV0lsdOXWh!^qkZ~`TGIDY}7mnptZ%9W~ql;=eCxTjat)N4fr!Hl6o z1OdE;-J+|ON`;J$*>hQk(b&K29&|s5>7SEoBtjkh+_**9EfzuamC~!6`!i-wuV&Wk zW)1&+_^c~CQe222{)m4B;l$DsGwc?jo}?Az-S-#gt~Vfz-S_W$4|nC9R(F*nbx$~QWPu#tUS4(Z>{9gyY_l6^rnAE^DXld}qfkR$BRs zFOc7=7z2e)r;5F{K`p`o)F1?*7PfFhblY{a+PQdFP%~w@b8&H=g`i**xQ+H6FFvNQYf#-3gpMSrMMWfM= zKqxtVI~I$*Jgdg>Odte!MVP^?%X~`K5jdm&S*5Y{b_uh5e%^I z>hWu00CihZTg3iOs{P^qfc!jJYwAWS=hpl!!Tn# zY7@gSVwn5L1IqW#+1cqQGb=N5b6>H{&CSd_nVy|>J{=z$o4B2S0X(0R5BJu+8~^|S M07*qoM6N<$g5tQ{761SM diff --git a/TMessagesProj/src/main/assets/emoji/0_1554.png b/TMessagesProj/src/main/assets/emoji/0_1554.png index bec8ca51535203f2fb0405b244f1e47f096d7d3a..f8f5009634086ba685c34b0fd0f2ecd65406faa6 100644 GIT binary patch delta 2821 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 XbUIcs;s(xb00000NkvXXu0mjfICmY# literal 3895 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 delta 3354 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 kdP5uoqoex%{{DXeA`?MdF<{9 diff --git a/TMessagesProj/src/main/assets/emoji/0_1556.png b/TMessagesProj/src/main/assets/emoji/0_1556.png index faccee097b85405cc81a526517a70002789f4747..87390bd47156abe49ce6ac593b444a69390ce506 100644 GIT binary patch delta 3062 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 Ef;d{JTmS$7 delta 3639 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1557.png b/TMessagesProj/src/main/assets/emoji/0_1557.png index ad96520aa079067137d14c3e67ab86ee1a3501f6..0eec7b58e34ee9bbda89499a4bfad732f58610ea 100644 GIT binary patch delta 2839 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 delta 2768 zcmV;>3NQ7Y7S|P!BYy#~P)t-sM{rCKa%&1%Q#cm|)u==H%Tnm9HS)PAiWnN%F*g^9 zf%(ZpPEIuTzbF06I3A*#=x7Y+at!;*I=>|a82Qd=2KO z7@1oKkWvQSoPQOlX$sVq6ti>-?y?+sJp`d)31&0|^};>;!Xx0L8T7aw_`M+i$R_Qx zC;H=}{OPXw(rxzEh5ho$=CeJ-lO?Hi6aC|n77YlxjWbab3-`n=|H~}2D_ePwuc(boIdQmRe%52Q`Dj%{nlfMbx?aN2Awwv z|M%68F$lLn39LK{upA)S$eNiM9N@1hmva`Rj$7x$Z+u@gryCy0V3QdD001s@QchC< z{{H?6{1*QH@cnH5hb!>#@Imm-{xq7%R;S$XJ^NpvHm=nu$UO&a zX1me6k84~lW!P1~ZO;~u&<6C$MIBw=m-%Y6w!8^DHn-3_^t|g4$_an zi9vQc9XbwH711Lq>a?7B2(4k%Ms{-ufcyqb<370nI{R+n%5>`U#FF|gCk>?H1Ix|9 zZ~@W)WB^gGMhw^uNUK;n-*S#8LkLl62!BOJCCEge5`pRQ#PxYimCoh>MDQwVldn`P ziM0D|$Ov8EP-N6;e@|Bo!{1B+NCQx144}0H{1_y*DxM}G>4b;5Qh*|G8i6T*n|=gfTT`0?vXRpM`tqQ6dL04?8#ga| ze}6p_WLf9oo-%q$2P;|bTib>k=V!J99!qAPO+dy1 zxZALhWgDr)NJE4VAwDnI1HpI0Xg@oQ-4P9%9dHGVEo2tiLXqhh4}ahXQ!KD$+muzZ zm*CvM_XF)6)9Wz^^M2rqg3a_8#wJ1F8!ne9%gD5gMP|S-rr<%YqMHme7!=DkWaQTp z*^R(;JA=XC=m;(+2$?7J`4C>^wClqeNvxIgCxerd+uIYkn5Ic@w;ykBZ|!`soTA^& zR^~MfIXryv;xMikP=D}p^zqLe2*}9OF;I7Kp|^R#%g)1}K=FtU`nFn-l3$AwAb^hh zyr@s}>)lrD9x6ir7_ec0mFG7RU#f@qf|IUz$rSEjAtmLX}Kr zX3!!671gG63mMJ7yyty=ut~bdQlwm*pPqAs&UtBJIZ+Ohpf2CyD86|@zzK465(Y+M z);quO2a?sSd~?IgO65`zMxK8e`3?erqm3|?pLZ@qi0Sm#i;JbA2oMLt zE~cuEpK}^0&VT3O+Cs5_03qXfT~kr69saB653w zf(i_T$kEI0YCb=k1o>i)e_ulIbHEWsB#sggQWQqWNS*cjL%bOtf){M!c|$y*s#qU} zjASGZfq?xKhkBsIux+arh>7dM0OUArwJmK3nM{U@_kiXMmg1avV)Db%Tk_Lt-ZqM+pcB6gEJpO|3;2_Q>N5aI(&+Y!kskn!dD;fZ%O} z0u%PBZhxt=rnoG)iY7NLQ&S94BFzCqA%cY6UB8D<6lJ+(o+`_sC*m$;+tOv61q3M_ z#wQ@`A|#~N1V#_XahJ<8Us%5G4=von4K5)7(FDX(L4+;xDNB=0r$3#J-@}-Av+2j$ zv~8(cTgOhMw3N8IEt*Aoqvz9=r1b|#=o&~bhW}IuM&ZESWiiF zw$TE>F&P1o(iKf_UA&Kue>=x;wfH9*z3X&vv)c`B!N3~H2!f1|$Q#Nl+gbExv&+lT z;@zY(ovkh>j&W)q77iqdgv|5a`xPDB>ZvHLdOO4^%ZO#bTu*9b~0kHkS)}fS_$4n*?r7S#N>xMgv11jd2Niy6! zdTQ@TFe^9Z5*ZT0z#$t<0AOQdA0Xb=aDQP~Bm6|&5hi#0rw@2Sm;k^6KIAbW_Cdnc z)%Y6kJf;B)H^ue%D*B=969@qQC?Jj>6Z8(fsn@IZ>Wgcd1ytj@R!7FP6DDZwA?Fh! zl@f>fq+YFlPKmuhV*F3FT0;#w&z$57#C+O9>|+ezvxgz%&!EL&kpCx6-mtK>wMq3O zKKe@m5~IVA5D-D0J>Cc(1qoRBAZ+~X69Nc`&BUL^ktZyC{U~I_lF8)G&i3}R&HM+) Wi;!?5$Z#0|0000G<;7r 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 JPDHLkV1jh{HUj_v diff --git a/TMessagesProj/src/main/assets/emoji/0_1559.png b/TMessagesProj/src/main/assets/emoji/0_1559.png index 4b8a646dd3a5ab1191bc0c0ec8d45fcfa4e0d54f..b5a3f73e8842a6bf9fee3544120920f6c2ad74e2 100644 GIT binary patch delta 2711 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 Rcb)(M002ovPDHLkV1kJ0+Ts8J literal 3794 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 IM6N<$f-?p^WB>pF diff --git a/TMessagesProj/src/main/assets/emoji/0_156.png b/TMessagesProj/src/main/assets/emoji/0_156.png index c32079fe1f157e6a673ff3052f743eb109b6c2d1..81a25e15cf10ae2aff44680046fd44570c2e66cb 100644 GIT binary patch delta 622 zcmV-!0+Ic;2!{obB!3=IOjJcja7;5K9X>23Iw>MUFe*PTCpak~TShxXF)L9#G*WKn zKL7v#2Xsr7&j;nNCi5BYfOcd1ir)V~900>Hrip9u^=p@2{z8-G7@)c_5FiHHTeDQT+^ z5*-AW?w-sRcSa1o3JQPU8S~VA!;J+6aKw(-Xu3ASvsM=)Lnix&PLv4y%tm*@5@Tzh zUI>asg!J1ghKD6Y*eF%h1!YgTRuRw#au=nbtd9g(-AThUg6;^eCZ4+(d(uT83Ra3i zSX#NduvSX(O@G7+VUFOn3Zf$T3j|P1Bm%mM_)!-x1Z23y?+6ow9tir|1;!-%vKDC7 zMQ!~MsNQVEz|}=Xpgt~7U~B}S8A7cfa3VAjJVBK5U0octP)M%`o4By8xNrnoy+wEFgg_+0 zLuj^@QCg2gB*9|<8A4%aORy^zazzWSId+^|Adra87T?>jZlr{7M;Pn?L@7Xdr-_(| zupCKIuw2w-u~Hy_%Q)GId>EulmL1wc2?%_FTA88cAY?o24B9+7O;`ZpWr)M1uOM2s1y&R@$~vOTN0cS? zC`EkuvA<$MS+#L5p$GqrT;6B$(Ue8R0X+9GNA}mf@Ya8=KZ=__Tj9vXL;wH)07*qo IM6N<$f(%p+HUIzs delta 1057 zcmV++1m63H1-1x~B!53pOjJcja7@sVYVgUY>c5=Zq<_$pZqt`=*`ImUmvGIDX6?kH z_tmrW&aC>|y6?xN>%g4lwUOVdg~NVV`{2Q_WIt}dwXOgF01I?dPE!EG-j-W0i2nZm zz8(RnivR!vn@L1LRCr$H)_ZTPED*q9FX(`C0kq%$v%WJ}R)2-~X3w7|=hvo5ll5_A zVcX%~X<4^zo89&M@~6T)v4vAX)@_=mZT&)V^ERD#-jMm=<2aby;3ndddjH?D5!+R` z4Ni~`OP$Rn!lE(97h_qLB24wpIFFUkqK_&Rk$D^XmU+@P)jyXpi%)peq!4GE`sJAM zDB-+7td}wQe18#S-aFwwK88K=MZiVieWchC({YVh35~qJ2= zgzHw~L$Gv2?M}!WVbPwi+4G&qH-b9i_CmZ9>1$%W5$xe2q8I*n4`OWyC&v}|+rmI1 zWDAjUM*c;(BbMnJg0nwg$&3^sM-d?ri75aPA*zNHdw+tlUWE{-BotEypVL{+AtWiD zmU@CT(?tY=-BQq$C?sbjQN^61rC>*7sio+5d(F91xOQ+EQB=t`5x9nMML+!%est<` z9Qqg~f%p2|5k|*kK+gLP84@2aA*HZ~uyh1~-C9#21qeFD8^S0M#-V9VIe5q#>>&z- z9fXW|3wi( zB$A{?j+&HWH19bF!P1-&L?k5CjEMGJkhJr>*@uSNce9)jBgE3~;95dU&)_G9u6n}U%KJB>~Ly7fC93P{OQH=dkk|6SZ zie@pUqZpPM@;gUCew|%ZxT2QWick@o<2>8owP4cE{y2F|DYwKUuJ22>iWEZPJ0UGG zmnp885!KL1&WwokfO)V?%6}=#{$C&2!jlc5jI)Uxu++3dX|HV%tLWsy$Xcg8>E`LG>7>Ac!j8PF&kkO*gkJBSD!RuqZHOEvG zp*AGV02RQm!+UeesVHZpS_P$knl@XaYt1<)Q>s%nQ8<~$)9RKU_!?dt b{(}AklmMY_*)p1100000NkvXXu0mjfWl{lS diff --git a/TMessagesProj/src/main/assets/emoji/0_1560.png b/TMessagesProj/src/main/assets/emoji/0_1560.png index ac0a14419c7a65b9a9b176f07ccd391a9d731991..df2becf50883fe21f38d558787320efbcdfdbb37 100644 GIT binary patch delta 2916 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 delta 3516 zcmV;t4MXzT7rq;iB!5g$OjJcja7^~UC;iJf`O#|RXbaUaHuQh*;jlyCpE1lv$NS1U zs5GSc$2+?@x7A3~mrM@%$U8C=2KmiZ#VRlEcIksU1^dP>PaXu_RttPC3irM!k4Opq z)?n+)cH(H=o<0z#VF>!iJM6I@zeowOM6dqVS+XN1ml_?67JnShSIPLoH2KLw$B7Wt znHHTck!3IekwFlpGi;<#2Qw7|b2tI|)NR663*C_>)-g8EEi=d{EWaWr$R^{Y7=lFu{^XL~pBAic3Y=XB z^tvF;j}ojA@H^+rDh0ZC89lb*fbYx1`hb`1|BEFthn>GmTzDcJZAA~Ij zv>+qxzAJzg7mtEy+Koj2-)-dE!PQwU)`CRZVhr)umHzkG)V`0kw|d6_00202QchC< zhb#T?@bC*5{z3j{{{A|h{&Vo~$X2KDkK|(D`G4@Ky{pyl@R0ED)bPl>>*es$?eO48 z?!Jqs8Lo1)000WJNC$pO=*F@W=C03t;lTn0Qti;KymW-|sU*c2O2whV7sTWE|9II!i*0mQupjemFS z18C+Afx`+7Fct)uvl{^f;5uTB8gIqPRQ2vRR`G zz$_Bq+ZxlT)i~^+a9Bw0rxGSF$?DVXLL7)>4f)!@c0i*A7_1Fy{1DpEff^}usneI)8vbKyHDW1;FK&G)iX~>B-?;7_YwfP4o)36B7VKz;zdUyQP zQLJFVvHB-Os;)AH$0sM#Z=VqW64_TL(@!7cxT=ZBcGv3D@PCvL(K_H!bH66N}i))z5$wMAjkFC}*(g9~}usIznmJxF22*v+ zAn3mj-{+d8QmT}${Caq|T2us8g`);ChCqUTeAuX*1GI_27#vwZ;4q3J72??{{Y$Ep zN~ehQD!sZx}A;TAb&?uj6&>m0bT$wj1EL#SxguB1OX|P(mQDw6_SudUA1ii zDtx1yuH`%6SqJ2C9YaI7dIe1rDO)m2D2dZ&sf2T|CdpBpC<+5${9`I-d;;mu;AYTy zLl{{WSV~q1B(@laY>B)EJE3VZRQLmMYJ!qD4~PUWz-GEVsDdOJMt|U1W6aF(hB-6i z48cN!Admt7)sZxzVE_mO6jEscL*!I}D8v5?w1!dc@_E5Q%JsRajbL?V$o1U_|LM;9L< z_4HMUij6;BK7W6XO6G6+U4v+Z?@@m9HY=4% zELO=Tn=$yR%>4|5j1EG>(*0t4Z6gzN){3v6Lr}-Jt}i+bze9bsTBT`v!z$8rwHkvC zcocYyrN&%mEnbEtv_}6^W!e3-ZG~~TQoBhAQK_OAy(u@XI`yVf@5oo7(1a1bOWVaU zBpkq|6?NU--T*e& z=Ym{_9=xJF!j36JurRDYX0WlloG3RVob8qBf1)Ik-l!Mn1V zSu-&}!=8=DE!|MCYQB7FR^PnIE-kH@Dh7eB!<2MRSSH_a9XBrA0)y9A&CI|!paOeE z=3??nO*gQbLIV5wO(`=YL_rP@XUVLX&}%x3V1Wps-fnQ5D7+;^1QkP-ZpmUgEyg#g zBY%nrdG&c2ku+97zFClCQ50uv>PRCbbwhfuUARRJ;bj74hP_!#Bv=@L;Fz^xmZu2H z{(%UB!EP^EafZOiBXQ=)*0CxO;y+b*K|yF)#)`+eyoMoWGG16RaGIcM7FxzihLaO9 zlOioI#w~;DNr1L-?Ls?M)M2MI45WmlVt+TP#wX;W7DXsjMSLpH$x|ZHPLLXlCmbzJ zNT|EJiz>Wc4^^KrLm5d@%3L(Oaktq(HGSiuX@h(LP3Uzli6&|YK zSvew#afWjYh~jXCtwbV{6j12^Nl7p;TVfI`lobn1oROz^eJ+?JKcV4w_Znp0pRadM{cK*B_d$dc*2+nH_dlzErinN24r7@=Ah z;14lpciuTo=IrEl9D#w8IzSbdnu^Y4ZkiE_@4tN9-NT^3V_$Z6-&i%E4Vkn!intpaDF;CgBPm&{S z?4O@jS1T`|4ZJ~DUw3#}CXKExKUH`-K~Yc296$H`r9mSN%e$5>UR;<6f5H8^==;s+m1 z0`zH$@@x^QQ4Pbfo#YygE-=t8ng&mOlp}f5J^m&4_&4)BHyWmf@LMK^nv6(MmkH9s zL8H6jKkuTxH@|Hqpiad_IDh|hIZIQaiP5pW<1EbNxdJ00Q#Gv|WwV-@C)~o`{87jc zX)5Y)5i_g`!y{A6tV1VIbZhAUNgs7RD-Y*xmw7^%&g@0vi7=d#|Ra>*R zc83QFJQTvaR8s;e3=EgK<>F{ba~8_O!vjg4q*N7X3h|@E!m`BYy%$P)t-sM{rCwAsHYZ9W){uxhN)jPB}pv~8uhEqEce7$kY^(GkY3XH6M! zudJ4ahjwl~d7B_cfN^ngCS0T#BRgP>pfFr^t5H2CXN-5oM1=qV0BLkmPE!E>{F?qy zE(8k`eP$;g(M^@SX&E&n{6$&*xz6q7{e3X|{(pDysQ$9c;r{6T@3!XTJf`@*;nfhp_M6k}(#mh@k)}nx@S^>o+2hTw&dSIBP}j3x z000N+NklHE+2N;qHxV&4Nuha*3__v(`+WPeb;5W+(a22D*SlZqlohud)TW=+k_ z?=ue^n4i*NfUI?-z>Yf6p zDehdnlJKBD91btcKoQ~aIh3x5rtWUP%Z2;FAk(l%q+Sin2YgP$`ue)Tpbwwp(GW6Q zw+#>IR4%`bL~Ko|am0*TzUCYl7%;CnoeQ+Y4Vw*j1x!|p%7rs+kj%YC&b@HXgntY` ztc61A!5cJ<@I^T8GI^{XkJV(-;kcjK5Ks7KBeOuvM#g=5I)ck|IJ!S$@8&($jd#Wk z+=18b9@%zxaC5^oyE3ry*)_frx|({ZfQtPN$Hu4N=6lS#`7X3+b2vo1M<$nPS3dP^ z4)|793@Zcr5}H{E;Jmue@88dRJbxRX-oJA>967>WKTEIn4fx<^04|LF7|k>baU2g= ztX3oSqXUA;-Ss(Foj#v$U26cvc`l!h@cVJU1%??=!5ijB1QW)gF_~1*5`ggpisqHcooc7NLyFKQExSpf$noPYxJ?}XoE$|{ zZQ@Oxr`Kz>S`cW1@`T)5Kh!c*3`QX5Uq9U9#(({x`JB@~eUKZ>AAXc_lIf9a_j3#W ziD@8z78LyZKDsCHzhN&gdw-`1-v>5(ditk4l&*{mi%Vc!wod$604Za*cqQAf23kI3#Wj34r>X*Y?Ny4zdM$XKYFD;dq&wq_ftzv~=i+Ixi zq-*=lFlh`gd!xm#Xv*Mc8?pA0o-=chGd;@gRbw_kM*J8Z&4_xz7zUx=o#AF5J`Hh^ zG1xu^2BfD)X~V1*S*(%fzl$^6+uk=2Z-2Bmbhi#AmeuTj%LV^YC`R7+rKi6B7WL~ zm!uFQDp7tmbboRMrr(B~%INKKQ|SWYG(y6c_7_nkMg%9~i3jP33^Qi`taifi#iPAl zu}}nZrGlu7zplLFn307d4=LjJ7;&Nn{%_5yaQ@5#0;=eZg(8qkiDii4Su94-${hki z5d!GXSWRe`i8cAfT1F<%P0LrGIc|^Xn6dhd@|Ms#F}3DAQ~8 zRJ5>@M^@e(Uj|Q7Dvo+gqUkfYfs0EAgBn>iHy}DMLs?Z=amh zHl~zK_J0}d`V^{mUiF=QPk10+4sAV;Rq<<#fb0;HeSP*u=~;uhF9HOWGA@a413x1YIQX6mq!=MXmsYApszfFx&5PN?1{QpmAEGCtR&pMPC|4JB+Ab)rgjY-2`Ap!<$MZ*2Wc%)32Wf(t_ z5Q=mf9itFQ%Ym(edyqKG2V&fyJw{7#6*`?NAVAU;DxHpznMjyt$0H>?lIXM35^#2v zN)?bHd=YFJ;snCJLmZntn#cqKE(n537(mDlAGrJ)DMcJZ zq;`tn(GrC^jUt`0G$slE01??C#wSbY39)YHlc-E*Ii7GB=Qa?x^AJvlnWX56v?7g! zM_DQhE1_TB_w(}}c*3Gm&-{EVZvOftbv5srYRn2==souC%tDbq! z4Z306@BH$m^EyRze(5~(IPQ%U^B7H3{laX^st41^XsS5BxVYGJktE2y5!j1`3tOMp z=`0jcWzlGK*bSO0F2bvt@;bFQ*3)v^= o_6z}wCFAcjm6pUxN{<8n2Z0?yqGg5eGXMYp07*qoM6N<$f}k+)nE(I) delta 2813 zcmVP= zD5M@4e;s|}Bp!+pTF)AG;vj_NBZ}fDAde-G#m=&Km>wj1`mA^X81+@BWhu^j%zCE}$Q%#RYfd=ABj5Sd>K z{nlIm%`yMUD*x0>{@QEEn z@FfuN{D1KN{xGee zSvfmj_|)rJlgp*yD}s8dLRB@pM=w&y=JMsrL4Ubi%4J`C7un2KKA$gbW&VfHtePZ4@y~m))&(i~VZ1*(??xzoKfs{&A{D=J+NSfFyyn=8^XcyN}hX@B7gLeq;sv zDSwB~yCMick-%ynXHzY$-I`NxFVTWeyA@J98KwMq4SWJ!gFb`bMG1}%snl~s+3Ewrn>;m~t<{T+1d*afa#Rax*QTd0W(Jfv8D z)sNai*bxZX$=0&R0y~Nk?oJv*Km*`;9)HKL7AZ#*BZms)croh%8eYRuB3Vl2l~4|0 z62OSS3V<DB_G+rH7g$qUz4WNVpj3PKRbq|*tQJhNG6|@uc9h(*$A*ptA ztMleitUj7vw}Keg(~%{q;77~Tju>2N2`r+#bjhzemgL)Bl4}N4WshpE-<1p^6P#zFk6kPb$_eck_4&M zJA0!PHKzp|Y5A=nJ{_=7`^$}BPNWQjF?5I`a0$jzGQrhqBP9+NVF(Nhs)6weLrFMa zhGY~M%m~1}>WAP3Jj49W>ZN9P5TpPVVh-xi0DA5uik+AEs|6FbjhV49J6-#?b!bw+ zgCWfs2u#Rfir+Dl8e^_C4u4~wAQ&Sp;jyGvt7%=Ufdb~(N%5JNkUz2~|J=13xv8pOQjTJNG)GY*6&gC;eoptXzh z^B#v5Nr`j}1`jy~#1884+YDv+5Ox84@=L5??=1#zX}~DKZ-3ZW=YKc;;D%oc(DvRp zg1wW|(;jFj15m;*PEUVJn{4cz%RM9SQ{k zp+Jb!H{PE8c>DG@=?{N>y5{L;&+yd`lB zVsdzuPA@=W*Wce8c|Zc@-F$iujGg8<<|`E-l=J5E-mF(1FC#F%8<}Fk?RGzQb0iW< zw~xBrbD3_pTYsq>UBu<2w;ySIJu=0@<6hW+@UcBUaTnRAVCk8dxVzsROuM`;mkS6P zAVL8&SmN}JP-?$zx7*8RUfGfImK+|04G`2}>1PTfAOfBp`{AKs?9nDtf`C`UdFZU( z1lS%P6*djy|QGs8B3oAyM_bP^uu1=Cyb$>~KBMl}{VGV)71h>$14O@<0FhBsw>$)wQ(eofkFvA9jFP^TiuLXlaX-Fbn zD5&B%@4!7u!*CR|tX4?TP0U4c7W)XbU;zY-KA~gbPz{H}kc8vl(8#GuAr)p|5n+U% z1}z|P2E>k2FNo}6v)MYaS!HYXeJL{`x=&3{=IWEkla^K6(zI-4&jne(&BH?4LN zMymC;e$mb-x~R@Yql?kS1ssY=tOe(hVPZ$g>zZ15U9WeJ%BAAVi#nE*^9=4d1p-2J z0WlG3G0zzgp1?u=cvpQnQGItlUfh3GKB^wH$IGfs*S0_akQorc{}GnQcHLNw-)$@2fE(w2x1k*qZQ{cN;GKoj0r>%~X!G+`iD4qIg5(a8S$e=9y zmf09%f{h?Oi1{3UY$uVcjwXaqb~}yj?c{dCBp6sWjn5G8lZk}o#fuk~D-Qm!SauT0 z-^h>z0K~WK|7?q7!m_#f>y2z~S`yFA7RzREBSXaefOwy<0I*s&C{~;es}+c4bI_un zVPbHdD`++`5sO8SC`)^yuj5*njgcz+v}QP(z^S P00000NkvXXu0mjf^?x%L diff --git a/TMessagesProj/src/main/assets/emoji/0_1563.png b/TMessagesProj/src/main/assets/emoji/0_1563.png index c177b804516921a809162f2e97d18c2aedb8d19b..d5651506a8080ba37782fed659cc1d03189bf91c 100644 GIT binary patch delta 2723 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 delta 2940 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 literal 3700 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 delta 3027 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 a(C{z!T6WvTsY6cy0000W78Y{I@z9lQ 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 JPDHLkV1o9cCDs4{ diff --git a/TMessagesProj/src/main/assets/emoji/0_1568.png b/TMessagesProj/src/main/assets/emoji/0_1568.png index e4894b8054454f6e78b6dc26c5d5d95aabaea87e..57d89bedd1d71ae48936aa5d37f2e9f853e89d60 100644 GIT binary patch delta 3189 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 bIRpO(V?jf=S__8g00000NkvXXu0mjfYJxBB delta 2332 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%0DlCaNkldAJ z3f^t6oKbeoWX}TTf{`>s5!tIU# zfOtPLaGW0Z`*iyQ<#d}K({yAZ0yqx%+s8b4_5iPkpGu#u0N?KJi>4y~Oj#Brf@v*jAReIpGeB801QD1p z7@nF1Ou;}hb0cxOGC?6f+XS!Aby$`7{3OHGLN_#FB!3X(NhbVS+@fBS6ZwW1p)sL9FY&S`qU$%&HX_u3WMUvevXs)Fdg4G_!*e6RR7Zet zE?3?jEdok`&0D@BSkPgu(kLMu_?999a8F}wO?vLhO*c$rzJ~r;(9G7I7=3No`xw3V zIhh(`M1M*2193+lMmk2UCQ@WrDz%oRDaD%PDeUWzkRuL`6M~jVb+y73wUJ<5{bYZo+!BV*eYjE3r)FxcW@xQ16_(Z3R1-K_ z-!Z(##jMs2L~6ApS-4_tGSw7xVKj8l(6@D+2Y;d%(^@H|t~UE>*Xlu+Ku@Ne_>MqK z=aIuqU)%JON1K z5>2*bO5bV!ZUh(0>7CG_+P$RZRE({Ovh6e({7&g*1X_;WF_Sr?65NQTnbr2@W{LwijMZl`www!DZ`s$GB4vKoptbt^**d7)cV1>vY<6Oyp)2!F&}M#9NKP=gTE716Mhw=W7J0{FBej-bcL<6P%?Jo6A!X}lD}uIi5TZn%G_i-sr9PC9$$Od1DAp zD%9OV3`T8@5oLNdfCO{=_#p?wNJ;yY#DEAt=5#id6ms686^QV2=7Tl#Y(MR3bX6H| zE`1$-M9!8NO*K7dE#Xg<)8TSCpNZ0(&zD25;IE)B`S@?=ALm5a$kCD}Z~y=R07*qo IM6N<$f(?0y6aWAK delta 1019 zcmVn8w z$BJOprG3$zbl$a&+O3Anlxw$kP2|FytZ6}&Rxt@T4l)1$019+cPE!EgnY(3*!~PaP zmfY7V000AbNkldD63_#mkV`~LF|NpHQWP)up)qj=Lyv#jb@_=<(AVFUL z8`gFGJHfV0(=^WO?|n679S7K9-({Ff{5%cAFfBi@%;PlVU(SXJ_KM7}Z4mSA=KI7p zi3P#5&T0x{*ho$x?7ICq^^6$?sBtj9F9i^)w2|rM*~TF=X`y$Ql zhc|4=gJ8TAa)0;n<_*oClEM{*cLiSxa*APZ4nF9n2+|brQ8CNj&_q`hrrXGER=y-7 z+y)Q+TZJ6)QpCF=#!Dx2uaMhdx+y5=rQn-FXTKH~0WaTO0bLd!6nGU96sdG%z5paf zXcLyDZ_S|zV2`1G2q21)R7F&kD4>WyK}5Zx`pYOL$$w}GsF;*oaq10ZOQ1 zQdLs(G|B)GGm|Q1ydtV0mhVBtbzj@@0QC=mD90E%zi@U6qHjH?FQ!OlZ~!P_2#CQo zcvjOX;CLitYzi+C4k;z4U_|D4E?VM%w;kmX#q?e~#lkTJj2TRcG`~J>yW zq{0zYgny4Cu|TH0b}*h2U7SLRF-rogh$tQhl8UHYbPn!HGOM)ugNPEQ6p8d3BJCU? zaqAUu_LeoT6338`iRpxk<2e_hrBk#igM2%VbTv1-G=%U`luh97P|6BSM<#_())~1^ z11N5Or<%kR&GGfk!Ce~C?X=ZSaC>f!kR6wWRezpYIK`udHB<5k$t>nM6dqahn{_(P zRnqc^h#^xD z0e`QsrEu%{S<)?LwA0h=l3yjUyn3eJC4pgeidg`DXc1+!B-~7_^d9)*G{W}sj8OA% z20sl;!n3IebajDxJ-VJ4>qI5=RcXKpS1)A#_<3E002ovPDHLkV1nlG=Wzf4 diff --git a/TMessagesProj/src/main/assets/emoji/0_1570.png b/TMessagesProj/src/main/assets/emoji/0_1570.png index a2eefa7275e057932ebc27a357bb4566da2057bb..b73933e8009438b27b7c265781027095ed6f5194 100644 GIT binary patch delta 3112 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 delta 2291 zcmVq81;cobtFK>#!a6y(Rk7a1CQz_`)X=9~A{JD)zuN zsx&UvnH2iYRrtas_{Tr{&s7ITK?p`a+@BTu*?7ZuC4~tb`hV7O=GLmfel{y14bG1c z-Juj}00!&3MeMaH|H~`;!zA;!9O9%H_`M51IvE6-TnNdUD3DYLq+$=vN-KLo18Fq|;jkqLNkhme zEc)W34L30kR!#20RBl!j4;T}yky+obJ<_RKSwAFAMlxhc8P}>Px{NsH&5+r4D^Cj# zuYnzpCMcR39RBv$7>tBNI2~DJHn^#T=8!k&zG~B6D1U!A5QKD7(YuOvVLEgY6{#E` zwjd*yay}fKlZO=cYUAMUR{}LGSO+v;4_x@tW zS6&4@{bFAWzF6`7CBfXkFC@dlhoKZjB1_^}3F#4f8#S;;WWb~?pMba69 zW`8)fdb*v8_(8&mGb8TyA@ZVGP|d@`?Q}W@63J*8we5(=2#o0JdM+ip5oMcRhB4$aJ7?hj5FGGh3wR7{xm4?Sd8e@B(u>jsJbxYb<+w#ZM6-`+}hgx z&5xrH+gsniA1X$xp-7mUW;~SYt+vj6`+xeryzj9TsSkVaD&G#3YN5fAJ~!P|3avKR zDSj=NPvglLY()D|E*G>TI3#tIS^9H>cUA?3Nta$9);w>LF_w*KZ?;Z9#lyVOsy8SX z{R}J`)k0e*iLj<=NgRicvL#I`rD>|#s#cXb7iV)?HL9%!L&Rb@{IKCLYz2ju3V*F? zLw2DUpH_6aT9D|NeKo>K`$de@TXjQ~XWb|y&Xfx(NmvU7iXtro!8ZzqtShb*lqA7n zw8~(!1SR0CRfJMCWX0rWy??HlU<5eOjfMbabZWY;*A56gMpK5Wa2zMi1Y9Uch7l;U zD#KQ4?Fyug;e;T|oJ2ufD+EeuD1S78chGUdVuYaU62(IpR|=YBAY7|bM^~00(DiIr z>Lvpb+$aJQ1WnRHqf#!H+cHnmG$~b2%H_%lbcbYUH(%9tC3;}6ImG6W8;>l$U~qjs zl}bax>2NrlT8FpWwg4odX42+iCtvnD8?l`7`y&~aO|#iF3Y&pZ9BG0B0vq{gahzqd zz)=wQJInC-F&^Dx*mOo@(SMaCXi;E}L4gu#ioeH6=V4!>1xn!=0)Mbyz{Cuj6(xcZ zs7u8$>EMFRX-1g!I%WqWm=evy+{OH&z*D@ys{+aM!-+&5?Sv8pP9iTjV{@M5Cq^7! zaGsJ$xarfP2qmyE%?U{rcpjRO&qFVG81~E!ZUBGoc&?#z2}YmQE*6r3*NQ3)6ky;i zo`qa+6Zn-PFs&;z&40;y2Q@sK?dYJ zM&uNNRJa}}P#KDYXC3^i7bA1v4gCgd5 zm7>L+58ropSY+7RdbhPrkR~VQ6S-VI@$rIxwRrl94=#y!hJTSIaveR0Y=yIF_S5eB z@^4216iPPpIVgj_;Cq!F;MogKE8N83x0G2*l4Ir2j`{-%~+BQg=DpzTCf-nmssuSa9c~l05c_I$mNfLGuOEXaTu_UcFHhz z;48?+!X*NS7k_Aq>fC2gpm3@z40r}{7V&AvEo0>QOUinn$PzF+v(_kQ_~T(PSjji# zTb$(odHw0{9}<*-P9MYJS>&JvI9Rpsh3ovY6=Np@kAKf&pu69@V zrZ~ZR#F<(}IUBai$PXvZ5O(l)fNwaSb-Qa;-lMFcH{I@P=u#0{y~zQ0pE(Ubbk`m{ z7#kZK9c&xq0Z4Z9;6O#}+8o8ne{jrz$7>J9Mn~T|GCB&9?m`|ioL}hP=1B6`dsPH7 zy#3F$yhV<^d_D(`z1#e)#Rp}0pMl~2{l8ty{rkwVFbr8(`y+03<9`Bv&C{&|w$uOs N002ovPDHLkV1g8+Rwn=e diff --git a/TMessagesProj/src/main/assets/emoji/0_1571.png b/TMessagesProj/src/main/assets/emoji/0_1571.png index 52b2fb3c3676f5dce75a14f840f6167a05733a30..564ac0d9a0fb8caa2b0a65d7e94941701fb50598 100644 GIT binary patch delta 3208 zcmV;340rR)6N?#;BYy()P)t-sM{rCnCo#*CYS5Hx(wT1!3ku-5iiKZe#E)^*mTJp- zSRof5-@=qBC@9jFYvZ$q;;)JqfWu2kNWVEN&z5Xy!R^tPZr`zn@#@MWM0nSzd&`k$ z->`@v8Wq~5f2V~(ua8O3IW5eQX5g!bBq==KuZQTomm7b-Cx0q5)S7VSxRlqVd(@a} z&5mTZnNG)vUL7GXE-f+CoptQNo$SJ%+^d8eHDXOkNzb@#*u#3)MK0vBjfod4BVd@s zMn%q=ZrG`TU$^Gp$BkfLUyczd(U@)E&zR@Bmfx_49W`L+x|Z0Wcp87g4GIR#j%Lj` zC|I)M95P(bEPo@%uWRSPm(+Gvj2J5AvyT!B1{{95*fKcMKQBXAfIK)i$$eNcE-uzs zI`GM+da1CD5hznnPr8p~H=h>+fc(xgT!K#&i z3wpTi<;2vXc$JBOdRtJ@I4t0td(U`RVt$UusaTyaH-GKs!{1&s%O)4Kfn3M1Xo#Vr zV2Gl6fQ963va{ayQ#h zFgTpm+M#sT!gME%$*gcmuY6nOqLFwP9 z!W=0uRgkt8Cnr*mN~hZ?OM=xNDlc1`a&mGyVW7<|7{;}m{QK$U+L0)JyVWlw>8gE4 zDH_;yS!icxk-W{Inv`0i$w4e8C3CP#S$b@bpR0XGWl>6sbY*v>xr}K`b;s}HAS>M- zDt}xd*-`)i0Frc4PE!CP{xAOiGz1D1ArKt?VkemX{uJu|I$8eywNt+PNBsOk%6d%9 ztXg+^$=SY}`~5g&ru5D3{>1#{Uhq5{{&3^_O8M~FlGN&o-|v`IukRCr#6)n`}}=@tj@AtadzEffg|1W=09B7%abpjZ&acClU8 zy4Ka*bywY5?)JUC%uIR@z4zXG$KHGIz3%RpduC!F$-}V!FL~j~{Bq8D-}f2BGJhz~ z4uT)zlf=lasg4nED6E2RpKE()oI!MIlj}?XS{F zo?$hv;67M&#@)TI@8-<`bHi$eGpFE4@`DFguRa*h;2-Gg)^^{zb>_@~yZf0BOegf8 z2L&8qfwQyok>unf8yR~+7oNG*t$)>a=jZ2BOgeXz@OO5$AJPl$3koR4If#j{i_g#Z z?QGEc=HJSvvTzjNSWqBryxZ6e29?cBWu(;Q>l%8MtOmUf%E+&aw;P$n<^ua6C4o2T zn+--31L0Ap(>F9K36jsMrgIYhn~FZ%F4RY(LAWt`g$49 zR}kkO>riuZe_meyt0%8mLmURe%}1-xcy#Z^fIQ3n^)0dam z2Vcn2a{R|860558%C4*dsDGlrzbmU#Tjk3)c9JF}3;W%H$m{DL5Dl$k*pWZ^_*C^~ zbY&44guF{GZm6pA;TriUVWTE5uP{5iFfUI+J_$k?h=>TE2C=-0=w)SP5iGrrk1u!R zhS@iZ;OP>wFt1SaMz}r5YHUKM>-LExGIqem%Eg_&5fKsdXu)=4M}J3w@LNqG!HOia zC0^?|&K)ys$0Xw7bP+FDWTRfsB71$ibvm7aKsR+3X$Lw*8yS$3}fymzi4@;nFr~ z`jVM8D8d+Q=Umr^87i4d_0ZMzUsFtUbmqRw%DWOZq`ml?EiR12&ZDlbt`Bcy+<5pa zWW^7o#H4R3Ax#RksJ*zjtaLe(!28GJqZjA8{z}Ewb;To((SL#+D~l^CDl6ODD~rpj z%ga8)7zlx?<#rDkkhv>rp0~wXk8~I#s;(}sfItbYttDH%8HgoB+w;tti!0{NU2*YZ z<|7diY$W(w3-7m9mlYRNHC(@6s9DRAGEzix(y#s_`nnV*g#>w;`hy^zLGo1i25H6u|dZ1{aM3Tw{f(jIIXBFlM|KTH+ z@s<&?U=$iLRk`E<>}Mgkf+BkEVku^ zQUgWTs(&RSH``q&PvpSkIXP!f&YwjU7Q(Y2_(_B;99?{P;-z!fAm`3aJRC%o5o^th zDO7u5Yl@0ao;VA@`IAM%yD*r>G|Lkj43pqRO+S3;+?8vmPMx}T?$Y7K81JCGB+*Tw zN#NSPTXg(H&Sl8i^T&(k&qCHpB!Q@zV4Wo2?SF|(r3p&70#&TEf?bk_hNz`}$gKHA zC(q{m{@ZWALnB4QYY@AbY$(HGJEBqKeVRB1#+3^b4^Q_;FfWl;Djv&6)(iu2nIbMz z#4Z#`QESYm;YrG6o(Q_wNF1YyAh>zbkk9~lFMd^ILL47{*9C4~HlAX-9kL|2*|u*9 z2!Bny4@5>ttkMC&cEKnN1T~D|`Bn%oCIkh(&;aS$|v@odpnv(8PIjV(ei4pL85~_73FPvm+g! z_*1;-{ENMjP(SuSj^gl*ifJBWu}B9j*HrsAXoqn3rA)`0ECj|iSQ=Z0^w;+h@`4u zxVpGVB=uk>mQ4^V*(?Ffq*f_rJAarFA|M=ql8U5KFLb;rl*$P(#&D(Bg7BjV*ol-j zAUwvK1rU?rNF}l@8bRIQ*QqzXAVDN;W1a=fKrF5er#b?{d`GMka8Ur@SOApchcGAl zZT-9jq{X@5g(&c7%36z$doGY*QU;@dgp(@s1C9l1aQer+Qx&O#aR^V+aDT2*2eKp@ zGt(U{hV1qe&LJf$;{%)_G0=$n|4$@0?`6{qPcCY8bJQ^NCi9%M;q>VZhALoH3K&Ds u^&fvc#kl$qEE8kZs!7Jxr|+2+@qY#_H_F+b>T&=8002ovPDHLkU;%>k0ATe1 delta 2499 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 N002ovPDHLkV1j?D=Kufz diff --git a/TMessagesProj/src/main/assets/emoji/0_1572.png b/TMessagesProj/src/main/assets/emoji/0_1572.png index 48f8e68826863051e16074f5a7fa31572bd3376e..b5f4437d13b7217a8975b6607dcfa7d050ad5fab 100644 GIT binary patch delta 3221 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 Hu0mjfPC#t_ delta 2003 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 c&9*Y}e~%YM%2Jj!aNgqaQ4GF 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 WAY3l$s)8o~0000 zX*nezekd#|AsXG1VJ#sUDI_N_D=^KGWy_LiFC!eMhD6n!amTG<&!uq|fWzd^oY0qT zTeRfOkZ8+ySgwvpL^3NvGAz%RYa4vI*r|Z?@66kHQ#>psmY#Y%juI&B!Y;8ipec(%_iC2Cw%>f*j4HD1%LjCxy8+{TQQEiKf)d00|U z=h~;aV>p%?9)!8O(Q`%2DHv}}LC3IY4|~BPG+bzZjemrimwJGO(Kag9PC5&ExDkE3 zQGJ}=(2_|;M*;%_T)pvCOG(%*AJIWGDu%#5n99yACaz00UXH4$cUVbSdPFfRT0}bJ zy_Mg#k4Q8vR6jP^sDRwAh1R2aP&_puh{x2Ob4)idCmk0+E+{=ZIyomG6Ald<78Eox zGUUUY;(u8@!-rfwEGD=eDAqqG-_e6OoYmGiCD<|{MmRBQ!R_5qFXgw5Eh;MHu!Px1 zEh>)62?hm|5h!I~U`nRh=x|0amC)A0bhUX=kXwTfo8qK(bBZL4ZV zS5;LoBOAygDBU0{F=3@AQja2q!Z~H9(Jv)4Tz{K*#_Q$UkvyvA>EEc+9xJXHD5n`H z;$}Y{JZ{7rDV!B4<;SCIqrmHcQi&@dC0m|qQ%ZPeT;Zg0S~Db{azyCVxt?Y{^=(mX zjGN51n$d4eyjekJLok-S$e^5*gk37eoqBU{Z{#2=Bxx2`Z%ko@}RD@}vz^wALj z0Dl0IbW%=J0C@iP9}_tQ2?+k15W5yEMO0)`V*bDVf&L)v{4^i_<i!U|{_H9K ztUrv%oWNK8-2Bio{P6bu(8>NrX4s~}l63sNHXHZ;D@$p4=TWvW_~-2H;LnI&)z{_t zu*>d``N~(Xvc}kP{n|x`!>Dn7-l)=@iGSOkm+jcT&ECVzpy%_$&)%%GtnaMHw{8B& zAWEJ900^2%L_t(|UWJxrcoXRs$0uphNs~6Uw4tRgRDh~bS_*~2A`68DF77NWwk~(~ zuJ2WsvAAp1-Cb~Zch{ABzuhwlp-IW~{`)+cx6gUzH^<)dzQ|ai!qCuAp%>ytTz?M8 z8~J~lHg`{6Uf!N98R%FGr#Ssrp!8zy_=JzPng3%`-rO;cERL>!VN+}R;_(O>@%_1{ z;^X6AXK;4+H0y?2TU%)cXPhYZ#AiOsJaOXGsl533Qy)2-K5W%B8%#Yt!^6X^!|6Om z#N1OSGP}Do%gf7Y%2%>>BEhEI(0BYwoB? zVA5%f8iTQ3r!#?48R~*&be0eHSylX@+hTB|ymL+Ht4u_hOa_g<1TZFm)SEmRyx7ty zzTMaVoRsmq`ox2sot+sDi>SWdXw;NQ6f~qBByvv>ei7L{#D8<2nINV8eSdd*BgL;G zNiiA>Be+C@<7%uL;xV$^Bi`Hgth+xSyM4)QesDwG-`ySgfup}z&CQw@*YO)Te*J~w zMt!q^0g;jW?C!p&`hh!yIq&-8J6+wqUpSKCX=uiNz7_PdM4dly>p^R?!OuM+Cb##l z>XP{mcyR}Q0I|(cR^FUu&42a$r?eOO`8V{2KQJ`;grJ~aD|yLGk|bd!597mO-N-T@3a3UiT3q3?%vj%(&UK3z9DfvN2l1s{cklA0 z*2qk;So{)^pc~QTa0F_tMx$3JaD0qLQ?z?TXXl_eGS@1XO4)runS=0eh9eW25g(Mt zD#0+VfQJBLnaF)#e6VKKs?6NmR;#tEH(R`F)tW7@iaIC9ANJY^hy_odISfTbgrU>c zf4Y?|SFzdsUw@i0Eq~N$V(^4JKaR$xZJ)%5Sa-6frsl~5^1+juG8+b}18K z($>o-+rsF#YmV2{ggu=y>Tt@V_V#vwJiO9gTU)!ifN740H-8Kq?f?d@u!{S2apA8b zOntn$_8dUKg~qb|k3Bq@+Ow|izOte%4Aj=993aRE4vTM;;%Zr~<=i<4qO9twLXpA{ z$84hEen?YA8>ph=@Bl%~7CJUNu2@;wSZlFZY8z>UB+7k*2g-;j+tZ z-QrzuyzY0+{HFb1!G$}*ANhF9V_RbJVaF4Z>WsRV+ zvZGa>B;gXb12`g%XefF|d05#5QYu4Yg9*Z(P+kEp@mX3~R#pat%A-}k7ASDFzZ*mV zN!|?jjq>nerR^`|tpFKOM<*2ZgBigptf~Y^WhIU9^nbu539q-PS1>_lMF4^pfI?!0 zv+W5*1vswtTnY$UM~_zh*;^pNqkP>Ylax(B=|F6PK#&*`5=vJT;@|(v^ z@#deO{D0qHjvYC2?AR}p&+nz(h)d>1!=U2LYq@x~^uqrA7fR1wY*|jb;oGf85G z&~x>9ngF5^^LgM#T}-h;lH}>VwgtR6ec-@pV6;qMf}}{sCNw#YkOm@qXF4NRFGd0Y zoUXuF$b#wM#OVV+0;BXyOUpcj6ODVg)YWSWNq@q={L+Rvc;v{zV}~Z6pXm=}GVk`l zl6(<}{0MHGfk;qjH-$?!0;Pm35JBhL5g;34FT_V|*ihhuBFkM7YrWyH$0?C> zIb?Crh}?~?h%W)LZ$q4_81Wi|n9f1C(b4Kuo>N=J#mo>QoQ*RlJ0s@9A(<5wofU&X zHh(WdHtmQ~KrDch!M`BN+sTXB;ejZ!c=Z?r4~h5}D?Mu}!uiA%(Xs@lIwv8TH;M=k zq_?EsOjpE4E^P}8K%pSch_iG_K%TGnxc^MZ#i4804j#OA&4yU$uq=U^+EU?2#`{cX zfd9L#|8}VLUH`@CD>oO+TX_|F3z`#rSbr&4!hDSmzRBiWyFUKR%2wSBb~!A#Ia+Or zUNC1wuh%d0MI3N98(t=p$v1@;$>CY#g7A%!D6kQKkshNc$NXkS6irH_5i?v6o*ohf zmE`N2q*kc4e$0qT!BUx2m4*bUWHM=1giER^g&ND@a&joOS}S5kL}W?fVi1E&oqq_= ziQ&#B7Nw@NJ}5VbezKSm$?&S2AAlrpl1t_6sm`Vpio!|+2sf3YD6N2z0AH8ORs29i zI72R%vjd$?34qYE5S|Z4VcLZ85p4cc#H&aJtN>?|0K>F;5j?f9fUV10!o*N&qouyj%dH2)0X%YJY4XA}t1^2a1~n2*Ef-odJk6IwH1Q?phJwBnr#n z(boh(un=aYNu@Ubg-~7BzTl>+u>^ZWl-7S7M2u86G1P|vaB=&=Y6QzK&kXhmK2FNDOlGmlVR*t2xf1Dewh~h94(0}#v#0|DN z^ILht)`c#;Ur?=mAGKXqs@3zxL41>#_|*y<;(5cH>zz%7w@kOT(+lB_YHSDdy>mtW z&6{7-UZAl9iK>61PUZdwRq}SBZM6d{d3zS~)wS*N<-ggyh`kIer|a*|MGqe>vb`Ab z-J?f~wlgCBdh+DS4*ErO9bl}QVn;1YE%)wO3hnpcd-v}Bg>jR_Dl0nPSm9Xx;FQk= z-&ri17udY`)?#TaWKL)758vCp=f!^i4zNZw>+ic}y=DB+|Q`_54ha%2`6ADyK`{bqn&p9d}wg1jE|J776B(wh6Z6q9{`p7Z=%rES; zBmd7V-=P$;bAJo`@XhVMEiWXw|LnBdrX=dPH3&mLEg`J;$xS>ip&J&97!U^>7JMNa zm?a&ti%|$06{-KzHSEAtY*iHgGM1^5c7MQ{TWvxJZ&YMXMJ)gI*kEii z1~e}ijD#{Ky(BClvxp~WPB|GlZl-h;zN>=VvP?lSC?Z!wM`Sr1oRizq`t$$*05o(` zPE!E;{zv@&ApY;0$6^Znrb#nY*{obW@I#pi|N zvb^Hm?SJC{00xywL_t(|UX_*yQyWPdhR+g`EWlv!Vp#Aw;&`_AcCWi9N9CNe$T{a6 zo%8PfNKg@mER+~tC>~B8ss+W*g+gEn zLgF&I*ZQ#xC<#6-r6*4()B4Ix2dp8xQgC^s+t*rF^a)sZ5E<*~!^!VCoOEE+`oRv# zSbxL`+$DMx6aA5fmU`giwfph-Dc8rv@$j3U>`+!GBQ5 z8qf2Dg)lNd2qjvMyDKFdHIi7@MZ-W)KNu{;*@FazVH3+PUDubhuoZ#`%dnJx^Rz}` zeH5|?3W79v#w^wl1;Qj(_GV`vWRnb$F_f^Fu6_g#HVI+DAj0!uHP`>6BUvDXFoX!Q zsQz)?s-W|?oo}ir%K}73;^+4}zkfZmBzb=@=Q?J^LL#Fkt_?dBxfL_X6$d_!F9WUl= zwhl<7BNB;hY}jnJjXRqYwGzio+;*pN`m%R)%*-q-(1C>Wb6llTnVG4al)tx_+HBwz z&frho^+$2HQYzERxRf0s2 zF*-066Z5-S;4)Lk8Onzm2MXT9Cz!aO%i@F*3r;6ef+#MVD=AMMn4HwOLixSgO5FEE zQP*Ug;&CDiLlTcMPGf`%M@Ef_=&~qEmpPB{ZD;L7Z)09X49f_L0)G|a@IuhiBF4K^ zQJ$z4Fz=vTY2ZBWs@==myhAg7^kKJPwu{GDmi44Hp6+KjFmY7i9g@j|Ke!IOrnu4X z@Cb^es(9KDnJzd~PlD(w4=uv5kgCh!krh`nuPNL;X)JiuLN*31AhB51pym5XNP+vAVv#XN$n5`#!Fp?q{;dAr-1QntwIm;t%ep{A;ENy#L2$ z^rg}s6r9^%zT@M#NN{fT;n%qc!K$VGg5)Ub1z-@1O;@TOFHbN;}E zMN#BEd+*;sM#50TEHUz?nKwGz&q`jex6SMQ^RL&hU;p)|7g8#fqT%pGi4t%~BY#%E z8=WO@TidS0SAJ{dK_;qs@SaFBG?m3ZWB`}N9|w{^L4Ibw|2sD1Ep>bf=W@{EQ!{^S@XlHZFkHR*uZCQ`3XZma8fp7G{)h_x2h*g)QfDHG Qu>b%707*qoM6N<$g8eO8J^%m! diff --git a/TMessagesProj/src/main/assets/emoji/0_1576.png b/TMessagesProj/src/main/assets/emoji/0_1576.png index f6ca6ed5e1ddbaf384df6415468d9365f1918a90..7cd48029d5b28c8288c37988b1d2e5fe390ec63d 100644 GIT binary patch delta 3209 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 Y1z&zX&ZGDx;s5{u07*qoM6N<$f~_aD`~Uy| diff --git a/TMessagesProj/src/main/assets/emoji/0_1577.png b/TMessagesProj/src/main/assets/emoji/0_1577.png index d26888feec0ab0797905ff3d8f3c07379b5a4c2f..a267ec64c4f0280263fc673d157b36a240e936be 100644 GIT binary patch delta 3202 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 delta 2383 zcmV-V39$Bt8QBt$BYyypP)t-sM{rEIMh$Z-6sA26p*;`2O%Am}46s8EvqTS$G!cz8 z64Fo$+g%HjHW0^23*lS}uR;y-XbJjs3bsQF*-{FJG!t?w6=fzBze)|ZM-6l<6MZid zmpKrwLk^}t4~8-k$4(5MJP?mI5zbKy^koa+SPRrs3+!JC*?(9I|Nq^qvF` zB=a;93vrr~C0k1P3t9Kpsxk)FrYT#}DxN2+TP;&5HGhO;AD5dy6WK0KHc&|^1A??> zwnNZVaxA4pON=aA{t07sB$XoBG}bm%>1-_(gVgi6RK><~WD&IkC`Z6Rg%sk6-Gs zcVu%71b;87V1CB}%c(ckd1`U8Y-}x(qZXK=db~7dw+t!9l5(gCIy9$JVwmcDCLPaX zYM5rMs7BnfhP#_DATW5gq18IJT$IeQIu{yPu<3kmmLVlw@feF|SfK-S(b}no)GM3n^(BNbK7T|6xwPbr3^AKIk0B+8xz5psPEQA7 z6^f<6?Cq~=Y?oddX;YsiHew;US(FI_=qW-QDiKadqA*3G7_G{SUm$L+R7!B8LxF@S zQT)w7NBDuWVku5d34t!t8F*t;dij~gDko*D;@q$l$1yf5hc}OKlPpjo>mE%vzs-Yg zQ-8FCyh(NZbmuQ>u{B!nB$tdrZ6#^X+BB*TFSZa=i#^iV+koU#)_xcnU>=9*oM4VIP> z**98AQ>WIq5;+L1*n2p32MADXh6sslYJWj{Wkas1Rjtlrixtsm%otX!tB|6M$q!sw zcDMdl%ezn#qtX%3e=5odqjEt?LWLidAZ9^dXDthmDVJ>1!&M5m-n*48~IdhiVywccpyjxtE3u>7?-*l5IUEbYRb&}1PI7$q|&6){Ray(3{r_f zIsufqufZDucN_GW;A+XWAB?%i7N@AtNEf1yK^Dpj&4eJU1xI{_c^1my(4!C(#$a3j z9czui8yj=dVL+ z371OsW>-jINAq zXk#RWQi$SIfBo3|cFzo9VSl8hP?kwyLX1qq&ZL}50hoge1=GZ$kV_{RQ^9d@_-X4q zbbcyXKMUtPm(;)l%4b|_6)YMC2m&Lb;+{cD(hRh(zI|ZqHPf&mt9gcehB1rLslb$~ z5S7_WD5xNDwhjqQ$vQ8j{P`Vz`|Q9A4aLl1eP&A4%yLi(%-`N11%E{B0w_%DRZV0B z_oq+W@7@?;IsuMR7$$NlDW)}EVY6{gE01Bo3eY-aEe!Xc-&S|0fjcF|_gfweylV}* z%ABR}gSQ$oi?>-)?i&+hFmU)x0)m=B5=o=A8Js1L{)9%BgfPZthaq{7ehx^g7MmU7k@G{!ZSGwL)A*H`#lVIh4<2VV~l$j^F10E!u!7eK@p=pgXs9` zN?M>9-ggoFU|u-wg}b|WI#|6JX?mx@X>NMrkw`d4PFj+~Fn|U3e4e@dj)B|bVy$1a zaswO$XW1hv6!R#@Y!a1Xz+aT$!`uA*{y;J>*Of;xB*Qq4Ie$KLrMx07yaE5dA4;YL z977i_%nv0lNAZAo6P!yxpsDjf=`)xf4xs_efz^3vgyJh2oMRB)dnj-pocG$Jf_s4z zDZ1fMwd>{eS1fkhJpzMn+#Bu;#~1YICI~Tblndv1KkUA|UP!T9FAmQyuV{yQAti^y zeQN=O9(gaka(}!-0@v{8^?LOS!gjH|V?Et~H+~S#aU3`?V;O;S$)$!S9LUD`tINm5 zhx=F=d@>#5<)uRi_#%502E)12hD+c1Lni6IaC6a03#80xdAQo|x7({%>2N(H zXCd7W0v@tr0qS}GK`epR()m_L{vp7!CHgt*A zwle^4T7UYi)E{t)Rg_Arq%|WVyZP1F%}pT5a!S_WLga+iI3jSM7faA8q?D091r(|Fqaa`k&U16O{eF@_#UkfUX%lJ?8)b002ovPDHLkV1fv8 BZgBtr diff --git a/TMessagesProj/src/main/assets/emoji/0_1578.png b/TMessagesProj/src/main/assets/emoji/0_1578.png index 4a242c870696d8f63607dfe3b499cacdae12eec8..0290d53661d0e329295da9484294a88fa8b26ba5 100644 GIT binary patch delta 2813 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 LNkvXXu0mjfbpPVz delta 1538 zcmV+d2L1Wz7?TW;BYyyCP)t-sM{rEEg*~ZwGti|{t$sJSia^GhNu6vfl3^sej6=DK zK);elwunEfdp5m}L#KB$(x+9PY%AfpWznWq(4|$>s#(~tT->x^vxGdvm`lo^P`;5y zxr;%jb~56*W#_+Yh)@^o#BX;#3GY$pcK`qY6m(KfQvgoXf`9%XF#i4zz-F9)jm(>|3jXZ2vxgwD&eG|iXXri zb!#*xhws&Qr>^S{zt`z_QA%BI&94dLrJ4oO>el@V&>y1!1oH7K#%SZ8O$*)rUm)EH zYCe3zyNfXk7=PrBCsw~V#N+WcMCYwBRRvY`Vw|JPaKnv#hK@0kwaGcJj4C+?WrBA$ z5zz-7ciFhikH=%OKqSqGqH6Na+4(Wg^ZTAg+|u-T%+5`dcdCX`f(jl20-DF45x04s z@URQoEHxpEpj1I9g&tDI<3}r_=LcaV=&Fk^RiP3JxqlS@5W-_V{m_jMerTmUJer~^ zCm|-lp7{FSe;3GF3O;2J42ch`qn+mOtTb+#VS`E~ARt$wkK{|3 z9-?eYa(~k|R{9Si*jNpmh-Qk(swe8QFPRa-NLi(gFe{@2s^Y+! zFK2^`03j>06hCi>0D=g7AZp<_=C2dI`3X@{RJy%#o$D{AvYZ7Y_S%2yKfe|w!7Rv)eOBRAZANp3;5Uulm zI)0G^6qM&c+J}j7SLAk^ftcJ`r#1Vt(xj5EgL=0=Y+oVUzbV?_RE!@``AZB=wT# zkjPq_a8e6iTIUEA6H?4YnGN9>@v^qg|9>LTe5Ls0PUoB`hG0Gs0|~)BPsv-Bme6@c z;PoIzU`YIK0x0JfdB-=^QstNam4Fkr>>DUBj~GH%703*mWF;G zp&t@4195t%mZg$+R>TvuOWlPLNYAQjNvV`{W(K(Nv=4Dw5mabdl1s_uKWalXI}tfS zL?Oj!S(K9iDD6dzDHq)$07*qoM6N<$f}s`L5&!@I diff --git a/TMessagesProj/src/main/assets/emoji/0_158.png b/TMessagesProj/src/main/assets/emoji/0_158.png index 75d368376dd21bb21eeeffba214f96c69d3def84..4e4e519d49dbe85a6d0e3591cd8ead0685a2e390 100644 GIT binary patch delta 1052 zcmV+%1mpXN2)PK5EPv3EYVgUY>c5=Zq<_$pZqt`=*`ImUmvGIDX6?kH^UkdI)wAWb zk^0-Z>%g4v$E4q?g~NVV`{2Q_WIwDfTl@e301I?dPE!EG-j-W0i2nZmz8(RnivR!v zo=HSORCr$H*6Wg^AP@y$FDPI)H{JJt);$d&Dy&=1&#gU~Nq;33`D_}<%<%tYS+{MQ z)%kw;sW4Ao!c#`pZJMTSeW9p%o64Ox_Wtn4ad=XLn#kwC`+Js+yo};)P?7y1fwL(` z`5lb#U@T>t%T({o^H>Qam;eEWAlskD&l9pi{|@s$8plUX%tVQIeLLpQr93Y>)M1`X zItdc*nNVM!?SCHpN$8W{Ye}IarsFKJ5(pV{65b^LOeng1xVtaG+R{nrE1|khd+AyhohXme?dmQ5{Trj+pV z!*#?mokjR$%9R*KL8lO7B>V69yUB}#j z2ZTaTIDZ(DeK�?YosN#S$;U^UdI}wuCfN8*5F9L=?18k#4#7mz`>fy#GRs#7q<& zj1-WV6M}g6I!G_g8DVC^0}&#~ytG5=O2gorL2hk{JmDe;;m}g6lar)uHDz$ncYuThWq1xrHOK70LsAZkoB{*mn}0nuWq?@k#PKz18QIuR#YJX+t)gkh zbYw#!M*P%~k&m;-TR*8Kwk%Xc>L_Ph8^l6FUmV{S)uooW#n*L7C6KIj{z}A_m~$0p zq^&SeNr^DwMud*2!im)BAb_Azv!>0rj;cUYNC_y};7u!<9lmgXvOk-IMdJ3TMi38w z+J9T5raSB@jSaC?qE~9Cn|Vk#yCs40G921gAd3BKK#J(+A*bZM!P3liXtVj(1QP_a zbcEuEuk02s+e(V)XTt2?2$)7GqR-6P@U75p2~V|%E=wd5<3xM~I-wNNXC@?fq&@`j z4CPdrf`jn%U;HGeNv3m#C7CT1iGU);;eR12gaAYoE`#a&R6L3z7);|Sb8w=7X~TpF z06`n{^4W07Wu=6mRWR0X(`GfgtSJG3Qk|+rz)pm&5xt=c0;Wj;j2@dt^if7M( zAj=2@44_*y0At4CRn%xo#L8Y74nPfWqt?+{)5MPJ@S`kBt?N2|v#O;B-fP1@kQLv3 WqoKPQ%NV)<0000nN delta 1002 zcmVB{{O|v)(Tv6{5}e~CH%S*|7k`D+d>SqGc(+=`Y$YQ&^H&w1i?V}a3j`R@%@N=3{%6uacha0b_I&UbbV<` z;4FPa02nz%RAP*o5fCb|R|M@QF9XifP`goLPGqE<34cFOtC&ZudMt33ccR`|1j|u0 z6oumJQlwAoNHMR{24pB3mQZpfjm4dU)UJNYe<&tZ^aMa+A-h(wC#1BlOstAKNnUeq zH@m0AGSF(E%vlw;5?b8wbSc(J5le!deV~RKBP z3MoV4;(s8Ny7Rj7KA)f;aCT7R@V5T6DWW=3z2BZRIq)?%3OG;{S{o|F0!1QmoE3B~ zhm)MU0i!t9Y>T_9nxQ~E$8cj%s;4SAuYXEeD@@H$0>tFbd&C4H(HK-68*6G}KqTKO zj2gpo93*6lEk#p|=W=x5=E!*!GzUWXRk2u$uz!^_F>@A?SWas`U`%Jlu&BYXB)aJ; zTs)0}TE%%oY!xBVm?@s;v^{majiZ(5!i*I>h7g52DO|TJZEkh|mUAiite8Pk^bP~N zt%{Uvb#9Cjqag?&7c@@;M6G69&!u-5tzJWPXSlyVqm~{C!FT^K?gdRTlb)XaE?K@J zXnzR*Xc@j$*o?le{_?@KBV31=9v$;|>A1)SNE)JNs3(4tpr28YVMvIc8LK07hV$u< z(L!7>AfiZwPj3jIYqK%fbX-&eO`;kTz?MyHSL+px#ZB*5&U_-j-d-Yn%{)8rr|JD+n!J1bL*`;DAOCs& Y0{p6+vz+ZFO#lD@07*qoM6N<$f=Hyu{Qv*} diff --git a/TMessagesProj/src/main/assets/emoji/0_1580.png b/TMessagesProj/src/main/assets/emoji/0_1580.png index 2603c404e75ac45a69f3d83fccc59fbaa6c63bac..906b5de83f18dc271519f4a758652b12344ea180 100644 GIT binary patch delta 3075 zcmV+e4E*!635XbwBYy(8P)t-sM{rD}aa2MyH!L9>Fdre`Tso<7RdG>IY)VC?Vo0TM zQz;%D8#H1nBp#h@Qz{`Em1InvXirEpD={uOJ1izRDI!@g7&ImxIxQ%eXic4EOUqbF zvyXSCZBnOjRcSvUEh#B2A{;&}B|9o4Krt$&aaJ3F!LEB=Uw^phZ%HvJ9v7x>RikcH zpmJNLBrTwOVy}E%w0~Z(gJxN>;(k&zZX+NtB^za7~G%iawFjqo2J}oB2lxwhfTD*v4w}WDCOgOWBUQ<3bC>|JF zMLIPlA5T0r7Z43vG#Y+XJ4-1K3kU~2APZ(dEWUqPOe`0PUr0SWJ2WyfA&JM_PcLr5 z?bI_ObALxB#vLixL@O*RDUuN=);cC0g~ck4$~m3Z=4wGOme8phC>$9VT{1pj+AV!Z zhICR+Qve|%b`AXg1PK)}Is6v>yZ%4TM_TUfm&}l25BkH-^>kN^^d^Z9%M@_PzPm|d7$IDgiLcQWB+ zTmAsrQdSb2uqL+VXI2FX(~PW)Z+rDUqmfd6FhXAPzz%6aax%+6eKY(mL-yK{k$+c! z3CiFVCOdCitTl3JfjU{b#KETjNo}RO*wuTD@6sHn-K*)`8-==91WKO|{er zrB3$%LvR*}Cp%GHS7+AKG+^og(tlQ$#(~(^oa)xpC~>u1GvIVKJDro0jc#k}2ZYW9 zkp4DMI!7HRZMO%cQmsOPYvmfZ!)=+YB(vXcHX3x4fg&*i;{Fhht%|+vs2L}QZz&YX zqvWvLVcX}OYlz*h|9;dkOi`o5rr|cbJum`YvE#No`RR_=KaDAV8*TngbAQ`$(%TG) z*^a#)D0rn4(wvH!{HX*y7d#dfR|euha;Bf#qYK2N5`KI8w{gQ$A@YA zL5_*cwb>k2l|rFX;kW`<4gey|n@c-r#wbdsWBy3JIRxQASS+>yrkPebyvW@)n-@`1 zwk69);ddcBd%;LG~^>*B)$BY% zdyAtHWUlif~GF ze9oeeR4%p4_2Z&N|H$^;yYjDYJa}dzNy6~FC-n0qE&_V|+?>Y7AD<>C1EF!z!UI#O z^3Vq$p~hf+-qRD>P=CdRNUB_S?m9p|YFyOV*f{5Zv!@JaKI`eZapS=+zuf3)XlS?} zDd0eaxyC1YfdQJcu>04s1(VAuh;%+~2nEQEp3v6E_nlc14#fNT*st~7*B8#2v+#O% z{kQ^u-cZ`ueTeDY(MZP(i6dC#!1e zU?3fU_*0z8Kz|1M(pjUzm5IyhI|0&J&ma<2ZyOr*seufsxYEI@2@sMjgD&IU6-8&` zcrFhR6Tp}NQnq;h+lFRPR90Hml_r(|S}KU6sBJlcnyG#tJp&Fr>fDX2Qn3w9I|X%! zs-|2lMJ3z7*E=SlnKQ#AA6&Zn;>EE8W| zeM|Du44p2%UwZiRW*OLkhK5HPOfu2(_G^9TTkhR!Ip24! z{jf-~joLQt!h>mio;YpBO(0ypaN)wG?_S>AiGmH)s%R4xBS~7#5C#VaS;mrlB$Jxn z(6B;$!G8v%%nz}Vk0b)P)P!Xs`Ae?#UA#AV=g#20i(q3p!jCj$`OQ@XnF#S6M_E+&o2PZlnxF z{tJkfK?VVpJZfJpM);=;M7r-dRE4mJf{innZhv0&BEA5Gx^jUs8WA17_UOD1VhJB9 ziHsy=BA+@6SIrY6C4lgC@dax-J|YoC_AhDoAnv?HEN3!l z?|(k)M1hNkzKF?=du9qIJR^Aoh`9X)&Yj~<;pdo-GlPGSEj^ainF$m!-WU~^^T%K<# znlO=Aad`M4k|gP9ZUiqEOb9n45i{YO8RnY`AxMIjq2a}FVjwZBCkW=`R0JTD(iMn!o)Qo%d{gTQ0yBmnA{j>Q_b8Q0VSl2Z z3k;);>FkL?K|vA96VS#4rBdsU$YkCM-!bVloO^?`lW~y(E45iTy^v^{V7__~Nem#k zdjUOwUL-Jf0O3E8v={;_7Qm{<10n?B)-0{Zzc^PrZ7;&(No+k^5kUmo3uKj6J#!_? zQmayu{H|bziC{lGDvQjL1VOCOs((Ctov2m$Uo$jLm&NWi|B$XaCkP^JfeN|_%2P7m z=)TG{Wl200nX38R1oVK`Rrw(k9Z`-|miVUDo+Rkc7^pasBtHv+IPKDIXA#Q^Tm=Vw zQxyYs1D~_3FA40+Bu>Px?Jn1827&G#cL|U9RFd=;lK#5F6Jhk%<(!D)>wMn4S+|Rc zcCUN04kDjN*XPflm$NRudiE^z-<*hL=gyt$&GtrJ5P4N~_lFGOF-1@qdqV^I8$j RQ{Mmp002ovPDHLkV1g11m4^TT delta 1184 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 QVgLXD07*qoM6N<$f-{;9vj6}9 delta 1300 zcmV+v1?&3m7^Vu4BYyx_P)t-sM{rE!oy+H_(xzLBqf2*)( zmdu5;u4t93T8_VXr|F{6?wr%pf3(|$y6TqB_^#sSk;nC@-QkMD@uJwscdWf{r2Dhx z{o*93>X1tC&2X``DZudujIS<3@$Z)>& zk9xZdM*&3VFq}@$XK#5vPp5#c5*|TD1uzv?3sPVP33DJU)s=)O$nWi(`x_w=B^06{ zmj5h>rPS&$kbj=N_2<90(5FP08fe7Ls##w~~(W>x1 zW;Jjt0Xc`zgbdMIiRVv2VU8Zu@Dgi0Iag(KjgcvyaxwX)`9$%D~S)Gbk}D0ua$zN(9iO5}$#yR+%Wo=eE{|MV%70_Vs7WwPMKn5s_06LXA0s&nuBVn4mNSh~mi}offefC0m~n z^tmWupfA>koS0i8ryQ*e!0z)mWjZMleWt`lSka4hLUZ=-gsmNEax&oKsmSq|kwUv+ zne%L&$j;u*i#>|$1pvJ3BtA1$sV_6yqcK50Tz@(#a-#~CoRG6LR=cqQpYw=-Sg;La zSr#9c;O=3Gerc!&Du@to+Qc{GhNae$IC>>yi%WFQFVWs;ysr9!H!0zJ#_7>@g&HC8 z%TkI=U=hHO7_jReJO2%)vd(i6LvIeec;!s+IhE;W?~nLcjcA5f#jDUpk)(&+JSf3? zCx21WFdwF#2`daLT~#ZG83MLgH;63Dt}Dbh?v7a5o;$~H{wM|LL8aJnO}qoZEFOE zLk~5qM0`h7$b6Kzti&dK5=T~NuLS2-#+C>{iT)swjPUP9{1+l&Bi<0U zD!r;$)AmM$V8rmNadnu25Y!0ZX7EZ7x^8b_jE{ndMf=$T_UloK9Cz2@XE#%Kw>VcN z#ZujRL`yi7aq7DNKGJpf&OP)y>+uZZbiH1?>oiT{IJA7f^nVNGz@GHG7!Bh90000< KMNUMnLSTaLba(#% diff --git a/TMessagesProj/src/main/assets/emoji/0_1583.png b/TMessagesProj/src/main/assets/emoji/0_1583.png index b253a67b6956b018f1315fd22196d88046042434..f75fa362b6ccfd2ed1a363b8f355d6c3c239c32b 100644 GIT binary patch delta 3033 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 delta 1272 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 JPDHLkV1nFl5ZwR( delta 1994 zcmV;*2Q~Qq71s}tBYy#LP)t-sM{rDihn#bRmW!08qOitMV204y;^*qu&)w+X&ZU!> zrFDRvhn~J~eWzb%eP?ZcW|z)EPk2{iiCSH7adwDGRB=gMhhA-&ji=0z%=|eyPH%w5 z*XZwXkl1RZ;Hk>uv&Ph7ZGd5Jzo4_iWr(~^YnfVfq<5aY(tp?DXPeTP#OjB!)N7>P zjj_;&upe)FW})UzQ-6aqJBL6;bUs9=S&Pp;Kb$>UoJLu*NmZ&rOR!K;bWvcBU3Z^2GloY( zSzv*(Lu;&bv-DDk$~#??P=U%sYqop4`#^KCO-z_7KXpxV#6(_*Zj`rGTco$u=&-)T zOJ2f?kD`KpfKq7CfvU?`j`W$n*`1`Z`uh0`0jLiE0Dk~8bW%=J08SVyI^iG-69sI9 zS(Cb=_xsDzaqsV_asJ_=`LXx@o&5Wdz4*%4u+!qv=efbd+`-FChFG-#00rVnL_t(| zUX9oFR~t(d2k-=vY!-K?EzkmOUv=H%?(TxSSO5BVXClCB-%joiIfp%)&wlTnnFTD* zi*h(|QGb+U7(QqUK2X6G{E3UQn3Qw%^VhFmKYmX?1mcabkCO73#~E#ntuo z_1B+1ZO_as(I$lBjr#}Gw{LfMg=5jkH)Hp|e?Le~<>-!A^7*3DWMi^CZbmq_gFjFK z5v?%UrXb({UVHFLQoJGoq%bTHu`#nosB!M%;(y!SMY*gcDl&Xkj@>`BWJJia!~zhD zwdQSR1U<^0K`G3yhf-OBuS!`#5NfQD&}z3euU7&>wmU3lW!?O?xp}Q9_YW*D3C$*} z6^p5iB6|4DuMMw^Qp9GRri5(@gfqp>vA`zQ+<;oco zaDUgBY$&84qFTN#m#g_=CUfrf$}$iXfhcQdIj)qc@jw(6rd+L7t}8&~GuVJyF(2p1 z^;yWL2QM>0kH?cr6@49|TCL_aFb>`4u&7ouf?9MX;_d=>SR z$<*tImzmlKZI)tuDjhDg8}*W51U0Rqxqr2M{w$*ui$J&n^?C-Xwq-_8ySIf%q21o| ztA;2-Bb3mDI8rKmsOD$SXM|CVKqZdWEfzmYLHtPwwTpe z_+&pF0l{A}L_wBio@upWk`MwTWf+FX!!ZjEGEo4c?9x&pLH2rEEjS%nv6xDUihrVn zvJ7J<6JhAX?{cNYtRTTISOJ2Exp?5~s5lbwqDN>ck(XreByC;sO6NfXeg>k+Fg^ld zeQ|P<2EwHp9!MdtI4ty>S3VD_utYw{pbSP75)cA{^MX7HtYgJ{9`yUwppW6ZjgV6$ z{3^=LOL#BS6W;UE-m%MYqZq_-+JEpY;C7D)A*6Y{1?GTAB>X^dgA=L&^XG-w1cjru z&I53AO2Gk%eN1>@5rxkwk7}qgAy`5R z$Gc=WQb4odg-60^55$k+Xn#d~oE{`Lass;(HzEkN9zo3>0)Y>S?$$@l3Ho&yj}tdC z-6v)a;|Ec^sJfmb66s_l3WNuUehSOvVZ49|pU&xH<^=U|c|ROI#svSAh!&18!LhoP zG)~wTn1I7R-6ux-DHwK|Ku{mj=?)=g|3dgUj-9qy%xgS?Uwn9j*MItv=g>GYq3a7I zVrl;*eb6C<{}KU21mBQ|SIbEt{Hh0td0U^jJVivw&2i)uTghbjpfgTkez-?i`vk+< zhe(Ztli}`)u=Zy}9B(a_wL3{fIvI}pT?R~3usfd-fetZ4B*Gm+)(|LQ`A z@NokW!&B)lAv__59|?VwNW4vV$N4wHJqY1^`UAtZ=~V~UqZn7V317-EXumyiJ-*Qn3W z_8Zx{#lfbg+Cz;xyvqnh+qOQu-`RP+IBFg0!$TumA9i*=f8O3+oCASGfHDL{KZo%( ceEE<17mDltmlx1bt^fc407*qoM6N<$f__}TbN~PV diff --git a/TMessagesProj/src/main/assets/emoji/0_1585.png b/TMessagesProj/src/main/assets/emoji/0_1585.png index 8a40a0ada3289d6709ab72122e976138d4e09111..04f027cf4e270f847eaa8c7787ea6bbdc4861762 100644 GIT binary patch delta 2962 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 RG%WxC002ovPDHLkV1kT(H>dyr diff --git a/TMessagesProj/src/main/assets/emoji/0_1586.png b/TMessagesProj/src/main/assets/emoji/0_1586.png index f6c1a2c7782dd948921689dbb7b6eaaf9e4815fe..cb3c9211fffa4b6120f7ff2392e12acaf84fbba9 100644 GIT binary patch delta 2975 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 GcIH1WnFV(M diff --git a/TMessagesProj/src/main/assets/emoji/0_1587.png b/TMessagesProj/src/main/assets/emoji/0_1587.png index 3593e0d54ded0cacb103ea913ef521d77ca261b9..a8566dac42039dcd384df4838269519945bcf8ce 100644 GIT binary patch delta 3173 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 LNkvXXu0mjf^d}9D literal 2521 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 M)zOERY1v@@4YlkdYybcN diff --git a/TMessagesProj/src/main/assets/emoji/0_1588.png b/TMessagesProj/src/main/assets/emoji/0_1588.png index c9d5089edd93c4aa7699ac5b9ff3e0536c716d8f..2e738cdcb843d924259152d2f82c161ee04bb2b0 100644 GIT binary patch delta 3072 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 M07*qoM6N<$f-vYei~s-t delta 2261 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 Z_&?3q$4uA4RXP9w002ovPDHLkV1l!E(bfO} delta 2615 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 Z{%^POi9POv z%7b50>8msU-huzaQi^qaysmBHx}Lxtv*eWk1EEKGLs5-=86eg>NPt6OMahx1V?7 zr5db>XyT+Acv3axq$1&?CgGkW?S75E-dY) zBC{ta<25r zQaOH8J9t1Wb~7S(VoiBsOn_-pgl}1TV@-)*MT&M`dQ&`pQ#*}iNs?+!d{8-fUPza4 zQG8K4oPTy!lYnQMhj68UUZIb7rHq%y|Nlhs|No$I|Jnck|NsC0#{d7b^8dX5|J(nA{Qlp_|FW+A{QqSC zkk{jW0ssI8^+`lQRCob=(FL08Di{Xfy1UZ`N?NFe3&}*s-Dm&nxuJ7}{?Fum@w_-W zkbI$7DwisSDug4I%jF^@m|Cgc(5aUTO@BbG3<4>%8}&|Cr_<|$7Bp!C1Tq+odgJlr zJJZ?;%`(YMvybKr3!}+|5VWKf(~e|M)B2iLSyNfhDC6_RVzb>^^Escbjn;R6h*>7V zCia{k4oe3Mj42oYtUi%~5zJi9ZC>Jflm?c7G6( zn6afeGbg;_F4Kh4mV6OpPQ;@qjADXF9EFH_=0sK;B}Yn52xf53#}}93L`|+PugBu1 zWfJ>Cw_|=Y$Qs3+K*MBA5J~Sy+! zGM5Qt5V%T87rRm_KNy%)4Sc1LCV!>eJ7bD4k5o}?GaIMRr&Fp?B^_&SVX5dds0RAN z_TuH$#y*^G{?3>9}{eR=0cSxz` z-=g#6mv@x;NHi8teDHxU5syV9^H186sdOfrOC%EcLb?b|?n#ztW`!SH$7RdXI^!|JfFS9XUG2v1 zh}EoWvRrE#(AG?GJ>o)a%vC0qE_dkhc-)ajhV||T9|h*`PQ;Hk^M4}GIRb00ZT;X| zav_!} zCWI^Ngn;m@Xy!l1l^ki;g6upf4_w>wbLd9gjIp~2TDHPcz)P?1Ye#^30WSE zG~2L-@Ew9KpF(|=e+a>n6`_i2hy5UhL(dPM1-R2feb3gl5k%905a$0t&=W5d<3CFt zm?{`7DPrxgcwWKOAFrPMkinhK`-C9Tr-bLok3L$2!3>380e>N?B!pNidQL;w_w-DG z{(f}o83N(N2I9gqA4X_liK2cy_tXy^LKICPQg9C9XY;y1;c$`=5V#%$LV%2pk3+e? zVfh2$#34NA$LRR{@sT-4J_BKpi%A^9`zi8QDm&g8VUjomthdm@Lm6b|$@tbUudc6e zNUpE1uA*eM;D3)QxifMc-EOU~=cid;--=9^0jm7{FcLoW)@w%VBFk+Uj03p#zC&qK z<}Ur-@PzDH_yVPal)Mac%*=K;xn4gh%=w$?XO@I7s#I^JQVmE7PZ&agQNVgf5CuV! zBmpAjNPFS&hsu&De|Y)wA0bjHnGo`vxPATP@ncMsI)9=fVnTuuA<(l=#V17oO$ddi$yH#;LYObS__!io{;MKF$hIvv7{_p3oe*%n zg$mIH&-WGSH%MSGWD9luY4t1$6q*qR&+84#u>;;nVPY9p45Ltyn2zVuguuDl{61%d z4TP47_kR#d(oJZ|YI~tC3ct~z00GBpYHS3&y-DPNh-isDhX{b^89}h0P}^SOE60ew zJpiI)?jh(1h|bU9jGzt^?qDz{+#O;RDIE@oP!WbFi296>dz(ZTh&J_`PD1)PaWOEQ zpNugWY!e!-2^F+_}V7JtF*C%Txh2+=-Bu>F7#4|;GB=@$gIiUk4fF zR(}k_K$Ja4`YR654Ohq-iQ@%Az&0f3>R44nq|({sMI+B(n?0p`pdn^Jd^^6J=UJVx z4PW~DFTnc3%!1J_nWfp6*T?5GiZlKgAhp)IGQ=9e3Vk{oCI?~CH6kFarDD48%oPo; zsRd9pIcClde{=5L-&H}79NDP))vC%6s+-J|FZnAW&T*-X`glF(r9@X00000NkvXX Hu0mjfydNU= delta 1559 zcmV+y2I%?W6sHW3BYy!hP)t-sM{rEEGzRCpEWjNGy&ea@JqV{U3Bhg=vN#Rfm=?<- z3cwx)?Z!2W5(B_n1iD=YtsVrmPXW<_57%@U&xjG{zb)5+6#D02#$5u$PzB6o1g#nb z->fFykQv*L75I)r&L0J@8U)ZE2iUG0#~ugRCJfIW1-~5z%zu3cv}+9Ky*l#hScxYA z`~PmmUIfZz1=Vl}+j|bUR0HEH5wuMM@uw)!X$8?F3hY57+awFkYX{bL4B2%I=Z_k` zSp(pM66~KM>X#tph#B905ctwP@|+_1!Z+TsA=)ev^sX)TxH9Q98>&SD@=Y+c8wJmD z43!oIqZbCBHh%)ilN7}s2mInk?o27*JQ>uT8d?tn+msXLVj9GT5%gF#iWUTT5Cr;T zI)pz5xNr}lUJR^j68WS>B(XUx0000kbW%=J05bi%{ZSkS5hDKP{+N23s@pxvk(T`Y z>cP9rQQ~+0g4U$6&+uo*Ud87^>8TpcyQlyF1a?V8L4Q9}{H)X)D*12y@9& z@5{!0c%kT?P(Rv}_BwY#3Z$Eg?z;^KS~)VqkbfPzllI-+nz$Z|nW)3Z@UpsTA8u%B zT?GUPC{ZJgMC^xR=x^2ueYJ2x-;$@lh{v%QMIw?yQFJ!Elj?0FTX41Mx(t}db>Ku< zh>)96w}%@q$novhq6|h`fm$NUO+$}+c|N)zTD8iXnye_(M7ev67M|%DPxJY2J7g*S z!GAZCWIAa-#$8rttoi(53nEDpMQJZ*NW*Bb6`{(tDXhqHXd&Evnm^o=5{0@vO7boB zh9^$Enr}f=K96LcZ#IFTs8)a$}5XsM1P-<_>`z} zlH|n8>+8$Y76ko|(Mxq5;!R>LP^qFe`oSCi&) zIE-T|p0ytOpDRQ}sm8Af-iU)ngK}-|q5qML_`v6ZO6-M`rlM=(`~Jr=;qwL|k@@N3 zL#Ir~W%gI>KrMnL3R!m~p!g*YbLA|+(V2u8YCxuOVFn18;| zE0&0MOqOe-QKC*~-B5%8VG$DVN25`(rmD-C9y)8nM!nG|0;2r;s8}qjD)eE8jw3p* zY2)7L0})Z|bZW9Xjk~7nI?gu4`%Y&h%c?nKfN(+ZeB3ME5Y3`ftkvXc{Op@1AZy~j zb3?Fa^nMZMDVsCwd7hcaW)Z9^8GixBGDe2&*v{c;sXh>8VcAjbPeSO!{kJ--?h96eUV+{_W7zI_pk=Fbe=qa13+dvlMrNG;|~A;002ov JPDHLkV1l$2-ktye diff --git a/TMessagesProj/src/main/assets/emoji/0_1592.png b/TMessagesProj/src/main/assets/emoji/0_1592.png index 839493114a38eaa5660bbc60f6c1d19e22d725c7..89af54b5c7f5df8e85aeb0dba2e68d166fd415c2 100644 GIT binary patch delta 2658 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 Q{{R3007*qoM6N<$f)pAba{vGU delta 1242 zcmV<01SR|G6zvI+BYyyyP)t-sM{rC6HB$pQRR%m-0xnVkKw&nmr5Ids12a)HwyFU^ zU^B3(FRG#}siQBjs4}stFRrC5tE2=#Spqm$3Tu4=Pj4celm(BH1A>eKa)bnXg(Iw< z1dNUZV|D{nYXU`JDYByjh>!-9k^*dh0eX!FnUtf}*Sgx@jepC{P@}9f!L8Ek?<>2e zX3W1hj-6S#w=ln{e6_$FhLI~G7Z3md02g#pPE!DY%brYV$`LF6^DFpCf@kEU=Bwhx z`@e=SO#lD`>`6pHRCr#M)@O60NDv0##UP_#$w~IaKu*f~|3B`!8Q3$ctE2ZtB~|g^ zsqUTu&9DE=@_+R`i2t}1?zV7?nrL6jbu=YHTe45G5kJW?cZ=!0FQ-eppc2au4Mgw< z>v)-m-qHC9MR)5a$`Kwbo2pE`oRzcz!1582?%<<2VZT z07@i?^Nc?w3YmuPOTORlB`bX!5WAp_f`h;`tcuAw%Q7a7(V6ZI+UANZ)_^IsG?-jw z5S;-++gyP`!5fhA8xckv#;5c|`7;?J&|PXH%Esa;L*db2EKN;7nC2b`Fnr44!Z0AX z3<*TrdVgaQFKB*mp6BPeeQA0F6mZ55Lm=g8Lm`&mm-@`pG-Z0cG)sMoTfKUpZ)EeP zn(7Y5LwM01PHIP3k!Q84Zv}@y;r%zHNQDMKSp#qH0uv)1+jVfYDT9BA9c1QHnNA+~U3y|<^GvE63KB0gd>^xN4&0C7Gv$AsQU{G6!dc&zHXoHl8cDOI%>IsI?BS9=<>xJvJI$Ssa-hZf&pqBBz^1?`D*-rwD?fhd3MO+6WW#eBV z5?$A=fS7$)cPlj^*bm~`K_|zz&Fr@F!ay)zMLJZ0#%eeB#zLZ-5IBpW3Y^B=Km#Ka z06fu-E0U)DqIMW%*317T7S5T$sDaQL0NwA4#uMMp&7IgjowEuH?&`w}$IXcXzkeYC z#@)GfGwXAN%MqX_ z!hPxuYi&3Ys9AnmXT0$7Fa~-d4vF<+3G~DZ%*-7B0Xd@5PV`B)#{d8T07*qoM6N<$ Eg6}^(A^-pY diff --git a/TMessagesProj/src/main/assets/emoji/0_1593.png b/TMessagesProj/src/main/assets/emoji/0_1593.png index 445192925022fbc4e714fcdf0ee5adab59317219..cba825fcf697218e41f58819e16ae266392431f4 100644 GIT binary patch delta 2979 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 Z{U6qrheXV4hROf{002ovPDHLkV1l5b^k)D7 delta 825 zcmV-91IGNQ7taQeBYyy#P)t-sM{rCcKVcLxRv9!_D_E0iRze>)RXJpxLrPOUMNk(v zVRK$fCrWn}D??dGI1?y85;9&DHd!84jU_TTtp;FbTC?y z3^8F3IBgO@dJi^e5Il1YE?gKXMg$&41|?7mDpnFif+8(MB!5hU6Gwhw zjdNLXT0|5|jWjesR9$z0XH9TgS-)P7!vFvP9CT7nQvhGIq5gzK{u3(3t&+%^e(~jL z%l6pf@%mBL$g#Md-~a#uMoC0LRCr$P)7fsLFcg4cc5D(R5Flw<@2uIn&HKOG9NVBU z>Qt?oo4MeRB7YR&d^)zk`MRa0rKP2%rKP1Mgzgp|<2AmMNJS8@qkBfdxs)u3pWL4# zE}@)|A&#GZyq^uBf(cFm34Hf^3SPT&!q-IC86+60@0ky_&A<$s2-wvpA^#h)^K_Jr5lyE@^k{J zS4y?;>3@4U#6#0iAq3@==B_3hX^ak#<2)uPWuU~D%jNgjKO=9ICH>H9EX1m~+- zYp`zKxQGx6(*R@&f`L)JZ4(%rkOVn+-+-YJ!R85*S!M4EsuOG+Rui1aHp31|;cN}U zIlaXxx4{p46=u+*%?<%VyT|%4zyL&&Pvb;WLVqKgu~Sk#LsOrDi1u||H}hH`P0~iJ zKFw*i#4Vu871B>euT1?d1=Tw6rVKVEWvhYnZmR_+e1E@Qukf|KKR*{mvD=mQiLj6z zZK{FlxleRz29Ki)01@cw$U>U`#Kz}kVf>=L#Pd7g`G48^i zep5T?znl<5d`VetJ1Qr4VN6FYEU|iAN;WL2bXk)O3OF$?-=~2QJ$GgY1FUmb?7*G0 zdR>lWM`Bu9cPt(SI&&03c@IEzJTowWR5|U$p@C{tieN~+iE8M+nq)j82|RSKcUoEq z1U@hBY&p8eF3_Mex*(6r96wD`Hu{`~~pO#lD~ z@_$K0K~#8Njn@TR8`&BM@F4*v0>NF1ltPO;6{OD6Qrm6!R<`Zx?b>x_ChG2jySuy8 zUBAOlF#Qy7IU$Eg@>{d5)xRU9L#U!@CQ7V zRgCWuLKA97P}QCb^e1HJ4p>ns6jnv#9)F>B#JJ_D!z@Ms56+z*Q$V%0j*X4A=6DM! z`SEYJ-a@(K-^9l==ZJ($=jX>-Tj}E!Z{qe_yM5)2+he>5VG=l5^FfQcXTwtI!ooA@ z{0;BEom+7m->j@af_OMw*I`+>!SyEM*)F4QXlO`ibV=g>&O~7Ml@`s+n%Qh#o6*E6@8e#4 z$d<&-8v(+_bF+<%6A|#0<~7k;pSkaYe$y=E3%mk`Z1s1DWI#L=DTj;~1q?(|t)_48 zT?Y{2cgj9x{Q<9g8s%P_c_&*PT7P~0ZfcEpH-#z1?@h#qRWlIgRSU6t&pSmv@8PCy zt!b!fO}E-4k7ew|FGp>J*-XGs9}#!-7jHg+$L=5M_xwuaM{p)0={Flie0ccq;Rk}U zUEdWp^x_5pF1ZU3_FX^Ul7>agoB|f7LS$KN*v-cn$bN~zZIJYnBZ(Mu34gBJItF>e zyg{|?-k#}lV>kL;_A&cNKRY%6^HZt!EQG~oA*iEY?&UKMvq`pVgJgdZgZV2w_4*>L z@5TS6?&mXNM>g1OS1kzsE2ilv)HlBTQaP0IfnR`=ar@V6pW>* ze%x@mHqP9+bBx0zaR2r4>3^&7my704%gZlbJo>@AYsYRbEjfEXl4MbvbLpo-rls}c z`0UeH>!w?akCxY8yjXwq!%mLio6e=BrQTlU$9C0{)7f5#`xGua#-D&O`{dQj^%v{w zj~-pyZX90N>jcB8`pMbuboQ#+yHEQP@E=X4P7@fYp1xeZw!FOkSbsRy-mB`Jn3!0a zm~c+0RBdhDg}&MmTxsfR>4Y3em>qX$9m|!ae}qt}y4%4()vIco?rA%9%m)#0t1~RD z63yl5?CiLyD{OT6R>)`KA4T1bZ7SM8vuK?Dt|;3FkrchS6*k%l#_W@ElS8XzFH+|{ zT@%!h`p4bvs$M8ndw*L`W1Ws{@Ih2lX3O&yhiUu?2%VMMlW}Gu?f^|(l8|IwPa85+ z5MufVXFj1^O!zU0k53cD}M;03Cfc8{b;45vl9d$ z!ZI$Pm*Cr*E|HKGg+1M1fY9C3cqSrULYAfMA<``Hk*WU#0t|WXB8oPYFWweW~Q6TArXH?J5tG_x9{lvua> z`SX(}PdLSo9W!^C$FTIpQqj+*T4@wRPny8Mu z5N&HfdWlFc5{ZI>MCdOf@CxtcRc$GNc_2dmnJ@y8fKn8c{a%oU^b-A?9)uv;VWI5F z$z>JW#DDqdwDSTW0;A*xgPa$|Gd9Bk5lP>k_^p5rSU;uI=nt|li%mp1RnNq@p5)pypCz5x1k%nV5akyEhGw@ik z%|czX9EhEYm{W_@Q$dL(%GXMf=&I)gXa9p72!A0EG5J1-DRqZh6T}LiQP1c_2Qh{M zVp1qHL#XpRaz2gKxFLX3#OaHab7pAa%2LPLBI8u5FvrX=MM z5L2RqxIaP$M8bX|M$_?LJXOLyq!a^j$R9EInUGBycM&WlBEs>5O0inwkN8RlL~KAp zvwuvcGoJH7U{^IX!TE~>zK=MBB~JY%f}7YZ8)P6@bBGA{LkK;DK{zNh9NAAC#8`U& zM8+40$mg&;1ZNi^rimCt==~A0L75?+6JrDlh{)e2jMQU)O>^BHVXuYceu z_HgF2%-ro=CLU=W7_cgknPY|F!r5S-0?voew%f0uVU|=nEVW1O%usg9`d*6k!yvWjx};;c*XZlH?mwRE$7n_v$J5Fm9xzkS6LNj;S?HX vowX{e;FRwi!NCEX&(UG*y?(gNrxyMX-kI4C6~#*0`%Lqw*SqScmPzM!PK77}n= zTuw+wH#9T8gMmssJBv#)#B69RDJfV*L^(7xEGQ_tS4=Q2F65bw!(CIiDI#KDU+A5D zFD)&RZ(?JF>XdJS~w=f5f0@tF7-@E(k3G4B_Z1z7fw)6=RG;h8W!CP2+alrtOf+c z1p-nsAxJJAG%YNTUOeOt3w%*DWI!nJF)rIGCg&R$wFLt`CL0V23iLlbqb49C8yaRP zB$-q;wLdh16Mqq!3<=vbEz3YMqggqBCL+BB0+(Yy?MX$tfl$&93$J)fo@he%U|WS) zH>GbzqXYwCMn-=~E?{J2R}v8TWnx_(VA%iw04;PlZNA$8>~PX0vI zG=+5hz(>^jMUks#ccYTWu9L>7ZfxVZ>cqauK=?rb0DlFBNklzQ5l3_TjC9FP@Kc)w}Y|<<|b&+HoD7<*$Zd+?DUQK7Dvw z8~J=zxqsuTB*^y1%?0|8JP?@?M{?X;Z*SgA7(-;UTA4@V{0#>EMI=OK#-UL@zrWr- z+03B-6hXMU$~K2U5aV)tpWcM<#6>ZC1%)xJRyH*JZczk4(=yFD&snW(z29WFUqmsj zXbnx%D$}aj3dVTv+lWx6k|9Z|)|}UtF}6Rs?0*yP^z=ezWw|RgryRCIVr;$Nw@n1& z;*@0>hGn~|IY&G4J(H2R_NoAVKBE)3|m)+H69I!0TZ?T zv>dd12F8FKvO41-28XRc4BK1rJNuS_F`fjBVJ+6?1*82sF<6{OR~;1vGLDTV8umK% zc7IPo17b|MBFVAYM3Wtdvz==gG9X=bw^|TLD`cW6o5SdII?jQppuwuM`)a{z1!H(@ z5w1|D)7QtQ(QRDcaD~<7_-rpm1Y%H+xpc!|VXwP4!8@TA$s_ zpM*_gcpM#==wnVyOEM!*=W`OnGPZ-ZjDJ|CQ=;@m9%3*|eKa4E7*;DMv>hS}DJUId z7%*LP%oupVY~3$^zwe-&WEwKVO7r266Zoa^&CdM_I~+(1S|UF8-O&&_!MkA@ zAMMQ3TLQvKO-LtlV?GSj1m1cz!40#qSUN_PO4QfmvDry|Gz>fmXpr~H&E*Mgi+`Y~ zgHzH8-cTTFaLvtml+Q11w35UW2fnWlq!U&h1p<6Qr~y)~VmG_5Z{+}q9T#>Y$t+vf zu#+Mh7^KRb@A>Qz?{)@fB3^R2sRW+*VnMJFo-gmcc1aJB@V`qGa-w3etX!|epLl^7 zh`_JAy%haAk$~lrwX$rtnd$MhB7YcwV8MRoN5S7A5tE=}FpTL1iIM5m3hiP65KurW z6!^eV%Jq993^RGbVPFikQt8!-Xdr?@5km3DDc>u^X}g8Pz!=R+#XV@Z;hb4$04bC| z`{-X0ULeAy2@vw%MtadkWC^s}g~iDDeiB^M&rZoCTp_#}uvTaVjfyxPz<)__02&My zaYfV8X=Sz-Tu*r5rYB#>JQ>T#fRc9ipyF|5D%GV%LrIGwAVZz`^}1mg(iDue+wE4qr|9)WqBKdvlZNkk1`HJpR5GYYl7R^3IBU7xKLv@F946uM z;`;;$C@@GfW@#Bs1;uP7e}C4>x&J+psKX-Y*b96(u|IzNK!YG^bIDw3Q1FSG2Z9*B zH3YPTodEGSf?r|XdRI3~*NW)(OCj=S!a2ZK(yfIMhFMCI+Q6-f zA`%b1(eA31oqoS>67(^ZgQZFG5?K{eU|n1oio2D2c$kcKKdy+91Ahsk>4Q9c4r`Jj zGsxU7nWe;DC~gQb=>b8nAv|C8ah80QYpT?hWfuD&C(RU)VTvIvVl|5;fid(+KAQyu z98JSjE(d@A3-7|2m(dH z3&Y`vMG^qKUbM#_J&c9CUMCb-@Z0N+B@d(iFpl4Tc|3`oNGBw67>Vxq{bA2$hgTb? cq1K=M3k2=m$NL;Ovj6}907*qoM6N<$g7JY$y#N3J diff --git a/TMessagesProj/src/main/assets/emoji/0_1595.png b/TMessagesProj/src/main/assets/emoji/0_1595.png index 3ea4c760b2407d5a88b0da4194702a82061d87ed..db59963f8e7f7798c68844768648d6d6dd93aa22 100644 GIT binary patch delta 2777 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 delta 1153 zcmV-{1b+MA6_p8)BYyysP)t-sM{rERrHs_Jnte_;rG{*PRX=n=DX)`xfK4=-dSaY< zV0=_ScSSGEu90#(IB#q<+GkdZc|` zu!(59n0K3WR<@CG%dU@*WJu4nmCmY!*1DYQ%&hOxv)sU;(tom!)VG$=u8GH~io&9U z_1(qt*SqJ&qu#obFbAZ{0000PbW%=J077Mo{$%_P`XE#~vzpW6&(DIRqunm`OxIRCr$P)#q;GMid2Li={)^-K}nudfinT*xO$f0f>J{AE+3J)2%aJik}Dvb(Tqq@ zoSq<(Lo5~60HY;JQE%+;E()?g5xY1}85&*JwT&wRMt{9eW+EuR|Fqd((xkEBqtUdK zd!zWAjO@ECtG|CgpOA4b(^M))OhykqCgW6<*K1k*TK%37Q~|=kz#hZBk^DNBB_LJx zxjd4!1cFd*Vk2^AG>^vWa;YkZlogC*nQ&W51%o1sJwDHu5veXqtJydr&p}a8gmyTP zaURF)Er0nwpAqpzDqt50Z$u_F3V_kj&RDHL7!gnw_GXKO3peJFj)oeIqZbfCqdYwj z?-QYn+=MCby4)>?d&9OB-1>m@_XEj1(Zd|IBi`02Z-4{E8`@TA%*drC!2;oj=m}?Z zz7%mr-&QVnh}HK*;t6Q38zq4l4MK9^p1J~xdw*k6s$n?Y6Mu2q<4y`spaB9Q3XJ-C zeL!j@9_Hx?0CZ!OWI%XB0RZ7l)L;POSA&XW>S0^I7!V*djX(ktrotPP4FwuAauz1~ z*q?%6mHn51`)y;9K*Lbt4PAh7k0`0MJ6Ie)R}-PV07Ntr$Nv6JFtnsttErSOb8f*j07EAsNziRX97ZJ0=Gr=b~Z*t$w*;1W6ZbMN~+t1 z7H*_S%tatYBqQ#_n3VLx_0FU~qMe9&q<7u@tjGg?cBj z1skv5#l}dVc(?enI;2eW7NckmgnLS_#Kh}q>~Wm>pTqJya~r0qVQT2L)*^>l!VoAk z@ow&%ZPyqOmXn3M128^P8k45!Aq3zt$ucnipKu2`z;76?w|MpQNs=sq+}ZyCYPHlI Tz?W5C00000NkvXXu0mjfmL?$^ diff --git a/TMessagesProj/src/main/assets/emoji/0_1596.png b/TMessagesProj/src/main/assets/emoji/0_1596.png index 1a661ade4c1e2a56caa80314984f3f8e2cf455f5..898e9a71fe424f9c25638094e8a3e10430fbea1a 100644 GIT binary patch delta 2636 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 AtpET3 delta 1614 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 RMT7tV002ovPDHLkV1oA#`#1mq delta 1270 zcmVd7a3n0@JO;5aueHO>L^K7Zum<2Ro&RD|FI6cef4j^%O~dTzZknu45lx;r-ACl`w(*W z+oy$B@F8Mf@PFg*Y!4)a;CpF^wN9;G=BMGR0i0YYDYzk5kL}Yx9*qP!Z zvLFQPe;p(X!6J2mGKhKk^)gvVI);cIAxBi3$0Ua(9ldx@F<7mU2#*SaQM>zuuOFYg z`5e%r2wlK{h&~4_8(Hgq3m*LE+=}-f9x<`dSpZ{-$$u(%wXI}Lz%`6^8y5V#PB-PgiTVK1ZP1ArBtThoclgQ z2-8HhHOX0<$RWXXC~XK*2;jm<#FUW1cTQ_d3=uNPXc*Ni=tC|syi5w&cywfF>ZFlL zMuQ2^eSa!_3=Ei9C`QtaYoY-`09aro7c+5v z98WP9UVUmg4<;-~83{8Nzz|b_KNG~ssKIC)6HU|cT6v#*@T~55!cgLm#`~#msf_}N zk@|2AmFI9Gf4b{5SLA-+r$nnuUE6HPkUoU4)_-wzQbIt4pY^=H2*kexH0WdCU@|3ny8`$Z_~&6ZCyff2N3PU7vg&GL0=6T1y_h z6^+3r&*#?cr;Y3RZrE0$kk5~mlC}~0*O{CAcnV~cyK#?H^5jfnr?%CMaji!q$ZCa< zrRsse{&R*{?XPuW1MbH~AX4lQt?I-3?0*B}`eMc4QQEd05^-)YLNQC8eyX=7D>7)5 zAybZm7Go2)5lmk2&~U8fIt3YJG#KGY_%_|n6V+M{o$;eFu0&HKL1kn3=9%wf{RM0! z8D%tB;jJuv{5hU5lc67RbQYBfLM(ZTQTeQLR>trVSZXBd1KnQ(vVT&H zC^9ztB}VnW*6O>FiW;i0A(74_*Bcq384Z^V19>nOzOL|czZ(|RSc{G7cs+xH*xn6| z4`b;o&*6ARWgbQs%xEl)L%!?CMgtreG(AG!j9wP+sn@h0CR3z_yR` z5`ct)L@chix}#y-w*wQ= zK!`{Iz8*_mKFvu(fv8>MY>Z#;&%Da7*XLXE02sU5<{907*qoM6N<$g4*+KG5`Po diff --git a/TMessagesProj/src/main/assets/emoji/0_1599.png b/TMessagesProj/src/main/assets/emoji/0_1599.png index 48679d00e9d82288c82ea8434c79bd0383fca142..228b0446fd185446e4522acbee83564f69a18844 100644 GIT binary patch delta 2744 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 At^fc4 delta 2225 zcmV;i2u}Ca4!seOB!5IuOjJcja7>gL48CUyvSbpAMjgiw2C8NoMKn5LE+f|y3yK;K zv|T9P6Yb>{(IKg&WW!6u4y#$!7(=Q3m9f8LJWrwigcUhzP3=1)mrR)rJ_` zcL~ZO7M~FbtV99+nh^i8Apfos{<=CG0sr}&|G_o?`lkQMINpQ^@stUHNC$E{1N_Y^?t=u=Yy|y* zc>U&SoMjQPb{D>uEzhk!`*3I9OAY_c$mp;${gH|P?t%ZIo9R9^>&-rpR0jPk9{p2B z|EV16m=FKpFMt1{7yrBq`rttS_+S4wDgXPj{?}3e&^G@+G5_m9{9{=E`GwhzBmeMB z|Fp2_*I)nr&fCIM=VuGIF$(|qcmMv||M=_w&k@RKDCMmUjsO4vAaqhrQvhYnhBN+K z3mE-Jp!WXx{gKYL?)}Mqx9r%SsM)5C{2(eN=>Px+2!BaLK~#8N)t6Ow<46!j$Bvnu zILRcL%*x2j%nV^>9{T_9`&GAO%l7O!dv>1oO0k_**G;v$TPc6~KcHp&SAkBYvDx-E z!Jf^gQR!w@!`7DJUs!b-+omOO_EW?cux##Wm_@g39gRBsFzOWh+gqxC5U6aMV)zMz zY0g}mHh%iv<3Qhivo}M6-$d-3du7HidaGsMQ7o>sNd2 zx!3zKvg=lF;2IP7zg>O*A>(^=cn8T@ciidR6Q08w7>ve>l@vBzXJ_49UN@Q4K^5V(%EztNE#-(lHx)7&7?m#;0iJSUo90vy;6AbcU2(DZm48Jj; zS%qI2zVsbxy~m?h!yv=vJw3aw6BqSKyMNVcwO_aiF1!#gta*YC{l^crUTx|cSCY6U z$91bwN)e@2{hN%7c9AzvTa#-zOdr+v4b{S(5M0*;>sTrli}18BWW3FqQ^i)_^6MiW zf3K{`_Qn_C)J=vaIy74Cx0jc$$B7`>#pxt_G2E}rg)r{970b9U*i?e6#8PQkk;8MI%#f-{rL z<<8H~L+5}T%a%KCIOpVYnM_c?NM`d<2s<-y+}zxR;PAt-if9Oh&?`p@cewCbHMtwql#(JC^fAiiG9)Be1PT)1vX6kl z87R!A)kq3BIIy56ndF9(GIJwd>gRMK3vq#J*P#eFi6bYe0*}opmeI6XKH>PwV#A}; z7v%jw0E%_3OmQUQ48*Z`N+6YLp7>Ab3^k;dV*bb_^(2K-R46Nj2sus}O@FN9DWg>4 zY4|6l5^uo*ukv1`h%70nT>z0185+d2g$x)i)>xg|$OM&{s2R5d&Y`v4W(bEn%yF*q2E2IhjBlHkBI2MRct zBpitx=i?iE99v@qqVO7Jt-GKYg$7w#OM8~6`Od%Q@` znm(lv=vtq9&(`AvNKqvf6hGMV!Z@-ucTB&%?na(9FSakx1-Ae=sY+FM(NJDk)5Q zy?R%t*oepTq9hUtLqtRfc=Ha^VgbJYNseJhy`#gMvVST`NCOeTJBY>N4phGK0vt&! zIJOO>(yeW92`qDBAfJyr{^FHya-{(0NH$~zQy-511sPd00000NkvXXu0mjf%!N!o diff --git a/TMessagesProj/src/main/assets/emoji/0_160.png b/TMessagesProj/src/main/assets/emoji/0_160.png index 0ad3bdd368c9dadcf32a42abc645031d70f7047f..1f0750bd0b76031a073b3a836b8f0527a5ae8814 100644 GIT binary patch delta 1004 zcmV$0OL6a`>SjKIEeNx%QI4x4SFLVrBzp83 zo#}rR{~w2k$Kx@(m*V}OdVXH0P${%H~67o_`E8aaz%gd*;K9aVO|!;!*aB2ZAusb0^|{!0w`i8l2=aQ81QkVy45% zEPMB8gypvh$nk=R2LgT~DC6E;5?m0WBLeJ1Ne6(oPCcP)L zBZfW9l@ZodZ)g!;SF>=+dJXAR_E)V}C!NN0p?{{g4~&4_mVKGXGpyYC1(q!Mjyq=svRMbtPG za$XLnJ$C_Ejhwd4ZB#cE;&TnRlooT0z?6UGoGd8aR0?r)=VxRCDq=OnjCXSEY7k2p z35(U(dK?fjVsFtc#^ZT3;BBO;WP>tL`AR&uo_~g@5fL#dq{?Z}7vOj%=BEjkR}&G5 z7OYN3NKc#}i1&(!GMmKbziI#02{w-&v5m zKP@LSBpoCf5*3?)=>Px#2y{|TQve>1&t^un=s<@wZU6uRz)3_wRCwCemy43yDhxo) z)9B&<|J{oe5)njtFU4uAXuij2)*ZgV;PL_wxNSp|Ha(_AFcm&Go4L|_7d-XZ`oV@IzeIK_$6 zjTsdgMa=Z#QeU@qXjOz0g@)42m%Ig3G6n!@D;^LC$VUNBNEBjd9z=$9miM}PAQBejX4(78;kilw}2o3ObMcP`#4$SXcc2pzg@)|3Dm&l_(UWclE-1K0wSNj^G@Vn;qQIDTqPUqn1hH7kKq zH+)VtfmlC&R6BTJN=7m%f>1L?H7(!3i#IDOOExfM1_5|tO@&V`wJ0ZNR!w+fOLt#M zd`~raN;X?XJAp_vP(L?EIyP`hG*c}i)}?)YMmE{4gGw(a)qkXV&75_AQ8#yCOF=X) z)2@Kjq>D9yBSeoQZeO*6{0 zX{mNr20C*WOn-=&6cZFfd>KuKaY8Awd``iUYlJ!~VFCaXT%DmNCF9nR)TDf)aZkjn zV#A7KFFjV5EhTds5b4~Rx_?|NS9(Y(8H-&(VoybZ3YI=IW2WVDb}ZfTs0umpLH-J9e;cW1Ak2~;=Gk?S6VO)PjbA*pOjuY+N%n}FXQ9?vQ$FidN+K{L{JSBqs) z&Kk<(0001PbW%=J0RBf02>vYu8UDzn^8Rtj>3_2gA`<@F`~LmKUy&vLd6#cHVX{=? zQ$i}l?wPy%zxMso`?o;sm{pLby8X{)&p_O#_*QSc`OB`! z*Zh_7U$yAO+3q@@`1RW2sgeFxmaHcL00-7dL_t(|UX9m>R}<+P2Jnd_nMn|m5UQZ` zB7Y)H1wj$PvWSAN-CgVM-fj2p%%t~T=)L#ed$ISe|JHrK2}oixSs&ockU9C~d1vO! zIfH$ch^hx=Wn~Ylj$(en`N>I1Ny&UJ7Bv4U`^}TGD*Q8{IO*3oCP}5igsL;Yoq>#w zj-DCK_Z9fR#vR&Ca*z%gODm(0m6aHYzj-Q5cP1u?Z1nOACv4?yN09*4EapM(hc=#3;}kjYb6o2vG+0$nvwxb$ z6s!dP*r2n0*yyx$ZhWxm79QhXyhJ~y=Trb;=4i(Bm$_^$9xu@ITdUAQ_hQLQClCxT?794Xy3C5a7i@GatXReH1 zXFA$%sM@b3_ zgrp}{$Nmk2{C&SVG2M4H5;t#syZ+9q)&6w-)&(w`Kveg?eAEBOYs>4{*k{j9RC{05 z3*WZ3whpaR)K99`)~DAA7Js6;f9~a*my>^i@aoyKSF!i@dhkI2VrVN))eD5`df*-< zHzxb%et$F94^5uEdUfK&{n}jtzuwS_();vj@6gcGrz+RYKmzx_gM$N;V4%GGBldo5 z?Dxd(7^;SbhM}RMR`lD@TUXa}K2Qz*jX{U09(o{QuK&j7jaWzWj(>i>p|?jh!~_X4 zSKX-#ffmU315r^9G|TUEbNz#ksE*jb?(NL+-Jd;ubqyY&LDkbIlby>9Kpf6^{Whv& z0F1f*$-(-z&G!a6ErKB;Yp6r#Trdm>s6^jL7*!j9$fqss?@aZBll>qJINCOK7W!-! zLnKn<+Ywh?Zv&)P)qf*9_jZ;n!~>L|>4!g<>IViVC!vI+Eoy?M>C;Fk&L+v2bFMm7 zFB0lpvU3&iLW+NhcACEXO$QK=0U$1x1CasWTzDu+QsVCr0Rf`#>)WvK6a2n6b7{Ig z@0$)s{lEYS^&M?d>C8(QwvPhh_IX!Nok|5l4-lzhk`y2G6@Tz5D3Ngu5n$BUJAf$3 zgJNkomOw)7R1cx5L&PcmJx~)d-<*aLY0`@(2N)nAA~hlx*uz{QNse72&dYl0ARx&4 zPF+ZeA<3FZzd0Ue@h_S>985Y)ZBZw&JRMEv6^lu#hKT%H1~ounh?`gfMUJKW5LsvG z_I#`a2*&8}5PuPAFi9;*Wv5_LL_l0FnXIqxCPvhdR3ZM^9JxoaOdwE9AhbnY!f=pt zg;WLHiTqPC7ZVvGZo#4ylj0Qb5)WZ$c=?AmlgZQuF|}=OUV^inW+{&`-{$TTGRO{r z)lyWbR}CnfkCsWcS*v}AqSczi5}8}}?p+~R7!e(}zJLBFllAqubkK=xGNxp&gwAs- z7mLHj$HO4wXp?}5vv(gF9w9xtN!`@+Vkhx{a)ofA_Rd6m2ATs)@h6^$f62{5`Z2Xy z%@D{5#~`7%#lpQgGV+);xo`hCk2fAB4&y0d6N*+&eyA`v3+cyZnrDF6f-*ZqZEB$x zk$V_QAb*0_-OUS2$W}UG0|X=@?=+(~O-)a!UmO5Q{o+LtBDmbp!o72m$HhE^(&^-d zC1!WqY|3#U_7bn2ZXBLDRutVl-P{BOlMrH8z(Ls|;Jv)CT44ZUX80oz;n7T)BN$s4 zLb*R(sI=L-{fWkzWAV{b!&B;}poCnm+@DgYlz+1j`wlcS1RjL2BO+8Om-`Woh$seP zdL}60wA+>9;shX^J_H`$jEHFB$d?m#Ujhqn{x}Z=*FzlO1|eGP%It#)O1s_3EA%H0 z;6*cy!$5?5A%Xi6AA!LBovW{0qU|p(6dxMG>sn;6yyn-qNBJ z?hKSocoS3e^TX;QECq>gh(I|DByUqLL(4Jystmtn2MQDLm(>MCGh0q@X?piAv{$CyT?mePN$U5 smvTK`q?9l9UI+vniu`nlPj~_U2X9Dkb$8g?7XSbN07*qoM6N<$g1}HKJ^%m! delta 1520 zcmVjrvLx|7j#liQvlhgbY|3x89X^_>#N`U?5wGy z#ktt(YA~S^000F2Nklv=Bf+iyVb=K=&cxxM}(WOW7oFw;|f z5wZz#DBxq5hhZ+RzS7Q33|yGP)O9TCp{|!hHn&|AmTOrUQxABM&Sn|ndgwaMrE`K0 zbsTC_qo>P7!@M<->yBxkl;x(Tc@*>062#>YBjdq)mVb0=To>!w%=NGBf@E%t2`q5S zh2u`CM#*lNrRyF~PjoPm$sl~NRw(P*rfotfMe)2keVC>bfqTi4*GiXVDyyomx?y{I zq9#h1VBBhvtZmRr(~srw`*agU>|`f>5SF>56-+ec_|od_l0>EKkcbxAIY%bS>1FKC zPhTq&JAXzdnC327Xb0N9qR=ETMO=4PNBANgP8jnZ`gw!l<1N;BxhPP=e^RdOzL1_y&#S#q}SX7k~9sIOib;m!`wXOIHcvwdY#uw zHDsbXahRLypC)!4lX(&%Ih!YuO`M(5!sR^xvBMzXfFCBI5JyiYEK9{1j$jtYb~tz$>vFvwAF9 z^vA@19gpmvUQZ<$7lL^_+FI-Agq01QawPhpfg2cr94T@E4{#vF0pa$Cyu`iTSM9|| z1_l#D;EV$T1N$~SDEZ2T2fD1LkrG{huzv#RKti2gFL|Z_1DN-~h7QGCHNHDcv~Yz4 za|;lWj1z|tP6W&HHd3>_rh zbUXwgNDsimUx3?RT!uhb{VRg(^9YvK=22@eypXRWW%$Kk)Z54B=f}q_BKS^yLH##o WYWW17y0u~e0000>C4KtnJoXIMpGOhPFm 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 P00000NkvXXu0mjfygn5E delta 1152 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 Hu0mjf&V7HY delta 891 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 delta 1345 zcmV-H1-|;F6w?ZjBYyy>P)t-sM{rCfB_t;&CmS0YBqSp*DkCN)CTv(RLoXouyF@D{ zB<-UxzIYoO8X7q`IFM#3s&y$MA|fv@FVl%BqGlGiZyEKsKlQUa^R+(W*J^%m!A9PYqQvije%uy&g z7z_Sy{`}<0o?^M-HvYa@Lk|GtY z5Hf2&I!zo*0U*YQJ~&O-5mxYqou>E5JvgBjAiKeR z)5Hj%fFi539hg47}IOLWgw10V;I2dCEBz)=u7@`w4+(XU< z67?FkikASH_2W-wm?7Wu#%-Pz(kTw2{B%qP zi{JD#Jedu~pm0GhLR$D$4@O0%5U~sw`k3s8zkki?xF4Poz%i)J6+yH2>wkt(SLp%} ztRmDd*;i+l9h2$|BVzz?@kMg|-mh=xRDuCWo|kq8zQezaLTm#84+4%bq|md#1D6BQ zS)tPG17{FW1ORfoaN@G}T95zoi|>!LmgR9@ohTgU`V2t*mb{Ucy3_mnyG!k`0v^K2 z7=HkKt`sV=GW+Zu8U4cgb_T;!ms^C3T$gYRpXF`8P{;lHY&c$yOfR`cRH?_&r$TS_ zb8^JPlnNdjk2odI4tNZo6F+{g_6w3_MWHar)T_wyP)r+y*8ImHSq3Ai!Ej2wOJ0;^ z%DQo@sYNn)iN};{i+IH$5{3|)%_wXlR)5K|)f*R-f^myTr4O0eK!OJ1HA$9nn5mQ+ zxccl$kxCWiK^lfczv(FU)uJE0%bZhIl-e7R>`>;$SR-gEQEi9IK&6~g!cuQQ^r57N zQY1!UGqIfnG8gz`Wt$AuO375TTa9`9*nPlphh4V$V;Fo7p`Z$g?BEzpdr@r{6QH8e1`R79MV$c0G7g(d zybf?LVrRG(7(xY1fdC54c|&6H;(uNW%*6^km)JpnDa0!zh7-$$&M=Nh6_&XCt7-bF z532QcyX-lzb1`rZB<}bsnLA>5Y1<#6fCSDl4jj--BuK!D`u{@bYgz&F*4BitZ9(BNU>?S_7ws5&N36YD34 zS9>AbXNdXpL~n)0cKFhIqQ={Dxtz>fPbKcf@#Db1%*7X~emlf{00000NkvXXu0mjf D%UNeJ diff --git a/TMessagesProj/src/main/assets/emoji/0_1607.png b/TMessagesProj/src/main/assets/emoji/0_1607.png index 75b723260099656abf3aa5278e61e89102b6d8c1..4fe89e2ce50f52bd3a625bdebbd8acbed24fd494 100644 GIT binary patch delta 2686 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 delta 1857 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 Ef>9|vKmY&$ delta 2628 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 P00000NkvXXu0mjfc9e_C delta 1950 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 QxBvhE07*qoM6N<$f(f^sNdN!< diff --git a/TMessagesProj/src/main/assets/emoji/0_1612.png b/TMessagesProj/src/main/assets/emoji/0_1612.png index a644b2d00d57c892158833d1d9ffe4bc6c15f354..dce6502302a9b6021ac2b963a56d9ceece329ef4 100644 GIT binary patch delta 2648 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 O002ovPDHLkU;%=jSgl$B diff --git a/TMessagesProj/src/main/assets/emoji/0_1613.png b/TMessagesProj/src/main/assets/emoji/0_1613.png index 221ea79d26879602a9bfaadb3c08a767478e85f0..ce0b889b0c4ecd18e4944413eb36956be498c4a3 100644 GIT binary patch delta 2807 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%0AvYiS-3bu*>qj@vd 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1615.png b/TMessagesProj/src/main/assets/emoji/0_1615.png index 8dbb9701ab3f6a4fefed741ead836116a4befe22..6449fc0189ffc6d2c6f4ad87fb6be29925921592 100644 GIT binary patch delta 2418 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 delta 1970 zcmV;j2Tl0=62A|SBYyzNP)t-sM{rCvCm%K|B{C@^Gb<-EBpfv?CMqHxHZUtYFex!5 z9wr$PE+ZU5GA1=VEi@=1MLs!nT}PC2P?~#CT~0k@Oh2lGTRbHgKqwh68xAQL4mTnd zVLT;8D;r8J8#5jfP%$1|IU{C4C?OOJS2ZA^ds>@uP={bbb$?GbZAUF#O+i61Cwx~s zr-NdUXi8E)Gi+K-f^%4uhj)6btYvd%LQq(sy|I{?hkc22tEZPrX*Guz4~N9t!_Uyh zyN+gzkeNd_vzTp0q{v^SYqbCX02g#pPE!D{h;UfKBmNIQ?%>kw|CrHq$Xx59iD|MC zh5!Htj!8s8RDXB@rNLW|9LIS8(DPMS^~~(@B8m(w2(lF*$xC1$|NnpFH9?>dk!^C# z+mh2=U0oH-E-6beRric(@jHmnDp8WRxKkgshY2)b+$Hhaki({;8G1uLl zV{>fB2FJZ!&FeWzPva1IAMMla=}@%O>G<^RFn@9Ww!Jw-)HIaEaSv#YvV5^zM^Aa0 zG)JNz&SOvMYBKPipnR=79x>`;_RRr{;m#3xV0W)hh4vxohK-v|#?dZFjlJk>;fRF= z*VKc1dABL++;#y48FgkoL_OP|HAq9vws2sHYIb{Ejtj?Ou0FQzVpAZyvs#TlxAkCE z%6|*5*A!W|#Z-(QYph}9RaI(F-BxO-GcvTG&QyGO^eo#vjrcJ}RxE+wz%pF4(Z^PV z5gRh(z549KSIt8a@7Xl;ejbTvRx$er{tk5M<1od%?VT{UR~W?`-BeyI8GQ zr%o+w7{VaP6gtXqQ5LtbM>S(w2%lB+JlqL}7)W^KPR3L>W$(+fM5R`DX7`%8GEm$Z z3W+^Vqf9<4#c#eomQvlRW`tc3}q_CHGd>LL4%X) z>*@MUcAUz_v76kPVK6W@7lUXlOxXURMd@-+?bEvFugjWhI>h$Y*R6l*BJGrE(-YI! zL+HfFeOk!~hTNJnZf_qQQpS|Nnr|nB?Zk#WAPl)N;R6!FY18C(!klhzZZ^&SzOMxa z+oqIK3>qR@rnQy>3C^ZQ<9|exX74cdN7t(_Ha{8eh3q1s+{hh`(a>mp_6<*cR@gQ< zAjXg}au!I~vpV)&CcDU)H8xCzz(y&Pfe;3A))XY9aJ6mQj_jf}$s4#O7^T>@Z5P5A z$Z~7)8^~CK5o0@0i{zqHxOwr85t)K%VeGR((`2F{K|0IBKn%URcz>1OzI~V9b;7;P zOhBf|G#44Bw>Q4Zt!1a%nNCV>F(M`8iCs}+AV!m0CX0j#_HpRTtnWo{drxAFG*Uzg zT9_tM8hsC8+L4jf4;9%(Yy1A^L*G3Q)F^a%LJzczsTtVZ%V?0?S=yM|*ruD;&tHg9 z>sCh}y>~cOnu`czGJhHZvM(0YC_Lw83^fWmCp1m&VFXP^RzvET{9K>6<>jmM)2pj9 z_MXHTMTv=`(toscuR z@_IeHH~GJ`{7QRvb@ee)hL+U1zvExIG7Z=@pxciOPE&u=k07*qoM6N<$ Ef}NYixBvhE diff --git a/TMessagesProj/src/main/assets/emoji/0_1616.png b/TMessagesProj/src/main/assets/emoji/0_1616.png index 303059c57a851339678fd5f821a396605e0c4a83..7dce50e00b2331dfc9ce92ae3f4f9eaf42f33e93 100644 GIT binary patch delta 2190 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1617.png b/TMessagesProj/src/main/assets/emoji/0_1617.png index 2e691b9dca7d4a4057c42bdd4a4382e2c0c1350c..66083d1d662abd1396582da34d6fa1970dd9d93f 100644 GIT binary patch delta 2976 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 KMNUMnLSTYNUH^sv diff --git a/TMessagesProj/src/main/assets/emoji/0_1618.png b/TMessagesProj/src/main/assets/emoji/0_1618.png index 9e7728be698edde2d6dc0a202d02b342d3ca5f32..7283e8beee31b8eba5a4d6c1b198f72df687dc2a 100644 GIT binary patch delta 3154 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1619.png b/TMessagesProj/src/main/assets/emoji/0_1619.png index c0e96e89340284b52d52ef792c3abd740c482c4c..547687896430e972b7351b1bef52905f9b90a78f 100644 GIT binary patch delta 2624 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 iv&{lwI;T5jS$_duY~gaI4Eb&V0000-Lp zIW|5W9UVd`Z8{`iXg!-yL3gXHs+E+LT~U%kDQ!6-V7a)tWPfI3Dk>^MC~Q6@XGSS< zS2c-EE__KUcT_omT0VxNbIp%syl+OLaZ{XnS*B!2k5MmygJG^;H%MiDt8Z zRj-+I!iQY9cTT8gJ(@ZpU}!{{l5o4LeAJg|#GZJ>KO$|wz`*V8?y`f~-3lL10000g zbW%=J07BBS2!9{Y68%M&Wx0k?X;IY1>!V!>+(^O3O4qm}Wj7brmECd4F!1`@`2sw=QIu21OZ`srlB; zxR_Hrabw2)5Dc@6@#CJRmSb!l#;mI`mo(Vf8yIY71Bf&$X4=2T{y*4NR8 zQ5;`iUlfgtxgQ2ueswk`V;;S{zP^6fwQs*K6o$(DGRgA!urXFIFR!Z`?c)3D%T{ko z3!maNN)RMoOwFWdir>UQ-7jM&X` zBaN$&R7=HYfd2dUpUe4;CzH$*Ic7Gk28zTGW`EIlzdAArkn3W%C>@% z$Py8|HXW-H+6-~z8Ie~xJIfW)4i_U;V)BRyBQZh=#FZi}`>MOEk1db%EXuH`wj6%yK10QIgx?RN?dE8Dr8I$u2uK2tu;3X-{Ee4P0UV zZXA!t%z~33NR|pOx#9F|oH%U^$bTVE0U=VMjN#nC_;doq380r_cCb=AWN4}KNWU_G zfDk_d1c)3AU+GLzsjKr*_%QRjCey5h9!kDFtJ~ zi|ms2lnnjHGx;DqFY+WKhKQjRrQA*zDsQ!J8Ewyq zFFgr=pt?rijDK=Y)-Qi_tvk}&3@+D~>l^Je8D7BW{`x`tTxMYOK50DsefL>H8^Qhj beEtDYXXE`p-Q*hp0000 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 W?38Ai^a+vx00001_U78<(W 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 niv2$ literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1627.png b/TMessagesProj/src/main/assets/emoji/0_1627.png new file mode 100644 index 0000000000000000000000000000000000000000..e638de1b2b76d9a38805ece83ea9dbcf47d10913 GIT binary patch literal 3638 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 IM6N<$f_p38b^rhX literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1628.png b/TMessagesProj/src/main/assets/emoji/0_1628.png new file mode 100644 index 0000000000000000000000000000000000000000..05cc3f57158891ec1e6995594ba4e11928205dfa GIT binary patch literal 2773 zcmV;`3M%!9P)|hd1jL08nOg_{$R@jd4d$m9^tc|7QU=|e6{u+n)Rq*pbPISr1fgLG zW;6u#!aeG(8{nfE%#ITHy&(L;Bkr;s|H~};j&JRkkmWB=DvtULfvUF$jELG^ZOL_;OdN0000kbW%=J0RH~|3H%oR{_y>5{)a2@@bE$K&i*u-$X2J^ z@Z<7_R-@jxg668X>++en$G*WIQ6T^T2&PFyK~#8Nl-1XA+c*>kV9k({GQ&t08n121 zqmg4fiL=SR2mtop)q8jEExqi%@*a@1V%gq{Jr^LU`S9yNAV#SNmB|-4ZinLvnFk;K zACTexDmQDBdaXAvujT&>)F<^i1%;=8&22SXM@da;*a8 z+n6_dy=JdLll zR~0-RArA;ev>kiK#UcXVQ~^gI`y1E^$j@dY+s3LQx}J)zRG7i9SzHtDR@#Y z0jjb95F&Lt7oKbp0Go7671=VdJ2<(%IU7}JWlw(I{On+YbkBjcQh;J`5`!6l>p=`) zTQeI1vXIjG`tqiKa?1nYo7XSoZbdeWL5aRjdrf+?k zP;hm0-Dl2@+E_+J+sLO10ElQ)aNb&g&QaR~unWg^Qz6KZ9lrN+^T>-W=w`wvFNLj+Z=yi0Z#P9EMp z$ALpkV6oLv=d>$yPcHz3SjV2GY3{4?-DTjCcW-v3U;&~gwpT1u494kH4h~Bwx|nDI z&;MX(b*q7|>7D|Ma>b1*?~6Kmx4OCoZFCdB2U|t9WXRa@M{$HBDuU?-LG?l<-3uNP z1kV*k=ugUR`3@$=3Y&tA1qim_hpbpg^};MfNDv}9f;AMRfRFdH%UE48q}e`K#Mnee zi7l3xZg>xVFr^|}u?$)Dc2iv7OOmg>WBPptVMp>MQLvak!&sj0OJTsJDl#&xQi&Nd zj3Ky?tLO&942PwP1sN-=srMz2ApNIU7iDMpCPlmE+;@@!sAs z42EIQ%igcOy*+ECRLRiyW;6F1rtI&(c(I?<3n+Lv`1NN21Z1qxIZ%f%&`VVCuzmk0 zP&%NKzC12Sfi9y22%z&mF6w(U9v;RSY-OL$|K~w{rbCb^#>GOAmj}_ zB*i%3^W%byFCW$SJ3H^qLr8$>|F&6ozll^~7{F1Yb{i7AK`u-hyxJQtX!*3z7MPKb zT_?^UOA~wM3kqe^nn5sCLm{xRibMGKyDL>6uOwIIwBV|P+Uy6Yx9LX0)&hgp}RXS9P;E2rIYJk^?F^(vWtnM zN9k`?t9co2#6oxf7Eu8}5IK3(T}`Lwb3dO=@%I%3ks}^ygrX<`Awdxeh{SonKf;|c zKyZW22ZIr=P$t)JLqU^5kXLgbebD- zGmJ5-#Tp>ySm}W`Viy5`#b z@p$nT#(Xdtf2fX!4%3GQcA_MeWG0hIW~2e)5CVmSv?yU)8gn}zBH^D`0~r5A7U9*Z z!E{Ch)?qzG6xl-y0HMnl0bWJLAdfYHl~r%;Wr#qHrPW8-f6E8X!(o>vhX^+L#gB&hnizoAYtA zr8QL|l#G(`;}fTT3kdYpiCOX@H+6kD;4dg^s)d58Dn}V5o5^PV9w2BNNRYsnQ!^SM z2D5h4n9caS!RqBwLCsT(EJBP=K;UQL?}La~li5Gc-Ylw=HEws;C=r1g3N1%u6G0$B zqFBU55+}oZpsV(Q1XsN;m&i~M4jc;u1O#CO_5tGeDn1y_46mp+!{l!M@E%u)AhJTh zgFGSRJ|J9QFK%(qV;XR5m)$O|!|%(2KmZ5=0de{+{T>hfQh-G0FcbuYpXX0Ef}AQ4RTSrpmf!j~U~j7U5l-{0Tc bdmhYxRoaSk0Jy_C00000NkvXXu0mjfu96QO literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1629.png b/TMessagesProj/src/main/assets/emoji/0_1629.png new file mode 100644 index 0000000000000000000000000000000000000000..ec2412f14d1b8fdb6f1879aa2fff3de188a1fb61 GIT binary patch literal 2815 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 R2n+xK002ovPDHLkV1o6bE`0z1 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_163.png b/TMessagesProj/src/main/assets/emoji/0_163.png index 65596e30101e043c6ba42eb58dbd5322dc8666a6..db1ded72dfffc3124cb07aa1f44f01e1acf7c743 100644 GIT binary patch delta 1044 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 IM6N<$f<0?B^#A|> literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1631.png b/TMessagesProj/src/main/assets/emoji/0_1631.png new file mode 100644 index 0000000000000000000000000000000000000000..27c87e41b2e54e745b406e5740675cf0d4f215a2 GIT binary patch literal 3210 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 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1632.png b/TMessagesProj/src/main/assets/emoji/0_1632.png new file mode 100644 index 0000000000000000000000000000000000000000..211e5849aa7c7b36cb4bcfd3c088c5b3eb907060 GIT binary patch literal 3519 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 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1633.png b/TMessagesProj/src/main/assets/emoji/0_1633.png new file mode 100644 index 0000000000000000000000000000000000000000..bac4122428b2de0ddeb79cd0f57c5c8a907bfc00 GIT binary patch literal 2819 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 V_E%0jmRA4(002ovPDHLkV1hpECWZh2 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1634.png b/TMessagesProj/src/main/assets/emoji/0_1634.png new file mode 100644 index 0000000000000000000000000000000000000000..d333b5ac5ae7fa51067376c4b2d4bbd69e80fa1a GIT binary patch literal 2945 zcmV-{3x4#8P)lf#w`BYat}+L>8>0FDRC8HxeZIKieC_9L7j0^8~@m4|JP(L zC7mlHm?9j6C?S$CC!!=Cixq0$7;xbfW!o|-rV?J)9ev{)cH$s|%8nHBwHxZK8UM^L|Hmi3f)M}JP2!{$y+imp4L;ue*_rxxia3z0R8Hs&nyPHk_&nx)586+AJ5D-!S&pOGR zD4Splvvv)TRR{j?#Q*HB6%twh-hHTP3I6Q4*tc3oB|!hySwt@o1SW3%=b_uefpcS1 zSVJ}c(L!@mHvZv<;j%PiMG^kwlL$Yk^V50l){>u)ZGLQ6(#Nc_s&fW2jxI7`q<9>t zf~QchCSkyQSkl#@J0Has@AyJ?eOg&>eK#!`P8tY(#EgQ!*t*A_`%w>+FkjC z000R9NklzM_w)?m+SBYQfQ<3HVcR_GoPDO83NCk!)J$5@GHTd4|Z*LEPL-@e?{)8v~ zvhN$fB23_XnY`6Qu0J@ux;j7K49Pwj%ZT0I27_>fZ0092B6}CFH*?v&y*+(T7r;ec zNllFsir&>`4jd!A)|2R14e#}z-HX<#PwTYhQ*`XGjnw8&_u^F714m0(6^A6on#kwd zy-t_YVhcI|O94=+ln9&1Uu<={%vSsuUse=HS{yyxMVoSschc#OhGsp_%NK1Eac(RI zdeWw5R|9>E(|k6Y)lUmWhcZUPHlt6dtQkZ?+Ey4O2n0!25Y(}EPm=3?Eu@N)jm(sQ$3u7xFLj6D(4aA0y2DA9r#3$9evHH@1lGHoIW z^nx(xI_L#|wvZVQBc_qzf&~f?C0D@ED_C5FZYC$Tf+$h_(N%I;6?{;F$YGbj)bt8e z5yfR>B08L4X=OTeOfSg9ui;SJmWhafjV{1GMj4N(uvj(BI3j+6Ba3Z>8Gf6pg%Rhb zs;Z((7H%W7fYNR=&f9HE1;=n3;Z`JqCD(!eiG>~4!GtbM{+mP>{5DD%L8+#y4u#Ph zW6f{~*R=8_(9tx8T_Y?J-cgsp+uSZ+mfJN86A2|J^w@$#TUUotN$Bd(z+TMVGR)0q zGG!z|2qBIup>ihk2t4D4nG+`Tp@E+?oAYzy6&}tAc0VIos!J03ygSou&dki;3k~xd z2L}hAN`_PiBvktJKmeVFh8bAW+}LRDo|Q|bv)$$f03nZpI`@7%IC${j@-n~g^iZy>vFbshVKfw=xRoBoI1505LAuRpH+l@s_OzeAUgHblVxZPwjSB3Bs4 zaT1!eyWDAscblf^-gdJWYF%K3UAH?z1$F@lg6*acym5^aM1JI`lCjschbS4(fR({4z`Vp-kf{z=ZAotpTGDn@B;(@ z<18k?_|og_v6ZCS#W!phCs}gr9eKSYQ3Qkh7zh(#+>08i%mD^CraK8=?sSfivDb97 z?64Ox&R>8a!Yh`GKsep+l8vNTYzP__mW}<>(B< zKoDVUY>XmojJC;_3J{8wBf*xM3YLVEv%}B0Yg`??={qtC}v}^2p5aE(Lq3v8IWs$7{95DOB$98p=8ixqmZ{1 z)4)5Kjga%vXe9c8P-2wzKv;EAYPRg0PM!)fOpVXkwzdQU=ea1$C7uR`Ab19wLYD+= zG|i@xYdENp6BJw7wRN2mi1Uz15CA3+H82K~vtHo|cUH+PPwfv+LZ1_VBw^;TN_wRRV+Z;J7RuKXwP5-E)h@Qf+$!DV+W^i*25EK6=FovMy z>hgZKdt6kHDyq}D=x(TbF2BRk;z>UO0svwJd#Lz-VGFp)4MSB+E2|~7V914KKHr~- z07%B)un6K2$Rkpze>029O3B2|V$^sE3zDqjCbwp1Vi36Go21`(jJVxC=~nL)zGTX# zb$@qvf3L|Zw)UIy#Z{I|5@FhBfB^8`Po#RC{Uhyq7wfF7ovou!?HYz?-nBPQD=>)g z7P$xr2z~;8>qW;{y*t~&HlS+PXJ?xl1Zi{Y+LE1v5fIbU({HC;tFbhp14!#^gPyW|`OTq)TBRIV+00000NkvXXu0mjfn#+9h literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1635.png b/TMessagesProj/src/main/assets/emoji/0_1635.png new file mode 100644 index 0000000000000000000000000000000000000000..ecedd05991f4044fc39a1f8ce4ca08c229918fd5 GIT binary patch literal 3698 zcmV-&4vq1NP)@{mw}v=k6A6%kMjIB^=3jMQ1r3|m>_rWO9-j`zSS|J7RzLXi^@PYXPU6M=XL zF?tkNqKaP-2`+XJZ)vPHq`E`4{?SblQl=GUy7Rjuj3teUWEmla*?B9EBOHMk6k!n# zSuZA=2sn})c-kTybrD+04^h4ZIGh?6ZwEc2DI$&uL#_--w+c{64|8o6Xw(;qg3(mZ z7ZiUD3uPK?y&QGS8Dy;pHZdHWl;v#Vv4tF%DUf>|e5*C64Na-f75;cUT{Apg!h|I;%6 z&@0uL6A1iC`G#xH{Ftl;764J0>yV zvMut~iuKfZm4;Tyn>G^=PG3$@Ixt?&w|^=>!-002aEQchC<=;!|a z=M@n%=jUS}{`*Usbmyyt&6LvoGH(6c>*nYF=&$|z!RK1eOXuh3@9V$PwTq7D$KLPu z=jZ3Pp^fY3vef4ZKC@{601HM*L_t(|UUZXJPg_|Og-5a#TQbPDaDZSQ0t9995Q1hN zG7piW`DLfv+KYSdh2DGb>2-SfF|)6+eQlIk2Ck*`Y2CHYK77|Bk3SfAG5sPC^m@Mg zraWF>Fcb{>2mZ(RhNjPw%`NyOXQo5mZvr!C$%BLB+01nC8@?wr)7;+P-fC%kyEzjW z=m!P@0N4Vz<=+kQ1d`iZ%>#Iat>a|!;B2;!@y<2@0KyhjX(ng={Sm`ATgl_Iy}iBp zuF4}lJ-j2$CICR#%c>&@l0X#iXNYvi_1IF!NEb-{&i|c*Tu=U@7rfm zSC!b@Tue{7VTRL&x~bF)1*TimGh$h?NHM9zAO;k-72~bWutDHu2^VDBe*b=BBW44# zi2dD_k6WUQDMc*Ouq6_ZSg-3xnQ;ifZ}1U<;o4 z8lr_lPlPC2w*Xim+h_E8Z$wqcNZDCSajgtx4ZcxJua36|31N5ztE8Asp{45-!y(Be zmd`m0!XpL_OTJbGLCu-*_}mqz70k|w2Q3pLd3i2of-mG4`^Xq1>Q(1*O%jVLYf7%h z+K9^51cv7{t1{f#h)6V~R~SWU`J2~Ds=`1G-RoR$9wX$sd=*Uys;UZV^wpA^N|x3ilrqlipAxx4OV4OUl)sSKJFQHlkvCDis!Y%Ppb>7 zmuVO^|Mh60xY69#cx%#WA&YeH|4G+W zflaQwdH-)yH7b0lyOD7sYAE7%l^a3=E`Q|Eb(n=wN#}MBiv@|6PClHZRRL6*j}E4@ z6cg;0!>IK zs35Q`i!dR+?nYqih-G0)Azg+C07$D7*hoj7u?gHlggP%0h6N#tC&s#jZ^F`A5t5}S zb?!DoyblX=bRQ64avX0GnrCgII@#lo5s4x@ndoK}-M)f%#&8gBC$pBxWOg{4fH53- zC$L5_mbe-RKN6OZX2BS}^0aEyHWrG-;=*no-6dct64hmS{T(P?sqjc5V_@{v;0>s; znOT3gp2@dr`uqF=sG(pb^X}+qeFs`-7)spHaMgew`5b)UAPjN%?mM1h3O(~2XK!4? z6R^-bdi)$RD5VH~C8PTM@x6Zk-p|C4zy<+uUU>B6PQZhqsi}2fG+UBEmZzq^?+bY{ z6n<1V2cO#hxqcK55A}uoFgi6lI{NvFoEwI5PIfCpF+u5C+UBgm^ zo9(Whqic?h!+oXXY!SAFEg{P`0dv`|ku3uW5E5qrl_Pd6Ffk#Ex$FRc%sxMvB;@f} zwvhGFcO(sZc9Fc@jU4=Y&e_<_BiY?Ob7-9U;^D)GdwcnNt?^mCel~tHzc3%!+xrwo zS|GdU<>tK!zUCtM!^f&|{0p)_NnxS7EG{f2!P=qm8QDLbJe^A5L#NXb<;-yipQ=D1 z2~pDfm*NHFPwJ&e14X&Hy1bT}`19wNk4;iknwoEsmm|JRPlj^+Pj^G6cw% z$1^^ABc!6?+EJ2zW^VKseAd2B!T9KNA~fIKAAOn*DLVVB4It9SpEEuNfEa2HYJXW= zL<g*TT|r^M=HPHJ81(t(vrc4YW;K?k4Gen4smLp~%Y#cB1+np`o;?b(yxAc>sg+oFXaHgCjndrGuu~8eMMD zw$0Qf8O^+FSe9MBAas^BIZd}P#>I;Tr!%q%k+jh)1hlYqPN4(V-kHHcpUZ5cjWM0B zWx(llcqP{C3TBz4?hx(s6FnC^d^$yLC1o;lyzLTp< z+9gS(O;)R9T9&&de9{h)bw;*}t1*R2z^J#=j60a%dN~t$Xj(ibMOnuftbHJ5h~v@d zz$1X^?(UYc)of!~PN1D_h3^Q8nz5szh<&|Y#?50+o_8}suMpyGG+kqeN4z2%Km+1k z2+x}tv!`1T{B8Lv@nJ@GiAHmCz)oA0F~!P;AfR`m(3u>43S(3WKWFWbL{12~NJ0)# z^fEN(JxXYA&d`!LrU)D-4B)~CgZ#9BOWVh>b`VKHU`>i(k}-v9giNAjvK@I z8fwRG?duh|0Stj#1KpK(dj>>q%)y#ch9u{pSzBlzkv90m%(~35k`QY+Bt9TSy^$O9 zvZ34cw?i&M@QJpz+YH^?XCI(a%c4Nr)}yNnu}nfttmfoIyKR!#y$#~K!zr{e`&h4& zotS#Q5ycciS0=tq)!T(h|Bj)?=n$RsW<2?5atVSjmfU#p`o7)IMJCG9#0P&bDbXhV zV~TU=e@XP1IUc8C5#L_FnzoL4V}@40gY(Nzw;wIk_Xl~);N2IfDw`22=ii2)5+&qh z3~~6`=<3>RUB3lWJiR;FRu`r_xvo|%HSJJ3Z6ljI_xI=cl^)+>bZ03Xw0k*!$v(d!!Hl%k)e>q%sR!Lt%Ipn4UDAM$#!^#*47?Bo_xIQF|(1GTNvW<<+nsMJlK;^ zlunxQBwqZCtc5Hnbjozr_}qz`S`AecCx-m;(SrvsWV5HN(t%Q5-ay89OQ-^X|GWzj80{D$Eqs3@Kw#W^Lm=7N zfBE{GbLUR}`u&_c_s!RT%g#Q3{;LZY&Yu0%(VRVd;j8oKzdU{V*s;In}yN)szQGY;YLEfMh#`y6ye7JR4)3uU7!+U;4^{rwUJDKom~tim&Mg1REBePT`s1d;g%JPIKzd|OiGp+b z$wIxIP5#?&>b_9_)J*;G$>ORX|Ijy=T?-ElWAnc*|KNmgQyj*dDC@d44o|uo7irb7 zR|hhN3PrP8Nm267aj$U<2|S#HOb7Pmw@5DyJTh36d`w+)g1V@BKrT2W9TL{Ti2vr7 z2se_|rX{DHdI&$I=+KZK8ggGl6FpgaGF_DqQ^W-5{TsHYS9WOI)ro|bEw%=L8#RECQVv1j%X!ZWR=K>!kc zl^tV@^Mwo%{Df)7=Sw1*s@ZW|nDI0v21g{2TCBFgSV zjH*e6q&cffP?fllU~nO3HxtZ04B@bQh>&ndBr-@4C5#cmSdtVhE!nN}Ql+dyAV5Tn zbOoeyNa3XLO#A%g|LVFH?=j3FdNlm(8fr&D~2Pnw)w zXOX!9Lf45b)QvPx0laA#uwVrZ5w1Cehyk0mZ}Omq0*&s=MAzR~fnZn{ChWSGfGPm!yqs<##WyifR}y zxvggqVM4A7`OEVL_({iU;j*wt1S|yy2s0ZNv_d?7_zohe>UlhVeAQ7U-EdnsC&v-T z*UQU4O63$F0vDI@M6E4wlE05|E`>1ZeEs0r%J39%)a~{%Wfg~(tX}=PB2;Vn<3xrc zQd;5IvsX*2S@d*xs0ezkIvlYa-+L;O%YLy;bQkF>=;o*tQAf!SB3XoKphc6&m zMQCzxA}CDgpMhSEL5})FVym>|npqSHLr4fCgAs_hI5SAhJeLH95De3l2tx>XVeH@5 z0#t!al5h$qBw0dQ81ZMY3N_$Dih|h}qH?T_kydCVb=%VwrFWa62{bdbp%thhssb1U z@S*@)vEUj**q^gyB;r&F*eoHuU>^;vVu2{3(BTJAGn?gLx1q!%%SiS-A3VJz-3jC# z^PNyb70q7v_}Fu6iUKP!F4rpU79b$n244MN4Uzfu>}6ywQAmH`I<6R_Dh#;sU*Nw;5ATt_x@=a$xB-F6-EgJQCM=QK~LUpl^ z!lEjMQR3oB6n^`r`+;fS_wQf6oFq_K1wr8Z7tre!*MQ)ofGFsq>q#WK7g0-VUW@P& zCTwrtY@g&4KYk?gA8!tBK-=5DP4@{j9*IUG(N+sMFhrQ5(HCBe0Q0F1evY8~dph3y z`mH|PK_Y||jHi`l^L6HbdKiSO}3WfacU#(VT6BxdU zi4`Cm96`wM*Oatx&>20X)#aJKNdW*w~+UJqT(zQ~mgk`Yo zoVm;_D*jPmnpRcuEgaRnftTa>vdkr&X{DIe2F$@EUr|sblS$06=5RwUdy?mwfrUVx z$wOA=-UVKchQoEixL{~uA=h}DCdmi|rRcXgvrX)(s%0U9LVKhXa>mb&n*|R6wdYI@ z9p-(Wfg%G%8YwpVZRW~io2T`p(;d%7D3jvCW3Du0%7E#i#Kshc>#C|@+nz7Vb8X!$ z88$m>HVd+=6LZZGv#=LGQKX^R?AZ+8dR8@7RI8Su7t6YFfj^IJbJZPZnyar56$?-_ z`xTq1YBgvFv7^>#*NR0=)+t2~iYF{+v;#0hM~X})^UcIdD57SMhmvZwK3;ZPqU-+t z{Qd!LMo?(3v5*nl@3s`dE(O!&hXg__znXZNUPwpHhGxs*N_U)8nF|w z3Yg;Wc8Qr_?F0<5Vj&srv(R;vlUC#J-J`uj<>Y#;_5ERy+eRab_N7qQ{Fohq{R8$Z zv4boOqXACp|;LuROWO_LNpVa@1@ zp;T?#5SP!A#w&#gFK^+@j+tMxZP{10iLuK>c4_%hK?{0Z$4!RXe9b8NJ`}1W!GOXn zf^GZ0Denwe`%9J-^Yf&LV{G($Oe^lxCcE`|z1zb@Ueho|tSAU()kn)n^g5(SL(#c##~8+dVt)CVV&l83kZIU;9@-DvJF4bX`cR09I-BP< zkC}y~ba-Vwks!rbimk1yNm&zjDhTLs?~4>r5UWVUN?_cmZ>_AyF`li(3e`=;;Ev-k zeez}{x3ba{h9p=n2PT7YNuSJt<%WvUFM_6&sCTQYtM5{&#l=)Am+Oc*2rZ(3!0_^_KBDsZ#Z>N=6t@t7{QOveVC%FRk13L!Vbd?eLL(fA5i@|F zh6PAW#25{7OI@R;x6~*ch%sPqM@0}!#2^J~YHE6VZfnKfUWVkzM&Cg00000NkvXXu0mjfBS*0X literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1637.png b/TMessagesProj/src/main/assets/emoji/0_1637.png new file mode 100644 index 0000000000000000000000000000000000000000..1f952ea697c7de24db48bb499319bd493925fb65 GIT binary patch literal 3654 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 YU#Dby1~ex4U;qFB07*qoM6N<$g5GNWb^rhX literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1638.png b/TMessagesProj/src/main/assets/emoji/0_1638.png new file mode 100644 index 0000000000000000000000000000000000000000..97fbd3f3139852fcac81aded0abc370d9459c797 GIT binary patch literal 2246 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 P00000NkvXXu0mjfMRtI_ literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_164.png b/TMessagesProj/src/main/assets/emoji/0_164.png index bf5c6e3417e4c9c532cdbd44c75d73bc2231936b..bef0db25ce613597de9285ee1cc59368beca7102 100644 GIT binary patch delta 827 zcmV-B1H}BO2GRzQB!5UyOjJcja7?CLImLoq&W~y5xRl3)UFEfs$%|*ohhf#5cICB^ z*q(Xz(y;f|wfEJt?ZThkrh(R(a_G60^v|vO+q&ejjPS{(``^Ct4SS>j000hjQchC< z{&ARa)1@5!M9tIFtLr_ahyVZrt4TybRCr$PmRpb7Fc3x)5`Pj0wsY|<|No!X;~CsU zUKY{5^nt@J62#xp=ZqsU{QrFT@ZrO{ZSy>@@8{M{lFM?tdG8VPSLdiJgrzb!GE$QiRi=_=!Y$%E! z(Gi`)rl_ZD5ykTkaqq&tBEM|WIUw2zQ^hTZex~h!#G^*jdU8PzaZ~7K5BVlI58E6e zgvY^G1!@cQ(0W2tPPI%Bq2$pBGLf|@9HFXnLA2fORDU0ez#BM=BB5>sXyoLDl*ngM zbOKO=tT5z&Z>M97o4gVCIzj7P^mWAX`S$pbBe&JPJ-wMK1uzSOl!N%V3HO#ZVRO zoN6$1C2SbzrGUF$r^{wf`s^{+^})N5Qig!!sM|*sR70Y>rW+Gt5C!DqMwdbfAbC4& z{V;sGUw<@yQq&1TCdbUVto9_m`Vwkrg2rNsfJ_mH;tp0Ko;y^7FNTi0H$`ID%X`={ zX^D910DT8zRRsWYu8Vi5Qx@8jA)F1pqBzL!iua)@F+eCo#e-A|MC!jwFs z1r?88@^qhM7cZ#_j}Lqy6^QQkXuf7*aTt~+zE4}9e>It;aiQdgci5abD3QUh`}e~w z4m7qnw*qh0aE_I$7I>eF6WF~a=nvWT+U?+N%fEy_{04&Rkb;ApRsaA1002ovPDHLk FV1o85n)Ltx delta 785 zcmV+s1Md9N2B-#*B!4_mOjJcja7?UrS#nA>W zuy|XHT12I8RJ@91nq*D4fnj-0Ilhf&L@FBjiv&yn000YgQchCK_h z-BfMTYp~Wp(hlOh>vc}q7MH( zA3l8e;M}@xx10NZom){kj>{qZhoydK{pfAO-q)gW_M3T592+ITk2J>fVs> zxcEi@gDDm$nj9#pmP=D5<>3wJz=HzYb1}xN)zETECt-Y093(hiG|8R>m4rLupn!us zQ*q-6$NLZvNP+NZtr7Eao$nmwBu1eZ11K3Fh=BFCLVqDek;vbD=E%&tf1?NnkqQ`O z=6$FsFd`!?m?qK0lJw(VAi%F z1bCNWaes}$U5c2sI>n?RQh96I3@|i`1qyXgCVR6JmSJ=VTdH_1cq6wfzgKs zH%aMdiF_L1fW)YVxD8ze9A|w>CTvJh+=h-KMswJ-n2eAb!#;G_Ssg+^A`7A19G51+ zAiL`+=FA*nk(gn40u~6=Fu~AUNzR#->=`R+A%B8@9r~>M~WV~_38)! P015yANkvXXu0mjfTxM!_ diff --git a/TMessagesProj/src/main/assets/emoji/0_1640.png b/TMessagesProj/src/main/assets/emoji/0_1640.png new file mode 100644 index 0000000000000000000000000000000000000000..86e3e0b89d84c7438294eb29036849b3447603c1 GIT binary patch literal 3016 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 KMNUMnLSTYXkH4S* literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1641.png b/TMessagesProj/src/main/assets/emoji/0_1641.png new file mode 100644 index 0000000000000000000000000000000000000000..9b56736032da9ea6181fbc1bbee6abbac61ebb21 GIT binary patch literal 2302 zcmVq81;c zobtFK>#!a6y(Rk7a1CQz_`)X=9~A{JD)zuNsx&UvnH2iYRrtas_{Tr{&s7ITK?p`a z+@BTu*?7ZuC4~tb`qpvg)~djMHY*_w&W{k?p%iKW2J5>;>aH9A%PafCB=ff%;-nb( zy&>9&pXpCGyl*vz#}M!O9TAqt^V9`Bo7BV83dYK2+5i# zkW>hyVh_zqD|*H= zsajb-Buz##WJwv)>W3lFb>9gij`ni?Gb_ShJVghMzTS!6c2sf6Z` zH|V}<(_SclI1q$%Q_;JMc40bn5*4W&AhsYQmvTNFoRfzY84N|W4gdfEFmzH*Qvm(^ zAN~qJ{_y+$EEW3WRsQDi)5E5L{f{QkV*1nNd$gCXWJ1#DXtnp+&wiLn?)AE$&Hw-g z=t)FDRCr#UmgPenNg9U(j073vkQfOhn`DzcYju}#cNg59xUSs&-S<{E%rvlj+w70| z(8DwJ%v*2Qbk&{zmx+FP;Yel3@Pd@#q^T@j_^M{MLr4 zC)H{p8tqH8C$}vm5Q-lf>)k>;9(OcR?a9=w3==P+@oHXAC4E}A03Imkwskx$L^Ua2 z<07e4vgp$^R8GP7WaJjpC>FG&Q~`$=0ZS^G^g%gV@~L;laxs}Qt-6uVTcRLbYT%y% z&qbtCrWuh9MXohf0VK$RJm#`j#k?6YBkj6QQJj&l97F^pfq=mc()BC|lIDVw$EZ%}Pa?_pml+ zRHM?YGej(g!;1}vVJaxJly6q*vIoWZjH1hxyhO*GyAe)07co+A)(lmi^P-SAOU|n# zVGqP8inI*`U(Xw|u6R;Vk_3yll>LuIjp8 zJs|KHO&O}fahxRE1&?E!ln&le0vjlNdB#qU}rBbOS^CV4^QstynDxW}iNQUfz zA9xh_qq{P`@SjX{|5Z~uqu5%G^d>rsD@Mzrk==zC5^Z7!dWGD$K7JWY7kuTW*MIw>t zBsySlIK<(QYe$wqD73zwN~Iy;bT}MNt;5@GM*xysBkAz4n=kv_jaW_vgAtQu(`+`4 z!kVxZM;hROz(hXU9B0`qa1_LY?lJ;Ffk)36Hf@S5`l>8Jix_hZ3Y1(!{5?*(7yA;8 zQ3}rxfPr2A*mS8Lo+fN=mpPHI&+O1z@NL$HIy#F z)@Qeig_v-ys8U}62F~VL$OX564-^wKxOthZ6av)Q&TD*|E3l%q&=B!|m3PhWDC z8YujaRi0L4N-&*|n5M`n1gUTxP@pmt7tgx*pcf;LRg9*I;6c!|6~XF3gdj-HYJdS0 z!#XHjJaWNj0{tT9d6lBYoe$r4cUWZD+IqLOO^_BRW)dqanZ(Bn{?+E`0q@@u|12X* z!BHWbj zetCZelwONLm^phry44R!$np*I^5Qh1SVS&7+@yH zz?rMuhd6Aou6D|>?Z8ivjfIN@4i{(_)w$20K;cvw>vI!v7V#O^BV*+GOUgb_WC>a3 zvi4Ta@W;bou#;)XH#o`v^XlpE9}<*-Rv*LRS>&KGSXhn%I@gH4}-Vla`;S=n%Ll9_&R!|-r(b6O%{OOBxraQmB^XPtg8z_59h zZ)`q%aNV%B)?3?~<}mw+Grfj#Htdv<8BUxb?BeeLUvoU`^;Ye?M_EO0dcC#Wr6RX> zodfPYa~po>t=_vgHa0do*3UhV>}J4$ir95Hikts1F!&#?-WwYoee25TC`fvX8OU&E zv3HXr$wU932xNHspDTHb9DA9}3OM#|^0zkcm*IZ~hP!wFb|rW3BFEw|WO4P6xZREa Y0YhKVzHl-avH$=807*qoM6N<$f_UIdWdHyG literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1642.png b/TMessagesProj/src/main/assets/emoji/0_1642.png new file mode 100644 index 0000000000000000000000000000000000000000..65b58c6f6ea002f486f2de9c566c0f491f8a9fad GIT binary patch literal 2509 zcmV;;2{QJHP)ee>sUY5<82imn|JPys)n{{44vZ&>`p7_V4;1ry?a?na|J-o?-Fn@uK>XBW!haTf z1sZ`LegE2LuY(-Fh7*(yBe{ww#Caum4Hy5)EC0_s|I9ARkl@bIg*l#a+>fgoDn}p(7hk&6LZ_ zpg52uW(JR1gCn)3UJEX#!r`_joSZpYGw#dbRMXT#PDe5b9;8XRj#kH|<#4iWnvypZ za8?|yBxq90l`q{#Xrr>6jLF$dLGpS-p+LattboSlykuW7T5$#P`p%rq(p5i2YT|~>uiWkQtq#(z$E2U7Vp(ujFjk)dhp@`n7sYln=wu(5# zlLDjGSDGd7xF9Iwwie647{eGDRVv}dP_am0AVGst$Qm*u^0qn|Qe?GW$kC-{xq;&Z zhJl1B%Tm5>>Y8|Bz|K&J@p@flqTA1&zGx6g!EbHv?QQ4OOkR@}J1cfXF4XIqwEyDi z{8I-8p#r;4U(WAuYgscd({=`9R5LSmiCKQJFrN;`C{QGK=NC-ZzNDH3ou05UnkRIm zAX~qzMI8@f6w6YH2ixgusUo9h3VFuHc)BmDS+j0%yg!jh#xMfMF`|-mRdAAlb(hVJ z+L(}wx|+}A1)icX_#^y&m{$~1HZ$40VMp=%oMvP*GD%@5e9R9XG^n(eG2^=NxgCWp zNrtJ@Jcdpc8HTf7@J!xR4J~I&!N{_#n^qYf56_602MiRK%f^jdPC7AQLm`MFBjxh~ zlu;_DwRCi=hEXIF*K-ocPq=?wF-8jla=@ez)6rGG9P5%UknVpP!Tjq^4~s++#e)k>c=u)PXK?BuUG8^yWT{ z4o8!Amg)$}Q|0>o`(=IGU82ZwI~R_b3IPt|76aV-sJAH2Y z4V>N1qV<4)Z+iONgnQr=d}`>>+58UnG|S7unMMMhU9YddS?tf7>o=~o`Ij!lzaD(A zfM4u?~zR5%bwp+m}XV{vimAd8DP9Pe<~JJ&Dw*QkJCFqup=LdhiB4TKZbu3~ZN zb@Dy_w!?in;i@=Wtys)oluCYotc7+1&Yh)ID@#kSJKPVP>GJ+wF14J2B92n5=^BfU zupNkPtacO|?{OUQ(SiQmfH#7%Y_aI~OKQC2FXAi_fepb<+puGC0`Zs>@8g4gy8(ry zSR6hO+sZS!c%bFSS&F2|ja8q|x4OE4IML-g@FI%=AL*?uj^+s*1c9h3Q)JwTfrEhM zCi=j!I;U8?*y91jDXw>;Kd#Um28KX6ZU_WHaJt@z`O(+VJ4ms^0cQ{6%0VY5p(FzL zMpa#=SQZ?7PAwOq44SJVMU@lUJpLX(*-=c90?$kNti};63gICbRaZPcMTgVxa&oGB zg`fqkkd?Svghdm^MrsNZ&x;hzZ6L)4cNotCCr7#pQO;&_hOSAGA_Ol*({Ur86*;=2 z5T*CI3LF&OM&gB>Uak==ZYfxgrxw);s@2FHUzG-~y~_>Y-9}E5a>k%*rDoG>Iq*hv zrCB4jj7(O+;Hz?SMyG3yX0!1Q=MRQ+a6F!o`0}%7FZTjS5!rt6a&KE?Or78H-MQo2 zArIxEsgDnKe_CpRVRoM_EDQ%>6|j}vg@u)$n}V7b=6rV`0&sD6x1SFquJ$hHQ<^FZ ziC>;h?msBvej@Sn-td0PD{8r_W$;yj)4;Fv@o)(ERBx?+Zb%%}ayWu5tk@#(MAA`V zNk)>P2rD^5q7UI0`)*6_?=^wv36{WkrbH7I;h}h1&Ry>qd~>=c_BaNM7V(Sy*NdTV zb(yOH@_1;G@^}a=LW4$WLjj4fgMozJ6!DJLWd8w8yRK2(c!cIIg@741`8u7 zl4FL?o?VeK&jxB_!=t>-d5aG-m}jIrr{$G1>kscfd>my2nx+LNdU}0*{Y+X>=8$5p zd^lfGdjB)J|8jc$?!9}nvp+pPx3;!+?(t9e?%jR3etP=44;*v8>(i$n9>)I;hJ$lAAj)ChsTcnp)bddefZG_AAj=cA0eN9^1t|1v{L^I XrzNX7u_*zg00000NkvXXu0mjfy)Eid literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1643.png b/TMessagesProj/src/main/assets/emoji/0_1643.png new file mode 100644 index 0000000000000000000000000000000000000000..e4a5b7dfb51f04c42bf460ca096ac7d598720217 GIT binary patch literal 2018 zcmV<82Oao{P)@s ztQq&cA>pJL(v=kd$}0TABmTxF|IRG`%rNh<8M}ZG^tT!Cwjaog5a+fn_QWpmy(%al zuK&Ua#?cs-ju(hYAbwM&d-cq-LU`w1=C4HK~#8N zotEWW9LW}kmu7$+E=~wRHz6S|*Gk%T+}#a#_vr3lzNdO1@?nPVeR+6jKFmAk{7!XM z{nmxa-r zctSZWV#>K_WLBZNScEVsGe{qt4eRAz0)HFY&SsFIk)}V7k!jd~tF_5UsP5 z6R%_&yeFkI2m?KKu9yRbd~(M=kzqu1 zQRF2yk!X@lgolNy5EpNI?_;6}A`b#lh(-lo=6PNe5c#)@4RrJ!YAY~D2oZQd#N@rJ zjeMA3=8z<0P{lR~8t2LYtw1LtZ?4<;>?q#3JO^g%GFs&V&@}BL+@1pcj}52H~|V|7RX4+aI^54ZIHhk}D`U4nqIqW-tXt>D?fKvPvTjF~_~N9BQm zXRah8Pq!HjiZlQj4fw~i{dC&7Vfu;3bHMOiH?FQ4l}Ika@OYj%HZVaXlFQ{1X`48Z zNPy>H&|w!(m?4))#N+8(La9_Lp2&gZfukg!whi$4!%FolP~8DnsO@;T`7wF`^K63F? zdI#<(K8u&x?h6jsf-RrvI}bq_@x*;|U5q3^QNkuc0xt)GmSsC+jCG{%#6nQV^ZOP> zE|E$fwiJa@g!w=)X(HW%S_r~OtHwg$c-uXUo=2>RijI(~>x3X=`g{ofDpbXaQi_Fu z@$O+v=i>2Htg0buh$1igd_Iev%L2x#p`ep+EDUrHV-XCYSQWlh=h-0;V92t_OSovD zg%C6N7rU>Dc#0{AN(5x6hGi=(s;X4bRobrN)5HF*QGg*7s~Co+!?*fa6+v)VCOC;v zih>$C(?D?&V+Q|=E@?gtg;${p zVyFb~m&(nBEG*3EO}TuuQPYTuAPjKyb;+~mZFqGx91g7;MS`Q7=jXMWoQVc^>kCu0 zAm&t5wH5xc&UucEuZBSps~Sa$1wNS!%3>xe%J3ixIyDv!+lnrEK3E09@E+_ms3Nen z6(Fjr2V{w7_oNDhZ7cdZ=eg*=RiqOt!XjIp5=YqbrPFtc#m)n{Q^eC13Jz(# zd3p?(5|1_RFda|9z?h=rNcvyciuQKjAPN?(E4W~kk9ZL)q>@PdQ1o}4DN{fZ2~cbw za|#wDU#n$F0#;~~9W8bk{w`DP8S{THV!KeVPj+@Wuut~FKm^KYhtbz@sv}ExiiGFm z$E~fcFDg+qO(E*>M+WPpT}9tWCx!n`aR7ofn=in%{k*m1u@$R+a6IU=Ec*N`3g`m_ zLqos+!qCv#R>ZENn_}=*5kJ^k1Hr_^zrHgu0g|;>-y0e1tnjl&60g7jpa0`0zygj4 zYoxnkY;0+KeEbnJfZ$h{bXPv)@t~| zFZa%1{?k__9HGlh#=b(i`^GchW7_PsFC-kE&yyD6qZj?jIT#an6%c9^4`S?e=k$8- zTpow&u_GuSuKme2`ok&x--IF>nb(^d)R`C#3P1}8Hu=Xr-*z#{g%BIBnRy?_tSlorQ}6s>Ox^~5dRpA^=c z7XQ{y|Ik1G&pH3oL=_R79~hSY>Z=q;|LmP791h>RU8RLkc27QDKo8Hv zsIrYH*sn^NWkM+*u>SMV;$7Ys5^t`SbGSCOR}@H(Z5uo-9%@k*m`7N@Qi9ikPoj%; zhHrM$O3%ZbSBZ0e?r!PgmN|!Vg1=eO#{d8THFQ!=QvmQ#VetMn5&r#G@GN_cCK?A` z{k^RF`*`p|#oz0RpYPc4@cjJQq}A!z!>@(s>b#4xyqrvOWVD@_wL@iP4AHUi*ux92>Gz<)jMNZJ03lA?mbuQ z^I4BvIzM$|W@hHz+~DLT_~<^9Q!@{?lZ%UskCNdBzYR{h7Y1j7k3LCoX3(uL_2AK? z#bh!W{E%d@G3QRW`Xf9Y4u=<qFw!a{m7L{)J03jbp8x z_xK}^uh-3&{ zS>h27y+kbHk#1HvQMuNCN3LF%1V%sJYvvIPLHXw1F2`YVZLnDc?1H7VHs{Rd5sES z6zis{o?~fY=c*m4CVD7Wn>$)t55Gq5u&wsqL)(@VzVK?5#CB`wF2LQ=;y# ztvy*=yLHxu@a2;yPv+<0vcG?FvcEOoo`=Ba33o!f-42C9{*d4A4+KJiP^b;iMBf6G z;5=_90zVGp7(@LC7jHQw!1L+C=KJ?s>Gam0e{Q7#v5j-1eGoT0La6Yr6y6R7!^gYf zU~s$iF5NL^`zYc|M@T;n!;oYTDftFm;jXmh7=4s6F%N>junPqQx9uV2?lfFs%t@9C zj&bUaj@_KM7qJUdO=m>$s1++7Z!Cbb>#XIAu~XME9|{Ei$W1SMU@q}`e0Md|8Bt(H zu&O|WPF=~_`F6m+>C5XnVgax$S<~{C$IBvJ*Nf>C7(=J^qYXtI>lJ}#0m#KwjmUB? z=kv0Rh=t8mBoH{ICu6tZKomrZ8P;RPb9q@KJk^w3&hjFTCYq^8B=Sw~%@{ow3izuD zDk85H&#Rg$B7}%0FXwzLk8wE-#_(wGt!M+Wm!JacEvlL#RT%TR_BSdv3)SAVlg3Oyo?~5S^|-H}ncMHLU`h zvAG_L#d@BMi|0Uy)-h2tSyk3l6Z#5cXBqD0tcI~eEDenI+6pKlnrdQ_&8k{iXW0$` zYpKX`M#iv^*wWHcug#bMA-cYoP+O{~7wdJsLllpW>N?h11Q%@L;e{T=Y$OWAW+Ic3 zg!x}h4FLHfZesAi8$-;($Y>k5>>^d;a`HqL@QGj~Eez=lg_1E1Rh( z5Z${v>JSlsp}10izOga#<}INZClZ*JUvF$|yyjM#k%&W_=|&7KIYhu;XujSU86SW4 z?9JQ1A#dM|kB^UxY@BQc{2z#+Zp4|TSQLm*=ne?aF8}^tE`R=Pd}JdO3YEMch?q^>v4zKv|N10=fRR3(7#J8B9v(ht3se(^t(bC958#oiZl3 z?y?;dDM=CzY5B!A(w7(v2}2EBSJj&#w~Q+^4shkSMhHeg4hlqBJQsZ&dxk2O@OJDV z8HTcW83PdzJ1z^MY9sr>A^pWB|I01*y&>?k8uPdv|IRDWl@z~%5Zjy*>8~BhiV^Cq z72u>7|I#z$sTuaeFSmIOtZfPZ%`*SiQvS&*|I|hQ(LXOFwExH^|Ia!8+GYRWdj9C5 z{Oi2KksR;2B%fdg?!GMe%1Dk<2Isde_S16q$Sm^1K-{k?{ojUhRT!gv8``8D_qrG# z7`OlN#1;~L2?+`cPDmylt|=h3GA6tWT2dt)!T-}MmnM^GQhXv41%_Ze9v7N?8h`%j zuF{?zs+4m&Dy4s9bnC)ZFe@Sd^|0vCkAOx6*tA;5nlrGBCSy*HePdZ-O+vesNQ`M4 ztBOl2BclEC(;gS75_)nR7K%qP40$h9201jgG_wtDXDKaqQa+HpnO>rLNkWJ6gaHCIPB5c3UOl~OSlQ0B<6YkFZt2lU&K;eVk54y`oOT=l z00264QchC<8bJmA=lu*W=TiJ)_x^|daeN{9-RsSZWTN}8(6gE6=jZ3W&-CTWPjXlib|e5t3Wr>mu| z0WNE&uC1p%5bOhjjpr`6G}UfsIX8FDLf~9Wt%kPtd-wW+!MQR4b4Yg9Hkez5xjWID_4|B=1!wwNbM=OX9)GVkpLRI`m&7cgQzP;9 z_4T+(B+dv#OZ5tpV^|dRcsvM6$fC%KqRi1WLAKSPU>Op1P!xqxCgbCj2PJr+CIt;e z$n<;|Gf5TT9g5H_QN5y*ph=Im9?@tWkirpI64}G?Vtw@;5k&-@FE}KJu4C|WU@0gA zrOx63M;Swt%`rDnIftOBjP_dnkfewF>kh!Y2 zXVXQRF8bb04NSfC!&JuCRtBbC^(iDRU#PwcnlC!%rtMpeK2T7B1$%xifRYS*s`{o1 zEQxrHbhm-&Ua#);rDKK%Ay~Pk`i{sV344>m96Dwg7zUdRHYz99@EfT+!x9MUz%U&} z3)rMvm)$~vI3WHHP`g;6>$_C)VTTUqQKxm$;vcpm?_NI|mxhm&?ek3;>U!6pE5;TdfDtb+ZgAv!Bc5O#?36s`)T#IZHwv z)Hr~Ffj9#Vt&xwuph+A-%OE(xeDP7Og3oXKxWW)c90Bm6kYD-n#^*Ij?p*!WWSSO= zfDqa(U*7n*dc((`ecRvP|L|e|^WAA+^5M)wlm5^C+EBHjESQ;@xepA%-^_iu07rk7 zjyq-zrr^*NR5(0x{GYkh)wgwZwcWnD)3G%9eCFumC3CnxbO?&)lS>_4U0p5BzrRHq z>Myt3AV}DHH*Bk`fwhH2Q!!iy959*5g|)f9djO=KuIAsV;IeHMB2lm}m`=hF>|1@i zT>?V|P;9>qz~_%??E0{h=5tU$078i^%XQmqfxujFHMw2-uV8rS{$zGF*m#8b6@i|n z4-DCCGFgr!F+O1!KA%6^Xxmska+J1{w)Q0817K)xUu#dkmo}O%`MP7VN)$=?aBV%?I%8=?!E~<+0tusOX#+A1rbLwtlu<5X5)wvK zfdc`a#^uJuc1>RwoZG^5EB7YV_tcrk=T_R5OVi!jIWEQdQJXN=>*3RJ_Aq`>_)lTMt# zF_&SaLmGoaq>wcx=5y)}yqH-W9(E6vmWqPNken!TTr?V%A+HcTk8nii@us?f6NuzW zFcDS8B=Z;!t6IismO;EQ%P74n3Owy`IFxYMECE9iJgl*VaQ?S`kOYeJkqC`|z(jJ; z5hf)eL~*j@c7uZ8p*#wMJCYafryLl?X|zT0DM@l_Ji_9slx{A#o{EOqh!*w`#if$l ztb$cJRAf|I_nJg`hADVtm9;83KCbbq$`rr=jsmZ0Ok5*LQ{i@(b{HCwHJVc-Z<$m| zW(b7kEo(t?kqECAQo6Y{Kp{y|f??uJvAAtcWOzqqNgP))2}Lg(GV=)>#YO&n(~;s7 z!msmqDzmw%R1}G=t<4mvtrO&nF}HhcGOE%f(z~$m=pbz>_7--hH*iE`l(yrhlJU5V zY%X-H9JtK2NW;61J(6Chp{eeXu_c7(iSXL)?$oqT_e#d}?#iRJ-XhE3$1Q0-8;=O{ zzjjPb9oTf2OSg4EzWH@th%hfpBO@bYlLEsC%Dw3+`$hm->R*_8v=vN(Lhd|n$puvt z!>jM?`)hr$&GprHxqRbXSY+7kF;npqG($%GYnvO5e%j&fK;bnwoE^BCbGImMBi3BnYd}v(2T& z;ju~?V=s6CFDp=*kl;Rs5<;gXOLU!UUuGBrcj!uJE1%!mis}xib2GWNuwALbJ-owm zh=a;M%H?wQeTDLnq%}2Nwq=c|dY2|pDrzt1i3EifSuK?I+kE8(h3$1X%@VjLk(-)= zc7TC+FY|O7F1?`I?KFX4(Y)Qh4+ccc?T5m;b7OI&tT-I%&zX+#XeN`Q5VA=B&3Z`J zUDOky{nxK^A%R54DQet<6zBi_dNFmE;q=qiiP^;= zcSZ4haCG$9vj-0zJOdt7Mvz$Y#vL$#;O`bd0**s>rHDaO@Piewj1FEs?rX!BU;x2C zEPwun=@q00000NkvXXu0mjf2xB-q literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1646.png b/TMessagesProj/src/main/assets/emoji/0_1646.png new file mode 100644 index 0000000000000000000000000000000000000000..b49afc1f0b495ccc736bfd21e8a0bbf134b534f5 GIT binary patch literal 2253 zcmV;;2r~DHP)=DB+|Q`_54ha%u)G|H>-krWg6YBJQvm)0PwVyC1xM4%(g;&5{-W(nIsUC@&bNxsLq9DctoO-HJT9S~ay}Rk2P7Pz*KBi6#nFl92R`_ z#X(a(6#VSK#+xwSwJh7nnXHacIUEBe9kF9hhyC1sfoDkr5gt-Ke2Qxs)2>^Ob!nbq z3Qk2VK{A%9l6JtFTWvxJZ&YM5CcR*6G5_`01~e}uEFl<-gtLezXHGd8Ic}zO6uzs1 z+_FqTF(@KeLq}ve9GsIjl4d0U001;}QchC<`~FA#{viJF3I6?SFGT(z+kg}BcV6gQ z{=16L@az4j$@Bf-{KeC$xSa4qmc{3VjwAJ$k%jXK{FBz z1~WlOM(2ktlo(zp9!?(01wE*RLSV^20us8{`mqe?2`(+BC(kC+>dH(9tRcHnaQVgC z*IHKe@mO^b39ISD$?rLwbYRr_!464SRtRAjhDZYDQmGV&1yK~Fo2@HQN=AfDCX;L+ z5Mbd2%aDX0TTt{NRUr&^DTx3LTW}S0h8GoNMIj>Q^VwlqO;Sbn5Viy}*w3}T7j`bi zGYZGTI*hPMq9lkUKD^etqMzfL*#6quf~hF3jm!{&aF4U~%c-PDY;}8k^i-pU%J#wN z!Ip$LVW?%ruqyJQ)zQ)Q(+DgjY5O)hIuob)j%dnJxbF@ZbeH5|?3W5}P#w^wlc)}!C_GV`vWRnb$FqE*Eu6_g# zHVI+DAi(osHP`>6B8ex2Fof`uApddQs-W|?oo})rNjyYC!smB8zdf@gd48)K^2@f0 z5d`}`b{p?ITQ_w6(mg*vKLLN|+an{}yAw3&;1$i_Pu=xLako+|>ahS!BH*ASO)OhX=-+FMMNbzRd64pA zeGPjtffb&G-|Lv3p;a=3moPdo6&qu_S>O^=#~I3p8V3r_&n1{ZP|M-;kQQoK)Fz29LZ{Qs6s@==moI^2w^kKJPwhP2qmi4CX(7fJ)KCYkb=d#El7OEba zHQ>Sz9;Ezht_ZyU$7b}U(tebg+h4xp)3iutZuQ~Uxd_3sxE%JpdgbvP)OhHE+YDa2 zp3a`MED#1B(F~(S7*-2uaC_h`Y=Qw&eVCRpVWv$UV>L}nQr=%T$~wCooH0;jbXgWN z#z=zjNY!I1Jk{NFGv|h!jsMA00-a{y`4ZV_>fnXKas0yYDjq*K`Lw~O4c_m(JWyan zSbcVJc6N60Ly{#3oo~QSn2vC~`r$Gcn#MnS4+oCrMVKdMSEykmTCOR|W4jMI#Mg1* zZqu-E{nlp;pJ7*4vPqUl!rpwjUQwQZ_nE8b51uz0cHZqNh>kW42*lZ)9qKR@)Ub1z z-@1O;@U~QXd-TAC1wr8ad+**tCc;p|EHUx6nKwGz&q`jex6SMQ^RL&hU;p)|7g8#f zqT%pGi4t%~BY#%E8=WO@TidS0SAJ{dK_;qs@SaFBG?m3ZWB`}N9|_jS2)Ic5|2E`3b$kkYJka7(Gk!k00000NkvXXu0mjfaLiFY literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1647.png b/TMessagesProj/src/main/assets/emoji/0_1647.png new file mode 100644 index 0000000000000000000000000000000000000000..a9ba4df4f0b333fe7b4f9295412f5b8259de7782 GIT binary patch literal 2416 zcmV-$36J)PP)p{jzdQB5EcwSd^TttoFjIja zh7=HH`ok){L%E=B9`kzb_P!?j%Rv6&hf)?l{mVTuCA0tAbR-K$_rWgy)nU_?7W>j= z+o2u**I#@aeBh%N$Bq{Ey(Id@DHIQP^~Orzs3eRhiT~JT77$!oJr@fII{(Twz>6Q` zrx?M96d)Ld5e#e&3`7qKMO7^q;IBT~szQ!+Pw}=K|I9A`%`*SWDgMSL`Mw|f!X*FC zIOwez^|~M7rWf0v7O-*)#fTH`vKiBs6})~9|Ise~oI{!YMo~rYIi3np_3$ z)PsLze(1M1q+|&G-hJ`EGxo(f{pYIx?yfK;z0IH_l2itPMg*{a7m_23T0xV+mo|AA zcb|e}{_DEKgfF?BYO;|~B^n63tBinZO=(eFIxr~U!g6d<8A&gUlxQ%8PYj-WDP27f z*se+=8>}4`j=OG0x;M7}^U&#R<=3Mv7ZQEs-NlVlOs|G7V&_`NirBa3b%@&Wfk}FhdD^(g000LANklH*}7Szd4ifk3qu zFpS@iXQ{r%6&+97%9ZJg%4Zo@DC7bK&fpk_9yh)%_AJYbia0$pEk?`9WHK=}n#m}V zV(DsF@h!zFD$TJev2ZXmb8s*XDNIW&YJ6k+I93&Cnj}e@lUbe@c%EeyMds{HCb}5EVF*QUvr>!-_$qaHKd>5K|5u!*ENbaBz?z zS&46aEjoFDA_bms5GS2rv|yn*<%hN@6t~0chp{YD*xL;^GMthq*ZAhq zCyx&lm}lweu;}q3RTyY|Q(1wdnNV9Ygy9T>`+aSR5JAfV+r*Br0wPJ+4)_U$^aDwP z;z8p(V*6f@X_C;+qhSjh{r=k!GL6VewugTAW@ANV<>tV=|1=fTU;2vwT44EQHEOWTKdzb|S z#XfBM6Rq=GNCK#L?QLi>4_~R=>X0tl+0_!rO6~qbLwii0$7F zfAhDdBtJgCrp20K5rmbt^go|}*|_1$YuDbtfBzDGw?6Lgf82Vh1^&GD*TxMXfOCG; z@&ckA4M~HJ9}R>-m<+RN6DncfWAEwHJ_pV-LuntsCBD zzjTW`o((xY6BC{%$4+=HuI}jqBU&AMrX7PnagI-ToHx5JRPbzQA{K+8B$h}nLt+!f z(up9VDSj;#&-2*O;2#V(JuuIBJTR4%+ni31XM8#4EJX|lC~~XLi~O9!HUjfZP#;NL zN(Kg!U==jU`AE%Bbpj8b=XcNcayytzB>W6aBd)9{;o3-&NZ$3Wxs61Yd^%?|uGaZ* z`l1!($eX#6jTmy{qskF&PZ`ae_kB zlF`YU_j1nNuC2r)4$(N{^7#_cv_Np8>H`Nxa@4z=X2@lLV>M2Rs_q~;?vd@Z4-4W5 zCIkXel`#zCM6t~mVxSBJoj@Pl37;}JGB`$|+T=6{C1cDebSaQHj$;@trKenej7D5Z zQby3y^ieWRE0uzTFx&{nr$vi{M3hNWm_TtErx7(!Qy^KIE+|~qi^IM# zxHoIz#R^Lp>ls-xc6S(sncn_kwC=60hcb}^+xQJFry-Gd0}A`*Az^7;nPBvQfCCJ6bS?( zr8;MHKB{vG_~~+XS;QHIo?2bn-b^r{7+W=MZ?3WY!7MfJ4ov3fxr=-Y_{?nfbW^(@ zrKbgcV`DwM?}1A3;6^xn_+dd#r;h`ZlaqnKyHjq}c@_A+#w+!qd_bxQvh(*{>&_dv zkuc{6tF;&#Wu=rUKMBd3Qfc5Hc6aN1CpHGWKK0n{sR|;4#iA!jxPll{br!2Q#VgU= zWI%J|KB=iX$92vC|NhJbXnQEJG>I`7LGu}e5g1O=NLZQA>xMu+w|^PGbM|@B@sC*n zE*uPVI1o!ZVD|P>Y}Ax<8;!VgB~`h||5+P2+Tq(|Qc_vYi+QKwv$OGd#^I$=Y9(3R zC_x#4-!_VuaAjqu_T6*P>GX|B{XeiY;kAY#>r)Pr<7eaLpfgy?=S$A2#^b=T8mA0i z9W?Isgp0|OapVgIgZk>U-MLJ7+e(er^8c)ym4st6$7!bIaUf&z5mrxO1C5y)BpU z@4#@HFW?=oTU-C5ML)D&e{F8*&A9`5UhK`)c&o-+H9pt-McvT-w8ebA_3F>{T)o<= zI|2c?McldG&+uFIA`HXZf1l><+n=wtUN^Vw>1DX*b^i7uua(jMR5M(;^5-+Taz%6W i{zXsA=lIih5d0Sz#XViSI5}qk0000F$ic3&=4pA{SoMxcHP5e_hS#}*L~VYp`m3kNH7MrVeSAP$rX z6cJy!Xa^4vV!I7owHIHo>=6>_6AkDR5(X@G85~TIB@O2g5)3VM4qdk14-o4T5_}H~ z2QPd>7CCJa6?795-VYM%7!v0Y5!w?MF)>^gX~eA+7jgy=haeRcX2E+57YZwGlp+v$ z3l)qT3k^Y!30}8WMOn)q6cAswjR+RX4in@z6Ad+f4@;aETdA=S7S4GLK1-3;Um1@Y zHj^M4zzGdh0|u8k2zh*GM@x-q2^G2z5zP)0VLnaALl7V&SP)mMxC;;e3j^(16YmKI zR5v%j4iRht2eu3m3pj=mU9{;E65kLK$qo|24H4uK64nqArV9}bNSU?`5f4_Y5m~R% z4iW7V61xl$uL}_jJ&Oh|dvOL12Qz~45)u<)xergF4`jd!F@B#43=Tw-3`(8_Dsr)aLGj0PSVvz_8C}N~07eHJ`MC}X;)I$qv*f(>it%BTI=@t;QhG1ukD}YX6f1IdVu|n#pV5=>+0(@{`CEg@3eFE z)%T#xzvubR%8IL@!ua`(k5n|(000OsNkl%p z*2!WXGYvB{3Yi(ql;jU?j~vO?ZmPWdb<3yf-I=Mbx6eiXH+;bte1Wbpw?DVP zwY9ae;MjJdR;#Tpt=9fQNY3$%+`kT-1eizhj?T`e+~0Q#OY3WEYtNoNb+)#>w7L*E zj`~k|8(Rma%w`-ne^^Eb`m?F%s_R$g;M5*IK`bh$)9uyR`~6}Ge24uTq+I`9Fc!ewpGIUsC3If^qlPLrg> zkR(BGFrGzvZO&#DEtu6RggE^c$2n2GE0q#4tX&7fHQ*k+1G!|y;%6@xLKPm`j7uJm z#H)(Js-#3x!lf*=;(`t2k^?H-tyF6_$cu~Dx&k1qc{ow{P?q>*~a3x>8 z65`(unx&-;oMcsYHhA&kcRQP_d*a*{RL?CeaHtnG+3hBi!C=q+KrNxQn`T-jC`r13 zTypB2Ng=+rC^Jh_1UVb2s_E1GxFujo0Sh@@A(wu26@{=s^DRw&ep`2zW^-+AePhZ) z;F3a8cad(p*U4F}FBi=?xg;sGv7z=_!75@_P7pXR=;uX&A-enPnaal8%F1&OU%p(& zpD!*>ZAgSiQ5CfcIUj)He9I)9B#ENb^b>BSA_@9CxsX+l`h4Di*A$%}b5Q=llhWf3 z^QecBWrD%qG899xVK!2QbQ|n|hYTDgnpfF*-`2_-$cocDA%W#()a$j+Pa0==l9m~g zcrhhW1oWLDJUmaS!CW_54?eQ3uyGj)5)<32SpGh z@28jc73ts~sYF;dm`-$ktwVCk+ol7XQw&Mtgc1xc=zV$=g>WzG4MgpBAebCC##oZ% zS%tZ}uPS~&0;y%KNIpOPVxIa(Eu<6?9I(>XL<{=DZ+E_>oX%p z<3tR2AUK#FGfqs5?e5uZYa<*T$!!Z6+o!&kNmKtvhUovbA7!veHSXr4FAi}>6#i_K=Ky>jnR*T$v?H%|^i zrno#hYL-XM8xMYalZwZMTe_p#?n?an($ZULN3dZ+d~U@O2fKgvO?&l+o1x*w6u7F4 z6EqAGjpOnLzBstHc|Tcxco|)*dq@xxwZ5)|w^CdP!%|6bdmEtcnzrOG16f;_7@GD- zH>VheAUuB3L(9*f<1ep#xTr4Q!BU$N%sTE-96NfS)#`G(Fbf8-SS+>Q4nFtbI5-@` zP~?NFieDmmg&}AFL3i|*07d&;NKCG7Gqh|r%Zy_h1{J)~3iy!8skt=|FsR_mEWaLB z;U`S_CCLv4?`Nd%`*p~jUtT4h?%nNm_zdjtnCt;N3iIv^i5M2g;EBI}DTTuW(#9@fFCJV5Pf?luH~1q?O$>UC1YvfbGXMly*s z49US0Yc6Y%&vPcKR;qCYD!>U648M%Z8?1AXa4kdvaGVWR0A1*4ME2_#gnH@p815vm8yr!_S3KU~`aAELff^irpPq?%8 zqvx!lkSnzEEG1gRH8Tv%66ztNYs#l_r!3$%Mxz zCr_Bb2n}u&E_2Yu3Po`~)HnSO5-&$8zbYGp{)`}j=EG^bP!(xuNd&WgKg&{la2z=1 z-3GVY4x*T#%TCY+4j#I?5ItWG0|tKhozYl^w0$(;qH|r)ELCNL36_nd#{f0O`EG+f zn+ZgE4cYq@&|H4_+1}G#UC1ZyqJu=jAaWv|iDZICP^wRd=<>P^hHNU+3)4UbFysTl zAqpz{{>^KP9$l|WB!Hpi;_1^hAFMP-li%#N1Kc1?cfO{$@IT%3*iJ#wg)`T$pSe&} z@R3|sn3vzymS3)cc*yIs9-XCu@Z+1nQh4lo_&m-32fpA7{smIZTC4cyatr_f002ov JPDHLkV1krP{$&6F literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1649.png b/TMessagesProj/src/main/assets/emoji/0_1649.png new file mode 100644 index 0000000000000000000000000000000000000000..c73615f4eee11d49c07295847545d7be87a2afb5 GIT binary patch literal 2395 zcmV-h38eOkP)N)4tz4~8-k$4(5MJP?mI5zbKy z^koa+SPRrs3+!JC*;otYUJ7a_6Z~om{&EjoBNP966iXiyL7ZFA0000ObW%=J0DPCm zF+-ps5p1%>R_N@X?%;gd+0y0n2}J*C000PLNklho}9z( zO8)=nGjj?Bl$&mb5C%tU0D-$xgdk<6mIiIY)Jl+?S;| zZ73ZVXL_qktu4mv9xv8^HnKUpaZ%Tt3na8L?1qG1YDu-$Y+-u57yF9nP zH052Z4UM$pu{PrQm{@^_-u=PDzO$QW*7LEo?1RpAX|*yWmPWK37cJwQ^6zZy*1L5p z)Rs#5cx-G8l{z15jJnt3F>@TfNp7v_$6xZ;dF@Jz8d>TJgq|apJT^9E>1lC1_nx%Z zJu>OGKMiJk5pzm4m)J5mbWb@mx;h@UNyj;NbTcX>?Rxm}-1 zNE>3pAlII~RWTKND09r&qpxFfao96aa|5v)+1>q2V{;LdRW6TSQr8@_KghbE0kb5q z(KR6nrFC4A)+sqEXFo~YIYlIeHL(IAN=Up}a6}$>Rh>>tCn>SZa)jR8$y|K4aal6C zMnYK5X`WMeYI+L^FjWPKV#a9t!`oppeMwH&%8K@%uKcrBT}v)_B^2w}dd((qUuGH- zizCcRGIoMQDZLgQiF1DXF_m@9F3*vovxh0Tw4ko$GFR{F7_XSe0YFB`2(ok1#+u^t z-3QC{7z)rYxp*n1FW)p$X~n115ow)UA!|t4w)An7s7V^)_u<%H0YG&H5VCf;M-#}! z(sFNxj&n~9qtV$~Zq7HLsB;dJP>%0c|FXP~HM6cm0sAkNth7`rrX)7x(KKLI?CYK5 z2u!6Gi|~5B{}<@yu|%VE&XI;r*IH9h0|*wFIM#5X#5CEUD?BvE0Pk!4;JH&)Nad9c zq#YZItqj{ajn#Wfu$I}_!`l?+oR-SoYvW^jc#rk+^>7eU93~+IXa;Z05QSiDP#9iP zZn84|#26&X$W;lqWUCPi{mUP9$C))cHnx*a?gq*_ZGPv+86PfH?fWUAI5jhs=C zhNaZbNP+R04hKmdPXh{JVUDg3FsZc!y}7ej0WI<4`;4!h2})VdktBu~%?N5yLCpdl zHgCG*-it2t;M+zjam>N`W4xKzOBI=oczc6}kR??R4MHe(F-8*LWVt5<7F&X9aypj} ziJdZzrLWNhae#!hrr|xFnCxVEoP`GN0LTz=o3Xm)((}`MA}i&!w!S7UrwKNMiZN9k zoo*zg$@4N-7o= zEA6~I9O7J=Dw1GDJ*oqCW$j|0lO~h`il_1TarSMWnWSWGlqAPW+L#g>#F@!cj?kQZ ztmr0HvWmQ9rs##d`r+ui8vZD|aFE^yp>&4}kT1;S2oX&afFOuOA}|4wVc0(Z@}aRa zY!E}C!vXj#vqS5;B9ulLl|xVcL{IR;d znS>`Lzg_Zh5Pa|8s!CBZOu-pomTw28OU{v)5#aRM1c2H}AyaFNoxIZl`)h3Ew3ODm z;z3o6(f7n;yb4OntDiqol@MSGRtVns;A3Gc1FM6yx;bUcxQ3Cg3_jfk-a zDFG-Um@o|l5-*e-frIMc70j<(Y&W|QEOryY3U38|z+;3U&YK)xh(0F+n5)!#!7J$GC;f)n44FABS{4dfx>$OKs_U7X1e7D-WOCS{A3!C#$vSlyRKbbGPee9Q;14bO5In3M+8+M*>|7Y zvs-t6db{{=w>ruBa|-~HkYfr zhjEvYdRcwq`RH{|o$ALOKPqkA$Z%z-DlI|2B$jGx%Q@wVXd`W{~YZ4HfqHsXXo+8+9S6#r^c|C zYBUscF02%Rf;P$%U0j|9aJIg)4Tux N002ovPDHLkV1it=ma_l= literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_165.png b/TMessagesProj/src/main/assets/emoji/0_165.png index fc3c245b8cda6eeacfe5d3f8b8dbcfe8178559a1..21aa0bd2c51d2903c686065004b7b23f8a081ac0 100644 GIT binary patch delta 739 zcmV<90v!Fi1^We%B!5CsOjJcja7@;we$bqA*{z1ij%Cf4ZnSnyw|rH*dQiN8ShjRa z+_8$GWIo!hhSHpL%#&%xh+fsCeBQQ?@}9Dg!eR$X_#Sqk?e*H zb$gjhlz3OM$bajKm}d`fDQuq83B~c8Z|4-%)(_%T2UVOcQ65xRjPU#0qHen(z9vH` zyoSiGs!eAI07REk>_nD_0#=G|pkE8k(cl6H1>s@})SO?YJEItgDCRgCi~_cUkesZF zjM1XNdQVIWGh;&$2H!=@G<81}d{@?FAjCY59Y6(aB!5nGXY}6`E2p%YCrJs#aS&n+ z()BvedFh;908CMfq&p#KQ(6g1(||Nikq%}xxB@WU6WU~fyhOt=_7UHi9xZ@YW(EyN ztArb}rH%@}oVXUEx|K!=>mcLOwH3rw2ZCi2G-sp3KMcz#V#BDy;Cr{C22<2S2RF18 zg(LzZ<$o~D<{WkfsG`JX!BYNmXd^d}8rq6@WR!woFo!QCZc3cHh62$Y#V1Y(&)>Zr zmAaw9M1&$>2!&ziVSv^sotasas2XCj$v!2~rfmq8D;q>fng;Uf^U6b2!&1aGE|DoUZ+Ag1E`_*`B-iSl$VL_yYoW Vgs5;dphExv002ovPDHLkV1k!rUAO=M delta 674 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 l0v6a~njS;|| literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1652.png b/TMessagesProj/src/main/assets/emoji/0_1652.png new file mode 100644 index 0000000000000000000000000000000000000000..cf1f93e2ee1a9cefdf58294b87ebcf025c3c51c7 GIT binary patch literal 1553 zcmV+s2JZQZP)x^vxGdvm`lo^P`;5y)T&vgb~56*W#_+Yh)@^o#BX;#3796Y z9RL6T6m(KfQvgoXg8m>d{{9cZW}JZIw5OWO*ISr89{>OaLrFwIRCr#Um+Nw)IuL{n zmXQEolNsFwc;EjaPmhS}WbIVKrlG$n zQT35c$kY6tmBvmpY!DX$0G&YbS{aY3B(Ubo*^nYYNLnrI<_E%qPz62^g(Z&p>qM_^LX;G= zX)nlgCD>%;@_`r{VMHs8@s-f!2?*FIs%cWKVm2x`X~YsLVH$QfWppBkN8b*wNvuUA zZEib3%z{|53=A!)65Mgux2E`zt#i}a}~@B!XD9hQ%a)j-29S8 zV>1B`L<3W2*oAkJER-MxP%AN~09bpm0&8BKm=3b91qKLNq=}8gyL|#grLDctM0_tu<$x zAwVNw5kYw$_UkA>h}bmG9Z`#CJQ&A1BgDzdNaKvYBxh~VI#id}x_-PewDI1d=d2be!!H7ma+B!E& zM??F%YjuU=gjPwONA{j<%u10E-5CswZ#q?}ror~brqRatlvW_+fn0DF2 zL4+eJs&E6mSyV{@-FekX15nyV()0-(3EA12fvNMV(bo|-2UN8f_;^)k%z4<$odz~g zf#m6uEDkH8oa(6d<8by`e7ve@K0Yf)FCHw_emoEm@$vC(-~8|adSU_r2uS8t3n1eN zm)%BP0zHhNuWI3ykTVVaHbOr{5(eUQRxe8-XLFTI&?X(uf?-lja5_?8Q@I_sB5)e5l;eU>xOY?PM5Yd z%2(7w+PA}Tj00000NkvXXu0mjf DvlG;2 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1653.png b/TMessagesProj/src/main/assets/emoji/0_1653.png new file mode 100644 index 0000000000000000000000000000000000000000..2603c404e75ac45a69f3d83fccc59fbaa6c63bac GIT binary patch literal 1203 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 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1655.png b/TMessagesProj/src/main/assets/emoji/0_1655.png new file mode 100644 index 0000000000000000000000000000000000000000..085b3a643f80d1bdba582c282a7393fe182841d6 GIT binary patch literal 1320 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 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1658.png b/TMessagesProj/src/main/assets/emoji/0_1658.png new file mode 100644 index 0000000000000000000000000000000000000000..a5e26dbff43e05c89c7cd688f7fcb75bbb0cc721 GIT binary patch literal 761 zcmVkc`9U+e)AZ8XWbR-^v98=FnJcBSNm?05Z3mod5sKNhih@ zn$oH>5A(v(DzI!8J0U2igM)*EgMXkr2TJ7QDufrFQf~Kq(=>HmS5=h}I+E!ufM4N) zrg8VX-c?KhZQCxN!4=@uecDr0N_oo|!Xu*}$I(AA#y;tk+EJ8^a$w&u_ztpQ#Jv^E zGWE9X3(+W2r{0O(c#jELt%rkk8PCkl-UicgA;Sh^*En~eshN#%(mQd0^W*oJIy#ZZd%B|yxg-F^UfflaUD>-O9UA?_SjP*7cUJf$Q3n2rr0Ks*= z5ryy=`k$X4l8A#O(Ll}Q3>KI6!*;gxJoHgQ-N3^HST%wK^Q^Z6Ud_X>afk#rY(ON! zTvTOpvlqpT4&>yBHW~k)NzYJ+}lu@s@WX%T!+Qq3WVwU+;d*pMX&K1yI^TM|0bzl5({tE;cUg&ChoC(0_mPHK7DOBHy*jQR~J4?HgBuGR+Ik&-yd$g9yQY6 zuqi43FnJ{v_6zv@091t^rmy2xS)9k;^_I1_e&Kxs@q<*`s|(~6+hs-D=8Cmestgw@ zw<^kX<@wmz0{p8>Dt{%aj%Q%U(r}Vw>~ub1lB=$~jT(r62V+#_*R&USu;?_V@dP|5 zxb^qzA#pvo%LLzB67eX9HspwZ8A})mQk&*Ey|{ZK+QRv>r>Ji8Y{LY9W&pVC9<|Qc zv#z&3ytMY7m0PzSyFAreTk$Nk%FYY`OdW&f9vFC?n?yX_~^u;rjA2%VznrW z4T^fqePe@MX=?nvVGkiakLXoPI#V?9_HLV->gIy~4-~sw5m&25+#g9a;PNTJ@AL^eJ$E!GXCYAESB<<@nb==p= z=L-;v^5KD^JEG7gjjdDVx1~2*pS(F-BAYdOtqh4RTzDU{kRq`TFV*~A->Y_ zWcvHq-i6;Dw#JXV9emfYpyZl+7u6()Dfg#M1(NK=;~s*}2M>ymN7V^(=f~vFmlJPD z>}wW3C*K?WogSETGBtJl6!grLa765VPt+r~Ki6}nC0ico7v;drOdfdNWZqS1yK&Gc!leN7{%!`+%pkvocD-7FL;=$dg#^=0den2Nnk9jux78 z>6RJikxcT&eiRo~P=sa!-EP}l&t`R;+bH|ORuo!h)xw(4V#$>Ist%8O-|+f**A@z7 z*}Ip5puiP8j-nS1tVuA8Wwo%r(>Ep7g<=|GAcSst;oG{tAP-ISGU&??$RnW^8G#Y`qo&>MqOXn-l!0g>n z+69vjP5_;C1fACrwfj0NriwBp^KIS;&3TifLDO;&XP|JrU%49KJoyD3+b7`TEGV^q z9$@$ogE?4=*{ADlP-d$r_v+Bc80$ja5`m^GP3qcg!_~xKZy?{o>}P>k52K-jEweTw zT5CI)FgG1oGftQuM7hA>27InG^6Wpo*$@l)WhV}e$0CjOeIeCF#>+=D#Q;2x1Qt7l zGo=QNnN2v!A^=lo2>U^mBxJy;%85i2?j}Qv?OKPw;O2+v)cnyv&c}HgE5{F3@ljulp3K4@rjC} ze=UNZuI>*}sVBzAk&m|8CUz~;-g=rup^g#bh#qiv^CH1~3({rirxmh+7pENt6{3ll zLu5xChOBqJ_i7d*lA)13N{|h|^3ep3eTn{+57m(yXd#|#)_rl;d)eiE?AJa_aD}B} z?9W6XyimnIt_`C98ndxFX<1RAJ&~f1pHlIrpEA@oN|D z1u2|KC1ItxGI)|GeX>}y+qPt{ByE|oU=C94Oq9-FJI}pTb+b!F3u|)w1bGrIX>ZAV zbn}SaLDZ(c!Cb9xNF5@$HJU<#uL@LI3?)h3~CN Uez!?0>GYQggU+Pgr?S)k1wVuXCjbBd literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_166.png b/TMessagesProj/src/main/assets/emoji/0_166.png index b92a8204f2c3b1b3fc566cc19430d726be5eea58..29d2eb7d944a91fa6c73fd34a251517524413a88 100644 GIT binary patch delta 785 zcmV+s1Md8~1gHj(B!4_mOjJcja7?UrS#nA>W zuy|XHT132xWuK_h z-LkQ_U9D0W^0-S7;0EhuiQdYt-UelYnagp?*Y|jMS zgK-?PZ$ss_MNTY5?jh0h^t@!lp51SbxSkfQ?|#9fW!aUsbx? zYKfyyy9^k0Dt~ntE{dWnY3Bj~z|j;N^;^_cT{mDSXn}d&p!k=hMz#DS#{$Jj-3Jn` zi*E!lsA7Sl>7gk*R85uGmp5Pn7X|jGuz4RO0C~zMVZ0~~iaA_pn_UH!j3?rtfP*}f zx$z0d>k<$|gYeZ_6Yj@#zH`zGDMd2F73%;&0xX9WihpQ|O#bc*CuWx83q?@GAZbvT z_o22x&rIbm_>;56)3>_LAwp12<^gO_pfVI(ygxmZJ0)O%V4C)Mb%QFR%`Qh#M3PVT zObE0F?I7t5>B{`2kXakbp*5A0Pz$(K?{0x?mmunuv-GiVeDV45WaW*Hkw zfL9$B*MAt?UqvdC&M8ZYY;R550ft7ghyoERq;Gb{GL%k-jv{liK#W-@flaN|z?egW zo1)FrDxU_MMKH{ewxO$ltWU0azdq!vsTbC8ZP=if62-g?|YCb?CG1lLz;r>&dbyb|U$-sG$q~ z>sjZ5xmwVO6p?41-S7r8Gsaq}zkuhf-Bjp~Rccfc(usM(FT=ac9u8PEjr@-M`>ei* zLt!vs0N=t*a2O~se4ovGkrbA{2?P8IGaRzv$ML7E^W;(BcR2Tp@P|LY@o+o_=YZ}2 P015yANkvXXu0mjf+}UiV delta 545 zcmV++0^a?o2D${0B!3}LOjJcja7-{E8#yQyyuG-A*%hLF=s63~+@ONHf@~C0iioZ*uNYK8rjXjYp`y+eL&RQ1?Rm0d z7z!%F#n9`Cfm4_&)bX=HQkW<{lgMiN-jKsgVGfHEGk@GH+69COAfgV1MGfY-NXSPy zA&bHXQr%!X+q=LGvrhacejL0Sr<^9X#h5!lYD1X1V!%xxn124(6SEd^N?12XgyGi3 ze5^c@M}8iHN1&R+@wX#Fis83p9qJ`r7*bdv`NFU`III78aRv92O8paT; jlK^!I!Wteiyln6V+!Q(NdF3a~00000NkvXXu0mjfwo~c_ diff --git a/TMessagesProj/src/main/assets/emoji/0_1660.png b/TMessagesProj/src/main/assets/emoji/0_1660.png new file mode 100644 index 0000000000000000000000000000000000000000..3593e0d54ded0cacb103ea913ef521d77ca261b9 GIT binary patch literal 2521 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 M)zOERY1v@@4YlkdYybcN literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1661.png b/TMessagesProj/src/main/assets/emoji/0_1661.png new file mode 100644 index 0000000000000000000000000000000000000000..c41cf39f99ef03753fe26b8d743513812285f973 GIT binary patch literal 1461 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 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1663.png b/TMessagesProj/src/main/assets/emoji/0_1663.png new file mode 100644 index 0000000000000000000000000000000000000000..ea02492d22a49e84be72bb265b245055535cd817 GIT binary patch literal 1260 zcmVeKa)bnXg(Iw<1dNUZV|D{nYXU`JDYByjh>!-9k^*dh z0eX$2*4NVO@4DLGjmynYqpSv*lrzDtFu$p0%)dB}omsiJE4!wAwZI&Pk=;3#Jpcdz z7j#liQviU=o=j-U5i9=lEBHx*XXK>jtK!A`zlJYO000B)NklvvP;Wb`AqF3vOw6cLE}?v zdCEWML}FsnR9X`c?^(?f7gMJx7~?kkT}Et-VOraWI!(zmGnttDd+SSD34|feGhS+~ znY3I)vtHnt)eu3PXJj-QnPL2EI-kwrXa}G~f;i9FR-%w<=)UE<-A=MLv;nbG+9)^( zOv9>}jI%Ul(iolU&Y*3s*kTQsR!f7)WD3zKAhgXD85Dv6>HiU7#9?e@Allza5rOU! z8&ftGPZ$c124hKLBEmFxK!6d_-Y*OTg3AekXqsRQ5(Ld}^~?A?*ROSFfC5hcV+bTX zsVT(#`&^xPk|a#`mu5*weytWCY8&16yE(q@+8mm zTUC4i_B5UkrHlMNz@T6vr%B^wV$U5J5TPSsf{ z+B9*ChfYlBL)`l)K=xspl>LdFG(d=ZfU0X1rb(WsFRmy^ywC`J;NB$96CadJ$a_TA zAc51QWrM^KmK6aW3|LYmR&)aA*$4nIpyUN^P4zw_5^vD7-&fZlXf*I4{TpI~#G$IW z3<40Rvc7nFBeNH;{N++qH^~#tH6XGnj~6ifhSlRG~Vb%AkiQJ0iy=uaJcvdX@`d*4uN18-4nzz)2u6VfwTzEN z5PBj_e-mJ=#~)MgK?p>``cEMe`~7|a#OTAiS*QWQei4T~baHuLjczLxeh3z-NbXgj zvDl2gv5?pgh<+AO1x{mZpplUtfIu|;iX=(5sC$eu%lZEjQ|HXxsDRKK0Nw42IuPH^ zjh)!G&RK;8@2m2aLf0;{ebzT^j3t3D5H$peM$C8VqagWFSy8-&$va@cA$XdLa&pY>P)u@d@$(Da`E4j&99k=?K`_rFs6MoY|Ev2;pE-8bwj3HD|9jq|DGV) zcp2V(8t;%7#Xk<{9a~GV{td+K3(Hm>JW682s5X;gKhV zb}hzi7|+$v&$ltob0_1Z6ZXL_?XVu7O%VV3M*s5}&zd8GLKaa(F-I#DF&PT~&@rrK zBWhJH^x!_Wq%q>!nDeF~KtDc8N=e|$GBz|dp{Jsio0guAGr5x~>f&syvaE`bi>iJr z9|V@f0000qbW%=J07Y3lLH?Z&APKv>Sa|;2o%~podGy!v=KNazlZ&6b*o^o7zo4kT zu-o_S$hDe-y};q_vxj!v000OTNkl1$P@)8U|oHwj((;)QJO*v)w>LO}049 zBW7l1Ff&6K|Mb51N_OhA+g-V@PL7fpeb0OsbfcmF70d9%KWHW_Lw_sd6Td#3pa1;% z^Zfk7Unl;KV7Yp-_^zLai;pHRFIb02J7VgRik#Y_@3nR z;-{El)SrzGjEs*?Uc1StwR*jM^6<<1FYgvlR%^A|TH@w+lY=OhVbmv*48z#kZS!bx z{>%HtlXkscUri)@KHJS}|3|S7Ke&bZBtDJon`Zvg;=6|@X1m=^*$^L+xOsna*zy<8 zpLl$KKb2&Xxddwcet#;J@~83} z8~Kw@`F!5QHC$3sL`me7ob4tQ>&54{tGQfGQ8ueKgbFbBH(-!Iexk-VH{*UkkZM)Q zIdY15>v4bA;`v9mq~=rNaizK$_t9aT8#MbAjaTEFDRQ^ES&ievTEe$_>xT*Jkmb9) z*+w01Y%2bo&)1tx6d^ssgh;xmZYoKM+)JS&^b4+?-}nIp#%lA~d`dNLOC%CWiPxp` zIc?|j8>Zi;Y|>fCNrH%5c!VupP1*dml-VOTK#UTBECP7$BqL{fN|7=o^{uY1#+YC<8V$N!f;&=n+Cy%ZDCi}MW^ATOh->v) zO(*53=U97aA!HAioz8G5omoSg1(FOO$U4{8BdrCy-R-8W@L*2s^`q}W)C{A8{!#C? zhe8Vxq`W>ix9*I5MGk1jwgAknFQ7db1mOfh5Sz8yBM|>IN~H$MQ4e5YA>wqFr*?OD zUcGwtmgH4GJG;A6&Mhuse!y2o#h-W+$2myWym=i%Gk zz4dSeBf(s>+>~i;ZI#Xll90W!(rUFL;qrk|ujh}j^NyC@tDMcx7VHF zNUPCWS>afgg>r$QSy`#9tSmUoAD4`yrJ89j9YX?O=1nl|(#M0cGeSPJ)?hij{!F+@ z?2SsL)u=?A<*!||zI1%J+wFFDcDl#MAG#lwmOgy^I0vGFG@B4O4$}#Ou1JZc!dj(a z$3V!M?!0~V`fNFREAsj^mUXJ^47V!oMsux62o5Vk3B%|St(9h_Ravn+52p4YpoZr4 zdEV}Uh^$m97)gZ^*cV2RFzDn2>=huDg~-9wE+H-el-MN%hJooUa+HV}HA2*C24;pB zjkPA(;0J$fZ*LzS?qGwSGdqWexCkN~@l-Gj(u4q_R-@mM7zmaPxB~&!PPRsQyX;A4 zGHHBg79iq^-Cax<(q89wIULS!^gjlUn0&u|V4Z$d{hl?3k5OKMJc=eNE zv+L_&bP@6fI1Yx8ZpLbLO2lGpk!5*J7QJ+%|1_OVXU+C%J-&0WIe1VI~*dfNzHEruJEcP zX`IIc;>JB^(dD9tP^H54P6l3gxr*g`Pn}^H0acYW-jQ?2-w5=jOE`yE))NYi%|3Ca zgHeW@vbIFBABG90o%fy)BEX8gs7tzhfzWV_3A`w<GvH%9C&b1PmY~l!y{y76dD) zA}{bfuga%A;u#2$S4G%(Q`zO)Bh%SF(HCGaAPV6pS1=d6#0w(l6;xep#A3A`u_oba zz$<`|+{<^Yl!%@QFwTglBQGc+;?o>2NlnA3J?IgdE@JLP0Rvec`;8Jzk{TC@Y3uLd zuveD^1Y^-oDKY*yW~^a`MUmqLyB$+8Yn{s$7)Q=`p^GSp?DY84a5(JouslavR!>VM zV{&NxDo$`-65Tvj1c&_C*!2+**d+>xGlMxJW}Qfww7_y0NU5}hU!;>Y!)S2Jt<%%f z&e+(@%pL2!YLOjb?}tK}}0y zF20R}62DuAMy`UbNrJAhE=s%|y zXnnCLaAQ9Y4NNoyUB|-84n#yf65utp^UKhn`MDzryvmC*!WStJz=oAN*9Rtk>FAQG zsR8sN1p2`-*O?idxZdF9Aq3V3y}IR}nqWcJ3(mmvWCWM90zF*{fFykQv*L75I)r&L0J@8U)ZE2iUG0 z#~ugRCJfIW1-~5z%zX#6YYgYTI`ZmRi6;U3|8B)z1j=Ov)o=*gdk(l%1LG?Zv`qu? zrzp{B1<@o5>_H^kBn!=J2iA5B*>w!(j~c#N1K@)a?4Kg)mmuYc8Q*>o_|iS{oFewP zGTyQw+AIw7`nt-&HF?<=Po3}zAg;6SsAi(iS{*Ofv zgXprn@q;)Cv&?mZ9}{H)=_uEf2y=-t@5{!0c%kT?P(M18&N>f42Be#b?z;^KS~)Vq zkR7^{&cnl+xE_mZfI(A1q28vX(LNT?1y6LZ`KKYwQxe;lBd6j$FZ2E zB9cN;bT+(`>TM%haJA{W44B7t;G|KAkQ-6AhZ`@*@$J{53`R$RT2ji*LXUfSKDr=U zwaS~CtSHk&d3a10p6MA+qtS0WWGVf@w~}N!={&}BR%fiy=za?#NfJfrEN4i=Xs{Kb z%C#x1$Z}{QJbxP9-;ol9y4+3jE%k;cPP`gzK~z3>Wu9-ffS{;X5J(BgJ_!7jSInmo z1d8a967&tPs=Uf8i(f>4pOE;JsB)6z#LMgJ%hMJF{f3tlsG~I*zPvs^KfeI+h9;Zl zM_J}`V!3*PGFHPUVxn9Jfmf5(ayX1*DxNj(`=2XBM5)HF3Eqf^w$BBBu1Yj4#9B^GZJq0&%fLfysgro(weXY zD<{B1P2nwF-66=XgfXLQR@1^jSXe^b9sq;{0)lIDn3-!Z7<5qHAtg{w2sy!QN9;)) zVpvTW2soE4$vP{L3G_QjKsu{62ZE*p!D*INA|uLYSU|>40*Vo^g?7n^l7`kd_79<3O@u9pXr6Ro?*IXT zgg2l8aNMU`uw2Z^MFH~)m&cK+@ z!GXiFd%3fM#Ir_nh)j8!me0YH&cAoOt51HSTAz+-v7T|esD8q+cD}4=v7S_me_54< zT%3$#tC?)KqlCt_VWpEtcX(Nppk0%`G+%-|Zj?-hv_yNRZLYCvpTdmFx{}Vn(#U;* z0000UbW%=J0BA|kA*&$%4gNmt=80N$%dM87jK<%fz0E5~x=Hoag&u{1h<<@Cy%=)icQ21NidBU(?}xd=haPAdA7oPkt4`HmiZP zj(^w&Ktsd_p4bJeXy*xjF$P|;s_2YC9oIQsvOGlfSE29abyVc>}XKCwU7cRB2W&?$$9=y0vZF8l!gJ*ladmq1kVz1@i2D z99_jpYpt}VCxiqVjx&Cl2P551@4vI1HjGI^AQ1ur27skumX!8j}6JGSC(^%3;W0FxU44pxdKkKc^t(@%K$~ z;SK8zCVK#M+j{F>=0to%KRUD#{Dk;Mn6o_rJDQg9^~V8aL@x*R&(4Klq#*#WPv3v- zcf08Wuf5|T#}%=P1R#g~ZkvuCTLlKL85rC)-34QR*rLyeRuO{vAb#4`T#Oz!HNJ}U zMhFsK8;uvREX(a?!}+?37+8f70mCC8NKjfELq~k%95*$3!2}l^1Pp0m&=~6+T@oRh zw{iS}wLS!pki;vdm5wgSQ3(DmV$_}17KRsYq8Kaf;b0ky8dafCDPpi2#Ue+$+w}~_ z%QSkjFhYh~Lu(K)nuw9ilu|c_V-5%zbWaUlow!k#SHpz|W6hNyV|>337?unO*Ribv z!9eiley6!N+TR%3`V2(y=4})=jJOywd`n5f$!MB+M+F?r zq=Z3Hto$D!m<%Tp4}wN8c+2ov8mhJQ%Z~~`eDWlll)=Dr9%EWv19%Xjbvhz0gAdcL zED&OdlFiDpqfz)#PO>5$4V^qq>Y^yJEL#?JlIEjlr^5U;=%4u)kV@s)(rVCG00000 LNkvXXu0mjf4s|W_ literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1667.png b/TMessagesProj/src/main/assets/emoji/0_1667.png new file mode 100644 index 0000000000000000000000000000000000000000..7bc72ae24ae6f1b0e9fe84898d120dce74641dc8 GIT binary patch literal 846 zcmV-U1F`&xP))RXJpxLrPOUMNk(vVRK$fCrWn}D??dGI1?y85;9&DHd!84jU_TTtp;FbTC?y3^8F3IBgO@dJi^e5Il1YE?gKXMhYrc z1Rh2PB~T(QL?ldu5=4R%M~F{GMnFDDW@mYgb6Ig(L^L!&R9$z0XH67Jjc{67G)L%l z0000SbW%=J0AIAB{)9yS6Dr27lE|8V@#SgD_SoX_`cc-%vACY#0006-Nkl0mS6o6rNY!W6AAZc3ftl7HF`@h>9+n_M&RIQqux!{i?E-;^tEjwSgw6wIew6wIe zw1m*z!ehL~cM_=x;&pV-C^(mr1@V*nbHpW-6Vk`=(~tMFAyhEIDIkIGeow(`cTV`4 z7zTp`ef6DF!HJ)4423KqHE}!+j0!*mPrg*#)Y+s61PeJH;f8=LLS^=a;^tnSMUGpg zks(q`yuaTNR=2WRyZ93(di3^6C5cKSJWW9j0Rb`y(Fbu)npWn?znQfkJ@N-A&r@Uw zc_XaD7$9-qDPXe7U%L@TlY|gF4;CxkW4K~ah7ZE~X8h}he&@-yHZ32T6k{}1~TQD>t z*gRn}tL$4rb%KqT$T z(1>R2lvK~qHfJEBebY4Uyc$T8v=OUMbDAx23#f91^v&p$sk^11MhD)M!KS3FHE`Z- zwcvzrZ`bP;{-kI4C6~#*0`%Lqw*SqScmPzM!PK77}n=Tuw+wH#9T8gMmssJBv#)#B69RDJfV* zL^(7xEGQ_tS4=Q2F65bw!(CIiDI#KDU+A5DFD)&z>+g-Jv~RCr#k)@N7SSP%waB4c42*Mh;u1VSJr*;TLZz4uP<<^TVKow?G= zyEzbKcISi7;lq8-J2O{EYyV%-!Qi&*zX@N5w-@WXLHgswo;$#m?=IGVY=2bn#cOf3 zbX~qYU*G*$JFdgi+QSfx>+;?Dm+gdk~P zL^i9GIW%rRV9?(LLS$wt8s*!&i;d&e4Ej$2golT0a|i@6&Np`HRR~X95V8+Y7{hF3 zMZ@nF1OOBz)0}gv*~2#a}K|_O;XLqHP*$T$+*dkn^PN%Pr4Wrw*xKvZi%kkA-j0nV_9&_nNfrY(p zT@LfSN@Cc5+!7s(u@KS?m}z}>Ie+3;jp1>0V4{yXAuURbG@Z{$4Aa;M+A?CDPLCCEAPB_ zNe__luO(7BcwSjns#oGq98U~H;OBa0kA9y>z;el2S+?8E^tgNx3_!48Kl8)j?~sT= z&@mXs^o+#F^zx~8F$D-HAf-}V;Be3Ndm;=odBI^|47pP2<%?(_f-Ghq9wW(Ma8x1Wj z2!I^=UM0|K=g5ChG$b@Ks5G0hT(8#)g@QN*Bkgv(wV!+R>qMeDNyC$d?|B9c84Of1 zsEA?#5zKMga=U*C60JH6!sEsF2@p_VkY}lB2kA)(6JZzaAI$6 zZqOiz+_abn1qwbUw_ca!rUC|>&!PY+a=G|u$F(H-{c4E( znQ#v9m2_nygkda6lpDBJK|tcZH`-dZvf1zV4T3(Ra%zL zOfiH>EN5X67(<`bvROdDQ50OIRk%^S6(|s5+akgTv83PR=%oIWVp^AIBDgiE5+>U<$@G-}-W(T?dr@{J5C3;50e6JZ}-W(?IFu?N?JG zS=FCG8Q-^-hnE6ubTWSFSNE}xw~JQUvtCYu+*o;IX p2a)Ke-yim@c6hmQ8tV14e*vH3-PV~fBGdo?002ovPDHLkV1i6RT!H`q literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1669.png b/TMessagesProj/src/main/assets/emoji/0_1669.png new file mode 100644 index 0000000000000000000000000000000000000000..7a6154313f6004cd9e05b9389074b9292e3a854b GIT binary patch literal 1172 zcmV;F1Z(?=P)(IBtoqD8wUa*O1yO?*IbXK;Jam%ickYq^Ix0cbaiOQsY z*1DX|s)XyztlYq%(z1^4(X-FAmB*=y!lHxc#-sAryY=10-nx=G`ps7W000?uQchC< zLS>5nWc&{LAXGZDn$zRY&w`_)-^#(xC=bVj000A*Nkl2Bgk6a`?s-~})t zB$=Mt%lpdm{!cfz%6)NcxmzOtM&d+~A^~4c-CMxsf16icdF7Q?!d>!ilDJOzL*Y|O zKJ=>V((aTvKOtgYGG-7^ilRHY;q$~B<5D65%E|o!AxTd7cpPX_7fJjqK_w@7S%P9` z0?5gEmSCKaJTJ2nk-Bi7B94MdAdJxE@!yC;5JYq| zvMfs*Qv{4U2`9p>zW%oCPobkgGc=l%Fl!Va4T;>tU(TNiP9z`{jIqZsH^N`Hssf~KKh{UG6+q;K=|J<+7|qgfuGh9TNY%nf)(Nvx z!YLG4?eTHDBGO*hPO~#aS%M;=2+78Q;5<(8Cj7eH5P>2su&abMd>v^C02;~|jspTB zpseg>ZwVWw^)W(2qHzKMkGPWVoUTeM`ei3 zHewBMpjbn7EgFbi>)c%-><}$sjLeqGjnSvA$qeb#oCqxe%~c}>5NN4e%vIt#Atv3YX+mfToy}f`&qjIs< zPYMJGO~aAccoDY-p+hkm6LRC)e^1V?>%`v)czxG&NEkzt+#0F?V~$866~J|I`fwhE zvH}o365&BxA@9Su zNUbp;Oy+rZzh5d4nv(w}R90+Vd@%e{9Yhe={R==!{5#@M8Bq@O~xAcem568Tk|d0000JAPhy@LYn}I|Npsr34z%TcBl4fA3RmDBRPfy9G5R&zJGlA|E${5E8%vx2=dKDE9~^c0wxxRPS+sVNE+qWuuo zF@yI86F3~If-v8{RbNUCjGV!h!KP@1HYm2HC?)ahCEAd8id=?4J8|iXVhVXxMC4_P zISDr?5F;!@kzJwU8cK5#uAnA3V%Yqo2V$#dP6P!pCV#0YzgHwPc=RB6`As2I*ThP5 zLwXK$Oh4SwvH+~8rZ8rc@=(kM^k7z47Kuf3QpJ+4k}$(aVa_6{SV2-@oi>OjJcja7@T`3ZPI9pi>RVcM7Li4eF>Gv1AX-fDYi84&avz zb2tjvjS;F?4*bP9zjt4F4c}x)1>1 zvLO_4}ao^`J5E_BtjC3xz^nHt6NVBWRQ0~xsrpdp$a2hYSTW*bSV?+}&ukN~BIwrgjPziO8h@i&$Fow4dI}9eegx3yC zB$bJ&0?LfX1iGcm((Y$8P=deTZOYd!xi8|ZfFkETL-x};O#Z&OQVNY@mDn{xYseIv z5zyW}qK%lr#!3u_Cv!+^B}@Xk4nufBLxWnU#DA{Ags)$`dOnj~WTR~kBp4!&O0*4i zPrd%fkwpX#p6a=GXqDLO#DR7yduph|(twbZ>00000NkvXXu0mjf)Rw;j diff --git a/TMessagesProj/src/main/assets/emoji/0_1670.png b/TMessagesProj/src/main/assets/emoji/0_1670.png new file mode 100644 index 0000000000000000000000000000000000000000..358a00655e0a634b9d03ffcd8bd49e07ce1d28b4 GIT binary patch literal 1291 zcmV+m1@!ufP)PN)3AkXWM4x$G*?qmd~s`IT2siVc4u2u)vtYyhJ9OBRKuQWw3>6v%FE88X~~{v z)~j;Rr*grUUdEbX(4}nCsBX)mZ@iLR;I@9aj##pZRjq_i*sgYAP(hD$QGR4ao_kKh zn{1+jS9fh==evHqm1o_tc`YU*w2xzog@LQ6shydX<-3HKbaZY2001I%QchCNel*H zSSFHeg8>7^_USM&2XgZJKh;Xz;PPJVEIljkztS&>sc!vS>Bh@qv1q>-cB@etn)dZM z8japZqt7ox8L*Aj*KqiUyOffEGwwYp_MtC6o%DLS{22m4Ip+aUBkaYx;6-I2 zm;}2>%VJZwlJJ!XT_nMR!`QmMB>vJ`DoJhwrJM6`>og*?XGyp~oWna|s1W)fmDiO3 zkpSUKLOBU^5pRd*4QWIeB8lUM+u^kmhoMa9gCr3Ly1iTrN*WOI$Z;6O^-{Qmcua0Y zJ&8;4FdRbs281nkA`WBYU>8gf$~%D|BnSw>c?zOg5?BWk?Dii~y{_K`V;l(8B$7bE zhjBI_w0#;20t$?bv39G$FdRn`*hR*Aszj%s{B+?nmK`!>!XEr0KsaPiwkq)y3j$*x z5oLW?siV-IGLHo!GA_4MYw}JT>h??lg;{Ltp}~)86vsjW*80ubildN#2!aB(G0>HApb&Ua zoZpG)Ra3|TO`zcgB=CL+7^qSXISWE5MMDyY$B*22-ixz><_fo<#_UW(B_CGjZ+WDh?q*F$56#)J3OeT}gI0S4Q_ zFgK&G*^dybZCMson#7@$L>Lc^-R|((H6B3bM=UeX%PNVJ1P~kxVPIfIgLdb?6wQ)` zX<2!ZV4WOT4)wv1NWZJq4_2QD0t9Pn<`o*DLkT6mSgok= zhtSW!xFJ!mj#!x(!vsQaEwK?CDusjhm^f2pBE0wdVW5CSOCOtNiC049Q&=ET#(3=; zuJa*hX-#yoq3JQ-z;WCSDCT>lmar!nBhPb5w3f4@Stek}w--Zz&|0Fkl0yEb-^{Uj zw8~06M`bzjrkvF+_655@;%9No=@C@8+M=k6qAYXMJWlI~jwP2mLqe85pW=A7Sh;1H z=5)NYYm||6f;~fA1002ovPDHLkV1o8A BXMq3! literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1671.png b/TMessagesProj/src/main/assets/emoji/0_1671.png new file mode 100644 index 0000000000000000000000000000000000000000..409bc747cdafeb276bb368e4eaa34bc55179c7d6 GIT binary patch literal 1630 zcmV-k2BG>Cv!wpUh~byz z{m_cd`nl@mq^slP-ot&*GpVv?ysP&hSrb0}X?d_Mh)R*SR$F#o4o{ZpXv@#9VDPlWPSyxnf^|DcFs z81Xhu)BCsfP@9(Fh!;vjeVfo=%rTuLNybT{yoqRro?)8Kc!i9wDsP!2bD0Cens4Uw z)#CQ_kyfuf&mzJIVW3Cj^kpzNG%~^p&p|B4r;ek75{x?tx0vU4K;$D;OVzTXG!>rb%nY&N^FinMVUM_0!X%xk=G>qLs0I-~JUY5__e}4Hgi{BS*;0OB! z1`tW)p%Ms)!En7EuG2K)ths+0l{>rtGD;&5v{Qpz=;SSY|FgI||ADxe#=FWML4CNh z_1vHu0g|_%8q+Benm<@Cml5|KOZz5qSF^h?X3K~O%YpzSV4-XQ0w4eS{paiJBod9Y zA_7P##Duhsp=g{;x->YGK1O*aNYH8e@&^L)iXMbS63 zTHn>s``vUYlHAZVgY%4lF~K!Sg}5m?Qk9x54Ja?8m<&WC!=ZsnVlqOFa^aDPfxyVW zXOWq}K*%5>AI4-E$Jf;&quN4^+NXy)j0E>6lZuQN8cicx35M~C8gYDIXsDI?n2S$ha;(`Ac-{{o6o`ti}K}X8#!P%SWDKq=9*uNoH_dSGg1r znIXinr@B%dMly;83|T`OOYAl3k>VXJ=3uH9-R>s9e**!dJ(b4#JJy08Gpy3QQq;r7 zB@CX%rh^)m+^=LTr7@Y|E#5e|7`1G}5cp?ASX6_0(0-duCS>5U8!!%~gk;Fdg5b_kR;C5nXQ z-5y>FZX-1qrore;k;twJG8mZ5^^_wIqct*O(+UxZ{MO~O&%>U3?CDa;4B@aae^`)A zhWP%JxxF4%a>T&-V6RM*c}Pgg?yR0ppV}UddwK#pZq(-7v^>}KC|MsU?RMy)gbU(W z%C?S!s^f6x=8+c2^WL|fm*0(#To)b4Jm5T}Po4J=7cT&KiZgDG3v_GNb=|h-9eS=s z_dF1&1g+zEROLgzuiM?tTyq?Q6aw(-g?nzrg|}552u>MN==f*!MKK)b;*{SCEi~z4 zMg7gZgEA(dVADs56H-+!bW$L_%hPY2ofx&ETzmkri(P-yuhD8nY1J<%^%fr8-WpXc cA-_KVH=f%~=b-W!6 z+O4#TorOQUS9>4<(RJ`Du{}8!P>bMR zBeqNDfCLbph~|}1EG;+;L?n2PSZnJ7uuurU{c(^ipaBdBWg&X=<6*K8Rlooadp+zTrhsg%qj0#CR$Ydz$q^&Ed1`}R&(RKkxCUOX!5Z+;1jhtJaNj0?Qh4A0# zL=JZ$IP*}9sM_2H?F-^P3ydVIM~;ufF(k{Qk3HwXgz=?x2{Ty_7$W+=Bg9dQYP6Y& zwv{|qo+ocSqa>$F>dFtMp3>D#gsxfcJMU2>(eNiRz%hYQ1NUWo-d;pljmBnbdgIIA#fZn zn&`VO#lK@jv)CV9s+oqK45dmQJQW3KqT_w5x8ug`{4h*kqA1S~6{9l2cc+Py{BT4v z?8B&$4ta7WL5fu~VchnEfjrtul%c9hK=(00ylrp$$cBGxmjaPuYP6!m%jAV|aW%!@ zIQqV?iR4@jw0h3%r+IIaAOj@`0;jq68HtJHU!3Y_FPt(;j(JacQ z)2may)tP4=RK`7w*%$2Qy6?3G zSq*L^_>zTiCkAE?mloqq|J*O=Nw7e~?0Vlzt1*AsFaaFQ?_xNYacG2z`t9a__Ofv~ zELvX^8Mc0eAHVW6*JIWeR6R*mME_Zb`m@y>mA5{q+-4KP=jD}G`NiUVkIs7t@_r@Z yrMg^i*Zckcc|A05FIV$+c)!*Zet|S!JNOU&-^ykDBJM)~00002ZZ>EP){FDsm3 zJRNj)As`@5MLRE9QzU?Xs8J$>RWu)wk*i)ZDJUi-BO)y>EFd5tY)?9MSV4PSL~v6+ zJ32UjU`J<5HicwMnsrw*GBF$*8&ff76xD? zN~EX`?y+ZW4*=$zgL2NDgZKU4We-60)YR5c&Gvtz(gnXdI0t~l+W&{Yxo*{J?RM?A z(+W-7zi!s+7eebdi6;JHXu7T=$^BXvTJ7HFiHb%7z*H=Sw(!UzN6Vnj{~mZUllQ~I8ARaz_}37&-@U@)x( zkiZK)@%s8l#NAYwX(PmJ6%Yp$3DZ&zmZ~bMZ;#`@K5R>;9(rK7m_RFnKqr_Y&Owun z{zy?q@e}`%(DP_QBEe9YqC0>fQ`R(Xq)JKrbp25;heJx_`7lJF6bO-!EGwFkdIUWCQ>ZR)eZiMOKH-_Vso9>?T6F zAQFTyCZ|Tc3q=%7RZabJx!>QOS;x&907=50$p{88!cYx^wPd^9E*6*FKT4S@lurTx{eIu~`=h?4Zo9AD%f+Ik3UQ+A9CwV@1(6g7j1m;^Z6BEFujMVxfBtGk|(Z2dhL=EN{AQ#T}G0F@lM#bJ+u4v18fT=aZ%DN zx$GQ5oOK+fvB!Fm=S4p)X3S=`Kia(9O?Q*$AP`G-MS~DBjAJg25hdW_D$0OfKoMZr zUbuy!E|+D!sEI&0Sqyn{2iWu84O#^w#(o|K3rOh^>0Idn(VwWXb`uYboGnJR7%}!| z4#_|mh^Hyo04F$cyR zjAA9QJ&h490SFlDgEw%KQli$bV>8M85r^?pYd3+QJ_Iu|-1 zUX-R$%B|;x!5RwNn>KVaeV9Tw=piXL9^Z5nW@!|Gld-jEO0h%xet&Fx=y^deJ}9HS z9ef>TyNXzjb1+~gV89Obt^U}D?rzVQ0qHq}5HF)b6s^1=U5dd5Ya9LXc((a9)m=szP8Xj8d5y3N-*3StCGvAB-P-6#`=~eKL#lVibmL8L(3*VQ9?{2>~ID z=jl`KvEdpJi=I1+{$d-7rYRp9ojO4XfnkC%3`1QHf(gV_fU*FT9pNLRRd;lPRvZ{1 zVC3|65d?a0fangnsC{UNVgn8@)FEM1Ad|6BnaXDUJ@I09Z3cux=F!s}yNtj96`vAnRC{M@e$jPWNV*Os zS7Hc6Vy{eMty=gd+(pFk0P*Mx4n869c~PsHHV_2SJ8``V5oWJDgtnzR0aqeH7#>RI z*)dzq6JVemI*{t=G_P=@4&|dH^gJTD5D7PHpGr&U2oh_Av!WHf3*Q>hNsr_c!EnW}=zVnX~{s(Q7VT}y3KkWbj002ovPDHLkV1j8l BRo4Ij literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1674.png b/TMessagesProj/src/main/assets/emoji/0_1674.png new file mode 100644 index 0000000000000000000000000000000000000000..eef6659c15ecc6e73f8684b3adecef64e3c13fc1 GIT binary patch literal 1539 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 UWpg&~bN~PV07*qoM6N<$f+*g~m;e9( literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1677.png b/TMessagesProj/src/main/assets/emoji/0_1677.png new file mode 100644 index 0000000000000000000000000000000000000000..020df67960bc2abd384c4712704a8d752d217f81 GIT binary patch literal 1172 zcmV;F1Z(?=P)mj zP9PyB9UUMS7#YD5xTsP}IUS8+48xZK^yP5I!h(ZT3V^)O8@`>A9PYqQveJ%QEYkiXcbN`6xn@yu2G^x5(p5lV;R6;`!z)jy}Jv9 zS|I|E1%NU3RNBxIITI!bWN7~jNk~N0xea!0*J;i`AtXcqS+qY9Ay6A(EJ)OLvR~v} z;Z{SdX$554kukMxaF@@STfm*I6B}p)`sm671vUe8UW{e>nCGq{N1%QL2rP0uRBRa{ z1Q=vw0J{H~Vg%!Jg%JQc8$6;Itw5Oecl;o}!ud8@T8#zj_CCL*g*YA%hdmb^!wR1N zd@BZO061)i3f!$r-RQ2u^tu0Q>oo43T^4HLdvWmCb&ap*2%HcQ+ZXqC?qhGV*tk5ty+DRR}T4Fe_7hto|CsIFd&Wl4AJtGsGJ4 zrnpdOvgWz5;UoPziPQd5TZ8FxtZvcm2GAWF5W1~H6!Ev~`K+D_@q2y7l zq|)D-FnI{1Y9l7|)d^xyoUHUTU7qiEfDej za}1ah0Ci2qk}(n=)+Njv!g;(gi9RambLbgDA&`Aa;XnWqKuwM>D^{E#q&DT$FkNf| zH%=!wVehzPyaKRYHEF_c4s2Gg4ff!>!)OIm=2WG`thgq?o^&*}eM}=286g#^N-24I zI&BExB~4|pw}t-FBU10*C)jZs))2v(AM0o!ZA|>rU8M3*+1QiCp==-knX zSmq8Nw-^kHbIQ0gfM^NVjT0T|3o3wB`x4m!8(~_(WUi*HYSUM6|1_I882~H<&c5li z0)<&ns=`wPmkJ187D-6>hTNL_W7qpWbIaEJZ@dLS<=@WtEHG*S0000A literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1678.png b/TMessagesProj/src/main/assets/emoji/0_1678.png new file mode 100644 index 0000000000000000000000000000000000000000..8182316498a85f8fa477a28b907ac95f37db2fbf GIT binary patch literal 910 zcmV;919AL`P)Ka+T7FNGgnfp+Z z@<)pBKZ5E)jQdcL^f-LwD|F>roBK9_@+^1kF?{emhWIIO-y&tu7+J#}U&&{q{UvJH zaI5}ImHl5QF(?24026dlPE!C?NNttnsSh(Dh0wv_#N)H``J)dHu>b%9xJg7oRCr$P zlh<{{LUx8)Of%5C*?4r$iMmeX9EkBIe1HC#4YO--0qp(+o%p zrMB|%e3I3h*Eib`pPx2MACt(mhM=_&2Fxe%k|lS~Dbo#P8)YFKAWM3mMAT=ju2c{N z%{IBikZjIa-)L(l1~V}5&8V#W-M|OX%1~yQW3+jZzuci_!=UXV-jW0y;-(^HgTWFZ z+D`Ofal`E%azh4dpo9u(&iC;2;2F%eyitNXm{ys~@C@G$CR@M63n(m?XceU~?|Rp{ zZld=%XZ77CuUul#3QK&)y>}kzJUDy@j@2nygTH2F(4cuhhfz2Bal{X4Msy@=JHTM9 z861v)0v!}^kYwKBL!u5G*~$(afydOU#TMAwdyY?#3aYd#OEOd#WgK79k%04u_X9j^ zIl!Jimuou!+(DP14lD?u4%T!|TvLcwQm7VN^kf)=;dD5`bKo+gcVgvth5xJ8X%K+n zOF;sH9Va}APgYL>3O^~riqi$y2OVPV6!^dBrV=y5@pL?fCMyc@X4F782#R1}*n&sR zuP8+Q@o_#kjnx|SbP85*2R4x704!gs%r+kcd8`5p-y)P?Ku53T=TECl>nRQbq(O_H zmIMVCp&rHDkjw=QU>j?d?!uCb7PO?AZ}^@N42)84J|&zZzTB|6E>MitXaPe24LiBm zur#1UBThRvj!cTBW@$AJSY|w^frm^ zKolAk%Pa7RyC~zF6k3sBdB;18pyKBpMf3>qR-+>bph6ivMp@;-p&zXf-i>BlUc}Mg kka1N2RV<_bnI}*F0SSbrRE#g2zyJUM07*qoM6N<$f|5y?*Z=?k literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1679.png b/TMessagesProj/src/main/assets/emoji/0_1679.png new file mode 100644 index 0000000000000000000000000000000000000000..310687440c8d81832053a992df4f85e6ae2fe723 GIT binary patch literal 2133 zcmV-b2&(sqP)$Do76dEdpGYOP^suwZAoT$_t!`0v@XoO|lnxVxZr zu$5_+gle0BR<@dV$*Ou~wnbT?JY1$fR+>3tutUwVhSjrxU$IkWx>sJSLDaBwRGLa$ zt5Mgtg>=qPchpnOu6=IAOShVA-M)*!pm1@?PHDSH#ie%h+Nx~7N?W2$Y_wOek6}=h zILxSQh+|A`$X~sgVxoXonRZ9w#FBbrLv?sUf{07s$)uU3Wx2F|e4|)=+*aVbba&cl zq=80!;cIcyWPj^#k8nmwi8I=>X@}xzbB;mp(U!rOROiBe^46bRPc}@CM~1Rufxls) zz;&FBS6YWj?8=I;h)KDRPSUGkiS=~Jp;}HkEIRjy&;S4cD0EUzQvmx=F#aJr1`z&Q zlm1`9`;>Ecec$B3tnR(4)Qr&Jy_=Qm*4~Zgzz~9dB>(^hgGod|RCr$PmStli$rgrz zU?E}RGLt*DBipXHyE}1rAN~Jw-&0LkvYXj(=ktAlrW2@#_nhh~u#Ln2@lN>WfN#R{ zyW{8HEiWz2%q%S}zxy4FYi@aFW@d5#Jj*`s|7P$lVR&`~c$Oz@PZLc$c#$zaab0GiHdB`{w-m z#qcbjH_yQR*(1RjbDU3&6Juhsnb8P={vj8+9_d4M)^@LbBa@eBVi|pectoPutEZI*ty#2*VCZ|u;Jgxn9M|- zeWl;)_4+Ib9RDzI{Tq9x_LX5-;2AtlYqeT3qx5cgLzE7Bi4Y|7wjonwh$ z@dXb{G{V|M> z=MACMXA1jZ(YO}XXp{t*>GdnFwk}GgQb_{Gu)qToJ#TMs7mI~hEQc6k=_;hEaJ=+d zWso6ChWL6RS<4xM^gw4DmcjT&yI(#gZ3WrlDg;hc+5)Mr0 zOJranC`De*#dvZM>?qOTHfZhRwNy9~Nud;3Dkv&B?y-eTgdiBy5nmUD0zO1GL{Sh4 za37=2YG$(qaN3q7Pr#^bl57!0FdC%a6mC{bEsStu$Cf5y%OG_plO0<$P%6BaxsG^10aQX z9gQkb*d16QY&0%5J#Ac3 zijb3*yLXYMlz;(>N(2g!B2a=@IyfjvrGty$-d2^zA0i(^2!SaQD{S*~&}c{M z1Euo^rOV5UpBEQDe+IU8fiA;BbWjL|0O*Ek87u{>#9||bIbdt?uq_ZS5WP>cx06!=ViCaP#EM zVT^hOm5?ATmr6#S40lje_FHY;Qta$~znRY9ItVSgY(pFwlTr*6l?^rlk}L-x2n6n0 zE$kVMmc|r2J9~TIzxTPQy6Coz;FvbqdQVa_D#zG>1vzL50>L&6jYfSx55*QK$f2ko zU>L>y!Hlw6C`PN*Znf?LG(MltYwdk(y|?vx2O)-vn?F&-V_ff(2*Ml<1gW(1`9K~7 zwZeYAUcAM($Zdh@unIYP^~7%skN-m%66!~s-X0`0P16hYV$EWm8Azb#XKhd6egBb3 zK2Cxf5-bq*XbfSB08Txe}4P+li%&~*j@xK$5Mb7nid3kIxM(c-r@frLIh@? zQ@qlcBTx88svIcTj6B0E3~(?O9x32l^}h}VpH(abhiH!!RGQ!BUe#Vbr|^#|JR=Gi zUU>2P>g=-$)S<1u)_^|yNTIE=1?qM`r$ACoTkyWnbp5eH)BLvaaJ|tr1jduDzZy|2 ztfH*(@V?d&n9__WfESn7n0RJ&zlWaPZ}bJ*@8NY10=s9QYutYU;XsW2_x@c800000 LNkvXXu0mjf0dX3v literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_168.png b/TMessagesProj/src/main/assets/emoji/0_168.png index c56528f1103e6b8540696f9fe7ddc730b00809ca..b92a8204f2c3b1b3fc566cc19430d726be5eea58 100644 GIT binary patch delta 545 zcmV++0^a?M2f751B!3}LOjJcja7-{E8#yQyyuG-A*%hLF=s63~+@ONHf@~C0iioZ*uNYK8rjXjYp`y+eL&RQ1?Rm0d z7z!%F#n9`Cfm4_&)bX=HQkW<{lgMiN-jKsgVGfHEGk@GH+69COAfgV1MGfY-NXSPy zA&bHXQr%!X+q=LGvrhacejL0Sr<^9X#h5!lYD1X1V!%xxn124(6SEd^N?12XgyGi3 ze5^c@M}8iHN1&R+@wX#Fis83p9qJ`r7*bdv`NFU`III78aRv92O8paT; jlK^!I!Wteiyln6V+!Q(NdF3a~00000NkvXXu0mjfeAnsf delta 885 zcmV-*1B(2*1dIoeB!5d#OjJcja7^pKoydh>#e!VtxRleFa@L)ArCK=5m2t<1Vc4H} z*q?ds$E3)GUgEHe=(?BPrh)Rzs`=Qr?!%z^+`IPDvE;Ii)tPep-@d0O!1DkA01tFh zPE!D<{*ZV*U;Ymuy4}v%;eA&KOaK4^;Ymb6RCr$PmfaGfFnL*dP6*+4Ywh?LB2wcQKBDRvzUE`cGh*}U zcD`pBZVSN@L4R~gWU00d9f(z}2I>6rn)q}lSq0IMW6g0E^?^XAsDdq~8ojfski5+P zu?k+>_aJE=bTtK)?Bj~ytt2Mscs1L_^A=Qybxrp^ML4e;!Un$`RiJlM;q?ryRCn}> zD!dBRpl5uoxJU}W)uXRc?As7)j|y1f=0Oxrd6d+X)_+yrJrdP>7i3FX7ZjFgUDv_) z;?}DK5Q(IUa{wmO8Q2lkQ7b%!UI(Ewpn*jdysP7kOvaocgf+*L!qbS5F$0rJUy`QC zos?(6LI-OA?uvRbM3GA=NEFleP%9cc6-Fe7F+3>@(-S6a3fl-{XHU~~ z)F7&e6eFia%&q_%NO4s~&3L^#?r4c~g=(^ZiGM?oVr*W~%^5_&ZNn#afI1REA&wM{ zl@epg)(BQm4wADb$~^LsqB-RU2O|P;WaL>&1~MEgnsrH&c2*oW2gnkR02y)Hk%JO* zkG+{BU9n)M03;}QQo+Htkc2I+LL9~*7G@foW4a5C1A$ok?S{Y)o!$`BscYUb$PYII z5pEPmO%zy8BmW(0{>Er8S0qg>0uV*>uZ$gKA&ur?#6XG<7}z4@6~qq}I-{Z%6oWCg z`520#PjKE%qnr70l&P#34)Gm>y%-UgQ}aFDX_~a4zGpc8cm3lJ%bAp>WK8Zr00000 LNkvXXu0mjfrf{Ul diff --git a/TMessagesProj/src/main/assets/emoji/0_1680.png b/TMessagesProj/src/main/assets/emoji/0_1680.png new file mode 100644 index 0000000000000000000000000000000000000000..9687c8752c9cbb9fad8abfa8e9150404c8f349fc GIT binary patch literal 1366 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 JPDHLkV1muGX&wLo literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1682.png b/TMessagesProj/src/main/assets/emoji/0_1682.png new file mode 100644 index 0000000000000000000000000000000000000000..43bc9618ce799afb2bee39d1946a76ef004dc9ac GIT binary patch literal 1497 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 literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1684.png b/TMessagesProj/src/main/assets/emoji/0_1684.png new file mode 100644 index 0000000000000000000000000000000000000000..687a3eb9fb61525d06a0d7359a610252823bf996 GIT binary patch literal 1966 zcmV;f2T}NmP)-QUN}(fR7)=jZ48_3@aTptZTY($&{?e1WdAwXLzWfQ5;%w6=|s zn6R|9iH?%f-Q|CRg`T3Op{A>>)9I1T_i}c5m71Qgw6~t3rn|CF#K_C9!O-jT`l8M8+}_~u^Y-NI^KY@@a-HCN zf{Brso_KzQb9#ZFrmeca#iXjRfrpJ{Y;&BUrI(zbvbnyRqpPT{v|VFrYI1nL#ma<> zl9QdLQ(9qfc72YNnu(B>(%0O%CRlUg3 zwe|99StNi_OqK533uIZ7H#N3F+{`8d5^Thtt-m?Dw{=eD! z-2eau{7FPXRCwBzmxod+SrCRVFk}%_6v3SJ2Jc9H7!hqw0k!{I+q^+@vD#<5qdSMt9f z3jKcJVccPy#O8Qn}ph^?HNnYmP*ah=*^2pqx%dpeuYB& z(KQwP`ALlXy;5mZEzb~ON1yV=j9qy>MEsEA&0eX{E0?Py&(XI=Z#?MrdwEUEtl1s0 zU5(23O8x#|Fc^==qeiz2n!4SIno6%-kqkd6cfru+VEphfE=nO;r@^94eT|{?+XT#Tt zG-0tM(W0VPiuG9(BaC9YhrR{g<}k7kvog<5B+hVM*3M5l}vhQ zA|wiu9;rYS;TwUxXa`ZLv~PFVBr-d%^`YSsqNqp=qeC!^BoQ>`fKR5jSGH&(MPYa&KUKU()H9FybuNrizhOM<{Tp9Kn5v|1KL zQpvfV%o25IC#Zzt1bxTJWeZfmS>2i29!jwW?W6-?FW|dtes~B(eY7HaMOW&z`kDl& zN2}G=5S93Nx=;Tn#C!=mH}`-*C>8iv&j<`fAQ0Hs2atT(zQ1o-#@r!GE489Wknrgm z4>Jc=8yF<_(ad{rrd;V!8NJLT^ zkB#fO19qra2pJ1xD(tTTaU7yF2WP_bPeu$Q!`kF8k zK7{zO>o_ilOuW>c`GQj zl$uz1ypK(pmSqzw^l9>I%Tox!JXh1JBm`xere#wm=tZY!8@Vp2QT+CD7YYEf1SGCG7kft1la8+BwxY|FW<|jzvEXKI4`Tmm+c~(sPEm+69Md#uDI(FUhU%3g zh@1gm^5W+F^62R3_VWDvf`{c#k;niU3d7Jrkg)3g0VHsaAaJA#Bdy(TTb8P-{5!&t z34%R6@#)>|tSE9ErdbC8V}`Ka5y+7h=!Fyip`6ZQ2XT%F$*65FW(bPIibSxvv%os< z5!<`2>xssqp{d^GHgW})AZTGP2`;V`v8yac*(B6Z6a)eKK!H{ea%b?~uzmy*yD6U6 zJPgbQES&D0Y=MWHMQkT=oVmETNWDL(u6O@`0Cxg(L*NMmYXATM07*qoM6N<$g5lNj Az5oCK literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1685.png b/TMessagesProj/src/main/assets/emoji/0_1685.png new file mode 100644 index 0000000000000000000000000000000000000000..003a099787e2bd5f18a3f52b3cd5637e91ea6fb9 GIT binary patch literal 1471 zcmV;w1wi_VP)Vmb@Aq?TDW4}oJw*RO-Wl4D^#7Mz7}QY{HtHW8n3Lr*UZNh%7EZd0_0 zUzc!8e^)lKp_Rv&W7DaB+pvVgo_f5FV6A>nmV9A{Trgog7Hvfxnrb?8OCq_6ROGyo zkz+M_P$k~AiGo)!pm9OIj#|y1ZHQep)vA2OnQ5_sPkd4>sd-0`XF|`Uce;W}WcpCwmz0!oP|0#7a9BdEs;5pZ z5B%V|_0p>P*s=4Gv|<1N03LKwPE!C>U^65ea1H+c%13+3ycsT3ZInB=F6 zqf%W_)OXa~>MMQvP59u04?g&ycX|R&PfvSb@IM5D;q7g-P#ov{{QTkO=5aVA-QYhN zcF*}C35CG(ysC2Zd{dU?`NQMz5TbMlYdU(?N7en`Y_beV}aV*Pr6x3<8)Alh~CaIMp0eSBZ6&8c(PH1LkjGt>se5+BM|87GL6CdX&8@WfWoInSP@lPD3C(a+|UaUYAj?3 z0^w_~y_-*9y?;s};3|A5L_zReEhk5YP-C%Rz@PW0ZAF^Si=uc+VW<^JrMZFN!H`oK z8A+%XHh}x~JjbMXVg-*gwjFek1yBG@gafdL4EI^)wG@NzY5GK@hEea9t)K%h3$;9o z^2iNCL;6x7K*H32XFxnO{4SMkN3S( z#6By0duH4G^=X%zG7{a0eoB&vQy4IxQ550Db+4_!yZdOv1Q5t_td!+O)1s0{5F#R= zMM*-(LtCMeg1_|GP{^iIF7WP2SuPgjU^aXtP6ErrkB#&tHMZ?~2vh>LOf?Wqq67wZ zfK5{4IOI5QD`XQ6D3B+EB*~N2YLUP|IMhtZ@Fj9UTQM)xm@pf`TqPsLeK zjs>)S$`OUEnoy`LfMQ;llgUa^7Ar>KmkT-!LNS!@ZG}`|2r&(k1VDm;)Ti}s0rdlQfD(rkbi|gnapOkN&lIAZv7g*%;AvfvuF%2b12{dGsGBs zHj8;{Orq1eBNuQ;1&~+(=CWxvQL{!RWCkzJx~#+R2D7iR#$_a@t(L6>-U Z@^6L8T;|~KIL-h7002ovPDHLkV1oOKx&r_J literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1686.png b/TMessagesProj/src/main/assets/emoji/0_1686.png new file mode 100644 index 0000000000000000000000000000000000000000..51388f393a4177cbe8d9e7e304d76b2c0ad49616 GIT binary patch literal 1325 zcmV+|1=9M7P)wdI(#uduN7ywvNj$JcY2?x4QYM|#ggcg;O<(NBWLK5*7qjM-$B z`K!(HsLA@B#r>knp`f6FfPs;YkN30E>X^Lum%#3!!{Ncv|ESLRz1Pah%Due2x0a*K zhNI?>wEwKp_sZh;ki6oAtku=k+;E)X;NakRq~rmg4FCWD9duGoQvgq?HvOXh{th8| zQs&l%UjF{d``hQonWe(_$k{6EBToPT1OiD!K~#8N?3Brpn=lkbBdjW5VT`LVad%~@ znR)Wi-O2xdR-Oh(u%VN*7uoc=vb=hSE1B|_|H3Dqgkkug0j2FBddL!ZT`MHU=z(J- zQp!DUw-5C2_JCCKff~_1N%m4EA8&!A7lu)i9CpEn?g1f`*vE&S@H{X2$0`BZDy78X zcs!=?5dsV01%EvqqR87G1jb$0zK*o7ZI`CU-R93-Pz2Kg=8d7X4##((O^@i^HlZh# zvWCtX<_@66DSD^ER)WGAVxWqvk=M#d;7DC3qSX#ykV;?}t(wan)kUj7fw5TY5y`z2 zapfjJvH)meP^`T2p?(nu-_QJv5JDMaoO416$sCQL8hR`a%QX-f)LU5;j1|CDFAFP8 zD5E7U{b3M7M5~JaM|oYMn50+wq7~lCRY*0wEGdea?ex~ar+7K>yT@N42It7NVjHX| z`cugYR*W#6iGo>62`5o23Z?p-FwS7<4fY$XhvkD<`BgooPL#kvtpm$)w!8jvp7PYM zE1om%=4@_o5?Zb+`iyY%#BqAT0TxE%RYg3Na2@8j!_=HTk_WTtVlg;VQMTY zg0umHWi~k$s!a(4^W)8e;pqY;h`q{jxlLmXlY;qAcaF`|r6HR7Os4wv9Cw)po;~kw z48Ap-bzs@lupHb90A?km@prc!G6K<@bpWDk5Zm6315Be|em-*q+Td`OOg92*LO21# zh!I#w1812GO_S+=tC@uSg6m9YC?-etZQ~4IGcahf-yk{$szVv295%*EFyuv^U-Obu z=h&6LGmH`=Bqr1u_|L-YUdK@w3d1lGa^hg5kxY>yi+^BeE7m2_AdCCIto_b82_9mt z<}suI{Mrg>LXm_c{YfcNVO_q`=X%#D=wIo2{e)|Q0IuOG&Xa@&Szuk4wC*3YiEY6x z+@lJ0%CvgA6qZBG9(T}{oEN_wwc$+T;l7~AI^9DPH zSY?zhjdv8-VH-FxstRul8Q=~c>zXHX zfyi9siJp≀6i?!g@+Kr-lSby|x@eD$aW<6vm=a5|~jd0V%kS3dK!DiAdlF9;|8J zwTMK91=zXdXn<#ywoq$3+ec6Mwf=|mu2<$6sOi>pN?F?jo;`6rSgTZLe)>0{wZ65+ jm=4rS2e{VWbiMpPLotIWUa))m00000NkvXXu0mjfD;AWp literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1687.png b/TMessagesProj/src/main/assets/emoji/0_1687.png new file mode 100644 index 0000000000000000000000000000000000000000..2caf68f71d03520e94a9102efebe907efedd5361 GIT binary patch literal 1939 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 delta 741 zcmV9%FU^*1vU5zda!S^xf6bR~xO-I3n{vN|Tfcx- zw{=b5w~^GMde^6b-?xz4u!+o*YSW)~#D-kszL?{|n`kzT%>V!Z4s=pZQvm+mhy9(s z8EZh^xy|u4u23xi00LY|L_t(|UhUTVuA({=z~KUwQqXm2;eY*K^{k61Y3ztjAsEO|L_|wW{Zdy!l}tJoN><|Bu|a^Eov>jl3#wjTxPo zw#%(F?OSm*U4P223COma$F5%>Y$ZvF*Uk~+JK>!tR@~c#pCX9V2T2J+k`PZ0u?mrd zxFG?7v?ER9&{qV|b0jAwD5ZcLrkK&Vqh>!m;0PumJhBj}XGi~T_p%@XSxoWDI@c|K5h<~VcQiOd9A*__AVVMu(Gl5V$ zE!G+<;A#ZGWWwPrGnYaQ1BoL8$~4@?&xA95!>}b5twSN zHjWcx_+Z!^jWKXrS>Ct`u{x33hV;i6rEJK0|H=)bJ%u>)7 X#BqsjnV&p@00000NkvXXu0mjftU_L^ diff --git a/TMessagesProj/src/main/assets/emoji/0_1690.png b/TMessagesProj/src/main/assets/emoji/0_1690.png new file mode 100644 index 0000000000000000000000000000000000000000..8dbb9701ab3f6a4fefed741ead836116a4befe22 GIT binary patch literal 1983 zcmV;w2SE6VP)@uP={bbbx$^JM=f1VK|wJmd{;ZCgJO_qN>V>FY+6l%b6AvzcY3R=Wpidi zP*|Y7v6z{MeTj3crn9+2|TvJ!Raf=Q z?D8Ut3@iw;6(Gq=U?Bhhf8;empb(L5a?RV4(_LL%70fOvOE6Zkk#i=$VvcySO?mgL zk_XMHOut#mbd_emCVR+fdU5mJ%kMb%G@U&xJftM|zVj+Aiw8{}kSD4!_W1DR`r|S@ zD0x7qA6jdDYCl>ZA3Z2}z(ikQ*;mj1B|IqkrQ`AFVxCR2d*zQOn+Hw4IHrgYV~nT! z+@AdQ{Xgy>-D%_L568trvWsJ^@U}r<4=8>(t_jBi03yR5b$h#8_sjy z4y&u%N6z(Nwk7GMye08&|F<7*JRtDwd&4p~){|bRje`{qu*CG=zI`<$Z-;8G1uLlV{>fB2FJZ!&FeWzPva1IAMMla=}@%O>G<^R zFme92y*WhGG?c}04``0Ee6d_dPkEX&N1`9jV^8U7GVq?De62hlG3sOX%>j$y&JlTF zcdt%`_95wpjhjuz(Jn}hz36P=h=m2$)Ps9@w<+t~b^!$$b!I(8J=>o(NJGuGaA1jQ zc6(fo3&&xuKDO>+Qy{yuT8%!p^&OVdPa+YERu(YN#_Zw4lyZ ze0cOM+dPfNg+HO?KVLY<&~8;C(mP z815t*h1o@Y{A|phKJC}-b{^LywDyjVjiQuNTWjy80i_TFGSnkgpq$Kz^K@*<>Gr_> z+N`;AxGCH7m931ej9@e}PuvSkhfybJV;hHLJ*+j`VjxD`Of|osD57kP7)X3zQVL{i zoj$p!$Ny++rRJQ6hzPMxIcFE!AjF6#WPcIEUJoB*(60X7@5h^BEnUUR0kVKnHw-?I z2w~nxf@Mk5JkS5>_y07OHGH-@SdEO)*-!=sGC^wvL$P>t8a@7Xl;ejbTvRx$er{tk z5M<1od%?VT{UR~W?`-BeyI8GQr%o+w7{VaP6gtXqQ5LtbM>S(w2%lB+JlqL}7)W^K zPR3L>W$(+fM5R`DX7`%8GEm$Z3W+^Vqf9<4#c#eomQvlRW`#DMC>HQX-rIJwQ=nXWh%wv<70QKS{bT~VdTLekg+=YqC}aA z;#rZ%A3s8cD%=Y{NhGv$ZD{D*Z%0wt4z2ZCS9fL?^X7{XWMf5QA!rSezPYuo1Kp#y z!w#XsTt~PV#(8ky63OU znrb@4_SV;}f9fLblxfow)7V4k#K?VG$q0trnlo;1A01N0l)jp8Cxq?9hCCn)xiR4b z62fWI)42*t0tJT_(H8nKd>{g}_EBlYtNha@G_iq;R!u z+m7s_HOU*eB^agHwrv-}7|3#K@*Bulf)QgoP>bZEQ@DBYjuDxHX<_WMLDOWSAwfFJ z!$1tZyLgq~zI~V9b;7;POhBf|G#44Bw>Q4Zt!1a%nNCV>F(M`8iCs}+AV!m0CX0j# z_HpRTtnWo{drxAFG*UzgT9_tM8hsC8+L4jf4;9%(Yy1A^L*G3Q)F^a%LJzczsTtVZ z%V?0?S=yM|*ruD;&tHg9>sCh}y>~cOnu`czG8zK1FBa4&Jm+Q%H3~W>G)?Yd1WiU( zL+Y6PT%Wh)<*W14tE)5ip2QeMi$L1DFp#p|(?0)s>)VaUu)o0;vaE#6M{=GLRnmXIw z?`L0xzt!BYxBa;>v%QMyC*kjKnl@hK?Z;C6MfiKndq3@3S^Pg7PwC{B{udYBe7O6K R)-C`5002ovPDHLkV1jN(!XW?v literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1691.png b/TMessagesProj/src/main/assets/emoji/0_1691.png new file mode 100644 index 0000000000000000000000000000000000000000..964ceb54577956c208d4908a6224ba74e5000bcd GIT binary patch literal 943 zcmV;g15o^lP)RRa#g&Jv%NhEfEh6v&+P#yS0g&n1qOgk)@%5l8zV{7p%g($Klqz)yvcE;NAG@ z>HqeA0a#D~000nlQchCQm%$YN1&NOY?7A>avTcP+< zp{={}J_z9)K;K_)#V<^IyY@XeA-o@kva7!}nxY$&QXzOGz}f|4`&)ag+(e7;`eWHz_Qo&K0eg3;56 zjgL>v*VpF=4hdkw(<@=bL^jg7NV(Xuy)-o- zG2#pdfe0ILh>EXk7o)N(5;#US2-#qhT(~Y4o(v=b35~=SSfI3TVtOPb8%XpG5jP}W zX$ag00<G)-xeCoQ+Za^*r{EsRghD**<9b=`=l6VVJ&E$eD9sNf_i zFDsW@T0<_7-hJRMXa?q)iQ-LEM9hq6oFgOB+SF+J#TokiH-U(q3Et0Lni&m5G$E{L zSa>UVKVdrxGYdeNhsS&%~N+Xf!Bbp~!{ax*7K| z37O!n$f;=zjQ|@-*_^#MKMDY#)0Id9E{8)@T*zbWsbVz8Oxl4f{x966+a|+V*)cYx zA##d6DwrNq$^-WToGTB7S~$0kc#M3EUP8XF4yU5rnyx0^KpKR*x5q*!gxL7jpcsh) zFL5;XxCfXuZTu{~7en!_(3IYLw-_8zI8(3W2@L z!m(2ml75J*`ZtB5R68ZcsLJCC-ya5LRaGTFBL4KS!Q)+xz`x|onKNh3{0BT literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1692.png b/TMessagesProj/src/main/assets/emoji/0_1692.png new file mode 100644 index 0000000000000000000000000000000000000000..2e691b9dca7d4a4057c42bdd4a4382e2c0c1350c GIT binary patch literal 596 zcmV-a0;~OrP)Iyf#bE+Zu*9331&MnzFpR9|Ida(Q=$kB!VK zR(b#c01R|ePE!CJJ!FHVz1G|R|Nf7nK!5-M0l`T`K~#7F?bLyWG)El8(Q~V7Y{>gR zYQjuc*G=}b(bftG2y+1C`a$vc_CNLZ_VyN$B$6Plt)Ki{{vx2Qw$vrKGA30*MPwn#A_B@Pu=gNt5rtx)50G{aM%myUMNAs_RbBPXJWqDnKu{w%Vq# ziUT|(s*r-Vr`wT+f>Md}1qXCb4T?f4uMI$Rlu#6jcy0*D{7|VPjdGsc@|XmQAYNx7 zfcX(Bg<_q>ZOn-Pi03K@z&MTxs&TEWzRNKW6$G#A0tA46PORO%>!*y70lVEBKztX} izYElV^Y-@k_VyQa(`7B#!{>1T0000g((C^Yird^z!rbu)4ayKow~K003QdQchC<2^}v+WqXa85va!L{{QB)u+siWoVdo* zv4&zV*8Tqf|LfVpxBmYA{{7a($k6|y6_I^(cA2QEzpVOi{(6d+&neLP>Hp~S`qk+F zasU5YO+-*tVr#iOfryq%Hpti&000F=Nklyz#L1q?W2W-=<WNnq%YUo5*wWG)S$J^B*qvq4zb@yogNe3bZ*E> zkcn_W8lm}(FetMNhkLkZKv6%JVdTD9f^UVs{Na|@>fZ-20MurH-8l60J--MPwuYdj ze?)xL|AEmz#OV)S4C;?6y1;H2h5-QTQaIyqxnbtG%=f?2r1AdqGqZ-T3~uzMsG6qh znraxPX?UiSPqBt0U=X&+N zY~PiX!A%HTqD)bUV7Wm$2zHtO|2r<&b<5{#kKH#syl-l4Wb@yfvc6}}RnHFs5lFPa z4}=y3zK~xuU-*9D%l};0^~31n`)4;&5fe@B9dE9_uf;l%isb&eCv2esN+F?)5k>%m zgi*=}WT5&3Qu&L5K-j_c`}^d13~^ffRSxZs4>-fMcW>1|K#Vcx7~u?IRJ}{&Ps!%1 z{9_Zx2-x)F+jlX{(4U(b_MWkh(PFwR z@-rqC)BWZ1#F4Bj5{Jr)Vm^w0I4Br`!F-utPzfYbut{JqSUclosUec-=}z%9)-w%( z!B;&r#tMRT?VM#^f>cG%FQyc`F6pk5` z>$$AqMA1Gf>QVu2iqF+BKc-M_QaC6mwfjd!%NK-pii2Qs=*GFz?{5rcStgVGXvjTC zZR2ET4h12eyvO7s1;_Lt39ZVop5?`f;)XD4-(4NCY(l6}T#n=_qy!QQ7G>#7&!>$^ z8L+!2ik?jg2*>$ZHzrO9C?4qyXy*7_urvT=nqNOrJPLrQ*~!l*Q>d{lOGg=}q<5w$ zx{4Vg5w=bgbyr|$T5r3PlgVTPtb;+vbfFGeuP6?JqNiFWW~XB+G3<saBP7$*mnAj3D$p!sJjAdvy{V4g?xy zh(%0-IkX4ohJCYA1O!!^bcU%IOwWQXM+6Xaj4@&|I6sc(g(O+HuJ60JRH9Jan5{Gb2%pMM^I0fy(ZllNjL;Q#;t07*qoM6N<$f)BNv;s5{u literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/assets/emoji/0_1694.png b/TMessagesProj/src/main/assets/emoji/0_1694.png new file mode 100644 index 0000000000000000000000000000000000000000..d2c275397c9157fbfdee7bdd5c321c990e677f96 GIT binary patch literal 1436 zcmV;N1!MY&P)-LpIW|5W9UVd`Z8{`iXg!-yL3gXHs+E+L zcXfF}DQ!6-V7a)tWM*S3Dk?%KY(6DtMk#VvHHl3wd{jArT0VwRFM*Rfr(*^CBn`U$F{5q2u zD$|QN&8Gd@SR9YP#Q8y*!=w>N37sE-H?Kv0zXyZzSSA~Q`hv%2fXr#r+LBOq8% z<$juSBsgOtgu`1k+>y@k;U^#^R1#E)udzHyax2n_X6JLYX&#-);}D_RKzd?sHXA4; z4+zhv5^cTZFk78s?0LdA4VVic)T<;6b;==+61ld^5Z1yN6f+4}H10PyE;ueRt(@5O zZAvh5Va>8a=M#zd!v!vp9#oFGH(*60QfiK27P`#cjo!)B9_7F{WgjV`H632i^#?P8l_VyDI?DY}E^bDg12!|`{!G&LQ8Q5a`dFqZiIc*dC2 zM!ZY+HG+`HE!vT|SPjF9ej5AzJ~g2e1c^f8CD$LHjDtsO17edUfDj>(Mt`bdd^iAN z`%ue1-I$3LFf^BWq+e)2KoC6y1c(d_UFuzX21boQD#C{8nn_*+a3~Tn0ON!Z4}uAp zaAFnpT&40r7$M>@E(B+cyP;Lkj+CL^K9euPbwgJ$qVWhyk&5f_jC>mP)kTzOKuE@5 zu0bMYXpomsiSnqJIXT`^$Uf qdocl{^G)Oa@0;%u%3z@Uf%pd&f8;QFE$a;c0000gL48CUyvSbpAMjgiw2C8NoMKn5LE+f|y3yK;K zv|T9P6Yb>{(IKg&WW!6u4y#$!7(=Q3m9f8LJWrwigcUhzP3=1)mrR)rJ_` zcL~ZO7M~FbtV99+nh^i468^d^|Ijx7vLOGD4gbO_|K~XRsecy#xg`I|IQOFx^PLd? z{J`ao3)y-F|M-ynM>_x4Gh-_O|G_ow9u(e$2=SB&fk+2(Is^R8EAE2?(`*F&fq4Dq zX`E#duyz-|mMzb%KKpQI-%AbXurvLUiU00_|Dl`dJ~fb32LH{->&-sum=FK?od4i2 z|N5r?`Gx=ML4W_e3;N(d|NYMY@J#;KQU9qN|DqTDQ%3*$vi&O_*^VRpV_5&Ru<6%d z|M*|q!c*sG3%4-}|2HZB_;>$5G5`MC|M=_w&k@RKC}O`{_W%F@AaqhrQvhYnhBN+K z3mE-Jp!WXx{gKYL?)}Mqx9r%SsM)5C{2(eN=>Px+1%F9IK~#8N)t6;gBij;&Pn3i> z1Q=kL6LoiY7u?+$`~TnXTh+UvL(X06tUI6X(>)}!v+JR@HI={qA6R1kSAjvRx7)YZ zz_#74*Baif%j@gQ|H5j}+t;k2<6nY6$hx+zXNzIOHX3zzU^J+9HrBQOMWD5>iST`f zHOKBXJAVQ;x>Hc!S<*V{)9Jvm{Lg|fZW06^4-ev}AbyZ)9PN|DYFAkXgL-{1uzhpX z@2AtBBZpye0yQiMzFq(Lso+O^cm&CDZ`|$P5&5e+7>vfMg%sA@$H%{p_D+8+a?tqo zt2e&80%=@V5OwQUTc1+UQwo{X>5o&O)SNO0XMZ)zRT_N%{v9uH-KD?HuY)}XLnD3~ zkH@7LML62G~Za3Z(Ja$S_^Q1jHhr|3*dtTMf&4kN+PH@L^sZ@fe^QhqIy*XQI_pQHQ zlF8?)MsYU2x-LCrXrV*1-FbR=c??iM<<4Os?SE{k zqYOM-cn2Oj&1?$}Yt-e}zbj0BQh3j2owLWYBjW6zK>G=Q^wjb6`yQXmzbzYFN$AE`pOtqHc#q*d9M2v$VH ztuGLk`hgG>D@zK+g}@g|V)K+iHrv_{?$e!V$}OeBgUSSwx8h(s|;qde!E#}p%WaeNGKJ>C>w|itB2PXkr^2HAHAp5^mwe7+zF1T3kpmp zV}c^)0)7Sq^@Rf!Zw9b{@qbpZ7#EkK4-dJRphaagNhsLBxReU8r~pDCZ!LYTP%JKH z;my2Tyf8#QXHhH`lJW-Et`;~A27YV~Pk_%HZoc?v1w2ql4i_sD1$y*}RTYZr^K;e3 zNw8v`3XTOi5G+qcK|bsTm7`a~vKD)`!C>6Gq$E7K&k7uG57MCh=YOIrM&mGvVL0wa zBU`T+>(!?}e@<;Z9}N8T_^?Fi$|)V3L`^T{;25BSyYKdTC`)q50S64x*lwbb6id2ct5XR_6&Q0jeh!eL z@0pM9!z&!2kYte8V}FB7I8lIsD@hS)m2N*IIcuxj=QQxFa=V2>-kRUWh$n$uJmsqa zn$Au(J84<@SNCsQvyi%jb2Qe>;-}I9S3O8T>C6OS~8{@j~(nEXqLe#NMg>h z!S%F3vnnKP5hOsNkaYenRle!P0-TX2S8IX<7Sb>xK8a(owY&)jP2{Vxd|pJWQP*H0 z55sS3HMK^IWI2z80(=pJ-lSe-jR;>=oAlxt#Ty{6Q~j$i+#1u$idwz0V$vwTaBsn3 wG^_sPYbU>9L#H!iCjSJ(<|Yh(hIY>IAMk$mRx{bWegFUf07*qoM6N<$f`Vi z#$^Wgoe=JyA?AMz@`eWUniann0?`!1=8+B7 zb_MjK6yS;q|2HVjYy|ly8v0K|;TjP3s44niRr+>rpfI|To{3jfbFqH`I~tub060R62N z|J@n?%n;|rE`R^%IsdjJ%d%I0MFsh&75>{Y|GzB$vm5Dw1^>D#j8F&v(=O7QA^+ks z|Hdu<)inS9$uVG z&~EtI^{kA%Ss-$o000IfNkl@W zZeK2!F95u1&9x-*pA`tB0tCyAEoX+|IEInQApuKOjD*ifh9VWb=!x^4C6Ni0h#$t` zB~(=_l7H3xtiypTvsYDxqz}^25pF!^K&^qtflQ-=oC_f!FsMd@!(z0^PgQ}0;aS6z zXCz6|Sy%zx$S`%BG2kr85{hw5(g52UI4(~+8biy$Lsv`IV%Awso}>!~uO{A_ zHIT&>`v(3B6~ARq_FA$YUJDfA0$uUFgBU{$Rex6H8gpk^YB!L_HUlb@y%uOZJQ2fG z0bRDOeLkP>puFpZyG4huK$QtmF8VP7l`0}7&r4+|zejITDg7vdi|$O*v~4wdYy^6T ztTTjaXxlcF-Xd4%4PgQ{81|N`hheCPY^NSlY!H9}ct6Gk41qOGGqoug!ZT0<)Mg+-UsMn`i$v=vB5`bM0LC~i-0`4OaQCQ4F*vZ2gTeRX9>jVq z%W|*$TockN7U-U14|9gf$|e~?j%^wQ0huY0PXOPC zm(LJeie=3#YYM+i`TT|_L6ANmxBI>LUw`h8?d@wYnP5V02-%R$=2`i(K5{hp(QKOM zf2*&*o<^}S4B!i`NVZq%jM_gcZL#!^&cuc*lZlOqX-MmkK!db}g2Y0<|0mezec>?G z?3$gu+h;OrjOXWb-gCS-Q37Hay!}|K$DgX_BZUnY*n?tjC> zvl%6m*VpCZQW_-@7un)4DSy-H{FMa|D;dO zqn`kP5P)bj-w|&%6NQn)&%3$f`XVuoGua?XF$ta~2r*72z0BtcW0FlWx_=(-cpT%7 zBn03SvVk$@~S_ z?&sD|Z%arrGJ2HZu(Phy*Tz?29BAoY4Mt}8R~X~*{MT_Kndw?{Ez4Xb7ZpR30nWcoBOM%3ZEZbbr$dqaXlrPU)Nj zLYLm~c6e5v2~PtAjG_o3ITS>mwbOMycp7!Du0U`Y8TL*N%YhbKu}ecZPf<7xBYiN? z^{3HsyEHlohH@qdwMJVh3`R;t$9W785X)x2O9m^PYvYsvj;vuTh4CJ_yALh1#l%9t zAtDzT>Kv;jQI)V2Hh%;{$&JT*YZ|r&Itq@cMhZbtpQxzbrz=1@oc|8E-U%wG$Nn=HX*K3lj z{?=1hk!oN#8ZwsGBt<-Re?w6ZWTjG(q)J7R57g>^ez?)m100000 LNkvXXu0mjfoe{iN diff --git a/TMessagesProj/src/main/assets/emoji/0_170.png b/TMessagesProj/src/main/assets/emoji/0_170.png index 123e24484c30cc7925a44cc7743df60578fc76a0..835f1f2b95bb60f954721eb7ba6c4fcb71ef53c2 100644 GIT binary patch delta 884 zcmV-)1B?9K1&areB!5d#OjJcja7^pKoydh>#e!VtxRleFa@L)ArCK=5m2t<1Vc4H} z*q?ds$E3)GUgEHe=(?Bo(y{s2x9-EB`rNzSrh(+Ljq=Q@)tPep-@d?K{FVR!01tFh zPE!D<{*ZV*U;Ymuy4}v%;eA&KOaK4^;7LS5RCr$PmfNzTFn=!LGjw* zC5R|I$B1Sr=9CErR$N7KWW3%TccjJ9p^}ViLVpNWjMW+49H}TUHmrez#9T~Z@A3kf4pfCLdJhOqC*d5fjT zyMZaUh8!XXU_lOz2wrRpOJGSy;82Qh2h&)+rn^MEgqQ@}Zg6<%^op69u6oDNTmvkO z6KxU(6d^YwK8LEmG3v`TKywfg6-D*0j2&lTjpPBvz={tTU@63v5I$5$MOiGN7?jf0 z$8Z#RgJU<9Z05&Nro5sM;yVU?QAMDd>U+9onxvt=XL$W}{o@aJxsy4liLqb+0000< KMNUMnLSTa1jH|-{ delta 709 zcmV;$0y_PR2i*mbB!4zgOjJcja7=tqJ8ecXYeg}8P&%M$QLA-XaY{63LN26jQ=@EC zf>b`QcU!iBVU%D=yNG4Ijb}?Q9wpOGvj6}93UpFVQvld-o;=E;7yE0>=CsKG00K-& zL_t(|UhUJ}Zlf>|hG7B*oB1{Of3xfHz_h!BrnJ%?gkswyk@IyPI&(!6N#Rx71{_oiB_R_$@an$}n$l`$jgrR4IK?FS9Pz`pXH6o&*DPcTYL4b(T!m@3| z2D1}pJW9cqAx`Mi6=f@>Y*sNs;~=e^#>tp4&V-#C{eN*pCw#>^c;S3ykQ4+~2H6U* z`gPLiK$OP^TpA2Q4eJL2GJ+d11rW%57*8%#puvoYn_LrNSf?2zT&ti~EH>2$nDbZ0 zX$AvS7S^gLJ3&Fb+MypaI!y>hkgqtGA8u4Vf5)MEAlyg5!-#W9fZXsQ9n)^WVX$5i z-e`uZBY&Op*bHW0rzQk(HtZI+~EduH1Bojm~3IA9eVdcFr zP@p9uh~scsdYD0cjtFooDA+2GG+dWv0aMH&j=xRl##XH9N{HW_AwWQ0U;u(sYUSZo zx&QnHJc>XXF?_e2+7@Tr@q0ugZj@|`F&%QE+&&`wS`Z~_LKz*nIR$qHn^3X?_osLz rM%-_liuF?=&Ql&!8h%&KSHQbJ%>8Oi?0*7W00000NkvXXu0mjfXXHL^ diff --git a/TMessagesProj/src/main/assets/emoji/0_171.png b/TMessagesProj/src/main/assets/emoji/0_171.png index 4ff6b12a2195e65e5f77596296b90708eeda56d9..57402a0b5320d38599ddc8be3aa119251d4792ec 100644 GIT binary patch delta 738 zcmV<80v-MM1o{P#B!5CsOjJcja7>9%FU^*1vU5zda!S^xf6bR~xO-I3n{vN|Tfcx- zw{=b5w~^GMde^6b-?xz4u!+;3cFdD%I^ndgtOAohMqv$V1Wf>zJOw)r{oo8XuOiiHkXyz^xStl{WQwpsP$V`XZ|+J_cU0md zQDVA$s@$@)Oz_cNPB)aLI$4D^e0IQH^O5(H`>YT*Q~ZZQ+t22=DZ1a)KV5(O1DK?U Ur^y7)7XSbN07*qoM6N<$f>cvwI{*Lx delta 607 zcmV-l0-*i+1^5JzB!4PUOjJcja7Z7BtyiJpcdz2y{|TQvm)ROrv+%%>i&XUJmIvfJx}T3#`Z;eBmDAG-{+;-irFV2<5o0<2t!3(hUVC zQ6 zumqW|1l}oxm`a{!lVDg*8(AZ8|3-%P8 z51!^jhs1!Mq#zo{7vhSYBOg1+9CB=OXaTE2+VlGyM1LeP$XX)kkz8@cVKEE}aD{aE zkz-I(ZEg6q$VLhynd4Jn4&d#xQVbN@^Z31ONnv39o<<6HVCNtm@-c^XpBqduAiINn ze#admQ2@CdD`GXr5w>Na=(hC+AN?(xgtsB+F45_Ng&5~(D%s%^Ykq-m2TP5B*k=wBv}-=NGo|x;bn2)k6^Fkg(xmq{Lefe tC4?qJDbqD#$|2k`_wK@&FL`GEic002ovPDHLkV1fl(60ZON diff --git a/TMessagesProj/src/main/assets/emoji/0_172.png b/TMessagesProj/src/main/assets/emoji/0_172.png index 651d49858c62423c6e325bdb0e6fe264de63fa03..5d640ef0f920fad11d782a9275a6c9182f0571f2 100644 GIT binary patch delta 708 zcmV;#0z3W81l$FXB!4zgOjJcja7=tqJ8ecXYeg}8P&%M$QLA-XaY{63LN26jQ=@EC zlwe7MR6ehFTeg8=yNG4Ijb}?Q9$qp-y8r+H3UpFVQvld-o;=E;7yE0>=CsKG00K)% zL_t(|UhUQ0lAR) ztLYmzT^K2wj(<*+2Dk*y{dWK-227EWSw?RPFhJDCY>(PW{;%XlL?=vJTVsDAo9+uD zR~j)XtvLc?58$M#wxpbBoq|FoA}`se|M%Cdjc<)Wq-Sf6K#qK!p1o>l#`HUBc2mk zcGpyU02`+7=%r!AS}`1m)CsG^{ovcY83%7DQ-w`LW@o0a}HeP)u=Tbc<2){*KdX5*vn~4#cj&q%hV&fMpoe49hPG z)VuNcDSrZm%ndWR1?K>9Z1_0oUg*y}`Knszs5j}WYM7ZTb>H%CGMOH?tkRpIjMnMTf qd{%!?=u@GcCv~_`KPkpnz_&k+{A$jKXQ?j$0000G00GZQL_t(|+U?fcZi6rkfMM*Mu>Jn; zJA4R5V(waycEw+brYriIWCeA3dU|^L=SuIbwQ@(OY}Go3S%2kgZLGA?%&lsirlvj( zEnc5KqO7x>it(X&LR9NGF1)W_7GUi=QP-=DvajR1;Y7PZP&1<6A*vDM4#Dj{(e0~w zix^Jah-(m}4?TPvag8g)Q{*B+JX7Vfm?u#-qBHozkhdQhGbIKwf{0m(0()jqD%dG{ zL_vzb`4^*Oq0rgR!S7X&*o&UbS&vT1-mA))|NLZ~rvgY|!j+W}=KYFV;*WYZv917bo% zxxqj&LUsa_$ma2jphk=tNrh|{OM}E9H6kYflt>JsGk;;*G2h6DsGkiY71RLsA*1k$B!4PUOjJcja7Z7BtyiJpcdz2y{|TQvm)ROrv+%%>i&XUJmIvfJx}T3#`Z;eBmDAG-{+;-irFV2<5o0<2t!3(hUVC zQ6 zumqW|1l}oxm`a{!lVDg*8(AZ8|3-%P8 z51!^jhs1!Mq#zo{7vhSYBOg1+9CB=OXaTE2+VlGyM1LeP$XX)kkz8@cVKEE}aD{aE zkz-I(ZEg6q$VLhynd4Jn4&d#xQVbN@^Z31ONnv39o<<6HVCNtm@-c^XpBqduAiINn ze#admQ2@CdD`GXr5w>Na=(hC+AN?(xgtsB+F45_Ng&5~(D%s%^Ykq-m2TP5B*k=wBv}-=NGo|x;bn2)k6^Fkg(xmq{Lefe tC4?qJDbqD#$|2k`_wK@&FL`GEic002ovPDHLkV1gQq5=;O9 delta 1022 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_176.png b/TMessagesProj/src/main/assets/emoji/0_176.png index d45970a6d2e4ae0277c77ae0ee9e02a7f9d6cdc9..36b7663d2b618415fc5556d03db7fe44d113c07c 100644 GIT binary patch delta 862 zcmV-k1EKua2K5GzB!4zgOjJcja7@*jb?3R2;H`<+p?uSsbk&`CyLnU6m2b@H zwlas5w*UZPn<8-AC2NrV*+TuEkV7*GqZkR&_lSzE3p%1foJR;kH#36>&6D)!M3B77 zEs4;~ND_MzZUQ0C43$nBj51Y)C4tKZc#g>=4UsL!gsLY2LeDXuM7P(R5_+LaoxH%5o-|%z<3!MBrSK2#vf@PIEb+!Mo7>RgJaU`h?J$ z63CI{i$ZG*h#}?IYE@z}kTK#XGtBw0Z`LJMHG~vm`7}vdLs+*QS-NvvwEw;;f0!i4 z?ib?1a_&xI^Fzg7jFN14B&Ncx3lted1aJFfY{J9^9e>ehA!1M8C*$M#ju0iWR$N}j z7y%c8NZMV(X@KyRj%Y~j7a|V2aDVd4R$di19t&* z7=--ENh?rFV-ye&f$l*Bm_eEV)#o6DU-QZMJ(f;<_Nj=8YPlc^H+alXh}%kFB%5$CP~i^|HQW%L zL3(1y5hD16$Q|LbS(pr@cp(7O^QB0dL!{Y2O@BstBl!8=7x`{Oc0m_k?*&+^0|tFM z#4#cV6!7`VRf)wJE-}y<&;P5*S4Y|7j;DZofW7UO_4?oQgq^O{W7-@v&-LRLNxymhb<1s9TEb ovMgoU71Q=Lz^}2jD?b_d3n?gEhfxV`o&W#<07*qoM6N<$f{T)sNB{r; delta 832 zcmV-G1Hb(B2G<6VB!4YXOjJcja7=klIg46Fl3_`fV@tJuU%QB8q;FKej%dV`Ypirx zpJ`BxTt#?II7=@crcZ^V0000EbW%=J047$9w*UXy|NsB~`TisozLx+10?SE6K~#9! zotO!Z!ypVr!(!tYGWS33*cj7PBZUlKZ9r;x`d$#I#|woR^naOhl5s~d1D15ef`lb* z5#SVIE<`6$+3*p{sUl#~0n-Ko41oiY_u^0?;I@lm2m(+7Y#@$8!v>Rvvs01;9~*=v z>=c!U4PYY3$BqhmBw%suL_*#gQ1&`J@U+3{*h6F-Hn_%PPl*RYr zFPlsRdxK(G^?)b-;)&=X>El&*g*@KFi{&XZMUd!p0)KH_BUFm$B4%CeTAw5#`!nh=@U3_DZ*jON@Uro!8 zN%C@IJnpo3Lttk(q|P4}*QLlfcY`vx)+Q3p1w@mbACeKi5X#^x7wQ*MN2VXPUYGB{*|pbELNLZ%F0 zggLj2)C9s{azHV{dn2t@9;ymx|NrYD#FTSsrkr9p_7qHy%YOmNsy3b(g>Yd20000< KMNUMnLSTYT*m#)$ diff --git a/TMessagesProj/src/main/assets/emoji/0_177.png b/TMessagesProj/src/main/assets/emoji/0_177.png index 2d5423117ca637aa77a65014c42dd7ed44f73126..b8a6f7825b5a800d8506ccc047ca7c769f81b971 100644 GIT binary patch delta 853 zcmV-b1FHQ01?&cpB!4zgOjJcja7?gtPQ-~|)T4a6f?B|dV#JMQ*QkM?Vm`!&UATEr zyoP=5QG;I2Amt`{a^OL1QK_%D~3)=@9zNhw(y@NtFP8iKMC-b|8q?|t0cy^R5z*!{CG-b<2#`K55M z5ekWNyT4|}dp+5qnDpRsLSTVW&smZbd;dAZ6VV8Wgnz|^-rXD5d~^hgRzlab7>4L4 z(i5SIO&fZ4e$;L z*9cIl5P!u&atQv)pqQ=^RaSZg$vUFoH`sNOz(m*$t7HKtBx2w*1AV$i4EF?@k0VP} z7G=EmrWxYp7bGA5y5!8@Fy9rKs6{yjLzot z{1IFs(so85F+)@1oDt!Acw#v-h?^Q^AP`w64}ZpY22zueurr9o8DLt^0eNx?c4u(C z<#IOjf2d+i_KR32({p3OKM7Xh>DDo{B=0`Dtk1Kp<1S42mk(+LGcg$%Y(CxzHjULx z%xr+!!1C5y22e9GwV^<#EC%ZqKt%r|I#%}Pz(Uk+J00000NkvXXu0mjf*%^Yf delta 743 zcmVP<5#Q*=@8WFIzSC9;3Z*XBh!+s5mC^R zh+oTr+}c1|oqq?{Hu&9Gt@pNm6;$UcaUSr=0WR%1l#tfOOcHCY3XaPgp7dolgxMrE z2IoSw0epVb2ca9vb4hGMnZKz7bz*KNQO;f4q#bbZUP8!oNkaXS%}Fp3SXXX8yZn2C zb1x<09KoHC8-X++@{PzMd5y^Qoe0lF%4glX;7$xil7HG>kWK-B2x{>hA;o|(4B=kI z(-rhQ)lde&vKbNNTNOp(fFJ=wjG=n4ZioPBKp1`7kSdk9BLhOnD8d=E?a%)T!9Eir zC|4p4^TmkI69IE=m`pjQfS_XI!TrW8e#TSn27^(c z%e4LACeVnAXra*zdH#vvsS|go3Y11SMCQLjR)LiQhF8Z>lH83#6k+uHEE4#O!9~y} z21(?v!TAIr<0iC?e~b>0iQ_9uP~(Plfx^^1Q($h!xeF?2j2VMS@C)gJ@spQTM^X^J z^gt@a7k6ewiqZw6!fe@ONEKxuasn^^5b(jMq7YF5-v8^t#}u4%M$3g16<8>1{ZaPm Z{T~aoJO}!Po>>3@002ovPDHLkV1iG3Q;`4w diff --git a/TMessagesProj/src/main/assets/emoji/0_178.png b/TMessagesProj/src/main/assets/emoji/0_178.png index 5f1381ea7177a5dbaef53ec0733ebd9f51f811f9..d45970a6d2e4ae0277c77ae0ee9e02a7f9d6cdc9 100644 GIT binary patch delta 832 zcmV-G1Hb&-1=j|UB!4YXOjJcja7=klIg46Fl3_`fV@tJuU%QB8q;FKej%dV`Ypirx zpJ`BxTt#?II7=@crcZ^V0000EbW%=J047$9w*UXy|NsB~`TisozLx+10?SE6K~#9! zotO!Z!ypVr!(!tYGWS33*cj7PBZUlKZ9r;x`d$#I#|woR^naOhl5s~d1D15ef`lb* z5#SVIE<`6$+3*p{sUl#~0n-Ko41oiY_u^0?;I@lm2m(+7Y#@$8!v>Rvvs01;9~*=v z>=c!U4PYY3$BqhmBw%suL_*#gQ1&`J@U+3{*h6F-Hn_%PPl*RYr zFPlsRdxK(G^?)b-;)&=X>El&*g*@KFi{&XZMUd!p0)KH_BUFm$B4%CeTAw5#`!nh=@U3_DZ*jON@Uro!8 zN%C@IJnpo3Lttk(q|P4}*QLlfcY`vx)+Q3p1w@mbACeKi5X#^x7wQ*MN2VXPUYGB{*|pbELNLZ%F0 zggLj2)C9s{azHV{dn2t@9;ymx|NrYD#FTSsrkr9p_7qHy%YOmNsy3b(g>Yd20000< KMNUMnLSTaVN_c+& delta 708 zcmV;#0z3WJ2HXXZB!47OOjJcja7;uoD>^A6B^eStD%GbA2cMmtqNH%&M( zDjgOo-IR6!000PdQchC<{{AJ@Q>=z$x}fg>00Li0L_t(|+MSr|vV$NHgS*Q$@%`WT zxKKn#D;)9zXB_#O>>`8xOvnXiV~WYH3knhN=@UFaAC?HryMGWp?CKYMIG>9s<$|Q{soAg`YYN(u_|Gz;6?EA}+>RuRwQ$sC1935jP!Ah!EeEqS8%#?%1Q{w= zDX81kR)y+9L4RHJfKRqIku#O}$KL6j4IXud6Pt`pSP>IRQuIECPb8{wUw>bfm`svT z`+peM;$pfdean}P`HTRk-;>x1e?q|S*)X-b+_A}>5&0qs14M2JX)`1@O%=n%_MrYk zU{udLf;Sg&(9Z zkT5`~5IaG4A>YMa>Ak61w5d^;9|THzcOeBJ$S_WR65;?sN-YORx-}^=`KEwbJqeFPQA76^$E(lOW^vjV+ z7tZ6#pnsT*(&3Qw-c{ra12l=8dP3{Ss3lz};(2L+>ZXo&cTP9qUlFbuzEgUQ(_jz( zfyfQP;n6YvveEnO$HzN7yC|YeoL~K;4HO2AV8tBScw!iVg`i>Lcq6aVN}v(*&;tf=;M_R*0!AY7hdg6Fr?U%}8nxVO5>4|NQ6=QH)~J0@(cj q|9Wu24v=NK_?UtLR^+N)r~d(KelgmyW(RHn0000P<5#Q*=@8WFIzSC9;3Z*XBh!+s5mC^R zh+oTr+}c1|oqq?{Hu&9Gt@pNm6;$UcaUSr=0WR%1l#tfOOcHCY3XaPgp7dolgxMrE z2IoSw0epVb2ca9vb4hGMnZKz7bz*KNQO;f4q#bbZUP8!oNkaXS%}Fp3SXXX8yZn2C zb1x<09KoHC8-X++@{PzMd5y^Qoe0lF%4glX;7$xil7HG>kWK-B2x{>hA;o|(4B=kI z(-rhQ)lde&vKbNNTNOp(fFJ=wjG=n4ZioPBKp1`7kSdk9BLhOnD8d=E?a%)T!9Eir zC|4p4^TmkI69IE=m`pjQfS_XI!TrW8e#TSn27^(c z%e4LACeVnAXra*zdH#vvsS|go3Y11SMCQLjR)LiQhF8Z>lH83#6k+uHEE4#O!9~y} z21(?v!TAIr<0iC?e~b>0iQ_9uP~(Plfx^^1Q($h!xeF?2j2VMS@C)gJ@spQTM^X^J z^gt@a7k6ewiqZw6!fe@ONEKxuasn^^5b(jMq7YF5-v8^t#}u4%M$3g16<8>1{ZaPm Z{T~aoJO}!Po>>3@002ovPDHLkV1m13Q(gc7 delta 1186 zcmV;T1YP_81-1#0B!5~^OjJcja7@5>3EPwo#&inHgbclP3e}Gcn^ptPh!3k{2H>0# z!Ep-bsv+&MCiAl%|ItbR%s>CtS^dU0`@t{wx+eeBQ}3-8>ZKCnn+)5K3eSHExM&Rj z)?bZA4XWBy2mk;84s=pZQvh1g=XOQ25|=CJ#KqeK(^z2u0DlAhNkl*DE~M-o{Tu?|<3h>#0Y0QG)6u1}j8({PZ4t*q`dj=;Zwdrkzk$2z+)D z0|c&N?6~jaqJIVLCZ>de3BB)py){BVdXMz>u66OF+&0>VF>w$nIs4Ojo8!)9ufk9PYyy zvJmKI0=hG1uR|L~n~Y3T{f3xIbol8$$F?gN`X@21>os|83?L3{e)|c#c8=*=v7j$O_vW$=Ca~_sEIIFd`sQ?j%K6;K$8_`aL+0#l3 zYKvAQqJIXePYX3%lCylK`s_ePuowc`LIgbs8ft8x&86f(&hC)e>p;K#RLl{Egm+s`&kIGY$-yJ%YwmkLK`N6V?sVOr$$g1 zLVG$3G`s+9&28r{MKW91*6!>?l-1N1ov+0?Yk!@OIV07luoN^sHJ=dRy`zPx))-St zxs(ziQd0CfFaal5r=n%NHg8)h$!g2dDA$VfAjNJcM9DejTQ{8gpfc$f4j1WN|U!N)h#XAp>a-}*+l2i1S3?a~7mNSBCOO0H4Dy7s) z6gV9|L>dl=F^cde%J%1z62)jl9M1@6t#!?)J5s<~3>@vEIv|F`f=1LIqw;PD+Q1RP zB~FMb0}Ip_-$invFq5377DA*WV!bgD0)HEtkeDdqR3cgl>+^W{%_l9GXa)d8U?@jv z!CQnf99~<|GeHr<^5J-aJQK(zVqK5#b|!X1TaIIh+G!RXr2BG23oHvKs-LVp*^v#9XJ7uf7ECKL(0nDJ-PS`#9bS)%X}jkVbIYoim*MoPWA= zjjtZK6JCVECC+N>27Z?ifCQezX^q?rLH1F!3M8nWpE6f6ydcczzXaY!MYauDOzK(-h5O6; z?LICI=+8Q+`~CXPT@3>KKFhMM>l?JLwETb0ztG%?EZvwRpa1{>07*qoM6N<$g00&% AZvX%Q diff --git a/TMessagesProj/src/main/assets/emoji/0_18.png b/TMessagesProj/src/main/assets/emoji/0_18.png index ef3c7c201c880a5f05f6d64a04689f264188ba86..6d104553104035636a0cd363ebf704b0178828b7 100644 GIT binary patch delta 1978 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 Xv3-DhLHP2i00000NkvXXu0mjfI4azf diff --git a/TMessagesProj/src/main/assets/emoji/0_180.png b/TMessagesProj/src/main/assets/emoji/0_180.png index 147a69559fca746c7fb0c5e2aae98ef7ebf38b13..5f1381ea7177a5dbaef53ec0733ebd9f51f811f9 100644 GIT binary patch delta 708 zcmV;#0z3WJ2iygaB!47OOjJcja7;uoD>^A6B^eStD%GbA2cMmtqNH%&M( zDjgOo-IR6!000PdQchC<{{AJ@Q>=z$x}fg>00Li0L_t(|+MSr|vV$NHgS*Q$@%`WT zxKKn#D;)9zXB_#O>>`8xOvnXiV~WYH3knhN=@UFaAC?HryMGWp?CKYMIG>9s<$|Q{soAg`YYN(u_|Gz;6?EA}+>RuRwQ$sC1935jP!Ah!EeEqS8%#?%1Q{w= zDX81kR)y+9L4RHJfKRqIku#O}$KL6j4IXud6Pt`pSP>IRQuIECPb8{wUw>bfm`svT z`+peM;$pfdean}P`HTRk-;>x1e?q|S*)X-b+_A}>5&0qs14M2JX)`1@O%=n%_MrYk zU{udLf;Sg&(9Z zkT5`~5IaG4A>YMa>Ak61w5d^;9|THzcOeBJ$S_WR65;?sN-YORx-}^=`KEwbJqeFPQA76^$E(lOW^vjV+ z7tZ6#pnsT*(&3Qw-c{ra12l=8dP3{Ss3lz};(2L+>ZXo&cTP9qUlFbuzEgUQ(_jz( zfyfQP;n6YvveEnO$HzN7yC|YeoL~K;4HO2AV8tBScw!iVg`i>Lcq6aVN}v(*&;tf=;M_R*0!AY7hdg6Fr?U%}8nxVO5>4|NQ6=QH)~J0@(cj q|9Wu24v=NK_?UtLR^+N)r~d(KelgmyW(RHn0000fT0(?EzZI@U5cz6V1zy&-XX z0z6&ObveoQ^eV7~xu<-5WjvA#XVMXRD+os?B&6l}Tz}GIg^WamYy*9T4bIVCXUVkF z4r>D>+KIqAfrT?FG1!pQzeiLWknUh*U5G*|F?FyI8VF^C7?OSFwpef%gP^f3sAcal zVaJ>Xgf853V_k{G2n&sgU4!mTFn<$%iXgQ5>6<{z+hCkTBtotQB^e6SPJKhHh!NrQ z5zGLt0)Oz4QVR4iWK`lcAQ)J_Uz+2>Xd$A$_)vrhm&961zjSS_RG|HLC zQbee=IU&A+nStYgXsx-{DsXFzq&-N?AcQg?xK!tAfeiJJgDm~`;Av3a!ZjhY?@PJ1 z0zWZBpFfub0O*B*xw^_M<`J+uX!y|aTDNQFx!P02ILE>1l7I{%nDNKbik3m0 z0DnQGJ_kfAL+UW3WGjORVY?z&fPOQI!KKzi5vPG16Zsnuk!}BotdJgY7|E*0>@RK;f{Tw~)&gp1#4w=Wrv5Qbd}$r3SP`e7_r%a}h2aOm zPeIz4H4G6(1O-%>GuEoe$K%I@=>+d;5jsU~o^|z6 jf%^#|#u!3){O|k)o&RS-xn)}v00000NkvXXu0mjf%4645 diff --git a/TMessagesProj/src/main/assets/emoji/0_181.png b/TMessagesProj/src/main/assets/emoji/0_181.png index eae0a604dabffc9c100a8f11957ef732a7255beb..b3fe651fcb027e3d9b7719b6512de30c33665aa2 100644 GIT binary patch delta 1186 zcmV;T1YP@s2et{2B!5~^OjJcja7@5>3EPwo#&inHgbclP3e}Gcn^ptPh!3k{2H>0# z!Ep-bsv+&MCjZe%^RpiR%s>CtS^dU0`@t{wx+eeBQ}3-8>ZKCnn+)5K3eSHExM&Rj z)?bZA4Q3I2W&i*H4s=pZQvh1g=XOQ25|=CJ#KqeK(^z2u0DlAhNkloxWx z)0fw8SbqwG(eJl^ZM_qJY5MnXGyGWM<=+&)b`paT!oR-f9-Kda)sxYBCNzH6u^J)Z ztCJYe^BCHU=YJkIC1^J>Met0hbMx&{3H9o|(#J9OZ8=dPyd|_RvjsU3w@*6=V!E-H z7*X*U-VL8N9TOVj)JsfJ2z}0dv$Y)Bth)>g$C0xfUd+th#By`MXW&uGm=Y73+w9I- z%K)rpj6q2iZtN$RtjW-hZpV43zEVkhCjpQoH?`qlL4K zAqfF?CZIcGa>`2?M>Epq`Ws@(!NOm!86UB-}y zHRVc}jtg0qdY{%9<1)2TD_o=W0=9J_%lP{Gnuq0y)+nV+%t(Z$kDh~7TC|2RJ347_ z-Gfm8pnous+#t|7O9x{qA;cI{ z&N*P9#Nd=?0&mMTLC5%P+V_~FQHG;H{;ybvGT5U*HPq!^qbLkKXprA5%#GDa%gO3tMa zg}ll^#NmP%g9rza_dlQHAVwv^*dnYk##W=8NJeMCbCeD11u;Yx6oC2|g|{JSM@s|` z(IBRTEYQ4g43aX1nP?SwFGRc|wg(g5vwxuo36UaBA)*dpT)OIFxiJAuR09zMGL(W$ z!7E}OE+0v7Oi;uyd^t`a#{}>Yp={T$or%*>hGPlhmK6&Y<8!$phK%-y0g4nQh&5#J zZjq|E%68*TPQyc03=2ktkjg~BdctRDx4qPU|bm@_&qI zPeX)CoDYYGXpM0if>hxENZ=-#W29;ba#kTiBBAHY+IA{;~42B2fBKGEa|Ce24WD;f*H>@*5aJ!+ zLP~xf5|{l@xIL2kD9tifCF~R*j|@9jBt__+JqXn@8HTs_!Ci>3zeIp7@K+w`B_i_v zD|5FPBF)>`_IyGomCR3ezfu!RZQf6b%}wddcVzroKt;hfu8$l7FGETZXxxUc{$8G)>^B1-diZpynw=nx=_wYRr`Xw)IAPs@_x zX9FVIi5P`+ol7871zD562cb0YEE7mfa|Q7hEE<9&vwxz9jIh(7AgQ%Mu~~5;^kdFW z%{u4^+;1ZBa}z=uf^ZsPO6|ph4Z;74$PK}F1kq?_g}oI5sY(F(UJsHqK*%8y;F1CO z5F&z#K}ZQQ7#D$=>sl;@k%@$=EHZ)mSC#<+QMb-N1vBiwL;@g!14J%(D3_dz9?%Db z0p0hCpaa)~-+;Adb4hPo6u7lbZDjJqTNfPg5X zI${N4EvafabixTB5l}`cS%r-;o}L~+6mc@jPZR!)06#(yk%fV!JQ+j~zTQfdpuM1{ zw4M*;6reeTL#tndpsI5CN<{b@VqN6QSsRsAh<`bA?^X8SCwM=}4n&94-$v2rI>`L!V$;LupiA03ZgjD+{hoo) zt_0kMSF~o_Gm4Xt;{dU44EH$BAg;baHFFRKo1>5Ff*!Isacx!xQM2I!oP_Wh%WXOx zs%3g27eUh)D(Zw$NRuUT5GHTFaYKVx9?gba%!rv>GBTed(2T@N*px7*HI$5%qT&-! zG>dt;u;q+RxdQz9c_|mecB&lT5DoBJt5dC?|E)iIfnQx!weO<<0000> diff --git a/TMessagesProj/src/main/assets/emoji/0_182.png b/TMessagesProj/src/main/assets/emoji/0_182.png index b9a8942608f91e78c14e3d955ed19a049dc1b94f..0d69179eb56f3b2d8f4af033a7a074a5f4afc4d0 100644 GIT binary patch delta 961 zcmV;y13vuh2G<9WB!53pOjJcja7^a7lv6_^3n{lt%UvU=aA5l9(y`BhamRko-%D$FMnD|IE)NMX zLPjTHc}PS$emW1U5whGJ=Ua?;4-|~Rj?S~A5fnyiM&xvt@cC!Op1T?E5|NBR--!i# zXW=dp-e|@${(o0N_WMU<>BJhos}k||0PEcdNKdCZk_crCL&XQvv_!T=vV8X?+Sl!Q z0**yGT>~EwuboiFFcRaVXVc=X6VX-PJjwnE5euMvYTtWTkZuDZ#^}h(p!gY#$n6b@ z`wFl+wskqR?a?Zb!@akBd}ln9nX=djeJ==SCnTh0U4NJK+90EdAoYR1!wzG#*IBY0 za==yrMGg_@oxnmFjhJjm(%*@21+g70WDBv8gP0#IgbIxs#HmUr@`PCM&}yMlUr_ka zbm739CWI|KawS`dti*`SiNk{KLlFHE{uUwF>z7{wG4GRciilQQ7+W$h$sxKSM&=pe z^BK$lu73c~8D<6zK}I9q6M}#MfVeth!X6RP#i!DUa7k>;dh1dv7m(xcNCwE6uZg`l z<|dRkX!#69ERjQToV8Ux|B*~ z7y&g5$?1{+0J|{|6<3JJHWzvwGJWZIs~b-Oh<{zJu4uR!V;qz&3CPfdZv5$~Y-NZN z;4g@zb3jBRS{)tX+{+L_*slm`fIf`PATH%pno|K$j`lYpBK7?f>4j*TLnxnJC4c#0 zW5gHIaw0_uQJd0~kVDK+1VAA`X@*Rn&mEMo`-#rA?~l?pq!O-Ad&Y4j3{fZBn6*3F zE`N#08G9#I_E1m>eUbUuhfObI6fzXl#(+wkeb{IjHho2oLFjmix7T$NLpKJ{=lT&! znh;^5VRWSn{oH5~voa_TqcKJd!Nu1!8-p4aH9DY=sejEA-&RLgRKOwVGch+D6AVP~ zThKOc8ipvNf&wbsG`3>M_v^=m+X>zkZaRvk1DguB6HlaYPdQV!6kZP#lHaz?X|~PB j0X%g=j4_1p`oHrZf)Z%(N5_a^00000NkvXXu0mjf{E5be delta 853 zcmV-b1FHPj2kZurB!4+jOjJcja7?CfRg7FjsB>3`SVDwVKbmJwXFxBNVoG>TIHqt_ ze^NZViDj{QT&8YSw}N4CNHe~UXF@3$Iw!w>0000CbW%=J0K1{pV)BX>{yONw1|5d@ z0008kNkl!3sc z!*C66w__5vtFP{anc-TLZqx0L#oI8PP7};D5KpBHu*XI9{0NaE zgVuiS54vt3q?8t9&`k)dR@A*A$*#!rLI^sHL`tk}A_N^jz|N!#?c`C3)`kRU=GnNg zF`Pjq)?^q8VY-e5Z&|BmC2&R+z`hesSCSGtM=X})I)D0aFY@@s=2Isl44nIiAcsL~>qg(NXA^2e}$BZ!n<2@`Y9 zOU{uo|9_A+@kE*gQWS%jQF`GkH;PSoClI*=VHt93BmfvrBmdOUZ5;4=-W{HTM2NGFyHN>j5$8r$BgUf}fwIV-M(hib zun2oa=*;2ZMZ8uK)~n~*jYN=m5sa?!ELTDe34a#os*c`&7==)yAW$3t6)>hZ!t1RX zC^;0+F$=MUH^LFa!`R_UDGSLrUKH_Z)S*;{@x2d;EyVu{VMfwEUOM@^j0zw{H@zop zLOkpEO!O4Ah;|v0XB8h|ks_L9R0Hl^oPY??cD=BQ!2*a;`ne0*M$3q#XI`VidEV00 zl}@zK2hm|x!A+e>TO>qPE+cvTbf3a1c_85>+|NqG??J*wk?{?jswbs fkR)Mr`FQ>TS&?KCjwf0<00000NkvXXu0mjf6@!OS diff --git a/TMessagesProj/src/main/assets/emoji/0_183.png b/TMessagesProj/src/main/assets/emoji/0_183.png index 0045a4d7bd3cf3769660fc8b73eb9147110361fa..1088431caa3e94c5fa83ac72dffd4d3971306d59 100644 GIT binary patch delta 875 zcmV-x1C;!O27(8WB!4zgOjJcja7?vxOT~*~)1i6Cjb*-oSJ0bt$c$sJYeBhrPriOs z+pdSun{wg1mDZc7on_^Wh{0*xUTT~Lj~9kOYb8-R0Q5X zI(Mrn;&hz7>~HBL(eh;X(VAFm^La{WY0Bk%76$p2CiTvy!?>>ux6*u?pHFqCf~i$C zjhE8_;dz?I!hcqVzo!}I6#>PX|LSW#PoV22hgZ7uczz2bn1bT#0SgM*46bCvKT(7P z)E85<&oDob?3~+J$d+_ot)l6HIKKj{34v@W1eBKT+%E4{p#wk`TN#TLM58w(FL7OC zcx^yLI}x9O(&{3})If67>%fK5k6^o`INq?*=I@lE&3?#PKpzyAAh5lKx zQ+pj;3fyndK#`k5nu2gzVZ?S}!KUEa41X4u+`92SlI8ev|32;dO ze1M3cFbJtZ2HS;a=6Wxd!pKBI6{}33ewB5gK-5R4zk&(&4@dw+aG*#94^l~~=mPzc zFrfQAk$+T_1YG`*XtyRVi2#P*3dTc{Py~)%Kst0;26=jB;M%YNr-E={it$_G0YE@h zQ4_HNv5r(3ZaV%HkO-)wl%!yDjCaokKvZ!$%3lND6|jsHbZ{!Lly3(S_@Ac|HRwv# zRa)1FdJ52-!lBKtNl>XC?u`ilQsh;7&r~I>Ab+OBy$IpummPmoVQ{Z0!iFZXK3WW^SP(P4B;+a)5(^TmVN=5#*_VXXqVOpw z+QmH1Zz*9TRl$;94{^b7C*}C}!32-VPRXx-&3}4*I;~)%0 z%QJrD|G#(LU~-$TRKrSpM^j}`eXuWvFt0tOwDs*=N_`I1(tlcBhtz(U%43KQQ(I-E zeq74WAz))=n-Oy&2~$sd2!b8u*hH`+@?A&UL{#>G1}iWU>lpwj>|9cFGdTTS+M)_O zBF}-zgu$U1BZOw&9c#L520G*U_xcuT&snP+$ZFS&y6GmA1!nBK>6xSWue#R#^fi%p zP!b^4)f~b3vwy7i+EDp4qo7STRF&z@9Vx9lQEOH4uzDLqTvq|5Gj|mxpScRWT{`7! zC)2?qG%SQK(SoGhdT;ezI9*u_yBUoa76k3XO=sb=lFqcYAlW13oZCakgT)gz+0sEZ z5v1Y|hl}&SB92`IopW;8MjYRhe$j&mqr+-33Z-8e(H-TG#U?vl@DqA>< ziCsh&f_i`$0V1c`2f2KH#|I7GWJu3b^x*<15+GCuLG=UzG6qWx5a)T?ud-Mk=xT^U zgov7iiPbo>eiI%-TR|VYZ5jeISkK z^fbgEcz<`?0wdZcnQ#9thJt}oh|AAg2@m%jA$miW5ucOM1(_Vi_)kRYK-`YVl@1Ur zc?|)`00juB0bzo(Cc5j;8obK~0~E*!VjUj)3Bve!%O9AfgcloUK$9^LqBS^xkp|@P zzRoSY<^4!w?3^54(ZB!!08b)HgXsaWM-beJ&}0pM9C;3KLRtFX((@qHF;fs-yL48S z0lB*Z1eCGDU^LV^0gMKSiOB&V#7adK?^6ey9fTECgQ&Rl0_61CRLZ6Gu0yQ=u**r+ dlo0;E^ar&LH|FcDf!6>4002ovPDHLkV1o9nONjsg diff --git a/TMessagesProj/src/main/assets/emoji/0_184.png b/TMessagesProj/src/main/assets/emoji/0_184.png index 027c5d8d90cfbf53d9b658cac1704147aa998de4..dccd15fc518fa51ce386442dba3954f0e8488f46 100644 GIT binary patch delta 854 zcmV-c1F8Jz1?>iqB!4+jOjJcja7?CfRg7FjsB>3`SVDwVKbmJwXFxBNVoG>TIHqt_ ze^NZLd0eJ$RlA90w}N4CNHe~UXF@3$MC1!l0000CbW%=J0K1{pV)BX>{yONw1|5d@ z0008lNklxk_kY-pPy~818}VZP)qgi;$(K5`Nw#-!?$zDe z+VC3)cHiwf5{{H(M?q7{*;fsBq!Ru8l3gS;S7LWxFCFe3!F?Pyy(VgO@8cyAKnV3A zP9gTyah}x5{zezG3vmV^Y@3c=6uwU=At0<00csg!g*aMS(%I`_^lP;(6MqaNpb&Oj zj$#^zq5Eu>qkrMo+bZhQTunG>cud^Y`&y1WnEIhGOm{sBhGA%#ChgmcSgd7`x-Xh% z-w?qwN$q_`ax|mmUkgqEyX7zyTtVniE=1q7aEaRDUa{Kl-!mQY=Jh1g1))DkOd+ zQb{IK300zpSg(CTaKzVyWN$Z`M&O?W*+s&8Apm|0kAzJ!fA8rI1A-iF0`GG|F*6Y} z7|(DA5rG-*3#LjOZcacA#s~=1Qs*fA`9L7v0Q#SZp3{)7JQ2oVj*lk)F{N(=0KQP!@$TjX0M~$z2*BkMSejb+DpD1on?P?od@>r- zwOZ~3poua15*+Fv0{uu3F%={JwBRrfnm+Fuijb3uQpadC0-lJn$Yywdcax!*E#g*$uCwVRTR_)akBhwpMB#DB0{E#-^%C!px4_x z?kdDs$7iBNkRle!kU~1r1S3UE%V-9TT@)Y-UM>A#%?6hhrrOUaNE=UvzYV4#(gb=F zwoj!5gC8UbA%fl(6E2ScqI5unwK!!w79~5-fGcco5;Eekq@ItLcH7H1t**;RF7+M| g#<`H=-1e{YA3Qr{z$9HKp8x;=07*qoM6N<$g5WNDsQ>@~ delta 720 zcmV;>0x$jT2IvKlB!47OOjJcja7-l`6Er0rI4B`5AQ?R?B|Ix6T17fjJ~l`-E;=eB zC>s^|Ax@M4000YgQchC<9BGq6yxaf(|NV_g`>g-~0%%D@K~#9!wU~=?+%O15s|OO` z|Nq}&85X;mEV$F&B$HXqa&)v|4o`&gFfx+G}XB^zx9>RlWseskR$Q}t)hBw zOFZS(JdEdyyni|qs`rPbtV-{F*vwsmF+|S-+CUtvHn95gP|4l$T>v-{4FMiSv>>Iz z7|_qg&k7_)tph_q>R1r4HO{1kgqa2LW59=<2SX^p5#dFp2y@{=tS=GBJfETnVRQXM z#H6i}EP~C&hKS;9_CDroYmp+HfDj(dQ$z>T5;GGaoqs|_j0m9;1Yfv`(~9Zz6>V@} zo%=Z0;&7c1`3VqGdg?eKICqh#2QChQ$hWj|i0@rU93Zp@M3UdDebo&DImx5XJ^sV@81JDNncI=EApZjUUlAAIpFN)I?-s^MQW!G>Pa6 z)|=Z+IDlK~Z%ZcH7)HoFbaq}0TZJdV+lYNE$VoFukrQHuLR1QHLafqQq_;V#g+sf@ zsyANJONWnRR8KPhe*+j}EWm)~fVZ5|MMcX0vwj2E>o%Lx>P=+;0000*I;~)%0 z%QJrD|G#(LU~-$TRKrSpM^j}`eXuWvFt0tOwDs*=N_`I1(tlcBhtz(U%43KQQ(I-E zeq74WAz))=n-Oy&2~$sd2!b8u*hH`+@?A&UL{#>G1}iWU>lpwj>|9cFGdTTS+M)_O zBF}-zgu$U1BZOw&9c#L520G*U_xcuT&snP+$ZFS&y6GmA1!nBK>6xSWue#R#^fi%p zP!b^4)f~b3vwy7i+EDp4qo7STRF&z@9Vx9lQEOH4uzDLqTvq|5Gj|mxpScRWT{`7! zC)2?qG%SQK(SoGhdT;ezI9*u_yBUoa76k3XO=sb=lFqcYAlW13oZCakgT)gz+0sEZ z5v1Y|hl}&SB92`IopW;8MjYRhe$j&mqr+-33Z-8e(H-TG#U?vl@DqA>< ziCsh&f_i`$0V1c`2f2KH#|I7GWJu3b^x*<15+GCuLG=UzG6qWx5a)T?ud-Mk=xT^U zgov7iiPbo>eiI%-TR|VYZ5jeISkK z^fbgEcz<`?0wdZcnQ#9thJt}oh|AAg2@m%jA$miW5ucOM1(_Vi_)kRYK-`YVl@1Ur zc?|)`00juB0bzo(Cc5j;8obK~0~E*!VjUj)3Bve!%O9AfgcloUK$9^LqBS^xkp|@P zzRoSY<^4!w?3^54(ZB!!08b)HgXsaWM-beJ&}0pM9C;3KLRtFX((@qHF;fs-yL48S z0lB*Z1eCGDU^LV^0gMKSiOB&V#7adK?^6ey9fTECgQ&Rl0_61CRLZ6Gu0yQ=u**r+ dlo0;E^ar&LH|FcDf!6>4002ovPDHLkV1joZOSJ$1 delta 1048 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 Z$sf@cb22`rh714z002ovPDHLkV1hkGiTVHl delta 762 zcmVUYg@Ncm5vz-NVCSW0`6I00MzY zL_t(|UcJ@ZlENSi24KQD(uBVM({9RP(b^Tp&g}1v7vVF>IDer2Ct7QF3y5i#m^*~o zOZ1HjYy4W`-<8Nx(wWxCvsaK)*!>L4AOnA!iH$1wag3 z35M3RwgaFY1_9J)kh4_?C<)N3*?JeFPTT=HlGHmvfZ<5qIg7>5_10S6hrkS*I}yF* zjB@lGYJU|2$PXXYiRg%Yu0qco=S_ED5X%t&Hm!OFLCXN~7-0~WXdU2(Q*ViumkgpZ zM7(@SgjfTHa7q$_)`Y(<4l^Z)_9CED*YPl!M1Ue>|M#^e1kHvJ!F+g`S&R=t>!Ggl zI;Idb=>hcsu9qfj5GbU}ASbsBfs`^JdxnCX7g6W^c zEK=%wf=ej{afc8oWCP@l5|~0xa^DjRg-V$JNytv<`-J)Xgt<#B&N+FDkdSi34Z^sz zH${Dez|u5{yF^IyTS5#Gwh~rrxmyvMI!Y{fBJe?Q{eOx+5!zOQY@4J=eIbQ_&xC6O z2Vr}iw=Ilbq+Fg=(}-Y?XNdqn7!|#?(83XA(_8h=0lxCVA%y*U0n(jmZUMbJB_S6MzVr^z5s(2`eIbf3R`Bb y1ueGYoE}D`UzLg_O0B1JdRWnVsnKToC;0__Lu>f3)AAMo00006(GIvEPU^O6yQZaEsCu%({vO|fJ7TZZEG00&0006bNklZ@JAvIf_fnafo&pw5Cg545h1B+3bQRCjLK@40P&1S5&?TJ%8cj+ z)yibyIw1tdh&cNqm`wq(5oaoom8J1<*@Xk)MfePAtADh#FBnsjzIpa(9{MB>>a`;; z8&OgSYAtwx{JyDfSonZR^l#6m#JAVPB{@OxZ;{nH>B0Le1H?z{#BKo2YQTL0RMg7u z6CjrG`2&u9094Za7}yu4e*%PpT>y0P%w}K*I6zI95wt~^!0GaE$EF~czjGK^0jH3! zkAbpi1AnatAH;kZSoToWD`vx33qFXemEaQSLS7tbbZMLbu@B<14L4>jECq|Q8I~Df zLbYdWnLG@5`2e`KXKQVA#6u0>Dkkhi*b%SyMeIb&iL{LRT4Wor1YtfECLVyVVH?TC nkF=6C-1~1s(w1cP-^eeYIYOr7PWGq(0000|+cEZ~6XcK#*?k7nas=Ln2*Qpe|M-&s`?3H0!vEk@|F#GJ zpauWuYyZ+m|MOY@_JRN2K>zxp|NYee_HF;|MEtB3|JoS;$bUEg!8MRo3I4Miaytb7 zy({a~Jpa@&|K&8?y)*yLHUGCHVk-du$`6D`2F|Z6>X;DlpAn*H4*$t4|NrMDFjh_g z000nlQchCb0 z>%yKrvoBrV|9`pq+gJiJB%Nv1&lgBO{y&{#bMw!nH~*g${CzlyGP3lLEK0sCN+Xir zc26&XptzGVCh28^lJbsn#uy)Kco6tPRZ6Lr=@mm+u>haIkPnE<4mZVP)x!o68{(lT zq*7$|CSxTZDWw&iYC<|dfpf$&cbY7e{8>=X-~mVv@qm$P@!@ULmBL#T4myYeFa}U8 z3SH=}RDY}U>&P&M&>Ceh6%FA46nc+QK8~@`0QIK02x^V?xKWa`*HC+*dm4{BJ$xBWWXEJv~4Gl3*Ya_BE@3t~{B2SE#cpCAUt+;kw8 z!-zqgx^A9lYYdFOpLj=E^)8iL=shsc9TWaq10rs07zD=a&`xc8=@;TE3qlwXP9TDX z823je)W9g0s#oK6YNsm%LxK`da-Q2KB7dX?BE|&(CQ2Ac`lLEs4t-)&=uXG|_?Eac zA%Ymx8B`*13nl^JN<0uL6IuiD04gky;Vi`c4N;_bIZv$tLi4a6f)Hr|f)fyNq!x`L z4+=~cj3oia>9l`KWT~7dhAI7L(7`r=~GrI3nCQ zV!NYByip@o@@(v(o`!ZxZ?2q{z?G)iZux8leiAVhK@Qh)!q+B@WL*xz&k^W{FV9j} zgJ*ef9I8u+Zx|a5q9y1kbP}$ihJVDmpXURN61ECdLgzqYs-cD=PKw&|Fk(tK1;(Hf zGKbztA*0|toS{lr;(Ixb5riRN_By1_!Aw__IK`{Rq;yCWdJpnA> zHntxTTW9zp&KbiNKp9~_RS@Axg-3&C;UbEZE%x64NCg#sV}vlc2rJS42nko|0Tyzd z;-kc3Fakw#=Zp+M2tRq%tY~&QBT&Eql8g(G?^d5btWbmzC_X9e2Ot$b&ju$#3K&2V z*`J5OAHNaf9V>7kW!TO8cL4t8sT=GApi3Z7Q3CL;&&4e)2ejd<%B=?vR z>XIbyj~4BfBH(-t|I#x5$t~-d5af^y*?tDrb_CIH1ImXT|KMK#`lJ8qaR2sz|Km&l zrUv|%2miMR|MXk`_>lko&Hwwh{jV4Q)ky!x5C8XX|HL={wtpatQV9R>LuM}m|JfF% zav1-*D!Gs&|Ni9v%s2nqGXKCZ?AJSaKLq)x6#wNk*|;yBVF=5nB;SSz@}Uy=rzqm( zU|awI01tFhPE!DYrNaH+_8eI`<%Gba%R9j)V*mgJ2}wjjRCr$G(Z`P4FaSl-j3GeP zvt=#n?w;OK{(t|s@>rmVu|09J%_Rg#6nH>NU;cyAJS)p3D$6WS|6zT$EQ)SDxYpf| zqAK&h0oI{A5Xf@)tm6k>N`!N!!9~k1k`dr+{(E9Xq;23LS z1#bigl7Gc;GsS$Z@8(E^{ zswXaE8|@VrW(_f(I7+pc5esahM?wfoKAGucLWc|j5&7;%YKdUSM3*5% zH0Fk@*O@MGMt3rT(3XI31Q9zTT#Ne`2!CfNJMo173m{wzyx<5Y8UWHUu~z#Bf+t}^ zx8D$8jLkfer6)O=o7oZ_5%*sbiaJ<>C_?-R1kN*&6JZUN(YS0_L0;$>f+7H`xO{;~ z91%ET7zQR35f<^m0Ry~CyUlyC$~uE`&9P51GG}7AbN{v{sTZ_fwPpz*D`cO8kdFCpm!S#<2 z#CSr6)|dly5nKs7hdh(YZi9`E1%dFjwX}?F8vrzHJ1EuvSvS*WiuvK43f|H)ED{_W@!9AVOJ72}v5&rGFT1BjWTU zkf!?Bwxb9%M)D?rWS>-zh9C^}v-va?a1m&XPynC68$fK8t-J92*};4+I41y8&=`>) z!zZlS_zAfH!b`E3roep`Xc1Mse*$!qcHfLkKF8}dn8S9{WpV~|4;q~{UYg@Ncm5vz-NVCSW0`6I00MwX zL_t(|UcJ`aa^o-v24JHzkpaK|)2@ugxZb#tTF>;)t@sKwBY$Q2n>gpmdZ-7|2>h8Q&c|?^qFvQ5U=a0(lXmc?8IfC#n%vOGGbGIv`^A~ zmgIdZOQ}pP?0;97>0+q|LB0(Y_QDW79f1rpT`ay6b%{X>8IfssiL*>~k$CI-^rV$6 z*jHf0s0#-N0cqVx`)R~(?gUN|r4xkxJWJ+HLnw1Z?dL_$(?*i%N>C$4`_zC?x6lXy z6^2CmpMW0|_GGb~)(?pYy#UB8HbQmcAra_*;=qXUmVYSGxfH*u#R#xJu3t}LmOCQ) zz|`E3-iZyszSmixMKIGFk@U3YG@=oV0?Z832u((%>AVR_HNb8WBgh620TIj@8-SSk zAQ*bnE}Q^ua1uZ^$zH2M#+D3rnnQ}ExXK35p1Qmf1eo{8#?mbQdOn1pKo^){jqilE zEU2Z|P=7yh0`f{_xe^v?pS#dkj%9TQoWyh*0IPey!>0^u;WEPcPn`$&74Lpx@RUKM zLzLT>#E2oF!d>*?nG?RdIQ)HBL-+ZYVd1pnb>=4N~pvJXE0t26|7ci;rl9ALwsr~=aK^J+89 rBWZmhVz1A3PybYj(H)6p`IGzuS@mXWJy@V_00000NkvXXu0mjfBt&9A delta 605 zcmV-j0;2tq2KEGyB!47OOjJcja7-~G8#pK-JuD?ZEhbz>J3J~RMl&o@JvBlwDMT?V zI42>F1eg8*000VfQchCweFYr;YiX@4j9IT5fE*)J36PYL-V z;RnQUIs<18ON7)mvOxG;+kh5`qmir=d4Wi=Cei9#M09Toj|po9c}iHV{G15deTMy( zS%QxFRC)&_r<7%q@Ci1bUYLV-KBFGutTTjbw}hPwudc|{F0N&cXzjU;392|)BPQ1b z!9kRpL}=}Wmi;jkq4dh>%uxhrnDF;gf(31Xjh& zd`2VCj!Y8X2%Cb7h2%fqIRg0}0ec)!e`=2)$@~0BkI<7)g{qbk|05*D7BTiDieigu zc^UPi*<^1$7K7<@t?LmSL|Ya^j&DJSK)FWG6G_PXz<;<1*#=@Kv~`7UL9`&Hbmj*Aldh_kkY`jD(h; zeWNYMnO58|tcp(r6?h5k-9)%l1Q*~~&&AC}HbY_224r%x3ArMQ^ZFH#dw0 rTc@WH;iRP{aWLSHLKOCpcVEdrAIdIxNHPQi00000NkvXXu0mjfp?wVU diff --git a/TMessagesProj/src/main/assets/emoji/0_191.png b/TMessagesProj/src/main/assets/emoji/0_191.png index 95517caf486e7fb16db8384d3c7a1e097881768a..1440efe6dc4d53d768d262cb0fcd165b6364c624 100644 GIT binary patch delta 653 zcmV;80&@MN2&Dy(B!4GROjJcja7>6(GIvEPU^O6yQZaEsCu%({vO|fJ7TZZEG00&0006bNklZ@JAvIf_fnafo&pw5Cg545h1B+3bQRCjLK@40P&1S5&?TJ%8cj+ z)yibyIw1tdh&cNqm`wq(5oaoom8J1<*@Xk)MfePAtADh#FBnsjzIpa(9{MB>>a`;; z8&OgSYAtwx{JyDfSonZR^l#6m#JAVPB{@OxZ;{nH>B0Le1H?z{#BKo2YQTL0RMg7u z6CjrG`2&u9094Za7}yu4e*%PpT>y0P%w}K*I6zI95wt~^!0GaE$EF~czjGK^0jH3! zkAbpi1AnatAH;kZSoToWD`vx33qFXemEaQSLS7tbbZMLbu@B<14L4>jECq|Q8I~Df zLbYdWnLG@5`2e`KXKQVA#6u0>Dkkhi*b%SyMeIb&iL{LRT4Wor1YtfECLVyVVH?TC nkF=6C-1~1s(w1cP-^eeYIYOr7PWGq(00003&M2@+K~>!bPDOF7S@dm-joW(cnGRo3Cej1 zsaX!%kP7?3FY&M&_qinh(M$i$LjK1&=ARDis1((Q3IEhp$8-z-)?I}_4R|E*E&u=k z4RlgYQvlJRuVLzi{yiY;{>>a8W!nG%19(Y9K~#8Nwba>?>whQ=2HTjoCa@=9=5qqBqi;UXIeZ*mxzd;b|YM>VlK90w0`=!U8%x5QUaz=Rcu$P2zN|MY@dh$bC^ZZ9n{}XHRwPkA~hlORY}kN0x_aZ$V~{gph^9l$OJ>_l$dMY z#mEJ%FMpvl)T2eUWPL$XpYY{%PuB{d6W!rTt)-OaSWj$ieIhs}c4?D>Rc1QZTq*MC z3PmNBaP~{=XA;jYz%z1ADM}I$LcTyaNH*TNhUxhw3L^p)-zB^eNjmeu9H0LUBemA~ zY&)|Ncsv~BtUV^#&4?MxDPipe zX-AX)si&e+j=K?ZopcGx*5!o7wa4RV8dp&aP3kwRcSh_9uoibb{&}TU)D!a*9>)$5 zjLt}-*6WkE`#Ox~l zVHhDH5!!q^$slEXF<3|@*m>0=PRme35P#VWBNSl4ia0NWjW;5K67&|v+j;!mRV2MP zE!l)Bt7x)}^UQZwkQB)#*fxl8_Y7P#svx4g1p(T9zFmwTnjoscyM(5~<%IEQj+Kg> zH*gI8_MQ0g-dM3T1?F)3X2LuU!`(6rV+ZIn9PfPyx4)Zz0TKvxw?=x>vH$=800>D% JPDHLkV1jxx+_(S$ diff --git a/TMessagesProj/src/main/assets/emoji/0_192.png b/TMessagesProj/src/main/assets/emoji/0_192.png index 1ffefe489ad8a3ec8295bd90978feef763769f5d..ef89035895ab5e125402bba346753376bb325d04 100644 GIT binary patch delta 606 zcmV-k0-^nf2loV!B!47OOjJcja7-~G8$vKCMl&otDkMKGCO9Y|JuD?$MmthHHAFEh zI42>iq~Cl1000PdQchC>$IN|-@ z_fiy7d)W=jO!xe0*TQE22i)x|aWSR1CUCBy6@qh1S|}py1b;s#5_ZD7Wg`43L0=@C zL73B-*mGJUsI{R5!ui$)ae+7*(K_K5h;S@hT%C)I;i9ljXe-cDLTlycM3Uh%>}qC- zc+987cYu5do+b$wp!4a7Ik`H=XqVWFMYQxK;X0^SSNPa(E@h7B?YWN$A~;wjCieuw zL6ng|d1o_{x@C^4}l2qoK9jN{Ln>z5<5#96;6alHhKpkDTXz+4sSlYkBcTE)zK zW+l+COcG8Boq~&n;6C3uQgkB%`Z%EdDI+41-{*%$gq(y3M5L7bA3-7akg_LH1T`Y% zWweiOM}6zjC>&2$yB@(o^ldTu{1yxdlxyVtAy9NKF@G+C*MaB{(z`-xkTnP)T>3+N z91*XsMUc%@fZR49G$xST_36A1)NTs|f(}6m+$tdskAXXa8=lN~C}?I0G+`LVtRQh4 zhXiv%p&z#`!CVb&oXocH+xEwR1yrHvGx=aLnn1=o2Fx1RIM4+6wFD{lIq;(aOXx{5 zHu`q#<5y;etMQ4T0WX1D4W>~Vf@=W{(6ul^)evZ;13CyZ$u~rB-oF8K?;rF~EmcaSpWb407*qoM6N<$f@=y5EdT%j delta 880 zcmV-$1CRXo1cwKZB!4+jOjJcja7@~wecYyj=)0HKoOaclb>6Cl?7*GYoOa2EVathP z`PjGi(Xaa5z3|DV=C_mJtA_jF!Mbot_)s5b0000BbW%=J0MV}G`C^UzJRJTKl*Qcu z00Qz!L_t(|UhUW2Zrd;n1>ne*M9KV9_Wln$F|?HyOBJof?tgZGwz+6NA5wOJ-2Ni9 zlzRI~Y8Iru{DjDN3;n<-a(`s|K9SIgy?%cVc0$G^{|T5AHE;Q=o*S+ZW$$GvebHit zs3vryOk33n!uF6@MWsMD}Gcq)+qZZOgS2xIiSJ2O)WU*qTd(w5I@gJ!T90q^$#a7lB-p zATl#TRATezMBSa>(0dayGH&+Qno+xmG$jH$vD?L&?{;zDBC|F>k|{CnK$f%-`>P1- ztTtRB@_9)N#~{>+J2Z53P9(i9d0c%4A?gIpiMr$Y|9{bmJ4L-;1Ur#$(}eL(If-@= zv__2Q9otD@Q#=V+BhpE*UW7J5WJK~o7;&2u1<(lqw2)|QV9{m-Gg7E?Vjs0d?2X!* zDuCEaG8<{HOGm<_pnx9sB_I*85o;|NwfRP`I4pt$WlpF+RGolx;?|PF!bVqqJ!0&M_w8 zH^lzzi)4su>*)wQ378T=2EkTDz+%otFq2Mqv44F!J+vm4uADZ%y+3m&Mhz>{6{H@a zlVFrqW<*l5!b9nZIR-JC$w=_#4sT+F$1JPj2=logTg7yrK+N7_#EmYwU~|l}sh|-f z>;&T}fQC9JlHbbwM-3}NCbV>WlK@u307st7AQ!yEyatdN7vP9jFu_aA6SNzKe5~Ps z327@|?@Cko00002BZj(B!5m&OjJcja7@K>3&M2@+K~>!bPDOF7S@dm-joW(cnGRo3Cej1 zsaX!%kP7#?B=N8t`@t{&%|idtOa8|>=ARDis1((Q3IEhp$8-z-)?I}_4MJaTOaK4? z4RlgYQvlJRuVLzi{yiY;{>>a8W!nG%19(Y9K~#8Nwba>?>whQ=2H~E)Ea@uL`5qqBqi;UXAeZ*mxzR)b|YM>VlK90uzvcwU8%x5P=cmURcu$P2zQK1Y@dh$bC zoHLcfKIT3V79pOAwh%TT$^_GZlw*t;nuELxG2eRGAb%;bgw@O39n{}XHQ+!c5;P(7Rf*620x_aZ$V~{gs7d{t!~{d}l$dMY z#mEJ%FMp{t)T0HpWPJfspYY{%PuEJM6W!rTt)-OaSdVONeIhs}c4?D>Rc1QZTq*MC z3M3_#aP~{=X9CYI#4~b^F-al;QocYqiZ7sJRXj6)*h4WW~7Yel(6<9aE}84009U9D1VA!tJ%U8A`;YgIIbFB`D&~e2swnc zw4=%Y)KgI*r`-s-PPznS>vF*2+T(FFjjJezCia`vJ0tc;Sc^Lz|Gd&F>WO&@k7I`j zMravkJYI^kGOUW}0wMjRMmr?zJSrKHBGsWs+>xSXBniS%!z{qU>*!|Gm8hYy^|Qf@32q2|Vs;h& zV;CU;5!!q^$slEXF<6Ku*m>0=PRme35P#VWBNSl4ia0NWjW;5K67Uwr+j;!mRRp~^ zE!l)Bt7x)}^UQZw5ERKK*fxl8_Y7P#svx4g1p(T9zFmwTnjossyM(5~<%IEQj+Kg> zH*gI8_MQ0g-dM3T1?F)3X2LuU!`(6rV+ZIn9PfPyx4)Zz0WcSJ`LG-5RR91000>D% JPDHLkV1m#J1W*?`12UG~-Iz)djOc@4Bd_}ZL z4a`&Q!^-9m2Y(4mrC16Ixai~d#AHUE?HJ*u5S+K8M00SK5LZN$Bs@U4xsJ>@XIPJN zHjIS@VH_aLv4M7f~fOCmmUqBy%jLa&oFtZ!!n!zdw;>V1;PoiWEg(R!A&EGYpf zbtaH(cYmCGSH|+E22KW2=n-%tHe*?Kqm@DVnrH?j&COXFfnCBWaTrV@0-77rrgTA= zQg17Sq&jlgETKnaC7OXuOdBNBI_&RfxL+a-Bj2)rk1G?z9${rCno=ReqOzF&hPTUm zaum?{=qUR0WLzH<+>8~g0DkHwYbQ^s2C7i{=zn(dwu~x(o%(S`2p^s`2e1iRL_b!` zH~~c~fC@>AxGqDDvw}^4JY6RyA?9;4xE4SK6Q_arBo)zDnPn{jlAnfR69{QH_$1hA zFx~)cmGJ2%iZGm*lOpv2z5~WjpTsMoj6gY`jCIq8i8h#9lE#>6Cl?7*GYoOa2EVathP z`rW9n+AZX9jUz}>dw;j5Dv2-5$LSVi`9@04 zW%*6YuEbmZ4Y5Bg{0k%N+2_2LCPr#fg`?`PCbEP{(-db5sU$nSG z6cd_}r!BS_k<`ase@^U-Uq654)-LwmLes|5p;t{z)wQ=@z2&=X5uXcpz)er?~~UC?3*g= zB`Fai5=3D%e@>Lm2@I__6B5#Df2|qUlSoq{kQ1BT9Pwc{_bnny^&^=Q;|WAfE2Dpk zfX+&#L0muLNZ}ZSIPri=j?RfB=Pi%3&mdHs;5kt?>VMylPCPiu<0R0DeVHbVE435# zB={aN-gl~39fNR7uoJ=I1T#B7pc#HazyIF4bQ1nD{>Y9r1wu~BNYH0KzT z;03Y0`Vt!=Qd=4VF9N1S&_SRTQLvbE5{N9*U4N`^r$^Sr(v)uF<@32WV$`rAO(AYk z?gWz7JR_2@6&^}M%rOYjOeBVjC%jtW9tA-U}6KYy662NL0;K*wk?1Gn=*8n!71CI0xCU}W?f;7XBKWjK( z!fCo(Cr1HgH}FjmsW!%KqahE zAmrsc$%Yss;ss(zW%*`G+CxjUgs@J4Ia5l`x&2=L+x!b$&t0Ug@?nSo0000e(>NC z1S&!43e;Rmu77*=%X{uxeJRR;U+};TC8q(v`I)JzB?)NENI!s8oANv_7F6A~kKopre4fXn7sV4G3B0e~eYG~^F* zV;W(tGpyjH+8K?oun=zGGh#)slM@pH!pJT^5+oeNd{5LF!DrwTJu?u*V8bh;4ULgg78b2p9zN)(Fp>2$mia5*Rh?<3#-sVOg-wn&NqZ>9ID>C?Z>PYujho_Ju$ R@C*O|002ovPDHLkV1f^YXA%Ga diff --git a/TMessagesProj/src/main/assets/emoji/0_195.png b/TMessagesProj/src/main/assets/emoji/0_195.png index 03698d4a80a9507800c1c427c96a2682f801fdd0..7b893d12222a3a974ba35c9634dbef35e69ca0c2 100644 GIT binary patch delta 795 zcmV+$1LXXI2C@c_B!4zgOjJcja7@UJWY?&H!iHV4Zb!$BWy+Ln&zEkzfLO+fU(1tg zxpz(Cy_es&klLqCk7H9`Jsg8wJsCW#nwcy~p>nQ{76cgMaa@(dBz zHuBF2%lLl(+!PV0U-T)#_-(iEKf`#q}9$5UMfMk9A#dEvy6B{L`gyugj?IljB|$c zC}l%fSrEbr!rV8|9+OS2eiWD?mbN~~HdEC&@vTOnqBJH#yB^J^SRteneHPa%ev_XB zH-hYth$|i^8$ox1DvuY$V(uro5zvYLBb*ur+&=)G2!FgH>_Nyu2rz1h8$o$Y_+y?d z?I0u&W)XoxAd+!&^CaOtBCtn<3qqAxrwIYUnyMlakv6i%SpsyT=O8g5$ps;eKuM_+ zJ;W@2ia_MFDTmJnve>yhf&^P)y61tS>?R3@1gs(6^Jrk0B?MBtpDc1R);K15&yuz+ zB><%!34dfe94DR1*#5M@gMl1I1UwMM*tWyyWpKVGx&cYEJ6k7kNVrNggIGjBvm<>< zBclK9^+H&hBX^r5jEJm6H;|aPK*GJl@qUK$5@`r&&+$Fph#`&$E1l>{fe@=oV#XWZ zZ{80_fwC`Q8O0f`_({QH+^`AYmtk`2;mNFIxz_o^=9h7!1(1i@ro!TP|qi0-SW#s8_b@hF(xbUNt}x%Zuz(Q Z3lxp#UHIGwYxDpB002ovPDHLkV1gO#ZCC&R delta 746 zcmVaJZ?WGplLsnTsLJoBZyNn zd`K*2IwER3Bupw9ZekEm0000EbW%=J02ermM#ri;3lbqW7oX@<6bwhDF{{v`s1ESTP5fx`w-UUi+`k?({d%LtN=A%A7u25@Nh=NFQyFQCr_gK!o#6b5An+;TKH;^` zTxu2m4D-(Z7M5j*0K>gG0`X1ek;*hQX_;tEIdP`6}?Zr1PxZ7ADIz4(N2l# zL@or-n-wD}3$xjeo*SM9k7(0>CxR5y+%rjS_Z^ zA>l{d31+a2l>iZ8W{L;F-sllPQigN5h}ZZ=bef3T6aheT*K2q)fH)+4X1)vIBTp9A z6m{Wii!k*dX`YQTOR$Le=c&$NK=deil))_byE2_3RNF%>Bzz1tJn}RKP?;rO3_c8? zIz_mlxqo+vV2(&zC(J;y?}*4w_zM^i^wd0{eb>5ljK}4SsJ^lfq6#XbKL>GsKFcei zLBKuq{82@ZRVNG?LDXNi9dE%2_vYUn@5ib*=@XrJM}{ELV}KFhRIokH%J?*fH?j+& zdjy+&Fkm;Z3pPYN2D~C&P(X#C2|HbH20ROOiDQ%ZRZxvX=`9Rl%gaQX@IZzECa^|C zg=u3TU{w-zz>1jK#Sruw_)UmA71of&0PA5kt%?YHWCu!GzD#a))5s>Ge`-_Um!y#$7qM+tZm_&!nKpS7TCqUW6JM=k0iWg%U(h={(x>vQ_8 z7Kz|u{}sGJWQ5oIuiqoQ1*WeF>j<|Ng82mzx2TLpKzWbl1ZJ|L2x5BwJa zM#L?u&vT>Z2Y6`V4bvkS#<-Hs1P&rA5I^t0P5=)A>3<%PP6Qyc-Cjg80su=)SZG|x zjY-2+N3Gzc+8Lejun@z*d&Gj^D<@q6f@YJC1PPUxu8BG!j2SR(rznC*^_pPxp>gxA zeMX2_oX7#;h7#Jtm3Ab`1h{Q4!W? zoBPB}dtWW0VN&EsLe(LCL7WOHN))S}k_dF4HB2x0=y{ePNBe6As!3L^VX2}p8ff# RDGUGr002ovPDHLkV1in7YWV;F delta 644 zcmV-~0(MdmG{a1+T!K2~)A00JCIL_t(|+Qrw6PQx$^1mHUV zIp_VK7qZNC3nlS70Ve?it>3Or+KTOk1Q+u5PI9WXM)wX8>whC}7@>~D`$WPZO1@9j zXTrOqsBr&E;ID{~VsZ<@Psiy>e@|Mpm=VFt{=3~G@nrvHQ;RhFoNR0{nRzbK!bGGA zF>m1*gNV0V1kZ9Y-fgj!C&A%@@TT1v8G}e)wrorxd$thiG>q(A=!@wAz$ecT!Zy!w zsE=7#CV4R<^nZLy&INd2`v{0kgiihN;dMj^INLoT$txw;MCktXBt%o<`EyCgkA*T!j~;xwt8M2Oou&a0snMDSs=7({$V zRL})o8z)2n9mLx3PXy-*+F_j#iAZnY187AATU?|Orjh1T-d;>dvG^YP{3@{ncan1m e&V`V--^~XJd^{)kBZCeA0000aJZ?WGplLsnTsLJoBZyNn zd`K*2IwER3Bupw9ZekEm0000EbW%=J02ermM#ri;3lbqW7oX@<6bwhDF{{v`s1ESTP5fx`w-UUi+`k?({d%LtN=A%A7u25@Nh=NFQyFQCr_gK!o#6b5An+;TKH;^` zTxu2m4D-(Z7M5j*0K>gG0`X1ek;*hQX_;tEIdP`6}?Zr1PxZ7ADIz4(N2l# zL@or-n-wD}3$xjeo*SM9k7(0>CxR5y+%rjS_Z^ zA>l{d31+a2l>iZ8W{L;F-sllPQigN5h}ZZ=bef3T6aheT*K2q)fH)+4X1)vIBTp9A z6m{Wii!k*dX`YQTOR$Le=c&$NK=deil))_byE2_3RNF%>Bzz1tJn}RKP?;rO3_c8? zIz_mlxqo+vV2(&zC(J;y?}*4w_zM^i^wd0{eb>5ljK}4SsJ^lfq6#XbKL>GsKFcei zLBKuq{82@ZRVNG?LDXNi9dE%2_vYUn@5ib*=@XrJM}{ELV}KFhRIokH%J?*fH?j+& zdjy+&Fkm;Z3pPYN2D~C&P(X#C2|HbH20ROOiDQ%ZRZxvX=`9Rl%gaQX@IZzECa^|C zg=u3TU{w-zz>1jK#Sruw_)UmA71of&0PA5kt%?YHWCu!GzD#a))5s>Ge`-_Um!y1TXu72IL8lB!6j8OjJcja7@5$460iUt6B`XZ423q3%_v<Ts2HnR4(Fm0&43K-s~)FS4&$5@wPFp$cMAX2TmQ;E|IbDJ#y0=dRsYgX`oJvo zv>)oE5%8@S_qrzk)?uVn4*%C@HhLzP0000LbW%=J0R3fzEPwq+{uTZ1VA-dm-@eU; z;lXU>%>DoX1Qkg{K~#8NrIu@RvN{xn8%Rh%QBZTg!TbMzKy7p9oE7w2X&85ZKX7lU5zxk2qL9{hMSw?$1YM_4Mx_SMIbQ5e*4RKz}H9XDFB3*jkeqT*T8Zg7avm%5Z>~T~%p1>&T2kWGTM;fK8Ip|9|}7M7ag5Z6giYV8LdbNE+iW=HJIMh95tc=LP4Q~BIAy#G(8xB zsyMJQ?d|iL1`k!SQiBf@eY1mc^PbK#O$^AW8+IV@*?)U7&p{YSsopm#RqK5_6D1*~ z+U~o2Y679OQ9w%hFY1a9hXy}9_mm>!k_|3?Ruk4-hE5vU4VRLCcBO6VFQd7M9>4u} zIIeO9VX~w;UU04~fw~H?p;fqS6E2-hiC;7s(G7IZxl(=>LI6 zS?j2e!Wg;P8tiDLky0cnCBy>B#Zfkf5S3J$2|Z93V|2kM1!vQ3wLpv%%6jT-^sj8- z27ffSmYi>ORfDRUF|0nQtHKk zpSWiqQ#afxDa%Gm8N*s#2LX07g-jkFC&1f8wpnB z#1;zY#;)0Dye#p`Z*j7EZe3mj)5C{wEA7P|Hn{p0XOG&Dhqs7xF2fP8ZE-mj8(;r` zfqw^)3$r9cd9s42yec+K*L?Yf+R~{H6Iw=kW-G~{w%E|>x%cob*oO-a(nf-beyul2 z6xqfEkvtK6yw3~26NDpZbt9dfGE`JO^4zktrFF2@3+^c)i0zV(`K!H(&u6T@WUx zqOCV}IEC;_EE!@X$Rs7gk_yypK1VWxFT?N<&oY~F6k!x1FbrSjVNo%mR1Bnl^M8~G zt}LzZ5M4}o=&Mcj6c`CoGC1++nGm6`@HT>tz<^*%B|%RF6~V;#_IYy!#xfYvm<&n) zAXpbDs@}g=QD$UFrlcKN01*f+#PL=Y^1xUiMXC@yLAkHqGblj72}l)L8xw#M)U%(x zysrcxi4qehf?Ni)3*kLuL;wLwa7kGqod>|UmCEny2N6Q4&noAyef7J?Gp@%gYFm=j uA~g2Rj>k8{Ro#!EzOFF)*ewRyJn$dGJEBi`r!J31*NQa&|1DkMHFCP*|c zJu4+E9TtFm?_2-?01R|ePE!CaMH6uUqW{U}|NfAg>lgq40v$<2K~#9!#n+8a!!Qg4 z;O6%dJMaIzkY%o0D2dkzI0+bN{dRTIR%|cCc^9^K5@Jdz`+s+coE~|@aA_ppCn5$> z!hIq=MqhAnpI!<5ud*Y(SjBr)<-|ZHWCi^d#TEyAs1Y?WI%tMhD zCL&IVc?(Y%M84g^Rg#PGZi}rv333-iHSNw!7)1QCWpi|)l7)z;VFd48U(5;sHCBQU zwt0?2YYxH^%YTa*q32sdD8K{TN5E_%bn1r>Pa{IW+wKWbUMWE)LicB7A(|4;pG!iH zls-EFw%xTVz7otr=oK_g*^gWh>v<+2(sv?n#$k{g$iR4EB>b5Gh?%K}r4CB4%@Z`j zLdXUOs+kza^k3yq7<;}tBf-o_8dX4kP7wCZ*v`b>Zht{|C0gTj6{2V)z^&nt1et~| ziH#s`OrHUve?J=0N{G>OHmWld+*;!i!oi@pToJ9YhmSRo%>*&40X1kzTpM&C%Hkfb z2IMN?P8{q!BjlN=h%he@_;yV^oFl<;{aDpNqa}FxSiQ)ZSnP1VHcktbw^>3J;u--+ z&SN$VOn+K*LC(W`CW>Hm80)cER$KzW5Z3<|MgGyCF7y)18dnA&Lf+Q#RSm5mLUo(P zV5T#of-dOVI3WV)Al62GA~;vj4(qtg%z6VKKr15H;xmsBkF*-Y_F`PjrS|aWSIHf? jlMtNq-np>-Zax6_`Ytt4L^weJ0000IRA z#D7@PlWfL;THvgP4uZifnlij3!|LfEf z_za~0000woQchC$5nHi1vz4g!woE9NBO&A5E!fk|%`q`Xr8d7zU|bWrSm)%#dW4;u6Y{ zs;H9&)5#p1wSQEV?*mn0_+W91=KyL`f_%~xuA7U$Z*c-z19%t z=$-RE_ktB{?G9}&-i1pmgc7%dPv1anbrM3{9$t;EZv92wamPf_AjC3*AkOQ}4n2GRlE0q^ zq94&nsI9#)P+`-?sM)Oz^W&x&OV*rNyD;3QjejOBz3uXUarT{ofCwg#eBKydVvHL$ zSd%n4ct+5R5L=PV@MGig9|!}H>q4KZkjw_6O<}PC&EsEmAjHb>x{P8Y86_@73GG9O zIT8XHEa%X~w6#Bs4qJ6qQ__T32|hrPn=@mC=$2jiecu;E@O~x4WQMOTOqzw}@oUJN0CyG4{?=M2v}EIt^*V!}-v{odRI zVi07pjZYO4e-TNl=Lj(+h`+r|a>(J;On>k}1J&cXl%z5;1D{onar^aP^)$kH)K$!_ zm;gz>xM56{5o!ik2zy`?MXG&-7%GEGd6xz9z$VP_`gXQ3xT8p9fB-~56aDMUyJQA$ z4W=-F2+4Hn>kUTA09sc_;1jk2DuGPARx8T_S;c^2Bl diff --git a/TMessagesProj/src/main/assets/emoji/0_199.png b/TMessagesProj/src/main/assets/emoji/0_199.png index caf4870b6af8aab97d4d8d5558da0818b00e0ce9..1f0b7e6358fe5a36134f33cf56a886611e6a1920 100644 GIT binary patch delta 1233 zcmV;?1TOpQ2jvNnB!6j8OjJcja7@5$460iUt6B`XZ423q3%_v<Ts2HnR4(Fm0&43K-s~)FS4&$5@wPFp$cMAX2TmQ;E|IbDJ#y0=dRsYgX`oJvo zv>)oE5%8@S_qrzk)?uVn4*%C@HhLzP0000LbW%=J0R3fzEPwq+{uTZ1VA-dm-@eU; z;lXU>%>DoX1Qtm|K~#8NrIzV(t1t|OYw!XjG^_Uw`u-1jB}0;%mXem9&h$qzd^wVi zu-|^9rg{6D==u20|3u)OvpVnoKxp=E7_8~&cErxh;bYKwzr7!ox5LMWG~s5m7=PI~Cgq@|cH62{ZH(>6jE0t4 z%*F=Q3`%LUf|kl(%$4qToZdY5LJ$(rhEzYBNyE>_PCMNl&wTpeB3jIsv(n{AU;a8g zZps8O**d=&Yi}_-!(YZ9d~b(z)YYLK&!A{C+Oj020S3zA9p7* zj?tiv7k}w$_OclG3K4*4Jus|Y4>|Yp;b8#XAtvK{!yE0KT0K)}=ioUhCH}Y0K7h`6 zA4JT`IlUTH)#w7@t$hMw``!?nKBrhZIpMczj#kAx(!Ay zaSt(L8fFT1*=enFTAJ%opzA&=0k;rcr`a0(tN42Cv7Uri$a3bX-}6- zVq<_xo(M6|`yyw83XCkCNQYotvEi_xk6a`qpo=@fM|N61wUXCzUdnemX9Cjc4I;F* zH-ZVGtrihg%##fWvD#Nn!}~+>2q=iDkbkmhNnDz5E+oM#J2SNJSPb4wQa6NkN|_wn z{@X(FDm)Dz1VU$Fbc@z)= zfZ#(C1nXEACxuZUg@R|~1js;Wp^lfTNCd_Vxyej~$Vkc6YlZ*_Izdd4_Zb0#k^X1* zPJUqkK}tqW289A>e@H;ai2x)f#7dwN8UVm)t(9MoAHtXrv1oe!(pSH`Jk$DgA#KZ0 vEg`3#Z@7Fnw5t0PsIM#9ylqwkT6Oym!#ko+%F`W#00000NkvXXu0mjf?uJL# delta 981 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_20.png b/TMessagesProj/src/main/assets/emoji/0_20.png index c0ecdcd8a94a93c8a1524492d185a98dd51fe149..4e740e4a85e599e6522c540351633de126125812 100644 GIT binary patch delta 1555 zcmV+u2JHEl45SQ@B!9Y4OjJcja7@Z_7R_=H$7>Api3Z7Q3CL;&&4e)2ejd<%B=?vR z>XIbyj~4BfBH(-t|I#x5$t~-d5af^y*?tDrb_CIH1ImXT|Km&l`lJ8&kpJp%|Mr0Y z;9mcx2K<)?|F;MK^jrV?w*URj{jV4Q)ky!x5C8XX|HL={wtpatQV9R>LuM}m|JfF% zav1-*D!Gs&|Ni9v%s2nqGXKCZ?AJSaKLq)x6#wNk*|;yBVF>uADBp$%%cdmqp%Psv zT%!O001tFhPE!DYrNaH+_8eI`<%Gba%R9j)V*mgJ3Q0skRCr$G(btaKFc3h|tRX;! zvR~Pon!C5Rlz;#Ktqg}7T8izBlh+(UfIwp|NczivATJ9-=75l*%>QA&m{(Q1>d~tG zTGgcds{qWmw(oZdblR7ihe!p&=63*L3bY=_=q?S8@c)P7Jn)zJg_Fg&Y0L)Yv%dq1?5rW zn+aG58ukE<`ck9FpddU-l{AkSJPI3^3z9|t92P07&HU_5hEoW};fegH!#s<^@7N%x zg}gSp7aUfAR~T`j09MnUI!dw zr9uH334e!Dh`~o9B0S2;ztJfrf&s}vPQXHh1*IOfSxgd(u!%r8c!tY_gZZFq&14%z zX7sXC$OS`qr*IW07ZV30#s4jfu%NCnF{$gqYqs` z14nPSVEyEh4X(UDIT|QTz)5Z<=XktNiOt*gd4Iir-o9^O*5Ug-uI#bUVPSa~U+63| zKYOpY-L!!q48XOGZE}-cpWv#f5=dYo8~L#K1n>V^{bzQ!ONxrxT=Y+b&^Y^LW{fPc z?~V;2Er_;M6H2f_jg%nVGS=DZzOTDZN+HOY%1K9! z=K(nnwt`7O7~urMx5NU1+R%o;KfCn(4F_%@khbK?NRjh(q0$0CY9^Na?SbG)*l4R8 z1Q>le4rH~1t&HWUiJFM}9|=J{XoDz1Tm=H>nMjDxhLAKa8(Oe0RE8i3z$#8x5RoA~ zLv&rogdjpAE+{a-yVTpfr;A;umn{kQNrp6rLma@7l&<@oSmz+P4WyB>0q|KNkADHt z;QA57iB^$jfqnEwdJ-~@5=5hsmVW`*Xy9m@NS4euL>y+RX#>WwfgxNP`6x6;c_cy4 zk$V6*0Zn4tfWZ;u9E8|R)h4OIawM*IwQeHKa6?SI!nRR^(1>LYV^!h_wwalxi#&#& zgSKgxk=Zt2;NkPh*lzm^kUMlM=zk`boL1o`Nu6ODaXD-+c<4dbf@vbninSxWg4?jh z6Vg>mZJ;}Wn{ac`J<0Vp*r-{s5Ps&0mNCyA03*;Q3Qq&B4QJrKxB$Qu$&3Kd0*}E> zJhcJi8Nm(N%)8Zno(ZtRlG`R+8@y582aHGLqSUmkb|7W|R>%t7gi9P0nSV9RMy%8H zK+1eK&wDG-7}44S?z53U8Wv%w8P$i%fg6Fx@GaotIRl7pWv)*=zuc&g33UQ61&tB7 zFis**he+=E`k3&SAH0NRvgwV6*0 za0@R47``*0n9Tfqp(NY_Zhxl}o(^5&7{e zfQN|;LX1tC@cAsaL%hy9AOs2+8=R*RiqLZ{yhhLo6fh=uo99JDz+dOh3nDN@u7h_` z=&$2{{<`h?K^R6+6o!HCedQ}RJMkM5$2k7Q;N<_wPeCY&iKY@|Zwvqc002ovPDHLk FV1iqj@7MqU delta 1541 zcmV+g2KxD=43`X$B!8<=OjJcja7@N+4#;T+$7>1Gdlt@m8}5Vz#D6jHpcck@CCF|K z<%t;RgADGRAM~9T|DhoNt0mop2;+|o|Ck`wcm@B&F3oKP|M-&s^Kku_1OKfC|NO%J z;bQ*POU$i3zmF&X`?3G`S^xKefky}b{nY=%IsdU5|N5f&(|;o3%ufHs4FAqGaykT} zY!v_OL}M!fkyQ!omkhq$K&OfNrJBzZPYuR9!2TGk$Uwxusu`#3Yq2&-40YL9I$yAR&KTC)r6D zP95?!-c0RYo$G#-au?kqSLh4|c_R0gpnpGL;L5X>s2PSq1dVSSgdBUO z@;p~d4Q!qqUsPw{c#Q8DOqb876^PGt`nJOv_T5DO3m5)Od;A>qnjsQW?iphp3pC3( zzOu~;-%+Zid}dXf;BYPB`?A3nOs2{ zpij40C4XE)$i4OsNbbPVz~L}bY?AOAt#;u1V6!Z<0}qmVD!UHH8?F)#(RhW)E{C(@ zkZHc4u+>z)WP?{U!5Bn{))=FWZ#-001&`$g9@6eN%w^Q842{OT2|?E9csC$J!x7U0 zYlmWiwo^4bVwz(EMYB3eggso9u<^Gjep&ogeg zGk@0_M7fVkAw*r@B}5z(DUvfYMxeGJ;$m#xhNU&u)}FzA5WEuuLkiT4gTa~{MR$9m<0=&?|8353ttil1`r+yOeE8|)?r6$MlRFVkB zFqG-u6T6HAjROFg!x1BqhdY&Q;cFbiQgB0j5=_Dx5+x--`25p6I(!}G^%VpRAc&hI zS-<$St1%JaO4#c)68sWsy3anhh<^}3CMlt@6mb&Ppdo?*0fQFh?^3Ph&brZJ-ukOXrF{?Jyy@7I3pk?I(PiG?#ja?%Rqr+Y+t-SXm1D-6-VKK zRf!(|B)eC{u5gAF@sXeJ0W<~$SOMz*p@8s(Aw^cD=^ssQ z6aiNFN}z#RDjGzB((*KUfPTU{#p`TR7(_&&Bgt9716BIXTg^7pf`@|t+VoC=jzx|H5$+WJ(5MnAs>+JV{cvh1v1tXG1(k$8T{^W%_ rDT*vBisVmTxL1hz|NqVK-|2q=cFcV33zB$z00000NkvXXu0mjf;{fG% diff --git a/TMessagesProj/src/main/assets/emoji/0_200.png b/TMessagesProj/src/main/assets/emoji/0_200.png index 73c766af4b3370bfb94e38728c5f3b239fb0c81c..0d6cb8a2eff6e273f2c66baf7f8fcfa5152db9be 100644 GIT binary patch delta 1108 zcmV-a1gra?2IRA z#D7@PlWfL;THvgP4uZifnlij3!|LfEf z_za~0000woQchCulkyqQ5l=IbqWUw@QbuD9k-ga))W(EfqY-L+ng zyU6p17WKNW7O&lTgx4#5JS^uCVAzK7@$8m%O|Xp67BApd zlQ;ToltH9GQABj5DsZAIawa2+qZAt_qL7gkN>$2^hBJLWhLHL`c&@Crr)MEPIk^el;DRE&fF@M~9HR+n=j@DSbFHLRJq{@cs zH@aN5%MJK=XBmHAWUj2@x-!GZ<(ROPQ@P1lptpz=R9DDJEL@KXc72uRKWSlsQP5fWZp;zDtQ3xy>cZOFt`CS{V zS*Yl2LGXhSdr21fXXEt;It9Meg&|oks2xNbT(tqs>o@2au`w*BsoSY)^0g?geTf)7 zBaE&xhD^+R=R={}tE-#?GGZfG2TAPCj0wD{r}FmP7fi5rBlw`kuRYBXYZB{j#fKcG zfPd&S!kBLYB(-II-8EAf#`0ll<|{d1Z3sgMjA`tCxR3zZsO@L)atT0-`Oh(8Gl5af zKfc4kGb2N6Uda#k@J+}$0&nKNc<*iP!92VQgaPIek;a2}ctlryWJpydY&nLbxd+T( zNVQF$EFyj*f{+K}cMjmcdzod3LysyBhkwBJ_*qhL84IIQDvANe_1LNs0qdw^%%chc zg81czF=vM38f=gnshCJY9wWLjGq{vbyTBfb2{rzHJFAS+Q7ksV049)$;rGkCC=905 zrl6;LUTzqbxSstVM=sMHc&Amx`tz+Yf`IoSYJFT zTskLaK`ozZP<>H5WI!yPX-}SMPp^Dj#+h@!j%dS_ZL@q{$(?x1pnXXi5fcCa026dl zPE!E>EKmLX68`@FasHsB*U@#+%^3Ba$p8QYaY;l$RCr#cmVfDDf-n$-oBJRFl8g6$ z((Wdqh)t>D{P%Nab`ZZ_l9XSciQeuv_7Q=py!teM;$g|_nuDRAnON7T?$`UU1(8F# zU3ZZXvHD=HRw|i}$haP59tWZP`azUi(!-#GM<4#uRj5&k48l}KR2OV8ostm)Q8CwX z%**RLjg{ohc_!Xas~;|4xIl`L+bVR)6KN%$VJBQj+-mf0DT*eo&4I z-Xc`MT~o0U)BT(f*Jq*kg-rsdfj0hGmt5A4GC0wI5USV+=B!Yv*1mi|h(?BoB=Q82 za`j#VW;G zg*CE~kbluxYn`*q@di0s0rd-IOZ0JJ5<#0RF{(b~`*A`EM0dwOxdF-}!*^{k-L~z2<&<_HDfmMprZX?O z*;vD`oK6r^Tg^DTjEG(mn|!me$fqbIwVCZ@Xn)>8%sR9-5`BVmEOc{$1fTdQd&5+| zTPPjPjzD=IG;zIc@>Ff)<6S9UwITpg35g5VedVN3ZTN>mr9}@F(G-KyWa_{9jEZ?< z&}|bssQ@`DVnq)TP1r8N>di*>aj{e~2M)kOHPKuEK^Z>LE`p9}vjKUP=4b$PK==qI zOny4eN7l;V|d8F1GX|FBKRcxfVP0T!dhIF-w7TOHOEO5^szxe z05~8*ILQH$4l9h?(~zI#{do=)69yP<%)cQ(IM0Eyq%!J|+H-X@q06q$qHtg|2x6XN zD8mK)I%iCc(YA0Tpb30F&P5vo_fYS#0e=d?@bet4Qe-p;V2WY^06`PT@d87eR3MGg zcB)b#*cbnKH;4*F3JeqgCjv(Cir7Q|f|RDz07N(-yvPs$L5fKz0|vl>nC#cfl5PM9 z=enqU-ZA<0j;Nc25TxkB=c^=T)=ePiEPVc|B+T{{H>` zyp!Cwk9j_`%>V!cOi4sRRCr#cmhGCWAPj^HLO`j85AXk4Pk$1Tx?PU8?(}bcpP6Jp zA0Nq>$KPa^dDed-Xv}Lu^#_7^uIrj3*uR-rbHeBSd8nAh1}^szcub7Q?7UUiiL=N9HHb)kb?7#g#se@(PLpmzB5tn0rx1GqddQk zVg^E>t2XXMQGXtQqlgWOqP}Mg4$$#Lx2@p!Q675o0PZzWit@dJ1Kvs$M#5V?pB%Wh zm2%659UMr(n33)s73H1Vx01OV_ZTu!Vtlh#tChB`mUTQ5S4V4B#D#g ztCvOxQlcY-N1n#TWp3lzSBi3AB}zGcr&y#xWD@(&6#T%5hz__L>9iW=$#IJ)MzP(} z5F{c18HuL@RSsDI4oKJ_B4QK7LHz$ftu=f<_+bi4g%EUb1mRdmE6D0MRL>=qSsP=` z@#4dSk$)`9A@v)ow`G*s{@@N|L`s=kOHwM>ZRlKT;GY{aVc?Mz^1^_Pl1tad6gRs$ zz7@x+$=AV36minEp<%c2E2mLhOhPml{d$>Zqx{NATLM8y3K=T&F0X*8GYz48tTmG; z;sU(wwW{O|f%aG5V%cXQgoJJ|onpC|>Oj@|n}4;Iy(*;$e(H78W3^F!B(W244neGy zfX;U-K47!49Jax|*b$Ww9hvB9f@*`WDN{Qk03oDCU=yl~P|$3o@>Is?@Pt_PLhxzr z4pYX4yA6V%bASyXE-HZ#K0Nw*o$dPHrgAjVhS{HnFxJW_rCAU{Lr9Lk>;Q5WUZ+}= zj(>!5lB4!e7Mg7nH>eenvTwdvgh@*%yD6-F(TXa{Tr&T%Cz42(yL^sEv_`_b1~W5gng zCGLb~;*tT#l!FKgOqh%SuCp)%a8ul0)lLK$gZcQ2*L&w+!w?E8U{H^bWx~i12f}gN z^Ff=(H?mnu0Z5||-;Ux6fZ1T#Z$@#Yz#N4jeqKi_02bx`a`*y$ zDri$7xU=U?ZGQ{~-?9;dGOSX$cU9aJMRYfAF-qT2mXGEdQ%W)aR$41{8}eouIk^p4 z7&n)WH7&i2&Un2VF}ZC+-c5p=iyCDl5kYV-VryxWgwdy;Sc)d$o@BcwupK->w$y5^ zFc6Tg|1=g7VTAfusEq3+kGQYJsFzKLf|uJB#~0rM%zvc_A`vKq5z(DC38)KH=6kM$QJwt1&=_<7K9tbBbKbk;i$Uh$Aa$*6q>Y7r$~orwax5T->kUn4 ziMRN~4V`h0!vw3jZai9ho>=xBGE-z1S=(qhMv3m!kZY$nBC@oR;IKjGoY__Fbq)iI z^~#5h9e@AH*$i>4oyg9xO5$nJhSAGY8=^NpED#QkHqJ?0uR;;yCrl;e)k^?*S!fP` zJY0y15lUO_W+9YClGuRIg2?cIRO)iY13hf`X&S)@7Q{Rtl<>1s17bP8bj6T66_J|>8se=-3zUOq>Z@qoM22lJRoAf0oZxuaF>YOlwpv^**S*p)iom=4CYe|C3M8=*O@W!8N+-KG{?14 z1#F-LG6|IcMMwHBW1=8F2=2|7w?YUfkpfC>@4Y)yP>2diWq?wBe*48+J47)mPzN=9 z@B+`i)?ySrt>=CE?C~63sEWCF-jriF!B!5d#OjJcja7>6;LUTzqbxSstVM=sMHc&Amx`tz+Yf`IoSYJFT zTskLaK`ozZP<>H5WI!yPX-}SMPp^DjvwU90nRCC6Xv36k$(?x1pncVdHdFur026dl zPE!E>EKmLX68`@FasHsB*U@#+%^3Ba$p8QYa7jc#RCr#cmVfD*vPukur}qT}CFySN z|4L6n^mCa$IAZ2fk(5lm<+!ucByOIz1glK#%by4G+x-bdaL zt-$HH3t+^GB^|BQn^>7~Jj!_*T)_2iR17zL?qZG}y+Qb@^rOsF9OM2p5RKN%jiWVeJbGLn1S_ShGeo;pFS zp?lX$6~p*^F+WaxN~YYMv;t9g5J3>Fyi}$0WD`*y8Q8U9;&t2jE2qzcf`U(tq|Us& z*dUc(IY+0GwAy%fjS;;h8Bh?o_?IXOWM&U#M1R{soMXAR0r~}QxzL*nCLq|!_l6m; zTd1DW9l=5@QH{NAS`ZuU`L3F;DhPrI0jx9KPYx8Zfe(fH%pL@BRV^W^x&P%$p|%@C z-!>5;6wXmmOdwV^k-LZ-Z#Ej%C2Ma+au5nh=DCRoA=z1X5qbi)Aq))BvH_7Ggg_=z zw|`7I-ks5Em4`bfAaa>~%^c;%K+1myU=vkF*ts)`hXu$Ar8p7Z3CIY^u@i-T+#np)r*NJyV{9ji6Icy`Who7 z>-5h)W4CN(XT$^o5z2L^ z0X9PZ<3DeKFohM!zy`3&$td2+%!(izMFdxXa$}FsXE=f|B>^ju0dnBxmlXT^7zko* z6v^|W@jstPkF#@5i9UZ`^(eu?9)<5mNe3JEq9jDP7sccW0W`{kId2T>3d5Z_cK{ki8TV{>LA(a6+`Coc z9z|_fK`-|fD}S;uF7?&N7=5skYEwjC79;pXvSiMb{1{Vg1#J)pzg#_$rdE~gl#)=B zs0~Pq*!|-s@e+T$AS$bk%x*#0&MKurT&=4lwrNZx5D)~ajYUCy7Q`H)HyigPVTmX` zK{*&<24F=%{1il&d8t8+k-4e;bc?5@2zK!iq7(rBV1L8QG)9N$D5XS{B4LLZrCXu7 z0g~_(L-4__;lznj{EX1|J@SXEP8hQ|GaD}Vw;VebsD(dJiniEK5L|lY)1Pw^G9MVF zOl?FMHvZ%csUjc3%*QJX8(aRf099*^e3M@?%nC|u)i}{l)zCX0{4`0KCrQ04Wv^u; zFuE{9aDSc_G&tzft^jQ-AWfh3+->B;3f_$zWq1%1I2~~}5G9jYNT38|41$<&^Igkq zWC~*@fO!XGBQVxDMI=S^lDiZ_q&))<6N3PV7WLG-HwHsbU@^qTK+wON7UvfupVV{Y z9TETE!;Nu(lpbSK6Vsuv{@EalP6WMXIp&JU>VLx^{Uv(O@o6JDJYmX2iyR`4pgtO; zyi>M!6SO`i+D)Zj`Z5!Mi+!0oBiridN}ykzcsoNW#u)@Y-yieNc80Z60fSJ}SEn-; z9Y!k;g66o&C8q#z6ihhso<@co~5HGy87W$kW_*VI>k5|y8iDu3snXBGY8(<4G6*@T}k z^0IB45XT1+EIR{vx!(^*VjBLDg)(lpBPYOZdlJQkP#L!eQ9MJfKq9xN5`nqA7(mI{OiA#iVEYtx1jB%glbj;O2}$jdbW+sQLzNo%bY z8UoVwPh(OdNKp48Wn3?Lq-|bE`m*Uz=yJPa`{G-Gv41H-#0<(nf^-#xuoaPNk0MH8 zLb_~d0zL|~%zJDJlA8R#p)uy;`%uE_o%7x$Ukox1hxn+uMp{tNr<`LRUycccXuhF| zEb$Ug+;A{{$3ceKTo*J~JWnk912R%%r_420GF>5eW=FUFiX$RZjRakTf9K4uYG21N zFj=qMHGekp{}>vgubs$-FiYZj(hZ}RQ#WKUf-pfi=-v38!~qj3qCJ9KLZ00O2&WCr z0SKFgXdyvaXS-RLWRfJVz+^$BIS`jRUGcy#4L?jH7(p$X13?M%zZNh`|JFq_Xn+<( zA*d2=ig3`AY>11?Ie7!9M7Kbbh*Lxi+%&Z3pnn2Lql6(?n>p8b?V$SFX#5k z7dPg?=H{Lg{qjF=glN0x2_?qtJjP0-O4#%+y4Q(096K|o<5ZT0000< KMNUMnLSTZ}bBQAW delta 867 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 delta 666 zcmV;L0%iTJ39p5won+pme!o_5TUXV|ELvv5a3D{3hK000bhQchC=NWiWrG zZ{NOs3vnE{cn1g}!Z>)$Ii-|w3>QB|1u9YiX0N<`7x4@=7a3?tZ1o1KUc-kFpbl$X8=KU=!l8Zi|ay*=iG2$6!KY!^b8etu%^N zf|N5M4eyA^3)W;EQr#3HM9|=!;ii3z@+gd`!UPFt!hgrMQ4Xb4MqZ5

    ^P3=KT;r z6>^wFA{6OthY7YC2T&;fsz)`QYi+0+V zQ)(#XH->K+2F{2~k;!;fa5Ptl3MhgYC&a69f$UQ#k}v1bhr@^vDyZ_A5!`_gp`At{ zDXY2-tk++P%8ga`o6GITa{h))AXWRUI<{TwgpFp>}EMlkarV#u9x z+mI{HgSlDU=NO{7U9e;<@@n5VoP%KgXy5(;BNGWtE)GXEl>h($07*qoM6N<$f|rUu A+W-In diff --git a/TMessagesProj/src/main/assets/emoji/0_206.png b/TMessagesProj/src/main/assets/emoji/0_206.png index f53361392899072ae7db73316a21628c9b65d120..ac1a8a4c1ceff97d95525ea7282d98844fa62dfa 100644 GIT binary patch delta 786 zcmV+t1MU3N1*ry*B!4GROjJcja7^&ct?kIA>b{!z*S7lIz4g$p>%pG$)wbxon(@k~ z?ZThvx04!9jV=HH01I?dPE!CjTiyTv|FIf~{y1C=mjD0)rb$FWRCwCem*H~UFbISz zgpmY#|L3h_u&}GEZCz$M({+9&!{=pzOY-XcfQC1PSAxo_?=Cb4iD(?v5*bru8BZ~PwLIxsL_8r5t zfY7>zfZfK3BY!MRq?aLb3~FPX%fgB2nR3jbs-?9wg4T3I(rm}o3as9_6d&=*Zh*hE z_V{wCG7#zAnU3RPYdsDZ^a@c(5jfr%Dlg?3*v5h5I^jUzD@2Yb6B5+d>DFR+-NuIg zN;owl;bj}w>_U|BJ%N{PG~s6i!($t6;yBD);`u`Zo`2f#BpPBrOo+nT-77>QR)jS| zDWodg5N}<;@j7SlUQdo-crsxKhcK-mf*ese1CRQ56De#6S1;9i6|%tXPFQR=BEDU4 zkS7EZOS%n{ZxM){P|F=6dK8mz2Q)%`ih>D0AkbD-8X@M}k;*3*r~o6}_W=XpBRm0= za5j;z3V#8T*hFx%2OXe{5#r;uNNtRC^1%HEq|!SW2*M#kIxI|W z0G-4N5ogd*?u6P2;c}9HilrLjDmH>>5Uyyiz!Rd2o38cN#5B)Lc7Q`2VGPTN9ncWd zMg*L5Si`cjLqIxKWzkNVmCANc7)&G!N zm=Q9m&hi{*B{BKnX2lY2|5!nbO` Q01E&B07*qoM6N<$f@F$oqyPW_ delta 699 zcmV;s0!00(2Ga$QB!5LvOjJcja7?&`Vue;fzm8{gN;SKRWr9>bh*(0Tb5@mROM_KE zxrk(hRY0L?QO1>Q%9w7#l4`t*X0LZ!mSRh!Y*V&@VOTgN@WEy!0000EbW%=J0BVZm z{^{4B)kAAdRDPG+;OGL)l&y7H9tpfa3*Y(GLxoP}ro9I+2 zZ0DS7fWrd9hy8l8@nT!a(b;V!9v0vUqQhJ})a1Tg#KLw0l^yjwe|en$W!T^a9rh8PSSSM3lee4V^Sa{7fWZSb@q1{n(2 z`aHvm4e%17)C32^WwbGdH4GHyyd84kv`mOHEs>tHgnt;0OoU%f+o65IECDlT@NMKP zDSRC}bXtmFM^YdSTRg2-z;NKA6v3rHa@3$BD;q53j`N+BV`yn+ffWWQ?i^|eL2@t% zkRs<|5XxMF^&ZQZ{~WeHcPKG>NfJayigE7%dgvj^X3#cIGa5K9B&cR@#6dzgIr5gk zkxf(z+F^IkZd2mK~Lh zJB)VZP{hJfuBHz`5_uHFxEtzPpqlJ|l7Qj16traQ)3E|oF8SH9pye=*I1U&#L6RVY z5ceqU@y8vDG6`8-{SxgZ2M31FZxM$e=)?o$xHJVZjjkS{lY=lb9-*S6Q`KXXZ|Z~y hk5NKMRsB(3{sEm$SvU)hG(rFX002ovPDHLkV1oJSLht|p diff --git a/TMessagesProj/src/main/assets/emoji/0_207.png b/TMessagesProj/src/main/assets/emoji/0_207.png index 5f7c989f434333ed6df27bfd8f71c3b64bc9db6d..154e615bcc6435574ac60ad7d84517a52845c136 100644 GIT binary patch delta 764 zcmV3liRL{(VlkRw2s)QfzzLN z&6I181qROm000VfQchC&_DlBDVLmoBILR(3$^rvhkwev=&s)zDMX8knaa0_ z#>~GlQYCT*eHBP54FK_C;-#f;q9llz4{PRes0AQ}>=}5-XaevOKE4XIh$w;yT|mwt z%Fhr0X&Iz<@Wv?5To{5BA=_N&Ngnxyuuf{<$5GP*1kAr8YR8+w?Fqu_7`2#<=dF}= z5UhyQ!iMTWqJNEu1Ci85Fy_-pAT?oGG_}+b3?|9bCZeL)T@}Ou%3PS(zO-jUc1M`4 z*_R?(Uyo|IV46Y{@0^*@R_NQsRGt}zU{!RU4KY8Gx|yKJzXXD(5QSnKb}M#>nCfI3 z$Lvy<4S_uQZol>pQD+g+21noA3{ZBD#w{YllZc5VJ%6hL(Dd`y-X^@0+`19wT!e`r z*jOO|96XanBRJyiV--`u7mu-DHtQVg+Y*m&0yj}vl*NEI-`g$S1yJj*#E?kl8S zh8cZ)k_AGLUak<;5GN*d(TmXUq6imbxm!@eO%!5?6TnK)KJF2!UAb-t7~x`6B{i8-oRL5BCVd0d)`-BnVfCHCIAtNFfL#g1tC?h>^ue z*iUmr42nAl8A4Ef{wI=XkP!~*7ftvBHApa&yJ|UqCPf9^wuU;>Xkk>7P5rdKmaBKN u^gGpd1+Xw~%CpwrD3{O5IVY|DKlB%J$2*y%0+HVU0000i6GN|$$y(SZ{9ehB?lip?2urY zz27+AgBt^g=p@J?0^t9h=b4}Odp5s}47Y?3W=Z+^9{-hXWGtaP$*Y^O;cSq2mYy1r z(nk_LLDR%=%P=vPsRYDPM47yHiS?EI)us7OV$wALNPJYluU$jRCx8q zK~d(G6+mZGl!&8cFt8glUJ(#k$OI$F*eb-e5jEH2KpC1Q_aR}WbRt5_Wh=1eVKhV) z83qgA#O%7pR}woC6U zz={yz(&!yHWTbY}gezn2850T8`tWL;k_(iZC`NG=iKAy|Xr1-Ul{@-7qpJq};jSrg1mr4WF;OTE)1IwqHe&h;)t+bt#Cs@BqSn`lDLusp+(#dT1Ju@qawy{X-!E#BeR zt#w(TX;EugUP1r>00?waPE!CLjN?USv*PD`y(|C#0#`{yK~#9!)t1|i!ypVq3o#el z{QviEkrO7j63R*|?W9i?K8%Mr$?Fg0LJ0IL0xdabj_wy87JsgYyv!R3%(*g{!z?0J zgh9NU?Sr$4rvh=oFCvYRqnnA6Mb#Knq5A58S(Ujl!q*5fAJ)vo!Fa8RH=`&5kuZlS zWzt75L}o1onKIJ^LQ*OW#xj1k)DSTh*)igb3tzM$GA}fYkacTGE*@<7@evcw=EAw8 zjWM1EZ6n6=Zhzhv0Yhoj#D-9hyTq7&%!F(N+tm32L>wH`)$TEQN41}$Ri?LHB=IcmMf(xO6(*OYoMZ)2+4GhHQ!ueFj5hUn? z*Z4zH5gtZFsV3keM~X#d903zZL(Bq?K7=E;?Eqo>bAQYQ$*vCsa-d2d;lNwkM> zi%186+5IfC4D!bXUvCkrI?QgcxS0|00_wh>w_%gPXKHtGfZjzEWz zyhwFpn15iwx;WnwOU62rtOPMzhkEm1=ZPp}C%kp~ zgeH{3MuS*2ngHPuVFXA40HKS3PBDNmfY7T2I}0Q95NwUyJGh@tvYFU> llhyY`{#GFbBIjQJLqCqiNSMhd(!~G(002ovPDHLkV1f*ZJ{14} delta 529 zcmV+s0`C3S1*!y)B!4PUOjJcja7;2I978cEKrbdhFD5-KBttMKFd-UQL^xbWI!iV% zR6jOBEhi`&6Mm#I82|tP33O6UQvm(0fHzqh&*e6m`M&@F0j5brK~#9!?Um7vgdhw> zrKO-F{{Qc8;f_;`(eAP@^Wce-m`Oa`)`HW+!^6Y3kfJaVaeo|oxIH~DZ#Yf2L?tOv z5fNr4n&)}xp*u&Sby?=da)IYigE8btd9D1*!KJ*w3YPV+jzl4po!3XFLeM*=Dw z@AKWZx9x6%GqYSB#7(jb;DE$+7y^lf=nd|8n56U)i+^!;xRO&d{GJ+;Q4Ug!IT8m* z#vC9LB*P9=vxVRUu@AOe&9!Dl4yPIn+m%Tbu4D`FK;<7EXCm8Chz6fS_@o%6!l>&| zjvwOumX60UO@D_&|ACv+G=KyPqP-jSKWQ_JGiAe-<}$U& T`ib}e015yANkvXXu0mjfht}vS diff --git a/TMessagesProj/src/main/assets/emoji/0_209.png b/TMessagesProj/src/main/assets/emoji/0_209.png index ec24961decc6a79d63f161ae8d0161139c927eac..4a4fb3e04b7cdecc39d6f103302806cafc56bc57 100644 GIT binary patch delta 731 zcmV<10wn#C2J;1wB!47OOjJcja7>kBKY>s&i&{8+OD&pWJCa*AdrB>fR5F83FM3BS za6l(U4!uYK000bhQchC<9&JX>|NfZ&|Ns6F$Qj-M00MGJL_t(|+SS+5ZsZ^g1<+y> zW1Ii~-%U&%GubSJRI0S*VXA64bL~Mi{rbg90DwOdFmKyNC4c=OL#Bh+^7|mbv>gT! zyd^U2gdtqs_F*Z^cr}m&g~g19jY1M6pv7)%G%wLGI{Ubdgd6$!yE7N znW$?7GM#-0G_)tugEqPlf7zVT2pm zSWuP61bzy3_e0(Rrl&;d2>XLtFjwLD?UX>i5JVy-#D95Zn1^t}5puwa1QtTL@uBjV z05M`%tT;RqbAd$Ds1FgQi6NSY!<_a(qP2{OJRyihwGKxyB#4@j$D{~Ywrbm1 zS_BtH#AbxYXxokGgq)^?z2A%*z=bHhKfnPvsA7VeFeQ8&iwT1aqZBNj!1tSAlbjLM z2rHA$CaMb~!uI!ql}3d7`!*5rxrqG~?<)XH;8bI{zpI6#qyb(Xpz!Z&@=~!;tL<(z z__wa;-&La=z|kdFk3F{hhk7wGq{+if9aJs_=MQCA?h5uoOzG?Ys6W$jH{OlxJxKrn N002ovPDHLkV1l%&P7444 delta 762 zcmVeK3&O-abG5EYF?Wq*oj|t|W4f3)b|I$tW)?)wFR|45C?f?J) z4|GyaQvjxyWE1C1{wRLG+JNfNHYR{G0007HNkl(&ci-TPZ~9i=2w8?()lzo8j@a;Pj(N}-0m*vaHwOcI3(#J+kk{Nh8BSYy=b z*~m*0zI%{l3x9ZWL;Mv7qvMoH3DFt^9LC1KIs}ynAw;%NIZoauiF2q?3LH*6CLu5nik>BdT(;z9c;F8RwRNH8wepgPcaH+DHZg*vMtzVdz2b$H~tVzKJDK2hL|3Nw3VV2i0mw5_xTbRMEp z1&rfPf`5)yavU86g@J&isiID$IS(y5+cPSCKN75?MRyf6;83drY-OY^J;myDX&41S zjc%55w-Jkq;{-w<=_(ZFJvq0TGMV(KBe7!1&|`EMQi*V5ymPQ$5;4-Qf(ED-b92QL*hdw&h^~VB;G%1zG2B;z4`k@V zCZBg;Az=Ik@fVcrZ0NJ5Lh3oc3b sk&5c)Yklql8P^e5DHm+`ZG8Cf2j{|Smir}r^Z)<=07*qoM6N<$f_v&{UH||9 diff --git a/TMessagesProj/src/main/assets/emoji/0_21.png b/TMessagesProj/src/main/assets/emoji/0_21.png index aa9631b1c2b66dde37a578c53539bd439b488432..d758f89a568536a0300e73de689a2df258135b17 100644 GIT binary patch delta 1539 zcmV+e2K@Pr4wVd$B!8<=OjJcja7@N+4#;T+$7>1Gdlt@m8}5Vz#D6jHpcck@CCF|K z<%t;RgADGRAM~9T|DhoNt0mop2;+|o|Ck`wcm@B&F3oKP|E&i9^Kku_1ONDv|NO%J z;bQ*POU$i3zmF&X`?3G`S^xKefky}b{nY=%IsdU5|N5f&(|;o3%ufHs4FAqGaykT} zY!v_OL}M!fkyQ!*wI~1DGyJI+{^dCAmk#>000kkQchCvh3C8 zhnF{EAWiq0vGl6~o&e?F%Bt78X|yhsIFJPr{uN2gGN8ODnjZ@qU6BP67XNXDHK5_p zW4^(<2&kIE3=_aQdTfZ^QShP~T)(+NZ*h@#_UID)6Mqdtd#)w=jKW1EkMA2KOoP%z zQRt-xZJq*8bZ^nIi60njU!2iPD1N3l_Z?)|_A|u=3ja=f{2u(4A(8-FrBts1%`%Rs zYId+2uem})rHI)RLTL{US%6g(8sfEt$y5Z*%!Fx*SDp`$>+o5a1Tex>f+QD@cLiw# z=S&BZg@4zOur=Nxsz(SM5a_TVS84bfogwgiba|e;Q3Oddw`qcS2Fb%ET0_|Uv^x^J z+=vCGtLOG99}Uq4YcMH0Ypt<tz@SJpHng-C4i}b@BjXvGL-YP`mins?_D-ys)kZ1q5dEq8 zfOnbO<${?cPxDxXxSihTaehC&f05HXp2qof6JmYLeL>{4Mn}@xC&yg;N@EjGRgm-dL6@ z4X@cg6N0M&fb(#~D9GKNN@?M1lyNDzAxwgqNDW4@1PSKv_TJ;?FmEm(U;rt@Jh+<7 zR=XM#0K{5*xkN&KgxdaN$Spzw$bZBVdK-y-h8i>|7!WYzl0chbw3bl_1eQoSkFc$* zF-@EX1scK0hyI)!3P#=zmhkh4dlHN;5)38Vp8I&y2+lNHCl8}Ld|3Kuc(gBw)@}t;7*Dn p%Zei52lwx0FZuuf%<$joe*h&ueA8;9e~SPB002ovPDHLkV1mG{;+p^f delta 1789 zcmVVIecn*{&eT>sWa|MrFd z`l0{$lK;F4|NF6GECK)g!Te{0Z4OO@F$Nljx&@WJ*D>dFI*_MO76= zX8AK{Qab&RBn(jSRA$xvE2=`bC<*@9P88ELU9|@C6)aEXR+aHpn$noOKSJV4_--pG zzq){Fv5?6-hNJ@nFOXhxkKw|jHz^fKc-1fyG~HPEe3=hmco4V)qrfo>-!UkYd3crcfOB-gg=tPHebH9i6J{`Z!0ypj zQ931Wh7m&>TqA?$ZQApbig-Mh0NRjc$xB^ok3C2CaLu`_sR+hx2zuZENE~`h={6q0 z6+lrjjm{Leg4R+>j+S`|+oN%L=DmPRxrC{Vi+@;1@0jyBf*$|C%L&Xo#$^PZsFg%G z1IaZ&&w9mDh}*#s!Z?;nDcJ%HIPSJ;lxD}rEu6Isu1Eze&W1uBpbzC}QL=0De0^ld zoSk^g^Zc7)ErN=@cp$^aggzFBgLklP)2!F|FU4N5%bRtRf5kis7K>VRv*EYu#P3?{ zwtqKqBZvcd4I!nZ2&6kOe!@-wRS_>ve&G$WWfN@0kGuBw|2CbO^_nW6-bHFhLMRUY z=|8iqU)>&5P=OqFq30cf6%Zk~#d^^7JV|q-(FnT>fCu%)TuTcwx5d2t_ z83+x$zT>4TXpOG1rYJZ+3X!H^8(mJD>3=Ya(<+GCszQSoIkT|3I4g&0@EWoi5CVv* zjer=2F_8oq0*yNEti0|z_C5#&WNP3VumuWL)wWRp#6(R~5@;kM;SFnGHO@#BvdW@k z&D&q)I}D>p5)c%j^@K(Q#sDLMX=Wua%G@7_g2ypktJ#?+2?EeZusVG#ALW89KY!M% z3&tRWH%*biNV51!6kT58wR4jW4Ri=XkE%-3bjJLB7!hG^ z#%izI8yE%{K(JYw!VAR}A*&Yz{I5Q+eT99jbkk6~eLC9c7$azN#_|*mfrwI+kz%!n zxx0({K1OPr{k||vNz7tqwJDWCRDnwP{@{A9JNrR>EQZgLv7ur#jP27fOn+4gqSB$l z(3*RWP9tYBqY%#ZW7y{yrI3|q(jj{E$!6*44}<$oRXSw|lzaDQ{g z{S8~o*m(}VJ-^>OT8yQEK?rHH_q=I3tEuyIOTdLT#%}Jq^KUl-jYA_t1)<&F7i?_; zR!EqJZ7-E@*T5hOQ8fT--P~*pgM|AA_Cn1N@(*T3Krh%D3HR%9GBU6kLa<1pS|b30 zVT>mKeq?-jl0iU0hISx$>H!e!#lz1JRwF`4L5ChtCiO5H|H?UWssTa@I40dK?*~Ae z{^ALHI$qeI0HX^2ulf5G@0N3$w}rf9q*00000NkvXXu0mjf?YdV9 diff --git a/TMessagesProj/src/main/assets/emoji/0_210.png b/TMessagesProj/src/main/assets/emoji/0_210.png index cf6b3ef69180657b280588bf04f994328b9a9ded..82d2cf159802fd7a8929d6d8cae8c9631ee19355 100644 GIT binary patch delta 641 zcmV-{0)G9h2ATzsB!3}LOjJcja7<1-GeWIx*14 z^Vltu00007bW%=J04H0B;<4XpH|weZ00JRNL_t(|+SQls&f6dqgWq%bvbp~Y-Y7v{ znhZ)RO`6j`r8!S*OAz(vAIjX_z9M)mr67F)v53+b(H|oMP=A_$@D!0y4k0|wfq{5b zhc~$oP%D2lgVQ*zV|`arZ$WBxQIhoDbPcXB@f#w5wIQK!CC#{{t}yl4{hfjkHj56HsPMcMs1f7swgNrR9 z$$)COB6@2el)evXTo!H>DG4w}1(1b{(krR1Tjel)Wz>~&TKrwNJRc8jejyL{a(AV~GM9hFhYugRahlZ66txHNb@!7H8dkf))O=r| zGz!)gmipTgWt@c#R)A$1zh`OM;4lXT0l!SOdSBD^COB_b!CKb5*<5usA)+K%ENa~J zW@FTDG)kOjjelU5;Vp@3Swa@;t$3_o)LZ?ida~$94hdtu3*(pVAL}m}$H5RfP+L5A z*T>L24^}S}5*TTm;Bj{XR|`JQPm0m4+Zos(gI9PdUms(*pdLfa9tF1twi|z$f5{S# z(LE@P1L7eGfuanh6NPnQz_Lb-!#t!EL8eTgs0q1;bAPOj72fG#m~|jzdMcx1l%{2J z3qch3d^_xjA)p~*+0uxkHJS*r(N3r6&_OB0AtZ-$F^xD~m_}87-?y2a&nEa}xFaH< zgZpu?VvHxcgE`tHI2;>qGB+y-xAF3lF*v~bjHF;Twh6cCwPJP{;{Kq>^PJmzU%J=p zuLm(?$A1$WIoGC;f+zGWp`zy;uN5j-;NYhexu-crL4gd>0*{y#Onv|ufRaLKE3H2p z&d)3er4#{@}*(;vq6RJ5GQ zSn(i`Kp&v0DJm4dgk(bkqqRBExDS^iT}zHL8U=g8>}YAbOPOjnT9E9h^{=O&4dJ4U31J;QV#B>PLgb)AGN&U(|%6tvehZ6tJM8R?h^}IFO zk{R%{Ea9Ca;+z+-V+sG$Q0S%_@2(u_swk}$%L8+w$up3=|10+11B!}2 z%W3H*3r;p!;Gd%b$-jO`UU}t}SBfIdcKh{ump=7yo@dE^CACvZIhhp8A5YUXzlHwG zvLxYeUak0PcYlxG=Ll+$h!!MN%}!F&6^; zTchgx{)5tWU4uvhy-09C)3U*W{PxI{;~0KG9^@GcZlr-=^#iwQzN>=s?sB9a3ui*)tDNq*bgq<)W!}#I!e=# z;A^m=7L98q0U?~p0nubcA~3Js0C5whh<}V5Md}d{nh6+iJff60;)?^M2?CTa zM3JFn0$_P@U^u7UBZDj(*lM*gbn12f9{F+#MO383@+#FRf*psMcp{>_715f6^w(2Kw|B$g%=j+@ rZ%$7peC00000NkvXXu0mjf)?%DU delta 708 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 delta 818 zcmV-21I_&W1jz=FB!5>>OjJcja7^~QD$IHb%6AIek`mN|49|TD_P8U=b_?*Z9qXwV z%y|mPbPC~`3-`Pz@v|WO#5DiSLI24+`Mxaiuo~l=3;)nb>!%X`(@)uq3IEky|J7Ij z*JWi`6Mp~z01$LiPE!D6MsOny;r{-Gt-PGm(M3^xRqOx&0)LT7L_t(|UhS3ZlA|CH zMio)wy}5Zw_Whr8yBn6Ub0L$NKU=jqNTjUkGhd6P)jz_E7cbg+8P*>eta(im0RU@e|GZg5qbp_o~pT?1(z`y9>YE8P!Cq^RNqbFi7slV zAmzsf{CS>pU)TLd)awV? z7zBk#h8y$egxnI>culJzq@M?BtHp(~U{Z#^{&?eY2Y-_x#?8EqgWC~5_p?KT;j|>U zUb&vz(b;`SYXIdrMXi)_Y>5U=e2t(2OR`&=R#fIsL2WExfv?zLAOS0WMa6~&wZFyF zj(37X#83zdf+1J1!|q+q*p1^jO-+2_7R_ul`5pw&z_3Nzy{Xz(O4%Y69n~F~w)vLe zHHJu%!+)q*R-dt^|ID%3a0`k%*9}zvsiIB-GTRiE<(ta7d{;wno1NQ&LdW-{<{yGI`4-_X zc=1R9d?a-2jUk2En}WhXhT%z)1U>NwxKaw6$bU>3B+=H(!dF9C98471lqei%0X399 zeT#C+G0~EXVl+3)s=$E7djvIvrGtlMsq#%#qQ+7mAPIxPn0R)lEGpXBpC~v3!Goq8 z|LB7%V)cc_C0f|C2fUxE2Q-&Nhm*7TJr3l&i0TWDt{bODNGV3NU>t%Q^cb(H9wQpj w-YeH=A)=`pMfE(b6wSmmm<;9rEiYdD2G&|{^)TrqNdN!<07*qoM6N<$f?H~ie*gdg diff --git a/TMessagesProj/src/main/assets/emoji/0_216.png b/TMessagesProj/src/main/assets/emoji/0_216.png index 3840d822b5cda6cbafdf3b192815e21ced78a5ba..d57ac8c6f3f085dda567c934dc9c5dc32233f557 100644 GIT binary patch delta 529 zcmV+s0`C2y2C4**B!4PUOjJcja7;2I978cEKrbdhFD5-KBttMKFd-UQL^xbWI!iV% zR6jOBEhi`&6Mm#I82|tP33O6UQvm(0fHzqh&*e6m`M&@F0j5brK~#9!?Um7vgdhw> zrKO-F{{Qc8;f_;`(eAP@^Wce-m`Oa`)`HW+!^6Y3kfJaVaeo|oxIH~DZ#Yf2L?tOv z5fNr4n&)}xp*u&Sby?=da)IYigE8btd9D1*!KJ*w3YPV+jzl4po!3XFLeM*=Dw z@AKWZx9x6%GqYSB#7(jb;DE$+7y^lf=nd|8n56U)i+^!;xRO&d{GJ+;Q4Ug!IT8m* z#vC9LB*P9=vxVRUu@AOe&9!Dl4yPIn+m%Tbu4D`FK;<7EXCm8Chz6fS_@o%6!l>&| zjvwOumX60UO@D_&|ACv+G=KyPqP-jSKWQ_JGiAe-<}$U& T`ib}e015yANkvXXu0mjf9AW47 delta 779 zcmV+m1N8i=1fm9zB!5v*OjJcja7?~+PQG?exNJtrg~bUTNc!7G}Nx00MDIL_t(|UVrVDeQ%>M42OY{0D)rX z1!(*IKj_(xxlnDR*WEuST_0ysRn3onPO?GukMQQro8jV|`748U=>7UPjwyIVkK>O8 z#(}307~0`Sdtf^!5pD?U>x#inor~bv;1Ob~U+kYoYDbS52yxk(SNhEu1E8RSb=m3{ z=9pYOwg(oZt$($DZs=Bk+)acSMbOtT7{)b1?hl{=`nEQ&OrZv8r~Z_-tsSSS`-;o- zMK(LLK_Lqj0RjTjV!Xgv=jn?v$lx*u!n8}6@O2)0}zv>xbWGFg$#ftz*QC8 z1H88nL}E>wkwe(O(J5G<3V{`TK|Ybv)*1u zKrzCJ;(uB)6vOo)gG|z$DB-{PtjhJiMLu zdxeQ1D(Vr9qB>a59_x0FaaBYULs5y5SkE6sPJaXoBN8Q0$zp42sxu~TPEv$~$wjQP z;+pKKVsI(5QKh6BMH4=IwJ@8|Z@rLm8mUZr{%X;1=STmM={E^eNU1l~QwO)!bz|&c zYLbwJJ<8TM)pO(@sbZSCC5s>f*3FOJ(oECT47qLfAM@tTFBnyAX!2>5QUCw|07*qo JLeK3&O-abG5EYF?Wq*oj|t|W4f3)b|I$tW)?)wFR|45C?f?J) z4|GyaQvjxyWE1C1{wRLG+JNfNHYR{G0007HNklE7I^6I~l!;AW@_s?5hVOE?opB~;D5;tiB}wa=tn3eKtBXJjEz4!(3ARmXR9fxhRL`L(j{z7@Wh)scvQB!tei3R+m&? zMX*}!b1LAO{jZefmWCM^T*?~~DJRT|5zVCNrtaxY0kOUwqh2X@EO5`#s z9QKVlnj;B{gN%1$pSq_E&T5FSe4lg~9(%4>tU9hw6f~pE%%2(fVoDMBtyIGSTQ;h| zaa?~aq<>0|qoEjZAS9_(l&PG~L(9hP8I`^t3Dt2%Hx)y`p;ial%1A3M#p-l!m;^|P zK3&SqMl30g3Wh$?R4B?@skfOj3HWR&CZ`?}n-i9n*%}JD*wnB&-=yU-h_H~Ecde1w z5>_)4v0z!(qIVcliTF^wb9lc1F%C_|5U^Ux6>}>P7z%EYO@;8mMR$&-a9;>Mu&xOo zeYyiPf#NTOzmR0-U7HmWWvF!_CXOz3|YFeEINLc3J5?Tr^t>otb^?UjxgxJMoA?~X|$)8PNU<{g~ zMG}%gpN3=FdTEi7nX$BjZW*uV2@8lwSPWKwlU67Srhjx#2tn?**AOL9y={jCHB7OCRprdSF$Q9;s6X*dym(9ekAV-lVqmuOGT@> z^=A>P!Eyk`uNAlZ5cdYv0(GZ~U1E7|=FoNNwRoX0ERsdYnUinM6!27HA*5qJoGIXM z4x7V(aDSF!0pmebGr{RXG8?ds_E1(6pDI{DZN@_+4ky>b6DqVHl$HnfL12of-wsHX z&1UC99hlBvM3E>}%u;Mdn3^+M5riF)Jb=>H;Z!li5Z16(f~KjeRC)@pUZ`G6$93FT zCCrhqy5EFwnH-7+6e^?H)k$b)X00001355=vfI+J_cd}9&R87?t)oW1Ig^`k9wf=4L1UIT z7l!SEgTz?Ukbh{K-jc8(O3g7GfpSMD3*hIfqQ&Ek z#_}150-ga?UsbU95~2pU2&D5Zs9U2ATn; zQAdtD1t#_#1tXJq*beAnfAex5Ffl;o!`RB=XKl_<2S;p2q-|L*oBxe3U;Y5Zl5EG7 TCJv}`00000NkvXXu0mjf6v~Gs delta 726 zcmV;{0xA8h2JQurB!5UyOjJcja7?UsSx+(`Z%8wsYEg7eH+W7sl3qwnF&<|^E{a)0 zPck4*F&}M3F{yG_x`t!5e_y?eWu0eFuXkIha8|#MXn|8b!jo(znj@M3000kkQchC< zWos&k6h;30`nJiN*2@6l*|q=x0!B$hK~#8N?UrkA;~)@4F@H7?@MDH&{{KJSVd50x zZJkZ~Wu@jA*;1l=xZudK_)mEA=8YP*P5;a=f%oYrjsY`(2ls7(-q2GCz*T)~1>-~l zGGxFotJmYhv_+_b+98$s#e9t;K#kuF#>!XndWsP$90$M{jD2Mtn(A{J2t)?anZ+vpMpmTLuN+_2i8+cL{FuSO) z;AvFCDhTC5Foc_2hzMPWdkePmCUih07H%=5lmc7Wz<+`^{gn-X*zYXH3dM@mwZw)* z{UEjulx$0=hQw2t2THNC<`U4s0^YC&IUt&KwamJ+5OV)rY}tR18;_1?q)?4oUVNZ@ z7uz?HPdyou8O2v#FsY1EZ!g$`>kj883H8*^J>S;Q0MrNI*7@e!%TGnSg1 z7pX@jXSUeVuoo$wBW3%8)p8~cW0_fg>n%;og{jTNFXqjgKQTLEI(La}BLDyZ07*qo IM6N<$f??lFvH$=8 diff --git a/TMessagesProj/src/main/assets/emoji/0_219.png b/TMessagesProj/src/main/assets/emoji/0_219.png index 1d107917d8ce026e3f1c1fd365080b72df1a1289..9445badf086bbaeed6c424304ada1d8985625294 100644 GIT binary patch delta 705 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 delta 1764 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 u(tF6#!`~~ZBS>iLQKhB;0000JtTESDTh)r zk6AUAUpaC?D1AyTU^XF~Wj)U~^lJbB019+cPE!Dn)VSbKs{SK<4?vew0005xNkl2!X>2Yz!*MO6sVanIJwU(VNUAc3t@_%Xnd)T4J5Fvc{h`#qzs6(gJ5HL z+rbjHU}Jf&MQ&b7sS?0L1NNNT z4uAmA)+0}yA%B7{=TT?%)LB05ayd(Fb)dJz&mX4^f7K$R^ZH49qwOHn{JT0mos zDr`ceQ(i18Aw)>V*u+InIchDm`3yeUK2^&r>c~~V00iv_cP{m0ZB&Oi1fFqvJ{QJ# z@8_K&Lq<9;s*2>f5oO{@Bn@FmmWfsYwzy??;;yTV>Gj9#x6X}!ci0beUz z#tRN=6g^%Y=WX358Yx`DbAc>oWLjyUFqzH-vbr{=g9*H44%CJT(0vKkiwoI~2<)jA zyJZc!WDfqwI`y|B@2nU9&P4jaFaOnB=b;b((@_7{WZshrKJ1sW0000DbW%=J0OFUo z7X4oSG=S2+|Mk(goxfxpYPFhN-Rr)Zq7u=7ADAHDF8ss z?xSJHjF9M(k%>iwV-ywG_}nqCd_nO-9Kc}!01oYpQh!j0Dtzf^eX;{*l=zO|j+pI7 z!mODHV4{2_mP(lRB>@B~=}m?ENNB!92ngkG@7X4lBLX0MCdf!%?f}faYCQ%<@I-LN zA4aMXxHbseF@eYg8-lQtwutCkgzD%L9t0w2sczW?^s8$S{pvAt1PCG}vYp7QQSHZ& ziVY!yQ-2mhYD6Aegzh9m3{m!5I3jYyXjNm5GLVSF*o7LgK6Q(*BV{ncdl{t)e8;Ss z8^|Ce3bLOfXGp~8+Jqg&;2lOO09ANc)t(_ESELeT91-#qZR0VnjCeK<0==h*S)H1F z5|X84BSNTmJRVw|n>J4l$$rZS+lRS6p6c}U%zq&@1FGONzox!!M3BXuue5SH&UZi~j=b+=*})ozv>#tQn>q>89Q=aD7_aI{h}_7p`qu VZ4k!MO0@t0002ovPDHLkV1ms2b2b0~ diff --git a/TMessagesProj/src/main/assets/emoji/0_222.png b/TMessagesProj/src/main/assets/emoji/0_222.png index 0225b35c4e99af55767cdb4910760fbb25eb39e0..0f9052381adfb10942749127e8dbf89b7fd96338 100644 GIT binary patch delta 472 zcmV;}0Vn>*2J!=tB!3}LOjJcja7;QWBR3}?G$kG@9u_ks9W^E&S3)>VI59shCMzBn zI~5xC00007bW%=J0DL2&-7{-Hr*jP%67E*1jcS9sG1h<|S@k`_mq;`wGFRveJ1 z3f<9!WC{t$Pl5b&CCMPsT8?H-Af9$WqL2Vp;VFl!l2xPC5vIyv3adrqYAN@ogFQ9z zB-xRy@Nt+nY7y1AM=@&5hxoxl>)&t@t$sU}!a?H{dP;-ci~<#!)E6j0)-3SGCnUuo z!2rQQ*oG}S4u7Dg%GKerB-x3cqeKIN0%b|axRr#fX|I@AN95%UgJlU&4C!omf?tSt)_Dt zm^_TeN9T2EZ(}J^yB|iWu5skB45CSx5jJqLK@f`p0J}7lk)8?TL_?24pll&5Y(&g$ z1g97qi?kD5Wca7V$h+9uiRKjTyJ%10N{YTA1rg9n1c0rb;1ufrC(PdwN(l8%gxkct zgs_b2jaY69(tpFYZDtWq!VaArhEZH5dcG$zdT|h7m(d$AIEs0kydgv<^N*c=IhKN7r*dXpM4eO?muKIZ67;&T;PBV>*k ztn);$0iPi-RS3}&5fGW+b-W|66TU`teey(vgMeLu_Yf`YwxIyu~pqLeCd)NnDc zU3J!+oIjBx#`X-6^js%|W}_g*cngv8B)a-Yty3&WcpV6Z;2Qd&x+}({Gb5xt31jvU zdRn_nBOVh4VFXK)(t|=w)758I$wvuNV(^5pZ-3%(AF%8_O_C2JVkiO6-5?#{j>OjJcja7^~QD$IHb%6AIek`mN|49|TD_P8U=b_?*Z9qXwV z%y|mPbPC~`3-`Pz@v|WR$vgkeLHxut`Mxaiuo~l=3;)nb*^CMQ)m{J7PwS@=|J7Ij z*JTG>Gd2JK01$LiPE!D6MsOny;r{-Gt-PGm(M3^xRqOx&0)LQ6L_t(|UhS6alA_TY%boIDm>c>12(7Xh9;>OI1eZP=9z#7CuD4EYSl?X56J3;E z*_4y&6s^LO8t8<3G-W+M{Kz}ko`+>Hx^BWL`cJN@(lokcc zLiN;+Ij)0FSgQi1D3wy4EXhELmjo!VWMA5Rg=JwD*v4p`r8|xdAYjF>q=;Zp+eZTK zcq1r83I%|G4Mznz+}0fFo4)U_*D5`6qah+pUIPXU1X+yRs-mu?lr>P`QS8XP%(o1A zAVij|T7M0)xW|+~c>&mPW5v!At!nQo$}B(w40O;+92Gb1x-$h!mi!p8FAGq;>eCd^ zNq&ky8+c2M8|0aSHUcKSqJh~BtFc>I+*icorjqWstK3_3Lw%w!>3h=931Q8?MR2x3 zJW^OXGA8v#ph9oei9*{0nkGsT{KT);pQUh_gMaA&N{kEgzG6}i29ZQAC*lJvR&~XF z*utKT3E^5ipt@uln3N@KX#n#@6yI<(O@FO~l%fX<#6hUR0P(8gF`^Rn veku(Xf=x{?Uiz0Nsw+`JGLZkbym|8*0|sxz!dLw}00000NkvXXu0mjfJhOvj delta 744 zcmV&ux&)IYeK(*S;2!@#fV?OeNx1SUciD_ z-Ls6^t%cyZlGdes)17qAm2Ak1VdTJ@RG2-80000BbW%=J0OH5X`xah{{xqnIl?Rak z00L`CL_t(|Uai>Kj^iK{1W<#`dKaMo|6>QZ#GX+nAr4ay{eO5=1*k1$dl6%{#aOL% zSP~rm{7|wBf=Se(7sgno+5*zT6xRttyFx%S&@BeU;8 zbz;2*5vm0uNsA@o|FtlSEfxt}Z-GS1#Fs-%24dFDRcIIjU>WhDvH9DLvK(~)U z3?CCJK{H5&2Y*2-a@*sAb;Z+`#yj z2(1RaBE*+vn31!rGF9hOqkz^=}RDIcwU15Fux}@ zR}uo`)ChXkVounSE5ZDf=5|OXl<_`j2*|nYW<~^G5}!z)(g6`t z_WL$X^nZC6IE)_}1amIl&57WfaUs3NS)v?ao5y-zDk4f3#OQ*TqnH{;H9B(EAQ;zi z$c|~k-jI~KK@yM|W5+zk?!NRjI4%VSv2P#8#9o9S?{pCUxbv~^V;IF4_mTY(?h;9i zAvD6?SaK35LMO`MJ}1J_h{r?aDs;l%I8S>LjA4vJkf-%&+#nK5265*+O*3KTPjWw$!5l0000=CzRU$fehub~bUTNc!7G}Nx00M4FL_t(|UVrVD?QWwm5JfS?1_Qz0 zko5f@bjR0&oTw>T+CM98&Jck}=IC0Ugf#yMZ{EDomvNN8GN{p58-C-Mqcz5w>Bj;& zI!hr;?DS6rTJ<9$+>8t76x=$*|5Yn)HwWdA%-yRoL=qTkl`Ouw9bbOx{>Y^yl2 zj(PO=?J*0|+JC9PH}t`|(oIC~AsEC7!xX$L{n2rNp%e1VD%gN_>Q8B1yJ?>LXI$nd z+0+6NID+ZAiRd~@XHpfS&0zF<;oZ~P-VmQnk{hnt$RdtLbNSU+-M7C z-?7|;5Cu5m);3xzDy^H+S5dC+7!?E@Vuu{YFRJ+tX}KRj01-P_VjTwHIhRlLS89j~ z#fS%rYk$p94cCVZSV@1ZKzdBkZm0^(mWhixSP1rkUq}Q6JK)VbGB<|`Q+L%u0(J#9 zbs&Z`tgFTQz(4~Nt8gO1@q=iDV1LU%!bB<@*_ztshP$GL)*LtKctLoMMoBZ1qv8WqLpl0ks-Hg{$t*}`2!1hZBSkNejNY+002ovPDHLk GU;%<%z;zt} delta 682 zcmV;b0#*H=2Eql9B!4+jOjJcja7=+yK73C*n`TaQOE!sELYHGphgU*YHzbQ%L}x-S zQZymIk7%rOShRj#x`$(;Yf_kFOvILN*uVuI0000CbW%=J077K5{{7e<{fnp05>xe< z0006kNklop8Qvym0($9(TD~R<3{uA!sC(>gg|0=@&FabYC z_?nMInkKYM$p!zBm=*BgIMoOMaEn^kiI;)PzyvteTYy`!QWTU9;SRK05+ga!1ZzZa zuz{2k-DsmtNq=lWR=N=kF(s8!4r-)CgJMu@L~YO`AR?~%E#Y^INv;u@_!0oA^43tM z5bzSi#D!7bkBOG20LoP^3|jBhAR#UcD*i@|bV(fJCE8{t?3)%T5B?Nh0&qzjH;7m; z0hF8oE?W#<)`6EmW&*w!s0;{gGo^(1fbh0df`|$DhJUEM9T1BvScxPAd{<&j1YW`c z$(It8tsW4HmoNe?pGy=oBD^gqMn^uEC`K(emXOroUpKmd+3tQBE@4BE(>Mh#5tm`2 zDTpW1w?Hpp!kF;Jl-!ZiXhN}@TE@|AypT>nBZ@V0im|a7+mO=$kP>E#%dM!rA#AYF zh&p5Q%YVIiy;q}T6he}cTw-5t$44oGBt+j)47a$QI!1^jNa}=|A*6;}BP9`p&=X7c zzC=P&qS!6oC)D;Lkcfd-iMe}fA-IMFF|#3$*4@NTATsbOA@`gnGICmpxqI&0W*b3W zm>jbI-J%L?SUdAv#7~5@nEVn|(N>`unGF}_KO=|r>N?@ppc^o&oVhIU2WJ9Lat;w8 Qpa1{>07*qoM6N<$g7h&gD*ylh diff --git a/TMessagesProj/src/main/assets/emoji/0_225.png b/TMessagesProj/src/main/assets/emoji/0_225.png index 670abfc0214cb4363bc04e1d8c862417084c6d80..8bb40af98549ba0bdfe606c15f0d8f7cde430038 100644 GIT binary patch delta 706 zcmV;z0zLhK1=qrDgXcg4RlgYQvhYH_=iW_ z{UH6gcFz0p;^zPW0y;@VK~#8N?UwD1qc99bfguC}w)4Tf|9`8losfEAJDH{PXQk~) zghnIXqw7FvyMKi@Z{GBqGd~i{8-)nwM-?JbAosGsI1Cg5;q>AN(L{kmz4pq$;cQRGV%{E2F-u+5`RR2uwSv(rZkycLK@ZEc53h` zlH%}oVwPp949vP7&&3wbNakpv4!^J6oO$*zQPi7V30YBzQEF)Riplr# zLBDf)IDZtftrn3o&qcKpH3tc(5DNOCe3-DQK*r~#{80&Q<17sL3>+^??L)_fL2%9A z4jwASrtgJ%L1=#wIe@*Q7O^RI?OOC4wFe@(;(4XHshFL$$)<|UZK`UQy<486iAlne zmO|n(XKWg}Z&;V*WBI7CBw0qXWx}+W?pudMhdW_4^K1r@EU8c?{Hq@)hSU1@FtMh< o`DHNOeYniJ4*HV*e|huf7vrl}N3ivJga7~l07*qoM6N<$f&{%<^Z)<= delta 616 zcmV-u0+;>T1%U;SB!4PUOjJcja7=PRC{!;TYds}vJtbv1B4IWmct$E-H6T$f8=q)D zmtZ=8OfHO8G=+U}tN;K23UpFVQvm+{jvQh<)Unzl9}m0$00I0-L_t(|+U?fe&YLg{ z24F(s{NVWhZ+FIyw;?`iqU@jtd#j=fsgGVes_6ERl(xk{Eq^gD36YNDAXpGmM<%c= z3l8s<+@?p@%0(urgxJt{gVW z8_0#wIkbeI1dWZL#-&7?c*<8PLNr<^AuZmg>dBymI!6xVb*zR7)TISXOrk3t28nPQ z@ja3EL1A!IV1tSJo&Y7(5JFqD_xp@S7@)+=KC2L7$V-H|eKu>+Rd5FJTbK}9o;cL_ zSBu|+6c#3us}c&FhW;y^Lm(CdN{JxAbkd(}5BUXH;5EZV@fAP-0000JifJpejouE z5}=>P^X1*J1So=%A?E31eJMu(a0DB)k!R}F5CRmq8~}sY=FB=2#ph}u5HZB4vzhw8 zHw+#D+Imld%YQjTU;{F1{Z*YUc z8=+>P%DM#JBYX;dN6uza90D3xzzwUA1A?As!^|sJLaz74lH50`a_i-C66))`4+&zA0{N`?kSzPl8}yDB26~$dKSTMWwav``I5T+}^Pl zkO93CM}LZj)ZAEYf5SW;DZu@pW?5~hk5VMqk7{Ws9X{>_)drrG zFG~~2;lTwFeGEh-LZg8S+q@Oe85gSd(bJ4^7F@-UNp>tC9ZSEeKrA3prY`~fjLVmj_hNMQf~002ov JPDHLkV1jIbPtyPZ delta 559 zcmV+~0?_^M1;_-DB!3}LOjJcja7;-xE-M}vHzy!ACLcB?A2TE!Hzy!lMmkhKHa{&U z5zk-I00008bW%=J0RH`oEz?`Fa7!Cx0005bNklC*2nEohBEtWF@D>Y` zrj4b>Np`dMVcvRj!Ol3_C}mqrC89MXb88Lif>1z-hAU%qf`6eb%%Ox%vQFebLD2so zn7_~hmkC}b_&Y6re;2&eLafCy@k=e%Po(TQwcvT8A~(!sVHXve2FtlcB~tWd5ZDbR zG)Ta^luOOIz9H;6#t*?qF#up@irds=4@#|0G*9<(jTB1$W92P8ZUE!+JO#zRh~h*W7)C_P(3o)r-VoV{HZVYv65%pnP=h;B1ETmO zYB1jgNhQ8R1OPtBMc4^ZB0du}JQpI-7KT!fRS;A{*T)3QR z{CXV5g`f!{olXTbqM6xebwblSz$}rKaKlT??UQZ<$mBlpAWneoV!nl3jG6Z$TMOxc x5!zuQg(#E|uqcqX*_2A?0FwV(n`b=RC_hzOxeE1M@ zPQMaFPl)gvM-yutPpVyjUpE&+;~3mi5EQAjmm3_Nq`QD9krc-C9mmo z_SRO^5T^>f$V0`|^m=fTeJ-#m_J6I#>!cit4GLR z8?eAkWCnay=zuin%q9y#6((vjR0n~$1)Y(~u;Ax97k?SQa(4X4GC!hmHcWQhwmNr^ zKqFs}n&9SaVibR^ums;ikS`UX3i==w-%;#?gjY61cCniRD|T^iDB;ml9Jq3Ti#-Jq zQsq)Zk~#{chE_t-YeWTH*8*1w9XmrRofL^%nn=hJI||sT0{eckQ0YAlBS5LF8sH;f zzS4gXWq1=v5fRli@Uo`<^EAoIBqphV$+n*$pbU-yPh-e=@k_pCXT-nozF6H}I zi+TKu(@nD+na1?^iNg)UoMKGF8bv*dHuM50%|iOYFaOd`_qrzXvK{H75ACTG-H{3Z)mi`6U-N`(wEzGB z4|GyaQvi(QM=R6(7XJOJZ^fR~HTS$_0008MNkl3?pcFcbygn8h0;UKi&5 zUvxMZ4?>k1OsF(HZKd=FpU$<7tUSJr5JQa+k5AG+pReW5me=#yi_5^vFDrmQ%3@#B zB|tolT~?z05aF^OE(sujPz|)PA(yV*(9v0HaWG6slK0Iey6mi{5^yLU#FZ9_2m+48 zD4GeDg7yB`Vt?^2Dyc8*s0yamK#RH|O0o-tj3ACJupxYECx$M6X>n~&kr7)`8&txD z#IF!KIlmq7oiHZkv2Q0B2v1W~!dq)iP^`I##vmTRPLSbZH??kR#9DkIyvH<3i>5iE zGjy~L1Zt3xb%P*A91HJ{#5ReAks4+ha5yc9qp%xMoqwl-{#iI!4tt`{i0rn&A*3!1N+=?fI9ZDvNFb#K z1|7{3?0@-U3|)#L9F*#8gj@;hB70AaD#Hj4znf7V>!OU?0X;dL1qKLrY(q%qY1`J} zEum#eIYua3sz8tO5?AYNl8Kk1Qic*kt>Xd=5HbZA@85XQNf2VfVU*K-)g6bT5JF-l(me5!V1JyyYyC8HStvkO25S-3j4|<#OXnB8 zV5q_YsiX=KL5*VKQsMAr*>Jh_6Jz}}N?GJQ<^Up%LZDtsIqgJ4n|YoDOCa1zJcQmx z)Z%d|JAvn>x#OK49@nDPP9Vbo;3^S~t;C1XD`h;00000NkvXXu0mjfdRK&0 diff --git a/TMessagesProj/src/main/assets/emoji/0_228.png b/TMessagesProj/src/main/assets/emoji/0_228.png index 03ff28f96738251aafd37b8cccae14365a59fa16..2d0b81e149ced7fa3b62b0ffdf579dee1df21b0b 100644 GIT binary patch delta 500 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 FV1hC&Uv>Zh delta 1807 zcmV+q2k`jv4V?~CfY!1$L6!4x9u5?AibtcMh z5Aucs!D=1oiWc&n8|IH5?1l@|fh4{VQ=lV1nm`}_*)r*t4FAC`q-F`=jSAX=2iA83 z{DQ-IJO}kMe*I&r{Z*d*a=7?Nkm#u;&us&(EjQyPYUh9g(tnX0yJicddmO%^E4zIb z$zdtIksbfwO#Q75|KDBz{J#B|1poP*|LAi6_JIHRj{n~;|MgY+-97*ENB_MG|IX5RW&iuD|NYP2!#2#JB=)5d|HU-^x+eer;{W$^|I0T2>N>ENHUHBtYBK_eNDKeb zHk(}w|H>?mReuQo%@AKF0E~H|DgXcg6?9TgQvm+W?HHDO{R}j(`c0+Dj^JM7gxW)1 z$@>5R1-MB>K~#8Nq|pbCqc9YJ;nj*1M1XJ-*FrDpWoo(qS@!V^6Tv2#ncY8*gdF>m zO@94%^Dh@b|ExQ16#4NGJSm31jeh@bVk?_mwxB-PXKxDK3tEOh}c}|1HePP-j zA(f47-$6|mB6K#r1I$AKg5nM5@NEWlljb3(!k^z1d=MTa=QR*Rh1+Tvq&1v7LMrRF zPX$L0*nb$F77Ss;)zI7zQ(4xNdxmsSssR zFo>*3bvLp?peS}iOfG^0huFa^A%vY@)+Di2Ne{rIjjUhJ43+`09sDT^5AIP|BRN05 zt<&Uc>H6*QoS=Y&7hPVaC(7;d8H^N+)zb$cS(X8i;lPIsfRCqDLQ)it+frO!==`@3 ze}77^*WSd9C=9?g1PGK5Ev(}kW|vFMH8fJcIF9NMEVhINW<2u$|1EvbnIW?g)uw4* zAYfr0opWYDahk!nB!4AI@$#~+HDba*y#|C_E|+7L;gIHzQ&pD}8*%ZvD`j~OwXqM+INZG!F$p-Ssvx9?hhN)o)4USZ>2v~N$HiU> zA?saH#2_{`9qkJOY@AYo$eHMAqDNI2gX{QSx^5{F2yq-Il8$z9Yy?FtdiQEUh<|ua zb8Qe3=du)X4S`c6Ybi>Z#{i7*45Fclh9)5BIx06Tw7zytBW*5n(tljEIqVpr+fk-uRaoieHuyp{a z&_rt2;RU5W(nE*G$!RS-41HZmfB+=Ot{kdeTB_|5Lymp$-Q88C=I3}G7p$%x3Q2IIC zpo=hR&-FNRR~uG@Sk|M3&?~`$m|cbW+a%1Q1RfdbOc^2?Q>IZgwXJSj zF$Rb!1%LS|lETzLZS)DaZAI6ymIB1|8)d4WBFxh@HO$)vFllL{^M9N#g)GPKiE$}+ zm}Cbv@F4#AA5S*8nS8c>9Dn;tnNIoX+xYQ&4nPY%9>i_#dN42$DkOaZF`3}AkR}rl zPX{XDCxWR%74q;jhJXOzr}2}=f=^u-;Wq7NpqlYOj7Fo$hy=VKLX{9S+dsc%>^D>) zOmF}w0yLG-=zn-&)qidh;;$kQCSRkKPe2n*e4K6zNU*Y|6C+Hf)+!*NtAUS^#%e{Y zIzdKw(3-AR4FLZ>cm38E3x)~=>r1Qu`3vTug$=5=rZrTbzyAbqj|=|cAR2R`!4Ss~ xKA-MzFtDt_V2By~=iGJs{qEg|760G-4ILdb;+W)*umAu600>D%PDHLkV1lE*We@-W diff --git a/TMessagesProj/src/main/assets/emoji/0_230.png b/TMessagesProj/src/main/assets/emoji/0_230.png index 8e3fe7e38e09df7d01d3693ac77e680c58474eb7..d87b43a1a67ca54f203517b94fdba4943dfacc9a 100644 GIT binary patch delta 817 zcmV-11J3-`1;_@FB!5UyOjJcja7^2ze&Mc(;H-wkd{xz(b<~-2*PVIUpn1`dY3R9? z$%bFRcu@W0#r4sy``y0y*S6`qmhHlx@yVv-vW?)XgxQ{W{^rZo3gIvS000eiQchC< z;li5yIA0ow{obg~D1nat0007_NklaQrv@-*QsOcX= zeNlCyT;|g`gN3CuKa5gM<;ZUCM3pcG*ucpOLCgjK>|9YsdLoPy6+Lz$$Qr`JhQwG! zaEiXJNIk(tx_?Uaw2Q5ts7_J8i~1C9PtjJSKmuwB4X{-coI?Hog!wx{38CHz{g@bM zt><375%c30CVy<(W@hmsY}d%H>&0!NrSpVFD-Hte+^3mP}L(eeFETlCorH4gN4JM4$j9pu`Rs9lW2v_fc#1nqss| zL;`5GYrt4zwHv=0Vv51SX5vJ|#{eQ$M_H&s4UFFj_p#15OA>uw$DMMcx0F4 zwE_Jj0Z2sgm5|v512#v5;Ex0?quiuKj9&@WQ4^D*#wMQ#m@?6fi4JpgC-J$8P$FcG zL0jjMAOk)_gj66zi-Zn=2wKNG0!;W4(X`1Up$`IBf%gzDBT-z2M!{M`b0FvAU_v%G zmJu$)uzvur5I#;NLSd5-$e_8}a0smE(jC}gqV^GZ0yQj1&$gn z=A|jll9Tf%a>UqPA<{IK2{Dnu$Z1?5QXWK89yv`Z?ufn)2!@~<)2f;~#xP|@e0UMY zaENJGnp-2*0fTT7ZgTX%5W{fynpJY;AbSiRt$%qF>w{Zl2gDvD1kC^o5u3;dO;#ilHQ@;-vD_!bFdQ32B#^+w^kARzBzz!%g_sf@t-CWG z1R36+#G`#K7x5C9kPn{ekbfsqN_kb!2{zo3BDdJ%!7_46agX6n;^BV*VrePFZZOi0 v)GFc`BKvMefsDE9B>~SzDJA%$ehlynJIY)a)q~zp00000NkvXXu0mjfLauww delta 702 zcmV;v0zv)A2G#|TB!4_mOjJcja7=bhIEqXS#-CsBl)aeO|(nYn^9L#g}k`+RB&!000eiQchC_@})>_JcBwaiRgNg4 z1W|U@M}HRTcxw=>Q{`(V)F~WzJy_Rw7-sLI_g;~lr7i;YFo+Bo!7lL`=U53| z0Nio03(=a!xf$k@Ffbh}PUgML`6P_7Zt=?mpAe}M1|WcWH&Yf&sKlq4$B8M9Pw{sM zOyk7=GX;(iwodV{34N+Vgl8h8VS+{p86<+wLN_FNkPsOn%o16Iqcfjp_L(_*J3xT* kF?t6BMEx0&ux&)IYeK(*S;2!@#fV?OeNx1SUciD_ z)}?&ivy9rUh2Xi8)17qAm2Ak1VdTJ@FyL)`G4)6D&Tl~5^J}`IAcs) z5%Z#yDVUfq7wySAxl{5ZDazON0mver<>tkk(o#vDyN`EVm%DdLy__ zthZpMeSyf@VvYEJE$m{8MS|8_5c4we%ON&KdlCE_!W$yv?N|7=-gxG&rvwJsF zQs`4CeG=MA4E-hhUlOh@VQj>c8i?7=mH;x=Mt|@lVSXo8mtZOQxCSFqc};9y zmLQhg2!7OJPPkfx0C-5~yMP%H_X0u)!#}6!^MpDfHX#V95t<(@C<`$^3<*kDnSTVx z)ot^`kaVH1;cG`DN|+ILub_se_uy|OLfocH%4M)30`L$BN}*U-2W9K^A`9h5NhBc!fChnqho-&G47*;Gu|b#8kZo1 zyRqaVs0&Ke)4xx|^Ydy+0wO38Zk(sP2q2&#yk7mZG=2~ndIoXlJkxg~Uxd4HA%n<& z3wMSH5k?C!@@4Gt#-(~~A;u+0j0iUp)82Ndp((q!+s#Cm%s9`y8}Agj9cyEceOllT X+tN*?&)Hf800000NkvXXu0mjf8evzu delta 656 zcmV;B0&o5O1*ip(B!4haOjJcja7=znEpb67YCk1nHz8m)AZtD)WjZ5cI3i&~p}JhZIt@qa$%E61ALQg>mt7o zT=z?^a|5$B{s{ZcvJY5YrA}Y~~mT0?@8+CIE}@h#(kSun^%`&WXb? zB4qNNiWZ4f2k7m41bVo`}yhH=gbmam2sr&)SA zS&c9wGM99xVOjzT0cJ*|CNOtEA3`86tkobigU2ojQ-6_YvQ#0`E7F{dsYuu4c49RW zE7Vg62lXUB4jQSq%usEJmteZ<9X> zk{T*z^nWX#8;PV1N~~3aSqPy~5fEZAhO8w+<r2?4=X(gUrdN9ip3`WB$+Jcoy>p_yB+pI{d9^+ZF%-00{s|MNUMnLSTZZ`y<-` diff --git a/TMessagesProj/src/main/assets/emoji/0_232.png b/TMessagesProj/src/main/assets/emoji/0_232.png index e0dc03266507646e0e379d959350218e3b3b5c7c..5836d9d45b7db1f423bef42460f99b0e480f822f 100644 GIT binary patch delta 683 zcmV;c0#yBx1j7Z8B!4+jOjJcja7=+yK73C*n`TaQOE!sELYHGphgU*YHzbQ%L}x-S zQZymIk7%rOShRj#x`$(;Yf_kFOvILN*uVuI0000CbW%=J077K5{{7e<{fnp05>xe< z0006lNklNZcggek`NsQz?6RZ)z z#s*SKbfb+nWq##*Q2WG@@7|r|27tu?;y504ZUXINgd`8^Q() zji@u0yMNED*K0LOMj<3A$tBi-S3XJ+Bq5F+#c+$;sbhrLd!&O&S!^Td z5C(^=uPtN;8`h3|FX9^^Ee3yys%WdwjLe1$<0LfBw z00(qZPE!E>9n^oSM&CeiX8-^Jo=HSORCwC$mf3E@Fbo9EL(=~L7gsjv7>VUltRDK% zZVVVXFc?y_l~>og>d|+;}LOH67CjwMpz{w z0*@B335^g31Ajw;DGEo!+0!tjfM%LeW!Lbl;cgK(gXPlj+r@H3)C?hl$05cr3$KKO z!>q?VE(&a!j&I^hbpPEYVg$F?=?6?WXolsDVjA{w+>Ppl{kn9lnb|BUut6iO&E4002ovPDHLkV1o6h+JXQ8 diff --git a/TMessagesProj/src/main/assets/emoji/0_233.png b/TMessagesProj/src/main/assets/emoji/0_233.png index 046b19ece32b4e34880407d4c27721cbb7943275..b8f30c2ca5d2c3cabc97494dfd29973faa2284aa 100644 GIT binary patch delta 620 zcmV-y0+apP2ZaTYB!4PUOjJcja7=4GC1p7xUNs30=jgz2ff@}28lR&RXN<1&aITV?MdZ#DDC(ea(*ZM^G$GYWn5~`>3uubd^0ZQ=u zp@dI_-jN8AI6s$gi7g2sz|X&vDulZXEkSod2yloZgnt=y7wX{=p;?W46Bf9{QMMP8 zaA@Qr2+_jkP9nw~u@Z4}6Av>~xpZJ6`$Ra{5X71oAp)<$4~QX%09V3R;TyfGG7Pd! z=p24Z8_0#wIkbeI0F8~V#-&7?c*;j9f;d_zAuZk~>dBA=D@P9Gb*zR7SfvF_Ork3t z28wVR`DHy(jzMr#V1tSHo&Y7(5JFqD_xsF77@)+=KBEv~$V-H|eKu=RRd5FJTbR&W znK;z^SBu|+Bo-!8q7n+6hW;y^Lm(#uQpzB}bi$u(5BUWs&@qwAkKI220000ElR9Q225_%P>vh@=3x7DZ%uCu#DSNBf|$JVk5Tk=fng~+?O8{ z^G<|Mh|P&#Z4r|h=}#aw`MibvYK!GRXfb}?VvJ%fJ|c<{+piPwb7EN*Bl3@lFhB11 zaSGQQ(>IAQ&42S0F5zCHri?d?@;zd*q2&?g96Gf(kFqiFM#Hh-6<1WGA!4}F4}EcI2HvpoM5 z+a_8P`+vm9Yh~uTwjN;j;yrqE1Tx~#C#bF#DtUcz0f-SShPjaNufII2O~nm?Ja>ozO@9CpaD(frO!z{c$(1=Wej2?oG#SeT%!{jH)7Fb zOMT~O6 zk1w&7IIfXnbi*U!LT-Ys#BmMn5#b9FBU%L$cslhp*$hWCUSbz~8i&S}2pxf4ut}J3 zJ^6hYuDl~Hdj%E3`7ejsknGRVk{zfjoITHQ_4gWD$bsARy|3J5m~WN$)LO4U`PEC*2nEohBEtWF@D>Y` zrj4b>Np`dMVcvRj!Ol3_C}mqrC89MXb88Lif>1z-hAU%qf`6eb%%Ox%vQFebLD2so zn7_~hmkC}b_&Y6re;2&eLafCy@k=e%Po(TQwcvT8A~(!sVHXve2FtlcB~tWd5ZDbR zG)Ta^luOOIz9H;6#t*?qF#up@irds=4@#|0G*9<(jTB1$W92P8ZUE!+JO#zRh~h*W7)C_P(3o)r-VoV{HZVYv65%pnP=h;B1ETmO zYB1jgNhQ8R1OPtBMc4^ZB0du}JQpI-7KT!fRS;A{*T)3QR z{CXV5g`f!{olXTbqM6xebwblSz$}rKaKlT??UQZ<$mBlpAWneoV!nl3jG6Z$TMOxc x5!zuQg(#E|uqcqX*_2A?0FwV(n`b=RC_hzpdd& zn}=wVZJ-FqAb$$+y%uR71HRhiAZQQ=@vXH;dDa#q<_kJTgv%|$<7ll_#vr~EItg79 z(a+W=0sKZ#8M?biluDlooCL0k6pl#%O^X>nw!nOs;2|J^D59!TCrZJvCgxd01;#cg z#1)t<4BQDszb%tRTZAeIk%+WQwDk~C?E0S8Ex6AS*MCYZ$2EQ2N+Pd`&|5P@1pqxh zr>H1WToY~9fXZC^0sV^51H#*Q3!&6M+-jGRQ$up=7DQ|jL~S*+2itXNw5KH@s(k}c zg#pHXh~;XOup+Xw@$*Ok5eX5K=!Ky8=v=%LQ2*2spjqSbH_b^GiWxGDnJS7W5f-Zv zMRELSzJD2(?!Z~2$dVv6VID;lGNi?nDrFL7O(eeD46z}^7E|baU-F9ZCo!9}H0LCA zeYnCTrqP;lB?K{9Ro!~uXl9W66|u(fM1=zhC5QlKC>tK Q01E&B07*qoM6N<$g3e@iuK)l5 diff --git a/TMessagesProj/src/main/assets/emoji/0_235.png b/TMessagesProj/src/main/assets/emoji/0_235.png index 79d2f9b844fcd94fd189c4877da9b96e911bba1b..127b636faa86461c1ed654af69038e717f8e4fb7 100644 GIT binary patch delta 854 zcmV-c1F8I%2JHrrB!5m&OjJcja7@W}3e0&4)rk_?k|5H83C(#5#ehY91F3($WF z$aM_CYz+L#LjKK2{>M50%|iOYFaOd`_qrzXvK{H75ACTG-H{3Z)mi`6U-N`(wEzGB z4|GyaQvi(QM=R6(7XJOJZ^fR~HTS$_0008NNklOgleFTb}{ws#_Wxz7AHfwAlT4cqK`&fDglRLL0oAOKxE)d zOuU)sg45QXTYqfUcq!%!J1U(jHPE7Lh!ougLU<787T6HBv=d_=zqGivr^tjYDGdr? zTwowBY>CYW{2-KaaT?l*4uqvC3SqU@%E_*|$c#ZOfP)~z_$>ED6fQu4zBc z21-yMV3hhBi={XbFi;~CRAXpaO?4RbuGwNJitDN`nO9_3WJBmnCX8yBWE4&z8o{F_ zL>RN{CR8RFKpaRZuwxq$9z?xYka6JjT{@!fl3k`ab8_{&CdwDH2{16nzq2?hvrZbL|9A#dyW zmY78f(R(O4MW9Dn^1D@=WML`E5TSTi>KF$Dga{7C`!}BV0tS%GQ0PG?dzPX@jrT`m z=!Hn61VDuNLaeKh7^S+ebI+higb-hdur4eG7=QJ5ZCF+&5(UW4U@g2{F(&>op?=Zx z4pkT+8Dt{D$%!vaNF2T>8ZNhC>AGQ=gh*nYq5}~o&QULf7!IPL&AKkU3n0u+JoubP z#HDm42Z867wP*c2KCWe!2Z4+ufUAU8IuoB}PQQWZeuhxLrbYk%34M!L1X|oAqWK|W zx=%qcT$4A6uoLbMF)-Y;_lO>Zze9|@#9ffq&k4SY;C)Q%ROh0psIjQUauB(*OVf07*qoM6N<$f;fV!knXFI+nq-CjbBd33O6UQvk%{tNXpCmXu z4)C84?kM@lNOZKg_X!V1Y~gJp9zREIuoHYhggWKkCqi`F z=6rAhuin()WAtGO4iOM&Uj<(z{6>JZrHIf%%0|dJk-Seu5Ck{?)|IS3GTS>kBa$OT za;Z;(s2BmP2!B^vgv|!l+$RfhSVS)^Bt+_y*(QN9-w1{)M7kY8>csI(&=~;_1nP|- zBY^w~aabVpBY~a3IT7xJO^%HiEihgp;6?zl3Lzp9Hv$0nIS~<{4w7n{6V|NUq6|$y zcR~meA&F!aVd)`i9AVS9Fehw`IcM&NYNR*_fIKI5ZGW{@v#QeZ7^qb^&51UvIWuQF zLYP&V5UJLn7Oa1x5o}>j*ia#)S|XJZ5i@$?$);ij zjL2EJC|n|)IKQlwFrg5|_{tU?HO_9D7pex-79!Q?$;B8%3{wK_p;?V~KuW5iqXvkZ ztRyiZ^nV*k715TWWVyFM*(WUmk2TwBxTY!$gNQT28DWMsk>;qt{l7dtT)PniDM~*X z&<&*d5s%V{VL;m-yQE!}HOz>_2;U8;OoI^Y1CpFPw^m!p6H?@xz$s0000FbW%=J0EIrN z+WIH`{uaez(TB@!S&>cv00NdtL_t(|UftH&j@vK{1yFCYx?nmy%9FrzjTECAPQkW z-VoMY%KnZNz&Lc5iH*qxV@%3Igv-Po_Q>U1I#;CjPo z(Fl*0vKK|tHeR2?uX-$^5ro%^m3E1}3ynDfm;tGuu011=--Zz3FtEQutW37YDX38- zW-M3sfLzr09XJh6^-dRb;xIfa-h9V4n7)lUfNKCnU)+LBx2%m-#1Q;TUL6F9u z%ZM=<;yDb06hcDLi2I+H_j?fN08Vll)BBF0(PL^bNqTDQ!i zBz-vo*`|;+lNx~a&+@4af`nizrNq_+4)Sj^0DoiGRMWL>+bu(s%rk-$)2xQ%Bwx(H delta 766 zcmVqEOr>vCh*(0GWK6AiT8LOenPg3dRzZYQKfaA; zx`tz=ZB(>=U#@mq!;@=qNi;+&8UB=TIsgCw3UpFVQvhkXw36ce{Wcp`Fx)=?00Mi}ybxc-B#bRAgFrtg0s!crVM@Kn zLXkv6imHIV%n4@h%@|pP8__?FV>J-BIkA%UXpcf#Ie*jZ2yjazvekP`$%re$jFM+W zUQ??Q#hoZdG2)7_+!2)amMF+^PY4JjCxYUpgcl*Aej7<49d0=hn7-SKXC5VHib>ca z%w|}^{HCJC9*KsGyb>_I8W%#SUzgZE(yIaNCWK>D1dPyY`^ypq4+A)q2_Xt-kXtC} zhVH~;27dti$w{)P(ASP3lv?8cYd;B`5@j<&je#g*586S<>>$Oz9N7?!GIG-Mhs%!@ z#}H&>g@geH%#>$DU?YwpfPj`S0-4H;$YR8a98BZXL>9kH2|8z7kr6~Dw@kAtVaORn zh9D`=i6ClRfqD^WRp9m{e?E)-^XZ8D8CL_U^>+&VMDqC zSHUe0vJPV?P+x_xJV{aGK&~6svOF_FG6WAo0TZ6aB_dJ9!rX!9!gwi>D&xJX{S<=% w&yldU8flXD*LQw3DA~CXR!wlZEI&KH0asv7X-3BEf&c&j07*qoM6N<$g4+dIQvd(} diff --git a/TMessagesProj/src/main/assets/emoji/0_237.png b/TMessagesProj/src/main/assets/emoji/0_237.png index fff4bface18ca0c556a4d966d6b0303aecd5b075..dbae794299efb9d9952a86a73fa5a8df180083fd 100644 GIT binary patch delta 672 zcmV;R0$=^t1-J!}B!4qdOjJcja7?~_RLqlU+_8$kepSYcV8n=D#fo9Yg<8OXRot

    +? z-)a+^LcB~)>VJjvhA<=3H^I)@kZPfD`A=v zL^Dl%HDV|xawlg604bYf9Ou$@?*&n!%)x$5}{l9s7L~hiV90NdI~| zfx`QD5))QKR>cT5f+b-U+JB$;RBK0W&LBXm?BA=0gs64&ajRqmIIN-u@4eTecYw7= z5ix=q5r2~zQ=h{zB-C`I@>(R?+DybVUy$B~;GGQvsgKx*3#iee#9X2Sa4`%bt`*^O zEQ4sOgM~yaaf#6@a4ew?;$+}Q5aE-=FX4U$fgd1*K0pxtZ^EN65r3QDZxJz7 zZmH)9`?6;HiFZB$tJv?e^ND~J5wyp7BR~p6I2nn20sIA;#7DJH;$=<%0000few@Bg}s!D$n!!H6~7Ns823!+$$OY&|!6R2oG5oxz z?+LonqM$!~S%0KCp-#v(qGl&}Bltn^Re~nOSS#ZR(MAZIpa((f6rOCec|f;8-HOSj z7AdylixVjbGcmI$4I-ZXQSjdbASRnr098>{Q0gYT0B$c~;Zwq96=3N-=+z(=ty3Z^EPobZSr%oo^vQh@oVO6Q*pbzs zXWBD4%?W1l2cQ6A;r?ycgW~B!B@@P50#u|II~bBC1d5FlSqt&KfPD$Oarz#|-eM4L zc=k0omdRC>F0{584+M5CB&P|XY=Fg(z7J>QB2k>MkRuj=12H>@|J&Om7K7wLvtpPe zI>cVVW#&3>r;b&@?CT zZ4Dx4Oo(Bgr1IXN$IYqXB=L>m4OT(D#CZ)mA})vtkiuzjHTYXS#-Cw0&Nva8|;SYn^9L#g}luXxj;s@Hz#hI1W98;FFlz2_G-}6y)TL0`2>JbJIKT++GPF)|=iq$wN*AATKwJ z>2g(h1}LqeeSeDUNpg^u#+CX+a2ARInA$$JmGDdyK{qnC5Q{#GZw=GZ13~13$c_Ne zQmmC;DMrah-qf;;l0Dp~D0s-(qG6TB;lu+u+@R2bG z@Z{*zj41VGgoO!@z>%FGsV^hUNsV{PZvrdJnB$89e|BQWSwjB%GR7ytM1(I40!SwE zy{b)&i%F5p&`TeD5{&f+8s-?2B743JOwJ`WD%OUugnp`Bgkwa&ZUTD=>Lk2Ngg8j4lOXCMhB-13M>~9;$tC9GOa~FH li_zI?kNTg%(3kKH@C(%>RHB=d_dfst002ovPDHLkV1l}yJTm|Q delta 656 zcmV;B0&o4-1*ip(B!47OOjJcja7;xqEIKM9Egu>|FDNo295^T;TShxiIx|&4H#{mN zEFKpP_GfVb000McQchC<{-7YyJ8()BW10W}0xU^HK~#9!?bzFn;~)$MU~B`io%es= zH3Wxf&_WJ-F&Fz+8C6yNVG11R9kW#MaUYeM_8!tNPp=#nsLGNB;r}%)-n7#|yk7M2`2Viqt~g zRl%aFjfi0y1TJF&)H)L^Y$+VD90bj~P^i&;KQ~p6uvlP0c-Om@Gclwz1Zln^wbptl z7i?pMVNOsir3L`A{gurg0|I&8MVW*FA`I3B*N9y%Eq}K-p;rl4>sS^BxEg{hLQ1Ug z*b*L*n{8liyAfu1)My75$0U0fZk)MJg^{L&)Rx;+x}lvAp4|viA^eRMITh$#z-*7x zwOGd3KW*f zIvVHERbP&I(2O5Q7ckrjnbD9zh~Z{X8{$F(^uh1etQEO_ky>^fg!xUWC>|{V49}9# ql%74l`maGs87~p}JhZIt@qa$%E61ALQg>mt7o zT=z?^a|5$B{s{ZcvJY5YrA}Y~~mT0?@8+CIE}@h#(kSun^%`&WXb? zB4qNNiWZ4f2k7m41bVo`}yhH=gbmam2sr&)SA zS&c9wGM99xVOjzT0cJ*|CNOtEA3`86tkobigU2ojQ-6_YvQ#0`E7F{dsYuu4c49RW zE7Vg62lXUB4jQSq%usEJmteZ<9X> zk{T*z^nWX#8;PV1N~~3aSqPy~5fEZAhO8w+<r2?4=X(gUrdN9ip3`WB$+Jcoy>p_yB+pI{d9^+ZF%-00{s|MNUMnLSTZmcq4oO delta 1157 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 delta 2054 zcmV+h2>JJ&4wDd&BYy#3P)t-sM{rEhB3#pX70GZA-GvCudLPMY2CZ~P#DXrxawWrS z4)u`<^q(8(k{--(4#;W<=!q4gUMIE$0|Nv3H-hjgcm76_ z?~?}MB4wm9FSmUb&zm2~jvB^cCgY+bw<$kiD*@_CjkBa#)3hx)IXM^@7~nQ<;XQx< zp#}f+o&V=h|Lb-Cz6+OzTL1jP|M8Fi`lbKgLI3N6|E~xB(n$aNvj5~}|MqU><>UR6 z1OD7s|M-3X{(s&7`HKJj&;Rvc{I3@O`j`Fv_wVlP|K>K5l9~U+H2&Z%|LsGEhm8O9 zQ@6Ib+`>b@rc9BFaR1XY$;rohcXIcq5$nA(>Vg9Q&p7|fHrLkF=F&p{$u0lAD*w(9 zp`)n&w;=TM@ECHvod5s;7j#liQvm*Xi~d&a3>P?>?SIXazR{>Fsnz3z+S>wX!~g&W zOi4sRRCr#b(Rpv$FdWC>i76r(iNwVFv2)+|!F|*F?zZ=@ePa{Rl$N&JgYX|DzmIJ5 z?Z0(Dd;$KsE=q#ZmzlmINaC001x3CZ>iRRM53giJ_)0~>JR4su7Skz~x}u{ZeLB$d zbc|1{!hbePFas-EBBOh~PesHI3piPj=i~7h-@N|hrls=8hsTj*f+MK3%#Q^jjzeVO zbb)Qbp(U3$p>i)!>y30y1iDIsf@YQ`G?ixFWUO=DOO)=rg+B50b7}@bU@~QcN7)10 z(LK@^PZS&)*a2s@1RNfwb))-s0jKb(%{3W>uzxT%NA2*vMhAski;ilo&S8FJ;~BLm z_L01Cr&5o2kFI4|qdoftTF-NZ1-?gmNB^xjz(r`To4EzkbVd|kDA>Zd@aU0&cytV+ zr>>^C85CK;u}Q3a7{6wqLHL^_-`jT6@|uO zKB^v!%U_!d*vu}C>lBIhZHR+}Jo!E%DkADyU9Z;_VBywVW3{=D<9HIs_nVb*jhE*n zdGV(RH;Fg*!EsPvjkX74b`eh|e_%YG@PEd9nA`|2FLOA*yY(G3SY(OJ@=*BOiMcf; zjzv*;A`B`IGCJ4^a!Er#BG3{pBHC@g_&`-ZFmIN`2qVbFNe~MB|21pxb0Si0kE36u zj27_KT4$d`W4GCZ;i-c|ItHHSEMF|>CVDI#$93HnVRu_y$=~95yuTBMYh-|MBY^=Lf4dm_iEH<&r|$zQ?k=cV{Efnw&l!=b9Gw%xKp zmyRwUmy0$T?!F!!9rdoEnBH8@=gY~L=f&7y#e6oK4TS@+Lvl+!P~`jwe4TO=sqn`d zhT_V1s57%_S=GwJ&|XuZ210-ZEq}=3a>vf~Xj|2FRt1>chHXDin7@F<)Lm zv9l=@JFH-bspWDhok-;xsmiTDuEm%P=RA^|pA|8oFpUNaq$GD{-{SY7J-C^6Xk+!x z&&Tbj4o^fVA}*v@JUAYZ_|%Zu|g6?0=;qDHRWu zv&R<7(>%J}$46TQx2oNw{mnth)EV`fGlYn(itPD{IZYK~A=Dv;i_gQLBF170hoC*W zxkm^nlB8h5>Fj|}I1Xmw4Oyb%@Uh`Q4i>;L?$4G`93(MR!A3lLAYwRhcr(wFIiv)E zT95a=#b^pfi{5?T;}8egbbr9#;Q3%uDu4$A4r%eRTTQxY-Sm3*%^xtZA{h5K_--hj zL=)dJBMC0sHH!;Lf6#0W`afJ}ju6x%9r7=;%}81_@pBL^flrDrz#Gz4thx>vWRJ-6 zZ7Uq-CNhS{4i`zJMnGPN;SiWdFwUzf7XvZaVOHyNHn8OdP}1Sd>3Oq2YS3*G)maUa4A|p{MAzoP`=3 zA}&WNXMz~)FmwYK7~ab&!RkkyUNzZ(5ON-pFk(=ZWd#8=13>hWGCmD7O|PN`hoHq= zi@{Z5lcl9=jBx_W0)PHiV{}azlIisjU?a~}aNp3RLpcVDa-snG&S0@&E+?YK+Dgcw zq=m!O#G8)`%*6$tipK^U>cW5;w5`_JrYh2*3q^^zIOS6T3So!|Lx}gpPgQ(}g`pb7 zQieD^rBkU?#0qQXvmyWLpTGg%FVVc7e{^T5^~96^$xObv>|LnvUvIa92~I074XV0fL)fOLRb5eD#Co{F_3 zM+j027=FnH=911rl7u3WNE{|$NB}6Zh(LzW#(zIEZtrlAY*r}PA{9XqA@ciMkF8sQ z5J}RtZ&0kre1EH@Ne~L4#GCAfA&F~Bi5ti$B}I!v5dPoKh=E96JE4()#32vlM9W74 z+wXeR4S!M!n5Q69P(Fq6sQXTK_mx5^!;}ij{_cnVC9oeoE{dx(y6?~N{XwEpMTtfc k;p1#=gRQsXe*AUGzXO%>7u_7hjQ{`u07*qoM6N<$f?MqaPXGV_ diff --git a/TMessagesProj/src/main/assets/emoji/0_240.png b/TMessagesProj/src/main/assets/emoji/0_240.png index 74cabd43e2285b6103bcbcd29a19a773dbf2e52e..e0dc03266507646e0e379d959350218e3b3b5c7c 100644 GIT binary patch delta 503 zcmVfBw z00(qZPE!E>9n^oSM&CeiX8-^Jo=HSORCwC$mf3E@Fbo9EL(=~L7gsjv7>VUltRDK% zZVVVXFc?y_l~>og>d|+;}LOH67CjwMpz{w z0*@B335^g31Ajw;DGEo!+0!tjfM%LeW!Lbl;cgK(gXPlj+r@H3)C?hl$05cr3$KKO z!>q?VE(&a!j&I^hbpPEYVg$F?=?6?WXolsDVjA{w+>Ppl{kn9lnb|BUut6iO&E4002ovPDHLkV1gAR+L8bO delta 1083 zcmV-B1jPH11kebOB!5CsOjJcja7^U0j?3mh2pP@ z#eiAOi)6@zUHaO&{NKR$)3Ni*sQu%{{^rWomvH{+&-^u=r~m)}4s=pZQvkd&Q5JRC z{`>xwm+ZY~qb}^&4qOg>dY|3~mlz zAa=C>h^Pd5iZO+5!OYoBN+2ZcAgCvL+biVy#E_*DqnC}C>Fk0J-^7oF5CH*IP=xf( zcl6vv9*5vWlz*65SU+KuKqr$+5O_YP+EVBzkTm=wawUNEHnJ!&gDB6ggnUKF{{%+~ zBIHs|FJWgTyfrS8NZ%7f7E!{VMCs^@b3sDomqA^pnph6CLxFtpe_lPT@R&f!~(_} zk&~Eh&%u`28V5@WPGpw>Rwt1~>MThl68pYCBM8=YO^i!s>l{R_pTzU|j5CPmzR5K) z=LCa;kPQ(MC}JlO3o%>}Rten#G!SPJi1ZQ6;Lr)`KUWS~&OE}}dWhh%L@cO81d&KY z7ku2e*ndGxK9TU_koFxb`Nzg2$MZ_!c1dKu3eJT3aKlD+aFK#m(J@v2l21AAFvR1V zQ{6Y_g|MSBKSaB@lz613a$E7?0F>BCG{5mUZzSSx_`lyJwO>ixSDBxM+}7ml1 z1P}xg3y@ZVjaIis6#)D^t-*s}6AcmZ zIe!867bQ_(1wS(_CvhTbD8M3Ac(jvfN8&&{8-j?20)sYEhG5^kXonI+o-Y7|vxqkW zV(&^Y+D2P~3h{%$JV@-Vv7Z7{_R`}-zRl{DP~)YErj7RkMUp0N%MQAV_=T#eexE30^Os~g8M6apqHkkGBG?Hji6AIeKWf|TPDak1_`t2Z~ zjq6MY3?OYBmY19Im~K5;VE}oJr?B3-VqpLQUuQJy`Y2h~X|%Ur#%eki{0EArbYnc*yQ=^I002ovPDHLkV1fnT B0IUE2 diff --git a/TMessagesProj/src/main/assets/emoji/0_241.png b/TMessagesProj/src/main/assets/emoji/0_241.png index d1d0b1b0ee175a46e40c666ede1008ed4c87bfb0..a4ce37688a6eeb7e1464d59e2014cd9905224c56 100644 GIT binary patch delta 967 zcmV;&133K52i*sdB!5m&OjJcja7@*S3Bqp+&3y~rmJaHt7t)3d$ae|Vhzqu73Fe;; z{l+)yr4r$o3-GTR^|vGc(Mtc!K>EKe)`tnmbqlj$4gb_t|JGfeP!4)J4JHMylK=n! z3v^OWQvgT548{lcq>~MK{}=7< zTF~i@>_9u|pNmXp(C1&WWX3ri&)f~ec={w`4050ek zk6b7^5s)C<547k-1sl1bkBs8PT?sx&)Z-XrLAQbv{(smNvaJ$(iH* zkJvV07JqCLeO`2IE{pd7yBBrzx*@=bU7Mh?SV(wzWC2JCJTX)wBph~@lPG6m5w;q_ z8u385R|BqNo7e^=VWg4~{crn~>ZY?EeVY(Vs#~ID^7})G0&3{bZjFgu@NJ;R@^~zo z$C8o7Prnn~T8#lsaKenTJifLpHkHkYz*B?h(0>Go5jGch|$o**w5|nBA?0AFvJ-@ZqWom zU4M#Z&L~igiiFJokEo#YXl5X*QH@uVN~FX{G@aTRGfFio@~rVXIlHe`6R}Ojkvfwq zi1>EZ68kkcB{yp7y{#MGR${*fu_SmQ(Fm_#LLLsiO}gQT$4gYfrg6kL6XAxyQ?N;x za6b5cIG*zp@jNT2Fdlz%D30*<92MSxqCmp&bmyE&gBIF=%kaIo+_{@BB|lS2IluE? pgL&+R>Fk+?vE85zX-@w-zW{ipXY!%adRzbi002ovPDHLkV1nM^#+Cp8 delta 950 zcmV;n14;bd2h0bMB!4+jOjJcja7@pbZ^43B&6I1!h+of|am9&X(w%h7k!QYsRKkH) zw{=UiZ$`IuOWd%D*r$Krw~*q!m*vEuuUx#70000EbW%=J0K71jcH2<={uTb@ox?eu za8B_gusriBWQ^1p1SJgYcgbQ3-IzKp?n? z%7mLIj(`z@fPV-2R?k#yRwA4OzatV=U6MmC2ht=_f)Er+#mi{&XR6ZRxbBkYraay1&^ZGuLKl^=)_xPFW;&jj5G zfbc+^Wt(=QoISVK6eTc}se>I#`xQ%|dgLI~nkAAQh<|j1O>4wqfa}600dfp-K&hOoM0!3mtlgSo7?~k#Dr|~Be9~it8i7(h~yFz z@LYvYXWun&2(`)s2aqW_W0OR5Iypu|wX$}|t%|8#^$vCNgmssQNHh?|#&{D;*5A{4 zBr&LVM1Q6JTv!(X08PB_s$7Yfbnq$M3F)d;FVa|vIk!X!HhMw&#V7zk_5Zae>0v!0mQV}`<5^+f)bse4Wsx(7l0|hV^72kK!S7xbpZ^{1=MK}Q%X56_O`2R zbVLt`0#uuj^Lz34izdhDASw&Y4biVe5MZ^hk$>2f-~!r0dV}dEa0TUl(GmhxCF&*A z4p4zq;0kW>nF$rtIir9IQbfv2{D1pYLNXRoS&*EXQ#L)Hji8<&U50=7FUbhdpTuS`2lpd!Pkbl6YD2f+Cl!$U!|y3eMlt9D803f` z%Xo@^CpJJk3~2Nn@p&1#C;2cCTG(rXEMuaKoD@NRwMeJrWlUscBVp=C^LTD_>uW0I zFmf7`84zLGIFN(MU9?%xCvJ+gyj!!LPA~D>^6s)Q@NsNh*KJ#tZCh6#%j<6`nwjDM Y0FQEUSY+qoY5)KL07*qoM6N<$g4P|pIRF3v diff --git a/TMessagesProj/src/main/assets/emoji/0_242.png b/TMessagesProj/src/main/assets/emoji/0_242.png index 900a91c45775eeb20a1b079c885c9806d92963e2..cdfc4c597f7e1eed9ce3db681aee467786ddcfde 100644 GIT binary patch delta 786 zcmV+t1MU2r2&o2;B!4zgOjJcja7@~xecPme;H`-5!=cxmcig0Y&5dT+qI~z%vhKv8 z>ARQXv5flLy7SGe&yZ^S;K8|XNe;J0%>V!Z33O6UQvh$$vfx1eB$yIcvP=K~0+~rf zK~#8N?bhpV;~)?PU<2kdH}Jmy%kBWv+HED`CjC*Z_DGhZNPqMB1c;OE8*!n;?Um#p z$06<&Vm~x58L=KC;d#QzB=-C?QH~!Y>I;Nei(f+gC&CX9@NW?LCt6f_fyjNzKTqVc z?|X3B>cxRvVSD7j(=Z%PqpgY+W19L3k&s5p_*O zZ>>)v@f$%hb$5@DMxO~V0@g$hhY`sLVTO+_pxh;R3P1__HrGmn5P`5J>?}e}41ExZ zTVm31;z0oTZJC0#2dO0_Ld1Sy?L81H41Le*7Ch#NTYn?Q*nef&HUiHMMh3G0QR_~=}`6RG`aGl{Im<8PY7A&43{4NJocClMB_ z5wXI2Xn(#Ln&G6ghTxLug~g6yMN*_km4;%3tclE*n*nr$SfdJ^?_*gJ{v@nPPj^nD zt`Ao*!i?UeM-|&uIiPY}5e}~{)DTcdqqG@-DX)k~Rm?DE22_yQt5PsvwVu}^XPLt` zo87jIN4wwGDkf0MYr>J$xC&-Wfy=f|PB=P$t$zUmLr8IZkV2mfIe{)%iFFM-qCOQCC0WLGkhB}IyL+%W{Z%FOtvj#xyH-B3Di;|GYb zMhL0`3F#?->lW08-&hE#!tln1&3v+p(GdZKuoDE2nCk38zI?KSOMpRwRl&MqGZH?e zu@Y_=3*kEZ$bZ~7cH%M#kqP(-p$h?j3HsFE2nN<+L=3omX({GjVv<2@NCZl3MCW#z zH39^H$spmquSEQapk$+72&yaQ{^tUyjBML%bo`VE7|2RZLTDts?;=L6sab~vu1Lx< z0Zd30_DM)|G??&2j6?vu5Yq!;HooRmeVRueFB2;g0DtL;kg}s@f-q;M$e1=r01@Wt zY(z9*GIbDU0*?tuNEPc7amF^wMqC#X8~6~O35x_q2Ei>Mabd!S#N|E2M`B83Bxj|5 z(7aNJa9tgQS%s)uu$fh?Zem~}#FaX~u2+KV3LV5=MnWquu0ls9lA8h%>5*_m_%K;n z**?Tn-hWB@@rVeKloKK;4W11;GkjQ{s<3AQpf|Zofee^Zz=>eQd7p@}%HBkCriesz zBNDO-fv*YcwusT{HWDVZ+*Y(wgyOyYOc*B!jAr*74CtBvc+SaW#O7qklCkmSM090a8l&T-5!nQoMibfWrUN zwK$owVJ zh4djv*^jbCfd#6d0yVo3JdC=VzOMK00#FY z+{XNHjUP)ULk=Vh7&1b+BhKa4#;ubxv40_F6iNtSLE3mOBSl0?A_k2}AJTIhGLw@G z3@xh>AaffXWtrZ_0h>ia`UBmQ(&j=r$0!g)Zy&qhk2z*kTKKmAIQH20nX~VQGQ$sJI6ce%0Q?Mm8Qm?|aR2}S07*qoM6N<$f`6pV A#Q*>R diff --git a/TMessagesProj/src/main/assets/emoji/0_243.png b/TMessagesProj/src/main/assets/emoji/0_243.png index 92b87a3dc874910c8dcc6576f660da6452b40654..2b7066d271cda41f8f4918c278cafabc4e3bed23 100644 GIT binary patch delta 760 zcmVV!knXFI+nq-CjbBd33O6UQvk%{w`Z^Jy5x4jp@;~hYzLEG(>_3CRpFpf{6LBYagNRnOzD~rn-fnA%tH852 zHHMTzv?nG40_~gNlSH@?Al-68@Q`vNmE#~r7nm*)a3=s+g%FX5odCdnPS`G5A*p(uuoh*HGPr>22_Zy; zBvMp_rH9BlLf3C`PP8)SQn)YGNOceZc~0!=ZL1blrGMjdz*^xvC%jfmVJ>aQzan!Y z@2thbDCI*D?62ivpoDoBVpA|7lC?n|wExi&+~S;QMU@b5&17w{{l9^1X zsfHoyseek5M;9pjq>IR7<~9vmOko&Ani1

    RsqDFTmodAeMCBL-5Hz8TOBr1^>` zabg(Y=hH4}S7nPcA~V7thA|FR8eAYbd2Ve!$ycPxcY(t)%_^gf!Spm?i*q9QvBE^) zeVHff-`YSx7c?&?Nxq=)85nmjEoaG_m~nhL+i`wt>_pEJv>Lx7&{xa_4a%4ChW z0xm!sg4M>jXb7PreTs*$FBg-P9dQN5!$bGDTus;v5h5HX(S+;C{d-L;+<+}D&n2f# qN3?7yzVg#Mhm`i3ltMP(C+8Qf6;ZeeN+}Eg0000<{940KXXQvke4Y59gM{Sw@t&7Q~==Kuf$BuPX;RCr#c z)!AaBFboAyY~wXr$p8QBAXyM+LIbq7FM08aBuDP_V^WNM`hQcBL&W$e!T~c-_=DgH zm>FyNJrR`v@(PsSNDifu-idd$#v4dUWhYn&?Fnv7HdL&kyofjzCm7dqXNvNTjbM!s zX`IS=ibMUzG!VgvaE(YAZ30mV+z7=k#Vf(sRsvsy~bSof0gnF z0&WtlMD9a00)H`I9A~Krl3I*FBj7H9SqK|!yGb}DASeGKP|L~w4j~J=5|Wj0SBc=9 zRN8bkj9>tG5$Q}IkfNt(MA)v^DFNq1sQ}FSyZ$89qB9~%=ZtROsn`id*DndFo)Es5 zoy#`GSgKeIMgY}vjYxfpj7^B=^Qi>$1tMh>gF+I5wSRtiuHpWH0Z)laO2lOKZv zN+l@++eXx4R!v5@6Jl~o?DemN!<`U{PKhS-wD07nd@zC{T_oa0I9!Dn!AL^E1tN5U zeCsDEIAE57G;m=SexZJ=k(7W+@YEa;C3*iLmQG*{#FpnsjF*~X#Wl`<-m0#IC(z^X z1P?^0(0@^Crdpa3Q1!LalY=lWd&pe?#3dfxDmm(hSr9!fVHwl@Pgl<)(lV#dD`7zB z9k2!ZAAoLqf0acbqP)!E{YvzGkPHM2q1s}VNg0rrW%eVH`jxy9z`cM?LIhU9fH{8b zD!z!ljTZo-o1j2T|3Cj3(Jn)0IUp(-4IqM4kbe#qjXH5S&b>Gjq=Jvch3q!E!+Y$! z3AhRmf4pc$h%xkHmt+A@Ax(!#vk{wO835)k{Is*>F%k!Y6=5|T=8;F@Cn3-N``gFg z1fAvH#_>E6)UX@~TExl2H4w*bEN%LdB=dYXU@#bLy}zV9>?ghxx)<+l#OZ6=LSk%! z5r6#lvn=0tgvKkiD2qeI18@4855Pn1j zY2!R$H4Gu7Avv!?oGzp^HS*hO$^tBN6X2S$qEOr>vCh*(0GWK6AiT8LOenPg3dRzZYQKfaA; zx`tz=ZB(vyTC{#&!;@=qNi;+&8A(bI+5i9m3UpFVQvhkXw36ce{Wcp`Fx)=?00MpAf#bd}L&-8vj1wz=*B9O@um#{4s&~pRR!KBg%im|AZCg8&-IPPgi^=k>9G9 zPRQFt3EQ@L_YP592(Bz;Lue7d3aTNG3D>K*<$$1(#0U>pWan}dSgW{21Z^Ub5^%dB zdu;JJ>TCc`<9`+a(X)e;O$)H?*6jNS!G!g}iV|=%49Hp`XS{HxRcuv6A&@k4(LCMt|!Fa7!ez)q70Ih$|w3oM%K{ zQ>zliohU{&;))305tR0p$S8472nZu5g6yV*XC@;38mU8lxaCA(`fe{?WRyfGCKd~e zm|+PsB5413BpNdEO2G7PTnHw;FR^{3R|CXN2q)MP7)09lUzW&t7$Bic2<|`+N(-gF zL7jNa0DllaIZ5U&=-M%aQcK)_?I(d#qHId2F_6yKgLV)+J4o>_M^;4B89wRx!{x_{ zV+aaLhgbjxER<(N5GBqbfPj`S0)@(q$ZW)k98BZ7iNb!F5_HbEA|r@GZkcB7gdt}P z83Ly~Cjxil3e<~0s{(f?`SV%q$EPE1XIu@a)^|67!g80K)Ho2Z6$UWrh`Tsyh7C~# zu7X=0WF5v(puP&>iC}M&1G#Qk%ksTe!rBvDF3Zo(Z*0g;jv51Hx&QzG07*qoM6N<$f}!0|X8-^I delta 800 zcmV+*1K<3X2Db)~B!4GROjJcja7-~G962Z=I42=JEG1AoGg(AAH6|WCEG0Q9B1ADO zUP(PPB_2!fT2TN101b3fPE!CDe_F@?|2N>J{{Q@TF{af300Oc}L_t(|+NG6?a^oNj zMGZ)R!2kcfi}e^yAzMsyJBgi+b-3t(um38L!XxX2J?*+|)zlPEa?(>Wp{o96WQp9pw|2q0^FHy150 z8Dcl7vL=$x6qnas;1;24HgAVexgr^YyV%W!6~Ym{cShtR7na5B2)-E%*dZ#SWU&eY zjuGKOprxQ^^?!o6ps@?^#Q`5wuIg)#poTJ`FakT@Sbup1wMRrn6v7eE`G#SLih`FX z9wxF5hv&kdmo7@vlBn-o$CbrDCqyWvEW}_4?r@IlqSZx-fJ2lfMwOCKYD`dsyYTLe zRsYo}d@2brLPFhyWZGXf%#`=Sia;0_A?SWgEeWA2VW{0@Dv82vd5(ACV9#2J`dV$h^`35tc3qfT)CSej4&i#OurDkBu;P_PGCe0 zzn^{nILircB5lsTu5uR>p~3F#^8j_RF)`;8Cx08Cwn4wYj%FL?!U;a!uBFAD@u{h% z!P>OAAvR4l_op(ZA>(`8ZNr+YAwv{^GUHB&*G}4>qH>)mMEDtB8E~kQh@cJuP%Pp4 en;8P@RrEiUXgiJOXFtIJ0000few@Bg}s!D$n!!H6~7Ns823!+$$OY&|!6R2oG5oxz z?+LonqM$!~S%0KCp-#v(qGl&}Bltn^Re~nOSS#ZR(MAZIpa((f6rOCec|f;8-HOSj z7AdylixVjbGcmI$4I-ZXQSjdbASRnr098>{Q0gYT0B$c~;Zwq96=3N-=+z(=ty3Z^EPobZSr%oo^vQh@oVO6Q*pbzs zXWBD4%?W1l2cQ6A;r?ycgW~B!B@@P50#u|II~bBC1d5FlSqt&KfPD$Oarz#|-eM4L zc=k0omdRC>F0{584+M5CB&P|XY=Fg(z7J>QB2k>MkRuj=12H>@|J&Om7K7wLvtpPe zI>cVVW#&3>r;b&@?CT zZ4Dx4Oo(Bgr1IXN$IYqXB=L>m4OT(D#CZ)mA})vtkiuzjHTYj#VpD5*_C+Vmv z;+!P*z)tDI6i8Si1XxH=Q;bdGln6*fB&aF65im7?=F?db*N}|`V(aVJ2#8Y& z_)8CAa(~p!Z^JUR6V;>Hz<3v7<2-xZNrb5%US}nrzurVd!uaSsy@?c~@n?KYNUY!P zR1Ru*W_1j>HRXUCmgGhkXha4iObYr44EGH3a#si9@mL^wULKD}4k2WEv#1$}oT54k zV@@ffa+hC3T7ZB80WAXp=GVdjmP0&Th}03v`+tyaGvrhWKwxc!WWEXwjn2s*-}Ic# z^Xy!VA!S2d;GX$D^Xxkm5gA5 z5J;#uuj6LKhy);MduDtz;oW~d@k~@Bm4DP~CtyO}#h5q4H{(@svzsn&O6@UrBj7?H zPzWawIPEAAujPq&{|*`2)IJ&MSpZ_DZk}|Mh#x~xH&2c-?}iU+@U&V8`fhd|C8Duy zhr&n15O|KW5_^n8wNB8CbsWWgGvXFP0nl-j+p7^tpiXp@+S?I#fO^UJrPFBbXii0f zb8NVD*1%djb^vPvp|`jgks!n&0OBYl0o@22Hy~DmX@2>%u b@3#K~bZmqOgi}S#00000NkvXXu0mjf8?yiG diff --git a/TMessagesProj/src/main/assets/emoji/0_246.png b/TMessagesProj/src/main/assets/emoji/0_246.png index 9ef81ba0ccc72f1598ce8d5a7fb1cb44189ec4d0..3aef5c8d29cf623165d2e7a666384cf1352fa9ba 100644 GIT binary patch delta 656 zcmV;B0&o3=2&e^+B!47OOjJcja7;xqEIKM9Egu>|FDNo295^T;TShxiIx|&4H#{mN zEFKpP_GfVb000McQchC<{-7YyJ8()BW10W}0xU^HK~#9!?bzFn;~)$MU~B`io%es= zH3Wxf&_WJ-F&Fz+8C6yNVG11R9kW#MaUYeM_8!tNPp=#nsLGNB;r}%)-n7#|yk7M2`2Viqt~g zRl%aFjfi0y1TJF&)H)L^Y$+VD90bj~P^i&;KQ~p6uvlP0c-Om@Gclwz1Zln^wbptl z7i?pMVNOsir3L`A{gurg0|I&8MVW*FA`I3B*N9y%Eq}K-p;rl4>sS^BxEg{hLQ1Ug z*b*L*n{8liyAfu1)My75$0U0fZk)MJg^{L&)Rx;+x}lvAp4|viA^eRMITh$#z-*7x zwOGd3KW*f zIvVHERbP&I(2O5Q7ckrjnbD9zh~Z{X8{$F(^uh1etQEO_ky>^fg!xUWC>|{V49}9# ql%74l`maGs87b{%ix02(piR{9k@W-U=z?|v4nCiZo z{o%v+)Uy8O%Ja^v``f$dxt0Iv&$W-U#{d8T3v^OWQvia(RvZ1E{{A@K;%(Rx000AX zNklVnVWe!R!??kQbj(v40&NA0wNPAHND$5R3bb zkQ>wr?KgRZPDJhIe*mvU>2=>L*zW;nV=)XRC5r!AXaLXywIVXHA4K-wbpU$ILd+~& zX)UZGzChh;M>DhNL^zpESR`^}0x&#s0wJt_Sf~`3SBXyRDq13>kZzeJYjwQ5kOU#( zBwS-_?_rgYg?}eOB^l(3>URWOiC(`e1cBRGqytI>CD1JrWfCre^O^d7Y^BAof?Hr)5G5N!~T>h4JMe{32nQs80gWO+pS!u;HUbgl2sbNeCpuVco$l z5VgWdv?n1uozIH#Hfw~)JMRPRk zggXhclt`VekA!I*ga|xcCd@%Ny$HzqL_`D-q7lW@HC>42Tx6m*w?e=x5i|>#5fd?g zB$^ZwEH8jwe3(rM^8_vt5XWGm62Y5|AF?H@@@=$6w3H6Q6+F@@$P|V<;IqsALZIwo zY|?_BN`FGV3UiWix7$FnyuKlvO%72@rx2pG)^{P?=uiQpyT3IMdxyOSe<3*Z2cYY5 z3oao*$J;CMhb*6okZ}+QYyb$NtAPVs8u_39P^TeIY?6j7 zQ$d%5bRzxxkoho+IS5oj7!mqYNIxAia}0)+7%v3CDKHTpKN~ZTDE;ibP9b{aKu%($ zpMP(?@Z2Dh1sNJJA2f+E+?&_&X-G3}fkzVM&8=sy1R;2a2uk>Ouk?#?Lo^8@-rjod zg%INkND|!5ccE#_nM{P9^g9aS-V*spBWfDAkJK@Adw=ez5GSI7CSgClL+ooebn!D{ znypwUMYq>AGzqQaQz_##ZUPf_<^P`CI%t0xQIgQzy;O=CjS&7~O_NCBu@dfV2P0~* zpyOCH#%VC5f}XI&$aa=;0g@$QHN4q~m`KtnMypsy?0C&$6q6rcM|LLILSbz%*+2d_ dJjL79e*nadUBAqKFn$04002ovPDHLkV1n<&&U^p> diff --git a/TMessagesProj/src/main/assets/emoji/0_247.png b/TMessagesProj/src/main/assets/emoji/0_247.png index 15af129941ee972c8bc0df6712f1e774e9fcc64d..27795fc07af14ec7720f54374394db025329ed26 100644 GIT binary patch delta 1158 zcmV;11bO@32Ac_xB!5m&OjJcja7@W}3FDj&+l>m`kqXg#0p64h#dHqCZw%3a3Fe{~ zyk`ZrVFulh39wuU{>L@{&PD&rJ^H~d^|&PNuNvo~5dY9k|I}IEkp=(PWg9Cs=l}o! z4|GyaQvgHobg2HwCl6iR@4$A000B+Nkl3?>^C=3N)yn?rg)lT34 zMdwPGlV&`v$@JEz?T_#oArbXsjMiHHDb4I@?*1Z}+1cI2<_|;{E#k*N5Pfh=w3-29 z%;$m`y+tT-CDS;M((rnZi$bXUZAhsYxZGWfa`SWo?M+jk}KZ&Wbjzmm^PWAB{f%s2}UI_mp7^^P? z@x9t2@ye5+dZIar5rpGb#x9?V52^Av_0v-!Fi$%ZV4K&jko_ zzBQc`B82CjhT74}Luo1LE;;L5CiXg_>-(l$jol?ZC4YkD;-==ji}{Yg6!Sot-a`P< z2;t}(VeZa=D@Wh@U=b!-Pe|BQ>mm3s-VlvUW!TO;<>J(|>vMUTq;XgUy% z8_~3GM|^K;iR8&~FDIF65V~~-!UXNMf@o5JLDGo4e<8jO0%5;k#9rMHPY^_DY7(I( z*7tA3VSg#y5xR{Y#(4w>9{~vbQ;7Rrn2`w=5xTwbQjF z79-VwIFMb+fM5|2z7Sm`Hi;+<&40F}k9I%Km*W>!OUSqSyiLS__aVgRYA!9YmIB$M z>>qJwh(eD_Ove|1ff!?YE^kDa03A`S%J@;%7OroM!geb44$waLLmgnVSrn-I}sSr*Nc{z zkmcnpUPcC3AkP8=*Yr%B{mjIv6aYdlBMl3eaLohf>30602*r@>W!RkvtN!7l4e=z9 zLWr_MkVrRDY2`J#5RAM7r;y9|Sx{zS;(vHI07wy%-4U13s2{T?FTwJRn=c@eW#s*>?3wLE8&63!VW!AFbJrIOMNPk18 z?y^2%1Wz0WB=Q$RMH$i)7>wiuj+X~O;xg{D!Vn}U@(({Epc@s@YykP5gyr&0`A}79 zU;udw&}R{)CBLDyZ07*qoM6N<$g3IDARR910 delta 839 zcmV-N1GxN~3El>fB!4PUOjJcja7@ykcG91A)1i6PqI%r1is8DH<-?%SoO9Hpd(obC z*r|ckpm)!gZGF@2`2YX_4s=pZQvf)GR^$Kw{~M&n{{Q~$RO4j;00PxXL_t(|+NId- zma8BP1<*oBgn;k=x|fhZ{b()RiSxrXYuuawT05_w<-B*VKYtYj!~lO091?95;va}q zg>57MKiAs0fi@x1IshEl3uMH4CxBF|8ZI9R7uRNhD7zB@jM>j27M}?HAUImGGzIkd zgy~3dJ43fd@F2z+`W0eR!p;D_of~*)0=eDSsK;$uz;Y6fvk3;xb_=Knc>DC9(f0b;9)&Fj7CzCTd16xn@Vqp?iEM*+!U1kaf_^sQGZIlF)Ur4m zLcfcriKMGLIzoURaE+kgk`iLsmYF0HXVPt*dPm8KIDbRb3-%q2;2ww3w%AX?=Ah`{ z0mi)>zHE!=z{L*)qNXUJ*x*hG!s~*#L{$GW!C_zM=rGG34hU9s-Og91%n~?qWN!f^o)GGV_m8gY8H$sAI4lzm-gy;qx1VMx-_nXYI zAy!7{HHQdY*xkoB)DMK!fsmP~#OIsLwQdGs#z1ryNQJ`R?yX_uau!B{CR8H5o($U} zYUn{jun@(6f9i^01}b4=8(<-Jc=$vgt(Y;A=zqC|czWvj9^>7JmI4;yx*+$B`d(F2 zhGZei<5LfgF-}D)WSz~Y>M`=oFhT}^N5XxLF=j%x_hb2o7(!H^<1-OiVi;ja)*lgs z@IPNVk1_PB!6T*Q{%powR3mh2pP@ z#eiAOi)6@zUHaO&{NKR+xwm+Z51YocYHYSm8x2pW_#Z zGfs(|KuD*QO6(TwT=5tP4hT0AS4zS43RT}2D=A?DWni|m1zw&h7$Jy2*h)ME_3qaM ze2X{^(G%^&gnz;M2`dDeOun#y^Eqjy*iUfEs6?qsFxFdS*@>A6dAAbu6+s7qRWcE) zjMGcFc_)IiK7lCT6JsUXiEt9q=!m`WYQG>#}6 zi_Gt>5rWDHRi-d^Ld6?TVltr|1gyH4yG>y1YMBB-6@LVAl%R4;U~D~h&hS75q%zr#N?&Hjct=vOIUn%heN+c!v;Sl~5AmG@1}+4GeL2ah=6syw}J{ zhFFK6h=<4hsRF8`l#U{KukkQH5$+ju41b*>DRBy6TZbRBE?$gw5Cj7eK^OW{?B?t7 zrzY1n!9cLin;Lq!78vrFUXKNcUQ@Rdoe^(k4`$++Q{agv_L{{fOmb1kHiq!9oB002ovPDHLkV1o2u?2P~b delta 870 zcmV-s1DX8H2>k|-B!4YXOjJcja7?FhSE+JWr*KuLa8F1D1<)Xn3<&4`$F1Pw4Nqe`QJR*?gg06UZC{t+h=1Jcr|^L}_+JFaGReg8 z2ZBVVN#v_EB7Ov(EF^u?fgF5=vNR$*uEeQWkSz{Gd;lepNkrX&a6y&sA~CccGVKV= zM(8GijlyY9q_$%BB~e$36@5>55b}@+dxED&Srir!TR!vyfsHHSZw__L!idxe(Yr+G zMD!z(-D5%*B7Zc3pAxwe=tW$J_#GkY7ovSwQld*~%)*G=3A+gR&IOWKQ23U`aN5{k z6Eex3*p4Y_`xw&|p(coAMmL%=A2&GXa3>6G@cxx;8+tbOi(kT7NrE|6klNkVO|5kN(vO|1S|iAPX2h z1W$CL%pYz&8q&Z<;Z?)g`*iEYun{nZ0P*qG^F|D5jDi(HpNN=tX>5q%drzW#{vG1b z4G`F>*u5q(TQ@%j?Hh^*FDoSRv76{9y3s2+eyJsaR$P?Qh_ittP{&2kHk2VU>bUdw z-d}b^&jL>O{ZdB3h?1@W95AG@BG~{47{?Ps+XGRG3GViPnE|Er&<;Sj8Ig?GjDjFk waUTgFmLdXxXW=}h6lx^$4!{=?Ykb`O2N*{{e`8j~&;S4c07*qoM6N<$f(xO9+5i9m diff --git a/TMessagesProj/src/main/assets/emoji/0_249.png b/TMessagesProj/src/main/assets/emoji/0_249.png index d245cdc6fa0bcf5ce177a090f193c78b6193544f..524c53ea782bfa63550c3c35e14fcd8463b56471 100644 GIT binary patch delta 948 zcmV;l155nU2FeGJB!4+jOjJcja7@pbZ^43B&6I1!h+of|am9&X(w%h7k!QYsRKkH) zw{=UiZ$`IuOWd%D*r$Krw~*q!m*vEuuUx#70000EbW%=J0K71jcH2<={uTb@ox?eu zFX%Jkql5}1HDvaF!(Q!VoM`PiHM@PX(0v( zUI|j77~<4WW(6dwz%#mwut}E`=Y%4YS4wtq*ob&NO~s~zKz|azg#V6+N`T{mK+uRP zgqtTgU=D%}6o0JMGZmYa2Gdl^b(qFw~Sw*;h~IKTR0Ur3S_ zf*Mh$iMFpRVPt|Mgn>Focw=O-GG!IQo`ksw`y`+qjYfEzpb`3zABYm9evFG3g6;%B zcp%QQ&Ho)`&-R+41coxTu|v7uVhL0^OsF+WBs&oA_kX(@v1Y2U8QJI?!Nj`}Z`osy zL{P%pt9~UY999+dsUrwLp!HWC5#&J<>?E-mAqcw34TwNYXqz924O!61wTeb0mxO@l zDttQcT>~uCdOSz~g*x`wBoUoXj?qx9qOshnnCq%{sFNqG?<0puG!VtccoR$3_vt)p zC#ZHrrGI{3SQh{QO}uxNI3^|?+=M&f6Z3kI#!AfD5+%eK1cGEo0RXZe2&V)ZBo!nK zPz(C=G|>qlrq$kCA~*|;=mfnmici!4O!*aiB4z+OkdB}(fWf(dIt^k^!YZA(Cn}*C3aKn;PGPqn4%(|DRM4o<2oXM=*|PS8j2nSg z#3+o}lMtP87o>=BM~>MBq8G*@me27S=w`f!Wjqw2TYMnKB93L`ZTX2q?# zJjHVv2!e5`C z2H*w=A))X8yd!}WwRS~KoieX{{SDOJZM!W9A#OiaOo;g>1AmYTl?*=+OjHU{`0Dcg zB`Hyezv)0uL7_}Vi3}eLNK`aE$RhzCKulT)Pee?ZmwN(PLlB08NHCJ|I-&EBC!vki z5yE0Cq!Y;rOwLmHo`~4<@TY{2cneqzTO>e`u86SO&L_gI&EFCEND&4>7=I?@QvxQD z>@5;lB=mfmM1L{D2Fv$bI;HRpt3+fD@G%iPQ7|p*0@Dtvzj3BS;&M)hCC4EsA-XKcuTNo*@fIl zn&Mm}ft5ha@El^Vtwg2)S=;%JNZJ%cN!tstJ3_>uy{YQa8=}=DX0a0c2!fe8?N#0y zgw{0_d4FAyv|A2Cq*ndKh+)tqtj>f6-v{EtLA2vhaH8shTm@-{Hy3@115>E*ZcBSp zYloaD_VXA48Au1f++Lf}Y^W<3!s2so03wjHl@y z!n=7{x;v)vQclF}CWhxgxezMce0g8RaAL2we?yWl%FH4C;UV}&u#WCW46$Q88L`h+ z+-(jwoDmbwOL}?Fx-sYDAojQ|7?Uu?pS%+*6{q0=T$szTY|N_S!lIE(m`GjE-~}NM zqck4#YYyu`M^dg9zzzjq`?z8ZoKnguG5_>W3;_7|@_(tGJwx~*1RDSV002ovPDHLk FV1lULdjS9d diff --git a/TMessagesProj/src/main/assets/emoji/0_25.png b/TMessagesProj/src/main/assets/emoji/0_25.png index 9f2faaccaf0d31de2720f90171e0d23f68321623..fe9fec19bd803c5ea6dfb6ebde5f59400a48980e 100644 GIT binary patch delta 2051 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 Bv>*Tg diff --git a/TMessagesProj/src/main/assets/emoji/0_250.png b/TMessagesProj/src/main/assets/emoji/0_250.png index 7cd379a5e67c8ea3ce278d93af0368e4090aba8a..86e7cadbac00636b79191ebea866d5ce79567130 100644 GIT binary patch delta 1028 zcmV+f1pE8P1)2zuB!5CsOjJcja7>qCOQCC0Wo7@L>=1H^eJ z1hrtoP@xoV3ueJ@R6<%f-q^CZPj)c}B9an*NF^d>ZcZUzKKL#`qCiioVz=Te60tyk z5TWap2sh`bJbyP%5-JIqiS!L&l}MljeY!sgCe2-sSfctmQm%K2K@MU;qEPaaxVfEf z&M9H*!66Z2Jc#@eL8;EX5Y#Kz`_Dz98r46~#^w(R+0JUrAcRFC##=;hEe#uxz!hLT z6Nw0I;adXG)nFnL(G!u<3o$eZw@_^`$J5;N@iH-Iet)uBgw)Pfi2}h5nKA2-NJO~S z-NWyI&Cqxh%L)mo{4=&Vo9--HsO)L$U*Q(NbH!hAhE}oa+4T<3XFdOom<$<1cadw0Zk$h5zF9Z z>ign<5)@XZW(TTKEkTP6B;^!UGIY@I)};ocF?c<1eDyAS01O zkA$p3;635Pk}=j?j)Vy-Z!27>f_g9iCiFupjMi{&Vwp$_6FUZ1tdC~_8(j0C&Cv6t8j45=P$8o*n(keU5M(H%MHEni z1b?Y;jh}>Inf?DiycFY*QZi_E zE3Ie}M;F5e%V1%Fe?`cQ{$(Kj93lJ%!9O(x9t7iytP=V?Ab(0)UQh@RP9k+Dj|6@J zY29b|Mu-~m{xt+qu7uRZrjZ+s0X+!4G~0?aLP0!N*{5t0{z*t9c$csbqO@k41a{)w zSiU<5S`c(0xUF^xx+mm0p$`d6qBOz`pA!_TT_Rgwh^_(%D=#I=)+LGaj|HH_i{ER} z32B6B{te0&VSiJCW5t^-q!BK|?XC%KEt0TKAZ-%4^IVK`wKZYUVnVpZVnw)JTbSW# ziMPd?h!*D?8|oP0f+*3#nR0^;)7d4=JvZq4!W0(acfv@{I(1=_2QGp*A@)2k!PK=dSKDs9l^^S^_=y*O<|Pb0XvRZ)h6yMMWvrIExWUN{KC_Yz)HkucD0 zP8iWa*g?QZM5=+c#EoI*RtX(%up5WZOny(8Rfu6yBavLBG4E1fF!&TYbw}7saDg$R zK4xxMlyHR46dD2hqXf+eK>aXmE*ylyJbVGBH7o^Z*fx&OFoz%t+(o;QKq^roCNW&d z-9v4|Xn&BM-$5YUrXP7JCFq>Ug@{?d>ph_soDorW&gkAV6^vkX zc1Q^2gz#2&%Dsyr7qOUL1VPEyh-h78tU^4WPbHWy5PvbD7%)d6SnH=}3)=$|o)QI= z2yxV}1YIU_BbtG=6D9YD_#)g1F*zf8{f%(=CWL}hqUw~}JNYROF9HHwBtj<~HenEq zAQW97W+T8?TM4rxW+_NR7kc4Wuu~0SYYNa)b429m{Z7nAV3>u_Jh#L+)EEl3IKMwt z9SIMl%YU~7e-LvaL!oXfsY+1M+e%jsVKeM=GJz1+aCEBRz!tM0x>~~0rv9gE>k(mH z;{HgOka*NDg8hhe+U-^r0RYmv%-bW;`$4kVzzCEY3W#7pTGwUM(P&4qA&9MjE+G<| zV89Y~vxf|ikY?y| zbNC%w-vw;K!ygY?Cv^SW=!aw>QXx)NM=|L1TEt1;u^&9Hr6_QNtAwW4f-&c_T#-j68pplp>wg_Mwq^) zu74oLTQGt*pJo0|%u537b7F!aeZuX2_`Z`B`oyb%g#ES<;cOc=X~_%=Y6KGCd>b|< zVgT-y%#THt zkwq`-JIM{%k delta 1304 zcmV+z1?T#-2dfH@B!5>>OjJcja7@d41=)=X=AaPYl?$|E3C48@=AR7RkO{kL3d?>8 z)rbb!j0o3?2(DTUpiK{=PYL`|&P4ywO8mkt_`4+YvmEZK6aUmx#&HY( z)?AU|sE7an01|XkPE!C`a^uPzF8=-vL9UYL;&7U~*NoxV0Dk}kaY;l$RCr#smRon~ zIt+w~b8!+NfaGi7|NqXT5plE9y+c+{*B%~P9{gDvjohC8wFYBM_bWo%u%lf425|}A zd9K@Ev{ADlD4G9{7%e&HT|9pQx^WzSgs3t(?_FpL!PFr%-7#PoyJ1C$z7SOsA~lC~ zj7^BkO{3i)hJPk_A*S(Yjx~8tb@xWFBcg&BGYR6@U6WP^$DRp@rF0XWi1HEQoM0hq z8QnDyF~tRORsg< zAi5rHalE#NiDV)iQv`d_vLuydA%q0@N42mJ9ZR{x27h5P5pl?u!)%@-LAg=`3!)5! zLN><>4g~xxGjIz6JVDrT_x7?F1|#u4AY28}X>1vYc-5Mv69Xc49NK+0JI3S(NFE}+m!-4|Go{7B7ZGG zrC!=;|K+*of&k<@p?H~}_tUO!NCpsV8C!xU-fg2K1Bms&)(7hlh)9v&F-KJ;1kpS-9=|>u>`}ABj-SJreR6{%7?hojG8{1DN{0A7no)M)$(&-5R O0000Nk@F(Mo}C?Y*9B{?Y~H6|WCEG0N6Az4H@ zUP(PrJ2MpkRU7~S019+cPE!E>{1$)5r8nSOu1<1l0008ANklh*_hM@NdSrQmAUbf;*h!x@dKg6VMRWiBY5^SOXIj;V!&8Q_+6~ zjGsyZjF3<_A({494KwAvup$V?MF_edQ>a2HN*D@vo=T!{Tb|=x^w@}r91!li&Ir|K z!eAf*Ie*|m9FC{?SBH}HK2SbzmnA_W6$P~`v zZR~}25E1{mh6lV}DdO0R>6GA%6>{@o{a&@)t1w?DiV1$k7X}%E!DhhXEei_VN? z#)4buyO+UvQoeRiLyR$P^EXUvg240N5ymA(grNeAF@I-i z5=0F47vaPJ*7O0hF*k@4W6aU^-EW{fDI%p*5muuy-3WOnZG!QM1-6Z*pYDll9tK5( z)VMf-34O!>sejIbc@ZL17Xw5tOh>Jcz^NcY2w~DM)N$kvlS&zt8s4T_sNIX9e?87U^|;J&XT7Vr3kYTny3Ay zArlW2jCx3tx;G7?p1FX-;|=GgTC=_>(F)=OLWJPP`>{@3zvd|jI2oZdqr326`J3_9 zo<~i4CC9wsSZFy4Vkii6d&L1y6pq*V93iuGMq-wR%(pWMff(U6^K+es7U5&ggs=|> zR2Xhm%YQ611rgz7pMrQeA(IDS8&>nwg(X=*jL3yNo{$$3Lc^Z~k*Pl`Dq<|vJ>NGg z2dbB*alB!qU>K3*!^x%23E@jl5Xl?)GNz@;O{Yucs1AWxoVR(r@d7cVuS3Ym7wG__2gCgijqrjs8CW~A) z*y%G+wlRA`WPzki;@5&$+izP&`{@!W5<+ZP@lTNYN{GxoT}#nQB)P?015HWpB}@4$ zqg6#rTM_^Opj(d5K*7B{qzfWNZ7v`+)r?LE0Eo`{W&b#9WCIaO1zIo>M1*iJyMY)| zfPa6Bi>ku~DJ7InR0HK90ErD&!h6||`Riz;R5mUSqWN_3oihuYda2fbM9sFU#pA&?dk z0Nk=Z|Bs`HYb{+9tq%NZBVD>7ChA1oPDW_fl&P+SAXz@jEZo+1j+9Xe;HZpe?GBVt z33cR^@Sc8jw7!uT3@Mj5i6Hs}fS$_eXx<$H8)50Xz)}E88GRcL1;T<>h{)aOYhFIQ zLxHFe5akaON;mqY2&0wbA5tOoW%jpg<(j#VpD5*_C+Vmv z;+!P*z)tVF^*24DffkjV9t#P@&E zv&#~V+8R7vX3|b)`21Pi=5$zt(8K9ZrP#WT>Mz0&EY!&VKE7Sh34u z$|V1z10xfF@Ua*qzCVfb1xiCJ&O1W#FQBPdV@n(wu~b4a?{(jSD84ae755ZOo>aXX z-AN1)HX6H5NPjGin2@z$=p!gT5pVFeK`F)x3)^g$TqHAKN9#lYa=-ma9B4rZvOHG7bW*r2z5x zwvE`Qq>c$3)iV+Xo2VXRqidgv?jbA@OC{9$e7og(Kxj&_C(uHIv(iWS1Vlb7y?q;i zpsRttf^~cleNGlqAYq9RU?D+GF*b=qA|Mfwpr+`JfT;mAAI^$6hiohmt*_%oK%7dz zUwR0Wqkm?;4a>Bhs2KJfq$^kbl$&D`1hzv-W6!bGNTrfPDhktB0Lr#?d1Xe2~^I2$UbWZ;HP0!gp z&(6gdQa02jeu*J3Eyb>~W21w>!87?xTrPxoK&~8f&C!DgRT0F9@IJ-_A7^E+f{!?HKhUI1dIZXR@$h#x~xHxG`o>xK_&@U*rN^xf<_N<^b= zhr&n15O|KG5|0=!MV+7->o|&gGhz#&0O&Z%<<*EJP$xP{J=zf;0QHjbQ>W3|u}&2U zpt9lASp%bX>;bF^gx=y}M1l~90EnZI1au>8Y(T68)BN;p$w3J{F|0|8p(Xg9k&<&R bKW+a9bZmqOPz!`{00000NkvXXu0mjf<|YL# delta 1100 zcmV-S1hf0<2;m5jB!53pOjJcja7@RGVaJJI$c<#rnQ*>c1_NeY`S<( zv~xk=wvXe#n%Jm-;kuON!=OJf5=a0501tFhPE!D}`Ha^&UHu#U z{&d-+)!HEhkpKV#!bwCyRCr#snCouiAP|LXW5D>58Nl!VtbaQev6)976EFBTO~t5`Kelm}|yq{*4Jn)Zf_fu~tIB(4gM`%u*mk&K0MVumZx= zi?@AKLuB#+CnA(g$m!nw1TgtFNNp}G8h;yMCh1G?2?_9Y;l&i*rt69(Xb6!Z98}gV zVt`tu3+93dr+0` z#LsEYv!xUY7b8oa4`_&45%6()gbAi_*4Q$9mTB^>-hUroNB}w~-dg}(5J-yNZhq~& zkU@r~Uu^+Ie@1Hv&~Ca;t+h{lPParj+pcIQ^@bEa-cRn6roGyhaEzdljx2})bHz@* zLln!!S&^-u4)SpvSvyh>V!-&R-hO0+)p|s=|2HBLEmwGSE+|O$t6F9ie?*yvi}<>#8G1uA9h}T z5X!@Ud1w0zN{KNp+h2id$)OZLb5Tt)HzDFUB`^yNNTazh4H0D&P46V&6N13fRLFt= zwts!Ts0K4MzBi$;45Vv_hP{j7#VM ztQn2L1Z%MQ>w(qO&p8o^P&wXhL S!(X2O0000b{%ix02(piR{9k@W-U=z?|v4nCiZo z_tdie;luvs%Ja^v``f$dxt0Iv&!qAZp8x;=3v^OWQvia(RvZ1E{{A@K;%(Rx000AW zNklO{oQjRid zGaiWw-Ui};BV$8mg&L4LafT9s;t~ty>&;_ht=0REbR)bV^H#bCc^y5Ll5^ay#OozU zHyUqUg)IHN6OaK)!3?*VsuvprL2ydH8j(vk&VLMH3nAS7rhEzF*#KYb>(#J~Y)DK& zCRDhYpthUg#9%~(S|@QfQli92DjB@l?h%eenlT6@Hi!i2tBC`%ui>BnP^TddWJyDo zbs>?2bi)7pkXbj283cAh7!k@_@IM_gH3q{9z=a?>1SZ_}voZ4k>1UxLO9dz#$VpWH z^M9@9-Wx=+z%qiy??|Fn^Wk-T7}AVe;7B5Vxb@VPXb2u5LMQB}SNg@cBa%cTKHhrf zM2K+(Bnj^3r|4oeo`iSXN|>V^j0^+( z7{{VfPX>nw{e&$>(6f{a;57@2VbzO?f%qO#^(xj8UC&w6sKWMj1f!geEwpwj*zJGA ca(r6w2LhK}xpL74UH||907*qoM6N<$f`!S|egFUf delta 1158 zcmV;11bO>}2%8CzB!5UyOjJcja7=SaHH=$Dn`cgdQax!yFP&&lp=(iYMlzCMNQziP zUpy&PH6og2O;9r-hgU&xNHf2UXS#-C#FlTgeO{|{Si+NQ#+h?9e_aIt000qmQchC< zSCYp(CE)!L{jqe~Y^CG=r#oJ4000B=Nkl2l*B5PyVM5*VS&n&I&Kzv<3_ zP*kx@WmDU6rThcFOg9acKmS|fx~}$jgdx9j?0$pjA>;s$@fS88jL32QcZ6}7g?$BB zW5%B$QqCa+7!JaUfP-xV#`>4Kq*EM-H3rhqoWl%=gZXNtPBB0rVl>SN1L&HSeIk$wVjL9V7}1_0 zU@r(U0tN8^CZKPf>Rb+TVuWnU-0*4(@HsXcS+_~SNd?h4V8yA07|FjlwiS^T(WlI| zQs3<6#1V4t-w-iy6pb_0mEt6Fo`eunwseyj&fFTXUC_&jH0IPijLYU*)0;K7#P{5UR=Dd$N8SWVXZ!?EM0N39k zQ2R7Wp7lab+IB(o$OOEpw`|Lr_Sw&#w~?h+V8l22W*9Ui*GEDBz6C1AtrtXK#ET>_ViICj zLP?kN?XC@#Kxx?k(u|NL3SBJ7q=?R`FH+jg7bhHOmed8o4AqHng6JL~BO=C__U%oe z>3=CPRz?=-+e?RPdY3D}xqZ0=Dt8TtjZmh@Uj-P`^YMs6P=Md-6tx(&LBqfU5tMNS6dSI#`dt_@ zh3bX?c$E4k3`MA}go3!WQJVn(=Z3cg8e(qzn{*vR>vSkK?#ns{H(>HGLC8i5$jjPC^i~SqA<#32T^@4#70YYaevHU zWncmVf(lV>G&S!jMl2Nksu-gq8*Po7Cq}IM^hcCxvzu0YO7T>RsmSg6P_|_j@5-L! z_*3L7p)I@Z{@h3(1uSy~v^CDl?n%y9?Tb8>KY?`HvY%SEnE*eQ?dEM;mSx-K&VCBv YFG_}zQkk7OnE(I)07*qoM6N<$g3F^EBme*a diff --git a/TMessagesProj/src/main/assets/emoji/0_255.png b/TMessagesProj/src/main/assets/emoji/0_255.png index afb0b2e1d42a10c6f50853250b88eb23f06a1b60..15af129941ee972c8bc0df6712f1e774e9fcc64d 100644 GIT binary patch delta 839 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 delta 876 zcmV-y1C#vy27?EXB!47OOjJcja7;rmDmp47EFT#)CLb~+9W*5#E+82*Bpp~oIb26O zPdYQRll|rZ000SeQchC<{n;C^JY@QasFVO800098NklqW1#bALK*w<%xX2iZjUwEyi!q?3 zny*EPcz!f8qd^Mrr9h}P+@%~X?3YrWh#rU{2X`Y`?p^RN zSu|1J8G*t)(s)30hJQn_P$0z0%4lUlIU_E0X*OCzj!1Urh-hvhE(kYQ4)gBGcMG!t z?~WiZ3y*{47JtHmXfg;|;@J#qogrdMQ2KC_j)>-nHpkJk&=>oLBghf>h#-);T_VuG3tOzzT_xUEvOvZ_Oe+{@zbAZY7BEE0 zOf?XAdwKQ)obxcAi3*w-<%%8~!G8g(8QpSyi1#Gag#560VxIPd6f?CB z=rR<2QlpIebl%(y*K}iHia^Ty-L;V=0k!P6aNkP_xLX=$f_j-Z>#v>*5vg|MH)d=B z?&U`9)6eClK&1`9H|V-5?n#)JJ2O7g;7iL$?3F;|9uo*ZpjyUWtjUnk`X zgJr?*cwv`_m2ngehRm=L=wBqdadHFXL1065R9+dN*Cp@gStV5f5d8=(guOCWSXCDv zwhT)3MyVQKvHbSG4w&jqNcr`9<qq+l00005`C z2H*w=A))X8yd!}WwRS~KoieX{{SDOJZM!W9A#OiaOo;g>1AmYTl?*=+OjHU{`0Dcg zB`Hyezv)0uL7_}Vi3}eLNK`aE$RhzCKulT)Pee?ZmwN(PLlB08NHCJ|I-&EBC!vki z5yE0Cq!Y;rOwLmHo`~4<@TY{2cneqzTO>e`u86SO&L_gI&EFCEND&4>7=I?@QvxQD z>@5;lB=mfmM1L{D2Fv$bI;HRpt3+fD@G%iPQ7|p*0@Dtvzj3BS;&M)hCC4EsA-XKcuTNo*@fIl zn&Mm}ft5ha@El^Vtwg2)S=;%JNZJ%cN!tstJ3_>uy{YQa8=}=DX0a0c2!fe8?N#0y zgw{0_d4FAyv|A2Cq*ndKh+)tqtj>f6-v{EtLA2vhaH8shTm@-{Hy3@115>E*ZcBSp zYloaD_VXA48Au1f++Lf}Y^W<3!s2so03wjHl@y z!n=7{x;v)vQclF}CWhxgxezMce0g8RaAL2we?yWl%FH4C;UV}&u#WCW46$Q88L`h+ z+-(jwoDmbwOL}?Fx-sYDAojQ|7?Uu?pS%+*6{q0=T$szTY|N_S!lIE(m`GjE-~}NM zqck4#YYyu`M^dg9zzzjq`?z8ZoKnguG5_>W3;_7|@_(tGJwx~*1RDSV002ovPDHLk FV1mi!db|Jt delta 1134 zcmV-!1d;pF27?KZB!5LvOjJcja7^Eo4#RT^;Fl85f(+%K72lQ-(SHNSco5Bi54U0m zziR}!Wd{GuLHfWg|IkeS$T$DfSo60e?5r8(pb_1X2mjY(>c=)Y0000DbW%=J0I7S3 zR_Dt87dX!DryEZW6aWAN;7LS5RCr#!l#6cLFbqX&TehUcq<`M||4$tsj$k)Sw5`Cd z3m9mvQ}XhPU;jmZnHKjm!U_Ra{{w>C5Fp_81B59N0OC)|m~w;wv6wIC{Xh2+AP~ZA zId6Xeam!-d1+gMXBMZ42U~^;lBj9vqctzm4W_}kxteUOM)7j06k(65#OR^ccU&a0E zUlCUSl;;6r=6?Z(n3vP96j5vuOUe*YwehEE^jZo=dK5wLVIwPEa-^{!VYN8|zs=Cj zEQsTOIgJI05lqVCkWPg@gqWvOEJ6r?tsxOGk8;udS2Gk5JAxQxeB1oW^#b;>`WitH zHHw?lIN%#0c>K#HDUfa9U}2p{*JE)D`xyYAW-LYhwSQR=W^g6RgSl$&tLq4$r?f2D zY##@*poD5g2$Jz@EE=*EnaCd`0f^ORINb%eDS|KAcp#dpVzv1^U1L!du?$j$JWkt= z{os!MkwQw?iu5rU$Wk+M$@ZLaUm&FiA#&hlF}NY7F@nvIFljQ3B67o&0^s0=xV0c+ zln{j!G=CXO4v7wzC&CSaS+tWH6Dh7vC(U-&76}oDmuzM;0BXa;-^-$%1QBZk@nUpC zd}9}&SSp?exkzGzAZi#RG)71av=!vsY8=Iz5s-5T{ql{I5nIEc2iF`!Vu>LD7liZ1 zyWg6j87Bh!0U*T*DqhOTX5PzAF81pzI`U-GUA-sgxT+OhI2+_94 zhf`vX0Oa%2J|qGoBVw`FI<|^3lS+sOBUF4|5v%V60pwiT?k;{Zf`p7n2SN(~dSWb- zJGy|#=S!*WW?pWZG$}2p1wv3EmTe&)K?rodwq|esWh7F^vkFi`7m~>9PO$c7UPi)h zkbjaA=(#{-+6O@Zb9bVTL;{*rAv_5Lk=KDHf|PJG?lt1v2@^Ww*~iX75*u#T6-I#R)|rF(pC8(wRV?Kjpd2a>P3yuH+v$C8MeL1p4REst8~^pMa-z|JUyR>)-@TS=5C8xG07*qoM6N<$f`Zcw AcK`qY diff --git a/TMessagesProj/src/main/assets/emoji/0_258.png b/TMessagesProj/src/main/assets/emoji/0_258.png index 638d16e2d8647520f47ce8f6499692322d0e966c..7cd379a5e67c8ea3ce278d93af0368e4090aba8a 100644 GIT binary patch delta 687 zcmV;g0#Nnf?DiycFY*QZi_E zE3Ie}M;F5e%V1%Fe?`cQ{$(Kj93lJ%!9O(x9t7iytP=V?Ab(0)UQh@RP9k+Dj|6@J zY29b|Mu-~m{xt+qu7uRZrjZ+s0X+!4G~0?aLP0!N*{5t0{z*t9c$csbqO@k41a{)w zSiU<5S`c(0xUF^xx+mm0p$`d6qBOz`pA!_TT_Rgwh^_(%D=#I=)+LGaj|HH_i{ER} z32B6B{te0&VSiJCW5t^-q!BK|?XC%KEt0TKAZ-%4^IVK`wKZYUVnVpZVnw)JTbSW# ziMPd?h!*D?8|oP0f+*3#nR0^;)7d4=JvZq4!W0(acfv@{I(1=_2QGp*A@)2k!PK=dSKDs9l^^S^_=y*O<|Pb0XvRZ)h6yMMWvrIExWUN{KC_Yz)HkucD0 zP8iWa*g?QZM5=+c#EoI*RtX(%up5WZOny(8Rfu6yBavLBG4E1fF!&TYbw}7saDg$R zK4xxMlyHR46dD2hqXf+eK>aXmE*ylyJbVGBH7o^Z*fx&OFoz%t+(o;QKq^roCNW&d z-9v4|Xn&BM-$5YUrX1ljw?1-l54B!4_mOjJcja7^Q|jL3vt%g4Gf?M{}vGK{K`r5kcy_o#p!TsaM{^-pahQK)h000eiQchCtNJ;^PBIO)1tp zf<=4UC7MT_yH6cLeff(bAPZ`AoP|;U?f#ktL69>I{=_&7q6vc9>WJ8YSXi3ogK1ts zjW*p8pok$+On(uU_+=V@BveEzsQI*MA{j{S_e=uPi6FIPZl@gda4RFuf)ovAijc5L zzbrVE1`BcqA>gzx%sfVXpRD;6F`u?7C&|moWfnw-BDJEA5JCO)vc_h=7wn^VXlXJY zA=ZQvxHo801TjL!6>@w_*nuF#Mx&4MZAP*ZwE{|dUw@DU+EiI)`!d7ZLMDZ1QV?wb z%G!m4FkYihon**9agz_LZ{{C_3t=^FLYlc5P#91$C}OYY{utvBgak30kkkN3GJ);` zzqWp`AZtNph?tQXBqKS-HSiIKA_^SG=(7o_g%P$}H2q*T9n9!hND;FM37QGytg(}t zk<`uJ7=JMaO%czA(i1Ji!47scBN&3Q>P49D8zer71@#&v9d$!Ac@w7jz5!;yX-3~; zP3Mn@Q-mqlvXFIe7k8v_h)D9dA?muW^}ou>h-R6HAN*1Y(N};dh8+R-u-?olg6LLO zy?8i*5pHKqVw<%59&eq|#0)B#?6wEN=LPZbwSPX809e*nKNZniBO{39-AzRMdM%L? zfGt1k-OtVpP=qm@pu=8eIm#MR0JfHw^)_k7=#H?j@BFX;A1Ul0Hb?{v$mJCg8`}0g ztxyk4)Qtg>su2{hT?Fq>J7NX77!rap6z&8DxD#FyLD+pGFv0^d^bmpqq654nXjYyS zhktl_GW4JXjo_|Dht)b_$lD>_shyOt7~rmuPlN*GF$h22svQt>dH%FA3~_3>4B%-v z;jUO5VKF%2LXZ%apSRARh&#c9$XoppQMU%FY?8TV)>5Sv% zWfZ_WKgk(qN8AX@`z^j%e_pzp%8g(zCx8Faq(6Z#c@)G5Z_A07W`;9{5_CRUMldg@ znb^eJXb=DhR&mNW$K4okr-(}1CW7X%j6;bBr)aI-5Q^+C|zrQ%(bIAI9E+40! g@l6Udj%a%7A0}gTL@C#K1poj507*qoM6N<$f{Tpy9{>OV diff --git a/TMessagesProj/src/main/assets/emoji/0_259.png b/TMessagesProj/src/main/assets/emoji/0_259.png index 6ff941d4f5ef05cc1104695d026a0d6efbbd67ba..c50782a4721be6dc44ec3f03678ca89ff1c9b4b6 100644 GIT binary patch delta 1308 zcmV+%1>^dh2(Jo|B!5>>OjJcja7@d41=)=X=AaPYl?$|E3C48@=AR7RkO{kL3d?>8 z)rbb!j0o3?2(DTUpiK{=PYL`|&P4ywO8mkt_`4+YvmEZK6aUmx#&HY( z)?AU|sE7an01|XkPE!C`a^uPzF8=-vL9UYL;&7U~*NoxV0Dk}kbxA})RCr#smg{cg zIt+y4t9*--kh(f~|K~hIMs|?wIz~^iW1wh%@DnxS5Iy~C^<`PMzalg>TS~=m5R-S- zan=0d8WjUUvHbst!H~7ihH(S5!_fZ-Q6#d?SzoV&vhu!ej{*JA_AdmqA&Lkh)rWly zwGa8E!Mq{*+J8F`<8btj72%|+eInQr(TW%n0deeZ8D9<#9TVhp>t(PIr6a@`#X{CL z+OsEO3K=mff)7Wn4x~pF8NtjzWGg@*Hb5M90flKrY!_+HUY+UMBQFvQ!;igK>jjq) zZ70{_aBdDKl8K~D5$vEGlEN?uJ_7z-jaVo*M!WqRqJK<8#6C@j(HaAZQlSQB#P%TM z({bn~L8zbk4QxgT4+t~tp1ua7i~u<2C7vsyJ!NAoh4Ws_$|_Xl8jNT6K-S@fXo0Xm z?4_)bfr{vTdj_q0`U1onTjDtG4HPQFWnEjW^50Yr`}X777Kpk55kQ$G4dyB-la*aBE>I3p0+LqqYd z)6)Wq#*=$I7V;qof;iUOkwZC6<8OS9V@24EC@K&DfJHIgZ*PWr7DMB?3nUj%gaVXdImGjD8YZKm^{7wA+~+q# z^-bV^45V#nIaw810>Yf@Dv%Ol1faXmw|~#9kyZbJSd{RRAVdsTgpd*d_xalYu{GpC z$Yu)&-zsJ=>`YL=rkk(L-xrS}G~%Bq zmkEwo34f3MMFy0#+vSrY!=?zmMt9qZY=LJbeNSaT)~x~{H-T$(bF;gECkHgS`g{%Xe7MqU-KE*xnS#p#__ z@bbH66FdteR}slyBHc2F*U+1!0Ds6Dc4A0#LrRF<^>n0WHc=Q%kN~{*tnxxQz6Nx; zrzjB5_)sSD_)s6C!8MN6-#Rb=$%^tll}w)Oz_!SQrzn-Nr SpT}ST0000fmp+WSk07d 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 Eg3DUCxBvhE delta 1363 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 delta 891 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 O0000K- delta 1640 zcmV-u2ABEv2l)(;B!7WWOjJcja7@T~4aal_UteFvcMQya51(>8qirnIg$luN2;i9* z!Egu7e+2BjX z42A8)mTYHhQfFzjd3VzHf51x~xq_2f+F)=wzySTBujDz0vKsxY#6d>?Slj!@@*fe) z%l)!_8IUIFoPY6le}9!xT(8%{3m}$){v*cnHG=MY<#wqT;!T2a`4K~Sf;?7)Xgx!I zKuqy*e-qyV;_|pFn3A5g>XoYWPQX$ymhbn&_wy^&YVKaH%}9vWnN1X7h!0|Izm+3B zj=p=EeBbGj5S6wu=x_G}NN;~fBz9EH(8P!rRx`pi$A2{PdTcSu-`aoxU{p;RMVrhx zLR8x91Z=@5-?brDh8e6t5y@3&DndAIifI(I@r@d%%($RHvhJFyZRv+|f_&aDf{dM+ zBGXj-+D6y7_UqV*lO7x_@|LpnF$URm-6gtBlftxr&HSa|2QePZ;}Q=tpOgU-G%O#Ap@Uf~LH)kV7s* z*Beh5Mtx3aLc~QuL{gxsytNyoV{%qLG<(+QVH_#Fp=3F#>RL*&g^u;iFa_jjiQ(l4 zwKt zg&7G!2@8@Y85zaV&*BG>GXn+^k>+5KI<6G^tYK-$+Am4tP7_jVlRx+*Hq2;M%M6JH zQGb11D_zP}rg_B5!9jF9auX19UaX?y_9?ZcKq7|Qt!_<`)HMhSj2060q(9^IK!_mcGs7a8=!4Te4)yKxvqldnYJw4*6T5i^h%^<`#idBT z>Kv!JbvRK&2$Z5GJVKk*6Cv4Mue*X6mNcdLnGt8rfD;o!5u6d9H4tn0IKox&9e+`Z zgc#!hJJ0)dGu-A)D9jNM=>wv0iW$u=C5GnhNwzJ4ZP4pIjQTRg3q<@-M{rbrN@=fe4(uye$;y5Thi zD=LP#a}uvRiY8KpE`VV~{RhP1{eR%ULq|A{>&ZxODtJ|!N%AkUK>^WNdjQ%VhVU;kHWue4^jB& zr(iIoGP`x7=tNBgX8~b_Icr$6#^9TeH&_@2*G|KF@U>JanjHm%pT{?*Fn@;y!apZ@ zl#6HVGmAaz75$qdASY8;9R5}tW1&TOP6o!tGpIaa2nZjK9#=7%z^7;$W$PLK^}!5W z6_Nwy+~3g1DMQGx*f(FGOeVUs?TO&*4_HACFU zi8;YHF`ETKgi3N4)6W?-BLbmYJYV433pFys$`y>k1@TN^K$gMLhgwo2^F9zV*m6UG zfJA|?$kXW8+8!RbVzcNpo*DR_Ay6|y68)|o2rw5fS)$AXMF0?fR$+0@<`TuH;blTF zMx$6qPgpEg=}!SLX3<&GP#FL~*vJ7!yj(IlQN?NWztn%vBN7|NAPlMi0000jqW1#bALK*w<%xX2iZjUwEyi!q?3 zny*EPcz!f8qd^Mrr9h}P+@%~X?3YrWh#rU{2X`Y`?p^RN zSu|1J8G*t)(s)30hJQn_P$0z0%4lUlIU_E0X*OCzj!1Urh-hvhE(kYQ4)gBGcMG!t z?~WiZ3y*{47JtHmXfg;|;@J#qogrdMQ2KC_j)>-nHpkJk&=>oLBghf>h#-);T_VuG3tOzzT_xUEvOvZ_Oe+{@zbAZY7BEE0 zOf?XAdwKQ)obxcAi3*w-<%%8~!G8g(8QpSyi1#Gag#560VxIPd6f?CB z=rR<2QlpIebl%(y*K}iHia^Ty-L;V=0k!P6aNkP_xLX=$f_j-Z>#v>*5vg|MH)d=B z?&U`9)6eClK&1`9H|V-5?n#)JJ2O7g;7iL$?3F;|9uo*ZpjyUWtjUnk`X zgJr?*cwv`_m2ngehRm=L=wBqdadHFXL1065R9+dN*Cp@gStV5f5d8=(guOCWSXCDv zwhT)3MyVQKvHbSG4w&jqNcr`9<qq+l0000%E!Xr-At_wP;$8 zlik^u_u?b~00iwxL_t(|UbUBra;rKJM2%U5z=n9YR^b1C^3AlQ2$TDgxNhC4@)B3+ z(3);7+5N8M<*@t9x*X4c%Q$@;KTdB0>Y`pT4(In7t#xK1gq;ZpTRtQv^t~IMv#|ps{Xq=xjj^#E=YQkn7c#~QjL?B%-_FD!9iq%K z*4?P(+k(FzLT zc`SMDM}Hz-iIJ>jppDMfFApNL((Jjrtq6meJU4DcsFc#iU8x-@9dI^_K$A#bRjhu+ zx-vr%hOtU!bVwKprl_RC3R0RgBW^1&i9o8@2_A-CJ&Ky!L6SVukr0)e6gh9*T7(=B zZY(mygB(M%s2xTrHL=YZL0#tAiEeGhEr#3M#DAb7pd1@gtu!Z0ChG|iM3gUXa=62z z2N~iqX;RzEjs~clFc@Md&xk#QWf|?fVNeeiZTq@wZD6>_xCx`ZwN`Z71p)@z9}}UL zMNMubp1~ZA>m>xoRuP&$`N2>pt{;Q%YFF$6KpK&*(cBm|358x{TPT6y1r;VdE8iYqa=m4877 zVvbiIv7-u@vY5&&5l5)rtAg}cXwVWO`Jkk}DGkh+Wr*U5Zwki?h` z_AV}rf7Jn65Fr?WD?0qRC&sOcdw+(8ZoHBPE)dX6C;DV5PXdffW_YYhh>raLVnQWC z+``ih9jG&ejLaZNj&n37?R_Q?L|$g{%nVEk#^90xV^)Z?=Di_6B#?jg^|F55sXn=6+RK#wtYQPS6!@002ovPDHLk FV1m|XsgVEx diff --git a/TMessagesProj/src/main/assets/emoji/0_265.png b/TMessagesProj/src/main/assets/emoji/0_265.png index 71f61953d0ed8fffb40929e8fffb72ccaf131b45..9d7ba7291bc41c8a3e0063f17b0f246fc0a34cea 100644 GIT binary patch delta 1129 zcmV-v1eW{23jPR?B!5LvOjJcja7^Eo4#RT^;Fl85f(+%K72lQ-(SHNSco5Bi54U0m zziR}!Wd{GuLH@`$|IkeOz%BE)BQ=Hz01?jJqKAL^8<6sYZIZdHR9Ua%T8}Nc*1gE`I77(dFfwW=(;WTa!q#nWbMP z{p#-sJN}i|34db62F8%L)1L;S*dmdXDWZSvricu4&1q%p}^1P%=;SVX~+E=JZbP1IT*KJP$bZ-7fiROJ$r-G5%)Yz-5&V>v zLCWpR4cU^EYEKlUDn@J1;JZaFb$|F-Z-b6?Qjv8gbSZ7!jt2Y(*GEl}+RO0@I5iLTw~j z%ua}JNP&uF^C;*hjg5k+afZ+uC1xaBN!IPgalL_{j1AGlH*ZF0Eyb~L&mndQOd`4< zoHyS6ISh0hOOOY}{=w=(ybNNNJ*T`c{`Y3E4S%^C0tg+Lk24}E!YzgIQetxr!vYb5 zZ2^mW2S)(%`RP7n0+1o4Vy`|P6$mOdU;x+{A_xeyQwad%T-wWB@&tmFfar>l)x=K- zWpQH)24a0FwH@Yu(%>2+XapcY;`_02jwA$LUt6<>zx7jms0&hpLRf*hO0f1Yw=F>$ ztbaZTc+L>nZ6yG(B8lskNI^RUgc9(B*C!eTSU8NkR~(ZFK^Z#BCqPO_R2RFna z2&sfJlp+9@i~+(6G2ZoJ1Vwx}0E0nM39QdC?Caf?(HJ40>Le=ERTL>DCcM3ejV*8i zT>-El>SGM`aFB$jPQ4I(A58b2AX*>LJsbC00000NkvXXu0mjfNnHc| delta 1325 zcmV+|1=9Nd2*3)EB!5~^OjJcja7@60S-^r>UteEYSy{n=R=#~xop)ZUd0M}JR?wSr z&X{jlSXjM$QoMOk&6R9hTU*kec3N6mTU%RKS65nETH?N#-Ls6^t%cU5ebSq9-?);@ zkY?q?pzq{F-T(jq7IachQvh~VJN^6K4vK3eBIDUUc)1we*kf z9}(T$&!01lHRavyb4I&{b%Fu9qpN;?%4mbzoIe>D@jMvjkE}l~tKYWG69Y{==&B$6 z?fqQTw4M}G%zrg(ju_#@OnoPYczS=Uo}UY>-i(oDY(7qe;3gi#THe}W)=gf`jB^Tt z2uTV3#sc)MfBuZH$rA(W?Z6E0eY_gMKl+7Q>H8mKz<`4>k&K;z-iJs)s!m#Y_P3v> zafv}32(hJ`J$jbGH&ps2GUhij+FclMz>dTa$kk>U`hQjoMH^EOS>AlOxY|Yy=>Q^O zHx{tueA#J@6oHyy#)LN$!;q*11SY$%4|<*#Q7}=Pj(nSHh9yQ|2#*DJ|h=@ZHpL332}&nE&E^-5d!^U@My^n@4lS;Um(z3DMF4WUd;@ITXv2nJEX0`QcHsp z5xXi8c8FPrmWXXUw=l6LW)zmHJ-~?(!m^CLV1HO)IO-rw=CaEO!GL1o2bfuw27@W# zNQC?P`r2YkJg|L~oo-)N>}`EOF3dQRDe+*0^Qk>U1~JlPjT(twT2UWVmJbF-!4bQ1 zoWTg`ir9z>jI`F_k*e5Yv<{E*6$~HXQGuu!35h5f`~V1Gz@iO^pBW1AAOh8kAcFXQ zgMXdx7}6LK7$E@kg!}4*6uS_qlB0T6hRqj525bc)UMhk;1>S{VaR2_Q)DQ*nY6Ao= z2}YGpv$ADzLNc9by`Bq%2O}dw;B8S>n@=h+!YdMhK?Dkjda6K#icwV62N0wpsixY8 zELDC(gt0juA3{-!ID(Pd>X@a#!6_Lcx_=gBv@*iTH<*6(OSN{=2?)%jW;m!21ir!W?U5O1<~7%h*)qaOzC{H-Uw>{I zq+^B32Lg%-g%VH*2Qy<5FY@Q)y%g4Gf?M&)rs}I$Nb;H{^-pgO9NE^000eiQchCW`PwZTNtA`>=6jW_63nPDbe~p5m5+haq1V0M`1wpvJ7Nigh5^6pW<^|Mf z!x>Q&Q7=T{(SH(un#Lai6oCmeADku<3#t7h69@D_kXkag6BGfyN8ug?NgB))Az_n# znHx~5tP*1p0!;hD%wt49nd3WRK5bb}(o0!a6htctCAv!pr+$vIdbIx&w91xXn2d+> zIe-K{8Z;<^7*VSf#Q#Xx3l-;)YOA%I5v)X*ijsaVNPj5WR8eNTo6*}sCWUBH5N!a8 z+J%+CKS!M!$&g)flMkzJ=3jA7gw+&E7-Qp9XRoMyu2YwV|j$foFN#iUbyML0pgR8K(Ce1N4-UqH$j;1o5GCpFr)20 zhsU1)Q-sOcvXFIe7k8j~h)D7{A@aJe`EO-q1X?EI2ftKGZ0!Z%-3|qIx1P*Mf@oG& zy?6{lecgvSh;7pHyFYaXiW!t5+3gVopBKb!tbg^YgaT=O_fruKk&GaccQeuR#~}bc z0D$qH&we&$6h#=L6KvSCEJs;G3IN2otfxscMjHtG`o<5dz%97Fhz$|}17dndcm&(N zW`Y2E63rMzQZ<4Cwod5%X-BLeok5L^q3})+KzCx4L=kr12#gqk7`h5U0e%2RNx-ap zP=DSa2GF4|O3(<-T69>gBdWXyWOQmHB`gLw%SA;9qvv9Vm_3Fl05RP^t&EOP%#Z;_ z8iR0_PaR=i3_?ec5SGtd=M`}#j3DBcKO*vmT9I=YM^__DZ_-6h2RBx(o1b=%u`AL)hEd7$MJ4TGQoOo$w3`SLg&L_(V z=H)aKn|K=y*$@KhdydnXX-Uc`q$)#3;54T4TSSAHfPrA2h-mXU4?`Gdp#Wl%H0H|6 zK*gXvA|v>(OIn!`W4~t)%LrE)TZ(7dvc9Z*-?k)*{5-VvRe2e*2xZ(~2H-kmy&>P1 ihwlDk3UiKVdg>2lo^Y~w%x delta 1413 zcmV;01$z3u2$&0yB!5~^OjJcja7=MjMsrg{wt!!qXHRunO?OvFrf*e}Ur1V7T6au0 zf>b_nNHk$kNMlYzn`Ta*X;GA5N^eIqT3T9ISXiZQR99D5y^ChLg<`OHTf&oTz>jFe zmT$+Jbf||N!2kdN7j#liQvfwh{{0Ui{{H^m{I_X~c+;Euu7B#c&$hej0RR95)=5M` zRCr#snCo)uC=i4VNFZA`%eKNze*f3pnFbSNoh>JOYA02e^@C4MPXlsJKdW}sr@t(D z{`y;n{5n76uK`-<`tJUF#_XJ$+hl~GYfB9AJAw)!xK$@3?##OX(2q7>u8t7aU74ZN z;Pwls4<**?3V-#wQ89#Q)ym9v0z*8`<7f34r3rEIHW0)41#DsvYy4=3zG4_07+x|O z>I2N2@Ol3*4dWs+SiS7&CPwT0RRjNZCYCtU=f4*Wu*|Tme(IQEiLt^%iK%>&(GEss z2WGnIyk&$lGZA?7$c}z+W9+=M?0_@!Brc7&T*_dSV1F6#q^Q=qJ<1?Pq_XNNPGip# z!;OZc?88{{C6=pF>$^30vSaxO)zljV44p+t+13ZL(Jr~`^Pd@194gp>&KilPAfpfu z0`TVGjZ8XXuxcS-ry^V98@8jG`a=3PqDR%}$_P2nL?j1%ZtYCzXjJO#b!VKQ;B6tY z?@L8kZGS+x$KI$Iwv8FEBQciRb`}xXGT(`Me_(guV&{`eOBNs3U~nXe!RfXH03yDM z2|%c3I@rk@g1CUeh8amWE&ve3uke$cSTCXV_@{s=?Tx!~0mefq&qJJwomg*zd5YDbeaR6c_XZe+7YTHG700 z`L8pC85X0T0D!;+0tyH-*908q&RT3VLS{dn1ra_V_;4s^NQ_`0R!=Z0z_v#$1u;IR zQ)W0D$tok|t@9;T7|m4>TZPa<&__D3`O&;axSf)26juAI0{)5$%ZRnDUV-i@-hZ8O zSZB`6^5PNZJo;S)5ICXq<2>PQZp;i1PlGipAznx2Ipa(icAcd z7(FqtmqT<3Sl)K{BNNJofx$qX?|&N1-XN&RVy=4cvx#7uvdqd`KL6?%69Ykw6{752 z49FU~3#=#%$=C4W;vf1RxW-`Ry0W$VgzpKx5uz08t3ov}zsayQrXo8JNm` zB6$`B==%2!e0-cAQ-#$--+;002=<#W9M2FEB5GkZqb3+8^gT`ESaNE2(0&Pwm=jqD z4HIq`aRk83eT}!glOa?Ds0i}(vl^+n&RG-y2MwP~Tzcb`a#Tuv6NVoX(3o3id@7Rx zH+c5*YNuP@8B{|A0>Fmfl^h7tbtC`)gy*-_%HeWLHT?JgLTE8g(jL diff --git a/TMessagesProj/src/main/assets/emoji/0_267.png b/TMessagesProj/src/main/assets/emoji/0_267.png index f3d751737c431f5a33f5597d9eb85b7dfccbd64c..2817909e8c7cff4bd08b2bafdf786b1734ff8269 100644 GIT binary patch delta 1029 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 N002ovPDHLkV1fZM;R*l% delta 1136 zcmV-$1dsc$2#pDlEPq*9Sve^pIVmDDBppCEGd?peNi{A-JUB=|Jvu5QG9w&VSXfzE zSzB6KS3)>HEhkYtG+s(RT17hg6b$l) zxIWUqBJS6F_!^Kx8lN8DGboqr7y!oF=eG>nj$b9AyI|Jzyr+ zug`$svPXPr*-AxJhA>q?x?i6k)fcRi|IV>MMs#35(FB%l)$I!YHeV{Lcy&Q;w zSh~hDTG(O9nphAtE+e>7Wx0e{ltHj#Om-9@>^O>Wx;52BJZ$0Ok*xGgqwDI?wvJ@q z97YmrXXFGs-hE3;EFi>nFp~wLIxrqBip;WEj$PWy=>-9Te`~J@MAOu0i)XsQ-qF$| z-3j7GBYz@bFqM(oaAS1XE5j_MbrZs-W||CP^r;G99LHW6DZ`E-7FT-{1p1gZNI8(L zZjgQ7OQfo)9Liu3d|CnI%qYjn5X7-X^7UtDghW{$fq)e=qfaKrV;4JOgc;3`xU|SM z()UW8QNVzWcb zjIhr;#NLG?BghUpjBpsD`RU&X!5`UEXNcAqLX`o8X#hdZ$o$rVEQ=14sisGn!=a61 zM9c$D&Bo|cXd4_)@It)=*AR0g6m^P~fheuOR1u1pA_;5XWf_bf=RQJyMBp%2NDiHW zE`NH>i0Fnmx%z2m2pI9qZzjwLx<30kq=$$yfcT_>Q^LI=*;$4-iO#Xw|E>bZ%X7Rp zq&zU>%_0C045I`fFk85T;j|@Vv|jvzPE?2fSs#YL9n7vk$)A2~Em!?mnFvMnI~eK3 zlpDhqG>Sp+TScsj(Cg&0GjNV7Lj}Cq(SHec6cL)ROSaSVT*uR5nFw~IVlhyU1m@aJ zg>}jRrl2~(wi!QK6XC9=(yg1iTOnNqC;?U&131BCqk2a*SnB!4YXOjJcja7<}DBx*e+a6l(+Kqg@~B7aLQoMkCnhk0000FbW%=J06vkpY8c-C|NsB~{`}Fb*J1Ji00RX{L_t(| z+P#&Fj`KPQgzH;uz{&eR?g@sLkZok^uXJWFQQi96VZh$k|9_$oQ!c*|w%Y0zejtVb;MA!h*0;J>|${o>8#1^+&TT5jj{R-}5L0kaoGfdMT zAB$H6DT2lW^2`LM-zo)L%7Va7<1Nf<4TN}IIuURpBS1X@rp@fxBT6UdLk65J`c$4`XwO4AVl8 zxa(vjS-m1)){ulC-LuJ%+xryIQbQsEXw?=*KtXhDZGV13G9x$)tt3lN6#*-VLI@xi zL*vhDEqeHN-TGMjZwMgCH7LM}kOe_YF#P6{7aE4Fn70 z^u9sf02~Hy+;WMW%lVDi3^AXK+B>@+r89w5>t93(A(X#uMflA4*r)^sN^Mqk+yG#U z;TA?mcz@4$bE-oYCs!zoTlQget%MX&4IvwnT>%Qk9vtG(o=~-|=7GZrR{{Va_E_$D zvcP9x!c?S+Hvp+0;Wk`V^(Ht0V2V-BzW}K3itsJ5PI!R+R@wj=AebD1%a|+eM5q)5yoji48S_$zAzp;Ug#21kICh4pklyM- zSY~`6U4FV;*2^k!-}mlxF6dRc4moyKKfi_!1FS~2mS|;B!5UyOjJcja7^W&5vN%V^SUz5f(_S>7~hx=-IEKuY7N(p5427^9Zh6%D^4!&&+_q!?j!ZiKKJ^#^6{>?<`q!ID39RJi*&wdMqwLBdF000kkQchC< zxA$r@8IJz^PjcMc!IG9kLNFm z_zwuECdRBp{eQ9OmGD~6dLsDxUNqo^sJ~Xtqy%PLNwgWGmUDMsrt4hWQ`+t)`+=bd zc5j+#O1Wfe+{di|A4H(F0Dy=d5dm^ejWeHJrx-(ska@L_fwP4WJqpr(Gz1aRb7I)e zkl|&P$-O@v=%aqO<|Ja|SyI!zsTKHmuD%l-L}<*L-G5NwPIx7Fkp7*peV2%cgm?LGl+sjWOD^vGdF8Ly3UwBk?}L$7A0b1e)cbZUFPFtk%RvFMEcP*+)tHkrsOG6yOiI WoSBADIUdgd0000 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 delta 1049 zcmV+!1m^p!2CfK@B!5>>OjJcja7^K@iu2L0*q(Xfv5wM~ama&Q(voc9t%%&HhVRFu z>AachzMIB^Tg87^%!^~(rGewJjks+__R_HN%BT6*w)@||`rW+k!k*{1ll$Pn+o5~^ z?8*9AoJ#-z026dlPE!CPYKc-j{`~w6*|Cst&!gbR`3_=uLw^7O19M44K~#9!wU&$0 zqA(1F@6JRl<o&aCcm75$S>!xBBtEd0!BDQWOirKfq%|v=5jBC z^^(U@Uv#1BazK^m%c6VC!!aSYecyG#02nZ)>(8!R6~H@3gn+^JDL_c*&uz-Rv54?s z0Kj_h(Gb_xTR_ZI>JzOAjPTY{I0J-1_pIsakJG^fH-FP9S`mykeet2K2qDpXgd?Gq zuK1kBe1s6la7<9~h%i$f#D=$>KJ;)*aMnAt|EAM;DH)V+64WC z4MGpbgn(_hwC%A=sW(}qA^0H*DF0G2@!;E>?ZylI0OBA?R+#;1i;$lmbPQfY>ZC0JnIkj}aV=qvG+rcIk$P(0^PBVvLE8Z8`VllZ*F{i~;JZ>lHE0 zLv1IOXGuy%r>DgEbixp*=RG{crlewu3YewyNgTLku8ozTvq1W-jV^@)N*M11w!woO?wloXyl4-RbUfF9dy{GJ zh=0NW%834G#qnf>7(@Er?h?^G$A%<=K=MqlRftHN9{(n)-J^#TMGO&&pqPLRBYm~B z`@b!ElK8e=mgg`ASSy7ECN78>Z(2yngd8*z(o_+~F~d%b zIE&G$8XuSwib#|dnBm|5Sl87(6`9HtXa~)Z=Hf7CY3fV9usGGd5)b)GmHZ9(4HCR> T7t(uV00000NkvXXu0mjf>3bN& diff --git a/TMessagesProj/src/main/assets/emoji/0_271.png b/TMessagesProj/src/main/assets/emoji/0_271.png index 2d66e2ed73422635eaf2f43451f0ab6f6732a55d..6e436f7d0bddcc3365c032d724ad8a409f5a4941 100644 GIT binary patch delta 1637 zcmV-r2AcWc2KEe)B!7WWOjJcja7@T~4aal_UteFvcMQya51(>8qirnIg$luN2;i9* z!Egu7e+2l*Z z41^_HB4x>UV7%fCb{ zFSpC~$AC0RLx0Bp_VQCke!X6EF+eR9eu1(48NpVS8Fr}{vDeJFe2bxkpid(ZoiOwp zo2lMzd-WwCE>F9hDCyan%9zpa6pxe{%a_~n>;8@DEUDLPHv!QNZUY20@dnoROFPoj zBdDw4;o6Bk7RI>IboB%NnLh(krFQ$&A-hV=OpU5yRzdM+XMk5!As= zLTJ}%xZRuxcF_%0O@Ex@2zHDeiqjz_8$^V``hP>v#%`d0O$>GD-DFT;B%17~YwRp| z^WfIb)CL5%PC|rb2ZTYP;)tCz?3kJc3|f{M(V7Z`wm+z_Jr4$oj_HCJRKrfaF5CnJ z5;j|!WEd1hKZ_qs&Kxs15$TEsC5Ms0}eX(-A}Sf|#ml zjDIb4ky&bSXk-eYE{+^jI1U3r1BT znG~@BhOf)t%G>gHVp`r!^jMkqawr;A95J~hK zMmrFKk_j6TAQVo5fHWG};bE%pA>x_gTYtK@W(J?Fn}!L7868_x!Sxo1&y`XlIGJFO zC@{#8h6#eGnqR-}H6cPfLx!hhiVjNmR5$luzZ%hiA`yh3ocPT%K+#<&7ngy3<2g=O ze&7=g8zBgY5QKHb6Cv4Mue%%!4^PoQG2*PP`NTWI01gCXF=DMBTeup!BT9uNL4Q7v z^L$vhP!WhQ=p#U+4~Tp)#AtUZ7?!q^)>E=UX0ikW5scuewte!5;8E~WCu=Zj6pfSz z3WOB(5g_76D`dgxl1P}r=bL8&_W^ep;q#|8^K}2ujQ2=@QBm>v3fK@Kt2@7@WE3MH zbm7J89?|4fu?ofzqWKrZ@#QGrA%ABF#Lr-y$qEc0IGJ2u8jN-4SJUn0wF}0;Xb?|n!axb3o)IWXhXH{^$frnJ*$P8mAH*1CrJx#s z`^+%BC*3>2_aC`XN7%u`x$T$o=Hig?V&A2NA`6T73Bk`-`20fOzOf#DWN^sjdXYGa zi-rO3gg*G1>Af_ewr`Ax;(zy`%0@`Z4JrWcqR-Gr$apy_f+>L_o74=l6(H`IL`V=3 zK`(5?T*-G*21Q~8GH<<|o1ppJiSMiF53toz(;b(+!Fjfja z3SqG*(&+o8i$(8Ui*gKL!bX1|Af{%$_s&y^ggE+XCB-7kda4Y7)vJzvUMfDU7F??W jfd5!Jc}2x(^uN?U)w2)vvITUh00000NkvXXu0mjfl12NB delta 841 zcmV-P1GfD34B!TkB!5CsOjJcja7^8`j?|-k+OCJnlWVeXM$nve)uVgPmTk(CYP)<> zx_C~^lxwweNwsrI18x$a z&|Blmup`*J4-p%8PvWQ`Z0CL+2<%1-ga;yYB4UMz{|zxwam#iau3q#bSP}hRn2+tW z9u+~sb!!1S$A23CSZm|pQieAaF^H@#7_Y&L&pAMCd2j=p=HKbj7U#Ql(_(g7X<&D zAbYE`jIRjrYz&kyNH>-2gNx>BoSUMx)`=0%N_g*8lYa)`D8+}ItBCy+L17J^h%(01 z9YnhnVr~KLAc?UiO2YU`Qj35xoOtvyVz^%~mvx<|dW`#aHUNkyRp$7h;yZ{himNp^ z2`FaC)Lb!!`&$Sog7+X~2sl_nAA*??G_DUp-Vdq<9Vi51#>(R$@4l zzy7+NAb(E-6ss;-PI2oM0xD1=CsU@(lXPei4`(e%ezH?ulkjk4MU_QUG%QckO}ae1 zBdE(UMHx`ix_LlMUBk$X8d(K!3{nW7YW{d~4w%Cd)duR6ofJ0(fbf8@q|1p&Aox{5 zVS5KAFK+HJ%?~Is<#_T31)&XMIrO-_A4D&!C4a$dmm@7Bdlf=h+W)t8d5Zp-eK!2o zhskHkJbk}8_~2!|*c+50oT`h+Dtlt0Z5hj6;G$WD;wk5VV6jeK7SmoIZ>s`sOSEyB zcT5Ip8-M@;i(O>>bo8^+a=Xp*nxdQ(g%k>~sUdNhv{~WWI3?74kv-Nfjq)ci zvO+dpuHTG;Pd%E!Xr-Amt_wP;$8 zlik^u_u?b~00itwL_t(|UbUC&a^gA=gfYI#4t5AvNxt#^FL`=e6GgzDB-GYU)sp3h zzO=eqwzB!%n8VxVFXyoP_*=&QefPe98Bk_r!g%|5oiSY8r3(g#|x0BU&27~JJqINS7cDVq^P3*;3e15B< zae=Ww{i*SG2Er`>GM0D44Skzz6<;0qYjWUW&>K7Zil&oYL>yXZi+Z5A+~qt3r% zq;8aDX`W@ss(GHRyJVYVRRf4GOK8}K2sp%k<=tgL1)kj4*1~{(2NzF8ZK-ML^t66; z!*qTUyIuDb3K^8&8?i%@wM-VPMSyuTBp`D(z-LeWtf*ri!KWRXY$gn@=5*eUD-}X* z9CPdj5Py$g#ApF@nrxYh&4FG=$=sh3LT~3uj2l?0bseog!j8}mwIdY)36NJL`{;PC zY@dZ?qEZ+w8wSCChyb3T6+XbEQv!wvwhBqGnDpwBm0|}ZP125tDEz#_W#>~7rgyrm zFIf-RNV8yvT~}EEctpTuaj0%nhfZ4V$$c^~0DqdHf@*kYd003Z5J5zKXR?$#{OaDY z9{2{eooTUP4GoKdIM9LE-sJ=bmInqrxQ(tWTdW|%E8|pKnB!dCJ{}M9&+@CZf{1+c%%G>MFj$XqWyKn(SOa6J zuYZjP5C}&4I3<%{_x)fZ12rT|e8Ni0?#_yMX7GS01ERnHg(Gf&0URu1QI-aXZy86{ z0|aq|1R`cZ+ydgb`CrBi3K-JvDIyR!2Lwgbrzbn*Sy-|WvfZi95hr802|;HJ2q}hd z9|&3R7CZ|-TSbOcAVrWM6C$~m5AU*3)PHwurp8%!#WDsf6!3t!_jAx^RbPtyX~jBx z^ZZXD0tn8Zx-~3TU*^hKS*MsN1OUK*sEddFK9c*+I(+p0kLfZ+% z)$mQpE0DfzOJP`nOuoO$SFc2>N z$8i0<4$^{%nh0Le&oo6Dr-IK68GlM3K{d#bKr?;a#YnLUG7gc!%MOb~<*}u67$xW< zTyN+^>0cd#FlY!6Izfp(`)nZ8ddz5tFt{ZK!%GHDB_g5lP62=t)QXg04%~~D42%>3 z98CZ~2?h3%GIj?+5=#byxt9@qR6^4<`bv#{(1`Tn)-ag$0UX_@ zSz8rFgCSrG39paI+ik_!wj)Dq!^@QHI1EFcZT`vp2UjWK{R}{Ep8x;=07*qoM6N<$ Eg3AT46951J delta 783 zcmV+q1MvL33#JB;B!4qdOjJcja7?CfRjzkhfKxr9Y*ey+UUf`2q-|4-TSS>=O?*%~ zpJ`CEeP6SCUAl&2zK&;VjCk3>b_wETyh5)9?+kyv%dm5MeOS_lVdK zfG-jCHKM+BVOhLw_&B08#QSRb!GdQ+lmc!v&0+^5;ZF#N(QS(1`#lN)c%L&-VP*fc zBq%0oA)c)whJTR9rzSQ8&oE#W35I-pmPFkLY}#aYa=d>IjpD4zpN&L5+|;Vn3k17j zgE`!;@oybsalgMty#h$g>?2=$$k!h1edL8hH|7`bTtp1P(M6JaJ6cWXh;USh2zD)3 z1nX)7BB`oBde90H*-KnzxidZhK-Ar`P!C#vk=AvCe1B3(({T+g%)KN=vC`esygruJ zdpC1z1%5|RP{)YR3F1Oan!^A>%2{onIEdI(Rqi{4?Lk1KjPf;t{TD7LTPbwEh+UTk z;dA~;z!X|;;*@y>)K*Sz6_<0t%SW~O=0Yjf2V%;^9(u&zYipP70wOnj>CP|eut{7P zuC3E(?0*HjbKR=X)iFYE%f2*-KicpD5ZSD)BA#poW7N~-j5^&xOlFGRw`!Ii5r_eN z{74}^#@+&mNGNvpOkT!KjnXqJK}rC^0qhWwM8F>+UFgJ-UZqcBj{E7g$o#GZdZA4{ zNGKmWoJ|NI1pZwqR0L#x+Pe^W3}=SZ`SfAQ%6}{-Y*L85PAxuS&zKV=Cd?Be&Wh3O zRKjSg*K;c9W8lVBlYZxe-oEn&v3SX$juz4D%PDHLkV1nohZ0i63 diff --git a/TMessagesProj/src/main/assets/emoji/0_273.png b/TMessagesProj/src/main/assets/emoji/0_273.png index 142ce3fde7513e84d27cdb1b63eb36853dd61550..29e69bdc96cbbddf0c44edbfce5799ab62b011c8 100644 GIT binary patch delta 1331 zcmV-31UteEYSy{n=R=#~xop)ZUd0M}JR?wSr z&X{jlSXjM$QoMOk&6R9hTU*kec3N6mTU%RKS65nETH?N#+O37wrG3(ya^16x-?);@ zkY?q?pe7Kcga7~l7IachQvh~VJN^6K45ij15QV`kwque&7B4{F|21!Iczi8Q(wWiJkEUsfFQ-l&SLo(vrDxszWzGGg z`%6SO_0#tZV@-K?`<~G*VR3AL?%=AQ-!j_ZH@}_?8}Sr|`H}TyHxkg4y$AW!cf)#Gyk)tfPb3}8eD2yEg3tofrIX4&YYk#SCe z5Fsg|-%x6a^AXG=KJp0@G zXvMfXg6x~s+wPRv;|@WClDOcxgeibJ|HlOGe3qm z7VJPCHf@U-M+$L>gDv|26D0)tVBlyKwBlc$elHN*T`7W&CVw62n6W!I=x%At@Ebzz=L@S(+J0 z36co^dcC&T0*~2iq@8XLEB3ZNAQxmvGASO2@M~(%`;nyNtWhJ-ODpPwit?F3qo9ag zG0w~g>B_Mo6+F^f2O;3GmPhO9QM?Lc4dhXQs2NF8RWd*e6PUpkZH#!&P+CO2pbi2F z!hidX?fk@`#(;nb0&q`!U!9O*7jmlTs9u#p^9hjwTY-p|ieOIxcA+q^e>kaXh=e%W zAOaNyqe`b)(6Z<_nVz&>&ly30wM2v<+agz+Pbx6N5ebGNK}rxZ)d~?RMpusq`H}jLqZtI25%A2}WwGW0nF2r+;LS=z`$oPe(9fM(~#d+9;64s*z&F1doS| zuNA^~=bUkn_DvSW@FB67XTMj~a)bRB->P8~6L?GOWWaI8F6jX*nj7vB3xrew@`ogdr_ z<~xv#nn3^|@a`-bh(xR~5;1Co5PuM`|9@%eCm7KcP)m#&fqi7cP%rR#>ZiLYcR4fs zZwcq7t`3BhI`nx!MuyY`Zli|Wb;;C6KsZ~OK!9Pi@BXdI)ebubqzF`qsU&tA zz9qUxEMt002ovPDHLkV1fv0XLbMp delta 747 zcmVZQVbF9O2DcBb4FWY>qaKwg|l$$PiP7+tzQ2eP#>giM4;NR*@h z`niYD3@nG?1%DO^h3_PRnt@Qx?+0Q*`sShRS_s&opI2&{OG(NS;tZgWE^39pDd5Nw z($yH3z>IHzE4?UWRgids&r5}q0akb5_Y=hg`zt*S`3 zCT~OvZl&JI+*hbYrf@3Ic7iaJ2u^<6*c&Cu_muN;sw9{jtdiLgLOl_pUQ91)N$_g=L@lt>k>h(*H`LH(+o5DigVr{Y+VPpD-O zX|Jrc(Ts$4y0Tc!qMmB0N!a!W=YX^Q`0Ix-YZx_Xvw}~bj@S%}Z5n=Au+B47G&=t= ziUbgX{7s9SSOlG^S_UAjLq%gd-}Cu3hHX2>qGWb_nNHk$kNMlYzn`Ta*X;GA5N^eIqT3T9ISXiZQR99D5y^ChLg<`OHTf&oTz>jFe zmT$+Jbf||N!2kdN7j#liQvfwh{{0Ui{{H^m{I_X~c+;Euu7B#c&$hej0RR95+DSw~ zRCr#sn2VC4JP?H^2_z^t@iMvL`@iPjr<*JwTkH65ZCfQWRz6Nnp9Gw*pHUB#eIr|VVmhs;wVyP3o|Dj-j2g5`C(178IK|skT9pA~QJ7*RL zMmlMt2O_wU2pHYN(Kl}NO$;6m1gF2$xr!cT9FJ0v!GE5Vvewo|8N|p`-dxmI-(q5X zV#QI7rj&fC>0->|U=6MuAfH1uv`zvRrzNDY_0HL-r={!T?-^7G72Cm`b()*P8MSpG zFy0-!(V`0rjVD6af*9M@d)WTKj%=5U4st6 z8aHXB&-9HT*ovc$lzyekC+bC_c=IPf=yTO@xHAyk(xZ;dsUpb(8O)6AL0|-244mB@ z0)Hcp4Bq>MAq#Z|1tkbflpF%LAdZX}7KUCJFcpB5QH&r4BYt~ZQOrOjh=Fu_0x%+% z0)Y{x8V+`1Lr`aCz%ZxjBqT;agH#d(TH?CH-7sJ;6b9_`m8Q(*f+&Q7IHuDY`j!%b zWSXU&ZfavXiV(!Ht7DM8>S38NvyK?^+J6lMH|-I6kBG8T&4n1wl%Y6CKloJ;lC5fw zP$a+HL%{Gn`Y8YqP#{P#!o4gKidFEQHyWiEKc0d>y+PErF82^Xn1NV9^cF$TJ!0KD z`#VCyjNmg_<+Q#Mqr^%^qY7f)AgogKCO2$c8fygY)O2EawU|zOH%m4! zJ}o9BzcK6p000PdQchC<{$h%_-aa3$(0zaa00Ih0L_t(|+QpaAj_e=^KwCf&`2YXi zO0TPSXWA*<%{`e1lh!i`mgw@AFaYF7hD=h55Iiublnqe~D}PW+dFViu;;2T~0wyht z6wO6b6t!R&oSH(6mKdbv=}K@=@PAW)_LAhs3Vo_5Poj99PWi=(gtwM-#nTP0hL5vp zurTKgxB+~39d0lpN~$WNq6zbzzUKy?D?WBq=`#uGFslr>h2TymN@KPVT$e-2IZAxF zGp`Wht7Tk+=YQ3Bi}X=?A457ZsP-%gPt%A95prh6(-_oTB6U0|P%BnRZa7h_rW;<^ zF$Srq_@j$jZjRNgY7Dx8d!{at4O=VI_lxBQQc+u{e#%sC;+8RpTp~;kC^3X%3Xwj9 zph9>TSEoaU1uHJZ1b$Gdqq7+$jh(r1zEF2jRR~Z3;+NC07*qo IM6N<$f;{aOm;e9( diff --git a/TMessagesProj/src/main/assets/emoji/0_275.png b/TMessagesProj/src/main/assets/emoji/0_275.png index 60c53f706b409c8a2f4926228449aea102984f5b..d8445d0f1784ef1210c80b00300848402d7b22fe 100644 GIT binary patch delta 1283 zcmV+e1^oK*36~0xB!5d#OjJcja7=1OGh|0NUNs000DONkl&}RL>@R~j}@52E>s90v8(Js88f*n$Ff)?~uQ zHzKz3o(ylgv7BfaU6RIy}^N6uI=ff=ws7Bv+&Mmkd!CnrFzHwY+FiT>^?YIM_H z84?cyP&I@GfmqxbMMowEk28Sq1^^5YfM`!hdlwpEup_Ibaqb5YxiT6=T)q&@i|)dy zFn_rJuv*G25N#WRL@;K5ZDHeGQ6ZUSoGVQQonJ+O!7A3PpE{h^HOrTAhDb0FZU_m6 zy&}#7E{r3$)ewLvBS}|;Soa1zi*%fMz}g^})zoG*myBh{$^Q$>}a*27whMS#G7v7cIkm^tVM z;?ICw3E^MDa=-sEn0DO@BiA-A1bk}aURJwHa~h1Au;WTF-~C%vOZOvgGAT?`jO_cT z?LI3RE=mBEU_KJ%-0fXrY5_x+C^vZn>5K|eFcz=;#yWf^w2r`bC1G#{) t{kEK4o;~V0Prm!Z@@CR{vZniA>K|Mf<}t^tK|~j|%_PRR7XUs#y;I*I~!`gGm4Y026dlPJdGXR)X4iJFOQADz3@x z%;w+h@Wp^^G;aU^1RqI6K~#8NrI?9st1u8n17QzI(|TXn^Z(!YW{mv|-6ZI(QdPnC zWPE1`RxjVHEX&KERHh%Vk2J5&6RM_rfu@hNK1)gE1O!jX&k%CaIYgk;$Ah@{)AZ`- z6gYE!I0!j|kAG>?({83@e$n)35CfTB(`(j?9o5JsAv`%osGp2N5>uzFS{6a6RK>xz zG?HMLGf`?9#*T{7X2%fqdru*Xi7Bgxo=7zc(jUtrQEngI08wbpAqzTp&-xf*fF4Y9 zM`%Y0{OaJ(=b^4UO6#OhA6+obru+xa@P2yyBFqvEzry7!&9uRX!VYp8s8dt=M z7*8SUC&MECf=Jyx`WHlXmmWdBK~!a(gX;1(a>ChvgxtqjCF%YCl#H?G{hlV}k743I z=u#3{)%ug=LsHs5g%w9&xQRE!MFH$JQSKASRkXs64_E2E*;OeDHzA zJHwm7z5(Eu{d*k|!ZF+<*(h6Nb}a$~Hh*vTA_xc{m&BuqL-cDAl}BwJsLf zX9Qyd6rrshg28pVb3Ns#E<+rck!Ef0u#ix7e_c=eyG#Cy?= zc35bP8Iy<*9wA+-Os+{p`_?~rKj-QZI+DK|KmY^O`*QbXqu09!;r(23Tf}p7Kz}$Z z-NY8$-X8s2DW$LFe*|9Bb(mskGj$TU+v_~9>#{5>c-3{DWLW{afeKWXCHe9HBUC{1s(v&71A;!vvU`$1;Q#;t07*qo IM6N<$f}hV!CjbBd diff --git a/TMessagesProj/src/main/assets/emoji/0_276.png b/TMessagesProj/src/main/assets/emoji/0_276.png index 0ef37f8f27dbf7b5d8b65bfc871d04ef21c94889..f7f754324a6d1ca328741b23c4d2bba5fcb45dd3 100644 GIT binary patch delta 1149 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 X6^og$*iORS00000NkvXXu0mjfZo|)i delta 941 zcmV;e15*6|2g3)DB!4_mOjJcja7?##Ov#aH-L#F;p?cY_htr~a?9Zy-xstVZPQiy? z+pmb>yOrLykmJ9Z*QbEfpLfocY{rIMRFOok{DB9vAkrC184vXcl-kz#GF=3H`^o>o_)OerY@ zi3C#!lMyj0!GFWgAs~!^SoXQ4b>xWYRRQWG!9NB>62csUmt*%wC_U`N8FET*9HSiddHe()$}y9r3Z@~HjRhUF??id+cc?rq^FQ!69}6Xs=! zz;oFi_Yi(XL`uZCi`bBWh(sN|i7>!~6mBE@8v4r2^?$g9a1iA8aUWrcKuQtnajTg< z1ogArLYOFo`zid|5$OuyH`YHpuTLsjE#s$7b(13hb=ioyM0>} z=Qu*lir8$9!d8V#hyz(yeO;LT`~mWOR5X{1TT>{)6eWBF@t=s55ve1ZAWS8~wbl=Y z&+#n<6n{ZDB78xl^l@5mg%R|T{lXEU>8bL6hC_rzPA6j1qwR`-jA1NB5cuI%lm!t- zm1N&zgm;F`gh>1x5p~&qOan$-D{-~=xwW7O+V}R&@7kV=LC8o#)^Qy_}7eHzIHoV@jUI>DG*hLvmf2m49Swu*TQ>POzwX46j#rW|} zj|ng;t5sCkUuo@qzEM63Io`jPRqB=U6rclCN6not!n+Suao0uxcnG7my)nJ3woXzt zej~>E?)p4*$G$JSYFXN+(2eE4ob7u0dnOUyJ9m&CsDtGkx~Jt;|1$gmIrev>Sr%ie P00000NkvXXu0mjfhH1s0 diff --git a/TMessagesProj/src/main/assets/emoji/0_278.png b/TMessagesProj/src/main/assets/emoji/0_278.png index afc59fac5b6ced3426187e219282aabcf3231307..0f4ed5c93a374ce60aa670f6a8d2c427eb4db64e 100644 GIT binary patch delta 1048 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_279.png b/TMessagesProj/src/main/assets/emoji/0_279.png index 044e425111175b40f8c1c818415117bb965af982..a6e3d234e36e9708a9a6b9e8c82cac83afee084a 100644 GIT binary patch delta 844 zcmV-S1GD_(2IB^hB!5CsOjJcja7^8`j?|-k+OCJnlWVeXM$nve)uVgPmTk(CYP)<> zx_C~^lxwweNwsrI7I5%lU9)E6 z125g4)B~ zUV;d0QvgKLcV|M#PYS|g4KN7lSBdQ<#NU7thK&8CnOurvg@)pYLcdW`4eEC9&lC}Z4I@e{?5#jR^_ zQc#-(45pQ%dw!&VTJQ#i4grg+Yg43@5DKnMLEh(D<$178fm}{;ARxta3fSBOa;>D{ ziTv%??SBNhwt%$in#(EOdZ&PuXjjfe*)k52VXpwDt`+{)PI*ki=9Lve1%+C}dhN1F zmd!JQWjQj%0hQNos>G~g7@4sktK_41b$zYo>zlK~Oj0xmtf@Q6Am}}86qb@gL?XeT z2t}qD5_##SVs?L^lqloLFBXJ7i1nqH_UD7>Wq-90e95w~cjR7$5T?tPTUpMOuhH4? zB~K!sE#vTda`3^+dTDPc7V)gINLgi1OtgE)qyeslSuCD1iv(-y@eN$<2W}iI(V+R@_^ldRYO}-;#iyF!OLGvKPQt2@g0g6NgEnXe_0)goc8`|ed;S2V W36RRhlsT&a0000&Paepa1M4B_AAC2!UNM`p@Rsicxj$EN0zB6959{$ zLfGbRt^I=_$$yhVT+WN23h^;VfV>H00h?hesS%`o$T|4OWLy?TB(wn(*rtWY3c}j9 z&)4j6T8Ntx0y$XU8F1q$xElU(D-M_u+17~nh+P;7ZH(<65f?_JV%#K>7(uASa`Pxe zh2tP($ooBFF~RQan}io6Bj`4kFw)@tsIpTd)uMk#HS>Z^DBK zV{jZ~JrPg|pL^ljh{9*W55iz9XCpx)2vHzBiF74s&W7&^E=1gbuLwdjMuG~VU;Um3 z;cA!F9)Cf_Rw66mvLIa%M8xj=kJk$HBp`=a*0`R6P*Nk7j$kFW_&-A^vGxQjQHBsD z>JW4(5HiFQp++Ub{v5*0AHebYTVI9P2&_+{aCH(?f+u2wr(wdA$RU?C=y%_Qo)8x42C)1f)T)AAEv;>J10;VEn%9vanSU{~`@R6QH-H36n9=Tz9>Bib>I$?6 zXGdtY4S&@3*f&AbzW{g;HlhfcuFuG=&9!bhy;8bDaQhmL+UIwq1l~YUp=CG1I;f#j zTUcI!2IL%qiytqG7AXyuA*I{_dwTR)p#Kny)ax_Z`rGh0+Ot$1Alp?kwynSW@lljQ z$VQf+$syMit~5)#>kr1h1?67}Mww<;$)@$x`eR~B@tKGHOy0X)v)QF_-rDo2=yl;A X`X*@NQ4DQI00000NkvXXu0mjfsndwG diff --git a/TMessagesProj/src/main/assets/emoji/0_28.png b/TMessagesProj/src/main/assets/emoji/0_28.png index 1cd0353c7840be8829b376dd242015846fc99fce..87b6fa5147ed211eaf4b52b5a4d9832bb42a8324 100644 GIT binary patch delta 2178 zcmV-|2z~dj5RVa%B!6yDOjJcja7@T)1;~9Q$8Ha?btv+a2FGmX;AK zcLUyv3(jr?^0*|yiyxV9H`<#Ww|f~%J|+L%R{#9D|DOc^_kWvXDg*!fjQ#D2{E`Fy z=tS`7o3M#RgG&j^xMXoa5dYCipqq|^ero>aWdE%P?(EM0`>XuuasRvt-pFRJmS_LT zH-=dk@#Kf^;B)`|%>UCn{_{xe+d}{NbN~Ir|HL@<++g$a-2c`R|M***eoNiNL6cSo z|J*{rrAF)MxPSlt)9K=?#=VpO{oS^V z|K>CP{p|d$7XQIHs(&hIVp*YmCR;`(`KcB6qYS5J3IEPD|HdveD^!ac~SAz+$lou8AG&R|O>D1duangd&4CpyLAjPpYf1U@{^WG;KTwT9NNtchEPZ=>!` zEPqRY9R$N+;<0}fk%S_ALGXJzhtMy3VJNVGY?}3x`jQjZw6e(Y2I_eHjo~5_P`+R8 zak`>uQF%Id&hxxrOU}2eKcg0>L zG537{M%lt1-3IfHvVn3$tzF}@xg1~SHGiv)!fQZd^?ci|9Wf&Lpi4MJm8yXRXxg7t zPHit``;$$+AN}0PVa=wf$H&0o5C(++L9?wx4;j1JESI$l7jpgna5(I**mEyhAt>g| z{WcOwkvTF9B$23Q@sjIwRK3&$TBZy6{%~ZPqv47@b9zV_#+f4$n@fppiO!h;bbq^) zR4irG+uM%XMvDE(9)x5w1?+S&;ajv2{ijov5Ab*o;DT;y=eh$cL)9F9e*3nPmSQG|uv04yGkSxYo zXbT8$vu1IUVG^PcgC_VOvwho;R7=E;W!eD>Quy!pJE!+jNSb}vxBbxYbboy3Tm@>5 z>4R8iwyQXv3~k@vc(Yy*1fz#l^SgO}HM$zzTeqL@?%HOJh@18!<*t4E_kXWT>uYFF zj+2MR+-DKQE7y<)hnXK1)yEF-B=YoSUI~Y9 z&gHk`lU$mGbWRXt06~CosDFmpdfdx(qgn|=`_lOnL}7<;hqk>Xo?%F2(YWRU@ffR0 z=!ccgvjW* zQeAbs-Bo=70K$5`wx=LUOL?iMnqI~-*y#A3jpwluE2uJy+Ib!X81^tC6hRysODuzH za1RfEr9m%{>G30&^*m(L@%tzNqVDJ?T2>I56ejt2r5fXPztib>o?ls9B8!TTDmXp! z1kmXS;oF;|FH;#oq<{06glnKj-v{CUY&N?{6K@^Wh2QG|ppf8005Pdq`ZB+L+fp@5 z!ZpyNPd&`R17~2qb(`Poiw*-M^v5i`PAp5;u+4ZGRD(x>0fb++hu~doV0OP$djb$+ zyt-wlwlruJ@g%6>P9uX65u5}w81M|pn1tcfb#9tg#mdd8eNLJXT(e&*%v8As0%Q0)u9Wh9N~J2Bc87EUmczv5Xpf1`vd$ zF&!5GHW>-JQIXQSkMjUcU;GQ z4l#-}VkFLx0e>kh>*r?)U)Ky_2!s@Z@Sscu5DD7P^Q7<5sxY_+5UEUg0029Jk^6L( zK%|S2!9`es!@r0Gq;MpNL?bF96jvUn^9%^#;Ns#S(V$tl2oO?aB!CJesJM)aPw8YM zo6=|)LZFbtnIizWf|fd^!-wZ^5_4FHia-GqryK#Okb94=;)rfFIY&y05mw+Jcmk<2 zkW$2pi)ADyqXHoXjEK(X0jTl+#hIKW8By{E6fiOx&Kr4!0Gaq&lXH|+^C<(-5PDAK z)hv&YmPGoDh<{fySw$`83WZ!zRk9hJ|8Gfi4*m!E2S?yAHoy=tHvj+t07*qoM6N<$ Eg13k<00000 delta 2082 zcmV+-2;KLO5w8%CB!4(iOjJcja7@T)1 zUFPWMrt`>_A{mH++D_>u(w$YQ`iR;umx%d;)7GmJpY=6@U^1tB(4 zo9%>qRDbwfQczuoqbA^G=j3J-(o38QN|1q;zsI}Iu zKF&-}YtmK%?Cj+XQ4H`@Bkhgzv?D#J5jNr%cYhmR7a&S3G~|$RBk55?C{aE^aeaC% zmllL9N!N@trM$-L>aIlnH?VA4h~ff%^*t5JjxW`uMGYzC=@^%`xTz$%efa4-+}_iH1A4eWY)VwE3(Kb0 z@qfLlepg<$PpKPG7%yI4WJ;)=Ap`_MViNNPA>lA!K$qyT3f=oMi_V!<(zC3$ClHoBJP6e`b36ald>M9QF0z(xaw)yL@=`Z*CBj zL{X9?4Q~uCuI}OH>FM{smLN-9B9}25HGdv1Pu>*sK`>ZcGwq?@hlaMPNg|oKxw!&a zGDgE84~z^>vGJ8X{-uf-?=(P)fB$!$SE=!&AMo*Iw)u!iSp zdMJCUs(3*dW5)CIGbUTYc6C|Is(HEE3UynQ28eo(}{F zFVD89%_ATRe1nz>myOzE%>n{JK!0LaVTb?-ZSi6Qp{sz(iWQTE7eW~I2#Hiqc|$6M z*v=)%MHCDmWI`-Z3p0!d(ksG`i2&K689mk-muGJgQNs{{AVwT87pgwC#UTo4h=WjO z2sZ|SG!o_AG2*Bx$z^g~8SUINL8qHX;=LzD_YAd|X*VsJ({kS#sLhL5RvLqC>?HEYWbl*t~2uaR?2_1nras1|hUTh-~_jA)plX^Cp_gRBQvWjds}N zX7JKt!rH#3O+mmFqB9E&xPKg9ll*mrQgoWdY=d_@D8}Os4C!Jt><^&+&=3tGaNtnV zc);~-13Pm~c{DohY=f6`&2wgBE!cEaTtJd2jr4d!fDK;pz~BMe@P?o4B9=$4oE=)# zW~Tug(R!V@wrOaPX%FyqIw;=wBNi}5ev+)CN0vwR_1G%3o9GGINPm(vb)2cAW6dUg zgGgaWN5DzbG+A>Kopu3$tQgz|F-R#FLH4&47m1=EFcas^?&09eSKA%3!5M)v2jo2^ zmg-~#GQso6+6o&P!|{67?mdDa_f(cewB6QWqRm^H^`y<3@<@!-?e&!TKOu==DLutu z9`+`v9|skfjf~-YfPYwXfmJs_0d~S%RsastjDU8uu{Dou95GzQ1I50+zMi|+B&_#5 zHAr_E0cpU*k&0cULJZU++NFW4DBkVeWHPy(O(u7DOHWZO2RkYwblP21;z;>3*w`}w zNm5rV3!(T4_`{n(- zM(Y`1PpF^}pD1ilKctjDDO7V^aF{U2RSPHi5{rIK zG%sI1DHbY~v$IO2P&_H;IsMDZCYMf`N^E=p{9n+2yBk0KN?M=lZ%)O1YpB5YL;wH) M07*qoM6N<$f^#_P!vFvP diff --git a/TMessagesProj/src/main/assets/emoji/0_280.png b/TMessagesProj/src/main/assets/emoji/0_280.png index 809a29f6e5b8938349116a33ef0ee59562bde462..294db2538320c8047892f1992f25f69cbd779e25 100644 GIT binary patch delta 784 zcmV+r1MmFo1*Zm(B!4qdOjJcja7?CfRjzkhfKxr9Y*ey+UUf`2q-|4-TSS>=O?*%~ zpJ`CEeP6zgXR~`)=NL-c;)gGt)$*kZyhLduvKK3Wb5 zmemL>$|Bc#um~}4n>ZSUFkS$H+1)Zvjmj^wxC-PIV}G36HY_mbs$;BHcK0-u%OWyJ z&TT629>G96Mz~I>E-a+U-$z(DY3(OGM2N^V-9%U)49v#Jw-KZ!G@NQB^LZl{7HVB& zj;{zxY2UbTTyFr{!l|j!a4vYfRI6`X7{&6yN}0t&kN93&vOkU>dc&99`9-N}WiAZ2 zwX@OG3xDp;^%i}NjuARrhW!S_wKiM@RDEkp)6}`eU=L21H0BSxuT{o(w63rMK#aQc@Yo4r O00{s|MNUMnLSTYzn0Iyn delta 724 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 P00000NkvXXu0mjffGDq| diff --git a/TMessagesProj/src/main/assets/emoji/0_282.png b/TMessagesProj/src/main/assets/emoji/0_282.png index ad89b67e3d96ae4f95337d185d9f92ca59fd3b02..0602cd7e3f3917a4ef609bb4c4f9be9450ef02d4 100644 GIT binary patch delta 622 zcmV-!0+IdL1&0NYB!47OOjJcja7-^D8bdKEJ1QeUE+;rBAv-D~JuN0%M>|zOH%m4! zJ}o9BzcK6p000PdQchC<{$h%_-aa3$(0zaa00Ih0L_t(|+QpaAj_e=^KwCf&`2YXi zO0TPSXWA*<%{`e1lh!i`mgw@AFaYF7hD=h55Iiublnqe~D}PW+dFViu;;2T~0wyht z6wO6b6t!R&oSH(6mKdbv=}K@=@PAW)_LAhs3Vo_5Poj99PWi=(gtwM-#nTP0hL5vp zurTKgxB+~39d0lpN~$WNq6zbzzUKy?D?WBq=`#uGFslr>h2TymN@KPVT$e-2IZAxF zGp`Wht7Tk+=YQ3Bi}X=?A457ZsP-%gPt%A95prh6(-_oTB6U0|P%BnRZa7h_rW;<^ zF$Srq_@j$jZjRNgY7Dx8d!{at4O=VI_lxBQQc+u{e#%sC;+8RpTp~;kC^3X%3Xwj9 zph9>TSEoaU1uHJZ1b$Gdqq7+$jh(r1zEF2jRR~Z3;+NC07*qo IM6N<$g1{#h&Hw-a delta 704 zcmV;x0zdtS1=t0UB!5UyOjJcja7@yK3E`Lv>ZTLdiVWC{47g$s(t!xecMI2v3EqQV!Q5#p5C5CBcMR!*so-X1=sAzcIL6Gr+*wFeiHtx4X)7wLeRT1$bfCxm(rJGGk>Qjq|L~SHYc3EX4 z*kB;CfP^?LQJi-L2(CdV%R(fYvi<`g_viU;-MF>HHvd^*he2u6G*MM}b;)p=QK@E;a zBB@2bRpStdm^%nuY1udGK_H?mqJvnm#r~`_k$_OTU66Nd!A}SLaf!YokqfuTj+1xd z-oDTI6OnKiJ^LIFBD1i!DC^MCLNW0akT7!SFgaEx06~W4NE(EmjHdi-K?h>Sp*yoM m(~UD3F%NG>&KNoT-TVN2tW(N8YkEBZ0000yJOF&OcwDdD$E%G+qA!4WD^?l#;6f2!T=_A(XQBh)8Mo2XQ6C@apjp zIa9ei2sMF^8h=4>KVdYzaK1MPhKAShn#?>}ZMi~-XZr~4gJS4l==G@QSz@eowR2lK zgd=N{f&gObF=65$qVq*82zv<8 zKBz0=FNoZKM*o6nt|}nVH;ATgOHfk5Jnun>GO9*KHY@b%^D0PL zc7N6N!Gr}wQyEG9G)y2c20H*e0vKwYM<mlUdoSRX#=W=gek~Rm|x2BErNQ4 zf0UU^Ti=#=JR>TVfIUNrG^po*Kml=T3nQ1Y2FKc;03a&6NN57W6PV!RslIVW(Xw5eR<~3R)J+;vGRL zgCfj0TB#O7f}rH~qK=RdckVm!T%oztAqkXxZ+5DbTgxM&T_dEV6kg=bilW!M6@!IB z2%9B@3<%{@rD{nc+1Gv+{G97s+>!Dr009gT3FU6f2C3j?GWfaXW0lU$5kcb3BYz;d z72Ei^*4muv{|LSyeED(fVra>{*aZ&&J+6+mxl0qI6mbloI6(9!yZ1+cSreL0OX&$9 z>c=BwmaJR5I}=_C=;9qAqsRTM#lfBY)&k(|MA@A6sz$$zC#64v8~nzM^R0+IL_}p` zeL=9+DLT_Ncc#5m(89aQ%V?|td{vME*_Hf7W3q3S)DGRQ_$ry&*MhmhO1Rk z{_<>Z%d&0jx^Cdrwq;fn73d7AoQfhV_x~TE0a{S=oB1DFCCAQ|81JwE0000b#fVs)W;*aKe05 z*q(Up!=UxhuH>_h`r5kg#G(D+#Mz#A{^rZijb@PTmDd0O01b3fPE!E(u+fS+WB&aZ zz17X6icD4j00IL^L_t(|UhUUga@#NrKv9e0(-FXjwEwjh0)K^R>c%w~rjvdY3pjH@ z4z2O+kCW1EZj#+LJB1{Z_dTyOhC?E1@e_nCl?X83P2`hUzko>7i~J|#IQLoNt18@d zMVujm5Z_zz4-q&^>_p60_$i|9`)7&dtxx_WDg^(T&xuFKu$pobIT*7Ie@|S5Tq^(x z=V6dkE0`g}7Jm}ABn%m^Eu2!D9E*YATe#9)F2i3ss6y}r~a zMptAP77Dhz;y16+Dh2vT2MZk0tmchHWJ8epZVilwziBeq=t!0hiCCP1NcYw-5Ym;) z=n?Ipqfi;g8FG~{AlGp$Ui&v>5kxA8;D|;2C2$;qfr*+Wg7;95=a6z4Odv8bW?UIv zAR@{ldVfOR3-FCH;Rc9)q-?OjL|gm-aleQn0uzVT3+W<4;b8&Ct|To?;Cmt>5lKxr zA=n5UfpO?cybxrNauKb`BBK?7h9jbp2=!x=3Rz_I54<;#g~A2_#@&X;S+j28oNYB$ ifZ<8*oOJuU^8=o!M`oT}zV-kB002ovPDHLkU;%1da%hB!5LvOjJcja7@aFVA!C1^wF>J%&W?XV&Sig_v_I5;lbamhtijE z^wF^F!l3!txcl9`<+YLa)Uxx=tnkOA>%N-cs)g8^bNk@HNXOlf0000DbW%=J0R5SQ zKjLN&CDgjivF&<^ZU6uSYe_^wRCr#cn2m1hAPj|b8v<+i-8yrF#b9i%TAJeG%LKqHVO^Voq zHO7PPn}sl(!hgk-VhAQ!`eo@sNK+dD4FLSJ7hQNhbBvinI9y|Vyd9r_V~8G5y23M!BF(=g2A z(oI;_fC$QudPxLyOGG4K4}_5F*+UaUSnC4CU_!U{Jbz5*k+D8QEGuRJu+E#O2tgsV z28%HsA|{Un6iwsx2%$D2(9V2}kRINf`ypZn3V}j|8J{2)4?6ep95J~PLW3p5!(kqG z2(>H%wJg7pMSv3`j%UA^w#`}6woUSuvSWyfaA$;)o3}KjB5;$q+1%6zG4v-w?7_0X z$?nV7&3}DP5#9)~dP;Ydo4$P?6`?aiGC@WU1#k_bu87^YX(A%YMqtEMdb>2EOiKaQ znIsFr!VN*gg&~YB2#pBO2$7g@!?@&-1%V4HVp)SD>`jboj)@SUIfV0O5I^b_oz*uX zG&9aK-Gd{9W<-dHkcq$NI|#{6*9WggK}O7rntu(oaUUZiLffcoLs;txF~%H%65sf# zoZCMT7D@;o(o4<3W#%^mss=W7qKXkfA@UjU8uKI=(I5mQECX^mdAgcp28W2loH)dB zUd4NW#)U5`=j7=;W`uPZf^Lky%%+yD@qrhK2>t`%YzYy9H=z=m-o=YQ6T%h2Uop(2Q=4Dz?iG-Q7PL?#sNIRzK2 zV{7K3aI)ts<@vZ$h^Rr?(QNc$Z!1rG?{RXYRI52Iv2<`-sB!4zgOjJcja7@gTYRr>r(VTO`hFrsjU9M_DzkO4{fmg$ZT(4|H z+pdPyqk7)9kK(C=vN^hjXEJPI2zs!F04d2PVwyd<)(-(bR)a$ zo)E!n#7+@sB!2`&*gYVQLX5to`PjaFFTx)+nxh1B93;39T?u^>EO8r{MP&9> z=te7{guTC+QMe=B=q1vI_e)L1xb)~H(r#`;sT!?G1AkPIw7HSTA`>ESqa#&_X(MwV z+N#luWFaV_!fFQy+_Ry`$4GuFp`#cwD$7#szGI_7F`L=H`iO zyBmrWAx;~az+u8Rq9&FSQ}d)s6r-1z`Vo63VkH30gt2ELML8J`%~S|3vjA(RV+oem jI}1<+=7Uy)=HKQQpAJ9g$p;9r00000NkvXXu0mjff6Ea@ diff --git a/TMessagesProj/src/main/assets/emoji/0_285.png b/TMessagesProj/src/main/assets/emoji/0_285.png index 768d0600323ffad4a2cfa6b90d20e7a7e8c2283a..e82b1f1955550b6872e68a5479f47dd4ebd33d17 100644 GIT binary patch delta 942 zcmV;f15y041;huCB!4_mOjJcja7?##Ov#aH-L#F;p?cY_htr~a?9Zy-xstVZPQiy? z+pmbzpLgE2kmJ9Z*QbEtyOqwBY{rIM+Rtl#y;TR#`@@z`qNV)`yL#Q$xfYQ_A*k zBlZ19seYTLuss+Ra|R+%c~W>ZuxtfNk&zMh*$6k8ThU{@)+Tka_r1pw|_?n3#I>mJV&fdV5JCkd)CYy z!TrQX2os6$Qwp~nh;)T;Ui7s?HkY07{}gszmM9x{SyuZ`%o+)iE>bwV3?sS3)&FZ# z=sM(~YM0j>cebirLM#-WyNoc${TcZFSZcXulFnA_t5O+o_f=CCVb%d!*xYlxF zxEw!H0DpFbtpdJON~hD>qafrX^TINr>8bLSp(py@&ZG#hN82TV7{gjjN6<%FffFIN zD#^aYD4&cqGa|`-Le$CsnFfNmR+4Jb41-q@JokckLECe+h`y4Ny&`6aWMGw!aC|nV z>kz3^NCnmrQ3NdA3@+r(d<{X8CfL7={(TY(LVpO1*i4gIyc^`wzlD4xwr>Q-&~;3q z^$?m{AxTxZTr?x1bON92RYM$C&#o$h02mQW5Cj7D5Sm%csv?Rc$Opm;BFcT>=S!D1 zv;WZ2YL5VrtNlO_qr*!tGt@3`f9&PiPYV7()SiO%_Kc;~9U<<1#HQ2Dq9W2zUEN|< z`+p9=8k{0{9i%<~fl#m7kNg6_7X0vfBia!RIoZ21s2?j6R4XBR43#>?t#c6l QHvj+t07*qoM6N<$f;4Z+TmS$7 delta 666 zcmV;L0%iTg2eJi_B!53pOjJcja7`2uSD0P`(EJ}2-#GKlV%P%#TocLo`_Fd7Bm`VVR1lg8G=bQ7KMMr6n!tu2FNO#)*mbxaZB0noK*H0I|1c~OTg_u(O%wygVBipeBleo--0wET6OoQ{ zm%-S*>b+QZoA)6|A>cu`p)e9~Y zHZV~}BHH%p#z#ersWk8uqJE#V5S$@XgtmR^7a}nsg59^_vkHk|#40y580$O1GqKPz zTG^A3gQ$6Ep4sQ$dRbVO$uscTxS7Yf;or_LzY`Ql=3xcY2mk;807*qoM6N<$g4y&a AO#lD@ diff --git a/TMessagesProj/src/main/assets/emoji/0_286.png b/TMessagesProj/src/main/assets/emoji/0_286.png index 9b5459c45c33abec2ef5c0c7f6ce6c5de0f1ba73..9153f2e8f45907ecb6196248975a0052b8bdd7a6 100644 GIT binary patch delta 867 zcmV-p1DyQk1o{S$B!4zgOjJcja7?p)UX5Nxa7r|3L@%g!SA$wWrfyZdi)N^GSh$2@ zzK&G0008$ zNkl|965JiiM1Iz>b|DU}&%%#e)=LEabm?m~FHh*9&uX{pxeTh$7@?Tlp zrlk1T;${1fdu9o=opIxmkZ`+z!wx5!%cQ2`;s*^;YKgpL0ANAnIJyv~fC8luqQE*j z4KpCXMzA44@q;B8u^LJ~Dlib@m?J=KLAjL73@p1Z4Q)v@#fG@yj_wGJDVT7(f;7EG z@Jw=cAPUT3NPn@i;7Nf(Sq%du7QwF!ftgwh5n?qA5rIT!f+)lQWr?prJdiqsm?4)% z4P!VU(&6)wU)Jy%2AGIgk_r5J|8;+(ht9;i^GvJW~WK@kI;Y41bSXBtdh?jUpJozj(EUt;Kam zqIXG@skhbcrj`}eC*)g2OV_T#Le zrf7x^yeZFNj|x}2y>K~SO^SPi#e?}#9EBKTH> ziA{S~;(v$3vxt}hiD20kQ&#Qg7AWqznp&flU|7P-7h4FtU5V=O9~F5CVFpz+NjD8e zIGhw@3NeMxBsT&yfwdsl6w{%QrYLim*_<_`pC&LwPBoG$%s^aLEujtzH$y{EgeaOJ zOsop2C7>+DN@z+i9rjx}D@eqq!MT)HqOo;x6o2VkkZ2DgVkWi{jXqwXp9)kl9hak0 zpVg>ALOTpi0jx>IR<)1!!_(1~OE@dUYP5`EseX83rK~R_wibPP1+Qsh6Ts;}7}Y?X zp&z@;Lp2!Q6lcdJ+~*k>a#4ffSPhD;oMq2xVgq(^S-hp2f<(GROIr3K=uearXzE>( z?_2;)>zQ;`!I?FaCQrOYaK4jEDa&;8rx=!!m2!|3xL|jeeSFLJ#C18CE6Yx)s8l)b tuD_m$gVMgnxUTDDtUEE<-EscT{R0j#XP-di~j%s delta 589 zcmV-T0rTsMYMF?vTUYCI(Cqv!Vk000VfQchC<{TGrlx7k&2(ub_UW&i*I+et)0RCwC$ z)$5MqAPfayZVtp4c>lLua6F|^X1Au%s?ul+-KgLj`#l_IQw=O|DTHsYsUH1UBS!r<{25AVWrP_);-=9cLFH6)y zrB%A_1bGyty(D5MNC>=6LPMlMlp-xenI+UMXb^(rv1Wzm0n zSU5KkVRwo{WrG=kzFrR|K=H+DVjwT6AVMd+;(qU~mVY8e9yLZ-u$q@WwZkZnt;}t7 zA}9z4-Kb*F!=R(YZZrwIWuxa1=7Cz9j4ICCj&PG{NC{_@iM!?9%o;KYF#04eA~hzl zn^l8rPzSyU>lTPOYmi*4TCEKW#26{pI8vBsHZ2e!M0pmP^?JeWOt8@x6N^U@Cc$BW zFNU75az?#Q!qPnBATGxGMy5~?p@B0C1~73(JPZ0nXlDSTSx!iP+qN$BU!Q_`GcJrc b^MCUP6@E3kO>&aE00000NkvXXu0mjft}y@; diff --git a/TMessagesProj/src/main/assets/emoji/0_287.png b/TMessagesProj/src/main/assets/emoji/0_287.png index aa72d19072cbe0e256ae809aac6abbd2bc575aeb..903460b601d1889d7990876dd95d9658f158c3ec 100644 GIT binary patch delta 844 zcmV-S1GD_J1mgyfB!4qdOjJcja7=woE`v`nkXtugG#`9REoVI?S~4D@Xg`o!H+@Pi zn`AteUpkLjHiuF%Za*fUXg}dfc;^5B019+cPE!Dg&bQlVto$B7u6*ZC0008jNklXuYd1JDZTy{=hw;QzX;Qc zOyTh;P9W^cqgiq>z?5+$d0vkhHYO}XT7@J^xIrP-`S4z43r2EY_sVHTpwJZ5AP5T!-z1%8w?LIf(jBD^vS?_PdJ^i)4Ig`*+| zfQ9CpkQeFxydRunTrmj@445h++kdPXd@2n)uTpApFy5#Ei5M6MuMl<*I? zqN=d2EQQ+gjPMX}vL6zm3WMOs#AL$rDN+##n1UV=p?@%l=L<>xmPjdUQo27BV#1lo zZt|jG@srD!%+$AHBU}f9R~-`~!Y*H|L-;F^eLX!FcuE)R_(tRz3;c|PGvVF{=|mt1 z=g4`G=|GSXp+WeSk!m>-;Z}g*k47dCyC9X~Mq~)rIU3=eC_9m6Dt816j5EPIp&$Ly zPQu+feZ>#GHOJgc8#`fqPlS z!PyC|+VCcbocjoA-d_L$)dHd)h2AgQW$n`I5c>IcN+6hjL#$tV>K^JqgkV`fpd%W# zcE7cScEDZRQ@Ls6f|6WX02!KUnS+7w!H8?hu{{?j7#GJ+T$_wzVHtT Wt7yX9KY`T%0000A>7bjt2jQ|3PfZS2oD+Xcq5U~5)DXp5cj8% zd2fM4?DrL!mw%2##pJevIYl&4)q}We$W@>yvk1?*6IfD&vifoI%|66(1S@|vn3F^k zQNHFV{}eHa_V*|A{3Q;&m#_;WkXY(8-b40N;a9{++<78bM;LE{SkJs;o)L;?@Qc9A z)oVwGE0J*kr(i8X0GV8f2I32y#7JHjc7?=Z;v_74@qhKx2qaFz%pm_)c)UH z(Jo>N5`fssdE#4z1R*Owq`44?146JZ7-S(tMRy@RNYUT|wQYGC(ilVMj6vwYgMl^& dVEec83lwzU9)1@UVNU=6002ovPDHLkV1h*NI;e&Sh4zN%RO00M7GL_t(|+NG9>a>F1DL@jYy(*OT& zk$_-RQx~$HWOB?tuMh@~XCWS6D!9{yuPFXBxwK6QbT;`t3V-r>mB)30qw}t1hBpEM ze@J0-AOt|N@;6S4WzYw~0G#89-zmcoaT3#uHGlR09 z)emu*aCk+qWPgDIc9x1LoCT)6#WPt5wg_R>+$R=M83x=#cqJ4@+#{f4?S_@&HWAiP zWo#otomXEVTp`%R+C!wzh~$PPIpFL_@LUKgV3fz_I<6@owBKVPjDJeg$!#J<4ExF``W?h~1le{z z65flst^N&>U_vmtI|GGolM|8>EW>{p=>dUJs3Tq(;fmmba6QD7F|L}GUdod|?p z5q7&apnn>>GU}eH$QS#NLJ{pp7U91MR1mg>hXGNtvA!v9YHomx=qZ?sOI31C?dCRJ z&tfP_sH(*_+bC{!75K~9q%m%{HNu$P{Ca8U@QNT(#+Z9FcYi0Cf)&zZ^g-|L(JufF z$CDnJdUXC}*LF7z$1x|hm2=4r00173UkH|RO-b!A$aeayw@Eak1gTxYWxAS2ts?LgO^7D0000pevP delta 1525 zcmV{X1hzd?rTrC#|3J3;$Jq&?D3oR}#_`x+`MmO-ZDT<1TWJWTAKn&lQ6zZoM_r5d< z1q0@x6_k>U=A<2hf`R6v9r3g%-If#Ws~vrPeV0uQ-ZK65W)J0` z4b6HA@UI#H0RV0`3o9HFV`OQ^gcx~vbwor)|JY}NUpmgKTOg`p$p8QVDRfd!QvlfH z#wZ~C4E_~nR)0ABN|d~b{^?2j@^Y(oy2<6E{+Y*!r^L>r-yuPet#fhXzz7!Yud0MbhYUdLY?fts|VM| zu%GmOBY$G7>Y{tI|9*fDF~oVU(?w{6-LroMQEntaw{065A!4x5vWze^x|gGW?&5_l z9N3QOI!%ns;D7)|Xw1%s%C9q+GJ@^6oX<8g#?0j)GUA2a<^C@SjRoB?xfL$Hi5Tm| zM7b_OJP&&Erjc7mS}j<9|Gollu zVJtkad-=1KYuCmUR#@a|l;L@=ShPj?Vp1!@A`OC# znmE#dL`cF9j1Xm57Ux4TSY3w@Ud7aJY)1Qk2Iwyk$#Lz+)u9vW_`4T|;Xs7sr zL8J|jTo8i#dFBGb;c*f>a<`lWlqtWS=bR8AL~vIe$qkK#;aN5Tn(cIrnlI(L0ukbz z%P53UV6vc@hASE=rde3#D3`lJym|8g0!T0f0w&AhmZ=L1BC#d9W?&&Hv0oD6hJVrB z7n5b14-- zfbvC^=XF}LvaIterUMiT2~d%W0ukp5&9`ZW9)}*%k;9UtE~7wIvn&gu6d2fkl;;Tm zxgUbX}UPhVfXMZapKgG2%^<^OeIfgW#ME&Ukxr_5hveiXnX0wZbwynxj?F0bVN zlCdaatV{t?b>)ZL-~it1R;+~5U|kI&76s5s7WqNo+PO!GHKuBZ77y zKfBO5EbyU16v2wR1}ZRAq%x=uXy{P}Twow1xo%AK2{D)>9A3qu3>W}Oqkte8X$68R z=#404-6MjscO>uYP61p-DnmqyzavTo1h#}IxL@sbK7u-+uM=USchr~nby^3_jz5+u zsMA5GX+*Y30g^tRPJ5aHg>E&i*Xt=V#~KO!0nnyj8S7};gr#XY{V<-)=krtejuo-= zd@_Fh{_(Jn9>&7aWYR;_WPbW`2^7TAZ%Nz3J^+1pjlslWyZ@#K%TI$A0LlR&S|T9C b|3QBP#DkcyQ!hva00000NkvXXu0mjfE-}jO diff --git a/TMessagesProj/src/main/assets/emoji/0_289.png b/TMessagesProj/src/main/assets/emoji/0_289.png index 32b4f37930fb8b9f76fcd4de38f2b255a103f766..27d83bca3dd6f0d6e54211afab82ec5bca16c4c8 100644 GIT binary patch delta 1513 zcmVwP;a&mHedwa35vChuU zZ*OmHZEa|1XgD}HYHDgZIXR!7pQEFrR#sM}rKOpfnUIi>K|w)OR8%c3Eni<>r>Cbh zG&ID-#DRf+ff{>7qZEbCHbANL*G&Dj&LWzlqE-o&6 zdwZXspQfg!+1c5?zP=3&4e9CW?cpk~0000VbW%=J0RCQ7JO2J44*veM)|#$;e%ylG zI>CqHzs~Yt?x*N@+2}g}00i$zL_t(|UY(ZdZsIT$MoCCW*eNaDXvh1S4e0y7+uUoD z4(;#*a-v8G<$oUgyLJ?hu2Veix4`~+|5T2KP&_~6NTsCGyX{kPub|xTbYiVF#w3zi zRaJkU?=*aB7@rBjm{GB_W~(v8DfR5*fO#{48>u z^UbY_@e8F)3iiGnzt!B;j#?D{pP)TqFYbCH2k=Mn&7Ttmgjpj#uo}D8@ZpoD)V#n``;D zTCK9%6~&`f#Bm2uMmcSicq>Mb;U0x-JPPVsn6R-w#-sbl2s6A!xHOXRH;8a2V@ik* z3P*$#V~B9K!h6rTt0$9*^KawP0J66l0mW$pJAYvaPje3C2rR@fcE{PV(}^UnLk-2l z@o+fIj??MGKt;K2kB1q|qwOBbVTz@0kF%)Q4O8IOtaRH=fq_BNchjgUqUYtH9MYme zSCwikD2C*~NoW8agA}PrAcjUju^g1chDk()8lor`Ni@VH>mfP%N#s#6G)HyQEXuOH zo`1t)H~SS)>F=_l$kM=azE~{g>+C;GDh(t738GZw_VeqqA?Z(dEO$qR>|Vh zQ80lHn}7ubM)r!QUE6g>g^EiopGEc(o;VBebeHYGaDSL}S|Q9+jwipfho5R`nqC10aCn4s_mXY9 z;{gO!lOzc=kZ{kP<3Kdkr%7a!re&`HxMvbDO5@=nG(#PC5gtWua+;h@r?4-2 z1;|C!cEA*XPFb{}Qb-{@2=Ls3m#c#+>gc#vj6p1##2{gBh2;|g2KZ3@AAin278eSF zWA;@)AcXKx@LK}O)6s>32?94({D2Y)#1x!gN+3l%+V=`ia6RI({!fVETv!*-#NX^a z9sN-FxL%a{^A+*Id~P8O#BeAaOUQXP`l;XnkI-;mf{Hi*lL2GqY5D80$UUwW$J$?@ z*11q0-)3p84T9f__}q1<<6@yczV2qRymFu{R^Ip7e`cTv;S|TmaswZs>nEUW1*L>V z$R!M+ST9Zg5xY*Aje#tZrt2ks_biYAe;!}w%XJFF-$hxL#XsVQ_&R?91eFrU5Mha_ P00000NkvXXu0mjf&^6uC delta 1336 zcmV-81;_gP3(E?SB!9F}OjJcja7;%rDNj*VAsQFgo_gxOo49gKn^`<*Gancb4dJed zkB*Gin|ABJoVadBBoq!;KQ^&uLiEzFFcu8vx0AMQM&YiC%g9+ zST=-%g7Cgpz=eLry zX+q43Vce#G#(`P8aZ3K>#E@M&tYJK4WN3VMar@xGTQC^`006;=W;QoDKT`?o0000W zbW%=J0BQa2D4^R9BK}kO{N%sGMug{(%Bzfa$@)aNTgUXIV7dIC000CgNkl2B*b5QV+Tw11p>OT5K)Qd0ZAdQ0y6zgK65j1*rey^U2A#XUcQK<0crXNEN7&VQ%T zoV6vqocrB&h(90nx3{M@M&=Jc-at<+VmzGQP&3vl21uXZO*lXd%F!Z5uWgK%bK4l* z|3M7)awbB*O^iMvx-E|7zZPTEB8Hr2ix@5E$>2-kbbo)0!A9F|x5M+@F~-^>FNz{M z-y37Rw~Nc=QW$4B&nx?G1kEmxaN!Rp86#c~z6W@OdQ_2~WQ;P1CII;cfCv;r60U)7 zc;005k05MK01|i3JsIQOFg*_;+V0m~+1=H}OXBk6(=Nz8_MLDso zh*IH}5Pw6zmMK?+8X_40K~1#Hcsv-ePYBMj z4@rDH_4Mm8r5WGqCk7lB>-AMrh&`9B^wT^qPuJ(jX#mtd0D>4iZ|0+H3)|8(AP2@M zLlvRf#s|Y7f@#Yk4<=aSn2_UGzFUm|UfV!MMJU!1@kj{FaSY6cY5+)#I%A%4VcK@F zXMcovr67t)TRRggdiCA-Lg=O;F@&+M+?n=dw2o1BEo^xAn({dYC*AszG`OU##dk!&b0^Nq{ z%L*`5D(fqPj|@ai2(g4|)daedhV<$yyMIcany62r4{HR*P!3E}ZWD!Jn1-QGkXl5D zq6is?STaORIQIy_r2`Af(;yHc5h6&V&k!^RfG|QK!`v%`V_3F2y#xr7EYD+5o(W)J zY!KBWKnXuEHF-rGJ4rDxnG93m#nq*BQ6y-i2HqrtAQ~`T#=)0YKofx~bE$rMyAGpX6K!$;!Mm_Z=ag4DESRt}ZP(=n@ zfB+Q*XxJo11PH+4`on~JAzI;c+}p^D diff --git a/TMessagesProj/src/main/assets/emoji/0_29.png b/TMessagesProj/src/main/assets/emoji/0_29.png index 3210ddcd673d612bc23bc91fc0e13e15d8867dd9..126f739d9a68a5a5c5345e25f714c3aaaff57442 100644 GIT binary patch delta 2085 zcmV+=2-^464Y3fABYy!nP)t-sM{rEYX$8%87Sewp%7iG$Z4StA5yz5CxOqUudnV_P z9rTU~$!-nss3OH_2X;AOfCl7{4FA?M z)^-Emi3y`=49;x>f=30CRtPaNH!dn0?$9+#JRItR0b)=dw10pcjc+3Dz%$UJC}uAK zx}Y$0I|I?NFT0W}-mxsAjV*OxC;#+2(a+3NQ%d8&FRibz)R7?1nn>BdF>h;6p`4PI zg|X!?29!xeK~#8Nw2^0S<1i3L1IcSiBn%Tn)-zpA0^h#J;*sD*w`WlXB zJeDzBLsm%G85pPx<}A#^3P}E_hzt!LZPaU$prHzpZb*m=fieh^q*M*{28wTydXfn+ z2f}rD5v(W36sK|=LQ08-wc$|IpZtb}4*2vq#yD!8N(t;1zch>8Qa2cIv)mUYDyB_D zhJWMuTb6H?mThn1Mihk$3nr+TrV_@y8auY*H!wCY0Rka>St0pDrInC2QK-Rni~s*W z=$RRVlQx^CCl0c>GY{w7J6J47tGl}!rn|e<=KIrMXFYx2tX~z!1MRoy%}~DFetY&- zD-=aR5JgeNKW=XBHgNOw^!uM{kVPheNq--Y8{cm8ubTOd*J)iftdTc>MwX$90x`2% z-GMCXos&?N{CqL_v43KaPW-E%p0mFp2Rd)nGDl+`gg(fW&*-HbD@jyeGVxPKDw238*&_G=n z1`KNn;{ZiSe%akLVtv&V4zBE z3}prDgPCZM881m3Nmk@RKncmg7xgea)>}ZN?F0fz>N=Xi7{O37wE!PK2*{8PaXHaU zX&9hPWsw{NQMn+xq#3*^=r$Pp!+swJ(2$rQCuND70NSHOYa6C)L$=s0~jc(_Bz{|O2i`v-n7I{?MK%yXywRleed;G;iofXJ|*S+Kv(j2*R zinyvayA9X~ce})~3|)l`YlyE?rg-m-X+a-*NwN!{X^!gUu~qCeTYq(GBT1sjwr946 zJ^SbtB7z|e1v`qOWXDW&JH_n5*JCy)1B#dkBz=i+5s@kg)I_V<%N~4%YNrbuDZ`f+ zfV`)~RP2;MO=LO9SYhMLu-(3SdXK za$mNohtvd_N2VgPk$*Bg7Z7v7)9xl{z=>Z-GQfUxCSV*Lb~G~^Zy1j3f@0m@-!Ghd zBJ6iv#g9%Y0Wne&nYbRJ5C-}Yo+4k8W%uE6I-Neur_;yBwJXb}jT4m;5TnOBk*RPE z8z}>jByuEq{s%OFB(H1PL&>D@_ESJgsGt!aFkpm0Ao5JWRm05%@FAhZ7|aMDz+|dX04&fH1uXu7O8FdR5C|xl z>QIAPz%00{AAb=_r10gM86gyKQZ=w20BWI%X)?kO!*DqYp_GeSbUy$&4k11ul;~A1 zQV1yEFyXFA0mbr99}%)VWv<%mb$}tlW~kHY^{QOC^a%j_kWwLEtmb;)P~j$5E#?a) zTK$~Jxq@1_<;w*||D>|Tr7Nlu#b$v23m*D!_g9~Z^`ZU-nLK_+Q|ovi P00000NkvXXu0mjf(MsCA delta 1734 zcmV;%208h$5Y-KkBYyzxP)t-sM{rE@k_E_V1;%U*#(O2tdK&A40>_a{x_Lm$gd^C2 z8Od%9$#4+tj1TIO9QKzD#c2r3aS+OF3gv?k@S`O0p%EAu84L~-EG;Y|A|mRV58HtT zH8wQXcLUyv3je+@h)V>|Z3BXZf<{P1T3lMHdmD8;18r|?+JB`e@3$(NWe{dC0$4*4 zw79dLp`AP}5yG1$@W(*^wg>;71poJn|LAf5{I~VtT>tu~|M_eG{mB3Ke73Vr|Fj(c z`I!B#7XQ^U|Iav!heiMX*#FEA|Nrd&$20!8CHJTlh*XCoY%FG*;g!SB`(0xmjG+vB4qkmfq$&m!0}c!rXx(FG;09rPf5zk z3wpCZ{=?oVOOkb6l^<3RNCLa+_Ku@lfrce0vYStsXIx=J0$x+P&Pf33>c%S?H zNQg5u_J5AI{zsM|85q_?PfSzX&n;k5%{!zu!bveK38IJ()6Cu2l4JI^g+Lg!>XnBs z&!9txrhNhwhqU|;00fxQ3Y%v!b^Q=xA4W)`$0 zwf*J)ZLYd?9mjF&INtczPtE-O@6TxD>2WdndVeV9)B6R4>qV;SbzWZ@ z3PjMVx1wR&{toSmM0jzYnCZmaB~N7}KYv)+wk-Wdy%{|c1*S5d#|3)kDS;!Ft4IcY z_;%yTl0th(!j4^bE*>Q&;te9c-EiKx8RIR2EAmxI!e~pv08!WztkBPr6J0O8-S#BL zIwYLkq_jcwJA&x+1z}%Y@8fYJxo0T%hHPC=8ys;wXI=UQi098l<&aPY1zChFgMT(< z3M?Wh?au`6VO(9&3m6XoK<)&C0f6d6IO4L12jW=R<<7-Y6%WGobQ7=iLIZK-2v1Zj zAfdJs=J8P2)y}Q=6VunHlQeEH@U4*pptlp>J_@3*h+)7#9rCm&uRB-8xg-?SPgZT+ zkL=h*emE9>8GIaSF9cB>^E^+FNq=>{Y`2$doMfj@N%w0EV5BOGBF%FY;ZFh!0AtR% zzbIoW0&1$)>txeBP5B(oIk1l)G!@Zm1|>V;(rJdAMNWLF$m??^0!#JLY$>8Mke$$w z1Q4a%g@5LHRRsGObQRGah5^q+wvr|56o6I~L>5Dt5L6!qfO<3T%1Ab|B!AO}&UCWe zkjP~bWiU5uqKi&YhBD6aW*Mgs2&&s`_Gcxah)IY(>R6#HLm1f`=FZ||s);O1ll5}5 ziIpIW2!~q0nP4~WjpcH)oW)g=GD%XcXPeD(c`u*{o`=pbWGl+Zv$uFQgMw8vgjc*k z7r7F69HIJZ>N41hFo0y(`+u2S&4|l5rEs7i+E7L4SaYT0k3f zO8`2ZXVnS}AP4LSlzq%p`{b<#ln~U%p<|*I8Ui^Gp`wzB7E}pRXqrDB(wo-?5LpTw z5t6Jx3-jIsz_0lyg9sQEkOZ_~bRGeGM-5?UMCT5WLZ2J)7-gUkB7anrgHMI6q zy6h#81`!_{I3Dgs|D`d?mC=o6oWksnF5uQ2|OA;4~?G zjdZQ1K!ifa#|NT-riCUTd>#5N0|*r`eBmwE129@YwD7x9TGn6=1O$sQ>@~07*qoM6N<$g0m|^<^TWy diff --git a/TMessagesProj/src/main/assets/emoji/0_290.png b/TMessagesProj/src/main/assets/emoji/0_290.png index e5f47685b06a1db87ff1bd77ee8fb8802ce34b07..40e111be4989a5bf2a0f0ffad124e5b9c682edb1 100644 GIT binary patch delta 704 zcmV;x0zdtb3fKjZB!5UyOjJcja7@yK3E`Lv>ZTLdiVWC{47g$s(t!xecMI2v3EqiZAPfay+kXLLNFx66`@d-=LAq&n zT0^{@_F|83a`nv-*pTUuQEECDCGU563Q;C_AC@!5oFVSs$`gdNuOi3sqK5oTf?1AmEfOl0eVtpw)D@IXX9Cgy~M zvw@6;RHv25Wj({O|| m%cW*9QcQ0~35uHjZhip3DN{M5Bo@p70000# delta 1276 zcmV>QQdP{9YZMI$hE+CDEgHgzUwKY9 z)S`RZt%ajvJJO(dAR8Fnw2jZ2aX2d?p=3Ukl8(@va~%)~GaV2a5)Ky*3M3g5EiEm7 zeSMu?IEIFWk&uwbicZoO9Kqd)%>#mRK{z zhg`C6M!9!QpkFv-WoQ8a0OP`(>BgUXb#G8C6@F4OJU&4Y%)es*001F$QchC2m5g5QS~9 zkuiiNgd}9U<9|ioSC)|Xf3i91RxnjVlDYWS{Fvjy<+9bE&S}X782_CdSM(+PI&2>L zAztq0+wFZHBktYD7P{{fqunY!itA&%jTB+@&?Cn4wqK6hUltKI{bRUS6NY~xM$gp{ zF9#ybZ+pjhx<1C+pNg^R5#w#%JH|(^^%REl(sB&vihuI)+MG_OtHb=-x63vc!G6E@ z4%co=dlv6^P<*hii!n9ZQJAVC&>&xO@Gu)(ORSTB8fY|c^YPruvKs}HDX2x zKhMfAJhty)8e9NyyO{wBPJs9eZi|@i2;rqNEZTwr-!fPr__5t>EFh4hIM&f+fR3UO z(I;WQX2gOJd6tAliFNoM(b*t`Ne#6<>bJ^K#=CD3oFwlMyD1}lLPSZOpszo;fKEwp z9e*qcv8F;lOS0f%8Pu5ofj5|L1~17npjJfwKT2a9op_h?K0h%SVFt7-&f37EN%6V- z&V*(#Ld<~h^Dac^*TacHIJAh6Wl=^9f5Hg#vh#p?ZWzSF@>4bHHQ|%t(~5|xHlYD} zP?{!Cnh~TE*my<m-IMN9v;}yaOf!1>%cu9;_!@L$=Rqr+!{S}JL>r-7OmKh mo{U}+8-(a5=iV{?5BeLdl}e-8GZ)bS0000b#fVs)W;*aKe05 z*q(Up!=UcOq2#lU_0X>U;l%pdy4jw0&y8mO=F3Ad;_Cna01b3fPE!E(u+fS+WB&aZ zz17X6icD4j00IX|L_t(|UhUW0j@%#&fZ>F2oE_Uh=KY_wHh(c{yN3=eTWv4ui;?E$ z({CaaW&7i#w5?6D_q$y}k|~czIaUmZOl0s2goVrmneQfw5XTn~X?c^!l5LBc_2FBBGLm6U#3fj>lb~iwzTdf!Z zsG`OdQBOXKA>)(~EzyWZ#B=wfpCNlkv_gm$u@AoqTnoX_h+KMv>@hyRg@783Konxq z(2Pr9B7gEClSIES@&lm}Zi3Jw6{87_sJovaZc0EG8gbfjAt@0+<`Qu3k)*v5_$v{S zi8M^OPBbHkz{b=g@tt6U6(wrbMW!nPPm72~BPK4JR`f+?Kj6KIO@L-FVB9u6&YI&M mWbTKt3d~P(GHLs}^8>BhNRkG=>DmAQ002ovP6b4+LSTY^%`k!h delta 1261 zcmVL@NKi2*OED!A4hoTJR)=3q zE*=y~E*woUAD?PbvVLAjEgX`Pl7)hOoorD?D;f+639)@!4F?4a2L!>8X{&QsyN6`3 zcw2NzG+8($#g%Ngf?=R(QN4_2Jth@PFCC_CRc1mhw0&NfWPeJJUPgaXJcw9AYHMu) z001N;B+Q*{J3KvIJH`wE000?uQchCC^V8*K z4c~jn;`lAT+^XT96A?q+E-TgueyZT9nDTbK@YPl9!hfFu9%4tx+#+(*>^I?00B-}r zEg~|h)bckW!3YpSyd77pQOUa2QtG|u|Hc*vK$a;{JB>mofY7p(a=-TfVFU#LCa5Gy zoJL;aFG!JPDNFBfbi#8y0cxpRr_p2zW>N#B+;6@;!=9K3GHn{CVKN~^_7RePXA^2M z0Cd^*4S#Dyg%XTl2r^QHd^L$*3ntVuZM*gY8c2|03_*B~G+lpjiZ_Ws0*uh~o#{{` z%BwmCFlS`oASvv`yB@_;f@f%YV=ZVzdC_w{6Jj1D83!rT{d(j3VHkWuBsy)YyZ{XV zfZFE}gO|#XQc5^HhgfH5o5-dsthwa2QP=e`FMotxWXX|Q*AKjw;7Ndp0)#25m2I=X z)C1(2A*IxHog{pc!zbEiUAC32OnC)h3t&tt5JCVU-Z0_;5lW|>wO##{0w)uI7*zj1h5WM2(1~?5ocNE}LH2geV7*?12y)MToRbvk5@OS3!b9 zK!0eRiV*y@P`a$e)Si1%@M`4)GG1>3!yz)LsI?jaT%B;#l-D4j`b;23T$|06`bNQvJ1AMHP1FOjY3Y1snt^FqOfU80>Dq(pp#(L)>k2v44VF zc45r809Zu@u>~c!6*i@Ed$U6fxNk2n9`I+TAcj zM2N)+KZzZvn;{4{%|E8#Ahu(VVEgJGh!&`58DT6<+Eru40LbqT+wJynxQDnQ!q><> z*9C_PvOE#ua3F}Kv8QYo%PPIGC3psjc?m({|Bycc XpOplBF!j)+00000NkvXXu0mjfYWz25 diff --git a/TMessagesProj/src/main/assets/emoji/0_292.png b/TMessagesProj/src/main/assets/emoji/0_292.png index db732c97a18ee59614b7af35e380dcf221ba85c6..5d4cef47b1d3d567720e42b9e00a2601dad22226 100644 GIT binary patch delta 595 zcmV-Z0<8Ve2r(VTO`hFrsjU9M_DzkO4{fmg$ZT(4|H z-nNh1u7=g4dg8s9(3x+_j%4J*p3C!q5&!@I3v^OWQvkNp={b-0{upMw4iI!K0005n zNkl;{QsZ5bgJa&!xiF8W-^&=e1CLhw;0_21MXP>y~jrg zcuE`jCq~G$ZAtI}5k(1(&k6q{hzWic@khKqfd~iiN95l?q)#I7y9hu;zBfgH0q?pK4Rz0{0n9-UTV1I&?CH7nvl@KwbAtvY?=@0x;`V$OHsrOBdo*>t~22%!j}@O>krO~ z$UccJ(^fHJC}Bn;Y>?p^YH$^d2m?ekLRe#hok)My4j(0=W$B6OAyVl^7Z%oQb>>9^8PjR-$A%84=u2&|h}pgBwmjKfNrI h#|DfBf(G2z<{uu;KQwr|8r1**002ovPDHLkV1nd446pzI delta 1083 zcmV-B1jPI71kebOB!7NTOjJcja7;HK6*3$UCKwV?FCQ8f6oXGNLL?SLCmL2aCwEUc zhEXw7R$7gXje<@sMkW`NUphu67Y+*vm0vl6f`Wg3evVi*lU+E2PcK|EA5kqENGBMI zR5L##7M*53m|;7hX+UK;B7I6NZa^k?MJWRU0c>t^Jv}~uZ+~2`gizX}GKl~H02Xvo zPE!E2i)SwQo(~>Pc;Wr{z~ITx&FRalyoKN&000APNklKI~fjJVjM`Z-w=cUp1bWa zl0O(jh8W)s5oKFqWO;f9?%$3f)At_u`~KY+^4#@o@N1db^R<&qL&ux zan?RY#o-o-0*NW*XPxAoH)v(%$#9HArBJYT0A-#$Q&0=jU?@goskH@icuA42TS;5r z!#G)IF@HwmW)iF=!J+D+%w>`!Vo`7tvuzy200BgM=3q&!h}0`eKT0!IZoD_vfbxkV ztcXH|*7}{tBF?N(<4{dUH}=nAheyNewvrdCU`0JTI}LUJLP7HghCb)Dcqawq07V$W zizo;wQn74St43R);kAMt+{Kv`vLi)3yQ%G8Du0$X9uzqhc4jvHmkhidzK!>c*Mde- z>vh2=bO0HG!z*~P+EsN&tOfp+4Gva_a%G@$jo|WhD>#NB2V^ROqFoGBAGSC|W;BUW zfKZmM5MI&gMc^MA#~Bz6NdmqF5Bf_|z;bHJu?X;`x5&T}73%3r4}@71t*X250$}}M zU4K7c>O8I_ChB*yQ_zTev?f8LW zItB2KW}yn8gL8;oxDf5Jjxu;hP%Ij>yFFyH-+EL{x(W{VU;=_s;($oa+|+1_;|CyTGulTlamU4H6Lm z(#e68e_?T*M}I-*ODHX?YF69=LcAD&kk)1*A-ypOiH%VLgB~LYF|8wn^k}_RGI74I z(ew^;{$T?W(fbxgH%wvd5&qBunNasb#1M~&MDK}Y{QZABK)MKeSE7MXOn`~V#_KFB zAOw3$_!s~~Kr!fdfe;|trWObZn2@~A5v{u4MNDj<O!y~5utCN>WN615W&i`-ru5@V8nKP>gfHI;H)h4 zL@l-uWspTr-O)aO>t$ivR$qYrIL&cx`oH-B^b_ex1lfp=jQ{`u07*qoM6N<$f(kn+ AH2?qr delta 966 zcmV;%13CP%1>6UaB!68{OjJcja7-N(5Eu{)OgAhoAR9L)Av7r^A{G-S8y7MtB}g?b zj*gB_J2W5`5ex_hetLCEHZWB|H%2ooPdhU(A{!_i6gVm)K`tg-M>`-D4{l2(0s#S2 zR$Fm#a(`+~O4xiy0000GbW%=J0JhD-f1W@RC0yq8+~MoK3V-mEl>h((9!W$&RCr$1 z*4c97I1B|)EnF2l&7Inu|NqP(0imRdI&sIEnyJ3YL!2@WalNYf@1lgfD9E=*r>_ye z-r};bD}s14O9{VHV_j;xD>Wt{^vi;NOUtz$ifYK$Ydn^JsRsKWYsjs}ySPvzT&y9s z8twHO>OzfpxqpVi8n2ePRzqpt_x-QO%kM71hq2`2@#?!v^masH1>r7#T7i!v30Na? z^&^1Y5ZG%>ArDOb3?RX7f-}baAtDcer3YdO#(Q58E}jayM}TSs5TduX5H-Hn-><+A zfGtaStYIt!75Ci(tNH`r&HS;V;K&5TnSsf#2)+Z>JAX58H3G4g5cgFZ4 zm>i~g4S!VOn>`5d)@mTsMwA}O2Lr&9HAomohQvTULQ3|Da5Tz|kpm$t5;;T^o;C4A zl)+x^uPkd42tOdIaRY)O;gTDl3Pd>f8^Rm^M}j2*4SZHP_}-pcQ%3rwB^(5dp%#%n z2U4f*crMUD|<+8xXhS5`Way<(yMWIRkvVt= zq?AU*6r1!-F}??4D1@^F)cFwNgo&XV&R}S}@{+h0HDAc z42a&&qs22a0Wltogxv|)I~GK5-{tcl6V7Q+m(cFV@)NrTsMYMF?vTUYCI(Cqv!Vk000VfQchC<{TGrlx7k&2(ub_UW&i*I+et)0RCwC$ z)$5MqAPfayZVtp4c>lLua6F|^X1Au%s?ul+-KgLj`#l_IQw=O|DTHsYsUH1UBS!r<{25AVWrP_);-=9cLFH6)y zrB%A_1bGyty(D5MNC>=6LPMlMlp-xenI+UMXb^(rv1Wzm0n zSU5KkVRwo{WrG=kzFrR|K=H+DVjwT6AVMd+;(qU~mVY8e9yLZ-u$q@WwZkZnt;}t7 zA}9z4-Kb*F!=R(YZZrwIWuxa1=7Cz9j4ICCj&PG{NC{_@iM!?9%o;KYF#04eA~hzl zn^l8rPzSyU>lTPOYmi*4TCEKW#26{pI8vBsHZ2e!M0pmP^?JeWOt8@x6N^U@Cc$BW zFNU75az?#Q!qPnBATGxGMy5~?p@B0C1~73(JPZ0nXlDSTSx!iP+qN$BU!Q_`GcJrc b^MCUP6@E3kO>&aE00000NkvXXu0mjfqN@N7 delta 1502 zcmV<41tI$81n>)xB!A>kOjJcja7@Q~4rnzQ20wy0ce}rE3?N^lRg>31e!?(sw6bXn z%XtdYhY1EHX2W?30UK4&gbFBUs~#3H(ufNIC287^2+w~B+mQ(iM~je53l82N$X(g~;4VFv|uwM;FhkwgjnA_!@4Eeq*>ZB0# zwITe)HT%Lb@vt1=mI~XB3I51B?Wz|4%s~IuTK2gn|ItdaV+_=T3Kv(K|I|}XjnNNI zlK<9Vm`o01qv&v!xL%#%d_fkXt(>u%TZMXHIw&$zbClq=M8&*;CY6>*0000gbW%=J z0R9gB{r>&@{(t^FA-MfnL81O5Y+>!#-S3%ky5fqZy2yp(-ucb8=>GoRwfpM;00faq zL_t(|UZvHEQrk!n24Kk-wy_P^0dpsTkcGJ~oj$oq_Wj>yduFsUp|UAUJFZd{l;*4c zdsosFU61$tmt5_V?YsSPAP)bbYq~3uL9IsL$ z9Pzalu}|1)6*(e7wT`4QAQ}i{(*Hw51+l_tP-`rXfQYpuKyWl@)FGxDf}x{2L?4mV z5(o&5rhmJ&2xAF_B1_a7&ygdTBO;{wHHfcB%q=0K7^Xvx>P!}*mdGuUnp)#IMHmR4 zD@zDjW46Xq#Nk=zVeW|cCXgCc8E<6#Ms3#ZBy|`? z@_(etcq8FEz|1-;A|(Xg8C7yn<_WUSXf$_6Vye7@2gD@W645&X8?^nGwJ(jpejj&) z%ftnNugUgBP!2>q_XHFaLngX?852ZA;)qmZw9bT1AxX*-LAE^C{vi<*LpMu;xr#Iv zhHUk1ZP*wI*Qw3H61mO{kJ7m%sDLPg#(x$9#K4Y7HK%Hw5v)CtP(h#_e>57OPOU&O zXRr&3z$Ra3C}B{BCkz9_P5+J0&8vbIqG@4(2i!}B=H=Eyx z5i|iovnYa27!G2zD_nh-^Qtb0iWlG3JHwI)9rv zdaFMo@LGXSycIM@In?A$#*{Ir7RlmHO6zmH+!Z^B$D zWD-aS#>0*^To{K0Hi8!xAlyCPKZ6iyERf2xlYa5ooIn_pa7#Qt-j#++6FA_VaDV?C zXmqcKu+28l~8^adT30w)#2A2W^XK?$H3!nBj#A&7^p%?@ptbcJ^8i5Pp z1y8_w_$lmhzP%^jLfegJ5Iz_OK`Hnm{4I;uFwCCL#~WgN{?ra%9^e-EIl>w(YXpVh zViW{KZFQQ%;VA%{B*WpdcWc9bGy*S_F?_SS2g~O0?ANF8Y}o9yT*IvJxKp&W1%wwo z4?i!=nnNFBv-XC~z~0OigbT`+<&h9!Kfdz~`I z$0)O2VHCt|K|qZ1-ypO;#weqlH;+3ldpqQ|7a+j+2h43q>=8|{I{*Lx07*qoM6N<$ Ef-@$u4*&oF diff --git a/TMessagesProj/src/main/assets/emoji/0_295.png b/TMessagesProj/src/main/assets/emoji/0_295.png index b8d58cae2ce75c1a3d848edf10dca030ab535e6f..aa72d19072cbe0e256ae809aac6abbd2bc575aeb 100644 GIT binary patch delta 539 zcmV+$0_6RH3$z4~B!47OOjJcja7;5J95yB&IVmDmK{s4SJ2fRAK`$swH!w9NA2}%^ zEgu+URULf*000bhQchC<7-qHq|2hBvjnn)=G`Bkd00FZ}L_t(|+TGRLZrd;nfMN4s zkrLnkeJ7g^8?@d=nHW}-xyapzKccN{e;(Ls14x8W5{UPmsefWLnZ&MGAiADJFB44l ziaNmq$`v(Y{}vVevnpDd&@#bwLghOU{J$%tULjtA<%)*{AR=H80LuanWgT=qT0}Gm z;lb_ChY;UPO9mA>7bjt2jQ|3PfZS2oD+Xcq5U~5)DXp5cj8% zd2fM4?DrL!mw%2##pJevIYl&4)q}We$W@>yvk1?*6IfD&vifoI%|66(1S@|vn3F^k zQNHFV{}eHa_V*|A{3Q;&m#_;WkXY(8-b40N;a9{++<78bM;LE{SkJs;o)L;?@Qc9A z)oVwGE0J*kr(i8X0GV8f2I32y#7JHjc7?=Z;v_74@qhKx2qaFz%pm_)c)UH z(Jo>N5`fssdE#4z1R*Owq`44?146JZ7-S(tMRy@RNYUT|wQYGC(ilVMj6vwYgMl^& dVEec83lwzU9)1@UVNU=6002ovPDHLkV1j`R)N=Bx9%9o_O7+fmty#MTE#ceZe+$y32}V z&XH`*m3G{wf#b4{)}49at%(C8XWXZO!+~7~7fA;yY22rR032TqN{!i|d%k&812lF4 z5=ZmTtp^iKvVv$$FfRr`gB)6(``*3y*R}fFx%17d>A95k(toh+!k^`{j_}B(>%N-d ztcUyH!O)X!QjygXQkG<-=q+rpUY_Dum)lH>&->xRz8L^)Ca=Ejn6 zWx|_*U3#AZwIUS&001L&QchC<{q+6*{tEv7{{B1|tl(LW{lO(L!fsLW+n}m#<>K;n zdj6H2=2!p#1b<3NL_t(|UZvLAcH%e?24EO$_OOQ}BqTj(Uu?5)+4}vTYDy&m&B>YW z*sTk$(0Bg7BpXVQsx3!tylTDYHvc(-{^bx_?%>-F%nsj4n2ev2uiR1lQwY z2coDW3=+K}LiNTG#5zKXq67m%C?pD`M@XH2p6!mdZU{0%f@+=nevUrjs(3)d|CK5!& zx|g>{A}E2qJP=&RgPg;RwP7g~IT2FC(JnJ1`9qI|>XB|`p6q|7AIIFC>r zXiLuo2sn&f^K3t8#nLN6iX_(^A3kW~cU}ma=1ruNNHNh*=! zVI3$F_Bn!+Fi-LQpT!o0pne~-7lJF%8Gb)RAPBt>j4S)y7-ONhWMmhJ>_kYTgzkQ; zMt?^cNyC9qvCj+(^W?^Ut4e!dAw=lGq`nZ88wC@s{`tQR3M>#D2pc>q(dbowhg9!= z+$gMp1Yy*~`=*cpBH@jf+o$UP0=I7w2pED9jBcZSQyWSMc#h!4f>930SD;*ev1fr0 zcLoB8L_rJ!1a(y)$LC^EzPjg>-7O+P$QB!o3#9Sw_KTUw1@S^8TFGfE6p&%Sy(QY2M{ns_RFhs5^KvT7>DJ0 zy_tjI2U2lF#gzyxKyU`6g%Hul=zl`|XhIAy4$CDP+h71v!V+FM5zC`70*>?T?m|4h zMTt=Sutws_C|wJFZRW3^S@Yw$eIZ8AAKB;Y5rVFfK%!h2Rlr!GfkcQ=ua~X`yfuv(gm^^YOO;g(48P`R wAW{40YSkK*d#v$=7(JKoD~;Or{8dl<2lu@gqp3YMtpET307*qoM6N<$g8yTcD*ylh diff --git a/TMessagesProj/src/main/assets/emoji/0_296.png b/TMessagesProj/src/main/assets/emoji/0_296.png index 277e81641d9e5db7f3c656cc19f8e9a66f08cae9..cb53bbbddc27af456eb7535b5faeb85cfb54e51e 100644 GIT binary patch delta 1522 zcmV{X1hzd?rTrC#|3J3;$Jq&?D3zU+K_`x+`MmO-ZDT<1TWJWTAKn&lQ6zZoM_r5d< z1q0@x6)i3<=A<2hf`R6v9r3g%-If#Ws~vrPeV0uQ-r`Tsv?s$RVgOpazoI%m$A>j4$JzPh(w zvH0P?Q)jF-Bxs+X4|>fIf1Ix7-D9NzVSM^D2OT$vaeuy^qYjk)W1M%9&>c32@oC;H zN9X*gVGQN-bJG|XzahpG#n2k8<@`6r=rxJa{4@mNV`u*u=c|S>#&wK+L%?aQ_m6RS zd4GL<{pa)EF$TA1w(CBAf8KX3`&Z13qQ}SR`G{g@?{#o*yHF20U3UdS9UZ=F2DfKe zkNUo*7=Oz}*}gk`KOlk_be^kp78+su@?SxeI|+zf*M&h)3?5pR5r#(lX7JBbymrZf z>)57K$H)u@2w;T9B0ywJNj`~{)55IHup!r2SOSS2>f zGzG--U?y)Gxp$-m+hk!}R%=>IZo^m{2OvyBynlx`(hLlz&R}>&vXL>CKtP0qAYQc-Bq?> z?thkm40p=_2vT5aXOqdjL|oZ~i1WaQ7=8i2|D8}X(gSj9f9x)uDIKgm3I!0M%h7eZwHq zhDRWW&5<9Y5ZUV}dU)wzw2oNHeNk?)g*23^CmjJR{JV)(anI<7Z+;bU4 zAQadv7^Y#;AZeS)GDDfnB(eI%0|+2u5CS&KVU`_{1xjqu)C_DSMfH*p*NpZdZGV<) zlLrFGEuL*#fkbsph(W~IBADfD0d!GWB%q?4p%*Gf2||eiiWgd61fp#_hGG8zK>M=D z^F>bJp~4iALV%jKzC>m zY#6un6fw8bSmeS8JyQn{@M`JDSf6r#nfZDEHywoYC zI_FgikfJT$0Pm5~4u8+G?GETA;5ZGST_em7nXh7MdNNR4J&{ zLZ_*Ywn+h!PA6q#d%gl-RLJaHj;7P;1>9ptY&{(f z!T2jW?xKewIU0>Rh#E~Vb}xa3*!nGL2RH|y@2?@4IBxdebZ`E#*93q$AVfn1h4|m= YFNJiPN#MMHg8%>k07*qoM6N<$f_rti761SM delta 1291 zcmV+m1@!ua44w**B!96`OjJcja7-Uvp~s722S0&DgvdXA!6|60OpMS}lhy(wXEAWJ zVK+3aY(=(xSjv)VICs1ZN{$6CZo`UV%ad!xjAY%ii@=3lS(x0ibWH^pNzIvX03Kn_ znQ#FfT+Nnki)2v*5lpvtPOx!GB^oS_QZU`KjN-kQ)}wmiyML6}sDR(Mk`3;rCc{`t5^%V*^N{V_0yPV;Ew{NlKrbd!&~Qpf-R1NTWpK~#8N zrPc?J;ye%r;C~c)37rKNw%xgwB$RFU|9{vwW5)?A^qok~ND)HGqj_hHA^7_mkNvgj zTCP^RV7ObY=1qkSd4K22-TV9ds%ag&lykaR!Idu?5(`cwQA~0|l4inqMbbQ1EYDN% zG;Bo71>Y7lJt=X+$gp z%rs@9IWcyGLV~l!unF-b@+)H8fY`8#pzNs$F)s*)5ZgB)mUb4jAk4fuVUWm0qwSe6 zVhM$WZnQlYOkNX7lbJFO1dj|7L^U`umU~8#SX)A>{k(n=N~HMgI!aMeDjC+EhtW9_ zM@vvYZ5FifSUR8Lu@rmQH^J$+a!^Ey8y*)g?jdom>gio*1pA!w6GvwayAcJ%4d52r1NJSSJTb9U(lCb6qD%BD8b_ z1%i}>O78!TX~J&^N(8%itV1k<<~M}Yj3syffRK`4C6P)kn7XSQo4p{i$dPg+{Cfh% z)A+9c1Xx5tNHscY>Is5ThIceVfZ&Lf5+DRm9U-9%H2#JRAAf`M@WG2G%rsP$-M7?EiT0;ODHOP|9myFs?IDF9*T4=V+{Uo&$=LKAKUXRtpV zG_olm6%c0#4BG7v;#vs==2l2V3gRJM7=It_$)H4h1qg(LNxRkkBCZdZLNjHe1bbQ;mdC%V>q-wb?AR)1AiO#?2N8A0xMj{z@Y8UH15xSo&&Rf98R23mSK$m zgsKR5IU$StFTR;RN3CaqPB!9F}OjJcja7;%rDNj*VAsQFgo_gxOo49gKn^`<*Gancb4dJed zkB*Gin|ABJoVadBBoq!;KQ^&uLiEzFFcu8vx0AMQM&YiC%g9+ zST=-%g7Cgpz=eLry zX+q43Vce#G#(`P$&8v`II{xLvtYJK4WN3VMar@xGTQC^`006;=W;QoDx+<=>0000W zbW%=J0BQa2D4^R9BK}kO{N%sGMug{(%Bzfa$@)aNTgUXIV7dIC000CfNkl2fMJ5QQ-?h=0Lhv)K&Tk!IgFRy*(iUg}zgr%%oDOoF6XNp#F4Dw}uj}e^331 zXi9iKcJ7)Xe!n+gUmu$oncV;J3VLi1O=CPCo5r~N z55y49M_R~H2=VJ65#Nc^0h|zGK0=^^;w|~dzE{)Y{)jQrCV_-bU-ENm0 zZ;dh7xVzKow6l&p&$IY$1jF4S;Uw=593x$HzXy20dNh$AI7SsELx6k(fCP@ggmV;H zWjS2_Er?hkfF-?Sn`69Lc3C3CSpT|D}dSuKoEoH&3@pvh!sr(a$t-q z))B7TcxPBduw5Q?8YYH3Ar;&seEl*si^vLJ}^komAN)cXZM_TWY-mBDgy&hoY^+u!~Xv!w~9aG=yL@xld+fjhUy&giMf;x+0(rCKw3jrI8K1k>s9U|bp zZr#g*o)A;85v*I=>3lxguBUU_5cZx=x7Y8FW3#^L_oq`_1ZCTgOX?l3N-&^_G0<<< tgnz^~(Or{Ux*q9x(rTvuW54x((4XtzQkr?&!BGGJ002ovPDHLkV1n9Mf)D@z delta 1219 zcmV;!1U&o73fBpcB!8b!OjJcja7>S0M-NVuZAU&-lh#Ow%O+*1S(w`zS)Dq0y#_ym zVnRNfW=@o1N(UumplVT_XioqfU#DrrPHF;q^Diabr1rkdG zJAZ3jUT#M+V?QjdbXmHGWVnK1!H{XDZdI~+T(o^(ooGv2%e0f2D#4vBPO>LHo42X*W001C#QchC<{{0jE{{8;`{ro7iNc`xR zQFc1pY0PlKnd-W!`MKJRx-jAZ00YNKL_t(|UZvF6a^pA<1yBZMQo)iOH+n6n|n)DI|zwqJo%6I$KjBED<7& zc%N!h2^%u^L{0>k^Mp}Iu;0Yq5!3FUEC5`~ znw)-stjmtX5~Pj@3#Rk7)>867P#wg9;L<#GBc?`b8xstSsk)8ANRCTI zAcR#W?|(Lo1@(vtE%Rk3;z_EA2*X%(`(pV~!~~eSE? z{WN33YREegpgdvqv9aN|ZeOk%G!X)cfN_9Lm*WlG|L=%k3Oda5Q7TUet6D-h!rb4a zR+`!UEujJGySG$o&crQYxq^9he+X``1Q)^+T7SXf?j7aK6V`$w!dRGAckXL7SDFY~ z76>#L##mSPykRKBgbs-q=XXuCtd&9m3E}$7W21t{CxA*ihdb8*qg1 z1Q{Q1&*lFDFSA_HAlxOKV7YRHm#d9Dk=>9}NsbNH%fnF@hI{+cQlcUrPk?UzO{L zIV5OL*mG~Ua|Q*$D?@=IkTBdHP9X%&VY3Ru+T;caEO^=udp$Bjkc=Wk!r^cdbf&=M z(Wi1_q~d6t4hLuKT4R93z?YyFD4>C7O6JGam3VF>D2{?7(CD|uAj1+NLrWaacz>o$ z^ZF1GuQ^WRv_;~lk&)1k1bk+9F?n-*jgD~jdd$t`yghhh7#Ud*s74@M%<*V4n>`cI z#+c2DuRfN=D~yAT%(sX_V93uwF`2#nd<)-ZlhN3P4aC*RA^}rwN%(TY>&+K#HJcQJ z&+z1s2&yv9+8UH%8w9KoW*Jur20S9eYm6)iAzu)p8aGwGyfF*}8btKkztXuI58@iP hRmS)@E^s$b{0sb6?US~Q=t=+p002ovPDHLkV1nuAGlKvC diff --git a/TMessagesProj/src/main/assets/emoji/0_298.png b/TMessagesProj/src/main/assets/emoji/0_298.png index b936bf458d035659ad8a2e5e1e0d80f24bb44264..7c1cdab5ef60ba1214d5b4a78665fb997e939da5 100644 GIT binary patch delta 1276 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 KMNUMnLSTY1xb2Vt diff --git a/TMessagesProj/src/main/assets/emoji/0_299.png b/TMessagesProj/src/main/assets/emoji/0_299.png index 9bb5c81669aa346ef2f7f4876cbb23a05805fb2e..1e71c592dac147d127e2b2c11556dc7930e46d2c 100644 GIT binary patch delta 1261 zcmVL@NKi2*OED!A4hoTJR)=3q zE*=y~E*woUAD?PbvVLAjEgX`Pl7)hOoorD?D;f+639)@!4F?4a2L!8gSi6U0uy|W^ zN;FwGCA58Bw}N4yX;HzDX}yeQOD`Q}LM^6lRhVQ-k6uQ9Qhz*%SVF~>Y&|9wYHMxG zooyr}Bmn>bJ3Kun2(zOA000?uQchC*Y=bq?F37$G(U2r5YFfS zJ7DC@{<{Ren14tRFNfFpG=%r^_Wu53N)i9%;~ny2ipKRF^EyG}5F#O5OwyR<5xgu} z!TX}IZivs?Yd+Q@m&Q^b(GuT%2!vu4S&7|cFuy&jY39|mQwFL{};B{1F}q|k<-X^3@+SV{(=-)ma_EzK_@tOBOsExb{bWtpp)t$sP~;U#Z*o(UZniH9O(vRkcvKM2H#pb|-4TyoF= z0I9i*MR=(UDW!zNbBI-jwy~_5+?wmfR_cDf<9~&)i!3=(>*$%+B91ADC_tFJSlT-K z+dM$-8B$6eMRDvCA~@1Eqp~h+VahuITL5EJfe-=+-I@{4h)_CdtZkyt6gXK5h(U!A zD)nfgz9xjMio8*GgfT4A*BB6IMns5+%eMF{fyc&2HX_PiBzq>rS`i|tlWYXg@LiDL z5PuL_ry>M@ER-&x%vhf$D0sE<0U55hp5YJ~Ohj4@0G^IHYRvfMkwEx^K?tz|&saN& zacQ`Djb(>KFwX=EZFEP7W0tDE0|H{UO)yTG9u&=l$}yrNBhr*hqy*riRaMt*Th~>B zeQ`F@7zu=mLJaK?S*8(@k^#-vZDULUX@6Q^VB>z?(c!4@FM36YU6#o*9tu=dYYLm^ z7f5bROD`=Yjyr%0$duZf5kje|*0BTBO<^w#Ac$!}hJrglJxJ3uEj=&SgjlKQ!;~b6 z02;SHF&cn?Ive1)!2kqZ_)7IxW*HU<7BEGQ?Q=K?l4A;kr^LWG?#NmTYhp++qkqho z@Rgk#Gb{jBQ9x`?x!3|vO5?^oNet7}M?nO!XjOp15~iD?Ny;&;fO X;874I3*4X100000NkvXXu0mjf)a@~+ delta 1027 zcmV+e1pNDf3YiFyB!6#EOjJcja7;HRAS50t2t|k~9v>niI4B`5RFc*bQkFJ#x4-ElxT!Hzy%W ziq2b_-6vE$o35lA_~n87pLhb5VAj^ENg|$CzMkYc8USBvPS-0uVx} zE^>}man3-Ri+_xqq?Cr>>*bh562cMc7M?hSk-ER=g5dxx)q)3T?UmzqAX%x}o zA2Um|#eWhkj>y0#qIRqF2^mFHI|9lmLJXJOT;Wj>k}$wF^VG*!Vzs$ zn~VrezambxXhCwHfV2n>0g8x)2qty#v8G>%F1So7sDDRGD9~-_c4M0^1(l%#3#~NG z;Zo2fI;@NiKyWVwO;QE6Da9@YH$)e@70gdTWd!Ybb_B)tDTEAra+UfUB5cPitiloN zJ0?L#5o{wA1f6Q?+GKJgBy=I`Eo~KCE(;R2&yYDB!FEKz&6-NA!V${7h1Z{crJ2Jc zoTdVfHGh>#F+YVPu+W#A5S9=gA=ImFWM+(wfJH0EVT?9=>E8+y!V=67i~JzaNM9B# zp^&hiKm(vFeoRnSP9TB_sXf9P$G7UAN_84RQV}b`m_h=u8T8PQQiASJ-y`KI&p!lC zgiwHl+z6@z>N-D_#Wz4*Uq=+M2vUTSNN7A`6n~gC)U_t$3t)uz>sBQr0Tx358ko%* z=5wEs%mU5r#+5H%2qJ7aLge$-yzi0h4*@7l)58jU6%3K4S_2|TknxyqO=Ap1>OYwW zpl~=m1#<$RaLmf12G0=BX}Y0-2r7vMOav6>dEzU9g4R0COiaoFmf*K}B7_W+K0&|} z?tk}(yC00u*}lqDgFRaDxX*`!HLwvw5U>fW!B)Zhg4D1c?el)0(b$GbtT3T~1Q|?F zlcoPPy&BK?PR8_MoRc#Sv1PD^LSaWNXs`zgd&3Ykgb_Sqo}Reb7jK2L%cA8I1tQQO zq9KAZ_`>}#-LCyOR=Znp9P`FToxM65Lwu0n6SEQC>wbLOKL_6W{7S}*!Zu2iG&aLw zFXa6t`*a_Ueg1wUg9M6!Mlw(a!U-VZn)h}Lf0Vwjo#Dk85*xz)kkA;R_r~x?A!8pS x83rSeaaiLG&DkHrALY{L=LSFTUc)pD!(YcwsqA-lU*iA(002ovPDHLkV1gbny}|$h diff --git a/TMessagesProj/src/main/assets/emoji/0_3.png b/TMessagesProj/src/main/assets/emoji/0_3.png index f49928553b4ac8d189cf2fbb15256dab2f9f4aaa..71581deccaf94dbbd2591f1ab2ea4e0c2dcc1c60 100644 GIT binary patch delta 1677 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 X4rOZQ6KD>a00000NkvXXu0mjfobw@= diff --git a/TMessagesProj/src/main/assets/emoji/0_30.png b/TMessagesProj/src/main/assets/emoji/0_30.png index 133b23cfd90b9196e9f4965f29857f875743472d..ebde1b6920c4526570aa7d5ad8f3a28c430fe79c 100644 GIT binary patch delta 1734 zcmV;%208iR64ecmBYyzxP)t-sM{rE@k_E_V1;%U*#(O2tdK&A40>_a{x_Lm$gd^C2 z8Od%9$#4+tj1TIO9QKzD#c2r3aS+OF3gv?k@S`O0p%EAu84L~-EG;Y|A|mRV58HtT zH8wQXcLUyv3je+@h)V>|Z3BXZf<{P1T3lMHdmD8;18r|?+JB`e@3$(NWe{dC0$4*4 zw79dLp`AP}5yG1$@W(*^wg>;71poJn|LAf5{I~!5r}g1n|M_dSvrhl_eEc0vMgRGj|J5@8{@DM|IQOU&|Nrb`Tsr^9GylvF{2B;G z3`QF%G?Qo`8nsVivt^lm>vr$^KTd6en$on>O+Drp<~uTQ^=oEVe@-zYiXRV{i%Q)F zR3-BA+j*g6yQd9@CaKHaHaHpkO0(Gap50S25@I= z9~t8V)X-aiOqCxRZV+IrdmHFeY}|Hx0KA!9GC1pKMT<@IL(jA0-8l+HhW*BE9Kn_Z zjx*d2j(_*wLu5z>hBeWXq#ZQ^9x$t>GvqbGSu^BFL@~}#FPzwuLrfk*BCL$=^Z*^6 zK$`(W>kKH%)KF9zf;U7*kSUU6JFd=XL#z7=mN;bT8=$onZEW*Lk8?Ag;V& z8q+jQ$Cc9XY8Ws1`rS*E}|f=+VsutCfYQTOF-rOf1LfFbCBVtG3mb8zqY~7 z%#U+sc+qxeTb5ZTOlVu2 z5`@>Ox1wd5?g8y`0=#G*&$L3?C8x?nE`O-9T~WBLdNT$@q?n3eHr|bypAj5hUPT!6 z;hL=%Lxk>_2s5;)bG{W%#2Z9-z2dy_VTv~gSHzbE5n5LW4Mb|rutMESCfZJXy&j2} zst{ovW`zl2*khtMWWv1J&f|6y*)x=TMRqpmhA^=lYg@P}h}U0<(qcjk5~K(z1AjJH z7PttnFn=ZR8OGh_Ucfj20AeRN7y$S<5eqgI@r5|0W^u4-sl!8dMYuE1cs$@s z+Fz70=YX24^(xssk7K$I%{fyap08I#r|lKo36{^hVqX z8$u8wN+a}RTF*sDAEQ11*-zi2Gm%!ZXd44iia^X_C}W}OLlZzYqfthbEPtX*87lMH zIw2yLA_{M**F+zkpp446gvmOLzaXeCNsgCFKoK)v`j8mDl)*;!hPjI{nkyp9;%K{0 zlCTn_2!E^uoC$WLX{^`DdJ&dUOo^g$yGWAtx+$OtIuDhx@6T!@&)&kt0t!|w5Wd0% zy2vYmj>DHnQvy`JVtLdPzhdr94b0mA%l@KA*58{M;c*3gtjg~GlOMq0FhGQ zaL%&6AuI=91w7_WgArmRAPG={*82+J8P(WOh)M$xVff@%XfaR-BY#jH4z3UZo(fV( zpL+4w5TqGXO5iT~RP_^O(DtPnR^ULwH;P-8;I{|8XF``~{Z$GPg&nni=AncUPLqV^ zNZ)8P!U{R~2Jiv24KxAaY1r>*Ku7^YFT73#!{ zn{@lSHfk>spMs0_NI%p2T^{{jXkNdg8`^OA`Z^qH2LHj`{q}k(MW`N!>S_Z272@ju c=l@{*3kP-haAx4=i2wiq07*qoM6N<$g2`t&Z~y=R delta 2391 zcmV-d38?nf4dD`yBYy#CP)t-sM{rEQY83C5AIx|cv1cLBdKSoeBhii~v~4EGXa&e_ z5YvPupHmarqeE#n6v%B1%4-MAYzF37to=ySCge|p)Kh%OD zi9HVOoDkP}1n89w+8R`FvE-mT@zh!P-ADfY(EIF__|ZN5=tKX)44q^h?d!k(*)exH5cBfO{o*xtNF>C6 z8o`Mk{jwO+lz%a^e=F+Rm;d{}_0BKQh8Oq4DqkZGv}Xes9{r%nR^v~sb zaO6o%t?$k$hL06DRnd;18a_TI~Tuk3aA z=-#j2Ln><0HU`=P{cH#XMSkaq___E0!qh9Z=Y(2?`A^%+Rle1FwFF+ZTKs;s_U|->|?bDvE>#DBzrXy-;?LUWB7`C$8P-`5pAZSrR zPn88t5eb^P&Gad4WxvLhzH97ulq~n4%zs|?FGs3mDvF|MngTzK3{zRBowQfjs_y)Z zh9kJYK?@^QFmp6hgTHx?1d?~(JE?Qb>{9SZM1RqzOI=C@K}gfoEP!!7B`2R;QwjL` zuA|@tQE^VOuq6mUS^#4*E2TI>qPX3uU_Db5O^cI&+)_ZL5)iB$IN{VkeA-ZHV-1cU zMOcz^3qpvP@~1@bEvO=DZs$oyz5R?-fKQ1sS0%y;gw*vt--;~Db=_!=y?F!!3xH`y69FZd-yZ!v8|7!WD@5NbTPW!S2n~mu zXmI!9jlUTV5efpw$x=lmZJ^b+oi_8=OdNGCtW;De8o@Ltp|_rScjFZvP9P$A&M2w( z)9s&+gQ>7zoJMY-JvK}xAzn3q#@<(B4u2ez#||xUt<$4Jw!-A~+0rrZyG|fz4?vi} zz>Q~~9^cJg``{o!dsvX73|rC5Mu}zi*aqj~EI?`To~Dr+ZeBO|T=i>*m7NRmdk~pMVe% zaP8u{F^A)|A7i=z$UtD*-J8LOE`KNp(8k~YsIZ=W9FN)JiXL5be)#6=F1*jT8%Fo!PF?2yOM2VHhJQ#tfnJCj z!LYcqjw1hlpL2j_YR6=H*JqM3;5ol}-}k`0yGJXE{(eGRU6$3>;)Z-n_J6x0OTknQ z3kXnV2gMYYxcTi4g%mS=cm4Hx-RRX)qQr88P_s8ve2eWdiHY#a{X5M<=W!X+0KvNH z)V^vO%QiEj!f}KCN#0CR{(n7ooCD80j>9;PV$6szGZb7QC<%(iu&B;*5qF`Ip#Ep*ulLmtsx8_1m?ipKN@Tqiq{9*Wq7+6L`Ia91l& zRCqo>Fi<2`G+gk!B1)^3Xc$Jk+)V$ZM7K(XT25?I;b>W&WVt#J`+tBk76%)G?pl&$ zMP6z=5P21GjCRG9B+82H?mchsik40Z(RD?rqAkm=wc1nTpG1)mea%21TxAT64-{Lp zJTa}pwJhvc0^Z>@J2f`C#)OzfMpOvFXhsaday7>k1T!{`gRbiai1%1m6dkUKIDsu5 zt%G6cCnh}QCsHf1gny6?W51Htnj_v&$2@@3O0W_%N=gO>~|C*gc^@%aPz~x@%$>Ngy8bG45_!-w2VL+4Ut!Z{PGY05KzQK;ssRE zAFxRUK$arP=zr5rE~pg(F`(oQE+C}D=n@I)Lmx=B%br3~hT?f-VnYbXLlxNmcAI-% zkQTuuJpg%XKPBt{t*GYKC)3|!b|YF({-^1HJ#tF^HZP*vDtt(*fiiHgD(`QvR~(~{ zSk|5fZ!Y5d(UyGYJ4EQ8*aXkj$Mll46+wYPv;CNB7Jmr3K!lJ>^0zckwUZk*jAwyh zrvi#779LV*usD^>_=?c1KN2<43XHUuXM*y#(7`MpQ*NdPa~AX{`UJs{^-SQ{M&;i^ ztx#Y zVSB#+c_Gzar$H4ILvzA*j-^2T0eFs7n%zbMhEV0`51S-Oqum3LHt`jtP;XUw?M@@l zkIiDK3>(0glC7-OtEEzfq|_>d{W_2<$isEvKL>SxNa25;zW^cr4Edy9DCGbE002ov JPDHLkV1jb#t}Xxo diff --git a/TMessagesProj/src/main/assets/emoji/0_300.png b/TMessagesProj/src/main/assets/emoji/0_300.png index 678bb1fef22b50b146e75f6ea79b6718782defc3..da8c91b6c46430b55353352da4f8ac1f677b6767 100644 GIT binary patch delta 1082 zcmV-A1jYOQ2hRwQB!7NTOjJcja7;HK6*3$UCKwV?FCQ8f6oXGNLL?SLCmL2aCwEUc zhEXw7R$7gXje<@sMkW`NUphu67Y+*vm0vl6f`Wg3evVi*lU+E2PcK|EAAL$KQ7s#a zR5L##7M*53m|;7hX+UK;B1k6~Za^k?MJWRU0c>t^Jv~0Jgnv+fZ(KoyAOZjY02Xvo zPE!E2i)SwQo(~>Pc;Wr{z~ITx&FRalyoKN&000AONkleT%su=5X6su#1pU3OU81=FJ^D%zh$go=zgMZKMiWvNRZq~;r z{$LClV|+J6R;`Iq)#W>I`*sXjehk20x9`S~@BP4ra4f6e6clAQu;K3m$MAXaTLO-7 zAEO=JzWj0{6$l;;yU{4E_Vt$}qGmyiaV4zkwN^^+OMm%=DJDS&F?bM@?m?jya*{7H zbV<;6LmY(adW0oSS^SIP{Z61&A7dD3r~_Eiz)Zw5MR{jX#^?}Z4B9AZn&w%WLZ=oQ zx9AXK;&4f#Kw?gxKA`J97_>6WY&gblQYd(I0H?Zmrl1z)(NK)mQfmov1j)X9Y^Cf% z4{o;JVtXfq+8eS`O$}zl?LiVI+7C(2xOMgXb<4#diVQ&^Qe96FvBed~R@v)#$ zH2SgN6MBFQ(Ge7Uu)2rpo_G|5TQ)jaAx;klD%XgDtABuF7;?apeN=SGK=pizQ@e~N zF$xgM((gr3^g0Q`BIg#s8I&Zrg#h|bq=3VzDMu3EO>dErB+;Ts-~tdPDLU2k@dm*9 z(SQ1BYNxiH{5aE6hTB^ha_BN6MK?4K19Jnj^(_bj6F5M^M8S-p!>F1Rr*8N)D}Vx6 zEWdYHTjjH--UF_Y+(mb08Q7mpez>LrBD0{MMNwBen;4^7v); zp#cx|um(REZ(&o~-CF)GNS3`ILv`RM4}V1mxZI8a6~q#6!I>7}lBJAIgcqU>+VO&7 z+64%XHZeue!8ybxz7TD(jxr<%DUt?lZ|4ngegpE1sCMzaPMpDD<%SgJGfG%-=h>9Q>hE<5mst`QDD*He14=z0DKyxVNO8@`>07*qoM6N<$g6U=9 AUH||9 delta 1000 zcmVu68mZ!hZXzAKl8XS_`x{Qh!NS66~1x{>8mT>o+Id{8}G3s{>($+ zofH4iN0wY+rT_o{5p+^cQvg@Pj^Lyx{{9m_{dKd}?ceAEkAK$y00TlvL_t(|UY*z5 za^oNj24DjQ*{+?KGd}G5zvfDqjMM4v2KLWPuc~h( z(rUYmoqFiwcoNpy%Se@4FP$(}>tpHE@>r%OLYU+DrL|#;(U^x?5PGNvK|L)J2iC3^ z!J^jIum)m|d4G;WKiAD-@k5YgL^rD1_3&s>z&yE&#>7=bi(Lq{JeRs@)QS}sAqVgd zxbP$ifgLS%8+Fl;Va-!~Q8*jGIhY^X+NY`_AfaJxjO*No5P&m+`uRx&s~V*Dks6O_ zomQWc=L}HdjJk_c-Eo3X81IDYo%fE<;G7dUj!&zaYJave2P%Q^#l{{SKo~;3z9cwnfP7-{QHN-GQ_<4K zeWYb6dvc-o$IGd-Qy4Am-O3t#jO&-ia(AQTEZWlK|g{m_W4< zV}FlL1V==9D9q-0*G8ZKh1fF@y=*1`ia-E$AzBF%d=aki*xW>@9`YC&uoxm(BSAfE zTLuaNQxh?Td{rrz9sD5Ct0sb>a26nkh_Q*7!JXx8Qi$kzBY|VQzgm%SvTKTPJ{kf_ zw2d&g5^1-ZghJ3lnhEnp9J=`^y15Yd9AQp$ZDH_E9L;l-|4Wd#1=l(UT^^Ik#6d!S z6Sjthyj6@Q0c6)62|hob*2Lt39J}_6l5Sm?#0000h((9!W$&RCr$9 z)`?CVF%$*RS-gxV33&Hx;r~Cg_VaVG2q6$xt<(z=2*qda%|g=sy-bWZ3jA~(L>uvX za_dT31a^{Z3~iZltSLjwj0Fhsv>;A?ZQC)G8T|Pf*Yyw0ApdX%#~ClIVTNs-!Ei?3 zK4WT_;hJa2Jb&Za5p6RjLC0}?y*~ZwVszeO-mcHSy4a|;EF2(Q_)jO$Z7V{a;pp@u zfSduSW-K<$Wcne1fjx6YGBBJF?_&tJF4UCpM&VR7K*@EbMYbH}w2!6jx5S*&k zp^=c!nh1r0kvdqJXDlwmRg+`@GTjhFy;tydzq$x4wz#)NXU0g#f@E zLrXnVA{b*uqF6!)x7fF1S)2#-mH-0~E%P%DiLnrVar@z%M&M2lh?X(N%o7OwoCz81 zvLCig_QKjG;byK-yE8nGrhJZ1r7JLNZ zcCo>Sz7EcKH{OZ515_=ys~7_=b|}Ufh;v<{Y=6}u1n+$afM8GvDIW=A3IONRX$y%+ zY66OkcF|FhW&~o6gjNMe=dE>1j>Yl@V|{0wqv` z05Ph4Q@LX(fOD1Mp>+YOjS&&}UcMhoF!_7}92yk@3Z8c8za^0%4ezZ`t$!8kZx4rDi9xl~ImAf9#*f}bQr4;6tx!)GHZw@HSda*5vK z=Q@&L(9yu&AB4-$#|*>eav>dL@(X^h<3l@a})eFVASL9oV<2hyVZp07*qoM6N<$f}!A|jsO4v delta 897 zcmV-{1AhG62bc$tB!5LvOjJcja7@R8T+fea*PVCKly1+DXwZ>s)|qm}epk|xZ0f$6 z$%bI;z?|T$hwjCp^Uka3yO#Uhz4z6$ zL*Hcn{2L3sW;6i~ZZGRp9eg8+jGfbmvvU>|2 z6Jw0|a%PCi^1pb$d>3z=VZfaGZoU%CnNv9Z;`f{qvN7Am@9CLRK9@D*oYT4Zb3fFcm}QgnivO+HEWyI}yrHsdW+ zfM$V01VufDPQ^4T-ao%m3GPExs$TiM6+;*>4Djqw`+rJu4{xRdfL&w2XaXuMYSP)MawS0sf3M2zg>&l)*`z9&?T z_@|MvT7Q2_98fU)Wn?S^glk-b*YP#sEfg^XNfKG-7_l7fG8jp@hmi@wY+^7HB%%-z zuiW6Ba6N=eln|>LA^b)?QJ{m6b|} z@OmPunkJ}3`naCBc|tl!5+BGc@pkOjJcja7@Q~4rnzQ20wy0ce}rE3?N^lRg>31e!?(sw6bXn z%XtdYhY1EHX2W?30UK4&gbFBUs~#3H(ufNIC287^2+w~B+mQ(iM~je53l82N$X(g~;4VFv|uwM;FhkwgjnA_!@4Eeq*>ZB0# zwITe)HT%Lb?Wz{>upHo)3fqne{>VD^xhDVBTK~~X|I9$LV+_=T3Kv(K|I|}XjnNNI zlK<9Vm`o01qv&3p;c%9?d_fkXt(>u%TZMXHIw&$zbClq=M8&*;?|&N?0000gbW%=J z0R9gB{r>&@{(t^FA-MfnL81O5Y+>!#-S3%ky5fqZy2yp(-ucb8=>GoRwfpM;00fXp zL_t(|UZvHEQrk!n24Kk-z5zR6?j#VhF!!a?CpXEy|NCsuj8-O8Hifj~DpdiRkH4o| za`5Lh7!=pqYkGNk9yHD`FUNI-eiX-ie4fUOtGYSPjep^Mb_Ew)H^x;&BdHO^Qts6g z23Im&r&^`4A+tukqabv#UI-b(<)B_u#w4=4X}pf*LA{<#JpoZ-s;2cCLU6oJh;+o) zTEre<>vigg2-RvyV@M1TNF@Jd)(io;gjq6MnqL#=lk%(I3IYSr-o@+}; zRb#d$GsNLp=V9)N8eJW0#DKu<+yD`&gMRhFQp7kSG%-j@Ri4i&(jtYuQRWDabmg`V zm8J#3fM6om6?@V+&Tp`^jim_&A}$E1gsOb6+8fIsMVwk9iTz;=s}V}Fl5kc;^mUct>gR~U zYyu$*BEdu-R%yxDpQfFMtc`(KCtRpXEtx8U3u5Dm1(QgRtBf}iexnhac9b}bB6VD4 zynm7OC&0ueD@uw8yfdoQL76AWCZp-XwM0~T2M>vejBDi^0t@u=KB$!KNuoUD& z->nT>M#N2G>tK=EWP+y<0|+Xilwsoo0)Lc&9g!GL^(G_Ocp{>bKv(`~G(MeJfnv^J z7lgnf-()Ca5W^D!jBlr(8vhA=c?}5>R$#Czf#?JXC9#2@7%q+Gm)|0d-OtVDHzFjB zKrk##;UokKH<>1sn>6M4Un5+teun_CTFqYw2p9yr7?wn}A2&IY5ttbB!g!g_9e?sG zaAAQ??*{^bJArXb1=5)%pf*^%Fwl=)$0DoGyYGShUbp*93&HRRGOHYjP`UCj=gb+; z-BxcOka>wrE{*_z2(9kT@_{-bbyXmx!|eEbs1ADs2yhIp3J{#Z?Mp6v+}#oAX*_}O&e#u1p$q{@moH(MJ)TXr#N_O;9X>xmPWU*&8ZB!Ch2Y94 z2#DG0G)JQo0JbqkqgC(5-u2!HO2LQlht=I*HAknvK82^FW~b#2%nJ8AMO#`xc)|1V z@xr`0@?~t-?x?xi@7lIG!&b#`Mo@-uycc>PjLPS*ETuF+fs2a)Mo^Yv3E!?>r!3=r zDf6B;V3jcf-;MIuAhh0>QI>MnJnFRIc6-0Q00G87|H4T7_=KXX00000NkvXXu0mjf DgtWZT delta 795 zcmV+$1LXYg3$g}~B!4zgOjJcja7@2{R?(ex)uepAd{VY_O1*wmvu;Jce^tDEQq`k- z-nEa}tcBE~de4_`$ckXUepKPSmhCI1OaK4?3v^OWQvfuu)7`LE{e~Ir^mEWh0007@ zNklB=J^5JlB?ZP&d2%g(h5BY}LAvQHrX@^EVbTYvqJl+;7K*9vHJUH*|k zUpZ%!=J|S+={U`ja5LwZQL$t?5yt2f1Kot9c#|hrG6-{>1kv|2fXh;f%hx=GCn0KP zZd=KORKTbtF2)oNk&ElKlzNe~m}G7vt0viZ3Kx3s!^U1QzvLAFW2i6NPlWGHekMzp?)!d8Kk495=AXv z4RD~TA^h%z?UmZ_1vsGixfqERudn3N&tTn4UwXiKOEFhn*@77oAqZU zP{_CQYYK@XS;Sz+UI=N5z2WTmM4STX00(M;1V18^Z-$Ue1h_Cb$Yy1dDs&)6tDEI0 ztw$vx!hb;$Q0EV@qqgBiisS+XfrKq9N1@FU;bB;g+5pEWsKY5C90QJBO9A3KKnh&S z+W|;{I;2F7@o7LSq7tK5400?*>t4xmyBTaat%EBGYbK|4>=gwoMLDlSCA&wmLR6~{ z6`W#+Kr7Ul;=P|+;Z7A~Sb{ti@u`9Y^rD_C_Y}p|oxL zv+c)YD*67*>jgQkq?Y{=Kb$(pu_MzvI9yWaBsY4i0D=I+BfJX(gy6h-O7hV;=YLJ} Z9~3)nPtf+X-Vgu)002ovPDHLkV1hV`bo>AS diff --git a/TMessagesProj/src/main/assets/emoji/0_303.png b/TMessagesProj/src/main/assets/emoji/0_303.png index d8eb81a32f90f10033a2f4c689f6ca7fdca085ad..c17125b681a40fea26cc8939723ca2b95f381218 100644 GIT binary patch delta 1391 zcmV-#1(5oe2Z9TbB!9zDOjJcja7+k5f>)N=Bx9!>TAtaScv&$s-KK%dieol)x;}lu z&XH`*m3G{wf#b4{)}49at%(C8XWXZO!+~7~7fA;yY22rR032TqN{!i|d%k&812lF4 z5=ZmTtp^iKvVv$$FfRr`gGGeM_}8`b&8z9Tl0V_;jD-H z+qwJRz0i|wQjygXQkG<-=q+rpUY_Dum)lH>&->xRz8L^)Ca=Ejn6 zWx|_*U3#Ba;5#Y+001L&QchC<{q+6*{tEv7{{B1|tl(LW{lO(L!fsLW+n}m#<>K;n zdj6H2=2!p#1b<6OL_t(|UZvLAcH%e?24FMT*eo$?NJ2u=gLZji-?H`lKh;!80-BRE z-LYF2T%qs$e@QlYzh9k>`>edi(`nD^^rq8pRiUll-$}Rk{{B9#nxmH!LgE-dtHy{4 z)ih;VQ+ZQO=uBz8%LU7K8IK#)Mxkhu?6}+|iHwJph<~oqxSQ^hofOrEG3H2cB&Zly zI}lEgkcQ}05gIp0#T5mq6(Od^pofO3_#D-dIbH{wK8y5TpB8bajIgjc$rG1EYh5Q#*J3KwG- zGkioykbhd@p;3OCDa#BIBB4e3d3IuSXSmpX!qa8PoXp^#YuMNWifVK6K=iqQ5*XkiJ$)1cfidMVSt5=kc0U|dFM z41^+Q0x29usd;uD1kaKyLbJ5g9UndjX?I=-m4B9cbG1W8b4x@4F>weNrQTd!p|mCB znUJE?k&FdD6NM!*$xk{R| z5)bQuOScaRn!9wB$^5 zzkgLD=28=PAcXA;nYnpVslHXEGf)u1^~kii5QIt&6K(wYzl{+xM^GS?^N2P^ukkyi zarfhfn;Jl%KxDX&m_`r@YrNb(HU1a4eG5P^A;7@sD%eLtk~{|w2`UvBHHUl!YPA=2 z7V;d=fB}(mh>-(9unOe(Tr6t0cV7?y7Jm!>Ls=n5BZCm4*his~V1Qr^u0H(5S7h`E zz@onT$xr|S01!A!i~T-ilA8U_5II$>W^^?h&YiFxwtw<_HZLL>fesNstO=M&yX&tktxL4@pMe=wAc)D8jvz7^B5zhcF!gjt{A1MlXMmYk-1n%>25CFn(rr7Ve0b>S+ zLx4cwBy85}gNZ>TOT%K)w&&f(GVW*(>kS&Mli_>5iEtK{%jE$C6QcO#RXGWTqB!Zp za=qTn!LS3VBT>f^t_28aKw1b9e1D8C#E%GKfN@wZjj?qGARd-*!iiWOrDSlNZ+92s z=`BbZr-wBX*M@g3*tMCzeiqTkbLT>go-Wtpud0BtvIY_^Myusr3mX)gK7@Eg;A@rD3=F&G x)<9zR&()eW>-SjWD=~Vm-PfD5?fI*g_z#)+8*u8~IMo0E002ovPDHLkV1kH&l(PT; delta 896 zcmV-`1AqL23zr9wB!5LvOjJcja7=VdHETpLeo;JlO*wo}J7_~MXhSb}OgL6IBxXS^ zt#?|hby%EdPPl?$z>sOZie;~NTcd1Kmt#zdSwnhGIm47~O9;T=0000EbW%=J09Ksh ze>c4T8vftosm1van+gB`0`o~kK~#8Noz{tN>Oc$y&{>yko_{_6|EbS*LZKCU%y1(C zLet>6n+95(0HXv_Cci+2{1g&O6 zHp{U=DjJY;IV^rG)ydwycaqv=D@Nj4EtuL=(5=?yOv5M~r&ew4$VN@?4bvAHG`)A- z@f*YAC_FR+MYuQrys5QNBdpR6<%!rJAD?^Jjs`a2m474-ZKh%sZ3^Tf2U@gN3*VOb z6I8H@mKrfLLR11G9k!FM^Fm71*7aJ|z&cwY0Eu6TDVJkie0LuS)mb?IB%%SO;Zi>n zbhy$(_}il*@o^UciA2PEqc4m7OjIV`_kil17$JC@?}^ft7~4g9PnLZD6riNbW1=}R z5all<13B00T?$H5BZOVqsHNnR?_5TL(v292SUN)fWT{Pr^(I{D8+2zy7tbvn>j|2+wVPPr&pXLiSf8rujL9)iopW6q*yW zaXiT_+)t3{N%*c(SWsd`3;rCc{`t5^%V*^N{V_0yPV;Ew{NlKrbd!&~Qpf-R1NKQoK~#8N zrPT+I;ye%r;C~c)37rKNw%xgwB$RFU|9{vwW2dk}---B)6d@Enns>%F!Qa<-Ts*zk za<$q8!`*5%_Z2qe{hcp&@9*y`-#T_F=X9}xCtrFJ3r-|aOmadJKViHgX`U;V=c#xa zdJ%I$@;ny?9_DG|Nk||JI%MxRlclK%<=4-h;TXgbJAWTxmI1oJ2ND$?5V=VWKBC)oFRQq}JB9ushkn1Q#NvUMmcplp1NE|Ie znQlDRg@01AATUpAwAwYzp&3Vl6a-Ov(Tteym7&*!WIAfL$9Gzh^oq!-(9ygZp_t4o z!ZjmWHoLKu;5AV+BWZSHVJqs1xMsXI+*l_45hUkAH@dmznvokqHTqXvVmAw7?V3W3 ziW(7RH&as)q}k1tFjEqvwR9L^>aEdTL1;-F3x7fiwHP+ZK~hJElE}Gfk|YsEI)Va0 zDncdqpD{!D4MB-u_l|XlMbP|)kcP43?mrMx5v(FoX#`Vubz`#^L>4(xjzsyLfblfG z=Y$C?q9CLi9StoBf>DNdG(v#jh?Ei_1Wz3yp$s(sh72EnfnX%3sUx`2qa%~FAe`|$ zJAeEiGCa&aBS=9|NL>*k8XXl*7>Uvt#SXcxU>3(C6eLBW7$XqcjhOP%SWmNf_IQH; zFwL?rK?ufhixZ*NqmgDrrYQ)Na)~W{4zuhA+0Lc_gq=UE67YS)^brX|xD}ki{&djD zrhwEyoFOo1w?Bw$B@mcfArUEvhjd|lw0|dq3Mnf?OMYkVKxn>na$8apxb*m ze@iP+2_bZ}eubmCd5sV;5(}jKyVvWs>O#VxD!~co(}kwC2&SUr+s4g%{sv(R;(u~} zK%-q00z?SFwQxE?6j#LhcRjK*MpwxF)tQ&+CtmZyWWD1QX*?8Bzz9m=s>0R)gepee(SDqPfv-N41Q(^b delta 799 zcmV+)1K|9f3bqE2B!4zgOjJcja79%45khEXwAFdbqzAy_dTPAeK*G#^%5OaK4?3v^OWQvg>wu$p!3KODXQNl;DE`;W{q= zkr1xd+ErXR+I^E^yIsn4Yc7|lspX2430p)W6&m@A+TGewE-7>D6bVOD;cnNV#C>=z zLw=`37s5VUyA6_zNE;iujA%kc>_k0glag*^4Jr2BY8?4wM2^X%l*GwPM8Hl>Lqcex zHz^&ehBX4zAb;vdsw@#gQjO?-Z4m5Qyh98X05E!Sq>GKSc0D2^XfTTgh%xCLS;v7I z!pcSyGa@pdzEno$YU3muC+DSm>ZP_NCj<)!88a(!P+vINz!ucCQnTo0keO@h)WI*b zKt!-(x!bMLt44}cUj<7`L>J(GrV(Hbkpc3;IuR!DKz}-1^*lMgB{EOpZxP$+TO#6| z;%^TW;_WVq5VFWuhSUh(5riDw3PCRo0?uw}7ynHX-xC?(wb44(vT~?)v%erb<7=aJ zSRhKB#(s-A34<8}X_8GMoNPT5p+*{01`*vtvKi1->H0Sm5eP7^5J7*BsE9BlVrU3B zxs{|-41YsLrqPl85>etXa0tH!fo^jt{+z~$5k$bzEhaw==wrDs=2+Y4FlGxQbdK#B zqk|E4q{|6&lE)kv+sRV;N%;1n75&Qq6d@fLeA5W}YRC zh;E<2F$fufd6O8c7*n(+MA{@C0yX-GFu^Klc7G4Vg=)eCj0k%Kvk3;=?N*}h5q=8u zk-T{=Tw)aA`Tsw|#tIyZvM{B-8S0M-NVuZAU&-lh#Ow%O+*1S(w`zS)Dq0y#_ym zVnRNfW=@o1N(UumplVT_XioqfU#DrrPHF;q^Diabr1rkdG zJAZ3jUT#M+V?QjdbXmcWX}X7GxPoE5jAo{8RkC_qooG;dP=7nLeP3jw=T42$#FT4W zJ1Uu$nrx1^FmJS8o#8=%#EpD;O>LH6@lW~y001C#QchC<{{0jE{{8;`{ro7iNc`xR zQFc1pY0PlKnd-W!`MKJRx-jAZ00YNKL_t(|UZvD&bK*D<24ElDHb;PjkYl!W+uTX! z|Npk_ZizvYt$&@u8hsEHWj*xUl9l~=lx3Kc$5P5=RxadvnkrQCaM07`;c#eE>sSb_ z^?Hr7d`u+PQb}b1C$&fu%C!;)VGK@oot9*36}G{))QfqQNJv^ujxuR`vTP$_nYJNB z2o9nkk+2#GAVNaYmXx(8EE9DiA^w(lB0>WkXnrbFh<`a(VL&7k6~si+*_tw;nGk8j zBW~x7Fw=Cx86vDndEIMJH=;EuXKM|T3FnDAVMFGg$eB=Pp3n*dIuIx!G3|b30nl36 z~;2bg0nta)bcrrF3LNgZKZY!$o);CYr?ZUhd2f>ss@qsTxH2OG`gIYwe&GHDR-f?w1^j)aW}GV-FBJU{#g zL4TkqM(7yT8v%pMPhi0tST&f22+BsXH{j=GKuEzz z44^Rn{Nfnmm*9}d4afUse2vFwF!JV+>aDl}{ry>S34&9AF?qB7kvjvv$&w6p?th}e z$f$T*W!1(5Ug-6{d?$n8@_(vT<4iDU$bZwmPX>iyB%9!R%HW0J$CDa~415SqfdUzPrtn0pZp5ZBU=;~SkkP*ygN#Ci6h!bi(|?(A z&C5eXyyVo4(+3g18yO4zNT6r-UoLNsFVPXMUXHo@I)CiEF^r5X2pl627 zKEsnkCOFDCyT(8Rfgn(f(91YVFgyqu-pa^=5HbcKit#PV#T&ywkikUn`YWHi@gR=z hJ<6CKrv*59;$LY|>{|0f{XqZ#002ovPDHLkV1jawH#z_S delta 685 zcmV;e0#g0g3B?7FB!4GROjJcja7-&67BM3nH6|Z2BOERu7%(ClE+835G%YwNAz4H@ zMKUZB9yt_NNeL=kC-3;00KlwL_t(|+MU(`Zo?o91yI1o zVC?&!ci5pqi=z4iXPQ46vh5MaU`SO`|z=>cKFgTY4x8u1V( zeh*TO_-4@We|xOYgz}o>eG8Qg>1Y?Z>>mY-1tn;oJ@d-{^fGdyYtrdy91*;ce^^lcRJV+>`7QQcHkni&%olo+C5~ z-&!z5h<{Qq~-ogFvVNAu;&O9yM)D`(lD`waXla{NGw4;!wCu!TNs`&L7Yw4 zz|i2Crj~gFZo~;2!+>qv&outIC}H9*+|KkRL2+XICu)kNvD`~QkRX=VbL_iQ-FW^m z4SxR=<`yPe-i8WiNb!IfYJdq?UJwQSF%c2w3??qb(=cb|`Gb_+rZhl=_N&1kaaTBE T$W(Jj00000NkvXXu0mjfxa%?r diff --git a/TMessagesProj/src/main/assets/emoji/0_306.png b/TMessagesProj/src/main/assets/emoji/0_306.png index 834b99caa1f9950b858e884ea386e376e9c3829a..010eaf7f63f0ec7b14c49bef2082b7ac2be142b2 100644 GIT binary patch delta 1146 zcmV-=1cm#S29F7lB!7xfOjJcja7=JOCIv8ZWjP`VMTsF^p*<}=Q7|E8J0(LcGi^U6 zbVDfuID2kDCJ7ly2^vy7c)V7W*k3guj#xAX5=?ePDUewLxaaVdcGoGp(<*wGIF*`DSsJrftYw`V`8G_EF341 zWJn#NZdd>S02OpnPE!Ej{-pZ!Oc(t#X}!3OZSeE-z~s83^D7|$00W;%L_t(|UZvHG zlA<~g24EEjf{MC2ojW(LmzjP4*E^jiS#X`RJ7iN<3ajv|zq>I^{=Blx@6l_q-!CRv zvEQe$LeA^jE`N%;uJ^Gy3azc4?zOdc5lJjLw;Tj+Dv1-az0$P?QP)~d<0{D|$2LfX zo0{fPL`sCBO{8%nl{OF@;`&(-A&C%06p?g<`UheuH4Z~`MATF>Pe>%JSpGY)%VLPB ztb1Y_L*#-8pgoRAg&GhLLo7TY+%6%HAc_G|%c#dQ5r5nfhEgafB8a81NLT|J4FyTe zOg&*7!C@NFO%U1<%oC7DgpfqEL|6gKZ1hM$)wp;d%;*?P0NxQy(?|>yW9tBEhXe<+ z8%LxDlpYdTiOI&b!U!G+N@JyA=_sOr-w3UMEk+SLY6TIdBRH63WH;6CgfP3Ygs%HS zs2MQo@PA7~H)}N@M!gjmAUO%TCzN2L2qCQ}ZY*30la4wo)Gwm-1Q(EuI{ya*_kzNQh*_OGw!-QeY+dh!EDNcZAnC8p-!NVfB~9H@lJJI0B)q zxV0)=qw%eGYer=RfH#D}QbH;$n#6k2$h*y+nccgfh2Qa8G!H zy|4dQS+6!G2$}>gkpMSgB7!kneT}56`J72bf+x5V3<*giwjF_nnK$!QntcH@P4fsD zXjvtpz1@sd4z;wLVa`qCkmo@XaK4-+=Rt6{3nB!%w0t}8zNSN7fa~e_=!BXCml+8L zSbv_QEhSNp)9KnH1K@l)osQL=li&z0g#gwjJ7$Ck1tP)k6&Zvyt9+8LJ#a;!D$9o^ zg9HH6PP3dD05m8Deja6YJfabh2?DN$ARNk{n86E%v0aWacZ4Y4q_V843JnT!Zr&y# z0tyHmK0fXpp-^ZO->)=bn1hpX|2UMCgMWfJ;*BDZKm-~-glUU@WQl=pw2zOEgEOjN zAkh^;Rgi!NJyXDLgTb%cF2)0Mk`Zz^0)e4G#!n@&jL#wQ$y_(?C=k&bNW2J`w0eMH zpPQ^F^39Ez2MHlYFecl+ia;F7>U5rMHtVOq;AS?zR&*DALOZV4$<_mAZvM125j+bUW+vEWVrSt|7-q=pIeHmyRNVqy-{c@Vj=FP>;zBfEk z`7(a#$Lo3S%XlfJxsp*1V_=HvM_3299k*|N884;0ZI3_tg~WFI9~r~Vlu^iXJOBUy M07*qoM6N<$f{l;!O8@`> delta 766 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 Ve#};x4;=si002ovPDHLkV1j8%)r$ZC delta 653 zcmV;80&@NR2c-p&B!53pOjJcja7@2{RlIso)uw;EdQrT4QM!3g+pvh!pLWKLWZSQa z*{p=wt%k~uWZt%r&zEl3r+>tRTH?Hx<-?!9d{TmqZubBH01b3fPE!EO>qc!doc{h3 z$atYz*|4<$00Ia}L_t(|+NIV@uEQV<1<>$^Bw$F`|5_i0Qh&X+>VR9%Dpg0<<`cGW z71VJYDr|6tV|Okkw<}mUa}!!!=?til9RplDWGKqH3-^s0!jBMlH`1{#m`D$zRWscB zOf?gu53bn?Okl0p7lILI)(P*%C}xgxwUH8icAc0;Qj0{5^h(^T6E(Gv&*{ZjoM;f` zBgVZL!bjOV3^+y*Wf~V6!#s_2pGQYL^1dJJL+UIZY* z1e|l(M-2(Qulj;!it8bQ7*CBUNVC2tqIZ*E0cb-~?tSnmd@LH++=cQSW+oPZJ|=-J z1`m@7_Yf?$vj^dtKsI3KoUh*wkYE9sCKI^{QJ4)X+X?SulnMgIYo}E#&~na~N@Ss; z!p2{sR)3|~4GzHs3jq%?1QC7=G0!)A_s_+ELvRYa{TL#O01LVc6csE4QTd1wsh`@Q zoU_ZvFS8s^BzJs)|qm}epk|xZ0f$6$%bI;z?|T$ zhwjCp-KBo%yO#Uhz4z6$L*Hcn{2NBZ@KG#qaSQV>;DZQcCeu{@l;GGHZ$NcTB~- zN@8mFXH0RQDI)b-jeQp)?haF8aHa$%7KE@NadvqjmDj{ZUQD#$LRbp!FBIwJPdvvE zPeP=a66y*>uz##gT3_M}5r(iNN!iy;vbas8V`n1xAp(LJGJ&&DD=bDJ>tr$Lh6b@Y zNO25{;is7v!%$tEv|1=Vk^^e2> z8OvWr!hbwKxGFVd9bXgPLheRGqNICqj8I4Ih9EJu2r@yKts9J#E0@AVL0Z&6bpN`* z(jUzAP9=~YA^gTYu5T>79@ytfCBvacahKdW$Xyv8ZW6P9)q2Jx%mEE+CbVk4ZuVx(Owa zntq2jEI4O+J))3r2;^$n>Om(cz0;6-BW}A03C;A^32gu QzW@LL07*qoM6N<$f@Ybhl>h($ delta 663 zcmV;I0%-l22e$=~EPruGG;>Ndwt`@CNi=jyHE>8Yh+IRAUPf?7Gr5Lhwu51bSwg07 zRghgry^LnUl53r2Pq27fg;qeggJFA5I>woDK<id|s6~75T_$ z*Z$%>o09+l0uxC@K~#8NrI+2V;~)%#10jK=#r&r4|EO#1YJbz!*>k~kq+ax*pT=X$ zrps>%{;@uMSYU<6*%Rx0z=XB-fyg$DAu!oZrMHd+w|Zo^#{F(V~>HiEqxGdeS18{Yh7<2@1j{-JSZZPiUk(1bf8F~H%TcQAYcPs{;MI>|`W#W91VnM&5cQ#;QAO^&vn{EF%64O6u`E*Xie? xIgZ0vYYtf%RN{QBe%pLtdAD2Z_{;BrKbLzzXb^vmPYVD5002ovPDHLkV1oR+GzkCz diff --git a/TMessagesProj/src/main/assets/emoji/0_31.png b/TMessagesProj/src/main/assets/emoji/0_31.png index e96d5d884a94bb299f24d27f034043994ab6947e..fb961ca06fb86a13532d28efb5379c902dbe5b73 100644 GIT binary patch delta 2208 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 FV1gUXujK#$ diff --git a/TMessagesProj/src/main/assets/emoji/0_310.png b/TMessagesProj/src/main/assets/emoji/0_310.png index 518d800295f1aec77f6da8283fc14f0e01ddbdc9..2af4a8615b759ef2f1d34bad46ed909dcc3059bd 100644 GIT binary patch delta 795 zcmV+$1LXYi1hNK@B!4zgOjJcja7@2{R?(ex)uepAd{VY_O1*wmvu;Jce^tDEQq`k- z*{p@$wU5-Ide4_`$ckXUepKPSmV(*PSpWb43v^OWQvfuu)7`LE{e~Ir^mEWh0007@ zNkl>yGOn3!M-oc1gH1=gX)_nXf2g^p3!H!XR(*$dL@n96LqyIRxae+~V*h4{)bM z$up-dETI)*R1yzkXqL$2S|KV2n`DwXjcl4^?-nk!*1C<2AVtGfB+;!93v|XX;(X|k z;xSY$C14PhGk@BSfIw_Kp%yP2q!u7ls@1k4&i5VwHOMkTxmIhztt}?oaKX(;#5fhI zP68tK-jE(V2weLZXAp=pr{tWXcMl^jqQt9FGqHn+Cy`*Yx^vomBpJb_6x3-p7An;X zTC~RZXXILcR8YnG1|v#{%6nyD{ziC5u46@l$2kwz^?x29r5YQsU&&HG2#io^Sc`-x z^ihCOuP>=MtP*pjYLB?j=YPWO5-cnr4M>_xj002ovPDHLkV1j8iaIydZ delta 600 zcmV-e0;m152Jr-tB!4+jOjJcja7;%lWP;$;CGI-q9 z3TKHZK+DliBImNuLxHnFM(jtMz>XUBCib0;;`Bo5Ow1C~NcuVIMeGt}6#qf&**zm< z6vBxcS+vBc^F;RFXg3;%)OaVf8%^u@AlQg1g2Gi}f6Jy_hSd0D6BDC1A=;53 zB2;p?h+yKlh`CBYFt$zt7bpk;AE(^xlV~FJ`#6zz6%Ka@kYM~taIgy@v6JYyK!FKP z9ms`vy&{O<4H(Y^M+Cft5SE^nz=afq7$F%nb{#@QgKuKa;my+$mS7=DiC*zVP+*~R zaKiH#=TXn2HHY7-G3GySSqQ&X_dnJK4P)mfco0r$OCmyANG|5sHm83Suj?ADy$*(F m(yuken23|2wbt{8@4yc&Z8R>6^vt*b0000c4T8vftosm1van+gB`0`*BmK~#8No!0BF<0=dVU?AMmB!9NK_5C09*r1$tM%5I$ zBDMR+)~97hBvt=PjOw>Ur=0-qJTCo{;LcXt8I?O~eUf0SUE)?f#0N}Mi z4|_11^xPnY4N56rj{nTXYk&~EmUhXhnRqOjQ_#c>OF?guV|0L0Hs@wGY5|Y~yJi9r zU;_ZOeH_DwW}-;%-T&W~lBE$>!OH|84ocVe9uC+5z<<7y)+3uK0JzyqDeH+Ah$Z*i zQvVMt1##0GV|Iop0#rF{Pr050$-GSurI?9zVitgjKT=!D*JBUhzY+$z@cb*44a&$% z{Z7c?YPaxrkHW;)T|_3D5T6a$clVtro%q~?O7Loi=-d2EWH4%O7wt3gYzh2#!eAc8 z=Vjm{PJbM;lIXJ`M42EoNDca2V~&UqDBb8gt#?*hCXBd=R*6@M ze%P6?iv)}kX$X8}Tqi^r07nSDM7T#625=K@jQ~UuUXNkQ+Zv(YpW}m&W4aQH*oF63 zha={>(u;0i0~rp8euU1@oT422DjQG)0^I8uN`EPpxYs|dpc(QLY|oCqT% zRVSDPVsKS;0L~Cq_pp@q39(i)@h~D@2VP2gTr4q&_@zPsLfr+NXlhRwV4~bsC3vE- znGHvviBkV&V>gUt15YE~=QgB$Hl=La_++I0G>mbO2FYR^jA-m%d_<6uVH*$QePF>n z@V!CSm(xu=7=Q0M<*?7V-wZ*nls}Ak%E;bVFpss-b0LHw#&8?y$qwprp|#z- zALacr0T2Q=M+^%nA;_AC*$jq8+YxX(eX zt-wgVUMfat-VAVS!h~m8IYH>iL~Cuf6W^HL4BW(Y!Qm*0!AJp?%rfvG0#8E4gP{3J zs(P5Es^-E+4IP9bp_9>e#8o2L4kHX@Q;I~O3+EW7NJ-mQ@d)GYBK>aFrNAY`9BC-B fh@|l&{1&SpopT=O4{|3k00000NkvXXu0mjf!rSe9 diff --git a/TMessagesProj/src/main/assets/emoji/0_312.png b/TMessagesProj/src/main/assets/emoji/0_312.png index e1f8e6ab851cf1589461fdb291270c02a31a233b..3389dae46dad8a1009f0c5a30e81a6ca0ed56926 100644 GIT binary patch delta 799 zcmV+)1K|9f3AP51B!4zgOjJcja79%45khEXwAFdbqzAy_dTPAeK*G#^n+a3v^OWQvg>wpA5h;4JjpY^4b*8scA?E zP4q)bhpJ(XKz}ue`jIM2gpkxhbiZ~8bS>U7hKh&~y*SckoDCao=vD~&uR+M!Ep74FCGj(n0cT?-pq9@B+nfCZ;TdLQ zCUAi$buzYF*d>f+7}6x0L^#=c2ttiCrWg_3Lh>-MtJ24pDfV&AD@4%GBPfFXi8T>| zlUqqT#eY!b$!m0AzeJR1#)I_7Ak;ON;?K#D41x$by2a$#z>YR9+8v9F&U%MV zMTxRSBnA=Y-~Z9=5df2*MBXKE{%?mmr#&JIVIAHnIBd6&5)%>2Zv<^m;XEV#c83cU zY>T%bggOGp@&!@i3D_k9oY{o!_;|A9tkJt~Q+$pw drx@@7_y@j*Q%^q2ssjK3002ovPDHLkV1m-gX4(J% delta 1161 zcmV;41a|wj2Av6zB!Br(OjJcja7=f1cTX}jK0ZFVy1JB%jj*w?X=!O*T3TFOTUbR# zdV73-e}8mzbaZrdZ*OmMa&uZ*UT0@)j*gCsii^0ryGcn&I5;?KXlFM!HfCmMxVgHl zPh5I+c3og#!NtX=5g}V!T}w+#NJvO7E-t7aFEcYUOiWCPiGPWLf`V9BShNco%F4>1 zMo@rcXQHB}tN;p?mX|X#Glz$Vfq{W?a&m-&gvZ3ir>3ZFZEbvfd{tFdii(R#Nl9X2 zVp>{SPft&tpP!MGn9=J>cNrwu+I#RA9Mnc8_Lkrg3_VPF0PKjf{_! zo(K=bo1a@MEr0aOA>{x705fz_PE!E>H~ak#{Qd<`6wO)Zg&sY&#;-6@+G?93Z@>PQ zj-UI>@5#hymZ|1*@63Ov&EAjg{*J)RCIA2fAW1|)RCr#c*4K8UNDu~KkP)C@Nmj6} zXv`sQlbssa&bhAQWfxj~N4l6o!YH#T_Zd%s&R<$87|0t_}u2)Hrv`6DN-2 zD42y3AOe2eL9~dX$k9dUp~loGozZexAPh!9)~Gzhal9-H5)|7&EW`Kx!Z7KfM!&RC zyGjy3w12^i8ZD!AZW9O;ahN`pfFkaV;b{_TBXaa80ry4*W|R<+I8u6}gm$atjWZxZ z-Gk{Hotqt_e7=PTW2sE)aoR!<_1h%W@nIC=@kSkC46h5rhfxUiyqbYXAHBT~wvUI#_E&?D4{B7d3QCvuh;W?2Sy3a5%Su46y;q`d3a z(8ln3>6oSz!Mu((+O^S%W3O%f6vpQ)qN#l`=vVQ?@OI9Hu&nU_-^3kQGRrb)J)w>E z*h(Q;Y7MYN)3PLwSSqaxEHM)z^Oruc#TW-v?;k9Y#)%);c@Ou+(<4!u%MXXALd+0C zzkf#p!dRZ$(iUr4K`invAe?)VT(9$W9?TE|As|psX+yBJ{I63-xhWu}w002XP@Xf^$?SF0|ghxOB!ajOC{|G|^nU-@9jw)E8JwFJr zN^GV)N|NyZ2%R6oj-dk_1~&KBTF?-G7?Ad>NLh?O4A*d1n zX_oDGt6#z%UzAqd?~6??gs{@jbhFy-c5j=<@0D_^c;1TbYPE#|+2{Uk^7VBIznd~d z|5eJ(X0zLEgphBO$>rrGEa$Oag6Mqy2`8D{?4S^2@?2&g?x?FXKhfzn8jY8im-E_x b3x5L}1E>lqccTIT0000W}000SeQchC<{vwpQ-bicXU5}U`0006+Nklo7jreBJ?|*x&&xG=t<9!R24C!bW-zLFBLZ69Rj(_fpXF^X1$}EqD9ucK_4UM@M3-O0NbRr(O3{lUztQLnvsrf>7%vc1Z!y0bz9Z}^>=_q&^yp1)_zOxQC z`Z0Ld80xDy3~XZ|>fziD1>fj>AA62SjeCoA9^q~55|g8J9^8}c5>iWmXp2~a$etrK z3Ex^UMSqA=FXQzbPV9B+GBCwkxUlC46T5`PpVBa~g>gL~El4auJ;MnK5?dIaFhQJ6 z*uc=>nWmO`18&3#8^eHY+|M-rxhP@cF5J%aB|&jw{3mLPrLo*gK#(Ao*K_Q{<|hm;#M3Zm=J|t^-ljA_g!Ze!A8}VW UV#ri;M*si-07*qoM6N<$g7Gaf9smFU delta 1241 zcmV;~1Sb2%1?&lsBYy!+P)t-sM{rDogM(aWQp-6+sZ>(XJ4UvMiwOz|XXM>{=0 zZf~CL{SV43_8*`m_A~%>Dh^dTBPSmu~UZh<0jCnu}hw zo@jAlFrklSR#sNJs(;C^S%Ggu{_3Erl~~xke6X2Gv9Ynoy_4|Vo9X4i%FNFB_1Dic zKd~z{t0*$!M1N4)L{8Q?ManEW=Rr=uD>nO#lifW^{k6H!D>&p;V5BH9_<@PmFFdy| zI=U=3#wj-GMpW)fSn^X~{HCh+ZFt{(Z}MJg{+glv%FW$1LcC&D@3fFY1TH85001j= zQchC<{We)6JreEyZT?&A{q1<|rsad;ap_z`?R&P%$A9p<+0Cfam3yZ7iO=nF+EFP0 z00SdQL_t(|Ud+?kY8x>W2H?Uh&9cH z^R0E51;nU8#*+k^sOzXG3Iq%; zb_Fut$?8Icd3`=dn_UG-szbz$595L87C;P}U6P%$Y7?=g`OVTT6mh7s(RQDgY@cR zWPgfqCJ^--f?q>yt%x5@S&|RL)|Q~3N~DT70>L={ehqPi7L$lv6E-b=e>tN5)E3ok z2f4eZg(k{>h)5IDT8N1R7#E^WS+9wi4MBkD@^O+wl_XV>S`p2Y&VIj7p5dkLxe@WV zS32lT5C*_7Jc&V4%`y{`IWZjOK@)7Dg@39b6|7D-b^et7|KnPqQ5RCTEb%*$kUo76 zZT7}poAA9DCj{h-F~IkSx9My?KOGNW_V~GH>V*LV01z%la^}-b9LJRLU1`jwi`|;@ zuGTP8N`00mgh*i%XIYfR{&Kfa#QJ^9?WUHn(o`6NNOIYbMN#yVSlXtZux=CjihuT< zh>`Jc0^E&A5~hgE->wVdR1(Q=2>C96zsVwuf&ju`#8V3P$75BI^mIgD5OP+C0_aVu zH9lA38=}yn)c12uh0*RiVTjACp(j=$tB(enl%NL#gojSQUTM3b1TaFS0Sm%YL?IR~ zgaLNy1oL%uO_XQO6#}UQQR0}l2vTLp^ol41Re^@)pDVDmlpu*_9Wkf~d{uEKq^Jzk z(GuvAD3I`?LJ>wS;kq5UC$UGlmYVz0=(Nrgzb=VyHX03ArV_kJ00000NkvXXu0mjf DKom&2 diff --git a/TMessagesProj/src/main/assets/emoji/0_314.png b/TMessagesProj/src/main/assets/emoji/0_314.png index 95a4b4cbaebb884af6ac2ac74570c1f3205f440c..4174422432a7da87d89f3597d20c9838e2934f92 100644 GIT binary patch delta 767 zcmV*; z^TkB%x;yT@J;{L<^Tk8zvNG$kF!aYo_{>Sri5T?7MBADq$$k>nk{#{1JMg|h!*vel zt~2`5PW{+ZJK8w;0000JbW%=J0Pvu_f?-Ae6EfEBZLi_Piht3Wa0o{@00073Nkl`-_C!pb3laHbJpxCdR((PJM?Kx3!R zbg>ul!UBmtj(@qQcpK)R5>roc8M~&Yuu*oR8NaDSh_dES;zgb4QmpR;7I~t&gw{zX zUet-IEno}>L@#2DIb75DAPj99dW0B%w{jzHMhVw?bz`T-D7HV?tB5h?f~_=zI}IiN zVGvhTZ(oKvdDB26yp8^2fnN$ENBm~&ifV}P-8j#K{(mCJ93Srv#_J28ZRiH$^@YZW zLv048Ft>qT%UICBc|e(c;%`qk*tjxwB;vO7A2{fP;hs0BH z3_XGoQ%jNM$|5!!-ydq@s%H>tzRTpUO8&0s5d;DT%H>qOo$12;>sm1m1)=CqqirS- z#$*ugnt#4m7D8NGmAoAnMjH`{CS=JGh9zJh&Y)0zK!JCxxVKaH7=|`E&lnh(EHBs^8`K&al@=CZEiuA5JjWXw z&mJD!DJt1FIfD}vo)#9a78cGhGtV0v)GRK@7Z8rCEws1_EZ78b%FA+i+}y(%rS z6&1M^6}=V~xFaOpGd05}D9kP|zak^YLPxwMC%+aJ+eS;=MSn`xPE*xTRLUw|Z!$BVb)(NXq$)R-x0@vY{7 zSfG&0_?YvESASN9000HFNkl^g@uz%F3!@{)PApPT)BC|6!w(Te|Cj6QZ95`oz`?;5=!e{^`GEKQ0^G5F^9^+~d2a4KrE~WXuDNZk1 zg^?RuX1g_yhublguA*2|f@l4F*7dMwKhuBu5R@}}1cGLC;&H=dhH^NthQG7|UaE!~ z@TBnPoqtts_s7Gz7>)r(6mgC`P3F9y@PtGY1Wioc)sqsy&(i!P3bY4Qz#TMrVY>;j zVtND*N@goUGT7>RQcy4Kc?RVReR=ZnK^qx#E(#Ll5R7-bG`{Qx{#`}AvgWH0Zd8M@ zDViqt-i^eTs#!^gNxX4m?ABi;q~>Q`0EW9k3x64pEUQjAP(xAO^#hhPQ3NNc5&IO$ z%qO|HP!kH@Fs#J52uQ*hcaksS%&Uf~8h~MV?$=j#dp;eGx7mmygUWEMQZ^%9LqUfD zyjYbQdFN@dj9Bh`I6lU4)U%mHoD`Hd4<{}%#*EfPRq-2xD1wN3u}TrgouTVv4`Zj! z_)bP!P(eJjlki1Wye zrtcp|=hZ+nEf?|l&9Qo?KxTa)=xuH6KYyY4c;rRi_pjHNS8nqpb~h2Y0N5jDf}CWQ zmyb@_L+EBH5@=Q5_Q&Jv(Ww?su!clRv3fHonUDpSurNl5tw?xtP6g---0_}V^r?u=?ysi& z-BH^lPDJDH>6$Ht*19TZD1ZTG$|~!?0~4Ru@A9ial#;?J?~ogvxT%zJzBRM4BfV`! z-rXgb&g5G7?*pL7;f#2_mqYS8Tz|Q|q{y?gZs{*wqHTaiF20s32+HjY{cb779_+$3 zjVnKsij%W}>|w|f)i5k45gdEF_<<)dSy*(P>p`gySB&v<2xpF;P6Ah~cxhTJ3qFq_{ls@jXX^mm{fx$;}>t;iY*)qUYDR?Oshf>u*AoR8aXM}}wbwIf zb<<#R6N;K!0YisvJ6c+E^P%X~uw1JWtzvC5r>4CKP(>jmU7y#a_SdlaYTQu{))Zzh zNKw^bPf(OO9$_lmLNmITuqL$l7MreM(DWEuua(S zfnectpHNs=5J0gbV#Y?SL~x}}Ch#KVSitKmYoD$nnfV#eQsQ@-sS;>o$?^n?ba||n zi+Z)TLYrlN0WwPWwOJN-G=~X2?X(>$`3XwQyk@ye&skZIheg7VC% z)R%G2j%W4KvGUEU_SCcb+Pe1Au-&GB*P3(f!k*)>i|4qL{o=&_=gl+0`>Fr{01$Li zPE!D0twb{9i~ju-cglFXpwmJXpTGbB0xL;GK~#8NrPs@{tA8L61yDs0P?I!I{r@k$ zy`emhn>qtJyDEcBR&5#zb^0rQ*|u%*lRVqQ2F_!V0{#hrh|cg77I|hS=xlk2jJYrY z;ku;8UO_;BLEE^XW6gm;bR&$GlX2@ zcnQDP`<018F42r13(TPtm}GRbU@r<2cZrzBg=tPDw-SV9NQ6nnMsTnh62Y5(0aJjm zijJjg1b+j$7A1Ryb+Lkgu#1H0z=f3o;6R9?+6DfJ;0*`{61Gzm?U*PmxMLD#WrCB^ zDiyS00)q0Nme~D=C9oOt5+M3!$V;HbI*FrNiLZ-J{3tDP5et5I{bVj5&9da2gWbfl zOeyu7SNgepv{9D+)%{vz+mTACHD`+=cGKRA&NwzwYE$atwGBUtjdNyKYB#7;Vy)w2 l)$@$@ULQ)SmH+$=`~$TnMgqoHI3xf7002ovPDHLkV1litTKE6} delta 1153 zcmV-{1b+M11(perB!AmbOjJcja7>mwNr^yDsXSAUJV}s7POLsqhD}eHJV~xQQK&ml zuRKtCHb1O9Qqe(Fc_}e+A0~e+I)^Je)k9dCG)Cn^WOWfAw?bUSHBy5ZDY!68YcM;k zD@2kXG}vEz-920WReqwLpI0R=_IH==a***!Z2f+ppe8-bP=9ObZHv)YbL41+VH6#E zEbrT5-(L7tFtgExCtZ`OZiD78}Xp#So zui#d6|6Ygz005s&VgHo3#=*i)MMwXJsQ>={@agK%W)8;y000$qQchCG+Xq6%a7w;##dz(e)>hu2(9x{SODV{4v42##J!*uWR8 z_w+amLv;cC@W_$c<*-JBAA7UM-TeOk;di#>uYU(BkFgi>57|^*CwBtM;cIBBY zj^o)3ix!J)#*mvZ)4<_oHmN~W1bV~> z+=TP~pFRCt*0R3Xjk-yYx)sDJyxt6_2jL{VO=NWfJOzw!UZz#> zrJ@>QJpqj)oR44>#>LFfc8n2;~dHVw_OEX&ahY~cUdM<4wI$G#d{Q>}c9Q@A01b3fPE!EO>qc!doc{h3 z$atYz*|4<$00IX|L_t(|UZvK{a>F1D1yJ5Xwk5#!|9@+Fgnv%jOcu!6Wpn0A!U6TI z(C+(gQHcxp4WJa*tXMcw6>44OK&g#afCR#QTBDgGrfpf)qwSx zx<-sXhOyxzLe@%nBL)I~oro|-F>@TNjbx4qIx&r67m1tcFLAC;)Zdw6Du0Z{iK5OQ zG0w#pA!qtOjepCobz)vI-i<>o#`svuSyp3wwsIb;d(AuyaSYUX8kaPN|24`bJ)+)x z8i#tEW5ZP={5P&$Ef$75GY>=ZvCZ9PrfvuZ+6$d|H?C__>*dTnjjN_8R&I=|t@OPL z=5gPd#{F0dc!?1z!SQuVmt8`jZbm92hwPU2=C_ps(SM2v%|xS|6GPRL`xCW!w{@dEVwQZ+YU%?Fs4XkAGJX# zB}n^|S&kkCGAqlxwrngGm%)>IfVjQ9xvFRhg#5ZCjlQ26Nv=>!3}GLzP+| mt9Q<0E$@O3uKxHA`~Z*AI2tEzpi%$;002ovP6b4+LSTXw>MipC delta 982 zcmV;{11bEZ1?&fqB!4_mOjJcja7@+6w9C4q-`2&wrG>txh`ptT;n~Z|xSzYBf#>1W z(Z#aX%(~ms!|mwZ^X}yL^yh(-KqX9{n~6! zxBvhHRY^oaRCwC0m5FkrKnz5K8DO|Q=Kue7b<&;)7wfHU5`U*Ek{&J1;h+DjoST-_ zl9w~ygZ!Gc`Auk7B1oJc z&14RV!Se1MVkd1)co<=?wCSfkqUZj6(r;um3%yJLl%Y96QVy}j282AXOxR99&3U4_ zW-PgGLkM3;CVvhS10(h?5&JfrHk$8EU>e`|0m+&_Fib;yJ&aj9Nef);{QOnDx>%Bq z;zVFI@5=c@5IT(htr5o9V~Mp8B{8DaY0hLr5U3YiR2Aj3wmg7{C*-;wA`?Iy^9RJ{ zXAC+ia<2ekHdr{FwSYpLMlma*FKh!0d`1X$}c_#E-0p&713pl7~*Yrestk?1|y6B#$i!r*jG^88HDh|EQo~F zA{~g{AmmaJM2DDc8b_@6h`|u4+W#D7{va1l6UzPjgb~(=PXc>)w&?m9G4jMP&c3#2 zlYg?yJ6$63s1ws1>jM_qBQDN-jp%gYgitOK6jVY92si87XVy_fzD19)An2D4iQQ{h z(&}5&qCU+yPfla;A?u?>4aTEhn-QMyH8=_+J+?Jj6sfg!Qi!xkxzRe&e&f#lu#ISSQKI~VNAiHMq-OGQFMtQ z#t8T=qs!4?#lB};^xK1Qr`&sHWOp|NB=_mVzpp0w2MVB>-kM~AZU6uP07*qoM6N<$ Eg4Z|6zW@LL diff --git a/TMessagesProj/src/main/assets/emoji/0_317.png b/TMessagesProj/src/main/assets/emoji/0_317.png index a7b154e2ddaf6bc15fc5f8bfd142e19a27e17988..a336175b2d59edd6416301b1589fae1de8fa3702 100644 GIT binary patch delta 667 zcmV;M0%ZNZ3bO@}B!5LvOjJcja7=MXG;>Ndwt`@CNi=jyHE>8Yh+IRAUPf?7Gr5Lh zwu51bSwg07Rghgry^LnUl54nwVV!1Auy|XARzQ1CI>woDArrf*0000EbW%=J0NS>i zd|s6~75T_$*Z$%>o09+l0uM<MX{2-^SBmfbZKM<}XtYxK zPDn8w0*Lm07^B8a%nmWsTuX?FkqFgrY}B|2?3T7`DSvF_Y9T_lQr5K)YXJzSU-Rpc zlf%pHS5RRsVFERf-WOgh%nYHBa{Ifn9z5J)2y%ZChCWJ^*3WIh$)`jP)b<6T+alH= z5J4zf#M%r*aFPjdJ2|#bA}_&UPuNA|S_{1(L1?}eM};9+0Yxzp0+9p-CmWR!0*=)4 z<|1N23x6AjaqNk8ipDq(-D_B^c{vDzr5$A{m6zZ6eZKtFH}DPRBq002ovPDHLkV1oF? BG6w(v delta 1323 zcmV+`1=RYp1-=T9B!7@lOjJcja7+~x6cG>*7ZerQbcPrc6eJoPe@s-@cZn4e63$|F z92FMRWqRCkh31Bs(PMa&Kv30ZdyF?o!Bc77W_jXle-RK6>3WRqf|KTQh0$4V?~0o8 zlA+gMbIem{vq4ppF+!<3PrOE3z)WDDHc7@!VudO@X&@|jB!4qn8zlCnvG=aINE93N zo2fMp6Cw%@7Jpbi0000KbW%=J0BYficf>CjI-{dd>$;)Le%r$9!7;jz000C@Nkl>)6NV5I@Z?`w8y9cwZCI8z!R8gwZ^vAiEFsuJe{NT?3 zI39Wap9niISbzE6diQm~Ng{eqoUaO-B-!CG>m-T3G>ji5i6>=}WbFi>A7Y(g2~6N6 z5O4Q6WJjkW;e6l_`TZt=LqM|j&0aa{=y$3F{)S#t#xRCf9RCsHI}sF+I5+Q(QP$qZ z+4+7D7z_UPcg`mA)``hRfTgjNyeQgWqR7){?+UWgpMO@8pUK_8KR9NUCOZUv=!mmC z`{UyRW}F*h1Lxi$SA1ecuC&g+<0X6nfYA-%!Rhnmaz3B0tgs__CtZhM#S0cfaK4^T z-PCp6=>!g4CK7mj9xnL^D9~uR4F7!T`e7K_wx385=89+O=mm44U|DRkTM*Buu5F5< zna4p89)C*C%jvG0`W~uE(dQ)rLakJ-5mDsj@pLy$Q{Q4!Pyo4}UlznmKi6>_s~Qn7 z7&++3fLjVP>rFV?h>>OV*r9XfEfy!f`|+adQsz7@nq2wCPBO=3bd98Jg=Mi9`%xLLEjO`sl8yO8O z(K5hxjW^OAubE z21N|otaJbx0hm@=j5kD90l|hKxHk*|AAcoy*hd77g7fMo%w(971VhZOMYt(`I$z1C zBy0$S00^3he<8w@_WAn8qi|#zN(n+n1QrFNZiaRY?-6frU{EwdOo<@@QV}r@-)tf{ z<}eBT9|$TUWn`}u?jVGM7Q-P}+55C=P_!XIjRdG!Wk`(kc4f!KZ()gqjmS>mQGam> z6p+aAn=0Eh%ZTGNlNyZBLg*}&0E0@0Xe3%uuW z6De<>#|pKc;(o$I-3S5-#QM(iU94!D<`AwPByjiiyU)M+9J(pwALoms8>}8DBt&i> zD8&j=*K%7rXy9>^11JsN2u*Ol;<#Oo@VLqoC<|kM*oMLCQwc(M`*b+&AtcAc)(yke hml6aaC0PA0@;6KODhXiemfHXT002ovPDHLkV1jS4RV)Ai diff --git a/TMessagesProj/src/main/assets/emoji/0_318.png b/TMessagesProj/src/main/assets/emoji/0_318.png index 681373d181d92327d338a85735e5219e350f1f47..080e446e49e81171c3da14ff09715ac6d513b8bb 100644 GIT binary patch delta 598 zcmV-c0;&DU2JZxrB!4+jOjJcja77@S25nl zxMZXeeuM-lKy@^)XfsoRjD7YZ6omQzL z2jY1mh+q|1a*L!c;30(2{5AwGkQ1UhQfTSD3gKaa_TGn8Z$oH?1ur2=B3NM8k5z#Q zc~{(jk58NpeyVEiU*5PeeyZjd>mY0$GKtnmtC%-pMp8%(<~k0ueiiTg?zA3@X+5ov kmAofzMP6%dy{FH>7cFfxE`n630ssI207*qoM6N<$g2s3QBme*a delta 818 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 JPDHLkV1j{;r}_W@ delta 1556 zcmV+v2J89Z5~K`}BYyz2P)t-sM{rE+g96BD2F7X##d{{kZ4SSZwyxptV!2UP(xO)Hq1rA9>K~#8Nw9#pgn=lZ7;f;hGY%L@o z$G5q2@7?qN|9`K}7*rAxw!5wR_){SBYLM^#+4AoHTav#GqzU69TcJ#FmZYDaXCi-* zO6_|}zT|>^rjqddp&x&WVnsdVBKc@Qk_E_JXPrG0rqiUuVscDY0aNAF{# z*6pl%m`9t*8XT7}p46k34vob#Dr17y5Mv?5B~FGK=K1yY*_8E+GQN+0G)Jh;E`=@d zJ2uArczpY|-EO}=nzF1fIu!j?i~aRBibGKV-+w?zo6SCugqV%QQ#%iY0&xLjKCOP|~f25TD}S16SuiPQPG_s{y}$jv|-P21p!ojP17i>X4U$1%s3 zN;E;@nE9uD8$BkOjTT1Hb@k-e6L12I3ZThLcRw!JiZF?5gMBm( zS*OYK*`VN>h&addwz7>yA8Vv3tq~;w3fu`lhrcJT4H^MiFeLMv;66}rO}P6JHZ(gw zjTXi#rByc(gwVvYji-UE5vz<5UceZ>iIDw;Mo+^bKMA=qTIcOG2$#JF7JoMd+mU)> z(aLCZsSE^Vosgy^{GZi&6c|8wsoS)RPSQ zxie2-A$(;3fzmJ66W|b>B7X?$?4u0B5TUY6N`Nh75nd+#DZ7}B5FtYd2Xi987UJF4 zFIJI5oPxvU?0^U_R$phE0D%IA(Ah1=dH~7xU%p{)_wfY^7@rL5FL40A&dcjAiK7dW zF*u3hWcT_zFWkxD5XXl@!WVAJzw;l37nlG2zYPD~{to@+l&;mA!3|sh00001 zMo@rcXQHB}tN;p?mX|X#Glz$Ve0+R?fq{gBgvZ3ir>3ZKa&m2LZB=J>cNrwu+I#RA9Mnc8_Lkjg5__ae9o8l%5C= zj80X=o1a@MEq}t(2Y&zn05fz_PE!E>H~ak#{Qd<`6wO)Zg&sY&#;-6@+G?93Z@>PQ zj-UI>@5#hymZ|1*@63Ov&EAjg{*J)RCIA2fA4x<(RCwB@m&bOaKoCViLV$9zEGt=( zJgLHZ=!*(`yW5Cv%?^XPfrEMX8gsRp7LwrwX2nVxK%rDo)> z90wpVgMTG9DpG3QIUq2inUsJHiZ~mcb7uk!@BvXEiP4oXQ6>QKd@HUfp^aR6MjH^5 z*oPS(bSBrN^tzp#7&B;#!Dt16DBOV$kPT6Y!HSpx*12{P1Vka!F!B;YnRCa9vuH99 z=s?0T?3m$MGSswK#WAkz*oJRe1~qE9F$_MEzJFLGjO&Ta;z5>~s|L_jEaTdVXbJ9=w>2ptKjigqGoGw5kI zJ`tdlSPhsD+rj@3Y9CznzymY`s|RJl=>*>lQ1y)mriX8aF6qw#uGeGpIfp!#gO?$X zg7M{t`i4Z@>^2*7uk>!*KyBenJWcz@@9*RMa8!}+S7th$_St50JgmOpInQBoOn;}V zwFts+vz~u(wKq&n(ch=bh;yz4`(Qa=t=GHd(|aaeDPC55HJ`7*K)B!R`iH{^emAM6 z?wb(H<#N4VaxQlL{%ACU;ye}7+>ZT^7zxF44TeDdmt3kp?TuLDdaOpVSbTkby~zKY a@EfzNr;!6b9iRXJ002ovPDHLkU;%=G5+5S~ delta 680 zcmV;Z0$2T<3BU!AB!47OOjJcja7@XKW6F?c%aUo%mTl3SbJ3i0*QS5luZZ5Zkjs*3 zgi0eEVYRFP000YgQchCmUq6UqX-s z{r~@+1j8}u#xQR+>glezk!9ng|Ne%KNB?pCnXU{XU+Mf6=6^_;Dn<9F6y>xJxdG)R zZbFWWDqm9GVVv0klX&hC0!BnAT@p!6yv16M;X%ZsT0!kGE*apt7Q6*GL}{fA`?YGj zyNRgi3@q5l6QLnWgA9hQRTG#9mMfs1##$1z7}PYfg_hDda=RCx%)} zQh>0ZTZ|kKYC`U^?@$45p_}l2#Ci}F6T#n4R&_myidtU;oV$oy zEc+%LQCKU=tSu8q?q~b=CJq$SZW69!83ZN*L~J5Xvnv?P9R%~SiQpR`D`O9#FM^k` zb5dPS*cmM<_7Fcz)B!ZYwo)C>b!1C&Uq`BKVIc(nlLN?^((`ZqFX#uwTr?q>D@x@6 O0000(XJ4UvMiwOz|XXM>{=0 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 B)Pev2 delta 1434 zcmV;L1!el_2doQ_B!7)iOjJcja7@XI7HDN*)t4G;Yiep|W6O61e}8{lTwH)>P}+_O zetv#^fQ5r;K5uYx)rSXYXlm4i2F!N{(0&Hdfd_(whpc!T|J7Ch%|idtP5#F>`oS>d zo)7S^8sC))>!=m2l&o5QGtu0C5PgvHQMsaeChW@iwaghhx|BNE0!e9RKu1R#rCAO#Y?{XgZx1 z#UBEuyWKj^*MI9Zeb#T&@qiqUuQpM6zAESQ)mt$Ruv+Jv_axQMIh`i$$6_%GQmj{b zzDZ1woD0smltG_97TIyWnhvzETJJUqo)?Uzh@LgP~rigDe4D=@qdsEV&rQOqJ>(>V4O2varR`K z7TIqZ(|q?HcmybC8w)j7`v?KU{K|;2{@KLFa0Y_ZO`~DKd!ucmgCK^GX;x-gHh=pe z3DiLf5R?VM1f`^u%EONr(S~o!V~K)Hf0*OlkqJ%&=ZU~ML3Cpx12&GwvOLc7Uc{#J zFd=j#1b+nv7ea8<^X`NDUq@28Df$raXNBZcV~OxY#CB?{7;LC6i;UhxXUX}BBph;x zgg6Nh#ITxE8Yz;XS^8YOHs?-Y4vQqC^F?KzOt-GGD2vY|op8|py zTxpHMh|mH-jPDCpEW`DDzDn(o0q25V5Q~BhRew_$<(yP5zV$I%Dh@_!U63)yuM)u; zRxz2}5y!=}4I#ewEBQ*P3BirUPOy@BR91YC2%LeDcI}O- zVFFySr-Zi(2>n2mKOriS-ny=_jipeYkXk6~Yap;yQnu^ah!j9nEKSaxb=q2MJ{e5v zh=0f)h|TxC@Pw%GzBXOwj045RVd|Kt`HJ{H&x4a3ixc=#={fPi8;71fd~oM#Y~+qO z_8?xYA_SLGRO;GU??W&ej4y~JB5>S`?~hpwqn5#Yg@UAxR%@(QA|i~dsGawQ_Z^Z0 z(qpwWT5FeH&ng(>>Gy`mV`5CjLVG{$C4Y_4GYM>P*W9`@UPh{W9O~}ES2(HJU45s$ zSbEqH4g{#Z>7d|5TQ4F)Rj369fs1_7r@e*^=1+JYF1nLN8s1rRN61R1i;~9Zor40U zG~}skKR((HMR&#+r(+o0i#l|RtSn1ZvtO?^z(&$ufH<|M6CsRtu*Rfk!nX_Luzvxe zU&Yoaq;b1kE-fkb$P)<0ghCV!cb z2zSqd2gbtoVPJp_R$bxZ1O%DTfuc|-*M2fc2c#h?1p*-urgfa65Vh1V!w@gD6u2M) zilLiWPA+Q^mXm>^rPPFIFEz+Xk|atD6uNllpZy;t)8ujm2Bmq^cGbg;@+o>>~m;d|gEX z#HbXb5JFQ9q9PH4Ow2|h1XI`rukN~=I7~)pE2&GIJw1#!Q7q--;{17gW`7d38ljoy z|GLGqQ6`{Q2gDZu2nwATqrLm;f(X)VCu0$m#b*wJdyFv-p()P#a|#~pxG|80Re~5b zyL$-wFd3;?Vk8)(2cejZ)#39_5wGyu@dR8FoPYiYFgAJ^&)8bJTLf?P5=s7%iq~yI or+vAnZT=}__5u}?|4IJM;BO#lD@ diff --git a/TMessagesProj/src/main/assets/emoji/0_325.png b/TMessagesProj/src/main/assets/emoji/0_325.png index daee7a36f310668558860a1a107c3be63c7735b1..06f1d622c65a0d4736a1adf86db17b22c470b6d9 100644 GIT binary patch delta 1319 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 IM6N<$f9V7c8c7Ds0Tb)2*;W=X?{r4uBT0AXg z+5V;wrr{!1OC*(Q+Jm4p1`$sYjls!~UMU2tTkua8!BD^sNjXZ!&_ys%cnq!D*gdxq z2#J^iBZ^$8Mt_*#AWQ)PrY6Ir)kcB_1;B0OPz-h(S4o;EUIv0D0jmNZLSf@7Nl(Ni zxDo-WxDDgI(hni_Rv3N^E@H08u8XmeCPFmd8W!+Nc?ka4D+u+G$OMZr$v_+xgb_wN z8@eFs2rVHn7rr6BrnZuh6%e_lm`@CvqrPi^5NvpPv~Y9wA!>=BI9vixiLlv_%d^#4b-EpIif%9ifjXKa zD#w%D#((?g%?bmdm|D$-lx&>i=jSatC4pc+6|0(sYS?6q2|#-tp+Hos33YPD8#W}u zP`WT&i-NWhjs1KWK>{J>rLf||y}<^`!3xGgAV=}pJ{-Xx0^lph_A03{81&&J#Dh#V zbJT5&wBG)=eLb=^+WRGWcw6CXWVy5@Me{@I;3m8rVpZg*)%K_bMleS3c| zuh&1#YNT$CO@DE5;6oU~FoX~o+tQF~WrgD|zc>!VLxRV*_p;P+)(K6q2Lm4Cc`VEF zaNX6v3%hgS_!+PwYQ!S-uR>lpufXd@*EC;(XVQQVv%zh7_|>So^FBSoC@BaD3Gimd z?yn_w7cjx26C?lzPzpKq8V`qqp6Pj6sJn|ZfyFr_W`D0?CJ{)Zyd7e6KbGfcDH2|+ zLj*zyo&jfLJY1E~MO`E=t$h?tuo5apWH#XKaJ{N>te1#(j07hk8o>q&YH%cctAsY` z7F$dsDnTk3kZPDAXqZl7#!`#ijbj)B3fSY8@M(Awc${SEFiwP{Qv%t~35ggOV~yaA zP~=$sB!ASsM{30*u@7IFcNK)~FcMLoe0Nwd zJYw1m%Oat*DHb6D8|JYFU?e3GhkBV9K*n}*f@sPEA*>LtAqJLdbP_}C?*=1063x#9 zr$rK75Fr#nxEuaEam;>7&px##H3&!*`Z7Gx1AkHee4Yha?|1;91~332ax#Juw&BZf zHOEiFt3)~q0I(T%!p}rkXA6fB4bK36aH9|bGYI;bxNqm;&2<7J05uLrX3(HO_#)!H zWj96~V__1n1i5K))7Vmog(%es1a<@4{h8KcaT1y)QQ|fUYhn!}fQNuu;$W|IDTUR5 zX@8nNZtXPP1e735gxAw7qhWI_)`+LUD!jknl$Z!WiO)+Jf}W-lnkHLLj_ilvZXfR- zx0pnDBZk3_qCB3nzohOzYur9Q3E?}zL!e{VHNXAe$%V~OA|j6GL4wxv`#M{Zp5lqJ z0ZOPq2u5g;J^^cL45Bp>f%coKaDZYJk$+Z{<`#rvFNDM3vC1~oKqDqm!Im?`>H2JC zdbksa&c+y24OFZpa*TutA}Y*xh?i^@DMGrkzjEczLhv-8*)m!^m>VUA9;r7 zcq+D(sPJDz;7uj6{F&Ia6PALW2@ietI+4bxHWC<~1RY~ra`8_>k!?)n;BJJ#bjmj8 zL>y+oGoI@0M7_5^uLgjausKza1k4P8`#gIsbVNzSGt~z6&c2JSK8MsM z{USVsOpCCG+{qKh+#GNf=C_29%xOZHm!T66Q!apJD|ai7Mb*NEjnaYi>rDvb$l!T?J6GHm3R zyE@GHATVSIqJJ0; zwh6`vM7=?XWlx?MMfdaYomX*4^>f!#B+Mr6lL(UNxvXSUG_4npp^ng0H7h5-P&_ zFDfhrB?z=#D6d5kL*YTge1Sj!!bBR;MG0?BOwFI|kaskX@Y_E&5vur2uq5&b`Hd)U zBA@0(F_`ZWlr}v?$bW<=Bah&f04L;C3$KI-B04`>VS|qev6;{TQk3w9;af7={Pt_T n>gHbTJNYeSu2sL*|A77hF>x?+*GeDO00000NkvXXu0mjf)PzJ8 delta 1130 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 DdweO1 delta 954 zcmV;r14aC`1<(hOB!5UyOjJcja7Cm=B+9XTr|W@cqhMnF|5OWB;eIb#4Gy304w1|NG zb<3*oi$!T?YoB#q=*CvZpdbQi01i+Cex7GL|G4}dqhT-64y2chC>aDhOMb@uod75~=Z=a|hcpCJ3<$itIJuXRT4WBcU_ID?mc{?+{ot$TGwz>m$M$A_mDEM+PJA zb4!-+o;`&_Lnk3b!n!Qs8Kg(@&44K$iR7ot5&Bbvz}q~(5bhU3Ch-U?4AIvz5@Gwy ziNxxGCx4b6vXxK5C!#te+VlrzVg|s>yYbngJe;Hf?X5lI%fJV5e5wO0A@fKBfCQnV z7NaYU_X*krfIR!npxpr8ZfBi)NR$At37$Xz_V z0s}9CAhTEz($&mwBZMV{cY=h7+qAYy9rD{CF&07I2(h^u$FYv9%-47su?2w>LBIkL|@w!0Bj&=A~N!f6W)lHkz_aB>nM#E=Rp#6xj94LosLLn2Iffsn^Uf&}O? zuMsi_`;QXtB0(&|-4aC`Z^Hc&oe|a31T$_#xNfuzfB>)=ihJoAvpuS&amDR)^)L)| cSNx;=2RDs}u>TBn_5c6?07*qoM6N<$f|!P-=l}o! diff --git a/TMessagesProj/src/main/assets/emoji/0_33.png b/TMessagesProj/src/main/assets/emoji/0_33.png index e74681c4db4139ead6508955f5afa5f0172bcfe4..b2442e5e3566b5f80d404fbf1ce3f0df91bd42da 100644 GIT binary patch delta 3430 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 IM6N<$g0e2gHUIzs delta 1515 zcmVWvrMfd|xc17|M+d_)I~R0^403Av0S;HM&^Z4=Iq8o+J~ z|K(@@tOoz}W&ixX|N5)^+E4%Xi2auY|M{5z^>_dM(*N{S|9`&={;?VV-Z1*A6zP=> z|Irfv%{Tw-L;uVxqMKL5lw|NiCwzb)SjMuh+X018RKM00iktL_t(|UbNBqZk#X>z~PmG$s(f_4=}zD z*!#-a_kXa?;D3!%pi7fh{rCrD%};~8_-D(-|Fk9a@}@=&FIiE2d!F(7vhKQl z(ycEwXWyw5WxY+~n_ge(wly!l8sLwD0?*QF6_L_b9yb^fk6(&Z<%$B&LC5!BL}ibC zq^$n9LQR3Ar}^AS?@5u)${2VLAp2F#VNc z<-`H70DplDLU}fU0LTb;E(VDQC)Nf?02%I+_(1O}Tr*zcEhRuEL5@ZfkU)$%jMgZf zTN~0sE9bSc1w*dRJuI>cm-u0NuTM{}rbUvTtp7ymyf?fQc6Q=tE%w^lIu3*Zc%7Tm zKsGp%EMGo_emK}MifuWv@&Er}J2R4Yy2Y@kuz&lel(w=SW=6C{Sq%JCD*;g&kgYsu zUFOvS!qR*WM;<2hu^3YTAeE9rl&@c}?*RO$jO(f}28hoj3gJh6HPyZ-2zIu~bD-$2 zalB_8bVAcu7PGjiR7$_y*BECoZiXcippP!Q9|LjNWkZT(KppGSFUCFQ`2~BNVZkE{ zE|~>~iNx*@i1Rh0Ga&0Lq>^p)$xIk*n8A6bW=^}8y9{>GfwPYiN6oPyP5A628b5A@ZgaCsMzGyoE$>BF|*oXbKz9Ykd zZ|m#+@T044a@_$FQ}3>czv`ZUc;QZN7sxHa3-`~q^TTJK|LQ%2|M4A+zW}LJqEXK% RD?0!H002ovPDHLkV1ib4&ba^p diff --git a/TMessagesProj/src/main/assets/emoji/0_330.png b/TMessagesProj/src/main/assets/emoji/0_330.png index db527bd898bf56efcfb2acf56a4dbb7273412fb8..92780475350a543c072affd8898ae24debd6cfea 100644 GIT binary patch delta 613 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 delta 662 zcmV;H0%`rL3$6u_B!4zgOjJcja7^I7m&J)-y?j%^epJYeWY?&G&68>4znRXKZpe*f z-?@_5r+?b5hTO4=)Sq|Xw~*w>p-m&jHvj+t40KXXQvh@~t@)A@{Qhaow%VzG@Bjb; z8%ab#RCr#^)QfKGAPffJmW1nkVekL4$5>F3rpYOE()OcDNPj6`E!W}pr{nI&xIrR( zKPQY5UkBoAkhuK>5e~%dQz8r#_pmp@1d+pcS(>uTcAQW{S16x+A0{Y=l7?iOBziIq z6A`l{sFQKRb)3uAn8#Rh;WjSC{U1jLWK{js0gwh zC9D!P^F%{rH-Ae|L-5lo)IeTFiKN7)3P^5(=mJgJ^?X7S?7y4adWIpLj$|hq(4tHyytx?3T#0s` z9-obj{^Va-bf9w9iuKe!gzYE5rz?UA0hFIZm6nAU1gk+PR6a%teavTs6#}pXpb07$4f@ofJ1BKA|bv3tB zV_8KhVW7Q11necNWHJA{E*33DyWdAs1v$OgXx_QBtRM`C?H1P-3t-Lrm$)gFwA)8p w=(YZ#7@JyOv;oNqFdCDY5)KL07*qoM6N<$f{(m53IG5A diff --git a/TMessagesProj/src/main/assets/emoji/0_333.png b/TMessagesProj/src/main/assets/emoji/0_333.png index 793961ef4cbd96a7a9f599cb1e29590cfc816ff5..1180366a7cf40b2c379400f1ff3d42a8d5cf312a 100644 GIT binary patch delta 1195 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 Su>-~c0000Lw7(^)nhg5dgZ$ zu+cjcN(autV4RQknFMDtfN#O6Gdw=!j2Rb!U9$AlXrLW_wB-z2h zC2U|j*Z6uJ7g3K5V%6k^Fd?-SHy%lw*$5?cKV#2aZ#JHPQtp!Y>0=l|vT Y1F7FkOjID_hyVZp07*qoM6N<$f)d~y;Q#;t diff --git a/TMessagesProj/src/main/assets/emoji/0_335.png b/TMessagesProj/src/main/assets/emoji/0_335.png index d15057c4bf7555fac985b02060d4281fa18e4a35..c1d6e4bef06ea54f0bb8e71c88551cf52a23032b 100644 GIT binary patch delta 1130 zcmV-w1eN=d1pf$-B!68{OjJcja7=t*R)%U`hhkA~Y-@dDSC3^-rEgVrb#;Dzer{`O zp=wcYU{{V^M_5)>fPjF3f`WloLa}>Yt8`eNYfrU+V7iE8xP)T7i)Ox!W{+StpM7O} zQZQv>Vn{6%s)fQU0000IbW%=J01;ud{U-eW{{E8LJ%s$Xjep+JlpAvZ00X~CL_t(| zUbWWilA~;{f6VO;47j_)C|2#M8h?Isx)YJj|4dcwN~-ETV0Wyq zZF}`UOTAkQRL9oSl(g+-|M79DS9LkImuuU61|SP?_&lHQtB~q?X-}U4qoyGmDHyW< zxEx=saJkk^kbg90M!dK}R5$kJ;e! z-Hc~F+UqPtK~J2GaJM`$j&1!p3PMoAKr*6=_hMXsF45r7fS3tUM3798(SZAQd*6Q4 z%fha0${0C<3ld8NfpM%Bw)^dN|FQdFj!!C$CqX??Xn!;mw)_3wjCPS|0y;rO7>JY} z4K%{jR7=F6$82LTxZuQi$yI3BM+{cMh{YB=?#T!mJ9zZV04f?7;l|Q7YVKKc0zipl zbTlFkHE<-B4y7UJIVsRAI58Lmj!7`Wk@njj)gf}%`+qewLBBgour3OZFWG)g3(?g5qTcQzlA(e$N37SHa zp@ffvoWGsqH2zOb8O=a(WHJ=#@kG8q)fx(+8hG($xsCL<6< zA_B#cz?@ll9B{pMYG(YY{Rb?cDLKD5G*ngF(+!; zwmtePf2<*+(HU|JGa;Jv@X|Y1<290$8m6Ei6+$H$F%@`TBhw=xWsa2aWWcL6G7h^4 zhy=qbG%LOOvIS0n9jXzGG+a)#4|zJr{D0Vpnz_tzBjWLTn__dkn3{|LKayJj7e*q& z?p0#vlaK+oz>GQyMl=SzI!RO|U;{|f6s3Cea!y778v>f<#6z`)NJdyB&w?*=6_LmU zN^|^juOY0z0F%C5V$sszb751KuvNqv;^N7>%n+Z0d=akVy4rO-^4#9%F%| z*i`Qjb5w>g-X}D|sxjtY=UJfBW@UCk^bf%nu{I4&FU}fez2G$tC{afNPA;rB8bI+N w9qP?{sZIxGU_PAuG~Y#zbzM(Ceg8eb0p(hji3Re--v9sr07*qoM6N<$f_Mu2>Hq)$ delta 503 zcmV zvVf2?;S~tKf;g^2`2ltWGC=lrTS7<&q;(CE)GVyJsC%U>;6)dOBTEQ|G_51LiPyQX zkDL!h#D74NBUT~%{IbbnRN*}O9`f{p{lM)*}0m?$D6lz>RYlZ*rgAUz801xXx!A`rUou|UDl zlOx8Ylw)E3$LW@=N3-trc}t=b9id-b6+I!Punpimm*WWx<+adam}-QBMz z0T{S&ILDy~s4Lt6!LD^Ca3PdubQ7aMyaO@>HIOT&zHm))el)6F|L9cEUQ`r7H=(sT z=TId{mvo{keYK7MbaICPR~T0hKz<*$>A1+0@4{5&{dHi>hZZ$RS1~}_?}vDWKdLH;z{{cSk9hVLEANXNzY`Sv4JXbacFpPUy_al>h($ z4|GyaQvkDzg&N!a{{AvtrDD^+>S+#X000ARNklwl7>Knw+7uEs`Zb8EnP z{}pc6UsE-FbrKqi>Yt|Tx|CAaeF&uUxw+?bPWyr83oYQ1WOGhr{T|_6;-!^nk+IejX%8F2_GOM|9%& zON#*};mo89P>3w3cwMLwW~|+mnrM>DO1DKW1`9w!S!2jcZTNkL@P zi2ziiOMhO1DsPEsVG)1{K`rF-+!$7TATH-sBBC&n5*dO^5urz7{Ca&Zun?KdAVgEh zjbQkhczsJ+k8IDd@(?i>ABtWIJE0e^pgPkyb%Yg`F) z$zEGt<5aDsjol&S@0=$VP!wDU&a6gQ{0UjD;oFc|aGnuGfzU$8g%BM_7s@i%x4{59 z&#Fp~gp^g-B8sqD!wdn7T0nh}Lij4`rfK4P=S_{Pp<$pHK}N9G>r=HMwbyVX1_6u~ zL4R10x)j(_Bcl<7P7smgAQ)Q%Hr5CNF2uJAIhG?zK7!7AJDlE3dIPrCpxFcf zB2X7H=a^$-1_}aToOM~0t- z&`|A3`-9+eFh3`_?DBJhMTcr%29;-l+G=MKAU_FpwL3M*&0rV0{Y2``FoX?2ZC%)J z)Ys2OMCym?vvh3_prC!5s*ls9VHi?Z{ipl|O)h~W-(Vr+00000NkvXXu0mjfAFtI; delta 628 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_339.png b/TMessagesProj/src/main/assets/emoji/0_339.png index 57308268e3b36dad3a36cb2785f7748315137264..aeeaaced9c2cf16b28c4dc209e169be6d3a0cb81 100644 GIT binary patch delta 745 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_34.png b/TMessagesProj/src/main/assets/emoji/0_34.png index 084b172cd03e02bb4c6f5cc6ab9307292e602b02..74b8411c5adeef10a5471a382f1a6542ed1eb8f3 100644 GIT binary patch delta 1560 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 UBY=RO_5c6?07*qoM6N<$f(!J~H2?qr diff --git a/TMessagesProj/src/main/assets/emoji/0_341.png b/TMessagesProj/src/main/assets/emoji/0_341.png index a7069a58d1256f18d33b9fc77903be6c1938c17b..46b2324e69d937899b2c7647910b68e509b773be 100644 GIT binary patch delta 706 zcmV;z0zLh>2HFLXB!5LvOjJcja7>|WQqi1onr2O9KrNPHORIKSnq^I{cUfyiFp*(L zj9x`%K`p$CX0(1^xrSr6gJQgkX0CQx#+7WPZd8X?LD8LY2r?wW0000EbW%=J0H=&@ z&CH1V7yCC;rO5IN9RmOW0yarRK~#8N&DGnMs~`*p;4-3!+J7XR_WM8T4v4hlp;PEw z%SOVXBEQjAfWogTZQIAj5I-N_Rs|gflVu4)p|J9-blS8i^9L^@RNe zg3JR!Lrny7(tmK|kZ&az!8Hwpr!2Hr;Q@1~kr19Z*&rnHLj!>YVGNpx6yz(#i&~=J z2wVyHgrGIHuO=)NqnS8VQF{nH2y7+Po`70nQm`k~R7cF86T=BHSAS)@6@l9COq>uy zYiAY1i?+5PZ0+z#6{4}X3W0>JtJ-a|`HkpWHXK4K0e>qhCNuTs0Rcb1H5=0)`d(Q& z34rQ_7^c_2D7>{0b4GBiwSE|1w?i5WbRI~rWySdOESBJ!on*zUrOf9J5FSI28wLFQ zqN|bfl8CwP^;rR~flQb!naJ{Wmx)Z2|C+~To~uAm7iIJcXd}=(Co4}?$n!;!$^sPv z_X=(Vfq%Uu0u!_m$7}>#6MgU&U~NM($5$c9PpuEjInimAyW3hqb3mv(_4;B(M$KhJ zgn#yBph1M~p%3!%{LxzZsPGS9sUzJH$>wJ&=;?N8NUe1U?06tHvVv<@_&7RfttAVW z8M{SFc7j?Lr-TS>953avym6{cu^2YsY10B0v^!p=_cw7yf=av3wgxINPob=#IqQquTGJ)#{eS-Y7$7fUV1TpumQ<(tWPW zgSXO$!Q671yF+G(W{DfZw{n|2nt-|NpN4|8@TV%zsO<{K)_S0(nV9K~#7F zrIm?xgCG<{5mR?eWC_Op|9^HuCmv4Lr@3q|9_AM5rruKMvOJV!p>~4&;qU_vhf?pc zR3+jyXfUAJeiVK9sT)9GIp~dsB&gR0>YsMA0X?JM<|w)>z5<8*UHUsieOre@`WknJ z%q4u4s(-EM3V-n-zC1=-Hzqaof6UsNUi2PaW7bR}S2U708UMd5dS>DSOj>dkh9Hv{ z^t6(zFz;xN0>#n1Wt-xZtt_OcIGGcA*0KjisK`Ti8Y4di2H=vFrmF-$-fM~ljjROU z)njvdgX9?1bei5frty=)V$-#u->>W+700xn+t)SI*nf}r>6p8d5L8ZmV)WBn!dZR9 zg?9$))MqM>jcGSm%q)Q)l>mnbm^d(_v6LJFoCEe#fFc))ZUR)%zG8}_65+xtMQ}>S zINuWg1D(@6Dk0~HNU&%$u#RUXrE>n72pA*@y;E|ki(iu%bX_X7f$r&|%vP@E$_V%+cK!jY@cQxP2w;g;WTa3d6# fuNr_tRp0UlF%zB#*n?v100000NkvXXu0mjfbw7}+ diff --git a/TMessagesProj/src/main/assets/emoji/0_342.png b/TMessagesProj/src/main/assets/emoji/0_342.png index 70595aa1f5c060dbeff7457528b2dc5040c61bd2..0b7e02c88971283d105dc6dbc822799c624ec49b 100644 GIT binary patch delta 639 zcmV-_0)YLo2ABnqB!4+jOjJcja7?FlOJ_PGnq)m`JtSW?AZk4%b3!P2M=M)1AEaFT?eBSSZNK}|17JGYl)?p$qVzexr zhpSkZ4LJ-NCbAHw=sZKP7%eOO7lKyHV$%!(tnV)s!AYWpCkW(KhD08w2x84@6HO8( ztVYC9A}V2-Cx0aB$ov*T4F!YZkTRYb-#%-O~^N(t6~8_zrn7Ct2axErEp`1ajsdMN8eRV{ Z&mT#PPW7OnsQ delta 794 zcmV+#1Lgdf1+fN@B!5LvOjJcja7>ZJ-H^uLOmLGeOKgg^(|xVVAwFN3&*o!`t1L=v zoXzA#Xp2yFmq%-jM{12tag<(!rdNEPd7{E|o4ah2v}KH~k?S%<0000FbW%=J09u1u z%>2q08#~U%htsXc=GJNe00N9jL_t(|+U=Ixa^oNnLY`9mlc5BHDnp!Dv=Lt1?t|Yv;mBZg#Lymt-wy$vfECKS z7a5DpaO98MF@KmRdinDDpxWa?UEWu>A#gcwgAaUU6Zf=^0KcxCNKr9*6?p?%qZAL6 zq(fg`l#A+14I@Y~ndFe_OGJcut}?JxP015)5fA#=%7`YNr{yW^eu{V~(7>506b%)N z*9acc;%OsOU_crDcpVh@C$L8wWEFrq=zRSdOj=zn9Z#~HE5VL`+PdPZm)_r52- zaF?DeZX8nbf z$u^_(3Y~PIJ-Q^Vu++$vZI&Lj%T!65j%TG`SqsY{NK2csX}YVHn#Xk4>a3-aJWI91 zkdh>1IDhAC8MQ|)rl#0rn*k7nUrW>Jm9BE?W*A3mE=#^I)Mx@j)7rT#(z_x9)6&qT z+F%@EQo-m&5FJOn6UXXCm{P+=m<0-g4=|}4)q8;uVRiqXwSXRctY8&o0RhSecH2TJ z%?0d2a^Mn7p)b*RP~uT=pjnJ_Av^|Dve63;dVdKYTk3!c&hT$lw9ahX-LgSJ(|h!@ z-_v_*FhCzEVmr+6KoQR=NzhZU8Il39IU?Y_6bw{)!8LTcup>KTv2p~uDFk=G8I9eM zBj->A&Oa+<)Ha-zh<}rD-Q{m0HfMeuVSav!?Y~Am|2&`Ykkaf=U(Z@#OA(X&k*4V{ Y^Ap3S1KIj@*#H0l07*qoM6N<$f<#Av)c^nh diff --git a/TMessagesProj/src/main/assets/emoji/0_343.png b/TMessagesProj/src/main/assets/emoji/0_343.png index 378879118556007e85e8f5d347c09b8c8f619ace..ab9c3c418b659c4b575e23ad1ab9db7787a5b7cc 100644 GIT binary patch delta 505 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 P00000NkvXXu0mjf^9deV delta 1684 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 delta 1595 zcmV-B2E_TQ4a^LXB!8JuOjJcja7@ytciG5)wQ@il=t}cJx6Mq1~e^hc*Kr0LYqK$O1 zp^bh}1gLll!?d5png`?7kRnQj0{{R34|GyaQvjO&;QMvwB@af$cEF*`8FnU)000G3 zNklF?jE_kU}M4*(#5rv7gU+wImt2EStjo9zZ6#PEKF7;LPzPrq$tGT!uzr@z4u zQ6oz?#3Ue|e%Q&xn~q}x4<|`Bo+m#5jN#cCJX$eCY&YY<_aHt3sDoY%Pj-_F zG4{Rz38sQG)><&2*dSuN*=1aCKK(LOZ!9<bVQ);DqBRu$L5YG~_>^(#+qUTsA7zqF8YtB<(!g=T|6sV{mNXsA_ z-oIXz%72=0UAX!XRfI(kp*&ztCyyqil7a~2!2vn}t@jb5jlrV{Nqx9BdP0&U#BfHC z@qrCbNHWnA8~_*~%jjF-{PAE1fZ*(=4J43=(=z%rrv7~&QgAe(uS`H`54mc^9*PX^ z`VeH|4qpTPLqR^D48_T;Us1L2XPOgu{2ZZFj zA1g`|%O0WtQ7bl24@wCzm=2~inl?<_KswUVU3pSyD235)>YiP zfNWznp5S4`7Qq0)tMb^CWwT#4HI#LVqH299FQ?^lSJp8hghT{ah!CtpFkM#b+kPpc$N@ilze^4_pR8o(X{n%o9}A)#dUAPYWj*5dvpA1b=Y7g3H=yKqx>6q4I#XSSCe&$RQk> zPm?B9RV7gx;qpL)eY;CTxSoWxs(&F(LdeX%XUw3Q5cai7Tew|g5hju9ZV%Cx)&>w+ ze#oTC?NamS8T@_7Z6{qhMqpSPhAC$$@vQ84OGK!wy$PHQvwTFIw2a6hcn(pkgGk*< z?3Msm`C*i2hi<_KvtTyLb7ebm46I^@(E+|Vy68NB3F-rikkD%ZHiWZ541cUL5;{C6 z6J2e0G6C1;54Q&aw4yjNoDEtWX)FZO_V-&8BkSP7hP}a{;I(m!$r!sgOux!7iN!sD zLZw4-jPTs7uGBQ^U1&|vWFFAOqh=#G>6Q_(X1QLjJ1rYgkO?|aYvNHpwc;Yxg<4$` zRx0d+a9MuPO7Ej!yQcNg9DiAuwgd=b_~FfbKnzX{qa%PEF^J=ig#`heham>>HG?2f zX-tZT+Y!{~1Y*GGU)=+zAa@)6r3a_U97ha|5Co+=0GF8Lmmg~U88EVk&lE8NRGyC( z-}$H+%n2f?9VdnWnCiJ};%g%aK?-2N4d(*u52N`EEqoIaEQUY<3^Yh(8P*RM0RVoY tNibW?ha=K(zL*7&;?L##6Q@u8{|Au)1DK7zQ9S?v002ovPDHLkV1n`AVpkfETTjEswhhJ}-plZAzaaB_2feSVsnnuvyj zgm!EA`1se>)XU1rVKD@@wX~#i0&hVG;^N|mXG~Tl0jsO4J0Ay#R|LSnzI074pNe+!H$VEt~fI6MghoB>|*2pV9`jL>~S|YNR*lG< z0%{l@BtIg?GHy$I87SokL=s?h>7K6oDWg#W zh(d@`03ndTj>8u0x?$*q5Wp-5N}0^Z=?0?UybvQ&EDEM>Lx)wNA-$ol%TZ(1tP5^Qqnx0Uo%`o)ua( zj<`QD2_!B-qwaSFUr+GkeqS6pm2T8buqBa=L@o!b@dUTR2)L$}Xd%;yFy0aFj)VTK zlz)1^+x^=r37F}N#u9^nTukR0{9@Zf*w{jk32cSCXz2dg`ZZa2cv+DtPrN3)I?f5a ztmxrY1x8MZsPcl~JLieGYDTOOJXU2oxql35Pb5T6RSkmkH$Gk zBv50YNVAUyrPd!nl0IP^0Sab^NG$OJ6-Rgt<807*qoM6N<$g7vPuvj6}9 delta 1596 zcmV-C2E+N}2h9wSB!8ArOjJcja7?LjSEFrHaY!&|L@uXrR%1UagI7R)Q$BV~HJxWq zSU4nJJ0^@;LSH>7w0~f+dtIw@Sgv+krf*fDYf_3@LX%-hy^LnRk7&4tV{}V2w}WE3 zh-8~)PEs)&_xJTb9th^%(YJ(M$fkzb$+gFpZ7UK5#FJ}mL4Oplnu5f!n~;5OmSY8j zR57-P1<$1ip?y29kVVfcPzV4301tFhPE!Ejwuk1*kFf6yS(paCz(0-e{-kR$igtmz~rms@ee}3uIjd=`0cqCptt{` zaJ3H9dKUhiFn>!wKuW9Gj|rZarpWmCAtRh0KpsGp`gs2lVs$8u4(W&b_*nmhu-KRw zsaKZRk?>#3-~H)?lMF;P_yEN0-|C^9LOmfQBUz--#%A$4z&E!is0=UMxHxzdKYSTL zuhrQg3PVZDl(UKdf|GE{C=wh1NF3UFs1;|7O`gv7eSg9^b@d4dAi0F6qb?~m4Ceox z;0wl$39NU@((+K(GNaruxW9OvkYAN3udGX%6JmS_#;1$F5^M^ncOsN|D$4;&2xg(v zZ~GtxvmORO6h-EeM{y2$9D{$;k5EcsOgIbCpdnC#49Y-X&t(cG9KiwN_(nk^=z~ud zU&cTawto+{e9%C#jIX0CCQ^<}IKr6WvM^Bi=QPlSB{;wy@ys&ZGC&1uBQk9~ctj=Q?nRf7n~AtfQa07SvA2u?^wyQ-<{^LYn| zV-@dRjJ!GTyrZ|Eq`bx3W+13@b|jjf$D><`p6DtA9q!X9|Pi4 zHHZ*W143L8JYxkWq5JBJsCV_{chvyGFkl*x4?o@=E~l#MD4}2i5L~VSF_nxkT}Xr2 zR#j7?jmsxw+Q)X!iJIz&?&{A=Q$Z5K1t0|E0L0s@5R~fz$J(CYyCs~#pTB;?SAPv+ zYY|m?0R8$r!dDJ`JJY zn-wAr0WEAAWHEk4)VzNz}-v9J2BC7Ef3R*JDg<2qSu z!Bn6NyXUm|w(GiW)aC$ih`i1B9e*fpTYRvfSZO9Sw8A7&g-`)pI5Ep4irmHp#U_Yd zdU?{qkKHar0e6Ld_}6td)l#RB1eXbx56URaHR2QuA;oQcTxgYQX-uHPwNh!IOcKi& zAWTWdWFT_8aUua1h*W_WC>6R5W42tP4MdC>JoVDROIbcT-*LY&CYIsDD}Tny*|_>7zUVYU`7%o z*omri_2s)qpzv@VbV9N;mEHc_yr zF)zo2lEp}{F}`~#Sj=rZNPlJ+S?Y|`DY+v+jBgYU41`26(bx!26ML2pgyq|}TF$Ro z9K@936)Zd@I3Lhch79*#aFW2U3GtkOjE#qj)!t~*Z7Ap_JNXGA9Y={9A zD)3gXyr3;N04b!nQf$2e=)i?|Y6Kw~D1ZSDHz$_{2lE+PcoDLi!!V!D diff --git a/TMessagesProj/src/main/assets/emoji/0_347.png b/TMessagesProj/src/main/assets/emoji/0_347.png index eafe3096d62785bab32c561067a1bda653fe60c1..9614a9f0b15b9c3f7fd6c3d02fd51d237aae9a52 100644 GIT binary patch delta 2617 zcmV-93dZ%N3&9kSBYy%eP)t-sM{rE#Zg93hR?bXL-9<*SK2BJU#lAsEnP_~!P*+KM zxXMLM(OY7kGfvA!NOnwaEmDoTJ3`G)RNhZekR&pZCo#c5NkeC&FinR;bhO=5Rkb}& zAw+=WNJ!gKPH?Q+vM(;WMOD2;P%~VcDol&8GB>9tDy}j(j(;dPQ-r!MQk5@Gf+I(T zXrIvPR$5Sgvn)7bZcJ> zQs`N7xGFTkLVsKQkC?wTL8vA*>3MwBOiG0!IR2EK^kRCY7%QkYQ2c6pk0LbLSX%X7 zWx`8S?tg;WPiN6fW4Jj+&P7MMGd9RQKE6Op{B42rS6cRoki;}J%u-puCM4l$YM?Yk zxE(IwbbGcWAJ}VhnjbLNWNM36bK+rPh$%qCLPY05K7YzaU)xbqg*Q&xUtw`DOjTl) zb6bOwLs|2Limw+cXQ9`6%Qj+cN(Wn(f>KWeE}L~nN>G?s0VksKpccCS;5 z&gO!Rqkl{{0&M{wW6!{$Kw7H~tlOOpTLOjW51_$?E** zaQ^emu}0BB+{1LIiD#Iev)18lFt}YF5;l}klmDe#wf1Jf4Ra8_HZ>w#K zkN>4!ZY~8-ee2HL+*}Rw0*YwpR?p1*@cs8cC}wQSs>stvB}Llwm)XhD$yw&tXctH` z*0ob3?SAIuz*ijg9{RlFc8e>jAdp4QdfRRwM78m?4+kk%W?FhF1 z3MhNGh>O|jv9T@;F&d8B)M{IN+%=!Mda>`;>H3lN%F4OQ>AQu~Xu8^U_2!M67~*7+ zWwULdCUz&+!NC=DeND~I&h+$jM}M(?^fkd?UEOyU2pb&K4Zo&U#i6d+2ZODDzdN`kE2oK);|-Tzu7zZx%h_B|Br}@RDWG|AUy&T z=Jedb`w{h}f=wk3nv6zE0zsrywv;Lb#<**16cBSTFVE|B3aUbZa4km1VBxu_ZtXE7 zXf(E!3bIm>pS-M92^FpfH+FIp0y&e)n5SmU`AM}^=BoYa4b9Hr< z2QRILK_Qd<9J1?i;hp>%Aaqi2K%?sAO0q#K`Hxm465&&mC$;GO|0_Y%YwC#R?hTF3#G&KLqc0tS_xqawcnxom#O=tx z{S?6AA}W!nxA0vehq2HjY(y@ecNy)x4=(_5N*GG#8_mKYtq?<8DmYxN1bjlDK-k<= z#;g)yh|dI^DsUJU0pS#JzoH-ly2efD^h=qX5C<-fKW#!CK!31@R$m+vL|QQ6PA5gi z@`5dSBIk1Pco+!f+o6cazREj3K6PQ&N`A|Yi%=78mB_eU7|{w@aO;=E^Res)kqVuL zO`c>05G!`xZ+VIVC8V8z=q48F2p2reo89ljX5p$GAiR~8mDliD{bX8dO#0kuRk_i; z{9VB;h~LQN^?%WqCY9UG4-eVx_Epdds?ANeLle$NLUm4~`RVds3vU=d$>q@lvQZUD zx*9(WeTHBNp~&+-(5Oi}H8DVt%8HC&hNX!xmTJP zpKmUQ&9iVN(Sv!1*(h?T9F0D>J%OSXy33s*Upk+QIDbzX!v+)I2$NNWF+lb^fZV~4%FBJnLZ2!hRyj@NRK1B`e!1uqXGhAl;4qsx=48I{1n0xKg+i52=<@|M z9=uayVhB=<81$oxpSB1`0(WFno2^BXDyj=;Clpe3QXQ(A3q{h2R}Z=cWY~ zi-7?IiUrznhK<2(GRolaV+>2V(^-e={k!cgAYdkX&wiG#O^IDzI%>p2h-oxVpoHHk z$&CbzK*6_^a17`TlD%{~g=1nc_!f&sqsi?C$$yko9taZ?3`pW^5qrcLG94fk3d3Nq zShjY_0s}*kq0lEL1cvsqQq)Wq?*RjYfRo)Q#lT?DGlB^~5K22kcP>RJeKq$%EQOHrLgkQsasH0@vd*B}q%49O7Qg*N%#r(*Iy->$FRQrHD zJS>w1fwQNC9EN2oj!yqsJyoX)lAcupl6axSdUN675`rPO3 z=1x9`?w!CKcscxDDC68Bws#u%9F7+S;4<66!xyNE*!)!|!D1o&t({o*3JK delta 1428 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_349.png b/TMessagesProj/src/main/assets/emoji/0_349.png index 0d26f91e9d4d13a934881151253405944655f6cf..57308268e3b36dad3a36cb2785f7748315137264 100644 GIT binary patch delta 1795 zcmV+e2mJWA50eg%B!8t)OjJcja7@F3lFF2&?4!8kilz3f!}XxL_^QMBug3SR#Qm(r z^`X1|zSI84+VPdK{iMMCwaov};s4s`@rxZS;bCS+!hQM5S+liw8 z2ECwVA3Zyhm> zG)=r$Y@O#sDJ4`S$C85rLq964#8NMt?%sHjT?-1Vklf7=NXZZVsS; zNN%ji7G!)pU-A8ZFA=tvT1}Bj$L^N^);|=f36&6edAs7i8o>~Xv^11)>Hf2fZVW|| zC=nPY^ZP;wHv*~e8^gr&&vjuswr5seOuRpJS>B6>_>4wqH-5;riq!wKhDq`HplCAV z>*e<734e-?h}3c%eQb9hKW5w}V$B+v$b4MMOzbcwAEQq(64))Mb0XpJqfQneL1vN) z91$%*XG(o!<>AOw?J;c- z3K3}nVh)y8U=IWNNN|FXqSqH1gIK?1+&&#i6n}%NqEHK%-C0aNnm4dX4c&Axl(fGP z-7X3A098n65j6xMP+O7_EaEsNZi>xec-8yWj-gi3Z~#E4s6=3C6(E!1Icl4jnhX}G zy`s=x-%)c2B?W*|gCqQxd?aYda1wmHZd-T0%(K8{$7Sm`MZy5Y*&@ zVShjbpuUV1_KamdzhkW;vgM-`L%@YF7-&d#Qw3bk0I(B8e7z8`R>Mo*5L>Nvf9}Uo zvLV{5AX_x*|dJO7FP()2&p>58ah1JoU1X+ zw>@iPV36n5zPcQ#e%(%aEjg3IV6-RPZZu4Ts_0sxO@p_c-~Z9}lbFrXwYUG7WV_Lk z5Mp8qF%nTOWygkPStQMe!rKL9?4x&Z2#yTS;A^lDIraHjO4-U1rI&BmpxA_0%74K& zzfFglt#L|l)5WaP@GT$U$LATfXkt3KYGSiZYTOoic`hW4B%#7!V+sKxo3a3(i5|y7ipd*pnHroHfQ+?`fNaa}Bw+)Yc9ynnn>2!6So)ZvnAf72^!1 zNF&Py-4wR#5z~}fk-^HOC4X>4S}j;BZ=k?S)QU_nkaTnKvK>PS2#j!0B)m9Ge_%W2%npDTG4jA=qR121 zQ_UcP5J(!9^ASb-fdeu|$yCRn)JO<{Vm+-r6;uQ*e+qIf`#%{lB7ca?5pi4%=i!Lf z*VAcbdP~yv!1aWLBL2()OG5apICCATpAe5&89iu5Is68Ozu@JXAgR*AiiF62V*wIJ zt1aDYTZgjsD-3__KtiE)uK#wsq5feQ!*nklA3rt-{*J?=3la}bP^1uLELlPE9!fe- z|HR97KA*R3d)$UXihLle8Ovob+w@;}y-FEt?-)5h?gWD}>VEoj?ZK41oVDPW% z8P21dB=IoZBVij)@p4{Us^LzAQMn6;=~>PX3>G9H+(QV@8@MNr4vUbk+w+34o9pAz lT027UKX}Eg{PRhC;U^(?`W}MmzE=PM002ovPDHLkV1nqHa(Vy& delta 1961 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 delta 1502 zcmV<41tI$T3-Ak&B!9F}OjJcja7@T)1<7y_*nk<%dK}1Y4(@~l>zEG2e=)^-Cg+VB z?vWJ8Y6!_}3d(N{?3Ek+uM+>xIsfD~|Gq5$>_q>#CH~n-icbc2J_P@v1*>)!m0%EI zDFElmI?Jsy|Fj$b!#V%zc>mTh*n0)ug$V!rzW?}_&~F3xr+*ax<6iNg5o$65|MXbp zs3rN61poDI#D*9D`m6uUE&up~xsoT=o*)1H(&Uf}|J^VD$PH5+0RR5wupMow0000G zbW%=J0Pl-=R;2p=5;U04*vGlAfF?f+000ErNkl#wuJSTIx&mo7j89AGL=fDG*nefv$Nd~e)PK=F7Bo?UJ$X?9q(1EZpC$_V zsEPIlLVx@+MhK9>8s&KSX>QuaZ-p+J7)-|F{kY5xz!8N+UE>46pX^1XqJlNf{PzaB zFs;d+j0yvmGhw5Bcaob30tb$a+6|uLo6+XZOj{3;dFW4$Y?M-EH*&-S#)DQFgt#91 z{r*wp7Js_lEYe2~xIW&Gqk%Sj5R9tU zU;s%F1|8#|2y@naczQ=Tjugn?Fd%CnfPaa_HSxN@Fd&dYh^j*Zl7LYmMkP@SFeIV` z2~ZUtrnz_>fuQJuFmDZRh8b1EK^B2&3gTH2Mfk!bK)=NU0mYwu)g@!@ALx17` z7vaff!;VwBs%d?h1{nnEW2%)ztAZ{5Vtu#9yd!leirg@5V}Nm-D56mn_^ezTyD*RmcT|BAbmJaj=v)UOP`vdS4?M-g13*o%@C@Mt z1BEbBP&_<}LIM?`YEUzb+y*WQL)pdsG-@;uAW$R&5c@AB)IPbZ(Vn;vD1sq~_cMU& zLHqQ^s$OG+6wYfC*>sz07*qoM6N<$ Ef{~xfVE_OC diff --git a/TMessagesProj/src/main/assets/emoji/0_350.png b/TMessagesProj/src/main/assets/emoji/0_350.png index e6c28369d9470e6364ef8111a6b325a907fd1f99..2adc98424b3d2844d3956d18718e25c870891563 100644 GIT binary patch delta 941 zcmV;e15*5q55otLB!6;HOjJcja7-5{OJQ`7HC22zMP<(L_`~Jx&pA+Z zI$3^_z|hD%T;=wy58zUXN+^0w?t=*OmUTL zk+V^Dnp%IOKw^hTY>{@Kzhj51X^pU6f~Hn`p6)&#ssI208h>*@ zn!(nr++$FCmg`Ta+pg@)q>1Fb0008!Nkl2&krNHul^@5^TSsf8q%*^Zp$nG@D+wbUDx*! z+J`VbY?0*j`F{hFPayF>703fV-vRv$Y5tkPPs17wEG0wukt0v>2rG_6e$WH8K!fHY zk7qe4_0Evcy(tbAz>f31KKgGAG8sk#Er7xT$D20PX>hYkRegP}$Ok7lKVV(uD~Gxw z^@ftYP?Rv-?7#`@HZF{s6zh(xo~{yzAv4XptxpSu%zuqj755u(xB21dGgl##@MIL% zo5KUS1$E*p*HBlnBB&N;CqJ(rSX9>`emtz94?Lrw7$zbpaJGX^cpbv@>)`)mV3R?K z^Mf*2z^Slkg0{WY__jC(f)q>I#|nL+6dCR?*#AiTbE3th)wbs4p<^*KfC86j0aP@x zkh6atdw*bx6}OpzWeoz;b(e?PzFTk}4Qv<0Fj%|`1#k(Vb`F>rS04!>W?vW;fB(Jo zm&t(&6D8iLPlztbI^0{Ze6P7kMo8ZvpKUY{tkcjSW5u(vi!uofNy#QWPFHY|CN?Ys zDd6a14}qw+6sC=glfdv4Kxxl?EEy0{92o>Nj(>P*opGxiX+ez0FBvP`l`_-1&U+h|LpK$KBamro5V!X$BF_` z*B)0KBI12h^>ovM10<-6Q6cu-_sl1&c&%Axyp zDu14_4;EpcKhDOYR2a(A?9YM6B z5b-QcEp!3$GXz^zXu{ESd%-pVg^hQ*3pN?hMTZ~_7&PCpZHSB3kcjd5 z$aZWaS>L&EZ>yr1DRdyVKF7Ip(Xrb4945M(5wneW`(Vb7ZAI*6h}VHXEdbIR0rmGF P00000NkvXXu0mjfF)hYA delta 1917 zcmV-@2ZH#+2aFGpB!9+GOjJcja7;owI7mJ`D<>v8H8nmqGd3|W;j4v2K0ZY~Jnh4u zHZU+LBqM=nQ_P)rARQg>$fh0{7wy5F?!uiF6cZU16(1ZNE-EVV%BM0eF7?u|A|D_6 z-oE(Rx9!57=(v*+4-F0YQF=JpsX3s?%vHaCl|Kp;MFN0 z$ftjQeCP4$)Bm%&(`xstXm_8Ux`X;d>wjaqz5aT=SZolBMKqZWhsJEZ*lhWQ&7kw& zfp&z|G8T~$tY&LmlUE0SpGijo3q-VtqDW&Fh=@Luf`4rK-M8t?h7Yn$M5roKZGB1tRX{-0f@r+K{8-WRrLXcq z!xe`3vf&-koz1i+2M+N0&me@Z?#4@hg-s=u>VMmQbQ_|LS#Y@)FnHYVGscQgH+54v z`@RvaYeWz*?i$(`Wr!{Tz@53-L@SnN5GX=2X!8@&7)>ReZvw7`NwnE6494QAr#lod zFcxhCL>QtQ>JK@SmO(_-2Yy0D8h|`>P208)whctdQa_;F)-YrmvKc)Pq6i4MiDnj4 z0e>I``#?d6=}lwCW-ulVVGU$Akr@~GByek{MII`y$pMMDVIH$!y;$EFL%A!U3W4?# z0hcC)x3}8Ry-Rjx+Irm(KfhN5?`9Ba08}46m|heJ6#(N+8sW4^)!9UD#Cnf+2&GP< z1pgzOPGu2TPr$u#$&m=%(_$o@iqHfRFn=0@6o`-^5XXcuEm&aGME4V+GM2s{r=ktE zV~YfM@N^uvbamZTF4HVkL0FH3r7|_mxZsZGqfNA(18Kq;8O%qgcV5Vi2g1OOgCSSK z?(8p9v}|ME6Z&X0pU;bQc^-$;X|Ae*=rj|t)Icpr2n&BQFC81v08LHiE=_kZ-hUYg znuy#NfwfZ4`4OEwpHHa!s{mwU}0Z~7;03>I|R?$@$`8!AH&vN6NpoKXlb5u z;;D)O2rJHy7fchAbjCZSRNTV@Fy0|@8dwGxj!xE^X1Y%C8MM1@=dA+caMRgp=CKI+_+5e zWe`3_$zGP?m~xfr*%Vq!GXW z{=K^#0!r5Pw+ir&(uKNRw{T>20uBX!;tRo0T z>5F+Z&w+y9=DLa7V-Mv@OMedshX`@};3`m@85NN|zF>6!h%Y#6I6+IWj09|yH`^44 zpiLnNMNzV$?1VIa=AozrLLH{3c%CQEa$-as%1#K6uZ*Zfq;aSf$3@>l*J%V>)G=<6 z@KqWhnlHshbY&8DlSI+`6VYk)4R)5@I7q`m;9mKZ1j@i^)9c)??|-$oo5gy?GMNSt zIF4SHrBarzU?Ef!EtocmqIO-)_g;UyCBjhCTv22<^gJu#I*P1(tHyycGNu}n1s3(& zJeBsA3(>@|{B){#^_Kf8)Y1`rr|EPyzx1xjMX7*hicZ(~Sgz=sK8Qax$e;OUtg z72=NbEX#Ku)&n5H^`1L_Fx3h)gN*7vY4cYGBKV`_zh+i+_ zc&T1)jpo=I7$nFuT_hrqCPWG%+6GU8df6Bt#N$mOuOvvtbO~sVC^S)(CgNKyw+`UXqcC0iWjutpC11KjO@EJ5cO#}00000NkvXXu0mjf Dd?tAO diff --git a/TMessagesProj/src/main/assets/emoji/0_351.png b/TMessagesProj/src/main/assets/emoji/0_351.png index ed160139cce04683e3755706e27d33905e57dd37..a7069a58d1256f18d33b9fc77903be6c1938c17b 100644 GIT binary patch delta 801 zcmV++1K#}h54Z-9B!5&;OjJcja7>ob=#IqQquTGJ)#{eS-Y7$7fUV1TpumQ<(tWPW zgSXO$!Q671yF+G(W{DfZw{n|2nt-|NpN4|8@TV%zsO<{K)_S0(nV9K~#7F zrIm?xgCG<{5mR?eWC_Op|9^HuCmv4Lr@3q|9_AM5rruKMvOJV!p>~4&;qU_vhf?pc zR3+jyXfUAJeiVK9sT)9GIp~dsB&gR0>YsMA0X?JM<|w)>z5<8*UHUsieOre@`WknJ z%q4u4s(-EM3V-n-zC1=-Hzqaof6UsNUi2PaW7bR}S2U708UMd5dS>DSOj>dkh9Hv{ z^t6(zFz;xN0>#n1Wt-xZtt_OcIGGcA*0KjisK`Ti8Y4di2H=vFrmF-$-fM~ljjROU z)njvdgX9?1bei5frty=)V$-#u->>W+700xn+t)SI*nf}r>6p8d5L8ZmV)WBn!dZR9 zg?9$))MqM>jcGSm%q)Q)l>mnbm^d(_v6LJFoCEe#fFc))ZUR)%zG8}_65+xtMQ}>S zINuWg1D(@6Dk0~HNU&%$u#RUXrE>n72pA*@y;E|ki(iu%bX_X7f$r&|%vP@E$_V%+cK!jY@cQxP2w;g;WTa3d6# fuNr_tRp0UlF%zB#*n?v100000NkvXXu0mjf>>H5L delta 2024 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 Y^Ap3S1KIj@*#H0l07*qoM6N<$g0ts<`2YX_ delta 1700 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 delta 1591 zcmV-72FUr?2gnSNB!7EQOjJcja7;HSA!J85Hz*-bJv3KDI$u64PdP17Ixb5!Dl8!! zaX=@JSTr^%BZyKkDH;-ULMJaG9T^c0Lo+Lzcv@LSJW@Y3L?#wwI3YbQCw@vSU`#?) zFdPN~0R8>^N;oj(-PC7ONtt0glwCK%t(nunuBeZ4vYv{4evTzg~8ULH{tVUkeK{Wv zb5-IYeE{U&Rev0VWq?2<6RpN`3-y2zk0FEmwsu^C@Y@MCa;G!s>jqHT^OB(sAe9o=Y z@VvJ)Wh%#> zfNh~?fv_)+-yzKYTa464kX$sJ@;fNK6`)Yr#z;;eya1osmjnP}AjSy)Xd5F9f@Ojx z3${5`}Q~y`Vbn zoTL@w8Gkl@WGitb0bVTN_;a5-5|lDvw0$2CCN?uU&FHcK2>>`(7W>c%0Y(Exem*n8 z#yXR%f)J}fK#!+lFiKF7A=$`to=L()8bYveK9>m8jZs%DGHT~+84QkL<8K5Dm)8LT(}`V$cx~` zm4#M>2zA2(j^`qh4H*deB3el#02U$)z73a60VY(Z6dAR%oMJ<0ZT%!nXCSTC!$uK< z8-K^q*@g^lw<(g`3)%~V#@}kE#XF%e-(cOSo2JGbn-s}jlAuv&^r#1aLN6amG|mkW z!|Lrx-IM4$>9qMcmYWK398HA@UxyY1hpjZG!T47pJ~-Gx4shw zQWil-aPrdbwO+}$`n7tFzJTyA6W7)SS< z&R~R@yxj&4v#c!=s;lqQa~wg?#dH@;h}%?*SamTijUl3@%LP{oL`{TwOh90nVt<;} zO|nc6A{2h#AOWjG#_#tL>xoX?r)km7jm_6>ns_GH0zZYie!=&*&J)Atc9zO|@Pq*4 zIdorN53t@-OgE#x(0wZGMKd(R_NIEM!9_xe=Q1si2c{{+>w;6@@$I%O_dEr0-}cz@pTGob_sKo}0O8b34`m;$f)^hVc9b;VJ1z2VP& zh~YrM)~G{_>srb*#u#w8zzFj=e0YFO4xR`GT`+~A7QLw=%;WPD-~LmK&LB%97SH2H z`b&r;j&iMsrr{V|f(|e1JV+R{-KW{+(f^2d+*a2O#klf41O$ckLPY39t$*99>?4kn zga_|3w`_O+!8>LDLYlxV5(JT%vJ~Fhmpt zAhgpIL-{4}X4J}OpwnTAs7gd4PJy@DxrMLx@lRtqnhO|>b_D3*O)z^6gbWWuwBO^t zCm~1TxC@4#jiN1S5C}qN;(yFS(PKbWh9~i;Cn1;q){=p-BG`c!0A*6xlh#U4RAGf> z{pQYa4F@5pE2zP>4_ObP^A?JNbvnF{n;5pLNU-qen`qsx9c)LQV6+T z(-T0zV5LJqby55pK)_7BWP?JyUqdoLHWdKglGq6rLiBwr_u02?lQ2e|;qfU09P>zf pWIG_H3|l41vN(>jEZP0%>n~(a6U$yPcJTlJ002ovPDHLkV1j|q*n|K8 diff --git a/TMessagesProj/src/main/assets/emoji/0_354.png b/TMessagesProj/src/main/assets/emoji/0_354.png index 5946db554f780ba89abece167c321b3e2fd67e7d..5955d65c3f5950de247f23261552ddc1077b8bdd 100644 GIT binary patch delta 1738 zcmV;*1~vKq3fc{jB!8<=OjJcja7^W>9*zS`+7}7uc2*z=a>hfD(5<6^Ba{ z+?Wyc$2RDw6O2w1{?9-5z%Imp693OQ>#Gvyr4r$u6WW&&(~c7V&NchOANh+<#u{xi61i9skuwRXZ8! zuOc895v^$!`0KJgDiqA5QT_Pc>BVH=%Z#?4aF~HtwvIF62kGhn000woQchCP!rUFA&Ejfs}und++p~_kXfq zk{2AfxoO8{CV%4@f1D#BW&eDs!82&^=l3#S{`)VU&FUBP*M#RVv+a0R&z^tFFp|V` z!pyIM@jJp`#0BT66UOz-fBBsWW#zf0L=w(odt&~^#H(c$1yE#S`}U7*3|@@sB1$|^ zq;l?Ler)`#mD5q;!A0_dLIt6pO$R>!jMDS#gzvqD`$*@MlW9wMnJd)1c?;fTJb3D zAjane&M*cMg0nnjS^0`5(Ki_PlC$>!2NgI;%5xP#RS<#<_D{y(kt2dK;QPG-xG7V| zVEq1Lf`9oa1QL3Hix=D-1_TYFFl_X3Uko95s#D%2j8MKn1k92B&SO_qo2|-5) zwSa;mh-R=4T5C>)k0V!m58EkL}NSu7S!gFYOGlB8E{ z9e*G~n~1m&Vj*Nh2(377q!3aSa*;trF-dwoYXi;*L34Ep5+g$2m;`gUF4+h$iRcmL zpL^_w*NqlfrGgSci=t3NG8?->HgId09l)48PcMit3{oy2w&Rlp64`JUsMP7YLWrp` zr89%!*clg`fmM8?vsJqR5?QY%oW4${q@%biS?aOlF0Ya*RM@+s#R}Cp5 zRwyc{TbJc&URCp)uhzRAP6)|g?|;_S94?{2M4bf@6NC`*6<384DJu#^Jwe8?UFGua zu-lbLsB3gl?sn@_yDB<@;{iey1xtm(r7^H1W0s{Pr?&cac{m;q>vdVjC_vzx*5!Il z&&wJ9z9E6KEXHI(bMguXth_*khYQDsZ?18$;1i<@95LKs_}HfrflkOGFMq%alme4j zQdlbsKoKJJ+NCnsSq)$7x^_%+)(H_QSMaUC(aY~a$zlaIaBmR;7X_^vk7soq3Kjwo zA$o5)&`g!D3aMVt!~UwQJFvl1ZR5ObeA!x3TCH*k;cEny!dl(s1;rqZpTFqUS%)i&P8flMHsl;tq3Ey8o2~?mm?-k$ zho@kys9?T$c2w&)l!XSj=I4+9*iE>#`H^0^xjVN%UYvKfS zxDp5;3*Uw0xRE)S0YfpyrLw*c(2yZea;s2ENu>(d4nqL^Oy>CMVK}@a4Tld;WAo2% gWSZs}Wq$hl|5*7(iaMDWBme*a07*qoM6N<$f`~ybpa1{> delta 1387 zcmV-x1(f>Q4gLy{B!6H~OjJcja7;BTC?_HyCLkR_IXN~kFE1%4E+!@`B_uK|D;^vi zF)S<=5DhvhA}$~p2n7WvBqTaDHBLG*BNq=uF)BknJ;Al7-`dlqnvQH-QHpzNO+`gk zK{x&U{Hl;`vU3QBu{d-9000VfQchC4X)|ErGFBr2h%oo!2SG{x zv$|+?*G(OJNqGB-9P4~xq}Qq{HPGDz8)dOe6&(ggzK635Bms0T$J)# z3o|h=EovplQ^%Hb~G|XNWYIfanX6&bnP8|bMg&Qmk@`L z0XVxhSU-ZHyDlk)1TyN3DByRJ4}oW&g>l4ICJ+S?qdkd=1!;nT$03Xkj0mJ4$;dk? zFGGm{EcH$Y6nZR=#^WJLB*xiEdrKi$AYh6B43330GnZBur_vJNGGKbw-{MqKm-BK9FBq*YDHrVS>uiLApnn~2uBbyIEbvo zTgyZ%^I?Of2x%rh>oBB~cqJ^>AWi%h7{$<^1b+#Lpn!1!b63CzC^(u7o>d_lBLZdc z1D^|EN)+JA|%wd0rVAt1%1{2w1pf-|X9Ol;=0tkM8%}0!WeeD6u?XShT)Cq1EQp#uy z0R)@^1XllkE!){fI{NDkzk4QhEKZ`iX@5{D#r%3L!vMlB_}?)a8yy||FFd+pBVh2V zkWxr^BzijM`3wJCHWknsNcP^|}Gi5U0gwY=Y$217_E_DaOaGQM{Up(X{sekqwbFl2z-=E3~B>!C8+^7 zvtv32t7Atm^c6*^7??VvZOBJ-2!B}($Z`k}keD8XV2Jx83AFEcHb}_~dkW55Aml~n z&M8SNwkV3Wg?Rt<`U{aZ(`i)LDy9Gc002ovPDHLkV1lGRT(1BC diff --git a/TMessagesProj/src/main/assets/emoji/0_355.png b/TMessagesProj/src/main/assets/emoji/0_355.png index 053c3249ba233861aff7f95f6735453a7aafb65e..49ae63cc412dd955d81d060cbb5b163ff06b1a87 100644 GIT binary patch delta 1683 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_356.png b/TMessagesProj/src/main/assets/emoji/0_356.png index 9c28697de895735ff12d088c39a22bb3d79b4265..9fbf6c54205537f627ecb686ac704f602380551a 100644 GIT binary patch delta 1595 zcmV-B2E_T_4$KUYB!8JuOjJcja7@ytciG5)wQ@Jx6Mq1~e^hc*Kr0LYqK$O1 zp^bh}1gLll!?d5png`?7ki7$gumAu64|GyaQvjO&;QMvwB@af$cEF*`8FnU)000G3 zNklan{Io?(_in0 zEzF$Je9E~G;tCK?KTI-n=2PFmtC1ob&$Ax@rtt0@UadGHcH8Obdk_}^l%N;KmEERN zPMvQ+ytx#dw-yY@H;CA6_lb}~%)czvnMwf&8Xsr}gnvC3LV_Ik^ANfvm>a?t2omBE zX$v2Sf8gqs)r+MuhjzBAyj=*?S0DM9;BKun_Ujd(P2l!g}Z}#Hb)9NXsA_ z&cE(TZGTNPDVq5R6-RLoF@~Z{XOAY7R+0$hp$Aw2t@q)hjnShCMLBGY0U-=SVl+mO z@qrCTDl*X#S^zLWmeEHM;&EX|fDrs91`bbBf3E#?H(a-*2JBQA%B4ugT{s;h%FQmLOi=SRSXdJ7yS5c z9L9W~bqHWgXCEMF-v}Z7TN_3}T}mszUlTp-(^E|qjM{9rN`vUX-WHr8?Aag$a8B@Orwe57ntG{MH3@ z>+|Uh7sIy*4hT`?r#jE;LsgeB)+q>z%{9NCt7@N@J|Uz+gwTkPyhCu77n^FoKO8po zB_AMIc{!i1>+_*r7kS7#1eXaSl<;Museeyd!A_bQ#j?J*W$6B+ByAv&d*0Ys7> z6QxsosJY7oemPUNB9!xqVoVIC;ncB&rEYL8Dq~4(;sEn#OfYE zrP87_jObFY2deAMK59(}l^oH;qZSib>6Q`jy4qBmPE{>qGC>P!O+3n_C{3j-*6Sf* zt)sq(VV93ldLJ?0*R7BG#DAl#B|s754p-9YKFiAO>vx!833MY96D%_Fy$z;ub?A1VOP5AQUzUJ$x>A0gU9~Zwem)I!z}l z_s`ezmIP50rx8a0?CNC`;%g%aK?-2NjSv#&kCWvBEqoK=t;RqB3^Yh53C@pK9squ# tnYUOi#}m?cxmtM8;?L!}vqqo#{|~a{0U~9Gtlj_s002ovPDHLkV1j+x$6x>e delta 1872 zcmV-W2e0_d4BrlrB!9F}OjJcja7;8XFgP0i)PoHcGjGB*qwG67Z}2eX&V_D^3JOZ3kvqru{}38H83wnKR@}}x%=P0>%N-r z$E4e!dFQr~CL<%>r-3XeC=(G6)|qn9kZ1w|1IL72`R?7;yMLZKCmR0z_*yt0CosREAjwggRi(hqFZs6TjRpr1mCrzC%e*xf|YpSnm$0IkUh@wdU zUt}$_00b1@6^DG0$wis_!dLng!AI1A;rh3@E`J18#DxQ!@f@lvj6o=E)9y;_fkBB7 zKwLK;4xuq0O|k$Kh`y~)%82Tgm+XR=z&eqD;D6(;WbQ5M=$dShxV0sDV(Ge0o$!jo zAOb~l1_mj+Isibpqs>^)`$L5A4v8ttV92JIeAEn=i1)`?x({AQ5YqUPa={JClDNCX zk%7Qij-BiP!9_~93m73ybQ^_?_H(KBCF<^|T|-B#*A2svEys(lyPOabGy5_WdB9SW;;gXduA)I8hKwb{M5vSUZvHalO%XatD$guoK8jh5Jl9yq|S z4pq*c?SN}J4ov6mgyD|vPf4^0J{%b{0JorGniOQ2!t2y4dt-G!A@F{pTsZ9a@C(4c z4HMcN| zIw44KHBC#-)Fy)kBBI80WAuyWW;&%-L?*;S^;vEMK`G^z0{-neAr=ahYsTKlsDDf? zE6mCGqP}TvP?uuoHv~0F2yR zs!ZRHVr12&-NH+_n@F5@OgmeTJ#lB9HFovRIEa33tF~=e@LpA53{CV3g!dqCtF5IA z;>sGwx)Z|s#Wb6svyqUkZQ7oSG=FETN%6Y$zg5~Ei`0!77*r5ZzBSFep@r#e^ThTX zATCv!leP(hx~x)t*oi7lOFwJzXqtIC5?<7WXXi#ZPIyg1*bGXuqN*8V0jtZb;M>R_ z@Mr+RqZe%9*b%N6h)3rfCP`$&ep*$rFN1)wc=u5ig}56IMp0Bb!f^>lD}Q<;yyu>H zcoGC|Mp_hYo!9lppROp<{XyJTMNwSqJYeOYE-g|@sVP=GJnCvr*m>J_!=Hk3BGS;P!hNF&+Ro0s9|C zNwXXi_kP|*IEf(io{$~OFsP#+215v@(_V}MYgChYGFs77kS7{OW5|6 zvDJD)%vqg?8gx{{pmq{@lmpWeVIGtDgqY2P_&To98@gaLcO^xZeh^-OYKH!om#Py`W7zuq#rU_Zf!_WknbZ&vH& z{p{h68yo?J|J;D^<$3mttRJ6jnDBL~FeibOf5lK*hfxutS{&j@`d3*^` z>4U)2-Sc05@n1i`y*xdEgR7rj?jCW3zt6+N^CRT>`C&c#r}+;YL6@`2MxL?&0000< KMNUMnLSTZI6mr!7 diff --git a/TMessagesProj/src/main/assets/emoji/0_357.png b/TMessagesProj/src/main/assets/emoji/0_357.png index 8a95443747b2f36acc19e0be13a26d4aeada8a0c..404cd92746ccc90ac8ad0d102f7d2f0f9cd26456 100644 GIT binary patch delta 1597 zcmV-D2EzI14$cgaB!8ArOjJcja7?LjSEFrHaY!&|L@uXrR%1UagI7R)Q$BV~HJxWq zSU4nJJ0^@;LSH>7w0~f+dtIw@Sgv+krf*fDYf_3@LX%-hy^LnRk7&4tV{}V2w}WE3 zh-8~)PEs)&_xJTb9th^%(YJ(M*~zuYriRCsZ7UK5Y(W&Snty`Cv73;6ZkA&OgH$oZ zlWVqz1<$1ip?y29kVVtbqs{;T01tFhPE!EjwukwD0O-H5n{csQTzO&E|=Gz5SAN^ zkq32cIuieD`AayTaZ-S&uJ_1T{98SgQ>Z6|6r@O$v9Vcx9}wc#6QjahIJ(#evoQWP zfKJtg6AhpxbAw^7@K{$wtp`(&gr#20|BIz@N~2_rO066 z-wB~$98K7It0J%WZ7U1Pk-@{|_X*{sOa*mY%aRcE0k_PTegWoQ?UPCIp)B2oLZK zZvz;!M;k9p2xd%__k^v7JlF^ya{z+h$1ngR%W&;*HkJ=Lm^bl2KzW8oi2Ecljt?NR zFAzQne;nBmsMIg0?ZoyYL}?rPxF&PXy$Rn+FMrokWE9rMeKTg%BTDeeI7#mjX+c4S ziDD5VzU!tX0D_oNWQ-ueiwMSqtR(eG#OLfov0M=YOW!3@GpsHNNz z5Rp7Q%TK3vS09HvMt?j;r(oAc-H;Vm1R)ew zb}2cr2$E&}&_s39)VsFsjyH_*Ftmr}uxnf0bOr%Aq$Gq_fT-An;Di)(Y`V5RopyjY zH0j$lM%kTq!6De~>iy6h>13jkgfc|D3V&LNN}461@c*{mf!e)phQuz)TRJv5evF7? z(;0-28W3Va@Pbt)34LoOM7wLxzncya$bi*=eCFfb{(Nkj5pD$&fZ*~K5Oc{0)0ITT zwrRTB*f_sKrnl7YIZ4+XjJx*z+%=GdZ~+JbIRNprs08JJz-8@^aBmG~@cXadaDOWz zwieOkd(f}<1ANPt0HV^0K@J?(7cDv0zyJj4M_^pe@4x;BgaKw25oub2`>r~l-;pr9 z;e<#;z;%K1p(@6e($Z`geKK~#csO=&HT%YPYo6=v&^5#1Ff_y16C7o!m13;YW=>wU zU@Fp;-E;bKJC5Tv>B}_rh_Wx=Mt@M+_vXQZVx^hT&6$_srb5KELJOHV?uZa&x1S)a^_r=AhX|~iBbg7*PEWytWqf-^ihFvJ%G$JhjBXe|UOsL28sI>J7Dq2)TjabXB?6#L^F z2RvAR=LK!G0Z1jqM6vY<(2)=El@SBcKmiPJIG$V@96T@3!gnF-XEqpfrL?X<+SG4W v7VvFKyjX8G&qkZgda;V1ex#+--wOT@tl<*B<{NK@00000NkvXXu0mjflSBFi delta 1881 zcmV-f2d4PW4CoG!B!9zDOjJcja7?y>P1nVJ*2R3urD(f%PS3M&*~oycg+bQEeAUEz z*2H_ww`;wBQ`g3Pw|q^zc~7=^OS*ec$&F;drB|SQJmbfp+pvn>wvgk$nc=&Y|rkXSSi4pcJ}Y%?A*sE7=H}n&$9pi{-=XjWkn*T zk8(dQ7JO+>*`_Go&x!8kqvY3;)xmh`-&@S6E6h(1_(LP?L`EFxSj(_t2X{)D(qvD7?a8$GzvOJ`Gd1fKNj5Ft>hZ+8k!eJAzL30e_m7Rf&y5kyZi=Ze%aU|GykD1}PiU;%3 z&t^h>P>6`_;ao%n)Eq*rtCx4;I0gcwVCnc~767!5;k3kFXY|uF#?=AAhRi3CYP0(t zN+=T&fPYS>;WS1iBq*chs-=>~sBL|#XyW|(GLPtTx(>t8M^)097-KG%KCbs6>g`Xd zeO3?%pgc5A*U#(6$Ei=|bYw0emwp&Sc@RQS_hXL`@c(RTo(bv#Gqk zuDUP8cMue#jXezDCb(2wMxiwfgWWKOOrGz1y*&}{hwH(l=u|I-?=#NF^*dcI^MlZ` z0`8)*fN|+zpFR`cObS~CoQ+c$*E^%aC4XqZoZ$f(>cQfq;!T@~KZt0Q2Y?870!)zu z5~vG=YojFt#5@HKUhgx82;5K0vTV5lCPk!8llmOP;nYiSH`N!SRe^*cOBJgc26t{L z=!)aD!(Ymj3mBLwcK8EveXEq^OUBA1DN`oQ2%L|t2(?cBW`@i26n}Tmr=o;mh_(s*A4XXHh=Qu^tpJ^HdCE@5Lw1Id z74IA3PIpgv$%u%;!S;d(gf0-F-CH3MVUeBplwyC*Gj}3*mYvVVY5!|~%$z_NA|Bp} zZ4_9sCcqzx{VxK6}IG%$SK8?gO3_5zWz~(8LzN7{eP>q6Q)uE3%9?jm)#cbwLzFxVt>d zo7%463Os{82GtK1LQJ(8)PFb(#u<0=JTDx5$X%x>9J&y@BBydW=hTNLFwFOQ0YN7N z1j@W9AOxorTw`=ga4Lidt)cIS`#G_!leotwp_2(9gGbVJWh9880zHPXkh@vViPeG# z&%_WnLwLOx4xtNRB*qY))hBAb`arDXr0*@n_-IJ0?>*+u1qy*a;(x>jF|T!~u=g zAdT=tCCqk^5Ly%>{z9}d#h_M<;c|K__NH*OkzpDHLO}RRRJBUtVQ!=_raCgyg%K<~ zs_JU}k$C+1(~fm39)I;hh|7+91Dr3y)xaq9u~PNo=i|p6S>1ha>YJg1FyZ>;<#@c5 zY=`v}A=1L2YP)XNSo5jwtHoc>s=pZq(f>>hFbUi3!d~BR9zFxev0U9fw2SS+B7+bp zQ%M7mu%Soq|K$tn>TdZ=27*LB6fhFy1JDr`Prvm=ceC(3LQ+UE6={H)Sl<0!Ew@0l zGF7O7XC2{pk(XynE2caH{Kqf;tEZP|nyg-JEw-Dnh5x85pPn|TrzdRI|62b5)ZECU T+&1J?00000NkvXXu0mjfaSNKc diff --git a/TMessagesProj/src/main/assets/emoji/0_358.png b/TMessagesProj/src/main/assets/emoji/0_358.png index 8d165e53290754c539fc6df7626009246e92ada8..ebd097edd0d4da1b05510e204b011fd7d1e68f5d 100644 GIT binary patch delta 1425 zcmV;C1#bGY4WkQ?B!7EQOjJcja7=baD^@Zfbww*iC>dHcAyF?LNGlyzG9X+xBS*wFu&c3yxjLEsCon}3fer}Rs1h|R?R6#e?s(%G<$#-7>000hjQchC< zl6T$TT}1vS6S(RCr#c*NJlCIuHfWvBB8Jpk3Z~mdyWu;cKal zyo3ZE)0rZar*wR~r6T6f%ZlSDivIjd9g_Xm*Eud#p?h4abgP;*S9mGk`861$=A5$xX?V_h`0O2y=daNx1#?w~f z9TIZ}yVeyF$`H6Ohi`0vw+NO z;55MSzJH%=AXdV(7!^w{V{pEUw|zKaZey;@gEfzYgN zTcx%@ZmwS_oe6&Ob|*6r52A7XAZXf*SIw?Nqt>m^wxOI}$A+3#kYJS1Qw*Cy)J#w^ zcINWF|>1fqz5Cnuc{3g3%2NBfs|LP!B~_Wi=Q; zFn=Uc9vFg9OF)dYsr#~m6h$SQuFYH}d~!8>cDm#*%liBa6{aJTkhFs`R;bx=z=*xlb+8bO4p>JUn zNI(el5O+XAXiJd1>HA?AyKZbUC@Vmo zroH6(lE_tVE;p^BN+BTy;{u<*pc4*+m=0*3FFro=OZ&jgb^LD%1UCe{BmmeLKuX)m z`fo@^(;Q~W(tQ5Ahy>$y1%`l%_CkiX6EqBh#iZt3OO6B@u8&ZNz55W4k|4ksTOtgl z3`6cxAc1}Ohs{@vS2)!M2i6;_*Tw zch5=qo+@w`A(E$${TKs{jF+ZDQ}$h@T^~kx{ygr7OM{lhs!B4?QpoUo2s|HP@Q0BR zXH-T=Gbd;%@$1bGtvDlBqH>5(nHwdx@k1RJ28DT07(C2FYC1)D9I60-pMMRB#)O!q z`1)FKhMlQYubwNxNER4Vb*uVVZ94F<3pn`>fiEw=9yH&6+!2pC! z2uSG!?0p1Y2JvAcRsqJOVRpR%Fv43%aNLK`50r)ycKs27_bWR1$#Fl`G4TUf|3SrZ fWGjw;Tks#>73)ror0p*N015yANkvXXu0mjfeinxj delta 1699 zcmV;U23+~03$qQ7B!7NTOjJcja7=JTC{-{QlVC@9OD=XvEObaKcuOvMOf7s*GlEn# zc}y_Fl4?XJ6N+0rmTF3oVnbazB)5cOQZN{7MlrjJWu0_VYd|2sj%Uc0Z8IDTw0~Z6 zMkcOzTc2o9sBu>A;?kmiT^0@pr-^FKnsEL5_}s{`(zKSio_~VImM+*W41oXu019+c zPE!ED*|Xq?q&OO5*qt-D000HrNkl6V&G6b0aD1f}MYd2+Vj{{`0eNq76uaLW1yNYxmDSs8ASObyB0JH>LMT_@gP_^EJ z^pprNPyuI2_!L6khmw<6St6hWttvExdJldKq1juBG;{=j=&i;cDN3m2Z3rQ6H8SX} zQgDyTS_?)(2rdwbiN_O4ztlMF;_fP)f?Ccw_6VWj2z=?`B?5ilf3A`B>6GbY6%xGa zX-H3d2!Fm*z*78&`Mf9_K!cx7VXd~oc%=&OE3Q`?@=ueA#4Ek#WTKY0%K^RCeT76a zDoDRsjidk*5p=LFcZPLBLl29`;UAp8f>@{)f(YF&M2^JL*1Cb!%t!}CY?Z=;0jxzb zGR3kUn^>&ZHVAsEF@7T2J`d?_`!o=YM79t+B!7CWS)nlc+6SbQG$N2*x7=zp?2E|P zv-vDbd+lUA9>&7zZX`}yYqhQj1Ei?};xE>4wz7$St=Mh+t8o#WiVNEcIMFfd;3(I9^ zJR2x)TU-EtY1W9b7CzuwdIrWoEVo|?&1u&eL)%u%u5MzU9qUOA&8C)RNi)uNY27hSbS-7HVhQg90pv?y3O$X!E{ffxKa*ROu z+A}|O02u}ct_|;N({*^wdL#(6pf92r-HY(`bi6&JdfXoMWfkV{_w)IFFT2_YLU3D& zp-9BfK>5)_>Qz zJ)PwBzFb?6>%)bu=eaaUOiFV%PDo%P;nXx3U*2YZIzx-r&T}G~3!7)#-X3A=t*ns{ zK*;e$jHBb+iE%L9<9cgPn6|oKZ!8)2W$W#FHb@X4gv=6ANC||-`Rs1j*#@E)@HQ@N z)67@shN)odtpfsjb4Nsxh`mxkSbr*~uA8sdbIaQk`S`ddqCw&+PtZe$t;U!E35|=I zk_*RM>u^39?p*=!F<);Di!Im%YV=_%RC^d)5bRA?H@=<5-wd1#4UK{X*-1TG2Tx>D5Xmcx3ivuRsyV~w@ZQGm@CVHgFL;2Qwe1P4On_XLdv z@zdnjCA>Go7)rD@e{yCf*5)_g3x1(_luXlp*y?fMGb> z0+GEFSc9r$FwakLO}7|$)pZh{!}vuD%|i`Mf&mCS1|$Brh5---;vDYF^_S_)H+dS$ zVi?^fgwzayr(j#&^6e)7yr_pCh2}3~3P{b4!U3v$Q%7J5g67;>yMKXWzGPo*vu$f% zMnoVD^9ItPAVA1BTf5z7*{_}~4?i-y&9}}GArq34041n%8Sc8iwBMQi#yKifKrp6* z3;;+$sM{5P^`M*W93=snhL{Ne1%L}P_?Hj66cAKmq!I{hif=uyZyYE@#E=Ml^TGd6 tWSbq0al5xi{%<}07aUo!hgtro`48ty1avXZ>L36B002ovPDHLkV1h(69Wej^ diff --git a/TMessagesProj/src/main/assets/emoji/0_359.png b/TMessagesProj/src/main/assets/emoji/0_359.png index 5863adcbef352233121a6db87e5ed7ec0210d3e9..79d8b9f22dc6042f71a16996d3d58abc90545ebc 100644 GIT binary patch delta 1244 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 M07*qoM6N<$f^Y-1?*IS* diff --git a/TMessagesProj/src/main/assets/emoji/0_36.png b/TMessagesProj/src/main/assets/emoji/0_36.png index a22b6e9ec9fa5484577dd9485d956808b6552132..59533bedd6720baed4e1d3a615be78c948c5200f 100644 GIT binary patch delta 1392 zcmV-$1&{ie42uhpEPu*w4Caa%^^^?Kc@@rj9LQ+}#D6izZ4SkIChUw5#c2rcoFDU} z6YQD~)N=#dfCl7|4U<;~gGdD4xG$`9708DdXfXn8H3GboCUiRkTO5?S_3aP&6rji1o`qYhM1p zhW!0-D{JwZiGNzQpAI!rbk%VBesvnEPRP$x+PXW3Jo~odOgML<{b)c`fdl<$^t6yk zE8kNlgz7_)rp|%h>*edtGMPR{>OZd2c8&s3@%*llf7L({*U9Gv$veEM?taiRQTALb#}D($iHDU>ZYkuYb*x0xHd@QligRaNOW6W~I6D zn9&=R8%exZkjYUYtp8sgiougCpip)nxF!>-@|tABN79(R2qy(?GxY~aYn{V_9(0mC13 zgv>$=n@(Pm+mFG(nAt#n^1_Q22m9x_XTcDWytq*?VcL<2`JK`|&wEFo&4dtP%<#BP zb{O7tyWYtd$8i>;1M&ozIXzuyjJZEIq`4{^m8ncq>F-#Y-YQ0} zW^E+e5Q&@TwaDp80y0&1B-nIsIsdOIn|~}X9>(^O*hBRkQ8XnLKtPu34uCZ}oiU=S zvQ%kn32!0%n1?||OD!uB@>;)<&^w@~)xGJQ3_@OucDTzZV&C3oL6V{jT~jpe@8+H| z+r>uTccjP_OA%=j*xT%UK__JN_%i5Q1{@+88O4_c3FzbEzP7@6DML=BZAEZ_!GG@9 zwx;FNSc-@-O$YGs0fLJGNIa|#hnRSZl& zoDlc`w(($CBx!o~mm!730$6n0Wxl!*b9@M&H`Mo3|1lHI&tfbg%M5xom3%(&3o-~!+;bN0ha yK#Wa5`~CA*9=OAkB>d6?w}UwU|7V7Or+))Y4|$e|TLP;90000N)0 delta 1534 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_362.png b/TMessagesProj/src/main/assets/emoji/0_362.png index 8b8f3e5bf9fca84dfe44b54279c2593000cc2771..fda07dd22e0c74b050cd92a34f2f4c24caf4cd00 100644 GIT binary patch delta 2023 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 M07*qoM6N<$g7R<(E&u=k diff --git a/TMessagesProj/src/main/assets/emoji/0_363.png b/TMessagesProj/src/main/assets/emoji/0_363.png index c9f2935c62101363fae5eb32ea525d4ed8e05d9b..6c6d52e833d5c91061292bd0824f0802cadd55a4 100644 GIT binary patch delta 1699 zcmV;U23+~*4YLi9B!7xfOjJcja7=zuF`8#deNZrQM<{hlD|t;WeNr-YNh_UaPGmeD zU^yJBa#vY27;;A`g;+O!QZ#r?Es9$`lwe7c4h!UqP^L2w`c$4*cL^69t=PQdHeroO_{y=H>2}3OOgd9$?~_i zJfjy$lBNHQ$$wXgltKutHGGwPyX8s>O%aP#{xbv2nr#|Ulp=i=odf=32AB|B>enDMEcti5OOi@UnK_Tb&MxM}k8Yh(xSG=n` zt{#!fD}Qd}3mQ)YX{?W9HFM5!3NeJp{LcgeXw)MO{(q_Ky1^eYoG4UOvi{MB!~-y{ zfpHZ2-T~1yG02d@SKogLd@;0R-W?sg6 zLBbrMz&!9TX+H6;c^Rn}BJpUQYU_%+HilZ6@$(aW#7*9c?mw!+Q7uXRhgNRk^W@si&g5!QLfJ(UI|J#(GOvNbta*o+a$}52GruL5-BLjBfKFu$xqbgUwjigOdij5P&@* z!RQ5kdf;Q~3AR}W;!y-Xl_&@kCPCvPf(_ApfI^6%DndW=P(79G*d|ytS>htwDo@4H}8C%4kp{3x%YZA*HI1kU{r`V;zx*z3{>? zaMR1&*-AT}f-!L=E8qwFosWS&oytT-Np@W$(kY?}^+ z5ryNi*#AD@+F{fZ3=9#J3|9np#31@!Sbw||R^%s8wrz#W)c4R*Z^TD+g-_Wy4hmKi zns2qamABhBq%;MLUxPR`S zMti;N?jLydAh~U6qsMMy65iA!Q>L{oyBy$7$k808G8S<;-05oFAFfSN^+pZ@eq6+) zycz020%7ilKs2|*bsuvLusR(MXN`n&uFGHl9qIUhL{&|P!*qoG*?nE$<}j1f8LvXV zzTo{!3xwuUZeI^wX(y$V23G`(4}ZqLe!;K1J{x+4kxqU60_y_p1VWl`$CNEMoCs?# z*TeL2x`1#lp`o9j_@tjF5HIKHI-RX2Odn4eaZ!}ieQRxLPv;BVI-U3U=?w&Z$BWZ+ z`Lq^^!Wg5LZ}a4vPU@nCnP5)z1%%4_?G8u@TbACnRS$%s<(L~=Cuk-B#DCZxc6HI( z*H3bqhtb&_2oEflF(=B_Xl;;)Lh0v$v-oWp<%?0;wuc6luY$!Qc>43SwoEwdewGoM zvX6vsreNJ>cAj6avV|7XF{fX<0gc3}TkJ6+{?j@sr79knyoB{)q(D_6M!F8-= zy6DkBq@DPwl7(;?9EQB`L5=%g# z0b=#GEP60PQ(Mi4p^?3x1PX1j%sV6;8H@Gv>`Vk5Tk>}>pb$cEY=2lxFZ4?o;E!Zz zq+w6Vcm~U8iQa*rLXg2&0zjzVm-IY^gC)lzC~5c~Ks-n;-&;ZgLjdL74@sT#1QkJ9 zaYw}Jx!HO`USqL@kc^|CsOV@QK_6rhd2fFJG3$&g<%O7Z49jZ tt2F=doaI!*Tv_M&avZtL;jRCC{s3UY6yJ}Hd6WPE002ovPDHLkV1lJm7L))0 delta 1752 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 delta 1646 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 Hu0mjf&1sp~ diff --git a/TMessagesProj/src/main/assets/emoji/0_366.png b/TMessagesProj/src/main/assets/emoji/0_366.png index 2038d28fa314241a87b5f24635ac1c0bbc0fee28..54618280f0aee8978601308dfbf51b3d41668cbd 100644 GIT binary patch delta 1850 zcmV-A2gUfU3ds(TB!8t)OjJcja7^T=8R)DU;I1&{sTks?8Rn}SaHBvo*Jod4V`5SjaUl8hZD_`7Vx<(wtEox z*oynYB=^&I|HvuzyCC=Bt@X@jd`t=d%`fr2Jpa!(`re)O$bVS;=(_#w$@0QVX*vb{ z`Q+Hck+zC7oQPdkLmIc8Y|f@n5Df@09|?YHMT>L9@Bjb+5_D2dQvi-q``^E#{TnuS z*>!2DV{nAx!zYIT00u!xL_t(|UbWZRRvS4G2H<#=4S~#PUwU7>?*`ug(WXjLhqj$$ zhKniZwmwh5zycM=bFujPlGAe;AuFYeI1w&#)Q~*yWOs~ttDhUd76La>MuVA zBfG7Va=pP?ua`;HQZgC-r!2$ictk0oZMIwk(5rRQ0`l+iCv2N#E5>ZKEP=R1Hi;#J zKL?o&$g13|mziY{!W(zUx?+?0pL&?s1eYz7mbF#ljemzEi5>sGnJ2O>Q7D&L3ymab zAkryl0lD1%)_5URH+^WtuCfFWP=M)IS%UHFUWOzKLJ2nzh;~(F86th9gjzzM<6q5m zHeUIdB?wt%32nEl$|K02(-oMBo&JKDwq*c7$W|jx@f&mHlSCyzs3l3pULJ%w$>Ied zL$xBBAb$}MQ1FG2r$EfMkF8AGB>GvkT5Y*75Tgx20ErbPKr1?U2!S`C1GcS}j$1Gy z0!*wdcvbZ<(Sh|JRRL(NlR~p#__GR7EYHBY?Olx7xW&&pz!IT^FcvB*9zqK>SX0YXD@|c{ti_@oX`yN*1y3nt5|l`#qd-58+7t63 zpaqh1lXejRSm1vaqA2AoHs*?)NXdi2K7WY;5PlLmPt&kJ3SHR|Hx^Rm1uS3!4aOL~ zC%6*0AOedU!g~nkco8b32`T0`1eJ=VKr|`kMr)G-&^Nf@oTY$Z4yha`4}?*sDBucO zNGY_|?JZ%Q6G95dQ!r9I$(q~{j1uWUNVQUqK-YJD_%?FOj8KxNX;E+~_+1L-B!2^f zN^P432*G%)oCryQU_y}o9r?kSmZqSEpM|f7{iuddXc`IHBL}Yfy(Qr=+NDYmUpTu8jAbg6391oX|kIUhj-h>z(E~nGwax5B8;0D5)zalYd3Z?r}KXO4#uYX>}9*T zocATXdn%7fd;A#vDeF-BAEKi}P4(?AGL?VuZ{Wn2nFu#>~SJbR)RhyA)sQGa3+SUY*x zABsRYLhUdT^AY1hXdFhG>^G-(D8-MP{jxi1>;2~A4UjWGuJ=oy!a(c2lRBl`N#}`X z39ENXk6>+r!m5i=@01%IA>{%HN{|Snh%t~bei-Sh+#D{KYq?zc@AD+_M?G7Ym*eqT zZjvUB!f8I5_kNE6fhP}$Jb%p>RhF$5dE@u4eK$?stne>`YLVwTgzyBp`Mo@FVHiMQ zb;l&n7fH5A(Fg?q5{z)8jhXj}nNY$R97ZSj^O|znG?eFm2?Q2DrqEK=lJt!c?Ck1nL5OVtAwZD&ew?qbLe(M~p&4681+nfe1ZlxgGd^-M}V+D zJeKvH?_-8VqkHq)$07*qoM6N<$g0Yitf&c&j delta 1306 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 delta 1996 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 RHOT+~002ovPDHLkV1g-psjUD2 diff --git a/TMessagesProj/src/main/assets/emoji/0_37.png b/TMessagesProj/src/main/assets/emoji/0_37.png index 7ee672192f39d6b88b1a2e842f6a4dca474d4140..178a1056483e14291bfcdd0bd99869a7c60d5bcc 100644 GIT binary patch delta 1493 zcmV;`1uFW`3-1e%EPu#p1<7y_*nk<%dK}1Y4(@~l>zEG2e=)^-Cg+VB?vWJ8Y6!_} z3d(N{?3Ek+uM+>xIsfD~|Gq5$>_q>#CH~n-icbc2J_P@v1!^(^t9BQ}h8LA!5Me0* z=gB(%%q{=48`ygV|HC=|>UhhoGymN$|NYYUrxeg{1M#2{|9|6N|MXb@^=<$9tL3OA z`I7|y)-nJ1ga7!K-h~MN{Jy!8C)S=H$JZ8`?Qch->fN(cE8{6^!x3GqWw11QrexZUVK#1 zXPvh4JBrrm%-HtHWMZ25AffdE4nj0|qhn${vTly?=U+pI%(sw%sKYs1rpVCI|xvonk~` zI$lAN0s1uy(JW|jno(XBesPP@RdKp+VhF-kQ4G@+y+nu!gC}xgjIoCMyLYy2z^ZUC&Bg5mf<+}l zmkiO&{-K6k6oF|H(Yq7nFrpZU0fQ0OIG->qi?@7|%)nXYG;gQsqBaJnCd$A)o_vq4 z7Vjh9MyU^g5vd<<*|L#4SDcjdQJe<#l2GPlCqvw!z8A$vZCM0ktn0>1~(G1 z41pKXybZeI&z3sioscmuPfo_DfdESGx|eD_BY_t&z%<1$1~*;?jBI>~qRTjQ0Z4H( zEMwh;P!&O=kUBvb+$jHu8bcYNLVwC-E>IEFhe*9FgBjM4#b7^>=tIO}0xyDJQgKaC zhA;%e4fcK#Pz0`r6m?Fm-0L7jjsUm-;xw4kFy%6+6>c!(B>04hOT4iTj`;B{~VNbF0A0m#CjrU*c4MHoP!B!B5$NE7Vm z00}6fAp`PNk&W2*MEsa4kOZ~$ifF044njzAwpYCHrk4YNHNk}*gij0rG%i>DgpofiUy7(je~1>k;AzI?E%*D3@G z&#eja#DH2IC43o8tFnj>#9oY v4<5MdYVRHCsdYvBizj!=zyCMG-_!pCSKN5ALobf$00000NkvXXu0mjfE>6rY delta 1462 zcmV;n1xfnv3(yOYEPv*S7|3Y_$7%@2Z4S$nGXNHGUSj9*n0%sh6(@fKhSRjn_vrBA^`vVzxt>W{;w4N)kXc61pnSx z|L1J~_l*DhtpEMe|M{H%;W7WjIRC#2|KUgf^H^~?1Z6G)|9|#<|Irfv&@R}%H~;o* z%c?MrQU;}L5C63v|GFvv%{JECu3jLI2+IZm3bRkft3}Yjlub8K~mjv#o87xK$LT5nJnytK!y>mt5>D z5^K`B82e4AD!rBh#?Z!?dBI*;laRGoGZy-8N6AYi zo`V4;v401j^9r;Cq)=s^+y=jBtR2iDFdya=*b5j$KXFBpL-1AuP#i!K0l63h3T>b> zJw~CFkQy1x032W?gq={*1NO;_Qsk%W;7?M5q}M|q6#Mh}h^p%vj_30p^8++#Xl{9Y zDf9*AkU$>*$#I;f>2-*Bou;?(2&Ep7fmWy&8h`yvCECa#zmKQWIPO=&ehfP&tfQiB zTbSfaG>7_8i@o-!2}EH4ZU9kQ19IP>{kCL_iG z^-P>9m?YlTuo8y_V_Tf7D8WG}-b|1|vB+YGz(`E1`AkHWC5&1Oi2%wV5c5(b%ccft z1_afpjWP;C$VLENDO1}L(J4y@IH?93BpQ;Q3~OO2{0vCtSlC zSu?b7eQjrw0Dyumf%_rxij^_x4zAxO76HFj1(%Q-1rpXU`0gzr!nOpj1{;jv?yi+s z04qod*_5>b2rCj$N2)LjvK^}x6@w9GrWm=A8ixtA)$Cj@f{Hl!G9e%>+}+1FRt_ViAe7+209W`p2hS-;A%~Mufx_|r_#QEE z5dj7vte+y_0`NDtx}FPNBrlHZ?e?F!;r4vrcYWXc%ni3dnE(H8hJUAj0tnJ$o=ypS Q*#H0l07*qoM6N<$f&~G$q5uE@ diff --git a/TMessagesProj/src/main/assets/emoji/0_370.png b/TMessagesProj/src/main/assets/emoji/0_370.png index 775b0107b366b6dd3bd40372888951612174ac22..9e086259972ca3a4f5325e12287b1774c6f6d606 100644 GIT binary patch delta 1509 zcmVirey!~?}#h7#6?1?dz*MXGx01ydTKnPn*FKv%GfJEO%szNZO{Bb)0Jb{@K_Vhcj zk*Jars&1?)LVtdKkdjG!P{0r!#*$!rc967_y3h$Tt`vQCnHb1tv=byl$+K$GI`T_+2Zm37{{KJRszO9F`7r%qUt=GdgePxZAV=q< zmcYOTaDRbd>WT8e*tC!2M7}mXofJ&T=zKy(R$d#tM_@+mcS?)4$Y>@+#TXNYf+;JU zCsHUjj>)*5*Ew{H1kD*|jB6Rg=6oH6;47lrm9!wxWrzj{oRJZTra&SLU=%kS?$Oq4 zZt;dkCLn-r1(4uSPbtZWtf4&4$83@bDNHni?SCa8oESoQXm~G5t$Ne>z!a2=3uj^Ug(+ep=DGCfFkU`obN*El3-%WR4g}l{L zWq^xIMXX@}f_y{lk@p922*wmALI#4oAe=Koa3-Qp$%pXdeYF8Y?mWFg1?NhJtab=j(|GEfg`G$NE8?B`cXzki2$UlBXapTCp)oR}aN+64DBsx4bx>*zv8 zh<>!c#=)iZHC6_*!{@&=YX>eeBD$z`TU_A(A!fuhM2{}KoQCRR7^Is%adub~27*UP zG_MHCryVDsP~I%#vf5ztIECbCb{cz85Ylv8I;o?j0mL*8kr0~0uxGiT!#D&28-Mt~ zk`cHNBFf7*2(_|SDEHyXG+WrII+for?v-=S^WrR^!FmC60 zwtepP(%hWcd0CdZ=OCpFAr8OGZGR|{V24wmlQ@{@IU@*4;8v$N(D!AJxZG2Yq^>3c z?t7uxPKZDg(fj)WalIuEh}A}w40!NXz|KTUv`?$fX>Vhr2pNLhGx=sB`SXt>!Y3Es z*x*X>KTSw9;o3hCDO3h8#Q@b&B}5O1?gilz+KBb+;(C=Lm9twA!KJr|YJVf=BP72m z#nr=VBE3a`H6Qm35q1QAAke0DFX?RCmKeFRIT#*Sf-~SD1GX^yt!t9L|!R?Y~gnLs|Ve#i4q~EG=M(I$ly00|KWx#|F8NFU85JQuSvOL00000 LNkvXXu0mjfQg5`< delta 1778 zcmV*>D-(80EJG#`QZE)+G#g_;EQeY^ODYqQV@Z5hKs_N0GaU_VK_Ox~9BfNBbx%68 zeqWnvP^@-aqH$M$Q7?5!D5QXD`}_Lq=Gw1|b;XoyBnkt#hJRztvXR!yxxI~NzMze_ zmV&E+5>FWb_aj{^0000EbW%=J0IS*BiK*WpYeB~P!|r?c$w~kK1`|m{K~#8Nwb+Mp z;z}9?;5#fqFxMS}au(5H-v90PKiw_FV6S)XR_%eZt0eUKbO2QT>;IhHZtt_({V%{i zS#MUW)lX!*-G8n&$^IWXyY<1;!*F~LIUa|hHfpur{dxUueLTJcc%uY{l-B$yl5F#m zE(fqAbg9j1{|6N|iZeL?cnX@dMy>y=aHwmRiaONzjF7R}eJ`xqqj4!KhvU&3Ps%$6 zbJ%^~;hl(cDpX4d804QAo0_^BeNLTJrfr7dS%J}hXMZH-2!f|+$_lGY-8M}{4uV0& z8s8XugM}D8;doJ6Ye*rc8LDMe!PtCF99sVZBT^cP69o`O3Ndi1Fgr)T$xQN}hcUED zIMiS{836&~odFC8+GD$~*0aIs)+p|rqZ*nFLP#OUL(%bs*?d(Zp6fVsj0i?X8I>od zu8lIu=YJA)3qYw(GfJAmC}ALT8#stk>eH$uDxOi9){N_CB=Ceo@*^7wI&2bcwT-& zWFhgA!=td<_I*bQ;}At@{cxqG9fHC9j>u@J{eN%c=*a+)p+t#IiIww+(|JeU?+Q|G z9w##jVI~So0QPiS&q!t;5gD3f+hs!cU7vvn%RwbPP*qh#oMRjaDR4YMDQxmEnOPt* z&EhbcOLeI{g5gj%LOKP-mUp8+EIYFg1PL?@>CX7vx*%jUH4rJ%GZTGhDP>OvQrt(f zSASU!BV*2Sk*3lbW2Je0eGLePqr~~ls3Xr&x9?>}M0OuZ(&afBf&?Z+(KglP@=8yi zJ7QId5jmy>{vZJlYqIHcAp~bGby}*rsa``)r-($wkBEnNF&B9*Wj}B7Lnb)a%TH(?W)4Y#TQTgu#lsc$=mig6rPK zX(4Xoq#^w3uH%gtxB^d+cL|6W?gf|X(p0x;9DdOb?>=th_;#8zjbllN(~pm7oQ6^o z0Ym5g8VizXhk&S?6aBp|>pwnT$A59WJ`%SKhp*#wZI#riLs;H#K**V3rD-Y{6<$gg zo$k59Xg?|lRV2_vcp}MJB%D-jb$Pu~S1LZC!(!ZUXrhCcnLu=Q0O99`!I7%2E|k;t zitC?(gMP2qRx%K%k>eX_Etn705Ew~#hkgRE!Eg#hDbhF)CsrUhW15041%F0z3BZ>K zh{hBg9T*Uez4e0w2!^zE10ovK+iNokVV;WEoJE5Bz$`G5MQBj!QZ;u2C1@PXh2oT# zNX!QF6AB{|rD@w%naeD|Gm<-u9U)>5f+GAkF>@Rfx)4>#g%q-WBx);W07ef&kbuCT z8t6V3ztoa*sjAn<5`~6<>VGgYPf&6MhJLD1D{GoShUGvB01)uV5+d?B=;4G~76nEH z5tqm1FfvvUP!=Mi#2O5X0^@=kr&20oOH;R15U?Bogb$Q_O++>)7~0lkP~_QvoNE7( z#+x808H5~xl5apf8C*r9AmV%mbY|uPp*4lp0G4D#Y&_5}h7+@4q<@rx(~q)w7JO?w zL97Ab5eT890R#(T2?Ri+hys8mAo|`5u}9cpxWlNRRQJ&2O122NqQ{RwAkoN!!3qQ9 zo`#l335OCr?0;&aNp*vd7imW%qUd`s%WO1Ii9+ UURveC%>V!Z07*qoM6N<$f`$by?*IS* diff --git a/TMessagesProj/src/main/assets/emoji/0_371.png b/TMessagesProj/src/main/assets/emoji/0_371.png index b216028517c5ab7579ce5b41dad80ce7eccc8b00..257d49884b27551ae4793b2c64f8e09b8518b327 100644 GIT binary patch delta 1469 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

    i^YPepqe7xGT0TARK_xX3OkUv1{rPZg zO@DVGnGd;iO?!cZZO{Eh3aN6V)zf1Vo1?5U;kXYzMBpeUVms@E&6T{NHnJ2J{{`1){Uv8V4@tm;d;Gv z-B?VG6l2$2uGgU(OSnW;aIyY)B0iAFmB8DVpN3&52&bhF7_=;4@k9k)0n==ZiJpi+ z>n5%%$vA{D?!OvupTU{`?6+^qs*ZsOpNLTFB+|{8-^n=_-tYr_W}}b6iqzyoSDWBLwEw)moOWM zP?CahCvX(acILY%j9?g*Lc&*0Dx>qN%4?HTUxXWlPPP#UGl>%DWGbVi%CrrnjdM;Q zP7o6MfG%dUNqi@00797iFpq0V5r1&Ql&X%CaDhm-vG!&7UIt~)iYf|KZQ`kjr9<(pph1~}VSh5heGRgL zBK&>%YNFn-=gXOYVcRg!#*1tw!|ik0By8SZCQ58Ccfj~9n0S}I{Un=h6350EZDRn~LJ2=i v7;T{xpKTQW$A3R;qTP14iyAiJ-&*(=oWAIEgD`zL00000NkvXXu0mjfTCu1f diff --git a/TMessagesProj/src/main/assets/emoji/0_473.png b/TMessagesProj/src/main/assets/emoji/0_473.png index 2b4541beb591a3eaefa7dd4c57314f0c5b035949..767c90fe050f2385d259d8caa3f633dcbfac8d9b 100644 GIT binary patch delta 1542 zcmV+h2Ko7r3YZL#B!7fZOjJcja7-#479|)FCmR&X%E~7i6vxNMEFTwqc67|l%)`UO z#l^)X7!f2H5+N23nwFGDGc8s@H#a37LMWq<@(q2Lgy#3AK(b&Y5G$ z0000GbW%=J06E-@+-HXV6|FX4u)v$iATiZI000FuNklv>Q)8dif6AWhN~z7r&ky%z>g6-krd#wK%cc##%& z(jq=TH>6pi3s5Xa69uAf6l(u$I!>x-iYSUHK#Iq7rhg1~LmaCZPR~jSVCsq}jI^SH zod6*P#UKNrFvdDWo~4BjLzEOKm~$_M6q+3C+3=DqRYe@3BhoQhGRI_b4#$(m?!f?6 zhC>euvY-Z71fg2+&HZUvN0Aj6FBElmmuQl#%DFjKeLbg%(vYGRbzL*lf&wL~z-n@U z3IYR;kAJ9CZ#5NZjEY`J;n%g#y1pGl%0jaT(AaQn+c2br!AenpqR@k6jFF`lvg`(9 zOph2~=&BOmGCF>y2uPtKE?EgMDTVMsgurRerE`k?aj8(TR;nd~wcJ|pfJll79}hft z(Q`$LD;Mh^15j}QO(mNnnY80;MLfdC?}iEP_b2smaB<6$RT^Y;zs^%|6Wz7}HL#M29$Mlp70{1fP#vx5Ton7|c*UcC~a@S;Z|^VVcS&F)$*Ff98*9=D~0T%4ir3YdQx1ks`#lxXWU)=&XSHXVaJv&6dNH-2nxnk zqoow^+3!60xlL5l3t9Wu@3BdsD}sl;^dINqxE0kn_|SHvn(=xCL(!;7!J{TKcz&o(y|#-xb?5t+T1bXnx47wc z)qKaG#cj;MnOmLp#rMBH9y#D%>!ZT*^_Jr-0KJKd+V^+M)hQ;0<%Ao@-4B8z7($Zb zuuvSgs1Wnb7vq!zl!+&fp*nxs3gA_z%B|}lk$|;4b0~KG#rDC(KA1kSN z#qc!_k(8pE)lp*|E5~k&mCR#E%!`vG_>`g~#de2=H3v{ke~RE#RkFSSVCdjAcM67e z{P}p!rmpXb(hhB;QWdtw^rJ469t|(25cQN{)s=e;)`eMvj<=;SRFI2?GKUoJ%71W66dfo*hl7-4poRI4<8E@G#4%-{iFgk=P(n;9xiGxV zfkEUv0TnSB-g59=5QM=22#nzGCc|4cUo|B`Bpf8Dw}+2ka6D{lXTdKFP;V*1?cSWv%bbNKVM1-?Fan|~zu57dnq&DtiD?*IS*07*qoM6N<$g8t>$VgLXD delta 1276 zcmVUZmA)IABp=v>%XFqU3D5QjG!?UF4;@h&Eh57sY-qp)7 z8xbE235jb}uy;zkkPWGDMN`sOr~m)}3UpFVQvkNluZdVg3Bde|Cby|-O$99&T!`H{H79c?5`xXgDL*`%TqOVd5S6P zruy^qPZtG!*L`8Su9xa^`Xi;PFS7f(f6G^|F7?MqeSvuXL6MjGBcM6S1RT<-Q}uyx zX|n#VV2%!|MD#7FQ=TX_ z5oAQmkU|@WU%m)k=ZerWG(yHPNoWCNW*W6o zTm>4O-w560`rs-!j4;HH6c#d_RA=r3T1JwR!ge6!DSxvb@|%&MXuc8Z$2DmT6J#KQ zQYOGvB;qj5AV3O1aR;-sF=3hP!0w#e4H41k28Y>qG&FUYA%^fr?*#OW=M@n;Ls(4& z(BPGXj+L&9Lrp2!duE#uCBn%#H5BJ8}Snp{V zc3j8nZQQTU%p*Jr7-#R60at2SN6W-uhvqvm7%zy>(|Ws7oY^MzB;>U1yw`uNlSX0? z-W&-t1VV0+@N(Or4MYpu?3lnJH>s^fVmJ`ZFnH&YfO(yq+pqp{U+3;gbn|+1I3M+x z)_)nO3MU5teHIlFJkMob7h~b^nAa^4+d3;_ACG077iz>i;R^;*ibyEkE!#BSmu;Tz zuW`2bY2KFmIBiR(RV2;_;^Yw?3}0Gu#N2xc{VO2*JM9Fzax_lUc~KsSIuKTc|9HNZ z5qNtS2MLn)D`klgqCOA}63!1y#5)=b^nWzH03d_LlHo`<9;qyb2;h zX*&>s(>$a^LNJl40Q4wIz7sqOhkYE=6jU4y<3+TVUefq1ns0N^D&hDpCY<0n mQIyU9{`%ouoX`L9)x*D3^R4=OHeCV$0000#`!#ni=-MF6OHq;;0_usUhO09P6+l z+ME>Mq8RP8C;!bc`oSmkyCv$c9{tNU?X@NL!Z82ID*n(u+@Kfy)n53=Jo@Xg`piuK z`PaLMBB^s0{p6GW(L?;$Z2iWK*;E6!Zcd1HmJpg zHtT5qWEH`}3Iv3f0XIQe9#5VkEZ13vh*sSVVzWFMKPE)WvdjVlDEN-baDYnpkTFhN zSq4V0Fxvw_F1eq}BvEDFF)rtq>oO>x-d_uqg8;G4E`PMf5dffj>oPKVhZxAu4~oWj z(lDT_j3tb6=>f*5_$Fd*TEr5y#>>C@cLbnr+enOP5hWlxPOqM!#q?%N2n`G%+>%p> z&|1GwZseh*7C>m;&WO-$rO8FqWIVvl5aC zGR825MgZ}4wKHa^^axrvO;c;vI`G19gJJ56aUY@UnrN*lF~3PLkPhLxHcs6`2%}QU z7*+#ctp~*{V+J{nIW5%#gt5#rU%3Aen6=y*V}BLUnRH^}*qE1FJA}rmV&-?9mf38iifCI84KR$eHNGRugXk%(5 zBIxdPIu!e_ulfpnN z;(xT$N>Ix5Y_LHjxZr7B6x*-wkB{%&vC29Cvw2l~ezf6p!vP`E>A*!wQ-~jn;_&qW zi27I+w$Ee(2#9`t61c0iPE$%|gPop2Sc|NHMBob>xu~i&G8A%(s@i=+xRym#2nmRk z437DjrUVdbQ5CzUAtJ8=0+-b)K%5|)ihm9_O? z>VE{W8X@Q`h+`g7U-^JqOt2o;y6y;xF^dc3jQ(#DL`)YzG3QcuS@ntnI z3oUvA$IcvVj=`qafzeLmppFnsgnvzbKb4lj2_bc}YihWN6du6CY5GW0+1l8BqPAQA zanLORSK|qW5F8-9`TXv*C7}@V?Wu=>Nvwf^5VAXLL5D*lEq|U6eDJ{F{)i^hTL@V^ zt9gVzJOxo40pQ^s2v2MLuDLLVw-P8id+q6LGK&O442L0rCF9ZSkC?MWLoPPniHKeW r^vCQpi9ks_I6z;aj6qO>ze4{4l8C+1O&)H900000NkvXXu0mjf)aP=* delta 1128 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 delta 1561 zcmV+!2Il#o3aSi{B!8SxOjJcja7-p6Bipl*Dkmo;A|fUvBq=5)gJ)HgbzfOdMkOL4 zCL<#&C@8O$fbYz#DJCZ9yO$v!ABt&KCnO{wA0O$umhHozG%qeJC@C2k8t=)bL_Is? zt%olwD?2td4-E?S@$OwoJ;GgxIUJJJ>HFqBlI;Kg+mtcYh7NZQRLnz8H%ePv5L&0?M?6n62IE{4W60^-N^(@r&XNn91)bi^P%z9~n5iht!%~;VS0>2nvWCPkz{NZNg$@Ol1C%Qlcq1t!zl* z9I0eJ)1f48TfZb>IP69C7{Z>{si}~ZNs_enR?rXv2N==G^a_^AvRKph>G(F z2Ph+IlVl47w6+&ks=%}aLFp7l9GpQC^Nfp?jWDgKqdUR~FbhoE zwT)9kWLfnXhpNO_8he#)w5KZBJR?Y)0CDniv!HUXkMQ*n-tZKnlCa@EuTHvUoS%4> zixNwy_MJY$@gc7ixj+bKC2ZJx@YEpCiYj0SBdeJ^jIcnpi!)Wp^yx~K)YAwAat4?^ zA%93@5lBEV=2Q8!125J@BOrDO&gbieeMLBz>-ij9SfpLllss*~FCL}7MmP;(^YDCe z`UG}4pG7XOjbjjm`Y#rN*9LKNnucBqndjGr^$5*X6xTebO~dXk0{)fp+9CJ_k;gNp z@7DC%5j8SAXL;B3M8)f`2uI%17|6**zH1t_jVkSHK2GJB5vSNh)bv z6mX$*`)GQFD#jb zSU7DKdJ2K)OZlM)UlE0O`}q94fUDNU7Qv1+t4Za9CpHkgVNQaw$yJEL9*$;s3<}pDx?MiA&tCEzE;kyEtg0Tg`FnARNb$Nrls;W8w zKP52;v&A4{3Iw4Z*FLc814yabv2bPk5hjv=Dlk-Lc5odM5>Ku`i{41a;b7z~V8 zAOJD;m%JNl#E;0#nguA%Pjv|D7}lH`Mp_=hqU60NFl6Z+sV0P|V?=Ku z7?2JW`^38$z^!ge1vT%I5c~g_mR%5$gw&W+R{NgkSEt>fP1UI3hm(KC!KJ diff --git a/TMessagesProj/src/main/assets/emoji/0_477.png b/TMessagesProj/src/main/assets/emoji/0_477.png index 1ccc94a6df19e537fafe19a31df22e0fa4cf6267..9a91e270066e8fccb8a643bdfa3271edc2464beb 100644 GIT binary patch delta 1283 zcmV+e1^oKG4VMa#B!7xfOjJcja7>L`MQTJaidjQ~RY0C+Pm5YahF3v?R6mGVL7!+) zZACG%dtJ1DU#@mrp=(m6ZdI0JN}Oj;k6uQ6P&sTwExwIsw}WE3h-9jASXenC@9^#3 z)yC1ouIAy_!jWkm5e7FR56P#0$+D2CmVu6SQKV@K#F~1dhJR+`tscgeY|EfY&6y>{ zhze1c3p4-#01R|ePE!Du&cj5u-~JwM;Gn5CLgxSg1TaZNK~#8N?bg{=+ei=wV1#8_ zvU}gOdtV^S`@h~)wM1JP%L`o0P38v@j&k&!zbdrQ%YT*slcjkw$0T{0eFsSA3&|NP zFib9z^s7KVmw&Va>hD1UpcS?lFSb|LvLfok_ z7dn>cfzi)ZG=$JPzxgAfkq9LsP(pfSM5x&fB3BBCD8xfHC}2dwq|-!#gp^STfQJkS z8xc1qnHeCkL==3?zl~&i6>mm~NDRUnGax`bSVl^)1QNaAQ5Z7xU_ewok=-Ux;GCAe z48V^NG=J6}7fJ`>ZIZ|bLRsgW6`=#%9X9uV4EVwAB?V+SyX2xs9ku~t_= z=o^GVf+$XL6O@AR8L%kBbug|>XmO8_oYSz&ONqD-+~?y#gyd8L#ZVXpyh3U%ISLPm zN?3C|Dx*9AV?z<6j>;+l!VMx_S{%f)h(F*^q-C3+k}9tM|?3*gC6}GDKWG$+K7MoKeah8oTX|n@!#A`9+|Irmn-~wsRy9 zD!(F}b3|LSTGboOY1h2_NW8DwEneN8_RYZ=+zUyri5hr&7>MofUDK7HLb-1S;x~L} ziGLx4*!=3G2SV)I=6$<`5+7Z&ivO>^ZD77F2p?_J3WEf>dg>$=30ZVadpezdee9a1 zIU^CWYMRcSP9GopW_6Z8SaN+za$DC{RlEe_=dYi8yvctO>pg%ST!w!lP3^NFMG zYHK8=^xU=Ws#$eA5Mp*Mn5(wk`+`ZF1AiZVQ_C=dvw|^y-kp6}u1CarectVMKf<$1 z0AUoYVtN@BD@q6+v?xTyL&}0`Vu_x5@};Jqq`*@e5{YQ6k>JW&HT|o3PN0V7ff(BR z624snIX>@_SSzQ0C1%O;)tZV0A|Rdt2vbo%5d9q1&2GOy=8g!QWN6_z(G}-Lm4C5S z$tvSsCo9Cm1`E9q3|0&g7owoTy1TDAsUz}IV_gbY*UnHsE@7d>y)3Qb;~JU}#erO- zFq8;;xHrnMjUMq7QsVs(5O5RAhp*rLHvHNPt%-BiSR0B2fomM&QF5X=!}ou;*<$Mc z&k6-92ndgp^hU|tcGEv+;BQg}!F;^JBAzkAX@g^8>ORg^zJMu&0^zyjMpP7$aH5E+ z3aG%id|E)`O-qglwrBkdUnR^kdwD+DObJAWP+kfBmPg^)B1#NzumDJ{mg&n^ljSo& tFxVgg;5$k4*&Ae*zzE+@26_2Q@(+aBygp8lNCp4^002ovPDHLkV1nOTP@@0< delta 1709 zcmV;e22%N#3cU@GB!8|@OjJcja7@s(bKA*)+R1>(s%*unYt6HA-_M81v1PfOQo)>B z*v5UpoL$bhZrsa)zM5I&){oAdbi$`x*QbEdyl~m9h0~&Y?&P8C;GE5qYSzPe=i8Rz z!kEIBVxoLUx0GGZ$iv;UjgV(G5)KH+iC<(o8}aFf6kij)bz7e)R0AURzjqa&5G(royS0w0H{Ew|z^3?*R*0w0Lj&cA11+Ga%K~#8NrPzmdn@SJ{;D9BHnzzuqdatf|{};Re zEC^yGE6%yUEPp45qy0QHtYq-7Z`17yJzp$8mt*A9M87H#$ED zy4sT&`wQfS9teH&nfau3eh7@P9?M!GDIWEIfEWba54nNf@BXEPzS#oW%7TrIhr&~g z?jPsH*R=-(1myo1n(3p4zbDp>?*v_se?a&_z()5^On;vRy526sU-%-eJ3`Q-OLRb-t>-As5 z05AfOJ7x3(A2Ee(+g4;U7Q?BUZ`M;PLGQPP?nu2fQ`fy?-jQx7%&DUazyAa8xmMYRS|gI8oGTkHRFMIe9ocY`5#le!rg(qcgl~t1N;T z6FY$RVh*CKEKc zMfO?bI8OA`-WAlL?(DdfuIow<#gv%=Yh|4|cYg^8kuG)~1Y`vUP7PID`OGGY7~T*O zVy99n0U6^-5-1h!T{D}AZwMzs9}NMdOo^3XNltd(5+bjJW-$QDl~ag&$nFt+8nVr$ z0$fbNgVR7j=$NYz$ukSa(;dP})i6Uk``DlS&oX$nrlVO(gm5Zth2*a^N$~~0H zQ>;yrah-Z72}xWHBejKNw1|!+Ku8c+BRycvEGr2IB{&csPld2wo)Y)d;K0``hbsx;z(`Ya>IWC3sv|ir_^t zeLpUz({sVcb$Ic%+?=P=Wl`{o2>Dk-<6JmIcpsa$DOE9@A3xk{6{`=RZ*Z4yn-8yS zgmbM;SS3+xupU{?i<7+eAx{MzQ$)c*qhRVQPW+dRDu=Q0P3w)=EyB z_xXJPnIAVNtgVa_3>@6OZ%&Ep5|M_z)>$2b@Q9E=ip%-^bV{n7rJ&?=d_P|b0Fnp` z#B*z33_$!wBQ6E|I~ltxENwPMb$^f|OJdL>v@q56kheawfHbv~A%cgFn9&Jo%`=S{ z4=bWUs36i-jR1m2ATZ6=JX43ElZK$Ut0Yi8)hYY<9f|fdk-^MjF>g9S#*(`Uvhw8k zOA(&wq98TiVOGV#kh5kGR`7m7cIA>}ym znQqwzfcu?9F^m{JCkrHCbbn11;c4R9+)vORTlfq`ppX0M*eC+0p%qSKz}@FquJ%Pu}Gww zs1qC0Zcs#QMpn=G^*BaPL@<0xP~Duo;D6MHPeoM1<2tOXu_&X48&G1?X}WkkkH};& z0;M!JCp61v2tSF|b99C!itv?1w>6A8+Rty=2f{JqxY{5H0cJEr2|rI~&~xZk!bhqd zHPrs~?+;yLFtor>bS7swFdhJp{|GYB1_RCLJX-%B5qC2+x#l3R00000NkvXXu0mjf DWA8{bXgecpJtbZ>A7eNnSu-79HXvX&Ax|tC zeo8H7J0y2SDsMq2g-|eCG#^VW8XFM@nSp6E9T1jZIq>oBj#o6|-O$m*t-Ps>o@YMI zoHnm?2ji_CNVjP70000BbW%=J0NcXpwnLT+A#K+A1>W!g0Dl9wNkl4)k^qUoSJFU`=6wq%lL(2j$Q;@?Q>>I>4T+LP6;;*m z5DEa;B8Vq?tACm104(!Jz%xgZRizaO@S3dt7_kb5CpNLxeO@?f~EDT*)^d_iI5PRX^|OwX*4Ij z^sxXsx@3~)PPE43&cL=PCNd!})FCl)C*@;Ag~SlT8h?->2_Y`gcpa=e9naL#=H@0x+U}bO2U@us+Ne>x|wo90a0- z5S<`SZS%l`<3^mHCp8A|hhWzP8)n1hFnOmD(cYg1_1Ush^r1I#B7~g+WP%Dkx~Ze` zID0FIyOq|QopV-497pR((aim7Sj;#^AE|ts`+wk(Wvi_VL13K65xr0Uori@m_hXdu zb?T>R(URIN;wT6`k3A*k{q1Y&$2=pZzK0kI{5AF?B*fjWQ(10A4RmLByIsHLzVGuY z8T)>M+wF_WV^GM5`ZkI3WAc5ZELR+ z+3|KHE`Uv__TgD3V*+c$7Dg@xqsYY0$=p=MS!`s25#V5QMfz~Zs@#3OARFAtHv-5N z0P0~y0CeYU;lZ$2gp9Zt>sYG$Y2xW?PJc;lu5D;0py?I@hq)b$ZKiBv=+>JZ!a_(U zc5=vzKBe(}mm#f_Q0S_cuit4c6vmLogO5jR*a8UQE!C|sVqG{Mt$ABhFc-XwW;-4UoN-Te zNhp0#FOy_MmuN?{eP4)LIjC}1EEo%aQ#yoJG;&HZ*2%$|ZGTG>4G4~3KE94t-Wyo)3S1bHR^000qmQchC<;mUlN zwQv?PO=9W4o7|Sl;zKS}000G%NklrzJ-1}vm(V#!6sw`VzvZ|a62d?vTU_2U5 zvN)Lqw@Kn^G8{QS1o~AB0Zw+pm(~%gh#&!T5h#7({XKZIY_*elKK~CCq|Z zcNUY;cS2=_R&`>J1Rj_y{Mr~r@%7cQ#wIq8I5xi_i+?I~zY-?l!q(f$YZiDw?C&g# zCQi3dWnma&y)8RcW%#%rSyok56b`$l)hUx%#-oKT$7J`Z3=lJDXC4i_43=B|tOVovLN3HgN2(XRzXpK16bqazY1(PsAWvM=OQ9^3T3L?Nr zB^d1iceykK^@3Qz)@@oF3V&`k>!pg#O41q#w?#NWlt@r072;LUWh)e?V!2*YBuXv$ z-4(chB0Q>&$HU?6sJu^tI=&qa$D^X&iGS#~g{Qto0)^)NaF`c|_tzW4dxa;-ym)V3 z!2p8j{!>e!vDO(7AT-7Mu9(k{jk*%5c_Z87d|ot-!Y(qR6Y<%260s)OMY`X<&7q5V zA$NOvnX5gZ2Li;~cAwfVf;N%PPDHbX`Z*F!BhF2TrkR_N#kM&SdD!K_Q%(K)9i1D za|3_B9^tdjAdA>d13JfDi26^sv zX8eE#DJgWlj5PrP3?BrHRDWxnw;A?8d>4T3l`!ms=TwxY8tQGJ3bz{emoR46(H+O0 z%ruuogHX&16a3c)lh+afuyGyTnHmCu0xJVq%uW0{(b(T9{)6)+;rhkdAgqLURh3-I zI;NXVVrfP|@E?0$=NXoACSsZj_<)-U7j$+OfS8WIA;#CGkQ#4jl7Bj^W4y&FE!??` z_LN`R(2G=M8nGx(6L}Tf-uH1~IL-!_n&3es*FP7mVF@E?%USg&0>+tw(G~3B+3Ec# zj}K-_JBY{LPvbnZ4#1zfy=Q`Tzg` diff --git a/TMessagesProj/src/main/assets/emoji/0_479.png b/TMessagesProj/src/main/assets/emoji/0_479.png index a00d551423ec75097e30ee2a64042ae1a9ce4538..681259e7e469c862734a4d3613205e46a13a2777 100644 GIT binary patch delta 974 zcmV;<12O!;3*-loB!5UyOjJcja7->B87m$aG9w%>AsQ?m7cCzcEFTv_FDWr18#*Z> zCmRzmMnI1BmU}9EfEODZ)l6Es*MCqFRVug)xl!w;E7d;K?NI zgAgOu>(>+m7Na`Z3dB;vgbm<^x@D5%&8Qc_j3R8a8-JzkP6#(FV!#2h8i>Oo(K`Wv z(Lz>#8)92VC+M6YA_ExNjJ*&eBC{b^1mm)qB6~u_M*-x^7PM^Uco1{1_reKMOI`)B zbrn1(1iOF{Y;=4Ukc^3JB~AvZE4CIK=X(y2Gw+AtJZF(Sb2I^m{?+J_jo^4oW13^k zGwnJkY=6u1jU#H9+GnF1*a(dClqu!NkY*T5Bu^vQvZPyNGYI=vBB~L`DTT-}^6!1h zn^982vTQXNxjH8JKBX~g_~$;|3K8Z>2@UFU^18?`_j~IE&1ssEw8T$RtRziSW>nag zh0&(2pNVQA!fi^wzrR0PV)97}aa)&DChKtUv48eX0F7$g7hx{KI4hWbyh8>hn6Wvy z)zv@}fP72ZJKeUs8FW#Rben^S6Gum1>ja1*W6pUL7m5*l(Z3Q%g~J25VhzG_mmVHD z8nb{*Xcah_1neKrqds_v!y~*wW+sp~Mi|#Q==kjHs%B7rJA*hFWIK$Nc=Ht6Ta8d^ z1b<)x0K~ALL+|wSw2ZK+Askslp$NX2Zy$4Nn`BeNk8PBFiT2`I%WIVLUkDlDsYLyr z=!V^g5(Ho?7+GCDej}0-K?JM=^144^8RLUz*WRztVBAJr@N@S%71FCg520+twP6Tx z^cOQI@TuVGkrXL6r41%7wBP(7al`X?Cr3iv$b@B?ZKYqJf1ghC=RcBv0DbRgXs7^s@Bjb+07*qoM6N<$f=3{>6aWAK delta 1455 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_480.png b/TMessagesProj/src/main/assets/emoji/0_480.png index 78b206baeb2fb2a50f0ebbefa6dc96be0aff2b79..d42af3d7a6d215e299bdb49e14286fa2f9ba4aa2 100644 GIT binary patch delta 1430 zcmV;H1!?-b3aAT^B!8$-OjJcja7^{XKlQ;j#*rA`sUXIY7{-$s&Y2v_lo`~V8O)U! z_{2BVoEgTC7Py5Y`OjG5tR?%|cKpL8_q`(Esw2{y8r-28{nc3i$tv=<9{$lr|Ij<^ zupIcyQ2EI~<)|3;!!!Kppv90G|I9J$w<-Mbzf&*`|NPl(On)8y(@)5(Y>`?IrEe7d zPQd#whFr}xYAcg7zF+^yW`8^jm~hs|aUNp7D%$$c1Z8FuVIYBq_XFXnMhNRS65^Jyth-t01yuw#(s)S* zOwS_A**2YR??)MIw_BEno+k;y-rERxJx-T0tAF6`vM{we%OycYD*;8U>J`t!@L{H~ z6f@u%8gUDuX2J5zgSeQvW?UIu&O~lQa^6nJdD?LdjC&v09>)Y;R7B%A4Xy~AZ6SHA zOSzsu&T*Mjm}MI=g!_U5K+?rxS(fJoRC1F%xYW2h^A%w>JvPT91_ase7Uk}IJk~of z{(l_t;auo~iH?04Ui_}&#;iUcE*he`Ov z2f|qtyYJ)a2!DJo0{cqD#o~yor}9$m7@;in{YOI3oaHo6kbs=ZRh1Ae*g*vZuGW{L z2porTM+_d{r+zM&Lz1GXPf$g@T2w`7Yky*0B_*t$maAO_gwMG@G9HL`<^w_9q}r8b zx#Y8=N-`b$P*sbvtXJu!Dh?D0HhLK6urC;AJ|!L)=jG~BRBI25@H}Z0)dJoji=x;Q z>a&!Kh8x4=5Fm&>Unh{YYfAwLG_pg2IoJdUp7N#}W5D4B<^Vx#JT(HEkcL_$5Pv5^ zV)95BDNj>P$YinzcdnkecwmqaDG)}}102c_*vXZUvDOFGi2|?>B=DWu(n&-K8rK~J zh>a(ISBM@(DjJ{Q!-?64PACCIcS0kYxgPNy4d_v%Gjr1Rxolu36bTgvP8Y%O9Q3k( z`{=*5X86t{M-s8BTC6afYLXDu$A93hJtoI8a2l!-8e!iK(H8^-C*tqDABaIJWEqGk z!*LucH7!tIq|DH$>mag zrwGU*9&W0p`#h3_L!DLmty88%vX0MF0Ce$U4f>5giV)F3AR0}7`7g6!j)Ybsh~TDd;+M#zKjK2*_R;$kfWJy_ kFqxX>WMDuG|7rdKkMtV)st^4b-T(jq07*qoM6N<$f)EC^d;kCd delta 1320 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_482.png b/TMessagesProj/src/main/assets/emoji/0_482.png index 4c7b7f82e26c122a949606ccc691f9f8fcdd1a8b..60479c8c9ee8b403bda13acca014445485f87d5a 100644 GIT binary patch delta 1272 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 JPDHLkV1gMf&@2D| diff --git a/TMessagesProj/src/main/assets/emoji/0_483.png b/TMessagesProj/src/main/assets/emoji/0_483.png index a1018f0a0bb31d13cd6b85b138e33fe1f9e8fb53..aefbbcc9bb9ca20e031d757ac7bfd5a6093f05b7 100644 GIT binary patch delta 1309 zcmV+&1>*YS5U>i6B!7fZOjJcja7=PXF=|IMU_U5;Q$2-MK7Ud>taMhUZBm9-K%#9> zooP*ML@#JTEs0w}wu4^5j%2uoV6uQ*uzFdHTtI_VJe6Zdq;*ldiD8^*On6K*zKdhU zk!H!2X*M4Y|Ni^KrGnqkyVt*;^z7mh4G8bx$x$s2+M#icq)*5Va1wK3NF|I z0000FbW%=J0MGjT6I?(2{wK+Zqk-sV5_#wV00c})L_t(|Ugg(mbK*D<2H?R4+klDg z)8_%?nE(I(wp$`Q!^Q?DU-zX#s#K+?x*OS;U;l?}_t`Ea+i!mY?2m^-o^!$&AtFB< zcl+-F+w4#X+$=tyQ{x)bE5HZrn_7K0K4ac2q9n` zwvPtEc?9N>3K9OWm7{^h2VtvKhH$%uVZQKc zRV*@c>g2}-#>%}>)yUfkwn&3O$z!6nMtkq|y}+eX(l9_E^#cL{e{I|AwN35cJ=OXOYi*mF zU;wdSCV$d4)dH`0dRIlonB@leU=X=LI7VygMAJ0b^?|_nIK>#ljbW_5OJfPFb3toK)(m4he4Nk8Sk-YV4S$4r%ac+t8jvT)bh8t-Z@4KNrV_H4+^`}uy{W-3(ZZM2%Wz1JX z3nQH%(b#n|$)k|Iy>`=Q5p?J-S0wz~h=ftn z$$#uCp^+f{)QxbK-`?J*?$XrpRpZ7MSATciNVro{zkC_zb|bZvhVcHa(1;6^hA(FByq9Y37QO*O8iHj2Km$<+ zqmBfvBOx>pFY~t?Xwh+obwr`ASRgFD2}s;VahiWtEH_FE7F(gHkQ@yv2m&YsqEJb> z_yoH1vLK%Z5M0Yb!sJWqht=YY&rnoLvH~2o51UY0tN` z+9D9z*!_Bz5?c|7U>(;Ml1gF&Ab+5Z5`m|!pn-_Mj)V}n9f2H$H9w59#4A@If}28w zKp-#TAXXZ>2uO}bo=43|zsUetYe*M10}|c<(5r=btzaP$P2{vmA>oK_0Qgb1``xK5%hM^t7Ji=RyB7ZeED+7i T&z8f^00000NkvXXu0mjfQPp5y delta 2134 zcmV-c2&wn53gZxvB!BZzOjJcja7<%jW6O_bU0q$Uudh~BRmqEE!NI|#k9}@$Z^eaM zwwQu`etyG*Tf>7{w6wImySs*lhK`MmT3K3!g@mlEti!>`;i;*pY-?*Ketmt6d2Y$c$)|Z&=jY~1MMJlCOziCJ-rn7#qoV1?pWE8k)YR0Tot=tW zJkQV0WMpHuwzi&ybFrF)4@NZo(@5hT)Ha;fo&u*v0?q`%1Z7W91o000LENklCxW;t}erf6o!{qe+4W z*&m0+Oqom+KaTnyc8LYd2$&HxZG5l)yd*3_01p7g!$6$Ol=kHQe$rNEMHr0tNp+@`45?ZxP(Z+r+5O0f*^M8 zCrt5+aLi7sGoar-O6|!c`$7AVBjSqyD9jJf@Y0 zev|}NJS?b&BT0^+ihwXhNy2`0q7tU|?SG}Dd$Bhsb5sW}N|ZLo6F|0EvZ3!FK3cpx zQ_W`^_5IMJ{J4_iL`f@vZpb&QN;m&Ph*8y)5Z1Gey(IFi1`#ZCTqqOHfB=Y;C6a94 z+{gyyLoN2PT-gPsUD^0rFoK&AgFp@h09JSagYeY~Pdi($ML_a)!4-v&_Z7F}0DlNz z$wW9yJDsLKoB5@*`cXHf0_8|&qJ-wWMgf@fvQBx-7@>g>`RRQpRs6*=Tgp5&t9qAZ z%Z1-=H^ojGjKQFYxfkxy!t{YapDeRag-G*kHGp0d7&0I^B^Z--L7nA&6rNHkfWQb{ z25Bc>*n@$bIW`zSXds~$&S0<%)PGJ}32DP1W*lBoORIJ3^+UgXFADO?XqKDJW-Yyj z4D7{X?0ID_4KhKUv=a(3v6936BUF<%P@i_Tl8U-?v(C+Bnl2ue*(-#!uo`7rYG&>X zB%#v|Fm2zX?YzHNA;K{({C2Jz_IlP^Y|88F+v8I*AItZ~HN} z|2V>iJSBu*#9dL@-N= zxJY~@)eR}{-gY zz!FD0#=~Jsh{s3IbTh}<6iR>?5Q49?Iu+RP{h5+BlXz^J(Qxr}clX#CcDFHdh2n6t z?P_-ze9WdH`Vf~W2E0=gRwox@Mu=Qh7f3MNx)04}HgvZ_nKaj#uzzkQrLlFl>*o4l z`+x$J3tdeWo;Nt)|2Fnv0|G)2bRi1`X|UZ6&^obPt_HNMHYJW9TCcL8$AYR0f|@I{ z83@Wg0GtUilqL=d!_bShAQ*B!o@~+jf>vMkk)Ei=qw`jy)Q4Y@DYK@&E$X(T*P&jDHXeAP|ZtNwaIL+%<$|b{oMz9G2 zylsOSG8nR8uYd9#;3>Cl0mEzp1Tyiq4#geAanOWy&dJ>6*#Olwb_DSdfOi?_ELthc zHag*CnMAL+q)|bCm%xm3hH!5oI2rICc9J1ffb(|=sK>Fmb0SL;gQ^$WXd-lsI=rv? zAw#$|B>oKy2n;x^|JHZAGj5H*j0*7Fh_m1RhFAYcOHTy*7JFa90{~tONZ}83atsKZ zuyg_(pZxKce$+(W>75$9pU&ag@$vcj@$uQ=#|rRQl#|25lV8OD7a`*aBgpkiI{*Lx M07*qoM6N<$f>#R-QUCw| diff --git a/TMessagesProj/src/main/assets/emoji/0_484.png b/TMessagesProj/src/main/assets/emoji/0_484.png index 8f0cd32ab394f3f9465bf0a1dc0e8999b667a267..efe88c4178782dba4780841be4044f69ba4975f1 100644 GIT binary patch delta 1259 zcmV{Bx5=vZ$c+-LMVq;G@NEW zU^yaMG#{pPN|9VQvxr)hUO0+ZGn!*Nf>AJbNh@nXCR;WitaweIXg{QELau>Vv4&iy za7H~Q7|Xw@?C|m0*VDYJm!+79t$a~|Xi%whNRE4D5ex{icz;OGhX6(LJ^}y$01$Li zPE!ExqJqzdV;D0~y1C%x+V^h9ms|h<1RzO7K~#8N<(JuVvp5ii2fSfB&U9;IU%e!G z{}-HYsi`=>!8lVjS93s=Bcd_y4$-vE-;;dCmBl2x2ehy8CU`@`v6 z-s$i1d|D;H0)JHJ!aE2}bXvXYWVg!Ff(dtrzz+M@2!|>?pU(mb1X8$MSFe=ua7|NT z-0Msysaj?v@7L?dUDA)m?Fpj(s4dFWRwE&-DbR#B%)n;|u$Z&1)q}V@qc9}2GYB2ZnJMtABmZNx z0swy#2r*fU#4-XD=*#VLyD{Wm>cTR}{29b9iGREcFvFnh`Z6e$XL7K!+s)MVZMbM= zXnUL>9Ns+wbkn=$_VHnRA4&wn%``MCm(DY^J3hW&_evRq0N8h~ZZ0%`Ll57CvZ-xj zskiAa2%w!-s|N&vCIk*`BP-z273@Q?pc|z3*7lkah}*{<0%$ZsHzFLgP1rLkgQ69L zD}USWrqNh5kBCTnMALSb304hlm#J_--*z<?Hr+YZ$G^+hHIM2|=&5XKq}cx~F|f_d3>J&$G)sO+c)_(^U`Ky93z+Gnvf#6|!p z`i9h3z#)PZWF>X=eW`#DmJsp8`nDv4z<*L5sBt6^c+mtebFrZUC7ff3S4@bFZy&&)gAMQ! z6EE2S1nnHvl3VTUNHF~Pf3Ce_Mv(g$Rhy84O)URE5&I}2SIex91mk3fE=TdwTFXU5 zF^&{tQOO%I1i_CXbN8dXffluom}H@Y4MVyk$b2p{*oQ`cu;hafUQ==;|2&jWZXwh0 zMS^Vnhy#rBfJip@%Sz(NGR1^)SR0FlUqLp<$Xd(8qxD7rzo%?BaU5^92}Sr%^$$tr V*%q^NP|*MY002ovPDHLkV1nfyL2dv5 delta 2044 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 k+PTI#SC07*qoM6N<$f+a8N)c^nh delta 1989 zcmV;$2Rit_2-6RcB!ALSOjJcja7<%4B7lE?Yfe3?tE*y8L%+YiU^gO+jErw)Vq7#I zRaI48H6gULvsPACii?U`TUw5ej=jCTv$C?gySq_QQDbCeo1B}arKXRLj)zk*lUz5L zU^&Ld#aS{QfJ`opS2TG?D6p`w%*)HTx3+OYDA?H6V_{)xJbxnI-rZ|zYoei`nVFfB zl96^t#02*{sPE!DXw>e8y{{H?Q($}epxNeK( zv9rnP;KKFAH-8M&iU0rxmPtfGRCr#cmj`zuxe|r#F?55oC+$9|bIzHZ?b-kTm)Zui=IUQGhOYh(jh{XVJ^e0a{OM(sXQce)({DkZUa~Yzw-8>k zm#5z#WEAf>p659ZDEWsOgG|ILilQrufaHS@BK{ETD}TD~y6zG3pAV*yIz50GIvCsR z12zT^Up=^o^odIk-J_Irl=}lvoVB{`f(VFXMk9=o0XX2eg_i$Y?GJB!YPF8hLP6t9~*>*0kfiUMa{cPEn*2E1T$!N$OIF-s_r@qYlMd0UokwnfY80u%h4aG@GsF-68t z#QL6-W_g>Gi$z(CvJ@1F2_P}&>)(!qr}v-gis;L{E5hAuv0N@@yQC$GFyq3^gk1jb z;dnyL1Og5apJpS(mjswj2~rXzPfrjaa7fPyf69u<5>f&p9x`m(zzZnw(&d?ifB>DB zV}JbOC^`s$D@dVB5HA2z)#Th%VT33IK|Z1;I>{THZu^w-fIz?|Pz8jH$YhYM8b2XL zo{H;7NcqwuhNG>g%LM5lloBunz~UOjEi*Du6M~dUj$HaX)fx0A@-5{jDw(w)^Z;#h zR1YB|Nk)j{jrxZ~+!Tb6)Kn0rQ`H9m%YRF8n6XS>6_8niRE{pZRN8oMC4x4i+kpVU z$$_RFUwPFK1U}j=*^mLBL>}MUOd>od4;KLJ!Z54}vHmGAnjKWCV3Z?D1p?w_OnG3Z zwjK>QSutBq7iH5_RRzL{LAa`7O*xwpBg`ZNCt!3#c?blWiV6XO%7g()=p}F%#mg$CO&Q$_Pqh=XPv;XjY@ooquom5Zs*G{1Dxrswh%V{9rRiXsWawzlm3tCugy#M^!q zjI{OPZ~!9<0-q3XZ(Cb)apAhK-kSxn9H0j-W!qqc8Fhfm`m!UE{bmQ zsz(@nb0+x~_Co{L4}uUiq<XL!pSXM0geJ2rW`+&lPjn1=`kt2d zeRXyW`i4AE4A_8n3)Q!A0Bg41Lu<=d!%Cx4XjNlGY<<8WvlG+zZC_m=287+CytIyp zso~qEi8*-2VUAS4s5U6ZdQ;W-E%HfCf^`TXV~_`F3>y*=*(S3a_OjYiitJ%2IA2|z<6c`T} z#<#oY@!!5d-5ZpNV36zx%S9v_wb_}8$T03Ne&4!LVZ-iiSSniOq@{0>3t3D|L=KlE zZ2&NgfKyX%Qob`k_nq@XAD*2Ho4cz92CrI90nnSyXX1mM?n1BfcJ5i;pG z0dQ$6->(TEzCI24sDes0_@Ktux9UlK4L%APUf>00000NkvXXu0mjfyF;Z; diff --git a/TMessagesProj/src/main/assets/emoji/0_486.png b/TMessagesProj/src/main/assets/emoji/0_486.png index 0c95a3430c1f74c28492483fcd55c1a7f153231d..f2494c5dcae7affcf92be02f1d7b756e56c0dc72 100644 GIT binary patch delta 1418 zcmV;51$Fv~51b2-B!7NTOjJcja7@pW6zj4a(v%V5s2JX*7v-!S?X(@^svP2}9^|SS z>#-a9!X*C2Ci=!J_P!(XxF6`P8vn{H{LVH1%`pG&x8S50{_CgMn-mfb2>jl8|MkUT zJP+KtX8hDa{M%&y=8!%s41-7pn`RWbeiHoHQtR2Dv6Wh>fPXOPxIx1NO2GgC01R|e zPE!E=;K^x;Nd6Qms>KZ=nSlTR1i?u}K~#8N&DUvTqRbKn;0pq+qF%V}|NY0aPNF#d;-qnutUta!N<;B|*|nVAMTsztK2bJt_`Ta# zMbQ;qhhIfeRDbQogz@Ir4Z^Ig@X~3}s&*>;U6W0!+p2gKL`?dNB1x#)3iDE_S{)|u z1RMm;;eOA^pA545{Z73z5}~#iHW=X)d{ivp;=D1E5VCB0VT2TReDD!1?>5unW?5K& zX{AO35n`rkS=eSur_1XS8-)ZKgrG9ZZg;^FS*A?1xPP1>Fu?|8hY(SCUT~6M1lyF=P1mX?0Js@M!a6wR1@J`PRMfD zF!AdZ1txH)IZg;MBQ+D1QwktmSPuZH2yr=9;ji(|`G7XiyYif^I+ap>nk8a+f(Y^vflQ zkpL3tz$l&qm(es(q>~szsD+3Y2*n|RFPq%+DMWw?rC$?*2?juGg$?jvh5INxhYavk zfcXa@oe0h+%vlrSp z;twD*Wq@O|#z~2SDgP!mams{}b{I~5bGQ$7O4#9kJT(0-N>q{DFQi(Atiu7el}>t=tfk?{n4cemz*Pj33_w|fxo`+8_@eS>iK4M^Bp zD3i%O* zuK`;GR?moJBmh*^4GliMKi|9VA-KFl7=Mw|Y3M42Ey}=}*_N>p3~P|Ps=M|5DL7xd zg2q6H%Zl!L?2qT*)>S*{iP?0nzo>;lLT2rLxZiKrV!w4rV6et^UtDkZ`><~_DK!&f zz5}O7l)`|-IC>@9@{YqVY`p2@e9}otge_|;;u#T-ga#r|!Q|sO_%_|SKnq*f)_*25 zBC&K@5HW60kBPkOvd8zFC-K)Fz79PBNN@;{a$6M_$tK6QD3SR4l_W)?v^*IMAmKnu zY9WD<{6QF72DOb}yqMJi5x~T#7~Vp_2<;w0VI-);JV}&#LV7_O?29Q&Bd6m)Vzux_ zIKeg1KQ(fxYuxQ{o0t*8*2&TvrGH>jgCY$X=UQm_BLJ0He7}Yx5qdO8p(W8q7!9)$ zWxD*|~axE>8(#A$1_%cnvedw*bgDBkeN zF^;%V5GBp!n{2!RauygntTrBaZ)jkJB_#oYx$xfb2uNVy6Tut8BNR;)#BT-8I>xmn z#D@V~&G?hg%gL%{#0LReuaZwcw6A!(5f}o>RYVm&M3R`QV9Ib6Cm#4%S#LP&e-`*Z Y(ip(aw1tUO00000NkvXXt^-0~f*_owQ~&?~ delta 1914 zcmV-=2Zi{Y3yBYqB!9zDOjJcja7;!yG`hOFR82~%tEzo|eZauLS5#A2Q&Bf4Ay`;g zIVmDlRaLaKw2F(0PenmID|V5Fw4ry#>K_8wY9IVtv)OzMKUYBytdlScTf=_&N`z^@jO_C(7Qj)|sm){`7i1&Suw)LG)8WN`ql|~{ zWw*D@R>z(V-);sFy(oUR zaw5Noy{Q8R)MLPYvn@k)ae)t{;@zp&CV8Itk?X8x!1RK>H*AbON8i%%w4X_wR#lp` zKCKHdnuEWqH*5^u4l(QFTL9J-V^v-N;(I-Y2!AW*4;vSed-(MbU*v0JyPMD1R<6?` zRv1vQG|J`c;kfjt@Yy+tbiAw;fX(N-ZKWyjLRMe`i>n!$(82`K9fwL7rSkzcia2M%(<0$Lfv*>CUWD@?a`wF8!LG_E z288tI6(KV0F}7Q7VItgboX}7Awttl@;sc{8H=8VPw{`in^aGRI!Is_&6}dvlb)FV! znpHb&6-$LC zS%HCqtTLI+ES%1tpIdKH+GUnWnNiSM3}`wH*vPWA+=p43$6m5|{OkAc=f}-5TGJhY z?|ij%>F^mDwP~KpU@O-d5hP9LM8XC=>{+k{EcIv684=_}ZK?qV5SR+c6o0(Ti*#M`fJwtt)vPKO@Dk~kJj@UuhN!2Ck*5H3nLvcF zZ95b^wDAdXGb^bW*cgE)3Je2N1oR`@87jsY5rKL_41>Xi&BIzEIDkS!G>t--va|sq ziCVpf1wfDq?7FrA2oM1f+%_t55OPCU4FJ-Os!K1RUN`K zc_pjbDuqB9LPmCwiWKOrAq=xoEFh#bPzfzeC?0E#Xc`lj4Fgk!O5%2angW8OvN4+; z0m3<@p*1y8^*b6XzyciZk)jM0YOnV5Lz8h6R5K2$ob&l zp@&SaU)lg6pw3cv=zrAaofA{%aXkUx4~=>ostUpUp%>O8gb!^3h!eEpE#376r8GFx z(MpWl;P%D5Bf#4>dWMN%AcocsOrSO4JrmG?^$gCz;fy@Y=ZsTp?7o(4aP+ROSyxii z1jZ!iCYq}2Xq&p9?E2^f4Nf{Ea6)PhErl8^p8}k~!$%sOv2)(ZOTiAM0G*9KCeV;+ zh&G}HLI+R-^(o})?xbgEj&8)=l?HsS5lyNpi4p*6B9X!ubakd6T2zIztFHibO%O*M zpaNZkFGEIy>$|g)le4qy!AJwXL%A9Zu0DzX8xQuHmf4GvbN~PV07*qoM6N<$g4Oqf AJ^%m! diff --git a/TMessagesProj/src/main/assets/emoji/0_487.png b/TMessagesProj/src/main/assets/emoji/0_487.png index 09c744ac5fc191d82907945abddedcd736608a25..ef5449cca4a833baac4bf23e00cfb5ec321fc10b 100644 GIT binary patch delta 1470 zcmV;v1ws0=5zq^eB!7xfOjJcja7^&WqtKCS(UNQGyp`m$j`7K)+@*lzv5exfj^3w% z(v)uBsf761xcAny^w6#L)3Nf*s_nv`<+YLFt%&NpnDED>(2r=_qka40!~5UB`rNzL zm~ulQ5MMkc_4V|XcVBH%Kj+`oBMbB$pKwu)>oq^!?hS?u!w00ihsL_t(|Ud`9(R_aO+1z;IM z5hDRb`(bLPY=F4Z1L}w)P_=I@r za~KjcGgFd}Qhy8mh={Zxflu)sQ2q(=x_r1Kp{5oT$w`~4{~L%k8NEoNSwhlzxEweh;}JT< zr67twCSHMn2+2x*I35pW4ts@yPF~_MUNSmqz6A<`AG@X=$GSh}g%521V^7DrBNyU3 zLVzH<@$W}^B>e8kdw+231V-wIgi}H&c>rOon}4RMx49RP*wP{V-9aiiah6ch1QRq$dyoL#pHU z2xBD@$s;0;UM&(r=*yw&>t=fq1b9PSwtZdqhf5+wqO~@!(faEhOJ~+0kqkp~+}C5h z9e*SY^^v=6({9JH8HPkCt(~>W=GKUuwwcii0%vw`a@`Mn5(+-R3iTtvtx`y2R-53K zFz$m$hPEI7jzF9)`!e?__m_IaG+jF+D$xcy-x0=E7F!H$H$wh4r%QV!+TnvZo!dbn zQDw&75`i%p5Q!4|_E6XL*qqO8d!0zzc7JsZ%}$4QFMzN>Wbq9V1CeGxs7u>!o73rh z9)KvW#L%DM=(cSyN@-`)%>G$_x%V14>a-FTK7Ef7X0LI}n2oshOVji&Eqf$yz37m&nZen>wu6Fo*ducX^WvmNPj_h z97%+&fC#=2L6%jOHCj#MAvp{y;dwQ<1Va0&5B1nuqwe-ui&giV6K6e*OrOAs!ro0;Uy zW!5-nY-TtKOkxQnRx=-j!z!~t2!A3VOjjwTGIA&uX=S$2cqD28iL4RjyI+{%1 z8Hp+h^H*Y86x#CG0}Up$F{yaY;lA;I0TeEvU8dNl|k;3}li z%hQCDK?*@gdBLy7bHh47Q1M9saQ3GH8L+lag91!K>ser*$6#%Q?_y72Zt7Yo5T!jJc?_Vo%6uv>iDE@Bz Ye@v9;$JZArCjbBd07*qoM6N<$f`kgY*8l(j delta 2215 zcmV;Y2w3;f3$qcBB!BQwOjJcja7@I84!?vLzJw9iogMGED!qjjyMYhKhz{SR9PhX$ z@3$qrfe*!r64{;_*_{~jx+w9vCBcIZiCPWToEUjZ3U^2e{>LZ&$t?fPEdI+h`@<#t z%s}?NBJs8!>8={sn-ulHFZRVf&zvUgx;L+S7u%;P#gHJDWPcImuq?TUAEa*-hFK4| zrg`%dud1u3ZM^f9Y8U%EJNxyE z=J^rnym@h0$I5@u;Zbv^esOM^mXc+?ZnxXZEbjcG{(pT!E##XQmZV(wy6vlnha0A= zuEL!kev{BRGEGxbT8ywkKo4z&YktqkPZj#86sW6dd>3C&a-R4l)A3xE0MTD}RjQIPz^^K%vc+wXs7F%FMG*%{a{v zV~Ys5(FuG-ksRBNgCKSz+v6~$wG=C?e>5@6vaG7x9=GhoWg$3r1WJ+wuI(t- zEr+u7() z3~S0*BM1^1J2TIJZ^;jaux7zjlNmr1MTu0EBW)xyf~?AM-wtP<{Tbmnk*kA1`+o&c zq)#$2a$pmJk5-ZQ3E`3pFYbUK%3d*bU3cnj0You$W6~72Fof%Q9}%(bd0{kFLGWlM zVlWEWAz?o(=|ur@oFuNw%Y?AuVt1<}u@7coP#L~!>ndUcfJKS`NFV_vYet~~;ji#e z+dg?mGy>nYQ45iH8A8@$Tl6(B^|0NA=l z4U=){tHg(nci#1P?7RIbLx{RRnM{T=6$cAi6L^sihaGR0M=8f>|+4J+`<8q!x8vW(2Tt5naY$0m>$n6ivzQ3I3^MCo%)8jmS zXYisq$sgy>k64~lOJoBB9VbY0JB$j!EwO#^a(8?8G*2zD5(xQodN*G@-QL~jxsQ{f z1@Qeh(%c%=Wxlj=EQa%!``f4c+uOU<%X2y&j?y$84aep4VtIT21oHiIzC;{O`M503 zwh@O~^tQ~?(I|g~0|0LC`+qNsd0rye$)wEl#o`UiM4r6nqfwfd{lL)c+lY=I1oosX z^VgfzEkRuOb@4or*}%w?`C?JB<^FW^nwRBd*6Al5ZyQnX7>TQE+9ZEnr1z^;-?m4K z#e9hUxWq~Nuy|cz{cRS#zUCn&O%M9|Y2(8;Q74${nmjABt3{dw5q}6bSvjUN4j;pk zYcF2j64#!*+`N<=;?&((|B%K0sqPlKrgG(wzrN~@MlTOt&Mwz&6`eBFt#*4j9JagS zsFVpYo$5b#wsqDi1|5voEO%sCkR(CV^>RoAkubv)n=}lcDm(d%Cj{=_`+zv;41myN zc>;#2Vj8$KrB6Pk*MCz4K~7Us)gX184?$4%PGK0e4~RpT zyEivIpiKOY)nS?rd1k^W45YcO1`q}i7&K>;LL-M~)75);=!rZuu1=W=!Wwb*`9Bl` z#Z?SmHgO{?@PeiZt(K&z0#B0Jn+(wz6b7RB7{&%sefn1t)PKRi09$5=3PU6^Q4H#z z5RKiUFwhff2N(&tfF9D7DO+(C&GPVBN0ubqs5LD`wIHH6k@2Ls655U z*->P3$d&f05G&)izs~Br#DM6L1YzPym{b6WQ2WELOMfsrdZ(ky5S^~~lc_^=sQ&ot zu5n3oVRVoOI>2NSfL8(T7=sg3@khpSF#tseLjc2)B<6!cFb2gj+W8IDE{o0N3+qzk zig1D=zNh_z-8G{cO#t-H_bqIynNqBJ)dc`RxU78}uo-?hL98T$YS^Rm^j{%+m%CG@ p-OGa-03iQI`;FQjRBQZp|34~=xxzK--`@ZL002ovPDHLkV1k$YFhu|W diff --git a/TMessagesProj/src/main/assets/emoji/0_488.png b/TMessagesProj/src/main/assets/emoji/0_488.png index c891e9730830cbcdb8317695ac55783410568c15..23c87333166c08c3817c3742b76431da85e5e08c 100644 GIT binary patch delta 1338 zcmV-A1;zTX5X}mZB!6a5OjJcja7@dUY{ZITz=K-HjAO}>Xv~*x)1!OMm29+eN8GWC z+O3A(wT|DplGmt#!Gl@Ropi^HV&T1)yLe6M(X->io?$m1NFWW4Uq9*M+4cALgH;@x zbXBXAfal7oG7bVF0|2^@42~Z(q5uE@3UpFVQvgDUp=rt?{D1!Wgq9!B000DxNklvp3!3;^KeYR7kTzb5JXzvN0X?!W}nbbqbjoEe<>tB{>4^q>EElu4du1x1$T zN%`yfc~%&qtM(4jwpy|x%YUPkX(6k7bBKFoiu7Y7XQFLR;x1YK5s(xTfb)P%$`1sl z+U9;`w2~!1-+zRn5}qnpTJe*SFkFU+9GN>273A?=kV1h02q^^7fhP%CN%p25WnrX1 zgOJx~+p1DZ$l{tvnM6WqLXi0b!T(XvN{BaWTXI7L8GrzDhzbQDgt}bX)PX>R(tyNh z@ubk22q{f|U5TARK@;h$=vq-0(p*#{=Q{$GlORG$>3_}_Hgg*hk#A~$C5T|@DN(RU zAQG9~d>D*`DXvQ)#Wxa_IG+v?2zk0Di4O#YA|xb37jb$dczIq;W2A`4QHWv`3{Nfy z$|4%EAi>(jC6NXK6+Dj1LXZ^nA`vdXASewuX-{AdTIv1T3M42_i7aLTvm|3uR|JH) zy3#lX*MA5YX|4%Clv{?mo9BU5ND!baHq09TOvawJSMcI((bA8RAP2+@jW?WXnl?8e3j!<@7J@7|a@76_x^oy+=o_Vb7Z zs5Bf9W7n_U^U<%9#*M|TXFNF)-1*uw14&H769R~4)R9nQ)8pWyTc!pG#%u3h2p$MI zPJhb-iEbXpkOjs#_75axJB<>vs4e$LBH`TLfG}d5+P;50x-UCT)H$dxP1Ay-^H(*E z0tjDQZ;!Pok+8Ti?&Gx1^ZfNSPGcJcUA1sA;GmnvyOhlNTkZdD1O*XzC%PFcYZ(bZ z5JJXU`)X{o1OngevzNUIFn8FNrP_Kp34h3FJgK)UeBC%CZ2Gb{E#&6Ru91+@LhKtE z2viCn^1q10+S|?ZK^vOfkqH2QJ+vm_+~(@=^Esh#!QIqofo0W?TJqJK!w zTYFkt9*D53HLHi=b{mEo2r>e}ZGH7kDXA$9B!VFw81qnj0|XTm2?qC3UJxY|DG*=~ zqJ?p|-}ELZT2fmV2wdI?1A-P64r!QkoO32)Tiezny(AJUXfP@^cl&UaQej`weOyKs zw+801^t%{vWZM*V_U>8cdtD*q&VN{FBqs6pVIT*CnSe;a2WVf=+y)-L7J$IKt<(39 zR7I%hW+=fpXF@B=3k7cDzI;hcz@>}AhlY2|V8r=`Isd5;>*4u^m;i83b@({SEFg|C1BVMh_A|TZ_PhWD w6bf$vC?JJjMv{RNqezqg{^tjXAO7_4FZ;BXt3p-7!2kdN07*qoM6N<$f^5@jQ2+n{ delta 2083 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 Hu0mjfq1C9+ delta 1080 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 delta 1967 zcmV;g2T=Ht3cU}IB!A3MOjJcja7=J)X?svQcu_r^c0qbpJ$6<<#>dCMzrMJiZg){W z$-}sEPd&@Gim0TY#JsGuri;$Su+hMp#=4}Lkc896uF=DwvZs~1ieJYsi^z%d(NSgIVFw zve2G#F&+`7au&jsG}ECfA1&as0000ObW%=J0RHEI6D(Bx{y@sjr&Z#uhN6C#ypE`@ zgd0C6000JvNq@8g@B@xzb5=5tk5wfSE^9`0b}5A>iu-Q4|}Te`j$+OF4@I{yWf zuM^f!zpU+cz1=PrE1|_|v0bb4hc6N)bKSDm0w4tdA%B28-F*r14G1~_0D&&f7YLpF zejk-Hz?=JQ9*l8Bx$04=uq({;wfH%I`ssH#8!L+S#9jQ?C= zjGuJ;jJ2*?fEX|q7Zl0(_ZsHHr9_BQ#6a}wF;_BuP^C#^SXLZLAA)j;*@}l+T)~8 z^E^Sth7$sWf0O4Cn*f};ewJ9e1&FxMbBYMnTE}HTJd}Yi`~pBBM4-f15@fLogzyr9 zVW?SZ3&2q4R1M5kVm&icLiIO9B3x9ZgMR?rE5pDSNs9X3X zQHOCMnFOtC0tf~O&~PpQ5hht+izMVoUX=$58oVR?*(1iYB#f1eQ-Sd4k&;V*Xnzu+ z$0HR4!-YWy{k-XQU&M)$xro>uk+i3DNWkl8>4j_0PMq%8*VT!z=i#&$v+eQfw0Te@7 zgT5yN#AF5t-y{ZY<8srTmdj-sMt^-PyhuH~9J*}zvZ*2tsqj*Xi~I2qaa$y90Ej$1 zy)4Vk684_-%7}#Wyt2Ar`O*OSg@-Nmh}psovms){szRw?cd`Nm>LopOaZyVZN!R&H zq0MoN`>M7n7#kKc_3NT!b=xN0Y9kP@ud7ZCjv|j^5O!U@M0WZ5+$C*Y2Y-H}u-i*S z06jHbzgl&Nm(6DL_dm~F7uJSU9jyQj>#zU(z3LKvw4I=A5HZYxm8oNULAyV7&*>`? zR);E=aqjAhp1Koz1;PoIT|xm-vWqOnGgdOkByO7@pHGMV9_E6&)w!*-GF|U*+LQg^ zK%)9cY=OAH8EVGTz%^~klYjhZ66m7iIuV$VB6(!P0wu(B^2GFr?FL!qk1h}+#uy;T zv5s=vG#$sWqez?>c;KLoh~lDS=21>OYP&2;Qyk7=o{VwFro^n1C{Yv29PX07x+o z`4&y^!AxA%f_+6B$bax`hrn)|+VCR81_lzOi9iH#)rJhz^LV-GRhFCp;cS9|i7Phb zY>2I!^JkLqIpaR{0pen+=UE^)>Kp(m z%=K3^6-Hca4J9Z_MF`A?BEG2c2+u7Ch-rf`#jjiFtI1LpaPA6m0T`z6#cDFl1d{s%&Zvz_GG9w%^Bpfy;A14|U zP&_k7G%YJ07gjWGCuj000BTNqMPm1s_kYbRwOS5F5IgtR96XgWiM~2o##D0n$J5lNJZef)H-8^ro`Ku8?L%5- zIG5%xN@LE@_T5YR)+-+)=FB>NrNG&I1k^`RAWsX&<^y3>AuCe5&Z>GLxKEVGLIgyWRoXx>nB5X*P(lz@;!6c3 z&dq)aAvg&B$}1?rX!c8JjVwA`josBS7B~tC>9vh2;&2Gy_QqBygedz_!)(r@z%&t2 zGKb|7U}q-H7X(0u%Y4$DI9(~Qy(hKxgd&O3HXOmH1An|t7*D`*Y`mn1VvV-Y1(cgf6Fi6W+9tHIpyv z|K@s^8Gm+LloScTe(c7vgVla?;cky01a1(GsVLUK`7(A_m}ig<`tt8bxOSIW3`D9- zvl7lok-%wyX|Rr_Y0(3wslCn4wZnu`f(VbVhOtWE=znsYox9$L5uP2!f$h}!yYp>C zAuQT@Mc6O<*!AO)DQJpmVLSDDPryDuw_g^Me$IBbD}Sj*LKx8c04tCdvpDRf(i+}K`zHhf$E0&r z?h^GW5Yb>r3qj#U*d~*lo~r#CYJhc%5X25rqRN1*20{o%gH!fQ3-R7a2wrLf zR6&>W6NAJMM5BOo_$cP&ND$9>$fEbi=VT5ar>R^($Z9AEuBs1zi77~s6i0zrcXvxF4RWKb^FdWRhnOQR*r=+35xTU9}o1>P0WL;LOp^=%9h>wGHlw3EC zSTvqzKiAjSm|!`zwX&LGJJ8Y6iBd3uOf7jwDr7k#Z9gSlG=ChJgL95+Q>dq=la7mp zfqq&=H;8s>PcR>wo11iLVw`0>+uPfua7N$W-Vh82MJE-nhFn=yRLZf7d0a=jo_YTL z_~O*J_3+;<924T=;>?{eu6Go}3+8nI000|wQchC<>r6`i6D1y3>og!PW-Lgv==V@7{UG}vMh(8UI)bTLco#|Mntsl~%;R|GNy z=4yx2=GKqDTbNw3rI|sMwZBn#X_Zy z9~A2X+!zEHgox5K2-0cn@E>9c#?ngVdE({9LVsO=bmq98v@WVr)|PTf8XHKmtl6-W z<1&sfaVC?!vkw;+snm9TsisqbVi|V>I!HMT3aRHqs)`dWRw@c9=UdVRsyY_Ya;>yt( z#DB@1fI~O|5dRF{OYvmzBy+1;yRKu_oYBdmnv^*XTt1A8VOfZfpWcUjP$B~0>Dr}K zuR%=$k*G$Q0MX&boB+y#Cgk`X(FX)Dw6gH23E~^@GIcIoL59ws=+w_j0t6%OcU-^( zk}P1H&{nIcC{DE@3z0jBu|On+a{=IrTjO9oOu)pQJ$xuTy3e2Qj}6f zkO~or0f?tokR%3ZDY+0fsuU#^h`OA0$~{Kj-;_+7*$}Kh=?M!iP93l zaLtU+2K4~}YR$z+0Ys8{3`_B;pc2?8cZ**d|K}Ys{8bvIBKZsns!l=rpSvl_M1ScH z%qZx;y?6aec^Ek`Sr`2ke8HoxEF@Mr(LJrTn^M3VQBni_2Q7CcxYuG}J9@A2BZK_Ac zX}!vd)#^DoS>YlSTIA#yt=1Wk*9#+}I%QRw?C;x%v6m-R3LBD_)AI_oc2CDRuOd{Q zmdE3M#pQ37__?&&rtZzCjR>l=@b^`foX-JAyuB@tWY2UH{@C6)9uF&I`+skTbD8IR z{E_iHh(WN2p4zsb&X2ow5csdJhvPAhnqo%D>3H^Fy?%W?pA&~M$ImkFv5gqr_*vjE z>gJo>d1t@9zV6P;O^ygv1w_tv=TnXACuq5?Q^zkPuTzWRqgQy2P3JzZ99&`!Vm%Q4pzZN7*bqxYU}-H({%}fTLCGAb*vwh9)%uVY{9b z-1Ryd-g^O0qT?qh?m>dhjX4Zgx$wD30TD>Sq}SCX2q1|K2*_WXLe%k4zD z@f_VGQoxg#&95kkXGS!mZAQ}&%+b~O?uOd{1Tv5SJE51ZgLm3OFet^%M40Gm!mFW+ zH!l*H4w)bV051$+>wm~?6{4Gk_Z2$H8O#9_jPZ+7U~_^nAx_xGHca$k>TXf2FDeSj zrI%k++wr}QiO!41^P8ri3F*0|!m$AX=IAFT(1s*N6vqHq{yQP#(*bCmfr$?)Ax;}a z!PCa)$y9A`jevDvLqTnv4vGYE%0G-E7z{RuLF7&4vuOjG0e=A+I_Q0(!3}5Fe6n$) ziQ6gS7@Si8_=4~`1CG6WEeV%-G2|j)-1`@e?gKa#&|NCdOEYJDs(s%J9)*X`8Fvyw zu&T{}Sv(5E44!m1>U~Aydw_`62#GSH1qksq4JW)JSXTzZDk7k5;frZ}tg9#@WC-rT z!nZWIlXy))9yCaL91nZn)o?JmzbR1C&HZE`0Nww;a8P4c(_B?Y1QFv>TIK1N6T& zj8p-LP673~8kAWCr=OvH$ed6%Pmg*=;-{2>QrCY&HS;%vapQfRuJQx|L4fwNdZVf^u3VuP!OT0000L zbW%=J0FXEMaSU$mISfX5n0n>e@97`9h{ zBX#Wf#eX&WFQ)kTo0K^4up1q1>RS&22E;lDVaQ9b(ad5q4W?8{>6#=AjVlFMreFao6Dq*L7^So^*P#z7roPZr z#8R0s%d*fYDVz;l8500!oEIsfvDC`bkY=aeihm%5B2y^|qg04k^CZi*TNH6s0r@4R zT*rd4R$YN55~2kGFi*@zmoZ_O!Ivb^Bkn4#b!aHSMm5DKg$fCEDM=A5*CLvj1ePi5 z*EbfnnMe-}z7LJT;W32PVQwhCQ&6Vj$`BwR!i*4RKh%;ql;0>Q6CS%L02nb6d;(%n zf`61H-Yvz5K!#FUgAE2pol=te+6WZbwpcpk3LQ(<-mBEI>%^)GNN~DnG68xmlA$TlkeQR~V zAQ>pqa2s+Z0cZLbjs!G^AEBXyDKDn=4Szlqv5ZmS)7Y_R>ske3mz{m zl@|p}lQ<6X8`E%L6@Dxgv6iom8@MmERru`mY7+HIzfRV9RSADRF&_YhlKr}2_*^Q$ zK=;RwkLB`k0>>3`Ivm!^^>I%t#q+RcAVOOOJ@421`FgoLp0E8Z==rc7AD7GZ{(nr% zLX;M@+p|NcRgly8u*58u+vxP!5C0Ucmk02!591Rlvrv?DzA6~iN`iu&#}E&!xBE$2 zDbmS)iJ;=lKp|aKzqW>yDpaH-f-I1263wq!%%LmVbyi_izrA@AsPKT)qmcz@H|xbc{JW<+e9A6i|D$!qQ&^I&0M)3N4bAd zJojqbf-0{(BdI@|oR7y-6s>F$Hj`BposP%-WQI2ep&As8lS-AVQGrbJJcn(Fh6+Ex z#llBW!6j=PGp4Y~)x{YAR#2Ulzb>wn3B_X^NUfimdxDWtQ34gfTdY<&3V-lHe0xM( zF0h-meroRGAxW*m2Km7(ie`at4G0*po19bVW{s9K*bH0Ag_NbmYLfdf>uVCA5T4<9 z<22GRu4m6`C7H6ArYI6Du=utWnkOzK(cu1(d$lx(Yjhk-SCLAAhE%vbc>+U&?wi5g zRVu2H$n6&I%eWHQBs^}C!GGN?9uf|vU>bI^gt2(L1`K1wuLLR4oSQ%0n~Fhb(2?3w zSS+RXOa^&yt#wSmfo?DusN?P?-9L$OT~Cw-3Spk-xh8={&(od+2f)z4Lt96ahcGGg zV16nf9{=;PfCeng4^kW_=Lytto57=Xz!bn>GQ6cq;QmR#5ew-W4u4OGb=>AH3k^Cj zaW_=2AM5I_l9-3Gf(};_ zl1_^pC;~zR7yu52@U8oUqWhlVWJ`ynlrbuVz<*e54IB)QwT;>6XlB!JT`edTQUiig zDqRE&^+w#D3Mi0rFm@VyD`V;X)_@M!VAf$LQ(~Q*C*hx_p-J!U>abWJCK0~%?tVk} z;nDCf3hy$|N0{a>={;Q%vBA|W-l2%!GkC&GEF3T(c`?0 znwZ<$+YSo{S5{TSuZ8#X<77V%-_*4J{`;kpa*=ymn9ql4-~pm=E;-B2L4U_>PN~hb|Kl45m?){Ja}vH$4o#ZY7O{!Em&P&HO`TSpf%!^SV1L;C`+l;zoGNS(pblaNh*U95Y!rDv&pt`F z4AGrlQT{u>P3NCFturA20YU_X-mfNFO`dsDf?&W~{ijMLg)mda!Ye2yZwM%tm+Q4+ zDAWih>$0qWbr6fJRy#}qk+bV*f4%NcD$jcsD*trJF8h5*phhBgs;rYPVkYa_Ab)a} zrFB~Fpw^@lM;^*rm1(le(lm!+h(JlHvRMbQ{G;laGeF2RB!?5<@-S5~%B@hG1be#O#u!4Du2(dUlpD*V2@nwIgrK~6?lJ*co9!h;&(WE%<@$q|T`u@pN89|6*EPrq>i{%J& zOc`R8q*cAYT=uCVq-|@SAQ3B=tji^1nIt)(f^&S=`zpFK2ttsGDTTpARM14aDJL=^ zLQp~o1yqd85z6sm(A5}>0RoXq#f)m9B(d|Uk6!(T8dXZ7yg>|mhy})&LKr!#RH9p% zsmu_XvkJj`(_U4fyg^J|ntv`&YeR2lJ5Mn(JKrLJ5u1}phGw%fjkufl5Oc^=Bg_M4 z7|c=2z!)Non7j595VGIZV*vES;MxZ29ruV~Be?D45S*LA>Q}<8jm|*_1_Y3?w&Eb6 ztwY#4`WoI%F|{@vLKi_n`maS;Hi0OnV;g2)V;g8|gOFy4IrLDA0DrE)ogn&M5%g9G zp+qN1^iLCMgN8a>5btbo+gFRAkR#{3`GqNRCRoozUrTL+*+ z0K-;|fJJWz3IUjC5c$l6+iiNYF#;_lI#_UG0ZjYX{w!g%{2VbG0fU+hnKi>eB-b+0 z8p3oq_=|>9Go&DcXnzI@A%g%p!q*It8|oW}f&>s2gD<3O!9sTiq1%|*fdT*?frqcO zyu%>3Z5skYO|*Bj!FRM6ahnK1jcklyVKEn#H6M;gQ*JaJjfX!5xM^K1#^c3s_Sg0Q0~8`RjV-0oPXqt}002ov JPDHLkV1l3TJd*$b diff --git a/TMessagesProj/src/main/assets/emoji/0_493.png b/TMessagesProj/src/main/assets/emoji/0_493.png index d8e1d30a419cfae835576d64c5293aaba9c64990..79715fa2812053891d26faa4c27cde51c4bc4e8d 100644 GIT binary patch delta 1564 zcmV+%2IKjb4y_E3B!8SxOjJcja7-p6Bipl*Dkmo;A|fUvBq=5)gJ)HgbzfOdMkOL4 zCL<#&C@8O$fbYz#DJCZ9yO$v!ABt&KCnO{+C@CNxAL+W5?ZclmFD~!NrWqL;L_Is? zt%olwD?2td4-E?S@$OwoJ;J6vV_#gp zv8INDf?6^cJs%8(P6@Pn5U*@Tuuk?00000JbW%=J0C(?QqOX7Mx1daIL<20TyOmc3*HnU#vA18|7yGWmatdxIPqB-_GI}Jf(h3d&q~w9d>>e5 z-n&m!{cWTaq~?4qT&9NnAp?&7E;R?pT}=~G#aN$hB7f(#o0^x6f+`tP{TqG$m_2tr*k#5G`LhKoes!GaG zhDe!Fn;#Cu3(IWt2 z3C6T!C}KY4Vy_XtAskL1i(tky;>a(_Iozu$|S)Cg9IUtbX-pnn=6x&red_^mq+jPTq=W|S120EEw#jd)2a zW?U5L7fpP0#cxE>F-`cWi$WqIij(BUMkqi)okh{n_xJaYPY6B?LNJVees)EHI|+$O zVIkH|n?(c>5Pd5@knj~zkhhP|&l_-YT{IBvShMORF(Po+I~83JK(0>&t z2nc1;M80sWb@3}XMoj_;)aiW2tznFSCpa3Sq=4XB{IU_?Eq)*%`*;56R6(dgv?;wH z!s;i9*yVv3NgFZ%bN5)^S&QAY`ss6y{Ty~q^LH-JXOleubT^L)bknY+<~(kNGz^m^ zg>FkIB+_scCFO-d-=Ge=l7MmC`G0x_C=_iXLjbj+w}Fyif)hvAVec56tBXM#Of3Sg zexS=mpo`%m;B(6V)dX8RO8K$BkeH1s`A;hu8iA@9r*!%gpT~jG0KqV16$Ewp1|n5e z^#FNDVj#HdNyHKmloP3az^)HK&T-SGl(Et|8L~LSbMDQ2e0CoU@O%ms0)MH-P*4;D z1I8;PP(Jrb-itJ&sX|F8r##{yyh9An0w~T;bqLfktra(nv^-*4==(^(U?n+nO^Be5 z8NEiDL3N4PYvw1!C)wNHp&9nPmV#ZkkL7XQr4(>9DQ zQpf`=Z#eKOstg>xysp1NtbezL!LX|$5hA#j*IK|Me;`<8Osw+XHvFU|6epyqk_)aU zW(f9#+FH7NU}PCLX(~>6?|~xWdu`kSK}}8L2bPB!tzHKP0>YS^W6R z|7ve1BZlL5+@EW+cez!=7A*Xo^v@5&xw`c>KL*%8f-DxEw^)9g{}n&ALofc^D~QPe O0000LZ$!z9Fo4g0_%#f1&spcdMm7R81R z!GR3)yCMC@DCDOW{>d)bniAQY6aB;{@Ufx!2s|VR`sAOsb_)INu>RkC|JrB&)Y1D z?&cGvOaK4|6iGxuRCr#Umxn^*I21(}Qba-mv#Q0lq*vPif7@O?MZvR^VVS*-6D+Kg z`-&y_>nlA>#(zU-JbC!*{|K{ZgXejc6~%u3JeZ9qe+GCM4(3HwuUD%LX|=A4`C#~c z%4GPQVfv=)mfbR`TY)kgf78Kpv0imFzl+*jKGv}E4JVU9R>J_MZGP3N%I3rWA`Iun zIwfGU`c-vN&c3eCxU7)FbvW<}XHvSTi)`@lr3aLuUVr0tOZ1ESYsPq9)OA%=bq!EZ z^^z~o{! zxmC=)&_YQix#T=AaeMsAWD1NtFUyjboJ+5t#=m$N)Nk4grKAJ_cVY(3AyF_m%ba7r zl)@P`|9>}QP}h6!g#d!X1WyW#9M=g}f}oVJMr6-F$1<$f`%^@4h~DVSV;YNKC<5U^ z31OYy7lWU|cwSd~?FbRX^XR=NN+`L53qn-cxNibs2yc;#UjY@41ff94h4rfX$;PaP z3BzJVDDHqrke(4h$c1A@?5p{tR}L~^Q#J`fgnuk50j>zcoR)h&?xmuT8lw~kPcDD} z2TH6mC?|wwh?)a&)pH3GOp^(~oO8zWf)I%zwKv9V71Jp!Gg|gt47fH68xY(tAO<;d zQCz~{js-1n7a{xt36(t;1LfJm1HsLBJqVi0sJfe7Qr=6}3f z5dsy_{yyd6hjuX#wc0I@;ojFRd)uwcZ99ckYcDtAM z*tT1ZTQ@*N8+kytIIMr)?YdyXG-%JiuN^)zz6l5=iw=zK!ip1qSm&5cki5coe{2^< zgRrcqsN1d8pY8eRJlh5YnzP<4&wual=jC!!DPBfGnXCO~xqJ)bn>utU5Q~NJpY1tu z-ZC3p&>j@F->Q_Taq6xd7g$;af*Q8J*2;NTe-R!n1+6cUJ% z2!wEK6cf?cJuSODF{D;`rhl9>1{@?p2tub+xVuE?$HELn5)o2y>TbA?&wQ>FAyO)) zxBk|mNE9c5lq7MaF%WVpsi9Qfio{dhb18(-;iQ8uNU>rn#c?YV*dT_dT{Xy)jK>8H zsQgk7RO6PWlu(%qwz#Un@hRr=m`sM&{=E&!MY9b%>$dIb2p0BJM}KjUi7#z%@4SGT z!)wyfD1oU)UMhOq1obE}l-5+h?9^ZlJhaCTORb67lAd#z_^n11iU5Kh7W4&@r_dmr zstI)LiByi;g$)et1tFwV62d#Ro6-SqZimr-WWms0r*={h0pJ1%ss_61D^2de@NkkI z7MvtXg@y-))$YF;27e3{2xSsb91i?<2w+StAVw?MM(s%*unYt6HA-_M81v1PfOQo)>B z*v5UpoL$bhZrsa)zM5Irr-0)@Q$!+6b;YT2xX)1rIg z!kEIBVxoLUx0GGZ$iv;UjgV(G5)KH+iC<(o8}aFf6kij)bz7ezdNpURzjqa&7eNslut3w0H{Ew|(#zDM|nU01$LiPE!DJ z{<1O^PyYV?+>?*R*0w0Lj&cA11+Ga%K~#8NrPzmZ+d2>h(2$Z?)QrYn)O(j}{{P3` zU63YYN>-eCSASNL;RI)P7f_*peVb0(GI}kYo?&%5zy2|8qc^m|{Zi#fMTBM;n#0b` zFeOJqcYn9r<(thW-}{~}rb;E*CIl}GoBL|n|08jbuBvd=eDjYGH{Mh^nwX9*&rC;~$cL8UdFqQM<< z$V1Qb!d8Q5QHQ3t7mUSm%n}q+WDcy6P43+#Ab*6WzfT|_YcOyssN{-gKGnqFh6oWi zV@wOk1W%Gc>4@Yr^Qr$0;f3gHb^7AC*GA7y#vy(@1>G?-4y3vMZPd zVoV`{Q$s-LTC5Q!atB814&h{am=Wzh&ZqdZ43Tf>YMv3199>k=yF>U95jmX!%BU&> z#D8cCfeuMdM6`Eq2_y9UkpRICi)nrwWusA2b%7)!Tsr2{#esnk^g=WmgylJYCK8k> zGOSJ0NtJ3SDM>;PBXfPvY7lM52f;vK4NHL4vn(ZCWZ*y~BJ+Lc<{fzONvy^D<>lpa z74_Cq#P#*%_3|!agb{J`&SzD`bqrxPdw+Spu4`d^eSUpe%~qH3^|O(I)esWlJDL#V z@$C7un$0d_F{vWPudD54Hd~Fyq9h{m)i8wcJtC6#?dy!Hm@Q84@n;q5cc8CuSFhXm zq-aD4qe(agG2UW5vRaJKObZA*kLj8w#sb6$MD&%gBH@Htggrl@3d-VeI>nPR@qYwkk$UZk*s=r;%>%1kp7jrS}dbuC4R5RvE4X+s+G z%t9`rlBf|Xh_rPrfDj=FOtUf1%;V^!CMfYb4RlXciavgaesh{gf9`N8>Q0ae6LE^H z6E^u$L}GiRIY!Y)yX)I3C8C~&I7WDR$6_u(R00#W?Hs%4B7~db~C!N`KLH^4#V0)nd)c8Ukf|el^SHzB+cGw82=aiaQY%dh(5;CNLPA z1d5xEYXP|5Nho1R^qek{fPd4ceTb(mmrIqRJ-$>NMWB!SX}c%`#!?0(gquZ`+$2&e zJbCD#kMHv2J3LS@^jA=EJgkZ=Hjyt$RS--R(f*dOTxvxlOGRUia(o6(k2stREvNtj z+HfD;kMz+>X(&daS3I2uwhl@HZ9H`z5S=IA0e{4UHtJJe8OxN# zsoq#gr$H0a4xO&`>v62EAHqno!!J+ZxV2A z2FAbs{-I;_2M!pD=_U>O)&t=2FG2c7zi(LWN9+Fs@(VO0gcL#;A?-?ckn`f9KuH`s&mp1_5|-ZCEuN(a_EN=YP$Dfq=1=aFugQa8NsI zYHNm51+9Jw%%1?&s{*PQR*-~cw*K$2DNA!UEg2^U}cJCbJXGbtwoqy*seAX|o)2a8@>*4C-<_Lkm8%(@@0p$-s43|>sO`l`Desz8)OxFy2 zLa?ay>n|#Cpn}b#9HElwFG`>qh78~li8z1#K?qQw#G@QXiI1<}*8oeH$8m1c;=k!v z@8Hk)8^c)#90cIpAveGBhx71W0)rm_f=?kZCkYcc4}W&UN(cjiD-4Cp!SoX8CUBp< zFND=12?ZkTbe-S;X&@w9US!GYzL3=+$%qgLaJZ5_T%HhVwpe|xkfcp9so_`Ib2%>b1lI%2W#Mg$1isTu?@_#zB9K`}(A zh74~sO)5g!ofW#6kUQxJVUG$+NG#*7ic>{>xLKCi#I!3}2<=h$&kzNvPibLOEPaYaEF1 zd_KEMks{R{k)DVUMyk5GmfNz~NVsf>5$$Ea-R|91Lnrsd{Dlc4RGpUfVY}TnwIU$5 zl7FnPyJEN9mTg-JTgC3=PCLPyiS)GdfdHW{%Qk~k;an5+5t{_iD-f5WRUHvZXCRs# z5i%^?Ev4L7#fUIa0cHQ*7OrjN4T!#snaJMWh-iD_y(;oSh>NQw-hl|EB^s%mo{$w0 zQr1OVmUQZeTO3VKY>H-EqWtjzr$|XeDu0(=M@%|G)J1VA-^=pjpG#3}1_J5*zTE%& zQNeK#kf`KrSP`XnZ@!j71Zcd!gU}X5j)Z+goF)4z4E~7mb$=-^ z7%6q+!$tFfm=U4K;L@R8EP`WyLV%zmEHQe7Peuga1LOr*75t?-aNL-l(6k_&c~8)t z3?Tr7{CLa_A#m6trX%bqIL=c0enbQym|ob_8!{k#+}>q)K97PsK|)I^!}em!r&qUF z2;?}}htxn&A48nkk~1C zQfnphfC)vyupEyUR%tohnfwKj$ZKljM*|397~w|*KZl?OzB?Yrn}GqvOLG^YbSM1I z;P-j_bZ^aCqX47)(STk+p=7%y;B*fO7Jgy)ozV+|g&BA8W9CaV6wj1zEfD;PN5F3j z(OLmQky4>Bai0DXXR@TJQZ!^an?LaVIL@~t_zyE`1aQ+; R_Co*w002ovPDHLkV1kNbI*3|1a!NAR$$!C`ZA%jk2*i_Yqia)+ zUp~v4bNKrE=HlMKr;}k{T%L`Aql0OEcyy?zr>t-Wyo)5202pHc000qmQchC<;mUlN zwQv?PO=9W4o7|Sl;zKS}000G$NklqM%MdcUnYm@pCR5C0GPAAu=$El(lkp-5s%nF&f^spP*w)X1`E0tV z;-vL1lf=PdI zW-~un0G%-c){Og9pTXuc~Na z4GTdPhB4NgvaYJa$LCR1K@ddYbZA|)x=x^hC<+IcGTlJ$p$LPnI50JM zTm}Io#@B6F0rnjU#lk4K{GZoA2pMW)qE`xpR05R%9q8xMir_$^4&iIk7v^KVPobz4 zrACR+L4T;LkBnft7+8t5z<&}j5y!RieV?KN&75k_tDQU(d9{iz7SsF}(MCj=P>x_{A9zV1idB0|_cAvg-ebzSWsbQOpB z3^Tqa0G1n<7$U;}gc3(A<@kjxk9~n%3=z<436TQ;4G_oka`y|eBDv=|L?do4aV66MLR5sq8roV>h{!LDRW2wFe(eFl zNq;Se2nKOD5Oslp0V*$vy70}Y)h-Yow$UH08DpwWLEy5W0w$;|oiAOKkXq0}axhW> zMt{IX$^$kBP<|FBnXsp{=!Mt3&E+#RvAH}RDxYy zfyW);66bU}9$!z6`$ce0ugBx*E}keV*MK9RN^(d?jpiA2-ztP5|NrH@5>z<(SHg1En&3b*IGWKroP3^)6~F~8E+Nghs)vI z!tXC9_!Gf%97fCZxi=Sob3qvrh=0H=Z!_{`K3$T*lPhA*fRiidZ-2A^7I}(>iy`j$ z%>fUCz|ma_VdG-wp+{Ii$XFBP@~WrbTw3Uw(Zq(Tb#C>D`Ex{R-4SSL#nl9WsN!J= z=vd{?S9b@0OA0jShHy>mDM7+bNk?|;h$Sq#zZLkhQb{8ujDd=iwgqLBVbZN z{Tg4=eylqxRYE=tOj_2Pq>aleyieQ^9KoT!)le757T^g@iF4Il2ST+ z$9L~bNo)RL@Vsp+T0lh7dOQOcg)CPf+|36G+oxbe#MOewlmhbO_JBEHXhBfO(`YdB zJ2YfTpzADF5(F@O5HP}7;eWif*n{+K0ESmWu@9CLUg~P>%saeNxEORnd zOh^Snu`G1(rw=Bp1p;8>I)?M82?z?b^hB}L@#{oke_i}L>n36Q1sXcEgjdxmnGkhM zw%f$eRD$5&k8bA)m(me2Njbd1^@MZMo(1YZ&c7k%pG%Q7-q0jcDJ7qOq9lZzD~a6cdYE|&fD2#hJGk54uLzt7y7-RsQ0t^W^r XDmnM+y0>uv0000WG0#7trivR!s7IachQvg-X==@td5&b81z_j9v zk(`&l-`dUO*ME%C000H}Nkl?Gji zDwhLl_bv{Pf77h#-rO1&0&d)<9{wKEya;04kH|pg2Y*jGX6PjMCqfP_d@1nZj&A=z zNOTpO;5w_BK7irg{(<0rp%mtxWt6E8@H~#w2Wo_GNuyEi%enY&Cfy_<3@QP2m4K@# zBl=@f{$etJaLWWChOP+=)dC#x@D-xJ*D9Y7u8W-&w=9MNP8vri87Z)$TQ8j-#z(@i zI2mxoFn<#gS)nkg7n7kZ?seMN?-}2Q?T$v6DEJ(R3@Km0rRtdYhm}7mwy%HBk{b?- z3c=KHv_fI1gg6*jCdsn6K*aFdyBO`_#6turEk#DaK@8agM5jG$8^4*r9NtPHpaLHN zx*?JT2^()sv6!HOb-^M!{tvVYaMCKC%pWXeEeNG=^z6NL!LMzNA9 z1(=w$Le3R|CXzf*pCU|mmkz?E?@itz(8StC1hWP&s6khISFq7a-CdgGLhQf>A<|j^ z!hfP1VXM{hL9LfGKO$B>snuGnfWU>b_BzFP2ybBnf`z>!!q-U@V?bQM_gYJIA$P4w z@qb4KQ7caTBf@_ftd`5=V5v+{5)86gE?0wre?&a>ykfSuaz)SI*%V}DnY6^ydF&!% zgfD15RzR=_(VEnq9N2-8$eo=yl&1+H?Im@pcrL?gT`!kGB2CqghTS-9Q}mI6oN zXub8Ae6@r7D`~M5k;@`HjbK7XFOP@*cz+QKGs(!}&Fy2q|F{|2oB_fHgr7m=zI&}6 zAvh2YQM=#oFCv*Cm?C~$2kU-+97iEPA_le7p2>ZUu%l>v7*61$hj_+M2p)I(>*x^> zZ^2M1M6b1ylc1;W@1LV!zyUEugeVf&AUKGS`Lx4Jjsq?n35^p0 zWB>f?=NrJ9mTn8va)Y3_e}4V>D}M}vDB)ZpBDCwLws7pHH6bkK#*rI_n<$D+NxhyR z!e((44R+x$ie2bVM8E*2ks>NnXIh<4C0CnX6V$bYBiXSz8N4xFd^YHsj44EQYEMfi zM4k}Tp6dIMfmJl2Wm>|vIWtkTgWFR;IMd7)-bfKBYG8;3j*j1e$iQ-g0e?I-;vutN zlmG!#bU}NPl#(+V4XH+iVsuvkfgyrEf0tcm4}h3sJwY5rRWVt&8OO5`V`xP=V5*vg zz*3~DrwC@L??a4WS@7r<&s@$a4MR~WpqhZ7#!6-63u!T!5_-33=P_-`6@e(a6omqq z$f{Dw6XHa$Bm*7 zTbmv@@%}jzq!L9Dj>D-1%&y79ki!N0&Ek$tg!$do88vWXrQ-;-7(kZ#jYt7=el`ZF zQlEnl$B`D(5COsT8-MB8HV|-ioMq&J;Y=NY&h^sN%bWum3DB1pFs4)5I!samCsX|Z zbx4=^`78*Lv=uASo-3fEF7ZH&Min4Vh5-bw2zle`GL;|BI00000NkvXXu0mjfw`XzS diff --git a/TMessagesProj/src/main/assets/emoji/0_496.png b/TMessagesProj/src/main/assets/emoji/0_496.png index 3afb52cdcd4f03797f6c593c138292dded02c529..1eb13efab334ba6a0dea5bde8c010cf3689a762a 100644 GIT binary patch delta 1456 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 Hu0mjf`t66) diff --git a/TMessagesProj/src/main/assets/emoji/0_497.png b/TMessagesProj/src/main/assets/emoji/0_497.png index 5caa8a5dfff5183845e9fe050bb9da3ade261f95..bf3c34bbee423fe8db0a8ad1043ace9565f3bac3 100644 GIT binary patch delta 1319 zcmV+?1=#wB4!R1EB!6R2OjJcja7;EYEjlqU2L}fIyJr5Fj@L!}@`AsO&epM;R?Es;Sk*#BxO@AihX z7-c6QS!=~29HMwoFs&&MOXA|EAsdwPmZsa`QWlrqAp0?Bf9Bsn~|4aRCCT#gE3q>sq#<~f*- z7){d1sedB%!R4$7N5LzffU>74#6Xk`dv;%=h}7A&D18VF0tbi?MJ{~+0b+Nk=uBY* zCm@C83Huaa<(wk)_lxWY1%ccT(h-_>JkO>Whkcf_fq)H85)jF^y#k1lcuHb`Y{d5k zUKkDsjzI(SN5G(CfLKu+b}CU&@H}=naPQUeKYwEIio+A>l2QOPW7ChLgI9q(7{&%5 zrMMg)r8X#F9+sw8wi&ve1G-^sP?=?zAt>zSt&z%MPyh^*T~?#@GVFSRVZ?ROnx?@) zP@sG5B!{TLaUFHnD`jCCVKa=Au?=cP{O_cI{9NINwGWHv&om^3lW1~M|7q4CD&S2~ zM1KWz6Q@uz`R_Dsi`-3<5d;1GZ=Ggfg(860i%|sy*G%g`%-?@9IVolqDvC523w`@VD1)rNfQ`hJcxcz?2i!!`q}EP@lbK#p&S+zCnXzRfBirA$=J z&W}K!n(@{U(QhCb_YNS-q}KyW@VpSLD6>=Qo0i-r{+7U#wHGrm z#|(@vvU5tA9UeDE>h%+mARDB!(8oEI3J$xy(5QgO!s+;>%s%l5RaW^7gcJ?dARnTQ z9k%+YDAeXqisZRrh>Y+R-e~M6Kzo2;BykJACTV7|sqt5TQv?aK{EFf6$d+I7L dJ$d!5{(nz)!G;R)^JxG8002ovPDHLkV1iGXUk3mH delta 1783 zcmVtBIbSv)VK*UoNGokXC1N)rhht82MkTL*g-|eeMk;?xEs{LYK~#8NotKAp z+d2$}>uousNq<{T?JdteGW-6Ibpe7_l+;=GmycxgkY9d)AgTQLNQ1%9XfXKke>CX! zE^b>b7ZkQ`FD|-+?~cE1x$D*8FqzzeCX>SoINzWQdbjTS0E6!vx|;yyV)!*euNAH) z_3$R-0FW;@8Q!`pG;sGy6Z=@Zt?p-pZY#tDn2U6PtAEyE<$4#N5ImDaxQteC)lb_L zx)+~#Sk*e<=U=TqWOQLBN!0lrh405QxYk}6!UuZ6vnedFlibj2y)(I2e+2W!vFE|) zu^x{-uQ3cT*Z@MJcCH3zEd1IoIoDQ=@#GyKz(w#F9=zP&T>gXjwb?FX!59FjCkj{~ z)GLb4o61|p^q$>ydx9Xl{FoqyXnEQ7|NY7-|LLRKb{#-!Y!iAoYe z8^*Ya07uXQWE%*V^M4U&LQ)*DQ=&q*X5ce6jZUnQAViP?qlx$ph)ODS5m)KdD6I<{ z5%H^Lr% zsDGE2=Qyz!$4-@|o9$#0m)mI?P&Q*t$@ChtfIi@XVsVVg0K`09UNsT>X$1(u zKw2>Ejk!VKaI@kN#9%r&*NihJ5K&EEA(m-HE;LtQ8N%SSsw@LXJ3_>zW2|yQGz)zA zCtZ*W6(65uGE2&%W@95FFkQsKY!)1kv41#+=w7D=!I_BjrzAhlX0xXqw*ZtD$GMX^ zvstps9c~e+bMdlg@~ScjF7iA{c1!3Qgu1R5Ne`HF41{|}VE7MzpI3R7Pq>{C%@6Rm<-_Ci-+Lg0oLorR zc_|Ai{Qwb+u~l&_CWj(F-iL~5Vt;6+!Xn?@PwtL+anPJ`C858RqZ%;)L=^Z6j}gXP zJdH!Gq+&=w8%+3WyguN&0oFI>B8UR%cN>SPMSu;PKMn+LPa?D-(4$5%s;nULrQbMO zM+SlAN#ep15JCg7MQ{`%q(Sr>TTZWmFuQ?*pv-7*bqEbgbJI#)01*LV)PG!NZEQlX z$UxCi$h`I4{lsJT6a$e-MF^@*s}3NrFc`@mh>+U#q0JhHF<#Wf%-E5M?uHzkT-`^y_?TW;z2filkC9ii7|N3L%uu_L&!*9w0Ch3lWls zt8%f3<9Jb)4wHhMfdpo=bARq#4UNx6hH$sJBT0?@7bV9k*$^pW9{4GpUAj04*DBV3@LF`&YH zUvY~V)7D4(3}o_i0&v9=5QBDKLU8dl0x=+`wBlY6b}}P40l%hh-!hmsvP&xnMqmGz zdk98+fGBPxOd6sN1@UD_r;QK^7=;tzw>w?1@I4KBqkdr3AN6b!zD*epyS-j_IQ%dL Z{{ct3YTPzfeS!c0002ovPDHLkV1nPtDfj>Y diff --git a/TMessagesProj/src/main/assets/emoji/0_498.png b/TMessagesProj/src/main/assets/emoji/0_498.png index 10b10ddda9fec443c4d04dc5ae949053f607d816..782d00aadb67797ca2722bf3a59b70bc8ec060d7 100644 GIT binary patch delta 2098 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_499.png b/TMessagesProj/src/main/assets/emoji/0_499.png index 056a7796344357b147df208b6dc759b671d5e36a..aa1b6bd28f62f5615ea750c1c706b29457c90b78 100644 GIT binary patch delta 1975 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_50.png b/TMessagesProj/src/main/assets/emoji/0_50.png index 9a5e4461dcafc145685113e1431e80a6a66af6ec..bfa74f044d216dc3fe0047cdae0070f2b75ced1e 100644 GIT binary patch delta 1487 zcmV;=1u*)<4dDxrB!8t)OjJcja7@#C7RYT4$Y}<}dnW9I1I~FI$Z7_~e=*B%49aj2 z>5dx4X$b3?5bTT)?wlXwj|wQ3!hbgZ{mK9JZ2##y{?#`B z;4%OH;QzHC@}Uy=s1*ObEB?|g|IZQs$t~N02e0a>!T;+ttpET7+et)0RCr#rk=b&iKnz7g3U^VVLf+N;%H}QG{Qswo5X5d1$CJ#| z9GV9j>7d)({eLsn-T$XT{=T_nMg2t71uK6ns#x6|t$th3_PMFqPb_88JZtLT&5#By z<#z@3BYl62QkWhwLJlKpv^{=HQWYfFIkUgOxHL%~i$BIG8^8!j^!v{U{-!lF?6!eT z8FsSY_eidxXOz$&w?fn&4GIqc7qLeT`Uu)}uiE;$`hVI0R=>*L7=w;AxQFy2XbVr( z4MPw{n1!tU1A&Ww?U+(*#e(?^$_aAR*9^>q-bx|G$&!1-0u^u#{>qt_8_@4^=29fG z_JyEf!`6nX0jrgC&PkVx*3DCeQtI78vp$XjV{nByf;?;7jFRY}DC-!uC4(B=8M$0% z1~n5bY=6oN#RCm7jWMW!aHz_`jRh27=?nP#)ez9}iKyam3;aZ+!ge)A;lYN$iO6Fd zrfbc#8SyPA!U6n4{yRLp1agq!1i5gX;Ikqi9r*00u#JbV4Ma*jr4+A{BEAfX>e>#I zu>3G>*OCJ(X5ytLEu0K(he_`99ET1aTXc-%Ab&=>C&sg2{4k*6oTU8a;dkwI+u|w` zL;-kXa>qmxi2ah*k72?p*fNRI{{Nr0r>d)`B{$6M&TOsbji3rqf7`-0` zJT*ikp9i`$;_w|2)8l>FACLFXVQiR~LI^Xi ztA7iXw&Rn~s)nz)ah`GO#KcC33dA)Tqie0vxZAijFx%$RXk%OFlR!k8XYuQF7lI57 zf`3xG@v~+Fz!J(Cn7D#C$UF~`5CaG?t!5(&)(@blSO9T9C1QX0b-q77q!Sp7IA<mRXG2B-;mkSnD9h6rPD{Ib)var0*egVfIcdW0ZCfyhjvSw|)*C zh+d|7Uecy+mgOWddLlaCeiELLOaLIE=MW$&A>Qf*op1~kj8%$QE26_K$iRIp^?#cX zyDfKu7-S$t*C`@YN5D)*TstBH6W8klA+|dq_D2vLBN^UmW3;^q;N#jr=yM1V*i)&h zhVi(jR(ixRTAR)z4-TAo?XVQ$8v7{ni?7TvnCN|H?d`^ZC*^jtw)42K4k4qEPB=z3 zkORQFJV4Tuz#+EiBh{vkF|vUq@_%e3uwDrgLbg=)WM!<8-knZUpM_~Hr2WVPJ>P#b zPDVG4HupY9hyoLNm^nr?GE&l;O5FFHHeUP_yeZKN8;m@(wtub*)KTc1 zZ4_VtNhn|b3tW|w0|*G~0{w72g0ld!P#61G#J;H6kRV9Ct`CV2g#(1w2Ioi!In)x) zTz3J!5MWf<5G7X@O6lUYvBADD0)-hsI8guruovHa)w~@`MxYP_NFGOk*u+tG^Xnjj zK#@8Vun@4V5aHX}6^sZYwMayu_}AZv71{xlt44tGSndAPr*3iFf=N|wkHy>mCm-BJ paX=Nt4?eiF!v*jU*Z=>Ce*kr}g=^|7jJ5y(002ovPDHLkV1hLQ(kcJ| delta 1715 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 M07*qoM6N<$g4NRt3jhEB delta 1888 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%0D>p6BXcJkVk8(I2L{%qe!rwwsxli) zCmZ0plYS@~K^_%Y9u>5bPDU3GsDMO@RWXt(7s;oAcTp&)gj?v%<=yxA z^^|TpQqImc4*a8WF608_l|y*2b;2m1=fV zJI0(V^uH~;<)f;YgpfBW&Osq#f>UjdTi>oHgNa&qn`N#{EYz7p$MUXIbxP^5O6#&m zP?PtY0000bbW%=J0Q~+w{wV%f2^al-`m*PC*FkWQ%YV$%_R!$_mR9?`s)gmK%i@q0 z@_hgR1*1tsK~#8N<=0nJ8%Y!eV3a@tgH5st#%XtQj>cx`v7WMiy75{v8mVs?~mv#G=0j#O7y~mX;=wCFD)$u}*AiaWyzO zc{B{5jepk*kw=uju(G}V?Pz~@_u9+u?*7ry#`fxBY)oN(WgC&MumAWFqBz;@)$wM# zum<46hX&T+`@PUo&a=p3bc`kdK=^Qay}Q3p=YZGIKDydp8_$?p+sEp*wB!6FlRI~MZJsh4NO)SzcLMz`U59s8lr~bs$bf*LWL=r^e1Om-xk2nTVVJoG?JO4JOJ20I5{IAnkgF3MCoJuQR`Fu~UVkDsBv=^a`gIb?&LI*{LSTmk0%B?;!LoKL zW!r4Am>Z@@4`H!QiONXgm`x$YT)bIxTvyX9MAKZ?acc2y5fCU;(Y^nd5t*A#7Hu2L zYmR2=0m(2;o>vf_Hw{VBEzPM>#xD92UE9X`rlaYS$t!{^a~#KT48n18THy`Ja(`;g zuAQ>)C!&!Tb}?QXR2@s=(^$lhM&8=ZY9>?G%rqxrnYy*5s#|z@@8I%`%!}n!Y3RX z2x$q0KKadm!+7%~Q+18BP>T;*=jW~SJEB284w_9xFtl>!$s1oG`Vs^gMWdl^l5B0# zz#viO2A4Jo@p8g9Lqe1>3|>}&fFS^;(`pDD2n$4HG-2UK(Ky}MsdR4`^?$Ys2pbpd z#p$UcP$J|jgcM2$eEa62*G=WlIIoP&{MpVdx7(5~Pvwl2<#2Y;oMSy7c0HoN%vwp(>p&R~0z{r$Q zMZ154&E@c<*9U;8?fy=MrGE!Ri4c-65ei7!0OM49z1HE$-G)E_q)iXx1x0deuJ1UJA%PneLr@`501O#Qp5Z`f zj%LjI3eg#yU>OP_upR;pG!pfea4lnI!Z#soOBx6n+l9AGrN$3}2Y;alFirnq=&nZh zEHO{ZVA4!J&j@*{iP-)4fQC_wdfW=lE^7fkJ?umkEFJrV+=A6j#~2oPJj@YnRrYVEXm-N zG!#S-(u!$3^XtO@hSQ~=pK=1Tkze>Pca}UXkw^jEyE`9`L}q56k<89Sq7%QKSS*I+ b|BL(sOcvq0&(E=600000NkvXXu0mjf5haMK diff --git a/TMessagesProj/src/main/assets/emoji/0_502.png b/TMessagesProj/src/main/assets/emoji/0_502.png index 5f0010aacc04f6a3ffa332e95e14ba1d7cb95578..a8e378d2121bf463af85677fa8f6db88c3a92305 100644 GIT binary patch delta 1992 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 FV1l3#d4~W1 delta 1677 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_505.png b/TMessagesProj/src/main/assets/emoji/0_505.png index eb1700d9fb4d50aea223814cc80f42e2c603e8c8..9d9bc750bcd460b617e9605b42a3b3dc1453b5ab 100644 GIT binary patch delta 2083 zcmV+;2;BGO4X_Z9B!A&hOjJcja7@svg4&{dva+$ikX6g3e7==!*q?d0j&H`s$Je2K z%fhVIpnZyRP|3r$+M#>N$i~UKo7bOurJtCimVcs`h-6t$rJ|o}XJlMhR`$}cqneZQ z%Bc6&wEW<}`q{Yj&#cnY((lEh;jD-2zntHufV{oErKF_#-G9C3xt5ZUjj%^C?6+Gd%fWVn$Q1z(SNktZ+wu@>D$BM^prrFPrJSL zhY&pwY>AiyaSEACuYPZ&)oKSrX!^|fMUx?t{tva$g1#aVc4gxYBX;k7Mx!^J&gT=m z+pQ3DVvy>IyvykHY$|qY4~aqTgz6YL!ZWe2->#ugnNOxR5GaKhRLluSx{q2+4?%dA9R{}WRBgpW1sG6h6(0m3*}vN8C`Z5eVK)n>QN%p|psiL3hZ_l* zzVrwf*f^c^FJ0TN8lVg(ipFhYJT`P^;H!t*Jbz1+AsAhdDhPG{q_M5f&(Y28tUKi{ z?~bJm({f_h2PFyYdBBGhZiTS>t$I5YSuq%sf5Y4kN>R+lm5hi9Z=h;#)pn8*>6YVddF*R>5+YUn1LE^b7@fZZYX5wgA3V>| zZwd5nSZmP|l&`F4Db!!i(I`xPS8223}l zs!h)_CBmdnyxAa6y4`M|gr9yz1ez~Epnoul7(RAz5_(cN3(^Dui9VfDG7ZsDlG(Bu7BZM zQ9i#QI$5YFSw29R6yKO4BmjL9gH-jYSj!z@ZM0hdBucoyjV&{hX)?jgm!2FMCKEyj z0g=b+eHbbs2K=bMvM||e9uU#k*+NCkjG75qm{$~SMqV>Nd+53V;R-W#5%f+|5Z#yN_jc4g$xBNERtg)P|wh^>|i z)o-nimLwStxiL}}_jl{v9T1CQx|og9G)0rs?&ka5{rc|i?*3NEnaMn!C4Z}%I^ul5 zvz(`+5ud|>)cw!JCQMdkQ4}Rl_y!0FFm+wqHIRJmDPpa#P;#cDo-xwwsNDV?sk!rkl-j zhxNxFkIN+=Sh#uewcD)6*?(!Ox$gj^!VV&4PQn zG1H74xdChTxvVmd0RP7-JKsgaM(d?!{SMH?Hq` zj>QTtEP3td!g10Om4O$|KW<;ablnmTk98(IS5^J<6U2q<0wI`HhJQ0l2;m4PP34Ih zLs7)iQ~>G-F$+g}g-{zOh=%XFu_G*96g-_lqjaQ$V2qc`v0<8)91kcZ0wH{)Sy#L1 z`U6i`@am;fqXk{H=6E?Cn@l%xQ_!+7fv`mEtNslDr+ET_FqnxT7^7R*WI_f&FPRTS zZ)Q0_Ac|9+`>Gqm27g^T2oMCI9Hfj#Fk(P>6Jp@2)nL^p!+)}2KJ@^4GVJ?qY*`ko zAuNi5T6&_!MN`_42(lslTKI7+7a15}5{BwW4l`hDJP6G)Wy1;+{MFBk9z&c~# zB8a!tIog0gaOh8l$tYrCASW{64eAX&jdT!G8i1J0yZv6%ZGQ|z1cXdtfZ2XqolBQy zgMKQUTijjGy8G_X%^G1co%mf7u%Xh3GTD2aTkRfz`)_#P=Qx~}jE2fUH{Mh0#wUh_ z$PldI<-2F5P(VmO>0b@LxyqR#BFPgEmO0Tz0(JrJ;IP?IswW17WCX z(5r#RKsk`~(0{}U{T*Wvdo)k_ld4Y)l;_32CxCJ3147-EEs%<&4~AY22CjdJDt@QV zg(@MQI8GA?H0n5UD(3nlYQTsbb_pQ?AVYu!6!9^&&YNJw9w;QFh!Dua$JItPE^-A1 z8ODRUg^xpS5D74q)XQ_4r$2<8-!xTH^X8&KfInBO(;PU58lC^#|9?b{$Tgav0;B){ N002ovPDHLkV1hkd1}y*p delta 1749 zcmV;`1}gcm5akV!B!AdYOjJcja7^2v7ucH?$;rvqn;YGq6~M*Aw6wF%lNQ0Uny|32 z!@SaQG}oSgBt9`?N>(9qDqz`^6F8vDZ~hlhufl7Eu_`qj9G9`V|Y%AY#_ z%rF1WIseKme0+RAA_g521^?1S)YR3>%gg`SV}VQvz^ZbXW)uAL#9}@U`RcBnfkoxF zKAnwm=;-O-;NaTY+vVluZ(20hymf(VLThVlv;N6r0000QbW%=J08V+%Bb_Y%{t<>s zc;Ty}V9d{T{C}Px_R-^f|)oPuepI=`$n~k&Y0?wKjr*{+0GlZ(D zx)p`@_qW%L?*M+Dx)V>RI>kr*{_lQ2v~*ou{A_$3;C~9s(kVVfbY$uHgH&;P@s)%K z;HkJ>01!q5qIgCM&pmB?YT-hgXojj9h8`hYP%(5!WfA1A^|6uWspo+p3>CHw&w%({ zKq|rD#k=@0i919H0CafPJWZRBG>=&YLuFA?49tL$7uP87Z37hqK`;OW1Rul{ za^kTOm2Uc3nuZk>7F=?02xl>b2cD-yH%?1zoLz{Ah1vm}oY zaL?mDFaa+PC&F{i&|m{g7lu~Ja9l^QR}dfquz#3DAf&R-gmO8~e#PvTB=d{^qi17A9^=B!W_UL-W*6T3R zzkfPHVDtqlW$A=u{=v(JUh<;>6y5@l}cE<#GM0mC}oxsfI zE{8u5AxA_>S8toZvNIw*f5c{^o@iT5TaW!Af*=&2WHH<&`Z?$!dxc(LCyBpte0>{s??H>q* zUxDdUhn#Gu>nP@N9?0ZAd`nCalEvocCP}v4oWTS?OOh;;on9bq`k`)=e*Ip*EqvPv z7Ms`2%V3460HElJ|2p5S2Aec96@N#*>04f-3{ksDd^<=s%a{3jFkGcurNiQuzP_%O z^Wku_hEdbM*9!68*W~PgT*>cfROx?N|{b< zNp_Ogcs?Y}vgNdw+X&Y2iVg=!8fUUC%g&Ed#1B)FZ8Ke_142mKcuf|_gnu%M;}_=o z>p1mIS+?In_&@~H_3~}CS|w&0=Qesu8pp4z*=k{Kap-)8!0qcq^6l3+UXlwMb7dOG z@jQ{u?J}MQjHs6)>ZU}aslZ2?uH$$;Qa}KL7)xBI=@Ms(;{#D%&guc7^rmT=PNyA( zOkmWh8r>-lry~Wjf$*!Ph<}kwh@S2fzugHyMa<56*3`JD<9}Y zCL2YFgDdR5lUq>8gv?od!3Hw|S%SJY*7>tA~)s)G@L;m-yK&HUbX2vFT-Mo*CzGiV_Nm`aBT<)tjo zg&+YSh@;8`L_i(Bp-yVsW(f5L?+yTFyIT2{YA6U%NH*dz*0suaRsGR6bNTK1H!T#) rUvIZ%xqVr$!ok1QSq=JX8~)c{W9NI&X6{>200000NkvXXu0mjfFt20e diff --git a/TMessagesProj/src/main/assets/emoji/0_506.png b/TMessagesProj/src/main/assets/emoji/0_506.png index d0cd795887d4896b7871a790a99c67e618640416..79eb878cfee371c1cc76df3dcca0620ed48e53dc 100644 GIT binary patch delta 2068 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 DM@(bK diff --git a/TMessagesProj/src/main/assets/emoji/0_507.png b/TMessagesProj/src/main/assets/emoji/0_507.png index 16fe89d6b840c91a60ec069efa71f0af3ffaabe0..daa20de15827802e7fe74985d2cd2fdb69a38f83 100644 GIT binary patch delta 1967 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 Qn*aa+07*qoM6N<$f{utqp#T5? diff --git a/TMessagesProj/src/main/assets/emoji/0_508.png b/TMessagesProj/src/main/assets/emoji/0_508.png index 9be3160d59ebdf7fc0600428eaad2389160b1d8c..801aec8592d749dbce9b7d0077c48892497e9f77 100644 GIT binary patch delta 1978 zcmV;r2SxbQ4ag6WB!ACPOjJcja7zrcXvxF4RWKb^FdWRhnOQR*r=+35xTU9}o1>P0WL;LOp^=%9h>wGHlw3EC zSTveqJDz7hm|!`zwX&RLJkZh7iBd3uOf7jwDr7k#Z9gSlG=ChJgL95+Q>dq=la7mp zfqq&=H;8s>PcR>wo11iLV%yu>-`?KW*Vm+QMi2}KMJE+mRaDBci+Nl}x}JId{rKY4 zxApMfuZCPL923l)Fyi9ku6GpuFQ3W)000|wQchC<>r6`i6D7mlYgdL`@S#iyY1xtpJ}Q} z$VfvR$JdABa~kU7)~#yUy^qv?9QJy{{^MjiWsJ$w$z#6{CtpyXO?r2eDYF)}X0wIG zrjPwE5ah*VV$D$VpYNJ4*z|89cT7dj`}|c!=yjf9gg5xW`M9Rh%RJiO+IGyCu{*F76Ualh|Pd!O%x0SCgEgR}vJlMI2;GEH{xLrR`@9h^tn zg=DesEyTZa9sFz_7hbvJrm2})BhxfhaN>DMT)?E6)ezXf?I_NOpKP=CUHiR!`OeV= zw11O30YQiWh<}EcD4q@KWM)-s*L75r7@b};l?%s#mk;Y=SQaAW=gX20N<;uWUAvs? zCg|Kj-I0k>0iwe%;RFy1nvmlQq7Mie5M|+W6+{L2QgsrX5JRVTbna&*1A-CvJ1$@Y zSr!N)v~>xUL{uAkVR8pCsu4-yGytsWMt@2=BSf|-<=-LX%;QLi@;n9QTDvw%QA!m- zSBOXqKs>h^Nn(JOk_*j7m7=7CKp#!48gN01qEukCMi@qWB57a>w_Lzrg||uKQW>-mgQ`K;p-~#~W~0PmD;L$wOXxn|D25?8Ox4f8w{lB> zCXA%q1YlCn<19NJSF2TKBpNX4m4DU}wtwB8cB|JSNrVoFLW$EK!xrN9DJ>P(=6Ylt z*Q=~ptzLtp6)wYC%bXpe)j9+6dTB&l=b}oJ-9sBO^75ogp&*G z{3GLc5QAU`Gqr6$ogKF8An@Pb_J>0pox_ZhUxD1 zpS(yAI`jlB0I*>ITYpDx6U0?7G*_4;F@ysqgrFDaz$QX%qI<)xZK&u&)!m|4H!2Fr z#iYrE?f72DMCZZd`RAda3F)<^!m$AX=J>}Z$cBWiQ2IKs{0kwY?Ethcz{FJ&?b`;e z;BBLQQZ?IKBVZla5U7pY!I99p<=3s$41oo-h%{8%O&ibx2!AlpLGKS5+z`X2&Bj6% z%Q@l%+*1JfMEHaO*WP`PgrqixTqKNopXl}>fLj66<@J3z?-^~i?|Z=$c=(iYFChd| zJ^zf$CL=>DnOVb0lVbSpWb4 delta 1732 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 IM6N<$f`aa8+yDRo delta 1674 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 O0000LZ$!z9Fo4g0_%#f1&spcdMm7R81R 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 Rh#UX_002ovPDHLkV1jKY;fw$P delta 1739 zcmV;+1~mEo3)>BlB!9_JOjJcja7@{q70AcNyScg1wtBXG6ws9wu&}U!f`W~WjkvwH z)tMN|%F3mtq}7-d*_{{HniJ8I5yr;I&X5wGo}c2V9ObAMy}iD+x3{XQs>a5~>8u&_ zxgYPd9nH&% zZ*SV#+F3LV-{0W=)ldJ;G5znfJ0A)Z4hYGgKm6Z=+s2CXzbfs)?ovK)x z&)tmy8~?9_PP^4=4W2>mcBdmeJl`HX*|tuIENhw@sG#@f&O?Bwu}x$R<*LeLGEvmP z)#O3@4=Fx6eH#1;q>TwQ_M41Pyw>68s%4x)o>5I_-w z5YEtBzabEqMC&r2AEQbNFjy99kK1<%G=LIwfDM4@cnad693taUk$auCY2adcIRMA! z_%&x3wtr|vxnxjVX-5tM%zzPc08<456k1l&(Tbc4Ggk2t0t|aNWihoRUgl(4=K0%PC$WkOxAW5r&Pyc|y2}*&N`B(=BAf*=Z9Jp+;Dd8uIBc;&H z+$J)=^!c0Uy@G(6A&5q>OQ?d!FXqSKU#56kWgC+UV&JOyo}$nN5SZ9B+9%)-8%8f| zIe+9pQPuwj5uQ|7??8rA%eR6}O!co*dZsxIqw(c%6(wj@5U`x8s}mrwB%hyi7~gJv z!w9!uHk$_oThcp-cO_5)LUr7VF|=TRUADgEc;4aQnEv*pPcg=v2cba)0eV*zl|p3D zbZ%>tV`L7O!=dLP#B==7G0^kZ4;)P`;(uA4Xd1;T#^jvFQIsr~L;N}{fikqBC`vUw ze~oIeo?5%QTCf;c1wE${7|1nb--jXoH6f0j-w;KWJJo9jdqH(_7DKNbFEI#02o!6} z0d8l_Wfz_UO(Sk9Iq*r#Iux7|;2kW>@~n%j6BYJbt9kRa;Y`n>F&vuGC5_YVFMqEz z!YbLq!^_riq_gWPlYn-rh*w2PMGK1C?$dO(nO%TUK!9*c)Ai=KzxZC5!cC_&CWLO9 zM!xAe+v|C~I&U`X{VyEnI_!?e?6}z+S0}^qQzg*5HHaUEm>8DhUstouaSe#ewY1^v zt{eVvzuKCn6raC7gev00loG=<_kYIuS|7{wt+pb!ExrsLg;KtwW%qwXC< zKZ@eg2D4IXi2y{PiTj9Ga1ljC8}M_$74Qu_>H{(zZX%8&@lCkHcz@}OqKHudVw#>b zD;1kwP6(qo>UVp9s8_T30>@~WT!&<~UavRsGx7@$ej>h!AC2Ft+3O?2VGt{XhGP)` z=nDz`Zc})Hi~bD+d{_)%8HR`%R(os9u|IK=FMvAieb-v~XM3UKiAB hzE&JOB$)mS^bbQ$WD3;-g6RMN002ovPDHLkV1jD{IL!b6 diff --git a/TMessagesProj/src/main/assets/emoji/0_512.png b/TMessagesProj/src/main/assets/emoji/0_512.png index 24fe71075ee25190f315e3be4c6ecc566a673821..71361fc4a250f8ae66427090f522fce2451ece3e 100644 GIT binary patch delta 1828 zcmV+<2iy3n53>%CB!AUVOjJcja7@j#oxgrmyn0Z&xwpT5Rm6;C#GHb?dQi)qd&sn* z#KgnDepKSVn8ATp;=h@_d{V%_zTv)?$c9hLLw-#WG0%)4}+yDRo7IachQvg-X==@td5&b81z_j9v zk(`&l-`dUO*ME%C000H|Nkl%69V1BP+)1;O}0Cz$amqe^{%dpb^UC=0)mEUWopEq<8((f0|1@;3|qm zKl;@ViusetaC9V=0xP=xF#p*&Ck)Gz z4p$7*M}KK6nHiv%3}y3RKD&I&_-8nqYlMk{>p)~k`2sFw$HX62;iNpf{4ZHk?RE%iKb+!6#404U+lv(txbW7&y!-|cEL=daxR)YA9f@Lehzs~$dx%1e*};Ni&a_2W^coP1WS5f>0@NmNVak(O43V2=a)=By2wtf^o^>^{%rNI0{GW zrN`u}9h_fDo1GAaJR;BtCS>yPeCUrCU4LQvIoW))eeU<4H$#^*K)8SibBMx^pxq+` z2f`tl_51xrB69>&bf4GJy5ApnlbEN7PBU9Gd8iR?l8g_-30!*UPI-pl-FbhVJOko2 z8cK!ewO6v5BJTO3M+mWuz`?i=`+gJo=E;N~_0;+OQxbJJAO?sKmDEO2Ataa6Xn)fu zjh{M^!BPYpMO)w!q8k}PAwuC*Q^b|f2$4kH@fZ90aON5ZF)9Wq7 zeIrG*WZdiRJSliLiq_-(c>MC~HHx}YPz5MzeM}JY`b1o4PyH{CTc<$qx5H>Tqi4n(}BVC+;Dw@zTZQ;6H-(kQ76a*07Ah(3KP6!k=FoXq;(mNnBFx_APcYlqzuVsh| zAb^T4Xibt*az>*eDvMBz&I%wfM9}rO`Du0!2nX{C;wZ|B$&Mp<(6SgqE6M>=*(3y{ zBGc6g!EAj$1QWJx!L#4g;GCjiC`tun6A;u`nT=xUlnkbX-d$RGOjmM6Ac{^!sYE6+ z)oMjTWCUAsUUyt6+=LbFvWoU4m- zRUsM51~OKg*^o3#kDH~50G$e_@(uzc(Kc+eJUdr;w#nkCzx%*;>!dc8^AEHEha62% z9OtT*AfXa#9|U3WzBZ`|isM{Y7>VGl)7A=cqhqQErjl8zy^pA3Ykwf3*XymZAYaO-%Bp+ik;W)+GM~Fs=Y;f1Lu^D}LyWJlS`|Z}H z2TnZynF&&bLJ^+FsRhiV$>W&A0sGD7o=XJh_Tm$@u&~negqjQ>TfHMvK+Qi5gH*e6 zz=!8an`wv;2q2>LTz?k`XS3tHN1?O>PoQ%>HT5*-fJOrL<=2eCfR+xEhuNkd6K)f6S2wV}0-~HQNDLQJ(Q7iWvoYtCjHZd@upq|o|ZrPo7Dkmqv!osz-w%(|OD<~_U zpPzhPOVZBMIWjV|w6y!-!l|mN$H&LJySwnmq|wpQ^UbUI-haQLqN4iRx#qKu!otD~ z3kaK=_> zQ!fh2nrevHUe zf^c_rQ7C@^IQv8Is;G_Ybt?>p!(kx!mi+DO(cyc6V_j#y70Ys3AB4VTS-$UEb#`2Q z4{`*+l`WaE82yKqT$ecjlezkF;h%uRuS!=@B{pm>;8A-T{ELzK=g*(2D{C z1T9zHy^g{+-^cnHAAvgP_cwhWAk+z83C@NoXMekhq95YWvKatm$q*1&2)dv)j(4(T;&L?nW?I*>e%J| zCJV3Mv|WZC`Jxoe;-itPUytOg6~>HNDt~s_e!W#sRDR!8@ounTU>klpm>&e;uU(Xn zLqU#xhG+eHE7D(It)h_Kznx5aD$EK3zxXThEeI_kR$K+wLdQa%p6->^sxfV8TC1_r z)5`%Oy`vz6Aj}bWfiKYA($T2ie|qe$8jYz@v+Y`~W&r5|-EaYf9}II{99)Hgz<-#F zRiK5gzpO5s(pZvA8wfHTJqSwrbxIDs-I*%ZG=D?HB^Z1S2K*GK_Km z@mO(gVGzW*3x0uJ)Lm84*>>AVq;aP+reur+(3q}VoCb^OsS4i;zY>RcmZdU9^`oiT zK~RD}ggYRhHm9quf(sffhr1s8m46?{sU%j)e0N4O&Cpi!an(b_=h@`7 zjbxH|{9|L@o*LRrtb9Mn=hS(r^fY5VUynQybNqan_s#4y=4O?DOy(0q(`KXA=`Lb0 z7__veG?`DU&(A;q`l~ZvOMhIDI`esyetenCJ58q#d`CX+9JTE+fJYHx;Z6Jgq!V48d9;Q29%h-fxzoEV#$W{x|OVQ?~=qZN&Q z9PG}CH*#o_*HO$K+Um8Oo|y@B9=+DcyWK~KVx^U~VVek;rc*&2!+hHWh{zL9_7I;% zZ}!>-6cjb72g80FgMXS>>?O(|suicFr5m+j(DwLhGJ%K}yx7mXiNi1ATN?;(CADxO z0JzY4@P1FA4KjGBZw*xjIP}AX2!i;fyvO(x$YMaF7)?ymSd5T|5i&Dse+z?=Cw}>S z0%CVgPHw9aH%N&dM2{jarEPWdT~-Jog@*v@ z;RE?}T_FT%A&vu}a$Wd{K*QV+lBH6)DU}aCn#0odMyTLhaC8@@~L!sdVN|d i70|)|9u)r@@)aN4?Btky6_Stu0000oMl!dGYQ4R?idsaFUPp>qL#K0DvwdEyby}x!SC(T-uz6gg zY*WFKY`KSIwSZu^gJPX$P`ip|y^U#?mzRZCLZhRivW#&2`+xYPfoqV9iR$Fj%%+FX zu94Wkr^Ca-j$KEtt*z9zoqSL{KqMB&pn)R^1JTjXY-?(9Ni=3!RDpnis+Wqxn00|| zW8l%ek#t;VGy#TG2d8ua&!PdOf-$*_3VrYxQ(p zaD%{?r_tus?0*N|CjbBj9!W$&RCr#U)`w!+N)QE55JiA(T;gP_dZqW?+>-zQq&GW~ zK#4K7-v!GFtd3?!E6IgR(e+}nSSc2Dz3_jcS1Qf>dfij0-#42T{k!|$*S+1W+w1kl z5ct(K>i3|012A^o-ngI7xHmKE&EnUDX5BdLpGU^sU4Om#g-VL|-VCbmkI$vIGwPMk zgo-MmH^x_*F22*u46pf#;6f9-J$PlA;r8^unPD_9*RY!%qsE`f?xInIGnoX(&UWW> zVJ`YF(=$BJz+vzY*K^^m;z10<*cljDYsK@x?Y*$v$cXHXASLpPNc~V)5{IBNl^N=qmzaC$$^7 zAOiprY!i+Ki$U>S5pAjnVx`ANBaeXMno1yaAAgRZjN5!Cu!s#K1WPzJFolqUZE6rA z_P#13-;FEPOn=Xkd0-n7#D$mQP;?T5aDCRkpY~Gr~?j^!;{( z1b<)pquM`&zvqf*ZG0ebu(8Vs*DzX0_&|Um1eKFbSi8y*x3#dncW6Su93a&QtH^rc zM#-n`4G>TT8!r9YLm^N2?Ena9MPx$o$STQMPze0Ov?41dHer5UR7U;=35ZPzoDl+h zA%KQLTw2U6yF^;ZwCG)mc--dgE8}gx_8w zVKa8vuBP*8^&l)W7ee}hHlJ(#0izkw&JmSg?UbOc&UV^4%;)p%f#n379oGAJKc7zz zot8+6O{;mjXOhhZ2_ie4>2wjo(C5yWoCw+<&0C!{5IkN`g2ZyuVwH?|6#FF-tbZE! z=MY77W6wSo;XwtM=a)`grGh#q0)xcFVT6t2aZ0?*;@+_vq!+If;suDYAk+zfpuC(B zKWIWwdWc~nIP|q2_fJGWt|s#9?>IgP%8+1>`jLzes|)yOVYc(ExK{sU%kA({n>$F5FwFp zejJH1cLHq%1gx4}zcY@^UZ*qmq-7_BX-T)=>CB?&(CN=CVhP44TEO|;k}Hzs&p^{A*iSUzNVuEj&c=tHXJIWCR-hsnhw%ZlB9|XI!a6<>Ez8*T#$AI5 zAhJN6KumyudE`=V+$8-(B7cjJwg)#*8~bt;u$w^Kl>Ys5yMfI>0ujQ5&@|2%*EA{s zLBP&haZ@h5%N@=nd!AX$5z(%?-#9ES9<71xFLDW7J7&m(wdstg9nwziE- zK#ub$ogr{0X&D|o?cQg!1tL48<-(aWTJY+PEm-eCPmNXee7Rm+SRfo93eJ*N|l^y~LoI7s?QX@S$Yz(&oo# zk}@U($4+h)4gDjce50x5B^(DAlFPLz08j#V)tVrVBzTcR5g(?6Q=yy-T*{_rF-J1X zGjX*6EpQswg$ub;27lw6s-xmHYZ2Tkk#dL1OVhyU*I+mfmjqW4Ae1TquN=l5CE(R@ z$!LJVhYnSMeF_l5fiEU_fqrfT!BC2Xz}p@ggbjmWvdVylphX7tisW0j_HS4x}kZKYf;LCWQe$Nvvkq?75ok8bS%0000t%E`!whljM3d%Ac{#-@Cdm z!kpi@lB=t$-L#G3zL(C<&ey4e+pmbp$;q{~wYs~y#l*#-p?{&Vu&<`3roX?xnwpx$ zhFr~?amkEhlai3Xe^cYlsJ51J{{8!Xe0|iTeBa;Sx&QzG9CT7nQvgWdb^SH{4IO=6!TxGti1)I{q?6W|)wSE7 z{Is?~>Hq)+Nl8RORCr$1m)COJSQ>;y5=@&F zYcIBWK@o-jV|U~HtkTi{R`o`yQmNdWL8qssYU8)(OMhQ4CDm|rjpupW4H@Q-i_>cT z5cp=+9^>jI)(-!wiF;Zl+e z9=BUI{D&q%xMT0|=qp?SAVL?IC&|M^h_>G2Dh~hz%gfqqQxgpwTL}z;^b8eE#9v0fQ$?$CzIa5vSM$-7(a+A_4eGltBrw=1$DeU7K?1ZRVt{$(rFXq5WHDsEX^Th0q-v!8KPTn!bo;;fUr$l({)}SLAS5YU*|`L##_39su9%DY?sM?T>O3IZ_E%2V(JoZ z>%J)O;#ShJc%)&l^21@dNb`3W_3Mz~ZGYF23>880DD>N{MH1?_`zHeiDm9tRtsLxF z7Q%<&7$cgb`|xn9T8l-}k!3$wNOb-oKVKt?2rCCCD{~pw(Lq2G?3Zd`ToE`T1rXzw z#GnL8)!YLY&;=frhRBkN)RMiun+q%}LL8O<{2Z!uTS0KFLd02^VbfJqG19~Be1ASq zdOenkU_=>LRy>vv`|jv`m}UPe9c&r8;0>HkeYHviwl|sdpf?QL>xqiLFeFE#8!Sl*xVEj^aM0@svMh)M@&>}Vh^q=G zFDz9j=bNt_B2LZFWL6!KRT6(Z-+%Z5I{|`lD2VH9=3_tU3rT3(DD%2{h-fg(b}XZ~ zBwlTw22TkGBRK*LPML4lgS&X)bICSiOufKF{nKi@>C2pwJS6LBG8jC?Z0`-hE${B8 z&x66;bkXPhRpuI31&FdYi~6$Qcc)K-yY*nOP9DWq1iRd=*W}{;B<(25aDNk8t@qQz^E_Wx;%O?}-`{`#^Uufhk?m2j%QRiB$;Eb>E)}^Sd4-7MC;&nb zz>vS==3V+2!$DrhE}bUi;(s(<3P5;4a9n_>MxHn9D4Zbfrn@+vPM0hTM9yI2$LVge zoIdshApBtHRSOV}vgZZ)db9CzIblT#h~tK^VxfdFX!X&n+;GfBy{{?U*T9P8UrTA^VwA~q5h>k8%Jn^ zG9Z#&fbv+h2tkI4&41=SMB{UNHmiAlhaz$YL__uR6vRX@-i+H{-b0+X+p{R3HmESs zk(CZPZ&3bu7;VP0^Uw8n7^TnW=MjyfD1yQzcTcZ+R&oMjj6t}%0-{j$larJ4$O8iq zX!SIpT0bvH2to*=cIzB5ex;LU8H|pcJ4sgC?RF*ONdQ0y<$tS_dg&kksX4CY44F1T zXJrb&Zj`G>A5ydC1wMsf%=i61{fiJHY}ZE_COh6VaZ7{_51JI`$ zV!_KGd|cI54Uk|s9Qt^Xc`s_Ahu=}XS*}Hq=YfN9FN(^|`qA&Iaoj3nO^IsdRtBIbSv)VK*UoNGokXC1N)rhht82MkTL*g-|eeMk;?xEsW(9f)K~KO+{Ces7A1hy48d>*dzRuz!<)e}1E)p_P@EBMAd# zS59wgXQy~pp>IpW!^5qtthl$g)zi+be_hnav9gG0w~=zan|+H}2B~=oshEe)q5-;% z3e;PEPXGV_6?9TgQvl`Xu}xyp6fORbiA;Xc=E=Uboz-C}H-7*C1>{LYK~#8NotKAN z<2n$9Nh5J63xB(->e@?s4|U)FvF?nhwN5KyIq@OdRk!8+4({MO48V=9?kB0rh z#cii!gM!ZO#YKPk)A_d@d$ru}kH#C@5!GA@o-%=sDjwrp zl#}gx_vck2egR@a2$Xhc6_8M02t)SNVgfdPUA{FjNd*T4XXLpC1kgxCVd!Fxh}~5? z6KG5it+-l!4lX8<|ck(nt`(Pl3@!`~gHM6}pJZbZV3~g^h@) z?oA?tkn^{Q?FLNXg3wSx*sGwi5h2tt(g+dChtg=L^J+Uu=Sm31tTY9?fg4$t4JMlH z<$qdM3rNv=xW!7vK z?{bS*h}61xd1msmGzc#8JdSr07#ikoDgNC`VB%X2%(Y;9n26> zWPz>;+RYc#A3o$+BDj#=e6bK}P}{f`@VhS+S4CD-h==>^j@1Zu%;to607SuSgnw*K z$DSgD5Ql6R$7bl`AuC=G_gO;Z$HzQ7Frf%>-W&#FB`ZXcWmfFP@#FI<%U+Vfi!6`B zFbaRWpGeHHuMX`JpGh*3mjP z2rN$$7Zm{^G!c6QM`84SQMluF4k6apY9gitoSCth?0zDJP|L`WVi zlf@#6qD7KeObT)a5}3{2segAhOh&V;Q8HPtccA*ZNi4UH18b8~`96}G5j}0!Ep6$# zNh$A zQ@lbr^ys7K3}o_a0&vCR6NAoFLU8dt0x=+`wBue7)nbNl0)9{Z^NPW=QMI*vfBgM_ zxkq5c1Bl{A!lWVWQ4rsT^tuR>0ByT-=GtE;NJi)F=>YtPTmtanJbkKcTG6Smu%d| ztL@*)+^vJInSsfsf|hzyXjnqlp>uC*XyD-B%$aXBC?DI~+nk1Tk5&xj<>kMC68?3N zzW@LL9duGoQ-1(WfFf%o`~Ch6>SRTReb%YS-Nndb!H%7wsIRZsh|Dek00t#VL_t(| zUe%OWf7)0O#ci4dt|fMCCs(!iUg#ayrHT&ODN65Hl^%TGF;&i(aQD1Y6fi@r*1-r{*aOwx3drX4@z z?YpD)=K+!(h5)bY55v&+0is_vJ_9+rkR+FfpW6Un6LexB0FkyUT^#=#pnb=w z9N}$3tRw-Bu0tMlM1>Hp(fyEceBrvBZtH~ieV(|ak`BVgBF%Pxe#AI(b>hO$F^9{! z9H&Yu9)Aq7D8xbr*Z6=ycpZOg*@S~~RqBHzO5t2&&?rRh@9jrJ_j&Y70krik!3Vi$@9Bf?Tlk==%8&fC?dfuz~%Afe$Zhhtj=Dd_r8>N)!dWS80PQ z+W|)GT9S6i+K51cB!LBBP|N^cNT_VkBpujat5HLA5?!YVl>ASR-9d;+;B(ZR_IGtcK|0WCuzrcWPRZEXX(yJN*zSarh z3ACa*4YX3tMW54Qb6jYYByo_%@1&a=;?7E7#X zrk6>F=Y3n{fI#(t?jijA<%PV_1|@^jLw`2)8#P3lgdK}>xjqU34;+-svZl%MTml>w z4o9CNk{aSF^;w)PoC=&Pm4|Xe5KMR(jy&fc2GxY33%}+9bf2)SZo87I!c<7%=7~{6 zkO>mt?Rcw1#krRx>;)o@>W7;0ysmN(gs>~d^Ww+xcq~>JQS&@+!*d+&J0W}m(|=hT z@M|^+d6#gK{t`rn__ziFLf$x!W6^*(l1n#)O*{29YhGEQu5)gZIp*V52&qUw6cvM) zRNGI|O&b0@sOjFfEMhGqWjt04LolJTgy07*qF}&nipFxj zj03?GAK$w%g&>A69L0IDENCX?sDCA4*;T9wqPCnYm)_8uFU1lWOO>17x{cR^d^h(7GX|St2`bKNBLYfi7@frkkBA@_!>r{S(&w9GG-(jhMrH0A%C6$+|*=-i6BT#r*RNCnz9(=v!Wt&VPt$9qdDRn51GL z0!~ksolK@cKvX%rVjtqWSHxfgqf|bGXavfXtqXdjapCPloHGTJRW>MOYzlG|$x7u3 z321^TylTAbi{^RW)&>aE3)@%~0ZkO%`5wfX=M@Yca>3j>F}D_wplHyE{fOon12#sP ztbq@d0VF4sjDW!GJJjZ3k71ZNLI%jpp0;8TN@E0G;q}hH17f#YEud@} zO7=9QdSYY*AR%Lz8wO+SSGRTA3y@&|MNpg|9<4GB#sL8^B4@XU-NV{+*R1r=2SNH&6fxm=8PEuB?vP3#PR6tw0rPXHCs15prDxE&1v(? rfNES%Z-4x_J#95>4!$I){vYTcK$X#&6e6X|00000NkvXXu0mjfBC?R* diff --git a/TMessagesProj/src/main/assets/emoji/0_515.png b/TMessagesProj/src/main/assets/emoji/0_515.png index 47e4ad93e7c7f17eae85bb8bd6c5bb26f424f9a6..762b64cb4db33fdac563f364e06f851b3b2a0dec 100644 GIT binary patch delta 1733 zcmV;$20HnH4%H2iB!8<=OjJcja7;QXB04G|Hz*%DD_gKyV_#xxX}oIR1n&oF&i$M1O<~6(9e4#mUuJ!l_s#$tsBn zgIDm?Dn8Tf%H-aAl4%fP=xj$?-pYJO-b(zr4?nPQ>*tI!CP=`+kw^PPK`tHyFV?re zFA%rEI!`1p7y^tmjWN*xf*`+>%5YjGoew~ku1?QomU2e1n$*-dHYWu z%D}GyL4O1xtd%|)iM6Eh2nY#?pu9UzL>a8>e1(DF__I_VGup=?i+b&s!S6E@5Jx>{ zh~Nz3?*SS9(aB;c4w=^f+PI@Q3dJ#3Ty=a z3E~bAb497Byt$EQ-CKlh_KFG-GOF^m@BcbOkO@u%i-6)J0x=SV8c2c&70qk^G@bWB zJ(rOr6P{P3Fc$ycCjr7pp!kynV)Wh-Meg67BK&+F5ke%1tqV&)gh?n>jaVfn8KY`m zpMN5LuK}S5A%x^&r5Pd2a3JE5VTp3A9gE2CPZ4?USr=TTi#Y94t`j?Yg-Qg6$QE5n zvt|*ewK~l6!XQ)o2S7YFS#LwcZD-nFp4+CA7Qs|+V=Suz5Q?i^<1b0u=f`Hw`b>1~!n8j> zwatzhL?OuqX`(bCB=?(kyG6v)Qvh9i#J<@tw@7{iL?EOhgc|pofvcoJ$X(MMwtvst z?bGX_Y1Tc0?*aYtvVD1ddTbh>s|XQQH16xni6Tvb@Oa%ehv%oa*F)R19k@)Q~t(rygJ}4g#k3qTX1ZP}f_b76E zL2(?1_BqG%_bTRj)*ZJfFU{UV^~cPt}$V4 zNc1Q)ZV|MysQ>6>Yjxid41YvGAIuDttla^LL3PMMfH3`U!Xv^tLEzm$D#ZnjPO>y6 zl;F^)BzEZ$?rE9bAcDLC1I36Sl5Ei}5+TqE!)CI{6(L4vj~Np{Y``gY5q}g6hQL@1 zh&1M$!Vy~7&CDPuj$XqtVinmGB<#b~VQFE72qN_J(a(xahLvWDb99FDC#B*R z!I((}%*KTrvob)`Q${RX6ls;{3Km4hlr(g(DG@RG=xGm=fi@@~ak2ADQb0$)_R@q| z6KIT5c_k8LRC^d7fZ$N#fqyRRPOz(SkX%3*8(F^oNdDSmluR4PrG_K40SrCQuPHSq zY#f)GSR2*+syu4~mc&&Xh+tJwRGO&>3U~xm@ zN5q9$+~X@IuvBPLcocD5j9QL}0^abO;F0`A^AJQ5&#W5;P*7R0SGcE76K?D zxZi)}9^&MJ5ul)?Nj}4bg7`jUazn+TB3mjq6MF0a8N_k%o=h6M=7s;~3Wvji;|vDF bPgC$8^#VlE(@sWM00000NkvXXu0mjfmdXya delta 1777 zcmVdIY%2PNjPB0|S&(EHpoS~ti#>L0AwYHOth`zqQj8-#}TsEYmqnKbhs;a7+ zWITRKEQL@n#>U3Cx3_XaDACc-)z#Iou&`!2BAlF@EE^PBG=CpZEf|xMl74)95)KKi zie>)(`pe79@9pW`+SZkt9aKXvyN>sBW){F8}}q*GWV{ zRCr$1mFIHfIDZg?SCNzzoDrCF4$8@4_x+#hW&ly^TTwo{uI|URs>o8n$DYOv^y9zP zXgC>_|C6Mprd$}=WltgL|lKG zj)z|ccwP`i9M>zbI*T}uKs<0Br^Bz5005##x)T6E$$tQ(BS0Vn;@wUDi7=enwe7%f z9iCBa!?p7(gHI5j4*z5!~&h`4zWQs z%C;p%?hX&^@h1cVE75vD#B$H`eb4(%k)=4bKe&x1i%x37kHf^eggrD(;ml7lD*a>G3C|C~qlc9^Di&~oFJ_CCa z;rsCO27m;4SuebroSHR?S~le&iyVRQFgYNco`3%;b+RG)Bf#koCM{6}jwE=sw|J3y zJp*JdzN|!n`Q_8gC^83K)KIS{V?@AQB9J9Zff3B|H&A|a(N_u&0wC0ccydEO7-%5A zt!H=uD6NQ_jEly0h-k|b;6p8Ij|4dMC=N#QhYJLcI8>q&Ph@#gL-O$mab!?3jr{Eb zF@NP5o>LCYlO)Jm=5u^J_^W-H#~L6cz-pfVAdH?eMc1PMrrL+yTVN@;obYm&J58|2 zz@2r#MRap9V|f;3+$Of@iUoFst(QAWEz4qiZ{85r4I;aU^C6Fvj5xNB6S97NsrNfZ zDPx+ZF>0}rtmm(?HN0zxXDH7J2t)yU>VNS!HD!jeGz>#SF;o4S)uKN=%mND;Uv6p+ zla5jNMER-4ak5#W43xH{YOEf)ZR3$au)A`7axrE2j{#A5PJT40vD_e`k%8|G%J#N* znvh(1x)`(31Bbq_NoH9ZF5dtIwEQT8?e<L(nGaS3skzQ zN&}Nb%zRs*;t;;3mZ`?>;K!u~VUm~@^{Tlm2=9k#t4V~mKXJqNZ8cw-W~#c~7DP7* zL)W6^ygI09`u^+J91u$(KvZRnAC^^h02fK(_FE8rfnc;;REKvUEUN9Q*?-Z^VP2K+ z;bA`CGeCrHc-w-wO%imWvCUzz-EJ3NX&C3O&{o?Q{BXNs8ns+N%vun$4lqoLO=zr2 z=qyb%=4!PC^gOm zQAetRiFQOBo^0s}S$7)(4KS6G&L^2G$fP4Pk3Hg$H}Q9CM@LWO@9kt$pOj7&iYfzTOr z0nx60x8F$x1I3V0AR)2N1Xb;+O&M1y9b`y|7>CeBQh@>g;9m$<{}1#R?dofO Tj+lD*00000NkvXXu0mjfRdq*~ diff --git a/TMessagesProj/src/main/assets/emoji/0_516.png b/TMessagesProj/src/main/assets/emoji/0_516.png index 729624c8e0ac4f14694cd44171c548391ab75c1a..9526f7e84433caa393419a1af7f4d5bf9267c8ce 100644 GIT binary patch delta 1915 zcmV->2ZZ>X4v7ztBYy#6P)t-sM{rE-vKP2}G2NR2xNth8Nix`+5WIyTH!kC!0L_X3 zku@cWkzVMe0n3O0x_JPNDHg6{AC#$ii?Mhm7Z)ZM7rc7_9)A`Y|H2IZz6Srr5&OCY z=Ar@fumbqC1MR5+;G6(lAsDf60l0SozqBLn8;1R{;LkRDY#vUp5Zrs15(; zi=fMh_}Oo*e19x{LICE$Vth{_gG>XGVjKU>F8|Ca84L%5B^6g25shXy)Ic7SHYdL} z8I`_%+odSF=AnCIK&{!8NEQ!`c~8igO60OW{qn=Ak5IcsBdu03@54my+^J-JO?8@L zzP)}~bVO;3SH|p{7ZiG-bLwF|(PO zA#-*OgM?>(T3DP9{-hAx>CO7XKL`Z; zA3v?GPJcmGS64rM3Wp2B6m;f{#$b&*mfhHwVp=lOrc5C(VO{tH}Jb zagiVZ`}^ldM}Pg3qoZc?CK4HQZl58ryZbxzgX=r7OSy{Va*@UG7{dO3WPcZkqmyRS zo(FgxG+|WD>)cpI@H!H4h$c*8wOaj(saBD>$$uphx!mFdLSR0Em)hOEKA5t*|LFvj zse>yZ00}-Y3~ZHy$+(`XV*f9HK)!sjmFih8v9*;*yc#)_@H`4YL~g3D&(6+{cOb_Q zP`-YB4MY}@k!1wmCu}3P=j7)6;^MHqx3`teKIt7FCx8Is)yQ!q63{#^iupXW&9-mX zV}FoyIFn3ni`yccg}fiNdl&bzV)FDfnG})e-Nx*!w?!njx8b8xV78u)7{`!Zx4S3g($6=tcjYRt!AwqFO z0_*T9>&*u^YAb#D%g(3yf{hQT)k$uXv0 z?$k=@(--#>zoc;pvMg|Lc`EaL(4cumDi@)U`-z!f(tVggN#$u9uMk<&>gLPIzV#2$iJ? zn!rg|Uxz=;hJ9>V6nw&~x-3k46VptpYyv^iK2@pvEJr{p=2O+Wk05B))PJQV{|JJ2 z2;W6}r%*hPSwkWQCrZ5w9}Bl6B`t+Kg^&*jgCqIY)$wI*v(}Bdgmt@fc2|n_S{E!< zVJvx0=Oo8VKyZhRUb+^I7S3C48L?KO1Sg8!7Q?D~%H%_y1kcO5!LhfE9`4uvdBbw2 z;;w+ZOYb&(yrQQJ#+wirAb(h{(zt>zin4ll=?(ata8NTCa4wtyaY?0+vOk)$LX)8Q7}| ztc$gP7ZF|)6v^ai+@}_9E~h^lu+%KrW=Nz|W+gmgfg`~=1P14!0)GMq37UfzD)VO4 z>Qte@zX%JarBSgt%O+Ssk&RIcJg{aUL4PwS8mtVNK_inPNShGWM*T(!tt_ho`;D+j zO=B2MAS}BGAb3rAw-TBdnK@PCIoN1mKtIArK@7qI0SS&bd)#+3XI5#eRi9e)WL8G_>(mdrRs;8ds|9)2#EQ|ys|0ikG)WjT(3LuVYCGREUc z;GMzPWl)q^gmmyANsK*KErBv&wC zRgG^9e;yDR1UL{T0T|zau`oP`l|X0!cxDMk@u-AeYJkAHg0KK+EB?nn>|1~X+1ug&p002ovPDHLkV1l#& Bc-#O0 delta 1806 zcmV+p2l4oc51bB=BYyzHP)t-sM{rDkfqu-+$-=U3W%gfNt&%M6Bp`oCjpPr(l zqR-FH$;rvZ#l^wF!MM1$udlDFs;Q%+qLY%5iiwDVe}28ay>)bRw6wF;)zq7tn!v!p z+uPgW;o#-vnaR{Z>mp1Q2}F_^jG%3#VbL+)BB_s{b&Z^Kc8!{>{=}T{6@>wdb8PXhX>Vex8JW< zKjSP`o2~O90wNNpJdR^dyS-Ar4{)v^Gn3Yj(=;hSKYyTX*2`}Z6fj4wtPNCMKUXH^ zYGNtd^*1uuc;|shfNDyW5IewHLV@5mUp2BGf)7Gau%?OtAfgaL6R9u4_(da!QeqSY zR3i|helnHv$g=OZtItdnDMdh-C58~ZcPbx3qlg%S8N>ENFN+PZtwsb^@7&zvIwt~% zxj~7?&41z}0#>wc8^G$1U7ZtRX%Mc7;qXBYm`IQ$`e%TX-b~8y2Ei6Cgm>duQDUUW z7OdQ4kW=r)2TQ~@nc}-v4k;-=8lVv#>zj;WUIbZ1@?IOuhs^wvV2`t@GiI~WyQuG` zu^MZo81Dp=)i*#xbVw*dHRYVs@OESOsd7<*A%Bi`Q@{&#L<_?vOx`$I>{2a?2yGhN z3&5qD>50Yytq(rD6NNxAA8PqdI9d7SnVa55JHJ!fyon+wkrLHL2(#tb0FU)e%5V|w z3Ua+(r~R7~ni-{N6eYIpc%6jdjt*EYq?E?%b=)mpr&*a45hdDOJ`zrMH`)AX=>jiAZ^KuT~8aWb{lb$Jg+5H;vF9F|6Yi`cLo5H3#hd>pGwTVCrW%%`4A z+gZ>+(`zHkA!XtOKKT3jwB=6@^X;D->084!XAQxMc)h8MVN5ksD1PovF6UX&?ce|Y zSN(UBlL1tHINnF>#+qw^zigFfW3wO-$A6!_vN6sM1Kb@5c14Tb?f3sw50Lsw|A~w7 zW8GMV0OKcpzS(o~ohb+ua<=sAIGNYtg!nnN?{r^m*NbJat5qU&1ICLCMXAOfHf8AV zwch%@sLrN{e7B2RQEqdzjc$!JqddrJ4T%p%F?Q{eG-W?#9M!vewp?sEAQ&m-h<}I* z1ps_gt~T3nr0IS;akHzxjBSc#mJ*VTUB+8P#XEsXSLKEUgm2&)s7v ztm_02TWjsh9OA>X6%xq(a?$tYDkYMi2m^wZW#2D$90627yiW=KNWwIbh>!&5g5cC& z#JeYR&Lsj7{%^hxR2&C^Fn^AlS2_UP5GEN9k zA?m3XMIsQ|+DCiA|Gis(8qr=?ZCj04Y_siC9*J(>9)W=IxC5>Y1li{LB(jXzuvUnN zodheZpyfGGVwRIkhH)0B(B>9!8k~bTt96Bg-~SuKdGB!3-QF_@;eRNo0(H zXxxy=n|Tu;!^+R3W3HpPaN9ZyDMjE;O^q2a1Yroe*2H#}i|R0t<6Z!4AVBOx)R;l6OS!<< zabKkM&Y?$6NYezqXn)$oTB+nag4#>D4*;KPOh+joenvcod?285u^^&&xdf<5ebkXF6BIazP(0PAo%tdL wgP3Y8>YI*|p0!fFV!;I8wjI)@etmxdXyZcu4c-Mq00000Ne4wvM6N<$g3g(B%>V!Z diff --git a/TMessagesProj/src/main/assets/emoji/0_517.png b/TMessagesProj/src/main/assets/emoji/0_517.png index d07d2a12033977e332d24587eb6662ffc6d36ee5..c372355af9605cbdc6020ab7491de272533ee4ce 100644 GIT binary patch delta 1888 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_519.png b/TMessagesProj/src/main/assets/emoji/0_519.png index f1f0729d5bda79d308607c285e21116f912ff2e6..9437062e001c119de1e9b23f1821c9ad24b5a1e7 100644 GIT binary patch delta 1720 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 Xb$bO$;xJzT0000P1#7CIyqv9GVq&COFc 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 delta 1619 zcmV-Z2CVt$4de`vB!8t)OjJcja7-Bz3=#|qXJTIy4hzG?#IUfi6AcT&!NC*{3=Rqi z5)BHzzrV`L%CfSvf`WpQl9H8`mY<)WoSd8~8x>7CFtxO_HYXvNn3$oVpcD@d7Znw} zySqX#DGdn;Tu3~vt*rzD1J>5nr>3UG#l?(^i&Q^0etms(ZGUNNS4fX~YU=9g&d$x= z-rib8InleMZ1Ui&;S4hT1iAfRCr#sm4|ZMNDxFB14zm~*&C5_Vp8<~f7g{)d^})S*Fa@0JKiP6mI&k z_^XAjyH5q44e?f71Q4(jk`hR`tNVn-gPW!T(kj7kE`NR?7s0kHxDngCMf?zW+7);i zE#4augeb-b5b5d;Axy}5(yot5Er%FJB8^wK2`V&p-ERFMJ{(#OSph^VWPBsjMFIj+ zCkM2?6;ZB@JPh`B{sS%OEOda5()vJqhugAJ3e9r?xDcKiz!P18fDf7yoebOfooOAW z9f1H(q<@BmTBsC2lpacB{!=Rux+-Y>?&$-BN-;wVse$2mM9^&xBml0}BHHOtKl+vY zQp#-*p9#Ch3YF5tp8~-0Xl{u(D{+A`cWt$2$80gB?0ict_8=4 z#tAZ=PRqyMTxB{00zN^wijr7V4giVCQqeKgM}MehYl(CqOH)mp3Nur*VF4=3U%kP? z#F#DW#``nja9M8rhk~Y_hQsu={HKS|S%RotWO*L#Cd@;OB_aiulBLcHlwpj*$ zg2FVPX2m|t%3zuh3jnC;N|Ft9WLqeeB?!}arB}uxn+BXT4FRE0n;CWW5aL&%GBaDK z)qfCTQB+u)9|I`oyizF$=iN4pcvM9ukQj70q-x4Ne*7Tr<)vtkur`ZTe=Z7~cP0uL zIC5@Y{{ewNc#x%gIz};{MWGi1)2TxfMObo=lz%_~Afc(C=};N!7}{o9qY$^iV#kjl z-wWvVgkTYgm1%5(D9ho^o+PfyCFcN;B!40B!Pkje9aWmDvMlwgkCEaf%8TY0-L71qcr{&KqXOidn5nt#k&Vc@+`|w#7%3Umb0BaWHk@N_`D`_(? z&o7h!_uv4bf}cyTRO!@Oe?m+ca}Xd9U?g>2GFDc^2#oS7$c`)zOMtm2S)e>NTYr8s z@d0rX-p;kz^NAQlsO#XR@L9d9IS?L;Y{ulchhUK}ks+^NDnFOL{e03K0CI9V+5z*~ zbG)l~-Xdm%=yXAF?!E+QtM5O*$H%seGWLAjVQ;6Gnv)9$h-EJehG$GA?n`akQS|(J zdZHwdWxcDIZ*Ikekb{Wz1;OiG{C^DndEKSK*~RXJJ8ys9U-p$jI1x-+qic;NlXm1# zSL^ij_V)UkWYu{fj-{?~>-`|A98us&CfR26NtOh{Mi{26RasS4!1D_t&npORrk+ap zm1xK(ZKQO3Tf#;+p9Hu-=!X!@x0#&u=i8Ddj0VvvxQKv8R0knoqR#-rk$)119)TDn zsso|Tki-CEY=I6Nor@N8yr`{XHeQZ~HSz7HC*2A_=-*Z}-L`LyZfOm~l?}M|j9Nxc zbvU*^xrtcLe1~kDPYli&llWr0wI;YBMC;K_S+LQS!X>jKa|*&52Y`lx0fEuJsSOZd z7z7+RkZlM?5{Q-%S)knh_*i7?EQAi@Od zxT7&W-O6XMV1$s*cR`3Iqq~|!7l!Qx2owa<5k`zJn1GF0WD^5n(tqomn~nw)4Fy3R zy{k=EirM#OD!93x5#40oFQtJn40C&xmohAr@plIK=!;B%@D;5c@=QTuR|I=9`l7~G z--r#u3`u@jYpXNTqyWGMMSMfcwKeM~z*zu%TjTY_nvtx@W<2_@T9WP-@GpXLS8B|{ RXm|hs002ovPDHLkV1hr>`Ah%+ diff --git a/TMessagesProj/src/main/assets/emoji/0_523.png b/TMessagesProj/src/main/assets/emoji/0_523.png index b0916915159077d3bf4fbec239367a691e6ecead..94b3eb722af31ffd44c9646b8bfe63640123c57f 100644 GIT binary patch delta 1760 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 LNkvXXu0mjf@;XP8 diff --git a/TMessagesProj/src/main/assets/emoji/0_524.png b/TMessagesProj/src/main/assets/emoji/0_524.png index 4a2d24122ac4c18a2bb0e52cc767b977e09f2e97..3a5b8ae88cd7a68ca5e09658b7727391dc905799 100644 GIT binary patch delta 1720 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 delta 1791 zcmVkWu`eQ3Hz;B`Csi{fU9ghOQ#^M>E@wF@XF@Q0 zLoaqaC|D{VQd2vWVoH~VYo$^cRnm~EFe@+I*&*+gWIu+R6Um8xsueLb9+f6jaV|jgMU?{Ydp!3XuF))qK3cZ z!kkz?oRxX9)~JALIThl+n74^&u#?QGdtFI0ZH#0~`T6(n=i5*$A;X<^t(%ajc24Hi zzFs#nc2P@XKVY1IZ$c?Y&cV0Gr{g0VNht^dUPOC}VQAB|@K7^VTSB52RtlW}000+s zQchC<=BB|{ZhzquCFbakJ>$`B{j2EwIJJQcEN%_}00qEFL_t(|Ue%Z9cH&47h1VDi zHpX#gI=6Bn=bUl&y#MoTmBe_?u0itbzrDb*TR!#a)~yzj|N393SS*%`p#NHad3}3z z=Ya06Zm&y!4k(qcOsCm|ccQ!7Z+{BF(_`sRe8s=qU4Q>cKi5}Kg=N2#EN;KvP1%8> zpZ^l_uD-}9mYwD&K-|rj8D%q0;FFSGzCtKiNsI>=sOxOP<%QYASsWtZ@vCBH5T}*{ z0>S}?gFB_1g~)5}m?j_&GVm{Vr7RQ7bogNeWbAOKX_MFm5Vl z#s$`H+KDyYQN^9O5p0rQqy<{mjC0MfdH%lY_@Dqjoz+f2cZguz;VPdt4+RLc?F?6b z5JZasXb}a0zk1gk_Lj*k_~g=}02h|vP5$l&i+^5k)^6K&yFHur22tR@56u|CS;|Z< zsaBk6&Q_g{AM{+e+wH=~b=}#>hfsFI7@^LOhmog3TTBh7ozb8-7_}SSL=Ag1>h%VJ z-`OcZXnL7}psS!~HyRBzv6qYMuHB0|JIk@O$R9^YDlD~%JbMN~bYl~HCvc!@+g>zf zj(;UY;V7aYDP`2JwinycdNi;b-3ACC_5jw~h1U){mcs;1K@dsVdr%$C=kw`wyLF)) zU+!SO-9E49qiX1Lhf$G=km@}M<`2{P^m+X-OH4Fo58KuJ`FZ{jEPT^cG{r@p5Tb{{ zXfl5W`I8450PvoV*LYwt-UdDn1YH!5Ab$)(#4wnRAAm58#uGq*+~xQck#Ia(L7J2v zpU7o}5UK-jIo@{s$R3ZAJl)B7>34!~GO?o#L_z80Q5VHiLZn_-?IrZE9FLbsKuy4q zJDGI7XoFF}?mVg-F^E`)ZM(6YOqS>&QFpn7CGLwCuG0|($dhgsaBk@V zP!)i73Vn^7=NC_c@$fw^&Bm_G0_K0pZilWf|=wl<$#QA0VEmi)* zhFuM-?Jf!kUNods0wUwKnv;g1Uw=IuiR-#;&+`BWf{BJ3AV@)TS@&gN5Nm*po*(!@ z6o7g_Xjfl_l!OXW$b32=(vUAb+#3tu?|}SZ1_W;~lsGS1DPaDxr@oojw_ofDbRe1wa-E*b@kqB%h5a7=|IGRIgwJg@E2GH3-4uq<;eQ$nGRQ z9n~+}DtPb^Ff@MYDJ#s6??32TDE9I?2*bge?yHTbr>9(OBHMF<7z&&!L(6FFTAKQ>{ zKoY?&3MquzIZQdkVa%Ns<2DwP0lob%gbvHqy_Yk&YF+_E?b0tFfh%@C>t zRop}!`KO|IRzn7=e}j*9_}q?Z@FWib(K1*&sKY+K)%zf51y#Gbhkt6M;9LMe75K3@ z5EAaeJg)2YehnCV$YcHHWr#WAgrsI5Y!AQ)J^aY_y$+0i9T*5f)mksO&2Tc12Ov<0 zfs774zZOqgF#;JMl>WUCQVPsdBW7;}Q_dfV;-rO)daGWm)nW)>9{cx0r6tukXMq@o zyB1KYd?1ROR?GlU4R|4mYW4devjnDz<4p(*7pDiJXdwdBYQbP?C`9z<_f&I6(aAmv zrg1u-?JT?FT002ovPDHLkV1lb)OuPU9 diff --git a/TMessagesProj/src/main/assets/emoji/0_526.png b/TMessagesProj/src/main/assets/emoji/0_526.png index 44b0a397858f97c7ecb625fa0240bd5c3e7f8e59..649d2112fcadfd3dedf63c3017863e8d6de1d4a1 100644 GIT binary patch delta 1674 zcmV;526g$n4Vn#*B!9Y4OjJcja7@k2%y2;`bwnv{Lnq3~%D=+EaY84vv$Ld@l5j#N zXgecpKP9B3qtMXLpP!z@#KfGQoW#Y(t*)(&j*W~~GoqrRxVN{QoSUt!t*EG|gMojP zTsDJGFulFK$jHae&dr@>J;TGpWI7>xNh{OT)Qyabmz9$j4u1tqEEfI!{bgHGa&d1m z8xGpq+L>WGrEx~z-{0`>?yQGn<=W2I#;Zy?E{SqmpOmt5!GC zr$zt(02OpnPE!C>wVfz^FaG`!eA!ip$FQho;Mn9L=7}u;00nwUL_t(|UhR}ucjGn? zh2zeSGWEDe=9Q}X>CHT*3LP3%jE-)DdWSv7|aa*V~s8@hQs0Q?d{{^ z<7hPgE?|5yyz@LSbS){R5^4JUeE&H57T_-NT}vq?B}?^eHq)tK%6ho?B4s?h^LmVL8h$0v1pq(~K#p8iJCR>wn+<(a8A0^F6Ml%T<;!X>m&; z0wYN!5%MP^qq{H+x#V05A>B`LZdt%W7?a_{Il}OXyCDYvQ#=HDp6_E}4CTZao*}rB zyWkyi)XNi)UsFQ2W=&kMOhY&!p!cV}u)uM&8N5Z|{C_|A+CHZHD^+_*=lK3GIz=dGUz3Z_t z{*i)1*9-qncrh{%w1H6+$O?OGjI@C8uj|tN)mEu@eu3ndoIo*J?kJI zSbwH0i@DI3P>uFhwA))Qo-nYmuzqM|T4(=6jGwYpDPcihLy#uQ=5^sRebjvYdMd5C z987C5>|Af1iIjyd5KIyX@3G_2aVT}1)Zc6j!Zb_bahB?=2O-kTcHjSMu@uk4q$$FaoUMS_Vsvr&xf)yx08-KMG z6q0O*9Hqxo=n*;WnHMZ&GuX?aPE-_;4GdJv2y7BXgxYbW71Of}b99rWRS{E4i-Q)~ z>_Aq*>Vyd5L#5N%AzC_7r8VQdy$Aw1qH43t$q_2JUDK0`c(Kj5 zPM$}*O%>5NiY9|TO`Hf2Vaan;v?{Yt8#e5YALq`#^dg54=c*TR6-UH5Zpz&p5pO@s z-Kiw&@`#AyZC7q+42a9$BkX-yRz)$VZ~JnyT{b4Rn{r=3sexPWsdFAdmw)^6W%c&< zb6>){K`d7RFUjel|gP0hEZNKj}{(e`MyV}Ic*ucN{yUp(1woQ=!&%pd{;M@@uvv6y!j@eZT`zC0ZlI_;NahCd=2_)A^+E3e85AG Ue!%z#00000NkvXXt^-0~g8f@6?*IS* delta 1707 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 delta 2491 zcmV;s2}Jg=55yCYBYy$@P)t-sM{rEipd%?;k~VIy*q9;QEupv%ib+LaP&XgGCsv1&cc28buG;OXnXPnKJ90o084>V-Giy<~taxreQ z_{KX3Fk~D|g(N^^5;b5)Xow9lVD!K(KU;VPFla1hsO+#DDt|mn5j$i*XOOd#lzfY$ zlYvPZSe_hQq!dDU7E_kjn;0BPffP%J}H0`__zD5n^FrnO+AmZ?h>UCI0rh8*ITS9T7}TOHwZd{`90AgXe>shzt@L z1sFa5%P#!vKJ~vT{ppDD<#;|+Xa3MlkzW(-H9 zKVf$+H#wuELjTS@(4aLZLSTYQ2$_IJz^8HJ(0@dApjUBqeQ7;%hio#W{)v-R&A~3t z$&}~AYVX`MK0rMwhukZQWqy2yem7=VHoUuXH5vpXfZ1Pi zRq)-5pMSTg_2B?lLnia?upMg6?Sa{bS>^0)S;GiznZv$Ip(B zR*w((Fput*RbH)ts-|`x5&C+uud{Rf>$e#N?^w{Plo)RTN~M} zV(t{clZ?WQh}yH0EiKjCR9>%F1qzJRLoU9^jN*Qtz5bkU0VWidx?G`&#>Q8#T7P@a zJM4D*OS^q=a4?w!*PE%K-dah@Es+q*l?dsH8HD+TB zX37|Xu4rLzB!7QU@bfCTwVxa`b$>t|J+0YZm`qT^-$?G4+$hM+A0`(%3Md9m3zN5t zDn|VYlW8TF0t5;F{N$}-ib#apO!anmtbpTx6i{Cx)xt#9iYu5{j5BQZe(LV-08A#+ zpveT+-HFtc!7x=fA1S7|6Y(1vx~{G+Hr3KL)xtB?GS$}75{ns)T$GEgM}MFfg(t!o ziFqa(iOe(W@wmleF<5w<937R9GNVyT9Rm|7NHu3*=11Y(%=}tpKFR_{m3V(j@CwT3 zoPJHG`9feU(#g*B^y%qz-v1_!ybnNvT*YAryB6 zMHDqOr%;QfQZWD-vWnr%ExanH2^zXtY;Qe;N?#uxZtCnOOa=DyQNEFPd)yf-m68M~75rLpy4IQ;| zsZ?(-|C_Q{rD7-}$G$A^{l`0`#@O*oAf|HGTtGYIPA{@7-l z(cpACEylK%Hj6)Ab3H}Pz4*dZ+uvC5$FJ8;LCHP;M33<=3@sa5@%n32Qdv>^pRHE% z++s0Y;+#@8Zht+jsk~x<+N#I@T%MS4c|r!xnS~?vDc8hAbJN|Q%ZnRo?>=+MTpOW~ z9z{P8mnfXe0Z%Bj;ljvgRYfF%hG%nb4~uPtTxeG~u%NhPA8z!a4JAvt=bkkbY-__Z z99Jb=9UH-X{p?}$hDKjTsGSL45nBy3L+vTsr z6iH$>rHs@!H{|a_vrVJ2k(3_Cscr6Cg^+D*ZKBr&rHd%r+GSBHn7aHc;MaA_V&^%AEu&kQaN+@dG~Ne zNeNjc>Khmv?^`_b;Vku!+T4n&0lnFb22cdSaUn?|2r9(1c(@lc|3#Lt5J4yvOQ}dOh<^fsIe2Ux`}2<@AA(@H9|davbznx# zC^F-?Cj5dk+){iqC}mVThkU2XLrKh$%5W zC;j`WMmjNoPz@9OFbhv5$*L_k6EPit_2f*e~uaQP4%E>zER zJ~Z5ESTl}87rSP_{lad4T``002ovPDHLk FV1miNonZg~ diff --git a/TMessagesProj/src/main/assets/emoji/0_53.png b/TMessagesProj/src/main/assets/emoji/0_53.png index c2514cf03153de6485faa8abc5448dc7d34506f3..b4ff0fa3cddc23089336a26d3bd430080d035ff7 100644 GIT binary patch delta 2809 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_530.png b/TMessagesProj/src/main/assets/emoji/0_530.png index cd748147a9a73302aeab3922919f87d047dd120c..3cbb8c179dbe22ece1041c584738eb7c2670e10a 100644 GIT binary patch delta 1962 zcmV;b2UYml6t@qMBYyz=P)t-sM{rEd$GN$7P0Gp0hlhu>lzX~(O~$5>#ki%pculr* zO1ytm!Jkvx$%3e;rl_f>%CTjjpr6pu(6)0*)xdtcyuHK2#M8ca+RB5OnVHVc(5I)T z5b-_+F9sDDM$ zo_727=(LqhkZL};qKxa+xSfJ#o^?EibY1P=#xWre+S=MpIVkAp=~OBM}uSTMvR-bv~WF>u#;3qyMd%txBy{yZ!_^J+0JRzkfYn`F0_xhO28l&pTekFn^q% z)|(#(v`#NZl56pf!}Dg8=RfkC@l4*jK5c!_LG5BRvP_fAGcX-_rfGT}K(wpt)<-N{ zNRq+B?Un=kMb4xiAbvvoxLe zJYIKolz$6vh_YZEpjqy>UomQi=DHdHz=sPkRh1-FRSin9a3NqAwO5W;XG;xFT_a1 z&d+f5@;F*oo(FC<3P8eeID8nQ-XJ=)qp7u08-HHJ;|c(f-UHqs5(WZBaE*(SHClf# zrt_Xa^*}@*=mik?XdTNaNwf|vaNIWnoxgk7WAIoy#{9OAIE5zYE`1U-$A`a)Fc5)G zJo9R=EY0)CqXa;J-UH|=5XaBQVqyEON=X!!PLjYw@VdesiXw;=K!6hl`s>v8zM_~& zgMY(~2igF_@D=b^E0Uo(QT_vzf7*+JF`-;w#C4H?2r~cP&TwRqEF-2A@hNghvosgO z1jL&tY$&<-HAGr(!Xo+k9>OslP1kuHv%GoP{AGS*XuPExl7wY(HOFJ}ALoCs{IwZD zK}=nO+lD_yv$&CTC>|yZEP6OB58V8Hi+|=-#PE)1Nrp=6g#i3?Ymr6z&D)bfhM}2E z?$!1>mPfFM;Tj|2WO#RXqgsnaX3KJrEhI93N6*)YAfnpd$;v&(b9Eq~lZPS9XSO16 zClo0yv>U@;v|Elb@46@)2IGy@xl?m*i*BgLdG3;Ob_H)m1bO$yV3k~kLZM5K*+sf3-h4+anXY~2tu6p$hF94F-zJdh_>(hfvlv{Lb$)b|NiHnkHsT9AYzwAvD)FqZc!{1c@q1j zh~qc}gdhMz{th>9i^mjP(0@3##Wcf<(_$$A!Vkma5=1@r{lr!{LEKKaX*!)QSr!nK z!KRPXZErb!90-62!o;taAX-)54{5#Gbh+%YA_1gnN*H2qxlCD7eH#$)KuXjB#6$*! z2(_ZEpaejWs?q8TvYmwC=c6*U;~4X#3=~3A5E`MPh)ELq5JjmI2!EP75h;P?L`1OM zOXU%PQTX7aR43y`0#4r65M^2HrK}=TB=rGN#N(5rLx^>VPTm+ctOeoOF9-}1e5?;5 zF1zzMvFREjfe1<5XvCrN6T#6X{Q2w<;_KOX{JI8*5K*v$WTJ5F3qrsp#`D=_IidNr zI~&KzgfLL(T>w#AB!37&h9%bPLx|Rw?rhfZ0~-;Pfg+{`)CDdPj@RSv*F%W2Zg&=k zxCRkU*s@~dc>~e^lXyLzoqcH@U{t=GoyEk8q6i9?J>9KNs<6wIPb?D$l-U?Y*!m`?EAohaX*f$?dH+%s&(9{LQPSP wYNy>g`j1pUZXgSj~!j4`{l>` z;lcafz6ma48(NyO#zZO7F#@`{TqRgyY(x zd<;T+4=`6LC4V9cGHNd>DDS_T4NHzAT9*0n}7#KV@=t z{PcohMlQ9SdUT3oL~W0kP%qKLDVTv~LSJ}KJ}-Tmg2$tQl$wl4d8kWscCU$UF{A$O zGD{S*tLoH23;_Py~Li=a%LaWe}8%c+(b_2mKJ3M$SJ!XVE|2>!#l5k zecjQ#y}dpC%)Zyu1XW!x%SjIa198BfUGdvz#Ps$v5m95`15DGU+|-bwveOYr5a!nq zQgZ^a%h-6PHj1PS1$3z_ML7l6ni%cDe1D1Hf%@6s2w=RduUA)@MTDY;(V3j2gfk>* zx04D~Vt!CnrB-h-h|yhOG|xS*XCMNzR7wy8dZr*rC(oiNsz40@074ZUhYVtKw|Voo zdQcqlKwy@DZX^lff`O4lATYznK<2hT8N}x1G^<|ySpb0#TsYcB!3BxLAb|t5DSt>( zp#Ve9#gC(#%`ZFEMx#+6h?@g@p!|X)E?~Y$gpvrS3B<9JBq~tu@3Yj#d=X?Im70MP zm*5{s!Z-3RM@HN` zN)r}WU0vPd$DKwa1QB;pob2K{X@8cyQa-N3uv(LH%k6e=DOq>x;sQ!HBMf^SQzkb7 zfu1zKeBO=0*R?qbCy`K1jRIm2iSmt|488mL7?VU&6`lR5(Ru3`_tLf*Xs?i&Ne|ETRr#gK^7KvE!O=-V3AdvW~=x{$*yIaEPsG-ABDi! zCS`hrrM9k?&Dwf(1OlsNvn|RKX%Js2m9^c0F^h?{;~x2c1Xjn6&0*apWd;aKcTE4Z z_jw>-u~F1)+1NP0zmFGvNXg~;#(&1Aj2ass$;CKd)=!1oF%!g@QYWx6N+#puef_d150_D5 zMwASu_sh5s@vz*)&Pz==bqiYw%kc4mo}QixZj{T_a+U`1OW5G{ z9aM}h1Onrq2EyW%nSZ55+?3I@c*b$i9S8(otgmYs8-Q@MV*xDC6JnkZ4 z;=7Cxg%`yXAmR{8uGecALkSadFp-hI`yml1B%zgwDIPab2A{HCEIO8 zJOqL&3j+9H7=Jkbp;%v8S=lJZc{t-C+xy?I!xTXHG74g0Hozp!NV$~{s3_P)AyS}d ztmAXV*&>QfwY`nBRRf!^#!BleW9+YrvaI7P3%j?vy7H-BuYXioU0oexTdrh>$YWV7 z?ab7KDl6yMmJ`__u2@*Uo~M;xTrDn_&f~G6C@O;c@$*H=g1F&>M;6rP@%#O@!Il;s zDRQ;ErLBuDmyvX>y8M#|pBDFL4I+s%nT>+;K7WY;^-Rvcd9%1YcLgln}xqt zbpo|<(B&U_{p)D+vImt&&m>8-bbc8{5&y`$@$q*feuDrdQFFtpZfUi_j3TI+HglFsJN2W>WvmxCaP2LYH+h)Ao*K^;;hK{y;CYX5z-qoZSb+3)d4&K|u( z{C|61f!MqpXdvh>Xd^%r0@P+if#CIeC+~cGJ-V?y;TH-GM?VVWRZQ48Hjc2NB_W7Y zC=`;Sd<6*zfCPWv=-AlZo$zpkhNGVaN*0y@fp9!SgF0xUZqUmhgi?`Ife0A};y&!S zGd+QLyh4NV%8@N~J8eRbhl4aUGz<;Gi%Jjy0)pm)4Pjg!>Fk8hFC;mL!B~9cW+^b( z5Yi?D1So+(5E3O6Pzi|P*&r5@Zi00000NkvXXu0mjfs8ak} diff --git a/TMessagesProj/src/main/assets/emoji/0_531.png b/TMessagesProj/src/main/assets/emoji/0_531.png index 17c99349aa3dc89bf7a1e5271acfdfdb4733ca59..17bb8db9b7aca3a184c23c5aa8f4f31607e70036 100644 GIT binary patch delta 1908 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 LMFvhpu0mjf<4K`6 diff --git a/TMessagesProj/src/main/assets/emoji/0_533.png b/TMessagesProj/src/main/assets/emoji/0_533.png index b95c70ef63485a25042f4832fe1b090c9f4b847b..729624c8e0ac4f14694cd44171c548391ab75c1a 100644 GIT binary patch delta 1806 zcmV+p2l4p)5}Xc@BYyzHP)t-sM{rDkfqu-+$-=U3W%gfNt&%M6Bp`oCjpPr(l zqR-FH$;rvZ#l^wF!MM1$udlDFs;Q%+qLY%5iiwDVe}28ay>)bRw6wF;)zq7tn!v!p z+uPgW;o#-vnaR{Z>mp1Q2}F_^jG%3#VbL+)BB_s{b&Z^Kc8!{>{=}T{6@>wdb8PXhX>Vex8JW< zKjSP`o2~O90wNNpJdR^dyS-Ar4{)v^Gn3Yj(=;hSKYyTX*2`}Z6fj4wtPNCMKUXH^ zYGNtd^*1uuc;|shfNDyW5IewHLV@5mUp2BGf)7Gau%?OtAfgaL6R9u4_(da!QeqSY zR3i|helnHv$g=OZtItdnDMdh-C58~ZcPbx3qlg%S8N>ENFN+PZtwsb^@7&zvIwt~% zxj~7?&41z}0#>wc8^G$1U7ZtRX%Mc7;qXBYm`IQ$`e%TX-b~8y2Ei6Cgm>duQDUUW z7OdQ4kW=r)2TQ~@nc}-v4k;-=8lVv#>zj;WUIbZ1@?IOuhs^wvV2`t@GiI~WyQuG` zu^MZo81Dp=)i*#xbVw*dHRYVs@OESOsd7<*A%Bi`Q@{&#L<_?vOx`$I>{2a?2yGhN z3&5qD>50Yytq(rD6NNxAA8PqdI9d7SnVa55JHJ!fyon+wkrLHL2(#tb0FU)e%5V|w z3Ua+(r~R7~ni-{N6eYIpc%6jdjt*EYq?E?%b=)mpr&*a45hdDOJ`zrMH`)AX=>jiAZ^KuT~8aWb{lb$Jg+5H;vF9F|6Yi`cLo5H3#hd>pGwTVCrW%%`4A z+gZ>+(`zHkA!XtOKKT3jwB=6@^X;D->084!XAQxMc)h8MVN5ksD1PovF6UX&?ce|Y zSN(UBlL1tHINnF>#+qw^zigFfW3wO-$A6!_vN6sM1Kb@5c14Tb?f3sw50Lsw|A~w7 zW8GMV0OKcpzS(o~ohb+ua<=sAIGNYtg!nnN?{r^m*NbJat5qU&1ICLCMXAOfHf8AV zwch%@sLrN{e7B2RQEqdzjc$!JqddrJ4T%p%F?Q{eG-W?#9M!vewp?sEAQ&m-h<}I* z1ps_gt~T3nr0IS;akHzxjBSc#mJ*VTUB+8P#XEsXSLKEUgm2&)s7v ztm_02TWjsh9OA>X6%xq(a?$tYDkYMi2m^wZW#2D$90627yiW=KNWwIbh>!&5g5cC& z#JeYR&Lsj7{%^hxR2&C^Fn^AlS2_UP5GEN9k zA?m3XMIsQ|+DCiA|Gis(8qr=?ZCj04Y_siC9*J(>9)W=IxC5>Y1li{LB(jXzuvUnN zodheZpyfGGVwRIkhH)0B(B>9!8k~bTt96Bg-~SuKdGB!3-QF_@;eRNo0(H zXxxy=n|Tu;!^+R3W3HpPaN9ZyDMjE;O^q2a1Yroe*2H#}i|R0t<6Z!4AVBOx)R;l6OS!<< zabKkM&Y?$6NYezqXn)$oTB+nag4#>D4*;KPOh+joenvcod?285u^^&&xdf<5ebkXF6BIazP(0PAo%tdL wgP3Y8>YI*|p0!fFV!;I8wjI)@etmxdXyZcu4c-Mq00000Ne4wvM6N<$f)7S^LjV8( delta 2418 zcmV-&361ug4*U|3BYy$iP)t-sM{rDKOFb@Xt{OgWJ}@UMUz|p2l|4>tURq!%Rf$Yt zcWy{Ab3`dvHzqG@t}SV`FKCHVF&;{OM=~s4Pe(>*if2?w zT{R$PIwXHmHbplv9yd-mRB@)Cn-4KxU_2&NJ1#a@eot_99*K4TQzn>D34e)i&ZihM}Zbpl@C31fK4wMLw9gMCwxgO4l-d= zFB=m}he;_I7CdX0UpXCLsSgbdUNs&DA4(lhj36E!B3G0mPk{(8XbLxPYdj)rR!R;{ zkRgTR3`2fQOn*x`K0zoGGH|sABv_+uMV)3n zgPe#rT!UwJb9!`b5hy^XeOBz_(?xQVE-*2-p@OiIbAKj5U|vf-N^Ek2h(U#lZlb45 z*U7rGx~5E7WX-`Y`1O&qnJE15di(55{`ajfYOdnYCW2QBG^YQ?sg(NYHovoE?b$8s z+&kgjrO~y0gKbw{U{}?>oB#X6yt_{Q^=04J&(+v!vaz1n0000lbW%=J08pQi{{A@? z2Pkzb&wqmN&R{&Y`h?b`(qxeF)YtWN%i!+)X_Tw3uIQ@k_tV?%!~2*3000LcNkl^=rJUxIkvt3Qynz{rKU{)3s%)kBq^4FL7Pp?0| zetqt2DHNb8h*DFah5(A7#c3}qz;JqQr0rkUL}P{!j1JTmUY z=aS-dbJ|u0Bt!7~pD&N0{h2Kh)Y}=xZhwbBk;Ts!FFx(B+EOV=lFH$R=7xqqad`@l zhcz1Y41yH^3~@4gDSUVswxx_p4_J?TNY;SjW`&{LP!xWwP~MCdr;AUmuCAt(F4`d% z>jsIO;zosCe=N6vg{inAk;KW&^72e5JY`WB85xcC!z4>ltYOz0d=g}Y_J;>4`9Ko@e35) zKNuS;8VrUQ8gum2QnWtZof1e9H7%G>!E3eZN?5I4k-~9~LUpR$#)j&2Mt?IXN#Zz) z;tS(AiJ~aSp(uq@qDYRLNR-I*T(6Ph$yAIYDX$L@7v>j$aT(F)`}$QNag@ubYA71H zF@YkjD_aMuo)r!RB?-5(y_Q*d6r(84kh#@bRdJ8f5tR4fkIYtPk~=n)9n_=k-7o3% z)^UvDtg#x3MoJ(!U-o!1oqtZhS>Gx-Olw)6C2c9LWe*5Zpl($!q#YFmaXWjIwpa}3 z>wheaD~j*gudpX?K4gzXLO^RRc!waM<44)AZ{D1L$*#{U3j8R0^ag&go?Sx;fvYjp z)?0!XCCA^bfB*71yS@#D%+Et1>)G`$-`9`UV5r33+G{B85iyR$$$$Cnckj06P2;ix zDv@7qt>LgP0?|?Hh;aSyF#^R+CLDl$0K>ez88~1vnMlz~+^Tsv>Ad6RNcijV67y?o zvO?B?f+FsAKpnMczavurQQ#26WCDR=z&Y=ehI;4}P_nEraU6+?xMBkXglMlzp}E6R zc-cXDtufA24ncC>&VPpb=vQKt9US_X0Y`~DnmQG&PdONh0*Rs=WdeaRj=PQZANe{^ zC}kYpmBpd~o;pz}L+Ed)pY{%vgdDN45(d!WGt8 zb!DuEokZxqR#Rse)X(|`mJ*4GJ!17*6=E@O)b2{0Jp9MAHg#=-`uTv1b?qb)E;APP z3T3RUDj+Ny48+tQNL z4yQX8Z;uB80dtHH;X%Yk1A!dIM~p@qK9MXnS2H|x@yc1*PMZV6K#NxdyoF&PuGiCG zXKB|`TjfbUt)*}dp@N-OV7@1=c%#7%rf1c$p@~0a~KjXQ4D4KsR`Vqew ziwDZ&z+sny`V_;#ro(l{P4hM2(S!;ptMjjM0%*==U#pyo6n2}(r@v@Qr z^3CPP7dEF1yP_S=qr>YJNUijND^Z(P&~e@6%X7&Kf*v4N8@qX630pkdDV~- kNqrD8GYrPi(vN=r8&ZS4MX5jDQvd(}07*qoM6N<$f*jv!%K!iX diff --git a/TMessagesProj/src/main/assets/emoji/0_534.png b/TMessagesProj/src/main/assets/emoji/0_534.png index 9d520cdc2049941f265eb6a539a1e1ecda7dbac0..68755087db34be510f58a0a2611271dea88bf6c9 100644 GIT binary patch delta 1902 zcmV-!2a)*25&RC2BYyzlP)t-sM{rEJeG9gL70k@e&#qs)h83xD28&n&l9G~$hlk9| z$)%u}k6Zx5i4@Dp$e3gS%gfBh$Ht$ZpSgVouC1=MwYJO4%h8hr%8mfSh6R{o0=j+% zuyzBcZv+?)2IHgz{?I)B)>Tk65d8Mi;krco>#TxpNN-6NHh&=ufKd$m;DO-Cj^@>( z!^6X~v$L$MtIyBRetmqsy}g{9o5{(^q@<&`xVY8T)%?UH+}zycDQT7O~B$UL8NnzXrx-N@7^kK+IU1~W-SK~#8Nw3FFx+dvFO3)lr_WWcbE z*ndHCc1hm1Ebae)P)S-Ag2+kJhh9B7!97Frl0W{h#-nM)ny9AJ(LejE`6?v{1&Js} zW363GM&s`TM%ButfRx2=ynpuI#++$heY2MFY~>urn197@*==IxPyT?*`F9`{1ArnS zGQb+CMEr`x;8xSW_ArN(3Q;K8upJ8`Wfpb90JE5rtFm&Oi3Tb8hs0b^80Vv^K!DcNI1T$QJG#TN+G^SSIlA{n*>Q{v5&LBOy z_+U9E<{g2*_Wy)3ItfYdGyZMM1uZ$&%$f0(7rH&ft?PyCYFy$!&3Re-I zJ|dRhM3W(aTy|Y=xcWq=^ZE61c|D(;`jsFEWP}+Y7Czb-3e?)kx`ljXd$Zl`cH09( zO3e)EPo^P=IM|B?hlLniN=$J4{;zAZy?<%9-8I+qF(y4VnWrMEVW?g%9a3Gx>3F_2 z{JN;eTwac(YZHQOmme~r^&e> z!0Aur<<^_J5k+BeiQTjy+M;SaH(#-_$>}AhhsqCBPBYUPhX4PAx@Q|x1x~DHg?|UM zBY#P zsgbG5%p)ihcZgXisFBh@l73&Fnxfdb*Afw#N0cuxV(wH{fN+j8PWfhWvlSc=%p+8` zuTHHrub--XTyPk@M8ce^Du3^lbxtsDcnE--BQb(eEThZ!`F5KFU|ev3z+}76v)<=` z)~MmZ>_(w6V9%EUj1KG%fDD9;qaVRy`5c4+VgrCX8=MK^tha%WARz~N2rl}FfHsW@ zW_Jqag2|X*5@eu<+zSyPL|_$ij!oS82$qtPAqf)vPv%VkY`k{734bG(!Nct9S~HGG zt~UDKSJ0{B8xx$ZXYVOwB6d!XHt?=;7G6CP(1dkFvhZC*5XrYTv_Ux}c2^To@GfGp zWSpjUI9H6$cOa&L*kKH9(^#@4G%=Bc#;NsDj-5)=l(1dVa(JV#39ZvuNVZ|{?evG@|ZZ6rhoqtBB)|2iSP_?oH_!bFM^u=P^DA|89|N-g)K5%iiBNqQ4z@) zhJ*_tSPLd5ZTKiLA&$gCXRo`WX`14^?I zF!HD38MtG8kL#dQf(*eTJdWuoYm5RAXRX$$m$ud+fnRrGT4!st0dgrGES8G{F4%e` zOe;hi1YV=ODU1<9ivOix!(-HyK#;HuKJXuVxWYOvLJNEzVu%kwHuDQ&D01^b074$Z o^=38q+N{H1s)T6_YVz@a0R`0T_u3oY!2kdN07*qoM6N<$g2hLs%m4rY delta 2234 zcmV;r2u1h&4#g3WBYy#dP)t-sM{rC=YL_!CEI&CoD_@*IN?klMFjHY~FiC1AQ-wV; zE-o=YK{qxmLtQRwuL&?>HYg-8Yp*bCtv7A0EFc>NE@Lw=FhpjKQe<{YLqjrZs<)ws z9!h=-GiOFSG-p0GHa}Z8894n z&kju}7Jvy5k`!rymQu8GJMJELcgNjb>-N*%J~MFNee017+%J%1vU0v` zn{{S-x_{wvJI2RGM#jb+ZdcF0!7)BEwFNB0V`^mF@kEQuGd4B4yu9D0mQQ}}Q(ODX z%cE0cp2u6<<0H$!*5Rk))6JP;P|9^<1tH3!nx&^e`Qi3*oH>Tnna-2n( zl!h#b4_(snOtldhTF~`?0iLJzV*Ts(r=8zTYat2@9Ef+G4pD$0mEvWIY6Ja} zB$&%bJY-gjb6~1)2;PXd1!_`xw)~yy`IP zgP`ykl9ccki`DAN#>UEGnvKO`Yw+*)mw!slCM>oTgPl$;2&0-V`D1xeNiUtRtSqH> z3w|JmJQlH%x(h)#I}XMx-|s(bG5A|wJ3mL?Vpr(p$^?}zJFOt zvuvSYDmMOK5d*o6!u@6uy5MIg9*iR9FQgZjdhHd3wY-QVEB_M(^p%AUrxzEW*(%bp zprB@g`8*`VLNQIyONLN0Yb+@2YO%-$IZjasLQzN($2lAzLqtY_4^&)D268d zL`c9RwOTC@`I`WV4niEsW&G*Bo`3H2vLYTLLnOzMk(#v}5g`Qu4+KKE>Yo^}iQ<`G z0Ra&?Kd%X)hzSS+!s7Ymxj+VRL1b;B=)>~_8B%i7M`|EP2JRhP?)FH{)dd_B;!yV; zX^<2Nk~q3jZ`HNhapcay)o&vw!Qk{UfeRUB$l1-{>LUq42sDn@g2CYRUVoi54WY}% zWnRo@&KgIms^B(F9l#Yr$Td!3EY!2Ty@**3^0<-92lLk_jZ;A-IJ$8)_p4HgUapUUx`ugl@FUNtxrkt)JLgC0jeed+-sAIxvK*xF zw(s$md@neZiYki1Ao>$kWZ)j1hSe2w3Y5Hs$RPs(-FS)v;($CjMHI!13ZvG+VCNt~ z0;NC#Tp)U%Xn@WtDhESNlCYi=RD~Vvc_M=>E5gPha2%{BGNQ=B>GdRBFF=tGiW!6m z`x0zreNQaK1Z-t_M1RnH3bHKQ`!q%0+d{PfGhqR*!@KOz69i6=<5{}uZHoUORZYL~ zJo4tq>3BUecTlYs6RC`nxkD+?-fDGz>aPzDdxPWkoHwiuSBJe6)l>)zRY_5a;_$Fn zqvu}RNL-V1`~3;sNEM4zvP>0JK}8U|aNsQtr*yi1e{QmCI)9S~aDAtxQeG{QT+L=F zMKCEOv)MAG6;lQccO(ZNx*6uZus)^HJWXX02?8cdAh38A95hXX-Jre2$+7qM5nuPJ!ti>Wk+SRY z%Kq`k`ptoE_`nAAbB;KPYEqxKIUAkyu?{Wfqunyt486$M(*K%!jp^ z4(H4G;eoDWm5q~=+uMywn4u-wmxNf>lRkLMP?f{)o1Zs-Rb-ui*I_exedv{WilQV8 zlO>wQFibL{ayg4d!xBYdytMfp9vAx+Sq?v(iSy$jkAHz8nO(IggNtW$zD0up*x&yA z_50>du7Y9Vhwn!m(}z68Q&=)?g35_e5D3G|mcqLUeEYUhp)md7dx6R64Nzc|oGhI!s`_Zenr-q*}nz<0iEzI=ZQm9`2YX_07*qo IM6N<$f)L6Pb^rhX diff --git a/TMessagesProj/src/main/assets/emoji/0_535.png b/TMessagesProj/src/main/assets/emoji/0_535.png index df911c57b520ef8133a6058b9753f0124c00ff45..ba80ad470916d1f36522a1e28d0e3ce7d3a03b26 100644 GIT binary patch delta 2063 zcmV+q2=Mo~6q^u`BYy!AP)t-sM{rEBXhQ}70Iz68w{1tr$j8mh%(1Yro}QkRfP0~# zp$7v30RaHY%F2~iJDOQL0{{V^pP#O+t;NN}0RRBKy}bhh0s#O31_A*E0s+v_(5YWM zux3GxjEn;T0RaI4Iy5v21_dA+8Yv|t6A=(GEG*B9VcDU3(SMR_9|{IVJUW$%d?*Q-Mr!9;Krtk+Pa*wnS=Jy zulovr4g0@0019!QchC<{TbN) zEL;Bm3}RW_i6B6Fw1w2J!@BJ>lg@Ux=*f}4;)VbK2AWAkK~#8Nw3J6~<3JEaXG1kD zfCI>aHv)8$>YS+TCW%L=H@4WmCWe&0g@5&R&>>_}(8MYbPYgZ#gh2HH7*+~omlh=pC1_$OQp|StF@Y;8RRQETC~Jr# zbA>R5IpVVUkl?A%KY$s9l){KmdQot9^~xH?TZ{l>g6*I;2r)`K5U#e;aYv1o8H@lk zVr=P!VG3&HN{psW-WP(bgu(s?RT(7)l+|9}N`FINf!1#s@R6SYgcukhg5oZv)OJ(E z+;JcE+aRqWKWXF`i!ti4@^;$E&BF0GAV_4adc=pSF+v>&22stGQ7}RfAxncrYyC%3 zO+hhgCn*Wxy9r|L016@pBve4P4}l6p1|*2{<#G}8$z3JSAcmZ^mb8uvAm`Z7*6KP- zVtPMxCvq*c%s{~R?;j?M*G9l>*jv5 z*&HACeXzq?ZB23JlZ`A~O2D+t83_{l9r>#e^Llzds6clwWu1j+XVaygm4Y0Cv;qCc z`xmS~>i%VO+Q$&e|4vj+i0OgPh4V_sAocDUbMJQj6Eeme{o!!f?QPce3lWJ;5P!ed z-U9^vxAHRWP233Mc)YmUw4{YfYz{5WczoUm7<09|ZB>#K2kgP)HJ=&mu>^OF)n?_M)Nimy-p0lMd z49aF692r@Xk^RK^booc8^YKK(&=q|g>bg;6%-A?iV2wGWNrH01F0{OjNq=BN%!!|` zM6vVJ*L`$Efg?;n6y?f}-dom`8{!lokUWoapg!-ja&MYGnhK)OJ4aaI1XPq|6j*_V zt;L!q2L>xc8JZr?pD6)^9^=$>fH7Y_M+q@>J+xjyd=x}cMt*~MSS%LP z<>U(>XpN|%6prT0O*BdhL!T%X{QK~v)}A1`W8^_4BpF3pf4bv=ariMb~k zV+pJ#s|i(g+>VMemX+LxheFpK0^n4}WQvh@M6iQ|iqCON0YM65;wotBx@RIFjgF6z zEY?m~Ljd^=g1#VNH)DjSbrR<~diO|;YZ)hu8pwdaxDOC<)q_G`ojZgjm+v?`Fi4TX zT~aiRMg;dexOi*22!F}3ZXDBKbg%2CsZY#|!n;O<>B|W9-$dNrAXW20Mp;{-$tLy% zLGVRF=|O}cN*JN;+m8U(2+Ow9$e?AK+bUKq6>Gt6lO(*3{mcdtSMM&~oIXOT0*r#N zBn@oa<{ybc{<8a)J=W#}@3DteH$r$`ATvNBz+L?Nu7pE+- zWlfV+{34)ngJ95 zWLX6Q?*HHC<=bn{kPpoO3+`jkcHjMm2ktIFj?M5YFfX$YCca_bbq80NOQ{tgbaUMT tXrc56_g66YgS+l+TL|r#dRnjl154CnyA7SBHUIzs00>D%PDHLkV1ik^+AIJ7 delta 2608 zcmV-03eWYM5V#bOBYy%7P)t-sM{rEnnHMrtd()a7EMulQR&haSmY9iQ8d#m(r61Ru z7+Pg&)|nI#MS>Mjli8dY(UuizXGzRYzfYF>J3mZm!&(6g5$B z2ry`@Zwt(h5ULL2DUX^AMy{3Alc`tTn zLh{H{#eb$>+SzB?wO-xZqOQTDpPMdxV=({uV&`mYE&u=kF?3Q+QvequCo%mO2Xu-nZ4e=gjW%`r5`HJ&ynY2dPO!K~#8N zotI@-99tHKfd)E_1PCNRNJ5k(cdksiw7a{z;D7G!?jCp7d*?UKu7X*U4|EaoESm09 zR6X_X-RH1QP?;j~+dJ`nO*$m%Ci@`!)He3#zyPaI&1R{iv|xHn0GdRl<_Ono1WSm-}rv zsodoi4<{Zyee}1%>2pMv{C>G#ey%D{Ai`}qhl0Ca)nwS>6vGcEAjei`r=iV9;$T_w z+iqtKl2@uB2tQ#nlB%XQgTXM!EA~0ZLVqV`iEo=;`U19&tLGjun@(Ev}17ajSy9bCyqc|RoE=6&N!*2IEM}Ihb*XV-kiohJN`12)P?r=aMTqW&;FUP039DEtj z6$8wT>E1spvI@jGmn9z-rhB>*P{&~V0oRN1?rx~z2c{R+C6{xuQ{+ywZxY>!@vMr( zI~tRe3n~I>IyltRJ$|A>+r6--mLkFmSs)Ow&WsKXCB_HaU;L=hY7>c}(SI<8r4hkG z$}t4NB4KHGW^`a+U}!v%=;lelV5lz`oCz`*hTSX^P?Uubj19^pGnu`;;JbJ4`gq;} zL7gs>VZt+3P}~&>C`30ACc;uk$YeqTA$EOlPp8xE?X9ztG-X0VG6Xajb1hduk$V@h zhB0@eDG)kLqi7(I4uwMLKz{%}9v-HtMvBg`nEFL*jjG3Zwq zzdgh#L>Fe*azRCrHO$JW(DKIW+pdAnE60w>PaofIbPX+kMPybT4Rr{o2-7lT`8j-n zTJ6>p${Si&mf;K04y=wHB5Z`YA*?7utTYlB`!>*}?Hc;9_^FjIV}ELS04B!J>f#he z2h}&kf{JpCRwL-M#jSyX(ctppd?TOY`Qkq?j=&gE>zI-pLCU0z8gq9HKVN;b{&jI` zvbAG!vct48#*LT9=G~auDlHOLh;A}8=BCh<;i;*ql}64m2{Ah6VLU%cxiOk%E(9*wMxkh<$;tiYvVOSRGIE7n%YE1S&hnrOgFdE|(C`T>BoYZDCSE~NGK`+NDmqP(do2@WxELt!prCk!4}Sy(HzL)|TrE3IA!-O_ zSS|*DHu5cKHJSJfZW*S|^hHkXMOi~IsN-W$Zpsa-JrD?Si=E;_g!?k#@>6>uDrvY1 zF=TGHjAG%R=qS8q(kKj}6PaK`5fpM7qO$U9oP&ey<0Nk+ZUD+?xOJ=KCpWISMKtd~ z5KJnO9O)2@DSr`(bAEdFDlSnUIbhYP8SKdLTke@Q(BcwWiXjjK;ojg~ss_W^5EtEL zK*EDzQYl>mhO<(3jb@}$?sBNcTAuR@6#gF6Sy@`GrrB`hYQ--YM0JCaU@#KV=^~L} zr04<0S} zFMw9kLvXwX_{tfKw>S>`{CG<(RjW76p6U{`r6zQPQq?Y5sT|T zFcKc-V=TTC?eDi6@wvI{)q>?z7r>)}!wv>p% zGp|}KfESLM%|_T_JMQFVQ`C9j=?OO{0dstI)~g{cmIDUauvna$mRU=3?fYL3cApsS zN=LRBd3Oqwq*=4J`QX8W7x5OGp>rfYYuQ-$&VPEHBhI)b`Rdu&@WiX6nRL{h+);7u z<`bitNFIEC|NiYkl62w(?u*TO=VoI*oG|(n$<5)^v(!cs>ak~;tM!{pX0u+eAUKRT zp->Q{K@)Ew3`#@Jzv90d!Rhen S7?7O+0000JV>N$MGOcMq#KgpUR5HrS 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_54.png b/TMessagesProj/src/main/assets/emoji/0_54.png index 6d29c0c763d46bf67e040dbffe3e50248b33dedd..e356bfc80d0484f8de005229d1bc257d71ebdfe9 100644 GIT binary patch delta 1957 zcmV;W2U_@&60;AGB!4VWOjJcja7@T&2F-LN%4`qMcpS%T49aZ`xpzMBhz-biB*<?T+q<<&8y}aPx-HVKm`lBr5 zdJxRZ$&7`1eSCeJgj9-rWTcaB-kL}f5)v&fEnQt)|M-Rf`>g-{yZ^2V`I8L)pauWe zOaH$Mg-s0q{mcL5X#e?;|L^5B1uF+ zRCr#rlZTF+Fcd{s8zhzp#LmvoxSQTPQ@57<|3Bo}Lw_^;eCy$S23OJ}aO)kkFa^8HqX9g2xDF&j(}#rCQ>CxE;&kAV_;Zn|RKCg9DIo$N1nYst6CE zpZPGeJ%6eI7p^uCWNyA=a2b`Gi1-t~H2wtf33`x}*>5^bn^P5m5R3`&PnfD$NXoCx zcMPJ(NnDR(9VZ0vr$NZBnkPN3-gdZ5Wf(?p0kn%|AO{T1qJ{F>8;4#w>^~U{WeDmu ztXq4Yw_e0pL9nK7by0Qe1RQLBZm_O6eaV}4;eUA3)f1%tt{bjy0E~~hSQHTnp2~oHQsS801ib>q$f#l3RHeB9t zdKW|mDxyMzPJxncbb3*swqhMAzA?V70!0)>U00|vfnaDtG%N&r8)yVFe%r#BdLfgYjDdRHD4Ef%{du zJVUH>Z&eBqi1G(#H~T{|t{A;5A;!;I?5#I(BZ>p~axpkqrBa1$*4PAmY49b!amfSj ztyC`O3 z(LSd{j(ejynR)(p+C`zM+rIDHx*Mm5#`Aw1(%3DB%rM%W-rjQZQ^Ga-Aea2Kh(q0X z<}{A4hw0&^&LO=HS$Y^RPWdInPO9}lB8yzxnvX^!c?7Y*I99?D1Q^1x>C~~^D1QT@ zNFJ*-=^9BvvJ7r>=J-4)Q`ypk-SGu3cG_B`r>@UxfH5@87#=7jzFO7}68q4`F6O#x%M@~G85k(SLBTh5hZ?dS?vbeGlQV!I z?2}|`bAP`MWmd-ijM=jyWOsdkzkl&%;4L>Ll<4(Q==XrwlE}2^ZBO?!x=d%odZRgnj2z5PNKp%=xE$Tos zB-%;6e{hG+ZRmp;$7k1W49Uf50eSc z8>+@#zfJ}1(E#EjMFPlj`TCY$kYIr~Z_h9k20@$x0K&}Ba4M=!M1SpZHv35P@UU8~ zeuP~9PF(2kU4g%GhU>T(` zsfjw58v+Hk9@hy)g8>zB`J8A9BG>B z3?#tF7L8ZQ``#wkbibZ5LIRX!m_0=1W-^^ zRTMZB-cNtfLIV+G@C6_PP-qRleAMgq1Pu^WfT<&ufF=&RAO0n6D5OTf!GKr-txo%E zj&~gFG8LjU1Mfw##eMY|u`?7vX@>5mVF!S(PP@wuTfjh6_z{HGkYh*P{(n*Kx&w~u rK{#&Ey=#BdsUE-o|Nooe+v&dmABRPU*Dr6900000NkvXXu0mjfA{V&O delta 2310 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 LNkvXXu0mjfP@Yi* delta 2307 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_542.png b/TMessagesProj/src/main/assets/emoji/0_542.png index 02d228d8547ba35b692ed6b7b68544c81aa5c437..bd590481e87bd06afa3b3d0b09ad35c04ab7ca97 100644 GIT binary patch delta 1790 zcmVX}A&^Rb&L@|9cC1FfAi90H7 zEFe@+I*(L6mM|k*K`wVlG=tl*iasoI-?@_1o^yLiBaK)xqkn5Wzk^lDk!ZV|*szn# zqK3cZ!km?PvRFTyYB?3wsDQVLXyU(^se4^XGi{7yOZoZt@8{c4EFr_4cCDL`sCG`~ z)xKUgGImi*oPcjaDM!x1w_`tG$EV}dwD4X;dnpJ4ieYFY8%abiZT+k0{5Z9N3@mOA000HPNkleJ^c@X!B3xm+%vgZ^vz)y>`Y zy#d`{-`(W@9*{3w>qfJQZ=(CVZ+{D*(^Kis_yhgCzkm6ger~Q&MP;8#cJ7YvreL55 zg};e-*GDpP1*7=~AnxX9MnR7g_(MrA#}Kl165}ogbaR++b*VRL7P|;^{5p3qh%?)O zK-j@BbTA5s5E)k*x(>un2L0zgf5-&a4Y?bEj16ft^_xQ`xUSo}@$0;{Er0DbC4xFj zPvg|GQGcX=n$TU-G@13a-;~lYWG0P}Ke43F`4(Zg>+yKJ)`YT+Z6`Xy)=yLWP+aO3 z*W&_vJ#NJsubCwcVgP}tF4F=nxLit?Q}gm;(F&jtTWhga=#CIv8q&(7&BFqMY#aSW z5QfpL2hE}|3>F`*#M;uijqNlo3b?S9Y|4)yoPTvXlXly2+U?1t(~H93qp!yZ$x~)> z#av5rSMo)x6@(qn>vp@?JkOg90)(>e#|Z0We;662T$@|{acj`)^akyEH&NXg3_6`& z7_`U`6 z%zq7Asq9`vRxrj{P;SpwgXN&-)Vp;E5T}Rz)y!{~TDHLzOF@`|@sF@Pm`~(1r-O1SkOpTe6(OvTFr042)A8$aGf7O;C!5t``uaNEgtI``EtcXUgNw@T zhlA1d6$(Zh2LODh!zCS<4Od}610ff=J%0$zG*v&G3^yQ*qu~e$$eRz}2#Mp-0%DafXY_@n~6niGLQT z=Q!n1a-^Ad>&q8SP4pw50P#2plb~?1IqlNYwiI(yZ(9h%R0zZKl3Dm|6gr;>fA$Ch zQ-w4{#)OSWgyAK#D3!|Pk{>&wJ_eRjLa9vpb3`D}fxks`%TW}SoUc9}6`44>N`It^ z-)uPLQn}qFf#64d#sm-t9;>H9(|_DIpGM+&UfcJ5;2=!2^az4b3~8n+2Zm|)h|vkc zAdEt&146s}ri3t=GP4KY4osnmmkzCs8Sej35KchwdwoIkV#WL+M82pIqf8C>rP2&T z0e}bqXo3m!aY$$HnlRzRj~@ZZf&g2B$%L6XjL2%5CWNrwV1z_~&KuJ}z<+VGhgo{dFz!*y(QaLYwz#xr!aAh4Z#?iW|nRDA3sn? z^|6ZC;|Qnk8dJ)$XdQ8GF*B(@+5!=9T6AIC+y#YUGm}2FvrHy`#M^Tbu8CnwT}n`t z0s|D2Af_m04gh|fKTwpWiGQ`>+B!rO@&N?Im{}~OU8vvApPrv?U01<9afEWQ!%!dF z5I7)A#V@ldgv!(N^K;cehOT8%F+`U)#6T66f;TDU-M(0VRH_vqU_{!sgb*lbBr<~` zD`rWZwC6`f?z}<_QuUTz?dZLo(vV3W3ej=^4AO2N-)dC|t&l3W4}Yj83e5!oX2Fjw zK}fhe^SG(isueJ{kf+-1OP_M22?>`&)E>YD-Tlh;y#_|L1_nV$mBtG#Gnx$Y0D?pq zWVGx3HFwd75ybeSR3DTQLLpBGn5`8`IkO{*iv}@jjasEri6Ou|RUi76E0{}jR)pcS zYJsu}JEFL4#0-Ec1b0bPsXg?$tpuYgC?;@1ob8CBK?tbPz+fsQLR6;@%$1yxlWi2- zrRn_nG|7E$+$N9)F%k;2*5hW0ccWvM=Hl6aR2}S07*qoM6N<$g2d2SHvj+t delta 2517 zcmV;`2`cuD4&D=xBYy$!P)t-sM{rChT9a>ojuSRwrJ0c{U7B)%j-Z~O(v)sAOK`rG zdcu`>(4&JdYOlqZc|2QqLTiu-GHA}4b|g)HDL_{(X|AuCi#Ree5i?@bnRPI1urO_~ zGj6fMjA%h$f4Pu!JTfgQO?p9JgC8+ZT5*R|WN_rOkVs;CA%8McYJ;NApMPUhNcGRH z^UJ6jS)U#p92;1f9bKgrONSOzmJvpR9Z`Z#+@g984iE9jr3frzDJCZA zx|JPDf!LdK`rEn~LU;xrN-CE29Bsi2I&um#YT~Yl=CzLwO^+~aulLrr4=`8^L3&Y5 zOzOUyDqx>1On+<~cFr<1H4ajsB1?8^P(NBkGK*(S5*8cl<8tl7pI>2LCWhhZ*Dm|s zz6AsX?!}@9BUW}?OCgKy?aHY&5(Oz`s4{W2KRY?1bX5ECfDN8-tUB8z32RQsh480``~`4 z*S^v{3tB<|00(kOL_t(|UY(cad)sOj#N)({9fT%LA!)MZ-d!=6nVC7v%*>2s=H9#T zhwgc$Jlij^;_Ud5BE@}wo*A7~R*9r46s;{aHGeIwii(o|ON!Q-n}NV+AP^V}+^lI; zD6a=lDq3#d9UJ>HN(a{0>z4vw#>Vd6Y`F%dqO}Irk1cJzJ^HoQ(X)Dbx_XSf+^uOX zE)f_Q0|iFu^|$Z-{Hvp~7#{HjbnJ0 z=Xr(+r@#Me@1omtD$_s*cDn~K zf{X=RlsppYO+Xd=;h$;xP6s(NT%sl@5xqs_? z+@u$k&p&@Y6$+sukc)=}5X##g_ssb7yk1Y5#v@%_U6JvmDG$=aulfW5E13in%7TM& z+mqYv)5FJU(rL?upjfCuqbUnbA$s3#*4Uts81SYhSZ+_pQIN+F2w=PwXHFF}wbc{L)R$&h3+ z68U+F3o=XQi$IvF&2t$OK)OU1c@Y7Zb$oEnm(gE=P~I}-2XVuv99pJ_Kwtubk>X`N z+>GM$-~xt1LV%dV@qUwjJOf%>oS2wc1m&`sOqT3B(BkH#-c&A$cxEEoaeo|J*~hg8 zv(Kwm>(n}(PVM!XaeQTe7&Cmz>P^yjm4_r*ZNM?DcBOrO7}E}m!tmk!x&5G4i{YO# z`ddmVg1i>mG+=n}=wNVUaLxAO#fx6F1)C4DhX)HdAO`#XQ7MI}?M#w@7+%ht9ZZij z3+oYLZMS)F`fzOlHvnSpNq>bD0?+Cp$il+m^z`)M#Ij8!>@<(S`R@GkFa+tFe?~(t&DXt;7bce14o9X({(bZj!=X;!6R9#PeRKLvaPjfz>(_s-E{KTU-kpzg zaK5*^gAn898&Z=cf8xzmcj8!ZXKinDVOi`Fww>jpz5Rs+3^SM)H-CM#lGAy|YgI>a z48wxGFM4ggzXcpEhT;7_tIk_hBBdK@mCkIyU@)}7pv`6r277Hmgn}Oe!mH9%%Ow$2 zYL(U3j|&VyXmLPbn5`FR2w{k-RqDShB@yyFR+SgZxUkXbGib4XvlbA-Y#Piul@4-9 zs*v-*y_2t=hyZ3Y`>!pcYlHrS0P&sQ)op%cdH z>Lg$T-zW9xe_Bx_NI$3r6Of}ARUsSE++c2Ea70uV3K^Woqkmwc$nT9ezy?GCRp+w1 zyP3IuG*yPEuUHdkIDpY<7{>c?ymJNS-C)2C{hdCwwYEqCYE=q$JyqP> zv|8a70=E)auYYQjT1Ea$I(D_7Q5S}vCtmql6r zps~JgW+u+Z7gfIz%feY2qhzAjtZjAb?tuiOw9W$S(X)$X>CF)6i_Q$AQT+uSCm0KQ*KL`tD=pkZoyHT=SQwsV znS^u5>2xB7Sq%g@?q>adhT}BweY{OxD8~IbJhE{96v&@|HI#eEd7}26IGrJC$T^hS z{`KqoX@6Z<BuqD1_k3${1iFvG%&p=@h}zR5)~58S>l4u%BWXf^Z2E5fsH)7zRB7BL?N?QZ&ob fEEjt4Kfr$h@#)0nQ*Yz_00000NkvXXu0mjfc^k># diff --git a/TMessagesProj/src/main/assets/emoji/0_543.png b/TMessagesProj/src/main/assets/emoji/0_543.png index 8b141d136a19156c5b1bf58ac7ad28147a345398..8641a8868801e4c1e0064769a76942923cf91507 100644 GIT binary patch delta 1708 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 XT0%aFbbGm$00000NkvXXu0mjfaR>P; diff --git a/TMessagesProj/src/main/assets/emoji/0_544.png b/TMessagesProj/src/main/assets/emoji/0_544.png index 884589828803241c87161c91c691aaa9db30802c..244efe1ce06aae34b25acb67d88983db3c824cea 100644 GIT binary patch delta 1632 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 delta 2227 zcmV;k2u%0#489SNBYy#gP)t-sM{rCxZLCo-Av`%s5;aY7~$N{3i79vDc0 zc}6NyE*U)|78nZ&U^gHhAR`(;ZVobF5fmB=IdP3wGa*)!gikOBEoKHEOFl3vDb~I0F9*68K6AK)6&n}+(3@cO)QlL9# zj1(w8Ut(aMXMa8hC0k5RO`dR0?AkFUh2L*jOe$unJwQNibaI+vI)j{u`|*7H_M!#` z1ui!{L|}BSsX@!Qrig7#Pd_v6;$dM-K>FxC;?O2DaI*gRyLm|m%)>jrq=nYolz*SMsLQ<}p>+fQ_g}iko{;;^ zGXMYpB6LztQvjN+41WX(q>>V{s34 zo8vd{|NGH40=|frq!|Tz9$GK zErBOUeYF%|__?nO!Jr3eJRKx%5Ln}b0v+Br6@MR)<1%76=p^DMVgldI6T2*q1J3h-hqM^l8_4(X)2%>kK!~tg#}?`vAB17x<0$GrulYu zb`-@2WSUTp=oIVrfJZM2L*(G0O+Ep?_s# zv25oQSvIc9NHY7+6h2=ps)|G>g$oo!2oDho8l$0_e7{l3ObBP}6+llkriKE6m?F!B zEc3i1@qkLmKv`i@xCp)Iw^a;AV+<&B4LVT#Ku_^UL#tn^XW735l`2 zMqFerffn1TW&LG-AVKZX=Cq0n+JIAjE*8!_wjj ziG`(U3E+cad@2Q=Ia7hh;eR7wY1!d^Ll6v9(n=9$@pLLArduhX74Q+xE_?b1U#M~X zR}7Kh8I@PlRtl(tm3o{I!XDRaUW7_gX&3_imjN{dXJ&{vLqIP(GAJ=-jQD%t=qMUJ zdXGqNKnRhC%d|87FH{tRfsre}0T-Tv5E3k_&bVLm5F;MT0#OTe7=Pm-gbH;$1t$S9 zLWE2ZvSLw|peGE3Koj~TdL%{+;Q@dpEuK zaZ!~Xu8z(f-j_*G{6^MCyaVnh zZjM|76C=}m@RSoQSOE}H6g|Ps{PEKJgfIgyrwjhVRI!*$B-T^}kG=|tV6ixrq=o73 z4icAly5R{5v|cEXxk}=QwO|(DBw3u&1;Nvp_PT5hdyQa{)_?V6fyynHN~??rz`D$p zN)@tD&~*WJB#j9hhj%7PI~;mJND7G(!o$V^)`N~KoB;70x{xe-+xKBcHw*}i9^otb ze7>5`H^9L*@`w_8n-g@0gPw7>E8}IsFld3Q15~A2UB>8qb&nMns(Aw|RrB@fA3rwt z_h{X(w~Ns?Q-Ac+9M#waPAerUl8IER`8{U2x@<&@O1{3n{dsHYl;UW5q)j)xn|mCG z)z@#%&u`Z2w7~@hN3Oc;spcFUCKzOWbL)8f{;Uq=INHo?_hypf5(yGR2pmR|7+s?( zC9LMh$OOp+zi%HOAOCFBDat?bcq{(cq%bN$=1R*J6@QR$2FKL|FaV7$DCGX*SslaZ z$F~9l<7X7fkytKo0__9^8T1=T3S3BWe}8=c;lo)yLDG-!ioD-WsRaBsm8&d+V!4t) z3XIliP$25F*T-95&rnkO-N2($I$PjKih>xqT%`gp7>3#+7|=}8grfJ(3U!i7K#v}q zR`*Dl<}5G_{^eS<`YLb~g#pM2GnN1|B^VF={2v_yEtD}liogH>002ovPDHLkV1kM= B0~r7S diff --git a/TMessagesProj/src/main/assets/emoji/0_546.png b/TMessagesProj/src/main/assets/emoji/0_546.png index 7effe8d43e9b53407a599bf465d3a589de2e5707..b8aabaf079c818b3a46798ecc69e51d12ef1b4cd 100644 GIT binary patch delta 2488 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_547.png b/TMessagesProj/src/main/assets/emoji/0_547.png index 0775a74b581da8294c7e7eecb70476f7dccdc85e..2e618e66e7dbf22f74862787f1690bbeef4d6d28 100644 GIT binary patch delta 2639 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 delta 2826 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_548.png b/TMessagesProj/src/main/assets/emoji/0_548.png index 49e1e015d4d26c1952617e347c63ec03e3289ad9..be487547d2d28dcce700e714e328c1f9bfcca09d 100644 GIT binary patch delta 2555 zcmViC-jIn0<|# zE^4mDrCtd#Xx6fNk&K5kZL!UzZgPQ=)U|>zY_8b4eke=-r#Nb4n*xg{q=h5hy_X{{9agF>!)%WkDlDZH@Bgp;tB&Hy{kWx}}1N zMU0-4PkN=)yes6%rn;whdzpbyKr5!0cIVNKsGKbH?}!8!J_Q5>!LTV-)`PwEpvB{qcIdi&Ovl#QyJK2LJ#7Jake{QvewK zeiZ!*1^z8UpZ(e|C0|8wtb|{l)7A0&g09HR*4Fj??aY_Gl!p6$lJ4GQ$*@}I-{}6N zx^t?h+g5f;%>V!gVo5|nRCr#Umj!biR~AOCv3~|cwk*jqLTo3ooeem&*vx~>%phiF zW@a>VVE^IXH>0GsYBe*`o>p~DkMvG`_rBX*tqb{37L`=il$F&~mJ}&3{2wSwD$DNO z??w#XzgJdSqCD^Vnmb<)4sNyDy5nz_ZQWaggJ0jNIftdFvJBP_cJKYVzCM+Dy*)d- zy?+Q%3WI+{V#`mij&q^Ra$H-OfYZf{2M+iT=Fvbf}K(&1jG$Huc~mZ%p+L0l`zX}HEP4hLf-)qmc$t}ctE?nD9XKLadX5XDUbIUThu%ZjW7 zg0?PnMB^F7(CeY21*AZdHj`Hk)GAMJM1>?tq@*^Pyk0fJ8<@%{hPL~kS%9w0sSW+U zqUiKGD%6sshJzJFhA|qAtmN5TfkHOsEYYaTWrA>sHb7pIBLyTh%UK53wgOt5VSiXx z@9b&2Z;#8i3LT(ndt=-wlXm-rFqjPg}QKTSItUn~Cr#WW*Ths#y zHf6>WkljqSw|CU_wlrlK8yj1gi$ND)P*D(c_=y zqH?##?2*Zm$@WZ)&an&&3v+W83(UsCPmlB7ugdDhg{IDymj1fBj%+VFJE4aEVyyl9 z3wcp|wvuQ8MQ<)eOJe1#{EFhwRt{(TJ3Apo`~NDMI`?M}SN>8+F*Q}bw12vaO6kb- z;txd=)VIGnFfnxo#o_3vFg>uk*4KjQ%mSa*mPQTJ15XMn6hBVQ_VAG&U|^u9XEY1C zK<9C4d^A2)pcl&Oi4lQ_1RL}Xl%P@>{zTvjjEHd5^plCJ7xHtle1s?9uY*C%r@=Ui z=V_j&IE;%#I86gV=|;-06n`k>(TIv8i1Bnfkr>ze^m4+Xc5`83nkls(PCpb`yR4el|X{$O}%V!yBFL(rF1Q0oUv6KiYh z9}*lrJzlLSpb&JybZotEt#9q)@CQv+fyLgz7pvv-47wCte1s!xVKZ=Xr2tfj~+wBbiD0X)A z4G24cQ99M%ppHUZ`i6!WS%sa@@A&LkR)L`qUu5U1U^{r?#9^mt7)atofkL1Rg(?0# z8v{u=l|e;gs0u6-0%qb&d@rCFnSR(gng;`bp%9-JpHZRwD}PNP2dpJ{iszsg7{Jl0 z%v7DR6doM*@lkkejr5?$6*8bQ&d%lQ6h~mh$iTqT(h@xMB6f@m>K>iz?e)_2Ob%XU zm^P>cu%QgdaIPFY&v6i+=Lv$~`12Zo;=42* zp1{FG_1Oi=;>)Fv4%*$l0ff-w4JH=55j-Zzt9Uk~jB7bk(E+A1<-B@mRux5B$(^~zu zG?9f{go~L#z|4}(%QvbN`7+#+%{Yv1WH4Ht&X?U03>mNpT=*M39RzjREu)`s`;(65bunDYBCLyBr;@+Do!5 z-ndx4yF1$+mRu}DdaZArTW_si7AL)p;l1P3tAEr+Bg3-t96S5Zy%|w#v}ti1XK<3m zaV;)&G5(i$mm1gFw5;R(aq2j=y&M)9_2W|w#sAt9anYu=I#2L}!{}ngC#GGBUUpIcDCcQmLV##jsW@Rh+sfRl7;i zCUoLj#_D%M|DAptQs8d0+XxDfFdgyZ-`;HCj18Aur!_#F@z@E<`cGAU8b R?k)fT002ovPDHLkV1g1f?(6^n delta 2915 zcmV-p3!L9I@qm1MLs_Ht}FE4fa}4XPDMpnkHvv zNW-O;TWEJfJUq*pFN1k^-tS_5k)_(*fjm)W;-rJFawEBW7v;rD$e&7Nn9Lg&75D3+ z?82V#$*2F!HGkdmb??ch{rkT3&aAn97kXMYreFu-$7t!-kDPX5`{c&^DMm^aqKsk^9u;{IIm#5L`_Eb_=a{p54| z-){HPOaAAA>ANre<9hkmRrSt6^UqZO>stTvmVf>1l=|IT|LlwS)?NJGWbME<@W3zY zw`RJa6uFEV z+<(73g;xzUVG8;H003QdQchC<9R3X${VoOm@9ysX4pp;h824{R`X}}1$yIUs{-1JQ zgf0I3HqPak$3xhVsqOtp`?8Af`To*}%KM=0*7$DYqlcjTM6~U%aNPa$-`UdZukF;@ z@2PZqgj&P4TosTsRh>}kT7RR; z8wM#!FuO`AQ`0E(m@nIXJHJt?_bpdu%=acNZKC-em0inf2ssZ@N(7bpj^RzxJnm>r zO^iye^C+BI7Oc-aP3st5lEHP2JFt~&xz${2P*>+ahw=F$UafSUpfDgf3>3JqfY|2hs6 zwg0?E6hyi(GOkL+j5R8D-=d~Doi3Nl;leb39W%|v5}Hm;Q||YF zR$rQrP^mNnRcH!mv z|Ht0pkxNHdbdnZCqg(fQwU#NgZUQf?EPYL}UR02~nbEUz#*a)kNLYO|^#^ z&y4LEkBu?d;61j%HZ`_mn|NVg!fN&vd%iQa4GMLk-@)Nc(hG11R2qeSQ-Z!I5GdIrRC8|kCJj1eVd*r zQ0le19_J$2($ccIupmm*sDJ3>wY13oe&(!>Y4o!P(jR1xPJgf0jSVixcf5!=fq)>9 z!9pPJe?Az|xb&9d^hEAAdOc0FI}7h`zE~Y}iog&Fk@mrb&CP#*Ul>iHRvNa93QKgPXgwQBa!sS-m`G4%hdAn6nc$3Cp4~AhD7p0+; zae*L|lr%)zkFgSakJvp5nR}LocVoN_(%;th3-DkDh+7YvLL>dd1}qYY9F!IYMSK&tJY zvh)VO%zvtu8D!9-ah3)IQCesW#z0%7^9ltilgU_WWaXUS&o!tG@T5ZKAGgq;U>NMD zT<#Eb0K%ZQ+V>sHNq|Lq@=R4 zvLpva!IDJD-2B`_XB%Fn>g=K1{8!8D$exPR=dKB=rLU!0aPFro<+~CJJ5X?`YIMLc zXAEjxE=@Ac!OU>~!01QCxo-iKU%L3`fXNmeX*I4;Hi{uk zLX5^%Ro%#QdBFBZm(Mp)Rgs^X__SzX;IXf(>u5k8aLm<-Z-LU<+NToV605=+xLiKf z)#Wn{j9y56Ef@MtreC|dB%N|O9vxBDiGRhn5)q5VeKUEu9K9ovOxaAP!iNTyCz`W(ga z&IB))uOClwEmKxbQ{ljGV9G(DkzPj&=!c>D8uBD!o4fw0AHHO!F8C-N4@a|rev4xG-@>3D>Ky)S_e6YUMTAPeurXPsJ z3Y^CjHVWQ6&yxZHFFQN?==+dt$f?VjJCi9rk_RhaC0Ft;?|f~Z{{#04)@Fn-ty%y8 N002ovPDHLkV1g_h?}q>Y diff --git a/TMessagesProj/src/main/assets/emoji/0_549.png b/TMessagesProj/src/main/assets/emoji/0_549.png index 14e61d6b3c9151d4847b0083e9dd99c03674f059..c933b745292d23dd7bd36ab975da78e1ae7c442f 100644 GIT binary patch delta 2448 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 b6FvM7a4t%jyOj&=00000NkvXXu0mjfzt_%L delta 2540 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 jnh;{4X^gfCfA#aM+00000NkvXXu0mjfCB|Ao literal 2783 zcmX|Dc{J4BA0Fg=Wf??K%2tfYzC?=|W=v_u7;E-jvS%wMS+a{EMY3lJQIU{jELq0B zWZx!RCS%tmWX$)c&hPCx=kq+zeeU_(b3XUnKkh?)oHiHxDRvMD#D%_&GCWk|?_y&) zrIf_2xx;tvV*k-psZT@pm z_eYNwt@FxCzbT#SMk6UNHNp3(HXALM=p%?#qReKK9A)?!y+>i0sI*3nYi+2X=_Br~ z*HLPuXDemtdo8nbQ*F-#C*MH!o26E2q`IDqe_zaAs8CpFMX$`6O*dYduJ#9L_kmR` zxjgu54Q~FO##G70hERcA2QfV6)D4B>_Lom5Sf39wfO;TAU%G&YmE1FW8)Tj9Wti=*gMo4rOt@mr zloHG!rG92r;pS~A?w^ue8WLUV;+#IlI2L*tm*Xuno#Ekn((dNk4}*N8JxsF*p_Spb zsrH!aP}`aa`{B<$bDuxmw6iYFNF)`8phH`wM&F9?WfC2@4Rx{i_0vBHGl+q3Wia?sGRq6nctju620_hhli`QMMf%unX#ly$? z<&GiF2qbvTE&8pMJS%7I0UcP$0{(*^01W@%kN?rT05A^K-T{E-6MxnTz~Sxn0zk=s z9l&9*I)51cLGj<1E>-^5hj!5ac;iDpJPIiE`n&bpEFN}ulLePHEsHcsV}phGZ`E^F znqOuPRxGOa0Xnb?8~}&%2M0jfZ+-9in-8;tq(h|vfDh1_3jkf~8(ZsZp)4-DAke=j z&?tm4o+<0e)yV|~PE8Jb6`iL-Q;YjE-u(RxV7j3Rr-$E7UZ7fy+#RVR&#C>QDd3cq zWml*%yX(eW$kH=!QmmFs4+aOy3Mz2S4^rp>;NnGJI%z;Ax3HR|IBKpHn@iTWxgL;{ z!WT>f_YqC5Btixu}EXmsswgh?6FPcFiUK6256Q%FdYT3gSk2*h(VpS0w zoc^&Bkt83Pdb*8lP1(46Rr|(4 z9y^~}oQ-|06?tC$nqQ!A+yW+^AF*LGbT==Uv#+hQGX$6l_V5&5k7fk zN}FOuDS8f4kZP-4ZybCv6~?&@Gg%cKq^S~){W^hQdj8~q53IjZo%`OspvK#KVeW{3m&IaL8PEyI zUNYN~2~TT|5Ye;R;=Ym~A5ziRnpEEu^<;buQ?ncfKB>LkQc&Qia|&Z{H1QEGaizEz z3wqmVm{F-&qtE=PZwlyAd}I1zQN;RAVxRmh)PWjUV}h~zY52KP?^g_qBVHZJo>Wt_ zkc@WzNN#)pqnKI0Azsys-NpOEvv9?qgNUYr5fgJ&ikt%71x*6=x7(tUEX9T8`-O(= zcTGdTba74F2R`)uwTkf4bbgVe zg%ure*W<0`CjC55LyID%#2`NvpbhA>r+1~xQTqdNeB$knP^tNXbBr0Z!L88SWyXu$ zrb|1-BO6YyB9}RDIq4^+u9} z;SMBLdWZ$L-rU9yK+xn+)uX!$=kYKk%rYaK@?u3(-kae{T z_B**Tg9-uR7b&pg!j+uMQ9R632UWKFTW}^L&}dkhbnE#0sD5Lmxz|FhqM;T6(<>s! zF03v42M3?&5Z~c`q-Lr|&2XH0Uzu8_0c+%cVAVS0*oi$iNDK@jespy!9UA*_AFQ%Q zS>8fWwi-!Y4)va*Y)vrAu&Gow=97}LvhsAdH+07L{LrPFHtFZm^PgJGm0Ca)T_QFH zE1K}OqPRQJSxpa6kS=7+dbba>zs}J3a|0?41jcdR|0K!_GYat=ftMh$vgY> z=in+2i_tVu9?q!dY~EIKy-@c2B1fM9&6}&v1!m1PwdRa zsz9 zeiMY!ShhV-Bue)`>V@Au1>FG;w}rXl($u{c_yqhk(Wvt3@{DwaB=2$Y`NpIq%>+EJBd5Dfl_$9!^q>!Ipo;tErTr5vji=H zAzpoNvd;M~_&T+tBlZ$IA%Q^1j!)3T@^HYg-8Yp*bCtv7A0EFc>NE@Lw=FhpjKQe<{YLqjrZs<)ws z9!h=-GiOFSG-p0GHa}Z8894n z&kjMbe|NF!A?}+^Mv48sLJ(8MAhJiFU01A z048)&PE!ClflvJnG6feWlxVB{pw`Lgg<#jV`=)c#%l*=l@$U5P!*QJ=5a$j8Bj4?Hx3!z0)rT)cwKU z-q`fG=joP#iP1ga{^;|`$@SLy<*(bz?EO7hMkfZIB=C%nS%N0@<@3Y0A6x6|>tDbA zl6sp>$ZBld<6ME!mY`SSEyWHpd_DKlaj<}=cYoB?QP4L&b`Lb0Qk?esZY{-6t4SOL93>=8}o;Fc{z%Y1OqMAUj zB*{9nbbGr5-7vhGrlA^x2Vh>bY07J#4-_)iytgN#H*RVXs6c};P!%DpkdLt(%q_r`TjNxeHIfzkgV4G+?o<7;3kJkLe*LE;o`+on~P5M_FM!_^`lLpW*(VEw5FpZTWGW`iN(2utC&5bk` z4NXId96}=dsXWVCK@_doS^lItX$km-eT6x_>&;&5C%C43Zp2hO72+M3@u=JQ@w+s(-TIA&No2 z0sH2>t}*Wa87&VgF~U!Iw{KD)wkg80zy zG#5l#AcJ`IxK_(nQ7Nh@6MuAAyMlS)2;ya*gQ8zZ6L>HhL}ML|B85Gj_Hj^9h(QN~ z+ui+2;es%a_E>_VYJaefapK)e$is>LS1N>o07(!OAhax25QFwyIhF&$XaPHe6G+Qo z2Z3U6X5ba*$>GONh6NMW8yd~iR0a_zV6p@Pi)Fw;)3j!Q#Vky<@8p8UFkTSI zGGB_tVjHnoT;({`j3F}cUtXuZ@D&RK?F#W%0SvTU2Kds(#+u}fZJ4SsvJqpX%towy zaPp~kd#HPTT7SD#JPU}dU}|O)6c{BZN^8)< zwGt(xTr@-D!3D^xU%u~LW+fREjh;uZI4?9FlVwUuBod_(ykHVi&t!0@3T~YMNa}^6pCfJ>Te>=_a`46qk{13>9~bw zUq5)Rb{hiU(g1t~X)~C-6G`5U0}k_v>;A+wuai0Z3$*L@sME!g_1T;Oan1H*N*zC; zcsywg;N0;e(7i!*+@Qisa`-Cq#+ly<(`I??Bb{ptwS#iGD)KeEvi2wPhUkmg z>8dJ-@=Nk^M%@>?$Hk;6%v$86PzqOi?xN_Y1_{y>PPLHcX9XLp%6pn=A>%mHowPEn zp=EALRo)tPLE7c+D)ALwW$^`MX_UVB6B|Pt zWhqNtH8mMgIU$~VB7E|KocBcdD>`TY&hr1$-OeFz!o3O;7@q#{&+IQ#k(gws%@`f$ zv<{21EsMMv4Qp@ILEPG@{Z6-!IoG^bNR|Ys2*R=}(5K_TqgDNfwzz-?6 z{4twdVh>G?IX0-vI&{ zAOQg3e-;7a044#$Y|-PlTCTgYHA^6Fv=c5zE`YYn&PyX*%pd<206_d5n*d-3@CSfO z060GfaJWOSNUe5EW~D|Q%04ce4wSF<|?vg~tFSkHHURoPntUWLqV z4=jT6h}wCb4ysa{P>=pCYb|u#PpY2Qx_;>VQ%J#eDL;hVsd-K$yiSl0Cj6RpB!^LL z_cTrWC?~8aS%@oJpf+8qk38rEotgy&(lhtcoAb%NOWA==o-KK559KF-u|`OdN< z3N+>4&a4c}X(qjQq`>RIxtrHyhJ7(-7#yLeWox}yh2@nn!^)uCNY9HRxZ4nGCkw~R zc^i_nKJ(J8K^Q2}5raXG^NoWmt~praqFx#8uaJB1h3~3T7vU9CY4qZcee`Jr#=CgJ zNKafw7-FNP1@j>TVYIMlaJti{EV3Z(ELI8}c(67>?ZU3ft(G$o8x7g3P%nhn63gF_BcRB(t!atGXMcd*-NES#C8Fwdh2`NF6;94btrf*s01?qGL)y23Cpd zXa+uX*sEc=2>pL%EN*{<#gGcH@D9s>5Y=vd^E=DdejE&S)#~ zLfw>?Gt9$Ecm)%n;nsz6%9WukBSr7p7^wc7fj)Y)^>eaX@5_g-B7yAduxl%NO2e!L zzV{m<>h9$|X`1&glD)RNQ(aK=po8!IHRnmCSWl#1k9?l;m1I^` zC6x=I+9hNk;jN6}A3Lzn-nkCMSQ>vED7X0FF*@?wG0R9Rx=18NQH09Ci(&btgMGS+ zyB!~*+~~Vr@;a>6X0E9|MG#NHk)@Nss9qj8zQ{f2Zy&FPl*3-DF(xd;O?Gc=;(WMM z2T4IPG1s$+A*ZIv>dNKxertHX-k(IR!w|TXw_|<3%9NlNf+L>Jox&1H@{++F{WUiA zNWJIi_NVtVTjzVdhpxK0VusGy6Fx`BN~{K~^sz5-NeI)s0vY_2ygb_< z*P%KJXK~DX)HBeN=pB9?>g|UV$yOx;fD567F}?uQ5yBrqFUT{D2MML@LD4FQO6mb@ zyHD_lVM3|9I(@5vQvN&Jc>ZnkR`HoIWf72ngI_y@dNkd|f|kIvi1By%hYs7y0w`Xj zB$Eb2U^=R0Ok1iaG-o(4WI4b1PASBbbO>QQYq9Jq=53|lER&Vek8xH8A09ePa&6QJ zL5=XsLydM#Mb;=WO5Eog&X|5KyB(w(N{a{lAs`of!YJYN!;E@a9c&stoQ-Q3r%e!2 zPcX~>qw!sH`&F78%2NKUbD!N>C}Doz#`n1ds}}-1matQg zT4te!k`!6k?NF+FrzfG7-E>}kHVt>uLe5`>7=I>@mmc4&@R9$x?S4oO+up7e(_y5X zUehqk^hG}t?kESl+^Mia_%P&2heD9X=r(fWa>(NT{2klcpzoh1-*+rE2WXr%!Sn2q z7-WDOWR+L6^Yr*s;NgodrGXSz-jh&lEWIyVVYMvX)0l0Wu59VXh&6?E{yY@2nsXv{ z6~#%%#HBAY78y**%8t*qWU5b`j`>zmm|I{6xCe3a9KLlLr>zJlT?sDV0>?%0rh0Za zdYs7tMs`bis8^*ul*om6dZx_HkW6#eu|kR7s;)(7kYL-piGgQPZpGU*UZGW36=&a7 zsx&dG%4ur&IYDSDeNr06nwr_!LH3YE`GajMMp7-G=e21#rBB@x?gEV(Urchu{}B$ zYzNh#)SQtWDyacuo3R!he-8Mrlt8c-IMExf)zYhGa;BH$+&^Rr4k?~a(nwrScjnh; z6X2&ZMB9t4Y_WfH6=0xE-;BJk=HJRs#VsApz4pW=e_FctXRPQXGVgI;aK`W(O3Ihu zn|v&_Vn{?j-4;Sf6_$LWzK51N^9mT@gQs%v%=egz6~*N^KDgCrs;}(Hnt3~RwzD-R zwx1@|*I&m*PFcp{A4%56gCe7L*_A(@R(Qm0I$DU_ZlawRDflvBR;8kCx=`tEx_ni+ eoqUmxCo)ht`)&kO03(+#9HggZq}izM6#Fl4b#WB{ diff --git a/TMessagesProj/src/main/assets/emoji/0_552.png b/TMessagesProj/src/main/assets/emoji/0_552.png index 180b18e282a84eebb8f02b8af6ab2f71ea7c6d47..53f39c2dbde13f2447f7e80344eecc914ca081f1 100644 GIT binary patch delta 2605 zcmV+|3exrd6SfqPB!3N1OjJcja7@>k7cx|P)0!PDW2QM)aY1O7n2BK;Se@OaAJ>~0 zT4ie1nG_I3f)!Ac*_;^BmKADgT?sK_FKn+dXsZb?W*jzEM`3v}Y_B+OuH2p!HBoQ~ zFlelA3(SrZKVN}HXNl>p8serJyMGWdUXnUjYrujJ)tMGDZhx~aX|T?a5gcs7kzf)x zOI=)4K%}CgeU7B@wH^J&DD1Hu7)gT~SDFqzb^F33*qasPrWX}cl+TnF>8u$lW2N=F z9||^Z2P|aYp%xrlp$-lXwR;d7UZ@5iOA$nV|II56N{cC#_Q;D88c>ZGK5H99b`LOF zFKn>*z9J<}d4D5?;Se`wC0Uj3x+th^4B@OLz=II6a|B{P2ShCO}>~2~15(FEB6d+cW>pH}&3!6n`HrgG>i6q5eQ|o&MWqTT3VY z`qC#@jNHYG{?baNgGWeli@%8=gojyun}UgcJIK8)BV@3ps!z3q9M`8g{qR8dB+8 znd9dhVx7EAn%>+vc zTPu5$Bu5NMQ9*rOb#+~RL6IcqUmz){ufAL5+I0a{cdP3QB&XfK?oO4fWnQkIfBblU z*EQeLQgx^96qcg;J5?<$ExTK(@87?rCU^Gsc3$tgT3l6k>Wh9#P*8Wb1#rprkN^9q zsedUo`QpXXr+@k7a=FVTzgt&uvY?s|02|8*+dma{+y)k)s#;u9R9EE!r0wvl-_FZJnL))A{&NasU1f z2o5D}DxZ=h$(k&UxJViSrAnnz0;Ezo@NEec_wMaXbQ^vE65wLq@pYUd55dhgmbKZS zBc5l^NA68-j~bkS5DsW-Yg3&o$dUpMZMU0QLL)R)L$J8&<=$SO!D+WU98e(yY<~kF z2&6cc8c_J`tY+6GOf9+JA9Zw&LIhrc3$czQs+ufwy_W9*Nx+_-fx;&b9=z)q?@MS8 zX>M+w8Ff0_juhv!Ev_0RIo>zZtkn)B`o=ptzyKp2aP$g*YoZTAWL+zHHOlR=UM(EX z?g66FD2_*?%Te6nu-kpkQQqD=wtuL)C^E+@e}4(PI~-65UrERK%ZV92hfoG|#Q<|- zrtkO4tO7~S1?h*yndYGc)G^-ij_<|9&=Az{4`voOq!)6sQ|wN2ZxTa^iL8pmLmHD- zh$;eUI@r}bG;yp#JG8j3mLcK_MIaEc&W?3;B__r@9{f|G)g}^MV_^(SBY&cWRA2~# zMZ&W1?AYMoVAn( z1%;x+Cett&dZtzd$A9p!shy%ww~SU_%g+&~SVl7lY}^j;yz-UZRpeVG0$^4pol0ovztW_q& zKtY1ikw_$rm;?nyDKL8WQvOMb+{>9D!^c1c2L;6=LLe}>5r3I(_EPytiu_x_49CX+ z&|#qk?Ix3u!L7j5nf}O$y(qsG4C;g!l$&zHY7YcL{9>ns5aIqzxZ=cKNM<(FwjCgXR9YOHW7PfyXWL7kPO)oPjxM=n+V3qyXxcqAB%M0C1HBpB)c zt>kpa&nqb@X^6fIhjm9-`|S-Sm3cq;a3m>dY`9W5P=DyL4d`gA)f$EuNB@mS3xB(L z<3{aI6ja%G#Y1`q1_q*f{YRRnIU0~!3-x~ZZrNzO(s+VIQhQ~6eiZcP)5>pw73 z0p?>Yz8f7Fup9CD`75=e<(6tsA**KRnkm48jkO%q<-s( z(M%-YeSZJ`?YkuD#0lINoAb`k#e6tn^l6e?BdJHJ%_P)g&oWmVx0cOjynSMY z%YTc_B%vXXe;%p);j(Nu^Tv?!QjzHO6y!$F7a{uRuX) z*jU_avA|r?3ksv%VI#l=rF1-=PVHV_RQI{XU_cRh$b@vWo2djmp=x=CTGje{a^7vj&$o!6QXf> P00000NkvXXu0mjfvnl3m delta 2548 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 Z{{cgDvX-M0Yt;Y%002ovPDHLkV1m(mR-OO= diff --git a/TMessagesProj/src/main/assets/emoji/0_554.png b/TMessagesProj/src/main/assets/emoji/0_554.png index f3184b28e7b43e8e9b273f9ce530efb7ce517403..01e1bf01ac99419d33bd89bbb79f471356333f60 100644 GIT binary patch delta 2784 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 T(F>FE00000NkvXXu0mjff`z-N delta 2780 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 aDE88u31HfW&Xx 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 delta 2400 zcmX|Cc|6mNA0I7`=`hQjP335dk#pvZnMWiRrsT-Y<4Sl&qkVIqxpJ*3cZE2QJJ4eK*A?e^?9SJ&Q$apxmslgjVhO7OWtNjF!L7s2_A8w#%bj>uhu*gqrMboYU8X9#UTYa( zCr^)dd|7D%IqeJ2u-tC!r&>iWr@to;`M&DpMu*(MUAZp{sqAN%;{5!D7VY^-+pPtc z$yS}ohEQ-V4BUtWm(R_=%ABt!PE}~O-4KZ<3tFfN+2}~P7>XHTU{5`dj-+co`x_~O zfWu${vM7|a*bxo1^eGgQpnS?i9Z)pKE9+rpJ7~gk;zvljYL|_*9ZYm>3~(0-cw540 z6=}&+l0vd5$(%%LMa(64l3HvC$@`*tEX5_*(@7a4hm}71rvF7nK_(g{s(K3DP*wPy zHGx4uIhsI_9d^}@dG~VO8 zu!~<{;eal#Rra`3_CPA5@_ULRCmNmp8uV)d69zyq0lNmC;+8ArGQq!FLGCOzCj2@G zDuNk`;Hq-0JINGqxCUmZhu-Vgaf-Bzs`tDz4AOCqdCZXrB`{lKm!s-c$BiGIxB!7b zYD26ntRccGzG;=`pe>tR5S%Lp|HUW>%77pj+y!6lW6E$#XC-+K{w;QgKq z{`UXJ;sAfF+a5ukx1wjtD&DrAo z-uC>;9&vvL{~P{G1$#0*3xwHVFygZjo;Jx8uT*O18ok_4`JE7qkeDIJOlNK-7{NV`ssd@YdmiS*A?;@e6`z; zc+NhAy9~O-|4QYdm{Aq`PScGs#+p)3BgZzeR3)N7a4B)&@je1G#6<}!s%?{qUw+&w zsT%Abt5a6@0dFE3WV91@m-w9T#`72UO>clA^5S9LKWU=GBUDa&#?yAHBwy!@FRk}6 z`G7h35+#rR9Vnp*1gm;}pAbrhC)q@y)lMW9d9{`tEBa%5HFizRVC1BR_>qI8WQ2@} ziScJk!9mjr6?G_YuIjwu%!LSeS3(aSpc$+TKgAN93-7OwHX?9K5J8Mp!D5JnKk&mL z*DO6lLcV@qkPM^Qt6wz6Y$wa=;zAXv(HvIt*ZsF0p)08}x#zP6Xg&K$7&xZTKaezC zmDA?a(5LYw``o)E+y3Y4QHleVz9v1n?=mB9CN>&Z<#$_TV*qdQC1llWo+XVqIBaE|QX)R(jUPnCZ*6n+(Wz?V zGk9nlRj>Q;?Lz?Q#Q0EDV5uSzopJKExJMRWRVVvwv{>=yS)VlhTj<-1emKTyk=hNn zR}nDJwf8I)uH|2La*abqF6zIEJ`zSR^t;jJlG%*@lJ<0ZT<)|&IPQ#e7q1W*y3Q)*sw%lGr%&*rp z(#nl%TJj@&YGgLpy=V*HsICs!N$k!|n?qq{!?de0-(zn>Hl=}@3eIY`B)s{f%eBzz z3muNC)%@C@Ql5!8BcnIsChR$@U{#!$aOedsNi?z(<2y?hlxT6q%oy@zHY??kvi8pk z`03(Z4f+P8gl#1?_0yc%uA(N8O6I*|2aU(9|n4Z9E*YPcieHOl{+34MT-pf##kpo?` z!IzMVsp`e0*BGjKsMk!>zM$yC<-&*6xizctb3$p=c|b^$hf`3y82b6@xYrMLMCY{t z-AUM!o`Zc>0b)i6q@l@~GkHtLa#~U(aBtLmR)pr0dyJ?X#4KH`h)K$o-GE2f-C1Zc zo>q}htwOOW70nY>%K=-m?A9&=5qqQj#t*Z^pYQdX=f+zW=-*e<9!;@~x|v$R$|m{^+n&!G znyV?V@DUKH5%wSIxb%lI#laqtD0g)AKXgt=1dy!$j|0-j^PBY83c~;aAiU5S)(k6K&vJ4O7-$nk}U7an#+07H(> z1_&SHYA`}RG*^c}Xk+#0t#ypn;f3R+NLM$;V99CYv*`^^#dTNz^#V}M4A(QP9 z_6P!Vhg3-KeR<1^IbuhGMphOopHWV=vxedR2tGlA-i>oLaOuX`I^zzK^X(hqcRpc@ z6|4&{=|(dzO$R;-FHE}9_31}9zZkEzgHH>jL^pO{yy)wLAKcvRR*seJd_i>QbZ+f^ ONrojuSRwrJ0c{U7B)%j-Z~O(v)sAOK`rG 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 delta 2539 zcmV~Qr zHl||`JyKnTf zURG1vq$TOD8t}CrYC@eHr}9p{`@l7gfUxacb~lB-tS`S>ww>`GO%zH+n|kT zwf~WOam$%C{Q1Lic7M~jbH$~xVj73;4WY_|OWlQsP4i1U9cnP3s+d^qd2D7t+SQlati&{bAHC+oW{ za5@G5^PPc92!K;5?*1+R$}9hvHqew7 zWuVso>s|imf%nKS|I{#)(EsnmJHmw&sBRJ1rZt_0X8)5dwWWPPAqeuoD1g28vSTIU zhE+vvl`dq4#oo#CQvd(}Ms!k6QvmNHOdB&|5(fTu{r&Bu{_g$u`RTa%x@|Vi z@|MCn{QdmW_;1qt`{eqW!TbA&&*)Wo;H&QK<9|*2)tlOf?XT&=kgC}JoZ-E!000Lp zNkldh-1@uiwdcgg-QC?#cXxNGx?Fqm*S&ov@IL*a z6NbB(z$7PG+25UnlT)1J=kW`Qe<;Y!5uEyC04xCfmE$;UsLs9+0lzAd zunyojKENV3$>qb=g!M{Zwu%BF7>02<9EsyX9KIOkCLB2`vUKEDB_KSU+GIAFoGVr<#K%oWquOjVMNFoMS$}Obn;@0f>MhPH1`Z*hdZXFwP@5xwS?vIc zJng8+qNRdr6kZMnwOXlW8CRMeW}_S=!#F>Sd-BSV(P%P(!J$@;vnZ8dgHRyB3$jo= z?C)rloC5G3>;Njzc>J(9q8SZXWv25ko`fpAj%Lyt&!*kNk{=3Ssm1)YR1W_OHNev>X9z2pEOo z=BnyUb?~P`8ZCi5lzv2bH@V`9P<3fbDJk~CB4PYKm-n+Q!DR(Xr#n&jM? z2-zrSiQV@0?c4nh5!{l1NEB4Tx(&mq_KDDB;bpF?DkyHZIqgBQYIgc_^z*LB;;^V; zQEpF9M-OKAU1Gb_X1mTgFMsjpos^xRyPBq_XZz-6n>ChBz%o92uoLb3yfdXBTuusm z$Tb-hv|^N&VLp9~_RaOpz1_4}I{Q02HQs4h?Mv=7iD@y05%==A6cWtlVu-zu2YqnJ z?(NQW6`IXySe*;)+-7L8lOpbMRgp_zAs3;*KhDPElO;R1(^Xhx)_?z|;z`w~k9)L2 zY?~0@6>vT4_go=Nte{PMpZ2$#HjSFJLepv8*`4~dhf5TU)<$W6;C#&PYMn?y>reoh zOk=Tt!Xj%$Es@YPYA5F6{tsNKr7*36)=4C-t*sh_MT3yRsze70JB8V~XT<^+<v@VQ97;qoboT^ozY7G!#)O0KxG|FfA%Wr+<@ltgF(jDt(I4dDWwp?xp2cw{mP$&p6TsYA?^yQ0~OAHby z0TzZKv`_;WPJcq~bCXO{v84dE>iw6oY=Y?T+) zFD=zR$VO6E``s^rKp?g34sWTPPL#vx+}{chmc9=Jet%v2{=VRt2)v&v*49AbTP#{| zhX-eOr@FePc4r5}3tLg2FA!T>`|eR4r{Ub$r8jFWEh|3X`_e(_LSr~QI5=1y4!fn& z<&@s%8)<3zW$ElAUS`Aj>7~G%mX?;^e0qI!OFH&Uy5M%Z7kb8?jr9~Ql6w8Bp=C7? zSo%xmFn@oq4+MfO1_Q0vlc{B?bnMl$G_S_S7E0ff`k9vo!>TV3IFqpq-s44|?>B?N z@NYdyLNlaez$?UF?KT*6NYQXULyk+!g(z=#clTA& z)0SH90SBU|r>C*#eVfO#3PT_Cr0;22h9tbQYyKIMOz#JZ`Xcx9oEt;#zV?Lu?mWn z=wvmxDd6zuZg*o*3KUnnk;0Q!e7zYr%gd1B1KJU)ZcE*8A5mUf4~nCam7>P7Cz%xA zoIZW}>YsqqKz&j9pAWfK`Ynt&4oAMd(fCC_{|6}xSU5X&n27)Y002ovPDHLkV1k68 BFRTCn diff --git a/TMessagesProj/src/main/assets/emoji/0_56.png b/TMessagesProj/src/main/assets/emoji/0_56.png index 1c833274b36a998f34ea9448a1712ff7fd418286..644c20476e42639d18ca76da496993f1d61f2a67 100644 GIT binary patch delta 2310 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_560.png b/TMessagesProj/src/main/assets/emoji/0_560.png index ea125d7e5586ccab6cd615a05fe4130eadc2fa39..00bde64c5ad61316437079887ef39f859dd2f115 100644 GIT binary patch delta 2610 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 bw|@Q?!!@y5$4=qD00000NkvXXu0mjf(wa?- literal 2626 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_562.png b/TMessagesProj/src/main/assets/emoji/0_562.png index f7d0680144b2084e1c2547723631233a71b2b3bc..9d15ab11bb62feedf9ee7d1918698740e05c7109 100644 GIT binary patch delta 2226 zcmV;j2u=5=6TK0TBYy#gP)t-sM{rCxZLCo-Av`%s5;aY7~$N{3i79vDc0 zc}6NyE*U)|78nZ&U^gHdKyD5)U?WR*eoHM2IdP3wGlWktAy$(IEoKHEOFl3vDjrq=lh%1Ao@rl%Kb#%e^80_g}ikp4FND zTL1t6B6LztQvjNxt6M{i6(s(;aJRq>g2L(E`Z+|JiAjf4`chL#3ASNBk=^39xU@+dN z?}RUrVhbsj4%6vyRo4Wt0HeKa4WsaHEXWDI(9TXc9A2~);8;3J10ZqHv;d5?b4+r8 zC9tVpTMA$w1h!-+6!Q6e^hldVjL|d=C4}Hz7NNpVTk(509sa}4P6!z5dAyD>(9`hb zIDZPkakR0yz4hN*M+h6lpc(Z+pTfpinfu^pklHVXGh$hWwb&MQhOvwyZYI}3*0Sl&iiwaMoryAZiJKk8Oz6_(a7TB>^ka2CT7*}K&%;oMmQ=m(O4`7t$0vC_y>@FsFNZiXJWD4$A44A zGSO(JbBYXWsxp$yKBTbcA{tReqLac63L=092nCIap_=l4QA$hzXPgy4cOa9v;GVG6f1E+JEhKZ0Ar0Df}l_Cx`ON#KMNn!pX_WXZhp`MU!K1 z9Sa!>Acg<%V&(8eDNX!w)DHNG6-Bz6!0~{bXWn}p6|%zM_|*lWloYvkXDb#au1Y0E zk-lG`6bk#^sTqADp}@=?+%hGl^!5CrW-AWv2)O=na9hL8s3N{|O3}~qihmlwCvFeE ze*Lk3@mFzs0@v5KcPZQ~mDp~lUi7?YWYzThYggYdZw?M_Hdq`H5TJlrT&UGHQqT&Uly&I`1xxU%^U~^830}mLDa3-s#zG3!0;Ez&e}Dl+ho!|6 z5(`Vy7QhF?_+%118_%x3iyb=7tZt#y;M#7 zPYjXZ8I@O4b_%G2mAd;Ngfs59ya<&fQ!oVjF9T`-uB;FyLqIP(G9)op4D&N^bQFmk zeMY1fAcV-nZQ7asmnw?Ez{r)qfD2DT2nm)|XFP9th+#%EK*R=}Mt^w-p+X%`p^tzV z0YWASS+OZe&=Uqipb32v-4Y`Pa6iBja;YS%IDGTq0h8rlLWn2P^M+?laNq$P2BH&$ zDXP-L-O;(DJmjzh2>VQYdKrj5U`rpFZMqmDb zC_;pnL(kq&c)AIRSASIoq4Lrjn2YDqJGx5{gk%9LWNP4Jy#^Uv$SCxjVzJ#F}msX`$UkFTi+9zBeBuuzyv(86?A z2Z?)dy5S89v}PD&wj4iVZJ0&4NED_tLGU)F2i=Z_y+$xWYkyk8pt8%w;v6Faur9O3 zVwp4yO%q^8(wKB`49+BImrFB*gb*(xysQbZUUXjO1c>L-ghXMmeII5tU5BvfCww`V z%T;o@1~}M84pBrebAsk_(KDWQWxO_YoffD%K$R<%WsJ^M_E>STlGCwbC0C#R^=or~ zkJfxzyBNJQ1%DsSQH@RDv|OaZ>2SG{+hdk1%X(NZ=j!X*AGelHDUPN`-EBItxyNx> zef{SA{ARsQ>s(N9Wh=|xO4h|;f=<>qw~n{(&+1T)tIf=IZ6+u#9w#w`z+ohb(N(Hk z#Hv1wjFVjO=l1dO@$W{RqI{E&x8k2o3Zvp=wzzCl27d{sb6iyb1JKxlLhe7E)iI2I zd@C?8aYm6GiDh#Z&`wa0L7$$Wz=ag|_s92NzMR$LB>niVXz=?f6^D0I+43?dmdkOZ zz-WyI1)@HCeZ2MU3?-#M3_Loevj#^}6vW78%VjuV7;1~4Lo-PWirzaj>LeA19z8a# zp3xA^VJjH?Wm~lRDsU8q0muk576&sW=nwt;ALOMgvW-gJtpET307*qoM6N<$f+nO9 AO8@`> delta 2462 zcmXw4c{tRI8XhMO#}=WqNKDMgSVly$Ph)Uo4?~3+<4z-WT+7&h)0mKwCBs28){cEC z4B4_IyM*j}mRzFj>-;V~_rA~bz3=q{A^O$U%a>4q^6N!JUvnfTdIJ!r%JEQF;*t*#@=fU z*ZG0VrUO|46XjO3rFvs|*E$&2D!s(>NP^yIJ`3a@PB$b%tzf#Bg-ZUCd~U~kPJm1K zEH4Ie&RkiN{HNL@Llsv&dB93D!cH&x4m!onn0enkl>i9GI~%|B#>D`SnBMlqevT}v zOJx||9R+vMk<0V4XXU0c<7kxoRt~7Eb;&?|G_m<5spc8M(Z>3LA+rC&yUwE6)(m=t=-$oS*Q zr+2;v>s!!R_Sx%3!EbIwb=f3O6%pj8i~S~6af>vh$s>AD)uxVt@rb{|S2kvR&1Zf| zeS;$B@$S&Tg&Ncd-b?5hPp7P~6<&0K5p5tF2$MU^R;2fU$$jAA3<3ldLjB2LG!k4> z4oR&C-yzMY<%IYaFj38i(F)R4*#{~hU5!`{4$+Wj_9#Cg5Jnm4refB2jC7HJOshc{o`2>?El5vtY30W zX&^{EY)b=!R)Cd_@88W;aB~pI?s_)ExdxcrJp!0c6s#xI%2s|t?pjaTWTJQUXvL^wub$!egXDkS#7kJu5mx;8zu|*Uj)Nj>$^$ML{~cXi^-Z z_ZgFitH_ye)o_N$kT2dQY;D>uhe+gE2=ccZ_6p2>`=cA{F7UXug>aVV!~oW5Xeoc( zZaxCy905mU&$$@t6=XJs>sA-{SPO9p11w2;$bc)J$GUXWnXN3|vb5UYk``vNOHWlS#XmCgLCu4T+AfOfAL}u^CL9@-^>U{fJ>5L6b*nlAz(=Vm zvv_?&XL47oxnh)B&*u^OV_kBCJ`}dS$bGQ+WlkNL9F?-x5Ro5Nw3vK^(0T@Mp4+@gq6qgZfU{$3Dc_s=nGwM7X!2%JO53!MyUsuw=6r8Y^G&W zJ`+X6keP_7Ie7Rs3N!eel8?_`vi-K}pL7|03T=r!sBJiJEXaF)%N?7~!{1bplL6;d zo()k=O$_h4FkpoZ^Cb3PNkHl6N2J2Id_-v!>D-!3={D^=p?j49vf2_Z5e=eZ z%V+hkrHB1CU*D=#(;wy>rD+peBKnV@hK^c%87~HZcVHcNn^w-D3(X}!i=A)PU)T!q zr{XdsV8-tI7gRh{4LNOwf9LZJekq;sVO`_Xu=ofc`O4!YYN$z0xQ-vD zsi=YRHAk7QtVhXT=kIsP6cQp)k$5Q_iR-YTgQh>7LeeYiVbdpo7;-A&USg{ z0aufVN}B{8!?GTY6p3ow@zE9(J2AQp{a!9uP>7MmWRE;IGaSftDryNUzwi`xY7BZ$ z2$K@IXn~YTkLZ-CyLi^{t>|QBr)PUao|I1j=^O-TfmzxQ3OuR4A97<2Ogo2IRq48g zZus}jQqHyzHjiJCbc3-@qy2SK^7+Zcy@isvN?cVD^-X$l;3a*dxR^`!b=fb3o^MyK zxJi4~nqPYpeu3QYGcGE-W7*5s%gn?k%yTc+N4L^q_Jy6zp}2n-zH9kB1N1SkQKR zweYWnM?DX&37T@jRa_#3YT)$1cxky8C0l@|?Ugp+4vrw$&AqI6lh-{=9KSB6`Jw_n zIWp9xF-_T9RCDSr;!nm26tC#8sJz^#C*{ByXn5AHZ{yjaG_6yGf(EWxHaHix($@(y zlg)7GqQDY@b7JT&S1)1b^HaF6RMI{f6;o!PYqNG6!YqH&8c-_$=5hdAWzeWEPG`h) ZAzS2Ak3*z9{f>Sq#29UMv&g`i`d^6C8z=w( diff --git a/TMessagesProj/src/main/assets/emoji/0_563.png b/TMessagesProj/src/main/assets/emoji/0_563.png index 171464158e7bf4ef03737b3a79a2d7f59db19c34..46b48572acd4a3e7334c2a0cf745b886d0a23e44 100644 GIT binary patch delta 2266 zcmV<02qpKE6Xg+*BYy#sP)t-sM{rCi9T+DhD|m>OHc@I&VRr>3T%w?&CsKznJX9$i z7iM{eDMMf{Yp^Y8tqL$?P-$!_9vDVth9MUZJ#w)o8x%NLeLFKTG-H@28Wb@oBo8rR zI&iKzZ>tM7a3E8SGf!+uUw2-5mpm~qCK?k9Gh>yGkbsb;8h==uDI69>F)J}696c%{ z8(X6kQj-}-f;T525=@H@KX({DY!EVC8%1{_7ZDK;4@fjF4n=_{B_=>FC?6gkQ9UyV zE@o9hH(5kDBvz3LCRGL>N*EUx3^;Eolk*&H!6#s#9bc(TI58klh9^#W9)|23cF$l= zMh#J)5+5)l;l6;> z%+|H8p6~B=+ZT|;od5s^+DSw~RCr#UmxWU!X&Q%-a0JL;0}Sj8JF;@EE^&AF;O_1^ zzI*q7-+%9Gva_{SqzU&>=?baz)4%t9zpty)VM(8TYDFOh3cYH}>Wp%%2~A|9*G4b#QWWu!}ITjPmcZ-B+hKnVJ;5yt0D+X;#m(lYt>Xqt&@>Vbz%l!; z-|Q_?Afl?u0)^qBsT3u+1J&!3DyE_8x@h(o5C>8`%1|7r0%dLsb23>y(r7d^q7btr zRsa$ZKrbGpi}XOjOtLwfZFqQXd1rOW<9~EIzu+}9GgEFvwArSktJUTj3dDDo$}>)< z!7i=ttgWpsRXsBV;(5S1H`o`LCW zD1c?rlAhPqhNj{K8!A~_Lm`VE-;7DQ+-O9jSR3W)P@mNvdF3gWV?K{(X?1mNd4HKG ze6eN?P0D4@PaPKYyz<0+J`07@=ZisMox*3bxVi(y+CLQ#cw)%-w1V@pbPSTUf243a zak9i2ICfbndZC~hmy2#*6T+CuObo+tN(>{#Vo+Go>4~wfOeXdvW&oPN(kxOL2GVdD zmlukDOT{my!k@v*7aknr+y-hT}Fj3}HV*7x8pPfQ|;;zn^}BjX3=!PWd9Uc=eh zYuV0Ud{FpZ80IvA?kZ8;Ol8Eh+cf*M(kFt;D6{ZEW_;8 zLQvdZ*NUdXU%9)2@jrXDqRWf9j9aDXmx#huukGF5{&&CDR0J!vZ@0I9?$`E$P&lQ| z4h!rftdqt3HY%0l>%G0@P_q}6yKl$eD$D*%hBIh(%5oy(tU-G*)Xa9Vxb6RIA|ZdU zSS83ghB zL))QH$W(Z7iOxPtMbC&~u#Bk)LBU9{FC^PT zBr!7HMJRp%SH=v{*@gjYgGLPI;Wpd^?_+F+;b_#+4qXOfFlaq(klP>mqsgqz5N$p; zc9L$mG62f}NMyOXTwaNO*x}PQJ?dk3wc%Q4%#@{$b2fBNDd)qs|d*bcrk!<)2H1Loo zxY0N7r`rhA{b4j0*Bv%THqBQhNn!~StEa;@ha;zmqaU7-^nVVFPELm1iki#u$wGRO z^O|r~{F8M!RJS-eIXcj5X*dewaaC1wx{zGR=hIkTgvDe&U*Pqes*2%M_-MkyF<{H- zs`;cVrt^d_#{e#s$ipFuBJ7Ho%?-5fgG~=;swm2WAQuve#9Sgl99%d-$m3JlEvjl< zf7jEhjQ2S$pnr%$3CM-Hxdlo|%;h-FF_+LN_)2HrFD_1w+-h8H6{Ba^7FT59?EK>5 zVz`hOqU%wJY|_Hqf)>>ZiPG-JKQ_091zAzvwdls!`H|aQ;+L;aPp{WXiY5wTJUO?J znoGt-N(}I&^P9_?!(Co*%fGdl?1%HLAoFRSqNoxjihmTvQ%XcA^5$~$ z^5Co_2=R%>Tk-F6fs)gFGQaRZ0S;Mn%MlRQ`(uEay(jto4eco%TXlz^`%oA4Cr oEcxv!P)%evQVN)f_IE%32lVn^qGY+rc>n+a07*qoM6N<$f+RjY-2eap delta 2442 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_565.png b/TMessagesProj/src/main/assets/emoji/0_565.png index ec09076702f49aafbbc457db3c5c7ad0f70a9367..81782b23db1785d2ff2bebe1ad98635ccf48b6f2 100644 GIT binary patch delta 2916 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 is%VGT{km-4RpTC2f>bmcy9Vh100007irG> z5MqY_0#SEr!}L`ixxhM-OwLJC$RJbwl%6lT(luB zTTV3G-&@KAwvB;(KVU;+VK92E*>4uBK**J@54ehk-~8fr7x`M+OC20yAeiDJi+C;; zV=s~J%#C@$H54IH_3mo4uijgIsJSeMpRt^+ikO}>80Bq@bWlk&XQ_@=NcWe|^L$bs zX8AqNsWtg+?t7bhge?aCAkFw5xG-|vAK`098OZO@A78(BP zlk?GQzA1I4I(7&h*%@OulH*^F3T~?|Fi;e;F;K_n!~2t6`%&KAXs=%6t9C4EYrb!! z*zz0`@esje&@$POAva$TSPveIAPj<6U=aT~&U zO%F!mf=%mCPxHf-rtuL8CX&T3Wj5wB9PVDnxM;PP*kWVVn)A)7k~Op4GT2qN zSd|>%HN^%(7jdU#U^yQ6R|5cm|93bC`}4x{>uyudy@~bjU#s`O+CR$u4gd3viGN4b zKh#pV^E-R<3v~ZCodH0a?e84Gp40u{g;M|+Tv$J6G;r1o05|}kta+4eFZ2_MBm2J( zAN?Q505Ej$Pj=4d_niw90|3(i;79>-0AS~A4FDpyw>CF7Gn*4cK_GfAb!A0;FDhgL zjW3@ASYa9vayQ^#)3}X}QWiR~5F+iIGKH3wT@#Ts(HP zI|aDIm%WpcSHq;;)HfhqU+)SP1%>_1q|Wb*$W!MlP06s2wzfJ!BaPWrCI1L?gc^Mo z`k*0|%h-2x#4*IaAw``I$w%hIj>RdZzR&!5IRhcWZsbU^&1@rG;ty?frEb12RSh^fsrT-5-rsKQPPsgP4A)r zwZ&*cBxGuNo3x7pv8e@xAWNx3S68N2BGJ7CPrr|OigU~_;`3=@p62V&+@+dl%1!`q zI~Lq?#r7?gL=JtNp~`Su+fgL+_C`aaY>j{GzTnq=<(&c)A=3+{TmJaH`S4Gvg=@zj zhYy8N1zTY^aLu9uU|X@7G5nf0Sd>7ivZ#Eh$D{E2aa>ytui8Xj3&df@CVsG@98Jw7 zksbaa<4sNfdk%S`#LdA|Cesv@N=L;BPmGCp&k|YjlgK_EKk{YRFmX#->nY2~oLxMP zme||G&W=0Xp77jf6;^!9kZN^1!{fCjp&B~vTdQ`6OSdj7cv9rBO-VvUqYU5ZS-*A! z+`q;7{HEsPXny2ePM9q^d`kB6LUcG!;EUUX3z>lgY^t4(Tfj1>bo-oK^=+2hyWZ1L^8f?N75LH4@kdu?w%uUS^$fGAx(xNkjX z%u%Y@&>?PuC`3(#iwT}&W($83@NI6?Jz<1MU#8K7bsF=57EvqY=}59>qUupCEbYl> zB~xIAdnQ3HuM|r%sv4)uVQiqDTKqSNy@>GSEG>Nn+d5hkSRZ~k6IF5PD!lztX{eBb zLfHJ5e_(IRKW5C>f_twx=CI`gsog**nM_?#!21V(*xP3Swf{=H&d#r+FGo zYUg63E~6F*liRB#fxWL`HMA#mEc&_VTXxa*!=L82!&})dvZ}T|c>d_v-D8uQv7u0w z-DSh&k$2dfC`509`y`GgSlcLG(eq-(l`=oMBFwQO)*Vs=$xJ_n1XE=MrYE9ic>t*U zC|v_Ug;ZuWxaDBOb%Rk*O%FLxneI>5NAjA&d__=ON~8%g@>sq@_*G77kY{Q6(DAw5 z63#%&wDW1a#bTqPtwFH5n$l+;kg+IwO_}O)%#z`9kJ~YV*NA`tKUTiX8Y*yAZcc7op>d|tsTy}s$g(?z z%9fK*L~Sys_tY}~j+3(CtyUclu9<5tbOW3lQ2jg1Ophj(nC11i70&uBWc)YZs}}@# z#>W2K$s9e>0Jug)8DI_=c(8~0>CJo->{6joy#}KvGk&0d<(~E9d{|Cg?9!}Ra~7eo z;(#V?h`JF)Z; z@AmcS6*>@dEfZTi8GLkATl`=$(SIhws+jX+>zM^0`Zg}&K3XWiXOpgQtYx_RFTc&8>EOrHQ&6GzzLRALgj+vV@mGbvN>otvM9Y;lafGN<38Oq-Yz}KA_$-8~R>gFx>;>Q_+2IL4SAHk%-xW4OsPxIDA z*Ndwk`B%FuPAmtRd?U-cA~cO6EFfhE_|5naX0LjMCA7MAuAWK@QBGaB8jj6AiJe^r zNEVJiuF--*TzOM7#29KKN>0CoIYzcNjyn zDaIBNy7`!vku)=J#k_xS&az*Z!Aw zKsYWtZl;1F`$pL|dJFidRJ07tb;0dUJs916>-ycpsvcOg6G>)?YXt;-g=CqLO#+it1E3ur4r=F7R%B%L*wd22?wxgMrh<|xp7`~-k-m-wKlug{! z#rxjA&%33Wc7Gzxv{>1zkfnq^^zG!em^}OF%=_fUqk<^e#dm3AT!LpUifJFZdrb4( zqU_j;e?l$F(A3Gox_y6vn~sNYP*J2TEU8F2P*PH!92{{F5XEb3u_7bDCMLi~NVO^_ z!X_rIj-dPi0047zQchC<1~f-mYY-yM_3GWlleMFH|9}7g|NsB6|NsC0|NsC0|Nrs- z|Ns9J{{R1W|NsC0|F-}C|Ns8~|Nom;|NsC0{{R2}IsgCv|Ns8~|IGdW|NsB~qyGQ@ z|NsC0n|{v!|NZ|`t#QlO|N7bg|NsC0{O;~Kh1qZb00vb_L_t(|0hElh0l-icMZayn z{TB_}@PD#9=tlTFLK&r;U?BziCm|)q+i|6h)!O;syhMUZ{F%U`r-`$mb1Aj;Hd-kz zDs3nI29e&3rh6%^WB}*|^2$hgtviy!K=^acp$Qs52-=2b!}~wr7Cn2-8J*zBPf04t zJFTtrUR@u5kkV#%*8xFxLMS^a0}UM6ST{{h{eLXvv_C7S3w<9 zC$!XISgbX0xOof_@7BFgQ-F4uI%+UbLn4PlG8vHhav0X)QCn%X_Q5C(^T8_vw_9gY zB(1@KwMKD(mup$0<=$T0Y*rnHksn$3_Sbl0yqBfnbZLmP)GS1idkttEf41}NhJOh7 zVp+O~j%lE^#Dt>82ttSg+Vq)j+doAtDmzrj;uy|fW72V)KbOD(4K5|KN&9OVJM1_qr ze?G7A*1FX-kJ|defeQIDvZ?CHIirV(oSqfxVQvvH5@oMXymvI%;G50<3`a_kDjWhE0I)VVkfr}iG5L84&jI4NeSG2W)L`j|G+25|IdFiq zNXQA^vf~Z@*Wvm6`=8%a(ti^E@GC6g-=)^BOfYJf^LvEYoKF8$UKR_kB2fS(quX)W zJ#D0$qR_Yyfe1}V(KxMfm;YZ(5jJBla&Wn)f`EoB z|NVEFlea2yD~R+B5G58uC`vLbNvtAesa%eglsurty8>~JVoBr}I)7iTRI4CYQ%iMB zEvvv>r7Sf7t(0!hDw-;r&r@Qx1>mP_OVcs!4ulNsbd{c%H`Mcr%)MmhIkw*i3^4n; zh0*%dC#KOKurjiRQuDmxL2xMAvD`B9`mP@Yfn~V^6b@Xi0XRdwCyBG*{%kZNJ@5lR zG5G09-?!SP3{CYRbAMhzK8UE7uUmnSV^adWV(IlL>?!w6;sP?U%mGsm62~z(U8x(Q z+$&~?ixiJCpcHdNzV`WNFG9M$z<_ z$P>Mbo00aYgZ_lbezi1J)qLH~%P8cp{6G7qk@rHmVZXk-yhdIR!rs%B2JCn;qFfKj zGV);0bIhmjiEF`)F>KqGq32bNSG#}>*E3X*gTfFQw&9G3%+>KEnHdg*yJyFF#;909 zUe$!=IG#-SX@72@mP&$9Qnl*z_F)o_n-|_8b%7 diff --git a/TMessagesProj/src/main/assets/emoji/0_567.png b/TMessagesProj/src/main/assets/emoji/0_567.png index 6dbb68fcfffcec3d706223ca23eca2fa57ec60d6..e7a8ad9a053fa65986a9e794fd11f21236a206d6 100644 GIT binary patch literal 2783 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 delta 1896 zcmV-u2bcKK6!s2~BYy!7P)t-sM{rDNST$EjE>J@%NINHcY*?P7j(llJDJ32(E-)b< z94;syLN_LWa7{WiC@3i^F*7wC9v>qmCLkdqI6FNW8XFfE7!(y25fTzXL`Mz}4+{$n z1_lQp7Y#Tp8eTyrPBt7cArBP_1xY+DY)vtHVIzocF@jk^U4K|phk0g~WlE)YSZ!fZ zoPj)NX=$>Yk(`i$w0~fMW=4ZmKdh2R*Tt*i+R?y}X}gGHZBiYcd?U!LWs_b@%%Xt5 zqf5q?ZQI9ikZmHdnLzU4h|0KP)wFof)78JQtek{}n~sK8Qd6LVfut-frbIe|8XHj> z7h?ztRzD;O8IcEkUCC=%3r&6$8 zc|U*gm4BY|Q3RrVL77wLk~66=gOT#jMyAJ>QAMIE1tP(*h#7S^fNs-I9$p!r#boYg zYW`QI1%%K0%DRkgtS6O}axS7`u2w6`YrCtNBzX9|vmRp`Uz@={L!@54LhkLpn_Ee5 zFy5DJW5m3hNc51&qZ&(tiFRAb*XQ%OfZ68ZRevmd_3%MOymqzL91Isu9|%U$vW_Fs zfx*Y^-%4GissKv=zRVc5#KkV;Ouh@I=OA@JO~3sG~xwBC&* z81Hwwm`F%p!>&H`u5qCyAnqniV1cKU-Vn^F9qVwyw&t!X1c;alht!n_$x6}F#4<+A zyMF_LTG&v<#y##9LzWpr!pk{CEUl-}1>W7P-yhww@&KEd`AV_o;^& zb`3_MQM91PeFM^ktwj}=?t=-YdTvLtfEFNnJydbD=uFgMGsO|DeXZj`?TD@xN0*pc zRS>W$@%6d3>9>fxBRopYBvhy*v^GD+V}Ewv{aXYfb~B}5C`36ycn#0-b=KP(1VS?~ z+*HgBtGZ^4dPYcJV}!PF(T%wGMLilrq_s0Jtz*Qr0nsV`_pu0)5ohvSu6X-C=jbZF zj`-jjl%7(kFRqfZ+^vu6dl?}fat8r_24RbHP}NG#*24rVfO6FMl9d z1dPduA=-wo)+?OXptyM~76{RpFD|8kQE2}fn3!KRY;=f4y@&u+I13OQ6c!)3c&Ksqc;JSWN{?eakc(tAzQ3K z3~VgNvH#O^-D;0km~yLkyIY_8fAfAUBgAu>mj5W9?>$FVD1hTkGxu)qU5@lbhRI?B zF+r!l{~ImI?!ReYdpn<>P~k7OnG=LG;`-x&jtm;k&&hn%aFL4=ww7I?18Ej8C{K37T-qSQ4ymp`_`Y_ukqLXfC@Y^kFE~6*_383=p~Q)*-gtdNX3( zwIQ^f>oIQ1dWH_Fl#p_;V}IMG3C@k9bL*~aTdx}^Ou5R?L9-Q?!Z_>Qm zP;UOnYZ**)hmMq0lf-7+WQ<;0w~f$!xPN$!j`g}}iVz>YR~!mV@v0_< zLPW2DF8K7`e4bdn2UV(4Xjd>qEn2*yPH8l9-R zjniC&o`;6@(KNSb=ww+HrzvvQ#Kmww+@%Spdr}~!F(D3(d`736W!ck`7X?6(ES^!8 zp%eURq#TeV2%<1th<}Z>jZsf*6w`M1?%e+%vHcaEQTpd*VT926-Ux)lUavPCf-#0S zD1x*9T(i21(%gtp#yi{N6a*niM;*Z!8Rb&6yZVn0AkH;=380j6*=aULM`W?lYxDb< zB)wh^!#_WXavSA@D6J_qMv6}Eid5@@8%niSB*`u2qCa-b=3y2SV4Z%z7{g`rA{6r8 zdq_BEL9)0p`-fuXh;sM5E}@DtY96D7BDCVu*f iOii=wW6DoHym1HMCJyB620@De0000~De2t-^ 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 D;C3mR delta 1944 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 BKtPLW{x~i|eA@rhgUv)HwgnIRC^q@ShUo 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_571.png b/TMessagesProj/src/main/assets/emoji/0_571.png index 4e71634a45b502b8257f2e2c550f7adee35f1df1..f3184b28e7b43e8e9b273f9ce530efb7ce517403 100644 GIT binary patch literal 2789 zcmY+FX*d*W8^i}q5Z7HdR*m8?K(Qkq{Pu?NmAlacFF#Qwp)@$ovwZ2N4R z{X&hxk4~kjH%J!qV|&r#wsfJdC9=#``RPiy*U3)f4oSe34fye&XLD9d{%$(8^}Xl&mSeaoGQ4B?8#KEeIO*r z%LRo(lkb{fZB!IaoxFrn2)uIs8Q$)U2-hPUc?uCz6NhQa_Ud>Z@ZnW>Z&`FxmZzq& ziu6gbJc36#>0wW0=E^|%Y}<1QQJA<0>}@D!u`bQU7?Ba|GW@ZUG1WR%8YL+qm3ZBV z+Md5XRIxPL!JPl7jgZ{zE&7}tfORm^(^Q{*8L=}^N?RC2Yn}b^t#Rk))@n29y0yth zUGkUgu(AB$`N{;qX8ve<8s=`_oBL?$6@IO=@aLCm){oVRrbx!}0G(30`>h^qO;g_| zQZjus4kHF34qwMn?RmX zb~beY_%#615YTiEX3Z!jhu-%}cn5$SNIC~L5N4M>!83$EsT}}C2SPK*P}L7_1^|g` z0~T@Jp6>xjRski-Y&P;{C3_f;06i*TNjdV8ans&wUh=axw}Bkf`75+2-BN+G@dpcl zIq=Wv{}%vYkL|Gs0JEnoz}^UGIZ6Ux8v|6Z23 zSFZz4@c!2t^I(2%etvFlF5vjvT?pjRnyCTG_Q3%Xr8SS!ito4n`L{8v%vL68b?xui z>Y$h6AKX=m*aik#Co=tBr~Gih&)n#0n_Ho3d<&ge+FjpM9B?%VX?e*14y;&$&x&mv z_uhrKOli6!${{La>36j&D#w%Qb0@Fsh4pmjmmt-=YhT?vD@AWVsmi{eTUaYTid!tt z8PgLs&;tW<_KE1WTCWit^J|%xy)4Ip%?q`Ygrwi9iV=LepF*gmA9eLIf{U69sEkR9 z=<>vb7>c&I0~JE;fYV&Cm@_y&Q;=hQGoHcAS+-FqADo zFPb>IMd6Vn*uh1lmiCCU0@tAWfAn1HKN2;PM);R71otTaxYjHUJBi_FR~0$=fiqGc z=!i3Hv59_P>j-)+THw=WzF(NJ%izSr>8=rHcsyfowRiN32&)3 zwBEnB&3qBCUB6<59+Rz4g8n+u|1%i?Ul zi|E?6@fnGAbp9T5J$@khtssB1|K=vu^k7`NlT?zkRkERDJ-mAwbtWPB5abpO$EJ?NuJIYVFd-sy@lBe~M-48%RE!wUG9Bfn zA29>()O}c`FNKc3%4<(J0gbW}_)sV*-ALjuDxW7l5WA>HJ%J31x%mK`6im(|`a22inD)ISuiRRWP)8$z=_NO;>(2^V`6F49R)?YxTy@dD<(WASSx{(7k|OO7>f*d@ zxC=X?{C=wK0ozOd-RGguf_qC$SJ&zMI@41s2;07ePn8Q+?%@ZIqHd>2r5$@GQoxZ# zb~1IpKB_F7wV8NCfFLXp(L{JQ!+-XQP1ls9cgr-4Dse8rhiN4mXG=SMSY3_w{qT-& zKcZ-cHU4e^diZcKZTX7F^GD)rR>OmmwV}Z{)pJXJyZVgT-RR;8FHKgXb;YGSq6Ch` zG^CCAv!0&ua>p)Q=(%be%;`Y~ZBW3@wG|6qLz z!P0pw+f^n-mPN%ICazW(HUAhigRv#hPjql-0%zpLj;bkzJCZeC8EJdrwuM^tcXiR} z2l@1XG0xT11QWa>&1L;)@6)XKlHu@e(M)M8%eF;zizinSybmPQ%1cf7rrcORlW5Xi zHad{v@zW{#M1p}-J;yR!uD!;9Pf(YS{Mtt{Md<$RMELMl;Mj)Y(0HrFlR_EJwyQj` z7pw`J+Br!nl~RAfgz{b&qGBApcU(7asN-x0x57>A^hw4}+MCx!C0APJ&^8XFuP z78Vy16crK@6A%y(LPbbAJwFl<4h{|u2?+@c3=A3<69ohXIDaY?9uo8)fr4jgYMhdZr(IrPQBzk=QKO7|R$gMHFE4@>7iVs6yMuCMK>*Grmz$wnjU(CMLorB@>1=fB*mhd2~`vQ-1&`T0T>B2M-);&h*>wmbQnc z|NsC0|NsC0|NsC0|NsC0^Z)<n+Z|NpfA|NsC0|Npr=|NZ~|{{H{}|CIdy z|NsC0|Nr=9(EtDc|NsC0q5l@7rT_T5$p2TRL35YNvDg3o|NsC0`v3p`|NsB~>E`A_ zc{w%!0DlHfNkl??q!&faYbH&1Ewt9CnlG-=dIG3<39?aAo`;5FYDn!uxoPV3qr6n5x)XNrBLj5*884^QlHzj1>yrIwL;a4nsq*x)PK~y^kFMMk7@b zvn*~lL|(&v=<3TyEm6Hnha^a1g1Np2&3~;ZYb3;JnDNu4rR4hI~I@c#$El5OZ8UN^F#vGQQCVDc~@Guq-@_d%BYJVU- zD-h(>7|W#CuBusAH}>>+dp=wFuGU|n#P=dq?auQ2nBO)(A!_NB5zCH4?=ao|Tn4%-PmJruPd z=-<{h+*43zwKlurxGqD)`QwRiXEetcB3MuZMoA%xHL1$%9Me$9X{zXpsYGlqq=Z>= zhL)&anJJJlcwA0H1SUuI))>EUxfSn)lvsq7jp%hdNY?INYASu7eRlM#`hS?B7^^@q z85W~?G{xb#Z#hCe{sI!=y}&=4gk(? z*ZB9#a~#j}T+ekq4uIr17+N^_7zkkdNov8@%?8-izxV(;WOm4JM8$}_^SQ|+ya<(2vcl?@>PZAj0`}H8fo=mnLBv3V%b*rFEP)4U=)VOXQSh+63wh%YaX< zBia45ai!UT`F2}&yF&T6z3*Aa>hS>GvQ+47S-zlJUj&~>I)AZ_*XK7S3U5SS4%T1| zsVGv_sO@GPzbRaPM!35XSx2eJI}(<1eB$@n>xL*9;hQAAxk)%gKj5%;!Yb^xWz5nr zF8xSyUs)$R>#vfVE{wQ(U@e=P!s#B#24g8PV+uc+bvxCiZ9mRNn+=2;V`UQ0 zm5~E-1u+m*Oi#(qaX+%9O&J+861T;K*;x)L~wdLfc}pT6?BlJR6$CRg5mPk z4a7Lz`Y9nhA{{O2-+3^5B^IWC{YnX5oJ7g4X5F(#%dccK+cqJ(Ce&~KK%aa=sJ za}>UZX8!y!)`BqC#A=0PQ0l=wPlC1D_GAD2z%oZ#^yZ!Y{K(9jHg9x&UU-k^ygKUG zkddOd|B*7rh<{$okZ01IbmF^|^2j*fw~^eii1*S=*{g)~%|PtDF4dxX+_R1P+-C5? zHUI01*QkK{+gtyLEdKu}&zEoGznJH_E&bzj{DUXtdpGO0DD!?R{?ar4?vqoU=vF{0 zcvd^(!kqBHE&rJ{``A$K{w<|>K#0o!e#HOw)LOT7On+>-|NY`?kP-Ei$N0)L$$ebUtVIsYSVJ<5q zh;LZ`@G;q?G_h|AWJjacz;Uo*HQE9-Rjb_$GEDTbXQAolhwMH zzhG zL-byKfiN2+IB@1GmHL7+@#_c@9t7DdmCE8u0%fr{ji0Sw(ZAufBRp;eG8Cur#ee)_ z0)8@Itjrb`6nN{{6NDQo`C>6MnNN_+6esg5aYwvY{Rn(RuZQxB#mTk~W-tJ?(p`(Kh5`M9=Qm7B|q7-t}f-)@)56@=P*c~`*8jVR~ ziuq}2%IxAjUaZM?=fr@G2?7C)wto$v2?Q`;ip6}eZ1zI&OPh{qV}gOk<_MfvEMQ|Z zZ8n>D&I?6EoKB}>LlG7MjlGUztt?2s9dnqGF8<7~_&WP3r~DyY3ayf{NBwjV2@GG*D4f zQ*!};(`lRxjRs~Fe{#FX1EZ2V?%Wf9N^tL=Kj2d*;yZVe4@A3ZhVMT8O2NY1;=;dx zw0nz-e_Lg7?jC+?VPSDjxPP+p=UA6HLiffU=)ZRDT7Um@ps%m*^csBt-0JTqrVj)~ zxoSuFwWrrd8pazZ8pc1zX*j>e_>CJkKA#<*XlxvBXc)Qv^!Kh}1b%pZA~(0WxxFdJ z*wo(MzQ4%H{{2^A)MU(QG8vn5b8|O9&)K!%Xj5Ql4spj(X z@3`~Ta?0u_+p1Wy&S$R$xKDw0V=P`D1;c#*{^Z0rjO7+cf%9OwWo+V`e=pDTSQHeC_OOXWqJJ2dN2fk$Sz2m&U@k1r z2g=RmOD#+DONBfhONL>-?iJ*%C`w__=~OxVAYmvi&BvdrxxA1{r}IQIEYj0XvW0}o zSUgae0VtysR}|s{xtvO8a53yPvWFCbuahtl4`L7sDi2b~>1G@-&{BfL6>oP41WsCX`n(K6bCFU50LjcNHQV@?vPVRBofM44Z(vt8X`UJBR=~&9T*XV ziuZ#qqHq~RQDA@&-3=k39u+Ymoe%>YfE-$gn+gl@M(|i%%;5;x3gdLL*{Q zFs_KjVlYaYF2g(9J^%t17$Re1cW>~Hz%3+R(Ln9VsX#qi~&o09&sC*s_TP5*Y=Mfq)bYhV|kXoRUI92}q<( zzU1`?$bV~&O(`$fy8a0M{{B0Toj7sH$%zw@$9DMpuO~+6?#SZ@6AsDhUO@RI;g9>@ z+ZEuYAmXiedeqG`hFVw`JSU8*TEp2}Jw5v({JjwDdh1u8sny!X$JK^Uo={hLSle40 zHmp@YKX*97QxgB(KRB2x72ElT`J8}Nsz|JiQrfTTw%kA1o=uT zJ%6cHtA7#bvJuBGYPC~RsZ=MCAkd8T7moDwTH}|9WJn4Ml~!wd)s^Da>5D2Y{;{j@ z3!xbhgOI>6aeE_zNb)j4uTrT@9|yQ-=KD9HUh7xV%*-JP@}+Sm5gbkuPfd?l5s5A{ zQ`)7Hs7!C}aPfj41cd~-nwfcf3PG&1H-D3o5}hO^)t();BFM?xnVESKiK^+Si%R@= zZXZD;@VVQ!yFhX4Y<1EaSuXQ0rluswXp`Z6^2;CT(d`omg6Ke@1I2JyLe?6o zH=C_iWC&LbA;{<#y$1tc-c7@sCg>TixC)9<AKWkkyDkUB$CL|vl z873zvJ2NIOC>}*SDKRrODJm=Hm&bwl(kvy1|jdfNO$F{SxcSU}Hft-?wqg`KLP*PM? zSB`*!vV()8D=Uc^8fI;7szf=mF)?Bb49aqJup%O(9v#IiEWIKkz(+{HXK2ADCbT9c zv9I(M0001TbW%=J05wWra|RJ1(d_O2owttv|NsC0|9`Om|NsC0|NsB;|NsB_5&r*j z|NsC0|NpW6{{R2~|D;?0{{R2~|NsC0K>q*#|Ns8b|NsB~q5uE?tpB5e(vJMd?LWDt z{BX*=*Z=?j|NsB@|Ns2||NsB^oaW|bVhLyf00tsSL_t(|0hABJ0RusBIa<5_N~3?0 zyRo5ugMT*G7^giTsCxj2{;eD_lLU&1GAb~i=p_IfqjA=zP-<;G^f7Bqk%X7IHUu+| z&Y{*>%icSLUCwUprApv<;U)hhtc=zhM`0-ZrISfBC8-gjSdvJ=-QD+p#XZXOnyO#H zxzNv%e2`!6B%;D;L*%-pT5@C48jO~H7V`S*ntvLkimrO4UawB{dH}Gt7|DW)k@-# z9f&!P0Tp=%W8d|MN?zVv1ZAhfj_hEJF^@T|;pFLxYXu(5i(}E^Lxp zD&n`_%NH^s+>}{WED(YsNSP?@d)pG>Sr!PyuTPY%NWq_YcYc~oM2y>x$WUST%hH_J z;VvPASdm+6O;uc!OWR;@bhGFhae50^B7cR5K+uwM&XtYe?pzUYc)2YR=f7@rh4y&8 z6pWULTP#$Vh~Li3UZ9<@((LZ=cJzWO7&VpDiW`Mt=n8ACR2;{cBODQ)nB5p@(2=RK znQ+Rfeq4S;i~t1U0D?#qLMp4esaCv{k7XT~+i}c5gpQ!OKIe~spaKOM6Ekk zamgDx0h8X=h|f8I2nhTUt6QI4n8>;X1GjaJI9+FtI*<#-UyFcbR5SHMVQ>td_f;!S z_pce5{o7pOk>I##%Q|O^>$;y;h<~`KF|PYCM6dvy*vu&>p9M3k(z1}(dx&uFW^RVv zg8?Rs)=EYxVY@D;)(4b_c1Ieb2WAYB!px;m;aUs-S$OO6a{HQ*1BydO7)!8H%BoZf zr&5ykm5Se&^NdCW<7p>Jm5YWcE2k9h#8Y4Q;yOcqR04!5=fs7$q(*3GsedI5O6T=w zWXAbEU7&%Ph(%Rvg_s;O5aw!hyR3R~^%&qb4T*8Spt-74Ia)!f#@9^mE5zyj^ZE6H zr9%W;)WpEKnJ^W~`&QQz{Gapv{_lU^^TxyGaHhK8*Krt&N#5SB=N00AO6qdKO&9>+ zcqX)Sci(D(aOfS$B@q0MWPd5;+}{5^*0lRt`&F?&j?wRrC(!(6S(Z5(S;#ak{ex`F zMhFd&Wg@uO?-^iS1B@q*`O9)#&-X`85V}F&yA$6Jkr%koHl4{n*yJE`>@Oos4w3)M zCWKJRXdH&a-+sceWxCNAY?5XW!rUpm`6DnVNvS2n-@i>*1XYcBwtqQc90eTOut>t= zswt9qt}MLcV?hc(7cz>{&56GgH8deh$|y_bg;Fa>L=);*HqVX*V54#5)Obo+nIz@1 zFy9dUzg0uTvzY-l8q6GA!;Z0dVG+_;Hx;!zOTiY5liarWGQntE(q)XuIrx%W;Xw3fafSGc?E zfo=7!6cVyyjCg_8GS;c5@ZuV5?^H>F!YQM{_ouI4IW46ZjnkZi9T=xq;w8eeW3)YN zV=7@K#9j~V zC--+QXsIid5CTid)h#e~UVbnz(ssh{mfCq@@UK#GX3QW6!f+E-ai)xI8{Jj0ljGX> z|3z$nPqQ4qHJM+gM_HB^<=XD@1G}qLF?^jJrI-J6Q$LVq^H3s;$ygg*+uz;apDlY6 z#!w0KS^5tr^?zvrg9{XKjEU$Q952_`I>!gc2*w!Eg#{?m`ad-V-9RhJ6~>x~q!%{U z`oeqfOxfy4lQIB4@WM|t?4vaO%SclxwZz!GcE<6)Me1yq(!yY!_73V*6 Z;||a}PRe!nX1xFa002ovPDHLkV1n#86IuWO diff --git a/TMessagesProj/src/main/assets/emoji/0_573.png b/TMessagesProj/src/main/assets/emoji/0_573.png index 5acaf376ca5711a2a983d00cc2281385125e124d..cfcffa290d15fea66506e3edcf4e4c533f530b30 100644 GIT binary patch delta 2770 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 Y50L)y%u8UDw*UYD07*qoM6N<$g8XNXZU6uP delta 2003 zcmV;^2Q2v672pq$BYy!nP)t-sM{rDUT{c%qEm%h?VN^IpJ1DTOoQrr`GA<=2CM75( zA3QWAF)JV@Cnzp3Gb$@B9v>hgBP1sx8#FdJ7#SKH932%F77`N^5D*YLJU&H6ND>ea z4Gj(o3JL`U1sxg|UtU~DI3X$>4>T(viD)src~5|1Hasa5cz;+WzJFkFRVJTuPp^@O zn0;PcME=u!+*DdEmH`=+Lb4;mnJ1EW3Jc{P*y^ zsD@c651EC0vXw~2hiraa7saVkrnQdLn>U}$NmJ~y8wC5agtUI`1TBO=Fo ze6=GZ#AIc{CML5`L(WZ3xja0*CMKjkO-29!0BCelPE!CQOkg>72NKTm-kY}n|NsC0 z&Hw-Z|NsC0|MLI;|Lm6k|Nnmf|NpgO|Nj5~|NsC0qksJW{{R2~|Ns7p|NsB~|HJJ(zK#|`^zBY6Y}zaHYkpgUpZ zww<^R1JKnTQqD9uk%=WaV4HLK|9_kf(4*evQ@2BHOL2utg?Pg5#Gr&2(bvhwJ|hlMl4Y) z`+uIK`1&v$?FucgbS^EA!5DqW-x-7 z1Eql0*W7T%iAp^VqqUgDn}KO*%Wjf|K!2_2ILBzcQ3ydbtXJaJDItd$5?9P9rj39g zmw+_hh@y!qVnL>wSPDCxdND>1L<}TobW$QjRf`qH^6mTbX9NLa#8-D!i|wkCud$dd zEq`u=2tvcu=wFQpxtPfojDP0itfR(CXro!IhGb*AruelVn1x;I9Px}kAoLIr<+;AZnKXSD|0rD7x_P*1}aV#@L z94ZZXZAOs&)}0S?*^~ForDa*CecYlCcL>fu2L=OXtTc;BN_^Zu=7{zVQk|$^V4{|2 zFtT#3`s*?=>vL^Aa(H!|e27(e@_%ww0YME(>#T~e>(XNo5pSJJiZ`opry7SM*p=&i z7WW?I1Mxs8d6Gprc(N(s{nI7O{LctmH1qDo3IvSeS;*x)Xd=#k~=@l?}v%vD|L|{ue^l(SJQO$4qr= zqmSWAcmHp%`)^9ivQ1JD0Kj^oU#`3FU=)l+m(fMkDb{8>{{L?|oM*pIy>{@@adtv9 zbltMim#=UDzd;D`ul@`%9zYBR7yt|ba&*%;zeaIw5B|o;zas=9KR~{Ze4CIE-}(0x zL(d*+mvAEwe1Rx_0OU80S%1P9XK5Jz_(L*3hmc02iwZqLlm=)#QRCh;&ElSM@aGSt z2y5o$kW#K-l<}hyr{sZZ#;! zrksaG?FCW*Pe`Ha^JYw|Y??9zQjp26+1_qYbbdi=DeJNk^q?8Hr@=6~2mAhsrBax; z1UI_>jg*6O#XuB>YumQFwSA_8+KtW{_vZcIph4|#80?RgH-F+E2VvjF*4kvk={7|B zkN${vR`tK})t(Q%NGRijEl4&`uMSDy;1Q*O?cjUW|4{Iv-o>R}Sz)$<`EW!XY_CNpt002ovPDHLkV1g_s*_i+U diff --git a/TMessagesProj/src/main/assets/emoji/0_574.png b/TMessagesProj/src/main/assets/emoji/0_574.png index bce31f8c5f28895034a0e6ca79568ab6c2466fd2..3c856e96730f30f9a470fd0c51bc08b8ad775be4 100644 GIT binary patch literal 2640 zcmYL~c{tSDAIB##(PoHym2K=>mKjSDV$5V;Geg3Zp={aL%925nOGFc)y7!V@O^mHF zOa`H7Ffj(%#blkUF!R0i{Or=QbgZ#BYN36dZpMpE2)uQEwg=j?X%(fZy$79FWpoUK#;@KkP@RWR0Sv_9#&HSaY_js@5W zz<29uqRCjf-bB3G1kUQSlQ(M+6Qj zO8n-eDG8Sl^g5^DhSKoRlW9v+z`!KKkt#9fsxkJkcxP?Db8_T35hp{fGs?1fd(8}2 z-8?VDoXdJe*Nh6h43c~ht~%nTs?v9zV71wiFXCMvggO$i`p^ALUZ%JgWkzO4`@~zR zTfr0^VX}=VT{(#bnFuzde!Woyi zKS!8%=$V1DsWvk=^*u70(WRR<8NC-UzOTF$$5PyxRT1MmZWEI(Yw@Q|10Dv|u_N&L zrlv^xO|@}$^gLI8{+r%*l2QVN<4PD>$xzSi1JXVKdHn#8s=5KFq~?}!N;INcxq(f< zlR-cq9R_4*ai&k_CPoEE!~uW`kOK$SG&wId5x0of3ihtSfPB3RiA}mF3=VA*{HPVk z(*fGGxd5!fU(1KM3#`I(@!6VtZ;=+^WOorHc-|+eswniLI^Vn1T@Ek}>`Q#lgL|g# zZ-C>pU*QG-U({HfJtj--7fE~W*@ypYe)K;OP*<~{(W0I&=I>2tID zD;{!&1prD9(sbF0@EOR=^hm7neU~>1Wjs1IH(;G>7|0hLK4G-c zcIRumFYl`TNGQX*uk#XN;3p-1>81S-f5gcL-<}Ype|$_aRqcx{I9E7%C6IxEkLaV| zgx}xEYlVFOyTPPwGUWF8Ms<s#;s}1P7=+79uqe&nHdsp9m|T(58xwdCR-31cq?V+opLJ{k#$p$^c+au(C+NFOwbi; zo@!V+0Vjt&bE;4Dk8LGVr0+-R3ldb*rA6*|$zUXdMXGQd9Wf~%25XE$x`XUIxjJJW z^DRdGtWr#bT0l}zh4^nRmBaDC_K(`Ph5vvl12KlhHZP_hES~mG*U87PdBck}snY`? zFLwh@YOdUN*8Pp5b(DFlCX7W0PRY;z%Jq4Cs!byHap}cL5y!HBwXQ;&Q zH7r+yI}SBOHzDtq8fNKGT@CB*)h?+gSw*F`8zr9lX+gRD^q@*DF>+|lhD6hf$He5a zUFvCEw=C(XQKJN+qqME+JNv_Y&zqj@>%{o&Wh4Xb|Lu{8VauL|H^@aA>+9nB8bk*1 z&uvcCxa}1WG@4eh)xky+Vy$I9Z1QB{jg{|RIy%kdHE{8vH_Wlw>`Qd>?@7LJ$;^Zc zaTw#mlL^r$viMczNSyPu-JhKDPi9|^(EGN)*!fYA6mMD`&Bz0ImLc4NCB8ewsH!21kL>H#W-zbU8@l62)T zcy|lAAaJd+!HvO`yMR0#<0S<#6^W$H-kDD^#6*bs?O?o=72ET^-qT1Q3o&zkl_Got z`_2+~oH|wBpUI~brp|BqQE@u1-M0}QD3CngCoLz2`#?a7gME_IpvB+29F}PQ8OTBmUdA1cd0tIOzjtwd0Jzr}=~t&V|;;#Uw(&W(ytT zEQzyRZ?D9*6#nk~riDU0Rl&5`*i!OFaQ(wKIMJTNV5ryw?f0NEu~*mLJ@r4NTXE3_ z2ewcs@fNPKf-}~avh{|K2QK6M54MZR$X}a$PtqM66}od3ikd=Y954~$H~&YUk~XS$ zClK^fu>I9pZquD?KAFJYoa`v%(vzh#w~wD(rQ)L^UMRhg&azV3`<}|3f}diQlsYrk zS{;d)aPhSEg$AEV_0P%q4^@52+{YDrT}zMsm7g4NImhwz$rQW4g3Aqd+03R1wsc)G?%=#SYWDFR6?9Y>10 z@bp?~P%XAqR>eh!Ds%?1hNImK8;H`%wGdA3g6EiYXK&ReZV3r0WN%2A7h1@-|AXC8 zifU_(H_En9E)=`p?EE0ckhuI@*_8J4a%z_({6sgo`9}NuQcv(R8JbOas=j?ibB)zW znI{9Ag*CI6ywmt-$r?3)ta*>oKL5%j*C4X^C@CznIAfxC-Oa_3+*sO6cx_a+8}5(`RT+j}Ri0n) zVXpR9KGUbGS5?oY6eEIOK3huJ1DQNoPu&wb!SE^CLbju zASNRnE+-yAHzqzdC^0J^CMPH@E-@)9EFK>qA|oU+G&VUqJr@`l8XFuH6&4Z_5)Tg$ zLPbay6cGGIbh1qB6LMlDP@9VQwNH!2r!N-}$2ADoDOmVawZi+g5iSUr<RhWuanJ@Vj&%)Df;mq)drp3}KZy|=WLmWsTM zk5*S%wvmgbCx0e?78ho1ZLmc^P*75u8ym=Ydb1-U&R=1{CML0BW4$~*y(T8GJ2I|d zKAJ>%RR910VRTYXQvfPnJydiD4;;_$+rN{fwEzGA|NsC0|NsC0|Nrj)|NsC0|NsC0 z|NsC0|Nj5~|NsAw@c;k*|NsBE|NsC0|D@G&|MUOSoPYby=S};l%%T7P|NsC0+5i0i z|NsB(=H})l((SeY00rquL_t(|0hA9z0s=sAZ47Jw|Iu_$W5av~>zohKr);zN53(&U z6>Dp~wK2z-#T0MTuM>(}GeqY$AQ1})3(;P+_2qvXQf6amKqRDy2!MJ)=7&;f^Ou+W z;OjZ()qkP{2qHv}kN~M7?2zt+l;LvoDhxy?P2JqIO@b|KBuIewf69Br*WX0Vka#*; z7VW`r2YB@^O=c<*qa;ZwYBr4VHtn2YS_F%WUjmzy7 znc;>F`ps%}h1LstD;}Q5X1{YA=PQn53?WF$g@39TXsuUVY@CCSzB$R~ch*FPOe53H zU#+$E){J(6;Qise_9W>p?N+WRJ`Aep~?|B^63(C19FzQUT7@GXY1cLi`>Jh#~>&JS29w9^S(?#CCx)pgU>w&TFbGL!g7y-+k8pBNgy(CQr&{k$W^Bs z3(*0UX(9_`73SEoGcD>wjY%?ujY9+?UFCk6&ElF{HMM3+MFbeGss#BP1$gfIm`R*( zi7{mOO3Amkkq71H5(>7${0)9t9>3q_K;}j?gH5Bq_SRcgPPc8Z-(|+d*MI4>{7-3F zpg9hL0W@Q2*WDEfOMn3Bk`m9fjQiaGGV}NA0h+wH@Nhwxe5dsL9|HXOO}>+_WCMjA zQ$p#>`E18J=P1GC4`sWK(TJR!Nai}z0g#K0qU-=|P90M<H{BR-o)<2aCmV|MG%oa;?;jAhP+^JpyVQ$<~AATQ;X&S>l9#pQgoVt!?@ zY+6TlRmB;?j5jdP59Xv$jRcLSqiJbQJb2C>h*Tu0e231OjT>6k;59? z{XxTrHBPKErlrApdxM*bKt;h+aF+13)!*H__z0*g0@Ys;F%=a`sGuzcS3@I=7Jn5& zq{1~Y9fTJ1>ndjET39XoU#oYPe?p;)viP`_eH7yvZ8Ih)>ejNC00000NkvXXu0mjf D)n~*2 diff --git a/TMessagesProj/src/main/assets/emoji/0_575.png b/TMessagesProj/src/main/assets/emoji/0_575.png index db4d5b9c140aee2770b7dfb8c70dee0c26d9b625..5ca705531f20c97b4899905a7fcb823cf6657e94 100644 GIT binary patch delta 2400 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_576.png b/TMessagesProj/src/main/assets/emoji/0_576.png index b61f2192428531e34f816aa7288dbb0b21face9e..5a44c36ac6388d0b5a98f4718266a366b3cea1d1 100644 GIT binary patch delta 2539 zcmVnTf zURG1vq$TOD8t}CrYC@eHr}9p{`@l7gfUxacb~lB-tS`S>ww>`GO%zH+n|kT zwf~WOam$%C{Q1Lic7M~jbH$~xVj73;4WY_|OWlQsP4i1U9cnP3s+d^qd2D7t+Sl+gcDq4Dt0RaQSI zfKw^|$SHwK2-v1Ia5@En#{d7AHqew7|MQ*XwJPrZEr0*fK-;V*j#Ufq#5?}fMI;gg zWuVso>s|l`dq4#ms5}pa1{>Ms!k6QvmNHOdB&|5(fTu{r&Bu{_g$u`RTa%x@|Vi z@|MCn{QdmW_;1qt`{eqW!TbA&&*)Wo;H&QK<9|*2)tlOf?XT&=kgC}JoZ-E!000Lp zNkl)N=hak~y4~*5(#jIf9}w_4w`)q>?d|Ow z=zrs`E-B1Arr}gc_1NU3+iW(w(_fQ#X=P#laSXglbGv(T3@iZrm*P15P?LKgd|q{X zyLk-9@v#h2gH$?cZZ}^(m8+t#6bzHN6h`8BDGob&sR2ih${Zb>>UKyTPHiw63{n8? z=%r(*G<7-EBk!`=4C&(ry!yf=ef4mL;%BzR#C ziU)mNeMX}Z#@jR*hg={~3T)s226HIJ{Zf-krBvEroJ}JTXaIpm05)*+_4OHksDD4o zaPL-2hiG`%CQmE=57@wAGnrny|HfrEaGS%5?%43K9G$;cqv^GcZ)a{2J^@Yg`sn5yTuA{F+`6yoNuZ*AMv!=9oE!Vy=dLdT~IZAjmn5#_#XYbRW{8>F|SO zj_@lKn#=48UT?QW;rGMY0kCCQQ-44UMdR;&(WZI8s>m-1hu?(%l_C7*D-M3shg-re zJU&Y$>UKBU@xj5tF92>F{LdkSgT^li=$hQvX#PijRzqcJ%T^+h*xLFPc#XD0poM^5 z=x(X5$rcAM5m=w__IQgXyvbxT9`9K{U?QGG^mx7A9@HK9Yql`*ekv-0V}B+l)|0cz zI1G4kh&SF7hu^>uPsY7P>$TZ0=}$%L6YJySmO#MLMi-<>q(238n`JyOeh}qNmTQuC zb39<7?FClL+qZA`Is|A+qN(mzK-+?0blZ4fqUaLaRppnoS?pH7P%$(0Ir4c&V6vH% zu*tWkrXu?@dk&%1Zn0eBuz$|1IXi77neOJPshR%SnHH6)3o!N0>~BZNrezWGbRItmBy^>Z^c3fZC4YF z3=AR&0#1+XMWZU%2Y&}BgjU*mhy9V0S74_dWJUoHj7r}%O2*QP7*b%g*y+p3RWm8k|e*1W$*BGJ9!QBX)wB{;b*Ig&G$#pm-ymz<$Zh24(wu-o@GLjz^+eSf}RSAV$2KOzF|&y}mIpztgd z&pSf{Gdqdy?!?Z_Kxlq5;_>)2tE=BXtY^1PPgLm`A%mIgZp^FcKKzM%D>!(LJpg^H1JKn&v4)#x;({g75@ zwNEc*$%KDnX+f)<2F1`jigHC7Q(_<}M$BJdXn&=sks+NC@8KBA%!cg_;xXFRFosd2Xr7r-5R~_Jfxzm0ThQl%f(IQPqHb# zJ9+Ztl|KO|frjFWKOb=E?X4tgG4Z~Cg9{{vDQS(ZKmWLW?J002ovPDHLkV1mAq BDyjeg delta 1944 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 N002ovPDHLkV1mo7t26)r diff --git a/TMessagesProj/src/main/assets/emoji/0_578.png b/TMessagesProj/src/main/assets/emoji/0_578.png index 94c0e461ac58925123820892d48389ed2b8f3b48..1f223161bbf4d0c0c2972ded60f0315f902bd617 100644 GIT binary patch literal 2626 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 delta 1938 zcmV;D2W|Mm6rT@}BYy!SP)t-sM{rC_Nk%_EKRGxzZ)8}7fqWw)BP%N_A0HnlCnqK* zCNnZJFflPOFfbnhOa7Y1h?mgzLL07tqt;-w zlL+08os7kwV;dhcG-nPW(+A}p(b`!HUF^ZwZGRpkJ|9r!9BJc{S5`Y)Ll6!!_HF(g zB5se0@F7A(2eej8W2)M9YU^s#5l>wSnoqpnY} z1OxRvjVeith$|aS_-h&tq|rECm??d*iB210w3XO}EzzFoIt_c_XN4*yVp<9;LIzcL zTYnCYgX2~_hlu-JQHZcWz^?%-$YeNK5qTRUJ|1j=quX#-i}OJdgn%V*JJUao=dEX< z6=fA5B0>gR5PhJPaQCbXB-pcH4(SL#l6OA&Kx*AiyjgQ&%Kg8J)FmngRM!iU1 zT(=?Ozkei}(waj>J44;L`Fg#^hrP7YPiJFFd0!~@xG{ys=8Nk(-h0}j4FTayc}qE| z9!V>{?0YPY_086z3l_C~s`L>gFdkA)-H%|rMkYR{6%2xc>X0R&37eT^9p>WMO2{i5aLO+)1u@brE-CSD9&WAmN<~P4egi&J6|rDs z-eh}x3<#fVrHu;$RxwrH@ypGGh{TJPk&9`%wStS$0x%{KJaCF6-aB1}LlN`DU)a^5PnCM2ZHk#4e1qj1jUY*6s3N`N^HnM(er z6+00+My&Y$rzkdIr96!A^2ZQ;&H2?nn>*tRjt(X^B z{)_VRT2mB;0F|FiJqbsz&VMQ1ypG~{ z90bXD5`2Q55(VRb;g`vH9HIpO{xL-$N$<|20~CY%jL_gWVkzf5z$s1R7F}A2{=IMHV)dYGJ zB9zNsVPv6oAs-Z3$GzWNxgywl6beWQIAjLM-e8^hfOprf1zzkr=6_51?2uN2Arp+b zyQ`NY+nOU*KR6%&-5aFyVt=?c2yo;%RvkE`EP#Gr=kI7eA6(CtbqY^AaFCut?rX>U zWZdLXpRs^Iq$IK+9ra3$AQ?9~1a&F|3D7W+Bz_0UxX}TbG4;w%mBZe#e0M*%nJ9Nn z*G&`VX63#+-frj}Wqm`eX4ZGM zmzH;+RB6@`N;&Y|{~WB#a&vPW@V*OCY|WPTcE+o7WqO|mK7TitWA2|lc)95uUzbXu z)>JeL%Ig9k>|7k`_?txZ3`G?i(+o_=7n4~^~s YC0-HQXv1z)01E&B07*qoM6N<$g3-jNH~;_u diff --git a/TMessagesProj/src/main/assets/emoji/0_579.png b/TMessagesProj/src/main/assets/emoji/0_579.png index acf9ab7b9e0d202f66fef85052a98fb0bb0222ac..f7d0680144b2084e1c2547723631233a71b2b3bc 100644 GIT binary patch delta 2462 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 LNkvXXu0mjf<5<&q diff --git a/TMessagesProj/src/main/assets/emoji/0_58.png b/TMessagesProj/src/main/assets/emoji/0_58.png index 960a9cbd48c8c26f0a386cc8e77b7dc71a012a03..7a9b4418a24da1e2886e4e2a186ed3db2bc11664 100644 GIT binary patch delta 1860 zcmV-K2fO&F57Q2iB!6X4OjJcja7-DB@WX5mDTUkAh#Mk~nGo zg9zP=4gR(u{Ju2y);!(KQ=4E5fJzDGzC)5$2J*o>Yc&MxuPf=&N56_J@6andid7e{=cSM zsjG>z!1#WViIk+xgm65HqQGxpJeHmWgwyVzO8{QhE=z(>>U zNtU!})x|Nz%>V!ee@R3^RCr#rk=b&bFc3vesVE+(c|c6fI4=8p*!OkTeP6sg-=A(V zGT;f0om39eOVjtz5?B9>boKv{kiQPgswlP?qNvK>_DHJO6-J}{%xENZMfE!tS?ogm zR0A|!QGfojKw$ZCYy~|hiXtbl;xV%bUy?{D!2Epjv%+i78W)m39;ee{0zZ1KF~L2L zQPS;vZct$a6ii_L3BU~#R)~Tz4x&n*AL4Y1dy(Tf5oXRrh{LdQkcd*VfsNqw5DY{d z6r9U!ke1YJ$j8APDJ%$td3;_F=Zy|DWC2puz<(<90m2+&(@kc6;QKzepaw*99!Gp2 zi1AJ@4ILunndMtP!ZjemRmKtMiF1Km{9CCdkjz3n&DC{R16Kf|GCU~io`qyYxVR3L z5E7%n4euE`g#5t(H(S12)I+dCTSiE`Zji4D$vn@~P!NW?9@4=FG##oTlX#vL6LKxr z6n|~ow!wg3(y5tXBuNHIDM*T%sp(+Rq1CoYyFP?%Ys{c)kgTvguM$(|4j7|8gz0Jb zA%zyk(p*+ZU_*(KByd{lnVM}^#*pq@S2InGt`nZG^9GwqaDkjs=yqLN{*(@-w7*`j zmuuh+pGKg8H$v#PJO?T`yZ(;zvU`CA4}YhR`yEQ#s}sV2}{$odev<0p|7 zW${?y;ql?Oz>69SMdAPChoUIyjB}VBK4tb!swn(2ZimA(HPV@37zfztxB!7wm zFtRKMEDN*AqSaCy2gdrRjHdo)1KvioMF)zN(JLV{&I#R^DeJiGSneSY6&*xl~vdqM$w4iT(K}!e8aNlpD@&a}-e& zRpokjpAyR#aolX#kQ48+M7mbHHh9Bybt7yLLn$*w zEOr+m#ObhZ8z(GZcAg?KDTg312*)7ee9ppf`vY0;ic@iTLe}(yhkAY3oPUb7M?1nW z%g$#ajE;)qFUP}|a|YuF#XB4h9)u>Ocu!bnVH<8iJQLw)!VQ>s1wqCF@jUP8PNCly z9{$25!tC|@G8``hR}(#JIi9{ePiljNmH~jm!ioENe6wnUi$r47B1HK~z*)KgT5-C*GN{Na{f~;`Tku+}7|=r3X#@IJmN(-(!fBRi zPD#@emx2aEJsQR0JJbL8=!6Ys~SOV6vqS438I0v&^C;& zD#8dD9U6cEs(^E_A^d9`iw#1cG#L`0D_G8df2#R5P(@gQQ)j9HKj^!iFJe*=Agt6G zBP#|h!|Z&Wo?!)OvSdaFM}QFm%kF95Yoy delta 1946 zcmV;L2W9xv4yX^1B!3rBOjJcja7@Z?4%T}U)P5Pehe5}CCC+*r@SYK{drR$v1MQd| z$Y%xYj1b0X2g_~?$!`rXzx)@K*(jmYV9dp5%Dn)0yP=g^|H?Q1uM_{nIQys({OueGU;gTG|JhUj;4lC9l_0bIaXJMx!~T6l z1^@1a;QjyWmkqP;|GbZL_t(|UcH!ya^uJmhRsZg)fBe@(as7{pGXAb07zzhY zK^#{g918w&eApkai#J~#GGaY`8vYeaC=i!8#(R|{j9(rq38Fr<*WO`9Vp}m z-F6=mF>?Adl3;)dvfbS0KRtXdOxsKn_+dFAlyLL4J-GY)o?Pea4ay0Be-6WQq+mgC z2R^@g?teJc<@H+HM{Wsz~2691EW6Je+gS>A~SUW(aHYO?m*FfsW;E^nidv z)&fUn^F+R>PN&ns;A+4{dzUvHU=SQ9;dhOQqkoL<6kGv!G}jDVu81j-5w-YXI|3-9 zH|=(z*n@mr@Nb7{eu`loMb`X>WoV+%CGy>TKL51rUcIBce9D6^qbF)7p@Z3wm0qXQ zVUqlIG$K*{YJU*j(PYaF7}(3mn(rV9S%LzT%bn$@vCF@soL@FZOZuGX2?uEeG)?S* zPJidJw^JL9Wxjlb{JPOl&CVqRAftJ^5sYhcrbk%jdW2_{%a=I3@c+|?Yt!lxDcL(I zVX8xrOnak4VC>457nkqB&GOQKMBmsZhNF_Or_#JvbguO-C9Blic)Cb3MeuuA#GVn9DPVY`+#gaOCMM?$Vv;Tlp?=2BXBY& zMXOb ze1JlR0*)%L#iY4cJ&vl18xu3RH@s66nPRtdDnWo@Od9s9!fs3q15#cF&qDSn&Pv6I ztSGy0-?$@b;vG}wx_^o{%5)Sd%!eXJiX~U!D;3cU@n!M+;wTV+2%UoY zrNap+6aq~sO{quEJ){0`uozws+ zTqzYb`{8;vyMKPzwJ;{R z)eYTPTQE3>wZ;v7n}$G=97SZ_thg_DCqzXEEnns2v35IKt!B4KLlQV| z6hc~HNGXXKD2ZkT-P|{0^M6oVkYZ6o8q!`Oc;kTtco{Oy$9Z_K2qqqDV;HCsN&^T- zkh}&;0(I;Oe5zeTv7kymnG)kjJOr+RlBjsU5k6=2`%vYjNJU?H9=jUPVlYasSlb9-7@C`fV zrr_idK^bq8i2k!SyuD`J)@q+<6(oy2!S|AZ6~Cb>lmQn|4pas@aiAFA65}B$M1>@k z(a6wsRo8W+q1Q>^F_dUJyg)G=gCPvHFLe14AnLXd#z6z8-EeVd&BwRuWKJElnJ0%YW2D-ZW^kcYGsI4%e0MAgamtoFM6Pe zA`K3bz%mGjZMQO_i_$XJbCCqxP&s?Q9|-<7<|&N7Y%0w;99SD=S(I7!bSg3zupG#6 z%)xlsoMQo+M<78ebr~mJb)ErIU{%0yjE}$n@yGA~j-8*MSAUwtIV7;`iEsf@z+7N6 z@jb!`C`!#{5f*41csx%b5&q%E${&M+B(S&?c|7_U!(QaagnT3+3p|V_i$?}AU+5=y z*dafa0}VmJ^!)Sl#LsRrqkOCDOT?hzAUu}v@vUz37dPC#vk&0RM;q>63ik|-a-4gA ghv@(5FBty;P!mT59;q9f{Qv*}07*qoM6N<$g5%z?Z2$lO diff --git a/TMessagesProj/src/main/assets/emoji/0_580.png b/TMessagesProj/src/main/assets/emoji/0_580.png index 91b648c6bdf8d9e93d0dea6e5a3a42eb3f102896..171464158e7bf4ef03737b3a79a2d7f59db19c34 100644 GIT binary patch delta 2442 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 V0%(lu5nTWP002ovPDHLkV1g)~jXeMW diff --git a/TMessagesProj/src/main/assets/emoji/0_581.png b/TMessagesProj/src/main/assets/emoji/0_581.png index 447dffd80415952c82ce4961801febd85ff3664d..e63a7d04c7e0e876a61236da5ee07f9d01562060 100644 GIT binary patch delta 2265 zcmV;~2qyQ+4&)J#BYy$uP)t-sM{rEboJ`N3G|{6v*sVj|wocWcVbP&9gKKc%xLWMc zZ}QxM{_Bh7$!Pi7W&iY_{NZ%|=Yan3mi*so_S9P8y>0v3SoYFR$F6Yb!9(@ULi5Nw z{_Ab<#5L~8OZw+v{M10}yDjImMex8a+tr%-$Sd*fm&L}$#DCP?`0%>pz*gwCE8w#& z#hDk{tSQT%BkAm!-M~EQ-B+}ulmGL5|LsrYvq9poILx3puWu1*MGQzU3q2$TRyY&U zkT$Y%6N**~2L%Na3<)S36e1T8z=R?l5eqLN88#*#Ju4-HRS{xTO><*fTuVelFe*?x zGgCe_N;WSf7k>^P6b)8FIHR1Df^}>>=e%c z%_SNXB^eMR77z3F_gF(YdqoG`+t?o!4|qxew3=#iJ`W@s6(1B1+n|llk8xFHc4e8( zWTD+YQDvKMP1@ao-iTh~eLY@{xmTp|MtiU&A|^?R$$zh9D(j9u+xKPde=S68lX9@@ zLqS5;doJVoM1I2kF*!p#U4BxP*Y5o-`+_Hk$^UA%{&Kwjkk0@Ai7fr7E|<~&{@g77 z|0t1radCEk|By0xoWlR`G5@WNd~+7{r~Cz|NsC0|NqVZ{}$N)|NsC0|NsC0|6>2sB~ADK|NsC0 z|APPjL;wH(|NsC0|NsB%&j0`a|NoZ%|NsB9{{R2~|NsB!o&W#;|Nm3}|NsC0|Nqey zZU6uO|1AIi|GtQa-sax={^+#(|NsB}|NQ^|_J9BX|NQ*_|NsB`|NsC0|NsC0|NsB5 zkpFT2{K}yJ|Nrmq?zqT9d;kCj2T4RhRCocL&$R)=Knw-YV+K*2{URN|Nm^4%sruAU^KKJW7>PuO!I`Z9r%)1y6wxf`0@tIMCet64&G`V-bXg0!X|imz)@bI(aCg z$n%_#yp%#oDd+fT&9#67WF?yM*vc0R&V|%aX!QbYa6rzMtN#q^&DJayLd4KQy#X5> zBF}C6KgV=Ac7Cx~K%kT~MpD_Ljfr7%mVx&vcZIcL*jDFcL5l2fPp0 zZL?8-qLe(=+tz_7tb0=*!B3E~%74~$CxBo;6@Z}FWvchc@4wBUC|((#{JXOKI&(O0 z6>%L!H@A1Ui2Hqi=Jw7V+e%5mMG` zO@ZG{=9`UGbTz$&yX~$>i~{67kYXih3{tl1iW71;?nYKI+SPZQ+(x@rqaqerK+$W! zC@@9$=MY`*yrP=#X4|J<&wuL<2f;~CUjvGL1{}LkWm`;+UF*Bp47+xM$90M+7^UN0 zfaQWxqtI$F7!Go4K&I2tU^K$BIsr=Asu$wK7$jOv^C_~aHu?Dn5A)P07-RdOV#OFm zMVfCcslqaHL)o#&81U6*0TV9Jn!)~L{o7|3p2TkuX z#Xj>6v!5IMnNGdo1%I2kj1>suQ0WWkTvfWTz&ukV?j9caB})vd08~J4Z~4<%)5=50%OQ| z%)HZh^Cu|TtySa9B*j)5P)I3!(#hdL>D~VHi{8u0`CM)j_kVkGlT*_(yzuB5)01bZ z9tr&P?5@JG4H7QRi6ZzkFUbP{BPc2_Xu5d#)<&LEnEQ1H0E06v$yA;_>LCI*;nI|N+l?aKfQD@$ zuP8~Os)mvjqkqKYFf=kzug!bviYpMNzCxsNz`>Asb;rM(!P|^HEDJhK*tz-XBGgLWBNQUi|DW&=cx!4E9 zlEAS}iBe4(lu$#EW^(^WNGgk+H2aH`3yK4UzD6mV3=v`e|9?oRzFt~dYA!P^G0h76 nN?)>lk2OyAC(iWBSf0NDtFEvoMOCII00000NkvXXu0mjfYY2=s delta 1852 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 FV1l>pcP9V< diff --git a/TMessagesProj/src/main/assets/emoji/0_583.png b/TMessagesProj/src/main/assets/emoji/0_583.png index 48d1e1df617edef7859846125a8c260c82716801..294034e6798a5679bc6718c145356b5c1d099619 100644 GIT binary patch delta 2149 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 IM6N<$f}Sk(%>V!Z diff --git a/TMessagesProj/src/main/assets/emoji/0_584.png b/TMessagesProj/src/main/assets/emoji/0_584.png index 5b947e6f033f3718322f965d7d83674b57c3919a..6dbb68fcfffcec3d706223ca23eca2fa57ec60d6 100644 GIT binary patch delta 1916 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 D4WiA@ diff --git a/TMessagesProj/src/main/assets/emoji/0_585.png b/TMessagesProj/src/main/assets/emoji/0_585.png index ce7c7bd28acf051d40340c48db4579a2a0469c53..f772b023e2e6bf17b033d8c36b637e93e0bd17c7 100644 GIT binary patch delta 1895 zcmV-t2blPR6!s2~B!3Q2OjJcja7<`eHCIS3P(vz6J12W=Se~Pfd}&E3B_1p;Fd-it zE+`*DHzt5^O*%9vC@Cs2Gc_F^A0s6uAR!_+J3Sg28y6QC6crW`5)wf~M-C4U3kwVe z1_vM)4LB?sUO^^KHXJY^4;2apNjxoVO)-06BZzJ>f>}XbSbtN8d1jYoN~L#LZDCQI zfjnnvX|kM=oREREe_(-TMuSy9tdd99#jE1l(ZG;tyNF|LQXQUrBgm{}lU_^AqJY1n zOU9OM+sAN_Z6dLmK=R>;%D7_Hw0O|d)xWT;oP>p&j)qrKQ=o%^q%16^L^^^R8&Mh; zV+;(&dwj4XBY&M79K~K=za}NUMMl45WxXgSut_&;fTh|1003HaQchCs*P|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsAy|NsB~|7^_u|NsC0|Ns53 z|NsB~)SUm%|5B-K%h><_|NsC0{r~^}|NEov?zpkk27dqm1-(f`K~#7Fl$FtT^C%32 ze>-k$Y&TdUk`(an`#+ZqrX5UKyXoWbS5a z{#T|2gwOlRx{PhCCzX_PE}~+tRx8SDyQ`Tbc=)`t9%CC{o54Rrq+Y#3?(M#tTS;#) z-j{4+#JrnG^pMG;8cTzTc3a8U=kvLM+2-L@EPs3T@IghqcD2?V3>Qux2u9Mfjw8{6 zK_uqEKy}5rRxyy@Krofp_Yh$X4DEzKSiNsy*vh$(N=~_mo$Ih6@Z7o!QFFkw-i;&} z?{~VGNJwA9u0HgxaiJw3?j}rNfv1$-5X`6@>u|!h=B_FPh?ok8)RhRyO3~BAGDgh1 z1Al>9*igmBJ?<7mmKj3A%Q-|Wt*6li-rcO#sfQVM z4Mw3+w4ld*1JZ@9MHQFsg9)a3Zbz|z79e^(RB^QEOw?gB#SyK2t>Z!Mh^`h#mzY^q z5U?uo^|`j`w}`tVJW9{gtl6x*=qkRB z_~06po>HhUu9C9ct&i(_86h5W2LXQuVT*H6)k@CR%9RqA*Kkme76h-R4up3vAb(f{ zjLC>0+J>*zE1cJ$xOprV2+^1?E~S7`X#X0Rm|rz)bcjX0hyYbM3lJO>79Y8Iu1nlw zZ>d@Y8)ZeP5bYL8Z!a;tZ{Tc7)X^L{KN#B-XK|0tjDJx5h2fa6Rv_ipc9j`T!^$zlUB zL8rg}8!gH1ziD54JD;CWUgqklFc&^GVHP>uDS4tA1)HOQftmMW3+$=Gp>bJIu zUNV*!%Ns6)F{(m`%xd1qg10T9r0JaZ-r5dmF1sc4VJOuVI%uT~5V`KwA-3ImGh*Gf zA+(+AF>cCwh7PKfkaDnN+kd7B&W)pU>#l2CuNx>#xysN%vlW-ZIP2Y*25hCHv(`;P zsQL;W;}xW0@BbD2E%9DQ(f3t`j&j{&kk)T9Y^inWHzRB*KNPpG(Q&Ti5QMfV!&wDT zZvMz?8BBABj+9lC#Ae)Nj9y!}jnI9#e|U|K^}1<_5Ffo)91^9yb${lqoUYLEswRd) zM6ZG5IRWh+rzqlGhK@J8HsM_g8Jt#1k3O0{gw<7*e z6Z~nU9FQXjqA*;DjeoU`QBQ0X({}gn-2Wi4{S}^3`sZe0gwXlk2!z94uQwcmF@`rN zg0ufzv$~7Y+=x)dJKN(F1R+RA9l;nG|xL5lzY002ovPDHLkV1lWgrU3u| delta 2552 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_587.png b/TMessagesProj/src/main/assets/emoji/0_587.png index f1e57fa030b75983810d59cddb9dd142fac22a6f..f06dd93352d642d3a6bc2cb7ab59e2747bce3f83 100644 GIT binary patch delta 1944 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_588.png b/TMessagesProj/src/main/assets/emoji/0_588.png index 61c9dc35c97857688d1f33bd076fc9fef9ed0bfb..4e71634a45b502b8257f2e2c550f7adee35f1df1 100644 GIT binary patch delta 2166 zcmV-+2#NQh5rYwsB!6pAOjJcja7<`eGD$xwSxYTwR4za^B(boUb6`AgUO7`lC@Uu) zD=H}_BON3nAU!lAFDV{LK`%QsDJCZp^`1q1~+Dt{Fo6A6uIBZXKHWH<;c z9}OxM1V}d{{{R2~l>Gny z|NsC0|M+Fl|NsC0|NsA?{}!aB|M2|rk-M7DkoNia*S7R;P**Ry7n-?d7$84^*-+xHjPU5|KH8aX$5N7KrD0hZ4)9&!& z0x!lHRv&^2iI6AnMPpQe=4F}9Wiuumc9ZGfqL5My0r#A6W&9uz9_wtv`*@7w?L(Zy z8Z`J2Lo6kuYRxftw|0h&(|C;SC3;~trq7X4K%`b{OF`_i&hxtH4@!2|=si3%tf`a) zM1N_eq9O>7$75Mm_qH9bV*goE^vonc77@zxsYY3h6$;)uBR<^@Lqo8-5|l{2j~xLdQwhQN2osBuHX{xxNR@t$!$MB*bZ$@zbTH!!#;W?b~6Hw zZL*FL+fRfs#Ll45Gj1$$Mp2M%3mW6t$Zd$&w{ApD9@P^m42CmAuHQ(2*6Vq=i}%_} z>v>MGCo3s+hB0g$$3Ps#Uobj@1|;v3Se3A3RMdc281As9HlpnBEE2$t*pfv>!V1 z2@S||OCB?j3K2M-nK22oF?L=Y-H!vr?viRjq-#JUv5<$w{SCCQRm{se`)PnUZf_qw z)1_sPA&5fPL`n)>UPK5d#DByA0*v!C{r!iwmTHT+fzbZ>6xy@a8Wrl?-_Of_gg9(Y z|508a3yQ)30EXGdc-y|`?Hh~`B?L4On!zOr7Boz+@Bb2$(YxhS%IT-KJ{&j>0M2jM z`1i|m9MAJy&viWyAmD<*uy=OgJ*PkN-9G@sfDk9d2#%l+M}$NmfPXMRu0I-EhfHXU z9Doys$RChqG|Td=2*cAg9&@F zTuFr6DqL?=Rp?rn#B9AT(@Of1b=l-_;+)FJmAYtI(wdbJLev*+%F;H60I6(oX&p4D zaf4Z|>x+xptbs8%ZkT+q=WtVc0_-0KO~e zOkCvowvn;WkIk#^Q9k$}!ufVJG+i#2CSe*1e?!fsb(}X1lX168 z+5NO}rP+b`c3XD4LixD8?^(y{@c`YjROoD3zMxuP1fNJcv44)&=Qkw^Z$w@W)?f{( zC{op^?PeUmDO`R=xVsTqN2$m=5|(m&;`iC>hA0`~neRRGzn{vG=S(;+# zn%bZ%_nP4V*Fgx6c9Ema>+?;=?uQ6DE^rL(z5x$3t9N;cP?V~G!^>^%(@n?7@)S`{*Mk7bdaM|K}wK<;qulE z#5mphDIq%|9WCnLc`$n=7N&pwN(rJULZyNXCiR+sx*^AL92WRF0bZJV-=8L_j)GOhsH+P-0zFR#Hn$NI^qEL1Z?3JC-R1R4+vA{Gxn zE+E#h|NsC0 z|NsBC|NsBkW&i2^|NsC0%#{EC|NsC0|NsC0|NsC0|9}4f|Ns5}|Ni~||NsC0|NsC0 z|NsB~|J2CL}3F+@70oRE1sSxCNY({^2JtdJxER%>gO=##0$piJ9+cWt8; z7*c>>Of+Uwhv;?FeV+-3L}OqO*Dt0KwKMIRkOBx}8Zai0k@OaZxFMRhMMF#*BX#;f z7<)@7IZPowfxtFz2^b2d`kEjtew2nTKxm*pd4D+tUWrKGH&N2#qHzc!4?BW=f=S-D zk&av{{Dd*FOhTlH20R8raQ1dnY9FXj7T>O%K;b~(6M_cM-?mZuz^MepDg{FPhQtuY zLkOb}`QmjG^8yK+UIe+0TWo5Aff}sHu;JV{6c<&bo&+U4> z!G8?t)#^XW#qOvF0u9Jf@ZOK`YuCSb1u7 z+iqF4yuFfwsfbVxVT{qEu=1;OcB>V)ZD)D4OzxYkEAEuG4vHic1R!wmbKp_}6WSP8 zl()bUS!M;3%9#C`IBY2;@g|;8IJ8>ws(*fU$QLOT7pSuuVjxY^{xMn>%B{md6rF~- z%-pW~Mz|Z5!whAH|NoIE*_m?d91Vo_%tmxQ!tQWezHPgSh8&Sek24`eu(qRZ75CS7 z$7A*z?iHrOPT39@(mJFRpOFp#=_PWZXG8!-bPpt!h}ATt`cdU&KakC8~j&h*6J3Ioc(+6kU2UMg2i z)koL%D|NvdWi%RaIZT156U`R46WH$5$TygkW{FD%-QKZLNYf!{N{DK$*B6Z8pffB5 zidOH8F?L?>bxMeo4!L||h*W9yE`QqR16L6!`n{9(`FZ!GxoH&YTv#F_YE!KZ`}KZv zcx>mQ;{M17=%-R7JHGm0WWYG+WAb6%LqXCl%3^z^@9 zF5!vg#BQ8%>rmt*8f*)o%zvAK@5~iaslBV~>zmuX^pBlvY|VO%F~1KowltUuLs|*$ zlT6NB-8t?b9+!V`yf>a?$#H;Abcv)>BNb{E8B+Hc=iAPgg!jFtUPZ^?_+bktIvhgv&(K9#%Bq6 zx~Y{hCa6``)*y8em93!SsJq1_cOj#6UzqPzJ(`V7T;tOtXvAR=aa|X@T@HQbE~*LFNXMGlF{$5ds1e zsPMiMj@#!)%ez*OVFYWV#{M!erAZ<=0bx!EW>(+de}9ihc{|n!2&YWNh)YNk4+s8xtTqmdn3xSTI;rxr;I|_zjfKWpy8{D z@70oOVpn=-L4T2NBEg~|NsC0|Ns9${{R2~|NhYb|Ns7>|NsB2|D%G^j{L~&Ke?s+ zaLT;b|NsC0|Nr;@|NQ^||Nr=$=H_K$31|QS1|msBK~#7Fln=uJ13_>(TD$*BqkodS zv7vs0Hh)?van`0#YHdCAF>6hcgqOKC1T&A$ zq1IW;-aCX{&Tj3cO5k|mCI2L>jMf`RVJQ5ilSwlrsS%=Bl1Rbb-S>aRJ<9Z&s$apm z(9e;4kYDa3qQYrIG?wLAWMcOwuU`|l&Bk2$U6?eTa3vHf{jw&MKO-J}#E{T4Cj@BtN4 z8-EaJMr-HG(h{FI+Z6wg8--!$3Tv%Y9LJa=91)(F-56=mk*Tto zaLTEETz*8100iOyf=CoXDyzDwR=kvtWgVB>am+x3j-a_d=Z}D(0u^<8Y}eC|2!A*# z5XTeYswQSZ(882s`kmL;Eb{Q5fjK<=2wFznq#tvgn6 z$s0NWlit>d&pChy2>cPNTc2H+$hrjsw{?v;U1yIvkPF6Ni-2TQGxbAZa15UJRVz;S zuNj&B+g#z1;J9haI%kXPx}R5wxPPcIuKO@VumGIc%qb_I1v9JCvXIw%h;Z*_Zid~1 z0Va#qN=7MRyDq2J2b70)M;f9BW(<+S%%xD_S_}VKcjOR!SPs#FT6 zQj+$Sir<&>j79|GX(vgQi-svHrxfnQQ(yPuIzxU`0)#5(#D%z|MrdcLC4US`=k;e~ z#`!*7pn;i)MOABsm>e?@=4y1ita@?v7~nPyiE+N5xvEq-T0yDC*G%s##OeL>`SpUO zLj+sY#K5_kFcr%CR@W2!pY#3x?|3`trn=zQaTtq9-rla~72T7mlT9%>M6!KA@CWxV!9u zZS}4c60&2Ac!Ab3)~ToP;u>u4R7rutDWk#nr>|c*Eu|NY)0~4H7^hd_CBm{}v^{KN zDq$tWUJvZ#K@GXcvApQIZrar7V|~*HJ9=;?FTz?>L!nUBD1W8T=dOCETuK?DrtxJb z_jfL6sVkHa0!zu&EiiUoelRf7cEazL+IeE|uTpYm%peHDa1&N>ri^VH-Bq!Z&+V1iLyQ@_(e4QPom;ZB9KaghgP$G=USQ}m2-`(GzEqfEj zPzm!{`VS}dX@3EO3lwpTiRc>~FW1*P#|Os<#u(9s1t`+`KQ#s2Kr6`=#+rzv7dF=V z#uB12R$NvTTH*K)AD7TdXQfg1=zEA5Tt$f>_uKm$Yve3#ZNB`ykvUY-*n3`_V1yZd zbf6xtjjUkm*M2Oy8E2nSk6yTBXWLH>j5WqshuqR{ohR@vJQG8Fgvofr9yZ|>=Rb7g Y4$wPJ%60c?LO(!3R#HlCX<>G7XMTBcOgtxN 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 bc^vpZ3M$de#Q}!)00000NkvXXu0mjf3_?7- diff --git a/TMessagesProj/src/main/assets/emoji/0_59.png b/TMessagesProj/src/main/assets/emoji/0_59.png index cbf97c0e41b98827b84fc95d72817329471d2c15..4f7f292f22c7cd7e27d63add3186dd4d5dd4fc06 100644 GIT binary patch delta 2260 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 kFUFrJs@SY&KmY&$07*qoM6N<$g7s3_vH$=8 delta 2539 zcmV=Ff5snce0~~FD@%VKRoU8_ocneDkvpCIy5RLB;Coo&EM%M zB_q|FZCh1LzpRej#vqD8iyrhU79Df`e85g;%i^tE=l%%Lq zNkPk}hAu29z_y%mX;qxFz>S1!&8?E=uZSBP8l$hYv8IVjM?b>U-+7Omes*AGVqNgG zie7Mfk)^T0%FmF8ZH$P39UB=I6cScaOrw{0j)iP)X<_orsS61Q@W-TQV_kW1Tst^4 zOGiIOLOh+4b$|NXy7$$zHZw71VOaIiuXb^0BOo4KSWuIRZc$7|sGNN6!=LNCm|fxvpVBA!|@BcU(cTdsTW>Cs;!<$*hECdWEHF z218I+2^Q-10000)bW%=J0RGI3AgbY_54rs3+O*{{*W~?h*5SLI=t~s6{`lnnF=2>9 zjxvO0F={7QEq*E+jWWl_aLm=S*z0x1`1FU z8iuFWEu!5i+E*_SRx23#o@7-BHnCO+ub+aNCQ6ZdGMSukjH(rg-)}XyDUXaiU1!qX?x%325_x4fB6y+cU41Y^i zApbu+8KhXdwdZYT&8KCL8z+w)0RT%0!VmWoIB+M+Qax8bNY(w%W!zSHto7IxG$Uhh zZ49_+?RJrp3I1)pjm7iuPI?L)5%wo+Qc+|vb_nZthjj$c^W@`t1T@QUot~ZU;$-ye z)dY0}v3+{F&GXn$e;uNq0OR!V^MBUX?)LWf*Z&2scDHs94|jPOOKWG{L*^iL>79eQ z^v>R1dbXN_^xn?S-rSz*3kmzIwcdeO12O0GdAa;fa_4*g`+4&D?{I131m8E(K}_DL zmr2r5;%uh8cJ}Oy-d}+TE13N3*=NrPXSN-X1o^fu@${QR#hLOav@yW%j(@DIZDQ6o z_vZpJ{@XqnDk3rY_2KUT-hxa`7L@OZ}V-h|2$BacvSiv z<@OT`TRaT+FtJh=7WVOa_seol5YFZr5YM8jkYHX;oWWTCE-i0B6F?*uPw_gsyvTWH zcYeE3H*ZwYkYHO|UitdPQMoQ95@ya94Lz$*3=Bo1UYi--cYh_Zi1%-x zu~EJ@**IS)`lde7_A?Ni*<@NAQichE zTa{iQCLp|_5DcV#Mu%WMZD=SlZ7eQsf>$9pZ%Fm5@n5sgA+OC=DSyN4vu&CL?wqg* z-r2skhQuUM@(JgLDO6IaqFl8IA+!x=tU=l|{2UxJAWVqZV2FaEDT^tjd0l5CLfy(+ zROK?T5R=(lsRsnk>-)w##v1=wCM#uNz`$zOkg~x_qXmHGe;EpP1;rs-uDb6!r4wXvoWPoJ|NA2$Ce+S^zlMRdWtqIP%kE z>+rj#rVoGo-dwwqN0Io_y#4?TK>&oykBsDPX7E7RTc0n+bBuTRT=fiuLJ56BJsDI-{(#S-l_E!V%qUs(z>r+0FR<%L|xk-c*3Ah|w1_Qrz#P;>m5*=5W^#^sV?aY7t_@(z%4 zU^y?X#e>@cd))7rB1|N3g2c2tm0C?8k#z-(bj(3LfmDgR|MXuJv_=?cgr);b#FYf1 zAOY&Hc>dvrcx;}3$N$^R*{q( ztK(0eynibTEqDLvzPP(R5tr6O8;t=pn849Vu3!(!$GJ@AIN(CUlYAe}f`LHC;Hz7` z7v?cA6^Kbjnywn2T%mAm31@SK6QheM6Lgr$OpkZ8bTkdV`s>n3ec*9P#ki+zxLnZ6 zQK2BpvOSmcxEKZmAhh(ne;l@W(}%maE$8lL@E7?#z)ZQZB-i zOlkuZb?fdQzy3Zkc6n36GQ!y?(n${(0W=uxj3t$lXK02wC$vUM6fIQpky62>KIlM1 zTGGcoNR*90L{6pLP!9?U;fcjrik#2CsQJiC0uhTB4KYu(6~@S>+)^wCzN-6XIzqE3>1MvM2a{?2N@X|8LdU!zTNfu^~aaPeZyV1 zAzg3<>3TW*^5sYPsr>Hc>yN|3t*u>CQxDF8{{j_WO`cO`re**D002ovPDHLkV1f`Y B>?!~N diff --git a/TMessagesProj/src/main/assets/emoji/0_591.png b/TMessagesProj/src/main/assets/emoji/0_591.png index ca95f232bdc61fcc38d8a4c3baeb781779984c10..bce31f8c5f28895034a0e6ca79568ab6c2466fd2 100644 GIT binary patch delta 1968 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 Vy+^;&?=1iT002ovPDHLkV1fX1L5ctX diff --git a/TMessagesProj/src/main/assets/emoji/0_592.png b/TMessagesProj/src/main/assets/emoji/0_592.png index bd5b8c883cdb91eecdae69d13f66bbbf4ee4c84b..db4d5b9c140aee2770b7dfb8c70dee0c26d9b625 100644 GIT binary patch delta 1957 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 JPDHLkV1m@lm7)Lu delta 2493 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 M07*qoM6N<$g2Lsh@Bjb+ delta 2318 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_595.png b/TMessagesProj/src/main/assets/emoji/0_595.png index 861cdc53f631f68e51293080dd2d5eabd7d7a05a..94c0e461ac58925123820892d48389ed2b8f3b48 100644 GIT binary patch delta 1937 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 KMNUMnLSTYU!qa5{ delta 2570 zcmV+l3ib8I50ey-B!A0LOjJcja7=k|TQM&zvd!IyerBqle(v=6tjO9-NI*L{Hn5|G zp_O*K(%;w7%a*06#n|I1CnUJ3h%YZKE-Wh2-{;G(nl3LdK0-r1K0D9HwIm}U=F z`{BZFXkeL+aerrGTK3bjHZw7ulXd<5{q4e^k%(>Z$ffDKmn|wNJUBI^n0OQs5Lr}A z`rW+y*|s1Z8{ejYcW`Ebcwud3Q_YfV*q?deopW?;SNHMhglAK+tD@J`&RJ4G3Izoq z1OegS*j*YFW-=Lpc5Qc3KB|3Nj9Wzd%%h-fP1UG{?0@Oy$%tQ)bX#IYHNw5OkBNhP z8z0xkvoI3}ZE$eS%EP~vdbo>bP&zD~6B(eIlGnMMOD7t&!NvdQ$ZC9rZC^?3)WgA| zT%v|?i&_M^j0moTBLUI^^#A|>LUdA2Qvm%Tr~dxpqy7&4^{*8DyiNW$pvN(Zwck%~ z;M9ER{eN=Jx&F5BTFU0w{)yS0x7+pn(74?2(ffyrz@FEz#^v<>&TdmC000NINkl{l6O3?yEF3?h;-g_C3y1Tmz?(S82f9~6767pVY2)SRfR+zOo z-~7(m`<$73x6shm-s3Q^{atl+b)vDs!NIY?N8kb{O03kSq;{O!j;9}Gs;zkOcMgtB8 z?|-RjHAI4Ig%T-nq)>u_i=nD1M!QU*L#tU*s7eZOpqX^n(i18e0VPFC!3chzh?~Lj z8hT^QaeY%R1gBuoaw3IWpn7&^QQG7z4h|TA44}9!33MwcaJ%8oqV)OX1|0PgOk7Yj za4`T-8st9q&edr5$ywMGGKOKwTLgi&oPS*|_etb;)U}~)5EKRnx;I`N^&38)#ODw- zRFt$05BGI-wU6~nIEABlUvyg-29$n5A+ftBCT3^<0)8t_Lk~?}9{2!WE9@xe#pa`_x?h2}_M7!%!W>wbfblYcl^ zJ8}Sa2*C|2<3g~ECcv=$q6#b7*Ut(V*wDp=1dyRT5Rmv#!J$J0gJYsw$|C9-WK}W+ zYGiI{9A%(Hr8alt>|kHDCKt(F5|{<quU6S?H)w4{w zE*!A5tlXE8EU#}ZXC&>_TdUtC-+uzu*H2GZRzSAA11v8mwpUJ1*H>uTf0}W1-O=B! zGk+vP(~Q(D6h1;v^ zu-Sfy57cU8u-g1@Yk4>L+i!yyUMYriXSh#phlhe&s74_u`pvx>coU@{h86cYa5x7U z83S)faIzC#6e8SNi=vZ;7#=Kx&TP5d4j(ypa$oArRCMlMEi}J{7}5=N&YWcrfoyhp zJF%QFLkRk1v7!xib$<<249|mG5$I4aApNm(byZj$^`Hx@jf$=;@&@3k+11`XJ3D;q zA^eVrZKJ7J(P81$TS2C`0$_-QLm{5!ud%_2g^rHaj}u*$lMEQKU~DA{4v<*QMM?%b zq2ysPhhX78Vx;wbcU=WT?~sMScp-35NK(dZ^GE3I#Tdp@sed}|bIgo1O?Fqv@qw?k z5W(2uN;CovB;m542y`MH3StcVo)bKLIMdPkXuhvPIR=DI3&dF5rXzkhu{kJ65DkA# zFUAOsgPDE^+UFPs*LA^3Vq(~*cDKo14_G=xJ4!fn`_o}PgSU}$Zs z|2QwISk-q=U`f|&2X`s=_;svQ;%S9(J?jO^=CQAphlqxVI*PP-2_8w=lpz$ zOOqtEPGgW&wt(ZoHIt0!ra@>V0zAygHxh(J2q|*9{P}r)4`jzik~H$2Dn|*V~O=f#{;8~iG;aE{_sjK{}?{r$pjl7vhU0u=mFty_6CIrV;Gw(ZZR5MV$Gp_mss zVt;(;(GL|j7bwtaqr%D#f*4Bd?7OI=KWBkM>qN{GE;3aV*GtDo8gLA;-sw@u8=SPkApfvJv1nKE-%S g#^oc0;fb8lr`QzRoIEiEk}At5LzC?+N* zF)=YWH#ajgGanxxBqJj)FE2PZHyIch92^`K6%`T^5)TdzJUu-`L_`r05ey3p2L=W; zCln_a3UpB{WJxzpKP^l+9z!b?fmAt4 zoP~j43k=73dw;zpC9EMK%w1l%NkFwIC&DHs;9cgI00014bW%=J05nWy3?9}0?*F@( ze*gdftN;K1|NsC0|L*_)|Nnvi|NsC0|NsC0|Nr~{|NsC0|NsC0*Z=?j|H1$N|NsC0 z?Ee4lox^=goXh-d@c;k+|Ns5}|Nr>z?w25<4FCWIw0}uNK~#7Fl$2R|>nae0qY)vQ z#_9ptDC7P&d8{ntImYATB zL(Dk@Vt;WIqPq95lb9o1!m3O}I0!R|sQ{FA1TuH8Vz@`Yi_{Ddti>)Vg>XEM6!|u` z5!(~Dc^J$Jm13oodKU1)v8TrobZs}Lo0W5R5yR{^e zeo#H@sT9-W@z{Zx+XcNni+LPGj&Rjl4GiNP9)Hk*J~xXoZO;mZ5V4vA;4UI4iKt56 zfyk2YQxl;TJ|fb5l1L{gJCi-b4UR_#mGw=(LK$4EP)^p1cU&S z`hO#f8A{mNiQKA}u^K~Q`G|lKiF^^tK+7^T5nHW3NyS0F2pA#8h&3C41icuo;XDEP zRV@sL2NDU{C=*WYu|Og~xVb_FNA)g(k;ywF5|1O?$M!>Y#HH#-6JnP@zUA~tbN5%o z=|{uOiu=KU->aHJ99|{j_UZ)B#`EXj;eUz&N-1sa$6nldwZ(8U1;Bt1HjW8H9*(_@ z81Pcz#E0Fmn5k7`BI3d!9sBWk++Y0Hg7x}bPBN@YIg*`>0mp;CH3=&`u4}liV6J>Z zRpl%~K0;|9?Lb zyHtPyf|*F1k+Ec1x(1=Ym+JRA#N#mWp8Dk?1VqFq){0^rZ?!lAKlOQHcnIzovcyP4 z0jILP=&6SfnIi-~A@T?BZX^*{j%yLyTr~OFMM%)!1t7l>L>wnGbA`FtMBPr~Aj&VHV8yfx3o>#GM^en2n$dN zF8mr$P4fPal!>ypt*g2^-?^-2vIxCs@?=yxFrG(0B9Rt_h_jTEB2BZRkbjh%KSU*s z$oK5{Y|><0kuQ-p=ZM6)k(I1vWALB0Kb4J;o$jB_S{Ghesfw$KVrs9q2Gib29J~9S z31LhA_H5)kz44;6M4Kx(f4u|TZUA>n6 zbdv3#BKBjUh450=O#}Z3?SD#vrjbFBwa0UfF?ZSmB9PF)Fx(o%KvTDq)B5sUVm;BE z(z0GHWZm9si83fL>s%)2f^`kepYro`i5V z{Mx;mWD=2W|5pK69qOQ6|NHfYZoV#F+O$=>2r^Gx>-us}lOpjP&BSUmks-03U5FN^LIqWtk z89P7EX%@P(@4Iq40rQ7x>#TL&cj9kl<)9ov3;@vD*4ef-s=FKWa`*pV(#)df8^kY8 zhX0*~_baV9{Ys@!Xnz(8l~V1|=KQO<^W*|B8)o{oVxeL^uy*tG0Nf|%kD5&cUi(OpKTwm{_^-nxKtj# zMC(2=#EUBr$s_K@kApC6qdYs`;2t4M}I6n>I!7P>mivYPW#)~XN%=;Vr3{@Zk UXpHL-T>t<807*qoM6N<$f)yc+q5uE@ delta 2671 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 FV1mypcH{s6 delta 2473 zcmV;a30C&m4zd%FBYy#mP)t-sM{rC+F(^7PDmgYXJ~}o!H#0RcE+!)%Ixs3dFeo=M zEkiRYDvb5&n*?*^^n2(2Wma4Oz6B$ZTRcsv{ ze;goD!?i&G004k=QchCPu_ZGX6Zk)F`X&%yrU-q*U}Px-H_{kgl=LPd;c#D5V5&)_(%AInL-$VT$v-OvoToY8#vj!Ro92 zC}OZcxSr$WtdfNQo?Ni1J!<00E%P-X7DQkdKvT-7-VjPEL`*xv%Has21_VwM5aHa&jsWE8NG5KeBF;cqAQBgP^LrLm^&pB|1ISG_zX)?9lZ0P33DBb;D4Q$ z!n`nA7Rqt!P#6v~58a`#XKYzul$Q5MxmB8_Ff+dYBlIkkTXlak=sO?`Ja1#k-LeAD zCxl?qFsWVR7#1eE8`Y*4`jl~hE0}S&@3k$$Ij4l;nNdOl6d{x{d?Z|mh-|IRyL;Kx z1`|TWv0zEUEAD>|$w6Hq!eiPM$-HJ>Vq~LP^@GrdmTh-X?am=)BqWWd zHj;&j9CIO55++6+HANVPGAPt>%2V(`UGC!JIe_h5`7>_J7_4Er8gNFUBNoxiD%4Y@D-e`BuXJ>6%5Gq_Q&s&*&gpp zFM38@P{3TjGWX^fa&mfBnus&beZn~QQpy;Ygs6u|*wi_`KX(WK5GTcQtnpSL!VJBT z{&i(_dut1dN9DJ+wpUk{Q@X()-z`M~)S`HHQHhyo2QNiHpnn=*ECaH;6=ipOZDV;k zRlscWN}_sl5(%eg`_+5Jy_< z!asNohL?IeHMI#R&~kJnE#uj#1XO}QxY97qY7ue08Ggfv}9b`W* zW6LqaXC6oR>VM-_>+npa3_|mw64RlO_W27+^r?>d@BUsU_4Ci3wZH$b)0x7QJ-ep8 zsnyCVH4tJ60A6?D&kSc_#@XA4vcF~2!=7!2#mX0 z1B~YTlm@pi35ZQ$9tgx35jF_Z`F=ki0%ir2A|dClG$2RK_wD%dcWk>Z2?=sJNeN+$ zcJ`bwv(fKwb;5sbL{x;_LL)->39VIy`F&Wbe0OO;Uq}iQn}893LBK$kwK5#7npw&s z0tDfrCt9-9D=oeH_VSz(K@o0pZp#((;mmANLR~B@)eh@>v zPy{!;M4F1RL6q^w_9Qkqi`pS`1oNlb{33VV^SI65_i2|K*qclF(ubgKx68V|UeLkl nA|iN4_#VgF;D>pd`$+r`H^nx?Hkjyj00000NkvXXu0mjf-MGk( diff --git a/TMessagesProj/src/main/assets/emoji/0_6.png b/TMessagesProj/src/main/assets/emoji/0_6.png index 4d520a2c888f99ec51e2546bdeb6269b9a024f4c..9cfac3d8d9098d9796c22fde54c027cf6fd3b4d9 100644 GIT binary patch delta 1957 zcmV;W2U_^s5#AB7907m*ngsv&lK;*@|JP0bs0aW0ss7_s|MXS=>Sh143ID$e|NX@O z-C|}g0srQ7|NYVb`?mk@NB{YT|L}PK`kns5F8}U^|M-09&_4gn5&!jM|MzhJ(>1|JE{tM+VrvHvi2o@}Cf`bP{+z1>+&BBAsUt|LQ&e|L%=X z1kaTk|K2j{mk$2pI`Fn7dIWR6Gx+A3rP@;7S*g=k8PCtGDv!M=e~P>q zX9-wb=U!9ZGb0HE?)bZHL|0$7TzS}BaY^rwb!6=xD*P4zXnHFK5OXfV92}}*w=`7{WvzE%vlFF+~L?T zVu7~-eBy}##Nk;-Thf_xhmAZpfAad(0}KIdhrG+F`%t){%yC{L0-LnRiye$}-({$G zJQumkoN+?tT(i!Z3gfSuJQ5Fc?i-SJdqJ0Cs!IM}Y#Oe9DKr=j??y zdy-yw(S!?HLRv}-Cl%U1{5&&L%&sfCPot?byuZ9NWiY6UVw#q0e;aMQ(#1ssi*oEQ z7rDQmE^OKHOhr*!EXg<~ z=BBQ@6V31_5%c%+e~=P$+nz2>Pc&p2%@Dosfa1dT$N2{!yez695>ZBQ$B7jPQJ&~# z(Lt?)7}$8bh!x>lj&w`LPCFzv9;&BLZC)MUtrGj;HIV}GFfmQMEeOElf+B145!)D% z0X)wGx8;JTwQ^jjf zhc3wo57iwGA<*C!0~jS4w%fz0s{TM6W>Tx!w{f@n#a!wpjgBnc5q{ANw@Zw$NsN4{ zcD-*P*mfd;%*WMTvEQt8XP!dpA@Vtv{}@B6iKsnja>jc%hp&}11-67SH5hawGbL@Vjon9&AOqi*!etrCoWFt8^6 zgaBd(L@uAdY1BIdwDTmIHt0y*#!Wtd?eum^NK@E;f9neuM5vTX*?ysu&*yWwPq|$F z=BClTuGb}`Ucc@(P@5yc3kJ!aP(cBViwGtDsFf>7sUq}(_6;$BeERFBd?GT^u>YwG zS0z$Yu3c~t;%|iN6;iqqdMiW9Qv(R{T{*IDLNdnn+GUB4b#4K90$6jE3WRvS;rjr`3?C5}JQy0> zEJOyN2PSaO3iuTD4T{izUkk({pFuuAg%}YwWj6}LN1&*xho~y6Cjx-rQD~FE5jwmV zd_=&otXMs3AsXO(VG|PyyiYTPDJ-m>cea2e;jfdYnQU7rr_?Q%qTF$_73 z1)+fPgIm-`k9I>0c+~(B+CBaay*wrujP3=((3$Wn3j4x+c(k_{i^cYijstH|zZuxP rEhq_*K-^sa`jUR3ntOffmG1usG`GI&?n+#600000NkvXXu0mjfXsOMw delta 1954 zcmV;T2VMBy5!(^4907m-s0aO;1poMw|L%tW`kns5F8|I!{^L~t*G>QGW&g7Y|Gx_V z`lOKG7 zGU}HO{^L6Ewk3^E1kaTkMhV0ule_^qf6_@rK~#8Nw363u+b|S{WB9^S8r=vGU>5>> z;U^+B_a5Feb9DE?`%{)n$0JQz^dn%vIy|5FAL`0JDGIs)kY?TZBQve#CW!C;^$ z?Up3GyI*P#B;pmS-kQ+BDY>oBgw?` zpY$Z%vJ<2YnTs^EExZ=uE2dy)Nlp5KWQ*|x$CY^2&{JW^lMHYT@2?+cHo}~BFvG2u z1py4)0^rMP0+7Y$97v%O?^X*8exxaQ}d9RK{qs`1`e(XvZkA%X-4Q1 z+C9D(@rrokSkpDe&chb(Mms~-wa_DK>nKK-5IS(ZDEw(D$~Q7KEEVR@u~IF3ui zu;Mt*i@YqbYBUa-0W0Nsj(sMfA6`Zgt|&1>rT_(~HJpMiMh;@&97SQbf8m6o%b0E{ z4wyE$APhs3@LS=B04|uglj&(DDAfkwcy#|5olBJx%W-VrPCztim^O<82X;A*(@cY3 z2c1JvJFJ_L9Rcov5sP7uPy`OJ2<=P!o9H8lRXe_Ko|lVFbP_unEf?#@2L}qvvgTC% zxHn9ufW!K^UMv>RH&Inpe^IqBz+Yf*P+s1f%wWzbA84nm(xC~5dB0e$A0hZ$odS=e z5j*9N2c|HQMErdpD*aV>z5XPQg<${}GFsFOVljJ zkCVBsdafbM^7J$r37Xj6XN0Kf-sI6)I1U*vL$HIv$0t))=Ma?P>G#FhNuEv>MV{#z zKl#sEP(~vkpw|%&mXSYXInG#DMIxrB;cbn87%K9W>P;NWa*LvAiqA7+^ivje9RoAN zvYfGIyFQT!*7L|Ge`dNqSs1Qpt9~?FbbkPfb3M4uKLg=aQ2~+MV+41ST!IkQv1JrJ z)Ov`Gh1ZLi5st;kGF7a!N6~RpU2CHA%J6=f+}{p~6o}`sVc@YKfX4wv)n+5MFd_qZ zo(Hb01=nhi(Zma4DC0iOReL^ePbls2+}0-`$Y^U`aJ}6&e?3ht8ixD|p(qpCZBL#Y z$_O{rd3qv&f>T_;RmxMl{WMXOpNOMOYB~Kj>{h=T3(N3hAq!`O7dq&4fh%kf@4r^N z?l%x@Igv=_=<{>Y4^Bk$%F{8T4Wvfh?w4C782xA@B>sc| zVhcnrpTBL?I|H=yBAPbnNZrP5K7Zr&wn|7-*nArZf0rawN~LVS(8=fXx!k8*E`NL5 z=-$-p5>l_cVx2 zYRa`s4#L43p?Zy!u7%#xmh#L1@*_j`>Z)obB zn+8qgf7Rstb<)LurCPN@HPtQQ1Gf>s$ZnOJK(3oL>3&9gbN~i3|Dg+3eIpHQ-L}2i z{kT@XhR`f;We?*U@k0Ry5HvM@P(-g#;K}hi9jSi9B1xTrP2mfLf+s2uA|_vLmLUk) z14dA?waxT$=+5~o3LqX-7#_t}emoQVE3;V(e~JWj!JR{*2tqHDnkq9M#_I3|SHbp@ z1c9nh`YyJ?9f0z4Ct|w=#%f`vOsA<#`iozLUJhulpTU56H%@0hrlv3oD-CZ>!ZMY~ zh<9iKlR0Di?BM+H@Z#+4emYHG9Mhp|dWF}3f@iwE@G+B4|90h5GX;ydcOrsbYitYI5l#zhfbh?VF~Ng(cK-6gf$`LC=rDM zCJ0VZzjwS7W58MiNNnfiH}vv7(dgc8WE*-YtXJ3{?xW+~-9#d>dwddki~7~T>SaMm oi~@0W{rV}bt%kjRXifM31MlL)KmoftAOHXW07*qoM6N<$g7m`2qW}N^ diff --git a/TMessagesProj/src/main/assets/emoji/0_60.png b/TMessagesProj/src/main/assets/emoji/0_60.png index c951b1898059bfe610efebae615dbd5562a4e3c6..8d496767299d94fa8129a7dfacc583961e7030c3 100644 GIT binary patch delta 1948 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 u>2|r?;#~e=mxASXDuu%#@OQS^!F|(+s-01JM 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 D4`sX= delta 2306 zcmV+d3H|oN6OIy)B!5a!OjJcja7^FQ&fdao_smw+$D94zeD>Uv{>?w-#&7x2W$)LV z{pzp&?z{f;$p81%`{0uM+J67gN&3e+-Juxgxl{e;q59Qt{me_LYzoVoGK)?G_{vk7 zTn3U<1<{lff=2_}r!V-$J^a*OxqJ?>a|`LM9QMF6!GjNWKz{`8wkiC@EA+f6{mw=<#3uN^DP=bVjA|hDydwF& zA&y@Y%cxehfh#W_4o@ru`objP#(-pEUl$Jutc_Loz$fUg9OgaQHbd;5r&CAQfc!spISoy#MP}R`+CF^}qLL zN#0*?_J6Ty!Y6OM;rl@t#jYqyQr{bi%)B(p@&bgI&xL>jWmY<5_zIq1W+2>qjuk?N zZ!`0f#lH&P1Xe)lWlH=oA;hZwk7Q8uR|u5Mf_{UAQbF}lS6CE4vBQbMMxq3mm0cSx zQK`Z~PT^goA*1({elA2|>P@}fnLR1U4l|-aoqq-Wdqf}rcZZEVp3Xa`Xvq$*rBE;Y zJ|RH>rFR#5wTIi;A%+-sh*2o__nvF`nNq0D`LMDZduh(pjv{8y3K4zhD7Do4wrvip zy4!3H&AFl2X_?X5v`hat!e8u-dE~o3v>VldFaV$Jeb*apQFJ6>3^K4rNL*nB>{u>1 z+kfl(zswy$$|*|zt!W=Kqfts+RVtw=rcsWI7>EKCh_40`$8YbPL>b5Ps;V@`b(Tny zGgJaHX6}FaoZK;ud;eAQIS`AQW(J`qrFovkv!R<}bc&)_%u@ z%5plL&ElbgVKTNT=64+ISz9c+s+woC)_-uKi$V#Wk{rML0Emw-!xoF>gIkBWf_G`F z$}kK<9K*A%5+)(*^LLY3IlKa@u(sRWdOPNY?b-?vhNjbLQI=)ZIY3ZN^6l=!3=}}Y zaI5>b4YO6&RVa$;WGnakeOy*;J0MCP){#7o!L(K>yL@unQY?hB4T+K_DPnlyNPl!5 zF-X@eUvC>_;U(Lhg^PH)5*iwhaIGCoq=Wzg0mOAqS%mXGPqRj-E_^2U9xP!KNKaF4 zMb;oajVmC=ED+Kr(-~b8j4^ksr@=Cg&ZK0$mWj}0n)O>_ZUj@Xet(J)EE{Whg1Yc9 zKBvhTnxj4W0{N;S2+ICPnaeuLWxBl{VM^VZm0?+7zq*NqiY_^nca+7t^Ah zynbJ`6{MZLdi}vH$`=!>Od9zz(DHtWK$L*7PGED~hxd>P6i^MjQNDo}-;~ZNBY|M7 zUWQKf$R%UYi4?YjZGv-X2VyWF9lXwoh7AM`Ue;rSrKBW}kaFC*)E<$lO2w9eyO^86o z7%-rfM2!aQgg+bj`?3f;3U$+_FlD$#9e)T;C4}M>0M5Do z6skg88ZeHrl|>FWt^!p$)J7NCyKD4#W2)ILl!tQ!i)`gbfh)jzTFwkT+n%n6cJDB@h4Daw_JVOJh<)0hx<>TK6r8j>g&%xe|N@T8c3Gar+@$cFSIVY8;5~7fR~%S z_r6%ZE;AN|0nHfViN{vR&iB8r)MZHeH=Oi-Pb{gAudch@%ahN$o1LXMrC{9rdi{YG z&cdD0q&Vs0Oxi_j`pV(rs;dRbnuF@t5&7_{iO0-qO&UiyNgk%KWS<()$z@RWS$^{`1 z+|FX!$$Jgaq#OxH;lK6Y^)Uvt7zmx>NCl$tjcMzc78;v__rw;Ya)<4jm(wEMrT?nX@fD|_)jG|V*o&6Qj3Ll*!Y;LjVXNy=gA@y3nd8w cexF@m0h%B6X=Cbd9smFU07*qoM6N<$f|tCgb^rhX diff --git a/TMessagesProj/src/main/assets/emoji/0_602.png b/TMessagesProj/src/main/assets/emoji/0_602.png index 6e02862afdc00cf2d19619e32f4c4e6b6bde649c..ce7c7bd28acf051d40340c48db4579a2a0469c53 100644 GIT binary patch delta 2552 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 delta 2366 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 delta 2174 zcmV-^2!Z#Z5{nU#B!59rOjJcja7=ejF?vofhgmvyN-KU-G>ct5hgv(5XiJ!CPosKZ zt%q>6l6|_GhQFeaj$TGH9};v@KC_E=qJe9lbXapnCq*R=tAAvBQ8_*!3tl!Ffm1Rt z9T1FOJykFjl4MGRS3hSx9)Mm(pK4KkPcAtl6HO};Xhbh;PJcUjODI7o7fCN3Z9*f2 zRWnmHB3e2pVLvQyN;Ii)SFm_ow0>W=gkrmjW+n&%!jNgkm27uPDt>)?qKkgc&(Nr- zspj3t-N~!Hyt`~cBj@Pl{r>!-e??|xWb*UwqIeC{xsS-6d%c}3_xJX6NGVxaSUEX5 z!NkOzou1Fn&wofsN!{S!(9+b{+uXCPx6;(rxwp60+1awRx4*)~Z*Xymii@gbl*h@* zicX)RcCv*nrLtnIqe#D%J+!pAxppU&X&Q%T6NzY%-Wvb_0BdwoPE!CAEJ}2gwbbGN z|NsC0|NgrF|NsC0|NsC0|6l+A|Ns8~|NsC0|NsC0|9}7g|NsC0|NsC0|NsC0|FZw| z{{R2~{ptVz|Ns8~|NsB})%X7V{zd=)jlci?*8d@I{`>#`{{8>||Np7{|MZVUaZLaK z298NYK~#7FO&kW{G8QOLgy4rhHqVu2_Eq~Urtc_72wy_C) zCu)fdIfkaB=;q%)LzG7Q;M(Yhq8P_ctZQIxQM(>#& zv(SU!@hB&jJDE6DW+R z*%&J);V|cAUDs9Hgv|Uj;)doC^596$lh}@J?)zzBO`B$3*G<#>hG4sp zTy8caj)OcPmp%K+GYraoGs>;Wy<qZ$bS9kgQ+3eZc&m&XUxe+H9owK>2BgD^Gx_vQ2!tF}d zfbn8?gRe(F?tT)fufwpDap!DmyniK%$Itic(QHN!`#mNDsh7KZNzQj`l13vKMmXpq zE-?;W5^lZRKe5BZakoFIkt}!1&_4XU+@G$pmY`whk_-$G`X~w>Pny+sbzJ_kKS}{P zEqB}Fak)HAS^|mt2pK=SnpD+kwOSq3Fcg9>Pj&S>F*1f-+j~Lfw$Vq}7JpN0ryBe7 zFKKF|Dw&*45VVKj9NR{hBdO|I0u6%qe;Acp2$bM>{m?~xpfWHrR#s9#suG1Jl_KOg z@<`_hh_f!jpaw#9Ig+YY1S2?KL#ftDXfn#k zu_#q-iO7#|I3vO2o#Ec30Bi(Ee9^V2QV4-yD7+bO?XPw0PE5w&gO|v_hz%q9_$C#RiV&&bZ3!=FLq3dq{uf=0F9(Cg zhYy?0CjIpJEh+LW%YV`gRh%!T*vNcXEC!e3^Rxeag!nr6w*LOseSF0jA&gyFPriRK zuP@|-#s7M;__a|w*o_kg!Z`i{RSr4#E!y;g#*$@(FKDsD?0WVikYQN}$@@P*&8CMQ z!YY3Wiwi&5gP)Hl+a{LtHp$O^{QyjRI6Z&o`|jl=?5ZBX!+*bDx-AcYt$z0L8_4qs z0H?+>*ycO+l%FljwyB1`sc`J>3rB$nxT=KVH?CsoOWD=Kk0pQicx z`1E*PrsS*ws((r*NYLZ%C@BO0%Wg?fz@r_7i^}KgE-bBMD*v24O z&B(aSTg&QTtW^>sYt*XlOtiCt07f!HBoXI*Jx(`a8f!8l3gjgdLT`J+6jnh>j2K;A zdtat$xozT7s^QvEHZ)oV*>2|?!lDx4oH1pcD|KCR(|3Eyg!83S$wZCOOHDHTIe#QK&WH)CCWS=zz0eQ~fRhK)FPUlJq& z3S@@CCe%JxUq04#{TTCGt?^Lw%@6}+f&L@@0u7qcA3-*Q#Q*>R07*qoM6N<$f^-p1 A5&!@I diff --git a/TMessagesProj/src/main/assets/emoji/0_605.png b/TMessagesProj/src/main/assets/emoji/0_605.png index fd07104ff871bc227c0a1cd970182028edd5214c..61c9dc35c97857688d1f33bd076fc9fef9ed0bfb 100644 GIT binary patch delta 2198 zcmV;H2x<4P4xtf{BYy!kP)t-sM{rDBSW+}FEH5o8JU25xJUBZyGc__WC?z34JUKTo zEH^VUD<>o+BOxy=Dj*yeCnY0BKRif8KSV$}QA|Z#SWseJR8~?;Oh`dPK|yF@S#D@x zcW`J#LqS_oOMiKAIx{dK9vdAR7$+nlEgu&a6cb`)Wng4wU4LI+4hjhb1Oyro3nCT| zKQ1RoH7++NA5S_mNI^1GKQ^SEmzj=orI~u5m3E4ReAd&%Y<1fR>}|@_+Z?>+#6j=5BF3|Qvzd&9 zYOKlHXM2XjyQi3^s?^WHV@NTUQ}HJN003rmQchC<3ObM4|Ns8uekm7Et^USqr2qf_ z|NsC0w*UYC*k%9e{{R2~|IC#C|NsC0|NsC0|NsC0|9}7f|NsB}|Ns8||NsC0|NsC0 z|NsC0{{Pg-%;ezGxzh8lx%#L7|Kc#o|D*qt{%W`ZrZ4~i2DM2xqD*S{ou}ngwhz2|cLU8tWQ)(ZmP!`{=oIv3~;1hxd&)>FD`oO6K#3}_s{D#C3 z#zP3B5BcJC6Y~NIoL&e?8Ry}Y-zcm`IwZ-%3hLQxmSttJ0)n9d6X3ezF?jD62+!?$ zy??DB5#%Ej)e2LcVqQSjc6@Z;m%)hbA>x3KG5R$sTsg;j_!SPul_V)_RL0fJ;LsATfS|(iH01JNslujM6kA_Z58*| zcgJJ)8}1dR!cN%^7t%VU6rYg}0O=)ip=U$@NRUE)K}b+qYvm;)Azeg0)TBhBSbr=6 zAUMz>6UDhXBtu$mhbT5kpfPfF|Dd?ImLM}4xO#Y`H;<7>!_M@?-wFfDz}g9(DqbpA zOw~u%_A7P48f7#Za5+qYs1wZ=w-eaz)W|oOm1c=c2HoDVQApDvX-bG{t=AWf;h-}t z1&UVhj4^gz?{!Luln%LkV~A8~^?xqf=L1&}DEhsV_W61Dq`7Gn>RebNBWhEv4g2+e zb9ij$qT>F@Nw3qWpIojGDclNsMo25r#!%^ae}B`T&5CQIV&B%*jHznGSXjJA6eu!P zLzckcLk{awfOa-RhyrL+eWzq4Zy1DBCOnH$py<7(TB%guj79^d#|cD0dVecYinMxr zM+k|HF%&Ze(DYUWQmXeRaC>G9MQ$b`)O#DG^_zhdu%$5+%X4uK+IP5x(RP@(CKy`^ zpNq)cOp+74_z4VWrY;4VXj4{6tGPX3B3PV~6 z?vqT;T-`bDA0C%~aO9@r9t#|9POZg3Rsf7!7~4t4FQ1-#$My5=_uD5@*!5fl27O3C zr5y@EjtpMBa6BCPiu>z_m)G?7P|Uj&wAr@}SS&IjB>=cQkh43?8h=GiSGrdF(mY9ErPP7QXCLZGaE zbDziZ8uFWGAPlaCcYpIoc7&Y@wn8rX_fON=r863bYepmW;N7^q;TBHs1>>wE zu`fNV()w}a32qS~`o;S(#9$Ha(zE{sft*sBFytH(i5Ga3h9MXfBTF!Tb3X*4F<7+Y z|8s1Q6Ke@$7+L2W=1~?(=n%<|qm1}Vn5h?AK-60v=w7x<{~uRI%vr%OLC6~x^O$Bd ziX@fwV{9#gT7Teo<*_%QD=yC(o#(gzuY}bGV?q`Nqgh6iNXjh6)=ddU-WKW*t+Qsc zFT&2%vx!;B>J~*BD4uAPLQcF?G8?<)p}kD5S(6Jf3R!BkDTRoyFVqAsZ|go zcu@@-SB+BIp(!D(a)tMM2U>_p?lwV?10$%s!}xbK95I0b!cHqej8^YU2RlfJ(IW8| Y4Gh`nC=bQqbN~PV07*qoM6N<$f`wBm-~a#s delta 1825 zcmV++2j2Lh5w8xABYyzlP)t-sM{rC;LO@VXO*1GWMK&)!FDXemGDkKqPdznIJ~m!U zLTgn^cVAY3XI)oBJToRCL^UrwE+`%r6B-Q)EFm0AJ2NI57BnXzQ9n019uh?-7*a1B zK|w-cHz967CwoaNg-|e#STvVkIi6=fb8>O6lXjMQWrT!+*?-KoqNAd@xwtwkCEefN zzp0OXP6FrXgzrn)M z($l}f#Lm#slu&Y*RGPlP!je3&qjs`_ETN)DzqPr#v$nZ#Adj*k>Bay6084aIPE!C0 z7%NI>nYGT~|9}7g|NhVa|NsC0|NsB~|NsB~|NsC0|NsC0|Ns2||NiO!|NsB}{r~^} z|NsB||3Q+v{{C-^|Nhwj{r~@7- ziu?b6WI(PP*KOWfy63^+&;OC4tTbiu+xN0=+O8jR`hT{mzGs>NjI}F`wZ;H;^>+g_ ze@Xsl;ih0)eJ)g;^GZk_5g0x$QV)hg1T`Kb1~wmd=#8b|$rx+xPe#$1mE{l;BV@&X zZM4Q_BCL5t0He7&=A(U7AcA2Zf?pG>a%D6IpfBH#VXYF9h$$yK3IUGT6)#KZBLH+M&eNsGCD%es_^L+H;;4kUdIR5@879UgW1>`A+c2HYru3>M4z<-n2re0Tm`QsgIY(zJ z?SFzZ#=!uRBsi^fl@NK@r2C*01s5eE*4C*4m16;hT4IUm_MMK8M`vLv7gv$xawZGAZ{W{KM2~ZX@m*n! zbH;yHc%!Mo;oz^$oI-L5xJY57X-;cx>nLJy2GbEN-gkKg!6ZUWVI+se8WX9QFaW&m zS~&$Bj_`s*rfO7c;C+bcYj7HqDSuR0SUaaED&P=8SBv5l(DZWCSfxP%3_!|RML#K$ z!@v=vRRSoXJq+GT7}$3@xztG|1 z9B5*xm9Edu3U%eRAq^TdvwQmh+h1sV6~@P0Yn6bBkpc!fr(sOL^Wa?6?sU4ic7NUN zc8qVsv|EVbA2e_a@zworyMLxr7*-W;F6=k_wO!pC*nTcdTb z;x-I~aUAvy+Dk8nc3bTliGKlE81Z@1=u6gdNNI-7 zH3QBs&xJE#$>1mw@$tGLCX5<~778{lUY-teq6J~&#RwTU!-S71YJa0z6#g6KnQq6Q_Be$9bMAV`dZ+m;=lH7=Nf`70MTn64a1sHC7@bhhP91{JPK1HC`@6fgt;? zQ!=KM#ye5Rq?uFzRDUC=x4mOhl#;Wc^RYLf&viAX<=ShGDRLuf1JCq^;{>z%nLFyP`XBKZFs>-~WFaf= P00000NkvXXu0mjfI?HcC diff --git a/TMessagesProj/src/main/assets/emoji/0_606.png b/TMessagesProj/src/main/assets/emoji/0_606.png index 53e8a0be57fb9ed948e33e8146fcea8be8916746..fef853f94d33cc745e05d90b6195f5bf573bad48 100644 GIT binary patch delta 2618 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 delta 1880 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 w>9GE{MsKzT$n9WS6|}S#D@xb#G*P zbZSXJE`NJ;8yXoN8yO}dAQlx9U|UdSVqIrwWps08WMg4)aDQ(K2?a_zAyhIFUOyUE zQ9y4?9(-IVjbAG|DHNA=IIMa{o_tQRl1;drRkeyywuVfcT-~&d-?)*|w2j-ah`4!9 zv7~*yeN)MdV}IAarK6X4mW*)Y!kgpApq-L*hJ0k$%Cg6)hQfhX@a*PdT1M;I!RF7a zA`%7o_3`83+NWqR|Ns8uyq0oRKK19)+0C)p(5%nJr*~~vesx`this;UXrHmV+UD-T z&eoBov0iX`wXBwmgKBMNQmCAK?DY2Z`u*+l_vG#K#edo5ftRDZ)8Ng&psk{Tn2&eX zi_@$<+F~3|NsC0|NsC0|NsB~NdN!*<16a_|NsC0 z|H9k<|NsC0|D?44|NsC0|8;%;|NsC0|NsC0|NsC0|NsC0|NsC0|Nj#+UH||8|JBgb z%gvSl|Nr0Q(!7>4eO zz_kVhFu=w<6T0d8n+t?6xM$BZ$Q*+J0fyY|_Qp&TdwhC&etv#=d3hgB;0~NnZhrt_ z8T9JGyb~ZsqU3V98kQgOO~T5Z5VSC(V_1QS+nkwh?VK?SwMU!H?r=ONKOs)X<6*nq?at?O!BGv`!xJse z=grpsay*+ZDtyfd}h3TK~92thu z)ev3NG}_H}s|HNH`I@>)t=?`o4a>3}S3|hHzHJPK=ExilO>^`wra4p@4S&Z2qd%EU zzi5chvq^uBJP-Th@fdDpeBU4Y2xCkJinw{F%k9LXm~qb^wp!!GYw)ny_WdQtD|<3o zYl)3*3Cz8_U-$Qw&O*vSs#_of^Wm}b^XYlXgf($oJrP=DiSMFnBd%1;LBH%#u%b*A|zLQ0OP=AJm>=d!|h=6Ts z({6&nyS#tt4E(Sw_V15yxL}=JoiIXB!4KS1ff6aHL043&cA$qp85*~~KO(0-! z^>PU%tjQV9UgiITtbcoxen>pLREWR7lJz}SS>N%=95y*8uaXtu>;g%UnZ5*{;Db$x)t3Kt@1x$rMdH86vzwvm zaCl7=rE}x?^IwpI3`0|~Cw;;H_}g!{(fYd!EAd1k`SR6}bbt5&%RDb{JqF_!P=5JU z+5YwU6PWq=C;x^Z^P=pu$5ZKaI+M-iKN)018H@y(;y3ml{6vtSNx+l{G*9t@>~JU3 z8HiLiQOFNUhhM9lghZJK!w(1q`GfxlkLkau2?0$m70-oKwv;PZ-Wl{Xt4!aZwrGM} z!~_4{2Dt`2bXj|{q%$QwmM0zX9w8}!~|zyE>X?|-~UZ}Feq}p)@=cFG|SnY_?jpL?ThDgV650 z9g=yyIK(19)97m5jW2>58^JGPnr<{EWW;%#wq`S#tAE!4D3nbg2ESiKqD2V{^OhC} z?LXTH1~+&93hnEbM`WdmrSVR=T!1K-%jOUw9631hOv?y04E?WADD=pDGk zHUQH&AQZ*nK7r@}(eB^J-FgwJGAzreD#J<=#%%X5y$R+X9oE5BsN&*0Tt=K6 z-!2#Or*~^7R0vj87!FRz_6vsEeO_4CU2q093 z8gJIJ&|l;$_xg+Q8-^7pD6C!^oMu2)eQI=B+$R(uRBr6lmw%amwRXSPA`cVE6c0OI z8GmZSX|uT-3=u8}PVjo2W9o}R6+5Z`AxuokSA>LF?6BEJVWuw-LJ{Se(`D+}>w#S! z6ebo0{!^qdR|e;?k9rWgAmCXbG~shB%e!ac`$G6%AV_aRP2np8OWe$uAczPxANY~A&DX^K`azkR#tjFnD*DL9QRgM78Z)tv*_i4{{jAJ Vy+^;&?=1iT002ovPDHLkV1nurLAn3{ delta 2000 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_61.png b/TMessagesProj/src/main/assets/emoji/0_61.png index d47a3db1d218d5206718f65e0adc05090e3f13f6..f577324ee94079607077b74b1bd95b742543a521 100644 GIT binary patch delta 2036 zcmVI4QMuUoq!jj$2Wr_f9u`#CN0CKed&^G6j4ELuL?3)naiVE_f5&zgUXn!#Rk5UA7Jp`Fr2i2G) zg-ZpWXAjh~G#jq^5vK76o#_7TVdeh+C%FF5`v3p=oBrr^{Fej&-dg|sz6FWYN5K03 z@Js*qe*gAw|NFJ|*GT{5O8@ta|NYSa^;`eSIQ**<|HKWp^8f$-*Z=*<|NE)`u@i=< zi2vL_h~NL6=70bH>OR(X1OLT1>45_O{@wny9RL65|Kv6Q)e`^SFtd9aW!3*}va-ar zPouYb;ODTn$Bq8RD%pSs-N8Bi(JR21G%?8j|G+lruO|MuCjY!F|BMg&0000XbW%=J z0FFQHE@e*v4gKF8BJQi<~Uvp<{ir8$CI5rQKd=K|BVrOd-n}MXX zt@3mF^OlBWM$II*Q{<=WG#>^eDG`mtW3n8JN1_SoZ3Crbsi*czqDCSj=L*@*X+XA+ zlOu^Ym4DE5Rn_u4QdBNvPrKcVCEYGGa#VV~#I>rc*QIzaJL37vxnC)RN^5?}Eu(BM z@`@zSW>Cynkqgch!#Oz%IT;Mi^FR`P@i4PR1faY-09d!y3>A4c5 zClo#E-Z+lK6T%b59Z+=~6OR3u^#2mf(}hCUSn3`x!y;Jb!LV9we1Fc7cWD|1u>>`S z2;fUYszE+LIO0znQX&=X=ljD}`9{Mq zAAfN!PtNuWqf;0JI?m*#5hRdBco`R%4YS*^avM|lj+w~M_=mbF6Yqw>MYfC^n83!A z_{QHuC}s;NOFfj4Sf?Cf3ddt-bIO6sNP1~VQ|8{8+`zzK26MxW# z;nyE)xkTFiaQyX$r%}K+Fh(`+?ptj>M{XY8xaReLh1JcEsz?+Ca1jvE#Cc|V)jI^g z5OHRbS2j?9Suy z*Z~p8ir}Zq(oO@)SBoC^ZtcDqR-a=nu#3CsFC4Mw9h0P^+q@%6R6 z-xq1j#4|v`g#@Q0da6ac2f}qzLMXu^g>a)4SSZ)xmxUV=D`5?Sx1{|$5r0vXr3jX% zEO4M)I5!RxqrvIN6S0mmnKTfy>2xN7l#y~du7tB$DBwe=5j`gIIQBw+qTluXiXCK(r`h43@fimL ziB~Ip07oQ~a}4cPc~UV6)yVS4BR(E+lpPKP5S*1m!sGG4c5G;lM1MCLZ1iXnszC+_ zGAiX+h(SO=2{}i<&4Ohf${P9O4MOg5B?T%$b0mlATg%W@4P}4;!huxgi0~M)L}E8f z!umYmhL#2+yuJ=VpfRXKkLF;bWut~1MH-Btcd?v-LckbQ!n7))-9IF1lucz&Sdc)` zVS_PfI}Ut6IHt{`tbfsihan{kf*^f70n~xVu+0Xy;Qwc+p^Qz1q++hlECZ;(9WVy( zXk|2YHq)R% zY%&#T7R#jcwKoKS3aW$NVxeZVbZMZ-$o1wT%~4$@%5ZB1cH*1xN|4bxs9}Jl8EUUp zP%6qsvVs&krSNJPeOnrYAZ{7FQ2_15k0uMR2GZ4FFaidU3|=t+;j{Zj;2xIQDG)GK z1_jVD@u9bbx^2|ebcGPZp*INuy4J0L_l9L?XaXe}N~l2K-t9(>0ncq-k`q{5{ZqV<2z-QqTXVN#%+_ S8cYlT0000&(tR1pZx88^7QuZo$$TZ$dlkrT z59ELb^q(8!gAD(}IQFIz{7X9jn-G&PP)i3_*);#kF8{+U z|NE@_=6e6W3;)nD|Dgr{zA*mnmH)2?{F4L!>}m3^EZv$ax0Nxya~SivI&wJ?-OOmn zX$8lqHfJva|MXbg#XA4`it2&^|K>DXAprmV(Er{qzN1?I{^S475NG$yNdN!<4s=pZ zQvlBG?pT_c5`Q&-wbRY7qiJ;N000H|NklRI{g>l1i=B}*Tc+;0m`Cw-JZ%^ted7k^OgKFsRS^e3mkCCTQQpdMFW z{!LSTu(%}q%Lvy)v|v?Gf5Z!p?hNe=uQOj8ScH1zMUa%g2)Y&p$$!W2-|(v--tNQD2N)8Woc<84e1B*|b(~qP_fR7qaHQGa(s(xDcC(z# zoSunRaz~2u=}@tuaB8y|DXe99&qe%g8-{OhTMDqQh!>yz8gYtr10H)QnbK8RXd}GJT2tjM*8wSt zgLb>qX(+P(m`|oD6v)9Guk`hSL%<#3^1eidVsXF?Op)x2ODG~11CC;`*ebqq4u2jN z3mI?>W0JDB2kQ(LVq_7i<&PNbWJ$gD)uOmPQl6{05~sk14dCOCtEAi zEQn5|k%Sbg3JdDs5uyRT0M4}4Bm@-AWP|6<%B&NmF$WUM(O#?q-}i%HwV1adLOB;m zl0*hJio#h=D6%J_6Gb-Xi@6F0Yx=wgq3^o>YS9@82ilNE4IaWMV?hMxynhpzZQEE# z%;D7;rMh>&^kIP+NJk;cmk@9=J9Gj^q?xw7noE#yC_8-&d3%4EHi!^n6rvM~0rSXK zRtpKJ$9SHZ2v{3znB_C{k&th)7_vTcxZ;CFf`H%#5kl+=u_lP2Lm~C%tHnqQsz!)RO@F;j2fQj7DE3IH;VVtyVh2NCanS z;tO)8a-;|%wu~63K@@mB1UWAF;*myMd diff --git a/TMessagesProj/src/main/assets/emoji/0_610.png b/TMessagesProj/src/main/assets/emoji/0_610.png index bcd14163e117b56bcee5dd8c5effcdabe6e5a1a1..735717f455bfe83fe6d92d0561ea920a487b0f35 100644 GIT binary patch delta 2493 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 FV1lQwZ3h4V diff --git a/TMessagesProj/src/main/assets/emoji/0_612.png b/TMessagesProj/src/main/assets/emoji/0_612.png index 9109407d22234d8095838b2f1395ce7e2d665709..861cdc53f631f68e51293080dd2d5eabd7d7a05a 100644 GIT binary patch delta 2561 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_613.png b/TMessagesProj/src/main/assets/emoji/0_613.png index d8423f4616345ff3f5e9cdcb1f592da69f77e113..34a0063e692f6b5e4b3c6481778b2e57fd914891 100644 GIT binary patch delta 2570 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 x!>_6L4-O9Y_bui4UsY~sUw3h6LqR=$ zcyDN9S}ZIoBp@9f8W2x|meFu#~;7ji_Texpz&gb4$sLV!nxE#HwG>#iy~6 zLBoStx`9^GopsHXY}TWE#jIP~%d^CiY1^@ij%!hGR6@LweV&tc;KZ%isDQkGPr7?l z+O37<&$^wDhJVMyyO)e{;k}sNw2q5{X{n@}z=Bxu?&;vUk>kOf*VD|agI@Oc_P~8q zwTBdPOcnqC|GIZgy|JEF9uC8^i;sqE#)n?s$-wR2&fn0Dx2cA}d{VM)MCjd@(ZG7~ z>!kSeuCJwscyL;FZ(DC?QbJ|*lz*wUnvipXcw*}D_3rff-0ASg z+U0tXoU5RKgkVp^(%Itc@VnCBzOs|5pMR>NjHkfQT5Wcun0Z-IK*-S0vd!Itn50ff zH;ssam!+t-z{9M`+Mc(?XM2XAm3FnWt*N)Wjfi;Q-`ZqdPM4~%j1?NG#MGx39&#NX z)yATzoqvLhgKAmI*|z`y0I76RPE!C2ERWy+{?ivzu;+5K|NsC0|NsC0|NsC0|Iq*c zKmY&#&7O<@{{O=N|No@_|NsC0|NsAob^rhW|Ns9_|NsC0|NrG7{{R2~|NsC0!8rf_ z|NsC0|NsA5|NsC0|NoNz|Nndc|M~yq5&!@G|9|EG|NsA~|Mvg>h|$Hp(*OV8;?20) z^Z&}*uCf2zwfz78{-@^s{r~@>zW??A_S66L=l`hx|Es$7Y%{Ax000MrNklz*MBfBDc!%Eceb@}gv%S4CdeP1|){+vgW&DIbKC zQhzb7c~$9Aa|XO3KZj5n>zp-GFvbKE${XXQDvvX=Ax!hK%q~cU0BM4?AsD%4M-hzy z!sRkg=z|F8$pWK4YGSq9atVkH5DKpV!ZtY@d|4ku^nRK@5K1Cq+K_S7Mz#htL5I8} zwt3zhWK$kW<4W4!5n#is<_MzjcEdCQ5r6zA#7vhA2MDz?7AwUlf>#0&;mt*m^1wD) zMsMKlfeN8gAx=VgvDPP(h+0tt@B$Kqc&)^Nz=h`h$wt%2X-hU3|Bj$-0g{hNpG>1o zqh{zm7&O5c0|<(7J&rM@@x;8cyh8;3FQgRo7AnROe)z;avL?%ZjiB%QqA1#G2Y&>o zPZJ@6Qv6WbleX8_H@B#(FJCWT4`(SwO^i1}dR3$+?R!+t-Q6$C-M3(SEdv#x!7nmE zgh*cnh{VF({k`K=^Zk;F8-g$m;+($|_OySI4)YRp)%*-3>nrVz4gMua5Fh~XA-Dtz zx091y3xHqM6df1Fxz|llrIZR)^nWs1tMtR;e_fd zT%}?zXrR!K!Z5Pj2t{{nh;h6)zffOF31uW| zG+R}M76}?2;UxR5FMl%s16aRFmuDwD!1V?aZXj*j*N z#|ie~5hP^@&z_nAXn&!wjKPnOPEPMQIXb3SAr4_oOs9Dj!wHU$kN0nYr-4Hu1RDI0 zVOJ?22DLOz(hOr0Fbql3G?zk%V&=MGj~>0KFr1xR2x2h881K~$K=%cQmjs7s{$l3A z!}pJ0z5Vj#-^byz?ej~wh|7+0CIt2q(iV*KvX{l*y6b|ud4C&>1Ni7=#=y(WOl}7+ zQ@x{DH~Dhs_3l#8z&)BHm8>wSja=rs+lmS81Xf+-pwD*C)@rh$2bs<$6%#KzM z22AGjyi_r~&u!XEKwbj_cW>HX_O*RJ1#RpKjg?X_kVyvy;D*2^M4af>rKHjE<`UAeaDP%As)h9%eBJ0b~6_M?w*C10l-kvFp>*tE02c8m@lb`gb5W zpE^k~!|tN`^|1$QYg|$BZstmzAG+p-Rz{C9j^X&GJhRG+>ufT!>t+8 zviw-jrfK|AuZJ#r zy<1-d)H6lEGJF&_T0w+hQP^B_2(O0#qG%WM@bz66sonc)&~_IH0)}@KiRN^GasPqi za88h}2%9YYb4fitJvlivFE2DNFE}$ZH7_nWG&DRnH%31{ zOhrU7E-g|@NIaj)3&7W#-j1brtQL?(UWYkk$-n@S4Q>Ft@6yO=C+c_ zqJsC+vH94x``^F&;lldcy3@R+#j&63(X@1nlbR)tPhi^YYi8da;Qn{QUgXnswHha@wGJ z&y{i0m2T6OZ-3COm!EiGR#;e@pPtm#*3Hn-va_{XTU)=v!`Rx|z{SSU($dt|*Nu;k z$jZvSzrc5Rc)Gp5U7V(mw!s*Km#V9*3VMzoj-mo^g|4!*ud}lRWOx1j{d9JAFw;>a z0001SbW%=J00I9jy-G=?MM{Dr(wFCp(JqPXt-x({iR|?W=J*Dvt!U_1oIVd1*fzZ{xjfioAfjlb^ zrDMwBeCJun8&NzPB?lK%DjCB?WF%^>IS2CW5Pu$HNj*{{20z(HwnmLlCQ2RVSXvvA zQNf}6vx8)_K1^_*>p!Js-PkA)MDcUK2wDgW5f%swOG2c^Md}K*@BdluEhYa_`f&T@ z&FoA-(e@0p2P?oxa8iwFw<7@n@Eei*>EdT3i`Y(oFno-&941ERJxJ_&?22q_CgR&q!b**iJ5qYK2>dV~Z-9MUl4 zJV_D`5J;|9iH_AK2=y<637$-*lTvA#CJ9yo7Y3@<1QCRkr+hY_rIVeei}{=-31ZWm zxM+Daw8kA(R(~(1)9D0mrb|thmEQqun164j^Wz^$H5sF*aZOS>`*^z40gf=h0jHLt z)(tB3T~PzZ*m4=~FBS_B%4w3|U}lc3ka{gysxPgtiWVc8NFY|zoe5Al<4MYqjIsPi zfgdW0K(IwH9tI0RD3#32;dr(PLxK1{sv{g7ONvDq&HnvctvBAL~vYZ;|h1glxF9>^?H4=cU?u2%{Mq6 z#@BE$l&#}B7dK=n$1cmR&5O;&?d-0~W_CHe*bHw^E|H6#LQX%_A?#QOBFxT%+gs~8 z+aa#Ed$+gymncs%Sd#nNW=hC4Ce7P zVQwNio{MfLg>N7g^)?=ThtP_V5+m}w$mT#K0^vr*7~~ZK2?_|+fHr3sHt{?cloIf60vPwXFak=c$aac{_Yt6%J|K1^ z1b~r0JinLlx*=2EzVzy>f{ALuj%kFC&v$u8WX5h* zqq9gZj23DTZj2GWzT4#oqHpe%)9vY!i3$P1mKp%?{r4R{0gaW@)8!qrFmbYBR0AS{ zD;YpQ_hX9(u9xW@6Ms$L!FqI}fiOemGzuYP*FAfXc{UTQC^dS^{+0$h!7)=^*iNv`1}>+`dw-TnbxDy3OI8}6%RsWx zT1(Z@h6^oWQlO8{Swx{!(GMGnVE}0u2@#26vQzu#m}Vj{fscq$i=s#hyOh%iLr@~3 zl9-@qJQ6P-saRnIWQ?h3qgA1bqJUutAq-1hkrjoaoJF)rR9!eqQ4s<#MFXf^5+qbu z8WO90p^TMEujg!R&-BMmn_P|`KSFV_r8?p3 x)Xmt|Ya8^d8;EpU$Mt{i=DKd}#&5gL_zx{Zpx4{L%NhUx002ovPDHLkV1flg?^pl; diff --git a/TMessagesProj/src/main/assets/emoji/0_615.png b/TMessagesProj/src/main/assets/emoji/0_615.png index 565a8c68e82bfd7809b7e42664225420f6bcd4e4..94031a5e22a2e13fddf6fe72a1050bcb7655afce 100644 GIT binary patch delta 2667 zcmV-x3Y7J(5cCv~B!AsdOjJcja7->NC^#}KFD@xQK07=)H8(UeGA}GIEh#1?BThXs zEhQf?GBP3|9V8tWK|MG{K{`oAKQ1dMQB6o(SWseJR82`jS5ix8Vp(lyUvq9{N;xe; zH!(*>KzVa(fO&9AKR04fL_j_`BOo0g92qDiAsQGK78DU&R)0xiYj0#`XI)=kH5(2| zEgVWE3S2Q5WjZ5pLm_21A`b!pdQCKnRW6=iJBe99WI!!fHzlNMNQ+xTfl)k@U`K~q zK$~Yxt8-Jdd{(Y@TC#gyVm&69W=_JKhJJEfX-_?>h-9N~Qk{}@n2vJFu9UciW43=_ zc1be5fo0Uftbd@EiX8|8yog@Ejc0FWQ;l?LtfigT(8X^?G4AW=!jWmkm2LI)^S6l= z;@{c7q+kF4{<^iTS{M?Pif@iwMyh~2!JtFAtB1RZWl}XF>*nIOt&*;zhIMXOJw!>6 zhiqqEN|A|gs-=~yxV_os?ZM8}lbDu_gKC9*Wb5|GSWi8u!O&uGcB7Yg#Kpm~&E3$-ysxB+j)#EB(bATywwI--tjOA)x5a0B zhM<*p*x1vYt+IuIa-9<>mU?_Zv?0ZmwFpu{rz9>o)fZe*{KUZbB6iy?;BNh(-O*N^LnvZ zuGZ`IW?ujMlj^49f_DgMXHqgs37s{6fz++i#%LuvLMR~}x5`?<+v$vI<$Ty~gK>f* zKz}HwwR1}B_EQlDYr^q#3?6+Hf-wW*Jk><2{q}S^ZbyVggg0PBw2Nto^I&2`a4rC0 zj0eVK8`aMFEg-gU5k3TDh;~vMOQ8z_;5kGp-iSe=JddOeu=kvU2Rl;F6K$2=9Eywv-~*8nn8j90sE2xgT6=H zz~Un2!q&0Pvih9ld?T%b@{}M)LRngrW1pCShS>G006s&O&6;(pRKTL4LGVJyOBa+@ zbN0CTspR|J<71LkI1Mr&@58gahkxZy{~0Z-?zUkt43C*_$4rLUk+DXp4Y-TcW{$c= zfikJg@aHF`aJ6}P&7kLes3TR;^wO0gm2^!vO!L#{L3!MKA|=d`+4=CftN_c_G~Fql zu}sadE!!}GWm&**O;1%l&oqF1HZ0%wT}>Y;M2r|(;QO|3had{=3;DJk27hsqq!1#Y zjTZOnn5l;lCVr(_Q)_kGPy9qG8?V;9AB_YP0g#;(fpS9-ae7usjq-ffl z`t`f4v>PcVKmn6Qo{UhYL?o?ry!=_7TOHc%33YpIMNx94-Y0~}ADkitiX@`Zck^;t zo9_3{5RDm4JR7rfm6WhN&VP!mxR%9vAP{r&3z{+An5$5UXf@{+7c^_S-4_TiPnL=h zFP1VTKm=E2n#(KAPP2RANN06Y{7~r0CMIsWgR=QS9 zko^uaBpJdD4qee?Dnp{g21cNmy}3HX@`8oZj4sZ?FtSWtH$fD}8SUbMANPk?UR)cE zgc&>mmKd02zAsL3Xn$Fl6O;v_O^0B-1u-OCHw^}YXdnwPLuZu0kd>|sq4l>+n87_o zQI&Ez7b@qfswj*LBiP1Sz^+|;Q9#(-a%D6KL>NbkM5r;v2ojWpthTiwr|Aa|wzuE> zGc%hzTf44w1!GJoPr?vVE+0@5gW6PeZ~wuauLp;RN5@~c|9@`D#`wwUR?Q7!h!7zN zUY-z)1NNuQvhH%@hN5^W%rUzhPRbnSM0<8r1{q2|9_x=OP31*t*Q{A<>@_S*YESLY zny1CUTr<4ixq4(55lOkS5eymB4>q?PbNZjpzhGZrr-H(O5S>%}$(fh~Tlkoo=_J zHLDT5cU}*!s$z&ZkvHBfUcQ|D^waB~X0sEiPSSx~ihmP(`mWoZ1(kuYvby$fa9#gi zXQ-Iyq}?>Ra^=e9E01K9MAT}U(1S8C8ffYagNi!d7bpfgTeLm_kTaXp#5-8t=Z zYDr~ayuqO9bS9T76gr-3evcW$hVuPWQGF6ksF!<9Naiypu&|Y{l!j0^il6av-xo#z zG7ZM4VfemWKNU7zvtBRH&i2+0Kil3_Nl}bg8eweMV5aBY9F35dk(2{MDPPL<3-9#1 z(0|@@mFDyNqTypyj55pjwGGWMT=#>~_+!@uPZS%PAiu=ncbb)6<>IC1x7J@Z9}D6* zQu=C}VRZ`QaiJr@(H6pzB>v8^cfOwv+E`UUa8x`&EREP?7#t8IN;e6RO=%&L44sKt zjlkiO3hQliT zrNghFzMxs@+RccCf}ftAA_M{3%Cc%^WzLmvwR~9S=H^5^I_Jr(yr+-Hied5a@2Y4& z`~3UZ+uOT(P=C|Ag0gi^v~Whkf>^zMQnqtRwQ@(GXF@J9GEq}g9wH;j&CSfv(7eCD zS6EoW#l_ax*}}xc)790+%FDC0wz#{z#mC6O#KqIr*4^RakC2Uacz14*j*qs%U!JcL zf|jbQtXh|yA&8txn577Ji^a#uACac}`}+WAd#$dn1%GCEnVOsSzw)O5004hzl@7w&F>U6vPRqR6w|fAV=%3#l|?M7=Mv!`}o&E%h;>c_WOd@;^xO z+E7?&^$IeH>hw#&p`-@Nd_XC4zWh#6nk0}$K7Sz|p<7%0Y8FnZS2-`d_s-dba}M&K z4Hp4G0?#-Kr}+5{;Q@f`CqpK6xJDlM2}=rqfEWpc>Zhe_lniaxrD2=*iiIi_KN;)j)x=ZI6=bzOU%X++CS{9_UBfz{z#MI&&+VOh71 zXn*?&Ef?V~7BJpZTGorM;y@T*_dRY^v^OEr5Q3H-;kdi5z5iqE1X%eimwt7bAKy%D z9M`qXnJj(UumFJ&_JYY|I2`VbU8~pc!}TG0yfYl_xX!k5T)+IZ>R5e?P{I($p6C0M z|0xK9u?2`VGh)lJdQ(b87z)ZH;+$iS|9_Pi^#JjW5%K+&({qp}C>6&_0f-Vp7}HOn z$ZtGJO0LrSM^7lZ?Ogs~!wwg^zF7=!NwC6Qy9Yq6vejD{@Bi=wbq znx+t+q_YBK&uSZ%c|?|e-FBu-h@zYqd7g(5T`Pl6#e5D7WFAz|uYG4qM3`kr*MAcn zXhAuYQf!t@|vj5Jmn3B{0+yZfbizv9$JSL~g5{p>tC035xC}=-D{IZ}5vJ zVMOAqy}hfno*0SN6?{%Z0f@lE=f**O#4kRgAt;XZN^9=$sF!Uh2!HWk&40(@n->I# zh)`)kT&NQL07!#i;PS>iwN_q(fVT)>PzG)U0ZzMlApgaKQkZSLzhFrlMjRs#G0Cw; zD2*Vz`5yR2C<%}b19o{r1r1##X z#W)YJwjtJk{0aILXcOQCT7RXdP=E>lL!0Q331^h{;3V7pp=~hWH0w(+frGa%y6D*l z8*F6Tqr7NkgCfDW_YSq}XhRajk>q))Rb)gW&KSaeGcmhVL#HCN&@9Wi2;m(i2z!sZ z5}i|#gi^{FJd^r~NJs;A&5l}n^dXlfoHYQ3xE|2%`cg9xKp?yZNPmPEBLL$$@G(Fn z14$_6!UWLsorZ9Z5aIv`e*1D!!piSQvzNg4J&^AQ!TukAF2q>+>->+ShwHn$yO&yj zH%bSpZNoqq$7vs6>>WCw1Ns65Hn72 zAOiUzeOM3Z!>`YuK7aiG<%*h`;rq`+Uxj0{Shp7+0UlNzq}&L=x4T2P%+xPJwQm1= zllv6|0EHSLu}<*b-H(J#sHza+>i)dYcEHR~1xecDm-nvv!RW;Zu?pO^=Y$7j4KP%k zk}*$@*H^o)t5H&@*%Q*D20UZjdqfq$hoXS7!}xrAt>tk_*nblf3HF)MKb%~0DY6rw z4rDZoxyX&o8gjJXlf{1;rN;FQ+DL z5%+{nf#gMv7bUcD78^a0FrpM9!sUr~tdVzwFF6ylvDOXqq{1}L$wXmfO^PQ$e|cg| z21FH@OP!o^Z+}kaahg<^tSM|QYgnRZruO(dgn@+%nG|d5tRiWiM{V=$Oac7~cSIpz zTpt~Di434b1g`U&+hr#;=6N$XTgY1D8Ko3aB3>Syf|Wq=IahtQZr{^Jfz1Y;gF5yh zH+8Hd1M|^O<6@1SM%^}7+t|JB8~*G|dW3D?j-00000 LNkvXXu0mjfO#Dlp diff --git a/TMessagesProj/src/main/assets/emoji/0_616.png b/TMessagesProj/src/main/assets/emoji/0_616.png index d7196ec180c5ba948dddd0c095e5abc0616dffae..a67033d66424d70c855367ce85e0b2506ec78672 100644 GIT binary patch delta 2472 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_617.png b/TMessagesProj/src/main/assets/emoji/0_617.png index 320a1562fc244a66a6278d17e55866f525245cd6..9e3caf2cfc494ed6a49aba8084f2f9e1c6b25872 100644 GIT binary patch delta 2340 zcmV+<3ETG04XzT9BYy#9P)t-sM{rC=LP0MqDJ?1|IXE>sH#9LWEF>QrA{!PeC?zEz z9VH?lBOMq%K0QG`IY&Z0Oh-T}CnQi!M_N=(Us_XEP)BECT5f1xcW-7xLqTO;Q+;=C zJUluuEGQ%(9UU4NEFTya6cb}=ZB0^BSYl{nWo2n>YZVR)C4U(b3amTSq%REG2ktS*M_xOfx9L!Ms;OIO5>kVOL0ZN;b8ysZcyLmyB?Y zg@5(+^He`Jmt+j<>E&J@8orY$|Ns7nP)XLjW}K09hI(UKL^+OxZJ3aO=HlD3r;2uO zTfMWGjDu=!W`9$Wh;6gI!P4L7#n|JMsI>0%_}%I6f|a1p$F-uCcYSqV_Cw7#jPnT3IJ zx`&9Ds<53C8M&*6d>bGA)mgUy004G$QchC<3oen||9}7BcNj;gy|w@U|NsC0|NsC0 z|JVQjd}06p|Nqvus*L~t|NsC0|NsC0|Ns8~|NsC0|NsC0|NsC0|NsC0|NsC0|Nj4+ zcpI$tdjJ0Z)5pBh;?Lnv_5ai;?qc|aBP@awKe}V5@sB3!a_J7yXyHC=zUC$UF7VUDmS`Wjp zS+sXQO1l+ONdbiQgVvl;y7nhRZ>)39E5Q%}&KQXOe52X=F-%h+LofoowbmQ8YvvLw zvk%i@3Zper2myg=f+3G{i`dz5Ivfs_pdzf>kAHg@YPXz6oYX!*s8vW1o(M8f#>^r- z6;Z2DQkE*l5MX#YZyGCA`8Y#rS68QQwhv-1iG@l7ystASH&JdQuSS$p>h^0P` z^Pvha<&4`{v-%ehXqtuaG|svc@%>U(kxLkL0Vo1Q-RhoB!z#|cUCJqG2E#f_LOsrU zTYnZsv6%R`(^x0X@n^<+V-y5LAmx$MI;N!iuRCelfe09gV4Ulch?o0#ACVl{scAkO z!RdHBcHMf&M8FVLz#k>NJSFAC?XTZ|{!(5or|FF)=8~m zGHazT;_SLsW&`0nB(Kfhnqsz)&((JL!b;Wx%WAvr+C+P+N(zFjV_QpGVe&gzfjjet$uy17?OIo?YGy28YoJ zp>saCORq+4~ z_kvWTXG*!nU_2t!cIU(iAZZREmNAy{;~4MnW9dXymSqfqH6b*#mMD}pK?K5mWC;?v zbobvB#wxA78$IARrum!^Trlq_%hnl~|xOavmH&OVih|#deG%A`{ z`g)QeimGE3#gK84 zCYA7Qug!W1p)vhUo0*~%Lk7&Bb2R zIDlWv_H}T<@uj!z%@;8Y94EFgWTb0E$mK#HtkxopY!CkY_XJl`c!|69^IvTQ;=kX% zzCIWZN8`=K`XoDqQDm={2Gk2x>X{NAKAA^suAvS7QnfpZHtLMMm@}4yx-zz)>3^kq z@x(?nX*7nVu)n{XMt^r}mf2fDIK-IOz<9D%1%N0J0R%lvSnFD(07VQ(?l;d*&$`^ zYis2$_L9-lij{H`S=c+s`mAS0^D9WZ|n2C zZ(6FYwf)6c^?%01I84H8_m7UgDx|9M1RpN#F-@X@5AGMLn;dn~p)aBBanX)sqq! zjVHIiy&M8lB%uf(KyaDoR^RiCJU2n$L=kbLb84QZ>1a6oIJtZC@<<4r*r+HCTpCWE zZ+laeX9BY-gb;DNd!&}+Cczq`7o zU>Iqr>wiL21_z^X72%3fD2YOZ-EN~JKh5C+5)o>YUWh$OtE54N35&zJ?e!-RoWeH$1)uAR-2NG%gtCe#IAWdd z@)|9Qy_)0Wy^JwuG?>@)xGH7vIIzPYfJZ11haEKNw$_&MIpS{$JMIe}B?zAY0000< KMNUMnLSTY5-i?I- delta 1713 zcmV;i22S~|63z{fBYyz%P)t-sM{rDrcyn7qHB>t;QaUeDH!Dv%FIGi7Wl=_KSWaC^ zKw3U9PBbW2L^??>Ay7RuNjEM(FeyqZ8zUJNHYg$)4GS(I98fD5S27 zVmBd!PA`d5GDj#Gkyft&WU~ zz_6rkZf?-i)8pjh#jlUa%*$gqA@K0<{QUf_f*-)1I9gm=#K*{%o1A}uf4jZC#mULx zGoU9Romb<>bA&;X6b&0OB zvjk;#btXA{02%-QQFKyHQveDWH(ZCI;s5{tx^e%s|NsBwlhFYaf5-pL|NsB}|Ni~| z|Nq$k{Qv*{C1U>nLV3OY|Ni{TU8;2d{r~^%|Nn#aONOT$000F!Nkl3wupg$#DG0#4N4kwq zaQa38nbFM`BC||bZohmVv4RYJ;di!#ctcf%%U7?m0P%4Q;VILLyU+>8&kIW>mSK&d zR-udgiZ@P62uqeZaZa=IN=90pME zInu3hBQ!J+<(2kS_1svGsh|n)1fcMy@9`WM5`~lz=T)!athIr6oE360sBGlM+t4;u zd9-e;UQsiBN)r%E(2Fz;U;^Qq&2f2+v>D;IyUTGme=Q7X?56Q@JNb;bFCtD%M%exH zZrh2MX=z1#xq5l+#<$55LZ2U%>M(7Cd%AmP?y(coe%4647x5rE_VEdX=+xJ72@zZe z#QvRQp|a_Hk@$EKcq~7@lMQ_*ze*OTl6TtJmtQ+3^zZ%mTuI!22PVw#_je$gPTmxI zF=|4je~-7_?>`^!`ytJRynjx=|LpgZMW`qTCwysEGyq=$8kf7&ESkFGfSkHtnt7YFcw7M zj-wT2jXF1D(Fj_Gpj6BfgpjO$B8jp`&E>3tf2#uhzjWIFlQ4?it~g}ebCor`!S?*v zV$DBXUj|DE6LfvDW@l%p#CmggN5>L6ThL+QZX^lGpVpjoj;RuBtGppz=j3f@Bnh_e zjB-XAfp(p4N&c0SM2%jq(@8wWngsxYUQeKQfS~}%lnjt?I6dt6d(JowcQ8l*K=Us+9F{W& zh*FXQ0K?KaEJr7s?Ui7RbFDS!jBo#*AH+ENukkuqaT^B0IDTwzZBHd^A*Y23ghvb# zC@UqI89Q0qj|VYYmp0q?Hs3MF-=F_4us<9r8fLrM zZvGL((zM-S_n8Zvj=;_~$WFE&ePyQfBiiop-<#~utlci*@Y~P#w#h*gQ;Kaq?jH-U zz^unca$2u5F13TR5eYE046l!b6I6g9CRV|Z{ja4sp^FAGA+?6_fw8{;R3f)>eF)E==g?!HS831UA2+k|thz__CS*#^sy+;_zU&1*- zt~&urR_e05KPCYqsK8*13pFa!e@*DU6Y!ov8IcTtZ+D3|tdC$J=fwCB^tdwB${3um z4<4Zsq|p6A&rk^vVK&x>n(s@QO1Tcf3+cS|^F@$ZU$QcV5}2*EsotVCUW<0c5ZFi) zZDYiU3Xos!{Z4fVz(A;L$^{l;xZbMEa3$JgE(98VjPVD2SREO2ln!qI3jhEBNkvXX Hu0mjfA@xe~ diff --git a/TMessagesProj/src/main/assets/emoji/0_618.png b/TMessagesProj/src/main/assets/emoji/0_618.png index 886e2a83dec95eb96c42d1575a10e30baedcbb52..1c0f5f9ee2c43caa4292dad1dab49d6107888f2b 100644 GIT binary patch delta 2307 zcmV+e3HDo)yJFt+kE!ilm5*=<;HLM(Pi(~ zoc-#r{_eZ}^T_}A)%)O*``Uj0&`J8oI^Cfd=ebk;=b`%5Z~e?mscZ_%nlg({1o+BR znp_5wR0YwL6M{zr+ov!1#XbDgUb%b@v2zRQtsM5iGQoonc7H$w?zSoX#Vho@DgDkx zqGbyI%r@?`9pk4N$BGgB$vW4X7R-+m_`fFexFG(>F8|6a{lq5tzbR!m1dM7R^}Hha zz9EiZ6U(SpwSg-y9u7||1p2}x;l_YuVqX^z2&|1&_rNFUt{myEJU>7{zrnzvqN2CC zy5r>J+}_^twtpDY*WAv~(%RkNt*)=p)6~}3*iutf=<4Wmbaa%Jmd(q{!+40y&Ci2` zgo#d|#>mL5Z?uIirS$akwYR#rn!%z*!IeFUPDq^7k00#w0L_t(|0nE_XVyiF=fMLQOa%6I_!>Qx!4ZQ#BRaW<8T=l>A zXGz{)Z-4f&X~HLOyy5#n7{#tAN>bk&iOjq-%JKq)n9qfP0%cY@WcUi6UuGcOdyW-C zhHo?TlEuFY-UL=a>19g%Fd@XM{*Po(^H&Iz%z}P{g;GKFP*+$KK(WJ#!A7D4n3Y`{ zEm5h$K~CXaq#>jClzuKmVd_o2-I+Zp$PP22K!2SD{d+_p0C$ItJ)X`xr)bFzucc5g z{5~N;0Ht>qd$ot#*&&7)c8F0Z_xGM__?c3u&H1ph8+&Qa)Q%!%&k7NJ=P0$*`?hTk ztGe544$Zlt*lC&3+O$jmH^N`+jd|p|KC~OvfiM7{?S0o9ZBcY2VGJ^`Mo3&?1?*TZ zIDgyg`@hT`LCPsg{;g>rGow*TTvaNeDW*}5ix`Lk6o{_|631`voJ1MN^Qx*e#&woR zk~35SGG^|7`JCJ_jeGx9^EnWUnq~%}CZ&0v#j~NCVswh4Sj_Jz{(kZx~iIIw13ucqKiTao{}8D`v8cKFT)m#<%3&?xq^3T ztI9A8LL9@htr8|7>+^S$SvkA{s<5`(+=P4eyT!weKa z!Emelw+*vZ)>SBq>SQbT`+ZziZ95=J9@ddOjlr~5DZ6}f+fpoqvJHunCMjZg;(thV z9x+JQEMIRMW#J{;orQ~dx)K^1k8rIWOr(SW0RhByPFaNWK2Nhos4jda_Z}=^6G%@} zZbjB0J&h|M#w-xhCes;R6O1u;tEa&-j?ScHy_Sj4WSaF`V{Qafuzr7v5iA>Pc!Ij{ zFg~e_MC*0R1-UrC`26L3qS|&)I)8DoeYgJdbw^RkA_C9ojzQu?(+G%6$ldcp-hb(z z&$@Pqd$aoz9lmT|?2}p&0){&aFIG)}$hqJzo*%w^`GO~}E;}h-pTf(%dGS2sDG-d? zZ=sv^V3|fF%5$!&_b<=;UfP$hXJaRCUSITmUze{Z3J3^RCn4g=cS(F1aDVjG`xn!q zoxFZuwH2hDy?Xt@EXo%Xt4tdCGSKpVh(MHpu})xf+=us&2^3HbyHUP@7vGf5DI0AA4XzOoKB*M zFiPe3&|++wG{ycCW+v>l(0^64S$ji3A3#tkr3n%|OOh1RoN9GV2-~*SUIM-k;su;y z^EOB{bp{5@Yh~MRJWks*+_Fq}7F$cX9dPCCJjx-LR-HV9dknN5g5 z#uzZ5l|+pO?1VoX`1`U5JPLKwpumRT+i0!PV6cc==LaD(Nib!&Mt>a$P9=om6adb- z{uHW0TpBQrv6V#*H{;;1%eDi-){NpLgW(v2M3@jjAP$BkR9FWemaO~3pew&g0cB_vRXnV8u9x4=dT@XyM#!L z)BW#54sB>ZWVc*>+dR1K$A|k*pFVhU1nTS0KYw?|Um8f3)qkh|{x7sHx*LaqIDnU% zz4yLYzAiHsg#pbN;)%yr$jF_Q{CfR? z7S6(*(4;u&<4oE^a3UG>)?=YtZonJ80oe2`L&Tk{aKG5Ux4(b9fBXeepPgsPH2l}_B_(!CX;w;a^8TLD?FRp#SNSvL4wFZhOr{7ahnv9STM3xR$UZMLC zf|i7`fiPup@HPSmMVYc7mW=8n*kNZyE0}_SMhO`JlU8-{^6lx{gQBjy%PLu^NOh9<;M>S=ZTWUrXjlT;HTGn11bxxb9qB!4M`U~MuY>wW5}o=&G#HJ#OD z9Ho|t!0A8?mt7j?z%mF%3WZX0K+4%PWHze}I;~?fNh*@Wy(R6?fD$b_mFEOty!T~2 zjj2md4uB95Sg{0}|DV`mu;F#iV6M_82+gFP#Y(hQ!_Ig^H-uya-C5EOu)v@&HOd7c z5ZumU+I-0k(WD#+N8!Kq-}NyDv=|7T;z$Le@r`Ngm=+qFgZIQ1q;iM=^Y#CA#TXGS zlOBz-Oa&l5WgCUoH;v4d$VO*cDQSZ--uO=?I%5DpVp5BRcG&oss*Ndq2u002ovPDHLkV1n3TsD1zd delta 1601 zcmV-H2EO@@644BhBYyzfP)t-sM{rC-J2^5dCod=^GAb!CD=IN6C@UcxIy5v#KR-)F zMpR5oJ~}!uCL=gAGCnyuGA%7BB_s|C3LhLC784UB84({63^^$xE+830Fe*qiE>1Zz zQ$96ULO5JTIwl$vdU<(@cWGr{U5ks0BpVi`q@%H%hC~?#nSYv@&e75E@b9*_xWK}~ zrh6pV+uLF~0Q>v<&%A@k%gU{;uhZ4lzLh58Y}|9}7g|NsC0|NsC0|NsC0=l%cx{mTFU|Ni~|{Qv*||NQ^|{r>;||0__B zx$ezy|NZ~=|NsC0|FUfZ-JSpd1l&nPK~#7F)R0GF1R)FrZITgDV&?yEHO=Nc;j~3M zbs_2JOZeRrR@ztxtkG(NNtr)SAw&=YCGYe)i?WI0fq&2!2;_}gZZN6G!X1$0r318t z+8+s2+_G+9K%!zDD18l{1mDc8o@5_K;!1_}Wm1S;_2rTE8E)sF?6}fV+wgFg#`DC~_K6GL$8vduWERlBum|NqCH6sO6c>vzN8GgmSyr2|E*EQ18Ygp$GWNUjzIBLIw1 zx)g{M5w)ee2rr@ybG#A+5}{xW+tFnwt+Y~Q!HCOa2xbsj>#Rit1_`QHi@1s-Bw-+g zsuhDsB)&wZD3TCt!nvwu@k!1D4%kKl0+=8LTz@@?ALSKMLM|AA97k4^ocroPz>-yf z*oY%oqpUDYD7o@jy^mF>P_V?XY#whHEy6+81~bGVQJ_Iaa3t}jbrBGit)|l+!E*fU zoNE#5_z-%Yl~Sel+Sj#jTu<=)ylKc0s&X6cBWL465VYI-y}sEsRY$n>d#~%eh8U4& zSAQ|a1s1s>^7j@ied8a3jjDOPsZihS?`(^pSS0fnfxCOF^Ze%NIkYXedA!lNe%aqQ zggS?4GS0!|266Z5Z*E?m-tL=#*uB>B{QlY?mN`U|akdr&O+P;U)7RVmW9Pzue?C3^ zynTAhE=m|hTj$zngVxg2vzkM-x;i|PC4W%L9BG|K86fHDj#c#?%{kt!3y65@yfjJ) z!c`(J8jh}kN()u$SkoF1B8yzDmZ}b635`~xBNNFL8^xZ1d`|$50jvSVE;@WN!t;>%=7Odv3v%YWmN zNYGNY5=Ic)S!CFnxH?JEmDs@ipt8Fb79qruXoEc)0G+p+0eMO{5wd|Y@Q?)~Wvz%X zF%zQGQOjWQslP}V^YlgYRv1zcMRXus{?F1iFhb!#f<6)Hi~|HkVA4Gd`Ow-JU?Bhl zbb20!vHW_X*-4O6&GhpBmhr!T(|_Ifb*@z>ojpEIx9O|+zkiL>g^uJf3fx@6#R=r7Y3u=?;g*iO`a`gTYqB-%IQ!`(H&;!#MQWm3QW z(|5~D5j5|t8yA;HPyr#d9g*^f!$7`$GYZx^V_(O|3msVii3n{wp}PEf$bb7)>lgx< z*8+?4f;0iFYeHCWe(dr-vsy2RjITVMGwug~Do}i#w!|t=@0#!`&jbb=0mcarr;P{Z zCQ$bpHE0Ns=lRw5@0+=-l~IV9AtqoPZ%$3+(B7*thBegaT#ad(b6EvMRj3B~y7B$V znb;9*9UyWwo+?q33xLG*3VnbbK?37Z;u(af z5{aa9{Vr3kAY}00j8u7+-aS#E(-;?nZFmm>4K)dzK00000NkvXXu0mjfP%{!q diff --git a/TMessagesProj/src/main/assets/emoji/0_619.png b/TMessagesProj/src/main/assets/emoji/0_619.png index a6001c75fbeee8ca8e8f1be5a1cca243135281d6..6e02862afdc00cf2d19619e32f4c4e6b6bde649c 100644 GIT binary patch delta 2099 zcmV-32+a3^8q*MvBYy!bP)t-sM{rDZYins_Wl%>)R7*=pK|x1CLP|qJML|JNOiVX3 zGfhlPRa8`6TwP^kV{2+@S5HqiGc#^)Z%9T(Ehr}r4Gsqf2pt<5P)J8QIXOQ)JS8F_ zLqI@QKru2dF13JPXiYm76%<4;BgTPScvnHqjc18sO4XNesef%s+M<2otcT{bkm|gc z@5Q3>%&DJ^diBz~$;qs%sw4&gwz#;U zp`kA;E8pPXctI5R_x1h#{O9QAzrnzN^a({KO#<^L($|Ni^`|Nj54|N8U> zuhOLe00weNL_t(|0p!s&g2XTkK+!N*5K!a{^Zn1b(sDD{&adrfQ1Tw7S?*=&YumG; ztm>w1+oowkRp!q#WdlgudCY_Wb^qK0$}sqU_R;%Mq{<%`@_JGy#=i_fXdk{v(c%zi z$%#Lg!EPEoTQweF7rWN8&iGWGM zn1R5I_qvGQn251$QR2H(CarmvXBi?!yB_5hDnP(#tbW&0*B6{vLK1hzr$uppLKe%s zL0sm{9L|U}u8qlV$Mu+SPB{w^aWbEK-s#bQdIf<>@{`k|I1es}t6Xm=8RH$7wa-BqPL**^FTE@8 zI=Go50j11u=g!sj`Qp}7YDOt#+#a+}^Nv-7Hst>58uD;|1!Z6_^Tzrzt?7Kt!A8m-Fju@Ad5&2*~>KsW=C6@${l9V#q|>CD|I0ig0v)oV~vl4-c=K zr^m9aI(dKkczF1Hy?@IiJ);mwdaW0P;}3_Pj??`8ZM|7OJ-(OCFdmzOzPmrLp z-$oorDy4*Bm^eiN4}{=wl~N`v|0)6nOeeuPXOiM|{iBoE zMClTTg2Rjo`A5V~8v)0Y+6by?K;Xo2oZzP*q_GmvD@IDP+cr*rQUwiJ#3{@%3O_$T zt2a{#&_+`!V`R`xph3BtfRU-shbmzLLSm*8fF@+rc54YDAYd>?2^v|RXg~B-l>JR0 zbwoQM5Fuzt%8M8gI21nM`vtC72#6|H7lCOEIW>T!u$e&MS}+uN0{}5-A$kILDhv`5 zSB@G6Dxf|n5A zy~)k}4{oPbqA0n)B?p7*g~k6HtpiTSfgph66gbzmuElwOb?zgaK#^IyMzU)SZ98e& zwwWaDYy17b!%ccu4_@m1(SrTSOcr^benl+ToABKr7rM!33uZI>wpo7Z<9EAZ^plc^ zita*m>HmVsj($#dUqF@{B0{TU5ElF7&ojm_A0MV~V_F|y3u`83!tsQWJfHrbPm&7! zFl8b6Rr=z8<%4WlBa*p8M340;N&X47hc|%$~Fvrix}t zN(hWB!3(1RU?qGxX0IvHo>u!s)i#y4Km-6{0tZ<42}cQmh!BUVV2nOWb3UI>=eE6w zH{$U@SP4)JdWd(1&V# zrPZ2SNBEd~U?r?5wEgsED?y}$^;Eh%({j8vT{q5g$1w^Z2V;qPCK;@V2|;X{mZi%c zM7&-~n&x`B#yk%PGn=L(Yg|x*SD(F;<4TxGKunriOIg(N`gXtHZ*|nEU^h&s^R!z9 dv#dUr@fYxcm+!#pB(?wm002ovPDHLkV1i2^08;<} delta 3290 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 delta 1848 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 literal 3299 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 literal 3474 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 P00000NkvXXu0mjf*5_|C literal 3084 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 N0Jxz!tlYpg;=jS22ZaCt diff --git a/TMessagesProj/src/main/assets/emoji/0_623.png b/TMessagesProj/src/main/assets/emoji/0_623.png index 654bdc4d4c253e464a3a836c90e728f65fcd8c88..53e8a0be57fb9ed948e33e8146fcea8be8916746 100644 GIT binary patch delta 1880 zcmV-e2dDU%7v>I-BYyz-P)t-sM{rCB1qBrp6cG^-9UB`S8yhGjBr`8BJvcZ^N=j5y zR9swKWMgA$YHDw9Z$v>sK0G`mA|fLoAT=^FCnO^b3kxwVEgBdYH#9UK92_|}Hxm*O zEGa1<9v&?zDIXLM8xIR68WSxb88#*$KP@IkGAv9uF;qV`T7O15q?LY$b6$gcbTthD zaal-&g@hp=AIHeaq@<#~zPuwKAl%*Ef>aCU=j8SE^R9>|{r&uDIRIZuMX{~4(7%(_ z*VmbfpUKS4aBghR(9yxf#qRI#yt}@BR(i3sw!gx}&d}1gxV(Bbkd05Dhc2g{Qmv*+ z!kR$1Zyk=Iqkp5%GcO|m002{TQchC<7byxobg9AJ|Ns8~|NsC0PQ?HJ|NsB-UjP4- z|NsC0|NsC0|NsC0|Ns8~|NGYe|NrX$|Ns5}|Nr~{|Ni<#>;0Ry@zx)2$=3V*|KI)p z{q)I0&r1LR1<6T7K~#7FzTYV*7>mC?}PWw5*LS6_tU&?e9#~uC|o4Vg`{k|-a~j7)G*cJ zL9)s<-C$p1yzkFT=8a$E!`~G+xhXtR{zkOrL5MvA^kwT+AzYK^mx@Ko{ z%@KlA88B2JNvz-~4_$(UgZbWQ9R(>0i4YPqE7VP0CyD9%N?B5j>DX3x$eAvXfwFtg zM1S2jgQP625lR=N(3+1`vdx)d3I^js)wFGc+aL+(EzD9VrlBZCDw%L4geIAD8F=Ftd<2T zN$9Vu)p~P+BvzJE2{zJ+75DBgW_3jl~;x_eUtDBu6pJc2moeaA9?Ov0mGUyW6YB)QhM4QF{@g(U z1kd(!FV$gPXfJM;57&3k_cxoA;^O}58gJa(Ed7TfYR)1|` zb8$~^Tx=pK2$o&&`%t8I#=72gUAIIT1Iw;kZJN6BrtDGE>~ppET=me#i@`&K+{+9p=ct~RP_)9bx>5wI-($Gk^G8L zdmn*lFRL! zf+gUf7;xZH#~7g_LkdAjNy2tBim9gEgdBYgI079d#^4%~ff}v|C?;7&f?`Ndj@sLV ztH|JCP;6k9n_3$1Uk=RCCVEGkc}<(2H_4zASq1N*T2f16)&I1r(iSYqKz{<>lUEc) za*%@7N=QG)X+jel2E|B_PQ^)H0e*9ojwHAQ%xg&sG8BpIwl&i@laobLC8aXf45zb6 zW&ASy*vc){#VIfPbCdTmj=$1?_899q6l6$8>yPPdFMR=B`eNW#+igO z@l~ly;&i&d*qiLqA{%FCXMbn=ZSn2m=ADi(@01hRmUG;SLj!a1b$FXE zELW>ynoPw7OUanF9)HTfh&zGr0*J|x)`_JPjY?uBgBb^6qAh21GBP-U6sl|njWM>R zGghUImdpr%krS}Nwv!3*B_%};TDwrEvg%srnvzB}02G*Dqsf-zfEXb_H6$0Dpmk@I zb^1osN-zq^U^IR8>6!x~-6>b;h3|x{OV=8;WW;DB;E;eVM^Q3y0#2l=>RpCde;bV( z&AN$o%{iQ0R%aXn3xN6LRl)!e*`}&S3GrKb-89X*jUH`It1r*hh73ObAie_8Usf{d S!n5-L00009}X5oS{GoOYCa(HI;$0wbP) zm%gOQk!mUDVv7&;u*4{!Gwc-A&>|UWSzTqZRT<&g;aBZ3>UmDe)s>}F@5hH;_l927 zBD$$}Jb%(ql-$+bCMm>6r5^Ow62C1?6?-w`pvv;-`Q9y_0b_1GsvG4EWK(> z?#Q!JhMC_Lu+f0&Ng+KOIc{__UTtBLQst8q5kQM0m328CNr=E!CWi``djrD09C7&{ z4*gsn{Q{&}IiD^ODHg*e;t!XP^Ft>}VPxjr1S&!O^s$ZxosJQy3mAGCkt?Q3S zeB>T-zuRAFDM)nOL#RxjDX*%h>iO_*KjhvG(SsC)Av5l0MgmW|CysKpzE~slOrag* z<+S^a)^6FIuBx{cpbp*zH6Hi@b5vG&XLNE-P5Vf=l-l1JdKPAhw*my*ZxFlC5DM+z zI6fin_g}e1qdlBb?*A*7d;XHf_Amd7%>P>d?@Y+9Yz0rXCoMI2U!=t!AJ@#Ros=9T zQfbr=v{kiM+W4dR6NB=L);3G?I-t=uj!#~4M5A^5+lhL@{iEZP{K#s)Nde+xL`R^EV0}NqFpJ|@9?|)qXNd735Z&M#?yTwK5ASbOhCcf}kiiydWl@7bofu^8YYHo%IBS_XS?EQ}xyV|7< z!V8W?V-N0h40j8M6F@v+s_ip%d z4qItyzHY=9G0Cy@@sx=zdqvednKX}>WVtFQuxQDl3Pmuuj$w#aQbIao_2^jGrhswt ztW`>Qi}-?Ibg7j_`D?YXGj#`^0<53u_&p`n29f5tKy!{=%c|t`L&G573+q{y{`Sw z;gJ~(FU_(E1dg}qb`3f(bQkr{h{T(*7;WW2A+D-;f6->*s!E;E8@M8{FsL3g}D3mY7Y)l=FkJ#m&M z0|##VshCAx-B2i6_h509zkl4&TQM(nrb4y#anBlf?AB~uLtor-JyX&j*#IM7=KA>- zpEj;k30YyoJHJE3*SnlHhc{=d+*Jal?+4ijHj+$NcY+~P<_ojs$u>TgYB%VPrXth; zTy8CB|FB6OUGuo(3T0zzH?a11!2I(kJxy2VpI@EV^jG%I*tm#BH_0!I3S4pTst%qk zIKG(nz-!mX@1C=kySJ~RM2+>mmhI0eQShBa5_ZRM7MTairO&PvZfKWoXGjSg z=a&Q*`uaq3AhcwO_E=~{f46uLS?V&f`oEGO<1GnckcJh z;3uDvk`8bjUwf{Xb_%CK2)S-H8#A%ncd%+!z!;ytiYPuNe3I+5F=E5O*yXExrm7;} z$JAa?64T2jN)1Z{8K`t9P^+j^e>TwO5e;3)F(wKT+eW$F9$k4Zklq^=D`SqUj z*$hl%ek!7Vvyl||jm|iJ*UE)OLtwTh5;bQZ)`^s-^Qx-SE+djNHOR=tr=Dr%OgT|K z`_9C0V6x+UvBFLmHhO605s}O<^9(qQ?Nn-Jjt5NkSNs!OGG##hb1pB_F&U?i&kBzi zl!Sh2^E%@6|1M`pFC>jSwv9IqelTZ2W~h-cATBLqYuyFNCx58Zl3)q04)w_&ht-@} zzmT%iGw1Z>_J!^p_=lK*^=Z0#b2q;M`srKJ$?|O94qGUhz`zk{8MXfp)h{X;>)dbh0UKW=q;ig z`gY|1e7b44q_zBPGe)dpe9EfG*`>?56~5c2kL?oFdnT}DcV>ckS}U2&js8l|7L_p# zra(G66qqdLgSOjw2R-P>ZqZPs$(-$h4lR+W6Qs3hj~JUFl2*&lg*KfsJ=U?q7E^{d zIE2j1@=k{6czqAi%>toqD_GI~mRwYlnEjFML+@q3aS^ct%HDkb+j)__hBV5^5~s87 z0zaWEy;h-SBN7dhZ5gs9hSy*T*#W^4zfiH?4TFgL$7JcELrW~ur<$>hfM|O=u4xDkWQ x60-1RP#>U43C#jk+gT-N!-D7HHS_)d==?H6?M}`&sh=!R0L~DPsnd6j{~wVmmdF4A diff --git a/TMessagesProj/src/main/assets/emoji/0_624.png b/TMessagesProj/src/main/assets/emoji/0_624.png index 14a1ccdabaef8f2a0ba22f7a80bf09cdc02f0ba5..bc6fdd7c977da1f3bb89d86361374aac70347e7b 100644 GIT binary patch delta 2067 zcmV+u2<-Q?7oQN2BYy!|P)t-sM{rEuwQk#=8s@7O=BgX-wIKMyI{3#)^}H*|krwyU zdHdm=`{l0w?85%-$=;+G`P-5H_0jgvZS%uO_sm`LxhCYO8~WXa`{}&?+G*#oCeoG{ z$cqx$ofq-GJ@v;>z=IL0Z4Ati75>jb;G!6WO$U-$4ehffT7NbUpJNK#sVnijGW5MD zw|fupwa82Ga}Dyg9rwH-`obpu$0+~HE1q>H|I9GlpcwzuF3*w_$BPlu zuUVdhPjXu^+{B0s2n8-12*0a*KQSHJ%AM)08n}Wj*}8T5`S+4t3d@fYyM7L6TTVDQ zHlw7az`3ScTYp?79}vjM%C@(+P*72to15C*-q6z0yuH52%FNu|-`CmM!^FkZ*VoI< z&9Sq!Yiw<_xVqKX*yQBok&%(W!oq=rgSx!E#KyHq)#|J(oT|E2%`=jZ3GolU*~00sg{L_t(|0o2h0dcZIk2H+Y| z+qm|8|9|r>n7uvRTO<1Z;6Df>D-46biQ**9aw{v6xD0-+OmhGc#)J@z5d?WrMZvFB zd5xQfcnvYPkmkv6I!PEZ?O(%?i}>d$NJZYk8Yx!&tO}Ko61;3nu**avRI|kV@NEw% zZ@ZppjNPtZKoI_D9%-u)8%6+;rO^wpR)9|5=6?~-=2t!}9aXgfA*`R64k+c~o4SOV zGHrOjZWE_~0*`u}^Lgfb^35ce84JwEdC_+>cYMp4ncdkh%deB*c1U)dSJ&Ik#Ab(0 z)2%T*xcf5EP;fKf`JU49UT~C!qWJdS3z>+_fu$`c^^5I# zz25CV%q|%I)dr70ZqIEM7i=g8>Mr4|vfC&7j~{ot^<&?sc=xG4K3Z5>lF!44I}kIw zJbJv}?RNVwFW+@G{EJWFc>d+(BY$8*ejZ+bpBpBvfBbU2-_OO@Z&Tm7c=B?C$L03r z)XGBMy)md2krJxr@zFZ_^7ZAU=`}kF$J?jV3S?|>cn>cagqh0uHxty%hvqZ1(M%_k zN7Ketz!(`>!f$>y9m4y%@jYP{qWHS5@nnTLacmCjj$y<)hX_fI&5SwfTXzvecRm;@OCQcig&p;pUGtHa6G@Sv)Jt zlG`4ECJak|j+Fu@ni2%6z;MWL-8ktG&Q;bFX}KERApI1I1{*=X^MC0fbg9b9(ORq! zQOIBe6;@7-&)jtcYj~#k^MBD=JZyjd3^q`X&U>X%7XwYGpLa%sV3gJEvkQhz()q`a z^Ne)|z<##v-GAM%-eJhVhc$*s(&Iq34{wHD(mz64X>5m(QWEID{Wxgji411I1{o9H z;a~#l`6)q2z~H+vtUZ{3W&OdV=|yCWU3oa+*SaiX%9x}HFV(NZ_kZyxzyEwKN+Cq~ zf2C!y?M4g((DV8UW#&zpVN>RZ&NLZI4#=Lw5RF6q|3&qf=?;VMFOn*PhH0&IklXe$@fJ;pTbo15I4PJc#TNNo4rR%njHneIWB1i>; z(0C+4k8F=$e`FsDW{at$x^tw#B8mcwgaF>V@8S^Nd{hX9M#DCi3T*3$QuNjoV9E?$ zVAZ(!`tj@6f0UAP7>vxA0@>c-juA7GD0CUUFea57e;(ibl7F@HY>+IobxzL1!|Jrz z<0t}vs$v)mUS;PR4VSg?CIVQ&D9gsS53LEirm$tgXjmLsIU%cHy)!W~qGc61;^>eb zF+_?8WO4`*QSvb{IJ*ra`b4OeRtqCc-=hm2*~FPkgpxk4U0$ z;^)@Eow&P;^;11q$TM8KFGkPeeI#Y6`!Br`wG zW<2qRkaM=87#>uTxju=)S`$J_VLZP^PC?5v&Ciq0RS_!Xlp|5ZgGzFyUk?U@x>rwU xv+1z@w?=Qa2FUGTS{1XEnI87me%n_32l#Hqk8k9TMGOD{002ovPDHLkV1hs+P38aq delta 2991 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_625.png b/TMessagesProj/src/main/assets/emoji/0_625.png index c11f5b7195d929f71256fa605d2bde3b3ef22d63..74241194f5a7621065cab15b2e98d7d70781e3b0 100644 GIT binary patch delta 2001 zcmV;?2QK);8txB}BYy!+P)t-sM{rDxbY~sj zKq?v|ARl&CK&yIKD;f_YARyqXh3~_j!i{TSLm=?Urs}(T%7)z+JJ*~zxT zka2igNZp@!@8;6u*UIzq@%6r!&8?W@v5L5aHv9Vc{`KdeV-e1~uhE`;*`ImMwW-IB zYjbjOU|U(FrGKWv!^2`@WSyR#*V)<9)YZJbzTxBK*V)<9)YO)ima($4x4OH(!@}j} z<&BMw$H~cof`ZJ?&&J2d+}_^DyR*N+!mF#SyuiS+w6=?ji~9NasH&{~$_@Ge003`v zQchC<2opzqkf_fj@c#e*|NmkC|Nrsq|NsC0|NsC0+zbEz|NsC0|NsC0GLumQ6@PKs zkpKVxxD)^X|Ns9*=(Z@%`I`Oz`2YX^|9QCS|NqEf|NsC0|8)QV=KrXI=jVSYp%dy21VFQEk|l@p|9_SlLbuLcu*?1d7iXMpBc#&Co*1L#j;*#+ z*7*?AS@2*@7V83J>(eVFtJW-0C4Z(T@hAi=RxWNKSNOUi9C?pW=cOU42HqCBZ`1hYVR3U~L>u-zJFpfzmGpD!AvVVs0i(@{)ZR+XFWF=Pb*5crAvdQs6BC)r?u(%9;QT;KTz`zMM3kqOk>?UJyOb-Ht5ew9QFy%()cxz`R!pJ?`24mZz-A&-BFYbJ9>z$?e1C<-@i{L4P5~xUVZDnkPN6|B@t3 z@JixMpoHyq^?oQTAoBeARZrlJ!BQktP}rh?k+Kpr&tLX;5U>B8#iUHz7zXTsf4;2e#4LMNEAIYM}8JSb;;}tptg? zyNLa1dpH{BG!;VdP2j2oWu=6|wEf@IAo_Hs-SYwrM6!SSj@kcz4S+~lbKY+M{;L

    p;rFxGrmfF5Vh zMbhLs!{kj;TxbN%v*n~nREm?Mv%T-9^W*slast8i$MoAm>+ol#WWeD@5XEs-r_W%tCL!BZmHZ_qcfrV80z~ zOg*8!|2*fm{@o!$_o*3okN=$HVT;yUXpEKINyVk2wd(hl`(_-QMc6*PPB;t}5p!xF z+nkRxK>*7m#B@W%JTB~Tc&+4nLPTq^88PP^!+&x4t!BA4oEwi07(SZJhgY_km<5sD zqSz<_bG(}gT4(AU0uYZ0+3hbPo(Sp?**6etP#3peF4x6`2o5b1aR^K>U2?ja2r40W z9oeYlr%MO`p?DV^(p?-Ij%bsJ&H^7QHS-hVUvERuQoxg7E42EaI6k zBViGh!Kk((qBmM=lXM#k$^j#CC?KHSxo%uN)j^3%$kwM9gfiYpM%Sw1M6a_*p^(M1 zn}~{92_~1)IQrO1R9lkwK8@JQPNlo?y*ddxpha~1vxuQ)8p`RUr{UL}=`<(Hu%#0;ljJ+8`mN2rf*=3utWZ$=t{UA$r2H8T9 z${vkK6h>4S=Kpj$*Lm~2cz)OY`+k1Qb$ze<#r@(Ypbc*_L*Nh)2*j+bqiOPssK1ku z?w7tzATNSIv_ohEGp(Cm2C8OKE@tZY4S54iV6k?51)d@g%rC^;6>_!HFjVKl+rbJv z`09cMnqvRcl_WEic6lsUu`O1j(ifiY05A99sSf+IFI{1}L}{)8SFZ8%)2f8KL@2xMr44Oa-#{*-YC|U(hFxp62PbwFd_Y;M`)`SR_zWsXy+d( zGC1iM&9h&)}g7;J2lYQ!yU;A`D3xivz%Zx)q`&jW`68+Zhv#&Y$arCHoMV} znX*+P#tX@FQa#!0deK(|oXu0`E#vhWX7f0J8N@~v_X87l&s$JsH4YmDn^zqR_A$3d z2WK#mA)xczS{46968m5*+hQJ%dM>9`9j9v>`*bFcX%QQ?3id9W^)*58b)vXYIgepE zA0ihn7tSi|$9z2*#%sd?(PEHK<&%yOxabK}O_ETJ6B9CmaT&A7Kjf1%7rB+m$!-97 z@}w-Uph(V>!`a2#*3He>!ULs?iHwYBZf?m6bjip_$Kh}a4l-sKcO!Gpy!?XB&JH9> zDc5!hz%|abMR6!I; zQqt7#xaDnQFW|30PSdU~V)%P>M0##3mX(#Ywzgm#Qx9=)N{Ujv0;BVrPs+cZ^;bU= zLsJk$+Ap(nxGGHT$|vBT_(J}Nw|~Rt=x@vd0Ad>8U+Vu=f8`tnfLj0%|9k(xa{Rx8 z|KA^dFIeYL4q6)ECoEY@wE?54z_P5?udDb1O8{^LtnUJwBR!{whrs0VoutmC(_eN^ zfiHiX?!Tq{_NJaue{=D-{wrtR|5jV;4x7KjcT-0T1UjdotBEuVqRE=23th)j`uA6T z4SmuLDwo^b_RIqtfj0N0e@;hRQ$yvBg?!!%U7zCij`^wX_lc{p;}N!og8Q+cYABCX zcVJlAJI&@ITG&=TwLt9aybuRe6K!0F?5Iloy-j}Ex>|lx46P+CVR(xk*e_?3iYRoE$v@n#ofl#QN?ixw^> zRa(t^^&0j@e;p>W9rLvP)pEUmCd*o-`#bFshzS1Tl97moCZj9=M!?binHyn_-kxEj z|A~y`^HnbT6Cct!7Z9zX8MupIj1*=w6AI#$dQt}4S)LS?rf3(_lH3K

    we29yM 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 literal 3270 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_627.png b/TMessagesProj/src/main/assets/emoji/0_627.png index 5c912a821e53aa42a2be1f63112b7c14263fd021..bcd14163e117b56bcee5dd8c5effcdabe6e5a1a1 100644 GIT binary patch delta 1903 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 W?pR0c{XbU@NJqm!y;{}o`M&|Uot%6C diff --git a/TMessagesProj/src/main/assets/emoji/0_628.png b/TMessagesProj/src/main/assets/emoji/0_628.png index bd382bc746aa23c4aef9c48b90a17a0259fffdd5..179efcf77c1fc2b37c29daf7a0e064a662aa50b1 100644 GIT binary patch delta 1748 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_629.png b/TMessagesProj/src/main/assets/emoji/0_629.png index 8af23c87fab02c4faf698751103a21dbde10e339..9109407d22234d8095838b2f1395ce7e2d665709 100644 GIT binary patch delta 1661 zcmV-@27>v57^w}ABYyzZP)t-sM{rDAT3IO~ASopzCLtdwA|Nd&CMY8!N<>3ZNl98# zQes$GA{`t(H#Q_6A0{IsMLs?x9~~SS8Z$318WRr=3=1nLC?g;sEFTsn7!f=wBQqo& zK`$srG%ZayFHt-*RX{dbL^)hXJ7rQqo{)Bhbz8o_zM`R^wSTFX-OjLtf`G8GvG4Bf zvxZ1;YG?WQ_vPi{(bLnVXcpzhi^a#sn3tE2jf`z?abjX(si~>=_xHxg%DcY5*V)<9 z)YR42*W2CQ#Ky#`S>djqhtU807rCEPE!C38bp4d$}Ii<|NmzH zR{sCt|NsC0|C81NAb)%3{USrTxat4@aR25j=jWY+qEG+;1w2VaK~#7F)R0AD1Thc; zV}`XdZOs3F8uv28+_na8D#`x&2859F5n^RrDs7D2VziQ<3!Jt-#LbQvyfx`VOR`~e zNr2U#NHpR_J~AFwy?qP6i@!C5;3=oK1R~j`&}E(lQ{k!VcYh29w6q$}4Pl2TqWZ=T zO)=J9=6?@oC&U5(_2qpi%oJK5v~TA5J3wHCl`oEA!>mQ=ZGdC`6h-BCqF;=t+&UG# zEfsrq(ZMg1-BX1D_tw%{Z-2YmJ!1!p((`lhe2jli%R|9g8wkQzjGbzNvI2DpT(0+i z@Bd)g5u_*L{C|%d^aK1lRVBo#LGZQ~+E|i+)OFqF_lT(R)tnSd zf#_`~g!3*#NOX(=NC^D!PFpO-8UOn>|B_DrhtA15DiyE{LV?&8u%OI>qPcA?06e|2qtPEy|NM?|{4P(S}7>E`a% z87h_nE|j+J$GdwarBr-NX2h!t&HLu&ZqEo+l@UKFW!>;_x6?X2KHXi$+^Wxa8|+`) zy*Q_BH8X25!iUZN{^s%K>H2)=#~=@R|Nb?2V}C8Wcd=F3MT}{8&bo~tfH7S1?&~H* zAWr9|U!`2YnCSbMK-g^f3)?Bg1VpiKLJO^oPpO9n5Jtq%Ln%6I(I7KPwDl2;0q@9+ zJ^_GF3eKwa(VQyENm6!^jElj9$pv!IOvi$jQk&5Ro@}(%Hcl~MLe3*jmPFPCFreg( z3x8vb1QS};Gu6a!CsNtQ1j&I$0!&D8I*$;7lmi2bAq3tY2{1wRY&nltRoiIHSurN3 zDNBcupd>Ymxge;LWoXjO=#tq2~AZkzPi|2zz0J-1X%tbs8;Oq%d6f>Tf-3V zoXNi+Oly+^7>Xf($k+o3(4t|8HCfgwReycU5_+k%QVO>#tx?8<32*Oc&Mf{#DG$`? z^6C-*g0!|D?}sHh{(Sqb(K2dr8;0RHV=%7i<6c)73}moOVu5T%RX-nv#3i zOWWPgV2UU|{FfDyQ>y(V#K8r4`1bYFH+r4lma(bz{YLg~#(rYO@nv3rf93$|8-H2t zBdbYF=;ebSXHv-Dhdi(UJ;^l$YCI%W^IykY?p&JrIOKdj;oJ4OVO>lqBAnUGYWsOO z;`tc4Mva~FNtgAh!HGzf&Y8kcA;%gN-9wEwMxpl7KX*0A?P5 zFoRzocES&Z519bCl!6Hn5T$uVh!T-=3I)v%CSrDFG6m@!h^&+enqU}GuN7IHRLKRv zX?wrlOdxYtK&8}dnnFP>35v89nY>h@P#}h%*ZVn`Oj(6%#Z;z!)s~W^)N*C2LQ!xE zg|HIMU+(81H6}sR*2}b0S~yzEFcpDPDkw3EE8R^J3Q{$9=so9FrvvP*wVrjFwBdN} zW5R@_O0eElEIZpGx0`IspM&joVDWR2*Vo(2t!>-!w||Pi^w|eZ-gcaG00000NkvXX Hu0mjfj5-`} delta 3025 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 TKUBVx00000NkvXXu0mjf4%e}y diff --git a/TMessagesProj/src/main/assets/emoji/0_63.png b/TMessagesProj/src/main/assets/emoji/0_63.png index dc0433df470fa46148b08af6cf7fb8de6a8d8013..fe2841e71b53be6129fbf0052466c37c9308b720 100644 GIT binary patch delta 1836 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 fsJ@&yY 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_631.png b/TMessagesProj/src/main/assets/emoji/0_631.png index d913d5e758a8edf92f9d2876f4a85b0818ada361..8ce68de6b48c4963b046479931fff319d467ac68 100644 GIT binary patch delta 2016 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 literal 3196 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_634.png b/TMessagesProj/src/main/assets/emoji/0_634.png index 59868e181b9ec2e2f436f28b7a1a71e19ce69c3a..320a1562fc244a66a6278d17e55866f525245cd6 100644 GIT binary patch delta 1727 zcmV;w20;1R7tRfkBYyz%P)t-sM{rDrcyn7qHB>t;QaUeDH!Dv%FIGi7Wl=_KSWaC^ zKw3U9PBbW2L^??>Ay7RuNjEM(FeyqZ8zUJNHYg$)4GS(I98fD5S27 zVmBd!PA`d5GDj#Gkyft&WU~ zz_6rkZf?-i)8pjh#jlUa%*$gqA@K0<{QUf_f*-)1I9gm=#K*{%o1A}uf4jZC#mULx zGoU9Romb<>bA&;X6b&0OB zvjk;#btXA{0Dk}gQFKyHQveDWH(ZCI;s5{tx^e%s|NsBw|NsC0|NsC0|NsC0|NsC0 z|Ns8S|IPpZ|NZ~|{r~^}*#G?h|NbRn{{KRGz5W0G{L5XcbpQST|Ly<(gY`>>ryKwP z1vyDXK~#7F)RNa?fG`LE8?y+Cfd>8mPc6jmJ)U~*aewE$`5%N3{$MXL<>KTNm*4oQ z)C$mGPFUA1hMxttitQzUYx+SXRdA`nGi;mo_}w>{vAK=lpbtLUCid-ni3|^rb41M8uwuE>?RfWq}ud)E~aSY)p z(~G;%34h1W3ri)IVU3|yp^N*9H%?3BFW-d9IcDV4=l8<1;q0IPVTI(5(y~B~T?e9Q zg&B-uw&Q_t@?iff`?qDk`h|+;1_yj{y4{M@S3Tnb5TaBtSprJc_I>|TB{vUkU$s&y z%>-l+s8Lh!|6f5g-`-ABSF4XJrIxcA1ct3~5QmDfIJaM6ZB|5#Mn6uyE)hoUCbK zar>i1u-n< zfq!?L6>>4CY~;q<&^A?hv~H_jQ8Rr?6A(+#i!=>j0^yp?ae0lj8R56P%W*d?3~218 z@p3!)jJPi%PE1DF{qt_yiI-_dF{rx$r3`JAC>AbZG(HdduQ&k6VrayNV^yD zAUgK(354j>*Kr9ETnEJdonxW0>3xy-cz+RiEI+=J4SgrSN*1S*ciPyOUpprB@BQ~& zN!))2Cd}{mcOaTh-V}Q=YC@!sx83hQAMg7i&4s*wPQU-`_mf8D!OF2!`nRdt! zi9q8$&_e()T8yjmXx(VWfj}aXa)?3kh*6H~@@SoD#-z;vB1BrT^ffFi-)P5iLw}0R z;EX9VOQe{r@xT}`7DV8VqZMV1IyYm{2wH}qRLl~DkgR?piLyt{<*b3L0{y>q+W(U< zirua_WZZL=HN3(0{Mcg6KU`l1O9&HmeX?d}XQ;$_b9YC_5;|MZVc~8h3CW+H`AH$jj0D@jmpmu;K@(GoZ9eWF3$MVe$A3n0TCX!MwS%(}2{5$`uaATiRDdBSR>6<`ucbJliv}_w zwTAJ5vA+ORBDZoQhN*v6;3-bCzJq`WAz45=trBNMV9i9Tf`@6IC^g}|7AGO95up-qK+&VTh80BDE^&MV)D z4!9CotR-N*M;OXq!Z|^%I{`{o>ax2(CIKU;z+j9EH7e6h=)Dv0oz1R8ye@dtcZ V9T{_!4sQSe002ovPDHLkV1kdDT&e&7 delta 3029 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 SoIm{f;s6K>lzBVcE9E~KkSXv0 diff --git a/TMessagesProj/src/main/assets/emoji/0_636.png b/TMessagesProj/src/main/assets/emoji/0_636.png index 8f6eb548948fa6b6dd239be2e434f5045da4427e..a6001c75fbeee8ca8e8f1be5a1cca243135281d6 100644 GIT binary patch literal 3329 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 bCDXsP_f{kp_4{7@9|5{BBh7ksr`Uf1X+o01 delta 2867 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 Rt2qDw002ovPDHLkV1g>&chvv@ diff --git a/TMessagesProj/src/main/assets/emoji/0_637.png b/TMessagesProj/src/main/assets/emoji/0_637.png index 6520f7fefc67106fe489a7098d0ced8ba1304ae6..cc8bf15f529db1c673d9b02d7985d6d72d38fd3b 100644 GIT binary patch literal 3299 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 M07*qoM6N<$f}JaNLjV8( diff --git a/TMessagesProj/src/main/assets/emoji/0_639.png b/TMessagesProj/src/main/assets/emoji/0_639.png index 252cb888f78a2ce8e249f1083838b12de402f071..7126b24aeb21441da23468fb4a1b8a253b961f79 100644 GIT binary patch literal 3084 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 N0Jxz!tlYpg;=jS22ZaCt delta 2626 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_64.png b/TMessagesProj/src/main/assets/emoji/0_64.png index 582a9e6ffe10739634a39e32b1a0f4ae0fdd569b..4deb4ac38a549c008a138b545431139d0e84bce1 100644 GIT binary patch delta 1844 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 delta 2530 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_641.png b/TMessagesProj/src/main/assets/emoji/0_641.png index 4fe83ca0c7bf26425de6a33ef023cf20acd773a9..ca66debb4cfe72813b52a59ad56ad1ad38803d87 100644 GIT binary patch delta 2990 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

    38S?Yd9l;T{3P z_xg*UH0tzI*LBkn;-R(YV}m-4lnLSc_uUbg@YmQ1C3x!Jr#%M*0N;1ZzxtY(2uud2 z{ye>=K3q3Y{_xvyKq$Ci@QPr|(%t6QNaQSceHQt;xtW)BR$+|!@WjXCa_+;gW5XQ;-;rNb z0&DA%dAAvfMAD^51SY&6KMKSBt6qQcn@@0Fnirn4hRk9Tk zurV<%k4KQhP))u|@d_odmaWUOd8U%hg!E09B)WaTzNB96uLg#Dh;j@7*ojewZJm8R z(`6l}C0nvs;vy5PyI1QAp<#8HO)01Y5EKH*cM>5b&J`^33?`G|je*E6iI9nn_^BzyJ(SkIsSF%(NZWp!`q1D>5GWtIC@@B zv2k3H>49{r8X(5Xuu1*pyfR^WjIUsYIjWmNgz7zt>Xa wGdX>Ze4d#ZA8(DUy})V49v_b?e|5%x0AJXqG3-~`^8f$<07*qoM6N<$f{OFvod5s; diff --git a/TMessagesProj/src/main/assets/emoji/0_652.png b/TMessagesProj/src/main/assets/emoji/0_652.png index 159e037c6e5452dbc8a65be0be4f0b92e6b87bbd..9651d0042439b539231e5221b584d77fec451083 100644 GIT binary patch literal 3219 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 SoIm{f;s6K>lzBVcE9E~KkSXv0 delta 2404 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 LNkvXXu0mjf@X&T+ delta 2097 zcmV-12+sHB6uuCUB!3Z5OjJcja7_BTLG!sG?z%E)X=$W?IV&tNC@3k-m?~LFIQzve zEG#T8E-x!AF0_U$ZEkTfGBWnOC-k;4E-x`_Tt8e~T-KB@@UkmvXk_K6B1J<%Ur#-k zWfg5{VsLC`^tvRweGXAfMTlM^%8)(yzb2f4MW&Nm=c^m?w|^i(K|w7oF72@$J3Biz zHa7OWBEyCj`oSffUU#w0IC}JO};s z$wo#;OG`}u$0s2oA~7*CjZp>t%sT(dE$_NB{?SG#C@ES*DcPtshi5WGG#~ESo5rke zr;%V%Q&ZE3Ab&Kno-G2Sry6Wk@``_MN%l-Dh-v9sxwMj%lRCr#smj`d# zN*0CJg;up9J969|JNxox*n2PPy}CR3|375!9nxzgOMfcB0`G_>#R1PZ=iVXU(ZBv- zah1ves#4+p598;?>oHQ zmoqhM^ChGa*6e(@;}Aw{JX*( ze6II;y=h-+gKHm!7Zlh#ZJfJQ2XlT~5rHL1)7}fH*Ary^p7~E$Pp8u!(&am5*n+5B zNJ6jof)wTuWGOSF9}ySa9}ov^DK&s^ihuY`5PyVzA5K${+^%dvd;!EIFHcbdv&pDz zH9>uV^!bDB2<{GZqdPP65|4r_2pNKOxgGJTEeU|=v#C=zz7BA}A20wR-*Ht?bk7ixLzDTFL`jH9S=w_b1XHm z34sT8ic*}bWo@jDhC@vq=$1Z+X9z)cnBONN9m9u?c8e^YtnjVF`ga5z>V1XZ+ZQ6a87 z280qCs&6(LHn8J&7Uo_XN<$C$@ZKY)d zy4uXvFF)5SD}b&Vku54a+YmNUlYjLK$Vwi&DPoee;QqOsY)n;m4BaJKwGiRNhE2xF z>gUT#Y$r+9iBg3V!ZJ_u5us%nPHfp!>!unZVv_cQi4xag2sih|*bQ7avJB6G zO1dy{s^Q~f_6^1~YKNXP&@Ib7&qesAsz#RMMTBAiW>ZF!iPnA3p@;!YVOU}4p6}%$ z>>x0qqn;6n+B<>}DiST@b$_YtIuIg^Ts0p-d_OSVaNvckp-eO|P14OmXkq~GH-vCi z^J^|bv~6Tqj$>ksREkJ58a6Wmf{uiM?BpRRAq4sn8lG-bWN4a3e9pd5Qwi}8x+bG1Iq}2 zKt!60fSG6-BSeO75~?VQrh%W@k>epDL;|GEM;x(d(-=^S7dxQ|vjKqkuHku3RtAhw zIPzAcs$`5bhJz*@+JDb_gLha45+GW^e-du@D=V7<17m>aLjYmx84$`E^jEcDdr++& z9qk^Uo`1Q$y&B-GA(Lh4y5Shs?d_NI^V8$qqv{T1C>FO(tcVoUz!6{q1-4)N`&$?{C!H(+3QT-Mp$ZT_#t?FH!xe|%(Vi*IzL=L6 zGSkN>e^MCZtbfzT9|6BekYpJ7b*SGyD_V^US?CEk4Mt#s-021NJ_?T%?c_hheA6j2 zr$uBxNm9fINdVMkKB6XkAn^SA1rY#brPgv|9F(9DSP3XAAD@=lg()p^D&WXLZXN6g zRgXP^--Hh#8+{BlW$eQ|M19Jh#`6?~=N@A5CL=LC3o2C4A#n9+sZ?r~wyVib&1R|g bU*mrOpKmlh;ixBD00000NkvXXu0mjfq?yrL diff --git a/TMessagesProj/src/main/assets/emoji/0_656.png b/TMessagesProj/src/main/assets/emoji/0_656.png index a3fdfe7b726cba73c6c339351c1c9cdf397e5db4..252cb888f78a2ce8e249f1083838b12de402f071 100644 GIT binary patch delta 2625 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 V@y6`6dHMhV002ovPDHLkV1nVCsdxYY diff --git a/TMessagesProj/src/main/assets/emoji/0_657.png b/TMessagesProj/src/main/assets/emoji/0_657.png index 8a9f5bfe7074a80b47feeee2a47ae2d5cd8502b9..613f17b63ae2fc5019c603e23d7e87d95a2592b8 100644 GIT binary patch delta 2529 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 delta 2247 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 VB2r7ZNWK67002ovPDHLkV1nE09JT-e delta 2031 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 delta 1811 zcmV+u2kiLZ5upx{BYyzTP)t-sM{rC>K|e}AG%+tQTwGjdN-{w=F)1l2bXYfNX=yMk zDoH;&OF%k7H88Go94ss>R7O12lsIW>Yj1CI{j*5(tvGL6MrdYZ`L{czl3O-5H!?Ca zFfcGdK|&!I6ht&FDJdyCJ3J>H87(a>OFA(wA{{;<6o5@Fi+@!zO)D8jM@LaVHFQKM znqxaQC?b&gn zJhuATQ_HIBtAEb`00rksL_t(|UbUC!dfP@6L<81dEXP!W-g{;3MRwl*nKE}5r1aSU z75~UUTneD(aPH~?Sp4xntKAcXCM5LQziEWCIc#(WgVAU_4i%%@9Z#o&PGi{YJ!g@T zoU_^M97>L)`DV3IBuOM;>`n)Ss*cr}PN(Dfcc#g4nSW$nyx&Kfp(u(W8Va_%05i%| z!cU0qLjI9Ods3)CA!!qCNMR{D%%vEzu6KT_LufX>OuM=+i{WO~!uCHg1@BtT?k_#Dw5DG~s1b1$_7sq6_EY@_iUA%q6vS`yq4w}d!BjrNfZafUstYl}CJ5Rr)xE{2`&GfEJ+uBrmE2ZkeN z_0t(>k!Gr{>$oT*^^z>}5hmURYT*=4s@cS-ujCsLaheh#*m+s9OcJ~@PTB1chbl_9 zq-a=&c*{(6T@WG0WF*Ta{ZJI&j|0dp)PJ>Un$Fhl)FLM88i+g&Rx1?lFQEj={M~*( zZ>25^;;4>Rd8)M;0zHKg?(K96^4mUJmXQ7Jc5~;4)MYswXFKXWMda@792~Z5?>t{} zdFRvqur5yLg4Lor+eoNt&a#jq$nDEvje_FKfyc;h*EtTj$7`QrAV(SvYg3p&?0-(z zvsqjD=%Fo!VKaBmYp{_TrWo;p!4Q7PjZ2tPX>4u=yjgF~=; z%zPlsH8IjkM8{M~YqW)*LFmm7N`EryF)yd7ph`wH2y`AkMU1=uBL)ccsEZJkwh}RL z&@&FAxH&4}-i!iyewicVQ(;ovQM(cW5u*s=2O`gLetC}&r~?FIjO!3-nu6i(?lBT1 zck}E$ghK=euW_#mk#ga$^7j}xW&Pwm1OXgEXq5=MD&m#iV?eNZu~+_z5PuAiI*=w* zAv7k&2pA)F@7iUVj}VyfGHJSP)*)v%K>pckDQrfVpF93i_M$Q->U3_U~ zeD6-sxa>*<1C$I^4PrnbkH(J#n<=VBM0Oct%R4NFom1!vTXM z0=Q^OAc(;Ktn#uov?C^B5Pw2dF^}xN7`O$${(}&es%))xXBqpbYG$ zHXha75(WMwK+h1}E@saSN&!)rX?F~bW;0sAw?BCvX$!-b*Vf7o@=~DKtJZ8N;DH3@ z&-L}?wNI<~2xn;wvAbc2wS4RK9bOf4W568}E# zd3^mH0icYa(zG&0v#VROMU_ahCCm5eWhH}!1;c_y{TBi905aO35}|j0L(_-vU*BMkWgXsd$_xMi002ovPDHLkV1lhI BIbZ+) diff --git a/TMessagesProj/src/main/assets/emoji/0_66.png b/TMessagesProj/src/main/assets/emoji/0_66.png index 3446dcc189b1b3d211733f73d12bdd52f5b9cc22..25cd46625d80d42618d96bb17b6bf766d1d0a139 100644 GIT binary patch delta 1829 zcmV+=2io|73$zZ9B!A&hOjJcja7@mICc|nB$!`wJfhy^yCd_yl#->uZdqBW!3*U<$ zn5W8ax|IRl4uM_{=G5_T?qGk;K+(7@I1^(!FkyQzT zN(tMdE8xF6_Q*M@fG%=61ONG!|H&-En=1d*FaP_u$AKOH`G2SW(@5Wn3jgIz|Lb7? z?m_>(DgNAB|M-FbzYJq50sqE0@v|@Yk_6O|BmcD^`{|h3fCv4*G}Chf*S%)&*n;Mh z4fUfE`l=QG{m1Q`5xSaI>w*IR_E@Z02mkkO|Nhwj(G>sx>Zq?wV*mgE6LeBeQvesH z#WVg?0S^0jn16}W?bf=hZW?5l^Z)<_?@2^KRCr#^)#r8^Ne~5Kfna7xlC8-(5OdB! zIoN*x2ijZRj9LguEAOwpgUvb6^{KihaQ6R?EXxXlxBmtxIjLCs!BQ$pIpr?_S&>SW zyfz;H<{2;Zm6DYCi)M1g$}KO~4Mb3>2a!03%yjXR{#N_u^rkc;mi zvQlJ#;WU2zd6Qp_QI{db%)joTVgu+VcfTlq!2F_vrPTvsSER26)`AY;4#r9DTId9g ze6bm&G}p$z9SndX6o?o|gFYYC$J)H4d@B63wQ)UZQ0|x`vX9K@VYh1BwXCsb|5UyZ ztfbMx-+wz{q6re4JA6I-+$cd%lNKde?e{B^M0O967f<5IX)&Yp(LAKNJyur<;_M>V z^W2A3gDb5=WBUgn(LPxX$M(GV!3A|;YgGq?Q}ZS~yOv1OO3>iyA)c7dYSq^43+ZGK z6>P(CMx&jJJ-gAv1BQo=P%1J?lASk+9LK3@c7G-Fu8AVHF~oO)H}N7Ar?sMb#FFgY z$7cbZ6LJ52+*->S^_{HHGdbW zrNRJ$2I5>{gmV6P%?M#wwOY+EbiDY1-SvZ7EiiNvD2%v1B5s$|Mrxn}bu0|3Go)|S zg@93fK=6seprim0gDxjb={FP7NxUcSZ_{BgL&qVyu)4h$hk~0+o$?kS2tt;#Aowsg zWTFz~=i*i#r!P@YC>KYu%1o^tuIb5A>gu&Jsz-XZMH!AdvpWz=I#t_6Ftj>NP6n}|OE@>xe z8&!78iV!fH&GIuAI0uG50e61sjFR1^ZIFSyMe5;Zme2eC!uRtCgF-lzFbEc$khbd% zBR(?1O@6UxuA2+IC_ZP<4Vv>8O^F0qxx_$)0fZ^s*nPmn;uHD5z6A{352gG@XDozcB^?}VW1k<3P7D)jvY=v;z zMN$X2Tq$V}rvwn`a+@Mx5UQne0$2-|5?}eb zktr8a1Yr)|c|CwaIU|J63^|u21PT~-pgsk%Ir&S0!jbYNDR2O-S+=OZEE6E=zwRU> zWiJb0(x5&oWeDKJH6)S4bOBD#D6iydL_HL*PW4TR1iu2c$}=XI6^gH{fMy^!f>ju8(Ze@ z7xJ)$%QW8MByHrqLma-Np!mpPB-qM=FLYmf%hJ0AW`BL%PnbnYa-b%;W;9 zMBJ6U-#DP~JUMDa86+32jISdZY$KIYt%kUSogf>3F-U!Q=;$n zlYh3_Ix`WGuSeQ07Z}btFX)oANl z&RM6e6e7V7{L7d~6lE5Oyo#NS6BE{2C{_S`Lt$ZzMU;6U4oM)`u!#ORz|CYJ1b-qq ztbgpK7-o9BZRF8FpduC&fin%s0&(%g?PW8M#lvNmo zbP`&bhmG7=KoQah<)PwMyfNAz8?g|m4HUsgx}HfWgX)(0%~wkMD?CT0sHhA-vQ6D$Ndmb=6gAQgKTE wNK%#WzjEPLYKJKGg$uVhl>h&4hJUAj0=ySt4=8TjxBvhE07*qoM6N<$g1=dnoB#j- diff --git a/TMessagesProj/src/main/assets/emoji/0_660.png b/TMessagesProj/src/main/assets/emoji/0_660.png index be19840c8fd782343e2bbed2e138d50c0c68d917..81eb4a61cfaa15f39f04226c74c518c3d020ff46 100644 GIT binary patch delta 2479 zcmV;g2~hUF4!9GLBYy#>P)t-sM{rE$;@#-x*?y{EqCpV9V0mnSW^)Y>c|ej1%eS zq<2Q$*3RkZS~>aQE%-r9Pc&wo!Pz=&0{u&J46I*?v5+u72VfoOr1x#g%B$;0aB;=a4Iw6Utl#lX9`vA%>A-k}!T+0*c| z8~nv5t*N5_%6}^Bts1wquHK$!^|~MVz$2Sv5ay|M*P0aSwkXJsR4m5lN4>F~0D{?0xA*<8nx9&0`bqo9|6pv~2zCS!i3 z|IIL%gk-9EB!`52mz}1Optkv4!u@L00j=O1^}?faUz=8(tCY+rTLyXW%z-K~${!{6A*_2-GO_?e&kp4efr zGp_&u2Y-Y~L_t(|UX7Ope;Y>{hb0RvnK@|^JBibzL1?bW%gkbCHZxP0+WXM=zPqa8 zYpu;aal9Ju&NKg+dB;Dm=X>~qq0oRsDCqhB@r4Gw!$5d^V)V(-{TGACi~B>PVedfb z`-0#=c=Y+~*dQazjND#A+HIL3S&JpxvMm}Pc7F@x9e*;&kX%ybDHbGh+vzUSoF)i@ zWI0m#1q8a%5(>|cF>TVKG<9Pmrbsjl%#bj?NKu@mDZC(wqzs_>)sXj3f`Rc_N@Sq} zO>sgD9J(M;v;~MXKnc3SYaBd*Qd-ie**`c!6SFi&Su87pfz$MjPE6HdSdO9r(Gs z0hBF}Bq7=9fFh~uieg(d6+(2uMUgm~l147?TRe`cX_5pp+1~&Kpey)OJ*Eh} zq9{7R!vhjVy{uS-(7N93fpG;Tw!a_y9e-6-H&g)>dQw%ByoNxNU%a#uFY!4H0UCHn z1!A53&c-)7Jsm8vZBvAiOUvo~8+41|MkaMNw$TC52y>DUTq2s%^cdd2RfW7T8#MIr zEsiX}RI#^BwH-b|E+yM_INbp_^p1l6 zA=F<%=}Dy<0-@oEYiJbhOpL7%6n{6xG>z4(2~YvMyR}-a)%x%&@}bqL)pmD3#}p09 zT2WjT3a@^ywVL(ydNrG^0NHG{S+B1H^>^^CRr{>)Zi-=A*=^OE>+4x#ZL7x`VC-eH z&3d&Cy4GjSMG+dQRricawqy|4vCxA+%~rNruYjw$JK^ciB#fTVmJ3D|=6{hb>_qWj zG!rertg;ouXjU=NLw|pR&%c!*j8ewTt`(y3ogUFRcnWJ3B400=TlvS=TvA+{ib{s>T%;~-YBP| z>5DJ54(Vn3Q?b?^EOn=%i%o~1J#r3k0PiHO~A8NZFKYm^PJ;&Lv*#2^sNS90I zouI4YRs zl@*X2VY_j(l8KmQ;-0%A_%o4Dq@&TDRUqCq;Fdsh1?nr2HwpI*@%e5g@BGcPf68CK#cBkz_~5u;nX=H z(ur~%QuuFA1p>tf)BVos<7~ym7>)x5hEs>2AwrbuCBOe}F@Q|ru`s{Fy?^!2 z;ZzPYfZ^{xH$lh?Z!?d6%a%$;xongwt^fRcV$mD2(}4mqEEoR~bm<=+9U7w~WqW&j zzm~05v$fy0w+}Rmo*f+ydVCKsMe5m){WA=V54~b7N`DiSgY8F~n+KJ>!_7zA+c93? zEb`S*IP?H&>e(;;{t3qK%k~?IB=EZJFan#K5JJIs0NNs%=egy;FD_f*9g-R6g+kK6 zp&lM?o`2muJcy~h{Z2t!?AfyGP7L2)B5eaI&~d2hx+3r=0|<%;i@hC=-mPnIm!0s$yM0`Lb4nv@eu5I_Kio2gU) zW;5PzFJ8zZC=iiGC|d@jTcoCmvF|^?#aukc?QpNX-#eb33#MNhFmL)}+WP6az$)^)&lP8~! zDZIg82vHU(lAXVDCf+d?2k1IT#1bs~a?F4N?qCR+p+ttA9k_BS{>d_=Mlxg<257^7 z_|#s4Zj9`NU^rGL=_^ZP0+KVD#q^M6nUrPw6DVZa4zVPY68=FSzH&9k1_uWh76vcz t(Rx8y=FO?809?lKk+E-;@n22YC3s*p>)-$Y002ovPDHLkV1hq)_Nf2> delta 1840 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 LMFvhpu0mjft*{GI delta 2066 zcmV+t2<`Wm6Q2-}B!4(iOjJcja7qL+al45#=DlOej3aDqZZ$U&QG1iG7SxGfzW@arJ2MGuUQZ5bs(MkH^i2c}R z{`u64#1o&W#$2I{#;4^6vFp@ zGfT0Oo8@_Wy=0=?xVxR%-RJMZl<2hN=5OA|TLZIJ0Dk}mXGugsRCwC8mxog0NDzjx z!M1R~fWaIrY01k5jiO~M2j?8gnZ0}eH@NPR3yNK2FIRPc*)tlI`kTL7BYQOSzbg_6 zhr^Lb?4xlp3|!eJdIqfyNXg2Hi} zpueEP?|-7gIOF%P3sn7nB9XWNN#z2_Z_6l2QaAxn@zrHuMcyLf^DX@m;y|L9%N26D zoG6M__+mR&4g^CyDD&R@%CD6RfBU)`pZ9o4tX6zAAP>Jsg+d`{A+dr)Gg=A%p3dxF z(O6_|MQ^7+pQN2t}L_i)Q2MCxCq~MCc+e_C46(Tk!BT|=Tfk%Rb*Hgf& zaDOOPL%Xqwh>eQQg9NGk5-t9+uqykJNr>1{!NW9^G62L^RZ$|Ig0`|U0g;ZJcG}&p z$3x|FG!Prqm{BfwyY0?#5F!2P{9EP_9x|)bzUc~u*WgCA0jlOC2=AGUvlt69Q9S>V zEEY>8!(n>ucDq}sVjwiMzv$j{EXH;X!harQ0ua%!&U&&rEEbEJX2aEBrXV(`s#5o+ zXLT6YP+66gOUVF4?8o!BWU~lj7){eu;xbnIA_pb7Xm>iD9@8^jTV+|cs7*xVfnZpc zU9SVIL>#lz215?fG{Z0~vu7ZJBm)z%vq@H#S<}fA+cYh!I4qV7*U;Ev$uv#IaDSPO z2{z=zOn`~mpUz(LKxSPtuYqT+R2rV04XNtG5<0R}yXSz7!=MK(`}3U19>^+V)a24X zs57cM{lKtZ%FC9ivFdivwlWO+>7-29axb4^LNDZFBH&Pcx~H9uhESU@Q|x%gzJ|5r2ELsz&7I z+1;pbEesy+&c=z1=y-JBl!>FR2O?&7_7;=r1C6lFTJ8Q0%?cstg311_)y!5!t(v&4e%DBfwHO*O=W$;Vsz#sN@s}* zMr2uL(U1IL0{U1#R3RFL7?otxGapuF5pw{ks!E)7D8k2eY%-2v5MsEtX>I-&LhKm- z1sR)R@Xzu1gDxT|cz>lhI%RBMNI5FlYs{SfZg6OQA$hGDp_>o6A$*vRj% zrDA^q*o93uY;MFt&LIY&G7J;I ziGl8Beb-innYN-#Fvh;f`0&A&*Y9)9JoeC8=P9KX-DoBYENhm--Ut@?; z2nE_$tLpd;@kYF)@VfB!RPdWol}yui^!pu>tN5(gg`_-ARy>&i*MUD@P#-SZ$y z;ea54{MQ+Y(|>^jBYIK+7rL_ielg=bAX++|59*+x3l3slhLptdfY9Ub+6d1>Autmt z9Khaow7f6^yaywmUwIF)>|rfi9u^E?D8C=S-(dry7x3?9^0~z$0$UG-Eq4CF7>IZs w8LRJ=Vs(BFG(V5cZ<<5-7x?Y!%j)_UK;s{=DJsu|01E&B07*qoM6N<$g7&1^)c^nh diff --git a/TMessagesProj/src/main/assets/emoji/0_662.png b/TMessagesProj/src/main/assets/emoji/0_662.png index efe5fa471f368a935e6cce672592918a1ba8d1cf..feb615e8e6551fae3865b4d8243d3f99b20c67ac 100644 GIT binary patch delta 2575 zcmV+q3h?!n5SSE@B!8PwOjJcja7?gMF?;@joq;Ns!k;^Exi-rC~e+~?)s z=jGt)=;Z3?;oREQ-P+UX=HKw{==t>O?CRv@h|bK%wzRK^g@ee&z|6_R&d9=rcxab`ZH94Ibzw$mQ8;EtCU{UHgI+U>V?LK_ zL{={eu!ds1kZZ)9ceQ{~vUEnFenhjAQPih^+_H?=u86*`gtmWCtddc|rC;R8q2s`s zZ^9{v3}T?Ve++tvT;WDyNdk7m6>NcZhwfcTX&y*o5zV*EtQ_GeNH5R zpUS1M!cBa|yu{AGrjE;M1%|NsC0 z|NsC0|NsC0|NsBH|NsC0_y7Ne|NsC0sM!Cv=FtED|NsC0|NsC0|NsC0|NsC0|NsA) zE$;vS|9}7g|7Y6%|NpZ8|NsB~|NsC0>Hq&q|Ns8M>ihrJi=kto!@B?f|NsAw|Noi( z|KghedH?_a|NrN?a1KiV00*N%!&Nk~;@S68>U>Giygn%kJUb zWpI-ekW1ce=kM*gL*ZRh}y1aodp9S{vSty%3z!*Lw`D2?#_3dy(#f@3Kbvhll

    -hH1Oh)G<0ycA>4 zN%XNBhOUPZ-wrT<#+9SK8^-~U$nS0*cV~zC@bL)|MBfeL072u)q`#pkL7wLr1%FI< z8H|WS*LZ}K`l;Pn+>FEN*%&dtj1dE2HLI&KPb2;ZB$YBG;@An}rv0rI>>N%MQwg$Z zg0LgE*R$MSC5I$Gh-rU&-Ih-B*YK4AwPy^-QKq@%)NZY1?};#x(tOS7cOU5oAbs03i zavZ^ua7f(s{hy&Hm5m>_4+juLVH87%D#198qA-kVwJ-!9PnVZI#KG0&Cx3|Y1}MQe z{TIfV)Deo}FlT}1JI`9|zJA4&QHn87aguN$g_K-!&T+vcC`OFJ__N`8zMCzj6vZ-u zF@!M9w9(pHX9a=?!UPk@lw!2)Lv*@bMI?ub)W&2c%dN?!bCSRa_v$pS&}#ZVksQJL z&e^PzsccRwq@C+i)$Mk?-+xgf9|RZH@{}-X{xOCVmU8DLVcqUv%cr(t!=7{L=<{nF zN}V?@Ihs>22BTDn3F)e~A3@l(=lJ=Kwc2lLl2`vjOH)0@&uHgci!-RQAdS-}ZC6cvTGc#X4)qkc(hBCwascu#4 zjc4QMh?Y`1W?uVKyu#Txg#wIGmaSP0Qeygbn) zph{2*9aa*EdWjW?KnQfxZ@oOzG*nWM4OlOhq>)m)!o`G;K}d-7blSSVw6iGCj;?Dp<;Bas@9jEsfgjJogaMJ83RMQP1K-jOBwU@^X4M>b5-RVWENrHYEZ&1f} zyWMYB%ZJmF$cz+0&XOR&!v#Tv{bALAGA)^10Em`2T5F^Fmoox^I`)UdenVe9**ZE% zkWvPZAedYS00;mM`~Q8H1&`Y>6o98P*HLZ1=n}iRWq91vja!Ta`eD_ZbM&p8Wnu(#SjZ(@Mb;VP^`DsK>8R{+4(Gr?AbFmn$73CX+a~_ znzh2m$$#L+n`M4U7HTa9()hFp+F@ttxN|>>W;5$y;O%S4`QhQ{yc_lEQ3I!L917T z!5J-~mKV6TnE_M~_(E;SL}(>~&=`eW8r=B8edrXj6*Vrjl- leD(0*OWbtnmhNxGSDL>+j)-+8iU0rr00>D%PDHLkV1k&LW|jZ| delta 2056 zcmV+j2>17x6qOK=B!4wfOjJcja7;WqJuNLRVqstWdAV^5*`Rv9kAG&&k2HR7T=l+}y_7}1 zbR04=G9@A+EG#T9FE2<)NjEn*C@3gIL`3-3v-;e-@5ZC`(XQ>mp7YG8+M|Bqt%mBm zmJtpP9~>O!w2#=hm`qJh`r*PrK|wt}KQ%Qq7Znxu>C#L*F*`du+{dg21_q0GWc>Q{ ztB!ERu$5UzI)6bgAnn<|X;MR*bV9hHhIw2=Sz21tm2dmy$F_qv$%$jth#qKZX)PEA zSwkDgq=t-NC+(jq|Mc3~uTVQC2JZj>04{V=PE!CA%>CswBnSQFCH!4XN2(I(pHAm<#IljQ&ZgzKJ#QKhmLkX&_-+!^e$`c2RDkerSDzoDY3WHOnG zQokMuk@@UV<@h)j^;o@nywZ6THrxvo^b4oCyn!50!I&#I8tdt97+@}JZB z&)YpJm9Maj$kJWDdL4g!e2fE+gg8V?U7Dj~5Puv}BUC_p+7#VZtL1`7fP6?a3@vaX z1BkR#A^}?z)CG+S#C2VUVVezF#ApPvtMi}tcPRGKI2;Cx1O`8_9D(JUU5P)~+o3qE z(kzCu5Joo%LQqcfu_5vCT)5&LD5yie$%|!*D zmw)~SO%f;$sjZ6BYnsd%#)seyJc1HXTpy&iDX5D&nFbm#5Mz-lU#+5p?96n2i()@j zbODAFz(7Lr+Q3T2g*u^V8kSL+=9$Z5H;Xjl?oAI`EO z$BH0vozA3F2T8h$R}kOFaDXX>&1CQG!+&L#VMS0llSO84 zvmpxV^XMweh>Yk?UC}pm|7BF3Pb5fVzA9%jv;o*;%+Zt(_a@!j($1@P1g_wHF7k{Q`#>!#bLRdkF zqR?_pO;*Os%=7c0S3?PEX5+>4^M7dREAq&3TVVy+CyL8CV`_@u8;nN%r{xUCCpoM} zgZ{KPR%Oebeok#uoSocHEluyWnQ6yy7Hx2#WY&9vdOl@_V?*!EzwB>UmU{8p+NwA=El-t)!}8P9^GAQ!hH`*qI9%a9sDBMTW1d7p zporofDl}!-&b;1P!*3uU4BLy>JA2rc4cqe0!~b0TadvjK|H-m+C`tQU8@_9S0Yu;M zz9wsi?OE?4p->bRp+11ZkQD{%Net~aI#34NR8wv5(_Umd=ayv~kVY*43~e+ZiXv;e z=Y61dDE5B8fyI#54n+osB7bibhHl-!Ja$m%c)Fo!L7436nr0iDBvieei0(2_G3Q2C zwe?gK+cZr}TW2I2s>c*lyA;t_e`V{q8VX8e)z&p-lZ2Y-7n8e^NF^M`v@s1CEEtK^ zAvtJ}#I*0`BRfbYTFxq14H-3>reTfI04tH{J4|-xS|pE)iFFTa-{<}v8VZg zWqAb4v&=Z0?c)cf9Q8AT!-GdSvGaUGGVQ-BVvq2+mtmXkbsOaDNo?AA|*kNUz5u2GWty*9!1)II$le!;|k}Ay}9Rz+xNJASgx96Ftk} zll+eqN1_NT&S1l_Y|yTIaFd?6L{zXpoXIgJ!J&u67d*TOENKvE(T5(k@S~+D6yE@e m1UCQR4MN&P&=xkk>wlXA58Vl1L*W1b002ovPDHLkU;%=lHq(p% diff --git a/TMessagesProj/src/main/assets/emoji/0_663.png b/TMessagesProj/src/main/assets/emoji/0_663.png index 8c53f9a4b24baa1b064ffd51fed819e462d695c0..c81b14c64976dbcd378b4ba014f1c5fba8d61c93 100644 GIT binary patch delta 2484 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 P00000NkvXXu0mjf%^J9M delta 2025 zcmVY;KQqR%2siYhYS8G%|E-XfH4@dD|ImSI zY-~9(ErMuPa85JKeHAe>GnaBw`^|PoNJx55I?RwWuYE?|sDDOQG8%6XY zj=Mi^@4eD{SC{Sl|KE_AT|^Q`3sTO>E6y#PeII7#4my{u|5{`=mC9sNS@Pw^Y$}sJ zJt!1*4`06>Zg0On+$|iOrZd@1EE0^F{qoUKv3UOZv-yDXgoQAqX^x^Ontntjgq7Ka zPdxwf<$nk2;obRbxO=$6GaM@{=Agx2HD780iOJmdYm6fE&vbtM-zzeeIba$M zp02Ur%As)F+rtI8YcxY2f;pkCh=8$7@jXhgV09P6pD+FGg`_+ zHdkGbAS)~d2qrRfQAfZ*%B#kZSs}Nk7{39cnuDVA5OL&=0W0B_73LLkEuu818B75Q zOMl}}oh2+zQtJ{SD>9Y=2tReFAYf0%tvTOche+-8`+Yb`Zbd+o0E!uMjfMvbNrYFw zT$VE-5o%Va*W)P}ohvP{v#EZk)3Ge=Q#Pp-UoVc+P0wo*2(c_m1}D1FzhGurvczKEsIcx9wX*@DV zhA)mo3&4gMb|8r4TKx9y;<%iLAiUP7AG#xBtk=8U7D(4cV>EI#OEoM^C7;w=|9}5> zaq%IKLA3mF{X3{03qZK7>kv-cBAUdfqz?b(>*dA!Pfg90M7=BdzNFXxlrH+dB0_-( ztw|)c772*U_XW)|B~cvTjh%2@@2&`UBgeV9^II5(mR^fE(lkK$gPWV1>)zdCD*9C$ z_SWFe7Xytr&n6qxl2M+Pi)cvk|%=hW7E9l32o5yh6? zMZsYpB3kRMmME!#3DsP$)VT-607gV;i4aA%^%sQs4)WNbqGqa5COSkf2DT^}%8H=a z&3twffh=0C5rv`a;4@s;HGicTAz~g@KD7yvJ+}xr6F8I>)}y5ww$%DF2(Lq&Z9=5- znihwFfyC<8;}{e*&^knQ6XFaIglWeNNs<&WVo0#VAS|m{-dKxNF`xGWRROy=vihJ# zKlC9BAhb0te*}qaQtB*y{tg%j896f`cm@KXxAVo~(R1&vM{Z!p5PwBgqe)Q>vzUVR zef9;o=$ZzY71g$Z1v3(|FS|q+ymkQYrEDW;BjII?)4Xd2hGE-=Z2;h10SGTurs#NX z+XS`So^t?2c)3n3Ep!|QFXL7xz4dQY&_YB2L9?s^`LZyw)l#Wa$vbWv<+`3jr4cwZOVW`7XNG(7>Y@+YM#`3%5*1uxyv<;*njL~J|}PiFB4LT<0J5pq_F z0C+LuXiv2t+hWMc@-T*!QfmqOCwl-uKShH~Nr@!6GrS9PKv~T9PWIOjs(ZNwy9CVO zRWrnhFyg2PNpUrRKUgcadX6l~&m zqluYuZxc@ClwxK)k1h%xMsNIc1`)VhPBcT$xPzyQdB^~wF;nJ4q$d2lv(@G)3boN!)FAQ*weaITkCealir4SJ?00000NkvXX Hu0mjfF#?-R diff --git a/TMessagesProj/src/main/assets/emoji/0_665.png b/TMessagesProj/src/main/assets/emoji/0_665.png index fd64f735f14a23be09f551fbda84d796eaf11b0d..7914380ad21144fe4ee243ae4a73bdc3c6ff1ae3 100644 GIT binary patch delta 2293 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 P00000NkvXXu0mjfgovFr delta 1884 zcmV-i2c!6a66y|+BYyz@P)t-sM{rC!E-64fI!Z!7Wo2bAE-q42Q+RDMfwcVY=}B;f000H^Nkl2XYV9j6xZ*RZq)9Lj3Wi~2}dZH*mqS)P_Qex##@QSy8|9wsM z@}h@djoIw}KA{p6Ix19x0v3x^1*`CH#7()+zYFhYvzaW*Jy?1@d85(xqDO@_y;7up zx&EIVg@1hK-N{W^;uU#R8bYPLhU^BriNX}+_ya1c=YKBeuXm?hpOX^36(U$r}xjDde?GY))7Ji?_TKgQ6i#Y@R)m3 zNPi3Q{pvh-4*@bB6PHh5q;Bdj^+eXQ#C2V(TTe^z?&@>S0s=v-K@<#PSAm;Kh9A;k zr|RZX5Zvvu0R)~xG}lxe(+dW!)x(F&isQi`j$@5z7E>zX%krl0g5Rnw0K zmK6n_=|JXyXe2WQD+C0W7`hV?JYAiHj(_2KrfQpnkk~i;SVJkPd%`279q>Pwl1uvPN`n$iInfF7uHQw;;eaBtE& z{QdXmt1mY$iBx+s3H1rJ?}Rv0JJf9_CYGDlS{xA1=M`7;Rohk{m$Ts8oleaRFn|9x zn=O})ts(}=Wg@DC01>X1%jK9n-feQ|kKeGiR!cSXG`Cqu?QfPMBA%+Q7R0?DkMCCc znlN7x3+wsf&M}DfF&j~h2A(rrJP|ZwJYCFL412ZGupZ18E60eVk6dOUIrNb;d0KoU zBzSpUJnHlf!TKv*uNIGv5&4y)On*c@3VcVMuAb)M_3PqwI$0O;^mG?KgBYrY@8#0J zF3!)-KNp&TZ-${he}(2c2-7JT506+rPQ%dge7~M`D&UT|k3nFlwr-<0Y(}`dLk@ba zhqfM?K-7-1Ri&F@!$Aea-F!ZMSTA(lrU>k2wrb7DGs7)I52y3_#NHvW6@LNhIG_sg zQHi~_*}$oWvmxjq-qUj75P>_&* z(mjrR(^13FHe$jwP<2KKh=10sqL4$X<#Tvr4M&BHD2_=SpkGmi;WsOl>d~*MP>p=U zq!9YW&0r3is!~Jy{_+9168Rn=j%h$__JWk}i8KUP83Yt!n)D9O_rjp8_W^e3wPK!_{c@5LxI@PCuyqKOj%Q-ngA z?Tc39SGR*}wAw`+*hezo+Knv2S+OK148WwA zDw83s?@)?dDxRe?xPObG+=Cwgo?kl*N|`?Y#>9 zgRtC@lnuZ7_GVs6K=d~$)}HMoZV>>oaxUNO^?X<2f#7#l?^UPGjFHtr@6_KyR3#wT zeuA_acQemsioytj^kyX$=I-}l*{a{)%-b6qIyfh9{xj_!L*+6Ze%9`>&E?6iyZ!;? WF}J?fEXp_l0000gws@;oj)x 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 U_N*B2iU0rr07*qoM6N<$g7E^tbN~PV diff --git a/TMessagesProj/src/main/assets/emoji/0_669.png b/TMessagesProj/src/main/assets/emoji/0_669.png index f92f130421993e8a77aa3e62c6a8a5c39a7c813f..159e037c6e5452dbc8a65be0be4f0b92e6b87bbd 100644 GIT binary patch delta 2403 zcmV-p37qz?5AG6>B!5{@OjJcja7^mq+vnxtE!C@*(Ru*VpOh;O*+<@$c&8(ALw;(9Xxo$il|NzQe$}*wf6Wqn)6gl&-6zySTExx_`5@uc(-li^#{p$HTso zgLlu&$a6?Ey}Gr}%fzsvnTU02e`Z&DQ$2D_HD^OEV>}^NGahe59DGnKhFCq0UqeeM z5I7tRpKMUBeo?1#R+wcuFrNH493YQ~jp zWI!s#sE)pwet+Debf|Jo+R3|$Uqzv9M4o9<*~6=>fgW^BHkxNeznwVSwu^&RKjNo$ z*`I9GmtwtzRp6s<$ct9qpJ?Z*cJQ-+$ca|9}7g|NsC0|NsC0|NsC0|Np`N z|NsC0|Nq3+|EUk|?f(4#{{R2}|NsC0|NsC0|NsC0|NsB5|NsA1cmMy||Nl1X|D$!+ z{{JlK|Nq!xlk@M&|NsC0$N%>K*#H0k|NU@M7hC`U2T@5xK~#7Fl+3dM1W^D0(fzi0 zR{u3F!+-P3XNGS8M3`(S9R9!{LX=X>iI7Sg>t;qvfe{4XYXI?_dFw(5F|A?@IhWdU zjO&OX_F;s$w7K-%{%~x0ek^inr}O1{yWe`P6kE~cg)`W1M@vdo{C2q7 zIE$czw~wE4*?TljxY=4eRw7&g9pMg0=j(_2oIArf)?-AC)6-C)9FAL{_;Y0^-sHB7FAHk3^;e*SI(P&hZ<9~A8s4Sb~ zyZ{i9lZ_WK4Jfk#URfoWB-4C+k0_=)1Z_{@f+w;cMa*^^MA%D`?M(eWz4s#jtMhdy zBi{o95PUy|I0#hQ5UP)vWSKI1dFw>=w_+-j)%U@9s_fxLERH~w2x0GImSvetKfaIS z=xYVX-Rjdkc&2n5VNiqkG=Gt@dwle18%e(RDVDN#{P`zowkPDU~eiB6tIcXXb5RITi0o5>aAUH25x`_70%M(P1^?!h9ASODH zkvn+3=rP7w0MLgUE>0IsfY(wp1MNFRb$vqr-Zv+M>E*CXnwOr2USI-X{sY7wlNzMqwbtoJt7>i)ryu1a% zs@8IT_cBrx0WS?9fO)V$;1ejv?D~PQTHHNf;Eg`!`r+~WUw3&5shZEZw~;-Q-7f;NGmoq@KNTz15p$|JQzpg zy}N5`V(X9dt=*yA?91g23kWcV`;y&#*uI$wOqI7nyqL{yj0*WVw1@!UJsKEL5=QJT zqA>MLW95%N&L&TKjY{71UF$2UKw!C$F&vvf8T%477+4kv_M7SS7VK9wuPs`_(aKp1 z0SH>6EPq=LJj6pEr;{hr(v6%^UL*;Gy^&g;I*_deS`^Yq;;yA#>6Eh(HA#4z-&7i3 zD2-EG<6s+>X3dZUDOajec2zVqIgZq8u?tDUgtW#XwH&_Yns9_|k%Yg@P{G!u43ZlW zks2t%iJc19CP~XA#PYnclUWr?lJpRX0|QvS^<1HkFcL`OiY=t delta 1953 zcmV;S2VVH@60Z-CB!4VWOjJcja7;KjH?@6Hl7MudmxX|CTq!9kuB)MBWo2}8Zf|aG zK0iNDP*1a^jQhuDPES$YqDsW6Tu4eyH8nQb#eF_MK%jqT@v=s7TuG&FLAP~Fb98lX zZ*Z`2N{?hmw|`H$i(lc>jAUbD#(*cIaR*RRQsKaRd23A6#(#pylW%NoZ89=5H8nNg zwvb3kNiZ-m*r|ftv5Po3INGj_Xn$EP7b^+`(}*8iTwJ1fIkbdX^6~J+kvX4>bGDs_!G0&qxS#ExE6=!V zcSZ)}!kicw7!E3Zt^fc4D|Av$Qvl4ZNE0FM2>z7$tZpVfIN|)uAW9FOO>Hi;|!ax$C!@}*Ll&4w39rQK*ZX_^6Oo@UDNJg8QbwT0hU8C+jq-`zoU zIGl~gqkoa-)d7i&9w0Fi+Pq&?JyC4bn9^_ra3iis;GWVX1fM)pQMUeFOFC7ozKxen zg_oM`#(y~vXtcRzU1By!6{*-$-n>nvi<^0~R#Rw?Yd6j_2#y4ZH$7UV%Uhep)QVXJ z1&moq`3tEjD%5kH$>ku-)g@l30Se9Sl0bwa`G1L4YN$XUqcR?ZLrhw#b9>1b6jU1% z7_KP@xtglV^Qvm{jMwCHg%=drHf>_mG*uoJ1R{BWB$1ExCYPb270Kf!0}7RdrC>!g zn>c!8Wz@NLCL67wG9FZ6^7z$Z{t?u1?epDqq$1m(Re+Yf$28Y`Tv?!K?4=?V-#n$J zn15(^vO3#=1BQBricloeU;86Q0S734iw8j3tB=OB!TVK)Rg^lqrrW;L0}BV~ zFz;Hnu4{`yCqfbXain3-q-G3QK+8pG4O=ekH5cEhz`iLk>9b1rDVbSmR z7rJjuX0x89>z8;Zih>4;s7CG*>90_QCW!s<5*TYN)M5)_>tKn@bXoAD=HmUs*~bDX zpk{fzob>^=)oQUY{KT3L#><5$*n`3MH>(t%AI|O$KNE$hY3$EOz=5Nz%Q7lTD}T4@ zhljJX#QPFah^*XSh%5#J347bWZNVJFd=3)nRkMkTlh36AHqyGkshn2sNh!p0dowz{ znaZHJ92`+mifgTd3UNNp-JG7@PFta3y1cENE~irg6c_fNsa5NnCB3&+iA?bP7+z?zz_C%ANY* z|s(6#$>m#mb=YUBjYQp9YmnSGd@KVLi~hpab^o%jqXCO>sn|MfyQB=1EGEO* za0mtw4Z39{);xhG3@dc7(7z_Lp}}`{sMvZGuoX=}33_l4z+hX(VQgKtcMRXwKtg~# zF_1Q1DVhtRd)=- zu`J8CV4E2GRP5EH)75UzbzQ?ST({S)zVe+UNp0^QA0JGBE`ZmA<8N7N-N{H(**!dP zx5r%qSbzqe$@j9WmTWQx!Bp@4#~DKKd&%qn04r5e0pJ}UkOL3RBdq~?5&00000NkvXXu0mjf8{VVb diff --git a/TMessagesProj/src/main/assets/emoji/0_67.png b/TMessagesProj/src/main/assets/emoji/0_67.png index 40db0dcb83caf72fa808a61db156af4dcd212812..4368cff9b25b160fb615442985e167b4a090eb7f 100644 GIT binary patch delta 1371 zcmV-h1*H1q3hoM!B!8SxOjJcja7^xm1IcR%$Y}=BdKS)l8^~=9#D6i^eH6xeCGLE(C8U>Dr000Da zNklxTFl49C2j!A@*1 zXCy!2AZtrdrMr`{rG-;2!6bb3wbP1{Rl_y6R$3s`pnnvRa5y+JvSQ#8u^4w?&LMv9 zK*KhdA1p1>;T`l>hS(V#G7mjo3Izx55{!FhaIH4U{cG%m5JvQl8e@se zO&9?j{C}(XA%vr!EnbDj05Q?rjS(qTan7++fTHO6jrU9D6x0ze_(6qZkW}dd2cT3S zw{~oAMUOF^k5nNbpdZ*T9wml7_FK#|!SPNzLh!=lQv$9aO;f4h-=MI^zL^}HvEprP zhhe;gipw|*?f6zOxG))-U9buHrqm7;+wJ$saerxtm!W-O-te;-JL*jvhN1wxCc(gz zI8@rpgo1=jutG|y`Tsv|=U)3HZbrqnr=6&jn)K80g+92u_rp7uE-Ls}=en*x5A#m8 z&5z;K2Q@qdz5o4i+)eqpJIWH&oxi`{9f%-Avzm&=ZgFE5&Zl7> zMt}8k1#u2x97XWEixQWd;F1Dv3_*zNOT}q|*ej8Yx5E*{$Id4J-#>H~Zz9}r8w4dd zPxErU?PCo^q=rn>&yo3Hn%)DTum@q{Jl8Wp!(WaU9|;<|RfpF*2qgFc-;%J_A d{vZB>@eBEsQKR4+Ry_a!002ovPDHLkV1gf@j*tKV delta 1361 zcmV-X1+Mz;3gilqB!8t)OjJcja7@T)1X867thXj8h3-CjkH8RsYyV{g?#$ zsS^IL6#w{w|K(`^_?7?kSpWK||GWwR?Rx+AZ2$be|IIxA{eRH^!#MxBC;#g^|Fj+T zq!Q}dLI2S)|IQHq$}Z-^GymW(|Ni6u*fRgWE(TG*-2eap4s=pZQvmb8_cWqb{t|zh z($}{GvV;Es00dx3L_t(|UbNBaZk;d?fYC@$2OH%9#{0%{mu%hM|Is?*ixOX_p-HPA z`46D^#K6rz8-H&8zXARIaL>57D+Fi#r$Yl1 z(SW!$38zoN#(70^^wSA5$=rS@GVn_v$Mt({wooGckL&bh1@JUqTk%BqlyDukUtk^X z@WZbgnxye{69KpB_}&siVIj}!jAy-ucZhvVMu}m!@PFv%InIbO%{++`8+XG_LB@hA zt+;{r8&p_)tTgj=L;U_rYTTlT{o=od}3`TKaCpO&%u>WkclnY5>0P1a%WtnT|=2?=Q5e>`=(5sbJD1;Z~lfp zgDa+uy?;*O^~M!Ptwi$@`T&5D;3hZia8v*Xur#m1l`;~DgWy64Q)mK#4n2YZg*+-H zu6~C;N?9TSLWSmPa7johmxHc<3Zp$1N#I109e`v>;3lm4n93ZMr9?n}een=B53l#+ zsRWkga8~L|wTJpui@oh8t^`p4JrHcL#`2wmm47i0JX!5aEXV5p|4*CR-PJV)0?b9T z?L-2pR;tPoQZpzv`l>98f^Pi!y!4dI=LxS%TxIqCu0bf(jXx*ZrQgTFsJWfA*8QHtk96x%SkE6U-RK3>IG|$G+e@5n) z5r4fU4}A*N#rvy5W*Tuzxc`p*VW6#3KSy71z-g_ufo;k%>_Y7*Rb4zzS$<*+ZUU>2NwCn7M>(F34|A$WkS1sjNknak(fXQ6=rLLP@C#3(QXxyb;)3T}*007-OZKv^+^ z0O*0oxKDs}U>}0`oKbE85rV^4#K9XDA;n!tgL()U0>T!;6GM=OYq=i4a{&hJ!y`~6 zqXRGmPw_C3H-LcQ>=}Ttd2y-<Au|Nd)+zo&ly{!emv TmVNP+00000NkvXXu0mjfs}Pes diff --git a/TMessagesProj/src/main/assets/emoji/0_670.png b/TMessagesProj/src/main/assets/emoji/0_670.png index 22244846f5f41728e848c0054e64a8d30326e83e..182528169cc7dc1145ef66557296f17af3fbf2bf 100644 GIT binary patch delta 2253 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 delta 1853 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 AkN^Mx diff --git a/TMessagesProj/src/main/assets/emoji/0_673.png b/TMessagesProj/src/main/assets/emoji/0_673.png index 75ea5be747870ea64ed021e66cda364a67fb17f9..13e09c158ef53ed8815db0b2b4f497989a4330a3 100644 GIT binary patch delta 2040 zcmV_GBGi4aBn_4IV>tF)s#3PAR+v;ML|D4Z*X!jE-$BS8F6oE@~k*$Xl6`GNEa6u zJv}{IT3c>jK#gA{^|3j(pI}~DK`}8gEi5cFGcz_eHYq45C4VC$L_|e8IXOQ*KMf5H z6cZB~85l7xEg&8q^Ukc)mu}*%huWfj>b;rGjb>m&FzB|C1qKLPTUzbJp-D001L&QchCE(Kg%k4oYz;plr28>BWK~#8NwU_655KS`-P16S2;0?Uc82rQ_RH^>f zj#A~vmw$FmQ5;#D^?+G##^~|CU(5!Ok6dq`R*x&?|7y(Nzm&zw@u}*%3enLsMqtl@ zXibM_*CDu++pVZT?UkX}mSx$lN->{ttA)XaOcX^`RacQuctEj2?C4arnZ$No6+8wH z&QSD@_=%#Tfr6nh*a@W$Ar7S!Zpb&KPZU?0jDL|7AcPl$&cM1L;2_4)#|p8Dc~gf+ z^NP@5W9TwCsB!hNqNM2#C?t&LXs>`n0)>1ceyF&@aic`i`O{w+a0jMAI^_=)%>gJJ zBI_8AC5ihCmWND;QTae2R<2zbOO-$pV0dGO8%PWZisrhoKg(YqepIm}Ow+U|INrh; z1Al|K@IT8|n}tdId^qnA$DxX9b+>C_0}d9-1+r^lIQI2Tr6`Lp4}$DSFch+7H&&|^ zSO)LoU5IAr)uJ^1xnEKT$3ig$ABf}CdIv4pIHn1YC#=R~P{^Hfk>YWzII^KRX5t4y z8bv|q&l`fUUMH@r<9HZM0YiRN*pNHL(SHrebmCap>YM$fkCqr%C8kRZurLKF__m7J zom)ksrn72ncFW~>b2}P({U}P)z~3f9qS%TA3g~g^Cch>B`1$aZs45uz$8a*5PKU$M z2qYd$20W0OjeSa~Q_zyHKOY_h%XC+BKbYJum;2Ea0LjpsOz_5I7&j6V=MhD(7Jn+v z&F*$S57T82X5n#v`YM4NyWTGL=jgC((iDpnf12F{lGwEN`|Wnw8fK2s61d;(H_)-$ zuI1Wl?y!oPViyOy*7NpddoMiir<|9UW%6==zkf;mcnvk~s(LAJOi}S zcZ(N~EB1#S-e??J4ZmTbLpmzT0)G`@@UnOY!}ff!;ELh%VTnrr@a!{%X*g&*RWzr#uNTum+!%^AxV@sxCOp zEvCU8!!!&gBW{>PK?4K;NPlXjJcY_}EmMHr@Yrn8Ptz1r0s|xwJEonHufQL4Tn%7T zAPsLAtbY-rAq^8SuvBeZspKiBLIFjErnryj@ci{1V-=wx*qOGgW++E_b%6qhD$Joi zMtx{Ya;0U0(}v z>@#Aha>2T;)#~+M?|%Z~C+{O->FDZPZ`Sa`3_tW6v);*3sVs^R{5gMIUW{?QJ`RE) zWduPu9>8My;_{FGNpOLSZd_MsAqXM>4v&U5KuPQ3Q%ULamq6FavY!#9JsB5pOmbQN zIE7XV1e(Fu5z>A*LHd&=;cH=(@I;CYV-)Bz3c#V=4xz@q;eTF-iUB|al5y(;$3<_T z@pwd%iMAgCd*kgMN_rQ?NqmFPk_`4xNnb{{OBq2&CNaL1iWHXvqEJfy14Y+=yF;in zxGXS~JF=rv{zZX30(oQ6XBUtH9w;eXH6F{9C<=?kbakC6@JPUeSL^^;5dA7&(WI!r zCrKnr0%PAUxpBz>1!?Ejd8MXMhpH4ulk!=?ao7Pb30^WiWm8Tiw;k+-N>#AK00%b2 zfy3+j9Rc_Ua+fG4D#e!Ip0eKq4hR5>u;HSpAoMg(ajMjTS}ohd_C|KMj_}jwtKi?N W!tpNvrxYpx0000BOhw1vCw`_Z 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 a^EVom(L1@HkX--(002ovP6b4+LSTZqbN43z diff --git a/TMessagesProj/src/main/assets/emoji/0_674.png b/TMessagesProj/src/main/assets/emoji/0_674.png index bd3bcef0ac12f9f035f15deb19bacc22003ba2a0..dd58c5728432d514958838fa69ca5bf2780d94fa 100644 GIT binary patch delta 2248 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_675.png b/TMessagesProj/src/main/assets/emoji/0_675.png index be445868dd6a55da61b3996d98d6b33e763c660c..701dedfbf35f3572a432bc5da4d06da8aa6cd406 100644 GIT binary patch delta 2031 zcmV z!;D6KP%&9NDI+8%U0hqGZ6?2xN%gTgcTPA)Egmi{Ehs1{Kz~3%M1D37ivEswSi%|hGVaJTrn{+R5m1~aaLhJD>NJqgH<`6Xi$Y*LXlxeHa0eK zMJ9MlDZPwlQd3iYP%j}OB49WhOG``k_44A`%hABE9t{e{m1|{XWx|nZw|OAci6POo zk&SFujb0qZoPT$cg?g`=datFOrh7Z>pe(6p7`%=l*M zB82Y#MgCUztjMP4iR!3Bq~_hc-r2)8_4C)z^Vy1k`yQYG00wqRL_t(|UbUC!cHGDj zMm>>}DGk@;l3WI@yODE_lOuDKwEO-K;;IIgW7)vS{(s@i!yW)cU3}H2&#>{g|1Yqd)Ke=V%k+STgke*fg;WT*<#!EiVj^gma-wFYzTe`L4XJUYKV>%?*L73oZ; zOCfbqhT{weeNaKJBGu=?;A+_UgK_`$%k%S$Xuc~+f*?pKjFKQR;3Q4+RMpy#imQXU zbMx$LOMgIBRY8DZi9ZZ>2;kN1NOCy-^S|{`Yd1d)u6UkH)#D^DYSe4h{(L^?9Z3bvErKHhs@b!zptw;yt*F43B!0f#Zb8JQ!nAeU>p?Nj zDbLT*p7vQmiQ;!qR8Axg%9#a#z9cNp;8Af>DSub|f{L~ZDf0Vy05v?vagGB652R{s zj{+O1swt1KDknuG1|B&eafI%EMSUPZZYg&d|q2PakcD{895fx?06k9t+jM{uB` zU*D^!f&w$J@_Z@fiwqqY!#Qc}Ra~nnDsWA!A1pKS9FEZ5qo~&|T}pW#6|D3}SPV)p zOMexWUmu#y*?43aIt^f1?F7^16oBPLDRo_6J1PzF?cvMWEJXAmP!y0r;m5DULA~#5 zzNW>$l_(mY9=?RLSr{jwuE5iDN~Psr^%U#19MUX{asFnGnPMbUpOBD@7Otd11DqnW zasodZ#yBfm^E8IDc|ossw>(#Btmqgyb>0WsTfFkH%p<(?wVF zsjEe%jTS=l9WQ1{tVJwJ;8eIk8OJ#xx{QTv=X>W-~I@jM7g2 z@$KRM*)U{9aka#}ySbT6?(QZN3pG)a#Kcz=QC}E_Z)g|Ao&5Uk;o-Y3DuLoBwtp8V z-rda|Fae8cnjW@5VOC^Wc74(;Rosg~5K!Wg4iH;6kcCOi1kP_=pE-0YUheG81&n}12>cw2SgT>QG~xh~A9A{(=ASqfBW(c5YxZnyIN zY6S^Uv0gm|pnO?v2r5KzF>97jrvi$}dgU3<_m8X9%T2CWkB#R))~lB!Q^?~&Mf3jt zy8#M6vL~C>=5f7RJwgcN1sso$>-CGB_^43CQQ`XR>LQ}JiEUahkDJXSwtta>r!TO` z@)XLVP|*a13<^p-)3U6|-A=$(hXo7O4s(TkUaXK25hla7U~y-aIAjuBr4gZEK+cL3 zf7fLlfKFnFF=2Ifr6#5LXsrJ&K0H?x+p-( z6bnQaVL~m7DJGFi-PmG>6MqZ=0!RwuaivHB0>dyMhs&)&>Z2M%@C%(U^fb^xQG=Le1C01Z=h!GXn-4<9~0FqB;I>z;uWt z@<3wQIO4Zw2+IZyvssu+vKTmzzD9`V;x}p*0u3SFcUrWx>dn(x2%sa2fl!4JD7wxJ*)11m zW&aYp-DdOX==}8b_<#6P*KsodXugYU!(AK$r)TF!&1Sc@{{^L9uQ$4f*R9s2M#2~f zp%?$M)jI0dDwR4E|D5*WHSC$E%VnHI8A(ExQ`k&jAGZHHK@SADu@Vw5@)%J>1lW0j zr1x`4g9) z0s@C2dCXxw;T3R#1@>^a`y7X@WflOz3gO8Dz_7aplGb6pG{midFzXZl4tK}?ZQ6T3)P%Q10HcZ z(2YW-;+ea!lRnSx#*s&GoTHYVcFH!SLW`4B0Ro9t=JN{{$Cm9vyI(ez5=m N002ovPDHLkV1h|Hww?e0 delta 3113 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 Dg^mb< diff --git a/TMessagesProj/src/main/assets/emoji/0_676.png b/TMessagesProj/src/main/assets/emoji/0_676.png index fe42b09487abfb128e0596b1fa74d5baf7de3295..529ce614fcc69b0a45578e0996f87037d3b6abb8 100644 GIT binary patch delta 1810 zcmV+t2krQt7@!W2BYyzTP)t-sM{rC>K|e}AG%+tQTwGjdN-{w=F)1l2bXYfNX=yMk zDoH;&OF%k7H88Go94ss>R7O12lsIW>Yj1CI{j*5(tvGL6MrdYZ`L{czl3O-5H!?Ca zFfcGdK|&!I6ht&FDJdyEE+{)YJSQC)EiEleIx#LH9X=rxfPYObi&ZjBD;Y*dM^QgD zbVMjNC?b_Q{KT}jxBO@al5)eyFO=vtKT1Y&&gn zJhuATQ_HIBtAEb`00rhrL_t(|UbUC!V%tU#gag)IEXP!W-g{;3MRwl*nKF9^Qi=mm z@sA9|qX23?%^nxP;kW-;?VcbsA)(j)MI)TeVWTq`j7H;eq?q0Acsd<)8pCGqIg5R6rWbUL1YXPO+Bi+{{d_WM{f6-6;cQ^9r@U}l+0 z_zBTn%RjPsPl^;MB5k8BDJn&WxfD~@_0CUq2+hWqX;;@}G1{(L*ggvTOgIWRDxwt4 z-oJ|Z{Y$UiYz)@xwJw_xO#Obp)yEqX?AyqcbiF%hG=-XJ1%gU4b#()+*S4r^nIC3F zl=U@97k_8mP><-1Ona>|hzbWdsG7S=#HjrVq8W*$LB~dB47M#pwyi@_Bz%HsC_w0N z!G?xlx__CH1cl|3PYZ8n}Ggvdl(TY?+n_K3YA;!q56)_#g; zM5at7zFJ)k_5PZ6D$>bl0dw z^uE0{I*z7kM(SF+sKETL)r#87c3n43wc6(Tz2BhtU zx)fjDve;qgs;d^BR}`rUH)+fKuqmx>Ymx&^ydia?`Y zJ%7R=gk!m3zDs;R*%8GpRMj%#ee6J-;SB5A;>{;SY$1e)VHX695{90qss`Y|aKx;B zIzuhiEY2ES5|9p(sI+gpgOL8-L5PT*K+qA|~nvh&%~bD-<3qp#_u$yZwIN zN<9|DRb8#}RBJN?dI}-D+vybMw|%xOA^Y3y=FJbO$8xx?G3q@<(|`5s z6`OE!y(||DalYP)%_jMAJ!49dVv{g36CV)UbjUNdPQ(TRRoic{OJ1l{nQ|KD5mV^?~tU|;Phad*)bU+{i zcxXx>h`|4>^0GB_VkTk`LVr~;kL|RAH?dQ4D6;h z9@X3u1^y&J&k)@%X3q;t0Z~|KcMOeYGg`p6KY1Q$3&WS!*2)Rwg3E0iea1NdO-kl+(Itg%$bd5PyLI;HO81*oOid z5{*`o5r_1iM|kA`_$4R_xcsH2@ zvdkR`Bb3MJARyb;OS?XVLVlTkNR)l=`+E?;ctAv@CDex4O7!SKAxL))2F`_Ow58~! zhR_>{^4f-p8AK9t^M5x|c~r6`v2NAa5N%o4nU@#A5T?lyoWv2b*r-NKZ6MZUMhfvk zdf&wepp2l>v@%AstJ|_ol}NHJ%lGNyyL>(fCFwF9Xjayt10k<<_-vY0Z1hfh^af!B zM`uH2C4;pM!oUK7AAw6@)8ccu8%dK7>Vtui0O<6&4l`5D*p?77-E>?SF9Bd|raELW#&*u%vUr z;A6knbkmY%l$JJimpyjtbJ$f&Y@j}aH>bySN_R0~aguJ9gf3)bV{@WEgUNi*$9m7k zc+L(E5F;Zb9UUGN7a7cb(kUt`x^cw9cgrp>FbD|=tY)@DL`4xVNKH>l!E?n$#onY{ zu01|KF*7$}Ie%*=Zc)oLO;q;q_annfhk~`ICgu{|)@}KahOpmvOVw5~@@tp7Ti0Fk_L8+aO;)B?s zhjz>{vG17dvV2{XU`p(5%yUXJzKv(uf7FvMY{Ou%TQ4=ciDm0^)50*N*=D|=Jb|@< zV9ssANPjIHdQLwk2La=2$Y&}-^P%$X=-u>`?OZ%5^?~MUadDx0T>k$3(7ch@#;$IW zlgE{8oEvL(TTbwm?6g$1$!@&fa?G+gnD>wEM;;;a?&yznV!9}np=?s9a#y~Va%Vv< z;Cs@wQlI{w_PLO+-$?xt&2i5*u`G=Cy=Emw_8S=VpJu6J8|L1lNT!NqKh znrTjUWuMP>%bBR4L?}+ls*1OXkf>sbbwUJ*I9t?kud0C)ie3QJtif7YSa+j4&gpsnoX}s8PJJh#RNwIIwD_}?cxB}L z_~r4w)z|yZz2D-d$ENSb>B*O+uz~Ebvp(q`rT_p4nn^@KRCr#r)kkj|M-&HeL6#{} zgebu_WC#-AI6lQefCTVG(AV1D*?aH3cYmt)-h1!vy{Gqj$SkP{$iYh~K>i1Um-*qn zH#0jm|7$LbYU@C1MVJ5M`ntA;)^;3%@b-p=wnmZo!a{8`&Ls+gYqQOqrlJ6(?gB&;KBXMz(+%VMB) z1w7@kp2hy4k!xaQxsQAldl2n>*l;o%vjjjuygy$j9u`g$BiU}x#fFrFD~0lHmnb1!|yuCK4Z zI}9T*Q!y$d;R#@{tOjZlS8W3bR(~apAQWZ^(=xj9t^XBjV&AF{4|)=TO8gbM11P+1qa*a z#4<&N;-`I_!5F8tWCaKyfT3iZNeCAzqh8`?fiXEbZrbbl<(o&lYYaA-0e|!GR1BV& z!eO{k;F5DZVM8A{iz|I!e!aW9OJgC~17pd<@Ptyy6B3#1wh&QZ*-C_reY;)liKt$)BUFMuTU;Y_6XE#{#k9uLL~84~Jj`TWBKlq|&8W_7wZ z!=K0!s&e$<2hrmYHi?Ej7!XKO0(I73|L`pMPbR9?9S?s$Jw2_eXZ1HJQWl->b2wbHdyW@wl^Ze`g27n-W7m_+Q-_Hp=@c$$6$udHI}~Zj^*M&J zj%+@l<=m?G@9#b_#DBD|9*0Th+K2#xqMK`katD@J#`?M(d5~vaf4ZT&6C2Bh!GT;p zABFq1G)bcr-6TkK!kndVV{S;D&u3rG%|WW~9xjgrwFC3{yxQ`lYl~b%DOmVPx*~&g zzeBI*`k%deIXEyE`Rn1x$cRBZpbb2Gwez~`X~cw5GT{eFlz+l?sRXpyH8iLl=-M~| z0w6}f|G`1+(DFgVf>NDgL8AT(%A|*JH@CUD`C}Ery2(Pavib$)yhnJ;D7!Hr>@Biv5k3fFU?(+r>AThalDYv(e zAl06B5rH5kbob|vhhssoGU#1gS~`mHS50pA`c{evf`7DB8wEii7I^=U-}=q+pf9UX zD0;w8)*b`GVjv0xqC;fXw?#Y z(A0i3uy~X<$Cm7Ym4N+TTAl_%_R+pnO0-;;3Y8&lk>2PakiQEpmzXxLC=Ayk1WRS( zq^Pt~X@7(QBx;&eiTX&zc^R~wi{Kikr`;oTUc2QVmW2s)*0$O=d13QcCP?}8z z@-nhiM=~R?iDV!=jD?XGJu{|~9tg{ST%47E6h)6Fk=Cj#cHk$`y zXv|s#L9n5NpYGkhl5kHqJZ!O8%KkAxtThQCn^lk`fkowKowu(ighJ)BgXfF+d^WeV zlz+?RviUWPSzrjey9iGJ>n9-O2g z84VRuR!U_c5?3TE?*90)Xy|X=`TohC)qhr+UmY#GT-9PS9*-|9EI`24V=;=OSc)Vm zRua&F;eQi)^Sej){dQleH14J-yE5hRY$gGqX{+k-oRv64a=<`VFsA#C{y%1X-5d4R zYNr74`AXxY`&HdjEv7FJCo#{IxkMt00|tqtjopgv+t!GEbR6b+UiJb;2wuZ;|2W*Ek3G%{xXT&(SELVp`+X7^OifNyRa9F?J6A$Cj(>E-yQ<{i*QcA1`}_K7 zS4-20Abn^~v4cForDE-%ET_rdm;e9(9duGoQvgu@sr@t`4)5)X{@iZE=G;I_%ZHr2 zjL_^Z$h>3@m<00sp~L_t(|UbUC$cH1}-gE!V*Voq{q|17<4h_pQJkNke6GFAPHGiJX=JV$tN_Tg6tJP(@%hM=| z!pMuXJSAf^*QkFZ=8v)XxyrXt5QL!;bHX$mh~Z*De! z>V}2>AdJWl@?!8G!TkMcFziofP8^#e3c$JP^~kKpg84d(ENPBl+?FCB&^|I-t{{e!NIJ1gisRTZr4b1e#ww`s!qx$qhZK}0ds*Bu6Mh`IyyiBAD7Z5J5hp%rmwFM%ks zVtv`Jty(dlIt#X!O$-Pe0Yh}#5lbMFD%qb-WxWsct%jug{l0iT#XkAr#<9~l8AI)b z?HB(3Se{CMbpV2u9`@UlUz`r)234-(^{*k4!aJUPXmva(#;$k1;JWy6?t!tyJ%5hX zX+`)zRQvOx@cr`ceBAPs=7;mX0P^SgfEita5sPW-T)2eT!eq6&JDiUfM(l95TCHA= z$5&()grzITO^B~pN=r;9Qo21I4~OIVxCeoB0RtU}OIZOyG8M09M1xGS#Mo`&c2rloPHhrg1m1YSL zG>+Yf=(;R&qpWj<$Z?jZ`I{q%1Jjf@0h@B4`nJn4x9^f`3_Aruvke zK&%iLjf+XwG^GiFK}i9lq*osOlMD$>Ga|5~klATMNLnS{7#SFOt0Xf-0n zl0}HvMph`FDCi`iQhO(uY9P^w5K?49fT5KCI~_IS))dT1@V@O5r4}iL&}twB%cWm2mmmmDI*4o6Qp}AsBq9&x`xs4Q(p$lx8HXuSG~Z`G5Px=l=?D-vfX* zR&1{!VL%)EUhn=x$Y8+$wYjshl9P(H-Qq1ELl%RNTmXRWkr^Y^D%D=ti^2eqtB!o` z_4t#8Gm8rFQY|Ke$&g;}3gaFgs0|etAx1`d*B~%LKo%hD&3(HQHzAuV7qs&P0D>6` z;)OT;HpF5rP=G)PEq{x}G3Z|6NGn*hWn*FpNAe>e(2^{VWYE=nFK%hu$xjU_Od#O3 zKnxJI5hFB-TWPg!US|kGn!L1X#acQaDne zqxoxK%C98Hgq?(dktDj(-*;%iG5K`bgy@=N01jjVhaZV9xGGbVq(XF?5hLjKmYN1} fuf758`^x?gJN=PzIa?*^00000NkvXXu0mjf;50~9 delta 2859 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 JPDHLkV1i%}g3$l~ diff --git a/TMessagesProj/src/main/assets/emoji/0_678.png b/TMessagesProj/src/main/assets/emoji/0_678.png index fee7e239d88efd6c29942047ab99563d7eb3eade..84a1afc3c4d0d85caa325732b05a9a802f15b7cd 100644 GIT binary patch delta 2063 zcmV+q2=MoT7n=}}BYy!nP)t-sM{rDDUtcgYHu%SDEiNumPEW|3Q=5ZUvvvWx%8VmyZEiL;Hq@CFJ2^KmE-lcOA!}-8gbRTai`=M}J62Y+y`_UK`h;M4E?e za$!E7e@WY)7%?$1H8nOZEiE%MGe<~BI5;>dDJk)_9YRAx>#!a5x*z$!B0oPr=c*dv zr5ZOkH`SOIrD+S7Uk<*35yy!X&5;&MOifr=SpCE%@3<*YQBxu#BRf1i|H>-gt14kZ z7kf<*LNg$VQGW;j%`x}HFJ)$CQZ5bp;)vFXAX!N@rhPmu83zdn2HwSp{n1JG>$UyZ zX8!rq(5zRHdrza1V(gtN7Z(@*)GipOsVe{g055b>PE!E=GDYVbBMAQI&Hh|T{uILZ zeltt4lAGmudc9<#+_<})+1=;w!j$N=azbjxcaCK{W`Q2Kf@KKwan=7onTi#ktT+<^rH`hOX`u43@yh7@&R!tK{m*;tr zdr@WIRDWf0#cy90C|6g-V(}7?I~I_P9YmI0UIbNPZ5dp-pB07qHunT^fFx;}rD>WZ zNi_+$+V)?>_5wy{ZF3B ztu71gwjy?(q3hXBL9&_V6>trZG|2MLEtzJ2EL<7OZh2^&6+4c zte{|&$RjenoG$%nNww4RWCe31@t}b902l8Fyu23Bp`c=OvZ8$25d}2h(iRoGf>WuM z*?(guDmLq!0EoE0mLUD@#;PCWCMlRBOTjYS4hW=IYKVje80)JO6qVfPL4P<@;7Xza z!*DG{ryUcB7grS+9;VP&1TbaLijc$V@WMaO&*?&f&m+Q zwr=Zcuau%-{`~&6WHteobsWbgF&p$RHE6+Qe=rz~*pVNHwyx_;?UBib*$SM}I89LU+}^-hkDPbl4!9%dBS;V6PM4$~gA>W>Sy`d+nJuc7w-iyTwB z^arNho}mW5quV=akNY1#E~3RV(*(nN%2t znPGNqVjB&h3sA!y=7GRT(lbzFyO z=-!CUPg7KO@L|L>Xf4n`M{SG^kOVtmSEeaec6{H{$7v)jcqzlsNibq(rz-Y+Kg2X} zRioL|o6TOc2@{$`I10k4?PONA!+p4}1_;c!e?}STAiz%e{!SGNnSVxprL+U37)U%o zLqJdfW$bKkS7&~W{02!Js%|@uJ^tuy=i&DK?5m#~-59ITg_ zUlHuVrW-allBGq&BNWf`ao^OcpDyi9mE_myu3gfsjw}{!2d)O*pxz~qdrm4@&rLLx z50)SUjORs>6Bi7fq82%xcU`%oNv+J%L3xs4=@ef&IxY%0k$iV1P<5{SLWddCdpZP5IFZ^%2nCo1x`^Q%H_cz z1Ig=*%yZy@8Gk+LLKd96{B|=70w~%XT@U);LKbLpU#8T=3!vZ%Z>Eu*helu}&^VC& ze4y=x8R!+53Bu}Iie&|R*;cS&C_|Ft`27wCfPO)Evyyjh0TnnZ2#)kXr(+@N(Ic$A t)rz(GIba^g`F}8nBwt9zwU@i=f8B)`ISSmUy#N3J00>D%PDHLkV1j!w*w+96 delta 2939 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_679.png b/TMessagesProj/src/main/assets/emoji/0_679.png index 79a64a1a08a01bbd4e8ec09bad1460a6c0c1a25b..08af63a964a42ae60a7ae6e3f94ef3a400952692 100644 GIT binary patch delta 2058 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 delta 2648 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_680.png b/TMessagesProj/src/main/assets/emoji/0_680.png index 1773db7d8add7532d6505890578aefbe94687e15..15f50f2ef913066ed392e257d363e1331719ba71 100644 GIT binary patch delta 2196 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 UwOhQ+hX4Qo07*qoM6N<$f=eb`4FCWD delta 2408 zcmV-u377Wh4)PL^BYy#~P)t-sM{rC^sys=KKTWkjfKxtApE^^wM@^wTGI%Oew?JaQ)#r3F+W zb}ShRO+71X&|XNkJLc%pxWTwjG97T^VMnt%bmnGu=V(8mH9VCv%b0FyMls;6eSMvI zEF>L7tT~E^idxc4curQ+vx%5;YF!uQdpu&giDL2v*7 z2SQ0iL4QiR#Xr(dZYfGCyyJ?j4j=lq21tTE+ z4=1z)-F$yJ@`KH`5F$r)5ALRq0%EBZpkx9JqOa#+MT||dm=VgC1B9HWflVkLv=bQ1 zvE%|6&HS{X))_z6IgWD3+qk!fkRJ?f$6l26k01A_7)OO#1Z1g27{Tc4Fx+nK-p9Q? zM}I8F5wh{)j)3972wjIFu)Ss5f`dzFSi%UCxMKhTN43BGJRLSvEjL`%z*u0OcL+2U zLfhT0kBN{GE(OLFQ`H2Ah2V_05Saj<#t5oiD!0C;PgK0Z$m(*Tp+;v{31l~ zslZ?<$C8bNA4E8Spg2x5Z%OnQvEI6nT5Y5ddCMLD&`+o^k z1WRU$wfXG4ux1qvo-$qF=}-uc2@pttgE2m-xOXBfMy>KRn;qsena`HBwKc17RA#3$ zw1eVkC;|YCz_i`{_l{N3OK=6&L9mVx{lQlrS0~l#YUbjAB7mU!y4qz#6=vq@_1Rf}*uQc0$JaGE z8?&>=sT1P-hQ$yu)`{?(AMBFf{(v03hb|y%mbJ^v%ZuyJo(xyBZ#_3>6_FttTz?F1Z3;jfO(&*0 z5{juqD8q1Z4ogH-2gCvsL4v?|hCdvRKY%zadKkZmg5$Vf5Dd78Jowvn^5O8efsT8j znE7q$#Aoosa?zLFl2bFF8vIQ7!{OA>1HN(fD3othUcRSQcHPU2EX5LU>F7pf=5?)J)$4}b^HNB zzc!$EyQNwx>~k@OW&rSom9q>>yBjOfcRVx#^v&aQ?+1FiUi&1 z>xmBgIq+4zWJh!p+iE`NPDI1e2bWu3CZpC=JUvScAufvHK@&|QQ4`aYxA%ho>n7U zPICn6NauqlX_IIu?<0nW`n0|5H87QmJs($jTuf^oS(DQoj7X9Mt?1wA2GsYS%<-Yg z)z$4xu41>R*MB|eNTB!)o|;oOoMxDod2rrGC$EO1bRf7{ftQe|-w zA@DNvxKfBFOP}P4FzHw_%C9t^YG}}K%}%#h8hm=^R1D>Ei?_3#j23twOjP&;LK55t zdZN)-4S$-0P7|8$qdSJ;mrAA~1C3@f>1d&BfFk&0G|e^SG>wQEO-2Ia$NhM%FIBjf zfU=mgNBPf!zg&pgOO000(|V^o-H6v6e0@vk9yDp1tu$K6*zHN)aLlLec5r32S;nvv zf~M=1%(v;>^Xkdtzw+Yot0!_^y?A^pPhJhfOJS}0^~;w} ayZ!^-Hp>~fdtF8V0000F)=b}X=`n6Z(dwm zT3cLlbanQ+P12S~{Nt#EeQHNYNbavjfMz|=qfOP5GkIe>et&LCuZ&A&UPUn@8!#|1 zH8nLPA|gjfNH{n+LPA4VLO3lgEk`siDJUow6A@EBGCe&#C>#|a6c0>IO)@evO*t_h z8yh|>B||VNI4B}pM>|tgR169UTwGjbQbDq)o0*J&(8;}ma$D4hApHFKrHf$i>f5P! zFYTWy<;aptM1MD-*h=aE001j=QchC8WBFhqo9m32Ai0lzuY|>p+55MVWPe!{MOl{K94H~M+iCXuM@J_& z=KlW4k26VclzUmmJK~ukendxO+GrY~&hYWW?NwKEHQp7PYR1o*P-iQeH=Uwk_T{=H zet+B^cihB=gx;CC0RkyHo&ZzHD4e%juUnVJyW6XdYm*|&qL77|WzwWp|L#|GmIynnN#hk=}n?)dtkcCFnEB?O!t3zF#g{-v3mhW?m>oS%*spB|B zWu@c!d~7`lkjmUj zE#E;!Goh}Ur1&Ca9&=F1<^9}W&-_QjdOaU6*M*;kXpP!xlH$1Uc`Ws<)%|iYWq*ry zm50AvFBa2$wRF7XKlI5PGHKEFPHpYdXDO`5Qxf6$Zbi(fwV!$UUu5r})Sf z{Se>9{O*CF8QJ%{Hh1`oRfKi^{%%#|QP_~SDw<(f7UR|3Itu;oKkt@YVXf|l)w;+- zChTo1=W#b=%t_~~hx_5}&xgg_+J6+YS}&Ea^4hDH(cmJAD*`dTU%UhoXWkMafXj?Z_>z zs2r9L2YgsrT!DRb_I4q7te|c1D8EEua_4svC`E+E+JV%VR%via9)=-HVSgiqpB8M| z+o_OGJf4PMIh?#mF>?cw2&bC3OCh%C=Hg&097I-vO%mQT>%K-2v78*Zd_PT7C$%;P zr^M}3+gVOY6nfNN4r2Wxf)9@{-P}n-&ujI?y`9Knr&T$Sc^E|zb0C0$^#q~+s*@`$ zee@_KP6h1-O(lpD{`yKJA%A3L0YQ=HaDlvJb@z#SN5~Le0YUgi0~}2hm6c@JeOgSz4E2u}hp5~R1KAs>uJrx*L!2*U-UsC98MI)80Bq=U<| zHXYalswY9^FmaS`pIshEuMwQ`L$|J*K?!nPkd$=RgJf{JQ*wB@5r3HUlOdtL0{B`J zegx!_%fqdPgR=ny6tAjDq81JZlIk#Q>XX^v?0lPH(4Oe@`G^Oq;Z%?js9e$>)H|fp zS!^0S0Y%}8%E4b#hy;>tN9cpL$-_wikUAg%DY%!+*w5^sPBDrV`so1$C*i2Lh{}M` zPV`Y-L*1yhW+y5oO@E_74+0jB!soNyG*#u(@cyY0MoDw@xjONS5 zJhGwClIrseTognG7@t-)6w1+yX^4qyE7%F`+E%LFqZYKRW>O(lykK`<+=mN=qPZxV zjjGbb=V}5N;c@x17k45cj&@=L7dp4X<^!mNF1HCU{xj|E6Co`=01Qvl{y%v-BK!|o W1u-6%`mpvN|-H zCQ6$>POm~muQ^kF>LMS2? zQL{u%u|YMTDkLZyDm)(%hzWkbb|+CJ5sC~lHyTLnkRIUp63CG98LjGIc{KlUp`$ z<6&&yUZH6~m|!_}=x8r6FlgLbODP$gWj$#+Bt0b;Eg23=N=iPOGghKVI5|05RarxV zHz-6OOpQBSd4D!fYDS)MOa^KLPlZabf>n58IBcC=Z_Z&usW)@xWjTv4ex7$NXeK~F zLAt-UNVq$yn24Z*ZLzASlgW(K+rRDS*KAZpfwyCS(sXA{F4MS={QLKhiBquKpoxcx zN3=SI@OZ0i05ov<{Qv*}D|Av$QvgdI{0#p1{{84N{(o&=vxNK4{^I@T&)fGT^MRkl zmr`-*Ir^eK&B@!in-rM;Qvd)4)Ja4^RCwC8mj`p&SQLeWLBN73p}5!B$rklq=)Lz2 z?!Bk&|DU~2#x`-*g6zy5&|pjGn{)2H?~Qo(KWffoa?OKWrVn%f31D&uF#;z+IDrM- z9*5-@0e=<`hT|m5aahZfH$leW?k6RaNuaQV z+cbNQ_XLXw6A)yDBQcLLiGY8Dgz{d*E~%70jTlA!|t5#vbQZJE}M zH3NhgIN_OQBAJXvIeEt>5;5q?t1P+=%w${%4$UGd`wBMHmKVr#MOmD9Z!ye~j=`e9 zQIzE%0AN{(t*~0y0Y)sA-kU6kUJN2=&=nH~07xs=_)s`g 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_686.png b/TMessagesProj/src/main/assets/emoji/0_686.png index c10ec92addabac174ed2be37e50b87486127b92b..feb89246c67a17422a18f2396cdc20c5ccfc398f 100644 GIT binary patch delta 1954 zcmV;T2VMB`6t54EBYy!bP)t-sM{rCyI5)L@QIddkpO=MzZd@rTDz2-cWMyS^b8c^L zZazOhP*6{^rHuQ>XHHL1-J(jwsa!}(O*J((*~NW6KR}>=XYsN|aa>8IZb7$oOLKH} zZf|g~aY~P5N4I}Zxr<-n(~M+eW5$3dqj3jNQc~f-dwFY2)PKf;$dhkuZEe7PQZ+R- zNJ&XBFfrJvg50r-I5;@ku7@coDK0K9)unyXpLa4cGb}7D$%|ponQ+8}TDf*iJ3Bke zl4wm%Pa`8FKR-WJRaHYnMB==c-?osvpH-`9K(la1qIg!dlTMFcHdsbDZAvtxV?0?c z7vRdZfLl51-ha`#k7%NJIV%bTTU=bzh#&2rE3|}J^6~J+kvX4>bGDs_!G0&qxS!<0 zoX@yx7#J9LMh2*Q$q4`e04sD-PE!EPtw<9g?g;*r`K)dxJvib1P2+2bXT14|^R?d8 z^m)|Y(a-welgG;9#&omw?f?J=2T4RhRCr#smv?vCNPiH(0fA{Igb+L6es!ongUjTeQKTz|iJ_*c^3V{7ME6soA8QRR#e^&3#|;(~Dh-yF z9nomu=+Vxoag|g$T*0I~$in3D)Rx^Ad|A$gC{T;s8`KvCaIgetyx zN`F-`(eOuiR+bJJYAGf}5l?>Z4Os;op!h9(2}FCf;b_)>yUGxMcTtZ2^{w6R4@N^t zs{IOmGz@2_?SA{)O2w5N&hlt7>jAB1v)O{-E9P`Cnk+=Y?)SgFTBZ1Sd2xUEkt#$@YkhqL95~9lEPtb- zu<}uTcX@FUdt0Ciu_gBwB5ImTN$ak6*Mv2O_3X!zt5y>gCm#!aETs8xTRJN}&{U}B z?sj-~JC#9k)jwjw6gOHM72GW*baGcZn@pzyC{FFa6RY~0D*C6ECQRp( zGvIXI3=DTTo!nhR7N^fC?5hDN=6}~CF#Kp=2T9DQsC@r$-4gWiz&?tHDDM5MnFCo| zKm7Rd{$~D5aeWK(!u4Df^ufT6h3&|_WsMyjmUI5FC`{+mppdWg`9oiuPGLvvu4^5x zd{WVgNN^{cOW+f_S~4hnmsrf|QvrPQ$DA&)1#AoidlP>Un1AB4XLX5_ zi-fW5blqidiKq|-(8w|x0PHNdMJyhw$Q`+^rK5tP+kz-+Hs-NZ*rZFgBjM!BU0963 z(X_k7a)=|+B=A}HNo@Q1Q`0`Np~aVJ2xL4ScWsabby!^{@;qf?=>j^?BHNa)!8J(2 zcJ>o%D3~3`)}R!8T!U>z8-Gm#>WHjCe4qH31}GN2g{|xURZm9)CgC!Xb=Y=k8Yo$e z2eZKd3?dqIi^SGEfyRgxI9gD@Cbt5E@9Z#<^~hl*UAA|KZ)+f- zKs+_jGG5}aY(0>m0IINPXTQkd_#gob{Ob4xiG~-!>=R=7wyguU?SEU&&S5h0LK5X2 zLLAGoe9LkO*=HgzCYdaEx~}UILR`1oDZlWYB+hK_9v>f!fewJzgX1r0Ccf_Nne-kW zxGSR$1uQ@v&*Xb)W-Y;P1_gL7>$u$jcYx<6Jdy7*&lQwQQvt+#k})FgPlgg6A~}?# zbKzULmpQM~c$PH`_J6=36lZ2E&%!9l>@i`6Oezo<25%Tft!Fua)k7n|N?wDjr!paq zT@cU&cpeQb3l3un@z8 z09d}xpdv8QQ8jpJ^XaCFDyZOD0JFd(f*_ve6ev_s@X;rGJ-?x-DpZ1n$D8An*0VW*~x?LtJ ocqRMPQe>5lbsH&en2(Bo0MZHqRZcg=VgLXD07*qoM6N<$f-0$`q5uE@ delta 2666 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 Y4UpH2|J1qAW&i*H07*qoM6N<$f{FP6>;M1& diff --git a/TMessagesProj/src/main/assets/emoji/0_687.png b/TMessagesProj/src/main/assets/emoji/0_687.png index 670a10dc6c7c963ac93e5293065ca3737b019da0..56a6df527840898bd4d45ac35d5f87204c86b52d 100644 GIT binary patch delta 1861 zcmV-L2fFx%6w?lnBYy!4P)t-sM{rDueRO3&D|2*noN7)cCMR1>MV*d5b8qDntKJ!olaeRyp!FfsA6MuJl@ zEG#U8RyJ>0M`l4Rja@`FH#n7WP{WNzz>q@6fGB5OO4FQ8(0`~;*^(=MQ#v&@HcLxP zEiEm#gknWTMnFJ8IyySFfM6*pDY1K9t94nUZ&WccF?CEfTsE0<$S#FJ`YHyXQ%Wg{aaQd3mEj%RX39X%iqMK~|TteDcgsh^2-+|0i!4FblN zZtb5dz=SN*hJPOM@b9yZak!m@=Hc3fXjvE-80@nTDF6TfDs)m#QvfOMsQ&I}3mX17 zN{IeT^{~I!{ypHM(SYo{dG6c$(N5;loBq$*Y5Vp;em+Y800qrSL_t(|UbUC!cH%}9 zfWcryZ_XOL#rE3q?q<|`Z}g74^Zrkgdqg8g(i(#_x#6maM{PE+QxIz8|I3Er< zi8WcoG}%P8C#@^q7sXYwk7Q7mO=JY`Ab zN|kg4(-B!v@a861+9FFRLPa-SkuAxfz>EQjg0ldd%?Ve_F{z5~(By&5^F`c{WMZL$ z5fq`{7c|4Q{iz5AOg$^og;5`_8}BF{6Ga{jN}gCG zuSb?WorbQVyOtH`;83izzQ{r$3@9v35r4>J1x&P&pyv&(A3H0=)&(U3#oiJ5d3%47 zZH{}cA}Ic(XA$D|;}H_ac{mIGRnS-To;SYSr?|eozx!Do_X0%_biE(P@j8BGy^hx- zMHd7`551$kv-9)q{r&Z2uNOgA2#=31#$*3AJRUtRUKUS69~6$)WcC;sRNP!sg@5ui zTf9upXZ>};=xMQVCX2a(3jg9VP4TDJ^FZwb2 z!*Cs#69=b(4k57p$;5Yzq<;(@l3)%}Fil7U9hiuw>jI{L2Iz@$<}k_^1RVgipi5CS z%?PY7nM0``p#vpb(17#uU<%+cK(dX8DgxROA93IxphlsBylXX!A2DEmI3&m$Is$@# zSXCzTL5kHQhqyrm1TL{I>X{G2FsGg!I*w&oPH1~ohWS_qm2R%nX@C2^?@{2O-RX2I z2X{s#*D2w8ed_HX!dkx6$yE-?zmjW!02fxW9oh+SfGahSG;)>q3d&LeU6{%2)Y(E` zZp1{AO|PNRKmo?%iBU% z;LUB_6d7Q_vvU=08SY7=0AH$VqM)(63fONN$ikGnZyK1E3W~vQ7F4x+h6*f|Z@t-} z<*(2Yv=S`WqzzA-?I~5Ms9?)))Eo2Lp^jaF0!L zuo0r3dQRU`wA8P_@iFfH3;iy+;S4x#Z3X`TRUp+uSyo*C00000NkvXXu0mjf4YXs= delta 2557 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 Tp7buR00000NkvXXu0mjf?)tyV diff --git a/TMessagesProj/src/main/assets/emoji/0_688.png b/TMessagesProj/src/main/assets/emoji/0_688.png index 90b2cc4dd4ed17ea8467168df862077e706c4277..508d2af62a59a36a33a9c8697f68e7668ff8ade8 100644 GIT binary patch delta 1855 zcmV-F2f+Br6V48hB!3G~OjJcja7;xwGDtx^OF1!QWo3eMWlKgyDk&! zK|z{gJ4HoBm0mcIS~V*xD<>x>GBPqsDH%LGJan z-~@;%am`J;tJ-^^ciema|1Y^SyGoqoSTg?3`Ci#tEr0Mn%*?LPZsGqdo~u?+RgV83 zj0d%1xn3%@TDq$2wpyinxmY_u7XP}l-R^w;-0gOa{`K|sQ+G5Ps*a-wAjc7&Q7@2+ zb@;~aC(!x%`P0*rDf%}z^Qot*s;77=93TZy3LIXmR6_P& z;CL$Z5)eE4`3SzJ3l{jDpI$YU$E51R%cFe6@s8&J!V$oYel|f=ICRz-4lg@=F5+m+ za#qle&QwGEV~FuyH5buQX&OjC)A08>iYRO@D>(>`FL^ed5grnrHG%`As)}@bE7h_H z+<(Wj6RtEJ3RyAl_E$&+;HHi=w*Ui!<&XKiIG1o zW+AE{&c3rK0x|HT7$_ctpx-4)|4RR3tzblr=Toz^1ltmvXQymhRh9nAP!!Tvp zM?~#aL?p|G?9b2hoPXm1;X(}a*#tBLRN(ufsgVgP z6lFOAL?bH*DCd{s`g9NjVm1jOibU)8HBi5gF}brzWQzV^HqD$D-+!E)pA@Hq1Q4QV z^#7J7i>4_C;cPc^c7FVEcJ}Q6N&%lVwX5#q)icIeJVM`uVgRDfXC;D&(=tWKSAXlP z$FRH6Qi681xw;9j)-pvj8+nLxaWIQSd2!c$++192HfbD-<$TkF{H5UP& z5XJSKdvS3QUN2b~+G>3Pir050A|gKn!BIruB4T+Tf#qR!w_uf6E<@;lS>7+iU^ela zTwWADnZTf~?w1b_Uq0QX2yK18dVhF0|9ZcKc`}>%<=k3C$si77bFp4uua?VIpJ}mP zuC7<>70!B>M8(WI_4M@gq?x#gFlBAA=o{LvL51$ZfY-&yjgv<9vz_M)<=7=KqYacs z)z^@OS9qTRf+Uqfo@#)=xs?J88HUv~fzxM*0N$^2xrl1hbtA|m4I=Pm!+#WggGGUt z#3i*tzA8m1hKLLeAUyBiC7p2 zk^LwVp-qGE{)~gdig2!WQD15C&sJFQNxY> zK$cBVL_$z3B7g=_=eI)eb$^mTDhR<6iY6pM2~dejVLMf5DhNRgN~VN_6bsv`aTw!s zC#9fYq=YhGcmsnV10i@~1f1D#Q0k7>b$Y!f%qlSB5r)lPuf4x5g@4~~_h8LD8hNhE z2q?NH2g+7}4lKH1Rif*P`&*|2LLPph5$wcnky6`NkE~H z>?QQ^j>_yz7(6f_27g2#SAxTVe0DPT6YZg6TlBjm{9|I!R1{-5dOK@MmjubC+lVv- z{6`7cLlkQ*M;K>}%8_76HoVU~)Jyji*iA`zrpX*-{N6zlmQBBjmJ%CgVlkx%%=BI9 z#ku~^E+C{^tN|-NYXof4mf|hwSVH9`M9rcIJV|iLn&%$2v^df>*4nDQgecqSvu(8C t{tnNqr40kpR56V5i>0u4-=O+0<9|d-#Y#W!QZE1i002ovPDHLkV1lMxQG@^h delta 2495 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 JPDHLkV1lSwfCK;l diff --git a/TMessagesProj/src/main/assets/emoji/0_689.png b/TMessagesProj/src/main/assets/emoji/0_689.png index 6f044d2670d25a8f7c3072c84ac931f588cbe1c8..22505e9bec49da8f8f580093858bdac1ffb5f021 100644 GIT binary patch delta 1758 zcmV<41|j+5673C;BYyzuP)t-sM{rCuFfTedIHr$uV`OA5FE2qsLvCqhCnhB~GctdH zf^%CxCmtC&H8Vy`LaLZtbzW#+s}J`=g+OersdZ5{s~x15&!@N zjY&j7RCr#smxprNSQLg4U}U;UjDuUsZq$1()Z*^s{avmWgYlLE+o7yai9}ar8=kW>Xf#)rbUlGw(ayP` zL?QmA=*cvWHyU^pmx~!y@?C8t9#FI<(zZZHsm^;QLR+*#YF}RK>{w+mN2|i16#p_!DqkX!;k0NURB4hcwTN8Q`OxG@M!pYZsgt+=)&F< zAAg^(Ns&y`AdN!LFcN<&Kz;5-X&QJX3h*Vn;uM}~jvZ$lM4pjLHX2a#JWT1-*i1>$ z+^hJOU5TWK%(3MJQ5dFah++@F&qp|Gnt7Q5jeI7B7nn|XPsENjPNOJrW}D-wIW|Km z%7*iz)=8#eFm~emX&6P(tY97B$cyhIhkrUr8v7KVemp;43#>rb&TM9_i5b2#`dTP(+0#bR z@9r^(q__yCF;c8w+w&}bc+4Cah?Vm+j~`yMz)X$%u-_|FnA7{v44xKgY{U;2uYVR= zL5S?pFpT)+@zpX@4C-m)kRk|Hi`heLy!>210G!9y2N;*D#X2BGUo2Ck-aY0;wphKq zEWaaUVyWvf+dx_R_IAe|oz3wpz_m&z7fEc9A`v;ig7L9twM> z*5}*X>%M0|flH~_v1SAujOT!7(y^aPZ7UVjKk(C_}2#YhKJB4-RE7DVxV<*lo)mzVw6_(j~myd1WU zwzSSi^uj$+pooi)LGSkU(Ru4Q!C4*knr8dP4$sxJ3B8dYmefeVD+XVd6C>ZE`n*D6 zNv%A>=xkfB0B>v1Wx{t!ayDv}84#fmNc0A-gdP(@pb+#Lk02$EbAJf99Vs4^P@FB6;Nvb0GdtwY!Qb@ZL*kjAa?G8c}3aKi- zIhZFH2y{ZdtD6yklUIikhkTYB(Q%~8jW_$?^;n|Qfa&UQ?ACXHFHoCrDFnVSNw@|& zeDs90I@p>>&z`}XL!qC5(^J~K0iP`{z;>tj2m3#xs|%#t9{>OV07*qoM6N<$f*ImD AQvd(} delta 2393 zcmV-f38wb#4dW7!BYy$2P)t-sM{rC%UzbmDttu)jRXsOKWR*`V9aTb9WQE8>Vv|QI z8(em{I$)PUXrM%BpjJ+2qdZJcXOl%!ax+()Q7|MqR*gg=6&o8HOEXbSb*M%s8c#z* zYdj%9BNa(sc@`QTNoJ{Edb>y|8e%aWEU=*CQvLJ z9v~!GF&$?+Bua6#bw(;WL1j5MJTWjaUpFCwPA_+v-iuZ;W{c06VLA^G5q?W9CMPI| zQ7{!48d`wEmR~fHS~XI5yEtEq*#RX&LPUB;Dm-DN&nGJ_Msy+z39bwiHCBATAvRH3 zf0Pay!2}gdNqB{!UINhUT=WnN^TCM$lR zw|WA z3knQZA}xJ^su?FdfMiw2v7j+bi*j_5WKmDmzPeE~D}T6`i0tFvRBorFTt}aXbheF6 zc}fUGbEJScB|UAPjq@&04j7+ zPE!CXj{YA*I1T-9im9i^RsQ__{Qj!tRnqes~A)86H|`ucgT000Ly zNkl+UAaqj^^%`f9ABcbiB~$HzAXH&5MqIptN*A{aYz>b4clE z`Fnu6Su;8JPRiSNhyg{@(e!s(crm^C_TAlpvwx|7(cQ41eGUQyI`~eR)HF9JbU!yv z&dmXVl<(50(KO`HPj1ek{D4e48Zxv4ZvEusri93ypocuxTfJM`z-BxS1sr-k7`L6= z&D`|Z!~4>X@rMD&G&FJ#k-*JOP1i$*td$_B7(+^^I5Y3`5#0|Er1Bn1i6 z4u^6Z?S#l$bT*p>=MMA6X(%x2Q6xnYj1DHRw6SeZ2pXEO84Na-gN-pxYYt&mpcE)5h=l}pjv}v0ZmJf;bEA7 zR{3-iKM_4U@3D;_va1-N#_+Z+)w z={%In-uJO15Kx?^N~HqlB_5@?0e)EdlT*Z2ld%{wK-k@KnifnZFyOn%>2k(X6nFTt zRgstwv9;H>^k0Gj>Rm1nkbmKF)kHDGJyE^{)W2W^T~B`#Oga`md~|*%v>_1|oC@(1 z4_zbegcwPu(~@9fF^U!`(Fp(=#Gu1Ze;r0mDCaR1Nv6HA-6N_wG(g}&(OGop8NPHZO|&-#w2l8-t)e>(0Xho=egeTyQ>Xo% zEe!}QPr2ot9XL{~Tz@J@2U7?tVY#QT`N7rb9!jmPEiDlkCE|XIPEw#3KYpsR3M!Sb zn(Jy(7PNiYnVEGk7BPaNan|pLLHsOEQ&tu4^Z5kpPGPJ?QFv9z)V~=B5osF7aayFP zc~angsT3G%g|Ti0VGINaAV4f)7(oyeJP2%YmK4AML?D$6Eq`-S=&ffmQX}h&^C%bu zJ(G4)1x77pwW|v5pBZhW4Tfh6zF3fYHx$hn(d@jB?y8~Agf)?Kfe;yE!wC3 z(Y{mX?sha zXfzb6LiYCT+hMMhNr|Pjg;cGkvOoLb|CoB|&D4}f4oLj^PJb!#nq^r(%g%tX&WEBNNY!kI zbME7L)rk83B>k7!Z)aimoO`OEatm;-87{Bvw5h`P~rOT++__g!>!Q_OzH?c_U{7 z^2Sq4jAmc!Ag_CNBE>2BxA11vN?Pq^F!+(-ds`Z>$5&+F)y6AGE|%bq(I-XEY9^Lj zf#1LzfPZXwU~{+8?((Yd*JC18D#`)^P(g2Srr%<)9gk*$y~vadKsKtd?_j8WKI>hh z?RPesg;6#TAtx6M7JHzHOfZ;}2@p^lyxk56>@F|Z@64k9UANp{jDKhJmV?>j<9fMV zxD^nwQd%QPa^%?`aLh<^`<)xeW$>qZic@G5SyI_pfi{ArLOB@Ay+W_$^<0V9mx1_A zt$qUI+}+u6bXjrP>>D`}(iaO#>D{=kM=54GtJNyNjy|*h(fa6rUJ2wx;?r!E00000 LNkvXXu0mjfR%}=+ diff --git a/TMessagesProj/src/main/assets/emoji/0_69.png b/TMessagesProj/src/main/assets/emoji/0_69.png index 8a44b4af4d29a1e8805c9268f0420c6c3a3d7d92..1afe9de9788cf05b7f1bc91e372c18a0731c50b6 100644 GIT binary patch delta 1360 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_690.png b/TMessagesProj/src/main/assets/emoji/0_690.png index 9c54a851815de5dad11a4c20e4edd9c648c4eb41..01987dc5e349af0e92700e8885082d4b88eb0559 100644 GIT binary patch delta 3086 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 delta 2307 zcmV+e3H*KGrFkgDS zK2(FCJ4j!8yFOo(O=OQ65)Dl&DIhI4v;Y7l7!e>94p2KXHh(7{Ju4(D9u_eo8Yd|$ zPj=4SAD-m zMMu&pD>`A0EJSR{1Rp+Qr5qg|A}>XUM_G6l8Z}yiXKITnJ6fD1D{Mz*S|u)_6c{gQe?`vh|3n?=4AsexT(#J3MV5Abd4Vjj!^1e5YYgM;9P5ydo{Djc22llkVx} zJ1{Xe3&an#yLS87c z=I{-7Q9`p5@j0N!=60tFTHiU}wSo5!ciPQ^v4)IJlg@IKP4A519bx1%j*B~e$Uul( zr2|NhD)-(vMsbX$WkW(_MGgSF4u|)ht>`B(nj{%8I6D-PB1;`%&CX3J68$($QUXPi zp?{VK3eDfD#s> zsm>L{*6{L@(PK~LetPZp)*=FYJ|E}N8dPteiS7d;2-1Xtg{`Pa#OtqfUVGmOhZ;aU z+8(8AeN-Y`u0o<%ELtJqaBgFfR(r=dSICPha2}8HqctfJsg(6ORl=#hy!3c|^?yqa zgrLV0Q7IDrh-e-?KE~sZVX4JK+hV&E)SS;q24NFvAbJ%5{Uq85kvhM*zh!REkx^>5 z+m_?oTaHWJ8aXZ!i+DcimA2ueane~nx;VZ+cVC_Vuv$;skmDQMeTq|`r6Sx05c5jJ zw7>w-`17LRcDoBt->ue%hf>^fe}8l3#v)u?Y=v^ zxUOct#*c}c?}aOOx^Z^C;t8>lz7GZkVuU1drup^p;^yw|>FMI)+WNQ(qd31fySuwP z`hFku)MJs>sPctF;%wY%z5emz>Fnmmwe_!6X%^>yo;{tV?kRPIjYUF}N`Hhw!{Fkn z73KQcYW;cy0*b|Qe0)sU1a%8b_r>~^Z%!J|h4WQpNP@)zfUH2A>N*~3O$;g${WP|o z%Y{1vVFQ97I*6@I;-L^sQ+XIT#wVUT2&BzII4Mhq5J+r?g?%VyaQZWy4~LPEva~6j zW*ChAMG!#n+WvRHm~|R@8Gi^6+LpGBhDQviBtRmV=t$4|nJz4YkwOB@K_DqxyHmnR z(G&VEh!G%`4_5qy1uYT;=^nJ8NjPB?qdi^3@MU>Y`VJ=2Gxgp3?nH)T89FH6A3h_*7kNG3~7x-u7G0<7}8q#O(030z4SL1 zrws22y`L)kkOGF$tdk3SOY2 zBGmAg%Oan6+t3YjTznx@tI0*K@Rz|{JPSQm{j7_Ob8i`j@u``anSoTcRIBBemev7q z10es1nxat{s3^i#>e{K{x1Wh2)x0{n*ofDv`QjCh;m=86CVv+gt|$zZ*9^Y3ks+0~ z>4%~7v1FrE%_lJW-?OOZ!C<2%Q&jZ(Sb(whh1Ry9Pei+gH*C-dV$>dHblupNDu@jfcZOm4S%&*Yv%cqT5w<(GU*pPp< zym$FU|BBEalz)Q3ASe)kVkhgBW;H=l@Pg!PjokW44Ez%?Skb@QWL^Jwy^r}!b7KQ3 zvJ|Q(a@o8fh1$=kbH#dS2R=*2U?*Vg?XepDD?^pdY?wEm6HHc$m2AQ(WeJ2zGAMnp z65@GQoz7%7NcVvQacu5sd!-Ao|nU(uR4(Y?jueECiN} zaB2E0`M?7FRYuHa^S78wK3#aqCSRV(7bwG+E8yg&qGHrn~Y7-O^!b+B-K!t`aWU)hu8W|gZD`15#WxaB~ zp+1D7biU+j&F6UDz)YB;K7%48BMS@+VuQ8jdEee&wBKR75q}X7%w4O3Eo0JHtr8a( z9UdOYX~L3bl<#lWRZDC)r^hj2aoBa#bXtY*ZPa69bLDy4sb;ptc+DCd91RW+E-*16 zBP7Rt%Dr;M5fvB+2ni@CD?&p=DSDmBe9$&FI7GtQf=iDGEk_(YR#`S_JUu@^GGIT> z;}aG!oL{6?n}5?pN=(jk%n(ar8CiB6WQsSo$0D}mm{y`#S6d=-dMlizw0p@JGd@;0 zSSF{_I96&W9zi|W?1i`Pu#VYdZeVB1@RN0t=#k`vEMcKOfVWGR%xS&NTCe%qyYPG8 z*=fUoCtti*rpsZs;fdVPlWp#i>8VV8{rvpQHL~-e@_*Z6yZhh2$}q0<(5}*0sq={F z@tp40Vz%<1@OVKG)5W~qebf8m!{=_z?wRYyRj2sYwD!`l?s3uRiQwC&fw3u&@5Q3x zt%<{5u%}~7^zP;5XTzB_d$w$5CItYDGHm;Z?t>#z>AIG^c2n?{?1xM%@ye%+JXD=d zjm<`}&40R(*q?Z{rIqKkkb0@k%7lW;QK0^w_L^8LBi_JQc<<=ca9Thn~c zmLOrklzYT@$HahIYD9HEnyu8Baa%(-?7*D1OneTue2ies+C z;+etf-omt8wpJ-Wy*#FXyvX2$y`x%)`I+&!ZNBloxu{*Ls(}-en3kY?Sj~)PK^YD9 zknO0)$xTd5lY+-@U!SpwXm*p)KqyQVW@R-gF5J4Av6p~7g{zBKoJnkCfINO`D`06fsy^TM#n{?+!`jQ{`$f=NU{RCr#r)KzaIXA}nD zB;#akudOJnfOZvCiBxUX_80Uo4U?IfnSUY7%*>o+W@aceSN+D`ZF95Zq*7nmzVoAV zUY~K<|C%akML9@?wCX>8UtTL}f<{1~CQ+?iDn7DMA%aLl+UpI0c+&<;Q*HSXXE`Ra zcxieYq-DDWWSjO{MDn8`VmZXnR_mK$0KqFEOKtfPj0VW7?kMITWt&bz4V8x`U5}F}DL4AO)j{sI7PeA=x8Xz!sB}0I5>z}ZKZ)xRq7-@qDMzZA2WFt4i}AL zB^^bCrVS$v;*x6s!KUU|7DpVQQ-44djRFy-y>`63#1NsD$B%6th+ERiatLSv00&nI zdkq$m;CaZ?^cxTa*^{(Suu#~CAU22X;27g}5^4}4YSY``u&v_=kzH;7;x|Z%D3vxn zxQ>4bW&{!%n&*e73Z8k6R)**iS-2&sk+7WXH07 zzpQL-zMfry`8A9liVE(otjsMvTInGO4ui-hsQ@8v#7XS*)fLz5!1uXM*L_{@Q|h+M zGw|2u#ep8p*V73FAbpWW|D&JDnbb?C^Ld|E zOMH3FwiPnJVpv7BsFvYtYs)5+ju(tZir)jg!DoOcG+C^stP~-^r*1}pad(LSE!w(*!Pw+m z!W<;y?-M5I3+@4sX$5?yVov)v_!5FbY|cpn%aKDYyjz~HOZ zSCL768wv~&zmQ~4RFxpAPOy1gvas;gEmxs|;9w*kql}=GfVrzJa<-dAD@qX3dK8sm z`@jCQ5e!gNAP|cW4qh@-6c8q3an%INqQ^^BfugJgMt}b}|HGs?5KoSEj)8Y)vOfrf z!TuzRqUcHCKEn%;}t+b#^A(fY26cM?vaQ;nS+92SGE~--VY+ zOdD4mhkG%#TE%uiiVVm>f}qlP5Jb2xgg3Z39mD==>16R~jE?Bbc_7usH ztfU%bAsaxQ?%waU2e((SLAKo0FE+mVo zOfKEJ*Bd6B8`-z1F|odF5(-m-~4v z_+&a@wZ2@9rHj~7Ovg5!mL?DjSym{|zt?-kJ?XP~muqNALUh#2?J6-^a%I$W8)pMvG!1 zOEUnmhysG-09y4$tD$^H{rP>L1J;fn&VL_7BAW@aTZ@Z}nN0k}w2U1PP!xcY4{7@q z|2v6m_dYEY?9SSZo2HNb4O!k#5dk6nK$c(C7(`)cr9I<->HeWr*&`a>G=kSehXcByENT_;LG+UGq+DZRtg#As*+9+cGXc&$JB1Lw~uk z<#yNXcKa^H&=C4I!vM5zx7HkzB!mweY;{q;P2O1`Vj&G264ZRqR>$2D@2>{K zn#p9q;OF*<)za8s!XdI{(HiiW)_)8wJlH{zb_H#l<6YfI6+1BICOKWuI{Niqbm^zC z-WDk5%mgAgdsx8WW}w7r`~Q_f*-ef@3}-yP6|#x@(M(o!2KjNKIFpzJnkMbCJ`N3> z?{uy8;|KKT{3O>Zhv2VSe~K1|NF; zTecqL4~*vwe#0~X=uW>D2LaSMMVAJFKdMvX{^m4@#)xC^p}H92`D)J4lo$wpZv-Hu zQFaY540HYusQMZe~b@~uAs%Y(=7 T9;mxr00000NkvXXu0mjf!>s}B delta 2425 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 X4fKGu{(6O#00000NkvXXu0mjfq*HLN diff --git a/TMessagesProj/src/main/assets/emoji/0_694.png b/TMessagesProj/src/main/assets/emoji/0_694.png index 486cb00c325b30389432ff3ead6a16b8fa56bbb7..ac68a1e6fd70e5de351e443a3466ed6e475e43b5 100644 GIT binary patch delta 2859 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

    )~e-gqReDi$M&t6?|oLAeJr44ZvAs(6uaF%gTqY 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 M07*qoM6N<$f*VFf_W%F@ diff --git a/TMessagesProj/src/main/assets/emoji/0_697.png b/TMessagesProj/src/main/assets/emoji/0_697.png index 2d336812168991f13eb8b2a9c7ce877d34671bf3..227e9a02d0afee4e381e09057bdc79f9e496f227 100644 GIT binary patch delta 2445 zcmV;833B%P5tkE?B!9(FOjJcja7;miI!>`cT%bVVr-C}2D@d+AMzT6gmpBv^7gDxG zQMg1-wL(<4NEa6xNv}O3HX&EON>a2%Z;NbBwL$Bzic+^mA0{FbA{AebSu&O0UYFdap=IE;#nIEF4f zm@;?hY5Dl@F=-~@t%z86Hn+L8cz<|gl3Y`CQlNEF(0`9=aCm9Vn001#`QchC<6Ko&;GfC(N{>O$~wdJBF^w|FM{^reb=VIcGPoqNo z)a2)T&VM@3>FLnteuum3o5VMOn*aa@P)S5VRCr#s*9BKxNfrn208LK|ZXqN=A~VU( z%-whV0wemy_1#j0 zaPOQ1Xaml(j(I%`mGnYcK;XQmMJYqz6y-@I5<70Q*=%&juGVk^PZ}H!jCDu^3x5RZ z^JrxViX#1x&k=LM$S{T2?neyw!)RD=VBAQ+>87_2SJFXJv?oCmy!XJ)4adisNF0nn z05cePN)H4QC`zMz__lTN&`LkcPaR}@zWtH$kr5`oQ{=aJf+al!lz{{wDwGe7wYr7! zrAdO~(SujNJq|`BzH|NYgo5KnvVTwpg(5Q$RmF2MF~$;bIIfG=1O~=97{~ii4dKt= zFmaj$LiVzD_N6aa3}YwGv%@FJ}^-Q zIon(LoLm^liK3X>SeO6+l!16ooWhs0*EEHQrYhN8gwA3Y$%Tb{E;syFaA6`cJ_1=- zILhS`o~sK|BI=*W<=4r01zmJSZt?A`#og2NBA3s!ilzl zeU3;=fhY+~#8`+G$+U;B0YJWzP%yrd#FB>yV2nU8=90mfWBZ zh@fTWpb4H{u9CnQo%?}hURzF3{WEoDav!d&L`E1`=M05HOU6A3I?DE>lwtsV+{WNAog0uCv&dwK49+irhw+342M!&m|@UK4`RH{b-?N7U> zHWW)vliTe!nVcrT;4i_}b6fZO&aOuYN=@d#Znxz_OF>v|0t87;BycwCq`$uG;jH>==u5a*?mujmEn_n?GlCTi+keJTD5O||C_u35a?xLtVQOoYHx&3pSHqQ`^GJ?3B<74 zCK;o$hDzH{jv)hxPpi@V<`Al*RLRh=+QNYm9_2*a7}fuPQK7A`uh+Ek#W4_8h0~!B z3>J;V3G>K{V1IBnn+-}ic&n{cJ^bU;i|2E5eV&i2f)GA$b-G=pn1Xq=WT-7LEz8q} zhu6QIo%MPb7rk?yW+8kU1VOrHF4tLf)FP@mizr%bRx8)@vf{rz{?Ydb0SJWj1%&7o z0?cOkGFfp9ox1_5O^8un)vyQdHV z1wmKsw%@Do&vR|9Z?F#-DZqT441`b2rMOPl{gYq4fG8}WQKFgOSZ zKoC$yC)43Lg9K&=gwa{(bDys7Kvdhnu-m!6HMJwqJa`kGWM!h0=_^Dqg)RSNGyyn7 z*Y8EcwSTDX(2uVBKg%?)P3t591(@~ddO8LMvzwTVu7g}ke}c1cY7tGh=jD$^HIy=~ z`<`i^5Y2ovGE6)$84dfU`*pX*92%~uhHC15>_>YylyYnILv(9k95c**CMpD`(JQzA zcAzdz7w+?2qoPOjt~CSk&6xHG!g`<(ON523!GC_F-uhqF5Hwx8&2p!fhC21sTr-q% zCu?Br7uN;h#|qa*Ef&ku_Bw=!e|{%k!rANguX+aWc4JEr(rH21(%m7Z1I?2_^i(wb z8>;DPxI?Jx>gwJxw6;6e!y{@P0$$tO{3F&nm>N!^c0000< LMFvhpu0mjfLM)ZC delta 2287 zcmVnRSLL^htgNiu(7}z4jm@8Q<>J=Xyq(9GZ1TQ2 zv4dGSAQQ?UAjFw)^Q{NuwTk%1Nz%WXpG!yNvOK$1SM|6ava+)Awi)!e7^tYIsi~>4 zCMNd5HukM(c&j5K*{g!hqkgoswE4j%y}iA{!hgcJhKcF8W;R+zLuXVw zUrRq@Pf2W9${-)`xF;}EKku_0{>mzpJWQ)>Foc{E~TZVd0IRmJ1w%UtUzg7KTkZkd=4uQ2a8h%%@-DZO$-bR486X; zuyYGfFcXqp4u9KlZd!0oc6&u_J_yQ+iN2B{pn@olfj9rsJ!D54Y-weHV;YPm_2Js*+Y_{6$9VwUbgcnuTRgp2sMe2XxRAOU=RMEPQJVUpxj^lHNJPYYfRQQ z)*ZGtIDb4DB#=H6AT*8NIE*(WsZr$y_kb-8`1VZI++k$UX z!g(~89s)qo>VscL=onvKqo&q!3;J=6a;am1I3$Ejv}Py-tlT1S+1}|`e0wa4=coZ5 zh8hE{1w`gp7gxvAPFw8m-yY6aRRAKMKBk&+hJSOZ7`dw7&)FwiW!IZH4u#>p*jeqi zXs_m9Bu)g5u$thkg<3@+3JOt(_=sRsRT|B?MbhsDC;aW?Uki(X;FfN4<0~>Gdfo|FhgLv z>OY~OFFV!MxlpF<|Drv8gwjV`?_4o*!0NefG7m9!pSDW3TI88XwQT7@VI(?mB d zyPqh0RA6wbQ$uO1i!#eZp|p_@foqV_wtsDDJ3lA}XYCvjD9#1ND!#I3(xvVr(x{>n zK&LqG43p@f3=}>{oKF=YE-X?h+wcGgrO_%CLY19K+miwz=Y>EoQR1y4EV>kF5QP0O zj*l8RT4P{7Goa}6c>?Vm`tMS}b`p<3J0oa8ry{O8QHuUJ0KgHqP)cfak#`bOn13pP z$QQjp1GIBEZz%h*sqa6pPCD!Qp*SxSpR>lCso3pQ`=&Q(U`4Z8Zki?&C4Y=>@6&WP?G*<16iOkZcZvZjh~uoXX-~y+yV_q* zCqHE|nNDGXz1&{!r@ifW3KMne1K7@U#ogejAWJpr@o4*_*PBfz_m6B=ce5sX+D>LL z-amiUy-Bz5u@%7JLV?Y2$ckn&e)asLhi6~DJ~TQ`8~V7#G_(EdPR(lm0DlSWRrEdu z_7iaCk*ZDb_uMeZPrKdYZY^@UUawi5j$yRhtz%sm zhRq=bfyAFFAfLNnI)nd{z<(mk%@`Dcs>=n8xfXS2xU3TB1tA|44hVeLOIFPAG_#Zi z3&!i+zvI|+`6G3k7k904OTe3BxF+ z0Lzgv2rvZYBC`q?@W^E$?op9;U5YVIPfmNF07IxuC{VbcC~!ku+Y7&1riEeXh+^H$ zEO~1U)QB!!%})j_#aEC04QyxY@^VA<;!a512zKiK816106r?b<-tK22ds_p1?(3(AOiWI7+Hla1~m9V zFbBmL$3I{g9=5^PAF-!6I)4Tq6!zhFD8|ODmIji* z3*c&#BxpcvAz-*nVI3I6HVbhYk!oW&H(GUBlh|f^7WdN>ryL069Dr{lL|3F~YJb}| zK1KvN9=_`gfV&&3INj`{!8v63?c108B2_@D(6ayM%eNsxGw2Dy1*88J*Ee_nHC_j= z3BynThc{f%q+~~9YO|=)Us|jr=41bMc_{z|PeO_vaBp?VP7?Upb zLAjJ-OcN4Oh2=w0Z2nA4Z(b48s!ApoIQvkycRIq`5@i9n~4xN2wuP9RWX^*8Aej_@x* zp{zL!Md-CN0Bp?6)002ov JPDHLkV1hsFPzV43 diff --git a/TMessagesProj/src/main/assets/emoji/0_698.png b/TMessagesProj/src/main/assets/emoji/0_698.png index e9731ca04595132fea4e8f4154e7ab4a6ede9e15..9de46ad67c1aaaa61aa686ac2c8365af49359fb6 100644 GIT binary patch delta 2464 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 Hu0mjf|A^No diff --git a/TMessagesProj/src/main/assets/emoji/0_699.png b/TMessagesProj/src/main/assets/emoji/0_699.png index db8298d956889cd939dfcba9f479cb71971ac3e5..630e89cd1f006fb520a8a77636d520dabaf53e7a 100644 GIT binary patch delta 2406 zcmV-s37Piy5b+X_B!93_OjJcja7;?7JV}l}O|?LPQ$9_fI#ahtO`$w8cq&u3MpU*( zP_{%ufI3T2-}3POL*tjX*FlGQEsvbLC{PdR%PZ zUTE7|9v~oa<6*&(X~vao3=0izYi?%OSQQo+r*Bm|JUoiDa8P+nHezOCSEollEgxu(V^B~~OMyR7Z8TY!Piu-t zcY$^+84683E4ab9YtUZi=+a2GJ4CEGN3%L~=4N*1Xg{DeJe4v}G976~G2pFzeVutM zBpu6`Zi1uhPE!Ce z6I%Qq=Lr7BuZlu${?C^CCFk^O=St_--9`1~{A%i@;^%eBbcXZ7_tB=XtS{9;Z~y=Y zK}keGRDXD0wblnyTS*cJaD)ViB!a;hY_M@S@9uf;<*b}@&N+*mb573Qy{~*dPgX5v z4+&q@{i{Hf#QfAfJyTNG|1mv7O64#_sT}I*`(J>ef!+xMqaYYD(K|4#_*tcIa00_9 z#%{M8Aa;hrCI*zCQ$Gts! zB!9vavhm}NfMLgo!45@Wd&^prosX$GLJyO;V*mk1b*TM3?OIeVKUP-5SYV!a2s9O< zzq?%@(*`|U3XIPu$}t`@z!`5LG66n=5p=s&#(M#vC?MEiS_6h&Z_wVJt-Kk;bepM6 zO#nb)bVFcqZ*(kz+4T%#LVdId14Gd?J%8M0qy(yg;Qan$9A{N?5zJtxDedwS^dnCM z5d_Ee-#^$%g2FJGzSd2OpRd} z>g?>Swu=ml1wSsjixeZ|(5C_ct$((^tp8fbeW_8qwS$}W=*|Awwp<5J9v`Kc)EtLV z7$Vx=)weO>OKrDSzqz@vmQVMg3}i^BCwT+CmBY}XAqaZ79r12G_hp}`*0<6XtJPco z3IyczvRsZZnhJpknrMI9|B;yc^6l)ZUbb4TW#`oa8pwHNl*_BBivyYff*$B6P>f4`?gAdRJWZSZRd3kwp{n?#@D@OM!+7f;5g29VwZ5LAe zYC*!r209#Oig&^UoBWh@RQQJiK+aYL<{8>6|QXZhs0u9L>dMI}(c7 zLnuRcaSlr)R0qTY6F~yWy2suhPCbA)%)42igo5L^k0f=tggp4$dGh}7x8aU^p_u<| z_Qb36!E(u)-jY+%p&EQ_@crTJ=mWlS^(d5YRA7)Kj(ekkq}O3ANO1o;KR?>_pma~c z;b6faacBbyf(M_@>3^PkJKop#AmI7$nouR-cItdSpN?f&C%!S#@4?ANIW2t)mT zjmsrg5<#z%)incvHy90tL|6Qm(av9#UR>|kTpm{_9R#x@HV+tqweqh<|~t^jb8!4v9wB(pyH+ z<;ud-M%(6#HpU4MrdF?}GPY#c3jmHn`hwXk7y+Zz zY7{-5z{u0?|8}I%`y&C2SWLZAuq8kF@b7Vk!#2TaH9D+TfS?d@k|)9@Bk{1X(tN3*M#D8aTpn@c>77$Cn#nBQ&O$t#6TC1{@)HPga2x39 zMq@Q#41YMRXu6N?7>Zv?sfG+Rnn@+YxuOn=5aQt^-;mQZLPj(h5sV-AC${9t6jC>G+j+eJXGvqqzF(IfS%Cy)Qii^s2?$a(eR@vS_0H3t6*Yx`cmeEGEN YKg>nNy$pYQvH$=807*qoM6N<$f?NE4SO5S3 delta 2154 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_70.png b/TMessagesProj/src/main/assets/emoji/0_70.png index a4dcf0ca5828c719870759f07ea7472dd62bb3c4..17a099726817ffc7b604b1b21657162f7d8ab109 100644 GIT binary patch delta 1638 zcmV-s2ATQ34EGF>B!A&hOjJcja7@T)1=xTY$#4+GdnU?+D9(Bu@17F4c|q-i1I26& z?2Hh`YYpg+9K~q}%5M$IZ3^z3AK!iw)^`K%@$%5q)!&H!r;p5M31H#3~nto({ zP$R3NnTlR8w79#rt)|1dufl^Bq?wNY-d+FJF8|;%|I|bO;(tp0mjr`H1poMg|NOrG ztr3}92L9|l{zEGYkqq0dD*yiD|IQF-G6nqo{c%fwbN~PV6LeBeQvmOI zi8L5i{tf${(toU%*u2TNqd9U;;{X5!GD$>1RCr#r(f4wjKoG!T4@L+DGl}&K*XSM9 zUR?7250u?Koj|hUw8_u-ACCKG@AUA`xexz87yIkYwqyCvly5oq;7@^p<9qYf?Csoa zHTQhyPZZnoRx{c!D6SdLw|^J#hY9TGSrN7I8j9PdP=6edWcXXiz&auz7VY}=^*cWF zzmE5c5bKx6vAqP2pc>eJ+qz|MvsvOfp8~FfBZy|*^$LHNT1A7np9p>c!ZKdR@SFit zjKOjEED8LYKM$Q;B z2-TN>rL@47496IM7=mF1wkQ^ND=1bl=ynV%2!9gEw4s%%G8lmP6jcYH!15q?y#6_+ zQc8tYkSce(7eY*Go9-r6QL#!v3_ia8QJfJG#!%Jv9V)9XwSyPo1eO#gp&Cx&^ez*w zLUzXFJxoK~ajB#?J1s~Orf`yR?;JrstuIJczNec_+8ZO=h3O^@!%3!uk_rVm&F9@o z?0-Wr&!=c`DTGkjHbf#UtIU*!8$f{&N(lI@uBS*G?CvTwQFD$+R_YC9c4>DZ1ecuG zn&>XW8Xb`!Lvq2h2~CksI-Vu}4je*cLYLv$!gK;N zkU&G^^W(_e=MxYsGX^2q%XW)H3q&$9N`HLAN#N%pfcWZ?;C=-n$&JCufW%e!f&@B- zA-?s9l_Ag|guHnyAq*i0CUwo-@St6o=CgiT+9MOd&c!6T=e{)YIVv zmthEs-;b6w@uL>AYf&5qqwscG+oebq($qAX`gIqW5{A84gy4lbVE_LQ+Vdv!Du3H` z*B#h>6hbO}I47w>M33TfntdqBQ*&Dkzw1XFNAsP(^|+i$ezXKBLX3BNT`fi|f10hX zwqQkb;zuiQu^6s)0~447J9!x>j16tM#-WSc*pQ1D++POKfty8l^~4 zj}-$HH56;5_SYSSpruGM{<2peO@F-Yq(lk@$FC`XQfn#Ysz->>qq_ZUm4cdhSJ)*f zw5q}H6-!&h5MoLKUW^dqY`d^_OX5BRc!qgrFL6KG{HBQNC~mQ-ZX`w&9JE#*BC;R!vi)_+>B(N~3y z0fW>-O{_^EH9p_2jt+)K@P6=uQWcLTTCVj2g^CKK&CfD5Dy&`1QNCc5n#dCFm_Ov7=)6Lg*gNPB7_!fc*IL0 zs0>M9xl@31j35#mCjLY|k3nDoMS$;*5vu&@!75FHBv_bBydQ!jMPG@hWF;hIfd(Sb z#QPzbW`B9Y&eE!d1sVpEwyo0aQ%BvhN?ITYj7e4Ilh2;=Ct04B)7gAJo0cgK+@HH0 keR&N0lm8F?^FJ6r0Qk`D2RuSOd;kCd07*qoM6N<$f_UW^1^@s6 delta 1581 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 delta 1944 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_704.png b/TMessagesProj/src/main/assets/emoji/0_704.png index 77528de04cf7e580f4ab0b926d5f6d9b9e5d084e..03259769c6e78d853d929fa43acce661fb450a1c 100644 GIT binary patch delta 2553 zcmVg7YDPU+fkIe@v4v*1mx-V{N}+L7 zX@e-Ex%J)}?;nxst?(U1o~UYmn8}yzVmcu-S%5fep1TAKJ{bvmG)#X-U0e?k zCI|;EMumEHpI%8}I&-E=Sb>c|PpW-vRwXEZW@4|VpnstZ515LCX-R93ZDPWxknh{l z)wiD8HAe97>xK&qzbGuVntYd9JY`2X&cU*HNe8B4JLJcsafYoIBsVfPQg=}>hZ-Tn z8$pkmtB|twjj!^Tke%3JYd9kz$zw>^a&OU^l9W?;t7t%ywfB8qQ0v3F$G*m`ski5g zl|*x-cYl_@zoRPbnX8<41dYeFA^-pYF?3Q+Qvi1Ua{d!e{{9CdI{yBf{IVlo{?pU7 z{#iD1-sXeX`pl@0#kqZ&oJarw2Y*RKK~#8NrPqa98(SI%a7Y44 zAcDKLrQUmYB<}9+io3hJd)4Lo+F!ZfnMt`_c7HphyD#m7%yWLc-3Z#tU_`FVB_+B?xU5rcv7ET8(XWwvsXc zxndvybQ(;d`^=-1RLgCo%DFXLi928zDu1*@2?m47VaG*`LkF6l|?F5tCbu5tx=!f?hvN@PzJ?>I@m)&qJOfo zl#y^!C6sHIfq1yJ61O`xC;fJ_8HR#4yB!F;ww8SZ0VR~Xf17(LNybyKA)yzWXdt1( z0YWeo^y4k;8vYH0LMhz{EX5;|NHQEH?15!GWVee0&>-aZ`*EVBh+V?4orq93j-d2_ z0Y!YlwN)Zy7aQ?VFo;8l8hEaMn}2B5IxPyt^OGL8+Z~rcBFQD;WhUSc;YL9aRlo^? z`Djsu`qkW^B$vpZ`Y5n{Bn;x|E!>aeVuJ9onNO$OX;E)qzWdm?{ElJ<)fc+$BSiqm z=Q3g(7bbuxW&r9RJmCQG>i6A^)rns|A>-qPPN!2IrE%hNH$VU(BpA>41AnQOwppBS0*kzV#8pRUuJZ&PdpRc>CMV%FN8nMB|QRP@(+zN%!j- zeCiV%{q7^gt3DqS!LLwhT$=6AzwVy^ahBO1+yna{8Te|(bL zcK@+A_<0QkFm|>xM{h4I0pD`ElJ$Uzs0U&T4z?sR2$8&;ThmdoS}!hi3bi62)+8!d zD+-wM#Ku`l?(IoXkYH6>;U7YjN~KyINNZS?jpfWIOY3UTl7o?)pnp^-byl_7s=FQ-6$PbZ7u7iw(hmVC+A_7_{RHS@y3+7-fsg@^`$p{FrP$54*KX;MV+#FJwrZJyiF`7S&k0+CXOC=CiwaQ6K z(R#WBsjV*0gQ#l*Vt-P&jn+slG8O$OMFNzNKPku~_0{9!;n@v%hG#~4=!_hzDUY;q z>I(8n#rXQOMR@M06~_~FMo3CfX|(P9ya@hZ2BK-HRH0C)GtWm>MxHlHl?pVIQ~L-? zQw8521p&@RF2?0@jj2RSDYH;0 zo(#W0#=yB85K={jbZQ>K@@zKC<*rQKFJ=^kOYU&^1t8N<1Q44B#io^?V2HS#9GIe%gC3WQUX3KqiJpf+5iU1t#GbW?zWwWbQ7OAtFbax09zHmR z0Z@K&xj3%a3}xssBN$a3-x{QpU2{8Y@Ar+=&0 zz(}Ol4-*UUm0k!KUJOIK3e#}^eLpJF^Dqj824F#h=Y?QdCfi8GJq^gD5Y(fOr>Bi9 z_O(&}(8-#dT%ZX$0goq^fD&%cVc<^!lI8Iz1T%7ZU(Hf3Q!OvXU=$#}APpYRWI7%5 zcygAm1RxeR2QVI1br(ZNME}E|M4iP#rUfzBO%$Z`E+jl2&(x9!N-Xr!4IpES?i7Y$ zRYfH~K#{NSY#lt^Y%t2$7$CVS;zJLW2JmtKT#ii&fZ%o%@bB_?9R>dax6crLMranv P00000NkvXXu0mjfKkT-? delta 2082 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_706.png b/TMessagesProj/src/main/assets/emoji/0_706.png index fdbdf5832fe89e43b320e196c61be48cf27887dd..7772eda30fc09d0f962325007fcc75aa2aa73345 100644 GIT binary patch delta 2393 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_707.png b/TMessagesProj/src/main/assets/emoji/0_707.png index 8bfa82af7ed704eba3e803c4505c69810ae4413b..a14b71735d173be83787aaa845141ca534d5a954 100644 GIT binary patch delta 2308 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_708.png b/TMessagesProj/src/main/assets/emoji/0_708.png index acf7989b95594e9052ee0c6ea89b746a97721306..3eb84f1dc53055d02fb61cba040be609e7fcf8ed 100644 GIT binary patch delta 2428 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 UJ%EnB&Hw-a07*qoM6N<$f_8F*VE_OC delta 2594 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 AO#lD@ diff --git a/TMessagesProj/src/main/assets/emoji/0_712.png b/TMessagesProj/src/main/assets/emoji/0_712.png index 477501494b2b5b5cdf08fcb81a09d60153decf48..8e79a81556be52e54a233303651cf8b9d3c327cf 100644 GIT binary patch delta 1984 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_713.png b/TMessagesProj/src/main/assets/emoji/0_713.png index a4df4e46adeb571f250e0a88cd6722b8d6e4fe98..aef258cf9de25f55c8f594fb3f993c719ed39a18 100644 GIT binary patch delta 1824 zcmV+*2jBRs6Rr-BBYyz!P)t-sM{rE*zm-5dKI*@g*tnO6uG^7nO_8_bpTg+Vw30nI zIMcI}F)b~aw%0^IK$*MWmXeT1MMaRZ)`@gv&Z2uFA0I0o7d9s#6Aum`5)C*uHVX*} z7#9~QC?_vXJTfjWJzz~yK{Ga3MMY;-KRrA}LqkkBF+VOQOn*&FSXER-Gb~|WUE=HO zTShx+XlTNXU45g{PjO#$n#kAJ)U~9a`T6*va7o3&zlwKnAwx8@epPacrFT;`Z*OkN zm1eEH&P)*kTzYzDkHfD}SVKT9Nmprf91^B=7nWo(vnni9cC5OGlHrMm${`@Jc5l!X z6i$b0tpET36@PS6PE!DnT3YR8QoJ1G|TUfNsUBeVPe|C^o*kRc^UY0|GfmZ(QE^zvQ+q@Mjha&Yic z=ionn{pIoL>3NBqpP!!|e?N0@d|viPqZ`U-H0qbd`G4`j_W`~;x-mkFoWA@H;WV*X ze*~fpkRm<)c43s-b_!z)`E~+%~lcI!Tn6DZyetB;4gU<6e z1%?tK{Uk}Dz-b`NY5Jxft&hLF(8T!iwv%x|Lla4cWf6kZ&ZrNg=nTIc|DcK6)paMs zlFkJJh<{@xK$0|VoPLQihV9_h?T>~S=MH18d*RYEEvZ^d+Db`n03pUWC?ZXh3k0Jb zF>Z*<@WS)FNQVYuv@fNSje#UBlvrsH2SE@;-n+{VflmURL??AYAW}AlafpIh#Bn^0 z<7k_J8zTiqLP#8`xG}IUgfx(E`M#e{DLX_|6Mv~sgzkeQ8et#-GzMaoPYKUdF^w${ zrU(E+2u_A{)3j4XTSmA|m_FzfW+njSRh1jW@iC948J}X2@UTOeG7=X;-G<0B#2|{0 zB25x)xV~RZ&pl9rF`v$R{JAu7hnNqE-r*xxPz+Lp6wM zIDZ`0NWH`i00`HjzN2t!Q6t?4LrCDF%EDotFa(n8S|p-(vR{DMS=1y5|tY6wv!eB5k z8AOcRDjLE@9LeQkvo7t;8LznQ*fOvD#eZfY)Z)fgrcUN#I=?_9%%(_gpAA%*+xPQL zE*L5Z#d@LoN?k7t8-D8jd!a+ z0$&f?C5oPQ?* zD^jtW<#O?fgdq`9-}LD%XAL0iR`h*%Shf(_P|k#VI&*c2h?f;R-~PUl$v2u!CQ ztK-mYGzPBo%m`EjggUMvx_7OZ2p0i?Rz!t~%;+v5@IYUt4G2^!9kGOMBY%d7Jpz0n zFeJ*z!VI13*c>%b8vvT5L3c&onH2#*LSx|6Ay+y=3tS6s9nUn+ zsuAXpAqmOp`alWPhD(H{1%Jyk8@weD&jMloZ)Q{~i6}*{O&bJIh`87$0x~>Hry(5G zO+!!;0MRa?gBNY3-i4l20G$2^Uw<^8l)u+o&7I#MwG%*{jHzhV^Sf1ft41$cq zqs92L$!cYYpSrm_I;x2o2xN{7mUw-9q%z33J8Q?kc($8Ytw2N@P0WaZadh%*Z;XJM zc>IlW*A3o7(PezaIDbI}T6m9)e&5btc)b0suH)4{;`LFFgx>r98WZp|>t8{@fO4?6 zk3;(ZjQ2;IKfaLl+t0+FPEM!hpHE^41jMU7ePEtY z=D!nE?Uy_09U|XG?3s)cL-e+ZU-uBN_Yp`<(6{Rlq$LouNg3TpOZ)?$PvIdnp}gb( O00007wi~FeL`@q1!AtEFr7!+SNAX{w0ODY*e zCKppNAUGftCmk9lC@L^AG!_;YEg>C}S~Z(vJ6?0hb3-VFP%wjof|g%6fJ`hnIy@R1 z8)At48yz4`PJd5~Rx^4?D=!-oYCIu6AQD4FMOJ6JS5{XX6cT8H<6>Z7XqEnEddy8+ zrAJboP+5;dOpj1suqHE0Tz&3XM?LuY{a0j@S8J@jzs(UB9v><U-P7u?;YDl32SJ>NG&yJeGs7nmoLhx6ul&YXmyqcz>eyZ^@6-*Icy`l<83{>dMI z%me3B-M3cg2HlNsAc4%xl>W9MdPDO+y!p?Cm|hT^mygpU->^ zpG0EnHZeK}MNuS(V9@^^I0+JjD4Ioculhzqx5kg_p$t`F2xOGb&A}1fO&K)!)$wop z5{ZyRBH=TOSVIJf5#=1ZX#yEQ;0vX)*}W^WsZiodLfltW+{Z0Ifte@ zCx2oIq3KlGN=?uL3egN1_MqM^1D3sP2pniA%B}SJEug?5WQ7b;q~w7B?H66Iu~_63 zxRJL%7((9_BW)G^7D+*1M=F)VJBA<222orjf(t>7zMW#kvW_L-fJ(xjPLm`Vjl#iC zn85~AtJOt?PIS|<0vth$B`qKbfq)}PT7QC~@9^-judlBPir#jk=vrTw9dM9#^ZR!C zErhRcY-3~Na51&BoF{pPW1`M*IPAhicou^2Jj+`*HWn8a7JScIDMCT4NJn{= zp&~Au$7b_*;D88+Z6J$K49g$(A%Df@O;ICtFx4gd`9i;MW~fr_G7-m(DPH^6eWkc?>j>Gdc}@$OH|fp*O`?|<5qh@4;4 z57yRB&Z88=r~Q6SudYMg=EJuO6b$7%I#>h#JUXyRA+{R3a30@kWLZ$8)A-X7M5*h0#a#sP;EWd98c&WTE5fBt>iIFe>z|J1nj!V^bFTND#br@Iss z`YyDTF_-7`=))=0o!B=wk$>ggr^eCg>E(wlucYW!P-vi0hVq7OTPLTdC-1-jfaM*W zpKRH}UWz3_(W#_>U*IWc7*^BcK@lWCVn@%|A`}bL)F>&Y1u`vgG1zW9?!aybixdP& z!cGoNQ=?b9y%E5{Qjsty5H@&ZbHSEMIb1Oq1u0DHloVD$NW(RO7=L&KVf2Z?c_o7< z41JKKV4YUCSE!9vt5ry|F|QoM?quUEg%?Z?K?;I(utQM+kOGP!4b$eNVlKO6Kp_M$ zSdASD^zNe=B#)+n-s6xx5<$a-Hf-J)0|KB|NpXK400(Nt=5fa3JkQ4YI2(fuE+=Od ztowlC4MzXI?0{CnHh&uxm0-QdK=EKe^viAQ9{}p>3YF}Dad^Sur8tIzRr|r9>hDmi z)el~d0{32CS9Ghe14c@6v4{(O{Cd4EbaYa<3#{mT^S_6qzt7J8{@dt({vfp1*$4{ti~%ZydaDRB1F_UFI>4Wn{SK7}?deZ+xOj9k`919Xh>E zX~}hJwcap!_kY>5u>=QDh**ZK2&@;H-m z6lwtn+zFSKK>?k#9BAjjKru<@lad0+BS-n`SAQ@dRtC`j0&|k0btjVp&`{P@m4`E?kcK@4kNym;~Y g9vk8(`2Mc=KaY<&bGhd-A^-pY07*qoM6N<$f@~dy7XSbN diff --git a/TMessagesProj/src/main/assets/emoji/0_714.png b/TMessagesProj/src/main/assets/emoji/0_714.png index 87ef64a7627b957634c0787c6a0d2013e36bb9e2..c7a5efbd6270823dcb5b66276e873894574835ff 100644 GIT binary patch delta 2287 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 LNkvXXu0mjf>fPyL diff --git a/TMessagesProj/src/main/assets/emoji/0_717.png b/TMessagesProj/src/main/assets/emoji/0_717.png index d43b7bb8def86bc83c1ebd6f237ea25c09f3acd4..1b08ee7af19fbc089b1e98c94cca4e03fb75e5d0 100644 GIT binary patch delta 2099 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_718.png b/TMessagesProj/src/main/assets/emoji/0_718.png index defbd354e651fcb667b14eef1d16a03834cbb11b..39b09fcae333ddb87c0eb5cb45a844a022643203 100644 GIT binary patch delta 1948 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_719.png b/TMessagesProj/src/main/assets/emoji/0_719.png index f4c55ac397158afdee34fd2fb107c8a4ad0380a3..e77733f54172d7145fbaa8cf64e7d658f319100c 100644 GIT binary patch delta 1943 zcmV;I2Wa@x6QmE2BYyz=P)t-sM{rD*l#-TlSLe5j*1Vp(yu!?$bEvAL#+Yo^%)i1S zA*`&dvV&POE-oe`BfNrypqrSQOHj48w!2eREGH+ctE(m=BBX+5*{p)gp?%Jze?wGF3s!ARn``vP?KJs(-4gOmJPjh+S+^H7PFGUBJ*A|gnVp|4OgmF_W6c*9U`#;UaBeON1c{1=_xSh8k(JTU%4KYByQr3T ze0+OpVw+_&<;aq|e;b5yPe(vMT2N0tI5#vgFHlHGUsY8Y5e_UVC}UVyBN-GWA|YBu zIt~d4t9eg(T7NvjkYxX(3Qzz502_2tPE!E>!pAfI_6qMq=jZ;>aQ!0u#{8gyOSi_c zxbt{a&Hw-gJV``BRCr$0(MxW_AQXk+NU`J$3d#VvPSb zNJ_j2C4Ur4abQDm3^(=KwAMnEl$yQ&yX^eGe2J7D8FFNjU(SEiJ+xf@@fRbOZ~f|` zyrqy&aR8&mx!d6m7w-6U*UfMDXT<#~)TthoPUO3d0X|aK-qc+LL|s9&`R(5;qAnmw zYEP8)E(RM0g4~qSUB)7XsIZnvcd;{F4oln9>*!FlhEi-D2?3@N0GBnYJz6NJjxM7h3% z9bN8y&KMgbNWctNLu*28xAGlgLwR5X#~MPy`Ml3rAQ?v>@{?Gb|3iQQA9_vk#%L{{ z?|*xyu;9l4!i*>phA#C4fpRLP1YAG?L0HNG7!a{MMdB#IiKI$c)}olCQ%Xdlw~`1k zH$!yB`2H%yV!9BF8$-!T4MsLYAdF0xl8b=@J=8Q!-}K|BAveZ*J5Y5?Dyf(il^9B7 zKp(wQ8q=UK7Sw-AgV?$VW&O57~8jSZH=XK{mQtPA7KZ; z5Y{k(R7?>V5d}#?gy{3T<>GO$iyTRffV!ub$H&1Po(#=j%BZjOv^#4?NL(#?+WAip z_JrfV4i11Jn&ZKqz7M;5?S#sqiRzwLG_JTL4J>&%H!xuplBqx_J|Yz8qKjZSV}FeIE(Xi}WrKBwhc2Ftr>#a69`>J%kL}F z&Vc~sHn7GyX{k3wHb)dd2+c`KG#<|3<}qe@^E&qD`6pv(Oo0%yKq@9sqJ^#o%ZFLH zGw5y)NW+iDg#>_R8&d?r!0)uEPc)@8;4BwowEoP47mS%^gq|TbFi}EVIDctFAREy6 z|C)CMbZerWJR)-Df)Rj=j*>=y0HPpe}8x3rlHm23g5K= z0EpEMQE#B4;2TSopT9hP5Amwub@B9NtBA}I7j)u=Sgz{-3a`7?gkdNE!^`mCx)xe1 z#hZaeI|zZ&htzd1F1YTgXfhcf=$&FlmNA$M20Eo zEq`Qtk)~h>HUP_@8NLaah(@=quog~)DL19>HNn#$M3AlVqn^D!*lXO42l-iGg5&p7 zODM?%#F6vf7sUX`gwlmcKr2;ftuw&}LhQU@B@D2z-x(oX|9>kC*WvI(@lpsphtQ9K zSfJulg4uz~mIFl`#ty>c_YEPR$Gh#aqcR*QSrdNbScf4vIbHp(7N=&5bHgJc3CVM; z1CNGcVs=@Jz@(Gt`G$~8Os)`!*m)*>kL)bO6@t*U83_}3o#1siHY4$E!u%+w_Z>0e d+nUYz1K$#K=@3ouM_m8_002ovPDHLkV1l|MmP-Ht delta 2505 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 delta 1581 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 u;$Pmya_j-?VEs5C@yAn!aqb# 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 w<9Wr;#NOT>UaYo$Wcn2djJ3c delta 2616 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 xDB8`ligu&qwRG*d-R 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 delta 2520 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_726.png b/TMessagesProj/src/main/assets/emoji/0_726.png index b116547bff6c0c4d3650f4241406b1764f0fea9c..f2aeb801c47691c5975a5ba697c8de942dfbe940 100644 GIT binary patch delta 2878 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 delta 2278 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 A+yDRo diff --git a/TMessagesProj/src/main/assets/emoji/0_727.png b/TMessagesProj/src/main/assets/emoji/0_727.png index eb8c03ef2d8a9bee4f015ed745ca8559ea964afd..890f6dc90204f4ff36cf6a07eafa798abde9e31a 100644 GIT binary patch delta 2595 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 FV1l8!;12)* delta 1537 zcmV+c2LAc06p{>(BYyz%P)t-sM{rF0(p`RlgCs7bW@v2q%Tm6ob}l-~WoK(AGq~2K zH)3OG|IbJK$vae8iAGJ2_P!^9gokKtmHfy!`NA#!&`bBqO#04LBrTiz%Sb6PoA=dv zCN7Tnz$8minDDh5iHwehiHnn!myC{(gN28Wk(7RcgP^0RnSY$1{{H^Gzravftl!|^ z%8V1FXbYHJ2>alX|H>`kq#3Sp4Az+y^}a9ixFd{D1nRFH`qy^<&p!RbCH&K2{Oh&2 zdJgr(L4rmCzJ(a3g-8GQ*1n}~{qMj2^UC|>q-;6^8W08H(3&b41xGX&bzL;XyR6mC zwOUCos3X540Dk}gAaqhrQvf5w`|kS@{P6z$@H}iPPsDrvnC4EW*W19f;EsXoqJXyV z6951Nu1Q2eRCr$G(#eh@M-T>Jb0`i7BqX{)Xw>o(&A``#+5%b82Q!fyNf|$DY}_~&6*gE_S?(N7PGZu@d}1H#432_UqBer7Dk_Pg zi78GrKYxCB(e@Myohl6&R;db`bt*zw<8`D&POwkbu`-j4E zo0?!8V`9h)76W(}aZ0!(}pR@p#ni8!bKrogNE3hC2BMoHCqe&J|)>@8hjHG4$M;I6h0SA%u znSUT|V;c`9dDfgm84=P3y;`Y>m=rG4(=#qhc)pt_Hd;2RhU=znaSI5W5_p5#wvi34 zO^Herw#)f#LaX(;7D$V}@9+0^#eRnOZF_s|g)9jeT-pcA*jiBoQSzq0-uwIIm8wb5 z*Y@xJcI&TL3S*4mR;}l^DGd+?*>dPFmw(F*7cQ_A-@RULm;0(~QG>xK?flJH>#~l7 zwAFCE-7aT73{w}hYr(`>=QzSO7&5%f9*Bjfi3oITiQujqr+uEfE5VH_25%El3q5-z z8%_)uH4w}VS9j`$8~_iDFS^0Gg8E<)0m2YIdp}WeMLje5`Q8>VjpoC5ts;Gz_@_C-VCq&uUDT!Il5&Q2y^Vj2i|CO2Rx%{Uwx^Ha|h`|6pbkxbf(*7ky%Dp64 zXZ`-4Z%Jy%?zGP5ghJ6DPjb~Ld4KTP&L|0Epx|XqbQOU2&c%q7z~Q&~ksu{T=e!4i zl%U#b;VDK~Mir0*B~rE1f{lRoxwVM@w}5pE142%u9l{A=M!pIm#JKDdj07wJjL0Rl zg%K7ZJPop{fjY-=B8pHTlp};)2_p-Gnrxftyg^(@U_xu~QAh>bX6oJ&R(}Jfy~BBo zB3O&`mPl3uHDQ|ODa4~K5_phXwQb=1LwPt6vTdf*265IFRwIrq%$|oRN>r!aL5$EA zWEvqxwN>JtU@;8w6BCoy5;n(meW_jF{w0tPMi(avnP>!siGH=uTiYlhh9DHDvoYb9 z7C=OME61oyLX;&YfVOzH^?G?#qPc<@5(D%fT?G?GjjqlK%_adtG)0X;h$Mz0Wo(&B z4CNd`cp>~DqU}%FjS7)Kkv&0)Y?5=$#Pdbu3*|=vHWX=?7>pQ{U__gg0nqP-AfxWP nf@tqwSw8tt=;xJh%iV}ydY{IubjyJ}00000NkvXXu0mjf0>Rkb diff --git a/TMessagesProj/src/main/assets/emoji/0_728.png b/TMessagesProj/src/main/assets/emoji/0_728.png index 0646ec59445e224ad7e965289d673db7b353a681..98bcb78bc90e92f2b5034ef9434ad954968c23a1 100644 GIT binary patch delta 2901 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 delta 1600 zcmV-G2EX~%6wnNiBYyz`P)t-sM{rCoI>Bgdgy`I)WoK>d;h^N#ktHy#Vr6OQ+m}#S zs(*omC@`C7ZIyg~g5lGY=GvJkFqOosVddGFeSd{2GLunOir>(P=-im&)}MohiQ&?Z z=-r&kw|3XVeP(EAiHwenj*y3mjE<0!la-f*hlzrOhLMw%et&_3EI7%bqo$dhp1Qof zs)|P0$bGYwOwqn|q<}o0c|6OtYnO62g;FfGbW8E+#>tIj-_eBj_2#B!KHRg6kY_QH zUpw;c)V-lr=iHdSgIms=beDKxq>Xyx){Wr1l2)k5C-6p5J+4FnTrIG?l(B=;(cG) zwHL zFiGMZH#CyPI5GJoZSBk-9WHd#&|7FLdm*s+_!-~B?4o7IEH zeCZ_0XbP)Hkip!I$z#TgvvasH#Djf0z;q58&V$Bmv)ef|GCHlZ&E|;Ay-xC&F`p#R zm}(PARe#r@Ak#ZYY?kxy$G~q=0W}D(5y_D09W)l-2-8XXH7>LmvfUw>8QdPHGRW;ilsV-G{__&}E36iF2WEpEqXdr?-uHJ5!+rhjQ zD1cL3tB=d!P+em?Hc}FpWIDV}rnQb@JAaS;%K`G9T%iW$a{hqpn>bfNV6@c48s6tr zk&bXL{`H1;_0Badov(0Uw3ITX!-OR@8nzpr{PO)>@Uy?|lAPbnd&CkybZsOw z;fo<+mP+^(i9HzC@O1W1+djK<5;jTF>{|k&UIqy!F*N36(uf(#Nr7$J-isd19916rq}kbpS?Erk$L{2U}w zmf{JQNc0s#z~I>#4H8n|?+`LfTtD-655D}oy#AJ<dQ|M{n?VdUViQJLT>_h4E~R zkwO3{<(#Go_@pnVopVY72q}%R)_eQbCuAiuk|Y91P#^>u)>Z@;xi!_d3ESMWP7z843Qvi9s>qu#Qr>8c;EG$1ut=1Q5~8I04xn-bSM-UGO7KA; ztn2rxlNp6dj6K3z-XyJ};Oh_0Ll8iOti<_^DA0^l#6Q-}^R-}c018FB?16p!Ju5F`-cEfUjZ zzs9sI-f~7~NT7&Rahj&nBFG>_Y#@;*??J>e%^Tr1wS=g1M3fAU$OIev$){jq zdySb1$wrT`mB3BLW{*VplF>oRF-;QuuxvNEPDGr%&qQ+ze5$|^R5`KT5jB!8t)OjJcja7@W+2Fq*-%W@LYek9X-8uW<-$Av@AgDcd2AMJ}2 z?w2I@m=Vx(56El_$ZQSnoe<`d45nxa*n9=kaRY!x1f5_Al2rw1G6LnbD6@MP&z~Z} zj2!>;bN~69{+k5<<75BTOaJ}J|M!Of`?3GxNd2u5|H2Lb^nYLfyD9(hPyfp{|LQ;f zv>gA}75~9B|JyVF{^0he6aUjR|Kl^?h6w-2EUQs6od5s;5Oh*bQvmefnmK&@4k1{< zo93*|z4LBNaR2}W)k#D_RCr#@l1Y-=FbqYzDxx*|2;e+uwB18;|Dy$sP%S$7fBFr$Oq@`*7j<%4*S6H-Lh)<=+e;NUJTPGk@Z~=I?ZwM~?b{2CxKavhf>| z9MvO(55{sN_3Kz0oQ}zHyqBZugb$Jvq_G)%L!pD^hO&tUV@ztbJiUCyU<+4X9O_KL z(4fo>Y`llrID66k`8kS%@DoS?vxi5Qp-O;}AO|nnd)L4tLl!W10bB?Qq|C2UV+bV) zScwzsFn?8Ka}3+xkwOge3iLhnfGdX%B$3C6Att3_j$ZZ~u+<74(!5k^5aPH~{19Rx zgL302$Nn*6KT78u8q^tM6q}*?Da4=<`5?Ra?YBBG5{bvW%sgddGxJ4b3~Lrgzjb|-=V^`jqP%=0*oKbLPCK=R`cO?}(0>qabdUDfm3;_s!bno@)nLO6 zB!7l=U5znUMNuU4!eFIMjgM7ngcWH?#DNfBkNeZqpfT2kQmSZ{Lso^)3r)chekd2~ z^_W1wAd;wD=Sq(UqAqf+l`5U^obE60>gt7JUp zyHunY5%-GUUr<9ROUGtqQjX~wK@JBFyr~=z35ils(~d8A%_}eGK>L62Ls;{ z2*~Ij6MRQTT+4Mw+=MuLZWsuRb?yLI!vG9EMu%>o&>JDO7d-S+5~#r*2#vRNCV%MQ zN~G==#x32|=!Q;^_vI)tNC^@=5ayC?#KHK@kld8Lkn%ue80pRcB9X<2U2jV~No4$@ zGQo|6Gn`V^Rg&N+yB)AAkwpY#CtD5PFA4@J6IC!u*GGXR_*HjjA~o1Uj0S+p5e2Dg z1rUKHcpf&V%x#4RQWZs>Yn^B$SARv)T7iSOKT-~JUnAT10Mej=P9$2ZqLNKeIF@kJ zuswiGN(tbMy4{3Hwjm{4f|xao!6HqO3t*8VA>cZAkptY_u*THGsFXesN>gA55WEwI zT)fm8=+P(+GT)*RRSB>OvE9buRAe4N`ov7Lsv4xK5?H$IcY=Q=a7cKgA%B}`>$+@L zgnyM~UG@Mt2RDfK1lAxTv)lggBnW&GknoyerWRqId=LU6_|gCT(=x!%#iKz)6t`Re zO!6>?0}|ny3L?R32JVZSIE8rg6B3?0B2XOjz>K38xP ziLM5LVjLzl>%I5@e00v2*g^xdi|1dXKL9o*I$dMm_dL&!Z>P%{>n-pnOc0)tFbp>J j@BU-r^D%yAXno9o)w_=tpeAH>00000NkvXXu0mjfc7eh$ delta 1425 zcmV;C1#bG=3!@8=B!8SxOjJcja7@#C7Rhc6%5V_HdnV3$9LQ+}?VAw9e=+Hf8tjY^ z#c2r2Z3^z3AH-@1&Tcqt*)jjWE%u`j{^K z_I1>A1ONDz|F|Uo{J#Ik4gdb*!%7@&0000GbW%=J0DPvDG*;k&lKLMI`Jls|&qWx4B%i@LxqRa^DvM@qg-{FPH5FF$|+J+u~J3zuXUc zD7G9zz;wfBNdCUTJrw7y%B^CKVFaT$HyMbHe@3=9kjYu5*ofebo!UzwlErzkI3sYn z)v6x16hZ{f-6F=ch}}ZwtRri6IkH=XA{zg_jvkGX?{>Szabbe0PO$>$J~N6LBN856 zIqr^#f`3fNJ|c7vr4Z55z9IT(0s*3eLRqT;o{ z4myRBzI^U0yjh=>7r z9!+9(=7@;!e7+VJ+(cED)uBN>((p-1ZNzkgCd?%EI*49EB7A>Z#B@_ymuXtoGX)TO zJxOCGrgWp{g+#1vwF(fSm#{IN#@W11xu7vb!$exovzTrmBJn~HY8kyH4e}BuNkRl0 zD1WG`Hj8DlwyJ=}0Eh@d1bw|t5ZZ`&5}pIqc=04%JtM6DHAy4?_w* z{c7rcPYIagy1W>R{CI+@7+zAM71482YSEVfv$bUTa z5!A~jKulcymUGf=T#>8M)Q7sNs=7XuZ15on-NXso>?}jT@HEj@{63SWWmzBQ5IiFY zwF*6nY=aF(kQoUnQr2|~Knb!5%pubQ@t0B7EFjfk=HCh+@JRJDxi|P-20379*eqei%H4^Kh4*GPn^^*hnk>XRVsIR1biA zfN<*F0eC9L5Ev(Hn|V5)H6bPdpajc(i*PL%8e!)}zP%U#dpJEo_{4}n2!EYO0v`x4 z`q&2{q=1P`y%8|Qy9RcOMu3(O f|NmzAclr;ytwdW&=sR@)015yANkvXXu0mjfj_aLE diff --git a/TMessagesProj/src/main/assets/emoji/0_730.png b/TMessagesProj/src/main/assets/emoji/0_730.png index 2ba43808795b140b3c1c88c1945c302086a3cba0..80d6e09f7c461ff5a810e74a671869fce384c234 100644 GIT binary patch delta 2468 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 IM6N<$g1nqfUH||9 diff --git a/TMessagesProj/src/main/assets/emoji/0_733.png b/TMessagesProj/src/main/assets/emoji/0_733.png index bced3ee13ee5e07044f2d86557a9a50adc88cf64..a11a32bfd52af16940ec4bc091963597bdedc8cf 100644 GIT binary patch delta 2550 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 M07*qoM6N<$f~$7`rvLx| delta 1616 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 delta 1631 zcmV-l2B7)274Hm?BYy!JP)t-sM{rCa9Udeuq?m$YAR|I5HMdMfNM&bh9vd5GXlU zg@}qHA0K^ygCZaxCoYc1$;uiT8OfD%>9dW)#m2zE!@s}5g@1>Mij9wjhl-Grl!%Iq zf`o^DfP^nQ%AusECo;L3ouGk(e_3Fo8Wt2IARqSAvG?1%^vkH{wU9S5G5-Dg&Y5%j zrzNuwLGYt$2vYmgxieUNg-&QjmS58jb(8FC* zQc_7tHYOQiR)1ERZA#+Z)?`^(C?zF+TQ#|aGn18&}gjk-xvd7z=600000e zbW%=J0A2e2Ama_^JLe$hO6bA9r>K75f_b0LhN$Vz(UwxRP-y6W000Es zNkl2lP42EsU5QG3$9bFW#gCJ;<_B;V+Mt}Rh%lnpY@BbPlN4DyV11ULo z=eG@rfcfz!MUMUlQq>7bRsUnUHa2v9O44V>Sety9FxID=-LcbVIyJNpnVA^=`go(= zakmU?UHbrH=I^>}(t5pKE;sS~QGM?e3>I8!AFugH*aU$+dlzFen=^9=6?jql8RpdGMfM>+Zbf1dazsD1^Am~tG2q7kFt};!Iv3hSsx1K2UoSpwr{tZ zYXfaOQB@xRn0-^4l-LQ$P6oy?wyCNOc~h{&rpj$Trk|3lw1I^n-wB+nrT|Q`=__?2 zNzSQv8tRje&g~PNttu}HkXaY8?osdSWHOgSKYu|UTJC;}5XL$LJ;`X^cXAr`j|AKc z%QO+v08$V`Ab>0AS?il-+ck@~B{xlzteo>^%YZlqff#+peF)hv6hUP1i;xq!)jr>{ z1{g>i?6DVtVtJEfLU`VlA`Q7p)c}x*As1A}4J{s~Why*@l8`h_P44D-G293OAUAm# z<9`Cg*-y`t6fX;K&b!ibu@%-oPVE^Hl}KYHTVZA=^s-8oAT{@7<9X7z7thiJ7e7hf zU&$DIvbJdBN$uTE0GD%5q@|){-d~8oIL(lOHozG5$zUup1ush_hjS*b9#$p3RV7UY zcY&Sy&+K832%a9!N?8=;>f%GJaz!a1{eNv?C-F=Fu`k>>;^E=2EuesXO*Rm7$N(sI zGBeEAul}5w3!L3~08+PCA5Tg`s7( zIEl#nZtU9^)cyVUU)kzL8R|Ct{_CH6`s3GsnTYzQkNVk790tMwzKYhVc8kQJu=Ic` zj{YAKIQ9+p$|cg|{a<7489QUhXn((|Jy879Hy*-%!d$P{DgA6y|2@r^v#`#Opsn@B z7y##Hm)?bME+?YOpE{%F-DQlNRaVb zVx|(@A_{}_rA4VB4uXOWNSvjOJQHp!0Eh&K2oFTGhHG!L-o>Xtd})mzEiFqs^D#D@gWg^j)}09K*UU0cvu4t)|D2bms%Xlqsq4d?(e3B zra|_Cuv4+UPsjk+B@>Iz0DrV|+)lfV@KcRQB*Po1h=(P`qsc@J@pf06FTle%WCCm8 zRw%}%7*l}t2}#6wcpaldf+oRKBM(4-P|z#U?KUNbcq0Ol>KH^Y{DdGe9{Q)7=n`>9 z;>iF8@_a2ZywtdK)PfB>(!{U(VB*pUeV${u6M;rKMiObBSDKOu)mXP1B_eVSLZ}Hz zDJT#z3}cyu_rWbzfP*Nu&@=}Tmn{*oMvClyr?;A4`L_wZ`u_G_ db5bcp`~%F9NB?GBYO4SM002ovPDHLkV1ne#{M-Nl diff --git a/TMessagesProj/src/main/assets/emoji/0_735.png b/TMessagesProj/src/main/assets/emoji/0_735.png index 75b68ac96c8d6374de5a20d255803a51511d090d..2b79d60e550fb32b72baac56c64fdca3f4203165 100644 GIT binary patch delta 2573 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 j-u~(@h=FO0000%kdBa& zeu0B7I?5+9x1gk`n3|oOprfRzt-PF8(4Tj-ibdF}gWk1{!-rj^c0l2~mDtCB)4+A< z)3og4ppIWQw-I^E?2*$Lb_VDDTi)}?D z2bFzU(#E;)=zpecP$F?*Li6jX+}+(_Gyp0*uLA%803~!%PE!ClL_t(|UeuMzZrd;rK%;{RNLC?& zb}tT)0Bt{kJGJlLou%#n|4D~bR0C}wIlc9XhYY}ZoPQzd@a{jr_ZJr5|HpK18Lpy; z5E4bJaOo{RY*?;H_Wep$MB(y7#rPqCyl4Btc(ag|_W?y%JpWC$>mF_`#Ct%y=l95p z@FvG1j1x@WHDp<_@^3J#c3DD`?3#G}fE()YSCHIMOtNg3{lRWm6h-$idzb|*Mkq&Q z2V`!HfPa7#MdZ!25!uBE)*N-k8$&8_bR8ixtt^RMjNm+{C?689|BlK-@)( zDMf7CZW2V95Kh7=MuP@p@K{HjcvHI>cdl*9nSYQ{FcoNkQ(Fz@;BpSMo>Tx0Mo2L^ zAXuwZ5ZG!oMc69hIR#A88cS)6kt4#1w5A%(SJ418U<_98d$5cm#+VR+&M8cY@swhn zBnje7o^p$<%d&JDVZ)1R1C7Cfr?%6BLaCB{ei8=K>$)yM<3v)Na>g`In&f`!P#3tt zP=ACp^@!7y!=KQT(x^e3$=kVUs1njh)@v%u(E$>sDHBjiKpXVsZi+9ME120IF0cDn z;~Y-WUtac?1JtKDqTZz9F`%uGta`ni_WM3{ZNNxhP7oiSm~1(|_oo#K6r%dEx8%q2 z&G6)6y*&uV@n%jDw8CtUXE6Na+jQ88Dt~n`-BzGzXB2Ctppk0ZpU*EmwF>ykYI{1L zb6#yz!BqP=^MnLeVbY`IG(Cc0pn@2u$68v&dRpP%tJd9%w5rnjdLlK1sTqECbI;;N zDF$Vj(gA`L3=kL?R?)U_H>X*24)(Q}eedwt^mY*D-4~N6kZy*@MG5+SJeSOE||7xUeavO(XC;-p6G1_bb zbm24wQXpMOvP8;1%_(Lv+uZ*sLxvVdvehCF&dR`t$Cn_Nnes)Mrink(^-2$Cx`$uQ z^lTk%{u430YD6)4}F;s0)HYHyv3|ckQPdiajwjn2w$-MSetpF)VXN?0dj=o*N(Ka|NJ>J&?hw;J&wgwYyEC0Mw5BGV5`iG7_& zzfV9hApB+H>Q&G~E*0U>M4Q!+xQ>a=Ay8P*HD3-Jp>0MbKnVjKAfb)~PIdH?gUXl}0YH<8IL~94mz{Dvh8qTxi^?4nA@tU%0C_?-Llrioul@FCt9{>OV07*qo IM6N<$f;B+{BLDyZ diff --git a/TMessagesProj/src/main/assets/emoji/0_736.png b/TMessagesProj/src/main/assets/emoji/0_736.png index ed35b85da41a3ef076cc75f1758f50d4f6da30fb..7f0e8d2379a7b79a6b040cba1b6610d915fb7c29 100644 GIT binary patch delta 2507 zcmV;+2{iVA3)B;kBYy$oP)t-sM{rC%|D=RG{ zAVyDyKvZyLXMq(L85I{9NjWq}N>g8IlM@vfF(@T!d(UQUnmIc_VMHrKG$&6oC2w<< zV0PgpFFHpoAXiy%5)~FTht_k?@)HynKP)3rU7uT~;8rjkZGVRJN=R00Zh$~Vc4~XQ zeTAOq{QvXs=~Q8LadeYYSaYNJ{BP~}$NK-Krl^gOlg7r!dx+wMgoVJv!yq9dhEOke zMkT zm5Nm|ODY&#Hh&&fV4+np9V8|wX*?uvLMTd0O=5AmYk%1o85wJP%3N!;F&+^?B^NwD zLRnZ@V_#uzh2>CCQ*N05t%Y4%bj*0A|1?8iW{LB3b$4fX#t#)7dV71IX+WE0Jz8Ll zDKN;x6B#<00(4AL_t(|UX7N8TN_;#he?(gNq`257Fw*``nUajcUCQR0f3^p(XQ;V>(3s+257Sq{lM~AdQhzJ7vN^yt`mkN`hSYN-_ zAVkCf3P@p}he9fXVp34-rc=S>WeSK7+O}0t2oj$?ix&5= zEb9im!1;M_-efbB4i2_aGg`DYa@?(`Kmi78#1u@yayJ_Y5CVZf!0-0DdwOBCwvl3D zqPuddmcoY=V6dO}c;k%K$`B+#k$Pc9Wnyrb6 ziGdmlMSC)`D#VDp13W1xjMowrW(rE;S;kjFiY-lz6m53HDqyuH{JhioF@L}2K07mC z#hA{Y_4FL)agsaGT*pSl|IA;IcKe@np z7uzm!Pk+GradKn-G*A8em*?-MswwiP)#D4wN%#YOjTQ1i*3XlaIsg9syZ3oB7&bP* zG4=7?yZ09x6onIhzsMtkRN`g{(rhuCjYhLz$Zw!p%od}CqRbQ?@PGHnK_Jo$!bzDe z(?&p0fWwHGwph$0AMi^QO=6XJ12|=dvmz`MD2!&o01C>x=4@%^}~!4JSh|f z9VT(YWmU<<6!K169Dia!DFDi00l^f?V1`ck;|A3&F@4k?JgE1*ARZUh8YyChG;< zh;s+mrPIPX>7$)T;^$XryB__cf3ANr{)Y7b{@Fu#~{6zQgpF5)0h*aAJ>*rz@Gw=kahH=h^%1?VHRTk4Tr7mXLy8o?AG`(KMZ@mqYnz4iymNJh52Jv-kGx zo@4xv9e;R?-wQ{Pg3c8x3vY5ca6PFLEqq51|gdJ~|E=Lg3JY0uCIGP$3NK!x>Km z9?NGl#bOQ=o7$SKa0rShWB|r59WhTVERZQhd_GJK8$y>sp{v;nq=0qfdO=ZTFU0AQ zAVeD0Z$&U{Hbc|7@@ARd?5Z^tkH^Nwnwy(%-){bjG58N+thKYVQ}cJk9r*dI_%D^2 V6zPLnoQwbf002ovPDHLkV1nX>vVi~q delta 1390 zcmV-!1(EvH6MzelBYyzWP)t-sM{rDtUO~sn%3(h^XFeitLnUQqY;IIbBrm9BJ0EXF zDJ(a>DKV2KE|pqgo^(hnvZS7Yg@=8Af`x~UB`u(Qe}a5}f^Tz>k6=YvG8KY_hlz}i zhKP%dkCBj)l!Aqae}RLer>iYF%qKFto1LJ&zraIHw_Pm5XO{i zv3y*Lr-%Oi{SyxeNG=@A znr`al-QA^ku!B*KfoI3JtCN+N!-f{&Up>|U000|wQchC<;HWfRt>+m2{)*#Isr}{r zf38>R_uKrl)ql#PF3^Mk00crwL_t(|UeuMzZrd;rhGR&EL0x>cpJ0ajrph^%8n?L_3x98Si}`SLacCD)Uk@&v9ZdCVJl!`)Vb`KK1OOlcImBU5II|v{LtZ zXwY?%#r~NXXk|jRav)Ob2)A1&A><#O2tkA}X+l%(!*j|VK=4}%BEknkd~AxHRQo)1 z0YbZ&B!7@9>7m8M;@R&?ikQ0=0M5=52~1=FvMq^9!>B_a$sj4P*l=D+nefvx+c;O^+oJc{IgUvQ<}zx{{NZIq!BLy>a+b3HH6{h2#>=V8drIN4DJ!Zy zDXbYD!`pp)4ELFF+Mlg;h;>=9+hm2g4@5o>udgXb+MkWh=e}CK3b`YNQ5iB!iiDZ| zxAZ~E)X_U@X9bnM66#5T{IGr%1=JrgjDMyW#!d!uXzl45Sz{}`USix0qI0O9`ha7h zkKdKk(T>_M5Cza`kxC>8f+g%q*ke1y;V1gQL;e5X)Un6Rj@?nqUV)-S%F&&%a(*j0 zrsMCg95Ky(N^cZRy2g@up5v@0&M}sM$~h@Z`0(CZg8=~NTq=pFyx4gSPTPw92v%ZlZcH07$&?<&>(0uEg}!%{@3DaEfG$c#K}R5anepiws1)zt_q@s zO1vY11`r_)Creb~@(;p13E6{NFcHog;TwV#R|9PejW`j(2DQ)1Hwmf%t|DOJ5e*5= zfm}8k5vTtQcdM;1-8z(-Y&839(R$ zA@nKm7ZMK3*pD$Rx6dyE*kG#=qQx@o`w}-I$Pi5CObwSPL|bDs5y1vjre{VHWZZAd z)YLc)nFvInp@ruNM6@-wVEqJ5C=m#0bp16ln wgBYR;S1y*PpkV8zA*Nl<&)0LjrdW&i*H diff --git a/TMessagesProj/src/main/assets/emoji/0_737.png b/TMessagesProj/src/main/assets/emoji/0_737.png index 12a964eb7b448d9efef1e542ad84728362ce407a..7cb6bef4733423229e106955c344e7d7bdff4db9 100644 GIT binary patch delta 2281 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 delta 1357 zcmV-T1+x0h6yFMvBYyzHP)t-sM{rCmCM0EMY%M1xGBZsg9ULGW8YnTMPEArwL_{Yc zAIQneB_JOtFq2SNswy_Ze}aT(Y?gd~f+jAPdwzw4hlyidUn3qJeSn0<$jK)zj=;df ziHwemj*yO!l7xqehlz}omY9BlgDpA9CNZ&5JTn~`7cC$dMt?IbHZd_eDIyXM3?(8W zS3);jM>{?^IAT{;EGQ^fPEF?E)0vESdty6AKR=|Ooy5YvsjIC0{r!b^Z^f#6xrjYf zDFKm_m4bwZF6NE#0000SbW%=J0IcW9B3(P@5c`p)=SuzMy#3j-Sb5oamaT?TJYdQ6 z000CpNklps~$?zLvi|c-hTTO4WJnXRwVB#wzx%Zq=w&u{tspN+X0prM`JP)sgs& z#Yh^CO$dTu$4<5fzwH*tb{j?7Frh;fAqd%4ueCe`rNveiHD~WEqSnHYke&AXLBx8u zfyfn$5r0z31%haU)=%4QmXUQzab`3c0GNV*Flg+mY!ksEgJ1;A7%c=MVV;5ZF@&Y` z;GFl41#ZbBcujAl;Koo$=|Ix42*Mu0f6Cp(GFGmPUalYIhkLf-v2zS1WVIHo0ORLBe zB7cOC0ON4G-^j7<U}T0+F1_r!3F1p<^w3%L>qVd{;Q z{`lP}9qqUY15p62sz@MJNt3W!ZCCaf6Mz1IhmgM5|Nm9J<8aYrpGtV}6xH zm*RCzlqAW#Mkjyo-&Lgc7^9xOz0MVnI!H?I&&2MWL+BmiMG_KC@G2tSyS@)0! zOX6J#8dN06bahJ!u`PBrVz5Li@o}D~IeIax*dX2pPO{bznf@VHC&GV|#JSxdSObQS zDonk%tFXj&3pIQyEp9ypC2}E-6@OvhfUq?*{alD39#LWavrhXbVb_d9wlzwepAoO- zLa@cDdD>@pxfCLRAfm?t0zm_Ts{k=}U&k1gV2wfm@iy*(IE>?$Q92MO5MrbjIAzm32NHndTqY%S#Cq~H24q+u= z?CpIhama`*!9{oyFi4;^C$R)@MKt|WaGI-JiOvwsZ_Uqd=g&b8G==yNE!K@p=Rp@D P00000NkvXXu0mjf8W>Mts$oYC=hQuk`z+ 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 delta 1594 zcmV-A2F3Zq6v_;cBYy!7P)t-sM{rCvJCW(LE9SE?rIKpcs4?BCD`aMBx2%;VFs;kX z&0Arb`pZh$tT`$+!|=yjeSd=V!#sh7h$u0fZ*qs>sUdxTgKu<@DKVQSE{^K4Ac2F1 z^t&X@(An>}B+HyO-lrqRktW5*$HBqDiHweiiHwYnk%Whdf`5dDk&~597Cr zxiB9J&a7WrHGd5f4hNxS4gdAj*usQwTsOVAv((JAVD)^g0000abW%=J06l-C9bzc( z4*k{q)JN_6*|ve)T-&Stw2tJ!-O9v}#=fajaX^-r000EXNklE}jlcaLh-Qn$Vix^Z z!D2O;u9u$mbTVK3`tkGiGA;Jo?HjS(?&^3w`8CUYneN~2*%tA1^<}|qeHCo)*~OFS zi$z!#ee|B#-BGP)Un;{(@wV-Qi=MiuZzL~Ya70rq_92=g(mK5(j=Sl&VO?2E;Xbzd zB%yCy#ea#ld_LNXsz{}+(mpP^(j<+?67Uj@q_L#Kg;uutJ37$$k98IR_(*G44V^5q zEHe_jhCKd3g2CfRz+t2s6MwT}?2_l17T~<5xk3sAF8OA-DeDdqjS_}k+P3u?n^d8) zi3MRaV_L|;Orj?T0Gb1rLg_4Ti9F9Qft+Z`Fn`>W*%NXQ8VTTBlE)a`V~kSDP%$Bgx8$490ub{y)5e&ap%HY& z@_$x1ZoH z4gEkl(;ww>zFg>^Q@)i9V|q#myMHCId3VlQNQhk*Lg=3o=$X)Um=aj$ypPd;{73*3 zb0e@o1c0?f_~=jTgku7w#VTQc(IQa`GWuEx;}E1FBjHzx?bsqE8Bz<<0ucac2iMrG z-AExUw|GW~6M~13A;cml%LF1X(J6sHDokgwN_=PwoLYpcgx;wT`&Gg-!GA`mqXHrn z!v9F@oT~^%w2KM}rWS8&geO7`-O}0cJ@8i)LR)NJ5PF~`*gqcMx1J0=ikHMbvH|>R zl$84SFUlEohgBlJza$``7&sK+ZVSmXU?R3JTPV?C;1(AcPa@UCityGFAqJu#_Ew08 z#gbZxpUWHBwAbi82~22>gnu^*z>;X%g>lGPTIdwy6SVx>s{|sVC&C=&Gfd8(U`|}~tj5t~A=F5MK$WtiCXVwR zxnaVJv54M>64|ud`ki1RY7IrWOHzOZGNKaolD!#;CBA=*tv{3~hx{yI&0!0;RTA9Tb6W@#kmxc~qF07*qoM6N<$f^o?Y2><{9 diff --git a/TMessagesProj/src/main/assets/emoji/0_74.png b/TMessagesProj/src/main/assets/emoji/0_74.png index 2f013754b57b8bf39fea553762b2effbbe5ab331..a19080d065300d98ae1397a1914ed2ee7cff7f49 100644 GIT binary patch delta 1580 zcmV+{2GjYM4ZRGIB!9Y4OjJcja7@T)2F7X#%5V_Jf-S~-CeC^r;D!kEjRd=SKG=X6 z#cU1Ba1F+54eF5`=Yb3Gp&|C26We4p*i)-(UTD*wYZ|H&=-sS~DX3H`4W|K~gY zwjh{W2mjVZ{+tAgPzQWN1^>JX$e}X0h9UdgU+B9mWGn&y_5`l9{ldH?up|L#WCzg3oOD)gfg|Ni9v&k^00 zQcVB=02FjmPE!Ex(ux-}R{s4Ad7izjm(sf4qN_i8|6>3E1s+L6K~#8Nwbuu8(@YQs zU|duz#|{Sd-hbuZd*J{7t#5bl&X$D<$;a?s7&9l|liigjGy3w^>3#Y4>0$ma(3NCu z_?0r$WU2e<^YU;sa?_tYzB?KX<aa zr0&O%u10`&oK1ezGMUa-glKem?3=S3D&lzcvZ zOvd)(tN^0$?WogeV-&ed&@Tui@%4JW%p18}AqieaBy=NHdLa5ysdN1=LPk+#8mZ3orVNq7e<#gIYPTOa|mR&nt zu2oiqepH`E_ce-)FbuO|yIQTb_ni0=DYgZDA-ja3Y1eOxtU@1Q2$w@3P$8$86)s2! zKR~$kXQQJ=uDM*oJ|oVn^ZC3z18~M4`h*?WCIPcFO+Qk<-5)D8@=b1pp67wk3>V;H z=zpOAgb}H?P9y~g1Bj)ruh$+TXAc0c4!{;BTkx35T|0iwJ{=jdCY;Z?-SWDC5|1oM!}V$8pICABdgOZW0Dn5fG6#1TQBd06>i5 zk=WQ`7}h$+ies2t4WKDwBl*1#Ag~e200XJWKKw}{f?DEhEVhxLnOppqJV8sA1#R!-8S!p8FXG4 zL=k|oguwe~-~Md%_e#BtIuq(TGk-)4^&<8I0K_nOC)~h#c^wwErQd*h5xYGfh3MpN zP{=5EP7udIzB8W*%Dx4Ch;*n7VF)CTD@X$W0zk~Vz>4S)Anpk-0}YOp0UVD5NDPW& zGz2U{LO`UyXc}c)B|+do0w)L(Gzb8J+JGX&Fhv>I3Nxq~!>M8bM1r`=0e`p&&_<&O znubCKFGLZ7Fp^|L01DIwO`@J&`)&YYI0*@LBgZk&97ur2su8)hr*Uw@Nt|B@DuLIq zZ^-~OqAkc^h@U3`Cguy0?0g20u+R`_rvG3#FpE6TD0vR^%ze8i40_Lq?tlzJ-dw*d z@sCqV%P`8)Cx8ntFo-`IHh=UDacS9fBdCO?&@`wQjv#Xjm<(WDknlV`ttARUrJfA~ z;BL0G_g@+1HY)@ba%e#~0MCQ`#}}&(6~Ywez$Zi@pw;=vd!p2DEl@!Qq5JtoYao5_ z4O{B87pQcyr0000vgNV> delta 1670 zcmV;126_3t43`a%B!AveOjJcja7@j58}5Vy$Y}+}dL`3(7RPN4?3fL^c|OO3E#`_C z&~py#j1b9e3h<*O#b^k~YY6|>F{Ne)<&g~Bfd($dGd zu%e-meg5~6|NXe};(`5_1pn=3|KDH#`=S5SNM}Y1Bh{=c|HL=`=sEYN6#w!{c0UOJ%n<*| zHviu-|IRJ{yej|S9R9Z>@t_g^#w`8)^_gD@eqcra(KYTXU10zK01 zqW%mQoVd})xqsH)zK#iV000G7Nkl~vCp?)t*%_@LtD)$d4d4D2rk%YlD3ic^mEWW(5U}cAr z>mdAN3sIZr=T29PDO#R$SdMr32t8~eq1B>-=?EaeM0d84`2_gZ#mpa{#!@LIkrWx3fPX%esRWe5HpsY%ol+yo6lqbwq>Vs` zrBMbQos_k#*V}cCg1VnLFp@Y_hX(T~+}#M_IPQ%x9a497y@j*g)-FTTSq!lI=}%IF3$J=Lj9j}Mu)bW-fq%+*2HAo z`Q?AkJjke%qA?&)<;zg7R;zj_zq#TiHQ+<4&!#C75RXo#(Wi=t#uz4yQu6=bO8W=HhG2}2_Ki>}--{P(l!c)9d_*O?GT znK6--t{zKm2%+ox{sLn5-nT?R1Y(d8qRJe^pw4CMh%+zcWr*sS&_@t~Bd#FC0MfRD z8Yo1|MQ;=Xy|k?W5QKP|%Yi(BI9NiAubIleig0&$sSP_z^qPsqn2;DkgxJ9uTz~yj zmN3In2z|JYiS@M-!Wz^JNv>o?1UB^X2O@HWHCTBNA$b-UjpDkF?nH1W5+a--ki0|) zMQ{Yh$rVH!8Ag)yP1khBm@YH|2qH!6rU8*8)JHX2NB2YZ;}Ov}O-G2aAznx@5NSVv zrY}IqC^nIAiAl31Bc51d>P72W#W7$sL|8;;s;*V0 zg=h?brcYcS-qaHFB|1TjUyQuI?RUHVO`U~6xe(OH^W(cDh|vkfkX9IhajtLMe^J|8 zUEKi@5Q6)_G~F;L#(@vE0K!C~Zrd+JeA(Vsjd6m6Kp*MEJzp(32DidF7=Ov@-Bwa; z_x0HTpt1r&Y+~039jnA}29OK{QjoE$PZkj2K$CEN$eAF<&qjt}?susD{>DTy7BC4p z4>!zdx1b_K~P$%>t5k!dMr8|ysE1W}&<0W^*pmG}HSnwvVJou&$ zLy$@hj}U_cL~w14jbLOP$T+bfAwV1sBO#c-dIu1L5mt022F^oczW^e*N7vU33L?l+ z=YyiJ4`dJk5q>LJLxKpR^*PVaT8{wkLWI}L_hJb$gF+4u5g@f75r1OO|NWJ5vams* z5F;kOZn*aa+ diff --git a/TMessagesProj/src/main/assets/emoji/0_740.png b/TMessagesProj/src/main/assets/emoji/0_740.png index 8aa1ac624f1cf0249121f7bcf17f760f4cde3a6c..a8d0c5003580b2fb3778deb6479c512bc8feca89 100644 GIT binary patch delta 2668 zcmV-y3X}Dp4D=L`BYy%nP)t-sM{rDKbHHnBa3LcsCM7E^GdxjJR8vk;QeB-XG*d-R zhHr!5U4*ZWY*=V|(mPFO5E2v{9Uo(9lMoXYt9e>fue@-o1TwQsi{!CYsk6t}lI45n1=3{{IYe6U8$+VwuN_u;J z9UdQ1QdGp1ZV?g^1m|MD^Vhr@wvZOr_5b1G>(91v_3f!DzcpO|002gGQchC<@cky@1FFZVwCZrOzMPwrC4`m$|m`sVlDuz$?4-@L8Yp}%Lyy{^{Pl#|28Vuz|4 zbYTDh2c}6xK~#8NjhBUY8`%|yZCS3s2r(qa#ED~vo9%X+g_O2~LS|+LGcz-@!;Fj2 z_K)j*GqTs|kz{=y%aYHz-~8^o_xN~nQgh|nA3o)ez_lAW*^_sFdHUa{*!u2AVEI;l z)_(@>Kl*++VHyN1TVwb0vNQ=f56oW3|iclT8HDdHT6jpJ~JLm^KoU3H2-(;_<#?;@uqYv15QJ6=Vn@b~wah6ap!b zVGQ_GF)%PdTuC3I!T}0MVOKMaFe&1U0UDWQ6a-R~rd8ZCg zc9+YA92IE?Tk7acIwbZ9JMn5L81Vp+;LrgC16y_V$jFEb9O*jYR)8YuNQhqzMIyoA z5Ci;tC6=hy*H=nPRz^TkmUbSUNd-F9g98cSVjvjA4r0AzX6EV43dBfv82O!`00|-? zk=X6(b#_13)e|n5g+shP^X}c#5`TzMk$OV~S3toSI>m$wmdnDKdd4zk@y@F45M=$` z>vuDtIG>lYjiRz)#sNVj>UPVs&5ez>Cu}S}v&`BD93`(`KShcwMJaMzm}+4ZV6eA; z_z-|m#5w>9y}X5wfxxzb7XViyN93EL|Ooi;ICsPk?L+&M=BUihox-b50dz+uz(C-`>|iJ)-}`{AOf)Gm7CIq{lUYQlwJk zUoS-=B0HoRmo067*c=_7kJ`GJer(a;{Pt*1G>WO{ouS9TjeKtEzugrro*mCyB^F)k z866!Rk1g34L;vp4D9|%MjbZx0Uhtrz3~r z(;AElMCSeqg0vJhHF;=AF}=UHxAW@~QULwCKWy&p{rYHnNrssNp1I1L4AeJ~O|%)q z`*-&r{t{h^_OnCn+Fjaz_A(Y zGfm3x@iHn3p%bSPLkfgakI8T)B|BEAC`bu?WTd{Cq^Xk_6e)MoI$8z-whz7T^K%d) zGlENUJsU%&vElUG+#LCfCaF-Fon%qY*)+?YW)uVe{`vFg-+%uHVBVmUfIco2W}zsm zqA7@h3jccoxG)HzmsjRw0q=9U-i#?9A|A1@?=dAs>!6P;I7iZYr7{+ak%6A^ak$1K zBpHi!z)8p}1z9Nsm2xMg!VnvtU{5d-Q{fntQIA5+rabDcE-v z2*Kc#Hy;=Ca(@aNF9P2drfa22?gWQQrBs^Hr2@>}dFRe&f4kTSDKa>q z^aLf!P{~WCY}@(`{{?z9mwQ$QUj5bb+An6Ffdan3^TB_!w!E>Bmm|2ld>7q6^C<|5 zYVX#(dGqFhkVDgQ77l-P&}hv4y8O$&l`h1`jF*eAW;n%KNC5SGx0~OqH9i?!o5wK>!{2Mc@X{oeO0|8r!%|a0 zdD_z~uYm)Aa%jQI7d?3rDmcUtW1*J-Qal(tG=E7=(t^fx%k;&YNxvV;-BzvE4GIxo z@$<){qc+8Ykx`fyy88xACUE^ZjUsR9XVma~VDhj`FwtEZf-&DFC{Oie}ROAhl+D|i+zBDDKVQQESM%Pj>MjX zDJCY_rGm_vdDN$f#mC2rjE;nt0M+5`~`rEtI zm~!B$gLYm{y^?C6hjKnQH_^72f^uT|;K3*e1OMj6{QUg2nt@Ft5OYKgz^|UCd<>&{ zRmQ@<)z8YDoqwMY4qFNU001F$QchC<-8}vx(pK;f{_}jKSJ_j{`nvJCbN!RF*^Y|$ z*1W8#r9R!4000EENklQ2!Ga_94SM`M6}hY;A}gUpUDkdeE?j_+M#ZFqUlQ50znKcW-|tnFh=razx97v2W29 zl_r{HDldXGpnn74awqE%ZTas{42vhaVI3A~_?g#mC`mY*K?}M<421P!FU^EtD zFsE^(r#F*Z1N<%{a5@@Lq*;u7#aO{6pfKhPA?NyF1%P=6<@nkiTshHmlrGFuH{9$fgHKwaOGiWVPU8AkHBhO_~BHNOD zdK(Tqg?nM&8$s~oS5H2ElttkbTDqrdKQbR+z|_8e*dq2{t(8>}XK>L%4mqR*d?{X{ zC;v%`q9o#)g(Nm3g5;+`prR;NzIb4@bqYCU0VlV}!8xQBsC-#PmfxS@|3>LxM}KV? z2m^41s2Xutgu=2cr`n#xb|Bd^kIbLdZx7iJiS_h(}L)^z~JSljn8;ys=-KN4f?dut3p=bQ_{?f*rf zp~}Dl5e7OkUJ)G;mIqa3EGABU_eXAF6soeAfsqelwgB|SHwr>9*z|i>Jp;} zbRa@(s|24a6NoU=4_<|WSk(weE!eD%PDHLkV1l)T B&D8(^ diff --git a/TMessagesProj/src/main/assets/emoji/0_741.png b/TMessagesProj/src/main/assets/emoji/0_741.png index e99bccd0609ee67aae18b5489d09fa6e181514dc..85fa5aef4311789d38bf12be36442bd5f842c61e 100644 GIT binary patch delta 2519 zcmV;|2`Ki%3*ZxwBYy$xP)t-sM{rCdAtGo>IXq8lXF@GDDk^VslSw%|D<>^ZPf}iZ z;2RttWlcgC5)o&4(L_y$T3vh?85<%oKs-ZGX+tkoHzyDi7EV!VWpl!2YL8|?Efp3Q zXa9wsn?f`VXz{Sp!q z?(XnQZjqyibY4b2a#&5Jr>`(RT;I>b*2A%znxKYQH*0~)Z;jlecTadn1`G@hSzd{} zzRiVbTzh+bW@2>3#?!x}UeD0r_W1sequWLr1=scem}>#7xyh!v*}$DBu7w66m`T_G z002F7Qh!cU0IppA@Fn{Q5w87*Jv#6HaqIp^tbf;)@JiBDAn+U8aLD~PtMK~H{i;&G zl&$;g>4E*=@O0zM$i3&TzG(Bc!TE^&8vx4OH#;9Pz3kG_2-32@(wed%OPW`C{y&2OKxXC-Z^&Y z{jG(s`1Rw*w{Ji0k99U}kc!rS`^?tDuNCscZA}^^?ctAK-~J2ZB58AqOXIWeORWAc zvwh9AG3?bNw4c#y^<}(c&BW+@f>|&O^ZArtjUhR0`N2R`o%NT&5A2i8?@!rFv3kYPGL3-#+|Kr%ZX_Ld!WTWMG7bfB=56(GpN z3lJ33upnSqTJjCn4$-Rv1xlfxMvZ()A%8SdO0fipYAObGWrYPf;_)z4!C-mOIWlN1 zYXB&EYd$L?-R5TptiMtj3sYDL6F*7rfnHdb5 z!DbLTrA41g9f-vT*Fe!;b3ZmWOEHvSf@;hnu!dpCsq>}8;`Da<0Af6;HJM-#Vt+tC zJ}5`4FdYt~6%octr%a`{x3|R*qqq8$O9nRu2N=-4!gS6e_Rt%e3JU~DZBLogpy+C= z+D1qFYh*w#Odp2YJ)Q$fZ}cAQs@A6yPfev$pcw3^lA~|63lxGw8y?@aM!!h}roNd#*C92pG^I zoIBiB4Nbvtbf6#S;W;8 z`m(~VA@E#w=UrqkYpWP?J3G6Poh**CTm(Wuim@t+PK5|5fEH0NkQ>KyM_JXUqr;qF01uoB*Ki_0a(qucg=Byx zpZRf>3U{pJ3^s?MjKh)3t=Ql?VdZH0QcFF$8IleVDwPf4a2RYhgMY&Y3XlksZe&UN zSzBGjC5GdzMnT~KY&g`bRA2zWfV)E^^NXae;^qL!v2MJQ!f(ZGHeNZWdcSVT7fRyEEkK#>?h}hO;8YS4G9?< z(!;Yt466n>;W>^zfqxSgcR+{$(|WV9LDIp6Pz()oqOn@ft-`@-P8c_YVEOLG24OZ> zKkm09NDe`ga2jJ&#z2VcXzu44is9x-jib8JM()6s+Kzx?h2yc?w}+ehLErIwm*jY!r(q~|Kin;cR_y1mbhb#_ zB#jc>>{mQ}o{p0hb|>!NRrKGKv`8KtKWO6q{ZAiU2HvF893Uv-p3K?u@^?SJP^=#} zd{iaYpbs4lM4|j%IS1bW>3-s$0;bL ziW!$jo-vsc^Q-q0(M3>fD5`JAZMnxuxy(@Sq<`RWExV|seDv-9DGWr>WiF~S@o+d< z00neXb-+91a!9`{)Ke~(Yk3(tlE+h-Oc5ayqyGh*g#uDstvVbEc@im5Jq0Ro0910q z2?m5&iCMI%VxgekfW@e~CwVi69+DIs>E=AIV zQc!>cDatWiPP1!Hz_q6IVX2~8txm`irbJ)0skoiIckjlH8&|L1_#5}&3gTW@msTsj hg}8d_mh8)9{1*!gP!9An2&e!6002ovPDHLkV1mLfvUvai delta 1458 zcmV;j1x@xOh#lj!VLWS)zJ8!>C-8YBcHP;J1)ve2$eKgotOaK4?AaqhrQvfp3{wPoq@cjE_-PhH*&HR6wOOUst zWc`J-+wq&-sg!vZu>b%BQ%OWYRCr$0(#dY(KokYgxYhOoBrG;WAw%zL^gNq+o-%a* z|F`seMFq2n%A|LF4H6}Ihg)Ue{ReR@%eHOHa{dvp?0^2C=XSeYw>Rk9*0%x2?sey{ zO^PSC|2@TaoB2i=+>ST{1d7+7l z1vN}I`+q34A!Qu5)v)Jf?FC5!h`d&?h&H^I)9BAVSxY}cL@8(HQUr~bo%AL#5LM`d zqLC7BEGW=Io&s<^%Op76QUbv_uR>%nfsR@vr<3&V&BO;10s{;Ejjsk=bMnGaz2dZT!B!AjkNC_oioGcauvmp92!&ZT8CsYY0 zve9V7F93yQ#?i=H&%*U25~H;W1z-UU7KvJ}I2DzV!1QWa2`X0W)d<4WJRsO9S*5W8aMJFWPn7vdjCD$ZF8cD@p}6{J-+2aa6jUYj*$qWN{Bo?PN&mj zl%5Ha?{~0XZ&PRyCH(QHf#~oc358guYnVC6ncm29eB4cU$$rKJPZDzrs|r^@Z;KvY5tFfM?hR0)dUp&!DdW!?!8 zO%0Bm;H)8h-|v{_A=U#B3Lp^fhgB6;pIgBe!;XXb60m=qGakP+8LM2c^{;+?fqyuE z8>ySz24Nryz?DELL_tE3Na@ZqHiVoY`<|fE-2X1MhcW&MZh2(Or}rij7p?WI=f9%e z!!dg2pRF$n5y=L?82uJw0DuS)m6~jByM%HCIKgCyaRFlqa)dfWpj&zfy6@8qUui3j)+jm$zP9; zDMYelY=zj2!VDKrq)P@S9xKc%4oZlB7~YrM8%K0?MpXUh;q-y{1!ol8N(s|wyZ`_I M07*qoM6N<$g0Ty_Pyhe` diff --git a/TMessagesProj/src/main/assets/emoji/0_742.png b/TMessagesProj/src/main/assets/emoji/0_742.png index 3d83ff10ac92e76ee852e31ccc992d061128e4f1..f5f9bdf8cf5304a58ed0ff4a8af0aa8229958ac2 100644 GIT binary patch delta 2325 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 N002ovPDHLkV1j@=hED(h diff --git a/TMessagesProj/src/main/assets/emoji/0_743.png b/TMessagesProj/src/main/assets/emoji/0_743.png index a7877b2d1c58877b344a3c34ea21ff7fdf6b4aa7..99d2400738de2e9a295b603c485e96580f77c3ff 100644 GIT binary patch delta 2278 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 delta 1318 zcmV+>1=;$Q47m!BB!9qAOjJcja7;5RD9+E(B`%{gEGsxLFJxwFR8UwqGebNzHGYAE zJ2f>hDJCj5!+d{&g@=wRGLs}Nmnbllb9ak|iHs~G9xEUle1L;XQJBTY$AgB5jE|9z zk&}Odgp!n&qot=VIm#z8w_#_SOH{HN5f3*gB1SSRAR8GfCVwVkPem{u7EL)ZRX{dB zIXSnqvs*?wH!?Bf;^B2NlA)~ zj)#eh%1ikG0000QbW%=J0C&>&RiE${FyGb5w(YN2OUjo0der8M>#3|bicSCk1P)0= zK~#8N)YaK;oqs?K2H;YG0D;u2MC!fm+1R(UCF%RWRc(e7k|qVxyZ(caMq)l$mVs~o zLE6guY$jyQzx z!qOpvXn!VZPT{E~MD`e=XQBQOp%4xc$buu(=+@H>V&mALV^xrII7r~N6g}@169{|b znQLX4fI%VWm5`=t7*Gh z`l++#=G3 zlP8LEZ+U;|+rl9XxY>*V)nJLLr`qz7sWqPHPu7CHoSqC36Ps^)h*pSmTU{>KYulQ_ z6HgQGr?x7Hh5o5W&xP4R`eQ;C2?pnufR z*dWLdNW@eku1e@j;h$NAtrkjXjigwzLuaC(gyZZA#Kk2-4$3Dq^Y}B2b2Rjt@QOG& zS%P9%JN$-pC_7X*yhnr*EDU6lAg2H(KHejw1#eTry&~$H(|gJ}Xk_AtgrG=p&hpF diff --git a/TMessagesProj/src/main/assets/emoji/0_745.png b/TMessagesProj/src/main/assets/emoji/0_745.png index 59cfcdd7864656f09a50b7e0ac479068bf003cf0..c83aebea242790f4ae0130c3183e0a7b589d117c 100644 GIT binary patch delta 1439 zcmV;Q1z`Hh53mc6BYyzZP)t-sM{rCxGczSFqc$@$CNj5QU}iu&JY;5SEjh|VLR&O2 zFgZ0ffP;xID=U3}f?HvlMnps?F`0jYg(@O3!*uEWGI#=)n~{UZFr*P&2yG{~oc z3dTH+?thkHO|Og?$vNkFD;UMybLLCu?r}&%5U3IiB4y1al2?&3x>trxq|_BNnkPvd z$EdUwp;7UHNF-!rEfYIw2m+-M_Ip$`Li{TPv)V2WQwxzVLGT3kt35_nk{iTKaw4R? zI84)rgqrixkHm{oYDNT5sg(=iEcStfB#humlz)9+`a^m_VlJu@he9M0_d40G2q6^e zmcJw_bzP;>bVl@OI35q91hd%5hEPg@wmFaYL*JiM7jse6(3dYbS^=nFHP+IRQU?0V zPU3P5MKSI_jeZp4Smk;s3=z3o-=3xxKwuH#_54!TeUQ2rq<`)EWBFU4Q3IolEDU33 zh<}PF)$5@?)yL}jJQ412>cyYq@q7|IF98iAH@AfKio!$`&FP4FYfj2FIcF8#*KHQG zyk**u_U&mhLnQIgJ=eJ7y=x{y9kO1NJbUJb07@1J&=Eah zox+m^3?ny>#HNO*@!Lk@c{rdjr^}jQK!0I>A%HjwgsCw{LZwaDHSSgPt}2Mk#nV#Os1q#962Im078g$72}?0 zJ1~MFtf5jsaXn;2tYf*t5$Fm1=LtJQ;Cq599O4wMIRaziQX;?-47o8ZVT~lh6QWFv zM37;B-wSjOUvd7}Zv_7$A%hyYF@NyC1TC)+$HWEbNpgcbfr#~p&_Yab|IbPWA*%Q+ z5N8n^Ug3;CHcMhw(UyocBXk4GWqB;pk#WT_A%GoLxn8 tGrF*Yd{p3fZ45EA8BzCNe;8gLh+qBqf}o>(!Rr73002ovPDHLkV1kq+kxu{s delta 1981 zcmV;u2SWI;3(60WBYy!hP)t-sM{rE|!6`;cSMRnX{l+cxxF9=BYU#2q^}8b^Dn9nY zILFJ*`ORAV#V_FI>fWIiJwZ)QOHeU3MEJro@Uch|-o4^SL2DK};biIv5@^NJ~|%a0rlK7mSOHL4QO|z=I6ssT%XUDTz%4 z|I04yup9BVACXlB_q-s&h7ik+5~*wo-JlnKL<6&R44PdBx_%F#WC;GwKGc^K`@$sr z=BEG2DfYlJ{_@5#J5lz;J}5CqGC^Ma+kOAWB>(r+BPu`p(`a!!0zX1e|I|*wt$^gR zHK~0r#hE+p$bWQNMl7q4UHjjWTr&s!>$f~33FGMPH%MmR#a6fsOzG1|3O6K~#8N?SIu*Tii$%2HssoU=OT9LUjO{{LUt@2F^&3kk#he&|NsrB~;is)zp9bMpV>b8CD1e1mmu7aMDha(UvbUbWLWj$=5ayvSHu#q2tc=o_Wm zTPVkK2RViDjCmAdOzzebMKdf_tGAs_qd^WaAdVaRzulKygWgruU0XD*5+SICJ77R` zc77w|_i0(bAs8rf~s*C~_NKzo^zF{$D z84fiQR5`+<429BKwy?BV0ue}-=~zrrWSJ1r8TNw`FC#I8r^;Bvs-hGqjvq2=Ur=O5 zh<{fFf^b3+ma{iy6DuUC^wlez=WLXnD(Fr}>8V<)*Y;Unii0rwhtNQwo$fr6fD2y>v zbS#SrLD0tqqR0_khTrX~x+N>JB4iwm{C^?~b-#;IVig+>36UfqP?`z@4CKUhJVTE5 zvbNOH-EP;zej4M^*U?xYfg@~;;dr58inggcx|Xr6IlRU0+6Ghf*L&Pp5&I&JU@= zJevqJi!cn`Gu5t-GDx6HEB5=vXilIH-xgH}&YM)i3PVG8eA_mt33DhuVOeCj_Ph*4LuoAHLNQXTqzDK`2EoYiOp#ARN)pLR^KlV4SSExponSI! zR!C*2p%PK+LL^&^F@XRoB6LY`AY>3S!Yq`b+CI~;rL22$a+X{sYCs#w;U>YdG6)3( zLm9qkJBeYOoFzF4NnnmhyMN)4z?M^qWo2H5n;2115_ACHON;bI7#2-b6>VD-U5ww*0pgDDXUJrY0)HZ{lf`90Lr@3G zpu!&ow_HGL+VbL7)(^>2?)BQyUSaFQhc92gPN!)7KE5kX?XO?{^WnqRR$*@~m;JMx zpIiC$jc@gy@6F?wYNh^p`)xjtCC|zF#=)z4rQX9NFbYH0bXf^cm74+O=4R#UN1f7JSopmCbT4n; zEhNGPC$1hs1f>GxVEt(UKqZy9fQ$Ajz23sdCyaOWe63QeRW6XbmCJdEKq~E8tp?>| z=0MgL+HG1?YhM%bofAC2h-hCY-?n=jS;Swp>+8g*)B#-F-G7{4UY?&{(%;oD`s8~( z@vmzi^BI%))aFFxI|Ah9d>&39^;#Rm^&c72*v5Cf3L@~%9|Z7Ry@x{yp80~q{}KNM1D8EqpAIG{ P00000NkvXXu0mjf*j&UK diff --git a/TMessagesProj/src/main/assets/emoji/0_746.png b/TMessagesProj/src/main/assets/emoji/0_746.png index daa925917c2f8ce30c10a22d1815c48e033797b7..a8879e1d0bf9f63b8a95c050958a6cdb403eb047 100644 GIT binary patch delta 1599 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 Q-v9sr07*qoM6N<$f|(Phi~s-t delta 2094 zcmV+}2+{Y)3%U@HBYy!_P)t-sM{rEw(vRKEhThPP>*284$%Y{)Jle{S93wf(#lhgx zk>%N-aw%Y?$HUwMI$M@m|^n^8qcR6<5m)xvqqv}i#_RM*9P z)xvu_Ollh=HQ2>_<=UXasa)XZ>gL<8M@d$jcR93`OQL{2l7DP9v~o$Qh(pJUV1!L8 z!hu-2dr;DybdFdwqGUbQ!FSrPh`*#*BPu|zkVP>+ThF?0Hb!LOznI~=lf|rH^zYKw zsDa?pgD5aY*~os&kY~A^QRm#G?dH4Bmu@gQPpoP|nOim9w2sxHddjnB;nS3dT`8${ zMb_5UjcQGCK7SMF-Iv|ZxZ>yR_Ve2p9yIy-_^^OnE+y8JdgCpEct(ei@vabi6rcsTMhm`u;~9!;3~KG`TX-y z7Wg>BKKwZx?eYCS8!a3iO{$b}91ww}U*5}H0DnTQCkcIl?;at&31J+kR;yOSzuM&z z&IPKB#2Shqb&m>#g2UK#0@doPUyS0b2C9e^=Ua-x#?b=^WhP)qdJ})} zWq%Lj2qlE^c?+v+7A3Orfu_oc*2G4#g~?9{h?i>kN>&Mi#SKJNF4uLvE^8*H=^jl` z#Sw63&GS-%e#=4$rXn>}x!%bm9U#q?ApwCx7(x_0Cs|xeTFm6A!Z$_JFh+-wNF<-v z31YT{XbH;Xhyh_0{GM}I-DIg$VOu7ie}8y5y3MrPk$eY;YAEJFsw7La1twYbApFT} zx684HDXN`z<~Y;NWPqRwkg}|broeL1ZZes)N*Xi`P1$_BzCQVK{}^$M%d@b#OmCxqdi1nchJl z$=`iFx&CrC8jeI$5m>&`eZT0sig1(#VVLr0IQ?>Vb~c_4?Hb2-=a2aQOaJ`ZY$^iJ z@=?oupC34Z1tQ9Kr^6HSjGF_yMSo^`a1C=DKNud01`e^D6?Sd0A=yMZkEe{sZ1&(_ zN{#f*!9SyMKR!J;E{iQf@JYYxg}mljM8K6srsvbU>B0HUv6I}vdHU{V?>J8hoQt{= zi*KRxAXGgc$=qCB-CzsPxxu&Xh)tj?_rdi}-}1a9@vNzp^O1I>ok>G@PJf#Gc0@XI z69SKqt)MF*#kn{P5t9J0p9lt&V?=b-#2o0#Z@3d2SE+Ck+f?iMcAFAy9be`1)IbZ& zVY0l0pToa)Cn_WyYLrpKCS*;PwR*;Gff7v?Rnb-QB%(;1AE-Jeq3w0iG&R~HLrV;Z z03+^B{3{yGX0y>soX4+*Q-32)n@D;t$ z0Rf^F#GU9SNnmi&K-MFXwr(hjVzv~+7(^h{)d2vzY1Ew{faMrkxdY=+8IMm+#$)9c zg05;DfGz^XgRl^4U>#an$3F71CW>k~Pddn2oC-;r_pZcy>&d`6cz=z&3`8RNj{SFC zmZ*TDG#&(bnL+GPSnO2qPi5CH^2iRb)C(KH%B)?YA|@pPnEq{g>}Q{;kv+C(E(EH# zkyt48DV6#J!U-YpP%K3MH+K2XvqW(}M2!Rl{Q0_T=XCe<;yZcZQ=&oq{o;DiV-xeC z{e40-KGA@94u6Ogc_>wkfe6ieY~$~JhbYp+g!sqF?(n;~;&kDgtrkI$pEUo*brm5HAwt9wHu3$!sj++d z^=AU7LMtAtz@1W};Sj^!U5EJLY#4Lm2x|Q8O3XiJ^CvHwKNtS}lt1l9HlI#}{I_YR{#J2 diff --git a/TMessagesProj/src/main/assets/emoji/0_748.png b/TMessagesProj/src/main/assets/emoji/0_748.png index 5176e0c493c1309dd6d153e1083d86c5feaeb57c..42701733e667644625c408fd9db6a05ecacf473a 100644 GIT binary patch delta 1365 zcmV-b1*-bW4(AGxBYyz8P)t-sM{rC}JvAgQq*z~}Co{NPSX@IpS!8BvFFMIZKTuUe zJ5xb9SVcU5gNS~Bf=DUsgOWDE$5W zi&ikCa!lpo+mu{3qNJt5rjWXrX`O|0&%BVdva*eOZG&lFl$Mu%fP;dChlYrYaBXLs zdbLyl000$qQchCNklv%^(@AcF&`vTSl{3Jibsd<;4WLNL*Ahk!v`9S~XYL|AX#Ijqx?AqkPQ zQzBWleKLxNbEw`3VP^x8{OW-6o|HgoM_8?a%my(8xjeoVZ)#jAq4jJ4`8$>O@H(bD z;3!cb8h?h8)h*IA4S!T4sN|&tgdA~5Q{5m95a~U5+O#yc2@;|xnh?c-$eS9w)#5TM zPA#NRx&Y91-3^je5}6FSIEg1gKoFYx+k6~nMAKd?L{2ppC-E_<Ea_BXCwP{I@x;f3`Wx|{M+yq zqv*o^NcFy9QEI{|(fg^|Gkbg&M8IgOyToei2wa974rE2c{!-(!HLz{p{+R0A;#?rF}?em0ao%7xsV*n9t5<~zn6z`o|7T2Ui-G6!( z0GK!+$bnU$oDxMu90h3sLM&H=BSH*1lC}VD!Nwhd#~NYRO6ZWY>ue%|kEsx{?vNpi z5*j8v37c_I;+`;j0_FTiEp!Px`bPMG&>B)kOYDgHgm^k4$N&S#1``IyiAC55cSlGI z3D{vC2TKOvJH+Cg5NeD+lqskpY=1-A;*#)&k*!1!Mh}qexF=Qwv;~sDgc$9KP3MKmn5yk1n~-KCiTeAbgC`!(}=m^8Pp@iwH1~gavJp zXJt}C2r?v6KRiYv0uy;(L^qKM5gSH~Gom`wcm?9Ygcxb`DmLP^6AIcv#7^Im3xfqQ zsw&UBBKk#{&>Ghzv_-U}%vK`3&=`;s(jr>&5`qmq$ji<LnLH8AAwahc}pr@HybuPM`v@0 z7#=f@U`9EAf9ei zmu5|LOg3RZD_1uqgjz$vk7vi0Y=BWP8X-1vMkcwMhAA>gHAQ1FKU#T9DZWa5($_P0000TbW%=J0Oye2{V8Ze=oP87{h#ilNv9fBBc)t9cCDsKcCIO zygHo^8>M__##BQJnV+A75zb%rD1VuOkPKB0Yb@~d${b1R%<}%156mMs$K)6{4Al%> zmlWU51AhWTyX)_l|GW&kalutXm7MSzNR6?89AZEOf85)Bx-V#Q$ud-~hu1*BkOL;4 z2l1z+lmgroumK2RxYtPH5QFzv?tS8jiL^QQyq!UaP!h*=&r9!?IA7Ej3$}2$7e%pU z7?RV3@fs}*L$~tob}X6@SX1UPwnGD=nuFR4qJLd$l=o_s_nJg3bna=`&VYqLB**

    i_Jhm^i>(l8Dsab~SakJfQ zHh)8^u~*L8kG7-hvTAu6Q|jYJeOj+SBN(k4S*j%C4jn7W*pu>+Zkk**te7b_3;b!L zJ{~8?$ga7X78{1jWlz?_T-KJFvZNY@7259O~u8i*Dob8>cP{~lcznbVh;v4O@BRO7)70{s)`cY<0O8%zBRYAIt)a)y7R8A zTYut39u5J?)V~$dr|FQOdbPN^HEwS~Or`)DjmCWQgx`(D=ERFF5Rx-UpJzo@DG{6B zOyt{Jb+O%C)yb%@HyxPH@6Dtp2-O@EQ;9RILjnNG$hblOUvDQ@N}vfsbt-8@;XVFu5$tFd_y* zJde)=6q0BnAZ*uzz=52l6S8cYGJjV+*T!EI4W_m-ohr&$5VQ`>Lsc1Nzh)37B1@7M zPz^z_kg?Dg1eK`8B*-w*3CA=Y$AN)?CdAmr!4XmmQNq_e0F(^k0)VbNCVx|-Zr7NC zxj+ylAfPLZbOI+qTNlP|8gy7FzHL(_2s8-+I3{wDO0;*;9ht`rpN*;SS$`HzF#HQg z5NtOFfTC!dO$-K!fu+E}c_(5q5*P#kyRP3-iGc_R-6X@tJd_%aN|z}@h&TyJ*L33B zi$NnL15Fg$rk@H%nFs@s3HM0r4NrpqGsO7oTL;xP0 zcMb_n5wytoLZ!eEHN;7b^M5|1Z)d|o2_YoeOFw>(_Ri0D2x<^vJqHF6BrFz-=J{SF z>x-mNDiw>lT;=HK?CioDT3#GQk%qJ1v#e$O_3Z5Es8Y!li>2~gAPf6`*z0`V_f)jaQrc(ba1#_^*~(y@_&6>#LqvS(3REU zDUc5UtL3ss#C^4TcXxNS#*gacfr#E}wK_fi!wkM3t|0V#c!8MwGf6@Oy_T!h;X&a& z;eY@lDECzeuY^c<3FP!0;{cC$m)&l+pAawE5&a?F!#$^&11TL2hr=#1Z1pbR639sp zmxe9z?r?dWS)$u&!GE9(~iH5F#L6QcVb~Ll6h)#80e3v>2i^ z&{}+qQe>h0000k}>{eS)ZHC)b#IsHj%XR<&1U*SaK~#8Nm|gXWjz&$A6OThO+(Fx1%JDcRq2NY+e_VU3pS+953T2 zr8<>|GpGOUe^Yr zki-P%`$nopX=)glClt@TR7X;dqauQtsw_`nf-_<>yMN8|HV$%>AP{X#<&@w^81eRb z8*~r^!i~u)C=~C2DAOlGba2No&IS+9fMhdsLO>jzv=Wy9s!G>QGaFFg%n-Q8Wki)r z27(dN=nM$r5C>(ZdbpL;A2SSuM>J}H62hUykJhm_Zh{=|3w+36yaJI0fph-oawLWm zk+B8@;(rh{10)!TS)ax>29eP)Nw5?ku8=B&5{UhFb(k3^f-@(y6pu7ONXcd+SskX) zAlxje729USetiH98%XXH8%(y+HcnOp%Hgjv|X3u$peB= zElg8ZJBc`B%nR1yAz?;ZYKIzv!kAv$Nx~rzA%CnWRbKKo_km%{TqzJh7{XV6uc;=1 z7RsjE&9+n3&4&5?F$wjqLHIIOhVcf02+>Sud$i5=#=SNvfZq?n1tl_bm)SV;apoQt6!E}bV7jG`C{Wd#I^j-L>1t3KX8FL~HV zE`O65Oke756p^-4aD0DfsZ%3`F&!(+)~Rxxa^m&g+>@-s3H{5c7Z_X zn*Yt>zl=YP(ZP?8tz}}Jj#^+LVwDhys9GEkl8s1;03}QuwE!Y450Vij>Osgjek3_XkjS5VVG42rOL@js{MW~146568MCB$&D zQ3v6%p(7#ZCt?*sM!~o&k5^*Mr{5GhdCDtrd zlU#_n7d=s+jW%E+8@EmgV=`gpzrW602t&j_DiE0HS>2fQ00000NkvXXu0mjf{sLS4 delta 1503 zcmV<51t9v^3i%6=EPqu;LQ6nELq}CpM?_3OKOrbQH76oWKs!uBLQOm~JWFOpHZVp% zK$V-MT1P&}%g#0^BjD!ha(s^{BPtyh6DJ!MEg>8_AQMA1E<7$MOFJ`DLOLWXK}aVU zRxloYN-S_dC1f}tGd)x^L}6}NPhLwxeq~&UQ!tuhIvOE1JAX`T!IP2FbTy@aLzo9 z7{(L?CeJ&7O2`>B~fP#E75W=DRV3ztA2%#ziig5@6X5T0JI0V8MGFD1)Zj6e7 z1M2Qp+^#8^2^Ggc1ZM$|uL=5h*AeO+1X9Kc62p*Q_{H#j?_L@0VGx);RFdQfA%dYY z^idIhV1L~iW?+gCC?e0&G|e<3eN3n{d@7^cZr*6%fe5A0!W{X6AY~a&^Dw=D1g@xl znQS(j3gJvIHPD1-HTU6Ta}bnNNuJ2;WATXy`b*{qFz$9@d(8K7IF9plv%viYQX-}n z%+{v_O*`o^DFqh_LYimU=40{k@u_53aSViWw14OacEd`$QsNn^RFWn7*^quvw2{%X z%u{3tDTLQ=n5IVpM-gha-%sP~WUdVqlU=WuWV#QG!6fU|55w`rj)O?z$$PS&?(*|& zVT^QeO7?8`He%?7b1wa^TR%<4Ifyv-M`yL$fjF5m7PIvg-;2$0pgW5lWitmM zN!ZDLEx`Z?d?eX?gDeQBjKzkM=CR;9y?;8Q!vuv3bW+`4d{xpU=JyGSppzt>Zw#@( zpHTiMfrmLpK|hDT))P_(Wn>`CI`bsYlFaO->_bR_yfhJvF)1+6s*E&NDw*FFL8Uem z6dy)a26d9>DQSzc2mu0VAn4@?pG zLYgQD352&fKb z42|F`lHLdbrIv656Jv19ln{h~ED_uY0Gf$z5E{gk!9@%NAwa)ovQh|}h;}ce+!(Zv zB&T<0MFbUr`z9c2(&=@(C87yI1b=-{BnT?P+#gy^ZzQhU={UA+^?SY7m&lLfgks)7 zw*E`6*X!&5)Vu9({TA>%-l7W=Qi^f^2fq)vj`ds=AOK`pmS=<%Me%HX6Y1E`MQe;3 zt67?vq?7A)40PP;JCBi$)oS4|Qv4o`PJ7DfG0RhO#T-UV>Ab`dFXt~_>n-!r@!;8^K10~&kUYTsuOkv`~|aKGl6PE2S)$^002ovPDHLk FV1l2nvf2Ou diff --git a/TMessagesProj/src/main/assets/emoji/0_75.png b/TMessagesProj/src/main/assets/emoji/0_75.png index 4d1935d85370b91043840650b693dd123acf0eed..cbdc4bff7b0a5c0635f2aab66f945e764a59269d 100644 GIT binary patch delta 1426 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 U^3862BLDyZ07*qoM6N<$f>OcO0RR91 diff --git a/TMessagesProj/src/main/assets/emoji/0_750.png b/TMessagesProj/src/main/assets/emoji/0_750.png index d59fda9603a60ebaf94b8d6d32181387c8c3fd71..f47c634d187f60d3691fc923bb794a1f2f93f266 100644 GIT binary patch delta 1619 zcmV-Z2CVtq3*!usBYy!SP)t-sM{rEoo)jf6qsX+2DKV1htQfnMO=V|nlUN61WN3hc zh~us-;HDTVHp20_C4GN_^t>#`$;u`!m)4vZeSm^`e1r0}9PhOtj*yb~#z-qOqxsEV z@3$q}pBc}S6yK>I$;-{agbpV!jqtP|QdW_}#m0}4lO`>W%74wy%*nrtj*yd;mx+vy zkdl;xhKPoUiinDgj*yaogN1#6gDpAACNj05rmum6f1IJJnVX(XRP8tk$j#D^06#3k^!CilK1+n*T!$|}y17PEE^`{SsfWD5J-d;RLY`_f(d+m83p zaDhz)&Y(c@y?;0L$y)TpN&fB0|MSuR%`lpJMcm4kw4HDc3I_ksKQkf?U@`(@Pb&WY z{d{+oxc~qFDs)m#Qvf~r{6kn3=l$n%{U_y<$mFQ9X{FOD)BCD*@yz=_ zMd}>M6U|IGZRaju-*jEn$6rO!{ptU}^u&J^Tuo++#l2&(m`z3>_l)NES&}c8%hhVR z%#-qdaX0#y;jT+uv&VZ@N!HJm}4y=x`YyK8{zhhF!P zB2SWT_J0n?bY5k#X_NdH$WT&_VZ}Vllb)$6@#M)RWtLU#;65gui_2_WW#!LQRn-;6 z_0_-_pG!*HnUuv{<;W^eS9K@)?l2n&(U;WJsk%0C?|Xc6f5||MSwV)Xhv+q8s-*_s z-4ddGgFl7mC@68?LYltT)`0I5C-6-ozXXr!x_@v60oK^Mj!1&y4gVTbEkB2DW7PJ9 zKx77$moW8aQOZR@6fz!#wkh1)D3~=UNRmcTlv-w-M=>Wu0z#*8D_bAgq)bv`vKVGl zhgB*yphy7%Zi5OJHcb^G=Uht3$%NoVHcE{JB*F?o7>drhAd7CfB!rZRNdE|{7j!b9jh zuO0+g#idyP06)2e6e-1k$Ix9&9|dD5wT>IpwEDslnwnG;U45ncI3A-kR?!?GX2_JpZE`#w_xnw9 zUTCpB)yoErg)d>n6DhFG6B6uSH>*<&U2c8dtV&c?&BKZbDuujUZH~vLxALq@DA!{Klshc2irG$)0Ep?`nt z927`SXkvX$~_XYdM5alR`w7ocE1_%nNCfbyJzde%k3<(q*c7)Emp z@DiyDg;4+owa3i?Q53j}-)^37Zl3=f@5bAI7&|V??QZG$BG(y?h>4jGbf&X&ZjfwbUv*@ zU&PQe1LdVb?3F^)0>Bt42RZo6gMXerOKA)Utx+j!?PyB}218y**;kTxY?8 z0iNPl1fK%)vRs!LOrC;U>^Ci9Ok)5O#$3NCXF&i@5#R47@fHY?Y8WcvgewwRy;$S+ zK?}hxoB`6eI3Wx9j&a)%`hNovxkd;sj#!id3JGb=&wYOI64tuQ&pqy zm_P~Uv)<&@E64Bh{L9QCz!BIG)xd3$5c$LFX_8A zv0g$zBGMGTMfYA4Uqm>BM=gUCg({vw#59qyD~Z1@A5V|-{PZ02;hyh2@gMQZK`ngI R!*~Dy002ovPDHLkV1gZb5hnlu delta 1483 zcmV;+1vL8O4BQKlBYyz2P)t-sM{rC$J3uxwH9JgdJv%}>IzJ;SJ~lKpQ&LhsJVKL| znlvylNk~m7CMm_p%S1#}`b>3T000EQNkl>VM5C-5e zjoW4?FcV4M_kW#r$u{r*UQ<;vj?)Jby07OC+!*=eSD^zZe?5}_Gct5-O3_xv@DG5Y zwl?!Tj`#aGj&pM{)knVxtY&$P_fz6MD(ltnAo|2%)SwF@+2HZ*tn$XOvl!Axz*rcM zb}-|{ahRDC690i=n0q7~p20kciGR}=u475qL6c=BGJg_6!ps&A%tM3qITDT=1Pv&_ zP#tj4n2x?JVdBETMuP=_pwc-&WUKFpDXjy-ve0PI=rKTiw-qCUMNPwj0K;Yh1*8sY z8tpzYXei9Ktr~l{(4%7r0?)WxVky_TAOK<6Wc0!j8{8u_T!H(rYYJ|LH$8-7?$sDg zc+i#bA%E1w4SqrH)zAapmGFh|gpdepvR2`g$xuB^jzj>n1i|yX$n*M0b43DOB@8Ew zgWx(A4Z)8fh|o-2-ay(O%AM$(F-}Lq#!0x|F$`P8!HX`FEf}AuPPxWh#!#qzFA9%G zcyx%5T^t7(2oDSeF>_rT1hA`v2%+<%`94A)d2scSpfxE6JmACG}|>=2P1 z^PD?m!22-8Fbo(25xx}{#Zi3k}C*%i-;5x()_T)#U<>ftbs2gyx~NAaB(eYoNjPo5a8-!t(RO*@Nx8T`E~4 z8h=+s4dh#O@g-sN)lFjNP-;Ias^b0q?cb`3B~es|H@I-AO1~z;VcIQW^yIWHyr?{1 zJ}%X{1c6di)yKzWzW1(#d-Hq_J3>U!u`G&`&K4!i%c6`!uOsZ6gz*o&LOT&&7-0zL zov$zg!jYNXCTt84biBLt86iv9YC;-TEq|g=8c-eI|4Mj7(ECgjgbN4nOO4R4eZLk` zzqNWGd z*{~@{nSr**KuCyq zouAK#bDJ^sN_IQboDS~_83;&Vfan4(=;8+aY<mH25Z*J zff$Q4#YLNRdnFDBdbUKmrB~CPt}L+6XC zsXU_qS5ereKNZt3wh(H8Yr*)HfFvpG60%b4qep=8g_!Tb1Y*+?ik-~1SaKr?M8@Y& z0xxt#x}A+~|FQ#-ZlOh*$V6E@e-bAUI|5cc4Hcv45s)5n27-#EK%`h!zeVUzKfC;( lJkS5WX8c3ux}Z1D{{ZeYMOm6WVT1qx002ovPDHLkV1j~ho67(I diff --git a/TMessagesProj/src/main/assets/emoji/0_751.png b/TMessagesProj/src/main/assets/emoji/0_751.png index 7a7a4144dacc9b5f4abfaa33483fc40128c64688..3c6e271d383cb0ab5ee200b9d7356d31ebec8add 100644 GIT binary patch delta 1629 zcmV-j2BP`I4(<$)B!3!EOjJcja7-W_9waWLn1W&;BSI=Qw@gJyWoK(18yjY5ZKIQj zV`OM3Fq1<(JTfjWgMfb}BO}bs&L|@ze1C!_E|+|Nf|rVbTVIZPeTFJ0C*`b#*PVEU zh>9a0AANv>A|N0qE{?~^${HCN$(3{IvyH>W#=yYCzrVqShkuERjgN(gijb0&h>DDY zgol2BgfBbFp`@oLGP#%c$?dp5Lj2C?zFJL_^21l+nJaWk)kaJUX(Sf53`hRx=#=@842MNnuu2 zHYOQYPEMI^N`KYizWd7sXPsOiqpmQuA)Xy|?b00i4f zL_t(|UeuG>ZrfN4hHc0YgaB3@T@7wOyYG_|FGco+b=}N29 zYLj@n_65YuUtO|=4u`{Lvn=NK>Sw25(4?z9Kp3Hn0%Fw+qLrwg8hnQC2Dz zlAO4A8tQ|O&b=6ptjaA5WL777dDZ(mnat(TV}Hm)W^UIAq4bQ9Z!((qot%dKBOwNt z1pz{8Knh|62;dBQ)cU5`c1??QNrE5{R*reSrXV<$08#N7_aS7zU?mYFosbim)iz(# z8YoB`^u8B?qIvCRoZI%9A`O{JRRahULoP%aGh`%8%aq$3B_U~=2E@#BYq${vKpv2? zz<&iOvUl5-6gx|B&a0A{*b40*r}l`5il>E=?J@Hr^s-NtBn`I0#^a=KFCL`{!rz7L zzmhTb#MWrzLG9g60Fw}#r=_A~_Fo9cIL(lOHozG5$)Gd}I4MgdhhxUi9`+^vt4f-3 zVgil(&+KlC2$JrON@-c;zVpHNxuRH*{(olJN%7Qw>J~Ir-keCaBBSQAE7!64MR^c#^(dGrn;6&nDgsEU31DdU|lM8~eFl0fC zlZd?U#(w=k-QK=_Wcw>+sO#|c; zynp!oDf%!!;d8*+5R8d2rWDT_;j$1cpn$+4o(M7=8F8l)Mj@t(KqXR2Dq)By#%qa3 zDN$P_Wssg*a1C`35?mzWq-|tL__Y9_5;cVgfW*@9?PycoLbX5}^{>Z97G7K?Wn>;67Ovnie|ond%n8|iQ%QjWy3ARD33G=vX6$iG(wMaU<)M3;KxW}EeMe?NOXO>(N;nvsUZkAA&GA( z6T>j_B(jgT1p{per52{lQHaZ$NK_*S8A*MbJ1~(a*|$X3bwhW2ll;P0lk&#<+q>l0 b;F48#tQB!4(iOjJcja7=r9b;!rX)R-3Ks2AUaG~&s~PphMs#y*#)=XD|Nr>MN%6KH(UcVKv?R-r6sV}9yM7Myxg@u?vgoZJ^}Q^u zt*ET5r*?L4l$DR^v@~XAUZtg=$&3)tk`$9=8-jv-XJ=rgrGK7-VJGXb9@?H4;-wkz zv>gA+D$FIn3AZdqxrug@3$rBs~PdTF#N?P$&D1hgAt!&3bl9+s%;CASPcB- zuJ_V(etviT>%X6#nRj+?qobaYk&E=kPxrtn`rME9%wYe_Fo}tR{NbI}*46mif&KH* z6blA|ObGh=_uW3`ihW zNU~%FOSWZux5MNd$T=tF=(z9y277x3OQp3LVE^rbs-|bSXTE#8VCDZnBJPv;kAnDG zc6V!ovA>&Li!CpRWjFGjT=9}o%yse`Td5^2sf|Xl-|t`g^e^F4r@4_`Mv|@Np!_)? z*4=Ep`g2eU9Xx6~oIPNv@I3E@Iei=8;g#6@Mky=`_*{3S-> zk0xtZC$@L(IRav3Iw0!0ieU9O^{p^P?3kras>C(j;n21)QXkP&U57wEFphD20n z9qR~Lf@azvaRj1G6_~(+5CTOsY??ajTcxHYAXPJ6&+}}@5->raFwxY(ZHFjQb)9uh zO@Gf6Re%VV_H2viL0}kx zMQ0+61<&>brodr}ZA4Y%nhLgD+q2acZ}3cGAZW!A1ZU_HrU)G;N0I4@#IsF~w8h9<<=3{yn+C~*Ws<^E>0o_}Clo>Qr96GS%SA&U4WoF`RyUgfysdg}>Z z=QyPB3WjNr%t{y;;+UdgaQEZu>v59*X{i5z{r9iPppHd^?NG&uX$hji-HpfN!Oea8 zr=$6e?eFfXXgYXv&M#H7ut*irOwXIrVcvxsJPb|3~!R8)lP&pty00zZVka{`UbBNpA>WDbToWCjl_07ZBwlQ~&g zh(zoJ2M&rfj?+Yi=@7}p5-W+71xaKA2h|8Bg!(e_J~+;09EggPQUnXE+Oh_4q&79E zo`N)-iLWe8^gSjTXpjco2!9`72+Q-AW0?X51k-UptS&EDeJ6c)9E;&N&iB&M>*aDJ zR{uPbL~16xLscC{+W@&QQZ3JzFxNdiS=1d2&_!j@5&DWp1q4TtVyhwLBR~N>?aZ@J!KV`>CQ_o-qtitS+y=c(MKhIC|w1`QwpD jaOKGV#`^mD+b6|8a^2z!+=yqs3hpLev1McAr?-nEXyhh3$1K;gTU*vEg*##<}q5rhjZuB5`3t^XsYH-Q8g{04hAM0{{R3C3I3wQvf*Q`TZUK=lu=*U7n~$ z-2LbMxmx{m*|M~>*p^a)g~^78mbJxm9>)Lx1gA+vK~#8N)RoC@+b|G7qk{=ZRw06R zFAk6ZX+MEGweQ}YrS1R!Nr#jj18pEVz4eKQ48VDuA%E%c?mxiyXBOZ8$8>KVE~1DK z5=Dz}?#(`Jm@i27<4RUU;rvs@_#uJ37yH3DTgbxugd!|n{wCXW54RTLJ)q6YM`T5K zlVcXf2__#JvaDG6Hy9S1ETKtuO}u`<4R!bnNbV>mS+>dkV6!QTqI;M;%mNl8lq0eM zGB*aCfPWN4WaGp~X6Tq%(Gp~@wo463x&|#hD z95$(Ju6G?H%8PhyzlKZhko#6&U z5r5Lu7o4UX{)C>CMh#kx-p*A+m5@fVUQ<~P4kuxnG6AIov_VgIV?1H5U}nENy=~u2 z`CdzZdflFOP@m$6dZUWRfVM)i>g{ycZu``=0V91qK)icqvgP>RA6F<)i0bFolJCp2 z;n~G{y%UV%)s!M=g<0>9VEDz?>97-3>VIOou0YXFD3(e=Bh|V;9$$HC74VhS`fxnv zyjrJ%srGT=2??yiq@F6(G3up~w1|e{p=>?RL-aKrn>Y_`93-?E{nlyHUE?X&nZl0DNy~1>IC) z5hzlT%EET+vGYTpf(6^Y|D!O&bcRV{P*2@eluu{IIZc>%%s7tpAJ1nzl<_IW5yB9F2WbEo ziMYMRq)g%#LXdH+tWyXeqP7Yd#Q#d1i1?|IW`GhAi9m$hh|LQVz=SoDlwg8{UkNhc zYIMdB!d~iYg*alvXljU(FiOO~3I4Q{=$OfjWM0MJ#FIBh!b3<7`SR|rLVva`{?~{S zl#o$iYTHXYLAI-4Vp}DA;AQAGa=v_EMu&i|f?GV-h*u_@*2q|bgiAzHJ}f16bwa*R z$ZSCRB;y=a&_PZWVc!&QYH&hJL>n?-NYHIQ>{r6J8I%Ae9JH8k6U-bQiDqRShMovE z1Oae}1{5e}4kU)da*Vs42!C$~M1Z4$AvVL^epRA>U;^VP;Oy%hCW9k8&gBq1Rm92{_NWhNpbT2M}7RZ)_Xi@>Rw zI5RPUfO#h)Bd?l?;NILaEiM25|GK-lC?q5u8yqMkBrPc^)|qq6ysg8IY|fr}w6w2u zZDb-KAicf0tgEJRacbYAeZ9T7qoSPEopzpWPqMPDs;Z@MaDQkS7#sP)n44}?oSm2^ zA|m(Gv9PeK^v|po6czEwr|i6!_uIQXHa70VpPHJK=CqIDs)P#)3EH81z^swCo`L(~ z!$dtiprD)o|Nkl{C;Q*Oh=_ss*R}Tc_WI<;eSCGNr=o;|doV04HZd@Eb#6*RLhS79 z{O8F{IV@61N`I`Zr^m_4;Lp02WkYmYMc=@n(7T>tOES~c)s}QxS2Y=}dt5dr8`73; zEfxp-?$iD9-(FNyqm6W9SXiNE7Q>1rbWH&}W021P001p?QchC<59fRS{x|*y{S+VP zvPJ#U=>1pXn&X-)^ZS$A!%)JS#d_{?tJ&#tijl&w*nh{^`Tzh0xJg7oRCr$1muFKO zNf3s?S_uiABn}ZpG6sx&cbjuk%sJ;kwtfHq4_x=ivP~823V*wop@tc@pLx4?W=dN7 zAIQJHkpDLU!Ki09w1o=odVImR1AMz%_4eZzqQ{MPeQP(m{wBb>XRrO`nI7x%N%Rc~ z`FG`K;eU^h8|b7O@~vD258eI+fCNyxU6=QKt0qBF?dO0t0NV9>J+T*E#X=|{Q@s30 zf(d|x0{{q#ReY?6>W}R-PuI~qlwi3$ku1wqcZMecQ5A!)z`AX+JXsv05m1$@A-_u+ zdl*;cfst5>#G)z{(xNUVWL&kv&+hoNybvr*!hb92%0eN>J?1}2VA^TE-{%dwg0UnV z0Sh6==R^qZq46rs&&~dw!PDuVqJIo%kK@Uxpz{jNPZe`MGXR2-ghW&H5)^WB5v|DJ zJ53t{P7uxhj0Xxu(L~EWO>a3B<1^MAJl|A@949FHVSn7Zp?DBY<8PWkcASc_n?~{c zV1KSL90yGhHS=)ZAGB`34K%_?yCSF?zRobYT#kXpKts@Nf6zxWNN{mMrz!e2W@j=C zmy;w3L7*H5Qu^S$eXCr8&W(20!+r1tBHZFnSFyoM9^t-LgD#X=84{T zvaC_OP$TY4>CFA$5(#GlX^aFDcms9Gg>#soqeBK)S_UKv47PV zF&aJnYt2#Tv8gEZQX>O2yUj}r6Ahb;W2v4Xww_!N`?@X)nbgDh?(W~Oz0~(=rV29{ ze}i5S=lZ2H;!@W&fhpvB{jcAK`G*2g{62+aF5kqhu7#ZuVG|L#%)>+B{-FsTn$0E_ zgN!pdM$k0JAVoh_xM)euVx%h45w(?`KB|%kHz4aoCNU%aev=L z7}@6%gNXe#7ljW^QD7jIcm@zs4z{)g$BhsqMi9-z12@F_&OlT+hLJJ|;WPol7=V!@ z3)LKl{BDTg&W)}R8^DO?G}AP-9C0B*F@>0M;)?L?7*n)?_YL@96j5OSKz|6FpbU(y zbyoy!v|x8}c=1W-9!Z5I!K4hhZ(J0G%Xcm+z(7G9!{H5x*B_^d1A|ZdT+8V@*=d=` zfKYqfBARl*0>UBBZ+XCln|wacv92isKm>cEnocLmLjVYhsBe4@MOXZ^7TiY$2=X5e z1q2}BGPven`9t64xvq%-QGXOsRGI&|g2w4iwr};Jl`q+=bxz|J@P1j?W z4g`nOVwyUUY2IG_*4KcmTOyNme{cSViGKq2t+~*xX$8(s-&l!*qYG8-_OKk9ZVn^e zfO_#^bM^S}(b;uU4J0G^Mo$y9A@p4}pe8>ag;%QS!H2VpWGShtfqzaTpU+3E9(0XK zGN7tSmOVT5y8}K#I6qGvc$4SF1Oa{M;4=#D1zvAQ;lu|5TyXjAiQ(! zSd-It9g;$lXd4OnR4M|jMiRLttVpSJ) zzuzOZST1KlwQLF0>3>dA3pFMa9ILe={IgsPoV{jaGm!PxipWq)9nf|@wN$>r;#5h^ zmdizNEf9WXLx*d{1p;0kJdTK;41!?U06`SrzvAM(w?+_Ul|>WJ5DhZLb`~zY$D1$b zaqKPDyod;}Ec+4yX3GRo^S+!(7%UVKkp%=Y*k2G47z4Oe1YSf9R{HcJ;uB`EC})So zAGYxmF-`~mn6ZY1vGJ+%tS00000NkvXXu0mjf;)#(d diff --git a/TMessagesProj/src/main/assets/emoji/0_753.png b/TMessagesProj/src/main/assets/emoji/0_753.png index 8ddea6c7ff15c5725d574559da993b4fd450fd59..4f3dff3fd1f7f127e83f17ff1a68a62fb877b764 100644 GIT binary patch delta 1384 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 Z`~!)BNo$%Qu;>5)002ovPDHLkV1lG{4J-fv diff --git a/TMessagesProj/src/main/assets/emoji/0_755.png b/TMessagesProj/src/main/assets/emoji/0_755.png index 19e1f47c29eccbf8f100eada661fca94a7e72668..ac41583824a400344faa9efd25d6676e2d32bfb1 100644 GIT binary patch delta 1359 zcmV-V1+eGq$Yj<0010xQchC1stt2cQ7gh{n!Ae zG;jZb$}%IBW%-Z(BCnIQVx>u)7vIO^N!9kBYOA#V9wn>0{#hrJ6yHE3&xDrMHHTM& z6t%CO2+XKj3i1*oOBxT|a|A|Ir`H%+da4FDw0{FC(SL~;b(B#iRo@y1T`Q9OY!!8+ z;SgPBN4Yz2zB|!p`Rn2(x5yaN6tOngMhNE(dpEb~%%<2law9_{gac!~cn33(_>9F! zI*v^Ug1|sdv5VgiD`bBfW!f=e08kQyY@646E=1{GCt1VU2M=JaawK4<|9TLy$#xKh zAqhfjy?;Ugyhwfpv^$KPdgsjGEFv-m{$RlQP5CZ@MFwS&B^av|0AW4@9byPi=`nr^VAq7til-2c2+vs zBp|IoYl*SD)U4rsvYi0J*c1dq@xa6G)hbg8p?@iOSjMH_7(%0(*cu2?zwN08M(F-J zFKW5qMrdcM=Q|=Q2T;TiR%1Uc^WC}Y#t0wFPpZ!!JZPVm`v?VuI8O?cbIbIY2VTwq z;NW)rr7gq|2S)VAiMRTGJ3eAC@=>1&p<;hIN>PfBt+M$(qHGuuaJihqo&HJ2@1Yi}|#Xd0`0FZ@rCa1sWAaC<~dEief}_+#a5 zx|hU<5HO&SqubrgB}lh;D-k`2rH1w6cpJT?yoz1oy~iZE2GQ-4b2mh|A|TH74uKkM zSTDk@vw9UEzHcFhol=WO2SJFKh<~Oa94aPs4M{g9!ja{OkZ;-Pu)U~N=%cQYV(iGV zV$K9woT|+}+hItAV*-dAa~u{VNx%m=h4$+hK?u}H1S3|*tcYU>Uq)$}IDue97^9D; z;HC>PgtlI9LJ^E0Wg+u{O|lZ%7H2o{{W#Tk9GD+ RrCwM=vBqE+a}YB~CmtJS!t%O+#u{OmbgU zcx79BYG7DJJ5M|`JuW9mH!nXcAu=T(B^nk*G%OMg3Pdg>F&z;w*UYC|M}*H=p2nir2qf~$4Nv%RCoc@kVRsJKn#Za7>khLaQ~Zjv@Sz;{gB;n zdHN4L3V)Ul#yX#H)`a1{!C*Wf@t7e5@50S8!Q=Q2Mt||`%y5{_wjSFqFTqV*F~5}1lq&1CZIenv6MOrg!_SwH6s+rYZQGhejlH7r z2|w=el7Fi2>ocY0q2?+ML*Z{J+jrTELX2d~ae)MOdY|`yvTK>ld>xXL(DBcaTzga< zw9Qg1ADW~yrd~r7d-1(%+MaX|2_ogvuQ?Nz%hiMy|4HNt(HbTz5NHJ>l9L5=DAuwm z;iqr4pdGW(*ed|Rv~sWc(r@dCoe*|jyDTPc(SP^7N|a0z8|@mR%!vbN*o6>7R^l*` zO&qD|ta8moBObi9VF)fnfrt`M;_|}S3`EkVC@?Aj<%T#!;Y3!TdMyc-P!7cg0(>A) zmW+vmC{qj(DrHE)7NR&TCd@F3hH*GcE~0VHCL8T)yZGft1IQsp7voZN*~G~x3FaP} zwtrghBQ01C!5vS(<7o==@j(nsC;iXy#K9r7D|IR=d(a%*d^-K#shcSZA`xzGkEgDg zkL)xw8v{m#N;BWxt7g}A;~WP;#Ayb(o*qt2YWKK~D6Q9Ke7IL#*Y)GW6eSm7o*`ZP z>1j69;|Ah4wAu{!Pq#|p^UKps$hG?Vkbkc2^Zazf&->M4@{ASkPz~B$;A+cul~klaeF$elof>dh(nOX5PzFs>VFU0 zD})-5*a<>h5F%Q)xX7u1rJJr#1JG;p%?O5!6F-9xn0(i4B8oi#l7w;&CX*HqY_#gy z3lJ^zRzeXu$MO%E;0$?yW;>llbvSql#koMe%JQ6PgaG@pxMZ>Tn^Y`wq7WuXZ%yK{ zA-k`t^3ugtiJAl=N=GLLvQ?2DU4Oh_t5C*YDVUUx+SW_)%NgG4RQN0+jY7Ci(38>mLR>ar|fZWx5r=n8nGVePn+a#eX@+M2i0f zyFC$0a55hH&0YKbag-QAh$m|Nub;jl@+qL8I`nq{gKgW(B@pD9iB>{lN<(`?7*Z0! ztOZ2FxQIO{uR#!WQaZHP1v`FN2qFkgA&xs)3EOV@#BHNvST zM5%cW2t*wS44p0z=USGtNa-y>`?(ZmqP7e{;6gG7sLdGl*^)CoR zQG`$~6I--0o=DVWD=!GICTKJQsdaPVI#xn3jSYTDs1btpG*!1B6C|fK-8hB+J%#5= dw@$nu{sX0)9!>r{2c-Z2002ovPDHLkV1i;N{+Iv& diff --git a/TMessagesProj/src/main/assets/emoji/0_756.png b/TMessagesProj/src/main/assets/emoji/0_756.png index ec1930dbed51723772bdc3836cb51f546a2da2d3..a96b14a13715aea31031b526163875584614a0ff 100644 GIT binary patch delta 1595 zcmV-B2E_TH3(E|UBYy!7P)t-sM{rCvJCW(LE9SE?rIKpcs4?BCD`aMBx2%;VFs;kX z&0Arb`pZh$tT`$+!|=yjeSd=V!#sh7h$u0fZ*qs>sUdxTgKu<@DKVQSE{^K4Ac2F1 z^t&X@(An>}B+HyO-lrqRktW5*$HBqDiHweiiHwYnk%Whdf`5dDk&~597Cr zxiB9J&a7WrHGd5f4hNxS4gdAjZ(KLn!i2rJv((JAu#vOH0000abW%=J06l-C9bzc( z4*k{q)JN_6*|ve)T-&Stw2tJ!-O9v}#=fajaX^-r000EYNkl^K54^N`nMppP>aL6TmA$)@|NoKHwas);Ms`o$a(@s=My}&pZuz(W1FK-UTn4NE zDp+o2^X=NRozE7_Uw`~!yN>fin!XWfy060R?AI)db$occC(Xn8=F5U$I|$Ny_TlV{ zZCS4KKKelH?zomU}-c#k(jp!x#f?ZtZu0$x@VNv!GNLMvPUi0)|p$2toDd}6elnw~6@ zBry`(nmj&{&fsw*;4smRnZH>vcFnRx3vgaj50CALuXP0Z1^`(yr3fCmR0c`W{u`2^yb2*F z6-JT)CDjh?4HU)*@D64s6sw&S3ecHu7FWC}bmK|Dp<+UgZ^<{I1t4ZkqKz>(LoMiv zWq*xu$e9-7Cw#87uLIz|8MPN7xe+uo%kf23T`Qaw2^03y!A)YUA2b;KeRNfWE(?eD zRJ>o_PdA6NMR7hBA#{q}XdyFHj1)Y7e=jbVA{@%GA4gIiKfd=k`#dD;dDM{ zdY=w&n(D1MpA)mM9P)(0e0)b_cP{EUWG2qbcA&~n>=c&{ksHNdCr+m#h2OEduIYE6 zzeI;1)zs;nlj63houDqG-rvn7vC2v&rc11JUq5!;=kd`RYsv@WbaXX&ajvX3)`YgQvlk9kAWGBHzJ-`JL`E-sG zPSY?^&h(~S&X)^)IO$u;BpE2q?SCq#@ZR^vKt%N3IX5ig=o;re#t5eGtqs9`{73*3 zYs0ZX1b{I_*kDg}qGtl7MV&CeXc4J}Ct|KR8GM_FNu9%1LVQ^xn$o65tIN0G%84mOf)Q)9GSR=AU&8_ thim~PV{YinekoR+SwsECMxi;045ZDy;grfX_s zOE)hZ6%h~(3@jTCFd`bFp_@A?A+WEiC?zGTsiay)I)#LNJ%2YgR6jLBFexD(9({Xr znwgVxacPl{hVJg|+}qhlKtKQg|1&NwV^BbPX;ra@OJP=4Q%XwZ$daXK7TryEIRF3v z9CT7nQviP2CSRT)5BB}%(lJHo>ASw=VD03XaK5X2a))ow8UO$UfJsC_RCr$1*6DKE zSP%u^5k`Ov7=OHFl9{_-?Ymg*eVWF3 zB&MUDHI_IObHV-iFnXGW2gT_rvBB1HCcuE1V>Z8M&|Slg>C7?#$u0(c$i}B6Qhzu&$fAKx=V1(e5+EjF@DCX!IVVMsgjhF$;UZ&6l7tBb9e_Ag{QgDgC=;ge+FSOj6GM%*2N8uRS1C4>6R=q+zq(Ny&cwTt{sU53dur zE`QQgD!1obODUDIt=H^-?SIz6;g0N@_PS!sDC2Y!qX7_bM{*rlO>1m{Ny5llU45_w z2sQ8f`jyZkNf=BgBp^Z069#l@6udXP{tzB>+8}NQ0XkhmbgdMD+hU za|LbE8VPXBu%idh`C!~jEQK^gP>hsPv42*e5@Ipx6UI})sYZ*y`K1>ngg@&&iv{P> zpb;LM90e*NvUwjd8*olF4q+JJNPrT;ANDRXa~BIV@C!WUT!1JfBP^AI4;)yeFQeIT zAkko8C=OAK0HYSJ>)iYoBN%{C2qVEALCc%}U~};kOECtq6olo7{M!w#2%#V#L4UY2 z&O!omh*Hvp74FS!$+=XNOw#-M{y1FnHd4yL?0(?k+tY`VhnTW@f4vv@>s=R~w}ojV z<<4t#p}#%cGynXki=t@OwPsR=b~0&nRTPiUuj8BMU!Na~00rIDlXbJp>-D5=0wA=t z&#$)tI8H=RPwI8!0aVwGMM5L;(0?O5+d%80eb^d>b?w1IwXN`n*d%~6=@E*e(iCXX zc#}06liFg3pr{HR1W@FHU%7O-}J1Dev$S ee7yWd`~%G@HeRjoeN_Me00{s|MNUMnLSTYXZJ0Cw diff --git a/TMessagesProj/src/main/assets/emoji/0_757.png b/TMessagesProj/src/main/assets/emoji/0_757.png index a5770a88d4479ba727b7c82b042e16bc22651615..396d53013dbf11fdf9828fab0f816e6bbaadf6d2 100644 GIT binary patch delta 1553 zcmV+s2JZQS51|Z@BYyz-P)t-sM{rC!G&DIkP3X9jS5#=s&CfC}E@WnFj*5-Wq=GOz z#WXK3IWsfJrH*}nf=g13LOMB1Q>-&DFC{Oie}ROAhl+D|i+zBDDKVQQESM%Pj>MjX zDJCY_rGm_vdDN$f#mC2rjE;n-LHY^2(?8)w3-rDevguB_Sd0!=M})8T8MsNkBi~se^W2PWs@%1Ox>) zF)`Gba#Tr2`rEs`l4_ubay~aV(YBX@a$>cbfhY(A|K`R`BM@^$4gCE4z^|Uh!oR0{ z45NBg)z8YDoqwNd=7wtk001F$QchC<-8}vx(pK;f{_}jKSJ_j{`nvJCbN!RF*^Y|$ z*1W8#r9R!4000EGNkl~x2j z(a11!H(yZXAk~*YRrbR_K(t(hVYpaEe<@gotMzUh1b@MHw_b&dKh{LyE-=*<6Kq$D zKQe^dxqilU>-#0kb!SWLb;U_m(Vd1Z)c;Bcmodd|c~={D_U+w|6w?K(yByKFaDr>K zg%u32_w^kH!&CvKKf)Y>2_e`ayg3VFSdQ7x1}6~{hakEUVrvS9^IQpM>1K;_C_vnb zvFHjRFn>5Oo-7>zia7^3ZggYSF(q)CihQ;Jv&1O^|4`P2P(n1Q{4fHtOcIv^>XpKP zIxPIHC?IKpBtl8~ks1&>1i*@}GGI{5+l*zvpr9gvl-3iM%@<`^CP~SxZ*@x{RI3Tm zRBP=#KVcMB?50971O`oMZK0Iv31S(rxXwC?Ztjl z=zrHXJ*Ikg)MHzn+l*L6zTNl~ds!$@5S|Y0@iFG4d%;Yg5!O zub0dFI|qe>zqIh&a1IJnpl9y}Pm(m2M1NB*oA{H@Q{}vGdY)-bP}88jcOs8TnIJoo zdO8~pyM%pV&znSW$}*AUD+QG{kwo;{Ku}qh8(%%J**gWDQoxs6XyzPL6O=q{BFpaw`hTNzw11;E z3`7C6LR5`-0HLrf%Tqme96ONg%YH^>iT(eN>3C+aoy4fUL`aC_=*~DlIUzi9Ld>H` zkh^|Ykml6)-!b=i-PfT%d%Q5iFubja?Y`@bQ3}9X@A00VBae9Rtp%lw>9p3)>C?Xm zG_o?VK!h?K8Lxb}OeAO*sfPeX3E4%RpcZ5lEs7FsknoCl@AT|gQK2s0 zCjpd6#Gy*isS1GzGj`~+P!O9Mp{WHM7;0gSe|*zVSP2E{DWVRQoA83~+Zn~ApFVSfF8j(B_967d(vW6MV-R;51x015yANkvXXu0mjf DNRrg< delta 1908 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 delta 2018 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 M07*qoM6N<$f|jO#d;kCd delta 1980 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 delta 2072 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 delta 1835 zcmV+`2h{k-3b_uDBYy!7P)t-sM{rEa#kO@xE_P8rcT6#dS2=e|Dr`b0h*~?6VnLN< zNt$m=pLJ4ZK`V@1J%CX#hF3IuPAqmwDQZ6-aYZ9N9}HG76<|0VNhuUC771@gF@;t@ zWjIhm2AnFa>J5p z83zNGgKC{}T*$VlWnp8=t&YE+iJqI3*~-23^Yh)-&8d4M$E97rh6#~h1FC>K$&)4J z&z)vLDOfiooW9hPv(tl%lV43nf1SL$&)uZQ<(|LYj;+gkn!2jQ*oCIZv)J~$;{Kbt z)vnX?Z;`X0zkk)F!`Z{@|F_=ys?P0PeWmZZLT`($;aYx700015bW%=J01F#FRf4K* z*Z%+i|J(on|NsC0|NsC0|Ns8~|EvH1|NsC0|NsC0|NsC0|NsA7|Nj5~|NsC0|NsC0 z|NsBI`Jey)|Nbxk|NqEp|NsC0|NFz_|NsC0|D>8CGk^U600n?aL_t(|0o0HMazil; z1#4!;^!^8}oCz}wbw9&fOZxdAAcVe1V?r5UFhTGqdBLU9W`~lJQ}m`lYGW71n%#|( z;*DCU)Q~aS=p$fKPP}Sh%37_?@UTH&f#X*VTKNOf#~twSnu7#w{2>;$rx4N>xbhd~ zpmOnkWq-qt1ms+IWctj2rAe&^P#jo>r6{G0QmT8_3Nt><%^Z1`KT1F`fRe?tB7CmB zZQ2|qhqwbQM@QvPCo#&Hv$Zy7FEyp>LK1%5hcCU1-#<#rbFoz%h{9XaOcGpal7i4k zNF$01j>+x!zW-D0fW1Fma_H^jsLpT^MQh$$5|Q22p{pz{lm$aAas{!7rvOz-A5bIe{}EwC zS6M46rLNY+{UYW7?m3iARn=8Pd)hU0S~<;M5EM(3`^%HXDh`#k-uaic$BGEe$Z+<> zHmTbVx*c?SCUAJ$fvY=TJJYAW! z1T$a}Ejo0*@y>hK(1AoZEf~SV%TvxB7a~`d7>?w<#fCOd8Wf+Mqw97HL_g zOnIt~5s{0l!Ho1se^y|&Da%Q)FUJ)KRShwNtDO=dHT zN}1vY6Qtiot^p|+Eao$Q3_}!_6Xui-*u!mUlHf*RNpUr5PofxIu8QHQ#%sq9{ZQ4owhf?*Py$ofp4vP8_Kyxt0o)loEh;LmbjMfBpBb zoAoHjhgKv>QYS(|o$6DJ!07Soku&sB>Xx6<-7Dj{(L~WCLl&qMpVVe27@q{WF+-M6 zFq&sRssAb|3nj;47=TWOkAIn&h7XpRlq#|kJF?qY?f(CdoYLGa;|mL3*u?>qqgU_W ze(rhu{&R`dZ50&)x$=kc{>P6|>4@vw^*2rJ*@YHIuV23Yu^?@9oDQ0*xM}}*B7mld zZAaz80_H9&Swtq|<_41LU_wrW6PhCDwk^49b5N3mBI2%<6wM%DPJdJA72WdsFX~L8 zJoOd^fpK;9Yj7q2EA^Zb#oVPQD=Q1qg-BCm@7Vxut};ju&w=FI4j1mOEXHgh5c@@Xtu0gnA#y#vo)Is*jLHi; zI!2B7Yi9|g&LP8@34ajl%kG1TNe80FXiK2`D{G~OI6wL)0uQOW_&#b-=d3pL4C~BG ztGnxxhtObB0GFDJ?<0v4MC%K=C-gJ^*_~}JxA{LNQXuCKFTRiDG>Ybd)+Xz~joEDT zS3W^dQG&X-NO9;%1F7{MV^7l*_v2B(9Hf!t!iQ0q!tO%Na3l<^n__X9+GDbYNDhyO Zu)m84Tkh~!qG134002ovPDHLkV1mS@n8g49 diff --git a/TMessagesProj/src/main/assets/emoji/0_761.png b/TMessagesProj/src/main/assets/emoji/0_761.png index 598bb5702202bc624f7975905b09e062462e792d..5e55134d14ad33f45d9497c4af3c7e3d590a8c15 100644 GIT binary patch delta 1314 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 N002ovPDHLkV1o72w=Dnw delta 1578 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 v)eS?tz4mzX!0^;>@Zy0IBWSU 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_764.png b/TMessagesProj/src/main/assets/emoji/0_764.png index 4c67a753d4caeed7b384d0d6e3b44c3f36a373ad..caa3398038b92c1084e8f76e7e26e340f9c86a8e 100644 GIT binary patch delta 2092 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 delta 2535 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_766.png b/TMessagesProj/src/main/assets/emoji/0_766.png index a46027b3826c9a7c7dd7bef437afa6e8449fcafe..decf4ca445ff55b42657ed23fb58c2f60a98e2fc 100644 GIT binary patch delta 1516 zcmVT-OKC?hHz7855M7A+wha6lziFdjTEC`&st zBr8EkCm1>)6Maf7Lp3gBI3P1UR2d5iQ$jjkOF}e6VQyGYet%_Lh*L0{VmcZjHakpf z;z$q%;FCZe z36u8LlavEFXMfwf|NnnocaOy4ItlQ7zPD`3n9<`71(?5{$^U74j%`tF$8G-yz_SO_ z>2zi?oenJLn~LXjtII27JaE1vI32-C;xhZZB9`~OFdY?QOa`S?pb+DH0rvU<3*{D1iWFjID=; zhr)Cu3c)!`2{DW*2#kljwdhMBq0z;;wFNW`@_sVDw zg2408YtT@7kIJD>ocEd_LQu3mR zW34nj8vs=lVm#On#pZpH#+Xci4fM{XU#BL&(&rUkIl}YQ8`0l={6t9L_{6 z_J{RnHV5*o3?Wjxb|F7_*+{b4uTT5aVZ8@|ay%T4`_t(>FA2`9+Jyjti8FY1yr1{` zGpwS_0`Bh5n>i2?g+lgf35FHImsax)WPd?GWh^$BB#Q*6bn6J02@Dt5Np=0=tCHx5 z-zOvlI?>5|V~7R(1m#!6Txl2u{vG~SPe=-sp@1;!%yg!-GJ7fe5K=&XG!cw3DR7`w z8A%k!dVX63mfB2Ud@!mqsFN&979^M=gpim90$+~cn@KKd8kl(ksa`jfmIzS8^?yW4 zK?7TXttK%f!kcUZLZV|37#v{i9zllSk-}Z5SU_SCD-<#ipi`52!n_5eAuD5^=}2oe zzY5T+NvEDbfL`XAF$jTMNOB_tm|DUMD5b%<)QCV3P+D*l2xulc!N?${3@#!-C`!|7 zCM$(e6VdLDFgFJ7LuXpUQjowR;D34(AZp@vJDn0CLLh-(7|8_{VXhxoO>ZQg=emw< zTfJ`g?MLWGk*3f)$kzYS?RIQlh$WD8xGpps8|-}pS>Io4~Q0|9_iDpQE$ zdH!lWiMaM_-kQJ_t68Ey!W9(S1Iarn_UM1QN*b05sW zZh=5VKKV8LxCRJH4v6JF7PfS{me}Tibnh5;E8k+m+z{)J^$oF_d&rTiTJU8VnOay?;RfqwwyH8-v> S8LFHB0000`y2F_cFB!pN&rEgSq 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_767.png b/TMessagesProj/src/main/assets/emoji/0_767.png index 06461b91a444ab10ea6178da0330a7e75fa2e3e0..56b34afc847aedadd3bfb3c4697f35085fe45634 100644 GIT binary patch delta 1481 zcmV;)1vdKY5!wroBYyz2P)t-sM{rC$J3uxwH9JgdJv%}>IzJ;SJ~lKpQ&LhsJVKL| znlvylNk~m7CMm_p%S1#MmKsHV}F=u9GGC*5NNlRW_TC1Lv_<#5HIX_P*F-KcQJCuWW zA}K%H-{V3*KN%o4Zf}`b>3T000EONklHUWyfQdWu-kCn!VoyW}`C0>p9txl=Md$JD%*wsz6d7`hz?fK% zcCfR(=Lx%1NcJBL%RUm}$pZ5PgZ!q^oo7rq?!G8&Vt*JS!Y(Ec%)`KX%mN8qcMk=O zsso3NVei`#HZ61=GK33+l*R#3%)TRrY8?pQCu2{>4Flr4tyl#X?e`J{3`e*eNDR@F z#(ko*R}qfmpQuNG9#@7Tc-Gw#Q(hN90O32e(L@r~xknf-Li=z|Dzq87zdcXigA*P%n{ZvZ@M$wapc#fKm^k_NF0I!7=ebO3q5lz9 zvA;PBpA0V$({B4T1CN4Jbv~mph%t{Nu`e4Rd0+IY1{u<9B|45G{HVO_LTu;#yxjjM_;YCMl%` zn)8*UAUw{fop2~1_;_=^GBKBM^aL9?oquV<2CCEhUx`o=>U{QX`3Q^E$;W z&^}l|o^%AoQ3Ji6OPq&OdRwBdsv!Wdaf+K7aTJ9~Q$h)WzJ*ZXtYGU{=l2#yjGhhGJOMSoKr zK~XiR2fZ>45dgmg$!RC1SA$3DL~;FHQs2W__=a#B!+}9XVg@Yl1}?%z zpbYvf`0kHz2?Zc>(0=Q`Qy=l z2P|W<%-=w~m1)cgljCzvSM2!%h&7xnmrD}zY&?GLQ(j-kyH}t{QOwP6W?)PT2)QC& z#=G5RSEsLf<;$gQ54(4T0s;{f5KYiRU0lI0=64JO4OYw5YLzp=9k_)8wtsjIYv$U4 zSd;CR7Ol32D{;B-FB98?dUm@swIx=E0}NGy34{?4Fwp}7ppI@5KetTeFUZ@=%c}xd zc_sl@Az;x@%`~h7qFT^e82=`ae2ZNoGtEA32pC_8@ewA7RZVDiGCEMn6%&N?cfSa_ z&=A|hsMr3@4q|&ii*3%cctZX~yh3aUta|EdMsY(RH^dHvDz*iI91dn1VLttA@DH;R-;9t00000NkvXXu0mjf)?JcH delta 2272 zcmaKtc|6mN1INE(n2=k}!bWq{#L6+%*v8|wnfpHGSSC4gj5Z@@F-J<8BSggG*ql+y zQAzbE5mJw6l816c$ev!W-|x@g>-YKN{m19?{{J&2@>P-vrGeZXZHYL`NZWW{w^Xug zs3VRRKnN$8``Mtqtk7;aQ!i`tP@>IwcY>cC&KZLWv^^8&=X#0cnM(Hc{KL%LK=+KE zmc!|jiqewD)l{6Zr==i52Ab-4Gh@|5vgSyHwTS^-MZv;QPhU~O zp?}y|M}tH&hMqqQjmK#-?2hNVBXfu+uKO6)kkO@qsPfRWNy%w$1dpVsm;y$8co^k+ zS?y43Rb~#8b*E)9VP98P+S`%C!B(`dlnk>I0A)@$e}T1a#~dFppsy; z;MGH#1m%+4C#UK?r8DVtQH96Y6WN^>I2@VcnF{4jLc%(zTIzCE_sfTFX$i<_b+G*) zl8Hy!SY5~RQLSU2dNE}&oT5`L?bXkfO;q?OvZKE2Y`4t#3T2KgMG2Z4@FpuTz34_9 z!n(SU3Y&5|4Lysbb&sV$({C1;ZT@VcNvapORh?JL>p5V$oLNH;Mz=9QDOXvC)Uurk z5z|DOD&V4D(HM;D2C6vzb&x^=NAP2W(ateuSYk3^`Wju^9F5&6Y8}~5>lwJzTlU_3#sx3`Pt)oTSb%8e6^0D}lMigUH+#Oo z#5+Up9Zdli(~5iTM7QoKnR3!n1v7;GyGn}N+!t2)=krAS%e%HSXdbS^yI(#T%!Ef7VByD@p7UQ$)FNi%`WzYsfD-jQ zqWJLCkW^?&A}$@W>!6y_WyKWLua(tsp>$%Pzta4{xe_ZIK0VesjI~>wkx}U# z11&Qy{N1D}l{Z!{?JpE@G^wk_;6qrEB0y4C%Y68^m>Bx9} ztV~RX^9~DUtvk-bb)CDVV!PV!MLiC}-o1>uvT>mrbu)-LsRJy6c3PLIe@r*%?1sg5 zEK*&DPoK8ydouN)XzfL1J5#}EE&w>j%;_WZ?tH_=dZ&NJ`%}*@*Hmirp*;(?ZXR4z z^p$d_hKV3L^Y@#zLer?}_1mh{e>$JD2bbQCUFJ06#le3jMx>G08weCL9YW6zad3U1 r4cLO3%I1o_k~g9rw9~RxBIXhA2ECW99%CGS|14mIv&S}>`!W6nq-IKq diff --git a/TMessagesProj/src/main/assets/emoji/0_768.png b/TMessagesProj/src/main/assets/emoji/0_768.png index 9997a165b93aa9d92249a1ad000320efaf41fd0d..33930fc7a568ee0855cce8c75d7a98d95f531ed8 100644 GIT binary patch delta 1845 zcmV-52g>+?5yTFVB!4(iOjJcja7=r9b;!rX)R-3Ks2AUaG~&s~PphMs#y*#)=XD|Nr>MN%6KH(UcVKv?R-r6sV}9yM7Myxg@u?vgoZJ^}Q^u zt*ET5r*?L4l$DR^v@~XAUZtg=$&3)tk`$9=8-jv-XJ=rgrGK7-VJGXb9@?H4;-wkV zl@;)`9QC;$n3$5NsH6G6BK*ZB=&Kp=yD%V?}cmK>VqobaYk&E=kPxrtn`rME9%wTtRZ;6S5{NbI}*46mif&KH* z=;-Ja3kHHr2!Hze_@RSLZ*FJ)+GPIh$^Xzm|NsB<^6_Co6Er0d<=eB`$CJydVBf%f zP%aR+wzJBhM1*QSvY2Sxu}A;ZE?(6~N&o-=Ds)m#Qvm1tF&+K<5(xe=NooG*pXk+l z*|b{c=9XaN$H=sCuW3`ihW zNU~%FOSWZux5MNd$T=tF=(z9y277x3OQp3LVE^rbs#b&UneX1NX664tBJPv;kAnDG zc6V!ovA>&Li!CpRWjFGjT=ASy%yse`Td5^2sf|Xl-|wIM^v~h1PIDu>j3isjLHTn) zvcI-)6Mt)5@B9~v#au6$TI>{3`y9zXD~6Xpl3XL5UBs~4%p+RM6@Mky=`_*{{L1j9b)PQ6_x}FN} zqsiLUh~-|pHbtyV0|ZU;5Ul>Dz7={ij#=uYM;yZ$jVu!*?-AA0G*~pRz84R<+fj{m ztRZAl)v!QfQ=(24n81P%0!1`zni}id;|-G{Pc^IXXzJj$!!BrDV_oxx zYkvqHK&WXu7T}nKI9Mgj!G|hN>a1PICPb}I@esivvMkeesIAUV!Jds>%hYucC`w?_ zm>BZn|W=r}nZ8IC|)%iuUpDF-O! zI>%wdvQ%?qK#a{WMRboRHdQ?CZ$|kEwtv+*kGCv>$Ywn3mTkg$^0Kab9CutVKcQ_Z4$a2syH!BDk$9DWHK4v+^2s! zn%~&|?w%J68*k3Jsj7(u{^9oK=JRm)t)m28)b9NKr1*oU4%v!_DzdzZd98SRGk+Wo zZzlbk?kgI1L*VnI-{UbT5}}F|!kAY&{cppYYv*Bn7ASJT{;q$VV{+(81?R z6c`0HppQ9ZT#N*8=u9G0;vtM4``}gULu{TQ@qT2e5TmXrECsf0+Z6m1U=R={1Dd82{bZ~Saf@nIT*%>8C)y_JikVGbM@G8NC@V<<^4~}yg2jT^u=MgNhs>>R{k=j(D zdJ0l;Ccd&X(f63Bpg}5hLw`TO5SHgJ+cYQ!s9`%FR+ks7z7xO0{b0a7`Cd4ByYqoV)V=*`8i09!+m))~yVYgt4_}GZsx-K~x}%hSy&Yc;zO<|2tHZ^T#9tp4#6kfS zU#>1MFZ=foY#B$|)v72-2Oya%IAGNU5fqUzCOl` zM8MFEjIX*ZMi&G?wNRR7D~Gck@dL5i21+Hd07zHN z0Dxm4vX9!W5_}D3GgI+eY_&?IQoGb@6)NzG_$~MY=}Lt{MLcblfL7^f);tm)+b>Uj z33LodFvuz6t1tdXRexqUJ#D|4HHq~WD40Q#dn`grUaY?Wj$Zjh{&*x3 jd~)Rf$NKvE+b6|8iALe&VVxNr00000NkvXXu0mjfXbF-a delta 2164 zcmV-)2#fc`4uKJnB!4wfOjJcja77e4)C@i;|mqk$<`l4GbI+3<(DZE-Nb( z5)v~nFC!KYC?zEr7Z)NQAU7r+EF2R-FDNh~8%HxNH#9RsKR;YYJ2^Kv77GYWH!)a4 zIX*i(Z*Op0T3b{o-@q zMRmM4Y|n^`k$-7dPT$+shIViJ`})ty#JaJpotvE-Jeoj%*|EmjHfZx|YHB=h^mb-s zS)uruXeLNUW44GUaz+5ovt+qbEhqp004a1*PE!E=XiR)3^8Wr73I5RL`~Exk{;d4x zILDNA{*{yL$E@_b=b?hQoV@;rd(gT700z=YL_t(|UVr7*XHy$l76xEYpp}qhfx#Bw zII~OV+{!uUoQT2p{QsY@@97q^6xABr`*mL^1*-eeIp^NGXz%|c{&?K$^~U4=(EoP3 z=PVN0->+2m1BZu^BTw*mfuJu?snqYvph<5l}unC z3PR9x9q)dD@B}ct3#WqJWDD?$uXhvE78AP(!eGQ+|U(>Wl$02qSm2o|^Z({*`= zODlmA%X2KRrb|FF#2~~F5efdJh=6@rnq@hTWq+HwQZAP(l^ll{5I<|>sE2DZJwX&X z$H>4S=Gp0Ga)JdnC`6Pn#%BXaF1~x1f{-rt1XiRP%tE1%B7`bY1zHTulFE>z zqg{k2tqAFi#Imx?@+>bFs@-lO)dC{tc~+B3Xov_wI1KLUL(mjSpyEAAzi6r=%i{xe zQ?&^rrfwjK^ws|7ZhoF{^B9){cqjdcj4RVbL% z*{qs^;G~->&WfoNw#SxWUAMSLWkpd0B3r3$v0AMbvoC@ThAn0qG6XU%+zC-s?d@rp z-R=FwZWRxX1+~z!M9pPznaeS=ARsP_tz0AT&+UV2CV-GMwcF z2nYyD)x2(mrr04v)>AOLCXPMbqB9Ue*R(j+?llnBRL$c?;3z?0s3KZ{QQ-Kz9o|3< zDP0y-YPEOM$JvB`1fkc22YA&e6I=nXq6m8WJN=7r3!Wcv~(hbW5!&@@vBO%)~;Aqe4UKMXlBgMwA=lPqD1`veoc_!`y4quyhv{e zQQ=;ssj4JMnQ0rw^zM(Z(P*ED*9isb%fH9x^PQa~60&U2kNr(UxcGeLqlDXJARs>O z?N0E-dmc*|hULUCb*%p1vF!A_pJdWXyP)^S3(+w37{nNjr0vi~OM&s-2@p|(x zD|QRnML33c4TnC>^(y7?bow#qDx93!_cKgqbUheckC(&wYJatw4=?H6C^@1eX5sSP z!;#m$2`@^Z`;o~2ne>-KWEq`2(mMtjF^PxirXTh17z2bPfLg6a#N*@Rcn)JZkKrW< z$Vj3*ZQp#|bI&>TKtS!bHi0lsOfFFb+K2%eOh5zwwwOk5cC-=vFd8Kt0mS3@`1p7{ zSYsOF#|B&w;raxh@-J68>dXw<`-o7lNK z@%}0~Ns>V6FmUdZ$D`NTZe=DSB3e*RV^vX-l8eBp znK&~sfq;1@BO|YxiQwMcGA%9t|NpwXxF{qf9UB}dBqS{pZBMeYt*WY}aDQ-U85kS+!I+zFRGgid zCL$vD)3LCytMt#T78Din$*1hRm-pMd?!%v&nv~|WkKw9>3knI^p?kork++_KDkmpA zHa0{(Jp1CqprD)o|Nr~nzlex|_}8`e_V)VZ#(jKsr>CNXgL^P6EH*JPUQ|?eb#6*R zLhS79{O8F{Ie#otNlL7&r^m_4;Lp02WkYmYMc=@n(7T>tOES~c)s}QxS2Y>@?$b6W z8!Z+G(w1)h^53m{T%(P2V^~^3#`gXHKXBb6%QjW8EBx(Vh8kwre&+4onJH=Q zf1tqnLV@1|gkqkZ@Fps}ofNrzdOzy^3u@FusC_Ygq z!303U0RV*LDn8c3&3f17=_Y!I5-gV|N+c3BcZMekQB|FiG^Tc5`SK`s|$r4_gLUKiD}#XaLDU)wYCrm zv=>5-&xsJ)MdLM^e>8@7I#1g_MgJJk9>p9*>)<%j*a5^ z(SM`La2zy2RE>kj;iz*9ZlDo{?TVmo`6k2U^LYju0}Vm22ZBz7p+{$Jd zE-y(Ef+9fgu?Uj>=W&O zGR;Ya?B%7(Nx%RYi(1s z!7!=z*t8~68^Z~tEln(QoRt`{!_$=G?p#0SJ0h27Oly8UeHtunvMy6N41s_WfQ*)$G2aw4DKfMe%p478>N9M-Sf!?{*@2s2bq83GyjDOA6 zgi-1FUu%v!i_b-2keTS9>-&PVFwwHeIGz~@V&};Pv8QRGkj*?y@9zHnI>>ylW~O)z z<8ROl;-hxqjJVJ=RbYyR!SL(1ap9pzl)A~_m@Bk#tE&-bM8rTuKKt-cym@GYhjzP- z#USHso)J`4+jmCnpJ|#5rz4wc!+(xK#0|a`_^X|Q6T``>dbZ(=2w*WdCNDueLEPN5 z5k~g8#2{jC%|(#|LlhWDC6xt)l!vV?!Eqx5i4jEOVBZa~zC99Uj$x!MLO4}`Fa}`c z$U-%z;eZ<=w0*0|#0D@@dDSosHBVefP)s4NAG;!a+xi@B;C%x=7+I7V0DlkyC&(jx zbKMm|>mAr#9A119x<^uRNiZlK?i&}yY@UAs^xpT^q==wmMq=Ux?wR85Ot zI1n68i(zO)hH-!STVDe%?}-f3{k`!UCjJRp_r^l^h8a9Pd1EE^56=~)KfrRRnlX;{ zgUb1bjn(5Lho@I*C76yDS_4&7$I$ncppyQ07+I;N`yWov)8(|H1b=(2LZJ{f2hg=< z>7b&dS@!fK;12i*;RK;+@Xtyqc>0=+jbP5(C?P{B_dr{P%u>TckBAa^ZDq9a4AEzalu`~J0R$A|MZ_OVoxdZB{`o^&@2+rW f`M}Xp=m+3G>}2h^M4gLz00000NkvXXu0mjffrg$G delta 2592 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_77.png b/TMessagesProj/src/main/assets/emoji/0_77.png index c7e4d80a76ca17df3d0c4f3fbd45ae43239f15e3..97232dba050e2eef62da296fc604dda9bf51b550 100644 GIT binary patch delta 2026 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 delta 2390 zcmV-c390tc4&f4zB!AjaOjJcja7>_?vLzxS9zv%d92_!b=q4j0C?zFHKtU%cEsT+w zvcb_QBqSmqASEIqB_bkWZlQsJiX2BPCE`rYl*{H!(5VpLtbSStcVRUt)bs zQej?fvOrOV7&VG5iuu}~d1-Q($c<{7Uom}(zL}$}T4=4+ntyVeq^&VRf@NrLCP=c` z;pad$G}f7N)SGs7R7BgOeuI*xcYcJEYEg!Uim126(v)xErhnk9hw-t7w9nkfhhzW6 zn=xndW`@ruA|m$BtoGBf@ye$b6cpjAg!|vW3knG@UDZ!HDCV<{MTFkkp?mJbpH4+a zJvKG^+qyC>EPqBnKKtUt=(&_JV&?hRw(Y%`HfZxUF)>?FQTEogFjvW@x5=HTwJ~4b zEhs2RddEzS>!h%~El``ao`1rwlIH2_H&(qb7z_UV`B|X)L|3K!?$SC@t|LpnGiL4Y z@$vri-PD(GnW3veIy!f3YgU)CUjb zq>R$Jn?P=}p?6&E;?2jLcYBn)*4EdGWJQ8`d0>31l5kaZVpwQgT+6?y#)DrrYx+2P z@VRbDO-N?3fMcVLbf9ZQXgmPPlQ6Y)4XvS|rWkd70000%bW%=J03AU6{^u?J3mN?W zvE`P2K7anzQEBMs(~g6~XQrO{{^vV~{r+c!%W2TX;o$!9sq5R8(A@rYVGJ!VmshT?u8;t86}CINJHA3P+wJa!ruHu}SQZut*74s0JI3t>N9`O2i+yET&yx1# z@PBfp0bGpA7aTxa&3SYzK$S~iU2Z#oUk}AljR*lQOO17DY(uF-EI1a*uLgcC#)OhJ z#?j(Hsa>p8Vv~+Cp-O!+=|W$w8Zivr3#jQN`}r{|kggEMg-Gi4NerkOH2Y{mxkGyP zKz&>iSTcDFNrFR)~=ha6Kt(P)tDm zEU{oA2olhfEWRU0n^9|;F6bOGCtY5OVr<;a>9$lNSb!i|6bU<;w6;bw?wVy!KYD43 zqG`w?t3w|zHl!p=lps*q(V(e-Rtbr9Q?%djry~*cjYV@88>bKk8?+UAQcsX`M}Ik< zr*|Swr_&D#AOe}Fz^PQi4(&!DCc8m7_b%NbGQ95Lc^+x_T}Q}$xht!u0)Z4-O9f`D>47(*y9lXD7d#TXcjOSrXtcy0x}vI}YLByPlYxot@a+1O@hNP5|rq z9qJ=24PnvVodl^;v}bcQpW9pC^nV};zSj40`90oA2PBpxGFeKv41|3D?g8J zF#+jQm$ssdRXQdb-LwddYY!#w_fqT8P{D%+GK$!z0GKlNevY9%TTiTwP^o z3Vb#%*JZ3T7>rNN@qb>N_sg zlKe`*E2~|2HI1ft<{6%5k2&^GdzW^-<~Z5w^#qB5a(&Emcr2U=Kamh9AfC^{o|fn#eaMz_QT-F(@dt8VzB@6 z{eRGJt?XVCIO4HbEECUY%)(GVJlNNnT}1E449$J)@9Z14)}s~>*S zIS%ZfbGNkaj{{Hotaa_J6-Ori@D9Nss-K)3-%suTYt>s}_dK;fo&`x~pVhKxLLoBq z4-HjY7=D84i+{!9eo9f!PY!ohft{`Ml#<$?1o7l}=eG{~%3`bOr|O3KJ`fa(QBjPh zlyo{3pD7ex6bdt$R64DsiU8RAug(^)7JD13H}M1#fFP0ZiC_T7$xLBpX6EEPy|k28 zqGA*%et<^IPwzN*`o^)q=kraA%F@!dh$WOMG*`^z*p2wC45uaRQx29T3SQDt_6X&Z~HG> z=gpng>VJLo>%^!C2IQC)eIQEcbm!N{>EaZ;-6vv2@WWzjCZ?-C3+sSR6h-LvUGNOVEc# zaV&~DYjwr_`}g4c-tQ{h!@vi({Ox)8*-t&uxBuh)8?~V31UW^xV*mgE07*qo IM6N<$f>qU>!vFvP diff --git a/TMessagesProj/src/main/assets/emoji/0_771.png b/TMessagesProj/src/main/assets/emoji/0_771.png index 9a9cfd7f4cecd3378cfb499286f82e0eaffbd6c8..f48044ba277790c999cd5be3f986a2d8f21d279d 100644 GIT binary patch delta 1627 zcmV-h2Bi7J6YC6+BYyzcP)t-sM{rDcO*L&nC2vJ4a!@#BJ06~$nD_Vhlzw$(KPYBA zAZb7)u&}GNw6M6iwR1==Z$u}~&(M8RG_%_s*G;`|Nk%_5p!~D%b9L|eRkf;vP3c>y}Y^% z2nE5UhK7cJ+q{(CsC<@$Yto)`uz^Fui!7~e16-R61^@s68gx=lQvm!(e=K3;`U@4~ zoaMGHxY7I8Xn*PDajW>CTTJB2000FjNklDdEQ&E;lf<5)-YdNq zmt^<<|D(Nk20QU?kYK;<0a+gL%+Y(V7^FY`4>VhX|0-zJ>Yd&_((BY~>h%J(e*YNF zW^-gViyrTLjVr@6?!);fW}(-wUn8m8vtOqRB4+n%7k_u5VX=Q0A|PZ`X*!e9QOYFAjTU3bieo?x%i1$#R*cmIYJc4IBI` zF-jX+Gq7^sO0B{yJd}_WG!_cd6n7{pZAJ|{Zdeu}p=p{iGe`yy^!Ot~DydKa#HTcvx*$1O zOx(B`TiKFWl_@NMEUAE)v=`=u35bt)xqB%=3MtLu4Xi$Q1x%0v(ny!H<5V%pu z?Ar$DC}FQp{XjAadSN$&AdNfwC(A- zzK+Hbj$ce(F!r_LE_6>>4D0J<3%o)G@%5Ol#dvMHJZG#{_4Dh|0@p-nW}jP&}%YcT+FtV3-P^22{uatQIp4S+7~4Q2R>A&38xOLW-&TZg9 zs02f}Vd0uN{|Lbgzul@bG<%tyix>e&g50)kYJP->8G&V5L90(Ji1F@lYaJLlf zcz}k&Bcxr2LaI>J23**fqa^e}vVT(|6!3z!JDvKa53F^C6;i_ESnPP5(~jEwqj~XD zZ%1Ky43fCW(S>{3li!HT9R_7ETLJ>+f#FK(Z5t#f7*#r8xE8hN8@5L&qn@o8_``oa zb;CcQDE7U2z2NRCd7~aatWoN*d2;h`ouGO5aHA)K!JLKo;5;7>^hEF8U4Jvbd#me7 zGSIaBEXwCwO&h~dzwJIWFA_X-Z*<22gEQ8&#dv-kEkNNU;FwHMQY~>ay&nZxxY*4Wpo~h*9YJ&=3BKcg%1bIdU@cX-aYY0{RR5+g$qg1`LVmI+jzkkN4 z3B?K(FdZ5HqL2n>b5aajXIilV@I3mz6l1B-Q30%m>TeapFYnyk3I^H-19{};i)8qV Z;%|OsM_@#7^X>ou002ovPDHLkV1m<}2}b|` delta 2490 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 eO1DnDApQfToE}a7JO`x!0000 delta 2397 zcmV-j38MDA4CfM%BYy$WP)t-sM{rDGKP*=~GGaL#fK)wJH63tTTvIO{E?w4bLM1&d zA$?LaVm~NvL?&)SCxwNNcS|vJf3bB^K7^0GGG*ycTa9^3E>T)9bGmVJ0T8A zC=ZKTL~}+adQ2?1g=BV2HjraM$CYerKq0VsU58jUE?UvHgJGk9UYc=Efl@K2a8{&- zX1t7MGiL5xPWJZnOOEQSbXniZvu;8oqH0h`DjBQ0 z%QRTOqq4(NH6cNE%v?V#D;Ec^fLu6JvM^ucHfZzAnQok>vO-j*ja)c7aQ2pJNLirz zsf=wIH;_br)>W7Bpscx=p{pTBujT0L3J3*2YOQf)WPe45;4xXrJ~Jlo{ayctcBuEF>PSZ3DuKEV8q=*|W>z0000tbW%=J07W3|{$U9d=h7_Icjl!2yLMek z=ShabFMsF${*$Qg`~CeK&8*>eu#BbX?u(g`!PNKX`SR@7Ru=E^000LLNkl5DsVR4PcAV?@h#e%f((XGChGp@j z(;`Z!{iY_RbP^UJGbRlTTKj#iCaD2wHE<@GsJeaoxcued*n1EV5Ckyjax4%mdw8%xzfw!>SM??w(~$wA?P~7|OngkVur^n!Ac7h&b((LA3LHitukor%NT~ufyme41Wjou^q)q zCHk)fLg=YSa$6@AA#9i1+gFqSK8z;b8>@|MZ||Y&L(&$fBJI)$Wdk2ElcfJB0Xh;V z1UNZF*Ow$|b44hH-1f^;aTrxU1Q`f`hxZ>oAO@TU&`Kdvk+h0!k%5CWpWAPN~Z=P9!e7=Zw|_oU(;or@3= z&_~>-f{jxy3=VS<0wMr)E)2sc9YO#B`iP`eN;yPrJx52(C=EZ#!*6!Qb$)>$n9#GT zZaGAE6OMxo7!))tRf!%*n>m8Bi~_96AQ+sc;x>UnlDe|ZR<$HyF1?G&~leBqwH?42L@pSilYdSEqxH| z0D)?1ZtlFL9DZ{T?R;Pc4mVO7^^rJ%Akc=H00%b0?4p{LYWOnyIFsuV2KMQjMyYn1 z^_0s@5QI4%k5`W=zJFCHY#+~^KM}@m`1FbNH!eLNamCG|;;snRsuT);U(7uhqPUwo z?NUoJ8k;aal5z=3MR@FfbynUU8W#~Sa;Lw^%v9wopC02W5Rd7Le|v8KI6j{1f*c`} z%x^L?_3o<@Ji>gSVxBF%REwVujV~=`et*&Sba62wCBxoG^8Nca)@&L*wCME{g26>(m zHMzgG2A@6b>rmgmCn6SekJL8+9!`KN6Kgv=Eyt-8j0wC&26uK4W1_#Wr0--yLdsaV%CZ6S&1$dW`AaYfykgQ>n%&Ck8c>uhZP_o zfY%!?EX-_7^vve~anT#=Sp#0!>kR>XV0UOSbHkp~(F0uwfYH&BLaZ`3H#h(K?Be2l zW2OgAW1-Pe@930ue|IP|e8bHCWo~oR8Ug^wn_XVEhBkW&=ND(a3x%-Py1W(|1x;1< zTRxul-haIw(KWYe-9!ik36B6Mv^=-=pYx5va%gnQYXu9VQ&W)U=S=0->nGK_Wovjd z6beoKE$IEAXRvpE8R4KF$vd##lFJ=DRA0NU=8*MJcz#AyY(!w}WJkbPRbmvc51uKn zj{+gWBiW7E0s_P!0k3z&nuUWXU`*`qe#{iC%U0Kh@$1}yH3VT;KYjYNu>o&k>J|0oz~2IB!>0u P00000NkvXXu0mjf->P<~ diff --git a/TMessagesProj/src/main/assets/emoji/0_773.png b/TMessagesProj/src/main/assets/emoji/0_773.png index e7c0db884ce1322dd590fc17571fa804f4ebb5fc..dadca392011eb21f4c4867570b5e3fb93b4a968d 100644 GIT binary patch delta 1429 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 delta 2572 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 N002ovPDHLkV1kT-C{X|a delta 2342 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_777.png b/TMessagesProj/src/main/assets/emoji/0_777.png index fb9c64b358720b5c44c06c9d3f6457b5ee921794..cdc7df0b2583c4b5aa4e4c909d3b31237a4307ed 100644 GIT binary patch delta 1835 zcmV+`2h{k;6S)qMBYy!7P)t-sM{rEa#kO@xE_P8rcT6#dS2=e|Dr`b0h*~?6VnLN< zNt$m=pLJ4ZK`V@1J%CX#hF3IuPAqmwDQZ6-aYZ9N9}HG76<|0VNhuUC771@gF@;t@ zWjIhm2AnFa>J5p z83zNGgKC{}T*$VlWnp8=t&YE+iJqI3*~-23^Yh)-&8d4M$E97rh6#~h1FC>K$&)4J z&z)vLDOfiooW9hPv(tl%lV43nf1SL$&)uZQ<(|LYj;+gkn!2jQ*oCIZv)J~$;{Kbt z)vnX?Z;`X0zkk)F!`Z{@|F_=ys?P0PeWmZZLT`($;aYx700015bW%=J01F#FRf4K* z*Z%+i|J(on|NsC0|NsC0|Ns8~|EvH1|NsC0|NsC0|NsC0|NsA7|Nj5~|NsC0|NsC0 z|NsBI`Jey)|Nbxk|NqEp|NsC0|NFz_|NsC0|D>8CGk^U600n?aL_t(|0o0HMazil; z1#4!;^!^8}oCz}wbw9&fOZxdAAcVe1V?r5UFhTGqdBLU9W`~lJQ}m`lYGW71n%#|( z;*DCU)Q~aS=p$fKPP}Sh%37_?@UTH&f#X*VTKNOf#~twSnu7#w{2>;$rx4N>xbhd~ zpmOnkWq-qt1ms+IWctj2rAe&^P#jo>r6{G0QmT8_3Nt><%^Z1`KT1F`fRe?tB7CmB zZQ2|qhqwbQM@QvPCo#&Hv$Zy7FEyp>LK1%5hcCU1-#<#rbFoz%h{9XaOcGpal7i4k zNF$01j>+x!zW-D0fW1Fma_H^jsLpT^MQh$$5|Q22p{pz{lm$aAas{!7rvOz-A5bIe{}EwC zS6M46rLNY+{UYW7?m3iARn=8Pd)hU0S~<;M5EM(3`^%HXDh`#k-uaic$BGEe$Z+<> zHmTbVx*c?SCUAJ$fvY=TJJYAW! z1T$a}Ejo0*@y>hK(1AoZEf~SV%TvxB7a~`d7>?w<#fCOd8Wf+Mqw97HL_g zOnIt~5s{0l!Ho1se^y|&Da%Q)FUJ)KRShwNtDO=dHT zN}1vY6Qtiot^p|+Eao$Q3_}!_6Xui-*u!mUlHf*RNpUr5PofxIu8QHQ#%sq9{ZQ4owhf?*Py$ofp4vP8_Kyxt0o)loEh;LmbjMfBpBb zoAoHjhgKv>QYS(|o$6DJ!07Soku&sB>Xx6<-7Dj{(L~WCLl&qMpVVe27@q{WF+-M6 zFq&sRssAb|3nj;47=TWOkAIn&h7XpRlq#|kJF?qY?f(CdoYLGa;|mL3*u?>qqgU_W ze(rhu{&R`dZ50&)x$=kc{>P6|>4@vw^*2rJ*@YHIuV23Yu^?@9oDQ0*xM}}*B7mld zZAaz80_H9&Swtq|<_41LU_wrW6PhCDwk^49b5N3mBI2%<6wM%DPJdJA72WdsFX~L8 zJoOd^fpK;9Yj7q2EA^Zb#oVPQD=Q1qg-BCm@7Vxut};ju&w=FI4j1mOEXHgh5c@@Xtu0gnA#y#vo)Is*jLHi; zI!2B7Yi9|g&LP8@34ajl%kG1TNe80FXiK2`D{G~OI6wL)0uQOW_&#b-=d3pL4C~BG ztGnxxhtObB0GFDJ?<0v4MC%K=C-gJ^*_~}JxA{LNQXuCKFTRiDG>Ybd)+Xz~joEDT zS3W^dQG&X-NO9;%1F7{MV^7l*_v2B(9Hf!t!iQ0q!tO%Na3l<^n__X9+GDbYNDhyO Zu)m84Tkh~!qG134002ovPDHLkV1f);n9l$J delta 2495 zcmV;w2|)I_4#*RbBYy$}P)t-sM{rDDVsFE#T#b^NqHg}!`JFj&XGq*%_CY`S_+q_V+8W2v!` zOq->#@9^+dnD0P%&#Sx4qH8}xf!vQ}H{#^vu69Y|znSF1oY%yAm!PX#FBhYIK3${u z(Y$h)b2&F^^+X&CB?bbwnM&Tyh~d+Xq!IosVj8i^KgGG11XI5A`X~1kkE91$svdG*yY~anuz)g?j>ej@6 zSU>IJ))Oy!U3;yahIY@fk<`Fe{QmwG{bxc<`ur@d zDuMND--AN_>z`wHMfKICr`5w?q5PHI`N5yh#lp{3<=~USv%b3a{=KuTctvpl00%Tl zL_t(|Ue%W8QyfPchsCmMf&@Y$2@sM%0wW0p+kcX5pM5tuZO%F8K+ZYmoP%<9xPS8A zo>`8oE11Ri?VjCgW~l0?-uKttG?)G_C_w!0vr9`V>mM~XHa@DaEGhlwFAMTY>%UjM zKV|&JqmsX7Dg8SZhe<{)4UYXnQ)2PwzR1Lwr6WT%0 z(_=JR5XSqZxfCViqsHC^qt1D1(1{8#C=?!r!ua=GMSMT*GgO-;%r&DYr+X!-a z07b4cN>w_GF_=vDb_MO0o_3HRKq5I5;D0bamRD4&j2??U9q&!{W-U6MScfD5hh5Pq zzfJ!!q_A5&9Pa`PNEYlCs6<>?U3-tkGq}(d^gt)FQM7wNLDGzxxB1dth=qk9Vqu}H zD<1C+4%&?+vK#ZpOS{M75m+1-NUxgXc;4o6`F!y8xm+%rE2zk==&>sli!4s)wSQVY z1|E{}0&4U@-z5(yD&-YMyTVSh1O^I++3avQw0b>;AP52%*u}vMC_J7;mL;@ibEd5g z1_XM}m@^Ix$C;r00t!0=27GZuIWi9hiQ_t@vTk0FvBJ`zM?Q;!Mx$quX0eg=PGFsA zlMHRWort}8g7wPB2|O~|7X<=e?|Lom1WPUj74o~YL{#YY+T)Rb>K&*8(d5w1Lo%>7pcpJKkd5=PXHYF* zg!${yUjN<~N1KE>^X_Q9|7e3iieS@KIYkX?UjT)Ee|6$$p#R;5Ijh+I^?%RRfzIs> z94CEU%(Kg~iltsoz&BF;0|Nv7UHg(Ev-{@&(D^P*;AFa&c_w!m+#;8fpx6zsgW|*6 zuoQ)Pe;X-(`x@5bWIV|<$%S!MUAM>6_(u5ahY!CE?w=@j!$rnhY(E#s-=|Fm14rXXfh43C*JA>s%_<-Ym%(-Gl04UI(mb5@tbcraZH z)xPg;<>mb65Q`u=17w+#8W%^RGO(fX(edFPi=};dd{pJs zYcX74Y&RjxoLn{VUK%Iv!v+8PeU{gw!#!})X|=0dtTcBgYLXR#Z-BQF=rOoR& z-Nd6LDxPmXtU!j^mWuNi_9nDKvp5bOdLD9N(KGGkT{Y0>k1>DqWu$1?{8pwFa4@vM zvI0%QM|xtUHg1Rf9WRjK^7G9Xa{K(IjblhrBA@|OUN98E#D5=W{bgblcl?{pdGZb( z3V{LunkM0Q$j(lzPy??6dj|P}4;ZrVG-K(xe*Vx?-kx*#XA3ASQ3t)O+dO8p|tV93f05%&x z5Jc0Ss#eu-eN*SqEdjYkY|2?`Amt9K7-s%BKbnZH6c-mmB~?#<{eQGNF_vF;wju9!)$}yXrzmPI zF*Ox!4W~W>sb5xhc6Opg?jpqU>e$%CMDsa^^<8Fd?j;#`0%l=d^Ks8Dao~Mx*HiMd0AzAo0g`Diw-$PaYgZ zBU>6^#=Sb0A8S2lTiz~oyD7=gr&*hvq%>4vwBz&kVPu8sqY49CeZWjHC^oBpI9u^_ z(oMOM0ZAz9%uJtYvM{jSk%&&3`erngMpQr)p?_HMgR?J?!bxh&4c)#%%)GkxN~1B& z75;vhn6&n3V6td1eVi!sx6VC1b7TG>DXd#pBHbcatWb`-aAgh*2+>19nz29TiYv~J zVh$8m>s(?AIU-Y03d%51Yw+WgX_V#~HFsth4<_d*6NEuQ8;L0xtX43XC7>KXt5 diff --git a/TMessagesProj/src/main/assets/emoji/0_778.png b/TMessagesProj/src/main/assets/emoji/0_778.png index 4bc0aa3bacfdb534e6fc6dee00d92d4e6a37b6b5..598bb5702202bc624f7975905b09e062462e792d 100644 GIT binary patch delta 1715 zcmV;k22A;$62c9TBYyz%P)t-sM{rDKQAJTYGgmq+QaCJ7IWA8*E>1KkT1P!&P)2Q8 zPEju&TuDDrJv3HAIY%}wJ}xI86A&yP8Z;*%5C{oLDH&ilA$CP5e@ZNCJtR~w8$KZu zh*2<%Ry31bHj!8|f=@7+VL6>g3<1d@7=NP|K@mz=sTyU<1gNE#}ajp260Wv(tTrj((uQr@zy_(A}iR<)6RZkFLyc zkg~GO-h!dOve)*$+iZkinn8E0Dk}gO>|ODQveYuPkf!WW!L`y+yDRn|NsC0|Ns8~|NsC0|NsC0|NsC0 z|NsC0|NsC0|NsC0|NsC0|NpE1|NT@c|NsBJZpi=t|Ns1!H<5_zwU81u;oP zK~#7F)R9$UL?H|Si)%=b?fsA1z`EO4=eaPkpZ|dn;(wdfQfXtYHO49V$$Dpf2yyOw z3f>we-V*5dM8TaX(KY$Q9A;Z^E9S`p=W6b zpAp*_wSP83D0}vj(W$qsge?egl?cekb!2MPH@}-!cd3;9a0?*InJ1N)(*Gze z3uU*JAc$7(HC1F1ENW&!1{uTu|81{#t(Rh1X^Y{wXF)SSD6NbYZB;^5RcGPt;rvY` zi%pF{h?zh!QUcUgZQVjb2y3evh{Y&kwZs4In19(h=P78VlmY9nV5XjcsElXtV(hvu zM(5yYPzWrmdXfu*iP#+uhwiTqPy|g^Zv$EE>PmWche$fa#K@dO44S)xCoih{J)+j^ z$f8f1$_+ja$9!s;S-tI%`L43Wv1&^6WyOafieox!8XJj#n2isuT_uT~I&ywB2Xe?q z2!HJu90yU>pW_4kg^2#dr;{H{V0HOCdPa!*k8#8v2=BwWzicj7e|V{L*UQ)K^{QP) zjJo*n`w|F!yMDcwMiTXpO<6akf5tAGINdQEnzny1 zQF>rL7KfI2LSG+8bYlDM@jWIR{`zcjZhw9}dJTk8v#~&wflnZA)~cW9NB=_Lz}jCw z?~m`A+D4hNK)w{Jw1ItpzkUDx=XuT}yNie0^Ze}xt`P^(s$#TD7Diajp6Gkue~*3` zoH*$Fz9Vw1tu@8?(2~L`N;BO>m*;9;I-JBj|CO+Ee1LySD-3z(B7}Fn!?3~%NPl8* zFhGod_`VcEn85DE=vX^o^uTbQwFKf#g8y6yssFce2-YZNq&olr1e3C&$o(X4J zycR?Y3C=EZ9CkJ#FVC#e#4fsk^t?$qaD&1i#11A9$6F83hn2}j*lcs5gH76Qx5GWC0uO>Kf@QR}~Nr>%Ajw#D9ERnIxnlpFUh=GYCnj5gsP&#BwXyAPU56suF6o zW1I#hEhg9`eH4kop2@RTDmc&SL>pU7E*zIa8l7AOY$M82)`qOp&)SW;A?L}2ZMVE{e>dMn&}_&jhw9nmkX-Tzf#Ys}4~qzPNHLnMn<6=< zjC09)ELlfk-`#bA9t#YI41b4;e*6uaqH<<71|sZlKdy5U0f>P)XSB(M_rHEUiOyQg znj2y<-7Qawd5MBK1hRHcZ@&Ne|9MlK4Ga=w!@@1+w_}Jx0r{0e0XcyBKmJ}a0h5FP z#3Ks5ym2>-p)(K}YE_d-?-2^3gbFo{(cz|DS#mUlXH>y|oBjyCdVeqTC=gNst=Bgw zwu}aAE0^C97XSVFrK&wzstrV7$T#fC8Y)riJ0qE|zh{4AI*W)0fb#VRbQy}ITVMMn z8RXypoDJhX9U*a{0upbpRV)HkUwk@`?f(zM_}hh0EgoTY?KQg9SZ%FR=iYEes~ zk%!8;sO93^9|!|+U}D$Cx1N1P+0xA9<>&A4@OVcCnQH;Jk{Gd$RYy8BVM#rVmcFF3 zzCS!cw9DS4v46iRD=DS3y>)kgq^!$`jgzXo%v@q=o29Xqo~Vb9n0b7KiHnkMa&%j2 zj);@FUvQ~QM_yc3Ve0DTc7VJ;QldXeeNtnkK4-0Ga5GGym0SI#qL?SEUI?O>(&HE8l2Jd;7|Of1|$JP9@v_|NsC0{{R20|NsC0|M~y_|NsC0)&Kwh|NsC0 z|NsC0|C3Dt34iYY|NsC0{r~^}|NsC0|NsC0|NsAw!cwF<{r_O#=q|edyZ`^${{D>6 zhVuXa6uSTa{{Pbd|NsC0|H}XW|NsC0|NsC0|NsC0|Nj5}|L~Pskn8{b|Nj5|{q^jD zz6>@100wSS9BkSvpI0!XE7>d^$^Yg%hx zFvet1tA7)tlQ3>RB#-Db|1{4Yw;hinr0_EmRWQ#TB!Gd8T}?bE!}GE=*t#&!78Fo0 zIOk1rbQ5B!5p}f_$o~rxs-R?u(V1o2y&!hp8p;INAW6vp7!VMQixgoybP~mE;ae>w z0%A@pKsHQ}Lj$QE%{(i|a})7V3QHv+YqFw;Wq*|n1~E>uGocYW2q_HERw9y12?yQ* z27(93k};6F2_zP6@<6XKwF}#vO@IQxLl_hSodik1)izlXhuWUgjPuV7577f%#H7;# zf^k})D4>Fp#PkQ@XrhRVMM8{0$RYwLA__@bG8|1%IIN9NoD+896#}3_cyxsgz0|d? ze}53rELQ_YSTKeYNfWd5>*AxIZkENzLZ|{?>`J zk|71(Jr}4^1lQX>+b!wk$|Su4m0WK3Gf2L8f7me>Wbg`AzbXnBK|loB=v}!`8-Z*d z9MVA;;{a)AXAF-P{ZEkLqFs$bYkS7h$i&gStYrxUy;c833)^WA4H$A9ITd znbmb;ItXYJL9dPB#64Q8o&*^#wY-;JU(D>ofC%$ zfl(Jxojea{IB%(}%nY7M?t-OqWuwXoZH1^EMETHJYumx@9k>I#))a#=imL3jvwsJ6 zcW$tzm}*Ws_lr?4I5fHaeW%rS7OQ|t-ZEw<46-18q`}3m6Q7@1R_7c7U=>Bk7RV@y z=62LO)f}~Jm0lD;Bx_D8qES&nKvP(S;fPLRM2I1wpunKXsZC7=Cdm?#w3~=m$5jEllS?+wl;j?%+vHMUlC^7#HNnV(LqN2f$k+T$8b6#T zc=`Yk8}Js9)#U+jtH^gd3H`~%t7nSz2YpQ!0KmVN2vOT$mv+W*s})i0)O0^nFTORt^Ms>j8zjN01`s1)?{}};Z{>IX`Zq)fMa^? zZ!WCcG!q&Cj31aQf7dGTvpcB<T~53BYjAiEs%Vk3e ztlsOSO@J|v=i&KD0n!hK(}-Iy$e9WuSV#J6lmFJ*WNx@@-q9)$t5ARY%`(3x$QLp% zB#yOJrV<=9&e0ZsRDT6xaZN266a{Gh`Wk+J%fIY*r)|_@Qsu%q3Pc-cVYIj{fWJ8k z;!_C&pjb}}kN#>n_1xLoLt&=yA_iwE>gvn}pg-z+0L{6sYiMP0JwoH*5c+D z!kKpCEKg4t4IXF_Ev-zw2;BRsFv_Do%mV~3dO-5|!E@sBz~g~{XLNF5{osv*olohM zbuk_~gsf)>dw&Vqxf9M4^s>z}1|9-{4}L7*SBs^3%0`vf1E6wn>I7g%Clo-V9r=_1 zAQ1NdN#cO~i78v;BmcZOgEP{szy>Qlwj_~hoKKKok`!wi7Be!10Jq`J<+1aPLCytb p8GuJG;+edhgz>9p+2-l~3%gza#B<@OXaE2J07*qoL z>$yQA84@BF4~C_}fS|#6m$k#$=f2S0nz_}b$mgZO+mf=ByyE`D z>i?_H?~JR;q{iB$!`V-3i?`nUp~2Q_i?EZf$KorX=l}o!NOV$8QveGiLUxhF-LYJK z|Nrd&|NsC0|9}7g|NsC0|NsC0|NsC0|NsC0|NsC0|NqYax9p_;{6s1L|NsBRZvX%P z|NsB1fg_N6`~x#yLYE(^ai00yp2R+i_eA?H#e zY>PMTqWR-v8}xSN8QgAio>RXuerdHy^nW)>)qrFYEbnaMdurm|Dr>rx5}W zoV8wyDGIN}8%ZINvB_UXiI=6$Ct^YX=bRNO#mZX;x$cZn;z-@Y7Z3s#6j1uav4y6Mrv408`NUA^wt}Y9Mxg4uKScEA*KD zKqw9Kz=V^;V{ROADd(qD?D+>FBT-CAWC}BWP#1{^2pDvC{)p~aTv8x%g;|WB;8&u= zx2me>r@%6PqcX4(_tQiOST}X7Yx*J7O%7x5Yv}PSHf9)nRt+7Ms^a(_Rk zLy?srhdh^#;@02@@R{d<5bSYQ!_I>R=0R2aQ1#)qja`_gdkte7rrPwFk*%UFQahT~iq<<)c8PGWC zUp-NX{hmCcs=CZYF{?H-nnEb)K=)v4V)Z`wa1JSx%+_ls z#7Ln~(g^OMWORz^=^A1jRey6Q1u_Deg#jLFW~b_vgye!~d)Tzg8O3N1mm&tv-TnF4 zF$IhguaR`VYAa0foT6e5`Tm@A4uyCM7tDOUOuS1jARt7jtiRJ7Jd#gds!BRDiI%=pMn86fx>!0aK9l%KC>T&@l9HC6 zPh5~%G$1x*)?R9_Xmq$;Yj-I?mbcL3eU!Rxa&$^nkz;0ThJT5VUp63S~jiclj|K{!e{FEC)^Z(2~8p{#v)eN>q8KvSfzk!@N>Jzb;sb7p9$Yd^5N#$SQC z(!#MqMQ1)vimjZF6EAwku%CrwO*LueT~Aob$;r2h5P!j{gE@Ne9ouu#0000obW%=J z0Muro{3b^J3lufp{{B(@{{H=wKfr2y{P6ewY`^u>rq7l8{*1%0!R)G^;OP41*tbri zOSu352A4@hK~#8N)t2W|8%Z99kpKyaY|?=Z%Q~;u-rbv+gL2L}i=1<|z4y1@+oLh& z1B}@Fc7G35qiL%8nYVwxp6VI+zhK1U@r?Y>0*}kNFf-?HIOb*+oLvjxI{4>kMocrf={1My^=kq0=K?u4%-1k=^aXr)Eb&%v;_fHPphldz+-67|*48slx z$Rvx6!wm}zHl5Eg%x%DcY4?P{W)J+jo{_=L`hVOogfJCY^V8|HkC09~`qp%&+hucX z2#N>v6oCNC27GB}zYy-jP#~9!vT0a)SQ6r3fzQ!rw=NuR`h3wGByxaQEFL%l{i-py z;bVQWBIhj2CK5nkVoA~q_M6JFiKuK!qYGA)&5+ev7<{Z8g?G?)C0=)0W&<=M3a}^z z8Gjy3>Jh~q83gQm;yU!n0k%bP6sL*;Jdp_fg9uPqRt}8XD^Q96t8*L`=J_zisG_b5 z571;*W=DtnDOiPqAG!c-5A;}|Fc{S*OK7NFpRiIbC{6zn0LfFKVwEwlX; zA#{!5s34`cS~?%JNKiscPmXi6H(GiD0nZ*}m;aZM0dC&Sq{Kl(`UQ!LAg`YE%|EwSLpgH8b@2 z4PwC2u5V{@nP#eSway8-f;woIVvvbOMTRQZo6StKU9Y!EF{EI*gE9TRd@gcAMiFh_ z_64<&(;4o(e2_|gKPW?i7<{7K5Pwta-|^pdE|rN0F56Q~h!g~dT0c1d`{3{T4FZsU z@SXGe!NJW<0_D^Sso!ijxc4_rNvUWmN1opPvBUW`>ME^sVM^6#ZP|8rdZ5st0KECG z^1Q@DgbT*loMJ@LP)$3QBT7Ux-*q5K6oqPXd{6>>7z&-HHK)B|f>vmq`G29{1rcdP z)l!iCt?Pe95a?gkxKfn2c6eP^k?R6@et}-0Opd^e+VKzBJL?N<>IU}D=^K<4F z|NV{AZYi1|LW0vwRYlwZQP392GF}z)J2S-K`TSa-62RfA!hb+J$;6Mv{2xR$ z;L1<^I$-OFq;y1J2uPx*B8z5h?@K7myLV7{>>LY=M52o(IwFkX(ZKa`r6O*-FFPQAdYUg5r#{$B zpPgS_+P_d}<(|u>)qnX}lKaC>k76-jbUsyv`PE-u?CfT<}I4u(zZz~v7A@=*T*-I=W{~3#TA_EK%#9~QI+B>SAHHac_ z938SYbXWQ>r!*c~fQJ+X}8OBhVS z+S-<}SG&HxMt?;cjbi0!^7`7SCf7jR|8@7}>7P$*%U9DVB_k zPD(L$dNw{e{CFwGp-66xSE|IZS6xX$vE|Q_pL@wZDMigc{%A2?PeS4M$NX4ArHTvM zOB8+>esXcVyOZ}P$6r6HC}mfMD%qi-e_0Hf7()+P!RwKKyRz~?@n02Y7p6l9}qsa$7=~IUeGE;qbowC!e$KchX^=m)%%nKw$rVp;#uHUHK#|L8gY!+$K1RR-621l@)R({Tf$ zW(jOG0(wCN>V*S_O9ZcZ6uX2OT_yn5vMJJd-e|Dpu{`lA233I5<(8%oFj)l2{F zU;nKH|KvmqIl%w?%K!VX(8Z7K)p-B*h5y$S|Nhti{Jj76cK`Nh|Huvh>_P}Bv;X*% zBU#osYTEzqPJe)dhxVoupr)LMm9SoMtMuZETv>G2*Qe;NE&s?k|F$6hu^IloF#OCY z|KctQGL#pw!#d=f^$&x+uYvB>&qm*?$Mc zr7ZEG65@;s@z*@}{uC$)?of?b+sfis{-5E` z{*JHw=5YPA)bOu{?5^|2i6)!?00u=#L_t(|UcA$1Z<|mQfML|yvXMm;kb~uVJNXZn zy}kDy*?V@czu$8V1cXyHRi!>SAILSY57(IbXEgPHB|LvIVImo4a=9GC#FKbgY|j&W zc#8@_H=Iw=*a6_zcJMtg}r2be->bNzWw zYu7wUtCp3bE9Mz6S!cwveGqb*vuzNRIT^M)i%7o*)6MaKg4b|8`Yp-bI{W;gN5 z+Yn2X8e6E=D){SB=ob~&|!|A(J0+gXpiOi6J z!dbm#gP;OhkMsWG(O&dT69(eAk3u>{Q5DlPE0NvIVPRm4qU~z=>{*|4Fv0ba`9&Af zaeo#Hd z{U|PLo+asi&2AUyf}l&JzJ!M{oI$fbS`6wzLtepcuvBy-1W6@?)I9?zd7KHFc?+aQ zNP7Z1auDCXjVl6+qzxbul<=w=aqDeF+J89L0l!a2zE44tiA+cb8lL)d3Ia7~yGZ8_ z3fZ6EKI79thleKctY9G5GSgPG}QSm4ai)7!$f`} zk>-U{RaO1QJ?h+t0&oU2G?ph>v|6pQ<+A_9GI{>tT1AFzjM4oI#u~1`J5>0c9DkmE z5cqV0^6kTY99?2THHJMlu)&uenf?*(e+bjv~hWXd-YsnMM8aYvSf?aU7~sVtxa$ zAz@AW{eBokQ51Lsy!{|SBN*QtA4j(9<_k$QG;tvT!`==CSj*te-jP%7mM8D#xOYmv zA`Y8(64`1ShMq|1P2R+M#(z0QJj{f_hvjOb{;2n&emQV6Vj7b`643_*jW|E{>iG6# zLx}Um=9cKxk7rF}xP159?f&C!iSx_Y;zXjzWWU`{PAe-D#QWv|LYV-T6e zYus7cIs};2lGnG5-&nH*h|5dQsK~VIM{dSK8dNM?>y~{ROC%Fm-&*!*jVJL)<24K(UYY1|VW6`;< z=u^_eB+6LB073cPbIh; zesN;}i9v)Q7!n$QAjeQUQRbnFQG}roDxPW)&NOfp3cqH4B7YiPjG_%7RNQSSh;WqU z0HiRba4dRNqw+asM;keYXDAwyYTKGJMzEk`{8$_sN6I@!aE|<$0q=1dU-SI_? zW=|RlA(QiOoLsK}DR3jcG^)ao2$eDl5EXtd(BLdAqL7lADgZ)(Deiv$XxXayq6iTx zItQ*lE1}v&hku{P>{ewFC}ecFUR7we8^3rm#4tS~LZQQ4xc>OU3K-&-F&~K(K)}cx z)q1~LGwy%u5&Q13SrrO$#0x2k9)ONvR(?08(ShRkbbKELx)1mN=_$Wq8trbaS!J5d zPPg4M|KJ0K1|Qm64-YLovN!(tbB4zM^a;j4tq4^>ln*ROng9R*07*qoM6N<$f^0YU Ag8%>k delta 1991 zcmV;&2RQhn5Y-QmB!5s)OjJcja7@f~7V(7xUvqKAY!1h12)%qa!+I&udKl7yBKMmQ z!DkA@YYoR~1!0qv$ZQEsugdC$4e+BRHpu(ve+M|Q+~|c7&2tgYat=Dv|MZ?1IMM$$ z%Jvh8$HQp})_4&@#^>gY8|Huk?3fPZj|*on0o{fOhD!yOS$_wkWeFUz{&qbB*n9=k zaRV;F|Mj~m3Zw8k)Bnf#|LLwN$CDrB`lkQT+ ze-Zfm&2gHLFNh>*{OM4Xl4Z81o54O?lJql`I9Wc!_OdJ=5q#Nf=<|}q9}SR)?!gUzo z5duZfyekfb4})A^dI|Cd1t$wBWq}&}Ac^#r@{UAj3k%EXR?D_+B`S_2f(2nHw~OdP z!H8D0NRGA8MX>D8H%Q0nw@RR2L;Y@4i9_SJ|9@mC=nC~2G~V8WMwgrx;>_}`(n@Q{ zAkmk`+jRx&N*Qi%PR=%(Sx%i&kU-TbeV~FnZfDbDNjgit3XL4-d?;yrau2QprJQrr zPG2RSTmHj=y3WzDgSGsf%Uuv&C7zsy-FxR5V~*7zhtd>W48lEd>v!9Ioer_~fCcpk z#DB&Z@?bhf0z(*oXsibHYE*(>11xw0W03K2boS1e5HU{=4^OYFGkjRZ+l*P;ZhkzJ z^rqu$1AaDRuFt6&aTu;vO)}onNi#WTdV1O_7ZC*_1P$?mF}L$E=X1)4GKz}u|KI!W zE^8WNC!K!kvjmB<&%D1Mi!+#5uB?h`cYnUwZ2lwz8wJN;-o=NqYteJP+4pSbO*6d& z0$HTEP`qcp2_2E*SU4F9)=*vt6uKgcs?!~#khwo6Z0NwofH+)?yN)V~ik^5et%P5X zm+!HsH;6t&+_~?=v5!xn8Vg|>x)-lrem>%@sJ%pSY@-L^++VMkOaB$7^HY}oa(}({ z=OKEc#BuaeAgDGK6S-xkTW&lAjP0U$T&t9;87A|V_XcfmX zJ~%Al3BVLlL4ebtsC`NmpNL}iH-7_@9Ebn~GXz0ATR~CXDFmj7P5m_nrs+(BgDD)l z47&MFalsUDIO;Iqbxch~p3?YBT~^Fpj9{oXPzX^7tPoJD3Fs#jNf+zRGId~DiYhuZ zKPN*!(fEQe@Q)lT;zq_|iIQOQadp5!$lcAjmEjD>0BAa=7W+a+evX zqRkihQNG10A&%#@aL3gZlk|+ikNXb|)mI0V%=);ccBrxqhcUT_19YxCn(-?aa8B~vK_x4N-I@&y z0GoRUNAKn)bs)y+zJDWAZczsdqKLSy6b^0~p-p;}NwW#XK?iaW$!druD7M|D*l@{; zRWS@h(=I7kq}th`XOUbv4N_m3!=b6iDLVeE_irBz#GnpM!+!yKaez!7jx@+BT19-r z5TIxpO*kMxh|6DaMGkRNWkFyeL}(2Da3n~5yP{DC!2a^=pC7Ccgi2uH2z5bd_3hg) zn9I<3h=UyE@@-~;Cq;32bEh6NgkB$ z;d5dpSIk4hDM06oxlDoRPtVUjpPilm%Lnevajx{WTK!te9cPXT|Mi!G0^!3+|A${N Z{sPJ!RDPvt^c4UA002ovPDHLkV1mfX*3AF_ diff --git a/TMessagesProj/src/main/assets/emoji/0_780.png b/TMessagesProj/src/main/assets/emoji/0_780.png index 86da784f49ad3c3dd338273284428d45424f3c80..52be148e0ba1e2496c8e5501cab81d79d55fdc9e 100644 GIT binary patch delta 2638 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 delta 2094 zcmV+}2+{Y~6uS_RB!6E}OjJcja7-yBD>pDNDkLBgDk?NEFdrNoCnF;V1O*Td4Hp#^AQlfZ zB_1pv7)3HGLoX;fC?O{r5=}TUNi{A$EG922D^WZ&RzWvgMt?eBOF(E?RC#JOy33f0ia9R~y^8WX~}u7gqy@bU4vix9Y(TO}G3AQlden7*X5 zzO~Ncq_V-Kv%PbBg`}>^gN(7Pz0O%%U3q+ko~gB%p{<04iBevEh>Me4YmGijifU_a zR&JgzJ6K$6gnxsMx98;IK4z&rPl;)CvtD_#QDCb-QKUIivp#OXL3++IR>DJo+%Q|y zP?GC@l(#Hb%rRfzGiB&AX6;&__cmqKMn`QmXz~^_esht?9zK~jYxg2YvLrvCIePFz za_b~QtU#0Y<=9Fd0001WbW%=J01iZ3age;ywg3PB>VKdAATs{{|NsC0|NsC0|NsC0 z|NsC0|NrIx|NsC0|NsC0|NsC0|NqYa|NsC0==4;i{QuzYFTDTCb^rgvzx&fzp!fg& zixmI;$o&8R|NsC0|NsB^|NsC0|M>s^|NsC0{*eFu%Kiyu1*8A~1{O&~K~#7F&DMi+ zbX&fM@qg#L)I01xNM7^av2EMRKR7InQ5f5H@z{vdyZ6HHD5*N=>bx_hdAij4)Ybz3 z6X{02xBr&VQ-P{I(SJ%v$(+P-&F6GDU%@js7njZJX(Fz5$Zq&3#!c0*=lnFxa=S5N zGWBXi$T3HrR*rtJ-Uu-%W&uJ8&-snvcFO6*cz?Pw3juLlg8&!+f=AkE#JC@Ing%sO zfdBv)cmSyTgYoomJgXy@QRe|d2!#S*Cz6?4^QRoeq~W7OwW$HnTq7JGh5=}2u!Tfe z_YP+u)q1Qz3t%Tkd$cVix|Lw^Y6e0@4GKWu1VN7!o?hVTF|N*_q|h3Mc~PqfR??w%PVaax5S;?bO1?*f{K&-#aFhmz`eSdKI zB0d!Wl~LWe|17I4RWPYrKz+ z;L~98QL}Jog||8VtS+2>@mFIhwz|3!mxA{f{nBVPuB?twAMR-|4!AXd_q=@!Am$lo zowtA~2ZTY1rmPyz|6>QeM}Ike&w#h<7X=W^Jr(E8h-3j+ge=u7zpC&7^-JH+fZo}D znSsE(4p_&>A;(CL0GZV5%C9TPH)aiBY`p(FfMZ^Eu-DW(<(wnroaOp><<|umJC1t; z$!RWeY&>wmR9#A?6eah>?fhi{c>7&iYVVnVDzLtA8}I&aH>P3$B7bmiw+n##aK-vn z-%pqO*nQg;5pTOizXcL7z_m?%1%UBuM!+Qpb=!6)5(*Vr@oInF3j{Y^R09bnE zip?Tm?cQHM@A_TmF@JEs*kum!w)0L1Ps20&cWrf$58?7nu9<;h?EU)ansgQa<6WLh zY*`ZWI4IuH{6EP+b1#ZeLIp!uT35^PLxFS!??MtPP1g zyRc)22?_v^zjTer!Rq?%oNKWPfMGoV!`eZC;*QLvasrexT;VQu;2k{oD7K~m&U{?2 z%a6LraxI}?)UaIO#9%DWPe+yOa|oQfF7{Qv*} diff --git a/TMessagesProj/src/main/assets/emoji/0_781.png b/TMessagesProj/src/main/assets/emoji/0_781.png index 3898a9782e1bfbb3e7b910311ba5df15a6d4247d..9bd385f32424b09c51216ecc21db84e99f97d151 100644 GIT binary patch delta 2395 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 P00000NkvXXu0mjf!LIx? diff --git a/TMessagesProj/src/main/assets/emoji/0_783.png b/TMessagesProj/src/main/assets/emoji/0_783.png index 6143364ad591612fe853b6baa0d0ea816a0842a8..42f4227744d10a9cae844d762266035934d97c03 100644 GIT binary patch delta 2467 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_785.png b/TMessagesProj/src/main/assets/emoji/0_785.png index 18d7aecc7764f5416f0fe95469c0aafa9e3de276..16f951e19410053b193c4c41fb121c7c89a94a39 100644 GIT binary patch delta 2164 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_786.png b/TMessagesProj/src/main/assets/emoji/0_786.png index d4f712ad3715c5fc9004adad1aea1b420a1b1957..891cd226f9ca0ab65914ef5afdbf832600fdef57 100644 GIT binary patch delta 2592 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 FV1gQ{;s^i$ delta 2570 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_789.png b/TMessagesProj/src/main/assets/emoji/0_789.png index 654156f5455c5dab7a7d5180d1a2fe5335f615a8..14ba5e04b363d74e5832f518f0ed3421d2ff79f0 100644 GIT binary patch delta 2395 zcmV-h38eO;6y_3;B!AIROjJcja7F~g@uoIOEGkRv2{{Dgpa*4W$8~_jd@EhQCe?W@h-8#tNo718T{amzAr49? z4~tqvxP@ePOg6`rY>;C?Yd|5qjApQTU58jUE?UvHgJGk9UYc=Efl@K2a8{&-X1|VT z#FA=jLoRMYBY$&7CZBg!GiK*7UfP>xPWJZnOOEQSbXniZvwBP{qH0h`DjBQ0%QRTO zqq4(NH6cNE%v?V#D;Ec^fLu6JvY4T(F>1Q2n9fDt#M^!MSq6iI&k(rGbZok)I)Z^eRg`O zeoO7ONOm&1Hy|eva`2T1q@{X001|1QchCRv2xewxhA=ZTLvdzy|Jr?CS=09HNu+ka&2?f)_IZA~ z&wW9@^G{H9jiBoP6Hue5?`^I_YHsXMD1RQH?0=|x8?d?NkX*LF+q%Z8nx7+7)dl8G z;Pq85ySc9ZXCUn{251u~Dc}t7!e#dLW>B zAlS#o^ojZ(A@rK{20USdQY6s;st1C8GVudGdi5?_f@AanTSemS1x-$x%?+}7C@`op zKd6gn(g4)%&@rMtQRDdqGCY_`0J1{;jn{g2g9@F74{QejjbAPrg-B-euy-=7t*>{r|N8{4FPCbJIq7-+zPS%R2 zry@ajtev^v9-LT>xzsTho^8-nzBz{C5G9}xpiJ!qv6$?)4Qxu+?{JFO%jbRa-{Ly2jK}eYj;^*hS+v|G%qY8B)xaREK(QA9vaJn(9UxE* zjg1|5l*4cCqn!`Tz~NR(y*3;p5CqyV5#Yc|n4DCjvKoHOK2B#lg@Jwgre3O@MlIzu z5d>k1#bT9Xl5Z9YTYo3A7f*z-8$N@h1fy5Whn+E#sF*X1H7kX}-!Mn;cw5apC%@k!(7h z1;p)HR6l5I>FXaFFle<}Z$*VK{e3NM58%5;BZ4NNpNZQZC=Z}~c6N4XeTe5NQIiMj z>+spbzP9SS_eI1~_EGgMfQPf7^6dKVZqrFJ31b3p;i27K#F*{xYkRWM^a&9@KfXE4 zHUub_Gnw`L!hb@~dHnPQ*2>9o6I|_<%Vl8qcWxIBHueUaUff8iZs`X=X4GP_>~2P* z3m1{d>gDBXET;eSPLQ`KyW&=u(-Im9PPPWU0sbV<(HR%fq%%LFB?rGXOC|g%ZFtkAi(r= zD8IP8IorLE1;k}fw0j+Rq3P)$zz6mQm(sWFIc?q0g#ehDnaW4Y^Yilyug@j#`2M08M9BRxH8M?)=5&dCy`#G;LW~527!&$_GuK z&U)H!Mt^k9k6K0%0zpDk01B?mum9&_Grtm?*_yV1g_*4_Nb_^L{Oiq=>fMSZG#U&B zxBeFNe%L+Kv#^42P%qdU*l5aT4n^FK<^z1_}- zFMX* z&xzQ^eb>i=v2{=3;os2F&#`k);NjxVxoz6i%Gbqx)4z1w%zuQuc~8frW4nG(#jIdD zof_N9gWJo5$f#qjZbXgLaA(y%_xbp;udRfgf0LY`hme-XwSLIdzv}Gk=I7_{@bC8b z_T%H@;NjrZ)YIMF-QKm2)xvn#!Km=(rTO~#(3)}W3`FpdB}}q&d$!;t%l>im%_ut;?=~?ww%R>U7c}1%d=_h=ikMqh~wMR z-psMH@qMq4NyDjNzQDeb=~JZdYMr8P?OZe&o*7?Wc)Nkl)Hd0Mrnowm2P+V`<}>pNFLF0^q+=);`r%%hg5 z$!nP0>ffBZk8wl=#=D)hkx=jE806TP2PE!CU7w7&J{tCk8{)gu!vQpyQWJPK{_%!Lm?C{Zh zvU;B7nZEA+mek<1S>T`Z$MN6&gURQ7^T*lq@X@x!!2kdUoJmAMRCr$1mgRRF*%^l; zOOa$Nw#?qxF~xQmyWQQk!y{&9W(G4ev%}2Uwts(S-9;;Qqp^~CAN}sV zbKlX0{|7`D8ASi9;9^_vwZ1D1_xgI<8h>2S*n35%`PVlzx*L717k|vqdV{I|9Z)iF ztmR7Yk4SnOlu)l!f;^X*6YIo9aHoj8cjp* zd4CMoit`ikNo55zK*Kq5T$@)aC-VWFh5@Qh@%;Jx{QUhh=cBFoyGB!7jmhVqb3h>n zBhcyQb=S{W7f~PcWyQEZFNdq=zoFwO0=i=FSs|FP#lY@vd;$til{S2%c%!lQOz4KS=pRqfmTGLfh`^AU0gSs&=ZiySx5aJ}?1gP%4iHI zmPe1Kr&j|3e|#dq{AVQGA{I-lD%g?7VgaX9Hajbm$>0EwtpuV~|8zb!A)ojh@idFY z5+1LvvI3$`#x1^*%Ox{_gh9sQTwJt0oZijLKO09zAca^etvr}pa&WBL9-BA!{kwkG z6Nblt0j6XlqqbXOpS=Z83=N4TQh#a17;O+V=HFO389&+D+FDv!`h&Htt&{QblclBo z(ZWb!q@{(=jHIJt#~hB2zk2oRpVfG^Ep$-f9)35{GQg|jRqR*SH(tFP--GX8{x4Qm zmRFXS)|RqDlf%I%y2X+@QRRibliym~-wb&pW7+IjM8RNWP=vBs?^x*V2!BOUrom=D zf2bV<73rVe-+vMEhDQ(H&TT9HbVNqS4(7H;3Ize9Fi~WWSXxbSRlC2DSs1ZyZ!gcS zjfRb!BjVX!hR-4WNSLM^4oX0vVwlS+DSR878KXY9JvTSEl)(xLh1aVvhCOTWc_oBf zX$MWvG%aY6)K%Ri+6@>-P=7VLwzR(*QF)BpdwW?$P@jd*c@Iud6ow%L*&^YIs%}*a zC>D&tU}!V&1Pe!&_cm7cMkCf>W-}16hQl<1S*-}lm+-1Tg>G+bh8Dcuf+ynf6cl57 znU_yi<`fD~*yHgi3MAB9tv%J(0}$QRPQ#i4Mj*1i_T=Tug}qUBWq-ZK0)=2$Fxb-~ zf&EdHeyz{`A~Oa8g@O(7l8XTnulKEkum*!D0*<;Gt?#zBv}g{6ykLlA*JP05ab^qd zG9%ns1*sACL9+>sfn+qJw#l4o^X8bsI2JO?JdlB;X_7CN)_fNE zwQ92g+Qh=b!mLZJ)qiU31{eGd|1|5d5(G++XiGbw5fn)~vP} z;Oug_p!ax!VYo3-gfEfSnv3Dp7{uUOmWu;=4r_4AJYk9=i5~s{uf{;S9^~^DpA8%U z%!w0Pr-5sK(2Fyp35S3$XqI%;NFi#xHvB+q2ZzBh`{HDrWq-@eWH76J)3Lu_9^~_z zVVl;Xv8(lgrDQWZA;9L=yLa!#mogB6G2Fg$r?07*KwFx4Xa3mg*Mb8iP-tcXIi2Q3 zwf$zJ=t5&XMbUJ9*V(_8u4?USkeC;3Y8!Vh`EIh0(k7Hfu_h3l?SO{~R4>}#SOgJk zU=^@U@XHs@Lx2Bm*exYBOUdrjUIhb}0>kmkqH{SKuUafxpU-ah`Lq^GKO^82s2)g=&}4G2yWwf!DB1ty zh1&$cn=nBVpr}3)QF}85&lrCQ1|dNK4eP_l&S>&Db@V!Q{BxzI(*fUuU@QniBe-6Vqq*F(T<)nAg`qjz6#eCE zG&waDeSMUi`l-^I43LBX)3ab0DxfhHu6px6mw(HlRumNo(+SG-r8Bv+Q%=2(9+%4% zM#5`GFdEV0@B)V(BPm+1QayeD{*4|X66v(tG*ye2!>+>t^)p0Ac8}o$xRT#^dSfm z?tjGHkDUoo=D&Q_;qJz2NWro)$(_1 zQr8T1Dg;rTia}C|LpN*})^M2k_2X2sbEiBtb)1T(rpn)~N!?KQUjaTGEZyDReEwj4 wee>X8J)9VRy?eK_^CzJ5(xppq;uQY@#uGLet0lu8>i_@%07*qoM6N<$g7L0R$p8QV diff --git a/TMessagesProj/src/main/assets/emoji/0_79.png b/TMessagesProj/src/main/assets/emoji/0_79.png index dde0d63e0e748eecc12603b79525cba14a96b93e..3555fa469d194f46048fc5c9be51a4396380ce10 100644 GIT binary patch delta 1858 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 Ef?S?IXaE2J diff --git a/TMessagesProj/src/main/assets/emoji/0_790.png b/TMessagesProj/src/main/assets/emoji/0_790.png index 5f694d390efb6b3923771f6ae8f520c4658198fd..b7d029cf3c446ef9d5b2a89f916f7d3519a68655 100644 GIT binary patch delta 2273 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 IM6N<$f_Mt%wg3PC delta 2468 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 O002ovP6b4+LSTXf@;|cx delta 2432 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 delta 2365 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_798.png b/TMessagesProj/src/main/assets/emoji/0_798.png index 82a5dcd88e1fd7369bbe8e955962863d7550be13..c74f1dcdf6ca058cccfd53af51b284a4073119cb 100644 GIT binary patch delta 3075 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 RP@Dh&002ovPDHLkV1i>DQcnN? delta 2236 zcmV;t2t)UX7{?KiBYy#LP)t-sM{rE-g(z{GciLuJt-X)t+22@Iy&X$ zlrtCnPK*Al25^ zJT^AN#KXC|y7Tn&hJSpNi-+jw=rk%RNX!=7-QC2;!_v~yCVv?cG^h|O9~v|-FUri# z*4Nm|%*)2d$A8>SWz;*Fo}jwByn=y(g`I#ql^>MSdWG0!fX!nmCMMqB-qF(0I4B}9 zBOLDU?%3Jc=I7_);^M=^!@Rw`t*WTY%gRJPJ{}w!o|%*w6cVGPq4f3iF)S=27!gZ1 zFnMfbJvTN=Lw`d?Gc75rc0Dk~FbW%=J01Fx{{uBxR`u>sf z{@t(sK<>T$-dLM$Q+__{#;oxA{{G7;_R;a+*ZpG9yt{?f_R7n;Z}|9sevh%qlP&-N z2FpoAK~#8N)s|&@8%Y*MW2r5$*euH&JB|ak2Qs_cjACX6Gh>pO-Cw_NRm(Ge5?CuD`g1BslqlhWDgxB!c%h=Dfzqo)T%BG-suBGXS0(O41 zBIslhZ9IMs2`opjyoiLxaWp0q?-@y06w~o@Ktnm}cMYO|8{X8?=u)JR?NPBPh@w4> z27e$9&=#0a(b2`2oTZ9FCX*=?1>&*W(**KK?&C*@;#a?Al!ApqgrQQYRVwfxpqE6W zarW+)sRjSUNJX?r4Sgzqg2*yrJQ|7ZY)(%vj#P+!L%B>8_;|jDq!>-LWBb#a(^D3! zWw=5hih{rj87iO`(kVimspLwr=FaBk=703!;^1U#@7XAdSrN=GMIa_DeU4^ot=76j z4c&+SXZ5DxQvAmDPLo)Z&;*BkZ{ZGWrl zMr`A%9y@$yBi5^5#fmt@HJbM6KM5Wlcl9S#7S@uEK^v z6*{lFwucRjd8%k7d8B34?5rXriqRG`S690Dj}nyPS|Ix-Oy1BzmyT%}#n&Ix4F7W1&d(Tb@mM|#xd znzD`91%hdN5p%VS;OkW(Z6}Lg4foknt!6MB2n0OliZi^Tb^(e?rCci2igeu-GAHd) z4Zj!|6N*b!JPYX45zHeKx_{{8Fx_%k`cqEq^My(+Qzp|ipeRgW4{OB;mh3c);+Zo~ z4mY@P!inTkSd&``{Y^-9p_u~BoGrdcrl<>6i$&oyc)|pI0P!8F93s` z9`{xxNlHR7-XWr<`2T&1s6(0>5QUUHhGINRWU>gb5Cj3nAhMte#Z-)E(o4Ekq@Yhz za}bycRZ8wdHx}EkKYy3v&qoW;{@HJu_Z3b`hQ{^CgvILr#c-^rUvOtQRu(b2th@>Z zw>MH?UHGuSs_VLDpc4Q+-iRCImp304_c)bflFSF&2*K1&IIQU!c8hRLKpjmgdKf=z zVJ)F?Dip&rnONACc^(dp$I7rS7W)VroJ=<%En(;~6x_lv!+#VfoA8>ZO8isaG&t{M zRYn*x*GxDZI+v7`k3$T5GRGlTRmB&tO49A=_1)9c)Ai{WMU{E-w@_t@~=|9>=S$?&5FjAX)~=YVobxMhff*LeB&n?}doZ8RP`?yW(YOsR@2ttAO- zk|J}`aq{@fH53YhlAAG&5C4A9al75VM&o{F=AYjiEFnh1z%yA(N-EDKkB@J!ufIr) zs>c!-Dh~%8U)SyKG#Z_mnE{zBpgm?Gn)L%=cuhWLu76LH5}%0aWMCl=RI}sjG<@!v zE&um;@#y~ma%E~AtBva5Q zC?q6kV`7!8jH9!l>gwvcy1IMRSEi|_Y?ff;^6}s<_pxzq-7~*jT4KwVO_;Up;|9BSvVRPDUWQ z0000ubW%=J0RHj*96}}j3H*^1{{H<=YHwHLGw-GOuI2Kn(!}@q;QsRcypzYF{^G;< z+Q^VkYJZpAqR04{{^-$ZjsO4$!bwCyRCr$H*7tW4*%b%yogLdMmW&&=VGUkkih&SH zcH`+yz4zXGmwWG(S~mHMbKeZ+ki&?QU-LZ}8SMAbz32ZM1wJMPa;=>-wK)Xy`6YP-Y~2 z4k*6R?BEXzvtEi|d{D)g2r{n!pfNn_HB$uP^1>#pDEUc4JLO$LM9>QR35?==G9o`@ zj73&fye@(u7^^b`3goIBm`vpN?@xE=x)~~Vkpw|ntO$wte2N3{f^m2F`)!~BQe?16 zkbkrl5NAkXz>$g2-@ii)UYCE3CYj_WDH~Ue;sEiTv1spxBB7AeX(6a&axaJs7X%bw zWCwmYrTu0RPKecMWyrmFGWnNavdbGgmbOkNRbUL1V*(4bkASjB2 zK zdP@+BJvln97s^t1_oTd-2S84@-0e0Fq-v+u)^Rx#CkivF#4Ll_KR&7#7W})N-Qt0+ z17&34t5fP8=NiopXR3)j$8jQt&8S`D!xPX35U2Hhq0=lDn|lIR+uEu@JAV>;P%IWV z4{@o}7BSK9=SuffFRa@np%5Lcz1b{oezak=t%B9r-QwM4F!$b zW0^QPt>i^pcW>`w-N9xTi`@ffXWK2l+I#g;z-w)s#V}hxVvHe?Q9P=w<#%lDdW~gw zDxv!7>VY}C?Z7IPo$Z|+mVd=Xk(UbIDOCa{3P|wqr~*^m+1}pS$`(#mS636EPFDVB zz9!-h*3Ux`ky~nn9tdQ-ik;Ti@@SsfS_F!a%aAXQTBU7c1yK|@(|%t96rvf+1TvKx zBFZOWMARD4rHX4NM0TTl*k5)Igw*VX{3p9Yr0;eW*PQ6-ySt0e4M zb{mb9&y{@>!+i-bHe(rB7=}f5J372#iKVs5nmru0XK_r#1W_mzoazMJW6Ev%3d#sC zt*$PuE@k4$c+`%*MMp<=o99HE4dV*Fi6K=&NsyqR3}isUnOJlgeWx5gYq?xW6#b<| z>*GN+!XgJ5C#Z}tI)Ahhu(b)`mY|J9G;S`Kayp(XRYSK`2{^N88X3?Eth0xse_bUO zw%Ze#SdsSm3MF1AnJtgURfs776eCD7hXF9`@xT5h=Vbue$V4|uhM@~OOysIARYFgH zVOYR`{RpI!FO%u0-417Yv`NBtQ)Q9G{5fYIf}&{ZlR+?t8Gk^a{6JvYz6`=q5d_$) zMFA#jq9|2@g2)IEaDMN`5Q36`$H^f>1Q{UcDsK~nG6mb&j{rnANP=jlqktro#}P%y zMbK0sCu04GaR6Kj0t6UMxUAsmj2`jHBt^&q5ODYk3zX{Bsnt*1hG*uLK{Cf^t&(`W zL6Qs-sC|>EB!4bGfq|%HXmET?KlR(KCpT`~cjuiiLhg>pJ{roX`!2er>UH1^t5V{{&+exJp2sq5l0HUhJgN=y!VJhX``(S1TyfISd(%b zuX{8)Fp2@;X77EghHH;*!qLY2{i0}BMvDH*^E~f||9^b($4x{y9%}nnFe3=)Q1J^k zn{CT(2gSY&FFTlk4jVYH-tia^{W}>IY#1iMACdR74uQ+tQS!RCIF3PG7$&`Y_s-9z z9MDOhCeVB15O@(-H~aea`P;W|&tGr6XK?}Q!i6_)&dx3`-P@OaI=S``!*Ny)4h_3g z?>AnfY=4}yfI@M2d#-0R7|t%w4AZKeXdeg|%Q{ft#SMh}H8M6fFhpQb$D8?{VZCL% zG_J4zL#>Pf46`}VQa4P^=1!$j9^qmG^4@`3^Yeo6Va_rCO&fX|&AQRp8yQjQyaZ94pz+NM4bbZB+k$4bbM)kzSq;VTCH`XK{GP)>?>jh3P|B8 z#dJ^zn_pTG_#Ed4f#bM0^K)~s6|LU7!Pshj-HG-->Vb8CQ3m=v!|}Z6=Rtt{Ip3S^ zX+|_HAl6%7cQSDQR}}o$&tY-w<{jNl$U_}>2lD6q-1PL^+=yn{0JFU!{sWxz{cN8> R8Danc002ovPDHLkV1keQ{g(g$ delta 3059 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 B=(_*_ diff --git a/TMessagesProj/src/main/assets/emoji/0_8.png b/TMessagesProj/src/main/assets/emoji/0_8.png index 3a792409d3e39cf4b3a0a9e329dd925670cd496c..9485abd4718923c2e47a4c6b13495633335e397e 100644 GIT binary patch delta 1934 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_80.png b/TMessagesProj/src/main/assets/emoji/0_80.png index c7abf2fbc1ec33a1fbf6b61c08bbd75d2d48a472..4d919f542c873350ac6cd54ca60099316e082d82 100644 GIT binary patch delta 1990 zcmV;%2RZn`5Y!KlB!5s)OjJcja7@f~7V(7xUvqKAY!1h12)%qa!+I&udKl7yBKMmQ z!DkA@YYoR~1!0qv$ZQEsugdC$4e+BRHpu(ve+M|Q+~|c7&2tgYat=Dv|MZ?1IMM$$ z%Jvh8$HQp})_4&@#^>gY8|Huk?3fPZj|*on0o{fOhD!yOS$_wkWeFUz{&qbB*n9=k zaRV;F|Mj~m3Zw8k)Bnf#|LLwN$CD|DXl`ybAy8W&f@R z|M-jl?1KOLrhotZ!2jM^|Mz_V))N2y&ij)C|MqSF`I-Oz+yDEs|Mgw}!#MxR5dY3B z|K~gXvKijNI{)D@|Nrg(?M45;E$!4o`KlBD(l-CuF#qyU^P&*{xh4P0Hzl>J1^@s6 zB6LztQvhT8mYwYpG=fj-*{=Tl%P!2hi04_UxWlK^;D7U&!KbE{3ex|0000INNklKqyepDq7&w$ee;?_ce!xhU{BeX87ovLT>V9_L&#bJ3;H&(6;WCVH z2Z1{1U)3Y)!yuREZi0M+0&}%BoH%OzzOJ~uqq3Ja0?AZA2lYa~a-JvOi;^Px&G}+riT5z>D+Gq_K zWT#SmTz9Z;3|0IpUlx)TSArP>3Dmu%M<#ewe6@TWS;K`lp-}=|&LxfiJb~-L7{-|3 z%UemWx%$CC+m=Dp!CLu>l`IIik}lo`KYHe+luWjugwhgR48k7R`kgnQmqTnlkU<-P zSbt0+50+zOFa-5uV>4?vQ3-y{u;3|-LE_iZ@JC8Rgg)KgK7HMs;KM3zqjbxg>*O_& zUo~n=!Ov#Qwl{4v3d17wL?KZ$R#$Y?(8tU+3LYkyie?Yzr*?_=6u>b%2 z?sLpZSy9_*pLRV44A__MbNoC=CUJbtP=Ach;_>nEFB;ew?1M!IUuwR?$4;i7k23#g z<|KhYQy3qLLl%#br!by_gQ1{?N*%1QbVV_|&IpAp!UgfjgEj`@Xg2D2hN9?JGKsko zxgHOnr7-8}}4%7OsOe6p+Aj$Q5H?N0rso^P)`< zK(S^A6VkxO13=CS92WWB6bk9*??^FiC&4lxHq88x%`O92E`y{!-BylXr2WjlC|9zA(b3P01$ABWjtL$arUIBri!?2kwXj{i#4

    H<@fxm46tJ;LJ}rCrRKC0Yj!Gh&jZzsy0s{kY;ct?3fTq%9=I2 z%cojxW{M0P0<948g+>~K9FT}bm@KW)=>EP`8V-m3;jnZ+;7&Ahs6#lB82b*fOeWUo z{^Q57X_|E!^}0R09#DwgtdMJ>9y;X7n%>`b?^^HQw}^LFU9)cAIDcwGu7@-fj_tlf zEEJ+WD)sH#?uQmMM5_x&hnu+{gGv#HbXCC0xE}WVw|5_4VGlVZ#9lX4aX>;>*BUsz zo(p|GUhaFDHLh(Iic zchk4)W8@(2#!dhza1N5J255rrx*f)aOVgc_ zZQG`K$zYP2=MWq?vc+AH%BnrUk7c~W!n;cE`qoAacFGCctN;K207*qoM6N<$f<_MHo&W#< delta 2100 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_801.png b/TMessagesProj/src/main/assets/emoji/0_801.png index b50d03df0665f436fd8eae5d98d7094c2d11d79a..0386c6b0ac764c68ff26b0d2af122c0e93b2a0e5 100644 GIT binary patch delta 2621 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 delta 2829 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 fjTf2Z82BHuW(41L%yOmx0000!kOTs8tLik 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 delta 2686 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_805.png b/TMessagesProj/src/main/assets/emoji/0_805.png index 568acf2b37e98fd5f1f0a3a28e0c87c3b6222c32..3781781aeec179bdd4ea9989013b3c08359ec8a0 100644 GIT binary patch delta 2570 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 delta 2990 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_806.png b/TMessagesProj/src/main/assets/emoji/0_806.png index 3fed689aa979afd92d76df04486e29b77ab0ac9c..60802f89f32f4413721890ce076365ca2348503c 100644 GIT binary patch delta 2584 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 A8~^|S delta 3038 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 delta 2747 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 BC%XUu diff --git a/TMessagesProj/src/main/assets/emoji/0_81.png b/TMessagesProj/src/main/assets/emoji/0_81.png index fdee548384213bae92b60b803c69cfa0325a4c2b..99b5cb941584290d611d4caae08a2609acb0281f 100644 GIT binary patch delta 1709 zcmV;e22%O{4ZRJJB!AmbOjJcja7^ie1ITFw>yjJJdK}7xDARiuxOqXzX#>W4CewEl z$ZZbAX$bU=1H@|$$!rShi4n_i4)vWB|GzHfkqq943E6!G({clVMFYc&8QPv8{+a}9 zGXnnRZvU(X{^V75Jp}*xga7-h|I|hQ^ko12!2k48|Jzpo{eRKJpez6PbF_;j|NEF+ zBmm{qfuedg_2`g@PYM3IDF4JZu6Y;IxM=j+KK`{I{I3@Oy$b*BLI2w^|K&81RR^12 z3Gt#6|Ni6nrxX9wGVGcU|IZMnX9xeyG|sa#|HvyL0V3`I000woQchC<`R}Dx7<&!= zG>@s+{+-9px_{g@9?_Km00n+YL_t(|UbK?uj+;OfMt23qf(Xgt?=*UE?sfa7y#EvB zn_0-(ICgdu;B%6623?%n3&XQKEiG>I=l-6aD%W^cS?SFVl`kWx}mPO8AR0zGAQl3@k$Y2$%E- zJSx2BEhpOOqCtb8VZ0PNXPh!A@KdOUV_?>PVm)kTl#)-xerSk%68dIT}r9j zw5aRKA%AGp=CoM0Z;sy?bQ>ukpjAa(*QM3cKceY2E4QgjIBetGVBT{6jb*f=cMW3H zHI6%?Ra@wgR_^yU;M~^FhA}}5R^Sli1*j@}`e*r5ZD#BTCzIh=3>cDniY~pLQvQIv zdhe8V(=fK?#2UsRh{2ebOS}u@Z+Q4H;N;dEPJd&aFiFVrU!bTj?#o%u6v+%z88$Ib zl0+~OzLB31=G`kM1U?$x)?&A}oTBte78IbtL+-~SWs%$%oKmu?HYV}%l%AOD%L$njhheGkURBY|5R6p|xI_`pbT zHNBj=eZn3e0Q7xP4UhB2`>-DY5 z(HM}Zk6Z|T)PR;!yqeWW3?L9;=DC`zuNB20BRw!7*deXQDeCgT1!qZ00)?o6*niIC zLbj7T5fo#9NwUX-!Ct_q)uW|J(o6>;awP7PjUjeO$QZPX%LR8^)<%GB!qtWh5|Fs= zo`@R~MyOk9v^5n946fE_?7;|zSK@w?o%9g+*vP#kdjUWLKPR>)x2;blG}sRTjY1Ms zD@}lLD*vEBMt5p30~&$^GX9)EAb;Y%n`{-~N1>c2#yH{ohLGme$VTW_65thh-4c;r z>J$kX1OHQyAf(18Jz5C>0W}n=k9!y`72(F=P7-Jg7Qqno#M1W{AgED|rws?{epaocm8m5gA<9|f05eP73-6mA_MR2}su=&)H2#+j|KKtIu^#{1O#jb0|Gp`c zRtkkm2BKpKc|ZkTCIJ57XQFf+x{M&tq$b_LI&C!q|G_unjDHN*b_D;oCI9F=^`jI2 z$S(ivUH|xi|Evc8`J(^uOZ<-u{-6~9>v{9NEBWh?y_`b-_HNsP2&tP( zpDT=Dtx^AYF&=Rrx2FZhS=|a>Y*9fA+8ee1SPdRoTQp6t{u`lB!v2+|Q~(w^YA-9j zU;A9pS1)Mc3E>R2QvmGowFTp6{ddCpiKSFZ09ik+BQiejg9LlcQ!tQltdGYdJ;t81 zXqJxzVSfwZxPHUI74EFxPqFL9@#!55o<5SX?R{`IrPXSVKlaA5zT}t;!Vow7aI+;n zcRX6Fl_XS!`Yp!TANR}U+mb81pHn#S&_nEcaN_7~xyQ@qtKDsN9X*U;?I}y-8aiSC zYy$t@Pi}ZxF82tnv{e~H)>rdrAAvY?ppk%jmVXZj z7)Uos({7q3z854HgC_CfTmYaWI~=+s-Ij!+k^!abg}5dLlrYc=Li0V(&osy3!d9m! zl6*~|4a%e&3<59kJkRxTJ#qpUM4D;_YXSg;AU+7vlt;>Jr{GmE_{2_CP4RBIbmybaY?I9E1tN z4ShzS3Ax1yVJu6E&H{rr>(I%yD?~oXCQpRLJDf9@argLpTA*PJV0fh<8`bR{qNyZ2UN5JrdWyV^dRo-9` zpBiX{Bb6`!Eue?b1Q?y%;0Q4c!f%RF2u%o|rQU0g^I?EMxsC#W4bi}tiQh%IDH

    we29yM zR=DOrrk6^^`Pcd$5S7{#Kl#2;eIQzZx~FyDUQrV&^mF;5>KWw}N+@Gg6ye56+uw1z z>7M%|Nv+zxy#$niPvfTUN?c_kJKWAlMdD&i^p4fb;H@2yO1wQc~V^?vV2j zHZc6+ujIrmyyI5TVvL}&&#!#X)b~u^id58t5y?9V1ux>)kIYgE^Ik7IyKq(v=vsw} zh}UesvTmWx8H-_%mR1a|O397BD}@W48=O0Nr)20FyO?J-F9 zdh>8TiqXD{|N5|GLHDp%!v=MNBz)tu;r%db%Q|AWCaxdP2v6;ZEe$FodspDlP%M-D zz5Ahp>j5u9A=l7K*Ulf`5hVD&QJ%sJ#h`g>31C^Yc$1rXJp&Z3x{!Bo%xB4A^9*2$ zSEpqiaR$FCu|3VQP^2?@eU^TUHthanqo2;L{ z94ZBvo->n-)60nizaPHeXp<#Zy2T+pCpVUfq zWK6X>Q{-gY2TmMgks9ilNw|%8?t``0tT%c8&;j3$WdA@oo6_&0iNs-(d%a4*E^po% zeFl6Kkz^vKx3RXNe#40G8!wj)e}YocpJ~uG{iYasQG_XR^&r?ICj)UvR+@-V09W3g zbbAhxO=!C105YGc&Fu^FA`^GEdx@K`Lgsfv)~#ad*jK30)OCX^&8dgj{eD(cNMu4_ zROYz$#7oCL86tIVDJ5DeGzD4{+rACfx;(modOu|54V0WXE{CUtBGOUj*DfS~&1$4M zGUg$-*yb}0DxIG@6pe~c7Q_kleOnf$Yo(GtPG+a(07LEBtK|0>*ZhF~8M{8dyE)<0 z+R{eu@V2InRZFnyo}3MhR(K#WHuOb`4mMo~OF68Eq69;RG0bA6!O4T94;4RmfGx^K#m$kR|V*h&-aSc+G$AJ&BTSL zl-LDbaP;I9@J^^Pip(mwe~#xM#WKK7qSJf(g#3$1N95 zPt|%s5)ml@F<+{3jPPvtH^vW1Q41{=wK7B$v*q`YW@rDGk}sU>$}n3EhJAo!#CBEq zwq%5qzHhWNFCQ0ypKW2aFC*#X{dgLo8)|cl8tj-wM|anO{q|Ef_oQq3i!v#}cIn-6bj+F*Ksr5(Cm+8`*t_ISYv zbFy2q$cYbnroJMzMtJ7YO*3A;I0jUN3>k(9ol*EiRmnSS|; zPHw5*Ga{W@ISDH<;(fD{kALFv^MQD0a8_~XaSJ?BC~|y(15&7Fu8iyzW8$+pN|d=< b)eb5rSv~7$gZ}zOfEr3= z;_B$&-rLvO*wX3e;Oy$<@$c#8&cVL8uBxM=pO&bkoV~iU(9p`8mXFBD!^p+Jl7EhdwXv&;er(Lk#?j2g zpqP+(aA#szPgF@kQ$93JI50&rDLX48F(Vxx77$lLI4B$yIWsZ_1qBif3t2=tMmI8w za9c$BpPZAOn`@@xci=}pq zr;A!IOio!?V|ZnLqm`bmqHjT7hQWZJ$)m5pyu{AS(c8+C6PN%10Bm$pPE!C18bnxx za5JF6;PBDm|NsC0|NsB^|NsC0{{R2~y#N3I{r_+Okbm0!?Ek3p@%#Jv|NsC0|NsC0 z{{R2~=hLMBSmZJj{_Ow%|NsC0|NnRY|H1z*Sh(uu|NsActpDYql>h(#|K|Vw|Nro| zwMl9K00!VmL_t(|0hG%}0fPVx0Kn`W|8iSE0OS4#PmoyjVvg_uk~6c2X+&04A1cF` z@Ktw<*?;Ok<7AoG$PNVIFlSH^E7GVv5X1ei_qqn&?uP46Vq5)HV^I`kHLEO(x@kpI zRF4n80Nvi)ztpW%+K3tu7KdBsrIaSrGqiZPzrOq`fvZKUTAQ3XXkS8=Utt z^Oi;3cKMfF{3^mjaxw1;8Ss$cqZNdpec!Fhx$id|BP8C%xcj$`0}N8mNox-7 z`@Vx6S_z?YFICr1eO5~~QtsXj_4Y85j4I(3E30U{vw~;bHmsV}SWk)B3B~yF>XXH~ z8b&GAwC^*QB(YUZjYZs4H^P~yGbbpIhkvaP?^PP zy8LP-;FHDhz}m$hjAVE)?I4)Ref+bx)*gQP1nN#;`SH?=H+k`#iLs-K34baP6+c<; zIsfqUVciP+Tr9oyhh^~%F=MrLnmf~d!hKigi4G$ z{;i*|LCBtbc6xmJ@n#?Wx!hIE-IDc@hmFQzDcx)Gwbe z0bC%a9mI$Xqsts1f(t?*6o0|+wS({t+3CtaOt{>pCE7S(GoEx3)3MN+a1a_Y~wIbW-~qLIT%i#>aD&BW{sdk(!W;W=0=V3Vt12}n8c^8QBTu~ zFtjyj?5qqz$Z>hKsf=oz*t9k3LLhtqKng-gcHIb?>#NCzZ^vM4we(GIb#2?24!{5V-i{wKxk0mjr+umb0Ds}n{jKKJeU+2H{@#G~ zbRswY{i+sX8j|B52!E;J9Ggp>904d(Hs zzhxE(DcU@BMPe}+4vQOiis1kV`2I?y=c*rZruu*Gm5-p(Fs#A(ymP2GWnBLYP7#kK zUp^?e&VPOLd4Jm+s`VC$+9?8zZX6CT{~N}5xI6RygUY+FTX$k_V}~^nfJls|vHP^w z>pUHG4js#<(T(-EUI(k?V`vbG4Z#87b7(Y(DXNQuaem0p;v*2Aw3>U$)}gkeSO*}c z5U3NMCe+iBb~-K*?7J^tUIvv)*Q8fv|I_ zPO|~BVsfvLU=Yupcn&3DYK;lKQ%@Cqq498xG7|MplF}eZ9n1dBOVJbxfkp6zn3+a{ z5s4rfyO7G$l`z&3Z}y?9mPtJELPR8EC1iALoF%lT?J(2)fjt|SLYX*+B@%oo$ zaTfn+B~Pp|o(#?_Q8%g&$A)-)MT=E?bx kWoadBmf6%rPA={K1AunO7;3w=Hvj+t07*qoM6N<$f?))tO8@`> diff --git a/TMessagesProj/src/main/assets/emoji/0_643.png b/TMessagesProj/src/main/assets/emoji/0_643.png index 3dcf5f18600c9016fea61ccc84a72d9ab49e60a2..ae1d9ffebf7f8fbb6d95e530407174989f26ff4e 100644 GIT binary patch literal 3270 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 delta 2476 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 W?pR0c{XbU@NJqm!y;{}o`M&|Uot%6C delta 2426 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 delta 2560 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 delta 2469 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_647.png b/TMessagesProj/src/main/assets/emoji/0_647.png index aa3ffaf94948ebf271a3722143668ae7c766d98f..5cb7b07c44c999c77de4101dce27ca808b61599b 100644 GIT binary patch delta 3005 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 P00000NkvXXu0mjfTZElW diff --git a/TMessagesProj/src/main/assets/emoji/0_649.png b/TMessagesProj/src/main/assets/emoji/0_649.png index 2e8f9b3e14f45e8936c0a9d9c1a2c18aefb9231b..5f73866fe283d454a6f76d44371feebf2992dc20 100644 GIT binary patch literal 3259 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 b8>9Rmib)N8XP;F>00000NkvXXu0mjfEh_HW diff --git a/TMessagesProj/src/main/assets/emoji/0_65.png b/TMessagesProj/src/main/assets/emoji/0_65.png index 4d330c44360895279c9b0038e534f8b55674bd6a..eb54b8d053cd44aa74e5b6539f8ac72d2e2c89d8 100644 GIT binary patch delta 1895 zcmV-t2blQr3ib|=B!AmbOjJcja7@c|Bh76U%WWC;s37Wf0>yPMxpgw=w_PO^ZDQ>7pdHVSfzWlOF%DDE`Vx*>(s2 z^O)3V1OM+}|CI&*?{oj&K>p!%|Kdpgq!RzxHvi;d|JGdp`Nse7hxncpcr^m^m=a(o z0qE9S!l6L__qMWtCI9xP|FsO+zg7SH)&Ip3|NZ9h{1&4C000$qQchCrtTxPRrj;>%}_rT_p2HAzH4RCr#s*N0NuN)!g*Yg;z5+{sn%y}9;YXi47x ziS9Y8T`WQ_B$>&NnE_e)=0B^&jQ;t{xocD^f>5b6?*0g9)T)CP2QlEgHK^7azkB_l zwKAT+z2^CO)f)VU(x|o$&v?B$cQ&)x##ye3a%fe54S%_-wpIYB%l*^tJI&XJ{YJ$q zzk~>_>FW90dQUDdXEzGJJ+G#%+GiE|9jM@qc3+Ep|4K^GJR#EQe|Ucy1E?S`c3*cp zhOq2NMjjLyRQ_M6;1KT9ZuhV&!Y-!(9Dms2Fv5qz_JL;iHV-U|Z)kiVEFPXnC_|tJ zc75^AUVjJUr?WJO@H85Yo~Tj|JvM^(pNR3Zn>)ZMMtdMop$-eX9J3!Sa82LemuhFa z%J&#N=jHkW*eihQ%k{b#?Tc)mr=9A%g{V(g(gK3W!atwSk6_%gzaGzL|3UybD_>1J zm3L!IpSLJ1X8YOoe2k9gEA2$`ay&-S`4Qe+kbmgYA4d^zj0GBt*=*q-eILGO`&%CI zP;|V^7R1DN+(C(KyWMUuvrFXri68l(y#|N`*q0fev4tqpY4`4j5)u#;@xcIM z_LhJ|mkA1({D&I-&eX{BZC)6Y;{5BRloy}O20}=HJXfZj!A)q?J5wcxgc!%UTwgAi z&41)=E|-_<#R;7dk|VL|)NePX26HG98ZHpa(19zQiSs5Caxh#1;G!TYMtN`aU=Bsn zG%t5uH=HkvI7b_itFW^#a*vG2nxEA9e+A?fh|S7b22hre>E@#69jWNCSq~WD+vY= zY%!{Y07I5#QB*znS{G3tgUJLK`YXO8iXxn*>pCI&l;{Jo!WzT?1Ve}*@n*9iD7ZBo zEeV-%>ePF5clYWh63k$TS`g3z0TQt+tdO|75eG&PgCS|+!60#A0!;-*nDs6tx_^`? z8>*^MyUqt;hz)F*~G`QPdYFFQz9^gpo_r_%zFOV z^c*LCyv|jzWY9Sd_KoP*Et{;T0((Q2WKGrp@I+5-0prK2eqyZwrS3$%c7=R*x zCEzri<78T6wmSuWXyPQqkT4)Xyui2QT#Ms44alDsydWUZIfi3_5{-MD1Zxlj6-^?< zV+?Dnx?#`^kRSjRaE{@90|88rPC^Zd8hXl!ut(==zKl~q-x9WI4R0U7)qgQg!fK#_ zNMLa)2x>UbG!1G{00aXBGRN&xtHKYho57Hj17NvvU@vf5nj)b{tOF^*m;RykXpORw z#=(>#>g?E@2r<30lKMt@<($}oA|g%&`Z z*5Fu{m4FufpmJX_hE3TeEiBt}4a-XSAWS2k3V1gv3@AsS1|qzvx$|)D z=@uVz*0AlzVGy-XFhtRTuOaY0HJ%ty#7t}tTDYEWx1%<^U?q}h_?dtP=>bKC2?vA= z#DR~F=cpNkanv?ph<`$;e(*5TEeswBh$tIo5`mBhNtBoXpl~mI_%zWY!z2aaiE?&o zCVm+n3X+?|dkS0kSq*2u75g6ZBKY!w^^!YIoUeV%UH=A+X zJ^}#%-@^)@N9ebclMI9=>jn^MoE)(Q00OJ51q4Eb0?RR}EQnyq|M->v@>2i((EY9!|M-Ca z$2WsW1pmJZ{^&jb^=X$~3286@|GO&x-!cEqF8HSt|Fs|g(SH*Ez&5Oc9RJTZ*0nP0 zmkpz53h|&3$fYR%#V!BVGXMVLTl^+u0000CbW%=J0Q%7GfLO8;n>E(C8U>Dr000Dd zNklwEHwlJ}cm_B?`K}Qmz1; z%KB~#lJb>*M#7@hfM9D?@gu}l9Z1Y`#Qr$K8UTLD=W zn8GY{01Lbuo!&l61O|ysl6cV~PFQrv!`&*$N}Jlwjz`!TVe~4weT{>Z(#oEw@GPO) zgq6U?zkiA!LK6LK@hUV1$cg%9j7aNJ2!X8}6nQVMqF*wXppOVCHaZ-GrP^!+0IeLk zHe++mdpy(qDCH6k+-j; z8HVv3D$e6DG~-*|!3UF}J_MVvZ(1Kfak+e-9DnC#co~|P&KrIfW4Ens!%!4}SHC45 zwp7@c5mZ8m?BJ+wD*yivJUqg$7t9zWhbXz2>UzlPx4bRN@A z+WyCQnIa5N0`C8KI~~{jJf3)o)T3Wsmq0{hqHotx5OI!fAcEo(k)niu^>j-ZTs&XK zG=GfhWhUYr<1nz`k5>@aoX{lzVTh55`K8in5^(?_#{1ieh|i-JfWCiX7Vj)9bQ=jE zbe_%2d^<=DMz{t~)2Hx!Xqw&=pu&NOW(Q%H2sQlmboD}rfhDgUlqfP{T#1DZZodtd z7)Zn|BYGzC8eC-A3cSKm;&K@`M0Xo$Cx1~1AWM#r2_P>)L{9{w#A<*LCI`qCA%f`o zMu>gi$vh`*p@1X-Aat5U=%Z!&88xODT^zzNgrJPi1%79sTjC`9FqIIs)tyXJbdH4~ zEPSPe1*?JHcO)oL3(=OelkvbcU^p@Y2|*mPqzshBT@&y2! zP~ow$7ekReH?5F_hp9>$h$5?VcSczq!7arzE;2%_49*ODOU(7nr`j{ zK!vAi_k@rFM$_Mc=C99)Rbj0GgP5L3Ym0sRZ%5stw1~lLSv2+TO9$?zDT=1~%7HsM g$n)0!|34VN0GYE>r}&lGjsO4v07*qoM6N<$f-RYtc>n+a diff --git a/TMessagesProj/src/main/assets/emoji/0_650.png b/TMessagesProj/src/main/assets/emoji/0_650.png index b441d840461e696c2f4508dc2f35ac58d5ec857b..6be8ce7e85f3a30924149a400052b4567be4ea1e 100644 GIT binary patch literal 3196 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 delta 2393 zcmV-f38wb^7~>LKzSS`T4xT0@C ze^Di-k&017Ed1)zi$+%*Nl`)!Nw8^2(>#*3ZSmz0%Lg%*n&P zy0o^ktI5W|;jxYP*0t)sn$wkPxwf$D=;HA0=lR^cu&kt_o|f~_ui&6+my(LvoORx* zgzv?n+@pNztbcbQ92u&opOt}b9|;A>i&!)%C6aSeOEoE#pRmrNfW)nkhGaqZh_&34~ zCuB@k6B&jmG+k79!BSOKm$Co?2~PZ3O4R>um&tOHW|_re!O(e0JhFP%;Ia42Yl>n0TZ56yYxvXtXFo*YB!+b8J^fNf#~77}NSuN2#qf5$K~M9ZRC z8G3*WInlt&+owGfiNF0|sD|l`Awa>PntxCvEV9T!41{7(&0+-w1Cy-&dIlbzG9m&0 ztM`^_Ryvh-o5B@%6wyP8=kTLKSFoH!F;(kT;Mw|)zcuiR0tm2x;>O&kav3ZV{oz$0 zGObHr86X%B9G1DXQ!(b^|z^kM1P|1uDYiO|CA?{a5L$Aozzpo;c4q*#OI-ZwOU8@x|~cV9By>O8) z$)#knB-iVRWZsJq`PgcW>vBmx-aotBPd-ADi=Df(MZ_cn@sE%fV$<%oYJc^TeAwv} zyWh&d=|@EneK4$mOoj&#%9UIUt6u zlqX`&9uFy9mbxK*W&irF>GZ69Y(;MXHf*EJr*Mk>waAJ#>dEpi?FLpjt6gTHSCm(raG=%eg3>U91i=dpTBk{0Lt}L zE#`Qb+gzISKrK~kDfH^(^XlqnFd*mHapGufM*&!lEiCl5H>cMIB1y?9d~y1#59;^( ztxggqs!Jej_ZCR8>3@u6*pL^2Kx=io_+E9ph^93trR+v*-WPq@>y?|$a&G}aO}AmE zun?)beK0(S?(h`~2Jv@HETusp^?K7QeY09aD2QE_gX5#4v5YGu0w%U1zQ{HazCh(3 zZl@LpG4TDXL*US%4g!{g7Cr3}nqSJ>(-F}vmq8HsNoj zKwJ|92-X@PK+9!9kecO>o?X9OZPe@(RHuV&HyRX$iy*?u$w_m;yWb*9u_{qWwOXTE z-MSyYR4zLN`6T`8UpC8rx(YSukRJa%a*y6jmjQsvzj$^_G=S~QUgao#ucOPo8Gj(^ zR!x%-UwU4IsDFQDZI{=Lz01APJ^}VCmzN_;LZmH;YK$&# z6NyoEJWAYNUjATJLE^*>e{>5q_50uEJshlKPvh)h*vx1zkx0}giNxOC$e=v{FLBI^ zW^=&<;0tVI8BtOQVS({uG)mZo#AwtuovjJaOJeFv`hORXEXLP!oa7J)K|X#MhQYEo zDr;CS;<#BpdJ&lJAbd=$3wSJ5p8E8r|+#tS%6Ox0}65ZY?^knpScWClLV* zO@P>up<9-2+(@db5r97~mlqI?f7)8CXL%8bM`>UQU}*}cS_-c~werG*)5K{u{0s+# z@*v5%B!845GL|4g;&C}WtBC@~$Dc>6a12Ic;G=dDJGjS55;T$2DEB6eByi%)^Cht+ zG78T<0yvJjxxHaqIYGgNYl0C(hEh|WEsYtPWl7AVvh)K4hnyy5vmBYg z#zqI3i$9x9F&qxRejR?Iox~eDy-B>$cEjPtSZo%jT^b_&SsDKZD`t^excCuS00000 LNkvXXu0mjfqcg28 diff --git a/TMessagesProj/src/main/assets/emoji/0_651.png b/TMessagesProj/src/main/assets/emoji/0_651.png index a545664fe6ba4ad80185ba4d09965006d17cb67b..59868e181b9ec2e2f436f28b7a1a71e19ce69c3a 100644 GIT binary patch delta 3029 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 M07*qoM6N<$f+kP|hyVZp delta 1712 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 Xq7%UW{`fGq00000NkvXXu0mjflB?12 diff --git a/TMessagesProj/src/main/assets/emoji/0_377.png b/TMessagesProj/src/main/assets/emoji/0_377.png index ea376e60760543ab20454360f24a1d26a8a06c76..2038d28fa314241a87b5f24635ac1c0bbc0fee28 100644 GIT binary patch delta 1306 zcmV+#1?Bp<3#|%}B!5v*OjJcja7;opC_*(ZJ1!+aG%PS&tZj?Un z00008bW%=J03=Oql)TpdEpRDi000DoNklKP z5#kjdf?PTpMm3O`{o8=~!cma~_nbP48NeBg&xXK{L1zYvd*K_znh2vG70m>a7&6JV z0izy5gkaGY27kp0_1jc01L4E3bg*CQ7!D7S6XLG;0of|k23iB)Ls*9c#-3;rv z(Y8^5p|~YdxI?CrL;SfY1MOs17ziKr*Sp6GA!J#g@Bg58#=xST(}E4;V-l!ug3~7f znV3HA(g}_r7=MQiX7Z^C+Qv_d!Q5fv@%gk7 zbVLZ424aJf^3Ts|UV;7cN-ke@yc{742#q)b%8C^RT+bJc`u^u_A@1WgVpKDgz|W_V zoDmYPQ*?SZbT#Ahm?nZ*ey6Y?CfO5_loEpg0VRP9@7;YN7=S_)5?p4c1g5Do&Yu76 z=am5{hJQgw{7K(p&?R8F?Z;&yXaP5>*&OhZzo$AMdn!xg}Q z{vrZR$Mo=6}<0i(k3@ZW@Z zoF@U{jBiBb0me>2Jk6Gg%^9>O1St{9p8BOaB7Y2oB47BHyaUq%XBXQLXalt12-o98 z1o5kY(z5W?RMmlqulqv$8wm63Fw%C{qIj4Pn~2*gZgn%}%w}pSyC7NtnS}&P|J(zt1-}Je$RA(Woj(WVkP^zH7^PZ+^iY`gk1gweWd)?-pcd~`wyDqu}N^Pa&8 zg~`VYL$15J#($oTm`NVjU{eYvdUX=h5e`Fk!`cV8;f7ed@KlV9GRtKm#puKJctVY_ z(;Z#Hp|l#jJSvKDJEF}EgOdc?_A(N2LJ#7 delta 1446 zcmV;X1zGy73b+f9B!75NOjJcja7;@tBS$taN+}sbDZ}~KsR1WKz~au6AcL7 z&$#~m`@^V&XjMv~Y(k!9KCp#Y@#)>EjBmMn5^`Wwdud;52Y>d$0000CbW%=J0N3#B zfuX-4KVsqM=G&va000EzNkl2}&k5CvcZ5<;Z+O}p6b_kY8ws+J;wM27sx zCB_ct^rzd^vSae~FOwY(`R^REzXlG;e!H!zQ%qHEkNf1Wm^|H9r|+M6zE9N_lusM% z%hR-Wu9VyKBY)&@tiD$T2p~!Jflz+0t&ha1DmMRDBuhiJ6ab*a(dK`g3g1WF)b&d zDz>XL%?n&m1+7DQ!q&6x&r@QGO|}%WVAKSySM7$&rntGHKGA}D*O8S#7ClSY00wK{TmKUCa#xYwQ$3O%rJr+@c7R*@oNK|Rd#e5?r)v|%N+6%+$X>>>w8Y0^gUd7kMsGOxVg z5W%5~an=Jw0Y!r`bxIZl3Q{Ut8zN%R0mxZ|pcH(l_XNOLTmis_Ob!INg(`7+hH zn5MzkJq*S-G7`^+ngb9dl;EC{p)IcyMI9>0zFkGKL2|5`|ME*h~ zKz~>uF1+r0?)^`HhIvl=VfSn8%X`miAdHkWis$4?A^|nq*0uMhsoE&SGQ7W^+Edf~ z-0p&j+H0j2Kll=>w5tUOom1@(oL}Ek4Qj#rR#t5VN8NU?ncC{$@&)0%1VZ#(E8`t- zx!qZ80Z+G{?hEa&T`NTGbTG*)kz1>PV1Ku+1ps2tT?<6q&AkHxqTRLY?s%VjvuJU! z&H{0{bvJ`8%%ksabedqWwrjoCjTVmw5b1AS&*;^jBjL>EYmvRRNHEUsEvCOR?0+yI z?A*s!&zwafT@s14*1$X=99J?Hfotpme}ymE@N>f%mn?}q5}e`MF(6#g7{BR3iX|LP zb2$v_UI-Y*6*7?%vB|!cNxXHYhNct3IJKBiHWHThv8B<~RVs2LK;j2;&r$ zSZ1%iLt-+xb2Zi$FC~1l`C4zGm46#*T%y5h>%F&z&jci7bIewWt=4v^L7|-(EHZ9v z5UkeQRpL;{sm8DuTms?%kN||z`q%m|jX_F@HKM_ZVUvc!SVD(YB2hpnYofvF;tVya zK`03hO30AEc`v1u@{SCQaMpSsKMYE78yY=Z_NGIaCV<9mM?SIp+N{dgGL@zaCU>h zhXySr0}#SUfV2G2@Ps_Yd@hi&_ZE?nF$Mt-Q~W$xvO@%7=;55TyM%<#b4Yg{6mTrY z?>>5;yu4dM0mu8@CRqTVDj#{0rfGuz_3&@=ACc(raTEV2G5`Po07*qoM6N<$g5?C9 A6#xJL diff --git a/TMessagesProj/src/main/assets/emoji/0_378.png b/TMessagesProj/src/main/assets/emoji/0_378.png index e469177913a4953c7d9ad5fe9104a7d82beeb1f6..9f8d89eda854c5a501550d136f59bfc7b6486b57 100644 GIT binary patch delta 1993 zcmV;)2R8VO3fB*iB!81oOjJcja7_BbEcwJV_Piwe!!G;9GWx`QxAW#D6>g_SF9I#sADPAruGw z>$6BF1mm(mu#QbWKnOkn000kkQchCW2INUZK~#8N zwbh4q+sY9J;E)7cOnZAl?_e!@|EJ483y_9&tz0MP+>s9@g2tzRW_N{u{lm50Pqp3t zKR0ip#qx02QGXo{hvg#L{7=k2S{`=Y@qU@=em{1*Vjb=OJi&5zztjEa%Nd1lqf%t6 zKT8rV%hT~fz`Vc^vflhb4~tCd=kc>Z29R#|_d)jS-L6%#LmR(Q5M);@wtpjZ_g&rV z!;xk&GMCTB^1m6|Wp}@Ktx>Y*fS@Mmld=C=SnTfTSAUzTeipl~JI$Qf|y_Tvd@l}KvbquB0d2rc3|M3UJ7EsSbQ}I5{`wm##kj|AQ=!; za3%&68PV^E4Yh%fGpVY^*xJJ&1Qncjnj;a#{x>1k9em6x6RN5Vj1mSEasAdSVk0C_nxrg)xC(dQ8O40*5DYpJc$TDP?|O|QwAvP^McjrA$U20jVdH5P59 zb0LIoRb?8*Pp7#tNl!?hVl04@{x2s!q%VN#z&NY&S}LJZ2m($$+-Bp@h- zSAWI|WO$xvhh$0082Z6v^9sll2q~cv=NL;d(03nrj}+WCRbJ+`t*m}#s3b|#kOT{4 zZiCH1LkTGujCUvdQ_RuZwXCq0a;3x*mB+|&O$ebRT;R|kO5bt}9WGUzL=zERx#y0F z%Ji+!*woon!I+YGPGhOf<6&CK86$+HuYdEpNjgh?p`FKK;XSgT9NlFdlOT;gC1k6zWnrwp^y zdE1V{8@c9fo(qj}>srwv&aD+LS&h?7O9;*IsA?^lA3i$uczir-jO|?zKAzQM_Bh_b>HN`qO)+ehdzWs)-hbrnL`auEFZUr3`f$F#iKIJ^#3L`xMSXJ^s z>|Loq7!X)dJXJq#$Wi<5e9n^BFz@F}Lzi=YJl`1>mI!5YmqtWzVXGc70uguTBQ36b zUe2>l@MhPjTC&6Wk~uHhKBTC9IIJ74Z52APAkr(058+AZ2pG3$amL$R`hVT!QZOP+ zAe2ZKMEKSQW9TKulcab$AL-dxTmvy0xOk>Vd=aN9h`JexmeDDR%34`#`+jJIcZ?3i zH7hb~$soM9dAOLSNkW7oLZSRb)Och2X3!p;Bx51KEJZ-3Vy?`qrXLBh2C*tz6q1+$ zi{#Sz{Sb;>G2iD1!MM~0gnv@_-FhT66*g^SsFOJXtGn;;Z5Cu2MUVAp>$>IGp5Mwm zRI5zW(wfYOl+gqd_9Etes8(yl2eJKD3Mv@3p*3MYiG-Cdj#Ka77eXIlNmZ>w`H(_N z8IZbfY8vP)MVS-Nl3zjyOG2v=UF(p-%dteRj1j-aa5B#YPm_5F*?;zS5>S4F6ub-t zL)%9AU#5ZBWKKW`;d5(g4zMYr-yntao_p_s&>ydsyO)vSD{jqNnFQZjiXh}veuWgwp+*BEHTKm?b$dMUZ@>#)-4z10 zq1phHR7BvMEtuo@a(|1Z{KnMUj_oPgOd*{GNm1!M}6o#yZ0S}&` zu`v!92~yP%0KAHG5UUgbe;e3grgkH8O}xe)7HA>}?x()L)< bzq{=}%W!@hOJ&Sr00000NkvXXu0mjff}+ka delta 1272 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 DxlRVE diff --git a/TMessagesProj/src/main/assets/emoji/0_381.png b/TMessagesProj/src/main/assets/emoji/0_381.png index a327cb7389ecb6ca8aa61c59c413c5f29d60ddef..924fe641153fc6b25b37fd4c8f956d44bb7c2f9d 100644 GIT binary patch delta 1781 zcmV*>D-(80EK4dALnaVXFBVxe8)HB$hgv|9V@W+B3^N@KY(XJxOE+RV9Cb)2bx%68 zeqWnvP^@-aqH$M$Q7?Q~K%{_b`}_Lq=GwT1W3P*KBnkt)jelp&vXR!yxxS!{#guHf zmV&E+5>FWb@plHY0000EbW%=J0IS*BiK*WpYeB~P!|r?c$w~kK1{O&~K~#8Nwb+Mp z+ej7#&@q<*phuk>IfGfj|NnP;-)j({DXrGCRePzTt03a&zU~&q@?Zbw>~=9{xBFj! zI9hL3tJP1+c7MBFZKC)eIlJ}V)x&Ul4>_HNp>}q)-u-#~ZGAeu6Yz=z21@Jx6p6NZ ziQ5TS61voG75_nnjaAYN1Uv-@irDpk74~&46J3WIpAi_F-S@((JvpDqayXsXcv9YJ znEmei4(}k&iMA~eFr0s4Y-)6M;+%M6UE2)9X9cr-XMaTQM1)F`L}tBpb=x!*910H= zYJ6kFjy7Uo!mF(8dj|zfGgQk|!PtCF>|1_;(+MW=IwQnF0Rsnp*g5ebbJ2euV`#1R zR72)40sRbxL{(Lc%B~<%y|l zXI=EU1b?amu(lHtNfI(j7|7BF4#!&iX;&hyYLQe3sl>DKSclS=_PNFiSMflJ9D>$L zU{R&eMV~#TB#NG%Ry69mzUw-RhZa&BL~#*S^kw#So@#8mG6=R%LKuVAK&Xhy%TI{O z483IkDD1XH(IH_DjYGxb8i5l+!~Bkz$*}QnbAJ>th)AhKY56oc%ZL|w2k&= za}vTzWIX^n(`|i6(*6-Kp-H-37BudPlnLGrlwhE$stNI4Dng);!vK=?(Zgb`a^v?ChT`re^&^T6~&k`L~PIZgIq#)9HlBmmb7#f1qI%}Kic)Z|?Gb6n% zX(BI$rXL94VNW(iuC-RuW9f~po9Yts_7;%4!V{_RTdZ`RV=?ZBe4lEigygeWy5?Bp zWVLSq-jEro+LF#f77o6U+@_DGqnVSCAb-->wpJPbn)lg}k)=s*`u=B@=uCMsl#)`J zE@C1sv=W{Lk<~UCUY!!|J*!}F*vN)cDb&xal$i(y?$SkAjHu8oaEU&--ppY*pY6?E z7URvnUNgEp98eX8_g-kNr^VQ$7>^CC#QEpg`&)lbe%)@(+nnZoG=eVc!!0pJqJJ?N z`E)9W}Snc^BS(k|xJ)DX##S)IKe4mks$h)*6v`ip+USVsj@X&Q(Q5MK8ro zZ*#6>v>z1-)kIJe%|w*TiSWj@)$wvgR}?=`hsD5zxQvU(iQtHIPXw=xgae|kj>y~f ziu<3!7x}E$y^$ceMoxc`)>?8=t43xke(ud;6 z%R;arc|q9-MCsbLweC0z@SIWTAUGgmA`s1giKSPxpbJrzN*itJN22aE1Cvn@p&=k_ zpayln7eCfUDPyb4V~I?#fPdO#q)Z?=g$(gjqqeoN!cmZTsy3>1su^?%)P#u%;eR5s57 zx8^SpYXt`&Zh=6l=3sG+Tm;;K;E4&&WaPoX zz7R5}!S-0~QQ|JlSqN6A8Zf->>vsCAgJ%E+@E1adO^xW^yE51CiPxDUgn=Fa1SVKm z2pp}L2_T%g29P9td~WPBEg*t;6uRjq{HCJD3x9CwW+K#J#6SK!mtX(^v4w!_q95Ds z_JtgTYOwK~r9?-0*=~QV=l=^}Cyt|NyKyGEiY#@*j$_jUgI>b8Fa XI-6+)(6*J|00000NkvXXu0mjf;A~7? delta 1727 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 Qg#Z8m07*qoM6N<$f}WgIvj6}9 diff --git a/TMessagesProj/src/main/assets/emoji/0_384.png b/TMessagesProj/src/main/assets/emoji/0_384.png index 0cbe63a2740ffd1d1f06aa82d8b166ff11ff9fef..ea25c0b53cd7974622b0d7fc3d813bae98303598 100644 GIT binary patch delta 1710 zcmV;f22uIx3BC=GB!8b!OjJcja7@{r7SE6p;H4SjrWfa|8R4cC(v=nT!b9=AH1W0_ z?Xn-xloQO35%RYmwR;cz#3$~vANao{>aQK;sT<*=7ulT{#)=c5WemD~5Up?x``wcC zxgPY#RgqT-@VF;~N(E~~6a478`PO~<3^kZ@)VN{(&4XxG?`@8ayFY4MKPOgtL%A_{E8V&vTZTlKn~%AOp9$c zNqRr+V3NW7yP%Rkr9bN7c^iO-NR>bRdpo`73WdkSbUs@@r~f8AH8UW-HlUlq_v`p9 zjQKWCz66F(`Jz$!zL6;oJg|)KjNzmzicAwxOn<)$3b0d_Ul~v9`Ephu*zBPJjtsWq`(m- z!N3!<#8gYz9}kLH7qLxaozAP}at0$F_#-6F4#}F{eG%Ityh={$)(`=A!R^;n*JLoV ztjg$J8Gi#BtE_Te?`lJ2p8YiqlS8sR!-2V9ji)sTNHn@`yVe=q#CtE(8yF2LIPffQ zH|b;@>&=r zEYeRz!m}ta>5PF%OcG~NvA~e%Fl97yj0r^K=kl7HW|9NYr5_g1`oPTSvxXXvfwctN0qx6o9t-G29edKD|qj3rX{dpAVth%=(3)ErOU@%`ncJLZ22%lGcsy}Z27&wqk4 z<&ARVyGMW~jsT&L({7K%%c-DOVYNK&1F=6&&t(Y(E0x?4r2>MNr_FKyg4w@qs%tCx z^z;(4dp#UgDVALkLW{vIkxFJXG&0{zyB9z@ zdpc~^7os@KcYB~~dklmDBEA1)!hbXnd_6xLce~D#*Ue#mU5f4DaDuDeoDZ8VXOejN z{NPc<6cTh@9FA|bKTi)uC?Zy}-5gGD_Vu)xZYdH*Ozt15BOoN>l&;qCdAwe&P*?|J zwb+J>+ZCmyP(+JI&r|_~C~5c`hj|DDBG!Q(T%`0uB=^KXDx#nhFhUlASbt+sfB`|D zmw2a4AAL9g8;PqCvMshqpb!ionAAkVL*zaQ5R&m=EFwZV5VJL<5r|ckNZ{VQ&+v~0 zqU4CIVoJ%O70OC9kqLb;MeLv9W1=%s{7o!MW0aJ{uq%LsP;U1H(QmDaWk9{L5$!RA z2QUyE`>5OgL!w7)O|E6cN`E+%U{pyFhyoNLO5nhKua!YE9*@Jn9{$_>A6^F@k`CEVQ2+n{07*qoM6N<$ Ef+##G!vFvP delta 1237 zcmV;`1SF!KT$|X zD<>x)9UTq}3mp>=F(Vu&8WTM$B}OwXPB}7FKsH)NI&WQ5gK}u2l!COXpiv|S+11eY z_xFrj46utZus-;10000GbW%=J03}Itj;qlA|NsC0|NsB~B!5(aWdHyKD@jB_RCocE z)4^`sR+NO{uMR1B#!is;f6m0RV>M3=v>Bn*5R&}Tsuv&XUXt;7kw8^_+Gj*2Z#9jk zZMXdo#LUFRdvtZL{ySohnRtxuUhO{;IX?rS+uQyFF=q|{P1BSV($HSF@;Pyw6YBHm z-VZrG2uBn)|9}6#*}j*ZO#2xzPm{9Q&Q_~cg-9Z3&g>^do~FYp1&F*AXB~a}JKNJf z-Ua5%o_U=`8uuO7!F$*32H*sc)5w==g?t160(!Xmc#!iXk*SAjIuH$#bO8n+PqvWf z^8gfpiwhONk%xnf&7q;0)TI;zT%ZAR%=Jj*NP#Aax_{7U8XT8{%7^3L`ZMncCa^}N9LcrL>Dk4)l#vn#fDG$V+W;x=hjbYIc zNRcKq8zg-v2rPy~)Cy@lw2Oxo4TuPdnkuog9-HN!h=2niQA!Vo_nPLKwGS%*27(Zx zQ}1s_1%JoQKCWni1PDL`LIjoG0Spk}NeOoAL)|SQo>=-}1rU+#>#)9z_x9(3eaf_Q zH)8;W1Ae^T(l+_&JwK;yb9?c3?HBL)(zh@$=HVa;g!A=j5+6GL7wx`2 zfz9j#Q3i4xC~;p!jHhSpcseiIfx4r$5qj^HlHYQ(R~N zcq&j0-~jUU+fI`3eEfYrz1;rCaRtCWyT0W6dYTI~&%3|?^UV}`9@p#M$~i{?oO64= zT|8gMS@%$Hf-Z_@X7n}uTWCTnAG7KC{fNbwptb&I5>c!Vn zntuW!x3^z^&+9=Ubx#;`A(!*GJ^e1OC_p*K@A2#GZBvW^9DqGFli2pSj{IV80Ic+O zdOfb|QbJ#@`xQ%OM_ku!me)1_>?ZkJZ;N!p<2S-=AY7>=-U|z&%1-UW#~y%+NeYF6 zL;ywfBk=eg>4mtYJY()Xew0;{YbcV0flPx+P8WYl>)`~=EHUB zpEF<4fHY0hMRI?5{M@aNE9`AIpr~qW+peI5D%tC{9#&x437}qV&cR++$G4`aZq$46 zUY@>+gzR?{wQ*b>()C+Zb@TFCk1No!1N(Q1IOqWU{1VlT)*}HfsPq?U6+j5To__;e zJ|p(~x9relJVxop_kAE9W*lqSrfD=yVomg6gm5SRrV~hGFPg?NG(|W5x;+y252X`9 z#V(G}P`YvVI35n7wE>D2m?duER&;3ylDMO8~X;*LoyA80VxBkh}%xHvYQ& z6Jf7sX$V9F)VjaQPYL__McNPm%1$Q!y!;zNe?2E@11YeL{<$8D$H@5&#lRALztz7c znDZ;3Y2f9y{1<|m`3m4=cloabNk*z~`LzE7x_q&~8i!{;00000NkvXXu0mjfPqIS6 diff --git a/TMessagesProj/src/main/assets/emoji/0_385.png b/TMessagesProj/src/main/assets/emoji/0_385.png index faa03b6364d10fef3702a01249f9f9eabe062c5c..6eab0c86886d8b7e173effc8e915ad783bcdcf65 100644 GIT binary patch delta 1695 zcmV;Q24MN25U&l8B!9P1OjJcja7@sWZ6_ooB_Sap9v&wnBqSgpEh#9hhiNM&CfJ*G zEhi-3i{o>^UbUH*S1GMK=8+;?ZBNr zH#aOOC?+E!H83#cvW)1sl-;C#;i`oG{P@+HbK=stUP3JN?0??b!lZUpJVz-KkY-24 zu91{|Vf*96?zxf|5C~C8Nhlf+!Hi$8nu5Tcc>L(gxp+5YSXf(9Qk`Q9Ydi-ust?8h z000tnQchCg%`HPkMV>TkiKMlRLNbpJ8-sIQ|x7KCt?Lw^q7498LZ|!w?94 zKSI_Z%N@-Bk1%%hUW8+awzb2XzxQz{gnrGwMn58uF@O3?0^4?kaNn*F4gf#^!yf%* zCDyLs&ibtr5l(IbSe9#lQOno`k0rQpJ4WX}$wIlqtBZT%(y}>{JC?rwq}EAZvg73r zCRfTB=oneIx#YG5rZrt8tFw2y){c=&kqIGe3uZl=-95=B1eDSb(XN=y%Tfx*CExkv zb}Re|jDK-&N7&$R5$Q__{jl8&*%#_{W9%N*%i(E^4B_BhBNsx0n#OO4>JX~$@E+UqGye&2a>14x&A`;2IyKDs@TqHQ$^;8pstPmo|e(;Nq ziKyXuGj7_tZA6H@Y8VJ9N~G|UQE=z8&X;vWh<~6;D^wNM1VtDvZ<=OTt6ErXQ`s`a{Cq_S%cm;biwzN6SDq;gNn7lM5S%-&wXxi; zc#Ak+)EfXe5<}>GJ*|@@S$q-((vl?Kz1pH?UO_R$#n!qNZ3xEd{F$`46pgZ7t{L%0 zB4TiPMz9l0m1zrbCy7FgGtRR@!x~e~3V&hN1rMhgO_xUO9-+v|W;? zNh4*N=V(1Zl6+bug_KPO%}|X>Iz{inHw)8E0Ejw?QX3Gf)jn%$Ax@H%X_Cs-CV$U% zaCo-T4QD;XvT;I#8FiFwK&cn_jTIc}{iQpy#idwh%!6AHxt3Yyq>B<;VNWO9nR|1%IFSWR*7klCF9^wfR1|voV_dZ8iw=;-Q z!)TmEw70y_fBMzaLl}mD&@=_iS=IrLdp&DM;ovgE^gREekC+8v=+pL86!3jM7~N+) zZHlHM!h;3r_cI85lMrWTD?2gh2?BK(zUPI|&3-e2fSN%JrI$j1>wqx*(0_Y^Zhl<} zF#7EFyTnRPr7#algUVGZ zrK`i7%E48_WFQLvzIr-|{~m4ABE5g(d{+dN1H{zE zmQr$j>GhG|2Nvh{9J+a36QE2_3@vZgu5G(-J5?h95WGKw`RI-aUw=}5KM}(K3Ko>) zxq)_-2wwOwxnl1>zXI6k071{v1QC!TgmAjPqkCX@1Oc1rQzQWVfIy7ELkP*hHv$CT zBv366aS#H;KVp0Uguw$4zONYs0Sd~;w=f7EXFmZ@kjFR%3Mv3SQiPvEW002ovPDHLkV1mOb5A^^5 delta 2068 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 IM6N<$f^at;ga7~l delta 2020 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_388.png b/TMessagesProj/src/main/assets/emoji/0_388.png index 5dff561732be282f215948eec88ac1217c32f3c4..0cec8f7fa27331698db81a51975ddf5549769c5a 100644 GIT binary patch delta 1438 zcmV;P1!4M)5x5JGEPqQcBS$taN+}sbDZ}~KsRVrN?uApe@iVB4G7-Pxc>e7 z!>ELzY(k!9KCp#Y@#)>EjBmMn5^`Wwdud;IIB-$`000bhQh!cU0N3#BfuX-4KVsqM z=G&va000EzNkl{fVuYqH7*lw$;jH!z4>5%-2$@bf-{QR2dv#hqDyxZVVl+)U|Qf&8c zA;(koxhg;aNq^EegyM5;eI&{%-~3;ZbRVjv001R!ZT2@HJDilNRwfvMXe57Wkmo@u z7-U(Y1b~bRjQo|6!j&j^cO9_IOZSra5^U?sH`6az}^A_qt5`Dp6re(t9&^U4bj5gfW0XFWg^ zP&61*r({8(Af>XkAtDAHfSg4LO2L|W)cRgTR~jxDuZ{KIu{pzpwbs>~Llr2xMt>wEXfL?1y1__xzD#v4rfKkX4;$kf z8Ht}4H3J|>D8XeTo#3$OXRwMeUN;7ZQ7HULe-KACl;B33V=i=|{# z1S}yqogGV{F&?HOaO9%K8cIIDVH^~csBr=&IGyiX7|u`M1YH?RMD|1^Kv*CyyzYDM z{eM?~W@wD_u=}<4#l2@W5Jt+Ut-xeTA^|nq*0uMhsoE&SGQ7W+ZP_$mx4U4X_FAdM z8((6TcC`SZbE^G<>({qbgIe&ul~r3cjchv@rnWk`Y(Y3Lfe?My%6JD{Zg&=2z~R=@ zeWCreYw?{x2a`M#nY9WCcI#RIAokp~K!3z(?i~;i?XF#S$NSuyMT?_#7KqEOyBTa@ z9({K^4>tsByVh&nXz^%~sExF4`R~Y%2yulP)?5B~z!M~pVSU&2-nz#FO7vXR#u}F{ zh>dkXaDHuJDS!008wh6%BK@uF8NJ$bB%IlNEOM|G3C7vI#q?K(9R`G*`}pdavwukJ zmqcQ%HML+6jw>09z%}-Ozrs^Cyl*(;k|mKvf-_t@281gb;}1PZv4o@DTyBPSPsAC{ z44KG@*rXrJB;GnxL(>UioLWpM8wpEuENdv5WY&Y%95+Dl0l)_r!Z<}GmN{sTlgte6 zT#dEGQwiT}KGs`k<%SxUXt3IP?|-e~GXV+NoYGZdtF;|!P-qf^MaIDf!D_u-C62kA zY7DdB5)cP~1R#{wf7X9#3{pz05e-fZn=};05<09Bi2_1d6Aex$XQB?LWb;R67|Zj&Vk5?(6l1`R^UnZASI>>*t&U*@<&gAh1^Mjlmgc7wp11}!B65W+}+ zYx$<(BQlS9Um)Y)Eg~ah3<4f@@%^O94iSipF delta 2168 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 IM6N<$f((b!OaK4? diff --git a/TMessagesProj/src/main/assets/emoji/0_390.png b/TMessagesProj/src/main/assets/emoji/0_390.png index ceed35e250e96223db137e8cbd13b90a0a75978b..ee620ce955f0f3dcaada195f29cff6ae6f4888d9 100644 GIT binary patch delta 1557 zcmV+w2I~3e4yFu{B!7fZOjJcja7^2t73{AV?Xw>4wI=z*IQF?3&yo}6sTkXy7WKIr z)0GnOwjS)T8}YUt_PinHsTljgB;KJG!i5sBbr9H^6aVkM{?SYS$twTPJparv{@iu` z#U}jbr2XNJnqdtX5((eHaM`LsZ$1bu9SHx{TTeC-s*qIw^MBG04G4!y0|^KOHH$4; z0000DbW%=J0IFQcA^ETVL4S+ZPpOlb&9i*{IS3{IzxSrIKF$q%6aic|<2wj`7pw zldkmY%l_J5Q?-3wm`#`q)wpOML&sd{<1GwB5j?GCSbsJtgpZ!*LFr5(0tmsMS=n9D zC}^JgSRaw6dG3CBg}Da^E_P3oKyk*j$j2`8g$g^wnPzCRuINnBEqQ36U27y1Fs4TFw7vsQ9vlf6uCc8#L2Qskqv;= z+}Kn_rhinXjn)MDK(&@>o}ru43vJ~^CP2r`m{{`7awv!{RLnR?tz)8`&u8Ko!v+$z z65P=d4&tyxP<}!fErdXdl!ze?iBKeG5cSbY6c3iOf*cC4QYaKsz;Uo^5@WFw{)tEH z5xXS<2_RxC5K&bX*`gLAtz=t`2-vO>0NgO;34dNyr4$)kh<&i<2F^;3kDMv@NmrVYDcoD-+tdEYK^H%X=i!G4lv4gaXO46@W`nh;fM6 z7`9q-j(S807_4Oj{|*oX8W})PT?xUCtMy{*jNs?c_wD&|yALoYz;OS#UCu)Q_g>6$= z76EwiM_sECQPuT@2;JExjYG7CFRB_zY6YRfI_WQ$OLw#8t)6`3^;_Frx=U;Oq<_YK zz_g6Z=zBpo5km9Rq9j|8h7qF5%ci$>Xp%B5 zCZ%Q4+^y-GGOq{`Gg#g10YI#Q`voV*2U}h& z=4O@hyB{jYqN3}fObkVfv41bBpb8Pd*;tliZH0ydA%blC`R-1f_%xP3TA4A#SP@U) zj(|3P&G2$33&I~6>hA>4&;;RP5+{Hr!Y{QsYGeSP35amq{NY=Fz_dh&!vMugty$o! z`TIm-%!EYo@|P*BS25ao`)&BNO8xzx7(s9hf?yy0Wa0ms)ABbVv<|0S00000NkvXX Hu0mjfsI&Hg delta 1880 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 JPDHLkV1lusrhWhb diff --git a/TMessagesProj/src/main/assets/emoji/0_392.png b/TMessagesProj/src/main/assets/emoji/0_392.png index 40618729eb6b68d75c66f5b57ec7340231d55ef2..d287c466c39b63ff8402e9482b5976536ec35fed 100644 GIT binary patch delta 1725 zcmV;u215Ca4$TdaB!9Y4OjJcja7@?4eAUBxynj=EYMo%zwD_^z-Awo|SGdieNiT zBMzo)LhR$9dr~W4H5};OnBlyZaYZGxj%%fof+z?8$GD@8a8@01c$xD-e>|D~Mlc-@%;WCQ4ZCnY82{8V>C59=%hBvl)E^}HE7<+n!HM8kVX+63 zZzIe@9NfWC$c}#h|AUM}NWkwu!r1|+V=3@97hf3lw?YrRZ~o+ZYT=3>XZD08Iv= z27fp(hszax>Dl6noMI;^Tkp^3{hD4IsJO-`kCDieii|;#SOgU8d=R{e;o|M>(7>?6 z7AnTQ4uwm!f}A%8hyYx0Xv+mIK#;@cOhDm6H@+w)W}0w?!PXa2@J9ZnX=*_(Yi0;V zo=(0jd#RJVgf~;n=@K)vh?x-&3o7C~cYowHM;%}aR1}78TrNZ}P_V?;5+#NHarr28 zLnwkgS*Wt2?s<3Z_tnDWwC_O2x^Mu^Ln${zgAjNa78XFRO%*q04cyw9$w4M z%gb}6g98sZ_3HUhKfk;j%E~AVP_W!`Zz~y6k~35oC%E$sZr<$6)_|Jwuz5bi)qm&u zgwIxxF-nKG3YV~qVT!6=zaX1)Ri2grO7yaVT)-i#D`iP|@uHIkka*2xl zmd4V0@#F@epioFzU(Wm0dtTO}8Gjf8#O3gSLZp7ik$)0^f;(D? zVW6Ub_jVmEcq;-WilLhlGf-eNt`!E=P+<_`st{apP%-PtOrI1~h)Nm>wICLjPDBVm zv?5ZJr;csT=;0BYaTVi4qbRoUPb_WLigvY79v?=%E*_KsV;G;6Xu*~fXlQIhU@IPa z-Hf1;Hb$YFc4+$!V;M_4Gk>%(g9w3jjP5AZ$0&BGhA}iV+yTcBwng|g@FdKI(!5GBQ91r(L(uU3V9AXga#!?-fF=)101N$rR z_bPLx5cgw{2=+2ju-|;L4g%Q6MTCclAjEwhFb3{)Gy_@^?+++AtbZ@qM@>Tmgpg-c zo)lgRw$uQP0kH#%!VK{XXppC)yObsejG)3rn%@Kr0hI9#!^S~GaOzSJwMI7%f?@Al z9)zPE2WX8BGhicr;=q1j5VW)&DjB}5CE!6QX`m=T!?5>5MvoDf02F~w6a-JB-jA8i z6fObKV{t(=oA!RgXf^?oCF)Al9Dk(B4CN?oK zOF}^=BO@6W7g zx|Nc1Sn3)VSlajqJjnUoQsa z+|S#fdj9|NsB=|NsC0|NsC0|NsC0|NsC0|NsC0W&i()INJZU zezugbGM+e60Dk}l(@8`@RCocLlHqQoKn#PsU;~?^gEM{qcRdn*-S*m6=O08uie-P9 zw{P?)-Sh3g^jKDK-Io1Wu`c`D$_q3Wt!&(Ge(dc=Wx@d z2+06npTEk#8XVos#WPwtvy$W#FG<-yqW%%lm|sq^2XoG#=B&kj zf`4kS4>mV(APm5pJh#1pLKQ_49bp?>FZus}?7k7~IhgeFtt$_CcQlMh!p0YrXFg0v z$bWdE0+#n1P9>r0R zBmp-s5$ACn@i2K{CpmzMC1`+v!|!Kc{}N*&4279B_RJsl#<-E*Sfamg!M#(8xv5JCiyJm z!GaLsje>nYzan&lW{*OtqEuC#BuPCLGp(x1k|b+d$Vvrtw#9C)=2ygA(O0R8Ho3Ox z!acSHbz+PxGRsW;OM^n%~1BJ+h1l%&^2UcAKXg*%66g7@>(|wVka>=qHJMgY)wK2I z?L_V{`iYQA)>XBt62`oW>L}iXDu44T%tNxSJ0)>R7<<0F{cb#FaUo<=^`6runBaQd z8o)U1+VMINPBql2OdmnaTY+r(^^+DNZThvtYzU4&wC80E4P!R43i@>;M8??b=91V1 zPY*g3-9QARll^`z-;B0z$Yn(IRVwt86)uP!h#0%O?|aX7Z07mA@6{wIz<;g{!S_2H zO+{@#g}Vi@_pWu9iX6XXwOaXy!_W`;ndoaAJseO(DbkeNkI{m7w-1vDgvf`!O8i5x z?uXANqwM>}_YZvNO9?_J;r?ooV-!U(2&r)TFaS_*gFPZR2tY{?o!0SjNoDv@3Kuqgc=JYR`K?V_~3egF4K&HZcBVZ(=)9H%>t%Zom zpa`uyDmy)Qf`smP_0@dT#*kAPx$HP4785B)B0hbcxDTnJWK4?aG=CK$)vO4#^6U8& zPu-wQ&7*bYXW`pLP#H1pH6qN6O*yZEmSKwcZZ}L!83s}`mx6-HL=oT2yYOsubrxjw zz_XFk2;VINIYne(G5E=@*%vzY zPyryk#B`J4#~&Ba(`^VO(qObn6h-0o>gTcp0%Z#4p(){~kz+`;KnnNUp9dyov)vxI e+YSEw-_3uthYO>U70A>80000wSZuuYEpqxFeVHHq5eG`)Wx!o000FJNklQ&WDy1BG{|P2 zeQThMBL(d=MwCT6n|5SvNrqw!R`!Y9PC2q!TgV`2X^hD4&{?vYs-)m;6g-1j0YL-c zuzb6kv$7OM=TJ-;0H;Bgcd0B{oqkAEPHw?Pyw6qV5&`Hpzw$lk1H zfs1qnjNu|!3Jh#ETA~CF%|X6+Q6xo6X&MtHT1O2a&me&#Nb=-0k0R$#Xjq~I2?a|& zTGyLH*zvk%WeYtvXPMCEF2Vfb3rK=N>+q{|q)5x0)I3*>Bn!u7u*6uzR|?vIkmzeM z7DZH)-hX>oN*6pN8qlZ^j2v1V#psD$EejD8O&x%ykr2V;>=D5X#kYy;4! zAR2IS7dk4kR|SHwbyTbaB&sPh*np=EyPH;k=4ObFO%#!9jR9&nYo+z1Lbqf9m>oxi zTsV(m0XD6OK|oL|RYwE%Nc?Uc91RSka)O{>p?{dlas!0A3D&eJVF0&^6h4RJNmGmN{YrK1{jRyBz#mz4zz(o(Qs#Ix37)&yLhL+K{5&9WR}{bX}GAyFsz*d39!8XU@l69Tn22BZbmNC`5TW zx{fgU=^>2Msp<&6Kc1)-qB5!(DH^XUT7QvUf8585i@qPC=z9|s?cZaMFchz}m(NR* zNiQni1jWIas^cGjkJllO>v3;TpW@>{3a@y_RXKXhX3BONitXWgJm>Al$47sBhyou9 z`gV7`9w-sr*=9CclBAJ_lcL@n`orhvuD_lh%Xzx?=g+_R)rQ_e4b!qo#{Z&9$$yzt z@$TFa&-dqgvm>?yDY%r&ks@_Y2q=Q%{?5Yo_>2tiLMenRUmi0kxO;j?$gsWtz=#G? zD943!*-Li;g{5LVI$%Q%^ph+^%)>%~YK~Z1QXrE@1B^J-o*Z8WQfOh9ZyGJGnH(}9 zi=xjo#Xkm7E6Fr}*Ewd3xp2)>F@F?ePD*E)T1Vn~C@1C-^x5j9|6qJEm z9(*y?H1d#1tcIuNzZJ0$puXNi6N8Y9XA_FmoVi;;_h@^iBndT|bdE37EePZ>*@iEL zjbZG=wEY9YwkLyXtXNJr&?1JR#I4U78XS-dp=ysH7(*UYBrJrnHx<#*7JumC(MYO< zWeEh|hvB{Df>~?2FLY>ntoQ2sAix6EXuPi@&Qv6*Oo=)YJ_IqW=)|HRmAhkGDGFkT`ERMgt1*BZr0K zE*S*!rv^9}vo1&m)Nc$RolZkiHjvzDf&hQ!{+QKLgh*r)k)^Yip}G1EX~KZDE?^-@ veip*`Eye_k#JAM{{7;M|SuWD-yA=Kdd^6yGSj=NQ00000NkvXXu0mjf5s|Z7 delta 2041 zcmV1#D`nOnq$wIZ`!Yj-?@_AwSSJ|!kpyApW?ok(yf8y z$f3A>O=~_P=gq0Tnscd$X0mulS1k{SVM3L0QPQAzgj_DWtC2J)8e2>-&AOmzJ|gVk z&=U^{{Q33Qr+~S3Ov{gE(ToArqQd3?002XDQchC<5+%FmHI1++2?!8a**QW=D z_}iZu|2@vXWI(8AsU1kr`Y@Y^aqUWX&tvuvl*a_oz)%%n%$0qg$Vy9AWg)GHgt#x~^-zfBY)lmo|w>Ywg8N5R*o4Hpiq?n4@zh z*%*-5_CTb^&jcHA2#UTIaiA77hV#$lRPJ`*rGGAFxDwfb;3vjyOyN+WU4rP53q!s* zF!nf1%_IXA!o7kT5dGA$+XRuU%5o<_EoUYrX0zTqc%~zCQN&s*AQ~$hVjoAV%yA zN8L%*G)Qd9+xL-jT$TI<5g2Ey=khAA=ivyt<~r|J5*@NAf08&r8LxXSrwA zdcLl_UZ1a9Reja<`MJ*rNB35V{OX0jYk%m6LfQZGQ7*h~`cM>C`&T3NKb1~$u!BoF z0>p2ZM@d*71Jm~Vf2LhGG!snPi4=i#`Ej{E#}P##O(IHZ1cE;jB?$#TQ-8CG5<)hV zK-^%*mtdNyxo)0e;46YLg&G1%vpge|z>Qx?(^a0Q7^mBu&={=>IznUr{Ryj-DRg17}+z{qHVxgDkKL`sc|B8AUOa7-49 zm&uMS?(Xgbnh*oE|CZHRQNX~^Loh`Ii~sKzgl?rTDnB)Oa9p(hiusv`V1V@m5mU4b zFcubS6|3sHu7C!T7b)SFj0A|48GpqgR6kGM`C23>z%jR$*G1D5MX}R%1Za?|3Q$w* z4KP};84A!WX6v5?MscRC-8H+~!0@FSyBH~)b5`w(qAjfe-!A_;b8cS2Ke&ZQDx>^I zU&lI9E<>`sVpi!K`BUe=Sr-t4Ff^Z~R(e}_#s&06^Ttrhx7UWthx=e2)qfb$h&)2; zwyMJ1@QW4H_-{4K!@R1P1jcq11aUHP7U($uZyBwns1JvzIqr;*)?Rw?KOySmc&g8J z3yf_Xgvqbl8R991a5JuX)t#Gf`@TO}{-+De%Q~^AzTbD1fj)h7U+2f~3q&dxoVT4j z9UlSFR~^50ARkuPJY*3Myrj(Koo8Npzk3vNJvuZ#e|rRpnZz< z|Npe-T2V2GEPCmohQ#30xzo{5+mH87VXQ?Fn7}JfOR!IB<#NHi-@UNN9=W(;-a01h zoF_?~nJ>1*DSbCd@?lZX z45Cy++hA&j3{Vvr1+C~=tSw5?95BbvE5!M*Hqzb-M~WmqkeqQ9|Jc$-}{*9OmsMQ%zF;DiE_3KDAuWB2KRr=YOr_XE(6$Oj7f6h(C&i z!ZVn!F|7tR|&!?oVi=ZmHx$F)sQK}<8 z?v=k>w_3wM5gM@F0V&*BK9#TAkD*^R{fWgv77_FP`wPBrAqEL#my29Ef+LlQLYM}lz!j@9lGFAWzT zN^#bVrDz9#LxKfQ5zg6ds+}C>Y>;57Si6~l5S?UMH#A~fr%^#SBd29DW;vaS@T>d- X157;400000NkvXXu0mjfx~&oU diff --git a/TMessagesProj/src/main/assets/emoji/0_394.png b/TMessagesProj/src/main/assets/emoji/0_394.png index a08bd8972be6f461db312596117ed6e472dc2280..8f6c5120e236f9c2acb280e68335b8ae73f4750b 100644 GIT binary patch delta 1356 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_395.png b/TMessagesProj/src/main/assets/emoji/0_395.png index 7ba6b424e56ccd62c1348dad4691c6d21daea748..0cbe63a2740ffd1d1f06aa82d8b166ff11ff9fef 100644 GIT binary patch delta 1237 zcmV;`1SF!KT$|X zD<>x)9UTq}3mp>=F(Vu&8WTM$B}OwXPB}7FKsH)NI&WQ5gK}u2l!COXpiv|S+11eY z_xFrj46utZus-;10000GbW%=J03}Itj;qlA|NsC0|NsB~B!5(aWdHyKD@jB_RCocE z)4^`sR+NO{uMR1B#!is;f6m0RV>M3=v>Bn*5R&}Tsuv&XUXt;7kw8^_+Gj*2Z#9jk zZMXdo#LUFRdvtZL{ySohnRtxuUhO{;IX?rS+uQyFF=q|{P1BSV($HSF@;Pyw6YBHm z-VZrG2uBn)|9}6#*}j*ZO#2xzPm{9Q&Q_~cg-9Z3&g>^do~FYp1&F*AXB~a}JKNJf z-Ua5%o_U=`8uuO7!F$*32H*sc)5w==g?t160(!Xmc#!iXk*SAjIuH$#bO8n+PqvWf z^8gfpiwhONk%xnf&7q;0)TI;zT%ZAR%=Jj*NP#Aax_{7U8XT8{%7^3L`ZMncCa^}N9LcrL>Dk4)l#vn#fDG$V+W;x=hjbYIc zNRcKq8zg-v2rPy~)Cy@lw2Oxo4TuPdnkuog9-HN!h=2niQA!Vo_nPLKwGS%*27(Zx zQ}1s_1%JoQKCWni1PDL`LIjoG0Spk}NeOoAL)|SQo>=-}1rU+#>#)9z_x9(3eaf_Q zH)8;W1Ae^T(l+_&JwK;yb9?c3?HBL)(zh@$=HVa;g!A=j5+6GL7wx`2 zfz9j#Q3i4xC~;p!jHhSpcseiIfx4r$5qj^HlHYQ(R~N zcq&j0-~jUU+fI`3eEfYrz1;rCaRtCWyT0W6dYTI~&%3|?^UV}`9@p#M$~i{?oO64= zT|8gMS@%$Hf-Z_@X7n}uTWCTnAG7KC{fNbwptb&I5>c!Vn zntuW!x3^z^&+9=Ubx#;`A(!*GJ^e1OC_p*K@A2#GZBvW^9DqGFli2pSj{IV80Ic+O zdOfb|QbJ#@`xQ%OM_ku!me)1_>?ZkJZ;N!p<2S-=AY7>=-U|z&%1-UW#~y%+NeYF6 zL;ywfBk=eg>4mtYJY()Xew0;{YbcV0flPx+P8WYl>)`~=EHUB zpEF<4fHY0hMRI?5{M@aNE9`AIpr~qW+peI5D%tC{9#&x437}qV&cR++$G4`aZq$46 zUY@>+gzR?{wQ*b>()C+Zb@TFCk1No!1N(Q1IOqWU{1VlT)*}HfsPq?U6+j5To__;e zJ|p(~x9relJVxop_kAE9W*lqSrfD=yVomg6gm5SRrV~hGFPg?NG(|W5x;+y252X`9 z#V(G}P`YvVI35n7wE>D2m?duER&;3ylDMO8~X;*LoyA80VxBkh}%xHvYQ& z6Jf7sX$V9F)VjaQPYL__McNPm%1$Q!y!;zNe?2E@11YeL{<$8D$H@5&#lRALztz7c znDZ;3Y2f9y{1<|m`3m4=cloabNk*z~`LzE7x_q&~8i!{;00000NkvXXu0mjf5eh=- delta 1622 zcmV-c2C4b!3Fi!uB!6{KOjJcja7;fdAw(-5P%t4#EgwBDCom)*MJ*vbC?7p096Ti& zM>Z}}KsI4cLpCQNE+QRrUQ{O>7#0u>9~Ke{2nHJz5mqrAc19|JPA-X5GLc&~X+0yC zU^$&;J)vnpp><5au9n25fUk;V=iSiQ$*leS`M7%)=z8?`0Dk}g7IachQve%%*X#ex zw^N)q|NsC0|Nj5~|Nq#Ibd>P`00oOlL_t(|0i06@w(2?%dp97OCK6-u_rKL|!zr)c zCP>`ps5n2~!P~-W*ZVto+YU#Z&f8@>9S_&bkGIrA|w*4Cr~{`P$W+u@tArq=gGbxsRgmfMTLHhmJDwn z)YuLL76VTt63E(X(eg-o!l&u%zi}sc^9l0GL^}>ruA}&`T z3q9K6&Jn!h$R@Zmp=XpG-j@xsRrlSa1=&lEw||Byxqmalg5|DNp;muddaqs$(_`Yl z?QdEx_Z@&U5)x9d?@u$)Ua4T|n^Qf~l8)P-73xmFR*wLZS0T1Vg(A59 znMMIJkcMRUkR`r^0P-S13rYkM_`}n4QRt-O2IZK90X~_OyB7smN(@5Q@Au=hW-~_8 z(|)>F9DlG;6U)qK@o#qwfl4mFe;JSf_h_yl)2P|{+0z$!{s+LjkP+CUY46>@<_n(&BZ%ZqO^ z8v~HtV{}KIG$>1`-y*pPc?_e+NKa%u9;4@LPJg<4JjZKhB!=1o!OJftTFT?mJ$GhI zq}B7#|72B%dbA)A{L{O9Dp}fMq4@rf_|I}CInS|EhGCm}XdfbgK&0qt9D2zU$Utx% z9fA$WT-}=n>%0pTj5WAhXRY_n8pqziXL5@9Uys2FYhf*|T--6m$ns>qd`^3#RoD>( zA%EOoZ%c)ey@%-<5l6#?WNJ*VgNa6Xzq>!0Q^HwmVi|XakjbMlSuH>vJyNt%Hz<~+ zt~KmO{AG~flt&kcD8y?$le7iPZ3Q#5(Z}$-`v$KX2+MdHE<$-% zFJ|Q_46V7dX!Xq{3L=g&5ICd3B1)@ZJ%4i(bR~qDy?Gk6j3M|>!r~-D_a0M>oo=vi zrGbqHwN+sFc)7_liDM-cGDk!l-6|%648EAwN(!pmRF#sdoD5*cGaw|_;3%!u3xydG z6M!d6tEI_jfOfqNu3LBIF8P?@#1rpJ+XJ6{40>v<_h5s1V+X_1Q(e$B=rN>Pll4~h;q~-KrCwR< zVy^W|)(hKO>l`m$0G)lh*LkMul*(DT$bS%zmBG87|zM9fIl9Hp^s?o6U( ztc+SeAgY9g*qwtKuJeH!i;-itQQlLYdp%Y$IF;C$rGzbE+o5)vJ7|vXk59ja8W2Ki z@Fe8914Pgi`x#pnDq}(_n}4(YECeOyRqmxz4I(0E$dzzVf*P|SM%FULK?yQU#N5Mf z#O>;b1jbN_;~J!<;^zb~>tJIXl;8n|kyt@0_PI!TgJ6mne1G`8sFPvIITp_+FCX#* zm{9z10AMs2LU5Kt_TW2>akLIIgjjDo_5dTo;UbjY3@f4pX&gfs&rbmA0U|{KI4@vy zUdS8(_HaH=t_3m09Qy~*y7PjH3?RnX&y-F>Tti%gLfU2!a6{?cFbvL(jPRfN1r{ye U;eS=0EC2ui07*qoM6N<$f|zdh{r~^~ diff --git a/TMessagesProj/src/main/assets/emoji/0_396.png b/TMessagesProj/src/main/assets/emoji/0_396.png index 8d0417ac0212fc1b8b0d716c0e017c785ecc6c82..b1402a5cd9779cb7014776b8c5545aec344a33e6 100644 GIT binary patch delta 2066 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 LNkvXXu0mjf`bMR& diff --git a/TMessagesProj/src/main/assets/emoji/0_397.png b/TMessagesProj/src/main/assets/emoji/0_397.png index 7c13eab13472ea6635f68bbcfcb425a374390e51..305d581854c7a72aa0b356377e25601e8d19a69d 100644 GIT binary patch delta 2012 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_398.png b/TMessagesProj/src/main/assets/emoji/0_398.png index d29d383330328fd3f94eb1d58a8d54b8dd538599..523a084a7a49c39110b887eba9574454a81837c5 100644 GIT binary patch delta 2430 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 delta 1944 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 AWB>pF diff --git a/TMessagesProj/src/main/assets/emoji/0_4.png b/TMessagesProj/src/main/assets/emoji/0_4.png index 3a76baf2b4b77695f53e1ce88e5488a6b3ee8a0f..55817ac00538b547eaf8e35d220ada7ae8ddc781 100644 GIT binary patch delta 1615 zcmV-V2C(_>4fG9=n}4~KC;j1G|M!po_F4b>q5rf8{g(s((?tK>QUB?2|NYl)I0^sz zvi;&h_@xh#R0VlK2mjU+*1k9Y_kjQW!-h%(|Hcph@Iq)W0sqH0|M+d`(mejRAp5Qs zpLr(#X!}w%q_Wq7Go;{PZj|Gz$*XOGoZk(0+Sj6A%CPvL_t(|UbK?u zZrd;vMiar7hY%Qk3C^Ltm$$Rp_kWyT(kh`iPMWmnq4bC1cX02e?*5ti-T!B<`P=Yf z;<=8q0vyNnCW~+9J!kc>Z<;1ItJy!S9Pc}piMvWT#Pj@g1WtJl7M`r!$yWu=%;b-h zu&N4zs)~po8_Uf3ihpG8K5D_ykAm}vpep0M;e6))v7L!-A&*%QoCDwtOFxDP=eiy5 zbHnnH^X5b<2*5kWY%rw@SvMg}BLrrx_jtORd-QkEqtt%kf0!&jg9{u3AL>v6cyhVp^(0=Yps0H^RS z5$<&xg7?0m+>{nFEXxM+2Fb;Aa&;TYPGO8eu^AYvOnN}q;A35e^QMS36oEB9MySA> z55NUNkk?$7;eQITmrCh6=;5_X(U!i=QoXh)?OqQQ@^Dn{#CRHuwMc$QsWfzh!j~?4 z-qI_!&sp~pB8rtp%03xiiZ>NWF9D@uMQM>{S(l-BEQk?oWobcMI3kq<#a>L8R&ft~ z^u`ebisD0Ehh18v zg75!v_TFoookr=l^R_21rm=rI=NMUW_jPwX_9&c048}$ArU)m9z!c%K>vu2<2pu5& zhoK5YbbrV8*#8X>JhcxY_q3KXnTrRt&=|M2HL&Q*q{rHZEu5DW+G{A^B zxPUS)B&dRWoJW@n0Ep0bhC)f;jfg_Xwl@Sq%r#Wf0@^cDfJ%KUz2j z0pyJUs*3Tu4+zq~i1r8!Xsp+2^hXJL&~<9W(swk%@|UWN+KnhGO}-H!)Oy#|RV;n8 zsekrr31xtdxZpC3x{u4750uW0y@E$zf)KWO!2|!DlE`aORf5Yn1UDLB7;PK5q4dh4 zDk|aXDpoUd?2RbNxsFAizb3`?S_tk*8OL!*f`OE*6cv1vWcjv?>N8a_GDqKZfl2m= zNMF|LG|#q40ibJTbOjYfvVG0d^?JQ!WPbv3EQVvtTB$v8%M50`JU>6btkX2#Y_eBU zw%O!qx_$uxAr-Pas~p&-DMQ;}$r>2|`Ef_j3XzKtOkkM-Rbi6&I?09*0J){0HA18b zi?j*KF>I?(HXdJ;pe4p#Ln}fU@j$n%B7J5a8Cv+2zbb;oM)vn5V?0iD66_ z*@2D{BI9#$FVcj-zWv=kUzs{M`v!rw<3>*yMf>1i5Gcl-AHlO=V0ib9FfOC>7(AF5 zx0+a*F|H$dhru|D>w#e1y(&!|#eaaagN(2nfOPAPLcw6Pux8WWzi`iN%b9~5%bq<<75?`%A$_&-|L`A-e*oTG`g#TP=mG!$ N002ovPDHLkV1m~46-NL7 delta 1610 zcmV-Q2DSP04et$*n}7Y`UjO%x|Mpq`vD|L{U?I0^s# z*Z=#n{o+FSr4RqF zZlgdDMiYebf+FNg^v=HTc+WO-|Km&*CWtt8CYe!Q!=I+Vr>bi1{+q?!&$B@OHN4bK zL(?ok(+pEzemie!*2B(q-Lzls?!nT`?^txhiaEs7^zjHhrYTr>Y#I7j1=_sN9~rfq zCJ34)q)F6U=Gs>z3xDGY1;-=|P7{Krj8d2Lx$)O_bZjAw>>xM=zzG&UJt0Z49rJU; z>WOprkv0&(cM5LUH5Rg3e9{C=fu~7xW-4jkpa;%{w!Cc+oF8ZthT#|q`Za(bY&ke? z8l)W#H0T)#A&odD$-dWCWTPLXXa zjLS9zcaom6D@W+CMmo$Rl8c#saU1crCWL^Z8$i{RZUAdY2$rF}D`E{r5F{Z=Wu&_S z$&`XTa#@BU#D7lKHP*rQuWg|=?0uHu+Nh#^-80C;QMnb)QFT$JiQciCSpfQlteXSS&`>$uA-?RQm~a58S~(X1cP*TVzwF;_t1ya zJ0hTFWM5T&TVx(%@WAV3MVnXEp0KEf6A}#$baFrbR)1?DwhjOaka&^DR8dsEue<@} z`&CgW=0$)+g#(I7CvYEsim}7qRFNnQz)SREYrz=Q9V!%1YqHtBF_LIfCL~4-gpQH_ z|8w>|X9m3`HSYbiuODhFJUQpZ5beIWY&H#Lhp-`JmVRjAh!unus$H|gQ4lU5ru|zL zATFD7(|`N}gznngKzd%D9Rci!$URR6+p5~tb%Ws03y518_K!~@E@fGgP{Rl%ra&1L z2USQ<%CM>cuuxuz`21nFZGt$lVGsxz3>J(5FcYDkp+q1M(e~+dh$hI>JpZ}d*45S6 z{mk*lps5+)Axo3a1jl5Kb7=j7g5HJ4plQ&W4^l-?eiULeyfYvC>&<&KAr-$^Axu%NQ z&=CC|Z*nT4Y_)oi)AKpaq^DFAMF9s-loEM%z$@``wa&xh#8veAhIk&+CVL{1xA{C- zE!S}h=zM5%M$$B1zps+{e7+Vu1ojwTZ+~0XOkWc>U*d?j*Vos#d6KLai{(3Kxmc`{ zWd4RgNHTRf={>kjQ-&Es#B(x${P|5@HL=P93_)f3sN%NC)NHa~0!UY((U?eL5t<=* z4-*@kkP(V(y-2VMLP*Qt85`77oJFPyvqyVPv{6Jk60fm3oG&}*ma{C+MM!I42!DM& zZiSjQJn0D`$wB{1^oUNE@9Q|u>1-+RVo>b$5Do*~F;1=&9)*tmH9~kgQt351Lm;+q zRtdAKlIU~fe>|y^|^S_@b&f_!x|Nmh83;ss@7IZ2C9smFU07*qo IM6N<$f&}drasU7T diff --git a/TMessagesProj/src/main/assets/emoji/0_40.png b/TMessagesProj/src/main/assets/emoji/0_40.png index abd1b0c239dfb7ab849d01c03e9d98ea90741928..ea49bb5b2a3f19c40d640d54ddc9de3c8dfd93ae 100644 GIT binary patch delta 1497 zcmV;~1t$904C@P!B!8$-OjJcja7@T)2FGg&=8727dKS)l8^>)9yLmpxf-S~+CCF|J z^^^?kj1caeAM&CS>zNPakPO|13fFoB&~5{$X$$}Nj{2w)|MOY@)kgo}Q2+X&{g(v) z;%5K63jh1G{;w4O{mK9IY>!n5|Mh+U{^0+-DSSc%{^&aY$A32ez%>8Q5znwN|L{fs z&o-W83;)zF{&o+1e-v<3{ATMY}wgJg#k$?I;B~@9w<7}+UiqOwgimc-C_}3t0 z9IvwCqX80seM( zr)SdflCCbJf;BAbdj?h=XfAp*)~33?mJHTVz3n3gr8O7>W|_72d9_MWntBhPK&0(a zTEgNoYkzx-WNpggB5`lHv#7N#2%WVSS$Khw8*=p!d~a1~1VXew_36w)0PU|HBQvI! zQURf?5aQHzuMkP$>?Dw~N=Ye4lU{6I89u^PAuN0WuL89qinEhYLIF%1czP-H#qfhf zD(I%Jo2ECBh_g;E1qqwH(B!WT_py(SojRYU?tk&IoA9yEVt#v{o#6`-9rn-0+$Vo4 z^P?8KZE+Kbq5xdQm`y106|wZgf}qZjjG8y+|Npa|xpyYx4yE0e_9(Pi@^J2TA)Q^M zP^w+qu^lhBVXEtCxLthwv$0)qDIw&tndDG>Z$Q9U@z3MFSv1e0v*;_2`&4j@ykfA8HiqMt!6`A4Kp+DU-EA$ZFK^*ra?2k;a zp~;vg5}-JUpRs@#;*?$E4MCHzfKdM+cz?7NLLvu2lMuoS!To{2BNE&umL??3B+>xf zW1TmM0cQfXC7M(IBGPM~HEtQ+SdH<@bM_^q=56M@P6PxmLrP;Pt&}sMFvJyh0sP|#0MM!N((Kdlr%?Hl!+yFRpFK)H4Lgjmu-T-C;pTj}Hhr-EG-)pnnp64tgiHhBKC$K6O6dP0qIo%uqPNmB9P(NvjV= zHav#gxka#qR^iLxex4qWdT|1FR8~|XtYM7;z`bovZy`CNZSVD?JFyU!aNA%5`)H=y zT}c;VnO>@MS9_sKEZ|?t##nT}^oaE7%?Q25Cau6fR^ce#Fyk!5NL*;yVia?6AT}0Y;b<2T<_!k+VG&Yr z6Xt8yazcqIwnCUBqG5nQAqE#GBLG4a945l-VlF}o9F`zDpo(|DKUhVK zu!7{~LIDDz delta 1608 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 Sa;#PW0000CmBVj%) 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 KMNUMnLSTaP@uwL8 delta 1523 zcmVT z%)X~VRc8#a<7|+De3EgkzidHE)k%Up5E+x`&pMG!hch_Lk{5p5qG$fal=)b*X%~N zxcxW-ZrVA&KDLwteI@{XIAMgEGHCu#W{a?ugsU3RJX-|N#Mn)I*lSZm=!a9b2j|KW zYJhtBHQkxXtMgwc=Axu34us)a1$VTjMLRd{dfxvfx4(*l#PXE2zf;U4G#`CSz_}Wf zh5j2RjSrw--HApUH@Ei;2-{{0-I?A5i*XD#IG z$|+G*5p{~hqz0DfAQu(WYMYA#4a|*<;JkOv4#At8DIfCRMkY!ukM-6G8W{dnosTHB zD5aQ8j5&s2T+JcLX?YD6}GQgJpZ#A`WK?wRNJ@>c#~`*`7P=EMqtjC1BOl4WTv8MR)Fh zV2Fo+r5)cdZ#lIjv|J;53oRqscoJcqq*p-7EAY=qB>YMJhLEF?Z*|!0UfUUkgM^r&zK_{0T4#iHyyl;^=)w)0&oFNnhs|0abu?r)d z0HH-T$tMW6Ak02*RQU+NJ`g})TYqMgWJt~@h^#J!2qK2G-NW%Xr=r}#Nyh4ieLQ1A z4>_DQj+uq}&ZsMr@#043MV05M`d2TAqpBgis}^0|Ktbn=$b8Yz;sY`QanzsQJ5}A{ zMzU9={A}T+#s-$tXB;Yrk1z1@V6^e)hxbLk5}Zx|ehnBQ1mgJoGQWQ!0)LnNZiG)E z#q7kU8bwt!Gmb~QH~QC5{Frzj4A}{)@kv#7BV0cyWGBi6Rx}5U;HV}${rva{rDZ?y zUNt-M_iWHl$$q>Qb+#Y%DKTL_e9lBs6c`qE!fzWI0FemyUXD_`910Mw$SlM!2+C{4 z-&G5Y3?Xy`A`@J(O?+Z#W^AmA0J0AP;X4KpE?pz>UlU*`5CT|a1A@>m34FyOAwU)Z z5WX3HtHT~g)S0|}OlsOw&F{6V&H@D;Ih?DnTqt%iD5Ca}GrQFP5dZq9_f@s8|Nf7Q Z{{T_h#-(0Uz)JuC002ovPDHLkV1jFN%rF1| diff --git a/TMessagesProj/src/main/assets/emoji/0_403.png b/TMessagesProj/src/main/assets/emoji/0_403.png index 1efec3142a93ef3bffab44348621e4ab6dd2c6a6..40618729eb6b68d75c66f5b57ec7340231d55ef2 100644 GIT binary patch delta 1788 zcmVF)Al9Dk(B4CN?oK zOF}^=BO@6W7g zx|Nc1Sn3)VSlajqJjnUoQsa z+|S#fdj9|NsB=|NsC0|NsC0|NsC0|NsC0|NsC0W&i()INJZU zezugbGM+e60Dk}l(@8`@RCocLlHqQoKn#PsU;~?^gEM{qcRdn*-S*m6=O08uie-P9 zw{P?)-Sh3g^jKDK-Io1Wu`c`D$_q3Wt!&(Ge(dc=Wx@d z2+06npTEk#8XVos#WPwtvy$W#FG<-yqW%%lm|sq^2XoG#=B&kj zf`4kS4>mV(APm5pJh#1pLKQ_49bp?>FZus}?7k7~IhgeFtt$_CcQlMh!p0YrXFg0v z$bWdE0+#n1P9>r0R zBmp-s5$ACn@i2K{CpmzMC1`+v!|!Kc{}N*&4279B_RJsl#<-E*Sfamg!M#(8xv5JCiyJm z!GaLsje>nYzan&lW{*OtqEuC#BuPCLGp(x1k|b+d$Vvrtw#9C)=2ygA(O0R8Ho3Ox z!acSHbz+PxGRsW;OM^n%~1BJ+h1l%&^2UcAKXg*%66g7@>(|wVka>=qHJMgY)wK2I z?L_V{`iYQA)>XBt62`oW>L}iXDu44T%tNxSJ0)>R7<<0F{cb#FaUo<=^`6runBaQd z8o)U1+VMINPBql2OdmnaTY+r(^^+DNZThvtYzU4&wC80E4P!R43i@>;M8??b=91V1 zPY*g3-9QARll^`z-;B0z$Yn(IRVwt86)uP!h#0%O?|aX7Z07mA@6{wIz<;g{!S_2H zO+{@#g}Vi@_pWu9iX6XXwOaXy!_W`;ndoaAJseO(DbkeNkI{m7w-1vDgvf`!O8i5x z?uXANqwM>}_YZvNO9?_J;r?ooV-!U(2&r)TFaS_*gFPZR2tY{?o!0SjNoDv@3Kuqgc=JYR`K?V_~3egF4K&HZcBVZ(=)9H%>t%Zom zpa`uyDmy)Qf`smP_0@dT#*kAPx$HP4785B)B0hbcxDTnJWK4?aG=CK$)vO4#^6U8& zPu-wQ&7*bYXW`pLP#H1pH6qN6O*yZEmSKwcZZ}L!83s}`mx6-HL=oT2yYOsubrxjw zz_XFk2;VINIYne(G5E=@*%vzY zPyryk#B`J4#~&Ba(`^VO(qObn6h-0o>gTcp0%Z#4p(){~kz+`;KnnNUp9dyov)vxI e+YSEw-_3uthYO>U70A>80000!{2KSj5 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 X157;400000NkvXXu0mjf)dvxr delta 1911 zcmV--2Z;EG5QYzsB!9Y4OjJcja7@2+J*7w_+kqv;hEBnUS<`?pw|-l?rj@Z%DY{%H z(S$p^X*JV(D!pGP!(t-);llXYxcvP4CkFuC*Us_o>9U!9mwIBvx21t(QBETgZbvY# zgBpWT0PmM2+j<-8ks;=Z9<4$d;es6VpewOR8lyH9_p3Pjwtq(azgEnOW4u%w)NmW9 zJs81S8^&K7w@w=T$7R`{dAxB+(v@!P!k)x{S@FuJ_0h1)WgE6*JKm^+X6pnGwy@nCbW{CsZKp~nOja~`> zR2<{`ATb#8J589OGYZjnXsDGGgpfjvAM5t4hI2$DOA-tb-*J?SAcGLc_&!tvf_S#X z?GGB2?|-gjNZ}MPaCb_w49txZ%Hbyvx>4Qkcwja7jAI6(r4sw?c8drVS>r+wkrPJ} zfd-q_hyzcosKoXSgG!A>Y{S8T2V9GxvW}+9$QD4)hxz?xinHV$>p>Ol9X|(_VCvZNQBo5l&b=TW& zvqlsJ;Mg^FND~JzV0?&vbtk0Q;oqzEIkZR2uko|EtU zlVvfoR6*vN{$A2(BT*Cumod~RKKcZLjE1(Y$7Z@*`SY}N2tjNq>mB z{8Ga((mW}IjG_u9=JM_b*W2ytUz^PUa`AmEUxMp}j6L>}CrSQG4dakz5SXZ^`X0D< z_i{d8gNv;N7?vLdynJ!*6^u#>QDj-3sylwyXDrAnF2}p?TyMeke7?D^Z>cL;^QNA#4wnJ3(?HLJHh<=s5gZ7@APey-Y|M#?UK837(NMxr2!H99b1Sq!#TSE#zVCDX zXaa^APmJ*O_yRDOgM^?7y?bD^kzQq~!8crlgJFb2!r1QVO-h13Lfv}DE!OB7FeH$8 z)CR^_?IS6|r3A7P2YURj05@TRj3^2RIu3r7M^002ovPDHLkV1gY!eU|_L diff --git a/TMessagesProj/src/main/assets/emoji/0_405.png b/TMessagesProj/src/main/assets/emoji/0_405.png index cb7634f5bf4798ef3dcedf3495d95554d71fff40..a08bd8972be6f461db312596117ed6e472dc2280 100644 GIT binary patch delta 1699 zcmV;U23+~p4zmrAB!6{KOjJcja7=APDR4$CdQCEaQ8RBtBxgV-TsIzcNiS(YCwEFK zhgmtBX-#K69%4Ktrif-;HX4s%LsKpkMkf%PcT~fYX}*nTGaU=5a#y;DW676o&6;qv zfneC9cV|a26b}iodR)V+kKfY4+Qp&p=Gy-K`?PoyqEa%t0Dk}gA9PYqQve%(+5i7N z&9Yqo|NsA*|NsC0|NsC0|NsC0|NsB`>7hd9000HfNkl-~Nl!vV!ZnoR`bGUe9l*^FN4g%k{e4R;acOG*MN& zT(rLbrR01CAb*c&Jvl} zQGs+fQ3Z+SONfDP0qd_EH`3`l8lahA-;V*>tmANpvVYx4y!@gPt6q+vWIDC)V~moC z++ks@x*_Y+~vpO6@(z6-@$><)a+J<6`eJD{K8#3D_vHVzvu|u+%Zi#dQ0=DC! zP(e;?qS&EI`qA+|hD1{xkq;A1qN-#{bfSVOc2j`#L!Vv?R3112-L8@)pvG~O6B9!w z(-uVY`+x3OA-bRQXY3ms>>m%=sxii~mzz|lGJ1W>> zmA-ArO`M6I3fgpLJ8`BZ(N52#neGTQsrqh6ZhutfG(BhRq`r?t8pYBiHuZKJ=4|(i1$?qoD>C$8#zqcSs7~5bd$RMrP3@_asj9A=_gZQ1ovIW*D_zyKOW74Am1X>9zNbjmH(uFou>*4z4J4Tj4Jky8WQY>@(elj)k4tvt1KBdd!j z37;ZObp}t;rlF}FE;+)9$- zD%v6qPOFM_p=j;AXiQt;U#Q{G7B@C%Q{gYFl9oCDrcb&GlB6X97a8_CyPG*fTW0~e z(T)28V#W$m+UbhFD07V9?WpF|vRSC$*_OvLIJf#(8bY~aNe2awE)!^SbGysgW`8t~ zp6Yg@>!<@|r`MHPt~(}0e(Xw1%Lr;tV>UO4J*AmAO0DdNd??$t8NgT(Za5}G)3)V! z3`zww^4&o`q9GGB9HE~Y14P^P>XK?Vng$3nOh>PLM$L5-1tDl(WVQ3%)SDJ6k4nRVWcD}N#v6Wd@+H~k_^rlzU$n(~zUTg0ZxbK$)nr>SWP zlFjF7te1XJ{WPBNZ88sp2o8wN{rOQ|h~QmEHfXOh&+`ZbZX~Qod((L)6NB@fHi`V} z9+6~{5bjKjGM#IB;bA4w%P>xzOyO*BK>VbCZV5OdrqX&x9oY3FsXr?&f`7Z6-V7r& zRJ4Q-LW+0oX|}gIiwF?}V^Ii0B@%$H_$S3qw^92w+^sUXy$v zgxown-(&(N3}LZi2+RNh@5F}}nP6;_ zlpz-ZAmfh-V894LxDFQ1#NXs_JNQi!lM~3&1Ayl64FN_D4JfH3;WDw=aS>laqHRM; tlB8+2hZXQOWgi_5ha70XK?(n-{sx#V$GiXQ0m}dY002ovPDHLkV1lJXGAjT8 delta 1863 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 U;eS=0EC2ui07*qoM6N<$f|Qi@)c^nh delta 1836 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 SPx$}<002ovPDHLkU;%1h diff --git a/TMessagesProj/src/main/assets/emoji/0_408.png b/TMessagesProj/src/main/assets/emoji/0_408.png index fa5bd463e12cab1581f9a28d9440a234177585df..50f8ffd219b9caf2ba680abfafbb8b0cdb6fa9d6 100644 GIT binary patch delta 1801 zcmV+k2ln{z444j(B!7ocOjJcja7^m6Ce@uF=e9N4r!U&6G}D$7&7wcguV&SzJnOhH zgjv3nfxwjTDpA?>jn`oSdVtQppr65^&8+@BTBkP*d)5B|j_|H>=> z%`vcX3%Y#|{?tvPWeND@qW#}}{`bZd5D5wh24_49uaQ$I8h;4fzH{QXPed*cg-8Ql zAf;~r000nlQchC<+MS?(ZR|E3PrvuoxcZ5q`O;Yc00uBgL_t(|UX@pecIrA1eDnY* zyXtZ`wIu)leQ#C{K45OzB(Y^hJDM%5#ed&nHd&2lPyhY5ST1n=BgA5{DzqUUjVJ3u zucl9n+2Z&1vwziSG?|W=>di(gL&RB5^ELBo`8$TiD9bb}XB5|)x?tzMch1|a$O`@y z$J3~&VMxY+CoghVmkaq=1`7>&S4fbqgtlsw(T8Gj94l$J3bBh!xq>N1CV0il`vCaq z7YrjdP!Xf$f(#ZH63DtBc(B>FnKv1dY;6SQ88sjIr=S=XG6^cMMyy z)^J^CK7R)IMKpQTP;WGo^NLJVkmCYt(y}jGhumT!Ak;cj(Mn86KR7d~3q{Up=*BLH zL@-7vUE~=BPvG{rDW^z*iZV^=p~_ZBf`YpYSG);uIamh^C__;pPoc8V<|JBAiXm1Q z;gV3vKvaR@Z6IRmj1Y_7&vh|Y0L;2;jOmt`qbLpIL18Ly9r7*K)_~0;mPQ7MLb@0w z4}gdSL*>=%2pe-{ObxDpiIPtPHeoP^68t?#q?7M+2cl}Z|f;c8#x0}iHufJ%{p z;!cM57S+SO1~Ke`r`{E2U&$w5J>Qq-l1Y;4k{dASFt}f3m>9jY&x6t$YfZ)n@dK(g zvxdc;{pXxSgMw7a%b>L043V*cAb~>J0DqBhRdAHKGLUePwKn+qK*gdA&IJpK@NxJ^ zh_@Qz$0veB!&{@we9(oTUK|C5{`B@rnd;;k&Bl8o}&S7lh!Jprvzcz^3P zOI}$8>*hm>r{$XuDIw-^em$Jtj~8>xU@phk_tW8gF`&>Y1ml;(j$=yeJSgbgz8~B7 z{qA_a(Lv|q`}VlszqeHW$8KN78F>! zfB$IPtWQP@*D$&JsJ1N@Dch9B3_hr9a={v;t=*nar_=6GR@-gSd$QfW?oPW?Q=YeN z4hqxexf}#7)nQZD!TjzrY zETQn`@%T7N6rY{|NjKwsfq$rScGb}NktinrIP=%pKSLw~{``M~Mq8&4o3 zV`~ITDeC^91#p2gX4U!ey^KsXAA-XT(nO=OUc?VFILd)49?+-~_WMJWQ(NSpL;zDO zNl95j4ywZm=IDWy#v{Oz4m<>Us^@hz5f;Q$Fs>?!3l z4SUuwTsbsrxd23_WB4@(gb??@ zgAxXK@jEP^t#?Y%4G{nPoX01JmWV_WuJ-Is{Vqj7P5k0000L>v!XCKmj_Sa&iM&1f8xJbxAZ$7Mk;C`vXjQ$95{ zCLgZ>3Mc>o01b3fPE!EbQ|_?j$Nm^EnSgCX(CRG!00oFiL_t(|UbNELlAAybhS5MX zG(GrUy|ZIG%lp4xgk-E5iiszw%EzUfQ$OHu|F@6*jTjY>kDcKbo>3j+!u}*_1=65xYTbEZ{Glk$AB%$*Mg~BmwH-o zh!OX4h$#S)?f{Kb1cy}33&95@lJiKMAY{~kGMXBejnG%{^fky?4m+SWp9>W%NMx;b z1dqs*5hZL!@u_jKVJEV)03I1i#?aRV`0QDX3V1L;r+=}|Sw@86*r-m8ruKAziPT#R zNFj$L`LABih|&f+V6REvbRvTgVK|zh%*lwt^RKo`dYW{~Y*@gH9j0i->Fa2%C!UFM z7K0g?Lxhz_kr6;ya9!5JIPN=~6^QeEt~kzU9qy%K&g+N`H#86sMHo8T9!ESU_c=`? zwWfR}Lw^*>*~5%7I*gEOzKz2$Y{qoUU1UKJw_k@Dm5W4xja{C{VMo@~_56gp#0Ykn zVH6YCwWARf54lDFULpclet4NNK1WPQ{GxWGcZf)YZ09Qxnwkl$%PR}tF+rkzB5t1% zoig$=BSu1>^?+@{54=!eWX(Mz91G6L3w?JFB7bfl^dV5PWKF#TOawHZ|MI4AJrX3$ zC`{8d&+||019H>b7bfLF$decq`yS2Teb)2TiB8yRe~>@rX+x>PSnF1TQHRqVrfM`Fa`fCn0(8h3tgI*7Sm`abwqp{kKyy?;Dw zrJ6L2LaCAt_s?fRGG7zKbnOjzek+^uL4Qwfo?7&|mUJL)Oc)*p6A}TAiUbRpB9S}1x31Q3 zsMbg|{PFBR9S>sGF=i*oNh{fjKeP=*T!&%eOxr!P#v<5i{ct2am+~v5Bw!r`AVPd+ z?n9WLHMW)S#C=F86WC-%5?eR`vBr3;L7kCAq!K2@p3s5;=NuVJe;DW%2!H5%e^|#b z<~%$biP*wHfH56w_(0~m9Vf9Q0mL0GQpnB6<1}#N^~cLGLD*Z|&_dFQK}!L#@!7cZ zhxCSv%g}NBk+=$hKLVc~^XCkVat{y>a}mJ7u#xD*ps=CYAjJP}1Ok#Eql=-fdhJ~L zA_60Y0VG6()&{{RAqJQbQh(uN7%>>}0h8eE%N@qW2(Tv-gg_Aj#?0qQ+tORHw zBs@R1Zn$@Lzay~*5K^WI|E)E5`8YeD zAs=f9!VzU($EWT2>w4Nhre98{`|X-#UuTIvpYvm2onx}>db^)47c@8omgIu(_~?>? d$8z*=>VJb;jMo9N#s&ZY002ovPDHLkV1jMS_a6WN diff --git a/TMessagesProj/src/main/assets/emoji/0_409.png b/TMessagesProj/src/main/assets/emoji/0_409.png index 8ce604902d67b0afe3c58b4bde1338f99c9af354..d83444b5338040e17106ed8cb8a13d7af0922519 100644 GIT binary patch delta 1946 zcmV;L2W9w{4X6*0B!9qAOjJcja7-p6Bh!{}CL$svAR#6qA}%T^W?E6flz7IJbkCM^ zEGQ^8Ffq=Xdf&gG!=8l|6BE{9 z$E5ATp4gmq>%5l=3Jcw(e?K`n=e3aa&#dCDh)F_0VpUM<;(yq-hGxmIm03M4if&o> z*tgA+Z1wf@R7*+&0|flz$DDd#KpF~7A`F0CMZTbcqmh5m!>lC+0Q=#=u#!-8L7HO}Q0000JbW%=J07UNDCZT^4Kyt2K$&~vh;@i=R#tHub00x9fL_t(|UY(YQ zLgTy^gdsgZ0)LAn_ugB2r@sGN-8u65vJPdl{}2>Au|DR^k!7xa(D1f@*T3yu4SToO z!>fPQ5L0^nK$x6&`*+vGQ#y;5D1Q$ zrbyD|QYefu1w*h5lHm3t53rpi#1Mif35pQ`S3FNO1Aiez_iwczxWQerOagA23R5^{ z2O>@J30FN>QA}mf`w=o6&|gQ0CSA-_Nz%$=|)wO6dg%G;5g!B z12npV4S&9CrZBll43TifWDG4$C`n9B(==d8KqFHf`D@#>4E#GeMi-uxSAb(3i{Pd<^2Dlyp8N*w%UQjU(&ldae zj#eb20zA)S_+70q5XPeeM(5NEpgg(^wyw_*U0FZA@mRS>bUZELfq<%_0wPMBKwyz8 zxa^DndAP7oYEb!-o}PY91L=5Pz6_ zejKHXnzB9$-1nTmn;MoCb7m^%_sFn|Rjc?~q*dvr(DdiotTxd&p>?7ao3zp*%L+?R zVV@ps1JzrJ5be-OXh}n8e8|>fpgi6EO8sIN?|ZA%rjBab^l+GJ#&b)CRvZeXZA5V4 zR-W<+aX%U`ud;x!W~Zv$mPaG{lYbBy$Ng@bo@SPTJnan@^ZAZ5b#vxzfUvTxEVA9x z_K?*+WJSjMST2rFPi2-_guun-ulp8aY}*cBZD{e~$_f{6U$dE_Yc#3;7?xqlO5eP@e` z2;S>kw$K|F`U0hq-d+|Nxo~nPj7M#RZ^v^dL`Sm4X}8-xy}rLJ79VLY7S#^|B| zE`5#D!^_Jl%V;;XLqgnKwSP5YD7FaLyUo#$JlWQ@q6>d zMCfDZ(VKnC#ZpKLB3yld;+mJD8#XO%wc~0Bdb7R5|eFxq6 zQX{IQ4pcX=$1RgUl#rl*xi-a22STgs7=42nKGrtqL68R6Zh_#Y$psFBAV>?nG4Y6Q ze65M&OB=?4a}bt)2!9aH4>Qe@2z28cjXF+Dflj%?ArbsvLf~BC(+Gsv>7b6EZA674 z|23nbmba3FQbe{36S%>CvO#HBd9^_=_S@}t2jOjxzHF-8`kM)8ENxg(t;4?Dfl}@d z=mp8L-IzN1lkOjDh6Y*K@54i$AEpLkqz^!7+VQtiTpPuJVSmd4jLt0wq$89$fO zFytI5I;jbD8J93(32Do|kN^!E#-9)y03>-C0UCE4Cnkub*qBd%5QGj0mud7Ujf64> zdes2`5lLRE`$-27A69C`1n5leul_}&8$dwuWBiahHy2uH?_!;~Q>#O})PK?Nel(uk g+)T!!A1nAD?GvzQto2~XRsaA107*qoM6N<$g30oYGynhq delta 1669 zcmV;02739Z50(v(B!9F}OjJcja7>gy2E$zl-=i41U<$uf2E0cD$%7Kgeh=lQ8rPW< z*O(HWLj=512Go`j*qRfcPY9Ju2=~4u^SB@AtQ*;#7viKB|H&%uvK!b<0{p`z#6$qk zNC2lj0EssRcsBY2V9``_^YcB?@RyBI#Tb|Ik0JU<#9YN9|%7gS^wz0000I zbW%=J0N{joWTWINMHATVy2O>Yd6o?iQ!M}h1%F9IK~#8Nwb+Mp;yM%t;6Nw_LW-Ju z@ARIs@Bd!+9DhkH0eiE_&fMPv0T254b({=L?*7M&hKAAW_A%XV&lvs~FuK!$>)9I> z+j9rgt}*&S0i*BQo7Z2T^SbfeY4^KbhEw;v{#F_Ejc@H?;7OnzS#?K$@1TWt>0logf_w8R_5D_6?L??Fq?4}5R)dYuO04UE<~xN@V*AXs`El~*`!W6QYHQQO6|v8BBV!er&y z_Qw9a?tI92khXDjU3g0*k}yD{Egr1aaRl#fg5y(~HTtfe6A(4@2oklxbM_{s7dRE;a5tA>PK1Ainei=}y0qY?(%K|MiDBmVU~`#|XJ zW^u+S2CC#`mDP0^O2-ExfIGDwi03Qf0RR-B_j_J4Lg9c=#(0|NB}%~fVVqzS6q_Faq(8vPAHt-cSZ5033FYn=O|?FdpK*cw9YN#mKaVf4g`6F8uNKvrFl`Tqcd@U z_ddpPnL>#J0iqPF`B5~s1QHG!AAec71wocjP0*;SdAj3zM}V?9bP1_t^ckO1*FVKJTx7)3Mpg5xlx5h=uRB%z*b0e=X=xwvot zs#U=-C>k@pf(im#aV!dkVjMNitTSpQI`dpGAaJA-iD(X+#w&<`7H|~hv7H!p=9Q2; zA-YB6@Dh^}38H`{n8@axVJnfuVXAA)Otl#zQYb?v35rlCmn4X5dE`(A_ z3o$ zS~v3i5QKFqfKXv&Rb`pFw)p4;n!m(J)Q*0o&!E5X= z9No2N2+Ei&H>NKAp=ck-rgtF6nc^GP-T^WvX99V){5XRI~M1DaKPeWJ^6~2ry zQ3eu1Z~ P00000NkvXXu0mjfu*L}j diff --git a/TMessagesProj/src/main/assets/emoji/0_41.png b/TMessagesProj/src/main/assets/emoji/0_41.png index 6e3ab8be4d644cf0fce7e4d738e4392b0277f744..415014269c60b55d9473c40f2cc76d50af0c12d4 100644 GIT binary patch delta 1505 zcmV<71s?k94D$<+B!8t)OjJcja7^EW7RYG^#%c)0dM3wh4bFNSyLmpxf-TW`74e=N z@{J1Kdkolo2IG(o;Drb3mk!Zy1B_A#qG=9xJ_TVZ0lSYO>$WBTo(2E-m;dQw|M-Ld z_iF#^dH=i#|J+yq^HTr%tNpGN|Kv&bjRXJuzW>!k|NYYcwSOP~x+(wPG54nv+Pyaa z&k_I3H~+&p|J5-6%P#-wJO98h@ShRw*FFFK<)~UQ0RR914RlgYQvjRp&@`)83>SgK z>c$8N{6_!)1n@~jK~#8Nw36qN+aMT4&5Q>yfWjLIxUbvR=ZuU9??AHX`3QH7kS(*=VHxd-4MUL!sji4LvS(I`j=!k zPC6;2)_+DLs#fVd^m$JvoI3!J_az>kb26i)UPq!J@xBHhAWqH|iC=X{p9QFJdl;%3 zYzJ_dvZHss_tN`ccX!@vuP+mqa4#LnC8kG!j#YmZ{3*Q-dmF`pFaX~{99nIGUu&6a=!bA{)fh*k!@$@ZeghwI~w^j)v%)~l3yLp+3@D;W+j+bux z69F^5oU@JvYDF2h*1m~EFpy+^1{u~{YkwUC zR{_xd^hBn&{*AsxFjYD7;g;&6cJ=wr5%k1YJU|(LI6#I z1)7HJ2}!YUHX|Tl$f0-m^N0w^G*UyssG_Q5Cl~SkmOBmbue;2h;DsQ0&l)lqfx^y%UJ<}*W_Xx*m3_Vy0tHOW;c*B6 z_QU?)AFQ%~K#_o~8OY?p>RMHHDr-mq0|=4pn@sI~^9g(Ro;Ogy5QKjb0QozB-%ath zS9#VX$#S(l>K6a;fm^8@Q7Sxe7ytXIA6Nc)ikDL;{@DKq4`F&$4pe(900000NkvXX Hu0mjf>|?z_ delta 1625 zcmV-f2B!J*3+fDzB!9F}OjJcja7@&E7sqW4%xww9dnU?+D9(Bu?U@d^c|qx_B*W~`onHcn=5#^8z*Leioh6#*N1ZObll#A-$tjt2sQ>^4R7pfZRCr#rk_m3xFc3wpR#F_q26Y4O zi}uBKw%-3nnvq%0qoaPB31wcrWr`dP&Sx$<_ zzBwvs09ZDX^S0q{D1+OD7 zpCd}kgqI|L94CblnzJyFFQI|~i?`ww*A;%Ujtbc^|%TM6SH?qHDIH18uc+I79Ki5qxG_9vc=-AZzM9$b znIS)dff;6Icp#1=%+Hcs8&WX5um!V#xe!L!3^uT)2j`($9@FhMdgZW<(T$$LtK#g4 z;4>=J3AeIsLIJI6f$j`+Kv{&UMSm>>RbT)`^luzsj>$U&QX|!ty2dy{ z1w}dxNUxljIGtsnc5+~(PO@11kq*p1`(i;hS5 zbALyNL%jEPCgLOP$%cr2wu2aM0`l8Tqnkt+?!+c+>F1V+d4Mt0*NO5CfYddF0mALF z{S4cBV4?>xTx(kly+VF%xn6SiKU`il0W4qmo#V za1S(GHx4YoSP)wwa1!xuY&5Pg^+XD!p+N=ObkpFOfFJ}K;Y1*k8@3ezfWwVODV?ht z07l_za;;S5NbnGNKd>PW;sAm=VSx=lwW=yr-eQtq3|g0!Y9{aRMetM*5rxr8Gk+$? zutIpFs!AIIoOfMALg@HboZ7fMH2!wJKH9InRe1+p;Wm!;@|AMPNg+ zGz|FrUI-YL4C`YBqGiEfA-b-vl-8}c5Ns&olokxIhx~@^V zj$ud}Or-R%OAe`&A%^W$&Lup@`hTuAFsO_mWN8E-+>G?}C<8S#XNQaIvtaGHYc&jM zgNrCOU&MO#R7P)1eYO-Yzu^bSxhdnPBBYP7tyG2>eS5a(<^|!*_FTszP!Y1FUwgu3 zgxfK*fj?jAMF_W2ije&Xi3({2Mi`G6^BBI}Xaht55inMCGZ$q9gDQzNo`2Sc3+XF< zaG!)_5y)E+jHF0`WICq@jlMj_lwhg0eV-J?B?v_r?vV8{l~%S2-8FSqT>BT8$1)sR>+7;g_NqPJ(e6(``Rdg zr8YMaiZ=j@9K^W5s36R@+kY%eGxykQ7+3}&+Wn4LM{Jy^j|H1eV Xv=f+{|MLi-00000NkvXXu0mjfZZjFN diff --git a/TMessagesProj/src/main/assets/emoji/0_410.png b/TMessagesProj/src/main/assets/emoji/0_410.png index f091f629263160cc41070d8f971ed59637ba8538..aee34f3894fdf10d31fb352ea73a9dc6b277b887 100644 GIT binary patch delta 2018 zcmV<82Oao^5AY9=B!A3MOjJcja7?$FYSqGe#5K!#p9vT{ejfmX(dUb}cs(3x?}k!aGOc(8m_*r|frt$&8wu!-HYj@6}pcTOtb zw~^tzmgB#fw|r3K!kn*pN}G0BVK*F9Clj)XWu}mP;>)(qy{1DQ3+CL=u%M9c=;9>? z0QLC!m0|+BjRLWCPq%bRNUen;0000)bW%=J01|qpz@H^JPX7P@|Nq(lP5=Mg|NsC0 z|NsAl|Ns5}|9}7g|NsAO|NsC0|NsC0|JMJw|NsC0|NsC0|NsC0|NsA-?kow3kN^M% zk4Z#9RCocDl4oMHS_pQ;j9@*$h$5Ny7e>j+Mx=^%f0u^NKE{Z8U*^!;EVT)>i)^g-@_@Dtc zY(lWuWO1@W6@@p%P-=LDD^Mc@RPckDODh%&ZGYX+pXqa)j&dN0GQo_aUu z)86ci$bFChD=!Z;5 zc>p6tAS0zBrDH3tFw%C8|Hc5!$&Nv%^?#|FlJNUO3%({J5Zv-HG;ta`Szr_ypA9G; z-|wpXPXo2krbuxj08s**E(psA;0hY%ORZu1*c=c_;YZF0BGe$I8IpBfkyjBP+cr_$ z5aHU0DO4JAF@wsk*_^$pw#ePXcOU|1#270ti07dtfdNG1d#Jf~=cd*oXsTwr=YNAR zo{W_=YBI;Nizf4_GE(6d81STnT3ggwwco^E)Mg0gST08iG?4Qb#9R&%Xtb0u%#a*T zw_3F}yFr#(J!X_%uGZ@nwC-Lby7n6GEVUv;6YW+*ycrGJtsXbAS>fSi1f|!AbOa@U ztc;Efr>0%h_x}ZTV-RV*9Hb^j6o29VmF5)K*rbD{)|3)7e>Iv=*hRhgKs@JfY6)|a z8%^mlI9dVWbvj6CUH$IB^Qkf;twm|T^xAr7MBWyeDzdpciX2do|lTVr+?M{akpFL zS!5BNR&Q1{Ba~8fI>>1>#*<4tyiM}Sixrb%wS7ug;oe81fq8h8s5YI4Y~yFWtk3yqH`NlOkW+tB3Z!&_J-E2zWIZ z4KBGS0;A$$zge%hyVbG1-+w>H6CeBia*OyJj+=cEM}%NLZ&WL5<`V)fk`?>M0mbty%jOf5Vku1Q#j%D^ov?y`sMj|TFwSk9Iv&%uQ_5{zFMr#o3_Kvh8lu5C z`DX}$Vrv8w{oerK$=R6^;hp;l z2k$SXF!_Y9D3LM}Mx1}=2XwM#D2ZbNy*93dDUJ?OStC#qe}6N>q(jsWOSaH@OG@a} zHB8OljBwH5KDnY0RGlVkOG#4H0~8UVjKuGg!U8Y|5k;|<>2jG$R7ezI4nn|OI{xMg zF(4z+GIoEUxg&4}H~ykfScY5V4vubO96^MCBTzU5vkc=FmYQnnzd)Wj^4|$i zc(x2cK(Uezz+2An;@@;LvxX3bI0%Rz5Mg%nj{xZ7=}Zt%Ab0kL2`B6_uh7kcAPg7? zp8))u3AJ79>~MC#Zk($M5O?1FR`}z}4*x@c;k-07*qoM6N<$g6GBV AS^xk5 delta 1911 zcmV--2Z;Fa4~7qrB!BQwOjJcja7?p81#>nN(2;9gG8>v>J-R{wvxa7dUQ2^D33oLS ztaMJTKnayO1#&S8)R%DBop;xrc8WI#)|zyrJOidf5YLlt(UEK3q()=1x6#6TnSZL%)_1bw000ImNklH?&-OV3z~}WE1hPu+T3+#>(j;fU}@dtPmGaivQv}& zh9`Fbc?n;grUei98ebg~r50=48G8-i9d|pg^0NAMGTGx29RN7d@IASUm9claJO#$- zpJ&HA!7F#iUT+SD2z3vC`}j|=#^G*UwfM{}*?*f)1t{Xmd%Y2mWjQ5)JG@DYH(fsU zSn=jTjD{!5z)4%N>Yl&?hj_dk< zMSrt2O*7260tzzdU?10a8O05Ee?PB)z%2q|J{Js)#|lYYs0i~ONXP(>m3D?(+9S?n zc4i{f76`HEE-Iy(>LP zVJZlrE=f{NvLPv>QB~J%Ep*~}1Dc%P3x6hiy_mv2tdqfVndp)ZVGK;P8Vm->T2o^| z==uCyyz>5uhzdM>!GNFL42Q$bus^9u816{3%?7S-mg|sIum%$Qhk6dDC1MHMANG^= zb~1rcYBf+&XENEYX3M9|j0U}i3x??D_lUBG_f*B8bhfIsA+;urS*-huLA~BzaAPMd27moUzg}NHCM#QW1mElZC>{`Z)1Dt&n!R3(`kTeF zUau#QlRq`K+YKY?i_y%|jEe6S?!Fx4I}w1O#yZ*#>nzLBR!WJ0HZ;wWgkE2mr!sY2*3J6|p>oyRM zX@=Kdj`BSqBs7rFb$B||B!6AvGwcjW0!_#NLo_5zIFRH042WrH6bwm%F9cA4Z~?FC zP(sy=&@}NtjyEF+a5Ge9@Ni=9IgfJ~Au(YqPE8WvB(DuyWi6PQw%~K%jdh&jt-uIM zRcOp+p@xbZU{PGpOV|_$A_&Ek#Le?GbSyAlYG@{m29s;A=gkg^UEbWpKGxO~p!PZ2rUe~!(xhK+_!aq}I`-n9S$Us0ydjnhO~_8OI4 z4b_H7XlNR2Fz&Dzb!I&0aGE zo?(B6f`&pc#}03O+AHQkDKLW}>T0ljf-DnFrGQ#61*v4pSGRxtWR%ZcqQMZ$qIA1j z!FL2LCS2!X`FkG~a~A;#9Y7!s#Bdw{5eQ9knfvmQd;`No1aRYoTrfT%qy`{dVU~kH z0K!L;yN($WhEM_$h5(S@8iWt0cy|#5sDNW)NDy4yfAV8{?*1Z1g$1~nSNJ4ycYP5f x6T}yn_YC-ain(uh_xJaAcR3j0zvSKJ{{pEL%vqDXh>-vQ002ovPDHLkV1ncph!X$+ diff --git a/TMessagesProj/src/main/assets/emoji/0_411.png b/TMessagesProj/src/main/assets/emoji/0_411.png index 0104bfc518d8945181f29fb1c1ac898fe8942ed4..79f9393ed713edb384eec454aafd4d6bac2cd897 100644 GIT binary patch delta 1859 zcmV-J2fX;f4bl#fB!7xfOjJcja7=nnGIL2VhFCj+Q#W5aB5y}8YCAgGE5Jl<{;;r}e%)ZV0 z`W?aO52Xp1y(i5?05kQTL{x8%_&Ter8a;bvB8(4&#eWe{y3@R6(gfM5s$cmr@U^{z&GHyETm5mxc6P!huXXachj!7N8m z-BI<{d4HKGrpiM>xSN_9l{EQD!V=bM1?~I4-aiwpSGoHg7a*FCb0!B!U|38!)~ELZ zCV*=#HY|1`q=3oWBy?YhAo8im?-9#4%hB*H03_T3 zC?IaauoaIEQkU4OizCqE< zFQL7>gb^{4ZD=eVQ}M83{We29zLh9XQ8g|8Mx3%HMgah~CN^dGv8}7t(9Ole9KkEm zz)YuoXs&1HD>CS46TB8R5DA>O-#yrNyrNSe&>4f*kid6T^b?IhcSNKr%i-o+i+`+C z1xK{44<8?gnnM!1PmHSm@8dtTHbfLUS2HV+$ZBVE8Gs1K;X`KjaBQatCQN%gc$>N5 z7@7-Wp2*{Wsj}9!APl2Aj`_Yk4%IhCH5~Nmu-~h3Xo--ywJ-N!JcXe142brCe|{Xw zeYP17{WXfisIr6JmpOiJiO4dYJb&FI(pKiV0Ae`#Jw(LNToJ>V#a5M`h6!Q)46!n; zv)Z6I$J593=kqvrUx;o*YSioJX=Eb!b82Q6st?}Eq^+9qG~{`?U!Olur}t|nr_)CU zf6nLOG9`FuQ$$BGDL(tnp(VZ0=X zl0eiI@*X}vkK;I833v_Tcwp<$S1c{5lH_Gp7th9M9q*e})f}Ps4tI@j72fnms^R@4 zB8++d?y2mxHbu+wyxh0?J54vO=@uLkt-YULBTFEZC*tn@&7BLa>$yur8@$q9d{^Kv zLc>qqawbHC)HQnZn*b;h;D4r2TFl*q84ieKdIWqi>QFVj*R>>(07WaD(hgS4GubL7 zVFnP_FanO5dK$W$$3PnrsnmRS5gEIM_E!WMeUQ>8iE%FU6JtUYUUPx)BR#RWE(~_4 zgPW!lGSJbO2MEmLXH)T|zGl)jAx+F>{;D>@Bx!q_$MUBWc@o*H#Y&o8(ciZ2t z5}#nl7o!THzzZY-5kqR6{DU>(Zejq!Q&Vvp2|gO}M+{-oBE-%ym1L<)fNyGctK3`qevM7ocv=g7n+fnB>B2RIElwn>O60>iV!C}C7g5H#UF(* xzl&`(IFQ~hutNS9JuX+f-D0uZt$w*q{~zeG4;-jOsf7Rl002ovPDHLkV1j~;Z-)Q? delta 1713 zcmV;i22T0X4#5qOB!9Y4OjJcja7@8Y55;^+wo?_mbvmn16uD|Nzlu!1dP2*dW4n1z zw{k|cSQ(y14WvN`oKF+nvWvipV6i^|pgaQKwvfL=0M(^_*{p@lNCMKHcFB%qOk7@UDE%Rz4q^X1YcQtO= z<{SV301$LiPE!Eod&X94lqf$F&FZSA=!hq_j;a6v1*SFNPK<-xS(St2%$DOoqzfTZpO*pMf{X`}<-t(_3F} zrSm#_e>#r<2#~F%s9#-&fj)VwX@CM4lgVVLzx;8Cfq%mE?OP47keLXh^?8MXZh4Hs zAoaim1k4tU&#%N{#<;h5t5ThxT(X6HI?G`8{`S6Q5gRUG?n`dYZ}A~A(`$Fy@D_O4 z^di!?P#KS2+i%MZw?h$2Y1fRQY_amhi*oL5CpWpAzRk?5Sx3u~l`Wn}+`=>0-qpb> z!x`(;lz)(ofdIoBLgn&tf8Ht)Z}3Q{p6rYS8v5+EwmffD0q1!egIRgKJRYZUUPR2h z)-D0h^DYE%j~BMvoXM#zoyTE<24~d)%ahN#FiJ;%n53f&0l-ZI;RIj^M8_BQF46Vs zd;HSu-mgM0ueYbO*fDL2!yv-oSQW-fN+7TI%YS$g#0*O4EDB8%5z!>#f{_s8dR52r z9xm%|z1$cGQ3?bx4JQ#wQ8}P9VMvnQ?{nY*fC9`BrzVjxY?`doIF8XlCISPMI^vfH z=RttlDW#@HG!Qfhw6OykCIEp_+h=BtT&XvXmFCqZyTF4or zG=E7`!xi!U8--}_tr^&1T;w^gC(zY-L5X1!+`yXpfM6tJCP_kVq9t*fM@;^AX;E#qtO(SRdF-vO-EA=cz+`iHCXfEP4E>;#MC63n@uz9fCM_%;7C~p zZ30n)|B^tJCc_e@runWNQ2f(?^P-D$cS1Z>rXp~a*k?4dpabTUx z)p9R{-N$N)02=OQwHc$Z+Z|V{k$-78apF9`kMtet*d`f4jWGa+!?GeWAfUz=ehMWv z1c-#v_9M~lNrFtlIPCUkc;S(#Ae_x|^|9X_K9Fq@HJup;WVBJHGd4lz%Y?; zMKUl@KmrX6@S0{KL1CNE%LqeUMrD*YCqw|ZMBq5Ein>Wcxr}QMU(1ky$=quTV%E=r zHJT~KNzia*hye!NqvW;(t|IMs>xokm*ye2w;y^E`ZQhkI>}32}OSF|!>I8-~T!CnI zhzTw&K*u?P_@uP!h>jKIVt=9X!U}`n=4|3uZwsPCc*^Su)#F7~qZ|f$qgV>q0X7k& zr-F6rh=$Ii7;2y)5fQ+oCIz^nA^s1fenN0AE($?Iyf^}gWElc-3@0rjt~WmUEX5cL z#V8ofSYJaC6+)1JpeR7pB1)@iiBTl79?#3{C=MZnkVo8Ww7Z{u7=Hn!kA`7Fu*ZHk z9>bka1b_nVD{8Cx$4^G>b`NHOA~Lu?d@>OL!RfW(_*WklJAGjwV%Q=GN`UqNzpKhZcq5=U3o+%Cct?o}h zv;zVPB&1;ofEeP3NGhY(PZD&Jeh+~Em$uqyLDUY6@K^I6mcUgZV*R;f00000NkvXX Hu0mjf=RPSI diff --git a/TMessagesProj/src/main/assets/emoji/0_412.png b/TMessagesProj/src/main/assets/emoji/0_412.png index ccf7d453108b1b89e11ad8c70d75e8d600c43c07..32a1902ddc81ad41996f23f5dd7e8460a5528363 100644 GIT binary patch delta 1593 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 Z{{T_h#-(0Uz)JuC002ovPDHLkV1kb)%r*c3 delta 1675 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 BmKFd2 delta 1553 zcmV+s2JZQa526f^B!8ArOjJcja7>Ih28cHaG9D3HD-e`A39~{4us;C2LI6-K87~|V zAQlcH7Z9L51))6#Ar=ozI59LO9Yr%Nj5q|uL;zAfG*&`4*iHjmMmx_)0O3>#Eguyl z8WBD%CZRk5N+t|qQABkz24F1+{QUapToUhP9S8~o%*wsu;(ynIgKlbOQ=FH9v96d~ zbTsyFD*ARbH&YY+c{fW!f<2V#WJHd%;AfVOz?(7RN|NnDypA^SnhaP&W`lKiu7w`DpCkcvQf0MxT z7CoL9{IS5BuYZ<0T5lX_q?a%AKhk(Fe!6*k|7YO+ZIkNN-21UWZ*2KHK(zysb?U$T zNa8Kix4y8ie|vuekVO70_>sX?yDn~q4L~E&>c7$iFM9n3!RIDy16Hx#tdVB%`!Ot; z-**9Sf-7qx)${K=nE8=rEF#4qxMhHV9O?HCWQaDKgnyNKL)qzTXka~%rr0LmWSK=M zNSR_V0i+)b(10WI@6L3Nw<{CPS>9qiU*SUohA|& zIVl@eCMhxWjq)+fn>LZ!$Z1lxttxe7OTX49QPP9k*;ujAE;1BVjz0V(8j}o=Y#B_J z!)1;%6n}ZE6w}H0?ON+(fQ=V+6}i-jW^HC2rGG8x>okE&|9Cb&TrPK{p%6u$R}Cc0 zRp}o8^S8-rr10I;6791_$U@{7zdYD)K*!8{qI}Fv5~0lZ6zOY8z&UF`Wg#90W!X+T|!93a=j2bA&0R;iAe~<;Gc#R>UV%ML)E) z$BX@)!qLk@qWSTGn$G-2{>j&Y*sE0l;A*>+oSgkd)I*RAD2%%}+?c^udA zed;)bUS=(|!A2WAD5(j0J$23vt`m&m2C>jgrARRwpH!NJRTvo`kH>l}F>zfVkCM~M zh=%#B93S>M_LL}i7;||#AB*C6LeVGq;eT)u@^G#TYJ+x|3Py^DN-2SN@Njqj*d4ap zcvpv?45!m^f81^l`-2RTq%2$H7%B3G6o&6QneCz2o_A(QaoFcIDYm-~VK9tRJWLgB z1BEeFtI zr>C0Jp@-sWs(8vt!Ra{BMvNgK=zo@gx~^+O2hb@VrV1~2N#Ka-bEO8uX>|vd6d9&D z9Y&sGNvr})4TMwBG#_c2)18r15^@X$)-gE4*yYG_{}mw04D{S zxW}rpNsPHExWEHc@F9lFQLXMOf@PE4k~m3NRW6gUVju>N^QU!owBi;*>|TrQ!wD_PE76h)C7K#}8sZ;4!z zfjdKq9x%=O1h70h2Vsyq2Y*>%0Jny`U3&8u7``V6$Z?gBX+Tnn*C3!*{T}a`vP(9Kf&-P zc#y#2pu1Na;!h>7uvnfSpCI^O1m43Fc<>P6uktUG^9+}}--&Pl015yANkvXXu0mjf DP7Bbc diff --git a/TMessagesProj/src/main/assets/emoji/0_415.png b/TMessagesProj/src/main/assets/emoji/0_415.png index 0aa84417fbc72e269211f44ae0bf3581068848d8..cd2a66ae1284ad0d659f14b66cec7394ee5b0029 100644 GIT binary patch delta 1910 zcmV-+2Z{KP4uubpB!9Y4OjJcja7@2+J*7w_+kqv;hEBnUS<`?pw|-l?rj@Z%DY{%H z(S$p^X*JV(D!pGP!(t-);llXYxcvP4CkFuC*Us_o>9U!9mwIBvx21t(QBETgZbvY# zgBpWT0Ifn9@0TU!i5}~bA>o1?u}B)IJs7-H8>2QA_p3Pbpnog-wnof~W7~Qg)NmX8 zzgEUy8@zEz(v@z@WgEnRS+`Ca!CD*q$7Qx-JMqe=*`Im!(Xi~op5CZ~=(?8UvW-xu z66XK_01$LiPE!Dv`R;pG%q$fA+Ow_Rw(r`!uj&8*25Lz}K~#8Nw9*N3n?Mu<&?vwF zA-ck>?5p<8&VT){mHvZRq+nY~Ra!2)${wEkf9Bi&O%V9^1i?Q%?R)M|wsssxI>?$u zuJ>1rzhaIQc~%rf)8Jc{^_Hf<@;u9WriZ2)x%y}p-=Pg;DoJ4+ zq!I#(Wu`tLtg*b)faUfIsY48dw^9)T#WLeq_q*yY5uPk;O(MQyl&yk6NY6}tsD^O- z#S-^_kbm&BJCPw3Da44$!5KQWG>R+jpM=s0kGtI|=C;S602vu@VquhEEph^ss`i}k zcDs&K51|G|O%8&C>*pG-#yLr;_dG017$!FDWI(wmCk$uZ=S^ryA7s1d-KGT6h1?t} zGNk$=Af9S?RizOK`e4FxgP_RC@T68_5jp&zV}JO1tPxd+C2A_Mxm+$lsK_1*0U~FP zMCdFF9xmocv{d5qhCnG%#3U8Qp8(s!R@UBpnN?kb7)n6+MR^0#0cmwUBE#0nh~~>A z0xmYeLrekToiZX@IU>>$nlihh-dLjLW``00ZfAUMgxH;!mJnf?LC~{>t_EUj>=>Bi zc7Hu1kBAne%n24ub8Ib9n;37SJcUVeD$my|F))D8Z__xbHC?b?K<#M~->HAsU1vRx z8c`I0$Bv1c9=97XtL-jDq2Pf*?82=7|8M2oTP*1)bNpbbM)m2`En%ihGD;!aB+2sx z(@5IHG*<*o#!Am~y5lTGTL2WCWV??tD}U28BcVtNjG@Q&!8A7nRl1IDxoU+B8+1mf z_FEUJZ!;~XWX?&12u{T{f%up2-;*Tu5u2Ob$moF$8*?3WtGDQzGyQOw1|w;#55 zy9K^yE&>e0^?hFU>_-kGmqOG{lcnm3Ka>p%GEchk;ab7n4{o=+ZM()6-?bj=@*}}e zbTUAwdHyVGiNq2ms=#sXH_Df5`G5UJxQ@Ln`<5G^MjHzlS($45tC@vTFwxDf?>LW@ zu=i>BmLl#TY)m6zLNtmvf6_UGA_m*Gy!#!()3%(gMekTR$W1NV^Ge9NOixVI5Xc~+ zw;lWO_4RyKmSq`RK={1u1D?i$2_#DoAhd=E0U`(S>TNWAK3!~bj6DE-kADU8MTE|T zY*Kn9X;BD(h_)LiJfEgxIV+!(k+DfJHUi6%w55w;FAz>Afm3rP{jFilHU>#K#U!aA`C&)ABw0E7&wWlu?gUK z=T0o6kdlkT`8fZ0yF>sYdVf}htW=F{%Yaf;eKq!TP;)junIM4;HPGEKCy>)Lj=d80 z5`vqDh$2{MU*-L7t40~M0n1wjYkL85l=c%+rgEewz5FpL)>Y5GpZNf&gUcf#-|~4jbwyv?FQryv?gB$9G;007yu} z5J1D@r$itwnaXaA%6Jud+a4)xo6juZLiKPP9fI>*h-h|$N1C$%Waj@bB}LH<%j=a! z$pDATfH*8b$;4tz6MrMP5QIS%l1PT-=61FSk)(38}W~~830!cDF&gJ0z_2`lmK3N^fnE^lO{N@0R)2ztS7k&*=v z8&E2N|89LdUEe=HX>nPtSArC|M)32wAEaqM-`@|~{%87G)3np!a=pG&bX`BL5j%n9 wch2>4IBDAXj0Rgai*p9~|9PVi^6x$W0C@!rfs_02l>h($07*qoM6N<$f`qS!CIA2c delta 1791 zcmV@U%`L&x;Y+ znG)D|2j;37<%S90qZjIq49R8&_`V^qYzw-25AfZcyH^J8lYbBY%r5bn6!@ql{Ly;( zvNZIc8vDRiqdx}!&M_7c2&_v7|JP69e+T~f$^GoD)v;efEe~Qx7`KTZ`^s;ulU(|_ zM0PL)on;RE#$$*_0;+&HfMqX~GX@T*f!P2602XvoPE!EdtcY$``!^l$veBBEbiUs5 zn|g>miK?9f374_Oh~!1 zWul|`xHFPD%Afr@CRq?Z{Q0$xt@E>sgKDGIBefa_Cx=I6>o)-F=%CTQ?LTZb9i`3Y zp?}+}o*ey@VjWi7eFQ`5X+ZsMbW#36O2>y$_W=RAy?+-C+_p~2-x10OZ3FnIhX=aQ zb)&Pdjhr`bDc(eB^&k5EKK1CJ+unus6(Q;?fC|+Cy1iGob+Dgd1zm)zXg&M3TU5K< z?ltx@tb?G7c!a;s$8FTpt=DQr7sq=Dt!V($h}}j&x^L;80F5XLjy_$@gZ6F9i`3U{ zqo|>KuYX1ZgrNFaDn~ssKJ|jvZ!;n0Y8XWXfX+TOK?>s73mQ5Uk*_Kerk~g-HDEo6 z>-E^1MhIvrKZf>3hyWm+?;sA<+@M|`55}MbQDi8zB}L47YGu4oe!KODX>@KKK# zN;du+LEyTN2?UUgNkE2Z27s~VP$B$r{Mm|3JraWn?qv7(_i4t!*fy4>G?+PD)hDhK z;;6VU2oYmNZRhds?h$g305Etsk4krsj(<%Emu&33XJu?YPK1P}k%cTv{ULI}MGDo> zJuwnu@H*KjZg7h#;Q=AtEKCpu0NNG;U=n7o4Mc^uy;XcuD{%~jv{8DQNIVd%31-ly z2a3TRLhSqkUwE;j5H|C}b>@Uz2Z90u57+5B^qIXy?EYRH#y}9kUo4(iqvg}W2Y+MR z{KeDra-Q^ug(F!6vxgK2J z&pHf(4m@&m(ePV#)xG(`B&c>sZG7K`Dc7}^E}0V0{4bUG6|k(#GW=u)^S zMM2i3>x3wVVrT?+Iqh*f@qal8Xr>gQ<6a_)G**#`L9iYU0x?c3I3qNAOc8V*RcjC8_yn1NVe=>m z%wfcv2KY=j*Cr^BlfB3AzbiPCfrj1_GIGvsDB2Fy(vx*@8!`@ z%(MyQu}`P4!KBb9le>3P0|O!1*Ct>?Rf9QcnmNvD^s1HPWVFKUTN9=lOqDc|$=X0x zYy62)DieRdB4AO#ND?()%5Z&uzYe7hYLX-%=;in_72|`%IZveC(V%J%NaGuo9M|76 zCXKrRLX833|yP|6>ugn9t-UR8JK002ovPDHLkV1mswM8yCA diff --git a/TMessagesProj/src/main/assets/emoji/0_416.png b/TMessagesProj/src/main/assets/emoji/0_416.png index d06be85ff052121b11e8db11d3ef79ad286f2ff8..a71ecf86b1af8524843655fe81dc356d60d34a54 100644 GIT binary patch delta 1861 zcmV-L2fFy<4b%>hB!9P1OjJcja7@sDGTVYC(R?evgHOAOUch)jvVB{yn}?=JBfDKD zy=^$oggmrUB)?xHzGpDw!kpl`lPd}W`}_Lo<=tE{8QIFWfnrXvp^%k(Wv6%tw~!(4 zmnE)48RLW<=ZhcRd>qzt8|#rF`?yK@usyp{8;?&Zv2RATOn(~lpDLa?8T`Li!CD*k zs57WM7|mxJ{KQ_)m~Y2m9MhqBpmUJQr3F| zPFJt)+j9SNg@2^VDu&~10^|YurO}5+YQFv7#9K;)PaOZt*U{$53w+;KJ|^&6nG4^DrUHn)Gz(HRNnSVMOg_-@j2o2+HA9rXRh`Mi~ z!*!A}?R0I}2S&Vu28pt+djnOPI!wb^kiC0sgvw!6$dD+tt?*(nGxZtMj7EH4i2QVq zge9VHr3D~`7>0PPh6pt7?=s-M?)Ny9T5yUGvmkr75-)ndS4Mi#y|!k$WUg6 zYkwcurAFDUvf9ms*rZN$6T(2p_9tc)JP7L1HMyOHmZ({E~~Z z)!YM}o8ZBl8j;p|BxGAA1t-5;>M}ESLKa71=zrj^HR7G75MeSb@kXH{H7|sb1tNnR z2l0BDzBWjZeJm3cJ}8J>5NQom3o;UNOtfC6HfAYtCgGhjA-L6wkaY{rZhf~66H4h; zBn1hF!|8N5EXbf3;i!dJUC~GrAtjC>xWqdGrz<`qlIPfj5MYJ{E%kb#8*K)jgMTQO zIDcI^Gjh%oag;#HOrRjWc)1jMz!oI*I7adEoMkT`*VorqLU^3FqDXp?8EFAvDuKu{ zN#vVhFk1iY!_IbFMS?H@&w@#8j}tI^B4&;+a3iZ_#L}$q|6cP~Rl{(sqxpRi8Htao z>IRZjxH&pC3}|GYhQ%Lu$f7R8FdVUAZ-3M<0c1GadQ=UJh6OdDiE;GD-bYxGb{48- zIO2(>>3TB0^?r444N^b=v5??Pygh=z!E7H;3XQq}p%c5LS{G&ce3*MT&23*#*;4x+ zeF*WT9~@SwaiTqoySU_Hu)E|wZy@9l3>8r)NtR_v(t92mQVB988DcsyN}PhZ{C{v| znzx1pE}~vcnkG?{q)F=`VnE6GaF!<4$cv^Znjf-3ok~M^qKZzv__tnx@m55tGShC;X#uyX^>pwgQwTMy zBn+b~B}#*IB!Fv4!|=*6IDDTvdVenF&!VYr2i}|55IGSjLZvHV+92#bn?4S#eD{Me znG_KS7RBKOp+0~R(Z*qrk#PTtgTPzkhe2RS`1%Ti5UblUffvQi1#xK52M{4fT+bNu z^*slB0$<{Y4);Om)r$~FV~LW#3en?&Vb*=OxNhieiOEpiH`<7MBCx8|zJI>a7I)AG ze;&tasr!EPfDjN{KxPUOhr`(KS3)|m1j1#=4Kj|nsy%;?crbahgScBFuYM<@AfVhj z84=uJzsksI=Sg7{Vrbf1ZjqM=83T0!0KzXLcN_@m1H!YU7t*;Ppn!o#*1~11f)9?* z+!Hbi)Qt}U;vGc6DRb(i-hUHq-Sc(*mGrp?JOtOu^X5Q=HOi98sCQ-fHORVNmR<;3 z1p0s=u>?iaQ-`K8?}>Km6jF~H(YN)2A~vBU;)8|NP_#9+PR3bvomyIdR|JMBf*4F_ z2nZXmWuR1diw<6F6nioSmL~w+FVW+_eO|OL@v6FxR0{Mw(IDgU#EeaVUJ+kTL zh&otZ_e4(TZ$#k|(clBX8b{t6NEaCd??Qvz+tIcmg4Px(&R7u$Yh)Z`0O^%65ywRL z1%M0!f^A!J#_j~5H$n^)PROhjt%y=nE5eLHSiv%y2)Ee^01fgt>Y0SLJjP=EHGKqJ*o&;=Ps+S%LLZ~!a=?hFvtK$wz7s;UB0ZDqiC41(Cy zysh`bs%RGkgq5#;exX$pJ&%`@Lvf!|26NNxBtmIXMfJWjk*EzRvbD<00000NkvXXu0mjffDmFD delta 1747 zcmV;^1}yp14&x1wB!9zDOjJcja7@UUdBTrx@0ljXYctK3bkdb?)0SD>kw46!ZquB2 z@0lm)k|^z#Ch(jq@trH`k09v5qtS05?ZKVYlx*g_n(xP?_SCcWq%Yc@cHO3d*mfM^ zuZq%c8}iJm=C+Z*S|7?}9MFbZ&U!`m_Vw`S;P~0N;D83>)VFi=Mg9N)1-wZ_K~#8N zm6r!s@=O$jMSp{U2=abgQhTBIVsHQdSABDLgP~exAzmXrvB>2HVeO{T!h=u!aDr!hH=$eOmfkr*Vd0^<8p%TuoJ^UJoz4 z`~9m^ghq2X>_u_kDhgqn4tQ$^M1b6$>w?lc701nlhZ>mCEkJ(0$(HK0DDNI^h> zS!KpLgt%nHJswJ(#sNgk6Jx$dA&$;gLv%0bq<)APk9xk}a}CF_dAhaYq93aiSU|Xb z97V9vK8j-C5+Y%t2TGC}Wk;By?f}K8R&@V3jDI%zfIHs~qy)wDU?xdZ!-%#rBEvA! zG)WS;i-EX1x<&gwA;LfgK_Hn3Lj{5($0j+nv{GLoZVwQ5mWm>k5{L;zZiD~_q+L0l zcMhS_^m(8NrfGJ&T@xT8NyeDK!i$!)_oX>Dej-z(Va>zXdYb% z6PT3(KmogI%7hRJf;qfX8=an?5Q1heRx1&hs`g7};H_4aHm*yCJpXGPB5vI{VG;z{ z70dONmqXD5j0lo>oI8}}L4Te=I2u8Z zPK`hfZZ5N+0jm)L2#?Y{$deEh1|bSYHwb{hvAZQ`L`c7jG!Ik-!VZft3LgQJ(s9wn5P`J4ra_34a$8vSDufaCqh1rtun`Xhzp$wD}+O49M+|u&-w(7$8s| z*QY(uRBUY{Fhgu|X&+6Sr@@H6;{?M)PnobWjWfEm9c9CO?GLQtACgCX1Y*>GHMI%* z5`c4^XdA59XIWz<7*JcSp3Afe^l?^IWg`gZN)J2IXGFjR286rgCx07~(eL02}(l`MQO5Ht_iSSt}qG+1W_jO%}}-s`qL)xkXQ*5F&2b!9N)G=3@NDstO*R@ z6C%QoZICKlF_>lu!LUjKvaDSEs7qpmC@Tb5>A@+3_&!q20HhSt7Jf$nQaE+9Gzs!Rs}vp|x+RlQ0^98k180$f+?7k^QWAi!uTz#lA>PqAxma{}?} p>LmgGu139bS%oeu^~N`V{{g<9dn)wf#W4T?002ovPDHLkV1l;1JRtx8 diff --git a/TMessagesProj/src/main/assets/emoji/0_417.png b/TMessagesProj/src/main/assets/emoji/0_417.png index 1aaded53ac05a024f8226673286f3e29a4906378..b5caac88bc92311334b1c8efbd5632a3a73da047 100644 GIT binary patch delta 1831 zcmV+?2iW+z4Ym%DB!8<=OjJcja7@d0E2>5w&v+-bTqv?cfWj7TBlU(PoG000hjQchC<%<`S&;|NqPSo=pad zn5C6^9VrsQCx7?ZKmK#lG|eFJ^-sIA!!ME)5167zNPf)z%1IBT(9C;E`@W}?de5vg z;YV0C73`sxl&{Hc*(b;et(OF6Tmw!fXdmvO<3T_!73-caI*=NR4 zQzU92lyQuC9~rtZ@pdiwK*$OTt-Y&7DMY88wNY6+@ot&R_X)!A4evSuHDsk7B0*W# zi8b``<1su#qCvxG`HjDJu|aXt&Fum>v9nIQ@b37hYgh(9?4#P}Kv z7h>I_M1O}dyE96fScZT@q8wkNq4B}i!NBt*-Ig#8q9I(VW&~qw)M5l>9jCW7QlgE< zkJFWs?KmOQO4S+bwu!3Nn;IE67!6FP%4wQz6Ba2|&BGSGBDB+(ZH?UUnc%f*r`s?L z0cm9o!yvLaLBMyDwU8E^qXBb32^3DJ(=Y%6Cx6m$%Mh6r9SL07ABTxVEFs$ofXn6a z@p77x%CH$(*DyL?5#(ON)T)6Jr_19LBp`6VjpF(p(X#+Zk**H&UZPUvEIebLp6*R# zg@}zzm;{E-xVw z!GG&%OHp&}qG4i+>^?`qe>Y;cJ&M~<6oA_)6xgC6kT)cpv>%d?$ceEW2l)TLtmou< z!m!d-Jkjmw&pe>!wtgn+w7*Ix;T=N*GI96=eek;hBUZ z?YgEciyQ8iwtn)~T7NveAygos5?&tM;u6K6mrc0mb<>oEs!+sW{HXCc8goAYI2;zl z@~B7WT)2P@kV_cG=F(A66^d}9b$M?3-sEOF%n6m4JlB2iGd&yEqG-AXv;7gK*?&<` z*T-Wp)@9j{_|wT`V}$)QI2W7ej>|rg`&Shx1g*%8U)K!;61_$Zv3_Lcbh>4kpNp9L z@p(M-nZ|OGIT~#N1BA@;M_no*2BS@q3@4_|Z185(Ge~b}+miDQd-zgf+a9aVbgCXj%w%GJg}>rjV%X zVDOwk4r!WV01F_^aB;pcBW_A1L{a}PL|O0y!_Zc4X%xK!GE=TcGtu7^2pS##yRvRd zNuh3zoh-o5O1LfFI`$#Wmwzk-9Co5dAznZC$Zr8VN)ZNq5GbjTSb=B|7;+{;Fwq1N zn|vgM^kH?++s=U5&jcdI*MC6Kh!9>I?>#QQn6u!G>njR^>^C#PDmoa2YTwF;CfyIn zNMh+j5A91RX9Al^bRCS!g)*e~`{??9FcZljV3;>m%J`Tr5FInuaebA+O_-gw9wf39 zapisp0&PhwfveiDLpe$-2-;W#Z-#aTXuK1PQGLBP?sl}sIc>Bytba@dt6N2Z5n>&P zy5H7!M`|#d&l?=ZlvJlw*Zj53$JR$h3;x|J8lL-RSgsebdXDy73 zR6Pw1AO;7D6LEv~(NBUXoe=Aq6)<9y!C)bil}Uu(ibhlD-XjDJQRHM{SV6EA;TH-| z2)`m2fr3$K6aplKfPXblRkDcxCPEoBSO}39P^n@mqF!FjT8PV{gfa>h5GDW+UPVaj z)V6$f*58qtpaGd&msk zP{w;mERD$S{cg8L4U+kf4BPE`wOZ|%k0t8kn}LPhoYiW*-5_p$@wWtM|08dE{{`Xv V(0)I0G1CA5002ovPDHLkV1gZIP&5Dl delta 1705 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 QiU0rr07*qoM6N<$g8ifR;s5{u delta 1805 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 IM6N<$f+5Q<5C8xG diff --git a/TMessagesProj/src/main/assets/emoji/0_42.png b/TMessagesProj/src/main/assets/emoji/0_42.png index d8588c16e1d15c7541decb6e7284fbde42c5f531..5fac8df6dbc2d37ad37c97752fb708caf44c4919 100644 GIT binary patch delta 1609 zcmV-P2DbU357`WmBYyzBP)t-sM{rEaZw$$B5cHA@$Y}-GfEmYX2*iIe#d{{sdK|}W z4d;y;#cU1bf)VC_3i6s2@S`OE&Nu(zGXKOk|GzB%=|BIjsySvzwWy%|NYX_a|HkTp5d$||M5)!_ibAv0O*ws|Irfv z{^gQTEh7K`01bqteo<5*X+FApigL;S{Barp{&pJ3?=Nm@ zwf4U}?V8s7WvHRGU!SLo#dn^?V*32r)_z54)?RyJxy~b);cL73RiOPmB)}Ta4x8O> zx7n~v=>VVfu=7;6DLgB_EL0dyu9+n3lrKrgBxPf|EKbUFrIUL%v zrHFFqz<*0Emx+eqvvxO#Z)l^K70cN>14ylvt8sZ&Aoei)_TxBe>u?bjlo`)bN-B_N zBE_;O=F>2&+_zx}p*TZ0Ln^76Off&x1rchcc|&x`m2`+02k722R#gVudFPRe& z&7-Ivt}8d&5t>8*8Ks`r1Y25*y|B49XH z7GOoZ)g5uz0D>Tg;BbLg(VM&t%2~7q-3jKY4CXji?ssptEFd&GJmEC_tx%XEh^B23W-5#^@V25K0F%@O9rAW*r(qi00;umKph zp++&NNJ87wFvu`W!>}203_N_T<;Ykm`Up~9gn^q#pi%5KNi?gn6JY?^dLUBEVd7wp zmH1u|92qkZ2$HBaCDEv(6H!JfxPNHEVhljU4Q7op&xN7d=uscoQ<+ZLi7>X_#ZOQI z0;7zT@_6YZK^38<@m>cIs-z#&UkoI0-Mv`?N>G!y z-ju-`HzWcf@O&O1ai0Q!3n1in+_wTlApI!`9yfR)d#on_f@niifJ#joR0xnRMi6Jm zEpp6!&kf!HK#(=;Yxe@}3V)0)8H9Lld^By7kHyB$xV`|S&}uv)8m(&sTiG8XQ~uUB z)3_&_AmItZX9h>;cQ90;jpD%P0*nskfq?*la+?VO)P(5b)KBrtSVK3KvALP0;pEL@|@W0aD*6waESE;w7&d|SVE~wMP-lm^-A-X z9(6nQDws0WYQ3X1e&d0=(rG;*txn}P9=Mgm^Y{PF@aOdZJynKjdaXw_00000NkvXX Hu0mjf+WQX# delta 1940 zcmV;F2W$A*451H@BYy!1P)t-sM{rEaa1hdeAoY|C)qNMqZVkw31-p4Z$AT@zdnU?s z73_=<>5dx3X$Z+|3d(N{?wlWhM+pC}5dY^pl~@M<`>UQ{2#rw%V=4k}HwAY<3jd%5 z*rzAp%1g+dDF4SR|G_cuo)Q20nA(2^|IaV~+%4me4FAYA^?#%i|Mpt{{l5OUB>&bi z|Gg^y;9%W{3jf?b&TRw#_;3C3L;t)9`jZ3xvm5^Cb?dk#|It9Wk0+*Q2mbGjt9%>1 zeH5X2H-=j!h;3E>@ zO7G;eoQ{J3{(sHtmJR>S5XQ{Y|Nrmg>hGdfm-GMt01u=Nz2lgnQrrP4@3@q+#r_ z*RxyuGsPgJ{y68fswjN)uXA$r-{*wpp8}C+P>6qFiGK^hXylLA2jj8h%kKAmYW?F_ zJoqO{REY8Ax!e_!%TcC#855$P1>(mdfSgpCD&?<8S(&yaFkSID{uv}9FhCk8oBthT zQ=YCFBK&PT(U{fkeqX1*ZZ@0e=gmIPW%{htzjwPfSrgGVeDk6&q& zH7n$UU4K4__aF?)Uoiq@Yv|7#S`3~Zbn>KNDCP1r+ZB89$oqmNcC*tmqU;vB{(xF| zHe20T>=bsU*%hrXkq?BXQdX3yvoLh?0iVi)qEM4L-lY|!{=PxG7^Tw#XR8{zzT83Z zg3o^-x^6C>oI#oy@!w9eN4uCV2-X{9`&?Fd_J9AEcMDTzXQt_E%tLr9M2{^I!gOJh zd*=-lZG`H#LbkwzugKq{A!ypDA(vOdiSp2)deB3>zr-SJrAzHE5 z;}CjQ_j-Wb`bpnT(`o#}6JGjnw{LM(y>In|w`~-t@HBSn?b~C5_{j?}DP=uHuIn)U$q6d611w<$R@Q#ZElHoI{2 zstf@|TqE^$z0`J=xC3TRsa>M$D1et7&=>V~sgA2~ZN=&ZehQIT&#F;kjg(65u}Sa6 zX6a`D7`j28+NCveO_Q{G2b&VS>xs$H=zk~jq!Cjmwhyd<5+XYQr~qR$Du~wI>ESTN zLSZy&Hk<64PRY?^%`n_fi9Sl5nQm&DC*Z0PghJ(DpeN{~pM(Jfk=9bDG}ctvG@Bh3 zM<=qXxh0&Dnlw~MRt`FeW_ng7$qXtqC1j>eR5I)ENK2wlw6O$0;x%L`QS4=+KYvG2 ztkghcv(;*~d37a8F8x>t5)H~wHB}=vuL0Lkp$5VqhH&?-*ss+Ri7Yj8x#pE^5>0lw zz>%@05p9Ssgensf2@sdPJHeYKB~S)6s>qd13^H*#(iI*OeZJ~+o>XGM0D%umBoehs zzxeIWn`ej-D1+CLvrS!d0sNAVG=C<#Hq3bfCoWF-hFpNSL?_&++J-)JI`|Gd6mW!z z=wt{Y!HE7Pi1S~F3Is~n<`O_P$KtK$2a-+5&@19Kk-GFd8N1RIhFbLmAHkcFG9*g+!Jj)vP@+b#t|PK~^i%AoC#?3b-Vhq(y+pc$+F@8XkdL zlnKL$VXPj0{C}Sx4=W%EYT$z8p7_?t1olL*)%ce34cdxJ^ws^3Uvj_FviN-_7 z63#s}ydr2H`OKOBT@tuy@G@8(u0dqFTvpY|KB_8fU^Hq_ffv!Z!8HA0U{81%wWLi< zSv^?pGcw*b9t2q8na<9}6xVP>eNJej-paF{H-N^&@~$1_zk=P4?LgGX<2+M*+E%1|gCS53;{zWHFjy}rgd)gq049VWyqA+x>I1B#$53BGV0pkY;90&(K^E)vbq6ic)UT~11KqyMv{R|Q~Yqf5`FeuZ= zVEIj}bry)y^`A`SG;|hj!GT0qx58(k(?9>g96c367w5=DNH~o~{^?%{PI!*~>-_sq a_zOVO{4Ye*gy2E$zl-=i41U<$uf2E0cD$%7Kgeh=lQ8rPW< z*O(HWLj=512Go`j*qRfcPY9Ju2=~4u^SB@4q!;L{8`+%~?y?*I%rN}JCB#Gkr#%3P zHwAb%2LH(_`Nb=0G6$SG0?v{Zkys4Agcbev%&l?}oM#k-Nq-1eFAdK~0N70e8V?7$ zK>*=Y3HjxlvOfU9ls?O>Y2V9``_^YcB?@RyBI#Tb|Ik0JU<#9YN9|%7-U(qy0000I zbW%=J0N{joWTWINMHATVy2O>Yd6o?iQ!M}h1${|GK~#8Nwb+Mp;z|$&P?JS+n53Mu z$kAc{|G!@M41d-F0*9@7R|N(YbGXy83(61wV}=7w>$ZECcDt($ehp~tY2T`5OO;t= z^`~uZ_=^Hs&zdb?|D5M_Sy|KePrD4JR=xg8>G!lB?V(@QKoeQChu?R&E1>Z@v!>d2 zLT^0-;;w;3x?cg^Uf;H7f4(B1$fA8081^h{ZQIuCmw&|a3u6dZVrhlp8m@- zvw{|-G=Bi8gR2&BoTXW#XPxE*L;*dVP%VJfYB^*LH>A|5#)X|iW7%^Zx_KOwFc4cU zSg6!S{jAsc<5I$6Z97R6!)6d!*K4J)Mx)O3lF$~_NkD=}8Ei%&5D?T4Tbid+i>qOD zk+3X9WSp}oi(QF?wqj7R!*v~yvbu< zx__B2IKlE+S0ML^p5{%NUC;|rnB(w|SSrSgnOq#?{I4*MEfF{PLB4S7pCqg7x z1E(2Y{a#4cO$f=|JmSPxfXZhTT_i;z^gM9oG+UR1hOCowLIgLAH=~Y%YR(s&umWq? z_GEZL3|dg4h$t~(kT?XR87N{JhDm7RLVpcAoIG4+0+Yx%5+2(?IJpKmo)*M23D4aS zi03Qf#kSo18n+iiR}d~B(AE|Bf!cql)%8}1Pr6^gpTK^`S(x-veAJ-qiJ z2(k!D>|VUY2YhQKe8&eK>31`*@YqxR4Lf9O0yx*Bfb-}C+I{{RK;WQfu-g1`U( N002ovPDHLkV1leA?=AoU delta 1626 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 delta 2084 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 DlM5^? delta 2262 zcmV;{2r2ix4dD@xBYy!(P)t-sM{rENqhNAlQ@)^ByrEgpv~j(lR>`bp#iU}rn^vQQ zN4lO?K07(RqgcG4SlGLL&$n>RtZ&`5g}|j;;HQ7%uZXjcO1+_0+{};MvXI2AWar(g zm~%R)gGJ4_dZ>s<=G&w!Eil5TTg9tk*TsLDbUED2h?8zJw11UNpL{y3j78U-c8g>& z;i`nulWfe1W5It{&9`^lqkQGDi{R3l(!O`4gFo-aqx#;x&9`pt!k*yKj`h*6>fpQP z+N|fdlla%QyPs9p#f#_MwBOO9(!PS~y_x*{`KxzK$gpO}v29#YM!$(*WR9+aQ7h)_ z?c&s}^318a(0|<7$(9QhC+y_J+CnKLyFu!X=MZNp~0000YbW%=J z0RH}xFHzPGA3|Sq{)6y#xy_EEwAa_U%Khua+PLq7oqw`YssVfe00$&VL_t(|UY*xv za~sJP24G8;EXm9i*n5W=#LUbxGdsNh|Lc9bHS$emly$ssxl$FC`>AtIPpdsMza$X! zg?z!l%#3f=kAL4D|H|&+`T2QtcikVDt-TAr9oWr({d#eHoXh1tM|T&N^Y7kRM_@gV z^|@T7l7Bz1MlUllwiaD^lMsAI04zU`US5{Dm>o-{xV6CB1OQlG=4vrJ)nXZz^)UOs zH+1ptD+;(Q*XU}dR4PfgoleI)|L4Mga{1_`5KFbNT0#IU()@85epDcE0I*(B;&DX; z@EuwF@1GX2OG{t@V7-iVu>4BnW!}5s4~2ZMPk(i#W}^lOs6gg zTK>4UvGhtuYo(Y#1ysO`nx=`K%GYnm#Rb{u%CLG_+uxZF{=+1;H_BX#3aCI6C0WX0 zwG$Y_VfFB^X3s7CwxPe~{h1gu5#n}P^c-ItJHn)n>S4K-n)6Q=0->3eOsXVNL6iMLynIrLk|rt1PD9(yKXjw7AXRPr&_7lnskmel?s#>gCb>g6Piw}a?H4h64?b? zQ!a7Rs?{M78W;{zvpow_TUoVBD8dm?g=pijlrN*zJjAg;5o)kYQ;9Y$LODe7m2+F{ zOM+152y&jsM{s^NnAvHwU_pqoT^W+oZh!Nd#tK}Ga}X$SUa4b&QQ|ybst(DwUNj|( zeX%8QF^=N|7(gfkp+aZc_PA#nk`$R&>?--T%4FKIsP*}jz#(NARUl&}pQjIq-JWyp zZE#zW z8tjRaD1Mwcgu9HH*;c!qN`c653g0vg!$dEl=j6+a0_2jUObN!lu{$jU2A65a`L2o> zrp1er@cE0Qpd$bR1VXSou14lqmVa$Q5QI{^X{cdc4+ClP@z`e|M1dfXhZeU42*%Y( zh;fKaO5wW@B8VO~y0Xlk02v#CKmgn`AQ=CzyUH?@z%Y3fp+^dJqyWT1Az#J_C5S*T zn_o}t62mYoDT0+zgkDIe(}_ePT_=?^Wr_O?gc=|qfN&kQSqP+v6q)7Y?SJj#UUq~` zkhsKsA;y?!w^$H60XNZ(ak04AZC-sxj=ZC6HcOBKK`c>;VS_Uu#zlCTxnGC{hH0g^ zm?B!YSGVe3{qE6wmn;^6B!CnmYNshFOiXwo7#HCulfY(JMprGQv&CXEi64s4b_&=Z zwW~<2*mT0#R7vJ7)6ffvQGfkzl>7wY1wko^dRSGvafx*Z*DQi_jMU^U%Tx=A#}4AX zgYgN_7|D(vz4-Lj=*CMe5HMT^ZKtH_mSq`{y^i<3cYXb|_zVD{l@!z7Cw$m@TI?E4 zg@wVm56MC)95F33ytnvtaD9J$dUk_4Xp%@4>`f0J-hZct`_V!IbAKREM5oi}ojp7q zon9Y2ll7GN^n8DCdVha(dUo)9rJ9;Vh$-KnYQ!|dkKZ2#XQxL;Dc zq;<8~mo}ydf%oJZG{X^e0>W8Dsfjlx>bjxvxKrJk=gFUoO;xX>lgXNF0vy&k;<%5n zr737*$}nYO@CF^|q>2RkN+cqMA{8i6M<4S1v{`KdMo|qAP8B1v zAJYWi(y}DW@qf51YN9hx07y1sm^e6z;!7Xth`R0WVrlJT&7&xiq7b9`a~VnOAf|&^ zBq7iu^tEZv)cTr7k~}41pp~vZoV!Z diff --git a/TMessagesProj/src/main/assets/emoji/0_423.png b/TMessagesProj/src/main/assets/emoji/0_423.png index c1bc45f0d7a5144ce7c307dfcc4a13311467f7f6..eb4ff8d0aa37c5dfdba9981964483f3fb0a85547 100644 GIT binary patch delta 1746 zcmV;@1}*u#5#bGxBYyzBP)t-sM{rDQHxtdvOoZTQ#`74Sj9yEze51Njc2iYU6y1^ zwt``aHw1G_Gs2N+r9A<4HVod@!v_on$CYgDVjA2~1=UOe&VQV7=v)%xRt(FSZelM9 zG$9fF{rguoAMxqk%|`$}P$bU8s#$P39W4yXsf(zohV*MC@Ma(PaV_7bc!ZK|g@9lB zcQvHG(Y^ox012Ui~cpo|a)zZ12{lnD*nK>Z<00qKHL_t(|UbUC!cB48J zg~txq;F3h0-hW(sFRAzaAL|}T7!yNgCO>9_SmSsL%Wm@f@*EhON zF`11hJaTG8;F0=3iOpj;nw- z(96r~Z0t1t9LH*oUn=z)09~2QCtdT8Da7op#sLrj0e=ig^YHsVHmNgzs{(XA5I}SB zJ)_-lCW6vQDab9tjUXHH9icZFjV3e^qqm!i0J2;WKx5|{AH4}Ap3{(yN3S4wQ`8sL z3NRi|nzcP`iC3tYIbrC`XQP{np<$Ps(xlt2iP4avY~f$ADO+q3wWS zsQWVd?j}Gq+xIyp+Vw;v>1MSI!AM?s0|+5X6vw>F(H-m5J10qr0gTY5w*sM$PMIMZ zm77anZ~+L+*=CuBVL}}_u(--`6hkQOME9;0j(<)KBhe5Co^MEqolpv8g($tD#Cub7;DJ z43OLq3b@ZAV3ML<0e!1g1?0m|h9Ch)LNfFx7FtfMxqchM6{NeVN9 zyMM^dh1?Q|L}|21Vg5U!K8TbP8Z3JBhDv1$VB$CqxJQ=ZGEKCLqV=<3bctA%8bSg{gsk|Io_m+LfF>Vc|ny4 zAEC`)BS(ve3lLBW4niwnZT6Kw(^%okIsg;v1<9(>^X+zq0oEj>Tq z-Db8j5g>O6B`%myj527U0xiG|-$)zu{s-fkN)v(XJm>uL6S->C>Ge2`5y#xa0VE1o zN*$WC?huV6NtqY8G4d~$;6h8HNN92!CgX zefBXJ><=-xSZKr)9X^iPelYml2A+#}WG89AvIIn_Lhx+8KV_eT!Qhg`P^=llb9UNG z#NeJOToF=k;Nrb=;nZc`p|6_L86dSZ6%&NND>NgvnUyLp!%u#Ob)s zAWCjxog+>k>-E_SNc!kk)-#I{27icnyWZ{D4yI04{z+$w|?6kY}=I145YDDZIP`;`^3EfG9GigASRZr7Rar8*wA>kFI(X9pw^ zK7RUD(Gyb$7scmno56mDNuAGi=;!pXg|pdV2;T@e#<*Wav=|}WlRq{w%zthu(uDW- zcjaR!Pfla`Ir2F6{Zk;BjanOtN){->W7BN(3PLT#>PQAa zlw^8&kn$wq$!g1?elN>lJ_d*`0s*ifbZV;W83aS2l0pDX0({c>+ow#k6A>_yQ?4jX z7!dweRwrTr!MqR#3ro?{Pac=sEdwAx$>kHmqCOCQBCBrzg%KsjBBQTD{1DRW7=Qs8 oMyCM$m}0j2{eG(jbK&3We`n@c7X~+(5dZ)H07*qoM6N<$g8PXeNdN!< delta 2225 zcmV;i2u}Cm4ZIPMBYy!tP)t-sM{rEKoK?M|V7Hf2yPH+Xt7pNQTD+WD!>M4ppi|w= zoS}Y2x}I0RrCGnES;~%Otb|3mn^DP)V%5Wc<=Ujnw{V&Pqi8+NlWMDLLcM!Z*{p@+*sR~SkmuX8<=K_n%ZU8^`{2@`#))6y zyq4e5m%E=;;L?uVv5VB9d8dRwg;OrlzlFz-W}00#h+rd)_EOF5UylkDCy-%3+tJ0Oc2l8>cF5Y|w8zoj!=>!w zppjpN;F!cKP3!000LKNklX$Z^Yhcw3#i(0WF!CnjX6@E0D$HBeDhHg%L%E#4z<(`T>;AF78u@ic>7zPdRA>|sFwMc& zX#PB?Q)J4ra=5vk`o$zRR*TH=Q5bv`G~wb&IQ0+9n%q^k60ahO^*EeGUog$KB3sc@ zSo?@Tj%*eTxhrkO!-Z6AWv?OC1tNSESfo5{x_EvRIW(Q-bo z41a_ZSd-7Af_cz*L|zG!{>V@m0tDOzWuVH?efcCy5JC{-1dV7Ul-O75Y8!+)3VFq} zl$s2+R?dQWimw1ElV-w*%^?Y)$`C$(qF5cFC^HNL2qt+h-=M;bkF)?GG$oH|%L+Rf z&_#yn0#d_vumZw2LVAf%Fif^y&Ys}Ajeo?N9cx%*c%EU31j%NJ0uq_26pbwraoi78 z!MB@6qcPO1L5Gzf2N1;u7>J+(78&VqYw3`sc2rHP%WJhp5!TQw5FrKvuu~W#WTcTc zt4gw5EaDQ15Ce9IAQA;INR=Vynv5|vmRd=#w(CllA<-Lk&FuHlkQ#o~0;CKT5P$UQ zQjFvdttbl5^AJPOOxLyhV9$(eu z6)k)z_*H`}1PF+bjolp5XaF&6v#tlF+x>whG`=8$NuVRSf%EF}K+v1%mwU2B)ASGo z7)9ImJOc_5tIdBQ2ohwxU4}=3T7T*!Mg>GeQd!+IDm};PRSey>G`au?Do8L43go7U zzaZiiMFPK(0^T4;Bi-c zf(|1hKu9Rq_VsNK+UQNiYA%-xke+dEw^fS46jDIEOT8E;hLBXV?|K!H%j9y^D*Pfy zlOUjYdRrLs&qR88Qw4lB^oqk}IIdZRI(tSq*q@$Z=$b%FugoI3MX4ybp3|yKp>Dae zv+5cACI~3K+v)VWue(}(=zkNdO9#AeRBQ|(Uf=zk&t~&!4*=glItvOWbNh2XUrZ+RhmPy^!3ZPL?~u@Y*VEE`azDG8 zT;AVR{TT4-{k)$n9t1K2d5u63rVRuAnaGrJHN7KT>Ht7E6_=03m)p zAJ5?*{5G47OE=YEqMyg5`^f}^*^kn>=(!z>BJX_RMCN8Zo?Twf<`1RPDH2$pOQq5R zzquHXKZ^zuR3wDhF@JQ|5VmF^dd2M{=)*hnr5$pg=GJvf@p zvy1U~TsqJDK#=2fTpEwhv+&R$!BSy;#8};My>MEZa=t!vkCAjUIMT_Q4KMSt(G?~)~;?tc~OWi-xHi4)>Iz%E6P*agLLFA~M*=hxM>o?r5y0v8HL0 zfj$x$L&rPGX+9CKrFxhUOKb?5)^2MghR8j2(scAbJiRSHMG)d(`BG0D{lQ07RZvwh z2G)Pa=y{$Y`hT+^lMpLAVQ1>&QB)A3bu?IWKu+kRk;}BiR!7&nHKrC?x*F8;vL2{U$(?Y`;VfF3KsM8s_O%R}s-E;`B zuM}l+-PbWk8@9zVe52PHjsC_OjjmgGp@`0Q*pW)_9e)?eRSPiyQB~L$8w@U!$#I6R zySA=-z0B(ZRw}-aKOuoZq0zQXG(<44`3hX}TyVSYzW$*mo!r|$Iy~IkdbjgIV=c=% zSWn=kNR~q3S5fRGf;qg-K&93#R{OAuAEDygj@SZ)R0|`-R(`93yNz2 zu)Q0{2r6%{SR}E#y}iAgfX|2jf2FX!UoZF%z=~Q9vnzr600000NkvXXu0mjfI0Z#1 diff --git a/TMessagesProj/src/main/assets/emoji/0_424.png b/TMessagesProj/src/main/assets/emoji/0_424.png index 75d9a8e85e22f10013662720de3e77e3bc9c464f..e2035c734a089bd7a648a64be6a82462e93382cf 100644 GIT binary patch delta 1680 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 JPDHLkV1j-U7%%_; diff --git a/TMessagesProj/src/main/assets/emoji/0_425.png b/TMessagesProj/src/main/assets/emoji/0_425.png index dacacd14992ba2c487d098bce2e1327ff0157056..2e65a7f90a28c2fb11d29aca5217f743db8586f1 100644 GIT binary patch delta 1558 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 delta 2060 zcmV+n2=n)n4ww*-BYy!AP)t-sM{rEPre91xE4-gq#IR<%om9iBW3iP}w3tw^l1?%s z8@-}g+slrwjz`M0bH%M@+|HN3qgp#FAxStV&$@P%bUigC9^=-dabs7Yd_9VAK|3lU z-q4s>M=@1EAu}W#DI68gx_iT@T^SDyQavU zH!#)0hFeEFbyF(p;k{l$BmV#X5IJy8cbj01uDsITfug!7UXEZ{PpG7y<=B-E9yU8V zI_%@1^YrrC*MHKvwy@&q>h0#nh=hHexXJPB&It<=cW`U;&iSMO0019!QchChj;AuFGt1A zriT_%&K>pM<=%UzwZ-s8mYTYE3r;A2G7;6?*jw&Tiv$%Th&AjMVLS36BlDzi#-Js)|t*M!}c)e17ra z9dqbaN`D32uyA@928h?WrupZOiM=|jKoxPmL*oG;#C6@1KW*a(Ge8Lu1#H{1?ameN z_RDy2mdfSQ+#eKS2sOhJUjVOIEcRPp)LNHnoSn7&;CU9HCu| z9&zfrfd#KoB>e`F+R7HJFknJ4s5OLg)T4Q%%wudYq%9n#-m2qNSHrlCsM-J#mg<#C zy#a*^Fjk0_<=!9+F)ku1HF_YN8m^RTsRASxU;v?pznx1a{E!KFcPxNV^!#cKVF;8S z3x694n)#SyaEBHnoLZxSB@~L~K(DpiZJi-Vufd474G^@CqAk>sQpxwqWffPfVYFeC zDmcg-RtN1R$;d`@Q-!4pyW3cHv0GGi1BnZ%ER}e51%G>Urg_?jBj9}8t{BnvEN1A` zUdM1pr8!61(Yy-G8M5 z@eRFTIUdn?9tPj_LjC4uWfW=!IxmdVQpJr$$?d8LBSNPOfhSNTrRW$pF+vF)fk27P zPV%A%0*w@WRs><;(TuHL-XP4NfMGB}{P?<)j0nT>*)aPMT-P*B*Cm>!lmlaFpa{e8 zeTx#ix!2QtAquL~MH2uN1PZV5{eL1Rf}o5wB6_{7+l(-D-zgIwA!dt4F`Pz4T2Q`0lVr44KE`rL@9>`YsK)FL}s%Q6+%!ZlEk~{!sJ`cW|JXoCX(BARAar0 z%;q>P-wL|Cgh41Rx!LUCyF(Ef2rY$oyLMzzLQN!6Sknj_Lei+9C~}9TNq+<6WwHd5 zRjqiM8$@nbEO)7ZE_nX>+9j>dN@1lCa(#^&`(E_MIJv{n#g?W;Nb|*bG#Z&MfR&<< zCmftUNkAOc0)a(+m25yH2t1K~PDan8;cVJbRzycO7vt%4IGirbUVmH-hm(b*N!<_xHu&r06$scp6k1P% zF+F%Sn-1oZ<`zX&Ot=MeI~paPZbAHD#O-`phJ5!gaj$87*8#D$8A=d$@o+mH4zI38 z3)?9-3Ut1?yukNwJPuDn(R&woh}a@pO$wjBosZr^L2 z$b?@1yb_Zy!~EZdkj@?+2$AE^M*x)3|D}u;p*M4RC7_6%gnwt0)agMKgi#m-)F_*D z8Y@FFP0VK1hDpvLBqS55mdXqp2BEE>7ka}aJaI{UKZbxd_>&|cmpu^L@#9PokApD7 zl-5FInYD481RM%F{q$ss(bDLn6&SLqtpvU$w;+%mE`dnz9mNlY>Mw@b0)jPV;oYT> zJP07CJ`x*@D1UYdF%=*!(kw46!ZquB2 z@0lm)k|^z#Ch(jq@trH`k09v5qtS05?ZKVqyqeUMZ12aU_0X>N)U)-ZFWR1V-KK%q zb{yibiul>M(rz2zfF0(xk@C!{z*-;5WE{|jTF!b!_V)Gg=zrkwnkV|SMCOPe`r*R1 zOBYEW4D6F4pE?out2^Y|&wyY`zoLX*I31*tfQwlO=&*sUjad7;Py61z9|Qm@1pxiR zS~U^{x{eGWWLe+<000woQchC3>)VFi=Mg9N)1;0r|K~#8N zm6wNl@;VSi1Amwv2>(@a@0H$L`ujiC-IWXm2U5mhh+xk*JCcp^a9{0Kp?3S>uWC2@ zPlIl6IMj!rUU%?V>o@;`Y1X>E<>>kSLeC?;H>mxV(tPYKi}Fj%vN!1e0@4D2EO>tw z8s!HFybK5Zp9uY~jA0Yq>uQf-F@sRHZ?K=d0Y@yq7wX8yU9z5VV z9@lOz$nI$5h0$2g3&A#?;3*v-0c3fW1(e>cIBLt0J`Sg$HAjGWAgO3V5~RHGb(xM8EO>)_R$g2Kr4#sX5rdc}alx{=1CKF2=8P(XlU zdD4tthFECC`Z_5soDM)lELNsh6y(TkB}DcDowUk`<I@hW7z=|N1{`KsDG6a&du~EGSNU`? z4V46R5Vg6H1CA&md`MKzsS>$f|I3}%l79%5#Rkztis)i;jsv6-BNi@50xPunZ4W#*Mg-11-E3%}iQ2QYz}{>yZCq{y^8Bw|Mm$((!F2_5q=4lZ+mZn-zTd<%+R69%(kwAWq`5*!DXQ*Q(n# zGi)MnIMTel#Lmlmk^u?tJBTotZP!bPifuAxQ;ASDvC7NB8yFHeu^BTl&3{s!fG{Nj zZ=DhWHE?lhIqiHqrGT(8%~GC-z%USzGn^m*1e~1{K_YzoE~Hsf9T0|}hmrdT2uBwI z36OAVgku!UgeXdCbpQcjT-qS`HM-7At17_ons)i|SXovA!&;KELmS;c=#|KTC zFscB!*NL=2@_m-Rl+u@CtL0fln7}^nsxE8<{#0mjAvr<=LScenNq_uggEO27V?8@- zZ7>|;KbpWa5hwiRS>jupUC z!2rAp5&B~ra)}BCkqj#KMg;+~tUUavDl&X5lLA=b!7PIKK2pg5NFgFEAmLYxMh?j- z1Vja)0fgVF*)d>p0Z$^Mz4}Vb;A&8Mez#l9Wcd-UD s7=l=%UPZv))oxX)bx^g^`ffq~4~md>syyB(G5`Po07*qoM6N<$g8dXTRR910 delta 1775 zcmVFW0Fv*S=}gmJ{dIir1kc z;=fhbm=oj0Wa!a(uZJ%C1@8pcMVaDDUE%^}i_V+>-jiBl6~=r)&u-;z|%j4G0tfCw78z z&Vii#{~z{xT7QBC#0GEGJCe&trqA4N$(DKfJrm&NUzv;t)6e;SeN_WdxxWIM04#&Qv$W%#Dpf`=V(=O%6E-ebkA-Nz?)h;@Kg;?LBKU|c_yAugiTQ_OC zDhdigTwS*9+oj7YmUXkK zh=M_c1T3I|O?X@r9Bn;p?)@;{=;jq+q`Z@Kn34(gup{oronmCS2GcaNyd;cq zqEzV$KuzZ{#gJWe^c6!JaY2z54dVhLET93>rV*1dn_SpHfxW%mU63KPDCQtR@G50t z2Y+WoQ_3nu6U|LZB}mf7=qY5Oa80_(&Cm*O;hcd;0}+HNs6;bY?xA%Sbwpn5WPvXvcgr7mR}Iu*cclGUtk)pfnMWj z8^g`V_jjl1LWq=DvBoyHU_IpNe4)l-Z*`VnL343`gO77@)fH~VklqMGf71tofXt7r zYL&UJln)=CAPdvXD#BymH;5+X(91)X@Jq`jNwbXDA}KXN@%D1hnur zx~F<;bc*N{?1W*JI(5Beq)at3cvOrv?s<&I+vUmG?TVFB)u-k420flmE}TtE=~N$M zMwE(>-lJ$T0|nu6yxpHvx@ye&w8s!zlpO1mPHCgpV6Z?@ve~4k7&1>03V+|GPS@O==V0sG)Y zQSjdEF!BFu!3n4-<9K3v+@n|+vJWrG>v(W$}{Db9VG#m~`Z&3gL@*k({Vkbpq R=!O6Q002ovPDHLkV1l2)R>%MV diff --git a/TMessagesProj/src/main/assets/emoji/0_428.png b/TMessagesProj/src/main/assets/emoji/0_428.png index 156f07dc30c6923a9f07e07a64051e52d35902e8..ee83b6a8e198a947df37e424fc09c71278557877 100644 GIT binary patch delta 1701 zcmV;W23q;%4z&%CB!9qAOjJcja7?yyNvv{Dw0c$TmL~9;DD9Re&6QWzi8ZWwT=JhR z?Uf|Cc~P{Tgu8)MxOYv`i&VFeanf)e)S!6VuZZxOCf25Y-Ls9^s)M|CP3)5+(VKF= zfL7;Cr*>@cErZmZnW5kAB({LNjlWMzG9<^&hv|BXk;(yuV%((UU_swV<-?x(C zfgRzzmP;cL#a|rwt~=wwo3lzAc1|podSb_RK%Y7n`?g0X2LQT{49dNwm0|+ztW=UC z4*kJct%w;r0000JbW%=J0PlI1oIvOjCO>q?*ZgL({`Jg2oKYD700ogrL_t(|UX_*y zR{}W{g_T|eWq&ih_eyW}-T(iu_P!8dU=Z~V4v^t}-d9de?!H&I+dHb;z5A=W?Llie z?8veM$#Q4dYPEZR!L(b$j`#9kRWC12XE8yPqNQ1t3c9{=;`M#2*qxqnFjfCo~PSCQj6B)(vD+BdQw zrxbt}1qsQHd=fqzo!)nZq3jXi73!J!#)D(K+^}4caSET&MFOdHbs&c? ztJ$)&4+I0DLb4$6aChdqxY<|BF<8BLcD#vQg9C6?a)5tA3aON)cB;}AJg>#HkUj?I{N!ycWArNI?0TK%csv;(mPYXCi2+JisYS$2kONc#- zd{8(h7GC%uP%ICoR5^W6tETOi?ks##6a^GN0Dotnq-lIo8mCZ_Byky*K(y+JkPxP( zXb>|aa5yQjE|rEZ5VK1}%bD>!2q3AdDoL8cOn^YT)V{od2%m@m#FPspO+#W;nT!R? z>j*Ri{!C8bh&hDY0VO1nIgKqvE$Rq2+-nLU5V>B@h1Qk#DIoB+K| zjDKkqvlb!%t>F4-Vq?ey`q3%>gh9-vh|!U06<`eHQiK^iUJ$%bws2nlBEAD zlnMv@o_?+BR1P0D>Z4_#oTj3w3INX=%+SW?;qwE<#}bTyp#WiGXlLWg0XL8b5O9$O zOr1l*fUrW{QCX037v>%l-mdL90-=gVB7d$5AmE|XszCfx+jE99;X=jVWTHsw`b?@c znv7IDJ|b%SMawOL!0agb`)<2f?AB71psgoZ+`i|^7vk{((H%XNgdjq;7-fss*HK>a zq2{A)F?xMnWVuENJzhRd&NCUas9X|4n-;s*-3~wAX7frpv&CYx1!7W6HI9fQHh(@x zm~6S>h`iXoLO|r%v8K~3UmR9+c&Ey)<+e^j#fY3-iu5H0zYQKIimYuTF^5jM2X&y{Dm%Q#(zw(Na=YSXzu z`1<{I57ZSs5H=LYp(FUpk$(-_a6Ej*c~qHl0`fpNzEM-R$cCnxwv4dlEsikBrITkCKxpju)|8n*~&%8{XA3zN)Xx0{&iRD(Dn5`XRZDHSjj9sw5L z9~l42306Ig`iOD{6ATlo5@;}gR09m(BqN+cqBlXHLi~zh`7k0NoI`$oPXOZ{9VG}T z;NZpqzGdBm@H_P%Xe^@0gm^ds0?T?pC4Z}4^PV8SA06Zq;J(?r`-}RI$Oa0yEC3$4 vg}*@>pa?yPUFz@Z^&T5dsL}7;8p!_vI1h9?h2>G+00000NkvXXu0mjf99j}p delta 1879 zcmV-d2dMb94dxDzB!A>kOjJcja7^aGe&NG=xSCL}kVoUagW=PS-OYy2r(5N`iocdw z=FEuZwUD!wPujV7B*S7QNr{>v|q+dPi-<Fw?N;lcXdyjqH_ibW#y>YxxRP}<($+{LyA4L8m=D z66&`*t&f6wo&K3Jo<6*2I#$k(+N}=&+Gk@AjQ?&07=LekcGP)imd@F91oi_xj2^~k z?e{?1U5^7AA)a#7`g4Y6LS4>iG(BtosgKx(f8Szw-C+*~zTU@f_q7xrA_SxVYC~Gz zt+8U+;}IJ6?7)5SI06_JGJ1`Ku{Rpqn(d8n4#B}Uc=e)@2L#a68a7w)eG2c6HO4F) z22=Q(b$|4mJkL|K#-0upegaLFSr;tLLckQ%y=XO*alw6_Ek~~~Jg_5R3{tGGhlsvX zmnp@O>{wF|HR4;XDV`tgN*8u*a2NtQf#WO|-$M>tf$`wt5?*wV!QSOMjM28HVx+~Q z$$cm@&4Q&WBu<;A$xyPdKZewYH2LY zgUNjiK^)EIrdnWov2*QJGSC!WYuD1GFin7gL73w>8p;-CP5T9aW9Pf;X_o!w@9vtgnzgQhV#*L5@Dkf?^#ViE%{B2doN)(?TM zZGT>^#uy7jrt7L|LJ}wkFd__!$r6tPc0_#JNpT{IbpQcVY7$k29ijx2NsJr-L1$Pb zGoWD%EbgzJ2?2y{LkI~5W|?UalwlAE1Dqg3P#m%-mLN%8$^inUN%1|Dfo9jJ1te9~ zshl%5~kUa(_`Z2bnHOf;6}f<5&_5_V?~TCpOxVqQJ~y zKKvw26Ssy4jGm;4ZxWKl&?}~4CDPRn;+kW_iSH6foI&+Lbz7kXsPeM_52k*aV+=Us zKH?h?Fa#k%misy}Tp-+X2@YmaX_{qJ4eld`!{yy|cEubFL5V^23cNx$^$Wn&GJkyC zpp#ez0z2vLt`V6*h@9Z*F?)r8Ekl4@eA6H#g-LNF`N!T$Jz*@&DDS-KCrP5ZNC4q4 zgjIwl3H6C<5Iu_-AYejv^h1IWDughS=jB~l-aWgw++K5BcfBgh^>bpnL`^3$lfuCs z;wlcq6c9!-Tb9f9d|p1ewHxK$tbbQetNHwHLv?6t7D~~N-X3C@3j}>CR`ccR=i_`m zt8TU_p2~7L|2dy87Zesx5K6&62N!S>gsD!{=i;e+{0S=WHfR^B7RxyveJt0-6IJy* zlKlQYqD@jjsAL0(xj+;PM2Meaizr-OPXW>1M|5;QNOaX*6vYZhm#cNL0DrUCX2qri z#^Y+WEQ(v*Orn5x_7SaP)%Q)6+%Ae`S(dB2yUiAHGb@TUKMEmc1Q1zz+&VyRp zBXo;Mvh!9W;^aOxO;sR-h30ue{UlGe2)r+t`F|(Pi1Rq0SP21yfPauQz)NOMjhbL! z2$N=UbBYd&q6FpyOQ{*InxqiKG~8_&s&1xnBz2k)Z5Bp3HC53Kq=1X)I^^2kRj>{k z#F5;H7)oInCMLu%gj^wn)c_G9iK0kuHzBTNK-4jWAUuLZ3PIo@q9~MxjfGsF$g(WD zK@8Z5(L%+dO3i_0sEWk93ulEXyHPn__JYk zH8aq}rR$UeP$Yuar=9mc=bmz34cXF=@LmlreQIva9AHxa@=zm>%e_7nV**9U#HJkg zKls?*IYLM+YSQD&&L_S(=wBZDK47SSeA*XJ>z|;shkf|!VTk_Es|VX3^gn|8&YK|f R`Y8Ya002ovPDHLkV1g9GgXjPN diff --git a/TMessagesProj/src/main/assets/emoji/0_429.png b/TMessagesProj/src/main/assets/emoji/0_429.png index ed500cf080cc9fb9e2995027bfc977f780979d9b..6c1ef37cbf99b5e489f9426c29de010bf9af8a06 100644 GIT binary patch delta 1804 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 delta 1797 zcmV+g2m1Kz43!R$B!BQwOjJcja7@#A6vlij$Y}-jk_FCs9LR1CyLmpxf-UQU0?2L+ z>5du6c^%Y!7|Lx6@tYdRYY4??2ibt>O9-a zkX9Z5|H%-CWIzA^<%x1!|KTy(tSSGGWG&@lhlF6x*L za_a(y0000JbbnG#QviuE@BCSv3>W^gqds@W$==r9%+8LN000HSNkl*ST7QQOn*w6^QKB%;)#K zuIseJCTB4^bzj#pMDffz(hVda%Ws;9v0T&^5i&M!Zg}sog4yf|y>94eIz-=Vue;vF zaVQMH%Vr2^1ZY_D38Xjf6`)l|nkcEHa6>Zr|Nmy+a~wBl+M;S#`$C0kbRL~! zr&4{v8jx10G)H0C`%#pT*eS=V8pa0po{HG+qQ;y+kcE1 z6R)RJ3!{2O(=vbFQU_N?wS7ioGJbrhNI1PRVUN`Xv1bFwOI1B7^#tIBQ_&j%!s``! zIGso!!tDwFia>rrL6rq;%<`|cwZtBTKVf0w-*t5Zf{YW0KD{y+CIE=Ifavb#Ju$!Q z&dqfj4A5&Rw*dEG=4d`9kih^k7=IrSXCmw%ArnIzjG(SfDJQ~Ay%j+0n{!A6hltt| z!z^jGl%hmLt`!)-B(#>OLHHAUs3GkqjG_Qw`cO+eMTg@WIUdAL=(M$66a~)#BCv-# zivqJ5Fc2bA0EhMJzRzlN1VVg4Kw;+S!pJ^a<0Rlo@Q_mGka1%U-Gwlg)5rv&;gZt1s zvEHmvEQK@?61%b?0|W{E9N#?v95nQti74^`e9(qQ6E~BKaBs$Ne)~6e zmKbAc2-^MMf+e#Xx?v$1F)+lNM{MMhi{s_9e$2Mptx{WskL*!Dn}07r@J2+7cXxv+ zM#0I(B46rErD^dlsmip*qoL0sjWH(R{U||~X>~#Nl*@Jc-&3W-F2EQw0Po_mQFEHc zBJ6RRrl~0`xRZ|v&nF}7x-%Q3GbACp;9*7)VCT?XqPb>lk5HbMN!UCsxJKo6Y5oS0c%1sA}GxEN2 zy>kr$W=LQFcZzAhcF9~MP@;e#u10(3G2 n9gU|R>;EDX6T|+G`S18Yn^6u1!Yv_%00000NkvXXu0mjfNcdh& diff --git a/TMessagesProj/src/main/assets/emoji/0_430.png b/TMessagesProj/src/main/assets/emoji/0_430.png index d3ea4092d0228be0371fa45847cf4324c90d61a9..5d5ce72ae52a39ec84a754250691c7983c67953b 100644 GIT binary patch delta 1714 zcmV;j22J_g55WzPBYyzKP)t-sM{rD3FdXZaC|EHbODP#zGav7oD9m~toM9(ZE*tNf zC{ivP@t!O2n<(s)BTOn8^r0?NEgR~OAnA@D?2{tMaU{}l9fnXak61NpJtd1&GD;^G znPEC&Hz3w>9F$!*e@iWOL@HG<9qElA@|`NBP9By(7D=_c zlK=$u9K47>_(99;;Y&&XDu4tuZL@x7Q~nc^JbvEWyMGx7aK`2w>&@)p@>2s=3LCH2gCKKg4#nC1!|sbuP!{)izj@VD`=yzlgW>-gy|D>!cq- zR-A*^KX{1m`8D3-M~1=GdhN%NhlUd<013hZ-|u|Xj_b`j@Z)i8dL(E%N`nc6p?C99 zBcRow7=Mo=(?`p!xK46_f*gLQ+0nZI41P2Q;>Zj=a8#5ca)gz`yKX3Mz!3UoydVi$ ze2>D^3JOx^@Sg^aW(FSC7`rY>YRge)YDZ)?E9q~xVE4n=aFv_P$Iw@l_}f`fK}+R< zA&S5s`u$Ty;Dw+L=Z+%`*EJHz5~BsP_*E}WoPS+LY&7F8@GzY@w;8hwi%62i92o<6 zUo4VjX&A;lG9yU*>-4Dzd=tV&l1Tt8ju6HXZiQN4EvA3^Wc-@>)J?`D=N7=hgCc}% zbOWt07Um}kbIv3wbOJ?^L1o9t$oyCV3xXjk!*fZY(&0ilN9Fju0-7l$8J<6+%0>Nb zDu3Xy2&tJI3>HLro|b}X@dL-eL8Zm!M=OE~SWz&@WV!tNce&)?m{wm7Lok*|>hl~@ zc#lm*7}+-CJo#I)q!^_F4Mc(phR;Rg(Sj7Q10f{MMi@>7NWpM~JQ5rZ?g)2{oi{Yc zsNl)c<~o&MB*3dg=k_w;oH1t(OVV%bIDha^paK`v0(6{Rfv#ed8p@nS6#aL)=L{Yy zg(VLJCqpgaIJP=Sixf!|{cdc&ze983Fm7>{X9q{QtDGFQAzvL_WoNmp6@!yHy02!G zfP%9uHS$zVCRxVc6+FwuD4$G>G-ITQqj~qZ63ymOj0(0IttN-nWTNbJrB?=hm46y4 zcVHC$n~@@xj&`hYSWF6;jSdq;CHu^(6jruZG-^yonMB2S%*3%`DD3$d6w=z43ga!^ z>(z6i@6$r@wj1p&Qp{~JJW^a3r9w|fnNnbQ*^ScoWlcv19DRGqMyXDUg=1VCFGv@} ziLj+yrK3D~dwY3FNBdF%xBV#P34aXcqjW`uEE1=CvLyFHECndIoaXy%x6AiwwyQ(v zyDZ)3yIr==r}Tikt`PUFW7>vL3KbTY`fjya?Vc^Y%z(|XrZlKa&bhQ5rG(KwQD}yN z3Pu|zeyx*jM+Ynf6+$V)&`uN=s4$#Dp(8X8MY>f<;DZWgtmS zBq#^A!ceXO-8`Y~D&>kop_dMBOA8f@lK`PQ9Q@sO>y(QwDOlksu!X~@bXKRJeNTX* z3w1Oc+I>+8uVdJdSK!Ohe#U};s*ZaN4NWxVI(GFU!6mVTA`Ct)rPxfYLu-A^Mb8xu zDS+3P4jeEeco)xOI3jdjUVp(-)zPanG*-nmiWvOW59sI};Q3}o$M3*@Eeucxti~DI ziejK)7QnneHDvQ&dD%=@jkA@MF(Nu2fuW7Ykc0%B-o|KXbfUQ^%0P#tgMS3)P`TkS%aT%} zgic|w9G^0TQYeSS8RX)0#}qb|F>HN-rpRFz4gw9VGPqjnOWKtKlQ5#{0~(+a-*uD{ zxT+JIBgpVAw4O^r0EXBkKtoS!eUo9=B?&|!oI>DshplgOaoZz_5DpIq&KKB3rOaK4?07*qo IM6N<$f_RuGM*si- delta 1999 zcmV;=2Qc`-4crfqBYyz}P)t-sM{rEq$%NL!dv{MYly*yQN-nvaUZ#XXua8LN*OGBc zGu6R)vXxVRSvI?$R+48&-_eX+J1EV!Z{yXFxSCXYP&d%LcAIoS=Gu{DKrCuQFJV3^ z)4p@p#Cm>II=hNxxQ1h~dtJ4GV5)Oi!jWp#!g!cuOumh0!GES%%(ZHcT}Gg4QOB-f z-_VMNSU|X%Pj^i=jc7NUcsy=NGyVSk(7SN+>ZkAKq}s`X&YW@R-I&LfZ0zEnCRm5Y zl4ezisi%8X)wGvRagyH7yzlMlQ8_Ed)Yt0b)!wFf%b0EqH*sY`FZJr7p}fVns+fYD zs)?+-ntxg`AAb`H4j2t0LGi1>|+qHuk*PLyk z=Vu=arB?t7XI19>>q*EO^v*w?yfndC58ba^7{3 zFMC(Wv5(GyEsB=EzML611^z*=*Yn@*S*n${%s0rzSoHkCmK$Lp4yb}Ur@M&LDoZ)g z!#EMWPOrVC0l3$GAJlnU*$pvZRrWd-NfXi1{eK=fz=v+Mq8aVX-|;*8PK-i_-=?Zt z(J~T5%kKDKLpP7koZQc~(~b8&zm>0h!EzZTV(8_%U#;@HbEmE|uinv7_SQl#z4dw4 zPHx3Px=dpsv^+aUlfV9;lOdS$?Mf%B0xObwsR17!?NQU*id5= zQGd^U1VEQ;D{&RsNN*tsK!Ac6RIYoL%>poLzBMPOI&U>x>4~nQ03=G&IN^}BY%8>K z9k!fB^U7NYR&8!smLN`KMUo`hb)qN=;)I7mh0tW%1BQ+A>Kll6P$GOhKscm{1eB~A zPC%lF00`S_!GZyr&KcfDKTGd;m#r|gM1R9jD3vJNB`8UC5kyEVSaA&JL;C;%nvSy( z2%!R2(=^#m8A*~52$flfrXIg64EPo8g z^qYJ%byXvcLsm+-HK{fWVNkmKv2-SoyMGPh6ds34vH^IPLNOS_6E_iM%YzVsOsO%s z?xL=r)dvz1;RJ0?pe6#{@T?D|4MatRS&v~hO}G|1Il4v$9-cKa@hqfqqXd>&_+jgp z`oV$_szjmllgYPl-xP`j48xDzk$(iE6IaqGRf5=pm0H|>?u9TNvP3o7e0UfShqDLB z)5RG4NV|`-;qdX{+eCvHB(y@IyoIO-Vgd-0y7Sd+^>}kLn`@AQRf9d4ex0pmH#g(U zzbB@o5+Q6}9Bru>C5Zuu$vm44SF;~CH(%!?FmuLedO4h}mN2?n{H;iGkbi_uaR(7J z5g|WhtKrQL&~Ut%j#vyhXqWdlKVk6a@G+ZDB-x2YV+T_JwXSa9mwh%#{qAhbo6LCHwC&lUjShKyXd7>>ftPZ$59oSRdYJO1kJBTeFSigy3{GKK*$n4Xhwaw z^@tO$uC7>)J|D!>5+Yzic2tjoz?BtBO|8##{R`sP-#x`gs(}--+kXr~3>6U@j4RNu zKYE6M5Vd`;!o@VgW^e|VMz0ZJYR?E>hZ8^@yQ?jZngK7{pXb6h*|PoCpLSB8nS(Q=C`= zA^*f+K{Se;QzdgVM1Me%@MIsN5DG~IF*pN@0TY!ZiBB^pun;6p#Jz~)P!M8>Au|N- z$iW@72C&5)#7QC+_90G1K@dpbvKSN@kR1UMg-O*A0GVXfAxR>H$9oGoZHS`4OF;;g zNtE8+rfhGnGr*c4_`1*l#Qui9dzVB8FcfTo5`F)%*7xSR3V#*K5QMN$IrM*8<>;hQ z;|zqD6S8D~8y(36CMN_9h|8z+5T#thmLi066zq)zL h70Xb<|DoTz{|B{H07ls}Hq`(C002ovPDHLkV1gXEx4-}Z diff --git a/TMessagesProj/src/main/assets/emoji/0_431.png b/TMessagesProj/src/main/assets/emoji/0_431.png index a5c0b43de4cd54866d15e27e750d7d54b1f2fc07..552ac813c56bab677207e89590d6e87da2efe16b 100644 GIT binary patch delta 1624 zcmV-e2B-PM4(SY#B!9h7OjJcja7-i^5hxoK@0ux1Ga4ot5+xZDF(Vu(92M)3AR`zN zBp4Czn=0^~EAyy1>X0Jtm?!e2H1VG>=Zhb{XCFv3E>AfzLog~=LO4@BH6s`iIw~aA zava@z9pi)@&S)ICO&Y;l8(}aQ*woEzSx;|3B1az#fYQ(WR7@cm1Gb7!dUycO1p>=%aAj#kyZ7{ zc6n~Z#Q*>R6?9TgQvh|@eH}WL{{AksSdm%us@>DJ!?K2#F?#?21x86kK~#8NmDdM* z+By^lU`PO&*?%UjDY{K28UBcuj5znJ|CKOTIK;!a5IC5Q?g^cj z_l*~ZE>^Ho(ikqr0cG01*UHUiF%5&j_i)De7B3-y(G=leT<^!-X)IQr9|S?@yHgO< zULYa~*MC#X7|#}Pi30>8jynZJt_ms=k%p)4u-Dnjbv!prcP9nwOGdLIPAEHLwBSU+1rvh~KoA1jWg`C};kY;t6pSW9 zx{MAk4V}Bh+yx?pi$FkP*~D0$JSpnCFNj=6LJGiK2g^bt^_>TVi_Js<%QtTT1J9X_ zQGYo1Rs@Nijh$dy5q2q<@}w-|4zY4wpJEZ)Q!a_~S-w)Cb7yO+YR2I3IgZBls=vtB4%Qzuq1uuj^j41FbwP)GnL_ZmKg>oBH#Br%KgH1a!xRs z>=St3)PiUChlC;oMCkv%6*|9RYXSj6S$`dpY2J2qPe9wcgj5ERU-b0d;L_Omtkw28AkuAi5!jMBfDwq11@ihvwoqK7V~n z%xax-;`nF1PB>9eGQ1+X#LguVXIWOKA9%4OmhrlTliBg3lEls?-J5oj2ne0heY~#n zAyGuOY^ThCkSGI!(PddxfBuwlTw)P2@H?EXsxqOtB3ef5 zLF+m_LM#gjlTkC-@At{_YJ)O^pMNwcgXp$pX{2{U3^gQdARr848tUyv-cykvTKk6R z5)EWQ7$SU}AwGlx5d?v2v70yjprdGD8TGu<=^x=1qD)Sfn8u#MG$?1k)KO zmV%%Gbm>F-%#6rpX$VJjpWH z@?(L|+nX6a-YjMtJp4?XO+hTV8ftnlb#A0C4wL^QfKMc5(;Ngok6!Chx`fY!vJfBn z;OS-~Gvg1VjzM`5>O9mk@PApWD0Ua&&o)6SiWn$>(oh;jTZmSlqSEe4Mr@ zg8~DwEdf{rn?Q9P1*H?}9u)>-3_oB9kj&)2AR?FJ>#1lq8W>$#ctGWIoVu;lsX!fa z3SN4X+uAFAs40a5|mjy&Qb756oQI~c#wS> zw*EPto`zk8Qg{TQ^*XKZWH`W^8!{L?7<9h_$h#P^nhv*~ov$ux6NbJJP>*VLc>lPA!>XI%GK_Y(6Df zGargnGJ{Spk6AU8T{nD5EZ)wDon<}Lz;^ECqIE+lPAnS0rGHq)tY4meKDnDv{Qdlp zZ8w2lF?Uid&$@5e#(wGEo656ipJzVw>ZVtOq@ij-uZLqbVvXqNg(@{u}<%-+yTAW~{H=v5UsB+UMJs(?)>+00sC-L_t(|UbWU|SKCSx2XJtaWC##K za+58py%+aNug~}YK+nvsFfqdC!i)RQaqNgQznvM&CI|mzw0{3^o4)q-`tJAh!SMEW zg1NmN4$jXnzQpvu4{kC4+XnvO4?y`eFof!MZYTcW`+uj9{<$xKwjmJhGr|Oby~gnT z@ZZ<4r-@r2aKFAIjQzlQ?MT9J0QuSn!50J?7kdHi!W%fXH<*YsWf4@u18U(3+ka6`HlEhnGKhiEkbf*lZQ$fnhUfq!fryqy&70LM3yo zy(chrHL7COHgw%)9FSZ^L@HoK3d~l4F+w8VT}IcFLKH=bnj1RA2q@>YEb^pr;y8jO zkAG09u&Mal4)H?_>y3aYS)rRE$S?|F2tjp}t8m5$+kmtP2sDwVu^I%X)dU^GumM6R ziHb6XPOyzu7n&gO-6++RfIx_af21QJaLO{w(;|s0k&n87O;Q$^gt%h}k!cu2!J#}^ z73oM2(K`Yc9Y+N-b;~kVJPavuU3aSxoqu!AY|~_nQ#BGqx=VCH9YqNJdCZ$P)gsSZjJ-CsdAjGg99v)_7-1N~{miquPOdN<7QJgB@-V!^SPwGS-jN#bUaik!BtN zS@UPO`uy}@5ZK8|iBh%qj_8$Y!tjjZWwY2k-`p>rX6_qdfxDUB+)tNt-7;;erUlHg zn-0&Bu=JN~ale_~-P}LE5J5;`d4Ipytl;VgjHWQIbC%5wgBA&G5j{>h5bjl$O~C-+ zFtz~1b+`Ojes%SW_uZu5C)XUO@c7L+zvHj8OkFp8_2Tf)UTY#RR2J|vDyoW%T_V9ds^ zZv9mda~J_<$9ssJ^S}^oxI_+O^Du>-pyRaZO^qgZG_ z8A_%JH!1*9u<0rR;_$;kx<3>p;Z%+Sj7~XhQ$7MPrNDTesK>`$0ko0hA3yRC4c)}h zYni+2Yunlig{r29nt%2&p=qG}4jCFkF=&WH7?`+LDf~X}cYij(9;SB$v)BTW5Mc7j z0D+$Mpu8otzQ2Tlh+*4-4H2ODpUP2B7JR~BfMC!-PP}3qg-;rxKp==T6r-OO&^QV? zBB)@30D&j`T ib9UA_g?r(@&Hn-Vq^~>MtYbO=0000GrA z&$VOZs2jkbOTV5;sER@1s37Ill-k94tA{t-$9*p?DzJ@2nsqS$$0f?GSkJU!^|~L_ zx@y_MaO&Ku=G2I{mP5v;QQydT`oSaP&ws(8OO3fRGY^yHb5T@iFe z4EyxX=d&lkjv)X1;!iIMWKuA%nrIge1@h|0^1nL%&O86qNd4}s|KE1%+K3{6@b~c+$Cd%{onl`=sWDn*_ z!SNGCnNA0)YRUTI`KtLDp>qkq1cwh*-;gDUAa|M12?z{*V*$ejf!BFm*ZEJZ26H)6 z;Qis<1s=xQwyi}+$oa=t@@fL}H)MEo7>psuA2juk5)A-+Spq=QJg?XDA_Or1X@7JY zs*e=_fPe8U%l3}*`TXb-mbkS>tKMP$FLWhKzAWfAHed;H9Ow8Wdhw^qWC9Z$E`;t$ zt^QYq>DrPdK?eX>09@D6mD>&Ew%F*QFY%}6f7#)dc4`<@pa9WWZHA*U^sqsbp}!E$ zYX1vqo}4!00Pz>HaMr4xPJjEnePs!@mJ6D%EL?j6nSoLmzYvK( z=~TA(((D?1Q9>Uo%8RQ_VT__sr7& zdaYeaNH&xx1VxI7H1r`9nIM2cq}rf_KudT&lvk#b<7yV1HN(geU|x+urGa~b^Ke*6 z!GE>`iMXzA8L})Jc@xZA4;hSRiKxLm2(brK08~|ABR3L|D2hO+0umlpNw8ZLhs$G$ zCk+Ne)v_qz5-^aktl{7ldEMKy(%v#>9?RPPaA;XDh9}W#1%_o{ER`BX2KgD|PfAm% z^;l0>_;iS+1CdYz5DRLlV4yO9;8BMfc7MIJC*N32l8fdx8zm_--uI0(WZ$WkZLtR*6O8_V)7ST9*Z;d%N!!+;7PE(!uL{Y*%EfZKm_MBa^Ub`#TC3k4_IcOpR z;%JfzJ#ah91Wk>WkUS?%oS!(4yWN%&eLz47lHJbJWt>ShL6=jIB+W^(Ks4_kXpley z5v&sKJWY6Qp}!~UHtYuoX*L%7+uaVAf)WJ+3F9<{Md5|&7W8P@BuV1X9DgUS8#&I; zdny#hXp65#D?}(^moBvSslE*pC?RI+>zC+o=#gFCA^#RQ*S+JxeK{sU;_=idT_g>A zJ5HfQuzp#%v*>32avh9bvvr2i^>lvYPLC-XxE77_2iI0iVI|hr`{VrOcrzz6&3q-& z;oyc`&u!0v_RC)c z{5&~8((&VdX$G-Nbo{(1r4}GzK5RA`tjTt=-#;ON$LoHx-!GCl5P#ME<46o+H=-A6 z`4c$H;6Irh^q9)(X1`hDj?&WsukH6U!UHH{97L=-^{lY1ph_zeb)bF!F6=CJ2wpjrRM5|#x6YrGL$m_Y)u|9gp; zoHySMZ@23;TVvT?4~%y;#2|)UDkf4aX0LoxKj{jR?s@bN@PEj4{#Xr|1^znf7Xp;{ zTCtLytFEnS`C|mEXqs={#6N8|Ob7q~ N002ovPDHLkV1lx1?oj{$ delta 1791 zcmV5G)@Q+|7qfI3m-*cqbYWE+81>*OIA;L&vXW z-_eYicRj9?Pa_x+=h>38oLk7UYU9W3GeR&ZH68I4dc346r)6vT}VvOME=8}kkT#BlBY+$Ru$9bKw3_g0pyt7?M zJoW0JOL?3gR)h{RY7Zz*u%(^!>6r%)AO_uSZ~y=R7<5ujQvlJUnItDe{{8;KY-)sd zNk?eY3;wK1<^@FK~#8Nwbo}_+ej1zU@$gg5ip%hRqe&K7ivlV|4-U` zXXLDn#V&lv5qA6t=GD=a6gc>sX|~SKe^fa?Z+#nRT^?Pv!}zI6*lu4PeTz9iYU9FR zTX}klQTb{E1ge$0%CLR)C8Tu~YoHDp#_gll7ld%Afq!~q7($W%JquH!o&Y26|M+j< zDhR?lBGz9|#yI+1_;K5A2c!0|26)n23<4Ozrv{wEFdX$p@$f0e?U&y4XZ<$B5}0sw z`ALVq{%#b3fx#sv@NqkF+`hf26D|T>a+Fv}fJS}dI1VBGliJe=H4!AG6$N44YFv*% z8xow=lz-?C4H0Eo0!EA(R+~u}o8|pJyl$ISsc0^yfQH0p<_V5&poYFv*A;A^i& z>oy$f!vwvoONu1v1^sr2sjBz?BrrMoSmUxEnmLVt=#tV(B6kFZx7G(ESg3^&Ztlg$ z^XMZ0V{&_$?|1zSjGj9h1z6g2hoyj^U~;xcn13@3+^8gu>UMdVBvI7sxjJSs{JRn0 z|oywwDhb)&-JTtJa=0R|ut7dCKuk*fiXy4SnIxNuEd{Mls8ZQCF?5=5#*I3O1Z zOmBA>r*5DJ28S)JlG{>B+abPB##veXaUv@L2o&t(MyET(nHf|MiVw&b1O}UgF3R_P zC4cxhD`31)X5pz}4LrGzgia6c2TKr18Kn$fR67nqh>Xi98z<1DI+fm84FQMYMUqMi z@jPn6AXOnQyIGVKk&D@D;hGW-9BkkXAdj9&rBD!UhZ9xsEP+Yv&*Ic|bqOVHn@KK| z5&(IF4dO9Dgkv*Cgc4R%Patb?hceMM@qZo%Cddr9*{QfA{HjKByhB{TPAEYnRb5|5 z=sf^oJ5WY)xN99rM1i+Q@2u6IUk zMgi~`V;&NQK?>g)lMJRznL~;mT>cs&;X+avANSH_ngRj@8s?38DeSgwAZ(RIK!2Qm zAWoC05DpNG&mR`k>GM2gk6VOXuAisV^+U=%Dg{rX#A<#Zns#Y9Krs0*o32)`_tRBM zD*__ttLNF`^?os1aw;8SCF91yha7juny}yV#rnw*zsi@k zo2$&KAqW`@ZnMdTczMpD zh9T%OUm?+bo38VG&S9RV+9R5W#3w*JTdj}Ydx9Rf=2`;fNSj_TC>J4<*JkM7zFVp7*xbF;~TH);fDrx}X*i5Dm`E0#dtbb?uLrSYV zV?gJVe6?6CRx=oolw1&T_!%K7W6Spm=R9bgw4Rv&-VZW0vh@w?!*_B90-`^eh!twVNmLA zKb~o72$Ky#NX;nl=JFK|V}IMA18m`WTZA5k@;e80X$Tw!*4P+~>-$s6of0;b_}Q!_ zPD%we*j5cDU^*~7xg{{Xq~p6*JyFeqq5@eGol##j;T=@*c-@yXIYgf?&|+&Of0J;e`-_=Qd=GL<$uVE;_kAJxCFw= zU>ay(Jl%qNjG00ZCT&OAMNuTRMC&vqfEqtmp54C{^ zzCn<~*xV8DY}72T`*{CL0D|F;<8TDA0SF47uCL_y&{tp}g6lS)92DRY|FS^@t~CJ& z0fNF;(`@((5KyXUzz5+Q=?J_VK&e82Y?wKGqX+>+0YenT_ZzyxH<8XEC_3tJ1AJdO h?ld5s`bp#iU}rn^vQQ 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_434.png b/TMessagesProj/src/main/assets/emoji/0_434.png index 96de472da373a7a9ca841c434a2a541a98d73236..fd0a8a9cbba9e12fb0516d743418b2c2faa0dadc 100644 GIT binary patch delta 2226 zcmV;j2u=5&4ZRVNBYy!tP)t-sM{rEKoK?M|V7Hf2yPH+Xt7pNQTD+WD!>M4ppi|w= zoS}Y2x}I0RrCGnES;~%Otb|3mn^DP)V%5Wc<=Ujnw{VcfcF5Y|w8zoj!=>!w zppjpN;F!cKP3!000LLNklH;iX=gjQQ|cD7GVJeR6Po>CTg`BH~AN2`}eov zQzl!ldaO`{)f@zXzi@uLjCcuG0075HQmZ9d0Q`gU@850%X21$00I*(`X?X~%hXY!s zCy{tOmQ4Ro;)r5BN+4<&pua-?{A*Hl>!l3ZqJORKAIF=KUw4!~tFfL)f`9?T7<`SE zE`ux(Q+LJF-R;ybCb6^WQN@)o_{zy#=1Exihh@v{ihGGyk;HZ!&Y~|EMoV<9=mOTR z5U3-Y1;gzMd+~4~727y!3N;Q3Upcqb9Yiw_DB#H`VWcaPiPvWG(IYtt4>DRWmBazJ zgnu=q5>lWZY^;!13Q2#Y2vh_XG8u6oxzK%mnZ*buFtS8OG!jZ2i#4eQLJjYuXjo#^ zg>2OU$t>WpLh87gFk-iei;!F>zO)pr4(GWPMFD~;d5&)oVa7+2gCb1_EHGP#Ga3jkIV< za9z(sO9)I1=pq6UQ2_&|4s~w1sEnPpR??fTn%JdKyk<={`h8>wO+VEDsY3#S+<#mv zBY8lIqR6r=l)=e{Y1(}-$V#Qsgh!(sjNwlqLnhAy# zt$eBYsX{Fn2#Ao4-7S*H0HWBUO%JWrjE%pmWFyTSE6pILAt$&jk5fDv5qBT`7_Y|d9)-~Ib$;uaBK?FsC;NL0Y zFNionU;>6o+eqN~cAHl)BC*egFCgOOFwzl%BuG>QDO;LeR`@mpK?t-%a}-8!8NL8S z;^l@A1TI2of$;tA?mJ&VSs`+bLPkIoQ4z#$I)q>;Rx(WOdWbS9@hzm4%L~nwSS^dY_1*fnqIb15&ZT2&)IZ3oAdw(3_$Mg(UX67Y}1xV z)XDlq65;f+*|$}tbN?{?F&$sc@7p&)U@~_|&BK-~#TJL(|%*GGX zi}BUNeZwyU9=)Frf6P|#ecV}$6My9jK7`v z7(F|lIrkl{W58L4*R8c|_Dr+<{eCpM8vBHkTM@ZiATA(RGw1eN?GGgq9gDRj%0Td+ zFGn-@h2N&rk#pM!Ci;2gJdDR6On*3+ylQqV0>AQw6NTH+XnJ)uojp3v0tlSXj^oVH zlk?H&Gp_>?GEK;Vu78<2&*Z@PF`qv;&gf>9Mrq_Y5A*pW2#incB-e%HiK?0^9L?NK zW;7Z(mn96W>R61N(daS@7Y!n4BCL-Xt?8!PYZu@s=JC0F27;gR@IN_5QSDBPh=mXl z+EO(*oD2v+gv3AU?Vj2naA8HHPiVusHgyHccqSTaM1e1B9e?^=GKAQsY0DVcaH%6A z0CEiU1m!nYL=O7UZ9@ucBY8q2!_ahvd8(qpz?IK1ijsdK3aF0{+hMajkZD<_4a3F* zT@eLcL-!;l_e8*!YGFbwvBSx7t0m(yc;=~-oTByN>TUZ!21T5#-_#Rlf3Q(W;v@-- zf%V^I^i);n{eM~DN$}-^uru}XEXr}w8Zu~OfKTYk$QRmtJJ-Moir9YTO*n}^NpRTE z(565y1-{Lf)v}_O{f*9npy-J(AeK0V+dWBuf$K0-SOSJJMCsd|VW%@Rb09z)hv^XD zSoBBc znrUmA+AD+$tEA$`=p7Om1TtEdfeaoD)O;Ck@=S1dJ$(H`O*(mWe0F-exA*SggG^hN zb+Vm6H$}V@g1+;7FA>b)bq12!wrKgoCi(~!-&goHC^&6YLTux=g8%f8_WO(MD{TnV z24Md%jw_yhdt#Bq;r{;qVFErM{{Km#_I|zKKhI)XG(E*g0{{R307*qoM6N<$f{$lE AYybcN delta 1680 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 delta 1823 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 delta 1640 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 delta 1536 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 N002ovPDHLkV1hSKuK@r6 delta 1965 zcmV;e2U7Ur4!aMKB!8<=OjJcja7^XWq~64Y-^h~Q$cf_2n&i-+=GLm*!Fk}tec{WN z;mela$&%Z-Tj|@fa!EdT%pu}MThRCr#s*oST;HxdTmo5)Ef**WJhIV-*YlU-GjRF4<3 z*LQ$_0m5Qd{D1Vb#O@yHKmTqP)1}UI@qesdZq~E;h)c`1EXhXm*?K(vUx4X)&TPl` zyDo~lsOvi4cLF|IFaLRixreK}$b=YB*lPNZfXO_zyJ$#f7(ndN=J!*X&MX!OonC3E z0pY9P8MueI=FmHOQNBemtl9K8g46j$(>fgn%MVqIVSms6&X|JG`E62j-zUUK1BFxl z8)Gr^aPo0dwzlK=nlXKJ4KkL0MNF&?tBNEkV>|F1V*FP|A&&P~J;uzZ@50KosRf)$ zVtmaE0XCQ|e%!{~QD4C7G%X8eNr?!S`4#dVIr)j$Nd4cePO`jgIT#YFC}vQ6Jn!s> zaZE?51b+}klVzzgPyq(p5ag@iNEbiM(pQ2filoZ2ya9tl24+wk$CHyEN+{k5M3Gi# zBsCe7Zw4kz@$Av`*Ag}X5Ie5(3XLi)g)KSboDFUCY&_5A>t9QFzUF1zoFHI8k=Qmx zUhCKx`AdzBQ~>a-NKbnRB6(U^Py~An1}fM`*MAs}wiaL?WwqZQA^Q^+X+&U=F)&i+ zPiJ(=aC;sI9&gjr@fczhk`@w?Are2(VVge?*z5&`pIb&4f=Aa=X0ssacot>xL077t;=Kv%Y> zE`J2B1YA$X0Sq^!$$nmH4yVDA){F6d$`_*m0*0*947O3kLWt{*3`A%s`}}hG5LOVt zk+2kF4Le!#0FSQ2%RD>noBF!DUaw?q!O%$9Hn%Ffe6-NT14JE-i6%A{-CsnRX1I;e z-C_e%0}-vzhCpGKYGO%q>siqbW9U$w_J1UpY#{?eb2(*?&r4GXjxEd~U(7AZSzG3x zK)@^yN7!~^2tp_!oRJe4)#GtVilT@C;bVP?Ss*kZz&^tM_;|N$&}=L2eF zX;YTMviX>%Dci;n)t4sDr#7-fLw|%K(!^dw4o-uJg4@;xh~$g!vTqlB3f$>!~_U3Gy%aYbw|L~9CQ65T`xo= zL==2JC88(*ft}zj@1R3~AqX+)@mk9@A@FRiS=_dul<9?r0gI`CCZLfy9O~oXB9SI# zT|izLPPBm3?tdz-gZRCV97a*JEfPz33Ne9+<2t#VsK)ma*ftouLqCve z9~G8pTc{t$NN|P`qAl}E)gXijx|xTeF?ER(OrkDgiWnooxi*qq57ZRzk9)|`RRqdF z!0itOC?JF;@ae$OiR(01N5dco7mcug83mS5yAT*AHb_v&C{vn-5`PY4gv!(%s6<*~ z1zHd7CqP&fRB#-(&~;yaD8Ti<{5WnXz0xab$@D%?f!A6JTmM+?-f802$%qY&$3`JXr$V}B5)8ZIB&Rz9|hai zgfS51anYaw2q-2!3Hzk}7Sz@)Ltsn|$()B|gxpf`48BlAPcpHSj2kRa+tB zlHYDe%q<5XO`00^VLF%aPPr40zM8i5*MG=NZ2`UC=$h?&F=o=#v}>i5>gW;Plz zE=i}6GBD~UNpN9`Nl2)bKqYWB8_iea#qei_@pv;?uV!<|D8?Hy^mt8E(k)^%nqyY$ z$!7fH-y{~8=_Yjf9gzPRGF~pH)5UZFd0F&dWom!2kzj4@00000NkvXXu0mjfWI?qf diff --git a/TMessagesProj/src/main/assets/emoji/0_44.png b/TMessagesProj/src/main/assets/emoji/0_44.png index 57e0d79963cfb790d42d3defb175a25ef07fbb41..1b315de4ec1122dec126276a08fa671377c81b8a 100644 GIT binary patch delta 1935 zcmV;A2XOf84xJB>B!37{OjJcja7@Z@5Ym4j^^^?NeHY1Y4ajK)yLmpxf-S{+Cdzab z?2HiUjvB>j2+3>;%5M$soF9Nk2>-4S|K~fESO%V82#rw%V=4k}HwAY<3jd%5*rzAp z%1g+dDB6Dp|Hmu;`>X%$oNV(LlJ5C;!1Q{_l*dd>g%e z6rp)HhFc}#(1!lA8;EUH|NhPY{@b{jR{!~f|JG0c;xYf_P3waJ)^-D~vbDafi|*x; z&9O@F~_I|L^4L@Ap4BsQ>@~5p+^cQvj4t?0=^33>P$F(wo@F zxwnZ;vKRmW1~W-SK~#8NwU~u+CEG)LdSIDd#`84gP$8>6rlwH@^9AnzGAg{I3?28Jjf@j ze30nFFn_F^RxtWp*PhNO3=a1idrYG#mCC%(6Z?tC#|BgE73LL?-mEn39$8$@&NY3t zN%JSIo@o9P`NYslSJLUZz0x(~9&dF)C}c9Gn`|01K6X$QlWcZqpDVhitv4|E;QjYZ z(~Q-lJ;eAql>=fn9hC7SWq?GXBA z?{Ww(wq!5n*)0CyfYa^m!39P&j?KRCwu}-P9;bF=aPc97hCQ{1;8HaAqc0SJzIogL zLw}oTvU52gE_PM80`^qZ){S8UG|hhKO^60D7-CPcsXcg0#$Fhjem)p9h{>xM0zzDZ z#&shzu-DiD3p+E&&^!|0)D>u}#vs$cD2%O{{lK#!67QQ$Qe1;fW-v8qFSatzK%iq! zJPtB6qPbNi^9vYcuX3LrVe+wXCp3*F{=0rL0aR2qZT{ffUt#GWy(#YOM)Hp?^@X z*IQRtlH|~9VUP&KP*g=_mYV@%$k2ph+YI66TlKivOr;9s$mLpBmcdln;Ra7KRaK^r z@r6+5hExiQQU6BpyGaVfAV(csSxjeTyDMGcBhm4y+kI4+4hIx?Q7V;c){d*+Zv1|R zxB@ZU968I-R0o0=bfqcN)N#%?xPOYH19w4=pctVN*HO20ZDDuu9ky%06*{7^F%&7T zI37Xq<%OaK11T(H4FOt0c=Npr$zp8mhj^{XkG7Re9q9^9t^0c9ZrD2lFP zMvgiJL=N)`sWC|5+*=AfB*l!U$a@M9f}-jxN(DfM`q(L}OxJaT$qOsRwSNVou>OA zI9c=+JjYVkzhcrIY5-Kt9e;#hb!HXF@LWeY>M0_JNyHe5aCipe>m6pVnd-vW8lF3H z_#vo{V)AhNT@twMxG{JRM`tokmldV#p(wHnjYVHT zij3R3T;mHW@(^vbVp|E1!5uY4m&+fasQR+$mO;%#9b1H3#Gq1+YkwVGMSu?-jOASe zLfrBt-L8on0}jQ2;bUZD34_}Se?9z$Vo|7+B2yvwEQVSYc^OG+=8G6!DNBU-6qyyh zG7#bgLK~&PQD$7BU>RS5Tl|T!#J)rsZFJ%VkuNBvn9s`$lWF{7F?AfraxBYoz;v-t zToGGVVMx+)ydoIp4u8dv%S*=^k7uP<%*JDDx=>VOnI}Uyxc7!wn_AjgS~YAwmzvA& zjj^>XQY+iS-a7=iqe_fMBT;lUzD^Wzvr2G7=-@p?Bm@WbG!F+y#D3);oVkKLI!T5j zG~yEnm%y^iR`9t24qgj_kOaIV;D!(kA8`=Fx*!NiVA+BTUw?qLz>kT~2!5d;B!LAU z;#oiu4ue1cVHNfy(D-1wCkO{n#7~KaNCFEqKDbDdAQYu?e?<~FY`1Tr;i6;*C%3ol z_F*7O^M8>@EOZ!d!vhn|Zif#;vETo}9E}N~qc7knB*dbTKm9Agfy>_C=D)w;U*u%- Vg7eDUSpWb400>D%PDHLkV1j({w1ofw delta 1885 zcmV-j2cr0$59|(*B!4DQOjJcja7@l^49aN)&1(VAa0<+78SRAw z&1(YCYyt3u0r{E@#%2Wdj|csq4Em1({jw4MvK9aT{{#dC_N5Zrfd}M}4FA6~*mwiq zi3%biA?lS2>zff05)&>iE=5E|-{0L{U0gL60(*OZl$M&$&wtXrzQFJB^5xBeudb`) z*0NAS9&K78rI%~}xd#9DW&P4g|EUH3<7of+od5m9|L%!;L<+WyA?wgr|Hcjf^;Q4) zcmMg3|NOhdp)1d~Q2wwN|M`Xg`?UYvSpAs=|NYLekU3*10ss50|N5o>(KP?&Gym*$ z*RL;%SrqBOE`R^+MgP?l_s2#5!#V%{+yAy8|Nrg(yej&t6#d#X|H?RxcPgfA82`pB z@ShRyyF`2d000$qQchC1BTeQI zuJ&$jL4PG=GY<+~*NY?2KGpRWV@inJzhRIGnfiK=2Ea+v^#dSH^@f3Cc+0@Fw65zE zKnr^Gt_}&35%T>LM^ENtsx?{zbQ++mV}Nl+`1NNQJc7Z{d<|%j8abA`J^%ygxVF;~ z8Vtj4=|n(RK4u2M2!H(j-41i^%ppyZ#809KB!75*;%m??ONf#L9p8AaTw6poN5BzP zOYrz-BzVj!g3!Yuao|tVFA9b8cOfwKJlm|wUT)LvGm z@J=M{IU*ofP%t1bJRe@}GUvN20||8(V2C_Qsdol#e~8S=v@$9LjBa^;u~A9pG0Tvx z1%G3qN3Vd6WmPQ~?IeS3^e3u77EhBy;Z*LB;A!Ur!G4?yj&CP=~+V{FIs(fPj$ zo`bO!=4NSA_j723lF9-_oImtBh4hfeyLV<)=0|9|?%N`?!qx1uyIzHswV1A5*N)1M zko_pX-g;9vq9_0tLy{t>sE!n4e7_xExPL~c zNz>=9JR}-1U)Jn#L@4+9%a_YQr7thJ3M2Xb_4Tz_ulykJ-PP0P^^&KR?_+U!+VLs` z6~yHv!q($k$)Du zWiY*`c)stf$k?zD-E*kOmWZl4LsK$*IZYn(QmwF5yAhHET$X?W+2KNkK<6;^e)HEp zR3_G#YpCih3SEcdhu$njNPkIi9|SmV5HB(!_#ArorX~iOI0+g1ndik}IFCIDO_GHd z&9NGJLI8mh%JA}jtkpHBM>1P@p0}7iUW78u#Nr~^L*NqUiK5*BsE48G7HYg3`z%Wy zv$QPBwD|&)C0SNhLO=;?qF@wFBt^%gQ5$=t{HN^q>YfBHf%_P>-+u)9if)pTld)&y zYC8jsfD*XUR)#c<#sDGG29QSJ>(Fo?-`BuITW7hBdJ*V4GzmZ}BaM&31|#Z^03qNQ zqC~p}9i=gVAXh*w&@uWviFPDS(`y3=6fg&C{r2{z=h!ZQMo?PU(Vi$9EhK;Y<16Ji z3;P+sU9iB%xJswnHh)-I0}w_HG(!L9Yk|kXMuQNs{PVOTg7!1;F8tsh&mJ45K%g9R zygOG_wOwzq9{^P_S-^dMWK1laMj)uq-=1s0ntUwaESN`KgmV;u2!JbyQ+$xlkPRSE znBmRXjs_-Gz+GUHALT~sGeQa&K!`>A0dR%E&A)##8)<~FVpdv!Oa!D(4Yc9sKArW3 zeWAb+(ZznPdq)*MhYT2L!u$K99)Qp1rZ?(#;fVCR-BGUt`@g2syOX5BK$0YE{~zQp Xi>IiN%Lr)uesT zxo+aUm)NR<-nNg+kZ0G$ebc{n?&YGtepJAvSjw|!xSCLDR*P-<%Ugehw>Glx$C0jjc+2qK2ZeqkUY!(AD$i)1tb-JUKPv$Ds7;pka88 z#j=rPE!DB&r%UXIR5@5=X|P>`uw@EW3kCslv``SFs@=7uFlId@bR(CB=2k z4)TMXEPwd$DzC65kFZj=>AkrX?-bgHSq;a&~>I8^@Gs0hPWP8B3Ug(lvB*ZO=927 zt~A}GAHndv+7sR_1qwqb?v?{a;=WKB7#w8{eFbg z`^+xqNUP%x}27OoQxLenmF%CS> z_p6`QlXKlbYBHLjIh)VtvW`k&JX5{8hU3|csTfE~aKrFqgQ)p_?8r=4_4%)-pOeYY zUyOtmq3d@zz56w9s%Rq#UH`1OL4WLz!vI8GpD!OK4|i9WlY#!K3w>~RyZCu^d9#?w zb=HgnKgJyEIgx^ZgP1MT$>qb(-&dD+%leAw4i=Y_hi^E2n9dlJrNDP8n?!{>L}Q3rs>0EGP%9E zS%3gQMt7N_4LU^=O9n#XeEUyPP7pfl!MMS-i}Z0oLx@>M%W3+A)2HclsT0ACTz-qF za?a5Op6bElbg`H|4!T_$qJP&TrQ2Ihr;EqOrK*Ey8b-VNX)85{^R~=%Je6t}PlEs; z41|G?bSR#EK^T>7Vjl$dspBClpz-%rTBmcXm-Y4I<~I4Frg))AF0F zo)ILV2`5UGnur5`Z|5MDqc9Ad7lY~Y{q-tyVKNP4I7twkor2iC z(8D9&G04yua{cXhmTz;~q!4%zg#O-J-}drlC`s)IRvNy;zkTgg?h|q^cO=gGeoR uAPGl0$kj67z0}my#>U38v$MFivd_=Y zx3;v4i;2z5%#@Ur+uPdU-`~{K)QgOa_4W0qrl$1It-!y&=H}*{ot^N=rLL{5_SLiH zwvoBHxPpR!$%kOwrGK)9XQYpR#G!-y{QT|h?2~_S(UNQ7t$&EvoOSx)!ui{~>%W|> zZ%2}ITX|YX!g^9B1ps?V4LubFRxcm1gbtinEgJ#==?(;v0000DbW%=J0DryO45u{y z{vcS_^7`RWf&c&pLPsXta zshVF^k%J;WcYik_$@Y(bH*0-6MqmGf-CIN1tW?Hrn{%eBtBqple+ST&6|=40bvugd zx_xMJRoVXa3SKPQy$mS5#T5N70m_TVI?C^gsTzNt%67#Q0mKs{p(~7R*B_YK2qM|JCm(hTrv}EW)OVxiXA{@g#F_d832gl3Fun1Xn1(s!g zEn}_PW64(FIrVOb#?^^5J0w8HdIX3sWf;ts*Mz1PH9HJ8Gl+zPD|?ZWHGyBsSg&l` zCL!dBsCNg<4vcF70}17(<$k#QOBq{cb4gfv)PI0bRr{)vh|qY5$UIsiFx*%UlXI#9 zhlxd0`~5!4_7WLH4zr&7k%Wn5td_%+L`ah$Av;4rkq8_!iO_=t4BO6x!8!IpZHN*G z65<$;sgfuM1Qmq9pzy~)H=HvfSme~B5X+26SvNwHM~4hsX0?9w!Kexp%0nA)DEsJR z=6_0dW#c#=GYKJrFFV;X9-u+O&eMX}KOI9Wg-po4YV)>+Qlgy0jU$5dM<)tr0T?+6 zZIxjYetJqzrxO?wq5A_J)dL*afRn%(J}hZsZ(CrY${ zF))}u9!-{Onio0O`@KBu&vDk)Z3g>~kbfD8{WEk@RtI|V2ru%IfKR7OR|75agi~Cw zh;w$8iH}Pp^;=jQuD4nmk(NX-mvI-~fAb_4*)8u#OamTi86Ljq-h0R-F9G;`09#BN{T`talR_4U{5TifMS z2Bq!IcU*pl<>n`pQ3C-6V+KtV4um6sfJxLI62IiNRy+x5&;dcqS!Z7lWl4n40wT6~ zA_R4Uca&T1@DAVb?UQ$IIul{%-hW{E{pY9YT3NLl2`^v@5;#mWi15wce0zKQ{H)!s zJI;as1hm|Cy?+K`AVLHTe`GPVh(xETfrwMfHS5b~+jm`me53>8a{0_$_Y^OPgs+fD zB0&M7%3|L?^<58uOTe7o?Oa$srhc3~h=>v4O~kMxB8AuKv%oneqAq0RB7a9h0V2Z4 zVW5#dF;1x@4nPQ*MAeCiJa|NNC(j8I&ie!PLB&TvtT!Gc@xXAflQR&LaDtxb=|PO6 zC}iPCY$cIkA~AN7PFvD56oub6T~u+#J{&PtE;J-)zlMf04fHe-2Ye^4_WnpreH0*I zppco+Ac-gB(U^%-d?0Nzl0|n|F5iQvu!NvqMj%GCc@`AaScYG?(D1TrZC;$+k0g8qM z0GxAK2pCQStfPcn$gco@K1FH0EGhy(D|Hz z2rdHt8Q#m6>$oi2HL42Gd7o6QTv!!kzxGX{YIA`S0_vf3z$ nVSM{Hi8Vym*ZQBbUhe%bwJc|RfaLew00000NkvXXu0mjfK9gvn diff --git a/TMessagesProj/src/main/assets/emoji/0_441.png b/TMessagesProj/src/main/assets/emoji/0_441.png index 6098b6acb505d3944d447be617f68e813382f012..c11bf99543d8e4bc5f24ca733c81026eed387a0e 100644 GIT binary patch delta 1991 zcmV;&2RQiG4b%^iBYyz}P)t-sM{rEq$%NL!dv{MYly*yQN-nvaUZ#XXua8LN*OGBc zGu6R)vXxVRSvI?$R+48&-_eX+J1EV!Z{yXFxSCXYP&d%LcAIoS=Gu{DKrCuQFJV3^ z)4p@p#Cm>II=+o(xQ1h~dtJ4GV5)Oim}E@5ieu!{{7X$c*2ot(7SN&=A`J|nA*vL^XjMU;-ANrY|flY?7Ic37aP9=$ZdNeAvd>b1)!xfew^YXh)XSG|7uW9iQs&iWuc%V>Ab za(}F%-2M&Xs@Lm#hrjRRS-1OKiZ(qdqx(Fg@cy5&*JyNl+|u8A`_ztXI1qy}-akh; z>9l+0mVeb~_paJkZ8+NWfDiw&FC0Cp&OguOc;BH{Ez|7wpexFOxV6{D!PRcJ`{lp) zPROB0oqbCbP4D4$98U#*ztib>Z}yC8=?(MsTVf=-UO(#w4B~(?)IHus9G6+jej|ut z(d~BH8TH}b_&uomrnDQP&#LTnO_Ic-+3-4Wz<&ofvobU6%-{98jhz^|E`Ln9VTP+v z5KXJ=!A9LYI&*SA*G@Oyd;C#e!}V9IFct&1)$qz?{&enaG?=%6KOieJ=!G{P&)RL7 zk)N!RNC-^VYEhH7{lLc%Os#AsrN2E^tJkoC$kE98If+F;T+6ar5O-tjcm}pqdy1&G zJbwy6mn<`OR7FqD5d;uWfT2Pp*R)swP@&A895;BYai=RfstQP$BvH&DTUlmcwi-BE zESg))AXv36(=-Kfs;IIoD~=t8p&!M<11CU}Ef)-y%B?;@yhVxlxIoyX4g!;+>9$Y8 zkN`y6YhqwPYjB49q@RViyvt?~n4+$$hJPU&?37WG=1>qJkzhsi~-Q2#uB}XG)@>}%z_V@H}!*w z5SnbD^V8{m*U^2tn97PBiTVzrO6*9-OTOd?+&oDa+kF|&(k*xQ2dx=@|kc zDrm)y@<~XW@yLM1xS$BB`H0|k*gopmRjG20N`OEq8-}b%!|P#Fm46KZgq~DN`w)d% z80tL6mLco9rXcnf!3l~+l3HPJidvM|+BOD*NE!*lkT?b>g1|$BQEhLEBU2#cAqFV$ z7_@VmEIke3lQ=lqhkwWgLL4FnXV79`GGtjss0RWIL84gPi#QAfAwmp=A#gGdJ)sSN z4Ywb~v6$P3I2Hv#AauM~JMckv3XlzKY7+nuFjh8+V<9-)TgY)u6a`)ig%}D6lk@Y0 zo%Kxy%mm61#2OI$8~XNb9O_^IA{%P>?fXXG>YFMwlpzQ~u76ZG*ss#TQLVxl3?fa* z>KnAOWeH49@N0;h+0qQ9SRr5lLdATlj0ymt1p8ePc0~BCihmK^;Sfd9APVIF=ys)e z@Df%3BDTYf3TJF+j_y;!3mKu0An-m)LlFdom#SDv2q2(r$XomouZ4cQ9$wZa}pBYw;|sr;ipp;;gyhlXaKP(TC|2{QP`-!~{tx}x Z{Xbx)1Hz!LXczzh002ovPDHLkV1jlP&bt5r delta 1736 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 delta 1607 zcmV-N2Dtf-4%iHkB!6sBOjJcja7?wdv9htS!^6Y8yu6&5m9DO?wY9Y9=jX`B#?Q{q zO)VV1zP^TqgprYv{QUgh-rjXYC~RF*wzjsUrKR)p^I|t3nwpxft*t*G64lk!D-j5V zQ7>3VJ9%<$o@YLjTsNtPX2PzMu7M4uG@j1@000PdQchC<+kdLwz#>Y3I?Jw!000G( zNklPiR|kZ6GfH0i zuMsg=y=-=1<2^&N-a^(r)o0jI#nh*>#s<7-pf;qp`xXcI)H4YmD zAPem(4Syp7Fh_@h`ME|WX9XdY(7H!}OtotiU4E^AsQhU&)t3@1R8{2>T@MC({n7%t zeBDf?6a=}9hE^-&^PVKiG{*1& z<-4)oZdl90^{B!VO%s%1Y>dS4CJirFvT4S4aN9BwLB;#NU#~|Z(&J{~al-XB)b*w#5}WjNd9NovfgAN0hqh5FVInis!CAXcRHEt^_o%hrZ7`yv zt*do^AN2yG#w_D#l;4cpG$c4%V~l=jWIx+wxti^E0M~waY`ASfW=R7Z)*7QM#hewK^Y7=HzZk^afJ7?eN@-A`L5^n&z{!W}hgQBI$i zQ3C`So=8s(l^_H}-*%#BVto|zCvh7KPfWP1wWbzi42|Jqk~O2_>_n^&(cPzsgb!JC z_iId9bSsRHkFpS}*3<%NjY^nkS+Kj-)q0ghNyp;j2di%aMgprB!5F7 zMi4MGwP53Z{dkb@0N`^MMIq^*MVznS#27~&G>Z`G zab20%ov$G;sV4@Cqy5DBpj_#wUSGo(@l_%wy+fdwlP5U5pWeV3`yO2N1Z{;S0c%D) zTL}>@WpGx5fN=dGFxE9}#eg0y6Mt>U5GOf=ZsA3`?0YwGBSc_AOvIA zuQm9E?4^Wld3Hvc90bR(;Wk?EwFbWk-kx`2XMqhS(xfpl1lvtN)mSMJJb%XUo5$f6 z1V{=IPov!Y+hLEe3V}*!*T%`2NT>w>jyGzm!7KDanJD!4G6CV^VOcel!yYY!7`cfe>pjfevaboUSnHh>fJgzma)W)Fd}ojr9K-VU^q)kU1K?|x6XYj zfwciK*&jSx5rq+Iut5rkK7#^2tWx$#4+%l=Tnk> z`9(pN<$01MC(7VEJO>8#Xivx`N%B0)()T~1{U*;#{|C(V3DBzg)4Tux002ovPDHLk FV1j1F`rZHl diff --git a/TMessagesProj/src/main/assets/emoji/0_444.png b/TMessagesProj/src/main/assets/emoji/0_444.png index e90e0fec15ade4a61cc0c9215ac4e7e57e5fa4a8..6f87251c4bb5ac928af4776013dabaa9b00f6558 100644 GIT binary patch delta 1544 zcmV+j2KV`y44Dj&B!81oOjJcja7@~!DbK1#(Y9di%3$5LN!hkg&9Yn1loH~#Kh>HP z)0Pk5#%#{ATkp3a{>CWxz9a0i8}qpze-7w zC=CD6F5PF~cv#;?VaG#gnaf{QVENOn@_-YA zzkT=rk>x5pV&U@~gmAd4*M?&qQ1EAg z8!sc!{G~w>6BFGishkANy3Lr>BCJO@NNfFk;58a}w_8B7nZEovOK=!N*JM^K_U=K!- z1#XTAF6d!Wv>}n~$u$0f0G&b^fS`hmc19$JXd?^ESs%C@NNffy1Q4tR6o?Y;3dx>y z;)FR8ZhzqkZ`gyPkUWHat|EKFslxr>XTfqdiX8fLgH~`R5>OyhE&132+zkF+683Bq zpa*%-G7gc-uu)8l=4nRQZ3>)|l(EC6V<}<=|vjl)t z2OQ2A6PQFE7$(~6C4r-0k|2;6LLf*{jz8+)+<$vR1erGq@neYQAfk9q5*_d;8-?*U3L5J6*E1rV#nBVlSHW|y!iPvzB5Z!4gAQJqfL^@SsWRhSRN;`@>T zk*0+DU3u+JTlhGc2zscBzT9q${z8eWf`5JA8+IIJ1y+$>`s=p10?~AJJPL8`Z!5UC zExV4Vlp(>>xz8_th2x#CkoAw7aT{rQg>ah<0C4YTvIZjoYflMeX`R66I#y zjYJ&vn%MaL8lNRawNKf76%HqD({fIuuJ=z^vA63dqVCrxxO(!uuJ3R~_T?rO&VR!= zQ?J|uk=9TKY)`gZ_s1Us;454d$)WFRMR;6|bILbo)xdC`^}5U3)?IgXGzBh(S-U&H z#gqWy4T61t+{fT7Nq`_ECFdFwsTyi2!Dg*7_!vm3{4AS&%@`0uZBIBc^X-ir9|xsgsx@iQ}VcIQj|91$^|&`Iu#CeCkfdRtSfBAwqDX0JR`M zd>YSRg6)Y=&G2LxJkJ{vo=$%TsGEY6Xsa8o01dd|)f`3>{ooIzn zCV-_%or?H;`5JB{x(wM1JaA+6=PQMOD?t^J7_VQ!zpxBNM6@Yy(lGGGBEF!HS23{+ zX@JvgZ&H$*B1{duF9VmLnuIEjrWJ)E-o)?{T?P(g*PPTdaCeSJfhC@v#Jfe&27w{c zUEA*Hc@oCuc;AXPFsMw6fq#N(<9%#T85&U(0$T8F1m4F`1|q3KG=PE}#P1D6kV!H0 z_X5Voc>tmmkf;Q34zn)a%oGdZoa(3-Vw~i!0{{dlz2c5Tiq^1A>002ovPDHLkU;%>N;^f%? delta 1544 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 a|9?8}ToR+c_e}r*00{s|MNUMnLSTYU5;C&@ delta 1758 zcmV<41|j*N4ekw)B!9Y4OjJcja7@?3k=DF@*1?X~!;#;+X4u4%;nAqlloQpsb=8{~ z)xnL}niR*HJ=>ob)|e8>uye?vN%_Gg^}HhPvmNEC8^WVq*TIR|#*_WUC)>!G?&Qto z*R%KY#iEz%b)YN9^0K1(6@QHl0uJK5XFugyMPz{^?$_w%rVfgXaC77ooE&P z&`Pdx4g2`<5e^6G-N5?YimHV|nsqn%=b&>+67uWWNhu5b*lqI4US2*HD-;I){ri=L zvK#;a01|XkPE!D!V|+sr-2VP1K)K!ifU)$|008#X000HiNklqC0|2JvE5V|qY< z5pqv1ye;<>&+~**-Uhmb`UVi9vS(;fn#6}V z5{Th_j3J-j#NKD3Ps*5<@F@b1?VSjk?W&j}#`54mJjFx8sU@79A!j!r+ z0c5siAs0#=&a1~IJorSk<>o1}L^z^^5NI+JO2oqOwz7Vt30M2PpD&7t?6{3n>ifhe z#8K15Ok@Yp8#g@QwX)O`Vp#6G!8NZ~EL>d0cWI!e>7p$3W^A_{n$$%5Gg0mNb{BH& zV}DczBf${jQU|12yp0ZwvjUntYvCCHcwrpJBUC4sOcj9CBv{03$G9e2@Wx(vhRAk7 z)Bxr4%lSOlb6w9X29EjVGDp~*&Ej2Hw&0z{8POo&%t88PBXiEDIo$L-M>;6;jm(9r z=|R+hgEy`VLlD~(qs!(z&t(9BfC15^gMXkMa%a1OLkr%xv^pBF;euk6Pxa}vGHOY$ zJY9#ua1cjagABWkuL~#^sXj)q0aJwZ{4qMh`V`9e>8=2QH@`53hQU(mBd9<}qi95N zqX{DL>L|cdgz18Djq_H6Xp2v%>!T@37>iG*T|qvLgNyCqblrv#)iF`UBoALXEq}&Y z;$j^oMtIeBtJRg`kHTep@D8ih&WZ@~gEZu$hcCXdQ!o_>hiBJ!LA= zukvi<`%e1Co$&+VQ$hGeroFG;SF6=&mtAh7pzIA$5Kd8MI6$zFJP<9HM5^nPy&y!c zJA1F+O4tlkAP!NMT?kECL0e5?Kz~URxW2y6vV&-GSQK`aS2gs_a({XUI$rQBn-i)= zln$Ci|CIzlp!wd`PN(ZkP0i*0wiRdFW~b|Qp^mcbjDbig?Kg?;D{%w?MyBoJ1zTsE ze0n!BJKW9E0t6(8#C`2P5ECFM!MZ-3Z}yPQd|C=~Y2@d<$a$(G>^f@TPJezqWb9T1 zAYxq&R7C0Nkct>T2;Bj7R0k#zgh*Zyb4ldzTtpB)5RTZ*$NdBw2qcKRafZ*n1ZqLY zga#^wt$55hP{kw&kZBbi<@5ap>em7oND=|e@tE%Kq$KVJrWm$DCs?+s=OB)n{O&#_ zhLPBek2U-xaVS+20>Et!*nf&7dQS9vqvSRT96+F8A)?}XuxgGZdh0(WLUykKDJM~( zh_BZILZXBkjh+*okg+6i3C2KF22AezSig6uO0c)*|1<(IQYk5G)Qk??4X8`7uZe<< z0xD`i0D^Tw!dTC935XJIkTAx=*3&`S!=hlSLwsR?Ll?7I9GCY*0)O`sz4li>W?qI+ z0}P0d$n5l9<(kMTuuo_(Vnx{MfAu@956Ww4_;4U+cDSBSr$b5*pq0>TwTF%K(NN&C zQX9l2#HAES->(E`(ud{E3e5~^!-v70z=60z@P+VNz5h21*OzhKQt%}R!T^A88jee( z0h5sGk?REC7QmPUP*;QiP~8EbPB8h&ukP*`h5B!8SxOjJcja7?vyNX)fvwQ@+pm|eq^UB{|r&bV#4bxX>dXU?>4 z$E9V;s%XuWYto%{)~0{Jfmh?dndHQt;JTFCuZY2>TE~lFnr}I~om1Jzf3uTI$gpLn zgGGX+xcB(=yNhMiz;=L5EL$-d7DRk7X_oKf)KrD5ux>@&&VPrh#?cltTG8X@;Lf^T zYIxqYj|UDP=Gma*){*JmnMENEXU7d@0000DbW%=J0K|HeE=gbh{t?@p!J+l=T>tr%aO6S!JV;7Lk&o#h8f`^*T?Iq)ZDy&=d9UAcm1bb9ZE( z8LdbYsLUg>a)Qi&0MSMaBafy7#NxCnq9Q624IxV5tjG;~z)WWZ3{*0#BP*h`i1OL7 zg`|;!Xnzb~#t0C3I+&}Kt*Fn0kP;A654v*dHaWUQKa`im&j&NHGlvjPlrzR+d2A^# zLnGAob4oUFLQDtUEPzO3CIsg!CNJO&g>W8?AtqUorZkb53n4;!10!buJ!m#Vq>L0| zGKz>&#))90{lu~C6q96`jw4n;pbky=&{8BVE`K0UW&Ruyp$<*>WCZ37rt!weMmma! zh>$ZL5(8<00w@8YBf7d+=3|H{5U2wH<=x~PNPt+VAe?E$bOe#=I{0x79Yc=*p63Pl zY!bwhMpu&O&kz!ba%iaYk@=_OXH~ zgxjx!=Q##Kg!A@XUoP9~7Wx4APll@JiRSyw7Z&8TlcB+^Pdx$F*AU3=OEslM(gxPLty zuJt}Ni2j{q!KFrc#Mtc=VISyT!UZuX2tq(ZCB%&Nr#j(rlIX2<+h42dyx-qELx7ik zeLYv_>)zM<;z(-;XN1MGqe2h_scMV+EhA7tebwQ#^ccs3Gole31SlYZ&>~3YS}1^+ z$#{515RbWdM11~s;B|8A8P`lR#@!~-LwqGwV{GKZKZ=x)A0d3?3n zW@zc@9d-2gRy=!Xbl-F{OgF$_lGGIvnpR*M<3c5d0bwM9lR$W^1C4khTYq^r46J7Q zo*Z)%`J4x)@kDPAHpF`KC?1%76;mAmyt08Z%Ksiz1`l<>#7i4sc+KV$uxUV0CQLJ* z%bLw%rVs@2!V<--*QE&Bok=G86CDnv+ZzFHA9VITRYiXsuNmEB9|tO55zPK-Cu`Js zP>pyg3k>ws2H5VHPh4y(5caT8McLrDKZ&`b8-Q14N6%LT?tYi#g6D zQ5YvN76X7H{zk6-Mou6cGyv>>`v1c_VW7A7DIENhT+1fC_?N@~AWIa>Z-?RV00000 LNkvXXu0mjf0u07W delta 1667 zcmV-}27LMV3zQ9zB!9Y4OjJcja7?|itGc?n)|+*-os74kl*Xix(9zMz$;h{=qQ}R_ zyuH1}#l_T@aL>=rxVgF3oOsifZ?LYd#;20rr-I_Iio3kM_0g}{+1cLS-uc|T^2@00 z#G&T3k^B4l>%N-*|NrXh>aMG**`IjEr;g9NqU6%G_|~=iC|CPE;T3^yO?;)l5eDiVO%Z*kYp*idt0e*7LtEu!jxIbiV#7y zVIcqj02FjmPE!C^b%6d7K>qzJrjWnv+3eS`&Z|Y#g7N?W1$9Y8K~#8Nwb+Mp>N*ex z;A0S$O-sm?jkZds zp_@OoT6(8%JJVShhH)H*^TeV3j`jnkrFETo7+)rwJN=IShl1Ii#ws<%?rMJ`X#H9I zZRU2{d?@I~Jie1z($^mCL)U>R+(l^P{u~WTXYu`nc7F$7ds}GRuzNI#9~n;P+nq?l zFrfx?@*p$&b}y~&Ty`qxJbsipy*bmyR5dDueSaDuBH~w0zl2E-?M1S^0EEZ5lGM}l0@KY{K)KdbPC-pKK(@<79pBm&1 z40{R-s(;|BDFmJq`2>&JG}_PyR+=~l`2+)+fd!aywKH`b2bF1=>y2&op?f(d+aTHD zZJi1O5E%y}1sjnn?d$!R%Z?MrrfCplZ^s29wsRiaMx#2=Z(R_Yt$LnH!jBjfq7WMy zpirZG+?66)dMmne) z(o?xQ$=hmhSVX?hJxj*(BhIqJe!nLqO$DVCTf+eB)$hsqF#?Kbe z3Z*Zt3&I4#AOR4rJ01^*ZV61zDLf2>6@QRa64#%-Fw5M>DkjDHcs%AqFqESV7Z0zA zHG!Gt3&W ztXA8isMdo}9Jh44T75X{Xyipi82LZHuF}l%lmn3)%k6Fm#A@#ht4?4#yX_E&-G4A4 zp5^DMV9grAkg)tB9`06{-Rp8Vse~k7$(%l8np-|gMNlI&#t9PBFXHsRblhqZ;l3im z!t;4raP6AVGoE21%Xqm(Vf&uNGhB^^yNTTs3a{^e98Z8C1+RaP^f&{;8i#RlI-TBs z|K7w)xgMQO9Pj1P&oJIto*!fZGk>p%)-z)~!b@Zs`me9=pQTU^bQ6X-9L<*DW`qO_ zp6h>L3`)Xv;WFF615WI5l?fntbmNYIhyotKp4PX7vA{>d#difj3Y(20Ab1cjTFXbG zStqm%30X#URaJ(Z2?T`^exz~+)BJWAr6E_Lu(`bE%VbWoJUx;R}rd@eDQLVFrOBL zt1>{4$SBG%fpsIp1^71uP=HO=v(67L|r-#_{;;KiEs1$-6i+EB*9TA-8RpP?Zt8#g{|Bwv91NOG9a{Kb^Do$%O_{^Hp+^7! N002ovPDHLkV1nf@CQASS diff --git a/TMessagesProj/src/main/assets/emoji/0_447.png b/TMessagesProj/src/main/assets/emoji/0_447.png index 33c41398e2ca440192c89b04071be14d08dd2c6e..4dae932675a980d0cd78e5d12069c3ab6e1a9cbb 100644 GIT binary patch delta 1827 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 m=5fv%t&Z_O)9!FSAL4&>C>ag_0000_xiyA delta 1700 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ⅇ}cHXCC$20yarW^ca$!G8x4&EGv6Ot1=W zHWqTxWF}4XcS%jwG_h38Iixj)1iW7*XtTx~ksalDo$mM4G+`THjVXY4@!2Rjb?p%L zICWi@6c+rukBHHjjIeFbY>-mp<>nbUw{1wm7zc5~z@a(>;b8~d7TEARgOQ#o>(T)% z_z*tJ-PDU5f|M?2q<-yy$iu_LtxRT#L%;w+dVng-ahta@8h9PT3@606ZIF0_(N`Yt ze2akT6Ij5XVB4=fWX=;PQNR#SV?Ox~;Omd^qoF_d5=w*@;>~^csQYzhG#L*3@eCRJ ngW+Vv`oGAXjb;DG{CE5xW!eRWf)*}T00000NkvXXu0mjf#h!4{ delta 2017 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 delta 1573 zcmV+=2HN?%54H@DB!8ArOjJcja7>Plj=8zHpPrs79TikgO}V(Y&CSfMtEbKdvk48 zK{wae*WKOSTShxPDgp2=2Vzl0|NsA;nSYjNURjWcg5T1#%Cm=G zFax)lWPE5spJ*P#h8l*m^jrV{02XvoPE!Cau1oz7{Qmv>HO_z6j%9hQRhZP?9f5?9?CSJ+ACP1I|DW4#$&3@@36p(}%9K%m_4>6{ z74E**7IgQ2wSQf0Hc#uI$HQjzQ_^&9Dw4ma ztaf?3tRh}-{)Vs-#Ryo2tZsV%!Z#`_akw>yb>dU_&dAgEISLjR?e{8^$L${p>$pl{ zR<*Yof1E^BmK9^z$EtE0du3 zGi2V$ihot5x17ZBU@}{)fdV8Rt4B&4Pq-xCZNHxIxbi*cfao%O&*GKQ2%fSB&{ zFrE@0c8=Sq(n@J#Njh+fkl&RfaeOix>th~b0|FN=Q_4fEQN8Q9Kn{wDi4iC4Yo6;I zEQJwK^&%(F~I0MP0C`}>s_nKtlLDX^k5NQ2=_XL-h*(JD%%>dx;{zYpmb zhIDW5I(j=dI+DsbHj4uF+)!>b_QB3++<(<|Lz_xt}BM9|!@2ayjgNef{|Lt7=&~DjLf6%|CrB%PyS%>!uX zL_i?~)5Iv2IJ7aUv&+L#Uyhb6?Lpd8Z(t%OAU z&D#h>AY>LyaPhR5#mkP0&JtvxB4rG*mf$j(hf1Y1$vQw#Kr9FPvhIB=0b=TltVT0P zFl3-q9RB!gZ*{lf4}pOcjDOC8NCpOwptZ66?(njk=CMS%_YAGPpeKJ1H<&OvuAuzZ zkGy*Wi~!L(Lj|Bl!o&UD-{_fG;vpItfuNB#5pFZ^+#_TX0*t*)n0h(d0GWgXK2C(2 z+HUv$jWD1LE~p3XLyA8zg7YLn$O{&J2-!an8$=%V_h{kg+TK6!j~>V4epdf;-7NnP X>@zP07d0r+00000NkvXXu0mjfhU@Q( diff --git a/TMessagesProj/src/main/assets/emoji/0_451.png b/TMessagesProj/src/main/assets/emoji/0_451.png index 63a206aad82026ad17db236f766d79f5e14b0017..bb1fc2e2eabf9f9c8e41a1c95d769e19889cb574 100644 GIT binary patch delta 1848 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 ns@ehWT}v8=)ov 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_453.png b/TMessagesProj/src/main/assets/emoji/0_453.png index 1c49ccd7cdc89efe27ca004913668d0b20c1796d..1dbd062c1884ad80ae009c92257554ef9e2c89ef 100644 GIT binary patch delta 1903 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 delta 1635 zcmV-p2AuiQ4D<|;B!8k%OjJcja7?6!dd$qsZbvd>KP$h#zj{zQ&(6(nM=;08$jZvf z$;rvY#KdDiEN4P4Z$>hVT11LkL$<18^HK*45SU z@$vWg__cvxm0?P!Z&b0ev3*fFpJ`CNzQ4krf2O0Mm3L^ytACcLig#ExAkn|Eh-+F$ z9SS501d)k_#FT5Hm5{KJPyhe_uYm)=kZ20&lv zABR~JBtX%q%s$IHk6fQWA}lTM!&jB|NEV92OUhkN9)EbSIk5pTEG3L%kv?2)CpMqU7GQF?S&W&timdqzt<7;Yx-M zjC(d#mIr2aKp@0bl#9L&5Jc#ZW_5#DdN#(4_l1OHI%1GBV)Q;>QEqc^f`}vmh@ucl z`ECj79Dhc?lVok#F4`+ZLX+;OtmuT>-h}`I2%=|blB~zAuq~PJ7)7B-5>f7pq7T#` zJhC{B5s%a3W=w4k2%gmrV~(P9UAaF>6-9x=eqVMS@Q*q{#Plx0%>ovnoG1-L@vTH8 zAevALKYQrKT?E*KRxm&qhG7~;z#IUjfEr2EnSXS#93w15WHp)q0_Y1a2!dcE)iKc@ zAP9-UgmEVHGNr&55*4%1A0qUl)5rK`91cB7Lck@fvxkVd@5CX`^Dh&sQ7|9{rVi)> z5G=miPVS-!MC4VAJAve1P(1($?u@p|(S>uox2P*X#17`D2moMPdjzX{C&ZI?yh|!v za(@=%*1ARLMFb{HqV8zoR$n~;-c&dze`SJ=r~n&d#2TB42%`eGsunLweI&?O8Hj)+ zH^=x~R|vUoAOj(TB*DaKY$zb=EX!`roF&m~gKx6^pb z6e6zQ7FUS(sE*?@Wd_Urde`lDyKTbr?|$S~vprInt^J&x5z+fKA`J?KXnnCmZ7FHZ zp%X3H%GoCMTZt$NmR=(^p>r$%5g6R>)E|Fx>uW$*Tp>PBJ~t%d=!DmZg@|g2Fn_I& zcDvmI;pBUVL7v~iPTGoV)B-jfPf8NS$<8E&(9P8;NJ-TVF{egeG7It zOUq-KzKxdTEetyW2qQSOygHq7*KRM{+1flmohr9I1O^}y8isG9eK8Beh5`cjrkPjp z!kc{%e8{V+%3+5Zh@edv&PIrLA%8S2#EoH?SLYU#;~j!$&T!~Bp{5D(K0+)IApn7l z0U$>OLk3Wg&m8<)?B=MSf;I^zQ4CcKICP6K z_A*1lt!5e|=^1c2e2He;fP@KW_dtLg+K^)GLmQG9X5Mn!<{5k!A7j_Dc$))d$gy~U zn7mM-Yy>&+)PpoWD5-xdJU5riA#*%@41d)Uv=Ib3_pok|qVYU8+Tpb@f<3<+UE`%XMw6l4V0xWF`^0+@yw-~=`z6;v+Avnc2zzzPRYXaJckz($A! zVm#4CF&xEEQXkL*#MnF|U^`?MYzWq|VZ;=DBc3yoFg-(%qW~kqb6kcrA}OjKLkLXq zOKo1LG!h{O6)C_A5Pqx0t47gDm@0(;fK9ph_ZMv>BuRu+f&j4aH%;&q1B_CCO8uR( hnZ1H$o5fEX@_+ESKURO#l=)y>Sz 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 Ef>h?>IRF3v diff --git a/TMessagesProj/src/main/assets/emoji/0_456.png b/TMessagesProj/src/main/assets/emoji/0_456.png index 4eeb1fb04b0a4f31f2e990e76f565fea9d87fba4..5039ead6b3d6cb2f5663cfe57468c29e30b9c277 100644 GIT binary patch delta 1761 zcmV<71|IpA4Dk(+B!9Y4OjJcja7@?3k=DF@*1?X~!;#;+X4u4%;nAqlloQpsb=8{~ z)xnL}niR*HJ=>ob)|e8>uye?vN%_Gg^S2)EvmNEC8{5d4^}Hh8%b(fClmE;y{lzEu z^W@>97wfJX!lPZ+!HL_Q6wtSMxspPUS`fvK8@qrP{q@AquzzQrXcd}uH|5u}`}pzl z>)HRwE9u?95e^5gaSi(2imHV|{m@GJ=b&>+67J;9Nhu5b*lqI4US2*HD-;I){riIr zpz{C#01|XkPE!D!V|+sr-2VP1K)K!ifU)$|008#X000HlNklk~O4}032Sa^XJ1lnPSzjf10 z{Dp%EIDi(N_M^$10ReIbnI|1)LYCM*O8{WSzdSU7CIR6Fy0kbPX1GHMmWjf$xX=Wn z)J+^j%7268g`2>W;3_P*mR>c%W3rgs+i0M9^eE|@Junow>{f=7K$8#Z)K~h;q>QNn z0vLg(iNb5SCTW_6lxnXp(spN2_>~lWlSlh;7I->VptMQ~LaM=flCA;>w5%z5n8eXO z3K61cAEk)Duf$I64%dp%lA`Et!sS&Ija`K3ihrVLxZ|MdZANf7$ZcYt*Fq;_ZoqCD1~GxMEk@5= zPWEU6Hm|lW6hv$im7Le7ts#UA0~jb%aDNE6BThcfaItu`rPa~_8?3lWjJY|-+DgJo z$ums|rutFnq33?P_P79Jp-fc*4VV*xMRl1(HRoW4CS#lwul~U3D~g+NO27gi48j3d zYfcD*(SfhdiON^d4bN-T5KX*89ZKdTcHQWB9B1rP95vhQkC#mla#Lk8Cb@g$G=E^t z#Exo`SP3rrc)7fI>PNzPv)A^^<#-Y@Lj5H026qp>p`E!hAZ#zayd&b>U6Wgmvvj;@ z7Z~-@0i|~G=GntL1m%dJS*pJ;-JD{VLm!@0B z<&g7U9npPdJ|M_;XX(e|C6|-Kba!pV$+Fzz<+73oX?jutk#OFvBigUbMg%ZYeH^Xa zMY={46(hBRah_yAAc%;a*Y+J^1PIPl)0}VDJJ5PtuJf&67^fZT1j|!(Y=7BzMt|-! zbV>w3u&x4>h=ON=O2qJv(C%?twjl{3P)3Q^A_8rQQAAKc*x1ecej=L^f`}XAg!euI zDuM~E@MVszxKHBCn1ldiUdklKcDDxm6#*DTAbiYmALXC8K-?HASD_UqQ-!N42eak) zpY}sUKg4Eyv_a$8<}iZ{0e@8vXhj@8Msz!a_?iSZKoEb0lGQ3$nIjJ0x(^Y7d$R#5 zlE`3$niYW%G$DtB$B0(oy0Pyt6&Pm8faH{_=FLNC!hL)E(g=uw%voWh!kB=&0xA>k zb42D2up7uA0D?Lssj6uh0)QqQKXzR=Xgmzk>}Q!P+l(Ru4!+9sD1R!BSO9J&I?ZPv zGcSF#K~)eXEI+=Ny2K)dN}&@2HwzlwXWwaEpu83g3LCNW{pEN(?h{4;S`s>qX8+4C zqb}Sl6@xkWUcdoKX-Tk0T`2$VQ?XYuC^+{Km`y8aEt$x zVLMDPAPFna9NS02Pg)rxAB->nlm`{>N~7O=b+?BQ1|TShISv49d02Gu7e-_oDIm@f zFcKkt2^o%FWe5ZbHyn;e!(k61{8jx21D98^wSX=;00000NkvXXu0mjf D;yqFU delta 1540 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 N002ovPDHLkV1h@DBZvS1 delta 1332 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 delta 1224 zcmV;(1ULJ(4crNkB!7NTOjJcja7^B(g5IZs*PM3bv5erXhuWfj-KK%urGVR@dfcXg z(U^1Rx0CI`p6a}q@5ZC$vW?-ahw{s*_|~-b(60L2yc`n=@9*kbL@(8tapd3BiFaZ< zDHWxPaBW*h&b5=Oo{jtA!p_C9(2i!trGLzsF5|5py=z6Xcz+0=E01R|e zPE!D5oXxr4KmH&7d-(bnp-1`CH@5A_S1YWQMp>>960Xsi@HGmg@(3vAm z(@a3%y+|)UfA(7zZW)mV;Zsdsc)r0{9lg z>Rbu{*u_tZ0E06u>mWO&^q<^P)&O$|x1p{M6XI!%0Dq*b!Wr}x8^aAEA2u5Aq*XY> zd`L**9Dqm}Je)(yJ41GZb+{BVdT`);sYr2aNG(@~n?tDw`?^(>g7Z5=j*!JTTntR> zKd53>puq|pR|gvS<1)fX83Sj+^hkn3ejrd{hq;!qjh`r(793cXlfen_LlT@rlY|EO z`Off+f`9S8>WZ%Ft-(sjG1+C#IKX3tl)%qbHMDJ86+K-((-##k4^?$$D+*|Prm4tr z%H4(z%@k9|L}!$QHPz8?hxWTnn%sEGEvp~c0a8cY=r zHZ}AURIt8lr?%>bVYqh;LyyaC+x1*3OyMmZ`+ulL1@DXLI5d4x;I`alXeYDW9=jHl zQV}ekj=(8TMpf^EsE|qjk95F%gQWQ`Bc0~6-6NT3q?YTp=z3{AimDcG>_6Z zO-HNU*H{h}DwK?VP@L*W4pVb5ith7V9`(VIPNh>^#_~8QOc5ncF=G@;9-Ff7@UK7L zkAG!zRp2Vl*P-~mDH~-Ki>HonQgDV>etmvk-p^%O&bJ0CMqGY>AIm1=s7RvaDe;oi zDN&pW{5Pk|Wo(?mfx_bjm&+y>KnfN7aMWv5fDj@>2?`o_*5@3wd`L45G>5WPEX$Bg zBUzfK=9ny?hnD~{sBo$9BkGe2ZQg0nvVSz7m=qG5peNs>Ntn5w1V1X!&s2h?;T%f> zRhvny!CsQ(=Ic(uF$Dklq{hC#O=yx?Avpe$X<;3?Q81a*+sALAo{jOR$(+%h!j#Nr zh2|>3lm3`37J8ckD@Nd|z&RkPz0DKCw+IAnhjnC7pH8(B=^TP#h|N>{M6sI~8h@fl zv5btlRY3F>K3BwB1#_W!DiAVQfoWpDSs_fQ4RmBusszWdXNPtM4NOMc%_@7dDagl{ z!G3*k96~ctW;fOyz%)wq2?Z5G29-Gj6|s)5fC-YQ(}$&Isn&vloDJ(aIMXN*lG>mq zUNR8g4k!rWUfTrYp!|6Ad*VQ05J7<$2?^xR?dA(XByi3w956z-d6n3sBy>F`u!7eK m_rVScd@tVoJu$NRkMIw>=%y~89HlM*00001 zi)O!%XTy?e(b3VWbXV)^>ihfp^YikUWJ}xI+rPiRh*&^wOn)|gP&)p%IpmyNUyfq^eST720Tu`8956zly77`2Jr*{ns z1;vOL$nxLy0000LbW%=J0By=hORbC!EA;BoFYKy>bJup0tloniKL7v)j!8s8RCr#U z*N0LnNfZWPL4O#6fH!P+Ps}+7GKTy9Z?)%i&$=WL?=Mo;Xn*zh=^3kdxSbK^;V&~9 z4+hduMCuL3--Sj4sUN7S=en*eyRPR1R$m%?LmBn@f#=GnalPPvW!zWg>j7nOk1&{c z@~82v;rQzgAl!)SOa@<_!%*c@xK*TgdyW&!^5olb1Al4ssW1%S^ejjI+W7P&9M^TM zN#OpSfgL=))9{WOo^^Gmk}67uVc^{cAkJib?J!+Vs9|BL-mUc>MwPCVaO952Loi&- z(LxbV#DUjjaJ>W)R@H`9;CNkNUANMK;G2j#JSTdpD_W{nw#~vxpgO3C@Fgm~AS!=3 zm(v(JLVs`qE8Bq)T7Zb)T1)_62z3d1XD8an#t;>VsM+p|a019_g5c!J@O%`G5P+zt zoot&5idcM2a2!sFLjBPRG2ruq(m`P5RAYX#+arQXAQ1eOb!?ptqXz_T8;QbZ8Y0a; z%L}1&ft&v*XU8h39N;Cw3J5|NO`0a&XH_BEAb$a%usGN|eLhqk#IrU701SAu{V0a) z+pNk%3wi4UxlZ72t%6b@Fgnq7U1K)&(5LF|l@%dhsT(>EhoFyU z(CWj`UvBU03j8)Og28C0uxOvRxg};X0pcjbu7s~MrYmJ#*QIHihKUM~ zS%21LspwkNHW_RMk?`z9#K2od%zCrJY?cZSKVohv6&L;p|5Irb|B?zfkb-7+H zm&y_&n68ki)SHb7MG7RW>G*^gV7CHF=xfC=mpm_!QwJuyGzm+p(1M)Z;NuX^Gou=T zT`v^_6kIM0gfOPALl>AXg&L6I`I8DIQh%nwADK3W=tu~MYX-3?vnhcpT3Ues2XY$8 zvT`I$;+JK#+oq+iy!=nR=p~D{4Xdeb5<=lna1^I`+!sK=KIo=yHre}oTpL{rj9!!d zCVqc!RgLMyZo^6T&*+T!6<4_rguQW_EfBA-<;M6RlybF=fq324o~99&7NP&+;eVWn zG9*|jZ?^BRkge~P%729Elz>8ZM7C@o@`7FvKN6bxOd}2wXzZxFGP@H|N*M_J+8MH3 zGUiv+WsAooO@J^Q*^2>qZw_nOLjVnPBd>O^ARG?0>>`ob>Ek&uo2MzZC_TB}?RJMh ze;j!Qgh=hmOMcaG<(g=WCe)vu6Mv(pDD`cPkoC%~>EZCQ@-}M##E~v*$1T&tpEu8` zbtF>yb96y0qBI3U*Nu`tXPZ({P*|@~QP%YeQ!9iMK3zOq*%V8u54u9jwfFSX9 z^ss^e1e6e?xVS%Kz7uYUnEDI0FwA2D_Yp<7kINcA_qdZ|gD^1Grba#lLHI3{xJLA= z$hSK}7{vE&2DLRob^@bqH633g#?!owY^;F@ugn7mXiU!2Q zS>WVsVjK&Mrq$=fM~%)fp?^1urkDf@qC`F&TqAm6QD6;Wpwb1mB@W}GL|$AaBp{#$ z1)?*cJ4!_SN7jX4rx^%g@9IXRei&A9iZw7gOX9d`#CNI-0k#oUMKPU909-?+(lCp0 zD;g?VynXGm^>GZ)fl(B~-e;foMq^N(5^kWP+ex#9G%4W#?1Dzww0|e{Z+Ff>!h=}Af?CRtX4a;D z(w%kCm~hRMY~Z_<%a3Koh+oyBdb@j3-nEb0uZY>IgYNF?* z#Ik!!DvE4L9ufseE)=tHN8`Yn$EAIpXhpA^hvdVZ->xs!o_{2&ZU)AT3~|Kj5dZ)H z3UpFVQvjRGVBbG>{vNtn_?C4500cuxL_t(|UhUV{ZtFM@2H?m=l-P^9+)K)N{|DTe zq3OV|tvKgmZ+3qpjzfSSh9feP-~O%qpJJJ3B__+4#oqw)av@z^R~RlA+48pq%uDHD zdbozGa{e1(S$|4S1yBOMLRHK1^-AW-fdIyBYPWc?kRp?g^BbeCY6_QG@rqCi=b~{N z4so*l*(er5MB}3H7{?t&L}R)JOhU*(00OYUls^!qgxnHT0tzBV=95AWKr*6-lU?4zQ6jRGkN<|_G^_575QZk#^QYfe^0e?Wu1p$EwwJ0WwP^lFJ(DouF zmO+G3`O__-%&kyeLq;N$DW9#w7$Q(eK!}M55+oS=jCVv4}V^GYXyf>@yQ zb|D_`jDI;1LildIUUx$h5;D-R7h;0QEfTitPJQ2Z<8VOX9fQAzv4i1L*I6{4RY64W z1#}{W<1q>ccp(CR>j2GQJ+5S`3MGZ(&`Ygj5r7Z_QY5Aq!i++Kt6>;wO~SPbNCm^{ zg?1`oy3OXa+4LIcA`+QHPs1IP>gh#YX3QET{D1m<-0XIno(x1HbLs~iK6iU%AdC6E zku&eDk$zmQ*6py}Zq7rRk4S$$({R69pNut@sk^&DF(bl`=ce1OHrwrPbv_~xmE*Y? zX?Sc`qc_G{W%4`1?>$r9rfqjy%-69wYZNF$+iv4<)eId7%&_bMv1jIVZrhQFKgVWO zfqy_%RI4V+yFa>Fbs#Xy?#_E8lx~}Tw}T=+VOBU?iU@7fthYOWKiZ~MKtS$p^BED6 z!_4mM>+|E-G|jtC`xA)O8izyEYDvWX&X`BSVa?|Aqk>88MZmq;fWbaL4o&;ciLm8^ zqrTsJD><)q3u)T+J?O*t_G;0@!K#h~wtwQj8Qv;aS9KL&Y6yXfh(dyN2o+Z-nB_f@ zFvu%Y_Wze;%^EDv~bzKeL9OvX$q17_)3 zF=iZH;A;{4%RmMO2O}7`9H$e!F&?Vd zg;WQp=d^ez9e(73gjX|PC<#bi!%W9(442f0*Rw1wBD_Y2zC=j1$P@5#Ax28!Fmx-n zaI$`zA}@^+6loR!{N?x5aser`bOZf62J-eF$v<+Pr<2uqt z&1(YCYyt3u0r{E@#%2Wdj|csq4Em1({jw4MvK9aT{{#dC_N5Zrfd}M}4FA6~*mwiq zi3%biA?lS2>zff05)&>iE=5E|-{0L{U0gL60(*OZl$M&$&wtXrzQFJB^5xBeudb`) z*0NAS9&K78rI%~}xd#9DW&P4g|EUH2nFas-&i>p@^k^lU={;(JS`Gx=cw6Ksl|J_*s`lbK2Apg-c z|K>B-uP=&O6o3Ehb^rd`>A)`c$3_3cIserZ|Nrg(yej&t6#d#X|H?RxcPgfA81SDF z|Hdra5}6tR000$qQchCV2eNdQeefb%+^zx@vkM*U$+ ze>C`~xF}D?Q+JO{#}irnOU+1}5exU3Lr2%b$#G@eI(I9G8X?ZlYzvE`xFv1^yKii?g-4#@eqDYH427d{z18@h~s)ABcpyMZ3#A}17R|q&_ zeF>iQi~^UX$50HhNt^Pg&)=!Y`MaiJH4Gg~uZk;Fx)q0L&@_#4E`K`DC!W_(0SR@M zx}}8&igtBqP*_kfATM0GJXuNMySfGm4HjUCLrQ6Q25tX{E#0zfs%g-=<;ulGM*`1T zjel%yXp2I61#~QReYt2m8BC*pc^of{)odGKPfUX#XfFysyaHSRb-r65i8hR}9ap6D zuL}0T*aquX<$#Mi4l0 z^%1dO-Pc=h>P8d=;9^Kp1QpehVvKM2c7J@~8Yzm@=)hCXLmny{Dq$qB3I6|oqHAww zJfsS0`r4I;L?hp!2LpNrKp2*bczzHFXlUY0?C#l>mI zs}OV$@+AGIVX9YURv^1&kW41`lgM*Vg#b1uFY>XNK;9NbmX&3tABIoA$x(nfRDUqC zVz&q<_Y^+}+$9+s7UFvj71g7AyMG`OezCeJK%CT>IGjpxUK*k&iSscfV`r%m3o}dQ zxW%Rb5xh@Wt+UD?q{n{}JdB;II#C?Y@LJ0uVo?)nki%mSP#*Nd>v1@iM5}A^FhJyZ4G7nAJ%W&HAR%Q9=ez~t*ZFRNNWiSbCoD4HmmiAO^id!+m<`@Oy=flJ^%27i}t0$t6t$w z7-K&JxC<8KF)q_;Uw;~`tO#I30FBW7RRSNz!A64+vH0t>B!c!c@Ge~W$FswRT_aGA zDc+r{s@kr$*bjgz*evjUUN=T#It?SJ&);4JFdkhI0}%jM5U04BR-X+Z zP?+J(*p3D^Rlr^FB(LX2=`unJ7(mFF_533^|9FAGGc#vq3!?w Z{0-&BT&+SZW~}7ZW6|72=ba0@S`NTwrnPg$^5Gw{pPn-GK(w za|7y@3}d$MLZHZi_G;qpXVBU*e{mkQLpSsrGM#v$MchqYMpsRj)7d` ztR#wOLZggTgmPGKSU%(9+{wwmr<{=W_42&6rXydVxUHU}*!M|NUH#u#{hS5==V||| z2mk!P|IL{|NF52{m%cq3jgeV|MzZnJOls7Hvj26 z|Nh&#i6Dkd1%KSTGXA$Adq)rK+C{B+7yr{TkyZ$tVhi??1kk-m>c}+z-y{Fb67{4I z|J*UnnIZqdDyX4YrDq8K|MtV`R)qin02*{sPE!C^qw^a3Gyx6#k;Zqm@120y(7D#1 zMQ^yXE7E8r000JsNkl28}q6b0Z=VZas=5`XoNyvwZYJKpy#OWXHFT- z+U6BM^%d-J?j5eS!(I5Xe+G$b{u%rNJ9hS)4u8|=ab6ek83x*>>$FnDGUvTFXKOve zHds*4si6aASZwxQ0NM}G zS$WIVw1PQgUBgb=7iwC=9i7+UXSmodgMZQU`fxamf;WB_Ubnr8DsdFRE82>;*TyEd z-K+@sfQk=Lt=+b}X?(LLyaEGac`$YrY`_0UxMyZS?3!Iqno_6u%lXd)6Xyt)ZO2?{ zJ|*^(TnHdy%hF6Ue4T4Jk>%0}?Zx~j98l!CT}QU(+0ojc|FoAg&$427vl1@$TYs_I zxN&TGvtaFeI1v-U@AvgQjTT}7!J@XEd#0mNBHfH)g%B_Tb3snT3BoW80%tjM77W;W z039d5A`Zm%U&C1xQv%1zb`yjF!i%=>gJ3xxkIC)MEZ9=Q#yMdD%gZ1zXVG>YYOzZQ zE+M#c5riB2z8}thJU!Lh?fPyJ*?*zwZ0B42pil7b>16%s>BlU$cne`xsr=N2v_(nGBX z0tn+X;j^Rwk`d`v$U+4KNv&KcFMwOOjM6?_~OePOwMT|YHVl;_Gyux2{9ToCX3fPZj7Kv0zC@P!D;PGl)uf{<4u5HKWV;Km08TEy-^ksyE=twbR^ zjx0Gk%Bb0)hB7eX$O$tdij9Fngifb9qGROFioYBG5@Xcvbbxd_gQ=?pK}rN6o~uEp zON35)M8>ETe&xGS1oL+|kq&;}q z(8phkBF%L-$jgANL#XQFN2wv(}H@7^i`nMz{`9hAn&gX0U{~zvIvJrYQ_B!8$-OjJcja7?YLsiU5qb!1$3Ug-hbYubxyE~WoS}Egm`hl zqJi1Rvy+aD7Y_$I9}b{uK;+fH%CniHXc2T$FUE)%y$Kl`0000LbW%=J0ChzAuqrkF z4*QW>e&5*D>s6k&tRDjK6aWAPYe_^wRCr#U)(2Pe%oYV;dJ;fvcUpSyh3fnN|Jglf zhA4*EzOATaF@Mk6Gl#I8d>a+!EGUIK}@tI_a4 z0q7c7*vFCIUcML-Q&}EX<#Bxg!@`%{EOYL1cNz;1fhz$96mejo0vspDFUSos9IXBz zOG8IXtA7)Am>X%V=ee2Y11m+*p& zQch$zK74R!f`#fVuIm_@SSs3p$Yr#yHd2$5K{!CLFEOuJ7H0+kV=YvPv`VTPR&Z!w zVs6^_en8!%%H|o?7!Z&Jj6%L8xa*RlY?`LDP22on?6N7#f`Gy5R2^=*`8*MIv2wZH zw11~l+n&yLAIX$0hh`)LUpA}7eKKjYrz^!P; z@)I$O@fwsM#SvOdpii%WLr7tBS9GbSY4P9XlMhZ7L{ zrv0cvn$tlNhc+yH9#F%e+sTk%b0qvGIvw_ygYA`Qs4980S69nO!<#tE?ulpiHh-tC zZ#q${h~yZ)*D%ZIO3*TjN*B(vOP+_sN+b*jJCD3K6zHXiyaK0U1JOn&hQj62Mj;Y) zm8|ZFrz8P_mr#ST7j?u6eGl)5g|z9HmDt8TX(|A#ND`kmMcApwI3NTki+}YlO*IR9PG-ADY51tXJlFxk0%*mRz~;Nn8bL`MQTJaidjQ~RY0C+Pm5YahF3v?R6mGVL7!+) zZACG%dtJ1DU#@mrp=(m6ZdI0JN}Oj;k6uQ6P&sTwExwIsw}WE3h-9jASXenC@9^#3 z)yC1ouIAy_!jWkm5e7FR56P#0$+D2CmVu6SQKV@K#F~1dhJR+`tscgeY|EfY&6y>{ zhze1c3p4-#01R|ePE!Du&cj5u-~JwM;Gn5CLgxSg1TslPK~#8N?bp|K;z$$)(3X)X z1eKGrh{5jg|Gzi4f(v>GGW{?wJ;#Y9FKypCP(uFpU*-QS@-i!2vNB)%36K{{P6?@8 z2w!ITt3X+BTz^%yi>V~}GL#tv>x7s%2LYl9#Nr|01t_Do zwFkcYIDcbpU74t`I27T#ybO{0aD7fMgmH>FP{avW0k7gxa_WQ$ zqG4Jck3tC>fMf`$=qR*cAUq)Ql?H++yZFIrc^iArxXaSMtT1Hbx0y4xQc($IYf4_Vgm)L)W(ca6cI2 z2~pk<#uy~E8pn3ya@uw8HWBY*zja5qr+s%Y%JqV>TcQPCA0n~+wd;oZQ>gb{B!0mo zjeitENS8M|-4krzckkOR4Dm5^V|rd~-@*E}Abj*)&y*w3%~dDUj^NeM^{3P6=f|$= zx-$?VW7iGlbo%(%cjK7@q0#LwDRtXw(a;)`QV>b>v5K?wMm}B4XZAG}NLVrOO_sUR=l8O*}-koh-`zq27Iq!D6@BZ4w zfKURexL-y?!ezg%Z4#1VA$5f%G$HR@`EnIjQiWX#NklT%j-WzoasREkKrn`+o`~nz z8Xm5Jyx#8|Y0dAyB`&hnn^q0+ghwm^5LSh4B*HqhnLWONEDd6AC2h|D%N0!_#K5r zQ^5#?@~;bE%q6EDf$2%O;cJ*$z49O0VkVeFVlZu(oR>j(VGzOM9V`G`iWSuGVix5L v5FeNz^T6xL%h?<<%U}tAo(1IFUy^?SgxS14BpmY!00000NkvXXu0mjfjR;UE diff --git a/TMessagesProj/src/main/assets/emoji/0_461.png b/TMessagesProj/src/main/assets/emoji/0_461.png index 8e4dd10bf978b188de55f17e71ec9a3f66b7840c..4f6ac2f4067987b63e6bc2351f4acf4c38e6f599 100644 GIT binary patch delta 1573 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_463.png b/TMessagesProj/src/main/assets/emoji/0_463.png index 133b8d9ee1330a98ec46a3e82a6c35f6b67fa97a..52d8be9bda9abc9fc56bcf9aecde5f6f31bba36c 100644 GIT binary patch delta 1669 zcmV;02739X3ziL#B!9Y4OjJcja7?|itGc?n)|+*-os74kl*Xix(9zMz$;h{=qQ}R_ zyuH1}#l_T@aL>=rxVgF3oOsifZ?LYd#;20rr-I_Iiuv5U_0g}{+1cLS-uTwF|NsB; z%c$+dq2{%b`}_LqzMA^s!s_bkuB)oMyuJJ6$Jw8F#;1C|CPE~JHFH7FRnn0U;RZ(J?}kYp*idt0e*7LtEu!jxIbiV)oj zg@XV902FjmPE!C^b%6d7K>qzJrjWnv+3eS`&Z|Y#g7N?W1$RkAK~#8NwU>!bb?}Dl9H#p1NJPFL zNitM&hq-aRmi}nLD@`Q$zQaPg+SBe#6q+Q)?QZx$G*PaUA^D=tB$3Vet@t^xm<`(s zH4>-H?~k&vG%7$tyUF z83fc|)PD?seZ+ULwYo8cIxy47l*tD;pcn{1s%Ud&nkHIi6<-IoKY{9bn+%y`r`JuK z$ROdE2saogsTqD9j|HzdG7TyAyzF(qM2TU3#xM+_5=@$Nykm%(XI$Y16cP~<48zN# zO_FLAAS=yon%HSH7*fI<$GJ$r0vhfByKDfcK!3@XVO34hHWLg<=^!r4PMeL;a1YvL z?h|~Oz#j?Qu1fYI!9JRS*&VZuogmWB-yif(g>iN+gnhU_t+s68HvPDc{U zWSK|_B+^mMm2QDh!;kQQHB3{@(w*#hB2_7Jvz;pUCeTQTUva_<8hX+dvP~V2ovJjF z=Ad@D7Lw4n5new`L)g-^;n6}!&vGbD!fLPK;SJG4 z=xM%`4G9LMi3(GXx(+0|A;*{V;f0j711&|q-yL@Q{Jqq4$Adw^Ry665L?||Lxs%@4 z>s?va@n9(TJ88FGznh!Dasrab`F{^z=w*4#K#|L<-Jt-*`e+uvD=CV@t^mcMh<}Kq zyLp_@UQ0nyp}VDB9M;I;WmSZ=A0Jr@-kUbR|gu&#sxz=ODGbr%)A zwxW}vf~OG*(%K<<0-(XdTPmZ_&2O7gId~Krw#_xqTfrD_MSFf`EO2#n)PDiu{w17M z7Q7V{=VqJ!Gr>weJ9O8A6f{TwWWZK1Li*Pg%N#4wf44(tEWos#S|RGlm(N!f%HxtS zkp>vJ#0oOR(?4|r>R@DvE4|GiiI;UH08axu=Q`SF111q)S9Cx@XizysF`BNU^0NVx z0LAqmjY%9YGfy}W4H4f$0DlHPxtH-b3KbMFPXi|hc9qA0MLdQ8@uVhjUedi(IzDB{Y5dd!!QaqVI=$X>+UpIVgn!Eaj8i>s9MQI_ P00000NkvXXu0mjf6$3?T delta 1428 zcmV;F1#9}24WqZO)V5=6Y*k=oS@9Nd|`@dNLESX3{ z(vmZitNfHbDVze*Oz zhxh((km+1s9}as+e3$)u|J8mb{oo7&8l=EcWj*h`HiWr-UPH*B9Po9Z=>3<3%lVAP zp%H}9crNHhWuOATtDNBg{PN70%xxWl#zW33x&g-%qkm6=VcZ+%3eZ(9`j0d11(?d9 z%I{+k5!my|PlF(#A|7KHDA)n!hgSL#BnWK%(l87(E;<5HkPbU%`9VT}0vN{qZVC|* zq_d21T2(;=?IcSbWZ261=$eLxgck&t3mK$51l}Ma6}^sOesE@bp5xePkn$K3E*kusC2=q79;OqR~3t;C3kMis^*;Q?WCIc~qCNSLaM zdaLos5CPprV$nLyS)++)<#T`pke$#II0mQMy-T@PZ-AIEYt!OL5;LtlCe;P zJ1kKZoB4F&t!1gF&@TMYK$2paXFvSs)MpY^G z`J)tulIq_juC81~Xl);x^O*pG9Z%Q%^tsuTCouj# zqJQ;gc`7%X&-fb*mL{X-mvj#rz)K=dS@{LT?RMQqULAHmeG&0>%8ncf!4{24xXcB@ zx@M=Z&20n!{F&)yO+?vsgR8gvyEqBPMdG?m!sn?-c^V@Dx#hbeW|d&-1rWGeerK6( zSwdR=xcQvAsV^)RXIXiJD$3op$O5w>_J2j3!|H9jI~72x=$^6sD z=&du8febAoA|jZ-!$__~08}62w}0+v63U>7s!Di>eOru*Ac9+=91MRT#)(g55JHA! zS)8;=;I5x6I{~`Qu?$wlq!+vI0*hEt5zouOslqm_DCMT-DWNXnX&GRkAYhW)t@=q2 zpduPKRoi_Y5@B&`mw#2s6Gp7%%4GWXEK3QkkifaWD|1M>N^8NF)W$2VkbmJqQXzy3 zmjwaK4W$NcJk50Ag8>3=@iC!W3-m$riZR1YfS?ijA^o91byK}oN4<@jQ2+|lw^uV9 z;kiL^=}-W4@oEj~!JmbI)IlJeEoly~XR6KoN(mvp)ToJHB8$;X`aW)-4VDV{eTL)3 iQqvaWDYWpP<}XyE9pn*6K@F4u0000u-;z|%j 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 delta 1270 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 TvablB00000NkvXXu0mjfN~~TO diff --git a/TMessagesProj/src/main/assets/emoji/0_467.png b/TMessagesProj/src/main/assets/emoji/0_467.png index 0ee7464813638907f83b3d13dfad24e12189e4a7..77f53ddf70db93f5ddc1dc90242276f295ac4a94 100644 GIT binary patch delta 1573 zcmV+=2HN@j3APN7B!8ArOjJcja7>Plj=8zHpPrs79TikgO}V(Y&CSfMtEbKdvk48 zK{wae*WKOSTShxPDfh3|%Cm=G zFax)lWPE5spJ*P#h8l6{dU^l=02XvoPE!Cau1oz7{Qmv>HO_z6j%9hQRhZP?`B*x zyYICI-Thy!7k{hOi2x8|@+dKLO>~J6R!DLMNjej&sP{9{7Z7}aY;gluC_w}HB zCXNShzsz}rj1n~#UQ`S^!ryf(3tk2U>n&#qtSSpUu&(rlAov%QFQG<_Jg(AM7T)eL0fey}jO61ddL>Ezp<^EJCllQkzSBI3tua*>fsy2+GVzK( zL#CZ9*nhDcEGKc?>&#TLrvQmVb)dxYh)eSA*KNLvv2m~rh&EG7SEg$zV@UA|i19oP z<1rb+&ha*tN=l^-N&AQ*CFX)4?(Bn6NmbxK+m(Kzvl$2kOdMs`jL2~`t}1PaNFjJnn*98a@IVr;O_V4yy|uMaMiR??BmC<`o(FR@%|zN$#zAd*(O{&b97Ow66Wy}G#RRb*z`d5D z<$tZM(^=JBA4Rn?9UWSsU$@o@!Bl3#b+vGF0O#O<+o@2x$5z;6gD-IE7ECw*Kz?%= z5i%CKMjLE7eNtgtW|?#VQ0d#-+m#oQ)^Jryu%a?ZgW*gkdB&|)(xpPS=Qp9=`t%D! z*w;7ZUeC31LTbwRex2}`V&L6uQs<;Wsg=lsZ-AF^W8+d%0?MJ z8@zN`(pOb=reY-YC*37oRhd)KDUm5k_3jE`x)u-d%y}XzFf^fEZ1*%6hRsq72rz->@1`%;n)RjTPxjA0a5K(h_F@NCh z{r%LGh_H@qrijfwA%KuJht)4H?|=Rr82zXICy-FX3nc2E!&TbX(jh|Y0|KTa zAp}N(8(5@uorc|sZ&84*>)H+XC4cmR1DVMa!*C$1NP}w7_@wylpV|l}==_&P9#Ly_U<6^EcW@ynty@6s=MWE^Mwo_gB_x8U z!G2O#`Z z>-BEf5gL@i3+h2TpW-i!;5>;J^1Ov#LU#AWc#-?v1}*$v>&?^da2`19LjC{O&GP>M X^`kDBQ=~X^00000NkvXXu0mjfS$yg~ delta 1256 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 delta 1414 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 delta 2336 zcmV+*3E%eY533T8B!7TVOjJcja7@a3CD48z@1Y>cX9JM7>7~i|rG8}Vg9E~VImB)h z&2tcjtK7_Z9Qmdh%x(I<=T1>>xU1tQUvLO2$Z$qp`@aUpuXpj9`BhL$7u+e zx!|wH;LU6X@sJUozUJ?m9I;LZqla_U-rWBG|NqV~_51(%s(%yclMUgC3;g{3|HUuu znGw`=1>AoJ?DqfA<^138|FhKl#NGM*zc`_E8qTpY^sq0($SPZ-q*pnvZv#(EyIBo=)o_yaw43Jc>ni?|Dgr{`?3G~r2pwm|M+(Q{Ja1C-2c~2 zseL+SEdl?q2Y>(GT>6p&g-Zwi=57D%djHTq@!^#J{?m3m1pn<^|M->vy$b#7J^#lI z&Yn*H^=Q|)U*XGg|MN`$!#BH>Ia(nA{jnE}V>JK&=>Pr8Z8ix1{lxyXAHkkr|H(L$ zU=#noE&ujf|J4@%*+2i{G2P9W|J5)5$twQ2C-$Tf|9{&s@}CdRvxq7c8qoj%03~!% zPE!CnTKxX^{tf;jhMtpe;>)_$tGxZ;b1*}Tz~5K<>Cd&Z)y1O}F{GdX00%WmL_t(| zUZj%8P9s4OhIfX;U?DhQaWEH)r|C2~XU81KY4fXZRjolbncc6Yal3o!>%YtX^4}Qm zY&QtwAAjYV-a2U?5bcwet{I=LZyoQ<>TdUj=yvPb&T;D#7DLB+EWhh?l#vEhP64VRNQg_8 z5Y;U>ny)$O6QQ=K0xu$ZxB085OV2ou!&BOg?jX2`|w*+8BCC{T` zH9#9Gd#fTE%8C&Qkox@S=~ebZUIz(cG7}}}xJ=+s3?3EHfCR9aAn|t|9&Q`7UARV! zB<31uU@>4sZv}?+a$?4aD;_qD zCm}8Zq%6z+8Z&l>CNXdmtR_JT1OUd+wmWg=I1VaMQeI#8aXi$)@w8A9BygPVZZwWU ze&rx4P^whmc!?4mu&b1VjCr{6qv*S#KTcD}xpfpWQloOTEf`&o6tNbh>3FvJ-+zE+ z&c+vMdW(?bFP+E9h)}4Zm(uiNe712D1Mcysw7UCE+YF-sUIG|G6SbMLBvO;AYG=%c z!G3MWd>I0viFUP>s+E|yKq!>JBt!s-hL4bcedl>!J8nAfYDXj&j`{JN$2OUqbE9m} zs+S*Y<#M_9@v=Iz#e1u>YQZ~LaernXxiDD&&?KaN*-Yl@lni^=!ktLzj9WwdTNn9O z7!Jpsj(6~DZPA`i)%kk!MGN_>AVN(hlMmf$$4?c4FvNi|{jzHdoTzdl?kyuh#9A1O zZejLSWL6;IJH5VL*xte0?so_)2$R&8c*46Y;eg`?G~!GV}Dl*c&`^Y z7vf;Ky959M#3mR2CFb7U@$_ayW2`vxAf^|BkBB@hIkAE;0`b}10eV+Myc)31ivOA zkY|QF0Z>jLE4rdSL3ycVa({fEFa#k|E_+NF=o0`ztYVwiUjImlWgsA2rC&px1rhx| z2S6Y=N30^3(Y){R{d|U+2xFR@lF)`wqCN zR*Hp`bXhM|o)bNmm955T^qGV$32*oies&_l*lbdtADJv0jWh@^AS!SbsdxTY{XWbW z5!v?v_lZXp7~%eX-%@0m-DSeX^_&B9tRkI36Pca;p(w18rW)cQ{kh6bycC|QL`cN%Jhe88{rsN)13zw~Ujp5fmiBE=LYe`NRzq8O~y z%j2#J$o?5Vg9k3Nw20A2ya>v%#B`TXviPJpUv3J(HW%+1{IE=c zWt|2SXRd%YhAEY>4H#TVgV1%|6VT;dkP!O~HE;q&H-9YCM3r1_yCor`-I~nOIUv&~ zSnpy1#3>`fi*7ZVbfX|7XbnjM;RYAwD5%E~Htx5TjXQp`rE~lys9>rmA!}IClR&~U zbO>$~qjZ&rfk4PdN+$D1WKwi5h&YifLs47-+b};xU}!>!Ts4@esn8VCLGTqhikgh- zDiq9m6@P(&kZ^eT2|ck%MaPSwM{xF{l0o}sj9F&%!~4U-2!(*d_aETXrC_?jBwizU zjHrdHZ%7ilp2T)TJNt>3NFuQl+TA@c88b~OYMRl#*nbhR)4ix^F*6F{_}_QlyMu!$ z;iq1U;GFCo930V4&?m%Vd(nUi0!|b^!8tw-vKe3e-~0ovBz)@&D{(9U0000+bd$!`8v9tc!Hsw||k?s)FOgpGhGP;=Y)? zjB0pPJZwM_l56|p000tnQchCWIuM4dr~#L16ZU<_b?JWp|1Y~U z8KemM)xHRvP=Dv?J2MFX5tF;$?r%2w0Ga`qR@Y_U>xGx}&L zG6kD19;M8NOo#BkB14@nAAk&o%=ow~lTVkw5tggQLF-N*g0SJ>pM(XMfasP?IFTi$ zv)>3!1RNI`_%Ub@>8tz6ESU*}RuBamARP~offB2GK7VE_VG_Y;i(*Avd^*14!Qc!X zQ(#+lpp+^v!<*e)MISs#L^m7>l7W#R#^Az(Td548dOVI3Ci;XQ1Oo*?;WumyRMXUX z5+j5o1q&!Yq#s5QAmfIOg$@KB#Hb`tg#bXK2GU|IdWe;&tBkYwEtQZY0553fnjt6` zV5q&O41ZKZus~(;d=8KnMRXd&Ir&gmgKkHKt_FZeJ=dLAsiYu7H_VIB4BB8pf_S#< zmI6%#Jjk8Umz1}($w=iWjD_GhPKn+t#t;#VC%J9gNC6!VRhG8(mQ__XpU=}IK*X?z z;8>%?wl^rm_yB6;wv+|zCPL>}iWmu&)CTQ@K!55fOC)02Ltr%_4@p>)5VXO}NSAva zV@vu70SGct6ZW9>{sN-|gjuFQU^fx0F@X?>zi3Uc##f%)K`<~;Blg?vcHa>`x}+8( zVt4}qlR~CZ7AhBlO9))(j!)F0Tw^9qeybx3KqL;DD4ELT@+evs)|{4^%1X51#5bna zf`6+)8UkVsd{r$9&JnSd2MEV1hy{oUQ?SuREE(hh2+JzVvQ>vIo$Go8f0PI;Xm^dw zf(t_SPWF^M;6)1iK|Qg<3|88#gBVX)QX}9zRJmncOc2DfvMPgOt_cw*{rAN*NU{(c zVwdIlxZ72w1)(S+lodQYmZjYw1|7mno_`QxQ}A7??>;~C0vUBGR*{~}x6jWLFE)gT z^OtMJ#M#7g7TRDmsy@%~<=s)xbRrkxv`dfhw2Ia+F~UO}+s@<~5!xvsis<->+MSAG zO#nCx2EIV2vsoY_OH(_%MvQzrO*1T~h|cuoufm{GVo427h_6>uU?NqTI{xSy;eR=K zS|LJ@%H0kK->;^*Z89;VGd$gWeV36=h|KY>yE=Xevp0z-^(Z@ieSQDOKlFVwFZ2&_ zJbitC=cZmt#9J1=bh`TD`_(*jaFrE$`TCl3qo^AqL4_&u*Vj@MG%x0J-+y_!mg4*G znvV!*%641g%5Ek(T?=>$0Ey7veScr+ASRxt5u$nT?XR@PV@(Lh*EG+cbk_(V-o4QN zAy5pSL~Fga9PeH8JZMO#o`h)LdvyRr)3r81r9cE!vm*r%E@jf#uHTY1-?TY2@S&W0WrU^%^6LeHOi#1;b7H#-*ufPGs;7Io_}B^`kH7i z%nY(23t%1Ir94Q)YD^%4y3yCD$pj$VLN^SN9S2gh3D02!D@w;ladkbw~TuN#^QH2yUW(gYb;4~mhZ z0TL*U2N?t*Cp7>)5aDqKQ4l~Di0~kzhLFes5@2~fsL?Yr{17N40!z5hqo;>8P|yfa z00V-%2Nsk80UkC25X6vNS0f95gDB4$2sjw8AmHyBk0y$uJS)m%^sfo|KjtDuO80Vu Q=l}o!07*qoM6N<$f`#PzA^-pY delta 1475 zcmV;!1w8uW4Al#eB!7xfOjJcja7^&WqtKCS(UNQGyp`m$j`7K)+@*lzv5exfj^3w% z(v)uBsf761xcAny^w6#L)3Nf*s_nv`<+YLU$E5q>!}{F2+oOHzyqNpnz~QZk)|hfb zArN0YCH3|6m3LpPmw@Nr)gufDZBjq@>)OzdX#3{O*1)C6uz!`7WCFF3IOfyA`s&mH z0Rn2u&O87B01b3fPE!Eg>B$pKwu)>oq^!?hS?u!w00iwxL_t(|Ud`8OTk1Lx2k=v% zwCKs6uKU8eobUhj?#$R&l~(cH9nhzi=J))QF%?G-k8q zjG=+ZBLi?0#f-@A;RTpNPkS>3{cRS01{#}yrmd{l9U1} z1LUzXB-l4GHlE-dV~_y~Iv}A22Uvg;As1F7Oyx)bLJUHqMSqM0T&3q5`(h;t6XGOS zE(Bkg$>y&>f{(_8Orz;R1mDj00|^pF1s~I3a;Z3%a<(TsBRHoR%N36VpZ^c_Qz74D z@Q>Q0PJb!%91&_k0{>WV0BG)oQJ1qV2{fgkk{q=ux*Lcw86DVgk&tv9qwcx2q@q(? z3ZnQt@d5;tkSyk>^Z67L80Wz}aJkYu3%!T-l z5Fp5=|Myk{665ZOhVf+I2rQ{*iBt)px_cuo*Sb?k z6p6_{6TUGC5LStOeJabcuddg+o+eV)O@CQJvdgL73m|eJlHKQq0C7lwP`A2ntIOqj z?SRN8q8l!7wyo=%Qm~qbB>%hl^4@FUY^s$I^0+@;ujj7bM-vh4>#n^XPWz)&!oq3- z@$z-6=Rg>3g%FD4oshOVji%pmhWFNp3n-gn8GQp?_jaVZWE;-UOtReYLB z#9$|wG&Ol*I0;N*2qe}EAB2M<$$x=xF*2r$165(<6awc_EPYb)X(poqNUYL?h+OlS z1Q!CjF<+ZC%|rq5*4LOp0}ZH<$_W$#y0K6%E(RL#pf?vVw8FkjAr8UvCs$ffGGwfW z>O&2Nk)W(eXdcTk#1%Tt*QKol;4QlnsTcdUN?PIH(HLI{|I zL-^;%3f>J;2olN(*p26mJk=HzSJvW6J}Zy`y-hVLR#_UawaE(Fd|HVI8uMT6a)`3s^``5}Y3|^sv daQEH#{{UMxKP$h#zj{zQ&(6(nM=;08$jZvf z$;rvY#KdDiEN4P4Z$>hVT11LkL$<1<-Q3%VT11s$O1Oq&yo+Yz;^OJ)>8^HK*45SU z@$vWg__cvxvV2~#vax+pIiG1zy}rM~o`0sJp_O-N#;ca7ihp-lHXzZzv50G0Bnkw? zlxv}tkdcXnz>sK19SWy!RIrgxuYm*q|NkHZFKz$;026dlPE!CEqKf@5JpTUt#(-AV ztYOq_xmE&*Qvd)3ZAnByRCr#Mmx)&LFc5_W3P}M)|0Lb_ePKu6|JDAPgjOgZdO5Tb zo$uT`S*S0MHGdjSJB>y!f7WQa9M5&)GAWnL$BX6kFM#P{?pmJzbt#XL`Qo>f>6qA1 zek9BplDELpJkozOrJg?%q{QBSC#fa7K*`3%AJoMcz>`Nu>mnGKG%a>=7R8t@!i>k z6f8}x4q|ZjG<91ic(_r^@^k*%#t36l6%j_)P)2rjS#|+((A&9D;YYx z@7Y*b9+=eufe=?wF8bO-5TQew#SLQa*%&k0Ooe!VxzH`==n3ZDZ~}=4jY|`O zlf*TRp%udi`)AS1xW1*QQNz%&;_Fkk`^8^L3U z@kA@da1=vHeLxQoWA%)H?T}fpApk+CyG+qF;yEK0$r*wi1sD*XGh3t)Nm2C}f@6wb zYV}H`k)y<5y#l-f;kTN-X%wA^L`eVu7Uk^aFIq`R9CN7{0bt>88sRAh7^Uu%`a5Mc gc>_&Wv!52^e{VBE#1-58p8x;=07*qoM6N<$f>f;ux&QzG delta 1335 zcmV-71<3mI49W_SB!6a5OjJcja7@dUY{ZITz=K-HjAO}>Xv~*x)1!OMm29+eN8GWC z+O3A(wT|DplGmt#!Gl@Ropi^HV&lS|;k}pX(X;8|*dVQ5C-7mRYLpXeF5_RFFD<6!}6bcMLNFj(`U_#VNvie-8DRH40h@@t3`=xgi1#K#ycAMA5m0s!bYUdqa8EK%M2gye07DZIpb)|9<7yfs1tH&sr??4*XU7E9 z0*!q^$lB$U$caD&ul=?V1UB77!j&fk8UhTZA-D#u^nPyz5-Ep7@mK}Sl8i|m6F_ry z)Hntp0)IxDa{>_MmSOJZd0-I;0(4}<41>es$T%lJ5KBktmk{-q7+{pLNP`zYCKwu~ z>$`3qApSupAUuxD0CyljjtQR#u?&`}2nidZ(lT&FF*_{sZ-h$^qGQDRq3~Plx2p3GV#p8Qg8A;SK?!Y4w9pZPVl6ty`uB2*yY6-Uv>FY^UXh zM1ME8Ev*96w*3u>*-ov*Rg9MVS0dxwUVt#7okHK=ZrzuiCJmn9p&Rz{gt00kttrVku?6bS~;QJ)Ys6p09>3DLqh zJa2jvRN7KIRtTIv2{V#56)tI*bDVP~A8l>hkNlL#QbEaxZ0`1PQ7JlC^c-g?=xES7 zmVTE3N47&T7JtrDKlc?PcgBJv&woY0hMuPcgBe1k-~+TTXl?_iw*??DZ%3@edFqNP zx*19^&Y92(Nr3{lyK{M3Q8WzA0SGHV015aQKcsvbsK^w=P%tQb@bN6)8B|1qXbpHI zJ~W&`ghGIE9}8r7#|(z%LzwfQ3seu!3865@J=NjU)CD1qF$0$)p!nVA_As&n1e6qS t0jSD9zfD$v@<^3u|NZL+$PZsV`~$$Tmuldn5#j&<002ovPDHLkV1mAVS!w_P diff --git a/TMessagesProj/src/main/assets/emoji/0_472.png b/TMessagesProj/src/main/assets/emoji/0_472.png index 2d2b344c48fe04bd1194b55e10e49d5f15219fd8..b7b83c25ee96d91c95bc678697ca1f358819dcb2 100644 GIT binary patch delta 1548 zcmV+n2J`v53#AN@EPqlh8_Ubf#>K_U%gevNzmR-$(a_ILD;ZcZ9#=6QRWBS+EgQ+n z$;8COVKp6zQ!#{3FX7?f+1S`~K_FMcOGa!#xG<``cW;!C3T{rXe^nYPd zsefIfoS8)(3$&SnmVexRsBLo_}XPYD_(`gbQ@r5d;7L z01$LiPE!Dkz@q#w75@G}X4kQQRx6$*77+jd1v*JYK~#8Nm6nNivPuwyBcj8v(ag%e zudeU^dbfLqMMS+x!NFw0e5vY2PJg}EcDot0-G2R9+s$!p*+g)Z5X7<$$IV|jn}bEX zq@5|@#5!z#3x8No`{xvoSjX+}0PR~P!aDvR;b?2X2MAezHgXVSgv6ZY0KvsDxV8C6 zFuPyL!_z|;SMS3dN%9ErhT~aWz4NiLIof@>$>Wa_*7l7DPY`gr+-?BkQR~+pl2)7* zA3X3mfD2?0K?s4XuwO-4LkMy1&II@J@t9HwM1X7?E`P6VYzRaEMAs=IkTPiwu?^#e zjf0nP@YjLP$`%|cv${?`Y|S_<5LV)0(yq!80u%z6rIC@bY|2J>oY;Wy{n|hbWx`B- z(G0P8HjdmAuuk&Gas2cG41^E?VMggRSPg}LBF9B3I8lJ8q>OyWzokPUxK{|%QM1`p z3+T_qSbuxmhGkWUjDEx&6`wAc$R|39|tZcz>Yu$G|~GrL>DBf{-o+6Cn4RWf>4A zx&2ZAqAciaEawu@n+US9A%Y8)A)^PmnSv$Klo`07VWsRP;sA&W!l4^G17L^a00b9A)JmN8|&KN;irG9a1N;)9cKTm{xtuI*g>B(f>v#Hs;kqf2zlm?F@G}d7x@iV%eJDF%CzfJxtk*-%>lszs@n7f z0t9KslEw`w^lEfX6b%rO(`Q5!UVzJJEZW-Kd>3MJA-JOvG)qLRU0lLwj`$bJN+Vp} zHbqeYAxpgLD6g$yvAExxmb)5J%jn;{r+b;^hzLsFmXh7?cixH#AzB`U^nNcBUVlQ< zWO_;Eemh5eNAh+1Cf6cXuqQa3O#b?vaP}dj; zgWzG+i*69ah;WK1T0J3lQRFyLNX>gQc4Gj{?kyMiT~srI_mn z5SWBMAec@@L&;2#DF+~az83no+B=bM>rjk11SrUNLU(dO86fs6ti)0)lLQ#305aU1 z0_5DVu<>J#KE={UpCrKjSwpxd&X=mXbcA!#WB?gVIHQL}R|Xq2Q)XJ$Lw|*toD-D= zg9+V@_emH9g217BlA(zV38BgHAqm)^vFfL_rwK>Jlri}}2kP7Lp&HEXV3xtDWKy1Y zuoyFK0>5CNZ7`PNG$WnUC`ZCVngU^IVp$E%2*EL>vM_)`;!t4bi)gIG$EN6EDZmRP zk0gs@+K*4+(2kE$kO2@7{(o1^V&?aLkb@YXwd)zo?9pNm1ZQUepUZ*unDz~yn8Fm| zFAPl?K%x9K0ka@OVuC@TwxCn|lCd8lM(6-6?1AuG{d_wJfre_CN!a=R`TC1?2pI-w yUjx9x-?YWI*dTmMZ4vNy%5L=yTJ1jW{|~ej5XCCN=Ar-q002ovP6b4+LSTY`G}I9Q delta 1441 zcmV;S1z!5447&@EEPthSRH=Jcs(M$CVn=aGG<8ikZbvd?Kr5AIN^3+gXhScJZ&|5( zR)<eO|42T8Uaid{H~dmu;YIQO=%o#FJ~Na#ogPOIkQ0 zNF@>F-`Dr}_{6G}&%UrT84Du{1k|H>ql$O6oP@BEPlizgr+;_?*QkERody4^!O8#t z01tFhPE!DLw%J3AY5n{m%&Ph9tJ-V=lmGw((Md!>RCr#^*x7dCI1mQl7;J0RW8uhYLyl9IB_EHV=mvXZdXG7(8m z2?4?)&kDFGl!VG)v50qOi4u`wE}13Bax0PIlv=^3cz=Z86$+MEDkI%X?yGRU+?e$g=uVRfrK}FDbGr2iKT=6sJJH(L1uzLv~Fn$&ed!u>4$Q}gm`KCc_-LveiQ-; zN_-~32Vev&A!g4ctUWQsZE~9twX!And%8GHPf!TCbHA~!kvyCua#w|qL+%`+{ud

    E5JGrK5(Hhh_n5Y6nt!(88tOrm!m%8Vqq58qUXwud0?&z5 zlvKkpG%(Z@qy{3w|AvQI97ih%M{6}j>{L2pry~MzEGjkdagu99D;z@tgD7^C#iA2X zS!^iC6v{ywQH2yh!E^HF`g%H9P85j7S7o}KOs}su93`8mUStZYArVR^tL1XpT3|er zaDO0Nu9gd#(?V}5a$=#Pwt!0#5e%rn&kBXaHZlc;YlV;2F)CzP5dl^Nqk}+8p`pCz z{uTbXA6PCZYBCk)b45V|vxstMUXf`WMT$2(P*7zyeta0um5NVCoXs9*<2glzErmX3 zXPj$eFUAi~)6sN17kz~?etgQVp2l;I@_%+;lTu*{-s?+*dl+Y@|BOb9aiEybR!`Z{ z>R~K{qNRNet0XCT6M=BE@oF?0t?aSiiO%eC1S~Rj z&K^+NugqXB`cvsDbUMFECMc*vJlnJU(M0A8&o)#A=fc#5vkzf>5lmgBPE!oM5tWz9h8S>mJ;xY{?o4M zrf~TooXb;a2KTJc1dZn{HHkKMio8gn!Bk8dwrU(qXKk`E)AyX@EpjWR8iXy$aJPT^-%V2o1XwWTSML>Mj`BawTdh{#WWZ7ON4}VeEjY?2a(BJE`|}A% z;LX0y?+1-sB7YR;`o%=9*SqWW(2;EgWY6y#-N67Yk+~ETy*>9J$xbE{5Zn#A46r1^ zGs))~NT6syCcxcY4+KLWkbmUzVL9X)1Ek^8YcvM%1H>~!89_;|_;w$2czV0LmoVeA zV9O|j0Z`3g?!~dWt`=PiHzXrxHpY1U5`cPdA*(qxT3us!ia3)y$0#q>S zuUAs+mhn&Du-?M!nIN7C0>#Ip*INPSvP&XcSoN3q!F8rA7hkVq3ym7Khh^q?MF8L# tP+h&8fAyArJUl%7h#ZCxoUq;Z^Isk>ra1X7q7MK7002ovPDHLkV1iZ6A3Oj6 diff --git a/TMessagesProj/src/main/assets/emoji/0_1252.png b/TMessagesProj/src/main/assets/emoji/0_1252.png index fca6cf7fb93e6df11e8d2974b5cb5067fec78384..5247013e27be3e7d01eb925ea95c9d0c49f91716 100644 GIT binary patch delta 1718 zcmV;n21)tl3&stQB!BQwOjJcja7*J}4m` ziBmC}V>@tgaBogLWo2Y;Kqf(Msf152f=w>xw{-x*1jE2Qq=!o%U=jY>j*X_*9p{$Op z5t37k000GENklNH!U;~iGVR?j3$|+)}?oL+?Q-K|Nr02z10iK zfcANO&=1z@sasub2xulTjJqiJRO^Q z?+XvYL-L~var{D9OZT3pCbR>XRFeWG*9gi=7@PAa25f$1}@6eF~%u{J=fMYI@` zA?m-QqAXTEb2?dZcM_BJTbNuhBR@_`I`5j|P+}V$6oIz9WC{f3-C}y-xj3GP=8F2~(gjD-;j9)&0 z=QvC6Z2#NN63uodbYe0hW-hM&BA10Rw}Vb$v%XTfjX&_^{cd^+?&(L~E8uxMmTFpY?vs)0Nu+`?#`omYhG z4e*yKALiakmW8q^vbm9B5H5_RRRX<3$3PrH`mMrfXJJ)@(v24RAik~#;SC7EU2uG) zoI$7TktxY5WP`{DapYQ{Gw4#sfqw!_N$r5qcgr4Fq(HX3_`JUl&N?NKpPxgdQ@kR+C zsO)_Gdfgz3?R7F#3zcO_q683CfPiGkGn5I&4`z-na5KMBI1(9|ajEQgr>k%l7Sty0zoNYZ3_YjDH zYN-Uv1+5tmeE`bbU*Fv9&427&>F$^&5{_2(EF{xFh;X)7tiHF|gUn`JpKc|(K*WYR zEW|l#LbT>GL*c&4&-?4V)yM5EOawIy#nVtA5G;`)VAuXEbH9^t4^4~)B|OYHfnbSQ z4m`^(Fz>gYNJ%gi0^!&aPk>wex`p7!c4A-xAPf?UIS!Oi*{s~a?SDqz?fMsr^K=MT zN`t^;mOTUh-2SPugK$h7<35Cv8U>hTz5%-)^BU2zZ*50&skpYnYy#Ow z$IFEG9q$ikT!0}JJ};G(P&IgwaKB%_|A=YkX@7ig^DfVucW*ZH9|PsMwM@R09smFU M07*qoM6N<$f`>mCWdHyG delta 1491 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 delta 1347 zcmV-J1-$z03*HKlEPq)(EmlA?MlK_0X>emsK3+vPTZ+hDS6f&Vz1Ja4l#W1to=QH)kIhEOnnOf5+%8CNkKV>u&kKqq%cERtI`G#n8e5)V8rCNLx( zK5wv>U^$y(JVi7tSw%ZwOhQC=x=cDUO@G2@Q%NmVitXy>pnr8$-O|a%v7NA%g`$Xf zA1OH_KW3k2K5$!7SBJ(@KQ=jNrZZoe)5E#`|NdQ!$;+~Mp~85s0000IbW%=J0J2-< z6F%bYC4=r!r{>YucA-d(EJ6SP1V>3kK~#8N<(6l6>NpUFmttQW2;r(0S86Zmi3|w6(jCxH8?GOVX0lY{wUah9Xpdn#~@n=o3kzoANZj=Rhpcv8%USHG+ znh+K*vx~UJVlnYr3~TGr3s;k5;t31*K)ffUq)AkVh<|3YNs?p}iuOVV5wa{x(@w9> z#B>1&fTTp2erDn!wKm$*1pOQf8p)V)ViZAQWTFImU%G0QxGGVL|H< zm83<%@L$8jkfL+8MpZidi606-xGP)c#@fCrvLZ7sT(h+xcW zqthfS06>^Yk||>h*if~IVVWt(BSEDC0VFq}?PeXfw5U~TrJ3f;S*GGZKUuAROE7 zHt)O5p*RunezQ3+a-l035zi8EvEA&BPw~^4G2ZNtv-t3F;DivpDg@5peE+d}IwtXc zH!cZ>jXFLha~>~{+8i~Zhl8%xuw-kn+kf)xc9?s5C*6B%#e9tMnYE0vC_x0aU5GKU)jBJrZ0 zc6#9);|35lTT20gmuDTLT|pO$5JF1@)vQvWq%?#e1``fCP7FHjR!LR&Ac;Cu3|A1t zDl3FB4hi6baX>V9oOMo_KoplKT_D1jB7bV|s?t(MoPYVO0s=dm5LyLI-VLPoHc-wV zTW>-Q(L{YF-UdM&j0oY#gv46bD?%H@a6(ZnxF;BePqL;qh#}}N6NVGPYSnJ~t|f_q z;sQiN&aF{&IvS@UI41%=9C6e<4N|wIw83b?Fpd}t1YFSO49LY2gd~L3M7V|#Nq?mg zBB&bHXf?c!K!*h(##n3VJpq4nuVzRom6w#QYXRM0^t%(su`C6n^!KRW+(&OTxLvQ; z_xJG^-9O~7w}VlyNgewT|F*`@!+mxFWcLrR^E^jNt(Rc%R%#9H0U#&9nIea%mHPs%?D&!put&+mS$ z#~{yfDnYz10mPW+qn}LN;ar@8%Bhi-p74h{Wc*~K4}{bAlnpx)0kEN9!o2@O9zZB( zJo`u=UlKfkAj`q`o9Ye-gg^*I`sfP+GQQ8GKVN#E#PITfOWl0CzeaO3>pWvG2-waJ zD3kv8dH72H+q^H~8Q`ls`gTcge*L;3{i=|k@cdcNe*p4q5%Wg0h-m--002ovPDHLk FV1m*MTT}o5 diff --git a/TMessagesProj/src/main/assets/emoji/0_1254.png b/TMessagesProj/src/main/assets/emoji/0_1254.png index 46843973140f7a3e12dc75ef91bbca49e6c60c9b..c5fdfcad2e00e2bc9edecafd41173745e7b382ce 100644 GIT binary patch delta 2008 zcmV;}2PgQw3g!=xB!9Y4OjJcja7_HjGxx(W`NJ*DpG*G9F8<0e^Sv+j#6b4SRsP8? z|I9N=2VMQkH%Sd%{mCv)1Y$!3SFCeFeFl?v1&nG0eue>-Tmx_GwJYD|( zs~oR#4X0@e_`oH%c@MsV6WE&;|I9Gpq8OfJ5t&*C?y?^L(0@Gs$12c~6VI9=k5mX& zDj$hV2zx>Va5)NtM+E)uzx~x;`{kwo)Jpo+cr*n*`reQ~1x_OYF8=n?CJ+Hj0$phP zLSp~`026dlPE!EWzT*`~F8=-ge`c4fN|(>%{D*J0WdHyM$Vo&&RCr#L)z@+w%NhmX zErIBfRFtZG)qgon%z>m}@ArSLv$_qI2TMNMi%Z~R{eL&`&u3Y0HV?O}`;cUH`?y*E z^B;q^C-=ct>`J({c6q zMd9`+`287JATRssY5f)9X8+P^@v=j%5fs_3ztCa7JAd%b-D4Lq*T(JtHMV<9-443F z$8lUUyRR6J$HVvCi|9Hf;-P{$L+>ZE{j0D^UUq>f=E6~u-0x3d5Gc`!#_{2A1Qrp> z3O$ZFF9{GRznGvL4!CBIe;K1XKzP{;)lI>mXp(?AJCO;a+^j!8&r^Iw;#HB)V*vvQ zxiFWhP=90l`7TcY?i13eLhE_zIE^6)6a)%_FW%;}68NNh2$bvGDm_dEB~%Jgo9HCx zHV~5SCnZwwNkWKpx#HaFL8rB#qBW)z5=cxELXx|WkD~%mqcm2*8{cr1r>W;4>Qaa} z(XXT**4Tu12chJ-@|l#rQKX_nZcWVuY9Ndd#(!9_KHSCwh>%z!6EtOLP^D^`Xlev% zls^#=VCs+V*NRYLAV^y%kKSo2+qSA?J_-=@5n=6@9AlBnaLO7^7`l3_)8`rP7Kt<>PE=m5{*5ps;%T=cOQ0O3L^! z+J8pnh(ZlG6>}M8%KN?zM+~HlFEp#`h2GUP!zs9VRNS^SK?BqfSVrBpY08x4b!xg% zwXzHbYTW%nNS}E%kJ@>Oc`8EN>PUEkaWIJCUIMb+)X$2CBmeVEo{VpJK2Evf5GV$q zEj?C(9ILcW)3o6@qS80E>!(6%mzCz`ihsCa9zs8A>zM&Tk2P*Y3AveEO@k0@cVGSoN<8wrU$g>LJ1&LVwuRrI5)u>v&I#3*C{XS?bSA$B7YLT zB&Mzn3Cl$G`%4Wx%2r4zJlFG36i%Ak1+iro#5i@>G^t@wAu0$+BqAa`N=OhR2%WLz zPw1^w#V|yIv@JD;2~N=Boq(IQnbR`kc_4DmR-483&UDdXlG&F=*c|Dm_Cj1Hu~=iq zGG0s|3MI+!#Aem#qUh#nY9y;`;eU#*>s(d+PSi%_t*Jo_fzaA7PIW`M)_Kv5laRqh=Sg7txMtaO(_Cn!)HQ({+i-4+NoOSpj7}(b>4iX;3x9KznVsh@ zx6WBxJ}wFGgQ4a*E)+3T%suM2G*=M7RmEe4SxKpH!QLy6lkLQMnv zMfjFs6S;yA0Pp4YcY>86(SJ~b3Zo$H*#G!3rqMuHBPG`X@IH<$Z`M}?f+C*l&ix!k z_dgI`MT3Y|xkgz4**Vw5!f04DXj@GEfQ=^KrvCNy`MHAtK>mD`OX9sohLuLcm>Qq$ z6iL3lzP|n&h~A-tyo4Y5Nx0lK=m=n2c>EmdbvN z;*~X9v6HYcA|ZeUfZ;Rk!vC90P{>u=Za2d@vT!&Z9%S?L3G#hBF~U2v7E+GGX1i@~ zFaCOVyIy1?Pt4iBkE1}Q;0X~S2YqjvOY0lc^J3>55zXOz;D2|Jza`_yjL9z-5lS52 zXu1mqQC1T!;pX}DTFzkJ{!bI56T&8qg;7jYA_mbIicpjyD5^#YmP$Kmf>0SMp%6i6 q8?}Z>bJS&`&Y=jNq}G6}(KkO+*QRJPG(JcG0000eA>j8I5OU5v@8p`WXjjJFTKTL1t67Iach zQvgKdS}b6J?fw>>v+Lrk;@8yfiSFD0+oW#*00bpTL_t(|UgekRQtLPnM&rab#JLFs z813Gd>^pFm_kVw|>6T=inM!Okf9I&m#8v9Ur>o}h0IgUI2PXgBq=EH?y zIG^~=cQsD1Sp2+Zv6%brcM?qAo8rbY40I>;q#=DaE_mIiBZ~6BU|6(WD47y`Ll`tW|+baw{l5FC z(AxozYX!bzLqYM}e!xAWP+@UA7EO+D3-6Iag@1_K?}#&`s8B^!R#kbb9b0(6l<=-o z$e?u{ID@F7tWE_l%46-QE~iNTDNjVPG?p)Jr-J-0i{hB3pViicIF{s8r01%PP{CT8 z;Yks5LM|nNE5(mxp&jAnk^<+?vLGyu<-GNdyl_+;s|XYypOtOJsXBx4pU)p3MO5!=q2D8=h!mW694#&cQ=z^iKx8FmJ$P?rDtO1y5<-}>1riu| zzRVf3SD&Y%<7hcN1qH@HBE>?uu>@_ARxpu@V9<^~#b($T5#y3EDMOnATk+Q8>uf66 zR}9!&0egWNYK1=@bTSdr#6TGKMuE&27=M3r2Hkjqn;5oE?~dsNk*1g3E5R5lG?Eaw z3L*SKAAA!7ff~D#5DijHAw=I81amM+6hI_F1BUQW(61ZlKnMej2SZE-eF?M!Bt*lA zHB8+>ZzkFS*Z{;BoI!ua=rEF6z^$RbBM=ybG4q8g!2k#QoA_@a;Zno75cqfd+kcK! zARLAe>E!$WMvQ`K9H)581U%#TEf~4|bGW0~Ux)Q!Pva}{{p#^)Hgfy)5$e|nIPz=5 z<7Tzemd*q-TW=*g3C;J1)doS!tUbx-QL|n@TGL^_-yaTZ6eLNqNzn2%YB#Jj+GBM1 zxPu6woYT)b%=pHJ~J!-C0Ls=I9`HSQ>$K z{21R}NAhK`#f{I!;GH zLQ5@8J2p2fCnrP#R#*aSX#{?G1de?Nly3!uhX9vk19(>gYxUEz@5`y~#GnZY3N$b< zBp@K>y_y>t8T#D3&#sXB<;Uc)jM0*86A}_SI5^#+dn_m@ynljSLqI@_T|=96U#^aK zZcsj2Sy)X=OU9vqW@Tk31Tj-JC;aWuI|WN^ZEbZ(VRAYe;u>r=0000HbW%=J0IJF7 zUwr5O8av~d@Ym(u=p^ucTL1tB=Sf6CRCr#L*4J{|SP%rzB?~Nzl=OUKK+b_lw*UXj zw&wyc0Z8;}n|~^l9)MFlbD{9h^Sm5`!;bQL2#zmLZ+rguVYfdGz0WWVr~TphKZV`U zUoJm=E);V1!S{jV?mfHwoQc^1vit5h!AZ*uz&gIk>3c;ELvN+-L2TlS1m6-aeJW+u zUr=P@&_)jbJ;i{=R!UvqQk7+G$)L3Df}vDTM>$kOMait}5*RuQn=Dg3b3duf%n%nmD>2npsV$SF zOzQUT`hP6zxoa~@MIXYlXEhEPLWq{PB*_!RMXk;{?!qct1miuavCotzGMhGe9-BB$ z_?;_RaVG|~B$Uc_UkS%IrF@A3B_KF1ViQHlO&P~7zTkqWj$fTh%ECB&wM<0>9Y>wVf(sTgZd}An0FEq#s*tE+okHd2tipViI zj>jOvy3l=iCWa7Fg3oiPf?D{~XzIG|8V-X;r~yLMw_8X@3drg9@F$V*2r?YSi!7~szH*qZ` zO|n_W%bT4E!64it17OZ%a1abcnR;XMW`7(N1R};c?o?wb5CXzs5D-?v&}zNUpm-4I zfJ7qN8iLWqw?GfAUe^bry+AKF4?{+VVF2!rWiSxDZ9p_sLfT?|B(GLNrbCUHX}YfO zhg;~MUl`}Et3z&bS|^ZVzdln70nvUC7q&>a9)$68$T3Ka7sE%dPj!d!5Sf-(=YM^S z;qxRg{34@>aSN*MKZ1ti9)_K zc+5SKcYd4cXTnlo)Z>dmF=zK6unOkqD7Bm_ZwNaXvd9G^0}5;7MGJ9uQ;E6p+lHWM z7>gQFSn@@SkpC%RQwu{KH-z@F(tnl$hCd75w(MbqhDzK>KtL30LQk<)-u{fj&UMLV zfyE(8G$Y`VB3Kc{7#OMS;?Xe8@7t|$e~u&+qSRhMTVzWtjI=RixU&9z)AM_dA=-1U zY<~Uv@$vDIr6f>W|Jf31GQdmS!eD5^&wpj&F!UgehuGKv4La*O4}Yb5cxrK37)&-nh zSQtbUO&%K{EWB<}b%35zzl955v}Zo+o4SdM17# zA0EiOvH3$1>`re8F~!GqfPWCj6I1?Mclo!r3PWM|+ICI67Ta@9l1+xAbZju({>c!( z|2Ny4#9y)7V-dQo*6*zf6wU9EsqerVdZZE%WFzPu6aH4|T?3kxk$FcHf`f(XvLcI&j(~!L?6V%IsjKO@IC*+} zm6eowdwuV@FZs(3Bi zvKr8l6!W(nq-6)dfe*!s6#e3q)tef&b_(dK6YH)Q`oJUaxhnU(AN|HF|H>?@Z3_C> zd7fScc0B|A=zpr+p&9zoVwYG1_rEIr@WJ=RLifTq|I$P(7!OM;6#mXR;;JU(r4Rn} z%&(ktxVgO4txpaH1pfEd|NZO4x0sP+9)w5(%dc*&dM%50O=(#)j!*^v(<@qBU)|EV zYutg10000lbW%=J073oz{3-qq{{8&>L~MClT4r2ZIp6$L~3pEtz)V;V+1qA_jMO$i)%0hA#QOtI$@f%NR%lveg=uPHsaaW-!NFBFzY)>8o`xKmi9J zkbgo8h%cM7y_tQDA!;?RqKm?hrl8g>%W4_Ggc8FbV4ia8^T@=#VwYZ}tBFDrdbo9i z#ctWH7cqeg)=|o2zB@cfK zDU(16vkPfqO%Yv}lsiM)UOVf<35I$4_3QfR2Bt^ zoz1e57d>%(1si7H;sWvEG^J5lAsrxKmxhIP0^8~IoB-Jfb65g&j~G|y=jZH1B)=)v zTf<%uFd%?XiWM^IM5ZyOu*0xKcz>>mBD3D#t78M%u!~TzSruf_vBVCT1y*61*-Yj* z{_Fq4C)ko;6_3ggh)sTC$$fkjq?R2#BtXn(v)RXZLQpm9emZ^XKR+lxw}SG(e!0C9 z;fY5G4EiveJ*0MG301O$+uP^%VDTi=Z3l1q-0m-){`^2J_Tm|aIh$oh)_-0sA&$x2 z>S;0PFYeO~v?fq@Ip_}-eSb3jp|uQH6`Df{OyegZm^6S`Ec&E2aW;g!+J#>R!w$e9&(24RBEf`oamKh+kc^T$)XmT^HYjbn4ZS&LZb-v(v$XbDLYUiI9Vi5RulNN zBSh<}2F8@1TNvxO5I2dSVZ%lU9xMPr2nev?K|_cU0x_t`Pc4e|l#cgfhRTLV$8xqDB`(-Fl$u%vQPfMcaTREhq(230WCv=Fo{Osdsty*tM^AVy#mBF4^X zE+B#$n;42H61oPE10{srYE`nS9+uEFy|5qdWB&_c#QSPhq}v)l4PCRGFn^U*cdd!GZRbd#%zwrFff+DS6Rk1EC~AxuQ8vo7vG!&zA_e{b-)Fsh;|Jrq@*;Uy z+jr+p?D#p7_Cy2%`FOg&TQ2YJpUQpwKtz)_%uOyF=(=+fpF4!l#QkXVylJwsgdi#a zphSy>o5Toj(KdPJxOk&oAm4H+Z=}4qu?}-iPHEmC#o~fn#ea#K6AXsqkWq4?fDz&- zmtSR$9~$N;Z z;k~;j9umeDsBs>MCijvg*D@$5_H zR?{@gZqdwpEh88s5)ttzmWQQjTg{XY{vilh5P$)N=K}+=B}B8^Fsxr^CyDxHyxkdw zVO>+kn6p^aj0KF-eP*W`aP#@Ut5IP!yAmb+{Ig7rbylh_jtmt7gL>J)# ci2vro|FgSB7S*>V`~Uy|07*qoM6N<$f_hn!4*&oF diff --git a/TMessagesProj/src/main/assets/emoji/0_1256.png b/TMessagesProj/src/main/assets/emoji/0_1256.png index d2afbc6d04c37e95c437a3a434cbd1a6cf0e9669..535c8712d51485aea6e2486d029a98ebd5ec3710 100644 GIT binary patch delta 2018 zcmV<82OaqQ5bqC=BYyzfP)t-sM{rE!)t=0>aOBvY>)op1)0yMdobBDT=-Q?2-ML2w zS>4WyN)lU85Mf6MSyTmQ%e90;1XX%UXrg(3c?FMt2b5_9eTD&+as`K618<66G^d6` z-@caKwvW}PecG>wv6D*W*p|?pbKA>+xtvkczjd8@JIa!0XdfHF-k zLeBvM6@PFr+EFzYU!SpsKF?<9d1MHwHg3*MLBTw%zAm9}FcS&{8hI4iww=58HYz*Q zoPJefV(#F>G$V(4XJv>S2v=IJtr28Qa~GMbuS!Habzkn#s;bVzrD8I+?NW$1w-LF= zj=tFF3QDWOso_;wmQ`oMnU&;;fEu|SDMU|Ze}7(MJ%?|h5G6*H6_D&K0^u1H2wg*c zf{^FY{IhM$qFfWPL9@d5xm8qsz{7zEjzpxR4cq+ed@XD@N5OUs5G;!`zw3g)A1*!@ zDGIk9y2j$OWxB2^krmN17`W0 zi=u_E{+SSu8c7<*(D?D0%_5I6@CEe|XpFboM%NFZ9v zFDeqkN*pJit{+Z!Vt}CL(1ZmQJ`fTwUr1pU=fU%+Q>M}EVVjN@VvEX0VprobA%8n< z=!mxFQux&ndY+f04<}>h8X*#T6~PW_h~Q>0rdvo0AGWkIf&?w|F|kT%=-mhj#IA0A z_RvE5KnQ6SitrM5GA0raXfQJ0>aO(;YIIVyxD!&!qOH5;PK1U#KA#f@2rx+HTb4TB za%!Ae2xzRdGKO>$$6PH#{^r6lohWi25J+am?${Py+rs z_+md0IYt|JI@CTm7kv|+j;{bH<@E#v*3Df=G$s_F3|)hSJrt2Z41e#hK-_C2DC9cP zYE0-q*mr}fKL?hu`sVVA#LK+~5CFj4BLcDjLK`_64mn=%AD!Os8uGCP)Nt`uMT}qJ zGk|aZ1LbaN9FM1>$RJg9CdXH8yuAGU`SNx`Lf<=Ij$h%6=jRBLx7XA0?LG4gzd!|u zf7>jho>qY%3TskhgMXBkc4l_=1tTvcKB&3Td+$@V88H0+U*yRwg%vK z0!J^(fau_#_veSZTNtjnU#-@=!`@K3{ogcA-GDbZe4kMRCuo1zt=B8eFUgCn^t63@ zsuRg^Y)w@8j98iFzY9uC#~4MVYfnvGS5*ZG94Ct+N}M2$W`CA#7KUQm`?La5Z2sL} zi>k&C!O{9S#UQ4Lz1l2Ep7qhk$zd``KL36o2;K~oyNW>?A+fT!Fl@F_hH=FK0cG0u z`{;D$O_WE62qXw{VQ_)pGa+cSHqp&vFdTv)qa%lbW-tebR8@K?W-)Yd3|+Dag)S5m z(Yi$pID8=+uUp}J7-3wdK$8KDQVf}5uu5`xl|lvuj}j2393+;up-Piuis73Wd$4;r z5Dw!cpqR&Cq7=ijSq~l_FkB!#6c*uF#;`K~0bpkBCQpw84FCWD07*qoM6N<$f^nR& AvH$=8 delta 2160 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_126.png b/TMessagesProj/src/main/assets/emoji/0_126.png index d002758843169b976081277e08392a0f92d228e7..dbad8f10e12b3112f00761abb1d452742bef3f6a 100644 GIT binary patch delta 1592 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 X+?V==Blf!={>3KHoPQnv%r5`XI`F$G=6|I{ZJ zqW|ZPTs;(_j#p@CY16Mm|L(7MY*To7d70HvO8@`>8+1}mQvi7BMCbh^5dP;{F|u#p zkD%Sl#+=jV{(sTu#d_vdssI25$4Nv%RCr#L*6D8JHWUTm2!?DxP;F!qK*9XKm;0u5 zv7K$&zW*cjQj#<6pi(j?i2?-S=R=Voc(1=Rg0I=Zia@cE3>}cQ4bxUy$_l)h34rIe!Vi8ZYPin0>9o39iroN08yt zT%ON><0MbxGXie06?o1FIy(QREaF`4N#H*4N@lpF~ZA zHOQ(Z%YR@&-?yaMdWkAFt$ZlUF@T`VgM}BKvOK*I`6`juBt)WnEqOrZed>jvr&8WC z#{4a-Z{u*RV`I;PwPo4s00_W5Qvd~c2GL-%v^JA{I?b0c>@_dT&Wu_x#TZv!2gVQ> z1tug}Au=BY&j5@DZ3(ee6#_Gb2n7)#8UV4)<9`Z~L?8-UYXH=3SE?Gg?gxPy7;0P$ zU=J(HdJ=w~Y~N`HszPmtx;92b5gDH71P?N~EaG+c_pC|MC9L@)tiG`7?e z@qe^JB%b`yGC$a^>&lX9m_bU2Er9;gRP|8KHS)DZWdPWZwJ9wxlrr2^+(=0eAv`Z) z8D-0n1YBFxonkPyAe5?8DbvC@Sv0AvibxDfr9u=#XAuyS6=HwSf(guv_^(7X%2iF_ zWU49}%m+_Up}P?<>{f_F&Zq?Q-V4O2pU({dl*Q$Dl_d<{GI>3rR=N)lGy@ihejS-G-2@6JBee@kSY`u2ZVvZUh-qc*9s|wc4!`8Dc=M`pz0|%7%n^i2o$KwSOLv z>y0CPr-)!e3=QqgvXcwpX2N^m%0tljuyKOlN5aQ>h$?Lg=ORHfSqL}jEIO7jU;0sqQG>MG9u=^xjhpqP zy0qJugS_oD!i^|89*qxzd%*TH;;FUEOk!A57G$_(e;UppbX}ip5&NgM?=`}WpaF`E zg%}J#+u8AP`=WFjTON?H2zX!E*Vmzzlt_do=+2rv`Rv}id(sFj#t*MC>3@x2W*omi zExTg7Np?RQ9)~bCovBHvS7vNp77#_8;HkEaq{&;(P`|H~ucVA6bAVvdF zkER>yA8&t8d4K=9vAaivNQBYY=I#CcMtnPb-FOOw00hmOe=4ch)&^lH48S7@Iz$km zD-x5FOIHRup@Z4tCu=eP|9>a#oK(__rL3=@Ae_h7L`-ZT{$C@`i==B1*%D!`MdGCz zX;w^a+a9{U*&)#-_N5wen&r$+INtZ)U56iQyAMRD@pQgm_#k`i8%p1IE&Yh?*#N@@ z=Vq0qPx>?L3IO)Fqtv@K8G9nE({kfeZ8Xc%#{k1=jWGsmthY$iYkzP24Augds`9~$ zc8`#Z0S;rh;hc|lI@P$Pb={CLjM@k>8%k9YV1cAL0W>}bu=(*+*EN1xhkfF-;hvZc z4uoXa!iwgvBaEXpoTe#BhQR`8jx}ZiqqPR-^7tYU;Em8jNMV3B2kT(qwuTa9fH#70 z7a@d{N=Zo<2@U`Wp>b5GVLajHcggjVpxUJP2w2ppBoW|P>Px^v5Oh#x0|`e&FfKK6 zBC>famPSzYxLgh8311_=TL}^7gCNbgtWgP1xSR+bg}me8&$o#f1|qs$ewrfEw6 delta 1803 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1262.png b/TMessagesProj/src/main/assets/emoji/0_1262.png index d9509a91005fe5aaf6b5e1f843d2abc629e3076c..a4dec7db98a315824008ce72e82a27be8e956807 100644 GIT binary patch delta 1812 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1263.png b/TMessagesProj/src/main/assets/emoji/0_1263.png index e5261b7db7f7c4f1d3887a0f3ae18af920c935b2..5189a54e86738d62778e2be06f341b74c7f0bb53 100644 GIT binary patch delta 1641 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1264.png b/TMessagesProj/src/main/assets/emoji/0_1264.png index 71b8626628752680186c09928916ff37fa9cb489..7de4ce8833755e61ccceb21f17f496514e7af7a8 100644 GIT binary patch delta 1564 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1265.png b/TMessagesProj/src/main/assets/emoji/0_1265.png index f6031248ba4a85c56bac2f4cbe82ef988f75e07d..0307b599f47af263487a96ce35f84206c9ab9bf0 100644 GIT binary patch delta 1312 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 P00000NkvXXu0mjfJ*V3u diff --git a/TMessagesProj/src/main/assets/emoji/0_1266.png b/TMessagesProj/src/main/assets/emoji/0_1266.png index 6f69527dc8aec02fffb10aa5f8104edbad5b8634..fc413dd77ace111b6fe1b599ee00f8e91a50d764 100644 GIT binary patch delta 1925 zcmV;02YUF050ej&BYy!DP)t-sM{rC&WtHT&J=Lp8TxNnsY_rL!U8AI>JaD(PrGG+3 zQax&*H&b-%xG(U(HcVlBKwgB-rbFbeCP7DCzK0(4#Ya76kky_d zqLXu_j$@2$Mard1*`64$jYLppfvSW(gJO(8VS_$$wLo^dI)7}tK4y_TZmvOas6A+z zMR~YCWQZ|Wid`@YH7Y4xOE&nvBgKgmiynXG>>|Mb*qUQL%XiRAzQ048)&PE!Ed zR46y+ItkJl?Ed|hw{>~s`jDD!(97QFv9fHg`S|bkz|?Z=Q#twq000IENkl2exJ6a`=xxS((aBB4aK%8TSUd4k^eW%gl}F!~e zXaCO_-jK;~a5kN#OwR_x$r$qNr!qR5U2T@j^)AcJ)oePL{0uN2%;xKl_kTa-{{HLo zYC1Yu7|u2y_oGh+Fzc)7@U#kN^RN4<`ycXgdH(w;!gK>G=qA$Z`>gYeY1DmHT7V}-Is>;s~p6>8!z0T#ln_j?R z7vH5yK%S$EL&OxWrV3+Hb(6bU2C3LCoaea^;=KQ8$CE4QT;UKh$xG%J)sFI2u5!l8 zGDePsQc4`y(Lv=IS?KU`9M!wi= z3e}MLX5m@c2x_#Uy(^iFXORm;GAa!y+qP}X60KI(-)JNSDOTA|cAAnwUx~?OgA_6v z%2Fw zO10bxQE)~IOniyZ%9fFm7@LM8l;MNKrIJ>QBp_u8W4O?a@w@;+XoVWiDrB6M@&G~Q zu7nL~|G6hw##pIR3l!2PkqhCpw7taml7DKgL`~av6m<1F_KC8EiIh_RMJJ7fF5 z@2@2`3e^b1G|da|Z74h|Eh%F(R)`pp71ZIIQ7>_3bRwGAFi(o2TClJJg7Y$#784#z zWdz0e)wq`!-Xx-d^WdHtOcp-Ry@z>dft=S=R%%3q`UAF5h<>L(5ROf zzg7lQQ8$QU7Yd(BEWaZptp(Lo^?x79R7sPFCM~?EJd}U{u{RovY9USUEeCQYrIxDh z3?MoK_Va--s8&+bV$@5FZXO9ZRq##$zLeTh)YWJT))|XOLI6RH zk#7(Eq^>eU#l8k1>^q{VsYZgD?EUBfF@Ez}Q?;)l3f38(fsqKKk&>&oAb%Xn2wNaJ z!;(GWJ3?TKsCj?vv2F57Q;}+bfmR%hrJp4c!ej#0@#gpg zXJ)C`8_mil!|w@d1T`N{c>LULC>RMr83p5k5LQVHC5~o@4HcbH3%n&@Fvb#5+tW&P zyU`i4-L_i+Ku0vxemh>GJAag9Bt%H0+fa4{AR>d~I4L7I*wiC6vD=n(HS(e;-aQ|m zZb&LbQdDRiW4^k6_v!BT%k7JwGgLxE*0$VV|8x7L%gZ4Urx_oxrAmRK+qQUr_hp~k z+g~TA8I#{$yvwwupqOpj-hIA(B%sD|WBmNjm!E=jS%$T-Hng8U1AlRP4VeGquV3z* zhTzPF5VkwwKQ*2oBF6s~S_iES!cZK*7s%*}f|tU;!wv&uo{32->!97*Qnpg02A_p?(q8(1i5HoT)$%l3p3a z#s;+OIWQt5Ao0W^6mtKDM1jO)4J0y7+lcye$o)ed#E>w6M1jQENZnQvU&0Fn`0b2{ z@qv~a`Wo|;2wEj#qQ%+x8mi1kAJ(`NkX|N1du00000 LNkvXXu0mjfjm)W~ delta 1911 zcmV--2Z;ES4}}kqBYyz!P)t-sM{rDthJ_&;7)nS@k&uvIT3W%szG-A+u&%MAqod5s z&7-5EO-oHXGctvRg}=YQ;o#smE-gt!L`gzIMLRf%iHUi7eKIU7etm$;%gea7wwjun zn3$M#baW&f7+O+Oba#Er%gd>$skODWpr4+~%F0wfHbO5c7=IEFNHi@@Ix#vbBTPd> zCnO{w77#8V8CX$KC>jxddw4V@9+#Gu9~~WYZ*EvbIiH`NQAtUsr>90fK0i1(rKP1a zFE0)Z3eU~Vv9GVTsghz)M53aiTt_?I+uQ5j#Aj19`SJuB_MhD4#>QNRj>){! zkE7uF000IaNkl`Pb?9 z_ir`ZR^Y7)%jNPJM`7g!&?ITNo4fB~w3=ElTR#7f<#NSbC6d#^;TYUW+Zx7olmHZn zv%;BIylO>?#;?1^Ap<|LRwyQ-(iIqwABP^xI7N$(g4`g+feh1m5SOEPJR1TJ)r{i= zL9v)0HGiv6)RzZhw0gR4tx!IuN|d4))l?2a-m*sR6BiI=hPYT+@7MnlHx1QCXT1q4Bx$*$Odoe05jR8|5v1;ZH_Z9wc?i5u=T? z=E?oARBc@~xjiXRFkeXXi8e}zKBX@S4LRGR5r3cAqd>`ABF9A2aJw{Q`Vi8!)voSU zXcH(Fl0KbIVl>ENNI9!+EDt>0aDsdNAm|ExN`65+9bB>8R*1$x5SDYT*l~ zR)7B-#C;8!xQeq;_@bOh5{nK?K5*FKY;{%utKnH;%;3h?^?DgpoB^5Y7nvRm=!K{# zimaLjH6_--1;|qj9EV|8Z#ZW0?%<*Z7^Xv=xn(jv%3zwJpx}T;R87-14Bz)*f`v}L zGU(J$icC$uNGGx_jJ#a049*#Lcw5Ir zQd7D5;GAXePdTKJOjQg~r-UCGSY$;uFsMiottXD-%B9s=YFgnflPv2SvY=8YjqoYl zAkq}OD!%qfk&6xVxc-7-o2=vt>cT`jg{K%2QEv@HQKJ}_hzKCqa04eMng#e0>jp!oG^B^RK zC+E-8>pGAH#g=>tdqkormu~hdl;X>4!C8pwhj5c&P1o`ZBPy=sn~?$s;O_4lds93w z7gKd%{~julLSWX5iHqyEcTtseH-G(vS4!nwg(y021qqY-&+q3rMz~xrqU*P@s!FDN zl2X*Yn>{Jy_vg1)+x++M%iFs^hKG-9M^tT7ZKV{aD>QUhp}ZGf{`~#@^6YGS5iH~D zK$cb4?d4J-N{&;iZ!28%U2xXxHTyuVc)%$l;zEj^)U~NawDFme0I3fg6Tz-rL)g1&VUsSdfwkqS6 zu|N=@5QId6ahTb3GyAmHHFgw|`x!$)Z)H`1fD{5gOP5@FN~yZeY!75%B1WtT1=Y4~ zcas9$5X}YVBSrt>wsOAH&VPlGiXn)qsK6B)WNaAOv;y6z)duCA{X#+va=-!vGR51M zj1UXjveGp6JR`n@81l!4r{Dz*eHIZy(py^v+>WAknbmC!1z`V^B22PjW!ej=$0Nme zRI5BDR+ME(RMRjF+fDu&=*=ddISQ_Ni5zkQxnwe!Jna%kLJkC>LVq=W7hOA9*~dFf zND>gi&hm)x6LL+PBr$ll?A}S{M{sat(MZ!YU7WUUU^)Dh9B)gKLD)DY$>wuEOmW?I zO;iGuM=tfM-#XgDRr_6w8ekh>6U8>CMW)leK4v_vez(R1Q_Kc6(TIpUJ91c-sdcZv z%~E4QQ4?uRkOV-034d0#fCaGhzlj2Y=LLB=Sy(Pmkx3OTC;C;vdTg!RIrK34NXFGcq>3^48v-+}zCx`$5002ovPDHLkV1hXOh3)_V diff --git a/TMessagesProj/src/main/assets/emoji/0_1267.png b/TMessagesProj/src/main/assets/emoji/0_1267.png index 7b60bed5e4b104e8bedafd70e89cf03828d0c428..fbf7cbe294b615a70553928df3867f71266f82c2 100644 GIT binary patch delta 1619 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 XBN7!@TQO(X00000NkvXXu0mjfTAaLL diff --git a/TMessagesProj/src/main/assets/emoji/0_1268.png b/TMessagesProj/src/main/assets/emoji/0_1268.png index bb334fbf9f1b31474f42ac7bfa0b73516bb7535f..1ae7556bb111c10bd692edc410b071b6d5b9c41d 100644 GIT binary patch delta 1695 zcmV;Q24MNQ5v~o8BYyzfP)t-sM{rCyQ*mcyb3tT@!<1<YFy2f629mOh-#RaJSjU zeN|q4Kw*PMZMN6Ic|2r~+{}eSXrSZOk*{qW|Kc}tT|taKWm{ydAKzzC)TBX&wrV4(Vuv~f>_3jVc@xw z-nNk3vWwfVh|H5}*s6oNc~H!?YOrrc;=Px*mrvWugTJF#)4g+_V>^#wHmr+B;L?kn zbvxF>d#QR!zm|1?Q88ycCgu*i0000UbW%=J0R23uF#b{! z{?crB?B|ZwxPRr-+9%(pUyIAo`nTu4*LB$d00m@8L_t(|UX<3^ZW>Dv24IrIFcv;S zC=obulIyBom)Tc#J9+;nI@Jw?I64FP7aDxw{`jkAgcuDc9#5t-pXp>AkKUhnGMoSC z`~DDKKjyQ^_?^IP(Z9US;m3Ru-w#X|hnN3Jzql6}&wu{{E?)Wlu5qS)IQCciaD6!} zCUZ6i`@{+YbU)ObdOkID!(c$IL ztC1#wIPeG& z!HBMHbboT_(<%jN((D^vRP3!TDiLHPsEzecin15|1vm9On0=Pt^f>$5PXv{sma~ zPUj#HcFTx1P88L3BB}&9$9Mbven&NgP*MlNHT!+*Xcl&znAcHZ!HE5yx4RwY%5o=F z7=OehyM0R%gJSr(pv>#4Krn2x%?)EHB_!l%WJDnPH$V_w5e*ZwG!R-DEg7PgirZXj zzXOd_Piux?i|#odBqmYCJwb(~v=(yd|4>>}3lP?6!>lL1kFF2}N9PI9xe+XvxjYft z2tgN%V7qSkdwk5IE(wGNssSK#id4$CFn<8r5DRwG!EBH~Tx~27N;zhHgZyZO7XIY~ zfL*QN%OD}JC4vb?HJGGah+`mOPPA8u_!)PN1;^XAX&RT4aG4}1OgJZYn_*(~j4L9H z2C-=x=79?l!q9&54kK@PBa@ z9OFcc2Z=Ee9NlsG2vWYC#CZafjMLLOm}j0P7R<2*s=o-sEPy3qIU3GW;)&BFmm235 zX#Fa(WPF8)pO&zsoN+wY5b*ZlVghN7&++Jb;?Id?&ew1b zg;w$p0y%(4mZMwwk_ZGcLJg~wynhf@_&NL-Hz)Bmg26Z=gQ8Rz1X-BlW|rp~G>hdB z3>9hsqDbi3zOM!uJ}k@NLO2xnlnC447J{+e?b^(#GhvV?r%l|xDFUg7bFc-`a76+c z6iAl${`@@}gcyTO14Ix5TgJY9yptGxB*U_RK+masEM^UYueXW0^U<29zTA4*l^Ah zAD%Q1M7*O${PFRhe?L6}O%NkEyjMwWMjsGjOY*rftqA1*P7O`j%!A&W|nS00d zZ_yvRYF9~NlJ|e2o_ihZOn*t}Cm0Bvk8>17$+PEpl1uscAYYHz@m(n5Z8KaF3{8i; z5No`t0lpoda)mLhw6?k+KsW#*6Hoiu@%oG!ho}w?+YwCD3!haCA#4f25H pt_-%n{)f)Apcig3`WQ~I)ej6UzD{q5*meK_002ovPDHLkV1ncfBNzYx delta 2222 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 delta 2195 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 VW35h;(+mIr002ovPDHLkV1jq#JsAK1 diff --git a/TMessagesProj/src/main/assets/emoji/0_127.png b/TMessagesProj/src/main/assets/emoji/0_127.png index 5a7a3764ddc94e818bf446962ddd5c2ab0e66a96..d67acc3d918ff33746d9eae2b875d50e38018488 100644 GIT binary patch delta 1390 zcmV-!1(EuJ3V{odB!7EQOjJcja7Ce-aaM+!9|LHR%U*Wr#|NsB2|NeOY|NsC0@8L+K$coVa;Q0T$B3J%V000DxNklVMw|$!e5;=lkzA!QxA_s9@_1L z^Yvl^+c%6|tL35Opss`A%rKo$BqL*E0jZGpf5I!t*?$S!$lh}fTOQme%>l0IG z6QCf7(|=AStz!}dz$Df1FmDm;1feb%QvW;R6o3VRieUJJ06~mIf&kn@*zU%WSV6`O zqVfoWi0=_6Lm)*#0B$B*i3@zXAP##j9Frl=9lQ`_TUCh&b)N4L$WahX=Z=YeIah_9 z*HfPn42pn#7a%Siupy@2hqgFelI-@(>Vkqy&fz<_{8)mLs*1=vA2m%ywyJ7Pu z7aVVjfVyMwy&w=f&jejY+{o=AkZ#kNZnx~B1N5iET@W(QNP>v(5Jd-35#r)3TVyOw z5dpZJV&rCug!LHNU3Oi>sb(4K`F4}ZG8%$O5u^x0Aa?EVE_9ygND(o{riqX~ToBQS zH-7;WF?LyBR()0E|K_rIAt;J&97WnRWQYXZi8X;f5zyqaN9X*t6hJqPFB`9HLomHXvfWQTREsAS$$TTXW^uTQCBw^(9*<4%$Fd}6G40?q2Sc+o| z$q!38uY*qxgi#c&69fpvtZ;Cg5y-@Ji+?W!hG}HN;D>d26!ZPbaOZPE6EGWsn5>Yi zw+=lCnIWExusmkHiY@{XhFXUwg4uRRt^RU&2tul`0JBo8;}HCM&36=qEW%KkN!VQ2 z!EWdeCvS}~hEc5F?9zHEHaF<|5LA~TM1~NhAgV(@pl!+svtVTmpU=_b)oUpRp?@br zg>Ib>^NRFZiCHBjUd_YC$D*Zd88<^L$HQ^SE7?Ufk(NR zd_|OE)Xhzuox?RVK?PsYJSd*e&H67zSI>@N)TupxG9INa2O3k%Nc3RfeTxcDCLb#0RUkCwcmvV>p5apAAru>BP8n#BK;b&UxAqFD| zLX_(_1OTYReS|6jG+Foo!OZva!2kdN07*qoM6N<$f=OJZSO5S3 delta 1261 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 Ef;V?GIsgCw diff --git a/TMessagesProj/src/main/assets/emoji/0_1271.png b/TMessagesProj/src/main/assets/emoji/0_1271.png index adab1cc4337ae6c7ae579b727adeaecca9d057c7..615cc143808337aa0b1bd64e7f39ee45fddd36bf 100644 GIT binary patch delta 1186 zcmV;T1YP@;548!9BYyy0P)t-sM{rCrC?q#CG$a}nH7qMXV~sH@DL-zuO-)fkKuJMl ziBn&IJ4s|B8Wu@4E}cP3%gf6FSXJkL~lUX}m8SD9zU&NNY` zDYCr!5|Hhhzqy)Sk(XaM0N{_$W>u0L@>6V=ld7@((QQ=A7 zm`xugQjCSqa(`Gq)m9&{t$D3>qfD{k;ji%?kY|EERHUbTy_HQv9+3Ao2m)lcHrk>w zj=Tzn;UzA^a;HQ_zBUcr=cBOK)U{EuGTg{m>_&+k28Et{64f=ECLvUjfh3EFtZ_h) zwUj7z%NmC3lqAB*wP6J>7zp5C2o&B% zq#VqGYM4i%D1uWwcI${jgMeTuP1I^LI3RF|6d_xPFc0zG5|OlEaoa|O12mXfX(yC9 z0s`AnEq|JX!O@pUU?p_af<>;{Lewn|u@)V4R=bGW*b$uBdjC@{BC3Rdw3m!>tQJU3 zVjqZ=51stsg0T=Mst&SFPZ6;gq^g}yE*K85RLKT&XoV<3vPFc2$4ljUwEgi`voS_GGcoGhs=HwXein5zz)V z&uk=wD56^ZeN&K=H#SlZARHC>##g&0;d}D=SjAbktBpvv*CdInr#4tf#G(;f%8(@4 z5PxT9z0e#)8e==jqZ=eshFICop+ZArHy}$qL9i7^82}&INDLw3v7KzAiEU+x!AkJN z6BlDAHizQCP>6{0ZjywGPk;UfhOkns_nd-2oR{A-n0%P*U(-XkT?NFa46+g8yncQ) z{VnSBIinzQ3K2_Q6p+;CA0o=*&JkoGB!B4@@s*A0crqTMBr`$u{c#IXR>#ABFg}UE z@j%RMtO7#)Ww=o+PojQicDve0U%WCx?YFgkRQW1AciiKC&uN)NqIoM0a+2{h}o?_o!K{#LIBb;W^AzbDz zzz9lN4v!|B@26*kx_E12UxgU(IGQ-WGCFm!U?WC30R%O+RWxFkVhee0q0eOGU-S#f*%MwzRaAkc~uUjmO8w zjEsz*pPxo#jA1}8Y(OX1*VoO*!nnA&dwP1PsHj0J4)E<#~JbFe>UjGJUUI&HiW3<+>u zQ-N@0K5@11-+#Kck7uodP?Ks#%&vy%uun%qMf>^dqFDld0000hbW%=J0R3JY4=eo# z5&OPP{>=U-bw8TlnRtnw7e@$?VPikERm<00s+5L_t(|UX|4a zTkFgc2k=yr)E#Sa4sdtlQg;_z&-ec#cV?3u^3oRhr+*asJe?mivng;t%89^z7akI3 zPa#YgUqW~YBT6US_XaSbY_J$($rXdybeKol?czZA-Uw%lv39%BXxw8Ojdng(%!a)J z;h^*_5RBbH@u#$7#gJ>1&c10Q9c$mOr*RLx1jEiGr(d^`%{P37A8AASu`DwV&V(<8 z&&6%5#(&&F@BVj+${ zIK9|L#QH-e+PuSG>lORc>31OcEO)Y-f;RXpzfSb~O+zt;9jBTB{xG50%oih-)CC_Z z<~9(Wraip9RSdi1lmO$a$E(S5TqqP``A(2qkAH33L&E?h>LIQHB&r=o*v+O0U;TV& z6EU=-mZ&Qp!WM~&>mcE!(=2iuG8_)0x-3%*kXzUZ7#LK%U3>_!upbaIJ3ASH5e6lM z$W(`MSSz0560Eud4?ACo`-RK$&Q2j20U~NhL{(KHOH^mAFr|GT*nxk?j0x`{wwFO^E|Vp4(RS!yqki9{lTAn+U?4`fh^ zC%9o$p+IO52N6x(Fcd{GqC>mc>9-q+1X5t369~ZJCX>mXWFWzaOn{3ThD_9YU4-@NrfyjPF)Mm>ex57MAaz1SJ%3A#z<_j7Nw?z3l72R zBJs>+vJA_)h(`q8IgiV|a=8KvHei{WjwOnrwz@0?JlqHjW!x(N^G=eFS5p2z8+-&f zz!Xa+8r3CLt7|PcUDyj8vI(2f6(qbIoF1%yMvzc(3jhI7!vLZYTrsSdMvWY+;(y`d z;#&v;?|qq4tG+^k8Te9u0h`e1FbKtNgtIeYGePcOU)~Jk`K7kP)K<@}x2W>GCu>0H z$3eFV$i;4C1EE6~kN4I@QC?nM;_2C%7`M{n3sKFeCFgt#+%0YFf;|0g!U0&*$EjmH z-s5@HA72SE4L`vNm5X)aR!8DVF@N;Q+h31(H4Ll%_V-mKrlQM5-#KO~!p1?mua6Tl zd3!uvvDAQMFJEAtiYaA%1@X$s8bPTHx5VmsGI@GJUL7-ac`Mgql>+KybH-yYwYqIDx0~ z=QBx*IElNBnkJJjerHXnGJovSAO5^hDpfLTpVlLZIBj%c3JD|2AmAL52)p!0I4_qk zV4LfcIBjT#qQC=UvL@E%KqDSs7dRfREH1XYG6ewM8087;}wO{&(qjvyU{ zxgVxTWi;4MA<#lyV`HSbpN7wgXaE9A*8x<5WBfefBkThZHz-Ib{C~#CQ3()G;DQjD z3BNT&Ku|$I7LT*sZxa$tiZ>NTlIU^h*FrjH>TsS^6h%r+__>(=S_#I7J-5iHW;?pY?jn>#M_W zCt5C-Js{kJq$Y$SAb%5k4g}=-yH{@MR(D}%*i zQ60?3P2${?7-&hhL3mg!27|$9)LR0wop`7|K&rFx*p^fbGLk)>FCQ=qR7N<_VR$RC zc);9@X7lm*-Nw9+$Me|$>+!-2u#v0u_AVH4b5rfjW^!T1049%LPuK`x?rpD1sw3)4Kcyj#r1}B{Xdf&3|(HxT=f6| O002ovPDHLkU;%>heuRVo diff --git a/TMessagesProj/src/main/assets/emoji/0_1272.png b/TMessagesProj/src/main/assets/emoji/0_1272.png index 4884a62e17175996cad52994b89e9a322ad800a2..c0a9aa4af6625e8b2bf808612250b73786480145 100644 GIT binary patch delta 2378 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 Ef@|;vMgRZ+ delta 2083 zcmV+;2;BFM5w8%CBYyzcP)t-sM{rE}!Ylc~DfPZA=)O?$yfCkNL-V^U=(IXdA7S~z zDDk{7`^PX^D`38aCicx>XEkHoqb=d7Fi|35Xx&qQD*ZvW9S{N|=j zCo1~gjBzV~jVqb|%PoH`j*43^fKg2T@4q@40`O)6UH||98gx=lQvkEmU=21T{{H@! zPj=I6NW^UWWzwx*o}T{I=jrKX)lDD%w8VP#>Gs#c?Bi;UL`s+iMggQS zI<|y6zt+v3a3X_*MTSDwE5qUfh^zgaABk8S9LGss)*X&xzgn%kFV`o;5{_}#>ld3R z`+%%9i+?S#>VE$iLPS=9fdrfUYL`q}B(}S)FS4vIt1L=w2b_K`x)$oo(qixG;^wk&UvxmES*0T> zNDgmW3Wf$M5O7#oX(Zz5q)! zGQE96EaJ4W1kZAs#)VCsAQFkP+`53YZhxzRXjzyx$(x4Grg0jk?mm?}NtHH6!@k~s z_Yy>?pJx@<-M(mDp<(XBF!kOnuX&p)#em>t6m2o4g$?t4(<6%Pc4fBJX<>XM(lBx6 z=kpOON`YXR^a;ZX+QJf>jpqU4`!vXLvE>E`rNSn@Id4Tm1M0hlE_2nyNMIhnqkn-& zlED1XNbYu|?R22R&^w=#Nf-o#yM-yEa3G)xG!U_+gftL4k#(@)ER8- zk~T?PSmP0jz-(*~f!QfJ>wH4;AUtcv+@TRPy=6QL8{AMxpfDhqq``)m)<{3_m2=vR zn}&+I%(SUU(>QJMeI#rK#Y=D~LVuH5`c$2*j78(~x~$4fsMLv}1&{qG&J;TqA+wB2 zUnP^XZjua$ouHwk-N$3_(hWRN?32)t;`kP!5gP(*Stsv4Gzw}H`vV)Ho63@F&pM#1dY&`%jP z_hW()AtkS?DpCy)fNV~QVVO3Rloj>@MlvSuDarF(@UqHPm{{T%_$J>U1#2WB%`0rD z5V;z!ts5E6Op${j7???E#UzbFU2(O9Zb0_fz z0>%;5B?yG%NJLJFdkO|3B(r4w ze$-@4gf?P`0b(}(xEKtd$Si0QG~~aB@Lr&KP5|gf zP0xt2!8rv3Mnb9{*h!}sNFMnBD10atj)?~pjz$pWnWRnQd7H-uMpE-!A<#5~a7;7m z#cYur4Rthl&_E#`c7L$J-zWq^fPetJ41Xgr1PDlvfI&o^MIj)dcz8VkVZ?df*AO0) zoD%RV%&{H0tV4IqnLdEbk6?pfG1TolX`H^NTlqAKu+z zmK?W0ptTPQ#6-S^15m~R&K}-FF@uka{IZz{s#t)h@J1qe(ALnklthSml1(j&?^Le>ESbU6p9u@N80N0=8>)jIajDf#*2V25e z!9s2a;SB&KfBW|B$JfIh=I|B%8|(OE3wbqep@xgbI2>=Qv~_$2;6IO`52oDavv~jj N002ovPDHLkV1nzr>WcsX diff --git a/TMessagesProj/src/main/assets/emoji/0_1274.png b/TMessagesProj/src/main/assets/emoji/0_1274.png index 6652ee1acd3f9ab0b6ea6a20850e48d47b9b472c..06b46668d8d626c38426647d12fd269e8e0aa6b1 100644 GIT binary patch delta 2486 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 AuK)l5 delta 2094 zcmV+}2+{Yy6S@$PBYyziP)t-sM{rC)J32TuG+Injn0<9sNK4zbmt#{`Rzpt9ns~mT zh|-~d*Q0+>Bwt!dP=s`7FfACIXd;%x$(@a z?82V}1O*fm6EZC>B_Sc%p?nJq3*fAV@X@r+jAchfMc9^ZN`Epg$bni`O-PAhNn=Ml z_S3O=Q$G6Mz4h9`t87Tes*k#PQz{HMTwGj?a$o19dZm42a9>pQzLm9@fxC=tdoPNj zSu|-WcXKO(j4zi+99UZkkz9haGV-QS{PH{S4{He28z`42#7>Kd)qx%K%!x-zR zf=gOVC;y|=O71KbLm!XdL*@LdfedsIjC*lTLNk9B@f{CAj6;6$^+3=FIw`cppa1ra zJoi|r!++4tuLw>=XoRflq`~}&*Cq)dz8cAeNmqo3xz^%^Kq_gGFS!u@O}q<2hmmWT z$pQ`yBwyT64LjqXRiF=w(Ysx4@_2#do8@gU+(rLC8lj08jIl5r7+lKZJdf7_8-&c{ zrfGox2f;yLri$lz0p}(UN)5|-r*N(Wo^&TEoPQa*Zr=3&N}PfSF;P`cqe)p5%b}}j zvF4P+VVSD3?UoW}AeODa?Pq_}1HlW+veYaoEz6c2jiS1)>dLn7TaF|Mt@9V+Dh6Rl zwr~4oltqPY$*7?Uy>NZ2FhOjz_VFD*i!~w&OSbJvlx5MxwQNTibyVNM0)uc)kKYMZ zn}1?rsW1C#gh2W2Tk4)6%U-Ax(LQ!ZyKU70(Q|Ft8m=PGOMpD6jb;$lz5|gvn$tPf zhvpJ7m1W^kkmWnEL{Z_WEGLgJMK>{GN-?r_1Aa-Gd zL}4ss{NHVm9;*@4ZTz3xp&|IwG6l+l? zg_CZU8#QI4!Jt9{DNTo^?aOM(L8u_q)~9*MG7;u1x+^4O^!`4YvXQP2NHID0ZhsYJ z6%EC189ACp83!{tb!23!D^cWe)6hpi-bV-&AmXkd$x!t`$f(#+4`$MGvDWrf53)od zfe1q0YXk<6Ael*qk>gTXJy`NCz3a=p(8~hO1|*2Tx)Na!;$@M-a$hE+)!o0F5G=K4 zMiCVOVEq1$CuP(uB%nr1%a>)_-GBeOc2o$KD|uPM*{%ZEzMtX>dHW&y-?5OCYCaw<% z5ue6NRRADD37BDUMHhWQpgv|81_DAoZxR4xJZvh1Gc-~W^jjW*K&TDIy;TZ96m7Ym z2n1ye6@^hJlo9i?Eb|zFRS_%f6$GKkdqf@7H&Zw|sSFezn5d~PB7aESs%JtD2p1v4 za#x&v7=~%=)`WgXsfZG7d>G#wgj)RN|3mvOVmL~G(LWB?yayg-45JSPsA_YK11;BCfWp5e+puy1Jynl$I*=+IvhBBE7j*=Y-DUptQWG9P*g{j&xIq2pN;C6V*;`ud_d&UL$uOFIBQr+<3+ zg3Dg#>y?K{V6fhFT=I}~j?bW69zRWWT>Ydg9v>g)B?&9iB9N@FY&N*$c1PxkU8rgIA5 Ye>-j5@{)E2MgRZ+07*qoM6N<$g8q`wiU0rr diff --git a/TMessagesProj/src/main/assets/emoji/0_1275.png b/TMessagesProj/src/main/assets/emoji/0_1275.png index 6a3223bd7ed5ededc8c58096c6c94a4e839135bf..e93494c62a18e15d04473991202cb8e81b0f14e4 100644 GIT binary patch delta 2179 zcmV-}2z>YN504R$BYy#3P)t-sM{rD-X+N@nT#7QCw1q~~wq%hurmKoXT`fqwlTT-c9pKDZ>IjWjyMpGAJ zaY-#U3_mjoK8RU9x`$?B8g4cWMKudRM-f(VAcB%Is>!2osDE@tnie+R(Gd&>_hcKEu3P@!icCSmpGzmYaMY*hUSA0t_R~To-r&Qvg}2bw&?f1rQ`HjeoC*8L@g)WYMh4M0)Sm#L=Fx zw$Y}xbDewIGBM>SkKrc*nUeJ|_A@MDP$N;MU~~Ah^7A7NcPM= z$}fj!N?VfJ#_n#j*;Eu2L!*(bQnRkpdN@)wAb+H`wwvCCG6)26AxWBIfI*lv)aR*Nu~CodXuOUMty0l6$&h7PsY@Y1 zfPf&_s85X%5UsYSghguu(bi=_5JW)qwx%@=EPzp;I*lG9euBeJ+9YTX5SpepMW&l# z1b?xtHq-Tb9TcNpPuGoUOWB5tQHbhU@p&5AHrhZ`^z_Y*E&u|GxO;VzhG-R_jA@;$ z_81}Hqs|T(T~qB~f551Jw28rbQ0R(2}Jbab;>wo-P z-N=M9`YKIk5D=F)F9lH`0-~3e1&pMG9)&g}AS%l3&ec`8dwYmC`|b8H^w+Q3Lpcp8 z!hbp;!l%tkCUptxdU$#%Yfpfm1%X1ZF;RzOHTC}X{2t59uk-WsZ{4!2W1{Xt)Fv5n zis^l}Jb7Dhi$GXyG$C}kd{2%s@P9!_$J}?pS0zm77G%97fT;Q?SinO$m&J0KLO@7T zSW-o?46)$2Sqx+>D;Z2k3$(8+!tYg|g+@=y|F+7qZrUU=%`!Ch-{Yns$n^|1qMk$*IqP9obvJ9mVbkOt%s!W zV~nmSlZi57*~p9udf^m*cz!}~d>Ec^`85Z69STV|dwVyk2nK^^Da!($gnDzew?_yY zA&Qeku+%CP3Lk@*81OtF9}q)Oby$NWGi7=3{Rj#S-pJ)JlJpmCD#V6gPq3qf#>;v+GKCW$B}E*ck&MkB^| zT2N2tff0z2JBsjpj7*brKO++OvYkdYn;o*%k1f38(&JtLF@K31TaA&O=KYg|{Q@=# z!f-guv+l)0!6e2b5I`K|B0z94e&HEG ze;C3bu`mz&{(nl|9={Vr_~Q>4Xe?i4-#gH=^8XluP>q9t?-G1tJd88R;SlhQ6xZjE zin%z;vTih`+;4y6`7JY_JsJf86Hh|`vE^7l0wnU@g{GCu?e=?34jy?dL~$QaCIOAm z#CSK4{;q--Q2-JN@|18U5g~*FT3%oOdjYvV0)d5b2z;}TF@b0r%|ej39}tflH3=`8 zvAio&iDL2HKO;bRNb$}!E8%z`vL?ZfQxs<=kbMQ_`AG04k$bo0MKhPzzPPf#zi)mu zl1Ae1*XR8X^pc_-LHnz(i;Hu(-1GjRck=w~6pjA>^&jUKV`o@E6L|mt002ovPDHLk FV1nFx>R$i= delta 2018 zcmV<82Oap25$_L>BYyzNP)t-sM{rEcuy@_fio%w0wrsn5Qnr{)*28$HheN!eRkCqOn15V1rD#B(dOyObT#HsO zd`~dj$$)G^Dz1iJ$ggD5y>j5wg|ClCFcCQ9!JCO;M^-H)%&&Y{C1vX1l<3Bzi7u7x z=DBq(gnllK^zhdB_T!%0m$Lu>02g#pPE!CS+WP&NLH-X|w%u`P( zJSRz2@$D>&M_tpHF#q~?DR;KO+kA5K?MfCCeXr@*2vDcV+dyNF0K#{ z@5IA+`u6s3%75hR+uO97{bg`%|MJ2fM^}hPy(hf(O%6w3K!NdAH3lO>H*c;l$X;h$ z*!dfPK|sB2451UDU7OFFiS`15aiiIwgLC7pLJ>XjaCJdmup+w7?UU?es7wVFK?J`- z+;P+iLVweQ5ln%o36*`ENFZW=op|X97?V@gFN#`_6Q{%f7eS2>!h|@TPEar$KX3+G zA|M|B2ca{BGdN5bEsUvQaz^VU@Qs?ePGIvfE)37J4O0ly4mZ!!z%xwKG;G_mO@aM+ zb$c!uwgoqmx-N^tNz$|kH=E~bYh_t>C~@@QnSa<_{IveZHLW-Zkn z&GR;DGN-Idn-eh|{ZkQB5X`GH-*S?oEUj%$z((d7RO{5KB%WuNh1+RGgjGjdCr#4? zMi^lzAu6s@nnYBa%VjJ#0SI0?dFI4OTGmeJS1^F|Oy$?ME{Tg}jK)F7_L?ZSzLmzF z=YPd5K5GBjf1E* zH(!X^rj`))}IuwZ*c5*BeE6lsf7klP*T^D@mWWC9w90X5O zFE$xYNL}F6R){bg!?feHaI(xK!gaeZoy@8z%6+bxNi5H8y1L*AM3V|bxar{xG=DS} zMXl>rpVwsU`u-MEWh9;{Adn%WQFNxudV~=d9%D_GZQEe8_%xgOHnbeBdx;?l%KifZ z&>MD=n!NG-ENrXWPv?2GwF*m!IK_IZOB@*r(Url?IJM2j+2(!}oKMC&zzOa+wkP|5 zpa>P!3ZpXO*hal!ln2Z6+3dCu3V)pB28z&N48}`Bb;4<39E*(ZoLIJ*gOsRJOxR#1 z&S!)1i7>pxu@K)~jfS(i$}NYI7{WXpnhEEOohIzv&?l1SRc~d=L<5QBw%gaMx!9fbEuy7-i`10{$_2VA`K5cs~^xVmbMcSVsW1z8_{zN@ZZ6 z3^PphZ*Y_WMD+n7lqE;Avwtc8P(oFPGITqon*j)f2o#Z$APs*=+(iv zNowdMpbA-p)%T3}%d;vlo`P$JbykM3ZIhO$C$PIy05U`@21Fj^GSWa9WN7q}hpytf zI??1gMuLw3@mE8l&GQz4L9N)*(Bs%kQ_qg^G?=<*Wdu;U$T{J*Dt~0iRxlmSky6u3 z!KC1k5K+aXL_=Z?!gbxgjx7wj6){buNm15Cl6Y!0GAe-z&Ra0;C&E>RnvUMk=_8h5 z^8R*WXCZ0;fY5*;v6ywPO5X}Ci$rvqP6hyi_eXI1bmKu4Ai54rM|H?noXj?bP~!=} zhR8?&fx(ndM9>BDAb)Jtii2(1BZ3Q>NXt@108kkcYoGxTq&GsxDT;({@rdDJS_>!p z5CR0R!>u)15up&Y64rHsQAmQwZ--+Y`Vd+IBoS2Wvs=*$N2*F9ZFAU_ah#?!8V^bu z$MJFZbZBxHKt&0th+!7Dv)OXFTDj5T>1kJc6euz@-oq~4J%1sG#tl}h<#M*Z__^`^ z@9$5PU1EDS1&$ov|90HX<=fx?9$o$rzWDJ|j-SuxyCVSxVyn;&i+8(U^LOO_g7D)z z4W9o(en0Jwo&mx%21z0O#=CRm5_10&0FCZ5-|Y^ziAcmm;u^v$y$7a8ek{&Qm}B@y zUVlC9c6BOyfm_lXj=SB{D+C!7BOCg8KM)i!MCMOBcj{ z@%s7;<@OVd-_#qIjr*@PNN1Q~0T?cyvKIjV1+w4X#O$m+%m4rY07*qoM6N<$g3w3C A=>Px# diff --git a/TMessagesProj/src/main/assets/emoji/0_1276.png b/TMessagesProj/src/main/assets/emoji/0_1276.png index b9a389088fb90201f3d4bf93e17acd4c60564bb0..fa3f4c6a7cc550b37e5a356beafef5b4a4ac273c 100644 GIT binary patch delta 2101 zcmV-52+H@P4#5zRBYy!wP)t-sM{rE3hDLTkZhKoeP!?s#ty^eHG`f#JUNBm8URPTz zS4I>}Q$;$GJEo#`Dn>OhVopV3PCbfOEngaNj5DB@W-m(HLMjUf2Sqh7Z9XJaK{{0~9!xzqEF2q0 zCK@9c6ktw9P7_@~3{EcyIW-AEsYkq*I;x#NuZJ+2Wgm8IBYjsGW}!i}fM;GkFf4&D zl2i?5r9`(o3x7zQWjtC(K4?`;Iv^BdI2|%3Am`o8b0>se9Bz_1q?lkiB?d5W7ln#% zWzNE>`}*_8u#=dTiKl>Du1dgR2y%8;KDeZW$*Esrq4ZV&001s@QchC~k!GFZ(=?_YOAx0`W)j^gO$(=OMLsP zhOfYQM1S0Oz84XJus+noH5^Z>_10fv_`)@PI5gc}FAVXhaPQsnvyg9VHN9@tP1WqW zERor(HwK1dxjnN!lYg%Zk60)kdeXvopqoHgh9+woDl&_x z3u_$9n-2yFMxd*jx@%f8&-0S3*?raRbwN=vv9@TjvLGelVjnpn$PHc9yS%jwd`wU<$vJm)BnZh6tYpPBRo0d{t>=b+ za>(d#KY!gBcVR&!4YSTFhG5)XU+H&0aS`GA z=M}4s%z>@2toe3A_>Q!|CR*AKnB;~G1_}>G6a-eY?{00Ky&v%)3%^FT(&t9kwxO`f za2>DCcP#Bdah^v47%MwGho%s;U5Ykg?J9)I|t zLh^{?&e6KG6=D+qvCIp|jFW2)3xn{tH@BVNH=_;*GWTmV8eMlJ84=1?KM_AVN8to{ z0D_lLU|)h`v>5`zao}-E_t&G*ZHI$TLOXb@Ft+BP7FK}R6fhuZ?*g-@#J3|!a)7{u zVrjf22?Dxw5)MjB0~Qg^3i(b35PtzrPkZpR!Z6z;5EhJLNCG!$03%OI^RlfdU^o#t z%GzMC6Q6%w5|=-k>Gu@5W&xq}H69rdS(A`}YCD)_kR0FlWAjO2n5vd z3|{6sNZ=(yL2-Zx{y-m&%n8(&23;7)olbvRO(3FCPRtYE@gTuip$eHXDoi^IBcK9UV1H7;_g3)$hV#tl~gLlFbKlL;g@j(h*SRp zqE!{kMI?yT79jaEacWEyOr)BX5++J>uNjF3L4;UY!YA4D5ds3f5!x>Ar^s{%z|2EndWH;i1D+9 z5J54IZb{ShW$KVZ1a9#-iq|5WP60vFp-LqwaY z05Ps?6Z7%YMR>=t07Jgc%@H6>2&e%>`4m1iAM#71h=d}nX5zi95q)`VD@QPunQ-X#sxrxxuo0#2XSD*$DBc`14f&U?HeP*(-qw3PwIT0pX7X zI%tK-K2Qm74ou)5bxRPth`{@J+$ady4?rxJ)dym_(J8UIEJ4k-n9T8F;&Zh+LsTA! z?9v1o+im5l^8`8=2uRnf#1=&vQ1^ufO f@fRV9|0w?gJ>OOm7p58f00000NkvXXu0mjf2=1qG delta 1813 zcmV+w2kQ925Tg!|BYyymP)t-sM{rDaN-c0jLUl_neo{SsPCKV`Sxq2WcTGKZOF3yN zca2^}QzlC=4{soqk&-YHUq99e)rAIUy&-lxvADm31tH zyPS%CE{&NGnn#GPFB6U7iy-w|KshwGR2fI=bH(MLBEeAgZa42@~g{p9_sAlRW_dRJdb+y@g_@> zi2et{k?x%1V{IINB7eM(d1~>FSRs*jT^FFnqoFbbb>+!!$F)2b$73-J$AJlRz$hV<5)72V z#e5gsZ241(9tnG74OE~*L0M}L=U7ZjkCFgkZT3?MY!T&AFq)bVlnD#SMLAei3^fww zhZRNW88wpMNiSrk;(IWJYK zs;524D$$5W=bEV=-|63%j0#65)J6_Rmw$8B2=TNh%SGEXjOyG|OF*~~cNCAr$-!{0 za88elv78CUXhFE89)(0q7{o?{3LR9_;9Ky1F;-Q>V4|7`spAxwGH7Tetri7?X+Lc1 zrfq0Z6wXpZc$d!k1fUUv7s^Xou%<2ViL7NH3{;9bPKG}+Si=fgP%uP!zn%+03x70Z zA0mn0Ic(|`n2J#ouP73AKL1VLTnJ9tehkuB zWK7@e+)HDX3TL3h5{zCNKM$L{(L20AHvYjc<2^3f29f87_(ZIPN!ea>Wd_S^`jzV?GeT%9r z@uqs73fA}O#vCE=KuE0$%C15Qc_c~<5@QW8DBhgUA+=>FAc5n@Jh#B0eXc>JRIb*9 zq^}u8QLuA~@|wln2OkhOLo}z86hcb)q15<`Je{D#O~A@`ch%MG0)If1+)9N>${8}| zv|TGTEs;Ik5jR=3SS)6xQS0^gWUR5)8dSsxz+c<-eh*4n&Sr~6wwb^D(wF_WUa$A- zt+LiR@13(I#X5*TZTFD%`oEW>vBwI=!%IFtKes0jLXYujFh2HfyZ-&TPkD{3{!62O zL;mi!C+JXPkg0ooIDc%nzyHFs@FGOA<l__YzDYj|`LgkR}dR8o`W zeTC1<@X`3a-fraq&kyOHI&HW6UnpRp%!o{8v$+S*Km>Baz~g%V_X1p-pfM3{WAWcF zMBt>*7k6m?3FP?155^ojJOrI-rUhVl`j2zT0QessVowlyaSkq&00000NkvXXu0mjf D0m4T- diff --git a/TMessagesProj/src/main/assets/emoji/0_1277.png b/TMessagesProj/src/main/assets/emoji/0_1277.png index c59743d259bf4b3391f8b75e8dc30c03b2aec271..50a330ee2d242877ae3a996413595e02b1a9404b 100644 GIT binary patch delta 1929 zcmV;42X^?G43-a&BYy!1P)t-sM{rD}hFEMtSIw3>ZCNo{NG?xBJWE7DSy4+?M>KU< zO-V#YO-V^wT3uyjWO#OUZ*FdPH-lAER6RR9DkLTy7aTJ(GaC{PLqI_e3=JwB6h1OE zH6R1qC}JDmEl7t$(79myUqLx~gbRIOX2S zoO3fZC>{Iy^vkMWQWa)i8EQ}xUqB2^T^ep{5PnAwRyGYkVjXf<7H2sNMP3i_>+^Z);q|Nq;#|Nj4dy#N3I z|Iz>d|Nrv;eqI0n|NsC0fN`1s;MR$+gckq+1?5RZL4QDaBpc(eIJfLAZh-Gw(Z)!xvU$;X)cy^yLSJ&D{XA%jMmGA$jt<2Upcdn?b#=g zhjsRi!_=KhtQx^<_vpFgFrWF%wmXEt3R;`O6$VrNU;4#Z_~@BL6abB<5|--3psi8< zh+dc}XMaRx$kb5#h{+g;kMZz|IHN*}y{jv1&`NS5jkrj(ALApDMe zyOnlm-(HYUw-eur#B`UH&pbuwsj+;QnD3|dU7{I?nG`>;QJ#yc!Y}|vS&E)r=z*3b zZK;wR)OBb6(eY(`R;d91b#sOAOzx5YPk$^@n}!L*_bPUkU_{vf8EffE5sH<3 zGlqBmC&dA%BuctnxF1KGTvY1##XjoNULk2c1-XM zG{g92`s1|_8mBio&0kI9y?Q(C#@M#`>u$RgXMK5h)~1xpUxowHxj#=k4ddx z$8qeB*3TEP&76_o3EoERgEYN;C~41 zrrkG^l1*E8x7pdXD{ptZ-;CWtAHGH&tTxSqG;&t@!`n;;w&Lm6+c zs69}|)N&*G@NyuS?{Om16%k0W zUOQ*wjapGR7Ws&H7`aizJdLoke6!hn*v77>x-HS-+n=4vijV&UDw?j zEby)q1kCp-M3TB+6UVA)yS9~??AnXL8Dl{ZoQc({jzN64H6kZM?AjIqWR_(eNzoK)cOM<0*6uskJDiL zzQG_>Z-5YrKniRUQJuBcrs3jgLP(Ni##UxeWJFwJ^j#E%M?{i{l{pYBdsopzgut0? z5RvB^;e{Xq4x;A1F@GF8*;SNz76n*xpTW2xP-oB+p$9@l%+&~M5$}|+G>D)&ZwM7) zJ}*LS!r8$zv~lYM0uPo}e@e3aOaKN!0*J}7phg*68v0n4C9mOqhj|5&D7e(v}03mSjx+UCgkKhM7!fxC^AF0L8? P0000Pc0iuIx|2d7M5N)7ZDF93^GX`SDt1* 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 KMNUMnLSTXusP``b diff --git a/TMessagesProj/src/main/assets/emoji/0_128.png b/TMessagesProj/src/main/assets/emoji/0_128.png index 1156536ecf837373e4aca5e2a7fe221d7fab5a1f..d002758843169b976081277e08392a0f92d228e7 100644 GIT binary patch delta 1253 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1280.png b/TMessagesProj/src/main/assets/emoji/0_1280.png index 99d7ea8a3e253c458432e07c78bf371d1bdb6b71..d9051abea032c13ce4afc792e34f5f06876ac097 100644 GIT binary patch delta 2133 zcmV-b2&(t%58@DzB!6pAOjJcja7?^`Q_Z+-v9YnVj%MQ3kF1YqrIUS|gmKTacdD0r zbaZsk#jeDVUeKIt$)RMElapj+W@Tk$y1KgDz=Xt%T)&T4udlDz#DJ-MT-msN!iHGJ zk6qTkeSCa;%Ajp%XJb)OQJ02gSyxqfczC|PzP`S`jg5_mhJS@jO--(@uFA^F<=B#I zYio>*jOW{z!NI}8!orMBpU;e?p_9qtepSo}QlEvx{+Y zaM!4P+pdGmk!XE=eRg(s)unWmm6ec?kVr^JVPRoWQBi7YYR}KlzP`TI)zwv1Rou*l zT3TAm%gd&wrhl56n&ro!y1KgK!kUVTio?UgtgNiyxsvM7thKeZ(w%jwdr`WWP~^Ul zvW-v0q=CqXS{)P%si~=igoMDPTgb@BK0G_|>8I@DpxD^hO-)TQGBbu}QJZQ$XH!Df z#CrAX+qjf)@Z7_Ue{54V5QE`X({-fvi!13kdzTo>}Z_%Cr00wMHL_t(| zUhUNPQyWPZ2k=nFyJ*{!`eRY?X5BPAs0EeQ3AS zuok{x^)QRCC<6ZX@sI9ZT3vnzNuzJqZ?|^zfq!`iO4qk;ZrXZntsZ`X{H_zD+dJ~a zk6PE;ML@dkV?A1bj1B$5WWp`*-d{`cr>D|)`Zmw}g zjDLk#@+rLFGP?z@X^2AC_GYWqdMFf1g%YGt;%m*8UcdD7;sq07^amVvn50`#*wR-Q z&w5F1z@P8h&E7+;P%o${bz41_wIBN|KM`KL(HKw^Oc;HN`gX^wzG4dCLG)S=C6$<7 z8{F2}W;;MW3%1X`r2wxu9LvaE@bO?kI)83b9mX-5#Mc|&#cD`O23h~=FSZDbs!vD2i>U26Rpw9y~Ei5~rs(=v_;A1dhXH(4~EQVD*50Rcj{@boGS!Qpc+ zja-%OZydKu6523C*b=<5RA6gJs0rd<=Hc11_jS7Eu{*aS$+674IjxLk9nT`8Ac&$^ zE1)8H-Cx7=J-7Dl`g+|oPH>UbkbfW+TcQ94AOdW70R*<$YI`-pDZ{%N>xf|TF!|8Y zu1Z*)fwry*280!Q4?Pfgdv|)(iJzOC91zh_!m>|aTwGLUaY3KBwc~al3|6>4y}AlN zKpWz9ID8s@hu3XrP5&C(dm!k_76|hP!JzbQt=n(%0^6Hjo90;ogsZF5aDO=b#t5U> z3k8G0gV_m0l1@MsrvDrs=JHZ3cC8Z?bl@OO@#gd@jB@EDh}ol1p2{&>V?+{&q6dno zHX7AjK3I-jxB6leMeKuciiPkh2}F>ga`{nW{(Ul;j8{BRL?V%B7!D~WBm<)B_xrk= zTeXWzNXklVl=Dn37n~g>PJa+_;vqJRCnqO~A~J$fEOQG9UxAQovm!m?*pLKkz<0PBRLYqEkq$8 zWFouP?H~ojfpsEL^mq~#0D!^0AVcC}kqk~M1w}--t-XBi@Q^x~n}1Av`J-5=R1(=Z z^fEM#Bw6NS;2+flYwADJsNmeN0|}fwu+j3j>Bqq{7h{Gy*3pzfF!3#xJm&MG%;vylU}a zf(Al89(j#`0~+BFL6yg*Nm#xZiit*!fs3(gB|J0`G!WV;#eW1B$wb4Ksn}77p@P!r z@y4GL216A}mSXVG6HgASXbcI|M-+~FL<;3Y(x*9MEVESZkb-A1Cmfm0EbIsn>MWo+ zt%%Dv@4_h#?al@<9^)RvAEiEtceB_?Ek`=I=3Rc&!T z5vOTP;7uJC5r4h>lUxsnqv*yHlR{comPm~&X5;ZVy048Yw4qJ{s)+tcnAYKw=gl1P zcd_kf5r9vpRs;+aRRL{U*VjS#TjFgN3l$h9E&`20BVHH_`uGDO(NM35Bx3?PAYV%q z8(JT73{5lo3c`d5d@8h2U;?VJ5HHQg>@yKk2|SB;FHR?HAKz!=i1;H1gd}4km3o5? z-pi5Ak8k&jMMIUsv)J8TU3Xe7#4AJE<~KKIAuB7^B_nAf{-^U_+pb2RzLqKP00000 LNkvXXu0mjf9cvmN delta 2013 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1281.png b/TMessagesProj/src/main/assets/emoji/0_1281.png index 817e92c6f3ff9da61407d23bb2c205c602a2073d..f839ba9838af7f7089db2fede8e818e8b4f4defc 100644 GIT binary patch delta 2140 zcmV-i2&4Dc5a|$*B!65`OjJcja7=MXEo)OnZc{;rSUZ7JHow2WcV%74muys2R8LM$ zg=bQ6M<>L@#DsiyvaqkqzqEHtEQ5D%ZAmeAPBe#FJC~Q2dr&f4TU(NnlElQsZ9^uM zVnDQjQ(IhIb#--%i;Hk@ajvee#>U3P#Ke(iMA6aFwzjr?eSdwXbVqS~O3$Hv9w{msKju;;*k;ks;=i2wiwg-Jv~RCr$P*X48DXcGW%gJg(PJBDx^ zYSLhHS9*mEMrLLR7ytj6cOS`iTicmS?$h1O?IihP?N7U_eKd~g-xU9a%WPgYn=RJA z3s}5?V}D+jW&U_IV7C7a!0J7|{$a#*SH`x@FBa?pc?xv9GOyyxFRlSM@~@!;ndj9; zgYmv>4BNH)F61MCS0TTF;TZFhI$Wz=Tw!F{xIc#BID=x{@_fQ8cN>brG$0@!lJAXp zek;~hnQw@XN{zu8Bfn-4+xDl1Kl_0hQyaM0SAQNAahzKd?`shLCpxj5ow;TRyn)?| zILllqiXuYPYD!IyCkA@PvS$GNQpz%eG52Ck;shRJ^df2^SWgqnRkrFjS$Dis#LIvn z;!?9&YL-eIC$YSYUnx%$W{hQn7VEL(o)UWV0w>E&P)be7@AotEy|Rd~nwPC6%W;(z zf`68P5VTLw+P#Pg{(ip^bvPVtM-zU!oNy(I=HHU-CYNtV#Vl|ds@2=5Bgo#KS;qtR z*F;usl%gmc=vP+1b0tjiyMCQv!{S=4R#n^r8SB+%2ZbYOTw>oA?>T5e?HWMz`g%C{ z#>wKU=clkDteb;uRaLjGXrSwCv(tlU?td6{com%EzF!Z9-#cKmM}y%|`TC7zR_#B9 zpt>3qs@3Xv>&@%XO0Uzb=-tomdZD{Y7RsDg<#!u4J#$=|)=;N>N>4MI|sM4nmP^ zGU=Wr4$BoX{J|jH2kQ#MA_Gz-neUchn3&T4W6xy}5xAXmmhikuefjdGu&MWSnjeU8 zN+dX>{?EhVmCV5tz54v{u(aVbs(_|rv$I%1M5?d`!aI_t^MigLV=OdM%D)mTqfb)VNNdg3`f&hTi8QX&@!(=6sDeo^JQmOPI z6p^smZm2SS7aI66o<+f9{m)~_^gQGXeFZI*~bAI12g=_s9x=L%_L(BTlV^Z@C)fbwHWBD-(8 zB+D5pLvAi4a)+kZ@nRedR7b0Fm)BwsfIK`v1xY9&OK9iT3%W%mGNkVb;#E2hVHgxz zmAsa8q6(5kG6^+gwNv*+C4&g}LLz;*mCixL$Gw1YSIB)pB z*o-=$5Q88hIzi1p5Yx&DJjnuFpUIH<{jD!3icl7elxkJzF+n(!h-gt%<@9kLdAV44lj$xS+Kqd=&ix=n{EM1Q1=4KvCJ*Fze-Tw_Ee zOqN@8-8VajiG-k! z`EXy5ccU1&KeR?o_-qoXy5%}t-%Wwo3B(eZz~Cor3J SD%x5A0000U|EsJVMk;<}c>t$v@Npt*Zf z!ID|Ys%N}@Q+$k@cVSVDjgF0wlfREw#>U2okC=vti^Yar)WCSUcul^3RNKmec!7)3 zoN~jKVAsce%8zE-%!Js-f6TLNx3{<4t%l*$j>@%a#jRt}zJGM$yOrLwjn}1p*s6ol zopaBZZOf5p)S-Fg!kpy4ncugN#D-hku7<#WR@<CUIHudlecxZci)@aU$!y}f*Wf1!e7-@}K&!NKImp!4jh zB^wv1DR6WE001d;QchC(aH{Nkxy+000KJNkl@87Mx#+&y?^5x^oS_-)%T|>4a5)>B0 znnuNDx&o;PCo2?PQ*HhxO;J%aRi@Z4N|L(X&&d24aJXG zRdrBUd$%tE$?Z9JOr(Y(7AY;s9qX#5o0M6PFyt2r=U6IGT0Pf~P!kj;b=WJ4b3u`& zeGL&ysb}R#3!$kPE6({Zj&CN@k)}37l-80>1%IlAbRFr8zjQ!l9~nlPRA}T~N>51$ z3alf97`u_ZKJH^*f!zR>|P>fB=jmO*b zb7-a_pJI%dHuOYGTU&35+C(N{!Z8eoGsdkE7#gnN9GZi22yb|uL428*XsoZ4vkgV-?^k^v8Sji=H2o5`}gsJY=lNNG3rUN1&PDv;>S+k*jt#X*GItFy0Z*C&i zZq#4jCYz1M0_jeFPvNkR9*p#%9){u9h*;8W!rd^`hc*o?MBDYG zbKpyx=uR+1nySL6uka@&aCy$6>3Hs%l-0i^9Yh&|t$@PRRiFujf#@0;WNk5;b-BXZ zNoQiEz!Yz;11MHVep0|I+9cbjzv7>%8SIE&n7Ae#jQ&7BL zPd?2GhQlb92e;QlTYc2scXm>(N=>b2t%ZQ3>YfG3zNy` zv|5~G2Gauc)s_mZYcXmFvyjuE3_?u*PE#Cw%47zXP{0A$urUnS8>3ncLj*7=!i6&u z4%8HiXP-YA23M$Q+ke? zaD1|P7G+4MSdk7w0no_n>KB~Cjd!`?+KUKjdqprQAqoQ&8r>5{!kS8QI2Kiyl=Hyzp<1K zVLY&$IhG|q9Xt{b<^+?n-GVo?Ha0evW#|B4SOrN`5{HkL_xX*D z7O=H_SbD{40(17PxNeKjU_=V*9u9eL` zFhZ$ZS_+YOYGp9oU0+{ZM3xpvc8V_|Y{U4AAKYEtXS3zeaHtSqSbG3L>rNVg$g&}8 zQu@iTvHJY@9q`V(yF5siSrBFA?S1Rw=~{BJVwGgO^h0cj5?sIJ>FMceqqTK^4>itT zJUu~#*bz&9c9gdB|9y@B{KP9S=kwd!TZbU{AB*fUiS=(`d;kCd07*qoM6N<$f}v3m AKmY&$ diff --git a/TMessagesProj/src/main/assets/emoji/0_1282.png b/TMessagesProj/src/main/assets/emoji/0_1282.png index cf639f5ad5dfcb907ad5a9c817c1088fe5a50b4f..72616246497692269651d384984dadb239c3ed1d 100644 GIT binary patch delta 2043 zcmVz-oBWyk#m|;41MIeV$CzxR`V}CXmmtZi7R4AWlK50E4 zr*T86azCwpRH>12Y+_B)yQjX6TgR)5^zGk!a%{)P$JW->n3RxdCU z!^6XIdLZxs0047zQchC<6Ff^^C<%3!+Wr5$=l}oz{eS=e|Nq+m|CcEK{{H{}{%rrP z|Nq+m+{U*5#Q);||NsB||Nl_`|8xKU%K!hYasU7S|NcP!g#VQP|NsB$o&O!@|Nr#= z|No5g|Ig$!!2kdM|55+{rvLxL#r5v#W#!u0MV6od00rwwL_t(|0qoE<0s}z^1<-Nf zPYA5t|9_@&>sG4RtI=;h$)9yTco&n|DCSZL08uMGZ8;$Ccz?r?=FD2D;NH&+kZ4$a zgT4+R64AUahSv3bYCi#yoT%!s<__Cf#{p+_Yd@Q!SuBHP90$3tzsoC*07-YGn>@4| zg@GsI#7iI+wDtPYqOQ;1~QDC%6VM)+4L} zr=Uz8gV#G0gsi000=d|RvCcVb+h8>LI%c4ZJ2I^6>3XAd(!JVwwyMLHORYOHG+uM# zwkWe48D|uC+4pPOyJ3von$mK=(d-o>YkzdzR8q=19EY!Q6t{JiUL3BUlU(k;QA+!b zLd5qSW!rsUh;9P>crsOGD((p=a;|w*fs`X6%uBi1KO{eY4G7~lyY0>a7fT=hyxm%B zO(n%d!11G{#;&?-Ty`xAwcBiWJ8LjjDTmusg*f-Y?QpjOU7nLS26tNH9HY+50)N0d zOg6Y?WALb;$ipcV%jx>uUr*!x{`2?hpLZ?F1y?9zz&OAILO>+Pl+&_g?D~JL^}VGi z7K8!(Zenvzwvnf3^c=Y(Q4uh8#5N3wV%FLB|6{)b>4ckis&o4B-J*)qnVoAWs-_$G zc5+(_%Ai>E|CmZ{$w|F4w<&B@C{vZ*Fd+8bj4?)n+b7 z9i^$x<$f(f5P$gL?!NhX{C7PSDU5uE@UE{tX-F9!MkBR<|6{3GrU)WFlz+?OuXp$N z&1Qc*z%NYP(P;Egdqqqi3E{0D_>N*}-{ZDW74Zt;j)cC^K+2ixguXq@5Z6Ss8Jh=- z1&onv^$R7jNF|mM0Ytwpu;FZEhrV;3h}uk8N|Ll%1fk<9+INLQsf1_Wk0cOa7~Et% z3gM432U&xtuG?(Biq=tV*ngvr%A52I{DB1edqdZGFCjwr9N|@wVzaJR*K0C-do)vI z!O#(bbGiP(c4YfO=w6;DhSS}eDmoc%2Q%Bp-y1p=*ED%=Zk-Us!+An#x1}hG z5F|Z|J5y9k)~GlNggV?heh`F{{8?gkIILhubeJg4;kdJoqN(lFtx_Xib72hORnXV)Lmtrx9}~N0LI9=^(yu*FSho3=S(? zG6)e{sSnyIK{3*HsImq^17Tyldn`*Va4YD7%HCvc?}<3Y=qMHu2Ddt{9gdVnh7jJ; zj+0Mha1bTs1aJ`R{D6TW=?DH&Bwa}*phk%heVpdZE?SHY85L`FLpZ5_1ed)1m z4Ysxop&JLBM;-(s(hv$d0pd*y8!KCub;-_@xpil^_2fr$y2T*q9DbN~f(YRa&cZc3 zyUvwh)=c4PN~+alO?(K{37OMDn9#zrXZ+Xy2T$L{51w^&3PD4m#RRVLVXO7m0vr5B z1T{0=cS}x*zjRqdkO1Q8vBUL$L~Kq3ZO9AagTG4%AgW0U5XqMEe@3w76Ol~jDaF@+ zpO`MM*2%8>PXy=V7JBjbk>hgnZby4cgQf1f^TLi3 delta 1817 zcmV+!2j=*Q5T_21BYyzQP)t-sM{rDNKqYNMD1=!(e_u;*L?~f9B$SktWj-Z&S3itl zOp%e1x3{;(#>ItNLt;80i;9YokdT*`muf;Oeo!`$V^5)MR9akJdQdo}rloIbWWtVd zx`<}8ePFkPVybgku6bOPWJ-WjI#Mqgnru*tTS9I_C}=+-!GDoy%$t0@jAzG{cfpQv zT{s=1Y*I8E3_~Upp?FqvOf<%oYWL8Xm zfPv4Pag|gupkhMbrg*B1ZHQofK{5>{^t!}+vn$lfvh}ow#l>M z{rBkp=*ze)5Ptvw1@1{iK~#8Njh2T}>q-(pZQ~@^#c;{I$w@gnkh$Ug|37W_NKmG( zrRB(F6zJpb=`N2)UzlF~16&`CM~9dnUBgp)JsS-$z0T5<2-%}h93C@sJgi7#R9pmy z6(WmcQVc3)VqXzVXB|_2=@l;-KOIsW(-;+I5{#zv@qgvysAF=mngyekrJzXZRWP79 zC2^b)Y9{mXk*pv8{ot{dYO=cUikMta`whWW;uXd1ZQTX$TN+8y_~j)tv%!XV1y|;4 z_`i=pZHo*Q>Ck%4u2WPHD(&BfM`Ky57+TL6hf>ol%Y=R0Gaz+cOPmT+hylg1z&ta6 z%g6l^0DmJ3G{n9oLp^4K!70y!%O`C6mgbh2;l|9weeCGlw=52GOQ4o z1R;b{2uT>X6639*gfPK5B}oQ}(958IvIJC0XknGI))c%@PFkrNSr`fT8YMYR(v+%I z?_^yH=qZ)Dd@jqX(pp!c{be^Asj3ogHU&##s(&WazMkHq!susDsq@?^wSiaOIY6x_ zD%`wBvD)xBCaQ#RG=!TkxG;qDH1~>ek7BGqL31!PRzoFu==OoD{JAus*tq54N`eV0 zc=cRq%Z!7(bsl<4tAg{edRAF1HqOlsFU1lRsVU1mSBwc6f}{cqhI(}9^mCJ>pa|!O z6@P963RzaU4k=@V8kJWFtZR-M)Rj3&c@u_*+d2nDn%Ppr2MWRnK)F;d*9gRGSe;U{ zRDf>Wqi{UV6l5U7SN#f_tB5vL3CN#o06j@m`|c>t zo6^Jt6g?eTIuUa%NmV*oQx-iSYa~hp02HazCNarR8L6Jm|H0K%H`xqrp6&Y-joPmhDq5Yy@GatRKK4pKL|s;b5i6i`vv<#>MK z%NQn@c?U`mI3f544XbG|+Dl<@NUh<50)hjAqJSGa?g{T1bXjl#79qS#@IoqI!uK7M z#>xUSKsYaqy&a?B`vmi)1Bo;RVx(2hSMhz$uWmP+Fl-uS0i_z}+<)@){M%_vf1KT@ zUjY724E?XQ%?2*t?oZBsoPXovFJl1$Hhcz?&!;$~+A^;3=WMH#K{clWPPpa4E3!IvhUVEm^64p`Fr`jG8c%2W=wfp9Y@+rsu7^j1rsWknz0T00000NkvXX Hu0mjf4x3uR diff --git a/TMessagesProj/src/main/assets/emoji/0_1283.png b/TMessagesProj/src/main/assets/emoji/0_1283.png index 3c8ce7f0ffa38ef22ab5d7af99050149df6ffd49..d7fbe6322ee6064e9e7529eda56caea9cc0888ba 100644 GIT binary patch delta 1840 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 Hu0mjff+O-e diff --git a/TMessagesProj/src/main/assets/emoji/0_1284.png b/TMessagesProj/src/main/assets/emoji/0_1284.png index 0bac6aaaf0f33d1b4a65304d66f07dc18fb6a1bc..f99c23885a64767fa90812b2a26c9b3cbbbcb6c8 100644 GIT binary patch delta 2011 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 delta 1924 zcmV-~2YdMC50ej&B!3rBOjJcja7@#Y3+b&H*P9yLr7Yg4E8u#s zof7V`8vey5_PikDrWpUpDeJT^w|p1>)hvil3ZG{Xm0Jw(ygvWXNdL<%|JZ2!!!q-^ zEC1Otu5uSwECpya26;RKc}@;QOlJShFf)hH8F$I3f*-n)AJeK*D1gf!H`{Qm9$Awqd~6zQO*+Eq`|a00sz2L_t(|UX|8` zdgDkI1>h(#2fI6I7+6SwnAyxhhVGf!egEg!Qx&cCWq&rZcaGDaWI6ZGy(MsOy-Djp z@9Kjg{np-kCqMDf)Vtl?`c`#7G`qSvWZ$;lB}ixvy4`R+ao9CVqTMRfE(qN)^4dD0 zzH11A{$s0M-#(L6lbtF?Y2LqRn6))BQ_5GMWm{$ca({`Wu1{C?m6cp! z6{^Im2ns(k6NKKyDc)H}7)BQajBpoKMww<#A%6(M=r<4A>k0g#i44Oq+|9cpdXD`e zV2OaE)$6&R%O+&`5D8h>)t5S>Lqsw#x<(!zRT6vns}LxO2ZpfU&3Zia;2$RV) z;}&9*C{5r%LXt!b_G7{&v0bqkHI?c*n@&>AbyZJu5XUj(=52^m@x)uLsFh%UJVlGZD?Wi}aRD2um4I zau=GLCgEB_3vogc#|`39&oq~#Wf^fG9xVfsP(Anksog&5V7eojVhR!YJ~jg{BYKl4l@FbrT<3EhxR@Q0)n(+N zK+U4O$(34#&;~)~e&7aDkXbqZy-LzFL>IM+wK(E=K29_c!HOsypn`}p212WNh;Q2= z%`(?5i2*9*rkDgePe@J_w_-64Ie(94Sj{*t)*^np7U1I8OH&>xYQ^`!fuGJ&EublX z8p%986~NQ$f%xh2BJk5R^R)_MPvbN0spjPzkGzZdtbPh+91_FRfl64SyK`t{`lu z`U1D`sRttnR+om}m5@jvA08fl$vUdKv<@76S`zXc^zV!S+d=@LS&D5{ez)%lLIY74 zxSo6cdm~V#P&DEAAnMisXH*own4||}so5%?KAx{)Nnosqo%U9xQ9G7|G_a6bmJ)@e zkt+l_2IjCo)ge^plbED1fPauFGPB_ogs1tqP1j~$Oi~z#>qleayzUA?%yHaWPqY-< z(J+cgZxpWrK{g@g*xHaC+mdalZa^)<+cNW~{KBbH?E+clV$D4<<>uafe{?K?w`1&^#BWGu4 z-(Nb5N8h)?Fa(2F=un@XLim0L1bGi>oSe&Q)QjA9ZcZ;9)qORGjx!vZs!1Og9S9PwD4H~-%(%Ww};Nn;`H%~G4%2HcnaWF0B?|A8l~_-)c+~hFAts0&CSgM|2hB) zzC=VLjZ*mjZq9CRUqo)NSM_DkNNF^_-2V1X{{1HZ`?>T_0Q?7agCGdTosnh$0000< KMNUMnLSTaa#-u6$ diff --git a/TMessagesProj/src/main/assets/emoji/0_1286.png b/TMessagesProj/src/main/assets/emoji/0_1286.png index 7dbcd56c90cf54f583975df2b4bb05783a23640e..24168e4baab00cb19193c760fb7d2c70a586f3e6 100644 GIT binary patch delta 2107 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 KMNUMnLSTaItCfxb delta 1766 zcmVw+o?<(WV@YW}Bcpv_ep5TrymlE!lFh4ZO-p7XXtf%6$vTYFpLjYf zgUv}E3~pa#!>M09cE#b-jpy5#^XsYX;-E%+%&Yoq000009duGoQvffWxc&ZG{vQfy zXx}~9JndfIhkvM@*~YHBz_`Mm!(2oF00pl}L_t(|+Le}vLSjn{Kt&jeimv^&>E(8M zwU;gb|3@#G0a^Aru?4a#dqXEEXqF0dv`f)d87QQ!A9T*nuYYbEjrTy~=IZjSjfyl))a5S4 z5f6%s^V`PPZ`-`zoN7taekLKuIF}+#DJXPf755#V_&{b36{$FF#|@p+#4C*c`tAFF z_+~6;X}_P??#=~CGs?NrJqY=_eyp)3K?U8_&#qyh5Q4kKI_y0>kcQ=yrD>n3%bg3- zPg#;A(tq_Z=wm^EUT>i&%l0XnDg_0lj4In}czP>lvxQ1nhKfuc?pRaV$1J?V%zC|z z01T3{wc>P-f{KI!Tq(7f1;Jt=xu6NU8RV(V`3?oVM)L zmAdLgCyS>zoW?n=oiWPj0W@=#!?A@+xwcA*EPqq>OLVxdKtZJ|hL4Yr!vYu%u#VCn z`ir^YER${)tE7D+VHX(;cnk~{y#}o5Z1D;V25?17Pz)AVF+~FuLJvtnaza*;!D6;< z>MJ-3#ZozVy^Sc&-a)}ZphN9t37!q1IO`R$W}Jf}Q$?Y}0vKx@Gf)!?DrL$OpK!kcAX1 zQ+ zfpzF2&$|%=RFY#e_(v8Jg{30May)Z72ZQ2S>& zEKs7IN9&x7u50bi@5Ucrx2D4(Jkf#>QVfTq<^1H&<638rrqih%|9^3EKYz&~XbaF4 zt-JgCd$jC)|G!V*ukKnSr^~V|ir|6Y1WxsGevdp|$0VKO>$~tL_w%JSu5uN40&wii zq;>c7bniJiu6-u>3!{ODr-!@wvQow`rLC;B1^~nS;o;#4LCN*6lG^n;905n`rIKNf z_(@ljm)1Pod_s-SWM8YC;}eYki8qu?Dr*!_O2sG-330mkC|*7wUf8c__4*?k6-V5|24$_3)G{Q_KC_~vH$=807*qo IM6N<$g5AJS(*OVf diff --git a/TMessagesProj/src/main/assets/emoji/0_1288.png b/TMessagesProj/src/main/assets/emoji/0_1288.png index f258aaa6361875a26264b9a98cc31d2a8c3d25d1..b72eb098deba6fb7f0cfb95dfa47d37c6703ba0b 100644 GIT binary patch delta 1870 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 delta 1375 zcmV-l1)%!F4Dt$)B!7EQOjJcja7E^T!YW97UN#|ZKPQh^HHAV zIy0$lLnj&)8hFWHNono1A_;89T^lSx(YEbg-;@Bf7N zRJHVH<_7fO7eUhhRMQ2#{FVCE_+T7YFaJtI4yP@*FY^HrI=@7Ot}~Aa55nGv`YuAW znQ+Y#(c11H#D5yQ&1yZCtgBU9H)KP12yV4RG!xNO=kv#(`+SY-wG!S|OT@}#B8@Ws zr^I9(u73La*`1<(x`d^5R2NAekTo5H3oxgOGPsta#AcSAKp6#nYfIt~^ zH*}N@(Rn;1ocxavf~E0W_TyfQ0MRWiNn;P02re7@ynp40poD#b@E!&RK_~!2@IDjk z2ShMIVjMF85QNCt{3{R;+$<4#IgPc}hyr7Tz*c^9a7^$ZsG9FA5Z+kFM8xdy9fe3N z6%i$3D4n;otLF){h2_{EkH@}`G4}l)!7lcWNS_?K%clL@OzO1|9HSb8jKP&apukat ztPuTbj(<42t}_H8B~gX}3<{YdMs!Ndtw}3{O)-+w$%_L>r5u#PAY#9(7YGO8wg8M! zPSTI46c&lmb)I8#5CQ@RkYmRs6v=o8qMd0A5P>6G6}(2I5|Ak^60Hyvr3e6>zmMD= zqEWI+)JsINMxPqSAAAY+O@L|`gk2^Kkqv>P_J2Swq{An~+*sZ%6ZIZMB4dt2j*iwE z+>jGZa#)eszNkkz&A|@G$g&a;V8|A5*?#iN@s zUVquSm~wX)A%6;CTqLxXt>y@#$j0PZi-3G9#2bnf#W$ z0*I=uUlvj&Mj2{I<2wje6vJwM`QDhn~0->{?OO*|cDhh~z)p*{Z3AqCxJfBrk zV^W+7I~ATcq9E)v%mB0@o=^R2-+#v_3c^GHV*jgt+NghQw)@!kK%hvXW_$g)`B6VL z{_S+#lZ@*%1xwq{)9D1|;rP?(bGy&Q!_lNXqwV!1dE2ye<6DfEyq~UH#}b96d)4vw z`u={>{QPGr?M6l;m-ox(b<0kpl+%pc>*aEJm;4i{H`8zpj8Qwhmsp$$`Ahim zQ^w!rH<0c5)>-a+-fpj-3KRp`)OW&L8DH}Ld4+PzbplFqA$1W7@Ljp(+xb#SG3vM9 hbGiIph~OIl{{gcg-&kMip;!O_002ovPDHLkV1n~SbWQ*O diff --git a/TMessagesProj/src/main/assets/emoji/0_129.png b/TMessagesProj/src/main/assets/emoji/0_129.png index b39ae5b0f7caca464df696d70693d9d058be7be4..5a7a3764ddc94e818bf446962ddd5c2ab0e66a96 100644 GIT binary patch delta 1261 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1291.png b/TMessagesProj/src/main/assets/emoji/0_1291.png index c286b9d32c6e041df8ee235c207f27e36f314b80..47e6fd05f729075823b6ccf4f6d16146511eb3b3 100644 GIT binary patch delta 1712 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 jJ^kyP{@X(!F(fD}kJVOSqm} zpF^seKc%Hguar8VcP536HJXAfj)*aoXB~HK!Gl}b$b7@AW8l!hu4+Tbv1zq(N#xg%wU)82xOUL%<;n8gKAGXb000HQNkl#s%QTJ zIIFd;u1BLsWHg#wUtHFHQmI$lqapG{!EZQ|t6KdhgzC8&KLU7*L@qyHNbPzq%n=dq z5h|qlX<;~Dh&jsmrvl@m`nfKyhr@ZWFefz2A?0U{v#ZCa$GNu9oX%uaYzZmHUamjU zOAAAIoPUdjrtnT@B9)^90`vIcOsf-GIajnmFr(LlLJUC^lrg#d!QR#{<+_N8Koe#J zgEAqf2#nf~il9Xug9$Cr6d06u3M{npaS@Zrpfm4eOmU@Qbb2yx<=|}N!y@LCPRFtC z)6@+D#pJzrfrrz*i{=MKv?3#ldY!1t(%jBdY=5m4W7=O*O z4RI7f$^B$=AR$OL-v>oD!##w>Zu6b0z`8Ck+mc!rI+WB`li_N=VESf502Q)9U3*~; z6U$XMM#0tZI=;_E<;A>kpV;vJ%8Vy$w|l} z7yx-4{k&d6#Eyfvqj%8?HU-9RX@@ql?318|5KyMPj(&djZ=xMLF;W;yY24arp66+5 zdnEWv#iGwUl(>Ybw;^O%2ISS~W2UMN05xD|3&D9^#Y+h(6o$!QctGC%b&_D}65x0l zCB&CD37qo`z0gP%8%7aT#eXD^0+%TzD#x>#Y=w!ywS85_w_TyIqd*S=5G9X+S`6Tw zp=d$irc3OHi@(IHAPGw8GqG~RjmSWF2BgbeN-B?+gU3vck7iZV2Z2S7CLm+kYSo#BmtJ5Gonr z#RHO!eLmi!o#|AmL*D;MdjE?~G?Iazmnd<*oXwEE_rc90>c;N2IrwSYw!YtgzFvLq z{Z>kue3-lYMu+bsMSk&@^c0|0t`&;A8^ZZwy%Y%mGZS%z;;$zO1wY5S*V1>0C`(|< z4SN34i5lV-|t1(-d*|0HP!YiE(-sUn?bSGexrrASfb6I2}R-4G0uj z3aGH^iej9N;UKKiKSmZZSwDv1+Jxr}0fr$~OeUb1$v1_MiPCCe;#RAc@-nv1k>eql zf$OywdK-%8p?MiWh=^0a8wS0dEwgI~CZ_9*+S%F0vhi a@2o#E!Q}rv*1-Az0000Fm_$?Aq}1+4c6;>+RL* z?ceY5(&_B#_4eoV_1o<3@AvrJ?CC@@! z-tO?u+T70N=*QO7zRSF@C4>+Ij>>Ehtm z*4WV2-{AfH`10-I@X@p3@A2;D+UwK0=-I{lbH z($(L(pT5Pzb!JpeKrx$$bf}}6!m^vrq=4M6kgmJF^7r^DBp;P-Rkwv`7!nPweI)3) zN95Id4FCWDDSvcQPE!DeLuNNmT?+*iE6X5~bHS*8%Kn?wrN6Uwny9q?j^_T==i|2N z{?g}jnTjR=00-VlL_t(|UWL~OU*gOb2Jj6?6A(h^7$rvVrib2pvG4o+zs-Hl$t1Au zEeGVM%g*0t=FBAc>pxaHl}cq$iI%489bMO2aw3<>q<>QBU;n?-X^hR?-oz5ISgfHN zrqM?kebX(-vD;g6(&_&_9>ZgaxGYN#lH64LQCWEE4~aw~c5|EiuL_L^ki3)f z5I94zUVp1(byu;>Db-{$H4MYD@Uvdd=Otl8NVEnd+$8Q~5Op2@AAkYieKL7}f1i-y zDyC8|m-A9E7dEaV&Uy91}b!NTr;Y<4mvt0tOKfq&$Rz>RM9}6Lisl z0fb6qpeSaYdXflJq$ov(LO=jeEYfzMVdwz9!K-P6fDsr*NozxAXp#*O z(OPgn^5};W3ZCcezCS)bc1x>onsD)=D1VBpxP`ok!CN#qAVEi@yo3YpD#%U3`|$(9 z_x`Y1VtIsNDPVBsMT}b}#Cr110-?Glhwzl$H-!D?>teC#E)_B?GN8Ek5s?!_Cfc3a zS{1@}|NXJweE~oL8JUI%f*jg~$PmFXLPAwoFlZ9H*F`U^^KQ2djlT#O=t-~`Qhz~J zED*+NcQ_t)i&qCGz5L?o)_c!d=}N1n8j%g-9NrJ4u9I=dxvk3 z3(xN!Rl|HLMa1PMKwFCm(@@*CKk?4LfB&=ah#qNDdH$m3d-K)k%>jXlU^zkD@>&QY8JE$LnxeF~_P`&^eb1j` zEEkO6=T$&dCvuQQ&LGbmH3CskmnGA`N3L-RkD(FZc5aGPp)Q@X|1ny~+qSAH(Vz8R8 z<_nzng&I0u^4rSKs&8fhE=sd0~oTAly01Q-Sd~I4TRZhRH%cfRL~I+jlWXFWr>Mw_ED>4I|JGqo3BrCJlm!me|g<( z=vId9CC8;!>;9f2;K?%yh!hc`rTHp^=WIaKtIazQRA+o`ns@nXl?Xz3hc`I}5y1^r zeEbI?x`vBVqq#v5f-o-<2+=UAI*h*v{wtnld(UEdnPnpu?O}F0;)TtLxK#W z6$~JDr$Pi`6qyhyAjBIFOgwA4>MDwDI|0$7N3TaIsBC+nC{GXqLT-cvhhXAfb5zH* zQ6pghfFKBaHL&UY@kEMc5Q(1z1jlh5n+*^m1Q^VO5q~~7{-AOpav3I)Oth*6$59zr ztw;!rFh+ntpl6AQyv#S|Uzr?;Mgu~t_2@V(3t65eT6$L+MyeT6!{6#p+C4^;r%^@tcZD1@_D1ab?i2@VJ z1PJaa6X*w`FSkTct=rT0cmDj(f(3(!x9tdBa|+c~NbrS|S5t$43J8^Ej?q&p2xO=M z@wRkOTI-4kLbR|HYck$Ipor*CMX>;PO~Tt2SvQ?WCK^eR0tPOek3s$GF{-Dl(w}sl k-bKC8doRt0haknj0imJ?ZyxxY`2YX_07*qoM6N<$f~d)%e*gdg diff --git a/TMessagesProj/src/main/assets/emoji/0_1293.png b/TMessagesProj/src/main/assets/emoji/0_1293.png index a9019f726d0b7cde3928891550ff666d802a1acb..9c866c94716e7743f16cb6b340954378e287d898 100644 GIT binary patch delta 1656 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 r`iJ4YJbe51?co96gW(0d3M} delta 2441 zcmV;433m453zHL&B!B!+OjJcja7@+e?bz$>(&_Bf>h0L>?$zq;-17C^_4Uu^>doco z-tO@0_4dZbz~=My==ApR`1#x8<=*b_-0ko0_V?`d_T=&NFmnm=Hc-2)zZw)kJkkLK|5(c|UF+IIv-*{Y1)62o0gmlfeq0_{-yqksH*wXj=`@O%p&Dh(-teU~k z)4jH>n{ijnrifujH-c+jfK@J$cWAGPcdV(S?ep}^pL@KNd(FMB&#sd3_V%-cWj!7f zv&6~1k88)6Z-1sjS;N*Ks-gb)zIMYNcy8*1Ki z@%LTNaU8CHdlQE1yPlg@VH7VZ`5}*b^XrM|e4A}|@ zVK73N0b4;qg|OQR;f)3bB0EHJZe@%pM+$?85P!r;*b7EEsR@Ej$O6C*5f~M<%uWy^ zB&5J55|_m^1XXiEygA;UaM;TL0tlwM&5KUtG*BSe1_c1=RI02a1XoGJk;Y*;B^8|{ zNJxVOLqOmh%6iuK1+l|GZOky7DFev8ar5jX8aX{ZAjDoU0#20aBL(y0Fu61k1|2XA zHGdj~a8DS6L|hP;#SDdf-WvHlQ9P2aFOH{YVzer)AxNo)k4^=D6E3^)MpMFeEgt@7zrAPK|*!{BLiaOBQ-({-1cHMTS0k$-}Hu> zFo;0$b0lO85-4^ejJi1*AvJby&oK|qapWKpJW z@M$G+#w+JMz9-Z?2+y(oZEw9^27k-t_a`7S#%vh`%V756a1@%Q>c#;fMy`v_d7X3L+Li4+%L=RW0CY>ML7kxcK<^Sh>@EjORh{fqEZoaevx9@3sO0 z_fGTzAwa<32~Qw~u9h6f?JKQa4aDN-n=6U$-NBmVd{Eo+u-_I0ad}8^7`Su{wd6T| zzt!^Jo>xDAz78DBlOyd9`m5E?AFlH<9gb{A5aJGwNrIikK;UJn7F@SqYjt1xPOH-& zI2{1u(;v8Mf}-_2c8IQ^{)QsBsdAvDivVlsz&|#3On*IqJV)WX$WHeyuqgjKoHZW6%sd+h)W^{ zBEh$S4g*Ndte7Oajeq4bSOomhmW@2*O$#v#l|P8MAQ;0SkxZIqB`F(eV-l?3nOi)5 z(6h;8;eg<|kOYLQtLseN&~w>rl9kQMJ?XXA%XND*r_g&a_{Sk}Cy1CJI0_Q=`pw=b zC6kq`0%44KVh{x8jc=K1js|BD66gfPnIx|7>NhvlYOV>P#D9V54`T>i&FVcC(?%6S zHi?{v#2E?sE`tD~nuP!(n=>-kkG=U=0-JBqVu~STHGdHp23`Vu4{<*X140wT?Vcz; zt}%zrhV!^CrVJ1a!4zQ(NpPBy&>=L#6#7m2@^QUH1^BuCmNs-<5TbZI!z}?3`Ay`S z&Hb+B@g#n0w}01bDhTsfFY7Quq5>lYA|Z%V5?3JjT`)};xRi1a4_|xFXaWqn={2VJ z&0KD8U{@=uj6ovYkUCO8XwooE+*{*Dqt|ZWOm zlQ||qgVh^%K(v6gOq`2Sf%oqraS|nAkjORfmB~a=hJRBKJ(duV0tQNH)oK=m10sGz zpbxl*s62hpEz?Sfp_=T?_ zgupDSdQ%w!;3P0j&Vs;qd=R5C9b5ZkFtM*QciZBIr6@xLK{-PxWdl+WQ5z5Ew3 zWKE}&5eSt3>0l`fUu}=X1jOf50ik4bf{23Pv44<#G^H>^2p{pWVD}~o3W9(z`J7G_ zR8!~Uo=AY;qaKce!WIOK5d;uiO@SdK@%g#kPLZ}*C2=JQoK5aWNPJFUpg@S#j!gk| zOxzz3azlW8-PgS=^Zx$!cUiZVWtsTxuVLNX-Q8WWk^cdHj8JGE0z0Yz0000u diff --git a/TMessagesProj/src/main/assets/emoji/0_1295.png b/TMessagesProj/src/main/assets/emoji/0_1295.png index d01916bae9e8ac7224dfb8becc2214b32cbe35f6..a040b20dfcc57dfb2ba10bb947225b5246d5670e 100644 GIT binary patch delta 1408 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 T^O?UX00000NkvXXu0mjfH6Il_ delta 2445 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_13.png b/TMessagesProj/src/main/assets/emoji/0_13.png index 73b2bf2435437d96b998ea818507873b4d3dcc3d..71fd0d7949a5605f2fe3530bfa49bbc351a4fdd7 100644 GIT binary patch delta 1532 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 delta 1468 zcmV;t1w;Ce3eF3VB!7xfOjJcja7?)g3Swems8tWaZVUIjDF4qz`oS;% z%Rm3pP5s9>=%Nwyv>@-S7vGi+*o+O%e+>WBRK;}+ylD;p)qh*GVGMhFdZ<_o>Z~b? zi;Lo+asU7T02y>rPE!C&aZ>r$Bn}=r=543DzoLZj)}Q3fi{0t(hMJiG00i1eL_t(| zUZvOBQsYVt24Fj}V>=F62{Y<-@s^GEf4w8M8%%O+n9QgOuA+}$Qd0%dM`bT@^l!Cz zN#1%Oj2Ga~$tO=sD#W?#b&^X+yX<%d^Tmt&8Rh%8O+9&qMs5Y~$E!-_L0`F3Kym_kq2 z+{)AGR)cI#4L^(%8{o~YwW2wZ5j|DK+M4~5OR2z~oe?K8w%^@n_VCE_ zJqT7+3V-L2aPBm)Z;dS8q)GY^!eM}_0(ruMb8WpL0gXKODYwM{%+drO!^;Cv0c)z( zs>T~#ZFz5$<#LJ5+a2tRfp{Sz&F+&OvHNy*@Msuk>^>`YT<~@FbrYNPktmi%iSDX{ zaq|Xp%owh>bIlop`^_vC_vd&$tegdX#bbB_6MuagobT3}Hx0WL(NyJ25Ny|iWYB&! zj5mbkrq#IUM(y({V(z$Xsv27*uR9I?VaeOM>J4R~t*oNuuBVIwKY-^j^7Lt7kzxBB zP_^2KQzOizvC@X!I?esFZpn~HNQXHT84NWVMRKzr-$#}&H5YCFDkSbhgJM!PXgJj9 zwtud37N-@HMl@eqrMlW1&4Pf}J^G_?~=Z-7528Gavw(V!tXj7^fQoRPYvH3S12CC8o8Sv)WpijUqTKho2x z$zWj?OvIfPQuZkZL#WY7qGG8P@6c$PV9+rH3SVNN)sJFy8I2iM!M%Yc8!F!%1b-g` z^dXuwDjp0ROnM`f2SN-*XPq)`XBt5UgGuR$5Q2a(iQVNBza|=u${W1BT7^b46avFC zkQg`aayZq;_{xM7%HSZAhVVJCQE}l361;=lK&;1s@JxLUYGI5C)+;g;K}3LC<&%c% z4MF_~P)X?_78oM9)%*FBv2s@F&VPXtRP3R=Km>qw+le6A%4y|VXShd(V&sJsXmBw4 zSWFwdYMljjhlEU$z7e9h(aWhEWu<`(!?{8xd_7Jk$jGN}t8LX*Iv_)RMhSO$og|`s zRcTk(4iVtU@KC*iLgR^V{}#*U$DOV*2qFf690&>`pG4__X=JslyV^Nakbj{f%Nwje zi@-U4sC>Tq^}DJ_A;%7e=#R3E{-m;P*VdJHdgEgwLx`V^W8HRLcdo-;21J$79}>mR z7^}%}147CZe;St>lrrZt4iu*G%J>*lFWzEDbsY=?240KkiOQE2z|_4FZiB*8HFuc9 z{_YKr>`{2G%JuqC7OQI)j5T#0JzZIb(BjvbjA~zI(cjkm*ZKExHP54esC?uf$NvB^ WBJ$dv;H#Mc0000s?rB_NMjGetEl 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1301.png b/TMessagesProj/src/main/assets/emoji/0_1301.png index d41b51735de1e7b1b396554c9698f906bdd886b8..0ea5048353bd77f517874c12dd5a8a41f30a5c59 100644 GIT binary patch delta 1346 zcmV-I1-<%<64VNiBYyy&P)t-sM{rCeA08zh8!sp(EF~o(9ULbi9zZ-h&(F`CoSY{j zASfdtn3$NpzP_58ny06yAsrlziHDPuld7t!kdTm3Qc@%v7E(SnJS!tHA{rSL6GbvA zVpmotBP2~YFj!7a4-E@AGBQCrI)Zj=S3)<<&CM_@D@#K|vwyO&sHmvX(b2-f!Ek0? z_4Dw%kW`{>D!aS8TShz9)z!zx$KcGXdp-}10000MbW%=J07&S?C}N)x=KFruI_PHL z_5P=s^XI;5G?V}U1WrjrK~#8N)s|^isM z-f!o@pjPOIw||>~@}IwfQO*A@A4Fj|w1m;Xe_Y^4!)=zuaeRtFww;8*gJFUR%D<77 zljspiRQzGc;w;-1!@=EC2o_r_IJE+1TNc5+O)RKZ{9yn^bWen^EE8SC4Xzvlrrg|- zBP!!;lT(=ilr!6gvMdX)cOC;6vO?#{me1VOmyQBVMt?nR47WTso$F26))u@qY@(hJ z1;;KZ&vn9ujH_%YCfzGFEID>T8V=f^u-=%YaU?-^A0@IE8`4&ixY`6e#(fOC6#k@S zLqb|AI3W3fP3J%dn*yLf8{;HIPN1oAcz%z9Lu)P5G&Pc}McZon9cj_EGy>Z@B}7uB zym1&J&3{mvDCkloJU5+FD#Qw}l>i*aigKObqX3$eLUn_vK_2bqyXaR)Q5)Vt|78d(Ltvo(i)2NJ%6n#rCLK~o+~BcNu{Q~JC&eFtAi|8 zd47EswISZAQsi_Qr%)urQFjVO%DkV?3JY6Z&av%9?7j%!<>g!%D8g<d zuV3e?j`4Xuky>59K2FAv3VWVfq!cFqe7IaMmt(bZjqJa!*UQ%~Mk7iE-3s4>0#l2t z>VI^47tJ^YzE>w91S|R;;X`zi@--Ipl*S6Aa?goJ917JA2xy25j}dt+aVSN2&^*k*BcK4@yx?&GuT!qoWPcf2 z!Q&}h6WHYADMr)T%dZ5}Y_7`Y*UM~r|1|vB%kmk-1q-aAJdOAJ@f@0a1k;!0atxNs zWt9oTi1>NG1F(!=ru_n(jv4RS^Nfe^samq&4X~w8GJ|0EwgXlJ4{Ruh;K;zT-_K`V z8O9K}Lt&|b&l*0N^%0Ws^tNFR!+$4ZB@J)2V7*=+@W+n%&1>_@hBa`O8kYb92LFU( zb~6MUa8zqyK3QPR2MarH#hAfx`1s(XoWQ0;gWo_IH1@~e;&mV$&vSa5chHtJ3Ar1va_E@ zfzcnaJG2HTXu$z*ION7KUZ0-+eR`T>-^J4$M}SuGAHF0CbbnOb+5i9m07*qoM6N<$ Ef}$LDlmGw# delta 2304 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1302.png b/TMessagesProj/src/main/assets/emoji/0_1302.png index c3599a7a33a7480fb1131cb4f69efaaad32670c7..b441cab92bf8bef7cee3e1804ad0dcd190ba5271 100644 GIT binary patch delta 1613 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 LNkvXXu0mjf2NvXC delta 2562 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 YFIy1txVs*je*gdg07*qoM6N<$f|=l@ZvX%Q diff --git a/TMessagesProj/src/main/assets/emoji/0_1304.png b/TMessagesProj/src/main/assets/emoji/0_1304.png index 8ed3f87557c2a059e6648a140a4d7766e546cd16..5102be1a6367524173cdca7cf3a3fa12fbbddc62 100644 GIT binary patch delta 1633 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1305.png b/TMessagesProj/src/main/assets/emoji/0_1305.png index 716657d2eb6d0df29c732aa3900008323c655236..0a7dc18af4a539b2f24ba7a69df1e8c7fc7ff517 100644 GIT binary patch delta 1478 zcmV;%1v&bh5!efmB!ALSOjJcja7>3;H${5CrgT_yT~$svE_zZncWY@|ipYOcG-yLE zIA^ADNiR5Nq>NraC@wuWW}`fBvo&L(YDF%JTs(A0Dlb=!6)#bjV@$S!VQN7ovwdE3 zM=FO{Ihklnu6J6FT}F9NJ6tv!Upptfi)Np2Q9^aNxrSpr9DfNsZLP+YY{QajNPE7J zVn0oQ#8rmIzmI54DG)Yfpny>@&908VntAT+>spG)S%<_gSdPuTuu_7-8vp>|*37Jp zcp^V$V2;Y!$+wtk3$KI^%CTF$m>=BrQiT8j02y>rPE!Em?*26XgBtBu<58Tau>9%Q zcFNNA+@k9&sDDMV000D>Nklf)|GzX< z_k!VrhS*={iR2hh>N#&+>OwsEUvSz^0`1d3613xs>((UDYF)?4M>WZXm}FU$?U8cQ zirXJaa3Lht9Re27Yb;4xSTI4tIezK_&4DYb~WWM`E0|1m}ygTv&=0 zQFRm?0FRHo8xYunqg>{B9!S56%B`Zh-ihrbjw5ZjL6oPY{3qBfpg$(myRKXNo z98ttUft?phrNh98MI;4RS`ft-XY~V~P%A-!Z-`%kont;q=finXct!mlX-5_m1!FpT zaW*S$4lg_9Tcn_W9l5VBd%H|x!Q#OK2`Ue8HE zGH!HSKU&(Eh!g;B)ZH!vM~Z_2FzJjwGJjfv^2`rL*s5T{7r4UKSK66Y{b;p?qcSMa zK@GE!hsKqj?;!Tuo0 z6*WT3@bnB3dVlaJpEyUkF-E|P(tqB^|BdK>y|mWtu-10I_PeLe>-*<_-{0R~UOL;c zJ35!&2g@(#{YLB2h5Eqv%Z}RthGjk&prw0Uuv{+hmpcbY5D?rC@_d}upswd5CF@UZmj{r`oMbzNbUvGz_`}Y21AYv&;kdZE5po#j=$cWk$-bAjK`0m z=RoeAJHag+!O?$j82-xh=_3FgSB!mvM-TwvG|u0P(ap!x+1(vVAWFqFL z>MH}}`1Iy{^>gfZ2DKhgR6p%kUEnPsn|9ysV+Kva>OBU>VfEoM0JGa^|4qfG&!0be gKG(3jVOFi@f1Q#tSmNtnFaQ7m07*qoM6N<$f?@-@EC2ui delta 2192 zcmV;B2yge;3!D*h06&?bhq=&*$pY>+RL*?bYe* z(&y^T<>=Gt?C10K>DBA)((3Kf>FeI^@9FgR?DqHQ^Yql*)#d2h-rvvY z>fPqtwDRq@(#5dNyrs#smgK^nu%D2)n|;EnV#cw8*|(Lkk7}fXX0d}($De@3m2=tR4*&oM3rR#l zRCob&&IN+y$PNU+NV#mc2k(E)kK6E^L(34wD8=7Nh<}iuOZ6MAzsO(KiA<6bA_(trLUl4P5`-8{fb65P7}KdspIgw_)9Tw{_f)m9_4mL;?dz zGD*lz@_+g9IFiC!Qr-;m^nQDiV^%VW5Dbze5;I5VaQ^oQ0$Mm;z?_dK(Ik*aY?4SM z`T2**0i_7x0W|Y=ylwaVyoOBtoIo;r9cC7Y;_7!mQ~PT|BoK@UlgxyXIo+l0^_8!! zRi!CCJ~)~rf-ph8+qce<^W@#TRxh@1Tvt`Ah<~5L3IQ=7lD+eECbu%z^>o>Gcx(=> zpVj(o2=Zf1B(Zmn#OLQ9(IYy~*laJ?{}pMZ{vFZ)>Chk?$$36pyCvDSZEf%0e>kzZ zE*GU`qLKgx$ll@PC%au@v-W+>y*^-bT&}O4-oL-ze>_=|5oGz33!~Yeg&97+4X+o~ z$A6=9``_`>n7UKO?>ztX3{pHTz^vom-@V&~Z7COBk{MWN^mRwI;8XI`rjaEkOEL-il8^dJYqa&%eow=e!uG{U}v{lEe?xW z?i!|##1M<@0!bkV6wK!RwzbXKdV5~3SGfYL^5wLc-#=Lilwl?mfIc^;607rlG;_M7(3j~?Knd=%O3o~T&c8Sh)` zo;@6GARqu)Ku&UulVb(0UVm|X`TS+Py|uRGs{ZWx?#2C^@1sou5)nivBY#5@nAvuq z`=EBtuW#9c*LG{hk_Znf5E+q50HVtw@CY{N+O}IeR;yo?o$Yp#749!M9PcH;M!)mt#Y-dP_K#_9 z0PeO3&b6|XeQW2lrI){&z<;K`xSQ2yM==0&kr5F9%xu@#T%Wtj_F}^M%o1$0GPCE@ zD+zQNBK%cPs&-ta^RYIp!FJ)qc}T4QB@*BS2(am%RBGKH4(F=YqXvNi<9LEZmk|MQ zG{@}48rLrdy|D+7hZ(gMSnM-fo+WgV0gxQ#T1`;G)L%}ZycA|}zJIe_IL?N;2SArW z;M`3dXPk5&{HWQy+3tm;qIuweoqozK+q8pQ2TQT3y9mB@*@lO08U=- zX}5LMs)Ak~t^jVTENWHh69gq9LWuBhKJ;$W>fcWO zmIfiEh*ojK&EIvPB6JYZ)rb<&@qYlH>;BP~{qq<7BhfQT0MRPoV~jG}^b3~LK&Ki1 S&+h;L00{s|MNUMnLSTX_KZ_^; diff --git a/TMessagesProj/src/main/assets/emoji/0_1306.png b/TMessagesProj/src/main/assets/emoji/0_1306.png index cd11a77a5a21f22b66e1f3734a7d75439c429065..c4991d7711fcbc8cefb19cf4f1e0087b7ea9cadc 100644 GIT binary patch delta 1486 zcmV;<1u^=!65tDvB!AdYOjJcja7*wRQoPXWb&-C{9wTl)sUzuQz%F41^)s1$O0000ObW%=J043pCH-Y}`RTZ7? z<)^jh<IgQC}%lGVh*$W z{%^GBc3XhAK$7?G9H|Rg)%Vl6!GRxtggVW(RW_I&g=j|$4gg0{v{iHAqyQ`$?KLOjCsoo0@DjARuggt z045e}l$e->Kmal(%6lag1PBxNjgm^VLTn5agebu5FaQ~!7SCyS2D7FRzNSz@GcBTc zAmCncCV%}K$~Vin6u!dXm8V7F8e7=cPCYb%uo<(nm`f=V-#7CkflO#@6j##&LAtJM zSuV5FG>ah~bDT;h6{A~i>1W~sE<6D zYjGjqIPeI7m8o6|z?qG?X%`}lu^9sqQRa+A)2&>FTet^=Fn`qw5p9jI(9Y?I2wD-^ zG96jyu`Pn)_ek@|1j2GR>1H9sCTCcSY_XB?##IQ}FJc(>IDm`AOE|j@{QI?~d$L$1 z4}Uj7^1Mc?l7JsIi}IiyjIEzU5CqBMMK?BjUio;vPTh*S__^}0#?#9F^D z^hm6q;>4G4tJejy{UAFkt_2Uc?Jia?Q|s-Yrt)o}~ z;aZFP1J0~F)kMk+Hq&0I66r7Mw1&ahFN*ab|RNV$NAQndw#jXV|Pk7j5B=H{QoHW$W^Dl)VUKp5w#ZO1aRGy%n|RYG(Is0K0IIOd!dw`{YARq5Bqbk6i!lbmG1^g8T`*EWK4kAjfI3}_LuwPmRRBe3@AvcD z5E4c}A*E@?F~3 zmX80K?%>VNMz)1bULmKm-LL#?Nm}fS|k%uRx)7p>xoL%S$XA*l_lZjRrQW z#~?(z(SLFP!lAz}FTrShlgEWadjJ_~IdnSEga|5LYclM8Jyd5ywS^cvn&bo^at1Q_ zG7pCUAZP}vpKCXsb{&2>Uq?SF4+@^_=;`@PmL#Q*>R07*qoM6N<$f-@YLt^fc4 delta 2348 zcmV+{3DfrA3%3%GB!B-+RF(?bGV))9LKd=(c4#*X!=*^YrWW_w4rf(bCPhyR^Z&vBAQ;!ph3j z(aXxz)z{J8s&AF<^pN2>|FGD01F&7QBy}Re_?=J}i@AvoM>Faz@3-0suqk0hS_4efP^SzrS z#o*)0jpUp9#1TSEQHjQh&*2&Wl7ir1(1PPZb6_U zH_SfxtkD+(3`h+Lp+%5-7l{J}gd9-8uWgQw>wk_@b@g=y0jz?e2`Vw9iy%cr3N3%3 z`%=m<9O?!|r3XpS&JY4!YJvpuaE}N?2oVZNl)^9o-4;&MCzjZ4XEVV-n0D1Y8M(=2$1(Q3Q~Pw3O9#(S!gf zgMYDrEQvJ*YsvsSNQ0K}3`)zA&Qk}-B9>GRW~jYDA+c(FUK9W;(NaoYPLuzI87Qxi zDsvt~wHgRM>Fw}#KmzZo5XRVW6>J2hfVlp!A%g{;1O$Pw{NUYN5hvDa9(|_bibDke zEi(`@WDDDJp3gl@kL@$k6XI?JWM0`(p?{k;{4N0cvk_Rr8NgUmo=+kH@?$p{EV2N2 zavl@YB2W|NTALB@=`GK|>P8)g!%PcRzrP=Kf?v&-wH3BlW{Cdf0sqiVZ%_FKd~7r1 z;eG?&`vyy2C_yve@_P0F9+^5`_xt^GM@#?PKR>^|KMwE-GE0v&@Vy`{B-kF($Z6qtdtAG3Y>3q7NZc$y}NpSmjUZ<$9Qk?bw8_D zl&$%E6hj~>Lbx}sXJ1B$*?V;xZzb`1+YAum7bhbKN*4V#($nHb+fF` zo}gh45``o)`)ZlRzL^0xVnb2!kiDtd7uZBXc0kI!1o$s51h<;^i*5nu%{FCOu-=EI|yL zv?a*!rV=TnM560LtxZ_h(Y*cOR!tad-jRqh6Bho#GzkdsA;>O|8Q^yi7z;g5KN2|K?t`*zR;(M0jT9%XIIYd~z~v zd~gba3PKbiASQtT{bGn;U1U`4<>LP?!tnT{l))+N%@vNH9UY>C;8_nvfPQE!qC6U! zsHV57Qpv^Xrw5-Le7wir9tWBL6yaVV^%{-#;3RwcTMZsppDZuiWi)%F56nk^Lcnjc z?_nOF0hFw7K!3-0a14HB|4 z*H;{-B7fo#u#&i{hU@@0O*HO$q}dG3ILb`b#R86mLIC&>yE~tYZ2)7}831hZMVq&- z7y%`M`WUu9WXDT`R@YFWjHw%y1CrVEcKl#R+qSYE6HwfKy;TGiA6@LY*x6>gt19qh z$aDfovoF5ZqO~RPjEJVX$$0i>VFEDgaqt{!A0_jbnI6>o^@HyLEBreBe*7PgS;@e; S4_WL00000R%k##ML1`s zIA^6cEh#l)omZ#Z^EyTSq%t zL^%)&2ups!X;@Gm8yiA9J3nx;HZd_@jmkM^r7&8NB0gm6>3`|X#k)=;1bAarsG*-k zc)VGO$AffiPDVz>uX&|`PoHlKk%fSJY-hcd9F=P^#JnHT0000IbW%=J0H$l^QHta3 z95qp@$>ipC*6QRhG|m731N%utK~#8N<(KDn;z$riEkGEN-C0@W=rm#X{oicsQ>!&I zYmmhL-P`6^;(t*0d{x~B{Pe$I6bvlE=syX9o;Mw?EW_c{A3UlVc&m?(j~qXE5UZgd zJdyx{udKYzlHTxNrC2t}prc`hvfFHWow}e5b%kBO(;>%TxY?liPt3+tyaXLG7;ZMJ z+XmpZDg4#Sq-kMpr6_>ew8R(NThVRh=S;%AOjRcoH!zabc%OUNQAJ3u>+RU(XA0hAs~tW zAYph~%YQ}%n3_UR2#zx@jjS}9uCb$vY1O!?z%$ebV^YvaI5(9-VK>nsDX5b{qr$g} zayuBSdtvAcPeIXdKH$9qiij2?Nv((y7SS}UV%n$(h6P88nB^BC^0;!a3wzI{iWwBC z^qL$!yh7{z#F9Kcf4j06B>CxliPH1u6$c}gFMmO+LS2t4O-XUGG1!ljNK=0PJjPbh zlwzPnDwVz-FK2Q7{&~!;;(APQe>&!+V%j*17nur0jhw!H|LgNurAXe7r@wLk1LuNE zukmy)B^QcmmcL&v@44HODE>+JKVzH=Aw=`hnhH{AMnptnAqQZDmRyLIqeTkrD(Ydt zA%Al!NE9hB%?1L&xl_QP7-@9m6k1Wrwht12iB6zE3?(Gqx>#I=&{FiLtsiHjJ}KNN zGzTJbAxPn)jTSs1D+g6!10<^q=tCew8$DrT01U$Z*}4$R_7FH5RSck{q?-sJgyjBH z7kms<<7j9EQc@@wG_LSo(K&|3{H2iepnu!apl~p|F%Z_Fk(`jYE<;Qq=-LV#8r>7P zv~2`Wo$=r(D`5i486I+2i4%}v@bnPAz(8uG5KCluh{2MRgiz(C^zokiC_PRH3+LYB z|3)mlKEBde=&J86#-r}_i^*)i-ye$fH_TzTn@tv-<}pS+I2;Uj0#1h4^?FT~aeupD zzk|R@3hIIv=CEJC5^Go{L9=0J*_VrC2e7w-EXzvGY}{m+?RJRkJj5DLz>pDP7-r3m z(ToIDT;L3dfcm!(WaPNJHxm+Mgq5rv5Lm+-Q92g)Ld?k!hE>a@hkn(98fs>KC&rlK z(krZl7J=$g;1t`p?G}#loj%C0b!!esSl4e!P!VR6JAIIWfWsC#YD4XKLnpWT2(1AQ zSBnK)xl_E}JYNe^*kVXrslzEMUpBtg$0VaVOc07M^)5tM?eF6DD4w66=frap^Vd0E c82*~)Ka!W{#b?b*I{*Lx07*qoM6N<$g18PqHvj+t delta 2257 zcmV;?2rl=A3f&QqB!Br(OjJcja7@|t_S*3B*6Z!l>h0C*?$77y)avcj>Fm_$?B?_J z+U@V?^!Co@>EQ73(&_8c=)r10y|}8J;OXqfyRzu*@9+2c?eq1;r$652=IizL z%H!tR3_1F_>KoCUX_nM&0{g3Hv34h7c3p?QKlF0CXH7&nILFE0P z+e_Si7CJ5B4LUYYI75bYH)v$jf$OM8A1-W&v6T{4uFG|aMR58Nn6&N>IRRo{% zaA^zKUW-|P{NBPU7_rkGPbbe*0(xMiz3<38|F2Opb46kSVigp3t;2QH#qSBC?{E9V zRd>6vkAL;`wZ(f|iO}7?Eu&1JeQ?LEh11oVIHJg%P?ABIP%28)MWo~ ze0eSHI2%Ahw#XuAbhp^LkI_ON5gABwhEf#Ap|CxJuA@*FLuSF99xmn#CLaPBHf_lniRI%2Bv;|SEljL!mC)EHjK}<|j5=lwm2CgfKYGD-^ z@)Qba#Qe8GaM^iG&@G*^Bmh|#*R~#2HhtFtUDs(5c^_DFNX{dIAp*8Q3hz;r_AR&S zm46QYl~or^vK!q2hM&`F4SB91%xJdPsdc#c%SGpTP!b4TrUfpKt$7uwn+`JOQ_OP_I$#`ash$VnRB7nNS5q@H<`@?@ce?{0$ zXpG-;9-8x?A2-N|eD#?fL8d|=!GD4hwcC}=@W}di2hG@~VQJ5UH{vQXqy6&R4q_ye zLIT|ce951cj$OW;Xrq?`wpsUepMVHt`ac2B$TrUVd7poM5P#MG*)#xP znWnKtY#PSaT;%8hdc+21iHKAJ5M%73YF99{!+2O)GHN5OEsJ^`gV+dv^gPcXC>ij- zE@00sNsXaV>!LNLMpYRH{t6fpAy6cuU-IpiNJ^94#Wb~3=sg} z!{0$&a=sGR@WP9YlQN?G^^5QskhOvO6*EMB{yt7uj8`I^Lu}ekrEvS1zGg=zYDNTb z-eaj^d;Y7RGPHta0MJG_{X85`2|$$riJaFzdV5h5q^&i9L%)z}+J6OZmtVuTJ_V`( zK}y_VXD$7^bLHGS_KT5`f9$zb+yNp`h$q6=zwMmE^Itn5Pk+OJHjK5tw(X2YxPQ2V z8vqeXfEayLqFn~?-qzn1E3D58*LEv<90v~-HK_!H7iCtVnI6`@S{~NDd zcew)K(jUr86UURI69o_j0l^mBa=8?Thb|&OxLhyGL)mU#`kx6nmVuAH6M-5LXaNGB z-Cj!R^UdA8!wL*nxxUzy8}5!k#|6 z8UO|G?QGTz9)AvCvkvUeXRwxXskPwe+~Vz5MG!&p6%PB}JDkqLaJD-mA2&CJLQWR2 z0u)5VsDRkKO7th(D4k)O+pV>iGD9(!yjy^$`;-*m>mLCxmkU6Y&5Ffh9oCHkDC671 z0(K+{0L06eBYzZ_K5#l$RkgdE+<-C{oGXq%M1cU;wO^3amx@wMrSwa^JfR1`zVz3b z{gG4fDWOE*J4(T;N8SSkZZ^wsVYfRk0bK{fF#JA%h(h2aP#u5bukOl?fO?lp6 zjSYKxSG*45If_65z!|H)Ejqw(MteZS;efKF6MANvJBdk^sY fFYt|D$=?49u-!7?Xn+nCU*MAI{L;p^t&Z?CWCz{isq;t z*O?Qrat-jcA7>>~pF^vfKc=Nhu#`KXj5V2rE|7UAh-)BxReu+1ZK#`8u;=_p zsCvNA-(A$e%htud=x+}`000HfNklO}9{%^=NUz(qAb;K7zXQ6X_W0&ooymA$eVOUC zzb(DRX7dxWSuDJ?b2Iu9(rrIJEj9p{)QY$4+*rRZSd%g{#LxGEO8SFe7QT5;GBj=c zL)n1Q{>3gP-sUNwPoB4c80V`-@5b9Ko@5aB)1`M|zSK)Q-2g!qWo5sUE)8=j#~7c_ z)aoqY%72n$MTG-MCk5uM9N0@b>3&9xm*y0dJjfMA&a~`<0!&&n9_)7bi7@KGRcU9& zrNr16Q>T2-EYq}OeKN}wuIZPEOHNfTg)^Oj@;3uQGVXmiiGHWwFUyiqs*RySFd&su zJMi)7BVw48Cev8zFw9^eSWn9u0R>V{LAv>%jDPNJ>6n{AA0a|WWTqKZo)M=CSRa)! zh^m4eC<4KKeS$)&@NU{Si21|RhfJe!@A@zu-w;evF*8=-+XyOAyC*9F0N*3ns*9!}dI+tVSm%_#}EAg1<%ba zWO&WPWM&i2&vns1b z`89$u^T1S!UCM}vKnS@NQ1wAU;5yb>tJ_2%AwbC}rclPbMhX!McylQN=D_1P%fe=Y zAOs4_RmfH1V#wMsi!gZ; z03cPa5q{kY7#R;VDGC>q$TcPSB$hlA!U*P)=4Z~ZC<>zxWX3_2guOuA0^&1x&#NNr z>P~(m(Jn5AU@?~p%M95Dt$)521F9JiAizae2&?6~aLby=xC}7H)&GMGl=+RrHcSzP ziTl|2{2feM4txkm)k%QWTLSo@W|+h;TuAHoyLIL3%(6zKLHqmN-TnQ;gHlq`bEHxa z5BK-?cXxNg_F!ba>!Mle_5T0+AAkO~qB_p97?Sb*UyYJMZo?oDMSm-AY#FgJVqvd> z8H1}x>DtN>x@wjCpQV3>j8j#n$&!^5^q*8*)m? zSl_=OXq`2=0Lj)~up1+@(8npr@AEy@1hWHdoFUz~QSUV33$- zB12IKYM8OmW2)2`*)W5WmM#zlp$OzRJ1P^k6cJ&xvm!=u0CCvkdrTB&1&#Ge`{&^Z zaXNfpZqX9E!$Wc6(yGuRx(hrXEIJxSI}r~L+brGjo1k5Am^erNa1>3~ hHB47$Pc)Bt{s5q&+cL8hk~;tZ002ovPDHLkV1h^ygCqa| delta 2034 zcmV+aC#>eT7%-0tz;@A1>< z>(=Y-<@5B+<>=Mw?9S%t*zE4t>+bFL_v!TZ?DqG;&(Ep1xU;ypzQe=D&(PE0;@$4> z(AnC(#>S?tt;f#K?f3ZU^!D!d_R!qkoTQ_bnwpJ|j(~-Rb$@txX=-X)T3As{Nk>3D zIWa9D9vyULV0vz8Y+Y7mQ%PM(K7x33ii3c-sFsp?Z#^9nu#;uk<>%z-F}--{X#-o_2(TiO9>c0000*bW%=J00j#aAS*aWRAh62g^rl0tGlY0 zpvUC@|MBF;(SPUv|BQCD|Nj5~|NsC0|NsC0|NsC0|NsC0|NsB~|Np=L|NqQi=;zX^ zo=yM&2AWAkK~#7Fb=7B6-FTh_;OG3WkN}72K-cw52hS$E_A9u*{-n2?bEjJGKtl%% z#z^-{zlE}@*!bM2baa&C|B?_P2r0F`{V(y~MIuRnkbfjftyHQ1KO%CkrAeyL);L)< zySWzX&Qi*X&WhZVcIP1Ms~2K@-L!sMO5I5fteKZ=}{1Jad<@c+~np5>P04|Hd$e*q(}2LlEaIL?kFl zyORj(0c&j-O7v8wkgg`Px#QiM{2q}OAM zw0}Ss6%-V`h{GC^Q64gsVM+J+I(iUFC|!jTr*}t$9|e#1Eo#6xj0{RymUJQ&oSbh@ z5k*5$Ri~fi;sQ`m7!1Rp)UpUX7Arz%P~c2iye~nf-82HC&GWp=p7`%X2UP+A*;l5G zMyxV5%(E^Yq(D=o;O+`JIeEilG52` z_6L`gEA9JGpsA9;Nh;U1R2^i=+-ly(%2H39+4ayV689@w0={>YV; z&Gn(fw->Sh1&-U2AptbXgX3wOivHl2`O(n_4N#{~=GoJOtEN=)!3RrDwn3Fftbh1G za-Z>CHu;#%_khjwgWIE+*23_g2?`wkSo;9N!#w z-*pG6kpQBKR;Z#*^Mo?Qq?~oXxX)R6p6=;kz4*2+%NSU$0M$Sh&MwNIg4({TX|8|# z*S9H^vj5}P_rs?jV2r>M2X1Oiob3e)=%TLeuZ2`BIp zrn*dLQ8ET2RV)GGziCpESozDAQ6X8DMW#CxmUJ%3?&bb9PQDM&Qb}U9_J2^)3GYf` zMU=es)lU#Wt4KVc!6n9Ns%5FW&#lptj+&;I{+ZfSSX)?K_;0Sq8mjtbo|nFEYupu= zHHH_C*P@Qz|vgP=C}^9(eWJpb<%4#rGHPYv6h+=+x3}`b{?@;ZoH<0|iL5 z5d2Z4UQMEhekt+xV#3wvPx)zRrU%mUi2ex_9`rk1(oXFEEE3u&J9-4fLGZj zsPKa4{S{*=s~B^=T!kATk%-U;`8^IobNmA1vp>D${#bhds>$v0CVz*9V>cX&G+rSM ziTme}po1|yzFbThce#7nO=^F6IP^y&$2b=92hftRO0)OR#%wm(KDyl3c$6{Y(de-D z*N0vA>Cqv);KOzhKm(jX;64Ei;?|+uGS=1b>9c2fwtdbEFaDIkmuTP>^&@ce9Bjf; zWIP1RVVBJYo`X+6aDNcLhlW+aBg$;Xb(N~INWHP$ut8qz@fxdU)oAE~*{rtRu%yaB z%y%WM{^_edpF#o+Az{ylkB%nJ6!5OXE$bIHvN@RlZI8vOL4c*E)?+Iq+iog>ETb(D z)bf?rz;7iDUIEffII|jNNG!3cjZw{zrihl{4_a_QKL{I$?tfNQJvg0~>5ji=e;KG2g#R!OqXDnpNl_`^}ckydm3lOKt-06XNw?V8V~`WoQH~lJrn> z%Bs69)C^U?t-&yay#^W{^rA0jn;A?CmMfr?%{+jqYyeFV=ne_(tBq4^V3>==&^be$ z@$dZ|2Fo74q-!O~?;kqg@yz=-ZmVhuoPoI_8T!6s)$l4UArva7QBWAGmRqnrb6?_6 zASn^(@Vi%k*i_1Mz~5}&ee-MI{Q4X8pZ>?Ee?3e)zVS`@X8#wp&a_zlCwxeAya+Ml QqyPW_07*qoM6N<$f}7|l`2YX_ diff --git a/TMessagesProj/src/main/assets/emoji/0_1309.png b/TMessagesProj/src/main/assets/emoji/0_1309.png index b2bd09d78f32f97ef089a26fe3d6ebe5e270692e..6b21d0917222a266fbebc9d4a398c1c73368c9b7 100644 GIT binary patch delta 1677 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 X-PWjl5DpaU00000NkvXXu0mjfGe0uy diff --git a/TMessagesProj/src/main/assets/emoji/0_131.png b/TMessagesProj/src/main/assets/emoji/0_131.png index 6d3b269c945a20afbb4481301425f7675d368b77..b39ae5b0f7caca464df696d70693d9d058be7be4 100644 GIT binary patch delta 1105 zcmV-X1g`sp3g!rqB!5UyOjJcja7;ZlF*q(NJT^05UteKiVO?EaWo2b?adAL4GBqV0 zIVmDKDI-ogF;_x3Qa&{|Cm>r!I!!q-G9w&BGAl(gD_%-HHzy#NDP`aQ000ZVgF2uGQqEZFT>|_C~+et*Z z-d=|Uk28cR(|_F}2vl|dm6E77X1IWzx_xqi*CF#%8v^zRt4h>3(D9>vLMNaE-U&ci$_dYe0J=y^ z89<#bL}JEAf|LMrxe!6XMtrvjxV;fm3_;ikdm@hn^DzZ8i<|V1kDHO!k-%qy&Jv|F-3MIIt#`HkwNv7o>c*%f7BN8{x zsWCng*$6fwWsqbgxDSxaP9!i>e4K()V&+oX?nH(X#7fvj#s^}7W%?AYWFu@5?X=c- zFUl65*7bPhxG?!&f_V=n^idc;i&(=56b<`GM1QhOJ5YpD3H@R^3D(L7LEw_OUo-*9 z@8Jvvs4m{mLb{$BPGE*9<(B~XaG^!fPX!E;TDK`|RTQDs``E)jlMswBSP7+igc9)~ zEPmRyTDwt-z#{x}hZ2hsN1>Otp+N56qBw8eXlEZozD6bVj&@vP*o->E9DZIsyMcb) z5`X7;D6zhB?Zi;66S74=zUeBN@f*`5E3qoE*HzdD9LuS37p&nG-ig)=B(uM~vp0ct zFNAx!`qpXZ8sT-RTN4WT8ryX9CaVHIAInM9^|!-( zK5!N8zN~(!VhIa2J{NYgc7`IkS;J1W3V-1&m89CKN9_g zIM-T5jFDQ;>vyYcwH`qdjh^E={UVt!J8&;p@-&Xmn%&u1)abbE!uIs2!sldB!6a5OjJcja7b;uJkZH$*TmV6dHvj+tB6LztQvesgLi?Tn+<$NX9gtJI|8D>P|Fr-A z|2qHw|Kb1s|J{k>97v6y000ClNklmAm~a1m zu*g1g$4>|zWc8~Vl|K+_A&LEBl2Kn1L7gCSLA+;y+apLyDs+fw&o5@1yzdTq&BrbB zspS>(rZEzCM1RJ18J_CpWQdSxzOW~^DjYk!$}PN~r6d;S`Xq;Z7eq$%BPOXc>VRb8 z)94C=j+lNSkg@N)J`fyNVK4yaZC?`0LW!`zhMC;|k`DoiJ&xJ-Z=J$t6{fx3ZetEF zP$ueQzyH{bx#n4iIiD{lGXM*m ze_`YYc4DT=?aF1IsXzwM4u`P@~^V9n9{Mn;C+QQHNk*@%%gE^VjcR zKJAK#WUY%-PRioA{LjMpSnxDXo9%x3k}t!a(AuLHw8ikn$p43NoacOaOq8azhfm+L z@qO3Xm47imJ;KwFT8AXz*-Q}w4Id`)HQ&|UK4wAmOL`cK8u`BgfYNwjvf5Su^UgH9 zov%?KE!D7FLx|#_gyrefOI?S9V8Oi_C?q~X9u2;k?wyQeZ_$-&-HeRz64kKT03QW) zK|{}&qF^RKPc}oNMy&&)X9>BfzHw#92NGFZ4S%Xe(hcceLe?1cjqo=0hQSn^XH*0H z!h}JM_}Fs(UlOtw`^IG!1n=Z&fEqV7N-NeTuU!QMnY#v9S=6{a469iUc2NM4fUk#* zjFTFi4Q-(I60FwY77n%;kP-_KNtzBycoRO4k-_ORn~|y!k|?1@kYWIz4;CUJz#M^O zZ-40hC_=6$2SI>H-VTUFH}pv-`7i>wYS@})1SA58ubsR{LF=L(pkjoqG@}WbXhyG- z1U7ll`$w&gYT#PLS_jB*bhQ$pcOQ)#B}Th5f*KMJb~4S3phlkF+Cj)^LtO<`U#(GVkhOIy3iHc1|B-DJv{FP%WxNnXvTxXfc=f`#r|2GzJQ?&h`9f-?_hg@0>b{6yk}1IsKV&b>91B zagVvcW2*g0>@y`0Nq%vP$P=M3oN4|zBNL%4i+52GD51{xO#Sa)h@u*sLOS1NbYf-! z0@sYXo37BwB?_V3o1sWw=w%#+^Eh3f#?YTbH>T|OUS~Rwr+?1nzTB_x7xn%*#+a8M as{RK<6QJ;0X}*;J0000wRVaC diff --git a/TMessagesProj/src/main/assets/emoji/0_1310.png b/TMessagesProj/src/main/assets/emoji/0_1310.png index a5b61a8b0cf6714941654c6e09f613c3c18c4622..7d519cb1ebcbb7a04c47a2eb454016f660eafed3 100644 GIT binary patch delta 1788 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1311.png b/TMessagesProj/src/main/assets/emoji/0_1311.png index 7722678605632dad939a26e1ffab67293c9e9c23..1d7f2c70372fc5150f7cd5a6bf70ef2a47430ded 100644 GIT binary patch delta 1701 zcmV;W23q;;53~)CBYyziP)t-sM{rD&X-94*c!)HZ(WPmpdQ7W$TzXC}o%97DHL{5J7hsDiC;#PW=uXJ4PZGOo^DgPhGH}w46=S*Ykxr?s&rUwNHcUtCBBVk zt%q>Mlxk)_5W1U(!K09RD2d3IZe279Y)v|(dt(s}32tIo@$&P9c3@~8c(jpyb0veN zO0a}3kfEQO)y~JexV4=@sNveviG_oeJE4pt$GA{BIDk2hLv$ z2MZPP1sJGQ$if~q|8gDMi#ruXYSF)gj3^&8E*B#tn6k8>CG!!ZY41jTAR?}W34(MH z_Yoqe561rWaE|)W*!7~w^XGtA3rxBw`t>K40dRt=>DP;skq5%2Bu|~8Hca|^^A%rg_mtJKMgAPQA zox5@-C@z;=YYs)EuK=l%&9lrs*ioZ(mK#qv_@#2r-j9 z!~GN)ATkl6L<&Ny?W=Lv&WT8v%!GyGkOl@3mVXGNiW(XT-QBt=P8SFva13RFG!EmK z5YIydswk*|h&tZ7m~H}u%RCN3I2goXiD(H3PN)>M$PTv8;U{^{JgH3_8_jjEM@Smz z<#HJ@KY_*GIZ3PQLzw4r5s0}mHXQUIAu?8JJZm1~zD~4uw@l)=oHINNIyH7MolXak z9)Bswq(b6plT32oZPydW31eOaga~`n9z4Mygp@Rm1BC~LG0BoGr|Zlo!PCJYG^^Fh zgq4BcD+>kVcx( zVQe)3^geD4(L#cA4&%U{ggsh@P$+9vS_)w*I0zUouO;CA89W%(00VCee91+Kg{VX( z3xUa`Sx@*FCjY3BsQ`hp1PUAtU4KgekdRT68-f61Fq)N;)Di6@Px8DpScaeA@ZK0Y zRH^Y9oB2tZdLoCAF`Ug9%WVqpPod9o=rEi4LjZD0MN}ao$w3%`F=M`fB7a5F)aDF? z*>LzlFSteO3gD(4TwO&?QZ)+(mX!9zP`FT`S$JG*RR9O7)vow#Q%zc7f!CO&yM&1 zSAXaJE_9qy)87b`O>FMoca(~ge!A0C# zpwT(M#Sk*bB7yn&bMlCp+@E(E`&u+QxAzlz+!I2%Mc@a7l#a7oIG;=&i%X$+kx2=B zhafXKZ|oERpeso!QUR~<_`ch4P{7Mdg;D{pufO1l#>Lh>?T|nrrGH2TU<%`Ai_p4w z{6QC%2r)nrKm-MiZ8aLu;n%~%10fZIYd``T5BNG5jV*JaKq)F$A%TpC(&%iN{1aW vR06oiK-|<4pTB(h3?BKiD|7{3Sgq$j%BG+n9kEL>00000NkvXXu0mjf%!m^- delta 2016 zcmV<62Os#f4ebw*BYy$8P)t-sM{rDmD{#MTeDS5_lvG^usqCdgj)G)SfK^h^n{$mz zb-Z$L)MUKxkKUJ3ec!i{gGFpZ6F|L!UZ74}cQIi=C^y!oe^4PhSsF^(u!(m%VW2jA z^?%dOnsmcipHDGDl{9hTyOra?oXTFHV>eUCaIID+IAt(XwSRI+>3hlHXt%E?ipYv! zyLe4L6*K0Y;niufxlEL&K6l)*i`S=sW;jyHPnEz&hwZKuS=R?5h#-5g7O!Q#U|EBB9ET+nOi**xR>9EDnP@4O7;^d{V&~fwY z0000_bW%=J0R2S%9sd3W67c#h{`vmz`u+T6Lo)IH`tbLo`fq?`gYxiTuKbA5(BAy} z+_tk#o`12$->~iO)YS5mk@@g`@W#!)?8g1@Y~7{Du($o!h~Xd8g}Kk4oqr=UtF6uT5&hFL5m~RBz$Spmea>a- zCoE5)3Lti8>L#E~M9j%m)Jgo9zH?kfd%Xl|Gt&Uk@&pKIb7r+}!Z3`8xm^g++73j0 z#_e2At)jsUioU=MRpMMEL%zvtF_E>}g%__%J`mO^CavE?$rLuWMl zm!2^^mubDkO6~oQjmq-IqFaY}IJbL=mAaqi6O}~Lv7$p@s0#N*m3O{RMv-9Cwr?4K zHIAtlD>*ZEK^6Ai&5cS$ayk~W)$LpQZ+}bCT)%p;po)tG2MAWDV<{USRZ_X1Mxs%3 zVM314U%IFY%j6xYvW$e4t!HuwOK))_nn=zr^1 zmz>MX)(8m32l54+hfBR#v}NO6VS=GP8Qc?&($RiaXAG?Gg(mnto>ZCzjeo|QHLLjZpeo=nBNdAyww0Cm zfbJ?Zfg>qFJWj=@IF3ux)Y|q!B$_a1ic2=*vomG(UG*IcAw}5H<_e{_G(nIcEP-H6 z&Mv~cb~Z!|*CP03fdQZ@K(#cDMH|u zU58MBR4ly{_M8+@5zJ12;;fo*NK&huFoI!KhY z7F0n9xI_S|FtG3_gs3Grf)=P)S$on0xj+a9SloANK`^jh2!F#>c$o6|v_+stp*1SN z-~ea@64I^~L+xoIsc;BapMw_VCut@apfv!}@k;5P2A%UV=n`=?0!o0Yq1j-7P*^Pl z2;_52kCW_sYwB&&(2Y|^`Td^hT;YFsl%zG@126*s0000FHErq1a$GT%ss zoqulGCjb0DGMSo8{`Pjq_vZ82d^VeVzVjD~d_;ja<{|`%aA}PVb~i` z;Fw0hoVz7V>0IbgDU~Ez*C+tsHgZ0>cO2#r8eJ>Zwu*{~CeNE5iK3{vSHsC0BJvs~ z+6-w434c&a_DT>*Z=CQN5VV;IgsSSgiV+bJV&;h``E-0U8?-K@77zfWX?ly~VC*RV z7~#tZ1np&;b?IuArYnPBV@1FtN(e#JjBcn$b2b8FWL=l3P^}O`su0h+7Bv`SFO#lf+j!|&KQOcMmEC_NYE&erqzD8uL!YBh1X7=RW0|Z>w4r^y;>6y zW@)!OoXg|6?5;wAFOG*J8yd3&(iz@O5fh=RZg)Dw(YZVwZ4Zc>O^mOzOo2d;;U{DI zq<^o(;k1c$5uZ=C#Q79OGFFFE$%KwYG`OE`6kmzs>6pYZh&MwVPV}?xa9C9;fe>Rq zhX|)e1tM@D$Maj5$O8s3Ic&nDdpoaEBFLx*312{f5%REY)L8Yg#>Wz7S}{z}8$rN^ z;BzIRO~NoF!=5OF8WAFx4iOQDjl>vfR?&+*tIQZ}tpyiF1_=*9gDWCKRqt<}uz%pC z7$ZT2z;=D=i9TM`AWT@pJYg$@rhq^dB9mdFu|z~4rvlG8BmLW+NRl8#Q~p#MA*5s@ zBm+0J6%bqmWQv3^yb^Md@IgqFfPer=R0ag$k0S=4gOJD|;YubH1ge2cDb>=`iGP`} zhGJsy{nweza%l(Qv;ZI=N?kjI5`QJ~*@H9om%HmYzVAIyo za`{0a#r;fh7nhqrL0$;hQdn8sZ?e4bYW|HjxZMEj^>$6l(_H_UN002ovPDHLkV1kb$lDz-` delta 1892 zcmV-q2b=iJ3-S(-BYy#IP)t-sM{rDIKPz4yRB=Z$p=(jNg<_UAfooAlZAna&VM$v! zKB!lFuz6g$XPUKEg;X{*l2Bp)sO;Qbt#3M7Nh&|BT#(0JqFyRZmN;{$a#xR1O@Kpd zUot+rzf`D)M{mcLZKPR=jW&6?NTAkJp{;jF!)&O-UaF8-HTGuK z*fX;2O2%z4Md@$Cc@$r+Uv$)!q{NDSN5=#90000zbbnG#Qvm(_{qXMo1rz>dAMgG} zBs2c~^F94}%d>V%@QP9SuKL;eu)mIu&+T&X@Zk8+(WK43`RbwIqVcom)4*Y*up$5e z1$Ie9K~#8NrPt?MQ%MvC@D#{R2np2)2nY%Yt|Dt+*SWoy^j_(`+1>ws&&=FpU2-El z$$WL5pMUSX=iK<{>+8gyO|CyzCtk1Ld;k7zUjh?9pZr#tn8;q z3rav0{Sv;!Hxq>7`XDPNx_x_`P`jSWWl;@?_@qnWj}k@0>7CQ)e> zroz5K&c{aU=pi$R5Zx@sjz$Iw5r3XNnVKGmNEEAu`vXkcE0zuZsfjch99F**jS zxPNt|%*Ly%kxyq+>ntQfu7;5b$iIKRqim{ngnh0m1(i0LQx^|@+X|;AXg9+xZO6>O|oqJm|@`k#b zIxE-rNbm8#YiTH^b{3i^;5t;n^ahyO(0@J@Nrk{0ENm?88(26jm!^rhSpD5Q!Yc(L z>~CY?(HNL(XITi9O&yl&tA_U@DE}3*R#kP{iG!!SAwteA%;D0|jt*QH! z+ETs#uzM6dFS!voE(zByi={$_=Nt!6QLzpV%GLC%!^?8HT)H`qxlx`+WE5>dw|G}T zP>d*wa!x<^x`Tgms#oyo+$?i;l!s@K2yG#Ps35^~98uG93Kh~Sj0e88n;}G2KsW*h zNMzm2xB?FXBv4Ec4zmW{^M5N4x^`k1XFx(*F!kIq6%a3QcsNP~ge#Q@+c2IdU0=sj zULp}d!0VuEZUizN2L#jlpRhOY>mnqn6G4vX;<5CLAcA1~gO^ySQX%*v+(jUP0&pMJ zAtO;hph6A=J^72ED|+`s1OVCsCs9EF0aU0m;@8E0(jCDPO{<%r5r6RPZ5|H%F&LcQH}4wD`=69gVf=%&C)ctMh} zle&Gu;u%Ngx(Nphk)VQL&)aY42&~&~6Ank7`eVFw7W z5WZ1a%UQb23j|eg)cvgGf5Myt3)}kMU5@=2%vs5gZbM2)VXE2_h)arN;?ISaLcMWIT$X zEbyHSv`iU_2>U!!P{4gGj-c2Fx+vff?v&gR+OoF*+t~piDqRThaa&0c5KTaz2)wpD z=IcRV01E(U8u^K`p7V>G&BUl(9;`- e{Q2@+PvKw7kr=Y01IdE`0000f zS5{U_N=okS?1g@Gmp!8~A{vf1nr&=sf-R3!8e>{UI>5cVo`02&u&JG-Nw0ibGP8w8 zoa_Tq` z2H-JXg9%5Q_l4N$5ixs8|Q8NYfXs#3?RHIe!q0X~QrSyqUi!0v1C=%}NHD z4GYojr&CE9*%+ck1m|KS;YZ5mX&JecXmADs1`Tev1Auu}M$~X31QL4)RU%|+3n3!* z6R{+M*CZ$iA~h3D3W_O%%P{j#lyj_?X`#Xp!Zd=>og_XYkw{2Zqfk{vRTN+tM3MqU zz@psWhkxLbGin1jisE9B8iEW4h%oXHD=vi40wPs$ffT3!!oVPgLwucNpk{u%Q=XYb90e+(Dj=7oLg!jCoDYPr-9*AcKmx~^4(YNI)eHj%oL)pQ;TdZz zP@r-2*LyqN`pOj1Ot<57os0pUxX&|Zh8V^xQ-Ak%JQg!?y-!np9MK?x$;5q{58^r= zS$V0i<1E}psj6CyW6FR)gU4>7ra&Ll__GJ>KDL^;j}q+f@v5*2jGKt~gHY}5N2%gE znWq6+PeQ6y`Ut@U8ul=7Q(4(Q zv;YQ=Tm%V1Fq|t8ri@Z8`lwB%ZbIlR%P2|)QMQOjgoog8LC~lQFbbd`dqsjGL126Y zr_cgw#RfbO_C~-s8%emZ1}jyCy^wG*0)GLzSm`EA1cW9#S7M%?w0(|;kaCI8M+pT1 zu>d5Oe!?0WQA*K=z`nEqmk{oJcSb;?KL>?!Kc_^3FN+A>kKYh@OK^dJf(x<$FyYGg zK@tT?9LIUSf`pta4D^AW@YS3=j*}qDe)BaT4~0EVCBjYe#vldCtMD(3>HAZPAlCu zcqVMS)4UWN1CX%W?f!)ekZ$X5CPQII(a6EcbAc114rdPN5dKepbAAb%c7{z3%n0p6z zC(#KAD;UI41*o5ydmg%IKVpUjzlXrxhaTl_ZrB6p86P%I;`8I<6Y}vav;r4e;y?M^ V`)<{w&!YeU002ovPDHLkV1o7o8>;{S delta 1838 zcmV+}2hsTc3A_%FBYy#9P)t-sM{rDtQ!-s2R#6*9on=0hUO7@QF=|0bS4cpAL|0xn zKCDQER4yFaSgAu6I9@g~aXDOgMk=^6i$fMSN+K+CLoi}CA-`Cb`JL*-TA)!YAIy2O z^?=oG9$A?)&HjJ$y&1Wxb=lEblh>q?wa79JBhhxp8l5T;(*F~Dr&`M zum79*)qlMGi0`Oci=%2n@}}=_C1i#_XZ(-fNGKMLOm_8U)ZB~4?M%nZET(8GK<#zJ z;XAwGXSJPMQKMa8!-J6dL`28{00202QchC<@csVq?td^61s`BO`2PGu^Xc!)f^*MS z{d}zb`Tlpc@xQL#$CjD?P0*gP?9}nye(>+-sj$=S>!8vT000F}Nklw51A_ZFhInCGPHqYyI=@bMFYWnUtR7zTgdWe)&Ig=gibtC$K;F zW+PlmuYbRPpZj|}V&(bV=d)5N-90?aU5rPp&S9e11Y*1t#Ot}QpIfC;zj>G&lOPY~ zzHYQitv;$_JRXCj6B1K_T0eLCac|2%Gp<0ao`3Z(7JO5aoTt6@i^s$y0{JA|JoQf$ zBCwG@T$q`NSZ!V9UQW~s;#CV;F;NKL(^hlg&sssgc;T9sY(p!^Kk3=452@5YZpO;l zRqhW)>RWwtoJ@wx0T%+bV(H$71rCapWThTW1YQ1#S`oZY*xFC0kdTE(oyNR-L0F5G zK7V{k-c!V0Ih;(!)6s18FP{ahK8dHot7a=UuI?MDZ#xQYI8H}1iOogp4RMf8rRufU zgt=Jj_iXpfb~J7Y9Ww;Emk*~Z^;%||Fc+)&`|b9>twAG^(CB#mc)I`A;>mcumQO4? ztss6=#L{UI8d)fUQ1#$4wjLELSZHhpv46PHzwrM?*tLW*66Q&Wy_ZQRQxGZ-y(RES zd(pQe=RuH2fXr=EQ2o%_d_7sgLc$9nfE@I${~Otg;56S)r64mr-|@`r>LR&aKDLET zv#jgh_8BqIMX8|jr~NmY$5653^y%B!pq=-Z;#yS~|k zKrZ{Viv%#fH>xKdo#zcr6Pk{2;#HJoA9~sJF26M97hM|(06LV+i6Sivil#IC6$mv; zkTf8Oz=r{ZfILIT4}wK7a5zy>4SzPm{HWBCfa;QTb!{r}`pp13;Zg>%#MlBW^BhNm zAR+IlSSvR{_#}#oHtXNoFAfIRSrXylO_#Us=f)2NDn6LoRaMppvl_3-a zjicoLF%~@YB5dw(A=8!s>p(dX?g%^^VIy6bX4RwcoG2-a#1O&ZB7a~V>3{9mYEF5zX=vk;)jakicE+D$|YlI5{533wYA;F1&1qBNZ0T~2o$L-x8g1gO7 zNT95rLKW+3Oky1Y*M9+msJnh&?N|b3m5U-6dhBNb5g;hf2sdI@mt_i$6#*VZjf@Gm z0ubgjq&4?1<`BaGfxBP=h5{FhW?4tTbs%AR#0SANBg@t{0)PbdT;oiE#fLIGfrQZn z?g9qzD@x}nORy)6$_S18qF~_g7J!7nNOcK`qY diff --git a/TMessagesProj/src/main/assets/emoji/0_1314.png b/TMessagesProj/src/main/assets/emoji/0_1314.png index 1527cdd73281a277f98413524e00616e3f9f5baf..e2c62725599f0b071804fd98e4f550976a17d2ff 100644 GIT binary patch delta 1832 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 R!|?zB002ovPDHLkV1j(cd)NQ~ diff --git a/TMessagesProj/src/main/assets/emoji/0_1316.png b/TMessagesProj/src/main/assets/emoji/0_1316.png index 5c4b1ccf5d781fc5f078d736fa3edc3dfca7862a..df5c9cbc6c2a812433abe0dadde4a3414e617bd7 100644 GIT binary patch delta 1727 zcmV;w20;0t3C<0WBYy!PP)t-sM{rEOt%1I(cGSXo&d$!lqHmm>oZiof&9`j4q;$}~ ze4B%I-p`2H$bZAb!^y8@kB^Yo#eUbteW|IbxOYvrbxlc2O`)Noetvzkv$MjbV3(Jd ztE;QHb4$9ASBZ&k&Y5uDwU5)HdeohE z%aCW{zL&hbyuW}|v5!i-o>ZcHJ;SMA$fbSM!Farua@og!rKP6f(~h@xOU1>-tgWr> zE4^?&ZpGW z)X~w=a&2mMRDV3m%E~ex3Sd}C%dd`qfPtl%gYoF5(!HeE*VfL?&O$aM)5Wgku7_H4 zq^AG?03&o#PE!CVR%qr4`TqSEJV(`u=j8sc(2927=BRAwoZQ`+;i0^{=B%a%wEzGG zI!Q!9RCr$1m1lDrNf3q!1}z|jgr!rmY~Rgn&Y7Gu%75AM{{O$Y?p+XN7urSscF!VU zRMQV{_YOtk|3D^(WHNs!$mNU0y=|ntS4<_}E=U%)yR9!vTHWovbnb12^!7{r%JL>j zdMgn8E-B|Xoh>8>?w=*Sdn7oJo3r4}Ep%^k(=msZ7Mx~(-_ zTy(pYRDYZyU&EFy)9YRUtqZ7I(M8I+m^SvXrsmj|SL=pgAyPxO;8BcLq_!~Z7SriC z9&E35@xs!83O?1!$(Tui0Tkm~+hW3spf(_Qfkis9k1__{sxZTPr(-%^Wrep|>_sV( z+kwGjh9d2BY>u4kV&uC>A4)oax7|C&4qPuLe#MZF-lQ4HCYNm5Z`zC%S#RkH5^A=-Jo9tz$hY9(4i{u^ZAd5hrwVnmx4yL(exhIv-wC6hhnUPLL<}Z{a`S-AI~q@ zppWU#0j`I0PEZW>BoRr$00rSkxA%kljyzgS^YSuS3mks+)ct5h?trQ?f#dD^gnxzl zCG4XwXc`=IQB@1kip*z96;QC3aI#Q=ui+bx<#|+mjQf$_H>fB`;6Rp&aG~)MkyRC@ z8BOxQfO#$)94~=G3w;_Y6l$arah!~)OhBQr8p}$eED=#)5grVJQpbZ8_giEeBF4}( zP-voI7?ivyWOWRqh#^-t>uL~#=YPS$3yMs%Rfu87%Eu{^CCh{u=)h(;7y-uxqm(d& zZO1F}CCeI81s&Lo+q=D;JaVA{PPc6`>DXB$_ev#0l?6hGgn}Oa5grW+waroyQpAzW zr%QEkfMhlc!U!{8B53${a#BoeMsD9w6#>PNZkaOd^xmkj$B(ihnYoxT1ou zf+Et-;fdJXQKu?ahbW?ohBvZ*V1Oh91jZQ{-b&%1UNd?H#>UkSiR0`s-E^lqI)+eL5;^K8@tjr_vO(nA|*7`+q>Qn#~>-;-->6%vKj+=!p{v>NgP7A6JgxS1*x6__ z+B#YgOaKu;@Ey5p=*{ZstM}%x+1Fub@L?DQHSmN2G+ZNrqxt@|!+-Dr46qSCYGDa! zpa3&mhmwZg|FAwrCIyD;tE(%JAgIA=s0YD9aRq>*nR=xUy>a~w011K;WMM!+0UOY9 z_(~u89qw2?%L}+DKy*PF(*2HldKdAcl&tl`Fh`PWA^VD7FB`bR|za( zKEdfotySnSy0+eikvOjA@jG{Lt8t(Hey!qsXJ_a5_;}~tKOyhd06RV$?*OZL{s)&3 Vy)FUazEuDK002ovPDHLkV1kP}aKr!r delta 1166 zcmV;91abS$4WS8;BYyzlP)t-sM{rDba&nV-ZZRt-mU?IS)wAlpnvji+gKukSWo3wk zg@}cPYG!7wqMh8RgNB2HjD><(TU^nacGQ?~*r9zmSZQu+Y_6=Vc5-okb#ZEEX7tdl zGcqu8Zf?zzZA3~=6A=xMjEv>Ak>s+D>%E#EAtD_c7$_?&-G8Qn``*2vo}H+srkj|U ztEi}@qobCSlZuFlb#ZZofr0VJrT^x|^v|qgl&^hydabFcuB)poI|NkIYcYBQe0!%&lz(P;8IZ&mAgp8$G z5<1$$!`tg%FdE26;B7Rr?WWyqZnrnc3hF_f#5O2s;(tL^w^8u%u^5k=NaF2!KL7mx z+vjqzYW8r%>t;S51F;ydnl(JJ`X&hEMh1ddF25UrE|QC=WfMpBOONk(!ypM#+1X}hHGtP_$t zDIwVx5Qd&*W$$8W5JH^oWbLdsn~lA18L3fnB^@Y{wba8wRoTn;U8~iWFvI}@gxb;( zJMH8^7-~V}1Vv>+m6@pS>U2@f=6j$GsNjwI3c8g@0u|~`WT`bf#6Q3J}=Tm5IrFP;Zk!F_sR=$ z9e)HL1TX>`)|JwNQV60(SpFwWtA`#JL<`T9OE05g9tGE>UInpE5N5oA?*`O+RLTlf zE^xwSLRdixV2BRhqgGDPDiH`%L4ZKRuzFc}OH&lN)~ojGa8j-ird;q&EmW&QDv(B_ zQHMlPWSSvA2rl?R03FOzzkgRD^?oIU2Y-7~mcaFyz?Wf~Cl`7Z6rsUi@%p-hM#WvL{=g@8o} zQB^ui%#H%TMj=oDKuDs7b(WYx`1tW-hytN$MoCharE>)3Up-sP?``n+XXD9al7F1P zY&m476!1_g>WlY>`FJv^Sm%j)1o!N*z@Ly$N4x+CaopFW^TZ@cq6p51j~3GqCUkq2 zbOCV(0|{diFF9!y(OiCA*2 gh%75G`_J^jA$ChJdrd8LR7AwY#G<02 zc1$o~JR@^QE18*@nwpx>(9nm6hqbk}Vp>qDs;Zx#pNm^ViHV80g<*wOHj!aNU^yOD zF&CC+OR|1kt#(1dRUv9n5U34va*qma6|wA02p*qPE!DXokad%C;k%VHL?hxS=hWZomKl z1msCXK~#8N)qj>(d+In4hSy*qp>E1a)aBmkJ>``D|EG3Fg5_cpo8)dkh#xsrE*uXEH=(n0&`Ds%#A!z}<2%jGhaey?+F5&>uLXMdS^1f;2ytmj-~p+#9Bdh?5c zQ+z5JV^{fTvH7x>afU0Kc)PrjPbuv+)}u`!jEZc_WQwxkKD;OZ5HY%GNMn$KYbr{y zrKgpB2(`iRMmY^8dYCfhWhnxBk&WHGV4;~6mcwr4|ae6R%}X4|RH!w2Vd zD+0GHGk+0a%t-+vtXj1@V}wQP1w7YG7zjk3UOYH+Y75%#VcsyEYodJv;XJUi17r^C z`r6r2%sLQRK}f7*E;5iX94^j?pdNv_bG~(p7#MM^66w1+=RgtV*%9y5B0xcw1q#AF zc!T1YC|&qDI1DCNx{^7M!IB=TYft>vxyJ;E~v&D6VUT7}9YKtxs5bf$@iHbkcu z;eT);Nvx~=Vz-)BJIN8APzAA9=_16N1|+v_ga(;cg+SkWY<=f{|M&KmY?M zQ4BUh4+e%16V3eQpXQce+SmYvaiL?9C_^xL=o~gklLncas52r;s7o0MLB@oV8Gmlm zrj}$}8XKNx8j)xMyY58LZpj-F-JuXP!M+*>^Z_r1fF?xA+t(lhrU{8nTNKT6p8z37 zLgHpw&}mGh+scQoLda{)&DUWUjrCF_g7YTzaLCb3iVuAeea<$kA$HJRk%x!1&C@1PHIMzkq={ za~2Sf))4U1ehj&MV&lil@p|ttr7TWQ$K=D7!Xtq_SiIH|pwlqrlVUvH-`?Kd n-{0T<{ju=>IHPaoT@e2OgL^-%E1;4}00000NkvXXu0mjfk=5p~ delta 1128 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 b6I;c9?Vt6YBFW{a00000NkvXXu0mjf^t?yZ delta 1146 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 VzA0ItPxJr)002ovPDHLkV1h`7Y-|7k diff --git a/TMessagesProj/src/main/assets/emoji/0_1320.png b/TMessagesProj/src/main/assets/emoji/0_1320.png index 2511e49142cdd174e47d9e749bdea70f386171dd..3da50dfb46e57bcc304f860ba00ed05af3ae3ef6 100644 GIT binary patch delta 1634 zcmV-o2A%no2=WY&BYy!1P)t-sM{rEvtt`TX59PEp+Ndwnq&Yuyx=nw9j2KyeQ0#5;S0%_|?M6?Bc!t?!T*)X8-N5<+L|hiN{BKzyI>hF*Zm<9M z+Jb99Vo@*O(SN2RMs!nz#o4SyaW(+KxR?i{B)9+o03>u$PE!C~qLV@==Kk#w{N?K= zMreEL>#O_bm2+~@)Vj{0v-Y;2s@)jz2-yGt1ocToK~#8N<(B7C<471q$HrhB00SOi zhKai!m7{Yc=QQd4-(+vMEbOfU$?V@f5@pNiJGx(YyMN2?{uiv43I~lwTMSr`nq@j1DYflv2lkNijYGbJ`swWpH?}EXMeoC|BE|H_KO**Jg>N@?-0+Y_9 zSKThS`bd~Wgtow>X7Ist7?mb-0?!@7kUCnF1&%ExaUI9Y z-gj2)KoBVn)j15$sLNK%gd%WuvNz&}R+y5XP9~@H*ckE$n|}_a zB-~@Xk-fA86nbF*LzU}YFS*2=Qv9FiEG;Z>o_tXe0NnIDDhf^$2I)e9(afU6JdabQ z&=NwRFbI4wKtWt)i@&nB-%4@E7OE4iFoYurWwwMuhoIaGK9+KS+UzhWW;wVY`F`Y> zGXtg=m9^ zkyw(VtsD@z+y&f)KpA$H|Jhhk4i^rb0JaQ6jze3tfWv^D`%R9333QPPV1K~Eek1!k zHYD7|p#(t@)A?pc=-3`(LNMk9Vezek%I4PhzkMsVLI;Fa9Dn`3wYjmhU}I~yc6s^Z z`Z~5^Kf&^^f832~yIUJeJsyE|ps%rk86UXCDmmOMVhXyO_f z+U@gp8=BE>c9N~y2+SlSWq;9J-nGwXKvLVv%1|5KX-0GKNgF^={t3#E)Lw69qjsnB zE=u5=3pC2{YA<^*oR`bG=NV~)G7M*m#If~Sh_!YbVU=T%^Hh)m$6Do;u|x#@oHA(R z(A5BfRB?57b)_7y#P|loRq9BY*I(hBaaP`Yc~Pyw0Cc~oOj$5IJ6nFf+{tG9r#67+ zQXKOR7C1Y9aZdK2NQ#vN$DBn);wx{y)W^4T)Ri%SY4KuxYEXBSRlL0yr?kAjzP<+5 gvnb;R+_<3l2XN7*48}Y20ssI207*qoM6N<$f=u)#5&!@I delta 1023 zcmVP)t-sM{rD$kB>VpD1v`~Sx`+D<&)=9e;d#Z)|Lbg@uWRhCW$mU0qzQs;Y>Eg;G8=FDfZ5Bp-5aZahUx zS5r_{LOFAAa8Eiipq-sWew~??mWhXlTt_>4cXwu#t~e+lHGeZPO;A!qZG&{4wW+74 zfqs6bqoYuUqn z>?9KV?ltTG|9{zZD>CJ&nldBJwVg^H`f%HVhZvgiY|qe+?F7LhG2`qLyH;&!7 zW9_SEh5dV5ao2UbuJiSXVBfaI_xDiO^(N9JHd%K0x?YFj+*x|WqCaQ#*Yz^g=XkD1 zgngEs1(C(G{~)f{OI`ObwjN<-kjr&IBG59t9TI~eSbu5i81@SiwIrS#4Z;z``2xg- zm7%A3TZ{w<+C(-WVd|a8;)ke*zGGTXs^^&fSr9d)W%;CD!#1Ciu1Dfr(*y~1ft4j= zfB?}pl$xIE79g;MA(CZXL*e&@q7Xv$1SSR1Ht<&&su2MQjJ93dw41(%7Boo$H6mni zS^AD?@qg1a%|i7NO>RUBL?aGFhe-aHK!Z}+HW*3+Los+D7$%Y=)Kq^uC@aT+v2&D( zKoasNtf3rdpD;)%g@vI*&;$Yq10mEAUK>GR6}=ALl6Mpg4BZ8WMl9}fHxb4@v~@Z} zgj6o)T|y~589MPvo~B0^igeWUbUL7LIvfaxB7c0TLs$h0Z*K=I0))PR2C2BEF3i^i z1wowBeC;R;&K86>86Z~5f-M9nAzP4{s^G2U7N8t(4`1gv9$e6}tSIt*f3;d|x9jz~Cbl?{5t(Tk`ThyeoWxP^7O_aakvQuv5d#W$LC#; z5`>VXu=1t|$mhomk_5aEK%s#9a{6n002ovPDHLkV1n6a*OmYP diff --git a/TMessagesProj/src/main/assets/emoji/0_1321.png b/TMessagesProj/src/main/assets/emoji/0_1321.png index b5ea36642a16d3cbe7638a383023c3100ff4f9c6..034473034b8a1116ffd78c331e96ca42b6610e28 100644 GIT binary patch delta 1634 zcmV-o2A%oU74i&_BYy!1P)t-sM{rC_C@4KQHQJg!yX$PPJqHVXQWq%$XklYI5RU|jLA(!MnXF~x`0_S zEG)~6WG4p#bXrUE>EL8eK>hghrjLEQql!)>6FqLPLUp;$rGXc)GFUIXMOwYLBO03mczPE!Ev{Z=8~FaGTjd*VYy ztw?3JujB7@k&WQ$mB`$Ep{i~&9;vR;6um3xp==0`i zr!HXlXLW}d;sQ52r>|%f`0^rbdxgMOtwFiEYq~=5*cECcO0io0|qowH$zLT8HSQTQOPIw(LukK?@rK7 zl!XQwB_V}XPwAx6p{QGf_x#z=A`6leLA7O>7PLpnOEH9^uQE+F4Ci^^Pi9Xcv)P36 z2R=MljC93BX0j|p1CPP;yu%ap>2y*Rxhw@gE2(d}00nN;t#C5{PPeBVLE~0*OnCIn7*#Y=IYnW6hobG##!RlI_F&*yHix32hTq-k%$@& zzV{QSL^C{_zdT6di{sixurW}m>v#cjAdN^0Ji<9iR9rc(XJ~SG)=`c9fID!BihqJW z@QCx|t#x91F0U~t0tZvE#h6C2NMXD7)j={>*RG?+3d1&3mFE>QK*6vSqcem^CUb40 zlgOdDBi9`{VyHj}-us$ANaf7tRTeoE!*gASiGU0mmI7;;%BANRv>HIfh3SL_QW*9% zg-Gutj)5F9W8_ex5FYJ`bgse}kbh7gz}8?R18-krpu5H(hoaIa!y;;d!PqebIB^|= zYGqUd(!ih@ynROF*tHcnAkkD@8aeRJ)4tr5{24hQfd*&*8Ju$rbRUP!Q;-N%MHhP+ z;JCtxgalDkfC%;%8201x+VdQqHvkWThn3u$uQ(o_XA{^RXZ!yfQT~=441Y$W5zZOj z2LtX~xwQK{GUd}h9v|=Sdjph)jQq~sx>-0a=XQC13H5*+_Z)H%1MdF5xmmBtQc7Es z(&=OKF@l0jd@$+V->o+USx%Fal$!yerU}X2-97F{2p&RUDU_2kG@EMzmXI~ws3$|C zQEgPK4M+;54-L7(njS}SV}Az-1P>^0;R+oe&gL@=4-JIftf7gBBeVh_f#dT>!z^qz zjq3LXvceKW2`EBDy9Gz#gRztmq4ga=f++L?4G3VMTHNh+x7)5ZHXp3$=|iL4ZMVrm zWieF}P&L*60NqyO{Z8_QMhk!L1`Z^F30IYf1!N#c_3+(JN}Fo;2V12GsfJf8AQIs3 zp{8}1dv_jCw5uR8v|`$^0goUfIw`%^$LRwmhLK_@lq4#RfdI7e4VrKD^SdKG{PgKC g;8Oz87k*Rx4dj}QmFeQ#DgXcg07*qoM6N<$g3EOU5C8xG delta 2766 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 U&FI+)lK=n!07*qoM6N<$g8Ee(`2YX_ diff --git a/TMessagesProj/src/main/assets/emoji/0_1322.png b/TMessagesProj/src/main/assets/emoji/0_1322.png index 55f4593f4f204445441a408af5adab9af10e2433..3df6c6373643618e53ec9581e2d7a2b995a3cb17 100644 GIT binary patch delta 1648 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 GLSTXu2-_t9 diff --git a/TMessagesProj/src/main/assets/emoji/0_1323.png b/TMessagesProj/src/main/assets/emoji/0_1323.png index b79dc67a997df5fc8de6640c5a96e71123872f40..aa982b92c6ebb3e729d5445c5f1f8525aee76df8 100644 GIT binary patch delta 1493 zcmV;`1uFX86Xpw$BYyzWP)t-sM{rDbNh>yHr8s7!ZC_x1Q#5r=FI$SpdU9`iVpND) zH%mA!HDjKHRx*fMI4CYXJa4maNi&OKL2XGgU_L2DdcQ?EJC9#NpK(vAbXK*1V3=o0 zpl?xFGaImaTzO79xP@bnVL!i*XogofVL2PDbXjddB40cwjDK52J|7EgL@-P#5xa|K z#j27|g2jMQFiCvBH)Ww)ipWBBxpqk?CkO#ohsO2u^5N9W(Z8^+l7Q;s+{BY=FIbK} zZm!0bZd8N8gll3VKW4s=LYr*|V2;X%!HD4i000_vQchCyDX6=6P_es($}h z>hIhD%34JN{kL}@h%0C3J0~}qzy24rY^y<7cI!V0>_+FR?H07JIyct28mrTG#V5Gy zUN!A=5_Eh{b%O7Kg}0k0Cuy`zv5QmFZU=sIWu0hnk$?LTpEmluXq+^LHiyCAF~Dn& zKe(_?FkDRsMu6i#m=Y1~{;nLV{lKGq3c+VgJrP9Fv{|LNaos3Q<@CU?bp%9oQ4zy# z`_m{-(_BWdeCp@JQ5B=%BC&)c&GP`gn-Ly5qTBM-@#v%9Aj@P5av4w*1Bu8XWl+&c zXAsCJ;C~{~nap!Uk;p=r@|*~!rE8=0Fh$ZxF%=4)_&ST_o|wo3I2+~Dgd!L)<~R;C z@Nk}dCLl$#S|Lc$H9(|P2-%iQRw-I-3_W9v!QeeTc?I+{b_nLUl?wX`LvtDHdfro4 z2v`b2!QksMrh>{8P(&ef1n#pa54u~!>ok`G*MH@R=hHZ=6h02jXIK@Hc-p}RSZ=da zI7~sNQpJN(foJUrvqKS1ymxE@w6Bv_6BPB(a-<2=$Mj%PS z*t*y2I;Q*;Z_mMZhZTzQd&K%-6l}d*td@&j_Z5(0z1*xeiykuy|FJZL3UbW7yI8K@ z(|`9x&qF<4-OXy9rRzmcVHPR>VV5bwEagnC7W(~tHtTIX2+&M#BiDMCFBc9e#6zo0 zA#|E3wp`@1*(_BH)WhK|S2G}ci&qxPRCG#LCr?PxTWTnN_cl<_^;j(>jK5ba2a1?K zmf!3=_CpMVaaa68`IesI?yp}S#wjwL+<%lWtt8f=Sr}$16g+t}6OZmQ#$%n7FRdFt z&IBm{8Q`Kf(Ith#DIV-ng#`syg#syroI7NIf-#}v z+vIBS+L)E6N_KgKL8X=LbR@4x_%0Dqeq zrqF*=i0V$XKn!x2St+3j>TVi?r^JR2duh}P^AN2)4ufN7yzFz+vOKf zTfXh2RYWGJt;|8BUJGs1N&N00#-kV|J9l7>vL$@7Is?F*HZOu?MGz;Lu)PsY1<4*W)|9KRB)SKGz+Z+M{{qGYL8OexFYJcuyKJE_z6k}6< vNYMh;1zH;)QGEaM<-6fa3EKnaAM^Yd$RkWg6pRZ`00000NkvXXu0mjf5(ls{ delta 2516 zcmV;_2`l#I3*8ftBYy$HP)t-sM{rDJMnkf4Re(x4-L;K&0Se8dc)Gu~k7ZJC0Se*M zjHFvh)~kKktAR``EpH1Ari4RXB_u5v7}%85fx&CCHR$*{FcanQ|!-6Cwu)tanVfhG2gg8lfU6)qkjhiex#IP&kKAEaJhH zm0>%VKP$JCRJDH z%jZ4ciFjFV0J>JowHx1;2YO>2!dF+9YvuCK?T6NMcm7`l&rj>C>+9>~TCEnFX*fE} zazid%JnX>m#xkh3vC$t2o^K#}SZT;rcYHSv&3gs~Z1neUZxv#f8whlWWxHJ^5%{Sa z%71S2y(up*m&>*7LQopN(KvjDoia@TTyZFRl8aXGhHh@~V>xYo4k z(zu(hw!hul-srDwZ*S!`v)Nosh{c5a&40ko@k?$xg8s3!wS9T3lFjaAvzvKVDCKg0 zH1R!Bj|+n5WyjmfRwb8(_|0rll2XO@m1Z5@bCR2m_};yFSE)b^l?$`8rH`??6#IC6 zyr*Gjw**$W(6#;z2T@?_^?KsNhZM)=mArK6j2DvN?s?rHJd6GPm0W>Ma9pCkV}Cr9 zxD>y`a?-h;A&H#C->L z!^p$?L3qpFbGtUYV~GUxvQQGF&)TPk{v8;;^WgsdGj2ELRY>9f&x>ytL#Yq^r%wlf z_+b=!)#-7cgCsl%_&~2hvXPEB0)K>iIjxgs4r?Ch6De77bo<0yqtka!AMhdR%T^fi zGqOxkl+tnHq)GYpP2XvVZi#C>2?L_SYdp`}Cr83c*aSCI2Jkdh5_sNFF>pK7B z_&K*3g+h?0OQ($Ixz?TrGbo)mOvSi)%!?&ILm^OQ-zl{WabsxHGRD$*-G5Z{BLvz$ z(9t_GpAiwiXo)|bQcAbfL(dh7rSfI5UNw1bBy})S;c|1Y^ZB{tR&Z6KI?F?(^3& z4LOh`9gb!Ye;CK2(eSO~41d%+#0vMk%{ma%ibpeG9rg6)^Iu+@j2|aKI314r<21ag z;pkcKu@rjl1@jM@tLceMA-2L~7?ZctnxRl4k|C;xgt$sp2@F%CQ|-sAco6#YnWxoz zS&ti<&cl3Kj$lj?2!yyWO;oE6DoQ^(u{qD5543Qj|B?;Fe_-g5q<`&~o&Ctinf^!~Xb^Kyn?GnDii=pdPlBr^>+2^`00RmBJ(&7oh7tn%Wn zw>eU%FEIVPM(LVj`484?MNcOi5E+bsa1eC1kxKQf?+alPfdP1Nd-~$Vi_^CjUcA<9 zol5gEpHU#zHWfvdKY#4(S0RV$7m)-pKY|_=Zo$YR4T%>zfo6QT;662JX)=WmEw4^S|5k@6xjK)@Wcff-! z5)0#dp%@?t0;k~tjc4L2H1tRTKZ4Cq{cbXdXv%id6wL^w;uucjD=QU1A4kH2V?~RaN{fP6PSY_3IZ!-)wqg3 z?sakFnt!VjRfix5#XYi$IrY=kT#V&%SUif2pl)uTbJa~JgE|YH|f#vy$W$|D;YqLTq!?;9xrd=Bb$i5a+k(}|GJQxJ$~WtK$z>L&^@m^FZu?q zq*61!lL)R}cX#{jm_P^Kv4zEJo!=BQg)ENO>+akbSn#whm5Rl}g>R0$*w?vqq0U`- zwN3QDDZUPUK0$H=z=@P%b(XXj72Kzyfsz(ki` e-VJQN4r! diff --git a/TMessagesProj/src/main/assets/emoji/0_1324.png b/TMessagesProj/src/main/assets/emoji/0_1324.png index 26fbd5d2871c0e0a61fff1a56fc8524889c12938..36271fe81d69b285312886a053fae5b73d472e3e 100644 GIT binary patch delta 1354 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 delta 2235 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1327.png b/TMessagesProj/src/main/assets/emoji/0_1327.png index 463c896e166c37cbb3e793d26ed19df0f5540aa3..57ba595b25b1cc17bcc66c2152658a16f1a15291 100644 GIT binary patch delta 2157 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 O00007>*1*F<*<^ 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 eC*!trF8l|y+!KOf6gJ-g0000)S>GD delta 1865 zcmV-P2e$b464(xqB!7=kOjJcja7;lMPFW&nPAOSN98hR4a(FgwH4;EgB2zyVO<^Z) zD-<~Gz@9)2O;#XdU?*!$7gQ7i&2y6y_psqAQl)J-=mP~w~4@LqG2a(K@Ckn3x7*vDQ{65Tzx=>R!25; zGJA(gkP;v&a4&f0yOi9igM&hV4<9B&4o_w)a@d@9g-VX1WPOB3jwn4x+@yXH7#-bx zjCwqT*`Im*)v?>9eUMm}^2eupJcU16XzswA7ZnvgS7r$b3(}Nr=2xP@MUgEwNtAV2 zTOw#+CTv(AWPei}Ur7~JMG#SGEp$~LVPqf;z=`L5ubO(GLcQK4p~Cd5 ze8=+!V&H_<;UWDo8HNcHYiDcui3VcoR4qw6$9zJtbqR)|RmncR551-2J<)@6J3+moZC zqbJkbA+Qm_n(=Zcw6L>0{!*4N4`@;0pnrV1s~u=`_quJ2zs%)wvYfl@cZFkGIU~0f zg>@2sfK@wZ7_yzN8aeatgC}dp{WJ8abAL982VhY;OOk3?sv{NcoLc$&AfN3QOy}#R zjFtJY57-8a5E4tAW~i0I*MsbgY~*Co(NJb<88{CAEYClljSOehN(IXYGj1$fawJTt zt>qxhh{Tcs-&|U+=vwtsmSx-4R8>N1MmFTFov;sDW28_i6~FykwKG;mwN%U!!GFrw zvb+vG-0(cFSJ>kDKk2ka0ZJ&NELN#uJY9ehOoG=7q$oM2NmFR1Dh(xL2_%@dY(EXa zh+d8_Am@u_nVO?orYek3H_|JlWjWmmBH9xQucOaDK5LpPsI(O!>dMI>%{J_@Fo+lu zIUY&aDHa{9nHfvy@@}3}HRPps5Pva9N<8`eMGzdpCDKKY2yavkBi#)l+Avah_R9}R z5F|v2j289ms3jZKD1?YgnB^4_NwkPdq{qBH^{>(-W1t*GN#sif9!nDD9G6(~?sjOy z9YzqaY|&Lg)C-jYrzi@K&5WH%zxMRGs%$K^ftG#{>6J=Br)d&vPsiMUxuq-i|(ho6o*_;e!=3RN^S1 zh?u2qSR>vzC+G{=0elp~BZO7z29l7e3HQAj_GQC4$t6bPe2GY!X|2|iY;JCbVKL?~5?MM< zeKyI&={N+<((0SGz3qclC&olns1Rr9UX0Qxj#?bK4glE^L}(Md{(y187_Sh?DGs*7 zg}{g_D4hNv`15_@SR^-yD+A;7XlD8aG`rZu4(1k}bbp(Q3-Gq?2;j1h|b-z5CIe|~gprIlb3NW$#L z$-tc(w)_6g>8D3--9iM0MV9+?vCrH^#7<8?U0hr|imhBshC*A3_ix-USh2l8ljHd_00000NkvXXu0mjf DA^>SF diff --git a/TMessagesProj/src/main/assets/emoji/0_1329.png b/TMessagesProj/src/main/assets/emoji/0_1329.png index 2ecdb64983be302adf3a33700cca7430fb26c516..503c5ca4233050b9912d39a23797f7938890644e 100644 GIT binary patch delta 2225 zcmV;i2u}Ci4ZRVNB!3Z5OjJcja7?11p)VK)gM@~NiHeYrl5#~RjC^u;Q9O28NqkN& zu&}e9pP*|%B4;}#Z$u`RY*B%Mg0!@=eR_Izc6ehu9jBIBz;dXbWAgAM>4pBVK*HLvwU4aB!3WFIxA8!9ISR*ieE^T zVoIoSSAthTpKVi@mX?=kPm5eVUN#xXm~Om_WhoQ~gjF+SI~`0Z5obv`M*&)}igU)5 zYs00Iz?_D{kZ8G-eyf3JBL^roA0a*jN&EZyEd)1*dvomO-pHz#b_I-N19%w*0&xb0 zf&r9G9yfdgkbl9Uj^5C~Y++f!!NH<#3RMDW%C4P=0GLg-_BQ|k03UQxPE!E;=z{%0 zJP!UKaeiOdyH&fp{F~Ddf|qyZ-^m6!%V!X!bHmOxh=-PmZ(6KsIxE^lLQeBQJwd_t(*7{u{CH zlY6_#M7DU;9o+n(xk12me^O+dNMokg$4Nr|XoPVfq7bAHWN*9V{KauTyT9B`0E&m> zo0#}wUVldBQGUCO)YUa}`h6aIKRL~M>GyB?q4Op6N8_Kxe>0fV^tUctI%7^T#)B7{ zK1o~gDgz3n5y9?V028 zxQmQJiv5QwoI8`<;gggx=ne;E@(Go*G7 ziWLNaJjXHDMU9lw!xD58wbX_}4=1cfx9#1Y5~Z|%3Y z<>~Rs$;oaZolfsA=~mA(yE|u1G}Ev=Q~HEw0gkLWUxuK*L%L<8K^T$ESG^ z`&X!ftf+2Gr+QG6Ws10*VQ`Hy6!O9q#(#fLZ9M4d(^ItMY8SmQ6lJQnUCWisVSlYg zk)SMT6&6SoDp{$NkKSz>S65fNSrCe1xQ;yRReQDJkRVX7r)_~}Hw-~oqK9!2(Yl5! z{8wEQ9oh68wb~o@B1BbX$IeywxDZUozqmjrl2TW6OBK=Wb`C-hNDUd1srQt?UM3QntLyW(`{{kXvU-uDI>vLojyv3nsk055pj2A2>_Os8 z3|lIJxWBJ|ysjcbex2*MqkOF9dQ%`mu6yANtdKktH1l=--fC$d>U@4vqkl#8=JT$i zwLW_DmCEykDEq#}B8f9GEE7h*@ljjNSJh!Sk=OZr-1w-@S2ahhKoA0di7n0whlzx1 zs`AZh^@@uKkpb^@^{1wqqQPQwE`5s<2l)g-5j{L!a&=H0)`r!Hz(&Ol+?E|l<3ae# z1_T(zBto}M8Jj6Aph^?%4u3=qB(0L!xe2q>LUd z!*Rs`=f-9cN(DqLkR0x1^7+i(AuwlqU z8Ru@GViu}tLx^IO8*wkWm>@aKQX(`A%RwhG8$?x2^dT0)W?&NEiOZdsKs3n)62`G5 z^x!Ml8F3LH!ocE+l!$~$T{9%t17dovWN4Ew!e~{>jcp-9(0|RCm`tWJ&S9GAyI> zJ1X4~G&pP8lf}dH?ZX3p0Y!8cLRj7 z;v%B_*og^(JU`ye789(a-qxR%YYFsWHLdK zzd>wP@hZ4g1u5e&n@j+R1Q-c3LE>$i|1SIs11)j3gAp`<00000NkvXXu0mjfaH$$z delta 1741 zcmV;;1~U1*5#0@tB!5#-OjJcja7;lCPDB|}ayNTfE?hwxPHr)IX*OO_9A085Z$B4J zkz1KoEoV&_SYaq^#gkvUn@&F!Okyx_%2%304^K)KS9LjmV<>Mz4Nlghg3X#}zKviG zA0=5KW^yrlITuKUNsSL3CdQ0o*{*_UEp$*BTxKn5xPng6oPTp0EH#Hpkiddivw})P z4^N0pkhYmm#F}1%K7|t@DYku06Cf(goNL*qf2@f`&uMqrr-6e>jLT-EGDB0ypJfgl zBsT;@z(S4FqIz2*XK^-sSRZ6W4^UMeVMh~GUnFa1EOU82gijh=Ocq#E9A9cLc62*{ ze?^IhPLPgOm4AFghJ#3rJ_<@U14D~Wl;XFM-mi+kmSxYGZp@)`<5Q)WVxP2*OyhH^ zz<*RBA~!fuUDc+2C_6@yU~RBent42Lt%X{db3n(gVUad~PCp^KpK;%r!GTRzdJ0fD z0000&bW%=J0L~^S5E}jlH~vZewc~&){)uh=Z?;_P=6`|~M*QB~R>zM1{;czvaawMO z>zlmUrj)R?&BNy7?EJ^=+~~OC!~Um!q|uD|H`lM`2J>_}-6N#;SsY>WwA3nZ4j^8h zL8R00^T!ktv2$@^>Q1ev`(>z=;CMBTmCV> zsSl0j*L zPJbl2UDr)`cR(neLv+3F+Z2+qtI!~k@Z7+6ysm9_UboJ3x%2b8L?A?vYL;}K+BRi) z#_iIo(z&kZRNK10a}|A>MM{}Ai9#eprXH_!Ey|VFvJRBZf#q$dk8fNF3hZ{n(Jx>6k>c*mqq11eGe*Bs%f^>+kZ`N z!FD}&l|>;IBtukq#bOvsp_*@7*&aG>1zv4&0*4R`QMkWVRZCTD&DWSdB9?SKPm7}# zj3>Hi{(A-pp4gh>(s=Poo$I(`w*ffAwmh)1H$<>%5|saEpiwog(4BF)rtsebjb#U|FlsB z&8;zUoMWfOYNaB|x+&;ZScTR}J z!-$C)8T?k{&3w1!1ryL*3sn=JBmnNUBLk-&mxvqAhx#RV_PfnUmXB|k1Mg? jwBp$Vj!stMBP#v_bPX;NMGR9$00000NkvXXu0mjfyB!<7 diff --git a/TMessagesProj/src/main/assets/emoji/0_133.png b/TMessagesProj/src/main/assets/emoji/0_133.png index abfb0a9f81e99b26bf296721e53e42e40d94b7a1..ccdabf572a296b1f2d0e25275173f0b61b4fe8c0 100644 GIT binary patch delta 1264 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1331.png b/TMessagesProj/src/main/assets/emoji/0_1331.png index c5788146c745a925497673aad7a44f95930cc05d..0aee496d2214568353e32426950a8de35ed0a240 100644 GIT binary patch delta 1805 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1332.png b/TMessagesProj/src/main/assets/emoji/0_1332.png index bd3df561fee7fa63eab97c4a2e9e864fbeb86fa6..0ae8c3215f19d52b7523d6b8ef62eb7cce8cb6aa 100644 GIT binary patch delta 2432 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 bzw!_BNf;u4VCLZf015yANkvXXu0mjf^nwY7 diff --git a/TMessagesProj/src/main/assets/emoji/0_1333.png b/TMessagesProj/src/main/assets/emoji/0_1333.png index 3a58e7a546919066f9e947ee1a0ef5e8dc4b77e4..f873524117415fb1eea498b00ee1f20e8f674c8b 100644 GIT binary patch delta 2321 zcmV+s3GViZ7Ml`~BYy#XP)t-sM{rDALpp_ngpG`h*VfgHii>SnPutJOqobouMMQpk zdmbDdqneh#y}hiOkW5EM)z#IFi;0Pchn$(0u&k+netyG$Sc`{*o12DRfWq@Eyr7e2YPvb=2rh{AzgRpTc47yttd&w$Rd~ z@>cHO!jG)#DAojJ000LONkl{dG(!{qme{BOC&}7zk0p=T!2Pnm_RZZG`CM{|4cpyU|3k& zaC)bIPwsDTFTHcDE*M4&^J!V5Q8%tRCAR3((Lj8KZ7NQdnACE_)(V00gV*hR1{_sf5nYo~z zrUM~A3dOMyj0J>nI2?R$AgIrKix1V;#B3~9=8lUA6pTZos>1LAz%giZf>^e0+aT!$ z&3}EwtTB4bNvU8ssz!%Lg#p3f@yr&vbhbzt=H8D%7~!zGT#gxo$Hyo_RS-Vv9tc{S zpG?|~&EOVsUo*!+V@d)>&S*3SRjE4&q^^%KGCX4#hcM=Hb*U?rQ?VSD5m>5Jpc;=h zbHq4AE*7gxU$11DOT|Drg{0yXfGWu5R)0^BZimAS6}KLXr8w!Nas|oMQz^itFi4e( z!C3^u+R=;N{!TYF<#E~pk*WhCUES%*vcv%egh=7IGS0ZbP)7%&iG=r8nN#nac8VgM zUSb^xoZM&Ae681&WJxMtV{!n|hv9 z#Ii!ZI@#-Vxw2FSOr0xpu#Op{P<2|pKSa}CzJ#<;zaEdr>6~)vO)i9RX$f;3VtOaM zj|G93YVF{p*T1L(02Z{W$2J^JPXY@r0lm)q&H>W-^)8#urE?QzuH2Q3J|Dv{J|u7> zr1OP?UcVa&F|vN5Y50OGceMf3%x-QGot0Dl80z=@#d z>40TVV2sP}u>-Usm&VP1<_hb}Muvky`w{>UjU~1R?O~Sj<-vwDM_eO_MXP!}A|UPU`a532MVh z-bIuIA0uXwFk$z)%tgj00Al_I0MQOu**vz}h?Po7V6PdB4^mKgA|P0yRQ))5ykiP- zFnBC?uaSJ3^{EVj7k?O`#HucQY&zeWy)~pBJFIlJI|#0t!8SyIFnpy_;TcR|z(jgQ zo*nHw%HeUly)NnwLO#JZFhlfZ_zWwmJpm^A^6c$f$C^jyB8j_*ivsQqkUHTg9(-V; zQkL2#))$p8$te03heUm)9uN&z5>5TH;20`($>VZK%^@H}4v@qD5B zW}YHmD$V3Ut$$K2AXTfCgAXqTfQ!kU9iSi`OzwRBx@veCfcoRFgM*!~pdAq2o_t!f z7^vsQ+gwwBR^Xukf>nW`TC=FtIaY1Y09ag8I(@O3FBK|~fa(PGOCeE&$8p`%(;4aX zdcQv2%x5w@7&(|!y9CDgJnjeS^-hQVmxSs*MoX81Ldf0@^A7Z&U6i=W2R-TIU>7U;hJj@1ZFQXk3y2015yANkvXXu0mjf>1bOq delta 2818 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 delta 2472 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 delta 2357 zcmV-53Ci}V5x^3VB!6^JOjJcja7^*LILwa~ynYXrRs=CJFf%hST`~}jPz)j@COg*P0ewNGHsc9ISB=FE1@G zE-92%1kREdt85CCS_?5QDY0`4uy6{$f)O`0EZU$SFEB2(dw&tSd<~FO1oOWs$&DD) znit5E88R|3_r@=}fD*%p63&wt=&>irj1{YM6!XI|%aIs;MhWJs9Hwar^T0BJQ4N7* zB5_O_{LDAnpBl}O7UZlU^}#DiM?Ln$Ih9=whgJ}UM*><)EdJ9pi%kP~WGwl~GCDgr zH8nCoLO}n_D1W_v4e_-d$%+u^upq*P5a+8J{>CKarWgOwGylyl?6)WMxgg-B8~evD zFflOOo)r1LA2>KRJUu%|KP>seCjZtp(UTK7JV7%yI-htNS57u;RUxm7Cfc$!*Qg~Z zDk_biY;n{q!XWxZnOatC%tVW8*Jli6!BOrgzx$JpLH{`}^sp_Irp+%l*h<(qKXQ z{JH-1objgpXQY;W;`Y+q%dOM9DgXcnEJ;K`RCr!>mj_cKOB97ivZx@42r6I zr^{qax}5!xI*B@003vy{XMc zZ6s=i7#-KK=5xJ%6nQ9)eTCJ&pAW@myDmqk7kX)cUH{H^BS z00UG)X%*{N7Kn>OmW&12*Zcb{8JUBO2KEl=KrEQK2Wqfu0QrPjfmhTD&C)a-NcKT< z*ne1tr?NE5(iJ*jAFx2s6sML5g6Fs#9r%Qx6_w)&qQo%@X@Nk_vJ{(DKvR}xgv1Iw z2*Y(H%kTK0fbqbA6u>yN^e^1R*~^YT5PPDFzNIPcMJ}lZfAX zzTA7#H|P*EJdmHqYOnEA>dlsqnPyb^F2j{J&0wkgnucX zFvi&KrACcWz!-agZ&@C1qM{1v#9&Xge?L(Xgv!p8H6VJiDxJ9f5jeu}>VM@WjyHf> zDT!k0!!_U5w2kX!A>-h`0jV56hrvBUk_q%4+qyNu|0 z`4n7*{X-Nj7=`AGhs#LldV|r#1tgvlZ6M4|Gv85bksl6Zc|0RayYI8O?Wyvf2bmhd z@@Ts-%oPHHcS$RsPdRLwc7Fy8u#TF?Fu$>AKO>1_4wEssp=q1OV`(t*dC=5;Q{!u8 zB{_xoDx$oN3kV#QvK) zwUm<9KO(;V5*hNxvI#I5aw(#lQT0nB!u6D?PR(hrSXce_y;KR_I1s2DcB-Mj`Jk9y zWY{13?ykB#cHcb_{e=n~w=A`h{(=h2M<+f1Q?n3!V8J+ z=~XOmglr$V1L<9p#(&8JhSBAkgw=NhP@QfIgm)y50!SM(;)T^k49$a(hMITvTOn4_ zLLLKUcn!nqJl0ja8KD|pMRCB;u>xK|7h!cG4?f0pJ&yy`Yk`;sYw`T*Du#ou2{(*D z4a6!yfTn3HgyEBSI)NRI`g?7C54-_ zxLZ@_l1NZ?B+e-mM}L9TI3r2CFoT>?3MC{h9>tZhlEgFPh+~Wbh#5%TKG&pD)`x7L zDwIl^8R6PXNq;3_92g1;M~}l9fkCPA1#yEID(SO8%rIK60z{83N6|Z@(35GGHDv?1 zFQ4W(a@_*)r9v^Z!QWIlIvIrxvI>`+GFY5IF0EMX=Z31L4a8Kk!m{ho+50N0ni({l zXqseadLw4%RE9BDy2n|Tgm-%O?s~8@;Ab-nC9w00SSdxT{W;ZyQTW{wf zfogFk>#8ij-I^JaB<*g+>zTsX z-yd??>VH_zbMKF}FPpvjml0PO^V+*-gwuVC?a8X}f{E#EG_}n`7bpNC4Bg63edB014czEc3K7`_hMRWax-vvZh=)K)v zz~MJ<7{@WAX|fA-;<&TFW7<}AfB%PX;5a_?DK3S7V%i(}_(Tr*!6fFd{`p~V|3}Xu be<$((n6C$4jmSQG00000NkvXXu0mjf4f1tj diff --git a/TMessagesProj/src/main/assets/emoji/0_1336.png b/TMessagesProj/src/main/assets/emoji/0_1336.png index 05322b5591dc86f03ed8396aa8895798329dd370..1a94dfb65f8166f6907066d665d54a2590e0b94c 100644 GIT binary patch delta 2038 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 LNkvXXu0mjfczoBm diff --git a/TMessagesProj/src/main/assets/emoji/0_1337.png b/TMessagesProj/src/main/assets/emoji/0_1337.png index ed7688958437161ddccfcbc620bab31bbb0cd5dc..9a7c7bd90deff355a9d4f4784b1ef738bb6651c5 100644 GIT binary patch delta 1912 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 X1ri%y%P3NC00000NkvXXu0mjfWcI#A delta 1012 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 Zm0#+*d_`zVV6FfF002ovPDHLkV1hq8%oP9t diff --git a/TMessagesProj/src/main/assets/emoji/0_134.png b/TMessagesProj/src/main/assets/emoji/0_134.png index 5a975e9d2f68a68c0905c036ba842575648113d5..127c84f718ebb3bf004849f103e9a9e3f087a456 100644 GIT binary patch delta 1260 zcmV5{8B3w*4uyoQ=2Ux&+9zB@_Obqcg^+MX)aPfCpgP=dfw-}uw%`;%a7X! z(Z<8c>yY-#noctKGn=tn<|lHP}I z^Q_J`B@`DhCZ2>oU^IY@vYcAps}(q9H9v+eVWdSsHyJoC1~s>$;KMgh*J?}X_htpU zL6#5=cz+q-0WZ3|I!oQ#Ch}}cR0TLU_C6Y{i7{;k$ln`J)^0X)JicGY^>J1Rz87Oy z4aOW0T{};R!xs{vCFhXkVsX>=)5M5AcAQ3|gfzBdqiAOwXBTk29q zWzY>qT8J^SVQn-p_8=1`*g~?$*~5VIdy*a$4S&^}xLu2^f#n)-sS-5`Bo_k81Quq) zilK-N(ME+NebR=2#?7d+RdFzs(K;uhA(I)PwklAAoOpsW~14Ckz9K5BmuVi4?1qR$HW z=D{vKScnEw?=8gGy_2%=h1D0hvf@NDe$5W&X3NB|T2 z##;~N=Ci~48xiM#2T2$PEzX7`yJnT95OjxBZfwLJGP~OhF{~}rxl9^rHufVx+$R=I z$~d#3dIio|mqZ*9pt>iDXf~W06_AtI-8eP~d{HG0Pi9moMpVSwv|?S1RF9kSV1I)0 zK;+)DX#!q|)Eh$+jK}{(n7AYfU7n3sAt**zS@W(q`#7Ydn?m_8D(?~Djad!W?gFIK zoUdUt%8N2N5UrK4Fwc=r*_^+EF-jP5UWQA|k-DC742C1fYPg*eX`=`urw|syh9GcZ;j`Sj?$K1|m(i7nkE1n1$FF`IgHo59KKwS#SN~O<8?NyCl*dwU-G2Zr Wu)Zm@%^t)60000EPdsozCuB=LY*R&hNGx47Aag`1 zWMpG(R7PcGV`gS$gHJG#S~r_yJ&IK`mR~w@Lnu!y8fiQvpJ+dQeSD0Ji}J5!tN;K2 z4|GyaQvmzSgE;0;8UFsOyJ*{yT`AMw000BnNklPP9n$a1eW;6C2;!?MxC zor;u?$GfYZcYiyhlas&h=Jlxtrd_q9^TQyvDXwDetA|na`qy~xcO@B-a+_os2BTSj8-ebF%;n1N) zqMVbi#3=y&!7z{Uc0ZKR)$_cr@V4!YIIAIsP>DmJ@}^Z-z8dgBX+VdPqdr9Y*-;IBXX^ zqn{?vTYrzuKpR12Hud>fB=UNf7%mN#c0#1q)rdjIk!M|s^W=rnz}rZSA%ntLHB9ED z<5)&;VGzy%n6yw^J4^ITQZ}i9|KF*faxq}aupFgo7z;=t02Kp}NR2$@(kM?J#3jU< z(OV$Y-kXsQh7a0^60)rt{N%l{?VeYRc+Mg}nzs5_@x5 z0lLlt&!sns;mhtI>Kfw3K1dB!P}}GpK5?bv1+DMhX)U(Fa7`z}crdp;N6G8HkIK zM5s(eh}hIJWG+1aTvsEgUB96V!6l+K903Iev)qko${&LM*!8d_fIbh3mDt~wX%IfvQ9+N40c zQaTnj+A7hQID-$tdu9}69|h=rsj>M@`qqn)J%A`%HbiR(F%+PNL>s0#dr^QTxKf26 zO>)g2;)dAToJCPaol>OCH+9V?aorTcoTbgd(75I^qn*Pf2|Hv}F854(c7DZYSzDw7} zZZNU*@DN?|b(SS2EJSX*=C9MsXxrF}_xEweo!0*cS`LmXa?z==00000NkvXXu0mjf DNf;)R diff --git a/TMessagesProj/src/main/assets/emoji/0_1340.png b/TMessagesProj/src/main/assets/emoji/0_1340.png index fdb8b0deb2e4c31701b4752b38a52b201ffb76ae..11927d4d7f28a9cc5189b82558d1542479df9ab9 100644 GIT binary patch delta 2194 zcmV;D2yOTF2b~d+BYy#gP)t-sM{rEu&x(hKhuYGw)5Dp^zpr_Cc=GA9)ySpU$+MJ` zlj78mp`oCCeSMsqoXnSOpr4+`j9|yd$Bm7RL}rbPi;I<<N*K$&F-DUWl5Sn}dUc zt*xy;WQoq9Z{X65-p`4JcXQp(iAZ9K!iig1QdhmbyQrwBuz#?xbYxk{$;ru_UBtx1 z!otFrY)H?TZP1!>wzjsSg-ShRh(%h6*2H?Lnss+>WX`o|zpZrE!+P1Pgx9Bl(w=qB zmTT3cd&!MspK?0euZZH+km1vgff6^X`I4@SU+y3*v5UXf=P^H zFy6M0m2EZL%zuQ$qFS|)Or(83bxkU}n^(uLWruNL&bo2QqJAzN4#1dnsfuj&>&iiM zu;jy>;=h@KSS++~LMuF2ODGX(J|I74k2`F;x_M9BvWz-tu`^G3K}An4MP={Ut`!gq zyNhGZ%f#!yasK@7)WCN>akR0dg2=(2vn$nYng%31I^u#J>xmC^YA*!TIW za^AxJ+?0stw0qd#tkk;1?-~zb000JyNklO#(N>-;}cUxhUY+LDPerdcdwNZ!Z;HG*# ze_G<{oif#pm(NT$&x9Gj4g~0{w|9zG!aRFuaq{x*z z^pwC9i^Zh(L%XFdrt-O{9F5fx4+$uj6F~tJNxCBoy7ojgElKKnEW4G}Qb~^&(!@}L z9PY?Rz8T<09S$4(Pd=5(sG_JyY7~&ISbwglr;3*3G-B4}bD1a#PCyh;w6!cM z`H24O-!JzeeNSd*&(6-i_L=AU?i*|thQTd~-d<$pvboy(>6;t+6zbUK=eWi!|sLa?NN{Agd_V$-s6 zjKzYdi3|{usyJb2yb&lylul2vy@}W~2U{@RhM%52<(l_xN@-DO#h$ZLtybdxe<@YJ zS4F2NN@_aOPYFauXBUCEoNzsluwi3%&fbFuSsIr_KcMB@3qe}wMkEYnKFfGE`pn~Czt(og@&>dFcr-#4}L zNw)S|5L4;2@&cz#n_+n}(4P2qkv%y%+0<$P0J2&uz-jqM?HGtmv_X)SG`HD>*9cK5 zmp6a>y7&eLr1l$6Qx{0YqJPo?X+F*HTx&BlXy@K>E&5~qSFN@}b9|A4)8m>SdXWf8 zV@(4r_l+%ttip;o{VV6^$HxeK`-U&a=jZMfygOu7e%{={fhUVhD_o5a__i zRX^OPf`SBhDH!K^42yg#AtK=?#41#=N|6R3yo@?|TN=PJaXnejvaB4hg5A zsH)twY1>9jI&O00S{V;jxj}%i7x%+K1VTva!~UiL?;TLekkxXP80(jzpEwl8#U-^; zkp({~0tiuhc&~ZepB#ZXn64ALd-Z;jaY|@?S9Sv7uM^YFMY9$wEUCqQeNC8$l1L3~ zhEq}E@J%q>%XN+(EVB@e*Ex}+=lu~v6aAW(k z4}Sy-AUGYq6R}KW~p0Dl1qV<8WQI#uCA!ROoA*$*BZ z9c@644ubmt&@_x78l4CLkf7Oz;5!j$8JEUut^+}{b0wq*nr36LGl6L(z`-h-r^4Mp z>|7^kNEO}6K!O?_h-Heuo_+N|sUD&Wz9 U1D3~201E&B07*qoM6N<$f(!XSP5=M^ delta 993 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 FV1g=zDi#0$ delta 921 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 O002ovPDHLkU;%q#AGcz?SD=k1k zK)N`;H#a#&Mn)$mC@(ND>9jN`DJy?~fIv%paBy)(Mnz3dPADiYC@3gKMn)YRA}A;* z@Xu7%q@OuCIVUG4Ha0gsJwr4!Gk#Zwrfv>IL_`x46#B<6`G3nll}Jwg+iGlWZc0iee$>$ZS+R8&G19 zO%zi~6H>!{oMFjZELJsU5l8K zK+)cg?f!q&^0a`#m2|#6nRu<&`laEC>fP|r^T7S?@A;bB?S+iB7uLmN(m426_o z5roWOX67(s`9Jl_cI%uzbhq1cdiv0LTCiFL7dlfWzUi@FcR%|1uSIVmLr7>v(4I$!nj_ z;;{7Kyt8=MH|0y51dat9@A5tiKm-bZE_9AwJeJI-x}~S?mqhVtr}NTRr3;f~e1D9j zbryX35@zW+CD@BSpKa!KC0mXkFSPW;zpUS07=ONwZ?ArI=DR(LhSOi*Q9$sF)3(k| z#aO8``Z-@Ay8#dh1K+tOnP1PpZyW1O7`IEYGZ(k>5$YRk6E;O>=boR=@7=py%4Zvg zJ8d4%m}1XpU?+{5!g2<6GR38K1zfq`3q85pp8Pn;M^5aFj7HjN@m5l3R}_e){7+aIO& zb}znkhwshf0qo5jAy48=Bo=#9z23gQ-jT(ABK9mAjmLi_G#Q);`=dvF-HY8zF@yR^ z^D{i|cxEN7MQRy0VpC!Ri+}6aukY&Wf~avT%DkE{EEH-`iVUT|oQx)WYO1$;ml7p{ zklBwQ2*fb+Z;EM+aVu%9hB=jm{mGLjz3C`NDTy&9$Av<|TzKVkZ5ms@nixq_g6KX+l`p?e zBvw&Y%`O0}>?D(A#DBn<5#UN7pgMo4G1d%?+6m~9F3qfWR7X*R+V0vo}NaI`_qaHdcEGD zLLwAPw^c&LLWBqg`}_N?ZJ8PB+?3CXAy*7NXMzPHsYnDXsee%BU*Bm8RJ;MA`$5da zuFJp!flRD&87g=EK1}6iwi~&I#QYQ!Bge<7R;_7?tw9ZM735Yw+xV;9cS9G_(EHmC zbhIqrDqN&`OOWgju~uh+xEhVo$^!6h6fX6Rx$4Kc$Jr*q&UnAwXWmf{+e%HlBFUsYh9~^ zq=K~W;4rm}Xl=*A+Ji)bkiyj=lBy8H0)YS)Z`F}8PP0>zfBl=9hth7@|(|= zmzTGl)KWPdC%9a7wVljc%|1OZEn>A=BWZc*k|d5H&M#FO-+r4+Y|PEgHD-cmoI@)5 gbNeO!Ed0mgH+3epk`34-0000007*qoM6N<$f=ry^XaE2J diff --git a/TMessagesProj/src/main/assets/emoji/0_1343.png b/TMessagesProj/src/main/assets/emoji/0_1343.png index 2762ecfb12df23cf828c9c557daf847e70be975e..134d289851b1df3219ef61db0b92cfed464eed5c 100644 GIT binary patch delta 1851 zcmV-B2gLZ356TXZB!3G~OjJcja7;fkEj=?Zy}Y_MCLeiuc|=ZOQ%g?Q($!f|P=|+y zy}iAGfq|KsnW3SfkdTm|prE(4vP?xqL1KrAiHVh!l}9~3Oh!hMl9DPO8AxG@#l^+R z$H7%$irU)RKsq@wBO5s?BDlD?si~^Z8z&kPJ#n{XT3SjrFjP!TP)JBqJ~jpg1WiRnI%~IIRaHK0 zqdsSsDJCXIKR_KD8#ggAFG624J4rN8ca?8AhIVDVq5B~jM z-F!#V{`$zmxv7P&_2rDY^(QvpteA@1$?oEv;AP0xWB>pK#Ysd#RCr#Mm4{a9S`dbT zgb;cW!FJ@TM?E{e(0i};{{ByLXC@dUBH{-tB&;`?0fZqc7k($n@zLofO#(SJ=b0+~w5{Z)W!;Z5~K4jkN3n)}|+?N;1cDkZAR`Ua2>KqueF$W*&ZU-edc zX&}8uM({<`XBYz)dX-95Rq9H&fyG}TLr+x;e(o%F>I>xZYZN_o(5=_&=AhxNgclUM z2B7fo-@kmJ=l6YOFc@?d6C{0-xPTEHu7c=Q3x9z%if(t%H+e((A|b~oMXv!N)+)Mv zL(?rAB}%tfbypMlq-dxa(JK(6ySs6b6pF>zheU0F1@VOF5raa|d$)1Bv1~S$Ed7C6 zd4G5a1|xf^R4NUmQjz2t9O4O%<3tg=a3UpwzJ6cP85j_dfW@#)@F+?j(ljb9FuAG} z28+dF$!s?SJjd0;^?X0Sy#{X6Q@Avq?q?D+6kGEQLrk8oPceO)*@pi7`qqLbz;ZM*4E^c#Z6--Z z-PUrRg7}%ZzLDAe^V9R|efru-F@L?E;pNf1ELn=73m!#c@9QuO3m0`holIV)Xdp-F z1uh?8!!zCBad)~z(}&!u!a{{C)3zc3Ibe&xS2AocONXuHa(oty9ExicD4;1&3i^O` zsW}SXJI%9fJRgjHQRq^c6vXu$stHnPmc{!$!;Eo0@iMj&W8cylG=d7qkAI&_9T;Ru zv-tl!eOzYY@F$k|tPuX=NkMfrP1iI{azjWu?+^G^6dWnM_-UR{feOhmEM0aL%sWeZ z${oW2y7^3CA3H$@PO;3Gd`rWmK4_NS7_n#+o>MD?uoD`ntO2?Xy)ZIRAD~;w_vd#4@t~kXooPFma5lI&5P$xJwjG0Turq@2 z2GtS}$Qle6=Q{`6Oa$uB7sCOARkTn7FYJidwb6LdLCcRFEs&u~|G_-Y0TWm-SEdd- zodt0IQ$EP6Nu%*iyWK$+JHn=^+}u3g6x+j*N?S@|2z*E?7>ai{ zU}cYRB!4P82vr>o7w|1WmJYTP`Zk5*xN3t0EI>~kjfUfPv511lJHV0b zd^cD6tzxlwb=B;Q$3tS=X_A1rBgqB_DvC(+3TXm#Muv|VcTSGbHwuR)+3fP-XxC002ovPDHLkV1nKVPk;ab delta 1924 zcmV-~2YdL+4wDa%B!Bo&OjJcja7-p9C?g{$7#JEfGBFJd4qjefSx{X*IY>D(I3y$` zH#j#I6cZyNA~G^FOG`{KF*JI5dw(W>P)tfyRaG}PHZU(QCnzUxZ*W#pQY|ele}8}- zB2BqDymD}GHZ(LOBrQiqMl&=tNJvOPOME3ICqO_zMMXqyZGUfBRaHVlK}$+WDk?1L z(7T(PnoM1cmQ$f9CnpLC2|7DGAR{zqWMoxpm``MtxHrAqu!(GJZB^lT&p##TYp(v_RXrKcU{++bT&S1PF{;U zMRn=Al~rk$5*H|xEtg~-W(^H5Ob}9bBX@}^i@ctIZZuhbbaegOxK$fYX<%7MHYjIN zNXV6Pc5Q7(RfIS_V3%EMTR}EeT5u>WTrD+Yo-m?pA8osaaJ#I{_VC^ z*w^U(w(H5v)Oc?9A^pl6d4Zt(@2qLv-`tfDHs@S_d77>?n3La8efj?WlcF(_!E3Yl z;DON7u=v}!POHpIx5U)R;Qsz?;{SgD00iPmM1Mh4cwX(6)pHw35XLQO1uL}B0$X5N zwq=Sri6M5tAv?@`m@K0h&CDF;+`oAvD>>)k>UM9g>gpcutJ0hLH(z&8_iV+#tpBA& z5bZw!=mzbcXw+lZK@-gPdRR8Gi|0MC47(rCaBFL8yPK>Fj(~(RMq+I@k$14%ITQ+k zo`1-!Y_qJ8VVI0Q2-geK)AdcYo>r4;qp<@nlh)&fPc%uYUl>WX2@WxEXJviGNETyT zq`DK<#izphO0iJbf_8DeuwIB23Nhe>tb#*aIS%4u)8kv99)V`Kww?xv)Od1-zI#8T zi9#{11HjE>tZ)|TR1>TnW=IFlo<4mOq<`|u85K!qnqX)B(eck?>0|wBl6FDwi<9Yi zJf7Pi)k;`I`>_%tp57o&s89q7aWb8Ymz29t8t_={HX@5Su zn0=Ru70yH1I0X>4`RvBx^JFr139_eeN{GePr^)f;-*urayT}2=+w9^OFtKN~vSWe% z;QTZ!%YR@RY`prZYh z&9($gJWnNeHfvFtCVFQ|dIo-zQ-8O9Ub5MMiPfj6ooy^2vlO}`Gn11ulR$fWbraR2 zzs+Y?pQomi+dNTKAs11KuA2gyn0Wnabe3?u2YYLJlW38T0LO#Vs}I!8St;>-YC85F zr`%zeLS8LyloA*PT3A?Ma0=&$VsU(Yi{Wre6OmWYk-fUQsp`uQSwgQDt$!GY5!)|{ zFN{K_qn~nnQCZhw^5x5y`^sPo&x@kK5L`E~L(MJE1(%=N8n0kFn z6~Q%XJ%;fNhA}+Bv>a?+vwuG!`I=NZyN=X>3sD_xu-;a=yiSbeIG(2INO|*me6>>5 zFgUAj93U<`{3tMG?ua-YETdPVU-R@?3{s`w4I>ALZoCmGr>3gM-5KRKm;OXhV#VBM zhelpcO}wh^7VmwfDxx1gv{|~E3@D;gxDxIv2}BpCu`G;MfBeXZeSa5*2HOV!qVEIM zhC3WwIMfirBoUS8XhPrxjKdf)-y&SJgdQrD7OKr^0r3qDAq$tlC8q5%W271q>S7>p=a}4OAutC)#)k&xF-15GZxVs)r>F;)SdS!fHOp)s&|AUo!_=ivnbIK z?N!cU#rZtdMkOx#?0@ATE^Iyw=(kGUi`Hn5U&9D)|Kp*qa#zuC_`74xJsQc|IcV^5 zc`Psp{#{R9IA~GxAwlP{I?a+Z67XMr?CU92-IVaz6-}H=dx&WAIi$aWgPN-Yfxwdx zC?(<*-Suo3J;XOzaT)u<<$g5W(>%`+&WAg1Xg-A z6z(ZqYy>s*`>DJa@FZn+J~`id$sZ_>HsY$stzuteV`HDymvEX8Sqr?%()KG=d+1(S zYf0d4JYlI-n&rOAhOU6=`}abjGAWfxlS)w`Us~Otd@WS`$Mrjr=v-wBL5kl10000< KMNUMnLSTZ8S&X*; diff --git a/TMessagesProj/src/main/assets/emoji/0_1344.png b/TMessagesProj/src/main/assets/emoji/0_1344.png index befbf22fb07f2e2a87e9215ff181c7535ae4ef89..04dae50195d1e70a4ad142cd2f4296f1ced0f894 100644 GIT binary patch delta 2084 zcmV+<2;29f5U>!CBYyzcP)t-sM{rE}!Ylc~DfPZA=)O?$yfCkNL-V^U=(IXdA7S~z zDDk{7`^PX^D`38aCicx>XEkHoqb=d7Fi|35|Fi`G3JK_q-tOvnl+?I6dCy*l&6N?;~#{?l9f)^Y#IDXx1WUM>VG3pW4HME}bz|Isl` zCn|p}j{N4P`rV9iD}aqFnTlI4fKg2T@4q@40(8Pc?f?J)8gx=lQvkEmU=21T{{H@! zPj=I6O2rtr(PZ zBID3$cHjSv_TCcK2u!p40 z9s1{GBKrS`6%gzSv0An7uMu;1Wr=_G!0h&Rj+xEIM1S|?8u7k860_O-=F4RIk7Fi_ zhx-}Kg@eTE$g=mefZN7>(!^*UkkI3t2GiSVHOw# zkgQR$CEWS7hV+CJHAq-wC}h2ASeyZIbw1}uB32EK<0RkK9ggF$TCKY;*BfF9r*YTo zZ#G};1AnqsEVjg|`~BC%O;145rdzFF6$`9g1p=(B|4qQ^^w3al2Q?4rToxmdA@T9b zvgipLCuOW>RxM-9O=HY;!dB4>PMW3;Bvq>GR;^<81q2W_{DV(-#w||_&(`pBY8|-WQ>HgO}Wl#h&l`MA{ zLlllDc2u*42vdQ91e^S7mrPnDw!5t_jH%1YM5&ztr|(7ALVYI94z9{>E(`Zr2SjQr z6-hyIxM?XE8mK_PVP&O|h^Lp!m>h5*tdf*S5=A8EWyOOQkU_x`V zIP>#<#F|ndn2|nVSV5avVzco)KzyGDIWD%m0Yd8{jL%o-BB25G-At9a4r3%RPk)bS zAd)1|9~#NsjVfVkgqBkt8UR>FjJap?kG~ zja||(fqvK;pa{&y1`+5^$yw(Uk_W}vWXv5JnTofJn?asq1Q&)6nBPvuzYpjbN`; zIQD>QcvWg0iL&NW`r*konNI@=M7a|>^c=M{WmT2DiHCtS5|0?sq)AV3NqjR+*?l?e)4#((RLpH|-vub^FA+Ltg6nM3Hq3E}$@e(u*L(IdhOWBA-j zyuXQ%Ms*1S+>e|QK@fmKWQ9HPhAK2I3au@197iBP5QIeJl(?s0AVQ2SV<18(E(nKR zg8ksOh6th;V?t91B6)3sQ5kRzh~px1E^-U_{uzNmB@(sJAvUF7P=6i-pI8AvVoUJ- z0RHr3OcXX64OvHhQ{sjYUJGd?@!4^&`&fb>*Z?sbe_RZPPoxRL1P%G0A-or8o)ZB2 zQPVSGY;aD&fRT`@2X@lw1(HWT02&`!7h~c9g`*KfxsfysJ#X_A!bobKYXrh@5RM5) zb1_>aM?)VC9)wVchktDh@jnWI5Fj7`Z^Qpc3;_btBVZ6wo2UQ;6c4Wlpolon`x=U4 zl2ZcSg*i?~F6&YR1sE6v0#F6%g%ER2JS3RGfE89&hUXD2tV<*OE`;79fUs3VZ*lS? z$s6v6A(%_-sA(D6}UnKKs;@QAi)_?rmmvCi{*J7j;K;_T- z7Zb$7R~A{(p#ljE-N$^LG62MTkh)9GaKFu(Yt@58%0 z%%0;G2$b?cfi#h?-~g1dgtN5v0Z})pRg>OLSEpq$0zy1Y-#{MTvTpT;#I8N-P zO|{>@{IDknWOiBtUOvv+%0Vh zV+9Mj9fUUkl>FnzkC*SuI}F?aUW|17vxU4Gw@|}HV;!8gRoXf}1Mpw*e+b{1)n|?X O0000Y;A5OBqb&$Cf?b@ z)Tx+EU5&$=aYj{$<=?Tys(wL1LAR%Nsftx2BsEWDm9{p%w>G`t*{BE!4s~i|xO`Pn zQBprYKuStV5fdv!QGbJift{V5Jv~9OaY$G@Zq=%SXKHF|RaI4pLyAK~ zLNG8e+R>dWD}OB%6+S>fL2XAJH#j+2T3LL2d|zK)fq{a^$jGxbxT`a*-`AbgpmxKC zSmfQS&&7n!zPENmOkblF&!+<|ZN=iyZL_|D2J~cHr z-LHr?K5b)SV$G0c(wS`4p?B%yxO8=N#D!c{R8z7xwQOu{aBy*}G_9L`Ksq-$jf{-r z+on53b!jhE+NpsZB2F(gVNVlNOInDsm{Pzy!CV?$Wgcb?4lY1Te9pgqbR%`buV@w< zEQ%_N=zl{vq6p@BRM%+JAhrw#g1%#$s0_7RunGTug3%{rhP- z-O~L({H*Thr2Sm{wXPeQH=mH*o+bHnd(r-zf1+*Z?tqJQm8M;fu9V|x*Ur=1^#1+R z*YDTFva5Bs#Dk{Rj*#%l;QooB<{$t71q?|&C{Ql{@0X;-YmBXtiu?g>x>f0O9h!dlwErI9kA^Ik8rNaC#l9 zx9|M0`F;WHYXG3{Gm7^eeH3$>{<;M#DPlxf**u( z>+PKrCu+E?K;f6;eyKE+e#`5+(FS3hOr)p#7ba%c-a4Gt8!4Ph3J{@J&nG4aYMrjd z!(8IPx-0#m7qgQSBLmNzgVqvG1%LU>A9^hXh><5w$Kc^lJ|2Ia^RK;#BL-F-UdM$` z9@K=3(Aq2M^NEpXU}7&OvCbh7_VM>uuU{-kCr1XH4#%d3EudmgTopBkAfRsP!os!* zN3BA{5>b(n@pD`mdy8`ThrW?YrL&XqTzc)Pe3mBmWIW9P6!47pU%fgjm45;g1FKH2 zkIZD53gO5Ul*g{ZZnFl8bGJmqQwYg;?X=N806!6(Jb;an*moJBP`3N2Hct|8dlmk1} zVp73RD#bklm_=82_(+N(8m?0^JC4vKK~OTWsX9Ulgb-vw4NB&m=Je3RHd}JJf+A5$ zCKJnO0#IlYQO295E?O^V%x0G2AgJeXvL-WNsFsl=jgTaW36UiRM1QWbr!mFBQ}pef zw%Gt83%6*}1PT(EpiN>ihyw`gLQ|QtAySkUB@m5z6%WFM@*@I;Pm74#`5)rMwIYV1 z=Fp-9VyIk_3vY*}F-n584%!w^WzT0=F&1r8$8dif;mL)z1>b-FzS-DUD&oOHIL#i+ z+hs;EfH_W_)=u>fC4VO)p3aj^H7VH`#J~Gnv^n7O5k_;CnFNU4UGR>HDT<~@f<%IP zgz7O~Z_(+r(PmuRV9v_QG8+kd03dc#BVrPh5wUpQWD4BP&r`MwzBS2wdg5L_9~LGF zg}h9OA%FLp3S_2ggq)w6pP$#Cfu?40jAW|LK0;6Dfx}AsshmR=;`<$=X+eF=lbUZho1K~Y&cui3Z+ZcndCJ zu`kk8C1)fj_ka6DP`pVzs4w+TguD(79OFTZQW6DCX9~_lwj zdayg0CBOHexZten!&e7RtC!%O&fMJGP8^jeSZ?qm#^#^U9qx6hT6-WEuxnFwa+co_ zOw`w++_|Uu8fANXyHdl4*egl+H~$u(|G54DHf)uqx(~X)G5`Po07*qoM6N<$f(i%K A6951J diff --git a/TMessagesProj/src/main/assets/emoji/0_1345.png b/TMessagesProj/src/main/assets/emoji/0_1345.png index a36e0e3d83a906cfff779ff43d32939b01e974da..7533beda1faeb6f47bdcabcbb3197bd84fc3ce34 100644 GIT binary patch delta 2098 zcmV-22+jA<4!#hOBYyziP)t-sM{rC)J32TuG+Injn0<9sNK4zbmt#{`Rzpt9ns~mT zh|-~d*Q0+>Bwt!dP=s`7FfApW;=;R(ZS}sDTO?|t zSu}euii|IpNE}#&Et0jEfoUmsb1Q;>E{<|LAZTc4Z*OlSXi1G0Iw~z9}@50Ac_jG^LArUDRS@JW2 z!^cdXeMOvh)kx9Lh%?`c)QIx03Em`*j(WWlNUwK#w0|W=qsaRH6>-MYC<5Z=x1*Ee zi&i^Hk|Iewuid)noPIkCkx=YQ;yWDy!K85vyNmgsZRT@uE-pd_#EAYp`hxgLM+&Oo zhL_;Ze=u96a2JxQ(dasor(X@EuYh3OPYM*8`7=*$cm%{K;%8qD1RH@)N^kz>pM9e! zd=@D%lz;UV!I6k)#Oh8O%%5asp#a2JBRR8hMFg={UNYB6EzOGsN8x`E*P2jZ6dufE zuATY3m|tNH8{c7>EcaDo7TOtFl}SOwUU^ zw;BwpOpw5=49%A|UfQ-T^0cz;fVdt;n5HmE;5fExXu|7!LR=(3P$O^x zr;78q3~T~5)WH{~W0w{XYp?zB89zxpBubkE!8p$Icx>8%i^eX(ap3?1;U0f{C4@JD ziGO7daYPIO<+o#tJ%bQGQb@Evx}ryI;R4Y$17Z)BvG1pV+>1st5E0w}QMjJl`KS-i zL}EgS6T~S@HAE%<4K*b@#0^#y3D<3ZFqD>nDwKL5fnBABA4*6F$nYJ z7A>%8_wryS$1Z_Pl#FAaTT~4JxgJ7Lp;TWLNIDQc5CkfA#lcKkCJBOIqQX3tC?J8z z^%emGkT9JZloqg*h=W6Zgzq|}8~J(2Ssw-c+*N`GB7PoARyYKW{ae20fnbZS6~|Zv z0Hf<`cwmOjLPBh`vK>MKbN_bj2!9Z4)9~|@vrQlPqaU>q^&@><<1`%DjuQ~`vezVz z^%shr<#EVqzb14UXpDe>^syP~$8qU^L5O?OBrZ?@W3iOoNf&nSHfyAgqTQEnn8ssV z>kzZEcQ%2*GRmc#6lSq_nM@{Ei|)1*wzz^fUKWMOCfrZQHY^6BIg(x*_J5;MEhX>5 zQqOgh^;L9TXY{g8T-PhsR}&6Isn-VNqDfpLix&e3t3Ol`L?12<;ERYc8o^vFAYdXG z(rOaI*%)RTN_{S1^L~b-`glk`%`{;<&4bZ1Yr>fVVNs<3Ifx#uqE_hVK~1z9#18_4 z4sa@iWe7xHfzYgE1Of!g;D6z=L;;N^aYCFx8#aMXfT*`CipQ+q*Ni@+yFQS(JRo!& z94l4<01`4}lya$bA0S{KQy9jkWO3Rg03h%aU>Tf2BQ=5F<+0Qvw!yf+%s|jZ+vZ;c z1j-ml$*>d5kokF@`wYRlh~?PE{aPV=#5PdhRN`$?8&G&?so}1OFn=}co)I}9Ob8mb zx#VnTP>bqgf)|xy5f!wtGk!D(a~m|OTW$3HJkF=^%=0v)T9C3tfnW{^(I5i5yyX=3 z$ot>h+;e>}Z>NrffLV9lIUs~UNMF(g)PYDmzQ>GnrnImM90ay$5*-16Da@u}fuXn` z=kbz57tG=)1P#G#-hb`KNMN)P;An3FVNeKTP>%-Wz}X6-&L>1|WCkL*9}vsBy)`ns z7Q{AYr%4Fc-68sP*knZxU+}%hqt%aS9B0LY(ejTczAe+Jm1Z-l`k;}Ny$TF zJ)1o|!)FhuXyoLe1l<3=%k$gQEGut}Z2^mFHoJQU0S#0%a?xuDuW$J48^kjrvzeP= z;KkG3`y&e4z-Z(gjaoPW(0F`&e1KJYLT~Sn8rYR_Xe;!7K@;0-7N7%49o&zf?Bz{Q c2XEDX0U~(SX0r-b4FCWD07*qoM6N<$f(cL6sQ>@~ delta 1858 zcmV-I2fg^d5YP^gBYy$fP)t-sM{rD5Lrpa;DPdq?E-f!IGc{^zYF|%VQ&C`hdweJ- zCObDYD=REIFd{4_CM_*7epEXyFE2JWHzy<^4-XMCGc>q3yA%~ZKs-7(Ffv0!L`O$Q z7#Ss4ZJ9bdKt)AGL_|eRPEJx%Q*m)|i7JY6TuVhoL^(M*a({V;cw1aoJ14PodTecO zFB}YjZsul zV~~q;S}inVTqRO@KU7s(a5z0+#F=ubWoBbZGX+a2M*si-XmnCeQveqo{{ATb0txzHE4L1;sp28vteEiZSO;eVLH>@ai642y8z^(JmsUFoEAc1}9o zi+f)9MWp%7^T$cszpVd7A_)0U0Q&y!@yW^YZap;N;`pOV<>lVX%CZrX(EVu7QrQD~ zd2}9*fIP`1EZ}^lQaQS$gF@&oCE~fGqud`2nc#AH{@{HsahOUaQmK>+E|P)Ev3#PM zNPpx21Tq=M$-TlswQ9*9LL&yQypI*)wO9cjalcR~#DHpvM9L0_=)W8Th`eQJsG9h3 zz8`8l#sNaE#cS2;?%cs7RBL<@lP$S;tT17utGP-yR6eJdzq5c)ep)gOrE=4dqfT~T z{!ngzFf)`m1PDk?mm`r#X1|(Rh9w~1w0}o{%KM2+1|8hYkG7X1Dg(6obps4x>B~%4 z2KdN)cyjHUK@T&nUqv#>WI2+F=dX;wWn!tlJ=3+mQ$DH5g)0M4h^qjxwXwdjUz78N z2@~_6H*!2S0ToFTar|12*W~-3?V#})Eq`yR zh!Z&;Z#@^Jo+QbSoNu?bx&UGy5OStgJE3p!-o3@C*^7v}b-KE`k~^x2n!DBB>^s-g z^C`a$`5~E1f`Wit#!;uPMH7qXUYsIcWQ&g<@2H4I#edCLs~u@xIskhsFY%b2Y}Ez09^AgBs>D%>a3JUN z6+sa?X{0s8!|d+vW(QC@oh}h|g2Qq-i)BdU2nA(utsvCT6hIW$d^V1cmIR99*b*il zRvoNJhZI3&XkuowZ{NOsXZB;FCwhi2gi@Hu za==a0;ox}&l+>f3w02IrS@GTGyH%{0XB9pQByxZvvKZY+RH)u-)y!s(`+HE%S2s*H z0tNP25o1|Qj zPs2E9G^>Z{l{hTwYtDy>3V#|jis}~)Qw_x0FT|knG&ECy5HR0ImtoYdv0^;IzL{6W z&DFJ%@N<)_yEQjA95A~KIATODpn?X1yuhKsbjRxIDkiMV_FWv%1H{T)eVC9WuG8D& zWi=7FGs^QK&vGm#JjHl6;I)~}!TK;21m}Btya5g+?0;VnUkMblQGbARlvuIbX&-al zQ33|sejL#Q;h@wS2&Uw4U~C$wB;7#()2K5AB(Lup*>vg>f*R}ZHY-ttDAkAS1grQ} ztc&wnL9v<&QCfX5a_epw#rT`Q-R?7=R#n&8`N_4`o0{F()^A`ql(qGfZPtL|QA^}M zBN#)JTYE-q;f33G?tj|BVH&;T*Lk=LI6gDOPGfE$fQ+%OZaOJMJ5 z%j$l%FtTv7`RX8afS`nx!NI{5N+Eh%+u)=tFg&Mx^h=UfvpX}05(0q+on~vR54*u^ wqd$E-btc;EGt(yB=lreE|Me%b?LV$R0R*U3#_iO(Q~&?~07*qoM6N<$f)j;lF8}}l diff --git a/TMessagesProj/src/main/assets/emoji/0_1346.png b/TMessagesProj/src/main/assets/emoji/0_1346.png index aa3ad5d5fa681998feb00a8ff4228da484a11913..69a10c1ca1db3d22c45d0ae17359c46c545d17b7 100644 GIT binary patch delta 2019 zcmV<92ORj^4)70d~& z&68@DayP<*S&e5i&9-d2ds4QTP1eJBsE0$mpjEPQNtj$WrGIEZpL#!wRxf-{Fx$z1 zY(grohF-|8WZ}D&!l+!*y>hRQM=%jM;M0ZV!JCO;M^-H)%&&av;FRs=x#-5DSS4kN zE|q>Rjdd-A^zhdB_T$CJe*ypi02g#pPE!CS+WP&NLH-X|w%u`P(G!=?Di`^7mid#`G)x$OeY=!s$H&YRuqD|;GUA)Yivxb=%%j=+Ed)bA+OjGP2<*4b~03^f{Gx5 zUm@-}>VE{$G(z{MK>C5oK8_?1vAa&ZDgwsjSg1|uH{{6a<$py`BZM#^j>jVuEXO}M z11%8{PuB^I6X6UF6M79}svDfqJ_&rGX08)Be2fd-buHZx!mxtv^VD~B!!UHqaxFvP zd|o}C3x;FC^|&naEVJVz$%5_nxmcTNn(lMFx_@^KoGyM`{o|e%9E6BVyDYOD&mi=- zNa3_?9agEGm$}7>n2!Fbh$#r>mZ@jjahB)ix+P#M^9-uC%R~~-H`Q_rW$d~*ig~5c)xrfKQ4(in zSOD<@u>;X{80gnN+S=he7Uxl%?~`<2?spm#iRe~*$YV2TyTTJY=5$@>f9YhkZNnA> zPZBpW7%oUn;L`39VN|+dMM-9-sX>I}bYD8TDZ;Szcw@woyte7L3!Xq4sW5~aE`P2- zy&S9Zrhft z`hYMb$Y3N;8Bt`R-XLuK#rZV5HGhN*7r8DtO%OsKl0G`&v@y0xMt4pu>eNPZR4FEG zFp2YNFg_8w8`~!0Im^*-n#f%J0wLc_ood5)k%r$5fd{R{tHk<~dSAPV})94$q zJ^yY<)F}WWBAv7IK`5g?>x|RsQa>&&&WJXpdj$;a2oawZC1^dNsxZ&0xC_%X2!hnK zW9no`ynYZ6Xj2mi(r{L11c3FLj0k0DCjmbgJ+S8QD!3X&ikNmgBvv7SwdVz?olqHA zD8qCE{p%cM0O|XH5Xh3ln}4$^08j!|#>vpEgl+~P5F$`Sq68S;khl*e5RyS5vJ-H@fK%QU_HfKr{-B1!moPmiMnlT1O~NYNkfYwH%VM8!c%AcFRhdSDi=8?oPW9x8L}0OqdHK^ z1ClW*xFm#BF)87YSb=aHN7b>0LAN5-h$PPPGK*uk-;I;}pMMN0rf)F0lz(pCkbUL&%jIHmv%2`X z@!{9^H_9fqT#EunE?3_jHZ%G5_g|ySAHwH9e#-T;*=%zlKu4@Tbi$&|=FjYeJX{cd ze5b{;KgjR5&B4_{82TUygx`2~hFn4(egdG?DznXIZyAV03?wQcywiJN6!K$!UcwB^ zKl1+PZL=v8*<1^hYJb>l-rgZ7!F zM?K!(|DaqoV0_oVaoKqIT7z_k85V%$@+o@(@P7np=$JGmilhJl002ovPDHLkV1o0Q B(jWi; delta 1870 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 delta 1843 zcmV-32h8}K48abNBYy$oP)t-sM{rCwH#uo(XfQD~dV75^F)}VKFm`icL_|b8K141q zGAt}EEG#WsTU$IZBR4iSC@CpLMMWheAx=(DR8>_R93C$)HOkf3#+H04kQZ!iaPhby)tw*2hZdNamw(pQ*66Mva&d98va|QYFOQFp zz`wr!$}G8l6frnru5%6>9!XALjQ`X%M^%JZY?>u0PXEs{J4JO87AC8!tEqe{$CM`@ zA~c_22%Cjmg<~pBIwUA9T;1N^e|Bb7T5!dxZ{M~~_1ADmKwWd?QCt830B&?rPE!CY z{ull^M}GwV30xq;{SfbhcmDeR{hR%^{@3XK^ZuOsi|_va8xDEM+Wh75$!z*0`(~Az ztNWKWEki%u1gtkW;RqbqSxF=Q85R)Lht_`=uJRUo8JC}_6(h%zDcsv%%6|0O_(kjt?mvhA9 zaeqgZ@~JdL+q`3ACK4$n;<@60v_eMv-?@vCQYBGx%-oZPxaa;OS4>CJu}W#WT^eGb zxKoV9V(G)7p*fi}_08u1B7S^ada9P%-_yBVI#MZBDho2H8c0Wuk0a^C(>ciq#p8t^ zhGMbz-;Ug1)@7=>`S*o}7ag*j=zC8?>VI`Zhw28N@l6$RBgS)2!2=MlJ(6oteU{2r z8J>4vN=1w`r1q1AhQdL7MymUDq*7TppFOF>b5jy+_*SYR%ahcbgNS2iKqV33$>w2_ z%=Aan?%NU(g=~@{GtrYoB0V4t;VJ9`L^N}lC`GR8JN3f9C}j7OJQ?i={u7~8tg=U-{CzMqoG zBuL@}5LhQBGKsrems;QbahV5%JpAS`QXvStNcU6USqItzpUutI@Y>p+FbSPF;)yfH z-y^#QVzYG@C>$=Ix9l<6{&XxI*MBmcMm%D36Wo1m8))r_fO)e2(2+ifQklkPg*e3B zS^+IJaZo-=(5I(ELnfMlcovt7V$5!~w(hQZ?F3_OB4L6+xwEs=GZ#u5hN%pWiE4}W zw{PE;ZJI@zCP|d@6GtE&mkHHlDkGf1bs`We7L;L##%GL)g*h4}2*zY}xqti&4j!qI z*BXQo6DVB{m$#erew1QNCM!4uK%r5t8mk`U^@7Kt?)HPD*e!p8j7PN~eU#=N zwOVe6*nb{a72f1>aVP*B9ch;o;0K)o@madYn=j4ONSX!g?-#-XL$sDp<{^}ts0R^U zSAvFNp}y!_UJYtFCKz}bvelm|*4TJK5Z9f6f#8G|wadZ3eU!0!Tl1CL)q}9GjjQc} zTQ8SZt6>IqNuw|l!+%%ykCCznPpXFPXt&#c?*auY@Jz->G|E5XjWC1@dtY;KBm_-# z)Q(;5Bq@vU1421SMV%s?&p?cXRz^bpTA&Q?CE@dE0Nni>;$* z_CYWi=n~{qN|V8}6wLqt002ovPDHLkV1ntOeOdqj diff --git a/TMessagesProj/src/main/assets/emoji/0_1349.png b/TMessagesProj/src/main/assets/emoji/0_1349.png index c56ff5cae0a28f3db45f691ad327125ab245d9a3..8c7b415879e2e80f41ee574043b8fad697f116d1 100644 GIT binary patch delta 1298 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 FV1j1QF=GG# diff --git a/TMessagesProj/src/main/assets/emoji/0_135.png b/TMessagesProj/src/main/assets/emoji/0_135.png index 0696ca806bcf8ca9206c9dc972efb4e92c2f9680..b50f831d863e0fa95c74e0e11ba1cb78daa794e1 100644 GIT binary patch delta 1237 zcmV;`1SRAOOYXI)p3Yglu0a)M@8rf^njL@=&*T4iKn zW@crYWlg4WRj_zls&iP8UPpmbJzP2`xPxM}eP6qXWxkDPz>sLIcUp>DLwry>m}N}D zl4_u9QH6zt>z{RM0000JbW%=J08+tqIQ<#^{&}9?<)7ZbzJJ~RBTk3g000CiNkll?d{t9UbwLE(N-Jr(X#f-Qa2$!u89!r-!0A2xQcO8DMfoJHdfb7 zufG3Nb^Dxz_kUUf>f6rOZF^PUgCw}FRe9de8I`22n@@Ysc3UU8sPg5RNNpDu^46O@ zoXXJ(#Yq!Uuf!!E^e|Sr6bDUlM z_xK>^2)tQNNh7?Q&xP(ONdoanXb`#I(%fOQaG z4M;hVFlu0!?y5vo3wKR{TO9@CK^onx&BVqm2E++TmOGY=M*d-nz@1`94k>S@Z66e( zN7gJ9jfV$r(6kwztPu0^nPb&JLc+bUkM$feqJQN+*@veUnJ0PFofwnR$k}Y!sCu*@ zH*j+@U^hq%=X6|SS1tl0poNs{y_{IS5({eGi0D43`b*OoAYm0GPo0 z34h_q*{J1cX?9utW;m&ha0!8vNiGxGIV^TJ1WCpwWP_3ONi?`6$|`e?*JmsnOc3CB za*=mWHU{7v_QlYC6EeX_;U-P*2@D&uvydj>k2VdGfi#LtQZUvW&O$P_5^HPE#87xm zEE+j!&LNeVOc35nuL=3xFl^Y|o|%nM1%Jca-H1Z$Kpv0AYvmy>F*KoeIbXsOdiIBCS+%54}T&H zDL-IR%`kZ#f?g3}a;?a=)SthLRS)e$T)anwT*=5pmw+NN^uYwJMafPwR>97Bjvs!( znD=Q}SYd~yY}nHfrSq5=re$IWG3TI@5M|>%L=%k(c`w^qk0Hv{Xh77_ghP_~7hjD# zPh`WMerfB1JeeP)9{fK|OGAZ)Ig= zU|?THGb~a)HBC7(Sw%WlK{!4vCNm@*C>#`AM>~Uqf-lo&1poj540KXXQvl9^s?6qB z8aw)*bUbOP@&Et>heB$M5cuuVScZ*8Qjd(sM_d5{I#>_@< zGEdV(0(_Xe?yi3nMt*ped0*vWcYc0Ov%e0~;Bl1u?j3!fx@VtltW6$X?mzWOhX)IX z5%%uBk0ysFZGWrAO{nV{c&#N@X++q1%>F3I#`SiGTh%eq?$P*ogU5N~>?^$1Ztx~0 zKPEbHf zAumK&GW~A&$K&*aq8M{dwZT#VtAU~s=5ZQNKW(c^ZhtH3-RRwe4hQh4FZYGuHMvk) zPjfhJEicx9b~ii|(}nN~5g_QsB*~W%81-waRUeB8rBy zkZ>s^8WBn+j4>fu(V&&O5sxnMFlaLp8=&q0?}D?q0vmDf(i*T9*BS%>MiS+4I|68J zfy%2pv5|TMR$CHP13}*%NQ`7H;%4-Vb<9zP7Joz{yltW~uBkw4klQi#E~mtV%)qsY z-nOyi*o@vqFe2h@6P0O&f>$H0*E#N+_;$7G9ey)1uyu}fHA1^u_%ixw#5*D;0yhXo z`7neqfnWx~pe4TyU_&NIiLVK8g~Je#jj&!c=wt{@PJ}c^{)tfX2M{9lBTX2$2!t7= z=zmNR_Sd`SmcVTMuf|=vun_>(NruT#jU*tANQjiRmyJ|El($F~x&hKx)K{ZqLPq2; zLSVhPA3$sXBOf^r6QG~PIV&I^d53ND>ieWrhg;*mZU%aPwDkiwnBTQ!&pz7DI2Pkg;O%T zBg~w4LQdEgLRns$yYH$Q{u~XMA}zJh+X3CwkYfN5GnZ*bO|oJ5k9bRnRJzd+B?wYn zu14!p5lN7vmC-I3?$QkTlO?Av3APbR4`0XG#VX_2`#wJS%ldzIZhb{UtK>ca015yA LNkvXXu0mjf)M3y3 diff --git a/TMessagesProj/src/main/assets/emoji/0_1350.png b/TMessagesProj/src/main/assets/emoji/0_1350.png index cd083c8d4a4da00a70df884fe8399f20522f31b6..9d29b50544c32e8cba768573a85b0cf05d8fbba0 100644 GIT binary patch delta 2080 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 KMNUMnLSTZKU-=FI delta 1805 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 delta 1779 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 delta 1593 zcmV-92FCf;5XuaYB!6O1OjJcja7<}wXhu0QdwYC>f`c|PGGbw3VP0EMPD?d0F)b`D z5)ThGH8mb1PberUNJmL7FD^ntLLnd|H8nLLA0|ddM$F92EG#WEF*Hg+Ia@U$MMXsr z5-lbe6FWILBqT6UP*68FIXfyMJTosMASG~ca2_8eMn*@LUw=6|Ehfju$4yR7ZEkPD zz`r~w9f@sMprD{tYMF^tFH>WRN?C`xv7}61j&nsOxw^b(W@dJBbCs5tKrkkCN-~U9 zF-cd684?j>Ykpckv*`=kWnUj#g!^F$W%afCn!^6W^ZJKgHCQ3_7 zM@B|nlagpWB~UILz`(y27(qZxdrDb{nwpv2-QKIKsxLA|cwtmkT5xkxKS41kQDc#j za9pN|X0wZ7M?hX_CqDZC002&OQchC<{vQ7RDg6Ws6@UKz{``Z{HvU}ily?2X*IEAW z{{2J!p|<{@NAIWQ{d1c3$RoN~`nZ&8m_g0qfZT?0?ZVl($~g4lo~T#F&dB1e;Qp7XWl|BY1Lh5=_T!3macnIVqC%h~nCpCnIC8 z51F-RBW<&nr{Te1@W^b~+X;Qv9u8u$7*OmI$i7+_#@N_ou(pYqtG6X)%JjWL)q)*R-wI!I%Zi9WH0#s0)H4zSer$FP^Ul;$Ke?3gY0HY6~hxz z6*oM#38a|b2&-!QWMxT@=sk9?QW^S4TDdell#IA@+#%Zdcb7j2Me*dyBM5_;n3c zlz--DQ7vrRB&PZZQ(8(>6xA(zgnxQ_4G4HR4vY4xcstbrvDn9WY`qsG$kXo+`fU|# z1O`GlWEI$c1+ue!PA`Z`wOSo%Xlqe~*JY8|{iT?Muh#$( zHTt5es>7bac&rkyflznM9LppmR8u~SLv`H5T6vzf)(b$)YqRKV7L7&|u-25ANjMyi zaT2T%0o;!PuRLJlFFX*Sl zfnsvhazPRcnsp=Y6<*I5GnKo@;(wqhS25u2^_WHuS?v=o#m!p5xptOB0xmy3j><&f z7Wa4gc$WCdkdg~R=xy$Rb~6A?gJlHS{Fcy-VY4sUHjyO|3UrD=0OJF@nL?&R9+kcj0*oNEz z2M}#E%N`G(3%rRjy}slPfnAUkg{NTR=L8u@uq@+_f+YHvG^mWGGm&0C=Ob4O1jXz` z-pYLx=K9)b1iP`&<02{l!$2lcv$?1o5?RoL=H(T(Qswxla@<)i!~+BdCzpeb$CFvDZ|S|~ z@_u|@SGB0jM6=Z-N-{y83$mDaI>jSD rm`H~A<$Qbwfvkt5{^4r@`j6)?nyu>AlD@h~00000NkvXXu0mjfVNm7- diff --git a/TMessagesProj/src/main/assets/emoji/0_1353.png b/TMessagesProj/src/main/assets/emoji/0_1353.png index 4d8f23f545cef020bc97cfea033acd7321f66598..06a9f6ba37af36b6c291b98762df9b9c39698024 100644 GIT binary patch delta 1819 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 KMNUMnLSTXlUg5L= delta 1959 zcmV;Y2Uz&r473lBBYy%YP)t-sM{rCkD=jcEGA}SOEG#Z*X=yMuJa=hMFE2ArK~FF+ zGkSY`D=RErTw4zh5^ryBDJdx-Atgdie$pyA|I?Br$(~fHE>NMMXqFKSW1IM>aM$X@5;mOkIuj!7SXO9Q@Bs z^}{hYH#b2+K~hpuJUu=Z7aN_OokBuFRce_}WR>!~DZeHz<*gk5*HUV0Y`C_xP*719 z8740!FIibxR8&+F7Br5HjNaVan3tD{iHfrqEZ8YL)E+ZNRfgCxHM34r?6@hfbPCp( z6JTIq#*h^m9Dhi0a&k2_HeX*}O;~+bY?`JzBmdM+u5%M+ZiDB%HviUDX)^%hpcs=k z5UF$$A|fI}LP+o4se5{Q*(E#OEI_{+EgvRSniV7e+hlERZ%|NC!^6Y)`1m3sAxKC_ zLqkMOO-+P^g>!UtVq#-%Zf`j{JTx>l#fKB}w;XE^6@OJ$R}K&?v>Ge_&oMqeKh2dM zyLu7etS1&1KsG*XTm}>W++6?KPj(L(OInEk-)$~5VE@uR$WQV-+OZ=8HiC4)tx4)T^*QO z5mj1nS${SWu(7e!mJ%#5OHpHy{>UoaekG7W9ExHfMl>v=g+HQtEn0A&+&er#4>R1t zb6Ze96*P!B0001RbW%=J03Sp*{r(FB76vN*!T$d3hg1IiCJvbP*_LMg{`B&FeEs^f z$yw^!D9V!|YyRtQtDyY+>8xo)gJa;zl9s8`)_-gKStPuFYve<$%pcT9y*AwK)xhqO z!N8t~OYF&_{J7=gxP{~|wwT)Pr?cqbQMu`-F#rGr%Sl8*RCwC$mQ{1xSQv&STQXz7 z5XTUQnYm$TnsS?@%PO^>wdz%_p#s+M7F5b925mpZDNSt$#2?K{)(s&gb)Ot;f!%3hc$%Vu09u@@((k zIY^++gE9`*W3jt}2~ho-_sQOt&sPr#mi+qd+ZLbi&goOoF(f^A@pbZS&&gvk>SkwW zrjzUB$8em}EaF&Y@sm3nVy-@n15{75{-uoq=FD%^(2QD{r+M9FFO?rRVo%!)NYpY-}u!4Zqpc1(qLM(6gHqeM z5!qJvsS)w#i73%UBpoA1!M$cg}4zgola({_M&_6&4$y%R3 zue6qzit=O7Az8R zM+lriXf+ZctfmKMvyrM)8bN$kmMI5kP>$2qjA$_2jbRnR3fEQS$(te}Lm zEfGYTj(BF1l4~zITl=-32d+n59p#Cs!Z|sg2>iBF3gwCVa5a&cCxygT%5gZNwj=9b zrsTG9Nv8Hhm$N?&;B<^L8+KTmj@&;EXFvyWNza@}&Ft$kfqxogDw?h$a};0j4kgON zFLc_DZnUkN6dx`L?F>|XMu^KOR|^m4vs*hmx;wkwhp#GB42717V6fP*s7Xtyd3mSU z*7bAeL+z(qN2ar)N?P04*mzkkp(IcL}*0$#(z%002ovPDHLkV1oA&m8}2( diff --git a/TMessagesProj/src/main/assets/emoji/0_1355.png b/TMessagesProj/src/main/assets/emoji/0_1355.png index 3023b7db63553006fd8441a1d6bb4bd872f4af24..fff442814170f0b2e141315ef66964f27332e11a 100644 GIT binary patch delta 1273 zcmVH%S77_uX@0000HbW%=J0NF9T{#N_v7yWnPkbk7FK6Od8-+cf81WHLn zK~#8NmDY)Jt2ht^&|nM$-jd!VHYfl8m(vS=#5ES4cO6nLgN|E`RQTg5U7d#^SN-+l zRT`}HbX7GUJ2`L~assSh5+{O`hlFp4{GNc*E&)m~VAc7wy2G087m?wzN1S+g5Qo#X zuG&ad)t9FGxPK@y3*t|TA~OTE0X!RsDH{Q&-ELYH%mmNC;z4#|*z0ElR%c2HXn7LswE(0X#Puy<2K)jd zj421fJH&}sA}54p`3Je60L5{Xepi&(JbwinN6A!H+pWgL3Yd8iPfY3eO) zKTR~P2!Rn(Q<{enOye2{wkV{C1W~%JS0liR5c2<4#?()meu|7ECL;8d{jSwkGz z#(QL>lz&0RL!lKt=Zrc7A!b++S0dsBXTYh@jHd4)C)D~!VNT3Qrfke8b||6T=?x*m z$-{s|A}b@~MqFMK)1(CHM8Nlh#~fd5u{4wbBMP_VH1$r%*!xz<5!Ed2jH*E9{VG_5 zLB}yb4kW_9(da?QsZ4;N^}_;##hrn@tq4FPDt}SBBZnX$jU&aL+>&i3+9vj|C=y*Y zaYlj6c_>6-p_FhcEUk}v;zUvg2I~$9D^ZuWnJ|;s-7E_O3Np#1Kr{p(l=BNChoAu= zBsmlbB7q=Y6_QO!Bt%tLBzzb7x4i&DNg#qn;$TH^PP_uke;ww;IAUEQIwUdz3Bj%f z zM;O_5dGvRk2aVT{Jz^ROI1EEFlEw*BoPUsgqM1fPH==s0JC;X&2snE=17iO2qKFD|0-GD6tmKoqf0oa#x0!bny&Ale_hXoA=i|FGALuCD4ZEI6(qBTb-D zrc<+1Mg01&D>EEne~MXiQV7+hxke59N`r22@*}ZxY{I3}(;M(^ks87P{wCg0;eT!x zjX*#XKtU)Ql{gY{pd^$H5=D$b3z1y^PWZgFq=wKM(Nwq3|BZBCw>!kh$V#=}=iArk zd*JiycK*Jj4MO@AbYq_9vnl)IXU#%{k;i!NMt`3z=UZuccAqhRKF&*T2H0z(M5{O+ z=TN@7mmSo>o}Zt2X-Ozbffz4>?Q;F+C$4yjbhkN%N9KFm%lPP{Xo#2Z_2eJqxrB2J z-|~H5xF_)t_U&??x07Maw{8=@W*h&USS(f{E09&Gv&p*NnykO>UyODl=&*;v_ jfBquJ$8kKLXY0qmi&4|G|6#CG00000NkvXXu0mjf|8YK| delta 1890 zcmV-o2c7tg3h)k)BYy$)P)t-sM{rC!IXZ!Xf=WtCE-fu5B_%RCMRH_cCoB~d6GcTu78M*WFEB4IE^lvd zH#RmhFE1-9E9TL^6%{@vCMrWhL0D~>Qe~7kH#s^uIVUD3MSny^O-@cnM@MXJZb(Q; z4h;>|G(SsOhugK1Qc_YZBRNY;OCuyT)y1_>WR=byGV8#bS65olm~=TgLqtG5aB+H7 zR8)h4fuEh5*)2WOBR9hzF}NHt?82U$6(dYtj4&`TadC1!Jv~}ZM;aVRUteBPESffKz|JmEFU6HGdgKNOM8(MAJ-l* z_}8>{4;kAoKTKPQ#~&|8RfAgv4&pmXf)E_ej%(SSb}KMk7aJ{nFDbj1crr0UrWq); zcUYH}l{_yaRa$VGSVB=_kT^YHX-Yz{u&~K>Rh)BIYgN0I zU9607B!3g^z5oCKWOPzaQvm+`{viGd0tOc;nErtNW)J@FK>k|%?M5}k?b-Z|A^x_< z{LEy=QM%Mdfhj=gIN^9Ett zg=`kP2t^Rf%ot>5ST6sal^oADGo6W5?M$Z+{a*BRemdWQdnL)gt^d^^m5K)_wOVb^ z?{zx;A|Xh?S*FTyUS+#d9K!?y42A>gGDq?wq7Z>L9ej*2@iM0=k!eW3D(q!37;ogH z6@S@_fk?re)tSvOj=RJm++WZOKWDS%GKOKOSVUnV@B=&UKwg!<#1~@{3-aO5ktrBsPUr$7G^yU_Entv&K4D3p zJ$gKpNEE)iA`veH=^P;1=Re~a;`L~0et&7b{hIs}%v_!45TC@j^4SWHSYP>CG~&yp z6vtRv|LL*ldOlb`m|K}|-^_i}DY_Kvspv-P9YIG1+~N?QUtLNqMi+O7=)%HvL>!`h zDYX%euI+BpxkRVfhNR{eqibuw&_wRKD8#k-GemTY*dp%#L%^BwCo8D~9&t!-5r5wz zf@9@!1mPY$L;fIjaAR(9ZI>p9_ag!U^8U-5I{F`uR;zh~BXH&1q=`MfK_H_4QcX8I zOj5;@xw*NG#kEtK82a5Q6_~{3ORs8-;nCDvDzF z-@G~e)tqM3gJ97v6*7|j%O@u%uZK;I3=oT@aRBP&(#c}1UW)XnV)h0BjDJC6Iv%H5 zZ>M2Wg)1LAg>L=pru>iRVuqxN4XU+?$o0TztIFa|RaM5P(FQOy^sD?b&e z+Yqn5+Ri&xPngtUEXCj~i!%TYSMNldgLKuip`7yHJVSU@L95!Xr%DvWU>N3+RRg*} zXT8oE^xDg_$(ijt9-~7kL4RbnNsr!G!eO-5iV-kmsMFLj#?Zkdrh7Fl4QJLyESh2? zS_=p`NYe!b9uX{!cWhS?v6dQHar^DtBa6Sspj0#{Tx3yu!Cdl)Vd!qC(loujkH?<( zj6WRZGLhbTn|~QL8X-%wx0&S-7iXdD#^UMyGz+nKG1Hi4EzLd@4S(g2RH4>puh-jb zp~$fI;)bBO8KVFU+o@pTTPBkl^|YDcQU+?|P9K?ECR2Jfr0HUW2R7^Q^iE}GXD9PQ z!I^7NSS`j@4~o3xo|(f>&W2g@QaCY z|5;b1t(Mwr1x}}AbbrJSWmw-RBC$<@J)E^+=v?_^T`Ik;?vD5zeG}kaE(}qVFHDLc zG<fWrG`OAJ|pNC&8GkU2U~Zaqju{kTvHlV%+b=) za!Unj^a4-tNz2P0L1*A25_N{ia4}4VoGzQti{0S&sn4I&QmYz8QMFYn5iXhR?_Udu cGFW+W-In diff --git a/TMessagesProj/src/main/assets/emoji/0_1356.png b/TMessagesProj/src/main/assets/emoji/0_1356.png index dfc92997887786fe2278687ff89bc86a0127ec30..b4b1fc1db0db8dff8a32357235b0f533f514487a 100644 GIT binary patch delta 1925 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 Ry8r+H07*qoLh zjW{$k*P?xDSx(ubeItFzGcGPMc)aDdlh&4QD0#svW~nkRE~I{GF)b}ZgTQ}dQ!+_? z?!=<%znt5nebbn7->QYqj%fMVw)D=d^x41Zx|K>nK=ReP@qf{@``x_Un{(x{i{-YG z?#!+6%BO>0NtJV4EF~iL)3IYuLHpssKRGz|-NgRr#TyqEz=K^bgwDmJht{{4rIvu# z#ivIwB&vmMk%V>Q)wfVla2QFIQ%XrJL3*ibM6`EN0|Nv9^3Nk^v>12EwvBK+cEvi3 z(?)#EKoPiaawN!+(x;DQx3IQT#-rppIdL=24d7 zm?}k3&gJ$_Zg0-o8_sTSPl}1cA*Wf2qsRaS2`*1=&aCw|?XzEuI7Y{g%2|rj5MBio zud4nlHGv94zc|cLl=VcxDZcUoyK%Re$^-u+os2z7WC>Olpc4C&S@+;0wl> z4;I@dwL&pfLGcLqGM-MG@%=;pA)Xe1=6(O+K5kB@)0mqPD(Yz~DgFXQ7)aTV>yJRM z*MmmFOo2LFz>k`Y*aj$W(-fru6s#{L_xkY^N&wJ+rw&t9jv6ZBURpEuDkH-nQc4DE zH-CNhTB}U!0Hy(Ob@4->6lW>TIB9}{f`RCIL@2b=G<{!S9|hpUb59D#CY5x>dSuvv zYr5G1(Wr^RHVbz6GCiA|cRz1TwqW0AI) zuW<~eE>?HYFj>QOp)z(UrJMP;BjCX?oiF@Guz7f=KfSS*qVt;OOAX-&p8owA4NoTMz|G^#zm zMo~C!*V|UJ(zFVrrxx-wuUi$kZr7W`Miez4M}A5_k9b(LSXx zne?C)DI8vU5}NUmf}k*>zK#Y|U@N%v_A_pC@|RwqVklf9ITMU~8-s4(KT*Xn_xa(m*htazInoqJktA_-2|u^dTif3O^)B@a9ty zfWRvs{vW~KUzPhlN|;bE=E>Ui-hXx+{=EJxz6T!ql6#zc9+zU;m;?tl5^r3#j;FvWAIe|dSnn+XoD+{fyqybpo+a`l2#ulLdfKd%qe zUsS8BrBJt<;8AdnxA3ob&x0xemV@)+cOAUK>H+fm`EEJHdrcUGVuZJyv%A&c_wT`= z3ZCyI#p|jnhCf1{S9fzk)VZJ(H)${|p&?=LF4 delta 1866 zcmV-Q2etU|4%iNmBYy$uP)t-sM{rCfCMGv9EKyNWi+6oBGc;*wX=_$UFfcSaG&O;N zf-WsDdV72=E-yqyMKUrnDJCc{Ff>C?el8*%KS4%EM@J725pYpMC@3mIAPTi*STi#- z6cs)!DlAxSnH?feW==XrMnyF>HBwSjNJvPxi)1P)DmFJaY=3QTNJ&X-NGokhF4QVK zCLtX;I5-;~N_BO0FfcH3a&d2NZ%<^E$sIAE7$!zkf<8V!FC{NRLP1bbQa3m`Vqsym zwY7(bhTh!UR&1JfN-?n+D{DtA*eN`;DKVTwHNz}5OIwSET0l=K5=&f*aba2`BsC5Z zF;!JmbaZ&Iu79joY?`=)VY!E4+%7?>cv;RLGpBV}XlH3cLP(*Zp_Y`Bnwpx;&CJ;) zJFSFTr*v0PWRpu-iJ@{;A0||p6CD{D8Tk14N=iyZL_|G3Jz-&DH#j+4T3U2AW{{A%W{FPt+L_*&DD!u$3wf<24{AbGXrhiRr+QxF5-utBN z`rgLw^l3`_mzC1@@}lneVjQ+CZ$H`XtqSc3q!I|B`){lnWxcRHhk1y}9 z*TLi3rq)r9$t)@W00gv2L_t(|UhS1tbK_PY#(yKpmTbuwa~yAM$6D`b+?)6Ost-ZPA~e**cY17PtTw0{%QRuC61#5EKaBMQs+WfSEmIH zKv}x{et*Cp2>AUAhz#dWAdrJUKU61$gpe<7Zf@qjAi5B3;9bSkW^PARz=@U&+2cqy zzkiv}iIh$>7Y#R3rIgLKnS&H$M5$Ct+jcVfeEt#|qUGD)N|EgTegsBiK+DC`QZ^fb zO51EpO2j}OMx38s(4_gos4Ug7i!FcSKqeS*$10v$`Ml2qTe@Z9zvk%a=-#3@LAtJbU@-`94 zwxAXywgnM;pHivF10=-a_HOJj4qc=&>D1qKK~?^q?8Zh8<9mB=6Pe6aO8VNBQGXOf zhz!}4SZrh~zIOr%euq@R@cjMz^Yg<-g^06^j2v#kIMRts+HI7G7`{-|_oI5e;pfAx zt$2Lzb0T%*ZNnv+xPIYHm9bj>X*@0>f+wj|8nAYWgQmRsrlQr=)%x;EQ{%f}5Vk}y zlNY$wI>`w5c3ITQ%GyC=nDZV*B7gfuFURPmZmA#O=U4g~`zoLkKW|&!?xyT0jZ@dI~&7)g&xW2y3tsx7-{{b5STQfE0mcFfmchg0-O|c=G94?i|fDO1|BtU>>U>u^F>9$(gFuL{ED~Q{Z zgYr5`scyCQ5(E?Nsg}Y)6Mu#p3qmg#N9#qzEwWu9KBJTd4H?q@VP8JP>(3#G2oEtk zx>jB}=u7(At7OHUnVFB8sScxDp;V0Vq1GCRF)%$DZag?RV0_OymMsl%IPw0O4=+Ll z0W>C;iLHr{k4HI9;8?&iKChOW(72xKbd!aTD#B!Pxm+d<;K}m`mVdgPgoP9f5RQiW z9eS+C`ag4$@B*y^Mj?|a<*?NH^AXmh+03wEsHC@F0hvmLK|`2&zV>8?k1(D;ruTqX zMGD@+#}DKL?fmi*Fr8`0W>u}en7cDQ=w-N}{+F{;U#g0mG-p1mp03@U7UKZ$vUUqq zr`FIN@WB{36T7lm<$ta{Blf}9FX?GLq+vX*$30-|%xHROFIIC<9sE6+-Tul1V^9qE zhBUw={}b;~krMU=Hq>&LblxLGyYg`#O=!L%)NpH!OW1rEn47&jH!D;kmJjd+vboaO zxY09M@Jia9YWJ)E&%GY1UL6HCL8^Su+S}XvRW#WvZG%&-nnM>ebX(Ogtc$LV;6tGh zPqgXOQm?XM%8s4g)3^iE_2@7MUMF3Y@-J98f&X&-4j2znrZX@2pa1{>07*qoM6N<$ Eg7-vUNdN!< diff --git a/TMessagesProj/src/main/assets/emoji/0_1358.png b/TMessagesProj/src/main/assets/emoji/0_1358.png index 36a5d5c27e490849a92c2944431998419a7583c5..ab282a660213e5520c0e5c9089bfe580d2e8130d 100644 GIT binary patch delta 1767 zcmVw+o?<(WV@YW}Bcpv_ep5TrymlE!lFh4ZO-p7XXtf%6$vTYFEQ8HS z9t>_@Wy7gopLja+>#674m^^mH;nR)m;-E%+%tMAi5dZ)H9duGoQvffWxc&ZG{vQfy zXx}~9JndfIhkvM@*~YHBz_`Mm!(2oF00po~L_t(|+Le}vLRw1@Kt))JipKuh_HsMD z+D$b1|37*&yC5OYg}ejkEzV(Pb{0I?qJ1hT70T8-2cK}HjbK#T?m-k((2RlN@YB0Z ztSxz5Pzb@@VjcD#9!SG-%95nd)aA|v z=_f2rQ-A4t81%6qK(Dt@lx6!AO_hLxQbv{SH9Wl)v)MwWEJH;m4|lAo>|++*VP?JF zMgRs$*;;YBM?pnO0j`u<%z|LCkX+Cd-3;KM6~oup*I@w+2Uthx z5Buyxc|1~S^93!O4loJAB3nK4^9&P5m_%0QGtN*^eai#-ZP9Wj^$Y^V$d8b+FV z@Er5fgzw9Ox>E8K)|Ly_hrj@gHRT*Xnk|uRM=#ELGD)@ODV>a_Mz{{4|E(K)=FsV1LAOmGQyLO(!y1Uu4FKqv~lqnpA){B>19u zI+;FAg*KoV+(rkS!&q36a-Q^&U_eJWXVB=;~v5rQ(BQsxB-Jkh~mWhl+4 zC>;}n!C5SeLrz_xU`hR0tXqi=#1BbY<^r;4b|OhwDRd#%3I>8e7GS7wg^}eT_J2Ka zYK$T!-zc^nVN^|_OSCy~0QPN8+2o;36-HCZ&of>V^zUCDf>b@x(Qt zED8OjSszJwH4#b|)5=D^N)A;yE)^Hm6en>66Ds>Yk^W?LJ|3x*tKrz_X5<6hTF62Q zmZ`}ELMqzFB5*1=j695+NGO+v5Pwrf2E6MW(MAd(SmG}lr0V>I{8T=y)i9)Wd@P?qUImr(@2T@1!BLAo)1w}!$(Pfvq=goti9Oc?59!dd;Fj_lB18BfHy1Nx^qAjN3^GGtkoC!cv zFs$l0*u!D&prKd_Rb}Ng;;Krl%CK0+9=e!DaLDP?n!=BSPXY#W4;@UyJGh_{w#F1b z`vnuhus?~=4J^ew;N_{DA{#W4hff56aKIR=^+hCySRN$znFOqZ6zc8&W2pVJ z92O|i&ZBisM%T4==Xc|euUpgM5T0m32q}ic(Qa7De#DZvv-!Ilo69uVa$V@%3H!ll%G78dtdrJOMa% zX41NQe7yIZ9M?V*{DslL!{fu@_-)C&1uU2F zV-A9CLL#+|;o(yr-|hmR+{a8dj@rrFXZ+aW?Z>b8z5g2G{{>Ucmp}_CoGkzV002ov JPDHLkV1h;}Ve0?@ delta 1749 zcmV;`1}gdX4de}wBYy$5P)t-sM{rCoE-q|!JTobfmvErP-7R#hyVZp zUvyGVQvm+{FeVfP3;z3^9scaXcmDhSU;6#pW=5OZ{(b$)w*ETt@BX&@&FqN&qKi^Q zAN|JM%73o?SXY&PeR25We_uP~L(SlqnKxF}p|Wv)Qx?i3GXr15l+>`B3pm zWLWkpl_vQ0Kw6cwI3nqEx_OI;N_0bE%d+V`K^40+gnG4DOq-g`CSb&*A;z9{&RMfL zodyi8RKy?W=ai|<0*FT%;>q*h&x^%uHj_4`9g+yDIRGeTG8xKjj;JLDvf3lC?X=nC zkbg;&>T3`N)uyNjAV}0K0JN!0c3vh~>Ur%HAY{LNDtmxbiD#MW!OE=cA)4PmsMm)d zsiYH>FAomtH#ZMqJRRQeA#V1i=k!s%Dnyc5m0Xk;_3_fjgMF&={E5_5d{eKUoK=52 z>J+~kli1`d_3GKl$sxsNi*qVz)4DR;Lx1cZUa*1w0-CT3gsq3U^?995`{ZO94bE zC=&7bU0;*y7TwtQr4k?rPIzrPkxmS~d*5f2kH3qY35Y|MrD(=4G8O8{_kzmh@_)#2 zUQ_r4+Ulayq4r1;lZi$M)Uz`yaa^OJhkr;04+M71gg&HG*%7xvOf0XAdXl7FE7A&+V&dkvvU_z=tyGlXb{W;hc;Ox>RLIBy%2jelgwJ~Yxp zOc}!p;8f6Kh#IXB;q1>x0e78j?{Z7iu!s+F-^Z4g4sc&&j#x7&ppsfC%1*J^-BEw-j>Mk9l|d@fo* z+{aKv2$JMTn$bgUFGT85*MGLwX>Cm-R$%Y*xllR>TkanaCvGBWjv#h+c511FCFV5z zV8X3lCX@hCsMKnOAI=RJSOdPZ1L*;vfO|KUfT`3uP@`*V^zUthH3n7WN7{(MoVPXI zg7v)pwnmKWj!_&L)EBRpmck$hwbYv#?QK;RD4LWB65E}Mq=E73{eK%WSrFy1-fJ2A zo%W9-p}{la5C8IJbE%iISZ>p#!JqSq+*`HZ|FaA9v(n&pqYSF}g2xb8 z#J-4yXO`iGWg+eINP{E*KedJiIM5wj%i|-13Urd-Bjv zzizz^_pgpJ7KIUaYEEKeB8Bj9G$w9?W9alEZ~L6~pw?#1)!en5)ixTGiBwYS_uM_6 rI)}&Ubb1^*nRuzx|M0aS`;Y4{P*)^|$PCWM00000NkvXXu0mjf($pY* diff --git a/TMessagesProj/src/main/assets/emoji/0_1359.png b/TMessagesProj/src/main/assets/emoji/0_1359.png index e801f70531ed56a59eeae0ff2b2c9702c421c7aa..328ed7f7b4bcc5ce68ea64b0725eb37d25a1fc16 100644 GIT binary patch delta 1598 zcmV-E2EqB#49*OYBYyyyP)t-sM{rCfJ$QOdEqF~ec3xR#LM&-kRB=u`dsIArP&au@ zFfVqv8*{>!WK3m1EmSrpBVVK`e#RSVvMxz_wSi%}hh?yOUWHdYlVeD!bXlQqQ;S_f zWYPUL!(;9fmJa)xKe9S!i{KWtO02FjmPE!E>>~cA&B3KQT%5UG!*zlpWyuuW? z zW;Ug$L?%UA;pOalbtMN@^Xo;uhysd6Ur#A!3?Jbl-OpB6Dj98P^d!4lL9y9ncDI~R zT=Pv)1X<=MlTN@QErVji@9J^G@~$f>OvGfRFjN`_9)G0bq-aw0&4x6b>1dTzG|H33 zpa*H1ObRoxC6#G5P;jQAEy#XI3}9JNWIdZu=!~3A*9cj7qVa@Lkl50q5EEOn5cG)# zXiTHI=b(%qD#(xiql~G!1uIOk{gEC3sScpoqE@vUH>e1#T1yg=Yv|#Hgg)c7) z!7wPE!eX>J1?n)q^)z9>hsL1{#Bjiuqp>L5*q+o%;|hqa_cWu01Qzc?peXQAI*-;7 z!LPq01VIYD6J*Zft8|AVm*{3GgzQc8+K5CKM(&(wh=uy1v!I~Zj^1?U0&S80Z0PzEcuU7R=3>LccJwlv3$%siaF7MlK2w?`1kPPM zrnpnO3tn(=o}<(QVXu%r3D>6Ch$0#71ApU#-(XMH%m%K5-&r+M$hD5UC>Xc<-Jb3Z`@QZ%Y~rqe zziSO=qTLxevYs=Qwoy|dI=Z%Xwj0XGB0>=?qiaVyZ^kaO$|@H%V(=~(h6cwI>VE*` z9%5Wj_oEGNeK1fEU141YN%{>TMe2=?5I}e*t#pAG zL9bA5zJOtzxlhiY0;Kg4ue(DesH z8Ctn}5=>WOhZx!_D}lu`BLjtq4s}dZl^B3`xEKZk2PH&6WBxQokx1vf3yQBfD~5Cm zF})f==~7CulyzVQA&d=Z?eAH5lp;t%$-(d%WyJgX;wN0Y!Ep{UC@SM;%zs@}=CcG5 z^p6c-35O*|u?QxBrVJw&=twO=B1p0Hf@H&e$?)?Wo+QZ_4UADXx>fyu4AsBKwuK~0 ztALd;_=m^p$Bz2u@v`+TD8C*<|C`gd$HVQfo9g=l>YHD;Z-?U(Cc<*Ulj`#2?d=Vg zE-cjEL9rY6Jd>+3V|rKElwrWalgm(hs6Crg)Vbwma_g^vu9 zPvzX)()=^t4~NTROh)&8d4%BQbh0?Wulmd|%s-bP2{;~)csxMxnKwR2^2YYMT`!Nmq$fVT8xW$X9HcOI(Y| z9W$O4Ce0)_P-Kya8zOspdZ?zOmXwp(B|F_PLbDw*y&5gxCpxJYCm$wMl9H16`1pEz zdr3)3A|WC*Cx0M4JUw!9b5T4r4Gat&6%k=!VKp^1R##VpgoHmVCPy?bDJLh86Cc?p zI2#)t4-zgfHDNCx8O9?qkBo`594ty39bO$AZ4MWA4;Vg4c{V?8M^%Is7eA*ODC0Ux zf)N~J3==OhMpasHPG5{yY?yy+RLCQ^3;+NCP;^pGQ-1*d9F>C<{sblpFhBfB{O!Pa zVq5;Tr11FG+MVy%`pU-Q!P1!TtK0loBkh!aJ?(XaMi?DL&#Tv7|G z-l)A?FMoFO=jWZk&SfTJX*M&N{E+YP8^cHY_Pt#Z__y0<#y3ng;7=wLl^9h+wX& zRdroATG#};_`9abx*;2_7KKMdcKVv8)oL|EpMQ;F2@Iu81X02p$uMg_3L!6ECyX1sj@0Dhu5?Yg=7>Yoq{)oV6yHos@^iO?GmZf=^d z@r@_Vo@?}8V-r6%2MPfA9@3q7|PwQ z|Gi)!Ux=Ru*Ux|$%0T$t3U2G@#fzh*(_^=V>@yH<$9Gk^D=$ZU5?jAb^UYE+`1Ea~ z(YQSu4?*DPgFdS`0$`HM^PjV~E-`{dD1Ru$_^jjQr)e%P&o5@KhU4*QScP^d$~FML ziOchcTwHWIS8audYpYu06(Zr6IDyB*(`VeQp^Br{Ep+b9WqH+mVc_! zgo4&!Il4p_f=s-m#zH=bxJ@ex+9@k_vqD%jg4IZ~x}wB5_|7pYACpDjcP={jYXyaN z6bWJ>P%NkecxI(9ggqNlE}TO;GtsnY&Pp_G5j0I$3Q>0tNH}AXUPQQ%e+dHtM7a`= zQn3Q!5wc)Mp^k^FI9adVh!hehE`O2U$v_9W$abt?^MsV1wjx>Ly$)N_iY&Rrnm9Lk z92XTt)gl3yR`Qi0W!!%7>q{M%Q0Jy<@L+#`Psqn3Y={d{rs_rH(GK6fnz_Fx)YbU< z@dgLP>VAJuv~465%SGBHzGkplNm1?<8qtJm6ACR9QzXeddli1ZST2`~0)H|^kJFZ} z8xpc4snu?YtI-6Nj^$?Syp5KVPzA$rY)Uje?%-H`Rww8-WX*mD-D5(*s9+bs-0V@6ui$!Du46*L+Ky^8fBJ}!8qDw9-ZQn?R`>{=5sEUdS8SqE)-KU z0-9(4EPdsozCuB=LY*R&hNGx47Aag`1 zWMpG(R7PcGV`gS$kypOmR~w@Lnu!y8fiQveSLhNXg`dMi{V6lN&o-= z4|GyaQvmzSgE;0;8UFsOyJ*{yT`AMw000BlNklEA zw<7uN`DUy0mVX(oPX4$J#U5Wpwn-*ipTEsbn{Dvd4x6Erv-$pdw5i?aNJ5!dH}JUI zPgghFT<18)tVCPJDj6=-X}0;=c{)7il*2Q$eLprffQ0Fy#d*mm zjFL{m;tBr4818d>JC#VM*L6RM#en`b`_K=^?Y8=1cq8;o^r+C*W6g$4lQDX@CosjZ z(=8eEc@Pr4J;H8aG0-7(b}+&a6gVogJ#E{duwPs;JW4VcL0mtQFhhS@;h*a;eQ*eF zSsa!g#eV=3D9Jd~_hW$BrDqBL(m-vegmkt>Olci)O-Er}oKh+DG6ccLtp-$$A)=&p zY%91h7*XM=#ZB5{eiQCu9U%K$ZF zG{lg47eh{l^QjRFps5=8#G_Gek2}V=MpRgUx_|3$-7p&1cEBfNT}X)(aE=rabi-u@ z>U%@D=H9G^%eRxNdl)wZsDCE{F@rH6=wH3D7*Bqd2q0Wf(&;+cyZw_D<=EpC7J$o1 z`t%5V$*);M6lo()GTTo{)-84L+zainh_$gQ$vnG$%_yGbiJ(`q6Qv} zcT7aosQnkUAv%fPA&9WNBk7e9GPNH4>VIJMkrYYc?ImxM2_V_(UW~)&S4Vr33>`|P zwIrjf63q}+a^5?K2&x>j50f8iX#SG1b819Kq)JIawi+T+25Lw!ep#bag-`=Kl?hIf zJV!lt3Z02j6-T?1i{$-E-+U6=FW#?F+nf!JZ9X%))h`-BWhq58Vut36Sc3rQ|1ebeDq}{ zgxteXu+7)mjtqVyV%Imn&Zw*H!l>TwV+Z?o{vS6Mkc|rw7~-N6 z@wg(+hy?h?XVc-r4awnJ^$28-I@yh$}+}&0n?2Hxp4ujV*vlyS^wK((W8+L z0000DbW%=J0JPo7j%~0FDMi`m<$zBx)Bpejmq|oHRCr$Pm4Dk(<2n#Uo%l}D7hUb} z{~vmGOGc0bVSss>Dwbao$F;P(+furJnqPkTWnPwLp1&bj*5zI>o}R#IT)t?Thl_-v zN#=Pu2~mv1EU1myLdUR^B)b)I~R#XLC}!1_}eqCijVxR zpk=%ZH@aiFNPp0X<`m-X83J!q30wh>bR8zPZax7^`0`dY3;oZ}w;6j4Lf=~;=GGL$Me$^C53vjQf)lg0; zXsNp?@OsVbw7~*RbKDDXwU1s9L6m`@txzHE(QcCy@N9ZU+N22VGLqPI|!pHX~==p)8StMxm&J-c-`+4r(vD`U6dc`QDz*H4yl=0XhcaGZ| zm(y(vq8c&`AF{qUm|h&WC@Rzn|5G`7N79N@UA)@E9OavB>%q@ z&VP_NBSz9>j-h+NngkDpEXTP3OTlSMa%^$U*bUSCP_YFjtf|GpA{2eWQQk6BnMO{- zC;zeQz6I5^l|3yIQdTPnxQN?9L}9o-6x6Y%oVR`7lu0B?t`Z}1Km`D=q-*-fj2nFg0N`F)(k%-XAby>PUv5w2MWo73mWnro1;|8;$ zMQisZrh3TcMDFH7Qo)sT0^2ZuS&>!3mZQJk_?Qty5>3|00000NkvXXu0mjf^(P8a diff --git a/TMessagesProj/src/main/assets/emoji/0_1360.png b/TMessagesProj/src/main/assets/emoji/0_1360.png index 7879022fe8880e2e2d7d4426cdec7988fc46eefb..e374be955638bb624d42c5694d224ed8208fbc70 100644 GIT binary patch delta 1376 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 B+j9T_ diff --git a/TMessagesProj/src/main/assets/emoji/0_1361.png b/TMessagesProj/src/main/assets/emoji/0_1361.png index c24e9495a15310456261202cbddbb71351750cad..f1c376d17bbfdf926e3aa41f9fcd92ad925e3412 100644 GIT binary patch delta 1235 zcmV;^1T6cz6y^z#BYyy0P)t-sM{rCqB_J^|JSrn3Hbhq{9~(3;FC;o~E;&Uh9TypL z!60d{EOodd77sfsBQYc$L@_ET92QePHB2`z9~BT#x&`@8~^|S4s=pZQvlRWkS?$O{u^W9vUKG000CkNklL6Q#%(EGp4{byuhvWryq^V1aC`pqa(LZ2SGoMH%(czF7$NhyXP zbbhJ_BFujw=GZ2BCuAos-!kI76H|*g%k0Dn+SCo(SEr#nUu=qb4b-)WN#@mwY1rCzxhakYhz-aq|1vTuo_5rNLl4cUq9{zFVo z%&ph6m)VFY%=c}(?^nszk%_LkA(%6o0pMHXHjX1x%!D+ENmeK9bd9*tuDv2SG5mrE z0mk080}zlCr#3NzKp2FGcYv5AT4sQtsY$pXBKAn^Yky$|AVTh7EyDGcbop=+t12@Q zsoG8`6EQ1d5*VUmUn2&Y=O~<(Wl2l2bVSKpP*M^jc&eT(BPgLIm#`AVNYxe1L{}s3 zMyL_`r6`YktS}N8p|w5fH=1VwP}UCTG2raPcBvdr5P=~0b_g7#4}pkAjD3xeIdD=4 z*#8iMJAa7F#hf&TCP4uNXJO6(3h^sZl|T(*q!2lg6aQ|_9H+k%suB(GqimH&uy`O4 z(jsIAff*?8-;M-7z~QXBAxR0uP$5_~Q9fAZ-u?b#7R-r@x(Y#Q zQHjxibXul3RlX0zK{PGQ6`~_GB0x$>Rnrpl3RYVDdwYfuWm%~9$u}`C>I;d)KnS<* zhJPJ-Wx{U9NGZ{^_8w7AN*E)Qqx999^Un|hcCDR@D`qvqoBvyIf|Kg-ROtkQr5p@H zTq<0E5i>E>h%OVy$q2SLbCfcL5u_mc8qr@C|>8aV2j(;)CAyzxAEPF z&}_(KLoJTWwgk7ka17C`zbeD<_Wg}wptvv; zpuH((WJH9dd}+%#wxeBFjNErY&riQ=a0A7XAQLLPQ8P$f!6g-;S*IB(kpb6=P=7O0 zQe`I30X_Bq2k2kNWGNWrAH8GOUw#W*-rk-$l{A%}Z!fQJznG+ddwqGojrP3WAt{Xa z_xG%{??=yU^Q$|@dUP|wl-ftmsEG56_L~EgxzW?bzy^3Qcc=gW002ovPDHLkV1hw5D%k)4 delta 2611 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 lrqQdYS9nNI%*h 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 IM6N<$f+I71@Bjb+ diff --git a/TMessagesProj/src/main/assets/emoji/0_1364.png b/TMessagesProj/src/main/assets/emoji/0_1364.png index 66a3a5865a3c84b256a2e57187ca7bbd28972c0d..11c6cd61f37f7d3af1ad8559d92e6939e30e245b 100644 GIT binary patch delta 2404 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1365.png b/TMessagesProj/src/main/assets/emoji/0_1365.png index 39d1bedd8e9aa4e23fd55d160e6d5068c3edfffc..ca3a87f0070f3fdcb39d3c58b06e9544e71a63b9 100644 GIT binary patch delta 2441 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1366.png b/TMessagesProj/src/main/assets/emoji/0_1366.png index 31c58413e9f2b39110d0a2ab429f47e90f5ffa61..01380e0da1c52236cad86b05eab0fdafda32ee91 100644 GIT binary patch delta 2315 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1367.png b/TMessagesProj/src/main/assets/emoji/0_1367.png index d9283736f428d1026a5c58c2a7370887b08a1673..678feca6340387f3f780e7db592e3513d223c2f9 100644 GIT binary patch delta 2258 zcmV;@2rc))65SDyBYyzZP)t-sM{rEl>h00z>g)CP z>DB7(*6Z%s;o{xy@!Re2(&_A~w6xdj?&kCL$ttW&E)3K=jqtt;^gk|&gJLE*W0n5Ct_rE!Q{7}&_44+{&dg&JC!(|`Z~04sD-PE!CDQkj6J4+#T|HbyJ{ z$66r%s&Zxi(0{qW&#^uJY@PmnjoRnH=-=Dq*rw8PI^_TW2aHKXK~#8NebbP)*_A}U{Gl3+#^YoC0aejm zcRF=lSD#cm5B2(EqjA6B&&#p6(;l=?gR!yY^6;b1#(%AL8xENNaq{Jrx7XUFIjM~d zS}f&nJ>Q*FDwWot-67_`{`(yOFR!&`wW{mYk?RW~hL0qAZT$LHX+1IWN1)w)YP}Gk zP`QS>_40xxMzdCXeW?sO4=`A{Zvld2P^`XbnyTsxaXte9fj^toYLg7gQ6MECLPdlr zectzZIe%(J$d=!-6c}$Wtv2nCAmt`t3=rOkfWW!EGhP7b#RjUYz<7PbIIuT`A!k75 zz=C4>Sh|J4RTwBRQ;AWbeStv;3kZP-xlnypL7bVOUt*xx@W{Y4B!&>VFlbeBK|#y3 zl==`tauhYS&Vt?n}=ql6+4O9#e5+ct~?HSYu3ezJ5 zoK(3tzEzbyfl(5&7fnP^5JCvdQ-$%*v9b)quV(UK#jSe9WJw362PhDrt? z2B?^r(zd?fggz80nBX=bDDGADF$TO~T#fCSumU*?q44RF7zHsX2*tuEK%fxBR}JS% zJ%6DjgA56TTx}fVo{&+n!TYccZ?{+_qhR@VA<9;PX&7}}D zdNd*HH&W>>vd?1ti)e5sAb1!vOmj1%MMw#Ij|u=$dTUCkaK{jj&MMkczf=OQgU~T9+U9n=W(TR%i4Vc;_RY?A2E{P@7F}xeENBQ( z=Zge{VtVJTtp%Qg9k_kpo;ECOc7Lnm&l`wUxYn?((>{nQ5ePv~H!i6Ba@D%TkyBLHDg8E>B$BDw0$T+Qj7X%FYd~}KM>yj6={Vri*+XW$) zJBA?yLR501KegEi3C@_8sBc zSDJ?8$Z&C`oB;$vICj@0;ywlX08z|>2-nfbh?8V@%+l;~(Sj4azD#c}sl?>(DcR7v1m2!Rm8;kY(|(R)Uj_;H9xV4$KS zfaCsS)WcuHC{y4fVFIIIVlo+xbp8;Ces9UUy58^i0<1rp^0%nxl4#dK$TSgx1bsGx z(1p>{mk@SXO|_5Shkvgl5HL`^Sx#UWk4y~sAui*V0MnHHkPslKTV+&xdylZ1u9GYpzcxoq+!;B6Y379f4+71;g1~C3%l@NQ)yqD} zxFh(1D#VNkGWrVo_}CXjw11z_mwO>FPh4m?;lp8NK!j`v5r4=D;@QOU>dls4-`9IF z5MrH#%f(EG0f30U1!7zh0}$g{Qx^i|E;PQzV8|TJLPW ziO^XHP+>^`$nqFKKxk|TQ3KI__(GRD_W@!VP>AxT2jY?)=yi#3$Jw!=k>R)?aDIoa zr>72xr&dnPAOut;A@h_J(g{x#MFgd2fp{ngU0(!Jnty%08phRjP8xj;HSl|b-nil| zEjL`t((eeF#1a5Tsa*~JChr;Qs;o18aV7@0A|e)+f~({gF%&`rfIuId z8AlL)eoF?yLLZgHpi&vimKFpILx`f}d$Xj_K4Tc4%YUT+vi!=mn3pxZFTAr@EN~Z~ gk1a=&$z({x-xQ(!Qu)L)@c;k-07*qoM6N<$g7Feg3IG5A delta 2359 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 b4gUc0tP*o$(D<0o00000NkvXXu0mjfoDQ2n delta 2297 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1370.png b/TMessagesProj/src/main/assets/emoji/0_1370.png index 76d1e67f3917f161f9d931bb312fbc14264b8c9d..bac2cdbde5f757edb8fd7cb39922688ab9c47566 100644 GIT binary patch delta 2363 zcmV-B3B>mA5ycXaBYy!JP)t-sM{rEq_4V5B@zv|?)avci>h09(?a=4y)avcm>+a(5 z^UdYx<@5CC^!Cu_>D}(|&*$pW>Fd?&?$_+@==ApK^!DrZ_T}c!=;Xrc=iB1$?eFKl z_3+8}^3m<}_T$&B_3_{9;;`=L$?*60@aNR>?Aq`5_xSYY?|=69-^Z%(?&8U^nc={j zCxNXx4^;M;(z1G)79YV>%hs%t+1}l*3;+h@6OG^?eg@~<>$-Z;KInh*HL1x00019 zbW%=J00j#a9w#n1Lrz(Bbb*FvmZPh+myDp!?cllp|Np7~|NsBM|NqMWwEyn^|NsC0 z|KR`s|NsC0|NsC0|NsC0|NsC0|IGjY|NsC0{anSv|9}7g|NsB~-v9sq|LErDii&ms z00(?YL_t(|0d>{|ljHbyz|nL6k}TVe9$MxNGt(3$lfr!46os)UP#A{C@9p5a2f7V{ z8@oo;;bR8<#1Q^35rlC2CgqV#{-^($2qB_GL?RGJ`PTThlK+1q#6c;uA*vyasqQrq zK`OC}E`J?6<81|Mx8kj;#4L+ZUpE8@W3?M+eI>K*#sefEOkz^XA`6B(s(^q@Lw1GO z$}ta(OcGQ;loC@RYB8^erK&`TK$USY&xlkvLkLNTfC3Q{QOZ0EyZI1722=wwx~eX- zQgR+mM2Qdtim4z%l$m5a6ndnP$pAr=W`5?-7=J`Sga}1UgHNksPF3b0+DtMbQ-o?P zmxxA`2p~#$n<^2dITo_2mj(08Er~ops6A=PI2}B$u@H+k%Vh`3Sv@oEQKm*o(qy}ZCViqZ&wpK2n(9z#K-SfGY$SK4ZMqaF0TRY>d_{wA zf80~en%z)JQ>Kjid}Nf&#n2!kD2Ys2i}H zRx9h`*m+GeA8*D|!>-b9fy`PUA`H={?Tm)*>1rj+afqzeD|axA!-J>Go$=pK-kiP; zkQA9BXkuQLOS62p>za18?r*N21Ai+khV6LWl?NX9L}9L(H-JJACi69P*5+pyC+oGz zx*KN~Ctttlx)pwMdA^+I5I{{v2w-{RT^PGhM7i8tm*LIK5GWjD=M2aE=sC)yDL4_*b+uj+d zBw%?BuL!>dN@N@${Z9kD+3&BZq^?Ek42DgOewvC55pK~v#$&+Cp?^9(ZQejfhjjA! zCqLoMNPRmM{-@yGuI*T_z1$36zgbn1md6AZ7zCLp84erZIfhn4(s%7Z-O977w25risw70Rx~G1R)t|e%J?|@AkTO_s%fpc8>AM z9dx{Vz0>#CJ^@6aCVvio+aD|2cB^OMBYzFacDNZ-RR}!3zWa?|-1s)%FcFa@fInBM z`ti*!*l_Xh@Z2!W7K>rHSU+iY&5!Q?l7&w``Q#^dX(~{JNf85VZ2tbEU%BLIb>aBQ zp;0|;+U6lF78W7gHVTM85)k0q-~Rlpv~A;JKO6@*OvnDTT7NE-hy0DdSwNJkM^H0e z^5>8KfG9+mL;)v1J*(0G z#QAk5D%_{8$G-kW64}0;j6jKi4uXd)d{Gy(f-4aiqQ9gbHuQs6j;NJb$~}jako1DGxR_ILC2LP{5-m!$6A%CZk)Zb2clrg$Kvw%~B>%Omxj@ z%U{yAM$lb$-HGFkZd52WyUjPynVS?uKn;KS@C^HY-z)07T%8BE%qvjf5q}K5-NOQE*qw~seYkXa*^LE^ zYOX%`+~f~M6!7ODEy1<=z;3AT!c}u^qA26jODz;?LJ>g^Ji_&6XHrI7HkaJ3O-3$p zW1>U}P(c*d)I~w940*q~?yg;S2K{(c^zaK)L{M&H;Sp9wdXw?)7hnA77hl{3J@$+} ztU*6*T7MG(Y?WynP;^}$Zj2VKzVFp;=zE1efg-}B;7ath5hI3LucwB#McLEW`ky)0 z5EL;rJjB)I%9g!bXiW63D?0XnZoZz}@^XlyudpRdc^~W-zt~8E^@2ZI3G1>piPxyQI3Ed34Hi51Y hCVtmw_)Wh*{s->HdgP7H8XW)t002ovPDHLkV1f^R=ac{d delta 2276 zcmVT+>*;Nakwl#$pYBjQ$8dwYzM`?Cc2+4}YSfqC6@kl#`QhZf!$Pek~mr zHzgsdsi}*Li%UyPI5|0;o0>B-Gi@Lsb#-?>KR{GeRc$^e1_ubo$H!hXBr`8B=ub}< z8ZH|f8%Z}WIYDq!Ws*u-iG@!tPhgIdTQ(jcJk-5e$8Oec9RBOeG;MGDn?nP>*3jlxk4MubWpwLajYLzCJ$MLqqlU z_gZkD0tX%14h|$Stcd^s0Bm$pPE!C7{zeo2UI+s)lys)Uz#Ju!{t~tR{vY#UfBsYc z=6@RTZ^t;!lQKcpyv?xK{;2aQq{7wwh}hyuWPfAV_u-lEzP5_ZPJ^JP`{4EIKKj7a zZ|d&F+K1Azz~tcZ^SO~@z6_-R00sm}L_t(|Ue%WMb0bF4< zmSowMZCR#`nb)|Sg)C$4atlE?^dJbCnZe9Vi;(30yYy(i$)@7?#&h?}eNv62nyF8( zUw^-T-JJg$Bm#h#!=7@{)t0fb4sCNITZ6P^@_?2$mV?kvzQ^1mV5g9|%x3eXxrB&i zDqH-1mkW4+sH0EH%F&r!@&WuVb1sVT*(sjSFZp(SOD0z}iCERR1XzZi zN2pIYas=)J3RbB8wrICJ*7v}8M>)G?GVq} z9@;@FpV>gyaX>qt9&a0H963L7YJdFef4qG8a;?-ZAjj6_W0kjL#P-eE`T5NfpkaV< zIJQ4yzBc*gpj&lb9jf}~tgVV>_PIF?Ibt=;6}1XAU(h_(aJyj)F5&k?fueq#!yLX= z*KtcH8n`#U6e30R961@3zc(m%Cegbh49oWl-?TQFrsyOdb$#5z>EHv znTlBUGL&;|^ALn?%#l;Nefwr$-Q!(3k9?Z~J9zGq=&VL6yEn&dUt|2@t`QRnq~ zr+5nmv}iOMAqX-WO+_PQDi)0j@wLA&h(dD33$XIeG(jIiD~by7Nk#>J-)p56-}e~b zVJcmVC{W02PBQ6tlKWPx6)2hw#Sg$>yjV18nFYaVwF0JYNSm9Azkfj?mz_T;V5pd) z71a`1Q(tZ~?@T#IBJZgd*J1z!!=uq0zIs{0tT_MlULiH; znmIs$Ab1#tqhTB~^qpX$5F99~IeZvabD9wZ3*-25ge1twGJZ=flgZRFb@h>z_1BW( z22kiQS$RWt^%WK(Gk+OMLuE2#5}Vxjqp0Bz6_RTGrAKr!c|3(cb-sS%&b=@46L3q}E}X^qhupyNRy$!;Y7=GP$Bhr$d5762@|I>PzYHy2gzl z*;W6lt3HdMK}|2rZ`TCF7(DFk`dvOG??eJAzkygriY63xcX8Em!igc~iB;Fl*Jccf zXyRINcOVSbJ`y6!jyO^T5*Ugin6O_Z{X0n{vD}@BiGPVZIV?nwLViWpI*fq1g5BMJ zylBb-ID&$wlKm=<=mOzPyy{dps5@UJBE*FTNk!K#eG`o82t|9pkZzYqaFk2?h=}mq z-PXJ3gl-}LVwZF~anQ?5iK7N0R+2&-4(}55Gu*)d0SesXSq~5aCB3QY`-2G>4mn4U z+E!Fb5?xFxd5K%9xj`pM5cJzQSW(J*SwHD^lcViNACk(H%0a#OASk`^f-~T}pez%= yAL*b{c}evj`>^mB4 diff --git a/TMessagesProj/src/main/assets/emoji/0_1371.png b/TMessagesProj/src/main/assets/emoji/0_1371.png index e0fb693d108391495846e570f9c61ca29e4cf7f5..18337cd1ff0a549ac67d6d327ef33fba88be4635 100644 GIT binary patch delta 2254 zcmV;<2r>7N5!n%tBYy!1P)t-sM{rEr_4V8B@YU<>)9UTj>+aC#>(c4#*X!=!@bk>& z=;ZSB=JWOB^7PN<>C5Bi(dg^b>g?C-?(FvW>GbvK^!Dra_r$-ovZa>2tDCjDv%<{D z+v4B8rjW(3oXokU(7>+O$F;PbhT6}-ua0!1k9^(K$mHDpXXE4CoqcJid0UcaOp$(ZjBsCgVNHQpJZVliNjfZEIw5jNDn=?4&Z zp?<}bYR<;J)wGu5&$`Q+Z`r@5+og953kNSKBJlY5BN`I+`1Y`UF7Ea9#o*-8+~2yw z!r0~K$I#NiynnRe>g=npt(%#Z%H7}U@bXhla0dVY09SNUPE!B{3ltwKHb6>OdUb+k zjcT2&x~ig$n9Akv=-s~m|NsC0|NsC0`^*3T{>1^@RDXB@b<%}*l}Vbw;peTYn{Wf6 zGdKaZJLBu_F8t4H$JX`uTK6*0mUb+3F3DF_?*?0+=hI`qQx^U&A_&2oJLQ}E{|Ep; z2oX_)3E#yZ;TArq)?3PeO%WvoKBi>DPO z;mwwctfekWJFQb9LWCxSc=al6#+q2I2b7s48Gk8JqS!wF6+r|EqJ1+m@9K zgG^GAg0hOp>t6&R5+ZpsiV~tt#A>U|A!i_y71%jm0-=o?pRSLI$Vei!Kty<1h;?jj zuPk#}S+G)Y{%f9>)k3IhpAoGmUNsuJ6l+zMYR(7t45jWe*uNBFonrt^hV=S)`g*4rAHIF>YFj#cnwKBrMA%+E=`E?_xQv~zfy^cl5oYXAnO45@ z?zi-FCK~iBEF8YG{jM}>s51bHOc9~Q+87us=6CxSPd`5e(D?G%lZX4wcLO^zty=(v zfWRbomWuoDesH|Ke)?Gl=%3ZC^?&jG;a+*Ct~R%B-O88(6cT`27;vHb^5V583Fu|# zs9(Ik^}#qOAC@@S-*;<*Oof0%@$oIIigmqmg6~=!H0Lg%BN4?I@UV)^nXVm*5jvp z$zf1oA0P|JGrepIn+aDxJim2m?|A*ZfOh%AqtD)In{z+75vtp8h`SL)k&?uO1K`=! z&o`Sm8k&NwYx{ef>h$)Z3J_U{padXVtS5)SLAkjsQ5r>oCHk_M0ze=HB?BVb6nV@3 z4&jj6EDb1V3k{%gc(^eM6n}{*!5aH+Pl9_u{}QL2MYeiR;O(wq&7XoIQbYi-gE%|@ z9=ESP|NQ9j%K`_73|j9#CIBTe&H!jmLIBvy)wy$lq}~HV=kEYeGDHB-0q((P#m z73!&PsQ2Cs;v)@Y0g8l#^f7&I6T-d9YUjq8tGheFSs@5px83Og&;$f!D%0U;8|zaJ z545qwlep;Vcz6?nZEpJx0D(fBxw}7k1H@Dlg8#|LQdp#cbrfIp=v4B$@x5xn={VP&X1{P*|r z#*gkmYnlWQ3Sh=8gw%cK;Qsf@cYi8#^;}h{ThF)W&t3BKK=VlecLjwI+Klyuy z0B8}x-9MYCBcN?J7;z>?OfsPi<@xvit?9V^al~By?Cu{?03bkvRuz(b0ZYlV(X7gk zcDMrtK>=hj6F<$`ME~36xP=Yxq&VbHFVzfr1EF0LHMZW6A7Y(UViFb_8la000UA zVEqT^y;C@N{eM5kfdQJ@*7rLANdd40JHN0nfl-oYpk~nkPO?E-0|oB>+0vYvc7DF1 zfLbh1TmTk;+VJlELlB540F1N3lktez(9}_W251Kqc7Z|eW8zPQB7lOdZ&fNy>l9fb zBmfv=dH-*0k#4nz6;=wx)zRO=G;@4LIe=!R% c2K*NO18xjoN2+YZ=>Px#07*qoM6N<$g5C;$^#A|> delta 2180 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1373.png b/TMessagesProj/src/main/assets/emoji/0_1373.png index 9a19e5213f3373db17c4be8170ba19fd8d9c50fb..c3599a7a33a7480fb1131cb4f69efaaad32670c7 100644 GIT binary patch delta 2258 zcmV;@2rc)K6WtMzBYyz)P)t-sM{rEq_4eED^4RR|)avci>h0C)?a$}x)avcn?C;|7 z^yTyP=JWN^>Fd$w>ge?L%;e|L=jzqx=-KSE7@5_jGV=Wno@gRZ&n%MMXR}xxm52y{~v_UT$4dJTNOUCm|#r8W|Q8V^Bm= zKQ<5z3tUG#A{7sVbY`BDh`6MH@c8)f^!2xiLa1*T=#W&)ePDPrht+-{s z000L@Nklgt(iGv>&VdfS~sc`r+-e$+&)wW-=AG(X1WY&93=|M zB#&lhuj+9spW=I9_}kyC@PCOALb(1bRi&=@Ujpoe_yPpP6>6u{{~r+|BQk~-vX#=w zwHFa0rq;e_(yFQdGa_EejJz3*$mxcFh_#Pr8M=#B)h(^HY7`)L0oM`TSX3J~78rz@ zdvm?)vwuu$Rkc@z6bN`|ht{b|p8?Sz(jO^mg-J%422;!Aj3Cqo>zLmc8o!kd_W@%)IW_;1l z08u@zL%LD;a%e@D*cU{B{bzjvasRAa0z{$bdZ67HYqz9=+z*H#Q0zaMx`+%F0Riy3 z1%G0-9uQQw9|>XS_GjxGPbC)7EfET$2LdBxYVMpFV;Mpr3T6x!A8)G3cJRJcWK&V3 zYaJYcPiB`&WS1Ett_%^eKVB~DT1|}fA|s%uVi)uH%NitmF=x+OC^5_;`&Hjkt8QI` zY?K~VQ2|+n0+&M$^BmE!ibCYoMB~nrmVZ`2D0)y)u};RR(Re{v<$_0F>%c zQ56MrjkxVJ4mzLS`?t3e+u&^kKIwkHpVdvH9@1BBlL zDN2R_7&^pxXj|5{Oc7H~GOsx2OhiP+ieIW)7sdKRi6C?tilDqU+X06ZaxR z;=!Sv-7FrlPB=SNwTL{ws^MinU8d=>-}9T*eMstqKYPDmS0h3O0m;pbcn_Rz-pTWDf?*h5@EqEQg%eIrYnLDeV8y%?9{Bk+ z0A{p7{%E^%YagdhPJf(wEhItw-n!VD1RgjX9>%+P;Khr9LCp8QQ=j;`;PCX+sfcL{ zf`rhMZ9>4%cl`L5zWV893~^d~@3^)WY(am#%r9O{*Vhjnxt7AU z0$S_34h~xtpzi2kA{_#9*CN7e+h4(WMJ&fpD9;g3ju$J)=?6|{4jxwk5_Y!jeLI(^ zQc;&oAQ^7H$A8%oKqNepwnS`4FhRz0*g}MeIux)nt?ZwI>s}G~Bdc7r@xtec$uvpF zp9yddI^BwY{q)m!&tNRSD^cV<{AlL0A_PN;G>lp!Y{D1tzCr>{7;3F`Opv#u>GvE<2 z1P}`RvuqtqxO@1McejT(p)rna^4^@%&$(9VwYb3^F-*o4Sa{FvPk{#O-sg+i^0!4w zAyP#A5!Cj=9;R;9V3dv_9WRPzCBnsWG2f_I;1MZ2vNQ2lT~-Gg;4Yxay??g1w`cES zAN&zA1WT``Suh&Aeli$G|4V6c30E1lumv$>eC3aF-4X%ley&MN-_ZRnetreI)jzC& gD$hH=?6=#00OodTp*e1jp#T5?07*qoM6N<$f*jtPb^rhX delta 2440 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 GU;%h03%?AGh<(C6yX>Fd_( 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 YFIy1txVs*je*gdg07*qoM6N<$f`!$kZ2$lO delta 2455 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 V`4IKsSx^7~002ovPDHLkV1mRKa)$r_ diff --git a/TMessagesProj/src/main/assets/emoji/0_1375.png b/TMessagesProj/src/main/assets/emoji/0_1375.png index ccc31ef508dc9a75b056aad21c894512dd68beba..8ed3f87557c2a059e6648a140a4d7766e546cd16 100644 GIT binary patch delta 2203 zcmV;M2xRw;5~dN5BYyz-P)t-sM{rEt^!42G_1Nw1)avch>g?6)?$77y)$8rm>g?6( z?b7J$<@5CA^YrBM^v&k!&gbgV>Fd_(?dtUP-@=Dv z*}m}6w)^43{p!x_<=c{aXbcGp<=)fS*v{gntC z_U7#G(%jzF+k3YQpvIlQq9cVoqw4O=KtSL^DxicH0D(2$J+x6O9?@@m?B5$?U5-FvT2&w9_ zty!7hW+{Ih5$^*owu6r2aUmj-L~b9gkCR&7*Zej`0m4H-lXPvYZsqn-HmkLW7}+v> z_&OxJs(+eat3p8olJ?r$pXgS%x!!HF5yXgb9H&*=cWoHkTS-XJLlQ|u8nwE;-bpDX z#nuS2TaL5!VwX3dM4d_(@0!S>9j+vq@+Z77$90(ZN};@Hc=~00)JGQS&O78s)}Sq0)jLoBrR+S4a6Cn|i z_J3{+i%3EWO+i}V_BN}QXx-Rm`o14p6Oy#F*1A=_HW7J0rRF5KvK543wH(h5gT8OA zd)KHs8``R@7EUcIdLFD-SKAh9DVwG&j@X7|e2oF*kN>!=C1Q)dFrmfo^nx^~k{ zxLIBt4|7C)<6BQ1y3-gM3Wc>>!+$bI&f4bwobepcy`0YW&p**Us;Zm0j-Fb9noIML z!4+R)FtjDZCvJPdq8ogCX!pvP_3>grL7}IjO4W8;ug2XWCdYpF1S zHPZaP2CCFtyQ66uzKi`wpMC!9*Dtzz!1nO*Up@QPX4C4T)$VEwSi4HF5+;&Ft_pbJ@?#C^$|4fzpr`C(bSyoYCgia+dr1m-o9C zZPviWS*9PFEC3oLPK;rKV}Eyi@%-?pb={-xcQ0nm5$s0)UIqf8ArCFV1)TMs-|P=B ze!JanKiJm(ck5~x8T})Lf})WG;3@1n?DOK#s5-t;vc8$Xk|(ZACMfhy>;^x4igDdJ zo^9qJnv=tD1o+-RI9T2*Xb4ov+7GA6)Y#Kjj~=aB1Iuyz)Tf4{!+*Xv`x+coO1Q|b0+;bPmDy=L$7pPs+~NRn!hv{>0$`{BRizY?RuwNkzoumv=DwcPEKn5Nui;!4uQJecr*KNJUA--Y;LK z{3C8XNCT2h0>u-Czkj*3$zGC*N@TxZZ)SDn)&mkPBCzO1a`gnYJHN5n?Du;i?Dy6_ z$OW!$xsqgeoJePzxVG~xVkHlq9*{u6#V0Nx_0P? zj5i-&n1FKFY*&w^{0vY2k=Dowfv@c?Yq@cS7}IZ-aZ`8Sv*Y#--Fn}M4Ewhq(XJV6Jfft>G{=DPY07!1g0 zi3OHM;9$Uh27fk6w1mKcd>dP3V6c7M?le1c7Xcjl$*}iBEFftB!6oi(fkDQbCGbH2 zJ($egs#8P)M7~3nfddTN$AM&w$Mmm3hxw^1LTG{W9b6;X%LKe%LAlGR(ddVl&Y+sBa#fzf0<^gtEBLl-Bp zmpB+9ceSjKpcpN-@=^z0Ob3FN09^C`?&|WTtsdZJxmj*9J{FA3_wt5o1)-7H1xNq? zHJ720-ZUAFxtj?J^)KV%*(JCmfS!`Y4&8tF5Ae&s`l%;+4*yt-XW#f=tLdkp@{>Ay d4)im?D-@_5SdnBx=cE7t002ovPDHLkV1j}6t*8J1 delta 2307 zcmV+e3HOPCq(AK|ni2 zb|)_`gMxxTKth|Fo2-?UX+k6&9UUPfD2#xBkB^TpD=i%y93~|r9UdfMWq>IrB{MWS z6B;7AerU0=v7w=%v3p$JCoQ)(J!Vlr##LOnxVUCbLarJeuYYk>U|?Si5izeuMD0;g zyMA6(YM5q4BR4N8(-|qBpP!eOm@XND(qNAhQK1;2wtvftC)D|GGt*SyoLUe6;E-5KXT#KS4B&Bv$F)}i+TS#72 zO~8m{%11@nMSo0LDJi^0NVR}oP*hZdPESf*icMaRL{fpBot-;Fbh17^934r&4Gqd; zR;O}Rn^8oHUOIm&F_CCLNkKP~V@4(|TB=4ySu_}4US8Q>UtUE>h!-F$DJU;5FC85n zAs`^PxVRb`8YLtoKudcS6%@CDVY`Q9zP`S_k7%*6v41!yCpb7btgNit9W_K!fgdI& z5*iv&Vvsf-9?lywprD|DDleuOD|a3vmzS3g5D-)uACZxf#l^)13k-^iic(Tio^DV$ zKycY7IS~~qVmlo$He=QsGZhaFZAvaxYL`hQ3*Rn3x*RY|T8TJoHaL!Ttzt)4SIQaM>8@=AtSw2P;hQ;W*r@La&h5IOn6Esms>}|m2Vmy zHNihWa8Wc`aGza5J|sPE!CalCvI0 z5(Ehn{r&v@c?RQW zzxybh%gae*wjkK0r)XQfjp_5OrG}D8_}YW|=i|a&Lw%3Mw%ho^)NrlW+1JSOwCL#d z+WzeYW{v;=1_((+K~#8N)t2>F8`~DgL!1bZKoSTRR0l{7{VnLwVa07CZGzBpBtNlze^&l|u+>Dt=bKdL}wF-Rq& zvUF`?;ZUW%1vZ${LnpN*#WYEZO0BJ=FsLFC$%bVm-q6ZQZ&9-3+?!;3p84#JV}Gos zL;}H0baI5kc9Y38=J92rayY={v08VZuoD=f`kU49ImtH-ncRmT4_ECzUw{4) zHogG}OiYihYPH%mA3(gIkWj~%X@A;Lu2rkwhkWDLFOflXM>q7NS}oIue2dpJ;sT^* zXJ=R5seEvEd%F}2oV9VEZ@oRf^3GO0RBP2B39qzTwMsn^@`e2Q#OFSP4to4$!Sm9G zvVoXnrCR{8+d&*rFRW%HrZ>GPES5r1={FY^0ir*iY%*w4iBu|T{kPqvw|`hHkf(nU z?CJGF!cD7Aef!={N31E|>F2~G_yT9K(vz0|G zj>Pjen{C!MX^Sa}nqLM8w}0Qd`?UKCu}oZ>ot-sv%(Ld%m~1xl{2%U_8Nby^>#oUX z5<{5HiqZMe(ceC6__g0-x8hkPPk+BeB%5ZS!THz22(APgkAC1*D}v)nA*;KFNGM;K z6$&$F{+!tNe^TN&E=}yZaUULx2CebCQRw;o(om3Q;Mo zmG|D*QN)6TgG+NTKJHiI@SHOkK;-r<*Z#BY)RP8gFF$G^CNv#nTU_5R73xY``%@iz8$cJ}tlZeMNaRQ96|-lt{&B7>hu1cq7=G$>(VTsAa*W2WuH51|S$|nlLCfzOyLxv?FE$qZnI3 zaU6jHMa;epY)Ou8K4{Umly6#4C$>RjHy90||Ij&I5`X1XT{Rly2uNjFPHVzHjaWnu zmv3)BD2L?{OjpKW7V#hyG#(UaV4Z=0Q3Sjd$!VqZG-FQw+~dCceUIPsy;yTGi&?aR zqTo3iJ_C`K(-@sqXt)y$h@>UV+xV#9cEO`YFJ=VZS(le!@EGSC&j^HlS=R_dh7BzG zPI9dgGko&)R(5#c`!X~34`Dt8%{e<$&pP1b>YRb4oNr^Jl3D8neX0Yuvz8glcv6nh z>(zCpoq5(|CSA_0tz#Yks>^M5E;*ZX>yrN)X>D%qw=oZAQrKS>e@0qeT1N7hvBrOj dW`T98{sYjVbJs~ErgQ)R002ovPDHLkV1h2{9d!Tz diff --git a/TMessagesProj/src/main/assets/emoji/0_1376.png b/TMessagesProj/src/main/assets/emoji/0_1376.png index 6cdc44f05995d6768362befa470e485b65699fe7..716657d2eb6d0df29c732aa3900008323c655236 100644 GIT binary patch delta 2193 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 JPDHLkV1me)<2C>Q diff --git a/TMessagesProj/src/main/assets/emoji/0_1378.png b/TMessagesProj/src/main/assets/emoji/0_1378.png index 4e6c4b89072854c3016fc0c28921e161bb7ef7c9..ba99a06632c6581e05a735635aa7e42802598430 100644 GIT binary patch delta 2258 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 delta 1794 zcmV+d2mScn5s?m%BYy&0P)t-sM{rCtIlDU=8Aw=%JSTu7AzIIy8%{dT5*RV;(bp?1 za4a%>XlkAD>D$pb+OkKQiHC{0yvQ*#nhgs$001W-BV!5+Gupf*zR#81%j#+_6jXzc16v!JAqHtWlq+q@k%swFCe!NnVaBDs(nGeh?E%Dk@(7-*&=> z6aWA!_P-zg<9~LfVFL#XGV#4D{MT8iKdk7oEwZhtz(&rXQbN?u!~y^=OkkJ*05UW^ zg(4tULQ;VZ21-+Gob9zQ-rLpHof{`7GRQ*D#lN>aKuy(sZ#Feixq1#ECs_aDO;Rgw z)MtmcQhc6X1&fQ4laZ17^5MURCO$=TK1g^@V2=IIEq}&D$u>M}MpJ>lImAItd=Cmb z@wFNV4<{}#VjUby>#iFA*geyg6U95v$&42P1R66pXZ^$`_`V%kZ<^Ja8|bGKQD~L^ z(LLa!8Sb_#x_S}`1u`=T=9)BHDBP34`5J&C8QBXKDx>=BvR}0vcMW-pV9U?lWNov@LXmn04yk}_PpI^vL z%KzhgNl$oEQChV>rp{5)yKY3sb7+<;qpE`}y+pd2ZZkC|Gq#XUZ9Sf*YCu*ccA-*C z#(jSI?}=Oh004P(QchC<7!Cdi{x|~u46|cGnSUq#^9U&AD>v2n9?!f@ep(mt zkfE=$nO=!zi0J;5rJ&yEu-v-q(yiLt=JDOP-`6pHRCr$1)zw=Y zX@3+3@Q_I|386p&p&i|7vS1xpRUMS;1fg5F=U0n|oQ-%YDD-V~J5HK|r z?`ntDSg~aDpr6P6Xe6){w?dxjS+m^fa(}s;mk)yo&KGjIC7?5*(N&6JF{&Ho!H~`3 z2?R_)0v9**%S|>*z-#fI;J{LF`j?zeoz7_j6ZkPX>QZO2$wHQqYOw&6;=^gD%Ve2Z zU7gu%8j$b+De#NVX_Kwl6KJlw>k0b1Au*06BG`1UKE~DN#_0+O!K$vR8Vb19zJICZ z$UH#_12}b+TWYKHTbV6*3rZaR%qrcJzLJH4eNf^^jaBjVY0V!qo`LH(AeVw?er#1I zh&kDet?}Yj03o;|Rj((A*xjM;hN@YB5VZ=0qJI3<%1%}pO9CKbYvwN)VfVbMPdP5WK&F zi1E2uI3cdg`kRn9o~(rt*8@+ih{*E0)@}lcK3lzYZ*P3XtZRxLfnDk4XKDo^o}0Zp zK%)D^rZquq$t^3f;~+xf$x0CGyJ!y>A^xgKEk#%QWY+r(M&J_jFTcL1SAVE?&8FwE zSTEqtI0HYqC#fjA!94B#?f0)U03j+yRFiHurhGY~^KLJGnFje6X+Q#{A+{R=q2g`y;J z9`aVS6=E2vEKU=ZYR4uPl&x)ol!>(B`zn$s6s6^b$0kM{L}6>nZ#Z6{QIX^$KI2+g zJ27gAYE;-;sc!QQB8W$48O+mRtkM8ZE$)mRpVtB|)kv>OEmfeUd~}nIssjH}e+R$z`Y#K9hExtO7(h{<-l>r*n*K zLzGlu-0}_{UE?eY;Yk12%srYwhy{D(gM7LKKf0elCPEgCc6;_A+MBc`i31m!`?=n( zAMT+|2#XQ%pCj*x*n1lFEGpP_Q#*l zdmhYdd65X0i-TZ!^5`^#Kv*j kP4a#`l$?8mb+l6d1p`5E9XeA`;Q#;t07*qoM6N<$f=K&X82|tP diff --git a/TMessagesProj/src/main/assets/emoji/0_1379.png b/TMessagesProj/src/main/assets/emoji/0_1379.png index c8f721ab16d1448177a2fcdc45cf56cac565a1a2..da7bec463f73156370b3ea47672661eed01d4f08 100644 GIT binary patch delta 2034 zcmV+aC#>eT7%-0tz;@A1>< z>(=Y-<@5B+<>=Mw?9S%t*zE4t>+bFL_v!TZ?DqG;&(Ep1xU;ypzQe=D&(PE0;@$4> z(AnC(#>S?tt;f#K?f3ZU^!D!d_R!qkoTQ_bnwpJ|j(~-Rb$@txX=-X)T3As{Nk>3D zIWa9D9vyULV0vz8Y+Y7mQ%PM(K7x33ii3c-sFsp?Z#^9nu#;uk<>%z-F}--{X#-o_2(TiO9>c0000*bW%=J00j#aAS*aWRAh62g^rl0tGlY0 zpvUC@|MBF;(SPUv|BQCD|Nj5~|NsC0|NsC0|NsC0|NsC0|NsB~|Np=L|NqQi=;zX^ zo=yM&2AWAkK~#7Fb=7B6-FTh_;OG3WkN}72K-cw52hS$E_A9u*{-n2?bEjJGKtl%% z#z^-{zlE}@*!bM2baa&C|B?_P2r0F`{V(y~MIuRnkbfjftyHQ1KO%CkrAeyL);L)< zySWzX&Qi*X&WhZVcIP1Ms~2K@-L!sMO5I5fteKZ=}{1Jad<@c+~np5>P04|Hd$e*q(}2LlEaIL?kFl zyORj(0c&j-O7v8wkgg`Px#QiM{2q}OAM zw0}Ss6%-V`h{GC^Q64gsVM+J+I(iUFC|!jTr*}t$9|e#1Eo#6xj0{RymUJQ&oSbh@ z5k*5$Ri~fi;sQ`m7!1Rp)UpUX7Arz%P~c2iye~nf-82HC&GWp=p7`%X2UP+A*;l5G zMyxV5%(E^Yq(D=o;O+`JIeEilG52` z_6L`gEA9JGpsA9;Nh;U1R2^i=+-ly(%2H39+4ayV689@w0={>YV; z&Gn(fw->Sh1&-U2AptbXgX3wOivHl2`O(n_4N#{~=GoJOtEN=)!3RrDwn3Fftbh1G za-Z>CHu;#%_khjwgWIE+*23_g2?`wkSo;9N!#w z-*pG6kpQBKR;Z#*^Mo?Qq?~oXxX)R6p6=;kz4*2+%NSU$0M$Sh&MwNIg4({TX|8|# z*S9H^vj5}P_rs?jV2r>M2X1Oiob3e)=%TLeuZ2`BIp zrn*dLQ8ET2RV)GGziCpESozDAQ6X8DMW#CxmUJ%3?&bb9PQDM&Qb}U9_J2^)3GYf` zMU=es)lU#Wt4KVc!6n9Ns%5FW&#lptj+&;I{+ZfSSX)?K_;0Sq8mjtbo|nFEYupu= zHHH_C*P@Qz|vgP=C}^9(eWJpb<%4#rGHPYv6h+=+x3}`b{?@;ZoH<0|iL5 z5d2Z4UQMEhekt+xV#3wvPx)zRrU%mUi2ex_9`rk1(oXFEEE3u&J9-4fLGZj zsPKa4{S{*=s~B^=T!kATk%-U;`8^IobNmA1vp>D${#bhds>$v0CVz*9V>cX&G+rSM ziTme}po1|yzFbThce#7nO=^F6IP^y&$2b=92hftRO0)OR#%wm(KDyl3c$6{Y(de-D z*N0vA>Cqv);KOzhKm(jX;64Ei;?|+uGS=1b>9c2fwtdbEFaDIkmuTP>^&@ce9Bjf; zWIP1RVVBJYo`X+6aDNcLhlW+aBg$;Xb(N~INWHP$ut8qz@fxdU)oAE~*{rtRu%yaB z%y%WM{^_edpF#o+Az{ylkB%nJ6!5OXE$bIHvN@RlZI8vOL4c*E)?+Iq+iog>ETb(D z)bf?rz;7iDUIEffII|jNNG!3cjZw{zrihl{4_a_QKL{I$?tfNQJvg0~>5ji=e;KG2g#R!OqXDnpNl_`^}ckydm3lOKt-06XNw?V8V~`WoQH~lJrn> z%Bs69)C^U?t-&yay#^W{^rA0jn;A?CmMfr?%{+jqYyeFV=ne_(tBq4^V3>==&^be$ z@$dZ|2Fo74q-!O~?;kqg@yz=-ZmVhuoPoI_8T!6s)$l4UArva7QBWAGmRqnrb6?_6 zASn^(@Vi%k*i_1Mz~5}&ee-MI{Q4X8pZ>?Ee?3e)zVS`@X8#wp&a_zlCwxeAya+Ml QqyPW_07*qoM6N<$g1urW-2eap delta 1687 zcmV;I259;J52g)}BYy%YP)t-sM{rCoFmi@(=?x1wCM8$t=ElZN$x1P{@W!Gd9VJma zwhRm>6%Y{+6e%kvFzC&(Mn6ANQ<#KiN_aFoa{BSw=hC$v8IGi&r3?!Tw=2E6fLRn15xEh1sEeBp@M1U5*nEHVp^e$R|!tVyxou!ZatS>K0eB6 zs=`dYl)X;z0001QbW%=J0JaO?{tWyB{tg*8{{A61{zmgEErBPQd}V;*{r>&nvsjn= zk?l`&xRA{AvHLS*X2$s9A6F+{<4bMsbhrEIntzG$LQdsS=-u0*_&jRZo9Xjv_wlyP z^zf8{rQYkVy0uICr?=>i^ZuIgu$IwhfoQ7j000BNNkl4x(uSHMGs7Z?nbFA15H5bb-c{kKeOgT)JMa3P|J<25E5-k! z%73nzuIv8`pf`=Tw6xqbsi1(`bT1e*odY+FGgs?(UoiGAF9}{?jAkv!@rGFhW;?NXGNIs^h=bwz8Qvp)ouSfY%;?NSh zSJy>pgV!N3&W9|?WP*s^QnXT{cMNoVFvO zxS)cy;fy@|?bn6v8WpS!MGfclGtc&f=&HC7!->oF67g`Ak3O9M68#n{hX`ww-)k6# z5qA?$Bw|}2_JKrM{SMlT^2mY^T7PJG6+~267C0v&cBAQSAn`@onkSZs!-<9(P>9d> znQs3h#>$6wCQ=~cZfxb}XDR2CB_Xt*O4ZnvfaU+#Q4z3^KU94pMbsV5jNhlTc!fEx`fA;5-sY2ZpU5CXX;PKq$R5zc}x9&3|Rr63I38 z#sGl0xI8~^r)Su#=a-`lR#FNHfdq1v%?1Ji4~sPeM*7N|cGL!DQ`$V942v~E`f%Ir ztG25rsyd@E{jg>{eC$8=zN!r!hqgDny z8EnSU+gMq&(I^q5Sy2}VWPh+Z2Ti_qrPv@>XhhJ>3RPVo%g)WZ(A!)pGDwq)bU9p& zD9;6D-k{y~7cLeRq~|K_ayatWrD?Mv1NCCJzgt@bq3%P(tVHC4Ok;lrF{|WncnK0_ z{&p>`VjH2BOi>1Ls0xX$T-B7!acFcppH#Yy7Ih(Ad%HsJPSk#1CDnt;$*;?xfB%0t hBh}Q@ZFwj0JI#VWe-Jgw7Lxz~002ovPDHLkV1i^5Eerqv diff --git a/TMessagesProj/src/main/assets/emoji/0_138.png b/TMessagesProj/src/main/assets/emoji/0_138.png index f9d52b5cb54a6a9b3376793a6e62332e5eef71f6..e0705ef6074b6c1d1a738951bfeb042637008908 100644 GIT binary patch delta 1073 zcmV-11kU@h2gV4HB!5v*OjJcja7^yCBdcZt)Qw7~-N6 z@wg(+hy?Ah7}Jde<)skanhO8WJ^$28{mL@)x*x`V0rO2gDft&#yd`#&3 zKj=TQQ@8x3YMx{y zgG|$Wq?|*@F%l@R5RP~|(|LgRW$4GQJ4b)3@-AGC%k)Qr^Uk3p38bRT6U!Zvc2xh2)Fn^3nKJ;$`^&W&lvLLZTs}2LVjTIfHoEbotW5 z%QP?jSt-MLV;mhyLdLKFC8;xl;V5QMS}x(zjon%B(0Ta0?6#Kd8=^3n^Q{upBoPdM zs~DFfpx$ho?_)*up&^P5LK~&~ESfDGp=j;2W&yBzCV#)wahR!wa6vf~H<=WEp)5kx zx=|ow?fD!h3zKSN#)MoDM*CJ?qw`f!-yu!*s-2Fk{0axuy7-!;chcSwQmwMrqg z(Mv3;J2PDvl2lX`gtsOyTp;!)IBo~TNQ)te0I?rS5qOLS$i4we_(8c*8UX5nP!TeU zmDn>gvwy`xlSN3JDkPXHf$WS9Y_qSJybteQZ3<2kAY_)CiAX(;JDyieVVHpjh}uo& zlvGOJ4T0k|E#qnw*2cI8;M4x}go0w>#VXRFZm83`R*zp8UvNQTq+|yW3HSRFn8$5h z8Tdy&?!Wj@j0i!>aHqmWAQ&Jdcm?et(J&v%SRM=Wd7m@DFhHoj-j9pm}Py2c~=-u5YtFG6aT-J z$bW!1QwUj-G5W(dS`y(UW!m=wC`C?EqWy{s<2H=bw}=&qqox!_B+9`Txy&mAYt!J= zKlvZKY^#c-wcKeUO)UFjbpel+NI_m@Ksn_)600000NkvXXu0mjfOzQ(P delta 923 zcmV;M17!Th2(br{B!4+jOjJcja7^E;hVRCt)R=Pc$*1JDlIp*l;H-zxkZI<)mfE6y z@yVz7*0t!kl>17^qm$ZMtVh8h@#RLu}tM>g$;>LWX`y zuVw<^#wH1^hQwIbbuE}_YE(=aS5Xv%R>uUmDwsL8^&_w7d@^01 zVL2+{t}z!^MQT#;&x+KyE1dtJ7*7TLsK5-=y_)FHI^xn6Pgo5Es-ZDjo^POE2a=hF z#(i;7EWiGvLVufL#NrAB8ryf4E4l`Q?cOt5|H^EKu{$?04JIFrGlgwE!IDZuP%m&1aM#*q9AoH#-?}O%3 z(XV@(@gLc&#kHx!5jO3q~mQ4Pl)8rLTfAy$&1GJw{rjR7`;(LV@u z{&B961opWx#afrcknmBFfn%NLxo*UrTIY@K7-=ZahXAH3hUl1#C`KR1v_4>pSfdnS z5yyh^M}LPpx#H1a3Wh8Ze=qUaW#dN$%T(1--b(ze@I3*h@IqFPM&>URl_V5=X@+I% zv!axeRUz3Dq#fC^WjzYd$tuzc+!ghRR?fDx#4vrzciB({P@St1$%zz)@Oo10+wC~U z{1?PZPI$D6p?AF_imW41P=BL|ss_01EI+nA6%D)892EJU3xH$$ zrrz(iM?x0x#1xi`+Y+*IIj*Szkg#Gmg)}#mijh@%1;&-IBAJ?#ju1V{?PfU&;F3ts^<-_yJT3V zbde6SVx4&IP87h`<}*Pg(H?0F1CFG);v;G3sY-D^KY!^=VHsv6o-Z>S>FWzp x3SnB7rHjPg(AxOzWD^bDhD`1C3x2or2NdQ0g00pKPmKTo002ovPDHLkV1oQ#%-a9} diff --git a/TMessagesProj/src/main/assets/emoji/0_1380.png b/TMessagesProj/src/main/assets/emoji/0_1380.png index 7eae36d444dfe9b5627cc2e3f2c7388765ac7700..687e9cf91da22963a736f064b78aefbd44e93557 100644 GIT binary patch delta 2193 zcmV;C2yXYn4V)2>BYy$lP)t-sM{rDbN@CrV4e6-g_r5Ov%0AL=xOY}Z=$F@_XGP6} z4&$I4+K>!gK2c3MMypepQ7BJ_P;z=nXX}N{tW}Edups}_Qmj~w+mQ_2k`0bneCVVW z$bhlHWuZ(cL%MAf>8K&cXP~-ioLoIo#bBIqMPcEA#>H!!}#^xF_hN67sYp?yes9ye#Ro>hzW2?Yr>**I~6}4*J3~#bvVSpx}u?dh5dQ z-HFTMk#xw$f`p<@Y3;C~cuPLvjjMwzY~qqirBsw=nsV;|002^SQchC<8T|Q@Z~WZGi>Xb|-<+YU^t!8* z>+r|^`Tk$^&3@S4udTl9_1(YJ_`%!E{{CF^u)zQT1{q02K~#8NrPk+L6ju}maF&&w zT^6N_M4EyWgQ$p#A{vdxXquT`xA)$c-g__hmVbXW=gxIBVF&P8?nm9{=X>6B?>v?i zbs7eTO|?d&x#`ZGp&yDPE({OP?o3Xa7stkihKeJafe21crWSxGE`_CQc(@jb{9e(7 z;Sp3ZIT_sCgE@*L8afbxtC%Q`sOuPBhc?p-CnC^7QhUV{7YEToa1|5P#oh~8h`9-c zsDCb!ATD%jRaDmiP~0pJ)A_yP30&#y=1}#G-roCXiYA(an-kXzB_}weD4BISsYuv6`Z5z*`OGhb~!8M0BAlPBe$*r{F@({qMU$eSNxVFaDk$t1)~} zXIK$bk2UBJU4Ox*iQ`vVcQ+Ln4aH64?K*9uD%y{$ynE0b z8V#6DmEX2+=zG{l;3_)JW0#Jp!qOj$Cr9T%NL;gMb9K&z;>|c=ZGPy=F~SX00|?XO z89Xvk_b43-#b^5o{KlG&zTHImAF7ZxZH!Oh*J$V;iH8F5^^F^dAf7-KN8aw%XMeMS z(Lfx8Y+|_`SGzu!44Bt9#!ssts)9ITi1ROcLYgph9R=^MOod>q^^t6*9lx>sQ7bLK z^`a*ULMn!Y2jvjEcf*{7v0je+lV~CEx5D)2;rlrEg#_Ycd z!PM~kshMSwi`;$&%K^az=2Q!$Ck%s2!QEFg`h?{cOOw0<@G=^U`)l3 zu-uA5^sa<Gl~4G6PH z$W+N59tfhY2b#!SCklo0WnnDPjG`!#)5i;K3@yEfD;a}kpjrHYM}*na{DA95~U7-;RjlMe2z{C(|=&YiYnAxtthd(`dofIuUW z{oDaXX0}}}PLQ8IUo@J7(B&naRY+K%Nk+0q{qPS84iHf&DCYHRtJ}v3k+pZ5##C@N zn@C(KT!oFKK?u_niv%Ah3j0`?C#9(05%qgLVq`0u4|I$yX0zGM!GCo$*4ro$)FHkI zIR*sWjNR|`dVL;oZEHFe3K;VX)9}^|2Ubzfssc%|HpT9ActIes0I1^dx;!2p326}0 z>#@qjgM%U55<`Y@1jQajf)$F?1gMtdkuahPFX8tK#({Gd1RTMs3V*AbK&gU@=Y_ScMI#6)BurKH5(Pv!j3YQ5eqV*SuhoDAD1zfF zB9XUoRaivA_HUK~0wN$F>TtURSf)zQ>K{hksvxc!|08g}mKP8VngNFJVgW}`1wY)< z(unNd55Q|hLZ)il$LkPZBEaqih6W-G5m>w(4__gR4%Yr23x6}q@C86G{@_LcKoQ_N zurv@fj(`Lg2UA4JFtxu4O~OlA_4{1hZK8mH2&j0`N|7`i9KopxPP8D(@pkOp>s9pu zmNpi=u~X_074j+tgcd;)1WE0NCMBm61q0$HQAqf`nm{5zvO96P@HTUrKtbm?Z3ToV zAkdFx2gLvY0)LtTP38fi)TRj(i|X}5h{r@BQSaeIG0HF$0IY-o$jgZlt0t(^IYEFB z=Sm8Xl@|qt1wnnO0HC-WFGt!~8UR(G(3c1ad~1o$DV1}Qjb#`d!QqDpnh=IVs|}&c z?uO1_p*m-vRFXhI5mW%mg;mI2mP7yuS_lws>i>_~s((NT7A*n;E)I&6{R{~qFo2tY za97JqbWfRLv*E9e8vz~;J`X~ap=cTdxMj5E%OL0zl1=^Kp#-WRuL(|;B2_>WP>9R0 z4E>`>D8g3&isbDqr3FxHR*n=P1)Ni->fu40ydBqUkj(44?Q z$4)T892$BC1~1{$tieCR=)jT^7%}wfs3jf{0`(gj^}8q@mi=$cKiB0RS)z4nh|eF;8TaE-rB1%auAlPNy%ht~9d^5G27! z%Bn`P*tC+et$(SviD$fLill>9gkCDkwQFN!caBv~qK%16V3@*+U=0RJQ*4~#)sgV! zqTbup1`aJMD`>{3hR8$Djb$^%zqiP+Y4-1}uaQuAb#^v2QQNP5QY&xW%!Z4Ll9Q2< z`0n4Db9djkj6FqlKT3KxL}!FKt#-o zT)=vb&wr7Qk632Ge^yXVV8p6nxnqMJB09HpNRMGPgIXy$peChPCUEJ};yVBU0CaRxPE!E<{tW*93j_WQ{uw7OBTD@K>tW@3D%MXzI{f}2 z{g9ZnvyxrnLUV)ST4;SQ6)xpz{_(uVW|880^?#t~)BE{G?CF~JVnwdyphESCYPzq~ zm7)H{_R941v-pX&l%>tT-oU)`+-JIsxXk>m(DAR9(VYGi|2x6}00YlSL_t(|Ue(uU zQyW(l24J+3SQP{kAS6J5LNgsBY;26_xWrD}aCds|&D+&`@ATe#b4~K^a#ze`Og^m+ zpMP?Hz%%c8?>*9N&i~=yrv>Et4t@St0p$*4(5ipL9y$VKrml_=l+sDJ@<>lc|L2clzy%^#5^+$a^U-UBYR+?Q{Bo+6& zDtCQQqV+)~Q5pApy?)>2G8j?z6@g(62Y*)S_dS9U_!)vgg2Q!~@;_*9$3ZC?F)ZzH zZ66*TZjF{#$pI6|-CMSq171quV_bSk!9`}_56piL?HntzM& z#M`6S@kc)l0EFDzhIuzn1fDz`eE1Cx8H3|E_grjsudhX1AqF+k!f{T;)DkhaaT|d! zBBq#COkrx`<(*vUeYoej*}s<5#O56(kSMvt6MF=aK3f7LnoNjrzdZ$k_x#BdQy84c zZ{&%&sWjp3D*(>nHDw55Z0Qn^=znpUxY^mcRl)%zaQV+GF+{jmiO5FaLr{ntm3s!B z*cfxI0*SjWQ-;`dtn>w1AVRBpC1yZdYDz~|0)Y=8RoqoSeeuFQ8{0%xAOf)IW!S69 zX_k>~sne0?fB#Ys`3qQoJUuxnvA!C0MBaohDj~#kB(T)Zo2|(Dn)!VkK!0>CAc1CN z=F#>Yvzl2kPt{3(BsSDaf$$uG=sxHlzz^kP+MM-OO8iK(@a)Oc4l4sclsiF83H96vj zV8}dSCDCB#vkX#8NhyY`MtQCj9~(4#y(^m_cpgcS408@gn(7*FFci(QpHyVkCnBsF zB1e2hmyl(KVXqg7g|FE;lC;jehaZD^4aEpyNSfAs(Igk#C&?h+kynR^|NP!HEqj*l3Eq3Ww0K`*xq3oS z-O_k|)C-MJ`rG4ui^X!`T|s=yV{J$*oB=Wo7DFF&(KhWXyU&yHqsIau6VtVAh0@Rs10 zIbqhFcY!}^=C_sEpnCJptNGfxpjU>oT#@yF)x%kzSuaXH5`Qv34>^l6Z=N=MyH1Sv z*0suBplCK#>3hlKd)?fleeA=ZWivv@hF(4uGv=M)l{<6BP@4JRzsyjU@ye#tXtB34 zkM+~C=$qi*alP7Ww^tuTuw_BPd{fPHvF(uJd^z2vft^Rn{!*|*PUD=>kZ;3oL>oFp7(jr zA&RC>_tJ3xJ$LJkKgQR7YHN;|I~(qgx3=2LYkzBP9nBFFgb1EMh~@}NcQ(8qYmMc{ zn%}M9dZPZ4a+h1@$6Us!U!fgyy#&u0p-A&@in!XkQ!Z`;pFG z+{h&VY-G&Ep$h8quoEp+e=?SsYCyawlqydz6{co_TmFnY>}o(zsEW&0N{ueXlYTZH z-ube9&BE&i5?(zYU%PCjn(2hw?`Q4doqx)GO>M4ub}KeZVzv| zw#mrU)Qo*ARQVf`5pPF3dl%>>eu{6VwxWWtn4Hlz+Jbf=^Uwb1fi1wU8>*K8ivt?r-hyu0H5%T%>np zdD;8VBU0oMBk`(e77Ga^C3!?9x2ENrFK@;1sTz}btBA3ab zjYf`hngyPrE!@9QEeMtE_MB8qy;Dr-S_=ESE*L|;idQwk%Q)3^c8xCC3x(a6Z~7Vt&XrmQ5KNv(k@w(YxKCv$a{GuegYZ^YcE=0*$DxNZLH&fb z)TaPJVtC$0Op8(C4-bnb5Pt%DpR?=1LUuKso|Lb``?X;8Fe$#CinGD7>X}sF!{Y9trvv}N zC`wfqJduci1pHdFiJgk_+Yly>u0(`g^9qZ)G`7`K)aWC zavi>G2Ne-eSsh!fJAY4vL$e?!?iw**GK(so!BUGrwgZBex6#hOiJ)xf;pWN*=_L_7 zj4E0a@MO4%Xn=QsXv>EaJ85_+HjgAcQ^*Loz$U#%$Q8Xrpvh!NfF7I}HI>FIhefAN zZ2-1j4kBQ{?1_j%YL9pPPryy+rN$e|v%S4{I??Ir=_(l;)4uJQy?gy2HE+(5Vs7FB!A#gOjJcja7;*8haeRxGanv4M|YWGJnYNo5)V6HPNPFjd$D_4 zUP`l@X+ofHKWcaAz(K#AWkZJw&>X~#=cW!bjEOElTv`Q!$ zRVi?rnw*uAl7H&s)*>KQOka+TS2Q0TRjV_u-rLnvYMNFr9mqq_c1kYAzqhkte$1n3 zHZ@VdR+dmK8=OLVX=!k^fnYpBaz#^tygI=j9ZtH8U`=3;i&Zp}TsW$ARJ(^{eM>Ex zXHUgG%QQG>2oEPNFk%e}G_N(ZI6ZE}M9FePC?_aWrGIQ#0R$SUOt2**S;CTMtY&*# zG$4alMzV8oW<4e{G)5X3L6b3tgikO{X_>D;qQ*_g%1g{xZJ9wWId(u;Qb9|USYD${ zf+Qj~pJzT35=xpYq|Z>&nMrT1h+&p)Yj8lDSXN%VNV}&!wcP*!0A_SjPE!E>Fbw|w z4E_WD{(l-N5(-f1U*|15G9odkC$%bydJZM>@f5FucUVPnBjcr=*{!%-r{H6+Pcz4t=-?Z>70d^YXATP zph-kQRCwCe*40}ZSrh>9Ofn%8D-a+}f&>dKP=BmcpatsQt*+Nr$35lhda?kMr>Rj@>)g^nVEIYk`(o@2u-<09W6QHWa-UXa(-xHd%g+qZe3>`^IZY z!hqFkJqaUv<+Nr+Ad z<$t>OK~*%#p=jDLu%9RI6ls;FRVBR&B&fckiUe9Om($Z;7X`|q4JV;bm;L3P$}ng} zsav$_&?{MG_~AlYvd%)%=yPPJYdWnCn$DLs*$W|#d2c^lQ0VG!t!BR_oihPra<0Vr ze1G`UaKim6?Av^oD3@1nL5bEB65geD{D0|TuN!nyI-Z9)Osx3Pa=bVXY3K%18yq4WP~vR%kPztVRDUas z7}OKt%?)l}aFl?Adv1?IL}Fi1N_iOZ%f0vE6e3DOb|!xcRtIVYCaMm73P!l@WH}!? zrR%h^mxmF9#lQZ3o7mv0sGIrxJO%iTI4WCfB2(BY(vH1Hj|L#WfC{^|wM9fKI<4&5 zx||T=J`zMbv%90n+nH}D$ZBGNO@9{n%4)41YlmE$XV$jX2qyMsTS{+dx<&!S-cw0OkxAB?N&9{P@5Jiz73$~ywZd>LHkXG~%qR2-0vG!$5d<$p= z)x#2mJ@&(BXM+H3MW>x0$Yht(?7>8Gq^IeAQqD^(OOp0ZXAlvY2t$qxG=FW3*fDX< zG#-yHXJU+(Ok!8e6ilCcxw&+QiD8{UnG$j382Iqu;RLb7b2Kh$E> zIL%<<(}c`p9+U}_$<=?lX@7L8*OE*G6Q2Sjd@eV1-1tb6C=1k!&yioFx#;3u!^CJ8 zBEC4}p?a?VfHF)Bc$Ndvqt8The;{{1Wc1xU@c7SzXf!(Z`A18CF89w%WAm_#2kZ4f z01-jU5n^}ffw6H==0LO&frFzL#YE_?(Vduhvb3}`H1uR~@iFwR*dOxrcq5*MjNMlM Y0ZnEjsLZ}0=l}o!07*qoM6N<$f($a`sQ>@~ diff --git a/TMessagesProj/src/main/assets/emoji/0_1382.png b/TMessagesProj/src/main/assets/emoji/0_1382.png index 6035c56e7debfb9cb642dbba18fb082dccf51a4c..725b271689f6bc4762ca20285025a98c5b70c19e 100644 GIT binary patch delta 2017 zcmV<72Ojw24DSz+B!9V3OjJcja7=+KaKCJP@ulUIR9y0@?4?7Ff@D#ERZ`HKbB#-N zymD~VWW4W>-j`B+-?x#2MQlS8K)r%qPccGwF=0R`H`b58cN!*iFZ0-pf-H< zf78yIbi-MnpiWzrG;!g(mE*yj%3h#jH&e)PtyU*EWiV5pmz)qQ?Vmj8Sfwy!@;JK8@j%DbZ z;Hq4XE(0ImalPDSyOdQi-L#9iSAf7$pN2{*uT5~DU^dsMfbEdtnG}2EXT{oBspP<# z;=PyHs)XRUk$=>qde4_`vT{h%opj2QXs2gE^Re-~d{e}XVcW2YD)bf*&`S5=5#?8L$#{KYY-KEE{?acn{+_yLY00ovwL_t(|UZvJ& zQya+|1z-t<5g-8;vcX`IG2o10o#U>(P8*nHNCBZj|CmA1Zoaes|errTN?Bl@QlBD&fzflUBW{8G#} zPFSBp6+moP8YZAkL~JQlG)R1#x_wwhN23I4Gk*c1^)V38W@Wlz!ZeJCt!)U=)&WFg z#;syetD?u$;Ih7ss#WwnGBvuIO51H6y@P`Tmm4Pfx3*gzIZPK>Z+Es^ZeSM?thb7* z9eUb$r|~ZEGo7d1O5g@W2&| z{cU6nZ{^$0F;Yjrb1k*Fw%{=!9&Bx&W2By^^T|{)?OZY-FjR%-tjY&Iq+>|1>(jT6 zzaGc5iJ_uwT^B_kJFV)PzwCRcoJ*DS~~@qgBz;`3vFU`}su>=GQ?;bbnbv z7~F6zF503XnC~m+c)Q~?pFWS)Kfi+@rZpiv0M*W}rINO&b9TAV?Lk6sb!YdVQ>$qD zjZ!j~W|xt`vLCIJ>o!f$rZc#^bMV!C3W4rfXSn?ngKwxgd zK^*_?96*Rp!y@;B%JRi&cZAP+8A&E63kaq4vLbL9Ah0GEH1Pw5Tete!L4Qye5hn z)y#Ovy)W=NI9GV3ZN@TREq~oHn{U*O;;+4$fFmKqL?Zs0No2inE|QCcH|=?`TpqD6 zEhRb)N1+QO!%Dc zzJzsOitDuqnh*-;8T?)(L_n~_L`&4U00X`>iWw0&ir|OPGV47Qa8=-?urOjt!dp{? z@J)vSp#t7qC=X7pepyM}Uymgb;5))FN=K zoA4c<4$WkQNEWAlu7805v*>c?Xr}%k?S3SXA%>N80kMh@j`%_JBf*^5r?VlNd10z2 zAOZ>bWc`jF5h#WAeyFd3{@f}6m#2q*!nhLeRbt+ILu z5SSO35%EmM5rLx?)Cg!40vS9Rf`n-p|Hs@+C_G delta 1618 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 delta 1532 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 RIurl^002ovPDHLkV1f1XTFg0+}zIab$ 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 delta 1465 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 delta 1423 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 delta 1304 zcmV+z1?T$r2&xK@BYy!?P)t-sM{rEt-Q9R>VlXsuzQN8wEG40wogy1~xwp4BJ8bCT z)+Q!aK0}*HI4vw59TX8W4-GgbCptAecrP)BBq)zoL^?-9LPtbQKrko=2rB96;ew2x zNkc?UI4ZonyhmlI5*0Pq*3z-Bu?PzwsidIP)6hOMFXQFq5PuIKkd28H5FJxOH`CC~ zM_Y>o05B*hbk5JwF*k2XIyJAXs&R9SPHCRb%gqoEI~^iLT3BT$DN|Bwqc}f|H#~kt zFem2Y-WU``Wp$l;dVNS+jY?gVTuDEblbTUHGT-0dK1OyrL2*uEkU>m)MN@(W3?)oB zFw)V{J1QkfT7QWvBqT;ME9&a%DIFFO4LlneOD!*74GS|H7Zx)&Xh%at*xA|Q;^I$A zOEx7P$;!$b8Zcr~Ns)|;#Kgn_0TwbXF@t}8ARkjzY@23gZW$IoJUTi?PIgW}KRc{3 z#Q*>RM|4t7Qvm+`$qD`a2>$*i{t`nPH0=JgMJoQpU4O%v6fiGo*GX1klDE)Fl{wrS zfs23dXmGOO-1Sqkm(%|J=x2MH=fSP<-OG^jZ3477%K!iaKS@MERCr$H*H>2}NfZZg zx}^gmAW3ml1ZB+5I7ZZoVYfQwK+f4T`~Blq;m+B^J~h|J{lD`&_ulFX1pWu%Vyifj z12C|(xqs50W@Q5?L<#VcGoZ2i5759lg3Te*AU}V}3I{SGneq6Ugb+)xPBuN;9^1BU zJ~vi^Fd~vhj&0XG#vboNmxQKu#FV z5W<27B}jI4JPXh4>>oy5^xpNHe7h~h3X2fD`ep(*B;g6o32ZB^I+mw5V}Kt(jT0Hi7TNcOdOq|Poe7? zJZ%aBtEY83`vyv64T|F12=%jzK;j^4G^ybuLh188AQ54kO`$u%1Pdg%T|yWGgb@1{ zMt?-l*d`?yY}!HRKw_0)sTU&61BoM(7X;D>(;w!68(lZ3Dbb<3$FTKa=oZxyjEU1> zyW6ln9F`DW+H`mr5k2c0uIsk=ey2Yif`}v3{>Ji6gGLN(46gwDY~!fTEJ2EpNgG(GmY#~?1Yi{FC$fy&C|y5cq8x^dV#|_c zHB|nZTdqFgDv}UFwJbb|WNevK0s1PEifSpLP%1@;`%oeooSRr$P*p|zmE^855r3{r zVq$AC`-T1v3x%EH4$2Cn`n<3V;QM|C|Psr`uw&T63 zrp^2x;@09f1)q-ud`M_7iEqptW!w2hzo*{!N0P~aEr8#Oi@)Pf_#2I+$`Q-;=X4tY O0000ZKCfkPG9R4AFuL|JGgq z(^0~14FA_=^_lNi0000GbW%=J0Dj@fI9jC`{*=tFpjgc0M}Mh|i2wit3<@e4cE86 zLh3{|jXw4HLg9gM2yyDOmTm|eKKo}{5k7UA(>)-D&PCnsQb-qKZb__!n7hxcHdN?n z=j3VA+m=xpzhz8N%V?(-`Y=wvf=nZ7A*{4!Xg!Rx`hPhgAWuUosf+?S4Z~bDyi95u zZ6yd|Gw6$~^%hwcEu8-Dc_leWCE7y?c4iY9jXpdwmXh8uOw**)qQ*uLgr=K2ZPrKZ z@qm(TuvOlV&7=(UPBUVAMu=x8t(|5WlMcUk-2%8JwYKCT84{c;ONUfiWVg)Y%@dTz+$4Cs8Fcf*=E#UM8WPEq{m{xd_x|GbC!OcH;2iC4#p+MxgaN zj3HCCaC$uuS#s-Ru!KNo#1@PQ-yzn9fC!dEX&f?!R`o{+$)bpTVMx^-7Lp*=a(xk{ z%Lpup2+!VfNRv|47KHdJuGk!ilw%-)#Y60`I5mH-q{iV7(y{{)^1fFyBqk9q#Vh9^ zh<^%MMNHrgAI-?ARss;p#R^HXn4ZJ7WL4P z8eQVKZa}OQh6sXv;fSegf%f4UFdc5;aesSAKnu}0%m^_Q0I;=)%v?`PCY99Dv0Wg< z9KctKt3t>;5oQn?IonV5CYrbaPw^q8VxvS1TQLNOxYLo73Zx1ke6q7dGg5exGc6}d zTqqV&CP&HP7ju4od0l1*9G=O6@9&pOJZ@raEiVu;@>_KnSam& zXAOz^14N}-IbA73q%IWw@co);r^wK}Q`{XoF4!svKYDY$U8#drkqfiftYW`MNM=U| zX{Z36r(D@~00>D%PDHLkV1ik(EfoL& delta 998 zcmVAx%$szmWj(}-V#9`9 z(w=tSw~*AKdC;12*{p@urhd$lXyCb%-Ls6oeN)AUU9)gTVP4000eiQchC< zkHVWYajX{nQs3IagqPv*000A4NklSby0h{l)ix)7zw!_R6ff zJ>$4LID8~Ir>)-JOHD+y&FigOnp~1MKdP6Yz&%->aPCCRlo8GwtNRfL10H?z(9(!7 z$Sz%ob@K(`A@+@QaVLUo-$ZBsJQ=uj=At0H$G(9oQ;KlCh;?fk>9n;VTt8xI9O*<% zC&F}Q>-JL+1b=bpA}A`Jk`1~qTCO0B?e(;-)HrtL`>X=u&|5@pqzke5is*CGh)AI}qwB!s%m$N+AW`kr8^v{4xZfOeUuXTgeQ8|zwaT&ObEi_vQ9(vhawCkcp8QyUc_)H(V9OZ zFa$K>>dTz%_}LJ5Agsv<*MaZ}VHm+`5RT#SJpwWU+FAIVtrCmRh=2fyk}c=6h@H}3 zBVuxdg>}zLU>o)4a7xG7)gxL05?qW66FxZNo_`r(Fs5uJ-9^X$I}<)2oKzuYggxd? zSos}nR1COAD<@C>WCSxHM0jz8JzWYyC9~yK%yQl}Vgx1vNieuJmLRtE+YF72{n-h)f$T)0_cXZYR%n17PGRQp+J5Y>AdgN&~wz zr+)}rN5^(#L$C-HB8ZZR#2|i2SRShVQk9>Nl9&{uC=f%Y9G^jw#h0@X?PC!_(M0_C zyd!aHgaJk{C0h4;NoeHvK>$_jf>u7r5gdmhSS(MJ`Rsd!pSpZ~TZaV5cWcFN>qnFj z0sF*Z!t>iA?X+}vi*;t?}ve&hh+5i9m07*qoM6N<$f;i^fF#rGn diff --git a/TMessagesProj/src/main/assets/emoji/0_1390.png b/TMessagesProj/src/main/assets/emoji/0_1390.png index 006ba31d2a1794992b7b11d915133f51299c59c6..e5e86f18dee0d0c5b75de9732c857b4c030c7bce 100644 GIT binary patch delta 1147 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 U+_HPPK>z>%07*qoM6N<$f-kZEYybcN delta 1696 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 delta 1564 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 n3W(oR0GLELJm>wc(f#V-Nrgd9kGmQ^2nQ;x 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 N002ovPDHLkV1h6d=nMb= delta 2223 zcmV;g2vGOR5xNnOBYy(!P)t-sM{rE?<)#=IOD!;A5)(l@Lvx{G2OS(tH6SE;V4N{E zXYJd0`RnE|F+xjDU^6~-`s!x7d=))6KucbZ5f?D$%G?%FwY9Y_ zGGvgDkPQqqA|zvRadFb9tPl_`#KFP|2{5WhuJgDe*=~0?DLZ#;bO;MIczb(^F$lxJ zx}jeNv7?RLq<<#ZgJ!KezxM6oz(K~PggO7tGqh=2!Gb9tCOf>hu=~U+I!1a%S&cnO zddXsM%16ydT8BVWlVD(G(3~J29W5j$IjKlLoH{P7Tuf+XY5(Pb zcX@q~kddvfv7Iy)q+|riLDBoeDgWkq&B@2~@8*exg?~p!PMMB>6 zG-KZ=y@y&y$Vfz*{0PhpV2Jj3#| z8UOB}uW=6Kp%X|}h09FNK1q574JO7)$-{;czdOsUF1buxi@8Om{nSMc3N|-BZx9VZ zQfQXjo)rGeCdfR}S5#ZMJH8wlM8ZkM0R$TV;D21|vqfA(FK$;Y{@g;LLvQ7^F#Y0v z)SMtVIcm*B)y`GXOgb>zoLny?FaG9_(27RT5Pi`u9zjb9|FRkX8Cf|n|+S#X>G z^1R)oAeB`F`q^>Vt!~42UZP$?%X@j#o-nMKZ8kn#K^JAYd|GWVh@B^tYi@S!b~3#H z0Dl0fbW%=J01g@bJO2It3j_WJ7yLaD9Q`NP{yH4~PNC}8#)=Fb{X$*W{v~RVRMy;U zaPeg=^8459*yTz4{^P-89h+v+zB>TJQFebA8h_?Q0u{{9u>BrgB}1ky=FK~#8Nz1L+_8)*~<;6O4lh(Rbt zi&LyX(bB~VrGi(WKy|zIt-8xvSGq1;cVy!3!QI_msxE8)cETcAAT;^*oXxMC`+ws( z_uhBr<^=V>e+X1xs>y!=sEfbw^zl5p7`OqWvtM;S7?et-KA;BmsMIH9@a|pdV5cV) zjJT5bbhJ|{?QF^`E%gQ?F4J=Pc}=BE4u?~H25hBHH0H37%a`zYT#1JfSR3m)nD=PH zsw$qG=dlPZk^Si%)l~(;D!Gss0DnfH_J0~u&Eax6TySDFlgZ&rxI$S$Rc0`l;S|8( z@VU9z`&exIRnM~o!vzz(Gl#>?l?jDGhYof;@bLwjMA9X@pDW?7L!ByU&RYx;$)fi^ z_%Mja_g}Lh7&|)b4HPTl1b@C>Tyy$+Y!}xX_G)s&SY3*29m&Zpb0D}GQo;n9*Z%?7$;h-SrQ+SXuSgbUM!iJJtmR>0- zNkEb8X0eoY?foJAk)J^G*dW#rZB5K48wh~J5(ja9+Mmr$%>E7bfP^DLG~6CSh*b*! ziBvxgk1)naP}#SS~RTAo!kn+WJ?b*^f2( z%7&t5N#;$2Fm#axeHV|XIK0l{i_Hm>_}dN*N`LXgHr}I~mR^SK z;qqAP=+#U1D7#8U_iw+q@p+H`_{OkAzHRO6VCJ4gQOxh$fuE;$N#rdRHz)=Gcz05( zbAYoG9<{f!QlzSFNte_5*zN=ardUCWbqaP$LSnJ26e*x=Ql@N-gkGq>U>Y8IU;?9< zR~ExWmsZ+XAA6~>zJCD0!uFM^p~-th3KhCypk)BZw$fYJ5g0!`^EOejpgg;*tSkq| zj@CEK@JOLPjG!Z%uEZUm=_BmcEvdHmVT?)5$KNB7Rd?)T#n1h z(GXF1eTKMZv;5y=gaVlZ7dKAaAn1{0@^P~n;cQn380hyf)_-O7I5f2Pg#wc0%xNjR z1TceWg^DYyXA_}iuf0H6X%j!IQ?q3P819ZnVXR%)-4MLhe%>rk>?6-+F%XOp5hzq_ z1wsfE+vdyCHqmSjI6}pMVIuNs7$@L}5UenNN%tCTR?L~0JIsI?Xbgh6A#JD>#df;x z^hzYlxdi-HgnxjRQZ!$qkVqKCI@&M|51UxS>}?`Mxz#v_vCbw!0@0jp#Dpd4dU6+* zGZ+lw#FcP!VVBR@24UwLYjr-j(GY{7n!FN(SR7i@24QBFZ@&Jr?wqU;0hwchFiyxO zsziG*GqPNBFiE$7-vz56t!sy@qa00-(jJ=-v*yrzZ+{>8GYIO|zIJPK=<3GMbJK$T z&UbYWVT}3uhkbN9-CC<}!li-6#@bKLPYLft9zLm4IFOJP8cL$8)$}O>?-oZ=H(uPl zaoUVOwp^!R@+Dn8@o}5lgj$XCVC$-V)5!De;acE@Uur{1Sy`mDlSJyrM~+-bb~WIq x#A4(5b12E1H`~T&mn;na8(?H=YNX@Z{SB>+g&ubOH;s-rYnl zDoQITN-8BmEh#}NCQ27CHl0B} zdKw#V3J$*P z{sx0rENzsp{eQUS+-u3mD*B_^Ikx0ciN|o8(9G=3>V~6`{$i%{bpQYc9!W$&RCr#U zmsexswi1O!LhMv6R(JPq5&~fFP1WB2|BLPb(kiljoiIKRwjMMe&zu>MRO=t4bOw{j zTxhqxEpy`c`-g+nRlZA5CaiwHf7|!OZz4K<007}_zkeTm&qsU0Eil5{L_9^)G5=c< zqr;i7kLNs50cG8WwWkRfeQD1D2S4s{gf1ia&_Lojye^oK4$|S^#S%xfdkA$JnGp8y zJq6~$Jb;UXn`J!Cb~no!BBX`T)=gb{1MLs}7-dKncxx!TQJN6Chqt%hVzFlgsqcAG zhNJ=St$(d&na}`X^!reKkeCDC`}Hf9P$r%Iw-?B4lIF-~OWE&3IVg7BI3Au0O?1;} zB6H8{`*3|OUv>dCKjU@OZDPVOpnneF1SEMIPd^)6$ekvL$zpgy_^#`|!Zcj9mUKRd z4x3B^>4yVHNEwJy7{_bk$~T4xCeT7`HL}4Nzkggtcsu4tgyirjA+*qYNN#vUgb`nc z3?Y;q3+uSwA9Gid5lAvxO&K0rNY|Co(JHq`l$7gH3>0~yG(;#pl*z8|d9Hjc%5rO! zaKenRiH?co4&wtxP zv06YGhUF;oB)|}%4Fo%aJ}R4|(ogRV;=uR2;_unhWS8VgNHL~N7-N-rsM0h76!Zfh zI-jy6Fj04Q>pl|lPzWrOEi<%HBUWq&z-&T*0lRNZciASp^t3BbfzFc_|(av?mh+@BuD zOn0m2pLw2OE2McHKq+Ji`=#z|D7=|;nt$qvcMhT7CeTCtLUnit3x)1-GOUE=6RTed6HNO3Bqle;2grl1PHbbjM$Cg zcvQ}r;)xf6c1PF-LV}bgc}RmYggi)*U_#5SmDipR#{wX}>%uzhb}6UWqrV5*Ua|U+ zVwx0rK(JL{lEdkMHA>aIOn-bI5UFE(F(5btC=kV9qB-POB_4fLX=syd_IGt8a@w6FpaSa|0+46$Ju_~1X<_^#wu z(TP!2>klVvyy}?RbgkkrAq964a)iwY3}JJGET!qm$3S2!@mUWzFMqHKiDDcE&@8m? z^L218h>8uwalU@9f3%)gUBkF{SUm?of^O^sB8qI!m1Q4-guND9UursSgFkTqQ)h&j zzwj~I1;O^h6Po;*+1MvS3E_FIulh>sI5SRrxSSJLFHkPwE;&C^D-F$$5fl9S`r0tihxPK_b>|<_Ujib_GNai@pEPqQ&0+3!^Mko3lr>DlTq!MM z1{%Jbp|PGCa+ck9jel=Oxotx?tJSKvd^f45Y3o7GUT3p~*ep~H^nT;+ra*>BXVA)lOXjxQ=mM^=SALRL^rcoz~W?Y@=~7cdG6 zBK+#v9UDy{AY6%Os-r`x^yk?a7cE^vJxxPHudJy$I5|a9f@x-FCMjJC3pC>2+5!X< zWL#bN>Dkw&o5qoA4h1L{6hpvMUQ$zD85mh8EN5(jtt&5QLw{C~B`jJE4K$mXn7KQ_ z&eO|$dwbQ$zQMk^u~4Vr(ZQ)Pu-2q~2?+_(u8C@9YqK`1H$QPdOn^5(aC38WQEHze zAz6WaeN14IOh-tMj*L`7LH5n58yzj6o}J2(YP%QI7Zy1P2_UC4tKogauu7%EL%=*K zHX;)r`Om87xPO!k3^k5Hlh&SiuBM_R9vZW=vU_`bj*5y_SXh;ml%E(R?1YUqK5l7}O&}v5&XH(*dwt)xl3i6*1q1_3GCcqQ6e=qu zXkcHHla&et21;U)laY_j$;Y;Pe)R9=ytl7*S3%)}jDO6`%pDp@YHDh>JV>rIKSNT1 z+;o1_WN@e_Ghtg>Ph^tKP0z+a%u8L2yL3$0j-JYhVcONrF)uIFO4E>gTN)P{-GirQ zE`H|5qNz!Vygj=4&8Zaxgn{z=!R-i7O*Os5FR;;v^eBY#dVMsh{R)0z;Cn@pFo!PmRJSZc~Q_snZkt#1i zuTPb|bC$<^qtJ_CK{8RiT%d3;cf*2PO&nOKg=m;!O~7EHvQ&VyU4+SBu8KRWu%eM_ zZEpGlLCF9B0Gf1CPE!CG{u=%h1PlKDISBq#4gC-wCwIpC{$$k9I&J$!H(`>z(KbMN zBY%}#Hu2Y_DWGYn&{6$K;{Nqk+o|w{g{H>W=-Nw?C)kxFY_U2g>i(0>-}2~g)`s7h zti(stJ!QY#WbYP{anD`3Q6chxt^4*^x7fVzk%E!^W!LzOdEaxeiPN*jRaE4);mw@q z-s#iR{Hw9*@4?Wx{<;0(W&i*L$Vo&&RDXD0y_RKHTUi)|!zE4#Ef6T~Lvf~9ozj*v z&=x2Ks?+Io>O$Se-QBo1?(QDk-Rs`*`4w}hq!~zPa%QbLpUzrY_gU}W`+eUW-2Z?4 zgZ+vB>HF|wB_+ELu7L&+LQaY7BE4Q84a*=L)7!iCZEbD(=-t6k1Y(HYY>u7=h<`-( z5I7y*iu*=H(IPveo545$d`jUyZ}EMjfDjBnvvdarOeXV$?kfu+%5VL264Eo?6WV(lRe*UIMiV71|13+ z3wfxr_3Nqz@dPx&?{i11Ml;yJF;~GNUaf3xzN)DNseDyRB*73ie4=y!g!CQ*BU*i{~ zN`M%Wk*@_U_8Bm5EqSEvb@Z2mb^nU8-hIjt&EauSSlJ zm7LC6tkh_(s_yc2y~9DZKCY@w{g=lx>H}*3%&XLN^#Ch|gZBC8!^6HQT|FIl)_|8k zxYlkVU%2Pu#$Djcn347}Y;`qtaes8&LW2Qe>1`wA z(Q#p_55pdi&8UjYk2?&mXAKBmA-vPufBz0I&<7`TS08$EC46c?B=U~F(c3oR0)MY< zhz!kkK4_8<1D?g}IR496r*NhB{jhHNGtCPTL}C(hx!gt?FU8w1x31pdQqfWbj|w^f zp_3*|_KuKsy4dvrK!11_3Dfc(Bi@|vrHH*GS7KTi9y8Gz8v&v-f#gk=Z)D7P$E4ta z4q8I`w2%a%H(72^ngLykm!N`(3GM;wreEJh@`Y3(s3| z8E?(1v~-yS!%QhSYI+AxuEmzp=ghKx|Bl(%L8}7@9-M-D!5CW%J@IAFIi;d3mLk3C{~LO_Z5m+aX0-B)fDA zJP1jJN{+2w0_x9387ec^wJ*_~7TC2h-%&>C{}kc@OEeK!{6_y<|7x zpb|RyF4*SRMe#+ z+?^Qf)m$SrK*>#r<+m-}TdZ_DZKQl!xsWU2ajcCte1F4bnXgZo<7SEHgS^Y9K;uQI zi&b>bVPBkf74qF}CmJ|`O;?OrW%}Sa z@~G_UoPSK?)7oQa9e&q?Rx*Y{T4>X$%$J@2dkO!Y0? zyZ8KB;45l+p^nghZ{ufD-}S)>{nLwe8WuJ@#DB&HoYA+q^6j-+7b`1-v9Xa#-K1cI zTW`~Asanl9SJu|nR>;L8gX+=!WO;d^9#JW8mn-YrPy{ubUQbQeBDTx>#ZswKDMAr} z`D8MEtJYch!(S_<MS)Q9EL@`qIUEjSvl58i*@dWKkBFP4hi z#DB^<7!jU0bgjv=`Q3h3ELXl%%EiZzpdy;1ShL*Tz!~FlvGQfVT%LueGr^m#^`8@} zwPh?_EEd<3x8aDU2A0WBMm#{IxAmc$ojUxSOeTMN6agcsaco<6gB1DsHe15Jq0%If+@kn5-kblW# z?Ci1QT3Oe&4UA02wVb(D3OwFUK9^I?PkY%cqcMhVVufdQ#&z6D=y0h~E|XK(y}d%g zHg!`ovDB_$qmXr-Z+f9IB?z9C4NbERTh~l^D4u9QtnM))K!ljdAmfv*6NEu7Y>aH- z_y}8Y-9iY6khqMnyT5Dd25V}X&VTyZj1Spa%ju**h#^|!1X*AWgT=PS=qhH zXa*tLkjnA9zpX~BcOeU8TC4Wicu*MJ> zt*3|<#<3=Xprvm^gpkP)HxjLTh-#uj1;?3!B_lZMBSc9-66+xfL0?6rb8G9zX5gEn zBg%0ZPE-V%_MB7$)xVfpe$Wp-RaBAVh!d<38G3aLw@Rhb1K^=R#dt*`3{gTDk%YH} zeZ+KXEqxz|=n*`GZv|sn*MIbuQ$*$d(^;62;2oq$D%n@Ups_*v+3k;H_Qlg61#4zE z5up-9u06`ByliXQls}UB`FR+D8pDWIRN~`Fyg4dL0&DB$u+N5`jUg=XwAYF2P2NkL zSYb`GI{+{8x)3}Ogy4rL!AVGFjkYEq0B!_L#*w*xs+zh^0w%NUFn=7;At2vI^xq)I z2SpyUED0#IVhHhy$hC*h?uZip8Yk2!k9d_E4AmZ!DylkxBP4OW7MtJ{*Kl1QIVe;=JTY)N_JcKr7-SMlQHc za4L<2p=LPZg5st@RY6GT0U&yO9}O1}R7_QPkPIq85DMLJQE-Q61SBKIle!EM9^nN+ zK#Bj;(A4wt7q7Y^m;3`m7%SwPs}IsQFIQI^y}ASuiP4Ic+E~z_Wpw%OBAAY9MlTC#WkQ(A70Cb3wvC7|wX%pu7X7 P00000NkvXXu0mjf??-&7 delta 2238 zcmV;v2toJb4#^RaBYy()P)t-sM{rC}VUG|JIo73hEg>q{&4S;viK?Hz<;lxWPg^J= zLrYFzP&YE?$)~TasrT~g7#UF%6HyKgHC#fZr9-PbLUO>fo^nhd6A?uuBTykBNPT>L z4h=Tt;nw8apyl15;I@(Q=-}JSkO~ngy1Ke2C}F-F+n$}AFn>9I1qLgbmzI!_kqizs zxje$>x_*s+4azrMbeT4`u)uy|8HOn^2$ZjFbBa&dBJXlX}Si5nP5D==c22;VZ{V_sT!gIXxrA#kfq#B`eBRTRtTM3l@8&Z%H&;G4 zys2NCd_}fANdL#rt~5W*PR~zdlEy*JyP|wURe_s+K-$&KnSNKbbxXLVV3CiB#lEzW zjENv6DS1vZ)v}7FNQLCxw3d>Vid%YuPeRT_(Y>2+-K>H}NK1TMCPPnuKudeqsDR+P zj7L?31b+)7+OCE@Ms^bsJgbmOy{BSJTZ%3+V#Ytp%b9dRKvK<>YSEu?QfHPD88b3A zXe1?Az&pmkL&e2O$j45~^X$DG8b!=Y&o@4A=Dw3SIch2@Tg0+!zJ^(qb~n_XhSQ&V zzK&w5dT?!5LJ9{n$Ue@^zkJD!g8%^*w47PSet(kGu!6Hsm|9g|%Z*_tD>~-isSyk} z%Rke(JH5L{tbkTCFfd5%=C5!}M$T2y?dG+%X^Ngpb;44xuQIo)SgafxP~Fp$)yIaX zMvA2?ta?vMT5y}acT3R3jI(h^hh#coNJ3gfGe0IapDmVGI6S|8Z$%qliaV>ToQj7+ zUw_ny?s@IsOeC{sImN7dhT(a`-mvWHUDCr0x2_fe{9{r>#n*87Ox z8fB2TSK3Vb$|$p$Xq1R^_UG7ZQpjD;VSnS%vi#egk#4s2-ctT$xsK)cupo)Gk7RCr#!*Hv^>R~QB0nT%&7I&m^F z8bZ{CAOV6~LU1hy~a(1@+Yp@Y!XD2@dKz4SofCd-B>sEbzF90sL zx!>}FOYup`N{V}1Tk`Fin%k$iP$~AV#4%Y>O_5wKFFMSGt7Mf76$E-sOkX=U=)!{LYp?=@m#9e+mG!4skRbTNiu<=rK+3kzs)g)9^ULi@Uf%Z2IH*d*y5a{~jJ}F=^1{Pps4WlQy7l?YycM zH#P(U5ROPU5_mq|5XglzlCGy`X8elf(`)xJA&FTjMxr(!FWqMcNrc;{XJ+2Lg5#z0 zUV-rTOtF@nH zKEU;&|5aI$U?duF-D3MC=3hrBrQ+zhud7vAnJKk&?G^J0hg0gx2v^R$>P$eCVl6l9 zlgu5(>XxTJ`#UUAb>v=3ZxZW%H=CfXF0XttF^v1&pD7u+U8Oi>@qdkFd(7*@Pb(j* z%T_T-C-lOCKPvLYl#0`*&6)@|vhpdGuMHvD?Y@5>(G;sON}qJ5IX6N*zo>G>!WEG$ z(geMpj5haGP+Fd(jc1rq#r8#CM9z&22iOTcS;$Z8DKCDc*)_p*!OF+qWdO5_(<_iv zr+Y0A`kW8hn0yvNJbzc}GmTBwDC(a} zrnbSypFPZrA`4NaQ+vBKXQ{KbX~MYm>p7&Mz;*!@P6tG4Jjt&rr!bX2{goF8VH0CVCFMjT2$E+@vT$=MERY~ktmn7k0DClR%?CsQ z*wlDwT7g6;T>HFP@?1Hi1%`_RMUYKkA8cmaRPqr;+!{i`(|7xr6I+L%2)fGxXtqwq z7>cO`JI)OQvws}(>_dEh0jOgz zm95lUB+~c{0jzDCiHoqY*#GSTgTW9mEH~rR*1Edp56=z?`~9bd5DG2LG!Q0#0 zdT>c>{T7MpG@p46nXyMF5enRM1`xUbvmNY&NK_|k<_&+;*s)o}M40cHh-OVsYisMy zXH|rsi8qM&JkgA2kyViA**S?k9?#(!!Lai53^Mn@%w<|xF$wPKALX;|q6XHIL;wH) M07*qoM6N<$g4s_@5&!@I diff --git a/TMessagesProj/src/main/assets/emoji/0_1399.png b/TMessagesProj/src/main/assets/emoji/0_1399.png index 10da24fa3bc20036d662bdb7d2745dc8cb6ee86b..d057ede9e5c0254340d960baa7448ef3bc43a642 100644 GIT binary patch delta 1867 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 hZZGg29&4RQ{To;aw^?tzHfY`1l@)S&~5|% zwI1=H5%;GP|GWwR+*#|G5C8nX|Li~i{nG#DPtUSC|J)h>_HF<1O#jRf|NiB#0J5I| z000kkQchC<&F-2s{{0fEgk(?8x8IQ6+l2rC1wu(gK~#8NwU_65qeu`%tzZF?W}2Ln za?a8AzW;OW?SE>ZB{|N{w+CdIPt@U7HT>Y|uTh@2Kc(%>Jg^==_PLsdYEJ{Cd3(0KTBvZn|3Yr-H_sU;pY1C$qx|9A=a72+Ov=Zu~@| zXnQVjrnA#OH=GWW^A(c4rhFTr>uQYHVz4}crO5HYleHh%kk zHw19J>@IOiDyoyU1kT_DegC<6zZxxng%IE+Nb)SpE>OJ4LOOaOLSkq7zWNxVw*%qu z;$>OxU0yyR9AevnDu$dyKY-!9OYUN=7p3!zJ^~QsnRgk!f+62-!SNY85rAF~owRR;359C~F5?EA^Llv4sbyFQp_`l5qFIfiwON_E8)eKf3_~~`EDl3C;1(7^p>stw3{5EP zD2WUUjsX*fjyt(+z);4my33OJ0Ev1s57j`%p(2LnDD zF{2m{I=|Ezq zagrpsFKpsLp{S&wVL)Qp2J=V}BRK?oys?)F^297ctTyX$m4XyBPrXRtv4m1kbbmNf z)OsA;7z`Hz7zGrnRM0SV;PMnPrSL9}AsDdCE6H-*g@L9yUX+Wf%@_MBhU>ak#1$U1 z=tjez!3D8m+*%k2OD$o*C>C?AP;{1ys*_&Nb}b&mLkJ5JzFAHXID#OsdP0Fd7W483 zZ`K#%Jrr=@XC5Pn850JwK!uOXv48Q1a)aojUOr|@t?b0)G2o!fT91%}GEj*9cuosK zsB`KB4z3^x3hv7b0U(3u1JkUAF&|S5a!?SW)VR{1QyWEyB}P$oLNQ7Q;l77{DB7S9 zb@Wl96*2A{w-y`;AV3BYLM&;uCWs*%rYR(%$|V&U%Lry+KnSddL|yV$M1Kx)L~#TM zAxvouLzw}J#e6A;DPxolNFqE?kzQud7c5KAgfz$yx6_agNZbTZ7K`^07$+VMB8ngl z%W@KOQG^4_A|ySQ=dk3S_{vkA1eKw>tt6fLyvR`mi5NZHzyq;e2uee}^Yo53Vh9H% zfg|xe#(^u-y00f924PQ7Agd`=XF9qB%|H=T`b!r9@SPIP=)l@Gc%hJMqE=hN0znNiM>Xn~H4TCv zqqNmpeR)H@rnZ$of8lOxs#*i8su% delta 1550 zcmV+p2J!jX44({;B!9F}OjJcja7^`-49IQ|*MAtuX$8=C6v}Q6#D6ixdnV0#9PEq` z>5dx8Zw1zM_tN+$a|M`XG&`kgCe*fNH|NOrHzY6}b8FV}ZW-bBGt$#DSiXs2XIRENE|Kl|O z(GrA82AO3O|JpPDy(<5~HUGvglUE4;(lq|JBc^s4`l=M_f&u^j<^S_hTgM+q0000G zbW%=J0PLD|?}w-oG*;4^y4c9Kg!|%x000FFNklDl}S_A zn~}On%BuK`Ws#MyLZdoje@mP3K!&Zs%wTK8Y1X9F`Z^3 zc$f6bHWMKp95ZZ!nolDR9xX(2vD>_a5Yjnk5Ox(a;(!Oi%lTSTFlZMs?@S_@6E5PP z1<&T!;D2H%0aQ?Ft#xJw79|CRM6}?^`Tz2Ti^h8oJ(wT1ZP)I+p$1+A5Bu1)?c)Fz z5WuGg!N1N!9DQ`ym$vJ=w%b}tsiR0dEtIh_=xFfES&WSHMr#e7e%p21-GG^ANZSv) z7P>tMwAas^XXooUXrzY#FP2{L<4w~;#%_O_ck4ut`D zLmi;IdI;>3=e*v6z4@Bd!24lxc@M$_3h`>zni!k?Cx6N>xz*ML+*PXq|c zUC&?J)J#~1Q|d!hvUxnTe&{&>h9Qs3AdUM_O2JB2lXaZ$K=gyGANm7+VjhIiljeK? z(tpUNSIPnLT*>Bie!n}fLR~-lzSV66^lQLwHNK&)gYxeFc|L8PtpLJ$ulhFhkQSon z0^>a-=w5kmfp|9K?d$k{wP*w+*l4+$^gy^Lp${GeAdX*I>?RUeh8MPr zt2I?l+i0HS)exu^--#m=K3oQKqnP2MX*w~w?s(jo1~I?c`0(xf#x*(Ow_`geehvt!camz*$~Leu|s=R-8t{d4(4kP6+`X z%m9Wjco^SdT_m!R*p?@31{+R!r2>Trwm6Ca?@&PERKyE>vpmI>fZ@qtg_$HM@SRKR zSjO9Iy)TGhLn#&#G6j@(R0I=y=zk_>QH*7f;glzaB&PTU#*r`Wr@H#jd5fekXIUos4EC`5u!eu1GiTmq(A=Gz)_aim5 z$k~WJ?M!ob3Fs=J2pEOb%x`5x!#Y(NCqNc@J9rHb_jKcBq41_$`+Qw1{ZQg;}#=4%twF)T*h|hi*LyW zBdGYgV_*>WN{i)t9JmwovvdES{}0ALaoUpT^@Ny500000Ne4wvM6N<$f^xIq AdjJ3c diff --git a/TMessagesProj/src/main/assets/emoji/0_140.png b/TMessagesProj/src/main/assets/emoji/0_140.png index abd2218bdeb071ed2f8ed7314741617ab0d2eec9..a507fdb40b7e3295f3cc16b7b7592cb88d145d32 100644 GIT binary patch delta 922 zcmV;L17-Y`2e1c_B!4+jOjJcja7^E;hVRCt)R=Pc$*1JDlIp*l;H-zxkZI<)mfE6y z@yVz7*0t!kle}-}>SSyMjR3bwiTO zA7iT5-wX+f4h8-&0C{V~UFCN}0#6{sm<|xdaPFabe*zJFCT0c(kbY$_z-my&2Z5Zw zU$dtQ+qp6MoVU{u@KF(geO}i!7yLoaYhhSS;nH&vz?7@O8!996-VS8hA5ewQUYd}I zV?sKw)j@j_5`TH8rdxxkv~vm0tVpAFf?25 z6)B}C3dvTXjw5QebVlwuS*g4c4@Ews6{9Y#YFOUoI~7C$l-DeHGCcXoy`B`uc00>h z|3Wd`73um?gLUGm!7>@0gheYU#qgV|h;k$XN`Ev_)Bu;AWo7GAQPE4)L7wlq064dA z80~I-B*Y3fRH3;zt3?E+(1u})MEYiNn8vCQAW9=z99(__oLpxDk~Et}&2)`c)Np~u z+d8QRTSp{O)Yc6;6445TYH-&-4fP|rpS;g&_9`)pM$7x6;R7N+NgKu->xZ_HR&_9( zP=E1WcVBLcvpJaT{=zhE*&ZlgQ7#IRH#QR(Ve@*$w7F3IZm_D`e8_s0dfn?TnYJZd zq*Gn7hHtwQD`0E$8CN6)((YwAXHwoOS|vl)5z3)j=)~~Pe>#KPrd9Cm$4rm(^#LI` ww`|)scw!r9?)-OBMAJ~Hr}p}W-*^836VYbPNen=7WMe)m?;%F%X zUarV8mc;liyMNwOQ>;TfOBFVp!v@=Y>rWjXPz|ae1a=|)&_F6MM*(oF|K7l2FtRwR zgx%T+KHVC6Axx1G8l@D(g6&hl`P);d!Jrn7M7gr-hwyn=lB5>A_bGYz#?apWn%PsQ zlPj8H#rXcE1vHd~DlxRH9PDx5{iS^>>C$l5#UdLuAYx*KZW0iX$@gdP?srgwRJTd{jV;P_RPz zDZ#??r+c5Y zFJYGlX&MLzTSpX8yRPtL0_x=cR0l*j71^MwNPo6_C1GnXXBVK1 zqFx8{r~>34mBY|sj!QEbD@ypekv4ItL}}iq-Diu_NGq_0>rz~n{=$B|L)acH z({~GLY4H-RzZ?8DYmoW~lB}fbr&s)<(I%bcb^>dGBJ|Pf?FiFne3evK{tmXD$|n1$ zu*{@@)l{F|fwpbFBh~Y54H=Bn+a diff --git a/TMessagesProj/src/main/assets/emoji/0_1400.png b/TMessagesProj/src/main/assets/emoji/0_1400.png index 5df809ff7dfa3d7c965330b5985d0b089dc79a9f..61d56c44c153830afe8cca438694e10fde1447e4 100644 GIT binary patch delta 1741 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 diff --git a/TMessagesProj/src/main/assets/emoji/0_1401.png b/TMessagesProj/src/main/assets/emoji/0_1401.png index 640575b7f3904f043c5244bac6e2fdc9ccb8f2c9..320618853cf8cbfc28d456cac51b7e0a6d0c1168 100644 GIT binary patch delta 1846 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 delta 2041 zcmV9;KU(mwjqNkvLz zDJ)-}X9%01rre_-!^6eNju*bZ!LqNbU1D!5Fl`A4F)b}x0e=H2BO^xq&Ob3GK|n-q z2MRIesvE+;!mXsOnOzL_FoIOc;R#;duIBK3AD}R4~(OhX76-A>+C~<+47VG#13h&iu?a zOJI_s6Yd*1&|=qa@|EM|*j8k&KBYCoHC)tLVg5pI;Fo9vi{0mY|Gw{J$!# zue3x+Q9w+5L{NY|Ms>D(6%!9R;NjsoKX3&MCEeZK|IjoX8b&iWXx7)+Cn#C@$1?G? z9OdNXx_`UA5)ed7T#Ng{C9820R%w_L88hkW>K+|a|Jqvq)I$HvE#{yS~ z8p4Se?5h+20vA_PTkOSEzQDyzJu(RgH2>OA&BVFWo+QD<%wIt)GBsW=Brn>S6WQG3 z?Y}kZzf9Z0fW*A9L_|{4uUTtVFutE=uAzhE$A5IAqpZiUgUzgKvxO+hl}5(8qNbO9 zb6F?Qs6GGPX@pZIe}a{kL`Opa005SBQchC<{tX)a8T}3e2q!uG*cbjp$nq#L{z(S> z7yLQe5-I(g{O`+TkF=(0TuycR(EVRG{AxC9PNCiN<9yO`(ovj{?Za0*j2M;N(yDu5 z<$t68W&XCrd!t8mOrgrxiImIek=v+(&d<8e``{s3_DT0RxO|aUN0M!j3DD$&3+qZB3IEeuX@H5ZUHU9;oS@;p8ktwtT&2_!?^<@E2LiPRL zx;p#s6(DXy5ux7*#La8e1bb!V+I~Hl&Ht%xRW_P)K5zLSfdm=~_gVJqTiwlv=KSGG5m(e~aoCG2N@^d=Ivt0f3MjX6xM`zMZra zb3(;<4&*sWy3q%SfjOc1Mvgz6P}T$p$-vWk-E^-}`4C6?@&Y6Nb*V7hNtBNoB3w ze{#cqmFx9-^`v%WcEIqXi&fkg4R(9~!7qJcP}gwgK`S_2B`)@%;`N(1zfqAp6f`Ae zw%*)W^-pfPD*~f(rdyzhynl)8-fOjDL(ltljf2J=bQc8rY4+=f;SVdB$WE)3f^`g5 zG>W=4u?*)0>IwD_mDhi+2G|`d1(j;p&ng02 zi^WPF&(}G@pZmTSc{2M zrq2b9*DQ4Qc zb{Za!4+N8dRo#qV;8>?>K{qICrjdT2*umy9e5DwMskQ=Ov40ehM%e0E=I13l9Mxe0 z5KFfNvrtI`X?)69c`ozw-bEZnJP;P^Ko+K=A}AN{Ym~&$3=LuO7C8<*=(PX@@Cu}Zg20n^5wEn z%FVm!P)JPmdvfrAZIj6^`z|j@LL6JxK9xgyx^KyiaVYTPZL-BkSnh;O)-LOaCcmYG z27_Tb-q+km9aC%`kDa_!Mc8-Ou6CJOlp) XxwE9r*M#7`00000NkvXXu0mjffyMHY diff --git a/TMessagesProj/src/main/assets/emoji/0_1403.png b/TMessagesProj/src/main/assets/emoji/0_1403.png index d82d4044bdaa88118e063eb5b395011d68f57196..ddd2bfc09d68b33b9e4931f5dd4f671cce54bc86 100644 GIT binary patch delta 1680 zcmV;B256ciLU7d{vp z99ko0VJB@K92=2ZnPw?$Ocz)>6g@&6NgEp^gG-D;4oyA_OKLH8PZ?WSA!HRLEgBpj zTqI~m7f%-#7eNh9TO(*f4o+l1J7pB1eMN_CF?LZJU2ryhcRzw#B4>?Lm2^6PPdYI;1w}zH zDIyvcdp?FYD1RcdNQr_&jF(}a;#sOLAsHz=M{H6;<$JV*V@{1yZKzS1h%I3!8aTI* zKZ`noM=Dt)At9Y{cUu=)txdi^0000zbW%=J0RAI(2m>n;{vD@jfKL28<2#9t{^rdx z^|AiQP*3T!<8l4!nf24I!)Rm2=G=(J{mbL+u%P_=&VTH*@O$f&BozPv1m8(SK~#8N zm6r!s>PQsF2`%(4MZn(ctG=>3GwD6_Vt-|KzyDX*I{|&79=%=<9%g`F{PtGibG_N zrd_}N0Dn;iL@#))#Bn0BAA4Ot@?ayC7!10>Ujm1KpG+4Jp;XVGSr=5`EYj;uvkU7h z|H{AExau}VBqG@yT>SlD{keB>apA*jfL0OvdUkns@MnEE03W(t`1cWuh=2P<-P73p z8j?InKt}wdYz!$vtTNlBwFk^2zdIdtyX6qt)_-M-x+nL@gUsha7oU$nM!2Bqxzix} zV(s7)rQdFEr@h`rUW}m`CFZ%ge5`hGa+;&=&15pU?M<&IXQwCWFt$tTnm#^0&5g%n zN^>{E$*?yVUS3{~-SKe-rzE<{tV%BD(n^2ij=ldTx6|R|?DFy~SCMx_oQ$?9Se|DY zf`38BR)>A@FNTI~{JNpc+>3^gGE9d#L{co*>U4e$H-@e|ro^xuy>fyKM|??9lxn%5 z1A)0;hAy~O(F{$Xx!m!Ih+~x2i_y?lU+t*Y=*FeALOsh8980IJdwdWLVQp9LbR_Hg z-%&-kb<48^B5NK%=%+A}5ZzPMj;US!?0@$?0N9pbE)izw73v<>aENdL5VD~ewrv@f z2Z){Gdco1`3Z?In0Vzmo$1$!w&-M%pI9db7N$D@GPien}RADMAGk$U}G(dP-Cg}bh zuj10(C&O%ohI=w4>V&UiF8%3u%~jhTu`903rr1&IFctWRs(;K?q=k4-}$iqug6!6d`h zEBz0%RL0(eCm#@Ljb^qrqN-4!rfI5zt%HpDWZxQ5_d_1zNo&&qLPrH}OcEgG71iof zce@?JSbh%>Do4nsp>sxUHswDJhksv@XPelrs(_G)LjoD|f=V84Y#b&-I1BGclEP&$ zF2ioj$oszUAH|W)+K`DU!Td2D!GQ|joONi#?+&oXW5(eK?u*F;&F;^ND;61iTuF(z zaIQIAgbF4RX5FWx+-w%3xM1!v+2pb4EL9Z=CYEh)=L1I~5gZ}5B{(ENRDX-fDuhGx zJS!crkqM2p1O}1dgd`v8;EG{c4fMep^!l8z8dSi#V#k~P0zsUgPuvwl zOXCq~<^&?Zi>l`$c}6( zrH9y(LLi`x7#_hH3zrnDAb&#>^4NqFWH9o;k9lGpVGAiExkP|KT8}mrg|N*U5>X&v z<{~0ig0@G?2-gXLx+pG!i-3@sfRYib)dLmzN877>2(m4diuQ8|*bWeDH59_+i27qh zw91phGN=~e2)X{m>-Cuo5sM)8Co`7M4cT!pGS&k`A^9ZEs{vvS(SK|u@+<=6fg@mu zW^2e`&mrPJg#Tz=*;T?9T{p!p&qn<|&fk^O9Fznpz0&K$5(7GDX)%NJ;tv&qL_ a`5%PG7%F9-$X@^e00{s|MNUMnLSTZYk@Ro? delta 1949 zcmV;O2V(f24XO{2BYy%*Ws?FXFw1C?G6PPhBuK zbIr!ZoSK^X=FjZp+Yk>a_Ry_;e0-3QkPZ+sG&pF}*3&;ZIXW~n#8+bS%cwa$VMJV{ z3kftgGc-6fHr%3u!N0u`5GM2O<*uov(Y&+hUl? zLspPYVUohX!(u-%iFSVs3^>ln#OT7E!M?fJ*Vvt#qt49C%CD6j99`tv(0qG<;;DhP zmVd#DX7kUlHa%`$TvKv!axN+>6A(Z}R);n|ajmVdC@EYgC}Bc0GbAKhy}iA^z`)DO z&fm0(5)wEZ9)BTrbdwJb9?HhS%FNCW2?r(|2~TF1i-?P}u&kYwjrh*05)VF%gM>_F zoU=GYo*paggpDpTWIs)O>Ajh8adFDb&BAd_6~ZPGFBjP=MUr-0sGq4hl8-)Uo8`?!ovav9TE;h($LWK%coXpn0;79*`Rsp>FVpuuLce#92!Ob+qXeL zQY9u@$$!4K*S)9d!JyBQYu2xkFDqBg#=sjE6|swJTSYWxQAd1VN~NW)`Np5Fpq7kj zR!Bu<M?F8mvZb@CqIFYM+Q+gnEiRa1O`&Q@cwnJ17yjbUPJcHT>aF}o*RnLiHB9;@u<%;l>Sa*`TqW5sOd#~=c32NlGvYh$nxj9g7!-$jdA?^hLd5=h2Ou#d!0;W zX62BSeV+DTk6lv+&B1ujkO|>Fx08{=F)VTmS$Bg-Jv~RCr#!lx0&K zOMe)JXLV+Q6<{F*4PjA9a0wbh2oOO+AV}@Z#P}H~^GThr(7MJ`nw8Q}vl}3{;%B35bqP{Hs0# z&P9DR5V-HrX(%gL@=LD(A_2|`_S5oWmw#HVo(Gf!Ap)h=nW<&9x@%!!e*Pj{6@sJ% zM&VMsR$231?FgKb${B@Woi$pmeu%*l(3_(QhhvptEvhdfkcfjtjDulV|EM<+C=4S1 z2bN^2%02D+qXYVx+;p&}r>mINRxUIm^v64Q9vPUSS{{O;2(*%lKG^A!P~-~~^?$Qj zs~l_z`GPtsbhLJGu(K2zf$~adopMlVZUkpYAE{cq9#mmI6a{NTSf(`Vb+moXQUQ%< z(JDLFCWjnzx1sw{LTl}7ic!gnGU(wtr=xW%Ljchtf<>Iw(dLy&fPl_Z1`xFVtwJ&c zjcA?lAl`WpJUGI^qB(%DypuSl&VPl%5iU*5nQ5)%t%8|^LsS%%&)Cgctz|-Cm^>>B z9+3Y;vbIzWil8kY6ov_XVbBCot)aRyIYqmPaIhxyM}q{QvRc+sT6kWG2caJ_%vb;- z*dX1D&mu|-X{A!Bn~<=|E&8Xy5qOu}uBEW2!k!hqS!sU(((JTc2r`F-^?#X}J`vJQ zYBn~?M;XIf<)5X&5Ck>4YBJx1b=IGx1CG>b93m!AmSKour1%nRUA#jom#KM3Ti3?cQyTH8@F1YFn?Gc5#~G z0wxsphGX6%8v8w|Ayl?Ee}6BHj5ni!PSnw`6WgA1Ns=;hSe}`8O_m9xT+v4UOvK69nbwN;c!a$PJg%9DT>0SC(&g2 z$gGro<9rak^a@QsPT`a>8;Oj!%}NQXA%EW(8Xwf{=4P=eijwvtNQZ44AT+uAn@HaS z+)v;Xr2N4zlX7PgnU92}?cyRqOXwv8JJ4SChij0-Pp^>SC5I7Kvh z=-6dX8Kj>wc#T(L_kU)8OtaZ@1c`D$8sycz2(l~T{wDVr8^>{}XG?gkfHZbDR&YJ$ zwBL1>O#nm_*Zb#5V1**PccvlwI_4|HubKhD>jU}N6@t7Gxg&<}uI2eBgq)%XLbd6` z8^^d&#ee8)8Ek-&urg7#U{ShI#%YhPOk4`f`1#?)AxYSH^pc9TV`H!Q!^8actsxO7Ck|Vm9ZKD1o~X?9OAscQhP@JRB{6IT zHKc_41c7CEn(235E7M+&y#hLocvbpKTH5c$Jl`yV_FF%PQ!C1fdwWx4zMl>Y5%d$r jXE&)RDoTXzeHP(A=}>~B8(DLP00000NkvXXu0mjfGxx51 diff --git a/TMessagesProj/src/main/assets/emoji/0_1404.png b/TMessagesProj/src/main/assets/emoji/0_1404.png index a07826adab1fca28dc10047316de1439ecee9318..1d55ce63424cff1535ceb142bac6915038212565 100644 GIT binary patch delta 2817 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 delta 1964 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 pMY zX=ZDfP-Bv4K_n$4SZ_=%%E-;WsIBSb;{WvIL_|^@AzNQkNRBlv4h=O73^WT2DzAH4 zZcHz>k8`oEt1~xSDJ)-@mzR8ee2|cknTL$g($oqIG!YjtQhzE9xU;%DArZm4v(eAW zk%@;E6hk&XbrTRlYe+4yu&^sHXDuySOkt6QfPC-knfncGTmD7B1*Vot7($2=n z%!i1Mrlg_Jhk3N7oS>ea(bCnbbys?KgtmcTlZ=h;m7QZ_V;vevwme9^Qe3}ERUsfy zm3miVIUN7|_c|8>dwF&qA6idkmqJ8PU0rD!8BJt7AAdtne%;;OvwmK?h-28;*{yX~ zKuml&KyW@rb!b8*;o;#lIcY93W4ME08W%(b4JJ%oj1LPp<>cfhCt09?Zbean($mx< zAy2oLfw;A^qi<7~XG@G+Lu^MXSwuTYG%r|enMNQ5#mC421R5(YLcFAxepNuGl!#SR zTzX6{Dt{m?>gwulPBC6J7RA20oSdj;OE?gc7-s+g0DW{)PE!E>{bB?C8X67<{ty1D zQYR-n5efW0KSyuuJBI80$T8a2r_38!(Ej>sjj3?_ysw3Ig)&Lk_%B53}xv`22)q z%+Sczx6l6magDox000C{NklFgSBF^ch6tl-jV{5-iU>lKA4hKm_SJqk)*hcO; z00I!85hylKQe-S1w-{SdSR0j&=yoDTl7E#V=uK1HC~ECtNPV05leWG5#a7TdQ}QW{ z#%F}pd+-QD;MGnO)`NqGN?-_*Abvmuy$4>p7v4mZHOK=lh++7NKKIfQnvOh+G(iV4 zWA(0g_(>+R081!+Kv;tv4yj}7IjoD4^E5$!AOYf088jkD&=Ei72oIM+B1Qp%0DlN7 z3>``3dw}3|P?R1PaqjMWnjqG9D2INy1dect%pl0{c__qveb~QF5LSR-!aOC^(Ydqh z2TMk*hbd-@cY!lO_LTI`&EB&D1TRcRBfKWA7Diu1lXLZonST&^#?Rxma2{kVrD_;e z(q1pvGb*~X&K1#kDV|E!wP3G5@PFuoV0simUOOj3*{kipqW(b{G9VY4cl}b5@pruB zln5$FrbuZ_gUEhgU1j^@QIbh{ev@$^NN$fL=U>bVFyxMW)y=As+f01K*N1ZG;^s)J zpj@B;#lWguX!3>P+m_A#Vh-nRTSN9~+4QPAU|UYc6RA+Gs9?f{>Uv4GsDF`zY1;Yw zsePxftKdO4Ee&Fa)n&OmU#qngO z-2tZI)jE$eWWRdnqlBUA`hSz%N^S*k*4B;8dYnF+dHjoy5L)W4oN`(-9>8&v7OBuV z`)y{tOLlgaUu#Zd)mL#Gw_QY#ZVzw~5MDm3i6`}n9P3(aW^vpORzuXhY&YTV>Bju8 zbluIIiS^+u&i1EgtmOk6LicC+vTOla=8~ifAk4LCx}+1>VBKHkwtpe+ozUcFi^c)M z)SWKCL_=U2@|-r56ClgnDmDRxEwlGpr!Q^ebg<}~?e;8aDX%8piasdz3$8RYz4VE9#zVvc&SG5Urh#38K zaj}ETSBZFNtbL)ay84Oo=%=xJ+WDrb+4Q2oU002ovPDHLk FV1n}(YR~`x diff --git a/TMessagesProj/src/main/assets/emoji/0_1406.png b/TMessagesProj/src/main/assets/emoji/0_1406.png index 9636651f0e70384944a04cd796936dd6b11aaa92..4ff0a480fe4cd849a6a48f0a3b0aa0325229aa44 100644 GIT binary patch delta 2359 zcmV-73CQ-{4Z;$TB!6^JOjJcja7^*LILwa~E-x*WRs=CJFf%hST`~}jPz)j@COg*P0ewNGHsc9ISB=FE1@G zE-92%1kREdt85CCS_?5QDY0`4uy6{$f)O`0EZU$SFEB2(dw&tSd<~FO1oOWs$&DD) znit5E88R|3_r@=}fD*%p63&wt=&>irj1{YM6!XI|%aIs;MhWJs9Hwar^T0BJQ4N7* zB5_O_{LDAnpBl}O7UZlU^}#DiM?Ln$Ih9=whgJ}UM*><)EdJ9pi%kP~WGwl~GB`Lk zH8nCoLO}n_D1W_v4e_-d$%+u^upq*P5a+8J{>CKarWgOwGylyl?6)WMxgg-B8~evD zFflMXJ2=sk6ZyR#NIxw3!Y2RLHrt*QIXpo#Haeep8dpv>Y*itzizYlhJKC}}*Qg~Z zDk_biY;n{q!XWxZnOatC%tVW8*Jli6!BOrgzx$JpLH{`}^sp_Irp+%l*h<(qKXQ z{JH-1objgpXQY;W;`Y+q%dOM9DgXcnE=fc|RCr!>mxogtO&Ety+5tuoB#4D#uVAl< zE!NcQy?-CQ*-Mh|pa1rd6S8vej57|;-t+$6+tnSAcA;}Y#IC^^6#2ITGqE>1H-Yr7 zfY)a`#(mxZM8|ROxa}Vra8#J>2hjoSy<+8N0DWEO!<`hU8#4!y{=UBc*bwf0H;B(1 zinZtjW{e>YHD}b0W?e4V@OBMe)Jj&niUYd;vwvnxAdZvNiiu*em`K!&&^sFRz0zi* zHZf6FL!qpDlrW;>fb$JBFSj(4$x?)0n{hXiGr%-8IEC?$U+}9 zhkuJ>1-im;9Fu1v;eH1NL-SgRBn6%?Fp+l(M%8$MBuhN2QVt5_ONHhtDp*uuSTVf} z55lvY)j-WMYJSvVklBj<=kS&!cOIU0`02iPik*kU9gXo>| zyV%I8f-LCAVBmrn{|JvM7D!S!*1?iOWdrG5{j;E0EeY%t$vuJX)6R=%eyq2eR{g1>9`+ptbgS= zEs)k2TfOMWuxe3y7x*2^A57;pF`NF-lLq$Ec~Q)7XPgBiXWPDHG8s)Kza4E%!8CRD zGXY>UdEmWFE%y}kZSIu++)xY!ig*%MH~s(WkIN55hNCE^UVYK`Q|LPZda)|$@=NWy z!1DBU?V6P2_(Fd^`+WaB1!VO`cl#*@^s6N z@Jo^by{){3@5U^w*>46G0H?4e&!nqwA_9>9c;|UzL`!>90Q`hkpc7JwGRi z2B7(pBrSCv^DSLpzg$GVCYx2FRn>#!*S$0^mnGoXEH5ow#gLX@)7Paow z)M{B>$RMG-q--IBpn*+Wck0G>iJgB_AfYT+g?c-EfWq1dnhJqqKdP1Yr-F9Iw&LPg z61)Er(AFw9ZjJk@@FN$iawQT%0rhMvQheNJQCrc!`CZR<8>~)jIe+f$Eb@+=Nh*`x zd!?EAC3&q|@%fj;Qa=_g*6mPA3B!(RoLdntGd9gk>o0hRe*0d^N3T2xRGu*1FkbtZ zxKU)eAA4wrE)L&ycEot5BS)wmGjiIo@ zv=l3rg1{!66jmS1>&1Y{boW-ceI^0ujPoEjH#PU1QL9$XZ-0JRQM2gS0D#p_MyP^C z(7$mM`__1VxL%lo=!|L6nP8&%{J@3%4p-61?X5zG{qaJnz%%fTws8ljIO#trlvIA& z;cR72Wr?K2NQzf!p7{jP6f4VuIEj3rRa#ugI9$rZC0Src5zjCU6q69$I@RS;C4_99 zsI*4e8R6Ppl7CC$C}=3EJTnSs1Px00PY4QPXjI5SG0EzMJb->zfo8TpLRV&3(baX( zeetBgQ)>>2PkEYUEdPeaGYcbdgNn*8WGojiQuE6W?{i(#vX&yVkmtBHXzxRLP0M|- zIx!5zP4-qyO=~P`J&BHT90kAi4~)j1SPeXBhI5MH4}Xh_GVcdqF~U(4)M#p*SNOG7 z9tu#0Jz3Kf<@MA|QWOvs5rjS-xj+%zfcnD+!igw8D-U^S4 zWr3n)qqqeq>tdE=cVClTQk>HnUjvF)gpM-s8TY$rwmqC@o>_Nz87Z2!?Nifvcw4`y zZ20XWXMdcw^|bJIS%)f>tA8CSm9>vOIw_v)IeaG(-ewHUv(2%8XrEfJcj@E!`dx9N zhaoWW^ZGDmgTbP)GS`(OHurRW^Z9^D+|1d}kGXvS`raA@ z+&2V#=M54BZY>(`NWBE%4YZrKsNoKDeFG{{g+>3Y`*xwVMC{002ovPDHLkV1j;(cclOT delta 1741 zcmV;;1~U1=65S1uB!AaXOjJcja7Ha~F`4?k5$K$1l-nNBvPmypJyu8dVOk6AP}H#$#ems2ko zXgwi}Rx?IfjeksKoY-u4IVT)uLnLu=aW_D8gMEC^($oY67TvP9U|?p4h>q0K&dtrx zyuH4AcZ7XXIgM2^LQ{z)B~;;qjJ7;Tt~5VANqXsYemW=~S1}YqL{N`~gOFDu!K~gF# zU=s`oA|Fe#udIY=TP7STp_!FfQA?Mbv?qG@(f|Mea&%HoQvm+`8U7mm4E_WDCjR68 z7Dzo21%EwO{yPZBraY?G*UBcZ>{I;vYn5z^EBrce&-wiP(W-fFlTabn*Vyi;-DLe^ zg_PsPky|sfW|4vRlTXviMslCYhd z000C-Nklbg9C9N8Pmtvqo4^&}-g;)plhfzs~`YA}ni^J&Q zmGoM;DfH1RMlcwB356gWzXq>Wfxt0-^W!*fFyJ^qzy+#)k`(*~gCXw1@fVOgVG2(( zet(0XWetXP1WqQWlM(!EAbIkZfJCeW0*p=&Sp1{~fz;wt1|X9D6LnMjb6!>|PP9DmQXaopKu+YB^fljl?2VI6z<29{vyBzbO| znPwX1U|kH4b0l}En`U-4%OPD1kEclPEF55*-&r7Cw6*~ko^uHSyW~#*g7j=NOn4F! zVR|Yd4!Q%n@MJ9{LFbVW4FSP94ux2B?t~9WfY@Q!o$+@tH(z}8R{Q+ZEaasRGz zNXC0RVK2$psYcyYr1a3`$GtU*f(ga8Dr1IbMp3tTthvB1PQ85v2U$PTcym6Vx!qK# zG!~2PpL+WXBv=OR<{O@M%Z<^>{a8!`5S4`yYL~0D*{87DO{u(^e-WdFMSoF0vT&<= zGlqdVG#UvpPZZMSo3X~*$bJl?Bd3l!3Gsuqpf0s{pj#M4E9WcgK$=R`P+?u(-aq17 zilQTZh$FV|ji?^A{s*CBtTD%__7O!*{i2(YOw8sLJ$ zo;}p14Ro0!b%{t*loB8mqkpAJ73Hor=8s|I)x92@C>q2mtyHtd8xk@1H~G2*G2BZg z`T#<#F-kw@OOI8wyL$NkE(c#{V#rOCrb2xZ4J7J~h!}dWjdpugzRev9(KIckDXDq? zI0S6u7OQ^TJCJwl`bC-+Gp~fz0Y;(FHTB&tf9y3OdDR3=gqkuy(0@uqbYqowVtD>j zZkO4+DT<&{piCSgW%}){vEM!a`JsI?*QivX?ANYYllJW$&1F^gOYdS{fTHZf?E7>& zU6yLz{6zm4Rf}uG5;a@J?*WjBYyzlP)t-sM{rCB2L}KE000007#SD@1OzZKFkn+Q5D*YLFCQx_ zD+2=qc1IgxVqyRQ05~@{Lq9uxW-)wxeEM2?_kHAG>=R;^X8zJUl=?JyKCo@PDBm@17fdYEC63B)_MF zo}QlhwK9~Hl>gCG*~XY*VPNi<7%eR=CM6~{Ha0OaF)1l2IyyUCTwDtX2qGdPMMXv# z5)W%@YyG@09UB@Q9wGYr`8+ES+lv^RjeXamELS%c|I9q5WEPjl8SnrA05o(`PE!CL z^>jtuF9Q(??0>fWBQ}V4{`p*CknjB1`5gZKtNmKTrTzW-!k&?4nm5b+c+^a<+2p_e zz!f9_00O^BL_t(|UhUM^mZL@xfMGNO8YF~-a@HvC%+3be9Rr}8-v5EzNWQlzZvAuJ z-)XAPDeFJ>f9SKZnQUh@xZwXtV@ic={s0rdQoc87+J77Zg|?%VO3bHJ)ddOl?EJGN zQH~7|?5;|d%iwf6CBZ|f?|y!wLy};3zu$NF>v?fI2*9swr9SndXf%qVC^%6GAl&E{ z)20j_R5ax+c=xUReLMGr?49osmGV6Jv;Ykkk6!RFqX?p4@Y90ie=N?+nI5&a3z9yLT zE@L)MsU`=u&A;^4#1OP8_f5$O*R)~fZbCH6rhgHq6dOX!085J-f-%{Qu^|XxU!XS5 z2-=g3VnRs223UL*Ltr5VrJNAH_VN?8j9@~%2sT0a3BOMmX4D{*b3(TkfS5c9BV>eV zSb*w=z?4zSIM;LrA=(FS2ovM@P;nu|@Jl9!5R{Sql;*TQL>4TskMUkU6trZ*SeMQ|;Kfhl&i*aWdc^ zqm};}$a7nrs`IMaX}KPPOf$4w<*b$+mW%*@(<~o>gqMT<{qWyxB6r?r98diK015yA LNkvXXu0mjfLzUhG delta 1668 zcmV-~27CFX2$T(wBYy#{P)t-sM{rC>R)qEJ>Mk*1u%o0lL0S|RH8UnKJVbLQBSO8q zyG~({8yQSIC^8=y6z%5UC?zOCFD2mK+wbe%!o$NMAY5)zMm8`ojgX!b4VvUN5Cx0tu5Dh#^Mn)137oD7( z3=A|YGhs|aK3G6C2?;OC%gi+kU}j8VkXb`FjEI0jQ;D`b zNUk(L+;o1ZCo@=bq;zqHOE)h*Eha!qdqYou;Naj;J2Ol-E;lG3+}zwoGb=418Q0g> zAs|l=3pOYyS>)v81`H)PJ#I5MXkk)I7ZgG^F)>S9ihn{rK6Ptm>+9=QX_#wXTClFH z0RtIVMm>pude6_$Ra9XnDL;F3axgMSPD)BfLqil46PK8zyTixT0001IbW%=J0R0*L z0|)*N{u%xL{v-ZA{z?-G{!}q)Dylm>{bHmh#{SzwW~R@{gV3#u*X%cseQf?(`jKzm zbU??G&wt(Q71#IHzF4Tw{@sOgp;wCBvd-yYy7%|rcI33&&yn(qw6KY@Rha3f!NU^@ z000CpNklc$Wa$(~HYUow5yjTR^|2t?j)w@DzG9>CBD$7r0B z>=FPry8}Zj$LJ_4N+Jus?2?GY0L!wRC<5D;9t^QYz7f3b3p$}&sOYy4;X#7B+s&ZEjG84%h3T|6hTvBYObtVEPzFE z(L-Xdb2&481Cl^$3T+Xk3)Kw^+aAY=6=ENAa3i4vFWIiNFG?3QD;*<+cBXSFI%cs; zwx-aGv1Fmj-#`|$ezQ46X%i7!Q-2`TRw_U&_ipI!xe0TMjs}9kU?LFeEKzX2>S!tQ zw#+zeA{f*s0)ffWgvNt+)*^6jIz_`UVG{{US7}i!_YRQ7Vn2@4QArr7LNc?g!`=PE*>hNk{~=hS#Oc^5JgDmo!bq+Awd>5`T&rUe^4F zP(R=Ls8cH>=vXIK+n0a@{j=`*S$=4F%uX5<0-o!hphDo!ZKcuQV0|nQFDQzpwU97& zS+oW^H9e;uL+{3u6YHcY7-v7!h7zGDg{LOeW(i|>3LwZfNEl`momASOQaew#p}9ZO zkJE%iv`yh)q5+tO`N=lwI)55ePA)MSg@lqOR@h2v=kZ{P&GtdnQFR(9iYnX^Ii~Ix*gRcyzgT zb9Hs)DG)X9kB)pR#R5hU#B|ioe-kSNy1oz{)G4+Np7>EczSiGa6k_GPtt< O00001ljw#5xNMFBYyzuP)t-sM{rC>Lp}us1p@;E7#S7-002HcJs=<#5f2gb&Vm2{ z00II61_lK@JUmoVPeejOKtVw8$fRRqV*mgEHZ?RfF)uGKF#rGn?7x@}4i4hRtf;7{ z%dL(I3JOC*LjV8(u$Y7Z007j~(`{{S=em_7Bqc5_E>~Ar<$uVjiHV86t(`6|F14YJ zql$K+@nw}EiE!JF*Y_gC@3f;B_%vOJR%_>4hjhz8yj6-UV2|gMn*>C zw2v1P5^88>1q21yqkX-MUUqeISwAoM&#U?Q`7$3BonS(ShKJ(gLU@Y@XH3{b}{zqwMdy)<^y5 z4fyt_-kB}iE4csw0?kQ8K~#9!?bOG1n?MwRVOnSsAgnG~a_=R{RC-aDY`_2OWRShd zBIkt5BAfgV@Nr?7EB)^;Gafu$*PRo%@O)aNgz)(46n{)S6m%CwQ9!OHK*3SM&&seZ zg9IGn_{7O;8!DV_pGadEihZ!0&T z0jfWR*$)_E?qQ0jDX$MX?mO!A6Y>+Qh@J)~%>I$k4LD)+sW=hhNe!CiWtlUl3DJpN zJ-#|=AXpFE%d73BAmDl1_jG&NX+r34Q-8jlwwe$ZoQK7&+CVVWG7odbl$sbbWvq0i zMwzx@8`3|_Ff`4q(lo;W0h(#6YO6|>ZBsJ{GnQ}I6 z*+%^#TH~`XK^X0e`ePWTIvlspl&Z7#Y^a(B=xery7u|06V%Sn`Apnk4C|_xS^B=Gz g%d(!W-;(~+F9v9NZ_F)kuK)l507*qoM6N<$f}JAY^8f$< delta 2223 zcmV;g2vGOB2)YrFBYy(QP)t-sM{rC*OLt3MjSm(%-5xaO<>l3(Vr5;QOgCH8;@9)S zHPzJ5c0m{w6gKMU;g5`rk_#v(DL$8%m+9&0XK8O27ecKKG&VkwSz3F%xwO?HIr`E% z(#^&H)kX{mI#^azIzxCB6FA;mR6|veI!KPOv9TW?RTU9MGB#QUH+<$5J&{^p*TWvT5sUR?)V+XL3LpnuxpkEA}Z6W!?CQN0gL{x^v!NR^y zSk2AP?1YUS8%ozAIkqxJadB}mF=QVjW7jA;<$GqS9y`WLFI8!kuoy7*$Uy(wW1lE0 zNoSk^2Ok0g3dDyG+IKdzu&lj?7W>aH^~OB-yCV0*C4bSQJ2pRpV`F1IOo&x4G2C>1 zwq0hfQH86+fE{>&`%xg7xk z4N6&vSbuGr(Uuqg)IayXA;NPQ)ZO8gBaK-Jr55(|K4ZWF+#Zp z9|H#*$%_;!EL$HOQBPu#8W~Ie-9H%@Lf$b#JtQvp$uQ}kE3Z>ZsRVj=`E!1Hq_q#QkTn1lONe2Th*{Lb)+M7o!QHxFkUIZzy zOheGXcd(^|Ttg!=w6J9W005J8QchC<7ybqQ4F~}Y1T`ZgXEVb7Bh?mV+&?x+r2P|l z9DndO&pYj&SGU|My(V)#Posl@r3 zyt?4OGyT=x`R!9>CphY8)K_Kkp|q6ONam4>8>s#F^Zk+J@}vH{>#dl6()f|ju6MJ| z&BoLCqqMx2<>&p;&v)HWrXEuO00j(5M1Mh4cwVKI{UD#^c&!1WLfp3T$cmyC>zoQr@%Y=3WU z)DGn3mw?LO2`6RQH_h5tN`)d1)LADuGn`^-M-4Km5?3e`a7rjnxud#@<_d#WitE!M zyU0DOYt*(hS5(MkQILpzzv)_WsZ43mE;;~3KyKve6u43;Eqva587>h@M2w|RksPJLBX%8Ui$rY6nP6xFBc9C`)r%y(nG9IO`Y+i=QGKaz z@1FJ0I(*qiNqv#=%w}jqgMkiX@8kCN^K)Sl@s6URGDB@Aes?MCjKAk7Dt|RTt3%S( zs8~jF2-RrB*gmaPCTl4Ez@E#WnAM%T=;s_d$@8A3fHySwLOM{`A%B=>JAryEYh6xu zHVedZnn0MU1`RF!{1n>}9zJOs%&=3T_cYZ!K~`bQ9}WDJHMSBmHg0toqj`U&(U4I= zL;voEI{y1MA{d9lk|^WjwH)YBbFt!=J;eawVADuaKFSFN1=V7qp!j8RT@8Pw zP3MB?y2Qt}9et#Yh6=Fx+C?UmFl_suO zyu!MOt02p%wSvn-xtz+C6w<=^HFAJZTa}XGevCey!5^Za36p#si9`umCC9itH92&; zR1gNRVfvL1B$~kZ;7ouvsxTo6GQNOJvzKvWSx&VAMTH!J7oiaessWMk)YW9~DTKwY zORP)`umT`Vm4C!)5N!Z6KpO?88I$(%@WD?g)@E%r7w90YAc_)HCE##TvN&;4mM0Ec z{XiiOfn2VTgH<`dP8(SZ3>ES?$(J@v*vn6kvIu}RE4ZKu!I6b#b3w?Bo zbaReXsgfUV^B7Z_>i(Hk8{97T^xPq;yu4iHY$iBgOfFZIcll7qRV0ObT6JM@S4R)= zI6=5%wt^7^fF0o$1cbi8`X%)6-xih@*)VH-qWo!X(*SR4R>bF^d*2{SP9&1Q0iWi1h#f002ovPDHLkV1g}D5c&WB diff --git a/TMessagesProj/src/main/assets/emoji/0_1409.png b/TMessagesProj/src/main/assets/emoji/0_1409.png index 7a28844a9673f3ab4254cc7a15917691cb3b5a75..faffadf867396b6073e2c87a0b3eeba5a3671f7c 100644 GIT binary patch delta 1010 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 P00000NkvXXu0mjfxF(|K diff --git a/TMessagesProj/src/main/assets/emoji/0_141.png b/TMessagesProj/src/main/assets/emoji/0_141.png index b9225fdfbc46cb05b51f0cd9a72c78ff0901ee86..5c2ea5a9b6bc1ca82c3caa07122f4df2023125aa 100644 GIT binary patch delta 999 zcmVAx%$szmWj(}-V#9`9 z(w=tSw~*Pah18*W;JK65rhd$lXx+1n(3*0-eN)AUU9)gT5QAIhX_^+&H0w`6sfJKj zNeGB&EgZ68)Bh%vEUF9!wBSt>7C~LhSUJ9V)>^4mZGRVn4;G*$Tz9hd#~#9MyAs|A zo^(mhHYda6p~&Nv0KtoXp?!14X+vLoBl7k_Fh~gS*F-Qab#rR#^!_dHf<##ubw5od z5%vBk11S-pEhtCpZAfD&=k%H2ZHf+A7CdK6Vq3U4s+z|KasSi4Cr1haEsJfM;y#=$ zUCrkp7=Q76?t3I9QH(oXd5&jG)kgv&T-={K4bOxqEDq~zh`tHJGJ>mN+2TbE$6~Gd z77=0;hlBrBXE)wA#2g4`Gs1KrJRvM2SPjB39KT0kMqpbDpS@LVagT@rkzD~|EfH|1 z^w)?)9btvKXA#&XeQ!?5ICu51mVgA8(n5s0T7Q^#Mo`k^Ez(nTeBOz0hcFU_gc0|Y zGhyXdboqh!YOU-%dCLf9U`+U{Biz%aAe7+=%P?8arV%3o5kQPV_tmwtt>@nRZki1i z{2>9zHJ7k>>zFN{k#)Z)!zJ$!fK)Kd5QNCK*0RkRpk+9CZZ~2`Y(;1};G!$m5=m(2 zmVf3HF)}=FM=nMeutEe;96=1=e=*BTwGUN!{veJa8zq5Qu;uuS;w-+*l3QO35vnHO z>GO^xu92IqV2ZWKQf2ew*FgYP>k^!Nku5k510_>tl=|#@hM&4TzO4fR@@TEN&ia+a zgh+pZ`G+M#Ss?NHw4#PQx=4*N)kT$}6kx}nZVO-ia@FG=QxSLRFt{h#TSSd)k6B#c zfB?mRWsTiy)x#*Qpn#4YN8D46kZ&w&}t7CDz*L*EYrJrB!B;<`V&wX*&u{{co3 VsC&$XZe0KX002ovPDHLkV1oOT(}(~7 delta 802 zcmV+-1Ks@n2e}52B!4YXOjJcja7=?yF?~!fb3-U|LnwYsE{0PwlU+GmGas2^JCIs7 zhf*?pNi1$ZCZK6Q@mN&200009bW%=J02x82)M=5#{>AK&yZ`_KvPnciRCwCOm)mlq zFbqKBE78UI|Ie*ugk(0|K)ero=ww<3pUSc%+Q(;N1;nj{$A2;rLBK7p8Un(r(;ZY6 z6{RcG!HbUC73v@kYpEbn2!Nc{a*<8397b{la$QTtq@c7|7cbvQ4*y9JvMEp$D{O~h zU6EYD|EjRsTHgp#tBb8_3T|;pQKmLqJk#x^AT6e%cx4gS)kaltQIPT;B@@ z5`!x^g|CMm&VLGV?Exng@wwft@XCPa5kjnm2z#Oot~%qX}6I)6yqES>eU0kAbDK_m*QLD?>X zAbvg@3#8{p%&k4E8Nz47P;}Z3_p2j!a(UcIg@$}6xEajc(l?5c4ICxDbE@!iL(#Oo z{;Z39aUkC0jqOnHDjYynoWp=2zaIs51);XPgUFn&%K|itMmy;1M~owonx-BBT{+_t zQIORZSe||QhHYA_51zpzcI*bdL_t$NCxO3hCM`G8jW`~KPv7ITW#58pQ0@(8uMS_` zi7rQ-NAkQ|P@>S%LWg*MAr^58+>wbiB!s5X(tpxe^vNU!qvE*fGfne{qS5LUS{Erg zIE|2)oA4BJPN|8+U>=K~6P5>aRDI(3yCLRTA^{TXw;HZ(!-y#-S?xdXDbzJ`sx~`y zY+fRg4y%IaGsSC#N9Ot4r-jy!_1HB*EQ7}4(CV>Q$Zbt5rPh?$653i?`^O-blyWDf gVjF@LPv?B+2aBg@MXsNaeE?vJ36LsQ@n>@ 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 B*6IKN diff --git a/TMessagesProj/src/main/assets/emoji/0_1411.png b/TMessagesProj/src/main/assets/emoji/0_1411.png index b28a14d075522d1d05f98f41598e1aee3bb8312d..ac503a64aea5f6bc702bcb5b672bf13e1eef7ba6 100644 GIT binary patch delta 993 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 delta 1840 zcmV-02haGg2fhxFBYy$`P)t-sM{rC!BPQtJ-7g&~OI?kHZIMAhRcLB)Lnt)r>E}>1 zBpw+p${$65ettGQl93B0y0^3DT%Q!@VvLG>z4lBqUGt$qCmxD6EY21$Yd$3|9u;;*DNkaNNGcc`5er;5AXh#$LqJZu9WqmAl?@Un1PB~R zI4%wgH`*~mx(FWz11_FvKz=?bC>$*x9YEhMK%GG`K`7;=n(v z7?6n=*3WKFWuLd)VM>fSsQmC4>ty%o;n)6L!SKVoWW9v+xAD=D*QT>UUFG54^P}

  • d!YOLY{y5X4Pyi z%Mijik{lqQC@wI5R5HANyQWRsgpLx)7~_IENq-O|Nd%ZEt`MCX1QNg@I5A>e3Q8TI zBtcvR={Nt3=tFmYk_fGpQbd&;!XyaR zG(QAu10qgXx<75wR4zao#nW^X>{DT4eET@Ez*(esg?xkRDUouq0xe2ud|F7!9EjmR zUVj0@NwH-Hf=q^0xJL*fiJ8mv;vy|l$rO=E9QuvRN}ez|Fvb@Cf7Qv@jU$H>2Eli` z^ukc->2TVnggKEvZdL~qV|-jx+YpRgAgu%tZ2P`D@7B9j#n|q)yY(rTj3)k|1WXub zM3lV76U^m=SY2Q{5#=&}U%$Pr4`mxVKYy>^*6Ty|E=3{`(d;q8!8CrT3g`?d22rHf z={z}9>g*jXZ~HteVr1Jj5P~e@BB76W?cqe32!qz$RS&=bDXWPHl4qO4A@H-jL}aJK zA<@~23x_t^J+tJPs3KGhECd;dV89@;&ho0xJeTn*Tj8b|H+qU-X8G{{Ejo~R_H;c42<_sZ(Q_3NZ2BF(jiVsRDCh<1|;NwdVAM20+ zL57eRL!(h4LYD}_1QIv^B!va`dj{i(P#PgZY9+bBK?t5o02o49#7!Mkl#DH7hM}e7 zIFuOzP`A&oz~InGQN*oUPrv}k`G58KtWaQ-fHg3EoX)2|em+Y)gPwkSWHcNqBtO5t z{`fwh9+e4#poLb)@6+jgKK=Kfp8^QiB5vydMhb*EXgWPIi2|xR{#R((?6wU9LAa>v zpl%O_EB9bH2~xED6Dg4eddUL_xfB6X5N!FQ_kWGArS+F@ww*ka&`_r7jp-7zR9>T*(WWK zF#%&@+BugHkd+y`-J68ZKYv_57C$@DCIUt@7yv*~Mtb(;{ONTIXZT(iD&rDn5}_0T z7@46K#?P;XIYan31@MtW9cnX@)CkJhuHfPo#%FL33>M_5E<>%=@GNEK)Gg<_TO;hg zvRF6BOQ|x2X$(-xRtv!x_Iq4=G9BTdP(dlu#)YR7q9k$=>!)Oi$jjh#(t zR{e`GAmIqYwLL8(J|w|t;#xavE924(s2agVm0Lr*T*eMP_GW zs(DaIkXa(58fg$j_@({q=$w{f_Jur*KKK#Cs8%l>fr!n*C{BO?0woQ(5{&mg1OtrG zsAdGjRuFqUq*=&nM1n#BFiMY*Y6Ku`1+m*FPWzC+0ug$ZD}TZJ%Ajf-K*SmX+81P@ z7$iuQ5rKlY4~(vHbx-;$1oaGz;pnDwF$#1rR2~crKp?bhv8PD`hEbzWP%8w zIaCH2!HeTHm@iml+-*tMpu^#?-ye@(Nyp=Ue;~E%+h=|J2m2#b1l%!JsQ>@~07*qo IM6N<$f<)%MQvd(} diff --git a/TMessagesProj/src/main/assets/emoji/0_112.png b/TMessagesProj/src/main/assets/emoji/0_112.png index 3b433433b543eebcee7e80a50b4e91aa93737574..eedaad7a9a0ad0e2423bcdef7ab51f4afbe71f8e 100644 GIT binary patch delta 2394 zcmV-g38nUs3gi-yBYy$HP)t-sM{rEgoj1soFDfG&&zm5~l^gBDb=|6CR7WY!mpJjr zY|54$;I>NJnk(hGklUOw+?pxGjvC#cH~isi#gP}_x{ChfVab;r#E}-?yqW2|mgA#D z9U2zao;HQIv|mUl=(uD!$NS%?Yv;h7=&(lWz*95F|4O&zIe*RnW6tH*mK4pC8^(?y z_|a7Dz&X^R8|S=6{?~2HnH2x>g1dew|J+pb$yDH;8po3m;IcXH#7OqdK;yPR#EKf` zvo8Pcc^DND%BDpLpzQtCWU+H5Ehinng(nuM^Mh(A;i)0+#8aAnGU&ikGs65sH5N`j z7FI?e)v!np41Wmi%468RTO}V9sf#mbQ66($D720x1_T6`ibs@h8H8>`yQW$9&S5n) zF2arw(4Q61`v3jaNdN1D|J`!7cPjtod;jZj|Mrj`vi`q^5&!3BuJ8Zi{{OU-IREjB z+^;auk}klUJ$}^w)utiAnl9O^DF5MIU`;&0^#4=K{(sG-Ho2Nhd0;~akJccEwBV>_ z@7ro|i*}%oT-=~mynFR;0zT|M!)X zc3Bx%dFVmWyZ`_IDs)m#QvfJgDg1OW6%0aK*ZS(y)BEbSeyR8KzLiLIibWN9)<%>Y=8r z&Fl4gVsL7;zfrVWCvm{b+jLZNy8;!q4f<&qR+@%IT%R0(--6>7#bXU=(Z^3uPq%b{ zqUkt*18>?$3s!79yEJy6P6Yu<5Cc^-(SH&J98dt&oG-vWY7kKvRbXgkj>?;sA93n#)fvrxsc7pNDV6-c2?vDm$eU>EkvPD zhf>KzRjb|DSX}%UVR7*{qPR*WQl)i%+6v4jv12B^XHdYvN0T6WH8TSR@&vS)nSYsI zXcUvlL@5o2!XlB2C}clcp)iCJsbneV)KbOb=ZbmfRWy}Krrgt5*e7jMqPU@fnYJebjwURETlF77Hp-}aRC|)QOis@4rPFEJ{nM`N~4uHI1$R#q#+)Av3 zk`^reQTAntK8HdPE28JhN~7W$uYWYOR6+%qVm9Iby;AfZL`um-!K!eG)cD5ca99h8 z)b@dQHdQ(Nm`Tmg&or6GJ~S$a*DhC1ueX$vMU}$gcyZGp{lVc-Sc-{)*XzytU4FkS zpPeTl4`vraE`Q#isUGlpTQRW?MPK&~#fUlVP`DEz-s@H8@_D~M@5&)LFMkL?30i-q ze!%nmUZSLMgdI00c@j245weVpjd^n}|MLXaPl4Z!j1vRtpry{?_B(J!lL&RF;Tg45(ACeBPDF&Z@~p@ycdnl`bo581DIKr>tp^$%ksiP>s|`r_I;Fsj0Q&3mY;Kck%GB7HxuJbhPuHkx}mM?!)4^_WTOPQSi+sGBiaolLtT^%XW8_N@Ksgb97WD%t3A~ zW)coaPA-B+YnUW{UUisT*+jl6fPta67M(;U+~5o|NhING59WYk$MZ(H*~&iR$WsAP zJf$-rPiY@y7=O(qBzqT_0}4!XUJaAM93)7yG%e&OCmCk&#uvke1AW=Ymt#@|B7!q};^?NE~1t z`(+8b8>~q)apBp4fw1E_j}|MHOr}yvnh>Q>0aX}>Wq)7(No5#TQ@HRPul`Db;*Uzk z1v2jv6V#y*@+K2X^mmJVIfjENoCo7ORIn5Gc>aJvaQK&zrf~?ULEa{UydMfra4CLF zhzC8v|M*Kdy!Fz!>s^w>kp~_I3wK?DT>?*|@$f$v9TZGRhS_sB>$3jAO2U$7JspPSeeG5`Po M07*qoM6N<$f(vb>82|tP delta 1277 zcmVK;(nLi{wZ2`D)>SG z00ewVL_t(|UhS7_lG`{8gl&lwC_G5X_do2i0aBVo-aSAz$bXNSa<@J-0miC%{U7RY zm9#9md{y#8`A%3&m6vbMMOkJ0Pe$qWN~T<^?oWA_+6BwqxBm-gU(B|B5k8K}-x0^b z0!#OO&9Dhqrl#FkHTQ|6TTIKAvm8)bQ)Z=ajBHw&t?|)Inkh@ZG+~xzwJS`dTv?WH zA=HmbKvW~Gm4B)H(AXSN9Z{9a^P~g>15vxrxE?&y7I3Q&*FZqC^gtxzqcRiK1O0t; zcM2dBO%M=>D*3r|0Yb@YxPjQp6tw~&Ku92T`MQtF(&YHS=BK(`8Hh0qZSH*Du|h6b zQ=g^*p;y)vx60U8VvLnM*1G$u)F@nmNSA8hL%dh=n15#$M-as*;*s5Na_K)P5DL|z zo8-qdv3hMW&4$QK>n5`AqO_7Pp@}1W82Y$ensZ=2ehYG_%+LR`rFja2 z^*~~bq7hdnoWTM?Ksc%XHqSDq+5OF@X?V=73P@=6;%k=IcsE6I!VmV^hz))#guOZ z`vWYtyiJ(ffa*1EmPV=~?d=F=agPkdys6A;Ia{X_#f_W@m#ym;0@K$z7JoPbgY=pC zm?*9j$>9harvf6q_GVB6;q9xEa;FZ&ZW0I%M1QxLz|{D61VcrWLt3=7%3}LYqSe}+ zB78qmBp}Ac`y8K7cd%&8mQ~0RJg8D(={83QQeFr-g%RQ7Rcq|DPDB;o*whh(b~XuvP6mQ*n+Y6#h^b3An+76Z2sJuS(x|!Ms-4`u0NezH(?l7$ zz*KB4 zWt}T<`B%a^-m7~x44Zv-QHq<^_38&%amJ>4W_|&!3)sJ)zF(Vg~*JN$YyfTGv#572iL^_a#0l ndwP4NQXbkA(+=&AuD|sUFlB~o&WQ$%00000NkvXXu0mjfZ5vrC diff --git a/TMessagesProj/src/main/assets/emoji/0_1120.png b/TMessagesProj/src/main/assets/emoji/0_1120.png index b955f1b6657fd2043497789cd7c754218c9ee99c..da872b5e3cc948ea0e8432029cf14334de5dbbf5 100644 GIT binary patch delta 1649 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 M07*qoM6N<$f`Fi~tpET3 diff --git a/TMessagesProj/src/main/assets/emoji/0_1121.png b/TMessagesProj/src/main/assets/emoji/0_1121.png index b26a4765a581fe3d2d9c5b4f8dfb2b0e2c7a603a..66bdf158e75c420d0bfa981f7bc8b4d7f9e5cd46 100644 GIT binary patch delta 1649 zcmV-%29Ei#4}lGkBYyz@P)t-sM{rD5KTKCvR!cQTaZqM-J9=F&UbkevVqsvgkf~xz zSgUrZXG>RPFKTLGS2;E|kyMm>VS9y3jgV26sA;F5U88P4a$z`ARWv<3HZ-kjv4cj5 zFfA>hTBfmWtu-()Mmaki8W|K35Gf@lnopyTNSU8gr+GVr9)A`ThC+~(Or8n}35rIP zZ!>#kSF1ZGAS)ghN;WN5LNzoY8B#klL@y|(RI)uSCR|25Zf$I= zU9&+xKZ8YyI5sx2VYf|8Os`bCO(#&bSHn3PH-~v@aac}wMrgcf#ImiU=HAD;s+6#p zdc$qYmxp&kIe#&;j#80eC%n!-Hvj+tB6LztQvhK7d>j7!{{9RxFGt~?$6tZ8{zA{k zsnD#d>ecXZ?C0IjlzKY=00j?8L_t(|UY*w0dfP@21z;8ctP(@XlBg2dS@hmJYcFbU z@Bb{BS<3nBisqhW$Awr}6w zwmCDweMEw!c^tzYhL|MTjdppeAo7RFfyLLBBL zP=8q*YP228I=de6JdNNaI7kv{Aqr(gXuCEOp?PRvjU-RQFfCy%unB@;BC47viXs@e zjV!|UQJ#kpq0hd@okEz@DAOoC2p&ZHhlObWBl-WNtlt7W)O@BnAt%TJE07#utxKflL2o%ZSH))ze7r_;T z)yH1%w$8B;cL0C@k<`_u49k@Z;jg(0Yd-v~V1+{wi+5@E{Pe!fDzxrk48_omU_1^2 z$(pLXyLWkhdijC9gajpY-U`NZK%`4BAnNq;FIM6XN03xkSH|=Cd<=!4h>FBjhks4z zV2Qxsg()SVh$3BDQ-~#9wU~%U3FnY`*HVf(4RkVOOV_7X@W{4IItLO`05uv7oaJD^ zC@rQri~tDBc4Y}BX&~{#aM%vz(ZD&3sq4xH)cBQ9EtW&Mlj$5P5@^hS7S#I=!z!+1 zdSCIbEz8h@-lDVt0Jhy{S;f5pt$$_56?jXQEok!NdX*Q3!}Bh~Ds%%{>#8f*x+Pnd z4sjs5W$fcPiId|Wj(y#bWL@R2DIv=sSU68Ho-6o&kYv?ktGICBGKc4@XSRa|-6=iW zwUXso9A<+fH98ln4uX2qKC@NFvJMCP^z`}jQ)4Y>c^>DtN4Kfc!|QTD=zl*6Xe_68 zmWMaTT1<7ND2l5JC8#h50)?mfxR7`_sUvsS2i;h%*Xu@yqk|X<5+I;)c2qZ1wjwI=Wmeu?JMfNhAe#foaU&3H8V=+PZdN0mX8?G#s1O zPzpHFr^fp;FY7>D9Qj+f;eSdQkfkC!bfF4;Ys{fUAQ=n<7-w_>rC1huAm60Kug%LPBz5CX$l=00fND2774xs02|`S%2E2gtR!&W~J`h$J vMe2-mIO3i-h9S&(00000NkvXXu0mjfl2ZVh delta 1955 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 IM6N<$g3nl>NB{r; delta 2303 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 O0000OjJcja7vRboRj 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 N002ovPDHLkV1mX*LahJ* delta 1975 zcmV;o2T1tF4a5(SBYy!DP)t-sM{rDrSvn$Iq&R4%gHkk)UqOspI*D{>W=TR6IcFM6 zh2FGNH*&g zK6$?tJZ_w4O-VE?)~R2`m0?MW%Rhj`G<3TaI%^g`bQCsW7=KEKEiXVpQgLT_m$!jo zm}*S2d|ZK3Gh;d&sdQGqj%U1zWx0lA#FJ`RF%^woMRZ3eNGTM3Pc4dCILeuCRyitZ zNjJ`>fi@irpmI`dKp;z!-O|0Llx9H0msgg4Z|maL_V@IUijCIGz`Ui93jqKl4+mA1 z)hTDPCSs~-j(@yOkj@!TkVJ;aI(xrSlF~43wHj2I9$KRqM1J$qx=8>403vi!PE!Ey zxj6wJ8a$@|<;eCyy(5cbi>fW`?xXmN}000I(NklvL=6@py3`Ozdf6iz|H{Ye#cl3HU z|BrtAcGzh}QPk=TC++SJ3wqsY%Ok}LWYy|Se$3LHM%DAA!O2#wN&kAoZHwTG{{tbb zyY|(F2nF8Ci#!icJQ`L}czb0PtXM^_u!tdHbui{%m80GA*(zc+p*s=(g|L4`h8E$0 zk8ckf8h=4qmYnmloL*Mkuc9)~tEx1P z7Wuri=*WZ0622vAg532k)xo$extF4(j>4iE7WyT(LBRb>4IPH4D1jC%K}#K`BB-P| zxY&%2Z#icGpsDcEBymqR1W0LZ*}l+Cr?3SeN`FbIK@`NRaSMf8%gftKiW0vBh}P&p z3?5QBG$;?Nx}>;4h4nPmCPrjKbzu|*YOhmp3QD;?FlCw;EJ;$LGzAuX*o(pJ-AoU8 z5P_!WlY_*@5tHgF2Mq;wwEMpBK{dEH^Vyri1_YD{QX)hlO^qxl6lp>=P@b3lH^FQ) zuYZ?jN1I>JR&i_Hd?ToaHJa8nT%_} zNQ08JX+eKlD5